diff options
Diffstat (limited to 'chrome/browser')
30 files changed, 610 insertions, 222 deletions
diff --git a/chrome/browser/extensions/api/declarative/declarative_api.cc b/chrome/browser/extensions/api/declarative/declarative_api.cc index 8f09411..72d9fc1 100644 --- a/chrome/browser/extensions/api/declarative/declarative_api.cc +++ b/chrome/browser/extensions/api/declarative/declarative_api.cc @@ -8,7 +8,7 @@ #include "base/bind_helpers.h" #include "base/values.h" #include "chrome/browser/extensions/api/declarative/rules_registry_service.h" -#include "chrome/browser/extensions/extension_service.h" +#include "chrome/browser/extensions/extension_system_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/extensions/api/experimental.declarative.h" #include "content/public/browser/browser_thread.h" @@ -46,7 +46,8 @@ bool RulesFunction::RunImpl() { EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &event_name)); RulesRegistryService* rules_registry_service = - profile()->GetExtensionService()->GetRulesRegistryService(); + ExtensionSystemFactory::GetForProfile(profile())-> + rules_registry_service(); rules_registry_ = rules_registry_service->GetRulesRegistry(event_name); // Raw access to this function is not available to extensions, therefore // there should never be a request for a nonexisting rules registry. diff --git a/chrome/browser/extensions/api/declarative/declarative_apitest.cc b/chrome/browser/extensions/api/declarative/declarative_apitest.cc index d40a401..3e56f45 100644 --- a/chrome/browser/extensions/api/declarative/declarative_apitest.cc +++ b/chrome/browser/extensions/api/declarative/declarative_apitest.cc @@ -7,9 +7,10 @@ #include "base/command_line.h" #include "base/memory/scoped_ptr.h" #include "chrome/browser/extensions/api/declarative/rules_registry_service.h" +#include "chrome/browser/extensions/api/declarative_webrequest/webrequest_constants.h" #include "chrome/browser/extensions/api/declarative_webrequest/webrequest_rules_registry.h" #include "chrome/browser/extensions/extension_apitest.h" -#include "chrome/browser/extensions/extension_service.h" +#include "chrome/browser/extensions/extension_system_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" #include "chrome/common/chrome_switches.h" @@ -21,35 +22,18 @@ using extensions::RulesRegistry; using extensions::RulesRegistryService; using extensions::WebRequestRulesRegistry; -namespace { -const char kTestEvent[] = "experimental.webRequest.onRequest"; -} // namespace - class DeclarativeApiTest : public ExtensionApiTest { public: - DeclarativeApiTest() : rules_registry_(NULL) {} + DeclarativeApiTest() {} virtual ~DeclarativeApiTest() {} virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { ExtensionApiTest::SetUpCommandLine(command_line); command_line->AppendSwitch(switches::kEnableExperimentalExtensionApis); } - - void RegisterTestRuleRegistry() { - Profile* profile = browser()->profile(); - RulesRegistryService* rules_registry_service = - profile->GetExtensionService()->GetRulesRegistryService(); - rules_registry_ = new WebRequestRulesRegistry(); - // TODO(battre): The registry should register itself when the - // RulesRegistryService is instantiated. - rules_registry_service->RegisterRulesRegistry(kTestEvent, rules_registry_); - } - - scoped_refptr<RulesRegistry> rules_registry_; }; IN_PROC_BROWSER_TEST_F(DeclarativeApiTest, DeclarativeApi) { - RegisterTestRuleRegistry(); ASSERT_TRUE(RunExtensionTest("declarative/api")) << message_; // Check that unloading the page has removed all rules. @@ -60,15 +44,22 @@ IN_PROC_BROWSER_TEST_F(DeclarativeApiTest, DeclarativeApi) { // to process this unloading. The next task to retrive all rules // is therefore processed after the UnloadExtension task has been executed. + RulesRegistryService* rules_registry_service = + ExtensionSystemFactory::GetForProfile(browser()->profile())-> + rules_registry_service(); + scoped_refptr<RulesRegistry> rules_registry = + rules_registry_service->GetRulesRegistry( + extensions::declarative_webrequest_constants::kOnRequest); + std::vector<linked_ptr<RulesRegistry::Rule> > known_rules; content::BrowserThread::PostTask( - rules_registry_->GetOwnerThread(), + rules_registry->GetOwnerThread(), FROM_HERE, base::Bind(base::IgnoreResult(&RulesRegistry::GetAllRules), - rules_registry_, extension_id, &known_rules)); + rules_registry, extension_id, &known_rules)); - ui_test_utils::RunAllPendingInMessageLoop(rules_registry_->GetOwnerThread()); + ui_test_utils::RunAllPendingInMessageLoop(rules_registry->GetOwnerThread()); EXPECT_TRUE(known_rules.empty()); } diff --git a/chrome/browser/extensions/api/declarative/rules_registry_service.cc b/chrome/browser/extensions/api/declarative/rules_registry_service.cc index 40d5c12..dcd1746 100644 --- a/chrome/browser/extensions/api/declarative/rules_registry_service.cc +++ b/chrome/browser/extensions/api/declarative/rules_registry_service.cc @@ -6,7 +6,11 @@ #include "base/bind.h" #include "base/logging.h" +#include "content/public/browser/browser_thread.h" #include "chrome/browser/extensions/api/declarative/initializing_rules_registry.h" +#include "chrome/browser/extensions/api/declarative_webrequest/webrequest_constants.h" +#include "chrome/browser/extensions/api/declarative_webrequest/webrequest_rules_registry.h" +#include "chrome/browser/extensions/api/web_request/web_request_api.h" #include "chrome/common/chrome_notification_types.h" #include "chrome/common/extensions/extension.h" #include "content/public/browser/notification_details.h" @@ -14,6 +18,17 @@ namespace extensions { +namespace { + +// Registers |web_request_rules_registry| on the IO thread. +void RegisterToExtensionWebRequestEventRouterOnIO( + scoped_refptr<WebRequestRulesRegistry> web_request_rules_registry) { + ExtensionWebRequestEventRouter::GetInstance()->RegisterRulesRegistry( + web_request_rules_registry); +} + +} // namespace + RulesRegistryService::RulesRegistryService(Profile* profile) { if (profile) { registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, @@ -23,6 +38,17 @@ RulesRegistryService::RulesRegistryService(Profile* profile) { RulesRegistryService::~RulesRegistryService() {} +void RulesRegistryService::RegisterDefaultRulesRegistries() { + scoped_refptr<WebRequestRulesRegistry> web_request_rules_registry( + new WebRequestRulesRegistry); + RegisterRulesRegistry(declarative_webrequest_constants::kOnRequest, + web_request_rules_registry); + content::BrowserThread::PostTask( + content::BrowserThread::IO, FROM_HERE, + base::Bind(&RegisterToExtensionWebRequestEventRouterOnIO, + web_request_rules_registry)); +} + void RulesRegistryService::RegisterRulesRegistry( const std::string& event_name, scoped_refptr<RulesRegistry> rule_registry) { diff --git a/chrome/browser/extensions/api/declarative/rules_registry_service.h b/chrome/browser/extensions/api/declarative/rules_registry_service.h index 145f62d..92bb166 100644 --- a/chrome/browser/extensions/api/declarative/rules_registry_service.h +++ b/chrome/browser/extensions/api/declarative/rules_registry_service.h @@ -34,6 +34,9 @@ class RulesRegistryService : public content::NotificationObserver { explicit RulesRegistryService(Profile* profile); virtual ~RulesRegistryService(); + // Registers the default RulesRegistries used in Chromium. + void RegisterDefaultRulesRegistries(); + // Registers a RulesRegistry and wraps it in an InitializingRulesRegistry. void RegisterRulesRegistry(const std::string& event_name, scoped_refptr<RulesRegistry> rule_registry); diff --git a/chrome/browser/extensions/api/declarative_webrequest/request_stages.h b/chrome/browser/extensions/api/declarative_webrequest/request_stages.h index 2e539b3..06772ec 100644 --- a/chrome/browser/extensions/api/declarative_webrequest/request_stages.h +++ b/chrome/browser/extensions/api/declarative_webrequest/request_stages.h @@ -11,6 +11,8 @@ namespace extensions { // The stages of the web request during which a condition can be tested and // an action can be applied. This is required because for example the response // headers cannot be tested before a request has been sent. +// +// TODO(battre) rename to singular. enum RequestStages { ON_BEFORE_REQUEST = 1 << 0, ON_BEFORE_SEND_HEADERS = 1 << 1, diff --git a/chrome/browser/extensions/api/declarative_webrequest/webrequest_action.cc b/chrome/browser/extensions/api/declarative_webrequest/webrequest_action.cc index 11ec612..6220ccd 100644 --- a/chrome/browser/extensions/api/declarative_webrequest/webrequest_action.cc +++ b/chrome/browser/extensions/api/declarative_webrequest/webrequest_action.cc @@ -8,19 +8,20 @@ #include "base/stringprintf.h" #include "base/values.h" #include "chrome/browser/extensions/api/declarative_webrequest/request_stages.h" +#include "chrome/browser/extensions/api/declarative_webrequest/webrequest_constants.h" +#include "chrome/browser/extensions/api/web_request/web_request_api_helpers.h" +#include "net/url_request/url_request.h" namespace extensions { -namespace { -// Constants from the JavaScript API. -const char kInstanceType[] = "instanceType"; -const char kInstanceCancel[] = "experimental.webRequest.CancelRequest"; -const char kInstanceRedirect[] = "experimental.webRequest.RedirectRequest"; +namespace keys = declarative_webrequest_constants; +namespace { // Error messages. const char kExpectedDictionary[] = "Expected a dictionary as action."; const char kInvalidInstanceTypeError[] = "An action has an invalid instanceType: %s"; +const char kMissingRedirectUrl[] = "No redirection target specified."; } // namespace // @@ -42,19 +43,26 @@ scoped_ptr<WebRequestAction> WebRequestAction::Create( } std::string instance_type = "No instanceType"; - if (!action_dict->GetString(kInstanceType, &instance_type)) { + if (!action_dict->GetString(keys::kInstanceTypeKey, &instance_type)) { *error = base::StringPrintf(kInvalidInstanceTypeError, instance_type.c_str()); return scoped_ptr<WebRequestAction>(NULL); } // TODO(battre): Change this into a proper factory. - if (instance_type == kInstanceCancel) { + if (instance_type == keys::kCancelRequestType) { *error = ""; return scoped_ptr<WebRequestAction>(new WebRequestCancelAction); - } else if (instance_type == kInstanceRedirect) { + } else if (instance_type == keys::kRedirectRequestType) { + std::string redirect_url_string; + if (!action_dict->GetString(keys::kRedirectUrlKey, &redirect_url_string)) { + *error = kMissingRedirectUrl; + return scoped_ptr<WebRequestAction>(NULL); + } *error = ""; - return scoped_ptr<WebRequestAction>(new WebRequestRedirectAction); + GURL redirect_url(redirect_url_string); + return scoped_ptr<WebRequestAction>( + new WebRequestRedirectAction(redirect_url)); } *error = base::StringPrintf(kInvalidInstanceTypeError, instance_type.c_str()); @@ -90,6 +98,22 @@ scoped_ptr<WebRequestActionSet> WebRequestActionSet::Create( return scoped_ptr<WebRequestActionSet>(new WebRequestActionSet(result)); } +std::list<LinkedPtrEventResponseDelta> WebRequestActionSet::CreateDeltas( + net::URLRequest* request, + RequestStages request_stage, + const std::string& extension_id, + const base::Time& extension_install_time) const { + std::list<LinkedPtrEventResponseDelta> result; + for (Actions::const_iterator i = actions_.begin(); i != actions_.end(); ++i) { + if ((*i)->GetStages() & request_stage) { + LinkedPtrEventResponseDelta delta = (*i)->CreateDelta(request, + request_stage, extension_id, extension_install_time); + if (delta.get()) + result.push_back(delta); + } + } + return result; +} // // WebRequestCancelAction @@ -108,11 +132,26 @@ WebRequestAction::Type WebRequestCancelAction::GetType() const { return WebRequestAction::ACTION_CANCEL_REQUEST; } +LinkedPtrEventResponseDelta WebRequestCancelAction::CreateDelta( + net::URLRequest* request, + RequestStages request_stage, + const std::string& extension_id, + const base::Time& extension_install_time) const { + if (!(request_stage & GetStages())) + return LinkedPtrEventResponseDelta(NULL); + LinkedPtrEventResponseDelta result( + new extension_web_request_api_helpers::EventResponseDelta( + extension_id, extension_install_time)); + result->cancel = true; + return result; +} + // // WebRequestRedirectAction // -WebRequestRedirectAction::WebRequestRedirectAction() {} +WebRequestRedirectAction::WebRequestRedirectAction(const GURL& redirect_url) + : redirect_url_(redirect_url) {} WebRequestRedirectAction::~WebRequestRedirectAction() {} @@ -124,4 +163,20 @@ WebRequestAction::Type WebRequestRedirectAction::GetType() const { return WebRequestAction::ACTION_REDIRECT_REQUEST; } +LinkedPtrEventResponseDelta WebRequestRedirectAction::CreateDelta( + net::URLRequest* request, + RequestStages request_stage, + const std::string& extension_id, + const base::Time& extension_install_time) const { + if (!(request_stage & GetStages())) + return LinkedPtrEventResponseDelta(NULL); + if (request->url() == redirect_url_) + return LinkedPtrEventResponseDelta(NULL); + LinkedPtrEventResponseDelta result( + new extension_web_request_api_helpers::EventResponseDelta( + extension_id, extension_install_time)); + result->new_url = redirect_url_; + return result; +} + } // namespace extensions diff --git a/chrome/browser/extensions/api/declarative_webrequest/webrequest_action.h b/chrome/browser/extensions/api/declarative_webrequest/webrequest_action.h index cd5973c..ff046b4 100644 --- a/chrome/browser/extensions/api/declarative_webrequest/webrequest_action.h +++ b/chrome/browser/extensions/api/declarative_webrequest/webrequest_action.h @@ -6,19 +6,35 @@ #define CHROME_BROWSER_EXTENSIONS_API_DECLARATIVE_WEBREQUEST_WEBREQUEST_ACTION_H_ #pragma once +#include <list> #include <string> #include <vector> #include "base/compiler_specific.h" #include "base/memory/linked_ptr.h" +#include "chrome/browser/extensions/api/declarative_webrequest/request_stages.h" #include "chrome/common/extensions/api/experimental.declarative.h" +#include "googleurl/src/gurl.h" namespace base { +class DictionaryValue; +class Time; class Value; } +namespace extension_web_request_api_helpers { +struct EventResponseDelta; +} + +namespace net { +class URLRequest; +} + namespace extensions { +typedef linked_ptr<extension_web_request_api_helpers::EventResponseDelta> + LinkedPtrEventResponseDelta; + // Base class for all WebRequestActions of the declarative Web Request API. // // TODO(battre): Add method that corresponds to executing the action. @@ -46,6 +62,14 @@ class WebRequestAction { // Sets |error| and returns NULL in case of an error. static scoped_ptr<WebRequestAction> Create(const base::Value& json_action, std::string* error); + + // Returns a description of the modification to |request| caused by this + // action. + virtual LinkedPtrEventResponseDelta CreateDelta( + net::URLRequest* request, + RequestStages request_stage, + const std::string& extension_id, + const base::Time& extension_install_time) const = 0; }; // Immutable container for multiple actions. @@ -53,8 +77,6 @@ class WebRequestAction { // TODO(battre): As WebRequestActionSet can become the single owner of all // actions, we can optimize here by making some of them singletons (e.g. Cancel // actions). -// -// TODO(battre): Add method that corresponds to executing the action. class WebRequestActionSet { public: typedef std::vector<linked_ptr<json_schema_compiler::any::Any> > AnyVector; @@ -69,6 +91,14 @@ class WebRequestActionSet { static scoped_ptr<WebRequestActionSet> Create(const AnyVector& actions, std::string* error); + // Returns a description of the modifications to |request| caused by the + // |actions_| that can be executed at |request_stage|. + std::list<LinkedPtrEventResponseDelta> CreateDeltas( + net::URLRequest* request, + RequestStages request_stage, + const std::string& extension_id, + const base::Time& extension_install_time) const; + const Actions& actions() const { return actions_; } private: @@ -90,24 +120,34 @@ class WebRequestCancelAction : public WebRequestAction { // Implementation of WebRequestAction: virtual int GetStages() const OVERRIDE; virtual Type GetType() const OVERRIDE; + virtual LinkedPtrEventResponseDelta CreateDelta( + net::URLRequest* request, + RequestStages request_stage, + const std::string& extension_id, + const base::Time& extension_install_time) const OVERRIDE; private: DISALLOW_COPY_AND_ASSIGN(WebRequestCancelAction); }; // Action that instructs to redirect a network request. -// TODO(battre): This needs to be expanded to contain information to which -// URL a request should be redirected. class WebRequestRedirectAction : public WebRequestAction { public: - WebRequestRedirectAction(); + explicit WebRequestRedirectAction(const GURL& redirect_url); virtual ~WebRequestRedirectAction(); // Implementation of WebRequestAction: virtual int GetStages() const OVERRIDE; virtual Type GetType() const OVERRIDE; + virtual LinkedPtrEventResponseDelta CreateDelta( + net::URLRequest* request, + RequestStages request_stage, + const std::string& extension_id, + const base::Time& extension_install_time) const OVERRIDE; private: + GURL redirect_url_; // Target to which the request shall be redirected. + DISALLOW_COPY_AND_ASSIGN(WebRequestRedirectAction); }; diff --git a/chrome/browser/extensions/api/declarative_webrequest/webrequest_action_unittest.cc b/chrome/browser/extensions/api/declarative_webrequest/webrequest_action_unittest.cc index a48b5dc..b7bb85d 100644 --- a/chrome/browser/extensions/api/declarative_webrequest/webrequest_action_unittest.cc +++ b/chrome/browser/extensions/api/declarative_webrequest/webrequest_action_unittest.cc @@ -5,15 +5,17 @@ #include "chrome/browser/extensions/api/declarative_webrequest/webrequest_action.h" #include "base/values.h" +#include "chrome/browser/extensions/api/declarative_webrequest/webrequest_constants.h" #include "testing/gtest/include/gtest/gtest.h" namespace { -const char kCancelRequestType[] = "experimental.webRequest.CancelRequest"; const char kUnknownActionType[] = "unknownType"; } // namespace namespace extensions { +namespace keys = declarative_webrequest_constants; + TEST(WebRequestActionTest, CreateAction) { std::string error; scoped_ptr<WebRequestAction> result; @@ -33,14 +35,14 @@ TEST(WebRequestActionTest, CreateAction) { EXPECT_FALSE(result.get()); // Test wrong instanceType element. - input.SetString("instanceType", kUnknownActionType); + input.SetString(keys::kInstanceTypeKey, kUnknownActionType); error.clear(); result = WebRequestAction::Create(input, &error); EXPECT_FALSE(error.empty()); EXPECT_FALSE(result.get()); // Test success - input.SetString("instanceType", kCancelRequestType); + input.SetString(keys::kInstanceTypeKey, keys::kCancelRequestType); error.clear(); result = WebRequestAction::Create(input, &error); EXPECT_TRUE(error.empty()); @@ -62,9 +64,9 @@ TEST(WebRequestActionTest, CreateActionSet) { EXPECT_TRUE(result->actions().empty()); DictionaryValue correct_action; - correct_action.SetString("instanceType", kCancelRequestType); + correct_action.SetString(keys::kInstanceTypeKey, keys::kCancelRequestType); DictionaryValue incorrect_action; - incorrect_action.SetString("instanceType", kUnknownActionType); + incorrect_action.SetString(keys::kInstanceTypeKey, kUnknownActionType); // Test success. linked_ptr<json_schema_compiler::any::Any> action1 = make_linked_ptr( diff --git a/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition.cc b/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition.cc index 4523dceb..609a109 100644 --- a/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition.cc +++ b/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition.cc @@ -11,6 +11,7 @@ #include "base/values.h" #include "chrome/browser/extensions/api/declarative_webrequest/request_stages.h" #include "chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_attribute.h" +#include "chrome/browser/extensions/api/declarative_webrequest/webrequest_constants.h" #include "net/url_request/url_request.h" namespace { @@ -28,9 +29,6 @@ const char kConditionExpectedString[] = "Condition '%s' expected a string value"; // String literals from the JavaScript API: -const char kRequestMatcher[] = "experimental.webRequest.RequestMatcher"; -const char kInstanceType[] = "instanceType"; - const char kHostContainsKey[] = "host_contains"; const char kHostEqualsKey[] = "host_equals"; const char kHostPrefixKey[] = "host_prefix"; @@ -113,6 +111,8 @@ static base::LazyInstance<URLMatcherConditionFactoryMethods> namespace extensions { +namespace keys = declarative_webrequest_constants; + // // WebRequestCondition // @@ -121,15 +121,27 @@ WebRequestCondition::WebRequestCondition( const URLMatcherConditionSet& url_matcher_conditions, const WebRequestConditionAttributes& condition_attributes) : url_matcher_conditions_(url_matcher_conditions), - condition_attributes_(condition_attributes) {} + condition_attributes_(condition_attributes), + applicable_request_stages_(~0) { + for (WebRequestConditionAttributes::const_iterator i = + condition_attributes_.begin(); i != condition_attributes_.end(); ++i) { + applicable_request_stages_ &= (*i)->GetStages(); + } +} WebRequestCondition::~WebRequestCondition() {} -bool WebRequestCondition::IsFulfilled(net::URLRequest* request) const { +bool WebRequestCondition::IsFulfilled(net::URLRequest* request, + RequestStages request_stage) const { // All condition attributes must be fulfilled for a fulfilled condition. + if (!(request_stage & applicable_request_stages_)) { + // A condition that cannot be evaluated is considered as violated. + return false; + } + for (WebRequestConditionAttributes::const_iterator i = condition_attributes_.begin(); i != condition_attributes_.end(); ++i) { - if (!(*i)->IsFulfilled(request)) + if (!(*i)->IsFulfilled(request, request_stage)) return false; } return true; @@ -148,11 +160,11 @@ scoped_ptr<WebRequestCondition> WebRequestCondition::Create( // Verify that we are dealing with a Condition whose type we understand. std::string instance_type; - if (!condition_dict->GetString(kInstanceType, &instance_type)) { + if (!condition_dict->GetString(keys::kInstanceTypeKey, &instance_type)) { *error = kConditionWithoutInstanceType; return scoped_ptr<WebRequestCondition>(NULL); } - if (instance_type != kRequestMatcher) { + if (instance_type != keys::kRequestMatcherType) { *error = kExpectedOtherConditionType; return scoped_ptr<WebRequestCondition>(NULL); } @@ -164,7 +176,7 @@ scoped_ptr<WebRequestCondition> WebRequestCondition::Create( iter.HasNext(); iter.Advance()) { const std::string& condition_attribute_name = iter.key(); const Value& condition_attribute_value = iter.value(); - if (condition_attribute_name == kInstanceType) { + if (condition_attribute_name == keys::kInstanceTypeKey) { // Skip this. } else if (IsURLMatcherConditionAttribute(condition_attribute_name)) { URLMatcherCondition url_matcher_condition = @@ -251,11 +263,12 @@ WebRequestConditionSet::~WebRequestConditionSet() {} bool WebRequestConditionSet::IsFulfilled( URLMatcherConditionSet::ID url_match, - net::URLRequest* request) const { + net::URLRequest* request, + RequestStages request_stage) const { MatchTriggers::const_iterator trigger = match_triggers_.find(url_match); DCHECK(trigger != match_triggers_.end()); DCHECK_EQ(url_match, trigger->second->url_matcher_condition_set_id()); - return trigger->second->IsFulfilled(request); + return trigger->second->IsFulfilled(request, request_stage); } void WebRequestConditionSet::GetURLMatcherConditionSets( diff --git a/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition.h b/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition.h index 6cfa8d1..e5e8b58 100644 --- a/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition.h +++ b/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition.h @@ -49,7 +49,7 @@ class WebRequestCondition { // Returns whether |request| is a match, given that the URLMatcher found // a match for |url_matcher_conditions_|. - bool IsFulfilled(net::URLRequest* request) const; + bool IsFulfilled(net::URLRequest* request, RequestStages request_stage) const; // Returns a URLMatcherConditionSet::ID which is the canonical representation // for all URL patterns that need to be matched by this WebRequestCondition. @@ -83,6 +83,10 @@ class WebRequestCondition { URLMatcherConditionSet url_matcher_conditions_; WebRequestConditionAttributes condition_attributes_; + // Bit vector indicating all RequestStages during which all + // |condition_attributes_| can be evaluated. + int applicable_request_stages_; + DISALLOW_COPY_AND_ASSIGN(WebRequestCondition); }; @@ -115,7 +119,8 @@ class WebRequestConditionSet { // by the URLMatcher to ensure that the each trigger in |match_triggers_| is // found. bool IsFulfilled(URLMatcherConditionSet::ID url_match, - net::URLRequest* request) const; + net::URLRequest* request, + RequestStages request_stage) const; // Appends the URLMatcherConditionSet from all conditions to |condition_sets|. void GetURLMatcherConditionSets( diff --git a/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_attribute.cc b/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_attribute.cc index 632333c..18cd897 100644 --- a/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_attribute.cc +++ b/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_attribute.cc @@ -8,12 +8,10 @@ #include "base/stringprintf.h" #include "base/values.h" #include "chrome/browser/extensions/api/declarative_webrequest/request_stages.h" +#include "chrome/browser/extensions/api/declarative_webrequest/webrequest_constants.h" #include "net/url_request/url_request.h" namespace { -// Constants from the JavaScript API. -const char kSchemeKey[] = "scheme"; - // Error messages. const char kUnknownConditionAttribute[] = "Unknown matching condition: '%s'"; const char kInvalidValue[] = "Condition '%s' has an invalid value"; @@ -21,6 +19,8 @@ const char kInvalidValue[] = "Condition '%s' has an invalid value"; namespace extensions { +namespace keys = declarative_webrequest_constants; + // // WebRequestConditionAttribute // @@ -64,7 +64,7 @@ WebRequestConditionAttributeHasScheme::~WebRequestConditionAttributeHasScheme() // static bool WebRequestConditionAttributeHasScheme::IsMatchingType( const std::string& instance_type) { - return instance_type == kSchemeKey; + return instance_type == keys::kSchemeKey; } // @@ -81,7 +81,7 @@ WebRequestConditionAttributeHasScheme::Create( std::string scheme; if (!value->GetAsString(&scheme)) { - *error = base::StringPrintf(kInvalidValue, kSchemeKey); + *error = base::StringPrintf(kInvalidValue, keys::kSchemeKey); return scoped_ptr<WebRequestConditionAttribute>(NULL); } @@ -96,7 +96,10 @@ int WebRequestConditionAttributeHasScheme::GetStages() const { } bool WebRequestConditionAttributeHasScheme::IsFulfilled( - net::URLRequest* request) { + net::URLRequest* request, + RequestStages request_stage) { + if (!(request_stage & GetStages())) + return false; return request->url().scheme() == pattern_; } diff --git a/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_attribute.h b/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_attribute.h index c026308..d0684bf 100644 --- a/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_attribute.h +++ b/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_attribute.h @@ -12,6 +12,7 @@ #include "base/basictypes.h" #include "base/memory/linked_ptr.h" #include "base/memory/scoped_ptr.h" +#include "chrome/browser/extensions/api/declarative_webrequest/request_stages.h" #include "chrome/common/extensions/api/experimental.declarative.h" namespace base { @@ -50,7 +51,8 @@ class WebRequestConditionAttribute { virtual int GetStages() const = 0; // Returns whether the condition is fulfilled for this request. - virtual bool IsFulfilled(net::URLRequest* request) = 0; + virtual bool IsFulfilled(net::URLRequest* request, + RequestStages request_stage) = 0; virtual Type GetType() const = 0; @@ -87,7 +89,8 @@ class WebRequestConditionAttributeHasScheme // Implementation of WebRequestConditionAttribute: virtual int GetStages() const OVERRIDE; - virtual bool IsFulfilled(net::URLRequest* request) OVERRIDE; + virtual bool IsFulfilled(net::URLRequest* request, + RequestStages request_stage) OVERRIDE; virtual Type GetType() const OVERRIDE; private: diff --git a/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_attribute_unittest.cc b/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_attribute_unittest.cc index d641127..e594b93 100644 --- a/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_attribute_unittest.cc +++ b/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_attribute_unittest.cc @@ -6,16 +6,18 @@ #include "base/message_loop.h" #include "base/values.h" +#include "chrome/browser/extensions/api/declarative_webrequest/webrequest_constants.h" #include "net/url_request/url_request_test_util.h" #include "testing/gtest/include/gtest/gtest.h" namespace { -const char kSchemeConditionName[] = "scheme"; const char kUnknownConditionName[] = "unknownType"; } // namespace namespace extensions { +namespace keys = declarative_webrequest_constants; + TEST(WebRequestConditionAttributeTest, CreateConditionAttribute) { // Necessary for TestURLRequest. MessageLoop message_loop(MessageLoop::TYPE_IO); @@ -42,15 +44,15 @@ TEST(WebRequestConditionAttributeTest, CreateConditionAttribute) { // Test success error.clear(); result = WebRequestConditionAttribute::Create( - kSchemeConditionName, &http_string_value, &error); + keys::kSchemeKey, &http_string_value, &error); EXPECT_TRUE(error.empty()); ASSERT_TRUE(result.get()); EXPECT_EQ(WebRequestConditionAttribute::CONDITION_HAS_SCHEME, result->GetType()); TestURLRequest url_request_ok(GURL("http://www.example.com"), NULL); - EXPECT_TRUE(result->IsFulfilled(&url_request_ok)); + EXPECT_TRUE(result->IsFulfilled(&url_request_ok, ON_BEFORE_REQUEST)); TestURLRequest url_request_fail(GURL("https://www.example.com"), NULL); - EXPECT_FALSE(result->IsFulfilled(&url_request_fail)); + EXPECT_FALSE(result->IsFulfilled(&url_request_fail, ON_BEFORE_REQUEST)); } } // namespace extensions diff --git a/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_unittest.cc b/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_unittest.cc index be5c6ae..ca49c39 100644 --- a/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_unittest.cc +++ b/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_unittest.cc @@ -8,16 +8,14 @@ #include "base/message_loop.h" #include "base/values.h" +#include "chrome/browser/extensions/api/declarative_webrequest/webrequest_constants.h" #include "net/url_request/url_request_test_util.h" #include "testing/gtest/include/gtest/gtest.h" -namespace { -const char kRequestMatcher[] = "experimental.webRequest.RequestMatcher"; -const char kInstanceType[] = "instanceType"; -} - namespace extensions { +namespace keys = declarative_webrequest_constants; + TEST(WebRequestConditionTest, CreateCondition) { // Necessary for TestURLRequest. MessageLoop message_loop(MessageLoop::TYPE_IO); @@ -29,16 +27,19 @@ TEST(WebRequestConditionTest, CreateCondition) { DictionaryValue invalid_condition; invalid_condition.SetString("invalid", "foobar"); invalid_condition.SetString("host_suffix", "example.com"); - invalid_condition.SetString(kInstanceType, kRequestMatcher); + invalid_condition.SetString(keys::kInstanceTypeKey, + keys::kRequestMatcherType); DictionaryValue invalid_condition2; invalid_condition2.Set("host_suffix", new ListValue); - invalid_condition2.SetString(kInstanceType, kRequestMatcher); + invalid_condition2.SetString(keys::kInstanceTypeKey, + keys::kRequestMatcherType); DictionaryValue valid_condition; valid_condition.SetString("scheme", "http"); valid_condition.SetString("host_suffix", "example.com"); - valid_condition.SetString(kInstanceType, kRequestMatcher); + valid_condition.SetString(keys::kInstanceTypeKey, + keys::kRequestMatcherType); // Test wrong condition name passed. error.clear(); @@ -62,10 +63,10 @@ TEST(WebRequestConditionTest, CreateCondition) { ASSERT_TRUE(result.get()); TestURLRequest match_request(GURL("http://www.example.com"), NULL); - EXPECT_TRUE(result->IsFulfilled(&match_request)); + EXPECT_TRUE(result->IsFulfilled(&match_request, ON_BEFORE_REQUEST)); TestURLRequest wrong_scheme(GURL("https://www.example.com"), NULL); - EXPECT_FALSE(result->IsFulfilled(&wrong_scheme)); + EXPECT_FALSE(result->IsFulfilled(&wrong_scheme, ON_BEFORE_REQUEST)); } TEST(WebRequestConditionTest, CreateConditionSet) { @@ -76,13 +77,13 @@ TEST(WebRequestConditionTest, CreateConditionSet) { DictionaryValue http_condition; http_condition.SetString("scheme", "http"); http_condition.SetString("host_suffix", "example.com"); - http_condition.SetString(kInstanceType, kRequestMatcher); + http_condition.SetString(keys::kInstanceTypeKey, keys::kRequestMatcherType); DictionaryValue https_condition; https_condition.SetString("scheme", "https"); https_condition.SetString("host_suffix", "example.com"); https_condition.SetString("host_prefix", "www"); - https_condition.SetString(kInstanceType, kRequestMatcher); + https_condition.SetString(keys::kInstanceTypeKey, keys::kRequestMatcherType); WebRequestConditionSet::AnyVector conditions; @@ -120,7 +121,7 @@ TEST(WebRequestConditionTest, CreateConditionSet) { url_match_ids = matcher.MatchURL(http_url); for (std::set<URLMatcherConditionSet::ID>::iterator i = url_match_ids.begin(); i != url_match_ids.end(); ++i) { - if (result->IsFulfilled(*i, &http_request)) + if (result->IsFulfilled(*i, &http_request, ON_BEFORE_REQUEST)) ++number_matches; } EXPECT_EQ(1, number_matches); @@ -131,7 +132,7 @@ TEST(WebRequestConditionTest, CreateConditionSet) { number_matches = 0; for (std::set<URLMatcherConditionSet::ID>::iterator i = url_match_ids.begin(); i != url_match_ids.end(); ++i) { - if (result->IsFulfilled(*i, &https_request)) + if (result->IsFulfilled(*i, &https_request, ON_BEFORE_REQUEST)) ++number_matches; } EXPECT_EQ(1, number_matches); @@ -143,7 +144,7 @@ TEST(WebRequestConditionTest, CreateConditionSet) { number_matches = 0; for (std::set<URLMatcherConditionSet::ID>::iterator i = url_match_ids.begin(); i != url_match_ids.end(); ++i) { - if (result->IsFulfilled(*i, &https_foo_request)) + if (result->IsFulfilled(*i, &https_foo_request, ON_BEFORE_REQUEST)) ++number_matches; } EXPECT_EQ(0, number_matches); diff --git a/chrome/browser/extensions/api/declarative_webrequest/webrequest_constants.cc b/chrome/browser/extensions/api/declarative_webrequest/webrequest_constants.cc new file mode 100644 index 0000000..0228b15 --- /dev/null +++ b/chrome/browser/extensions/api/declarative_webrequest/webrequest_constants.cc @@ -0,0 +1,25 @@ +// Copyright (c) 2012 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/api/declarative_webrequest/webrequest_constants.h" + +namespace extensions { +namespace declarative_webrequest_constants { + +// Signals to which WebRequestRulesRegistries are registered. +const char kOnRequest[] = "experimental.webRequest.onRequest"; + +// Keys of dictionaries. +const char kInstanceTypeKey[] = "instanceType"; +const char kRedirectUrlKey[] = "redirectUrl"; +const char kSchemeKey[] = "scheme"; + +// Values of dictionaries, in particular instance types +const char kCancelRequestType[] = "experimental.webRequest.CancelRequest"; +const char kRedirectRequestType[] = "experimental.webRequest.RedirectRequest"; +const char kRequestMatcherType[] = "experimental.webRequest.RequestMatcher"; + + +} // namespace declarative_webrequest_constants +} // namespace extensions diff --git a/chrome/browser/extensions/api/declarative_webrequest/webrequest_constants.h b/chrome/browser/extensions/api/declarative_webrequest/webrequest_constants.h new file mode 100644 index 0000000..538497f --- /dev/null +++ b/chrome/browser/extensions/api/declarative_webrequest/webrequest_constants.h @@ -0,0 +1,30 @@ +// Copyright (c) 2012 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. + +// Constants used for the WebRequest API. + +#ifndef CHROME_BROWSER_EXTENSIONS_API_DECLARATIVE_WEBREQUEST_WEBREQUEST_CONSTANTS_H_ +#define CHROME_BROWSER_EXTENSIONS_API_DECLARATIVE_WEBREQUEST_WEBREQUEST_CONSTANTS_H_ +#pragma once + +namespace extensions { +namespace declarative_webrequest_constants { + +// Signals to which WebRequestRulesRegistries are registered. +extern const char kOnRequest[]; + +// Keys of dictionaries. +extern const char kInstanceTypeKey[]; +extern const char kRedirectUrlKey[]; +extern const char kSchemeKey[]; + +// Values of dictionaries, in particular instance types +extern const char kCancelRequestType[]; +extern const char kRedirectRequestType[]; +extern const char kRequestMatcherType[]; + +} // namespace declarative_webrequest_constants +} // namespace extensions + +#endif // CHROME_BROWSER_EXTENSIONS_API_DECLARATIVE_WEBREQUEST_WEBREQUEST_CONSTANTS_H_ diff --git a/chrome/browser/extensions/api/declarative_webrequest/webrequest_rule.cc b/chrome/browser/extensions/api/declarative_webrequest/webrequest_rule.cc index a05cdca..b61c9c0 100644 --- a/chrome/browser/extensions/api/declarative_webrequest/webrequest_rule.cc +++ b/chrome/browser/extensions/api/declarative_webrequest/webrequest_rule.cc @@ -7,14 +7,17 @@ #include "base/logging.h" #include "chrome/browser/extensions/api/declarative_webrequest/webrequest_action.h" #include "chrome/browser/extensions/api/declarative_webrequest/webrequest_condition.h" +#include "chrome/browser/extensions/api/web_request/web_request_api_helpers.h" namespace extensions { WebRequestRule::WebRequestRule( const GlobalRuleId& id, + base::Time extension_installation_time, scoped_ptr<WebRequestConditionSet> conditions, scoped_ptr<WebRequestActionSet> actions) : id_(id), + extension_installation_time_(extension_installation_time), conditions_(conditions.release()), actions_(actions.release()) { CHECK(conditions_.get()); @@ -36,6 +39,7 @@ bool WebRequestRule::CheckConsistency( scoped_ptr<WebRequestRule> WebRequestRule::Create( URLMatcherConditionFactory* url_matcher_condition_factory, const std::string& extension_id, + base::Time extension_installation_time, linked_ptr<RulesRegistry::Rule> rule, std::string* error) { scoped_ptr<WebRequestRule> error_result; @@ -60,7 +64,15 @@ scoped_ptr<WebRequestRule> WebRequestRule::Create( GlobalRuleId rule_id(extension_id, *(rule->id)); return scoped_ptr<WebRequestRule>( - new WebRequestRule(rule_id, conditions.Pass(), actions.Pass())); + new WebRequestRule(rule_id, extension_installation_time, + conditions.Pass(), actions.Pass())); +} + +std::list<LinkedPtrEventResponseDelta> WebRequestRule::CreateDeltas( + net::URLRequest* request, + RequestStages request_stage) const { + return actions_->CreateDeltas(request, request_stage, id_.first, + extension_installation_time_); } } // namespace extensions diff --git a/chrome/browser/extensions/api/declarative_webrequest/webrequest_rule.h b/chrome/browser/extensions/api/declarative_webrequest/webrequest_rule.h index 7a81287..843cb79 100644 --- a/chrome/browser/extensions/api/declarative_webrequest/webrequest_rule.h +++ b/chrome/browser/extensions/api/declarative_webrequest/webrequest_rule.h @@ -6,10 +6,13 @@ #define CHROME_BROWSER_EXTENSIONS_API_DECLARATIVE_WEBREQUEST_WEBREQUEST_RULE_H_ #pragma once +#include <list> #include <vector> #include "base/compiler_specific.h" +#include "base/time.h" #include "chrome/browser/extensions/api/declarative/rules_registry.h" +#include "chrome/browser/extensions/api/declarative_webrequest/request_stages.h" namespace extensions { class URLMatcherConditionFactory; @@ -17,8 +20,19 @@ class WebRequestConditionSet; class WebRequestActionSet; } +namespace extension_web_request_api_helpers { +struct EventResponseDelta; +} + +namespace net { +class URLRequest; +} + namespace extensions { +typedef linked_ptr<extension_web_request_api_helpers::EventResponseDelta> + LinkedPtrEventResponseDelta; + // Representation of a rule of the declarative Web Request API class WebRequestRule { public: @@ -27,6 +41,7 @@ class WebRequestRule { typedef std::pair<ExtensionId, RuleId> GlobalRuleId; WebRequestRule(const GlobalRuleId& id, + base::Time extension_installation_time, scoped_ptr<WebRequestConditionSet> conditions, scoped_ptr<WebRequestActionSet> actions); virtual ~WebRequestRule(); @@ -36,6 +51,7 @@ class WebRequestRule { static scoped_ptr<WebRequestRule> Create( URLMatcherConditionFactory* url_matcher_condition_factory, const std::string& extension_id, + base::Time extension_installation_time, linked_ptr<RulesRegistry::Rule> rule, std::string* error); @@ -43,6 +59,10 @@ class WebRequestRule { const WebRequestConditionSet& conditions() const { return *conditions_; } const WebRequestActionSet& actions() const { return *actions_; } + std::list<LinkedPtrEventResponseDelta> CreateDeltas( + net::URLRequest* request, + RequestStages request_stage) const; + private: // Checks whether the set of |conditions| and |actions| are consistent, // meaning for example that we do not allow combining an |action| that needs @@ -53,6 +73,7 @@ class WebRequestRule { std::string* error); GlobalRuleId id_; + base::Time extension_installation_time_; // For precedences of rules. scoped_ptr<WebRequestConditionSet> conditions_; scoped_ptr<WebRequestActionSet> actions_; diff --git a/chrome/browser/extensions/api/declarative_webrequest/webrequest_rules_registry.cc b/chrome/browser/extensions/api/declarative_webrequest/webrequest_rules_registry.cc index bffb974..8f4c69c 100644 --- a/chrome/browser/extensions/api/declarative_webrequest/webrequest_rules_registry.cc +++ b/chrome/browser/extensions/api/declarative_webrequest/webrequest_rules_registry.cc @@ -5,6 +5,7 @@ #include "chrome/browser/extensions/api/declarative_webrequest/webrequest_rules_registry.h" #include "chrome/browser/extensions/api/declarative_webrequest/webrequest_condition.h" +#include "chrome/browser/extensions/api/web_request/web_request_api_helpers.h" #include "net/url_request/url_request.h" namespace extensions { @@ -14,7 +15,8 @@ WebRequestRulesRegistry::WebRequestRulesRegistry() {} WebRequestRulesRegistry::~WebRequestRulesRegistry() {} std::set<WebRequestRule::GlobalRuleId> -WebRequestRulesRegistry::GetMatches(net::URLRequest* request) { +WebRequestRulesRegistry::GetMatches(net::URLRequest* request, + RequestStages request_stage) { std::set<WebRequestRule::GlobalRuleId> result; // Figure out for which rules the URL match conditions were fulfilled. @@ -29,16 +31,39 @@ WebRequestRulesRegistry::GetMatches(net::URLRequest* request) { CHECK(rule_trigger != rule_triggers_.end()); WebRequestRule* rule = rule_trigger->second; - if (rule->conditions().IsFulfilled(*url_match, request)) + if (rule->conditions().IsFulfilled(*url_match, request, request_stage)) result.insert(rule->id()); } return result; } +std::list<LinkedPtrEventResponseDelta> WebRequestRulesRegistry::CreateDeltas( + net::URLRequest* request, + RequestStages request_stage) { + std::set<WebRequestRule::GlobalRuleId> matches = + GetMatches(request, request_stage); + + std::list<LinkedPtrEventResponseDelta> result; + + for (std::set<WebRequestRule::GlobalRuleId>::iterator i = matches.begin(); + i != matches.end(); ++i) { + RulesMap::const_iterator rule = webrequest_rules_.find(*i); + CHECK(rule != webrequest_rules_.end()); + std::list<LinkedPtrEventResponseDelta> rule_result = + rule->second->CreateDeltas(request, request_stage); + result.splice(result.begin(), rule_result); + } + + return result; +} + std::string WebRequestRulesRegistry::AddRulesImpl( const std::string& extension_id, const std::vector<linked_ptr<RulesRegistry::Rule> >& rules) { + // TODO(battre): Retrieve this from somewhere + base::Time extension_installation_time; + std::string error; RulesMap new_webrequest_rules; @@ -49,7 +74,7 @@ std::string WebRequestRulesRegistry::AddRulesImpl( scoped_ptr<WebRequestRule> webrequest_rule( WebRequestRule::Create(url_matcher_.condition_factory(), extension_id, - *rule, &error)); + extension_installation_time, *rule, &error)); if (!error.empty()) { // We don't return here, because we want to clear temporary // condition sets in the url_matcher_. diff --git a/chrome/browser/extensions/api/declarative_webrequest/webrequest_rules_registry.h b/chrome/browser/extensions/api/declarative_webrequest/webrequest_rules_registry.h index f6c45fe..08a84e6 100644 --- a/chrome/browser/extensions/api/declarative_webrequest/webrequest_rules_registry.h +++ b/chrome/browser/extensions/api/declarative_webrequest/webrequest_rules_registry.h @@ -7,18 +7,25 @@ #pragma once #include <vector> +#include <list> #include "base/memory/linked_ptr.h" #include "chrome/browser/extensions/api/declarative/rules_registry_with_cache.h" #include "chrome/browser/extensions/api/declarative/url_matcher.h" +#include "chrome/browser/extensions/api/declarative_webrequest/request_stages.h" #include "chrome/browser/extensions/api/declarative_webrequest/webrequest_rule.h" +namespace extension_web_request_api_helpers { +struct EventResponseDelta; +} + namespace net { class URLRequest; } namespace extensions { +class RulesRegistryService; class WebRequestRule; // The WebRequestRulesRegistry is responsible for managing @@ -56,7 +63,14 @@ class WebRequestRulesRegistry : public RulesRegistryWithCache { // TODO(battre): This will become an implementation detail, because we need // a way to also execute the actions of the rules. - std::set<WebRequestRule::GlobalRuleId> GetMatches(net::URLRequest* request); + std::set<WebRequestRule::GlobalRuleId> GetMatches( + net::URLRequest* request, + RequestStages request_stage); + + // Returns which modifications should be executed on the network request + // according to the rules registered in this registry. + std::list<LinkedPtrEventResponseDelta> CreateDeltas( + net::URLRequest* request, RequestStages request_stage); // Implementation of RulesRegistryWithCache: virtual std::string AddRulesImpl( diff --git a/chrome/browser/extensions/api/declarative_webrequest/webrequest_rules_registry_unittest.cc b/chrome/browser/extensions/api/declarative_webrequest/webrequest_rules_registry_unittest.cc index 6d06f8e..478954c 100644 --- a/chrome/browser/extensions/api/declarative_webrequest/webrequest_rules_registry_unittest.cc +++ b/chrome/browser/extensions/api/declarative_webrequest/webrequest_rules_registry_unittest.cc @@ -9,6 +9,7 @@ #include "base/memory/linked_ptr.h" #include "base/message_loop.h" #include "base/values.h" +#include "chrome/browser/extensions/api/declarative_webrequest/webrequest_constants.h" #include "content/test/test_browser_thread.h" #include "net/url_request/url_request_test_util.h" #include "testing/gtest/include/gtest/gtest.h" @@ -18,14 +19,12 @@ const char kExtensionId[] = "ext1"; const char kExtensionId2[] = "ext2"; const char kRuleId1[] = "rule1"; const char kRuleId2[] = "rule2"; - -const char kCancelRequestType[] = "experimental.webRequest.CancelRequest"; -const char kRequestMatcher[] = "experimental.webRequest.RequestMatcher"; -const char kInstanceType[] = "instanceType"; -} +} // namespace namespace extensions { +namespace keys = declarative_webrequest_constants; + class WebRequestRulesRegistryTest : public testing::Test { public: public: @@ -47,13 +46,15 @@ class WebRequestRulesRegistryTest : public testing::Test { DictionaryValue http_condition_dict; http_condition_dict.SetString("scheme", "http"); http_condition_dict.SetString("host_suffix", "example.com"); - http_condition_dict.SetString(kInstanceType, kRequestMatcher); + http_condition_dict.SetString(keys::kInstanceTypeKey, + keys::kRequestMatcherType); DictionaryValue https_condition_dict; https_condition_dict.SetString("scheme", "https"); https_condition_dict.SetString("host_suffix", "example.com"); https_condition_dict.SetString("host_prefix", "www"); - https_condition_dict.SetString(kInstanceType, kRequestMatcher); + https_condition_dict.SetString(keys::kInstanceTypeKey, + keys::kRequestMatcherType); linked_ptr<json_schema_compiler::any::Any> condition1 = make_linked_ptr( new json_schema_compiler::any::Any); @@ -64,7 +65,7 @@ class WebRequestRulesRegistryTest : public testing::Test { condition2->Init(https_condition_dict); DictionaryValue action_dict; - action_dict.SetString(kInstanceType, kCancelRequestType); + action_dict.SetString(keys::kInstanceTypeKey, keys::kCancelRequestType); linked_ptr<json_schema_compiler::any::Any> action1 = make_linked_ptr( new json_schema_compiler::any::Any); @@ -83,14 +84,14 @@ class WebRequestRulesRegistryTest : public testing::Test { // Returns a rule that matches anything and cancels it. linked_ptr<RulesRegistry::Rule> CreateRule2() { DictionaryValue condition_dict; - condition_dict.SetString(kInstanceType, kRequestMatcher); + condition_dict.SetString(keys::kInstanceTypeKey, keys::kRequestMatcherType); linked_ptr<json_schema_compiler::any::Any> condition = make_linked_ptr( new json_schema_compiler::any::Any); condition->Init(condition_dict); DictionaryValue action_dict; - action_dict.SetString(kInstanceType, kCancelRequestType); + action_dict.SetString(keys::kInstanceTypeKey, keys::kCancelRequestType); linked_ptr<json_schema_compiler::any::Any> action = make_linked_ptr( new json_schema_compiler::any::Any); @@ -126,7 +127,7 @@ TEST_F(WebRequestRulesRegistryTest, AddRulesImpl) { GURL http_url("http://www.example.com"); TestURLRequest http_request(http_url, NULL); - matches = registry->GetMatches(&http_request); + matches = registry->GetMatches(&http_request, ON_BEFORE_REQUEST); EXPECT_EQ(2u, matches.size()); EXPECT_TRUE(matches.find(std::make_pair(kExtensionId, kRuleId1)) != matches.end()); @@ -135,7 +136,7 @@ TEST_F(WebRequestRulesRegistryTest, AddRulesImpl) { GURL foobar_url("http://www.foobar.com"); TestURLRequest foobar_request(foobar_url, NULL); - matches = registry->GetMatches(&foobar_request); + matches = registry->GetMatches(&foobar_request, ON_BEFORE_REQUEST); EXPECT_EQ(1u, matches.size()); EXPECT_TRUE(matches.find(std::make_pair(kExtensionId, kRuleId2)) != matches.end()); diff --git a/chrome/browser/extensions/api/web_request/web_request_api.cc b/chrome/browser/extensions/api/web_request/web_request_api.cc index db8d5e4..c566a31 100644 --- a/chrome/browser/extensions/api/web_request/web_request_api.cc +++ b/chrome/browser/extensions/api/web_request/web_request_api.cc @@ -16,6 +16,7 @@ #include "base/values.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/chrome_content_browser_client.h" +#include "chrome/browser/extensions/api/declarative_webrequest/webrequest_rules_registry.h" #include "chrome/browser/extensions/api/web_request/web_request_api_constants.h" #include "chrome/browser/extensions/api/web_request/web_request_api_helpers.h" #include "chrome/browser/extensions/api/web_request/web_request_time_tracker.h" @@ -512,6 +513,11 @@ ExtensionWebRequestEventRouter::ExtensionWebRequestEventRouter() ExtensionWebRequestEventRouter::~ExtensionWebRequestEventRouter() { } +void ExtensionWebRequestEventRouter::RegisterRulesRegistry( + scoped_refptr<extensions::WebRequestRulesRegistry> rules_registry) { + rules_registry_ = rules_registry; +} + int ExtensionWebRequestEventRouter::OnBeforeRequest( void* profile, ExtensionInfoMap* extension_info_map, @@ -530,29 +536,43 @@ int ExtensionWebRequestEventRouter::OnBeforeRequest( request->url(), profile); + // Whether to initialized blocked_requests_. + bool initialize_blocked_requests = false; + + initialize_blocked_requests |= + ProcessDeclarativeRules(request, extensions::ON_BEFORE_REQUEST); + int extra_info_spec = 0; std::vector<const EventListener*> listeners = GetMatchingListeners(profile, extension_info_map, keys::kOnBeforeRequest, request, &extra_info_spec); - if (listeners.empty()) - return net::OK; + if (!listeners.empty() && + !GetAndSetSignaled(request->identifier(), kOnBeforeRequest)) { + ListValue args; + DictionaryValue* dict = new DictionaryValue(); + ExtractRequestInfo(request, dict); + args.Append(dict); + + initialize_blocked_requests |= + DispatchEvent(profile, request, listeners, args); + } - if (GetAndSetSignaled(request->identifier(), kOnBeforeRequest)) - return net::OK; + if (!initialize_blocked_requests) + return net::OK; // Nobody saw a reason for modifying the request. - ListValue args; - DictionaryValue* dict = new DictionaryValue(); - ExtractRequestInfo(request, dict); - args.Append(dict); + blocked_requests_[request->identifier()].event = kOnBeforeRequest; + blocked_requests_[request->identifier()].callback = callback; + blocked_requests_[request->identifier()].new_url = new_url; + blocked_requests_[request->identifier()].net_log = &request->net_log(); - if (DispatchEvent(profile, request, listeners, args)) { - blocked_requests_[request->identifier()].event = kOnBeforeRequest; - blocked_requests_[request->identifier()].callback = callback; - blocked_requests_[request->identifier()].new_url = new_url; - blocked_requests_[request->identifier()].net_log = &request->net_log(); + if (blocked_requests_[request->identifier()].num_handlers_blocking == 0) { + // If there are no blocking handlers, only the declarative rules tried + // to modify the request and we can respond synchronously. + return ExecuteDeltas(profile, request->identifier(), + false /* call_callback*/); + } else { return net::ERR_IO_PENDING; } - return net::OK; } int ExtensionWebRequestEventRouter::OnBeforeSendHeaders( @@ -1273,100 +1293,7 @@ void ExtensionWebRequestEventRouter::DecrementBlockCount( extension_id, request_id, block_time); if (num_handlers_blocking == 0) { - request_time_tracker_->IncrementTotalBlockTime(request_id, block_time); - - bool credentials_set = false; - - helpers::EventResponseDeltas& deltas = blocked_request.response_deltas; - deltas.sort(&helpers::InDecreasingExtensionInstallationTimeOrder); - std::set<std::string> conflicting_extensions; - helpers::EventLogEntries event_log_entries; - - bool canceled = false; - helpers::MergeCancelOfResponses( - blocked_request.response_deltas, - &canceled, - &event_log_entries); - - if (blocked_request.event == kOnBeforeRequest) { - CHECK(!blocked_request.callback.is_null()); - helpers::MergeOnBeforeRequestResponses( - blocked_request.response_deltas, - blocked_request.new_url, - &conflicting_extensions, - &event_log_entries); - } else if (blocked_request.event == kOnBeforeSendHeaders) { - CHECK(!blocked_request.callback.is_null()); - helpers::MergeOnBeforeSendHeadersResponses( - blocked_request.response_deltas, - blocked_request.request_headers, - &conflicting_extensions, - &event_log_entries); - } else if (blocked_request.event == kOnHeadersReceived) { - CHECK(!blocked_request.callback.is_null()); - helpers::MergeOnHeadersReceivedResponses( - blocked_request.response_deltas, - blocked_request.original_response_headers.get(), - blocked_request.override_response_headers, - &conflicting_extensions, - &event_log_entries); - } else if (blocked_request.event == kOnAuthRequired) { - CHECK(blocked_request.callback.is_null()); - CHECK(!blocked_request.auth_callback.is_null()); - credentials_set = helpers::MergeOnAuthRequiredResponses( - blocked_request.response_deltas, - blocked_request.auth_credentials, - &conflicting_extensions, - &event_log_entries); - } else { - NOTREACHED(); - } - - for (helpers::EventLogEntries::const_iterator i = - event_log_entries.begin(); - i != event_log_entries.end(); ++i) { - blocked_request.net_log->AddEvent(i->event_type, i->params); - } - if (!conflicting_extensions.empty()) { - BrowserThread::PostTask( - BrowserThread::UI, - FROM_HERE, - base::Bind(&ExtensionWarningSet::NotifyWarningsOnUI, - profile, - conflicting_extensions, - ExtensionWarningSet::kNetworkConflict)); - } - - if (canceled) { - request_time_tracker_->SetRequestCanceled(request_id); - } else if (blocked_request.new_url && - !blocked_request.new_url->is_empty()) { - request_time_tracker_->SetRequestRedirected(request_id); - } - - if (!blocked_request.callback.is_null()) { - // This triggers onErrorOccurred. - int rv = canceled ? net::ERR_BLOCKED_BY_CLIENT : net::OK; - net::CompletionCallback callback = blocked_request.callback; - // Ensure that request is removed before callback because the callback - // might trigger the next event. - blocked_requests_.erase(request_id); - callback.Run(rv); - } else if (!blocked_request.auth_callback.is_null()) { - net::NetworkDelegate::AuthRequiredResponse response = - net::NetworkDelegate::AUTH_REQUIRED_RESPONSE_NO_ACTION; - if (canceled) { - response = net::NetworkDelegate::AUTH_REQUIRED_RESPONSE_CANCEL_AUTH; - } else if (credentials_set) { - response = net::NetworkDelegate::AUTH_REQUIRED_RESPONSE_SET_AUTH; - } - net::NetworkDelegate::AuthCallback callback = - blocked_request.auth_callback; - blocked_requests_.erase(request_id); - callback.Run(response); - } else { - blocked_requests_.erase(request_id); - } + ExecuteDeltas(profile, request_id, true); } else { // Update the URLRequest to indicate it is now blocked on a different // extension. @@ -1384,6 +1311,138 @@ void ExtensionWebRequestEventRouter::DecrementBlockCount( } } +int ExtensionWebRequestEventRouter::ExecuteDeltas( + void* profile, + uint64 request_id, + bool call_callback) { + BlockedRequest& blocked_request = blocked_requests_[request_id]; + CHECK(blocked_request.num_handlers_blocking == 0); + helpers::EventResponseDeltas& deltas = blocked_request.response_deltas; + base::TimeDelta block_time = + base::Time::Now() - blocked_request.blocking_time; + request_time_tracker_->IncrementTotalBlockTime(request_id, block_time); + + bool credentials_set = false; + + deltas.sort(&helpers::InDecreasingExtensionInstallationTimeOrder); + std::set<std::string> conflicting_extensions; + helpers::EventLogEntries event_log_entries; + + bool canceled = false; + helpers::MergeCancelOfResponses( + blocked_request.response_deltas, + &canceled, + &event_log_entries); + + if (blocked_request.event == kOnBeforeRequest) { + CHECK(!blocked_request.callback.is_null()); + helpers::MergeOnBeforeRequestResponses( + blocked_request.response_deltas, + blocked_request.new_url, + &conflicting_extensions, + &event_log_entries); + } else if (blocked_request.event == kOnBeforeSendHeaders) { + CHECK(!blocked_request.callback.is_null()); + helpers::MergeOnBeforeSendHeadersResponses( + blocked_request.response_deltas, + blocked_request.request_headers, + &conflicting_extensions, + &event_log_entries); + } else if (blocked_request.event == kOnHeadersReceived) { + CHECK(!blocked_request.callback.is_null()); + helpers::MergeOnHeadersReceivedResponses( + blocked_request.response_deltas, + blocked_request.original_response_headers.get(), + blocked_request.override_response_headers, + &conflicting_extensions, + &event_log_entries); + } else if (blocked_request.event == kOnAuthRequired) { + CHECK(blocked_request.callback.is_null()); + CHECK(!blocked_request.auth_callback.is_null()); + credentials_set = helpers::MergeOnAuthRequiredResponses( + blocked_request.response_deltas, + blocked_request.auth_credentials, + &conflicting_extensions, + &event_log_entries); + } else { + NOTREACHED(); + } + + for (helpers::EventLogEntries::const_iterator i = + event_log_entries.begin(); + i != event_log_entries.end(); ++i) { + blocked_request.net_log->AddEvent(i->event_type, i->params); + } + if (!conflicting_extensions.empty()) { + BrowserThread::PostTask( + BrowserThread::UI, + FROM_HERE, + base::Bind(&ExtensionWarningSet::NotifyWarningsOnUI, + profile, + conflicting_extensions, + ExtensionWarningSet::kNetworkConflict)); + } + + if (canceled) { + request_time_tracker_->SetRequestCanceled(request_id); + } else if (blocked_request.new_url && + !blocked_request.new_url->is_empty()) { + request_time_tracker_->SetRequestRedirected(request_id); + } + + // This triggers onErrorOccurred if canceled is true. + int rv = canceled ? net::ERR_BLOCKED_BY_CLIENT : net::OK; + + if (!blocked_request.callback.is_null()) { + net::CompletionCallback callback = blocked_request.callback; + // Ensure that request is removed before callback because the callback + // might trigger the next event. + blocked_requests_.erase(request_id); + if (call_callback) + callback.Run(rv); + } else if (!blocked_request.auth_callback.is_null()) { + net::NetworkDelegate::AuthRequiredResponse response = + net::NetworkDelegate::AUTH_REQUIRED_RESPONSE_NO_ACTION; + if (canceled) { + response = net::NetworkDelegate::AUTH_REQUIRED_RESPONSE_CANCEL_AUTH; + } else if (credentials_set) { + response = net::NetworkDelegate::AUTH_REQUIRED_RESPONSE_SET_AUTH; + } + net::NetworkDelegate::AuthCallback callback = blocked_request.auth_callback; + blocked_requests_.erase(request_id); + if (call_callback) + callback.Run(response); + } else { + blocked_requests_.erase(request_id); + } + return rv; +} + +bool ExtensionWebRequestEventRouter::ProcessDeclarativeRules( + net::URLRequest* request, + extensions::RequestStages request_stage) { + if (!rules_registry_.get()) + return false; + + base::Time start = base::Time::Now(); + + std::list<linked_ptr<helpers::EventResponseDelta> > result = + rules_registry_->CreateDeltas(request, request_stage); + + base::TimeDelta elapsed_time = start - base::Time::Now(); + UMA_HISTOGRAM_TIMES("Extensions.DeclarativeWebRequestNetworkDelay", + elapsed_time); + + if (result.empty()) + return false; + + helpers::EventResponseDeltas& deltas = + blocked_requests_[request->identifier()].response_deltas; + CHECK(deltas.empty()); + deltas.swap(result); + return true; +} + bool ExtensionWebRequestEventRouter::GetAndSetSignaled(uint64 request_id, EventTypes event_type) { SignaledRequestMap::iterator iter = signaled_requests_.find(request_id); diff --git a/chrome/browser/extensions/api/web_request/web_request_api.h b/chrome/browser/extensions/api/web_request/web_request_api.h index 41e9333..8585426 100644 --- a/chrome/browser/extensions/api/web_request/web_request_api.h +++ b/chrome/browser/extensions/api/web_request/web_request_api.h @@ -14,6 +14,7 @@ #include "base/memory/singleton.h" #include "base/time.h" +#include "chrome/browser/extensions/api/declarative_webrequest/request_stages.h" #include "chrome/browser/extensions/api/web_request/web_request_api_helpers.h" #include "chrome/browser/extensions/extension_function.h" #include "chrome/browser/profiles/profile.h" @@ -38,6 +39,10 @@ namespace content { class RenderProcessHost; } +namespace extensions { +class WebRequestRulesRegistry; +} + namespace net { class AuthCredentials; class AuthChallengeInfo; @@ -126,6 +131,9 @@ class ExtensionWebRequestEventRouter { static ExtensionWebRequestEventRouter* GetInstance(); + void RegisterRulesRegistry( + scoped_refptr<extensions::WebRequestRulesRegistry> rules_registry); + // Dispatches the OnBeforeRequest event to any extensions whose filters match // the given request. Returns net::ERR_IO_PENDING if an extension is // intercepting the request, OK otherwise. @@ -311,6 +319,21 @@ class ExtensionWebRequestEventRouter { uint64 request_id, EventResponse* response); + // Processes the generated deltas from blocked_requests_ on the specified + // request. If |call_back| is true, the callback registered in + // |blocked_requests_| is called. + // The function returns the error code for the network request. This is + // mostly relevant in case the caller passes |call_callback| = false + // and wants to return the correct network error code himself. + int ExecuteDeltas(void* profile, uint64 request_id, bool call_callback); + + // Evaluates the rules of the declarative webrequest API and stores + // modifications to the request that result from WebRequestActions as + // deltas in |blocked_requests_|. Returns whether any deltas were + // generated. + bool ProcessDeclarativeRules(net::URLRequest* request, + extensions::RequestStages request_stage); + // Sets the flag that |event_type| has been signaled for |request_id|. // Returns the value of the flag before setting it. bool GetAndSetSignaled(uint64 request_id, EventTypes event_type); @@ -346,6 +369,8 @@ class ExtensionWebRequestEventRouter { CallbacksForPageLoad callbacks_for_page_load_; + scoped_refptr<extensions::WebRequestRulesRegistry> rules_registry_; + DISALLOW_COPY_AND_ASSIGN(ExtensionWebRequestEventRouter); }; diff --git a/chrome/browser/extensions/api/web_request/web_request_apitest.cc b/chrome/browser/extensions/api/web_request/web_request_apitest.cc index d75cc3c8..93809a5 100644 --- a/chrome/browser/extensions/api/web_request/web_request_apitest.cc +++ b/chrome/browser/extensions/api/web_request/web_request_apitest.cc @@ -52,6 +52,10 @@ class CancelLoginDialog : public content::NotificationObserver { class ExtensionWebRequestApiTest : public ExtensionApiTest { public: virtual void SetUpInProcessBrowserTestFixture() { + // TODO(battre): remove this when declarative webRequest API becomes stable. + CommandLine::ForCurrentProcess()->AppendSwitch( + switches::kEnableExperimentalExtensionApis); + ExtensionApiTest::SetUpInProcessBrowserTestFixture(); host_resolver()->AddRule("*", "127.0.0.1"); ASSERT_TRUE(StartTestServer()); @@ -115,3 +119,8 @@ IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest, WebRequestNewTab) { ASSERT_TRUE(catcher.GetNextResult()) << catcher.message(); } + +IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest, WebRequestDeclarative) { + ASSERT_TRUE(RunExtensionSubtest("webrequest", "test_declarative.html")) << + message_; +} diff --git a/chrome/browser/extensions/extension_service.cc b/chrome/browser/extensions/extension_service.cc index 766dcf7..4a27f8c 100644 --- a/chrome/browser/extensions/extension_service.cc +++ b/chrome/browser/extensions/extension_service.cc @@ -2644,11 +2644,3 @@ ExtensionService::api_resource_controller() { } return api_resource_controller_; } - -extensions::RulesRegistryService* ExtensionService::GetRulesRegistryService() { - if (!rules_registry_service_.get()) { - rules_registry_service_.reset( - new extensions::RulesRegistryService(profile_)); - } - return rules_registry_service_.get(); -} diff --git a/chrome/browser/extensions/extension_service.h b/chrome/browser/extensions/extension_service.h index e34298e..90a91cee 100644 --- a/chrome/browser/extensions/extension_service.h +++ b/chrome/browser/extensions/extension_service.h @@ -75,7 +75,6 @@ namespace extensions { class APIResourceController; class ComponentLoader; class ExtensionUpdater; -class RulesRegistryService; class SettingsFrontend; class WebNavigationEventRouter; } @@ -583,8 +582,6 @@ class ExtensionService // Call only from IO thread. extensions::APIResourceController* api_resource_controller(); - extensions::RulesRegistryService* GetRulesRegistryService(); - AppShortcutManager* app_shortcut_manager() { return &app_shortcut_manager_; } private: @@ -818,8 +815,6 @@ class ExtensionService input_method_event_router_; #endif - scoped_ptr<extensions::RulesRegistryService> rules_registry_service_; - // A collection of external extension providers. Each provider reads // a source of external extension information. Examples include the // windows registry and external_extensions.json. diff --git a/chrome/browser/extensions/extension_system.cc b/chrome/browser/extensions/extension_system.cc index c72ad64..663f042 100644 --- a/chrome/browser/extensions/extension_system.cc +++ b/chrome/browser/extensions/extension_system.cc @@ -11,6 +11,7 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/extensions/component_loader.h" #include "chrome/browser/content_settings/cookie_settings.h" +#include "chrome/browser/extensions/api/declarative/rules_registry_service.h" #include "chrome/browser/extensions/extension_devtools_manager.h" #include "chrome/browser/extensions/extension_error_reporter.h" #include "chrome/browser/extensions/extension_event_router.h" @@ -168,6 +169,9 @@ void ExtensionSystemImpl::Shared::Init(bool extensions_enabled) { extension_service_->InitEventRouters(); } } + + rules_registry_service_.reset(new extensions::RulesRegistryService(profile_)); + rules_registry_service_->RegisterDefaultRulesRegistries(); } ExtensionService* ExtensionSystemImpl::Shared::extension_service() { @@ -195,6 +199,11 @@ ExtensionEventRouter* ExtensionSystemImpl::Shared::event_router() { return extension_event_router_.get(); } +extensions::RulesRegistryService* +ExtensionSystemImpl::Shared::rules_registry_service() { + return rules_registry_service_.get(); +} + // // ExtensionSystemImpl // @@ -270,6 +279,11 @@ ExtensionEventRouter* ExtensionSystemImpl::event_router() { return shared_->event_router(); } +extensions::RulesRegistryService* +ExtensionSystemImpl::rules_registry_service() { + return shared_->rules_registry_service(); +} + void ExtensionSystemImpl::RegisterExtensionWithRequestContexts( const Extension* extension) { base::Time install_time; diff --git a/chrome/browser/extensions/extension_system.h b/chrome/browser/extensions/extension_system.h index bc1f52a..f93a62e 100644 --- a/chrome/browser/extensions/extension_system.h +++ b/chrome/browser/extensions/extension_system.h @@ -27,6 +27,10 @@ class LazyBackgroundTaskQueue; class Profile; class UserScriptMaster; +namespace extensions { +class RulesRegistryService; +} + // The ExtensionSystem manages the creation and destruction of services // related to extensions. Most objects are shared between normal // and incognito Profiles, except as called out in comments. @@ -73,6 +77,9 @@ class ExtensionSystem : public ProfileKeyedService { // The ExtensionEventRouter is created at startup. virtual ExtensionEventRouter* event_router() = 0; + // The RulesRegistryService is created at startup. + virtual extensions::RulesRegistryService* rules_registry_service() = 0; + // Called by the ExtensionService that lives in this system. Gives the // info map a chance to react to the load event before the EXTENSION_LOADED // notification has fired. The purpose for handling this event first is to @@ -113,6 +120,9 @@ class ExtensionSystemImpl : public ExtensionSystem { virtual ExtensionInfoMap* info_map() OVERRIDE; // shared virtual ExtensionMessageService* message_service() OVERRIDE; // shared virtual ExtensionEventRouter* event_router() OVERRIDE; // shared + // The RulesRegistryService is created at startup. + virtual extensions::RulesRegistryService* rules_registry_service() + OVERRIDE; // shared virtual void RegisterExtensionWithRequestContexts( const Extension* extension) OVERRIDE; @@ -142,6 +152,7 @@ class ExtensionSystemImpl : public ExtensionSystem { LazyBackgroundTaskQueue* lazy_background_task_queue(); ExtensionMessageService* message_service(); ExtensionEventRouter* event_router(); + extensions::RulesRegistryService* rules_registry_service(); private: Profile* profile_; @@ -160,6 +171,7 @@ class ExtensionSystemImpl : public ExtensionSystem { scoped_ptr<ExtensionMessageService> extension_message_service_; scoped_ptr<ExtensionEventRouter> extension_event_router_; scoped_ptr<ExtensionNavigationObserver> extension_navigation_observer_; + scoped_ptr<extensions::RulesRegistryService> rules_registry_service_; }; Profile* profile_; diff --git a/chrome/browser/extensions/test_extension_system.cc b/chrome/browser/extensions/test_extension_system.cc index 07e7522..a3436aa 100644 --- a/chrome/browser/extensions/test_extension_system.cc +++ b/chrome/browser/extensions/test_extension_system.cc @@ -97,6 +97,11 @@ ExtensionEventRouter* TestExtensionSystem::event_router() { return NULL; } +extensions::RulesRegistryService* +TestExtensionSystem::rules_registry_service() { + return NULL; +} + // static ProfileKeyedService* TestExtensionSystem::Build(Profile* profile) { return new TestExtensionSystem(profile); diff --git a/chrome/browser/extensions/test_extension_system.h b/chrome/browser/extensions/test_extension_system.h index c739c69..94cd663 100644 --- a/chrome/browser/extensions/test_extension_system.h +++ b/chrome/browser/extensions/test_extension_system.h @@ -40,6 +40,8 @@ class TestExtensionSystem : public ExtensionSystem { virtual LazyBackgroundTaskQueue* lazy_background_task_queue() OVERRIDE; virtual ExtensionMessageService* message_service() OVERRIDE; virtual ExtensionEventRouter* event_router() OVERRIDE; + virtual extensions::RulesRegistryService* rules_registry_service() + OVERRIDE; // Factory method for tests to use with SetTestingProfile. static ProfileKeyedService* Build(Profile* profile); |