proxy_config_service_impl.h revision c2e0dbddbe15c98d52c4786dac06cb8952a8ae6d
1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#ifndef CHROME_BROWSER_CHROMEOS_PROXY_CONFIG_SERVICE_IMPL_H_ 6#define CHROME_BROWSER_CHROMEOS_PROXY_CONFIG_SERVICE_IMPL_H_ 7 8#include <string> 9#include <vector> 10 11#include "base/basictypes.h" 12#include "base/prefs/pref_member.h" 13#include "base/values.h" 14#include "chrome/browser/chromeos/cros/network_library.h" 15#include "chrome/browser/net/pref_proxy_config_tracker_impl.h" 16 17class PrefRegistrySimple; 18 19namespace user_prefs { 20class PrefRegistrySyncable; 21} 22 23namespace chromeos { 24 25// Implementation of proxy config service for chromeos that: 26// - extends PrefProxyConfigTrackerImpl (and so lives and runs entirely on UI 27// thread) to handle proxy from prefs (via PrefProxyConfigTrackerImpl) and 28// system i.e. network (via shill notifications) 29// - exists one per profile and one per local state 30// - retrieves initial system proxy configuration from cros settings persisted 31// on chromeos device from chromeos revisions before migration to shill, 32// - persists proxy setting per network in flimflim 33// - provides network stack with latest effective proxy configuration for 34// currently active network via PrefProxyConfigTrackerImpl's mechanism of 35// pushing config to ChromeProxyConfigService 36// - provides UI with methods to retrieve and modify proxy configuration for 37// any remembered network (either currently active or non-active) of current 38// user profile 39class ProxyConfigServiceImpl : public PrefProxyConfigTrackerImpl, 40 public NetworkLibrary::NetworkManagerObserver, 41 public NetworkLibrary::NetworkObserver { 42 public: 43 // ProxyConfigServiceImpl is created in ProxyServiceFactory:: 44 // CreatePrefProxyConfigTrackerImpl via Profile::GetProxyConfigTracker() for 45 // profile or IOThread constructor for local state and is owned by the 46 // respective classes. 47 // 48 // From the UI, it is accessed via Profile::GetProxyConfigTracker to allow 49 // user to read or modify the proxy configuration via UIGetProxyConfig or 50 // UISetProxyConfigTo* respectively. 51 // The new modified proxy config, together with proxy from prefs if available, 52 // are used to determine the effective proxy config, which is then pushed 53 // through PrefProxyConfigTrackerImpl to ChromeProxyConfigService to the 54 // network stack. 55 // 56 // In contrary to other platforms which simply use the systems' UI to allow 57 // users to configure proxies, we have to implement our own UI on the chromeos 58 // device. This requires extra and specific UI requirements that 59 // net::ProxyConfig does not suffice. So we create an augmented analog to 60 // net:ProxyConfig here to include and handle these UI requirements, e.g. 61 // - state of configuration e.g. where it was picked up from - policy, 62 // extension, etc (refer to ProxyPrefs::ConfigState) 63 // - the read/write access of a proxy setting 64 // - may add more stuff later. 65 // This is then converted to the common net::ProxyConfig before being pushed 66 // to PrefProxyConfigTrackerImpl::OnProxyConfigChanged and then to the network 67 // stack. 68 struct ProxyConfig { 69 // Specifies if proxy config is direct, auto-detect, using pac script, 70 // single-proxy, or proxy-per-scheme. 71 enum Mode { 72 MODE_DIRECT, 73 MODE_AUTO_DETECT, 74 MODE_PAC_SCRIPT, 75 MODE_SINGLE_PROXY, 76 MODE_PROXY_PER_SCHEME, 77 }; 78 79 // Proxy setting for mode = direct or auto-detect or using pac script. 80 struct AutomaticProxy { 81 GURL pac_url; // Set if proxy is using pac script. 82 }; 83 84 // Proxy setting for mode = single-proxy or proxy-per-scheme. 85 struct ManualProxy { 86 net::ProxyServer server; 87 }; 88 89 ProxyConfig(); 90 ~ProxyConfig(); 91 92 // Converts net::ProxyConfig to |this|. 93 bool FromNetProxyConfig(const net::ProxyConfig& net_config); 94 95 // Converts |this| to Dictionary of ProxyConfigDictionary format (which 96 // is the same format used by prefs). 97 DictionaryValue* ToPrefProxyConfig(); 98 99 // Map |scheme| (one of "http", "https", "ftp" or "socks") to the correct 100 // ManualProxy. Returns NULL if scheme is invalid. 101 ManualProxy* MapSchemeToProxy(const std::string& scheme); 102 103 // We've migrated device settings to shill, so we only need to 104 // deserialize previously persisted device settings. 105 // Deserializes from signed setting on device as std::string into a 106 // protobuf and then into the config. 107 bool DeserializeForDevice(const std::string& input); 108 109 // Serializes config into a ProxyConfigDictionary and then std::string 110 // persisted as string property in shill for a network. 111 bool SerializeForNetwork(std::string* output); 112 113 // Encodes the proxy server as "<url-scheme>=<proxy-scheme>://<proxy>" 114 static void EncodeAndAppendProxyServer(const std::string& url_scheme, 115 const net::ProxyServer& server, 116 std::string* spec); 117 118 Mode mode; 119 120 ProxyPrefs::ConfigState state; 121 122 // True if user can modify proxy settings via UI. 123 // If proxy is managed by policy or extension or other_precde or is for 124 // shared network but kUseSharedProxies is turned off, it can't be modified 125 // by user. 126 bool user_modifiable; 127 128 // Set if mode is MODE_DIRECT or MODE_AUTO_DETECT or MODE_PAC_SCRIPT. 129 AutomaticProxy automatic_proxy; 130 // Set if mode is MODE_SINGLE_PROXY. 131 ManualProxy single_proxy; 132 // Set if mode is MODE_PROXY_PER_SCHEME and has http proxy. 133 ManualProxy http_proxy; 134 // Set if mode is MODE_PROXY_PER_SCHEME and has https proxy. 135 ManualProxy https_proxy; 136 // Set if mode is MODE_PROXY_PER_SCHEME and has ftp proxy. 137 ManualProxy ftp_proxy; 138 // Set if mode is MODE_PROXY_PER_SCHEME and has socks proxy. 139 ManualProxy socks_proxy; 140 141 // Exceptions for when not to use a proxy. 142 net::ProxyBypassRules bypass_rules; 143 }; 144 145 // Constructor. 146 explicit ProxyConfigServiceImpl(PrefService* pref_service); 147 virtual ~ProxyConfigServiceImpl(); 148 149 // Called by UI to set service path of |network| to be displayed or edited. 150 // Subsequent UISet* methods will use this network, until UI calls it again 151 // with a different network. 152 void UISetCurrentNetwork(const std::string& current_network); 153 154 // Called from UI to make the currently active network the one to be displayed 155 // or edited. Subsequent UISet* methods will use this network until UI calls 156 // it again when the active network has changed. 157 void UIMakeActiveNetworkCurrent(); 158 159 // Called from UI to get name of the current network set via 160 // UISetCurrentNetwork or UIMakeActiveNetworkCurrent. 161 void UIGetCurrentNetworkName(std::string* network_name); 162 163 // Called from UI to retrieve proxy configuration in |current_ui_config_|. 164 void UIGetProxyConfig(ProxyConfig* config); 165 166 // Called from UI to update proxy configuration for different modes. 167 // Returns true if config is set properly and persisted to shill for the 168 // current network (set via UISetCurrentNetwork/UIMakeActiveNetworkCurrent). 169 // If this network is also currently active, config service proceeds to start 170 // activating it on network stack. 171 // Returns false if config is not set properly, probably because information 172 // is incomplete or invalid; while config service won't proceed to activate or 173 // persist this config, the information is "cached" in the service, so that 174 // the next UIGetProxyConfig call will return this latest information. 175 bool UISetProxyConfigToDirect(); 176 bool UISetProxyConfigToAutoDetect(); 177 bool UISetProxyConfigToPACScript(const GURL& pac_url); 178 bool UISetProxyConfigToSingleProxy(const net::ProxyServer& server); 179 // |scheme| is one of "http", "https", "ftp" or "socks". 180 bool UISetProxyConfigToProxyPerScheme(const std::string& scheme, 181 const net::ProxyServer& server); 182 // Only valid for MODE_SINGLE_PROXY or MODE_PROXY_PER_SCHEME. 183 bool UISetProxyConfigBypassRules(const net::ProxyBypassRules& bypass_rules); 184 185 // Add/Remove callback functions for notification when network to be viewed is 186 // changed by the UI. 187 void AddNotificationCallback(base::Closure callback); 188 void RemoveNotificationCallback(base::Closure callback); 189 190 // PrefProxyConfigTrackerImpl implementation. 191 virtual void OnProxyConfigChanged(ProxyPrefs::ConfigState config_state, 192 const net::ProxyConfig& config) OVERRIDE; 193 194 // NetworkLibrary::NetworkManagerObserver implementation. 195 virtual void OnNetworkManagerChanged(NetworkLibrary* cros) OVERRIDE; 196 197 // NetworkLibrary::NetworkObserver implementation. 198 virtual void OnNetworkChanged(NetworkLibrary* cros, 199 const Network* network) OVERRIDE; 200 201 // Parse |network| proxy config and store result in |proxy_config|. 202 // Returns true if proxy config was successfully parsed. 203 static bool ParseProxyConfig(const Network* network, 204 net::ProxyConfig* proxy_config); 205 206 // Register UseShardProxies preference. 207 static void RegisterPrefs(PrefRegistrySimple* registry); 208 static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry); 209 210#if defined(UNIT_TEST) 211 void SetTesting(ProxyConfig* test_config) { 212 UIMakeActiveNetworkCurrent(); 213 if (test_config) { 214 std::string value; 215 test_config->SerializeForNetwork(&value); 216 SetProxyConfigForNetwork(active_network_, value, false); 217 } 218 } 219#endif // defined(UNIT_TEST) 220 221 private: 222 // Called when the kUseSharedProxies preference changes. 223 void OnUseSharedProxiesChanged(); 224 225 // Called from the various UISetProxyConfigTo*. 226 void OnUISetProxyConfig(); 227 228 // Called from OnNetworkManagerChanged and OnNetworkChanged for currently 229 // active network, to handle previously active network, new active network, 230 // and if necessary, migrates device settings to shill and/or activates 231 // proxy setting of new network. 232 void OnActiveNetworkChanged(NetworkLibrary* cros, 233 const Network* active_network); 234 235 // Sets proxy config for |network_path| into shill and activates setting 236 // if the network is currently active. If |only_set_if_empty| is true, 237 // proxy will be set and saved only if network has no proxy. 238 void SetProxyConfigForNetwork(const std::string& network_path, 239 const std::string& value, 240 bool only_set_if_empty); 241 242 // Returns value of UseSharedProxies preference if it's not default, else 243 // returns false if user is logged in and true otherwise. 244 bool GetUseSharedProxies(); 245 246 // Returns true if proxy is to be ignored for network, which happens if 247 // network is shared and use-shared-proxies is turned off. 248 bool IgnoreProxy(const Network* network); 249 250 // Determines effective proxy config based on prefs from config tracker, 251 // |network| and if user is using shared proxies. 252 // If |activate| is true, effective config is stored in |active_config_| and 253 // activated on network stack, and hence, picked up by observers. 254 // if |activate| is false, effective config is stored in |current_ui_config_| 255 // but not activated on network stack, and hence, not picked up by observers. 256 void DetermineEffectiveConfig(const Network* network, bool activate); 257 258 // Determines |current_ui_config_| based on |network|, called from 259 // UISetCurrentNetwork and UIMakeActiveNetworkActive. 260 void OnUISetCurrentNetwork(const Network* network); 261 262 // Reset UI cache variables that keep track of UI activities. 263 void ResetUICache(); 264 265 void FetchProxyPolicy(); 266 267 // Data members. 268 269 // Service path of currently active network (determined via shill 270 // notifications); if effective proxy config is from system, proxy of this 271 // network will be the one taking effect. 272 std::string active_network_; 273 274 // State of |active_config_|. |active_config_| is only valid if 275 // |active_config_state_| is not ProxyPrefs::CONFIG_UNSET. 276 ProxyPrefs::ConfigState active_config_state_; 277 278 // Active proxy configuration, which could be from prefs or network. 279 net::ProxyConfig active_config_; 280 281 // Proxy config retreived from device, in format generated from 282 // SerializeForNetwork, that can be directly set into shill. 283 std::string device_config_; 284 285 // Service path of network whose proxy configuration is being displayed or 286 // edited via UI, separate from |active_network_| which may be same or 287 // different. 288 std::string current_ui_network_; 289 290 // Proxy configuration of |current_ui_network_|. 291 ProxyConfig current_ui_config_; 292 293 // Track changes in UseSharedProxies user preference. 294 BooleanPrefMember use_shared_proxies_; 295 296 // Callbacks for notification when network to be viewed has been changed from 297 // the UI. 298 std::vector<base::Closure> callbacks_; 299 300 base::WeakPtrFactory<ProxyConfigServiceImpl> pointer_factory_; 301 302 DISALLOW_COPY_AND_ASSIGN(ProxyConfigServiceImpl); 303}; 304 305} // namespace chromeos 306 307#endif // CHROME_BROWSER_CHROMEOS_PROXY_CONFIG_SERVICE_IMPL_H_ 308