Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(260)

Side by Side Diff: chrome/browser/chromeos/proxy_config_service_impl.cc

Issue 8102019: redesign and reimplement proxy config service and tracker, revise proxy ui on cros (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/proxy_config_service_impl.h ('k') | chrome/browser/chromeos/proxy_config_service_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698