Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(478)

Side by Side Diff: extensions/browser/api/declarative/rules_registry.cc

Issue 1158693006: Create a mechanism define declarative rules via the extension manifest. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Prevent removal of rules set in manifest. Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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"
11 #include "base/message_loop/message_loop.h" 11 #include "base/message_loop/message_loop.h"
12 #include "base/metrics/histogram.h" 12 #include "base/metrics/histogram.h"
13 #include "base/stl_util.h" 13 #include "base/stl_util.h"
14 #include "base/strings/stringprintf.h" 14 #include "base/strings/stringprintf.h"
15 #include "base/time/time.h" 15 #include "base/time/time.h"
16 #include "base/values.h" 16 #include "base/values.h"
17 #include "content/public/browser/browser_thread.h" 17 #include "content/public/browser/browser_thread.h"
18 #include "content/public/browser/notification_details.h" 18 #include "content/public/browser/notification_details.h"
19 #include "content/public/browser/notification_source.h" 19 #include "content/public/browser/notification_source.h"
20 #include "extensions/browser/api/declarative/rules_cache_delegate.h" 20 #include "extensions/browser/api/declarative/rules_cache_delegate.h"
21 #include "extensions/browser/extension_prefs.h" 21 #include "extensions/browser/extension_prefs.h"
22 #include "extensions/browser/extension_registry.h"
22 #include "extensions/browser/extension_system.h" 23 #include "extensions/browser/extension_system.h"
23 #include "extensions/browser/state_store.h" 24 #include "extensions/browser/state_store.h"
24 #include "extensions/common/extension.h" 25 #include "extensions/common/extension.h"
26 #include "extensions/common/manifest_constants.h"
25 27
26 namespace { 28 namespace {
27 29
28 const char kSuccess[] = ""; 30 const char kSuccess[] = "";
29 const char kDuplicateRuleId[] = "Duplicate rule ID: %s"; 31 const char kDuplicateRuleId[] = "Duplicate rule ID: %s";
30 32
31 scoped_ptr<base::Value> RulesToValue( 33 scoped_ptr<base::Value> RulesToValue(
32 const std::vector<linked_ptr<extensions::RulesRegistry::Rule> >& rules) { 34 const std::vector<linked_ptr<extensions::RulesRegistry::Rule> >& rules) {
33 scoped_ptr<base::ListValue> list(new base::ListValue()); 35 scoped_ptr<base::ListValue> list(new base::ListValue());
34 for (size_t i = 0; i < rules.size(); ++i) 36 for (size_t i = 0; i < rules.size(); ++i)
(...skipping 16 matching lines...) Expand all
51 continue; 53 continue;
52 linked_ptr<extensions::RulesRegistry::Rule> rule( 54 linked_ptr<extensions::RulesRegistry::Rule> rule(
53 new extensions::RulesRegistry::Rule()); 55 new extensions::RulesRegistry::Rule());
54 if (extensions::RulesRegistry::Rule::Populate(*dict, rule.get())) 56 if (extensions::RulesRegistry::Rule::Populate(*dict, rule.get()))
55 rules.push_back(rule); 57 rules.push_back(rule);
56 } 58 }
57 59
58 return rules; 60 return rules;
59 } 61 }
60 62
63 scoped_ptr<base::ListValue> ConvertListFromManifest(
64 const base::ListValue* list) {
65 scoped_ptr<base::ListValue> result(new base::ListValue);
66 for (base::ListValue::const_iterator it = list->begin(); it != list->end();
67 ++it) {
68 base::DictionaryValue* dictionary = nullptr;
69 if (!(*it)->GetAsDictionary(&dictionary))
70 continue;
71 std::string type;
72 if (!dictionary->GetString("type", &type))
73 continue;
74 scoped_ptr<base::DictionaryValue> copy = dictionary->CreateDeepCopy();
75 copy->Remove("type", NULL);
76 copy->SetString("instanceType", type);
77 result->Append(copy.Pass());
78 }
79 return result.Pass();
80 }
81
82 std::vector<linked_ptr<extensions::RulesRegistry::Rule>> RulesFromManifest(
not at google - send to devlin 2015/06/04 17:58:49 - This file is already in the extensions namespace
danduong 2015/06/04 19:10:59 - All these helper functions are in anonymous name
not at google - send to devlin 2015/06/04 19:23:52 I see. Move the "namespace extensions {" declarati
danduong 2015/06/04 21:39:40 Done.
83 const base::Value* value,
84 const std::string& event_name) {
85 std::vector<linked_ptr<extensions::RulesRegistry::Rule>> rules;
86
87 const base::ListValue* list = nullptr;
88 if (!value || !value->GetAsList(&list))
89 return rules;
90
91 for (size_t i = 0; i < list->GetSize(); ++i) {
not at google - send to devlin 2015/06/04 17:58:49 You should look at defining this structure in exte
danduong 2015/06/05 06:41:57 I looked into it and I ran into some problems with
92 const base::DictionaryValue* dict = nullptr;
93 if (!list->GetDictionary(i, &dict))
94 continue;
95 std::string event;
96 if (!dict->GetString("event", &event))
97 continue;
98 if (event_name != event)
99 continue;
100 const base::ListValue* list;
101 if (!dict->GetList("conditions", &list) || !list->GetSize())
102 continue;
103 scoped_ptr<base::ListValue> conditions = ConvertListFromManifest(list);
104 if (!conditions->GetSize())
105 continue;
106 if (!dict->GetList("actions", &list) || !list->GetSize())
107 continue;
108 scoped_ptr<base::ListValue> actions = ConvertListFromManifest(list);
109 if (!actions->GetSize())
110 continue;
111 scoped_ptr<base::DictionaryValue> rule_dict(new base::DictionaryValue);
112 rule_dict->Set("conditions", conditions.Pass());
113 rule_dict->Set("actions", actions.Pass());
114 rule_dict->SetBoolean("removable", false);
115 linked_ptr<extensions::RulesRegistry::Rule> rule(
116 new extensions::RulesRegistry::Rule());
117 if (extensions::RulesRegistry::Rule::Populate(*rule_dict, rule.get()))
118 rules.push_back(rule);
119 }
120
121 return rules;
122 }
123
61 std::string ToId(int identifier) { 124 std::string ToId(int identifier) {
62 return base::StringPrintf("_%d_", identifier); 125 return base::StringPrintf("_%d_", identifier);
63 } 126 }
64 127
65 } // namespace 128 } // namespace
66 129
67 130
68 namespace extensions { 131 namespace extensions {
69 132
70 // RulesRegistry 133 // RulesRegistry
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
132 FillInOptionalPriorities(rules); 195 FillInOptionalPriorities(rules);
133 196
134 return AddRulesNoFill(extension_id, rules); 197 return AddRulesNoFill(extension_id, rules);
135 } 198 }
136 199
137 std::string RulesRegistry::RemoveRules( 200 std::string RulesRegistry::RemoveRules(
138 const std::string& extension_id, 201 const std::string& extension_id,
139 const std::vector<std::string>& rule_identifiers) { 202 const std::vector<std::string>& rule_identifiers) {
140 DCHECK_CURRENTLY_ON(owner_thread()); 203 DCHECK_CURRENTLY_ON(owner_thread());
141 204
205 // Check if any of the rules are non-removable.
206 for (RuleId rule_id : rule_identifiers) {
207 RulesDictionaryKey lookup_key(extension_id, rule_id);
208 RulesDictionary::iterator entry = rules_.find(lookup_key);
209 if (entry != rules_.end()) {
210 Rule* rule = entry->second.get();
211 if (rule->removable.get() && !*(rule->removable))
212 return "List contains non-removable rules";
not at google - send to devlin 2015/06/04 17:58:48 I'd prefer to define this as a constant.
danduong 2015/06/04 19:10:58 Done.
213 }
214 }
215
142 std::string error = RemoveRulesImpl(extension_id, rule_identifiers); 216 std::string error = RemoveRulesImpl(extension_id, rule_identifiers);
143 217
144 if (!error.empty()) 218 if (!error.empty())
145 return error; 219 return error;
146 220
147 for (std::vector<std::string>::const_iterator i = rule_identifiers.begin(); 221 for (std::vector<std::string>::const_iterator i = rule_identifiers.begin();
148 i != rule_identifiers.end(); 222 i != rule_identifiers.end();
149 ++i) { 223 ++i) {
150 RulesDictionaryKey lookup_key(extension_id, *i); 224 RulesDictionaryKey lookup_key(extension_id, *i);
151 rules_.erase(lookup_key); 225 rules_.erase(lookup_key);
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
215 LOG(ERROR) << error; 289 LOG(ERROR) << error;
216 } 290 }
217 291
218 void RulesRegistry::OnExtensionUninstalled(const std::string& extension_id) { 292 void RulesRegistry::OnExtensionUninstalled(const std::string& extension_id) {
219 DCHECK_CURRENTLY_ON(owner_thread()); 293 DCHECK_CURRENTLY_ON(owner_thread());
220 std::string error = RemoveAllRulesNoStoreUpdate(extension_id); 294 std::string error = RemoveAllRulesNoStoreUpdate(extension_id);
221 if (!error.empty()) 295 if (!error.empty())
222 LOG(ERROR) << error; 296 LOG(ERROR) << error;
223 } 297 }
224 298
225 void RulesRegistry::OnExtensionLoaded(const std::string& extension_id) { 299 void RulesRegistry::OnExtensionLoaded(const std::string& extension_id) {
not at google - send to devlin 2015/06/04 17:58:49 Repeat previous comment: Could you update OnExten
226 DCHECK_CURRENTLY_ON(owner_thread()); 300 DCHECK_CURRENTLY_ON(owner_thread());
227 std::vector<linked_ptr<Rule> > rules; 301 std::vector<linked_ptr<Rule> > rules;
228 GetAllRules(extension_id, &rules); 302 GetAllRules(extension_id, &rules);
229 std::string error = AddRulesImpl(extension_id, rules); 303 if (rules.empty()) {
not at google - send to devlin 2015/06/04 17:58:48 Repeat previous comment: Why only if there are no
danduong 2015/06/04 19:10:59 Isn't that use case still met, since the complete
not at google - send to devlin 2015/06/04 19:23:53 I think this won't work for update, though. There
danduong 2015/06/04 19:56:07 Update would work still right? Uninstall will remo
not at google - send to devlin 2015/06/04 20:02:21 Maybe. Either way this code looks wrong. I would h
danduong 2015/06/04 21:39:40 Done.
230 if (!error.empty()) 304 // If no rules have been registered yet, check if there are any rules
231 LOG(ERROR) << error; 305 // defined in the extension manifest to add.
306 const Extension* extension =
307 ExtensionRegistry::Get(browser_context())
308 ->GetExtensionById(extension_id, ExtensionRegistry::EVERYTHING);
not at google - send to devlin 2015/06/04 17:58:49 Btw once https://codereview.chromium.org/113035301
danduong 2015/06/04 19:10:59 Acknowledged.
309 const base::ListValue* value = NULL;
310 if (extension->manifest()->GetList(manifest_keys::kEventRules, &value)) {
311 AddRules(extension_id, RulesFromManifest(value, event_name_));
Mike Wittman 2015/06/04 18:40:13 this needs to handle the error which may be return
danduong 2015/06/04 19:10:59 Done.
312 }
313 } else {
314 std::string error = AddRulesImpl(extension_id, rules);
315 if (!error.empty())
316 LOG(ERROR) << error;
317 }
232 } 318 }
233 319
234 size_t RulesRegistry::GetNumberOfUsedRuleIdentifiersForTesting() const { 320 size_t RulesRegistry::GetNumberOfUsedRuleIdentifiersForTesting() const {
235 size_t entry_count = 0u; 321 size_t entry_count = 0u;
236 for (RuleIdentifiersMap::const_iterator extension = 322 for (RuleIdentifiersMap::const_iterator extension =
237 used_rule_identifiers_.begin(); 323 used_rule_identifiers_.begin();
238 extension != used_rule_identifiers_.end(); 324 extension != used_rule_identifiers_.end();
239 ++extension) { 325 ++extension) {
240 // Each extension is counted as 1 just for being there. Otherwise we miss 326 // Each extension is counted as 1 just for being there. Otherwise we miss
241 // keys with empty values. 327 // keys with empty values.
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
367 for (i = identifiers.begin(); i != identifiers.end(); ++i) 453 for (i = identifiers.begin(); i != identifiers.end(); ++i)
368 used_rule_identifiers_[extension_id].erase(*i); 454 used_rule_identifiers_[extension_id].erase(*i);
369 } 455 }
370 456
371 void RulesRegistry::RemoveAllUsedRuleIdentifiers( 457 void RulesRegistry::RemoveAllUsedRuleIdentifiers(
372 const std::string& extension_id) { 458 const std::string& extension_id) {
373 used_rule_identifiers_.erase(extension_id); 459 used_rule_identifiers_.erase(extension_id);
374 } 460 }
375 461
376 } // namespace extensions 462 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698