Cleanup the UseSharedProxies preference.

- remove the UserSharedProxies pref from local state
- fix the default value of the pref in the profile pref service
- make the conditionals, when to use or ignore proxy settings, more explicit and clearer.

BUG=258835
TEST=Manually checked all combinations of {DevicePolicy, UserPolicy, SharedNetwork, NotSharedNetwork} x {before, after login} x {enabled, disabled UseSharedProxies} for proxies of the system context, signin profile and user's profile. I checked the proxies by looking at the vlogs and the UI (like net-internals and settings page). I did not test the actual network connectivity of each context.

[email protected], [email protected]

Review URL: https://codereview.chromium.org/18112018

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@211954 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
index 9d7097f..e857e2d 100644
--- a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
+++ b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
@@ -590,13 +590,6 @@
   //    i.e. not on Chrome OS device w/o login flow.
   if (parsed_command_line().HasSwitch(switches::kLoginUser) &&
       !parsed_command_line().HasSwitch(switches::kLoginPassword)) {
-    // Make sure we flip every profile to not share proxies if the user hasn't
-    // specified so explicitly.
-    const PrefService::Preference* use_shared_proxies_pref =
-        profile()->GetPrefs()->FindPreference(prefs::kUseSharedProxies);
-    if (use_shared_proxies_pref->IsDefaultValue())
-      profile()->GetPrefs()->SetBoolean(prefs::kUseSharedProxies, false);
-
     // This is done in LoginUtils::OnProfileCreated during normal login.
     LoginUtils::Get()->InitRlzDelayed(profile());
 
diff --git a/chrome/browser/chromeos/login/login_utils.cc b/chrome/browser/chromeos/login/login_utils.cc
index fa9368b..14023382 100644
--- a/chrome/browser/chromeos/login/login_utils.cc
+++ b/chrome/browser/chromeos/login/login_utils.cc
@@ -365,13 +365,6 @@
         UserManager::Get()->GetLoggedInUser()->display_email());
   }
 
-  // Make sure we flip every profile to not share proxies if the user hasn't
-  // specified so explicitly.
-  const PrefService::Preference* use_shared_proxies_pref =
-      user_profile->GetPrefs()->FindPreference(prefs::kUseSharedProxies);
-  if (use_shared_proxies_pref->IsDefaultValue())
-    user_profile->GetPrefs()->SetBoolean(prefs::kUseSharedProxies, false);
-
   RespectLocalePreference(user_profile);
 }
 
diff --git a/chrome/browser/chromeos/net/proxy_config_handler.cc b/chrome/browser/chromeos/net/proxy_config_handler.cc
index 013fb447..adb4c86 100644
--- a/chrome/browser/chromeos/net/proxy_config_handler.cc
+++ b/chrome/browser/chromeos/net/proxy_config_handler.cc
@@ -9,11 +9,13 @@
 #include "base/logging.h"
 #include "base/values.h"
 #include "chrome/browser/prefs/proxy_config_dictionary.h"
+#include "chrome/common/pref_names.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "chromeos/dbus/shill_service_client.h"
 #include "chromeos/network/network_handler_callbacks.h"
 #include "chromeos/network/network_state.h"
 #include "chromeos/network/network_state_handler.h"
+#include "components/user_prefs/pref_registry_syncable.h"
 #include "dbus/object_path.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
 
@@ -64,6 +66,14 @@
   }
 }
 
+void RegisterProfilePrefs(
+    user_prefs::PrefRegistrySyncable* registry) {
+  registry->RegisterBooleanPref(
+      prefs::kUseSharedProxies,
+      false,
+      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
+}
+
 }  // namespace proxy_config
 
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/net/proxy_config_handler.h b/chrome/browser/chromeos/net/proxy_config_handler.h
index 5162c5c6..b8455dc 100644
--- a/chrome/browser/chromeos/net/proxy_config_handler.h
+++ b/chrome/browser/chromeos/net/proxy_config_handler.h
@@ -9,6 +9,10 @@
 
 class ProxyConfigDictionary;
 
