15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file.
45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_registry.h"
65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/strings/string_util.h"
85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_registry_factory.h"
95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_registry_observer.h"
105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace extensions {
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
13c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochExtensionRegistry::ExtensionRegistry(content::BrowserContext* browser_context)
14c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    : browser_context_(browser_context) {}
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ExtensionRegistry::~ExtensionRegistry() {}
165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// static
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ExtensionRegistry* ExtensionRegistry::Get(content::BrowserContext* context) {
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return ExtensionRegistryFactory::GetForBrowserContext(context);
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)scoped_ptr<ExtensionSet> ExtensionRegistry::GenerateInstalledExtensionsSet()
2323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    const {
2423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  scoped_ptr<ExtensionSet> installed_extensions(new ExtensionSet);
2523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  installed_extensions->InsertAll(enabled_extensions_);
2623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  installed_extensions->InsertAll(disabled_extensions_);
2723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  installed_extensions->InsertAll(terminated_extensions_);
2823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  installed_extensions->InsertAll(blacklisted_extensions_);
2923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  return installed_extensions.Pass();
3023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
3123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ExtensionRegistry::AddObserver(ExtensionRegistryObserver* observer) {
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  observers_.AddObserver(observer);
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ExtensionRegistry::RemoveObserver(ExtensionRegistryObserver* observer) {
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  observers_.RemoveObserver(observer);
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
40effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid ExtensionRegistry::TriggerOnLoaded(const Extension* extension) {
41effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK(enabled_extensions_.Contains(extension->id()));
42c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  FOR_EACH_OBSERVER(ExtensionRegistryObserver,
43c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                    observers_,
44c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                    OnExtensionLoaded(browser_context_, extension));
45effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
46effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid ExtensionRegistry::TriggerOnUnloaded(
480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const Extension* extension,
490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    UnloadedExtensionInfo::Reason reason) {
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(!enabled_extensions_.Contains(extension->id()));
51c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  FOR_EACH_OBSERVER(ExtensionRegistryObserver,
52c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                    observers_,
530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                    OnExtensionUnloaded(browser_context_, extension, reason));
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
56cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ExtensionRegistry::TriggerOnWillBeInstalled(const Extension* extension,
57cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                                 bool is_update,
58cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                                 bool from_ephemeral,
59cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                                 const std::string& old_name) {
60cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(is_update ==
61cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)         GenerateInstalledExtensionsSet()->Contains(extension->id()));
62cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(is_update == !old_name.empty());
63cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FOR_EACH_OBSERVER(
64cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      ExtensionRegistryObserver,
65cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      observers_,
66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      OnExtensionWillBeInstalled(
67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          browser_context_, extension, is_update, from_ephemeral, old_name));
68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
70116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid ExtensionRegistry::TriggerOnInstalled(const Extension* extension,
71116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                           bool is_update) {
72f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DCHECK(GenerateInstalledExtensionsSet()->Contains(extension->id()));
73f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  FOR_EACH_OBSERVER(ExtensionRegistryObserver,
74f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                    observers_,
75116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                    OnExtensionInstalled(
76116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        browser_context_, extension, is_update));
77f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
78f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void ExtensionRegistry::TriggerOnUninstalled(const Extension* extension,
805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                             UninstallReason reason) {
81cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(!GenerateInstalledExtensionsSet()->Contains(extension->id()));
825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  FOR_EACH_OBSERVER(
835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      ExtensionRegistryObserver,
845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      observers_,
855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      OnExtensionUninstalled(browser_context_, extension, reason));
86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
87cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const Extension* ExtensionRegistry::GetExtensionById(const std::string& id,
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                                     int include_mask) const {
906e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  std::string lowercase_id = base::StringToLowerASCII(id);
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (include_mask & ENABLED) {
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const Extension* extension = enabled_extensions_.GetByID(lowercase_id);
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (extension)
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return extension;
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (include_mask & DISABLED) {
975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const Extension* extension = disabled_extensions_.GetByID(lowercase_id);
985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (extension)
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return extension;
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (include_mask & TERMINATED) {
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const Extension* extension = terminated_extensions_.GetByID(lowercase_id);
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (extension)
1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return extension;
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (include_mask & BLACKLISTED) {
1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const Extension* extension = blacklisted_extensions_.GetByID(lowercase_id);
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (extension)
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return extension;
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return NULL;
1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool ExtensionRegistry::AddEnabled(
1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const scoped_refptr<const Extension>& extension) {
1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return enabled_extensions_.Insert(extension);
1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool ExtensionRegistry::RemoveEnabled(const std::string& id) {
1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return enabled_extensions_.Remove(id);
1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool ExtensionRegistry::AddDisabled(
1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const scoped_refptr<const Extension>& extension) {
1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return disabled_extensions_.Insert(extension);
1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool ExtensionRegistry::RemoveDisabled(const std::string& id) {
1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return disabled_extensions_.Remove(id);
1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool ExtensionRegistry::AddTerminated(
1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const scoped_refptr<const Extension>& extension) {
1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return terminated_extensions_.Insert(extension);
1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool ExtensionRegistry::RemoveTerminated(const std::string& id) {
1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return terminated_extensions_.Remove(id);
1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool ExtensionRegistry::AddBlacklisted(
1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const scoped_refptr<const Extension>& extension) {
1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return blacklisted_extensions_.Insert(extension);
1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool ExtensionRegistry::RemoveBlacklisted(const std::string& id) {
1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return blacklisted_extensions_.Remove(id);
1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ExtensionRegistry::ClearAll() {
1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  enabled_extensions_.Clear();
1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  disabled_extensions_.Clear();
1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  terminated_extensions_.Clear();
1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  blacklisted_extensions_.Clear();
1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ExtensionRegistry::SetDisabledModificationCallback(
1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const ExtensionSet::ModificationCallback& callback) {
1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  disabled_extensions_.set_modification_callback(callback);
1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ExtensionRegistry::Shutdown() {
1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Release references to all Extension objects in the sets.
1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ClearAll();
16546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  FOR_EACH_OBSERVER(ExtensionRegistryObserver, observers_, OnShutdown(this));
1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace extensions
169