| Index: chrome/browser/policy/host_blacklist_manager.cc
|
| diff --git a/chrome/browser/policy/host_blacklist_manager.cc b/chrome/browser/policy/host_blacklist_manager.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..a11dc5ba8cc6cc58c814ff724d0e8aeaa6b03779
|
| --- /dev/null
|
| +++ b/chrome/browser/policy/host_blacklist_manager.cc
|
| @@ -0,0 +1,221 @@
|
| +// Copyright (c) 2011 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "chrome/browser/policy/host_blacklist_manager.h"
|
| +
|
| +#include "base/task.h"
|
| +#include "base/values.h"
|
| +#include "chrome/browser/prefs/pref_service.h"
|
| +#include "chrome/browser/profiles/profile.h"
|
| +#include "chrome/common/chrome_notification_types.h"
|
| +#include "chrome/common/pref_names.h"
|
| +#include "content/browser/browser_thread.h"
|
| +#include "content/common/notification_details.h"
|
| +#include "content/common/notification_source.h"
|
| +#include "googleurl/src/gurl.h"
|
| +
|
| +// A note on ownership of HostBlacklistManager:
|
| +// HostBlacklistManager is held mainly by ProfileImpl and its ProfileIOData.
|
| +// Its pending tasks can also hold references to it during destruction of the
|
| +// profile thought; however, those tasks only affect the internal state of
|
| +// HostBlacklistManager, and won't attempt to touch the profile or anything
|
| +// else. So in those cases, the HostBlacklistManager will be gone when the
|
| +// tasks are deleted.
|
| +//
|
| +// Its only client is the ChromeNetworkDelegate, which is also owned by the
|
| +// ProfileIOData. If the Profile is gone before the ChromeNetworkDelegate,
|
| +// the HostBlacklistManager won't see any more changes to the preferences,
|
| +// but it can still serve the ChromeNetworkDelegate until the ProfileIOData is
|
| +// deleted too.
|
| +
|
| +namespace policy {
|
| +
|
| +namespace {
|
| +
|
| +// Time to wait before starting an update of the blacklist. Scheduling another
|
| +// update during this period will reset the timer.
|
| +const int64 kUpdateDelayMs = 5000;
|
| +
|
| +// Maximum host filter per policy. Filters over this index are ignored.
|
| +const size_t kMaxHostsPerPolicy = 100;
|
| +
|
| +typedef std::vector<std::string> StringVector;
|
| +
|
| +StringVector* ListValueToStringVector(const base::ListValue* list) {
|
| + StringVector* vector = new StringVector;
|
| +
|
| + if (!list)
|
| + return vector;
|
| +
|
| + vector->reserve(list->GetSize());
|
| + std::string s;
|
| + for (base::ListValue::const_iterator it = list->begin();
|
| + it != list->end() && vector->size() < kMaxHostsPerPolicy; ++it) {
|
| + if ((*it)->GetAsString(&s))
|
| + vector->push_back(s);
|
| + }
|
| +
|
| + return vector;
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +// TODO(joaodasilva): this is a work in progress. http://crbug.com/49612
|
| +class HostBlacklistManager::Blacklist {
|
| + public:
|
| + Blacklist() {
|
| + }
|
| +
|
| + private:
|
| + DISALLOW_COPY_AND_ASSIGN(Blacklist);
|
| +};
|
| +
|
| +// A task that also owns the StringVectors.
|
| +class BuildBlacklistTask : public Task {
|
| + public:
|
| + BuildBlacklistTask(
|
| + scoped_refptr<HostBlacklistManager> host_blacklist_manager,
|
| + StringVector* blacklist,
|
| + StringVector* whitelist)
|
| + : host_blacklist_manager_(host_blacklist_manager),
|
| + blacklist_(blacklist),
|
| + whitelist_(whitelist) {
|
| + }
|
| +
|
| + virtual void Run() {
|
| + host_blacklist_manager_->BuildBlacklist(blacklist_.get(), whitelist_.get());
|
| + }
|
| +
|
| + private:
|
| + scoped_refptr<HostBlacklistManager> host_blacklist_manager_;
|
| + scoped_ptr<StringVector> blacklist_;
|
| + scoped_ptr<StringVector> whitelist_;
|
| + DISALLOW_COPY_AND_ASSIGN(BuildBlacklistTask);
|
| +};
|
| +
|
| +// A task that also owns the Blacklist.
|
| +class SetBlacklistTask : public Task {
|
| + public:
|
| + SetBlacklistTask(
|
| + scoped_refptr<HostBlacklistManager> host_blacklist_manager,
|
| + HostBlacklistManager::Blacklist* blacklist)
|
| + : host_blacklist_manager_(host_blacklist_manager),
|
| + blacklist_(blacklist) {
|
| + }
|
| +
|
| + virtual void Run() {
|
| + host_blacklist_manager_->SetBlacklist(blacklist_.release());
|
| + }
|
| +
|
| + private:
|
| + scoped_refptr<HostBlacklistManager> host_blacklist_manager_;
|
| + scoped_ptr<HostBlacklistManager::Blacklist> blacklist_;
|
| + DISALLOW_COPY_AND_ASSIGN(SetBlacklistTask);
|
| +};
|
| +
|
| +HostBlacklistManager::HostBlacklistManager(Profile* profile)
|
| + : update_task_(NULL),
|
| + pref_service_(profile->GetPrefs()) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| +
|
| + pref_change_registrar_.Init(pref_service_);
|
| + pref_change_registrar_.Add(prefs::kHostBlacklist, this);
|
| + pref_change_registrar_.Add(prefs::kHostWhitelist, this);
|
| +}
|
| +
|
| +void HostBlacklistManager::Initialize() {
|
| + // Start enforcing the policies without a delay when they are present at
|
| + // startup.
|
| + if (pref_service_->HasPrefPath(prefs::kHostBlacklist))
|
| + Update();
|
| +}
|
| +
|
| +void HostBlacklistManager::ShutdownOnUIThread() {
|
| + pref_change_registrar_.RemoveAll();
|
| +}
|
| +
|
| +HostBlacklistManager::~HostBlacklistManager() {
|
| +}
|
| +
|
| +void HostBlacklistManager::Observe(int type,
|
| + const NotificationSource& source,
|
| + const NotificationDetails& details) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| + DCHECK(type == chrome::NOTIFICATION_PREF_CHANGED);
|
| + PrefService* prefs = Source<PrefService>(source).ptr();
|
| + DCHECK(prefs == pref_service_);
|
| + std::string* pref_name = Details<std::string>(details).ptr();
|
| + DCHECK(*pref_name == prefs::kHostBlacklist ||
|
| + *pref_name == prefs::kHostWhitelist);
|
| + ScheduleUpdate();
|
| +}
|
| +
|
| +void HostBlacklistManager::ScheduleUpdate() {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| + if (update_task_)
|
| + update_task_->Cancel();
|
| + update_task_ = NewRunnableMethod(this, &HostBlacklistManager::Update);
|
| + PostUpdateTask();
|
| +}
|
| +
|
| +void HostBlacklistManager::PostUpdateTask() {
|
| + // This is overriden in tests to post the task without the delay.
|
| + MessageLoop::current()->PostDelayedTask(FROM_HERE, update_task_,
|
| + kUpdateDelayMs);
|
| +}
|
| +
|
| +void HostBlacklistManager::Update() {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| + update_task_ = NULL;
|
| +
|
| + StringVector* blacklist = ListValueToStringVector(
|
| + pref_service_->GetList(prefs::kHostBlacklist));
|
| + StringVector* whitelist = ListValueToStringVector(
|
| + pref_service_->GetList(prefs::kHostWhitelist));
|
| +
|
| + BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
|
| + new BuildBlacklistTask(this, blacklist, whitelist));
|
| +}
|
| +
|
| +void HostBlacklistManager::BuildBlacklist(const StringVector* host_blacklist,
|
| + const StringVector* host_whitelist) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
|
| +
|
| + // TODO(joaodasilva): this is a work in progress. http://crbug.com/49612
|
| +
|
| + if (host_blacklist->empty()) {
|
| + BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
|
| + new SetBlacklistTask(this, NULL));
|
| + return;
|
| + }
|
| +
|
| + Blacklist* blacklist = new Blacklist;
|
| + BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
|
| + new SetBlacklistTask(this, blacklist));
|
| +}
|
| +
|
| +void HostBlacklistManager::SetBlacklist(Blacklist* blacklist) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| + blacklist_.reset(blacklist);
|
| +}
|
| +
|
| +bool HostBlacklistManager::ShouldBlockRequest(const GURL& url) const {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| +
|
| + if (!blacklist_.get())
|
| + return false;
|
| +
|
| + // TODO(joaodasilva): this is a work in progress. http://crbug.com/49612
|
| + return false;
|
| +}
|
| +
|
| +// static
|
| +void HostBlacklistManager::RegisterPrefs(PrefService* pref_service) {
|
| + pref_service->RegisterListPref(prefs::kHostBlacklist,
|
| + PrefService::UNSYNCABLE_PREF);
|
| + pref_service->RegisterListPref(prefs::kHostWhitelist,
|
| + PrefService::UNSYNCABLE_PREF);
|
| +}
|
| +
|
| +} // namespace policy
|
|
|