| // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef CHROME_BROWSER_CHROMEOS_PROXY_CONFIG_SERVICE_IMPL_H_ |
| #define CHROME_BROWSER_CHROMEOS_PROXY_CONFIG_SERVICE_IMPL_H_ |
| #pragma once |
| |
| #include <string> |
| #include <vector> |
| |
| #include "base/basictypes.h" |
| #include "base/memory/ref_counted.h" |
| #include "base/memory/scoped_ptr.h" |
| #include "base/observer_list.h" |
| #include "base/values.h" |
| #include "chrome/browser/chromeos/login/signed_settings.h" |
| #include "net/proxy/proxy_config.h" |
| #include "net/proxy/proxy_config_service.h" |
| #include "net/proxy/proxy_server.h" |
| |
| namespace chromeos { |
| |
| // Implementation of proxy config service for chromeos that: |
| // - is RefCountedThreadSafe |
| // - is wrapped by chromeos::ProxyConfigService which implements |
| // net::ProxyConfigService interface by fowarding the methods to this class |
| // - retrieves initial system proxy configuration from cros settings persisted |
| // on chromeos device |
| // - provides network stack with latest system proxy configuration for use on |
| // IO thread |
| // - provides UI with methods to retrieve and modify system proxy configuration |
| // on UI thread |
| // - TODO(kuan): persists proxy configuration settings on chromeos device using |
| // cros settings |
| class ProxyConfigServiceImpl |
| : public base::RefCountedThreadSafe<ProxyConfigServiceImpl>, |
| public SignedSettings::Delegate<bool>, |
| public SignedSettings::Delegate<std::string> { |
| public: |
| // ProxyConfigServiceImpl is created on the UI thread in |
| // chrome/browser/net/proxy_service_factory.cc::CreateProxyConfigService |
| // via BrowserProcess::chromeos_proxy_config_service_impl, and stored in |
| // g_browser_process as a scoped_refptr (because it's RefCountedThreadSafe). |
| // |
| // Past that point, it can be accessed from the IO or UI threads. |
| // |
| // From the IO thread, it is accessed periodically through the wrapper class |
| // chromeos::ProxyConfigService via net::ProxyConfigService interface |
| // (GetLatestProxyConfig, AddObserver, RemoveObserver). |
| // |
| // From the UI thread, it is accessed via |
| // BrowserProcess::chromeos_proxy_config_service_impl to allow user to read |
| // or modify the proxy configuration via UIGetProxyConfig or |
| // UISetProxyConfigTo* respectively. |
| // The new modified proxy config is posted to the IO thread through |
| // SetNewProxyConfig(). We then notify observers on the IO thread of the |
| // configuration change. |
| |
| // In contrary to other platforms which simply use the systems' UI to allow |
| // users to configure proxies, we have to implement our own UI on the chromeos |
| // device. This requires extra and specific UI requirements that |
| // net::ProxyConfig does not suffice. So we create an augmented analog to |
| // net:ProxyConfig here to include and handle these UI requirements, e.g. |
| // - where configuration was picked up from - policy or owner |
| // - the read/write access of a proxy setting |
| // - may add more stuff later. |
| // This is then converted to the common net::ProxyConfig before being returned |
| // to ProxyService::GetLatestProxyConfig on the IO thread to be used on the |
| // network stack. |
| struct ProxyConfig { |
| // Specifies if proxy config is direct, auto-detect, using pac script, |
| // single-proxy, or proxy-per-scheme. |
| enum Mode { |
| MODE_DIRECT, |
| MODE_AUTO_DETECT, |
| MODE_PAC_SCRIPT, |
| MODE_SINGLE_PROXY, |
| MODE_PROXY_PER_SCHEME, |
| }; |
| |
| // Specifies where proxy configuration was picked up from. |
| enum Source { |
| SOURCE_NONE, // No default configuration. |
| SOURCE_POLICY, // Configuration is from policy. |
| SOURCE_OWNER, // Configuration is from owner. |
| }; |
| |
| struct Setting { |
| Setting() : source(SOURCE_NONE) {} |
| bool CanBeWrittenByUser(bool user_is_owner); |
| |
| Source source; |
| }; |
| |
| // Proxy setting for mode = direct or auto-detect or using pac script. |
| struct AutomaticProxy : public Setting { |
| GURL pac_url; // Set if proxy is using pac script. |
| }; |
| |
| // Proxy setting for mode = single-proxy or proxy-per-scheme. |
| struct ManualProxy : public Setting { |
| net::ProxyServer server; |
| }; |
| |
| ProxyConfig() : mode(MODE_DIRECT) {} |
| |
| // Converts |this| to net::ProxyConfig. |
| void ToNetProxyConfig(net::ProxyConfig* net_config); |
| |
| // Returns true if proxy config can be written by user. |
| // If mode is MODE_PROXY_PER_SCHEME, |scheme| is one of "http", "https", |
| // "ftp" or "socks"; otherwise, it should be empty or will be ignored. |
| bool CanBeWrittenByUser(bool user_is_owner, const std::string& scheme); |
| |
| // Map |scheme| (one of "http", "https", "ftp" or "socks") to the correct |
| // ManualProxy. Returns NULL if scheme is invalid. |
| ManualProxy* MapSchemeToProxy(const std::string& scheme); |
| |
| // Serializes config into a DictionaryValue and then into std::string |
| // persisted as property on device. |
| bool Serialize(std::string* output); |
| // Deserializes from property value on device as std::string into a |
| // DictionaryValue and then into the config. Opposite of Serialize. |
| bool Deserialize(const std::string& input); |
| |
| // Creates a textual dump of the configuration. |
| std::string ToString() const; |
| |
| Mode mode; |
| |
| // Set if mode is MODE_DIRECT or MODE_AUTO_DETECT or MODE_PAC_SCRIPT. |
| AutomaticProxy automatic_proxy; |
| // Set if mode is MODE_SINGLE_PROXY. |
| ManualProxy single_proxy; |
| // Set if mode is MODE_PROXY_PER_SCHEME and has http proxy. |
| ManualProxy http_proxy; |
| // Set if mode is MODE_PROXY_PER_SCHEME and has https proxy. |
| ManualProxy https_proxy; |
| // Set if mode is MODE_PROXY_PER_SCHEME and has ftp proxy. |
| ManualProxy ftp_proxy; |
| // Set if mode is MODE_PROXY_PER_SCHEME and has socks proxy. |
| ManualProxy socks_proxy; |
| |
| // Exceptions for when not to use a proxy. |
| net::ProxyBypassRules bypass_rules; |
| |
| private: |
| // Encodes the proxy server as "<url-scheme>=<proxy-scheme>://<proxy>" |
| static void EncodeAndAppendProxyServer(const std::string& scheme, |
| const net::ProxyServer& server, |
| std::string* spec); |
| }; |
| |
| // Usual constructor. |
| ProxyConfigServiceImpl(); |
| // Constructor for testing. |
| // |init_config| specifies the ProxyConfig to use for initialization. |
| explicit ProxyConfigServiceImpl(const ProxyConfig& init_config); |
| virtual ~ProxyConfigServiceImpl(); |
| |
| // Methods called on IO thread from wrapper class chromeos::ProxyConfigService |
| // as ProxyConfigService methods. |
| void AddObserver(net::ProxyConfigService::Observer* observer); |
| void RemoveObserver(net::ProxyConfigService::Observer* observer); |
| // Called from GetLatestProxyConfig. |
| net::ProxyConfigService::ConfigAvailability IOGetProxyConfig( |
| net::ProxyConfig* config); |
| |
| // Called from UI thread to retrieve proxy configuration in |config|. |
| void UIGetProxyConfig(ProxyConfig* config); |
| |
| // Called from UI thread to set flag to persist settings to device. |
| // Subsequent UISet* methods will use this flag, until UI calls it again with |
| // a different flag. |
| void UISetPersistToDevice(bool persist) { |
| persist_to_device_ = persist; |
| } |
| |
| // Called from UI thread to update proxy configuration for different modes. |
| // Returns true if config is set properly and config service has proceeded to |
| // start activating it on network stack and persisting it to device. |
| // Returns false if config is not set properly, probably because information |
| // is incomplete or invalid; while config service won't proceed to activate or |
| // persist this config, the information is "cached" in the service, so that |
| // the next UIGetProxyConfig call will return this latest information. |
| bool UISetProxyConfigToDirect(); |
| bool UISetProxyConfigToAutoDetect(); |
| bool UISetProxyConfigToPACScript(const GURL& pac_url); |
| bool UISetProxyConfigToSingleProxy(const net::ProxyServer& server); |
| // |scheme| is one of "http", "https", "ftp" or "socks". |
| bool UISetProxyConfigToProxyPerScheme(const std::string& scheme, |
| const net::ProxyServer& server); |
| // Only valid for MODE_SINGLE_PROXY or MODE_PROXY_PER_SCHEME. |
| bool UISetProxyConfigBypassRules(const net::ProxyBypassRules& bypass_rules); |
| |
| // Implementation for SignedSettings::Delegate |
| virtual void OnSettingsOpCompleted(SignedSettings::ReturnCode code, |
| std::string value); |
| virtual void OnSettingsOpCompleted(SignedSettings::ReturnCode code, |
| bool value); |
| |
| private: |
| friend class base::RefCountedThreadSafe<ProxyConfigServiceImpl>; |
| |
| // Persists proxy config to device. |
| void PersistConfigToDevice(); |
| |
| // Called from UI thread from the various UISetProxyConfigTo* |
| // |update_to_device| is true to persist new proxy config to device. |
| void OnUISetProxyConfig(bool update_to_device); |
| |
| // Posted from UI thread to IO thread to carry the new config information. |
| void IOSetProxyConfig( |
| const ProxyConfig& new_config, |
| net::ProxyConfigService::ConfigAvailability new_availability); |
| |
| // Checks that method is called on BrowserThread::IO thread. |
| void CheckCurrentlyOnIOThread(); |
| |
| // Checks that method is called on BrowserThread::UI thread. |
| void CheckCurrentlyOnUIThread(); |
| |
| // Data members. |
| |
| // True if tasks can be posted, which can only happen if constructor has |
| // completed (NewRunnableMethod cannot be created for a RefCountedThreadBase's |
| // method until the class's ref_count is at least one). |
| bool can_post_task_; |
| |
| // Availability status of the configuration. |
| net::ProxyConfigService::ConfigAvailability config_availability_; |
| |
| // True if settings are to be persisted to device. |
| bool persist_to_device_; |
| |
| // True if there's a pending operation to store proxy setting to device. |
| bool persist_to_device_pending_; |
| |
| // Cached proxy configuration, to be converted to net::ProxyConfig and |
| // returned by IOGetProxyConfig. |
| // Initially populated from the UI thread, but afterwards only accessed from |
| // the IO thread. |
| ProxyConfig cached_config_; |
| |
| // Copy of the proxy configuration kept on the UI thread of the last seen |
| // proxy config, so as to avoid posting a call to SetNewProxyConfig when we |
| // are called by UI to set new proxy but the config has not actually changed. |
| ProxyConfig reference_config_; |
| |
| // List of observers for changes in proxy config. |
| ObserverList<net::ProxyConfigService::Observer> observers_; |
| |
| // Operations to retrieve and store proxy setting from and to device |
| // respectively. |
| scoped_refptr<SignedSettings> retrieve_property_op_; |
| scoped_refptr<SignedSettings> store_property_op_; |
| |
| DISALLOW_COPY_AND_ASSIGN(ProxyConfigServiceImpl); |
| }; |
| |
| } // namespace chromeos |
| |
| #endif // CHROME_BROWSER_CHROMEOS_PROXY_CONFIG_SERVICE_IMPL_H_ |