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_service.h" | 11 #include "chrome/browser/extensions/extension_service.h" |
12 #include "chrome/browser/extensions/extension_system.h" | 12 #include "chrome/browser/extensions/extension_system.h" |
13 #include "chrome/browser/extensions/extension_tab_util.h" | 13 #include "chrome/browser/extensions/extension_tab_util.h" |
14 #include "chrome/browser/profiles/profile.h" | 14 #include "chrome/browser/profiles/profile.h" |
15 #include "chrome/common/extensions/extension_messages.h" | 15 #include "chrome/common/extensions/extension_messages.h" |
16 #include "content/public/browser/navigation_details.h" | 16 #include "content/public/browser/navigation_details.h" |
17 #include "content/public/browser/notification_service.h" | 17 #include "content/public/browser/notification_service.h" |
18 #include "content/public/browser/notification_source.h" | 18 #include "content/public/browser/notification_source.h" |
19 #include "content/public/browser/render_process_host.h" | 19 #include "content/public/browser/render_process_host.h" |
20 #include "content/public/browser/web_contents.h" | 20 #include "content/public/browser/web_contents.h" |
21 | 21 |
22 namespace extensions { | 22 namespace extensions { |
23 | 23 |
24 ContentRulesRegistry::ContentRulesRegistry( | 24 ContentRulesRegistry::ContentRulesRegistry(Profile* profile, |
25 Profile* profile, | 25 RulesCacheDelegate* cache_delegate) |
26 scoped_ptr<RulesCacheDelegate>* cache_delegate) | 26 : RulesRegistry(profile, |
27 : RulesRegistry((cache_delegate ? profile : NULL), | |
28 declarative_content_constants::kOnPageChanged, | 27 declarative_content_constants::kOnPageChanged, |
29 content::BrowserThread::UI, | 28 content::BrowserThread::UI, |
30 false /*log_storage_init_delay*/, | 29 cache_delegate) { |
31 cache_delegate), | |
32 profile_(profile) { | |
33 extension_info_map_ = ExtensionSystem::Get(profile)->info_map(); | 30 extension_info_map_ = ExtensionSystem::Get(profile)->info_map(); |
34 | 31 |
35 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CREATED, | 32 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CREATED, |
36 content::NotificationService::AllBrowserContextsAndSources()); | 33 content::NotificationService::AllBrowserContextsAndSources()); |
37 registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED, | 34 registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED, |
38 content::NotificationService::AllBrowserContextsAndSources()); | 35 content::NotificationService::AllBrowserContextsAndSources()); |
39 } | 36 } |
40 | 37 |
41 void ContentRulesRegistry::Observe( | 38 void ContentRulesRegistry::Observe( |
42 int type, | 39 int type, |
43 const content::NotificationSource& source, | 40 const content::NotificationSource& source, |
44 const content::NotificationDetails& details) { | 41 const content::NotificationDetails& details) { |
45 switch (type) { | 42 switch (type) { |
46 case content::NOTIFICATION_RENDERER_PROCESS_CREATED: { | 43 case content::NOTIFICATION_RENDERER_PROCESS_CREATED: { |
47 content::RenderProcessHost* process = | 44 content::RenderProcessHost* process = |
48 content::Source<content::RenderProcessHost>(source).ptr(); | 45 content::Source<content::RenderProcessHost>(source).ptr(); |
49 if (process->GetBrowserContext() == profile_) | 46 if (process->GetBrowserContext() == profile()) |
50 InstructRenderProcess(process); | 47 InstructRenderProcess(process); |
51 break; | 48 break; |
52 } | 49 } |
53 case content::NOTIFICATION_WEB_CONTENTS_DESTROYED: { | 50 case content::NOTIFICATION_WEB_CONTENTS_DESTROYED: { |
54 content::WebContents* tab = | 51 content::WebContents* tab = |
55 content::Source<content::WebContents>(source).ptr(); | 52 content::Source<content::WebContents>(source).ptr(); |
56 // GetTabId() returns -1 for non-tab WebContents, which won't be | 53 // GetTabId() returns -1 for non-tab WebContents, which won't be |
57 // in the map. Similarly, tabs from other profiles won't be in | 54 // in the map. Similarly, tabs from other profiles won't be in |
58 // the map. | 55 // the map. |
59 active_rules_.erase(ExtensionTabUtil::GetTabId(tab)); | 56 active_rules_.erase(ExtensionTabUtil::GetTabId(tab)); |
60 break; | 57 break; |
61 } | 58 } |
62 } | 59 } |
63 } | 60 } |
64 | 61 |
65 void ContentRulesRegistry::Apply( | 62 void ContentRulesRegistry::Apply( |
66 content::WebContents* contents, | 63 content::WebContents* contents, |
67 const std::vector<std::string>& matching_css_selectors) { | 64 const std::vector<std::string>& matching_css_selectors) { |
68 const int tab_id = ExtensionTabUtil::GetTabId(contents); | 65 const int tab_id = ExtensionTabUtil::GetTabId(contents); |
69 RendererContentMatchData renderer_data; | 66 RendererContentMatchData renderer_data; |
70 renderer_data.page_url_matches = url_matcher_.MatchURL(contents->GetURL()); | 67 renderer_data.page_url_matches = url_matcher_.MatchURL(contents->GetURL()); |
71 renderer_data.css_selectors.insert(matching_css_selectors.begin(), | 68 renderer_data.css_selectors.insert(matching_css_selectors.begin(), |
72 matching_css_selectors.end()); | 69 matching_css_selectors.end()); |
73 std::set<ContentRule*> matching_rules = GetMatches(renderer_data); | 70 std::set<ContentRule*> matching_rules = GetMatches(renderer_data); |
74 if (matching_rules.empty() && !ContainsKey(active_rules_, tab_id)) | 71 if (matching_rules.empty() && !ContainsKey(active_rules_, tab_id)) |
75 return; | 72 return; |
76 | 73 |
77 std::set<ContentRule*>& prev_matching_rules = active_rules_[tab_id]; | 74 std::set<ContentRule*>& prev_matching_rules = active_rules_[tab_id]; |
78 ContentAction::ApplyInfo apply_info = { | 75 ContentAction::ApplyInfo apply_info = { |
79 profile_, contents | 76 profile(), contents |
80 }; | 77 }; |
81 for (std::set<ContentRule*>::const_iterator it = matching_rules.begin(); | 78 for (std::set<ContentRule*>::const_iterator it = matching_rules.begin(); |
82 it != matching_rules.end(); ++it) { | 79 it != matching_rules.end(); ++it) { |
83 if (!ContainsKey(prev_matching_rules, *it)) | 80 if (!ContainsKey(prev_matching_rules, *it)) |
84 (*it)->actions().Apply((*it)->extension_id(), base::Time(), &apply_info); | 81 (*it)->actions().Apply((*it)->extension_id(), base::Time(), &apply_info); |
85 } | 82 } |
86 for (std::set<ContentRule*>::const_iterator it = prev_matching_rules.begin(); | 83 for (std::set<ContentRule*>::const_iterator it = prev_matching_rules.begin(); |
87 it != prev_matching_rules.end(); ++it) { | 84 it != prev_matching_rules.end(); ++it) { |
88 if (!ContainsKey(matching_rules, *it)) | 85 if (!ContainsKey(matching_rules, *it)) |
89 (*it)->actions().Revert((*it)->extension_id(), base::Time(), &apply_info); | 86 (*it)->actions().Revert((*it)->extension_id(), base::Time(), &apply_info); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
132 if (rule->conditions().IsFulfilled(*url_match, renderer_data)) | 129 if (rule->conditions().IsFulfilled(*url_match, renderer_data)) |
133 result.insert(rule); | 130 result.insert(rule); |
134 } | 131 } |
135 return result; | 132 return result; |
136 } | 133 } |
137 | 134 |
138 std::string ContentRulesRegistry::AddRulesImpl( | 135 std::string ContentRulesRegistry::AddRulesImpl( |
139 const std::string& extension_id, | 136 const std::string& extension_id, |
140 const std::vector<linked_ptr<RulesRegistry::Rule> >& rules) { | 137 const std::vector<linked_ptr<RulesRegistry::Rule> >& rules) { |
141 ExtensionService* service = | 138 ExtensionService* service = |
142 ExtensionSystem::Get(profile_)->extension_service(); | 139 ExtensionSystem::Get(profile())->extension_service(); |
143 const Extension* extension = service->GetInstalledExtension(extension_id); | 140 const Extension* extension = service->GetInstalledExtension(extension_id); |
144 DCHECK(extension) << "Must have extension with id " << extension_id; | 141 DCHECK(extension) << "Must have extension with id " << extension_id; |
145 | 142 |
146 base::Time extension_installation_time = | 143 base::Time extension_installation_time = |
147 GetExtensionInstallationTime(extension_id); | 144 GetExtensionInstallationTime(extension_id); |
148 | 145 |
149 std::string error; | 146 std::string error; |
150 RulesMap new_content_rules; | 147 RulesMap new_content_rules; |
151 | 148 |
152 for (std::vector<linked_ptr<RulesRegistry::Rule> >::const_iterator rule = | 149 for (std::vector<linked_ptr<RulesRegistry::Rule> >::const_iterator rule = |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
224 match_id_to_rule_.erase((*j)->id()); | 221 match_id_to_rule_.erase((*j)->id()); |
225 } | 222 } |
226 | 223 |
227 // Remove the ContentRule from active_rules_. | 224 // Remove the ContentRule from active_rules_. |
228 for (std::map<int, std::set<ContentRule*> >::iterator | 225 for (std::map<int, std::set<ContentRule*> >::iterator |
229 it = active_rules_.begin(); | 226 it = active_rules_.begin(); |
230 it != active_rules_.end(); ++it) { | 227 it != active_rules_.end(); ++it) { |
231 if (ContainsKey(it->second, rule)) { | 228 if (ContainsKey(it->second, rule)) { |
232 content::WebContents* tab; | 229 content::WebContents* tab; |
233 if (!ExtensionTabUtil::GetTabById( | 230 if (!ExtensionTabUtil::GetTabById( |
234 it->first, profile_, true, NULL, NULL, &tab, NULL)) { | 231 it->first, profile(), true, NULL, NULL, &tab, NULL)) { |
235 LOG(DFATAL) << "Tab id " << it->first | 232 LOG(DFATAL) << "Tab id " << it->first |
236 << " still in active_rules_, but tab has been destroyed"; | 233 << " still in active_rules_, but tab has been destroyed"; |
237 continue; | 234 continue; |
238 } | 235 } |
239 ContentAction::ApplyInfo apply_info = {profile_, tab}; | 236 ContentAction::ApplyInfo apply_info = {profile(), tab}; |
240 rule->actions().Revert(rule->extension_id(), base::Time(), &apply_info); | 237 rule->actions().Revert(rule->extension_id(), base::Time(), &apply_info); |
241 it->second.erase(rule); | 238 it->second.erase(rule); |
242 } | 239 } |
243 } | 240 } |
244 | 241 |
245 // Remove reference to actual rule. | 242 // Remove reference to actual rule. |
246 content_rules_.erase(content_rules_entry); | 243 content_rules_.erase(content_rules_entry); |
247 } | 244 } |
248 | 245 |
249 // Clear URLMatcher based on condition_set_ids that are not needed any more. | 246 // 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... |
285 | 282 |
286 if (css_selectors.size() != watched_css_selectors_.size() || | 283 if (css_selectors.size() != watched_css_selectors_.size() || |
287 !std::equal(css_selectors.begin(), css_selectors.end(), | 284 !std::equal(css_selectors.begin(), css_selectors.end(), |
288 watched_css_selectors_.begin())) { | 285 watched_css_selectors_.begin())) { |
289 watched_css_selectors_.assign(css_selectors.begin(), css_selectors.end()); | 286 watched_css_selectors_.assign(css_selectors.begin(), css_selectors.end()); |
290 | 287 |
291 for (content::RenderProcessHost::iterator it( | 288 for (content::RenderProcessHost::iterator it( |
292 content::RenderProcessHost::AllHostsIterator()); | 289 content::RenderProcessHost::AllHostsIterator()); |
293 !it.IsAtEnd(); it.Advance()) { | 290 !it.IsAtEnd(); it.Advance()) { |
294 content::RenderProcessHost* process = it.GetCurrentValue(); | 291 content::RenderProcessHost* process = it.GetCurrentValue(); |
295 if (process->GetBrowserContext() == profile_) | 292 if (process->GetBrowserContext() == profile()) |
296 InstructRenderProcess(process); | 293 InstructRenderProcess(process); |
297 } | 294 } |
298 } | 295 } |
299 } | 296 } |
300 | 297 |
301 void ContentRulesRegistry::InstructRenderProcess( | 298 void ContentRulesRegistry::InstructRenderProcess( |
302 content::RenderProcessHost* process) { | 299 content::RenderProcessHost* process) { |
303 process->Send(new ExtensionMsg_WatchPages(watched_css_selectors_)); | 300 process->Send(new ExtensionMsg_WatchPages(watched_css_selectors_)); |
304 } | 301 } |
305 | 302 |
306 bool ContentRulesRegistry::IsEmpty() const { | 303 bool ContentRulesRegistry::IsEmpty() const { |
307 return match_id_to_rule_.empty() && content_rules_.empty() && | 304 return match_id_to_rule_.empty() && content_rules_.empty() && |
308 url_matcher_.IsEmpty(); | 305 url_matcher_.IsEmpty(); |
309 } | 306 } |
310 | 307 |
311 ContentRulesRegistry::~ContentRulesRegistry() {} | 308 ContentRulesRegistry::~ContentRulesRegistry() {} |
312 | 309 |
313 base::Time ContentRulesRegistry::GetExtensionInstallationTime( | 310 base::Time ContentRulesRegistry::GetExtensionInstallationTime( |
314 const std::string& extension_id) const { | 311 const std::string& extension_id) const { |
315 if (!extension_info_map_.get()) // May be NULL during testing. | 312 if (!extension_info_map_.get()) // May be NULL during testing. |
316 return base::Time(); | 313 return base::Time(); |
317 | 314 |
318 return extension_info_map_->GetInstallTime(extension_id); | 315 return extension_info_map_->GetInstallTime(extension_id); |
319 } | 316 } |
320 | 317 |
321 } // namespace extensions | 318 } // namespace extensions |
OLD | NEW |