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