OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 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 "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/message_loop.h" | 8 #include "base/message_loop.h" |
9 #include "base/stl_util.h" | 9 #include "base/stl_util.h" |
10 #include "base/string_number_conversions.h" | 10 #include "base/string_number_conversions.h" |
(...skipping 28 matching lines...) Expand all Loading... | |
39 std::string s; | 39 std::string s; |
40 for (base::ListValue::const_iterator it = list->begin(); | 40 for (base::ListValue::const_iterator it = list->begin(); |
41 it != list->end() && vector->size() < kMaxFiltersPerPolicy; ++it) { | 41 it != list->end() && vector->size() < kMaxFiltersPerPolicy; ++it) { |
42 if ((*it)->GetAsString(&s)) | 42 if ((*it)->GetAsString(&s)) |
43 vector->push_back(s); | 43 vector->push_back(s); |
44 } | 44 } |
45 | 45 |
46 return vector; | 46 return vector; |
47 } | 47 } |
48 | 48 |
49 // A task that builds the blacklist on the FILE thread. Takes ownership | 49 // A task that builds the blacklist on the FILE thread. |
50 // of |block| and |allow| but not of |blacklist|. | |
51 void BuildBlacklist(URLBlacklist* blacklist, | 50 void BuildBlacklist(URLBlacklist* blacklist, |
52 StringVector* block, | 51 scoped_ptr<StringVector> block, |
53 StringVector* allow) { | 52 scoped_ptr<StringVector> allow) { |
54 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 53 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
55 | |
56 scoped_ptr<StringVector> scoped_block(block); | |
57 scoped_ptr<StringVector> scoped_allow(allow); | |
58 | |
59 for (StringVector::iterator it = block->begin(); it != block->end(); ++it) { | 54 for (StringVector::iterator it = block->begin(); it != block->end(); ++it) { |
60 blacklist->Block(*it); | 55 blacklist->Block(*it); |
61 } | 56 } |
62 for (StringVector::iterator it = allow->begin(); it != allow->end(); ++it) { | 57 for (StringVector::iterator it = allow->begin(); it != allow->end(); ++it) { |
63 blacklist->Allow(*it); | 58 blacklist->Allow(*it); |
64 } | 59 } |
65 } | 60 } |
66 | 61 |
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 } | |
78 | |
79 } // namespace | 62 } // namespace |
80 | 63 |
81 struct URLBlacklist::PathFilter { | 64 struct URLBlacklist::PathFilter { |
82 explicit PathFilter(const std::string& path, uint16 port, bool match) | 65 explicit PathFilter(const std::string& path, uint16 port, bool match) |
83 : path_prefix(path), | 66 : path_prefix(path), |
84 port(port), | 67 port(port), |
85 blocked_schemes(0), | 68 blocked_schemes(0), |
86 allowed_schemes(0), | 69 allowed_schemes(0), |
87 match_subdomains(match) {} | 70 match_subdomains(match) {} |
88 | 71 |
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
360 MessageLoop::current()->PostTask( | 343 MessageLoop::current()->PostTask( |
361 FROM_HERE, | 344 FROM_HERE, |
362 base::Bind(&URLBlacklistManager::Update, | 345 base::Bind(&URLBlacklistManager::Update, |
363 ui_weak_ptr_factory_.GetWeakPtr())); | 346 ui_weak_ptr_factory_.GetWeakPtr())); |
364 } | 347 } |
365 | 348 |
366 void URLBlacklistManager::Update() { | 349 void URLBlacklistManager::Update() { |
367 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 350 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
368 | 351 |
369 // The preferences can only be read on the UI thread. | 352 // The preferences can only be read on the UI thread. |
370 StringVector* block = | 353 scoped_ptr<StringVector> block( |
371 ListValueToStringVector(pref_service_->GetList(prefs::kUrlBlacklist)); | 354 ListValueToStringVector(pref_service_->GetList(prefs::kUrlBlacklist))); |
372 StringVector* allow = | 355 scoped_ptr<StringVector> allow( |
373 ListValueToStringVector(pref_service_->GetList(prefs::kUrlWhitelist)); | 356 ListValueToStringVector(pref_service_->GetList(prefs::kUrlWhitelist))); |
374 | 357 |
375 // Go through the IO thread to grab a WeakPtr to |this|. This is safe from | 358 // Go through the IO thread to grab a WeakPtr to |this|. This is safe from |
376 // here, since this task will always execute before a potential deletion of | 359 // here, since this task will always execute before a potential deletion of |
377 // ProfileIOData on IO. | 360 // ProfileIOData on IO. |
378 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, | 361 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
379 base::Bind(&URLBlacklistManager::UpdateOnIO, | 362 base::Bind(&URLBlacklistManager::UpdateOnIO, |
380 base::Unretained(this), block, allow)); | 363 base::Unretained(this), |
364 base::Passed(&block), | |
365 base::Passed(&allow))); | |
381 } | 366 } |
382 | 367 |
383 void URLBlacklistManager::UpdateOnIO(StringVector* block, StringVector* allow) { | 368 void URLBlacklistManager::UpdateOnIO(scoped_ptr<StringVector> block, |
369 scoped_ptr<StringVector> allow) { | |
384 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 370 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
385 URLBlacklist* blacklist = new URLBlacklist; | 371 scoped_ptr<URLBlacklist> blacklist(new URLBlacklist); |
372 // Get a raw pointer now, since |blacklist.get()| might be evaluated after | |
373 // |Passed(&blacklist) below. | |
374 URLBlacklist* raw_blacklist = blacklist.get(); | |
Joao da Silva
2011/12/10 14:11:54
Only found this after the unit_tests crashed. Havi
awong
2011/12/12 22:01:26
Oh interesting. I had not thought about that. Yea
| |
386 // The URLBlacklist is built on the FILE thread. Once it's ready, it is passed | 375 // The URLBlacklist is built on the FILE thread. Once it's ready, it is passed |
387 // to the URLBlacklistManager on IO. | 376 // to the URLBlacklistManager on IO. |
388 // |blacklist|, |block| and |allow| can leak on the unlikely event of a | |
389 // policy update and shutdown happening at the same time. | |
390 BrowserThread::PostTaskAndReply(BrowserThread::FILE, FROM_HERE, | 377 BrowserThread::PostTaskAndReply(BrowserThread::FILE, FROM_HERE, |
391 base::Bind(&BuildBlacklist, | 378 base::Bind(&BuildBlacklist, |
392 blacklist, block, allow), | 379 raw_blacklist, |
393 base::Bind(&SetBlacklistOnIO, | 380 base::Passed(&block), |
381 base::Passed(&allow)), | |
382 base::Bind(&URLBlacklistManager::SetBlacklist, | |
394 io_weak_ptr_factory_.GetWeakPtr(), | 383 io_weak_ptr_factory_.GetWeakPtr(), |
395 blacklist)); | 384 base::Passed(&blacklist))); |
396 } | 385 } |
397 | 386 |
398 void URLBlacklistManager::SetBlacklist(URLBlacklist* blacklist) { | 387 void URLBlacklistManager::SetBlacklist(scoped_ptr<URLBlacklist> blacklist) { |
399 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 388 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
400 blacklist_.reset(blacklist); | 389 blacklist_.swap(blacklist); |
401 } | 390 } |
402 | 391 |
403 bool URLBlacklistManager::IsURLBlocked(const GURL& url) const { | 392 bool URLBlacklistManager::IsURLBlocked(const GURL& url) const { |
404 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 393 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
405 return blacklist_->IsURLBlocked(url); | 394 return blacklist_->IsURLBlocked(url); |
406 } | 395 } |
407 | 396 |
408 // static | 397 // static |
409 void URLBlacklistManager::RegisterPrefs(PrefService* pref_service) { | 398 void URLBlacklistManager::RegisterPrefs(PrefService* pref_service) { |
410 pref_service->RegisterListPref(prefs::kUrlBlacklist, | 399 pref_service->RegisterListPref(prefs::kUrlBlacklist, |
411 PrefService::UNSYNCABLE_PREF); | 400 PrefService::UNSYNCABLE_PREF); |
412 pref_service->RegisterListPref(prefs::kUrlWhitelist, | 401 pref_service->RegisterListPref(prefs::kUrlWhitelist, |
413 PrefService::UNSYNCABLE_PREF); | 402 PrefService::UNSYNCABLE_PREF); |
414 } | 403 } |
415 | 404 |
416 } // namespace policy | 405 } // namespace policy |
OLD | NEW |