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

Unified Diff: chrome/renderer/extensions/dispatcher.cc

Issue 11571014: Lazy load chrome.* APIs (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: comments/TODOs Created 7 years, 11 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 side-by-side diff with in-line comments
Download patch
Index: chrome/renderer/extensions/dispatcher.cc
diff --git a/chrome/renderer/extensions/dispatcher.cc b/chrome/renderer/extensions/dispatcher.cc
index 8d5aa46be680cc3f0cc83e31da6df41c0a7e41d2..bd0d241ea7fca6f43def02c988a9bc6037157e70 100644
--- a/chrome/renderer/extensions/dispatcher.cc
+++ b/chrome/renderer/extensions/dispatcher.cc
@@ -36,11 +36,12 @@
#include "chrome/renderer/extensions/media_galleries_custom_bindings.h"
#include "chrome/renderer/extensions/miscellaneous_bindings.h"
#include "chrome/renderer/extensions/module_system.h"
-#include "chrome/renderer/extensions/native_handler.h"
+#include "chrome/renderer/extensions/object_backed_native_handler.h"
#include "chrome/renderer/extensions/page_actions_custom_bindings.h"
#include "chrome/renderer/extensions/page_capture_custom_bindings.h"
#include "chrome/renderer/extensions/request_sender.h"
#include "chrome/renderer/extensions/runtime_custom_bindings.h"
+#include "chrome/renderer/extensions/schema_generated_native_handler.h"
#include "chrome/renderer/extensions/send_request_natives.h"
#include "chrome/renderer/extensions/set_icon_natives.h"
#include "chrome/renderer/extensions/sync_file_system_custom_bindings.h"
@@ -87,7 +88,38 @@ static const char kEventDispatchFunction[] = "Event.dispatchEvent";
static const char kOnUnloadEvent[] = "runtime.onSuspend";
static const char kOnSuspendCanceledEvent[] = "runtime.onSuspendCanceled";
-class ChromeHiddenNativeHandler : public NativeHandler {
+static v8::Handle<v8::Object> GetOrCreateChrome(
+ v8::Handle<v8::Context> context) {
+ v8::Handle<v8::String> chrome_string(v8::String::New("chrome"));
+ v8::Handle<v8::Object> global(context->Global());
+ v8::Handle<v8::Value> chrome(global->Get(chrome_string));
+ if (chrome.IsEmpty() || chrome->IsUndefined()) {
+ v8::Handle<v8::Object> chrome_object(v8::Object::New());
+ global->Set(chrome_string, chrome_object);
+ return chrome_object;
+ }
+ CHECK(chrome->IsObject());
+ return chrome->ToObject();
+}
+
+class SchemaRegistryNativeHandler : public ObjectBackedNativeHandler {
+ public:
+ SchemaRegistryNativeHandler(V8SchemaRegistry* registry)
+ : registry_(registry) {
+ RouteFunction("GetSchema",
+ base::Bind(&SchemaRegistryNativeHandler::GetSchema,
+ base::Unretained(this)));
+ }
+
+ private:
+ v8::Handle<v8::Value> GetSchema(const v8::Arguments& args) {
+ return registry_->GetSchema(*v8::String::AsciiValue(args[0]));
+ }
+
+ V8SchemaRegistry* registry_;
+};
+
+class ChromeHiddenNativeHandler : public ObjectBackedNativeHandler {
public:
ChromeHiddenNativeHandler() {
RouteFunction("GetChromeHidden",
@@ -100,7 +132,19 @@ class ChromeHiddenNativeHandler : public NativeHandler {
}
};
-class PrintNativeHandler : public NativeHandler {
+class ChromeNativeHandler : public ObjectBackedNativeHandler {
+ public:
+ ChromeNativeHandler() {
+ RouteFunction("GetChrome",
+ base::Bind(&ChromeNativeHandler::GetChrome, base::Unretained(this)));
+ }
+
+ v8::Handle<v8::Value> GetChrome(const v8::Arguments& args) {
+ return GetOrCreateChrome(v8::Context::GetCurrent());
+ }
+};
+
+class PrintNativeHandler : public ObjectBackedNativeHandler {
public:
PrintNativeHandler() {
RouteFunction("Print",
@@ -234,7 +278,7 @@ class ProcessInfoNativeHandler : public ChromeV8Extension {
bool send_request_disabled_;
};
-class LoggingNativeHandler : public NativeHandler {
+class LoggingNativeHandler : public ObjectBackedNativeHandler {
public:
LoggingNativeHandler() {
RouteFunction("DCHECK",
@@ -297,20 +341,6 @@ void InstallWebstoreBindings(ModuleSystem* module_system,
"chromeHiddenWebstore");
}
-static v8::Handle<v8::Object> GetOrCreateChrome(
- v8::Handle<v8::Context> context) {
- v8::Handle<v8::String> chrome_string(v8::String::New("chrome"));
- v8::Handle<v8::Object> global(context->Global());
- v8::Handle<v8::Value> chrome(global->Get(chrome_string));
- if (chrome.IsEmpty() || chrome->IsUndefined()) {
- v8::Handle<v8::Object> chrome_object(v8::Object::New());
- global->Set(chrome_string, chrome_object);
- return chrome_object;
- }
- CHECK(chrome->IsObject());
- return chrome->ToObject();
-}
-
} // namespace
Dispatcher::Dispatcher()
@@ -552,6 +582,86 @@ bool Dispatcher::AllowScriptExtension(WebFrame* frame,
return true;
}
+void Dispatcher::SetUpChainedField(v8::Handle<v8::Object> object,
+ const std::string& field,
+ const std::string& module_name,
+ const std::string& module_field,
+ ModuleSystem* module_system,
+ LazyFieldSetter setter) {
+ size_t prev = -1, next = field.find_first_of(".");
+ std::vector<std::string> parts;
+ // TODO(cduvall): Clean up.
+ while (next != std::string::npos) {
+ parts.push_back(field.substr(prev + 1, next - prev - 1));
+ prev = next;
+ next = field.find_first_of(".", prev + 1);
+ }
+ parts.push_back(field.substr(prev + 1));
+
+ v8::Handle<v8::Object> current = object;
+ for (size_t i = 0; i < parts.size() - 1; i++) {
+ v8::Handle<v8::String> key = v8::String::New(parts[i].c_str());
+ if (current->Has(key)) {
+ current = v8::Handle<v8::Object>::Cast(current->Get(key));
+ } else {
+ v8::Handle<v8::Object> new_object = v8::Object::New();
+ current->Set(key, new_object);
+ current = new_object;
+ }
+ }
+
+ (module_system->*setter)(current, parts.back(), module_name, module_field);
+}
+
+void Dispatcher::RegisterSchemaGeneratedBindings(
+ ModuleSystem* module_system,
+ ChromeV8Context* context,
+ v8::Handle<v8::Context> v8_context) {
+ std::set<std::string> apis =
+ ExtensionAPI::GetSharedInstance()->GetAllAPINames();
+ for (std::set<std::string>::iterator it = apis.begin();
+ it != apis.end(); ++it) {
+ const std::string& api_name = *it;
+ if (lazy_bindings_map_.find(api_name) != lazy_bindings_map_.end()) {
+ InstallBindings(module_system, v8_context, api_name);
+ // If there isn't already a custom binding for this API, we need to make
+ // sure one exists to load the schema. Otherwise the custom binding will
+ // need to do it itself. Either way, register it on the chrome object to be
+ // loaded lazily.
+ } else if (!source_map_.Contains(api_name)) {
+ module_system->RegisterNativeHandler(
+ api_name,
+ scoped_ptr<NativeHandler>(new SchemaGeneratedNativeHandler(
+ module_system,
+ v8_schema_registry(),
+ api_name,
+ "bindings")));
+ SetUpChainedField(GetOrCreateChrome(v8_context),
+ api_name,
+ api_name,
+ "bindings",
+ module_system,
+ &ModuleSystem::SetNativeLazyField);
+ } else {
+ // TODO(cduvall): Handle apitest.
+ SetUpChainedField(GetOrCreateChrome(v8_context),
+ api_name,
+ api_name,
+ "bindings",
+ module_system,
+ &ModuleSystem::SetLazyField);
+ }
+ }
not at google - send to devlin 2013/01/25 00:44:31 I feel like this should look more like const std:
cduvall 2013/02/12 02:13:47 Done.
+ module_system->SetLazyField(GetOrCreateChrome(v8_context),
+ "Event",
+ "event_bindings",
not at google - send to devlin 2013/01/25 00:44:31 would it work to make schema_binding_generator req
cduvall 2013/02/12 02:13:47 Done.
+ "bindings");
+ module_system->SetLazyField(GetOrCreateChrome(v8_context),
not at google - send to devlin 2013/01/25 00:44:31 Maybe we should fix that test thing before submitt
+ "test",
+ "apitest",
+ "bindings");
+}
+
void Dispatcher::RegisterNativeHandlers(ModuleSystem* module_system,
ChromeV8Context* context) {
module_system->RegisterNativeHandler("event_bindings",
@@ -678,6 +788,8 @@ void Dispatcher::PopulateSourceMap() {
source_map_.RegisterSource("webRequestInternal",
IDR_WEB_REQUEST_INTERNAL_CUSTOM_BINDINGS_JS);
source_map_.RegisterSource("webstore", IDR_WEBSTORE_CUSTOM_BINDINGS_JS);
+ source_map_.RegisterSource("schema_binding_generator",
+ IDR_SCHEMA_BINDING_GENERATOR_JS);
// Platform app sources that are not API-specific..
source_map_.RegisterSource("tagWatcher", IDR_TAG_WATCHER_JS);
@@ -754,6 +866,8 @@ void Dispatcher::DidCreateScriptContext(
RegisterNativeHandlers(module_system.get(), context);
+ module_system->RegisterNativeHandler("chrome",
+ scoped_ptr<NativeHandler>(new ChromeNativeHandler()));
module_system->RegisterNativeHandler("chrome_hidden",
scoped_ptr<NativeHandler>(new ChromeHiddenNativeHandler()));
module_system->RegisterNativeHandler("print",
@@ -762,6 +876,9 @@ void Dispatcher::DidCreateScriptContext(
scoped_ptr<NativeHandler>(new LazyBackgroundPageNativeHandler(this)));
module_system->RegisterNativeHandler("logging",
scoped_ptr<NativeHandler>(new LoggingNativeHandler()));
+ module_system->RegisterNativeHandler("schema_registry",
+ scoped_ptr<NativeHandler>(
+ new SchemaRegistryNativeHandler(v8_schema_registry())));
int manifest_version = extension ? extension->manifest_version() : 1;
bool send_request_disabled =
@@ -785,24 +902,19 @@ void Dispatcher::DidCreateScriptContext(
InstallBindings(module_system.get(), v8_context, "app");
InstallBindings(module_system.get(), v8_context, "webstore");
break;
-
case Feature::BLESSED_EXTENSION_CONTEXT:
case Feature::UNBLESSED_EXTENSION_CONTEXT:
case Feature::CONTENT_SCRIPT_CONTEXT: {
- module_system->Require("miscellaneous_bindings");
- module_system->Require("schema_generated_bindings");
- module_system->Require("apitest");
+ if (extension && !extension->is_platform_app())
+ module_system->Require("miscellaneous_bindings");
+ RegisterSchemaGeneratedBindings(module_system.get(),
+ context,
+ v8_context);
// TODO(kalman): move this code back out of the switch and execute it
// regardless of |context_type|. ExtensionAPI knows how to return the
// correct APIs, however, until it doesn't have a 2MB overhead we can't
// load it in every process.
- const std::set<std::string>& apis = context->GetAvailableExtensionAPIs();
- for (std::set<std::string>::const_iterator i = apis.begin();
- i != apis.end(); ++i) {
- InstallBindings(module_system.get(), v8_context, *i);
- }
-
break;
}
}

Powered by Google App Engine
This is Rietveld 408576698