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 "extensions/browser/api/declarative/rules_registry.h" | 5 #include "extensions/browser/api/declarative/rules_registry.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 21 matching lines...) Expand all Loading... |
32 namespace extensions { | 32 namespace extensions { |
33 | 33 |
34 namespace { | 34 namespace { |
35 | 35 |
36 const char kSuccess[] = ""; | 36 const char kSuccess[] = ""; |
37 const char kDuplicateRuleId[] = "Duplicate rule ID: %s"; | 37 const char kDuplicateRuleId[] = "Duplicate rule ID: %s"; |
38 const char kErrorCannotRemoveManifestRules[] = | 38 const char kErrorCannotRemoveManifestRules[] = |
39 "Rules declared in the 'event_rules' manifest field cannot be removed"; | 39 "Rules declared in the 'event_rules' manifest field cannot be removed"; |
40 | 40 |
41 scoped_ptr<base::Value> RulesToValue( | 41 scoped_ptr<base::Value> RulesToValue( |
42 const std::vector<linked_ptr<core_api::events::Rule>>& rules) { | 42 const std::vector<linked_ptr<api::events::Rule>>& rules) { |
43 scoped_ptr<base::ListValue> list(new base::ListValue()); | 43 scoped_ptr<base::ListValue> list(new base::ListValue()); |
44 for (size_t i = 0; i < rules.size(); ++i) | 44 for (size_t i = 0; i < rules.size(); ++i) |
45 list->Append(rules[i]->ToValue().release()); | 45 list->Append(rules[i]->ToValue().release()); |
46 return list.Pass(); | 46 return list.Pass(); |
47 } | 47 } |
48 | 48 |
49 std::vector<linked_ptr<core_api::events::Rule>> RulesFromValue( | 49 std::vector<linked_ptr<api::events::Rule>> RulesFromValue( |
50 const base::Value* value) { | 50 const base::Value* value) { |
51 std::vector<linked_ptr<core_api::events::Rule>> rules; | 51 std::vector<linked_ptr<api::events::Rule>> rules; |
52 | 52 |
53 const base::ListValue* list = NULL; | 53 const base::ListValue* list = NULL; |
54 if (!value || !value->GetAsList(&list)) | 54 if (!value || !value->GetAsList(&list)) |
55 return rules; | 55 return rules; |
56 | 56 |
57 rules.reserve(list->GetSize()); | 57 rules.reserve(list->GetSize()); |
58 for (size_t i = 0; i < list->GetSize(); ++i) { | 58 for (size_t i = 0; i < list->GetSize(); ++i) { |
59 const base::DictionaryValue* dict = NULL; | 59 const base::DictionaryValue* dict = NULL; |
60 if (!list->GetDictionary(i, &dict)) | 60 if (!list->GetDictionary(i, &dict)) |
61 continue; | 61 continue; |
62 linked_ptr<core_api::events::Rule> rule(new core_api::events::Rule()); | 62 linked_ptr<api::events::Rule> rule(new api::events::Rule()); |
63 if (core_api::events::Rule::Populate(*dict, rule.get())) | 63 if (api::events::Rule::Populate(*dict, rule.get())) |
64 rules.push_back(rule); | 64 rules.push_back(rule); |
65 } | 65 } |
66 | 66 |
67 return rules; | 67 return rules; |
68 } | 68 } |
69 | 69 |
70 std::string ToId(int identifier) { | 70 std::string ToId(int identifier) { |
71 return base::StringPrintf("_%d_", identifier); | 71 return base::StringPrintf("_%d_", identifier); |
72 } | 72 } |
73 | 73 |
(...skipping 16 matching lines...) Expand all Loading... |
90 last_generated_rule_identifier_id_(0), | 90 last_generated_rule_identifier_id_(0), |
91 weak_ptr_factory_(browser_context_ ? this : NULL) { | 91 weak_ptr_factory_(browser_context_ ? this : NULL) { |
92 if (cache_delegate) { | 92 if (cache_delegate) { |
93 cache_delegate_ = cache_delegate->GetWeakPtr(); | 93 cache_delegate_ = cache_delegate->GetWeakPtr(); |
94 cache_delegate->Init(this); | 94 cache_delegate->Init(this); |
95 } | 95 } |
96 } | 96 } |
97 | 97 |
98 std::string RulesRegistry::AddRulesNoFill( | 98 std::string RulesRegistry::AddRulesNoFill( |
99 const std::string& extension_id, | 99 const std::string& extension_id, |
100 const std::vector<linked_ptr<core_api::events::Rule>>& rules, | 100 const std::vector<linked_ptr<api::events::Rule>>& rules, |
101 RulesDictionary* out) { | 101 RulesDictionary* out) { |
102 DCHECK_CURRENTLY_ON(owner_thread()); | 102 DCHECK_CURRENTLY_ON(owner_thread()); |
103 | 103 |
104 // Verify that all rule IDs are new. | 104 // Verify that all rule IDs are new. |
105 for (std::vector<linked_ptr<core_api::events::Rule>>::const_iterator i = | 105 for (std::vector<linked_ptr<api::events::Rule>>::const_iterator i = |
106 rules.begin(); | 106 rules.begin(); |
107 i != rules.end(); ++i) { | 107 i != rules.end(); ++i) { |
108 const RuleId& rule_id = *((*i)->id); | 108 const RuleId& rule_id = *((*i)->id); |
109 // Every rule should have a priority assigned. | 109 // Every rule should have a priority assigned. |
110 DCHECK((*i)->priority); | 110 DCHECK((*i)->priority); |
111 RulesDictionaryKey key(extension_id, rule_id); | 111 RulesDictionaryKey key(extension_id, rule_id); |
112 if (rules_.find(key) != rules_.end() || | 112 if (rules_.find(key) != rules_.end() || |
113 manifest_rules_.find(key) != manifest_rules_.end()) | 113 manifest_rules_.find(key) != manifest_rules_.end()) |
114 return base::StringPrintf(kDuplicateRuleId, rule_id.c_str()); | 114 return base::StringPrintf(kDuplicateRuleId, rule_id.c_str()); |
115 } | 115 } |
116 | 116 |
117 std::string error = AddRulesImpl(extension_id, rules); | 117 std::string error = AddRulesImpl(extension_id, rules); |
118 | 118 |
119 if (!error.empty()) | 119 if (!error.empty()) |
120 return error; | 120 return error; |
121 | 121 |
122 // Commit all rules into |rules_| on success. | 122 // Commit all rules into |rules_| on success. |
123 for (std::vector<linked_ptr<core_api::events::Rule>>::const_iterator i = | 123 for (std::vector<linked_ptr<api::events::Rule>>::const_iterator i = |
124 rules.begin(); | 124 rules.begin(); |
125 i != rules.end(); ++i) { | 125 i != rules.end(); ++i) { |
126 const RuleId& rule_id = *((*i)->id); | 126 const RuleId& rule_id = *((*i)->id); |
127 RulesDictionaryKey key(extension_id, rule_id); | 127 RulesDictionaryKey key(extension_id, rule_id); |
128 (*out)[key] = *i; | 128 (*out)[key] = *i; |
129 } | 129 } |
130 | 130 |
131 MaybeProcessChangedRules(extension_id); | 131 MaybeProcessChangedRules(extension_id); |
132 return kSuccess; | 132 return kSuccess; |
133 } | 133 } |
134 | 134 |
135 std::string RulesRegistry::AddRules( | 135 std::string RulesRegistry::AddRules( |
136 const std::string& extension_id, | 136 const std::string& extension_id, |
137 const std::vector<linked_ptr<core_api::events::Rule>>& rules) { | 137 const std::vector<linked_ptr<api::events::Rule>>& rules) { |
138 return AddRulesInternal(extension_id, rules, &rules_); | 138 return AddRulesInternal(extension_id, rules, &rules_); |
139 } | 139 } |
140 | 140 |
141 std::string RulesRegistry::AddRulesInternal( | 141 std::string RulesRegistry::AddRulesInternal( |
142 const std::string& extension_id, | 142 const std::string& extension_id, |
143 const std::vector<linked_ptr<core_api::events::Rule>>& rules, | 143 const std::vector<linked_ptr<api::events::Rule>>& rules, |
144 RulesDictionary* out) { | 144 RulesDictionary* out) { |
145 DCHECK_CURRENTLY_ON(owner_thread()); | 145 DCHECK_CURRENTLY_ON(owner_thread()); |
146 | 146 |
147 std::string error = CheckAndFillInOptionalRules(extension_id, rules); | 147 std::string error = CheckAndFillInOptionalRules(extension_id, rules); |
148 if (!error.empty()) | 148 if (!error.empty()) |
149 return error; | 149 return error; |
150 FillInOptionalPriorities(rules); | 150 FillInOptionalPriorities(rules); |
151 | 151 |
152 return AddRulesNoFill(extension_id, rules, out); | 152 return AddRulesNoFill(extension_id, rules, out); |
153 } | 153 } |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
208 } | 208 } |
209 }; | 209 }; |
210 remove_rules(rules_); | 210 remove_rules(rules_); |
211 if (remove_manifest_rules) | 211 if (remove_manifest_rules) |
212 remove_rules(manifest_rules_); | 212 remove_rules(manifest_rules_); |
213 | 213 |
214 RemoveAllUsedRuleIdentifiers(extension_id); | 214 RemoveAllUsedRuleIdentifiers(extension_id); |
215 return kSuccess; | 215 return kSuccess; |
216 } | 216 } |
217 | 217 |
218 void RulesRegistry::GetRules( | 218 void RulesRegistry::GetRules(const std::string& extension_id, |
219 const std::string& extension_id, | 219 const std::vector<std::string>& rule_identifiers, |
220 const std::vector<std::string>& rule_identifiers, | 220 std::vector<linked_ptr<api::events::Rule>>* out) { |
221 std::vector<linked_ptr<core_api::events::Rule>>* out) { | |
222 DCHECK_CURRENTLY_ON(owner_thread()); | 221 DCHECK_CURRENTLY_ON(owner_thread()); |
223 | 222 |
224 for (const auto& i : rule_identifiers) { | 223 for (const auto& i : rule_identifiers) { |
225 RulesDictionaryKey lookup_key(extension_id, i); | 224 RulesDictionaryKey lookup_key(extension_id, i); |
226 RulesDictionary::iterator entry = rules_.find(lookup_key); | 225 RulesDictionary::iterator entry = rules_.find(lookup_key); |
227 if (entry != rules_.end()) | 226 if (entry != rules_.end()) |
228 out->push_back(entry->second); | 227 out->push_back(entry->second); |
229 entry = manifest_rules_.find(lookup_key); | 228 entry = manifest_rules_.find(lookup_key); |
230 if (entry != manifest_rules_.end()) | 229 if (entry != manifest_rules_.end()) |
231 out->push_back(entry->second); | 230 out->push_back(entry->second); |
232 } | 231 } |
233 } | 232 } |
234 | 233 |
235 void RulesRegistry::GetRules( | 234 void RulesRegistry::GetRules(const std::string& extension_id, |
236 const std::string& extension_id, | 235 RulesDictionary& rules, |
237 RulesDictionary& rules, | 236 std::vector<linked_ptr<api::events::Rule>>* out) { |
238 std::vector<linked_ptr<core_api::events::Rule>>* out) { | |
239 for (const auto& i : rules) { | 237 for (const auto& i : rules) { |
240 const RulesDictionaryKey& key = i.first; | 238 const RulesDictionaryKey& key = i.first; |
241 if (key.first == extension_id) | 239 if (key.first == extension_id) |
242 out->push_back(i.second); | 240 out->push_back(i.second); |
243 } | 241 } |
244 } | 242 } |
245 | 243 |
246 void RulesRegistry::GetAllRules( | 244 void RulesRegistry::GetAllRules( |
247 const std::string& extension_id, | 245 const std::string& extension_id, |
248 std::vector<linked_ptr<core_api::events::Rule>>* out) { | 246 std::vector<linked_ptr<api::events::Rule>>* out) { |
249 DCHECK_CURRENTLY_ON(owner_thread()); | 247 DCHECK_CURRENTLY_ON(owner_thread()); |
250 GetRules(extension_id, manifest_rules_, out); | 248 GetRules(extension_id, manifest_rules_, out); |
251 GetRules(extension_id, rules_, out); | 249 GetRules(extension_id, rules_, out); |
252 } | 250 } |
253 | 251 |
254 void RulesRegistry::OnExtensionUnloaded(const Extension* extension) { | 252 void RulesRegistry::OnExtensionUnloaded(const Extension* extension) { |
255 DCHECK_CURRENTLY_ON(owner_thread()); | 253 DCHECK_CURRENTLY_ON(owner_thread()); |
256 std::string error = RemoveAllRulesImpl(extension->id()); | 254 std::string error = RemoveAllRulesImpl(extension->id()); |
257 if (!error.empty()) | 255 if (!error.empty()) |
258 ReportInternalError(extension->id(), error); | 256 ReportInternalError(extension->id(), error); |
259 } | 257 } |
260 | 258 |
261 void RulesRegistry::OnExtensionUninstalled(const Extension* extension) { | 259 void RulesRegistry::OnExtensionUninstalled(const Extension* extension) { |
262 DCHECK_CURRENTLY_ON(owner_thread()); | 260 DCHECK_CURRENTLY_ON(owner_thread()); |
263 std::string error = RemoveAllRulesNoStoreUpdate(extension->id(), true); | 261 std::string error = RemoveAllRulesNoStoreUpdate(extension->id(), true); |
264 if (!error.empty()) | 262 if (!error.empty()) |
265 ReportInternalError(extension->id(), error); | 263 ReportInternalError(extension->id(), error); |
266 } | 264 } |
267 | 265 |
268 void RulesRegistry::OnExtensionLoaded(const Extension* extension) { | 266 void RulesRegistry::OnExtensionLoaded(const Extension* extension) { |
269 DCHECK_CURRENTLY_ON(owner_thread()); | 267 DCHECK_CURRENTLY_ON(owner_thread()); |
270 std::vector<linked_ptr<core_api::events::Rule>> rules; | 268 std::vector<linked_ptr<api::events::Rule>> rules; |
271 GetAllRules(extension->id(), &rules); | 269 GetAllRules(extension->id(), &rules); |
272 DeclarativeManifestData* declarative_data = | 270 DeclarativeManifestData* declarative_data = |
273 DeclarativeManifestData::Get(extension); | 271 DeclarativeManifestData::Get(extension); |
274 if (declarative_data) { | 272 if (declarative_data) { |
275 std::vector<linked_ptr<core_api::events::Rule>>& manifest_rules = | 273 std::vector<linked_ptr<api::events::Rule>>& manifest_rules = |
276 declarative_data->RulesForEvent(event_name_); | 274 declarative_data->RulesForEvent(event_name_); |
277 if (manifest_rules.size()) { | 275 if (manifest_rules.size()) { |
278 std::string error = | 276 std::string error = |
279 AddRulesInternal(extension->id(), manifest_rules, &manifest_rules_); | 277 AddRulesInternal(extension->id(), manifest_rules, &manifest_rules_); |
280 if (!error.empty()) | 278 if (!error.empty()) |
281 ReportInternalError(extension->id(), error); | 279 ReportInternalError(extension->id(), error); |
282 } | 280 } |
283 } | 281 } |
284 std::string error = AddRulesImpl(extension->id(), rules); | 282 std::string error = AddRulesImpl(extension->id(), rules); |
285 if (!error.empty()) | 283 if (!error.empty()) |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
331 | 329 |
332 ready_.Signal(); | 330 ready_.Signal(); |
333 } | 331 } |
334 | 332 |
335 void RulesRegistry::ProcessChangedRules(const std::string& extension_id) { | 333 void RulesRegistry::ProcessChangedRules(const std::string& extension_id) { |
336 DCHECK_CURRENTLY_ON(owner_thread()); | 334 DCHECK_CURRENTLY_ON(owner_thread()); |
337 | 335 |
338 DCHECK(ContainsKey(process_changed_rules_requested_, extension_id)); | 336 DCHECK(ContainsKey(process_changed_rules_requested_, extension_id)); |
339 process_changed_rules_requested_[extension_id] = NOT_SCHEDULED_FOR_PROCESSING; | 337 process_changed_rules_requested_[extension_id] = NOT_SCHEDULED_FOR_PROCESSING; |
340 | 338 |
341 std::vector<linked_ptr<core_api::events::Rule>> new_rules; | 339 std::vector<linked_ptr<api::events::Rule>> new_rules; |
342 GetRules(extension_id, rules_, &new_rules); | 340 GetRules(extension_id, rules_, &new_rules); |
343 content::BrowserThread::PostTask( | 341 content::BrowserThread::PostTask( |
344 content::BrowserThread::UI, FROM_HERE, | 342 content::BrowserThread::UI, FROM_HERE, |
345 base::Bind(&RulesCacheDelegate::WriteToStorage, cache_delegate_, | 343 base::Bind(&RulesCacheDelegate::WriteToStorage, cache_delegate_, |
346 extension_id, base::Passed(RulesToValue(new_rules)))); | 344 extension_id, base::Passed(RulesToValue(new_rules)))); |
347 } | 345 } |
348 | 346 |
349 void RulesRegistry::MaybeProcessChangedRules(const std::string& extension_id) { | 347 void RulesRegistry::MaybeProcessChangedRules(const std::string& extension_id) { |
350 // Read and initialize |process_changed_rules_requested_[extension_id]| if | 348 // Read and initialize |process_changed_rules_requested_[extension_id]| if |
351 // necessary. (Note that the insertion below will not overwrite | 349 // necessary. (Note that the insertion below will not overwrite |
(...skipping 22 matching lines...) Expand all Loading... |
374 } | 372 } |
375 | 373 |
376 std::string RulesRegistry::GenerateUniqueId(const std::string& extension_id) { | 374 std::string RulesRegistry::GenerateUniqueId(const std::string& extension_id) { |
377 while (!IsUniqueId(extension_id, ToId(last_generated_rule_identifier_id_))) | 375 while (!IsUniqueId(extension_id, ToId(last_generated_rule_identifier_id_))) |
378 ++last_generated_rule_identifier_id_; | 376 ++last_generated_rule_identifier_id_; |
379 return ToId(last_generated_rule_identifier_id_); | 377 return ToId(last_generated_rule_identifier_id_); |
380 } | 378 } |
381 | 379 |
382 std::string RulesRegistry::CheckAndFillInOptionalRules( | 380 std::string RulesRegistry::CheckAndFillInOptionalRules( |
383 const std::string& extension_id, | 381 const std::string& extension_id, |
384 const std::vector<linked_ptr<core_api::events::Rule>>& rules) { | 382 const std::vector<linked_ptr<api::events::Rule>>& rules) { |
385 // IDs we have inserted, in case we need to rollback this operation. | 383 // IDs we have inserted, in case we need to rollback this operation. |
386 std::vector<std::string> rollback_log; | 384 std::vector<std::string> rollback_log; |
387 | 385 |
388 // First we insert all rules with existing identifier, so that generated | 386 // First we insert all rules with existing identifier, so that generated |
389 // identifiers cannot collide with identifiers passed by the caller. | 387 // identifiers cannot collide with identifiers passed by the caller. |
390 for (std::vector<linked_ptr<core_api::events::Rule>>::const_iterator i = | 388 for (std::vector<linked_ptr<api::events::Rule>>::const_iterator i = |
391 rules.begin(); | 389 rules.begin(); |
392 i != rules.end(); ++i) { | 390 i != rules.end(); ++i) { |
393 core_api::events::Rule* rule = i->get(); | 391 api::events::Rule* rule = i->get(); |
394 if (rule->id.get()) { | 392 if (rule->id.get()) { |
395 std::string id = *(rule->id); | 393 std::string id = *(rule->id); |
396 if (!IsUniqueId(extension_id, id)) { | 394 if (!IsUniqueId(extension_id, id)) { |
397 RemoveUsedRuleIdentifiers(extension_id, rollback_log); | 395 RemoveUsedRuleIdentifiers(extension_id, rollback_log); |
398 return "Id " + id + " was used multiple times."; | 396 return "Id " + id + " was used multiple times."; |
399 } | 397 } |
400 used_rule_identifiers_[extension_id].insert(id); | 398 used_rule_identifiers_[extension_id].insert(id); |
401 } | 399 } |
402 } | 400 } |
403 // Now we generate IDs in case they were not specified in the rules. This | 401 // Now we generate IDs in case they were not specified in the rules. This |
404 // cannot fail so we do not need to keep track of a rollback log. | 402 // cannot fail so we do not need to keep track of a rollback log. |
405 for (std::vector<linked_ptr<core_api::events::Rule>>::const_iterator i = | 403 for (std::vector<linked_ptr<api::events::Rule>>::const_iterator i = |
406 rules.begin(); | 404 rules.begin(); |
407 i != rules.end(); ++i) { | 405 i != rules.end(); ++i) { |
408 core_api::events::Rule* rule = i->get(); | 406 api::events::Rule* rule = i->get(); |
409 if (!rule->id.get()) { | 407 if (!rule->id.get()) { |
410 rule->id.reset(new std::string(GenerateUniqueId(extension_id))); | 408 rule->id.reset(new std::string(GenerateUniqueId(extension_id))); |
411 used_rule_identifiers_[extension_id].insert(*(rule->id)); | 409 used_rule_identifiers_[extension_id].insert(*(rule->id)); |
412 } | 410 } |
413 } | 411 } |
414 return std::string(); | 412 return std::string(); |
415 } | 413 } |
416 | 414 |
417 void RulesRegistry::FillInOptionalPriorities( | 415 void RulesRegistry::FillInOptionalPriorities( |
418 const std::vector<linked_ptr<core_api::events::Rule>>& rules) { | 416 const std::vector<linked_ptr<api::events::Rule>>& rules) { |
419 std::vector<linked_ptr<core_api::events::Rule>>::const_iterator i; | 417 std::vector<linked_ptr<api::events::Rule>>::const_iterator i; |
420 for (i = rules.begin(); i != rules.end(); ++i) { | 418 for (i = rules.begin(); i != rules.end(); ++i) { |
421 if (!(*i)->priority.get()) | 419 if (!(*i)->priority.get()) |
422 (*i)->priority.reset(new int(DEFAULT_PRIORITY)); | 420 (*i)->priority.reset(new int(DEFAULT_PRIORITY)); |
423 } | 421 } |
424 } | 422 } |
425 | 423 |
426 void RulesRegistry::RemoveUsedRuleIdentifiers( | 424 void RulesRegistry::RemoveUsedRuleIdentifiers( |
427 const std::string& extension_id, | 425 const std::string& extension_id, |
428 const std::vector<std::string>& identifiers) { | 426 const std::vector<std::string>& identifiers) { |
429 std::vector<std::string>::const_iterator i; | 427 std::vector<std::string>::const_iterator i; |
430 for (i = identifiers.begin(); i != identifiers.end(); ++i) | 428 for (i = identifiers.begin(); i != identifiers.end(); ++i) |
431 used_rule_identifiers_[extension_id].erase(*i); | 429 used_rule_identifiers_[extension_id].erase(*i); |
432 } | 430 } |
433 | 431 |
434 void RulesRegistry::RemoveAllUsedRuleIdentifiers( | 432 void RulesRegistry::RemoveAllUsedRuleIdentifiers( |
435 const std::string& extension_id) { | 433 const std::string& extension_id) { |
436 used_rule_identifiers_.erase(extension_id); | 434 used_rule_identifiers_.erase(extension_id); |
437 } | 435 } |
438 | 436 |
439 } // namespace extensions | 437 } // namespace extensions |
OLD | NEW |