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                                           bool is_update) {
72  DCHECK(GenerateInstalledExtensionsSet()->Contains(extension->id()));
73  FOR_EACH_OBSERVER(ExtensionRegistryObserver,
74                    observers_,
75                    OnExtensionInstalled(
76                        browser_context_, extension, is_update));
77}
78
79void ExtensionRegistry::TriggerOnUninstalled(const Extension* extension,
80                                             UninstallReason reason) {
81  DCHECK(!GenerateInstalledExtensionsSet()->Contains(extension->id()));
82  FOR_EACH_OBSERVER(
83      ExtensionRegistryObserver,
84      observers_,
85      OnExtensionUninstalled(browser_context_, extension, reason));
86}
87
88const Extension* ExtensionRegistry::GetExtensionById(const std::string& id,
89                                                     int include_mask) const {
90  std::string lowercase_id = base::StringToLowerASCII(id);
91  if (include_mask & ENABLED) {
92    const Extension* extension = enabled_extensions_.GetByID(lowercase_id);
93    if (extension)
94      return extension;
95  }
96  if (include_mask & DISABLED) {
97    const Extension* extension = disabled_extensions_.GetByID(lowercase_id);
98    if (extension)
99      return extension;
100  }
101  if (include_mask & TERMINATED) {
102    const Extension* extension = terminated_extensions_.GetByID(lowercase_id);
103    if (extension)
104      return extension;
105  }
106  if (include_mask & BLACKLISTED) {
107    const Extension* extension = blacklisted_extensions_.GetByID(lowercase_id);
108    if (extension)
109      return extension;
110  }
111  return NULL;
112}
113
114bool ExtensionRegistry::AddEnabled(
115    const scoped_refptr<const Extension>& extension) {
116  return enabled_extensions_.Insert(extension);
117}
118
119bool ExtensionRegistry::RemoveEnabled(const std::string& id) {
120  return enabled_extensions_.Remove(id);
121}
122
123bool ExtensionRegistry::AddDisabled(
124    const scoped_refptr<const Extension>& extension) {
125  return disabled_extensions_.Insert(extension);
126}
127
128bool ExtensionRegistry::RemoveDisabled(const std::string& id) {
129  return disabled_extensions_.Remove(id);
130}
131
132bool ExtensionRegistry::AddTerminated(
133    const scoped_refptr<const Extension>& extension) {
134  return terminated_extensions_.Insert(extension);
135}
136
137bool ExtensionRegistry::RemoveTerminated(const std::string& id) {
138  return terminated_extensions_.Remove(id);
139}
140
141bool ExtensionRegistry::AddBlacklisted(
142    const scoped_refptr<const Extension>& extension) {
143  return blacklisted_extensions_.Insert(extension);
144}
145
146bool ExtensionRegistry::RemoveBlacklisted(const std::string& id) {
147  return blacklisted_extensions_.Remove(id);
148}
149
150void ExtensionRegistry::ClearAll() {
151  enabled_extensions_.Clear();
152  disabled_extensions_.Clear();
153  terminated_extensions_.Clear();
154  blacklisted_extensions_.Clear();
155}
156
157void ExtensionRegistry::SetDisabledModificationCallback(
158    const ExtensionSet::ModificationCallback& callback) {
159  disabled_extensions_.set_modification_callback(callback);
160}
161
162void ExtensionRegistry::Shutdown() {
163  // Release references to all Extension objects in the sets.
164  ClearAll();
165  FOR_EACH_OBSERVER(ExtensionRegistryObserver, observers_, OnShutdown(this));
166}
167
168}  // namespace extensions
169