From a7fc1264e00391787a5c473255c39d4bfbd4bc90 Mon Sep 17 00:00:00 2001 From: annekao Date: Tue, 11 Aug 2015 12:25:27 -0700 Subject: [PATCH] [Extension ServiceWorkers] Chrome: Passing v8::context to extensions dispatcher Pass the v8::context from the worker thread up to the extensions dispatcher. In the dispatcher, 42 is binded to "chrome" for testing purposes. Please view https://codereview.chromium.org/1264913002/ for the implementation done in blink. BUG=501569 Review URL: https://codereview.chromium.org/1256323008 Cr-Commit-Position: refs/heads/master@{#342864} --- .../browser/extensions/service_worker_apitest.cc | 24 ++++++++++++++++++++++ chrome/renderer/chrome_content_renderer_client.cc | 10 +++++++++ chrome/renderer/chrome_content_renderer_client.h | 5 ++++- .../api_test/service_worker/bindings/manifest.json | 10 +++++++++ .../api_test/service_worker/bindings/page.html | 2 ++ .../api_test/service_worker/bindings/page.js | 20 ++++++++++++++++++ .../api_test/service_worker/bindings/sw.js | 7 +++++++ .../api_test/service_worker/bindings/test.js | 5 +++++ content/public/renderer/content_renderer_client.h | 6 ++++++ .../service_worker_context_client.cc | 9 ++++++++ .../service_worker/service_worker_context_client.h | 3 +++ extensions/renderer/dispatcher.cc | 11 ++++++++++ extensions/renderer/dispatcher.h | 5 +++++ 13 files changed, 116 insertions(+), 1 deletion(-) create mode 100644 chrome/test/data/extensions/api_test/service_worker/bindings/manifest.json create mode 100644 chrome/test/data/extensions/api_test/service_worker/bindings/page.html create mode 100644 chrome/test/data/extensions/api_test/service_worker/bindings/page.js create mode 100644 chrome/test/data/extensions/api_test/service_worker/bindings/sw.js create mode 100644 chrome/test/data/extensions/api_test/service_worker/bindings/test.js diff --git a/chrome/browser/extensions/service_worker_apitest.cc b/chrome/browser/extensions/service_worker_apitest.cc index 933cb3160372..9523bae7d260 100644 --- a/chrome/browser/extensions/service_worker_apitest.cc +++ b/chrome/browser/extensions/service_worker_apitest.cc @@ -65,4 +65,28 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerTest, ServiceWorkerFetchEvent) { EXPECT_EQ("Caught a fetch!", output); } +// Binding that was created on the v8::Context of the worker for testing +// purposes should bind an empty object to chrome. +IN_PROC_BROWSER_TEST_F(ServiceWorkerTest, ServiceWorkerChromeBinding) { + ASSERT_TRUE(RunExtensionTest("service_worker/bindings")) << message_; + content::WebContents* contents = + browser()->tab_strip_model()->GetActiveWebContents(); + content::WaitForLoadStop(contents); + + std::string output; + ASSERT_TRUE(content::ExecuteScriptAndExtractString( + contents, "window.domAutomationController.send(document.body.innerText);", + &output)); + EXPECT_EQ("No Fetch Event yet.", output); + + // Page must reload in order for the service worker to take control. + contents->GetController().Reload(true); + content::WaitForLoadStop(contents); + + ASSERT_TRUE(content::ExecuteScriptAndExtractString( + contents, "window.domAutomationController.send(document.body.innerText);", + &output)); + EXPECT_EQ("object", output); +} + } // namespace extensions diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc index d925fe3a1f2b..a2a7bedf638c 100644 --- a/chrome/renderer/chrome_content_renderer_client.cc +++ b/chrome/renderer/chrome_content_renderer_client.cc @@ -1631,3 +1631,13 @@ void ChromeContentRendererClient::AddImageContextMenuProperties( data_reduction_proxy::chrome_proxy_lo_fi_directive(); } } + +void +ChromeContentRendererClient::DidInitializeServiceWorkerContextOnWorkerThread( + v8::Local context, + const GURL& url) { +#if defined(ENABLE_EXTENSIONS) + extensions::Dispatcher::DidInitializeServiceWorkerContextOnWorkerThread( + context, url); +#endif +} diff --git a/chrome/renderer/chrome_content_renderer_client.h b/chrome/renderer/chrome_content_renderer_client.h index cd1f3df60c2e..bafd24fd348e 100644 --- a/chrome/renderer/chrome_content_renderer_client.h +++ b/chrome/renderer/chrome_content_renderer_client.h @@ -15,6 +15,7 @@ #include "base/strings/string16.h" #include "content/public/renderer/content_renderer_client.h" #include "ipc/ipc_channel_proxy.h" +#include "v8/include/v8.h" class ChromeExtensionsDispatcherDelegate; class ChromeRenderProcessObserver; @@ -153,7 +154,9 @@ class ChromeContentRendererClient : public content::ContentRendererClient { void AddImageContextMenuProperties( const blink::WebURLResponse& response, std::map* properties) override; - + void DidInitializeServiceWorkerContextOnWorkerThread( + v8::Local context, + const GURL& url) override; #if defined(ENABLE_EXTENSIONS) // Takes ownership. void SetExtensionDispatcherForTest( diff --git a/chrome/test/data/extensions/api_test/service_worker/bindings/manifest.json b/chrome/test/data/extensions/api_test/service_worker/bindings/manifest.json new file mode 100644 index 000000000000..89dba049e40d --- /dev/null +++ b/chrome/test/data/extensions/api_test/service_worker/bindings/manifest.json @@ -0,0 +1,10 @@ +{ + "name": "Service Worker Bindings", + "version": "0.1", + "manifest_version": 2, + "description": "Test for service worker bindings", + "permissions": ["tabs"], + "background": { + "scripts": ["test.js"] + } +} diff --git a/chrome/test/data/extensions/api_test/service_worker/bindings/page.html b/chrome/test/data/extensions/api_test/service_worker/bindings/page.html new file mode 100644 index 000000000000..cbfdf2677ec5 --- /dev/null +++ b/chrome/test/data/extensions/api_test/service_worker/bindings/page.html @@ -0,0 +1,2 @@ +No Fetch Event yet. + \ No newline at end of file diff --git a/chrome/test/data/extensions/api_test/service_worker/bindings/page.js b/chrome/test/data/extensions/api_test/service_worker/bindings/page.js new file mode 100644 index 000000000000..e9698a74a98e --- /dev/null +++ b/chrome/test/data/extensions/api_test/service_worker/bindings/page.js @@ -0,0 +1,20 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +var logForDebugging = false; +function log(message) { + if (logForDebugging) + console.log(message); +} +navigator.serviceWorker.register('/sw.js').then(function(registration) { + // Registration was successful + log('ServiceWorker registration successful with scope: ', + registration.scope); + chrome.test.succeed(); +}).catch(function(err) { + // registration failed :( + var errorMsg = err.name + ': ' + err.message; + log('ServiceWorker registration failed: ' + errorMsg); + chrome.test.fail(); +}); diff --git a/chrome/test/data/extensions/api_test/service_worker/bindings/sw.js b/chrome/test/data/extensions/api_test/service_worker/bindings/sw.js new file mode 100644 index 000000000000..1bec850dc081 --- /dev/null +++ b/chrome/test/data/extensions/api_test/service_worker/bindings/sw.js @@ -0,0 +1,7 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +self.addEventListener('fetch', function(event) { + event.respondWith(new Response(typeof chrome)); +}); \ No newline at end of file diff --git a/chrome/test/data/extensions/api_test/service_worker/bindings/test.js b/chrome/test/data/extensions/api_test/service_worker/bindings/test.js new file mode 100644 index 000000000000..2497dc84f994 --- /dev/null +++ b/chrome/test/data/extensions/api_test/service_worker/bindings/test.js @@ -0,0 +1,5 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +chrome.tabs.create({url: chrome.extension.getURL("page.html")}); diff --git a/content/public/renderer/content_renderer_client.h b/content/public/renderer/content_renderer_client.h index ebb7f4453079..837ba55fa070 100644 --- a/content/public/renderer/content_renderer_client.h +++ b/content/public/renderer/content_renderer_client.h @@ -297,6 +297,12 @@ class CONTENT_EXPORT ContentRendererClient { virtual void AddImageContextMenuProperties( const blink::WebURLResponse& response, std::map* properties) {} + + // Notifies that a service worker context has been created. This function + // is called from the worker thread. + virtual void DidInitializeServiceWorkerContextOnWorkerThread( + v8::Local context, + const GURL& url) {} }; } // namespace content diff --git a/content/renderer/service_worker/service_worker_context_client.cc b/content/renderer/service_worker/service_worker_context_client.cc index 815d1d7c2e58..40eadbc26271 100644 --- a/content/renderer/service_worker/service_worker_context_client.cc +++ b/content/renderer/service_worker/service_worker_context_client.cc @@ -31,6 +31,7 @@ #include "content/common/service_worker/embedded_worker_messages.h" #include "content/common/service_worker/service_worker_messages.h" #include "content/public/common/referrer.h" +#include "content/public/renderer/content_renderer_client.h" #include "content/public/renderer/document_state.h" #include "content/renderer/background_sync/background_sync_client_impl.h" #include "content/renderer/devtools/devtools_agent.h" @@ -380,6 +381,14 @@ void ServiceWorkerContextClient::didEvaluateWorkerScript(bool success) { GetWeakPtr())); } +void ServiceWorkerContextClient::didInitializeWorkerContext( + v8::Local context, + const blink::WebURL& url) { + GetContentClient() + ->renderer() + ->DidInitializeServiceWorkerContextOnWorkerThread(context, GURL(url)); +} + void ServiceWorkerContextClient::willDestroyWorkerContext() { // At this point OnWorkerRunLoopStopped is already called, so // worker_task_runner_->RunsTasksOnCurrentThread() returns false diff --git a/content/renderer/service_worker/service_worker_context_client.h b/content/renderer/service_worker/service_worker_context_client.h index 2f2c61f425ba..038684e20bf0 100644 --- a/content/renderer/service_worker/service_worker_context_client.h +++ b/content/renderer/service_worker/service_worker_context_client.h @@ -23,6 +23,7 @@ #include "third_party/WebKit/public/platform/WebMessagePortChannel.h" #include "third_party/WebKit/public/platform/WebServiceWorkerError.h" #include "third_party/WebKit/public/web/WebServiceWorkerContextClient.h" +#include "v8/include/v8.h" namespace base { class SingleThreadTaskRunner; @@ -100,6 +101,8 @@ class ServiceWorkerContextClient virtual void workerContextStarted(blink::WebServiceWorkerContextProxy* proxy); virtual void didEvaluateWorkerScript(bool success); + virtual void didInitializeWorkerContext(v8::Local context, + const blink::WebURL& url); virtual void willDestroyWorkerContext(); virtual void workerContextDestroyed(); virtual void reportException(const blink::WebString& error_message, diff --git a/extensions/renderer/dispatcher.cc b/extensions/renderer/dispatcher.cc index e870f86b5233..1ca506f3bae4 100644 --- a/extensions/renderer/dispatcher.cc +++ b/extensions/renderer/dispatcher.cc @@ -83,6 +83,7 @@ #include "extensions/renderer/user_gestures_native_handler.h" #include "extensions/renderer/utils_native_handler.h" #include "extensions/renderer/v8_context_native_handler.h" +#include "extensions/renderer/v8_helpers.h" #include "grit/extensions_renderer_resources.h" #include "third_party/WebKit/public/platform/WebString.h" #include "third_party/WebKit/public/platform/WebURLRequest.h" @@ -305,6 +306,16 @@ void Dispatcher::DidCreateScriptContext( VLOG(1) << "Num tracked contexts: " << script_context_set_->size(); } +// static +void Dispatcher::DidInitializeServiceWorkerContextOnWorkerThread( + v8::Local context, + const GURL& url) { + if (url.SchemeIs(extensions::kExtensionScheme)) { + v8_helpers::SetProperty(context, context->Global(), "chrome", + v8::Object::New(context->GetIsolate())); + } +} + void Dispatcher::WillReleaseScriptContext( blink::WebLocalFrame* frame, const v8::Local& v8_context, diff --git a/extensions/renderer/dispatcher.h b/extensions/renderer/dispatcher.h index 87a45359386c..4f5a132e1b97 100644 --- a/extensions/renderer/dispatcher.h +++ b/extensions/renderer/dispatcher.h @@ -95,6 +95,11 @@ class Dispatcher : public content::RenderProcessObserver, int extension_group, int world_id); + // Runs on a different thread and should not use any member variables. + static void DidInitializeServiceWorkerContextOnWorkerThread( + v8::Local context, + const GURL& url); + void WillReleaseScriptContext(blink::WebLocalFrame* frame, const v8::Local& context, int world_id); -- 2.11.4.GIT