| 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/chrome_content_rules
_registry.h" | 5 #include "chrome/browser/extensions/api/declarative_content/chrome_content_rules
_registry.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/macros.h" | 8 #include "base/macros.h" |
| 9 #include "base/memory/ptr_util.h" |
| 9 #include "chrome/browser/chrome_notification_types.h" | 10 #include "chrome/browser/chrome_notification_types.h" |
| 10 #include "chrome/browser/extensions/api/declarative_content/content_constants.h" | 11 #include "chrome/browser/extensions/api/declarative_content/content_constants.h" |
| 11 #include "chrome/browser/extensions/extension_util.h" | 12 #include "chrome/browser/extensions/extension_util.h" |
| 12 #include "chrome/browser/profiles/profile.h" | 13 #include "chrome/browser/profiles/profile.h" |
| 13 #include "chrome/browser/ui/browser.h" | 14 #include "chrome/browser/ui/browser.h" |
| 14 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 15 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
| 15 #include "content/public/browser/navigation_details.h" | 16 #include "content/public/browser/navigation_details.h" |
| 16 #include "content/public/browser/notification_service.h" | 17 #include "content/public/browser/notification_service.h" |
| 17 #include "content/public/browser/notification_source.h" | 18 #include "content/public/browser/notification_source.h" |
| 18 #include "content/public/browser/web_contents.h" | 19 #include "content/public/browser/web_contents.h" |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 123 return ManagingRulesForBrowserContext(context); | 124 return ManagingRulesForBrowserContext(context); |
| 124 } | 125 } |
| 125 | 126 |
| 126 void ChromeContentRulesRegistry::MonitorWebContentsForRuleEvaluation( | 127 void ChromeContentRulesRegistry::MonitorWebContentsForRuleEvaluation( |
| 127 content::WebContents* contents) { | 128 content::WebContents* contents) { |
| 128 // We rely on active_rules_ to have a key-value pair for |contents| to know | 129 // We rely on active_rules_ to have a key-value pair for |contents| to know |
| 129 // which WebContents we are working with. | 130 // which WebContents we are working with. |
| 130 active_rules_[contents] = std::set<const ContentRule*>(); | 131 active_rules_[contents] = std::set<const ContentRule*>(); |
| 131 | 132 |
| 132 EvaluationScope evaluation_scope(this); | 133 EvaluationScope evaluation_scope(this); |
| 133 for (const scoped_ptr<ContentPredicateEvaluator>& evaluator : evaluators_) | 134 for (const std::unique_ptr<ContentPredicateEvaluator>& evaluator : |
| 135 evaluators_) |
| 134 evaluator->TrackForWebContents(contents); | 136 evaluator->TrackForWebContents(contents); |
| 135 } | 137 } |
| 136 | 138 |
| 137 void ChromeContentRulesRegistry::DidNavigateMainFrame( | 139 void ChromeContentRulesRegistry::DidNavigateMainFrame( |
| 138 content::WebContents* contents, | 140 content::WebContents* contents, |
| 139 const content::LoadCommittedDetails& details, | 141 const content::LoadCommittedDetails& details, |
| 140 const content::FrameNavigateParams& params) { | 142 const content::FrameNavigateParams& params) { |
| 141 if (ContainsKey(active_rules_, contents)) { | 143 if (ContainsKey(active_rules_, contents)) { |
| 142 EvaluationScope evaluation_scope(this); | 144 EvaluationScope evaluation_scope(this); |
| 143 for (const scoped_ptr<ContentPredicateEvaluator>& evaluator : evaluators_) | 145 for (const std::unique_ptr<ContentPredicateEvaluator>& evaluator : |
| 146 evaluators_) |
| 144 evaluator->OnWebContentsNavigation(contents, details, params); | 147 evaluator->OnWebContentsNavigation(contents, details, params); |
| 145 } | 148 } |
| 146 } | 149 } |
| 147 | 150 |
| 148 ChromeContentRulesRegistry::ContentRule::ContentRule( | 151 ChromeContentRulesRegistry::ContentRule::ContentRule( |
| 149 const Extension* extension, | 152 const Extension* extension, |
| 150 std::vector<scoped_ptr<const ContentCondition>> conditions, | 153 std::vector<std::unique_ptr<const ContentCondition>> conditions, |
| 151 std::vector<scoped_ptr<const ContentAction>> actions, | 154 std::vector<std::unique_ptr<const ContentAction>> actions, |
| 152 int priority) | 155 int priority) |
| 153 : extension(extension), | 156 : extension(extension), |
| 154 conditions(std::move(conditions)), | 157 conditions(std::move(conditions)), |
| 155 actions(std::move(actions)), | 158 actions(std::move(actions)), |
| 156 priority(priority) {} | 159 priority(priority) {} |
| 157 | 160 |
| 158 ChromeContentRulesRegistry::ContentRule::~ContentRule() {} | 161 ChromeContentRulesRegistry::ContentRule::~ContentRule() {} |
| 159 | 162 |
| 160 scoped_ptr<const ChromeContentRulesRegistry::ContentRule> | 163 std::unique_ptr<const ChromeContentRulesRegistry::ContentRule> |
| 161 ChromeContentRulesRegistry::CreateRule( | 164 ChromeContentRulesRegistry::CreateRule( |
| 162 const Extension* extension, | 165 const Extension* extension, |
| 163 const std::map<std::string, ContentPredicateFactory*>& predicate_factories, | 166 const std::map<std::string, ContentPredicateFactory*>& predicate_factories, |
| 164 const api::events::Rule& api_rule, | 167 const api::events::Rule& api_rule, |
| 165 std::string* error) { | 168 std::string* error) { |
| 166 std::vector<scoped_ptr<const ContentCondition>> conditions; | 169 std::vector<std::unique_ptr<const ContentCondition>> conditions; |
| 167 for (const scoped_ptr<base::Value>& value : api_rule.conditions) { | 170 for (const std::unique_ptr<base::Value>& value : api_rule.conditions) { |
| 168 conditions.push_back( | 171 conditions.push_back( |
| 169 CreateContentCondition(extension, predicate_factories, *value, error)); | 172 CreateContentCondition(extension, predicate_factories, *value, error)); |
| 170 if (!error->empty()) | 173 if (!error->empty()) |
| 171 return scoped_ptr<ContentRule>(); | 174 return std::unique_ptr<ContentRule>(); |
| 172 } | 175 } |
| 173 | 176 |
| 174 std::vector<scoped_ptr<const ContentAction>> actions; | 177 std::vector<std::unique_ptr<const ContentAction>> actions; |
| 175 for (const scoped_ptr<base::Value>& value : api_rule.actions) { | 178 for (const std::unique_ptr<base::Value>& value : api_rule.actions) { |
| 176 actions.push_back(ContentAction::Create(browser_context(), extension, | 179 actions.push_back(ContentAction::Create(browser_context(), extension, |
| 177 *value, error)); | 180 *value, error)); |
| 178 if (!error->empty()) | 181 if (!error->empty()) |
| 179 return scoped_ptr<ContentRule>(); | 182 return std::unique_ptr<ContentRule>(); |
| 180 } | 183 } |
| 181 | 184 |
| 182 // Note: |api_rule| may contain tags, but these are ignored. | 185 // Note: |api_rule| may contain tags, but these are ignored. |
| 183 | 186 |
| 184 return make_scoped_ptr(new ContentRule(extension, std::move(conditions), | 187 return base::WrapUnique(new ContentRule(extension, std::move(conditions), |
| 185 std::move(actions), | 188 std::move(actions), |
| 186 *api_rule.priority)); | 189 *api_rule.priority)); |
| 187 } | 190 } |
| 188 | 191 |
| 189 bool ChromeContentRulesRegistry::ManagingRulesForBrowserContext( | 192 bool ChromeContentRulesRegistry::ManagingRulesForBrowserContext( |
| 190 content::BrowserContext* context) { | 193 content::BrowserContext* context) { |
| 191 // Manage both the normal context and incognito contexts associated with it. | 194 // Manage both the normal context and incognito contexts associated with it. |
| 192 return Profile::FromBrowserContext(context)->GetOriginalProfile() == | 195 return Profile::FromBrowserContext(context)->GetOriginalProfile() == |
| 193 Profile::FromBrowserContext(browser_context()); | 196 Profile::FromBrowserContext(browser_context()); |
| 194 } | 197 } |
| 195 | 198 |
| 196 // static | 199 // static |
| 197 bool ChromeContentRulesRegistry::EvaluateConditionForTab( | 200 bool ChromeContentRulesRegistry::EvaluateConditionForTab( |
| 198 const ContentCondition* condition, | 201 const ContentCondition* condition, |
| 199 content::WebContents* tab) { | 202 content::WebContents* tab) { |
| 200 for (const scoped_ptr<const ContentPredicate>& predicate : | 203 for (const std::unique_ptr<const ContentPredicate>& predicate : |
| 201 condition->predicates) { | 204 condition->predicates) { |
| 202 if (predicate && !predicate->IsIgnored() && | 205 if (predicate && !predicate->IsIgnored() && |
| 203 !predicate->GetEvaluator()->EvaluatePredicate(predicate.get(), tab)) { | 206 !predicate->GetEvaluator()->EvaluatePredicate(predicate.get(), tab)) { |
| 204 return false; | 207 return false; |
| 205 } | 208 } |
| 206 } | 209 } |
| 207 | 210 |
| 208 return true; | 211 return true; |
| 209 } | 212 } |
| 210 | 213 |
| 211 std::set<const ChromeContentRulesRegistry::ContentRule*> | 214 std::set<const ChromeContentRulesRegistry::ContentRule*> |
| 212 ChromeContentRulesRegistry::GetMatchingRules(content::WebContents* tab) const { | 215 ChromeContentRulesRegistry::GetMatchingRules(content::WebContents* tab) const { |
| 213 const bool is_incognito_tab = tab->GetBrowserContext()->IsOffTheRecord(); | 216 const bool is_incognito_tab = tab->GetBrowserContext()->IsOffTheRecord(); |
| 214 std::set<const ContentRule*> matching_rules; | 217 std::set<const ContentRule*> matching_rules; |
| 215 for (const RulesMap::value_type& rule_id_rule_pair : content_rules_) { | 218 for (const RulesMap::value_type& rule_id_rule_pair : content_rules_) { |
| 216 const ContentRule* rule = rule_id_rule_pair.second.get(); | 219 const ContentRule* rule = rule_id_rule_pair.second.get(); |
| 217 if (is_incognito_tab && | 220 if (is_incognito_tab && |
| 218 !ShouldEvaluateExtensionRulesForIncognitoRenderer(rule->extension)) | 221 !ShouldEvaluateExtensionRulesForIncognitoRenderer(rule->extension)) |
| 219 continue; | 222 continue; |
| 220 | 223 |
| 221 for (const scoped_ptr<const ContentCondition>& condition : | 224 for (const std::unique_ptr<const ContentCondition>& condition : |
| 222 rule->conditions) { | 225 rule->conditions) { |
| 223 if (EvaluateConditionForTab(condition.get(), tab)) | 226 if (EvaluateConditionForTab(condition.get(), tab)) |
| 224 matching_rules.insert(rule); | 227 matching_rules.insert(rule); |
| 225 } | 228 } |
| 226 } | 229 } |
| 227 return matching_rules; | 230 return matching_rules; |
| 228 } | 231 } |
| 229 | 232 |
| 230 std::string ChromeContentRulesRegistry::AddRulesImpl( | 233 std::string ChromeContentRulesRegistry::AddRulesImpl( |
| 231 const std::string& extension_id, | 234 const std::string& extension_id, |
| 232 const std::vector<linked_ptr<api::events::Rule>>& api_rules) { | 235 const std::vector<linked_ptr<api::events::Rule>>& api_rules) { |
| 233 EvaluationScope evaluation_scope(this); | 236 EvaluationScope evaluation_scope(this); |
| 234 const Extension* extension = ExtensionRegistry::Get(browser_context()) | 237 const Extension* extension = ExtensionRegistry::Get(browser_context()) |
| 235 ->GetInstalledExtension(extension_id); | 238 ->GetInstalledExtension(extension_id); |
| 236 DCHECK(extension); | 239 DCHECK(extension); |
| 237 | 240 |
| 238 std::string error; | 241 std::string error; |
| 239 RulesMap new_rules; | 242 RulesMap new_rules; |
| 240 std::map<ContentPredicateEvaluator*, | 243 std::map<ContentPredicateEvaluator*, |
| 241 std::map<const void*, std::vector<const ContentPredicate*>>> | 244 std::map<const void*, std::vector<const ContentPredicate*>>> |
| 242 new_predicates; | 245 new_predicates; |
| 243 | 246 |
| 244 std::map<std::string, ContentPredicateFactory*> predicate_factories; | 247 std::map<std::string, ContentPredicateFactory*> predicate_factories; |
| 245 for (const scoped_ptr<ContentPredicateEvaluator>& evaluator : evaluators_) { | 248 for (const std::unique_ptr<ContentPredicateEvaluator>& evaluator : |
| 249 evaluators_) { |
| 246 predicate_factories[evaluator->GetPredicateApiAttributeName()] = | 250 predicate_factories[evaluator->GetPredicateApiAttributeName()] = |
| 247 evaluator.get(); | 251 evaluator.get(); |
| 248 } | 252 } |
| 249 | 253 |
| 250 for (const linked_ptr<api::events::Rule>& api_rule : api_rules) { | 254 for (const linked_ptr<api::events::Rule>& api_rule : api_rules) { |
| 251 ExtensionIdRuleIdPair rule_id(extension_id, *api_rule->id); | 255 ExtensionIdRuleIdPair rule_id(extension_id, *api_rule->id); |
| 252 DCHECK(content_rules_.find(rule_id) == content_rules_.end()); | 256 DCHECK(content_rules_.find(rule_id) == content_rules_.end()); |
| 253 | 257 |
| 254 scoped_ptr<const ContentRule> rule( | 258 std::unique_ptr<const ContentRule> rule( |
| 255 CreateRule(extension, predicate_factories, *api_rule, &error)); | 259 CreateRule(extension, predicate_factories, *api_rule, &error)); |
| 256 if (!error.empty()) { | 260 if (!error.empty()) { |
| 257 // Notify evaluators that none of the created predicates will be tracked | 261 // Notify evaluators that none of the created predicates will be tracked |
| 258 // after all. | 262 // after all. |
| 259 for (const scoped_ptr<ContentPredicateEvaluator>& evaluator : | 263 for (const std::unique_ptr<ContentPredicateEvaluator>& evaluator : |
| 260 evaluators_) { | 264 evaluators_) { |
| 261 if (!new_predicates[evaluator.get()].empty()) { | 265 if (!new_predicates[evaluator.get()].empty()) { |
| 262 evaluator->TrackPredicates( | 266 evaluator->TrackPredicates( |
| 263 std::map<const void*, std::vector<const ContentPredicate*>>()); | 267 std::map<const void*, std::vector<const ContentPredicate*>>()); |
| 264 } | 268 } |
| 265 } | 269 } |
| 266 | 270 |
| 267 return error; | 271 return error; |
| 268 } | 272 } |
| 269 DCHECK(rule); | 273 DCHECK(rule); |
| 270 | 274 |
| 271 // Group predicates by evaluator and rule, so we can later notify the | 275 // Group predicates by evaluator and rule, so we can later notify the |
| 272 // evaluators that they have new predicates to manage. | 276 // evaluators that they have new predicates to manage. |
| 273 for (const scoped_ptr<const ContentCondition>& condition : | 277 for (const std::unique_ptr<const ContentCondition>& condition : |
| 274 rule->conditions) { | 278 rule->conditions) { |
| 275 for (const scoped_ptr<const ContentPredicate>& predicate : | 279 for (const std::unique_ptr<const ContentPredicate>& predicate : |
| 276 condition->predicates) { | 280 condition->predicates) { |
| 277 if (predicate.get()) { | 281 if (predicate.get()) { |
| 278 new_predicates[predicate->GetEvaluator()][rule.get()].push_back( | 282 new_predicates[predicate->GetEvaluator()][rule.get()].push_back( |
| 279 predicate.get()); | 283 predicate.get()); |
| 280 } | 284 } |
| 281 } | 285 } |
| 282 } | 286 } |
| 283 | 287 |
| 284 new_rules[rule_id] = make_linked_ptr(rule.release()); | 288 new_rules[rule_id] = make_linked_ptr(rule.release()); |
| 285 } | 289 } |
| 286 | 290 |
| 287 // Notify the evaluators about their new predicates. | 291 // Notify the evaluators about their new predicates. |
| 288 for (const scoped_ptr<ContentPredicateEvaluator>& evaluator : evaluators_) | 292 for (const std::unique_ptr<ContentPredicateEvaluator>& evaluator : |
| 293 evaluators_) |
| 289 evaluator->TrackPredicates(new_predicates[evaluator.get()]); | 294 evaluator->TrackPredicates(new_predicates[evaluator.get()]); |
| 290 | 295 |
| 291 // Wohoo, everything worked fine. | 296 // Wohoo, everything worked fine. |
| 292 content_rules_.insert(new_rules.begin(), new_rules.end()); | 297 content_rules_.insert(new_rules.begin(), new_rules.end()); |
| 293 | 298 |
| 294 // Request evaluation for all WebContents, under the assumption that a | 299 // Request evaluation for all WebContents, under the assumption that a |
| 295 // non-empty condition has been added. | 300 // non-empty condition has been added. |
| 296 for (const auto& web_contents_rules_pair : active_rules_) | 301 for (const auto& web_contents_rules_pair : active_rules_) |
| 297 RequestEvaluation(web_contents_rules_pair.first); | 302 RequestEvaluation(web_contents_rules_pair.first); |
| 298 | 303 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 328 action->Revert(apply_info); | 333 action->Revert(apply_info); |
| 329 tab_rules_pair.second.erase(rule); | 334 tab_rules_pair.second.erase(rule); |
| 330 } | 335 } |
| 331 } | 336 } |
| 332 | 337 |
| 333 rules_to_erase.push_back(content_rules_entry); | 338 rules_to_erase.push_back(content_rules_entry); |
| 334 predicate_groups_to_stop_tracking.push_back(rule); | 339 predicate_groups_to_stop_tracking.push_back(rule); |
| 335 } | 340 } |
| 336 | 341 |
| 337 // Notify the evaluators to stop tracking the predicates that will be removed. | 342 // Notify the evaluators to stop tracking the predicates that will be removed. |
| 338 for (const scoped_ptr<ContentPredicateEvaluator>& evaluator : evaluators_) | 343 for (const std::unique_ptr<ContentPredicateEvaluator>& evaluator : |
| 344 evaluators_) |
| 339 evaluator->StopTrackingPredicates(predicate_groups_to_stop_tracking); | 345 evaluator->StopTrackingPredicates(predicate_groups_to_stop_tracking); |
| 340 | 346 |
| 341 // Remove the rules. | 347 // Remove the rules. |
| 342 for (RulesMap::iterator it : rules_to_erase) | 348 for (RulesMap::iterator it : rules_to_erase) |
| 343 content_rules_.erase(it); | 349 content_rules_.erase(it); |
| 344 | 350 |
| 345 return std::string(); | 351 return std::string(); |
| 346 } | 352 } |
| 347 | 353 |
| 348 std::string ChromeContentRulesRegistry::RemoveAllRulesImpl( | 354 std::string ChromeContentRulesRegistry::RemoveAllRulesImpl( |
| (...skipping 13 matching lines...) Expand all Loading... |
| 362 content::WebContents* tab) { | 368 content::WebContents* tab) { |
| 363 std::set<const ContentRule*> matching_rules = GetMatchingRules(tab); | 369 std::set<const ContentRule*> matching_rules = GetMatchingRules(tab); |
| 364 if (matching_rules.empty() && !ContainsKey(active_rules_, tab)) | 370 if (matching_rules.empty() && !ContainsKey(active_rules_, tab)) |
| 365 return; | 371 return; |
| 366 | 372 |
| 367 std::set<const ContentRule*>& prev_matching_rules = active_rules_[tab]; | 373 std::set<const ContentRule*>& prev_matching_rules = active_rules_[tab]; |
| 368 for (const ContentRule* rule : matching_rules) { | 374 for (const ContentRule* rule : matching_rules) { |
| 369 ContentAction::ApplyInfo apply_info = | 375 ContentAction::ApplyInfo apply_info = |
| 370 {rule->extension, browser_context(), tab, rule->priority}; | 376 {rule->extension, browser_context(), tab, rule->priority}; |
| 371 if (!ContainsKey(prev_matching_rules, rule)) { | 377 if (!ContainsKey(prev_matching_rules, rule)) { |
| 372 for (const scoped_ptr<const ContentAction>& action : rule->actions) | 378 for (const std::unique_ptr<const ContentAction>& action : rule->actions) |
| 373 action->Apply(apply_info); | 379 action->Apply(apply_info); |
| 374 } else { | 380 } else { |
| 375 for (const scoped_ptr<const ContentAction>& action : rule->actions) | 381 for (const std::unique_ptr<const ContentAction>& action : rule->actions) |
| 376 action->Reapply(apply_info); | 382 action->Reapply(apply_info); |
| 377 } | 383 } |
| 378 } | 384 } |
| 379 for (const ContentRule* rule : prev_matching_rules) { | 385 for (const ContentRule* rule : prev_matching_rules) { |
| 380 if (!ContainsKey(matching_rules, rule)) { | 386 if (!ContainsKey(matching_rules, rule)) { |
| 381 ContentAction::ApplyInfo apply_info = | 387 ContentAction::ApplyInfo apply_info = |
| 382 {rule->extension, browser_context(), tab, rule->priority}; | 388 {rule->extension, browser_context(), tab, rule->priority}; |
| 383 for (const scoped_ptr<const ContentAction>& action : rule->actions) | 389 for (const std::unique_ptr<const ContentAction>& action : rule->actions) |
| 384 action->Revert(apply_info); | 390 action->Revert(apply_info); |
| 385 } | 391 } |
| 386 } | 392 } |
| 387 | 393 |
| 388 if (matching_rules.empty()) | 394 if (matching_rules.empty()) |
| 389 active_rules_[tab].clear(); | 395 active_rules_[tab].clear(); |
| 390 else | 396 else |
| 391 swap(matching_rules, prev_matching_rules); | 397 swap(matching_rules, prev_matching_rules); |
| 392 } | 398 } |
| 393 | 399 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 421 size_t count = 0; | 427 size_t count = 0; |
| 422 for (const auto& web_contents_rules_pair : active_rules_) | 428 for (const auto& web_contents_rules_pair : active_rules_) |
| 423 count += web_contents_rules_pair.second.size(); | 429 count += web_contents_rules_pair.second.size(); |
| 424 return count; | 430 return count; |
| 425 } | 431 } |
| 426 | 432 |
| 427 ChromeContentRulesRegistry::~ChromeContentRulesRegistry() { | 433 ChromeContentRulesRegistry::~ChromeContentRulesRegistry() { |
| 428 } | 434 } |
| 429 | 435 |
| 430 } // namespace extensions | 436 } // namespace extensions |
| OLD | NEW |