| 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 |