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

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

Issue 8102019: redesign and reimplement proxy config service and tracker, revise proxy ui on cros (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 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) 2011 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 "base/values.h"
8 #include "chrome/browser/prefs/pref_service.h"
9 #include "chrome/browser/prefs/pref_set_observer.h"
10 #include "chrome/browser/prefs/proxy_config_dictionary.h"
11 #include "chrome/common/chrome_notification_types.h"
12 #include "chrome/common/pref_names.h"
13 #include "content/public/browser/browser_thread.h"
14 #include "content/public/browser/notification_details.h"
15 #include "content/public/browser/notification_source.h"
16
17 using content::BrowserThread;
18
19 PrefProxyConfigTracker::PrefProxyConfigTracker(PrefService* pref_service)
20 : pref_service_(pref_service) {
21 config_state_ = ReadPrefConfig(&pref_config_);
22 proxy_prefs_observer_.reset(
23 PrefSetObserver::CreateProxyPrefSetObserver(pref_service_, this));
24 }
25
26 PrefProxyConfigTracker::~PrefProxyConfigTracker() {
27 DCHECK(pref_service_ == NULL);
28 }
29
30 PrefProxyConfigTracker::ConfigState
31 PrefProxyConfigTracker::GetProxyConfig(net::ProxyConfig* config) {
32 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
33 if (config_state_ != CONFIG_UNSET)
34 *config = pref_config_;
35 return config_state_;
36 }
37
38 void PrefProxyConfigTracker::DetachFromPrefService() {
39 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
40 // Stop notifications.
41 proxy_prefs_observer_.reset();
42 pref_service_ = NULL;
43 }
44
45 void PrefProxyConfigTracker::AddObserver(
46 PrefProxyConfigTracker::Observer* observer) {
47 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
48 observers_.AddObserver(observer);
49 }
50
51 void PrefProxyConfigTracker::RemoveObserver(
52 PrefProxyConfigTracker::Observer* observer) {
53 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
54 observers_.RemoveObserver(observer);
55 }
56
57 void PrefProxyConfigTracker::Observe(
58 int type,
59 const content::NotificationSource& source,
60 const content::NotificationDetails& details) {
61 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
62 if (type == chrome::NOTIFICATION_PREF_CHANGED &&
63 content::Source<PrefService>(source).ptr() == pref_service_) {
64 net::ProxyConfig new_config;
65 ConfigState config_state = ReadPrefConfig(&new_config);
66 BrowserThread::PostTask(
67 BrowserThread::IO, FROM_HERE,
68 NewRunnableMethod(this,
69 &PrefProxyConfigTracker::InstallProxyConfig,
70 new_config, config_state));
71 } else {
72 NOTREACHED() << "Unexpected notification of type " << type;
73 }
74 }
75
76 void PrefProxyConfigTracker::InstallProxyConfig(
77 const net::ProxyConfig& config,
78 PrefProxyConfigTracker::ConfigState config_state) {
79 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
80 if (config_state_ != config_state ||
81 (config_state_ != CONFIG_UNSET && !pref_config_.Equals(config))) {
82 config_state_ = config_state;
83 if (config_state_ != CONFIG_UNSET)
84 pref_config_ = config;
85 FOR_EACH_OBSERVER(Observer, observers_, OnPrefProxyConfigChanged());
86 }
87 }
88
89 PrefProxyConfigTracker::ConfigState
90 PrefProxyConfigTracker::ReadPrefConfig(net::ProxyConfig* config) {
91 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
92
93 // Clear the configuration.
94 *config = net::ProxyConfig();
95
96 const PrefService::Preference* pref =
97 pref_service_->FindPreference(prefs::kProxy);
98 DCHECK(pref);
99
100 const DictionaryValue* dict = pref_service_->GetDictionary(prefs::kProxy);
101 DCHECK(dict);
102 ProxyConfigDictionary proxy_dict(dict);
103
104 if (PrefConfigToNetConfig(proxy_dict, config)) {
105 return (!pref->IsUserModifiable() || pref->HasUserSetting()) ?
106 CONFIG_PRESENT : CONFIG_FALLBACK;
107 }
108
109 return CONFIG_UNSET;
110 }
111
112 bool PrefProxyConfigTracker::PrefConfigToNetConfig(
113 const ProxyConfigDictionary& proxy_dict,
114 net::ProxyConfig* config) {
115 ProxyPrefs::ProxyMode mode;
116 if (!proxy_dict.GetMode(&mode)) {
117 // Fall back to system settings if the mode preference is invalid.
118 return false;
119 }
120
121 switch (mode) {
122 case ProxyPrefs::MODE_SYSTEM:
123 // Use system settings.
124 return false;
125 case ProxyPrefs::MODE_DIRECT:
126 // Ignore all the other proxy config preferences if the use of a proxy
127 // has been explicitly disabled.
128 return true;
129 case ProxyPrefs::MODE_AUTO_DETECT:
130 config->set_auto_detect(true);
131 return true;
132 case ProxyPrefs::MODE_PAC_SCRIPT: {
133 std::string proxy_pac;
134 if (!proxy_dict.GetPacUrl(&proxy_pac)) {
135 LOG(ERROR) << "Proxy settings request PAC script but do not specify "
136 << "its URL. Falling back to direct connection.";
137 return true;
138 }
139 GURL proxy_pac_url(proxy_pac);
140 if (!proxy_pac_url.is_valid()) {
141 LOG(ERROR) << "Invalid proxy PAC url: " << proxy_pac;
142 return true;
143 }
144 config->set_pac_url(proxy_pac_url);
145 bool pac_mandatory = false;
146 proxy_dict.GetPacMandatory(&pac_mandatory);
147 config->set_pac_mandatory(pac_mandatory);
148 return true;
149 }
150 case ProxyPrefs::MODE_FIXED_SERVERS: {
151 std::string proxy_server;
152 if (!proxy_dict.GetProxyServer(&proxy_server)) {
153 LOG(ERROR) << "Proxy settings request fixed proxy servers but do not "
154 << "specify their URLs. Falling back to direct connection.";
155 return true;
156 }
157 config->proxy_rules().ParseFromString(proxy_server);
158
159 std::string proxy_bypass;
160 if (proxy_dict.GetBypassList(&proxy_bypass)) {
161 config->proxy_rules().bypass_rules.ParseFromString(proxy_bypass);
162 }
163 return true;
164 }
165 case ProxyPrefs::kModeCount: {
166 // Fall through to NOTREACHED().
167 }
168 }
169 NOTREACHED() << "Unknown proxy mode, falling back to system settings.";
170 return false;
171 }
172
173 PrefProxyConfigService::PrefProxyConfigService(
174 PrefProxyConfigTracker* tracker,
175 net::ProxyConfigService* base_service)
176 : base_service_(base_service),
177 pref_config_tracker_(tracker),
178 registered_observers_(false) {
179 }
180
181 PrefProxyConfigService::~PrefProxyConfigService() {
182 if (registered_observers_) {
183 base_service_->RemoveObserver(this);
184 pref_config_tracker_->RemoveObserver(this);
185 }
186 }
187
188 void PrefProxyConfigService::AddObserver(
189 net::ProxyConfigService::Observer* observer) {
190 RegisterObservers();
191 observers_.AddObserver(observer);
192 }
193
194 void PrefProxyConfigService::RemoveObserver(
195 net::ProxyConfigService::Observer* observer) {
196 observers_.RemoveObserver(observer);
197 }
198
199 net::ProxyConfigService::ConfigAvailability
200 PrefProxyConfigService::GetLatestProxyConfig(net::ProxyConfig* config) {
201 RegisterObservers();
202 net::ProxyConfig pref_config;
203 PrefProxyConfigTracker::ConfigState state =
204 pref_config_tracker_->GetProxyConfig(&pref_config);
205 if (state == PrefProxyConfigTracker::CONFIG_PRESENT) {
206 *config = pref_config;
207 return CONFIG_VALID;
208 }
209
210 // Ask the base service.
211 ConfigAvailability available = base_service_->GetLatestProxyConfig(config);
212
213 // Base service doesn't have a configuration, fall back to prefs or default.
214 if (available == CONFIG_UNSET) {
215 if (state == PrefProxyConfigTracker::CONFIG_FALLBACK)
216 *config = pref_config;
217 else
218 *config = net::ProxyConfig::CreateDirect();
219 return CONFIG_VALID;
220 }
221
222 return available;
223 }
224
225 void PrefProxyConfigService::OnLazyPoll() {
226 base_service_->OnLazyPoll();
227 }
228
229 void PrefProxyConfigService::OnProxyConfigChanged(
230 const net::ProxyConfig& config,
231 ConfigAvailability availability) {
232 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
233
234 // Check whether there is a proxy configuration defined by preferences. In
235 // this case that proxy configuration takes precedence and the change event
236 // from the delegate proxy service can be disregarded.
237 net::ProxyConfig actual_config;
238 if (pref_config_tracker_->GetProxyConfig(&actual_config) !=
239 PrefProxyConfigTracker::CONFIG_PRESENT) {
240 availability = GetLatestProxyConfig(&actual_config);
241 FOR_EACH_OBSERVER(net::ProxyConfigService::Observer, observers_,
242 OnProxyConfigChanged(actual_config, availability));
243 }
244 }
245
246 void PrefProxyConfigService::OnPrefProxyConfigChanged() {
247 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
248
249 // Evaluate the proxy configuration. If GetLatestProxyConfig returns
250 // CONFIG_PENDING, we are using the system proxy service, but it doesn't have
251 // a valid configuration yet. Once it is ready, OnProxyConfigChanged() will be
252 // called and broadcast the proxy configuration.
253 // Note: If a switch between a preference proxy configuration and the system
254 // proxy configuration occurs an unnecessary notification might get send if
255 // the two configurations agree. This case should be rare however, so we don't
256 // handle that case specially.
257 net::ProxyConfig new_config;
258 ConfigAvailability availability = GetLatestProxyConfig(&new_config);
259 if (availability != CONFIG_PENDING) {
260 FOR_EACH_OBSERVER(net::ProxyConfigService::Observer, observers_,
261 OnProxyConfigChanged(new_config, availability));
262 }
263 }
264
265 void PrefProxyConfigService::RegisterObservers() {
266 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
267 if (!registered_observers_) {
268 base_service_->AddObserver(this);
269 pref_config_tracker_->AddObserver(this);
270 registered_observers_ = true;
271 }
272 }
273
274 // static
275 void PrefProxyConfigService::RegisterPrefs(PrefService* pref_service) {
276 DictionaryValue* default_settings = ProxyConfigDictionary::CreateSystem();
277 pref_service->RegisterDictionaryPref(prefs::kProxy,
278 default_settings,
279 PrefService::UNSYNCABLE_PREF);
280 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698