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

Side by Side Diff: chrome/common/extensions/api/extension_api.cc

Issue 15091002: Lazily load API schemas from resource files and convert all APIs to features (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix chromeos tests Created 7 years, 6 months 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
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 19 matching lines...) Expand all
30 using base::DictionaryValue; 30 using base::DictionaryValue;
31 using base::ListValue; 31 using base::ListValue;
32 using base::Value; 32 using base::Value;
33 33
34 namespace extensions { 34 namespace extensions {
35 35
36 using api::GeneratedSchemas; 36 using api::GeneratedSchemas;
37 37
38 namespace { 38 namespace {
39 39
40 const char kUnavailableMessage[] = "You do not have permission to access this "
41 "API. Ensure that the required permission "
42 "or manifest property is included in your "
43 "manifest.json.";
44 const char* kChildKinds[] = { 40 const char* kChildKinds[] = {
45 "functions", 41 "functions",
46 "events" 42 "events"
47 }; 43 };
48 44
49 // Returns true if |dict| has an unprivileged "true" property.
50 bool IsUnprivileged(const DictionaryValue* dict) {
51 bool unprivileged = false;
52 return dict->GetBoolean("unprivileged", &unprivileged) && unprivileged;
53 }
54
55 // Returns whether the list at |name_space_node|.|child_kind| contains any
56 // children with an { "unprivileged": true } property.
57 bool HasUnprivilegedChild(const DictionaryValue* name_space_node,
58 const std::string& child_kind) {
59 const ListValue* child_list = NULL;
60 const DictionaryValue* child_dict = NULL;
61
62 if (name_space_node->GetList(child_kind, &child_list)) {
63 for (size_t i = 0; i < child_list->GetSize(); ++i) {
64 const DictionaryValue* item = NULL;
65 CHECK(child_list->GetDictionary(i, &item));
66 if (IsUnprivileged(item))
67 return true;
68 }
69 } else if (name_space_node->GetDictionary(child_kind, &child_dict)) {
70 for (DictionaryValue::Iterator it(*child_dict); !it.IsAtEnd();
71 it.Advance()) {
72 const DictionaryValue* item = NULL;
73 CHECK(it.value().GetAsDictionary(&item));
74 if (IsUnprivileged(item))
75 return true;
76 }
77 }
78
79 return false;
80 }
81
82 base::StringPiece ReadFromResource(int resource_id) { 45 base::StringPiece ReadFromResource(int resource_id) {
83 return ResourceBundle::GetSharedInstance().GetRawDataResource( 46 return ResourceBundle::GetSharedInstance().GetRawDataResource(
84 resource_id); 47 resource_id);
85 } 48 }
86 49
87 scoped_ptr<ListValue> LoadSchemaList(const std::string& name, 50 scoped_ptr<ListValue> LoadSchemaList(const std::string& name,
88 const base::StringPiece& schema) { 51 const base::StringPiece& schema) {
89 std::string error_message; 52 std::string error_message;
90 scoped_ptr<Value> result( 53 scoped_ptr<Value> result(
91 base::JSONReader::ReadAndReturnError( 54 base::JSONReader::ReadAndReturnError(
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
245 { 208 {
246 Value* value = NULL; 209 Value* value = NULL;
247 schema_list->Remove(schema_list->GetSize() - 1, &value); 210 schema_list->Remove(schema_list->GetSize() - 1, &value);
248 CHECK(value->IsType(Value::TYPE_DICTIONARY)); 211 CHECK(value->IsType(Value::TYPE_DICTIONARY));
249 schema = static_cast<DictionaryValue*>(value); 212 schema = static_cast<DictionaryValue*>(value);
250 } 213 }
251 214
252 CHECK(schema->GetString("namespace", &schema_namespace)); 215 CHECK(schema->GetString("namespace", &schema_namespace));
253 PrefixWithNamespace(schema_namespace, schema); 216 PrefixWithNamespace(schema_namespace, schema);
254 schemas_[schema_namespace] = make_linked_ptr(schema); 217 schemas_[schema_namespace] = make_linked_ptr(schema);
255 CHECK_EQ(1u, unloaded_schemas_.erase(schema_namespace)); 218 if (!GeneratedSchemas::IsGenerated(schema_namespace))
256 219 CHECK_EQ(1u, unloaded_schemas_.erase(schema_namespace));
257 // Populate |{completely,partially}_unprivileged_apis_|.
258
259 // For "partially", only need to look at functions/events; even though
260 // there are unprivileged properties (e.g. in extensions), access to those
261 // never reaches C++ land.
262 bool unprivileged = false;
263 if (schema->GetBoolean("unprivileged", &unprivileged) && unprivileged) {
264 completely_unprivileged_apis_.insert(schema_namespace);
265 } else if (HasUnprivilegedChild(schema, "functions") ||
266 HasUnprivilegedChild(schema, "events") ||
267 HasUnprivilegedChild(schema, "properties")) {
268 partially_unprivileged_apis_.insert(schema_namespace);
269 }
270 } 220 }
271 } 221 }
272 222
273 ExtensionAPI::ExtensionAPI() { 223 ExtensionAPI::ExtensionAPI() : default_configuration_initialized_(false) {
274 } 224 }
275 225
276 ExtensionAPI::~ExtensionAPI() { 226 ExtensionAPI::~ExtensionAPI() {
277 } 227 }
278 228
279 void ExtensionAPI::InitDefaultConfiguration() { 229 void ExtensionAPI::InitDefaultConfiguration() {
280 RegisterDependencyProvider( 230 RegisterDependencyProvider(
281 "api", BaseFeatureProvider::GetByName("api")); 231 "api", BaseFeatureProvider::GetByName("api"));
282 RegisterDependencyProvider( 232 RegisterDependencyProvider(
283 "manifest", BaseFeatureProvider::GetByName("manifest")); 233 "manifest", BaseFeatureProvider::GetByName("manifest"));
284 RegisterDependencyProvider( 234 RegisterDependencyProvider(
285 "permission", BaseFeatureProvider::GetByName("permission")); 235 "permission", BaseFeatureProvider::GetByName("permission"));
286 236
287 // Schemas to be loaded from resources. 237 // Schemas to be loaded from resources.
288 CHECK(unloaded_schemas_.empty()); 238 CHECK(unloaded_schemas_.empty());
289 RegisterSchema("app", ReadFromResource( 239 RegisterSchemaResource("app", IDR_EXTENSION_API_JSON_APP);
290 IDR_EXTENSION_API_JSON_APP)); 240 RegisterSchemaResource("browserAction", IDR_EXTENSION_API_JSON_BROWSERACTION);
291 RegisterSchema("browserAction", ReadFromResource( 241 RegisterSchemaResource("browsingData", IDR_EXTENSION_API_JSON_BROWSINGDATA);
292 IDR_EXTENSION_API_JSON_BROWSERACTION)); 242 RegisterSchemaResource("commands", IDR_EXTENSION_API_JSON_COMMANDS);
293 RegisterSchema("browsingData", ReadFromResource( 243 RegisterSchemaResource("declarativeContent",
294 IDR_EXTENSION_API_JSON_BROWSINGDATA)); 244 IDR_EXTENSION_API_JSON_DECLARATIVE_CONTENT);
295 RegisterSchema("commands", ReadFromResource( 245 RegisterSchemaResource("declarativeWebRequest",
296 IDR_EXTENSION_API_JSON_COMMANDS)); 246 IDR_EXTENSION_API_JSON_DECLARATIVE_WEBREQUEST);
297 RegisterSchema("declarativeContent", ReadFromResource( 247 RegisterSchemaResource("experimental.input.virtualKeyboard",
298 IDR_EXTENSION_API_JSON_DECLARATIVE_CONTENT)); 248 IDR_EXTENSION_API_JSON_EXPERIMENTAL_INPUT_VIRTUALKEYBOARD);
299 RegisterSchema("declarativeWebRequest", ReadFromResource( 249 RegisterSchemaResource("experimental.processes",
300 IDR_EXTENSION_API_JSON_DECLARATIVE_WEBREQUEST)); 250 IDR_EXTENSION_API_JSON_EXPERIMENTAL_PROCESSES);
301 RegisterSchema("experimental.input.virtualKeyboard", ReadFromResource( 251 RegisterSchemaResource("experimental.rlz",
302 IDR_EXTENSION_API_JSON_EXPERIMENTAL_INPUT_VIRTUALKEYBOARD)); 252 IDR_EXTENSION_API_JSON_EXPERIMENTAL_RLZ);
303 RegisterSchema("experimental.processes", ReadFromResource( 253 RegisterSchemaResource("runtime", IDR_EXTENSION_API_JSON_RUNTIME);
304 IDR_EXTENSION_API_JSON_EXPERIMENTAL_PROCESSES)); 254 RegisterSchemaResource("fileBrowserHandler",
305 RegisterSchema("experimental.rlz", ReadFromResource( 255 IDR_EXTENSION_API_JSON_FILEBROWSERHANDLER);
306 IDR_EXTENSION_API_JSON_EXPERIMENTAL_RLZ)); 256 RegisterSchemaResource("fileBrowserPrivate",
307 RegisterSchema("runtime", ReadFromResource( 257 IDR_EXTENSION_API_JSON_FILEBROWSERPRIVATE);
308 IDR_EXTENSION_API_JSON_RUNTIME)); 258 RegisterSchemaResource("input.ime", IDR_EXTENSION_API_JSON_INPUT_IME);
309 RegisterSchema("fileBrowserHandler", ReadFromResource( 259 RegisterSchemaResource("inputMethodPrivate",
310 IDR_EXTENSION_API_JSON_FILEBROWSERHANDLER)); 260 IDR_EXTENSION_API_JSON_INPUTMETHODPRIVATE);
311 RegisterSchema("fileBrowserPrivate", ReadFromResource( 261 RegisterSchemaResource("pageAction", IDR_EXTENSION_API_JSON_PAGEACTION);
312 IDR_EXTENSION_API_JSON_FILEBROWSERPRIVATE)); 262 RegisterSchemaResource("pageActions", IDR_EXTENSION_API_JSON_PAGEACTIONS);
313 RegisterSchema("input.ime", ReadFromResource( 263 RegisterSchemaResource("privacy", IDR_EXTENSION_API_JSON_PRIVACY);
314 IDR_EXTENSION_API_JSON_INPUT_IME)); 264 RegisterSchemaResource("proxy", IDR_EXTENSION_API_JSON_PROXY);
315 RegisterSchema("inputMethodPrivate", ReadFromResource( 265 RegisterSchemaResource("scriptBadge", IDR_EXTENSION_API_JSON_SCRIPTBADGE);
316 IDR_EXTENSION_API_JSON_INPUTMETHODPRIVATE)); 266 RegisterSchemaResource("streamsPrivate",
317 RegisterSchema("pageAction", ReadFromResource( 267 IDR_EXTENSION_API_JSON_STREAMSPRIVATE);
318 IDR_EXTENSION_API_JSON_PAGEACTION)); 268 RegisterSchemaResource("ttsEngine", IDR_EXTENSION_API_JSON_TTSENGINE);
319 RegisterSchema("pageActions", ReadFromResource( 269 RegisterSchemaResource("tts", IDR_EXTENSION_API_JSON_TTS);
320 IDR_EXTENSION_API_JSON_PAGEACTIONS)); 270 RegisterSchemaResource("types", IDR_EXTENSION_API_JSON_TYPES);
321 RegisterSchema("privacy", ReadFromResource( 271 RegisterSchemaResource("webRequestInternal",
322 IDR_EXTENSION_API_JSON_PRIVACY)); 272 IDR_EXTENSION_API_JSON_WEBREQUESTINTERNAL);
323 RegisterSchema("proxy", ReadFromResource( 273 RegisterSchemaResource("webstore", IDR_EXTENSION_API_JSON_WEBSTORE);
324 IDR_EXTENSION_API_JSON_PROXY)); 274 RegisterSchemaResource("webstorePrivate",
325 RegisterSchema("scriptBadge", ReadFromResource( 275 IDR_EXTENSION_API_JSON_WEBSTOREPRIVATE);
326 IDR_EXTENSION_API_JSON_SCRIPTBADGE)); 276 default_configuration_initialized_ = true;
327 RegisterSchema("streamsPrivate", ReadFromResource(
328 IDR_EXTENSION_API_JSON_STREAMSPRIVATE));
329 RegisterSchema("ttsEngine", ReadFromResource(
330 IDR_EXTENSION_API_JSON_TTSENGINE));
331 RegisterSchema("tts", ReadFromResource(
332 IDR_EXTENSION_API_JSON_TTS));
333 RegisterSchema("types", ReadFromResource(
334 IDR_EXTENSION_API_JSON_TYPES));
335 RegisterSchema("webRequestInternal", ReadFromResource(
336 IDR_EXTENSION_API_JSON_WEBREQUESTINTERNAL));
337 RegisterSchema("webstore", ReadFromResource(
338 IDR_EXTENSION_API_JSON_WEBSTORE));
339 RegisterSchema("webstorePrivate", ReadFromResource(
340 IDR_EXTENSION_API_JSON_WEBSTOREPRIVATE));
341
342 // Schemas to be loaded via JSON generated from IDL files.
343 GeneratedSchemas::Get(&unloaded_schemas_);
344 } 277 }
345 278
346 void ExtensionAPI::RegisterSchema(const std::string& name, 279 void ExtensionAPI::RegisterSchemaResource(const std::string& name,
347 const base::StringPiece& source) { 280 int resource_id) {
348 unloaded_schemas_[name] = source; 281 unloaded_schemas_[name] = resource_id;
349 } 282 }
350 283
351 void ExtensionAPI::RegisterDependencyProvider(const std::string& name, 284 void ExtensionAPI::RegisterDependencyProvider(const std::string& name,
352 FeatureProvider* provider) { 285 FeatureProvider* provider) {
353 dependency_providers_[name] = provider; 286 dependency_providers_[name] = provider;
354 } 287 }
355 288
356 bool ExtensionAPI::IsAnyFeatureAvailableToContext(const std::string& api_name, 289 bool ExtensionAPI::IsAnyFeatureAvailableToContext(const std::string& api_name,
357 Feature::Context context, 290 Feature::Context context,
358 const GURL& url) { 291 const GURL& url) {
359 FeatureProviderMap::iterator provider = dependency_providers_.find("api"); 292 FeatureProviderMap::iterator provider = dependency_providers_.find("api");
360 CHECK(provider != dependency_providers_.end()); 293 CHECK(provider != dependency_providers_.end());
361 std::set<std::string> features = provider->second->GetAllFeatureNames(); 294 const std::vector<std::string>& features =
295 provider->second->GetAllFeatureNames();
362 296
363 // Check to see if there are any parts of this API that are allowed in this 297 // Check to see if there are any parts of this API that are allowed in this
364 // context. 298 // context.
365 for (std::set<std::string>::iterator i = features.begin(); 299 for (std::vector<std::string>::const_iterator i = features.begin();
366 i != features.end(); ++i) { 300 i != features.end(); ++i) {
367 const std::string& feature_name = *i; 301 const std::string& feature_name = *i;
368 if (feature_name != api_name && feature_name.find(api_name + ".") == 0) { 302 if (feature_name != api_name && feature_name.find(api_name + ".") == 0) {
369 if (IsAvailable(feature_name, NULL, context, url).is_available()) 303 if (IsAvailable(feature_name, NULL, context, url).is_available())
370 return true; 304 return true;
371 } 305 }
372 } 306 }
373 return IsAvailable(api_name, NULL, context, url).is_available(); 307 return IsAvailable(api_name, NULL, context, url).is_available();
374 } 308 }
375 309
376 Feature::Availability ExtensionAPI::IsAvailable(const std::string& full_name, 310 Feature::Availability ExtensionAPI::IsAvailable(const std::string& full_name,
377 const Extension* extension, 311 const Extension* extension,
378 Feature::Context context, 312 Feature::Context context,
379 const GURL& url) { 313 const GURL& url) {
380 std::string feature_type; 314 std::string feature_type;
381 std::string feature_name; 315 std::string feature_name;
382 SplitDependencyName(full_name, &feature_type, &feature_name); 316 SplitDependencyName(full_name, &feature_type, &feature_name);
383 317
384 std::string child_name;
385 std::string api_name = GetAPINameFromFullName(feature_name, &child_name);
386
387 Feature* feature = GetFeatureDependency(full_name); 318 Feature* feature = GetFeatureDependency(full_name);
388 319 CHECK(feature) << full_name;
389 // Check APIs not using the feature system first.
390 if (!feature) {
391 return IsNonFeatureAPIAvailable(api_name, context, extension, url)
392 ? Feature::CreateAvailability(Feature::IS_AVAILABLE,
393 std::string())
394 : Feature::CreateAvailability(Feature::INVALID_CONTEXT,
395 kUnavailableMessage);
396 }
397 320
398 Feature::Availability availability = 321 Feature::Availability availability =
399 feature->IsAvailableToContext(extension, context, url); 322 feature->IsAvailableToContext(extension, context, url);
400 if (!availability.is_available()) 323 if (!availability.is_available())
401 return availability; 324 return availability;
402 325
403 for (std::set<std::string>::iterator iter = feature->dependencies().begin(); 326 for (std::set<std::string>::iterator iter = feature->dependencies().begin();
404 iter != feature->dependencies().end(); ++iter) { 327 iter != feature->dependencies().end(); ++iter) {
405 Feature::Availability dependency_availability = 328 Feature::Availability dependency_availability =
406 IsAvailable(*iter, extension, context, url); 329 IsAvailable(*iter, extension, context, url);
407 if (!dependency_availability.is_available()) 330 if (!dependency_availability.is_available())
408 return dependency_availability; 331 return dependency_availability;
409 } 332 }
410 333
411 return Feature::CreateAvailability(Feature::IS_AVAILABLE, std::string()); 334 return Feature::CreateAvailability(Feature::IS_AVAILABLE, std::string());
412 } 335 }
413 336
414 bool ExtensionAPI::IsPrivileged(const std::string& full_name) { 337 bool ExtensionAPI::IsPrivileged(const std::string& full_name) {
415 std::string child_name;
416 std::string api_name = GetAPINameFromFullName(full_name, &child_name);
417 Feature* feature = GetFeatureDependency(full_name); 338 Feature* feature = GetFeatureDependency(full_name);
418 339 CHECK(feature);
419 // First try to use the feature system. 340 DCHECK(!feature->GetContexts()->empty());
420 if (feature) { 341 // An API is 'privileged' if it can only be run in a blessed context.
421 // An API is 'privileged' if it can only be run in a blessed context. 342 return feature->GetContexts()->size() ==
422 return feature->GetContexts()->size() == 343 feature->GetContexts()->count(Feature::BLESSED_EXTENSION_CONTEXT);
423 feature->GetContexts()->count(Feature::BLESSED_EXTENSION_CONTEXT);
424 }
425
426 // Get the schema now to populate |completely_unprivileged_apis_|.
427 const DictionaryValue* schema = GetSchema(api_name);
428 // If this API hasn't been converted yet, fall back to the old system.
429 if (completely_unprivileged_apis_.count(api_name))
430 return false;
431
432 if (partially_unprivileged_apis_.count(api_name))
433 return IsChildNamePrivileged(schema, child_name);
434
435 return true;
436 }
437
438 bool ExtensionAPI::IsChildNamePrivileged(const DictionaryValue* name_space_node,
439 const std::string& child_name) {
440 bool unprivileged = false;
441 const DictionaryValue* child = GetSchemaChild(name_space_node, child_name);
442 if (!child || !child->GetBoolean("unprivileged", &unprivileged))
443 return true;
444
445 return !unprivileged;
446 } 344 }
447 345
448 const DictionaryValue* ExtensionAPI::GetSchema(const std::string& full_name) { 346 const DictionaryValue* ExtensionAPI::GetSchema(const std::string& full_name) {
449 std::string child_name; 347 std::string child_name;
450 std::string api_name = GetAPINameFromFullName(full_name, &child_name); 348 std::string api_name = GetAPINameFromFullName(full_name, &child_name);
451 349
452 const DictionaryValue* result = NULL; 350 const DictionaryValue* result = NULL;
453 SchemaMap::iterator maybe_schema = schemas_.find(api_name); 351 SchemaMap::iterator maybe_schema = schemas_.find(api_name);
454 if (maybe_schema != schemas_.end()) { 352 if (maybe_schema != schemas_.end()) {
455 result = maybe_schema->second.get(); 353 result = maybe_schema->second.get();
456 } else { 354 } else {
457 // Might not have loaded yet; or might just not exist. 355 // Might not have loaded yet; or might just not exist.
458 std::map<std::string, base::StringPiece>::iterator maybe_schema_resource = 356 UnloadedSchemaMap::iterator maybe_schema_resource =
459 unloaded_schemas_.find(api_name); 357 unloaded_schemas_.find(api_name);
460 if (maybe_schema_resource == unloaded_schemas_.end()) 358 if (maybe_schema_resource != unloaded_schemas_.end()) {
359 LoadSchema(maybe_schema_resource->first,
360 ReadFromResource(maybe_schema_resource->second));
361 } else if (default_configuration_initialized_ &&
362 GeneratedSchemas::IsGenerated(api_name)) {
363 LoadSchema(api_name, GeneratedSchemas::Get(api_name));
364 } else {
461 return NULL; 365 return NULL;
366 }
462 367
463 LoadSchema(maybe_schema_resource->first, maybe_schema_resource->second);
464 maybe_schema = schemas_.find(api_name); 368 maybe_schema = schemas_.find(api_name);
465 CHECK(schemas_.end() != maybe_schema); 369 CHECK(schemas_.end() != maybe_schema);
466 result = maybe_schema->second.get(); 370 result = maybe_schema->second.get();
467 } 371 }
468 372
469 if (!child_name.empty()) 373 if (!child_name.empty())
470 result = GetSchemaChild(result, child_name); 374 result = GetSchemaChild(result, child_name);
471 375
472 return result; 376 return result;
473 } 377 }
474 378
475 namespace {
476
477 const char* kDisallowedPlatformAppFeatures[] = {
478 // "app" refers to the the legacy app namespace for hosted apps.
479 "app",
480 "extension",
481 "tabs",
482 "windows"
483 };
484
485 bool IsFeatureAllowedForExtension(const std::string& feature,
486 const extensions::Extension& extension) {
487 if (extension.is_platform_app()) {
488 for (size_t i = 0; i < arraysize(kDisallowedPlatformAppFeatures); ++i) {
489 if (feature == kDisallowedPlatformAppFeatures[i])
490 return false;
491 }
492 }
493
494 return true;
495 }
496
497 } // namespace
498
499 bool ExtensionAPI::IsNonFeatureAPIAvailable(const std::string& name,
500 Feature::Context context,
501 const Extension* extension,
502 const GURL& url) {
503 // Make sure schema is loaded.
504 GetSchema(name);
505 switch (context) {
506 case Feature::UNSPECIFIED_CONTEXT:
507 break;
508
509 case Feature::BLESSED_EXTENSION_CONTEXT:
510 if (extension) {
511 // Availability is determined by the permissions of the extension.
512 if (!IsAPIAllowed(name, extension))
513 return false;
514 if (!IsFeatureAllowedForExtension(name, *extension))
515 return false;
516 }
517 break;
518
519 case Feature::UNBLESSED_EXTENSION_CONTEXT:
520 case Feature::CONTENT_SCRIPT_CONTEXT:
521 if (extension) {
522 // Same as BLESSED_EXTENSION_CONTEXT, but only those APIs that are
523 // unprivileged.
524 if (!IsAPIAllowed(name, extension))
525 return false;
526 if (!IsPrivilegedAPI(name))
527 return false;
528 }
529 break;
530
531 case Feature::WEB_PAGE_CONTEXT:
532 return false;
533 }
534
535 return true;
536 }
537
538 std::set<std::string> ExtensionAPI::GetAllAPINames() {
539 std::set<std::string> result;
540 for (SchemaMap::iterator i = schemas_.begin(); i != schemas_.end(); ++i)
541 result.insert(i->first);
542 for (UnloadedSchemaMap::iterator i = unloaded_schemas_.begin();
543 i != unloaded_schemas_.end(); ++i) {
544 result.insert(i->first);
545 }
546 return result;
547 }
548
549 Feature* ExtensionAPI::GetFeatureDependency(const std::string& full_name) { 379 Feature* ExtensionAPI::GetFeatureDependency(const std::string& full_name) {
550 std::string feature_type; 380 std::string feature_type;
551 std::string feature_name; 381 std::string feature_name;
552 SplitDependencyName(full_name, &feature_type, &feature_name); 382 SplitDependencyName(full_name, &feature_type, &feature_name);
553 383
554 FeatureProviderMap::iterator provider = 384 FeatureProviderMap::iterator provider =
555 dependency_providers_.find(feature_type); 385 dependency_providers_.find(feature_type);
556 if (provider == dependency_providers_.end()) 386 if (provider == dependency_providers_.end())
557 return NULL; 387 return NULL;
558 388
559 Feature* feature = provider->second->GetFeature(feature_name); 389 Feature* feature = provider->second->GetFeature(feature_name);
560 // Try getting the feature for the parent API, if this was a child. 390 // Try getting the feature for the parent API, if this was a child.
561 if (!feature) { 391 if (!feature) {
562 std::string child_name; 392 std::string child_name;
563 feature = provider->second->GetFeature( 393 feature = provider->second->GetFeature(
564 GetAPINameFromFullName(feature_name, &child_name)); 394 GetAPINameFromFullName(feature_name, &child_name));
565 } 395 }
566 return feature; 396 return feature;
567 } 397 }
568 398
569 std::string ExtensionAPI::GetAPINameFromFullName(const std::string& full_name, 399 std::string ExtensionAPI::GetAPINameFromFullName(const std::string& full_name,
570 std::string* child_name) { 400 std::string* child_name) {
571 std::string api_name_candidate = full_name; 401 std::string api_name_candidate = full_name;
572 while (true) { 402 while (true) {
573 if (schemas_.find(api_name_candidate) != schemas_.end() || 403 if (schemas_.find(api_name_candidate) != schemas_.end() ||
404 GeneratedSchemas::IsGenerated(api_name_candidate) ||
574 unloaded_schemas_.find(api_name_candidate) != unloaded_schemas_.end()) { 405 unloaded_schemas_.find(api_name_candidate) != unloaded_schemas_.end()) {
575 std::string result = api_name_candidate; 406 std::string result = api_name_candidate;
576 407
577 if (child_name) { 408 if (child_name) {
578 if (result.length() < full_name.length()) 409 if (result.length() < full_name.length())
579 *child_name = full_name.substr(result.length() + 1); 410 *child_name = full_name.substr(result.length() + 1);
580 else 411 else
581 *child_name = ""; 412 *child_name = "";
582 } 413 }
583 414
584 return result; 415 return result;
585 } 416 }
586 417
587 size_t last_dot_index = api_name_candidate.rfind('.'); 418 size_t last_dot_index = api_name_candidate.rfind('.');
588 if (last_dot_index == std::string::npos) 419 if (last_dot_index == std::string::npos)
589 break; 420 break;
590 421
591 api_name_candidate = api_name_candidate.substr(0, last_dot_index); 422 api_name_candidate = api_name_candidate.substr(0, last_dot_index);
592 } 423 }
593 424
594 *child_name = ""; 425 *child_name = "";
595 return std::string(); 426 return std::string();
596 } 427 }
597 428
598 bool ExtensionAPI::IsAPIAllowed(const std::string& name,
599 const Extension* extension) {
600 return PermissionsData::GetRequiredPermissions(extension)->
601 HasAnyAccessToAPI(name) ||
602 PermissionsData::GetOptionalPermissions(extension)->
603 HasAnyAccessToAPI(name);
604 }
605
606 bool ExtensionAPI::IsPrivilegedAPI(const std::string& name) {
607 return completely_unprivileged_apis_.count(name) ||
608 partially_unprivileged_apis_.count(name);
609 }
610
611 } // namespace extensions 429 } // namespace extensions
OLDNEW
« no previous file with comments | « chrome/common/extensions/api/extension_api.h ('k') | chrome/common/extensions/api/extension_api_stub.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698