Add initial support for serviceWorkerClient.postMessage()
authorcdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 27 Oct 2017 16:35:45 +0000 (16:35 +0000)
committercdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 27 Oct 2017 16:35:45 +0000 (16:35 +0000)
https://bugs.webkit.org/show_bug.cgi?id=178794

Reviewed by Youenn Fablet.

Source/WebCore:

Add initial support for serviceWorkerClient.postMessage():
- https://w3c.github.io/ServiceWorker/#client-postmessage

It is now possible to do bi-directional communication with a service worker
via postMessage().

No new tests, updated existing test.

* WebCore.xcodeproj/project.pbxproj:
* dom/Document.cpp:
(WebCore::generateDocumentIdentifier):
(WebCore::Document::allDocumentsMap):
(WebCore::Document::allDocuments):
(WebCore::m_identifier):
(WebCore::Document::~Document):
* dom/Document.h:
(WebCore::Document::identifier const):
* dom/ScriptExecutionContext.cpp:
(WebCore::ScriptExecutionContext::serviceWorkerContainer):
* dom/ScriptExecutionContext.h:
* workers/service/ServiceWorker.cpp:
(WebCore::ServiceWorker::postMessage):
* workers/service/ServiceWorkerClient.cpp:
(WebCore::ServiceWorkerClient::ServiceWorkerClient):
(WebCore::ServiceWorkerClient::~ServiceWorkerClient):
(WebCore::ServiceWorkerClient::id const):
(WebCore::ServiceWorkerClient::postMessage):
* workers/service/ServiceWorkerClient.h:
(WebCore::ServiceWorkerClient::create):
* workers/service/ServiceWorkerClient.idl:
* workers/service/ServiceWorkerClientIdentifier.h: Copied from Source/WebCore/workers/service/ServiceWorkerClient.idl.
(WebCore::ServiceWorkerClientIdentifier::toString const):
* workers/service/ServiceWorkerRegistration.cpp:
(WebCore::ServiceWorkerRegistration::unregister):
* workers/service/ServiceWorkerWindowClient.cpp:
(WebCore::ServiceWorkerWindowClient::ServiceWorkerWindowClient):
* workers/service/ServiceWorkerWindowClient.h:
* workers/service/context/SWContextManager.cpp:
(WebCore::SWContextManager::postMessageToServiceWorkerGlobalScope):
* workers/service/context/SWContextManager.h:
* workers/service/context/ServiceWorkerThread.cpp:
(WebCore::ServiceWorkerThread::postMessageToServiceWorkerGlobalScope):
* workers/service/context/ServiceWorkerThread.h:
* workers/service/server/SWClientConnection.cpp:
(WebCore::SWClientConnection::postMessageToServiceWorkerClient):
* workers/service/server/SWClientConnection.h:

Source/WebKit:

Add initial support for serviceWorkerClient.postMessage():
- https://w3c.github.io/ServiceWorker/#client-postmessage

It is now possible to do bi-directional communication with a service worker
via postMessage().

* Shared/WebCoreArgumentCoders.cpp:
(IPC::ArgumentCoder<ServiceWorkerClientIdentifier>::encode):
(IPC::ArgumentCoder<ServiceWorkerClientIdentifier>::decode):
* Shared/WebCoreArgumentCoders.h:
* StorageProcess/ServiceWorker/WebSWServerConnection.cpp:
(WebKit::WebSWServerConnection::postMessageToServiceWorkerGlobalScope):
(WebKit::WebSWServerConnection::postMessageToServiceWorkerClient):
* StorageProcess/ServiceWorker/WebSWServerConnection.h:
* StorageProcess/ServiceWorker/WebSWServerConnection.messages.in:
* StorageProcess/StorageProcess.cpp:
(WebKit::StorageProcess::postMessageToServiceWorkerClient):
* StorageProcess/StorageProcess.h:
* StorageProcess/StorageProcess.messages.in:
* WebProcess/Storage/WebSWClientConnection.cpp:
(WebKit::WebSWClientConnection::postMessageToServiceWorkerGlobalScope):
(WebKit::WebSWClientConnection::postMessageToServiceWorkerClient):
* WebProcess/Storage/WebSWClientConnection.h:
* WebProcess/Storage/WebSWClientConnection.messages.in:
* WebProcess/Storage/WebSWContextManagerConnection.cpp:
(WebKit::WebSWContextManagerConnection::postMessageToServiceWorkerGlobalScope):
(WebKit::WebSWContextManagerConnection::postMessageToServiceWorkerClient):
* WebProcess/Storage/WebSWContextManagerConnection.h:
* WebProcess/Storage/WebSWContextManagerConnection.messages.in:

LayoutTests:

Add layout test coverage.

* http/tests/workers/service/basic-ServiceWorker-postMessage.https-expected.txt:
* http/tests/workers/service/resources/basic-ServiceWorker-postMessage-worker.js:
* http/tests/workers/service/resources/basic-ServiceWorker-postMessage.js:
(then):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@224113 268f45cc-cd09-0410-ab3c-d52691b4dbfc

39 files changed:
LayoutTests/ChangeLog
LayoutTests/http/tests/workers/service/basic-ServiceWorker-postMessage.https-expected.txt
LayoutTests/http/tests/workers/service/resources/basic-ServiceWorker-postMessage-worker.js
LayoutTests/http/tests/workers/service/resources/basic-ServiceWorker-postMessage.js
Source/WebCore/ChangeLog
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/dom/Document.cpp
Source/WebCore/dom/Document.h
Source/WebCore/dom/ScriptExecutionContext.cpp
Source/WebCore/dom/ScriptExecutionContext.h
Source/WebCore/workers/service/ServiceWorker.cpp
Source/WebCore/workers/service/ServiceWorkerClient.cpp
Source/WebCore/workers/service/ServiceWorkerClient.h
Source/WebCore/workers/service/ServiceWorkerClient.idl
Source/WebCore/workers/service/ServiceWorkerClientIdentifier.h [new file with mode: 0644]
Source/WebCore/workers/service/ServiceWorkerRegistration.cpp
Source/WebCore/workers/service/ServiceWorkerWindowClient.cpp
Source/WebCore/workers/service/ServiceWorkerWindowClient.h
Source/WebCore/workers/service/context/SWContextManager.cpp
Source/WebCore/workers/service/context/SWContextManager.h
Source/WebCore/workers/service/context/ServiceWorkerThread.cpp
Source/WebCore/workers/service/context/ServiceWorkerThread.h
Source/WebCore/workers/service/server/SWClientConnection.cpp
Source/WebCore/workers/service/server/SWClientConnection.h
Source/WebKit/ChangeLog
Source/WebKit/Shared/WebCoreArgumentCoders.cpp
Source/WebKit/Shared/WebCoreArgumentCoders.h
Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.cpp
Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.h
Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.messages.in
Source/WebKit/StorageProcess/StorageProcess.cpp
Source/WebKit/StorageProcess/StorageProcess.h
Source/WebKit/StorageProcess/StorageProcess.messages.in
Source/WebKit/WebProcess/Storage/WebSWClientConnection.cpp
Source/WebKit/WebProcess/Storage/WebSWClientConnection.h
Source/WebKit/WebProcess/Storage/WebSWClientConnection.messages.in
Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.cpp
Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.h
Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.messages.in

index 27c43229edec80bbcfcb65db34d2aa7c91319d00..20ef89a6c013ca8b23f9ce53a247ee7c77867c48 100644 (file)
@@ -1,3 +1,17 @@
+2017-10-27  Chris Dumez  <cdumez@apple.com>
+
+        Add initial support for serviceWorkerClient.postMessage()
+        https://bugs.webkit.org/show_bug.cgi?id=178794
+
+        Reviewed by Youenn Fablet.
+
+        Add layout test coverage.
+
+        * http/tests/workers/service/basic-ServiceWorker-postMessage.https-expected.txt:
+        * http/tests/workers/service/resources/basic-ServiceWorker-postMessage-worker.js:
+        * http/tests/workers/service/resources/basic-ServiceWorker-postMessage.js:
+        (then):
+
 2017-10-27  Ryan Haddad  <ryanhaddad@apple.com>
 
         Skip failing service worker tests that were missed in r224066.
index 7d12235475f1eeb59323debe0df15e68250ea67c..f7c37e64c73349431c0548bf0d3896c00df21fcf 100644 (file)
@@ -1,4 +1,5 @@
-PASS: Status code is 200
-PASS: Status text is Worker received the message event. messageEvent.origin was https://127.0.0.1:8443
-PASS: Source is Service worker
+PASS: Client received message from service worker, origin: https://127.0.0.1:8443
+PASS: Service worker received message 'Message 1' from origin 'https://127.0.0.1:8443'
+PASS: Client received message from service worker, origin: https://127.0.0.1:8443
+PASS: Service worker received message 'Message 2' from origin 'https://127.0.0.1:8443'
 
