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
11 namespace extensions {
12
ExtensionRegistry(content::BrowserContext * browser_context)13 ExtensionRegistry::ExtensionRegistry(content::BrowserContext* browser_context)
14 : browser_context_(browser_context) {}
~ExtensionRegistry()15 ExtensionRegistry::~ExtensionRegistry() {}
16
17 // static
Get(content::BrowserContext * context)18 ExtensionRegistry* ExtensionRegistry::Get(content::BrowserContext* context) {
19 return ExtensionRegistryFactory::GetForBrowserContext(context);
20 }
21
22 std::unique_ptr<ExtensionSet>
GenerateInstalledExtensionsSet() const23 ExtensionRegistry::GenerateInstalledExtensionsSet() const {
24 return GenerateInstalledExtensionsSet(EVERYTHING);
25 }
26
GenerateInstalledExtensionsSet(int include_mask) const27 std::unique_ptr<ExtensionSet> ExtensionRegistry::GenerateInstalledExtensionsSet(
28 int include_mask) const {
29 std::unique_ptr<ExtensionSet> installed_extensions(new ExtensionSet);
30 if (include_mask & IncludeFlag::ENABLED)
31 installed_extensions->InsertAll(enabled_extensions_);
32 if (include_mask & IncludeFlag::DISABLED)
33 installed_extensions->InsertAll(disabled_extensions_);
34 if (include_mask & IncludeFlag::TERMINATED)
35 installed_extensions->InsertAll(terminated_extensions_);
36 if (include_mask & IncludeFlag::BLOCKLISTED)
37 installed_extensions->InsertAll(blocklisted_extensions_);
38 if (include_mask & IncludeFlag::BLOCKED)
39 installed_extensions->InsertAll(blocked_extensions_);
40 return installed_extensions;
41 }
42
GetStoredVersion(const ExtensionId & id) const43 base::Version ExtensionRegistry::GetStoredVersion(const ExtensionId& id) const {
44 int include_mask = ExtensionRegistry::ENABLED | ExtensionRegistry::DISABLED |
45 ExtensionRegistry::TERMINATED |
46 ExtensionRegistry::BLOCKLISTED |
47 ExtensionRegistry::BLOCKED;
48 const Extension* registry_extension = GetExtensionById(id, include_mask);
49 return registry_extension ? registry_extension->version() : base::Version();
50 }
51
AddObserver(ExtensionRegistryObserver * observer)52 void ExtensionRegistry::AddObserver(ExtensionRegistryObserver* observer) {
53 observers_.AddObserver(observer);
54 }
55
RemoveObserver(ExtensionRegistryObserver * observer)56 void ExtensionRegistry::RemoveObserver(ExtensionRegistryObserver* observer) {
57 observers_.RemoveObserver(observer);
58 }
59
TriggerOnLoaded(const Extension * extension)60 void ExtensionRegistry::TriggerOnLoaded(const Extension* extension) {
61 CHECK(extension);
62 DCHECK(enabled_extensions_.Contains(extension->id()));
63 for (auto& observer : observers_)
64 observer.OnExtensionLoaded(browser_context_, extension);
65 }
66
TriggerOnReady(const Extension * extension)67 void ExtensionRegistry::TriggerOnReady(const Extension* extension) {
68 CHECK(extension);
69 DCHECK(enabled_extensions_.Contains(extension->id()));
70 for (auto& observer : observers_)
71 observer.OnExtensionReady(browser_context_, extension);
72 }
73
TriggerOnUnloaded(const Extension * extension,UnloadedExtensionReason reason)74 void ExtensionRegistry::TriggerOnUnloaded(const Extension* extension,
75 UnloadedExtensionReason reason) {
76 CHECK(extension);
77 DCHECK(!enabled_extensions_.Contains(extension->id()));
78 for (auto& observer : observers_)
79 observer.OnExtensionUnloaded(browser_context_, extension, reason);
80 }
81
TriggerOnWillBeInstalled(const Extension * extension,bool is_update,const std::string & old_name)82 void ExtensionRegistry::TriggerOnWillBeInstalled(const Extension* extension,
83 bool is_update,
84 const std::string& old_name) {
85 CHECK(extension);
86 DCHECK_EQ(is_update,
87 GenerateInstalledExtensionsSet()->Contains(extension->id()));
88 DCHECK_EQ(is_update, !old_name.empty());
89 for (auto& observer : observers_)
90 observer.OnExtensionWillBeInstalled(browser_context_, extension, is_update,
91 old_name);
92 }
93
TriggerOnInstalled(const Extension * extension,bool is_update)94 void ExtensionRegistry::TriggerOnInstalled(const Extension* extension,
95 bool is_update) {
96 CHECK(extension);
97 DCHECK(GenerateInstalledExtensionsSet()->Contains(extension->id()));
98 for (auto& observer : observers_)
99 observer.OnExtensionInstalled(browser_context_, extension, is_update);
100 }
101
TriggerOnUninstalled(const Extension * extension,UninstallReason reason)102 void ExtensionRegistry::TriggerOnUninstalled(const Extension* extension,
103 UninstallReason reason) {
104 CHECK(extension);
105 DCHECK(!GenerateInstalledExtensionsSet()->Contains(extension->id()));
106 for (auto& observer : observers_)
107 observer.OnExtensionUninstalled(browser_context_, extension, reason);
108 }
109
GetExtensionById(const std::string & id,int include_mask) const110 const Extension* ExtensionRegistry::GetExtensionById(const std::string& id,
111 int include_mask) const {
112 std::string lowercase_id = base::ToLowerASCII(id);
113 if (include_mask & ENABLED) {
114 const Extension* extension = enabled_extensions_.GetByID(lowercase_id);
115 if (extension)
116 return extension;
117 }
118 if (include_mask & DISABLED) {
119 const Extension* extension = disabled_extensions_.GetByID(lowercase_id);
120 if (extension)
121 return extension;
122 }
123 if (include_mask & TERMINATED) {
124 const Extension* extension = terminated_extensions_.GetByID(lowercase_id);
125 if (extension)
126 return extension;
127 }
128 if (include_mask & BLOCKLISTED) {
129 const Extension* extension = blocklisted_extensions_.GetByID(lowercase_id);
130 if (extension)
131 return extension;
132 }
133 if (include_mask & BLOCKED) {
134 const Extension* extension = blocked_extensions_.GetByID(lowercase_id);
135 if (extension)
136 return extension;
137 }
138 return NULL;
139 }
140
GetInstalledExtension(const std::string & id) const141 const Extension* ExtensionRegistry::GetInstalledExtension(
142 const std::string& id) const {
143 return GetExtensionById(id, ExtensionRegistry::EVERYTHING);
144 }
145
AddEnabled(const scoped_refptr<const Extension> & extension)146 bool ExtensionRegistry::AddEnabled(
147 const scoped_refptr<const Extension>& extension) {
148 return enabled_extensions_.Insert(extension);
149 }
150
RemoveEnabled(const std::string & id)151 bool ExtensionRegistry::RemoveEnabled(const std::string& id) {
152 // Only enabled extensions can be ready, so removing an enabled extension
153 // should also remove from the ready set if possible.
154 if (ready_extensions_.Contains(id))
155 RemoveReady(id);
156 return enabled_extensions_.Remove(id);
157 }
158
AddDisabled(const scoped_refptr<const Extension> & extension)159 bool ExtensionRegistry::AddDisabled(
160 const scoped_refptr<const Extension>& extension) {
161 return disabled_extensions_.Insert(extension);
162 }
163
RemoveDisabled(const std::string & id)164 bool ExtensionRegistry::RemoveDisabled(const std::string& id) {
165 return disabled_extensions_.Remove(id);
166 }
167
AddTerminated(const scoped_refptr<const Extension> & extension)168 bool ExtensionRegistry::AddTerminated(
169 const scoped_refptr<const Extension>& extension) {
170 return terminated_extensions_.Insert(extension);
171 }
172
RemoveTerminated(const std::string & id)173 bool ExtensionRegistry::RemoveTerminated(const std::string& id) {
174 return terminated_extensions_.Remove(id);
175 }
176
AddBlocklisted(const scoped_refptr<const Extension> & extension)177 bool ExtensionRegistry::AddBlocklisted(
178 const scoped_refptr<const Extension>& extension) {
179 return blocklisted_extensions_.Insert(extension);
180 }
181
RemoveBlocklisted(const std::string & id)182 bool ExtensionRegistry::RemoveBlocklisted(const std::string& id) {
183 return blocklisted_extensions_.Remove(id);
184 }
185
AddBlocked(const scoped_refptr<const Extension> & extension)186 bool ExtensionRegistry::AddBlocked(
187 const scoped_refptr<const Extension>& extension) {
188 return blocked_extensions_.Insert(extension);
189 }
190
RemoveBlocked(const std::string & id)191 bool ExtensionRegistry::RemoveBlocked(const std::string& id) {
192 return blocked_extensions_.Remove(id);
193 }
194
AddReady(const scoped_refptr<const Extension> & extension)195 bool ExtensionRegistry::AddReady(
196 const scoped_refptr<const Extension>& extension) {
197 return ready_extensions_.Insert(extension);
198 }
199
RemoveReady(const std::string & id)200 bool ExtensionRegistry::RemoveReady(const std::string& id) {
201 return ready_extensions_.Remove(id);
202 }
203
ClearAll()204 void ExtensionRegistry::ClearAll() {
205 enabled_extensions_.Clear();
206 disabled_extensions_.Clear();
207 terminated_extensions_.Clear();
208 blocklisted_extensions_.Clear();
209 blocked_extensions_.Clear();
210 ready_extensions_.Clear();
211 }
212
Shutdown()213 void ExtensionRegistry::Shutdown() {
214 // Release references to all Extension objects in the sets.
215 ClearAll();
216 for (auto& observer : observers_)
217 observer.OnShutdown(this);
218 }
219
220 } // namespace extensions
221