Declarative content scripts: Browser-side: per-extension shared memory regions (lazily loaded)

BUG=377978

Review URL: https://codereview.chromium.org/420543002

Cr-Commit-Position: refs/heads/master@{#289969}
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@289969 0039d316-1c4b-4281-b951-d872f2087c98
parent e120b01a
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
#include "base/path_service.h" #include "base/path_service.h"
#include "base/strings/string_util.h" #include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "chrome/browser/extensions/user_script_master.h" #include "chrome/browser/extensions/user_script_loader.h"
#include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_paths.h"
#include "crypto/sha2.h" #include "crypto/sha2.h"
#include "extensions/common/constants.h" #include "extensions/common/constants.h"
...@@ -45,7 +45,7 @@ scoped_refptr<Extension> ConvertUserScriptToExtension( ...@@ -45,7 +45,7 @@ scoped_refptr<Extension> ConvertUserScriptToExtension(
} }
UserScript script; UserScript script;
if (!UserScriptMaster::ParseMetadataHeader(content, &script)) { if (!UserScriptLoader::ParseMetadataHeader(content, &script)) {
*error = base::ASCIIToUTF16("Invalid script header."); *error = base::ASCIIToUTF16("Invalid script header.");
return NULL; return NULL;
} }
......
// Copyright 2014 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/extensions/declarative_user_script_master.h"
#include <set>
#include "chrome/browser/profiles/profile.h"
#include "extensions/browser/extension_registry.h"
namespace extensions {
DeclarativeUserScriptMaster::DeclarativeUserScriptMaster(
Profile* profile,
const ExtensionId& extension_id)
: extension_id_(extension_id),
loader_(profile,
extension_id,
false /* listen_for_extension_system_loaded */),
extension_registry_observer_(this) {
extension_registry_observer_.Add(ExtensionRegistry::Get(profile));
}
DeclarativeUserScriptMaster::~DeclarativeUserScriptMaster() {
}
void DeclarativeUserScriptMaster::OnExtensionUnloaded(
content::BrowserContext* browser_context,
const Extension* extension,
UnloadedExtensionInfo::Reason reason) {
if (extension_id_ == extension->id())
ClearScripts();
}
void DeclarativeUserScriptMaster::AddScript(const UserScript& script) {
std::set<UserScript> set;
set.insert(script);
loader_.AddScripts(set);
}
void DeclarativeUserScriptMaster::RemoveScript(const UserScript& script) {
std::set<UserScript> set;
set.insert(script);
loader_.RemoveScripts(set);
}
void DeclarativeUserScriptMaster::ClearScripts() {
loader_.ClearScripts();
}
} // namespace extensions
// Copyright 2014 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.
#ifndef CHROME_BROWSER_EXTENSIONS_DECLARATIVE_USER_SCRIPT_MASTER_H_
#define CHROME_BROWSER_EXTENSIONS_DECLARATIVE_USER_SCRIPT_MASTER_H_
#include "base/scoped_observer.h"
#include "chrome/browser/extensions/user_script_loader.h"
#include "extensions/browser/extension_registry_observer.h"
#include "extensions/common/extension.h"
class Profile;
namespace extensions {
class ExtensionRegistry;
class UserScript;
// Manages declarative user scripts for a single extension. Owns a
// UserScriptLoader to which file loading and shared memory management
// operations are delegated, and provides an interface for adding, removing,
// and clearing scripts.
class DeclarativeUserScriptMaster : public ExtensionRegistryObserver {
public:
DeclarativeUserScriptMaster(Profile* profile,
const ExtensionId& extension_id);
virtual ~DeclarativeUserScriptMaster();
// Adds script to shared memory region. This may not happen right away if a
// script load is in progress.
void AddScript(const UserScript& script);
// Removes script from shared memory region. This may not happen right away if
// a script load is in progress.
void RemoveScript(const UserScript& script);
// Removes all scripts from shared memory region. This may not happen right
// away if a script load is in progress.
void ClearScripts();
const ExtensionId& extension_id() const { return extension_id_; }
private:
// ExtensionRegistryObserver implementation.
virtual void OnExtensionUnloaded(
content::BrowserContext* browser_context,
const Extension* extension,
UnloadedExtensionInfo::Reason reason) OVERRIDE;
// ID of extension that owns scripts that this component manages.
ExtensionId extension_id_;
// Script loader that handles loading contents of scripts into shared memory
// and notifying renderers of script updates.
UserScriptLoader loader_;
ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver>
extension_registry_observer_;
DISALLOW_COPY_AND_ASSIGN(DeclarativeUserScriptMaster);
};
} // namespace extensions
#endif // CHROME_BROWSER_EXTENSIONS_DECLARATIVE_USER_SCRIPT_MASTER_H_
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
#include "chrome/browser/extensions/extension_apitest.h" #include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_test_message_listener.h" #include "chrome/browser/extensions/extension_test_message_listener.h"
#include "chrome/browser/extensions/user_script_master.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/browser_window.h"
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
#include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_util.h" #include "chrome/browser/extensions/extension_util.h"
#include "chrome/browser/extensions/user_script_master.h" #include "chrome/browser/extensions/shared_user_script_master.h"
#include "chrome/browser/prefs/chrome_pref_service_factory.h" #include "chrome/browser/prefs/chrome_pref_service_factory.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser.h"
...@@ -131,12 +131,12 @@ class ExtensionStartupTestBase : public InProcessBrowserTest { ...@@ -131,12 +131,12 @@ class ExtensionStartupTestBase : public InProcessBrowserTest {
content::WindowedNotificationObserver user_scripts_observer( content::WindowedNotificationObserver user_scripts_observer(
extensions::NOTIFICATION_USER_SCRIPTS_UPDATED, extensions::NOTIFICATION_USER_SCRIPTS_UPDATED,
content::NotificationService::AllSources()); content::NotificationService::AllSources());
extensions::UserScriptMaster* master = extensions::SharedUserScriptMaster* master =
extensions::ExtensionSystem::Get(browser()->profile())-> extensions::ExtensionSystem::Get(browser()->profile())->
user_script_master(); shared_user_script_master();
if (!master->ScriptsReady()) if (!master->scripts_ready())
user_scripts_observer.Wait(); user_scripts_observer.Wait();
ASSERT_TRUE(master->ScriptsReady()); ASSERT_TRUE(master->scripts_ready());
} }
void TestInjection(bool expect_css, bool expect_script) { void TestInjection(bool expect_css, bool expect_script) {
......
...@@ -12,10 +12,12 @@ ...@@ -12,10 +12,12 @@
#include "base/metrics/field_trial.h" #include "base/metrics/field_trial.h"
#include "base/metrics/histogram.h" #include "base/metrics/histogram.h"
#include "base/strings/string_tokenizer.h" #include "base/strings/string_tokenizer.h"
#include "base/strings/string_util.h"
#include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process.h"
#include "chrome/browser/content_settings/cookie_settings.h" #include "chrome/browser/content_settings/cookie_settings.h"
#include "chrome/browser/extensions/blacklist.h" #include "chrome/browser/extensions/blacklist.h"
#include "chrome/browser/extensions/component_loader.h" #include "chrome/browser/extensions/component_loader.h"
#include "chrome/browser/extensions/declarative_user_script_master.h"
#include "chrome/browser/extensions/error_console/error_console.h" #include "chrome/browser/extensions/error_console/error_console.h"
#include "chrome/browser/extensions/extension_error_reporter.h" #include "chrome/browser/extensions/extension_error_reporter.h"
#include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/extension_service.h"
...@@ -26,11 +28,11 @@ ...@@ -26,11 +28,11 @@
#include "chrome/browser/extensions/install_verifier.h" #include "chrome/browser/extensions/install_verifier.h"
#include "chrome/browser/extensions/navigation_observer.h" #include "chrome/browser/extensions/navigation_observer.h"
#include "chrome/browser/extensions/shared_module_service.h" #include "chrome/browser/extensions/shared_module_service.h"
#include "chrome/browser/extensions/shared_user_script_master.h"
#include "chrome/browser/extensions/standard_management_policy_provider.h" #include "chrome/browser/extensions/standard_management_policy_provider.h"
#include "chrome/browser/extensions/state_store_notification_observer.h" #include "chrome/browser/extensions/state_store_notification_observer.h"
#include "chrome/browser/extensions/unpacked_installer.h" #include "chrome/browser/extensions/unpacked_installer.h"
#include "chrome/browser/extensions/updater/manifest_fetch_data.h" #include "chrome/browser/extensions/updater/manifest_fetch_data.h"
#include "chrome/browser/extensions/user_script_master.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/ui/webui/extensions/extension_icon_source.h" #include "chrome/browser/ui/webui/extensions/extension_icon_source.h"
...@@ -305,7 +307,7 @@ void ExtensionSystemImpl::Shared::Init(bool extensions_enabled) { ...@@ -305,7 +307,7 @@ void ExtensionSystemImpl::Shared::Init(bool extensions_enabled) {
bool allow_noisy_errors = !command_line->HasSwitch(switches::kNoErrorDialogs); bool allow_noisy_errors = !command_line->HasSwitch(switches::kNoErrorDialogs);
ExtensionErrorReporter::Init(allow_noisy_errors); ExtensionErrorReporter::Init(allow_noisy_errors);
user_script_master_.reset(new UserScriptMaster(profile_)); shared_user_script_master_.reset(new SharedUserScriptMaster(profile_));
// ExtensionService depends on RuntimeData. // ExtensionService depends on RuntimeData.
runtime_data_.reset(new RuntimeData(ExtensionRegistry::Get(profile_))); runtime_data_.reset(new RuntimeData(ExtensionRegistry::Get(profile_)));
...@@ -439,8 +441,9 @@ ManagementPolicy* ExtensionSystemImpl::Shared::management_policy() { ...@@ -439,8 +441,9 @@ ManagementPolicy* ExtensionSystemImpl::Shared::management_policy() {
return management_policy_.get(); return management_policy_.get();
} }
UserScriptMaster* ExtensionSystemImpl::Shared::user_script_master() { SharedUserScriptMaster*
return user_script_master_.get(); ExtensionSystemImpl::Shared::shared_user_script_master() {
return shared_user_script_master_.get();
} }
InfoMap* ExtensionSystemImpl::Shared::info_map() { InfoMap* ExtensionSystemImpl::Shared::info_map() {
...@@ -482,6 +485,27 @@ ContentVerifier* ExtensionSystemImpl::Shared::content_verifier() { ...@@ -482,6 +485,27 @@ ContentVerifier* ExtensionSystemImpl::Shared::content_verifier() {
return content_verifier_.get(); return content_verifier_.get();
} }
DeclarativeUserScriptMaster*
ExtensionSystemImpl::Shared::GetDeclarativeUserScriptMasterByExtension(
const ExtensionId& extension_id) {
DCHECK(ready().is_signaled());
DeclarativeUserScriptMaster* master = NULL;
for (ScopedVector<DeclarativeUserScriptMaster>::iterator it =
declarative_user_script_masters_.begin();
it != declarative_user_script_masters_.end();
++it) {
if ((*it)->extension_id() == extension_id) {
master = *it;
break;
}
}
if (!master) {
master = new DeclarativeUserScriptMaster(profile_, extension_id);
declarative_user_script_masters_.push_back(master);
}
return master;
}
// //
// ExtensionSystemImpl // ExtensionSystemImpl
// //
...@@ -506,7 +530,7 @@ void ExtensionSystemImpl::Shutdown() { ...@@ -506,7 +530,7 @@ void ExtensionSystemImpl::Shutdown() {
void ExtensionSystemImpl::InitForRegularProfile(bool extensions_enabled) { void ExtensionSystemImpl::InitForRegularProfile(bool extensions_enabled) {
DCHECK(!profile_->IsOffTheRecord()); DCHECK(!profile_->IsOffTheRecord());
if (user_script_master() || extension_service()) if (shared_user_script_master() || extension_service())
return; // Already initialized. return; // Already initialized.
// The InfoMap needs to be created before the ProcessManager. // The InfoMap needs to be created before the ProcessManager.
...@@ -529,8 +553,8 @@ ManagementPolicy* ExtensionSystemImpl::management_policy() { ...@@ -529,8 +553,8 @@ ManagementPolicy* ExtensionSystemImpl::management_policy() {
return shared_->management_policy(); return shared_->management_policy();
} }
UserScriptMaster* ExtensionSystemImpl::user_script_master() { SharedUserScriptMaster* ExtensionSystemImpl::shared_user_script_master() {
return shared_->user_script_master(); return shared_->shared_user_script_master();
} }
ProcessManager* ExtensionSystemImpl::process_manager() { ProcessManager* ExtensionSystemImpl::process_manager() {
...@@ -589,6 +613,12 @@ scoped_ptr<ExtensionSet> ExtensionSystemImpl::GetDependentExtensions( ...@@ -589,6 +613,12 @@ scoped_ptr<ExtensionSet> ExtensionSystemImpl::GetDependentExtensions(
extension); extension);
} }
DeclarativeUserScriptMaster*
ExtensionSystemImpl::GetDeclarativeUserScriptMasterByExtension(
const ExtensionId& extension_id) {
return shared_->GetDeclarativeUserScriptMasterByExtension(extension_id);
}
void ExtensionSystemImpl::RegisterExtensionWithRequestContexts( void ExtensionSystemImpl::RegisterExtensionWithRequestContexts(
const Extension* extension) { const Extension* extension) {
base::Time install_time; base::Time install_time;
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#ifndef CHROME_BROWSER_EXTENSIONS_EXTENSION_SYSTEM_IMPL_H_ #ifndef CHROME_BROWSER_EXTENSIONS_EXTENSION_SYSTEM_IMPL_H_
#define CHROME_BROWSER_EXTENSIONS_EXTENSION_SYSTEM_IMPL_H_ #define CHROME_BROWSER_EXTENSIONS_EXTENSION_SYSTEM_IMPL_H_
#include "base/memory/scoped_vector.h"
#include "extensions/browser/extension_system.h" #include "extensions/browser/extension_system.h"
#include "extensions/common/one_shot_event.h" #include "extensions/common/one_shot_event.h"
...@@ -13,9 +14,11 @@ class Profile; ...@@ -13,9 +14,11 @@ class Profile;
namespace extensions { namespace extensions {
class ContentVerifier; class ContentVerifier;
class DeclarativeUserScriptMaster;
class ExtensionSystemSharedFactory; class ExtensionSystemSharedFactory;
class ExtensionWarningBadgeService; class ExtensionWarningBadgeService;
class NavigationObserver; class NavigationObserver;
class SharedUserScriptMaster;
class StandardManagementPolicyProvider; class StandardManagementPolicyProvider;
class StateStoreNotificationObserver; class StateStoreNotificationObserver;
...@@ -37,7 +40,8 @@ class ExtensionSystemImpl : public ExtensionSystem { ...@@ -37,7 +40,8 @@ class ExtensionSystemImpl : public ExtensionSystem {
virtual ExtensionService* extension_service() OVERRIDE; // shared virtual ExtensionService* extension_service() OVERRIDE; // shared
virtual RuntimeData* runtime_data() OVERRIDE; // shared virtual RuntimeData* runtime_data() OVERRIDE; // shared
virtual ManagementPolicy* management_policy() OVERRIDE; // shared virtual ManagementPolicy* management_policy() OVERRIDE; // shared
virtual UserScriptMaster* user_script_master() OVERRIDE; // shared // shared
virtual SharedUserScriptMaster* shared_user_script_master() OVERRIDE;
virtual ProcessManager* process_manager() OVERRIDE; virtual ProcessManager* process_manager() OVERRIDE;
virtual StateStore* state_store() OVERRIDE; // shared virtual StateStore* state_store() OVERRIDE; // shared
virtual StateStore* rules_store() OVERRIDE; // shared virtual StateStore* rules_store() OVERRIDE; // shared
...@@ -63,6 +67,10 @@ class ExtensionSystemImpl : public ExtensionSystem { ...@@ -63,6 +67,10 @@ class ExtensionSystemImpl : public ExtensionSystem {
virtual scoped_ptr<ExtensionSet> GetDependentExtensions( virtual scoped_ptr<ExtensionSet> GetDependentExtensions(
const Extension* extension) OVERRIDE; const Extension* extension) OVERRIDE;
virtual DeclarativeUserScriptMaster*
GetDeclarativeUserScriptMasterByExtension(
const ExtensionId& extension_id) OVERRIDE; // shared
private: private:
friend class ExtensionSystemSharedFactory; friend class ExtensionSystemSharedFactory;
...@@ -87,7 +95,7 @@ class ExtensionSystemImpl : public ExtensionSystem { ...@@ -87,7 +95,7 @@ class ExtensionSystemImpl : public ExtensionSystem {
ExtensionService* extension_service(); ExtensionService* extension_service();
RuntimeData* runtime_data(); RuntimeData* runtime_data();
ManagementPolicy* management_policy(); ManagementPolicy* management_policy();
UserScriptMaster* user_script_master(); SharedUserScriptMaster* shared_user_script_master();
Blacklist* blacklist(); Blacklist* blacklist();
InfoMap* info_map(); InfoMap* info_map();
LazyBackgroundTaskQueue* lazy_background_task_queue(); LazyBackgroundTaskQueue* lazy_background_task_queue();
...@@ -99,6 +107,9 @@ class ExtensionSystemImpl : public ExtensionSystem { ...@@ -99,6 +107,9 @@ class ExtensionSystemImpl : public ExtensionSystem {
const OneShotEvent& ready() const { return ready_; } const OneShotEvent& ready() const { return ready_; }
ContentVerifier* content_verifier(); ContentVerifier* content_verifier();
DeclarativeUserScriptMaster* GetDeclarativeUserScriptMasterByExtension(
const ExtensionId& extension_id);
private: private:
Profile* profile_; Profile* profile_;
...@@ -113,7 +124,13 @@ class ExtensionSystemImpl : public ExtensionSystem { ...@@ -113,7 +124,13 @@ class ExtensionSystemImpl : public ExtensionSystem {
scoped_ptr<LazyBackgroundTaskQueue> lazy_background_task_queue_; scoped_ptr<LazyBackgroundTaskQueue> lazy_background_task_queue_;
scoped_ptr<EventRouter> event_router_; scoped_ptr<EventRouter> event_router_;
scoped_ptr<NavigationObserver> navigation_observer_; scoped_ptr<NavigationObserver> navigation_observer_;
scoped_ptr<UserScriptMaster> user_script_master_; // Shared memory region manager for scripts statically declared in extension
// manifests. This region is shared between all extensions.
scoped_ptr<SharedUserScriptMaster> shared_user_script_master_;
// Shared memory region manager for programmatically declared scripts, one
// per extension. Managers are instantiated the first time the declarative
// API is used by an extension to request content scripts.
ScopedVector<DeclarativeUserScriptMaster> declarative_user_script_masters_;
scoped_ptr<Blacklist> blacklist_; scoped_ptr<Blacklist> blacklist_;
// StandardManagementPolicyProvider depends on Blacklist. // StandardManagementPolicyProvider depends on Blacklist.
scoped_ptr<StandardManagementPolicyProvider> scoped_ptr<StandardManagementPolicyProvider>
......
// Copyright 2014 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/extensions/shared_user_script_master.h"
#include "chrome/browser/extensions/extension_util.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/extensions/manifest_handlers/content_scripts_handler.h"
#include "extensions/browser/extension_registry.h"
namespace extensions {
SharedUserScriptMaster::SharedUserScriptMaster(Profile* profile)
: loader_(profile,
std::string() /* owner_extension_id */,
true /* listen_for_extension_system_loaded */),
profile_(profile),
extension_registry_observer_(this) {
extension_registry_observer_.Add(ExtensionRegistry::Get(profile_));
}
SharedUserScriptMaster::~SharedUserScriptMaster() {
}
void SharedUserScriptMaster::OnExtensionLoaded(
content::BrowserContext* browser_context,
const Extension* extension) {
loader_.AddScripts(GetScriptsMetadata(extension));
}
void SharedUserScriptMaster::OnExtensionUnloaded(
content::BrowserContext* browser_context,
const Extension* extension,
UnloadedExtensionInfo::Reason reason) {
loader_.RemoveScripts(GetScriptsMetadata(extension));
}
const std::set<UserScript> SharedUserScriptMaster::GetScriptsMetadata(
const Extension* extension) {
bool incognito_enabled = util::IsIncognitoEnabled(extension->id(), profile_);
const UserScriptList& script_list =
ContentScriptsInfo::GetContentScripts(extension);
std::set<UserScript> script_set;
for (UserScriptList::const_iterator it = script_list.begin();
it != script_list.end();
++it) {
UserScript script = *it;
script.set_incognito_enabled(incognito_enabled);
script_set.insert(script);
}
return script_set;
}
} // namespace extensions
// Copyright 2014 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.
#ifndef CHROME_BROWSER_EXTENSIONS_SHARED_USER_SCRIPT_MASTER_H_
#define CHROME_BROWSER_EXTENSIONS_SHARED_USER_SCRIPT_MASTER_H_
#include <set>
#include "base/scoped_observer.h"
#include "chrome/browser/extensions/user_script_loader.h"
#include "extensions/browser/extension_registry_observer.h"
#include "extensions/common/extension.h"
#include "extensions/common/user_script.h"
namespace content {
class BrowserContext;
}
class Profile;
namespace extensions {
class ExtensionRegistry;
// Manages statically-defined user scripts for all extensions. Owns a
// UserScriptLoader to which file loading and shared memory management
// operations are delegated.
class SharedUserScriptMaster : public ExtensionRegistryObserver {
public:
explicit SharedUserScriptMaster(Profile* profile);
virtual ~SharedUserScriptMaster();
// Provides access to loader state method: scripts_ready().
bool scripts_ready() const { return loader_.scripts_ready(); }
private:
// ExtensionRegistryObserver implementation.
virtual void OnExtensionLoaded(content::BrowserContext* browser_context,
const Extension* extension) OVERRIDE;
virtual void OnExtensionUnloaded(
content::BrowserContext* browser_context,
const Extension* extension,
UnloadedExtensionInfo::Reason reason) OVERRIDE;
// Gets an extension's scripts' metadata; i.e., gets a list of UserScript
// objects that contains script info, but not the contents of the scripts.
const std::set<UserScript> GetScriptsMetadata(const Extension* extension);
// Script loader that handles loading contents of scripts into shared memory
// and notifying renderers of scripts in shared memory.
UserScriptLoader loader_;
// The profile for which the scripts managed here are installed.
Profile* profile_;
ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver>
extension_registry_observer_;
DISALLOW_COPY_AND_ASSIGN(SharedUserScriptMaster);
};
} // namespace extensions
#endif // CHROME_BROWSER_EXTENSIONS_SHARED_USER_SCRIPT_MASTER_H_
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
#include "chrome/browser/extensions/install_verifier.h" #include "chrome/browser/extensions/install_verifier.h"
#include "chrome/browser/extensions/shared_module_service.h" #include "chrome/browser/extensions/shared_module_service.h"
#include "chrome/browser/extensions/standard_management_policy_provider.h" #include "chrome/browser/extensions/standard_management_policy_provider.h"
#include "chrome/browser/extensions/user_script_master.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#include "chrome/common/chrome_switches.h" #include "chrome/common/chrome_switches.h"
#include "content/public/browser/browser_thread.h" #include "content/public/browser/browser_thread.h"
...@@ -131,7 +130,7 @@ void TestExtensionSystem::SetExtensionService(ExtensionService* service) { ...@@ -131,7 +130,7 @@ void TestExtensionSystem::SetExtensionService(ExtensionService* service) {
extension_service_.reset(service); extension_service_.reset(service);
} }
UserScriptMaster* TestExtensionSystem::user_script_master() { SharedUserScriptMaster* TestExtensionSystem::shared_user_script_master() {
return NULL; return NULL;
} }
...@@ -194,6 +193,12 @@ scoped_ptr<ExtensionSet> TestExtensionSystem::GetDependentExtensions( ...@@ -194,6 +193,12 @@ scoped_ptr<ExtensionSet> TestExtensionSystem::GetDependentExtensions(
extension); extension);
} }
DeclarativeUserScriptMaster*
TestExtensionSystem::GetDeclarativeUserScriptMasterByExtension(
const ExtensionId& extension_id) {
return NULL;
}
// static // static
KeyedService* TestExtensionSystem::Build(content::BrowserContext* profile) { KeyedService* TestExtensionSystem::Build(content::BrowserContext* profile) {
return new TestExtensionSystem(static_cast<Profile*>(profile)); return new TestExtensionSystem(static_cast<Profile*>(profile));
......
...@@ -22,8 +22,10 @@ class BrowserContext; ...@@ -22,8 +22,10 @@ class BrowserContext;
} }
namespace extensions { namespace extensions {
class DeclarativeUserScriptMaster;
class ExtensionPrefs; class ExtensionPrefs;
class RuntimeData; class RuntimeData;
class SharedUserScriptMaster;
class StandardManagementPolicyProvider; class StandardManagementPolicyProvider;
// Test ExtensionSystem, for use with TestingProfile. // Test ExtensionSystem, for use with TestingProfile.
...@@ -62,7 +64,7 @@ class TestExtensionSystem : public ExtensionSystem { ...@@ -62,7 +64,7 @@ class TestExtensionSystem : public ExtensionSystem {
virtual ExtensionService* extension_service() OVERRIDE; virtual ExtensionService* extension_service() OVERRIDE;
virtual RuntimeData* runtime_data() OVERRIDE; virtual RuntimeData* runtime_data() OVERRIDE;
virtual ManagementPolicy* management_policy() OVERRIDE; virtual ManagementPolicy* management_policy() OVERRIDE;
virtual UserScriptMaster* user_script_master() OVERRIDE; virtual SharedUserScriptMaster* shared_user_script_master() OVERRIDE;
virtual ProcessManager* process_manager() OVERRIDE; virtual ProcessManager* process_manager() OVERRIDE;
virtual StateStore* state_store() OVERRIDE; virtual StateStore* state_store() OVERRIDE;
virtual StateStore* rules_store() OVERRIDE; virtual StateStore* rules_store() OVERRIDE;
...@@ -80,6 +82,9 @@ class TestExtensionSystem : public ExtensionSystem { ...@@ -80,6 +82,9 @@ class TestExtensionSystem : public ExtensionSystem {
virtual ContentVerifier* content_verifier() OVERRIDE; virtual ContentVerifier* content_verifier() OVERRIDE;
virtual scoped_ptr<ExtensionSet> GetDependentExtensions( virtual scoped_ptr<ExtensionSet> GetDependentExtensions(
const Extension* extension) OVERRIDE; const Extension* extension) OVERRIDE;
virtual DeclarativeUserScriptMaster*
GetDeclarativeUserScriptMasterByExtension(
const ExtensionId& extension_id) OVERRIDE;
void SetReady() { void SetReady() {
LOG(INFO) << "SetReady()"; LOG(INFO) << "SetReady()";
......
// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#ifndef CHROME_BROWSER_EXTENSIONS_USER_SCRIPT_MASTER_H_ #ifndef CHROME_BROWSER_EXTENSIONS_USER_SCRIPT_LOADER_H_
#define CHROME_BROWSER_EXTENSIONS_USER_SCRIPT_MASTER_H_ #define CHROME_BROWSER_EXTENSIONS_USER_SCRIPT_LOADER_H_
#include <map> #include <map>
#include <string> #include <set>
#include "base/compiler_specific.h" #include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "base/scoped_observer.h" #include "base/scoped_observer.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h" #include "content/public/browser/notification_registrar.h"
#include "extensions/browser/extension_registry_observer.h" #include "extensions/browser/extension_registry_observer.h"
#include "extensions/common/extension_messages.h" #include "extensions/common/extension.h"
#include "extensions/common/extension_set.h" #include "extensions/common/extension_set.h"
#include "extensions/common/user_script.h" #include "extensions/common/user_script.h"
...@@ -25,6 +24,7 @@ class SharedMemory; ...@@ -25,6 +24,7 @@ class SharedMemory;
} }
namespace content { namespace content {
class BrowserContext;
class RenderProcessHost; class RenderProcessHost;
} }
...@@ -35,12 +35,17 @@ namespace extensions { ...@@ -35,12 +35,17 @@ namespace extensions {
class ContentVerifier; class ContentVerifier;
class ExtensionRegistry; class ExtensionRegistry;
typedef std::map<std::string, ExtensionSet::ExtensionPathAndDefaultLocale> typedef std::map<ExtensionId, ExtensionSet::ExtensionPathAndDefaultLocale>
ExtensionsInfo; ExtensionsInfo;
// Manages a segment of shared memory that contains the user scripts the user // Manages one "logical unit" of user scripts in shared memory by constructing a
// has installed. Lives on the UI thread. // new shared memory region when the set of scripts changes. Also notifies
class UserScriptMaster : public content::NotificationObserver, // renderers of new shared memory region when new renderers appear, or when
// script reloading completes. Script loading lives on the UI thread. Instances
// of this class are embedded within classes with names ending in
// UserScriptMaster. These "master" classes implement the strategy for which
// scripts to load/unload on this logical unit of scripts.
class UserScriptLoader : public content::NotificationObserver,
public ExtensionRegistryObserver { public ExtensionRegistryObserver {
public: public:
// Parses the includes out of |script| and returns them in |includes|. // Parses the includes out of |script| and returns them in |includes|.
...@@ -51,20 +56,25 @@ class UserScriptMaster : public content::NotificationObserver, ...@@ -51,20 +56,25 @@ class UserScriptMaster : public content::NotificationObserver,
// the file thread. Exposed only for tests. // the file thread. Exposed only for tests.
static void LoadScriptsForTest(UserScriptList* user_scripts); static void LoadScriptsForTest(UserScriptList* user_scripts);
explicit UserScriptMaster(Profile* profile); UserScriptLoader(Profile* profile,
virtual ~UserScriptMaster(); const ExtensionId& owner_extension_id,
bool listen_for_extension_system_loaded);
virtual ~UserScriptLoader();
// Kicks off a process on the file thread to reload scripts from disk // Add |scripts| to the set of scripts managed by this loader.
// into a new chunk of shared memory and notify renderers. void AddScripts(const std::set<UserScript>& scripts);
virtual void StartLoad();
// Gets the segment of shared memory for the scripts. // Remove |scripts| from the set of scripts managed by this loader.
base::SharedMemory* GetSharedMemory() const { void RemoveScripts(const std::set<UserScript>& scripts);
return shared_memory_.get();
} // Clears the set of scripts managed by this loader.
void ClearScripts();
// Initiates procedure to start loading scripts on the file thread.
void StartLoad();
// Return true if we have any scripts ready. // Return true if we have any scripts ready.
bool ScriptsReady() const { return shared_memory_.get() != NULL; } bool scripts_ready() const { return shared_memory_.get() != NULL; }
private: private:
// content::NotificationObserver implementation. // content::NotificationObserver implementation.
...@@ -73,15 +83,22 @@ class UserScriptMaster : public content::NotificationObserver, ...@@ -73,15 +83,22 @@ class UserScriptMaster : public content::NotificationObserver,
const content::NotificationDetails& details) OVERRIDE; const content::NotificationDetails& details) OVERRIDE;
// ExtensionRegistryObserver implementation. // ExtensionRegistryObserver implementation.
virtual void OnExtensionLoaded(content::BrowserContext* browser_context,
const Extension* extension) OVERRIDE;
virtual void OnExtensionUnloaded( virtual void OnExtensionUnloaded(
content::BrowserContext* browser_context, content::BrowserContext* browser_context,
const Extension* extension, const Extension* extension,
UnloadedExtensionInfo::Reason reason) OVERRIDE; UnloadedExtensionInfo::Reason reason) OVERRIDE;
// Called when ExtensionSystem is ready. // Initiates script load when we have been waiting for the extension system
void OnExtensionsReady(); // to be ready.
void OnExtensionSystemReady();
// Returns whether or not it is possible that calls to AddScripts(),
// RemoveScripts(), and/or ClearScripts() have caused any real change in the
// set of scripts to be loaded.
bool ScriptsMayHaveChanged() const;
// Attempt to initiate a load.
void AttemptLoad();
// Called once we have finished loading the scripts on the file thread. // Called once we have finished loading the scripts on the file thread.
void OnScriptsLoaded(scoped_ptr<UserScriptList> user_scripts, void OnScriptsLoaded(scoped_ptr<UserScriptList> user_scripts,
...@@ -93,7 +110,14 @@ class UserScriptMaster : public content::NotificationObserver, ...@@ -93,7 +110,14 @@ class UserScriptMaster : public content::NotificationObserver,
// updated. // updated.
void SendUpdate(content::RenderProcessHost* process, void SendUpdate(content::RenderProcessHost* process,
base::SharedMemory* shared_memory, base::SharedMemory* shared_memory,
const std::set<std::string>& changed_extensions); const std::set<ExtensionId>& changed_extensions);
// Add to |changed_extensions_| those extensions referred to by |scripts|.
void ExpandChangedExtensions(const std::set<UserScript>& scripts);
// Update |extensions_info_| to contain info for each element of
// |changed_extensions_|.
void UpdateExtensionsInfo();
bool is_loading() const { bool is_loading() const {
// Ownership of |user_scripts_| is passed to the file thread when loading. // Ownership of |user_scripts_| is passed to the file thread when loading.
...@@ -112,18 +136,22 @@ class UserScriptMaster : public content::NotificationObserver, ...@@ -112,18 +136,22 @@ class UserScriptMaster : public content::NotificationObserver,
// Maps extension info needed for localization to an extension ID. // Maps extension info needed for localization to an extension ID.
ExtensionsInfo extensions_info_; ExtensionsInfo extensions_info_;
// The IDs of the extensions which have changed since the last update sent to // The mutually-exclusive sets of scripts that were added or removed since the
// the renderer. // last script load.
std::set<std::string> changed_extensions_; std::set<UserScript> added_scripts_;
std::set<UserScript> removed_scripts_;
// Indicates whether the the collection of scripts should be cleared before
// additions and removals on the next script load.
bool clear_scripts_;
// The mutually-exclusive sets of extensions that were added or removed since // The IDs of the extensions which changed in the last update sent to the
// the last script load. // renderer.
std::set<std::string> added_extensions_; ExtensionIdSet changed_extensions_;
std::set<std::string> removed_extensions_;
// If the extensions service has finished loading its initial set of // If the extensions service has finished loading its initial set of
// extensions. // extensions.
bool extensions_service_ready_; bool extension_system_ready_;
// If list of user scripts is modified while we're loading it, we note // If list of user scripts is modified while we're loading it, we note
// that we're currently mid-load and then start over again once the load // that we're currently mid-load and then start over again once the load
...@@ -136,15 +164,18 @@ class UserScriptMaster : public content::NotificationObserver, ...@@ -136,15 +164,18 @@ class UserScriptMaster : public content::NotificationObserver,
// The profile for which the scripts managed here are installed. // The profile for which the scripts managed here are installed.
Profile* profile_; Profile* profile_;
// Listen to extension load, unloaded notifications. // ID of the extension that owns these scripts, if any. This is only set to a
// non-empty value for declarative user script shared memory regions.
ExtensionId owner_extension_id_;
base::WeakPtrFactory<UserScriptLoader> weak_factory_;
ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver> ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver>
extension_registry_observer_; extension_registry_observer_;
base::WeakPtrFactory<UserScriptMaster> weak_factory_; DISALLOW_COPY_AND_ASSIGN(UserScriptLoader);
DISALLOW_COPY_AND_ASSIGN(UserScriptMaster);
}; };
} // namespace extensions } // namespace extensions
#endif // CHROME_BROWSER_EXTENSIONS_USER_SCRIPT_MASTER_H_ #endif // CHROME_BROWSER_EXTENSIONS_USER_SCRIPT_LOADER_H_
// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "chrome/browser/extensions/user_script_master.h" #include "chrome/browser/extensions/user_script_loader.h"
#include <set>
#include <string> #include <string>
#include "base/file_util.h" #include "base/file_util.h"
...@@ -14,6 +15,7 @@ ...@@ -14,6 +15,7 @@
#include "base/strings/string_util.h" #include "base/strings/string_util.h"
#include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/chrome_notification_types.h"
#include "chrome/test/base/testing_profile.h" #include "chrome/test/base/testing_profile.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h" #include "content/public/browser/notification_registrar.h"
#include "content/public/browser/notification_service.h" #include "content/public/browser/notification_service.h"
#include "content/public/test/test_browser_thread.h" #include "content/public/test/test_browser_thread.h"
...@@ -28,19 +30,17 @@ static void AddPattern(URLPatternSet* extent, const std::string& pattern) { ...@@ -28,19 +30,17 @@ static void AddPattern(URLPatternSet* extent, const std::string& pattern) {
int schemes = URLPattern::SCHEME_ALL; int schemes = URLPattern::SCHEME_ALL;
extent->AddPattern(URLPattern(schemes, pattern)); extent->AddPattern(URLPattern(schemes, pattern));
} }
} }
namespace extensions { namespace extensions {
// Test bringing up a master on a specific directory, putting a script // Test bringing up a script loader on a specific directory, putting a script
// in there, etc. // in there, etc.
class UserScriptMasterTest : public testing::Test, class UserScriptLoaderTest : public testing::Test,
public content::NotificationObserver { public content::NotificationObserver {
public: public:
UserScriptMasterTest() : shared_memory_(NULL) { UserScriptLoaderTest() : shared_memory_(NULL) {}
}
virtual void SetUp() { virtual void SetUp() {
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
...@@ -50,7 +50,7 @@ class UserScriptMasterTest : public testing::Test, ...@@ -50,7 +50,7 @@ class UserScriptMasterTest : public testing::Test,
extensions::NOTIFICATION_USER_SCRIPTS_UPDATED, extensions::NOTIFICATION_USER_SCRIPTS_UPDATED,
content::NotificationService::AllSources()); content::NotificationService::AllSources());
// UserScriptMaster posts tasks to the file thread so make the current // UserScriptLoader posts tasks to the file thread so make the current
// thread look like one. // thread look like one.
file_thread_.reset(new content::TestBrowserThread( file_thread_.reset(new content::TestBrowserThread(
BrowserThread::FILE, base::MessageLoop::current())); BrowserThread::FILE, base::MessageLoop::current()));
...@@ -89,17 +89,19 @@ class UserScriptMasterTest : public testing::Test, ...@@ -89,17 +89,19 @@ class UserScriptMasterTest : public testing::Test,
}; };
// Test that we get notified even when there are no scripts. // Test that we get notified even when there are no scripts.
TEST_F(UserScriptMasterTest, NoScripts) { TEST_F(UserScriptLoaderTest, NoScripts) {
TestingProfile profile; TestingProfile profile;
UserScriptMaster master(&profile); UserScriptLoader loader(&profile,
master.StartLoad(); std::string() /* owner_extension_id */,
true /* listen_for_extension_system_loaded */);
loader.StartLoad();
message_loop_.PostTask(FROM_HERE, base::MessageLoop::QuitClosure()); message_loop_.PostTask(FROM_HERE, base::MessageLoop::QuitClosure());
message_loop_.Run(); message_loop_.Run();
ASSERT_TRUE(shared_memory_ != NULL); ASSERT_TRUE(shared_memory_ != NULL);
} }
TEST_F(UserScriptMasterTest, Parse1) { TEST_F(UserScriptLoaderTest, Parse1) {
const std::string text( const std::string text(
"// This is my awesome script\n" "// This is my awesome script\n"
"// It does stuff.\n" "// It does stuff.\n"
...@@ -118,35 +120,35 @@ TEST_F(UserScriptMasterTest, Parse1) { ...@@ -118,35 +120,35 @@ TEST_F(UserScriptMasterTest, Parse1) {
"alert('hoo!');\n"); "alert('hoo!');\n");
UserScript script; UserScript script;
EXPECT_TRUE(UserScriptMaster::ParseMetadataHeader(text, &script)); EXPECT_TRUE(UserScriptLoader::ParseMetadataHeader(text, &script));
ASSERT_EQ(3U, script.globs().size()); ASSERT_EQ(3U, script.globs().size());
EXPECT_EQ("*mail.google.com*", script.globs()[0]); EXPECT_EQ("*mail.google.com*", script.globs()[0]);
EXPECT_EQ("*mail.yahoo.com*", script.globs()[1]); EXPECT_EQ("*mail.yahoo.com*", script.globs()[1]);
EXPECT_EQ("*mail.msn.com*", script.globs()[2]); EXPECT_EQ("*mail.msn.com*", script.globs()[2]);
} }
TEST_F(UserScriptMasterTest, Parse2) { TEST_F(UserScriptLoaderTest, Parse2) {
const std::string text("default to @include *"); const std::string text("default to @include *");
UserScript script; UserScript script;
EXPECT_TRUE(UserScriptMaster::ParseMetadataHeader(text, &script)); EXPECT_TRUE(UserScriptLoader::ParseMetadataHeader(text, &script));
ASSERT_EQ(1U, script.globs().size()); ASSERT_EQ(1U, script.globs().size());
EXPECT_EQ("*", script.globs()[0]); EXPECT_EQ("*", script.globs()[0]);
} }
TEST_F(UserScriptMasterTest, Parse3) { TEST_F(UserScriptLoaderTest, Parse3) {
const std::string text( const std::string text(
"// ==UserScript==\n" "// ==UserScript==\n"
"// @include *foo*\n" "// @include *foo*\n"
"// ==/UserScript=="); // no trailing newline "// ==/UserScript=="); // no trailing newline
UserScript script; UserScript script;
UserScriptMaster::ParseMetadataHeader(text, &script); UserScriptLoader::ParseMetadataHeader(text, &script);
ASSERT_EQ(1U, script.globs().size()); ASSERT_EQ(1U, script.globs().size());
EXPECT_EQ("*foo*", script.globs()[0]); EXPECT_EQ("*foo*", script.globs()[0]);
} }
TEST_F(UserScriptMasterTest, Parse4) { TEST_F(UserScriptLoaderTest, Parse4) {
const std::string text( const std::string text(
"// ==UserScript==\n" "// ==UserScript==\n"
"// @match http://*.mail.google.com/*\n" "// @match http://*.mail.google.com/*\n"
...@@ -158,12 +160,12 @@ TEST_F(UserScriptMasterTest, Parse4) { ...@@ -158,12 +160,12 @@ TEST_F(UserScriptMasterTest, Parse4) {
AddPattern(&expected_patterns, "http://mail.yahoo.com/*"); AddPattern(&expected_patterns, "http://mail.yahoo.com/*");
UserScript script; UserScript script;
EXPECT_TRUE(UserScriptMaster::ParseMetadataHeader(text, &script)); EXPECT_TRUE(UserScriptLoader::ParseMetadataHeader(text, &script));
EXPECT_EQ(0U, script.globs().size()); EXPECT_EQ(0U, script.globs().size());
EXPECT_EQ(expected_patterns, script.url_patterns()); EXPECT_EQ(expected_patterns, script.url_patterns());
} }
TEST_F(UserScriptMasterTest, Parse5) { TEST_F(UserScriptLoaderTest, Parse5) {
const std::string text( const std::string text(
"// ==UserScript==\n" "// ==UserScript==\n"
"// @match http://*mail.google.com/*\n" "// @match http://*mail.google.com/*\n"
...@@ -171,10 +173,10 @@ TEST_F(UserScriptMasterTest, Parse5) { ...@@ -171,10 +173,10 @@ TEST_F(UserScriptMasterTest, Parse5) {
// Invalid @match value. // Invalid @match value.
UserScript script; UserScript script;
EXPECT_FALSE(UserScriptMaster::ParseMetadataHeader(text, &script)); EXPECT_FALSE(UserScriptLoader::ParseMetadataHeader(text, &script));
} }
TEST_F(UserScriptMasterTest, Parse6) { TEST_F(UserScriptLoaderTest, Parse6) {
const std::string text( const std::string text(
"// ==UserScript==\n" "// ==UserScript==\n"
"// @include http://*.mail.google.com/*\n" "// @include http://*.mail.google.com/*\n"
...@@ -183,10 +185,10 @@ TEST_F(UserScriptMasterTest, Parse6) { ...@@ -183,10 +185,10 @@ TEST_F(UserScriptMasterTest, Parse6) {
// Allowed to match @include and @match. // Allowed to match @include and @match.
UserScript script; UserScript script;
EXPECT_TRUE(UserScriptMaster::ParseMetadataHeader(text, &script)); EXPECT_TRUE(UserScriptLoader::ParseMetadataHeader(text, &script));
} }
TEST_F(UserScriptMasterTest, Parse7) { TEST_F(UserScriptLoaderTest, Parse7) {
// Greasemonkey allows there to be any leading text before the comment marker. // Greasemonkey allows there to be any leading text before the comment marker.
const std::string text( const std::string text(
"// ==UserScript==\n" "// ==UserScript==\n"
...@@ -196,7 +198,7 @@ TEST_F(UserScriptMasterTest, Parse7) { ...@@ -196,7 +198,7 @@ TEST_F(UserScriptMasterTest, Parse7) {
"// ==/UserScript==\n"); "// ==/UserScript==\n");
UserScript script; UserScript script;
EXPECT_TRUE(UserScriptMaster::ParseMetadataHeader(text, &script)); EXPECT_TRUE(UserScriptLoader::ParseMetadataHeader(text, &script));
ASSERT_EQ("hello", script.name()); ASSERT_EQ("hello", script.name());
ASSERT_EQ("wiggity woo", script.description()); ASSERT_EQ("wiggity woo", script.description());
ASSERT_EQ(1U, script.url_patterns().patterns().size()); ASSERT_EQ(1U, script.url_patterns().patterns().size());
...@@ -204,7 +206,7 @@ TEST_F(UserScriptMasterTest, Parse7) { ...@@ -204,7 +206,7 @@ TEST_F(UserScriptMasterTest, Parse7) {
script.url_patterns().begin()->GetAsString()); script.url_patterns().begin()->GetAsString());
} }
TEST_F(UserScriptMasterTest, Parse8) { TEST_F(UserScriptLoaderTest, Parse8) {
const std::string text( const std::string text(
"// ==UserScript==\n" "// ==UserScript==\n"
"// @name myscript\n" "// @name myscript\n"
...@@ -213,7 +215,7 @@ TEST_F(UserScriptMasterTest, Parse8) { ...@@ -213,7 +215,7 @@ TEST_F(UserScriptMasterTest, Parse8) {
"// ==/UserScript==\n"); "// ==/UserScript==\n");
UserScript script; UserScript script;
EXPECT_TRUE(UserScriptMaster::ParseMetadataHeader(text, &script)); EXPECT_TRUE(UserScriptLoader::ParseMetadataHeader(text, &script));
ASSERT_EQ("myscript", script.name()); ASSERT_EQ("myscript", script.name());
ASSERT_EQ(1U, script.url_patterns().patterns().size()); ASSERT_EQ(1U, script.url_patterns().patterns().size());
EXPECT_EQ("http://www.google.com/*", EXPECT_EQ("http://www.google.com/*",
...@@ -223,26 +225,26 @@ TEST_F(UserScriptMasterTest, Parse8) { ...@@ -223,26 +225,26 @@ TEST_F(UserScriptMasterTest, Parse8) {
script.exclude_url_patterns().begin()->GetAsString()); script.exclude_url_patterns().begin()->GetAsString());
} }
TEST_F(UserScriptMasterTest, SkipBOMAtTheBeginning) { TEST_F(UserScriptLoaderTest, SkipBOMAtTheBeginning) {
base::FilePath path = temp_dir_.path().AppendASCII("script.user.js"); base::FilePath path = temp_dir_.path().AppendASCII("script.user.js");
const std::string content("\xEF\xBB\xBF alert('hello');"); const std::string content("\xEF\xBB\xBF alert('hello');");
size_t written = base::WriteFile(path, content.c_str(), content.size()); size_t written = base::WriteFile(path, content.c_str(), content.size());
ASSERT_EQ(written, content.size()); ASSERT_EQ(written, content.size());
UserScript user_script; UserScript user_script;
user_script.js_scripts().push_back(UserScript::File( user_script.js_scripts().push_back(
temp_dir_.path(), path.BaseName(), GURL())); UserScript::File(temp_dir_.path(), path.BaseName(), GURL()));
UserScriptList user_scripts; UserScriptList user_scripts;
user_scripts.push_back(user_script); user_scripts.push_back(user_script);
UserScriptMaster::LoadScriptsForTest(&user_scripts); UserScriptLoader::LoadScriptsForTest(&user_scripts);
EXPECT_EQ(content.substr(3), EXPECT_EQ(content.substr(3),
user_scripts[0].js_scripts()[0].GetContent().as_string()); user_scripts[0].js_scripts()[0].GetContent().as_string());
} }
TEST_F(UserScriptMasterTest, LeaveBOMNotAtTheBeginning) { TEST_F(UserScriptLoaderTest, LeaveBOMNotAtTheBeginning) {
base::FilePath path = temp_dir_.path().AppendASCII("script.user.js"); base::FilePath path = temp_dir_.path().AppendASCII("script.user.js");
const std::string content("alert('here's a BOOM: \xEF\xBB\xBF');"); const std::string content("alert('here's a BOOM: \xEF\xBB\xBF');");
size_t written = base::WriteFile(path, content.c_str(), content.size()); size_t written = base::WriteFile(path, content.c_str(), content.size());
...@@ -255,7 +257,7 @@ TEST_F(UserScriptMasterTest, LeaveBOMNotAtTheBeginning) { ...@@ -255,7 +257,7 @@ TEST_F(UserScriptMasterTest, LeaveBOMNotAtTheBeginning) {
UserScriptList user_scripts; UserScriptList user_scripts;
user_scripts.push_back(user_script); user_scripts.push_back(user_script);
UserScriptMaster::LoadScriptsForTest(&user_scripts); UserScriptLoader::LoadScriptsForTest(&user_scripts);
EXPECT_EQ(content, user_scripts[0].js_scripts()[0].GetContent().as_string()); EXPECT_EQ(content, user_scripts[0].js_scripts()[0].GetContent().as_string());
} }
......
...@@ -644,6 +644,8 @@ ...@@ -644,6 +644,8 @@
'browser/extensions/crx_installer_error.h', 'browser/extensions/crx_installer_error.h',
'browser/extensions/data_deleter.cc', 'browser/extensions/data_deleter.cc',
'browser/extensions/data_deleter.h', 'browser/extensions/data_deleter.h',
'browser/extensions/declarative_user_script_master.cc',
'browser/extensions/declarative_user_script_master.h',
'browser/extensions/dev_mode_bubble_controller.cc', 'browser/extensions/dev_mode_bubble_controller.cc',
'browser/extensions/dev_mode_bubble_controller.h', 'browser/extensions/dev_mode_bubble_controller.h',
'browser/extensions/devtools_util.cc', 'browser/extensions/devtools_util.cc',
...@@ -842,6 +844,8 @@ ...@@ -842,6 +844,8 @@
'browser/extensions/settings_api_helpers.h', 'browser/extensions/settings_api_helpers.h',
'browser/extensions/shared_module_service.cc', 'browser/extensions/shared_module_service.cc',
'browser/extensions/shared_module_service.h', 'browser/extensions/shared_module_service.h',
'browser/extensions/shared_user_script_master.cc',
'browser/extensions/shared_user_script_master.h',
'browser/extensions/standard_management_policy_provider.cc', 'browser/extensions/standard_management_policy_provider.cc',
'browser/extensions/standard_management_policy_provider.h', 'browser/extensions/standard_management_policy_provider.h',
'browser/extensions/startup_helper.cc', 'browser/extensions/startup_helper.cc',
...@@ -877,8 +881,8 @@ ...@@ -877,8 +881,8 @@
'browser/extensions/url_request_util.h', 'browser/extensions/url_request_util.h',
'browser/extensions/user_script_listener.cc', 'browser/extensions/user_script_listener.cc',
'browser/extensions/user_script_listener.h', 'browser/extensions/user_script_listener.h',
'browser/extensions/user_script_master.cc', 'browser/extensions/user_script_loader.cc',
'browser/extensions/user_script_master.h', 'browser/extensions/user_script_loader.h',
'browser/extensions/webstore_data_fetcher.cc', 'browser/extensions/webstore_data_fetcher.cc',
'browser/extensions/webstore_data_fetcher.h', 'browser/extensions/webstore_data_fetcher.h',
'browser/extensions/webstore_data_fetcher_delegate.cc', 'browser/extensions/webstore_data_fetcher_delegate.cc',
......
...@@ -986,7 +986,7 @@ ...@@ -986,7 +986,7 @@
'browser/extensions/updater/extension_cache_fake.cc', 'browser/extensions/updater/extension_cache_fake.cc',
'browser/extensions/updater/extension_updater_unittest.cc', 'browser/extensions/updater/extension_updater_unittest.cc',
'browser/extensions/user_script_listener_unittest.cc', 'browser/extensions/user_script_listener_unittest.cc',
'browser/extensions/user_script_master_unittest.cc', 'browser/extensions/user_script_loader_unittest.cc',
'browser/extensions/webstore_inline_installer_unittest.cc', 'browser/extensions/webstore_inline_installer_unittest.cc',
'browser/extensions/webstore_installer_unittest.cc', 'browser/extensions/webstore_installer_unittest.cc',
'browser/extensions/zipfile_installer_unittest.cc', 'browser/extensions/zipfile_installer_unittest.cc',
......
...@@ -27,6 +27,7 @@ namespace extensions { ...@@ -27,6 +27,7 @@ namespace extensions {
class Blacklist; class Blacklist;
class ContentVerifier; class ContentVerifier;
class DeclarativeUserScriptMaster;
class ErrorConsole; class ErrorConsole;
class EventRouter; class EventRouter;
class Extension; class Extension;
...@@ -40,8 +41,8 @@ class OneShotEvent; ...@@ -40,8 +41,8 @@ class OneShotEvent;
class ProcessManager; class ProcessManager;
class QuotaService; class QuotaService;
class RuntimeData; class RuntimeData;
class SharedUserScriptMaster;
class StateStore; class StateStore;
class UserScriptMaster;
// ExtensionSystem manages the lifetime of many of the services used by the // ExtensionSystem manages the lifetime of many of the services used by the
// extensions and apps system, and it handles startup and shutdown as needed. // extensions and apps system, and it handles startup and shutdown as needed.
...@@ -72,8 +73,8 @@ class ExtensionSystem : public KeyedService { ...@@ -72,8 +73,8 @@ class ExtensionSystem : public KeyedService {
// The ManagementPolicy is created at startup. // The ManagementPolicy is created at startup.
virtual ManagementPolicy* management_policy() = 0; virtual ManagementPolicy* management_policy() = 0;
// The UserScriptMaster is created at startup. // The SharedUserScriptMaster is created at startup.
virtual UserScriptMaster* user_script_master() = 0; virtual SharedUserScriptMaster* shared_user_script_master() = 0;
// The ProcessManager is created at startup. // The ProcessManager is created at startup.
virtual ProcessManager* process_manager() = 0; virtual ProcessManager* process_manager() = 0;
...@@ -135,6 +136,11 @@ class ExtensionSystem : public KeyedService { ...@@ -135,6 +136,11 @@ class ExtensionSystem : public KeyedService {
// so it can be retrieved from ExtensionSystem directly. // so it can be retrieved from ExtensionSystem directly.
virtual scoped_ptr<ExtensionSet> GetDependentExtensions( virtual scoped_ptr<ExtensionSet> GetDependentExtensions(
const Extension* extension) = 0; const Extension* extension) = 0;
// Get the user script master for declarative scripts, if any.
virtual DeclarativeUserScriptMaster*
GetDeclarativeUserScriptMasterByExtension(
const ExtensionId& extension_id) = 0;
}; };
} // namespace extensions } // namespace extensions
......
...@@ -34,7 +34,7 @@ ManagementPolicy* MockExtensionSystem::management_policy() { ...@@ -34,7 +34,7 @@ ManagementPolicy* MockExtensionSystem::management_policy() {
return NULL; return NULL;
} }
UserScriptMaster* MockExtensionSystem::user_script_master() { SharedUserScriptMaster* MockExtensionSystem::shared_user_script_master() {
return NULL; return NULL;
} }
...@@ -90,6 +90,12 @@ ContentVerifier* MockExtensionSystem::content_verifier() { ...@@ -90,6 +90,12 @@ ContentVerifier* MockExtensionSystem::content_verifier() {
return NULL; return NULL;
} }
DeclarativeUserScriptMaster*
MockExtensionSystem::GetDeclarativeUserScriptMasterByExtension(
const ExtensionId& extension_id) {
return NULL;
}
scoped_ptr<ExtensionSet> MockExtensionSystem::GetDependentExtensions( scoped_ptr<ExtensionSet> MockExtensionSystem::GetDependentExtensions(
const Extension* extension) { const Extension* extension) {
return scoped_ptr<ExtensionSet>(); return scoped_ptr<ExtensionSet>();
......
...@@ -30,7 +30,7 @@ class MockExtensionSystem : public ExtensionSystem { ...@@ -30,7 +30,7 @@ class MockExtensionSystem : public ExtensionSystem {
virtual ExtensionService* extension_service() OVERRIDE; virtual ExtensionService* extension_service() OVERRIDE;
virtual RuntimeData* runtime_data() OVERRIDE; virtual RuntimeData* runtime_data() OVERRIDE;
virtual ManagementPolicy* management_policy() OVERRIDE; virtual ManagementPolicy* management_policy() OVERRIDE;
virtual UserScriptMaster* user_script_master() OVERRIDE; virtual SharedUserScriptMaster* shared_user_script_master() OVERRIDE;
virtual ProcessManager* process_manager() OVERRIDE; virtual ProcessManager* process_manager() OVERRIDE;
virtual StateStore* state_store() OVERRIDE; virtual StateStore* state_store() OVERRIDE;
virtual StateStore* rules_store() OVERRIDE; virtual StateStore* rules_store() OVERRIDE;
...@@ -46,6 +46,9 @@ class MockExtensionSystem : public ExtensionSystem { ...@@ -46,6 +46,9 @@ class MockExtensionSystem : public ExtensionSystem {
virtual ContentVerifier* content_verifier() OVERRIDE; virtual ContentVerifier* content_verifier() OVERRIDE;
virtual scoped_ptr<ExtensionSet> GetDependentExtensions( virtual scoped_ptr<ExtensionSet> GetDependentExtensions(
const Extension* extension) OVERRIDE; const Extension* extension) OVERRIDE;
virtual DeclarativeUserScriptMaster*
GetDeclarativeUserScriptMasterByExtension(
const ExtensionId& extension_id) OVERRIDE;
private: private:
content::BrowserContext* browser_context_; content::BrowserContext* browser_context_;
......
...@@ -240,4 +240,11 @@ void UserScript::UnpickleScripts(const ::Pickle& pickle, PickleIterator* iter, ...@@ -240,4 +240,11 @@ void UserScript::UnpickleScripts(const ::Pickle& pickle, PickleIterator* iter,
} }
} }
bool operator<(const UserScript& script1, const UserScript& script2) {
// The only kind of script that should be compared is the kind that has its
// IDs initialized to a meaningful value.
DCHECK(script1.id() != -1 && script2.id() != -1);
return script1.id() < script2.id();
}
} // namespace extensions } // namespace extensions
...@@ -287,6 +287,9 @@ class UserScript { ...@@ -287,6 +287,9 @@ class UserScript {
bool incognito_enabled_; bool incognito_enabled_;
}; };
// For storing UserScripts with unique IDs in sets.
bool operator<(const UserScript& script1, const UserScript& script2);
typedef std::vector<UserScript> UserScriptList; typedef std::vector<UserScript> UserScriptList;
} // namespace extensions } // namespace extensions
......
...@@ -112,7 +112,7 @@ ManagementPolicy* ShellExtensionSystem::management_policy() { ...@@ -112,7 +112,7 @@ ManagementPolicy* ShellExtensionSystem::management_policy() {
return NULL; return NULL;
} }
UserScriptMaster* ShellExtensionSystem::user_script_master() { SharedUserScriptMaster* ShellExtensionSystem::shared_user_script_master() {
return NULL; return NULL;
} }
...@@ -193,4 +193,10 @@ scoped_ptr<ExtensionSet> ShellExtensionSystem::GetDependentExtensions( ...@@ -193,4 +193,10 @@ scoped_ptr<ExtensionSet> ShellExtensionSystem::GetDependentExtensions(
return empty.PassAs<ExtensionSet>(); return empty.PassAs<ExtensionSet>();
} }
DeclarativeUserScriptMaster*
ShellExtensionSystem::GetDeclarativeUserScriptMasterByExtension(
const ExtensionId& extension_id) {
return NULL;
}
} // namespace extensions } // namespace extensions
...@@ -23,11 +23,13 @@ class BrowserContext; ...@@ -23,11 +23,13 @@ class BrowserContext;
namespace extensions { namespace extensions {
class DeclarativeUserScriptMaster;
class EventRouter; class EventRouter;
class InfoMap; class InfoMap;
class LazyBackgroundTaskQueue; class LazyBackgroundTaskQueue;
class ProcessManager; class ProcessManager;
class RendererStartupHelper; class RendererStartupHelper;
class SharedUserScriptMaster;
// A simplified version of ExtensionSystem for app_shell. Allows // A simplified version of ExtensionSystem for app_shell. Allows
// app_shell to skip initialization of services it doesn't need. // app_shell to skip initialization of services it doesn't need.
...@@ -52,7 +54,7 @@ class ShellExtensionSystem : public ExtensionSystem { ...@@ -52,7 +54,7 @@ class ShellExtensionSystem : public ExtensionSystem {
virtual ExtensionService* extension_service() OVERRIDE; virtual ExtensionService* extension_service() OVERRIDE;
virtual RuntimeData* runtime_data() OVERRIDE; virtual RuntimeData* runtime_data() OVERRIDE;
virtual ManagementPolicy* management_policy() OVERRIDE; virtual ManagementPolicy* management_policy() OVERRIDE;
virtual UserScriptMaster* user_script_master() OVERRIDE; virtual SharedUserScriptMaster* shared_user_script_master() OVERRIDE;
virtual ProcessManager* process_manager() OVERRIDE; virtual ProcessManager* process_manager() OVERRIDE;
virtual StateStore* state_store() OVERRIDE; virtual StateStore* state_store() OVERRIDE;
virtual StateStore* rules_store() OVERRIDE; virtual StateStore* rules_store() OVERRIDE;
...@@ -73,6 +75,9 @@ class ShellExtensionSystem : public ExtensionSystem { ...@@ -73,6 +75,9 @@ class ShellExtensionSystem : public ExtensionSystem {
virtual ContentVerifier* content_verifier() OVERRIDE; virtual ContentVerifier* content_verifier() OVERRIDE;
virtual scoped_ptr<ExtensionSet> GetDependentExtensions( virtual scoped_ptr<ExtensionSet> GetDependentExtensions(
const Extension* extension) OVERRIDE; const Extension* extension) OVERRIDE;
virtual DeclarativeUserScriptMaster*
GetDeclarativeUserScriptMasterByExtension(
const ExtensionId& extension_id) OVERRIDE;
private: private:
content::BrowserContext* browser_context_; // Not owned. content::BrowserContext* browser_context_; // Not owned.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment