Resource Load Statistics: Make WebResourceLoadStatisticsStore::updateCookiePartitioni...
authorwilander@apple.com <wilander@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 25 Jun 2018 23:37:39 +0000 (23:37 +0000)
committerwilander@apple.com <wilander@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 25 Jun 2018 23:37:39 +0000 (23:37 +0000)
https://bugs.webkit.org/show_bug.cgi?id=186903
<rdar://problem/41350182>

Reviewed by Chris Dumez.

Source/WebKit:

This patch stores the callback sent to
WebResourceLoadStatisticsStore::updateCookiePartitioningForDomains(),
sets up a context ID, and sends that ID to the network process when
asking it to update cookie partitioning and blocking. The network
process then tells the UI process when it's done, at which point the
callback is called.

This change is meant to address layout test flakiness.

* NetworkProcess/NetworkProcess.cpp:
(WebKit::NetworkProcess::updatePrevalentDomainsToPartitionOrBlockCookies):
* NetworkProcess/NetworkProcess.h:
* NetworkProcess/NetworkProcess.messages.in:
* UIProcess/Network/NetworkProcessProxy.cpp:
(WebKit::NetworkProcessProxy::updatePrevalentDomainsToPartitionOrBlockCookies):
(WebKit::NetworkProcessProxy::didUpdatePartitionOrBlockCookies):
* UIProcess/Network/NetworkProcessProxy.h:
* UIProcess/Network/NetworkProcessProxy.messages.in:
* UIProcess/WebResourceLoadStatisticsStore.cpp:
(WebKit::WebResourceLoadStatisticsStore::updateCookiePartitioning):
(WebKit::WebResourceLoadStatisticsStore::updateCookiePartitioningForDomains):
* UIProcess/WebResourceLoadStatisticsStore.h:
* UIProcess/WebsiteData/WebsiteDataStore.cpp:
(WebKit::WebsiteDataStore::updatePrevalentDomainsToPartitionOrBlockCookies):
(WebKit::WebsiteDataStore::enableResourceLoadStatisticsAndSetTestingCallback):
* UIProcess/WebsiteData/WebsiteDataStore.h:

LayoutTests:

* http/tests/storageAccess/grant-storage-access-under-opener-expected.txt:
* http/tests/storageAccess/grant-storage-access-under-opener.html:
    Moved the code block to the page's body instead of its head.
    Added an initial console log statement. The reason for these
    changes is that we're seeing flaky timeouts with no output.

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

14 files changed:
LayoutTests/ChangeLog
LayoutTests/http/tests/storageAccess/grant-storage-access-under-opener-expected.txt
LayoutTests/http/tests/storageAccess/grant-storage-access-under-opener.html
Source/WebKit/ChangeLog
Source/WebKit/NetworkProcess/NetworkProcess.cpp
Source/WebKit/NetworkProcess/NetworkProcess.h
Source/WebKit/NetworkProcess/NetworkProcess.messages.in
Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp
Source/WebKit/UIProcess/Network/NetworkProcessProxy.h
Source/WebKit/UIProcess/Network/NetworkProcessProxy.messages.in
Source/WebKit/UIProcess/WebResourceLoadStatisticsStore.cpp
Source/WebKit/UIProcess/WebResourceLoadStatisticsStore.h
Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp
Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h

index d08a752..7b20ee5 100644 (file)
@@ -1,3 +1,17 @@
+2018-06-25  John Wilander  <wilander@apple.com>
+
+        Resource Load Statistics: Make WebResourceLoadStatisticsStore::updateCookiePartitioningForDomains() wait for the network process before calling its callback
+        https://bugs.webkit.org/show_bug.cgi?id=186903
+        <rdar://problem/41350182>
+
+        Reviewed by Chris Dumez.
+
+        * http/tests/storageAccess/grant-storage-access-under-opener-expected.txt:
+        * http/tests/storageAccess/grant-storage-access-under-opener.html:
+            Moved the code block to the page's body instead of its head.
+            Added an initial console log statement. The reason for these
+            changes is that we're seeing flaky timeouts with no output.
+
 2018-06-25  Chris Dumez  <cdumez@apple.com>
 
         performance-api/performance-observer-no-document-leak.html is flaky
index 5308804..bc5a809 100644 (file)
@@ -1,7 +1,8 @@
-CONSOLE MESSAGE: line 54: Running test.
-CONSOLE MESSAGE: line 67: About to call testRunner.statisticsUpdateCookiePartitioning().
-CONSOLE MESSAGE: line 69: About to open the new window.
-CONSOLE MESSAGE: line 43: About to open the third party iframe.
+CONSOLE MESSAGE: line 8: First JavaScript statement.
+CONSOLE MESSAGE: line 57: Running test.
+CONSOLE MESSAGE: line 73: About to call testRunner.statisticsUpdateCookiePartitioning().
+CONSOLE MESSAGE: line 75: About to open the new window.
+CONSOLE MESSAGE: line 45: About to open the third party iframe.
 Tests that a cross-origin window from a prevalent domain with non-recent user interaction gets immediate storage access under its opener.
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
index 1cbd1c7..c4a3e47 100644 (file)
@@ -2,76 +2,80 @@
 <html>
 <head>
     <script src="/js-test-resources/js-test.js"></script>
