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

Unified Diff: chrome/browser/chromeos/proxy_config_service_impl.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/chromeos/proxy_config_service_impl.cc
===================================================================
--- chrome/browser/chromeos/proxy_config_service_impl.cc (revision 107101)
+++ chrome/browser/chromeos/proxy_config_service_impl.cc (working copy)
@@ -6,16 +6,23 @@
#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 "chrome/browser/profiles/profile_manager.h"
+#include "chrome/common/chrome_notification_types.h"
+#include "chrome/common/pref_names.h"
#include "content/browser/browser_thread.h"
+#include "content/public/browser/notification_details.h"
+#include "content/public/browser/notification_source.h"
#include "grit/generated_resources.h"
#include "ui/base/l10n/l10n_util.h"
@@ -25,51 +32,75 @@
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";
@@ -99,85 +130,102 @@
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*
@@ -261,47 +309,6 @@
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
@@ -322,156 +329,33 @@
*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;
- }
-
- 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;
- }
-
- 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;
-}
-
//------------------- ProxyConfigServiceImpl: public methods -------------------
-ProxyConfigServiceImpl::ProxyConfigServiceImpl()
- : testing_(false),
- can_post_task_(false),
- config_availability_(net::ProxyConfigService::CONFIG_UNSET),
- use_shared_proxies_(true) {
+ProxyConfigServiceImpl::ProxyConfigServiceImpl(PrefService* pref_service)
+ : PrefProxyConfigTracker(pref_service),
+ active_config_state_(ProxyPrefs::CONFIG_UNSET) {
+ // Register for notifications of UseSharedProxies user preference.
+ if (pref_service->FindPreference(prefs::kUseSharedProxies))
+ use_shared_proxies_.Init(prefs::kUseSharedProxies, pref_service, this);
+
// 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() {
NetworkLibrary* netlib = CrosLibrary::Get()->GetNetworkLibrary();
if (netlib) {
@@ -480,108 +364,69 @@
}
}
-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_;
+void ProxyConfigServiceImpl::UIGetCurrentNetworkName(
+ std::string* network_name) {
+ if (!network_name)
return;
- }
- use_shared_proxies_ = use_shared;
- VLOG(1) << "new use_shared_proxies = " << use_shared_proxies_;
- if (active_network_.empty())
- 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();
@@ -590,8 +435,6 @@
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();
@@ -600,8 +443,6 @@
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 << "]";
@@ -615,8 +456,6 @@
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();
@@ -629,29 +468,19 @@
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(
@@ -663,7 +492,8 @@
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_)) {
@@ -672,15 +502,15 @@
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());
}
@@ -688,70 +518,64 @@
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.
+ // ProxyConfigServiceImpl constructor will set 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::Source<PrefService>(source).ptr() == prefs() &&
+ *(content::Details<std::string>(details).ptr()) ==
+ prefs::kUseSharedProxies) {
+ 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;
}
+ PrefProxyConfigTracker::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;
@@ -759,10 +583,13 @@
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;
}
@@ -773,26 +600,27 @@
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);
}
}
@@ -807,52 +635,128 @@
}
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 =
+bool ProxyConfigServiceImpl::GetUseSharedProxies() {
+ bool default_use_shared_proxies = !UserManager::Get()->user_is_logged_in();
+ const PrefService::Preference* use_shared_proxies_pref =
+ prefs()->FindPreference(prefs::kUseSharedProxies);
+ if (!use_shared_proxies_pref)
+ return default_use_shared_proxies;
+ if (use_shared_proxies_pref->IsDefaultValue() &&
+ use_shared_proxies_.GetValue() != default_use_shared_proxies)
+ return default_use_shared_proxies;
+ return use_shared_proxies_.GetValue();
Mattias Nissler (ping if slow) 2011/10/25 17:27:24 You can write this whole function more compact as
kuan 2011/11/03 20:20:14 Done.
+}
+
+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;
- // 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;
+ 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;
+ }
+ }
+ }
}
- IOSetProxyConfig(active_config_, available);
-}
-void ProxyConfigServiceImpl::SetCurrentNetworkName(const Network* network) {
- if (!network) {
- if (testing_)
- current_ui_network_name_ = "test";
- return;
+ // 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 PrefProxyConfigTracker 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();
+ PrefProxyConfigTracker::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);
}
- 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();
- }
}
-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
« no previous file with comments | « chrome/browser/chromeos/proxy_config_service_impl.h ('k') | chrome/browser/chromeos/proxy_config_service_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698