Chromium Code Reviews| Index: chrome/browser/extensions/api/declarative/rules_registry_service.cc |
| diff --git a/chrome/browser/extensions/api/declarative/rules_registry_service.cc b/chrome/browser/extensions/api/declarative/rules_registry_service.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..833ead4c2ee9d72bf37b83ac5073bc07e6a248d7 |
| --- /dev/null |
| +++ b/chrome/browser/extensions/api/declarative/rules_registry_service.cc |
| @@ -0,0 +1,164 @@ |
| +// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "chrome/browser/extensions/api/declarative/rules_registry_service.h" |
| + |
| +#include "base/callback.h" |
| +#include "base/logging.h" |
| +#include "base/stl_util.h" |
| +#include "base/string_number_conversions.h" |
| +#include "chrome/browser/extensions/api/declarative/declarative_api_constants.h" |
| +#include "chrome/browser/extensions/api/declarative/rule_identifier.h" |
| +#include "chrome/common/chrome_notification_types.h" |
| +#include "chrome/common/extensions/extension.h" |
| +#include "content/public/browser/notification_details.h" |
| +#include "content/public/browser/notification_source.h" |
| + |
| +namespace keys = extension_declarative_api_constants; |
| + |
| +namespace { |
| + std::string ToId(int identifier) { |
| + return "_" + base::IntToString(identifier) + "_"; |
| + } |
| +} |
| + |
| +namespace extensions { |
| + |
| +RulesRegistryService::RulesRegistryService() |
| + : last_generated_rule_identifier_id_(0) { |
| +} |
| + |
| +RulesRegistryService::~RulesRegistryService() { |
| + STLDeleteContainerPairSecondPointers( |
| + rule_registries_.begin(), rule_registries_.end()); |
|
not at google - send to devlin
2012/02/02 11:59:16
if you make RulesRegistryMap contain linked_ptrs,
battre
2012/02/02 19:12:36
Done.
|
| +} |
| + |
| +void RulesRegistryService::Init(Profile* profile) { |
| + registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, |
| + content::Source<Profile>(profile)); |
| + |
| + // TODO(battre): Register various rules registries here. |
| + // RegisterRuleRegistry("chrome.net", new FoobarRulesRegistry()); |
|
not at google - send to devlin
2012/02/02 11:59:16
Yeah, if you make this owned by a Profile or Exten
battre
2012/02/06 16:21:04
Done.
|
| +} |
| + |
| +void RulesRegistryService::RegisterRuleRegistry( |
| + const std::string& event_name, |
| + scoped_ptr<RulesRegistry> rule_registry) { |
| + DCHECK(rule_registries_.find(event_name) == rule_registries_.end()); |
| + rule_registries_[event_name] = rule_registry.release(); |
| +} |
| + |
| +bool RulesRegistryService::IsUniqueId(const RuleIdentifier& id) const { |
|
Aaron Boodman
2012/02/02 16:28:51
nit: Prefer "ID" (capitalized).
battre
2012/02/02 19:12:36
I did a check of
grep -r "[ ,.>]ID[ ()]" chrome
vs
|
| + return used_rule_identifiers_.find(id) == used_rule_identifiers_.end(); |
| +} |
| + |
| +std::string RulesRegistryService::GenerateUniqueId( |
| + std::string extension_id, std::string event_name) { |
| + while ( |
| + !IsUniqueId( |
| + RuleIdentifier(extension_id, |
| + event_name, |
| + ToId(last_generated_rule_identifier_id_)))) { |
| + ++last_generated_rule_identifier_id_; |
| + } |
| + RuleIdentifier new_id(extension_id, |
| + event_name, |
| + ToId(last_generated_rule_identifier_id_)); |
| + used_rule_identifiers_.insert(new_id); |
| + return new_id.rule_id(); |
| +} |
| + |
| +bool RulesRegistryService::CheckAndFillInOptionalRules( |
| + const std::string& event_name, |
| + const std::string& extension_id, |
| + const std::vector<DictionaryValue*>& rules, |
| + RulesRegistry::SetErrorCallback set_error_callback) { |
| + std::vector<DictionaryValue*>::const_iterator i; |
| + for (i = rules.begin(); i != rules.end(); ++i) { |
| + DictionaryValue* rule = *i; |
| + if (rule->HasKey(keys::kId)) { |
| + std::string id; |
| + CHECK(rule->GetString(keys::kId, &id)); |
| + if (!IsUniqueId(RuleIdentifier(extension_id, event_name, id))) { |
| + set_error_callback.Run("Id " + id + " was used multiple times."); |
| + return false; |
| + } |
| + } else { |
| + std::string id = GenerateUniqueId(extension_id, event_name); |
| + rule->SetString(keys::kId, id); |
| + } |
| + } |
| + return true; |
| +} |
| + |
| +void RulesRegistryService::FillInOptionalPriorities( |
| + const std::vector<DictionaryValue*>& rules) { |
| + std::vector<DictionaryValue*>::const_iterator i; |
| + for (i = rules.begin(); i != rules.end(); ++i) { |
| + DictionaryValue* rule = *i; |
| + if (!rule->HasKey(keys::kPriority)) |
| + rule->SetInteger(keys::kPriority, 100); |
| + } |
| +} |
| + |
| +bool RulesRegistryService::AddRules( |
| + const std::string& event_name, |
| + const std::string& extension_id, |
| + const std::vector<DictionaryValue*>& rules, |
| + RulesRegistry::SetErrorCallback set_error_callback) { |
| + DCHECK(rule_registries_.find(event_name) != rule_registries_.end()); |
| + if (!CheckAndFillInOptionalRules(event_name, extension_id, rules, |
| + set_error_callback)) { |
| + return false; |
| + } |
| + FillInOptionalPriorities(rules); |
| + |
| + return rule_registries_[event_name]->AddRules( |
| + extension_id, rules, set_error_callback); |
| +} |
| + |
| +bool RulesRegistryService::RemoveRules( |
| + const std::string& event_name, |
| + const std::string& extension_id, |
| + const std::vector<std::string>& rule_identifiers, |
| + RulesRegistry::SetErrorCallback set_error_callback) { |
| + DCHECK(rule_registries_.find(event_name) != rule_registries_.end()); |
| + // TODO(battre): Free rule_identifiers_; |
| + return rule_registries_[event_name]->RemoveRules( |
| + extension_id, rule_identifiers, set_error_callback); |
| +} |
| + |
| +void RulesRegistryService::GetRules( |
| + const std::string& event_name, |
| + const std::string& extension_id, |
| + const std::vector<std::string>& rule_identifiers, |
| + std::vector<DictionaryValue*>* out) { |
| + DCHECK(rule_registries_.find(event_name) != rule_registries_.end()); |
| + rule_registries_[event_name]->GetRules(extension_id, rule_identifiers, out); |
| +} |
| + |
| +void RulesRegistryService::OnExtensionUnloaded( |
| + const std::string& extension_id) { |
| + RulesRegistryMap::iterator i; |
| + for (i = rule_registries_.begin(); i != rule_registries_.end(); ++i) |
| + i->second->OnExtensionUnloaded(extension_id); |
| +} |
| + |
| +void RulesRegistryService::Observe( |
| + int type, |
| + const content::NotificationSource& source, |
| + const content::NotificationDetails& details) { |
| + switch (type) { |
| + case chrome::NOTIFICATION_EXTENSION_UNLOADED: { |
| + const Extension* extension = |
| + content::Details<UnloadedExtensionInfo>(details)->extension; |
| + OnExtensionUnloaded(extension->id()); |
| + break; |
| + } |
| + default: |
| + NOTREACHED(); |
| + } |
| +} |
| + |
| +} // namespace extensions |