Elim cr-checkbox
[chromium-blink-merge.git] / chrome / browser / extensions / api / declarative_content / chrome_content_rules_registry.h
blob494715e4bea664cd1096ab6a51c4e3afe88763db
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_
8 #include <map>
9 #include <set>
10 #include <string>
11 #include <utility>
12 #include <vector>
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"
26 namespace content {
27 class BrowserContext;
28 class WebContents;
29 struct FrameNavigateParams;
30 struct LoadCommittedDetails;
33 namespace extensions {
35 class Extension;
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
50 // tabs.
51 class ChromeContentRulesRegistry
52 : public ContentRulesRegistry,
53 public content::NotificationObserver,
54 public ContentPredicateEvaluator::Delegate {
55 public:
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;
75 // RulesRegistry:
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();
97 protected:
98 ~ChromeContentRulesRegistry() override;
100 private:
101 // The internal declarative rule representation. Corresponds to a declarative
102 // API rule: https://developer.chrome.com/extensions/events.html#declarative.
103 struct ContentRule {
104 public:
105 ContentRule(const Extension* extension,
106 ScopedVector<const ContentCondition> conditions,
107 ScopedVector<const ContentAction> actions,
108 int priority);
109 ~ContentRule();
111 const Extension* extension;
112 ScopedVector<const ContentCondition> conditions;
113 ScopedVector<const ContentAction> actions;
114 int priority;
116 private:
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
135 // consistent.
136 scoped_ptr<const ContentRule> CreateRule(
137 const Extension* extension,
138 const std::map<std::string, ContentPredicateFactory*>&
139 predicate_factories,
140 const api::events::Rule& api_rule,
141 std::string* error);
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
154 // selectors.
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_