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

Side by Side Diff: chrome/browser/net/pref_proxy_config_service.cc

Issue 5005002: Dynamically refresh pref-configured proxies. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address Eric's feedback. Created 10 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/net/pref_proxy_config_service.h"
6
7 #include "chrome/browser/browser_thread.h"
8 #include "chrome/browser/prefs/pref_service.h"
9 #include "chrome/browser/prefs/pref_set_observer.h"
10 #include "chrome/common/notification_details.h"
11 #include "chrome/common/notification_source.h"
12 #include "chrome/common/notification_type.h"
13 #include "chrome/common/pref_names.h"
14
15 PrefProxyConfigTracker::PrefProxyConfigTracker(PrefService* pref_service)
16 : pref_service_(pref_service) {
17 valid_ = ReadPrefConfig(&pref_config_);
18 proxy_prefs_observer_.reset(
19 PrefSetObserver::CreateProxyPrefSetObserver(pref_service_, this));
20 }
21
22 PrefProxyConfigTracker::~PrefProxyConfigTracker() {
23 }
24
25 bool PrefProxyConfigTracker::GetProxyConfig(net::ProxyConfig* config) {
26 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
27 if (valid_)
28 *config = pref_config_;
29 return valid_;
30 }
31
32 void PrefProxyConfigTracker::Shutdown() {
eroman 2010/11/20 03:19:07 Can you add an assertion that we are on UI thread?
Mattias Nissler (ping if slow) 2010/11/21 22:49:14 Done.
33 // Stop notifications.
34 proxy_prefs_observer_.reset();
35 pref_service_ = NULL;
36 }
37
38 void PrefProxyConfigTracker::AddObserver(
39 PrefProxyConfigTracker::Observer* observer) {
eroman 2010/11/20 03:19:07 Please DCHECK that we are on IO thread.
Mattias Nissler (ping if slow) 2010/11/21 22:49:14 Done.
40 observers_.AddObserver(observer);
41 }
42
43 void PrefProxyConfigTracker::RemoveObserver(
eroman 2010/11/20 03:19:07 Please DCHECK that we are on IO thread.
Mattias Nissler (ping if slow) 2010/11/21 22:49:14 Done.
44 PrefProxyConfigTracker::Observer* observer) {
45 observers_.RemoveObserver(observer);
46 }
47
48 void PrefProxyConfigTracker::Observe(NotificationType type,
49 const NotificationSource& source,
50 const NotificationDetails& details) {
51 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
52 if (type == NotificationType::PREF_CHANGED &&
53 Source<PrefService>(source).ptr() == pref_service_) {
54 net::ProxyConfig new_config;
55 bool valid = ReadPrefConfig(&new_config);
56 BrowserThread::PostTask(
57 BrowserThread::IO, FROM_HERE,
58 NewRunnableMethod(this,
59 &PrefProxyConfigTracker::InstallProxyConfig,
60 new_config, valid));
61 } else {
62 NOTREACHED() << "Unexpected notification of type " << type.value;
63 }
64 }
65
66 void PrefProxyConfigTracker::InstallProxyConfig(const net::ProxyConfig& config,
67 bool valid) {
68 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
69 pref_config_ = config;
70 valid_ = valid;
71 FOR_EACH_OBSERVER(Observer, observers_, OnPrefProxyConfigChanged());
72 }
73
74 bool PrefProxyConfigTracker::ReadPrefConfig(net::ProxyConfig* config) {
75 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
76
77 // Clear the configuration.
78 *config = net::ProxyConfig();
79
80 // Scan for all "enable" type proxy switches.
81 static const char* proxy_prefs[] = {
82 prefs::kProxyPacUrl,
83 prefs::kProxyServer,
84 prefs::kProxyBypassList,
85 prefs::kProxyAutoDetect
86 };
87
88 // Check whether the preference system holds a valid proxy configuration. Note
89 // that preferences coming from a lower-priority source than the user settings
90 // are ignored. That's because chrome treats the system settings as the
91 // default values, which should apply if there's no explicit value forced by
92 // policy or the user.
93 bool found_enable_proxy_pref = false;
94 for (size_t i = 0; i < arraysize(proxy_prefs); i++) {
95 const PrefService::Preference* pref =
96 pref_service_->FindPreference(proxy_prefs[i]);
97 DCHECK(pref);
98 if (pref && (!pref->IsUserModifiable() || pref->HasUserSetting())) {
99 found_enable_proxy_pref = true;
100 break;
101 }
102 }
103
104 if (!found_enable_proxy_pref &&
105 !pref_service_->GetBoolean(prefs::kNoProxyServer)) {
106 return false;
107 }
108
109 if (pref_service_->GetBoolean(prefs::kNoProxyServer)) {
110 // Ignore all the other proxy config preferences if the use of a proxy
111 // has been explicitly disabled.
112 return true;
113 }
114
115 if (pref_service_->HasPrefPath(prefs::kProxyServer)) {
116 std::string proxy_server = pref_service_->GetString(prefs::kProxyServer);
117 config->proxy_rules().ParseFromString(proxy_server);
118 }
119
120 if (pref_service_->HasPrefPath(prefs::kProxyPacUrl)) {
121 std::string proxy_pac = pref_service_->GetString(prefs::kProxyPacUrl);
122 config->set_pac_url(GURL(proxy_pac));
123 }
124
125 config->set_auto_detect(pref_service_->GetBoolean(prefs::kProxyAutoDetect));
126
127 if (pref_service_->HasPrefPath(prefs::kProxyBypassList)) {
128 std::string proxy_bypass =
129 pref_service_->GetString(prefs::kProxyBypassList);
130 config->proxy_rules().bypass_rules.ParseFromString(proxy_bypass);
131 }
132
133 return true;
134 }
135
136 PrefProxyConfigService::PrefProxyConfigService(
137 PrefProxyConfigTracker* tracker,
138 net::ProxyConfigService* base_service)
139 : base_service_(base_service),
140 pref_config_tracker_(tracker),
141 registered_observers_(false) {
142 }
143
144 PrefProxyConfigService::~PrefProxyConfigService() {
145 if (registered_observers_) {
146 base_service_->RemoveObserver(this);
147 pref_config_tracker_->RemoveObserver(this);
148 }
149 }
150
151 void PrefProxyConfigService::AddObserver(
152 net::ProxyConfigService::Observer* observer) {
153 RegisterObservers();
154 observers_.AddObserver(observer);
155 }
156
157 void PrefProxyConfigService::RemoveObserver(
158 net::ProxyConfigService::Observer* observer) {
159 observers_.RemoveObserver(observer);
160 }
161
162 bool PrefProxyConfigService::GetLatestProxyConfig(net::ProxyConfig* config) {
163 RegisterObservers();
164 const net::ProxyConfig pref_config;
165 if (pref_config_tracker_->GetProxyConfig(config))
166 return true;
167
168 return base_service_->GetLatestProxyConfig(config);
169 }
170
171 void PrefProxyConfigService::OnLazyPoll() {
172 base_service_->OnLazyPoll();
173 }
174
175 void PrefProxyConfigService::OnProxyConfigChanged(
176 const net::ProxyConfig& config) {
177 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
178 net::ProxyConfig pref_config;
179 if (!pref_config_tracker_->GetProxyConfig(&pref_config)) {
eroman 2010/11/20 03:19:07 I suggest adding a comment to make this easier to
Mattias Nissler (ping if slow) 2010/11/21 22:49:14 Done.
180 FOR_EACH_OBSERVER(net::ProxyConfigService::Observer, observers_,
181 OnProxyConfigChanged(config));
182 }
183 }
184
185 void PrefProxyConfigService::OnPrefProxyConfigChanged() {
186 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
187 net::ProxyConfig new_config;
188 if (GetLatestProxyConfig(&new_config)) {
eroman 2010/11/20 03:19:07 I suggest adding a comment to the effect that if G
Mattias Nissler (ping if slow) 2010/11/21 22:49:14 Done.
189 FOR_EACH_OBSERVER(net::ProxyConfigService::Observer, observers_,
eroman 2010/11/20 03:19:07 Nit: we may broadcast a change event even though t
Mattias Nissler (ping if slow) 2010/11/21 22:49:14 You are right. I added an Equals() check to the pr
190 OnProxyConfigChanged(new_config));
191 }
192 }
193
194 void PrefProxyConfigService::RegisterObservers() {
195 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
196 if (!registered_observers_) {
197 base_service_->AddObserver(this);
198 pref_config_tracker_->AddObserver(this);
199 registered_observers_ = true;
200 }
201 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698