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

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: 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_system.h" 22 #include "extensions/browser/extension_system.h"
23 #include "extensions/browser/state_store.h" 23 #include "extensions/browser/state_store.h"
24 #include "extensions/common/extension.h" 24 #include "extensions/common/extension.h"
25 #include "extensions/common/manifest_constants.h"
26
27 namespace extensions {
25 28
26 namespace { 29 namespace {
27 30
28 const char kSuccess[] = ""; 31 const char kSuccess[] = "";
29 const char kDuplicateRuleId[] = "Duplicate rule ID: %s"; 32 const char kDuplicateRuleId[] = "Duplicate rule ID: %s";
33 const char kErrorNonRemovableRules[] = "List contains non-removable rules";
not at google - send to devlin 2015/06/05 16:16:14 Be more literal: const char kErrorCannotRemoveMan
danduong 2015/06/05 21:35:07 Done.
30 34
31 scoped_ptr<base::Value> RulesToValue( 35 scoped_ptr<base::Value> RulesToValue(
32 const std::vector<linked_ptr<extensions::RulesRegistry::Rule> >& rules) { 36 const std::vector<linked_ptr<RulesRegistry::Rule>>& rules) {
33 scoped_ptr<base::ListValue> list(new base::ListValue()); 37 scoped_ptr<base::ListValue> list(new base::ListValue());
34 for (size_t i = 0; i < rules.size(); ++i) 38 for (size_t i = 0; i < rules.size(); ++i)
35 list->Append(rules[i]->ToValue().release()); 39 list->Append(rules[i]->ToValue().release());
36 return list.Pass(); 40 return list.Pass();
37 } 41 }
38 42
39 std::vector<linked_ptr<extensions::RulesRegistry::Rule> > RulesFromValue( 43 std::vector<linked_ptr<RulesRegistry::Rule>> RulesFromValue(
40 const base::Value* value) { 44 const base::Value* value) {
41 std::vector<linked_ptr<extensions::RulesRegistry::Rule> > rules; 45 std::vector<linked_ptr<RulesRegistry::Rule>> rules;
42 46
43 const base::ListValue* list = NULL; 47 const base::ListValue* list = NULL;
44 if (!value || !value->GetAsList(&list)) 48 if (!value || !value->GetAsList(&list))
45 return rules; 49 return rules;
46 50
47 rules.reserve(list->GetSize()); 51 rules.reserve(list->GetSize());
48 for (size_t i = 0; i < list->GetSize(); ++i) { 52 for (size_t i = 0; i < list->GetSize(); ++i) {
49 const base::DictionaryValue* dict = NULL; 53 const base::DictionaryValue* dict = NULL;
50 if (!list->GetDictionary(i, &dict)) 54 if (!list->GetDictionary(i, &dict))
51 continue; 55 continue;
52 linked_ptr<extensions::RulesRegistry::Rule> rule( 56 linked_ptr<RulesRegistry::Rule> rule(new RulesRegistry::Rule());
53 new extensions::RulesRegistry::Rule()); 57 if (RulesRegistry::Rule::Populate(*dict, rule.get()))
54 if (extensions::RulesRegistry::Rule::Populate(*dict, rule.get()))
55 rules.push_back(rule); 58 rules.push_back(rule);
56 } 59 }
57 60
58 return rules; 61 return rules;
59 } 62 }
60 63
64 bool ConvertManifestRule(linked_ptr<RulesRegistry::Rule> rule) {
not at google - send to devlin 2015/06/05 16:16:14 avoid copy and use a const linked_ptr&
danduong 2015/06/05 21:35:07 Done.
65 // Swaps key 'type' (used in manifest) for 'instanceType'.
not at google - send to devlin 2015/06/05 16:16:14 Could you move this comment up to a function-level
danduong 2015/06/05 21:35:06 Done.
66 auto convert_list = [](std::vector<linked_ptr<base::Value>>& list) {
67 for (linked_ptr<base::Value> value : list) {
not at google - send to devlin 2015/06/05 16:16:14 avoid copy and use a (const?) linked_ptr&
danduong 2015/06/05 21:35:06 Done.
68 base::DictionaryValue* dictionary = nullptr;
69 if (!value->GetAsDictionary(&dictionary))
70 return false;
71 std::string type;
72 if (!dictionary->GetString("type", &type))
73 return false;
74 dictionary->Remove("type", nullptr);
75 dictionary->SetString("instanceType", type);
76 }
77 return true;
78 };
79 return convert_list(rule->actions) && convert_list(rule->conditions);
80 }
81
82 std::vector<linked_ptr<RulesRegistry::Rule>> RulesFromManifest(
83 const base::Value* value,
84 const std::string& event_name) {
85 std::vector<linked_ptr<RulesRegistry::Rule>> rules;
86
87 const base::ListValue* list = nullptr;
88 if (!value || !value->GetAsList(&list))
not at google - send to devlin 2015/06/05 16:16:14 The (!value) here here shouldn't be necessary, it
danduong 2015/06/05 21:35:06 Done.
89 return rules;
not at google - send to devlin 2015/06/05 16:16:13 Another problem is that this silently fails if an
danduong 2015/06/05 21:35:06 Should we just log error in these cases?
not at google - send to devlin 2015/06/05 23:29:42 Ideally we'd be parsing these rules when the exten
danduong 2015/06/06 03:10:32 added a manifest handler.
90
91 for (size_t i = 0; i < list->GetSize(); ++i) {
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;
not at google - send to devlin 2015/06/05 16:16:14 It would help to document this stuff. I only know
danduong 2015/06/05 21:35:06 Done.
100 linked_ptr<RulesRegistry::Rule> rule(new RulesRegistry::Rule());
101 if (!RulesRegistry::Rule::Populate(*dict, rule.get()))
102 continue;
103 if (!ConvertManifestRule(rule))
104 continue;
105 rules.push_back(rule);
not at google - send to devlin 2015/06/05 16:16:14 Apologies for this nit, but btw, these methods tha
danduong 2015/06/05 21:35:06 Done.
106 }
107
108 return rules;
109 }
110
61 std::string ToId(int identifier) { 111 std::string ToId(int identifier) {
62 return base::StringPrintf("_%d_", identifier); 112 return base::StringPrintf("_%d_", identifier);
63 } 113 }
64 114
65 } // namespace 115 } // namespace
66 116
67 117
68 namespace extensions {
69
70 // RulesRegistry 118 // RulesRegistry
71 119
72 RulesRegistry::RulesRegistry(content::BrowserContext* browser_context, 120 RulesRegistry::RulesRegistry(content::BrowserContext* browser_context,
73 const std::string& event_name, 121 const std::string& event_name,
74 content::BrowserThread::ID owner_thread, 122 content::BrowserThread::ID owner_thread,
75 RulesCacheDelegate* cache_delegate, 123 RulesCacheDelegate* cache_delegate,
76 int id) 124 int id)
77 : browser_context_(browser_context), 125 : browser_context_(browser_context),
78 owner_thread_(owner_thread), 126 owner_thread_(owner_thread),
79 event_name_(event_name), 127 event_name_(event_name),
80 id_(id), 128 id_(id),
81 ready_(/*signaled=*/!cache_delegate), // Immediately ready if no cache 129 ready_(/*signaled=*/!cache_delegate), // Immediately ready if no cache
82 // delegate to wait for. 130 // delegate to wait for.
83 last_generated_rule_identifier_id_(0), 131 last_generated_rule_identifier_id_(0),
84 weak_ptr_factory_(browser_context_ ? this : NULL) { 132 weak_ptr_factory_(browser_context_ ? this : NULL) {
85 if (cache_delegate) { 133 if (cache_delegate) {
86 cache_delegate_ = cache_delegate->GetWeakPtr(); 134 cache_delegate_ = cache_delegate->GetWeakPtr();
87 cache_delegate->Init(this); 135 cache_delegate->Init(this);
88 } 136 }
89 } 137 }
90 138
91 std::string RulesRegistry::AddRulesNoFill( 139 std::string RulesRegistry::AddRulesNoFill(
92 const std::string& extension_id, 140 const std::string& extension_id,
93 const std::vector<linked_ptr<Rule> >& rules) { 141 const std::vector<linked_ptr<Rule>>& rules,
142 bool from_manifest) {
not at google - send to devlin 2015/06/05 16:16:14 It's more direct to pass around the list of rules
danduong 2015/06/05 21:35:06 Done.
not at google - send to devlin 2015/06/08 21:44:58 except, pass as a pointer not a reference.
danduong 2015/06/09 01:21:26 Done.
94 DCHECK_CURRENTLY_ON(owner_thread()); 143 DCHECK_CURRENTLY_ON(owner_thread());
95 144
96 // Verify that all rule IDs are new. 145 // Verify that all rule IDs are new.
97 for (std::vector<linked_ptr<Rule> >::const_iterator i = 146 for (std::vector<linked_ptr<Rule> >::const_iterator i =
98 rules.begin(); i != rules.end(); ++i) { 147 rules.begin(); i != rules.end(); ++i) {
99 const RuleId& rule_id = *((*i)->id); 148 const RuleId& rule_id = *((*i)->id);
100 // Every rule should have a priority assigned. 149 // Every rule should have a priority assigned.
101 DCHECK((*i)->priority); 150 DCHECK((*i)->priority);
102 RulesDictionaryKey key(extension_id, rule_id); 151 RulesDictionaryKey key(extension_id, rule_id);
103 if (rules_.find(key) != rules_.end()) 152 if (rules_.find(key) != rules_.end() ||
153 manifest_rules_.find(key) != manifest_rules_.end())
104 return base::StringPrintf(kDuplicateRuleId, rule_id.c_str()); 154 return base::StringPrintf(kDuplicateRuleId, rule_id.c_str());
105 } 155 }
106 156
107 std::string error = AddRulesImpl(extension_id, rules); 157 std::string error = AddRulesImpl(extension_id, rules);
108 158
109 if (!error.empty()) 159 if (!error.empty())
110 return error; 160 return error;
111 161
112 // Commit all rules into |rules_| on success. 162 // Commit all rules into |rules_| on success.
113 for (std::vector<linked_ptr<Rule> >::const_iterator i = 163 for (std::vector<linked_ptr<Rule> >::const_iterator i =
114 rules.begin(); i != rules.end(); ++i) { 164 rules.begin(); i != rules.end(); ++i) {
115 const RuleId& rule_id = *((*i)->id); 165 const RuleId& rule_id = *((*i)->id);
116 RulesDictionaryKey key(extension_id, rule_id); 166 RulesDictionaryKey key(extension_id, rule_id);
117 rules_[key] = *i; 167 if (from_manifest)
168 manifest_rules_[key] = *i;
169 else
170 rules_[key] = *i;
118 } 171 }
119 172
120 MaybeProcessChangedRules(extension_id); 173 MaybeProcessChangedRules(extension_id);
121 return kSuccess; 174 return kSuccess;
122 } 175 }
123 176
124 std::string RulesRegistry::AddRules( 177 std::string RulesRegistry::AddRules(const std::string& extension_id,
125 const std::string& extension_id, 178 const std::vector<linked_ptr<Rule>>& rules,
126 const std::vector<linked_ptr<Rule> >& rules) { 179 bool from_manifest) {
127 DCHECK_CURRENTLY_ON(owner_thread()); 180 DCHECK_CURRENTLY_ON(owner_thread());
128 181
129 std::string error = CheckAndFillInOptionalRules(extension_id, rules); 182 std::string error = CheckAndFillInOptionalRules(extension_id, rules);
130 if (!error.empty()) 183 if (!error.empty())
131 return error; 184 return error;
132 FillInOptionalPriorities(rules); 185 FillInOptionalPriorities(rules);
133 186
134 return AddRulesNoFill(extension_id, rules); 187 return AddRulesNoFill(extension_id, rules, from_manifest);
not at google - send to devlin 2015/06/05 16:16:14 This can only ever be false, so remove the |from_m
danduong 2015/06/05 21:35:06 Done.
135 } 188 }
136 189
137 std::string RulesRegistry::RemoveRules( 190 std::string RulesRegistry::RemoveRules(
138 const std::string& extension_id, 191 const std::string& extension_id,
139 const std::vector<std::string>& rule_identifiers) { 192 const std::vector<std::string>& rule_identifiers) {
140 DCHECK_CURRENTLY_ON(owner_thread()); 193 DCHECK_CURRENTLY_ON(owner_thread());
141 194
195 // Check if any of the rules are non-removable.
196 for (RuleId rule_id : rule_identifiers) {
197 RulesDictionaryKey lookup_key(extension_id, rule_id);
198 RulesDictionary::iterator itr = manifest_rules_.find(lookup_key);
199 if (itr != manifest_rules_.end())
200 return kErrorNonRemovableRules;
201 }
202
142 std::string error = RemoveRulesImpl(extension_id, rule_identifiers); 203 std::string error = RemoveRulesImpl(extension_id, rule_identifiers);
143 204
144 if (!error.empty()) 205 if (!error.empty())
145 return error; 206 return error;
146 207
147 for (std::vector<std::string>::const_iterator i = rule_identifiers.begin(); 208 for (std::vector<std::string>::const_iterator i = rule_identifiers.begin();
148 i != rule_identifiers.end(); 209 i != rule_identifiers.end();
149 ++i) { 210 ++i) {
150 RulesDictionaryKey lookup_key(extension_id, *i); 211 RulesDictionaryKey lookup_key(extension_id, *i);
151 rules_.erase(lookup_key); 212 rules_.erase(lookup_key);
(...skipping 12 matching lines...) Expand all
164 225
165 std::string RulesRegistry::RemoveAllRulesNoStoreUpdate( 226 std::string RulesRegistry::RemoveAllRulesNoStoreUpdate(
166 const std::string& extension_id) { 227 const std::string& extension_id) {
167 DCHECK_CURRENTLY_ON(owner_thread()); 228 DCHECK_CURRENTLY_ON(owner_thread());
168 229
169 std::string error = RemoveAllRulesImpl(extension_id); 230 std::string error = RemoveAllRulesImpl(extension_id);
170 231
171 if (!error.empty()) 232 if (!error.empty())
172 return error; 233 return error;
173 234
174 for (RulesDictionary::const_iterator i = rules_.begin(); 235 auto remove_rules = [&extension_id](RulesDictionary& dictionary) {
175 i != rules_.end();) { 236 for (RulesDictionary::const_iterator i = dictionary.begin();
176 const RulesDictionaryKey& key = i->first; 237 i != dictionary.end();) {
177 ++i; 238 const RulesDictionaryKey& key = i->first;
178 if (key.first == extension_id) 239 ++i;
179 rules_.erase(key); 240 if (key.first == extension_id) {
180 } 241 dictionary.erase(key);
242 }
not at google - send to devlin 2015/06/05 16:16:14 Btw the way I usually see this written is along th
danduong 2015/06/05 21:35:07 Done.
243 }
244 };
245 remove_rules(rules_);
246 remove_rules(manifest_rules_);
181 247
182 RemoveAllUsedRuleIdentifiers(extension_id); 248 RemoveAllUsedRuleIdentifiers(extension_id);
183 return kSuccess; 249 return kSuccess;
184 } 250 }
185 251
186 void RulesRegistry::GetRules(const std::string& extension_id, 252 void RulesRegistry::GetRules(const std::string& extension_id,
187 const std::vector<std::string>& rule_identifiers, 253 const std::vector<std::string>& rule_identifiers,
188 std::vector<linked_ptr<Rule> >* out) { 254 std::vector<linked_ptr<Rule> >* out) {
189 DCHECK_CURRENTLY_ON(owner_thread()); 255 DCHECK_CURRENTLY_ON(owner_thread());
190 256
191 for (std::vector<std::string>::const_iterator i = rule_identifiers.begin(); 257 for (std::vector<std::string>::const_iterator i = rule_identifiers.begin();
192 i != rule_identifiers.end(); ++i) { 258 i != rule_identifiers.end(); ++i) {
193 RulesDictionaryKey lookup_key(extension_id, *i); 259 RulesDictionaryKey lookup_key(extension_id, *i);
194 RulesDictionary::iterator entry = rules_.find(lookup_key); 260 RulesDictionary::iterator entry = rules_.find(lookup_key);
195 if (entry != rules_.end()) 261 if (entry != rules_.end()) {
196 out->push_back(entry->second); 262 out->push_back(entry->second);
263 } else {
264 entry = manifest_rules_.find(lookup_key);
265 if (entry != manifest_rules_.end())
266 out->push_back(entry->second);
267 }
not at google - send to devlin 2015/06/05 16:16:14 Simpler: RulesDictionary::iterator entry = rules_
danduong 2015/06/05 21:35:06 Done.
197 } 268 }
198 } 269 }
199 270
200 void RulesRegistry::GetAllRules(const std::string& extension_id, 271 void RulesRegistry::GetAllRules(const std::string& extension_id,
201 std::vector<linked_ptr<Rule> >* out) { 272 std::vector<linked_ptr<Rule> >* out) {
202 DCHECK_CURRENTLY_ON(owner_thread()); 273 DCHECK_CURRENTLY_ON(owner_thread());
203 for (RulesDictionary::const_iterator i = rules_.begin(); 274 auto get_rules = [&extension_id, out](const RulesDictionary& dictionary) {
204 i != rules_.end(); ++i) { 275 for (RulesDictionary::const_iterator i = dictionary.begin();
205 const RulesDictionaryKey& key = i->first; 276 i != dictionary.end(); ++i) {
not at google - send to devlin 2015/06/05 16:16:13 (btw, consider changing all of these sorts of loop
danduong 2015/06/05 21:35:07 Acknowledged.
206 if (key.first == extension_id) 277 const RulesDictionaryKey& key = i->first;
207 out->push_back(i->second); 278 if (key.first == extension_id)
208 } 279 out->push_back(i->second);
280 }
281 };
282 get_rules(manifest_rules_);
283 get_rules(rules_);
209 } 284 }
210 285
211 void RulesRegistry::OnExtensionUnloaded(const std::string& extension_id) { 286 void RulesRegistry::OnExtensionUnloaded(const Extension* extension) {
212 DCHECK_CURRENTLY_ON(owner_thread()); 287 DCHECK_CURRENTLY_ON(owner_thread());
213 std::string error = RemoveAllRulesImpl(extension_id); 288 std::string error = RemoveAllRulesImpl(extension->id());
214 if (!error.empty()) 289 if (!error.empty())
215 LOG(ERROR) << error; 290 LOG(ERROR) << error;
216 } 291 }
217 292
218 void RulesRegistry::OnExtensionUninstalled(const std::string& extension_id) { 293 void RulesRegistry::OnExtensionUninstalled(const Extension* extension) {
219 DCHECK_CURRENTLY_ON(owner_thread()); 294 DCHECK_CURRENTLY_ON(owner_thread());
220 std::string error = RemoveAllRulesNoStoreUpdate(extension_id); 295 std::string error = RemoveAllRulesNoStoreUpdate(extension->id());
221 if (!error.empty()) 296 if (!error.empty())
222 LOG(ERROR) << error; 297 LOG(ERROR) << error;
223 } 298 }
224 299
225 void RulesRegistry::OnExtensionLoaded(const std::string& extension_id) { 300 void RulesRegistry::OnExtensionLoaded(const Extension* extension) {
226 DCHECK_CURRENTLY_ON(owner_thread()); 301 DCHECK_CURRENTLY_ON(owner_thread());
227 std::vector<linked_ptr<Rule> > rules; 302 std::vector<linked_ptr<Rule>> rules;
228 GetAllRules(extension_id, &rules); 303 GetAllRules(extension->id(), &rules);
229 std::string error = AddRulesImpl(extension_id, rules); 304 const base::ListValue* value = NULL;
305 if (extension->manifest()->GetList(manifest_keys::kEventRules, &value)) {
306 std::string error =
307 AddRules(extension->id(), RulesFromManifest(value, event_name_), true);
308 if (!error.empty())
309 LOG(ERROR) << error;
310 }
311 std::string error = AddRulesImpl(extension->id(), rules);
230 if (!error.empty()) 312 if (!error.empty())
231 LOG(ERROR) << error; 313 LOG(ERROR) << error;
232 } 314 }
233 315
234 size_t RulesRegistry::GetNumberOfUsedRuleIdentifiersForTesting() const { 316 size_t RulesRegistry::GetNumberOfUsedRuleIdentifiersForTesting() const {
235 size_t entry_count = 0u; 317 size_t entry_count = 0u;
236 for (RuleIdentifiersMap::const_iterator extension = 318 for (RuleIdentifiersMap::const_iterator extension =
237 used_rule_identifiers_.begin(); 319 used_rule_identifiers_.begin();
238 extension != used_rule_identifiers_.end(); 320 extension != used_rule_identifiers_.end();
239 ++extension) { 321 ++extension) {
240 // Each extension is counted as 1 just for being there. Otherwise we miss 322 // Each extension is counted as 1 just for being there. Otherwise we miss
241 // keys with empty values. 323 // keys with empty values.
242 entry_count += 1u + extension->second.size(); 324 entry_count += 1u + extension->second.size();
243 } 325 }
244 return entry_count; 326 return entry_count;
245 } 327 }
246 328
247 void RulesRegistry::DeserializeAndAddRules( 329 void RulesRegistry::DeserializeAndAddRules(
248 const std::string& extension_id, 330 const std::string& extension_id,
249 scoped_ptr<base::Value> rules) { 331 scoped_ptr<base::Value> rules) {
250 DCHECK_CURRENTLY_ON(owner_thread()); 332 DCHECK_CURRENTLY_ON(owner_thread());
251 333
252 AddRulesNoFill(extension_id, RulesFromValue(rules.get())); 334 AddRulesNoFill(extension_id, RulesFromValue(rules.get()), false);
253 } 335 }
254 336
255 RulesRegistry::~RulesRegistry() { 337 RulesRegistry::~RulesRegistry() {
256 } 338 }
257 339
258 void RulesRegistry::MarkReady(base::Time storage_init_time) { 340 void RulesRegistry::MarkReady(base::Time storage_init_time) {
259 DCHECK_CURRENTLY_ON(owner_thread()); 341 DCHECK_CURRENTLY_ON(owner_thread());
260 342
261 if (!storage_init_time.is_null()) { 343 if (!storage_init_time.is_null()) {
262 UMA_HISTOGRAM_TIMES("Extensions.DeclarativeRulesStorageInitialization", 344 UMA_HISTOGRAM_TIMES("Extensions.DeclarativeRulesStorageInitialization",
263 base::Time::Now() - storage_init_time); 345 base::Time::Now() - storage_init_time);
264 } 346 }
265 347
266 ready_.Signal(); 348 ready_.Signal();
267 } 349 }
268 350
269 void RulesRegistry::ProcessChangedRules(const std::string& extension_id) { 351 void RulesRegistry::ProcessChangedRules(const std::string& extension_id) {
270 DCHECK_CURRENTLY_ON(owner_thread()); 352 DCHECK_CURRENTLY_ON(owner_thread());
271 353
272 DCHECK(ContainsKey(process_changed_rules_requested_, extension_id)); 354 DCHECK(ContainsKey(process_changed_rules_requested_, extension_id));
273 process_changed_rules_requested_[extension_id] = NOT_SCHEDULED_FOR_PROCESSING; 355 process_changed_rules_requested_[extension_id] = NOT_SCHEDULED_FOR_PROCESSING;
274 356
275 std::vector<linked_ptr<Rule> > new_rules; 357 std::vector<linked_ptr<Rule> > new_rules;
276 GetAllRules(extension_id, &new_rules); 358 GetAllRules(extension_id, &new_rules);
359 std::vector<linked_ptr<Rule>> rules_to_write;
360 for (auto rule : new_rules) {
361 const RuleId& rule_id = *(rule->id);
362 RulesDictionaryKey key(extension_id, rule_id);
363 // Only write rules that were added programmatically.
364 if (manifest_rules_.find(key) == manifest_rules_.end())
365 rules_to_write.push_back(rule);
366 }
not at google - send to devlin 2015/06/05 16:16:13 This is pretty wasteful. 1. GetAllRules gets |rule
danduong 2015/06/05 21:35:06 Done.
277 content::BrowserThread::PostTask( 367 content::BrowserThread::PostTask(
278 content::BrowserThread::UI, 368 content::BrowserThread::UI, FROM_HERE,
279 FROM_HERE, 369 base::Bind(&RulesCacheDelegate::WriteToStorage, cache_delegate_,
280 base::Bind(&RulesCacheDelegate::WriteToStorage, 370 extension_id, base::Passed(RulesToValue(rules_to_write))));
281 cache_delegate_,
282 extension_id,
283 base::Passed(RulesToValue(new_rules))));
284 } 371 }
285 372
286 void RulesRegistry::MaybeProcessChangedRules(const std::string& extension_id) { 373 void RulesRegistry::MaybeProcessChangedRules(const std::string& extension_id) {
287 // Read and initialize |process_changed_rules_requested_[extension_id]| if 374 // Read and initialize |process_changed_rules_requested_[extension_id]| if
288 // necessary. (Note that the insertion below will not overwrite 375 // necessary. (Note that the insertion below will not overwrite
289 // |process_changed_rules_requested_[extension_id]| if that already exists. 376 // |process_changed_rules_requested_[extension_id]| if that already exists.
290 std::pair<ProcessStateMap::iterator, bool> insertion = 377 std::pair<ProcessStateMap::iterator, bool> insertion =
291 process_changed_rules_requested_.insert(std::make_pair( 378 process_changed_rules_requested_.insert(std::make_pair(
292 extension_id, 379 extension_id,
293 browser_context_ ? NOT_SCHEDULED_FOR_PROCESSING : NEVER_PROCESS)); 380 browser_context_ ? NOT_SCHEDULED_FOR_PROCESSING : NEVER_PROCESS));
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
367 for (i = identifiers.begin(); i != identifiers.end(); ++i) 454 for (i = identifiers.begin(); i != identifiers.end(); ++i)
368 used_rule_identifiers_[extension_id].erase(*i); 455 used_rule_identifiers_[extension_id].erase(*i);
369 } 456 }
370 457
371 void RulesRegistry::RemoveAllUsedRuleIdentifiers( 458 void RulesRegistry::RemoveAllUsedRuleIdentifiers(
372 const std::string& extension_id) { 459 const std::string& extension_id) {
373 used_rule_identifiers_.erase(extension_id); 460 used_rule_identifiers_.erase(extension_id);
374 } 461 }
375 462
376 } // namespace extensions 463 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698