1 // Copyright (c) 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.
5 #include "extensions/common/manifest_handler.h"
9 #include "base/logging.h"
10 #include "base/stl_util.h"
11 #include "extensions/common/extension.h"
12 #include "extensions/common/permissions/manifest_permission.h"
13 #include "extensions/common/permissions/manifest_permission_set.h"
15 namespace extensions
{
19 static base::LazyInstance
<ManifestHandlerRegistry
> g_registry
=
20 LAZY_INSTANCE_INITIALIZER
;
21 static ManifestHandlerRegistry
* g_registry_override
= NULL
;
23 ManifestHandlerRegistry
* GetRegistry() {
24 if (!g_registry_override
)
25 return g_registry
.Pointer();
26 return g_registry_override
;
31 ManifestHandler::ManifestHandler() {
34 ManifestHandler::~ManifestHandler() {
37 bool ManifestHandler::Validate(const Extension
* extension
,
39 std::vector
<InstallWarning
>* warnings
) const {
43 bool ManifestHandler::AlwaysParseForType(Manifest::Type type
) const {
47 bool ManifestHandler::AlwaysValidateForType(Manifest::Type type
) const {
51 const std::vector
<std::string
> ManifestHandler::PrerequisiteKeys() const {
52 return std::vector
<std::string
>();
55 void ManifestHandler::Register() {
56 linked_ptr
<ManifestHandler
> this_linked(this);
57 const std::vector
<std::string
> keys
= Keys();
58 for (size_t i
= 0; i
< keys
.size(); ++i
)
59 GetRegistry()->RegisterManifestHandler(keys
[i
], this_linked
);
62 ManifestPermission
* ManifestHandler::CreatePermission() {
66 ManifestPermission
* ManifestHandler::CreateInitialRequiredPermission(
67 const Extension
* extension
) {
72 void ManifestHandler::FinalizeRegistration() {
73 GetRegistry()->Finalize();
77 bool ManifestHandler::IsRegistrationFinalized() {
78 return GetRegistry()->is_finalized_
;
82 bool ManifestHandler::ParseExtension(Extension
* extension
,
83 base::string16
* error
) {
84 return GetRegistry()->ParseExtension(extension
, error
);
88 bool ManifestHandler::ValidateExtension(const Extension
* extension
,
90 std::vector
<InstallWarning
>* warnings
) {
91 return GetRegistry()->ValidateExtension(extension
, error
, warnings
);
95 ManifestPermission
* ManifestHandler::CreatePermission(const std::string
& name
) {
96 return GetRegistry()->CreatePermission(name
);
100 void ManifestHandler::AddExtensionInitialRequiredPermissions(
101 const Extension
* extension
, ManifestPermissionSet
* permission_set
) {
102 return GetRegistry()->AddExtensionInitialRequiredPermissions(extension
,
107 const std::vector
<std::string
> ManifestHandler::SingleKey(
108 const std::string
& key
) {
109 return std::vector
<std::string
>(1, key
);
112 ManifestHandlerRegistry::ManifestHandlerRegistry() : is_finalized_(false) {
115 ManifestHandlerRegistry::~ManifestHandlerRegistry() {
118 void ManifestHandlerRegistry::Finalize() {
119 CHECK(!is_finalized_
);
120 SortManifestHandlers();
121 is_finalized_
= true;
124 void ManifestHandlerRegistry::RegisterManifestHandler(
125 const std::string
& key
, linked_ptr
<ManifestHandler
> handler
) {
126 CHECK(!is_finalized_
);
127 handlers_
[key
] = handler
;
130 bool ManifestHandlerRegistry::ParseExtension(Extension
* extension
,
131 base::string16
* error
) {
132 std::map
<int, ManifestHandler
*> handlers_by_priority
;
133 for (ManifestHandlerMap::iterator iter
= handlers_
.begin();
134 iter
!= handlers_
.end(); ++iter
) {
135 ManifestHandler
* handler
= iter
->second
.get();
136 if (extension
->manifest()->HasPath(iter
->first
) ||
137 handler
->AlwaysParseForType(extension
->GetType())) {
138 handlers_by_priority
[priority_map_
[handler
]] = handler
;
141 for (std::map
<int, ManifestHandler
*>::iterator iter
=
142 handlers_by_priority
.begin();
143 iter
!= handlers_by_priority
.end(); ++iter
) {
144 if (!(iter
->second
)->Parse(extension
, error
))
150 bool ManifestHandlerRegistry::ValidateExtension(
151 const Extension
* extension
,
153 std::vector
<InstallWarning
>* warnings
) {
154 std::set
<ManifestHandler
*> handlers
;
155 for (ManifestHandlerMap::iterator iter
= handlers_
.begin();
156 iter
!= handlers_
.end(); ++iter
) {
157 ManifestHandler
* handler
= iter
->second
.get();
158 if (extension
->manifest()->HasPath(iter
->first
) ||
159 handler
->AlwaysValidateForType(extension
->GetType())) {
160 handlers
.insert(handler
);
163 for (std::set
<ManifestHandler
*>::iterator iter
= handlers
.begin();
164 iter
!= handlers
.end(); ++iter
) {
165 if (!(*iter
)->Validate(extension
, error
, warnings
))
171 ManifestPermission
* ManifestHandlerRegistry::CreatePermission(
172 const std::string
& name
) {
173 ManifestHandlerMap::const_iterator it
= handlers_
.find(name
);
174 if (it
== handlers_
.end())
177 return it
->second
->CreatePermission();
180 void ManifestHandlerRegistry::AddExtensionInitialRequiredPermissions(
181 const Extension
* extension
, ManifestPermissionSet
* permission_set
) {
182 for (ManifestHandlerMap::const_iterator it
= handlers_
.begin();
183 it
!= handlers_
.end(); ++it
) {
184 ManifestPermission
* permission
=
185 it
->second
->CreateInitialRequiredPermission(extension
);
187 permission_set
->insert(permission
);
193 ManifestHandlerRegistry
* ManifestHandlerRegistry::SetForTesting(
194 ManifestHandlerRegistry
* new_registry
) {
195 ManifestHandlerRegistry
* old_registry
= GetRegistry();
196 if (new_registry
!= g_registry
.Pointer())
197 g_registry_override
= new_registry
;
199 g_registry_override
= NULL
;
203 void ManifestHandlerRegistry::SortManifestHandlers() {
204 std::set
<ManifestHandler
*> unsorted_handlers
;
205 for (ManifestHandlerMap::const_iterator iter
= handlers_
.begin();
206 iter
!= handlers_
.end(); ++iter
) {
207 unsorted_handlers
.insert(iter
->second
.get());
212 std::set
<ManifestHandler
*> next_unsorted_handlers
;
213 for (std::set
<ManifestHandler
*>::const_iterator iter
=
214 unsorted_handlers
.begin();
215 iter
!= unsorted_handlers
.end(); ++iter
) {
216 ManifestHandler
* handler
= *iter
;
217 const std::vector
<std::string
>& prerequisites
=
218 handler
->PrerequisiteKeys();
219 int unsatisfied
= prerequisites
.size();
220 for (size_t i
= 0; i
< prerequisites
.size(); ++i
) {
221 ManifestHandlerMap::const_iterator prereq_iter
=
222 handlers_
.find(prerequisites
[i
]);
223 // If the prerequisite does not exist, crash.
224 CHECK(prereq_iter
!= handlers_
.end())
225 << "Extension manifest handler depends on unrecognized key "
227 // Prerequisite is in our map.
228 if (ContainsKey(priority_map_
, prereq_iter
->second
.get()))
231 if (unsatisfied
== 0) {
232 priority_map_
[handler
] = priority
;
235 // Put in the list for next time.
236 next_unsorted_handlers
.insert(handler
);
239 if (next_unsorted_handlers
.size() == unsorted_handlers
.size())
241 unsorted_handlers
.swap(next_unsorted_handlers
);
244 // If there are any leftover unsorted handlers, they must have had
245 // circular dependencies.
246 CHECK(unsorted_handlers
.size() == 0) << "Extension manifest handlers have "
247 << "circular dependencies!";
250 } // namespace extensions