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

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: Rebased. Created 7 years, 6 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 if (pref_proxy_config.empty())
43 bool operator() (const T& element) { 36 return false;
44 return element.Equals(key_); 37 ProxyConfigDictionary proxy_dict(&pref_proxy_config);
45 } 38 return PrefProxyConfigTrackerImpl::PrefConfigToNetConfig(proxy_dict,
46 private: 39 proxy_config);
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 } 40 }
111 41
112 } // namespace 42 } // namespace
113 43
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) 44 ProxyConfigServiceImpl::ProxyConfigServiceImpl(PrefService* pref_service)
266 : PrefProxyConfigTrackerImpl(pref_service), 45 : PrefProxyConfigTrackerImpl(pref_service),
267 active_config_state_(ProxyPrefs::CONFIG_UNSET), 46 active_config_state_(ProxyPrefs::CONFIG_UNSET),
47 ui_proxy_config_service_(pref_service),
268 pointer_factory_(this) { 48 pointer_factory_(this) {
269 49
270 // Register for notifications of UseSharedProxies user preference. 50 // Register for notifications of UseSharedProxies user preference.
271 if (pref_service->FindPreference(prefs::kUseSharedProxies)) { 51 if (pref_service->FindPreference(prefs::kUseSharedProxies)) {
272 use_shared_proxies_.Init( 52 use_shared_proxies_.Init(
273 prefs::kUseSharedProxies, pref_service, 53 prefs::kUseSharedProxies, pref_service,
274 base::Bind(&ProxyConfigServiceImpl::OnUseSharedProxiesChanged, 54 base::Bind(&ProxyConfigServiceImpl::OnUseSharedProxiesChanged,
275 base::Unretained(this))); 55 base::Unretained(this)));
276 } 56 }
277 57
278 // Register for shill network notifications. 58 // Register for changes to the default network.
279 NetworkLibrary* network_lib = CrosLibrary::Get()->GetNetworkLibrary(); 59 NetworkStateHandler* state_handler =
280 OnActiveNetworkChanged(network_lib, network_lib->active_network()); 60 NetworkHandler::Get()->network_state_handler();
281 network_lib->AddNetworkManagerObserver(this); 61 state_handler->AddObserver(this);
62 DefaultNetworkChanged(state_handler->DefaultNetwork());
282 } 63 }
283 64
284 ProxyConfigServiceImpl::~ProxyConfigServiceImpl() { 65 ProxyConfigServiceImpl::~ProxyConfigServiceImpl() {
285 NetworkLibrary* netlib = CrosLibrary::Get()->GetNetworkLibrary(); 66 if (NetworkHandler::IsInitialized())
286 if (netlib) { 67 NetworkHandler::Get()->network_state_handler()->RemoveObserver(this);
287 netlib->RemoveNetworkManagerObserver(this);
288 netlib->RemoveObserverForAllNetworks(this);
289 }
290 } 68 }
291 69
292 void ProxyConfigServiceImpl::UISetCurrentNetwork( 70 UIProxyConfigService& ProxyConfigServiceImpl::GetUIService() {
293 const std::string& current_network) { 71 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 } 72 }
411 73
412 void ProxyConfigServiceImpl::OnProxyConfigChanged( 74 void ProxyConfigServiceImpl::OnProxyConfigChanged(
413 ProxyPrefs::ConfigState config_state, 75 ProxyPrefs::ConfigState config_state,
414 const net::ProxyConfig& config) { 76 const net::ProxyConfig& config) {
415 VLOG(1) << "Got prefs change: " << ConfigStateToString(config_state) 77 VLOG(1) << "Got prefs change: "
78 << ProxyPrefs::ConfigStateToDebugString(config_state)
416 << ", mode=" << config.proxy_rules().type; 79 << ", mode=" << config.proxy_rules().type;
417 Network* network = NULL; 80 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 } 81 }
446 82
447 // static 83 // 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) { 84 void ProxyConfigServiceImpl::RegisterPrefs(PrefRegistrySimple* registry) {
464 // Use shared proxies default to off. GetUseSharedProxies will return the 85 // Use shared proxies default to off. GetUseSharedProxies will return the
465 // correct value based on pre-login and login. 86 // correct value based on pre-login and login.
466 registry->RegisterBooleanPref(prefs::kUseSharedProxies, true); 87 registry->RegisterBooleanPref(prefs::kUseSharedProxies, true);
467 } 88 }
468 89
469 // static 90 // static
470 void ProxyConfigServiceImpl::RegisterUserPrefs( 91 void ProxyConfigServiceImpl::RegisterUserPrefs(
471 user_prefs::PrefRegistrySyncable* registry) { 92 user_prefs::PrefRegistrySyncable* registry) {
472 registry->RegisterBooleanPref( 93 registry->RegisterBooleanPref(
473 prefs::kUseSharedProxies, 94 prefs::kUseSharedProxies,
474 true, 95 true,
475 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 96 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
476 } 97 }
477 98
478 //------------------ ProxyConfigServiceImpl: private methods -------------------
479
480 void ProxyConfigServiceImpl::OnUseSharedProxiesChanged() { 99 void ProxyConfigServiceImpl::OnUseSharedProxiesChanged() {
481 VLOG(1) << "New use-shared-proxies = " << GetUseSharedProxies(); 100 VLOG(1) << "New use-shared-proxies = " << GetUseSharedProxies(prefs());
482 101 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 } 102 }
494 103
495 void ProxyConfigServiceImpl::OnUISetProxyConfig() { 104 void ProxyConfigServiceImpl::DefaultNetworkChanged(
496 if (current_ui_network_.empty()) 105 const NetworkState* new_network) {
497 return; 106 std::string new_network_path;
498 // Update config to shill. 107 if (new_network)
499 std::string value; 108 new_network_path = new_network->path();
500 if (current_ui_config_.SerializeForNetwork(&value)) { 109
501 VLOG(1) << "Set proxy (mode=" << current_ui_config_.mode 110 VLOG(1) << "DefaultNetworkChanged to '" << new_network_path << "'.";
502 << ") for " << current_ui_network_; 111 VLOG_IF(1, new_network) << "New network: name=" << new_network->name()
503 current_ui_config_.state = ProxyPrefs::CONFIG_SYSTEM; 112 << ", proxy=" << new_network->proxy_config()
504 SetProxyConfigForNetwork(current_ui_network_, value, false); 113 << ", profile=" << new_network->profile_path();
505 } 114
115 // Even if the default network is the same, its proxy config (e.g. if private
116 // version of network replaces the shared version after login), or
117 // use-shared-proxies setting (e.g. after login) may have changed, so
118 // re-determine effective proxy config, and activate if different.
119 DetermineEffectiveConfigFromDefaultNetwork();
506 } 120 }
507 121
508 void ProxyConfigServiceImpl::OnActiveNetworkChanged(NetworkLibrary* network_lib, 122 // static
509 const Network* active_network) { 123 bool ProxyConfigServiceImpl::GetUseSharedProxies(
510 std::string new_network; 124 const PrefService* pref_service) {
511 if (active_network) 125 const PrefService::Preference* use_shared_proxies_pref =
512 new_network = active_network->service_path(); 126 pref_service->FindPreference(prefs::kUseSharedProxies);
127 if (!use_shared_proxies_pref || !use_shared_proxies_pref->GetValue()) {
128 if (UserManager::Get()->IsUserLoggedIn()) {
129 VLOG(1) << "use-shared-proxies not set, defaulting to false/IgnoreProxy.";
130 return false;
131 } else {
132 // Make sure that proxies are always enabled at sign in screen.
133 VLOG(1) << "Use proxy on login screen.";
134 return true;
135 }
136 }
137 bool use_shared_proxies = false;
138 use_shared_proxies_pref->GetValue()->GetAsBoolean(&use_shared_proxies);
139 return use_shared_proxies;
140 }
513 141
514 if (active_network_ == new_network) { // Same active network. 142 // static
515 VLOG(1) << "Same active network: " 143 bool ProxyConfigServiceImpl::IgnoreProxy(const PrefService* pref_service,
516 << (new_network.empty() ? "empty" : 144 const std::string network_profile_path,
517 (active_network->name().empty() ? 145 onc::ONCSource onc_source) {
518 new_network : active_network->name())); 146 const NetworkProfile* profile =
519 // Even though network is the same, its proxy config (e.g. if private 147 NetworkHandler::Get()->network_profile_handler()->
520 // version of network replaces the shared version after login), or 148 GetProfileForPath(network_profile_path);
521 // use-shared-proxies setting (e.g. after login) may have changed, 149 if (!profile) {
522 // so re-determine effective proxy config, and activate if different. 150 LOG(WARNING) << "Unknown profile_path " << network_profile_path;
523 if (active_network) { 151 return true;
524 VLOG(1) << "Profile=" << active_network->profile_type() 152 }
525 << "," << active_network->profile_path() 153 if (profile->type() == NetworkProfile::TYPE_USER) {
526 << ", proxy=" << active_network->proxy_config(); 154 VLOG(1) << "Respect proxy of not-shared networks.";
527 DetermineEffectiveConfig(active_network, true); 155 return false;
528 }
529 return;
530 } 156 }
531 157
532 // If there was a previous active network, remove it as observer. 158 if (onc_source == onc::ONC_SOURCE_DEVICE_POLICY &&
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.
581 return !UserManager::Get()->IsUserLoggedIn();
582 }
583 return use_shared_proxies_.GetValue();
584 }
585
586 bool ProxyConfigServiceImpl::IgnoreProxy(const Network* network) {
587 if (network->profile_type() == PROFILE_USER)
588 return false;
589
590 if (network->ui_data().onc_source() == onc::ONC_SOURCE_DEVICE_POLICY &&
591 UserManager::Get()->IsUserLoggedIn()) { 159 UserManager::Get()->IsUserLoggedIn()) {
592 policy::BrowserPolicyConnector* connector = 160 policy::BrowserPolicyConnector* connector =
593 g_browser_process->browser_policy_connector(); 161 g_browser_process->browser_policy_connector();
594 const User* logged_in_user = UserManager::Get()->GetLoggedInUser(); 162 const User* logged_in_user = UserManager::Get()->GetLoggedInUser();
595 if (connector->GetUserAffiliation(logged_in_user->email()) == 163 if (connector->GetUserAffiliation(logged_in_user->email()) ==
596 policy::USER_AFFILIATION_MANAGED) { 164 policy::USER_AFFILIATION_MANAGED) {
597 VLOG(1) << "Respecting proxy for network " << network->name() 165 VLOG(1) << "Respecting proxy for network, as logged-in user belongs to "
598 << ", as logged-in user belongs to the domain the device " 166 << "the domain the device is enrolled to.";
599 << "is enrolled to.";
600 return false; 167 return false;
601 } 168 }
602 } 169 }
603 170
604 return !GetUseSharedProxies(); 171 return !GetUseSharedProxies(pref_service);
605 } 172 }
606 173
607 void ProxyConfigServiceImpl::DetermineEffectiveConfig(const Network* network, 174 void ProxyConfigServiceImpl::DetermineEffectiveConfigFromDefaultNetwork() {
608 bool activate) { 175 const NetworkState* network =
176 NetworkHandler::Get()->network_state_handler()->DefaultNetwork();
177
609 // Get prefs proxy config if available. 178 // Get prefs proxy config if available.
610 net::ProxyConfig pref_config; 179 net::ProxyConfig pref_config;
611 ProxyPrefs::ConfigState pref_state = GetProxyConfig(&pref_config); 180 ProxyPrefs::ConfigState pref_state = GetProxyConfig(&pref_config);
612 181
613 // Get network proxy config if available. 182 // Get network proxy config if available.
614 net::ProxyConfig network_config; 183 net::ProxyConfig network_config;
615 net::ProxyConfigService::ConfigAvailability network_availability = 184 net::ProxyConfigService::ConfigAvailability network_availability =
616 net::ProxyConfigService::CONFIG_UNSET; 185 net::ProxyConfigService::CONFIG_UNSET;
617 bool ignore_proxy = activate; 186 bool ignore_proxy = true;
618 if (network) { 187 if (network) {
619 // If we're activating proxy, ignore proxy if necessary; 188 ignore_proxy =
620 // otherwise, for ui, get actual proxy to show user. 189 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. 190 // If network is shared but use-shared-proxies is off, use direct mode.
623 if (ignore_proxy) { 191 if (ignore_proxy) {
624 VLOG(1) << "Shared network && !use-shared-proxies, use direct"; 192 VLOG(1) << "Shared network && !use-shared-proxies, use direct";
625 network_availability = net::ProxyConfigService::CONFIG_VALID; 193 network_availability = net::ProxyConfigService::CONFIG_VALID;
626 } else if (!network->proxy_config().empty()) { 194 } else if (ParseProxyConfig(network->proxy_config(), &network_config)) {
627 // Network is private or shared with user using shared proxies. 195 // Network is private or shared with user using shared proxies.
628 if (ParseProxyConfig(network->proxy_config(), &network_config)) { 196 VLOG(1) << this << ": using network proxy: "
629 VLOG(1) << this << ": using network proxy: " 197 << network->proxy_config();
630 << network->proxy_config(); 198 network_availability = net::ProxyConfigService::CONFIG_VALID;
631 network_availability = net::ProxyConfigService::CONFIG_VALID;
632 }
633 } 199 }
634 } 200 }
635 201
636 // Determine effective proxy config, either from prefs or network. 202 // Determine effective proxy config, either from prefs or network.
637 ProxyPrefs::ConfigState effective_config_state; 203 ProxyPrefs::ConfigState effective_config_state;
638 net::ProxyConfig effective_config; 204 net::ProxyConfig effective_config;
639 GetEffectiveProxyConfig(pref_state, pref_config, 205 GetEffectiveProxyConfig(pref_state, pref_config,
640 network_availability, network_config, ignore_proxy, 206 network_availability, network_config, ignore_proxy,
641 &effective_config_state, &effective_config); 207 &effective_config_state, &effective_config);
642 208
643 // Determine if we should activate effective proxy and which proxy config to 209 // Activate effective proxy and store into |active_config_|.
644 // store it. 210 // If last update didn't complete, we definitely update now.
645 if (activate) { // Activate effective proxy and store into |active_config_|. 211 bool update_now = update_pending();
646 // If last update didn't complete, we definitely update now. 212 if (!update_now) { // Otherwise, only update now if there're changes.
647 bool update_now = update_pending(); 213 update_now = active_config_state_ != effective_config_state ||
648 if (!update_now) { // Otherwise, only update now if there're changes. 214 (active_config_state_ != ProxyPrefs::CONFIG_UNSET &&
649 update_now = active_config_state_ != effective_config_state || 215 !active_config_.Equals(effective_config));
650 (active_config_state_ != ProxyPrefs::CONFIG_UNSET && 216 }
651 !active_config_.Equals(effective_config)); 217 if (update_now) { // Activate and store new effective config.
652 } 218 active_config_state_ = effective_config_state;
653 if (update_now) { // Activate and store new effective config. 219 if (active_config_state_ != ProxyPrefs::CONFIG_UNSET)
654 active_config_state_ = effective_config_state; 220 active_config_ = effective_config;
655 if (active_config_state_ != ProxyPrefs::CONFIG_UNSET) 221 // If effective config is from system (i.e. network), it's considered a
656 active_config_ = effective_config; 222 // 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 223 // 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 224 // when PrefProxyConfigTrackerImpl pushes it to ChromeProxyConfigService.
659 // others, so bump it up to CONFIG_OTHER_PRECEDE to force its precedence 225 if (effective_config_state == ProxyPrefs::CONFIG_SYSTEM)
660 // when PrefProxyConfigTrackerImpl pushes it to ChromeProxyConfigService. 226 effective_config_state = ProxyPrefs::CONFIG_OTHER_PRECEDE;
661 if (effective_config_state == ProxyPrefs::CONFIG_SYSTEM) 227 // If config is manual, add rule to bypass local host.
662 effective_config_state = ProxyPrefs::CONFIG_OTHER_PRECEDE; 228 if (effective_config.proxy_rules().type !=
663 // If config is manual, add rule to bypass local host. 229 net::ProxyConfig::ProxyRules::TYPE_NO_RULES)
664 if (effective_config.proxy_rules().type != 230 effective_config.proxy_rules().bypass_rules.AddRuleToBypassLocal();
665 net::ProxyConfig::ProxyRules::TYPE_NO_RULES) 231 PrefProxyConfigTrackerImpl::OnProxyConfigChanged(effective_config_state,
666 effective_config.proxy_rules().bypass_rules.AddRuleToBypassLocal(); 232 effective_config);
667 PrefProxyConfigTrackerImpl::OnProxyConfigChanged(effective_config_state, 233 if (VLOG_IS_ON(1) && !update_pending()) { // Update was successful.
668 effective_config); 234 scoped_ptr<base::DictionaryValue> config_dict(
669 if (VLOG_IS_ON(1) && !update_pending()) { // Update was successful. 235 effective_config.ToValue());
670 scoped_ptr<DictionaryValue> config_dict(static_cast<DictionaryValue*>( 236 VLOG(1) << this << ": Proxy changed: "
671 effective_config.ToValue())); 237 << ProxyPrefs::ConfigStateToDebugString(active_config_state_)
672 std::string config_value; 238 << ", " << *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 } 239 }
693 } 240 }
694 } 241 }
695 242
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 243 } // 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