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