index 84395b2a6d3d6f5a67349fcb706d8ab47566bab5..b49dad71372e99d7d497f2de40ce11d794ca3e76 100644 (file)
@@ -1,14 +1,4 @@
-let responseToSend = { status: 404, statusText: "Not Found" };
-
 self.addEventListener("message", (event) => {
-    responseToSend = event.data;
-    responseToSend.statusText += " messageEvent.origin was " + event.origin;
+    event.source.postMessage("Service worker received message '" + event.data + "' from origin '" + event.origin + "'");
 });
 
-self.addEventListener("fetch", (event) => {
-    if (event.request.url.indexOf("test1") !== -1) {
-        event.respondWith(new Response(null, responseToSend));
-        return;
-    }
-    event.respondWith(Response.error());
-});
index 96a41ca08688b483ae824b2365531707cd08e7cc..1f0a63044be50ae15b7b7e2e447cd322a7ddd7fb 100644 (file)
@@ -1,37 +1,14 @@
-function done()
-{
-    finishSWTest();
-}
-
-async function test()
-{
-    try {
-        await navigator.serviceWorker.register("resources/basic-ServiceWorker-postMessage-worker.js", { });
-
-        navigator.serviceWorker.controller.postMessage({ status: 200, statusText: "Worker received the message event." });
-
-        let response = await fetch("test1");
-        if (response.status == 200)
-            log("PASS: Status code is " + response.status);
-        else
-            log("FAIL: Status code is " + response.status);
-
-        if (response.statusText.startsWith("Worker received the message"))
-            log("PASS: Status text is " + response.statusText);
-        else
-            log("FAIL: Status text is " + response.statusText);
-
-        if (window.internals) {
-            let source = internals.fetchResponseSource(response);
-            if (source === "Service worker")
-                log("PASS: Source is " + source);
-            else
-                log("FAIL: Source is " + source);
-        }
-    } catch(e) {
-        log("Got exception: " + e);
-    }
-    finishSWTest();
-}
-
-test();
+var messageNumber = 1;
+navigator.serviceWorker.addEventListener("message", function(event) {
+    log("PASS: Client received message from service worker, origin: " + event.origin);
+    log("PASS: " + event.data);
+    if (messageNumber == 1) {
+        event.source.postMessage("Message 2");
+        messageNumber++;
+    } else
+        finishSWTest();
+});
+
+navigator.serviceWorker.register("resources/basic-ServiceWorker-postMessage-worker.js", { }).then(function() {
+    navigator.serviceWorker.controller.postMessage("Message 1");
+});
index df031fc0f3de5e5184b0811fc09170f8c04fa4ee..e1fc2ac311b466de696f586358f85cdae7f9473c 100644 (file)
@@ -1,3 +1,57 @@
+2017-10-27  Chris Dumez  <cdumez@apple.com>
+
+        Add initial support for serviceWorkerClient.postMessage()
+        https://bugs.webkit.org/show_bug.cgi?id=178794
+
+        Reviewed by Youenn Fablet.
+
+        Add initial support for serviceWorkerClient.postMessage():
+        - https://w3c.github.io/ServiceWorker/#client-postmessage
+
+        It is now possible to do bi-directional communication with a service worker
+        via postMessage().
+
+        No new tests, updated existing test.
+
+        * WebCore.xcodeproj/project.pbxproj:
+        * dom/Document.cpp:
+        (WebCore::generateDocumentIdentifier):
+        (WebCore::Document::allDocumentsMap):
+        (WebCore::Document::allDocuments):
+        (WebCore::m_identifier):
+        (WebCore::Document::~Document):
+        * dom/Document.h:
+        (WebCore::Document::identifier const):
+        * dom/ScriptExecutionContext.cpp:
+        (WebCore::ScriptExecutionContext::serviceWorkerContainer):
+        * dom/ScriptExecutionContext.h:
+        * workers/service/ServiceWorker.cpp:
+        (WebCore::ServiceWorker::postMessage):
+        * workers/service/ServiceWorkerClient.cpp:
+        (WebCore::ServiceWorkerClient::ServiceWorkerClient):
+        (WebCore::ServiceWorkerClient::~ServiceWorkerClient):
+        (WebCore::ServiceWorkerClient::id const):
+        (WebCore::ServiceWorkerClient::postMessage):
+        * workers/service/ServiceWorkerClient.h:
+        (WebCore::ServiceWorkerClient::create):
+        * workers/service/ServiceWorkerClient.idl:
+        * workers/service/ServiceWorkerClientIdentifier.h: Copied from Source/WebCore/workers/service/ServiceWorkerClient.idl.
+        (WebCore::ServiceWorkerClientIdentifier::toString const):
+        * workers/service/ServiceWorkerRegistration.cpp:
+        (WebCore::ServiceWorkerRegistration::unregister):
+        * workers/service/ServiceWorkerWindowClient.cpp:
+        (WebCore::ServiceWorkerWindowClient::ServiceWorkerWindowClient):
+        * workers/service/ServiceWorkerWindowClient.h:
+        * workers/service/context/SWContextManager.cpp:
+        (WebCore::SWContextManager::postMessageToServiceWorkerGlobalScope):
+        * workers/service/context/SWContextManager.h:
+        * workers/service/context/ServiceWorkerThread.cpp:
+        (WebCore::ServiceWorkerThread::postMessageToServiceWorkerGlobalScope):
+        * workers/service/context/ServiceWorkerThread.h:
+        * workers/service/server/SWClientConnection.cpp:
+        (WebCore::SWClientConnection::postMessageToServiceWorkerClient):
+        * workers/service/server/SWClientConnection.h:
+
 2017-10-27  Frederic Wang  <fwang@igalia.com>
 
         Use auto for some variables in RenderLayerCompositor/Backing
index 59c81435dff7b8806458e9a5bad4a8a30a67c6e3..9f1cf60dff0c60410737a1add29d3c6c7c1fcfe1 100644 (file)
                837964CF1F8DB69D00218EA0 /* GeolocationPositionIOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = 837964CE1F8DB69A00218EA0 /* GeolocationPositionIOS.mm */; };
                837A80131E1E127300026B9F /* Localizable.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = 837A80111E1E127300026B9F /* Localizable.stringsdict */; };
                837B7D201DC3F55000D051FC /* ValidationBubbleIOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = 837B7D1F1DC3F54C00D051FC /* ValidationBubbleIOS.mm */; };
+               837D46271FA2A8CE0054E1FA /* ServiceWorkerClientIdentifier.h in Headers */ = {isa = PBXBuildFile; fileRef = 837D46251FA2A8C50054E1FA /* ServiceWorkerClientIdentifier.h */; settings = {ATTRIBUTES = (Private, ); }; };
                837FB3451F9EA06D00D0FC31 /* ExtendableMessageEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 837FB3401F9EA06600D0FC31 /* ExtendableMessageEvent.h */; };
                8386A96D19F61B2E00E1EC4A /* StyleBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = 8386A96C19F61B2E00E1EC4A /* StyleBuilder.h */; };
                838867351D13BA5F003697D0 /* RenderObjectEnums.h in Headers */ = {isa = PBXBuildFile; fileRef = 838867341D13BA59003697D0 /* RenderObjectEnums.h */; settings = {ATTRIBUTES = (Private, ); }; };
                837964CE1F8DB69A00218EA0 /* GeolocationPositionIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = GeolocationPositionIOS.mm; path = Modules/geolocation/ios/GeolocationPositionIOS.mm; sourceTree = SOURCE_ROOT; };
                837A80121E1E127300026B9F /* English */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = English; path = English.lproj/Localizable.stringsdict; sourceTree = SOURCE_ROOT; };
                837B7D1F1DC3F54C00D051FC /* ValidationBubbleIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ValidationBubbleIOS.mm; sourceTree = "<group>"; };
+               837D46251FA2A8C50054E1FA /* ServiceWorkerClientIdentifier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ServiceWorkerClientIdentifier.h; sourceTree = "<group>"; };
                837DFB341EBFEA7000601385 /* ElementCSSInlineStyle.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ElementCSSInlineStyle.idl; sourceTree = "<group>"; };
                837FB3401F9EA06600D0FC31 /* ExtendableMessageEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExtendableMessageEvent.h; sourceTree = "<group>"; };
                837FB3421F9EA06700D0FC31 /* ExtendableMessageEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExtendableMessageEvent.cpp; sourceTree = "<group>"; };
                                46EF14271F97B7BA00C2A524 /* ServiceWorkerClient.cpp */,
                                46EF14241F97B7BA00C2A524 /* ServiceWorkerClient.h */,
                                46EF14281F97B7BA00C2A524 /* ServiceWorkerClient.idl */,
