Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/chromeos/proxy_config_service_impl.h" | 5 #include "chrome/browser/chromeos/proxy_config_service_impl.h" |
| 6 | 6 |
| 7 #include <ostream> | 7 #include <ostream> |
| 8 | 8 |
| 9 #include "base/bind.h" | |
|
achuithb
2011/11/07 22:59:32
Kuan: I don't think you're using this?
| |
| 9 #include "base/json/json_value_serializer.h" | 10 #include "base/json/json_value_serializer.h" |
| 10 #include "base/logging.h" | 11 #include "base/logging.h" |
| 11 #include "base/string_util.h" | 12 #include "base/string_util.h" |
| 12 #include "base/task.h" | |
| 13 #include "chrome/browser/chromeos/cros/cros_library.h" | 13 #include "chrome/browser/chromeos/cros/cros_library.h" |
| 14 #include "chrome/browser/chromeos/cros_settings_names.h" | 14 #include "chrome/browser/chromeos/cros_settings_names.h" |
| 15 #include "chrome/browser/chromeos/login/user_manager.h" | |
| 15 #include "chrome/browser/policy/proto/chrome_device_policy.pb.h" | 16 #include "chrome/browser/policy/proto/chrome_device_policy.pb.h" |
| 17 #include "chrome/browser/prefs/pref_service.h" | |
| 16 #include "chrome/browser/prefs/proxy_config_dictionary.h" | 18 #include "chrome/browser/prefs/proxy_config_dictionary.h" |
| 17 #include "chrome/browser/prefs/proxy_prefs.h" | 19 #include "chrome/browser/prefs/proxy_prefs.h" |
| 18 #include "content/public/browser/browser_thread.h" | 20 #include "chrome/browser/profiles/profile_manager.h" |
| 21 #include "chrome/common/chrome_notification_types.h" | |
| 22 #include "chrome/common/pref_names.h" | |
| 23 #include "content/public/browser/notification_service.h" | |
| 19 #include "grit/generated_resources.h" | 24 #include "grit/generated_resources.h" |
| 20 #include "ui/base/l10n/l10n_util.h" | 25 #include "ui/base/l10n/l10n_util.h" |
| 21 | 26 |
| 22 using content::BrowserThread; | |
| 23 | |
| 24 namespace em = enterprise_management; | 27 namespace em = enterprise_management; |
| 25 | 28 |
| 26 namespace chromeos { | 29 namespace chromeos { |
| 27 | 30 |
| 28 namespace { | 31 namespace { |
| 29 | 32 |
| 30 const char* SourceToString(ProxyConfigServiceImpl::ProxyConfig::Source source) { | 33 const char* ModeToString(ProxyConfigServiceImpl::ProxyConfig::Mode mode) { |
| 31 switch (source) { | 34 switch (mode) { |
| 32 case ProxyConfigServiceImpl::ProxyConfig::SOURCE_NONE: | 35 case ProxyConfigServiceImpl::ProxyConfig::MODE_DIRECT: |
| 33 return "SOURCE_NONE"; | 36 return "direct"; |
| 34 case ProxyConfigServiceImpl::ProxyConfig::SOURCE_POLICY: | 37 case ProxyConfigServiceImpl::ProxyConfig::MODE_AUTO_DETECT: |
| 35 return "SOURCE_POLICY"; | 38 return "auto-detect"; |
| 36 case ProxyConfigServiceImpl::ProxyConfig::SOURCE_OWNER: | 39 case ProxyConfigServiceImpl::ProxyConfig::MODE_PAC_SCRIPT: |
| 37 return "SOURCE_OWNER"; | 40 return "pacurl"; |
| 41 case ProxyConfigServiceImpl::ProxyConfig::MODE_SINGLE_PROXY: | |
| 42 return "single-proxy"; | |
| 43 case ProxyConfigServiceImpl::ProxyConfig::MODE_PROXY_PER_SCHEME: | |
| 44 return "proxy-per-scheme"; | |
| 38 } | 45 } |
| 39 NOTREACHED() << "Unrecognized source type"; | 46 NOTREACHED() << "Unrecognized mode type"; |
| 40 return ""; | 47 return ""; |
| 41 } | 48 } |
| 42 | 49 |
| 43 std::ostream& operator<<(std::ostream& out, | 50 const char* ConfigStateToString(ProxyPrefs::ConfigState state) { |
| 51 switch (state) { | |
| 52 case ProxyPrefs::CONFIG_POLICY: | |
| 53 return "config_policy"; | |
| 54 case ProxyPrefs::CONFIG_EXTENSION: | |
| 55 return "config_extension"; | |
| 56 case ProxyPrefs::CONFIG_OTHER_PRECEDE: | |
| 57 return "config_other_precede"; | |
| 58 case ProxyPrefs::CONFIG_SYSTEM: | |
| 59 return "config_network"; // For ChromeOS, system is network. | |
| 60 case ProxyPrefs::CONFIG_FALLBACK: | |
| 61 return "config_recommended"; // Fallback is recommended. | |
| 62 case ProxyPrefs::CONFIG_UNSET: | |
| 63 return "config_unset"; | |
| 64 } | |
| 65 NOTREACHED() << "Unrecognized config state type"; | |
| 66 return ""; | |
| 67 } | |
| 68 | |
| 69 // Only unblock if needed for debugging. | |
| 70 #if defined(NEED_DEBUG_LOG) | |
| 71 std::ostream& operator<<( | |
| 72 std::ostream& out, | |
| 44 const ProxyConfigServiceImpl::ProxyConfig::ManualProxy& proxy) { | 73 const ProxyConfigServiceImpl::ProxyConfig::ManualProxy& proxy) { |
| 45 out << " " << SourceToString(proxy.source) << "\n" | 74 out << (proxy.server.is_valid() ? proxy.server.ToURI() : "") << "\n"; |
| 46 << " server: " << (proxy.server.is_valid() ? proxy.server.ToURI() : "") | |
| 47 << "\n"; | |
| 48 return out; | 75 return out; |
| 49 } | 76 } |
| 50 | 77 |
| 51 std::ostream& operator<<(std::ostream& out, | 78 std::ostream& operator<<(std::ostream& out, |
| 52 const ProxyConfigServiceImpl::ProxyConfig& config) { | 79 const ProxyConfigServiceImpl::ProxyConfig& config) { |
| 53 switch (config.mode) { | 80 switch (config.mode) { |
| 54 case ProxyConfigServiceImpl::ProxyConfig::MODE_DIRECT: | 81 case ProxyConfigServiceImpl::ProxyConfig::MODE_DIRECT: |
| 55 out << "Direct connection:\n " | |
| 56 << SourceToString(config.automatic_proxy.source) << "\n"; | |
| 57 break; | |
| 58 case ProxyConfigServiceImpl::ProxyConfig::MODE_AUTO_DETECT: | 82 case ProxyConfigServiceImpl::ProxyConfig::MODE_AUTO_DETECT: |
| 59 out << "Auto detection:\n " | 83 out << ModeToString(config.mode) << ", " |
| 60 << SourceToString(config.automatic_proxy.source) << "\n"; | 84 << ConfigStateToString(config.state) << "\n"; |
| 61 break; | 85 break; |
| 62 case ProxyConfigServiceImpl::ProxyConfig::MODE_PAC_SCRIPT: | 86 case ProxyConfigServiceImpl::ProxyConfig::MODE_PAC_SCRIPT: |
| 63 out << "Custom PAC script:\n " | 87 out << ModeToString(config.mode) << ", " |
| 64 << SourceToString(config.automatic_proxy.source) | 88 << ConfigStateToString(config.state) |
| 65 << "\n PAC: " << config.automatic_proxy.pac_url << "\n"; | 89 << "\n PAC: " << config.automatic_proxy.pac_url << "\n"; |
| 66 break; | 90 break; |
| 67 case ProxyConfigServiceImpl::ProxyConfig::MODE_SINGLE_PROXY: | 91 case ProxyConfigServiceImpl::ProxyConfig::MODE_SINGLE_PROXY: |
| 68 out << "Single proxy:\n" << config.single_proxy; | 92 out << ModeToString(config.mode) << ", " |
| 93 << ConfigStateToString(config.state) << "\n " << config.single_proxy; | |
| 69 break; | 94 break; |
| 70 case ProxyConfigServiceImpl::ProxyConfig::MODE_PROXY_PER_SCHEME: | 95 case ProxyConfigServiceImpl::ProxyConfig::MODE_PROXY_PER_SCHEME: |
| 71 out << "HTTP proxy: " << config.http_proxy; | 96 out << ModeToString(config.mode) << ", " |
| 72 out << "HTTPS proxy: " << config.https_proxy; | 97 << ConfigStateToString(config.state) << "\n" |
| 73 out << "FTP proxy: " << config.ftp_proxy; | 98 << " HTTP: " << config.http_proxy |
| 74 out << "SOCKS proxy: " << config.socks_proxy; | 99 << " HTTPS: " << config.https_proxy |
| 100 << " FTP: " << config.ftp_proxy | |
| 101 << " SOCKS: " << config.socks_proxy; | |
| 75 break; | 102 break; |
| 76 default: | 103 default: |
| 77 NOTREACHED() << "Unrecognized proxy config mode"; | 104 NOTREACHED() << "Unrecognized proxy config mode"; |
| 78 break; | 105 break; |
| 79 } | 106 } |
| 80 if (config.mode == ProxyConfigServiceImpl::ProxyConfig::MODE_SINGLE_PROXY || | 107 if (config.mode == ProxyConfigServiceImpl::ProxyConfig::MODE_SINGLE_PROXY || |
| 81 config.mode == | 108 config.mode == |
| 82 ProxyConfigServiceImpl::ProxyConfig::MODE_PROXY_PER_SCHEME) { | 109 ProxyConfigServiceImpl::ProxyConfig::MODE_PROXY_PER_SCHEME) { |
| 83 out << "Bypass list: "; | 110 out << "Bypass list: "; |
| 84 if (config.bypass_rules.rules().empty()) { | 111 if (config.bypass_rules.rules().empty()) { |
| 85 out << "[None]"; | 112 out << "[None]"; |
| 86 } else { | 113 } else { |
| 87 const net::ProxyBypassRules& bypass_rules = config.bypass_rules; | 114 const net::ProxyBypassRules& bypass_rules = config.bypass_rules; |
| 88 net::ProxyBypassRules::RuleList::const_iterator it; | 115 net::ProxyBypassRules::RuleList::const_iterator it; |
| 89 for (it = bypass_rules.rules().begin(); | 116 for (it = bypass_rules.rules().begin(); |
| 90 it != bypass_rules.rules().end(); ++it) { | 117 it != bypass_rules.rules().end(); ++it) { |
| 91 out << "\n " << (*it)->ToString(); | 118 out << "\n " << (*it)->ToString(); |
| 92 } | 119 } |
| 93 } | 120 } |
| 94 } | 121 } |
| 95 return out; | 122 return out; |
| 96 } | 123 } |
| 97 | 124 |
| 98 std::string ProxyConfigToString( | 125 std::string ProxyConfigToString( |
| 99 const ProxyConfigServiceImpl::ProxyConfig& proxy_config) { | 126 const ProxyConfigServiceImpl::ProxyConfig& proxy_config) { |
| 100 std::ostringstream stream; | 127 std::ostringstream stream; |
| 101 stream << proxy_config; | 128 stream << proxy_config; |
| 102 return stream.str(); | 129 return stream.str(); |
| 103 } | 130 } |
| 131 #endif // defined(NEED_DEBUG_LOG) | |
| 104 | 132 |
| 105 } // namespace | 133 } // namespace |
| 106 | 134 |
| 107 //---------- ProxyConfigServiceImpl::ProxyConfig::Setting methods -------------- | |
| 108 | |
| 109 bool ProxyConfigServiceImpl::ProxyConfig::Setting::CanBeWrittenByUser( | |
| 110 bool user_is_owner) { | |
| 111 // Setting can only be written by user if user is owner and setting is not | |
| 112 // from policy. | |
| 113 return user_is_owner && source != ProxyConfig::SOURCE_POLICY; | |
| 114 } | |
| 115 | |
| 116 //----------- ProxyConfigServiceImpl::ProxyConfig: public methods -------------- | 135 //----------- ProxyConfigServiceImpl::ProxyConfig: public methods -------------- |
| 117 | 136 |
| 118 ProxyConfigServiceImpl::ProxyConfig::ProxyConfig() : mode(MODE_DIRECT) {} | 137 ProxyConfigServiceImpl::ProxyConfig::ProxyConfig() |
| 138 : mode(MODE_DIRECT), | |
| 139 state(ProxyPrefs::CONFIG_UNSET), | |
| 140 user_modifiable(true) {} | |
| 119 | 141 |
| 120 ProxyConfigServiceImpl::ProxyConfig::~ProxyConfig() {} | 142 ProxyConfigServiceImpl::ProxyConfig::~ProxyConfig() {} |
| 121 | 143 |
| 122 void ProxyConfigServiceImpl::ProxyConfig::ToNetProxyConfig( | 144 bool ProxyConfigServiceImpl::ProxyConfig::FromNetProxyConfig( |
| 123 net::ProxyConfig* net_config) { | 145 const net::ProxyConfig& net_config) { |
| 124 switch (mode) { | 146 *this = ProxyConfigServiceImpl::ProxyConfig(); // Reset to default. |
| 125 case MODE_DIRECT: | 147 const net::ProxyConfig::ProxyRules& rules = net_config.proxy_rules(); |
| 126 *net_config = net::ProxyConfig::CreateDirect(); | 148 switch (rules.type) { |
| 127 break; | 149 case net::ProxyConfig::ProxyRules::TYPE_NO_RULES: |
| 128 case MODE_AUTO_DETECT: | 150 if (!net_config.HasAutomaticSettings()) { |
| 129 *net_config = net::ProxyConfig::CreateAutoDetect(); | 151 mode = ProxyConfig::MODE_DIRECT; |
| 130 break; | 152 } else if (net_config.auto_detect()) { |
| 131 case MODE_PAC_SCRIPT: | 153 mode = ProxyConfig::MODE_AUTO_DETECT; |
| 132 *net_config = net::ProxyConfig::CreateFromCustomPacURL( | 154 } else if (net_config.has_pac_url()) { |
| 133 automatic_proxy.pac_url); | 155 mode = ProxyConfig::MODE_PAC_SCRIPT; |
| 134 break; | 156 automatic_proxy.pac_url = net_config.pac_url(); |
| 135 case MODE_SINGLE_PROXY: | 157 } else { |
| 136 *net_config = net::ProxyConfig(); | 158 return false; |
| 137 net_config->proxy_rules().type = | 159 } |
| 138 net::ProxyConfig::ProxyRules::TYPE_SINGLE_PROXY; | 160 return true; |
| 139 net_config->proxy_rules().single_proxy = single_proxy.server; | 161 case net::ProxyConfig::ProxyRules::TYPE_SINGLE_PROXY: |
| 140 net_config->proxy_rules().bypass_rules = bypass_rules; | 162 if (!rules.single_proxy.is_valid()) |
| 141 break; | 163 return false; |
| 142 case MODE_PROXY_PER_SCHEME: | 164 mode = MODE_SINGLE_PROXY; |
| 143 *net_config = net::ProxyConfig(); | 165 single_proxy.server = rules.single_proxy; |
| 144 net_config->proxy_rules().type = | 166 bypass_rules = rules.bypass_rules; |
| 145 net::ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME; | 167 return true; |
| 146 net_config->proxy_rules().proxy_for_http = http_proxy.server; | 168 case net::ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME: |
| 147 net_config->proxy_rules().proxy_for_https = https_proxy.server; | 169 // Make sure we have valid server for at least one of the protocols. |
| 148 net_config->proxy_rules().proxy_for_ftp = ftp_proxy.server; | 170 if (!rules.proxy_for_http.is_valid() && |
| 149 net_config->proxy_rules().fallback_proxy = socks_proxy.server; | 171 !rules.proxy_for_https.is_valid() && |
| 150 net_config->proxy_rules().bypass_rules = bypass_rules; | 172 !rules.proxy_for_ftp.is_valid() && |
| 151 break; | 173 !rules.fallback_proxy.is_valid()) { |
| 174 return false; | |
| 175 } | |
| 176 mode = MODE_PROXY_PER_SCHEME; | |
| 177 if (rules.proxy_for_http.is_valid()) | |
| 178 http_proxy.server = rules.proxy_for_http; | |
| 179 if (rules.proxy_for_https.is_valid()) | |
| 180 https_proxy.server = rules.proxy_for_https; | |
| 181 if (rules.proxy_for_ftp.is_valid()) | |
| 182 ftp_proxy.server = rules.proxy_for_ftp; | |
| 183 if (rules.fallback_proxy.is_valid()) | |
| 184 socks_proxy.server = rules.fallback_proxy; | |
| 185 bypass_rules = rules.bypass_rules; | |
| 186 return true; | |
| 152 default: | 187 default: |
| 153 NOTREACHED() << "Unrecognized proxy config mode"; | 188 NOTREACHED() << "Unrecognized proxy config mode"; |
| 154 break; | 189 break; |
| 155 } | 190 } |
| 191 return false; | |
| 156 } | 192 } |
| 157 | 193 |
| 158 bool ProxyConfigServiceImpl::ProxyConfig::CanBeWrittenByUser( | 194 DictionaryValue* ProxyConfigServiceImpl::ProxyConfig::ToPrefProxyConfig() { |
| 159 bool user_is_owner, const std::string& scheme) { | |
| 160 // Setting can only be written by user if user is owner and setting is not | |
| 161 // from policy. | |
| 162 Setting* setting = NULL; | |
| 163 switch (mode) { | 195 switch (mode) { |
| 164 case MODE_DIRECT: | 196 case MODE_DIRECT: { |
| 165 case MODE_AUTO_DETECT: | 197 return ProxyConfigDictionary::CreateDirect(); |
| 166 case MODE_PAC_SCRIPT: | 198 } |
| 167 setting = &automatic_proxy; | 199 case MODE_AUTO_DETECT: { |
| 168 break; | 200 return ProxyConfigDictionary::CreateAutoDetect(); |
| 169 case MODE_SINGLE_PROXY: | 201 } |
| 170 setting = &single_proxy; | 202 case MODE_PAC_SCRIPT: { |
| 171 break; | 203 return ProxyConfigDictionary::CreatePacScript( |
| 172 case MODE_PROXY_PER_SCHEME: | 204 automatic_proxy.pac_url.spec(), false); |
| 173 setting = MapSchemeToProxy(scheme); | 205 } |
| 174 break; | 206 case MODE_SINGLE_PROXY: { |
| 207 std::string spec; | |
| 208 if (single_proxy.server.is_valid()) | |
| 209 spec = single_proxy.server.ToURI(); | |
| 210 return ProxyConfigDictionary::CreateFixedServers( | |
| 211 spec, bypass_rules.ToString()); | |
| 212 } | |
| 213 case MODE_PROXY_PER_SCHEME: { | |
| 214 std::string spec; | |
| 215 EncodeAndAppendProxyServer("http", http_proxy.server, &spec); | |
| 216 EncodeAndAppendProxyServer("https", https_proxy.server, &spec); | |
| 217 EncodeAndAppendProxyServer("ftp", ftp_proxy.server, &spec); | |
| 218 EncodeAndAppendProxyServer("socks", socks_proxy.server, &spec); | |
| 219 return ProxyConfigDictionary::CreateFixedServers( | |
| 220 spec, bypass_rules.ToString()); | |
| 221 } | |
| 175 default: | 222 default: |
| 176 break; | 223 break; |
| 177 } | 224 } |
| 178 if (!setting) { | 225 NOTREACHED() << "Unrecognized proxy config mode for preference"; |
| 179 NOTREACHED() << "Unrecognized proxy config mode"; | 226 return NULL; |
| 180 return false; | |
| 181 } | |
| 182 return setting->CanBeWrittenByUser(user_is_owner); | |
| 183 } | 227 } |
| 184 | 228 |
| 185 ProxyConfigServiceImpl::ProxyConfig::ManualProxy* | 229 ProxyConfigServiceImpl::ProxyConfig::ManualProxy* |
| 186 ProxyConfigServiceImpl::ProxyConfig::MapSchemeToProxy( | 230 ProxyConfigServiceImpl::ProxyConfig::MapSchemeToProxy( |
| 187 const std::string& scheme) { | 231 const std::string& scheme) { |
| 188 if (scheme == "http") | 232 if (scheme == "http") |
| 189 return &http_proxy; | 233 return &http_proxy; |
| 190 if (scheme == "https") | 234 if (scheme == "https") |
| 191 return &https_proxy; | 235 return &https_proxy; |
| 192 if (scheme == "ftp") | 236 if (scheme == "ftp") |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 256 | 300 |
| 257 bool ProxyConfigServiceImpl::ProxyConfig::SerializeForNetwork( | 301 bool ProxyConfigServiceImpl::ProxyConfig::SerializeForNetwork( |
| 258 std::string* output) { | 302 std::string* output) { |
| 259 scoped_ptr<DictionaryValue> proxy_dict(ToPrefProxyConfig()); | 303 scoped_ptr<DictionaryValue> proxy_dict(ToPrefProxyConfig()); |
| 260 if (!proxy_dict.get()) | 304 if (!proxy_dict.get()) |
| 261 return false; | 305 return false; |
| 262 JSONStringValueSerializer serializer(output); | 306 JSONStringValueSerializer serializer(output); |
| 263 return serializer.Serialize(*proxy_dict.get()); | 307 return serializer.Serialize(*proxy_dict.get()); |
| 264 } | 308 } |
| 265 | 309 |
| 266 bool ProxyConfigServiceImpl::ProxyConfig::DeserializeForNetwork( | |
| 267 const std::string& input) { | |
| 268 JSONStringValueSerializer serializer(input); | |
| 269 scoped_ptr<Value> value(serializer.Deserialize(NULL, NULL)); | |
| 270 if (!value.get() || value->GetType() != Value::TYPE_DICTIONARY) | |
| 271 return false; | |
| 272 DictionaryValue* proxy_dict = static_cast<DictionaryValue*>(value.get()); | |
| 273 return FromPrefProxyConfig(proxy_dict); | |
| 274 } | |
| 275 | |
| 276 bool ProxyConfigServiceImpl::ProxyConfig::Equals( | |
| 277 const ProxyConfig& other) const { | |
| 278 if (mode != other.mode) | |
| 279 return false; | |
| 280 switch (mode) { | |
| 281 case MODE_DIRECT: | |
| 282 case MODE_AUTO_DETECT: | |
| 283 return true; | |
| 284 case MODE_PAC_SCRIPT: | |
| 285 return automatic_proxy.pac_url == other.automatic_proxy.pac_url; | |
| 286 case MODE_SINGLE_PROXY: | |
| 287 return single_proxy.server == other.single_proxy.server && | |
| 288 bypass_rules.Equals(other.bypass_rules); | |
| 289 case MODE_PROXY_PER_SCHEME: | |
| 290 return http_proxy.server == other.http_proxy.server && | |
| 291 https_proxy.server == other.https_proxy.server && | |
| 292 ftp_proxy.server == other.ftp_proxy.server && | |
| 293 socks_proxy.server == other.socks_proxy.server && | |
| 294 bypass_rules.Equals(other.bypass_rules); | |
| 295 default: { | |
| 296 NOTREACHED() << "Unrecognized proxy config mode"; | |
| 297 break; | |
| 298 } | |
| 299 } | |
| 300 return false; | |
| 301 } | |
| 302 | |
| 303 std::string ProxyConfigServiceImpl::ProxyConfig::ToString() const { | |
| 304 return ProxyConfigToString(*this); | |
| 305 } | |
| 306 | |
| 307 //----------- ProxyConfigServiceImpl::ProxyConfig: private methods ------------- | 310 //----------- ProxyConfigServiceImpl::ProxyConfig: private methods ------------- |
| 308 | 311 |
| 309 // static | 312 // static |
| 310 void ProxyConfigServiceImpl::ProxyConfig::EncodeAndAppendProxyServer( | 313 void ProxyConfigServiceImpl::ProxyConfig::EncodeAndAppendProxyServer( |
| 311 const std::string& scheme, | 314 const std::string& scheme, |
| 312 const net::ProxyServer& server, | 315 const net::ProxyServer& server, |
| 313 std::string* spec) { | 316 std::string* spec) { |
| 314 if (!server.is_valid()) | 317 if (!server.is_valid()) |
| 315 return; | 318 return; |
| 316 | 319 |
| 317 if (!spec->empty()) | 320 if (!spec->empty()) |
| 318 *spec += ';'; | 321 *spec += ';'; |
| 319 | 322 |
| 320 if (!scheme.empty()) { | 323 if (!scheme.empty()) { |
| 321 *spec += scheme; | 324 *spec += scheme; |
| 322 *spec += "="; | 325 *spec += "="; |
| 323 } | 326 } |
| 324 *spec += server.ToURI(); | 327 *spec += server.ToURI(); |
| 325 } | 328 } |
| 326 | 329 |
| 327 DictionaryValue* ProxyConfigServiceImpl::ProxyConfig::ToPrefProxyConfig() { | |
| 328 switch (mode) { | |
| 329 case MODE_DIRECT: { | |
| 330 return ProxyConfigDictionary::CreateDirect(); | |
| 331 } | |
| 332 case MODE_AUTO_DETECT: { | |
| 333 return ProxyConfigDictionary::CreateAutoDetect(); | |
| 334 } | |
| 335 case MODE_PAC_SCRIPT: { | |
| 336 return ProxyConfigDictionary::CreatePacScript( | |
| 337 automatic_proxy.pac_url.spec(), false); | |
| 338 } | |
| 339 case MODE_SINGLE_PROXY: { | |
| 340 std::string spec; | |
| 341 if (single_proxy.server.is_valid()) | |
| 342 spec = single_proxy.server.ToURI(); | |
| 343 return ProxyConfigDictionary::CreateFixedServers( | |
| 344 spec, bypass_rules.ToString()); | |
| 345 } | |
| 346 case MODE_PROXY_PER_SCHEME: { | |
| 347 std::string spec; | |
| 348 EncodeAndAppendProxyServer("http", http_proxy.server, &spec); | |
| 349 EncodeAndAppendProxyServer("https", https_proxy.server, &spec); | |
| 350 EncodeAndAppendProxyServer("ftp", ftp_proxy.server, &spec); | |
| 351 EncodeAndAppendProxyServer("socks", socks_proxy.server, &spec); | |
| 352 return ProxyConfigDictionary::CreateFixedServers( | |
| 353 spec, bypass_rules.ToString()); | |
| 354 } | |
| 355 default: | |
| 356 break; | |
| 357 } | |
| 358 NOTREACHED() << "Unrecognized proxy config mode for preference"; | |
| 359 return NULL; | |
| 360 } | |
| 361 | |
| 362 bool ProxyConfigServiceImpl::ProxyConfig::FromPrefProxyConfig( | |
| 363 const DictionaryValue* dict) { | |
| 364 ProxyConfigDictionary proxy_dict(dict); | |
| 365 | |
| 366 *this = ProxyConfigServiceImpl::ProxyConfig(); // Reset to default. | |
| 367 | |
| 368 ProxyPrefs::ProxyMode proxy_mode; | |
| 369 if (!proxy_dict.GetMode(&proxy_mode)) { | |
| 370 // Fall back to system settings if the mode preference is invalid. | |
| 371 return false; | |
| 372 } | |
| 373 | |
| 374 switch (proxy_mode) { | |
| 375 case ProxyPrefs::MODE_SYSTEM: | |
| 376 // Use system settings, so we shouldn't use |this| proxy config. | |
| 377 return false; | |
| 378 case ProxyPrefs::MODE_DIRECT: | |
| 379 // Ignore all the other proxy config preferences if the use of a proxy | |
| 380 // has been explicitly disabled. | |
| 381 return true; | |
| 382 case ProxyPrefs::MODE_AUTO_DETECT: | |
| 383 mode = MODE_AUTO_DETECT; | |
| 384 return true; | |
| 385 case ProxyPrefs::MODE_PAC_SCRIPT: { | |
| 386 std::string proxy_pac; | |
| 387 if (!proxy_dict.GetPacUrl(&proxy_pac)) { | |
| 388 LOG(ERROR) << "Proxy settings request PAC script but do not specify " | |
| 389 << "its URL. Falling back to direct connection."; | |
| 390 return true; | |
| 391 } | |
| 392 GURL proxy_pac_url(proxy_pac); | |
| 393 if (!proxy_pac_url.is_valid()) { | |
| 394 LOG(ERROR) << "Invalid proxy PAC url: " << proxy_pac; | |
| 395 return true; | |
| 396 } | |
| 397 mode = MODE_PAC_SCRIPT; | |
| 398 automatic_proxy.pac_url = proxy_pac_url; | |
| 399 return true; | |
| 400 } | |
| 401 case ProxyPrefs::MODE_FIXED_SERVERS: { | |
| 402 std::string proxy_server; | |
| 403 if (!proxy_dict.GetProxyServer(&proxy_server)) { | |
| 404 LOG(ERROR) << "Proxy settings request fixed proxy servers but do not " | |
| 405 << "specify their URLs. Falling back to direct connection."; | |
| 406 return true; | |
| 407 } | |
| 408 net::ProxyConfig::ProxyRules proxy_rules; | |
| 409 proxy_rules.ParseFromString(proxy_server); | |
| 410 if (proxy_rules.type == net::ProxyConfig::ProxyRules::TYPE_SINGLE_PROXY) { | |
| 411 mode = MODE_SINGLE_PROXY; | |
| 412 single_proxy.server = proxy_rules.single_proxy; | |
| 413 } else if (proxy_rules.type == | |
| 414 net::ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME) { | |
| 415 mode = MODE_PROXY_PER_SCHEME; | |
| 416 http_proxy.server = proxy_rules.proxy_for_http; | |
| 417 https_proxy.server = proxy_rules.proxy_for_https; | |
| 418 ftp_proxy.server = proxy_rules.proxy_for_ftp; | |
| 419 socks_proxy.server = proxy_rules.fallback_proxy; | |
| 420 } else { | |
| 421 LOG(ERROR) << "Proxy settings request fixed proxy servers but do not " | |
| 422 << "have valid proxy rules type. " | |
| 423 << "Falling back to direct connection."; | |
| 424 return true; | |
| 425 } | |
| 426 | |
| 427 std::string proxy_bypass; | |
| 428 if (proxy_dict.GetBypassList(&proxy_bypass)) { | |
| 429 bypass_rules.ParseFromString(proxy_bypass); | |
| 430 } | |
| 431 return true; | |
| 432 } | |
| 433 case ProxyPrefs::kModeCount: { | |
| 434 // Fall through to NOTREACHED(). | |
| 435 } | |
| 436 } | |
| 437 NOTREACHED() << "Unknown proxy mode, falling back to system settings."; | |
| 438 return false; | |
| 439 } | |
| 440 | |
| 441 //------------------- ProxyConfigServiceImpl: public methods ------------------- | 330 //------------------- ProxyConfigServiceImpl: public methods ------------------- |
| 442 | 331 |
| 443 ProxyConfigServiceImpl::ProxyConfigServiceImpl() | 332 ProxyConfigServiceImpl::ProxyConfigServiceImpl(PrefService* pref_service) |
| 444 : testing_(false), | 333 : PrefProxyConfigTrackerImpl(pref_service), |
| 445 can_post_task_(false), | 334 active_config_state_(ProxyPrefs::CONFIG_UNSET) { |
| 446 config_availability_(net::ProxyConfigService::CONFIG_UNSET), | 335 |
| 447 use_shared_proxies_(true) { | 336 // Register for notification when user logs in, so that we can activate the |
| 337 // new proxy config. | |
| 338 registrar_.Add(this, chrome::NOTIFICATION_LOGIN_USER_CHANGED, | |
| 339 content::NotificationService::AllSources()); | |
| 340 | |
| 341 // Register for notifications of UseSharedProxies user preference. | |
| 342 if (pref_service->FindPreference(prefs::kUseSharedProxies)) | |
| 343 use_shared_proxies_.Init(prefs::kUseSharedProxies, pref_service, this); | |
| 344 | |
| 448 // Start async fetch of proxy config from settings persisted on device. | 345 // Start async fetch of proxy config from settings persisted on device. |
| 449 if (CrosLibrary::Get()->EnsureLoaded()) { | 346 if (CrosLibrary::Get()->libcros_loaded()) { |
| 450 retrieve_property_op_ = SignedSettings::CreateRetrievePropertyOp( | 347 retrieve_property_op_ = SignedSettings::CreateRetrievePropertyOp( |
| 451 kSettingProxyEverywhere, this); | 348 kSettingProxyEverywhere, this); |
| 452 if (retrieve_property_op_) { | 349 if (retrieve_property_op_) { |
| 453 retrieve_property_op_->Execute(); | 350 retrieve_property_op_->Execute(); |
| 454 VLOG(1) << "Start retrieving proxy setting from device"; | 351 VLOG(1) << this << ": Start retrieving proxy setting from device"; |
| 455 } else { | 352 } else { |
| 456 VLOG(1) << "Fail to retrieve proxy setting from device"; | 353 VLOG(1) << this << ": Fail to retrieve proxy setting from device"; |
| 457 } | 354 } |
| 458 } | 355 } |
| 459 | 356 |
| 357 // Register for flimflam network notifications. | |
| 460 NetworkLibrary* network_lib = CrosLibrary::Get()->GetNetworkLibrary(); | 358 NetworkLibrary* network_lib = CrosLibrary::Get()->GetNetworkLibrary(); |
| 461 OnActiveNetworkChanged(network_lib, network_lib->active_network()); | 359 OnActiveNetworkChanged(network_lib, network_lib->active_network()); |
| 462 network_lib->AddNetworkManagerObserver(this); | 360 network_lib->AddNetworkManagerObserver(this); |
| 463 | |
| 464 can_post_task_ = true; | |
| 465 } | |
| 466 | |
| 467 ProxyConfigServiceImpl::ProxyConfigServiceImpl(const ProxyConfig& init_config) | |
| 468 : testing_(false), | |
| 469 can_post_task_(true), | |
| 470 config_availability_(net::ProxyConfigService::CONFIG_VALID), | |
| 471 use_shared_proxies_(true) { | |
| 472 active_config_ = init_config; | |
| 473 // Update the IO-accessible copy in |cached_config_| as well. | |
| 474 cached_config_ = active_config_; | |
| 475 } | 361 } |
| 476 | 362 |
| 477 ProxyConfigServiceImpl::~ProxyConfigServiceImpl() { | 363 ProxyConfigServiceImpl::~ProxyConfigServiceImpl() { |
| 478 NetworkLibrary* netlib = CrosLibrary::Get()->GetNetworkLibrary(); | 364 NetworkLibrary* netlib = CrosLibrary::Get()->GetNetworkLibrary(); |
| 479 if (netlib) { | 365 if (netlib) { |
| 480 netlib->RemoveNetworkManagerObserver(this); | 366 netlib->RemoveNetworkManagerObserver(this); |
| 481 netlib->RemoveObserverForAllNetworks(this); | 367 netlib->RemoveObserverForAllNetworks(this); |
| 482 } | 368 } |
| 483 } | 369 } |
| 484 | 370 |
| 371 void ProxyConfigServiceImpl::UISetCurrentNetwork( | |
| 372 const std::string& current_network) { | |
| 373 Network* network = CrosLibrary::Get()->GetNetworkLibrary()->FindNetworkByPath( | |
| 374 current_network); | |
| 375 if (!network) { | |
| 376 ResetUICache(); | |
| 377 LOG(ERROR) << "can't find requested network " << current_network; | |
| 378 return; | |
| 379 } | |
| 380 current_ui_network_ = current_network; | |
| 381 OnUISetCurrentNetwork(network); | |
| 382 } | |
| 383 | |
| 384 void ProxyConfigServiceImpl::UIMakeActiveNetworkCurrent() { | |
| 385 Network* network = CrosLibrary::Get()->GetNetworkLibrary()->FindNetworkByPath( | |
| 386 active_network_); | |
| 387 if (!network) { | |
| 388 ResetUICache(); | |
| 389 LOG(ERROR) << "can't find requested network " << active_network_; | |
| 390 return; | |
| 391 } | |
| 392 current_ui_network_ = active_network_; | |
| 393 OnUISetCurrentNetwork(network); | |
| 394 } | |
| 395 | |
| 396 void ProxyConfigServiceImpl::UIGetCurrentNetworkName( | |
| 397 std::string* network_name) { | |
| 398 if (!network_name) | |
| 399 return; | |
| 400 network_name->clear(); | |
| 401 Network* network = CrosLibrary::Get()->GetNetworkLibrary()->FindNetworkByPath( | |
| 402 current_ui_network_); | |
| 403 if (!network) { | |
| 404 LOG(ERROR) << "can't find requested network " << current_ui_network_; | |
| 405 return; | |
| 406 } | |
| 407 if (network->name().empty() && network->type() == chromeos::TYPE_ETHERNET) { | |
| 408 *network_name = | |
| 409 l10n_util::GetStringUTF8(IDS_STATUSBAR_NETWORK_DEVICE_ETHERNET); | |
| 410 } else { | |
| 411 *network_name = network->name(); | |
| 412 } | |
| 413 } | |
| 414 | |
| 485 void ProxyConfigServiceImpl::UIGetProxyConfig(ProxyConfig* config) { | 415 void ProxyConfigServiceImpl::UIGetProxyConfig(ProxyConfig* config) { |
| 486 // Should be called from UI thread. | 416 // Simply returns the copy last set from UI via UISetCurrentNetwork or |
| 487 CheckCurrentlyOnUIThread(); | 417 // UIMakeActiveNetworkCurrent. |
| 488 // Simply returns the copy on the UI thread. | |
| 489 *config = current_ui_config_; | 418 *config = current_ui_config_; |
| 490 } | 419 } |
| 491 | 420 |
| 492 bool ProxyConfigServiceImpl::UISetCurrentNetwork( | |
| 493 const std::string& current_network) { | |
| 494 // Should be called from UI thread. | |
| 495 CheckCurrentlyOnUIThread(); | |
| 496 if (current_ui_network_ == current_network) | |
| 497 return false; | |
| 498 Network* network = CrosLibrary::Get()->GetNetworkLibrary()->FindNetworkByPath( | |
| 499 current_network); | |
| 500 if (!network) { | |
| 501 LOG(ERROR) << "can't find requested network " << current_network; | |
| 502 return false; | |
| 503 } | |
| 504 current_ui_network_ = current_network; | |
| 505 current_ui_config_ = ProxyConfig(); | |
| 506 SetCurrentNetworkName(network); | |
| 507 if (!network->proxy_config().empty()) | |
| 508 current_ui_config_.DeserializeForNetwork(network->proxy_config()); | |
| 509 VLOG(1) << "current ui network: " | |
| 510 << (current_ui_network_name_.empty() ? | |
| 511 current_ui_network_ : current_ui_network_name_) | |
| 512 << ", proxy mode: " << current_ui_config_.mode; | |
| 513 return true; | |
| 514 } | |
| 515 | |
| 516 bool ProxyConfigServiceImpl::UIMakeActiveNetworkCurrent() { | |
| 517 // Should be called from UI thread. | |
| 518 CheckCurrentlyOnUIThread(); | |
| 519 if (current_ui_network_ == active_network_) | |
| 520 return false; | |
| 521 Network* network = NULL; | |
| 522 if (!testing_) { | |
| 523 network = CrosLibrary::Get()->GetNetworkLibrary()->FindNetworkByPath( | |
| 524 active_network_); | |
| 525 if (!network) { | |
| 526 LOG(ERROR) << "can't find requested network " << active_network_; | |
| 527 return false; | |
| 528 } | |
| 529 } | |
| 530 current_ui_network_ = active_network_; | |
| 531 current_ui_config_ = active_config_; | |
| 532 SetCurrentNetworkName(network); | |
| 533 VLOG(1) << "current ui network: " | |
| 534 << (current_ui_network_name_.empty() ? | |
| 535 current_ui_network_ : current_ui_network_name_) | |
| 536 << ", proxy mode: " << current_ui_config_.mode; | |
| 537 return true; | |
| 538 } | |
| 539 | |
| 540 void ProxyConfigServiceImpl::UISetUseSharedProxies(bool use_shared) { | |
| 541 // Should be called from UI thread. | |
| 542 CheckCurrentlyOnUIThread(); | |
| 543 | |
| 544 // Reset all UI-related variables so that the next opening of proxy | |
| 545 // configuration dialog of any network will trigger javascript reloading of | |
| 546 // (possibly) new proxy settings. | |
| 547 current_ui_network_.clear(); | |
| 548 current_ui_network_name_.clear(); | |
| 549 current_ui_config_ = ProxyConfig(); | |
| 550 | |
| 551 if (use_shared_proxies_ == use_shared) { | |
| 552 VLOG(1) << "same use_shared_proxies = " << use_shared_proxies_; | |
| 553 return; | |
| 554 } | |
| 555 use_shared_proxies_ = use_shared; | |
| 556 VLOG(1) << "new use_shared_proxies = " << use_shared_proxies_; | |
| 557 if (active_network_.empty()) | |
| 558 return; | |
| 559 Network* network = CrosLibrary::Get()->GetNetworkLibrary()->FindNetworkByPath( | |
| 560 active_network_); | |
| 561 if (!network) { | |
| 562 LOG(ERROR) << "can't find requested network " << active_network_; | |
| 563 return; | |
| 564 } | |
| 565 DetermineConfigFromNetwork(network); | |
| 566 } | |
| 567 | |
| 568 bool ProxyConfigServiceImpl::UISetProxyConfigToDirect() { | 421 bool ProxyConfigServiceImpl::UISetProxyConfigToDirect() { |
| 569 // Should be called from UI thread. | |
| 570 CheckCurrentlyOnUIThread(); | |
| 571 current_ui_config_.mode = ProxyConfig::MODE_DIRECT; | 422 current_ui_config_.mode = ProxyConfig::MODE_DIRECT; |
| 572 OnUISetProxyConfig(); | 423 OnUISetProxyConfig(); |
| 573 return true; | 424 return true; |
| 574 } | 425 } |
| 575 | 426 |
| 576 bool ProxyConfigServiceImpl::UISetProxyConfigToAutoDetect() { | 427 bool ProxyConfigServiceImpl::UISetProxyConfigToAutoDetect() { |
| 577 // Should be called from UI thread. | |
| 578 CheckCurrentlyOnUIThread(); | |
| 579 current_ui_config_.mode = ProxyConfig::MODE_AUTO_DETECT; | 428 current_ui_config_.mode = ProxyConfig::MODE_AUTO_DETECT; |
| 580 OnUISetProxyConfig(); | 429 OnUISetProxyConfig(); |
| 581 return true; | 430 return true; |
| 582 } | 431 } |
| 583 | 432 |
| 584 bool ProxyConfigServiceImpl::UISetProxyConfigToPACScript(const GURL& pac_url) { | 433 bool ProxyConfigServiceImpl::UISetProxyConfigToPACScript(const GURL& pac_url) { |
| 585 // Should be called from UI thread. | |
| 586 CheckCurrentlyOnUIThread(); | |
| 587 current_ui_config_.mode = ProxyConfig::MODE_PAC_SCRIPT; | 434 current_ui_config_.mode = ProxyConfig::MODE_PAC_SCRIPT; |
| 588 current_ui_config_.automatic_proxy.pac_url = pac_url; | 435 current_ui_config_.automatic_proxy.pac_url = pac_url; |
| 589 OnUISetProxyConfig(); | 436 OnUISetProxyConfig(); |
| 590 return true; | 437 return true; |
| 591 } | 438 } |
| 592 | 439 |
| 593 bool ProxyConfigServiceImpl::UISetProxyConfigToSingleProxy( | 440 bool ProxyConfigServiceImpl::UISetProxyConfigToSingleProxy( |
| 594 const net::ProxyServer& server) { | 441 const net::ProxyServer& server) { |
| 595 // Should be called from UI thread. | |
| 596 CheckCurrentlyOnUIThread(); | |
| 597 current_ui_config_.mode = ProxyConfig::MODE_SINGLE_PROXY; | 442 current_ui_config_.mode = ProxyConfig::MODE_SINGLE_PROXY; |
| 598 current_ui_config_.single_proxy.server = server; | 443 current_ui_config_.single_proxy.server = server; |
| 599 OnUISetProxyConfig(); | 444 OnUISetProxyConfig(); |
| 600 return true; | 445 return true; |
| 601 } | 446 } |
| 602 | 447 |
| 603 bool ProxyConfigServiceImpl::UISetProxyConfigToProxyPerScheme( | 448 bool ProxyConfigServiceImpl::UISetProxyConfigToProxyPerScheme( |
| 604 const std::string& scheme, const net::ProxyServer& server) { | 449 const std::string& scheme, const net::ProxyServer& server) { |
| 605 // Should be called from UI thread. | |
| 606 CheckCurrentlyOnUIThread(); | |
| 607 ProxyConfig::ManualProxy* proxy = current_ui_config_.MapSchemeToProxy(scheme); | 450 ProxyConfig::ManualProxy* proxy = current_ui_config_.MapSchemeToProxy(scheme); |
| 608 if (!proxy) { | 451 if (!proxy) { |
| 609 NOTREACHED() << "Cannot set proxy: invalid scheme [" << scheme << "]"; | 452 NOTREACHED() << "Cannot set proxy: invalid scheme [" << scheme << "]"; |
| 610 return false; | 453 return false; |
| 611 } | 454 } |
| 612 current_ui_config_.mode = ProxyConfig::MODE_PROXY_PER_SCHEME; | 455 current_ui_config_.mode = ProxyConfig::MODE_PROXY_PER_SCHEME; |
| 613 proxy->server = server; | 456 proxy->server = server; |
| 614 OnUISetProxyConfig(); | 457 OnUISetProxyConfig(); |
| 615 return true; | 458 return true; |
| 616 } | 459 } |
| 617 | 460 |
| 618 bool ProxyConfigServiceImpl::UISetProxyConfigBypassRules( | 461 bool ProxyConfigServiceImpl::UISetProxyConfigBypassRules( |
| 619 const net::ProxyBypassRules& bypass_rules) { | 462 const net::ProxyBypassRules& bypass_rules) { |
| 620 // Should be called from UI thread. | |
| 621 CheckCurrentlyOnUIThread(); | |
| 622 if (current_ui_config_.mode != ProxyConfig::MODE_SINGLE_PROXY && | 463 if (current_ui_config_.mode != ProxyConfig::MODE_SINGLE_PROXY && |
| 623 current_ui_config_.mode != ProxyConfig::MODE_PROXY_PER_SCHEME) { | 464 current_ui_config_.mode != ProxyConfig::MODE_PROXY_PER_SCHEME) { |
| 624 NOTREACHED(); | 465 NOTREACHED(); |
| 625 VLOG(1) << "Cannot set bypass rules for proxy mode [" | 466 VLOG(1) << "Cannot set bypass rules for proxy mode [" |
| 626 << current_ui_config_.mode << "]"; | 467 << current_ui_config_.mode << "]"; |
| 627 return false; | 468 return false; |
| 628 } | 469 } |
| 629 current_ui_config_.bypass_rules = bypass_rules; | 470 current_ui_config_.bypass_rules = bypass_rules; |
| 630 OnUISetProxyConfig(); | 471 OnUISetProxyConfig(); |
| 631 return true; | 472 return true; |
| 632 } | 473 } |
| 633 | 474 |
| 634 void ProxyConfigServiceImpl::AddObserver( | 475 void ProxyConfigServiceImpl::OnProxyConfigChanged( |
| 635 net::ProxyConfigService::Observer* observer) { | 476 ProxyPrefs::ConfigState config_state, |
| 636 // Should be called from IO thread. | 477 const net::ProxyConfig& config) { |
| 637 CheckCurrentlyOnIOThread(); | 478 VLOG(1) << this << ": got prefs change: " << ConfigStateToString(config_state) |
| 638 observers_.AddObserver(observer); | 479 << ", mode=" << config.proxy_rules().type; |
| 639 } | 480 Network* network = NULL; |
| 640 | 481 if (!active_network_.empty()) { |
| 641 void ProxyConfigServiceImpl::RemoveObserver( | 482 network = CrosLibrary::Get()->GetNetworkLibrary()->FindNetworkByPath( |
| 642 net::ProxyConfigService::Observer* observer) { | 483 active_network_); |
| 643 // Should be called from IO thread. | 484 if (!network) |
| 644 CheckCurrentlyOnIOThread(); | 485 LOG(ERROR) << "can't find requested network " << active_network_; |
| 645 observers_.RemoveObserver(observer); | |
| 646 } | |
| 647 | |
| 648 net::ProxyConfigService::ConfigAvailability | |
| 649 ProxyConfigServiceImpl::IOGetProxyConfig(net::ProxyConfig* net_config) { | |
| 650 // Should be called from IO thread. | |
| 651 CheckCurrentlyOnIOThread(); | |
| 652 if (config_availability_ == net::ProxyConfigService::CONFIG_VALID) { | |
| 653 VLOG(1) << "returning proxy mode=" << cached_config_.mode; | |
| 654 cached_config_.ToNetProxyConfig(net_config); | |
| 655 } | 486 } |
| 656 return config_availability_; | 487 DetermineEffectiveConfig(network, true); |
| 657 } | 488 } |
| 658 | 489 |
| 659 void ProxyConfigServiceImpl::OnSettingsOpCompleted( | 490 void ProxyConfigServiceImpl::OnSettingsOpCompleted( |
| 660 SignedSettings::ReturnCode code, | 491 SignedSettings::ReturnCode code, |
| 661 std::string value) { | 492 std::string value) { |
| 662 retrieve_property_op_ = NULL; | 493 retrieve_property_op_ = NULL; |
| 663 if (code != SignedSettings::SUCCESS) { | 494 if (code != SignedSettings::SUCCESS) { |
| 664 LOG(WARNING) << "Error retrieving proxy setting from device"; | 495 LOG(WARNING) << this << ": Error retrieving proxy setting from device"; |
| 665 device_config_.clear(); | 496 device_config_.clear(); |
| 666 return; | 497 return; |
| 667 } | 498 } |
| 668 VLOG(1) << "Retrieved proxy setting from device, value=[" << value << "]"; | 499 VLOG(1) << this << ": Retrieved proxy setting from device, value=[" |
| 500 << value << "]"; | |
| 669 ProxyConfig device_config; | 501 ProxyConfig device_config; |
| 670 if (!device_config.DeserializeForDevice(value) || | 502 if (!device_config.DeserializeForDevice(value) || |
| 671 !device_config.SerializeForNetwork(&device_config_)) { | 503 !device_config.SerializeForNetwork(&device_config_)) { |
| 672 LOG(WARNING) << "Can't deserialize device setting or serialize for network"; | 504 LOG(WARNING) << "Can't deserialize device setting or serialize for network"; |
| 673 device_config_.clear(); | 505 device_config_.clear(); |
| 674 return; | 506 return; |
| 675 } | 507 } |
| 676 if (!active_network_.empty()) { | 508 if (!active_network_.empty()) { |
| 677 VLOG(1) << "try migrating device config to " << active_network_; | 509 VLOG(1) << this << ": try migrating device config to " << active_network_; |
| 678 SetProxyConfigForNetwork(active_network_, device_config_, true); | 510 SetProxyConfigForNetwork(active_network_, device_config_, true); |
| 679 } | 511 } |
| 680 } | 512 } |
| 681 | 513 |
| 682 void ProxyConfigServiceImpl::OnNetworkManagerChanged( | 514 void ProxyConfigServiceImpl::OnNetworkManagerChanged( |
| 683 NetworkLibrary* network_lib) { | 515 NetworkLibrary* network_lib) { |
| 684 VLOG(1) << "OnNetworkManagerChanged: use-shared-proxies=" | 516 VLOG(1) << this << " OnNetworkManagerChanged: use-shared-proxies=" |
| 685 << use_shared_proxies_; | 517 << GetUseSharedProxies(); |
| 686 OnActiveNetworkChanged(network_lib, network_lib->active_network()); | 518 OnActiveNetworkChanged(network_lib, network_lib->active_network()); |
| 687 } | 519 } |
| 688 | 520 |
| 689 void ProxyConfigServiceImpl::OnNetworkChanged(NetworkLibrary* network_lib, | 521 void ProxyConfigServiceImpl::OnNetworkChanged(NetworkLibrary* network_lib, |
| 690 const Network* network) { | 522 const Network* network) { |
| 691 if (!network) | 523 if (!network) |
| 692 return; | 524 return; |
| 693 VLOG(1) << "OnNetworkChanged: " | 525 VLOG(1) << this << " OnNetworkChanged: " |
| 694 << (network->name().empty() ? network->service_path() : | 526 << (network->name().empty() ? network->service_path() : |
| 695 network->name()) | 527 network->name()) |
| 696 << ", use-shared-proxies=" << use_shared_proxies_; | 528 << ", use-shared-proxies=" << GetUseSharedProxies(); |
| 697 // We only care about active network. | 529 // We only care about active network. |
| 698 if (network == network_lib->active_network()) | 530 if (network == network_lib->active_network()) |
| 699 OnActiveNetworkChanged(network_lib, network); | 531 OnActiveNetworkChanged(network_lib, network); |
| 700 } | 532 } |
| 701 | 533 |
| 534 // static | |
| 535 void ProxyConfigServiceImpl::RegisterPrefs(PrefService* pref_service) { | |
| 536 // Use shared proxies default to off. GetUseSharedProxies will return the | |
| 537 // correct value based on pre-login and login. | |
| 538 pref_service->RegisterBooleanPref(prefs::kUseSharedProxies, | |
| 539 false, | |
| 540 PrefService::UNSYNCABLE_PREF); | |
| 541 } | |
| 542 | |
| 702 //------------------ ProxyConfigServiceImpl: private methods ------------------- | 543 //------------------ ProxyConfigServiceImpl: private methods ------------------- |
| 703 | 544 |
| 704 void ProxyConfigServiceImpl::OnUISetProxyConfig() { | 545 void ProxyConfigServiceImpl::Observe( |
| 705 if (testing_) { | 546 int type, |
| 706 active_config_ = current_ui_config_; | 547 const content::NotificationSource& source, |
| 707 IOSetProxyConfig(active_config_, net::ProxyConfigService::CONFIG_VALID); | 548 const content::NotificationDetails& details) { |
| 549 if (type == chrome::NOTIFICATION_PREF_CHANGED && | |
| 550 *(content::Details<std::string>(details).ptr()) == | |
| 551 prefs::kUseSharedProxies) { | |
| 552 if (content::Source<PrefService>(source).ptr() == prefs()) { | |
| 553 VLOG(1) << this << ": new use-shared-proxies = " << GetUseSharedProxies(); | |
| 554 // Determine new proxy config which may have changed because of new | |
| 555 // use-shared-proxies. If necessary, activate it. | |
| 556 Network* network = NULL; | |
| 557 if (!active_network_.empty()) { | |
| 558 network = CrosLibrary::Get()->GetNetworkLibrary()->FindNetworkByPath( | |
| 559 active_network_); | |
| 560 if (!network) | |
| 561 LOG(WARNING) << "can't find requested network " << active_network_; | |
| 562 } | |
| 563 DetermineEffectiveConfig(network, true); | |
| 564 } | |
| 708 return; | 565 return; |
| 709 } | 566 } |
| 567 if (type == chrome::NOTIFICATION_LOGIN_USER_CHANGED) { | |
| 568 VLOG(1) << this << ": login user changed"; | |
| 569 // If active network is the same, its proxy config and/or UseSharedProxies | |
| 570 // pref for this user could be different from that in login screen; | |
| 571 // determine effective config and activate it if different. | |
| 572 const Network* active_network = | |
| 573 CrosLibrary::Get()->GetNetworkLibrary()->active_network(); | |
| 574 if (active_network && active_network_ == active_network->service_path()) | |
| 575 DetermineEffectiveConfig(active_network, true); | |
| 576 return; | |
| 577 } | |
| 578 PrefProxyConfigTrackerImpl::Observe(type, source, details); | |
| 579 } | |
| 580 | |
| 581 void ProxyConfigServiceImpl::OnUISetProxyConfig() { | |
| 710 if (current_ui_network_.empty()) | 582 if (current_ui_network_.empty()) |
| 711 return; | 583 return; |
| 712 // Update config to flimflam. | 584 // Update config to flimflam. |
| 713 std::string value; | 585 std::string value; |
| 714 if (current_ui_config_.SerializeForNetwork(&value)) { | 586 if (current_ui_config_.SerializeForNetwork(&value)) { |
| 715 VLOG(1) << "set proxy (mode=" << current_ui_config_.mode | 587 VLOG(1) << this << ": set proxy (mode=" << current_ui_config_.mode |
| 716 << ") for " << current_ui_network_; | 588 << ") for " << current_ui_network_; |
| 589 current_ui_config_.state = ProxyPrefs::CONFIG_SYSTEM; | |
| 717 SetProxyConfigForNetwork(current_ui_network_, value, false); | 590 SetProxyConfigForNetwork(current_ui_network_, value, false); |
| 718 } | 591 } |
| 719 } | 592 } |
| 720 | 593 |
| 721 void ProxyConfigServiceImpl::IOSetProxyConfig( | |
| 722 const ProxyConfig& new_config, | |
| 723 net::ProxyConfigService::ConfigAvailability new_availability) { | |
| 724 if (!BrowserThread::CurrentlyOn(BrowserThread::IO) && can_post_task_) { | |
| 725 // Posts a task to IO thread with the new config, so it can update | |
| 726 // |cached_config_|. | |
| 727 Task* task = NewRunnableMethod(this, | |
| 728 &ProxyConfigServiceImpl::IOSetProxyConfig, | |
| 729 new_config, | |
| 730 new_availability); | |
| 731 if (!BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, task)) | |
| 732 VLOG(1) << "Couldn't post task to IO thread to set new proxy config"; | |
| 733 return; | |
| 734 } | |
| 735 | |
| 736 // Now guaranteed to be on the correct thread. | |
| 737 | |
| 738 if (config_availability_ == new_availability && | |
| 739 cached_config_.Equals(new_config)) | |
| 740 return; | |
| 741 | |
| 742 VLOG(1) << "Proxy changed: mode=" << new_config.mode | |
| 743 << ", avail=" << new_availability; | |
| 744 cached_config_ = new_config; | |
| 745 config_availability_ = new_availability; | |
| 746 // Notify observers of new proxy config. | |
| 747 net::ProxyConfig net_config; | |
| 748 cached_config_.ToNetProxyConfig(&net_config); | |
| 749 if (net_config.proxy_rules().type != | |
| 750 net::ProxyConfig::ProxyRules::TYPE_NO_RULES) { | |
| 751 net_config.proxy_rules().bypass_rules.AddRuleToBypassLocal(); | |
| 752 } | |
| 753 FOR_EACH_OBSERVER(net::ProxyConfigService::Observer, observers_, | |
| 754 OnProxyConfigChanged(net_config, config_availability_)); | |
| 755 } | |
| 756 | |
| 757 void ProxyConfigServiceImpl::OnActiveNetworkChanged(NetworkLibrary* network_lib, | 594 void ProxyConfigServiceImpl::OnActiveNetworkChanged(NetworkLibrary* network_lib, |
| 758 const Network* active_network) { | 595 const Network* active_network) { |
| 759 std::string new_network; | 596 std::string new_network; |
| 760 if (active_network) | 597 if (active_network) |
| 761 new_network = active_network->service_path(); | 598 new_network = active_network->service_path(); |
| 762 | 599 |
| 763 if (active_network_ == new_network) { // Same active network. | 600 if (active_network_ == new_network) { // Same active network. |
| 764 VLOG(1) << "same active network: " | 601 VLOG(1) << this << ": same active network: " |
| 765 << (new_network.empty() ? "empty" : | 602 << (new_network.empty() ? "empty" : |
| 766 (active_network->name().empty() ? | 603 (active_network->name().empty() ? |
| 767 new_network : active_network->name())); | 604 new_network : active_network->name())); |
| 605 // If last proxy update to network stack wasn't completed, do it now. | |
| 606 if (active_network && update_pending()) | |
| 607 DetermineEffectiveConfig(active_network, true); | |
| 768 return; | 608 return; |
| 769 } | 609 } |
| 770 | 610 |
| 771 // If there was a previous active network, remove it as observer. | 611 // If there was a previous active network, remove it as observer. |
| 772 if (!active_network_.empty()) | 612 if (!active_network_.empty()) |
| 773 network_lib->RemoveNetworkObserver(active_network_, this); | 613 network_lib->RemoveNetworkObserver(active_network_, this); |
| 774 | 614 |
| 775 active_network_ = new_network; | 615 active_network_ = new_network; |
| 776 | 616 |
| 777 if (active_network_.empty()) { | 617 if (active_network_.empty()) { |
| 778 VLOG(1) << "new active network: empty"; | 618 VLOG(1) << this << ": new active network: empty"; |
| 779 active_config_ = ProxyConfig(); | 619 DetermineEffectiveConfig(active_network, true); |
| 780 IOSetProxyConfig(active_config_, net::ProxyConfigService::CONFIG_UNSET); | |
| 781 return; | 620 return; |
| 782 } | 621 } |
| 783 | 622 |
| 784 VLOG(1) << "new active network: path=" << active_network->service_path() | 623 VLOG(1) << this << ": new active network: path=" |
| 785 << ", name=" << active_network->name() | 624 << active_network->service_path() |
| 786 << ", profile=" << active_network->profile_path() | 625 << ", name=" << active_network->name() |
| 787 << ", proxy=" << active_network->proxy_config(); | 626 << ", profile=" << active_network->profile_path() |
| 627 << ", proxy=" << active_network->proxy_config(); | |
| 788 | 628 |
| 789 // Register observer for new network. | 629 // Register observer for new network. |
| 790 network_lib->AddNetworkObserver(active_network_, this); | 630 network_lib->AddNetworkObserver(active_network_, this); |
| 791 | 631 |
| 792 // If necessary, migrate config to flimflam. | 632 // If necessary, migrate config to flimflam. |
| 793 if (active_network->proxy_config().empty() && !device_config_.empty()) { | 633 if (active_network->proxy_config().empty() && !device_config_.empty()) { |
| 794 VLOG(1) << "try migrating device config to " << active_network_; | 634 VLOG(1) << this << ": try migrating device config to " << active_network_; |
| 795 SetProxyConfigForNetwork(active_network_, device_config_, true); | 635 SetProxyConfigForNetwork(active_network_, device_config_, true); |
| 796 } else { | 636 } else { |
| 797 DetermineConfigFromNetwork(active_network); | 637 // Otherwise, determine and activate possibly new effective proxy config. |
| 638 DetermineEffectiveConfig(active_network, true); | |
| 798 } | 639 } |
| 799 } | 640 } |
| 800 | 641 |
| 801 void ProxyConfigServiceImpl::SetProxyConfigForNetwork( | 642 void ProxyConfigServiceImpl::SetProxyConfigForNetwork( |
| 802 const std::string& network_path, const std::string& value, | 643 const std::string& network_path, const std::string& value, |
| 803 bool only_set_if_empty) { | 644 bool only_set_if_empty) { |
| 804 Network* network = CrosLibrary::Get()->GetNetworkLibrary()->FindNetworkByPath( | 645 Network* network = CrosLibrary::Get()->GetNetworkLibrary()->FindNetworkByPath( |
| 805 network_path); | 646 network_path); |
| 806 if (!network) { | 647 if (!network) { |
| 807 NOTREACHED() << "can't find requested network " << network_path; | 648 NOTREACHED() << "can't find requested network " << network_path; |
| 808 return; | 649 return; |
| 809 } | 650 } |
| 810 if (!only_set_if_empty || network->proxy_config().empty()) { | 651 if (!only_set_if_empty || network->proxy_config().empty()) { |
| 811 network->SetProxyConfig(value); | 652 network->SetProxyConfig(value); |
| 812 VLOG(1) << "set proxy for " | 653 VLOG(1) << this << ": set proxy for " << (network->name().empty() ? |
| 813 << (network->name().empty() ? network_path : network->name()) | 654 network_path : network->name()) |
| 814 << ", value=" << value; | 655 << ", value=" << value; |
| 815 if (network_path == active_network_) | 656 if (network_path == active_network_) |
| 816 DetermineConfigFromNetwork(network); | 657 DetermineEffectiveConfig(network, true); |
| 817 } | 658 } |
| 818 } | 659 } |
| 819 | 660 |
| 820 void ProxyConfigServiceImpl::DetermineConfigFromNetwork( | 661 bool ProxyConfigServiceImpl::GetUseSharedProxies() { |
| 821 const Network* network) { | 662 const PrefService::Preference* use_shared_proxies_pref = |
| 822 active_config_ = ProxyConfig(); // Default is DIRECT mode (i.e. no proxy). | 663 prefs()->FindPreference(prefs::kUseSharedProxies); |
| 823 net::ProxyConfigService::ConfigAvailability available = | 664 if (!use_shared_proxies_pref || use_shared_proxies_pref->IsDefaultValue()) |
| 824 net::ProxyConfigService::CONFIG_UNSET; | 665 return !UserManager::Get()->user_is_logged_in(); |
| 825 // If network is shared but user doesn't use shared proxies, use direct mode. | 666 return use_shared_proxies_.GetValue(); |
| 826 if (network->profile_type() == PROFILE_SHARED && !use_shared_proxies_) { | |
| 827 VLOG(1) << "shared network and !use_shared_proxies, using direct"; | |
| 828 available = net::ProxyConfigService::CONFIG_VALID; | |
| 829 } else if (!network->proxy_config().empty() && | |
| 830 active_config_.DeserializeForNetwork(network->proxy_config())) { | |
| 831 // Network is private or shared with user using shared proxies. | |
| 832 VLOG(1) << "using network proxy: " << network->proxy_config(); | |
| 833 available = net::ProxyConfigService::CONFIG_VALID; | |
| 834 } | |
| 835 IOSetProxyConfig(active_config_, available); | |
| 836 } | 667 } |
| 837 | 668 |
| 838 void ProxyConfigServiceImpl::SetCurrentNetworkName(const Network* network) { | 669 void ProxyConfigServiceImpl::DetermineEffectiveConfig(const Network* network, |
| 839 if (!network) { | 670 bool activate) { |
| 840 if (testing_) | 671 // Get prefs proxy config if available. |
| 841 current_ui_network_name_ = "test"; | 672 net::ProxyConfig pref_config; |
| 842 return; | 673 ProxyPrefs::ConfigState pref_state = GetProxyConfig(&pref_config); |
| 674 | |
| 675 // Get network proxy config if available. | |
| 676 net::ProxyConfig network_config; | |
| 677 net::ProxyConfigService::ConfigAvailability network_availability = | |
| 678 net::ProxyConfigService::CONFIG_UNSET; | |
| 679 bool ignore_proxy = activate; | |
| 680 if (network) { | |
| 681 // If we're activating proxy, ignore proxy if necessary; | |
| 682 // otherwise, for ui, get actual proxy to show user. | |
| 683 ignore_proxy = activate ? IgnoreProxy(network) : false; | |
| 684 // If network is shared but use-shared-proxies is off, use direct mode. | |
| 685 if (ignore_proxy) { | |
| 686 VLOG(1) << this << ": shared network && !use-shared-proxies, use direct"; | |
| 687 network_availability = net::ProxyConfigService::CONFIG_VALID; | |
| 688 } else if (!network->proxy_config().empty()) { | |
| 689 // Network is private or shared with user using shared proxies. | |
| 690 JSONStringValueSerializer serializer(network->proxy_config()); | |
| 691 scoped_ptr<Value> value(serializer.Deserialize(NULL, NULL)); | |
| 692 if (value.get() && value->GetType() == Value::TYPE_DICTIONARY) { | |
| 693 DictionaryValue* dict = static_cast<DictionaryValue*>(value.get()); | |
| 694 ProxyConfigDictionary proxy_dict(dict); | |
| 695 if (PrefConfigToNetConfig(proxy_dict, &network_config)) { | |
| 696 VLOG(1) << this << ": using network proxy: " | |
| 697 << network->proxy_config(); | |
| 698 network_availability = net::ProxyConfigService::CONFIG_VALID; | |
| 699 } | |
| 700 } | |
| 701 } | |
| 843 } | 702 } |
| 844 if (network->name().empty() && network->type() == chromeos::TYPE_ETHERNET) { | 703 |
| 845 current_ui_network_name_ = l10n_util::GetStringUTF8( | 704 // Determine effective proxy config, either from prefs or network. |
| 846 IDS_STATUSBAR_NETWORK_DEVICE_ETHERNET); | 705 ProxyPrefs::ConfigState effective_config_state; |
| 847 } else { | 706 net::ProxyConfig effective_config; |
| 848 current_ui_network_name_ = network->name(); | 707 GetEffectiveProxyConfig(pref_state, pref_config, |
| 708 network_availability, network_config, ignore_proxy, | |
| 709 &effective_config_state, &effective_config); | |
| 710 | |
| 711 // Determine if we should activate effective proxy and which proxy config to | |
| 712 // store it. | |
| 713 if (activate) { // Activate effective proxy and store into |active_config_|. | |
| 714 // If last update didn't complete, we definitely update now. | |
| 715 bool update_now = update_pending(); | |
| 716 if (!update_now) { // Otherwise, only update now if there're changes. | |
| 717 update_now = active_config_state_ != effective_config_state || | |
| 718 (active_config_state_ != ProxyPrefs::CONFIG_UNSET && | |
| 719 !active_config_.Equals(effective_config)); | |
| 720 } | |
| 721 if (update_now) { // Activate and store new effective config. | |
| 722 active_config_state_ = effective_config_state; | |
| 723 if (active_config_state_ != ProxyPrefs::CONFIG_UNSET) | |
| 724 active_config_ = effective_config; | |
| 725 // If effective config is from system (i.e. network), it's considered a | |
| 726 // special kind of prefs that ranks below policy/extension but above | |
| 727 // others, so bump it up to CONFIG_OTHER_PRECEDE to force its precedence | |
| 728 // when PrefProxyConfigTrackerImpl pushes it to ChromeProxyConfigService. | |
| 729 if (effective_config_state == ProxyPrefs::CONFIG_SYSTEM) | |
| 730 effective_config_state = ProxyPrefs::CONFIG_OTHER_PRECEDE; | |
| 731 // If config is manual, add rule to bypass local host. | |
| 732 if (effective_config.proxy_rules().type != | |
| 733 net::ProxyConfig::ProxyRules::TYPE_NO_RULES) | |
| 734 effective_config.proxy_rules().bypass_rules.AddRuleToBypassLocal(); | |
| 735 PrefProxyConfigTrackerImpl::OnProxyConfigChanged(effective_config_state, | |
| 736 effective_config); | |
| 737 if (VLOG_IS_ON(1) && !update_pending()) { // Update was successful. | |
| 738 scoped_ptr<DictionaryValue> config_dict(static_cast<DictionaryValue*>( | |
| 739 effective_config.ToValue())); | |
| 740 std::string config_value; | |
| 741 JSONStringValueSerializer serializer(&config_value); | |
| 742 serializer.Serialize(*config_dict.get()); | |
| 743 VLOG(1) << this << ": Proxy changed: " | |
| 744 << ConfigStateToString(active_config_state_) | |
| 745 << ", " << config_value; | |
| 746 } | |
| 747 } | |
| 748 } else { // For UI, store effective proxy into |current_ui_config_|. | |
| 749 current_ui_config_.FromNetProxyConfig(effective_config); | |
| 750 current_ui_config_.state = effective_config_state; | |
| 751 if (PrefPrecedes(effective_config_state)) | |
| 752 current_ui_config_.user_modifiable = false; | |
| 753 else | |
| 754 current_ui_config_.user_modifiable = !network || !IgnoreProxy(network); | |
| 849 } | 755 } |
| 850 } | 756 } |
| 851 | 757 |
| 852 void ProxyConfigServiceImpl::CheckCurrentlyOnIOThread() { | 758 void ProxyConfigServiceImpl::OnUISetCurrentNetwork(const Network* network) { |
| 853 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 759 DetermineEffectiveConfig(network, false); |
| 760 VLOG(1) << this << ": current ui network: " | |
| 761 << (network->name().empty() ? | |
| 762 current_ui_network_ : network->name()) | |
| 763 << ", " << ModeToString(current_ui_config_.mode) | |
| 764 << ", " << ConfigStateToString(current_ui_config_.state) | |
| 765 << ", modifiable:" << current_ui_config_.user_modifiable; | |
| 854 } | 766 } |
| 855 | 767 |
| 856 void ProxyConfigServiceImpl::CheckCurrentlyOnUIThread() { | 768 void ProxyConfigServiceImpl::ResetUICache() { |
| 857 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 769 current_ui_network_.clear(); |
| 770 current_ui_config_ = ProxyConfig(); | |
| 858 } | 771 } |
| 859 | 772 |
| 860 } // namespace chromeos | 773 } // namespace chromeos |
| OLD | NEW |