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