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

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

Powered by Google App Engine
This is Rietveld 408576698