OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 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> | |
8 | |
9 #include "base/bind.h" | 7 #include "base/bind.h" |
10 #include "base/json/json_string_value_serializer.h" | |
11 #include "base/logging.h" | 8 #include "base/logging.h" |
12 #include "base/prefs/pref_registry_simple.h" | 9 #include "base/prefs/pref_registry_simple.h" |
13 #include "base/prefs/pref_service.h" | 10 #include "base/prefs/pref_service.h" |
14 #include "base/string_util.h" | 11 #include "base/values.h" |
15 #include "chrome/browser/browser_process.h" | 12 #include "chrome/browser/browser_process.h" |
16 #include "chrome/browser/chromeos/cros/cros_library.h" | 13 #include "chrome/browser/chromeos/cros/cros_library.h" |
17 #include "chrome/browser/chromeos/cros/network_property_ui_data.h" | 14 #include "chrome/browser/chromeos/cros/network_library.h" |
18 #include "chrome/browser/chromeos/login/user_manager.h" | 15 #include "chrome/browser/chromeos/login/user_manager.h" |
19 #include "chrome/browser/chromeos/settings/cros_settings.h" | 16 #include "chrome/browser/chromeos/settings/cros_settings.h" |
20 #include "chrome/browser/chromeos/settings/cros_settings_names.h" | 17 #include "chrome/browser/chromeos/settings/cros_settings_names.h" |
21 #include "chrome/browser/policy/browser_policy_connector.h" | 18 #include "chrome/browser/policy/browser_policy_connector.h" |
22 #include "chrome/browser/policy/cloud/cloud_policy_constants.h" | 19 #include "chrome/browser/policy/cloud/cloud_policy_constants.h" |
23 #include "chrome/browser/policy/proto/chromeos/chrome_device_policy.pb.h" | |
24 #include "chrome/browser/prefs/proxy_config_dictionary.h" | 20 #include "chrome/browser/prefs/proxy_config_dictionary.h" |
25 #include "chrome/browser/prefs/proxy_prefs.h" | 21 #include "chrome/browser/prefs/proxy_prefs.h" |
26 #include "chrome/browser/profiles/profile_manager.h" | |
27 #include "chrome/common/chrome_notification_types.h" | |
28 #include "chrome/common/pref_names.h" | 22 #include "chrome/common/pref_names.h" |
29 #include "chromeos/network/network_ui_data.h" | 23 #include "chromeos/network/network_profile.h" |
30 #include "chromeos/network/onc/onc_constants.h" | 24 #include "chromeos/network/network_profile_handler.h" |
25 #include "chromeos/network/network_state.h" | |
26 #include "chromeos/network/network_state_handler.h" | |
27 #include "chromeos/network/onc/onc_utils.h" | |
31 #include "components/user_prefs/pref_registry_syncable.h" | 28 #include "components/user_prefs/pref_registry_syncable.h" |
32 #include "content/public/browser/notification_service.h" | |
33 #include "grit/generated_resources.h" | |
34 #include "ui/base/l10n/l10n_util.h" | |
35 | |
36 namespace em = enterprise_management; | |
37 | 29 |
38 namespace chromeos { | 30 namespace chromeos { |
39 | 31 |
40 namespace { | 32 namespace { |
41 | 33 |
42 // Shoud we try to push this to base? | 34 // Convert and store the proxy config of |pref_proxy_config| of |
43 // Helper comparator functor for the find_if call in |findIfEqual| | 35 // ProxyConfigDictionary format to |proxy_config|. Returns true if |
44 template <class T> | 36 // |pref_proxy_config| was not empty and if it was successfully converted. |
45 class EqualsComparator{ | 37 bool ParseProxyConfig(const base::DictionaryValue& pref_proxy_config, |
46 public: | 38 net::ProxyConfig* proxy_config) { |
47 explicit EqualsComparator(const T& key) : key_(key) { } | 39 if (pref_proxy_config.empty()) |
48 bool operator() (const T& element) { | 40 return false; |
49 return element.Equals(key_); | |
50 } | |
51 private: | |
52 const T& key_; | |
53 }; | |
54 | 41 |
55 // Tiny STL helper function to allow using the find_if syntax on objects that | 42 ProxyConfigDictionary proxy_dict(&pref_proxy_config); |
56 // doesn't use the operator== but implement the Equals function which is the | 43 return PrefProxyConfigTrackerImpl::PrefConfigToNetConfig(proxy_dict, |
57 // quasi standard with the coding style we have. | 44 proxy_config); |
58 template<class InputIterator, class T> | |
59 InputIterator findIfEqual(InputIterator first, InputIterator last, | |
60 const T& key) { | |
61 return std::find_if(first, last, EqualsComparator<T>(key)); | |
62 } | 45 } |
63 | 46 |
64 const char* ModeToString(ProxyConfigServiceImpl::ProxyConfig::Mode mode) { | |
65 switch (mode) { | |
66 case ProxyConfigServiceImpl::ProxyConfig::MODE_DIRECT: | |
67 return "direct"; | |
68 case ProxyConfigServiceImpl::ProxyConfig::MODE_AUTO_DETECT: | |
69 return "auto-detect"; | |
70 case ProxyConfigServiceImpl::ProxyConfig::MODE_PAC_SCRIPT: | |
71 return "pacurl"; | |
72 case ProxyConfigServiceImpl::ProxyConfig::MODE_SINGLE_PROXY: | |
73 return "single-proxy"; | |
74 case ProxyConfigServiceImpl::ProxyConfig::MODE_PROXY_PER_SCHEME: | |
75 return "proxy-per-scheme"; | |
76 } | |
77 NOTREACHED() << "Unrecognized mode type"; | |
78 return ""; | |
79 } | |
80 | |
81 const char* ConfigStateToString(ProxyPrefs::ConfigState state) { | |
82 switch (state) { | |
83 case ProxyPrefs::CONFIG_POLICY: | |
84 return "config_policy"; | |
85 case ProxyPrefs::CONFIG_EXTENSION: | |
86 return "config_extension"; | |
87 case ProxyPrefs::CONFIG_OTHER_PRECEDE: | |
88 return "config_other_precede"; | |
89 case ProxyPrefs::CONFIG_SYSTEM: | |
90 return "config_network"; // For ChromeOS, system is network. | |
91 case ProxyPrefs::CONFIG_FALLBACK: | |
92 return "config_recommended"; // Fallback is recommended. | |
93 case ProxyPrefs::CONFIG_UNSET: | |
94 return "config_unset"; | |
95 } | |
96 NOTREACHED() << "Unrecognized config state type"; | |
97 return ""; | |
98 } | |
99 | |
100 // Returns true if proxy settings from |network| is editable. | |
101 bool IsNetworkProxySettingsEditable(const Network* network) { | |
102 if (!network) | |
103 return true; // editable if no network given. | |
104 | |
105 NetworkLibrary* network_library = CrosLibrary::Get()->GetNetworkLibrary(); | |
106 const base::DictionaryValue* onc = | |
107 network_library->FindOncForNetwork(network->unique_id()); | |
108 | |
109 NetworkPropertyUIData proxy_settings_ui_data; | |
110 proxy_settings_ui_data.ParseOncProperty( | |
111 network->ui_data(), | |
112 onc, | |
113 onc::network_config::kProxySettings); | |
114 return proxy_settings_ui_data.editable(); | |
115 } | |
116 | |
117 // Only unblock if needed for debugging. | |
118 #if defined(NEED_DEBUG_LOG) | |
119 std::ostream& operator<<( | |
120 std::ostream& out, | |
121 const ProxyConfigServiceImpl::ProxyConfig::ManualProxy& proxy) { | |
122 out << (proxy.server.is_valid() ? proxy.server.ToURI() : "") << "\n"; | |
123 return out; | |
124 } | |
125 | |
126 std::ostream& operator<<(std::ostream& out, | |
127 const ProxyConfigServiceImpl::ProxyConfig& config) { | |
128 switch (config.mode) { | |
129 case ProxyConfigServiceImpl::ProxyConfig::MODE_DIRECT: | |
130 case ProxyConfigServiceImpl::ProxyConfig::MODE_AUTO_DETECT: | |
131 out << ModeToString(config.mode) << ", " | |
132 << ConfigStateToString(config.state) << "\n"; | |
133 break; | |
134 case ProxyConfigServiceImpl::ProxyConfig::MODE_PAC_SCRIPT: | |
135 out << ModeToString(config.mode) << ", " | |
136 << ConfigStateToString(config.state) | |
137 << "\n PAC: " << config.automatic_proxy.pac_url << "\n"; | |
138 break; | |
139 case ProxyConfigServiceImpl::ProxyConfig::MODE_SINGLE_PROXY: | |
140 out << ModeToString(config.mode) << ", " | |
141 << ConfigStateToString(config.state) << "\n " << config.single_proxy; | |
142 break; | |
143 case ProxyConfigServiceImpl::ProxyConfig::MODE_PROXY_PER_SCHEME: | |
144 out << ModeToString(config.mode) << ", " | |
145 << ConfigStateToString(config.state) << "\n" | |
146 << " HTTP: " << config.http_proxy | |
147 << " HTTPS: " << config.https_proxy | |
148 << " FTP: " << config.ftp_proxy | |
149 << " SOCKS: " << config.socks_proxy; | |
150 break; | |
151 default: | |
152 NOTREACHED() << "Unrecognized proxy config mode"; | |
153 break; | |
154 } | |
155 if (config.mode == ProxyConfigServiceImpl::ProxyConfig::MODE_SINGLE_PROXY || | |
156 config.mode == | |
157 ProxyConfigServiceImpl::ProxyConfig::MODE_PROXY_PER_SCHEME) { | |
158 out << "Bypass list: "; | |
159 if (config.bypass_rules.rules().empty()) { | |
160 out << "[None]"; | |
161 } else { | |
162 const net::ProxyBypassRules& bypass_rules = config.bypass_rules; | |
163 net::ProxyBypassRules::RuleList::const_iterator it; | |
164 for (it = bypass_rules.rules().begin(); | |
165 it != bypass_rules.rules().end(); ++it) { | |
166 out << "\n " << (*it)->ToString(); | |
167 } | |
168 } | |
169 } | |
170 return out; | |
171 } | |
172 | |
173 std::string ProxyConfigToString( | |
174 const ProxyConfigServiceImpl::ProxyConfig& proxy_config) { | |
175 std::ostringstream stream; | |
176 stream << proxy_config; | |
177 return stream.str(); | |
178 } | |
179 #endif // defined(NEED_DEBUG_LOG) | |
180 | |
181 } // namespace | 47 } // namespace |
182 | 48 |
183 //----------- ProxyConfigServiceImpl::ProxyConfig: public methods -------------- | |
184 | |
185 ProxyConfigServiceImpl::ProxyConfig::ProxyConfig() | |
186 : mode(MODE_DIRECT), | |
187 state(ProxyPrefs::CONFIG_UNSET), | |
188 user_modifiable(true) {} | |
189 | |
190 ProxyConfigServiceImpl::ProxyConfig::~ProxyConfig() {} | |
191 | |
192 bool ProxyConfigServiceImpl::ProxyConfig::FromNetProxyConfig( | |
193 const net::ProxyConfig& net_config) { | |
194 *this = ProxyConfigServiceImpl::ProxyConfig(); // Reset to default. | |
195 const net::ProxyConfig::ProxyRules& rules = net_config.proxy_rules(); | |
196 switch (rules.type) { | |
197 case net::ProxyConfig::ProxyRules::TYPE_NO_RULES: | |
198 if (!net_config.HasAutomaticSettings()) { | |
199 mode = ProxyConfig::MODE_DIRECT; | |
200 } else if (net_config.auto_detect()) { | |
201 mode = ProxyConfig::MODE_AUTO_DETECT; | |
202 } else if (net_config.has_pac_url()) { | |
203 mode = ProxyConfig::MODE_PAC_SCRIPT; | |
204 automatic_proxy.pac_url = net_config.pac_url(); | |
205 } else { | |
206 return false; | |
207 } | |
208 return true; | |
209 case net::ProxyConfig::ProxyRules::TYPE_SINGLE_PROXY: | |
210 if (rules.single_proxies.IsEmpty()) | |
211 return false; | |
212 mode = MODE_SINGLE_PROXY; | |
213 single_proxy.server = rules.single_proxies.Get(); | |
214 bypass_rules = rules.bypass_rules; | |
215 return true; | |
216 case net::ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME: | |
217 // Make sure we have valid server for at least one of the protocols. | |
218 if (rules.proxies_for_http.IsEmpty() && | |
219 rules.proxies_for_https.IsEmpty() && | |
220 rules.proxies_for_ftp.IsEmpty() && | |
221 rules.fallback_proxies.IsEmpty()) { | |
222 return false; | |
223 } | |
224 mode = MODE_PROXY_PER_SCHEME; | |
225 if (!rules.proxies_for_http.IsEmpty()) | |
226 http_proxy.server = rules.proxies_for_http.Get(); | |
227 if (!rules.proxies_for_https.IsEmpty()) | |
228 https_proxy.server = rules.proxies_for_https.Get(); | |
229 if (!rules.proxies_for_ftp.IsEmpty()) | |
230 ftp_proxy.server = rules.proxies_for_ftp.Get(); | |
231 if (!rules.fallback_proxies.IsEmpty()) | |
232 socks_proxy.server = rules.fallback_proxies.Get(); | |
233 bypass_rules = rules.bypass_rules; | |
234 return true; | |
235 default: | |
236 NOTREACHED() << "Unrecognized proxy config mode"; | |
237 break; | |
238 } | |
239 return false; | |
240 } | |
241 | |
242 DictionaryValue* ProxyConfigServiceImpl::ProxyConfig::ToPrefProxyConfig() { | |
243 switch (mode) { | |
244 case MODE_DIRECT: { | |
245 return ProxyConfigDictionary::CreateDirect(); | |
246 } | |
247 case MODE_AUTO_DETECT: { | |
248 return ProxyConfigDictionary::CreateAutoDetect(); | |
249 } | |
250 case MODE_PAC_SCRIPT: { | |
251 return ProxyConfigDictionary::CreatePacScript( | |
252 automatic_proxy.pac_url.spec(), false); | |
253 } | |
254 case MODE_SINGLE_PROXY: { | |
255 std::string spec; | |
256 if (single_proxy.server.is_valid()) | |
257 spec = single_proxy.server.ToURI(); | |
258 return ProxyConfigDictionary::CreateFixedServers( | |
259 spec, bypass_rules.ToString()); | |
260 } | |
261 case MODE_PROXY_PER_SCHEME: { | |
262 std::string spec; | |
263 EncodeAndAppendProxyServer("http", http_proxy.server, &spec); | |
264 EncodeAndAppendProxyServer("https", https_proxy.server, &spec); | |
265 EncodeAndAppendProxyServer("ftp", ftp_proxy.server, &spec); | |
266 EncodeAndAppendProxyServer("socks", socks_proxy.server, &spec); | |
267 return ProxyConfigDictionary::CreateFixedServers( | |
268 spec, bypass_rules.ToString()); | |
269 } | |
270 default: | |
271 break; | |
272 } | |
273 NOTREACHED() << "Unrecognized proxy config mode for preference"; | |
274 return NULL; | |
275 } | |
276 | |
277 ProxyConfigServiceImpl::ProxyConfig::ManualProxy* | |
278 ProxyConfigServiceImpl::ProxyConfig::MapSchemeToProxy( | |
279 const std::string& scheme) { | |
280 if (scheme == "http") | |
281 return &http_proxy; | |
282 if (scheme == "https") | |
283 return &https_proxy; | |
284 if (scheme == "ftp") | |
285 return &ftp_proxy; | |
286 if (scheme == "socks") | |
287 return &socks_proxy; | |
288 NOTREACHED() << "Invalid scheme: " << scheme; | |
289 return NULL; | |
290 } | |
291 | |
292 bool ProxyConfigServiceImpl::ProxyConfig::DeserializeForDevice( | |
293 const std::string& input) { | |
294 em::DeviceProxySettingsProto proxy_proto; | |
295 if (!proxy_proto.ParseFromString(input)) | |
296 return false; | |
297 | |
298 const std::string& mode_string(proxy_proto.proxy_mode()); | |
299 if (mode_string == ProxyPrefs::kDirectProxyModeName) { | |
300 mode = MODE_DIRECT; | |
301 } else if (mode_string == ProxyPrefs::kAutoDetectProxyModeName) { | |
302 mode = MODE_AUTO_DETECT; | |
303 } else if (mode_string == ProxyPrefs::kPacScriptProxyModeName) { | |
304 mode = MODE_PAC_SCRIPT; | |
305 if (proxy_proto.has_proxy_pac_url()) | |
306 automatic_proxy.pac_url = GURL(proxy_proto.proxy_pac_url()); | |
307 } else if (mode_string == ProxyPrefs::kFixedServersProxyModeName) { | |
308 net::ProxyConfig::ProxyRules rules; | |
309 rules.ParseFromString(proxy_proto.proxy_server()); | |
310 switch (rules.type) { | |
311 case net::ProxyConfig::ProxyRules::TYPE_NO_RULES: | |
312 return false; | |
313 case net::ProxyConfig::ProxyRules::TYPE_SINGLE_PROXY: | |
314 if (rules.single_proxies.IsEmpty()) | |
315 return false; | |
316 mode = MODE_SINGLE_PROXY; | |
317 single_proxy.server = rules.single_proxies.Get(); | |
318 return true; | |
319 case net::ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME: | |
320 // Make sure we have valid server for at least one of the protocols. | |
321 if (rules.proxies_for_http.IsEmpty() && | |
322 rules.proxies_for_https.IsEmpty() && | |
323 rules.proxies_for_ftp.IsEmpty() && | |
324 rules.fallback_proxies.IsEmpty()) { | |
325 return false; | |
326 } | |
327 mode = MODE_PROXY_PER_SCHEME; | |
328 if (!rules.proxies_for_http.IsEmpty()) | |
329 http_proxy.server = rules.proxies_for_http.Get(); | |
330 if (!rules.proxies_for_https.IsEmpty()) | |
331 https_proxy.server = rules.proxies_for_https.Get(); | |
332 if (!rules.proxies_for_ftp.IsEmpty()) | |
333 ftp_proxy.server = rules.proxies_for_ftp.Get(); | |
334 if (!rules.fallback_proxies.IsEmpty()) | |
335 socks_proxy.server = rules.fallback_proxies.Get(); | |
336 break; | |
337 } | |
338 } else { | |
339 NOTREACHED() << "Unrecognized proxy config mode"; | |
340 return false; | |
341 } | |
342 | |
343 if (proxy_proto.has_proxy_bypass_list()) | |
344 bypass_rules.ParseFromString(proxy_proto.proxy_bypass_list()); | |
345 | |
346 return true; | |
347 } | |
348 | |
349 bool ProxyConfigServiceImpl::ProxyConfig::SerializeForNetwork( | |
350 std::string* output) { | |
351 scoped_ptr<DictionaryValue> proxy_dict_ptr(ToPrefProxyConfig()); | |
352 if (!proxy_dict_ptr.get()) | |
353 return false; | |
354 | |
355 // Return empty string for direct mode for portal check to work correctly. | |
356 DictionaryValue *dict = proxy_dict_ptr.get(); | |
357 ProxyConfigDictionary proxy_dict(dict); | |
358 ProxyPrefs::ProxyMode mode; | |
359 if (proxy_dict.GetMode(&mode)) { | |
360 if (mode == ProxyPrefs::MODE_DIRECT) { | |
361 output->clear(); | |
362 return true; | |
363 } | |
364 } | |
365 JSONStringValueSerializer serializer(output); | |
366 return serializer.Serialize(*dict); | |
367 } | |
368 | |
369 //----------- ProxyConfigServiceImpl::ProxyConfig: private methods ------------- | |
370 | |
371 // static | |
372 void ProxyConfigServiceImpl::ProxyConfig::EncodeAndAppendProxyServer( | |
373 const std::string& url_scheme, | |
374 const net::ProxyServer& server, | |
375 std::string* spec) { | |
376 if (!server.is_valid()) | |
377 return; | |
378 | |
379 if (!spec->empty()) | |
380 *spec += ';'; | |
381 | |
382 if (!url_scheme.empty()) { | |
383 *spec += url_scheme; | |
384 *spec += "="; | |
385 } | |
386 *spec += server.ToURI(); | |
387 } | |
388 | |
389 //------------------- ProxyConfigServiceImpl: public methods ------------------- | |
390 | |
391 ProxyConfigServiceImpl::ProxyConfigServiceImpl(PrefService* pref_service) | 49 ProxyConfigServiceImpl::ProxyConfigServiceImpl(PrefService* pref_service) |
392 : PrefProxyConfigTrackerImpl(pref_service), | 50 : PrefProxyConfigTrackerImpl(pref_service), |
393 active_config_state_(ProxyPrefs::CONFIG_UNSET), | 51 active_config_state_(ProxyPrefs::CONFIG_UNSET), |
52 ui_proxy_config_service_(pref_service), | |
394 pointer_factory_(this) { | 53 pointer_factory_(this) { |
395 | 54 |
396 // Register for notifications of UseSharedProxies user preference. | 55 // Register for notifications of UseSharedProxies user preference. |
397 if (pref_service->FindPreference(prefs::kUseSharedProxies)) { | 56 if (pref_service->FindPreference(prefs::kUseSharedProxies)) { |
398 use_shared_proxies_.Init( | 57 use_shared_proxies_.Init( |
399 prefs::kUseSharedProxies, pref_service, | 58 prefs::kUseSharedProxies, pref_service, |
400 base::Bind(&ProxyConfigServiceImpl::OnUseSharedProxiesChanged, | 59 base::Bind(&ProxyConfigServiceImpl::OnUseSharedProxiesChanged, |
401 base::Unretained(this))); | 60 base::Unretained(this))); |
402 } | 61 } |
403 | 62 |
404 FetchProxyPolicy(); | 63 FetchDeviceProxySetting(); |
405 | 64 |
406 // Register for shill network notifications. | 65 // Register for changes to the default network. |
407 NetworkLibrary* network_lib = CrosLibrary::Get()->GetNetworkLibrary(); | 66 NetworkStateHandler* state_handler = NetworkStateHandler::Get(); |
408 OnActiveNetworkChanged(network_lib, network_lib->active_network()); | 67 state_handler->AddObserver(this); |
409 network_lib->AddNetworkManagerObserver(this); | 68 DefaultNetworkChanged(state_handler->DefaultNetwork()); |
410 } | 69 } |
411 | 70 |
412 ProxyConfigServiceImpl::~ProxyConfigServiceImpl() { | 71 ProxyConfigServiceImpl::~ProxyConfigServiceImpl() { |
413 NetworkLibrary* netlib = CrosLibrary::Get()->GetNetworkLibrary(); | 72 NetworkStateHandler::Get()->RemoveObserver(this); |
stevenjb
2013/05/15 17:44:14
Test NetworkStateHandler::IsInitialized() here. (T
pneubeck (no reviews)
2013/05/15 20:24:48
Done.
| |
414 if (netlib) { | |
415 netlib->RemoveNetworkManagerObserver(this); | |
416 netlib->RemoveObserverForAllNetworks(this); | |
417 } | |
418 } | 73 } |
419 | 74 |
420 void ProxyConfigServiceImpl::UISetCurrentNetwork( | 75 UIProxyConfigService& ProxyConfigServiceImpl::GetUIService() { |
421 const std::string& current_network) { | 76 return ui_proxy_config_service_; |
422 Network* network = CrosLibrary::Get()->GetNetworkLibrary()->FindNetworkByPath( | |
423 current_network); | |
424 if (!network) { | |
425 ResetUICache(); | |
426 LOG(ERROR) << "Can't find requested network " << current_network; | |
427 return; | |
428 } | |
429 current_ui_network_ = current_network; | |
430 OnUISetCurrentNetwork(network); | |
431 } | |
432 | |
433 void ProxyConfigServiceImpl::UIMakeActiveNetworkCurrent() { | |
434 Network* network = CrosLibrary::Get()->GetNetworkLibrary()->FindNetworkByPath( | |
435 active_network_); | |
436 if (!network) { | |
437 ResetUICache(); | |
438 LOG(ERROR) << "Can't find requested network " << active_network_; | |
439 return; | |
440 } | |
441 current_ui_network_ = active_network_; | |
442 OnUISetCurrentNetwork(network); | |
443 } | |
444 | |
445 void ProxyConfigServiceImpl::UIGetCurrentNetworkName( | |
446 std::string* network_name) { | |
447 if (!network_name) | |
448 return; | |
449 network_name->clear(); | |
450 Network* network = CrosLibrary::Get()->GetNetworkLibrary()->FindNetworkByPath( | |
451 current_ui_network_); | |
452 if (!network) { | |
453 LOG(ERROR) << "Can't find requested network " << current_ui_network_; | |
454 return; | |
455 } | |
456 if (network->name().empty() && network->type() == chromeos::TYPE_ETHERNET) { | |
457 *network_name = | |
458 l10n_util::GetStringUTF8(IDS_STATUSBAR_NETWORK_DEVICE_ETHERNET); | |
459 } else { | |
460 *network_name = network->name(); | |
461 } | |
462 } | |
463 | |
464 void ProxyConfigServiceImpl::UIGetProxyConfig(ProxyConfig* config) { | |
465 // Simply returns the copy last set from UI via UISetCurrentNetwork or | |
466 // UIMakeActiveNetworkCurrent. | |
467 *config = current_ui_config_; | |
468 } | |
469 | |
470 bool ProxyConfigServiceImpl::UISetProxyConfigToDirect() { | |
471 current_ui_config_.mode = ProxyConfig::MODE_DIRECT; | |
472 OnUISetProxyConfig(); | |
473 return true; | |
474 } | |
475 | |
476 bool ProxyConfigServiceImpl::UISetProxyConfigToAutoDetect() { | |
477 current_ui_config_.mode = ProxyConfig::MODE_AUTO_DETECT; | |
478 OnUISetProxyConfig(); | |
479 return true; | |
480 } | |
481 | |
482 bool ProxyConfigServiceImpl::UISetProxyConfigToPACScript(const GURL& pac_url) { | |
483 current_ui_config_.mode = ProxyConfig::MODE_PAC_SCRIPT; | |
484 current_ui_config_.automatic_proxy.pac_url = pac_url; | |
485 OnUISetProxyConfig(); | |
486 return true; | |
487 } | |
488 | |
489 bool ProxyConfigServiceImpl::UISetProxyConfigToSingleProxy( | |
490 const net::ProxyServer& server) { | |
491 current_ui_config_.mode = ProxyConfig::MODE_SINGLE_PROXY; | |
492 current_ui_config_.single_proxy.server = server; | |
493 OnUISetProxyConfig(); | |
494 return true; | |
495 } | |
496 | |
497 bool ProxyConfigServiceImpl::UISetProxyConfigToProxyPerScheme( | |
498 const std::string& scheme, const net::ProxyServer& server) { | |
499 ProxyConfig::ManualProxy* proxy = current_ui_config_.MapSchemeToProxy(scheme); | |
500 if (!proxy) { | |
501 NOTREACHED() << "Cannot set proxy: invalid scheme [" << scheme << "]"; | |
502 return false; | |
503 } | |
504 current_ui_config_.mode = ProxyConfig::MODE_PROXY_PER_SCHEME; | |
505 proxy->server = server; | |
506 OnUISetProxyConfig(); | |
507 return true; | |
508 } | |
509 | |
510 bool ProxyConfigServiceImpl::UISetProxyConfigBypassRules( | |
511 const net::ProxyBypassRules& bypass_rules) { | |
512 if (current_ui_config_.mode != ProxyConfig::MODE_SINGLE_PROXY && | |
513 current_ui_config_.mode != ProxyConfig::MODE_PROXY_PER_SCHEME) { | |
514 NOTREACHED(); | |
515 VLOG(1) << "Cannot set bypass rules for proxy mode [" | |
516 << current_ui_config_.mode << "]"; | |
517 return false; | |
518 } | |
519 current_ui_config_.bypass_rules = bypass_rules; | |
520 OnUISetProxyConfig(); | |
521 return true; | |
522 } | |
523 | |
524 void ProxyConfigServiceImpl::AddNotificationCallback(base::Closure callback) { | |
525 | |
526 std::vector<base::Closure>::iterator iter = | |
527 findIfEqual(callbacks_.begin(), callbacks_.end(), callback); | |
528 if (iter == callbacks_.end()) | |
529 callbacks_.push_back(callback); | |
530 } | |
531 | |
532 void ProxyConfigServiceImpl::RemoveNotificationCallback( | |
533 base::Closure callback) { | |
534 std::vector<base::Closure>::iterator iter = | |
535 findIfEqual(callbacks_.begin(), callbacks_.end(), callback); | |
536 if (iter != callbacks_.end()) | |
537 callbacks_.erase(iter); | |
538 } | 77 } |
539 | 78 |
540 void ProxyConfigServiceImpl::OnProxyConfigChanged( | 79 void ProxyConfigServiceImpl::OnProxyConfigChanged( |
541 ProxyPrefs::ConfigState config_state, | 80 ProxyPrefs::ConfigState config_state, |
542 const net::ProxyConfig& config) { | 81 const net::ProxyConfig& config) { |
543 VLOG(1) << "Got prefs change: " << ConfigStateToString(config_state) | 82 VLOG(1) << "Got prefs change: " |
83 << ProxyPrefs::ConfigStateToString(config_state) | |
544 << ", mode=" << config.proxy_rules().type; | 84 << ", mode=" << config.proxy_rules().type; |
545 Network* network = NULL; | 85 DetermineEffectiveConfigFromDefaultNetwork(); |
546 if (!active_network_.empty()) { | |
547 network = CrosLibrary::Get()->GetNetworkLibrary()->FindNetworkByPath( | |
548 active_network_); | |
549 if (!network) | |
550 LOG(ERROR) << "can't find requested network " << active_network_; | |
551 } | |
552 DetermineEffectiveConfig(network, true); | |
553 } | |
554 | |
555 void ProxyConfigServiceImpl::OnNetworkManagerChanged( | |
556 NetworkLibrary* network_lib) { | |
557 VLOG(1) << "OnNetworkManagerChanged: use-shared-proxies=" | |
558 << GetUseSharedProxies(); | |
559 OnActiveNetworkChanged(network_lib, network_lib->active_network()); | |
560 } | |
561 | |
562 void ProxyConfigServiceImpl::OnNetworkChanged(NetworkLibrary* network_lib, | |
563 const Network* network) { | |
564 if (!network) | |
565 return; | |
566 VLOG(1) << "OnNetworkChanged: " | |
567 << (network->name().empty() ? network->service_path() : | |
568 network->name()) | |
569 << ", use-shared-proxies=" << GetUseSharedProxies(); | |
570 // We only care about active network. | |
571 if (network == network_lib->active_network()) | |
572 OnActiveNetworkChanged(network_lib, network); | |
573 } | 86 } |
574 | 87 |
575 // static | 88 // static |
576 bool ProxyConfigServiceImpl::ParseProxyConfig(const Network* network, | |
577 net::ProxyConfig* proxy_config) { | |
578 if (!network || !proxy_config) | |
579 return false; | |
580 JSONStringValueSerializer serializer(network->proxy_config()); | |
581 scoped_ptr<Value> value(serializer.Deserialize(NULL, NULL)); | |
582 if (!value.get() || value->GetType() != Value::TYPE_DICTIONARY) | |
583 return false; | |
584 ProxyConfigDictionary proxy_dict(static_cast<DictionaryValue*>(value.get())); | |
585 return PrefProxyConfigTrackerImpl::PrefConfigToNetConfig(proxy_dict, | |
586 proxy_config); | |
587 } | |
588 | |
589 // static | |
590 void ProxyConfigServiceImpl::RegisterPrefs(PrefRegistrySimple* registry) { | 89 void ProxyConfigServiceImpl::RegisterPrefs(PrefRegistrySimple* registry) { |
591 // Use shared proxies default to off. GetUseSharedProxies will return the | 90 // Use shared proxies default to off. GetUseSharedProxies will return the |
592 // correct value based on pre-login and login. | 91 // correct value based on pre-login and login. |
593 registry->RegisterBooleanPref(prefs::kUseSharedProxies, true); | 92 registry->RegisterBooleanPref(prefs::kUseSharedProxies, true); |
594 } | 93 } |
595 | 94 |
596 // static | 95 // static |
597 void ProxyConfigServiceImpl::RegisterUserPrefs( | 96 void ProxyConfigServiceImpl::RegisterUserPrefs( |
598 user_prefs::PrefRegistrySyncable* registry) { | 97 user_prefs::PrefRegistrySyncable* registry) { |
599 registry->RegisterBooleanPref( | 98 registry->RegisterBooleanPref( |
600 prefs::kUseSharedProxies, | 99 prefs::kUseSharedProxies, |
601 true, | 100 true, |
602 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); | 101 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); |
603 } | 102 } |
604 | 103 |
605 //------------------ ProxyConfigServiceImpl: private methods ------------------- | |
606 | |
607 void ProxyConfigServiceImpl::OnUseSharedProxiesChanged() { | 104 void ProxyConfigServiceImpl::OnUseSharedProxiesChanged() { |
608 VLOG(1) << "New use-shared-proxies = " << GetUseSharedProxies(); | 105 VLOG(1) << "New use-shared-proxies = " << GetUseSharedProxies(prefs()); |
609 | 106 DetermineEffectiveConfigFromDefaultNetwork(); |
610 // Determine new proxy config which may have changed because of new | |
611 // use-shared-proxies. If necessary, activate it. | |
612 Network* network = NULL; | |
613 if (!active_network_.empty()) { | |
614 network = CrosLibrary::Get()->GetNetworkLibrary()->FindNetworkByPath( | |
615 active_network_); | |
616 if (!network) | |
617 LOG(WARNING) << "Can't find requested network " << active_network_; | |
618 } | |
619 DetermineEffectiveConfig(network, true); | |
620 } | 107 } |
621 | 108 |
622 void ProxyConfigServiceImpl::OnUISetProxyConfig() { | 109 void ProxyConfigServiceImpl::DefaultNetworkChanged( |
623 if (current_ui_network_.empty()) | 110 const NetworkState* new_network) { |
624 return; | 111 std::string new_network_path; |
625 // Update config to shill. | 112 if (new_network) |
626 std::string value; | 113 new_network_path = new_network->path(); |
627 if (current_ui_config_.SerializeForNetwork(&value)) { | 114 |
628 VLOG(1) << "Set proxy (mode=" << current_ui_config_.mode | 115 VLOG(1) << "DefaultNetworkChanged to " << new_network_path << "."; |
stevenjb
2013/05/15 17:44:14
nit: '' around path (which might be empty)
pneubeck (no reviews)
2013/05/15 20:24:48
Done.
| |
629 << ") for " << current_ui_network_; | 116 VLOG_IF(1, new_network) << "New network: name=" << new_network->name() |
630 current_ui_config_.state = ProxyPrefs::CONFIG_SYSTEM; | 117 << ", proxy=" << new_network->proxy_config() |
631 SetProxyConfigForNetwork(current_ui_network_, value, false); | 118 << ", profile=" << new_network->profile_path(); |
632 } | 119 |
120 // If necessary, migrate device proxy settings to per network settings. | |
121 // If this changes the proxy configuration, a notification will be triggered | |
122 // afterwards which will call this function again. | |
123 MigrateDeviceToUserProxyConfig(new_network); | |
124 | |
125 // Even if the default network is the same, its proxy config (e.g. if private | |
126 // version of network replaces the shared version after login), or | |
127 // use-shared-proxies setting (e.g. after login) may have changed, so | |
128 // re-determine effective proxy config, and activate if different. | |
129 DetermineEffectiveConfigFromDefaultNetwork(); | |
633 } | 130 } |
634 | 131 |
635 void ProxyConfigServiceImpl::OnActiveNetworkChanged(NetworkLibrary* network_lib, | 132 void ProxyConfigServiceImpl::MigrateDeviceToUserProxyConfig( |
636 const Network* active_network) { | 133 const NetworkState* network_state) { |
637 std::string new_network; | 134 if (!network_state || |
638 if (active_network) | 135 !network_state->proxy_config().empty() || |
stevenjb
2013/05/15 17:44:14
This is somewhat non-obvious. Can you add a commen
pneubeck (no reviews)
2013/05/15 20:24:48
Done.
| |
639 new_network = active_network->service_path(); | 136 device_config_.empty()) { |
640 | |
641 if (active_network_ == new_network) { // Same active network. | |
642 VLOG(1) << "Same active network: " | |
643 << (new_network.empty() ? "empty" : | |
644 (active_network->name().empty() ? | |
645 new_network : active_network->name())); | |
646 // Even though network is the same, its proxy config (e.g. if private | |
647 // version of network replaces the shared version after login), or | |
648 // use-shared-proxies setting (e.g. after login) may have changed, | |
649 // so re-determine effective proxy config, and activate if different. | |
650 if (active_network) { | |
651 VLOG(1) << "Profile=" << active_network->profile_type() | |
652 << "," << active_network->profile_path() | |
653 << ", proxy=" << active_network->proxy_config(); | |
654 DetermineEffectiveConfig(active_network, true); | |
655 } | |
656 return; | 137 return; |
657 } | 138 } |
658 | 139 |
659 // If there was a previous active network, remove it as observer. | 140 const std::string& network_path = network_state->path(); |
660 if (!active_network_.empty()) | 141 VLOG(1) << "Try migrating device config to " << network_path; |
661 network_lib->RemoveNetworkObserver(active_network_, this); | |
662 | 142 |
663 active_network_ = new_network; | 143 Network* network = |
144 CrosLibrary::Get()->GetNetworkLibrary()->FindNetworkByPath(network_path); | |
145 if (!network) | |
146 return; | |
664 | 147 |
665 if (active_network_.empty()) { | 148 network->SetProxyConfig(device_config_); |
stevenjb
2013/05/15 17:44:14
Can we move this to NetworkLibrary, i.e.
CrosLibra
pneubeck (no reviews)
2013/05/15 20:24:48
Actually I had liked to remove this migration code
stevenjb
2013/05/16 17:04:34
If we eliminate
If we eliminate this, or plan to e
| |
666 VLOG(1) << "New active network: empty"; | 149 VLOG(1) << "Set proxy for " << network_path << ", value=" << device_config_; |
667 DetermineEffectiveConfig(active_network, true); | 150 // Even in case the default network was changed, there's no need to apply |
668 return; | 151 // the new proxy settings, because we will be notified afterwards. |
669 } | |
670 | |
671 VLOG(1) << "New active network: path=" << active_network->service_path() | |
672 << ", name=" << active_network->name() | |
673 << ", profile=" << active_network->profile_type() | |
674 << "," << active_network->profile_path() | |
675 << ", proxy=" << active_network->proxy_config(); | |
676 | |
677 // Register observer for new network. | |
678 network_lib->AddNetworkObserver(active_network_, this); | |
679 | |
680 // If necessary, migrate config to shill. | |
681 if (active_network->proxy_config().empty() && !device_config_.empty()) { | |
682 VLOG(1) << "Try migrating device config to " << active_network_; | |
683 SetProxyConfigForNetwork(active_network_, device_config_, true); | |
684 } else { | |
685 // Otherwise, determine and activate possibly new effective proxy config. | |
686 DetermineEffectiveConfig(active_network, true); | |
687 } | |
688 } | 152 } |
689 | 153 |
690 void ProxyConfigServiceImpl::SetProxyConfigForNetwork( | 154 // static |
691 const std::string& network_path, const std::string& value, | 155 bool ProxyConfigServiceImpl::GetUseSharedProxies( |
692 bool only_set_if_empty) { | 156 const PrefService* pref_service) { |
693 Network* network = CrosLibrary::Get()->GetNetworkLibrary()->FindNetworkByPath( | 157 const PrefService::Preference* use_shared_proxies = |
694 network_path); | 158 pref_service->FindPreference(prefs::kUseSharedProxies); |
695 if (!network) { | 159 if (!use_shared_proxies) { |
696 NOTREACHED() << "Can't find requested network " << network_path; | |
697 return; | |
698 } | |
699 if (!only_set_if_empty || network->proxy_config().empty()) { | |
700 network->SetProxyConfig(value); | |
701 VLOG(1) << "Set proxy for " | |
702 << (network->name().empty() ? network_path : network->name()) | |
703 << ", value=" << value; | |
704 if (network_path == active_network_) | |
705 DetermineEffectiveConfig(network, true); | |
706 } | |
707 } | |
708 | |
709 bool ProxyConfigServiceImpl::GetUseSharedProxies() { | |
710 const PrefService::Preference* use_shared_proxies_pref = | |
711 prefs()->FindPreference(prefs::kUseSharedProxies); | |
712 if (!use_shared_proxies_pref) { | |
713 // Make sure that proxies are always enabled at sign in screen. | 160 // Make sure that proxies are always enabled at sign in screen. |
714 return !UserManager::Get()->IsUserLoggedIn(); | 161 return !UserManager::Get()->IsUserLoggedIn(); |
715 } | 162 } |
716 return use_shared_proxies_.GetValue(); | 163 return use_shared_proxies->GetValue(); |
717 } | 164 } |
718 | 165 |
719 bool ProxyConfigServiceImpl::IgnoreProxy(const Network* network) { | 166 // static |
720 if (network->profile_type() == PROFILE_USER) | 167 bool ProxyConfigServiceImpl::IgnoreProxy(const PrefService* pref_service, |
168 const std::string network_profile_path, | |
169 onc::ONCSource onc_source) { | |
170 const NetworkProfile* profile = | |
171 NetworkProfileHandler::Get()->GetProfileForPath(network_profile_path); | |
172 if (!profile) { | |
173 LOG(WARNING) << "Unknown profile_path " << network_profile_path; | |
174 return true; | |
175 } | |
176 if (profile->type() == NetworkProfile::TYPE_USER) | |
721 return false; | 177 return false; |
722 | 178 |
723 if (network->ui_data().onc_source() == onc::ONC_SOURCE_DEVICE_POLICY && | 179 if (onc_source == onc::ONC_SOURCE_DEVICE_POLICY && |
724 UserManager::Get()->IsUserLoggedIn()) { | 180 UserManager::Get()->IsUserLoggedIn()) { |
725 policy::BrowserPolicyConnector* connector = | 181 policy::BrowserPolicyConnector* connector = |
726 g_browser_process->browser_policy_connector(); | 182 g_browser_process->browser_policy_connector(); |
727 const User* logged_in_user = UserManager::Get()->GetLoggedInUser(); | 183 const User* logged_in_user = UserManager::Get()->GetLoggedInUser(); |
728 if (connector->GetUserAffiliation(logged_in_user->email()) == | 184 if (connector->GetUserAffiliation(logged_in_user->email()) == |
729 policy::USER_AFFILIATION_MANAGED) { | 185 policy::USER_AFFILIATION_MANAGED) { |
730 VLOG(1) << "Respecting proxy for network " << network->name() | 186 VLOG(1) << "Respecting proxy for network, as logged-in user belongs to " |
731 << ", as logged-in user belongs to the domain the device " | 187 << "the domain the device is enrolled to."; |
732 << "is enrolled to."; | |
733 return false; | 188 return false; |
734 } | 189 } |
735 } | 190 } |
736 | 191 |
737 return !GetUseSharedProxies(); | 192 return !GetUseSharedProxies(pref_service); |
738 } | 193 } |
739 | 194 |
740 void ProxyConfigServiceImpl::DetermineEffectiveConfig(const Network* network, | 195 void ProxyConfigServiceImpl::DetermineEffectiveConfigFromDefaultNetwork() { |
741 bool activate) { | 196 const NetworkState* network = NetworkStateHandler::Get()->DefaultNetwork(); |
197 | |
742 // Get prefs proxy config if available. | 198 // Get prefs proxy config if available. |
743 net::ProxyConfig pref_config; | 199 net::ProxyConfig pref_config; |
744 ProxyPrefs::ConfigState pref_state = GetProxyConfig(&pref_config); | 200 ProxyPrefs::ConfigState pref_state = GetProxyConfig(&pref_config); |
745 | 201 |
746 // Get network proxy config if available. | 202 // Get network proxy config if available. |
747 net::ProxyConfig network_config; | 203 net::ProxyConfig network_config; |
748 net::ProxyConfigService::ConfigAvailability network_availability = | 204 net::ProxyConfigService::ConfigAvailability network_availability = |
749 net::ProxyConfigService::CONFIG_UNSET; | 205 net::ProxyConfigService::CONFIG_UNSET; |
750 bool ignore_proxy = activate; | 206 bool ignore_proxy = true; |
751 if (network) { | 207 if (network) { |
752 // If we're activating proxy, ignore proxy if necessary; | 208 // If we're activating proxy, ignore proxy if necessary; |
753 // otherwise, for ui, get actual proxy to show user. | 209 // otherwise, for ui, get actual proxy to show user. |
754 ignore_proxy = activate ? IgnoreProxy(network) : false; | 210 ignore_proxy = |
211 IgnoreProxy(prefs(), network->profile_path(), network->onc_source()); | |
755 // If network is shared but use-shared-proxies is off, use direct mode. | 212 // If network is shared but use-shared-proxies is off, use direct mode. |
756 if (ignore_proxy) { | 213 if (ignore_proxy) { |
757 VLOG(1) << "Shared network && !use-shared-proxies, use direct"; | 214 VLOG(1) << "Shared network && !use-shared-proxies, use direct"; |
758 network_availability = net::ProxyConfigService::CONFIG_VALID; | 215 network_availability = net::ProxyConfigService::CONFIG_VALID; |
759 } else if (!network->proxy_config().empty()) { | 216 } else if (ParseProxyConfig(network->proxy_config(), &network_config)) { |
760 // Network is private or shared with user using shared proxies. | 217 // Network is private or shared with user using shared proxies. |
761 if (ParseProxyConfig(network, &network_config)) { | 218 VLOG(1) << this << ": using network proxy: " |
762 VLOG(1) << this << ": using network proxy: " | 219 << network->proxy_config(); |
763 << network->proxy_config(); | 220 network_availability = net::ProxyConfigService::CONFIG_VALID; |
764 network_availability = net::ProxyConfigService::CONFIG_VALID; | |
765 } | |
766 } | 221 } |
767 } | 222 } |
768 | 223 |
769 // Determine effective proxy config, either from prefs or network. | 224 // Determine effective proxy config, either from prefs or network. |
770 ProxyPrefs::ConfigState effective_config_state; | 225 ProxyPrefs::ConfigState effective_config_state; |
771 net::ProxyConfig effective_config; | 226 net::ProxyConfig effective_config; |
772 GetEffectiveProxyConfig(pref_state, pref_config, | 227 GetEffectiveProxyConfig(pref_state, pref_config, |
773 network_availability, network_config, ignore_proxy, | 228 network_availability, network_config, ignore_proxy, |
774 &effective_config_state, &effective_config); | 229 &effective_config_state, &effective_config); |
775 | 230 |
776 // Determine if we should activate effective proxy and which proxy config to | 231 // Activate effective proxy and store into |active_config_|. |
777 // store it. | 232 // If last update didn't complete, we definitely update now. |
778 if (activate) { // Activate effective proxy and store into |active_config_|. | 233 bool update_now = update_pending(); |
779 // If last update didn't complete, we definitely update now. | 234 if (!update_now) { // Otherwise, only update now if there're changes. |
780 bool update_now = update_pending(); | 235 update_now = active_config_state_ != effective_config_state || |
781 if (!update_now) { // Otherwise, only update now if there're changes. | 236 (active_config_state_ != ProxyPrefs::CONFIG_UNSET && |
782 update_now = active_config_state_ != effective_config_state || | 237 !active_config_.Equals(effective_config)); |
783 (active_config_state_ != ProxyPrefs::CONFIG_UNSET && | 238 } |
784 !active_config_.Equals(effective_config)); | 239 if (update_now) { // Activate and store new effective config. |
785 } | 240 active_config_state_ = effective_config_state; |
786 if (update_now) { // Activate and store new effective config. | 241 if (active_config_state_ != ProxyPrefs::CONFIG_UNSET) |
787 active_config_state_ = effective_config_state; | 242 active_config_ = effective_config; |
788 if (active_config_state_ != ProxyPrefs::CONFIG_UNSET) | 243 // If effective config is from system (i.e. network), it's considered a |
789 active_config_ = effective_config; | 244 // special kind of prefs that ranks below policy/extension but above |
790 // If effective config is from system (i.e. network), it's considered a | 245 // others, so bump it up to CONFIG_OTHER_PRECEDE to force its precedence |
791 // special kind of prefs that ranks below policy/extension but above | 246 // when PrefProxyConfigTrackerImpl pushes it to ChromeProxyConfigService. |
792 // others, so bump it up to CONFIG_OTHER_PRECEDE to force its precedence | 247 if (effective_config_state == ProxyPrefs::CONFIG_SYSTEM) |
793 // when PrefProxyConfigTrackerImpl pushes it to ChromeProxyConfigService. | 248 effective_config_state = ProxyPrefs::CONFIG_OTHER_PRECEDE; |
794 if (effective_config_state == ProxyPrefs::CONFIG_SYSTEM) | 249 // If config is manual, add rule to bypass local host. |
795 effective_config_state = ProxyPrefs::CONFIG_OTHER_PRECEDE; | 250 if (effective_config.proxy_rules().type != |
796 // If config is manual, add rule to bypass local host. | 251 net::ProxyConfig::ProxyRules::TYPE_NO_RULES) |
797 if (effective_config.proxy_rules().type != | 252 effective_config.proxy_rules().bypass_rules.AddRuleToBypassLocal(); |
798 net::ProxyConfig::ProxyRules::TYPE_NO_RULES) | 253 PrefProxyConfigTrackerImpl::OnProxyConfigChanged(effective_config_state, |
799 effective_config.proxy_rules().bypass_rules.AddRuleToBypassLocal(); | 254 effective_config); |
800 PrefProxyConfigTrackerImpl::OnProxyConfigChanged(effective_config_state, | 255 if (VLOG_IS_ON(1) && !update_pending()) { // Update was successful. |
801 effective_config); | 256 scoped_ptr<base::DictionaryValue> config_dict( |
802 if (VLOG_IS_ON(1) && !update_pending()) { // Update was successful. | 257 effective_config.ToValue()); |
803 scoped_ptr<DictionaryValue> config_dict(static_cast<DictionaryValue*>( | 258 VLOG(1) << this << ": Proxy changed: " |
804 effective_config.ToValue())); | 259 << ProxyPrefs::ConfigStateToString(active_config_state_) |
805 std::string config_value; | 260 << ", " << *config_dict; |
806 JSONStringValueSerializer serializer(&config_value); | |
807 serializer.Serialize(*config_dict.get()); | |
808 VLOG(1) << this << ": Proxy changed: " | |
809 << ConfigStateToString(active_config_state_) | |
810 << ", " << config_value; | |
811 } | |
812 } | |
813 } else { // For UI, store effective proxy into |current_ui_config_|. | |
814 current_ui_config_.FromNetProxyConfig(effective_config); | |
815 current_ui_config_.state = effective_config_state; | |
816 if (PrefPrecedes(effective_config_state)) { | |
817 current_ui_config_.user_modifiable = false; | |
818 } else if (!IsNetworkProxySettingsEditable(network)) { | |
819 // TODO(xiyuan): Figure out the right way to set config state for managed | |
820 // network. | |
821 current_ui_config_.state = ProxyPrefs::CONFIG_POLICY; | |
822 current_ui_config_.user_modifiable = false; | |
823 } else { | |
824 current_ui_config_.user_modifiable = !network || !IgnoreProxy(network); | |
825 } | 261 } |
826 } | 262 } |
827 } | 263 } |
828 | 264 |
829 void ProxyConfigServiceImpl::OnUISetCurrentNetwork(const Network* network) { | 265 void ProxyConfigServiceImpl::FetchDeviceProxySetting() { |
830 DetermineEffectiveConfig(network, false); | |
831 VLOG(1) << "Current ui network: " | |
832 << (network->name().empty() ? current_ui_network_ : network->name()) | |
833 << ", " << ModeToString(current_ui_config_.mode) | |
834 << ", " << ConfigStateToString(current_ui_config_.state) | |
835 << ", modifiable:" << current_ui_config_.user_modifiable; | |
836 // Notify whoever is interested in this change. | |
837 std::vector<base::Closure>::iterator iter = callbacks_.begin(); | |
838 while (iter != callbacks_.end()) { | |
839 if (iter->is_null()) { | |
840 iter = callbacks_.erase(iter); | |
841 } else { | |
842 iter->Run(); | |
843 ++iter; | |
844 } | |
845 } | |
846 } | |
847 | |
848 void ProxyConfigServiceImpl::ResetUICache() { | |
849 current_ui_network_.clear(); | |
850 current_ui_config_ = ProxyConfig(); | |
851 } | |
852 | |
853 void ProxyConfigServiceImpl::FetchProxyPolicy() { | |
854 if (CrosSettingsProvider::TRUSTED != | 266 if (CrosSettingsProvider::TRUSTED != |
855 CrosSettings::Get()->PrepareTrustedValues( | 267 CrosSettings::Get()->PrepareTrustedValues( |
856 base::Bind(&ProxyConfigServiceImpl::FetchProxyPolicy, | 268 base::Bind(&ProxyConfigServiceImpl::FetchDeviceProxySetting, |
857 pointer_factory_.GetWeakPtr()))) { | 269 pointer_factory_.GetWeakPtr()))) { |
858 return; | 270 return; |
859 } | 271 } |
860 | 272 |
861 std::string policy_value; | 273 std::string device_value; |
862 if (!CrosSettings::Get()->GetString(kSettingProxyEverywhere, | 274 if (!CrosSettings::Get()->GetString(kSettingProxyEverywhere, |
863 &policy_value)) { | 275 &device_value)) { |
864 VLOG(1) << "No proxy configuration exists in the device settings."; | 276 VLOG(1) << "No proxy configuration exists in the device settings."; |
865 device_config_.clear(); | 277 device_config_.clear(); |
866 return; | 278 return; |
867 } | 279 } |
868 | 280 |
869 VLOG(1) << "Retrieved proxy setting from device, value=[" | 281 VLOG(1) << "Retrieved proxy setting from device, value=[" |
870 << policy_value << "]"; | 282 << device_value << "]"; |
871 ProxyConfig device_config; | 283 UIProxyConfig device_config; |
872 if (!device_config.DeserializeForDevice(policy_value) || | 284 if (!device_config.DeserializeForDevice(device_value) || |
873 !device_config.SerializeForNetwork(&device_config_)) { | 285 !device_config.SerializeForNetwork(&device_config_)) { |
874 LOG(WARNING) << "Can't deserialize device setting or serialize for network"; | 286 LOG(WARNING) << "Can't deserialize device setting or serialize for network"; |
875 device_config_.clear(); | 287 device_config_.clear(); |
876 return; | 288 return; |
877 } | 289 } |
878 if (!active_network_.empty()) { | 290 MigrateDeviceToUserProxyConfig(NetworkStateHandler::Get()->DefaultNetwork()); |
879 VLOG(1) << "Try migrating device config to " << active_network_; | |
880 SetProxyConfigForNetwork(active_network_, device_config_, true); | |
881 } | |
882 } | 291 } |
883 | 292 |
884 } // namespace chromeos | 293 } // namespace chromeos |
OLD | NEW |