1// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "extensions/browser/extension_registry.h"
6
7#include "base/strings/string_util.h"
8#include "extensions/browser/extension_registry_factory.h"
9#include "extensions/browser/extension_registry_observer.h"
10
11namespace extensions {
12
13ExtensionRegistry::ExtensionRegistry(content::BrowserContext* browser_context)
14    : browser_context_(browser_context) {}
15ExtensionRegistry::~ExtensionRegistry() {}
16
17// static
18ExtensionRegistry* ExtensionRegistry::Get(content::BrowserContext* context) {
19  return ExtensionRegistryFactory::GetForBrowserContext(context);
20}
21
22scoped_ptr<ExtensionSet> ExtensionRegistry::GenerateInstalledExtensionsSet()
23    const {
24  scoped_ptr<ExtensionSet> installed_extensions(new ExtensionSet);
25  installed_extensions->InsertAll(enabled_extensions_);
26  installed_extensions->InsertAll(disabled_extensions_);
27  installed_extensions->InsertAll(terminated_extensions_);
28  installed_extensions->InsertAll(blacklisted_extensions_);
29  return installed_extensions.Pass();
30}
31
32void ExtensionRegistry::AddObserver(ExtensionRegistryObserver* observer) {
33  observers_.AddObserver(observer);
34}
35
36void ExtensionRegistry::RemoveObserver(ExtensionRegistryObserver* observer) {
37  observers_.RemoveObserver(observer);
38}
39
40void ExtensionRegistry::TriggerOnLoaded(const Extension* extension) {
41  DCHECK(enabled_extensions_.Contains(extension->id()));
42  FOR_EACH_OBSERVER(ExtensionRegistryObserver,
43                    observers_,
44                    OnExtensionLoaded(browser_context_, extension));
45}
46
47void ExtensionRegistry::TriggerOnUnloaded(
48    const Extension* extension,
49    UnloadedExtensionInfo::Reason reason) {
50  DCHECK(!enabled_extensions_.Contains(extension->id()));
51  FOR_EACH_OBSERVER(ExtensionRegistryObserver,
52                    observers_,
53                    OnExtensionUnloaded(browser_context_, extension, reason));
54}
55
56void ExtensionRegistry::TriggerOnWillBeInstalled(const Extension* extension,
57                                                 bool is_update,
58                                                 bool from_ephemeral,
59                                                 const std::string& old_name) {
60  DCHECK(is_update ==
61         GenerateInstalledExtensionsSet()->Contains(extension->id()));
62  DCHECK(is_update == !old_name.empty());
63  FOR_EACH_OBSERVER(
64      ExtensionRegistryObserver,
65      observers_,
66      OnExtensionWillBeInstalled(
67          browser_context_, extension, is_update, from_ephemeral, old_name));
68}
69
70void ExtensionRegistry::TriggerOnInstalled(const Extension* extension) {
71  DCHECK(GenerateInstalledExtensionsSet()->Contains(extension->id()));
72  FOR_EACH_OBSERVER(ExtensionRegistryObserver,
73                    observers_,
74                    OnExtensionInstalled(browser_context_, extension));
75}
76
77void ExtensionRegistry::TriggerOnUninstalled(const Extension* extension) {
78  DCHECK(!GenerateInstalledExtensionsSet()->Contains(extension->id()));
79  FOR_EACH_OBSERVER(ExtensionRegistryObserver,
80                    observers_,
81                    OnExtensionUninstalled(browser_context_, extension));
82}
83
84const Extension* ExtensionRegistry::GetExtensionById(const std::string& id,
85                                                     int include_mask) const {
86  std::string lowercase_id = StringToLowerASCII(id);
87  if (include_mask & ENABLED) {
88    const Extension* extension = enabled_extensions_.GetByID(lowercase_id);
89    if (extension)
90      return extension;
91  }
92  if (include_mask & DISABLED) {
93    const Extension* extension = disabled_extensions_.GetByID(lowercase_id);
94    if (extension)
95      return extension;
96  }
97  if (include_mask & TERMINATED) {
98    const Extension* extension = terminated_extensions_.GetByID(lowercase_id);
99    if (extension)
100      return extension;
101  }
102  if (include_mask & BLACKLISTED) {
103    const Extension* extension = blacklisted_extensions_.GetByID(lowercase_id);
104    if (extension)
105      return extension;
106  }
107  return NULL;
108}
109
110bool ExtensionRegistry::AddEnabled(
111    const scoped_refptr<const Extension>& extension) {
112  return enabled_extensions_.Insert(extension);
113}
114
115bool ExtensionRegistry::RemoveEnabled(const std::string& id) {
116  return enabled_extensions_.Remove(id);
117}
118
119bool ExtensionRegistry::AddDisabled(
120    const scoped_refptr<const Extension>& extension) {
121  return disabled_extensions_.Insert(extension);
122}
123
124bool ExtensionRegistry::RemoveDisabled(const std::string& id) {
125  return disabled_extensions_.Remove(id);
126}
127
128bool ExtensionRegistry::AddTerminated(
129    const scoped_refptr<const Extension>& extension) {
130  return terminated_extensions_.Insert(extension);
131}
132
133bool ExtensionRegistry::RemoveTerminated(const std::string& id) {
134  return terminated_extensions_.Remove(id);
135}
136
137bool ExtensionRegistry::AddBlacklisted(
138    const scoped_refptr<const Extension>& extension) {
139  return blacklisted_extensions_.Insert(extension);
140}
141
142bool ExtensionRegistry::RemoveBlacklisted(const std::string& id) {
143  return blacklisted_extensions_.Remove(id);
144}
145
146void ExtensionRegistry::ClearAll() {
147  enabled_extensions_.Clear();
148  disabled_extensions_.Clear();
149  terminated_extensions_.Clear();
150  blacklisted_extensions_.Clear();
151}
152
153void ExtensionRegistry::SetDisabledModificationCallback(
154    const ExtensionSet::ModificationCallback& callback) {
155  disabled_extensions_.set_modification_callback(callback);
156}
157
158void ExtensionRegistry::Shutdown() {
159  // Release references to all Extension objects in the sets.
160  ClearAll();
161  FOR_EACH_OBSERVER(ExtensionRegistryObserver, observers_, OnShutdown(this));
162}
163
164}  // namespace extensions
165