summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorphajdan.jr@chromium.org <phajdan.jr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-11-04 11:11:34 +0000
committerphajdan.jr@chromium.org <phajdan.jr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-11-04 11:11:34 +0000
commit24e7a9d2b4d7925ca25d2cdf75808d3ff88b5f6e (patch)
tree809ce617d8e41b1ba284eba33694af966654fb87
parenta6cf2a3e9f1d7b44dda39975139f5ae39524e363 (diff)
downloadchromium_src-24e7a9d2b4d7925ca25d2cdf75808d3ff88b5f6e.zip
chromium_src-24e7a9d2b4d7925ca25d2cdf75808d3ff88b5f6e.tar.gz
chromium_src-24e7a9d2b4d7925ca25d2cdf75808d3ff88b5f6e.tar.bz2
Implement loading blacklists from extensions.
It doesn't yet work in full-browser scenario, but allows me to write a simple test. TEST=Covered by browser_tests. BUG=21541 Review URL: http://codereview.chromium.org/341050 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@30952 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/browser.cc5
-rw-r--r--chrome/browser/extensions/extension_disabled_infobar_delegate.cc4
-rw-r--r--chrome/browser/extensions/extension_host.cc2
-rw-r--r--chrome/browser/extensions/extension_process_manager.cc5
-rw-r--r--chrome/browser/extensions/extensions_service.cc60
-rw-r--r--chrome/browser/extensions/extensions_service.h8
-rw-r--r--chrome/browser/extensions/user_script_listener.cc4
-rw-r--r--chrome/browser/extensions/user_script_listener_unittest.cc62
-rw-r--r--chrome/browser/gtk/browser_actions_toolbar_gtk.cc7
-rw-r--r--chrome/browser/privacy_blacklist/blacklist_manager.cc34
-rw-r--r--chrome/browser/privacy_blacklist/blacklist_manager_browsertest.cc92
-rw-r--r--chrome/browser/privacy_blacklist/blacklist_manager_unittest.cc43
-rw-r--r--chrome/browser/views/browser_actions_container.cc6
-rwxr-xr-xchrome/chrome.gyp2
-rw-r--r--chrome/common/notification_type.h30
-rw-r--r--chrome/test/data/extensions/common/privacy_blacklist/manifest.json8
-rw-r--r--chrome/test/data/extensions/common/privacy_blacklist/privacy_blacklist.pbl12
17 files changed, 294 insertions, 90 deletions
diff --git a/chrome/browser/browser.cc b/chrome/browser/browser.cc
index 48e46d7..6dd5f0e 100644
--- a/chrome/browser/browser.cc
+++ b/chrome/browser/browser.cc
@@ -2221,7 +2221,10 @@ void Browser::Observe(NotificationType type,
case NotificationType::EXTENSION_UPDATE_DISABLED: {
// Show the UI.
- ExtensionsService* service = Source<ExtensionsService>(source).ptr();
+ Profile* profile = Source<Profile>(source).ptr();
+ DCHECK_EQ(profile_, profile);
+ ExtensionsService* service = profile->GetExtensionsService();
+ DCHECK(service);
Extension* extension = Details<Extension>(details).ptr();
ShowExtensionDisabledUI(service, profile_, extension);
break;
diff --git a/chrome/browser/extensions/extension_disabled_infobar_delegate.cc b/chrome/browser/extensions/extension_disabled_infobar_delegate.cc
index ea8de22..0d0d7b4 100644
--- a/chrome/browser/extensions/extension_disabled_infobar_delegate.cc
+++ b/chrome/browser/extensions/extension_disabled_infobar_delegate.cc
@@ -88,9 +88,9 @@ class ExtensionDisabledInfobarDelegate
extension_(extension) {
// The user might re-enable the extension in other ways, so watch for that.
registrar_.Add(this, NotificationType::EXTENSION_LOADED,
- Source<ExtensionsService>(service));
+ Source<Profile>(service->profile()));
registrar_.Add(this, NotificationType::EXTENSION_UNLOADED_DISABLED,
- Source<ExtensionsService>(service));
+ Source<Profile>(service->profile()));
}
virtual ~ExtensionDisabledInfobarDelegate() {
}
diff --git a/chrome/browser/extensions/extension_host.cc b/chrome/browser/extensions/extension_host.cc
index a468700..f9d6bd1 100644
--- a/chrome/browser/extensions/extension_host.cc
+++ b/chrome/browser/extensions/extension_host.cc
@@ -248,7 +248,7 @@ void ExtensionHost::RenderViewGone(RenderViewHost* render_view_host) {
DCHECK_EQ(render_view_host_, render_view_host);
NotificationService::current()->Notify(
NotificationType::EXTENSION_PROCESS_CRASHED,
- Source<ExtensionsService>(profile_->GetExtensionsService()),
+ Source<Profile>(profile_),
Details<ExtensionHost>(this));
}
diff --git a/chrome/browser/extensions/extension_process_manager.cc b/chrome/browser/extensions/extension_process_manager.cc
index e9bb7c49..6718691 100644
--- a/chrome/browser/extensions/extension_process_manager.cc
+++ b/chrome/browser/extensions/extension_process_manager.cc
@@ -175,11 +175,12 @@ void ExtensionProcessManager::Observe(NotificationType type,
switch (type.value) {
case NotificationType::EXTENSIONS_READY:
CreateBackgroundHosts(this,
- Source<ExtensionsService>(source).ptr()->extensions());
+ Source<Profile>(source).ptr()->GetExtensionsService()->extensions());
break;
case NotificationType::EXTENSION_LOADED: {
- ExtensionsService* service = Source<ExtensionsService>(source).ptr();
+ ExtensionsService* service =
+ Source<Profile>(source).ptr()->GetExtensionsService();
if (service->is_ready()) {
Extension* extension = Details<Extension>(details).ptr();
::CreateBackgroundHost(this, extension);
diff --git a/chrome/browser/extensions/extensions_service.cc b/chrome/browser/extensions/extensions_service.cc
index 1692e3f..dcca59e 100644
--- a/chrome/browser/extensions/extensions_service.cc
+++ b/chrome/browser/extensions/extensions_service.cc
@@ -333,7 +333,7 @@ void ExtensionsService::NotifyExtensionLoaded(Extension* extension) {
NotificationService::current()->Notify(
NotificationType::EXTENSION_LOADED,
- Source<ExtensionsService>(this),
+ Source<Profile>(profile_),
Details<Extension>(extension));
}
@@ -342,7 +342,7 @@ void ExtensionsService::NotifyExtensionUnloaded(Extension* extension) {
NotificationService::current()->Notify(
NotificationType::EXTENSION_UNLOADED,
- Source<ExtensionsService>(this),
+ Source<Profile>(profile_),
Details<Extension>(extension));
if (profile_ && !profile_->IsOffTheRecord()) {
@@ -417,7 +417,7 @@ void ExtensionsService::UnloadExtension(const std::string& extension_id) {
disabled_extensions_.erase(iter);
NotificationService::current()->Notify(
NotificationType::EXTENSION_UNLOADED_DISABLED,
- Source<ExtensionsService>(this),
+ Source<Profile>(profile_),
Details<Extension>(extension.get()));
return;
}
@@ -463,7 +463,7 @@ void ExtensionsService::OnLoadedInstalledExtensions() {
}
NotificationService::current()->Notify(
NotificationType::EXTENSIONS_READY,
- Source<ExtensionsService>(this),
+ Source<Profile>(profile_),
NotificationService::NoDetails());
}
@@ -494,7 +494,7 @@ void ExtensionsService::OnExtensionLoaded(Extension* extension,
extension_prefs_->SetExtensionState(extension, Extension::DISABLED);
NotificationService::current()->Notify(
NotificationType::EXTENSION_UPDATE_DISABLED,
- Source<ExtensionsService>(this),
+ Source<Profile>(profile_),
Details<Extension>(extension));
}
} else {
@@ -528,7 +528,7 @@ void ExtensionsService::OnExtensionLoaded(Extension* extension,
if (extension->IsTheme() && extension->location() == Extension::LOAD) {
NotificationService::current()->Notify(
NotificationType::THEME_INSTALLED,
- Source<ExtensionsService>(this),
+ Source<Profile>(profile_),
Details<Extension>(extension));
} else {
ExtensionDOMUI::RegisterChromeURLOverrides(profile_,
@@ -538,7 +538,7 @@ void ExtensionsService::OnExtensionLoaded(Extension* extension,
case Extension::DISABLED:
NotificationService::current()->Notify(
NotificationType::EXTENSION_UPDATE_DISABLED,
- Source<ExtensionsService>(this),
+ Source<Profile>(profile_),
Details<Extension>(extension));
disabled_extensions_.push_back(scoped_extension.release());
break;
@@ -558,12 +558,12 @@ void ExtensionsService::OnExtensionInstalled(Extension* extension,
if (extension->IsTheme()) {
NotificationService::current()->Notify(
NotificationType::THEME_INSTALLED,
- Source<ExtensionsService>(this),
+ Source<Profile>(profile_),
Details<Extension>(extension));
} else {
NotificationService::current()->Notify(
NotificationType::EXTENSION_INSTALLED,
- Source<ExtensionsService>(this),
+ Source<Profile>(profile_),
Details<Extension>(extension));
}
@@ -576,12 +576,12 @@ void ExtensionsService::OnExtensionOverinstallAttempted(const std::string& id) {
if (extension && extension->IsTheme()) {
NotificationService::current()->Notify(
NotificationType::THEME_INSTALLED,
- Source<ExtensionsService>(this),
+ Source<Profile>(profile_),
Details<Extension>(extension));
} else {
NotificationService::current()->Notify(
NotificationType::NO_THEME_DETECTED,
- Source<ExtensionsService>(this),
+ Source<Profile>(profile_),
NotificationService::NoDetails());
}
}
@@ -666,7 +666,7 @@ void ExtensionsService::ReportExtensionLoadError(
bool be_noisy) {
NotificationService* service = NotificationService::current();
service->Notify(type,
- Source<ExtensionsService>(this),
+ Source<Profile>(profile_),
Details<const std::string>(&error));
// TODO(port): note that this isn't guaranteed to work properly on Linux.
@@ -676,6 +676,42 @@ void ExtensionsService::ReportExtensionLoadError(
ExtensionErrorReporter::GetInstance()->ReportError(message, be_noisy);
}
+std::vector<FilePath> ExtensionsService::GetPersistentBlacklistPaths() {
+ std::vector<FilePath> result;
+ for (ExtensionList::const_iterator extension_iter = extensions()->begin();
+ extension_iter != extensions()->end(); ++extension_iter) {
+ if ((*extension_iter)->location() == Extension::LOAD)
+ continue;
+
+ std::vector<Extension::PrivacyBlacklistInfo> blacklists(
+ (*extension_iter)->privacy_blacklists());
+ std::vector<Extension::PrivacyBlacklistInfo>::const_iterator blacklist_iter;
+ for (blacklist_iter = blacklists.begin();
+ blacklist_iter != blacklists.end(); ++blacklist_iter) {
+ result.push_back(blacklist_iter->path);
+ }
+ }
+ return result;
+}
+
+std::vector<FilePath> ExtensionsService::GetTransientBlacklistPaths() {
+ std::vector<FilePath> result;
+ for (ExtensionList::const_iterator extension_iter = extensions()->begin();
+ extension_iter != extensions()->end(); ++extension_iter) {
+ if ((*extension_iter)->location() != Extension::LOAD)
+ continue;
+
+ std::vector<Extension::PrivacyBlacklistInfo> blacklists(
+ (*extension_iter)->privacy_blacklists());
+ std::vector<Extension::PrivacyBlacklistInfo>::const_iterator blacklist_iter;
+ for (blacklist_iter = blacklists.begin();
+ blacklist_iter != blacklists.end(); ++blacklist_iter) {
+ result.push_back(blacklist_iter->path);
+ }
+ }
+ return result;
+}
+
// ExtensionsServicesBackend
ExtensionsServiceBackend::ExtensionsServiceBackend(
diff --git a/chrome/browser/extensions/extensions_service.h b/chrome/browser/extensions/extensions_service.h
index 6d525d7..55e336d 100644
--- a/chrome/browser/extensions/extensions_service.h
+++ b/chrome/browser/extensions/extensions_service.h
@@ -21,6 +21,7 @@
#include "chrome/browser/extensions/extension_process_manager.h"
#include "chrome/browser/extensions/external_extension_provider.h"
#include "chrome/browser/extensions/sandboxed_extension_unpacker.h"
+#include "chrome/browser/privacy_blacklist/blacklist_manager.h"
#include "chrome/common/extensions/extension.h"
class Browser;
@@ -51,6 +52,7 @@ class ExtensionUpdateService {
// Manages installed and running Chromium extensions.
class ExtensionsService
: public ExtensionUpdateService,
+ public BlacklistPathProvider,
public base::RefCountedThreadSafe<ExtensionsService> {
public:
@@ -201,6 +203,8 @@ class ExtensionsService
return show_extensions_prompts_;
}
+ Profile* profile() { return profile_; }
+
// Profile calls this when it is destroyed so that we know not to call it.
void ProfileDestroyed() { profile_ = NULL; }
@@ -219,6 +223,10 @@ class ExtensionsService
NotificationType type,
bool be_noisy);
+ // BlacklistPathProvider:
+ virtual std::vector<FilePath> GetPersistentBlacklistPaths();
+ virtual std::vector<FilePath> GetTransientBlacklistPaths();
+
private:
// Look up an extension by ID, optionally including either or both of enabled
// and disabled extensions.
diff --git a/chrome/browser/extensions/user_script_listener.cc b/chrome/browser/extensions/user_script_listener.cc
index 31f0971..76a4ff5 100644
--- a/chrome/browser/extensions/user_script_listener.cc
+++ b/chrome/browser/extensions/user_script_listener.cc
@@ -6,6 +6,7 @@
#include "chrome/browser/chrome_thread.h"
#include "chrome/browser/extensions/extensions_service.h"
+#include "chrome/browser/profile.h"
#include "chrome/browser/renderer_host/resource_dispatcher_host_request_info.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/notification_service.h"
@@ -136,7 +137,8 @@ void UserScriptListener::Observe(NotificationType type,
// Clear all our patterns and reregister all the still-loaded extensions.
URLPatterns new_patterns;
- ExtensionsService* service = Source<ExtensionsService>(source).ptr();
+ ExtensionsService* service =
+ Source<Profile>(source).ptr()->GetExtensionsService();
for (ExtensionList::const_iterator it = service->extensions()->begin();
it != service->extensions()->end(); ++it) {
if (*it != unloaded_extension)
diff --git a/chrome/browser/extensions/user_script_listener_unittest.cc b/chrome/browser/extensions/user_script_listener_unittest.cc
index 14a9d0e..2f87798 100644
--- a/chrome/browser/extensions/user_script_listener_unittest.cc
+++ b/chrome/browser/extensions/user_script_listener_unittest.cc
@@ -180,6 +180,38 @@ class ResourceDispatcherHostTester
std::vector<int> completed_requests_;
};
+class ExtensionTestingProfile : public TestingProfile {
+ public:
+ ExtensionTestingProfile() {
+ }
+
+ FilePath GetExtensionsInstallDir() {
+ return GetPath().AppendASCII(ExtensionsService::kInstallDirectoryName);
+ }
+
+ void InitializeExtensionsService() {
+ DCHECK(!GetExtensionsService());
+ service_ = new ExtensionsService(this,
+ CommandLine::ForCurrentProcess(),
+ GetPrefs(),
+ GetExtensionsInstallDir(),
+ false);
+ service_->set_extensions_enabled(true);
+ service_->set_show_extensions_prompts(false);
+ service_->ClearProvidersForTesting();
+ service_->Init();
+ }
+
+ virtual ExtensionsService* GetExtensionsService() {
+ return service_.get();
+ }
+
+ private:
+ scoped_refptr<ExtensionsService> service_;
+
+ DISALLOW_COPY_AND_ASSIGN(ExtensionTestingProfile);
+};
+
class UserScriptListenerTest : public testing::Test {
public:
virtual void SetUp() {
@@ -196,17 +228,9 @@ class UserScriptListenerTest : public testing::Test {
resource_tester_ = new ResourceDispatcherHostTester();
- master_ = new MockUserScriptMaster(install_dir);
+ master_ = new MockUserScriptMaster(profile_.GetExtensionsInstallDir());
- service_ = new ExtensionsService(&profile_,
- CommandLine::ForCurrentProcess(),
- profile_.GetPrefs(),
- install_dir,
- false);
- service_->set_extensions_enabled(true);
- service_->set_show_extensions_prompts(false);
- service_->ClearProvidersForTesting();
- service_->Init();
+ profile_.InitializeExtensionsService();
}
virtual void TearDown() {
@@ -217,14 +241,13 @@ class UserScriptListenerTest : public testing::Test {
}
protected:
- TestingProfile profile_;
+ ExtensionTestingProfile profile_;
MessageLoopForUI loop_;
scoped_ptr<ChromeThread> ui_thread_;
scoped_ptr<ChromeThread> file_thread_;
scoped_ptr<MockIOThread> io_thread_;
scoped_refptr<ResourceDispatcherHostTester> resource_tester_;
scoped_refptr<MockUserScriptMaster> master_;
- scoped_refptr<ExtensionsService> service_;
};
// Loads a single extension and ensures that requests to URLs with content
@@ -238,9 +261,9 @@ TEST_F(UserScriptListenerTest, SingleExtension) {
.AppendASCII("Extensions")
.AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
.AppendASCII("1.0.0.0");
- service_->LoadExtension(ext1);
+ profile_.GetExtensionsService()->LoadExtension(ext1);
loop_.RunAllPending();
- ASSERT_EQ(1u, service_->extensions()->size());
+ ASSERT_EQ(1u, profile_.GetExtensionsService()->extensions()->size());
// Our extension has a content script on google.com. That request should be
// delayed.
@@ -271,18 +294,18 @@ TEST_F(UserScriptListenerTest, UnloadExtension) {
.AppendASCII("Extensions")
.AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
.AppendASCII("1.0.0.0");
- service_->LoadExtension(ext1);
+ profile_.GetExtensionsService()->LoadExtension(ext1);
loop_.RunAllPending();
- ASSERT_EQ(1u, service_->extensions()->size());
+ ASSERT_EQ(1u, profile_.GetExtensionsService()->extensions()->size());
FilePath ext2 = extensions_path
.AppendASCII("good")
.AppendASCII("Extensions")
.AppendASCII("bjafgdebaacbbbecmhlhpofkepfkgcpa")
.AppendASCII("1.0");
- service_->LoadExtension(ext2);
+ profile_.GetExtensionsService()->LoadExtension(ext2);
loop_.RunAllPending();
- ASSERT_EQ(2u, service_->extensions()->size());
+ ASSERT_EQ(2u, profile_.GetExtensionsService()->extensions()->size());
// Our extension has a content script on google.com. That request should be
// delayed.
@@ -294,7 +317,8 @@ TEST_F(UserScriptListenerTest, UnloadExtension) {
EXPECT_TRUE(resource_tester_->IsRequestComplete(1));
// Unload the first extension and run a scan. Request should complete.
- service_->UnloadExtension("behllobkkfkfnphdnhnkndlbkcpglgmj");
+ profile_.GetExtensionsService()->UnloadExtension(
+ "behllobkkfkfnphdnhnkndlbkcpglgmj");
resource_tester_->WaitForScan(master_.get());
EXPECT_TRUE(resource_tester_->IsRequestStarted(0));
diff --git a/chrome/browser/gtk/browser_actions_toolbar_gtk.cc b/chrome/browser/gtk/browser_actions_toolbar_gtk.cc
index 86aec26..176b4ee 100644
--- a/chrome/browser/gtk/browser_actions_toolbar_gtk.cc
+++ b/chrome/browser/gtk/browser_actions_toolbar_gtk.cc
@@ -201,13 +201,12 @@ BrowserActionsToolbarGtk::BrowserActionsToolbarGtk(Browser* browser)
: browser_(browser),
profile_(browser->profile()),
hbox_(gtk_hbox_new(FALSE, kBrowserActionButtonPadding)) {
- ExtensionsService* extension_service = profile_->GetExtensionsService();
registrar_.Add(this, NotificationType::EXTENSION_LOADED,
- Source<ExtensionsService>(extension_service));
+ Source<Profile>(profile_));
registrar_.Add(this, NotificationType::EXTENSION_UNLOADED,
- Source<ExtensionsService>(extension_service));
+ Source<Profile>(profile_));
registrar_.Add(this, NotificationType::EXTENSION_UNLOADED_DISABLED,
- Source<ExtensionsService>(extension_service));
+ Source<Profile>(profile_));
CreateAllButtons();
}
diff --git a/chrome/browser/privacy_blacklist/blacklist_manager.cc b/chrome/browser/privacy_blacklist/blacklist_manager.cc
index f7c9311..0629806 100644
--- a/chrome/browser/privacy_blacklist/blacklist_manager.cc
+++ b/chrome/browser/privacy_blacklist/blacklist_manager.cc
@@ -35,7 +35,7 @@ class BlacklistManagerTask : public Task {
protected:
BlacklistManager* blacklist_manager() const { return manager_; }
-
+
MessageLoop* original_loop_;
private:
@@ -59,7 +59,7 @@ class BlacklistManager::CompileBlacklistTask : public BlacklistManagerTask {
virtual void Run() {
bool success = true;
-
+
Blacklist blacklist;
std::string error_string;
@@ -107,7 +107,7 @@ class BlacklistManager::ReadBlacklistTask : public BlacklistManagerTask {
ReportReadResult(NULL);
return;
}
-
+
std::string error_string;
std::vector<FilePath>::const_iterator i;
for (i = transient_blacklists_.begin();
@@ -117,7 +117,7 @@ class BlacklistManager::ReadBlacklistTask : public BlacklistManagerTask {
return;
}
}
-
+
ReportReadResult(blacklist.release());
}
@@ -128,7 +128,7 @@ class BlacklistManager::ReadBlacklistTask : public BlacklistManagerTask {
&BlacklistManager::OnBlacklistReadFinished,
blacklist));
}
-
+
FilePath compiled_blacklist_;
std::vector<FilePath> transient_blacklists_;
@@ -145,7 +145,10 @@ BlacklistManager::BlacklistManager(Profile* profile,
path_provider_(path_provider),
backend_thread_(backend_thread) {
registrar_.Add(this,
- NotificationType::BLACKLIST_PATH_PROVIDER_UPDATED,
+ NotificationType::EXTENSION_LOADED,
+ Source<Profile>(profile));
+ registrar_.Add(this,
+ NotificationType::EXTENSION_UNLOADED,
Source<Profile>(profile));
ReadBlacklist();
}
@@ -153,8 +156,15 @@ BlacklistManager::BlacklistManager(Profile* profile,
void BlacklistManager::Observe(NotificationType type,
const NotificationSource& source,
const NotificationDetails& details) {
- DCHECK(type == NotificationType::BLACKLIST_PATH_PROVIDER_UPDATED);
- CompileBlacklist();
+ switch (type.value) {
+ case NotificationType::EXTENSION_LOADED:
+ case NotificationType::EXTENSION_UNLOADED:
+ CompileBlacklist();
+ break;
+ default:
+ NOTREACHED();
+ break;
+ }
}
void BlacklistManager::CompileBlacklist() {
@@ -167,7 +177,7 @@ void BlacklistManager::CompileBlacklist() {
void BlacklistManager::ReadBlacklist() {
DCHECK(CalledOnValidThread());
-
+
RunTaskOnBackendThread(new ReadBlacklistTask(
this, compiled_blacklist_path_,
path_provider_->GetTransientBlacklistPaths()));
@@ -175,7 +185,7 @@ void BlacklistManager::ReadBlacklist() {
void BlacklistManager::OnBlacklistCompilationFinished(bool success) {
DCHECK(CalledOnValidThread());
-
+
if (success) {
ReadBlacklist();
} else {
@@ -189,7 +199,7 @@ void BlacklistManager::OnBlacklistCompilationFinished(bool success) {
void BlacklistManager::OnBlacklistReadFinished(Blacklist* blacklist) {
DCHECK(CalledOnValidThread());
-
+
if (!blacklist) {
if (!first_read_finished_) {
// If we're loading for the first time, the compiled blacklist could
@@ -207,7 +217,7 @@ void BlacklistManager::OnBlacklistReadFinished(Blacklist* blacklist) {
}
first_read_finished_ = true;
compiled_blacklist_.reset(blacklist);
-
+
NotificationService::current()->Notify(
NotificationType::BLACKLIST_MANAGER_BLACKLIST_READ_FINISHED,
Source<Profile>(profile_),
diff --git a/chrome/browser/privacy_blacklist/blacklist_manager_browsertest.cc b/chrome/browser/privacy_blacklist/blacklist_manager_browsertest.cc
new file mode 100644
index 0000000..bbc30c4
--- /dev/null
+++ b/chrome/browser/privacy_blacklist/blacklist_manager_browsertest.cc
@@ -0,0 +1,92 @@
+// Copyright (c) 2009 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/privacy_blacklist/blacklist_manager.h"
+
+#include "chrome/browser/browser.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/extensions/extension_browsertest.h"
+#include "chrome/browser/profile.h"
+#include "chrome/common/notification_registrar.h"
+#include "chrome/common/notification_source.h"
+#include "chrome/test/in_process_browser_test.h"
+#include "chrome/test/ui_test_utils.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+// Returns true if |blacklist| contains a match for |url|.
+bool BlacklistHasMatch(const Blacklist* blacklist, const char* url) {
+ Blacklist::Match* match = blacklist->findMatch(GURL(url));
+
+ if (!match)
+ return false;
+
+ delete match;
+ return true;
+}
+
+} // namespace
+
+class BlacklistManagerBrowserTest : public ExtensionBrowserTest {
+ public:
+ void InitializeBlacklistManager() {
+ Profile* profile = browser()->profile();
+ blacklist_manager_ = new BlacklistManager(
+ profile, profile->GetExtensionsService(),
+ g_browser_process->io_thread());
+ WaitForBlacklistUpdate();
+ }
+
+ virtual void CleanUpOnMainThread() {
+ blacklist_manager_ = NULL;
+ ExtensionBrowserTest::CleanUpOnMainThread();
+ }
+
+ // NotificationObserver
+ virtual void Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details) {
+ if (type != NotificationType::BLACKLIST_MANAGER_ERROR &&
+ type != NotificationType::BLACKLIST_MANAGER_BLACKLIST_READ_FINISHED) {
+ ExtensionBrowserTest::Observe(type, source, details);
+ return;
+ }
+ MessageLoop::current()->Quit();
+ }
+
+ protected:
+ void WaitForBlacklistUpdate() {
+ NotificationRegistrar registrar;
+ registrar.Add(this,
+ NotificationType::BLACKLIST_MANAGER_BLACKLIST_READ_FINISHED,
+ Source<Profile>(browser()->profile()));
+ ui_test_utils::RunMessageLoop();
+ }
+
+ scoped_refptr<BlacklistManager> blacklist_manager_;
+};
+
+IN_PROC_BROWSER_TEST_F(BlacklistManagerBrowserTest, Basic) {
+ InitializeBlacklistManager();
+ ASSERT_TRUE(blacklist_manager_->GetCompiledBlacklist());
+ EXPECT_FALSE(BlacklistHasMatch(blacklist_manager_->GetCompiledBlacklist(),
+ "http://host/annoying_ads/ad.jpg"));
+
+ // Test loading an extension with blacklist.
+ ASSERT_TRUE(LoadExtension(
+ test_data_dir_.AppendASCII("common").AppendASCII("privacy_blacklist")));
+ WaitForBlacklistUpdate();
+ EXPECT_TRUE(BlacklistHasMatch(blacklist_manager_->GetCompiledBlacklist(),
+ "http://host/annoying_ads/ad.jpg"));
+
+ // Make sure that after unloading the extension we update the blacklist.
+ ExtensionsService* extensions_service =
+ browser()->profile()->GetExtensionsService();
+ ASSERT_EQ(1U, extensions_service->extensions()->size());
+ UnloadExtension(extensions_service->extensions()->front()->id());
+ WaitForBlacklistUpdate();
+ EXPECT_FALSE(BlacklistHasMatch(blacklist_manager_->GetCompiledBlacklist(),
+ "http://host/annoying_ads/ad.jpg"));
+}
diff --git a/chrome/browser/privacy_blacklist/blacklist_manager_unittest.cc b/chrome/browser/privacy_blacklist/blacklist_manager_unittest.cc
index b2e6996..e7d9f9d 100644
--- a/chrome/browser/privacy_blacklist/blacklist_manager_unittest.cc
+++ b/chrome/browser/privacy_blacklist/blacklist_manager_unittest.cc
@@ -10,6 +10,7 @@
#include "base/thread.h"
#include "chrome/browser/privacy_blacklist/blacklist.h"
#include "chrome/common/chrome_paths.h"
+#include "chrome/common/extensions/extension.h"
#include "chrome/common/notification_service.h"
#include "chrome/test/testing_profile.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -37,7 +38,7 @@ class TestBlacklistPathProvider : public BlacklistPathProvider {
virtual std::vector<FilePath> GetPersistentBlacklistPaths() {
return persistent_paths_;
}
-
+
virtual std::vector<FilePath> GetTransientBlacklistPaths() {
return transient_paths_;
}
@@ -46,12 +47,12 @@ class TestBlacklistPathProvider : public BlacklistPathProvider {
persistent_paths_.push_back(path);
SendUpdateNotification();
}
-
+
void AddTransientPath(const FilePath& path) {
transient_paths_.push_back(path);
SendUpdateNotification();
}
-
+
void clear() {
persistent_paths_.clear();
transient_paths_.clear();
@@ -60,12 +61,18 @@ class TestBlacklistPathProvider : public BlacklistPathProvider {
private:
void SendUpdateNotification() {
+#if defined(OS_WIN)
+ FilePath path(FILE_PATH_LITERAL("c:\\foo"));
+#elif defined(OS_POSIX)
+ FilePath path(FILE_PATH_LITERAL("/foo"));
+#endif
+ Extension extension(path);
NotificationService::current()->Notify(
- NotificationType::BLACKLIST_PATH_PROVIDER_UPDATED,
+ NotificationType::EXTENSION_LOADED,
Source<Profile>(profile_),
- Details<BlacklistPathProvider>(this));
+ Details<Extension>(&extension));
}
-
+
Profile* profile_;
std::vector<FilePath> persistent_paths_;
@@ -78,7 +85,7 @@ class BlacklistManagerTest : public testing::Test, public NotificationObserver {
public:
BlacklistManagerTest() : path_provider_(&profile_) {
}
-
+
virtual void SetUp() {
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir_));
test_data_dir_ = test_data_dir_.AppendASCII("blacklist_samples");
@@ -103,7 +110,7 @@ class BlacklistManagerTest : public testing::Test, public NotificationObserver {
Source<Profile>(&profile_));
MessageLoop::current()->Run();
}
-
+
void WaitForBlacklistUpdate() {
NotificationRegistrar registrar;
registrar.Add(this,
@@ -111,11 +118,11 @@ class BlacklistManagerTest : public testing::Test, public NotificationObserver {
Source<Profile>(&profile_));
MessageLoop::current()->Run();
}
-
+
FilePath test_data_dir_;
MyTestingProfile profile_;
-
+
TestBlacklistPathProvider path_provider_;
private:
@@ -157,24 +164,24 @@ TEST_F(BlacklistManagerTest, BlacklistPathProvider) {
path_provider_.AddPersistentPath(
test_data_dir_.AppendASCII("annoying_ads.pbl"));
WaitForBlacklistUpdate();
-
+
const Blacklist* blacklist2 = manager->GetCompiledBlacklist();
// Added a real blacklist, the manager should recompile.
EXPECT_NE(blacklist1, blacklist2);
EXPECT_TRUE(BlacklistHasMatch(blacklist2, "http://host/annoying_ads/ad.jpg"));
EXPECT_FALSE(BlacklistHasMatch(blacklist2, "http://host/other_ads/ad.jpg"));
-
+
path_provider_.AddTransientPath(test_data_dir_.AppendASCII("other_ads.pbl"));
WaitForBlacklistUpdate();
-
+
const Blacklist* blacklist3 = manager->GetCompiledBlacklist();
-
+
// In theory blacklist2 and blacklist3 could be the same object, so we're
// not checking for inequality.
EXPECT_TRUE(BlacklistHasMatch(blacklist3, "http://host/annoying_ads/ad.jpg"));
EXPECT_TRUE(BlacklistHasMatch(blacklist3, "http://host/other_ads/ad.jpg"));
-
+
// Now make sure that transient blacklists don't survive after re-creating
// the BlacklistManager.
manager = NULL;
@@ -183,9 +190,9 @@ TEST_F(BlacklistManagerTest, BlacklistPathProvider) {
test_data_dir_.AppendASCII("annoying_ads.pbl"));
manager = new BlacklistManager(&profile_, &path_provider_, NULL);
WaitForBlacklistUpdate();
-
+
const Blacklist* blacklist4 = manager->GetCompiledBlacklist();
-
+
EXPECT_TRUE(BlacklistHasMatch(blacklist4, "http://host/annoying_ads/ad.jpg"));
EXPECT_FALSE(BlacklistHasMatch(blacklist4, "http://host/other_ads/ad.jpg"));
}
@@ -222,7 +229,7 @@ TEST_F(BlacklistManagerTest, BlacklistPathReadError) {
ASSERT_FALSE(file_util::PathExists(bogus_path));
path_provider_.AddPersistentPath(bogus_path);
WaitForBlacklistError();
-
+
const Blacklist* blacklist = manager->GetCompiledBlacklist();
EXPECT_TRUE(blacklist);
}
diff --git a/chrome/browser/views/browser_actions_container.cc b/chrome/browser/views/browser_actions_container.cc
index 179677c..f6036dd 100644
--- a/chrome/browser/views/browser_actions_container.cc
+++ b/chrome/browser/views/browser_actions_container.cc
@@ -229,11 +229,11 @@ BrowserActionsContainer::BrowserActionsContainer(
return;
registrar_.Add(this, NotificationType::EXTENSION_LOADED,
- Source<ExtensionsService>(extension_service));
+ Source<Profile>(profile_));
registrar_.Add(this, NotificationType::EXTENSION_UNLOADED,
- Source<ExtensionsService>(extension_service));
+ Source<Profile>(profile_));
registrar_.Add(this, NotificationType::EXTENSION_UNLOADED_DISABLED,
- Source<ExtensionsService>(extension_service));
+ Source<Profile>(profile_));
registrar_.Add(this, NotificationType::EXTENSION_HOST_VIEW_SHOULD_CLOSE,
Source<Profile>(profile_));
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index 4ef2bff..c1fe430 100755
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -78,6 +78,7 @@
'browser/gtk/bookmark_manager_browsertest.cc',
'browser/gtk/view_id_util_browsertest.cc',
'browser/net/ftp_browsertest.cc',
+ 'browser/privacy_blacklist/blacklist_manager_browsertest.cc',
'browser/ssl/ssl_browser_tests.cc',
],
'browser_tests_sources_win_specific': [
@@ -117,6 +118,7 @@
'browser/extensions/extension_toolstrip_apitest.cc',
'browser/extensions/isolated_world_apitest.cc',
'browser/extensions/page_action_apitest.cc',
+ 'browser/privacy_blacklist/blacklist_manager_browsertest.cc',
'browser/ssl/ssl_browser_tests.cc',
],
# TODO(jcampan): move these vars to views.gyp.
diff --git a/chrome/common/notification_type.h b/chrome/common/notification_type.h
index 5da2c6e..1ea5923 100644
--- a/chrome/common/notification_type.h
+++ b/chrome/common/notification_type.h
@@ -632,26 +632,30 @@ class NotificationType {
// Sent when the known installed extensions have all been loaded. In
// testing scenarios this can happen multiple times if extensions are
- // unloaded and reloaded.
+ // unloaded and reloaded. The source is a Profile.
EXTENSIONS_READY,
- // Sent when a new extension is loaded. The details are an Extension.
+ // Sent when a new extension is loaded. The details are an Extension, and
+ // the source is a Profile.
EXTENSION_LOADED,
// Sent when attempting to load a new extension, but they are disabled. The
- // details are an Extension*.
+ // details are an Extension*, and the source is a Profile*.
EXTENSION_UPDATE_DISABLED,
// Sent when a theme is ready to be installed, so we can alert the user.
EXTENSION_READY_FOR_INSTALL,
- // Sent on ExtensionOverinstallAttempted when no theme is detected.
+ // Sent on ExtensionOverinstallAttempted when no theme is detected. The
+ // source is a Profile.
NO_THEME_DETECTED,
- // Sent when a new theme is installed. The details are an Extension.
+ // Sent when a new theme is installed. The details are an Extension, and the
+ // source is a Profile.
THEME_INSTALLED,
- // Sent when new extensions are installed. The details are an Extension.
+ // Sent when new extensions are installed. The details are an Extension, and
+ // the source is a Profile.
EXTENSION_INSTALLED,
// An error occured during extension install. The details are a string with
@@ -664,9 +668,10 @@ class NotificationType {
// Sent when an extension is unloaded. This happens when an extension is
// uninstalled. When we add a disable feature, it will also happen then.
- // The details are an Extension. Note that when this notification is sent,
- // ExtensionsService has already removed the extension from its internal
- // state.
+ // The details are an Extension, and the source is a Profile.
+ //
+ // Note that when this notification is sent, ExtensionsService has already
+ // removed the extension from its internal state.
EXTENSION_UNLOADED,
// Same as above, but for a disabled extension.
@@ -694,7 +699,7 @@ class NotificationType {
EXTENSION_PROCESS_CREATED,
// Sent when extension render process crashes. The details are
- // an ExtensionHost* and the source is an ExtensionsService*.
+ // an ExtensionHost* and the source is a Profile*.
EXTENSION_PROCESS_CRASHED,
// Sent when the contents or order of toolstrips in the shelf model change.
@@ -727,11 +732,6 @@ class NotificationType {
// Privacy Blacklist -------------------------------------------------------
- // Sent when a privacy blacklist path provider changes the list of its
- // blacklist paths (like adds/removes items). The details are
- // a BlacklistPathProvider, and the source is a Profile.
- BLACKLIST_PATH_PROVIDER_UPDATED,
-
// Sent when the blacklist manager successfully finishes reading
// a blacklist. The details are a Blacklist, and the source is a Profile.
BLACKLIST_MANAGER_BLACKLIST_READ_FINISHED,
diff --git a/chrome/test/data/extensions/common/privacy_blacklist/manifest.json b/chrome/test/data/extensions/common/privacy_blacklist/manifest.json
new file mode 100644
index 0000000..8e3b221
--- /dev/null
+++ b/chrome/test/data/extensions/common/privacy_blacklist/manifest.json
@@ -0,0 +1,8 @@
+{
+ "description": "Extension which has a privacy blacklist",
+ "name": "privacy_blacklist",
+ "privacy_blacklists": [
+ "privacy_blacklist.pbl"
+ ],
+ "version": "0.1"
+} \ No newline at end of file
diff --git a/chrome/test/data/extensions/common/privacy_blacklist/privacy_blacklist.pbl b/chrome/test/data/extensions/common/privacy_blacklist/privacy_blacklist.pbl
new file mode 100644
index 0000000..b9dc8d2
--- /dev/null
+++ b/chrome/test/data/extensions/common/privacy_blacklist/privacy_blacklist.pbl
@@ -0,0 +1,12 @@
+[Chromium::PrivacyBlacklist]
+|Name: AnnoyingAds
+|URL: http://www.ads.tv
+
+# Block Ads by servers
+annoying.ads.tv/@ => kBlockAll
+
+# Block Ads by name
+@/annoying/120x600.jpg => kBlockAll
+
+# Block Ads by path
+@/annoying_ads/@ => kBlockAll