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

Side by Side Diff: chrome/renderer/extensions/dispatcher.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/renderer/extensions/dispatcher.h" 5 #include "chrome/renderer/extensions/dispatcher.h"
6 6
7 #include "base/callback.h" 7 #include "base/callback.h"
8 #include "base/command_line.h" 8 #include "base/command_line.h"
9 #include "base/debug/alias.h" 9 #include "base/debug/alias.h"
10 #include "base/json/json_reader.h" 10 #include "base/json/json_reader.h"
(...skipping 704 matching lines...) Expand 10 before | Expand all | Expand 10 after
715 } 715 }
716 716
717 v8::Handle<v8::Object> new_object = v8::Object::New(); 717 v8::Handle<v8::Object> new_object = v8::Object::New();
718 object->Set(key, new_object); 718 object->Set(key, new_object);
719 return handle_scope.Close(new_object); 719 return handle_scope.Close(new_object);
720 } 720 }
721 721
722 void Dispatcher::RegisterSchemaGeneratedBindings( 722 void Dispatcher::RegisterSchemaGeneratedBindings(
723 ModuleSystem* module_system, 723 ModuleSystem* module_system,
724 ChromeV8Context* context) { 724 ChromeV8Context* context) {
725 std::set<std::string> apis = 725 FeatureProvider* feature_provider = BaseFeatureProvider::GetByName("api");
726 ExtensionAPI::GetSharedInstance()->GetAllAPINames(); 726 const std::vector<std::string>& apis = feature_provider->GetAllFeatureNames();
727 for (std::set<std::string>::iterator it = apis.begin(); 727 for (std::vector<std::string>::const_iterator it = apis.begin();
728 it != apis.end(); ++it) { 728 it != apis.end(); ++it) {
729 const std::string& api_name = *it; 729 const std::string& api_name = *it;
730
731 Feature* feature = feature_provider->GetFeature(api_name);
732 DCHECK(feature);
733 if (feature->HasParent() || feature->IsInternal())
734 continue;
735
730 if (!context->IsAnyFeatureAvailableToContext(api_name)) 736 if (!context->IsAnyFeatureAvailableToContext(api_name))
731 continue; 737 continue;
not at google - send to devlin 2013/05/30 16:38:52 without the parent this is going to get trickier.
cduvall 2013/06/12 01:22:19 I ended up keeping the HasParent(), and just using
732 738
733 Feature* feature =
734 BaseFeatureProvider::GetByName("api")->GetFeature(api_name);
735 if (feature && feature->IsInternal())
736 continue;
737
738 std::vector<std::string> split; 739 std::vector<std::string> split;
739 base::SplitString(api_name, '.', &split); 740 base::SplitString(api_name, '.', &split);
740 741
741 v8::Handle<v8::Object> bind_object = 742 v8::Handle<v8::Object> bind_object =
742 GetOrCreateChrome(context->v8_context()); 743 GetOrCreateChrome(context->v8_context());
743 744
744 // Check if this API has an ancestor. If the API's ancestor is available and 745 // Check if this API has an ancestor. If the API's ancestor is available and
745 // the API is not available, don't install the bindings for this API. If 746 // the API is not available, don't install the bindings for this API. If
746 // the API is available and its ancestor is not, delete the ancestor and 747 // the API is available and its ancestor is not, delete the ancestor and
747 // install the bindings for the API. This is to prevent loading the ancestor 748 // install the bindings for the API. This is to prevent loading the ancestor
748 // API schema if it will not be needed. 749 // API schema if it will not be needed.
749 // 750 //
750 // For example: 751 // For example:
751 // If app is available and app.window is not, just install app. 752 // If app is available and app.window is not, just install app.
752 // If app.window is available and app is not, delete app and install 753 // If app.window is available and app is not, delete app and install
753 // app.window on a new object so app does not have to be loaded. 754 // app.window on a new object so app does not have to be loaded.
754 std::string ancestor_name; 755 std::string ancestor_name;
755 bool only_ancestor_available = false; 756 bool only_ancestor_available = false;
756 for (size_t i = 0; i < split.size() - 1; ++i) { 757 for (size_t i = 0; i < split.size() - 1; ++i) {
757 ancestor_name += (i ? ".": "") + split[i]; 758 ancestor_name += (i ? ".": "") + split[i];
758 if (!ancestor_name.empty() && 759 if (ancestor_name == "app" &&
759 context->GetAvailability(ancestor_name).is_available() && 760 context->GetAvailability(ancestor_name).is_available() &&
760 !context->GetAvailability(api_name).is_available()) { 761 !context->GetAvailability(api_name).is_available()) {
761 only_ancestor_available = true; 762 only_ancestor_available = true;
762 break; 763 break;
763 } 764 }
764 bind_object = GetOrCreateObject(bind_object, split[i]); 765 bind_object = GetOrCreateObject(bind_object, split[i]);
765 } 766 }
766 if (only_ancestor_available) 767 if (only_ancestor_available)
767 continue; 768 continue;
768 769
(...skipping 650 matching lines...) Expand 10 before | Expand all | Expand 10 after
1419 DLOG(ERROR) << "Not in a v8::Context"; 1420 DLOG(ERROR) << "Not in a v8::Context";
1420 return false; 1421 return false;
1421 } 1422 }
1422 1423
1423 if (!context->extension()) { 1424 if (!context->extension()) {
1424 v8::ThrowException( 1425 v8::ThrowException(
1425 v8::Exception::Error(v8::String::New("Not in an extension."))); 1426 v8::Exception::Error(v8::String::New("Not in an extension.")));
1426 return false; 1427 return false;
1427 } 1428 }
1428 1429
1429 if (!context->extension()->HasAPIPermission(function_name)) {
1430 static const char kMessage[] =
1431 "You do not have permission to use '%s'. Be sure to declare"
1432 " in your manifest what permissions you need.";
1433 std::string error_msg = base::StringPrintf(kMessage, function_name.c_str());
1434 APIActivityLogger::LogBlockedCall(context->extension()->id(),
1435 function_name);
1436 v8::ThrowException(
1437 v8::Exception::Error(v8::String::New(error_msg.c_str())));
1438 return false;
1439 }
1440
1441 if (ExtensionAPI::GetSharedInstance()->IsPrivileged(function_name) &&
1442 context->context_type() != Feature::BLESSED_EXTENSION_CONTEXT) {
1443 static const char kMessage[] =
1444 "%s can only be used in an extension process.";
1445 std::string error_msg = base::StringPrintf(kMessage, function_name.c_str());
1446 v8::ThrowException(
1447 v8::Exception::Error(v8::String::New(error_msg.c_str())));
1448 return false;
1449 }
1450
1451 // Theoretically we could end up with bindings being injected into sandboxed 1430 // Theoretically we could end up with bindings being injected into sandboxed
1452 // frames, for example content scripts. Don't let them execute API functions. 1431 // frames, for example content scripts. Don't let them execute API functions.
1453 WebKit::WebFrame* frame = context->web_frame(); 1432 WebKit::WebFrame* frame = context->web_frame();
1454 ExtensionURLInfo url_info(frame->document().securityOrigin(), 1433 ExtensionURLInfo url_info(frame->document().securityOrigin(),
1455 UserScriptSlave::GetDataSourceURLForFrame(frame)); 1434 UserScriptSlave::GetDataSourceURLForFrame(frame));
1456 if (extensions_.IsSandboxedPage(url_info)) { 1435 if (extensions_.IsSandboxedPage(url_info)) {
1457 static const char kMessage[] = 1436 static const char kMessage[] =
1458 "%s cannot be used within a sandboxed frame."; 1437 "%s cannot be used within a sandboxed frame.";
1459 std::string error_msg = base::StringPrintf(kMessage, function_name.c_str()); 1438 std::string error_msg = base::StringPrintf(kMessage, function_name.c_str());
1460 v8::ThrowException( 1439 v8::ThrowException(
1461 v8::Exception::Error(v8::String::New(error_msg.c_str()))); 1440 v8::Exception::Error(v8::String::New(error_msg.c_str())));
1462 return false; 1441 return false;
1463 } 1442 }
1464 1443
1465 return true; 1444 Feature::Availability availability = context->GetAvailability(function_name);
1445 if (!availability.is_available()) {
1446 v8::ThrowException(v8::Exception::Error(
1447 v8::String::New(availability.message().c_str())));
1448 }
1449
1450 return availability.is_available();
1466 } 1451 }
1467 1452
1468 } // namespace extensions 1453 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698