Index: extensions/renderer/dispatcher.cc |
diff --git a/extensions/renderer/dispatcher.cc b/extensions/renderer/dispatcher.cc |
index df828dcc4856a49e5c627612b396d2fcf7f4df75..4630fb78300d3ded5f50c1cecd13ee2e1806eaf7 100644 |
--- a/extensions/renderer/dispatcher.cc |
+++ b/extensions/renderer/dispatcher.cc |
@@ -41,6 +41,7 @@ |
#include "extensions/common/features/behavior_feature.h" |
#include "extensions/common/features/feature.h" |
#include "extensions/common/features/feature_provider.h" |
+#include "extensions/common/features/feature_util.h" |
#include "extensions/common/manifest.h" |
#include "extensions/common/manifest_constants.h" |
#include "extensions/common/manifest_handlers/background_info.h" |
@@ -98,6 +99,7 @@ |
#include "extensions/renderer/v8_helpers.h" |
#include "extensions/renderer/wake_event_page.h" |
#include "extensions/renderer/worker_script_context_set.h" |
+#include "extensions/renderer/worker_thread_dispatcher.h" |
#include "grit/extensions_renderer_resources.h" |
#include "mojo/public/js/constants.h" |
#include "third_party/WebKit/public/platform/WebString.h" |
@@ -109,6 +111,7 @@ |
#include "third_party/WebKit/public/web/WebLocalFrame.h" |
#include "third_party/WebKit/public/web/WebRuntimeFeatures.h" |
#include "third_party/WebKit/public/web/WebScopedUserGesture.h" |
+#include "third_party/WebKit/public/web/WebScriptController.h" |
#include "third_party/WebKit/public/web/WebSecurityPolicy.h" |
#include "third_party/WebKit/public/web/WebView.h" |
#include "ui/base/layout.h" |
@@ -232,6 +235,11 @@ Dispatcher::Dispatcher(DispatcherDelegate* delegate) |
request_sender_.reset(new RequestSender(this)); |
PopulateSourceMap(); |
WakeEventPage::Get()->Init(RenderThread::Get()); |
+ // Ideally this should be done after checking |
+ // ExtensionAPIEnabledInExtensionServiceWorkers(), but the Dispatcher is |
+ // created so early that sending an IPC from browser/ process to synchronize |
+ // this enabled-ness is too late. |
+ WorkerThreadDispatcher::Get()->Init(RenderThread::Get()); |
RenderThread::Get()->RegisterExtension(SafeBuiltins::CreateV8Extension()); |
@@ -330,7 +338,8 @@ void Dispatcher::DidCreateScriptContext( |
// Enable natives in startup. |
ModuleSystem::NativesEnabledScope natives_enabled_scope(module_system); |
- RegisterNativeHandlers(module_system, context); |
+ RegisterNativeHandlers(module_system, context, request_sender_.get(), |
+ v8_schema_registry_.get()); |
// chrome.Event is part of the public API (although undocumented). Make it |
// lazily evalulate to Event from event_bindings.js. For extensions only |
@@ -389,8 +398,16 @@ void Dispatcher::DidCreateScriptContext( |
} |
// static |
+void Dispatcher::InstallV8ExtensionForServiceWorkers() { |
+ if (feature_util::ExtensionAPIEnabledInExtensionServiceWorkers()) { |
+ blink::WebScriptController::registerExtensionForServiceWorkerScript( |
+ SafeBuiltins::CreateV8Extension()); |
+ } |
+} |
+ |
void Dispatcher::DidInitializeServiceWorkerContextOnWorkerThread( |
v8::Local<v8::Context> v8_context, |
+ int embedded_worker_id, |
const GURL& url) { |
const base::TimeTicks start_time = base::TimeTicks::Now(); |
@@ -435,6 +452,37 @@ void Dispatcher::DidInitializeServiceWorkerContextOnWorkerThread( |
extension, Feature::SERVICE_WORKER_CONTEXT); |
context->set_url(url); |
+ if (feature_util::ExtensionAPIEnabledInExtensionServiceWorkers()) { |
+ WorkerThreadDispatcher::Get()->AddWorkerData(embedded_worker_id); |
+ { |
+ // TODO(lazyboy): Make sure accessing |source_map_| in worker thread is |
+ // safe. |
+ std::unique_ptr<ModuleSystem> module_system( |
+ new ModuleSystem(context, &source_map_)); |
+ context->set_module_system(std::move(module_system)); |
+ } |
+ |
+ ModuleSystem* module_system = context->module_system(); |
+ // Enable natives in startup. |
+ ModuleSystem::NativesEnabledScope natives_enabled_scope(module_system); |
+ RegisterNativeHandlers( |
+ module_system, context, |
+ WorkerThreadDispatcher::Get()->GetRequestSender(), |
+ WorkerThreadDispatcher::Get()->GetV8SchemaRegistry()); |
+ // chrome.Event is part of the public API (although undocumented). Make it |
+ // lazily evalulate to Event from event_bindings.js. |
+ v8::Local<v8::Object> chrome = AsObjectOrEmpty(GetOrCreateChrome(context)); |
+ if (!chrome.IsEmpty()) |
+ module_system->SetLazyField(chrome, "Event", kEventBindings, "Event"); |
+ |
+ UpdateBindingsForContext(context); |
+ // TODO(lazyboy): Get rid of RequireGuestViewModules() as this doesn't seem |
+ // necessary for Extension SW. |
+ RequireGuestViewModules(context); |
+ delegate_->RequireAdditionalModules(context, |
+ false /* is_within_platform_app */); |
+ } |
+ |
g_worker_script_context_set.Get().Insert(make_scoped_ptr(context)); |
v8::Isolate* isolate = context->isolate(); |
@@ -499,12 +547,15 @@ void Dispatcher::WillReleaseScriptContext( |
// static |
void Dispatcher::WillDestroyServiceWorkerContextOnWorkerThread( |
v8::Local<v8::Context> v8_context, |
+ int embedded_worker_id, |
const GURL& url) { |
if (url.SchemeIs(kExtensionScheme) || |
url.SchemeIs(kExtensionResourceScheme)) { |
// See comment in DidInitializeServiceWorkerContextOnWorkerThread. |
g_worker_script_context_set.Get().Remove(v8_context, url); |
} |
+ if (feature_util::ExtensionAPIEnabledInExtensionServiceWorkers()) |
+ WorkerThreadDispatcher::Get()->RemoveWorkerData(embedded_worker_id); |
} |
void Dispatcher::DidCreateDocumentElement(blink::WebLocalFrame* frame) { |
@@ -917,6 +968,9 @@ bool Dispatcher::OnControlMessageReceived(const IPC::Message& message) { |
IPC_MESSAGE_HANDLER(ExtensionMsg_Loaded, OnLoaded) |
IPC_MESSAGE_HANDLER(ExtensionMsg_MessageInvoke, OnMessageInvoke) |
IPC_MESSAGE_HANDLER(ExtensionMsg_SetChannel, OnSetChannel) |
+ IPC_MESSAGE_HANDLER( |
+ ExtensionMsg_SetExtensionAPIEnabledInExtensionServiceWorkers, |
+ OnSetExtensionAPIEnabledInExtensionServiceWorkers) |
IPC_MESSAGE_HANDLER(ExtensionMsg_SetScriptingWhitelist, |
OnSetScriptingWhitelist) |
IPC_MESSAGE_HANDLER(ExtensionMsg_SetSystemFont, OnSetSystemFont) |
@@ -1091,6 +1145,11 @@ void Dispatcher::OnSetChannel(int channel) { |
delegate_->SetChannel(channel); |
} |
+void Dispatcher::OnSetExtensionAPIEnabledInExtensionServiceWorkers( |
+ bool enabled) { |
+ feature_util::SetExtensionAPIEnabledInExtensionServiceWorkers(enabled); |
+} |
+ |
void Dispatcher::OnSetScriptingWhitelist( |
const ExtensionsClient::ScriptingWhitelist& extension_ids) { |
ExtensionsClient::Get()->SetScriptingWhitelist(extension_ids); |
@@ -1317,6 +1376,8 @@ void Dispatcher::UpdateBindings(const std::string& extension_id) { |
base::Unretained(this))); |
} |
+// Note: this function runs on multiple threads: main renderer thread and |
+// service worker threads. |
void Dispatcher::UpdateBindingsForContext(ScriptContext* context) { |
v8::HandleScope handle_scope(context->isolate()); |
v8::Context::Scope context_scope(context->v8_context()); |
@@ -1341,6 +1402,9 @@ void Dispatcher::UpdateBindingsForContext(ScriptContext* context) { |
UpdateContentCapabilities(context); |
break; |
+ case Feature::SERVICE_WORKER_CONTEXT: |
+ DCHECK(feature_util::ExtensionAPIEnabledInExtensionServiceWorkers()); |
+ // Intentional fallthrough. |
case Feature::BLESSED_EXTENSION_CONTEXT: |
case Feature::UNBLESSED_EXTENSION_CONTEXT: |
case Feature::CONTENT_SCRIPT_CONTEXT: |
@@ -1367,15 +1431,14 @@ void Dispatcher::UpdateBindingsForContext(ScriptContext* context) { |
continue; |
} |
- if (context->IsAnyFeatureAvailableToContext(*map_entry.second.get())) |
+ if (context->IsAnyFeatureAvailableToContext(*map_entry.second.get())) { |
+ // TODO(lazyboy): RegisterBinding() uses |source_map_|, any thread |
+ // safety issue? |
RegisterBinding(map_entry.first, context); |
+ } |
} |
break; |
} |
- case Feature::SERVICE_WORKER_CONTEXT: |
- // Handled in DidInitializeServiceWorkerContextOnWorkerThread(). |
- NOTREACHED(); |
- break; |
} |
} |
@@ -1423,12 +1486,11 @@ void Dispatcher::RegisterBinding(const std::string& api_name, |
// NOTE: please use the naming convention "foo_natives" for these. |
void Dispatcher::RegisterNativeHandlers(ModuleSystem* module_system, |
- ScriptContext* context) { |
- RegisterNativeHandlers(module_system, |
- context, |
- this, |
- request_sender_.get(), |
- v8_schema_registry_.get()); |
+ ScriptContext* context, |
+ RequestSender* request_sender, |
+ V8SchemaRegistry* v8_schema_registry) { |
+ RegisterNativeHandlers(module_system, context, this, request_sender, |
+ v8_schema_registry); |
const Extension* extension = context->extension(); |
int manifest_version = extension ? extension->manifest_version() : 1; |
bool is_component_extension = |
@@ -1499,6 +1561,7 @@ bool Dispatcher::IsWithinPlatformApp() { |
return false; |
} |
+// static. |
v8::Local<v8::Object> Dispatcher::GetOrCreateObject( |
const v8::Local<v8::Object>& object, |
const std::string& field, |
@@ -1520,6 +1583,7 @@ v8::Local<v8::Object> Dispatcher::GetOrCreateObject( |
return new_object; |
} |
+// static. |
v8::Local<v8::Object> Dispatcher::GetOrCreateBindObjectIfAvailable( |
const std::string& api_name, |
std::string* bind_name, |