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/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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |