Fix crash on app list start page contents not existing.
[chromium-blink-merge.git] / extensions / common / manifest_handler.cc
blob78df1cd1cdf99a10a4a2a55b4905020457d4c247
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"
7 #include <map>
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 {
17 namespace {
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;
29 } // namespace
31 ManifestHandler::ManifestHandler() {
34 ManifestHandler::~ManifestHandler() {
37 bool ManifestHandler::Validate(const Extension* extension,
38 std::string* error,
39 std::vector<InstallWarning>* warnings) const {
40 return true;
43 bool ManifestHandler::AlwaysParseForType(Manifest::Type type) const {
44 return false;
47 bool ManifestHandler::AlwaysValidateForType(Manifest::Type type) const {
48 return false;
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() {
63 return NULL;
66 ManifestPermission* ManifestHandler::CreateInitialRequiredPermission(
67 const Extension* extension) {
68 return NULL;
71 // static
72 void ManifestHandler::FinalizeRegistration() {
73 GetRegistry()->Finalize();
76 // static
77 bool ManifestHandler::IsRegistrationFinalized() {
78 return GetRegistry()->is_finalized_;
81 // static
82 bool ManifestHandler::ParseExtension(Extension* extension,
83 base::string16* error) {
84 return GetRegistry()->ParseExtension(extension, error);
87 // static
88 bool ManifestHandler::ValidateExtension(const Extension* extension,
89 std::string* error,
90 std::vector<InstallWarning>* warnings) {
91 return GetRegistry()->ValidateExtension(extension, error, warnings);
94 // static
95 ManifestPermission* ManifestHandler::CreatePermission(const std::string& name) {
96 return GetRegistry()->CreatePermission(name);
99 // static
100 void ManifestHandler::AddExtensionInitialRequiredPermissions(
101 const Extension* extension, ManifestPermissionSet* permission_set) {
102 return GetRegistry()->AddExtensionInitialRequiredPermissions(extension,
103 permission_set);
106 // static
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))
145 return false;
147 return true;
150 bool ManifestHandlerRegistry::ValidateExtension(
151 const Extension* extension,
152 std::string* error,
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))
166 return false;
168 return true;
171 ManifestPermission* ManifestHandlerRegistry::CreatePermission(
172 const std::string& name) {
173 ManifestHandlerMap::const_iterator it = handlers_.find(name);
174 if (it == handlers_.end())
175 return NULL;
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);
186 if (permission) {
187 permission_set->insert(permission);
192 // static
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;
198 else
199 g_registry_override = NULL;
200 return old_registry;
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());
210 int priority = 0;
211 while (true) {
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 "
226 << prerequisites[i];
227 // Prerequisite is in our map.
228 if (ContainsKey(priority_map_, prereq_iter->second.get()))
229 unsatisfied--;
231 if (unsatisfied == 0) {
232 priority_map_[handler] = priority;
233 priority++;
234 } else {
235 // Put in the list for next time.
236 next_unsorted_handlers.insert(handler);
239 if (next_unsorted_handlers.size() == unsorted_handlers.size())
240 break;
241 unsorted_handlers.swap(next_unsorted_handlers);
244 // If there are any leftover unsorted handlers, they must have had
245 // circular dependencies.
246 CHECK_EQ(unsorted_handlers.size(), std::set<ManifestHandler*>::size_type(0))
247 << "Extension manifest handlers have circular dependencies!";
250 } // namespace extensions