OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/extensions/api/declarative_content/content_rules_regist
ry.h" | 5 #include "chrome/browser/extensions/api/declarative_content/content_rules_regist
ry.h" |
6 | 6 |
7 #include "chrome/browser/chrome_notification_types.h" | 7 #include "chrome/browser/chrome_notification_types.h" |
8 #include "chrome/browser/extensions/api/declarative_content/content_action.h" | 8 #include "chrome/browser/extensions/api/declarative_content/content_action.h" |
9 #include "chrome/browser/extensions/api/declarative_content/content_condition.h" | 9 #include "chrome/browser/extensions/api/declarative_content/content_condition.h" |
10 #include "chrome/browser/extensions/api/declarative_content/content_constants.h" | 10 #include "chrome/browser/extensions/api/declarative_content/content_constants.h" |
11 #include "chrome/browser/extensions/extension_tab_util.h" | 11 #include "chrome/browser/extensions/extension_tab_util.h" |
12 #include "chrome/browser/profiles/profile.h" | |
13 #include "content/public/browser/navigation_details.h" | 12 #include "content/public/browser/navigation_details.h" |
14 #include "content/public/browser/notification_service.h" | 13 #include "content/public/browser/notification_service.h" |
15 #include "content/public/browser/notification_source.h" | 14 #include "content/public/browser/notification_source.h" |
16 #include "content/public/browser/render_process_host.h" | 15 #include "content/public/browser/render_process_host.h" |
17 #include "content/public/browser/web_contents.h" | 16 #include "content/public/browser/web_contents.h" |
18 #include "extensions/browser/extension_registry.h" | 17 #include "extensions/browser/extension_registry.h" |
19 #include "extensions/browser/extension_system.h" | 18 #include "extensions/browser/extension_system.h" |
20 #include "extensions/common/extension_messages.h" | 19 #include "extensions/common/extension_messages.h" |
21 | 20 |
22 using url_matcher::URLMatcherConditionSet; | 21 using url_matcher::URLMatcherConditionSet; |
23 | 22 |
24 namespace extensions { | 23 namespace extensions { |
25 | 24 |
26 ContentRulesRegistry::ContentRulesRegistry(Profile* profile, | 25 ContentRulesRegistry::ContentRulesRegistry( |
27 RulesCacheDelegate* cache_delegate) | 26 content::BrowserContext* browser_context, |
28 : RulesRegistry(profile, | 27 RulesCacheDelegate* cache_delegate) |
| 28 : RulesRegistry(browser_context, |
29 declarative_content_constants::kOnPageChanged, | 29 declarative_content_constants::kOnPageChanged, |
30 content::BrowserThread::UI, | 30 content::BrowserThread::UI, |
31 cache_delegate, | 31 cache_delegate, |
32 WebViewKey(0, 0)) { | 32 WebViewKey(0, 0)) { |
33 extension_info_map_ = ExtensionSystem::Get(profile)->info_map(); | 33 extension_info_map_ = ExtensionSystem::Get(browser_context)->info_map(); |
34 | 34 |
35 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CREATED, | 35 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CREATED, |
36 content::NotificationService::AllBrowserContextsAndSources()); | 36 content::NotificationService::AllBrowserContextsAndSources()); |
37 registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED, | 37 registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED, |
38 content::NotificationService::AllBrowserContextsAndSources()); | 38 content::NotificationService::AllBrowserContextsAndSources()); |
39 } | 39 } |
40 | 40 |
41 void ContentRulesRegistry::Observe( | 41 void ContentRulesRegistry::Observe( |
42 int type, | 42 int type, |
43 const content::NotificationSource& source, | 43 const content::NotificationSource& source, |
44 const content::NotificationDetails& details) { | 44 const content::NotificationDetails& details) { |
45 switch (type) { | 45 switch (type) { |
46 case content::NOTIFICATION_RENDERER_PROCESS_CREATED: { | 46 case content::NOTIFICATION_RENDERER_PROCESS_CREATED: { |
47 content::RenderProcessHost* process = | 47 content::RenderProcessHost* process = |
48 content::Source<content::RenderProcessHost>(source).ptr(); | 48 content::Source<content::RenderProcessHost>(source).ptr(); |
49 if (process->GetBrowserContext() == profile()) | 49 if (process->GetBrowserContext() == browser_context()) |
50 InstructRenderProcess(process); | 50 InstructRenderProcess(process); |
51 break; | 51 break; |
52 } | 52 } |
53 case content::NOTIFICATION_WEB_CONTENTS_DESTROYED: { | 53 case content::NOTIFICATION_WEB_CONTENTS_DESTROYED: { |
54 content::WebContents* tab = | 54 content::WebContents* tab = |
55 content::Source<content::WebContents>(source).ptr(); | 55 content::Source<content::WebContents>(source).ptr(); |
56 // GetTabId() returns -1 for non-tab WebContents, which won't be | 56 // GetTabId() returns -1 for non-tab WebContents, which won't be |
57 // in the map. Similarly, tabs from other profiles won't be in | 57 // in the map. Similarly, tabs from other browser_contexts won't be in |
58 // the map. | 58 // the map. |
59 active_rules_.erase(ExtensionTabUtil::GetTabId(tab)); | 59 active_rules_.erase(ExtensionTabUtil::GetTabId(tab)); |
60 break; | 60 break; |
61 } | 61 } |
62 } | 62 } |
63 } | 63 } |
64 | 64 |
65 void ContentRulesRegistry::Apply( | 65 void ContentRulesRegistry::Apply( |
66 content::WebContents* contents, | 66 content::WebContents* contents, |
67 const std::vector<std::string>& matching_css_selectors) { | 67 const std::vector<std::string>& matching_css_selectors) { |
68 const int tab_id = ExtensionTabUtil::GetTabId(contents); | 68 const int tab_id = ExtensionTabUtil::GetTabId(contents); |
69 RendererContentMatchData renderer_data; | 69 RendererContentMatchData renderer_data; |
70 renderer_data.page_url_matches = url_matcher_.MatchURL(contents->GetURL()); | 70 renderer_data.page_url_matches = url_matcher_.MatchURL(contents->GetURL()); |
71 renderer_data.css_selectors.insert(matching_css_selectors.begin(), | 71 renderer_data.css_selectors.insert(matching_css_selectors.begin(), |
72 matching_css_selectors.end()); | 72 matching_css_selectors.end()); |
73 std::set<ContentRule*> matching_rules = GetMatches(renderer_data); | 73 std::set<ContentRule*> matching_rules = GetMatches(renderer_data); |
74 if (matching_rules.empty() && !ContainsKey(active_rules_, tab_id)) | 74 if (matching_rules.empty() && !ContainsKey(active_rules_, tab_id)) |
75 return; | 75 return; |
76 | 76 |
77 std::set<ContentRule*>& prev_matching_rules = active_rules_[tab_id]; | 77 std::set<ContentRule*>& prev_matching_rules = active_rules_[tab_id]; |
78 ContentAction::ApplyInfo apply_info = { | 78 ContentAction::ApplyInfo apply_info = { |
79 profile(), contents | 79 browser_context(), contents |
80 }; | 80 }; |
81 for (std::set<ContentRule*>::const_iterator it = matching_rules.begin(); | 81 for (std::set<ContentRule*>::const_iterator it = matching_rules.begin(); |
82 it != matching_rules.end(); ++it) { | 82 it != matching_rules.end(); ++it) { |
83 if (!ContainsKey(prev_matching_rules, *it)) { | 83 if (!ContainsKey(prev_matching_rules, *it)) { |
84 (*it)->actions().Apply((*it)->extension_id(), base::Time(), &apply_info); | 84 (*it)->actions().Apply((*it)->extension_id(), base::Time(), &apply_info); |
85 } else { | 85 } else { |
86 (*it)->actions().Reapply( | 86 (*it)->actions().Reapply( |
87 (*it)->extension_id(), base::Time(), &apply_info); | 87 (*it)->extension_id(), base::Time(), &apply_info); |
88 } | 88 } |
89 } | 89 } |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
136 if (rule->conditions().IsFulfilled(*url_match, renderer_data)) | 136 if (rule->conditions().IsFulfilled(*url_match, renderer_data)) |
137 result.insert(rule); | 137 result.insert(rule); |
138 } | 138 } |
139 return result; | 139 return result; |
140 } | 140 } |
141 | 141 |
142 std::string ContentRulesRegistry::AddRulesImpl( | 142 std::string ContentRulesRegistry::AddRulesImpl( |
143 const std::string& extension_id, | 143 const std::string& extension_id, |
144 const std::vector<linked_ptr<RulesRegistry::Rule> >& rules) { | 144 const std::vector<linked_ptr<RulesRegistry::Rule> >& rules) { |
145 const Extension* extension = | 145 const Extension* extension = |
146 ExtensionRegistry::Get(profile()) | 146 ExtensionRegistry::Get(browser_context()) |
147 ->GetExtensionById(extension_id, ExtensionRegistry::EVERYTHING); | 147 ->GetExtensionById(extension_id, ExtensionRegistry::EVERYTHING); |
148 DCHECK(extension) << "Must have extension with id " << extension_id; | 148 DCHECK(extension) << "Must have extension with id " << extension_id; |
149 | 149 |
150 base::Time extension_installation_time = | 150 base::Time extension_installation_time = |
151 GetExtensionInstallationTime(extension_id); | 151 GetExtensionInstallationTime(extension_id); |
152 | 152 |
153 std::string error; | 153 std::string error; |
154 RulesMap new_content_rules; | 154 RulesMap new_content_rules; |
155 | 155 |
156 for (std::vector<linked_ptr<RulesRegistry::Rule> >::const_iterator rule = | 156 for (std::vector<linked_ptr<RulesRegistry::Rule> >::const_iterator rule = |
157 rules.begin(); rule != rules.end(); ++rule) { | 157 rules.begin(); rule != rules.end(); ++rule) { |
158 ContentRule::GlobalRuleId rule_id(extension_id, *(*rule)->id); | 158 ContentRule::GlobalRuleId rule_id(extension_id, *(*rule)->id); |
159 DCHECK(content_rules_.find(rule_id) == content_rules_.end()); | 159 DCHECK(content_rules_.find(rule_id) == content_rules_.end()); |
160 | 160 |
161 scoped_ptr<ContentRule> content_rule( | 161 scoped_ptr<ContentRule> content_rule( |
162 ContentRule::Create(url_matcher_.condition_factory(), | 162 ContentRule::Create(url_matcher_.condition_factory(), |
163 profile(), | 163 browser_context(), |
164 extension, | 164 extension, |
165 extension_installation_time, | 165 extension_installation_time, |
166 *rule, | 166 *rule, |
167 ContentRule::ConsistencyChecker(), | 167 ContentRule::ConsistencyChecker(), |
168 &error)); | 168 &error)); |
169 if (!error.empty()) { | 169 if (!error.empty()) { |
170 // Clean up temporary condition sets created during rule creation. | 170 // Clean up temporary condition sets created during rule creation. |
171 url_matcher_.ClearUnusedConditionSets(); | 171 url_matcher_.ClearUnusedConditionSets(); |
172 return error; | 172 return error; |
173 } | 173 } |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
229 match_id_to_rule_.erase((*j)->id()); | 229 match_id_to_rule_.erase((*j)->id()); |
230 } | 230 } |
231 | 231 |
232 // Remove the ContentRule from active_rules_. | 232 // Remove the ContentRule from active_rules_. |
233 for (std::map<int, std::set<ContentRule*> >::iterator | 233 for (std::map<int, std::set<ContentRule*> >::iterator |
234 it = active_rules_.begin(); | 234 it = active_rules_.begin(); |
235 it != active_rules_.end(); ++it) { | 235 it != active_rules_.end(); ++it) { |
236 if (ContainsKey(it->second, rule)) { | 236 if (ContainsKey(it->second, rule)) { |
237 content::WebContents* tab; | 237 content::WebContents* tab; |
238 if (!ExtensionTabUtil::GetTabById( | 238 if (!ExtensionTabUtil::GetTabById( |
239 it->first, profile(), true, NULL, NULL, &tab, NULL)) { | 239 it->first, browser_context(), true, NULL, NULL, &tab, NULL)) { |
240 LOG(DFATAL) << "Tab id " << it->first | 240 LOG(DFATAL) << "Tab id " << it->first |
241 << " still in active_rules_, but tab has been destroyed"; | 241 << " still in active_rules_, but tab has been destroyed"; |
242 continue; | 242 continue; |
243 } | 243 } |
244 ContentAction::ApplyInfo apply_info = {profile(), tab}; | 244 ContentAction::ApplyInfo apply_info = {browser_context(), tab}; |
245 rule->actions().Revert(rule->extension_id(), base::Time(), &apply_info); | 245 rule->actions().Revert(rule->extension_id(), base::Time(), &apply_info); |
246 it->second.erase(rule); | 246 it->second.erase(rule); |
247 } | 247 } |
248 } | 248 } |
249 | 249 |
250 // Remove reference to actual rule. | 250 // Remove reference to actual rule. |
251 content_rules_.erase(content_rules_entry); | 251 content_rules_.erase(content_rules_entry); |
252 } | 252 } |
253 | 253 |
254 // Clear URLMatcher based on condition_set_ids that are not needed any more. | 254 // Clear URLMatcher based on condition_set_ids that are not needed any more. |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
290 | 290 |
291 if (css_selectors.size() != watched_css_selectors_.size() || | 291 if (css_selectors.size() != watched_css_selectors_.size() || |
292 !std::equal(css_selectors.begin(), css_selectors.end(), | 292 !std::equal(css_selectors.begin(), css_selectors.end(), |
293 watched_css_selectors_.begin())) { | 293 watched_css_selectors_.begin())) { |
294 watched_css_selectors_.assign(css_selectors.begin(), css_selectors.end()); | 294 watched_css_selectors_.assign(css_selectors.begin(), css_selectors.end()); |
295 | 295 |
296 for (content::RenderProcessHost::iterator it( | 296 for (content::RenderProcessHost::iterator it( |
297 content::RenderProcessHost::AllHostsIterator()); | 297 content::RenderProcessHost::AllHostsIterator()); |
298 !it.IsAtEnd(); it.Advance()) { | 298 !it.IsAtEnd(); it.Advance()) { |
299 content::RenderProcessHost* process = it.GetCurrentValue(); | 299 content::RenderProcessHost* process = it.GetCurrentValue(); |
300 if (process->GetBrowserContext() == profile()) | 300 if (process->GetBrowserContext() == browser_context()) |
301 InstructRenderProcess(process); | 301 InstructRenderProcess(process); |
302 } | 302 } |
303 } | 303 } |
304 } | 304 } |
305 | 305 |
306 void ContentRulesRegistry::InstructRenderProcess( | 306 void ContentRulesRegistry::InstructRenderProcess( |
307 content::RenderProcessHost* process) { | 307 content::RenderProcessHost* process) { |
308 process->Send(new ExtensionMsg_WatchPages(watched_css_selectors_)); | 308 process->Send(new ExtensionMsg_WatchPages(watched_css_selectors_)); |
309 } | 309 } |
310 | 310 |
311 bool ContentRulesRegistry::IsEmpty() const { | 311 bool ContentRulesRegistry::IsEmpty() const { |
312 return match_id_to_rule_.empty() && content_rules_.empty() && | 312 return match_id_to_rule_.empty() && content_rules_.empty() && |
313 url_matcher_.IsEmpty(); | 313 url_matcher_.IsEmpty(); |
314 } | 314 } |
315 | 315 |
316 ContentRulesRegistry::~ContentRulesRegistry() {} | 316 ContentRulesRegistry::~ContentRulesRegistry() {} |
317 | 317 |
318 base::Time ContentRulesRegistry::GetExtensionInstallationTime( | 318 base::Time ContentRulesRegistry::GetExtensionInstallationTime( |
319 const std::string& extension_id) const { | 319 const std::string& extension_id) const { |
320 if (!extension_info_map_.get()) // May be NULL during testing. | 320 if (!extension_info_map_.get()) // May be NULL during testing. |
321 return base::Time(); | 321 return base::Time(); |
322 | 322 |
323 return extension_info_map_->GetInstallTime(extension_id); | 323 return extension_info_map_->GetInstallTime(extension_id); |
324 } | 324 } |
325 | 325 |
326 } // namespace extensions | 326 } // namespace extensions |
OLD | NEW |