+namespace user_prefs {
+class PrefRegistrySyncable;
+}
+
 namespace chromeos {
 
 class NetworkState;
@@ -21,6 +25,8 @@
 void SetProxyConfigForNetwork(const ProxyConfigDictionary& proxy_config,
                               const NetworkState& network);
 
+void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
+
 }  // namespace proxy_config
 
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/proxy_config_service_impl.cc b/chrome/browser/chromeos/proxy_config_service_impl.cc
index f9cceac..95f4f19 100644
--- a/chrome/browser/chromeos/proxy_config_service_impl.cc
+++ b/chrome/browser/chromeos/proxy_config_service_impl.cc
@@ -7,7 +7,6 @@
 #include "base/bind.h"
 #include "base/location.h"
 #include "base/logging.h"
-#include "base/prefs/pref_registry_simple.h"
 #include "base/prefs/pref_service.h"
 #include "base/values.h"
 #include "chrome/browser/browser_process.h"
@@ -23,7 +22,6 @@
 #include "chromeos/network/network_state.h"
 #include "chromeos/network/network_state_handler.h"
 #include "chromeos/network/onc/onc_utils.h"
-#include "components/user_prefs/pref_registry_syncable.h"
 
 namespace chromeos {
 
@@ -43,15 +41,19 @@
 
 }  // namespace
 
-ProxyConfigServiceImpl::ProxyConfigServiceImpl(PrefService* pref_service)
-    : PrefProxyConfigTrackerImpl(pref_service),
+ProxyConfigServiceImpl::ProxyConfigServiceImpl(PrefService* profile_prefs,
+                                               PrefService* local_state_prefs)
+    : PrefProxyConfigTrackerImpl(profile_prefs ? profile_prefs
+                                               : local_state_prefs),
       active_config_state_(ProxyPrefs::CONFIG_UNSET),
