Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1842)

Unified Diff: chrome/browser/net/pref_proxy_config_tracker.cc

Issue 8102019: redesign and reimplement proxy config service and tracker, revise proxy ui on cros (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/net/pref_proxy_config_tracker.cc
===================================================================
--- chrome/browser/net/pref_proxy_config_tracker.cc (revision 104725)
+++ chrome/browser/net/pref_proxy_config_tracker.cc (working copy)
@@ -2,8 +2,9 @@
// 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.h"
+#include "base/bind.h"
#include "base/values.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/prefs/pref_set_observer.h"
@@ -14,8 +15,113 @@
#include "content/common/notification_details.h"
#include "content/common/notification_source.h"
-PrefProxyConfigTracker::PrefProxyConfigTracker(PrefService* pref_service)
- : pref_service_(pref_service) {
+//============================= 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 PrefProxyConfigTracker::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));
+ VLOG(1) << "got UpdateProxyConfig";
+
+ 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 (!PrefProxyConfigTracker::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;
+ }
+}
+
+//=========================== PrefProxyConfigTracker ===========================
+
+PrefProxyConfigTracker::PrefProxyConfigTracker(
+ 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));
@@ -25,12 +131,13 @@
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::SetChromeProxyConfigService(
+ ChromeProxyConfigService* chrome_proxy_config_service) {
+ VLOG(1) << "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 PrefProxyConfigTracker::DetachFromPrefService() {
@@ -38,72 +145,79 @@
// Stop notifications.
proxy_prefs_observer_.reset();
pref_service_ = NULL;
+ SetChromeProxyConfigService(NULL);
}
-void PrefProxyConfigTracker::AddObserver(
- PrefProxyConfigTracker::Observer* observer) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- observers_.AddObserver(observer);
+// static
+bool PrefProxyConfigTracker::PrefPrecedes(
+ ProxyPrefs::ConfigState config_state) {
+ return config_state == ProxyPrefs::CONFIG_POLICY ||
+ config_state == ProxyPrefs::CONFIG_EXTENSION ||
+ config_state == ProxyPrefs::CONFIG_OTHER_PRECEDE;
}
-void PrefProxyConfigTracker::RemoveObserver(
- PrefProxyConfigTracker::Observer* observer) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- observers_.RemoveObserver(observer);
-}
+// static
+net::ProxyConfigService::ConfigAvailability
+ PrefProxyConfigTracker::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;
-void PrefProxyConfigTracker::Observe(int type,
- const NotificationSource& source,
- const NotificationDetails& details) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- if (type == chrome::NOTIFICATION_PREF_CHANGED &&
- 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;
+ if (PrefPrecedes(pref_state)) {
+ *effective_config = pref_config;
+ return net::ProxyConfigService::CONFIG_VALID;
}
-}
-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());
+ // 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;
}
-PrefProxyConfigTracker::ConfigState
- PrefProxyConfigTracker::ReadPrefConfig(net::ProxyConfig* config) {
+// static
+void PrefProxyConfigTracker::RegisterPrefs(PrefService* pref_service) {
+ DictionaryValue* default_settings = ProxyConfigDictionary::CreateSystem();
+ pref_service->RegisterDictionaryPref(prefs::kProxy,
+ default_settings,
+ PrefService::UNSYNCABLE_PREF);
+}
+
+ProxyPrefs::ConfigState PrefProxyConfigTracker::GetProxyConfig(
+ net::ProxyConfig* config) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ if (config_state_ != ProxyPrefs::CONFIG_UNSET)
+ *config = pref_config_;
+ return config_state_;
+}
- // 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;
+void PrefProxyConfigTracker::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;
}
-
- return CONFIG_UNSET;
+ 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 PrefProxyConfigTracker::PrefConfigToNetConfig(
@@ -167,111 +281,57 @@
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 PrefProxyConfigTracker::Observe(int type,
+ const NotificationSource& source,
+ const NotificationDetails& details) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ if (type == chrome::NOTIFICATION_PREF_CHANGED &&
+ 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;
}
}
-void PrefProxyConfigService::AddObserver(
- net::ProxyConfigService::Observer* observer) {
- RegisterObservers();
- observers_.AddObserver(observer);
-}
+ProxyPrefs::ConfigState PrefProxyConfigTracker::ReadPrefConfig(
+ net::ProxyConfig* config) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-void PrefProxyConfigService::RemoveObserver(
- net::ProxyConfigService::Observer* observer) {
- observers_.RemoveObserver(observer);
-}
+ // Clear the configuration and source.
+ *config = net::ProxyConfig();
+ ProxyPrefs::ConfigState config_state = ProxyPrefs::CONFIG_UNSET;
-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;
- }
+ const PrefService::Preference* pref =
+ pref_service_->FindPreference(prefs::kProxy);
+ DCHECK(pref);
- // Ask the base service.
- ConfigAvailability available = base_service_->GetLatestProxyConfig(config);
+ const DictionaryValue* dict = pref_service_->GetDictionary(prefs::kProxy);
+ DCHECK(dict);
+ ProxyConfigDictionary proxy_dict(dict);
- // 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;
+ 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 available;
+ return config_state;
}
-
-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);
-}

Powered by Google App Engine
This is Rietveld 408576698