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

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: Implement tests. 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 "base/ref_counted.h"
8 #include "chrome/browser/browser_thread.h"
9 #include "chrome/browser/prefs/pref_service.h"
10 #include "chrome/browser/prefs/pref_set_observer.h"
11 #include "chrome/common/notification_details.h"
12 #include "chrome/common/notification_observer.h"
13 #include "chrome/common/notification_source.h"
14 #include "chrome/common/notification_type.h"
15 #include "chrome/common/pref_names.h"
16
17 // A helper class that tracks proxy preferences. It translates the configuration
18 // to net::ProxyConfig and proxies the result over to PrefProxyConfigService on
19 // the IO thread.
20 class PrefProxyConfigService::PrefProxyConfigTracker
21 : public base::RefCountedThreadSafe<PrefProxyConfigTracker,
22 BrowserThread::DeleteOnUIThread>,
jochen (gone - plz use gerrit) 2010/11/16 22:48:32 make sure to run this on the valgrind bots
Mattias Nissler (ping if slow) 2010/11/16 22:58:11 Will do.
23 public NotificationObserver {
24 public:
25 PrefProxyConfigTracker(
26 base::WeakPtr<PrefProxyConfigService> pref_config_service,
27 PrefService* pref_service)
28 : pref_config_service_(pref_config_service),
29 pref_service_(pref_service) {
30 ReadPrefConfig(&pref_config_);
31 proxy_prefs_observer_.reset(
32 PrefSetObserver::CreateProxyPrefSetObserver(pref_service_, this));
33 }
34
35 virtual ~PrefProxyConfigTracker() {}
36
37 // Get the proxy configuration currently defined by preferences.
38 const net::ProxyConfig& GetProxyConfig() { return pref_config_; }
39
40 private:
41 // NotificationObserver implementation:
42 virtual void Observe(NotificationType type,
43 const NotificationSource& source,
44 const NotificationDetails& details);
45
46 // Install a new configuration (to be called on the IO thread).
47 void InstallProxyConfig(const net::ProxyConfig& config);
48
49 // Creates a proxy configuration from proxy-related preferences. Sets |config|
50 // to invalid if there's no proxy configuration defined in prefs.
51 void ReadPrefConfig(net::ProxyConfig* config);
52
53 // Configuration as defined by prefs. Only to be accessed from the IO thread
54 // (expect for construction).
55 net::ProxyConfig pref_config_;
56
57 base::WeakPtr<PrefProxyConfigService> pref_config_service_;
58 PrefService* pref_service_;
59 scoped_ptr<PrefSetObserver> proxy_prefs_observer_;
60 };
jochen (gone - plz use gerrit) 2010/11/16 22:48:32 disallow copy and assign?
Mattias Nissler (ping if slow) 2010/11/16 22:58:11 Done.
61
62 void PrefProxyConfigService::PrefProxyConfigTracker::Observe(
63 NotificationType type,
64 const NotificationSource& source,
65 const NotificationDetails& details) {
66 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
67 if (type == NotificationType::PREF_CHANGED &&
68 Source<PrefService>(source).ptr() == pref_service_) {
69 net::ProxyConfig new_config;
70 ReadPrefConfig(&new_config);
71 BrowserThread::PostTask(
72 BrowserThread::IO, FROM_HERE,
73 NewRunnableMethod(this,
74 &PrefProxyConfigTracker::InstallProxyConfig,
75 new_config));
76 } else {
77 NOTREACHED() << "Unexpected notification of type " << type.value;
78 }
79 }
80
81 void PrefProxyConfigService::PrefProxyConfigTracker::InstallProxyConfig(
82 const net::ProxyConfig& config) {
83 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
84 pref_config_ = config;
85 if (pref_config_service_.get())
86 pref_config_service_->PrefProxyConfigChanged();
87 }
88
89 void PrefProxyConfigService::PrefProxyConfigTracker::ReadPrefConfig(
90 net::ProxyConfig* config) {
91 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
92
93 // Invalidate the configuration.
94 config->set_id(net::ProxyConfig::INVALID_ID);
95
96 // Scan for all "enable" type proxy switches.
97 static const char* proxy_prefs[] = {
98 prefs::kProxyPacUrl,
99 prefs::kProxyServer,
100 prefs::kProxyBypassList,
101 prefs::kProxyAutoDetect
102 };
103
104 // Check whether the preference system holds a valid proxy configuration. Note
105 // that preferences coming from a lower-priority source than the user settings
106 // are ignored. That's because chrome treats the system settings as the
107 // default values, which should apply if there's no explicit value forced by
108 // policy or the user.
109 bool found_enable_proxy_pref = false;
110 for (size_t i = 0; i < arraysize(proxy_prefs); i++) {
111 const PrefService::Preference* pref =
112 pref_service_->FindPreference(proxy_prefs[i]);
113 DCHECK(pref);
114 if (pref && (!pref->IsUserModifiable() || pref->HasUserSetting())) {
115 found_enable_proxy_pref = true;
116 break;
117 }
118 }
119
120 if (!found_enable_proxy_pref &&
121 !pref_service_->GetBoolean(prefs::kNoProxyServer)) {
122 return;
123 }
124
125 // There is a valid configuration present.
126 config->set_id(1);
127
128 if (pref_service_->GetBoolean(prefs::kNoProxyServer)) {
129 // Ignore all the other proxy config preferences if the use of a proxy
130 // has been explicitly disabled.
131 return;
132 }
133
134 if (pref_service_->HasPrefPath(prefs::kProxyServer)) {
135 std::string proxy_server = pref_service_->GetString(prefs::kProxyServer);
136 config->proxy_rules().ParseFromString(proxy_server);
137 }
138
139 if (pref_service_->HasPrefPath(prefs::kProxyPacUrl)) {
140 std::string proxy_pac = pref_service_->GetString(prefs::kProxyPacUrl);
141 config->set_pac_url(GURL(proxy_pac));
142 }
143
144 config->set_auto_detect(pref_service_->GetBoolean(prefs::kProxyAutoDetect));
145
146 if (pref_service_->HasPrefPath(prefs::kProxyBypassList)) {
147 std::string proxy_bypass =
148 pref_service_->GetString(prefs::kProxyBypassList);
149 config->proxy_rules().bypass_rules.ParseFromString(proxy_bypass);
150 }
151 }
152
153 PrefProxyConfigService::PrefProxyConfigService(
154 PrefService* pref_service,
155 net::ProxyConfigService* base_service)
156 : base_service_(base_service),
157 current_id_(1) {
158 pref_config_tracker_ = new PrefProxyConfigTracker(AsWeakPtr(), pref_service);
159 base_service_->AddObserver(this);
160 }
161
162 PrefProxyConfigService::~PrefProxyConfigService() {
163 base_service_->RemoveObserver(this);
164 }
165
166 void PrefProxyConfigService::PrefProxyConfigChanged() {
167 ++current_id_;
168 net::ProxyConfig current_config;
169 GetLatestProxyConfig(&current_config);
170 FOR_EACH_OBSERVER(net::ProxyConfigService::Observer, observers_,
171 OnProxyConfigChanged(current_config));
172 }
173
174 void PrefProxyConfigService::AddObserver(
175 net::ProxyConfigService::Observer* observer) {
176 observers_.AddObserver(observer);
177 }
178
179 void PrefProxyConfigService::RemoveObserver(
180 net::ProxyConfigService::Observer* observer) {
181 observers_.RemoveObserver(observer);
182 }
183
184 bool PrefProxyConfigService::GetLatestProxyConfig(net::ProxyConfig* config) {
185 const net::ProxyConfig& pref_config(pref_config_tracker_->GetProxyConfig());
186 if (pref_config.is_valid()) {
187 *config = pref_config;
188 config->set_id(current_id_);
189 return true;
190 }
191
192 bool result = base_service_->GetLatestProxyConfig(config);
193 if (config->is_valid())
194 config->set_id(current_id_);
195 return result;
196 }
197
198 void PrefProxyConfigService::OnLazyPoll() {
199 base_service_->OnLazyPoll();
200 }
201
202 void PrefProxyConfigService::OnProxyConfigChanged(
203 const net::ProxyConfig& config) {
204 if (!pref_config_tracker_->GetProxyConfig().is_valid()) {
205 net::ProxyConfig new_config = config;
206 new_config.set_id(++current_id_);
207 FOR_EACH_OBSERVER(net::ProxyConfigService::Observer, observers_,
208 OnProxyConfigChanged(new_config));
209 }
210 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698