-    <script>
-        description("Tests that a cross-origin window from a prevalent domain with non-recent user interaction gets immediate storage access under its opener.");
-        jsTestIsAsync = true;
+</head>
+<body onload="run()">
+<script>
+    console.log("First JavaScript statement.");
 
-        function setEnableFeature(enable) {
-            if (!enable)
-                testRunner.statisticsResetToConsistentState();
-            internals.setResourceLoadStatisticsEnabled(enable);
-            testRunner.setCookieStoragePartitioningEnabled(enable);
-            testRunner.setStorageAccessAPIEnabled(enable);
-        }
+    description("Tests that a cross-origin window from a prevalent domain with non-recent user interaction gets immediate storage access under its opener.");
+    jsTestIsAsync = true;
 
-        window.addEventListener("message", receiveMessage, false);
+    function setEnableFeature(enable) {
+        if (!enable)
+            testRunner.statisticsResetToConsistentState();
+        internals.setResourceLoadStatisticsEnabled(enable);
+        testRunner.setCookieStoragePartitioningEnabled(enable);
+        testRunner.setStorageAccessAPIEnabled(enable);
+    }
 
-        function finishTest() {
-            setEnableFeature(false);
-            finishJSTest();
-        }
+    function finishTest() {
+        setEnableFeature(false);
+        finishJSTest();
+    }
 