+                               837D46251FA2A8C50054E1FA /* ServiceWorkerClientIdentifier.h */,
                                46EF14211F97B7BA00C2A524 /* ServiceWorkerClients.cpp */,
                                46EF14221F97B7BA00C2A524 /* ServiceWorkerClients.h */,
                                46EF14231F97B7BA00C2A524 /* ServiceWorkerClients.idl */,
                                2D93AEE319DF5641002A86C3 /* ServicesOverlayController.h in Headers */,
                                51F1755D1F3EBC8300C74950 /* ServiceWorker.h in Headers */,
                                46EF142D1F97B7D800C2A524 /* ServiceWorkerClient.h in Headers */,
+                               837D46271FA2A8CE0054E1FA /* ServiceWorkerClientIdentifier.h in Headers */,
                                46EF142C1F97B7D800C2A524 /* ServiceWorkerClients.h in Headers */,
                                8369FDFC1FA102E300C1FF1F /* ServiceWorkerClientType.h in Headers */,
                                51F1755F1F3EBC8300C74950 /* ServiceWorkerContainer.h in Headers */,
index d40f99c50d360d95fbf2378b1728c39970194f1c..ee12a04e7d99366b50d5fa8469e4ee5576fd5e14 100644 (file)
@@ -434,12 +434,23 @@ static void printNavigationErrorMessage(Frame* frame, const URL& activeURL, cons
 
 uint64_t Document::s_globalTreeVersion = 0;
 
-HashSet<Document*>& Document::allDocuments()
+static uint64_t generateDocumentIdentifier()
 {
-    static NeverDestroyed<HashSet<Document*>> documents;
+    static uint64_t identifier = 0;
+    return ++identifier;
+}
+
+auto Document::allDocumentsMap() -> DocumentsMap&
+{
+    static NeverDestroyed<DocumentsMap> documents;
     return documents;
 }
 
+auto Document::allDocuments() -> DocumentsMap::ValuesIteratorRange
+{
+    return allDocumentsMap().values();
+}
+
 static inline int currentOrientation(Frame* frame)
 {
 #if ENABLE(ORIENTATION_EVENTS)
@@ -496,8 +507,10 @@ Document::Document(Frame* frame, const URL& url, unsigned documentClasses, unsig
     , m_isSynthesized(constructionFlags & Synthesized)
     , m_isNonRenderedPlaceholder(constructionFlags & NonRenderedPlaceholder)
     , m_orientationNotifier(currentOrientation(frame))
+    , m_identifier(generateDocumentIdentifier())
 {
-    allDocuments().add(this);
+    auto addResult = allDocumentsMap().add(m_identifier, this);
+    ASSERT_UNUSED(addResult, addResult.isNewEntry);
 
     // We depend on the url getting immediately set in subframes, but we
     // also depend on the url NOT getting immediately set in opened windows.
@@ -547,7 +560,8 @@ Ref<Document> Document::create(Document& contextDocument)
 
 Document::~Document()
 {
-    allDocuments().remove(this);
+    bool wasRemoved = allDocumentsMap().remove(m_identifier);
+    ASSERT_UNUSED(wasRemoved, wasRemoved);
 
     ASSERT(!renderView());
     ASSERT(m_pageCacheState != InPageCache);
index 19d8b977fa505d48dd5fac64ce4fba81ec44ba2a..3e9c8026a89a4356b843bace5d6adf1e73e4a31a 100644 (file)
@@ -347,7 +347,11 @@ public:
 
     void removedLastRef();
 
-    WEBCORE_EXPORT static HashSet<Document*>& allDocuments();
+    uint64_t identifier() const { return m_identifier; }
+
+    using DocumentsMap = HashMap<uint64_t, Document*>;
+    WEBCORE_EXPORT static DocumentsMap::ValuesIteratorRange allDocuments();
+    WEBCORE_EXPORT static DocumentsMap& allDocumentsMap();
 
     MediaQueryMatcher& mediaQueryMatcher();
 
@@ -1835,6 +1839,7 @@ private:
     bool m_grantStorageAccessOverride { false };
 
     RefPtr<DocumentTimeline> m_timeline;
+    uint64_t m_identifier;
 };
 
 Element* eventTargetElementForDocument(Document*);
index 92e9059b9a03b29eca2f0454ffb900d44f40585a..13b1db4b55f7fcd4e3ec70cf7f20e79fc09cbf1c 100644 (file)
@@ -38,6 +38,7 @@
 #include "JSDOMExceptionHandling.h"
 #include "JSDOMWindow.h"
 #include "MessagePort.h"
+#include "Navigator.h"
 #include "NoEventDispatchAssertion.h"
 #include "PublicURLManager.h"
 #include "RejectedPromiseTracker.h"
@@ -45,6 +46,7 @@
 #include "ScriptState.h"
 #include "Settings.h"
 #include "WorkerGlobalScope.h"
+#include "WorkerNavigator.h"
 #include "WorkerThread.h"
 #include <heap/StrongInlines.h>
 #include <inspector/ScriptCallStack.h>
@@ -525,4 +527,18 @@ JSC::ExecState* ScriptExecutionContext::execState()
     return execStateFromWorkerGlobalScope(workerGlobalScope);
 }
 
+#if ENABLE(SERVICE_WORKER)
+ServiceWorkerContainer* ScriptExecutionContext::serviceWorkerContainer()
+{
+    NavigatorBase* navigator = nullptr;
+    if (is<Document>(*this)) {
+        if (auto* window = downcast<Document>(*this).domWindow())
+            navigator = window->navigator();
+    } else
+        navigator = &downcast<WorkerGlobalScope>(*this).navigator();
+
+    return navigator ? navigator->serviceWorker() : nullptr;
+}
+#endif
+
 } // namespace WebCore
index 266f49aeec063fc44b0f8c78d7e93012314edb7a..5218be852329e81bf39c607442735f08051d2ce6 100644 (file)
@@ -68,6 +68,10 @@ class SecurityOrigin;
 class SocketProvider;
 class URL;
 
+#if ENABLE(SERVICE_WORKER)
+class ServiceWorkerContainer;
+#endif
+
 namespace IDBClient {
 class IDBConnectionProxy;
 }
@@ -234,6 +238,8 @@ public:
 #if ENABLE(SERVICE_WORKER)
     uint64_t selectedServiceWorkerIdentifier() const { return m_serviceWorkerIdentifier; }
     void setSelectedServiceWorkerIdentifier(uint64_t identifier) { m_serviceWorkerIdentifier = identifier; }
+
+    ServiceWorkerContainer* serviceWorkerContainer();
 #endif
 
 protected:
index 17964ead604c9c430b5939aead6d4ce201956ef2..0cf9a81642e2e3ea0cf2c6c69105a1a8786c0d44 100644 (file)
@@ -69,7 +69,7 @@ ExceptionOr<void> ServiceWorker::postMessage(ScriptExecutionContext& context, JS
         return Exception { NotSupportedError, ASCIILiteral("Passing MessagePort objects to postMessage is not yet supported") };
 
     auto& swConnection = ServiceWorkerProvider::singleton().serviceWorkerConnectionForSession(context.sessionID());
-    swConnection.postMessageToServiceWorkerGlobalScope(m_identifier, message.releaseReturnValue(), context.origin());
+    swConnection.postMessageToServiceWorkerGlobalScope(m_identifier, message.releaseReturnValue(), context);
 
     return { };
 }
index cd301d08823d94be113e0149b92a1c36252426f3..67de30cdf1f18587e80145c3a058a24378658056 100644 (file)
 #if ENABLE(SERVICE_WORKER)
 #include "ServiceWorkerClient.h"
 
+#include "MessagePort.h"
+#include "SWContextManager.h"
+#include "ScriptExecutionContext.h"
+#include "SerializedScriptValue.h"
+#include "ServiceWorkerGlobalScope.h"
+#include "ServiceWorkerThread.h"
+
 namespace WebCore {
 
-ServiceWorkerClient::ServiceWorkerClient(ScriptExecutionContext& context, Type type)
+ServiceWorkerClient::ServiceWorkerClient(ScriptExecutionContext& context, const Identifier& identifier, Type type)
     : ContextDestructionObserver(&context)
+    , m_identifier(identifier)
     , m_type(type)
 {
 }
 
+ServiceWorkerClient::~ServiceWorkerClient()
+{
+}
+
 String ServiceWorkerClient::url() const
 {
     return { };
@@ -48,14 +60,36 @@ auto ServiceWorkerClient::frameType() const -> FrameType
 
 String ServiceWorkerClient::id() const
 {
-    return { };
+    return m_identifier.toString();
 }
 
-ExceptionOr<void> ServiceWorkerClient::postMessage(JSC::ExecState&, JSC::JSValue message, Vector<JSC::Strong<JSC::JSObject>>&& transfer)
+ExceptionOr<void> ServiceWorkerClient::postMessage(ScriptExecutionContext& context, JSC::JSValue messageValue, Vector<JSC::Strong<JSC::JSObject>>&& transfer)
 {
-    UNUSED_PARAM(message);
-    UNUSED_PARAM(transfer);
-    return Exception { NotSupportedError, ASCIILiteral("client.postMessage() is not yet supported") };
+    auto* execState = context.execState();
+    ASSERT(execState);
+
+    Vector<RefPtr<MessagePort>> ports;
+    auto message = SerializedScriptValue::create(*execState, messageValue, WTFMove(transfer), ports, SerializationContext::WorkerPostMessage);
+    if (message.hasException())
+        return message.releaseException();
+
+    // Disentangle the port in preparation for sending it to the remote context.
+    auto channelsOrException = MessagePort::disentanglePorts(WTFMove(ports));
+    if (channelsOrException.hasException())
+        return channelsOrException.releaseException();
+
+    // FIXME: Support sending the channels.
+    auto channels = channelsOrException.releaseReturnValue();
+    if (channels && !channels->isEmpty())
+        return Exception { NotSupportedError, ASCIILiteral("Passing MessagePort objects to postMessage is not yet supported") };
+
+    uint64_t sourceIdentifier = downcast<ServiceWorkerGlobalScope>(context).thread().identifier();
+    callOnMainThread([message = message.releaseReturnValue(), destinationIdentifier = m_identifier, sourceIdentifier, sourceOrigin = context.origin().isolatedCopy()] () mutable {
+        if (auto* connection = SWContextManager::singleton().connection())
+            connection->postMessageToServiceWorkerClient(destinationIdentifier, WTFMove(message), sourceIdentifier, sourceOrigin);
+    });
+
+    return { };
 }
 
 } // namespace WebCore
index 69b91e08a396b8b95f2a974891b006b78fc79df5..538c0b2f6cb386086a7810a9a94403497ba62a73 100644 (file)
 
 #include "ContextDestructionObserver.h"
 #include "ExceptionOr.h"
+#include "ServiceWorkerClientIdentifier.h"
 #include "ServiceWorkerClientType.h"
 #include <heap/Strong.h>
 #include <wtf/RefCounted.h>
 
 namespace JSC {
-class ExecState;
 class JSValue;
 }
 
@@ -42,6 +42,8 @@ namespace WebCore {
 
 class ServiceWorkerClient : public RefCounted<ServiceWorkerClient>, public ContextDestructionObserver {
 public:
+    using Identifier = ServiceWorkerClientIdentifier;
+
     using Type = ServiceWorkerClientType;
     enum class FrameType {
         Auxiliary,
@@ -50,21 +52,24 @@ public:
         None
     };
 
-    static Ref<ServiceWorkerClient> create(ScriptExecutionContext& context, Type type)
+    static Ref<ServiceWorkerClient> create(ScriptExecutionContext& context, const Identifier& identifier, Type type)
     {
-        return adoptRef(*new ServiceWorkerClient(context, type));
+        return adoptRef(*new ServiceWorkerClient(context, identifier, type));
     }
 
+    ~ServiceWorkerClient();
+
     String url() const;
     FrameType frameType() const;
     Type type() const { return m_type; }
     String id() const;
 
-    ExceptionOr<void> postMessage(JSC::ExecState&, JSC::JSValue message, Vector<JSC::Strong<JSC::JSObject>>&& transfer);
+    ExceptionOr<void> postMessage(ScriptExecutionContext&, JSC::JSValue message, Vector<JSC::Strong<JSC::JSObject>>&& transfer);
 
 protected:
-    ServiceWorkerClient(ScriptExecutionContext&, Type);
+    ServiceWorkerClient(ScriptExecutionContext&, const Identifier&, Type);
 
+    Identifier m_identifier;
     Type m_type;
 };
 
index f7e4a98de20d0c1ffb3c33eda353e4ed7d9dc034..d8acac99891a67d7ffeb59162e8aa0efd7aa6c77 100644 (file)
@@ -35,7 +35,7 @@
     readonly attribute ServiceWorkerClientType type;
     readonly attribute DOMString id;
 
-    [CallWith=ScriptState, MayThrowException] void postMessage(any message, optional sequence<object> transfer = []);
+    [CallWith=ScriptExecutionContext, MayThrowException] void postMessage(any message, optional sequence<object> transfer = []);
 };
 
 enum FrameType {
diff --git a/Source/WebCore/workers/service/ServiceWorkerClientIdentifier.h b/Source/WebCore/workers/service/ServiceWorkerClientIdentifier.h
new file mode 100644 (file)
index 0000000..1464852
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+struct ServiceWorkerClientIdentifier {
+    uint64_t serverConnectionIdentifier;
+    uint64_t scriptExecutionContextIdentifier;
+
+    String toString() const { return String::number(serverConnectionIdentifier) + "-" +  String::number(scriptExecutionContextIdentifier); }
+};
+
+}
index 25919ab1a39969ac54ebcfb884960f03e7009fc1..abfdacb375eb321e1a1416687db473220a8a285f 100644 (file)
 #if ENABLE(SERVICE_WORKER)
 #include "DOMWindow.h"
 #include "Document.h"
-#include "Navigator.h"
 #include "ServiceWorkerContainer.h"
 #include "WorkerGlobalScope.h"
-#include "WorkerNavigator.h"
 
 namespace WebCore {
 
-static ServiceWorkerContainer* containerForScriptExecutionContext(ScriptExecutionContext& context)
-{
-    NavigatorBase* navigator = nullptr;
-    if (is<Document>(context)) {
-        if (auto* window = downcast<Document>(context).domWindow())
-            navigator = window->navigator();
-    } else
-        navigator = &downcast<WorkerGlobalScope>(context).navigator();
-
-    return navigator ? navigator->serviceWorker() : nullptr;
-}
-
 ServiceWorkerRegistration::ServiceWorkerRegistration(ScriptExecutionContext& context, ServiceWorkerRegistrationData&& registrationData)
     : ActiveDOMObject(&context)
     , m_registrationData(WTFMove(registrationData))
@@ -94,7 +80,7 @@ void ServiceWorkerRegistration::unregister(Ref<DeferredPromise>&& promise)
         return;
     }
 
-    auto* container = containerForScriptExecutionContext(*context);
+    auto* container = context->serviceWorkerContainer();
     if (!container) {
         promise->reject(Exception(InvalidStateError));
         return;
index 46d2990e296e08ff7c4af4c91ed8689235ac9258..e71443b002e21b02e3ee8c03ab4ebb0fef41b40d 100644 (file)
@@ -32,8 +32,8 @@
 
 namespace WebCore {
 
-ServiceWorkerWindowClient::ServiceWorkerWindowClient(ScriptExecutionContext& context)
-    : ServiceWorkerClient(context, Type::Window)
+ServiceWorkerWindowClient::ServiceWorkerWindowClient(ScriptExecutionContext& context, const Identifier& identifier)
+    : ServiceWorkerClient(context, identifier, Type::Window)
 {
 }
 
index 83c80e2807b3412afd386a802d5db5a034056603..3e2f3956a7d82d7fc4ab02b16885ebd12bf6a65d 100644 (file)
@@ -36,9 +36,9 @@ class DeferredPromise;
 
 class ServiceWorkerWindowClient final : public ServiceWorkerClient {
 public:
-    static Ref<ServiceWorkerWindowClient> create(ScriptExecutionContext& context)
+    static Ref<ServiceWorkerWindowClient> create(ScriptExecutionContext& context, const Identifier& identifier)
     {
-        return adoptRef(*new ServiceWorkerWindowClient(context));
+        return adoptRef(*new ServiceWorkerWindowClient(context, identifier));
     }
 
     VisibilityState visibilityState() const;
@@ -48,7 +48,7 @@ public:
     void navigate(const String& url, Ref<DeferredPromise>&&);
 
 private:
-    explicit ServiceWorkerWindowClient(ScriptExecutionContext&);
+    ServiceWorkerWindowClient(ScriptExecutionContext&, const Identifier&);
 };
 
 } // namespace WebCore
index 678b92b43601d74b4f6cf2fd1ece9e451c42abdc..946b3fd5691f24ec310dd6d9a824e31132ec1c44 100644 (file)
@@ -59,14 +59,14 @@ ServiceWorkerThreadProxy* SWContextManager::serviceWorkerThreadProxy(uint64_t se
     return m_workerMap.get(serviceWorkerIdentifier);
 }
 
-void SWContextManager::postMessageToServiceWorkerGlobalScope(uint64_t serviceWorkerIdentifier, Ref<SerializedScriptValue>&& message, const String& sourceOrigin)
+void SWContextManager::postMessageToServiceWorkerGlobalScope(uint64_t destinationServiceWorkerIdentifier, Ref<SerializedScriptValue>&& message, const ServiceWorkerClientIdentifier& sourceIdentifier, const String& sourceOrigin)
 {
-    auto* serviceWorker = m_workerMap.get(serviceWorkerIdentifier);
+    auto* serviceWorker = m_workerMap.get(destinationServiceWorkerIdentifier);
     if (!serviceWorker)
         return;
 
     // FIXME: We should pass valid MessagePortChannels.
-    serviceWorker->thread().postMessageToServiceWorkerGlobalScope(WTFMove(message), nullptr, sourceOrigin);
+    serviceWorker->thread().postMessageToServiceWorkerGlobalScope(WTFMove(message), nullptr, sourceIdentifier, sourceOrigin);
 }
 
 } // namespace WebCore
index cdccacc1a07e5cc85a3f05bd1dd845389f407a5c..9d62400d464690e0263b0dfbd1ec424e13eae5c9 100644 (file)
@@ -34,6 +34,7 @@
 namespace WebCore {
 
 class SerializedScriptValue;
+struct ServiceWorkerClientIdentifier;
 
 class SWContextManager {
 public:
@@ -42,6 +43,8 @@ public:
     class Connection {
     public:
         virtual ~Connection() { }
+
+        virtual void postMessageToServiceWorkerClient(const ServiceWorkerClientIdentifier& destinationIdentifier, Ref<SerializedScriptValue>&& message, uint64_t sourceServiceWorkerIdentifier, const String& sourceOrigin) = 0;
     };
 
     WEBCORE_EXPORT void setConnection(std::unique_ptr<Connection>&&);
@@ -49,7 +52,7 @@ public:
 
     WEBCORE_EXPORT void registerServiceWorkerThread(Ref<ServiceWorkerThreadProxy>&&);
     WEBCORE_EXPORT ServiceWorkerThreadProxy* serviceWorkerThreadProxy(uint64_t) const;
-    WEBCORE_EXPORT void postMessageToServiceWorkerGlobalScope(uint64_t serviceWorkerIdentifier, Ref<SerializedScriptValue>&& message, const String& sourceOrigin);
+    WEBCORE_EXPORT void postMessageToServiceWorkerGlobalScope(uint64_t destinationServiceWorkerIdentifier, Ref<SerializedScriptValue>&& message, const ServiceWorkerClientIdentifier& sourceIdentifier, const String& sourceOrigin);
 
 private:
     SWContextManager() = default;
index cf78e91902bc0e48f995b03b98977cb39c87a755..6adebbf2d40eda60a9603ee6a172212fe5064c57 100644 (file)
@@ -34,6 +34,7 @@
 #include "SecurityOrigin.h"
 #include "ServiceWorkerFetch.h"
 #include "ServiceWorkerGlobalScope.h"
+#include "ServiceWorkerWindowClient.h"
 #include "WorkerLoaderProxy.h"
 #include "WorkerObjectProxy.h"
 #include <pal/SessionID.h>
@@ -99,12 +100,13 @@ void ServiceWorkerThread::postFetchTask(Ref<ServiceWorkerFetch::Client>&& client
     }, WorkerRunLoop::defaultMode());
 }
 
-void ServiceWorkerThread::postMessageToServiceWorkerGlobalScope(Ref<SerializedScriptValue>&& message, std::unique_ptr<MessagePortChannelArray>&& channels, const String& sourceOrigin)
+void ServiceWorkerThread::postMessageToServiceWorkerGlobalScope(Ref<SerializedScriptValue>&& message, std::unique_ptr<MessagePortChannelArray>&& channels, const ServiceWorkerClientIdentifier& sourceIdentifier, const String& sourceOrigin)
 {
-    ScriptExecutionContext::Task task([channels = WTFMove(channels), message = WTFMove(message), sourceOrigin = sourceOrigin.isolatedCopy()] (ScriptExecutionContext& context) mutable {
+    ScriptExecutionContext::Task task([channels = WTFMove(channels), message = WTFMove(message), sourceIdentifier, sourceOrigin = sourceOrigin.isolatedCopy()] (ScriptExecutionContext& context) mutable {
         auto& serviceWorkerGlobalScope = downcast<ServiceWorkerGlobalScope>(context);
         auto ports = MessagePort::entanglePorts(serviceWorkerGlobalScope, WTFMove(channels));
-        serviceWorkerGlobalScope.dispatchEvent(ExtendableMessageEvent::create(WTFMove(ports), WTFMove(message), sourceOrigin));
+        ExtendableMessageEventSource source = RefPtr<ServiceWorkerClient> { ServiceWorkerWindowClient::create(context, sourceIdentifier) };
+        serviceWorkerGlobalScope.dispatchEvent(ExtendableMessageEvent::create(WTFMove(ports), WTFMove(message), sourceOrigin, { }, WTFMove(source)));
         serviceWorkerGlobalScope.thread().workerObjectProxy().confirmMessageFromWorkerObject(serviceWorkerGlobalScope.hasPendingActivity());
     });
     runLoop().postTask(WTFMove(task));
index 3373139c2b574861ce1049bd4d7a69296261f037..24f1526f7b5528c2a9edb1ac00f66d9e15d58296 100644 (file)
@@ -40,6 +40,7 @@ class MessagePortChannel;
 class SerializedScriptValue;
 class WorkerLoaderProxy;
 class WorkerObjectProxy;
+struct ServiceWorkerClientIdentifier;
 struct ServiceWorkerContextData;
 
 using MessagePortChannelArray = Vector<std::unique_ptr<MessagePortChannel>, 1>;
@@ -55,7 +56,7 @@ public:
     WorkerObjectProxy& workerObjectProxy() const { return m_workerObjectProxy; }
 
     WEBCORE_EXPORT void postFetchTask(Ref<ServiceWorkerFetch::Client>&&, ResourceRequest&&, FetchOptions&&);
-    WEBCORE_EXPORT void postMessageToServiceWorkerGlobalScope(Ref<SerializedScriptValue>&&, std::unique_ptr<MessagePortChannelArray>&&, const String& sourceOrigin);
+    WEBCORE_EXPORT void postMessageToServiceWorkerGlobalScope(Ref<SerializedScriptValue>&&, std::unique_ptr<MessagePortChannelArray>&&, const ServiceWorkerClientIdentifier& sourceIdentifier, const String& sourceOrigin);
 
 protected:
     Ref<WorkerGlobalScope> createWorkerGlobalScope(const URL&, const String& identifier, const String& userAgent, const ContentSecurityPolicyResponseHeaders&, bool shouldBypassMainWorldContentSecurityPolicy, Ref<SecurityOrigin>&& topOrigin, MonotonicTime timeOrigin, PAL::SessionID) final;
index 8e93c5e06c94a5ba93ee3354ea3a0aebac37d068..a9268c8695e86dc34b05e7d2255cbf2dd58b73b8 100644 (file)
 
 #if ENABLE(SERVICE_WORKER)
 
+#include "Document.h"
 #include "ExceptionData.h"
+#include "MessageEvent.h"
+#include "ServiceWorkerContainer.h"
 #include "ServiceWorkerFetchResult.h"
 #include "ServiceWorkerJobData.h"
 
@@ -109,6 +112,29 @@ void SWClientConnection::startScriptFetchForServer(uint64_t jobIdentifier)
     job->startScriptFetch();
 }
 
+void SWClientConnection::postMessageToServiceWorkerClient(uint64_t destinationScriptExecutionContextIdentifier, Ref<SerializedScriptValue>&& message, uint64_t sourceServiceWorkerIdentifier, const String& sourceOrigin)
+{
+    // FIXME: destinationScriptExecutionContextIdentifier can only identify a Document at the moment.
+    auto* destinationDocument = Document::allDocumentsMap().get(destinationScriptExecutionContextIdentifier);
+    if (!destinationDocument)
+        return;
+
+    auto* container = destinationDocument->serviceWorkerContainer();
+    if (!container)
+        return;
+
+    std::optional<MessageEventSource> source;
+    if (destinationDocument->selectedServiceWorkerIdentifier() == sourceServiceWorkerIdentifier) {
+        ASSERT(container->controller()->identifier() == sourceServiceWorkerIdentifier);
+        source = MessageEventSource { RefPtr<ServiceWorker> { container->controller() } };
+    } else
+        source = MessageEventSource { RefPtr<ServiceWorker> { ServiceWorker::create(*destinationDocument, sourceServiceWorkerIdentifier) } };
+
+    // FIXME: We should pass in ports.
+    auto messageEvent = MessageEvent::create({ }, WTFMove(message), sourceOrigin, { }, WTFMove(source));
+    container->dispatchEvent(messageEvent);
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(SERVICE_WORKER)
index 508a58a49f27bdad629052b5f35346499be4015b..c61a61e76b1c8506fa80d238080c063f054133b5 100644 (file)
@@ -49,7 +49,7 @@ public:
     void scheduleJob(ServiceWorkerJob&);
     void finishedFetchingScript(ServiceWorkerJob&, const String&);
     void failedFetchingScript(ServiceWorkerJob&, const ResourceError&);
-    virtual void postMessageToServiceWorkerGlobalScope(uint64_t serviceWorkerIdentifier, Ref<SerializedScriptValue>&&, const String& sourceOrigin) = 0;
+    virtual void postMessageToServiceWorkerGlobalScope(uint64_t destinationServiceWorkerIdentifier, Ref<SerializedScriptValue>&&, ScriptExecutionContext& source) = 0;
 
     virtual uint64_t identifier() const = 0;
     virtual bool hasServiceWorkerRegisteredForOrigin(const SecurityOrigin&) const = 0;
@@ -59,6 +59,7 @@ protected:
     WEBCORE_EXPORT void registrationJobResolvedInServer(uint64_t jobIdentifier, ServiceWorkerRegistrationData&&);
     WEBCORE_EXPORT void unregistrationJobResolvedInServer(uint64_t jobIdentifier, bool unregistrationResult);
     WEBCORE_EXPORT void startScriptFetchForServer(uint64_t jobIdentifier);
+    WEBCORE_EXPORT void postMessageToServiceWorkerClient(uint64_t destinationScriptExecutionContextIdentifier, Ref<SerializedScriptValue>&& message, uint64_t sourceServiceWorkerIdentifier, const String& sourceOrigin);
 
 private:
     virtual void scheduleJobInServer(const ServiceWorkerJobData&) = 0;
index 2681e2c176c8dfe624d6dca81685806977ad405d..efbce26c5636afb6c6178f0c49c9927ddd804eea 100644 (file)
@@ -1,3 +1,40 @@
+2017-10-27  Chris Dumez  <cdumez@apple.com>
+
+        Add initial support for serviceWorkerClient.postMessage()
+        https://bugs.webkit.org/show_bug.cgi?id=178794
+
+        Reviewed by Youenn Fablet.
+
+        Add initial support for serviceWorkerClient.postMessage():
+        - https://w3c.github.io/ServiceWorker/#client-postmessage
+
+        It is now possible to do bi-directional communication with a service worker
+        via postMessage().
+
+        * Shared/WebCoreArgumentCoders.cpp:
+        (IPC::ArgumentCoder<ServiceWorkerClientIdentifier>::encode):
+        (IPC::ArgumentCoder<ServiceWorkerClientIdentifier>::decode):
+        * Shared/WebCoreArgumentCoders.h:
+        * StorageProcess/ServiceWorker/WebSWServerConnection.cpp:
+        (WebKit::WebSWServerConnection::postMessageToServiceWorkerGlobalScope):
+        (WebKit::WebSWServerConnection::postMessageToServiceWorkerClient):
+        * StorageProcess/ServiceWorker/WebSWServerConnection.h:
+        * StorageProcess/ServiceWorker/WebSWServerConnection.messages.in:
+        * StorageProcess/StorageProcess.cpp:
+        (WebKit::StorageProcess::postMessageToServiceWorkerClient):
+        * StorageProcess/StorageProcess.h:
+        * StorageProcess/StorageProcess.messages.in:
+        * WebProcess/Storage/WebSWClientConnection.cpp:
+        (WebKit::WebSWClientConnection::postMessageToServiceWorkerGlobalScope):
+        (WebKit::WebSWClientConnection::postMessageToServiceWorkerClient):
+        * WebProcess/Storage/WebSWClientConnection.h:
+        * WebProcess/Storage/WebSWClientConnection.messages.in:
+        * WebProcess/Storage/WebSWContextManagerConnection.cpp:
+        (WebKit::WebSWContextManagerConnection::postMessageToServiceWorkerGlobalScope):
+        (WebKit::WebSWContextManagerConnection::postMessageToServiceWorkerClient):
+        * WebProcess/Storage/WebSWContextManagerConnection.h:
+        * WebProcess/Storage/WebSWContextManagerConnection.messages.in:
+
 2017-10-27  David Kilzer  <ddkilzer@apple.com>
 
         REGRESSION (r224077): DeprecatedGlobalSettings::setAVKitEnabled() not protected by HAVE(AVKIT)
index 4afe7e7e21c20fe012ee4dd7e03f9667c90fe34a..39e0f895dbe451e9aef1916c0d796a4264db8e5b 100644 (file)
@@ -65,6 +65,7 @@
 #include <WebCore/ScrollingConstraints.h>
 #include <WebCore/ScrollingCoordinator.h>
 #include <WebCore/SearchPopupMenu.h>
+#include <WebCore/ServiceWorkerClientIdentifier.h>
 #include <WebCore/TextCheckerClient.h>
 #include <WebCore/TextIndicator.h>
 #include <WebCore/TimingFunction.h>
@@ -1901,6 +1902,27 @@ bool ArgumentCoder<TextCheckingRequestData>::decode(Decoder& decoder, TextChecki
     return true;
 }
 
+#if ENABLE(SERVICE_WORKER)
+void ArgumentCoder<ServiceWorkerClientIdentifier>::encode(Encoder& encoder, const ServiceWorkerClientIdentifier& identifier)
+{
+    encoder << identifier.serverConnectionIdentifier << identifier.scriptExecutionContextIdentifier;
+}
+
+bool ArgumentCoder<ServiceWorkerClientIdentifier>::decode(Decoder& decoder, ServiceWorkerClientIdentifier& identifier)
+{
+    uint64_t serverConnectionIdentifier;
+    if (!decoder.decode(serverConnectionIdentifier))
+        return false;
+
+    uint64_t scriptExecutionContextIdentifier;
+    if (!decoder.decode(scriptExecutionContextIdentifier))
+        return false;
+
+    identifier = { serverConnectionIdentifier, scriptExecutionContextIdentifier };
+    return true;
+}
+#endif
+
 void ArgumentCoder<TextCheckingResult>::encode(Encoder& encoder, const TextCheckingResult& result)
 {
     encoder.encodeEnum(result.type);
index 1c2dc707903ac97c547c55c14c7a809176f5ea02..308e92e5c4fc2e2f6236db9f06d58d72285af6ee 100644 (file)
@@ -157,6 +157,10 @@ struct MediaConstraints;
 #if ENABLE(INDEXED_DATABASE)
 using IDBKeyPath = Variant<String, Vector<String>>;
 #endif
+
+#if ENABLE(SERVICE_WORKER)
+struct ServiceWorkerClientIdentifier;
+#endif
 }
 
 namespace IPC {
@@ -477,6 +481,13 @@ template<> struct ArgumentCoder<WebCore::TextCheckingRequestData> {
     static bool decode(Decoder&, WebCore::TextCheckingRequestData&);
 };
 
+#if ENABLE(SERVICE_WORKER)
+template<> struct ArgumentCoder<WebCore::ServiceWorkerClientIdentifier> {
+    static void encode(Encoder&, const WebCore::ServiceWorkerClientIdentifier&);
+    static bool decode(Decoder&, WebCore::ServiceWorkerClientIdentifier&);
+};
+#endif
+
 template<> struct ArgumentCoder<WebCore::TextCheckingResult> {
     static void encode(Encoder&, const WebCore::TextCheckingResult&);
     static std::optional<WebCore::TextCheckingResult> decode(Decoder&);
index fc1c5f075bbc35b046dcebd943574b49a20ae2ec..006436f651d2d3ca9e111c26030f100e0a42dc98 100644 (file)
@@ -44,6 +44,7 @@
 #include <WebCore/ExceptionData.h>
 #include <WebCore/NotImplemented.h>
 #include <WebCore/SecurityOrigin.h>
+#include <WebCore/ServiceWorkerClientIdentifier.h>
 #include <WebCore/ServiceWorkerContextData.h>
 #include <WebCore/ServiceWorkerJobData.h>
 #include <WebCore/ServiceWorkerRegistrationData.h>
@@ -108,9 +109,10 @@ void WebSWServerConnection::startFetch(uint64_t fetchIdentifier, uint64_t servic
     sendToContextProcess(Messages::WebSWContextManagerConnection::StartFetch(identifier(), fetchIdentifier, serviceWorkerIdentifier, request, options));
 }
 
-void WebSWServerConnection::postMessageToServiceWorkerGlobalScope(uint64_t serviceWorkerIdentifier, const IPC::DataReference& message, const String& sourceOrigin)
+void WebSWServerConnection::postMessageToServiceWorkerGlobalScope(uint64_t destinationServiceWorkerIdentifier, const IPC::DataReference& message, uint64_t sourceScriptExecutionContextIdentifier, const String& sourceOrigin)
 {
-    sendToContextProcess(Messages::WebSWContextManagerConnection::PostMessageToServiceWorkerGlobalScope(serviceWorkerIdentifier, message, sourceOrigin));
+    ServiceWorkerClientIdentifier sourceIdentifier { identifier(), sourceScriptExecutionContextIdentifier };
+    sendToContextProcess(Messages::WebSWContextManagerConnection::PostMessageToServiceWorkerGlobalScope { destinationServiceWorkerIdentifier, message, sourceIdentifier, sourceOrigin });
 }
 
 void WebSWServerConnection::didReceiveFetchResponse(uint64_t fetchIdentifier, const ResourceResponse& response)
@@ -138,6 +140,11 @@ void WebSWServerConnection::didNotHandleFetch(uint64_t fetchIdentifier)
     m_contentConnection->send(Messages::ServiceWorkerClientFetch::DidNotHandle { }, fetchIdentifier);
 }
 
+void WebSWServerConnection::postMessageToServiceWorkerClient(uint64_t destinationScriptExecutionContextIdentifier, const IPC::DataReference& message, uint64_t sourceServiceWorkerIdentifier, const String& sourceOrigin)
+{
+    send(Messages::WebSWClientConnection::PostMessageToServiceWorkerClient { destinationScriptExecutionContextIdentifier, message, sourceServiceWorkerIdentifier, sourceOrigin });
+}
+
 template<typename U> bool WebSWServerConnection::sendToContextProcess(U&& message)
 {
     if (!m_contextConnection)
index 2926e83e4317b5715ddc810155eb73c317902b9f..60397e97c145942f6a65ae9f194577a692a6d77a 100644 (file)
@@ -57,6 +57,8 @@ public:
     void didFailFetch(uint64_t fetchIdentifier);
     void didNotHandleFetch(uint64_t fetchIdentifier);
 
+    void postMessageToServiceWorkerClient(uint64_t destinationScriptExecutionContextIdentifier, const IPC::DataReference& message, uint64_t sourceServiceWorkerIdentifier, const String& sourceOrigin);
+
 private:
     // Implement SWServer::Connection (Messages to the client WebProcess)
     void rejectJobInClient(uint64_t jobIdentifier, const WebCore::ExceptionData&) final;
@@ -66,7 +68,7 @@ private:
 
     void startFetch(uint64_t fetchIdentifier, uint64_t serviceWorkerIdentifier, const WebCore::ResourceRequest&, const WebCore::FetchOptions&);
 
-    void postMessageToServiceWorkerGlobalScope(uint64_t serviceWorkerIdentifier, const IPC::DataReference& message, const String& sourceOrigin);
+    void postMessageToServiceWorkerGlobalScope(uint64_t destinationServiceWorkerIdentifier, const IPC::DataReference& message, uint64_t sourceScriptExecutionContextIdentifier, const String& sourceOrigin);
 
     // Messages to the SW context WebProcess
     void startServiceWorkerContext(const WebCore::ServiceWorkerContextData&) final;
index 3b2045c6444adcd18db4cfecc51efc394b212d59..de515d90bec7bc3ba578632554a696a43dce3012 100644 (file)
@@ -28,7 +28,7 @@ messages -> WebSWServerConnection {
     FinishFetchingScriptInServer(struct WebCore::ServiceWorkerFetchResult result)
 
     StartFetch(uint64_t identifier, uint64_t serviceWorkerIdentifier, WebCore::ResourceRequest request, struct WebCore::FetchOptions options)
-    PostMessageToServiceWorkerGlobalScope(uint64_t serviceWorkerIdentifier, IPC::DataReference message, String sourceOrigin)
+    PostMessageToServiceWorkerGlobalScope(uint64_t destinationServiceWorkerIdentifier, IPC::DataReference message, uint64_t sourceScriptExecutionContextIdentifier, String sourceOrigin)
 }
 
 #endif // ENABLE(SERVICE_WORKER)
index 8764cd0702d4988079a3c5513071d135edde29e1..ecd51707830809be3522375b1124a9a84e34343f 100644 (file)
@@ -38,6 +38,7 @@
 #include <WebCore/IDBKeyData.h>
 #include <WebCore/NotImplemented.h>
 #include <WebCore/SecurityOrigin.h>
+#include <WebCore/ServiceWorkerClientIdentifier.h>
 #include <WebCore/TextEncoding.h>
 #include <pal/SessionID.h>
 #include <wtf/CrossThreadTask.h>
@@ -435,6 +436,12 @@ void StorageProcess::didFinishFetch(uint64_t serverConnectionIdentifier, uint64_
         connection->didFinishFetch(fetchIdentifier);
 }
 
+void StorageProcess::postMessageToServiceWorkerClient(const ServiceWorkerClientIdentifier& destinationIdentifier, const IPC::DataReference& message, uint64_t sourceServiceWorkerIdentifier, const String& sourceOrigin)
+{
+    if (auto* connection = m_swServerConnections.get(destinationIdentifier.serverConnectionIdentifier))
+        connection->postMessageToServiceWorkerClient(destinationIdentifier.scriptExecutionContextIdentifier, message, sourceServiceWorkerIdentifier, sourceOrigin);
+}
+
 void StorageProcess::registerSWServerConnection(WebSWServerConnection& connection)
 {
     ASSERT(!m_swServerConnections.contains(connection.identifier()));
index aa8645b771cadc86aaee1924097aa6a813729437..ec5e08c879fd3f63ce90a6639a299641e297f33e 100644 (file)
@@ -37,6 +37,7 @@
 namespace WebCore {
 class SWServer;
 struct SecurityOriginData;
+struct ServiceWorkerClientIdentifier;
 struct ServiceWorkerRegistrationKey;
 }
 
@@ -125,6 +126,8 @@ private:
     void didFinishFetch(uint64_t serverConnectionIdentifier, uint64_t fetchIdentifier);
     void didFailFetch(uint64_t serverConnectionIdentifier, uint64_t fetchIdentifier);
     void didNotHandleFetch(uint64_t serverConnectionIdentifier, uint64_t fetchIdentifier);
+
+    void postMessageToServiceWorkerClient(const WebCore::ServiceWorkerClientIdentifier& destinationIdentifier, const IPC::DataReference& message, uint64_t sourceServiceWorkerIdentifier, const String& sourceOrigin);
 #endif
 #if ENABLE(INDEXED_DATABASE)
     Vector<WebCore::SecurityOriginData> indexedDatabaseOrigins(const String& path);
index 3392af715d1270c7afd4f7febe6f32651b0ccf49..ab08fcd10b7e89b86accf57a965f81c189d3fb29 100644 (file)
@@ -46,5 +46,6 @@ messages -> StorageProcess LegacyReceiver {
     DidReceiveFetchResponse(uint64_t serverConnectionIdentifier, uint64_t fetchIdentifier, WebCore::ResourceResponse response)
     DidReceiveFetchData(uint64_t serverConnectionIdentifier, uint64_t fetchIdentifier, IPC::DataReference data, int64_t encodedDataLength)
     DidFinishFetch(uint64_t serverConnectionIdentifier, uint64_t fetchIdentifier)
+    PostMessageToServiceWorkerClient(struct WebCore::ServiceWorkerClientIdentifier destinationIdentifier, IPC::DataReference message, uint64_t sourceServiceWorkerIdentifier, String sourceOrigin)
 #endif
 }
index 3086ea4fc0ebf1b8d46c459a4f13fe92635a95a3..7b8778ad300dbba00fa4b86c9347673c01ec9999 100644 (file)
@@ -35,6 +35,7 @@
 #include "WebCoreArgumentCoders.h"
 #include "WebSWOriginTable.h"
 #include "WebSWServerConnectionMessages.h"
+#include <WebCore/Document.h>
 #include <WebCore/SerializedScriptValue.h>
 #include <WebCore/ServiceWorkerFetchResult.h>
 #include <WebCore/ServiceWorkerJobData.h>
@@ -68,9 +69,13 @@ void WebSWClientConnection::finishFetchingScriptInServer(const ServiceWorkerFetc
     send(Messages::WebSWServerConnection::FinishFetchingScriptInServer(result));
 }
 
-void WebSWClientConnection::postMessageToServiceWorkerGlobalScope(uint64_t serviceWorkerIdentifier, Ref<SerializedScriptValue>&& scriptValue, const String& sourceOrigin)
+void WebSWClientConnection::postMessageToServiceWorkerGlobalScope(uint64_t destinationServiceWorkerIdentifier, Ref<SerializedScriptValue>&& scriptValue, ScriptExecutionContext& source)
 {
-    send(Messages::WebSWServerConnection::PostMessageToServiceWorkerGlobalScope(serviceWorkerIdentifier, IPC::DataReference { scriptValue->data() }, sourceOrigin));
+    // FIXME: Add support for posting messages from workers.
+    if (!is<Document>(source))
+        return;
+
+    send(Messages::WebSWServerConnection::PostMessageToServiceWorkerGlobalScope(destinationServiceWorkerIdentifier, IPC::DataReference { scriptValue->data() }, downcast<Document>(source).identifier(), source.origin()));
 }
 
 bool WebSWClientConnection::hasServiceWorkerRegisteredForOrigin(const SecurityOrigin& origin) const
@@ -92,6 +97,11 @@ Ref<ServiceWorkerClientFetch> WebSWClientConnection::startFetch(WebServiceWorker
     return ServiceWorkerClientFetch::create(provider, WTFMove(loader), identifier, m_connection.get(), WTFMove(callback));
 }
 
+void WebSWClientConnection::postMessageToServiceWorkerClient(uint64_t destinationScriptExecutionContextIdentifier, const IPC::DataReference& message, uint64_t sourceServiceWorkerIdentifier, const String& sourceOrigin)
+{
+    SWClientConnection::postMessageToServiceWorkerClient(destinationScriptExecutionContextIdentifier, SerializedScriptValue::adopt(message.vector()), sourceServiceWorkerIdentifier, sourceOrigin);
+}
+
 } // namespace WebKit
 
 #endif // ENABLE(SERVICE_WORKER)
index 1cd29299e3fd3c2fc9288e1860ad540310ce548d..27cdba2a0944c08cdb0d0b37e01394ff287db696 100644 (file)
@@ -56,7 +56,7 @@ public:
 
     void scheduleJobInServer(const WebCore::ServiceWorkerJobData&) final;
     void finishFetchingScriptInServer(const WebCore::ServiceWorkerFetchResult&) final;
-    void postMessageToServiceWorkerGlobalScope(uint64_t serviceWorkerIdentifier, Ref<WebCore::SerializedScriptValue>&&, const String& sourceOrigin) final;
+    void postMessageToServiceWorkerGlobalScope(uint64_t destinationServiceWorkerIdentifier, Ref<WebCore::SerializedScriptValue>&&, WebCore::ScriptExecutionContext& source) final;
 
     void disconnectedFromWebProcess();
     void didReceiveMessage(IPC::Connection&, IPC::Decoder&) final;
@@ -64,6 +64,8 @@ public:
     bool hasServiceWorkerRegisteredForOrigin(const WebCore::SecurityOrigin&) const final;
     Ref<ServiceWorkerClientFetch> startFetch(WebServiceWorkerProvider&, Ref<WebCore::ResourceLoader>&&, uint64_t identifier, ServiceWorkerClientFetch::Callback&&);
 
+    void postMessageToServiceWorkerClient(uint64_t destinationScriptExecutionContextIdentifier, const IPC::DataReference& message, uint64_t sourceServiceWorkerIdentifier, const String& sourceOrigin);
+
 private:
     void scheduleStorageJob(const WebCore::ServiceWorkerJobData&);
 
index 1155d1baad89558631f0381329db6fcf068f6693..911cf102e409a592276e2278fe5249d39530a105 100644 (file)
@@ -30,6 +30,7 @@ messages -> WebSWClientConnection {
     StartScriptFetchForServer(uint64_t jobIdentifier)
 
     SetSWOriginTableSharedMemory(WebKit::SharedMemory::Handle handle)
+    PostMessageToServiceWorkerClient(uint64_t destinationScriptExecutionContextIdentifier, IPC::DataReference message, uint64_t sourceServiceWorkerIdentifier, String sourceOrigin)
 }
 
 #endif // ENABLE(SERVICE_WORKER)
index 3d0b27d9cdbee820e9b3fc94bb7856921611866d..079a28f0c842a12ff5c65ce15381aaa652c382fb 100644 (file)
@@ -130,9 +130,14 @@ void WebSWContextManagerConnection::startFetch(uint64_t serverConnectionIdentifi
     serviceWorkerThreadProxy->thread().postFetchTask(WTFMove(client), WTFMove(request), WTFMove(options));
 }
 
-void WebSWContextManagerConnection::postMessageToServiceWorkerGlobalScope(uint64_t serviceWorkerIdentifier, const IPC::DataReference& message, const String& sourceOrigin)
+void WebSWContextManagerConnection::postMessageToServiceWorkerGlobalScope(uint64_t destinationServiceWorkerIdentifier, const IPC::DataReference& message, const ServiceWorkerClientIdentifier& sourceIdentifier, const String& sourceOrigin)
 {
-    SWContextManager::singleton().postMessageToServiceWorkerGlobalScope(serviceWorkerIdentifier, SerializedScriptValue::adopt(message.vector()), sourceOrigin);
+    SWContextManager::singleton().postMessageToServiceWorkerGlobalScope(destinationServiceWorkerIdentifier, SerializedScriptValue::adopt(message.vector()), sourceIdentifier, sourceOrigin);
+}
+
+void WebSWContextManagerConnection::postMessageToServiceWorkerClient(const ServiceWorkerClientIdentifier& destinationIdentifier, Ref<SerializedScriptValue>&& message, uint64_t sourceServiceWorkerIdentifier, const String& sourceOrigin)
+{
+    m_connectionToStorageProcess->send(Messages::StorageProcess::PostMessageToServiceWorkerClient(destinationIdentifier, IPC::DataReference { message->data() }, sourceServiceWorkerIdentifier, sourceOrigin), 0);
 }
 
 } // namespace WebCore
index 046d2263b649b6d25e86121f6a422d72adeacee5..2da096c166cde3417f8a129a38761ba205fa628d 100644 (file)
@@ -41,19 +41,22 @@ namespace WebKit {
 
 struct WebPreferencesStore;
 
-class WebSWContextManagerConnection : public WebCore::SWContextManager::Connection, public IPC::MessageReceiver {
+class WebSWContextManagerConnection final : public WebCore::SWContextManager::Connection, public IPC::MessageReceiver {
 public:
     WebSWContextManagerConnection(Ref<IPC::Connection>&&, uint64_t pageID, const WebPreferencesStore&);
 
     void didReceiveMessage(IPC::Connection&, IPC::Decoder&) final;
 
-    void postMessageToServiceWorkerGlobalScope(uint64_t serviceWorkerIdentifier, const IPC::DataReference& message, const String& sourceOrigin);
-
 private:
     void updatePreferences(const WebPreferencesStore&);
 
+    // WebCore::SWContextManager::Connection.
+    void postMessageToServiceWorkerClient(const WebCore::ServiceWorkerClientIdentifier& destinationIdentifier, Ref<WebCore::SerializedScriptValue>&& message, uint64_t sourceServiceWorkerIdentifier, const String& sourceOrigin) final;
+
+    // IPC messages.
     void startServiceWorker(uint64_t serverConnectionIdentifier, const WebCore::ServiceWorkerContextData&);
     void startFetch(uint64_t serverConnectionIdentifier, uint64_t fetchIdentifier, uint64_t serviceWorkerIdentifier, WebCore::ResourceRequest&&, WebCore::FetchOptions&&);
+    void postMessageToServiceWorkerGlobalScope(uint64_t destinationServiceWorkerIdentifier, const IPC::DataReference& message, const WebCore::ServiceWorkerClientIdentifier& sourceIdentifier, const String& sourceOrigin);
 
     Ref<IPC::Connection> m_connectionToStorageProcess;
     uint64_t m_pageID { 0 };
index 5d72d1b5f83f61ac5fc0427d8964c14c1e964718..94b8e031b11b7b3ce38c333b1534f83be6f8f53f 100644 (file)
@@ -25,7 +25,7 @@
 messages -> WebSWContextManagerConnection {
     StartServiceWorker(uint64_t serverConnectionIdentifier, struct WebCore::ServiceWorkerContextData contextData)
     StartFetch(uint64_t serverConnectionIdentifier, uint64_t fetchIdentifier, uint64_t serviceWorkerIdentifier, WebCore::ResourceRequest request, struct WebCore::FetchOptions options)
-    PostMessageToServiceWorkerGlobalScope(uint64_t serviceWorkerIdentifier, IPC::DataReference message, String sourceOrigin)
+    PostMessageToServiceWorkerGlobalScope(uint64_t destinationServiceWorkerIdentifier, IPC::DataReference message, struct WebCore::ServiceWorkerClientIdentifier sourceIdentifier, String sourceOrigin)
 }
 
 #endif