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

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: more comments and fixed 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 28 matching lines...) Expand all
39 39
40 const char kUnavailableMessage[] = "You do not have permission to access this " 40 const char kUnavailableMessage[] = "You do not have permission to access this "
41 "API. Ensure that the required permission " 41 "API. Ensure that the required permission "
42 "or manifest property is included in your " 42 "or manifest property is included in your "
43 "manifest.json."; 43 "manifest.json.";
44 const char* kChildKinds[] = { 44 const char* kChildKinds[] = {
45 "functions", 45 "functions",
46 "events" 46 "events"
47 }; 47 };
48 48
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) { 49 base::StringPiece ReadFromResource(int resource_id) {
83 return ResourceBundle::GetSharedInstance().GetRawDataResource( 50 return ResourceBundle::GetSharedInstance().GetRawDataResource(
84 resource_id); 51 resource_id);
85 } 52 }
86 53
87 scoped_ptr<ListValue> LoadSchemaList(const std::string& name, 54 scoped_ptr<ListValue> LoadSchemaList(const std::string& name,
88 const base::StringPiece& schema) { 55 const base::StringPiece& schema) {
89 std::string error_message; 56 std::string error_message;
90 scoped_ptr<Value> result( 57 scoped_ptr<Value> result(
91 base::JSONReader::ReadAndReturnError( 58 base::JSONReader::ReadAndReturnError(
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
245 { 212 {
246 Value* value = NULL; 213 Value* value = NULL;
247 schema_list->Remove(schema_list->GetSize() - 1, &value); 214 schema_list->Remove(schema_list->GetSize() - 1, &value);
248 CHECK(value->IsType(Value::TYPE_DICTIONARY)); 215 CHECK(value->IsType(Value::TYPE_DICTIONARY));
249 schema = static_cast<DictionaryValue*>(value); 216 schema = static_cast<DictionaryValue*>(value);
250 } 217 }
251 218
252 CHECK(schema->GetString("namespace", &schema_namespace)); 219 CHECK(schema->GetString("namespace", &schema_namespace));
253 PrefixWithNamespace(schema_namespace, schema); 220 PrefixWithNamespace(schema_namespace, schema);
254 schemas_[schema_namespace] = make_linked_ptr(schema); 221 schemas_[schema_namespace] = make_linked_ptr(schema);
255 CHECK_EQ(1u, unloaded_schemas_.erase(schema_namespace)); 222 if (!GeneratedSchemas::IsGenerated(schema_namespace))
256 223 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 } 224 }
271 } 225 }
272 226
273 ExtensionAPI::ExtensionAPI() { 227 ExtensionAPI::ExtensionAPI() : default_configuration_initialized_(false) {
274 } 228 }
275 229
276 ExtensionAPI::~ExtensionAPI() { 230 ExtensionAPI::~ExtensionAPI() {
277 } 231 }
278 232
279 void ExtensionAPI::InitDefaultConfiguration() { 233 void ExtensionAPI::InitDefaultConfiguration() {
280 RegisterDependencyProvider( 234 RegisterDependencyProvider(
281 "api", BaseFeatureProvider::GetByName("api")); 235 "api", BaseFeatureProvider::GetByName("api"));
282 RegisterDependencyProvider( 236 RegisterDependencyProvider(
283 "manifest", BaseFeatureProvider::GetByName("manifest")); 237 "manifest", BaseFeatureProvider::GetByName("manifest"));
284 RegisterDependencyProvider( 238 RegisterDependencyProvider(
285 "permission", BaseFeatureProvider::GetByName("permission")); 239 "permission", BaseFeatureProvider::GetByName("permission"));
286 240
287 // Schemas to be loaded from resources. 241 // Schemas to be loaded from resources.
288 CHECK(unloaded_schemas_.empty()); 242 CHECK(unloaded_schemas_.empty());
289 RegisterSchema("app", ReadFromResource( 243 RegisterSchemaResource("app", IDR_EXTENSION_API_JSON_APP);
290 IDR_EXTENSION_API_JSON_APP)); 244 RegisterSchemaResource("browserAction", IDR_EXTENSION_API_JSON_BROWSERACTION);
291 RegisterSchema("browserAction", ReadFromResource( 245 RegisterSchemaResource("browsingData", IDR_EXTENSION_API_JSON_BROWSINGDATA);
292 IDR_EXTENSION_API_JSON_BROWSERACTION)); 246 RegisterSchemaResource("commands", IDR_EXTENSION_API_JSON_COMMANDS);
293 RegisterSchema("browsingData", ReadFromResource( 247 RegisterSchemaResource("declarativeContent",
294 IDR_EXTENSION_API_JSON_BROWSINGDATA)); 248 IDR_EXTENSION_API_JSON_DECLARATIVE_CONTENT);
295 RegisterSchema("commands", ReadFromResource( 249 RegisterSchemaResource("declarativeWebRequest",
296 IDR_EXTENSION_API_JSON_COMMANDS)); 250 IDR_EXTENSION_API_JSON_DECLARATIVE_WEBREQUEST);
297 RegisterSchema("declarativeContent", ReadFromResource( 251 RegisterSchemaResource("experimental.input.virtualKeyboard",
298 IDR_EXTENSION_API_JSON_DECLARATIVE_CONTENT)); 252 IDR_EXTENSION_API_JSON_EXPERIMENTAL_INPUT_VIRTUALKEYBOARD);
299 RegisterSchema("declarativeWebRequest", ReadFromResource( 253 RegisterSchemaResource("experimental.processes",
300 IDR_EXTENSION_API_JSON_DECLARATIVE_WEBREQUEST)); 254 IDR_EXTENSION_API_JSON_EXPERIMENTAL_PROCESSES);
301 RegisterSchema("experimental.input.virtualKeyboard", ReadFromResource( 255 RegisterSchemaResource("experimental.rlz",
302 IDR_EXTENSION_API_JSON_EXPERIMENTAL_INPUT_VIRTUALKEYBOARD)); 256 IDR_EXTENSION_API_JSON_EXPERIMENTAL_RLZ);
303 RegisterSchema("experimental.processes", ReadFromResource( 257 RegisterSchemaResource("runtime", IDR_EXTENSION_API_JSON_RUNTIME);
304 IDR_EXTENSION_API_JSON_EXPERIMENTAL_PROCESSES)); 258 RegisterSchemaResource("fileBrowserHandler",
305 RegisterSchema("experimental.rlz", ReadFromResource( 259 IDR_EXTENSION_API_JSON_FILEBROWSERHANDLER);
306 IDR_EXTENSION_API_JSON_EXPERIMENTAL_RLZ)); 260 RegisterSchemaResource("fileBrowserPrivate",
307 RegisterSchema("runtime", ReadFromResource( 261 IDR_EXTENSION_API_JSON_FILEBROWSERPRIVATE);
308 IDR_EXTENSION_API_JSON_RUNTIME)); 262 RegisterSchemaResource("input.ime", IDR_EXTENSION_API_JSON_INPUT_IME);
309 RegisterSchema("fileBrowserHandler", ReadFromResource( 263 RegisterSchemaResource("inputMethodPrivate",
310 IDR_EXTENSION_API_JSON_FILEBROWSERHANDLER)); 264 IDR_EXTENSION_API_JSON_INPUTMETHODPRIVATE);
311 RegisterSchema("fileBrowserPrivate", ReadFromResource( 265 RegisterSchemaResource("pageAction", IDR_EXTENSION_API_JSON_PAGEACTION);
312 IDR_EXTENSION_API_JSON_FILEBROWSERPRIVATE)); 266 RegisterSchemaResource("pageActions", IDR_EXTENSION_API_JSON_PAGEACTIONS);
313 RegisterSchema("input.ime", ReadFromResource( 267 RegisterSchemaResource("privacy", IDR_EXTENSION_API_JSON_PRIVACY);
314 IDR_EXTENSION_API_JSON_INPUT_IME)); 268 RegisterSchemaResource("proxy", IDR_EXTENSION_API_JSON_PROXY);
315 RegisterSchema("inputMethodPrivate", ReadFromResource( 269 RegisterSchemaResource("scriptBadge", IDR_EXTENSION_API_JSON_SCRIPTBADGE);
316 IDR_EXTENSION_API_JSON_INPUTMETHODPRIVATE)); 270 RegisterSchemaResource("streamsPrivate",
317 RegisterSchema("pageAction", ReadFromResource( 271 IDR_EXTENSION_API_JSON_STREAMSPRIVATE);
318 IDR_EXTENSION_API_JSON_PAGEACTION)); 272 RegisterSchemaResource("ttsEngine", IDR_EXTENSION_API_JSON_TTSENGINE);
319 RegisterSchema("pageActions", ReadFromResource( 273 RegisterSchemaResource("tts", IDR_EXTENSION_API_JSON_TTS);
320 IDR_EXTENSION_API_JSON_PAGEACTIONS)); 274 RegisterSchemaResource("types", IDR_EXTENSION_API_JSON_TYPES);
321 RegisterSchema("privacy", ReadFromResource( 275 RegisterSchemaResource("webRequestInternal",
322 IDR_EXTENSION_API_JSON_PRIVACY)); 276 IDR_EXTENSION_API_JSON_WEBREQUESTINTERNAL);
323 RegisterSchema("proxy", ReadFromResource( 277 RegisterSchemaResource("webstore", IDR_EXTENSION_API_JSON_WEBSTORE);
324 IDR_EXTENSION_API_JSON_PROXY)); 278 RegisterSchemaResource("webstorePrivate",
325 RegisterSchema("scriptBadge", ReadFromResource( 279 IDR_EXTENSION_API_JSON_WEBSTOREPRIVATE);
326 IDR_EXTENSION_API_JSON_SCRIPTBADGE)); 280 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 } 281 }
345 282
346 void ExtensionAPI::RegisterSchema(const std::string& name, 283 void ExtensionAPI::RegisterSchemaResource(const std::string& name,
347 const base::StringPiece& source) { 284 int resource_id) {
348 unloaded_schemas_[name] = source; 285 unloaded_schemas_[name] = resource_id;
349 } 286 }
350 287
351 void ExtensionAPI::RegisterDependencyProvider(const std::string& name, 288 void ExtensionAPI::RegisterDependencyProvider(const std::string& name,
352 FeatureProvider* provider) { 289 FeatureProvider* provider) {
353 dependency_providers_[name] = provider; 290 dependency_providers_[name] = provider;
354 } 291 }
355 292
356 bool ExtensionAPI::IsAnyFeatureAvailableToContext(const std::string& api_name, 293 bool ExtensionAPI::IsAnyFeatureAvailableToContext(const std::string& api_name,
357 Feature::Context context, 294 Feature::Context context,
358 const GURL& url) { 295 const GURL& url) {
359 FeatureProviderMap::iterator provider = dependency_providers_.find("api"); 296 FeatureProviderMap::iterator provider = dependency_providers_.find("api");
360 CHECK(provider != dependency_providers_.end()); 297 CHECK(provider != dependency_providers_.end());
361 std::set<std::string> features = provider->second->GetAllFeatureNames(); 298 const std::vector<std::string>& features =
299 provider->second->GetAllFeatureNames();
362 300
363 // Check to see if there are any parts of this API that are allowed in this 301 // Check to see if there are any parts of this API that are allowed in this
364 // context. 302 // context.
365 for (std::set<std::string>::iterator i = features.begin(); 303 for (std::vector<std::string>::const_iterator i = features.begin();
366 i != features.end(); ++i) { 304 i != features.end(); ++i) {
367 const std::string& feature_name = *i; 305 const std::string& feature_name = *i;
368 if (feature_name != api_name && feature_name.find(api_name + ".") == 0) { 306 if (feature_name != api_name && feature_name.find(api_name + ".") == 0) {
369 if (IsAvailable(feature_name, NULL, context, url).is_available()) 307 if (IsAvailable(feature_name, NULL, context, url).is_available())
370 return true; 308 return true;
371 } 309 }
372 } 310 }
373 return IsAvailable(api_name, NULL, context, url).is_available(); 311 return IsAvailable(api_name, NULL, context, url).is_available();
374 } 312 }
375 313
376 Feature::Availability ExtensionAPI::IsAvailable(const std::string& full_name, 314 Feature::Availability ExtensionAPI::IsAvailable(const std::string& full_name,
377 const Extension* extension, 315 const Extension* extension,
378 Feature::Context context, 316 Feature::Context context,
379 const GURL& url) { 317 const GURL& url) {
380 std::string feature_type; 318 std::string feature_type;
381 std::string feature_name; 319 std::string feature_name;
382 SplitDependencyName(full_name, &feature_type, &feature_name); 320 SplitDependencyName(full_name, &feature_type, &feature_name);
383 321
384 std::string child_name;
385 std::string api_name = GetAPINameFromFullName(feature_name, &child_name);
386
387 Feature* feature = GetFeatureDependency(full_name); 322 Feature* feature = GetFeatureDependency(full_name);
388 323 CHECK(feature);
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 324
398 Feature::Availability availability = 325 Feature::Availability availability =
399 feature->IsAvailableToContext(extension, context, url); 326 feature->IsAvailableToContext(extension, context, url);
400 if (!availability.is_available()) 327 if (!availability.is_available())
401 return availability; 328 return availability;
402 329
403 for (std::set<std::string>::iterator iter = feature->dependencies().begin(); 330 for (std::set<std::string>::iterator iter = feature->dependencies().begin();
404 iter != feature->dependencies().end(); ++iter) { 331 iter != feature->dependencies().end(); ++iter) {
405 Feature::Availability dependency_availability = 332 Feature::Availability dependency_availability =
406 IsAvailable(*iter, extension, context, url); 333 IsAvailable(*iter, extension, context, url);
407 if (!dependency_availability.is_available()) 334 if (!dependency_availability.is_available())
408 return dependency_availability; 335 return dependency_availability;
409 } 336 }
410 337
411 return Feature::CreateAvailability(Feature::IS_AVAILABLE, std::string()); 338 return Feature::CreateAvailability(Feature::IS_AVAILABLE, std::string());
412 } 339 }
413 340
414 bool ExtensionAPI::IsPrivileged(const std::string& full_name) { 341 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); 342 Feature* feature = GetFeatureDependency(full_name);
418 343 CHECK(feature);
419 // First try to use the feature system. 344 DCHECK(!feature->GetContexts()->empty());
420 if (feature) { 345 // 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. 346 return feature->GetContexts()->size() ==
422 return feature->GetContexts()->size() == 347 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 } 348 }
447 349
448 const DictionaryValue* ExtensionAPI::GetSchema(const std::string& full_name) { 350 const DictionaryValue* ExtensionAPI::GetSchema(const std::string& full_name) {
449 std::string child_name; 351 std::string child_name;
450 std::string api_name = GetAPINameFromFullName(full_name, &child_name); 352 std::string api_name = GetAPINameFromFullName(full_name, &child_name);
451 353
452 const DictionaryValue* result = NULL; 354 const DictionaryValue* result = NULL;
453 SchemaMap::iterator maybe_schema = schemas_.find(api_name); 355 SchemaMap::iterator maybe_schema = schemas_.find(api_name);
454 if (maybe_schema != schemas_.end()) { 356 if (maybe_schema != schemas_.end()) {
455 result = maybe_schema->second.get(); 357 result = maybe_schema->second.get();
456 } else { 358 } else {
457 // Might not have loaded yet; or might just not exist. 359 // Might not have loaded yet; or might just not exist.
458 std::map<std::string, base::StringPiece>::iterator maybe_schema_resource = 360 UnloadedSchemaMap::iterator maybe_schema_resource =
459 unloaded_schemas_.find(api_name); 361 unloaded_schemas_.find(api_name);
460 if (maybe_schema_resource == unloaded_schemas_.end()) 362 if (maybe_schema_resource != unloaded_schemas_.end()) {
363 LoadSchema(maybe_schema_resource->first,
364 ReadFromResource(maybe_schema_resource->second));
365 } else if (default_configuration_initialized_ &&
366 GeneratedSchemas::IsGenerated(api_name)) {
367 LoadSchema(api_name, GeneratedSchemas::Get(api_name));
368 } else {
461 return NULL; 369 return NULL;
370 }
462 371
463 LoadSchema(maybe_schema_resource->first, maybe_schema_resource->second);
464 maybe_schema = schemas_.find(api_name); 372 maybe_schema = schemas_.find(api_name);
465 CHECK(schemas_.end() != maybe_schema); 373 CHECK(schemas_.end() != maybe_schema);
466 result = maybe_schema->second.get(); 374 result = maybe_schema->second.get();
467 } 375 }
468 376
469 if (!child_name.empty()) 377 if (!child_name.empty())
470 result = GetSchemaChild(result, child_name); 378 result = GetSchemaChild(result, child_name);
471 379
472 return result; 380 return result;
473 } 381 }
474 382
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) { 383 Feature* ExtensionAPI::GetFeatureDependency(const std::string& full_name) {
550 std::string feature_type; 384 std::string feature_type;
551 std::string feature_name; 385 std::string feature_name;
552 SplitDependencyName(full_name, &feature_type, &feature_name); 386 SplitDependencyName(full_name, &feature_type, &feature_name);
553 387
554 FeatureProviderMap::iterator provider = 388 FeatureProviderMap::iterator provider =
555 dependency_providers_.find(feature_type); 389 dependency_providers_.find(feature_type);
556 if (provider == dependency_providers_.end()) 390 if (provider == dependency_providers_.end())
557 return NULL; 391 return NULL;
558 392
559 Feature* feature = provider->second->GetFeature(feature_name); 393 Feature* feature = provider->second->GetFeature(feature_name);
560 // Try getting the feature for the parent API, if this was a child. 394 // Try getting the feature for the parent API, if this was a child.
561 if (!feature) { 395 if (!feature) {
562 std::string child_name; 396 std::string child_name;
563 feature = provider->second->GetFeature( 397 feature = provider->second->GetFeature(
564 GetAPINameFromFullName(feature_name, &child_name)); 398 GetAPINameFromFullName(feature_name, &child_name));
565 } 399 }
566 return feature; 400 return feature;
567 } 401 }
568 402
569 std::string ExtensionAPI::GetAPINameFromFullName(const std::string& full_name, 403 std::string ExtensionAPI::GetAPINameFromFullName(const std::string& full_name,
570 std::string* child_name) { 404 std::string* child_name) {
571 std::string api_name_candidate = full_name; 405 std::string api_name_candidate = full_name;
572 while (true) { 406 while (true) {
573 if (schemas_.find(api_name_candidate) != schemas_.end() || 407 if (schemas_.find(api_name_candidate) != schemas_.end() ||
408 GeneratedSchemas::IsGenerated(api_name_candidate) ||
574 unloaded_schemas_.find(api_name_candidate) != unloaded_schemas_.end()) { 409 unloaded_schemas_.find(api_name_candidate) != unloaded_schemas_.end()) {
575 std::string result = api_name_candidate; 410 std::string result = api_name_candidate;
576 411
577 if (child_name) { 412 if (child_name) {
578 if (result.length() < full_name.length()) 413 if (result.length() < full_name.length())
579 *child_name = full_name.substr(result.length() + 1); 414 *child_name = full_name.substr(result.length() + 1);
580 else 415 else
581 *child_name = ""; 416 *child_name = "";
582 } 417 }
583 418
584 return result; 419 return result;
585 } 420 }
586 421
587 size_t last_dot_index = api_name_candidate.rfind('.'); 422 size_t last_dot_index = api_name_candidate.rfind('.');
588 if (last_dot_index == std::string::npos) 423 if (last_dot_index == std::string::npos)
589 break; 424 break;
590 425
591 api_name_candidate = api_name_candidate.substr(0, last_dot_index); 426 api_name_candidate = api_name_candidate.substr(0, last_dot_index);
592 } 427 }
593 428
594 *child_name = ""; 429 *child_name = "";
595 return std::string(); 430 return std::string();
596 } 431 }
597 432
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 433 } // namespace extensions
not at google - send to devlin 2013/05/30 16:38:52 reducing file size by 30%! awesome.
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698