Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(75)

Side by Side Diff: chrome/common/extensions/manifest_handler.cc

Issue 60393005: Revert 232631 - Revert 232499 "Move ManifestHandler to top-level extensions." (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: deps Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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.
4
5 #include "chrome/common/extensions/manifest_handler.h"
6
7 #include <map>
8
9 #include "base/logging.h"
10 #include "base/stl_util.h"
11 #include "chrome/common/extensions/extension.h"
12
13 namespace extensions {
14
15 namespace {
16
17 static base::LazyInstance<ManifestHandlerRegistry> g_registry =
18 LAZY_INSTANCE_INITIALIZER;
19 static ManifestHandlerRegistry* g_registry_override = NULL;
20
21 ManifestHandlerRegistry* GetRegistry() {
22 if (!g_registry_override)
23 return g_registry.Pointer();
24 return g_registry_override;
25 }
26
27 } // namespace
28
29 ManifestHandler::ManifestHandler() {
30 }
31
32 ManifestHandler::~ManifestHandler() {
33 }
34
35 bool ManifestHandler::Validate(const Extension* extension,
36 std::string* error,
37 std::vector<InstallWarning>* warnings) const {
38 return true;
39 }
40
41 bool ManifestHandler::AlwaysParseForType(Manifest::Type type) const {
42 return false;
43 }
44
45 bool ManifestHandler::AlwaysValidateForType(Manifest::Type type) const {
46 return false;
47 }
48
49 const std::vector<std::string> ManifestHandler::PrerequisiteKeys() const {
50 return std::vector<std::string>();
51 }
52
53 void ManifestHandler::Register() {
54 linked_ptr<ManifestHandler> this_linked(this);
55 const std::vector<std::string> keys = Keys();
56 for (size_t i = 0; i < keys.size(); ++i)
57 GetRegistry()->RegisterManifestHandler(keys[i], this_linked);
58 }
59
60 // static
61 void ManifestHandler::FinalizeRegistration() {
62 GetRegistry()->Finalize();
63 }
64
65 // static
66 bool ManifestHandler::IsRegistrationFinalized() {
67 return GetRegistry()->is_finalized_;
68 }
69
70 // static
71 bool ManifestHandler::ParseExtension(Extension* extension, string16* error) {
72 return GetRegistry()->ParseExtension(extension, error);
73 }
74
75 // static
76 bool ManifestHandler::ValidateExtension(const Extension* extension,
77 std::string* error,
78 std::vector<InstallWarning>* warnings) {
79 return GetRegistry()->ValidateExtension(extension, error, warnings);
80 }
81
82 // static
83 const std::vector<std::string> ManifestHandler::SingleKey(
84 const std::string& key) {
85 return std::vector<std::string>(1, key);
86 }
87
88 ManifestHandlerRegistry::ManifestHandlerRegistry() : is_finalized_(false) {
89 }
90
91 ManifestHandlerRegistry::~ManifestHandlerRegistry() {
92 }
93
94 void ManifestHandlerRegistry::Finalize() {
95 CHECK(!is_finalized_);
96 SortManifestHandlers();
97 is_finalized_ = true;
98 }
99
100 void ManifestHandlerRegistry::RegisterManifestHandler(
101 const std::string& key, linked_ptr<ManifestHandler> handler) {
102 CHECK(!is_finalized_);
103 handlers_[key] = handler;
104 }
105
106 bool ManifestHandlerRegistry::ParseExtension(Extension* extension,
107 string16* error) {
108 std::map<int, ManifestHandler*> handlers_by_priority;
109 for (ManifestHandlerMap::iterator iter = handlers_.begin();
110 iter != handlers_.end(); ++iter) {
111 ManifestHandler* handler = iter->second.get();
112 if (extension->manifest()->HasPath(iter->first) ||
113 handler->AlwaysParseForType(extension->GetType())) {
114 handlers_by_priority[priority_map_[handler]] = handler;
115 }
116 }
117 for (std::map<int, ManifestHandler*>::iterator iter =
118 handlers_by_priority.begin();
119 iter != handlers_by_priority.end(); ++iter) {
120 if (!(iter->second)->Parse(extension, error))
121 return false;
122 }
123 return true;
124 }
125
126 bool ManifestHandlerRegistry::ValidateExtension(
127 const Extension* extension,
128 std::string* error,
129 std::vector<InstallWarning>* warnings) {
130 std::set<ManifestHandler*> handlers;
131 for (ManifestHandlerMap::iterator iter = handlers_.begin();
132 iter != handlers_.end(); ++iter) {
133 ManifestHandler* handler = iter->second.get();
134 if (extension->manifest()->HasPath(iter->first) ||
135 handler->AlwaysValidateForType(extension->GetType())) {
136 handlers.insert(handler);
137 }
138 }
139 for (std::set<ManifestHandler*>::iterator iter = handlers.begin();
140 iter != handlers.end(); ++iter) {
141 if (!(*iter)->Validate(extension, error, warnings))
142 return false;
143 }
144 return true;
145 }
146
147 // static
148 ManifestHandlerRegistry* ManifestHandlerRegistry::SetForTesting(
149 ManifestHandlerRegistry* new_registry) {
150 ManifestHandlerRegistry* old_registry = GetRegistry();
151 if (new_registry != g_registry.Pointer())
152 g_registry_override = new_registry;
153 else
154 g_registry_override = NULL;
155 return old_registry;
156 }
157
158 void ManifestHandlerRegistry::SortManifestHandlers() {
159 std::set<ManifestHandler*> unsorted_handlers;
160 for (ManifestHandlerMap::const_iterator iter = handlers_.begin();
161 iter != handlers_.end(); ++iter) {
162 unsorted_handlers.insert(iter->second.get());
163 }
164
165 int priority = 0;
166 while (true) {
167 std::set<ManifestHandler*> next_unsorted_handlers;
168 for (std::set<ManifestHandler*>::const_iterator iter =
169 unsorted_handlers.begin();
170 iter != unsorted_handlers.end(); ++iter) {
171 ManifestHandler* handler = *iter;
172 const std::vector<std::string>& prerequisites =
173 handler->PrerequisiteKeys();
174 int unsatisfied = prerequisites.size();
175 for (size_t i = 0; i < prerequisites.size(); ++i) {
176 ManifestHandlerMap::const_iterator prereq_iter =
177 handlers_.find(prerequisites[i]);
178 // If the prerequisite does not exist, crash.
179 CHECK(prereq_iter != handlers_.end())
180 << "Extension manifest handler depends on unrecognized key "
181 << prerequisites[i];
182 // Prerequisite is in our map.
183 if (ContainsKey(priority_map_, prereq_iter->second.get()))
184 unsatisfied--;
185 }
186 if (unsatisfied == 0) {
187 priority_map_[handler] = priority;
188 priority++;
189 } else {
190 // Put in the list for next time.
191 next_unsorted_handlers.insert(handler);
192 }
193 }
194 if (next_unsorted_handlers.size() == unsorted_handlers.size())
195 break;
196 unsorted_handlers.swap(next_unsorted_handlers);
197 }
198
199 // If there are any leftover unsorted handlers, they must have had
200 // circular dependencies.
201 CHECK(unsorted_handlers.size() == 0) << "Extension manifest handlers have "
202 << "circular dependencies!";
203 }
204
205 } // namespace extensions
OLDNEW
« no previous file with comments | « chrome/common/extensions/manifest_handler.h ('k') | chrome/common/extensions/manifest_handler_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698