Chromium Code Reviews| 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 18 matching lines...) Expand all Loading... | |
| 29 using base::DictionaryValue; | 29 using base::DictionaryValue; |
| 30 using base::ListValue; | 30 using base::ListValue; |
| 31 using base::Value; | 31 using base::Value; |
| 32 | 32 |
| 33 namespace extensions { | 33 namespace extensions { |
| 34 | 34 |
| 35 using api::GeneratedSchemas; | 35 using api::GeneratedSchemas; |
| 36 | 36 |
| 37 namespace { | 37 namespace { |
| 38 | 38 |
| 39 const char kUnavailableMessage[] = "You do not have permission to access this " | |
| 40 "API. Ensure that the required permission " | |
| 41 "or manifest property is included in your " | |
| 42 "manifest.json."; | |
| 39 const char* kChildKinds[] = { | 43 const char* kChildKinds[] = { |
| 40 "functions", | 44 "functions", |
| 41 "events" | 45 "events" |
| 42 }; | 46 }; |
| 43 | 47 |
| 44 // Returns true if |dict| has an unprivileged "true" property. | 48 // Returns true if |dict| has an unprivileged "true" property. |
| 45 bool IsUnprivileged(const DictionaryValue* dict) { | 49 bool IsUnprivileged(const DictionaryValue* dict) { |
| 46 bool unprivileged = false; | 50 bool unprivileged = false; |
| 47 return dict->GetBoolean("unprivileged", &unprivileged) && unprivileged; | 51 return dict->GetBoolean("unprivileged", &unprivileged) && unprivileged; |
| 48 } | 52 } |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 223 // TODO(aa): Remove this code when all API descriptions have been updated. | 227 // TODO(aa): Remove this code when all API descriptions have been updated. |
| 224 *feature_type = "api"; | 228 *feature_type = "api"; |
| 225 *feature_name = full_name; | 229 *feature_name = full_name; |
| 226 return; | 230 return; |
| 227 } | 231 } |
| 228 | 232 |
| 229 *feature_type = full_name.substr(0, colon_index); | 233 *feature_type = full_name.substr(0, colon_index); |
| 230 *feature_name = full_name.substr(colon_index + 1); | 234 *feature_name = full_name.substr(colon_index + 1); |
| 231 } | 235 } |
| 232 | 236 |
| 237 bool ExtensionAPI::UsesFeatureSystem(const std::string& full_name) { | |
| 238 std::string api_name = GetAPINameFromFullName(full_name, NULL); | |
| 239 return features_.find(api_name) != features_.end(); | |
| 240 } | |
| 241 | |
| 233 void ExtensionAPI::LoadSchema(const std::string& name, | 242 void ExtensionAPI::LoadSchema(const std::string& name, |
| 234 const base::StringPiece& schema) { | 243 const base::StringPiece& schema) { |
| 235 scoped_ptr<ListValue> schema_list(LoadSchemaList(name, schema)); | 244 scoped_ptr<ListValue> schema_list(LoadSchemaList(name, schema)); |
| 236 std::string schema_namespace; | 245 std::string schema_namespace; |
| 237 | 246 |
| 238 while (!schema_list->empty()) { | 247 while (!schema_list->empty()) { |
| 239 DictionaryValue* schema = NULL; | 248 DictionaryValue* schema = NULL; |
| 240 { | 249 { |
| 241 Value* value = NULL; | 250 Value* value = NULL; |
| 242 schema_list->Remove(schema_list->GetSize() - 1, &value); | 251 schema_list->Remove(schema_list->GetSize() - 1, &value); |
| 243 CHECK(value->IsType(Value::TYPE_DICTIONARY)); | 252 CHECK(value->IsType(Value::TYPE_DICTIONARY)); |
| 244 schema = static_cast<DictionaryValue*>(value); | 253 schema = static_cast<DictionaryValue*>(value); |
| 245 } | 254 } |
| 246 | 255 |
| 247 CHECK(schema->GetString("namespace", &schema_namespace)); | 256 CHECK(schema->GetString("namespace", &schema_namespace)); |
| 248 PrefixWithNamespace(schema_namespace, schema); | 257 PrefixWithNamespace(schema_namespace, schema); |
| 249 schemas_[schema_namespace] = make_linked_ptr(schema); | 258 schemas_[schema_namespace] = make_linked_ptr(schema); |
| 250 CHECK_EQ(1u, unloaded_schemas_.erase(schema_namespace)); | 259 CHECK_EQ(1u, unloaded_schemas_.erase(schema_namespace)); |
| 251 | 260 |
| 252 // Populate |{completely,partially}_unprivileged_apis_|. | 261 // Populate |{completely,partially}_unprivileged_apis_|. |
| 253 // | 262 |
| 254 // For "partially", only need to look at functions/events; even though | 263 // For "partially", only need to look at functions/events; even though |
| 255 // there are unprivileged properties (e.g. in extensions), access to those | 264 // there are unprivileged properties (e.g. in extensions), access to those |
| 256 // never reaches C++ land. | 265 // never reaches C++ land. |
| 257 bool unprivileged = false; | 266 bool unprivileged = false; |
| 258 if (schema->GetBoolean("unprivileged", &unprivileged) && unprivileged) { | 267 if (schema->GetBoolean("unprivileged", &unprivileged) && unprivileged) { |
| 259 completely_unprivileged_apis_.insert(schema_namespace); | 268 completely_unprivileged_apis_.insert(schema_namespace); |
| 260 } else if (HasUnprivilegedChild(schema, "functions") || | 269 } else if (HasUnprivilegedChild(schema, "functions") || |
| 261 HasUnprivilegedChild(schema, "events") || | 270 HasUnprivilegedChild(schema, "events") || |
| 262 HasUnprivilegedChild(schema, "properties")) { | 271 HasUnprivilegedChild(schema, "properties")) { |
| 263 partially_unprivileged_apis_.insert(schema_namespace); | 272 partially_unprivileged_apis_.insert(schema_namespace); |
| 264 } | 273 } |
| 265 | 274 |
| 266 // Populate |url_matching_apis_|. | 275 bool uses_feature_system = false; |
| 267 ListValue* matches = NULL; | 276 schema->GetBoolean("uses_feature_system", &uses_feature_system); |
| 268 if (schema->GetList("matches", &matches)) { | 277 |
| 269 URLPatternSet pattern_set; | 278 if (!uses_feature_system) { |
| 270 for (size_t i = 0; i < matches->GetSize(); ++i) { | 279 // Populate |url_matching_apis_|. |
| 271 std::string pattern; | 280 ListValue* matches = NULL; |
| 272 CHECK(matches->GetString(i, &pattern)); | 281 if (schema->GetList("matches", &matches)) { |
| 273 pattern_set.AddPattern( | 282 URLPatternSet pattern_set; |
| 274 URLPattern(UserScript::ValidUserScriptSchemes(), pattern)); | 283 for (size_t i = 0; i < matches->GetSize(); ++i) { |
| 284 std::string pattern; | |
| 285 CHECK(matches->GetString(i, &pattern)); | |
| 286 pattern_set.AddPattern( | |
| 287 URLPattern(UserScript::ValidUserScriptSchemes(), pattern)); | |
| 288 } | |
| 289 url_matching_apis_[schema_namespace] = pattern_set; | |
| 275 } | 290 } |
| 276 url_matching_apis_[schema_namespace] = pattern_set; | 291 continue; |
| 277 } | 292 } |
| 278 | 293 |
| 279 // Populate feature maps. | 294 // Populate feature maps. |
| 280 // TODO(aa): Consider not storing features that can never run on the current | 295 // TODO(aa): Consider not storing features that can never run on the current |
| 281 // machine (e.g., because of platform restrictions). | 296 // machine (e.g., because of platform restrictions). |
| 282 bool uses_feature_system = false; | |
| 283 schema->GetBoolean("uses_feature_system", &uses_feature_system); | |
| 284 if (!uses_feature_system) | |
| 285 continue; | |
| 286 | |
| 287 SimpleFeature* feature = new SimpleFeature(); | 297 SimpleFeature* feature = new SimpleFeature(); |
| 288 feature->set_name(schema_namespace); | 298 feature->set_name(schema_namespace); |
| 289 feature->Parse(schema); | 299 feature->Parse(schema); |
| 290 | 300 |
| 291 FeatureMap* schema_features = new FeatureMap(); | 301 FeatureMap* schema_features = new FeatureMap(); |
| 292 CHECK(features_.insert( | 302 CHECK(features_.insert( |
| 293 std::make_pair(schema_namespace, | 303 std::make_pair(schema_namespace, |
| 294 make_linked_ptr(schema_features))).second); | 304 make_linked_ptr(schema_features))).second); |
| 295 CHECK(schema_features->insert( | 305 CHECK(schema_features->insert( |
| 296 std::make_pair("", make_linked_ptr(feature))).second); | 306 std::make_pair("", make_linked_ptr(feature))).second); |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 401 void ExtensionAPI::RegisterSchema(const std::string& name, | 411 void ExtensionAPI::RegisterSchema(const std::string& name, |
| 402 const base::StringPiece& source) { | 412 const base::StringPiece& source) { |
| 403 unloaded_schemas_[name] = source; | 413 unloaded_schemas_[name] = source; |
| 404 } | 414 } |
| 405 | 415 |
| 406 void ExtensionAPI::RegisterDependencyProvider(const std::string& name, | 416 void ExtensionAPI::RegisterDependencyProvider(const std::string& name, |
| 407 FeatureProvider* provider) { | 417 FeatureProvider* provider) { |
| 408 dependency_providers_[name] = provider; | 418 dependency_providers_[name] = provider; |
| 409 } | 419 } |
| 410 | 420 |
| 411 bool ExtensionAPI::IsAvailable(const std::string& full_name, | 421 Feature::Availability ExtensionAPI::IsAvailable(const std::string& full_name, |
| 412 const Extension* extension, | 422 const Extension* extension, |
| 413 Feature::Context context) { | 423 Feature::Context context, |
| 424 const GURL& url) { | |
| 414 std::set<std::string> dependency_names; | 425 std::set<std::string> dependency_names; |
| 415 dependency_names.insert(full_name); | 426 dependency_names.insert(full_name); |
| 416 ResolveDependencies(&dependency_names); | 427 ResolveDependencies(&dependency_names); |
| 417 | |
| 418 for (std::set<std::string>::iterator iter = dependency_names.begin(); | 428 for (std::set<std::string>::iterator iter = dependency_names.begin(); |
| 419 iter != dependency_names.end(); ++iter) { | 429 iter != dependency_names.end(); ++iter) { |
| 430 //////////////////////////////////////////////////////////////////////////// | |
| 431 // TODO(cduvall): Take this out once all APIs have been converted to | |
| 432 // features. | |
| 433 std::string feature_type; | |
| 434 std::string feature_name; | |
| 435 SplitDependencyName(*iter, &feature_type, &feature_name); | |
| 436 if (feature_type == "api" && !UsesFeatureSystem(feature_name)) { | |
|
cduvall
2013/03/22 20:26:45
This now *should* never happen since non-features
not at google - send to devlin
2013/03/22 22:10:12
Nah just take it out, code will be safe by virtue
cduvall
2013/03/22 22:52:29
Done.
| |
| 437 // Check the parent feature's availability if there are dependencies. | |
| 438 if (!IsNonFeatureAPIAvailable(feature_name, context, extension, url)) | |
| 439 return Feature::CreateAvailability(Feature::INVALID_CONTEXT, | |
| 440 kUnavailableMessage); | |
| 441 continue; | |
| 442 } | |
| 443 //////////////////////////////////////////////////////////////////////////// | |
| 444 | |
| 445 // This seems wrong. The dependencies aren't checked, it just checks the | |
| 446 // parent feature again. Changing to check dependencies makes these fail: | |
| 447 // ExtensionApiTest.OptionalPermissionsGranted | |
| 448 // ExtensionApiTest.OptionalPermissionsAutoConfirm | |
| 449 // ExtensionApiTest.OptionalPermissionsDeny | |
| 450 // | |
| 451 // Checking dependencies would mean that some APIs, like chrome.bookmarks | |
| 452 // would now be required to be in the manifest permissions when they | |
| 453 // previously did not need to be (the bookmarks API has the | |
| 454 // permission:bookmarks dependency). This seems like it would break a lot | |
| 455 // of things. | |
| 420 Feature* feature = GetFeatureDependency(full_name); | 456 Feature* feature = GetFeatureDependency(full_name); |
|
cduvall
2013/03/22 20:26:45
Still not quite sure what to do here. Check the ac
not at google - send to devlin
2013/03/22 22:10:12
see long IRC essay
not at google - send to devlin
2013/03/22 22:10:12
IRC resolved this right/
cduvall
2013/03/22 22:52:29
Yep, resolved.
| |
| 421 CHECK(feature) << *iter; | 457 CHECK(feature) << *iter; |
| 422 | 458 |
| 423 Feature::Availability availability = | 459 Feature::Availability availability = |
| 424 feature->IsAvailableToContext(extension, context); | 460 feature->IsAvailableToContext(extension, context, url); |
| 425 if (!availability.is_available()) | 461 if (!availability.is_available()) |
| 426 return false; | 462 return availability; |
| 427 } | 463 } |
| 428 | 464 |
| 429 return true; | 465 return Feature::CreateAvailability(Feature::IS_AVAILABLE, ""); |
| 430 } | 466 } |
| 431 | 467 |
| 432 bool ExtensionAPI::IsPrivileged(const std::string& full_name) { | 468 bool ExtensionAPI::IsPrivileged(const std::string& full_name) { |
| 433 std::string child_name; | 469 std::string child_name; |
| 434 std::string api_name = GetAPINameFromFullName(full_name, &child_name); | 470 std::string api_name = GetAPINameFromFullName(full_name, &child_name); |
| 435 | 471 |
| 436 // First try to use the feature system. | 472 // First try to use the feature system. |
| 437 Feature* feature(GetFeature(full_name)); | 473 Feature* feature(GetFeature(full_name)); |
| 438 if (feature) { | 474 if (feature) { |
| 439 // An API is 'privileged' if it or any of its dependencies can only be run | 475 // An API is 'privileged' if it or any of its dependencies can only be run |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 517 if (extension.is_platform_app()) { | 553 if (extension.is_platform_app()) { |
| 518 for (size_t i = 0; i < arraysize(kDisallowedPlatformAppFeatures); ++i) { | 554 for (size_t i = 0; i < arraysize(kDisallowedPlatformAppFeatures); ++i) { |
| 519 if (feature == kDisallowedPlatformAppFeatures[i]) | 555 if (feature == kDisallowedPlatformAppFeatures[i]) |
| 520 return false; | 556 return false; |
| 521 } | 557 } |
| 522 } | 558 } |
| 523 | 559 |
| 524 return true; | 560 return true; |
| 525 } | 561 } |
| 526 | 562 |
| 527 // Removes APIs from |apis| that should not be allowed for |extension|. | |
| 528 // TODO(kalman/asargent) - Make it possible to specify these rules | |
| 529 // declaratively. | |
| 530 void RemoveDisallowedAPIs(const Extension& extension, | |
| 531 std::set<std::string>* apis) { | |
| 532 CHECK(apis); | |
| 533 std::set<std::string>::iterator i = apis->begin(); | |
| 534 while (i != apis->end()) { | |
| 535 if (!IsFeatureAllowedForExtension(*i, extension)) { | |
| 536 apis->erase(i++); | |
| 537 } else { | |
| 538 ++i; | |
| 539 } | |
| 540 } | |
| 541 } | |
| 542 | |
| 543 } // namespace | 563 } // namespace |
| 544 | 564 |
| 545 std::set<std::string> ExtensionAPI::GetAPIsForContext( | 565 bool ExtensionAPI::IsNonFeatureAPIAvailable(const std::string& name, |
| 546 Feature::Context context, const Extension* extension, const GURL& url) { | 566 Feature::Context context, |
| 547 // We're forced to load all schemas now because we need to know the metadata | 567 const Extension* extension, |
| 548 // about every API -- and the metadata is stored in the schemas themselves. | 568 const GURL& url) { |
| 549 // This is a shame. | |
| 550 // TODO(aa/kalman): store metadata in a separate file and don't load all | |
| 551 // schemas. | |
| 552 LoadAllSchemas(); | |
| 553 | |
| 554 std::set<std::string> temp_result; | |
| 555 | |
| 556 // First handle all the APIs that have been converted to the feature system. | |
| 557 if (extension) { | |
| 558 for (APIFeatureMap::iterator iter = features_.begin(); | |
| 559 iter != features_.end(); ++iter) { | |
| 560 if (IsAvailable(iter->first, extension, context)) | |
| 561 temp_result.insert(iter->first); | |
| 562 } | |
| 563 } | |
| 564 | |
| 565 // Second, fall back to the old way. | |
| 566 // TODO(aa): Remove this when all APIs have been converted. | |
| 567 switch (context) { | 569 switch (context) { |
| 568 case Feature::UNSPECIFIED_CONTEXT: | 570 case Feature::UNSPECIFIED_CONTEXT: |
| 569 break; | 571 break; |
| 570 | 572 |
| 571 case Feature::BLESSED_EXTENSION_CONTEXT: | 573 case Feature::BLESSED_EXTENSION_CONTEXT: |
| 572 if (extension) { | 574 if (extension) { |
| 573 // Availability is determined by the permissions of the extension. | 575 // Availability is determined by the permissions of the extension. |
| 574 GetAllowedAPIs(extension, &temp_result); | 576 if (!IsAPIAllowed(name, extension)) |
| 575 ResolveDependencies(&temp_result); | 577 return false; |
| 576 RemoveDisallowedAPIs(*extension, &temp_result); | 578 if (!IsFeatureAllowedForExtension(name, *extension)) |
| 579 return false; | |
| 577 } | 580 } |
| 578 break; | 581 break; |
| 579 | 582 |
| 580 case Feature::UNBLESSED_EXTENSION_CONTEXT: | 583 case Feature::UNBLESSED_EXTENSION_CONTEXT: |
| 581 case Feature::CONTENT_SCRIPT_CONTEXT: | 584 case Feature::CONTENT_SCRIPT_CONTEXT: |
| 582 if (extension) { | 585 if (extension) { |
| 583 // Same as BLESSED_EXTENSION_CONTEXT, but only those APIs that are | 586 // Same as BLESSED_EXTENSION_CONTEXT, but only those APIs that are |
| 584 // unprivileged. | 587 // unprivileged. |
| 585 GetAllowedAPIs(extension, &temp_result); | 588 if (!IsAPIAllowed(name, extension)) |
| 586 // Resolving dependencies before removing unprivileged APIs means that | 589 return false; |
| 587 // some unprivileged APIs may have unrealised dependencies. Too bad! | 590 if (!IsPrivilegedAPI(name)) |
| 588 ResolveDependencies(&temp_result); | 591 return false; |
| 589 RemovePrivilegedAPIs(&temp_result); | |
| 590 } | 592 } |
| 591 break; | 593 break; |
| 592 | 594 |
| 593 case Feature::WEB_PAGE_CONTEXT: | 595 case Feature::WEB_PAGE_CONTEXT: |
| 594 if (url.is_valid()) { | 596 if (!url_matching_apis_.count(name)) |
| 595 // Availablility is determined by the url. | 597 return false; |
| 596 GetAPIsMatchingURL(url, &temp_result); | 598 CHECK(url.is_valid()); |
| 597 } | 599 // Availablility is determined by the url. |
| 598 break; | 600 return url_matching_apis_[name].MatchesURL(url); |
| 599 } | 601 } |
| 600 | 602 |
| 601 // Filter out all non-API features and remove the feature type part of the | 603 return true; |
| 602 // name. | |
| 603 std::set<std::string> result; | |
| 604 for (std::set<std::string>::iterator iter = temp_result.begin(); | |
| 605 iter != temp_result.end(); ++iter) { | |
| 606 std::string feature_type; | |
| 607 std::string feature_name; | |
| 608 SplitDependencyName(*iter, &feature_type, &feature_name); | |
| 609 if (feature_type == "api") | |
| 610 result.insert(feature_name); | |
| 611 } | |
| 612 | |
| 613 return result; | |
| 614 } | 604 } |
| 615 | 605 |
| 616 std::set<std::string> ExtensionAPI::GetAllAPINames() { | 606 std::set<std::string> ExtensionAPI::GetAllAPINames() { |
| 617 std::set<std::string> result; | 607 std::set<std::string> result; |
| 618 for (SchemaMap::iterator i = schemas_.begin(); i != schemas_.end(); ++i) | 608 for (SchemaMap::iterator i = schemas_.begin(); i != schemas_.end(); ++i) |
| 619 result.insert(i->first); | 609 result.insert(i->first); |
| 620 for (UnloadedSchemaMap::iterator i = unloaded_schemas_.begin(); | 610 for (UnloadedSchemaMap::iterator i = unloaded_schemas_.begin(); |
| 621 i != unloaded_schemas_.end(); ++i) { | 611 i != unloaded_schemas_.end(); ++i) { |
| 622 result.insert(i->first); | 612 result.insert(i->first); |
| 623 } | 613 } |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 692 if (last_dot_index == std::string::npos) | 682 if (last_dot_index == std::string::npos) |
| 693 break; | 683 break; |
| 694 | 684 |
| 695 api_name_candidate = api_name_candidate.substr(0, last_dot_index); | 685 api_name_candidate = api_name_candidate.substr(0, last_dot_index); |
| 696 } | 686 } |
| 697 | 687 |
| 698 *child_name = ""; | 688 *child_name = ""; |
| 699 return ""; | 689 return ""; |
| 700 } | 690 } |
| 701 | 691 |
| 702 void ExtensionAPI::GetAllowedAPIs( | 692 bool ExtensionAPI::IsAPIAllowed(const std::string& name, |
| 703 const Extension* extension, std::set<std::string>* out) { | 693 const Extension* extension) { |
| 704 for (SchemaMap::const_iterator i = schemas_.begin(); i != schemas_.end(); | 694 return extension->required_permission_set()->HasAnyAccessToAPI(name) || |
| 705 ++i) { | 695 extension->optional_permission_set()->HasAnyAccessToAPI(name); |
| 706 if (features_.find(i->first) != features_.end()) { | |
| 707 // This API is controlled by the feature system. Nothing to do here. | |
| 708 continue; | |
| 709 } | |
| 710 | |
| 711 if (extension->required_permission_set()->HasAnyAccessToAPI(i->first) || | |
| 712 extension->optional_permission_set()->HasAnyAccessToAPI(i->first)) { | |
| 713 out->insert(i->first); | |
| 714 } | |
| 715 } | |
| 716 } | 696 } |
| 717 | 697 |
| 718 void ExtensionAPI::ResolveDependencies(std::set<std::string>* out) { | 698 void ExtensionAPI::ResolveDependencies(std::set<std::string>* out) { |
| 719 std::set<std::string> missing_dependencies; | 699 std::set<std::string> missing_dependencies; |
| 720 for (std::set<std::string>::iterator i = out->begin(); i != out->end(); ++i) | 700 for (std::set<std::string>::iterator i = out->begin(); i != out->end(); ++i) |
| 721 GetMissingDependencies(*i, *out, &missing_dependencies); | 701 GetMissingDependencies(*i, *out, &missing_dependencies); |
| 722 | 702 |
| 723 while (missing_dependencies.size()) { | 703 while (missing_dependencies.size()) { |
| 724 std::string next = *missing_dependencies.begin(); | 704 std::string next = *missing_dependencies.begin(); |
| 725 missing_dependencies.erase(next); | 705 missing_dependencies.erase(next); |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 749 | 729 |
| 750 for (size_t i = 0; i < dependencies->GetSize(); ++i) { | 730 for (size_t i = 0; i < dependencies->GetSize(); ++i) { |
| 751 std::string dependency_name; | 731 std::string dependency_name; |
| 752 if (dependencies->GetString(i, &dependency_name) && | 732 if (dependencies->GetString(i, &dependency_name) && |
| 753 !excluding.count(dependency_name)) { | 733 !excluding.count(dependency_name)) { |
| 754 out->insert(dependency_name); | 734 out->insert(dependency_name); |
| 755 } | 735 } |
| 756 } | 736 } |
| 757 } | 737 } |
| 758 | 738 |
| 759 void ExtensionAPI::RemovePrivilegedAPIs(std::set<std::string>* apis) { | 739 bool ExtensionAPI::IsPrivilegedAPI(const std::string& name) { |
| 760 std::set<std::string> privileged_apis; | 740 return completely_unprivileged_apis_.count(name) || |
| 761 for (std::set<std::string>::iterator i = apis->begin(); i != apis->end(); | 741 partially_unprivileged_apis_.count(name); |
| 762 ++i) { | |
| 763 if (!completely_unprivileged_apis_.count(*i) && | |
| 764 !partially_unprivileged_apis_.count(*i)) { | |
| 765 privileged_apis.insert(*i); | |
| 766 } | |
| 767 } | |
| 768 for (std::set<std::string>::iterator i = privileged_apis.begin(); | |
| 769 i != privileged_apis.end(); ++i) { | |
| 770 apis->erase(*i); | |
| 771 } | |
| 772 } | |
| 773 | |
| 774 void ExtensionAPI::GetAPIsMatchingURL(const GURL& url, | |
| 775 std::set<std::string>* out) { | |
| 776 for (std::map<std::string, URLPatternSet>::const_iterator i = | |
| 777 url_matching_apis_.begin(); i != url_matching_apis_.end(); ++i) { | |
| 778 if (features_.find(i->first) != features_.end()) { | |
| 779 // This API is controlled by the feature system. Nothing to do. | |
| 780 continue; | |
| 781 } | |
| 782 | |
| 783 if (i->second.MatchesURL(url)) | |
| 784 out->insert(i->first); | |
| 785 } | |
| 786 } | |
| 787 | |
| 788 void ExtensionAPI::LoadAllSchemas() { | |
| 789 while (unloaded_schemas_.size()) { | |
| 790 std::map<std::string, base::StringPiece>::iterator it = | |
| 791 unloaded_schemas_.begin(); | |
| 792 LoadSchema(it->first, it->second); | |
| 793 } | |
| 794 } | 742 } |
| 795 | 743 |
| 796 } // namespace extensions | 744 } // namespace extensions |
| OLD | NEW |