diff options
author | battre@chromium.org <battre@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-12-23 10:18:20 +0000 |
---|---|---|
committer | battre@chromium.org <battre@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-12-23 10:18:20 +0000 |
commit | eccf68e19bd5ddb3a6eac53a5313a49054a418f3 (patch) | |
tree | 3e883a8c74dd9e1503da8a05b3f4a555a7e0f1ec /chrome/browser | |
parent | f61c397ae7c8d07762b02d6578928163e2a8eca0 (diff) | |
download | chromium_src-eccf68e19bd5ddb3a6eac53a5313a49054a418f3.zip chromium_src-eccf68e19bd5ddb3a6eac53a5313a49054a418f3.tar.gz chromium_src-eccf68e19bd5ddb3a6eac53a5313a49054a418f3.tar.bz2 |
Introduce a separate preference for 'proxy server mode'
The new preference is kProxyServerMode, which supersedes kProxyAutoDetect and kNoProxyServer. The point of this change is to represent 'use system proxy settings' in a more robust way. The proxy extension API is also adjusted to the preference system.
This is a continuation of gfeher's patch from issue 5701003.
BUG=65732, 66023
TEST=ProxyPrefsTest.*, and also covered by ExtensionApiTest.Porxy*, PrefProxyConfigServiceTest.*
Review URL: http://codereview.chromium.org/6004003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@70042 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
22 files changed, 703 insertions, 420 deletions
diff --git a/chrome/browser/extensions/extension_proxy_api.cc b/chrome/browser/extensions/extension_proxy_api.cc index 9bc33cb..d71c055 100644 --- a/chrome/browser/extensions/extension_proxy_api.cc +++ b/chrome/browser/extensions/extension_proxy_api.cc @@ -7,6 +7,7 @@ #include "base/string_util.h" #include "base/stringprintf.h" #include "base/values.h" +#include "chrome/browser/prefs/proxy_prefs.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/common/pref_names.h" @@ -53,8 +54,8 @@ bool UseCustomProxySettingsFunction::RunImpl() { DictionaryValue* proxy_config; EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &proxy_config)); - bool auto_detect = false; - proxy_config->GetBoolean("autoDetect", &auto_detect); + std::string proxy_mode; + proxy_config->GetString("mode", &proxy_mode); DictionaryValue* pac_dict = NULL; proxy_config->GetDictionary("pacScript", &pac_dict); @@ -62,7 +63,9 @@ bool UseCustomProxySettingsFunction::RunImpl() { DictionaryValue* proxy_rules = NULL; proxy_config->GetDictionary("rules", &proxy_rules); - return ApplyAutoDetect(auto_detect) && + // TODO(battre,gfeher): Make sure all the preferences get always + // overwritten. + return ApplyMode(proxy_mode) && ApplyPacScript(pac_dict) && ApplyProxyRules(proxy_rules); } @@ -75,13 +78,19 @@ bool UseCustomProxySettingsFunction::GetProxyServer( return true; } -bool UseCustomProxySettingsFunction::ApplyAutoDetect(bool auto_detect) { - // We take control of the auto-detect preference even if none was specified, - // so that all proxy preferences are controlled by the same extension (if not - // by a higher-priority source). - SendNotification(prefs::kProxyAutoDetect, - Value::CreateBooleanValue(auto_detect)); - return true; +bool UseCustomProxySettingsFunction::ApplyMode(const std::string& mode) { + // We take control of the mode preference even if none was specified, so that + // all proxy preferences are controlled by the same extension (if not by a + // higher-priority source). + bool result = true; + ProxyPrefs::ProxyMode mode_enum; + if (!ProxyPrefs::StringToProxyMode(mode, &mode_enum)) { + mode_enum = ProxyPrefs::MODE_SYSTEM; + LOG(WARNING) << "Invalid mode for proxy settings: " << mode; + result = false; + } + ApplyPreference(prefs::kProxyMode, Value::CreateIntegerValue(mode_enum)); + return result; } bool UseCustomProxySettingsFunction::ApplyPacScript(DictionaryValue* pac_dict) { @@ -92,14 +101,16 @@ bool UseCustomProxySettingsFunction::ApplyPacScript(DictionaryValue* pac_dict) { // We take control of the PAC preference even if none was specified, so that // all proxy preferences are controlled by the same extension (if not by a // higher-priority source). - SendNotification(prefs::kProxyPacUrl, Value::CreateStringValue(pac_url)); + ApplyPreference(prefs::kProxyPacUrl, Value::CreateStringValue(pac_url)); return true; } bool UseCustomProxySettingsFunction::ApplyProxyRules( DictionaryValue* proxy_rules) { - if (!proxy_rules) + if (!proxy_rules) { + ApplyPreference(prefs::kProxyServer, Value::CreateStringValue("")); return true; + } // Local data into which the parameters will be parsed. has_proxy describes // whether a setting was found for the scheme; proxy_dict holds the @@ -153,12 +164,12 @@ bool UseCustomProxySettingsFunction::ApplyProxyRules( } } - SendNotification(prefs::kProxyServer, Value::CreateStringValue(proxy_pref)); + ApplyPreference(prefs::kProxyServer, Value::CreateStringValue(proxy_pref)); return true; } -void UseCustomProxySettingsFunction::SendNotification(const char* pref_path, - Value* pref_value) { +void UseCustomProxySettingsFunction::ApplyPreference(const char* pref_path, + Value* pref_value) { profile()->GetExtensionService()->extension_prefs() ->SetExtensionControlledPref(extension_id(), pref_path, pref_value); } diff --git a/chrome/browser/extensions/extension_proxy_api.h b/chrome/browser/extensions/extension_proxy_api.h index 95be304..d645c44 100644 --- a/chrome/browser/extensions/extension_proxy_api.h +++ b/chrome/browser/extensions/extension_proxy_api.h @@ -33,14 +33,12 @@ class UseCustomProxySettingsFunction : public SyncExtensionFunction { bool GetProxyServer(const DictionaryValue* dict, ProxyServer* proxy_server); - bool ApplyAutoDetect(bool auto_detect); + bool ApplyMode(const std::string& mode); bool ApplyPacScript(DictionaryValue* pac_dict); bool ApplyProxyRules(DictionaryValue* proxy_rules); - // Sends a notification that the given pref would like to change to the - // indicated pref_value. This is mainly useful so the ExtensionPrefStore can - // apply the requested change. - void SendNotification(const char* pref_path, Value* pref_value); + // Takes ownership of |pref_value|. + void ApplyPreference(const char* pref_path, Value* pref_value); }; #endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_PROXY_API_H_ diff --git a/chrome/browser/extensions/extension_proxy_apitest.cc b/chrome/browser/extensions/extension_proxy_apitest.cc index f24b7ef..5537f32 100644 --- a/chrome/browser/extensions/extension_proxy_apitest.cc +++ b/chrome/browser/extensions/extension_proxy_apitest.cc @@ -4,13 +4,46 @@ #include "chrome/browser/extensions/extension_apitest.h" #include "chrome/browser/prefs/pref_service.h" +#include "chrome/browser/prefs/proxy_prefs.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/extensions/extension.h" #include "chrome/common/pref_names.h" -// Tests auto-detect and PAC proxy settings. +// Tests direct connection settings. +IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ProxyDirectSettings) { + CommandLine::ForCurrentProcess()->AppendSwitch( + switches::kEnableExperimentalExtensionApis); + + ASSERT_TRUE(RunExtensionTest("proxy/direct")) << message_; + const Extension* extension = GetSingleLoadedExtension(); + ASSERT_TRUE(extension); + + PrefService* pref_service = browser()->profile()->GetPrefs(); + + const PrefService::Preference* pref = + pref_service->FindPreference(prefs::kProxyMode); + ASSERT_TRUE(pref != NULL); + ASSERT_TRUE(pref->IsExtensionControlled()); + int mode = pref_service->GetInteger(prefs::kProxyMode); + EXPECT_EQ(ProxyPrefs::MODE_DIRECT, mode); + + // Other proxy prefs should also be set, so they're all controlled from one + // place. + pref = pref_service->FindPreference(prefs::kProxyPacUrl); + ASSERT_TRUE(pref != NULL); + EXPECT_TRUE(pref->IsExtensionControlled()); + EXPECT_EQ("", pref_service->GetString(prefs::kProxyPacUrl)); + + // No manual proxy prefs were set. + pref = pref_service->FindPreference(prefs::kProxyServer); + ASSERT_TRUE(pref != NULL); + EXPECT_TRUE(pref->IsExtensionControlled()); + EXPECT_EQ("", pref_service->GetString(prefs::kProxyServer)); +} + +// Tests auto-detect settings. IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ProxyAutoSettings) { CommandLine::ForCurrentProcess()->AppendSwitch( switches::kEnableExperimentalExtensionApis); @@ -22,11 +55,37 @@ IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ProxyAutoSettings) { PrefService* pref_service = browser()->profile()->GetPrefs(); const PrefService::Preference* pref = - pref_service->FindPreference(prefs::kProxyAutoDetect); + pref_service->FindPreference(prefs::kProxyMode); + ASSERT_TRUE(pref != NULL); + ASSERT_TRUE(pref->IsExtensionControlled()); + int mode = pref_service->GetInteger(prefs::kProxyMode); + EXPECT_EQ(ProxyPrefs::MODE_AUTO_DETECT, mode); + + // Other proxy prefs should also be set, so they're all controlled from one + // place. + pref = pref_service->FindPreference(prefs::kProxyPacUrl); + ASSERT_TRUE(pref != NULL); + EXPECT_TRUE(pref->IsExtensionControlled()); + EXPECT_EQ("", pref_service->GetString(prefs::kProxyPacUrl)); +} + +// Tests PAC proxy settings. +IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ProxyPacScript) { + CommandLine::ForCurrentProcess()->AppendSwitch( + switches::kEnableExperimentalExtensionApis); + + ASSERT_TRUE(RunExtensionTest("proxy/pac")) << message_; + const Extension* extension = GetSingleLoadedExtension(); + ASSERT_TRUE(extension); + + PrefService* pref_service = browser()->profile()->GetPrefs(); + + const PrefService::Preference* pref = + pref_service->FindPreference(prefs::kProxyMode); ASSERT_TRUE(pref != NULL); ASSERT_TRUE(pref->IsExtensionControlled()); - bool auto_detect = pref_service->GetBoolean(prefs::kProxyAutoDetect); - EXPECT_TRUE(auto_detect); + int mode = pref_service->GetInteger(prefs::kProxyMode); + EXPECT_EQ(ProxyPrefs::MODE_PAC_SCRIPT, mode); pref = pref_service->FindPreference(prefs::kProxyPacUrl); ASSERT_TRUE(pref != NULL); @@ -37,11 +96,12 @@ IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ProxyAutoSettings) { // No manual proxy prefs were set. pref = pref_service->FindPreference(prefs::kProxyServer); ASSERT_TRUE(pref != NULL); - EXPECT_TRUE(pref->IsDefaultValue()); + EXPECT_TRUE(pref->IsExtensionControlled()); + EXPECT_EQ("", pref_service->GetString(prefs::kProxyServer)); } // Tests setting a single proxy to cover all schemes. -IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ProxyManualSingle) { +IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ProxyFixedSingle) { CommandLine::ForCurrentProcess()->AppendSwitch( switches::kEnableExperimentalExtensionApis); @@ -64,19 +124,53 @@ IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ProxyManualSingle) { // Other proxy prefs should also be set, so they're all controlled from one // place. - pref = pref_service->FindPreference(prefs::kProxyAutoDetect); + pref = pref_service->FindPreference(prefs::kProxyMode); + ASSERT_TRUE(pref != NULL); + EXPECT_TRUE(pref->IsExtensionControlled()); + EXPECT_EQ(ProxyPrefs::MODE_FIXED_SERVERS, + pref_service->GetInteger(prefs::kProxyMode)); + + pref = pref_service->FindPreference(prefs::kProxyPacUrl); ASSERT_TRUE(pref != NULL); EXPECT_TRUE(pref->IsExtensionControlled()); - EXPECT_FALSE(pref_service->GetBoolean(prefs::kProxyAutoDetect)); + EXPECT_EQ("", pref_service->GetString(prefs::kProxyPacUrl)); +} + +// Tests setting to use the system's proxy settings. +IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ProxySystem) { + CommandLine::ForCurrentProcess()->AppendSwitch( + switches::kEnableExperimentalExtensionApis); + + ASSERT_TRUE(RunExtensionTest("proxy/system")) << message_; + const Extension* extension = GetSingleLoadedExtension(); + ASSERT_TRUE(extension); + + PrefService* pref_service = browser()->profile()->GetPrefs(); + + // There should be no values superseding the extension-set proxy in this test. + const PrefService::Preference* pref = + pref_service->FindPreference(prefs::kProxyMode); + ASSERT_TRUE(pref != NULL); + ASSERT_TRUE(pref->IsExtensionControlled()); + int proxy_server_mode = pref_service->GetInteger(prefs::kProxyMode); + EXPECT_EQ(ProxyPrefs::MODE_SYSTEM, proxy_server_mode); + // Other proxy prefs should also be set, so they're all controlled from one + // place. pref = pref_service->FindPreference(prefs::kProxyPacUrl); ASSERT_TRUE(pref != NULL); EXPECT_TRUE(pref->IsExtensionControlled()); EXPECT_EQ("", pref_service->GetString(prefs::kProxyPacUrl)); + + // No manual proxy prefs were set. + pref = pref_service->FindPreference(prefs::kProxyServer); + ASSERT_TRUE(pref != NULL); + EXPECT_TRUE(pref->IsExtensionControlled()); + EXPECT_EQ("", pref_service->GetString(prefs::kProxyServer)); } // Tests setting separate proxies for each scheme. -IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ProxyManualIndividual) { +IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ProxyFixedIndividual) { CommandLine::ForCurrentProcess()->AppendSwitch( switches::kEnableExperimentalExtensionApis); @@ -100,10 +194,11 @@ IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ProxyManualIndividual) { // Other proxy prefs should also be set, so they're all controlled from one // place. - pref = pref_service->FindPreference(prefs::kProxyAutoDetect); + pref = pref_service->FindPreference(prefs::kProxyMode); ASSERT_TRUE(pref != NULL); EXPECT_TRUE(pref->IsExtensionControlled()); - EXPECT_FALSE(pref_service->GetBoolean(prefs::kProxyAutoDetect)); + EXPECT_EQ(ProxyPrefs::MODE_FIXED_SERVERS, + pref_service->GetInteger(prefs::kProxyMode)); pref = pref_service->FindPreference(prefs::kProxyPacUrl); ASSERT_TRUE(pref != NULL); diff --git a/chrome/browser/net/pref_proxy_config_service.cc b/chrome/browser/net/pref_proxy_config_service.cc index 10ae74b..2b10104 100644 --- a/chrome/browser/net/pref_proxy_config_service.cc +++ b/chrome/browser/net/pref_proxy_config_service.cc @@ -8,38 +8,12 @@ #include "chrome/browser/browser_thread.h" #include "chrome/browser/prefs/pref_service.h" #include "chrome/browser/prefs/pref_set_observer.h" +#include "chrome/browser/prefs/proxy_prefs.h" #include "chrome/common/notification_details.h" #include "chrome/common/notification_source.h" #include "chrome/common/notification_type.h" #include "chrome/common/pref_names.h" -namespace { - -const bool kProxyPrefDefaultBoolean = false; -const char kProxyPrefDefaultString[] = ""; - -// Determines if a value of a proxy pref is set to its default. Default values -// have a special role in the proxy pref system, because if all of the proxy -// prefs are set to their defaults, then the system proxy settings are applied. -// TODO(gfeher): Proxy preferences should be refactored to avoid the need -// for such solutions. See crbug.com/65732 -bool IsDefaultValue(const Value* value) { - bool b = false; - std::string s; - if (value->IsType(Value::TYPE_BOOLEAN) && - value->GetAsBoolean(&b)) { - return b == kProxyPrefDefaultBoolean; - } else if (value->IsType(Value::TYPE_STRING) && - value->GetAsString(&s)) { - return s == kProxyPrefDefaultString; - } else { - NOTREACHED() << "Invalid type for a proxy preference."; - return false; - } -} - -} // namespace - PrefProxyConfigTracker::PrefProxyConfigTracker(PrefService* pref_service) : pref_service_(pref_service) { valid_ = ReadPrefConfig(&pref_config_); @@ -112,65 +86,62 @@ bool PrefProxyConfigTracker::ReadPrefConfig(net::ProxyConfig* config) { // Clear the configuration. *config = net::ProxyConfig(); - // Scan for all "enable" type proxy switches. - static const char* proxy_prefs[] = { - prefs::kProxyPacUrl, - prefs::kProxyServer, - prefs::kProxyBypassList, - prefs::kProxyAutoDetect - }; - - // Check whether the preference system holds a valid proxy configuration. Note - // that preferences coming from a lower-priority source than the user settings - // are ignored. That's because chrome treats the system settings as the - // default values, which should apply if there's no explicit value forced by - // policy or the user. - // Preferences that are set to their default values are also ignored, - // regardless of their controlling source. This is because 'use system proxy - // settings' is currently encoded by all the preferences being set to their - // defaults. This will change when crbug.com/65732 is addressed. - bool found_enable_proxy_pref = false; - for (size_t i = 0; i < arraysize(proxy_prefs); i++) { - const PrefService::Preference* pref = - pref_service_->FindPreference(proxy_prefs[i]); - DCHECK(pref); - if (pref && (!pref->IsUserModifiable() || pref->HasUserSetting()) && - !IsDefaultValue(pref->GetValue())) { - found_enable_proxy_pref = true; - break; - } - } - - if (!found_enable_proxy_pref && - !pref_service_->GetBoolean(prefs::kNoProxyServer)) { + ProxyPrefs::ProxyMode mode; + int proxy_mode = pref_service_->GetInteger(prefs::kProxyMode); + if (!ProxyPrefs::IntToProxyMode(proxy_mode, &mode)) { + // Fall back to system settings if the mode preference is invalid. return false; } - if (pref_service_->GetBoolean(prefs::kNoProxyServer)) { - // Ignore all the other proxy config preferences if the use of a proxy - // has been explicitly disabled. - return true; - } - - if (pref_service_->HasPrefPath(prefs::kProxyServer)) { - std::string proxy_server = pref_service_->GetString(prefs::kProxyServer); - config->proxy_rules().ParseFromString(proxy_server); - } - - if (pref_service_->HasPrefPath(prefs::kProxyPacUrl)) { - std::string proxy_pac = pref_service_->GetString(prefs::kProxyPacUrl); - config->set_pac_url(GURL(proxy_pac)); - } - - config->set_auto_detect(pref_service_->GetBoolean(prefs::kProxyAutoDetect)); - - if (pref_service_->HasPrefPath(prefs::kProxyBypassList)) { - std::string proxy_bypass = - pref_service_->GetString(prefs::kProxyBypassList); - config->proxy_rules().bypass_rules.ParseFromString(proxy_bypass); + switch (mode) { + case ProxyPrefs::MODE_SYSTEM: + // Use system settings. + return false; + case ProxyPrefs::MODE_DIRECT: + // Ignore all the other proxy config preferences if the use of a proxy + // has been explicitly disabled. + return true; + case ProxyPrefs::MODE_AUTO_DETECT: + config->set_auto_detect(true); + return true; + case ProxyPrefs::MODE_PAC_SCRIPT: { + if (!pref_service_->HasPrefPath(prefs::kProxyPacUrl)) { + LOG(ERROR) << "Proxy settings request PAC script but do not specify " + << "its URL. Falling back to direct connection."; + return true; + } + std::string proxy_pac = pref_service_->GetString(prefs::kProxyPacUrl); + GURL proxy_pac_url(proxy_pac); + if (!proxy_pac_url.is_valid()) { + LOG(ERROR) << "Invalid proxy PAC url: " << proxy_pac; + return true; + } + config->set_pac_url(proxy_pac_url); + return true; + } + case ProxyPrefs::MODE_FIXED_SERVERS: { + if (!pref_service_->HasPrefPath(prefs::kProxyServer)) { + LOG(ERROR) << "Proxy settings request fixed proxy servers but do not " + << "specify their URLs. Falling back to direct connection."; + return true; + } + std::string proxy_server = + pref_service_->GetString(prefs::kProxyServer); + config->proxy_rules().ParseFromString(proxy_server); + + if (pref_service_->HasPrefPath(prefs::kProxyBypassList)) { + std::string proxy_bypass = + pref_service_->GetString(prefs::kProxyBypassList); + config->proxy_rules().bypass_rules.ParseFromString(proxy_bypass); + } + return true; + } + case ProxyPrefs::kModeCount: { + // Fall through to NOTREACHED(). + } } - - return true; + NOTREACHED() << "Unknown proxy mode, falling back to system settings."; + return false; } PrefProxyConfigService::PrefProxyConfigService( @@ -258,14 +229,8 @@ void PrefProxyConfigService::RegisterObservers() { // static void PrefProxyConfigService::RegisterUserPrefs( PrefService* pref_service) { - pref_service->RegisterBooleanPref(prefs::kNoProxyServer, - kProxyPrefDefaultBoolean); - pref_service->RegisterBooleanPref(prefs::kProxyAutoDetect, - kProxyPrefDefaultBoolean); - pref_service->RegisterStringPref(prefs::kProxyServer, - kProxyPrefDefaultString); - pref_service->RegisterStringPref(prefs::kProxyPacUrl, - kProxyPrefDefaultString); - pref_service->RegisterStringPref(prefs::kProxyBypassList, - kProxyPrefDefaultString); + pref_service->RegisterIntegerPref(prefs::kProxyMode, ProxyPrefs::MODE_SYSTEM); + pref_service->RegisterStringPref(prefs::kProxyServer, ""); + pref_service->RegisterStringPref(prefs::kProxyPacUrl, ""); + pref_service->RegisterStringPref(prefs::kProxyBypassList, ""); } diff --git a/chrome/browser/net/pref_proxy_config_service_unittest.cc b/chrome/browser/net/pref_proxy_config_service_unittest.cc index cc602ec..dad5c53 100644 --- a/chrome/browser/net/pref_proxy_config_service_unittest.cc +++ b/chrome/browser/net/pref_proxy_config_service_unittest.cc @@ -8,6 +8,7 @@ #include "base/file_path.h" #include "chrome/browser/net/chrome_url_request_context.h" #include "chrome/browser/prefs/pref_service_mock_builder.h" +#include "chrome/browser/prefs/proxy_prefs.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/pref_names.h" #include "chrome/test/testing_pref_service.h" @@ -114,6 +115,9 @@ TEST_F(PrefProxyConfigServiceTest, BaseConfiguration) { TEST_F(PrefProxyConfigServiceTest, DynamicPrefOverrides) { pref_service_->SetManagedPref( prefs::kProxyServer, Value::CreateStringValue("http://example.com:3128")); + pref_service_->SetManagedPref( + prefs::kProxyMode, + Value::CreateIntegerValue(ProxyPrefs::MODE_FIXED_SERVERS)); loop_.RunAllPending(); net::ProxyConfig actual_config; @@ -126,7 +130,8 @@ TEST_F(PrefProxyConfigServiceTest, DynamicPrefOverrides) { net::ProxyServer::SCHEME_HTTP)); pref_service_->SetManagedPref( - prefs::kProxyAutoDetect, Value::CreateBooleanValue(true)); + prefs::kProxyMode, + Value::CreateIntegerValue(ProxyPrefs::MODE_AUTO_DETECT)); loop_.RunAllPending(); proxy_config_service_->GetLatestProxyConfig(&actual_config); @@ -156,10 +161,20 @@ TEST_F(PrefProxyConfigServiceTest, Observers) { // Override configuration, this should trigger a notification. net::ProxyConfig pref_config; pref_config.set_pac_url(GURL(kFixedPacUrl)); + EXPECT_CALL(observer, OnProxyConfigChanged(ProxyConfigMatches(pref_config))).Times(1); + pref_service_->SetManagedPref(prefs::kProxyPacUrl, Value::CreateStringValue(kFixedPacUrl)); + // The above does not trigger a notification, because PrefProxyConfig still + // sees the mode as the default (ProxyPrefs::SYSTEM), so that it doesn't claim + // to have proxy config. + // TODO(battre): Remove this comment when http://crbug.com/65732 is + // resolved. + pref_service_->SetManagedPref( + prefs::kProxyMode, + Value::CreateIntegerValue(ProxyPrefs::MODE_PAC_SCRIPT)); loop_.RunAllPending(); Mock::VerifyAndClearExpectations(&observer); @@ -175,6 +190,11 @@ TEST_F(PrefProxyConfigServiceTest, Observers) { // Clear the override should switch back to the fixed configuration. EXPECT_CALL(observer, OnProxyConfigChanged(ProxyConfigMatches(config3))).Times(1); + pref_service_->RemoveManagedPref(prefs::kProxyMode); + // The above switches the mode to the default (ProxyPrefs::SYSTEM), so the + // next removal won't bother PrefProxyConfigService. + // TODO(battre): Remove this comment when http://crbug.com/65732 is + // completed. pref_service_->RemoveManagedPref(prefs::kProxyPacUrl); loop_.RunAllPending(); Mock::VerifyAndClearExpectations(&observer); @@ -350,19 +370,16 @@ static const CommandLineTestParams kCommandLineTestParams[] = { "*.google.com,foo.com:99,1.2.3.4:22,127.0.0.1/8"), }, { - "Pac URL with proxy bypass URLs", + "Pac URL", // Input { { switches::kProxyPacUrl, "http://wpad/wpad.dat" }, - { switches::kProxyBypassList, - ".google.com, foo.com:99, 1.2.3.4:22, 127.0.0.1/8" }, }, // Expected result false, // is_null false, // auto_detect GURL("http://wpad/wpad.dat"), // pac_url - net::ProxyRulesExpectation::EmptyWithBypass( - "*.google.com,foo.com:99,1.2.3.4:22,127.0.0.1/8"), + net::ProxyRulesExpectation::Empty(), }, { "Autodetect", diff --git a/chrome/browser/policy/config_dir_policy_provider_unittest.cc b/chrome/browser/policy/config_dir_policy_provider_unittest.cc index 7197f490..8b7e9a0 100644 --- a/chrome/browser/policy/config_dir_policy_provider_unittest.cc +++ b/chrome/browser/policy/config_dir_policy_provider_unittest.cc @@ -259,8 +259,8 @@ INSTANTIATE_TEST_CASE_P( kPolicyDefaultSearchProviderEncodings, key::kDefaultSearchProviderEncodings), ValueTestParams::ForIntegerPolicy( - kPolicyProxyServerMode, - key::kProxyServerMode), + kPolicyProxyMode, + key::kProxyMode), ValueTestParams::ForStringPolicy( kPolicyProxyServer, key::kProxyServer), diff --git a/chrome/browser/policy/configuration_policy_pref_store.cc b/chrome/browser/policy/configuration_policy_pref_store.cc index 3971980..3c7ea6a 100644 --- a/chrome/browser/policy/configuration_policy_pref_store.cc +++ b/chrome/browser/policy/configuration_policy_pref_store.cc @@ -8,10 +8,12 @@ #include "base/lazy_instance.h" #include "base/logging.h" #include "base/path_service.h" +#include "base/stl_util-inl.h" #include "base/string16.h" #include "base/string_util.h" #include "base/utf_string_conversions.h" #include "base/values.h" +#include "chrome/browser/prefs/proxy_prefs.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/policy/configuration_policy_provider.h" #if defined(OS_WIN) @@ -248,7 +250,7 @@ ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList() { key::kDefaultSearchProviderIconURL }, { kPolicyDefaultSearchProviderEncodings, Value::TYPE_STRING, key::kDefaultSearchProviderEncodings }, - { kPolicyProxyServerMode, Value::TYPE_INTEGER, key::kProxyServerMode }, + { kPolicyProxyMode, Value::TYPE_INTEGER, key::kProxyMode }, { kPolicyProxyServer, Value::TYPE_STRING, key::kProxyServer }, { kPolicyProxyPacUrl, Value::TYPE_STRING, key::kProxyPacUrl }, { kPolicyProxyBypassList, Value::TYPE_STRING, key::kProxyBypassList }, @@ -331,17 +333,16 @@ ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList() { ConfigurationPolicyPrefStore::ConfigurationPolicyPrefStore( ConfigurationPolicyProvider* provider) : provider_(provider), - prefs_(new DictionaryValue()), - lower_priority_proxy_settings_overridden_(false), - proxy_disabled_(false), - proxy_configuration_specified_(false), - use_system_proxy_(false) { + prefs_(new DictionaryValue()) { if (!provider_->Provide(this)) LOG(WARNING) << "Failed to get policy from provider."; + FinalizeProxyPolicySettings(); FinalizeDefaultSearchPolicySettings(); } -ConfigurationPolicyPrefStore::~ConfigurationPolicyPrefStore() {} +ConfigurationPolicyPrefStore::~ConfigurationPolicyPrefStore() { + DCHECK(proxy_policies_.empty()); +} PrefStore::ReadResult ConfigurationPolicyPrefStore::GetValue( const std::string& key, @@ -415,17 +416,6 @@ ConfigurationPolicyPrefStore::CreateRecommendedPolicyPrefStore() { g_configuration_policy_provider_keeper.Get().recommended_provider()); } -// static -void ConfigurationPolicyPrefStore::GetProxyPreferenceSet( - ProxyPreferenceSet* proxy_pref_set) { - proxy_pref_set->clear(); - for (size_t current = 0; current < arraysize(kProxyPolicyMap); ++current) { - proxy_pref_set->insert(kProxyPolicyMap[current].preference_path); - } - proxy_pref_set->insert(prefs::kNoProxyServer); - proxy_pref_set->insert(prefs::kProxyAutoDetect); -} - const ConfigurationPolicyPrefStore::PolicyToPreferenceMapEntry* ConfigurationPolicyPrefStore::FindPolicyInMap( ConfigurationPolicyType policy, @@ -469,108 +459,152 @@ bool ConfigurationPolicyPrefStore::ApplyPolicyFromMap( bool ConfigurationPolicyPrefStore::ApplyProxyPolicy( ConfigurationPolicyType policy, Value* value) { - bool result = false; - bool warn_about_proxy_disable_config = false; - bool warn_about_proxy_system_config = false; - - const PolicyToPreferenceMapEntry* match_entry = - FindPolicyInMap(policy, kProxyPolicyMap, arraysize(kProxyPolicyMap)); - - // When the first proxy-related policy is applied, ALL proxy-related - // preferences that have been set by command-line switches, extensions, - // user preferences or any other mechanism are overridden. Otherwise - // it's possible for a user to interfere with proxy policy by setting - // proxy-related command-line switches or set proxy-related prefs in an - // extension that are related, but not identical, to the ones set through - // policy. - if (!lower_priority_proxy_settings_overridden_ && - (match_entry || - policy == kPolicyProxyServerMode)) { - ProxyPreferenceSet proxy_preference_set; - GetProxyPreferenceSet(&proxy_preference_set); - for (ProxyPreferenceSet::const_iterator i = proxy_preference_set.begin(); - i != proxy_preference_set.end(); ++i) { - // We use values of TYPE_NULL to mark preferences for which - // READ_USE_DEFAULT should be returned by GetValue(). - prefs_->Set(*i, Value::CreateNullValue()); - } - lower_priority_proxy_settings_overridden_ = true; + // We only collect the values until we have sufficient information when + // FinalizeProxyPolicySettings() is called to determine whether the presented + // values were correct and apply them in that case. + if (policy == kPolicyProxyMode || + policy == kPolicyProxyServer || + policy == kPolicyProxyPacUrl || + policy == kPolicyProxyBypassList) { + delete proxy_policies_[policy]; + proxy_policies_[policy] = value; + return true; } + // We are not interested in this policy. + return false; +} - // Translate the proxy policy into preferences. - if (policy == kPolicyProxyServerMode) { - int int_value; - bool proxy_auto_detect = false; - if (value->GetAsInteger(&int_value)) { - result = true; - switch (int_value) { - case kPolicyNoProxyServerMode: - if (!proxy_disabled_) { - if (proxy_configuration_specified_) - warn_about_proxy_disable_config = true; - proxy_disabled_ = true; - } - break; - case kPolicyAutoDetectProxyMode: - proxy_auto_detect = true; - break; - case kPolicyManuallyConfiguredProxyMode: - break; - case kPolicyUseSystemProxyMode: - if (!use_system_proxy_) { - if (proxy_configuration_specified_) - warn_about_proxy_system_config = true; - use_system_proxy_ = true; - } - break; - default: - // Not a valid policy, don't assume ownership of |value| - result = false; - break; - } +void ConfigurationPolicyPrefStore::FinalizeProxyPolicySettings() { + if (CheckProxySettings()) + ApplyProxySettings(); - if (int_value != kPolicyUseSystemProxyMode) { - prefs_->Set(prefs::kNoProxyServer, - Value::CreateBooleanValue(proxy_disabled_)); - prefs_->Set(prefs::kProxyAutoDetect, - Value::CreateBooleanValue(proxy_auto_detect)); - } - } - } else if (match_entry) { - // Determine if the applied proxy policy settings conflict and issue - // a corresponding warning if they do. - if (!proxy_configuration_specified_) { - if (proxy_disabled_) - warn_about_proxy_disable_config = true; - if (use_system_proxy_) - warn_about_proxy_system_config = true; - proxy_configuration_specified_ = true; - } - if (!use_system_proxy_ && !proxy_disabled_) { - prefs_->Set(match_entry->preference_path, value); - // The ownership of value has been passed on to |prefs_|, - // don't clean it up later. - value = NULL; - } - result = true; + STLDeleteContainerPairSecondPointers(proxy_policies_.begin(), + proxy_policies_.end()); + proxy_policies_.clear(); +} + +bool ConfigurationPolicyPrefStore::HasProxyPolicy( + ConfigurationPolicyType policy) const { + std::map<ConfigurationPolicyType, Value*>::const_iterator iter; + iter = proxy_policies_.find(policy); + return iter != proxy_policies_.end() && + iter->second && !iter->second->IsType(Value::TYPE_NULL); +} + +bool ConfigurationPolicyPrefStore::CheckProxySettings() { + bool mode = HasProxyPolicy(kPolicyProxyMode); + bool server = HasProxyPolicy(kPolicyProxyServer); + bool pac_url = HasProxyPolicy(kPolicyProxyPacUrl); + bool bypass_list = HasProxyPolicy(kPolicyProxyBypassList); + + if ((server || pac_url || bypass_list) && !mode) { + LOG(WARNING) << "A centrally-administered policy defines proxy setting" + << " details without setting a proxy mode."; + return false; } - if (warn_about_proxy_disable_config) { - LOG(WARNING) << "A centrally-administered policy disables the use of" - << " a proxy but also specifies an explicit proxy" - << " configuration."; + if (!mode) + return true; + + int mode_value; + if (!proxy_policies_[kPolicyProxyMode]->GetAsInteger(&mode_value)) { + LOG(WARNING) << "Invalid proxy mode value."; + return false; } - if (warn_about_proxy_system_config) { - LOG(WARNING) << "A centrally-administered policy dictates that the" - << " system proxy settings should be used but also specifies" - << " an explicit proxy configuration."; + switch (mode_value) { + case kPolicyNoProxyServerMode: + if (server || pac_url || bypass_list) { + LOG(WARNING) << "A centrally-administered policy disables the use of" + << " a proxy but also specifies an explicit proxy" + << " configuration."; + return false; + } + break; + case kPolicyAutoDetectProxyMode: + if (server || bypass_list) { + LOG(WARNING) << "A centrally-administered policy dictates that a proxy" + << " shall be auto configured but specifies fixed proxy" + << " servers or a by-pass list."; + return false; + } + break; + case kPolicyManuallyConfiguredProxyMode: + if (!server) { + LOG(WARNING) << "A centrally-administered policy dictates that the" + << " system proxy settings should use fixed proxy servers" + << " without specifying which ones."; + return false; + } + if (pac_url) { + LOG(WARNING) << "A centrally-administered policy dictates that the" + << " system proxy settings should use fixed proxy servers" + << " but also specifies a PAC script."; + return false; + } + break; + case kPolicyUseSystemProxyMode: + if (server || pac_url || bypass_list) { + LOG(WARNING) << "A centrally-administered policy dictates that the" + << " system proxy settings should be used but also " + << " specifies an explicit proxy configuration."; + return false; + } + break; + default: + LOG(WARNING) << "Invalid proxy mode " << mode_value; + return false; } + return true; +} - // If the policy was a proxy policy, cleanup |value|. - if (result && value) - delete value; - return result; +void ConfigurationPolicyPrefStore::ApplyProxySettings() { + if (!HasProxyPolicy(kPolicyProxyMode)) + return; + + int int_mode; + CHECK(proxy_policies_[kPolicyProxyMode]->GetAsInteger(&int_mode)); + ProxyPrefs::ProxyMode mode; + switch (int_mode) { + case kPolicyNoProxyServerMode: + mode = ProxyPrefs::MODE_DIRECT; + break; + case kPolicyAutoDetectProxyMode: + mode = ProxyPrefs::MODE_AUTO_DETECT; + if (HasProxyPolicy(kPolicyProxyPacUrl)) + mode = ProxyPrefs::MODE_PAC_SCRIPT; + break; + case kPolicyManuallyConfiguredProxyMode: + mode = ProxyPrefs::MODE_FIXED_SERVERS; + break; + case kPolicyUseSystemProxyMode: + mode = ProxyPrefs::MODE_SYSTEM; + break; + default: + mode = ProxyPrefs::MODE_DIRECT; + NOTREACHED(); + } + prefs_->Set(prefs::kProxyMode, Value::CreateIntegerValue(mode)); + + if (HasProxyPolicy(kPolicyProxyServer)) { + prefs_->Set(prefs::kProxyServer, proxy_policies_[kPolicyProxyServer]); + proxy_policies_[kPolicyProxyServer] = NULL; + } else { + prefs_->Set(prefs::kProxyServer, Value::CreateNullValue()); + } + if (HasProxyPolicy(kPolicyProxyPacUrl)) { + prefs_->Set(prefs::kProxyPacUrl, proxy_policies_[kPolicyProxyPacUrl]); + proxy_policies_[kPolicyProxyPacUrl] = NULL; + } else { + prefs_->Set(prefs::kProxyPacUrl, Value::CreateNullValue()); + } + if (HasProxyPolicy(kPolicyProxyBypassList)) { + prefs_->Set(prefs::kProxyBypassList, + proxy_policies_[kPolicyProxyBypassList]); + proxy_policies_[kPolicyProxyBypassList] = NULL; + } else { + prefs_->Set(prefs::kProxyBypassList, Value::CreateNullValue()); + } } bool ConfigurationPolicyPrefStore::ApplySyncPolicy( diff --git a/chrome/browser/policy/configuration_policy_pref_store.h b/chrome/browser/policy/configuration_policy_pref_store.h index 820306a..6d0ae15 100644 --- a/chrome/browser/policy/configuration_policy_pref_store.h +++ b/chrome/browser/policy/configuration_policy_pref_store.h @@ -56,10 +56,6 @@ class ConfigurationPolicyPrefStore : public PrefStore, static const ConfigurationPolicyProvider::PolicyDefinitionList* GetChromePolicyDefinitionList(); - // Returns the set of preference paths that can be affected by a proxy - // policy. - static void GetProxyPreferenceSet(ProxyPreferenceSet* proxy_pref_set); - private: // Policies that map to a single preference are handled // by an automated converter. Each one of these policies @@ -79,23 +75,11 @@ class ConfigurationPolicyPrefStore : public PrefStore, ConfigurationPolicyProvider* provider_; scoped_ptr<DictionaryValue> prefs_; - // Set to false until the first proxy-relevant policy is applied. At that - // time, default values are provided for all proxy-relevant prefs - // to override any values set from stores with a lower priority. - bool lower_priority_proxy_settings_overridden_; - - // The following are used to track what proxy-relevant policy has been applied - // accross calls to Apply to provide a warning if a policy specifies a - // contradictory proxy configuration. |proxy_disabled_| is set to true if and - // only if the kPolicyNoProxyServer has been applied, - // |proxy_configuration_specified_| is set to true if and only if any other - // proxy policy other than kPolicyNoProxyServer has been applied. - bool proxy_disabled_; - bool proxy_configuration_specified_; + // Temporary cache that stores values until FinalizeProxyPolicySettings() + // is called. + std::map<ConfigurationPolicyType, Value*> proxy_policies_; - // Set to true if a the proxy mode policy has been set to force Chrome - // to use the system proxy. - bool use_system_proxy_; + bool HasProxyPolicy(ConfigurationPolicyType policy) const; // Returns the map entry that corresponds to |policy| in the map. const PolicyToPreferenceMapEntry* FindPolicyInMap( @@ -136,6 +120,19 @@ class ConfigurationPolicyPrefStore : public PrefStore, // map entries from |prefs_|. void FinalizeDefaultSearchPolicySettings(); + // If the required entries for the proxy settings are specified and valid, + // finalizes the policy-specified configuration by initializing the + // respective values in |prefs_|. + void FinalizeProxyPolicySettings(); + + // Returns true if the policy values stored in proxy_* represent a valid + // proxy configuration. + bool CheckProxySettings(); + + // Assumes CheckProxySettings returns true and applies the values stored + // in proxy_*. + void ApplyProxySettings(); + DISALLOW_COPY_AND_ASSIGN(ConfigurationPolicyPrefStore); }; diff --git a/chrome/browser/policy/configuration_policy_pref_store_unittest.cc b/chrome/browser/policy/configuration_policy_pref_store_unittest.cc index 43e1295..5dad5dc 100644 --- a/chrome/browser/policy/configuration_policy_pref_store_unittest.cc +++ b/chrome/browser/policy/configuration_policy_pref_store_unittest.cc @@ -7,6 +7,7 @@ #include "base/file_path.h" #include "chrome/browser/policy/configuration_policy_pref_store.h" #include "chrome/browser/policy/mock_configuration_policy_provider.h" +#include "chrome/browser/prefs/proxy_prefs.h" #include "chrome/common/pref_names.h" #include "chrome/common/chrome_switches.h" @@ -96,7 +97,7 @@ TEST_P(ConfigurationPolicyPrefStoreStringTest, GetDefault) { TEST_P(ConfigurationPolicyPrefStoreStringTest, SetValue) { store_.Apply(GetParam().type(), - Value::CreateStringValue("http://chromium.org")); + Value::CreateStringValue("http://chromium.org")); std::string result; EXPECT_TRUE(store_.prefs()->GetString(GetParam().pref_name(), &result)); EXPECT_EQ(result, "http://chromium.org"); @@ -108,12 +109,6 @@ INSTANTIATE_TEST_CASE_P( testing::Values( TypeAndName(kPolicyHomePage, prefs::kHomePage), - TypeAndName(kPolicyProxyServer, - prefs::kProxyServer), - TypeAndName(kPolicyProxyPacUrl, - prefs::kProxyPacUrl), - TypeAndName(kPolicyProxyBypassList, - prefs::kProxyBypassList), TypeAndName(kPolicyApplicationLocale, prefs::kApplicationLocale), TypeAndName(kPolicyApplicationLocale, @@ -225,6 +220,44 @@ INSTANTIATE_TEST_CASE_P( // Test cases for the proxy policy settings. class ConfigurationPolicyPrefStoreProxyTest : public testing::Test { + protected: + // Verify that all the proxy prefs are set to the specified expected values. + static void VerifyProxyPrefs( + const ConfigurationPolicyPrefStore& store, + const std::string& expected_proxy_server, + const std::string& expected_proxy_pac_url, + const std::string& expected_proxy_bypass_list, + const ProxyPrefs::ProxyMode& expected_proxy_mode) { + std::string string_result; + + if (expected_proxy_server.empty()) { + EXPECT_FALSE(store.prefs()->GetString(prefs::kProxyServer, + &string_result)); + } else { + EXPECT_TRUE(store.prefs()->GetString(prefs::kProxyServer, + &string_result)); + EXPECT_EQ(expected_proxy_server, string_result); + } + if (expected_proxy_pac_url.empty()) { + EXPECT_FALSE(store.prefs()->GetString(prefs::kProxyPacUrl, + &string_result)); + } else { + EXPECT_TRUE(store.prefs()->GetString(prefs::kProxyPacUrl, + &string_result)); + EXPECT_EQ(expected_proxy_pac_url, string_result); + } + if (expected_proxy_bypass_list.empty()) { + EXPECT_FALSE(store.prefs()->GetString(prefs::kProxyBypassList, + &string_result)); + } else { + EXPECT_TRUE(store.prefs()->GetString(prefs::kProxyBypassList, + &string_result)); + EXPECT_EQ(expected_proxy_bypass_list, string_result); + } + int int_result = -1; + EXPECT_TRUE(store.prefs()->GetInteger(prefs::kProxyMode, &int_result)); + EXPECT_EQ(expected_proxy_mode, int_result); + } }; TEST_F(ConfigurationPolicyPrefStoreProxyTest, ManualOptions) { @@ -232,140 +265,95 @@ TEST_F(ConfigurationPolicyPrefStoreProxyTest, ManualOptions) { new MockConfigurationPolicyProvider()); provider->AddPolicy(kPolicyProxyBypassList, Value::CreateStringValue("http://chromium.org/override")); - provider->AddPolicy(kPolicyProxyPacUrl, - Value::CreateStringValue("http://short.org/proxy.pac")); provider->AddPolicy(kPolicyProxyServer, Value::CreateStringValue("chromium.org")); - provider->AddPolicy(kPolicyProxyServerMode, + provider->AddPolicy(kPolicyProxyMode, Value::CreateIntegerValue( kPolicyManuallyConfiguredProxyMode)); ConfigurationPolicyPrefStore store(provider.get()); - - std::string string_result; - EXPECT_TRUE(store.prefs()->GetString(prefs::kProxyBypassList, - &string_result)); - EXPECT_EQ("http://chromium.org/override", string_result); - EXPECT_TRUE(store.prefs()->GetString(prefs::kProxyPacUrl, &string_result)); - EXPECT_EQ("http://short.org/proxy.pac", string_result); - EXPECT_TRUE(store.prefs()->GetString(prefs::kProxyServer, &string_result)); - EXPECT_EQ("chromium.org", string_result); - bool bool_result; - EXPECT_TRUE(store.prefs()->GetBoolean(prefs::kNoProxyServer, &bool_result)); - EXPECT_FALSE(bool_result); - EXPECT_TRUE(store.prefs()->GetBoolean(prefs::kProxyAutoDetect, &bool_result)); - EXPECT_FALSE(bool_result); + VerifyProxyPrefs( + store, "chromium.org", "", "http://chromium.org/override", + ProxyPrefs::MODE_FIXED_SERVERS); } -TEST_F(ConfigurationPolicyPrefStoreProxyTest, NoProxy) { +TEST_F(ConfigurationPolicyPrefStoreProxyTest, ManualOptionsReversedApplyOrder) { scoped_ptr<MockConfigurationPolicyProvider> provider( new MockConfigurationPolicyProvider()); + provider->AddPolicy(kPolicyProxyMode, + Value::CreateIntegerValue( + kPolicyManuallyConfiguredProxyMode)); provider->AddPolicy(kPolicyProxyBypassList, Value::CreateStringValue("http://chromium.org/override")); - provider->AddPolicy(kPolicyProxyServerMode, - Value::CreateIntegerValue( - kPolicyNoProxyServerMode)); + provider->AddPolicy(kPolicyProxyServer, + Value::CreateStringValue("chromium.org")); ConfigurationPolicyPrefStore store(provider.get()); - - std::string string_result; - EXPECT_FALSE(store.prefs()->GetString(prefs::kProxyBypassList, - &string_result)); - EXPECT_FALSE(store.prefs()->GetString(prefs::kProxyPacUrl, &string_result)); - EXPECT_FALSE(store.prefs()->GetString(prefs::kProxyServer, &string_result)); - bool bool_result; - EXPECT_TRUE(store.prefs()->GetBoolean(prefs::kNoProxyServer, &bool_result)); - EXPECT_TRUE(bool_result); - EXPECT_TRUE(store.prefs()->GetBoolean(prefs::kProxyAutoDetect, &bool_result)); - EXPECT_FALSE(bool_result); + VerifyProxyPrefs( + store, "chromium.org", "", "http://chromium.org/override", + ProxyPrefs::MODE_FIXED_SERVERS); } -TEST_F(ConfigurationPolicyPrefStoreProxyTest, NoProxyReversedApplyOrder) { +TEST_F(ConfigurationPolicyPrefStoreProxyTest, NoProxy) { scoped_ptr<MockConfigurationPolicyProvider> provider( new MockConfigurationPolicyProvider()); - provider->AddPolicy(kPolicyProxyServerMode, - Value::CreateIntegerValue( - kPolicyNoProxyServerMode)); - provider->AddPolicy(kPolicyProxyBypassList, - Value::CreateStringValue("http://chromium.org/override")); + provider->AddPolicy(kPolicyProxyMode, + Value::CreateIntegerValue(kPolicyNoProxyServerMode)); ConfigurationPolicyPrefStore store(provider.get()); - - std::string string_result; - EXPECT_FALSE(store.prefs()->GetString(prefs::kProxyBypassList, - &string_result)); - EXPECT_FALSE(store.prefs()->GetString(prefs::kProxyPacUrl, &string_result)); - EXPECT_FALSE(store.prefs()->GetString(prefs::kProxyServer, &string_result)); - bool bool_result; - EXPECT_TRUE(store.prefs()->GetBoolean(prefs::kNoProxyServer, &bool_result)); - EXPECT_TRUE(bool_result); - EXPECT_TRUE(store.prefs()->GetBoolean(prefs::kProxyAutoDetect, &bool_result)); - EXPECT_FALSE(bool_result); + VerifyProxyPrefs(store, "", "", "", ProxyPrefs::MODE_DIRECT); } TEST_F(ConfigurationPolicyPrefStoreProxyTest, AutoDetect) { scoped_ptr<MockConfigurationPolicyProvider> provider( new MockConfigurationPolicyProvider()); - provider->AddPolicy(kPolicyProxyServerMode, - Value::CreateIntegerValue( - kPolicyAutoDetectProxyMode)); + provider->AddPolicy(kPolicyProxyMode, + Value::CreateIntegerValue(kPolicyAutoDetectProxyMode)); ConfigurationPolicyPrefStore store(provider.get()); - - std::string string_result; - EXPECT_FALSE(store.prefs()->GetString(prefs::kProxyBypassList, - &string_result)); - EXPECT_FALSE(store.prefs()->GetString(prefs::kProxyPacUrl, &string_result)); - EXPECT_FALSE(store.prefs()->GetString(prefs::kProxyServer, &string_result)); - bool bool_result; - EXPECT_TRUE(store.prefs()->GetBoolean(prefs::kNoProxyServer, &bool_result)); - EXPECT_FALSE(bool_result); - EXPECT_TRUE(store.prefs()->GetBoolean(prefs::kProxyAutoDetect, &bool_result)); - EXPECT_TRUE(bool_result); + VerifyProxyPrefs(store, "", "", "", ProxyPrefs::MODE_AUTO_DETECT); } -TEST_F(ConfigurationPolicyPrefStoreProxyTest, UseSystem) { +TEST_F(ConfigurationPolicyPrefStoreProxyTest, AutoDetectPac) { scoped_ptr<MockConfigurationPolicyProvider> provider( new MockConfigurationPolicyProvider()); - provider->AddPolicy(kPolicyProxyBypassList, - Value::CreateStringValue("http://chromium.org/override")); - provider->AddPolicy(kPolicyProxyServerMode, - Value::CreateIntegerValue( - kPolicyUseSystemProxyMode)); + provider->AddPolicy(kPolicyProxyPacUrl, + Value::CreateStringValue("http://short.org/proxy.pac")); + provider->AddPolicy(kPolicyProxyMode, + Value::CreateIntegerValue(kPolicyAutoDetectProxyMode)); ConfigurationPolicyPrefStore store(provider.get()); - - std::string string_result; - EXPECT_FALSE(store.prefs()->GetString(prefs::kProxyBypassList, - &string_result)); - EXPECT_FALSE(store.prefs()->GetString(prefs::kProxyPacUrl, &string_result)); - EXPECT_FALSE(store.prefs()->GetString(prefs::kProxyServer, &string_result)); - bool bool_result; - EXPECT_FALSE(store.prefs()->GetBoolean(prefs::kNoProxyServer, &bool_result)); - EXPECT_FALSE(store.prefs()->GetBoolean(prefs::kProxyAutoDetect, - &bool_result)); + VerifyProxyPrefs( + store, "", "http://short.org/proxy.pac", "", ProxyPrefs::MODE_PAC_SCRIPT); } -TEST_F(ConfigurationPolicyPrefStoreProxyTest, UseSystemReversedApplyOrder) { +TEST_F(ConfigurationPolicyPrefStoreProxyTest, UseSystem) { scoped_ptr<MockConfigurationPolicyProvider> provider( new MockConfigurationPolicyProvider()); - provider->AddPolicy(kPolicyProxyServerMode, - Value::CreateIntegerValue( - kPolicyUseSystemProxyMode)); - provider->AddPolicy(kPolicyProxyBypassList, - Value::CreateStringValue("http://chromium.org/override")); + provider->AddPolicy(kPolicyProxyMode, + Value::CreateIntegerValue(kPolicyUseSystemProxyMode)); ConfigurationPolicyPrefStore store(provider.get()); + VerifyProxyPrefs(store, "", "", "", ProxyPrefs::MODE_SYSTEM); +} - std::string string_result; - EXPECT_FALSE(store.prefs()->GetString(prefs::kProxyBypassList, - &string_result)); - EXPECT_FALSE(store.prefs()->GetString(prefs::kProxyPacUrl, &string_result)); - EXPECT_FALSE(store.prefs()->GetString(prefs::kProxyServer, &string_result)); - bool bool_result; - EXPECT_FALSE(store.prefs()->GetBoolean(prefs::kNoProxyServer, &bool_result)); - EXPECT_FALSE(store.prefs()->GetBoolean(prefs::kProxyAutoDetect, - &bool_result)); +TEST_F(ConfigurationPolicyPrefStoreProxyTest, ProxyInvalid) { + for (int i = 0; i < MODE_COUNT; ++i) { + scoped_ptr<MockConfigurationPolicyProvider> provider( + new MockConfigurationPolicyProvider()); + provider->AddPolicy(kPolicyProxyMode, Value::CreateIntegerValue(i)); + // No mode expects all three parameters being set. + provider->AddPolicy(kPolicyProxyPacUrl, + Value::CreateStringValue("http://short.org/proxy.pac")); + provider->AddPolicy(kPolicyProxyBypassList, + Value::CreateStringValue( + "http://chromium.org/override")); + provider->AddPolicy(kPolicyProxyServer, + Value::CreateStringValue("chromium.org")); + + ConfigurationPolicyPrefStore store(provider.get()); + EXPECT_FALSE(store.prefs()->HasKey(prefs::kProxyMode)); + } } class ConfigurationPolicyPrefStoreDefaultSearchTest : public testing::Test { diff --git a/chrome/browser/policy/configuration_policy_provider_mac_unittest.cc b/chrome/browser/policy/configuration_policy_provider_mac_unittest.cc index 5690375..345a3f6 100644 --- a/chrome/browser/policy/configuration_policy_provider_mac_unittest.cc +++ b/chrome/browser/policy/configuration_policy_provider_mac_unittest.cc @@ -233,8 +233,8 @@ INSTANTIATE_TEST_CASE_P( kPolicyDefaultSearchProviderEncodings, key::kDefaultSearchProviderEncodings), PolicyTestParams::ForIntegerPolicy( - kPolicyProxyServerMode, - key::kProxyServerMode), + kPolicyProxyMode, + key::kProxyMode), PolicyTestParams::ForStringPolicy( kPolicyProxyServer, key::kProxyServer), diff --git a/chrome/browser/policy/configuration_policy_provider_win_unittest.cc b/chrome/browser/policy/configuration_policy_provider_win_unittest.cc index 78c6f7b..beed450 100644 --- a/chrome/browser/policy/configuration_policy_provider_win_unittest.cc +++ b/chrome/browser/policy/configuration_policy_provider_win_unittest.cc @@ -391,8 +391,8 @@ INSTANTIATE_TEST_CASE_P( kPolicyDefaultSearchProviderEncodings, key::kDefaultSearchProviderEncodings), PolicyTestParams::ForIntegerPolicy( - kPolicyProxyServerMode, - key::kProxyServerMode), + kPolicyProxyMode, + key::kProxyMode), PolicyTestParams::ForStringPolicy( kPolicyProxyServer, key::kProxyServer), diff --git a/chrome/browser/policy/configuration_policy_store_interface.h b/chrome/browser/policy/configuration_policy_store_interface.h index 00ebf30..b6d1f3b 100644 --- a/chrome/browser/policy/configuration_policy_store_interface.h +++ b/chrome/browser/policy/configuration_policy_store_interface.h @@ -25,7 +25,7 @@ enum ConfigurationPolicyType { kPolicyDefaultSearchProviderIconURL, kPolicyDefaultSearchProviderEncodings, kPolicyDisableSpdy, - kPolicyProxyServerMode, + kPolicyProxyMode, kPolicyProxyServer, kPolicyProxyPacUrl, kPolicyProxyBypassList, @@ -69,10 +69,24 @@ enum ConfigurationPolicyType { kPolicyDisable3DAPIs }; -static const int kPolicyNoProxyServerMode = 0; -static const int kPolicyAutoDetectProxyMode = 1; -static const int kPolicyManuallyConfiguredProxyMode = 2; -static const int kPolicyUseSystemProxyMode = 3; + +// Constants for the "Proxy Server Mode" defined in the policies. +// Note that these diverge from internal presentation defined in +// ProxyPrefs::ProxyMode for legacy reasons. The following four +// PolicyProxyModeType types were not very precise and had overlapping use +// cases. +enum PolicyProxyModeType { + // Disable Proxy, connect directly. + kPolicyNoProxyServerMode = 0, + // Auto detect proxy or use specific PAC script if given. + kPolicyAutoDetectProxyMode = 1, + // Use manually configured proxy servers (fixed servers). + kPolicyManuallyConfiguredProxyMode = 2, + // Use system proxy server. + kPolicyUseSystemProxyMode = 3, + + MODE_COUNT +}; // An abstract super class for policy stores that provides a method that can be // called by a |ConfigurationPolicyProvider| to specify a policy. diff --git a/chrome/browser/policy/managed_prefs_banner_base.cc b/chrome/browser/policy/managed_prefs_banner_base.cc index 1351da4..7c20a09 100644 --- a/chrome/browser/policy/managed_prefs_banner_base.cc +++ b/chrome/browser/policy/managed_prefs_banner_base.cc @@ -84,8 +84,7 @@ void ManagedPrefsBannerBase::Init(PrefService* local_state, #if defined(GOOGLE_CHROME_BUILD) AddLocalStatePref(prefs::kMetricsReportingEnabled); #endif - AddUserPref(prefs::kNoProxyServer); - AddUserPref(prefs::kProxyAutoDetect); + AddUserPref(prefs::kProxyMode); AddUserPref(prefs::kProxyServer); AddUserPref(prefs::kProxyPacUrl); AddUserPref(prefs::kProxyBypassList); diff --git a/chrome/browser/prefs/command_line_pref_store.cc b/chrome/browser/prefs/command_line_pref_store.cc index ae70d97..4a386d6 100644 --- a/chrome/browser/prefs/command_line_pref_store.cc +++ b/chrome/browser/prefs/command_line_pref_store.cc @@ -7,6 +7,7 @@ #include "app/app_switches.h" #include "base/logging.h" #include "base/values.h" +#include "chrome/browser/prefs/proxy_prefs.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/pref_names.h" @@ -25,8 +26,6 @@ const CommandLinePrefStore::StringSwitchToPreferenceMapEntry const CommandLinePrefStore::BooleanSwitchToPreferenceMapEntry CommandLinePrefStore::boolean_switch_map_[] = { - { switches::kNoProxyServer, prefs::kNoProxyServer, true }, - { switches::kProxyAutoDetect, prefs::kProxyAutoDetect, true }, { switches::kDisableAuthNegotiateCnameLookup, prefs::kDisableAuthNegotiateCnameLookup, true }, { switches::kEnableAuthNegotiatePort, prefs::kEnableAuthNegotiatePort, @@ -37,6 +36,7 @@ const CommandLinePrefStore::BooleanSwitchToPreferenceMapEntry CommandLinePrefStore::CommandLinePrefStore(const CommandLine* command_line) : command_line_(command_line) { ApplySimpleSwitches(); + ApplyProxyMode(); ValidateProxySwitches(); } @@ -73,3 +73,19 @@ bool CommandLinePrefStore::ValidateProxySwitches() { } return true; } + +void CommandLinePrefStore::ApplyProxyMode() { + if (command_line_->HasSwitch(switches::kNoProxyServer)) { + SetValue(prefs::kProxyMode, + Value::CreateIntegerValue(ProxyPrefs::MODE_DIRECT)); + } else if (command_line_->HasSwitch(switches::kProxyPacUrl)) { + SetValue(prefs::kProxyMode, + Value::CreateIntegerValue(ProxyPrefs::MODE_PAC_SCRIPT)); + } else if (command_line_->HasSwitch(switches::kProxyAutoDetect)) { + SetValue(prefs::kProxyMode, + Value::CreateIntegerValue(ProxyPrefs::MODE_AUTO_DETECT)); + } else if (command_line_->HasSwitch(switches::kProxyServer)) { + SetValue(prefs::kProxyMode, + Value::CreateIntegerValue(ProxyPrefs::MODE_FIXED_SERVERS)); + } +} diff --git a/chrome/browser/prefs/command_line_pref_store.h b/chrome/browser/prefs/command_line_pref_store.h index c3baf7a..75d8b10 100644 --- a/chrome/browser/prefs/command_line_pref_store.h +++ b/chrome/browser/prefs/command_line_pref_store.h @@ -45,6 +45,9 @@ class CommandLinePrefStore : public ValueMapPrefStore { // corresponding preferences in this pref store. void ApplySimpleSwitches(); + // Determines the proxy mode preference from the given proxy switches. + void ApplyProxyMode(); + // Weak reference. const CommandLine* command_line_; diff --git a/chrome/browser/prefs/command_line_pref_store_unittest.cc b/chrome/browser/prefs/command_line_pref_store_unittest.cc index 031a7c9..1be9c0a 100644 --- a/chrome/browser/prefs/command_line_pref_store_unittest.cc +++ b/chrome/browser/prefs/command_line_pref_store_unittest.cc @@ -9,6 +9,7 @@ #include "base/string_util.h" #include "base/values.h" #include "chrome/browser/prefs/command_line_pref_store.h" +#include "chrome/browser/prefs/proxy_prefs.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/pref_names.h" @@ -22,6 +23,12 @@ class TestCommandLinePrefStore : public CommandLinePrefStore { bool ProxySwitchesAreValid() { return ValidateProxySwitches(); } + + void VerifyIntPref(const std::string& path, int expected_value) { + Value* actual = NULL; + ASSERT_EQ(PrefStore::READ_OK, GetValue(path, &actual)); + EXPECT_TRUE(FundamentalValue(expected_value).Equals(actual)); + } }; const char unknown_bool[] = "unknown_switch"; @@ -47,13 +54,9 @@ TEST(CommandLinePrefStoreTest, SimpleStringPref) { TEST(CommandLinePrefStoreTest, SimpleBooleanPref) { CommandLine cl(CommandLine::NO_PROGRAM); cl.AppendSwitch(switches::kNoProxyServer); - CommandLinePrefStore store(&cl); + TestCommandLinePrefStore store(&cl); - Value* actual = NULL; - ASSERT_EQ(PrefStore::READ_OK, store.GetValue(prefs::kNoProxyServer, &actual)); - bool result; - EXPECT_TRUE(actual->GetAsBoolean(&result)); - EXPECT_TRUE(result); + store.VerifyIntPref(prefs::kProxyMode, ProxyPrefs::MODE_DIRECT); } // Tests a command line with no recognized prefs. @@ -76,15 +79,11 @@ TEST(CommandLinePrefStoreTest, MultipleSwitches) { cl.AppendSwitchASCII(switches::kProxyServer, "proxy"); cl.AppendSwitchASCII(switches::kProxyBypassList, "list"); cl.AppendSwitchASCII(unknown_bool, "a value"); - CommandLinePrefStore store(&cl); + TestCommandLinePrefStore store(&cl); Value* actual = NULL; EXPECT_EQ(PrefStore::READ_NO_VALUE, store.GetValue(unknown_bool, &actual)); - ASSERT_EQ(PrefStore::READ_OK, - store.GetValue(prefs::kProxyAutoDetect, &actual)); - bool bool_result = false; - EXPECT_TRUE(actual->GetAsBoolean(&bool_result)); - EXPECT_TRUE(bool_result); + store.VerifyIntPref(prefs::kProxyMode, ProxyPrefs::MODE_AUTO_DETECT); EXPECT_EQ(PrefStore::READ_NO_VALUE, store.GetValue(unknown_string, &actual)); std::string string_result = ""; @@ -124,3 +123,16 @@ TEST(CommandLinePrefStoreTest, ProxySwitchValidation) { TestCommandLinePrefStore store4(&cl2); EXPECT_TRUE(store4.ProxySwitchesAreValid()); } + +TEST(CommandLinePrefStoreTest, ManualProxyModeInference) { + CommandLine cl1(CommandLine::NO_PROGRAM); + cl1.AppendSwitch(unknown_string); + cl1.AppendSwitchASCII(switches::kProxyServer, "proxy"); + TestCommandLinePrefStore store1(&cl1); + store1.VerifyIntPref(prefs::kProxyMode, ProxyPrefs::MODE_FIXED_SERVERS); + + CommandLine cl2(CommandLine::NO_PROGRAM); + cl2.AppendSwitchASCII(switches::kProxyPacUrl, "proxy"); + TestCommandLinePrefStore store2(&cl2); + store2.VerifyIntPref(prefs::kProxyMode, ProxyPrefs::MODE_PAC_SCRIPT); +} diff --git a/chrome/browser/prefs/pref_service_unittest.cc b/chrome/browser/prefs/pref_service_unittest.cc index 8ada07a..1a79708 100644 --- a/chrome/browser/prefs/pref_service_unittest.cc +++ b/chrome/browser/prefs/pref_service_unittest.cc @@ -16,6 +16,7 @@ #include "chrome/browser/prefs/pref_observer_mock.h" #include "chrome/browser/prefs/pref_service_mock_builder.h" #include "chrome/browser/prefs/pref_value_store.h" +#include "chrome/browser/prefs/proxy_prefs.h" #include "chrome/browser/prefs/testing_pref_store.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_switches.h" @@ -150,17 +151,14 @@ TEST(PrefServiceTest, Observers) { TEST(PrefServiceTest, ProxyPolicyOverridesCommandLineOptions) { CommandLine command_line(CommandLine::NO_PROGRAM); command_line.AppendSwitchASCII(switches::kProxyBypassList, "123"); - command_line.AppendSwitchASCII(switches::kProxyPacUrl, "456"); command_line.AppendSwitchASCII(switches::kProxyServer, "789"); scoped_ptr<policy::MockConfigurationPolicyProvider> provider( new policy::MockConfigurationPolicyProvider()); Value* mode_value = Value::CreateIntegerValue( policy::kPolicyManuallyConfiguredProxyMode); - provider->AddPolicy(policy::kPolicyProxyServerMode, mode_value); + provider->AddPolicy(policy::kPolicyProxyMode, mode_value); provider->AddPolicy(policy::kPolicyProxyBypassList, Value::CreateStringValue("abc")); - provider->AddPolicy(policy::kPolicyProxyPacUrl, - Value::CreateStringValue("def")); provider->AddPolicy(policy::kPolicyProxyServer, Value::CreateStringValue("ghi")); @@ -170,10 +168,10 @@ TEST(PrefServiceTest, ProxyPolicyOverridesCommandLineOptions) { builder.WithCommandLine(&command_line); scoped_ptr<PrefService> prefs(builder.Create()); browser::RegisterUserPrefs(prefs.get()); - EXPECT_FALSE(prefs->GetBoolean(prefs::kProxyAutoDetect)); - EXPECT_FALSE(prefs->GetBoolean(prefs::kNoProxyServer)); + EXPECT_EQ(ProxyPrefs::MODE_FIXED_SERVERS, + prefs->GetInteger(prefs::kProxyMode)); EXPECT_EQ("789", prefs->GetString(prefs::kProxyServer)); - EXPECT_EQ("456", prefs->GetString(prefs::kProxyPacUrl)); + EXPECT_EQ(std::string(), prefs->GetString(prefs::kProxyPacUrl)); EXPECT_EQ("123", prefs->GetString(prefs::kProxyBypassList)); // Try a second time time with the managed PrefStore in place, the @@ -183,23 +181,22 @@ TEST(PrefServiceTest, ProxyPolicyOverridesCommandLineOptions) { builder.WithManagedPlatformProvider(provider.get()); scoped_ptr<PrefService> prefs2(builder.Create()); browser::RegisterUserPrefs(prefs2.get()); - EXPECT_FALSE(prefs2->GetBoolean(prefs::kProxyAutoDetect)); - EXPECT_FALSE(prefs2->GetBoolean(prefs::kNoProxyServer)); + EXPECT_EQ(ProxyPrefs::MODE_FIXED_SERVERS, + prefs2->GetInteger(prefs::kProxyMode)); EXPECT_EQ("ghi", prefs2->GetString(prefs::kProxyServer)); - EXPECT_EQ("def", prefs2->GetString(prefs::kProxyPacUrl)); + EXPECT_EQ(std::string(), prefs2->GetString(prefs::kProxyPacUrl)); EXPECT_EQ("abc", prefs2->GetString(prefs::kProxyBypassList)); } TEST(PrefServiceTest, ProxyPolicyOverridesUnrelatedCommandLineOptions) { CommandLine command_line(CommandLine::NO_PROGRAM); command_line.AppendSwitchASCII(switches::kProxyBypassList, "123"); - command_line.AppendSwitchASCII(switches::kProxyPacUrl, "456"); command_line.AppendSwitchASCII(switches::kProxyServer, "789"); scoped_ptr<policy::MockConfigurationPolicyProvider> provider( new policy::MockConfigurationPolicyProvider()); Value* mode_value = Value::CreateIntegerValue( - policy::kPolicyUseSystemProxyMode); - provider->AddPolicy(policy::kPolicyProxyServerMode, mode_value); + policy::kPolicyAutoDetectProxyMode); + provider->AddPolicy(policy::kPolicyProxyMode, mode_value); // First verify that command-line options are set correctly when // there is no policy in effect. @@ -207,10 +204,9 @@ TEST(PrefServiceTest, ProxyPolicyOverridesUnrelatedCommandLineOptions) { builder.WithCommandLine(&command_line); scoped_ptr<PrefService> prefs(builder.Create()); browser::RegisterUserPrefs(prefs.get()); - EXPECT_FALSE(prefs->GetBoolean(prefs::kProxyAutoDetect)); - EXPECT_FALSE(prefs->GetBoolean(prefs::kNoProxyServer)); + EXPECT_EQ(ProxyPrefs::MODE_FIXED_SERVERS, + prefs->GetInteger(prefs::kProxyMode)); EXPECT_EQ("789", prefs->GetString(prefs::kProxyServer)); - EXPECT_EQ("456", prefs->GetString(prefs::kProxyPacUrl)); EXPECT_EQ("123", prefs->GetString(prefs::kProxyBypassList)); // Try a second time time with the managed PrefStore in place, the @@ -221,8 +217,8 @@ TEST(PrefServiceTest, ProxyPolicyOverridesUnrelatedCommandLineOptions) { builder.WithManagedPlatformProvider(provider.get()); scoped_ptr<PrefService> prefs2(builder.Create()); browser::RegisterUserPrefs(prefs2.get()); - EXPECT_FALSE(prefs2->GetBoolean(prefs::kProxyAutoDetect)); - EXPECT_FALSE(prefs2->GetBoolean(prefs::kNoProxyServer)); + EXPECT_EQ(ProxyPrefs::MODE_AUTO_DETECT, + prefs2->GetInteger(prefs::kProxyMode)); EXPECT_EQ(std::string(), prefs2->GetString(prefs::kProxyServer)); EXPECT_EQ(std::string(), prefs2->GetString(prefs::kProxyPacUrl)); EXPECT_EQ(std::string(), prefs2->GetString(prefs::kProxyBypassList)); @@ -235,7 +231,7 @@ TEST(PrefServiceTest, ProxyPolicyOverridesCommandLineNoProxy) { new policy::MockConfigurationPolicyProvider()); Value* mode_value = Value::CreateIntegerValue( policy::kPolicyAutoDetectProxyMode); - provider->AddPolicy(policy::kPolicyProxyServerMode, mode_value); + provider->AddPolicy(policy::kPolicyProxyMode, mode_value); // First verify that command-line options are set correctly when // there is no policy in effect. @@ -243,8 +239,7 @@ TEST(PrefServiceTest, ProxyPolicyOverridesCommandLineNoProxy) { builder.WithCommandLine(&command_line); scoped_ptr<PrefService> prefs(builder.Create()); browser::RegisterUserPrefs(prefs.get()); - EXPECT_FALSE(prefs->GetBoolean(prefs::kProxyAutoDetect)); - EXPECT_TRUE(prefs->GetBoolean(prefs::kNoProxyServer)); + EXPECT_EQ(ProxyPrefs::MODE_DIRECT, prefs->GetInteger(prefs::kProxyMode)); EXPECT_EQ(std::string(), prefs->GetString(prefs::kProxyServer)); EXPECT_EQ(std::string(), prefs->GetString(prefs::kProxyPacUrl)); EXPECT_EQ(std::string(), prefs->GetString(prefs::kProxyBypassList)); @@ -256,8 +251,8 @@ TEST(PrefServiceTest, ProxyPolicyOverridesCommandLineNoProxy) { builder.WithManagedPlatformProvider(provider.get()); scoped_ptr<PrefService> prefs2(builder.Create()); browser::RegisterUserPrefs(prefs2.get()); - EXPECT_TRUE(prefs2->GetBoolean(prefs::kProxyAutoDetect)); - EXPECT_FALSE(prefs2->GetBoolean(prefs::kNoProxyServer)); + EXPECT_EQ(ProxyPrefs::MODE_AUTO_DETECT, + prefs2->GetInteger(prefs::kProxyMode)); EXPECT_EQ(std::string(), prefs2->GetString(prefs::kProxyServer)); EXPECT_EQ(std::string(), prefs2->GetString(prefs::kProxyPacUrl)); EXPECT_EQ(std::string(), prefs2->GetString(prefs::kProxyBypassList)); @@ -270,7 +265,7 @@ TEST(PrefServiceTest, ProxyPolicyOverridesCommandLineAutoDetect) { new policy::MockConfigurationPolicyProvider()); Value* mode_value = Value::CreateIntegerValue( policy::kPolicyNoProxyServerMode); - provider->AddPolicy(policy::kPolicyProxyServerMode, mode_value); + provider->AddPolicy(policy::kPolicyProxyMode, mode_value); // First verify that the auto-detect is set if there is no managed // PrefStore. @@ -278,8 +273,7 @@ TEST(PrefServiceTest, ProxyPolicyOverridesCommandLineAutoDetect) { builder.WithCommandLine(&command_line); scoped_ptr<PrefService> prefs(builder.Create()); browser::RegisterUserPrefs(prefs.get()); - EXPECT_TRUE(prefs->GetBoolean(prefs::kProxyAutoDetect)); - EXPECT_FALSE(prefs->GetBoolean(prefs::kNoProxyServer)); + EXPECT_EQ(ProxyPrefs::MODE_AUTO_DETECT, prefs->GetInteger(prefs::kProxyMode)); EXPECT_EQ(std::string(), prefs->GetString(prefs::kProxyServer)); EXPECT_EQ(std::string(), prefs->GetString(prefs::kProxyPacUrl)); EXPECT_EQ(std::string(), prefs->GetString(prefs::kProxyBypassList)); @@ -291,8 +285,7 @@ TEST(PrefServiceTest, ProxyPolicyOverridesCommandLineAutoDetect) { builder.WithManagedPlatformProvider(provider.get()); scoped_ptr<PrefService> prefs2(builder.Create()); browser::RegisterUserPrefs(prefs2.get()); - EXPECT_FALSE(prefs2->GetBoolean(prefs::kProxyAutoDetect)); - EXPECT_TRUE(prefs2->GetBoolean(prefs::kNoProxyServer)); + EXPECT_EQ(ProxyPrefs::MODE_DIRECT, prefs2->GetInteger(prefs::kProxyMode)); EXPECT_EQ(std::string(), prefs2->GetString(prefs::kProxyServer)); EXPECT_EQ(std::string(), prefs2->GetString(prefs::kProxyPacUrl)); EXPECT_EQ(std::string(), prefs2->GetString(prefs::kProxyBypassList)); diff --git a/chrome/browser/prefs/pref_set_observer.cc b/chrome/browser/prefs/pref_set_observer.cc index a073eb2..133b219 100644 --- a/chrome/browser/prefs/pref_set_observer.cc +++ b/chrome/browser/prefs/pref_set_observer.cc @@ -47,8 +47,7 @@ PrefSetObserver* PrefSetObserver::CreateProxyPrefSetObserver( PrefService* pref_service, NotificationObserver* observer) { PrefSetObserver* pref_set = new PrefSetObserver(pref_service, observer); - pref_set->AddPref(prefs::kNoProxyServer); - pref_set->AddPref(prefs::kProxyAutoDetect); + pref_set->AddPref(prefs::kProxyMode); pref_set->AddPref(prefs::kProxyServer); pref_set->AddPref(prefs::kProxyPacUrl); pref_set->AddPref(prefs::kProxyBypassList); diff --git a/chrome/browser/prefs/pref_value_store_unittest.cc b/chrome/browser/prefs/pref_value_store_unittest.cc index 5649061..b78e0fc 100644 --- a/chrome/browser/prefs/pref_value_store_unittest.cc +++ b/chrome/browser/prefs/pref_value_store_unittest.cc @@ -133,8 +133,8 @@ class PrefValueStoreTest : public testing::Test { Value::TYPE_LIST); pref_value_store_->RegisterPreferenceType(prefs::kDefaultPref, Value::TYPE_INTEGER); - pref_value_store_->RegisterPreferenceType(prefs::kProxyAutoDetect, - Value::TYPE_BOOLEAN); + pref_value_store_->RegisterPreferenceType(prefs::kProxyMode, + Value::TYPE_INTEGER); } // Creates a new dictionary and stores some sample user preferences diff --git a/chrome/browser/prefs/proxy_prefs.cc b/chrome/browser/prefs/proxy_prefs.cc new file mode 100644 index 0000000..7eb504c --- /dev/null +++ b/chrome/browser/prefs/proxy_prefs.cc @@ -0,0 +1,45 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/prefs/proxy_prefs.h" + +#include "base/basictypes.h" +#include "base/logging.h" + +namespace { + +// These names are exposed to the proxy extension API. They must be in sync +// with the constants of ProxyPrefs. +const char* kProxyModeNames[] = { "direct", + "auto_detect", + "pac_script", + "fixed_servers", + "system" }; + +} // namespace + +namespace ProxyPrefs { + +COMPILE_ASSERT(arraysize(kProxyModeNames) == kModeCount, + kProxyModeNames_must_have_size_of_NUM_MODES); + +bool IntToProxyMode(int in_value, ProxyMode* out_value) { + DCHECK(out_value); + if (in_value < 0 || in_value >= kModeCount) + return false; + *out_value = static_cast<ProxyMode>(in_value); + return true; +} + +// static +bool StringToProxyMode(const std::string& in_value, ProxyMode* out_value) { + DCHECK(out_value); + for (int i = 0; i < kModeCount; i++) { + if (in_value == kProxyModeNames[i]) + return IntToProxyMode(i, out_value); + } + return false; +} + +} // namespace diff --git a/chrome/browser/prefs/proxy_prefs.h b/chrome/browser/prefs/proxy_prefs.h new file mode 100644 index 0000000..bbeb44d --- /dev/null +++ b/chrome/browser/prefs/proxy_prefs.h @@ -0,0 +1,45 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_PREFS_PROXY_PREFS_H_ +#define CHROME_BROWSER_PREFS_PROXY_PREFS_H_ +#pragma once + +#include <string> + +namespace ProxyPrefs { + +// Possible types of specifying proxy settings. Do not change the order of +// the constants, because numeric values are exposed to users. +// If you add an enum constant, you should also add a string to +// kProxyModeNames in the .cc file. +enum ProxyMode { + // Direct connection to the network, other proxy preferences are ignored. + MODE_DIRECT = 0, + + // Try to retrieve a PAC script from http://wpad/wpad.dat or fall back to + // direct connection. + MODE_AUTO_DETECT = 1, + + // Try to retrieve a PAC script from kProxyPacURL or fall back to direct + // connection. + MODE_PAC_SCRIPT = 2, + + // Use the settings specified in kProxyServer and kProxyBypassList. + MODE_FIXED_SERVERS = 3, + + // The system's proxy settings are used, other proxy preferences are + // ignored. + MODE_SYSTEM = 4, + + kModeCount +}; + +bool IntToProxyMode(int in_value, ProxyMode* out_value); +bool StringToProxyMode(const std::string& in_value, + ProxyMode* out_value); + +} // namespace ProxyPrefs + +#endif // CHROME_BROWSER_PREFS_PROXY_PREFS_H_ diff --git a/chrome/browser/prefs/proxy_prefs_unittest.cc b/chrome/browser/prefs/proxy_prefs_unittest.cc new file mode 100644 index 0000000..72aa0f1 --- /dev/null +++ b/chrome/browser/prefs/proxy_prefs_unittest.cc @@ -0,0 +1,52 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <string> + +#include "base/logging.h" +#include "base/values.h" +#include "base/version.h" +#include "chrome/browser/prefs/proxy_prefs.h" +#include "testing/gtest/include/gtest/gtest.h" + +TEST(ProxyPrefsTest, StringToProxyMode) { + ProxyPrefs::ProxyMode mode; + EXPECT_TRUE(ProxyPrefs::StringToProxyMode("direct", &mode)); + EXPECT_EQ(ProxyPrefs::MODE_DIRECT, mode); + EXPECT_TRUE(ProxyPrefs::StringToProxyMode("auto_detect", &mode)); + EXPECT_EQ(ProxyPrefs::MODE_AUTO_DETECT, mode); + EXPECT_TRUE(ProxyPrefs::StringToProxyMode("pac_script", &mode)); + EXPECT_EQ(ProxyPrefs::MODE_PAC_SCRIPT, mode); + EXPECT_TRUE(ProxyPrefs::StringToProxyMode("system", &mode)); + EXPECT_EQ(ProxyPrefs::MODE_SYSTEM, mode); + EXPECT_TRUE(ProxyPrefs::StringToProxyMode("fixed_servers", &mode)); + EXPECT_EQ(ProxyPrefs::MODE_FIXED_SERVERS, mode); + + EXPECT_FALSE(ProxyPrefs::StringToProxyMode("monkey", &mode)); +} + +TEST(ProxyPrefsTest, IntToProxyMode) { + ASSERT_EQ(ProxyPrefs::MODE_DIRECT, 0); + ASSERT_EQ(ProxyPrefs::MODE_AUTO_DETECT, 1); + ASSERT_EQ(ProxyPrefs::MODE_PAC_SCRIPT, 2); + ASSERT_EQ(ProxyPrefs::MODE_FIXED_SERVERS, 3); + ASSERT_EQ(ProxyPrefs::MODE_SYSTEM, 4); + // Update the following as necessary, don't change the previous ones. + ASSERT_EQ(ProxyPrefs::kModeCount, 5); + + ProxyPrefs::ProxyMode mode; + EXPECT_TRUE(ProxyPrefs::IntToProxyMode(0, &mode)); + EXPECT_EQ(ProxyPrefs::MODE_DIRECT, mode); + EXPECT_TRUE(ProxyPrefs::IntToProxyMode(1, &mode)); + EXPECT_EQ(ProxyPrefs::MODE_AUTO_DETECT, mode); + EXPECT_TRUE(ProxyPrefs::IntToProxyMode(2, &mode)); + EXPECT_EQ(ProxyPrefs::MODE_PAC_SCRIPT, mode); + EXPECT_TRUE(ProxyPrefs::IntToProxyMode(3, &mode)); + EXPECT_EQ(ProxyPrefs::MODE_FIXED_SERVERS, mode); + EXPECT_TRUE(ProxyPrefs::IntToProxyMode(4, &mode)); + EXPECT_EQ(ProxyPrefs::MODE_SYSTEM, mode); + + EXPECT_FALSE(ProxyPrefs::IntToProxyMode(-1, &mode)); + EXPECT_FALSE(ProxyPrefs::IntToProxyMode(ProxyPrefs::kModeCount, &mode)); +} |