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

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 Jochen's comments. Created 10 years 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 DCHECK(pref_service_ == NULL);
24 }
25
26 bool PrefProxyConfigTracker::GetProxyConfig(net::ProxyConfig* config) {
27 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
28 if (valid_)
29 *config = pref_config_;
30 return valid_;
31 }
32
33 void PrefProxyConfigTracker::DetachFromPrefService() {
34 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
35 // Stop notifications.
36 proxy_prefs_observer_.reset();
37 pref_service_ = NULL;
38 }
39
40 void PrefProxyConfigTracker::AddObserver(
41 PrefProxyConfigTracker::ObserverInterface* observer) {
42 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
43 observers_.AddObserver(observer);
44 }
45
46 void PrefProxyConfigTracker::RemoveObserver(
47 PrefProxyConfigTracker::ObserverInterface* observer) {
48 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
49 observers_.RemoveObserver(observer);
50 }
51
52 void PrefProxyConfigTracker::Observe(NotificationType type,
53 const NotificationSource& source,
54 const NotificationDetails& details) {
55 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
56 if (type == NotificationType::PREF_CHANGED &&
57 Source<PrefService>(source).ptr() == pref_service_) {
58 net::ProxyConfig new_config;
59 bool valid = ReadPrefConfig(&new_config);
60 BrowserThread::PostTask(
61 BrowserThread::IO, FROM_HERE,
62 NewRunnableMethod(this,
63 &PrefProxyConfigTracker::InstallProxyConfig,
64 new_config, valid));
65 } else {
66 NOTREACHED() << "Unexpected notification of type " << type.value;
67 }
68 }
69
70 void PrefProxyConfigTracker::InstallProxyConfig(const net::ProxyConfig& config,
71 bool valid) {
72 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
73 if (valid_ != valid || !pref_config_.Equals(config)) {
eroman 2010/11/30 02:58:54 This is a little weird in the case where (!valid_
battre (please use the other) 2010/12/02 18:06:12 Done.
74 valid_ = valid;
75 if (valid_)
76 pref_config_ = config;
77 FOR_EACH_OBSERVER(ObserverInterface, observers_,
78 OnPrefProxyConfigChanged());
79 }
80 }
81
82 bool PrefProxyConfigTracker::ReadPrefConfig(net::ProxyConfig* config) {
83 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
84
85 // Clear the configuration.
86 *config = net::ProxyConfig();
87
88 // Scan for all "enable" type proxy switches.
89 static const char* proxy_prefs[] = {
90 prefs::kProxyPacUrl,
91 prefs::kProxyServer,
92 prefs::kProxyBypassList,
93 prefs::kProxyAutoDetect
94 };
95
96 // Check whether the preference system holds a valid proxy configuration. Note
97 // that preferences coming from a lower-priority source than the user settings
98 // are ignored. That's because chrome treats the system settings as the
99 // default values, which should apply if there's no explicit value forced by
100 // policy or the user.
101 bool found_enable_proxy_pref = false;
102 for (size_t i = 0; i < arraysize(proxy_prefs); i++) {
103 const PrefService::Preference* pref =
104 pref_service_->FindPreference(proxy_prefs[i]);
105 DCHECK(pref);
106 if (pref && (!pref->IsUserModifiable() || pref->HasUserSetting())) {
107 found_enable_proxy_pref = true;
108 break;
109 }
110 }
111
112 if (!found_enable_proxy_pref &&
113 !pref_service_->GetBoolean(prefs::kNoProxyServer)) {
114 return false;
115 }
116
117 if (pref_service_->GetBoolean(prefs::kNoProxyServer)) {
118 // Ignore all the other proxy config preferences if the use of a proxy
119 // has been explicitly disabled.
120 return true;
121 }
122
123 if (pref_service_->HasPrefPath(prefs::kProxyServer)) {
124 std::string proxy_server = pref_service_->GetString(prefs::kProxyServer);
125 config->proxy_rules().ParseFromString(proxy_server);
126 }
127
128 if (pref_service_->HasPrefPath(prefs::kProxyPacUrl)) {
129 std::string proxy_pac = pref_service_->GetString(prefs::kProxyPacUrl);
130 config->set_pac_url(GURL(proxy_pac));
131 }
132
133 config->set_auto_detect(pref_service_->GetBoolean(prefs::kProxyAutoDetect));
134
135 if (pref_service_->HasPrefPath(prefs::kProxyBypassList)) {
136 std::string proxy_bypass =
137 pref_service_->GetString(prefs::kProxyBypassList);
138 config->proxy_rules().bypass_rules.ParseFromString(proxy_bypass);
139 }
140
141 return true;
142 }
143
144 PrefProxyConfigService::PrefProxyConfigService(
145 PrefProxyConfigTracker* tracker,
146 net::ProxyConfigService* base_service)
147 : base_service_(base_service),
148 pref_config_tracker_(tracker),
149 registered_observers_(false) {
150 }
151
152 PrefProxyConfigService::~PrefProxyConfigService() {
153 if (registered_observers_) {
154 base_service_->RemoveObserver(this);
155 pref_config_tracker_->RemoveObserver(this);
156 }
157 }
158
159 void PrefProxyConfigService::AddObserver(
160 net::ProxyConfigService::Observer* observer) {
161 RegisterObservers();
162 observers_.AddObserver(observer);
163 }
164
165 void PrefProxyConfigService::RemoveObserver(
166 net::ProxyConfigService::Observer* observer) {
167 observers_.RemoveObserver(observer);
168 }
169
170 bool PrefProxyConfigService::GetLatestProxyConfig(net::ProxyConfig* config) {
171 RegisterObservers();
172 const net::ProxyConfig pref_config;
173 if (pref_config_tracker_->GetProxyConfig(config))
174 return true;
175
176 return base_service_->GetLatestProxyConfig(config);
177 }
178
179 void PrefProxyConfigService::OnLazyPoll() {
180 base_service_->OnLazyPoll();
181 }
182
183 void PrefProxyConfigService::OnProxyConfigChanged(
184 const net::ProxyConfig& config) {
185 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
186
187 // Check whether there is a proxy configuration defined by preferences. In
188 // this case that proxy configuration takes precedence and the change event
189 // from the delegate proxy service can be disregarded.
190 net::ProxyConfig pref_config;
191 if (!pref_config_tracker_->GetProxyConfig(&pref_config)) {
192 FOR_EACH_OBSERVER(net::ProxyConfigService::Observer, observers_,
193 OnProxyConfigChanged(config));
194 }
195 }
196
197 void PrefProxyConfigService::OnPrefProxyConfigChanged() {
198 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
199
200 // Evaluate the proxy configuration. If GetLatestProxyConfig returns false,
201 // we are using the system proxy service, but it doesn't have a valid
202 // configuration yet. Once it is ready, OnProxyConfigChanged() will be called
203 // and broadcast the proxy configuration.
204 // Note: If a switch between a preference proxy configuration and the system
205 // proxy configuration occurs an unnecessary notification might get send if
206 // the two configurations agree. This case should be rare however, so we don't
207 // handle that case specially.
208 net::ProxyConfig new_config;
209 if (GetLatestProxyConfig(&new_config)) {
210 FOR_EACH_OBSERVER(net::ProxyConfigService::Observer, observers_,
211 OnProxyConfigChanged(new_config));
212 }
213 }
214
215 void PrefProxyConfigService::RegisterObservers() {
216 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
217 if (!registered_observers_) {
218 base_service_->AddObserver(this);
219 pref_config_tracker_->AddObserver(this);
220 registered_observers_ = true;
221 }
222 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698