OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/common/extensions/api/extension_api.h" | 5 #include "chrome/common/extensions/api/extension_api.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <string> | 8 #include <string> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
118 | 118 |
119 struct Static { | 119 struct Static { |
120 Static() | 120 Static() |
121 : api(ExtensionAPI::CreateWithDefaultConfiguration()) { | 121 : api(ExtensionAPI::CreateWithDefaultConfiguration()) { |
122 } | 122 } |
123 scoped_ptr<ExtensionAPI> api; | 123 scoped_ptr<ExtensionAPI> api; |
124 }; | 124 }; |
125 | 125 |
126 base::LazyInstance<Static> g_lazy_instance = LAZY_INSTANCE_INITIALIZER; | 126 base::LazyInstance<Static> g_lazy_instance = LAZY_INSTANCE_INITIALIZER; |
127 | 127 |
128 // If it exists and does not already specify a namespace, then the value stored | |
129 // with key |key| in |schema| will be updated to |schema_namespace| + "." + | |
130 // |schema[key]|. | |
131 void MaybePrefixFieldWithNamespace(const std::string& schema_namespace, | |
132 DictionaryValue* schema, | |
133 const std::string& key) { | |
134 if (!schema->HasKey(key)) | |
135 return; | |
136 | |
137 std::string old_id; | |
138 CHECK(schema->GetString(key, &old_id)); | |
139 if (old_id.find(".") == std::string::npos) | |
140 schema->SetString(key, schema_namespace + "." + old_id); | |
141 } | |
142 | |
143 // Modify all "$ref" keys anywhere in |schema| to be prefxied by | |
144 // |schema_namespace| if they do not already specify a namespace. | |
145 void PrefixRefsWithNamespace(const std::string& schema_namespace, | |
146 Value* value) { | |
147 if (value->IsType(Value::TYPE_LIST)) { | |
148 ListValue* list; | |
149 CHECK(value->GetAsList(&list)); | |
150 for (ListValue::iterator i = list->begin(); i != list->end(); ++i) { | |
151 PrefixRefsWithNamespace(schema_namespace, *i); | |
152 } | |
153 } else if (value->IsType(Value::TYPE_DICTIONARY)) { | |
154 DictionaryValue* dict; | |
155 CHECK(value->GetAsDictionary(&dict)); | |
156 MaybePrefixFieldWithNamespace(schema_namespace, dict, "$ref"); | |
157 for (DictionaryValue::key_iterator i = dict->begin_keys(); | |
158 i != dict->end_keys(); ++i) { | |
159 Value* next_value; | |
160 CHECK(dict->GetWithoutPathExpansion(*i, &next_value)); | |
161 PrefixRefsWithNamespace(schema_namespace, next_value); | |
162 } | |
163 } | |
164 } | |
165 | |
166 // Modify all objects in the "types" section of the schema to be prefixed by | |
167 // |schema_namespace| if they do not already specify a namespace. | |
168 void PrefixTypesWithNamespace(const std::string& schema_namespace, | |
169 DictionaryValue* schema) { | |
170 if (!schema->HasKey("types")) | |
171 return; | |
172 | |
173 // Add the namespace to all of the types defined in this schema | |
174 ListValue *types; | |
175 CHECK(schema->GetList("types", &types)); | |
176 for (size_t i = 0; i < types->GetSize(); ++i) { | |
177 DictionaryValue *type; | |
178 CHECK(types->GetDictionary(i, &type)); | |
179 MaybePrefixFieldWithNamespace(schema_namespace, type, "id"); | |
180 MaybePrefixFieldWithNamespace(schema_namespace, type, "customBindings"); | |
181 } | |
182 } | |
183 | |
184 // Modify the schema so that all types are fully qualified. | |
185 void PrefixWithNamespace(const std::string& schema_namespace, | |
186 DictionaryValue* schema) { | |
187 PrefixTypesWithNamespace(schema_namespace, schema); | |
188 PrefixRefsWithNamespace(schema_namespace, schema); | |
189 } | |
190 | |
191 } // namespace | 128 } // namespace |
192 | 129 |
193 // static | 130 // static |
194 ExtensionAPI* ExtensionAPI::GetSharedInstance() { | 131 ExtensionAPI* ExtensionAPI::GetSharedInstance() { |
195 return g_lazy_instance.Get().api.get(); | 132 return g_lazy_instance.Get().api.get(); |
196 } | 133 } |
197 | 134 |
198 // static | 135 // static |
199 ExtensionAPI* ExtensionAPI::CreateWithDefaultConfiguration() { | 136 ExtensionAPI* ExtensionAPI::CreateWithDefaultConfiguration() { |
200 ExtensionAPI* api = new ExtensionAPI(); | 137 ExtensionAPI* api = new ExtensionAPI(); |
(...skipping 16 matching lines...) Expand all Loading... |
217 *feature_type = full_name.substr(0, colon_index); | 154 *feature_type = full_name.substr(0, colon_index); |
218 *feature_name = full_name.substr(colon_index + 1); | 155 *feature_name = full_name.substr(colon_index + 1); |
219 } | 156 } |
220 | 157 |
221 void ExtensionAPI::LoadSchema(const std::string& name, | 158 void ExtensionAPI::LoadSchema(const std::string& name, |
222 const base::StringPiece& schema) { | 159 const base::StringPiece& schema) { |
223 scoped_ptr<ListValue> schema_list(LoadSchemaList(name, schema)); | 160 scoped_ptr<ListValue> schema_list(LoadSchemaList(name, schema)); |
224 std::string schema_namespace; | 161 std::string schema_namespace; |
225 | 162 |
226 while (!schema_list->empty()) { | 163 while (!schema_list->empty()) { |
227 DictionaryValue* schema = NULL; | 164 const DictionaryValue* schema = NULL; |
228 { | 165 { |
229 Value* value = NULL; | 166 Value* value = NULL; |
230 schema_list->Remove(schema_list->GetSize() - 1, &value); | 167 schema_list->Remove(schema_list->GetSize() - 1, &value); |
231 CHECK(value->IsType(Value::TYPE_DICTIONARY)); | 168 CHECK(value->IsType(Value::TYPE_DICTIONARY)); |
232 schema = static_cast<DictionaryValue*>(value); | 169 schema = static_cast<const DictionaryValue*>(value); |
233 } | 170 } |
234 | 171 |
235 CHECK(schema->GetString("namespace", &schema_namespace)); | 172 CHECK(schema->GetString("namespace", &schema_namespace)); |
236 PrefixWithNamespace(schema_namespace, schema); | |
237 schemas_[schema_namespace] = make_linked_ptr(schema); | 173 schemas_[schema_namespace] = make_linked_ptr(schema); |
238 CHECK_EQ(1u, unloaded_schemas_.erase(schema_namespace)); | 174 CHECK_EQ(1u, unloaded_schemas_.erase(schema_namespace)); |
239 | 175 |
240 // Populate |{completely,partially}_unprivileged_apis_|. | 176 // Populate |{completely,partially}_unprivileged_apis_|. |
241 // | 177 // |
242 // For "partially", only need to look at functions/events; even though | 178 // For "partially", only need to look at functions/events; even though |
243 // there are unprivileged properties (e.g. in extensions), access to those | 179 // there are unprivileged properties (e.g. in extensions), access to those |
244 // never reaches C++ land. | 180 // never reaches C++ land. |
245 if (schema->HasKey("unprivileged")) { | 181 if (schema->HasKey("unprivileged")) { |
246 completely_unprivileged_apis_.insert(schema_namespace); | 182 completely_unprivileged_apis_.insert(schema_namespace); |
(...skipping 548 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
795 | 731 |
796 void ExtensionAPI::LoadAllSchemas() { | 732 void ExtensionAPI::LoadAllSchemas() { |
797 while (unloaded_schemas_.size()) { | 733 while (unloaded_schemas_.size()) { |
798 std::map<std::string, base::StringPiece>::iterator it = | 734 std::map<std::string, base::StringPiece>::iterator it = |
799 unloaded_schemas_.begin(); | 735 unloaded_schemas_.begin(); |
800 LoadSchema(it->first, it->second); | 736 LoadSchema(it->first, it->second); |
801 } | 737 } |
802 } | 738 } |
803 | 739 |
804 } // namespace extensions | 740 } // namespace extensions |
OLD | NEW |