Index: chrome/browser/chromeos/proxy_config_service_impl.cc |
=================================================================== |
--- chrome/browser/chromeos/proxy_config_service_impl.cc (revision 0) |
+++ chrome/browser/chromeos/proxy_config_service_impl.cc (revision 0) |
@@ -0,0 +1,305 @@ |
+// Copyright (c) 2010 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_impl.h" |
+ |
+#include <ostream> |
+ |
+#include "base/logging.h" |
+#include "base/string_util.h" |
+#include "base/task.h" |
+#include "base/values.h" |
+#include "chrome/browser/chrome_thread.h" |
+ |
+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"; |
+ } |
+ NOTREACHED() << "Unrecognized source type"; |
+ return ""; |
+} |
+ |
+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"; |
+ return out; |
+} |
+ |
+std::ostream& operator<<(std::ostream& out, |
+ 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"; |
+ break; |
+ case ProxyConfigServiceImpl::ProxyConfig::MODE_PAC_SCRIPT: |
+ out << "Custom PAC script:\n " |
+ << SourceToString(config.automatic_proxy.source) |
+ << "\n PAC: " << config.automatic_proxy.pac_url << "\n"; |
+ break; |
+ case ProxyConfigServiceImpl::ProxyConfig::MODE_SINGLE_PROXY: |
+ out << "Single proxy:\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; |
+ break; |
+ default: |
+ NOTREACHED() << "Unrecognized proxy config mode"; |
+ break; |
+ } |
+ if (config.mode == ProxyConfigServiceImpl::ProxyConfig::MODE_SINGLE_PROXY || |
+ config.mode == |
+ ProxyConfigServiceImpl::ProxyConfig::MODE_PROXY_PER_SCHEME) { |
+ out << "Bypass list: "; |
+ if (config.bypass_rules.rules().empty()) { |
+ out << "[None]"; |
+ } else { |
+ const net::ProxyBypassRules& bypass_rules = config.bypass_rules; |
+ net::ProxyBypassRules::RuleList::const_iterator it; |
+ for (it = bypass_rules.rules().begin(); |
+ it != bypass_rules.rules().end(); ++it) { |
+ out << "\n " << (*it)->ToString(); |
+ } |
+ } |
+ } |
+ return out; |
+} |
+ |
+std::string ProxyConfigToString( |
+ const ProxyConfigServiceImpl::ProxyConfig& proxy_config) { |
+ std::ostringstream stream; |
+ stream << proxy_config; |
+ return stream.str(); |
+} |
+ |
+} // namespace |
+ |
+//-------------- ProxyConfigServiceImpl::ProxyConfig 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; |
+} |
+ |
+void ProxyConfigServiceImpl::ProxyConfig::ConvertToNetProxyConfig( |
+ 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().socks_proxy = socks_proxy.server; |
+ net_config->proxy_rules().bypass_rules = bypass_rules; |
+ break; |
+ default: |
+ NOTREACHED() << "Unrecognized proxy config mode"; |
+ break; |
+ } |
+} |
+ |
+std::string ProxyConfigServiceImpl::ProxyConfig::ToString() const { |
+ return ProxyConfigToString(*this); |
+} |
+ |
+//------------------- ProxyConfigServiceImpl: public methods ------------------- |
+ |
+ProxyConfigServiceImpl::ProxyConfigServiceImpl() { |
+ // Fetch and cache proxy config from cros settings persisted on device. |
+ // TODO(kuan): retrieve config from policy and owner and merge them |
+ // for now, hardcode it as AUTO_DETECT and it'll pick up the PAC script set in |
+ // chromeos environment. |
+ cached_config_.mode = ProxyConfig::MODE_AUTO_DETECT; |
+ cached_config_.automatic_proxy.source = ProxyConfig::SOURCE_OWNER; |
+ |
+ // Update the thread-private copy in |reference_config_| as well. |
+ reference_config_ = cached_config_; |
+} |
+ |
+ProxyConfigServiceImpl::ProxyConfigServiceImpl(const ProxyConfig& init_config) { |
+ cached_config_ = init_config; |
+ // Update the thread-private copy in |reference_config_| as well. |
+ reference_config_ = cached_config_; |
+} |
+ |
+ProxyConfigServiceImpl::~ProxyConfigServiceImpl() { |
+} |
+ |
+void ProxyConfigServiceImpl::UIGetProxyConfig(ProxyConfig* config) { |
+ // Should be called from UI thread. |
+ CheckCurrentlyOnUIThread(); |
+ // Simply returns the copy on the UI thread. |
+ *config = reference_config_; |
+} |
+ |
+void ProxyConfigServiceImpl::UISetProxyConfigToDirect() { |
+ // Should be called from UI thread. |
+ CheckCurrentlyOnUIThread(); |
+ reference_config_.mode = ProxyConfig::MODE_DIRECT; |
+ OnUISetProxyConfig(); |
+} |
+ |
+void ProxyConfigServiceImpl::UISetProxyConfigToAutoDetect() { |
+ // Should be called from UI thread. |
+ CheckCurrentlyOnUIThread(); |
+ reference_config_.mode = ProxyConfig::MODE_AUTO_DETECT; |
+ OnUISetProxyConfig(); |
+} |
+ |
+void ProxyConfigServiceImpl::UISetProxyConfigToPACScript(const GURL& url) { |
+ // Should be called from UI thread. |
+ CheckCurrentlyOnUIThread(); |
+ reference_config_.mode = ProxyConfig::MODE_PAC_SCRIPT; |
+ reference_config_.automatic_proxy.pac_url = url; |
+ OnUISetProxyConfig(); |
+} |
+ |
+void ProxyConfigServiceImpl::UISetProxyConfigToSingleProxy( |
+ const net::ProxyServer& server) { |
+ // Should be called from UI thread. |
+ CheckCurrentlyOnUIThread(); |
+ reference_config_.mode = ProxyConfig::MODE_SINGLE_PROXY; |
+ reference_config_.single_proxy.server = server; |
+ OnUISetProxyConfig(); |
+} |
+ |
+void ProxyConfigServiceImpl::UISetProxyConfigToProxyPerScheme( |
+ const std::string& scheme, const net::ProxyServer& server) { |
+ // Should be called from UI thread. |
+ CheckCurrentlyOnUIThread(); |
+ ProxyConfig::ManualProxy* proxy = NULL; |
+ if (scheme == "http") |
+ proxy = &reference_config_.http_proxy; |
+ else if (scheme == "https") |
+ proxy = &reference_config_.https_proxy; |
+ else if (scheme == "ftp") |
+ proxy = &reference_config_.ftp_proxy; |
+ else if (scheme == "socks") |
+ proxy = &reference_config_.socks_proxy; |
+ else |
+ NOTREACHED() << "Unrecognized scheme for setting proxy config"; |
+ if (proxy) { |
+ reference_config_.mode = ProxyConfig::MODE_PROXY_PER_SCHEME; |
+ proxy->server = server; |
+ OnUISetProxyConfig(); |
+ } |
+} |
+ |
+void ProxyConfigServiceImpl::UISetProxyConfigBypassRules( |
+ const net::ProxyBypassRules& bypass_rules) { |
+ // Should be called from UI thread. |
+ CheckCurrentlyOnUIThread(); |
+ DCHECK(reference_config_.mode == ProxyConfig::MODE_SINGLE_PROXY || |
+ reference_config_.mode == ProxyConfig::MODE_PROXY_PER_SCHEME); |
+ if (reference_config_.mode == ProxyConfig::MODE_SINGLE_PROXY || |
+ reference_config_.mode == ProxyConfig::MODE_PROXY_PER_SCHEME) { |
+ reference_config_.bypass_rules = bypass_rules; |
+ OnUISetProxyConfig(); |
+ } |
+} |
+ |
+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); |
+} |
+ |
+bool ProxyConfigServiceImpl::IOGetProxyConfig(net::ProxyConfig* net_config) { |
+ // Should be called from IO thread. |
+ CheckCurrentlyOnIOThread(); |
+ |
+ // Simply return the last cached proxy configuration. |
+ cached_config_.ConvertToNetProxyConfig(net_config); |
+ |
+ // We return true to indicate that *config was filled in. It is always |
+ // going to be available since we initialized eagerly on the UI thread. |
+ // TODO(kuan): do lazy initialization instead, so we no longer need |
+ // to construct ProxyConfigServiceImpl on the UI thread. |
+ // In which case, we may return false here. |
+ return true; |
+} |
+ |
+//------------------ ProxyConfigServiceImpl: private methods ------------------- |
+ |
+void ProxyConfigServiceImpl::OnUISetProxyConfig() { |
+ // Posts a task to IO thread with the new config, so it can update |
+ // |cached_config_|. |
+ Task* task = NewRunnableMethod(this, |
+ &ProxyConfigServiceImpl::IOSetProxyConfig, reference_config_); |
+ if (!ChromeThread::PostTask(ChromeThread::IO, FROM_HERE, task)) { |
+ LOG(INFO) << "Couldn't post task to IO thread to set new proxy config"; |
+ delete task; |
+ } |
+ |
+ // TODO(kuan): write new config out to cros settings for persistence. |
+} |
+ |
+void ProxyConfigServiceImpl::CheckCurrentlyOnIOThread() { |
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); |
+} |
+ |
+void ProxyConfigServiceImpl::CheckCurrentlyOnUIThread() { |
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); |
+} |
+ |
+void ProxyConfigServiceImpl::IOSetProxyConfig(const ProxyConfig& new_config) { |
+ // This is called on the IO thread (posted from UI thread). |
+ CheckCurrentlyOnIOThread(); |
+ LOG(INFO) << "Proxy configuration changed"; |
+ cached_config_ = new_config; |
+ // Notify observers of new proxy config. |
+ net::ProxyConfig net_config; |
+ cached_config_.ConvertToNetProxyConfig(&net_config); |
+ FOR_EACH_OBSERVER(net::ProxyConfigService::Observer, observers_, |
+ OnProxyConfigChanged(net_config)); |
+} |
+ |
+} // namespace chromeos |
Property changes on: chrome\browser\chromeos\proxy_config_service_impl.cc |
___________________________________________________________________ |
Added: svn:eol-style |
+ LF |