+      profile_prefs_(profile_prefs),
       pointer_factory_(this) {
-
   // Register for notifications of UseSharedProxies user preference.
-  if (pref_service->FindPreference(prefs::kUseSharedProxies)) {
+  if (profile_prefs) {
+    DCHECK(profile_prefs->FindPreference(prefs::kUseSharedProxies));
     use_shared_proxies_.Init(
-        prefs::kUseSharedProxies, pref_service,
+        prefs::kUseSharedProxies,
+        profile_prefs,
         base::Bind(&ProxyConfigServiceImpl::OnUseSharedProxiesChanged,
                    base::Unretained(this)));
   }
@@ -79,24 +81,8 @@
   DetermineEffectiveConfigFromDefaultNetwork();
 }
 
-// static
-void ProxyConfigServiceImpl::RegisterPrefs(PrefRegistrySimple* registry) {
-  // Use shared proxies default to off.  GetUseSharedProxies will return the
-  // correct value based on pre-login and login.
-  registry->RegisterBooleanPref(prefs::kUseSharedProxies, true);
-}
-
-// static
-void ProxyConfigServiceImpl::RegisterProfilePrefs(
-    user_prefs::PrefRegistrySyncable* registry) {
-  registry->RegisterBooleanPref(
-      prefs::kUseSharedProxies,
-      true,
-      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
-}
-
 void ProxyConfigServiceImpl::OnUseSharedProxiesChanged() {
-  VLOG(1) << "New use-shared-proxies = " << GetUseSharedProxies(prefs());
+  VLOG(1) << "use-shared-proxies pref changed.";
   DetermineEffectiveConfigFromDefaultNetwork();
 }
 
@@ -119,43 +105,30 @@
 }
 
 // static
-bool ProxyConfigServiceImpl::GetUseSharedProxies(
-    const PrefService* pref_service) {
-  const PrefService::Preference* use_shared_proxies_pref =
-      pref_service->FindPreference(prefs::kUseSharedProxies);
-  if (!use_shared_proxies_pref || !use_shared_proxies_pref->GetValue()) {
-    if (UserManager::Get()->IsUserLoggedIn()) {
-      VLOG(1) << "use-shared-proxies not set, defaulting to false/IgnoreProxy.";
-      return false;
-    } else {
-      // Make sure that proxies are always enabled at sign in screen.
-      VLOG(1) << "Use proxy on login screen.";
-      return true;
-    }
-  }
-  bool use_shared_proxies = false;
-  use_shared_proxies_pref->GetValue()->GetAsBoolean(&use_shared_proxies);
-  return use_shared_proxies;
-}
-
-// static
-bool ProxyConfigServiceImpl::IgnoreProxy(const PrefService* pref_service,
+bool ProxyConfigServiceImpl::IgnoreProxy(const PrefService* profile_prefs,
                                          const std::string network_profile_path,
                                          onc::ONCSource onc_source) {
+  if (!profile_prefs) {
+    // If the profile preference are not available, this must be the object
+    // associated to local state used for system requests or login-profile. Make
+    // sure that proxies are enabled.
+    VLOG(1) << "Use proxy for system requests and sign-in screen.";
+    return false;
+  }
+
   const NetworkProfile* profile =
       NetworkHandler::Get()->network_profile_handler()->
       GetProfileForPath(network_profile_path);
   if (!profile) {
-    LOG(WARNING) << "Unknown profile_path " << network_profile_path;
+    LOG(WARNING) << "Unknown profile_path '" << network_profile_path
+                 << "'. Ignoring proxy.";
     return true;
   }
   if (profile->type() == NetworkProfile::TYPE_USER) {
     VLOG(1) << "Respect proxy of not-shared networks.";
     return false;
   }
-
-  if (onc_source == onc::ONC_SOURCE_DEVICE_POLICY &&
-      UserManager::Get()->IsUserLoggedIn()) {
+  if (onc_source == onc::ONC_SOURCE_DEVICE_POLICY) {
     policy::BrowserPolicyConnector* connector =
         g_browser_process->browser_policy_connector();
     const User* logged_in_user = UserManager::Get()->GetLoggedInUser();
@@ -167,7 +140,10 @@
     }
   }
 
-  return !GetUseSharedProxies(pref_service);
+  // This network is shared and not managed by the user's domain.
+  bool use_shared_proxies = profile_prefs->GetBoolean(prefs::kUseSharedProxies);
+  VLOG(1) << "Use proxy of shared network: " << use_shared_proxies;
+  return !use_shared_proxies;
 }
 
 void ProxyConfigServiceImpl::DetermineEffectiveConfigFromDefaultNetwork() {
@@ -184,8 +160,8 @@
       net::ProxyConfigService::CONFIG_UNSET;
   bool ignore_proxy = true;
   if (network) {
-    ignore_proxy =
-        IgnoreProxy(prefs(), network->profile_path(), network->onc_source());
+    ignore_proxy = IgnoreProxy(
+        profile_prefs_, network->profile_path(), network->onc_source());
     // If network is shared but use-shared-proxies is off, use direct mode.
     if (ignore_proxy) {
       VLOG(1) << "Shared network && !use-shared-proxies, use direct";
diff --git a/chrome/browser/chromeos/proxy_config_service_impl.h b/chrome/browser/chromeos/proxy_config_service_impl.h
index c45c4b7..de8f493 100644
--- a/chrome/browser/chromeos/proxy_config_service_impl.h
+++ b/chrome/browser/chromeos/proxy_config_service_impl.h
@@ -38,14 +38,18 @@
  public:
   // ProxyConfigServiceImpl is created in ProxyServiceFactory::
   // CreatePrefProxyConfigTrackerImpl via Profile::GetProxyConfigTracker() for
-  // profile or IOThread constructor for local state and is owned by the
+  // profile or via IOThread constructor for local state and is owned by the
   // respective classes.
   //
-  // 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
+  // The user's proxy config, proxy policies and proxy from prefs, are used to
+  // determine the effective proxy config, which is then pushed through
+  // PrefProxyConfigTrackerImpl to ChromeProxyConfigService to the
   // network stack.
-  explicit ProxyConfigServiceImpl(PrefService* pref_service);
+  //
+  // |profile_prefs| can be NULL if this object should only track prefs from
+  // local state (e.g., for system request context or sigin-in screen).
+  explicit ProxyConfigServiceImpl(PrefService* profile_prefs,
+                                  PrefService* local_state_prefs);
   virtual ~ProxyConfigServiceImpl();
 
   // PrefProxyConfigTrackerImpl implementation.
@@ -55,21 +59,13 @@
   // NetworkStateHandlerObserver implementation.
   virtual void DefaultNetworkChanged(const NetworkState* network) OVERRIDE;
 
-  // Register UseShardProxies preference.
-  static void RegisterPrefs(PrefRegistrySimple* registry);
-  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
-
  protected:
   friend class UIProxyConfigService;
 
-  // Returns value of UseSharedProxies preference if it's not default, else
-  // returns false if user is logged in and true otherwise.
-  static bool GetUseSharedProxies(const PrefService* pref_service);
-
-  // Returns true if proxy is to be ignored for this profile and |onc_source|,
-  // e.g. this happens if the network is shared and use-shared-proxies is turned
-  // off.
-  static bool IgnoreProxy(const PrefService* pref_service,
+  // Returns true if proxy is to be ignored for this network profile and
+  // |onc_source|, e.g. this happens if the network is shared and
+  // use-shared-proxies is turned off. |profile_prefs| may be NULL.
+  static bool IgnoreProxy(const PrefService* profile_prefs,
                           const std::string network_profile_path,
                           onc::ONCSource onc_source);
 
@@ -93,6 +89,10 @@
   // Track changes in UseSharedProxies user preference.
   BooleanPrefMember use_shared_proxies_;
 
+  // Not owned. NULL if tracking only local state prefs (e.g. in the system
+  // request context or sign-in screen).
+  PrefService* profile_prefs_;
+
   base::WeakPtrFactory<ProxyConfigServiceImpl> pointer_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(ProxyConfigServiceImpl);
diff --git a/chrome/browser/chromeos/proxy_config_service_impl_unittest.cc b/chrome/browser/chromeos/proxy_config_service_impl_unittest.cc
index feffd4d..7ecb8cb 100644
--- a/chrome/browser/chromeos/proxy_config_service_impl_unittest.cc
+++ b/chrome/browser/chromeos/proxy_config_service_impl_unittest.cc
@@ -221,9 +221,11 @@
     SetUpNetwork();
 
     PrefProxyConfigTrackerImpl::RegisterPrefs(pref_service_.registry());
-    ProxyConfigServiceImpl::RegisterPrefs(pref_service_.registry());
     proxy_config_service_.reset(new ChromeProxyConfigService(NULL));
-    config_service_impl_.reset(new ProxyConfigServiceImpl(&pref_service_));
+    // Create a ProxyConfigServiceImpl like for the system request context.
+    config_service_impl_.reset(
+        new ProxyConfigServiceImpl(NULL,  // no profile prefs
+                                   &pref_service_));
     config_service_impl_->SetChromeProxyConfigService(
         proxy_config_service_.get());
     // SetChromeProxyConfigService triggers update of initial prefs proxy
diff --git a/chrome/browser/chromeos/ui_proxy_config_service.cc b/chrome/browser/chromeos/ui_proxy_config_service.cc
index 0f6988a..a7925a9c 100644
--- a/chrome/browser/chromeos/ui_proxy_config_service.cc
+++ b/chrome/browser/chromeos/ui_proxy_config_service.cc
@@ -56,13 +56,17 @@
 
 }  // namespace
 
-UIProxyConfigService::UIProxyConfigService() {
+UIProxyConfigService::UIProxyConfigService()
+    : signin_screen_(false),
+      pref_service_(NULL) {
 }
 
 UIProxyConfigService::~UIProxyConfigService() {
 }
 
-void UIProxyConfigService::SetPrefs(PrefService* pref_service) {
+void UIProxyConfigService::SetPrefs(bool signin_screen,
+                                    PrefService* pref_service) {
+  signin_screen_ = signin_screen;
   pref_service_ = pref_service;
 }
 
@@ -157,10 +161,10 @@
     current_ui_config_.state = ProxyPrefs::CONFIG_POLICY;
     current_ui_config_.user_modifiable = false;
   } else {
-    current_ui_config_.user_modifiable =
-        !ProxyConfigServiceImpl::IgnoreProxy(pref_service_,
-                                             network.profile_path(),
-                                             network.onc_source());
+    current_ui_config_.user_modifiable = !ProxyConfigServiceImpl::IgnoreProxy(
+        signin_screen_ ? NULL : pref_service_,
+        network.profile_path(),
+        network.onc_source());
   }
 }
 
diff --git a/chrome/browser/chromeos/ui_proxy_config_service.h b/chrome/browser/chromeos/ui_proxy_config_service.h
index 05d867e..f9d0de3 100644
--- a/chrome/browser/chromeos/ui_proxy_config_service.h
+++ b/chrome/browser/chromeos/ui_proxy_config_service.h
@@ -28,7 +28,13 @@
   UIProxyConfigService();
   ~UIProxyConfigService();
 
-  void SetPrefs(PrefService* prefs);
+  // |signin_screen| indicates whether this object is used for the
+  // signin screen, in which case proxies of (shared) networks are
+  // unconditionally respected. After signin, proxy settings of shared networks
+  // may be ignored, e.g. depending on the kUseSharedProxies flag. After this
+  // call, proxy settings are read from
+  // |prefs|.
+  void SetPrefs(bool signin_screen, PrefService* prefs);
 
   // Called by UI to set the network with service path |current_network| to be
   // displayed or edited.  Subsequent Set*/Get* methods will use this
@@ -58,6 +64,7 @@
   // Proxy configuration of |current_ui_network_|.
   UIProxyConfig current_ui_config_;
 
+  bool signin_screen_;
   PrefService* pref_service_;
 
   DISALLOW_COPY_AND_ASSIGN(UIProxyConfigService);
diff --git a/chrome/browser/io_thread.cc b/chrome/browser/io_thread.cc
index 8840dce..b9f09a9 100644
--- a/chrome/browser/io_thread.cc
+++ b/chrome/browser/io_thread.cc
@@ -398,7 +398,8 @@
       prefs::kAuthNegotiateDelegateWhitelist);
   gssapi_library_name_ = local_state->GetString(prefs::kGSSAPILibraryName);
   pref_proxy_config_tracker_.reset(
-      ProxyServiceFactory::CreatePrefProxyConfigTracker(local_state));
+      ProxyServiceFactory::CreatePrefProxyConfigTrackerOfLocalState(
+          local_state));
   ChromeNetworkDelegate::InitializePrefsOnUIThread(
       &system_enable_referrers_,
       NULL,
diff --git a/chrome/browser/net/proxy_service_factory.cc b/chrome/browser/net/proxy_service_factory.cc
index 9d30b1e3..0c83d0e8 100644
--- a/chrome/browser/net/proxy_service_factory.cc
+++ b/chrome/browser/net/proxy_service_factory.cc
@@ -54,20 +54,28 @@
   return new ChromeProxyConfigService(base_service);
 }
 
+// static
+PrefProxyConfigTracker*
+ProxyServiceFactory::CreatePrefProxyConfigTrackerOfProfile(
+    PrefService* profile_prefs,
+    PrefService* local_state_prefs) {
 #if defined(OS_CHROMEOS)
-// static
-chromeos::ProxyConfigServiceImpl*
-    ProxyServiceFactory::CreatePrefProxyConfigTracker(
-        PrefService* pref_service) {
-  return new chromeos::ProxyConfigServiceImpl(pref_service);
-}
+  return new chromeos::ProxyConfigServiceImpl(profile_prefs, local_state_prefs);
 #else
-// static
-PrefProxyConfigTrackerImpl* ProxyServiceFactory::CreatePrefProxyConfigTracker(
-    PrefService* pref_service) {
-  return new PrefProxyConfigTrackerImpl(pref_service);
-}
+  return new PrefProxyConfigTrackerImpl(profile_prefs);
 #endif  // defined(OS_CHROMEOS)
+}
+
+// static
+PrefProxyConfigTracker*
+ProxyServiceFactory::CreatePrefProxyConfigTrackerOfLocalState(
+    PrefService* local_state_prefs) {
+#if defined(OS_CHROMEOS)
+  return new chromeos::ProxyConfigServiceImpl(NULL, local_state_prefs);
+#else
+  return new PrefProxyConfigTrackerImpl(local_state_prefs);
+#endif  // defined(OS_CHROMEOS)
+}
 
 // static
 net::ProxyService* ProxyServiceFactory::CreateProxyService(
diff --git a/chrome/browser/net/proxy_service_factory.h b/chrome/browser/net/proxy_service_factory.h
index c0c26fd..154f5e9 100644
--- a/chrome/browser/net/proxy_service_factory.h
+++ b/chrome/browser/net/proxy_service_factory.h
@@ -18,6 +18,12 @@
 }
 #endif  // defined(OS_CHROMEOS)
 
+#if defined(OS_CHROMEOS)
+typedef chromeos::ProxyConfigServiceImpl PrefProxyConfigTracker;
+#else
+typedef PrefProxyConfigTrackerImpl PrefProxyConfigTracker;
+#endif  // defined(OS_CHROMEOS)
+
 namespace net {
 class NetLog;
 class NetworkDelegate;
@@ -34,13 +40,19 @@
   // about the proxy configuration by calling its UpdateProxyConfig method.
   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)
+  // Creates a PrefProxyConfigTracker that tracks preferences of a
+  // profile. On ChromeOS it additionaly tracks local state for shared proxy
+  // settings. This tracker should be used if the profile's preferences should
+  // be respected. On ChromeOS's signin screen this is for example not the case.
+  static PrefProxyConfigTracker* CreatePrefProxyConfigTrackerOfProfile(
+      PrefService* profile_prefs,
+      PrefService* local_state_prefs);
+
+  // Creates a PrefProxyConfigTracker that tracks local state only. This tracker
+  // should be used for the system request context and the signin screen
+  // (ChromeOS only).
+  static PrefProxyConfigTracker* CreatePrefProxyConfigTrackerOfLocalState(
+      PrefService* local_state_prefs);
 
   // Create a proxy service according to the options on command line.
   static net::ProxyService* CreateProxyService(
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc
index e1818e0f..69c7e85 100644
--- a/chrome/browser/prefs/browser_prefs.cc
+++ b/chrome/browser/prefs/browser_prefs.cc
@@ -134,11 +134,11 @@
 #include "chrome/browser/chromeos/login/user_image_manager.h"
 #include "chrome/browser/chromeos/login/user_manager.h"
 #include "chrome/browser/chromeos/login/wallpaper_manager.h"
+#include "chrome/browser/chromeos/net/proxy_config_handler.h"
 #include "chrome/browser/chromeos/policy/auto_enrollment_client.h"
 #include "chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos.h"
 #include "chrome/browser/chromeos/policy/device_status_collector.h"
 #include "chrome/browser/chromeos/preferences.h"
-#include "chrome/browser/chromeos/proxy_config_service_impl.h"
 #include "chrome/browser/chromeos/settings/device_oauth2_token_service.h"
 #include "chrome/browser/chromeos/settings/device_settings_cache.h"
 #include "chrome/browser/chromeos/status/data_promo_notification.h"
@@ -263,7 +263,6 @@
   chromeos::KioskAppManager::RegisterPrefs(registry);
   chromeos::LoginUtils::RegisterPrefs(registry);
   chromeos::Preferences::RegisterPrefs(registry);
-  chromeos::ProxyConfigServiceImpl::RegisterPrefs(registry);
   chromeos::RegisterDisplayLocalStatePrefs(registry);
   chromeos::ServicesCustomizationDocument::RegisterPrefs(registry);
   chromeos::system::AutomaticRebootManager::RegisterPrefs(registry);
@@ -373,7 +372,7 @@
 #if defined(OS_CHROMEOS)
   chromeos::OAuth2LoginManager::RegisterProfilePrefs(registry);
   chromeos::Preferences::RegisterProfilePrefs(registry);
-  chromeos::ProxyConfigServiceImpl::RegisterProfilePrefs(registry);
+  chromeos::proxy_config::RegisterProfilePrefs(registry);
   extensions::EnterprisePlatformKeysPrivateChallengeUserKeyFunction::
       RegisterProfilePrefs(registry);
   FlagsUI::RegisterProfilePrefs(registry);
diff --git a/chrome/browser/profiles/off_the_record_profile_impl.cc b/chrome/browser/profiles/off_the_record_profile_impl.cc
index cf95b53..931ed9a 100644
--- a/chrome/browser/profiles/off_the_record_profile_impl.cc
+++ b/chrome/browser/profiles/off_the_record_profile_impl.cc
@@ -59,6 +59,7 @@
 
 #if defined(OS_CHROMEOS)
 #include "chrome/browser/chromeos/preferences.h"
+#include "chrome/browser/chromeos/profiles/profile_helper.h"
 #include "chrome/browser/chromeos/proxy_config_service_impl.h"
 #endif
 
@@ -397,10 +398,8 @@
 #endif  // defined(OS_CHROMEOS)
 
 PrefProxyConfigTracker* OffTheRecordProfileImpl::GetProxyConfigTracker() {
-  if (!pref_proxy_config_tracker_) {
-    pref_proxy_config_tracker_.reset(
-        ProxyServiceFactory::CreatePrefProxyConfigTracker(GetPrefs()));
-  }
+  if (!pref_proxy_config_tracker_)
+    pref_proxy_config_tracker_.reset(CreateProxyConfigTracker());
   return pref_proxy_config_tracker_.get();
 }
 
@@ -474,3 +473,15 @@
        return;
   }
 }
+
+PrefProxyConfigTracker* OffTheRecordProfileImpl::CreateProxyConfigTracker() {
+#if defined(OS_CHROMEOS)
+  if (chromeos::ProfileHelper::IsSigninProfile(this)) {
+    return ProxyServiceFactory::CreatePrefProxyConfigTrackerOfLocalState(
+        g_browser_process->local_state());
+  }
+#endif  // defined(OS_CHROMEOS)
+  return ProxyServiceFactory::CreatePrefProxyConfigTrackerOfProfile(
+      GetPrefs(), g_browser_process->local_state());
+}
+
diff --git a/chrome/browser/profiles/off_the_record_profile_impl.h b/chrome/browser/profiles/off_the_record_profile_impl.h
index 6559269c..c43ad0ab 100644
--- a/chrome/browser/profiles/off_the_record_profile_impl.h
+++ b/chrome/browser/profiles/off_the_record_profile_impl.h
@@ -117,6 +117,7 @@
 #endif  // defined(OS_ANDROID) || defined(OS_IOS)
 
   void OnZoomLevelChanged(const content::HostZoomMap::ZoomLevelChange& change);
+  PrefProxyConfigTracker* CreateProxyConfigTracker();
 
   // The real underlying profile.
   Profile* profile_;
diff --git a/chrome/browser/profiles/profile_impl.cc b/chrome/browser/profiles/profile_impl.cc
index d363656a..b4ef81e 100644
--- a/chrome/browser/profiles/profile_impl.cc
+++ b/chrome/browser/profiles/profile_impl.cc
@@ -1070,10 +1070,8 @@
 #endif  // defined(OS_CHROMEOS)
 
 PrefProxyConfigTracker* ProfileImpl::GetProxyConfigTracker() {
-  if (!pref_proxy_config_tracker_) {
-    pref_proxy_config_tracker_.reset(
-        ProxyServiceFactory::CreatePrefProxyConfigTracker(GetPrefs()));
-  }
+  if (!pref_proxy_config_tracker_)
+    pref_proxy_config_tracker_.reset(CreateProxyConfigTracker());
   return pref_proxy_config_tracker_.get();
 }
 
@@ -1162,3 +1160,15 @@
   *max_size = is_media_context ? prefs_->GetInteger(prefs::kMediaCacheSize) :
                                  prefs_->GetInteger(prefs::kDiskCacheSize);
 }
+
+PrefProxyConfigTracker* ProfileImpl::CreateProxyConfigTracker() {
+#if defined(OS_CHROMEOS)
+  if (chromeos::ProfileHelper::IsSigninProfile(this)) {
+    return ProxyServiceFactory::CreatePrefProxyConfigTrackerOfLocalState(
+        g_browser_process->local_state());
+  }
+#endif  // defined(OS_CHROMEOS)
+  return ProxyServiceFactory::CreatePrefProxyConfigTrackerOfProfile(
+      GetPrefs(), g_browser_process->local_state());
+}
+
diff --git a/chrome/browser/profiles/profile_impl.h b/chrome/browser/profiles/profile_impl.h
index d2c7396..4fb1a51 100644
--- a/chrome/browser/profiles/profile_impl.h
+++ b/chrome/browser/profiles/profile_impl.h
@@ -190,6 +190,8 @@
                           base::FilePath* cache_path,
                           int* max_size);
 
