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

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

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

Powered by Google App Engine
This is Rietveld 408576698