<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[225011] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/225011">225011</a></dd>
<dt>Author</dt> <dd>cdumez@apple.com</dd>
<dt>Date</dt> <dd>2017-11-17 19:42:17 -0800 (Fri, 17 Nov 2017)</dd>
</dl>

<h3>Log Message</h3>
<pre>[Service Workers] Implement "Notify Controller Change" algorithm
https://bugs.webkit.org/show_bug.cgi?id=179822

Reviewed by Youenn Fablet.

Source/WebCore:

Implement "Notify Controller Change" algorithm:
- https://w3c.github.io/ServiceWorker/#notify-controller-change

Use it to support step 7 of "Activate" algorithm:
- https://w3c.github.io/ServiceWorker/#activate

Test: http/tests/workers/service/controller-change.html

* workers/service/ServiceWorkerContainer.cpp:
(WebCore::ServiceWorkerContainer::scheduleTaskToFireControllerChangeEvent):
* workers/service/ServiceWorkerContainer.h:
* workers/service/server/SWClientConnection.cpp:
(WebCore::SWClientConnection::notifyClientsOfControllerChange):
* workers/service/server/SWClientConnection.h:
* workers/service/server/SWServer.h:
* workers/service/server/SWServerJobQueue.cpp:
(WebCore::SWServerJobQueue::activate):
* workers/service/server/SWServerRegistration.cpp:
(WebCore::SWServerRegistration::notifyClientsOfControllerChange):
* workers/service/server/SWServerRegistration.h:

Source/WebKit:

* Scripts/webkit/messages.py:
(class_template_headers):
* StorageProcess/ServiceWorker/WebSWServerConnection.cpp:
(WebKit::WebSWServerConnection::notifyClientsOfControllerChange):
* StorageProcess/ServiceWorker/WebSWServerConnection.h:
* WebProcess/Storage/WebSWClientConnection.messages.in:

LayoutTests:

Add layout test coverage.