+  PrefProxyConfigTracker* CreateProxyConfigTracker();
+
   content::HostZoomMap::ZoomLevelChangedCallback zoom_callback_;
   PrefChangeRegistrar pref_change_registrar_;
 
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 27bf949..e9464098 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
@@ -14,6 +14,7 @@
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/login/user_manager.h"
+#include "chrome/browser/chromeos/profiles/profile_helper.h"
 #include "chrome/browser/chromeos/proxy_cros_settings_parser.h"
 #include "chrome/browser/chromeos/settings/cros_settings.h"
 #include "chrome/browser/policy/browser_policy_connector.h"
@@ -108,13 +109,15 @@
 
   CoreOptionsHandler::InitializeHandler();
 
-  PrefService* prefs = Profile::FromWebUI(web_ui())->GetPrefs();
+  Profile* profile = Profile::FromWebUI(web_ui());
+  PrefService* prefs = profile->GetPrefs();
   proxy_prefs_.Init(prefs);
   proxy_prefs_.Add(prefs::kProxy,
                    base::Bind(&CoreChromeOSOptionsHandler::OnPreferenceChanged,
                               base::Unretained(this),
                               prefs));
-  proxy_config_service_.SetPrefs(prefs);
+  proxy_config_service_.SetPrefs(ProfileHelper::IsSigninProfile(profile),
+                                 prefs);
 }
 
 base::Value* CoreChromeOSOptionsHandler::FetchPref(