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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: extensions/browser/api/declarative/rules_registry.cc
diff --git a/extensions/browser/api/declarative/rules_registry.cc b/extensions/browser/api/declarative/rules_registry.cc
index dfd9c35260ace0ea706aa383d78d355c8177e57b..8dbeede61ab09ebea8925acf16c27c194efbe338 100644
--- a/extensions/browser/api/declarative/rules_registry.cc
+++ b/extensions/browser/api/declarative/rules_registry.cc
@@ -19,26 +19,31 @@
#include "content/public/browser/notification_source.h"
#include "extensions/browser/api/declarative/rules_cache_delegate.h"
#include "extensions/browser/extension_prefs.h"
+#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extension_system.h"
#include "extensions/browser/state_store.h"
#include "extensions/common/extension.h"
+#include "extensions/common/manifest_constants.h"
+
+namespace extensions {
namespace {
const char kSuccess[] = "";
const char kDuplicateRuleId[] = "Duplicate rule ID: %s";
+const char kErrorNonRemovableRules[] = "List contains non-removable rules";
scoped_ptr<base::Value> RulesToValue(
- const std::vector<linked_ptr<extensions::RulesRegistry::Rule> >& rules) {
+ const std::vector<linked_ptr<RulesRegistry::Rule>>& rules) {
scoped_ptr<base::ListValue> list(new base::ListValue());
for (size_t i = 0; i < rules.size(); ++i)
list->Append(rules[i]->ToValue().release());
return list.Pass();
}
-std::vector<linked_ptr<extensions::RulesRegistry::Rule> > RulesFromValue(
+std::vector<linked_ptr<RulesRegistry::Rule>> RulesFromValue(
const base::Value* value) {
- std::vector<linked_ptr<extensions::RulesRegistry::Rule> > rules;
+ std::vector<linked_ptr<RulesRegistry::Rule>> rules;
const base::ListValue* list = NULL;
if (!value || !value->GetAsList(&list))
@@ -49,9 +54,67 @@ std::vector<linked_ptr<extensions::RulesRegistry::Rule> > RulesFromValue(
const base::DictionaryValue* dict = NULL;
if (!list->GetDictionary(i, &dict))
continue;
- linked_ptr<extensions::RulesRegistry::Rule> rule(
- new extensions::RulesRegistry::Rule());
- if (extensions::RulesRegistry::Rule::Populate(*dict, rule.get()))
+ linked_ptr<RulesRegistry::Rule> rule(new RulesRegistry::Rule());
+ if (RulesRegistry::Rule::Populate(*dict, rule.get()))
+ rules.push_back(rule);
+ }
+
+ return rules;
+}
+
+scoped_ptr<base::ListValue> ConvertListFromManifest(
+ const base::ListValue* list) {
+ scoped_ptr<base::ListValue> result(new base::ListValue);
+ for (base::ListValue::const_iterator it = list->begin(); it != list->end();
+ ++it) {
+ base::DictionaryValue* dictionary = nullptr;
+ if (!(*it)->GetAsDictionary(&dictionary))
+ continue;
+ std::string type;
+ if (!dictionary->GetString("type", &type))
+ continue;
+ scoped_ptr<base::DictionaryValue> copy = dictionary->CreateDeepCopy();
+ copy->Remove("type", NULL);
+ copy->SetString("instanceType", type);
+ result->Append(copy.Pass());
+ }
+ return result.Pass();
+}
+
+std::vector<linked_ptr<RulesRegistry::Rule>> RulesFromManifest(
+ const base::Value* value,
+ const std::string& event_name) {
+ std::vector<linked_ptr<RulesRegistry::Rule>> rules;
+
+ const base::ListValue* list = nullptr;
+ if (!value || !value->GetAsList(&list))
+ return rules;
+
+ for (size_t i = 0; i < list->GetSize(); ++i) {
+ const base::DictionaryValue* dict = nullptr;
+ if (!list->GetDictionary(i, &dict))
+ continue;
+ std::string event;
+ if (!dict->GetString("event", &event))
+ continue;
+ if (event_name != event)
+ continue;
+ const base::ListValue* list;
+ if (!dict->GetList("conditions", &list) || !list->GetSize())
+ continue;
+ scoped_ptr<base::ListValue> conditions = ConvertListFromManifest(list);
+ if (!conditions->GetSize())
+ continue;
+ if (!dict->GetList("actions", &list) || !list->GetSize())
+ continue;
+ scoped_ptr<base::ListValue> actions = ConvertListFromManifest(list);
+ if (!actions->GetSize())
+ continue;
+ scoped_ptr<base::DictionaryValue> rule_dict(new base::DictionaryValue);
+ rule_dict->Set("conditions", conditions.Pass());
+ rule_dict->Set("actions", actions.Pass());
+ linked_ptr<RulesRegistry::Rule> rule(new RulesRegistry::Rule());
+ if (RulesRegistry::Rule::Populate(*rule_dict, rule.get()))
rules.push_back(rule);
}
@@ -65,8 +128,6 @@ std::string ToId(int identifier) {
} // namespace
-namespace extensions {
-
// RulesRegistry
RulesRegistry::RulesRegistry(content::BrowserContext* browser_context,
@@ -90,7 +151,8 @@ RulesRegistry::RulesRegistry(content::BrowserContext* browser_context,
std::string RulesRegistry::AddRulesNoFill(
const std::string& extension_id,
- const std::vector<linked_ptr<Rule> >& rules) {
+ const std::vector<linked_ptr<Rule>>& rules,
+ bool from_manifest) {
DCHECK_CURRENTLY_ON(owner_thread());
// Verify that all rule IDs are new.
@@ -100,6 +162,8 @@ std::string RulesRegistry::AddRulesNoFill(
// Every rule should have a priority assigned.
DCHECK((*i)->priority);
RulesDictionaryKey key(extension_id, rule_id);
+ if (from_manifest)
+ manifest_rule_ids_.insert(key);
if (rules_.find(key) != rules_.end())
return base::StringPrintf(kDuplicateRuleId, rule_id.c_str());
}
@@ -121,9 +185,9 @@ std::string RulesRegistry::AddRulesNoFill(
return kSuccess;
}
-std::string RulesRegistry::AddRules(
- const std::string& extension_id,
- const std::vector<linked_ptr<Rule> >& rules) {
+std::string RulesRegistry::AddRules(const std::string& extension_id,
+ const std::vector<linked_ptr<Rule>>& rules,
+ bool from_manifest) {
DCHECK_CURRENTLY_ON(owner_thread());
std::string error = CheckAndFillInOptionalRules(extension_id, rules);
@@ -131,7 +195,7 @@ std::string RulesRegistry::AddRules(
return error;
FillInOptionalPriorities(rules);
- return AddRulesNoFill(extension_id, rules);
+ return AddRulesNoFill(extension_id, rules, from_manifest);
}
std::string RulesRegistry::RemoveRules(
@@ -139,6 +203,14 @@ std::string RulesRegistry::RemoveRules(
const std::vector<std::string>& rule_identifiers) {
DCHECK_CURRENTLY_ON(owner_thread());
+ // Check if any of the rules are non-removable.
+ for (RuleId rule_id : rule_identifiers) {
+ RulesDictionaryKey lookup_key(extension_id, rule_id);
+ RuleIdSet::iterator itr = manifest_rule_ids_.find(lookup_key);
+ if (itr != manifest_rule_ids_.end())
+ return kErrorNonRemovableRules;
+ }
+
std::string error = RemoveRulesImpl(extension_id, rule_identifiers);
if (!error.empty())
@@ -175,8 +247,10 @@ std::string RulesRegistry::RemoveAllRulesNoStoreUpdate(
i != rules_.end();) {
const RulesDictionaryKey& key = i->first;
++i;
- if (key.first == extension_id)
+ if (key.first == extension_id) {
rules_.erase(key);
+ manifest_rule_ids_.erase(key);
+ }
}
RemoveAllUsedRuleIdentifiers(extension_id);
@@ -224,7 +298,17 @@ void RulesRegistry::OnExtensionUninstalled(const std::string& extension_id) {
void RulesRegistry::OnExtensionLoaded(const std::string& extension_id) {
DCHECK_CURRENTLY_ON(owner_thread());
- std::vector<linked_ptr<Rule> > rules;
+ const Extension* extension =
+ ExtensionRegistry::Get(browser_context())
+ ->GetExtensionById(extension_id, ExtensionRegistry::EVERYTHING);
+ const base::ListValue* value = NULL;
+ if (extension->manifest()->GetList(manifest_keys::kEventRules, &value)) {
+ std::string error =
+ AddRules(extension_id, RulesFromManifest(value, event_name_), true);
+ if (!error.empty())
+ LOG(ERROR) << error;
+ }
+ std::vector<linked_ptr<Rule>> rules;
GetAllRules(extension_id, &rules);
std::string error = AddRulesImpl(extension_id, rules);
if (!error.empty())
@@ -249,7 +333,7 @@ void RulesRegistry::DeserializeAndAddRules(
scoped_ptr<base::Value> rules) {
DCHECK_CURRENTLY_ON(owner_thread());
- AddRulesNoFill(extension_id, RulesFromValue(rules.get()));
+ AddRulesNoFill(extension_id, RulesFromValue(rules.get()), false);
}
RulesRegistry::~RulesRegistry() {
@@ -274,13 +358,18 @@ void RulesRegistry::ProcessChangedRules(const std::string& extension_id) {
std::vector<linked_ptr<Rule> > new_rules;
GetAllRules(extension_id, &new_rules);
+ std::vector<linked_ptr<Rule>> rules_to_write;
+ for (auto rule : new_rules) {
+ const RuleId& rule_id = *(rule->id);
+ RulesDictionaryKey key(extension_id, rule_id);
+ // Only write rules that were added programmatically.
+ if (manifest_rule_ids_.find(key) == manifest_rule_ids_.end())
+ rules_to_write.push_back(rule);
+ }
content::BrowserThread::PostTask(
- content::BrowserThread::UI,
- FROM_HERE,
- base::Bind(&RulesCacheDelegate::WriteToStorage,
- cache_delegate_,
- extension_id,
- base::Passed(RulesToValue(new_rules))));
+ content::BrowserThread::UI, FROM_HERE,
+ base::Bind(&RulesCacheDelegate::WriteToStorage, cache_delegate_,
+ extension_id, base::Passed(RulesToValue(rules_to_write))));
}
void RulesRegistry::MaybeProcessChangedRules(const std::string& extension_id) {

Powered by Google App Engine
This is Rietveld 408576698