diff options
64 files changed, 1695 insertions, 1822 deletions
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index a98c45b..b9ed348 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd @@ -8512,7 +8512,7 @@ Keep your key file in a safe place. You will need it to create new versions of y <if expr="pp_ifdef('chromeos')"> <message name="IDS_OPTIONS_POLICY_MANAGED_PREFS" desc="Banner displayed in case there are policy-managed options the user won't be able to change."> - Some settings have been disabled by your administrator. + Some settings are being managed by your administrator. </message> <message name="IDS_OPTIONS_EXTENSION_MANAGED_PREFS" desc="Banner displayed in case there are extension-managed options the user won't be able to change."> Some settings are being managed by an extension. @@ -8520,6 +8520,9 @@ Keep your key file in a safe place. You will need it to create new versions of y <message name="IDS_OPTIONS_POLICY_EXTENSION_MANAGED_PREFS" desc="Banner displayed in case there are policy- and extension-managed options the user won't be able to change."> Some settings have been disabled by your administrator and others are being managed by an extension. </message> + <message name="IDS_OPTIONS_UNMODIFIABLE_PREFS" desc="Banner displayed in case there are options that the user won't be able to change."> + Some settings cannot be modified by the user. + </message> </if> <if expr="not pp_ifdef('chromeos') and is_posix"> <message name="IDS_OPTIONS_POLICY_MANAGED_PREFS" desc="Banner displayed in case there are policy-managed options the user won't be able to change."> @@ -12173,16 +12176,7 @@ Keep your key file in a safe place. You will need it to create new versions of y Change proxy settings... </message> <message name="IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_ENABLE_SHARED_PROXIES_HINT" desc="In settings Internet options, when proxy can't be changed, the hint for user to do so by enabling the setting for IDS_OPTIONS_SETTINGS_USE_SHARED_PROXIES."> - To change proxy settings, enable "<ph name="USE_SHARED_PROXIES">$1<ex>Allow proxies for shared networks</ex></ph>" setting. - </message> - <message name="IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_POLICY_MANAGED_PROXY_TEXT" desc="In settings Internet options, the text to display when proxy is policy-managed and user won't be able to change."> - Proxy settings have been disabled by your administrator. - </message> - <message name="IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_EXTENSION_MANAGED_PROXY_TEXT" desc="In settings Internet options, the text to display when proxy is extension-managed and user won't be able to change."> - Proxy settings are being managed by an extension. - </message> - <message name="IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_UNMODIFIABLE_PROXY_TEXT" desc="In settings Internet options, the text to display when proxy is not modifiable by user."> - Proxy settings cannot be modified by user. + To change proxy, enable "<ph name="USE_SHARED_PROXIES">$1<ex>Allow proxies for shared networks</ex></ph>" setting. </message> <message name="IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_HARDWARE_ADDRESS" desc="In settings Internet options, the label hardware address."> Hardware address: diff --git a/chrome/browser/automation/testing_automation_provider.cc b/chrome/browser/automation/testing_automation_provider.cc index fef9c88..8823643 100644 --- a/chrome/browser/automation/testing_automation_provider.cc +++ b/chrome/browser/automation/testing_automation_provider.cc @@ -2348,10 +2348,6 @@ void TestingAutomationProvider::SendJSONRequest(int handle, handler_map["NetworkScan"] = &TestingAutomationProvider::NetworkScan; handler_map["ToggleNetworkDevice"] = &TestingAutomationProvider::ToggleNetworkDevice; - handler_map["GetProxySettings"] = - &TestingAutomationProvider::GetProxySettings; - handler_map["SetProxySettings"] = - &TestingAutomationProvider::SetProxySettings; handler_map["ConnectToCellularNetwork"] = &TestingAutomationProvider::ConnectToCellularNetwork; handler_map["DisconnectFromCellularNetwork"] = @@ -2547,6 +2543,10 @@ void TestingAutomationProvider::SendJSONRequest(int handle, browser_handler_map["CaptureProfilePhoto"] = &TestingAutomationProvider::CaptureProfilePhoto; browser_handler_map["GetTimeInfo"] = &TestingAutomationProvider::GetTimeInfo; + browser_handler_map["GetProxySettings"] = + &TestingAutomationProvider::GetProxySettings; + browser_handler_map["SetProxySettings"] = + &TestingAutomationProvider::SetProxySettings; #endif // defined(OS_CHROMEOS) // Look for command in handlers that take a Browser handle. diff --git a/chrome/browser/automation/testing_automation_provider.h b/chrome/browser/automation/testing_automation_provider.h index c0e5d7b..69f1c7d 100644 --- a/chrome/browser/automation/testing_automation_provider.h +++ b/chrome/browser/automation/testing_automation_provider.h @@ -1255,10 +1255,12 @@ class TestingAutomationProvider : public AutomationProvider, void ToggleNetworkDevice(base::DictionaryValue* args, IPC::Message* reply_message); - void GetProxySettings(base::DictionaryValue* args, + void GetProxySettings(Browser* browser, + base::DictionaryValue* args, IPC::Message* reply_message); - void SetProxySettings(base::DictionaryValue* args, + void SetProxySettings(Browser* browser, + base::DictionaryValue* args, IPC::Message* reply_message); void ConnectToCellularNetwork(base::DictionaryValue* args, diff --git a/chrome/browser/automation/testing_automation_provider_chromeos.cc b/chrome/browser/automation/testing_automation_provider_chromeos.cc index 8258d73..bdfb531 100644 --- a/chrome/browser/automation/testing_automation_provider_chromeos.cc +++ b/chrome/browser/automation/testing_automation_provider_chromeos.cc @@ -68,8 +68,8 @@ DictionaryValue* GetNetworkInfoDict(const chromeos::Network* network) { return item; } -Value* GetProxySetting(const std::string& setting_name) { - chromeos::ProxyCrosSettingsProvider settings_provider; +Value* GetProxySetting(Browser* browser, const std::string& setting_name) { + chromeos::ProxyCrosSettingsProvider settings_provider(browser->profile()); std::string setting_path = "cros.session.proxy."; setting_path.append(setting_name); @@ -518,7 +518,8 @@ void TestingAutomationProvider::ToggleNetworkDevice( } } -void TestingAutomationProvider::GetProxySettings(DictionaryValue* args, +void TestingAutomationProvider::GetProxySettings(Browser* browser, + DictionaryValue* args, IPC::Message* reply_message) { const char* settings[] = { "pacurl", "singlehttp", "singlehttpport", "httpurl", "httpport", "httpsurl", "httpsport", @@ -526,10 +527,10 @@ void TestingAutomationProvider::GetProxySettings(DictionaryValue* args, "socks", "socksport", "ignorelist" }; scoped_ptr<DictionaryValue> return_value(new DictionaryValue); - chromeos::ProxyCrosSettingsProvider settings_provider; + chromeos::ProxyCrosSettingsProvider settings_provider(browser->profile()); for (size_t i = 0; i < arraysize(settings); ++i) { - Value* setting = GetProxySetting(settings[i]); + Value* setting = GetProxySetting(browser, settings[i]); if (setting) return_value->Set(settings[i], setting); } @@ -537,8 +538,9 @@ void TestingAutomationProvider::GetProxySettings(DictionaryValue* args, AutomationJSONReply(this, reply_message).SendSuccess(return_value.get()); } -void TestingAutomationProvider::SetProxySettings(DictionaryValue* args, - IPC::Message* reply_message) { +void TestingAutomationProvider::SetProxySettings(Browser* browser, + DictionaryValue* args, + IPC::Message* reply_message) { AutomationJSONReply reply(this, reply_message); std::string key; Value* value; @@ -551,7 +553,8 @@ void TestingAutomationProvider::SetProxySettings(DictionaryValue* args, setting_path.append(key); // ProxyCrosSettingsProvider will own the Value* passed to Set(). - chromeos::ProxyCrosSettingsProvider().Set(setting_path, value->DeepCopy()); + chromeos::ProxyCrosSettingsProvider(browser->profile()).Set(setting_path, + value->DeepCopy()); reply.SendSuccess(NULL); } diff --git a/chrome/browser/browser_process.h b/chrome/browser/browser_process.h index d61209d..58ad4fc 100644 --- a/chrome/browser/browser_process.h +++ b/chrome/browser/browser_process.h @@ -54,10 +54,6 @@ class Thread; namespace browser { class OomPriorityManager; } - -namespace chromeos { -class ProxyConfigServiceImpl; -} #endif // defined(OS_CHROMEOS) namespace net { @@ -111,10 +107,6 @@ class BrowserProcess { virtual net::URLRequestContextGetter* system_request_context() = 0; #if defined(OS_CHROMEOS) - // Returns ChromeOS's ProxyConfigServiceImpl, creating if not yet created. - virtual chromeos::ProxyConfigServiceImpl* - chromeos_proxy_config_service_impl() = 0; - // Returns the out-of-memory priority manager. virtual browser::OomPriorityManager* oom_priority_manager() = 0; #endif // defined(OS_CHROMEOS) diff --git a/chrome/browser/browser_process_impl.cc b/chrome/browser/browser_process_impl.cc index 55cdd5b..d1ef581 100644 --- a/chrome/browser/browser_process_impl.cc +++ b/chrome/browser/browser_process_impl.cc @@ -103,7 +103,6 @@ #endif #if defined(OS_CHROMEOS) -#include "chrome/browser/chromeos/proxy_config_service_impl.h" #include "chrome/browser/chromeos/web_socket_proxy_controller.h" #include "chrome/browser/oom_priority_manager.h" #endif // defined(OS_CHROMEOS) @@ -498,16 +497,6 @@ net::URLRequestContextGetter* BrowserProcessImpl::system_request_context() { } #if defined(OS_CHROMEOS) -chromeos::ProxyConfigServiceImpl* -BrowserProcessImpl::chromeos_proxy_config_service_impl() { - DCHECK(CalledOnValidThread()); - if (!chromeos_proxy_config_service_impl_) { - chromeos_proxy_config_service_impl_ = - new chromeos::ProxyConfigServiceImpl(); - } - return chromeos_proxy_config_service_impl_; -} - browser::OomPriorityManager* BrowserProcessImpl::oom_priority_manager() { DCHECK(CalledOnValidThread()); if (!oom_priority_manager_.get()) diff --git a/chrome/browser/browser_process_impl.h b/chrome/browser/browser_process_impl.h index 4bb6a7b..5c0ced3 100644 --- a/chrome/browser/browser_process_impl.h +++ b/chrome/browser/browser_process_impl.h @@ -68,8 +68,6 @@ class BrowserProcessImpl : public BrowserProcess, virtual ui::Clipboard* clipboard() OVERRIDE; virtual net::URLRequestContextGetter* system_request_context() OVERRIDE; #if defined(OS_CHROMEOS) - virtual chromeos::ProxyConfigServiceImpl* - chromeos_proxy_config_service_impl() OVERRIDE; virtual browser::OomPriorityManager* oom_priority_manager() OVERRIDE; #endif // defined(OS_CHROMEOS) virtual ExtensionEventRouterForwarder* @@ -309,8 +307,6 @@ class BrowserProcessImpl : public BrowserProcess, #endif // defined(OS_WIN) || defined(OS_LINUX) #if defined(OS_CHROMEOS) - scoped_refptr<chromeos::ProxyConfigServiceImpl> - chromeos_proxy_config_service_impl_; scoped_ptr<browser::OomPriorityManager> oom_priority_manager_; #endif diff --git a/chrome/browser/chromeos/cros/network_library.cc b/chrome/browser/chromeos/cros/network_library.cc index adfa8b9..3e2e994 100644 --- a/chrome/browser/chromeos/cros/network_library.cc +++ b/chrome/browser/chromeos/cros/network_library.cc @@ -4812,14 +4812,14 @@ void NetworkLibraryImplStub::Init() { ethernet->set_name("Fake Ethernet"); ethernet->set_is_active(true); ethernet->set_connected(true); - AddStubNetwork(ethernet, PROFILE_NONE); + AddStubNetwork(ethernet, PROFILE_SHARED); WifiNetwork* wifi1 = new WifiNetwork("wifi1"); wifi1->set_name("Fake WiFi1"); wifi1->set_strength(100); wifi1->set_connected(true); wifi1->set_encryption(SECURITY_NONE); - AddStubNetwork(wifi1, PROFILE_NONE); + AddStubNetwork(wifi1, PROFILE_SHARED); WifiNetwork* wifi2 = new WifiNetwork("wifi2"); wifi2->set_name("Fake WiFi2"); diff --git a/chrome/browser/chromeos/preferences.cc b/chrome/browser/chromeos/preferences.cc index 8ec40c6..4aee054f 100644 --- a/chrome/browser/chromeos/preferences.cc +++ b/chrome/browser/chromeos/preferences.cc @@ -17,7 +17,6 @@ #include "chrome/browser/chromeos/input_method/input_method_util.h" #include "chrome/browser/chromeos/input_method/xkeyboard.h" #include "chrome/browser/chromeos/login/login_utils.h" -#include "chrome/browser/chromeos/proxy_config_service_impl.h" #include "chrome/browser/chromeos/system/touchpad_settings.h" #include "chrome/browser/prefs/pref_member.h" #include "chrome/browser/prefs/pref_service.h" @@ -27,6 +26,7 @@ #include "chrome/common/pref_names.h" #include "content/public/browser/notification_details.h" #include "content/public/browser/notification_source.h" +#include "googleurl/src/gurl.h" #include "unicode/timezone.h" namespace chromeos { @@ -195,11 +195,6 @@ void Preferences::RegisterUserPrefs(PrefService* prefs) { true, PrefService::UNSYNCABLE_PREF); - // Use shared proxies default to off. - prefs->RegisterBooleanPref(prefs::kUseSharedProxies, - false, - PrefService::SYNCABLE_PREF); - // OAuth1 all access token and secret pair. prefs->RegisterStringPref(prefs::kOAuth1Token, "", @@ -275,8 +270,6 @@ void Preferences::Init(PrefService* prefs) { enable_screen_lock_.Init(prefs::kEnableScreenLock, prefs, this); - use_shared_proxies_.Init(prefs::kUseSharedProxies, prefs, this); - // Initialize preferences to currently saved state. NotifyPrefChanged(NULL); @@ -466,11 +459,6 @@ void Preferences::NotifyPrefChanged(const std::string* pref_name) { CrosLibrary::Get()->GetPowerLibrary()->EnableScreenLock( enable_screen_lock_.GetValue()); } - - if (!pref_name || *pref_name == prefs::kUseSharedProxies) { - g_browser_process->chromeos_proxy_config_service_impl()-> - UISetUseSharedProxies(use_shared_proxies_.GetValue()); - } } void Preferences::SetLanguageConfigBoolean(const char* section, diff --git a/chrome/browser/chromeos/preferences.h b/chrome/browser/chromeos/preferences.h index 6c593e1..3566986 100644 --- a/chrome/browser/chromeos/preferences.h +++ b/chrome/browser/chromeos/preferences.h @@ -128,8 +128,6 @@ class Preferences : public content::NotificationObserver { BooleanPrefMember enable_screen_lock_; - BooleanPrefMember use_shared_proxies_; - DISALLOW_COPY_AND_ASSIGN(Preferences); }; diff --git a/chrome/browser/chromeos/proxy_config_service.cc b/chrome/browser/chromeos/proxy_config_service.cc deleted file mode 100644 index b4668fd..0000000 --- a/chrome/browser/chromeos/proxy_config_service.cc +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) 2011 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/chromeos/proxy_config_service.h" - -namespace chromeos { - -ProxyConfigService::ProxyConfigService( - const scoped_refptr<ProxyConfigServiceImpl>& impl) - : impl_(impl) { -} - -ProxyConfigService::~ProxyConfigService() {} - -void ProxyConfigService::AddObserver(Observer* observer) { - impl_->AddObserver(observer); -} - -void ProxyConfigService::RemoveObserver(Observer* observer) { - impl_->RemoveObserver(observer); -} - -ProxyConfigService::ConfigAvailability ProxyConfigService::GetLatestProxyConfig( - net::ProxyConfig* config) { - return impl_->IOGetProxyConfig(config); -} - -} // namespace chromeos diff --git a/chrome/browser/chromeos/proxy_config_service.h b/chrome/browser/chromeos/proxy_config_service.h deleted file mode 100644 index 955c775..0000000 --- a/chrome/browser/chromeos/proxy_config_service.h +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) 2011 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_CHROMEOS_PROXY_CONFIG_SERVICE_H_ -#define CHROME_BROWSER_CHROMEOS_PROXY_CONFIG_SERVICE_H_ -#pragma once - -#include "chrome/browser/chromeos/proxy_config_service_impl.h" - -namespace chromeos { - -// Wrapper class for the RefCountedThreadSafe chromeos::ProxyConfigServiceImpl -// that forwards net::ProxyConfigService interface to the actual implementation, -// instantiated in ProfileIOData::CreateProxyConfigService. -class ProxyConfigService : public net::ProxyConfigService { - public: - explicit ProxyConfigService( - const scoped_refptr<ProxyConfigServiceImpl>& impl); - virtual ~ProxyConfigService(); - - // ProxyConfigService methods. Called from IO thread. - virtual void AddObserver(Observer* observer); - virtual void RemoveObserver(Observer* observer); - virtual ConfigAvailability GetLatestProxyConfig(net::ProxyConfig* config); - - private: - scoped_refptr<ProxyConfigServiceImpl> impl_; - - DISALLOW_COPY_AND_ASSIGN(ProxyConfigService); -}; - -} // namespace chromeos - -#endif // CHROME_BROWSER_CHROMEOS_PROXY_CONFIG_SERVICE_H_ diff --git a/chrome/browser/chromeos/proxy_config_service_impl.cc b/chrome/browser/chromeos/proxy_config_service_impl.cc index 6aec3c3..7d18ba4 100644 --- a/chrome/browser/chromeos/proxy_config_service_impl.cc +++ b/chrome/browser/chromeos/proxy_config_service_impl.cc @@ -6,72 +6,99 @@ #include <ostream> +#include "base/bind.h" #include "base/json/json_value_serializer.h" #include "base/logging.h" #include "base/string_util.h" -#include "base/task.h" #include "chrome/browser/chromeos/cros/cros_library.h" #include "chrome/browser/chromeos/cros_settings_names.h" +#include "chrome/browser/chromeos/login/user_manager.h" #include "chrome/browser/policy/proto/chrome_device_policy.pb.h" +#include "chrome/browser/prefs/pref_service.h" #include "chrome/browser/prefs/proxy_config_dictionary.h" #include "chrome/browser/prefs/proxy_prefs.h" -#include "content/public/browser/browser_thread.h" +#include "chrome/browser/profiles/profile_manager.h" +#include "chrome/common/chrome_notification_types.h" +#include "chrome/common/pref_names.h" +#include "content/public/browser/notification_service.h" #include "grit/generated_resources.h" #include "ui/base/l10n/l10n_util.h" -using content::BrowserThread; - namespace em = enterprise_management; namespace chromeos { namespace { -const char* SourceToString(ProxyConfigServiceImpl::ProxyConfig::Source source) { - switch (source) { - case ProxyConfigServiceImpl::ProxyConfig::SOURCE_NONE: - return "SOURCE_NONE"; - case ProxyConfigServiceImpl::ProxyConfig::SOURCE_POLICY: - return "SOURCE_POLICY"; - case ProxyConfigServiceImpl::ProxyConfig::SOURCE_OWNER: - return "SOURCE_OWNER"; +const char* ModeToString(ProxyConfigServiceImpl::ProxyConfig::Mode mode) { + switch (mode) { + case ProxyConfigServiceImpl::ProxyConfig::MODE_DIRECT: + return "direct"; + case ProxyConfigServiceImpl::ProxyConfig::MODE_AUTO_DETECT: + return "auto-detect"; + case ProxyConfigServiceImpl::ProxyConfig::MODE_PAC_SCRIPT: + return "pacurl"; + case ProxyConfigServiceImpl::ProxyConfig::MODE_SINGLE_PROXY: + return "single-proxy"; + case ProxyConfigServiceImpl::ProxyConfig::MODE_PROXY_PER_SCHEME: + return "proxy-per-scheme"; } - NOTREACHED() << "Unrecognized source type"; + NOTREACHED() << "Unrecognized mode type"; return ""; } -std::ostream& operator<<(std::ostream& out, +const char* ConfigStateToString(ProxyPrefs::ConfigState state) { + switch (state) { + case ProxyPrefs::CONFIG_POLICY: + return "config_policy"; + case ProxyPrefs::CONFIG_EXTENSION: + return "config_extension"; + case ProxyPrefs::CONFIG_OTHER_PRECEDE: + return "config_other_precede"; + case ProxyPrefs::CONFIG_SYSTEM: + return "config_network"; // For ChromeOS, system is network. + case ProxyPrefs::CONFIG_FALLBACK: + return "config_recommended"; // Fallback is recommended. + case ProxyPrefs::CONFIG_UNSET: + return "config_unset"; + } + NOTREACHED() << "Unrecognized config state type"; + return ""; +} + +// Only unblock if needed for debugging. +#if defined(NEED_DEBUG_LOG) +std::ostream& operator<<( + std::ostream& out, const ProxyConfigServiceImpl::ProxyConfig::ManualProxy& proxy) { - out << " " << SourceToString(proxy.source) << "\n" - << " server: " << (proxy.server.is_valid() ? proxy.server.ToURI() : "") - << "\n"; + out << (proxy.server.is_valid() ? proxy.server.ToURI() : "") << "\n"; return out; } std::ostream& operator<<(std::ostream& out, - const ProxyConfigServiceImpl::ProxyConfig& config) { + const ProxyConfigServiceImpl::ProxyConfig& config) { switch (config.mode) { case ProxyConfigServiceImpl::ProxyConfig::MODE_DIRECT: - out << "Direct connection:\n " - << SourceToString(config.automatic_proxy.source) << "\n"; - break; case ProxyConfigServiceImpl::ProxyConfig::MODE_AUTO_DETECT: - out << "Auto detection:\n " - << SourceToString(config.automatic_proxy.source) << "\n"; + out << ModeToString(config.mode) << ", " + << ConfigStateToString(config.state) << "\n"; break; case ProxyConfigServiceImpl::ProxyConfig::MODE_PAC_SCRIPT: - out << "Custom PAC script:\n " - << SourceToString(config.automatic_proxy.source) + out << ModeToString(config.mode) << ", " + << ConfigStateToString(config.state) << "\n PAC: " << config.automatic_proxy.pac_url << "\n"; break; case ProxyConfigServiceImpl::ProxyConfig::MODE_SINGLE_PROXY: - out << "Single proxy:\n" << config.single_proxy; + out << ModeToString(config.mode) << ", " + << ConfigStateToString(config.state) << "\n " << config.single_proxy; break; case ProxyConfigServiceImpl::ProxyConfig::MODE_PROXY_PER_SCHEME: - out << "HTTP proxy: " << config.http_proxy; - out << "HTTPS proxy: " << config.https_proxy; - out << "FTP proxy: " << config.ftp_proxy; - out << "SOCKS proxy: " << config.socks_proxy; + out << ModeToString(config.mode) << ", " + << ConfigStateToString(config.state) << "\n" + << " HTTP: " << config.http_proxy + << " HTTPS: " << config.https_proxy + << " FTP: " << config.ftp_proxy + << " SOCKS: " << config.socks_proxy; break; default: NOTREACHED() << "Unrecognized proxy config mode"; @@ -101,85 +128,102 @@ std::string ProxyConfigToString( stream << proxy_config; return stream.str(); } +#endif // defined(NEED_DEBUG_LOG) } // namespace -//---------- ProxyConfigServiceImpl::ProxyConfig::Setting methods -------------- - -bool ProxyConfigServiceImpl::ProxyConfig::Setting::CanBeWrittenByUser( - bool user_is_owner) { - // Setting can only be written by user if user is owner and setting is not - // from policy. - return user_is_owner && source != ProxyConfig::SOURCE_POLICY; -} - //----------- ProxyConfigServiceImpl::ProxyConfig: public methods -------------- -ProxyConfigServiceImpl::ProxyConfig::ProxyConfig() : mode(MODE_DIRECT) {} +ProxyConfigServiceImpl::ProxyConfig::ProxyConfig() + : mode(MODE_DIRECT), + state(ProxyPrefs::CONFIG_UNSET), + user_modifiable(true) {} ProxyConfigServiceImpl::ProxyConfig::~ProxyConfig() {} -void ProxyConfigServiceImpl::ProxyConfig::ToNetProxyConfig( - net::ProxyConfig* net_config) { - switch (mode) { - case MODE_DIRECT: - *net_config = net::ProxyConfig::CreateDirect(); - break; - case MODE_AUTO_DETECT: - *net_config = net::ProxyConfig::CreateAutoDetect(); - break; - case MODE_PAC_SCRIPT: - *net_config = net::ProxyConfig::CreateFromCustomPacURL( - automatic_proxy.pac_url); - break; - case MODE_SINGLE_PROXY: - *net_config = net::ProxyConfig(); - net_config->proxy_rules().type = - net::ProxyConfig::ProxyRules::TYPE_SINGLE_PROXY; - net_config->proxy_rules().single_proxy = single_proxy.server; - net_config->proxy_rules().bypass_rules = bypass_rules; - break; - case MODE_PROXY_PER_SCHEME: - *net_config = net::ProxyConfig(); - net_config->proxy_rules().type = - net::ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME; - net_config->proxy_rules().proxy_for_http = http_proxy.server; - net_config->proxy_rules().proxy_for_https = https_proxy.server; - net_config->proxy_rules().proxy_for_ftp = ftp_proxy.server; - net_config->proxy_rules().fallback_proxy = socks_proxy.server; - net_config->proxy_rules().bypass_rules = bypass_rules; - break; +bool ProxyConfigServiceImpl::ProxyConfig::FromNetProxyConfig( + const net::ProxyConfig& net_config) { + *this = ProxyConfigServiceImpl::ProxyConfig(); // Reset to default. + const net::ProxyConfig::ProxyRules& rules = net_config.proxy_rules(); + switch (rules.type) { + case net::ProxyConfig::ProxyRules::TYPE_NO_RULES: + if (!net_config.HasAutomaticSettings()) { + mode = ProxyConfig::MODE_DIRECT; + } else if (net_config.auto_detect()) { + mode = ProxyConfig::MODE_AUTO_DETECT; + } else if (net_config.has_pac_url()) { + mode = ProxyConfig::MODE_PAC_SCRIPT; + automatic_proxy.pac_url = net_config.pac_url(); + } else { + return false; + } + return true; + case net::ProxyConfig::ProxyRules::TYPE_SINGLE_PROXY: + if (!rules.single_proxy.is_valid()) + return false; + mode = MODE_SINGLE_PROXY; + single_proxy.server = rules.single_proxy; + bypass_rules = rules.bypass_rules; + return true; + case net::ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME: + // Make sure we have valid server for at least one of the protocols. + if (!rules.proxy_for_http.is_valid() && + !rules.proxy_for_https.is_valid() && + !rules.proxy_for_ftp.is_valid() && + !rules.fallback_proxy.is_valid()) { + return false; + } + mode = MODE_PROXY_PER_SCHEME; + if (rules.proxy_for_http.is_valid()) + http_proxy.server = rules.proxy_for_http; + if (rules.proxy_for_https.is_valid()) + https_proxy.server = rules.proxy_for_https; + if (rules.proxy_for_ftp.is_valid()) + ftp_proxy.server = rules.proxy_for_ftp; + if (rules.fallback_proxy.is_valid()) + socks_proxy.server = rules.fallback_proxy; + bypass_rules = rules.bypass_rules; + return true; default: NOTREACHED() << "Unrecognized proxy config mode"; break; } + return false; } -bool ProxyConfigServiceImpl::ProxyConfig::CanBeWrittenByUser( - bool user_is_owner, const std::string& scheme) { - // Setting can only be written by user if user is owner and setting is not - // from policy. - Setting* setting = NULL; +DictionaryValue* ProxyConfigServiceImpl::ProxyConfig::ToPrefProxyConfig() { switch (mode) { - case MODE_DIRECT: - case MODE_AUTO_DETECT: - case MODE_PAC_SCRIPT: - setting = &automatic_proxy; - break; - case MODE_SINGLE_PROXY: - setting = &single_proxy; - break; - case MODE_PROXY_PER_SCHEME: - setting = MapSchemeToProxy(scheme); - break; + case MODE_DIRECT: { + return ProxyConfigDictionary::CreateDirect(); + } + case MODE_AUTO_DETECT: { + return ProxyConfigDictionary::CreateAutoDetect(); + } + case MODE_PAC_SCRIPT: { + return ProxyConfigDictionary::CreatePacScript( + automatic_proxy.pac_url.spec(), false); + } + case MODE_SINGLE_PROXY: { + std::string spec; + if (single_proxy.server.is_valid()) + spec = single_proxy.server.ToURI(); + return ProxyConfigDictionary::CreateFixedServers( + spec, bypass_rules.ToString()); + } + case MODE_PROXY_PER_SCHEME: { + std::string spec; + EncodeAndAppendProxyServer("http", http_proxy.server, &spec); + EncodeAndAppendProxyServer("https", https_proxy.server, &spec); + EncodeAndAppendProxyServer("ftp", ftp_proxy.server, &spec); + EncodeAndAppendProxyServer("socks", socks_proxy.server, &spec); + return ProxyConfigDictionary::CreateFixedServers( + spec, bypass_rules.ToString()); + } default: break; } - if (!setting) { - NOTREACHED() << "Unrecognized proxy config mode"; - return false; - } - return setting->CanBeWrittenByUser(user_is_owner); + NOTREACHED() << "Unrecognized proxy config mode for preference"; + return NULL; } ProxyConfigServiceImpl::ProxyConfig::ManualProxy* @@ -263,47 +307,6 @@ bool ProxyConfigServiceImpl::ProxyConfig::SerializeForNetwork( return serializer.Serialize(*proxy_dict.get()); } -bool ProxyConfigServiceImpl::ProxyConfig::DeserializeForNetwork( - const std::string& input) { - JSONStringValueSerializer serializer(input); - scoped_ptr<Value> value(serializer.Deserialize(NULL, NULL)); - if (!value.get() || value->GetType() != Value::TYPE_DICTIONARY) - return false; - DictionaryValue* proxy_dict = static_cast<DictionaryValue*>(value.get()); - return FromPrefProxyConfig(proxy_dict); -} - -bool ProxyConfigServiceImpl::ProxyConfig::Equals( - const ProxyConfig& other) const { - if (mode != other.mode) - return false; - switch (mode) { - case MODE_DIRECT: - case MODE_AUTO_DETECT: - return true; - case MODE_PAC_SCRIPT: - return automatic_proxy.pac_url == other.automatic_proxy.pac_url; - case MODE_SINGLE_PROXY: - return single_proxy.server == other.single_proxy.server && - bypass_rules.Equals(other.bypass_rules); - case MODE_PROXY_PER_SCHEME: - return http_proxy.server == other.http_proxy.server && - https_proxy.server == other.https_proxy.server && - ftp_proxy.server == other.ftp_proxy.server && - socks_proxy.server == other.socks_proxy.server && - bypass_rules.Equals(other.bypass_rules); - default: { - NOTREACHED() << "Unrecognized proxy config mode"; - break; - } - } - return false; -} - -std::string ProxyConfigServiceImpl::ProxyConfig::ToString() const { - return ProxyConfigToString(*this); -} - //----------- ProxyConfigServiceImpl::ProxyConfig: private methods ------------- // static @@ -324,154 +327,37 @@ void ProxyConfigServiceImpl::ProxyConfig::EncodeAndAppendProxyServer( *spec += server.ToURI(); } -DictionaryValue* ProxyConfigServiceImpl::ProxyConfig::ToPrefProxyConfig() { - switch (mode) { - case MODE_DIRECT: { - return ProxyConfigDictionary::CreateDirect(); - } - case MODE_AUTO_DETECT: { - return ProxyConfigDictionary::CreateAutoDetect(); - } - case MODE_PAC_SCRIPT: { - return ProxyConfigDictionary::CreatePacScript( - automatic_proxy.pac_url.spec(), false); - } - case MODE_SINGLE_PROXY: { - std::string spec; - if (single_proxy.server.is_valid()) - spec = single_proxy.server.ToURI(); - return ProxyConfigDictionary::CreateFixedServers( - spec, bypass_rules.ToString()); - } - case MODE_PROXY_PER_SCHEME: { - std::string spec; - EncodeAndAppendProxyServer("http", http_proxy.server, &spec); - EncodeAndAppendProxyServer("https", https_proxy.server, &spec); - EncodeAndAppendProxyServer("ftp", ftp_proxy.server, &spec); - EncodeAndAppendProxyServer("socks", socks_proxy.server, &spec); - return ProxyConfigDictionary::CreateFixedServers( - spec, bypass_rules.ToString()); - } - default: - break; - } - NOTREACHED() << "Unrecognized proxy config mode for preference"; - return NULL; -} - -bool ProxyConfigServiceImpl::ProxyConfig::FromPrefProxyConfig( - const DictionaryValue* dict) { - ProxyConfigDictionary proxy_dict(dict); - - *this = ProxyConfigServiceImpl::ProxyConfig(); // Reset to default. - - ProxyPrefs::ProxyMode proxy_mode; - if (!proxy_dict.GetMode(&proxy_mode)) { - // Fall back to system settings if the mode preference is invalid. - return false; - } +//------------------- ProxyConfigServiceImpl: public methods ------------------- - switch (proxy_mode) { - case ProxyPrefs::MODE_SYSTEM: - // Use system settings, so we shouldn't use |this| proxy config. - 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: - mode = MODE_AUTO_DETECT; - return true; - case ProxyPrefs::MODE_PAC_SCRIPT: { - std::string proxy_pac; - if (!proxy_dict.GetPacUrl(&proxy_pac)) { - LOG(ERROR) << "Proxy settings request PAC script but do not specify " - << "its URL. Falling back to direct connection."; - return true; - } - GURL proxy_pac_url(proxy_pac); - if (!proxy_pac_url.is_valid()) { - LOG(ERROR) << "Invalid proxy PAC url: " << proxy_pac; - return true; - } - mode = MODE_PAC_SCRIPT; - automatic_proxy.pac_url = proxy_pac_url; - return true; - } - case ProxyPrefs::MODE_FIXED_SERVERS: { - std::string proxy_server; - if (!proxy_dict.GetProxyServer(&proxy_server)) { - LOG(ERROR) << "Proxy settings request fixed proxy servers but do not " - << "specify their URLs. Falling back to direct connection."; - return true; - } - net::ProxyConfig::ProxyRules proxy_rules; - proxy_rules.ParseFromString(proxy_server); - if (proxy_rules.type == net::ProxyConfig::ProxyRules::TYPE_SINGLE_PROXY) { - mode = MODE_SINGLE_PROXY; - single_proxy.server = proxy_rules.single_proxy; - } else if (proxy_rules.type == - net::ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME) { - mode = MODE_PROXY_PER_SCHEME; - http_proxy.server = proxy_rules.proxy_for_http; - https_proxy.server = proxy_rules.proxy_for_https; - ftp_proxy.server = proxy_rules.proxy_for_ftp; - socks_proxy.server = proxy_rules.fallback_proxy; - } else { - LOG(ERROR) << "Proxy settings request fixed proxy servers but do not " - << "have valid proxy rules type. " - << "Falling back to direct connection."; - return true; - } +ProxyConfigServiceImpl::ProxyConfigServiceImpl(PrefService* pref_service) + : PrefProxyConfigTrackerImpl(pref_service), + active_config_state_(ProxyPrefs::CONFIG_UNSET) { - std::string proxy_bypass; - if (proxy_dict.GetBypassList(&proxy_bypass)) { - bypass_rules.ParseFromString(proxy_bypass); - } - return true; - } - case ProxyPrefs::kModeCount: { - // Fall through to NOTREACHED(). - } - } - NOTREACHED() << "Unknown proxy mode, falling back to system settings."; - return false; -} + // Register for notification when user logs in, so that we can activate the + // new proxy config. + registrar_.Add(this, chrome::NOTIFICATION_LOGIN_USER_CHANGED, + content::NotificationService::AllSources()); -//------------------- ProxyConfigServiceImpl: public methods ------------------- + // Register for notifications of UseSharedProxies user preference. + if (pref_service->FindPreference(prefs::kUseSharedProxies)) + use_shared_proxies_.Init(prefs::kUseSharedProxies, pref_service, this); -ProxyConfigServiceImpl::ProxyConfigServiceImpl() - : testing_(false), - can_post_task_(false), - config_availability_(net::ProxyConfigService::CONFIG_UNSET), - use_shared_proxies_(true) { // Start async fetch of proxy config from settings persisted on device. - if (CrosLibrary::Get()->EnsureLoaded()) { + if (CrosLibrary::Get()->libcros_loaded()) { retrieve_property_op_ = SignedSettings::CreateRetrievePropertyOp( kSettingProxyEverywhere, this); if (retrieve_property_op_) { retrieve_property_op_->Execute(); - VLOG(1) << "Start retrieving proxy setting from device"; + VLOG(1) << this << ": Start retrieving proxy setting from device"; } else { - VLOG(1) << "Fail to retrieve proxy setting from device"; + VLOG(1) << this << ": Fail to retrieve proxy setting from device"; } } + // Register for flimflam network notifications. NetworkLibrary* network_lib = CrosLibrary::Get()->GetNetworkLibrary(); OnActiveNetworkChanged(network_lib, network_lib->active_network()); network_lib->AddNetworkManagerObserver(this); - - can_post_task_ = true; -} - -ProxyConfigServiceImpl::ProxyConfigServiceImpl(const ProxyConfig& init_config) - : testing_(false), - can_post_task_(true), - config_availability_(net::ProxyConfigService::CONFIG_VALID), - use_shared_proxies_(true) { - active_config_ = init_config; - // Update the IO-accessible copy in |cached_config_| as well. - cached_config_ = active_config_; } ProxyConfigServiceImpl::~ProxyConfigServiceImpl() { @@ -482,108 +368,69 @@ ProxyConfigServiceImpl::~ProxyConfigServiceImpl() { } } -void ProxyConfigServiceImpl::UIGetProxyConfig(ProxyConfig* config) { - // Should be called from UI thread. - CheckCurrentlyOnUIThread(); - // Simply returns the copy on the UI thread. - *config = current_ui_config_; -} - -bool ProxyConfigServiceImpl::UISetCurrentNetwork( +void ProxyConfigServiceImpl::UISetCurrentNetwork( const std::string& current_network) { - // Should be called from UI thread. - CheckCurrentlyOnUIThread(); - if (current_ui_network_ == current_network) - return false; Network* network = CrosLibrary::Get()->GetNetworkLibrary()->FindNetworkByPath( current_network); if (!network) { + ResetUICache(); LOG(ERROR) << "can't find requested network " << current_network; - return false; + return; } current_ui_network_ = current_network; - current_ui_config_ = ProxyConfig(); - SetCurrentNetworkName(network); - if (!network->proxy_config().empty()) - current_ui_config_.DeserializeForNetwork(network->proxy_config()); - VLOG(1) << "current ui network: " - << (current_ui_network_name_.empty() ? - current_ui_network_ : current_ui_network_name_) - << ", proxy mode: " << current_ui_config_.mode; - return true; + OnUISetCurrentNetwork(network); } -bool ProxyConfigServiceImpl::UIMakeActiveNetworkCurrent() { - // Should be called from UI thread. - CheckCurrentlyOnUIThread(); - if (current_ui_network_ == active_network_) - return false; - Network* network = NULL; - if (!testing_) { - network = CrosLibrary::Get()->GetNetworkLibrary()->FindNetworkByPath( +void ProxyConfigServiceImpl::UIMakeActiveNetworkCurrent() { + Network* network = CrosLibrary::Get()->GetNetworkLibrary()->FindNetworkByPath( active_network_); - if (!network) { - LOG(ERROR) << "can't find requested network " << active_network_; - return false; - } + if (!network) { + ResetUICache(); + LOG(ERROR) << "can't find requested network " << active_network_; + return; } current_ui_network_ = active_network_; - current_ui_config_ = active_config_; - SetCurrentNetworkName(network); - VLOG(1) << "current ui network: " - << (current_ui_network_name_.empty() ? - current_ui_network_ : current_ui_network_name_) - << ", proxy mode: " << current_ui_config_.mode; - return true; + OnUISetCurrentNetwork(network); } -void ProxyConfigServiceImpl::UISetUseSharedProxies(bool use_shared) { - // Should be called from UI thread. - CheckCurrentlyOnUIThread(); - - // Reset all UI-related variables so that the next opening of proxy - // configuration dialog of any network will trigger javascript reloading of - // (possibly) new proxy settings. - current_ui_network_.clear(); - current_ui_network_name_.clear(); - current_ui_config_ = ProxyConfig(); - - if (use_shared_proxies_ == use_shared) { - VLOG(1) << "same use_shared_proxies = " << use_shared_proxies_; - return; - } - use_shared_proxies_ = use_shared; - VLOG(1) << "new use_shared_proxies = " << use_shared_proxies_; - if (active_network_.empty()) +void ProxyConfigServiceImpl::UIGetCurrentNetworkName( + std::string* network_name) { + if (!network_name) return; + network_name->clear(); Network* network = CrosLibrary::Get()->GetNetworkLibrary()->FindNetworkByPath( - active_network_); + current_ui_network_); if (!network) { - LOG(ERROR) << "can't find requested network " << active_network_; + LOG(ERROR) << "can't find requested network " << current_ui_network_; return; } - DetermineConfigFromNetwork(network); + if (network->name().empty() && network->type() == chromeos::TYPE_ETHERNET) { + *network_name = + l10n_util::GetStringUTF8(IDS_STATUSBAR_NETWORK_DEVICE_ETHERNET); + } else { + *network_name = network->name(); + } +} + +void ProxyConfigServiceImpl::UIGetProxyConfig(ProxyConfig* config) { + // Simply returns the copy last set from UI via UISetCurrentNetwork or + // UIMakeActiveNetworkCurrent. + *config = current_ui_config_; } bool ProxyConfigServiceImpl::UISetProxyConfigToDirect() { - // Should be called from UI thread. - CheckCurrentlyOnUIThread(); current_ui_config_.mode = ProxyConfig::MODE_DIRECT; OnUISetProxyConfig(); return true; } bool ProxyConfigServiceImpl::UISetProxyConfigToAutoDetect() { - // Should be called from UI thread. - CheckCurrentlyOnUIThread(); current_ui_config_.mode = ProxyConfig::MODE_AUTO_DETECT; OnUISetProxyConfig(); return true; } bool ProxyConfigServiceImpl::UISetProxyConfigToPACScript(const GURL& pac_url) { - // Should be called from UI thread. - CheckCurrentlyOnUIThread(); current_ui_config_.mode = ProxyConfig::MODE_PAC_SCRIPT; current_ui_config_.automatic_proxy.pac_url = pac_url; OnUISetProxyConfig(); @@ -592,8 +439,6 @@ bool ProxyConfigServiceImpl::UISetProxyConfigToPACScript(const GURL& pac_url) { bool ProxyConfigServiceImpl::UISetProxyConfigToSingleProxy( const net::ProxyServer& server) { - // Should be called from UI thread. - CheckCurrentlyOnUIThread(); current_ui_config_.mode = ProxyConfig::MODE_SINGLE_PROXY; current_ui_config_.single_proxy.server = server; OnUISetProxyConfig(); @@ -602,8 +447,6 @@ bool ProxyConfigServiceImpl::UISetProxyConfigToSingleProxy( bool ProxyConfigServiceImpl::UISetProxyConfigToProxyPerScheme( const std::string& scheme, const net::ProxyServer& server) { - // Should be called from UI thread. - CheckCurrentlyOnUIThread(); ProxyConfig::ManualProxy* proxy = current_ui_config_.MapSchemeToProxy(scheme); if (!proxy) { NOTREACHED() << "Cannot set proxy: invalid scheme [" << scheme << "]"; @@ -617,8 +460,6 @@ bool ProxyConfigServiceImpl::UISetProxyConfigToProxyPerScheme( bool ProxyConfigServiceImpl::UISetProxyConfigBypassRules( const net::ProxyBypassRules& bypass_rules) { - // Should be called from UI thread. - CheckCurrentlyOnUIThread(); if (current_ui_config_.mode != ProxyConfig::MODE_SINGLE_PROXY && current_ui_config_.mode != ProxyConfig::MODE_PROXY_PER_SCHEME) { NOTREACHED(); @@ -631,29 +472,19 @@ bool ProxyConfigServiceImpl::UISetProxyConfigBypassRules( return true; } -void ProxyConfigServiceImpl::AddObserver( - net::ProxyConfigService::Observer* observer) { - // Should be called from IO thread. - CheckCurrentlyOnIOThread(); - observers_.AddObserver(observer); -} - -void ProxyConfigServiceImpl::RemoveObserver( - net::ProxyConfigService::Observer* observer) { - // Should be called from IO thread. - CheckCurrentlyOnIOThread(); - observers_.RemoveObserver(observer); -} - -net::ProxyConfigService::ConfigAvailability - ProxyConfigServiceImpl::IOGetProxyConfig(net::ProxyConfig* net_config) { - // Should be called from IO thread. - CheckCurrentlyOnIOThread(); - if (config_availability_ == net::ProxyConfigService::CONFIG_VALID) { - VLOG(1) << "returning proxy mode=" << cached_config_.mode; - cached_config_.ToNetProxyConfig(net_config); +void ProxyConfigServiceImpl::OnProxyConfigChanged( + ProxyPrefs::ConfigState config_state, + const net::ProxyConfig& config) { + VLOG(1) << this << ": got prefs change: " << ConfigStateToString(config_state) + << ", mode=" << config.proxy_rules().type; + Network* network = NULL; + if (!active_network_.empty()) { + network = CrosLibrary::Get()->GetNetworkLibrary()->FindNetworkByPath( + active_network_); + if (!network) + LOG(ERROR) << "can't find requested network " << active_network_; } - return config_availability_; + DetermineEffectiveConfig(network, true); } void ProxyConfigServiceImpl::OnSettingsOpCompleted( @@ -661,11 +492,12 @@ void ProxyConfigServiceImpl::OnSettingsOpCompleted( std::string value) { retrieve_property_op_ = NULL; if (code != SignedSettings::SUCCESS) { - LOG(WARNING) << "Error retrieving proxy setting from device"; + LOG(WARNING) << this << ": Error retrieving proxy setting from device"; device_config_.clear(); return; } - VLOG(1) << "Retrieved proxy setting from device, value=[" << value << "]"; + VLOG(1) << this << ": Retrieved proxy setting from device, value=[" + << value << "]"; ProxyConfig device_config; if (!device_config.DeserializeForDevice(value) || !device_config.SerializeForNetwork(&device_config_)) { @@ -674,15 +506,15 @@ void ProxyConfigServiceImpl::OnSettingsOpCompleted( return; } if (!active_network_.empty()) { - VLOG(1) << "try migrating device config to " << active_network_; + VLOG(1) << this << ": try migrating device config to " << active_network_; SetProxyConfigForNetwork(active_network_, device_config_, true); } } void ProxyConfigServiceImpl::OnNetworkManagerChanged( NetworkLibrary* network_lib) { - VLOG(1) << "OnNetworkManagerChanged: use-shared-proxies=" - << use_shared_proxies_; + VLOG(1) << this << " OnNetworkManagerChanged: use-shared-proxies=" + << GetUseSharedProxies(); OnActiveNetworkChanged(network_lib, network_lib->active_network()); } @@ -690,70 +522,75 @@ void ProxyConfigServiceImpl::OnNetworkChanged(NetworkLibrary* network_lib, const Network* network) { if (!network) return; - VLOG(1) << "OnNetworkChanged: " - << (network->name().empty() ? network->service_path() : - network->name()) - << ", use-shared-proxies=" << use_shared_proxies_; + VLOG(1) << this << " OnNetworkChanged: " + << (network->name().empty() ? network->service_path() : + network->name()) + << ", use-shared-proxies=" << GetUseSharedProxies(); // We only care about active network. if (network == network_lib->active_network()) OnActiveNetworkChanged(network_lib, network); } +// static +void ProxyConfigServiceImpl::RegisterPrefs(PrefService* pref_service) { + // Use shared proxies default to off. GetUseSharedProxies will return the + // correct value based on pre-login and login. + pref_service->RegisterBooleanPref(prefs::kUseSharedProxies, + false, + PrefService::UNSYNCABLE_PREF); +} + //------------------ ProxyConfigServiceImpl: private methods ------------------- -void ProxyConfigServiceImpl::OnUISetProxyConfig() { - if (testing_) { - active_config_ = current_ui_config_; - IOSetProxyConfig(active_config_, net::ProxyConfigService::CONFIG_VALID); +void ProxyConfigServiceImpl::Observe( + int type, + const content::NotificationSource& source, + const content::NotificationDetails& details) { + if (type == chrome::NOTIFICATION_PREF_CHANGED && + *(content::Details<std::string>(details).ptr()) == + prefs::kUseSharedProxies) { + if (content::Source<PrefService>(source).ptr() == prefs()) { + VLOG(1) << this << ": new use-shared-proxies = " << GetUseSharedProxies(); + // Determine new proxy config which may have changed because of new + // use-shared-proxies. If necessary, activate it. + Network* network = NULL; + if (!active_network_.empty()) { + network = CrosLibrary::Get()->GetNetworkLibrary()->FindNetworkByPath( + active_network_); + if (!network) + LOG(WARNING) << "can't find requested network " << active_network_; + } + DetermineEffectiveConfig(network, true); + } + return; + } + if (type == chrome::NOTIFICATION_LOGIN_USER_CHANGED) { + VLOG(1) << this << ": login user changed"; + // If active network is the same, its proxy config and/or UseSharedProxies + // pref for this user could be different from that in login screen; + // determine effective config and activate it if different. + const Network* active_network = + CrosLibrary::Get()->GetNetworkLibrary()->active_network(); + if (active_network && active_network_ == active_network->service_path()) + DetermineEffectiveConfig(active_network, true); return; } + PrefProxyConfigTrackerImpl::Observe(type, source, details); +} + +void ProxyConfigServiceImpl::OnUISetProxyConfig() { if (current_ui_network_.empty()) return; // Update config to flimflam. std::string value; if (current_ui_config_.SerializeForNetwork(&value)) { - VLOG(1) << "set proxy (mode=" << current_ui_config_.mode - << ") for " << current_ui_network_; + VLOG(1) << this << ": set proxy (mode=" << current_ui_config_.mode + << ") for " << current_ui_network_; + current_ui_config_.state = ProxyPrefs::CONFIG_SYSTEM; SetProxyConfigForNetwork(current_ui_network_, value, false); } } -void ProxyConfigServiceImpl::IOSetProxyConfig( - const ProxyConfig& new_config, - net::ProxyConfigService::ConfigAvailability new_availability) { - if (!BrowserThread::CurrentlyOn(BrowserThread::IO) && can_post_task_) { - // Posts a task to IO thread with the new config, so it can update - // |cached_config_|. - Task* task = NewRunnableMethod(this, - &ProxyConfigServiceImpl::IOSetProxyConfig, - new_config, - new_availability); - if (!BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, task)) - VLOG(1) << "Couldn't post task to IO thread to set new proxy config"; - return; - } - - // Now guaranteed to be on the correct thread. - - if (config_availability_ == new_availability && - cached_config_.Equals(new_config)) - return; - - VLOG(1) << "Proxy changed: mode=" << new_config.mode - << ", avail=" << new_availability; - cached_config_ = new_config; - config_availability_ = new_availability; - // Notify observers of new proxy config. - net::ProxyConfig net_config; - cached_config_.ToNetProxyConfig(&net_config); - if (net_config.proxy_rules().type != - net::ProxyConfig::ProxyRules::TYPE_NO_RULES) { - net_config.proxy_rules().bypass_rules.AddRuleToBypassLocal(); - } - FOR_EACH_OBSERVER(net::ProxyConfigService::Observer, observers_, - OnProxyConfigChanged(net_config, config_availability_)); -} - void ProxyConfigServiceImpl::OnActiveNetworkChanged(NetworkLibrary* network_lib, const Network* active_network) { std::string new_network; @@ -761,10 +598,13 @@ void ProxyConfigServiceImpl::OnActiveNetworkChanged(NetworkLibrary* network_lib, new_network = active_network->service_path(); if (active_network_ == new_network) { // Same active network. - VLOG(1) << "same active network: " - << (new_network.empty() ? "empty" : - (active_network->name().empty() ? - new_network : active_network->name())); + VLOG(1) << this << ": same active network: " + << (new_network.empty() ? "empty" : + (active_network->name().empty() ? + new_network : active_network->name())); + // If last proxy update to network stack wasn't completed, do it now. + if (active_network && update_pending()) + DetermineEffectiveConfig(active_network, true); return; } @@ -775,26 +615,27 @@ void ProxyConfigServiceImpl::OnActiveNetworkChanged(NetworkLibrary* network_lib, active_network_ = new_network; if (active_network_.empty()) { - VLOG(1) << "new active network: empty"; - active_config_ = ProxyConfig(); - IOSetProxyConfig(active_config_, net::ProxyConfigService::CONFIG_UNSET); + VLOG(1) << this << ": new active network: empty"; + DetermineEffectiveConfig(active_network, true); return; } - VLOG(1) << "new active network: path=" << active_network->service_path() - << ", name=" << active_network->name() - << ", profile=" << active_network->profile_path() - << ", proxy=" << active_network->proxy_config(); + VLOG(1) << this << ": new active network: path=" + << active_network->service_path() + << ", name=" << active_network->name() + << ", profile=" << active_network->profile_path() + << ", proxy=" << active_network->proxy_config(); // Register observer for new network. network_lib->AddNetworkObserver(active_network_, this); // If necessary, migrate config to flimflam. if (active_network->proxy_config().empty() && !device_config_.empty()) { - VLOG(1) << "try migrating device config to " << active_network_; + VLOG(1) << this << ": try migrating device config to " << active_network_; SetProxyConfigForNetwork(active_network_, device_config_, true); - } else { - DetermineConfigFromNetwork(active_network); + } else { + // Otherwise, determine and activate possibly new effective proxy config. + DetermineEffectiveConfig(active_network, true); } } @@ -809,52 +650,124 @@ void ProxyConfigServiceImpl::SetProxyConfigForNetwork( } if (!only_set_if_empty || network->proxy_config().empty()) { network->SetProxyConfig(value); - VLOG(1) << "set proxy for " - << (network->name().empty() ? network_path : network->name()) - << ", value=" << value; + VLOG(1) << this << ": set proxy for " << (network->name().empty() ? + network_path : network->name()) + << ", value=" << value; if (network_path == active_network_) - DetermineConfigFromNetwork(network); + DetermineEffectiveConfig(network, true); } } -void ProxyConfigServiceImpl::DetermineConfigFromNetwork( - const Network* network) { - active_config_ = ProxyConfig(); // Default is DIRECT mode (i.e. no proxy). - net::ProxyConfigService::ConfigAvailability available = - net::ProxyConfigService::CONFIG_UNSET; - // If network is shared but user doesn't use shared proxies, use direct mode. - if (network->profile_type() == PROFILE_SHARED && !use_shared_proxies_) { - VLOG(1) << "shared network and !use_shared_proxies, using direct"; - available = net::ProxyConfigService::CONFIG_VALID; - } else if (!network->proxy_config().empty() && - active_config_.DeserializeForNetwork(network->proxy_config())) { - // Network is private or shared with user using shared proxies. - VLOG(1) << "using network proxy: " << network->proxy_config(); - available = net::ProxyConfigService::CONFIG_VALID; - } - IOSetProxyConfig(active_config_, available); +bool ProxyConfigServiceImpl::GetUseSharedProxies() { + const PrefService::Preference* use_shared_proxies_pref = + prefs()->FindPreference(prefs::kUseSharedProxies); + if (!use_shared_proxies_pref || use_shared_proxies_pref->IsDefaultValue()) + return !UserManager::Get()->user_is_logged_in(); + return use_shared_proxies_.GetValue(); } -void ProxyConfigServiceImpl::SetCurrentNetworkName(const Network* network) { - if (!network) { - if (testing_) - current_ui_network_name_ = "test"; - return; +void ProxyConfigServiceImpl::DetermineEffectiveConfig(const Network* network, + bool activate) { + // Get prefs proxy config if available. + net::ProxyConfig pref_config; + ProxyPrefs::ConfigState pref_state = GetProxyConfig(&pref_config); + + // Get network proxy config if available. + net::ProxyConfig network_config; + net::ProxyConfigService::ConfigAvailability network_availability = + net::ProxyConfigService::CONFIG_UNSET; + bool ignore_proxy = activate; + if (network) { + // If we're activating proxy, ignore proxy if necessary; + // otherwise, for ui, get actual proxy to show user. + ignore_proxy = activate ? IgnoreProxy(network) : false; + // If network is shared but use-shared-proxies is off, use direct mode. + if (ignore_proxy) { + VLOG(1) << this << ": shared network && !use-shared-proxies, use direct"; + network_availability = net::ProxyConfigService::CONFIG_VALID; + } else if (!network->proxy_config().empty()) { + // Network is private or shared with user using shared proxies. + JSONStringValueSerializer serializer(network->proxy_config()); + scoped_ptr<Value> value(serializer.Deserialize(NULL, NULL)); + if (value.get() && value->GetType() == Value::TYPE_DICTIONARY) { + DictionaryValue* dict = static_cast<DictionaryValue*>(value.get()); + ProxyConfigDictionary proxy_dict(dict); + if (PrefConfigToNetConfig(proxy_dict, &network_config)) { + VLOG(1) << this << ": using network proxy: " + << network->proxy_config(); + network_availability = net::ProxyConfigService::CONFIG_VALID; + } + } + } } - if (network->name().empty() && network->type() == chromeos::TYPE_ETHERNET) { - current_ui_network_name_ = l10n_util::GetStringUTF8( - IDS_STATUSBAR_NETWORK_DEVICE_ETHERNET); - } else { - current_ui_network_name_ = network->name(); + + // Determine effective proxy config, either from prefs or network. + ProxyPrefs::ConfigState effective_config_state; + net::ProxyConfig effective_config; + GetEffectiveProxyConfig(pref_state, pref_config, + network_availability, network_config, ignore_proxy, + &effective_config_state, &effective_config); + + // Determine if we should activate effective proxy and which proxy config to + // store it. + if (activate) { // Activate effective proxy and store into |active_config_|. + // If last update didn't complete, we definitely update now. + bool update_now = update_pending(); + if (!update_now) { // Otherwise, only update now if there're changes. + update_now = active_config_state_ != effective_config_state || + (active_config_state_ != ProxyPrefs::CONFIG_UNSET && + !active_config_.Equals(effective_config)); + } + if (update_now) { // Activate and store new effective config. + active_config_state_ = effective_config_state; + if (active_config_state_ != ProxyPrefs::CONFIG_UNSET) + active_config_ = effective_config; + // If effective config is from system (i.e. network), it's considered a + // special kind of prefs that ranks below policy/extension but above + // others, so bump it up to CONFIG_OTHER_PRECEDE to force its precedence + // when PrefProxyConfigTrackerImpl pushes it to ChromeProxyConfigService. + if (effective_config_state == ProxyPrefs::CONFIG_SYSTEM) + effective_config_state = ProxyPrefs::CONFIG_OTHER_PRECEDE; + // If config is manual, add rule to bypass local host. + if (effective_config.proxy_rules().type != + net::ProxyConfig::ProxyRules::TYPE_NO_RULES) + effective_config.proxy_rules().bypass_rules.AddRuleToBypassLocal(); + PrefProxyConfigTrackerImpl::OnProxyConfigChanged(effective_config_state, + effective_config); + if (VLOG_IS_ON(1) && !update_pending()) { // Update was successful. + scoped_ptr<DictionaryValue> config_dict(static_cast<DictionaryValue*>( + effective_config.ToValue())); + std::string config_value; + JSONStringValueSerializer serializer(&config_value); + serializer.Serialize(*config_dict.get()); + VLOG(1) << this << ": Proxy changed: " + << ConfigStateToString(active_config_state_) + << ", " << config_value; + } + } + } else { // For UI, store effective proxy into |current_ui_config_|. + current_ui_config_.FromNetProxyConfig(effective_config); + current_ui_config_.state = effective_config_state; + if (PrefPrecedes(effective_config_state)) + current_ui_config_.user_modifiable = false; + else + current_ui_config_.user_modifiable = !network || !IgnoreProxy(network); } } -void ProxyConfigServiceImpl::CheckCurrentlyOnIOThread() { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); +void ProxyConfigServiceImpl::OnUISetCurrentNetwork(const Network* network) { + DetermineEffectiveConfig(network, false); + VLOG(1) << this << ": current ui network: " + << (network->name().empty() ? + current_ui_network_ : network->name()) + << ", " << ModeToString(current_ui_config_.mode) + << ", " << ConfigStateToString(current_ui_config_.state) + << ", modifiable:" << current_ui_config_.user_modifiable; } -void ProxyConfigServiceImpl::CheckCurrentlyOnUIThread() { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); +void ProxyConfigServiceImpl::ResetUICache() { + current_ui_network_.clear(); + current_ui_config_ = ProxyConfig(); } } // namespace chromeos diff --git a/chrome/browser/chromeos/proxy_config_service_impl.h b/chrome/browser/chromeos/proxy_config_service_impl.h index fc0109f..dc25618 100644 --- a/chrome/browser/chromeos/proxy_config_service_impl.h +++ b/chrome/browser/chromeos/proxy_config_service_impl.h @@ -10,65 +10,60 @@ #include <vector> #include "base/basictypes.h" -#include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" -#include "base/observer_list.h" #include "base/values.h" #include "chrome/browser/chromeos/cros/network_library.h" #include "chrome/browser/chromeos/login/signed_settings.h" -#include "net/proxy/proxy_config.h" -#include "net/proxy/proxy_config_service.h" -#include "net/proxy/proxy_server.h" +#include "chrome/browser/net/pref_proxy_config_tracker_impl.h" +#include "chrome/browser/prefs/pref_member.h" +#include "content/public/browser/notification_registrar.h" namespace chromeos { // Implementation of proxy config service for chromeos that: -// - is RefCountedThreadSafe -// - is wrapped by chromeos::ProxyConfigService which implements -// net::ProxyConfigService interface by fowarding the methods to this class +// - extends PrefProxyConfigTrackerImpl (and so lives and runs entirely on UI +// thread) to handle proxy from prefs (via PrefProxyConfigTrackerImpl) and +// system i.e. network (via flimflam notifications) +// - exists one per profile and one per local state // - retrieves initial system proxy configuration from cros settings persisted // on chromeos device from chromeos revisions before migration to flimflam, // - persists proxy setting per network in flimflim -// - provides network stack with latest proxy configuration for currently -// active network for use on IO thread +// - provides network stack with latest effective proxy configuration for +// currently active network via PrefProxyConfigTrackerImpl's mechanism of +// pushing config to ChromeProxyConfigService // - provides UI with methods to retrieve and modify proxy configuration for -// any network (either currently active or non-active) on UI thread +// any remembered network (either currently active or non-active) of current +// user profile class ProxyConfigServiceImpl - : public base::RefCountedThreadSafe<ProxyConfigServiceImpl>, + : public PrefProxyConfigTrackerImpl, public SignedSettings::Delegate<std::string>, public NetworkLibrary::NetworkManagerObserver, public NetworkLibrary::NetworkObserver { public: - // ProxyConfigServiceImpl is created on the UI thread in - // chrome/browser/net/proxy_service_factory.cc::CreateProxyConfigService - // via BrowserProcess::chromeos_proxy_config_service_impl, and stored in - // g_browser_process as a scoped_refptr (because it's RefCountedThreadSafe). + // ProxyConfigServiceImpl is created in ProxyServiceFactory:: + // CreatePrefProxyConfigTrackerImpl via Profile::GetProxyConfigTracker() for + // profile or IOThread constructor for local state and is owned by the + // respective classes. // - // Past that point, it can be accessed from the IO or UI threads. - // - // From the IO thread, it is accessed periodically through the wrapper class - // chromeos::ProxyConfigService via net::ProxyConfigService interface - // (GetLatestProxyConfig, AddObserver, RemoveObserver). - // - // From the UI thread, it is accessed via - // BrowserProcess::chromeos_proxy_config_service_impl to allow user to read - // or modify the proxy configuration via UIGetProxyConfig or + // From the UI, it is accessed via Profile::GetProxyConfigTracker to allow + // user to read or modify the proxy configuration via UIGetProxyConfig or // UISetProxyConfigTo* respectively. - // The new modified proxy config is posted to the IO thread through - // SetNewProxyConfig(). We then notify observers on the IO thread of the - // configuration change. - + // The new modified proxy config, together with proxy from prefs if available, + // are used to determine the effective proxy config, which is then pushed + // through PrefProxyConfigTrackerImpl to ChromeProxyConfigService to the + // network stack. + // // In contrary to other platforms which simply use the systems' UI to allow // users to configure proxies, we have to implement our own UI on the chromeos // device. This requires extra and specific UI requirements that // net::ProxyConfig does not suffice. So we create an augmented analog to // net:ProxyConfig here to include and handle these UI requirements, e.g. - // - where configuration was picked up from - policy or owner + // - state of configuration e.g. where it was picked up from - policy, + // extension, etc (refer to ProxyPrefs::ConfigState) // - the read/write access of a proxy setting // - may add more stuff later. - // This is then converted to the common net::ProxyConfig before being returned - // to ProxyService::GetLatestProxyConfig on the IO thread to be used on the - // network stack. + // This is then converted to the common net::ProxyConfig before being pushed + // to PrefProxyConfigTrackerImpl::OnProxyConfigChanged and then to the network + // stack. struct ProxyConfig { // Specifies if proxy config is direct, auto-detect, using pac script, // single-proxy, or proxy-per-scheme. @@ -80,40 +75,25 @@ class ProxyConfigServiceImpl MODE_PROXY_PER_SCHEME, }; - // Specifies where proxy configuration was picked up from. - enum Source { - SOURCE_NONE, // No default configuration. - SOURCE_POLICY, // Configuration is from policy. - SOURCE_OWNER, // Configuration is from owner. - }; - - struct Setting { - Setting() : source(SOURCE_NONE) {} - bool CanBeWrittenByUser(bool user_is_owner); - - Source source; - }; - // Proxy setting for mode = direct or auto-detect or using pac script. - struct AutomaticProxy : public Setting { - GURL pac_url; // Set if proxy is using pac script. + struct AutomaticProxy { + GURL pac_url; // Set if proxy is using pac script. }; // Proxy setting for mode = single-proxy or proxy-per-scheme. - struct ManualProxy : public Setting { - net::ProxyServer server; + struct ManualProxy { + net::ProxyServer server; }; ProxyConfig(); ~ProxyConfig(); - // Converts |this| to net::ProxyConfig. - void ToNetProxyConfig(net::ProxyConfig* net_config); + // Converts net::ProxyConfig to |this|. + bool FromNetProxyConfig(const net::ProxyConfig& net_config); - // Returns true if proxy config can be written by user. - // If mode is MODE_PROXY_PER_SCHEME, |scheme| is one of "http", "https", - // "ftp" or "socks"; otherwise, it should be empty or will be ignored. - bool CanBeWrittenByUser(bool user_is_owner, const std::string& scheme); + // Converts |this| to Dictionary of ProxyConfigDictionary format (which + // is the same format used by prefs). + DictionaryValue* ToPrefProxyConfig(); // Map |scheme| (one of "http", "https", "ftp" or "socks") to the correct // ManualProxy. Returns NULL if scheme is invalid. @@ -129,18 +109,15 @@ class ProxyConfigServiceImpl // persisted as string property in flimflam for a network. bool SerializeForNetwork(std::string* output); - // Deserializes from string property in flimflam for a network into a - // ProxyConfigDictionary and then into the config. - // Opposite of SerializeForNetwork. - bool DeserializeForNetwork(const std::string& input); - - // Returns true if the given config is equivalent to this config. - bool Equals(const ProxyConfig& other) const; + Mode mode; - // Creates a textual dump of the configuration. - std::string ToString() const; + ProxyPrefs::ConfigState state; - Mode mode; + // True if user can modify proxy settings via UI. + // If proxy is managed by policy or extension or other_precde or is for + // shared network but kUseSharedProxies is turned off, it can't be modified + // by user. + bool user_modifiable; // Set if mode is MODE_DIRECT or MODE_AUTO_DETECT or MODE_PAC_SCRIPT. AutomaticProxy automatic_proxy; @@ -163,55 +140,30 @@ class ProxyConfigServiceImpl static void EncodeAndAppendProxyServer(const std::string& scheme, const net::ProxyServer& server, std::string* spec); - - // Converts |this| to Dictionary of ProxyConfigDictionary format (which - // is the same format used by prefs). - DictionaryValue* ToPrefProxyConfig(); - - // Converts |this| from Dictionary of ProxyConfigDictionary format. - bool FromPrefProxyConfig(const DictionaryValue* proxy_dict); }; - // Usual constructor. - ProxyConfigServiceImpl(); - // Constructor for testing. - // |init_config| specifies the ProxyConfig to use for initialization. - explicit ProxyConfigServiceImpl(const ProxyConfig& init_config); + // Constructor. + explicit ProxyConfigServiceImpl(PrefService* pref_service); virtual ~ProxyConfigServiceImpl(); - // Methods called on IO thread from wrapper class chromeos::ProxyConfigService - // as ProxyConfigService methods. - void AddObserver(net::ProxyConfigService::Observer* observer); - void RemoveObserver(net::ProxyConfigService::Observer* observer); - // Called from GetLatestProxyConfig. - net::ProxyConfigService::ConfigAvailability IOGetProxyConfig( - net::ProxyConfig* config); - - // Called from UI thread to retrieve proxy configuration in |config|. - void UIGetProxyConfig(ProxyConfig* config); + // Called by UI to set service path of |network| to be displayed or edited. + // Subsequent UISet* methods will use this network, until UI calls it again + // with a different network. + void UISetCurrentNetwork(const std::string& current_network); - // Called from UI thread to set service path of network to be displayed or - // edited. Subsequent UISet* methods will use this network, until UI calls - // it again with a different network. - bool UISetCurrentNetwork(const std::string& current_network); + // Called from UI to make the currently active network the one to be displayed + // or edited. Subsequent UISet* methods will use this network until UI calls + // it again when the active network has changed. + void UIMakeActiveNetworkCurrent(); - // Called from UI thread to make the currently active network the one to be - // displayed or edited. Subsequent UISet* methods will use this network. until - // UI calls it again when the active network has changed. - bool UIMakeActiveNetworkCurrent(); - - // Called from UI thread to get name of the current active network. - const std::string& current_network_name() const { - return current_ui_network_name_; - } + // Called from UI to get name of the current network set via + // UISetCurrentNetwork or UIMakeActiveNetworkCurrent. + void UIGetCurrentNetworkName(std::string* network_name); - // Called from UI thread to set/get user preference use_shared_proxies. - void UISetUseSharedProxies(bool use_shared); - bool use_shared_proxies() const { - return use_shared_proxies_; - } + // Called from UI to retrieve proxy configuration in |current_ui_config_|. + void UIGetProxyConfig(ProxyConfig* config); - // Called from UI thread to update proxy configuration for different modes. + // Called from UI to update proxy configuration for different modes. // Returns true if config is set properly and persisted to flimflam for the // current network (set via UISetCurrentNetwork/UIMakeActiveNetworkCurrent). // If this network is also currently active, config service proceeds to start @@ -232,33 +184,42 @@ class ProxyConfigServiceImpl // Implementation for SignedSettings::Delegate virtual void OnSettingsOpCompleted(SignedSettings::ReturnCode code, - std::string value); + std::string value) OVERRIDE; // NetworkLibrary::NetworkManagerObserver implementation. - virtual void OnNetworkManagerChanged(NetworkLibrary* cros); + virtual void OnNetworkManagerChanged(NetworkLibrary* cros) OVERRIDE; // NetworkLibrary::NetworkObserver implementation. - virtual void OnNetworkChanged(NetworkLibrary* cros, const Network* network); + virtual void OnNetworkChanged(NetworkLibrary* cros, + const Network* network) OVERRIDE; + + // PrefProxyConfigTrackerImpl implementation. + virtual void OnProxyConfigChanged(ProxyPrefs::ConfigState config_state, + const net::ProxyConfig& config) OVERRIDE; + + // Register UseShardProxies preference. + static void RegisterPrefs(PrefService* pref_service); #if defined(UNIT_TEST) - void SetTesting() { - testing_ = true; - active_network_ = "test"; + void SetTesting(ProxyConfig* test_config) { UIMakeActiveNetworkCurrent(); + if (test_config) { + std::string value; + test_config->SerializeForNetwork(&value); + SetProxyConfigForNetwork(active_network_, value, false); + } } #endif // defined(UNIT_TEST) private: - friend class base::RefCountedThreadSafe<ProxyConfigServiceImpl>; + // content::NotificationObserver implementation. + virtual void Observe(int type, + const content::NotificationSource& source, + const content::NotificationDetails& details) OVERRIDE; - // Called from UI thread from the various UISetProxyConfigTo*. + // Called from the various UISetProxyConfigTo*. void OnUISetProxyConfig(); - // Posted from UI thread to IO thread to carry the new config information. - void IOSetProxyConfig( - const ProxyConfig& new_config, - net::ProxyConfigService::ConfigAvailability new_availability); - // Called from OnNetworkManagerChanged and OnNetworkChanged for currently // active network, to handle previously active network, new active network, // and if necessary, migrates device settings to flimflam and/or activates @@ -267,72 +228,67 @@ class ProxyConfigServiceImpl const Network* active_network); // Sets proxy config for |network_path| into flimflam and activates setting - // if the network is currently active. + // if the network is currently active. If |only_set_if_empty| is true, + // proxy will be set and saved only if network has no proxy. void SetProxyConfigForNetwork(const std::string& network_path, const std::string& value, bool only_set_if_empty); - // Determines and activates proxy config of |network| based on if network is - // shared/private or user is using shared proxies, etc. - void DetermineConfigFromNetwork(const Network* network); - - // Set |current_ui_network_name_| with name of |network|. - void SetCurrentNetworkName(const Network* network); - - // Checks that method is called on BrowserThread::IO thread. - void CheckCurrentlyOnIOThread(); + // Returns value of UseSharedProxies preference if it's not default, else + // returns false if user is logged in and true otherwise. + bool GetUseSharedProxies(); + + // Determines effective proxy config based on prefs from config tracker, + // |network| and if user is using shared proxies. + // If |activate| is true, effective config is stored in |active_config_| and + // activated on network stack, and hence, picked up by observers. + // if |activate| is false, effective config is stored in |current_ui_config_| + // but not activated on network stack, and hence, not picked up by observers. + void DetermineEffectiveConfig(const Network* network, bool activate); + + // Determines |current_ui_config_| based on |network|, called from + // UISetCurrentNetwork and UIMakeActiveNetworkActive. + void OnUISetCurrentNetwork(const Network* network); + + // Returns true if proxy is to be ignored for network, which happens if + // network is shared and use-shared-proxies is turned off. + bool IgnoreProxy(const Network* network) { + return network->profile_type() == PROFILE_SHARED && !GetUseSharedProxies(); + } - // Checks that method is called on BrowserThread::UI thread. - void CheckCurrentlyOnUIThread(); + // Reset UI cache variables that keep track of UI activities. + void ResetUICache(); // Data members. - // True if running unit_tests, which will need to specifically exclude - // flimflam logic. - bool testing_; - - // True if tasks can be posted, which can only happen if constructor has - // completed (NewRunnableMethod cannot be created for a RefCountedThreadBase's - // method until the class's ref_count is at least one). - bool can_post_task_; - - // Availability status of the configuration, initialized on UI thread, but - // afterwards only accessed from IO thread. - net::ProxyConfigService::ConfigAvailability config_availability_; - // Service path of currently active network (determined via flimflam - // notifications) whose proxy config is taking effect. + // notifications); if effective proxy config is from system, proxy of this + // network will be the one taking effect. std::string active_network_; - // Proxy configuration of |active_network_|, only accessed from UI thread. - ProxyConfig active_config_; + + // State of |active_config_|. |active_config_| is only valid if + // |active_config_state_| is not ProxyPrefs::CONFIG_UNSET. + ProxyPrefs::ConfigState active_config_state_; + + // Active proxy configuration, which could be from prefs or network. + net::ProxyConfig active_config_; // Proxy config retreived from device, in format generated from // SerializeForNetwork, that can be directly set into flimflam. std::string device_config_; - // Cached proxy configuration, to be converted to net::ProxyConfig and - // returned by IOGetProxyConfig. - // Initially populated from UI thread, but afterwards only accessed from IO - // thread. - ProxyConfig cached_config_; - // Service path of network whose proxy configuration is being displayed or // edited via UI, separate from |active_network_| which may be same or // different. std::string current_ui_network_; - // Name of network with current_ui_network_, set in UIMakeActiveNetworkCurrent - // and UISetCurrentNetwork. - std::string current_ui_network_name_; - - // Proxy configuration of |current_ui_network|. + // Proxy configuration of |current_ui_network_|. ProxyConfig current_ui_config_; - // True if user preference UseSharedProxies is true. - bool use_shared_proxies_; + // Track changes in UseSharedProxies user preference. + BooleanPrefMember use_shared_proxies_; - // List of observers for changes in proxy config. - ObserverList<net::ProxyConfigService::Observer> observers_; + content::NotificationRegistrar registrar_; // Operation to retrieve proxy setting from device. scoped_refptr<SignedSettings> retrieve_property_op_; diff --git a/chrome/browser/chromeos/proxy_config_service_impl_unittest.cc b/chrome/browser/chromeos/proxy_config_service_impl_unittest.cc index 2b43cb3..80219a3 100644 --- a/chrome/browser/chromeos/proxy_config_service_impl_unittest.cc +++ b/chrome/browser/chromeos/proxy_config_service_impl_unittest.cc @@ -14,10 +14,12 @@ #include "base/string_util.h" #include "base/stringprintf.h" #include "chrome/browser/chromeos/cros/cros_library.h" +#include "chrome/browser/chromeos/dbus/dbus_thread_manager.h" +#include "chrome/common/pref_names.h" +#include "chrome/test/base/testing_pref_service.h" #include "content/test/test_browser_thread.h" #include "net/proxy/proxy_config_service_common_unittest.h" #include "testing/gtest/include/gtest/gtest.h" -#include "testing/platform_test.h" using content::BrowserThread; @@ -41,16 +43,15 @@ struct Input { // Fields of chromeos::ProxyConfigServiceImpl::ProxyConfig. // Shortcuts to declare enums within chromeos's ProxyConfig. #define MK_MODE(mode) ProxyConfigServiceImpl::ProxyConfig::MODE_##mode -#define MK_SRC(src) ProxyConfigServiceImpl::ProxyConfig::SOURCE_##src #define MK_SCHM(scheme) net::ProxyServer::SCHEME_##scheme +#define MK_AVAIL(avail) net::ProxyConfigService::CONFIG_##avail // Inspired from net/proxy/proxy_config_service_linux_unittest.cc. -const struct { +const struct TestParams { // Short description to identify the test std::string description; bool is_valid; - bool test_read_write_access; Input input; @@ -59,11 +60,10 @@ const struct { GURL pac_url; net::ProxyRulesExpectation proxy_rules; } tests[] = { - { + { // 0 TEST_DESC("No proxying"), true, // is_valid - true, // test_read_write_access { // Input. MK_MODE(DIRECT), // mode @@ -75,11 +75,10 @@ const struct { net::ProxyRulesExpectation::Empty(), // proxy_rules }, - { + { // 1 TEST_DESC("Auto detect"), true, // is_valid - true, // test_read_write_access { // Input. MK_MODE(AUTO_DETECT), // mode @@ -91,11 +90,10 @@ const struct { net::ProxyRulesExpectation::Empty(), // proxy_rules }, - { + { // 2 TEST_DESC("Valid PAC URL"), true, // is_valid - true, // test_read_write_access { // Input. MK_MODE(PAC_SCRIPT), // mode @@ -108,11 +106,10 @@ const struct { net::ProxyRulesExpectation::Empty(), // proxy_rules }, - { + { // 3 TEST_DESC("Invalid PAC URL"), false, // is_valid - false, // test_read_write_access { // Input. MK_MODE(PAC_SCRIPT), // mode @@ -125,11 +122,10 @@ const struct { net::ProxyRulesExpectation::Empty(), // proxy_rules }, - { + { // 4 TEST_DESC("Single-host in proxy list"), true, // is_valid - true, // test_read_write_access { // Input. MK_MODE(SINGLE_PROXY), // mode @@ -141,15 +137,14 @@ const struct { false, // auto_detect GURL(), // pac_url net::ProxyRulesExpectation::Single( // proxy_rules - "www.google.com:80", // single proxy - ""), // bypass rules + "www.google.com:80", // single proxy + "<local>"), // bypass rules }, - { + { // 5 TEST_DESC("Single-host, different port"), true, // is_valid - false, // test_read_write_access { // Input. MK_MODE(SINGLE_PROXY), // mode @@ -161,15 +156,14 @@ const struct { false, // auto_detect GURL(), // pac_url net::ProxyRulesExpectation::Single( // proxy_rules - "www.google.com:99", // single - ""), // bypass rules + "www.google.com:99", // single + "<local>"), // bypass rules }, - { + { // 6 TEST_DESC("Tolerate a scheme"), true, // is_valid - false, // test_read_write_access { // Input. MK_MODE(SINGLE_PROXY), // mode @@ -181,15 +175,14 @@ const struct { false, // auto_detect GURL(), // pac_url net::ProxyRulesExpectation::Single( // proxy_rules - "www.google.com:99", // single proxy - ""), // bypass rules + "www.google.com:99", // single proxy + "<local>"), // bypass rules }, - { + { // 7 TEST_DESC("Per-scheme proxy rules"), true, // is_valid - true, // test_read_write_access { // Input. MK_MODE(PROXY_PER_SCHEME), // mode @@ -209,14 +202,13 @@ const struct { "https://www.foo.com:110", // https "ftp.foo.com:121", // ftp "socks5://socks.com:888", // fallback proxy - ""), // bypass rules + "<local>"), // bypass rules }, - { + { // 8 TEST_DESC("Bypass rules"), true, // is_valid - true, // test_read_write_access { // Input. MK_MODE(SINGLE_PROXY), // mode @@ -229,48 +221,56 @@ const struct { // Expected result. false, // auto_detect GURL(), // pac_url - net::ProxyRulesExpectation::Single( // proxy_rules - "www.google.com:80", // single proxy - "*.google.com,*foo.com:99,1.2.3.4:22,127.0.0.1/8"), // bypass_rules + net::ProxyRulesExpectation::Single( // proxy_rules + "www.google.com:80", // single proxy + // bypass_rules + "*.google.com,*foo.com:99,1.2.3.4:22,127.0.0.1/8,<local>"), }, }; // tests -} // namespace - -class ProxyConfigServiceImplTest : public PlatformTest { +template<typename TESTBASE> +class ProxyConfigServiceImplTestBase : public TESTBASE { protected: - ProxyConfigServiceImplTest() - : ui_thread_(BrowserThread::UI, &message_loop_), - io_thread_(BrowserThread::IO, &message_loop_) { - } - - virtual ~ProxyConfigServiceImplTest() { - config_service_ = NULL; - MessageLoop::current()->RunAllPending(); + ProxyConfigServiceImplTestBase() + : ui_thread_(BrowserThread::UI, &loop_), + io_thread_(BrowserThread::IO, &loop_) {} + + virtual void Init(PrefService* pref_service) { + ASSERT_TRUE(pref_service); + DBusThreadManager::Initialize(); + PrefProxyConfigTrackerImpl::RegisterPrefs(pref_service); + ProxyConfigServiceImpl::RegisterPrefs(pref_service); + proxy_config_service_.reset(new ChromeProxyConfigService(NULL)); + config_service_impl_.reset(new ProxyConfigServiceImpl(pref_service)); + config_service_impl_->SetChromeProxyConfigService( + proxy_config_service_.get()); + // SetChromeProxyConfigService triggers update of initial prefs proxy + // config by tracker to chrome proxy config service, so flush all pending + // tasks so that tests start fresh. + loop_.RunAllPending(); } - void CreateConfigService( - const ProxyConfigServiceImpl::ProxyConfig& init_config) { - // Instantiate proxy config service with |init_config|. - config_service_ = new ProxyConfigServiceImpl(init_config); - config_service_->SetTesting(); + virtual void TearDown() { + config_service_impl_->DetachFromPrefService(); + loop_.RunAllPending(); + config_service_impl_.reset(); + proxy_config_service_.reset(); + DBusThreadManager::Shutdown(); } void SetAutomaticProxy( ProxyConfigServiceImpl::ProxyConfig::Mode mode, - ProxyConfigServiceImpl::ProxyConfig::Source source, const char* pac_url, ProxyConfigServiceImpl::ProxyConfig* config, ProxyConfigServiceImpl::ProxyConfig::AutomaticProxy* automatic_proxy) { config->mode = mode; - automatic_proxy->source = source; + config->state = ProxyPrefs::CONFIG_SYSTEM; if (pac_url) automatic_proxy->pac_url = GURL(pac_url); } void SetManualProxy( ProxyConfigServiceImpl::ProxyConfig::Mode mode, - ProxyConfigServiceImpl::ProxyConfig::Source source, const char* server_uri, net::ProxyServer::Scheme scheme, ProxyConfigServiceImpl::ProxyConfig* config, @@ -278,162 +278,82 @@ class ProxyConfigServiceImplTest : public PlatformTest { if (!server_uri) return; config->mode = mode; - manual_proxy->source = source; + config->state = ProxyPrefs::CONFIG_SYSTEM; manual_proxy->server = net::ProxyServer::FromURI(server_uri, scheme); } void InitConfigWithTestInput( - const Input& input, ProxyConfigServiceImpl::ProxyConfig::Source source, - ProxyConfigServiceImpl::ProxyConfig* init_config) { + const Input& input, ProxyConfigServiceImpl::ProxyConfig* test_config) { switch (input.mode) { case MK_MODE(DIRECT): case MK_MODE(AUTO_DETECT): case MK_MODE(PAC_SCRIPT): - SetAutomaticProxy(input.mode, source, input.pac_url, init_config, - &init_config->automatic_proxy); + SetAutomaticProxy(input.mode, input.pac_url, test_config, + &test_config->automatic_proxy); return; case MK_MODE(SINGLE_PROXY): - SetManualProxy(input.mode, source, input.single_uri, MK_SCHM(HTTP), - init_config, &init_config->single_proxy); + SetManualProxy(input.mode, input.single_uri, MK_SCHM(HTTP), + test_config, &test_config->single_proxy); break; case MK_MODE(PROXY_PER_SCHEME): - SetManualProxy(input.mode, source, input.http_uri, MK_SCHM(HTTP), - init_config, &init_config->http_proxy); - SetManualProxy(input.mode, source, input.https_uri, MK_SCHM(HTTPS), - init_config, &init_config->https_proxy); - SetManualProxy(input.mode, source, input.ftp_uri, MK_SCHM(HTTP), - init_config, &init_config->ftp_proxy); - SetManualProxy(input.mode, source, input.socks_uri, MK_SCHM(SOCKS5), - init_config, &init_config->socks_proxy); + SetManualProxy(input.mode, input.http_uri, MK_SCHM(HTTP), + test_config, &test_config->http_proxy); + SetManualProxy(input.mode, input.https_uri, MK_SCHM(HTTPS), + test_config, &test_config->https_proxy); + SetManualProxy(input.mode, input.ftp_uri, MK_SCHM(HTTP), + test_config, &test_config->ftp_proxy); + SetManualProxy(input.mode, input.socks_uri, MK_SCHM(SOCKS5), + test_config, &test_config->socks_proxy); break; } - if (input.bypass_rules) { - init_config->bypass_rules.ParseFromString(input.bypass_rules); - } - } - - void TestReadWriteAccessForMode(const Input& input, - ProxyConfigServiceImpl::ProxyConfig::Source source) { - // Init config from |source|. - ProxyConfigServiceImpl::ProxyConfig init_config; - InitConfigWithTestInput(input, source, &init_config); - CreateConfigService(init_config); - - ProxyConfigServiceImpl::ProxyConfig config; - config_service()->UIGetProxyConfig(&config); - - // For owner, write access to config should be equal CanBeWrittenByOwner(). - // For non-owner, config is never writeable. - bool expected_writeable_by_owner = CanBeWrittenByOwner(source); - if (config.mode == MK_MODE(PROXY_PER_SCHEME)) { - if (input.http_uri) { - EXPECT_EQ(expected_writeable_by_owner, - config.CanBeWrittenByUser(true, "http")); - EXPECT_FALSE(config.CanBeWrittenByUser(false, "http")); - } - if (input.https_uri) { - EXPECT_EQ(expected_writeable_by_owner, - config.CanBeWrittenByUser(true, "http")); - EXPECT_FALSE(config.CanBeWrittenByUser(false, "https")); - } - if (input.ftp_uri) { - EXPECT_EQ(expected_writeable_by_owner, - config.CanBeWrittenByUser(true, "http")); - EXPECT_FALSE(config.CanBeWrittenByUser(false, "ftp")); - } - if (input.socks_uri) { - EXPECT_EQ(expected_writeable_by_owner, - config.CanBeWrittenByUser(true, "http")); - EXPECT_FALSE(config.CanBeWrittenByUser(false, "socks")); - } - } else { - EXPECT_EQ(expected_writeable_by_owner, - config.CanBeWrittenByUser(true, std::string())); - EXPECT_FALSE(config.CanBeWrittenByUser(false, std::string())); - } - } - - void TestReadWriteAccessForScheme( - ProxyConfigServiceImpl::ProxyConfig::Source source, - const char* server_uri, - const std::string& scheme) { - // Init with manual |scheme| proxy. - ProxyConfigServiceImpl::ProxyConfig init_config; - ProxyConfigServiceImpl::ProxyConfig::ManualProxy* proxy = - init_config.MapSchemeToProxy(scheme); - net::ProxyServer::Scheme net_scheme = MK_SCHM(HTTP); - if (scheme == "http" || scheme == "ftp") - net_scheme = MK_SCHM(HTTP); - else if (scheme == "https") - net_scheme = MK_SCHM(HTTPS); - else if (scheme == "socks") - net_scheme = MK_SCHM(SOCKS4); - SetManualProxy(MK_MODE(PROXY_PER_SCHEME), source, server_uri, net_scheme, - &init_config, proxy); - CreateConfigService(init_config); - - ProxyConfigServiceImpl::ProxyConfig config; - config_service()->UIGetProxyConfig(&config); - - // For owner, write access to config should be equal CanBeWrittenByOwner(). - // For non-owner, config is never writeable. - bool expected_writeable_by_owner = CanBeWrittenByOwner(source); - EXPECT_EQ(expected_writeable_by_owner, - config.CanBeWrittenByUser(true, scheme)); - EXPECT_FALSE(config.CanBeWrittenByUser(false, scheme)); - - const char* all_schemes[] = { - "http", "https", "ftp", "socks", - }; - - // Rest of protos should be writeable by owner, but not writeable by - // non-owner. - for (size_t i = 0; i < ARRAYSIZE_UNSAFE(all_schemes); ++i) { - if (scheme == all_schemes[i]) - continue; - EXPECT_TRUE(config.CanBeWrittenByUser(true, all_schemes[i])); - EXPECT_FALSE(config.CanBeWrittenByUser(false, all_schemes[i])); - } + if (input.bypass_rules) + test_config->bypass_rules.ParseFromString(input.bypass_rules); } // Synchronously gets the latest proxy config. - bool SyncGetLatestProxyConfig(net::ProxyConfig* config) { + net::ProxyConfigService::ConfigAvailability SyncGetLatestProxyConfig( + net::ProxyConfig* config) { + *config = net::ProxyConfig(); // Let message loop process all messages. - MessageLoop::current()->RunAllPending(); - // Calls IOGetProxyConfig (which is called from + loop_.RunAllPending(); + // Calls ChromeProIOGetProxyConfig (which is called from // ProxyConfigService::GetLatestProxyConfig), running on faked IO thread. - return config_service_->IOGetProxyConfig(config); + return proxy_config_service_->GetLatestProxyConfig(config); } - ProxyConfigServiceImpl* config_service() const { - return config_service_; - } + MessageLoop loop_; + scoped_ptr<ChromeProxyConfigService> proxy_config_service_; + scoped_ptr<ProxyConfigServiceImpl> config_service_impl_; private: - bool CanBeWrittenByOwner( - ProxyConfigServiceImpl::ProxyConfig::Source source) const { - return source == MK_SRC(POLICY) ? false : true; - } - + // Default stub state has ethernet as the active connected network and + // PROFILE_SHARED as profile type, which this unittest expects. ScopedStubCrosEnabler stub_cros_enabler_; - MessageLoop message_loop_; content::TestBrowserThread ui_thread_; content::TestBrowserThread io_thread_; +}; + +class ProxyConfigServiceImplTest + : public ProxyConfigServiceImplTestBase<testing::Test> { + protected: + virtual void SetUp() { + Init(&pref_service_); + } - scoped_refptr<ProxyConfigServiceImpl> config_service_; + TestingPrefService pref_service_; }; -TEST_F(ProxyConfigServiceImplTest, ChromeosProxyConfigToNetProxyConfig) { +TEST_F(ProxyConfigServiceImplTest, NetworkProxy) { for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { SCOPED_TRACE(StringPrintf("Test[%" PRIuS "] %s", i, tests[i].description.c_str())); - ProxyConfigServiceImpl::ProxyConfig init_config; - InitConfigWithTestInput(tests[i].input, MK_SRC(OWNER), &init_config); - CreateConfigService(init_config); + ProxyConfigServiceImpl::ProxyConfig test_config; + InitConfigWithTestInput(tests[i].input, &test_config); + config_service_impl_->SetTesting(&test_config); net::ProxyConfig config; - SyncGetLatestProxyConfig(&config); + EXPECT_EQ(MK_AVAIL(VALID), SyncGetLatestProxyConfig(&config)); EXPECT_EQ(tests[i].auto_detect, config.auto_detect()); EXPECT_EQ(tests[i].pac_url, config.pac_url()); @@ -447,66 +367,66 @@ TEST_F(ProxyConfigServiceImplTest, ModifyFromUI) { tests[i].description.c_str())); // Init with direct. - ProxyConfigServiceImpl::ProxyConfig init_config; - SetAutomaticProxy(MK_MODE(DIRECT), MK_SRC(OWNER), NULL, &init_config, - &init_config.automatic_proxy); - CreateConfigService(init_config); + ProxyConfigServiceImpl::ProxyConfig test_config; + SetAutomaticProxy(MK_MODE(DIRECT), NULL, &test_config, + &test_config.automatic_proxy); + config_service_impl_->SetTesting(&test_config); // Set config to tests[i].input via UI. net::ProxyBypassRules bypass_rules; const Input& input = tests[i].input; switch (input.mode) { case MK_MODE(DIRECT) : - config_service()->UISetProxyConfigToDirect(); + config_service_impl_->UISetProxyConfigToDirect(); break; case MK_MODE(AUTO_DETECT) : - config_service()->UISetProxyConfigToAutoDetect(); + config_service_impl_->UISetProxyConfigToAutoDetect(); break; case MK_MODE(PAC_SCRIPT) : - config_service()->UISetProxyConfigToPACScript(GURL(input.pac_url)); + config_service_impl_->UISetProxyConfigToPACScript(GURL(input.pac_url)); break; case MK_MODE(SINGLE_PROXY) : - config_service()->UISetProxyConfigToSingleProxy( + config_service_impl_->UISetProxyConfigToSingleProxy( net::ProxyServer::FromURI(input.single_uri, MK_SCHM(HTTP))); if (input.bypass_rules) { bypass_rules.ParseFromString(input.bypass_rules); - config_service()->UISetProxyConfigBypassRules(bypass_rules); + config_service_impl_->UISetProxyConfigBypassRules(bypass_rules); } break; case MK_MODE(PROXY_PER_SCHEME) : if (input.http_uri) { - config_service()->UISetProxyConfigToProxyPerScheme("http", + config_service_impl_->UISetProxyConfigToProxyPerScheme("http", net::ProxyServer::FromURI(input.http_uri, MK_SCHM(HTTP))); } if (input.https_uri) { - config_service()->UISetProxyConfigToProxyPerScheme("https", + config_service_impl_->UISetProxyConfigToProxyPerScheme("https", net::ProxyServer::FromURI(input.https_uri, MK_SCHM(HTTPS))); } if (input.ftp_uri) { - config_service()->UISetProxyConfigToProxyPerScheme("ftp", + config_service_impl_->UISetProxyConfigToProxyPerScheme("ftp", net::ProxyServer::FromURI(input.ftp_uri, MK_SCHM(HTTP))); } if (input.socks_uri) { - config_service()->UISetProxyConfigToProxyPerScheme("socks", + config_service_impl_->UISetProxyConfigToProxyPerScheme("socks", net::ProxyServer::FromURI(input.socks_uri, MK_SCHM(SOCKS5))); } if (input.bypass_rules) { bypass_rules.ParseFromString(input.bypass_rules); - config_service()->UISetProxyConfigBypassRules(bypass_rules); + config_service_impl_->UISetProxyConfigBypassRules(bypass_rules); } break; } // Retrieve config from IO thread. net::ProxyConfig io_config; - SyncGetLatestProxyConfig(&io_config); + EXPECT_EQ(MK_AVAIL(VALID), SyncGetLatestProxyConfig(&io_config)); EXPECT_EQ(tests[i].auto_detect, io_config.auto_detect()); EXPECT_EQ(tests[i].pac_url, io_config.pac_url()); EXPECT_TRUE(tests[i].proxy_rules.Matches(io_config.proxy_rules())); // Retrieve config from UI thread. ProxyConfigServiceImpl::ProxyConfig ui_config; - config_service()->UIGetProxyConfig(&ui_config); + config_service_impl_->UIGetProxyConfig(&ui_config); EXPECT_EQ(input.mode, ui_config.mode); if (tests[i].is_valid) { if (input.pac_url) @@ -534,134 +454,108 @@ TEST_F(ProxyConfigServiceImplTest, ModifyFromUI) { } } -TEST_F(ProxyConfigServiceImplTest, ProxyChangedObserver) { - // This is used to observe for OnProxyConfigChanged notification. - class ProxyChangedObserver : public net::ProxyConfigService::Observer { - public: - explicit ProxyChangedObserver( - const scoped_refptr<ProxyConfigServiceImpl>& config_service) - : config_service_(config_service) { - config_service_->AddObserver(this); - } - virtual ~ProxyChangedObserver() { - config_service_->RemoveObserver(this); - } - net::ProxyConfigService::ConfigAvailability availability() const { - return availability_; - } - const net::ProxyConfig& config() const { - return config_; - } - - private: - virtual void OnProxyConfigChanged( - const net::ProxyConfig& config, - net::ProxyConfigService::ConfigAvailability availability) { - config_ = config; - availability_ = availability; - } - - scoped_refptr<ProxyConfigServiceImpl> config_service_; - net::ProxyConfigService::ConfigAvailability availability_; - net::ProxyConfig config_; +TEST_F(ProxyConfigServiceImplTest, DynamicPrefsOverride) { + // Groupings of 3 test inputs to use for managed, recommended and network + // proxies respectively. Only valid and non-direct test inputs are used. + const size_t proxies[][3] = { + { 1, 2, 4, }, + { 1, 4, 2, }, + { 4, 2, 1, }, + { 2, 1, 4, }, + { 2, 4, 5, }, + { 2, 5, 4, }, + { 5, 4, 2, }, + { 4, 2, 5, }, + { 4, 5, 6, }, + { 4, 6, 5, }, + { 6, 5, 4, }, + { 5, 4, 6, }, + { 5, 6, 7, }, + { 5, 7, 6, }, + { 7, 6, 5, }, + { 6, 5, 7, }, + { 6, 7, 8, }, + { 6, 8, 7, }, + { 8, 7, 6, }, + { 7, 6, 8, }, }; - - // Init with direct. - ProxyConfigServiceImpl::ProxyConfig init_config; - SetAutomaticProxy(MK_MODE(DIRECT), MK_SRC(OWNER), NULL, &init_config, - &init_config.automatic_proxy); - CreateConfigService(init_config); - - ProxyChangedObserver observer(config_service()); - - // Set to pac script from UI. - EXPECT_TRUE(config_service()->UISetProxyConfigToPACScript( - GURL("http://wpad.dat"))); - // Retrieve config from IO thread. - net::ProxyConfig io_config; - SyncGetLatestProxyConfig(&io_config); - - // Observer should have gotten the same new proxy config. - EXPECT_EQ(net::ProxyConfigService::CONFIG_VALID, observer.availability()); - EXPECT_TRUE(io_config.Equals(observer.config())); -} - -TEST_F(ProxyConfigServiceImplTest, SerializeAndDeserializeForNetwork) { - for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { - if (!tests[i].is_valid) - continue; - - SCOPED_TRACE(StringPrintf("Test[%" PRIuS "] %s", i, - tests[i].description.c_str())); - - ProxyConfigServiceImpl::ProxyConfig source_config; - InitConfigWithTestInput(tests[i].input, MK_SRC(OWNER), &source_config); - - // Serialize source_config into std::string. - std::string serialized_value; - EXPECT_TRUE(source_config.SerializeForNetwork(&serialized_value)); - - // Deserialize std:string into target_config. - ProxyConfigServiceImpl::ProxyConfig target_config; - EXPECT_TRUE(target_config.DeserializeForNetwork(serialized_value)); - - // Compare the configs after serialization and deserialization. - net::ProxyConfig net_src_cfg; - net::ProxyConfig net_tgt_cfg; - source_config.ToNetProxyConfig(&net_src_cfg); - target_config.ToNetProxyConfig(&net_tgt_cfg); -#if !defined(NDEBUG) - if (!net_src_cfg.Equals(net_tgt_cfg)) { - std::string src_output, tgt_output; - JSONStringValueSerializer src_serializer(&src_output); - src_serializer.Serialize(*net_src_cfg.ToValue()); - JSONStringValueSerializer tgt_serializer(&tgt_output); - tgt_serializer.Serialize(*net_tgt_cfg.ToValue()); - VLOG(1) << "source:\n" << src_output - << "\ntarget:\n" << tgt_output; - } -#endif // !defined(NDEBUG) - EXPECT_TRUE(net_src_cfg.Equals(net_tgt_cfg)); + for (size_t i = 0; i < ARRAYSIZE_UNSAFE(proxies); ++i) { + const TestParams& managed_params = tests[proxies[i][0]]; + const TestParams& recommended_params = tests[proxies[i][1]]; + const TestParams& network_params = tests[proxies[i][2]]; + + SCOPED_TRACE(StringPrintf( + "Test[%" PRIuS "] managed=[%s], recommended=[%s], network=[%s]", i, + managed_params.description.c_str(), + recommended_params.description.c_str(), + network_params.description.c_str())); + + ProxyConfigServiceImpl::ProxyConfig managed_config; + InitConfigWithTestInput(managed_params.input, &managed_config); + ProxyConfigServiceImpl::ProxyConfig recommended_config; + InitConfigWithTestInput(recommended_params.input, &recommended_config); + ProxyConfigServiceImpl::ProxyConfig network_config; + InitConfigWithTestInput(network_params.input, &network_config); + + // Managed proxy pref should take effect over recommended proxy and + // non-existent network proxy. + config_service_impl_->SetTesting(NULL); + pref_service_.SetManagedPref(prefs::kProxy, + managed_config.ToPrefProxyConfig()); + pref_service_.SetRecommendedPref(prefs::kProxy, + recommended_config.ToPrefProxyConfig()); + net::ProxyConfig actual_config; + EXPECT_EQ(MK_AVAIL(VALID), SyncGetLatestProxyConfig(&actual_config)); + EXPECT_EQ(managed_params.auto_detect, actual_config.auto_detect()); + EXPECT_EQ(managed_params.pac_url, actual_config.pac_url()); + EXPECT_TRUE(managed_params.proxy_rules.Matches( + actual_config.proxy_rules())); + + // Recommended proxy pref should take effect when managed proxy pref is + // removed. + pref_service_.RemoveManagedPref(prefs::kProxy); + EXPECT_EQ(MK_AVAIL(VALID), SyncGetLatestProxyConfig(&actual_config)); + EXPECT_EQ(recommended_params.auto_detect, actual_config.auto_detect()); + EXPECT_EQ(recommended_params.pac_url, actual_config.pac_url()); + EXPECT_TRUE(recommended_params.proxy_rules.Matches( + actual_config.proxy_rules())); + + // Network proxy should take take effect over recommended proxy pref. + config_service_impl_->SetTesting(&network_config); + EXPECT_EQ(MK_AVAIL(VALID), SyncGetLatestProxyConfig(&actual_config)); + EXPECT_EQ(network_params.auto_detect, actual_config.auto_detect()); + EXPECT_EQ(network_params.pac_url, actual_config.pac_url()); + EXPECT_TRUE(network_params.proxy_rules.Matches( + actual_config.proxy_rules())); + + // Managed proxy pref should take effect over network proxy. + pref_service_.SetManagedPref(prefs::kProxy, + managed_config.ToPrefProxyConfig()); + EXPECT_EQ(MK_AVAIL(VALID), SyncGetLatestProxyConfig(&actual_config)); + EXPECT_EQ(managed_params.auto_detect, actual_config.auto_detect()); + EXPECT_EQ(managed_params.pac_url, actual_config.pac_url()); + EXPECT_TRUE(managed_params.proxy_rules.Matches( + actual_config.proxy_rules())); + + // Network proxy should take effect over recommended proxy pref when managed + // proxy pref is removed. + pref_service_.RemoveManagedPref(prefs::kProxy); + EXPECT_EQ(MK_AVAIL(VALID), SyncGetLatestProxyConfig(&actual_config)); + EXPECT_EQ(network_params.auto_detect, actual_config.auto_detect()); + EXPECT_EQ(network_params.pac_url, actual_config.pac_url()); + EXPECT_TRUE(network_params.proxy_rules.Matches( + actual_config.proxy_rules())); + + // Removing recommended proxy pref should have no effect on network proxy. + pref_service_.RemoveRecommendedPref(prefs::kProxy); + EXPECT_EQ(MK_AVAIL(VALID), SyncGetLatestProxyConfig(&actual_config)); + EXPECT_EQ(network_params.auto_detect, actual_config.auto_detect()); + EXPECT_EQ(network_params.pac_url, actual_config.pac_url()); + EXPECT_TRUE(network_params.proxy_rules.Matches( + actual_config.proxy_rules())); } } -TEST_F(ProxyConfigServiceImplTest, ReadWriteAccessForPolicySource) { - for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { - if (!tests[i].test_read_write_access) - continue; - SCOPED_TRACE(StringPrintf("Test[%" PRIuS "] %s", i, - tests[i].description.c_str())); - TestReadWriteAccessForMode(tests[i].input, MK_SRC(POLICY)); - } -} - -TEST_F(ProxyConfigServiceImplTest, ReadWriteAccessForOwnerSource) { - for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { - if (!tests[i].test_read_write_access) - continue; - SCOPED_TRACE(StringPrintf("Test[%" PRIuS "] %s", i, - tests[i].description.c_str())); - TestReadWriteAccessForMode(tests[i].input, MK_SRC(OWNER)); - } -} - -TEST_F(ProxyConfigServiceImplTest, ReadWriteAccessForMixedSchemes) { - const char* http_uri = "www.google.com:80"; - const char* https_uri = "www.foo.com:110"; - const char* ftp_uri = "ftp.foo.com:121"; - const char* socks_uri = "socks.com:888"; - - // Init with policy source. - TestReadWriteAccessForScheme(MK_SRC(POLICY), http_uri, "http"); - TestReadWriteAccessForScheme(MK_SRC(POLICY), https_uri, "https"); - TestReadWriteAccessForScheme(MK_SRC(POLICY), ftp_uri, "ftp"); - TestReadWriteAccessForScheme(MK_SRC(POLICY), socks_uri, "socks"); - - // Init with owner source. - TestReadWriteAccessForScheme(MK_SRC(OWNER), http_uri, "http"); - TestReadWriteAccessForScheme(MK_SRC(OWNER), https_uri, "https"); - TestReadWriteAccessForScheme(MK_SRC(OWNER), ftp_uri, "ftp"); - TestReadWriteAccessForScheme(MK_SRC(OWNER), socks_uri, "socks"); -} +} // namespace } // namespace chromeos diff --git a/chrome/browser/chromeos/proxy_cros_settings_provider.cc b/chrome/browser/chromeos/proxy_cros_settings_provider.cc index 58fb046..85a89a1 100644 --- a/chrome/browser/chromeos/proxy_cros_settings_provider.cc +++ b/chrome/browser/chromeos/proxy_cros_settings_provider.cc @@ -7,6 +7,7 @@ #include "base/string_util.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/chromeos/cros_settings.h" +#include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser_list.h" namespace chromeos { @@ -45,30 +46,22 @@ static const char* const kProxySettings[] = { //------------------ ProxyCrosSettingsProvider: public methods ----------------- -ProxyCrosSettingsProvider::ProxyCrosSettingsProvider() { } +ProxyCrosSettingsProvider::ProxyCrosSettingsProvider(Profile* profile) + : profile_(profile) { +} void ProxyCrosSettingsProvider::SetCurrentNetwork(const std::string& network) { - if (!GetConfigService()->UISetCurrentNetwork(network)) - return; + GetConfigService()->UISetCurrentNetwork(network); for (size_t i = 0; i < arraysize(kProxySettings); ++i) CrosSettings::Get()->FireObservers(kProxySettings[i]); } void ProxyCrosSettingsProvider::MakeActiveNetworkCurrent() { - if (!GetConfigService()->UIMakeActiveNetworkCurrent()) - return; + GetConfigService()->UIMakeActiveNetworkCurrent(); for (size_t i = 0; i < arraysize(kProxySettings); ++i) CrosSettings::Get()->FireObservers(kProxySettings[i]); } -bool ProxyCrosSettingsProvider::IsUsingSharedProxies() const { - return GetConfigService()->use_shared_proxies(); -} - -const std::string& ProxyCrosSettingsProvider::GetCurrentNetworkName() const { - return GetConfigService()->current_network_name(); -} - void ProxyCrosSettingsProvider::DoSet(const std::string& path, Value* in_value) { if (!in_value) { @@ -235,6 +228,7 @@ bool ProxyCrosSettingsProvider::Get(const std::string& path, Value** out_value) const { bool found = false; bool managed = false; + std::string controlled_by; Value* data = NULL; chromeos::ProxyConfigServiceImpl* config_service = GetConfigService(); chromeos::ProxyConfigServiceImpl::ProxyConfig config; @@ -274,6 +268,21 @@ bool ProxyCrosSettingsProvider::Get(const std::string& path, } else { data = Value::CreateIntegerValue(1); } + switch (config.state) { + case ProxyPrefs::CONFIG_POLICY: + controlled_by = "policyManagedPrefsBannerText"; + break; + case ProxyPrefs::CONFIG_EXTENSION: + controlled_by = "extensionManagedPrefsBannerText"; + break; + case ProxyPrefs::CONFIG_OTHER_PRECEDE: + controlled_by = "unmodifiablePrefsBannerText"; + break; + default: + if (!config.user_modifiable) + controlled_by = "enableSharedProxiesBannerText"; + break; + } found = true; } else if (path == kProxySingle) { data = Value::CreateBooleanValue(config.mode == @@ -312,6 +321,10 @@ bool ProxyCrosSettingsProvider::Get(const std::string& path, data = Value::CreateStringValue(""); dict->Set("value", data); dict->SetBoolean("managed", managed); + if (path == kProxyType) { + dict->SetString("controlledBy", controlled_by); + dict->SetBoolean("disabled", !config.user_modifiable); + } *out_value = dict; return true; } else { @@ -328,7 +341,7 @@ bool ProxyCrosSettingsProvider::HandlesSetting(const std::string& path) const { chromeos::ProxyConfigServiceImpl* ProxyCrosSettingsProvider::GetConfigService() const { - return g_browser_process->chromeos_proxy_config_service_impl(); + return profile_->GetProxyConfigTracker(); } net::ProxyServer ProxyCrosSettingsProvider::CreateProxyServerFromHost( diff --git a/chrome/browser/chromeos/proxy_cros_settings_provider.h b/chrome/browser/chromeos/proxy_cros_settings_provider.h index 8680140..5532fae 100644 --- a/chrome/browser/chromeos/proxy_cros_settings_provider.h +++ b/chrome/browser/chromeos/proxy_cros_settings_provider.h @@ -11,11 +11,13 @@ #include "chrome/browser/chromeos/cros_settings_provider.h" #include "chrome/browser/chromeos/proxy_config_service_impl.h" +class Profile; + namespace chromeos { class ProxyCrosSettingsProvider : public CrosSettingsProvider { public: - ProxyCrosSettingsProvider(); + explicit ProxyCrosSettingsProvider(Profile* profile); // CrosSettingsProvider implementation. virtual bool Get(const std::string& path, Value** out_value) const OVERRIDE; virtual bool HandlesSetting(const std::string& path) const OVERRIDE; @@ -28,13 +30,6 @@ class ProxyCrosSettingsProvider : public CrosSettingsProvider { // displayed and possibly edited on. void MakeActiveNetworkCurrent(); - // Returns name of current network that has been set via SetCurrentNetwork or - // MakeActiveNetworkCurrent. - const std::string& GetCurrentNetworkName() const; - - // Returns true if user has selected to use shared proxies. - bool IsUsingSharedProxies() const; - private: // CrosSettingsProvider implementation. virtual void DoSet(const std::string& path, Value* value) OVERRIDE; @@ -57,6 +52,8 @@ class ProxyCrosSettingsProvider : public CrosSettingsProvider { Value* CreateServerPortValue( const ProxyConfigServiceImpl::ProxyConfig::ManualProxy& proxy) const; + Profile* profile_; // Weak ptr. + DISALLOW_COPY_AND_ASSIGN(ProxyCrosSettingsProvider); }; diff --git a/chrome/browser/chromeos/status/network_menu.cc b/chrome/browser/chromeos/status/network_menu.cc index ea38941..ad6e5db 100644 --- a/chrome/browser/chromeos/status/network_menu.cc +++ b/chrome/browser/chromeos/status/network_menu.cc @@ -17,13 +17,10 @@ #include "chrome/browser/chromeos/sim_dialog_delegate.h" #include "chrome/browser/chromeos/status/network_menu_icon.h" #include "chrome/browser/defaults.h" -#include "chrome/browser/prefs/pref_service.h" -#include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/views/window.h" #include "chrome/common/chrome_switches.h" -#include "chrome/common/pref_names.h" #include "chrome/common/url_constants.h" #include "content/public/browser/browser_thread.h" #include "grit/generated_resources.h" @@ -919,35 +916,15 @@ void MoreMenuModel::InitMenuItems( bool oobe = !should_open_button_options; // we don't show options for OOBE. bool connected = cros->Connected(); // always call for test expectations. if (!oobe) { - int flags = FLAG_OPTIONS; int message_id = -1; - if (is_browser_mode) { + if (is_browser_mode) message_id = IDS_STATUSBAR_NETWORK_OPEN_OPTIONS_DIALOG; - } else if (connected) { - const PrefService::Preference* proxy_pref = - ProfileManager::GetDefaultProfile()->GetPrefs()->FindPreference( - prefs::kProxy); - if (proxy_pref && (!proxy_pref->IsUserModifiable() || - proxy_pref->HasUserSetting())) { - flags |= FLAG_DISABLED; - if (proxy_pref->IsManaged()) { - message_id = - IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_POLICY_MANAGED_PROXY_TEXT; - } else if (proxy_pref->IsExtensionControlled()) { - message_id = - IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_EXTENSION_MANAGED_PROXY_TEXT; - } else { - message_id = - IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_UNMODIFIABLE_PROXY_TEXT; - } - } else { - message_id = IDS_STATUSBAR_NETWORK_OPEN_PROXY_SETTINGS_DIALOG; - } - } + else if (connected) + message_id = IDS_STATUSBAR_NETWORK_OPEN_PROXY_SETTINGS_DIALOG; if (message_id != -1) { link_items.push_back(MenuItem(ui::MenuModel::TYPE_COMMAND, l10n_util::GetStringUTF16(message_id), - SkBitmap(), std::string(), flags)); + SkBitmap(), std::string(), FLAG_OPTIONS)); } } diff --git a/chrome/browser/extensions/extension_proxy_apitest.cc b/chrome/browser/extensions/extension_proxy_apitest.cc index 96b5494..4b84316 100644 --- a/chrome/browser/extensions/extension_proxy_apitest.cc +++ b/chrome/browser/extensions/extension_proxy_apitest.cc @@ -255,8 +255,19 @@ IN_PROC_BROWSER_TEST_F(ProxySettingsApiTest, pref_service); } +// This test sets proxy to an inavalid host "does.not.exist" and then fetches +// a page from localhost, expecting an error since host is invalid. +// On ChromeOS, localhost is by default bypassed, so the page from localhost +// will be fetched successfully, resulting in no error. Hence this test +// shouldn't run on ChromeOS. +#if defined(OS_CHROMEOS) +#define MAYBE_ProxyEventsInvalidProxy DISABLED_ProxyEventsInvalidProxy +#else +#define MAYBE_ProxyEventsInvalidProxy ProxyEventsInvalidProxy +#endif // defined(OS_CHROMEOS) + // Tests error events: invalid proxy -IN_PROC_BROWSER_TEST_F(ProxySettingsApiTest, ProxyEventsInvalidProxy) { +IN_PROC_BROWSER_TEST_F(ProxySettingsApiTest, MAYBE_ProxyEventsInvalidProxy) { ASSERT_TRUE(StartTestServer()); ASSERT_TRUE( RunExtensionSubtest("proxy/events", "invalid_proxy.html")) << message_; diff --git a/chrome/browser/io_thread.cc b/chrome/browser/io_thread.cc index 666f3c0..b4307f18 100644 --- a/chrome/browser/io_thread.cc +++ b/chrome/browser/io_thread.cc @@ -24,7 +24,7 @@ #include "chrome/browser/net/chrome_url_request_context.h" #include "chrome/browser/net/connect_interceptor.h" #include "chrome/browser/net/passive_log_collector.h" -#include "chrome/browser/net/pref_proxy_config_service.h" +#include "chrome/browser/net/pref_proxy_config_tracker.h" #include "chrome/browser/net/proxy_service_factory.h" #include "chrome/browser/net/sdch_dictionary_fetcher.h" #include "chrome/browser/prefs/pref_service.h" @@ -62,6 +62,10 @@ #include "net/ocsp/nss_ocsp.h" #endif // defined(USE_NSS) +#if defined(OS_CHROMEOS) +#include "chrome/browser/chromeos/proxy_config_service_impl.h" +#endif // defined(OS_CHROMEOS) + using content::BrowserThread; namespace { @@ -360,7 +364,8 @@ IOThread::IOThread( auth_delegate_whitelist_ = local_state->GetString( prefs::kAuthNegotiateDelegateWhitelist); gssapi_library_name_ = local_state->GetString(prefs::kGSSAPILibraryName); - pref_proxy_config_tracker_ = new PrefProxyConfigTracker(local_state); + pref_proxy_config_tracker_.reset( + ProxyServiceFactory::CreatePrefProxyConfigTracker(local_state)); ChromeNetworkDelegate::InitializeReferrersEnabled(&system_enable_referrers_, local_state); ssl_config_service_manager_.reset( @@ -371,7 +376,7 @@ IOThread::IOThread( } IOThread::~IOThread() { - if (pref_proxy_config_tracker_) + if (pref_proxy_config_tracker_.get()) pref_proxy_config_tracker_->DetachFromPrefService(); // We cannot rely on our base class to stop the thread since we want our // CleanUp function to run. @@ -579,9 +584,13 @@ void IOThread::InitSystemRequestContext() { // If we're in unit_tests, IOThread may not be run. if (!message_loop()) return; - system_proxy_config_service_.reset( - ProxyServiceFactory::CreateProxyConfigService( - pref_proxy_config_tracker_)); + ChromeProxyConfigService* proxy_config_service = + ProxyServiceFactory::CreateProxyConfigService(); + system_proxy_config_service_.reset(proxy_config_service); + if (pref_proxy_config_tracker_.get()) { + pref_proxy_config_tracker_->SetChromeProxyConfigService( + proxy_config_service); + } system_url_request_context_getter_ = new SystemURLRequestContextGetter(this); message_loop()->PostTask( diff --git a/chrome/browser/io_thread.h b/chrome/browser/io_thread.h index 1918e6e..da09839 100644 --- a/chrome/browser/io_thread.h +++ b/chrome/browser/io_thread.h @@ -21,7 +21,7 @@ class ChromeNetLog; class ChromeURLRequestContextGetter; class ExtensionEventRouterForwarder; class MediaInternals; -class PrefProxyConfigTracker; +class PrefProxyConfigTrackerImpl; class PrefService; class SystemURLRequestContextGetter; @@ -178,7 +178,7 @@ class IOThread : public content::BrowserProcessSubThread { // which gets posted by calling certain member functions of IOThread. scoped_ptr<net::ProxyConfigService> system_proxy_config_service_; - scoped_refptr<PrefProxyConfigTracker> pref_proxy_config_tracker_; + scoped_ptr<PrefProxyConfigTrackerImpl> pref_proxy_config_tracker_; scoped_refptr<net::URLRequestContextGetter> system_url_request_context_getter_; diff --git a/chrome/browser/net/pref_proxy_config_service.cc b/chrome/browser/net/pref_proxy_config_service.cc deleted file mode 100644 index a4f578c..0000000 --- a/chrome/browser/net/pref_proxy_config_service.cc +++ /dev/null @@ -1,280 +0,0 @@ -// Copyright (c) 2011 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/net/pref_proxy_config_service.h" - -#include "base/values.h" -#include "chrome/browser/prefs/pref_service.h" -#include "chrome/browser/prefs/pref_set_observer.h" -#include "chrome/browser/prefs/proxy_config_dictionary.h" -#include "chrome/common/chrome_notification_types.h" -#include "chrome/common/pref_names.h" -#include "content/public/browser/browser_thread.h" -#include "content/public/browser/notification_details.h" -#include "content/public/browser/notification_source.h" - -using content::BrowserThread; - -PrefProxyConfigTracker::PrefProxyConfigTracker(PrefService* pref_service) - : pref_service_(pref_service) { - config_state_ = ReadPrefConfig(&pref_config_); - proxy_prefs_observer_.reset( - PrefSetObserver::CreateProxyPrefSetObserver(pref_service_, this)); -} - -PrefProxyConfigTracker::~PrefProxyConfigTracker() { - DCHECK(pref_service_ == NULL); -} - -PrefProxyConfigTracker::ConfigState - PrefProxyConfigTracker::GetProxyConfig(net::ProxyConfig* config) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - if (config_state_ != CONFIG_UNSET) - *config = pref_config_; - return config_state_; -} - -void PrefProxyConfigTracker::DetachFromPrefService() { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - // Stop notifications. - proxy_prefs_observer_.reset(); - pref_service_ = NULL; -} - -void PrefProxyConfigTracker::AddObserver( - PrefProxyConfigTracker::Observer* observer) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - observers_.AddObserver(observer); -} - -void PrefProxyConfigTracker::RemoveObserver( - PrefProxyConfigTracker::Observer* observer) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - observers_.RemoveObserver(observer); -} - -void PrefProxyConfigTracker::Observe( - int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - if (type == chrome::NOTIFICATION_PREF_CHANGED && - content::Source<PrefService>(source).ptr() == pref_service_) { - net::ProxyConfig new_config; - ConfigState config_state = ReadPrefConfig(&new_config); - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - NewRunnableMethod(this, - &PrefProxyConfigTracker::InstallProxyConfig, - new_config, config_state)); - } else { - NOTREACHED() << "Unexpected notification of type " << type; - } -} - -void PrefProxyConfigTracker::InstallProxyConfig( - const net::ProxyConfig& config, - PrefProxyConfigTracker::ConfigState config_state) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - if (config_state_ != config_state || - (config_state_ != CONFIG_UNSET && !pref_config_.Equals(config))) { - config_state_ = config_state; - if (config_state_ != CONFIG_UNSET) - pref_config_ = config; - FOR_EACH_OBSERVER(Observer, observers_, OnPrefProxyConfigChanged()); - } -} - -PrefProxyConfigTracker::ConfigState - PrefProxyConfigTracker::ReadPrefConfig(net::ProxyConfig* config) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - - // Clear the configuration. - *config = net::ProxyConfig(); - - const PrefService::Preference* pref = - pref_service_->FindPreference(prefs::kProxy); - DCHECK(pref); - - const DictionaryValue* dict = pref_service_->GetDictionary(prefs::kProxy); - DCHECK(dict); - ProxyConfigDictionary proxy_dict(dict); - - if (PrefConfigToNetConfig(proxy_dict, config)) { - return (!pref->IsUserModifiable() || pref->HasUserSetting()) ? - CONFIG_PRESENT : CONFIG_FALLBACK; - } - - return CONFIG_UNSET; -} - -bool PrefProxyConfigTracker::PrefConfigToNetConfig( - const ProxyConfigDictionary& proxy_dict, - net::ProxyConfig* config) { - ProxyPrefs::ProxyMode mode; - if (!proxy_dict.GetMode(&mode)) { - // Fall back to system settings if the mode preference is invalid. - return false; - } - - 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: { - std::string proxy_pac; - if (!proxy_dict.GetPacUrl(&proxy_pac)) { - LOG(ERROR) << "Proxy settings request PAC script but do not specify " - << "its URL. Falling back to direct connection."; - return true; - } - 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); - bool pac_mandatory = false; - proxy_dict.GetPacMandatory(&pac_mandatory); - config->set_pac_mandatory(pac_mandatory); - return true; - } - case ProxyPrefs::MODE_FIXED_SERVERS: { - std::string proxy_server; - if (!proxy_dict.GetProxyServer(&proxy_server)) { - LOG(ERROR) << "Proxy settings request fixed proxy servers but do not " - << "specify their URLs. Falling back to direct connection."; - return true; - } - config->proxy_rules().ParseFromString(proxy_server); - - std::string proxy_bypass; - if (proxy_dict.GetBypassList(&proxy_bypass)) { - config->proxy_rules().bypass_rules.ParseFromString(proxy_bypass); - } - return true; - } - case ProxyPrefs::kModeCount: { - // Fall through to NOTREACHED(). - } - } - NOTREACHED() << "Unknown proxy mode, falling back to system settings."; - return false; -} - -PrefProxyConfigService::PrefProxyConfigService( - PrefProxyConfigTracker* tracker, - net::ProxyConfigService* base_service) - : base_service_(base_service), - pref_config_tracker_(tracker), - registered_observers_(false) { -} - -PrefProxyConfigService::~PrefProxyConfigService() { - if (registered_observers_) { - base_service_->RemoveObserver(this); - pref_config_tracker_->RemoveObserver(this); - } -} - -void PrefProxyConfigService::AddObserver( - net::ProxyConfigService::Observer* observer) { - RegisterObservers(); - observers_.AddObserver(observer); -} - -void PrefProxyConfigService::RemoveObserver( - net::ProxyConfigService::Observer* observer) { - observers_.RemoveObserver(observer); -} - -net::ProxyConfigService::ConfigAvailability - PrefProxyConfigService::GetLatestProxyConfig(net::ProxyConfig* config) { - RegisterObservers(); - net::ProxyConfig pref_config; - PrefProxyConfigTracker::ConfigState state = - pref_config_tracker_->GetProxyConfig(&pref_config); - if (state == PrefProxyConfigTracker::CONFIG_PRESENT) { - *config = pref_config; - return CONFIG_VALID; - } - - // Ask the base service. - ConfigAvailability available = base_service_->GetLatestProxyConfig(config); - - // Base service doesn't have a configuration, fall back to prefs or default. - if (available == CONFIG_UNSET) { - if (state == PrefProxyConfigTracker::CONFIG_FALLBACK) - *config = pref_config; - else - *config = net::ProxyConfig::CreateDirect(); - return CONFIG_VALID; - } - - return available; -} - -void PrefProxyConfigService::OnLazyPoll() { - base_service_->OnLazyPoll(); -} - -void PrefProxyConfigService::OnProxyConfigChanged( - const net::ProxyConfig& config, - ConfigAvailability availability) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - - // Check whether there is a proxy configuration defined by preferences. In - // this case that proxy configuration takes precedence and the change event - // from the delegate proxy service can be disregarded. - net::ProxyConfig actual_config; - if (pref_config_tracker_->GetProxyConfig(&actual_config) != - PrefProxyConfigTracker::CONFIG_PRESENT) { - availability = GetLatestProxyConfig(&actual_config); - FOR_EACH_OBSERVER(net::ProxyConfigService::Observer, observers_, - OnProxyConfigChanged(actual_config, availability)); - } -} - -void PrefProxyConfigService::OnPrefProxyConfigChanged() { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - - // Evaluate the proxy configuration. If GetLatestProxyConfig returns - // CONFIG_PENDING, we are using the system proxy service, but it doesn't have - // a valid configuration yet. Once it is ready, OnProxyConfigChanged() will be - // called and broadcast the proxy configuration. - // Note: If a switch between a preference proxy configuration and the system - // proxy configuration occurs an unnecessary notification might get send if - // the two configurations agree. This case should be rare however, so we don't - // handle that case specially. - net::ProxyConfig new_config; - ConfigAvailability availability = GetLatestProxyConfig(&new_config); - if (availability != CONFIG_PENDING) { - FOR_EACH_OBSERVER(net::ProxyConfigService::Observer, observers_, - OnProxyConfigChanged(new_config, availability)); - } -} - -void PrefProxyConfigService::RegisterObservers() { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - if (!registered_observers_) { - base_service_->AddObserver(this); - pref_config_tracker_->AddObserver(this); - registered_observers_ = true; - } -} - -// static -void PrefProxyConfigService::RegisterPrefs(PrefService* pref_service) { - DictionaryValue* default_settings = ProxyConfigDictionary::CreateSystem(); - pref_service->RegisterDictionaryPref(prefs::kProxy, - default_settings, - PrefService::UNSYNCABLE_PREF); -} diff --git a/chrome/browser/net/pref_proxy_config_service.h b/chrome/browser/net/pref_proxy_config_service.h deleted file mode 100644 index 3f9ee75..0000000 --- a/chrome/browser/net/pref_proxy_config_service.h +++ /dev/null @@ -1,148 +0,0 @@ -// Copyright (c) 2011 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_NET_PREF_PROXY_CONFIG_SERVICE_H_ -#define CHROME_BROWSER_NET_PREF_PROXY_CONFIG_SERVICE_H_ -#pragma once - -#include "base/basictypes.h" -#include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" -#include "base/observer_list.h" -#include "chrome/browser/prefs/proxy_config_dictionary.h" -#include "content/public/browser/notification_observer.h" -#include "net/proxy/proxy_config.h" -#include "net/proxy/proxy_config_service.h" - -class PrefService; -class PrefSetObserver; - -// A helper class that tracks proxy preferences. It translates the configuration -// to net::ProxyConfig and proxies the result over to the IO thread for -// PrefProxyConfigService to use. -class PrefProxyConfigTracker - : public base::RefCountedThreadSafe<PrefProxyConfigTracker>, - public content::NotificationObserver { - public: - // Observer interface used to send out notifications on the IO thread about - // changes to the proxy configuration. - class Observer { - public: - virtual ~Observer() {} - virtual void OnPrefProxyConfigChanged() = 0; - }; - - // Return codes for GetProxyConfig. - enum ConfigState { - // Configuration is valid and present. - CONFIG_PRESENT, - // There is a fallback configuration present. - CONFIG_FALLBACK, - // Configuration is known to be not set. - CONFIG_UNSET, - }; - - explicit PrefProxyConfigTracker(PrefService* pref_service); - - // Observer manipulation is only valid on the IO thread. - void AddObserver(Observer* observer); - void RemoveObserver(Observer* observer); - - // Get the proxy configuration currently defined by preferences. Status is - // indicated in the return value. Writes the configuration to |config| unless - // the return value is CONFIG_UNSET, in which case |config| is not touched. - ConfigState GetProxyConfig(net::ProxyConfig* config); - - // Notifies the tracker that the pref service passed upon construction is - // about to go away. This must be called from the UI thread. - void DetachFromPrefService(); - - private: - friend class base::RefCountedThreadSafe<PrefProxyConfigTracker>; - virtual ~PrefProxyConfigTracker(); - - // content::NotificationObserver implementation: - virtual void Observe(int type, - const content::NotificationSource& source, - const content::NotificationDetails& details); - - // Install a new configuration. This is invoked on the IO thread to update - // the internal state after handling a pref change on the UI thread. - // |config_state| indicates the new state we're switching to, and |config| is - // the new preference-based proxy configuration if |config_state| is different - // from CONFIG_UNSET. - void InstallProxyConfig(const net::ProxyConfig& config, ConfigState state); - - // Creates a proxy configuration from proxy-related preferences. Configuration - // is stored in |config| and the return value indicates whether the - // configuration is valid. - ConfigState ReadPrefConfig(net::ProxyConfig* config); - - // Converts a ProxyConfigDictionary to net::ProxyConfig representation. - // Returns true if the data from in the dictionary is valid, false otherwise. - static bool PrefConfigToNetConfig(const ProxyConfigDictionary& proxy_dict, - net::ProxyConfig* config); - - // Configuration as defined by prefs. Only to be accessed from the IO thread - // (except for construction). - net::ProxyConfig pref_config_; - - // Tracks configuration state. |pref_config_| is valid only if |config_state_| - // is not CONFIG_UNSET. - ConfigState config_state_; - - // List of observers, accessed exclusively from the IO thread. - ObserverList<Observer, true> observers_; - - // Pref-related members that should only be accessed from the UI thread. - PrefService* pref_service_; - scoped_ptr<PrefSetObserver> proxy_prefs_observer_; - - DISALLOW_COPY_AND_ASSIGN(PrefProxyConfigTracker); -}; - -// A net::ProxyConfigService implementation that applies preference proxy -// settings as overrides to the proxy configuration determined by a baseline -// delegate ProxyConfigService. -class PrefProxyConfigService - : public net::ProxyConfigService, - public net::ProxyConfigService::Observer, - public PrefProxyConfigTracker::Observer { - public: - // Takes ownership of the passed |base_service|. - PrefProxyConfigService(PrefProxyConfigTracker* tracker, - net::ProxyConfigService* base_service); - virtual ~PrefProxyConfigService(); - - // ProxyConfigService implementation: - virtual void AddObserver(net::ProxyConfigService::Observer* observer); - virtual void RemoveObserver(net::ProxyConfigService::Observer* observer); - virtual ConfigAvailability GetLatestProxyConfig(net::ProxyConfig* config); - virtual void OnLazyPoll(); - - static void RegisterPrefs(PrefService* user_prefs); - - private: - // ProxyConfigService::Observer implementation: - virtual void OnProxyConfigChanged(const net::ProxyConfig& config, - ConfigAvailability availability); - - // PrefProxyConfigTracker::Observer implementation: - virtual void OnPrefProxyConfigChanged(); - - // Makes sure that the observer registrations with the base service and the - // tracker object are set up. - void RegisterObservers(); - - scoped_ptr<net::ProxyConfigService> base_service_; - ObserverList<net::ProxyConfigService::Observer, true> observers_; - scoped_refptr<PrefProxyConfigTracker> pref_config_tracker_; - - // Indicates whether the base service and tracker registrations are done. - bool registered_observers_; - - DISALLOW_COPY_AND_ASSIGN(PrefProxyConfigService); -}; - -#endif // CHROME_BROWSER_NET_PREF_PROXY_CONFIG_SERVICE_H_ diff --git a/chrome/browser/net/pref_proxy_config_tracker.h b/chrome/browser/net/pref_proxy_config_tracker.h new file mode 100644 index 0000000..45c00b4 --- /dev/null +++ b/chrome/browser/net/pref_proxy_config_tracker.h @@ -0,0 +1,23 @@ +// Copyright (c) 2011 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_NET_PREF_PROXY_CONFIG_TRACKER_H_ +#define CHROME_BROWSER_NET_PREF_PROXY_CONFIG_TRACKER_H_ +#pragma once + +#include "chrome/browser/net/pref_proxy_config_tracker_impl.h" + +#if defined(OS_CHROMEOS) +namespace chromeos { +class ProxyConfigServiceImpl; +} +#endif // defined(OS_CHROMEOS) + +#if defined(OS_CHROMEOS) +typedef chromeos::ProxyConfigServiceImpl PrefProxyConfigTracker; +#else +typedef PrefProxyConfigTrackerImpl PrefProxyConfigTracker; +#endif // defined(OS_CHROMEOS) + +#endif // CHROME_BROWSER_NET_PREF_PROXY_CONFIG_TRACKER_H_ diff --git a/chrome/browser/net/pref_proxy_config_tracker_impl.cc b/chrome/browser/net/pref_proxy_config_tracker_impl.cc new file mode 100644 index 0000000..319e9a0 --- /dev/null +++ b/chrome/browser/net/pref_proxy_config_tracker_impl.cc @@ -0,0 +1,339 @@ +// Copyright (c) 2011 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/net/pref_proxy_config_tracker_impl.h" + +#include "base/bind.h" +#include "base/values.h" +#include "chrome/browser/prefs/pref_service.h" +#include "chrome/browser/prefs/pref_set_observer.h" +#include "chrome/browser/prefs/proxy_config_dictionary.h" +#include "chrome/common/chrome_notification_types.h" +#include "chrome/common/pref_names.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/notification_details.h" +#include "content/public/browser/notification_source.h" + +using content::BrowserThread; + +//============================= ChromeProxyConfigService ======================= + +ChromeProxyConfigService::ChromeProxyConfigService( + net::ProxyConfigService* base_service) + : base_service_(base_service), + pref_config_state_(ProxyPrefs::CONFIG_UNSET), + registered_observer_(false) { +} + +ChromeProxyConfigService::~ChromeProxyConfigService() { + if (registered_observer_ && base_service_.get()) + base_service_->RemoveObserver(this); +} + +void ChromeProxyConfigService::AddObserver( + net::ProxyConfigService::Observer* observer) { + RegisterObserver(); + observers_.AddObserver(observer); +} + +void ChromeProxyConfigService::RemoveObserver( + net::ProxyConfigService::Observer* observer) { + observers_.RemoveObserver(observer); +} + +net::ProxyConfigService::ConfigAvailability + ChromeProxyConfigService::GetLatestProxyConfig(net::ProxyConfig* config) { + RegisterObserver(); + + // Ask the base service if available. + net::ProxyConfig system_config; + ConfigAvailability system_availability = + net::ProxyConfigService::CONFIG_UNSET; + if (base_service_.get()) + system_availability = base_service_->GetLatestProxyConfig(&system_config); + + ProxyPrefs::ConfigState config_state; + return PrefProxyConfigTrackerImpl::GetEffectiveProxyConfig( + pref_config_state_, pref_config_, + system_availability, system_config, false, + &config_state, config); +} + +void ChromeProxyConfigService::OnLazyPoll() { + if (base_service_.get()) + base_service_->OnLazyPoll(); +} + +void ChromeProxyConfigService::UpdateProxyConfig( + ProxyPrefs::ConfigState config_state, + const net::ProxyConfig& config) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + + pref_config_state_ = config_state; + pref_config_ = config; + + if (!observers_.size()) + return; + + // Evaluate the proxy configuration. If GetLatestProxyConfig returns + // CONFIG_PENDING, we are using the system proxy service, but it doesn't have + // a valid configuration yet. Once it is ready, OnProxyConfigChanged() will be + // called and broadcast the proxy configuration. + // Note: If a switch between a preference proxy configuration and the system + // proxy configuration occurs an unnecessary notification might get send if + // the two configurations agree. This case should be rare however, so we don't + // handle that case specially. + net::ProxyConfig new_config; + ConfigAvailability availability = GetLatestProxyConfig(&new_config); + if (availability != CONFIG_PENDING) { + FOR_EACH_OBSERVER(net::ProxyConfigService::Observer, observers_, + OnProxyConfigChanged(new_config, availability)); + } +} + +void ChromeProxyConfigService::OnProxyConfigChanged( + const net::ProxyConfig& config, + ConfigAvailability availability) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + + // Check whether there is a proxy configuration defined by preferences. In + // this case that proxy configuration takes precedence and the change event + // from the delegate proxy service can be disregarded. + if (!PrefProxyConfigTrackerImpl::PrefPrecedes(pref_config_state_)) { + net::ProxyConfig actual_config; + availability = GetLatestProxyConfig(&actual_config); + FOR_EACH_OBSERVER(net::ProxyConfigService::Observer, observers_, + OnProxyConfigChanged(actual_config, availability)); + } +} + +void ChromeProxyConfigService::RegisterObserver() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + if (!registered_observer_ && base_service_.get()) { + base_service_->AddObserver(this); + registered_observer_ = true; + } +} + +//========================= PrefProxyConfigTrackerImpl ========================= + +PrefProxyConfigTrackerImpl::PrefProxyConfigTrackerImpl( + PrefService* pref_service) + : pref_service_(pref_service), + chrome_proxy_config_service_(NULL), + update_pending_(true) { + config_state_ = ReadPrefConfig(&pref_config_); + proxy_prefs_observer_.reset( + PrefSetObserver::CreateProxyPrefSetObserver(pref_service_, this)); +} + +PrefProxyConfigTrackerImpl::~PrefProxyConfigTrackerImpl() { + DCHECK(pref_service_ == NULL); +} + +void PrefProxyConfigTrackerImpl::SetChromeProxyConfigService( + ChromeProxyConfigService* chrome_proxy_config_service) { + VLOG(1) << this << ": set chrome proxy config service to " + << chrome_proxy_config_service; + chrome_proxy_config_service_ = chrome_proxy_config_service; + if (chrome_proxy_config_service_ && update_pending_) + OnProxyConfigChanged(config_state_, pref_config_); +} + +void PrefProxyConfigTrackerImpl::DetachFromPrefService() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + // Stop notifications. + proxy_prefs_observer_.reset(); + pref_service_ = NULL; + SetChromeProxyConfigService(NULL); +} + +// static +bool PrefProxyConfigTrackerImpl::PrefPrecedes( + ProxyPrefs::ConfigState config_state) { + return config_state == ProxyPrefs::CONFIG_POLICY || + config_state == ProxyPrefs::CONFIG_EXTENSION || + config_state == ProxyPrefs::CONFIG_OTHER_PRECEDE; +} + +// static +net::ProxyConfigService::ConfigAvailability + PrefProxyConfigTrackerImpl::GetEffectiveProxyConfig( + ProxyPrefs::ConfigState pref_state, + const net::ProxyConfig& pref_config, + net::ProxyConfigService::ConfigAvailability system_availability, + const net::ProxyConfig& system_config, + bool ignore_fallback_config, + ProxyPrefs::ConfigState* effective_config_state, + net::ProxyConfig* effective_config) { + *effective_config_state = pref_state; + + if (PrefPrecedes(pref_state)) { + *effective_config = pref_config; + return net::ProxyConfigService::CONFIG_VALID; + } + + // If there's no system proxy config, fall back to prefs or default. + if (system_availability == net::ProxyConfigService::CONFIG_UNSET) { + if (pref_state == ProxyPrefs::CONFIG_FALLBACK && !ignore_fallback_config) + *effective_config = pref_config; + else + *effective_config = net::ProxyConfig::CreateDirect(); + return net::ProxyConfigService::CONFIG_VALID; + } + + *effective_config_state = ProxyPrefs::CONFIG_SYSTEM; + *effective_config = system_config; + return system_availability; +} + +// static +void PrefProxyConfigTrackerImpl::RegisterPrefs(PrefService* pref_service) { + DictionaryValue* default_settings = ProxyConfigDictionary::CreateSystem(); + pref_service->RegisterDictionaryPref(prefs::kProxy, + default_settings, + PrefService::UNSYNCABLE_PREF); +} + +ProxyPrefs::ConfigState PrefProxyConfigTrackerImpl::GetProxyConfig( + net::ProxyConfig* config) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + if (config_state_ != ProxyPrefs::CONFIG_UNSET) + *config = pref_config_; + return config_state_; +} + +void PrefProxyConfigTrackerImpl::OnProxyConfigChanged( + ProxyPrefs::ConfigState config_state, + const net::ProxyConfig& config) { + if (!chrome_proxy_config_service_) { + VLOG(1) << "No chrome proxy config service to push to UpdateProxyConfig"; + update_pending_ = true; + return; + } + update_pending_ = !BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + base::Bind(&ChromeProxyConfigService::UpdateProxyConfig, + base::Unretained(chrome_proxy_config_service_), + config_state, config)); + VLOG(1) << this << (update_pending_ ? ": Error" : ": Done") + << " pushing proxy to UpdateProxyConfig"; +} + +bool PrefProxyConfigTrackerImpl::PrefConfigToNetConfig( + const ProxyConfigDictionary& proxy_dict, + net::ProxyConfig* config) { + ProxyPrefs::ProxyMode mode; + if (!proxy_dict.GetMode(&mode)) { + // Fall back to system settings if the mode preference is invalid. + return false; + } + + 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: { + std::string proxy_pac; + if (!proxy_dict.GetPacUrl(&proxy_pac)) { + LOG(ERROR) << "Proxy settings request PAC script but do not specify " + << "its URL. Falling back to direct connection."; + return true; + } + 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); + bool pac_mandatory = false; + proxy_dict.GetPacMandatory(&pac_mandatory); + config->set_pac_mandatory(pac_mandatory); + return true; + } + case ProxyPrefs::MODE_FIXED_SERVERS: { + std::string proxy_server; + if (!proxy_dict.GetProxyServer(&proxy_server)) { + LOG(ERROR) << "Proxy settings request fixed proxy servers but do not " + << "specify their URLs. Falling back to direct connection."; + return true; + } + config->proxy_rules().ParseFromString(proxy_server); + + std::string proxy_bypass; + if (proxy_dict.GetBypassList(&proxy_bypass)) { + config->proxy_rules().bypass_rules.ParseFromString(proxy_bypass); + } + return true; + } + case ProxyPrefs::kModeCount: { + // Fall through to NOTREACHED(). + } + } + NOTREACHED() << "Unknown proxy mode, falling back to system settings."; + return false; +} + +void PrefProxyConfigTrackerImpl::Observe( + int type, + const content::NotificationSource& source, + const content::NotificationDetails& details) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + if (type == chrome::NOTIFICATION_PREF_CHANGED && + content::Source<PrefService>(source).ptr() == pref_service_) { + net::ProxyConfig new_config; + ProxyPrefs::ConfigState config_state = ReadPrefConfig(&new_config); + if (config_state_ != config_state || + (config_state_ != ProxyPrefs::CONFIG_UNSET && + !pref_config_.Equals(new_config))) { + config_state_ = config_state; + if (config_state_ != ProxyPrefs::CONFIG_UNSET) + pref_config_ = new_config; + update_pending_ = true; + } + if (update_pending_) + OnProxyConfigChanged(config_state, new_config); + } else { + NOTREACHED() << "Unexpected notification of type " << type; + } +} + +ProxyPrefs::ConfigState PrefProxyConfigTrackerImpl::ReadPrefConfig( + net::ProxyConfig* config) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + + // Clear the configuration and source. + *config = net::ProxyConfig(); + ProxyPrefs::ConfigState config_state = ProxyPrefs::CONFIG_UNSET; + + const PrefService::Preference* pref = + pref_service_->FindPreference(prefs::kProxy); + DCHECK(pref); + + const DictionaryValue* dict = pref_service_->GetDictionary(prefs::kProxy); + DCHECK(dict); + ProxyConfigDictionary proxy_dict(dict); + + if (PrefConfigToNetConfig(proxy_dict, config)) { + if (!pref->IsUserModifiable() || pref->HasUserSetting()) { + if (pref->IsManaged()) + config_state = ProxyPrefs::CONFIG_POLICY; + else if (pref->IsExtensionControlled()) + config_state = ProxyPrefs::CONFIG_EXTENSION; + else + config_state = ProxyPrefs::CONFIG_OTHER_PRECEDE; + } else { + config_state = ProxyPrefs::CONFIG_FALLBACK; + } + } + + return config_state; +} diff --git a/chrome/browser/net/pref_proxy_config_tracker_impl.h b/chrome/browser/net/pref_proxy_config_tracker_impl.h new file mode 100644 index 0000000..a96faf6 --- /dev/null +++ b/chrome/browser/net/pref_proxy_config_tracker_impl.h @@ -0,0 +1,155 @@ +// Copyright (c) 2011 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_NET_PREF_PROXY_CONFIG_TRACKER_IMPL_H_ +#define CHROME_BROWSER_NET_PREF_PROXY_CONFIG_TRACKER_IMPL_H_ +#pragma once + +#include "base/basictypes.h" +#include "base/memory/ref_counted.h" +#include "base/memory/scoped_ptr.h" +#include "base/observer_list.h" +#include "chrome/browser/prefs/proxy_config_dictionary.h" +#include "content/public/browser/notification_observer.h" +#include "net/proxy/proxy_config.h" +#include "net/proxy/proxy_config_service.h" + +class PrefService; +class PrefSetObserver; + +// A net::ProxyConfigService implementation that applies preference proxy +// settings (pushed from PrefProxyConfigTrackerImpl) as overrides to the proxy +// configuration determined by a baseline delegate ProxyConfigService on +// non-ChromeOS platforms. ChromeOS has its own implementation of overrides in +// chromeos::ProxyConfigServiceImpl. +class ChromeProxyConfigService + : public net::ProxyConfigService, + public net::ProxyConfigService::Observer { + public: + // Takes ownership of the passed |base_service|. + explicit ChromeProxyConfigService(net::ProxyConfigService* base_service); + virtual ~ChromeProxyConfigService(); + + // ProxyConfigService implementation: + virtual void AddObserver(net::ProxyConfigService::Observer* observer); + virtual void RemoveObserver(net::ProxyConfigService::Observer* observer); + virtual ConfigAvailability GetLatestProxyConfig(net::ProxyConfig* config); + virtual void OnLazyPoll(); + + // Method on IO thread that receives the preference proxy settings pushed from + // PrefProxyConfigTrackerImpl. + void UpdateProxyConfig(ProxyPrefs::ConfigState config_state, + const net::ProxyConfig& config); + + private: + // ProxyConfigService::Observer implementation: + virtual void OnProxyConfigChanged(const net::ProxyConfig& config, + ConfigAvailability availability); + + // Makes sure that the observer registration with the base service is set up. + void RegisterObserver(); + + scoped_ptr<net::ProxyConfigService> base_service_; + ObserverList<net::ProxyConfigService::Observer, true> observers_; + + // Tracks configuration state of |pref_config_|. |pref_config_| is valid only + // if |pref_config_state_| is not CONFIG_UNSET. + ProxyPrefs::ConfigState pref_config_state_; + + // Configuration as defined by prefs. + net::ProxyConfig pref_config_; + + // Indicates whether the base service registration is done. + bool registered_observer_; + + DISALLOW_COPY_AND_ASSIGN(ChromeProxyConfigService); +}; + +// A class that tracks proxy preferences. It translates the configuration +// to net::ProxyConfig and pushes the result over to the IO thread for +// ChromeProxyConfigService::UpdateProxyConfig to use. +class PrefProxyConfigTrackerImpl : public content::NotificationObserver { + public: + explicit PrefProxyConfigTrackerImpl(PrefService* pref_service); + virtual ~PrefProxyConfigTrackerImpl(); + + // Sets the proxy config service to push the preference proxy to. + void SetChromeProxyConfigService( + ChromeProxyConfigService* proxy_config_service); + + // Notifies the tracker that the pref service passed upon construction is + // about to go away. This must be called from the UI thread. + void DetachFromPrefService(); + + // Determines if |config_state| takes precedence regardless, which happens if + // config is from policy or extension or other-precede. + static bool PrefPrecedes(ProxyPrefs::ConfigState config_state); + + // Determines the proxy configuration that should take effect in the network + // layer, based on prefs and system configurations. + // |pref_state| refers to state of |pref_config|. + // |system_availability| refers to availability of |system_config|. + // |ignore_fallback_config| indicates if fallback config from prefs should + // be ignored. + // Returns effective |effective_config| and its state in + // |effective_config_source|. + static net::ProxyConfigService::ConfigAvailability GetEffectiveProxyConfig( + ProxyPrefs::ConfigState pref_state, + const net::ProxyConfig& pref_config, + net::ProxyConfigService::ConfigAvailability system_availability, + const net::ProxyConfig& system_config, + bool ignore_fallback_config, + ProxyPrefs::ConfigState* effective_config_state, + net::ProxyConfig* effective_config); + + // Registers the proxy preference. + static void RegisterPrefs(PrefService* user_prefs); + + protected: + // Get the proxy configuration currently defined by preferences. + // Status is indicated in the return value. + // Writes the configuration to |config| unless the return value is + // CONFIG_UNSET, in which case |config| and |config_source| are not touched. + ProxyPrefs::ConfigState GetProxyConfig(net::ProxyConfig* config); + + // Called when there's a change in prefs proxy config. + // Subclasses can extend it for changes in other sources of proxy config. + virtual void OnProxyConfigChanged(ProxyPrefs::ConfigState config_state, + const net::ProxyConfig& config); + + // content::NotificationObserver implementation: + virtual void Observe(int type, + const content::NotificationSource& source, + const content::NotificationDetails& details); + + // Converts a ProxyConfigDictionary to net::ProxyConfig representation. + // Returns true if the data from in the dictionary is valid, false otherwise. + bool PrefConfigToNetConfig(const ProxyConfigDictionary& proxy_dict, + net::ProxyConfig* config); + + const PrefService* prefs() const { return pref_service_; } + bool update_pending() const { return update_pending_; } + + private: + // Creates a proxy configuration from proxy-related preferences. Configuration + // is stored in |config|, return value indicates whether the configuration is + // valid. + ProxyPrefs::ConfigState ReadPrefConfig(net::ProxyConfig* config); + + // Tracks configuration state. |pref_config_| is valid only if |config_state_| + // is not CONFIG_UNSET. + ProxyPrefs::ConfigState config_state_; + + // Configuration as defined by prefs. + net::ProxyConfig pref_config_; + + PrefService* pref_service_; + ChromeProxyConfigService* chrome_proxy_config_service_; // Weak ptr. + bool update_pending_; // True if config has not been pushed to network stack. + scoped_ptr<PrefSetObserver> proxy_prefs_observer_; + + DISALLOW_COPY_AND_ASSIGN(PrefProxyConfigTrackerImpl); +}; + +#endif // CHROME_BROWSER_NET_PREF_PROXY_CONFIG_TRACKER_IMPL_H_ diff --git a/chrome/browser/net/pref_proxy_config_service_unittest.cc b/chrome/browser/net/pref_proxy_config_tracker_impl_unittest.cc index 656b484..1a11816 100644 --- a/chrome/browser/net/pref_proxy_config_service_unittest.cc +++ b/chrome/browser/net/pref_proxy_config_tracker_impl_unittest.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/net/pref_proxy_config_service.h" +#include "chrome/browser/net/pref_proxy_config_tracker_impl.h" #include "base/command_line.h" #include "base/file_path.h" @@ -71,44 +71,50 @@ class MockObserver : public net::ProxyConfigService::Observer { }; template<typename TESTBASE> -class PrefProxyConfigServiceTestBase : public TESTBASE { +class PrefProxyConfigTrackerImplTestBase : public TESTBASE { protected: - PrefProxyConfigServiceTestBase() + PrefProxyConfigTrackerImplTestBase() : ui_thread_(BrowserThread::UI, &loop_), io_thread_(BrowserThread::IO, &loop_) {} virtual void Init(PrefService* pref_service) { ASSERT_TRUE(pref_service); - PrefProxyConfigService::RegisterPrefs(pref_service); + PrefProxyConfigTrackerImpl::RegisterPrefs(pref_service); fixed_config_.set_pac_url(GURL(kFixedPacUrl)); delegate_service_ = new TestProxyConfigService(fixed_config_, net::ProxyConfigService::CONFIG_VALID); - proxy_config_tracker_ = new PrefProxyConfigTracker(pref_service); proxy_config_service_.reset( - new PrefProxyConfigService(proxy_config_tracker_.get(), - delegate_service_)); + new ChromeProxyConfigService(delegate_service_)); + proxy_config_tracker_.reset(new PrefProxyConfigTrackerImpl(pref_service)); + proxy_config_tracker_->SetChromeProxyConfigService( + proxy_config_service_.get()); + // SetChromeProxyConfigService triggers update of initial prefs proxy + // config by tracker to chrome proxy config service, so flush all pending + // tasks so that tests start fresh. + loop_.RunAllPending(); } virtual void TearDown() { proxy_config_tracker_->DetachFromPrefService(); loop_.RunAllPending(); + proxy_config_tracker_.reset(); proxy_config_service_.reset(); } MessageLoop loop_; TestProxyConfigService* delegate_service_; // weak - scoped_ptr<PrefProxyConfigService> proxy_config_service_; + scoped_ptr<ChromeProxyConfigService> proxy_config_service_; net::ProxyConfig fixed_config_; private: - scoped_refptr<PrefProxyConfigTracker> proxy_config_tracker_; + scoped_ptr<PrefProxyConfigTrackerImpl> proxy_config_tracker_; content::TestBrowserThread ui_thread_; content::TestBrowserThread io_thread_; }; -class PrefProxyConfigServiceTest - : public PrefProxyConfigServiceTestBase<testing::Test> { +class PrefProxyConfigTrackerImplTest + : public PrefProxyConfigTrackerImplTestBase<testing::Test> { protected: virtual void SetUp() { pref_service_.reset(new TestingPrefService()); @@ -118,14 +124,14 @@ class PrefProxyConfigServiceTest scoped_ptr<TestingPrefService> pref_service_; }; -TEST_F(PrefProxyConfigServiceTest, BaseConfiguration) { +TEST_F(PrefProxyConfigTrackerImplTest, BaseConfiguration) { net::ProxyConfig actual_config; EXPECT_EQ(net::ProxyConfigService::CONFIG_VALID, proxy_config_service_->GetLatestProxyConfig(&actual_config)); EXPECT_EQ(GURL(kFixedPacUrl), actual_config.pac_url()); } -TEST_F(PrefProxyConfigServiceTest, DynamicPrefOverrides) { +TEST_F(PrefProxyConfigTrackerImplTest, DynamicPrefOverrides) { pref_service_->SetManagedPref( prefs::kProxy, ProxyConfigDictionary::CreateFixedServers("http://example.com:3128", "")); @@ -157,7 +163,7 @@ MATCHER_P(ProxyConfigMatches, config, "") { return reference.Equals(arg); } -TEST_F(PrefProxyConfigServiceTest, Observers) { +TEST_F(PrefProxyConfigTrackerImplTest, Observers) { const net::ProxyConfigService::ConfigAvailability CONFIG_VALID = net::ProxyConfigService::CONFIG_VALID; MockObserver observer; @@ -212,7 +218,7 @@ TEST_F(PrefProxyConfigServiceTest, Observers) { proxy_config_service_->RemoveObserver(&observer); } -TEST_F(PrefProxyConfigServiceTest, Fallback) { +TEST_F(PrefProxyConfigTrackerImplTest, Fallback) { const net::ProxyConfigService::ConfigAvailability CONFIG_VALID = net::ProxyConfigService::CONFIG_VALID; MockObserver observer; @@ -266,7 +272,7 @@ TEST_F(PrefProxyConfigServiceTest, Fallback) { proxy_config_service_->RemoveObserver(&observer); } -TEST_F(PrefProxyConfigServiceTest, ExplicitSystemSettings) { +TEST_F(PrefProxyConfigTrackerImplTest, ExplicitSystemSettings) { pref_service_->SetRecommendedPref( prefs::kProxy, ProxyConfigDictionary::CreateAutoDetect()); @@ -316,11 +322,11 @@ void PrintTo(const CommandLineTestParams& params, std::ostream* os) { *os << params.description; } -class PrefProxyConfigServiceCommandLineTest - : public PrefProxyConfigServiceTestBase< +class PrefProxyConfigTrackerImplCommandLineTest + : public PrefProxyConfigTrackerImplTestBase< testing::TestWithParam<CommandLineTestParams> > { protected: - PrefProxyConfigServiceCommandLineTest() + PrefProxyConfigTrackerImplCommandLineTest() : command_line_(CommandLine::NO_PROGRAM) {} virtual void SetUp() { @@ -342,7 +348,7 @@ class PrefProxyConfigServiceCommandLineTest scoped_ptr<PrefService> pref_service_; }; -TEST_P(PrefProxyConfigServiceCommandLineTest, CommandLine) { +TEST_P(PrefProxyConfigTrackerImplCommandLineTest, CommandLine) { net::ProxyConfig config; EXPECT_EQ(net::ProxyConfigService::CONFIG_VALID, proxy_config_service_->GetLatestProxyConfig(&config)); @@ -468,8 +474,8 @@ static const CommandLineTestParams kCommandLineTestParams[] = { }; INSTANTIATE_TEST_CASE_P( - PrefProxyConfigServiceCommandLineTestInstance, - PrefProxyConfigServiceCommandLineTest, + PrefProxyConfigTrackerImplCommandLineTestInstance, + PrefProxyConfigTrackerImplCommandLineTest, testing::ValuesIn(kCommandLineTestParams)); } // namespace diff --git a/chrome/browser/net/proxy_service_factory.cc b/chrome/browser/net/proxy_service_factory.cc index a1388db..5090b01 100644 --- a/chrome/browser/net/proxy_service_factory.cc +++ b/chrome/browser/net/proxy_service_factory.cc @@ -8,7 +8,7 @@ #include "base/string_number_conversions.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/io_thread.h" -#include "chrome/browser/net/pref_proxy_config_service.h" +#include "chrome/browser/net/pref_proxy_config_tracker.h" #include "chrome/common/chrome_switches.h" #include "content/public/browser/browser_thread.h" #include "net/base/net_log.h" @@ -19,38 +19,54 @@ #include "net/url_request/url_request_context.h" #if defined(OS_CHROMEOS) -#include "chrome/browser/chromeos/proxy_config_service.h" +#include "chrome/browser/chromeos/proxy_config_service_impl.h" #endif // defined(OS_CHROMEOS) using content::BrowserThread; // static -net::ProxyConfigService* ProxyServiceFactory::CreateProxyConfigService( - PrefProxyConfigTracker* proxy_config_tracker) { +ChromeProxyConfigService* ProxyServiceFactory::CreateProxyConfigService() { // The linux gconf-based proxy settings getter relies on being initialized // from the UI thread. DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - // Create a baseline service that provides proxy configuration in case nothing - // is configured through prefs (Note: prefs include command line and - // configuration policy). net::ProxyConfigService* base_service = NULL; +#if !defined(OS_CHROMEOS) + // On ChromeOS, base service is NULL; chromeos::ProxyConfigServiceImpl + // determines the effective proxy config to take effect in the network layer, + // be it from prefs or system (which is network flimflam on chromeos). + + // For other platforms, create a baseline service that provides proxy + // configuration in case nothing is configured through prefs (Note: prefs + // include command line and configuration policy). + // TODO(port): the IO and FILE message loops are only used by Linux. Can // that code be moved to chrome/browser instead of being in net, so that it // can use BrowserThread instead of raw MessageLoop pointers? See bug 25354. -#if defined(OS_CHROMEOS) - base_service = new chromeos::ProxyConfigService( - g_browser_process->chromeos_proxy_config_service_impl()); -#else base_service = net::ProxyService::CreateSystemProxyConfigService( g_browser_process->io_thread()->message_loop(), g_browser_process->file_thread()->message_loop()); -#endif // defined(OS_CHROMEOS) +#endif // !defined(OS_CHROMEOS) - return new PrefProxyConfigService(proxy_config_tracker, base_service); + return new ChromeProxyConfigService(base_service); } +#if defined(OS_CHROMEOS) +// static +chromeos::ProxyConfigServiceImpl* + ProxyServiceFactory::CreatePrefProxyConfigTracker( + PrefService* pref_service) { + return new chromeos::ProxyConfigServiceImpl(pref_service); +} +#else +// static +PrefProxyConfigTrackerImpl* ProxyServiceFactory::CreatePrefProxyConfigTracker( + PrefService* pref_service) { + return new PrefProxyConfigTrackerImpl(pref_service); +} +#endif // defined(OS_CHROMEOS) + // static net::ProxyService* ProxyServiceFactory::CreateProxyService( net::NetLog* net_log, diff --git a/chrome/browser/net/proxy_service_factory.h b/chrome/browser/net/proxy_service_factory.h index aa6796c..b060f42 100644 --- a/chrome/browser/net/proxy_service_factory.h +++ b/chrome/browser/net/proxy_service_factory.h @@ -8,8 +8,16 @@ #include "base/basictypes.h" +class ChromeProxyConfigService; class CommandLine; -class PrefProxyConfigTracker; +class PrefProxyConfigTrackerImpl; +class PrefService; + +#if defined(OS_CHROMEOS) +namespace chromeos { +class ProxyConfigServiceImpl; +} +#endif // defined(OS_CHROMEOS) namespace net { class NetLog; @@ -22,8 +30,15 @@ class ProxyServiceFactory { public: // Creates a ProxyConfigService that delivers the system preferences // (or the respective ChromeOS equivalent). - static net::ProxyConfigService* CreateProxyConfigService( - PrefProxyConfigTracker* proxy_config_tracker); + static ChromeProxyConfigService* CreateProxyConfigService(); + +#if defined(OS_CHROMEOS) + static chromeos::ProxyConfigServiceImpl* CreatePrefProxyConfigTracker( + PrefService* pref_service); +#else + static PrefProxyConfigTrackerImpl* CreatePrefProxyConfigTracker( + PrefService* pref_service); +#endif // defined(OS_CHROMEOS) // Create a proxy service according to the options on command line. static net::ProxyService* CreateProxyService( diff --git a/chrome/browser/net/ssl_config_service_manager_pref_unittest.cc b/chrome/browser/net/ssl_config_service_manager_pref_unittest.cc index 555f077..3d8704b 100644 --- a/chrome/browser/net/ssl_config_service_manager_pref_unittest.cc +++ b/chrome/browser/net/ssl_config_service_manager_pref_unittest.cc @@ -2,13 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/net/pref_proxy_config_service.h" +#include "chrome/browser/net/ssl_config_service_manager.h" #include "base/command_line.h" #include "base/memory/ref_counted.h" #include "base/message_loop.h" #include "base/values.h" -#include "chrome/browser/net/ssl_config_service_manager.h" #include "chrome/browser/prefs/pref_service_mock_builder.h" #include "chrome/browser/prefs/testing_pref_store.h" #include "chrome/common/chrome_switches.h" diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc index 7419011..d90afd6 100644 --- a/chrome/browser/prefs/browser_prefs.cc +++ b/chrome/browser/prefs/browser_prefs.cc @@ -28,7 +28,6 @@ #include "chrome/browser/net/http_server_properties_manager.h" #include "chrome/browser/net/net_pref_observer.h" #include "chrome/browser/net/predictor.h" -#include "chrome/browser/net/pref_proxy_config_service.h" #include "chrome/browser/net/ssl_config_service_manager.h" #include "chrome/browser/notifications/desktop_notification_service.h" #include "chrome/browser/notifications/notification_ui_manager.h" @@ -85,6 +84,7 @@ #include "chrome/browser/chromeos/login/user_manager.h" #include "chrome/browser/chromeos/login/wizard_controller.h" #include "chrome/browser/chromeos/preferences.h" +#include "chrome/browser/chromeos/proxy_config_service_impl.h" #include "chrome/browser/chromeos/status/input_method_menu.h" #include "chrome/browser/chromeos/status/network_menu_button.h" #include "chrome/browser/chromeos/user_cros_settings_provider.h" @@ -123,7 +123,7 @@ void RegisterLocalState(PrefService* local_state) { geolocation::RegisterPrefs(local_state); BackgroundModeManager::RegisterPrefs(local_state); NotificationUIManager::RegisterPrefs(local_state); - PrefProxyConfigService::RegisterPrefs(local_state); + PrefProxyConfigTrackerImpl::RegisterPrefs(local_state); SSLConfigServiceManager::RegisterPrefs(local_state); #if defined(ENABLE_CONFIGURATION_POLICY) policy::CloudPolicySubsystem::RegisterPrefs(local_state); @@ -139,6 +139,7 @@ void RegisterLocalState(PrefService* local_state) { chromeos::ServicesCustomizationDocument::RegisterPrefs(local_state); chromeos::SignedSettingsTempStorage::RegisterPrefs(local_state); chromeos::NetworkMenuButton::RegisterPrefs(local_state); + chromeos::ProxyConfigServiceImpl::RegisterPrefs(local_state); #endif } @@ -168,7 +169,7 @@ void RegisterUserPrefs(PrefService* user_prefs) { PinnedTabCodec::RegisterUserPrefs(user_prefs); ExtensionPrefs::RegisterUserPrefs(user_prefs); TranslatePrefs::RegisterUserPrefs(user_prefs); - PrefProxyConfigService::RegisterPrefs(user_prefs); + PrefProxyConfigTrackerImpl::RegisterPrefs(user_prefs); #if defined(TOOLKIT_VIEWS) BrowserActionsContainer::RegisterUserPrefs(user_prefs); #elif defined(TOOLKIT_GTK) @@ -176,6 +177,7 @@ void RegisterUserPrefs(PrefService* user_prefs) { #endif #if defined(OS_CHROMEOS) chromeos::Preferences::RegisterUserPrefs(user_prefs); + chromeos::ProxyConfigServiceImpl::RegisterPrefs(user_prefs); #endif SigninManager::RegisterUserPrefs(user_prefs); InstantController::RegisterUserPrefs(user_prefs); diff --git a/chrome/browser/prefs/proxy_prefs.h b/chrome/browser/prefs/proxy_prefs.h index 46be7595..7d17134 100644 --- a/chrome/browser/prefs/proxy_prefs.h +++ b/chrome/browser/prefs/proxy_prefs.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -36,6 +36,22 @@ enum ProxyMode { kModeCount }; +// State of proxy configuration. +enum ConfigState { + // Configuration is from policy. + CONFIG_POLICY, + // Configuration is from extension. + CONFIG_EXTENSION, + // Configuration is not from policy or extension but still precedes others. + CONFIG_OTHER_PRECEDE, + // Configuration is from system. + CONFIG_SYSTEM, + // Configuration is recommended i.e there's a fallback configuration. + CONFIG_FALLBACK, + // Configuration is known to be not set. + CONFIG_UNSET, +}; + // Constants for string values used to specify the proxy mode through externally // visible APIs, e.g. through policy or the proxy extension API. extern const char kDirectProxyModeName[]; @@ -50,6 +66,8 @@ bool StringToProxyMode(const std::string& in_value, // Ownership of the return value is NOT passed to the caller. const char* ProxyModeToString(ProxyMode mode); +bool DoesPrefPrecede(ConfigState config_state); + } // namespace ProxyPrefs #endif // CHROME_BROWSER_PREFS_PROXY_PREFS_H_ diff --git a/chrome/browser/profiles/off_the_record_profile_impl.cc b/chrome/browser/profiles/off_the_record_profile_impl.cc index 70214c1..8a5be4f 100644 --- a/chrome/browser/profiles/off_the_record_profile_impl.cc +++ b/chrome/browser/profiles/off_the_record_profile_impl.cc @@ -26,7 +26,7 @@ #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/extension_special_storage_policy.h" #include "chrome/browser/extensions/extension_webrequest_api.h" -#include "chrome/browser/net/pref_proxy_config_service.h" +#include "chrome/browser/net/proxy_service_factory.h" #include "chrome/browser/plugin_prefs.h" #include "chrome/browser/prefs/incognito_mode_prefs.h" #include "chrome/browser/prefs/pref_service.h" @@ -61,6 +61,7 @@ #if defined(OS_CHROMEOS) #include "chrome/browser/chromeos/preferences.h" +#include "chrome/browser/chromeos/proxy_config_service_impl.h" #endif using content::BrowserThread; @@ -145,7 +146,7 @@ OffTheRecordProfileImpl::~OffTheRecordProfileImpl() { if (host_content_settings_map_) host_content_settings_map_->ShutdownOnUIThread(); - if (pref_proxy_config_tracker_) + if (pref_proxy_config_tracker_.get()) pref_proxy_config_tracker_->DetachFromPrefService(); ExtensionService* extension_service = GetExtensionService(); @@ -549,9 +550,11 @@ void OffTheRecordProfileImpl::OnLogin() { #endif // defined(OS_CHROMEOS) PrefProxyConfigTracker* OffTheRecordProfileImpl::GetProxyConfigTracker() { - if (!pref_proxy_config_tracker_) - pref_proxy_config_tracker_ = new PrefProxyConfigTracker(GetPrefs()); - return pref_proxy_config_tracker_; + if (!pref_proxy_config_tracker_.get()) { + pref_proxy_config_tracker_.reset( + ProxyServiceFactory::CreatePrefProxyConfigTracker(GetPrefs())); + } + return pref_proxy_config_tracker_.get(); } chrome_browser_net::Predictor* OffTheRecordProfileImpl::GetNetworkPredictor() { diff --git a/chrome/browser/profiles/off_the_record_profile_impl.h b/chrome/browser/profiles/off_the_record_profile_impl.h index f98bdf7..273238a 100644 --- a/chrome/browser/profiles/off_the_record_profile_impl.h +++ b/chrome/browser/profiles/off_the_record_profile_impl.h @@ -125,6 +125,7 @@ class OffTheRecordProfileImpl : public Profile, #endif // defined(OS_CHROMEOS) virtual PrefProxyConfigTracker* GetProxyConfigTracker() OVERRIDE; + virtual chrome_browser_net::Predictor* GetNetworkPredictor() OVERRIDE; virtual void ClearNetworkingHistorySince(base::Time time) OVERRIDE; virtual GURL GetHomePage() OVERRIDE; @@ -183,7 +184,7 @@ class OffTheRecordProfileImpl : public Profile, // The file_system context for this profile. scoped_refptr<fileapi::FileSystemContext> file_system_context_; - scoped_refptr<PrefProxyConfigTracker> pref_proxy_config_tracker_; + scoped_ptr<PrefProxyConfigTracker> pref_proxy_config_tracker_; scoped_ptr<ChromeURLDataManager> chrome_url_data_manager_; diff --git a/chrome/browser/profiles/profile.cc b/chrome/browser/profiles/profile.cc index d80ce7e..f7c550e 100644 --- a/chrome/browser/profiles/profile.cc +++ b/chrome/browser/profiles/profile.cc @@ -25,7 +25,6 @@ #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/extension_special_storage_policy.h" #include "chrome/browser/extensions/extension_webrequest_api.h" -#include "chrome/browser/net/pref_proxy_config_service.h" #include "chrome/browser/prefs/incognito_mode_prefs.h" #include "chrome/browser/prefs/pref_service.h" #include "chrome/browser/profiles/off_the_record_profile_io_data.h" diff --git a/chrome/browser/profiles/profile.h b/chrome/browser/profiles/profile.h index 032a4b4..0d32bd0 100644 --- a/chrome/browser/profiles/profile.h +++ b/chrome/browser/profiles/profile.h @@ -13,6 +13,7 @@ #include "base/basictypes.h" #include "base/logging.h" #include "chrome/browser/net/preconnect.h" // TODO: remove this. +#include "chrome/browser/net/pref_proxy_config_tracker.h" #include "chrome/common/extensions/extension_constants.h" #include "content/browser/browser_context.h" @@ -66,7 +67,6 @@ class HistoryService; class HostContentSettingsMap; class NavigationController; class PasswordStore; -class PrefProxyConfigTracker; class PrefService; class ProfileSyncFactory; class ProfileSyncService; diff --git a/chrome/browser/profiles/profile_impl.cc b/chrome/browser/profiles/profile_impl.cc index aa2d69a..673a36c 100644 --- a/chrome/browser/profiles/profile_impl.cc +++ b/chrome/browser/profiles/profile_impl.cc @@ -54,7 +54,7 @@ #include "chrome/browser/net/gaia/token_service.h" #include "chrome/browser/net/net_pref_observer.h" #include "chrome/browser/net/predictor.h" -#include "chrome/browser/net/pref_proxy_config_service.h" +#include "chrome/browser/net/proxy_service_factory.h" #include "chrome/browser/net/ssl_config_service_manager.h" #include "chrome/browser/net/url_fixer_upper.h" #include "chrome/browser/password_manager/password_store_default.h" @@ -136,6 +136,7 @@ #include "chrome/browser/chromeos/locale_change_guard.h" #include "chrome/browser/chromeos/login/user_manager.h" #include "chrome/browser/chromeos/preferences.h" +#include "chrome/browser/chromeos/proxy_config_service_impl.h" #endif using base::Time; @@ -608,7 +609,7 @@ ProfileImpl::~ProfileImpl() { if (extension_message_service_) extension_message_service_->DestroyingProfile(); - if (pref_proxy_config_tracker_) + if (pref_proxy_config_tracker_.get()) pref_proxy_config_tracker_->DetachFromPrefService(); if (protocol_handler_registry_) @@ -1547,10 +1548,11 @@ void ProfileImpl::InitChromeOSPreferences() { #endif // defined(OS_CHROMEOS) PrefProxyConfigTracker* ProfileImpl::GetProxyConfigTracker() { - if (!pref_proxy_config_tracker_) - pref_proxy_config_tracker_ = new PrefProxyConfigTracker(GetPrefs()); - - return pref_proxy_config_tracker_; + if (!pref_proxy_config_tracker_.get()) { + pref_proxy_config_tracker_.reset( + ProxyServiceFactory::CreatePrefProxyConfigTracker(GetPrefs())); + } + return pref_proxy_config_tracker_.get(); } chrome_browser_net::Predictor* ProfileImpl::GetNetworkPredictor() { diff --git a/chrome/browser/profiles/profile_impl.h b/chrome/browser/profiles/profile_impl.h index 10ec531d..10371fe 100644 --- a/chrome/browser/profiles/profile_impl.h +++ b/chrome/browser/profiles/profile_impl.h @@ -282,7 +282,7 @@ class ProfileImpl : public Profile, scoped_ptr<chromeos::LocaleChangeGuard> locale_change_guard_; #endif - scoped_refptr<PrefProxyConfigTracker> pref_proxy_config_tracker_; + scoped_ptr<PrefProxyConfigTracker> pref_proxy_config_tracker_; scoped_ptr<ChromeURLDataManager> chrome_url_data_manager_; diff --git a/chrome/browser/profiles/profile_io_data.cc b/chrome/browser/profiles/profile_io_data.cc index 016e1da..f90e64d 100644 --- a/chrome/browser/profiles/profile_io_data.cc +++ b/chrome/browser/profiles/profile_io_data.cc @@ -30,7 +30,6 @@ #include "chrome/browser/net/chrome_fraudulent_certificate_reporter.h" #include "chrome/browser/net/chrome_net_log.h" #include "chrome/browser/net/chrome_network_delegate.h" -#include "chrome/browser/net/pref_proxy_config_service.h" #include "chrome/browser/net/proxy_service_factory.h" #include "chrome/browser/notifications/desktop_notification_service_factory.h" #include "chrome/browser/policy/url_blacklist_manager.h" @@ -69,6 +68,7 @@ #if defined(OS_CHROMEOS) #include "chrome/browser/chromeos/gview_request_interceptor.h" +#include "chrome/browser/chromeos/proxy_config_service_impl.h" #endif // defined(OS_CHROMEOS) using content::BrowserThread; @@ -243,9 +243,11 @@ void ProfileIOData::InitializeOnUIThread(Profile* profile) { DesktopNotificationServiceFactory::GetForProfile(profile); params->protocol_handler_registry = profile->GetProtocolHandlerRegistry(); - params->proxy_config_service.reset( - ProxyServiceFactory::CreateProxyConfigService( - profile->GetProxyConfigTracker())); + ChromeProxyConfigService* proxy_config_service = + ProxyServiceFactory::CreateProxyConfigService(); + params->proxy_config_service.reset(proxy_config_service); + profile->GetProxyConfigTracker()->SetChromeProxyConfigService( + proxy_config_service); params->profile = profile; profile_params_.reset(params.release()); diff --git a/chrome/browser/profiles/profile_manager_unittest.cc b/chrome/browser/profiles/profile_manager_unittest.cc index abbb572..0392b4d 100644 --- a/chrome/browser/profiles/profile_manager_unittest.cc +++ b/chrome/browser/profiles/profile_manager_unittest.cc @@ -78,6 +78,13 @@ class ProfileManagerTest : public testing::Test { MOCK_METHOD2(OnProfileCreated, void(Profile* profile, Status status)); }; +#if defined(OS_CHROMEOS) + // Do not change order of stub_cros_enabler_, which needs to be constructed + // before io_thread_ which requires CrosLibrary to be initialized to construct + // its data member pref_proxy_config_tracker_ on ChromeOS. + chromeos::ScopedStubCrosEnabler stub_cros_enabler_; +#endif + // The path to temporary directory used to contain the test operations. ScopedTempDir temp_dir_; ScopedTestingLocalState local_state_; @@ -92,10 +99,6 @@ class ProfileManagerTest : public testing::Test { scoped_ptr<base::SystemMonitor> system_monitor_dummy_; -#if defined(OS_CHROMEOS) - chromeos::ScopedStubCrosEnabler stub_cros_enabler_; -#endif - // Also will test profile deletion. scoped_ptr<ProfileManager> profile_manager_; }; diff --git a/chrome/browser/resources/options/chromeos/internet_detail.html b/chrome/browser/resources/options/chromeos/internet_detail.html index 4211549..4620b42 100644 --- a/chrome/browser/resources/options/chromeos/internet_detail.html +++ b/chrome/browser/resources/options/chromeos/internet_detail.html @@ -313,7 +313,6 @@ <button id="change-proxy-button" i18n-content="changeProxyButton"> </button> </div> - <div id="change-proxy-text" hidden></div> </section> </div> <div id="security-tab" diff --git a/chrome/browser/resources/options/chromeos/internet_options.js b/chrome/browser/resources/options/chromeos/internet_options.js index 1422cf0..fa45f3c 100644 --- a/chrome/browser/resources/options/chromeos/internet_options.js +++ b/chrome/browser/resources/options/chromeos/internet_options.js @@ -455,20 +455,9 @@ cr.define('options', function() { $('ipTypeDHCPDiv').hidden = !data.showStaticIPConfig; $('ipTypeStaticDiv').hidden = !data.showStaticIPConfig; - // Hide change-proxy-button if proxy is not configurable. - $('change-proxy-button').hidden = !data.proxyConfigurable; - // If necessary, set text for change-proxy-text and show it. - var changeProxyText = $('change-proxy-text'); - if (data.changeProxyText != '') { - changeProxyText.textContent = - localStrings.getString(data.changeProxyText); - changeProxyText.hidden = false; - } else { - changeProxyText.hidden = true; - } - // Hide change-proxy-section if button and text are hidden. - $('change-proxy-section').hidden = !data.proxyConfigurable && - changeProxyText.hidden; + // Hide change-proxy-button and change-proxy-section if not showing proxy. + $('change-proxy-button').hidden = !data.showProxy; + $('change-proxy-section').hidden = !data.showProxy; var ipConfigList = $('ipConfigList'); ipConfigList.disabled = $('ipTypeDHCP').checked || !data.showStaticIPConfig; diff --git a/chrome/browser/resources/options/chromeos/proxy.html b/chrome/browser/resources/options/chromeos/proxy.html index 433f12a..b2900f4 100644 --- a/chrome/browser/resources/options/chromeos/proxy.html +++ b/chrome/browser/resources/options/chromeos/proxy.html @@ -1,4 +1,8 @@ <div id="proxyPage" class="page" hidden> + <div id="info-banner" class="managed-prefs-banner" hidden> + <span id="banner-icon" class="managed-prefs-icon"></span> + <span id="banner-text" class="managed-prefs-text"></span> + </div> <h1 id="proxy-page-title" i18n-content="proxyPage"></h1> <section> <h3 i18n-content="proxy_config_title"></h3> @@ -34,8 +38,8 @@ </td> <td> <span i18n-content="proxyPort"></span> - <input id="proxyHostSinglePort" type="text" dataType="number" size="5" - pref="cros.session.proxy.singlehttpport" disabled> + <input id="proxyHostSinglePort" type="text" dataType="number" + size="5" pref="cros.session.proxy.singlehttpport" disabled> </td> </tr> </table> @@ -127,11 +131,11 @@ <section id="advancedConfig"> <h3 i18n-content="advanced_proxy_config"></h3> <div class="option"> - <div i18n-content="proxyBypass"></div> - <list id="ignoredHostList"></list> - <input id="newHost" type="url" size="30"> - <button id="addHost" i18n-content="addHost"></button> - <button id="removeHost" i18n-content="removeHost"></button> + <div i18n-content="proxyBypass"></div> + <list id="ignoredHostList"></list> + <input id="newHost" type="url" size="30"> + <button id="addHost" i18n-content="addHost"></button> + <button id="removeHost" i18n-content="removeHost"></button> </div> </section> </div> diff --git a/chrome/browser/resources/options/chromeos/proxy_options.js b/chrome/browser/resources/options/chromeos/proxy_options.js index 993b986..f42a08d 100644 --- a/chrome/browser/resources/options/chromeos/proxy_options.js +++ b/chrome/browser/resources/options/chromeos/proxy_options.js @@ -43,7 +43,7 @@ cr.define('options', function() { * Initializes ProxyOptions page. */ initializePage: function() { - // Call base class implementation to starts preference initialization. + // Call base class implementation to start preference initialization. OptionsPage.prototype.initializePage.call(this); // Set up ignored page. @@ -63,21 +63,22 @@ cr.define('options', function() { observePrefsUI($('proxyAllProtocols')); }, - proxyListInitalized_: false, + proxyListInitialized_: false, /** * Update controls state. * @public */ updateControls: function() { + this.updateBannerVisibility_(); this.toggleSingle_(); if ($('manualProxy').checked) { this.enableManual_(); } else { this.disableManual_(); } - if (!this.proxyListInitalized_ && this.visible) { - this.proxyListInitalized_ = true; + if (!this.proxyListInitialized_ && this.visible) { + this.proxyListInitialized_ = true; $('ignoredHostList').redraw(); } }, @@ -92,6 +93,44 @@ cr.define('options', function() { }, /** + * Updates info banner visibility state. This function shows the banner + * if proxy is managed or shared-proxies is off for shared network. + * @private + */ + updateBannerVisibility_: function() { + var bannerDiv = $('info-banner'); + // Remove class and listener for click event in case they were added + // before and updateBannerVisibility_ is called repeatedly. + bannerDiv.classList.remove("clickable"); + bannerDiv.removeEventListener('click', this.handleSharedProxiesHint_); + + // Show banner and determine its message if necessary. + var controlledBy = $('directProxy').controlledBy; + if (controlledBy == '') { + bannerDiv.hidden = true; + } else { + bannerDiv.hidden = false; + // controlledBy must match strings loaded in proxy_handler.cc and + // set in proxy_cros_settings_provider.cc. + $('banner-text').textContent = localStrings.getString(controlledBy); + if (controlledBy == "enableSharedProxiesBannerText") { + bannerDiv.classList.add("clickable"); + bannerDiv.addEventListener('click', this.handleSharedProxiesHint_); + } + } + }, + + /** + * Handler for "click" event on yellow banner with enable-shared-proxies + * hint. + * @private + * @param {Event} e Click event fired from info-banner. + */ + handleSharedProxiesHint_: function(e) { + OptionsPage.navigateToPage("internet"); + }, + + /** * Handler for when the user clicks on the checkbox to allow a * single proxy usage. * @private @@ -114,6 +153,7 @@ cr.define('options', function() { * @param {Event} e Click event. */ disableManual_: function(e) { + $('advancedConfig').hidden = true; $('proxyAllProtocols').disabled = true; $('proxyHostName').disabled = true; $('proxyHostPort').disabled = true; @@ -125,11 +165,8 @@ cr.define('options', function() { $('ftpProxyPort').disabled = true; $('socksHost').disabled = true; $('socksPort').disabled = true; - $('newHost').disabled = true; - $('removeHost').disabled = true; - $('addHost').disabled = true; - $('advancedConfig').style.display = 'none'; - $('proxyConfig').disabled = !$('autoProxy').checked; + $('proxyConfig').disabled = $('autoProxy').disabled || + !$('autoProxy').checked; }, /** @@ -139,22 +176,23 @@ cr.define('options', function() { * @param {Event} e Click event. */ enableManual_: function(e) { - $('proxyAllProtocols').disabled = false; - $('proxyHostName').disabled = false; - $('proxyHostPort').disabled = false; - $('proxyHostSingleName').disabled = false; - $('proxyHostSinglePort').disabled = false; - $('secureProxyHostName').disabled = false; - $('secureProxyPort').disabled = false; - $('ftpProxy').disabled = false; - $('ftpProxyPort').disabled = false; - $('socksHost').disabled = false; - $('socksPort').disabled = false; - $('newHost').disabled = false; - $('removeHost').disabled = false; - $('addHost').disabled = false; - $('advancedConfig').style.display = '-webkit-box'; + $('advancedConfig').hidden = false; $('ignoredHostList').redraw(); + var all_disabled = $('manualProxy').disabled; + $('newHost').disabled = all_disabled; + $('removeHost').disabled = all_disabled; + $('addHost').disabled = all_disabled; + $('proxyAllProtocols').disabled = all_disabled; + $('proxyHostName').disabled = all_disabled; + $('proxyHostPort').disabled = all_disabled; + $('proxyHostSingleName').disabled = all_disabled; + $('proxyHostSinglePort').disabled = all_disabled; + $('secureProxyHostName').disabled = all_disabled; + $('secureProxyPort').disabled = all_disabled; + $('ftpProxy').disabled = all_disabled; + $('ftpProxyPort').disabled = all_disabled; + $('socksHost').disabled = all_disabled; + $('socksPort').disabled = all_disabled; $('proxyConfig').disabled = true; }, diff --git a/chrome/browser/resources/options/options.html b/chrome/browser/resources/options/options.html index d65e97a..c25db77 100644 --- a/chrome/browser/resources/options/options.html +++ b/chrome/browser/resources/options/options.html @@ -112,9 +112,9 @@ </ul> </div> <div id="mainview"> - <div id="managed-prefs-banner" hidden> - <span id="managed-prefs-icon"></span> - <span id="managed-prefs-text"></span> + <div id="managed-prefs-banner" class="managed-prefs-banner" hidden> + <span id="managed-prefs-icon" class="managed-prefs-icon"></span> + <span id="managed-prefs-text" class="managed-prefs-text"></span> </div> <div id="subpage-backdrop" hidden></div> <div id="mainview-content"> diff --git a/chrome/browser/resources/options/options_page.css b/chrome/browser/resources/options/options_page.css index 61520ae..2cc83a1 100644 --- a/chrome/browser/resources/options/options_page.css +++ b/chrome/browser/resources/options/options_page.css @@ -228,19 +228,20 @@ html[dir='rtl'] .action-area { width: 650px; } -#managed-prefs-banner { +.managed-prefs-banner { background: -webkit-linear-gradient(#fff2b7, #fae691 97%, #878787); height: 31px; width: 100%; -} - -#managed-prefs-banner { margin: 0; padding: 0; vertical-align: middle; } -#managed-prefs-icon { +.managed-prefs-banner.clickable:active { + background: -webkit-linear-gradient(#878787, #fae691 3%, #fff2b7); +} + +.managed-prefs-icon { background-image: url("chrome://theme/IDR_WARNING"); background-repeat: no-repeat; background-position:center; @@ -251,7 +252,7 @@ html[dir='rtl'] .action-area { width: 24px; } -#managed-prefs-text { +.managed-prefs-text { vertical-align: middle; } diff --git a/chrome/browser/ui/webui/chromeos/proxy_settings_ui.cc b/chrome/browser/ui/webui/chromeos/proxy_settings_ui.cc index 4f0e51f..8c06afb 100644 --- a/chrome/browser/ui/webui/chromeos/proxy_settings_ui.cc +++ b/chrome/browser/ui/webui/chromeos/proxy_settings_ui.cc @@ -66,7 +66,7 @@ namespace chromeos { ProxySettingsUI::ProxySettingsUI(TabContents* contents) : ChromeWebUI(contents), proxy_settings_(NULL), - proxy_handler_(new ProxyHandler) { + proxy_handler_(new ProxyHandler(GetProfile())) { // |localized_strings| will be owned by ProxySettingsHTMLSource. DictionaryValue* localized_strings = new DictionaryValue(); @@ -103,9 +103,10 @@ void ProxySettingsUI::InitializeHandlers() { } if (proxy_settings()) { proxy_settings()->MakeActiveNetworkCurrent(); - std::string network = proxy_settings()->GetCurrentNetworkName(); - if (!network.empty()) - proxy_handler_->SetNetworkName(network); + std::string network_name; + GetProfile()->GetProxyConfigTracker()->UIGetCurrentNetworkName( + &network_name); + proxy_handler_->SetNetworkName(network_name); } } diff --git a/chrome/browser/ui/webui/options/advanced_options_handler.cc b/chrome/browser/ui/webui/options/advanced_options_handler.cc index d1a3750..c0cc2c9 100644 --- a/chrome/browser/ui/webui/options/advanced_options_handler.cc +++ b/chrome/browser/ui/webui/options/advanced_options_handler.cc @@ -245,8 +245,10 @@ WebUIMessageHandler* AdvancedOptionsHandler::Attach(WebUI* web_ui) { auto_open_files_.Init(prefs::kDownloadExtensionsToOpen, prefs, this); default_font_size_.Init(prefs::kWebKitDefaultFontSize, prefs, this); +#if !defined(OS_CHROMEOS) proxy_prefs_.reset( PrefSetObserver::CreateProxyPrefSetObserver(prefs, this)); +#endif // !defined(OS_CHROMEOS) // Return result from the superclass. return handler; @@ -308,8 +310,10 @@ void AdvancedOptionsHandler::Observe( std::string* pref_name = content::Details<std::string>(details).ptr(); if (*pref_name == prefs::kDownloadExtensionsToOpen) { SetupAutoOpenFileTypesDisabledAttribute(); +#if !defined(OS_CHROMEOS) } else if (proxy_prefs_->IsObserved(*pref_name)) { SetupProxySettingsSection(); +#endif // !defined(OS_CHROMEOS) } else if ((*pref_name == prefs::kCloudPrintEmail) || (*pref_name == prefs::kCloudPrintProxyEnabled)) { #if !defined(OS_CHROMEOS) @@ -547,6 +551,7 @@ void AdvancedOptionsHandler::SetupAutoOpenFileTypesDisabledAttribute() { } void AdvancedOptionsHandler::SetupProxySettingsSection() { +#if !defined(OS_CHROMEOS) // Disable the button if proxy settings are managed by a sysadmin or // overridden by an extension. PrefService* pref_service = Profile::FromWebUI(web_ui_)->GetPrefs(); @@ -570,6 +575,7 @@ void AdvancedOptionsHandler::SetupProxySettingsSection() { web_ui_->CallJavascriptFunction( "options.AdvancedOptions.SetupProxySettingsSection", disabled, label); +#endif // !defined(OS_CHROMEOS) } void AdvancedOptionsHandler::SetupSSLConfigSettings() { diff --git a/chrome/browser/ui/webui/options/advanced_options_handler.h b/chrome/browser/ui/webui/options/advanced_options_handler.h index 30e9c7a..7531d11 100644 --- a/chrome/browser/ui/webui/options/advanced_options_handler.h +++ b/chrome/browser/ui/webui/options/advanced_options_handler.h @@ -7,11 +7,14 @@ #pragma once #include "chrome/browser/prefs/pref_member.h" -#include "chrome/browser/prefs/pref_set_observer.h" #include "chrome/browser/printing/cloud_print/cloud_print_setup_handler.h" #include "chrome/browser/ui/shell_dialogs.h" #include "chrome/browser/ui/webui/options/options_ui.h" +#if !defined(OS_CHROMEOS) +#include "chrome/browser/prefs/pref_set_observer.h" +#endif // !defined(OS_CHROMEOS) + class CloudPrintSetupHandler; // Chrome advanced options page UI handler. @@ -156,7 +159,10 @@ class AdvancedOptionsHandler StringPrefMember auto_open_files_; IntegerPrefMember default_font_size_; + +#if !defined(OS_CHROMEOS) scoped_ptr<PrefSetObserver> proxy_prefs_; +#endif // !defined(OS_CHROMEOS) DISALLOW_COPY_AND_ASSIGN(AdvancedOptionsHandler); }; diff --git a/chrome/browser/ui/webui/options/chromeos/core_chromeos_options_handler.cc b/chrome/browser/ui/webui/options/chromeos/core_chromeos_options_handler.cc index 6755181..831a5b1 100644 --- a/chrome/browser/ui/webui/options/chromeos/core_chromeos_options_handler.cc +++ b/chrome/browser/ui/webui/options/chromeos/core_chromeos_options_handler.cc @@ -9,7 +9,10 @@ #include "base/string_number_conversions.h" #include "base/string_util.h" #include "chrome/browser/chromeos/cros_settings.h" +#include "chrome/browser/prefs/pref_set_observer.h" +#include "chrome/browser/profiles/profile.h" #include "chrome/common/chrome_notification_types.h" +#include "chrome/common/pref_names.h" #include "content/browser/user_metrics.h" #include "content/public/browser/notification_details.h" #include "content/public/browser/notification_source.h" @@ -20,9 +23,29 @@ CoreChromeOSOptionsHandler::CoreChromeOSOptionsHandler() : handling_change_(false) { } +CoreChromeOSOptionsHandler::~CoreChromeOSOptionsHandler() {} + +void CoreChromeOSOptionsHandler::Initialize() { + proxy_prefs_.reset(PrefSetObserver::CreateProxyPrefSetObserver( + Profile::FromWebUI(web_ui_)->GetPrefs(), this)); +} + Value* CoreChromeOSOptionsHandler::FetchPref(const std::string& pref_name) { - if (!CrosSettings::IsCrosSettings(pref_name)) + if (!CrosSettings::IsCrosSettings(pref_name)) { + // Specially handle kUseSharedProxies because kProxy controls it to + // determine if it's managed by policy/extension. + if (pref_name == prefs::kUseSharedProxies) { + PrefService* pref_service = Profile::FromWebUI(web_ui_)->GetPrefs(); + const PrefService::Preference* pref = + pref_service->FindPreference(prefs::kUseSharedProxies); + if (!pref) + return Value::CreateNullValue(); + const PrefService::Preference* controlling_pref = + pref_service->FindPreference(prefs::kProxy); + return CreateValueForPref(pref, controlling_pref); + } return ::CoreOptionsHandler::FetchPref(pref_name); + } Value* pref_value = NULL; CrosSettings::Get()->Get(pref_name, &pref_value); @@ -70,6 +93,18 @@ void CoreChromeOSOptionsHandler::Observe( NotifySettingsChanged(content::Details<std::string>(details).ptr()); return; } + // Special handling for preferences kUseSharedProxies and kProxy, the latter + // controls the former and decides if it's managed by policy/extension. + if (type == chrome::NOTIFICATION_PREF_CHANGED) { + const PrefService* pref_service = Profile::FromWebUI(web_ui_)->GetPrefs(); + std::string* pref_name = content::Details<std::string>(details).ptr(); + if (content::Source<PrefService>(source).ptr() == pref_service && + (proxy_prefs_->IsObserved(*pref_name) || + *pref_name == prefs::kUseSharedProxies)) { + NotifyPrefChanged(prefs::kUseSharedProxies, prefs::kProxy); + return; + } + } ::CoreOptionsHandler::Observe(type, source, details); } diff --git a/chrome/browser/ui/webui/options/chromeos/core_chromeos_options_handler.h b/chrome/browser/ui/webui/options/chromeos/core_chromeos_options_handler.h index b65578b..122df37 100644 --- a/chrome/browser/ui/webui/options/chromeos/core_chromeos_options_handler.h +++ b/chrome/browser/ui/webui/options/chromeos/core_chromeos_options_handler.h @@ -8,15 +8,19 @@ #include "chrome/browser/ui/webui/options/core_options_handler.h" +class PrefSetObserver; + namespace chromeos { // CoreChromeOSOptionsHandler handles ChromeOS settings. class CoreChromeOSOptionsHandler : public CoreOptionsHandler { public: CoreChromeOSOptionsHandler(); + virtual ~CoreChromeOSOptionsHandler(); protected: // ::CoreOptionsHandler overrides + virtual void Initialize(); virtual Value* FetchPref(const std::string& pref_name); virtual void ObservePref(const std::string& pref_name); virtual void SetPref(const std::string& pref_name, @@ -36,6 +40,8 @@ class CoreChromeOSOptionsHandler : public CoreOptionsHandler { // Keeps the track of change caused by the handler to make sure // it does not signal itself again. bool handling_change_; + + scoped_ptr<PrefSetObserver> proxy_prefs_; }; } // namespace chromeos diff --git a/chrome/browser/ui/webui/options/chromeos/internet_options_handler.cc b/chrome/browser/ui/webui/options/chromeos/internet_options_handler.cc index f9452be..cccdc544 100644 --- a/chrome/browser/ui/webui/options/chromeos/internet_options_handler.cc +++ b/chrome/browser/ui/webui/options/chromeos/internet_options_handler.cc @@ -32,7 +32,6 @@ #include "chrome/browser/chromeos/sim_dialog_delegate.h" #include "chrome/browser/chromeos/status/network_menu_icon.h" #include "chrome/browser/chromeos/user_cros_settings_provider.h" -#include "chrome/browser/prefs/pref_service.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_list.h" @@ -41,7 +40,6 @@ #include "chrome/browser/ui/webui/web_ui_util.h" #include "chrome/common/chrome_notification_types.h" #include "chrome/common/chrome_switches.h" -#include "chrome/common/pref_names.h" #include "chrome/common/time_format.h" #include "content/public/browser/notification_service.h" #include "grit/chromium_strings.h" @@ -120,19 +118,6 @@ void InternetOptionsHandler::GetLocalizedValues( localized_strings->SetString("changeProxyButton", l10n_util::GetStringUTF16( IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CHANGE_PROXY_BUTTON)); - localized_strings->SetString("enableSharedProxiesHint", - l10n_util::GetStringFUTF16( - IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_ENABLE_SHARED_PROXIES_HINT, - l10n_util::GetStringUTF16(IDS_OPTIONS_SETTINGS_USE_SHARED_PROXIES))); - localized_strings->SetString("policyManagedProxyText", - l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_POLICY_MANAGED_PROXY_TEXT)); - localized_strings->SetString("extensionManagedProxyText", - l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_EXTENSION_MANAGED_PROXY_TEXT)); - localized_strings->SetString("unmodifiableProxyText", - l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_UNMODIFIABLE_PROXY_TEXT)); localized_strings->SetString("wifiNetworkTabLabel", l10n_util::GetStringUTF16( @@ -705,11 +690,8 @@ void InternetOptionsHandler::SetIPConfigCallback(const ListValue* args) { void InternetOptionsHandler::PopulateDictionaryDetails( const chromeos::Network* network) { DCHECK(network); - bool use_shared_proxies = false; - if (proxy_settings()) { + if (proxy_settings()) proxy_settings()->SetCurrentNetwork(network->service_path()); - use_shared_proxies = proxy_settings()->IsUsingSharedProxies(); - } DictionaryValue dictionary; std::string hardware_address; chromeos::NetworkIPConfigVector ipconfigs = cros_->GetIPConfigs( @@ -738,40 +720,9 @@ void InternetOptionsHandler::PopulateDictionaryDetails( dictionary.SetBoolean("connected", network->connected()); dictionary.SetString("connectionState", network->GetStateString()); - // Determine if proxy is configurable. - // First check proxy prefs. - bool proxy_configurable = true; - std::string change_proxy_text; - if (web_ui_) { - const PrefService::Preference* proxy_pref = - Profile::FromWebUI(web_ui_)->GetPrefs()->FindPreference(prefs::kProxy); - if (proxy_pref && (!proxy_pref->IsUserModifiable() || - proxy_pref->HasUserSetting())) { - proxy_configurable = false; - // Provide reason that proxy is managed by admin or extension. - if (proxy_pref->IsManaged()) - change_proxy_text = "policyManagedProxyText"; - else if (proxy_pref->IsExtensionControlled()) - change_proxy_text = "extensionManagedProxyText"; - else - change_proxy_text = "unmodifiableProxyText"; - } - } - // Next check network type and use-shared-proxies. - chromeos::NetworkProfileType profile = network->profile_type(); - bool shared_network = type == chromeos::TYPE_ETHERNET || - profile == chromeos::PROFILE_SHARED; - if (proxy_configurable) { // Only check more if proxy is still configurable. - proxy_configurable = profile == chromeos::PROFILE_USER || - (shared_network && use_shared_proxies); - } - // If no reason has been set yet, provide hint to configure shared proxy. - if (change_proxy_text.empty() && shared_network && !use_shared_proxies) - change_proxy_text = "enableSharedProxiesHint"; - // Lastly, store proxy-configurable flag and, if available, text to display. - dictionary.SetBoolean("proxyConfigurable", proxy_configurable); - if (!change_proxy_text.empty()) - dictionary.SetString("changeProxyText", change_proxy_text); + // Only show proxy for remembered networks. + chromeos::NetworkProfileType network_profile = network->profile_type(); + dictionary.SetBoolean("showProxy", network_profile != chromeos::PROFILE_NONE); // Hide the dhcp/static radio if not ethernet or wifi (or if not enabled) bool staticIPConfig = CommandLine::ForCurrentProcess()->HasSwitch( @@ -779,7 +730,7 @@ void InternetOptionsHandler::PopulateDictionaryDetails( dictionary.SetBoolean("showStaticIPConfig", staticIPConfig && (type == chromeos::TYPE_WIFI || type == chromeos::TYPE_ETHERNET)); - if (network->profile_type() == chromeos::PROFILE_USER) { + if (network_profile == chromeos::PROFILE_USER) { dictionary.SetBoolean("showPreferred", true); dictionary.SetBoolean("preferred", network->preferred()); } else { diff --git a/chrome/browser/ui/webui/options/chromeos/proxy_handler.cc b/chrome/browser/ui/webui/options/chromeos/proxy_handler.cc index 567bb96..867ccf3 100644 --- a/chrome/browser/ui/webui/options/chromeos/proxy_handler.cc +++ b/chrome/browser/ui/webui/options/chromeos/proxy_handler.cc @@ -20,8 +20,8 @@ namespace chromeos { -ProxyHandler::ProxyHandler() - : CrosOptionsPageUIHandler(new ProxyCrosSettingsProvider()) { +ProxyHandler::ProxyHandler(Profile* profile) + : CrosOptionsPageUIHandler(new ProxyCrosSettingsProvider(profile)) { } ProxyHandler::~ProxyHandler() { @@ -67,6 +67,16 @@ void ProxyHandler::GetLocalizedValues( l10n_util::GetStringUTF16(IDS_PROXY_PORT)); localized_strings->SetString("proxyBypass", l10n_util::GetStringUTF16(IDS_PROXY_BYPASS)); + localized_strings->SetString("policyManagedPrefsBannerText", + l10n_util::GetStringUTF16(IDS_OPTIONS_POLICY_MANAGED_PREFS)); + localized_strings->SetString("extensionManagedPrefsBannerText", + l10n_util::GetStringUTF16(IDS_OPTIONS_EXTENSION_MANAGED_PREFS)); + localized_strings->SetString("unmodifiablePrefsBannerText", + l10n_util::GetStringUTF16(IDS_OPTIONS_UNMODIFIABLE_PREFS)); + localized_strings->SetString("enableSharedProxiesBannerText", + l10n_util::GetStringFUTF16( + IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_ENABLE_SHARED_PROXIES_HINT, + l10n_util::GetStringUTF16(IDS_OPTIONS_SETTINGS_USE_SHARED_PROXIES))); } void ProxyHandler::SetNetworkName(const std::string& name) { diff --git a/chrome/browser/ui/webui/options/chromeos/proxy_handler.h b/chrome/browser/ui/webui/options/chromeos/proxy_handler.h index 37c97ed..3f23b20 100644 --- a/chrome/browser/ui/webui/options/chromeos/proxy_handler.h +++ b/chrome/browser/ui/webui/options/chromeos/proxy_handler.h @@ -12,7 +12,7 @@ namespace chromeos { // ChromeOS proxy options page UI handler. class ProxyHandler : public CrosOptionsPageUIHandler { public: - ProxyHandler(); + explicit ProxyHandler(Profile* profile); virtual ~ProxyHandler(); // OptionsPageUIHandler implementation. diff --git a/chrome/browser/ui/webui/options/core_options_handler.cc b/chrome/browser/ui/webui/options/core_options_handler.cc index 0e17749..c7e175a 100644 --- a/chrome/browser/ui/webui/options/core_options_handler.cc +++ b/chrome/browser/ui/webui/options/core_options_handler.cc @@ -15,7 +15,6 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/google/google_util.h" #include "chrome/browser/net/url_fixer_upper.h" -#include "chrome/browser/prefs/pref_service.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/chrome_notification_types.h" #include "chrome/common/pref_names.h" @@ -30,33 +29,6 @@ #include "grit/theme_resources.h" #include "ui/base/l10n/l10n_util.h" -namespace { - -DictionaryValue* CreateValueForPref(const PrefService* pref_service, - const PrefService::Preference* pref) { - DictionaryValue* dict = new DictionaryValue; - dict->Set("value", pref->GetValue()->DeepCopy()); - const PrefService::Preference* controlling_pref = pref; -#if defined(OS_CHROMEOS) - // For use-shared-proxies pref, the proxy pref determines if the former is - // modifiable or managed by policy/extension. - if (pref->name() == prefs::kUseSharedProxies) { - controlling_pref = pref_service->FindPreference(prefs::kProxy); - if (!controlling_pref) - return dict; - } -#endif // defined(OS_CHROMEOS) - if (controlling_pref->IsManaged()) { - dict->SetString("controlledBy", "policy"); - } else if (controlling_pref->IsExtensionControlled()) { - dict->SetString("controlledBy", "extension"); - } - dict->SetBoolean("disabled", !controlling_pref->IsUserModifiable()); - return dict; -} - -} // namespace - CoreOptionsHandler::CoreOptionsHandler() : handlers_host_(NULL) { } @@ -138,8 +110,15 @@ WebUIMessageHandler* CoreOptionsHandler::Attach(WebUI* web_ui) { void CoreOptionsHandler::Observe(int type, const content::NotificationSource& source, const content::NotificationDetails& details) { - if (type == chrome::NOTIFICATION_PREF_CHANGED) - NotifyPrefChanged(content::Details<std::string>(details).ptr()); + if (type == chrome::NOTIFICATION_PREF_CHANGED) { + std::string* pref_name = content::Details<std::string>(details).ptr(); + if (*pref_name == prefs::kClearPluginLSODataEnabled) { + // This preference is stored in Local State, not in the user preferences. + UpdateClearPluginLSOData(); + return; + } + NotifyPrefChanged(*pref_name, std::string()); + } } void CoreOptionsHandler::RegisterMessages() { @@ -191,7 +170,7 @@ Value* CoreOptionsHandler::FetchPref(const std::string& pref_name) { if (!pref) return Value::CreateNullValue(); - return CreateValueForPref(pref_service, pref); + return CreateValueForPref(pref, NULL); } void CoreOptionsHandler::ObservePref(const std::string& pref_name) { @@ -217,6 +196,7 @@ void CoreOptionsHandler::SetPref(const std::string& pref_name, } pref_service->ScheduleSavePersistentPrefs(); + ProcessUserMetric(value, metric); } @@ -245,6 +225,47 @@ void CoreOptionsHandler::ProcessUserMetric(const Value* value, UserMetrics::RecordComputedAction(metric_string); } +void CoreOptionsHandler::NotifyPrefChanged( + const std::string& pref_name, + const std::string& controlling_pref_name) { + const PrefService* pref_service = Profile::FromWebUI(web_ui_)->GetPrefs(); + const PrefService::Preference* pref = + pref_service->FindPreference(pref_name.c_str()); + if (!pref) + return; + const PrefService::Preference* controlling_pref = + !controlling_pref_name.empty() ? + pref_service->FindPreference(controlling_pref_name.c_str()) : NULL; + std::pair<PreferenceCallbackMap::const_iterator, + PreferenceCallbackMap::const_iterator> range; + range = pref_callback_map_.equal_range(pref_name); + for (PreferenceCallbackMap::const_iterator iter = range.first; + iter != range.second; ++iter) { + const std::wstring& callback_function = iter->second; + ListValue result_value; + result_value.Append(Value::CreateStringValue(pref_name.c_str())); + result_value.Append(CreateValueForPref(pref, controlling_pref)); + web_ui_->CallJavascriptFunction(WideToASCII(callback_function), + result_value); + } +} + +DictionaryValue* CoreOptionsHandler::CreateValueForPref( + const PrefService::Preference* pref, + const PrefService::Preference* controlling_pref) { + DictionaryValue* dict = new DictionaryValue; + dict->Set("value", pref->GetValue()->DeepCopy()); + if (!controlling_pref) // No controlling pref is managing actual pref. + controlling_pref = pref; // This means pref is controlling itself. + if (controlling_pref->IsManaged()) { + dict->SetString("controlledBy", "policy"); + } else if (controlling_pref->IsExtensionControlled()) { + dict->SetString("controlledBy", "extension"); + } + dict->SetBoolean("disabled", !controlling_pref->IsUserModifiable()); + return dict; +} + void CoreOptionsHandler::StopObservingPref(const std::string& path) { registrar_.Remove(path.c_str(), this); } @@ -427,32 +448,3 @@ void CoreOptionsHandler::UpdateClearPluginLSOData() { web_ui_->CallJavascriptFunction( "OptionsPage.setClearPluginLSODataEnabled", *enabled); } - -void CoreOptionsHandler::NotifyPrefChanged(const std::string* pref_name) { - if (*pref_name == prefs::kClearPluginLSODataEnabled) { - // This preference is stored in Local State, not in the user preferences. - UpdateClearPluginLSOData(); - return; - } - - PrefService* pref_service = Profile::FromWebUI(web_ui_)->GetPrefs(); - const PrefService::Preference* pref = - pref_service->FindPreference(pref_name->c_str()); - if (!pref) - return; - - std::pair<PreferenceCallbackMap::const_iterator, - PreferenceCallbackMap::const_iterator> range; - range = pref_callback_map_.equal_range(*pref_name); - for (PreferenceCallbackMap::const_iterator iter = range.first; - iter != range.second; ++iter) { - const std::wstring& callback_function = iter->second; - ListValue result_value; - result_value.Append(Value::CreateStringValue(pref_name->c_str())); - - result_value.Append(CreateValueForPref(pref_service, pref)); - - web_ui_->CallJavascriptFunction(WideToASCII(callback_function), - result_value); - } -} diff --git a/chrome/browser/ui/webui/options/core_options_handler.h b/chrome/browser/ui/webui/options/core_options_handler.h index e077857..95c9903 100644 --- a/chrome/browser/ui/webui/options/core_options_handler.h +++ b/chrome/browser/ui/webui/options/core_options_handler.h @@ -12,6 +12,7 @@ #include "base/values.h" #include "chrome/browser/plugin_data_remover_helper.h" #include "chrome/browser/prefs/pref_change_registrar.h" +#include "chrome/browser/prefs/pref_service.h" #include "chrome/browser/ui/webui/options/options_ui.h" // Core options UI handler. @@ -66,8 +67,23 @@ class CoreOptionsHandler : public OptionsPageUIHandler { void ProcessUserMetric(const Value* value, const std::string& metric); + // Notifies registered JS callbacks on change in |pref_name| preference. + // |controlling_pref_name| controls if |pref_name| is managed by + // policy/extension; empty |controlling_pref_name| indicates no other pref is + // controlling |pref_name|. + void NotifyPrefChanged(const std::string& pref_name, + const std::string& controlling_pref_name); + + // Creates dictionary value for |pref|, |controlling_pref| controls if |pref| + // is managed by policy/extension; NULL indicates no other pref is controlling + // |pref|. + DictionaryValue* CreateValueForPref( + const PrefService::Preference* pref, + const PrefService::Preference* controlling_pref); + typedef std::multimap<std::string, std::wstring> PreferenceCallbackMap; PreferenceCallbackMap pref_callback_map_; + private: // Type of preference value received from the page. This doesn't map 1:1 to // Value::Type, since a TYPE_STRING can require custom processing. @@ -122,8 +138,6 @@ class CoreOptionsHandler : public OptionsPageUIHandler { void UpdateClearPluginLSOData(); - void NotifyPrefChanged(const std::string* pref_name); - OptionsPageUIHandlerHost* handlers_host_; PrefChangeRegistrar registrar_; diff --git a/chrome/browser/ui/webui/options/options_ui.cc b/chrome/browser/ui/webui/options/options_ui.cc index 7674a91..1da512c 100644 --- a/chrome/browser/ui/webui/options/options_ui.cc +++ b/chrome/browser/ui/webui/options/options_ui.cc @@ -252,7 +252,8 @@ OptionsUI::OptionsUI(TabContents* contents) new chromeos::LanguagePinyinHandler()); AddOptionsPageUIHandler(localized_strings, new chromeos::VirtualKeyboardManagerHandler()); - AddOptionsPageUIHandler(localized_strings, new chromeos::ProxyHandler()); + AddOptionsPageUIHandler(localized_strings, + new chromeos::ProxyHandler(GetProfile())); AddOptionsPageUIHandler(localized_strings, new chromeos::ChangePictureOptionsHandler()); AddOptionsPageUIHandler(localized_strings, diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index b7c283a..871c7e7 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -754,8 +754,6 @@ 'browser/chromeos/preferences.h', 'browser/chromeos/prerender_condition_network.cc', 'browser/chromeos/prerender_condition_network.h', - 'browser/chromeos/proxy_config_service.cc', - 'browser/chromeos/proxy_config_service.h', 'browser/chromeos/proxy_config_service_impl.cc', 'browser/chromeos/proxy_config_service_impl.h', 'browser/chromeos/proxy_cros_settings_provider.cc', @@ -1624,8 +1622,9 @@ 'browser/net/preconnect.h', 'browser/net/predictor.cc', 'browser/net/predictor.h', - 'browser/net/pref_proxy_config_service.cc', - 'browser/net/pref_proxy_config_service.h', + 'browser/net/pref_proxy_config_tracker.h', + 'browser/net/pref_proxy_config_tracker_impl.cc', + 'browser/net/pref_proxy_config_tracker_impl.h', 'browser/net/proxy_service_factory.cc', 'browser/net/proxy_service_factory.h', 'browser/net/quoted_printable.cc', diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index 5a2b86c..e86c146 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -1426,7 +1426,7 @@ 'browser/net/network_stats_unittest.cc', 'browser/net/passive_log_collector_unittest.cc', 'browser/net/predictor_unittest.cc', - 'browser/net/pref_proxy_config_service_unittest.cc', + 'browser/net/pref_proxy_config_tracker_impl_unittest.cc', 'browser/net/quoted_printable_unittest.cc', 'browser/net/sqlite_origin_bound_cert_store_unittest.cc', 'browser/net/sqlite_persistent_cookie_store_unittest.cc', diff --git a/chrome/test/base/testing_browser_process.cc b/chrome/test/base/testing_browser_process.cc index 6f24fdc..32b4bf8 100644 --- a/chrome/test/base/testing_browser_process.cc +++ b/chrome/test/base/testing_browser_process.cc @@ -131,11 +131,6 @@ net::URLRequestContextGetter* TestingBrowserProcess::system_request_context() { } #if defined(OS_CHROMEOS) -chromeos::ProxyConfigServiceImpl* -TestingBrowserProcess::chromeos_proxy_config_service_impl() { - return NULL; -} - browser::OomPriorityManager* TestingBrowserProcess::oom_priority_manager() { return NULL; } diff --git a/chrome/test/base/testing_browser_process.h b/chrome/test/base/testing_browser_process.h index 2a561f9..3705c1a 100644 --- a/chrome/test/base/testing_browser_process.h +++ b/chrome/test/base/testing_browser_process.h @@ -78,8 +78,6 @@ class TestingBrowserProcess : public BrowserProcess { virtual net::URLRequestContextGetter* system_request_context() OVERRIDE; #if defined(OS_CHROMEOS) - virtual chromeos::ProxyConfigServiceImpl* - chromeos_proxy_config_service_impl() OVERRIDE; virtual browser::OomPriorityManager* oom_priority_manager() OVERRIDE; #endif // defined(OS_CHROMEOS) diff --git a/chrome/test/base/testing_profile.cc b/chrome/test/base/testing_profile.cc index 04f2b72..f5bdde6 100644 --- a/chrome/test/base/testing_profile.cc +++ b/chrome/test/base/testing_profile.cc @@ -26,7 +26,7 @@ #include "chrome/browser/history/history_backend.h" #include "chrome/browser/history/top_sites.h" #include "chrome/browser/net/gaia/token_service.h" -#include "chrome/browser/net/pref_proxy_config_service.h" +#include "chrome/browser/net/proxy_service_factory.h" #include "chrome/browser/notifications/desktop_notification_service.h" #include "chrome/browser/notifications/desktop_notification_service_factory.h" #include "chrome/browser/prefs/browser_prefs.h" @@ -62,6 +62,10 @@ #include "webkit/quota/mock_quota_manager.h" #include "webkit/quota/quota_manager.h" +#if defined(OS_CHROMEOS) +#include "chrome/browser/chromeos/proxy_config_service_impl.h" +#endif // defined(OS_CHROMEOS) + using base::Time; using content::BrowserThread; using testing::NiceMock; @@ -719,10 +723,11 @@ void TestingProfile::set_last_selected_directory(const FilePath& path) { } PrefProxyConfigTracker* TestingProfile::GetProxyConfigTracker() { - if (!pref_proxy_config_tracker_) - pref_proxy_config_tracker_ = new PrefProxyConfigTracker(GetPrefs()); - - return pref_proxy_config_tracker_; + if (!pref_proxy_config_tracker_.get()) { + pref_proxy_config_tracker_.reset( + ProxyServiceFactory::CreatePrefProxyConfigTracker(GetPrefs())); + } + return pref_proxy_config_tracker_.get(); } void TestingProfile::BlockUntilHistoryProcessesPendingRequests() { diff --git a/chrome/test/base/testing_profile.h b/chrome/test/base/testing_profile.h index 75a26a1..b4e412d 100644 --- a/chrome/test/base/testing_profile.h +++ b/chrome/test/base/testing_profile.h @@ -383,7 +383,7 @@ class TestingProfile : public Profile { extension_special_storage_policy_; // The proxy prefs tracker. - scoped_refptr<PrefProxyConfigTracker> pref_proxy_config_tracker_; + scoped_ptr<PrefProxyConfigTracker> pref_proxy_config_tracker_; // We use a temporary directory to store testing profile data. In a multi- // profile environment, this is invalid and the directory is managed by the diff --git a/chrome/test/pyautolib/pyauto.py b/chrome/test/pyautolib/pyauto.py index 61d402f..3f1a593 100644 --- a/chrome/test/pyautolib/pyauto.py +++ b/chrome/test/pyautolib/pyauto.py @@ -3621,7 +3621,7 @@ class PyUITest(pyautolib.PyUITestBase, unittest.TestCase): self.PROXY_TYPE_PAC: 'Automatic proxy configuration' } return values[proxy_type] - def GetProxySettingsOnChromeOS(self): + def GetProxySettingsOnChromeOS(self, windex=0): """Get current proxy settings on Chrome OS. Returns: @@ -3648,9 +3648,9 @@ class PyUITest(pyautolib.PyUITestBase, unittest.TestCase): pyauto_errors.JSONInterfaceError if the automation call returns an error. """ cmd_dict = { 'command': 'GetProxySettings' } - return self._GetResultFromJSONRequest(cmd_dict, windex=-1) + return self._GetResultFromJSONRequest(cmd_dict, windex=windex) - def SetProxySettingsOnChromeOS(self, key, value): + def SetProxySettingsOnChromeOS(self, key, value, windex=0): """Set a proxy setting on Chrome OS. Owner must be logged in for these to persist. @@ -3702,7 +3702,7 @@ class PyUITest(pyautolib.PyUITestBase, unittest.TestCase): 'key': key, 'value': value, } - return self._GetResultFromJSONRequest(cmd_dict, windex=-1) + return self._GetResultFromJSONRequest(cmd_dict, windex=windex) def ForgetWifiNetwork(self, service_path): """Forget a remembered network by its service path. |