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

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: comments Created 7 years, 7 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 700 matching lines...) Expand 10 before | Expand all | Expand 10 after
711 } 711 }
712 712
713 v8::Handle<v8::Object> new_object = v8::Object::New(); 713 v8::Handle<v8::Object> new_object = v8::Object::New();
714 object->Set(key, new_object); 714 object->Set(key, new_object);
715 return handle_scope.Close(new_object); 715 return handle_scope.Close(new_object);
716 } 716 }
717 717
718 void Dispatcher::RegisterSchemaGeneratedBindings( 718 void Dispatcher::RegisterSchemaGeneratedBindings(
719 ModuleSystem* module_system, 719 ModuleSystem* module_system,
720 ChromeV8Context* context) { 720 ChromeV8Context* context) {
721 std::set<std::string> apis = 721 std::vector<std::string> apis =
not at google - send to devlin 2013/05/24 19:09:18 also const&
cduvall 2013/05/30 00:50:51 Done.
722 ExtensionAPI::GetSharedInstance()->GetAllAPINames(); 722 BaseFeatureProvider::GetByName("api")->GetAllFeatureNames();
723 for (std::set<std::string>::iterator it = apis.begin(); 723 for (std::vector<std::string>::iterator it = apis.begin();
724 it != apis.end(); ++it) { 724 it != apis.end(); ++it) {
725 const std::string& api_name = *it; 725 const std::string& api_name = *it;
726
727 Feature* feature =
728 BaseFeatureProvider::GetByName("api")->GetFeature(api_name);
not at google - send to devlin 2013/05/24 19:09:18 maybe save a reference to this.
cduvall 2013/05/30 00:50:51 Done.
729 if (feature && (feature->HasParent() || feature->IsInternal()))
not at google - send to devlin 2013/05/24 19:09:18 there should always be a feature here since we're
cduvall 2013/05/30 00:50:51 Done.
730 continue;
731
726 if (!context->IsAnyFeatureAvailableToContext(api_name)) 732 if (!context->IsAnyFeatureAvailableToContext(api_name))
727 continue; 733 continue;
728 734
729 Feature* feature =
730 BaseFeatureProvider::GetByName("api")->GetFeature(api_name);
731 if (feature && feature->IsInternal())
732 continue;
733
734 std::vector<std::string> split; 735 std::vector<std::string> split;
735 base::SplitString(api_name, '.', &split); 736 base::SplitString(api_name, '.', &split);
736 737
737 v8::Handle<v8::Object> bind_object = 738 v8::Handle<v8::Object> bind_object =
738 GetOrCreateChrome(context->v8_context()); 739 GetOrCreateChrome(context->v8_context());
739 740
740 // Check if this API has an ancestor. If the API's ancestor is available and 741 // Check if this API has an ancestor. If the API's ancestor is available and
741 // the API is not available, don't install the bindings for this API. If 742 // the API is not available, don't install the bindings for this API. If
742 // the API is available and its ancestor is not, delete the ancestor and 743 // the API is available and its ancestor is not, delete the ancestor and
743 // install the bindings for the API. This is to prevent loading the ancestor 744 // install the bindings for the API. This is to prevent loading the ancestor
744 // API schema if it will not be needed. 745 // API schema if it will not be needed.
745 // 746 //
746 // For example: 747 // For example:
747 // If app is available and app.window is not, just install app. 748 // If app is available and app.window is not, just install app.
748 // If app.window is available and app is not, delete app and install 749 // If app.window is available and app is not, delete app and install
749 // app.window on a new object so app does not have to be loaded. 750 // app.window on a new object so app does not have to be loaded.
750 std::string ancestor_name; 751 std::string ancestor_name;
751 bool only_ancestor_available = false; 752 bool only_ancestor_available = false;
752 for (size_t i = 0; i < split.size() - 1; ++i) { 753 for (size_t i = 0; i < split.size() - 1; ++i) {
753 ancestor_name += (i ? ".": "") + split[i]; 754 ancestor_name += (i ? ".": "") + split[i];
754 if (!ancestor_name.empty() && 755 if (ancestor_name == "app" &&
755 context->GetAvailability(ancestor_name).is_available() && 756 context->GetAvailability(ancestor_name).is_available() &&
756 !context->GetAvailability(api_name).is_available()) { 757 !context->GetAvailability(api_name).is_available()) {
757 only_ancestor_available = true; 758 only_ancestor_available = true;
758 break; 759 break;
759 } 760 }
760 bind_object = GetOrCreateObject(bind_object, split[i]); 761 bind_object = GetOrCreateObject(bind_object, split[i]);
761 } 762 }
762 if (only_ancestor_available) 763 if (only_ancestor_available)
763 continue; 764 continue;
764 765
(...skipping 650 matching lines...) Expand 10 before | Expand all | Expand 10 after
1415 DLOG(ERROR) << "Not in a v8::Context"; 1416 DLOG(ERROR) << "Not in a v8::Context";
1416 return false; 1417 return false;
1417 } 1418 }
1418 1419
1419 if (!context->extension()) { 1420 if (!context->extension()) {
1420 v8::ThrowException( 1421 v8::ThrowException(
1421 v8::Exception::Error(v8::String::New("Not in an extension."))); 1422 v8::Exception::Error(v8::String::New("Not in an extension.")));
1422 return false; 1423 return false;
1423 } 1424 }
1424 1425
1425 if (!context->extension()->HasAPIPermission(function_name)) {
1426 static const char kMessage[] =
1427 "You do not have permission to use '%s'. Be sure to declare"
1428 " in your manifest what permissions you need.";
1429 std::string error_msg = base::StringPrintf(kMessage, function_name.c_str());
1430 APIActivityLogger::LogBlockedCall(context->extension()->id(),
1431 function_name);
1432 v8::ThrowException(
1433 v8::Exception::Error(v8::String::New(error_msg.c_str())));
1434 return false;
1435 }
1436
1437 if (ExtensionAPI::GetSharedInstance()->IsPrivileged(function_name) &&
1438 context->context_type() != Feature::BLESSED_EXTENSION_CONTEXT) {
1439 static const char kMessage[] =
1440 "%s can only be used in an extension process.";
1441 std::string error_msg = base::StringPrintf(kMessage, function_name.c_str());
1442 v8::ThrowException(
1443 v8::Exception::Error(v8::String::New(error_msg.c_str())));
1444 return false;
1445 }
1446
1447 // Theoretically we could end up with bindings being injected into sandboxed 1426 // Theoretically we could end up with bindings being injected into sandboxed
1448 // frames, for example content scripts. Don't let them execute API functions. 1427 // frames, for example content scripts. Don't let them execute API functions.
1449 WebKit::WebFrame* frame = context->web_frame(); 1428 WebKit::WebFrame* frame = context->web_frame();
1450 ExtensionURLInfo url_info(frame->document().securityOrigin(), 1429 ExtensionURLInfo url_info(frame->document().securityOrigin(),
1451 UserScriptSlave::GetDataSourceURLForFrame(frame)); 1430 UserScriptSlave::GetDataSourceURLForFrame(frame));
1452 if (extensions_.IsSandboxedPage(url_info)) { 1431 if (extensions_.IsSandboxedPage(url_info)) {
1453 static const char kMessage[] = 1432 static const char kMessage[] =
1454 "%s cannot be used within a sandboxed frame."; 1433 "%s cannot be used within a sandboxed frame.";
1455 std::string error_msg = base::StringPrintf(kMessage, function_name.c_str()); 1434 std::string error_msg = base::StringPrintf(kMessage, function_name.c_str());
1456 v8::ThrowException( 1435 v8::ThrowException(
1457 v8::Exception::Error(v8::String::New(error_msg.c_str()))); 1436 v8::Exception::Error(v8::String::New(error_msg.c_str())));
1458 return false; 1437 return false;
1459 } 1438 }
1460 1439
1461 return true; 1440 Feature::Availability availability = context->GetAvailability(function_name);
1441 if (!availability.is_available()) {
1442 v8::ThrowException(v8::Exception::Error(
1443 v8::String::New(availability.message().c_str())));
not at google - send to devlin 2013/05/24 19:09:18 nice
cduvall 2013/05/30 00:50:51 So a side effect of this is that API methods with
not at google - send to devlin 2013/05/30 16:38:51 Cool. That's fine, the right thing to do for now -
1444 }
1445
1446 return availability.is_available();
1462 } 1447 }
1463 1448
1464 } // namespace extensions 1449 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698