* http/tests/workers/service/controller-change-expected.txt: Added.
* http/tests/workers/service/controller-change.html: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestshttptestsworkersserviceresourcesswtestprejs">trunk/LayoutTests/http/tests/workers/service/resources/sw-test-pre.js</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreworkersserviceServiceWorkerContainercpp">trunk/Source/WebCore/workers/service/ServiceWorkerContainer.cpp</a></li>
<li><a href="#trunkSourceWebCoreworkersserviceServiceWorkerContainerh">trunk/Source/WebCore/workers/service/ServiceWorkerContainer.h</a></li>
<li><a href="#trunkSourceWebCoreworkersserviceserverSWClientConnectioncpp">trunk/Source/WebCore/workers/service/server/SWClientConnection.cpp</a></li>
<li><a href="#trunkSourceWebCoreworkersserviceserverSWClientConnectionh">trunk/Source/WebCore/workers/service/server/SWClientConnection.h</a></li>
<li><a href="#trunkSourceWebCoreworkersserviceserverSWServerh">trunk/Source/WebCore/workers/service/server/SWServer.h</a></li>
<li><a href="#trunkSourceWebCoreworkersserviceserverSWServerJobQueuecpp">trunk/Source/WebCore/workers/service/server/SWServerJobQueue.cpp</a></li>
<li><a href="#trunkSourceWebCoreworkersserviceserverSWServerRegistrationcpp">trunk/Source/WebCore/workers/service/server/SWServerRegistration.cpp</a></li>
<li><a href="#trunkSourceWebCoreworkersserviceserverSWServerRegistrationh">trunk/Source/WebCore/workers/service/server/SWServerRegistration.h</a></li>
<li><a href="#trunkSourceWebKitChangeLog">trunk/Source/WebKit/ChangeLog</a></li>
<li><a href="#trunkSourceWebKitScriptswebkitmessagespy">trunk/Source/WebKit/Scripts/webkit/messages.py</a></li>
<li><a href="#trunkSourceWebKitStorageProcessServiceWorkerWebSWServerConnectioncpp">trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.cpp</a></li>
<li><a href="#trunkSourceWebKitStorageProcessServiceWorkerWebSWServerConnectionh">trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.h</a></li>
<li><a href="#trunkSourceWebKitWebProcessStorageWebSWClientConnectionmessagesin">trunk/Source/WebKit/WebProcess/Storage/WebSWClientConnection.messages.in</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestshttptestsworkersservicecontrollerchangeexpectedtxt">trunk/LayoutTests/http/tests/workers/service/controller-change-expected.txt</a></li>
<li><a href="#trunkLayoutTestshttptestsworkersservicecontrollerchangehtml">trunk/LayoutTests/http/tests/workers/service/controller-change.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (225010 => 225011)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog      2017-11-18 03:02:20 UTC (rev 225010)
+++ trunk/LayoutTests/ChangeLog 2017-11-18 03:42:17 UTC (rev 225011)
</span><span class="lines">@@ -1,3 +1,15 @@
</span><ins>+2017-11-17  Chris Dumez  <cdumez@apple.com>
+
+        [Service Workers] Implement "Notify Controller Change" algorithm
+        https://bugs.webkit.org/show_bug.cgi?id=179822
+
+        Reviewed by Youenn Fablet.
+
+        Add layout test coverage.
+
+        * http/tests/workers/service/controller-change-expected.txt: Added.
+        * http/tests/workers/service/controller-change.html: Added.
+
</ins><span class="cx"> 2017-11-17  Joseph Pecoraro  <pecoraro@apple.com>
</span><span class="cx"> 
</span><span class="cx">         Web Inspector: Fix grammar typo in tests
</span></span></pre></div>
<a id="trunkLayoutTestshttptestsworkersservicecontrollerchangeexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/http/tests/workers/service/controller-change-expected.txt (0 => 225011)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/workers/service/controller-change-expected.txt                              (rev 0)
+++ trunk/LayoutTests/http/tests/workers/service/controller-change-expected.txt 2017-11-18 03:42:17 UTC (rev 225011)
</span><span class="lines">@@ -0,0 +1,5 @@
</span><ins>+
+PASS: frame has a controller
+PASS: controllerchange event has been fired
+PASS: controller has been updated
+
</ins></span></pre></div>
<a id="trunkLayoutTestshttptestsworkersservicecontrollerchangehtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/http/tests/workers/service/controller-change.html (0 => 225011)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/workers/service/controller-change.html                              (rev 0)
+++ trunk/LayoutTests/http/tests/workers/service/controller-change.html 2017-11-18 03:42:17 UTC (rev 225011)
</span><span class="lines">@@ -0,0 +1,44 @@
</span><ins>+<html>
+<head>
+<script src="resources/sw-test-pre.js"></script>
+</head>
+<body>
+<script>
+let initialController = null;
+
+function listenForControllerChange(frame)
+{
+    frame.contentWindow.navigator.serviceWorker.addEventListener("controllerchange", function() {
+        log("PASS: controllerchange event has been fired");
+
+        let newController = frame.contentWindow.navigator.serviceWorker.controller;
+        if (newController != null && newController != initialController)
+             log("PASS: controller has been updated");
+        else
+             log("FAIL: controller has not been updated");
+
+        finishSWTest();
+    });
+}
+
+async function test() {
+    let scopeURL = "/";
+    let registration = await registerAndWaitForActive("resources/service-worker-fetch-worker.js", scopeURL);
+    let frame = await withFrame(scopeURL);
+    initialController = frame.contentWindow.navigator.serviceWorker.controller;
+    if (initialController === null) {
+        log("FAIL: frame does not have a controller");
+        finishSWTest();
+        return;
+    }
+
+    log("PASS: frame has a controller");
+    
+    listenForControllerChange(frame);
+    registration.update();
+}
+
+test();
+</script>
+</body>
+</html>
</ins></span></pre></div>
<a id="trunkLayoutTestshttptestsworkersserviceresourcesswtestprejs"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/http/tests/workers/service/resources/sw-test-pre.js (225010 => 225011)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/workers/service/resources/sw-test-pre.js    2017-11-18 03:02:20 UTC (rev 225010)
+++ trunk/LayoutTests/http/tests/workers/service/resources/sw-test-pre.js       2017-11-18 03:42:17 UTC (rev 225011)
</span><span class="lines">@@ -39,23 +39,10 @@
</span><span class="cx">         testRunner.notifyDone();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-async function interceptedFrame(workerURL, scopeURL)
</del><ins>+function withFrame(scopeURL)
</ins><span class="cx"> {
</span><del>-    var registration = await navigator.serviceWorker.register(workerURL, { scope : scopeURL });
-    await new Promise(resolve => {
-        if (registration.active)
-            resolve();
-        worker = registration.installing;
-        if (worker.state === "activated")
-            resolve();
-        worker.addEventListener("statechange", () => {
-            if (worker.state === "activated")
-                resolve();
-        });
-    });
-
-    return await new Promise((resolve) => {
-        var frame = document.createElement('iframe');
</del><ins>+    return new Promise((resolve) => {
+        let frame = document.createElement('iframe');
</ins><span class="cx">         frame.src = scopeURL;
</span><span class="cx">         frame.onload = function() { resolve(frame); };
</span><span class="cx">         document.body.appendChild(frame);
</span><span class="lines">@@ -62,6 +49,27 @@
</span><span class="cx">     });
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+function registerAndWaitForActive(workerURL, scopeURL)
+{
+    return navigator.serviceWorker.register(workerURL, { scope : scopeURL }).then(function(registration) {
+        return new Promise(resolve => {
+            if (registration.active)
+                resolve(registration);
+            worker = registration.installing;
+            worker.addEventListener("statechange", () => {
+                if (worker.state === "activated")
+                    resolve(registration);
+            });
+        });
+    });
+}
+
+async function interceptedFrame(workerURL, scopeURL)
+{
+    await registerAndWaitForActive(workerURL, scopeURL);
+    return await withFrame(scopeURL);
+}
+
</ins><span class="cx"> function gc() {
</span><span class="cx">     if (typeof GCController !== "undefined")
</span><span class="cx">         GCController.collect();
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (225010 => 225011)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog   2017-11-18 03:02:20 UTC (rev 225010)
+++ trunk/Source/WebCore/ChangeLog      2017-11-18 03:42:17 UTC (rev 225011)
</span><span class="lines">@@ -1,5 +1,33 @@
</span><span class="cx"> 2017-11-17  Chris Dumez  <cdumez@apple.com>
</span><span class="cx"> 
</span><ins>+        [Service Workers] Implement "Notify Controller Change" algorithm
+        https://bugs.webkit.org/show_bug.cgi?id=179822
+
+        Reviewed by Youenn Fablet.
+
+        Implement "Notify Controller Change" algorithm:
+        - https://w3c.github.io/ServiceWorker/#notify-controller-change
+
+        Use it to support step 7 of "Activate" algorithm:
+        - https://w3c.github.io/ServiceWorker/#activate
+
+        Test: http/tests/workers/service/controller-change.html
+
+        * workers/service/ServiceWorkerContainer.cpp:
+        (WebCore::ServiceWorkerContainer::scheduleTaskToFireControllerChangeEvent):
+        * workers/service/ServiceWorkerContainer.h:
+        * workers/service/server/SWClientConnection.cpp:
+        (WebCore::SWClientConnection::notifyClientsOfControllerChange):
+        * workers/service/server/SWClientConnection.h:
+        * workers/service/server/SWServer.h:
+        * workers/service/server/SWServerJobQueue.cpp:
+        (WebCore::SWServerJobQueue::activate):
+        * workers/service/server/SWServerRegistration.cpp:
+        (WebCore::SWServerRegistration::notifyClientsOfControllerChange):
+        * workers/service/server/SWServerRegistration.h:
+
+2017-11-17  Chris Dumez  <cdumez@apple.com>
+
</ins><span class="cx">         Unreviewed attempt to fix build after r225006.
</span><span class="cx"> 
</span><span class="cx">         * platform/network/cf/NetworkStorageSessionCFNet.cpp:
</span></span></pre></div>
<a id="trunkSourceWebCoreworkersserviceServiceWorkerContainercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/workers/service/ServiceWorkerContainer.cpp (225010 => 225011)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/workers/service/ServiceWorkerContainer.cpp  2017-11-18 03:02:20 UTC (rev 225010)
+++ trunk/Source/WebCore/workers/service/ServiceWorkerContainer.cpp     2017-11-18 03:42:17 UTC (rev 225011)
</span><span class="lines">@@ -411,6 +411,19 @@
</span><span class="cx">     m_registrations.remove(registration.identifier());
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void ServiceWorkerContainer::scheduleTaskToFireControllerChangeEvent()
+{
+    if (m_isStopped)
+        return;
+
+    scriptExecutionContext()->postTask([this, protectedThis = makeRef(*this)](ScriptExecutionContext&) mutable {
+        if (m_isStopped)
+            return;
+
+        dispatchEvent(Event::create(eventNames().controllerchangeEvent, false, false));
+    });
+}
+
</ins><span class="cx"> } // namespace WebCore
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(SERVICE_WORKER)
</span></span></pre></div>
<a id="trunkSourceWebCoreworkersserviceServiceWorkerContainerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/workers/service/ServiceWorkerContainer.h (225010 => 225011)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/workers/service/ServiceWorkerContainer.h    2017-11-18 03:02:20 UTC (rev 225010)
+++ trunk/Source/WebCore/workers/service/ServiceWorkerContainer.h       2017-11-18 03:42:17 UTC (rev 225011)
</span><span class="lines">@@ -67,6 +67,7 @@
</span><span class="cx">     void getRegistration(const String& clientURL, Ref<DeferredPromise>&&);
</span><span class="cx">     void scheduleTaskToUpdateRegistrationState(ServiceWorkerRegistrationIdentifier, ServiceWorkerRegistrationState, const std::optional<ServiceWorkerData>&);
</span><span class="cx">     void scheduleTaskToFireUpdateFoundEvent(ServiceWorkerRegistrationIdentifier);
</span><ins>+    void scheduleTaskToFireControllerChangeEvent();
</ins><span class="cx"> 
</span><span class="cx">     using RegistrationsPromise = DOMPromiseDeferred<IDLSequence<IDLInterface<ServiceWorkerRegistration>>>;
</span><span class="cx">     void getRegistrations(RegistrationsPromise&&);
</span></span></pre></div>
<a id="trunkSourceWebCoreworkersserviceserverSWClientConnectioncpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/workers/service/server/SWClientConnection.cpp (225010 => 225011)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/workers/service/server/SWClientConnection.cpp       2017-11-18 03:02:20 UTC (rev 225010)
+++ trunk/Source/WebCore/workers/service/server/SWClientConnection.cpp  2017-11-18 03:42:17 UTC (rev 225011)
</span><span class="lines">@@ -165,6 +165,24 @@
</span><span class="cx">     });
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void SWClientConnection::notifyClientsOfControllerChange(const HashSet<uint64_t>& scriptExecutionContexts, ServiceWorkerData&& newController)
+{
+    ASSERT(!scriptExecutionContexts.isEmpty());
+
+    for (auto& clientIdentifier : scriptExecutionContexts) {
+        // FIXME: Support worker contexts.
+        auto* client = Document::allDocumentsMap().get(clientIdentifier);
+        if (!client)
+            continue;
+
+        ASSERT(client->activeServiceWorker());
+        ASSERT(client->activeServiceWorker()->identifier() != newController.identifier);
+        client->setActiveServiceWorker(ServiceWorker::getOrCreate(*client, ServiceWorkerData { newController }));
+        if (auto* container = client->serviceWorkerContainer())
+            container->scheduleTaskToFireControllerChangeEvent();
+    }
+}
+
</ins><span class="cx"> } // namespace WebCore
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(SERVICE_WORKER)
</span></span></pre></div>
<a id="trunkSourceWebCoreworkersserviceserverSWClientConnectionh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/workers/service/server/SWClientConnection.h (225010 => 225011)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/workers/service/server/SWClientConnection.h 2017-11-18 03:02:20 UTC (rev 225010)
+++ trunk/Source/WebCore/workers/service/server/SWClientConnection.h    2017-11-18 03:42:17 UTC (rev 225011)
</span><span class="lines">@@ -86,6 +86,7 @@
</span><span class="cx">     WEBCORE_EXPORT void updateRegistrationState(ServiceWorkerRegistrationIdentifier, ServiceWorkerRegistrationState, const std::optional<ServiceWorkerData>&);
</span><span class="cx">     WEBCORE_EXPORT void updateWorkerState(ServiceWorkerIdentifier, ServiceWorkerState);
</span><span class="cx">     WEBCORE_EXPORT void fireUpdateFoundEvent(ServiceWorkerRegistrationIdentifier);
</span><ins>+    WEBCORE_EXPORT void notifyClientsOfControllerChange(const HashSet<uint64_t>& scriptExecutionContexts, ServiceWorkerData&& newController);
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     virtual void scheduleJobInServer(const ServiceWorkerJobData&) = 0;
</span></span></pre></div>
<a id="trunkSourceWebCoreworkersserviceserverSWServerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/workers/service/server/SWServer.h (225010 => 225011)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/workers/service/server/SWServer.h   2017-11-18 03:02:20 UTC (rev 225010)
+++ trunk/Source/WebCore/workers/service/server/SWServer.h      2017-11-18 03:42:17 UTC (rev 225011)
</span><span class="lines">@@ -73,6 +73,7 @@
</span><span class="cx">         virtual void updateRegistrationStateInClient(ServiceWorkerRegistrationIdentifier, ServiceWorkerRegistrationState, const std::optional<ServiceWorkerData>&) = 0;
</span><span class="cx">         virtual void updateWorkerStateInClient(ServiceWorkerIdentifier, ServiceWorkerState) = 0;
</span><span class="cx">         virtual void fireUpdateFoundEvent(ServiceWorkerRegistrationIdentifier) = 0;
</span><ins>+        virtual void notifyClientsOfControllerChange(const HashSet<uint64_t>& scriptExecutionContexts, const ServiceWorkerData& newController) = 0;
</ins><span class="cx"> 
</span><span class="cx">     protected:
</span><span class="cx">         WEBCORE_EXPORT explicit Connection(SWServer&);
</span></span></pre></div>
<a id="trunkSourceWebCoreworkersserviceserverSWServerJobQueuecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/workers/service/server/SWServerJobQueue.cpp (225010 => 225011)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/workers/service/server/SWServerJobQueue.cpp 2017-11-18 03:02:20 UTC (rev 225010)
+++ trunk/Source/WebCore/workers/service/server/SWServerJobQueue.cpp    2017-11-18 03:42:17 UTC (rev 225011)
</span><span class="lines">@@ -230,7 +230,12 @@
</span><span class="cx">     // Run the Update Worker State algorithm passing registration's active worker and activating as the arguments.
</span><span class="cx">     registration.updateWorkerState(*registration.activeWorker(), ServiceWorkerState::Activating);
</span><span class="cx">     // FIXME: For each service worker client client whose creation URL matches registration's scope url...
</span><del>-    // FIXME: For each service worker client client who is using registration...
</del><ins>+
+    // For each service worker client client who is using registration:
+    // - Set client's active worker to registration's active worker.
+    // - Invoke Notify Controller Change algorithm with client as the argument.
+    registration.notifyClientsOfControllerChange();
+
</ins><span class="cx">     // FIXME: Invoke Run Service Worker algorithm with activeWorker as the argument.
</span><span class="cx"> 
</span><span class="cx">     // Queue a task to fire the activate event.
</span></span></pre></div>
<a id="trunkSourceWebCoreworkersserviceserverSWServerRegistrationcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/workers/service/server/SWServerRegistration.cpp (225010 => 225011)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/workers/service/server/SWServerRegistration.cpp     2017-11-18 03:02:20 UTC (rev 225010)
+++ trunk/Source/WebCore/workers/service/server/SWServerRegistration.cpp        2017-11-18 03:42:17 UTC (rev 225011)
</span><span class="lines">@@ -163,6 +163,17 @@
</span><span class="cx">         m_clientsUsingRegistration.remove(iterator);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+// https://w3c.github.io/ServiceWorker/#notify-controller-change
+void SWServerRegistration::notifyClientsOfControllerChange()
+{
+    ASSERT(activeWorker());
+
+    for (auto& item : m_clientsUsingRegistration) {
+        if (auto* connection = m_server.getConnection(item.key))
+            connection->notifyClientsOfControllerChange(item.value, activeWorker()->data());
+    }
+}
+
</ins><span class="cx"> void SWServerRegistration::unregisterServerConnection(SWServerConnectionIdentifier serverConnectionIdentifier)
</span><span class="cx"> {
</span><span class="cx">     m_connectionsWithClientRegistrations.removeAll(serverConnectionIdentifier);
</span></span></pre></div>
<a id="trunkSourceWebCoreworkersserviceserverSWServerRegistrationh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/workers/service/server/SWServerRegistration.h (225010 => 225011)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/workers/service/server/SWServerRegistration.h       2017-11-18 03:02:20 UTC (rev 225010)
+++ trunk/Source/WebCore/workers/service/server/SWServerRegistration.h  2017-11-18 03:42:17 UTC (rev 225011)
</span><span class="lines">@@ -78,6 +78,8 @@
</span><span class="cx">     void removeClientUsingRegistration(const ServiceWorkerClientIdentifier&);
</span><span class="cx">     void unregisterServerConnection(SWServerConnectionIdentifier);
</span><span class="cx"> 
</span><ins>+    void notifyClientsOfControllerChange();
+
</ins><span class="cx"> private:
</span><span class="cx">     void forEachConnection(const WTF::Function<void(SWServer::Connection&)>&);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKitChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/ChangeLog (225010 => 225011)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/ChangeLog    2017-11-18 03:02:20 UTC (rev 225010)
+++ trunk/Source/WebKit/ChangeLog       2017-11-18 03:42:17 UTC (rev 225011)
</span><span class="lines">@@ -1,5 +1,19 @@
</span><span class="cx"> 2017-11-17  Chris Dumez  <cdumez@apple.com>
</span><span class="cx"> 
</span><ins>+        [Service Workers] Implement "Notify Controller Change" algorithm
+        https://bugs.webkit.org/show_bug.cgi?id=179822
+
+        Reviewed by Youenn Fablet.
+
+        * Scripts/webkit/messages.py:
+        (class_template_headers):
+        * StorageProcess/ServiceWorker/WebSWServerConnection.cpp:
+        (WebKit::WebSWServerConnection::notifyClientsOfControllerChange):
+        * StorageProcess/ServiceWorker/WebSWServerConnection.h:
+        * WebProcess/Storage/WebSWClientConnection.messages.in:
+
+2017-11-17  Chris Dumez  <cdumez@apple.com>
+
</ins><span class="cx">         Use a strongly typed identifier for SWServer::Connection
</span><span class="cx">         https://bugs.webkit.org/show_bug.cgi?id=179848
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKitScriptswebkitmessagespy"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/Scripts/webkit/messages.py (225010 => 225011)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/Scripts/webkit/messages.py   2017-11-18 03:02:20 UTC (rev 225010)
+++ trunk/Source/WebKit/Scripts/webkit/messages.py      2017-11-18 03:42:17 UTC (rev 225011)
</span><span class="lines">@@ -300,6 +300,7 @@
</span><span class="cx">     class_template_types = {
</span><span class="cx">         'WebCore::RectEdges': {'headers': ['<WebCore/RectEdges.h>'], 'argument_coder_headers': ['"ArgumentCoders.h"']},
</span><span class="cx">         'HashMap': {'headers': ['<wtf/HashMap.h>'], 'argument_coder_headers': ['"ArgumentCoders.h"']},
</span><ins>+        'HashSet': {'headers': ['<wtf/HashSet.h>'], 'argument_coder_headers': ['"ArgumentCoders.h"']},
</ins><span class="cx">         'std::optional': {'headers': ['<wtf/Optional.h>'], 'argument_coder_headers': ['"ArgumentCoders.h"']},
</span><span class="cx">         'OptionSet': {'headers': ['<wtf/OptionSet.h>'], 'argument_coder_headers': ['"ArgumentCoders.h"']},
</span><span class="cx">         'Vector': {'headers': ['<wtf/Vector.h>'], 'argument_coder_headers': ['"ArgumentCoders.h"']},
</span></span></pre></div>
<a id="trunkSourceWebKitStorageProcessServiceWorkerWebSWServerConnectioncpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.cpp (225010 => 225011)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.cpp       2017-11-18 03:02:20 UTC (rev 225010)
+++ trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.cpp  2017-11-18 03:42:17 UTC (rev 225011)
</span><span class="lines">@@ -102,6 +102,11 @@
</span><span class="cx">     send(Messages::WebSWClientConnection::FireUpdateFoundEvent(identifier));
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void WebSWServerConnection::notifyClientsOfControllerChange(const HashSet<uint64_t>& scriptExecutionContexts, const ServiceWorkerData& newController)
+{
+    send(Messages::WebSWClientConnection::NotifyClientsOfControllerChange(scriptExecutionContexts, newController));
+}
+
</ins><span class="cx"> void WebSWServerConnection::updateWorkerStateInClient(ServiceWorkerIdentifier worker, ServiceWorkerState state)
</span><span class="cx"> {
</span><span class="cx">     send(Messages::WebSWClientConnection::UpdateWorkerState(worker, state));
</span></span></pre></div>
<a id="trunkSourceWebKitStorageProcessServiceWorkerWebSWServerConnectionh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.h (225010 => 225011)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.h 2017-11-18 03:02:20 UTC (rev 225010)
+++ trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.h    2017-11-18 03:42:17 UTC (rev 225011)
</span><span class="lines">@@ -73,6 +73,7 @@
</span><span class="cx">     void updateRegistrationStateInClient(WebCore::ServiceWorkerRegistrationIdentifier, WebCore::ServiceWorkerRegistrationState, const std::optional<WebCore::ServiceWorkerData>&) final;
</span><span class="cx">     void updateWorkerStateInClient(WebCore::ServiceWorkerIdentifier, WebCore::ServiceWorkerState) final;
</span><span class="cx">     void fireUpdateFoundEvent(WebCore::ServiceWorkerRegistrationIdentifier) final;
</span><ins>+    void notifyClientsOfControllerChange(const HashSet<uint64_t>& scriptExecutionContexts, const WebCore::ServiceWorkerData& newController);
</ins><span class="cx"> 
</span><span class="cx">     void startFetch(uint64_t fetchIdentifier, std::optional<WebCore::ServiceWorkerIdentifier>, const WebCore::ResourceRequest&, const WebCore::FetchOptions&, const IPC::FormDataReference&);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKitWebProcessStorageWebSWClientConnectionmessagesin"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/WebProcess/Storage/WebSWClientConnection.messages.in (225010 => 225011)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/WebProcess/Storage/WebSWClientConnection.messages.in 2017-11-18 03:02:20 UTC (rev 225010)
+++ trunk/Source/WebKit/WebProcess/Storage/WebSWClientConnection.messages.in    2017-11-18 03:42:17 UTC (rev 225011)
</span><span class="lines">@@ -31,6 +31,7 @@
</span><span class="cx">     UpdateRegistrationState(WebCore::ServiceWorkerRegistrationIdentifier identifier, enum WebCore::ServiceWorkerRegistrationState state, std::optional<WebCore::ServiceWorkerData> serviceWorkerIdentifier)
</span><span class="cx">     UpdateWorkerState(WebCore::ServiceWorkerIdentifier serviceWorkerIdentifier, enum WebCore::ServiceWorkerState state)
</span><span class="cx">     FireUpdateFoundEvent(WebCore::ServiceWorkerRegistrationIdentifier identifier)
</span><ins>+    NotifyClientsOfControllerChange(HashSet<uint64_t> scriptExecutionContexts, struct WebCore::ServiceWorkerData newController)
</ins><span class="cx"> 
</span><span class="cx">     InitializeSWOriginTableAsEmpty()
</span><span class="cx">     SetSWOriginTableSharedMemory(WebKit::SharedMemory::Handle handle)
</span></span></pre>
</div>
</div>

</body>
</html>