summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
authorkuan@chromium.org <kuan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-11-04 02:26:07 +0000
committerkuan@chromium.org <kuan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-11-04 02:26:07 +0000
commit6f96cbcbd242db55cac30552d82472ecf6bf383d (patch)
tree69fa35f4ae5723946f14905007d91afe889d7ea1 /chrome/browser
parent5946838ef91d54c07e4cf2c345b61ae7eb6db064 (diff)
downloadchromium_src-6f96cbcbd242db55cac30552d82472ecf6bf383d.zip
chromium_src-6f96cbcbd242db55cac30552d82472ecf6bf383d.tar.gz
chromium_src-6f96cbcbd242db55cac30552d82472ecf6bf383d.tar.bz2
redesign and reimplement proxy config service and tracker, revise proxy ui on cros
* original plan was to revise proxy ui on cros for all proxy sources and network types, refer to bug rpt 21219 for ui details * redesign and reimplement PrefProxyConfigTracker and PrefProxyConfigService by switching the inter-dependencies between the two and renaming the latter - PrefProxyConfigService used to observe PrefProxyConfigTracker and retrieve new prefs proxy from the latter whenever the former gets notification of proxy change from prefs or delegate service to determine effective proxy config. Now, PrefProxyConfigTracker pushes new prefs proxy to the renamed ChromeProxyConfigService on the IO thread; the latter then uses it and proxy from delegate service to determine effective proxy config. - remove all thread-switching in PrefProxyConfigTracker which now lives and runs on UI thread, except for when it pushes proxy config to ChromeProxyConfigService on IO thread - enhances and moves ConfigState definition to namespace ProxyPrefs to indicate source of proxy config (policy, extension, other-precede, system, fallback) so that PrefProxyConfigTracker, ChromeProxyConfigService and chromeos::ProxyConfigServiceImpl can acccess it - extract code for deciding effective proxy config from PrefProxyConfigService into static PrefProxyConfigTracker method to be shared by all classes * re-design and re-implement chromeos::ProxyConfigServiceImpl - this now extends PrefProxyConfigTracker to act as a special of "prefs", handles all proxy changes from network and prefs notifications and uses PrefProxyConfigTracker to push effective proxy to ChromeProxyConfigService and hence to network stack - remove wrapper chromeos::ProxyConfigService - this is the authority on cros, and ChromeProxyConfigService does not have a delegat service. - provide proxy config to ui for all proxy sources: policy, extension, network or recommended (in order of precedence), also indicates if proxy is user-modifiable - handle user profile changes to use correct PrefProxyConfigTracker * modify CoreOptionsHandler and CoreChromeosOptionsHandler to implement dynamic monitoring of prefs::kProxy and on-the-fly ui changes of affected use-shared-proxies user pref * modify ui native code, html, css and javascript for internet options and proxy pages to show yellow banner with different messages (same banner as options page when there's policy), en/dis-able ui fields, set current user profile in backend * modify network dropdown menu to always show proxy settings menu item as long as there's a network * modify automation tests, PrefProxyConfigTracker and ProxyConfigSerivceImpl unittests to handle redesign, fix unittests that fail due to redesign BUG=chromium-os:20679,chromium-os:21219 TEST=verify per bugs rpts Review URL: http://codereview.chromium.org/8102019 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@108616 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r--chrome/browser/automation/testing_automation_provider.cc8
-rw-r--r--chrome/browser/automation/testing_automation_provider.h6
-rw-r--r--chrome/browser/automation/testing_automation_provider_chromeos.cc19
-rw-r--r--chrome/browser/browser_process.h8
-rw-r--r--chrome/browser/browser_process_impl.cc11
-rw-r--r--chrome/browser/browser_process_impl.h4
-rw-r--r--chrome/browser/chromeos/cros/network_library.cc4
-rw-r--r--chrome/browser/chromeos/preferences.cc14
-rw-r--r--chrome/browser/chromeos/preferences.h2
-rw-r--r--chrome/browser/chromeos/proxy_config_service.cc29
-rw-r--r--chrome/browser/chromeos/proxy_config_service.h35
-rw-r--r--chrome/browser/chromeos/proxy_config_service_impl.cc831
-rw-r--r--chrome/browser/chromeos/proxy_config_service_impl.h286
-rw-r--r--chrome/browser/chromeos/proxy_config_service_impl_unittest.cc520
-rw-r--r--chrome/browser/chromeos/proxy_cros_settings_provider.cc41
-rw-r--r--chrome/browser/chromeos/proxy_cros_settings_provider.h13
-rw-r--r--chrome/browser/chromeos/status/network_menu.cc31
-rw-r--r--chrome/browser/extensions/extension_proxy_apitest.cc13
-rw-r--r--chrome/browser/io_thread.cc21
-rw-r--r--chrome/browser/io_thread.h4
-rw-r--r--chrome/browser/net/pref_proxy_config_service.cc280
-rw-r--r--chrome/browser/net/pref_proxy_config_service.h148
-rw-r--r--chrome/browser/net/pref_proxy_config_tracker.h23
-rw-r--r--chrome/browser/net/pref_proxy_config_tracker_impl.cc339
-rw-r--r--chrome/browser/net/pref_proxy_config_tracker_impl.h155
-rw-r--r--chrome/browser/net/pref_proxy_config_tracker_impl_unittest.cc (renamed from chrome/browser/net/pref_proxy_config_service_unittest.cc)50
-rw-r--r--chrome/browser/net/proxy_service_factory.cc42
-rw-r--r--chrome/browser/net/proxy_service_factory.h21
-rw-r--r--chrome/browser/net/ssl_config_service_manager_pref_unittest.cc3
-rw-r--r--chrome/browser/prefs/browser_prefs.cc8
-rw-r--r--chrome/browser/prefs/proxy_prefs.h20
-rw-r--r--chrome/browser/profiles/off_the_record_profile_impl.cc13
-rw-r--r--chrome/browser/profiles/off_the_record_profile_impl.h3
-rw-r--r--chrome/browser/profiles/profile.cc1
-rw-r--r--chrome/browser/profiles/profile.h2
-rw-r--r--chrome/browser/profiles/profile_impl.cc14
-rw-r--r--chrome/browser/profiles/profile_impl.h2
-rw-r--r--chrome/browser/profiles/profile_io_data.cc10
-rw-r--r--chrome/browser/profiles/profile_manager_unittest.cc11
-rw-r--r--chrome/browser/resources/options/chromeos/internet_detail.html1
-rw-r--r--chrome/browser/resources/options/chromeos/internet_options.js17
-rw-r--r--chrome/browser/resources/options/chromeos/proxy.html18
-rw-r--r--chrome/browser/resources/options/chromeos/proxy_options.js86
-rw-r--r--chrome/browser/resources/options/options.html6
-rw-r--r--chrome/browser/resources/options/options_page.css13
-rw-r--r--chrome/browser/ui/webui/chromeos/proxy_settings_ui.cc9
-rw-r--r--chrome/browser/ui/webui/options/advanced_options_handler.cc6
-rw-r--r--chrome/browser/ui/webui/options/advanced_options_handler.h8
-rw-r--r--chrome/browser/ui/webui/options/chromeos/core_chromeos_options_handler.cc37
-rw-r--r--chrome/browser/ui/webui/options/chromeos/core_chromeos_options_handler.h6
-rw-r--r--chrome/browser/ui/webui/options/chromeos/internet_options_handler.cc59
-rw-r--r--chrome/browser/ui/webui/options/chromeos/proxy_handler.cc14
-rw-r--r--chrome/browser/ui/webui/options/chromeos/proxy_handler.h2
-rw-r--r--chrome/browser/ui/webui/options/core_options_handler.cc112
-rw-r--r--chrome/browser/ui/webui/options/core_options_handler.h18
-rw-r--r--chrome/browser/ui/webui/options/options_ui.cc3
56 files changed, 1671 insertions, 1789 deletions
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,