1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef CHROME_BROWSER_EXTENSIONS_API_DECLARATIVE_CONTENT_CHROME_CONTENT_RULES_REGISTRY_H_
6 #define CHROME_BROWSER_EXTENSIONS_API_DECLARATIVE_CONTENT_CHROME_CONTENT_RULES_REGISTRY_H_
14 #include "base/callback.h"
15 #include "base/memory/linked_ptr.h"
16 #include "base/memory/scoped_ptr.h"
17 #include "base/memory/scoped_vector.h"
18 #include "chrome/browser/extensions/api/declarative_content/content_action.h"
19 #include "chrome/browser/extensions/api/declarative_content/content_condition.h"
20 #include "chrome/browser/extensions/api/declarative_content/content_predicate_evaluator.h"
21 #include "content/public/browser/notification_observer.h"
22 #include "content/public/browser/notification_registrar.h"
23 #include "extensions/browser/api/declarative_content/content_rules_registry.h"
24 #include "extensions/common/extension.h"
29 struct FrameNavigateParams
;
30 struct LoadCommittedDetails
;
33 namespace extensions
{
37 // The ChromeContentRulesRegistry is responsible for managing
38 // the internal representation of rules for the Declarative Content API.
40 // Here is the high level overview of this functionality:
42 // api::events::Rule consists of conditions and actions, these are
43 // represented as a ContentRule with ContentConditions and ContentActions.
45 // A note on incognito support: separate instances of ChromeContentRulesRegistry
46 // are created for incognito and non-incognito contexts. The incognito instance,
47 // however, is only responsible for applying rules registered by the incognito
48 // side of split-mode extensions to incognito tabs. The non-incognito instance
49 // handles incognito tabs for spanning-mode extensions, plus all non-incognito
51 class ChromeContentRulesRegistry
52 : public ContentRulesRegistry
,
53 public content::NotificationObserver
,
54 public ContentPredicateEvaluator::Delegate
{
56 using PredicateEvaluatorsFactory
=
57 base::Callback
<ScopedVector
<ContentPredicateEvaluator
>(
58 ContentPredicateEvaluator::Delegate
*)>;
60 // For testing, |cache_delegate| can be NULL. In that case it constructs the
61 // registry with storage functionality suspended.
62 ChromeContentRulesRegistry(
63 content::BrowserContext
* browser_context
,
64 RulesCacheDelegate
* cache_delegate
,
65 const PredicateEvaluatorsFactory
& evaluators_factory
);
67 // ContentRulesRegistry:
68 void MonitorWebContentsForRuleEvaluation(
69 content::WebContents
* contents
) override
;
70 void DidNavigateMainFrame(
71 content::WebContents
* tab
,
72 const content::LoadCommittedDetails
& details
,
73 const content::FrameNavigateParams
& params
) override
;
76 std::string
AddRulesImpl(
77 const std::string
& extension_id
,
78 const std::vector
<linked_ptr
<api::events::Rule
>>& rules
) override
;
79 std::string
RemoveRulesImpl(
80 const std::string
& extension_id
,
81 const std::vector
<std::string
>& rule_identifiers
) override
;
82 std::string
RemoveAllRulesImpl(const std::string
& extension_id
) override
;
84 // content::NotificationObserver:
85 void Observe(int type
,
86 const content::NotificationSource
& source
,
87 const content::NotificationDetails
& details
) override
;
89 // DeclarativeContentConditionTrackerDelegate:
90 void RequestEvaluation(content::WebContents
* contents
) override
;
91 bool ShouldManageConditionsForBrowserContext(
92 content::BrowserContext
* context
) override
;
94 // Returns the number of active rules.
95 size_t GetActiveRulesCountForTesting();
98 ~ChromeContentRulesRegistry() override
;
101 // The internal declarative rule representation. Corresponds to a declarative
102 // API rule: https://developer.chrome.com/extensions/events.html#declarative.
105 ContentRule(const Extension
* extension
,
106 ScopedVector
<const ContentCondition
> conditions
,
107 ScopedVector
<const ContentAction
> actions
,
111 const Extension
* extension
;
112 ScopedVector
<const ContentCondition
> conditions
;
113 ScopedVector
<const ContentAction
> actions
;
117 DISALLOW_COPY_AND_ASSIGN(ContentRule
);
120 // Specifies what to do with evaluation requests.
121 // TODO(wittman): Try to eliminate the need for IGNORE after refactoring to
122 // treat all condition evaluation consistently.
123 enum EvaluationDisposition
{
124 EVALUATE_REQUESTS
, // Evaluate immediately.
125 DEFER_REQUESTS
, // Defer for later evaluation.
126 IGNORE_REQUESTS
// Ignore.
129 class EvaluationScope
;
131 // Creates a ContentRule for |extension| given a json definition. The format
132 // of each condition and action's json is up to the specific ContentCondition
133 // and ContentAction. |extension| may be NULL in tests. If |error| is empty,
134 // the translation was successful and the returned rule is internally
136 scoped_ptr
<const ContentRule
> CreateRule(
137 const Extension
* extension
,
138 const std::map
<std::string
, ContentPredicateFactory
*>&
140 const api::events::Rule
& api_rule
,
143 // True if this object is managing the rules for |context|.
144 bool ManagingRulesForBrowserContext(content::BrowserContext
* context
);
146 // True if |condition| matches on |tab|.
147 static bool EvaluateConditionForTab(const ContentCondition
* condition
,
148 content::WebContents
* tab
);
150 std::set
<const ContentRule
*> GetMatchingRules(
151 content::WebContents
* tab
) const;
153 // Evaluates the conditions for |tab| based on the tab state and matching CSS
155 void EvaluateConditionsForTab(content::WebContents
* tab
);
157 // Returns true if a rule created by |extension| should be evaluated for an
158 // incognito renderer.
159 bool ShouldEvaluateExtensionRulesForIncognitoRenderer(
160 const Extension
* extension
) const;
162 using ExtensionIdRuleIdPair
= std::pair
<extensions::ExtensionId
, std::string
>;
163 using RulesMap
= std::map
<ExtensionIdRuleIdPair
,
164 linked_ptr
<const ContentRule
>>;
166 RulesMap content_rules_
;
168 // Maps a WebContents to the set of rules that match on that WebContents.
169 // This lets us call Revert as appropriate. Note that this is expected to have
170 // a key-value pair for every WebContents the registry is tracking, even if
171 // the value is the empty set.
172 std::map
<content::WebContents
*, std::set
<const ContentRule
*>> active_rules_
;
174 // The evaluators responsible for creating predicates and tracking
175 // predicate-related state.
176 ScopedVector
<ContentPredicateEvaluator
> evaluators_
;
178 // Specifies what to do with evaluation requests.
179 EvaluationDisposition evaluation_disposition_
;
181 // Contains WebContents which require rule evaluation. Only used while
182 // |evaluation_disposition_| is DEFER.
183 std::set
<content::WebContents
*> evaluation_pending_
;
185 // Manages our notification registrations.
186 content::NotificationRegistrar registrar_
;
188 DISALLOW_COPY_AND_ASSIGN(ChromeContentRulesRegistry
);
191 } // namespace extensions
193 #endif // CHROME_BROWSER_EXTENSIONS_API_DECLARATIVE_CONTENT_CHROME_CONTENT_RULES_REGISTRY_H_