-        function openIframe(url, onLoadHandler) {
-            const element = document.createElement("iframe");
-            element.src = url;
-            if (onLoadHandler) {
-                element.onload = onLoadHandler;
-            }
-            document.body.appendChild(element);
+    function openIframe(url, onLoadHandler) {
+        const element = document.createElement("iframe");
+        element.src = url;
+        if (onLoadHandler) {
+            element.onload = onLoadHandler;
         }
+        document.body.appendChild(element);
+    }
 
-        function receiveMessage(event) {
-            if (event.origin === "http://localhost:8000") {
-                if (event.data.indexOf("PASS") !== -1)
-                    testPassed(event.data.replace("PASS ", ""));
-                else
-                    testFailed(event.data);
-            } else
-                testFailed("Received a message from an unexpected origin: " + event.origin);
+    function receiveMessage(event) {
+        if (event.origin === "http://localhost:8000") {
+            if (event.data.indexOf("PASS") !== -1)
+                testPassed(event.data.replace("PASS ", ""));
+            else
+                testFailed(event.data);
+        } else
+            testFailed("Received a message from an unexpected origin: " + event.origin);
 
-            newWin.close();
-            console.log("About to open the third party iframe.");
-            openIframe(thirdPartyBaseUrl + subPathToGetCookies + "&message=Should receive first-party cookie.", finishTest);
-        }
+        newWin.close();
+        console.log("About to open the third party iframe.");
+        openIframe(thirdPartyBaseUrl + subPathToGetCookies + "&message=Should receive first-party cookie.", finishTest);
+    }
 
-        const thirdPartyOrigin = "http://localhost:8000";
-        const resourcePath = "/storageAccess/resources";
-        const thirdPartyBaseUrl = thirdPartyOrigin + resourcePath;
-        const firstPartyCookieName = "firstPartyCookie";
-        const subPathToGetCookies = "/get-cookies.php?name1=" + firstPartyCookieName;
-        var newWin;
-        function run() {
-            console.log("Running test.");
-            setEnableFeature(true);
-            testRunner.setCanOpenWindows();
+    const thirdPartyOrigin = "http://localhost:8000";
+    const resourcePath = "/storageAccess/resources";
+    const thirdPartyBaseUrl = thirdPartyOrigin + resourcePath;
+    const firstPartyCookieName = "firstPartyCookie";
+    const subPathToGetCookies = "/get-cookies.php?name1=" + firstPartyCookieName;
+    var newWin;
 
-            testRunner.setStatisticsPrevalentResource(thirdPartyOrigin, true);
-            if (!testRunner.isStatisticsPrevalentResource(thirdPartyOrigin))
-                testFailed("Host did not get set as prevalent resource.");
-            testRunner.setStatisticsHasHadNonRecentUserInteraction(thirdPartyOrigin, true);
-            if (!testRunner.isStatisticsHasHadUserInteraction(thirdPartyOrigin))
-                testFailed("Host did not get logged for user interaction.");
-            testRunner.dumpChildFramesAsText();
-            testRunner.setCloseRemainingWindowsWhenComplete(true);
+    function run() {
+        console.log("Running test.");
+        setEnableFeature(true);
 
-            console.log("About to call testRunner.statisticsUpdateCookiePartitioning().");
-            testRunner.statisticsUpdateCookiePartitioning(function () {
-                console.log("About to open the new window.");
-                newWin = window.open(thirdPartyOrigin + "/storageAccess/resources/set-cookie-and-report-back.html", "testWindow");
-            });
-        }
-    </script>
-</head>
-<body onload="run()">
+        window.addEventListener("message", receiveMessage, false);
+
+        testRunner.setCanOpenWindows();
+
+        testRunner.setStatisticsPrevalentResource(thirdPartyOrigin, true);
+        if (!testRunner.isStatisticsPrevalentResource(thirdPartyOrigin))
+            testFailed("Host did not get set as prevalent resource.");
+        testRunner.setStatisticsHasHadNonRecentUserInteraction(thirdPartyOrigin, true);
+        if (!testRunner.isStatisticsHasHadUserInteraction(thirdPartyOrigin))
+            testFailed("Host did not get logged for user interaction.");
+        testRunner.dumpChildFramesAsText();
+        testRunner.setCloseRemainingWindowsWhenComplete(true);
+
+        console.log("About to call testRunner.statisticsUpdateCookiePartitioning().");
+        testRunner.statisticsUpdateCookiePartitioning(function () {
+            console.log("About to open the new window.");
+            newWin = window.open(thirdPartyOrigin + "/storageAccess/resources/set-cookie-and-report-back.html", "testWindow");
+        });
+    }
+</script>
 </body>
 </html>
\ No newline at end of file
index 97adba5..ab486c6 100644 (file)
@@ -1,3 +1,38 @@
+2018-06-25  John Wilander  <wilander@apple.com>
+
+        Resource Load Statistics: Make WebResourceLoadStatisticsStore::updateCookiePartitioningForDomains() wait for the network process before calling its callback
+        https://bugs.webkit.org/show_bug.cgi?id=186903
+        <rdar://problem/41350182>
+
+        Reviewed by Chris Dumez.
+
+        This patch stores the callback sent to
+        WebResourceLoadStatisticsStore::updateCookiePartitioningForDomains(),
+        sets up a context ID, and sends that ID to the network process when
+        asking it to update cookie partitioning and blocking. The network
+        process then tells the UI process when it's done, at which point the
+        callback is called.
+
+        This change is meant to address layout test flakiness.
+
+        * NetworkProcess/NetworkProcess.cpp:
+        (WebKit::NetworkProcess::updatePrevalentDomainsToPartitionOrBlockCookies):
+        * NetworkProcess/NetworkProcess.h:
+        * NetworkProcess/NetworkProcess.messages.in:
+        * UIProcess/Network/NetworkProcessProxy.cpp:
+        (WebKit::NetworkProcessProxy::updatePrevalentDomainsToPartitionOrBlockCookies):
+        (WebKit::NetworkProcessProxy::didUpdatePartitionOrBlockCookies):
+        * UIProcess/Network/NetworkProcessProxy.h:
+        * UIProcess/Network/NetworkProcessProxy.messages.in:
+        * UIProcess/WebResourceLoadStatisticsStore.cpp:
+        (WebKit::WebResourceLoadStatisticsStore::updateCookiePartitioning):
+        (WebKit::WebResourceLoadStatisticsStore::updateCookiePartitioningForDomains):
+        * UIProcess/WebResourceLoadStatisticsStore.h:
+        * UIProcess/WebsiteData/WebsiteDataStore.cpp:
+        (WebKit::WebsiteDataStore::updatePrevalentDomainsToPartitionOrBlockCookies):
+        (WebKit::WebsiteDataStore::enableResourceLoadStatisticsAndSetTestingCallback):
+        * UIProcess/WebsiteData/WebsiteDataStore.h:
+
 2018-06-25  Brent Fulgham  <bfulgham@apple.com>
 
         Allow access to APTDevice in iOS WebContent process
index 184d127..67bc9e1 100644 (file)
@@ -403,10 +403,11 @@ void NetworkProcess::writeBlobToFilePath(const WebCore::URL& url, const String&
 }
 
 #if HAVE(CFNETWORK_STORAGE_PARTITIONING)
-void NetworkProcess::updatePrevalentDomainsToPartitionOrBlockCookies(PAL::SessionID sessionID, const Vector<String>& domainsToPartition, const Vector<String>& domainsToBlock, const Vector<String>& domainsToNeitherPartitionNorBlock, bool shouldClearFirst)
+void NetworkProcess::updatePrevalentDomainsToPartitionOrBlockCookies(PAL::SessionID sessionID, const Vector<String>& domainsToPartition, const Vector<String>& domainsToBlock, const Vector<String>& domainsToNeitherPartitionNorBlock, bool shouldClearFirst, uint64_t callbackId)
 {
     if (auto* networkStorageSession = NetworkStorageSession::storageSession(sessionID))
         networkStorageSession->setPrevalentDomainsToPartitionOrBlockCookies(domainsToPartition, domainsToBlock, domainsToNeitherPartitionNorBlock, shouldClearFirst);
+    parentProcessConnection()->send(Messages::NetworkProcessProxy::DidUpdatePartitionOrBlockCookies(callbackId), 0);
 }
 
 void NetworkProcess::hasStorageAccessForFrame(PAL::SessionID sessionID, const String& resourceDomain, const String& firstPartyDomain, uint64_t frameID, uint64_t pageID, uint64_t contextId)
index be34931..97e2f5f 100644 (file)
@@ -134,7 +134,7 @@ public:
     void grantSandboxExtensionsToStorageProcessForBlobs(const Vector<String>& filenames, Function<void ()>&& completionHandler);
 
 #if HAVE(CFNETWORK_STORAGE_PARTITIONING)
-    void updatePrevalentDomainsToPartitionOrBlockCookies(PAL::SessionID, const Vector<String>& domainsToPartition, const Vector<String>& domainsToBlock, const Vector<String>& domainsToNeitherPartitionNorBlock, bool shouldClearFirst);
+    void updatePrevalentDomainsToPartitionOrBlockCookies(PAL::SessionID, const Vector<String>& domainsToPartition, const Vector<String>& domainsToBlock, const Vector<String>& domainsToNeitherPartitionNorBlock, bool shouldClearFirst, uint64_t callbackId);
     void hasStorageAccessForFrame(PAL::SessionID, const String& resourceDomain, const String& firstPartyDomain, uint64_t frameID, uint64_t pageID, uint64_t contextId);
     void getAllStorageAccessEntries(PAL::SessionID, uint64_t contextId);
     void grantStorageAccess(PAL::SessionID, const String& resourceDomain, const String& firstPartyDomain, std::optional<uint64_t> frameID, uint64_t pageID, uint64_t contextId);
index 8376bbc..4bfd6c2 100644 (file)
@@ -81,7 +81,7 @@ messages -> NetworkProcess LegacyReceiver {
     PreconnectTo(WebCore::URL url, enum WebCore::StoredCredentialsPolicy storedCredentialsPolicy);
 
 #if HAVE(CFNETWORK_STORAGE_PARTITIONING)
-    UpdatePrevalentDomainsToPartitionOrBlockCookies(PAL::SessionID sessionID, Vector<String> domainsToPartition, Vector<String> domainsToBlock, Vector<String> domainsToNeitherPartitionNorBlock, bool shouldClearFirst)
+    UpdatePrevalentDomainsToPartitionOrBlockCookies(PAL::SessionID sessionID, Vector<String> domainsToPartition, Vector<String> domainsToBlock, Vector<String> domainsToNeitherPartitionNorBlock, bool shouldClearFirst, uint64_t callbackId)
     HasStorageAccessForFrame(PAL::SessionID sessionID, String resourceDomain, String firstPartyDomain, uint64_t frameID, uint64_t pageID, uint64_t contextId)
     GetAllStorageAccessEntries(PAL::SessionID sessionID, uint64_t contextId)
     GrantStorageAccess(PAL::SessionID sessionID, String resourceDomain, String firstPartyDomain, std::optional<uint64_t> frameID, uint64_t pageID, uint64_t contextId)
index e7b2eec..117a551 100644 (file)
@@ -234,6 +234,12 @@ void NetworkProcessProxy::clearCallbackStates()
 
     while (!m_pendingDeleteWebsiteDataForOriginsCallbacks.isEmpty())
         m_pendingDeleteWebsiteDataForOriginsCallbacks.take(m_pendingDeleteWebsiteDataForOriginsCallbacks.begin()->key)();
+
+    while (!m_updatePartitionOrBlockCookiesCallbackMap.isEmpty())
+        m_updatePartitionOrBlockCookiesCallbackMap.take(m_updatePartitionOrBlockCookiesCallbackMap.begin()->key)();
+    
+    while (!m_storageAccessResponseCallbackMap.isEmpty())
+        m_storageAccessResponseCallbackMap.take(m_storageAccessResponseCallbackMap.begin()->key)(false);
 }
 
 void NetworkProcessProxy::didReceiveMessage(IPC::Connection& connection, IPC::Decoder& decoder)
@@ -431,6 +437,24 @@ void NetworkProcessProxy::canAuthenticateAgainstProtectionSpace(uint64_t loaderI
 #endif
 
 #if HAVE(CFNETWORK_STORAGE_PARTITIONING)
+void NetworkProcessProxy::updatePrevalentDomainsToPartitionOrBlockCookies(PAL::SessionID sessionID, const Vector<String>& domainsToPartition, const Vector<String>& domainsToBlock, const Vector<String>& domainsToNeitherPartitionNorBlock, ShouldClearFirst shouldClearFirst, CompletionHandler<void()>&& callback)
+{
+    if (!canSendMessage()) {
+        callback();
+        return;
+    }
+    
+    auto callbackId = generateCallbackID();
+    auto addResult = m_updatePartitionOrBlockCookiesCallbackMap.add(callbackId, WTFMove(callback));
+    ASSERT_UNUSED(addResult, addResult.isNewEntry);
+    send(Messages::NetworkProcess::UpdatePrevalentDomainsToPartitionOrBlockCookies(sessionID, domainsToPartition, domainsToBlock, domainsToNeitherPartitionNorBlock, shouldClearFirst == ShouldClearFirst::Yes, callbackId), 0);
+}
+
+void NetworkProcessProxy::didUpdatePartitionOrBlockCookies(uint64_t callbackId)
+{
+    m_updatePartitionOrBlockCookiesCallbackMap.take(callbackId)();
+}
+
 static uint64_t nextRequestStorageAccessContextId()
 {
     static uint64_t nextContextId = 0;
index 6cc521c..f707c69 100644 (file)
@@ -78,6 +78,7 @@ public:
     void deleteWebsiteDataForOrigins(PAL::SessionID, OptionSet<WebKit::WebsiteDataType>, const Vector<WebCore::SecurityOriginData>& origins, const Vector<String>& cookieHostNames, WTF::Function<void()>&& completionHandler);
 
 #if HAVE(CFNETWORK_STORAGE_PARTITIONING)
+    void updatePrevalentDomainsToPartitionOrBlockCookies(PAL::SessionID, const Vector<String>& domainsToPartition, const Vector<String>& domainsToBlock, const Vector<String>& domainsToNeitherPartitionNorBlock, ShouldClearFirst, CompletionHandler<void()>&&);
     void hasStorageAccessForFrame(PAL::SessionID, const String& resourceDomain, const String& firstPartyDomain, uint64_t frameID, uint64_t pageID, CompletionHandler<void(bool)>&& callback);
     void getAllStorageAccessEntries(PAL::SessionID, CompletionHandler<void(Vector<String>&& domains)>&&);
     void grantStorageAccess(PAL::SessionID, const String& resourceDomain, const String& firstPartyDomain, std::optional<uint64_t> frameID, uint64_t pageID, CompletionHandler<void(bool)>&& callback);
@@ -144,6 +145,7 @@ private:
     void canAuthenticateAgainstProtectionSpace(uint64_t loaderID, uint64_t pageID, uint64_t frameID, const WebCore::ProtectionSpace&);
 #endif
 #if HAVE(CFNETWORK_STORAGE_PARTITIONING)
+    void didUpdatePartitionOrBlockCookies(uint64_t callbackId);
     void storageAccessRequestResult(bool wasGranted, uint64_t contextId);
     void allStorageAccessEntriesResult(Vector<String>&& domains, uint64_t contextId);
 #endif
@@ -176,7 +178,8 @@ private:
     unsigned m_syncAllCookiesCounter { 0 };
 
     HashMap<uint64_t, CompletionHandler<void(bool success)>> m_writeBlobToFilePathCallbackMap;
-    HashMap<uint64_t, WTF::CompletionHandler<void(bool wasGranted)>> m_storageAccessResponseCallbackMap;
+    HashMap<uint64_t, CompletionHandler<void()>> m_updatePartitionOrBlockCookiesCallbackMap;
+    HashMap<uint64_t, CompletionHandler<void(bool wasGranted)>> m_storageAccessResponseCallbackMap;
     HashMap<uint64_t, CompletionHandler<void(Vector<String>&& domains)>> m_allStorageAccessEntriesCallbackMap;
 
 #if ENABLE(CONTENT_EXTENSIONS)
index 996a4a5..b1ba929 100644 (file)
@@ -47,6 +47,7 @@ messages -> NetworkProcessProxy LegacyReceiver {
     CanAuthenticateAgainstProtectionSpace(uint64_t loaderID, uint64_t pageID, uint64_t frameID, WebCore::ProtectionSpace protectionSpace)
 #endif
 #if HAVE(CFNETWORK_STORAGE_PARTITIONING)
+    DidUpdatePartitionOrBlockCookies(uint64_t callbackId)
     StorageAccessRequestResult(bool wasGranted, uint64_t contextId)
     AllStorageAccessEntriesResult(Vector<String> domains, uint64_t contextId)
 #endif
index 7db9c02..4c6e578 100644 (file)
@@ -1321,9 +1321,10 @@ void WebResourceLoadStatisticsStore::updateCookiePartitioning(CompletionHandler<
 #endif
 
     RunLoop::main().dispatch([this, protectedThis = makeRef(*this), domainsToPartition = crossThreadCopy(domainsToPartition), domainsToBlock = crossThreadCopy(domainsToBlock), domainsToNeitherPartitionNorBlock = crossThreadCopy(domainsToNeitherPartitionNorBlock), completionHandler = WTFMove(completionHandler)] () mutable {
-        m_updatePrevalentDomainsToPartitionOrBlockCookiesHandler(domainsToPartition, domainsToBlock, domainsToNeitherPartitionNorBlock, ShouldClearFirst::No);
-        m_statisticsQueue->dispatch([completionHandler = WTFMove(completionHandler)] () {
-            completionHandler();
+        m_updatePrevalentDomainsToPartitionOrBlockCookiesHandler(domainsToPartition, domainsToBlock, domainsToNeitherPartitionNorBlock, ShouldClearFirst::No, [this, protectedThis = makeRef(*this), completionHandler = WTFMove(completionHandler)]() mutable {
+            m_statisticsQueue->dispatch([completionHandler = WTFMove(completionHandler)]() mutable {
+                completionHandler();
+            });
         });
 #if !RELEASE_LOG_DISABLED
         RELEASE_LOG_INFO_IF(m_debugLoggingEnabled, ResourceLoadStatisticsDebug, "Done updating cookie partitioning and blocking.");
@@ -1339,10 +1340,6 @@ void WebResourceLoadStatisticsStore::updateCookiePartitioningForDomains(const Ve
         return;
     }
     
-    RunLoop::main().dispatch([this, shouldClearFirst, protectedThis = makeRef(*this), domainsToPartition = crossThreadCopy(domainsToPartition), domainsToBlock = crossThreadCopy(domainsToBlock), domainsToNeitherPartitionNorBlock = crossThreadCopy(domainsToNeitherPartitionNorBlock)] () {
-        m_updatePrevalentDomainsToPartitionOrBlockCookiesHandler(domainsToPartition, domainsToBlock, domainsToNeitherPartitionNorBlock, shouldClearFirst);
-    });
-
     if (shouldClearFirst == ShouldClearFirst::Yes)
         resetCookiePartitioningState();
     else {
@@ -1359,7 +1356,13 @@ void WebResourceLoadStatisticsStore::updateCookiePartitioningForDomains(const Ve
     for (auto& domain : domainsToBlock)
         ensureResourceStatisticsForPrimaryDomain(domain).isMarkedForCookieBlocking = true;
 
-    completionHandler();
+    RunLoop::main().dispatch([this, shouldClearFirst, protectedThis = makeRef(*this), domainsToPartition = crossThreadCopy(domainsToPartition), domainsToBlock = crossThreadCopy(domainsToBlock), domainsToNeitherPartitionNorBlock = crossThreadCopy(domainsToNeitherPartitionNorBlock), completionHandler = WTFMove(completionHandler)] () mutable {
+        m_updatePrevalentDomainsToPartitionOrBlockCookiesHandler(domainsToPartition, domainsToBlock, domainsToNeitherPartitionNorBlock, shouldClearFirst, [this, protectedThis = makeRef(*this), completionHandler = WTFMove(completionHandler)]() mutable {
+            m_statisticsQueue->dispatch([completionHandler = WTFMove(completionHandler)]() mutable {
+                completionHandler();
+            });
+        });
+    });
 }
 
 void WebResourceLoadStatisticsStore::clearPartitioningStateForDomains(const Vector<String>& domains, CompletionHandler<void()>&& completionHandler)
index d2ec740..96a529f 100644 (file)
@@ -68,12 +68,12 @@ enum class StorageAccessStatus {
 
 class WebResourceLoadStatisticsStore final : public IPC::Connection::WorkQueueMessageReceiver {
 public:
-    using UpdatePrevalentDomainsToPartitionOrBlockCookiesHandler = WTF::Function<void(const Vector<String>& domainsToPartition, const Vector<String>& domainsToBlock, const Vector<String>& domainsToNeitherPartitionNorBlock, ShouldClearFirst)>;
+    using UpdatePrevalentDomainsToPartitionOrBlockCookiesHandler = WTF::Function<void(const Vector<String>& domainsToPartition, const Vector<String>& domainsToBlock, const Vector<String>& domainsToNeitherPartitionNorBlock, ShouldClearFirst, CompletionHandler<void()>&&)>;
     using HasStorageAccessForFrameHandler = WTF::Function<void(const String& resourceDomain, const String& firstPartyDomain, uint64_t frameID, uint64_t pageID, WTF::Function<void(bool hasAccess)>&& callback)>;
     using GrantStorageAccessHandler = WTF::Function<void(const String& resourceDomain, const String& firstPartyDomain, std::optional<uint64_t> frameID, uint64_t pageID, WTF::Function<void(bool wasGranted)>&& callback)>;
     using RemoveAllStorageAccessHandler = WTF::Function<void()>;
     using RemovePrevalentDomainsHandler = WTF::Function<void (const Vector<String>&)>;
-    static Ref<WebResourceLoadStatisticsStore> create(const String& resourceLoadStatisticsDirectory, Function<void (const String&)>&& testingCallback, bool isEphemeral, UpdatePrevalentDomainsToPartitionOrBlockCookiesHandler&& updatePrevalentDomainsToPartitionOrBlockCookiesHandler = [](const WTF::Vector<String>&, const WTF::Vector<String>&, const WTF::Vector<String>&, ShouldClearFirst) { }, HasStorageAccessForFrameHandler&& hasStorageAccessForFrameHandler = [](const String&, const String&, uint64_t, uint64_t, WTF::Function<void(bool)>&&) { }, GrantStorageAccessHandler&& grantStorageAccessHandler = [](const String&, const String&, std::optional<uint64_t>, uint64_t, WTF::Function<void(bool)>&&) { }, RemoveAllStorageAccessHandler&& removeAllStorageAccessHandler = []() { }, RemovePrevalentDomainsHandler&& removeDomainsHandler = [] (const WTF::Vector<String>&) { })
+    static Ref<WebResourceLoadStatisticsStore> create(const String& resourceLoadStatisticsDirectory, Function<void (const String&)>&& testingCallback, bool isEphemeral, UpdatePrevalentDomainsToPartitionOrBlockCookiesHandler&& updatePrevalentDomainsToPartitionOrBlockCookiesHandler = [](const WTF::Vector<String>&, const WTF::Vector<String>&, const WTF::Vector<String>&, ShouldClearFirst, CompletionHandler<void()>&& callback = []() { }) { }, HasStorageAccessForFrameHandler&& hasStorageAccessForFrameHandler = [](const String&, const String&, uint64_t, uint64_t, WTF::Function<void(bool)>&&) { }, GrantStorageAccessHandler&& grantStorageAccessHandler = [](const String&, const String&, std::optional<uint64_t>, uint64_t, WTF::Function<void(bool)>&&) { }, RemoveAllStorageAccessHandler&& removeAllStorageAccessHandler = []() { }, RemovePrevalentDomainsHandler&& removeDomainsHandler = [] (const WTF::Vector<String>&) { })
     {
         return adoptRef(*new WebResourceLoadStatisticsStore(resourceLoadStatisticsDirectory, WTFMove(testingCallback), isEphemeral, WTFMove(updatePrevalentDomainsToPartitionOrBlockCookiesHandler), WTFMove(hasStorageAccessForFrameHandler), WTFMove(grantStorageAccessHandler), WTFMove(removeAllStorageAccessHandler), WTFMove(removeDomainsHandler)));
     }
index c3f3182..7d181b9 100644 (file)
@@ -47,6 +47,7 @@
 #include <WebCore/OriginLock.h>
 #include <WebCore/SecurityOrigin.h>
 #include <WebCore/SecurityOriginData.h>
+#include <wtf/CallbackAggregator.h>
 #include <wtf/CompletionHandler.h>
 #include <wtf/CrossThreadCopier.h>
 #include <wtf/ProcessPrivilege.h>
@@ -1205,10 +1206,14 @@ void WebsiteDataStore::removeDataForTopPrivatelyControlledDomains(OptionSet<Webs
 }
 
 #if HAVE(CFNETWORK_STORAGE_PARTITIONING)
-void WebsiteDataStore::updatePrevalentDomainsToPartitionOrBlockCookies(const Vector<String>& domainsToPartition, const Vector<String>& domainsToBlock, const Vector<String>& domainsToNeitherPartitionNorBlock, ShouldClearFirst shouldClearFirst)
+void WebsiteDataStore::updatePrevalentDomainsToPartitionOrBlockCookies(const Vector<String>& domainsToPartition, const Vector<String>& domainsToBlock, const Vector<String>& domainsToNeitherPartitionNorBlock, ShouldClearFirst shouldClearFirst, CompletionHandler<void()>&& completionHandler)
 {
-    for (auto& processPool : processPools())
-        processPool->sendToNetworkingProcess(Messages::NetworkProcess::UpdatePrevalentDomainsToPartitionOrBlockCookies(m_sessionID, domainsToPartition, domainsToBlock, domainsToNeitherPartitionNorBlock, shouldClearFirst == ShouldClearFirst::Yes));
+    auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
+
+    for (auto& processPool : processPools()) {
+        if (auto* process = processPool->networkProcess())
+            process->updatePrevalentDomainsToPartitionOrBlockCookies(m_sessionID, domainsToPartition, domainsToBlock, domainsToNeitherPartitionNorBlock, shouldClearFirst,  [callbackAggregator = callbackAggregator.copyRef()] { });
+    }
 }
 
 void WebsiteDataStore::hasStorageAccessForFrameHandler(const String& resourceDomain, const String& firstPartyDomain, uint64_t frameID, uint64_t pageID, WTF::CompletionHandler<void(bool hasAccess)>&& callback)
@@ -1472,15 +1477,15 @@ void WebsiteDataStore::enableResourceLoadStatisticsAndSetTestingCallback(Functio
     }
 
 #if HAVE(CFNETWORK_STORAGE_PARTITIONING)
-    m_resourceLoadStatistics = WebResourceLoadStatisticsStore::create(m_configuration.resourceLoadStatisticsDirectory, WTFMove(callback), m_sessionID.isEphemeral(), [weakThis = makeWeakPtr(*this)] (const Vector<String>& domainsToPartition, const Vector<String>& domainsToBlock, const Vector<String>& domainsToNeitherPartitionNorBlock, ShouldClearFirst shouldClearFirst) {
+    m_resourceLoadStatistics = WebResourceLoadStatisticsStore::create(m_configuration.resourceLoadStatisticsDirectory, WTFMove(callback), m_sessionID.isEphemeral(), [weakThis = makeWeakPtr(*this)] (const Vector<String>& domainsToPartition, const Vector<String>& domainsToBlock, const Vector<String>& domainsToNeitherPartitionNorBlock, ShouldClearFirst shouldClearFirst, CompletionHandler<void()>&& completionHandler) {
         if (weakThis)
-            weakThis->updatePrevalentDomainsToPartitionOrBlockCookies(domainsToPartition, domainsToBlock, domainsToNeitherPartitionNorBlock, shouldClearFirst);
-    }, [weakThis = makeWeakPtr(*this)] (const String& resourceDomain, const String& firstPartyDomain, uint64_t frameID, uint64_t pageID, WTF::CompletionHandler<void(bool hasAccess)>&& callback) {
+            weakThis->updatePrevalentDomainsToPartitionOrBlockCookies(domainsToPartition, domainsToBlock, domainsToNeitherPartitionNorBlock, shouldClearFirst, WTFMove(completionHandler));
+    }, [weakThis = makeWeakPtr(*this)] (const String& resourceDomain, const String& firstPartyDomain, uint64_t frameID, uint64_t pageID, CompletionHandler<void(bool hasAccess)>&& completionHandler) {
         if (weakThis)
-            weakThis->hasStorageAccessForFrameHandler(resourceDomain, firstPartyDomain, frameID, pageID, WTFMove(callback));
-    }, [weakThis = makeWeakPtr(*this)] (const String& resourceDomain, const String& firstPartyDomain, std::optional<uint64_t> frameID, uint64_t pageID, WTF::CompletionHandler<void(bool wasGranted)>&& callback) {
+            weakThis->hasStorageAccessForFrameHandler(resourceDomain, firstPartyDomain, frameID, pageID, WTFMove(completionHandler));
+    }, [weakThis = makeWeakPtr(*this)] (const String& resourceDomain, const String& firstPartyDomain, std::optional<uint64_t> frameID, uint64_t pageID, WTF::CompletionHandler<void(bool wasGranted)>&& completionHandler) {
         if (weakThis)
-            weakThis->grantStorageAccessHandler(resourceDomain, firstPartyDomain, frameID, pageID, WTFMove(callback));
+            weakThis->grantStorageAccessHandler(resourceDomain, firstPartyDomain, frameID, pageID, WTFMove(completionHandler));
     }, [weakThis = makeWeakPtr(*this)] () {
         if (weakThis)
             weakThis->removeAllStorageAccessHandler();
index 978c3d9..1a56a01 100644 (file)
@@ -130,13 +130,13 @@ public:
     void removeDataForTopPrivatelyControlledDomains(OptionSet<WebsiteDataType>, OptionSet<WebsiteDataFetchOption>, const Vector<String>& topPrivatelyControlledDomains, Function<void(HashSet<String>&&)>&& completionHandler);
 
 #if HAVE(CFNETWORK_STORAGE_PARTITIONING)
-    void updatePrevalentDomainsToPartitionOrBlockCookies(const Vector<String>& domainsToPartition, const Vector<String>& domainsToBlock, const Vector<String>& domainsToNeitherPartitionNorBlock, ShouldClearFirst);
-    void hasStorageAccessForFrameHandler(const String& resourceDomain, const String& firstPartyDomain, uint64_t frameID, uint64_t pageID, WTF::CompletionHandler<void(bool hasAccess)>&& callback);
+    void updatePrevalentDomainsToPartitionOrBlockCookies(const Vector<String>& domainsToPartition, const Vector<String>& domainsToBlock, const Vector<String>& domainsToNeitherPartitionNorBlock, ShouldClearFirst, CompletionHandler<void()>&&);
+    void hasStorageAccessForFrameHandler(const String& resourceDomain, const String& firstPartyDomain, uint64_t frameID, uint64_t pageID, CompletionHandler<void(bool hasAccess)>&&);
     void getAllStorageAccessEntries(CompletionHandler<void(Vector<String>&& domains)>&&);
-    void grantStorageAccessHandler(const String& resourceDomain, const String& firstPartyDomain, std::optional<uint64_t> frameID, uint64_t pageID, WTF::CompletionHandler<void(bool wasGranted)>&& callback);
+    void grantStorageAccessHandler(const String& resourceDomain, const String& firstPartyDomain, std::optional<uint64_t> frameID, uint64_t pageID, CompletionHandler<void(bool wasGranted)>&&);
     void removeAllStorageAccessHandler();
     void removePrevalentDomains(const Vector<String>& domains);
-    void hasStorageAccess(String&& subFrameHost, String&& topFrameHost, uint64_t frameID, uint64_t pageID, WTF::CompletionHandler<void (bool)>&& callback);
+    void hasStorageAccess(String&& subFrameHost, String&& topFrameHost, uint64_t frameID, uint64_t pageID, CompletionHandler<void(bool)>&&);
     void requestStorageAccess(String&& subFrameHost, String&& topFrameHost, uint64_t frameID, uint64_t pageID, bool promptEnabled, CompletionHandler<void(StorageAccessStatus)>&&);
     void grantStorageAccess(String&& subFrameHost, String&& topFrameHost, uint64_t frameID, uint64_t pageID, bool userWasPrompted, CompletionHandler<void(bool)>&&);
 #endif