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

Side by Side Diff: chrome/browser/policy/url_blacklist_manager.cc

Issue 10692158: Refactor URLBlacklistManager to use URLMatcher. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 8 years, 5 months 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
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/policy/url_blacklist_manager.h" 5 #include "chrome/browser/policy/url_blacklist_manager.h"
6 6
7 #include <algorithm>
8
7 #include "base/bind.h" 9 #include "base/bind.h"
8 #include "base/message_loop.h" 10 #include "base/message_loop.h"
9 #include "base/stl_util.h" 11 #include "base/stl_util.h"
10 #include "base/string_number_conversions.h" 12 #include "base/string_number_conversions.h"
11 #include "base/values.h" 13 #include "base/values.h"
12 #include "chrome/browser/net/url_fixer_upper.h" 14 #include "chrome/browser/net/url_fixer_upper.h"
13 #include "chrome/browser/prefs/pref_service.h" 15 #include "chrome/browser/prefs/pref_service.h"
14 #include "chrome/common/chrome_notification_types.h" 16 #include "chrome/common/chrome_notification_types.h"
17 #include "chrome/common/extensions/matcher/url_matcher.h"
15 #include "chrome/common/pref_names.h" 18 #include "chrome/common/pref_names.h"
16 #include "content/public/browser/browser_thread.h" 19 #include "content/public/browser/browser_thread.h"
17 #include "content/public/browser/notification_details.h" 20 #include "content/public/browser/notification_details.h"
18 #include "content/public/browser/notification_source.h" 21 #include "content/public/browser/notification_source.h"
19 #include "googleurl/src/gurl.h" 22 #include "googleurl/src/gurl.h"
20 23
21 using content::BrowserThread; 24 using content::BrowserThread;
25 using extensions::URLMatcher;
26 using extensions::URLMatcherCondition;
27 using extensions::URLMatcherConditionFactory;
28 using extensions::URLMatcherConditionSet;
29 using extensions::URLMatcherPortFilter;
30 using extensions::URLMatcherSchemeFilter;
22 31
23 namespace policy { 32 namespace policy {
24 33
25 namespace { 34 namespace {
26 35
27 // Maximum filters per policy. Filters over this index are ignored. 36 // Maximum filters per policy. Filters over this index are ignored.
28 const size_t kMaxFiltersPerPolicy = 100; 37 const size_t kMaxFiltersPerPolicy = 100;
29 38
30 typedef std::vector<std::string> StringVector; 39 const char* kStandardSchemes[] = {
40 "http",
41 "https",
42 "file",
43 "ftp",
44 "gopher",
45 "ws",
46 "wss"
47 };
31 48
32 StringVector* ListValueToStringVector(const base::ListValue* list) { 49 bool IsStandardScheme(const std::string& scheme) {
33 StringVector* vector = new StringVector; 50 for (size_t i = 0; i < arraysize(kStandardSchemes); ++i) {
34 51 if (scheme == kStandardSchemes[i])
35 if (list == NULL) 52 return true;
36 return vector;
37
38 vector->reserve(list->GetSize());
39 std::string s;
40 for (base::ListValue::const_iterator it = list->begin();
41 it != list->end() && vector->size() < kMaxFiltersPerPolicy; ++it) {
42 if ((*it)->GetAsString(&s))
43 vector->push_back(s);
44 } 53 }
45 54 return false;
46 return vector;
47 } 55 }
48 56
49 // A task that builds the blacklist on the FILE thread. Takes ownership 57 // A task that builds the blacklist on the FILE thread.
50 // of |block| and |allow| but not of |blacklist|. 58 scoped_ptr<URLBlacklist> BuildBlacklist(scoped_ptr<base::ListValue> block,
51 void BuildBlacklist(URLBlacklist* blacklist, 59 scoped_ptr<base::ListValue> allow) {
52 StringVector* block,
53 StringVector* allow) {
54 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 60 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
55 61
56 scoped_ptr<StringVector> scoped_block(block); 62 scoped_ptr<URLBlacklist> blacklist(new URLBlacklist);
57 scoped_ptr<StringVector> scoped_allow(allow); 63 blacklist->Block(block.get());
58 64 blacklist->Allow(allow.get());
59 for (StringVector::iterator it = block->begin(); it != block->end(); ++it) { 65 return blacklist.Pass();
60 blacklist->Block(*it);
61 }
62 for (StringVector::iterator it = allow->begin(); it != allow->end(); ++it) {
63 blacklist->Allow(*it);
64 }
65 }
66
67 // A task that owns the URLBlacklist, and passes it to the URLBlacklistManager
68 // on the IO thread, if the URLBlacklistManager still exists.
69 void SetBlacklistOnIO(base::WeakPtr<URLBlacklistManager> blacklist_manager,
70 URLBlacklist* blacklist) {
71 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
72 if (blacklist_manager) {
73 blacklist_manager->SetBlacklist(blacklist);
74 } else {
75 delete blacklist;
76 }
77 } 66 }
78 67
79 } // namespace 68 } // namespace
80 69
81 struct URLBlacklist::PathFilter { 70 struct URLBlacklist::FilterComponents {
82 explicit PathFilter(const std::string& path, uint16 port, bool match) 71 FilterComponents() : match_subdomains(true), allow(true) {}
83 : path_prefix(path), 72 ~FilterComponents() {}
84 port(port),
85 blocked_schemes(0),
86 allowed_schemes(0),
87 match_subdomains(match) {}
88 73
89 std::string path_prefix; 74 std::string scheme;
75 std::string host;
90 uint16 port; 76 uint16 port;
91 uint8 blocked_schemes; 77 std::string path;
92 uint8 allowed_schemes;
93 bool match_subdomains; 78 bool match_subdomains;
79 bool allow;
94 }; 80 };
95 81
96 URLBlacklist::URLBlacklist() { 82 URLBlacklist::URLBlacklist() : id_(0),
83 url_matcher_(new URLMatcher) {
97 } 84 }
98 85
99 URLBlacklist::~URLBlacklist() { 86 URLBlacklist::~URLBlacklist() {
100 STLDeleteValues(&host_filters_);
101 } 87 }
102 88
103 void URLBlacklist::Block(const std::string& filter) { 89 void URLBlacklist::AddFilters(bool allow,
104 AddFilter(filter, true); 90 const base::ListValue* list) {
91 URLMatcherConditionSet::Vector all_conditions;
92 size_t size = std::min(kMaxFiltersPerPolicy, list->GetSize());
93 for (size_t i = 0; i < size; ++i) {
94 std::string pattern;
95 bool success = list->GetString(i, &pattern);
96 DCHECK(success);
97 FilterComponents components;
98 components.allow = allow;
99 if (!FilterToComponents(pattern, &components.scheme, &components.host,
100 &components.match_subdomains, &components.port,
101 &components.path)) {
102 LOG(ERROR) << "Invalid pattern " << pattern;
103 continue;
104 }
105
106 all_conditions.push_back(
107 CreateConditionSet(url_matcher_.get(), ++id_, components.scheme,
108 components.host, components.match_subdomains,
109 components.port, components.path));
110 filters_[id_] = components;
111 }
112 url_matcher_->AddConditionSets(all_conditions);
105 } 113 }
106 114
107 void URLBlacklist::Allow(const std::string& filter) { 115 void URLBlacklist::Block(const base::ListValue* filters) {
108 AddFilter(filter, false); 116 AddFilters(false, filters);
117 }
118
119 void URLBlacklist::Allow(const base::ListValue* filters) {
120 AddFilters(true, filters);
109 } 121 }
110 122
111 bool URLBlacklist::IsURLBlocked(const GURL& url) const { 123 bool URLBlacklist::IsURLBlocked(const GURL& url) const {
112 SchemeFlag flag = SCHEME_ALL; 124 if (!HasStandardScheme(url))
113 if (!SchemeToFlag(url.scheme(), &flag)) {
114 // Not a scheme that can be filtered.
115 return false; 125 return false;
126
127 std::set<URLMatcherConditionSet::ID> matching_ids =
128 url_matcher_->MatchURL(url);
129
130 const FilterComponents* max = NULL;
131 for (std::set<URLMatcherConditionSet::ID>::iterator id = matching_ids.begin();
132 id != matching_ids.end(); ++id) {
133 std::map<int, FilterComponents>::const_iterator it = filters_.find(*id);
134 DCHECK(it != filters_.end());
135 const FilterComponents& filter = it->second;
136 if (!max || FilterTakesPrecedence(filter, *max))
137 max = &filter;
116 } 138 }
117 139
118 std::string host(url.host()); 140 // Default to allow.
119 int int_port = url.EffectiveIntPort(); 141 if (!max)
120 const uint16 port = int_port > 0 ? int_port : 0; 142 return false;
121 const std::string& path = url.path();
122 143
123 // The first iteration through the loop will be an exact host match. 144 return !max->allow;
124 // Subsequent iterations are subdomain matches, and some filters don't apply 145 }
125 // to those.
126 bool is_matching_subdomains = false;
127 const bool host_is_ip = url.HostIsIPAddress();
128 while (1) {
129 HostFilterTable::const_iterator host_filter = host_filters_.find(host);
130 if (host_filter != host_filters_.end()) {
131 const PathFilterList* list = host_filter->second;
132 size_t longest_length = 0;
133 bool is_blocked = false;
134 bool has_match = false;
135 bool has_exact_host_match = false;
136 for (PathFilterList::const_iterator it = list->begin();
137 it != list->end(); ++it) {
138 // Filters that apply to an exact hostname only take precedence over
139 // filters that can apply to subdomains too.
140 // E.g. ".google.com" filters take priority over "google.com".
141 if (has_exact_host_match && it->match_subdomains)
142 continue;
143 146
144 // Skip if filter doesn't apply to subdomains, and this is a subdomain. 147 // static
145 if (is_matching_subdomains && !it->match_subdomains) 148 bool URLBlacklist::HasStandardScheme(const GURL& url) {
146 continue; 149 for (size_t i = 0; i < arraysize(kStandardSchemes); ++i) {
Joao da Silva 2012/07/13 12:32:11 return IsStandardScheme(url.scheme())?
Bernhard Bauer 2012/07/13 14:21:07 Done. Originally I used SchemeIs() because that do
147 150 if (url.SchemeIs(kStandardSchemes[i]))
148 if (it->port != 0 && it->port != port) 151 return true;
149 continue;
150
151 // Skip if the filter doesn't apply to the scheme.
152 if ((it->allowed_schemes & flag) == 0 &&
153 (it->blocked_schemes & flag) == 0)
154 continue;
155
156 // If this match can't be longer than the current match, skip it.
157 // For same size matches, the first rule to match takes precedence.
158 // If this is an exact host match, it can be actually shorter than
159 // a previous, non-exact match.
160 if ((has_match && it->path_prefix.length() <= longest_length) &&
161 (has_exact_host_match || it->match_subdomains)) {
162 continue;
163 }
164
165 // Skip if the filter's |path_prefix| is not a prefix of |path|.
166 if (path.compare(0, it->path_prefix.length(), it->path_prefix) != 0)
167 continue;
168
169 // This is the best match so far.
170 has_match = true;
171 has_exact_host_match = !it->match_subdomains;
172 longest_length = it->path_prefix.length();
173 // If both blocked and allowed bits are set, allowed takes precedence.
174 is_blocked = !(it->allowed_schemes & flag);
175 }
176 // If a match was found, return its decision.
177 if (has_match)
178 return is_blocked;
179 }
180
181 // Quit after trying the empty string (corresponding to host '*').
182 // Also skip subdomain matching for IP addresses.
183 if (host.empty() || host_is_ip)
184 break;
185
186 // No match found for this host. Try a subdomain match, by removing the
187 // leftmost subdomain from the hostname.
188 is_matching_subdomains = true;
189 size_t i = host.find('.');
190 if (i != std::string::npos)
191 ++i;
192 host.erase(0, i);
193 } 152 }
194
195 // Default is to allow.
196 return false; 153 return false;
197 } 154 }
198 155
199 // static 156 // static
200 bool URLBlacklist::SchemeToFlag(const std::string& scheme, SchemeFlag* flag) {
201 if (scheme.empty()) {
202 *flag = SCHEME_ALL;
203 } else if (scheme == "http") {
204 *flag = SCHEME_HTTP;
205 } else if (scheme == "https") {
206 *flag = SCHEME_HTTPS;
207 } else if (scheme == "ftp") {
208 *flag = SCHEME_FTP;
209 } else if (scheme == "ws") {
210 *flag = SCHEME_WS;
211 } else if (scheme == "wss") {
212 *flag = SCHEME_WSS;
213 } else {
214 return false;
215 }
216 return true;
217 }
218
219 // static
220 bool URLBlacklist::FilterToComponents(const std::string& filter, 157 bool URLBlacklist::FilterToComponents(const std::string& filter,
221 std::string* scheme, 158 std::string* scheme,
222 std::string* host, 159 std::string* host,
223 uint16* port, 160 bool* match_subdomains,
224 std::string* path) { 161 uint16* port,
162 std::string* path) {
225 url_parse::Parsed parsed; 163 url_parse::Parsed parsed;
226 URLFixerUpper::SegmentURL(filter, &parsed); 164 URLFixerUpper::SegmentURL(filter, &parsed);
227 165
228 if (!parsed.host.is_nonempty()) 166 if (!parsed.host.is_nonempty())
229 return false; 167 return false;
230 168
231 if (parsed.scheme.is_nonempty()) 169 if (parsed.scheme.is_nonempty())
232 scheme->assign(filter, parsed.scheme.begin, parsed.scheme.len); 170 scheme->assign(filter, parsed.scheme.begin, parsed.scheme.len);
233 else 171 else
234 scheme->clear(); 172 scheme->clear();
235 173
236 host->assign(filter, parsed.host.begin, parsed.host.len); 174 host->assign(filter, parsed.host.begin, parsed.host.len);
237 // Special '*' host, matches all hosts. 175 // Special '*' host, matches all hosts.
238 if (*host == "*") 176 if (*host == "*") {
239 host->clear(); 177 host->clear();
178 *match_subdomains = true;
179 } else if ((*host)[0] == '.') {
180 // A leading dot in the pattern syntax means that we don't want to match
181 // subdomains.
182 host->erase(0, 1);
183 *match_subdomains = false;
184 } else {
185 url_canon::RawCanonOutputT<char> output;
186 url_canon::CanonHostInfo host_info;
187 url_canon::CanonicalizeHostVerbose(filter.c_str(), parsed.host,
188 &output, &host_info);
189 if (host_info.family == url_canon::CanonHostInfo::NEUTRAL) {
190 // We want to match subdomains. Add a dot in front to make sure we only
191 // match at domain component boundaries.
192 *host = "." + *host;
193 *match_subdomains = true;
194 } else {
195 *match_subdomains = false;
196 }
197 }
240 198
241 if (parsed.port.is_nonempty()) { 199 if (parsed.port.is_nonempty()) {
242 int int_port; 200 int int_port;
243 if (!base::StringToInt(filter.substr(parsed.port.begin, parsed.port.len), 201 if (!base::StringToInt(filter.substr(parsed.port.begin, parsed.port.len),
244 &int_port)) { 202 &int_port)) {
245 return false; 203 return false;
246 } 204 }
247 if (int_port <= 0 || int_port > kuint16max) 205 if (int_port <= 0 || int_port > kuint16max)
248 return false; 206 return false;
249 *port = int_port; 207 *port = int_port;
250 } else { 208 } else {
251 // Match any port. 209 // Match any port.
252 *port = 0; 210 *port = 0;
253 } 211 }
254 212
255 if (parsed.path.is_nonempty()) 213 if (parsed.path.is_nonempty())
256 path->assign(filter, parsed.path.begin, parsed.path.len); 214 path->assign(filter, parsed.path.begin, parsed.path.len);
257 else 215 else
258 path->clear(); 216 path->clear();
259 217
218 if (!scheme->empty() && !IsStandardScheme(*scheme))
219 return false;
220
260 return true; 221 return true;
261 } 222 }
262 223
263 void URLBlacklist::AddFilter(const std::string& filter, bool block) { 224 // static
264 std::string scheme; 225 scoped_refptr<extensions::URLMatcherConditionSet>
265 std::string host; 226 URLBlacklist::CreateConditionSet(
266 uint16 port; 227 extensions::URLMatcher* url_matcher,
267 std::string path; 228 int id,
268 if (!FilterToComponents(filter, &scheme, &host, &port, &path)) { 229 const std::string& scheme,
269 LOG(WARNING) << "Invalid filter, ignoring: " << filter; 230 const std::string& host,
270 return; 231 bool match_subdomains,
232 uint16 port,
233 const std::string& path) {
234 URLMatcherConditionFactory* condition_factory =
235 url_matcher->condition_factory();
236 std::set<URLMatcherCondition> conditions;
237 conditions.insert(match_subdomains ?
238 condition_factory->CreateHostSuffixPathPrefixCondition(host, path) :
239 condition_factory->CreateHostEqualsPathPrefixCondition(host, path));
240
241 scoped_ptr<URLMatcherSchemeFilter> scheme_filter;
242 if (!scheme.empty())
243 scheme_filter.reset(new URLMatcherSchemeFilter(scheme));
244
245 scoped_ptr<URLMatcherPortFilter> port_filter;
246 if (port != 0) {
247 std::vector<URLMatcherPortFilter::Range> ranges;
248 ranges.push_back(URLMatcherPortFilter::CreateRange(port));
249 port_filter.reset(new URLMatcherPortFilter(ranges));
271 } 250 }
272 251
273 SchemeFlag flag; 252 return new URLMatcherConditionSet(id, conditions,
274 if (!SchemeToFlag(scheme, &flag)) { 253 scheme_filter.Pass(), port_filter.Pass());
275 LOG(WARNING) << "Unsupported scheme in filter, ignoring filter: " << filter; 254 }
276 return;
277 }
278 255
279 bool match_subdomains = true; 256 // static
280 // Special syntax to disable subdomain matching. 257 bool URLBlacklist::FilterTakesPrecedence(const FilterComponents& lhs,
281 if (!host.empty() && host[0] == '.') { 258 const FilterComponents& rhs) {
282 host.erase(0, 1); 259 if (lhs.match_subdomains && !rhs.match_subdomains)
283 match_subdomains = false; 260 return false;
284 } 261 if (!lhs.match_subdomains && rhs.match_subdomains)
262 return true;
285 263
286 // Try to find an existing PathFilter with the same path prefix, port and 264 size_t host_length = lhs.host.length();
287 // match_subdomains value. 265 size_t other_host_length = rhs.host.length();
288 PathFilterList* list; 266 if (host_length < other_host_length)
289 HostFilterTable::iterator host_filter = host_filters_.find(host); 267 return false;
290 if (host_filter == host_filters_.end()) { 268 if (host_length > other_host_length)
291 list = new PathFilterList; 269 return true;
292 host_filters_[host] = list;
293 } else {
294 list = host_filter->second;
295 }
296 PathFilterList::iterator it;
297 for (it = list->begin(); it != list->end(); ++it) {
298 if (it->port == port && it->match_subdomains == match_subdomains &&
299 it->path_prefix == path) {
300 break;
301 }
302 }
303 PathFilter* path_filter;
304 if (it == list->end()) {
305 list->push_back(PathFilter(path, port, match_subdomains));
306 path_filter = &list->back();
307 } else {
308 path_filter = &(*it);
309 }
310 270
311 if (block) { 271 size_t path_length = lhs.path.length();
312 path_filter->blocked_schemes |= flag; 272 size_t other_path_length = rhs.path.length();
313 } else { 273 if (path_length < other_path_length)
314 path_filter->allowed_schemes |= flag; 274 return false;
315 } 275 if (path_length > other_path_length)
276 return true;
277
278 if (lhs.allow && !rhs.allow)
279 return true;
280
281 return false;
316 } 282 }
317 283
318 URLBlacklistManager::URLBlacklistManager(PrefService* pref_service) 284 URLBlacklistManager::URLBlacklistManager(PrefService* pref_service)
319 : ALLOW_THIS_IN_INITIALIZER_LIST(ui_weak_ptr_factory_(this)), 285 : ALLOW_THIS_IN_INITIALIZER_LIST(ui_weak_ptr_factory_(this)),
320 pref_service_(pref_service), 286 pref_service_(pref_service),
321 ALLOW_THIS_IN_INITIALIZER_LIST(io_weak_ptr_factory_(this)), 287 ALLOW_THIS_IN_INITIALIZER_LIST(io_weak_ptr_factory_(this)),
322 blacklist_(new URLBlacklist) { 288 blacklist_(new URLBlacklist) {
323 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 289 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
324 290
325 pref_change_registrar_.Init(pref_service_); 291 pref_change_registrar_.Init(pref_service_);
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
364 MessageLoop::current()->PostTask( 330 MessageLoop::current()->PostTask(
365 FROM_HERE, 331 FROM_HERE,
366 base::Bind(&URLBlacklistManager::Update, 332 base::Bind(&URLBlacklistManager::Update,
367 ui_weak_ptr_factory_.GetWeakPtr())); 333 ui_weak_ptr_factory_.GetWeakPtr()));
368 } 334 }
369 335
370 void URLBlacklistManager::Update() { 336 void URLBlacklistManager::Update() {
371 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 337 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
372 338
373 // The preferences can only be read on the UI thread. 339 // The preferences can only be read on the UI thread.
374 StringVector* block = 340 scoped_ptr<base::ListValue> block(
375 ListValueToStringVector(pref_service_->GetList(prefs::kUrlBlacklist)); 341 pref_service_->GetList(prefs::kUrlBlacklist)->DeepCopy());
376 StringVector* allow = 342 scoped_ptr<base::ListValue> allow(
377 ListValueToStringVector(pref_service_->GetList(prefs::kUrlWhitelist)); 343 pref_service_->GetList(prefs::kUrlWhitelist)->DeepCopy());
378 344
379 // Go through the IO thread to grab a WeakPtr to |this|. This is safe from 345 // Go through the IO thread to grab a WeakPtr to |this|. This is safe from
380 // here, since this task will always execute before a potential deletion of 346 // here, since this task will always execute before a potential deletion of
381 // ProfileIOData on IO. 347 // ProfileIOData on IO.
382 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, 348 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
383 base::Bind(&URLBlacklistManager::UpdateOnIO, 349 base::Bind(&URLBlacklistManager::UpdateOnIO,
384 base::Unretained(this), block, allow)); 350 base::Unretained(this),
351 base::Passed(&block),
352 base::Passed(&allow)));
385 } 353 }
386 354
387 void URLBlacklistManager::UpdateOnIO(StringVector* block, StringVector* allow) { 355 void URLBlacklistManager::UpdateOnIO(scoped_ptr<base::ListValue> block,
356 scoped_ptr<base::ListValue> allow) {
388 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 357 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
389 URLBlacklist* blacklist = new URLBlacklist;
390 // The URLBlacklist is built on the FILE thread. Once it's ready, it is passed 358 // The URLBlacklist is built on the FILE thread. Once it's ready, it is passed
391 // to the URLBlacklistManager on IO. 359 // to the URLBlacklistManager on IO.
392 // |blacklist|, |block| and |allow| can leak on the unlikely event of a 360 BrowserThread::PostTaskAndReplyWithResult(
393 // policy update and shutdown happening at the same time. 361 BrowserThread::FILE, FROM_HERE,
394 BrowserThread::PostTaskAndReply(BrowserThread::FILE, FROM_HERE, 362 base::Bind(&BuildBlacklist,
395 base::Bind(&BuildBlacklist, 363 base::Passed(&block),
396 blacklist, block, allow), 364 base::Passed(&allow)),
397 base::Bind(&SetBlacklistOnIO, 365 base::Bind(&URLBlacklistManager::SetBlacklist,
398 io_weak_ptr_factory_.GetWeakPtr(), 366 io_weak_ptr_factory_.GetWeakPtr()));
399 blacklist));
400 } 367 }
401 368
402 void URLBlacklistManager::SetBlacklist(URLBlacklist* blacklist) { 369 void URLBlacklistManager::SetBlacklist(scoped_ptr<URLBlacklist> blacklist) {
403 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 370 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
404 blacklist_.reset(blacklist); 371 blacklist_ = blacklist.Pass();
405 } 372 }
406 373
407 bool URLBlacklistManager::IsURLBlocked(const GURL& url) const { 374 bool URLBlacklistManager::IsURLBlocked(const GURL& url) const {
408 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 375 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
409 return blacklist_->IsURLBlocked(url); 376 return blacklist_->IsURLBlocked(url);
410 } 377 }
411 378
412 // static 379 // static
413 void URLBlacklistManager::RegisterPrefs(PrefService* pref_service) { 380 void URLBlacklistManager::RegisterPrefs(PrefService* pref_service) {
414 pref_service->RegisterListPref(prefs::kUrlBlacklist, 381 pref_service->RegisterListPref(prefs::kUrlBlacklist,
415 PrefService::UNSYNCABLE_PREF); 382 PrefService::UNSYNCABLE_PREF);
416 pref_service->RegisterListPref(prefs::kUrlWhitelist, 383 pref_service->RegisterListPref(prefs::kUrlWhitelist,
417 PrefService::UNSYNCABLE_PREF); 384 PrefService::UNSYNCABLE_PREF);
418 } 385 }
419 386
420 } // namespace policy 387 } // namespace policy
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698