Title: [225006] trunk
Revision
225006
Author
[email protected]
Date
2017-11-17 17:27:23 -0800 (Fri, 17 Nov 2017)

Log Message

Storage Access API: UI process should update network process about granted access
https://bugs.webkit.org/show_bug.cgi?id=176943
<rdar://problem/34440612>

Reviewed by Alex Christensen.

Source/WebCore:

Tests: http/tests/storageAccess/request-and-grant-storage-access-cross-origin-sandboxed-iframe-from-prevalent-domain-with-non-recent-user-interaction.html
       http/tests/storageAccess/request-and-grant-storage-access-cross-origin-sandboxed-iframe-from-prevalent-domain-with-recent-user-interaction.html

* platform/network/NetworkStorageSession.h:
* platform/network/cf/NetworkStorageSessionCFNet.cpp:
(WebCore::NetworkStorageSession::setStorageAccessAPIEnabled):
(WebCore::NetworkStorageSession::cookieStoragePartition const):
    Now also checks if the resource has been granted storage access
    under this partition and if so, does not return a partition.
(WebCore::NetworkStorageSession::setPrevalentDomainsToPartitionOrBlockCookies):
    Now clears storage access when it is told to clear first.
(WebCore::NetworkStorageSession::isStorageAccessGranted const):
(WebCore::NetworkStorageSession::setStorageAccessGranted):

Source/WebKit:

* NetworkProcess/NetworkProcess.cpp:
(WebKit::NetworkProcess::updateStorageAccessForPrevalentDomains):
    Updates storage access on the session.
* NetworkProcess/NetworkProcess.h:
* NetworkProcess/NetworkProcess.messages.in:
* NetworkProcess/NetworkProcessCreationParameters.cpp:
(WebKit::NetworkProcessCreationParameters::encode const):
(WebKit::NetworkProcessCreationParameters::decode):
* NetworkProcess/NetworkProcessCreationParameters.h:
* NetworkProcess/cocoa/NetworkProcessCocoa.mm:
(WebKit::NetworkProcess::platformInitializeNetworkProcessCocoa):
(WebKit::NetworkProcess::setStorageAccessAPIEnabled):
* UIProcess/API/C/WKCookieManager.cpp:
(WKCookieManagerSetStorageAccessAPIEnabled):
* UIProcess/API/C/WKCookieManager.h:
* UIProcess/API/C/WKWebsiteDataStoreRef.cpp:
(WKWebsiteDataStoreSetStatisticsHasHadNonRecentUserInteraction):
* UIProcess/API/C/WKWebsiteDataStoreRef.h:
* UIProcess/API/Cocoa/WKProcessPool.mm:
(-[WKProcessPool _isStorageAccessAPIEnabled]):
(-[WKProcessPool _setStorageAccessAPIEnabled:]):
* UIProcess/API/Cocoa/WKProcessPoolPrivate.h:
* UIProcess/API/Cocoa/WKWebsiteDataStore.mm:
(-[WKWebsiteDataStore _resourceLoadStatisticsSetHasHadNonRecentUserInteractionForHost:]):
    Test infrastructure.
* UIProcess/API/Cocoa/WKWebsiteDataStorePrivate.h:
* UIProcess/Cocoa/WebProcessPoolCocoa.mm:
(WebKit::WebProcessPool::platformInitializeNetworkProcess):
(WebKit::WebProcessPool::setStorageAccessAPIEnabled):
* UIProcess/Network/NetworkProcessProxy.cpp:
(WebKit::nextRequestStorageAccessContextId):
(WebKit::NetworkProcessProxy::updateStorageAccessForPrevalentDomains):
    Sends a message to the network process to update storage access.
(WebKit::NetworkProcessProxy::storageAccessRequestResult):
    Receives a message from the network process that storage access
    was updated.
* UIProcess/Network/NetworkProcessProxy.h:
* UIProcess/Network/NetworkProcessProxy.messages.in:
* UIProcess/WebCookieManagerProxy.cpp:
(WebKit::WebCookieManagerProxy::setStorageAccessAPIEnabled):
* UIProcess/WebCookieManagerProxy.h:
* UIProcess/WebProcessPool.h:
* UIProcess/WebResourceLoadStatisticsStore.cpp:
(WebKit::WebResourceLoadStatisticsStore::WebResourceLoadStatisticsStore):
(WebKit::WebResourceLoadStatisticsStore::requestStorageAccess):
(WebKit::WebResourceLoadStatisticsStore::logNonRecentUserInteraction):
    Test infrastructure.
(WebKit::WebResourceLoadStatisticsStore::updateCookiePartitioningForDomains):
    Now makes the API call even if the only operation is to clear first.
* UIProcess/WebResourceLoadStatisticsStore.h:
* UIProcess/WebsiteData/WebsiteDataStore.cpp:
(WebKit::WebsiteDataStore::updateStorageAccessForPrevalentDomainsHandler):
    Propagates the storage access directive to the network process proxy.
(WebKit::WebsiteDataStore::enableResourceLoadStatisticsAndSetTestingCallback):
* UIProcess/WebsiteData/WebsiteDataStore.h:

Tools:

This adds the TestRunner function setStatisticsHasHadNonRecentUserInteraction()
which enables testing of prevalent resources with user interaction outside the
24 hour window.

* WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl:
* WebKitTestRunner/InjectedBundle/TestRunner.cpp:
(WTR::TestRunner::setStorageAccessAPIEnabled):
(WTR::TestRunner::setStatisticsHasHadNonRecentUserInteraction):
* WebKitTestRunner/InjectedBundle/TestRunner.h:
* WebKitTestRunner/TestController.cpp:
(WTR::TestController::setStatisticsHasHadNonRecentUserInteraction):
* WebKitTestRunner/TestController.h:
* WebKitTestRunner/TestInvocation.cpp:
(WTR::TestInvocation::didReceiveSynchronousMessageFromInjectedBundle):
* WebKitTestRunner/cocoa/TestControllerCocoa.mm:
(WTR::initializeWebViewConfiguration):
(WTR::TestController::setStatisticsHasHadNonRecentUserInteraction):

LayoutTests:

* http/tests/storageAccess/request-and-grant-storage-access-cross-origin-sandboxed-iframe-from-prevalent-domain-with-non-recent-user-interaction-expected.txt: Added.
* http/tests/storageAccess/request-and-grant-storage-access-cross-origin-sandboxed-iframe-from-prevalent-domain-with-non-recent-user-interaction.html: Added.
* http/tests/storageAccess/request-and-grant-storage-access-cross-origin-sandboxed-iframe-from-prevalent-domain-with-recent-user-interaction-expected.txt: Added.
* http/tests/storageAccess/request-and-grant-storage-access-cross-origin-sandboxed-iframe-from-prevalent-domain-with-recent-user-interaction.html: Added.
* http/tests/storageAccess/request-and-grant-storage-access-cross-origin-sandboxed-iframe-from-prevalent-domain-with-user-interaction-expected.txt: Removed.
* http/tests/storageAccess/request-and-grant-storage-access-cross-origin-sandboxed-iframe-from-prevalent-domain-with-user-interaction.html: Removed.
    Renamed to make the recent and non-recent user interaction explicit.
* http/tests/storageAccess/resources/get-cookies.php: Added.
* http/tests/storageAccess/resources/set-cookie.php: Added.
* platform/mac-wk2/TestExpectations:
    Added the new tests as [ Pass ] for High Sierra and up.

Modified Paths

Added Paths

Removed Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (225005 => 225006)


--- trunk/LayoutTests/ChangeLog	2017-11-18 01:18:12 UTC (rev 225005)
+++ trunk/LayoutTests/ChangeLog	2017-11-18 01:27:23 UTC (rev 225006)
@@ -1,3 +1,23 @@
+2017-11-17  John Wilander  <[email protected]>
+
+        Storage Access API: UI process should update network process about granted access
+        https://bugs.webkit.org/show_bug.cgi?id=176943
+        <rdar://problem/34440612>
+
+        Reviewed by Alex Christensen.
+
+        * http/tests/storageAccess/request-and-grant-storage-access-cross-origin-sandboxed-iframe-from-prevalent-domain-with-non-recent-user-interaction-expected.txt: Added.
+        * http/tests/storageAccess/request-and-grant-storage-access-cross-origin-sandboxed-iframe-from-prevalent-domain-with-non-recent-user-interaction.html: Added.
+        * http/tests/storageAccess/request-and-grant-storage-access-cross-origin-sandboxed-iframe-from-prevalent-domain-with-recent-user-interaction-expected.txt: Added.
+        * http/tests/storageAccess/request-and-grant-storage-access-cross-origin-sandboxed-iframe-from-prevalent-domain-with-recent-user-interaction.html: Added.
+        * http/tests/storageAccess/request-and-grant-storage-access-cross-origin-sandboxed-iframe-from-prevalent-domain-with-user-interaction-expected.txt: Removed.
+        * http/tests/storageAccess/request-and-grant-storage-access-cross-origin-sandboxed-iframe-from-prevalent-domain-with-user-interaction.html: Removed.
+            Renamed to make the recent and non-recent user interaction explicit.
+        * http/tests/storageAccess/resources/get-cookies.php: Added.
+        * http/tests/storageAccess/resources/set-cookie.php: Added.
+        * platform/mac-wk2/TestExpectations:
+            Added the new tests as [ Pass ] for High Sierra and up.
+
 2017-11-17  Ryan Haddad  <[email protected]>
 
         Skip imported/w3c/web-platform-tests/service-workers/service-worker/getregistration.https.html on debug bots.

Added: trunk/LayoutTests/http/tests/storageAccess/request-and-grant-storage-access-cross-origin-sandboxed-iframe-from-prevalent-domain-with-non-recent-user-interaction-expected.txt (0 => 225006)


--- trunk/LayoutTests/http/tests/storageAccess/request-and-grant-storage-access-cross-origin-sandboxed-iframe-from-prevalent-domain-with-non-recent-user-interaction-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/http/tests/storageAccess/request-and-grant-storage-access-cross-origin-sandboxed-iframe-from-prevalent-domain-with-non-recent-user-interaction-expected.txt	2017-11-18 01:27:23 UTC (rev 225006)
@@ -0,0 +1,54 @@
+CONFIRM: Do you want to use your localhost ID on 127.0.0.1?
+Tests that cross-origin iframe storage access is granted if the iframe is sandboxed, has the allow token, the iframe origin is a prevalent resource, the iframe origin has had user interaction, and the user opts in.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS document.hasStorageAccess was granted.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+  
+
+--------
+Frame: 'theIframe'
+--------
+
+
+--------
+Frame: '<!--framePath //<!--frame1-->-->'
+--------
+Should receive first-party cookie.
+Received cookie named 'firstPartyCookie'.
+Did not receive cookie named 'partitionedCookie'.
+Client-side document.cookie: firstPartyCookie=value
+
+--------
+Frame: '<!--framePath //<!--frame2-->-->'
+--------
+Should not receive cookies.
+Did not receive cookie named 'firstPartyCookie'.
+Did not receive cookie named 'partitionedCookie'.
+Client-side document.cookie:
+
+--------
+Frame: '<!--framePath //<!--frame3-->-->'
+--------
+
+
+
+--------
+Frame: '<!--framePath //<!--frame4-->-->'
+--------
+Should receive partitioned cookie.
+Did not receive cookie named 'firstPartyCookie'.
+Received cookie named 'partitionedCookie'.
+Client-side document.cookie: partitionedCookie=value
+
+--------
+Frame: '<!--framePath //<!--frame5-->-->'
+--------
+Should receive first-party cookie.
+Received cookie named 'firstPartyCookie'.
+Did not receive cookie named 'partitionedCookie'.
+Client-side document.cookie: firstPartyCookie=value

Added: trunk/LayoutTests/http/tests/storageAccess/request-and-grant-storage-access-cross-origin-sandboxed-iframe-from-prevalent-domain-with-non-recent-user-interaction.html (0 => 225006)


--- trunk/LayoutTests/http/tests/storageAccess/request-and-grant-storage-access-cross-origin-sandboxed-iframe-from-prevalent-domain-with-non-recent-user-interaction.html	                        (rev 0)
+++ trunk/LayoutTests/http/tests/storageAccess/request-and-grant-storage-access-cross-origin-sandboxed-iframe-from-prevalent-domain-with-non-recent-user-interaction.html	2017-11-18 01:27:23 UTC (rev 225006)
@@ -0,0 +1,140 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <script src=""
+    <script src=""
+    <script>
+        description("Tests that cross-origin iframe storage access is granted if the iframe is sandboxed, has the allow token, the iframe origin is a prevalent resource, the iframe origin has had user interaction, and the user opts in.");
+        jsTestIsAsync = true;
+
+        const hostUnderTest = "localhost:8000";
+        const statisticsUrl = "http://" + hostUnderTest + "/temp";
+
+        const partitionHost = "127.0.0.1:8000";
+        const thirdPartyOrigin = "http://localhost:8000";
+        const resourcePath = "/storageAccess/resources";
+        const thirdPartyBaseUrl = thirdPartyOrigin + resourcePath;
+        const firstPartyCookieName = "firstPartyCookie";
+        const subPathToSetFirstPartyCookie = "/set-cookie.php?name=" + firstPartyCookieName + "&value=value";
+        const partitionedCookieName = "partitionedCookie";
+        const subPathToSetPartitionedCookie = "/set-cookie.php?name=" + partitionedCookieName + "&value=value";
+        const returnUrl = "http://" + partitionHost + "/storageAccess/request-and-grant-storage-access-cross-origin-sandboxed-iframe-from-prevalent-domain-with-non-recent-user-interaction.html";
+        const subPathToGetCookies = "/get-cookies.php?name1=" + firstPartyCookieName + "&name2=" + partitionedCookieName;
+
+        function setEnableFeature(enable) {
+            if (!enable)
+                testRunner.statisticsResetToConsistentState();
+            internals.setResourceLoadStatisticsEnabled(enable);
+            testRunner.setCookieStoragePartitioningEnabled(enable);
+            testRunner.setStorageAccessAPIEnabled(enable);
+        }
+
+        function openIframe(url, onLoadHandler) {
+            const element = document.createElement("iframe");
+            element.src = ""
+            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);
+            runTest();
+        }
+
+        function activateElement(elementId) {
+            var element = document.getElementById(elementId);
+            var centerX = element.offsetLeft + element.offsetWidth / 2;
+            var centerY = element.offsetTop + element.offsetHeight / 2;
+            UIHelper.activateAt(centerX, centerY).then(
+                function () {
+                    if (window.eventSender)
+                        eventSender.keyDown("escape");
+                    else {
+                        testFailed("No eventSender.");
+                        finishJSTest();
+                    }
+                },
+                function () {
+                    testFailed("Promise rejected.");
+                    finishJSTest();
+                }
+            );
+        }
+
+        function runTest() {
+            switch (document.location.hash) {
+                case "#step1":
+                    // Set localhost as prevalent.
+                    if (testRunner.isStatisticsPrevalentResource(statisticsUrl))
+                        testFailed("Host prematurely set as prevalent resource.");
+                    // Set first-party cookie for localhost.
+                    document.location.href = "" + subPathToSetFirstPartyCookie + "#" + returnUrl + "#step2";
+                    break;
+                case "#step2":
+                    document.location.hash = "step3";
+                    // Check that the first-party cookie does get sent for localhost under 127.0.0.1.
+                    openIframe(thirdPartyBaseUrl + subPathToGetCookies + "&message=Should receive first-party cookie.", runTest);
+                    break;
+                case "#step3":
+                    document.location.hash = "step4";
+                    testRunner.setStatisticsPrevalentResource(statisticsUrl, true);
+                    if (!testRunner.isStatisticsPrevalentResource(statisticsUrl))
+                        testFailed("Host did not get set as prevalent resource.");
+                    testRunner.setStatisticsHasHadNonRecentUserInteraction(statisticsUrl);
+                    if (!testRunner.isStatisticsHasHadUserInteraction(statisticsUrl))
+                        testFailed("Host did not get logged for user interaction.");
+                    testRunner.statisticsUpdateCookiePartitioning();
+                    // Check that the first-party cookie does not get sent for localhost under 127.0.0.1.
+                    openIframe(thirdPartyBaseUrl + subPathToGetCookies + "&message=Should not receive cookies.", runTest);
+                    break;
+                case "#step4":
+                    document.location.hash = "step5";
+                    // Set partitioned cookie for localhost.
+                    openIframe(thirdPartyBaseUrl + subPathToSetPartitionedCookie, runTest);
+                    break;
+                case "#step5":
+                    document.location.hash = "step6";
+                    // Check that the partitioned cookie does get sent for localhost under 127.0.0.1.
+                    openIframe(thirdPartyBaseUrl + subPathToGetCookies + "&message=Should receive partitioned cookie.", runTest);
+                    break;
+                case "#step6":
+                    document.location.hash = "step7";
+                    activateElement("theIframe");
+                    break;
+                case "#step7":
+                    document.location.hash = "step8";
+                    // Check that not the partitioned but the first-party cookie gets sent for localhost under 127.0.0.1.
+                    openIframe(thirdPartyBaseUrl + subPathToGetCookies + "&message=Should receive first-party cookie.", runTest);
+                    break;
+                case "#step8":
+                    setEnableFeature(false);
+                    finishJSTest();
+                    break;
+            }
+        }
+
+        if (document.location.hash === "") {
+            setEnableFeature(true);
+            if (testRunner.isStatisticsPrevalentResource(thirdPartyBaseUrl))
+                testFailed("Localhost was classified as prevalent resource before the test starts.");
+            // Make sure the network process is up-to-date.
+            testRunner.statisticsSetShouldPartitionCookiesForHost("localhost", false);
+            testRunner.dumpChildFramesAsText();
+            document.location.hash = "step1";
+        }
+
+        window.addEventListener("message", receiveMessage, false);
+    </script>
+</head>
+<body>
+    <iframe sandbox="allow-storage-access-by-user-activation allow-scripts allow-same-origin allow-modals" _onload_="runTest()" id="theIframe" src=""
+</body>
+</html>
\ No newline at end of file

Copied: trunk/LayoutTests/http/tests/storageAccess/request-and-grant-storage-access-cross-origin-sandboxed-iframe-from-prevalent-domain-with-recent-user-interaction-expected.txt (from rev 225005, trunk/LayoutTests/http/tests/storageAccess/request-and-grant-storage-access-cross-origin-sandboxed-iframe-from-prevalent-domain-with-user-interaction-expected.txt) (0 => 225006)


--- trunk/LayoutTests/http/tests/storageAccess/request-and-grant-storage-access-cross-origin-sandboxed-iframe-from-prevalent-domain-with-recent-user-interaction-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/http/tests/storageAccess/request-and-grant-storage-access-cross-origin-sandboxed-iframe-from-prevalent-domain-with-recent-user-interaction-expected.txt	2017-11-18 01:27:23 UTC (rev 225006)
@@ -0,0 +1,11 @@
+CONFIRM: Do you want to use your localhost ID on 127.0.0.1?
+Tests that cross-origin iframe storage access is granted if the iframe is sandboxed, has the allow token, the iframe origin is a prevalent resource, the iframe origin has had recent user interaction, and the user opts in.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS document.hasStorageAccess was granted.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Copied: trunk/LayoutTests/http/tests/storageAccess/request-and-grant-storage-access-cross-origin-sandboxed-iframe-from-prevalent-domain-with-recent-user-interaction.html (from rev 225005, trunk/LayoutTests/http/tests/storageAccess/request-and-grant-storage-access-cross-origin-sandboxed-iframe-from-prevalent-domain-with-user-interaction.html) (0 => 225006)


--- trunk/LayoutTests/http/tests/storageAccess/request-and-grant-storage-access-cross-origin-sandboxed-iframe-from-prevalent-domain-with-recent-user-interaction.html	                        (rev 0)
+++ trunk/LayoutTests/http/tests/storageAccess/request-and-grant-storage-access-cross-origin-sandboxed-iframe-from-prevalent-domain-with-recent-user-interaction.html	2017-11-18 01:27:23 UTC (rev 225006)
@@ -0,0 +1,60 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <script src=""
+    <script src=""
+    <script>
+        description("Tests that cross-origin iframe storage access is granted if the iframe is sandboxed, has the allow token, the iframe origin is a prevalent resource, the iframe origin has had recent user interaction, and the user opts in.");
+        jsTestIsAsync = true;
+
+        window.addEventListener("message", receiveMessage, false);
+
+        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);
+            finishJSTest();
+        }
+
+        function activateElement(elementId) {
+            var element = document.getElementById(elementId);
+            var centerX = element.offsetLeft + element.offsetWidth / 2;
+            var centerY = element.offsetTop + element.offsetHeight / 2;
+            UIHelper.activateAt(centerX, centerY).then(
+                function () {
+                    if (window.eventSender)
+                        eventSender.keyDown("escape");
+                    else {
+                        testFailed("No eventSender.");
+                        finishJSTest();
+                    }
+                },
+                function () {
+                    testFailed("Promise rejected.");
+                    finishJSTest();
+                }
+            );
+        }
+
+        function runTest() {
+            activateElement("theIframe");
+        }
+
+        const hostUnderTest = "localhost:8000";
+        const statisticsUrl = "http://" + hostUnderTest + "/temp";
+        testRunner.setStatisticsPrevalentResource(statisticsUrl, true);
+        if (!testRunner.isStatisticsPrevalentResource(statisticsUrl))
+            testFailed("Host did not get set as prevalent resource.");
+        testRunner.setStatisticsHasHadUserInteraction(statisticsUrl, true);
+        if (!testRunner.isStatisticsHasHadUserInteraction(statisticsUrl))
+            testFailed("Host did not get logged for user interaction.");
+    </script>
+</head>
+<body>
+    <iframe sandbox="allow-storage-access-by-user-activation allow-scripts allow-same-origin allow-modals" _onload_="runTest()" id="theIframe" src=""
+</body>
+</html>
\ No newline at end of file

Deleted: trunk/LayoutTests/http/tests/storageAccess/request-and-grant-storage-access-cross-origin-sandboxed-iframe-from-prevalent-domain-with-user-interaction-expected.txt (225005 => 225006)


--- trunk/LayoutTests/http/tests/storageAccess/request-and-grant-storage-access-cross-origin-sandboxed-iframe-from-prevalent-domain-with-user-interaction-expected.txt	2017-11-18 01:18:12 UTC (rev 225005)
+++ trunk/LayoutTests/http/tests/storageAccess/request-and-grant-storage-access-cross-origin-sandboxed-iframe-from-prevalent-domain-with-user-interaction-expected.txt	2017-11-18 01:27:23 UTC (rev 225006)
@@ -1,11 +0,0 @@
-CONFIRM: Do you want to use your localhost ID on 127.0.0.1?
-Tests that cross-origin iframe storage access is granted if the iframe is sandboxed, has the allow token, the iframe origin is a prevalent resource, the iframe origin has had user interaction, and the user opts in.
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-PASS document.hasStorageAccess was granted.
-PASS successfullyParsed is true
-
-TEST COMPLETE
-

Deleted: trunk/LayoutTests/http/tests/storageAccess/request-and-grant-storage-access-cross-origin-sandboxed-iframe-from-prevalent-domain-with-user-interaction.html (225005 => 225006)


--- trunk/LayoutTests/http/tests/storageAccess/request-and-grant-storage-access-cross-origin-sandboxed-iframe-from-prevalent-domain-with-user-interaction.html	2017-11-18 01:18:12 UTC (rev 225005)
+++ trunk/LayoutTests/http/tests/storageAccess/request-and-grant-storage-access-cross-origin-sandboxed-iframe-from-prevalent-domain-with-user-interaction.html	2017-11-18 01:27:23 UTC (rev 225006)
@@ -1,60 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-    <script src=""
-    <script src=""
-    <script>
-        description("Tests that cross-origin iframe storage access is granted if the iframe is sandboxed, has the allow token, the iframe origin is a prevalent resource, the iframe origin has had user interaction, and the user opts in.");
-        jsTestIsAsync = true;
-
-        window.addEventListener("message", receiveMessage, false);
-
-        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);
-            finishJSTest();
-        }
-
-        function activateElement(elementId) {
-            var element = document.getElementById(elementId);
-            var centerX = element.offsetLeft + element.offsetWidth / 2;
-            var centerY = element.offsetTop + element.offsetHeight / 2;
-            UIHelper.activateAt(centerX, centerY).then(
-                function () {
-                    if (window.eventSender)
-                        eventSender.keyDown("escape");
-                    else {
-                        testFailed("No eventSender.");
-                        finishJSTest();
-                    }
-                },
-                function () {
-                    testFailed("Promise rejected.");
-                    finishJSTest();
-                }
-            );
-        }
-
-        function runTest() {
-            activateElement("theIframe");
-        }
-
-        const hostUnderTest = "localhost:8000";
-        const statisticsUrl = "http://" + hostUnderTest + "/temp";
-        testRunner.setStatisticsPrevalentResource(statisticsUrl, true);
-        if (!testRunner.isStatisticsPrevalentResource(statisticsUrl))
-            testFailed("Host did not get set as prevalent resource.");
-        testRunner.setStatisticsHasHadUserInteraction(statisticsUrl, true);
-        if (!testRunner.isStatisticsHasHadUserInteraction(statisticsUrl))
-            testFailed("Host did not get logged for user interaction.");
-    </script>
-</head>
-<body>
-    <iframe sandbox="allow-storage-access-by-user-activation allow-scripts allow-same-origin allow-modals" _onload_="runTest()" id="theIframe" src=""
-</body>
-</html>
\ No newline at end of file

Added: trunk/LayoutTests/http/tests/storageAccess/resources/get-cookies.php (0 => 225006)


--- trunk/LayoutTests/http/tests/storageAccess/resources/get-cookies.php	                        (rev 0)
+++ trunk/LayoutTests/http/tests/storageAccess/resources/get-cookies.php	2017-11-18 01:27:23 UTC (rev 225006)
@@ -0,0 +1,24 @@
+<?php
+echo $_GET["message"] . "<br>";
+if(!isset($_COOKIE[$_GET["name1"]])) {
+    echo "Did not receive cookie named '" . $_GET["name1"] . "'.<br>";
+} else {
+    echo "Received cookie named '" . $_GET["name1"] . "'.<br>";
+}
+if(!isset($_COOKIE[$_GET["name2"]])) {
+    echo "Did not receive cookie named '" . $_GET["name2"] . "'.<br>";
+} else {
+    echo "Received cookie named '" . $_GET["name2"] . "'.<br>";
+}
+if(!empty($_GET["name3"])) {
+    if(!isset($_COOKIE[$_GET["name3"]])) {
+        echo "Did not receive cookie named '" . $_GET["name3"] . "'.<br>";
+    } else {
+        echo "Received cookie named '" . $_GET["name3"] . "'.<br>";
+    }
+}
+?>
+<p id="output"></p>
+<script>
+    document.getElementById("output").textContent = "Client-side document.cookie: " + document.cookie;
+</script>
\ No newline at end of file

Added: trunk/LayoutTests/http/tests/storageAccess/resources/set-cookie.php (0 => 225006)


--- trunk/LayoutTests/http/tests/storageAccess/resources/set-cookie.php	                        (rev 0)
+++ trunk/LayoutTests/http/tests/storageAccess/resources/set-cookie.php	2017-11-18 01:27:23 UTC (rev 225006)
@@ -0,0 +1,9 @@
+<?php
+setcookie($_GET["name"], $_GET["value"], (time()+60*60*24*30), "/");
+echo $_GET["message"] . "<br>";
+?>
+<script>
+if (document.location.hash) {
+    setTimeout("document.location.href = "" 10);
+}
+</script>
\ No newline at end of file

Modified: trunk/LayoutTests/platform/mac-wk2/TestExpectations (225005 => 225006)


--- trunk/LayoutTests/platform/mac-wk2/TestExpectations	2017-11-18 01:18:12 UTC (rev 225005)
+++ trunk/LayoutTests/platform/mac-wk2/TestExpectations	2017-11-18 01:27:23 UTC (rev 225006)
@@ -755,7 +755,8 @@
 http/tests/storageAccess/request-storage-access-same-origin-sandboxed-iframe-without-allow-token.html [ Pass ]
 http/tests/storageAccess/request-storage-access-same-origin-sandboxed-iframe.html [ Pass ]
 http/tests/storageAccess/request-and-grant-storage-access-cross-origin-sandboxed-nested-iframe.html [ Pass ]
-http/tests/storageAccess/request-and-grant-storage-access-cross-origin-sandboxed-iframe-from-prevalent-domain-with-user-interaction.html [ Pass ]
+http/tests/storageAccess/request-and-grant-storage-access-cross-origin-sandboxed-iframe-from-prevalent-domain-with-recent-user-interaction.html [ Pass ]
+[ HighSierra+ ] http/tests/storageAccess/request-and-grant-storage-access-cross-origin-sandboxed-iframe-from-prevalent-domain-with-non-recent-user-interaction.html [ Pass ]
 http/tests/storageAccess/request-and-grant-storage-access-cross-origin-sandboxed-iframe-from-prevalent-domain-without-user-interaction.html [ Pass ]
 http/tests/storageAccess/request-storage-access-top-frame.html [ Pass ]
 

Modified: trunk/Source/WebCore/ChangeLog (225005 => 225006)


--- trunk/Source/WebCore/ChangeLog	2017-11-18 01:18:12 UTC (rev 225005)
+++ trunk/Source/WebCore/ChangeLog	2017-11-18 01:27:23 UTC (rev 225006)
@@ -1,3 +1,25 @@
+2017-11-17  John Wilander  <[email protected]>
+
+        Storage Access API: UI process should update network process about granted access
+        https://bugs.webkit.org/show_bug.cgi?id=176943
+        <rdar://problem/34440612>
+
+        Reviewed by Alex Christensen.
+
+        Tests: http/tests/storageAccess/request-and-grant-storage-access-cross-origin-sandboxed-iframe-from-prevalent-domain-with-non-recent-user-interaction.html
+               http/tests/storageAccess/request-and-grant-storage-access-cross-origin-sandboxed-iframe-from-prevalent-domain-with-recent-user-interaction.html
+
+        * platform/network/NetworkStorageSession.h:
+        * platform/network/cf/NetworkStorageSessionCFNet.cpp:
+        (WebCore::NetworkStorageSession::setStorageAccessAPIEnabled):
+        (WebCore::NetworkStorageSession::cookieStoragePartition const):
+            Now also checks if the resource has been granted storage access
+            under this partition and if so, does not return a partition.
+        (WebCore::NetworkStorageSession::setPrevalentDomainsToPartitionOrBlockCookies):
+            Now clears storage access when it is told to clear first.
+        (WebCore::NetworkStorageSession::isStorageAccessGranted const):
+        (WebCore::NetworkStorageSession::setStorageAccessGranted):
+
 2017-11-17  Simon Fraser  <[email protected]>
 
         Inadvertently swapped m_baseFrequencyX and m_baseFrequencyY in the previous commit.

Modified: trunk/Source/WebCore/platform/network/NetworkStorageSession.h (225005 => 225006)


--- trunk/Source/WebCore/platform/network/NetworkStorageSession.h	2017-11-18 01:18:12 UTC (rev 225005)
+++ trunk/Source/WebCore/platform/network/NetworkStorageSession.h	2017-11-18 01:27:23 UTC (rev 225006)
@@ -28,6 +28,7 @@
 #include "CredentialStorage.h"
 #include <pal/SessionID.h>
 #include <wtf/Function.h>
+#include <wtf/HashMap.h>
 #include <wtf/HashSet.h>
 #include <wtf/text/WTFString.h>
 
@@ -89,6 +90,7 @@
     CFURLStorageSessionRef platformSession() { return m_platformSession.get(); }
     WEBCORE_EXPORT RetainPtr<CFHTTPCookieStorageRef> cookieStorage() const;
     WEBCORE_EXPORT static void setCookieStoragePartitioningEnabled(bool);
+    WEBCORE_EXPORT static void setStorageAccessAPIEnabled(bool);
 #if HAVE(CFNETWORK_STORAGE_PARTITIONING)
     WEBCORE_EXPORT String cookieStoragePartition(const ResourceRequest&) const;
     WEBCORE_EXPORT bool shouldBlockCookies(const ResourceRequest&) const;
@@ -96,6 +98,8 @@
     String cookieStoragePartition(const URL& firstPartyForCookies, const URL& resource) const;
     WEBCORE_EXPORT void setPrevalentDomainsToPartitionOrBlockCookies(const Vector<String>& domainsToPartition, const Vector<String>& domainsToBlock, const Vector<String>& domainsToNeitherPartitionNorBlock, bool clearFirst);
     WEBCORE_EXPORT void removePrevalentDomains(const Vector<String>& domains);
+    WEBCORE_EXPORT bool isStorageAccessGranted(const String& resourceDomain, const String& firstPartyDomain) const;
+    WEBCORE_EXPORT void setStorageAccessGranted(const String& resourceDomain, const String& firstPartyDomain, bool value);
 #endif
 #elif USE(SOUP)
     NetworkStorageSession(PAL::SessionID, std::unique_ptr<SoupNetworkSession>&&);
@@ -154,6 +158,7 @@
     bool shouldBlockThirdPartyCookies(const String& topPrivatelyControlledDomain) const;
     HashSet<String> m_topPrivatelyControlledDomainsToPartition;
     HashSet<String> m_topPrivatelyControlledDomainsToBlock;
+    HashMap<String, HashSet<String>> m_domainsGrantedStorageAccess;
 #endif
 
 #if PLATFORM(COCOA)

Modified: trunk/Source/WebCore/platform/network/cf/NetworkStorageSessionCFNet.cpp (225005 => 225006)


--- trunk/Source/WebCore/platform/network/cf/NetworkStorageSessionCFNet.cpp	2017-11-18 01:18:12 UTC (rev 225005)
+++ trunk/Source/WebCore/platform/network/cf/NetworkStorageSessionCFNet.cpp	2017-11-18 01:27:23 UTC (rev 225006)
@@ -40,6 +40,7 @@
 namespace WebCore {
 
 static bool cookieStoragePartitioningEnabled;
+static bool storageAccessAPIEnabled;
 
 static RetainPtr<CFURLStorageSessionRef> createCFStorageSessionForIdentifier(CFStringRef identifier)
 {
@@ -158,6 +159,11 @@
     cookieStoragePartitioningEnabled = enabled;
 }
 
+void NetworkStorageSession::setStorageAccessAPIEnabled(bool enabled)
+{
+    storageAccessAPIEnabled = enabled;
+}
+
 #if HAVE(CFNETWORK_STORAGE_PARTITIONING)
 
 String NetworkStorageSession::cookieStoragePartition(const ResourceRequest& request) const
@@ -190,6 +196,9 @@
     if (firstPartyDomain == resourceDomain)
         return emptyString();
 
+    if (storageAccessAPIEnabled && isStorageAccessGranted(resourceDomain, firstPartyDomain))
+        return emptyString();
+
     return firstPartyDomain;
 }
 
@@ -241,6 +250,7 @@
     if (clearFirst) {
         m_topPrivatelyControlledDomainsToPartition.clear();
         m_topPrivatelyControlledDomainsToBlock.clear();
+        m_domainsGrantedStorageAccess.clear();
     }
 
     for (auto& domain : domainsToPartition) {
@@ -273,6 +283,32 @@
     }
 }
 
+bool NetworkStorageSession::isStorageAccessGranted(const String& resourceDomain, const String& firstPartyDomain) const
+{
+    auto it = m_domainsGrantedStorageAccess.find(firstPartyDomain);
+    if (it == m_domainsGrantedStorageAccess.end())
+        return false;
+
+    return it->value.contains(resourceDomain);
+}
+
+void NetworkStorageSession::setStorageAccessGranted(const String& resourceDomain, const String& firstPartyDomain, bool value)
+{
+    auto iterator = m_domainsGrantedStorageAccess.find(firstPartyDomain);
+    if (value) {
+        if (iterator == m_domainsGrantedStorageAccess.end())
+            auto accessEntry = m_domainsGrantedStorageAccess.add(firstPartyDomain, HashSet<String>({ resourceDomain }));
+        else
+            iterator->value.add(resourceDomain);
+    } else {
+        if (iterator == m_domainsGrantedStorageAccess.end())
+            return;
+        iterator->value.remove(resourceDomain);
+        if (iterator->value.isEmpty())
+            m_domainsGrantedStorageAccess.remove(firstPartyDomain);
+    }
+}
+
 #endif // HAVE(CFNETWORK_STORAGE_PARTITIONING)
 
 #if !PLATFORM(COCOA)

Modified: trunk/Source/WebKit/ChangeLog (225005 => 225006)


--- trunk/Source/WebKit/ChangeLog	2017-11-18 01:18:12 UTC (rev 225005)
+++ trunk/Source/WebKit/ChangeLog	2017-11-18 01:27:23 UTC (rev 225006)
@@ -1,3 +1,67 @@
+2017-11-17  John Wilander  <[email protected]>
+
+        Storage Access API: UI process should update network process about granted access
+        https://bugs.webkit.org/show_bug.cgi?id=176943
+        <rdar://problem/34440612>
+
+        Reviewed by Alex Christensen.
+
+        * NetworkProcess/NetworkProcess.cpp:
+        (WebKit::NetworkProcess::updateStorageAccessForPrevalentDomains):
+            Updates storage access on the session.
+        * NetworkProcess/NetworkProcess.h:
+        * NetworkProcess/NetworkProcess.messages.in:
+        * NetworkProcess/NetworkProcessCreationParameters.cpp:
+        (WebKit::NetworkProcessCreationParameters::encode const):
+        (WebKit::NetworkProcessCreationParameters::decode):
+        * NetworkProcess/NetworkProcessCreationParameters.h:
+        * NetworkProcess/cocoa/NetworkProcessCocoa.mm:
+        (WebKit::NetworkProcess::platformInitializeNetworkProcessCocoa):
+        (WebKit::NetworkProcess::setStorageAccessAPIEnabled):
+        * UIProcess/API/C/WKCookieManager.cpp:
+        (WKCookieManagerSetStorageAccessAPIEnabled):
+        * UIProcess/API/C/WKCookieManager.h:
+        * UIProcess/API/C/WKWebsiteDataStoreRef.cpp:
+        (WKWebsiteDataStoreSetStatisticsHasHadNonRecentUserInteraction):
+        * UIProcess/API/C/WKWebsiteDataStoreRef.h:
+        * UIProcess/API/Cocoa/WKProcessPool.mm:
+        (-[WKProcessPool _isStorageAccessAPIEnabled]):
+        (-[WKProcessPool _setStorageAccessAPIEnabled:]):
+        * UIProcess/API/Cocoa/WKProcessPoolPrivate.h:
+        * UIProcess/API/Cocoa/WKWebsiteDataStore.mm:
+        (-[WKWebsiteDataStore _resourceLoadStatisticsSetHasHadNonRecentUserInteractionForHost:]):
+            Test infrastructure.
+        * UIProcess/API/Cocoa/WKWebsiteDataStorePrivate.h:
+        * UIProcess/Cocoa/WebProcessPoolCocoa.mm:
+        (WebKit::WebProcessPool::platformInitializeNetworkProcess):
+        (WebKit::WebProcessPool::setStorageAccessAPIEnabled):
+        * UIProcess/Network/NetworkProcessProxy.cpp:
+        (WebKit::nextRequestStorageAccessContextId):
+        (WebKit::NetworkProcessProxy::updateStorageAccessForPrevalentDomains):
+            Sends a message to the network process to update storage access.
+        (WebKit::NetworkProcessProxy::storageAccessRequestResult):
+            Receives a message from the network process that storage access
+            was updated.
+        * UIProcess/Network/NetworkProcessProxy.h:
+        * UIProcess/Network/NetworkProcessProxy.messages.in:
+        * UIProcess/WebCookieManagerProxy.cpp:
+        (WebKit::WebCookieManagerProxy::setStorageAccessAPIEnabled):
+        * UIProcess/WebCookieManagerProxy.h:
+        * UIProcess/WebProcessPool.h:
+        * UIProcess/WebResourceLoadStatisticsStore.cpp:
+        (WebKit::WebResourceLoadStatisticsStore::WebResourceLoadStatisticsStore):
+        (WebKit::WebResourceLoadStatisticsStore::requestStorageAccess):
+        (WebKit::WebResourceLoadStatisticsStore::logNonRecentUserInteraction):
+            Test infrastructure.
+        (WebKit::WebResourceLoadStatisticsStore::updateCookiePartitioningForDomains):
+            Now makes the API call even if the only operation is to clear first.
+        * UIProcess/WebResourceLoadStatisticsStore.h:
+        * UIProcess/WebsiteData/WebsiteDataStore.cpp:
+        (WebKit::WebsiteDataStore::updateStorageAccessForPrevalentDomainsHandler):
+            Propagates the storage access directive to the network process proxy.
+        (WebKit::WebsiteDataStore::enableResourceLoadStatisticsAndSetTestingCallback):
+        * UIProcess/WebsiteData/WebsiteDataStore.h:
+
 2017-11-16  Yousuke Kimoto  <[email protected]>
 
         [WinCairo] Add network (curl) files for wincairo webkit

Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp (225005 => 225006)


--- trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp	2017-11-18 01:18:12 UTC (rev 225005)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp	2017-11-18 01:27:23 UTC (rev 225006)
@@ -329,6 +329,19 @@
         networkStorageSession->setPrevalentDomainsToPartitionOrBlockCookies(domainsToPartition, domainsToBlock, domainsToNeitherPartitionNorBlock, shouldClearFirst);
 }
 
+void NetworkProcess::updateStorageAccessForPrevalentDomains(PAL::SessionID sessionID, const String& resourceDomain, const String& firstPartyDomain, bool shouldGrantStorage, uint64_t contextId)
+{
+    bool isStorageGranted = false;
+    if (auto* networkStorageSession = NetworkStorageSession::storageSession(sessionID)) {
+        networkStorageSession->setStorageAccessGranted(resourceDomain, firstPartyDomain, shouldGrantStorage);
+        ASSERT(networkStorageSession->isStorageAccessGranted(resourceDomain, firstPartyDomain) == shouldGrantStorage);
+        isStorageGranted = shouldGrantStorage;
+    } else
+        ASSERT_NOT_REACHED();
+
+    parentProcessConnection()->send(Messages::NetworkProcessProxy::StorageAccessRequestResult(isStorageGranted, contextId), 0);
+}
+
 void NetworkProcess::removePrevalentDomains(PAL::SessionID sessionID, const Vector<String>& domains)
 {
     if (auto* networkStorageSession = NetworkStorageSession::storageSession(sessionID))

Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcess.h (225005 => 225006)


--- trunk/Source/WebKit/NetworkProcess/NetworkProcess.h	2017-11-18 01:18:12 UTC (rev 225005)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcess.h	2017-11-18 01:27:23 UTC (rev 225006)
@@ -138,6 +138,7 @@
 
 #if HAVE(CFNETWORK_STORAGE_PARTITIONING)
     void updatePrevalentDomainsToPartitionOrBlockCookies(PAL::SessionID, const Vector<String>& domainsToPartition, const Vector<String>& domainsToBlock, const Vector<String>& domainsToNeitherPartitionNorBlock, bool shouldClearFirst);
+    void updateStorageAccessForPrevalentDomains(PAL::SessionID, const String& resourceDomain, const String& firstPartyDomain, bool value, uint64_t contextId);
     void removePrevalentDomains(PAL::SessionID, const Vector<String>& domains);
 #endif
 
@@ -256,6 +257,7 @@
 #if PLATFORM(COCOA)
     void platformInitializeNetworkProcessCocoa(const NetworkProcessCreationParameters&);
     void setCookieStoragePartitioningEnabled(bool);
+    void setStorageAccessAPIEnabled(bool);
 
     // FIXME: We'd like to be able to do this without the #ifdef, but WorkQueue + BinarySemaphore isn't good enough since
     // multiple requests to clear the cache can come in before previous requests complete, and we need to wait for all of them.

Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcess.messages.in (225005 => 225006)


--- trunk/Source/WebKit/NetworkProcess/NetworkProcess.messages.in	2017-11-18 01:18:12 UTC (rev 225005)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcess.messages.in	2017-11-18 01:27:23 UTC (rev 225006)
@@ -58,6 +58,7 @@
 #if PLATFORM(COCOA)
     SetQOS(int latencyQOS, int throughputQOS)
     SetCookieStoragePartitioningEnabled(bool enabled)
+    SetStorageAccessAPIEnabled(bool enabled)
 #endif
     SetAllowsAnySSLCertificateForWebSocket(bool enabled) -> ()
 
@@ -82,6 +83,7 @@
 
 #if HAVE(CFNETWORK_STORAGE_PARTITIONING)
     UpdatePrevalentDomainsToPartitionOrBlockCookies(PAL::SessionID sessionID, Vector<String> domainsToPartition, Vector<String> domainsToBlock, Vector<String> domainsToNeitherPartitionNorBlock, bool shouldClearFirst)
+    UpdateStorageAccessForPrevalentDomains(PAL::SessionID sessionID, String resourceDomain, String firstPartyDomain, bool shouldGrantAccess, uint64_t contextId)
     RemovePrevalentDomains(PAL::SessionID sessionID, Vector<String> domainsWithInteraction);
 #endif
 }

Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcessCreationParameters.cpp (225005 => 225006)


--- trunk/Source/WebKit/NetworkProcess/NetworkProcessCreationParameters.cpp	2017-11-18 01:18:12 UTC (rev 225005)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcessCreationParameters.cpp	2017-11-18 01:27:23 UTC (rev 225006)
@@ -85,6 +85,7 @@
     IPC::encode(encoder, networkATSContext.get());
 #endif
     encoder << cookieStoragePartitioningEnabled;
+    encoder << storageAccessAPIEnabled;
 #endif
 #if USE(SOUP)
     encoder << cookiePersistentStoragePath;
@@ -186,6 +187,8 @@
 #endif
     if (!decoder.decode(result.cookieStoragePartitioningEnabled))
         return false;
+    if (!decoder.decode(result.storageAccessAPIEnabled))
+        return false;
 #endif
 
 #if USE(SOUP)

Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcessCreationParameters.h (225005 => 225006)


--- trunk/Source/WebKit/NetworkProcess/NetworkProcessCreationParameters.h	2017-11-18 01:18:12 UTC (rev 225005)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcessCreationParameters.h	2017-11-18 01:27:23 UTC (rev 225006)
@@ -98,6 +98,7 @@
     RetainPtr<CFDataRef> networkATSContext;
 #endif
     bool cookieStoragePartitioningEnabled;
+    bool storageAccessAPIEnabled;
 #endif
 
 #if USE(SOUP)

Modified: trunk/Source/WebKit/NetworkProcess/cocoa/NetworkProcessCocoa.mm (225005 => 225006)


--- trunk/Source/WebKit/NetworkProcess/cocoa/NetworkProcessCocoa.mm	2017-11-18 01:18:12 UTC (rev 225005)
+++ trunk/Source/WebKit/NetworkProcess/cocoa/NetworkProcessCocoa.mm	2017-11-18 01:27:23 UTC (rev 225006)
@@ -96,6 +96,7 @@
 #endif
 
     WebCore::NetworkStorageSession::setCookieStoragePartitioningEnabled(parameters.cookieStoragePartitioningEnabled);
+    WebCore::NetworkStorageSession::setStorageAccessAPIEnabled(parameters.storageAccessAPIEnabled);
 
     // FIXME: Most of what this function does for cache size gets immediately overridden by setCacheModel().
     // - memory cache size passed from UI process is always ignored;
@@ -211,6 +212,11 @@
     WebCore::NetworkStorageSession::setCookieStoragePartitioningEnabled(enabled);
 }
 
+void NetworkProcess::setStorageAccessAPIEnabled(bool enabled)
+{
+    WebCore::NetworkStorageSession::setStorageAccessAPIEnabled(enabled);
+}
+
 void NetworkProcess::syncAllCookies()
 {
 #pragma clang diagnostic push

Modified: trunk/Source/WebKit/UIProcess/API/C/WKCookieManager.cpp (225005 => 225006)


--- trunk/Source/WebKit/UIProcess/API/C/WKCookieManager.cpp	2017-11-18 01:18:12 UTC (rev 225005)
+++ trunk/Source/WebKit/UIProcess/API/C/WKCookieManager.cpp	2017-11-18 01:27:23 UTC (rev 225006)
@@ -80,6 +80,11 @@
     toImpl(cookieManager)->setCookieStoragePartitioningEnabled(enabled);
 }
 
+void WKCookieManagerSetStorageAccessAPIEnabled(WKCookieManagerRef cookieManager, bool enabled)
+{
+    toImpl(cookieManager)->setStorageAccessAPIEnabled(enabled);
+}
+
 void WKCookieManagerStartObservingCookieChanges(WKCookieManagerRef cookieManager)
 {
     toImpl(cookieManager)->startObservingCookieChanges(PAL::SessionID::defaultSessionID());

Modified: trunk/Source/WebKit/UIProcess/API/C/WKCookieManager.h (225005 => 225006)


--- trunk/Source/WebKit/UIProcess/API/C/WKCookieManager.h	2017-11-18 01:18:12 UTC (rev 225005)
+++ trunk/Source/WebKit/UIProcess/API/C/WKCookieManager.h	2017-11-18 01:27:23 UTC (rev 225006)
@@ -73,6 +73,7 @@
 WK_EXPORT void WKCookieManagerGetHTTPCookieAcceptPolicy(WKCookieManagerRef cookieManager, void* context, WKCookieManagerGetHTTPCookieAcceptPolicyFunction callback);
 
 WK_EXPORT void WKCookieManagerSetCookieStoragePartitioningEnabled(WKCookieManagerRef cookieManager, bool enabled);
+WK_EXPORT void WKCookieManagerSetStorageAccessAPIEnabled(WKCookieManagerRef cookieManager, bool enabled);
 
 WK_EXPORT void WKCookieManagerStartObservingCookieChanges(WKCookieManagerRef cookieManager);
 WK_EXPORT void WKCookieManagerStopObservingCookieChanges(WKCookieManagerRef cookieManager);

Modified: trunk/Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreRef.cpp (225005 => 225006)


--- trunk/Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreRef.cpp	2017-11-18 01:18:12 UTC (rev 225005)
+++ trunk/Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreRef.cpp	2017-11-18 01:27:23 UTC (rev 225006)
@@ -109,6 +109,15 @@
         store->clearUserInteraction(WebCore::URL(WebCore::URL(), WebKit::toImpl(host)->string()));
 }
 
+void WKWebsiteDataStoreSetStatisticsHasHadNonRecentUserInteraction(WKWebsiteDataStoreRef dataStoreRef, WKStringRef host)
+{
+    auto* store = WebKit::toImpl(dataStoreRef)->websiteDataStore().resourceLoadStatistics();
+    if (!store)
+        return;
+    
+    store->logNonRecentUserInteraction(WebCore::URL(WebCore::URL(), WebKit::toImpl(host)->string()));
+}
+
 void WKWebsiteDataStoreIsStatisticsHasHadUserInteraction(WKWebsiteDataStoreRef dataStoreRef, WKStringRef host, void* context, WKWebsiteDataStoreIsStatisticsHasHadUserInteractionFunction callback)
 {
     auto* store = WebKit::toImpl(dataStoreRef)->websiteDataStore().resourceLoadStatistics();

Modified: trunk/Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreRef.h (225005 => 225006)


--- trunk/Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreRef.h	2017-11-18 01:18:12 UTC (rev 225005)
+++ trunk/Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreRef.h	2017-11-18 01:27:23 UTC (rev 225006)
@@ -44,6 +44,7 @@
 typedef void (*WKWebsiteDataStoreIsStatisticsPrevalentResourceFunction)(bool isPrevalentResource, void* functionContext);
 WK_EXPORT void WKWebsiteDataStoreIsStatisticsPrevalentResource(WKWebsiteDataStoreRef dataStoreRef, WKStringRef host, void* context, WKWebsiteDataStoreIsStatisticsPrevalentResourceFunction callback);
 WK_EXPORT void WKWebsiteDataStoreSetStatisticsHasHadUserInteraction(WKWebsiteDataStoreRef dataStoreRef, WKStringRef host, bool value);
+WK_EXPORT void WKWebsiteDataStoreSetStatisticsHasHadNonRecentUserInteraction(WKWebsiteDataStoreRef dataStoreRef, WKStringRef host);
 typedef void (*WKWebsiteDataStoreIsStatisticsHasHadUserInteractionFunction)(bool hasHadUserInteraction, void* functionContext);
 WK_EXPORT void WKWebsiteDataStoreIsStatisticsHasHadUserInteraction(WKWebsiteDataStoreRef dataStoreRef, WKStringRef host, void* context, WKWebsiteDataStoreIsStatisticsHasHadUserInteractionFunction callback);
 WK_EXPORT void WKWebsiteDataStoreSetStatisticsGrandfathered(WKWebsiteDataStoreRef dataStoreRef, WKStringRef host, bool value);

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKProcessPool.mm (225005 => 225006)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKProcessPool.mm	2017-11-18 01:18:12 UTC (rev 225005)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKProcessPool.mm	2017-11-18 01:27:23 UTC (rev 225006)
@@ -446,6 +446,16 @@
     _processPool->setCookieStoragePartitioningEnabled(enabled);
 }
 
+- (BOOL)_isStorageAccessAPIEnabled
+{
+    return _processPool->storageAccessAPIEnabled();
+}
+
+- (void)_setStorageAccessAPIEnabled:(BOOL)enabled
+{
+    _processPool->setStorageAccessAPIEnabled(enabled);
+}
+
 - (void)_setAllowsAnySSLCertificateForServiceWorker:(BOOL) allows
 {
 #if ENABLE(SERVICE_WORKER)

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKProcessPoolPrivate.h (225005 => 225006)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKProcessPoolPrivate.h	2017-11-18 01:18:12 UTC (rev 225005)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKProcessPoolPrivate.h	2017-11-18 01:27:23 UTC (rev 225006)
@@ -93,6 +93,7 @@
 - (void)_setAllowsAnySSLCertificateForServiceWorker:(BOOL)allows WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
 
 @property (nonatomic, getter=_isCookieStoragePartitioningEnabled, setter=_setCookieStoragePartitioningEnabled:) BOOL _cookieStoragePartitioningEnabled WK_API_AVAILABLE(macosx(10.12.3), ios(10.3));
+@property (nonatomic, getter=_isStorageAccessAPIEnabled, setter=_setStorageAccessAPIEnabled:) BOOL _storageAccessAPIEnabled WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
 
 @end
 

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.mm (225005 => 225006)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.mm	2017-11-18 01:18:12 UTC (rev 225005)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.mm	2017-11-18 01:27:23 UTC (rev 225006)
@@ -346,6 +346,15 @@
         store->clearUserInteraction(URL(URL(), host));
 }
 
+- (void)_resourceLoadStatisticsSetHasHadNonRecentUserInteractionForHost:(NSString *)host
+{
+    auto* store = _websiteDataStore->websiteDataStore().resourceLoadStatistics();
+    if (!store)
+        return;
+    
+    store->logNonRecentUserInteraction(URL(URL(), host));
+}
+
 - (void)_resourceLoadStatisticsHadUserInteraction:(NSString *)host completionHandler:(void (^)(BOOL))completionHandler
 {
     auto* store = _websiteDataStore->websiteDataStore().resourceLoadStatistics();

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStorePrivate.h (225005 => 225006)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStorePrivate.h	2017-11-18 01:18:12 UTC (rev 225005)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStorePrivate.h	2017-11-18 01:27:23 UTC (rev 225006)
@@ -58,6 +58,7 @@
 - (void)_resourceLoadStatisticsIsRegisteredAsSubFrameUnder:(NSString *)subFrameHost topFrameHost:(NSString *)topFrameHost completionHandler:(void (^)(BOOL))completionHandler WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
 - (void)_resourceLoadStatisticsIsRegisteredAsRedirectingTo:(NSString *)hostRedirectedFrom hostRedirectedTo:(NSString *)hostRedirectedTo completionHandler:(void (^)(BOOL))completionHandler WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
 - (void)_resourceLoadStatisticsSetHadUserInteraction:(BOOL)value forHost:(NSString *)host WK_API_AVAILABLE(macosx(10.13), ios(11.0));
+- (void)_resourceLoadStatisticsSetHasHadNonRecentUserInteractionForHost:(NSString *)host WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
 - (void)_resourceLoadStatisticsHadUserInteraction:(NSString *)host completionHandler:(void (^)(BOOL))completionHandler WK_API_AVAILABLE(macosx(10.13), ios(11.0));
 - (void)_resourceLoadStatisticsSetIsGrandfathered:(BOOL)value forHost:(NSString *)host WK_API_AVAILABLE(macosx(10.13), ios(11.0));
 - (void)_resourceLoadStatisticsIsGrandfathered:(NSString *)host completionHandler:(void (^)(BOOL))completionHandler WK_API_AVAILABLE(macosx(10.13), ios(11.0));

Modified: trunk/Source/WebKit/UIProcess/Cocoa/WebProcessPoolCocoa.mm (225005 => 225006)


--- trunk/Source/WebKit/UIProcess/Cocoa/WebProcessPoolCocoa.mm	2017-11-18 01:18:12 UTC (rev 225005)
+++ trunk/Source/WebKit/UIProcess/Cocoa/WebProcessPoolCocoa.mm	2017-11-18 01:27:23 UTC (rev 225006)
@@ -295,6 +295,7 @@
 #endif
 
     parameters.cookieStoragePartitioningEnabled = cookieStoragePartitioningEnabled();
+    parameters.storageAccessAPIEnabled = storageAccessAPIEnabled();
 
 #if ENABLE(NETWORK_CAPTURE)
     parameters.recordReplayMode = [defaults stringForKey:WebKitRecordReplayModeDefaultsKey];
@@ -587,6 +588,12 @@
     sendToNetworkingProcess(Messages::NetworkProcess::SetCookieStoragePartitioningEnabled(enabled));
 }
 
+void WebProcessPool::setStorageAccessAPIEnabled(bool enabled)
+{
+    m_storageAccessAPIEnabled = enabled;
+    sendToNetworkingProcess(Messages::NetworkProcess::SetStorageAccessAPIEnabled(enabled));
+}
+
 int networkProcessLatencyQOS()
 {
     static const int qos = [[NSUserDefaults standardUserDefaults] integerForKey:@"WebKitNetworkProcessLatencyQOS"];

Modified: trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp (225005 => 225006)


--- trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp	2017-11-18 01:18:12 UTC (rev 225005)
+++ trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp	2017-11-18 01:27:23 UTC (rev 225006)
@@ -38,6 +38,7 @@
 #include "WebProcessMessages.h"
 #include "WebProcessPool.h"
 #include "WebsiteData.h"
+#include <wtf/CompletionHandler.h>
 
 #if ENABLE(SEC_ITEM_SHIM)
 #include "SecItemShimProxy.h"
@@ -394,6 +395,28 @@
 }
 #endif
 
+#if HAVE(CFNETWORK_STORAGE_PARTITIONING)
+static uint64_t nextRequestStorageAccessContextId()
+{
+    static uint64_t nextContextId = 0;
+    return ++nextContextId;
+}
+
+void NetworkProcessProxy::updateStorageAccessForPrevalentDomains(PAL::SessionID sessionID, const String& resourceDomain, const String& firstPartyDomain, bool value, WTF::CompletionHandler<void(bool)>&& callback)
+{
+    auto contextId = nextRequestStorageAccessContextId();
+    auto addResult = m_storageAccessResponseCallbackMap.add(contextId, WTFMove(callback));
+    ASSERT_UNUSED(addResult, addResult.isNewEntry);
+    send(Messages::NetworkProcess::UpdateStorageAccessForPrevalentDomains(sessionID, resourceDomain, firstPartyDomain, value, contextId), 0);
+}
+
+void NetworkProcessProxy::storageAccessRequestResult(bool wasGranted, uint64_t contextId)
+{
+    auto callback = m_storageAccessResponseCallbackMap.take(contextId);
+    callback(wasGranted);
+}
+#endif
+
 void NetworkProcessProxy::sendProcessWillSuspendImminently()
 {
     if (!canSendMessage())

Modified: trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.h (225005 => 225006)


--- trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.h	2017-11-18 01:18:12 UTC (rev 225005)
+++ trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.h	2017-11-18 01:27:23 UTC (rev 225006)
@@ -75,6 +75,10 @@
     void setProcessSuppressionEnabled(bool);
 #endif
 
+#if HAVE(CFNETWORK_STORAGE_PARTITIONING)
+    void updateStorageAccessForPrevalentDomains(PAL::SessionID, const String& resourceDomain, const String& firstPartyDomain, bool value, WTF::CompletionHandler<void(bool)>&& callback);
+#endif
+
     void processReadyToSuspend();
 
     void setIsHoldingLockedFiles(bool);
@@ -121,6 +125,9 @@
 #if USE(PROTECTION_SPACE_AUTH_CALLBACK)
     void canAuthenticateAgainstProtectionSpace(uint64_t loaderID, uint64_t pageID, uint64_t frameID, const WebCore::ProtectionSpace&);
 #endif
+#if HAVE(CFNETWORK_STORAGE_PARTITIONING)
+    void storageAccessRequestResult(bool wasGranted, uint64_t contextId);
+#endif
 
     // ProcessLauncher::Client
     void didFinishLaunching(ProcessLauncher*, IPC::Connection::Identifier) override;
@@ -138,6 +145,8 @@
     LegacyCustomProtocolManagerProxy m_customProtocolManagerProxy;
     ProcessThrottler m_throttler;
     ProcessThrottler::BackgroundActivityToken m_tokenForHoldingLockedFiles;
+
+    HashMap<uint64_t, WTF::CompletionHandler<void(bool wasGranted)>> m_storageAccessResponseCallbackMap;
 };
 
 } // namespace WebKit

Modified: trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.messages.in (225005 => 225006)


--- trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.messages.in	2017-11-18 01:18:12 UTC (rev 225005)
+++ trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.messages.in	2017-11-18 01:27:23 UTC (rev 225006)
@@ -42,4 +42,6 @@
 #if USE(PROTECTION_SPACE_AUTH_CALLBACK)
     CanAuthenticateAgainstProtectionSpace(uint64_t loaderID, uint64_t pageID, uint64_t frameID, WebCore::ProtectionSpace protectionSpace)
 #endif
+#if HAVE(CFNETWORK_STORAGE_PARTITIONING)
+    StorageAccessRequestResult(bool wasGranted, uint64_t contextId)
 }

Modified: trunk/Source/WebKit/UIProcess/WebCookieManagerProxy.cpp (225005 => 225006)


--- trunk/Source/WebKit/UIProcess/WebCookieManagerProxy.cpp	2017-11-18 01:18:12 UTC (rev 225005)
+++ trunk/Source/WebKit/UIProcess/WebCookieManagerProxy.cpp	2017-11-18 01:27:23 UTC (rev 225006)
@@ -286,4 +286,13 @@
 #endif
 }
 
+void WebCookieManagerProxy::setStorageAccessAPIEnabled(bool enabled)
+{
+#if PLATFORM(COCOA)
+    processPool()->sendToNetworkingProcess(Messages::NetworkProcess::SetStorageAccessAPIEnabled(enabled));
+#else
+    UNUSED_PARAM(enabled);
+#endif
+}
+
 } // namespace WebKit

Modified: trunk/Source/WebKit/UIProcess/WebCookieManagerProxy.h (225005 => 225006)


--- trunk/Source/WebKit/UIProcess/WebCookieManagerProxy.h	2017-11-18 01:18:12 UTC (rev 225005)
+++ trunk/Source/WebKit/UIProcess/WebCookieManagerProxy.h	2017-11-18 01:27:23 UTC (rev 225006)
@@ -80,6 +80,7 @@
     void getHTTPCookieAcceptPolicy(PAL::SessionID, Function<void (HTTPCookieAcceptPolicy, CallbackBase::Error)>&&);
 
     void setCookieStoragePartitioningEnabled(bool);
+    void setStorageAccessAPIEnabled(bool);
 
     void startObservingCookieChanges(PAL::SessionID);
     void stopObservingCookieChanges(PAL::SessionID);

Modified: trunk/Source/WebKit/UIProcess/WebProcessPool.h (225005 => 225006)


--- trunk/Source/WebKit/UIProcess/WebProcessPool.h	2017-11-18 01:18:12 UTC (rev 225005)
+++ trunk/Source/WebKit/UIProcess/WebProcessPool.h	2017-11-18 01:27:23 UTC (rev 225006)
@@ -415,6 +415,8 @@
 #if PLATFORM(COCOA)
     bool cookieStoragePartitioningEnabled() const { return m_cookieStoragePartitioningEnabled; }
     void setCookieStoragePartitioningEnabled(bool);
+    bool storageAccessAPIEnabled() const { return m_storageAccessAPIEnabled; }
+    void setStorageAccessAPIEnabled(bool);
 #endif
 
     static uint64_t registerProcessPoolCreationListener(Function<void(WebProcessPool&)>&&);
@@ -611,6 +613,7 @@
 
 #if PLATFORM(COCOA)
     bool m_cookieStoragePartitioningEnabled { false };
+    bool m_storageAccessAPIEnabled { false };
 #endif
 
     struct Paths {

Modified: trunk/Source/WebKit/UIProcess/WebResourceLoadStatisticsStore.cpp (225005 => 225006)


--- trunk/Source/WebKit/UIProcess/WebResourceLoadStatisticsStore.cpp	2017-11-18 01:18:12 UTC (rev 225005)
+++ trunk/Source/WebKit/UIProcess/WebResourceLoadStatisticsStore.cpp	2017-11-18 01:27:23 UTC (rev 225006)
@@ -145,10 +145,11 @@
     return mergedDates;
 }
 
-WebResourceLoadStatisticsStore::WebResourceLoadStatisticsStore(const String& resourceLoadStatisticsDirectory, Function<void (const String&)>&& testingCallback, UpdatePrevalentDomainsToPartitionOrBlockCookiesHandler&& updatePrevalentDomainsToPartitionOrBlockCookiesHandler, RemovePrevalentDomainsHandler&& removeDomainsHandler)
+WebResourceLoadStatisticsStore::WebResourceLoadStatisticsStore(const String& resourceLoadStatisticsDirectory, Function<void(const String&)>&& testingCallback, UpdatePrevalentDomainsToPartitionOrBlockCookiesHandler&& updatePrevalentDomainsToPartitionOrBlockCookiesHandler, UpdateStorageAccessForPrevalentDomainsHandler&& updateStorageAccessForPrevalentDomainsHandler, RemovePrevalentDomainsHandler&& removeDomainsHandler)
     : m_statisticsQueue(WorkQueue::create("WebResourceLoadStatisticsStore Process Data Queue", WorkQueue::Type::Serial, WorkQueue::QOS::Utility))
     , m_persistentStorage(*this, resourceLoadStatisticsDirectory)
     , m_updatePrevalentDomainsToPartitionOrBlockCookiesHandler(WTFMove(updatePrevalentDomainsToPartitionOrBlockCookiesHandler))
+    , m_updateStorageAccessForPrevalentDomainsHandler(WTFMove(updateStorageAccessForPrevalentDomainsHandler))
     , m_removeDomainsHandler(WTFMove(removeDomainsHandler))
     , m_dailyTasksTimer(RunLoop::main(), this, &WebResourceLoadStatisticsStore::performDailyTasks)
     , m_statisticsTestingCallback(WTFMove(testingCallback))
@@ -249,9 +250,26 @@
     ASSERT(subFrameHost != topFrameHost);
     ASSERT(RunLoop::isMain());
 
-    m_statisticsQueue->dispatch([this, protectedThis = makeRef(*this), subFramePrimaryDomain = isolatedPrimaryDomain(subFrameHost), callback = WTFMove(callback)] () {
-        auto& statistic = ensureResourceStatisticsForPrimaryDomain(subFramePrimaryDomain);
-        callback(!statistic.isPrevalentResource || statistic.hadUserInteraction);
+    m_statisticsQueue->dispatch([this, protectedThis = makeRef(*this), subFramePrimaryDomain = isolatedPrimaryDomain(subFrameHost), topFramePrimaryDomain = isolatedPrimaryDomain(topFrameHost), callback = WTFMove(callback)] () mutable {
+
+        auto& topFrameStatistic = ensureResourceStatisticsForPrimaryDomain(topFramePrimaryDomain);
+        if (topFrameStatistic.storageAccessUnderTopFrameOrigins.contains(subFramePrimaryDomain)) {
+            callback(true);
+            return;
+        }
+        
+        auto& subFrameStatistic = ensureResourceStatisticsForPrimaryDomain(subFramePrimaryDomain);
+        if (shouldBlockCookies(subFrameStatistic)) {
+            callback(false);
+            return;
+        }
+        
+        if (!shouldPartitionCookies(subFrameStatistic)) {
+            callback(true);
+            return;
+        }
+        
+        m_updateStorageAccessForPrevalentDomainsHandler(subFramePrimaryDomain, topFramePrimaryDomain, true, WTFMove(callback));
     });
 }
     
@@ -325,6 +343,20 @@
     });
 }
 
+void WebResourceLoadStatisticsStore::logNonRecentUserInteraction(const URL& url)
+{
+    if (url.isBlankURL() || url.isEmpty())
+        return;
+    
+    m_statisticsQueue->dispatch([this, protectedThis = makeRef(*this), primaryDomain = isolatedPrimaryDomain(url)] {
+        auto& statistics = ensureResourceStatisticsForPrimaryDomain(primaryDomain);
+        statistics.hadUserInteraction = true;
+        statistics.mostRecentUserInteractionTime = WallTime::now() - (m_parameters.timeToLiveCookiePartitionFree + Seconds::fromHours(1));
+
+        updateCookiePartitioningForDomains({ primaryDomain }, { }, { }, ShouldClearFirst::No);
+    });
+}
+
 void WebResourceLoadStatisticsStore::clearUserInteraction(const URL& url)
 {
     if (url.isBlankURL() || url.isEmpty())
@@ -726,7 +758,7 @@
 void WebResourceLoadStatisticsStore::updateCookiePartitioningForDomains(const Vector<String>& domainsToPartition, const Vector<String>& domainsToBlock, const Vector<String>& domainsToNeitherPartitionNorBlock, ShouldClearFirst shouldClearFirst)
 {
     ASSERT(!RunLoop::isMain());
-    if (domainsToPartition.isEmpty() && domainsToBlock.isEmpty() && domainsToNeitherPartitionNorBlock.isEmpty())
+    if (domainsToPartition.isEmpty() && domainsToBlock.isEmpty() && domainsToNeitherPartitionNorBlock.isEmpty() && shouldClearFirst == ShouldClearFirst::No)
         return;
 
     RunLoop::main().dispatch([this, shouldClearFirst, protectedThis = makeRef(*this), domainsToPartition = crossThreadCopy(domainsToPartition), domainsToBlock = crossThreadCopy(domainsToBlock), domainsToNeitherPartitionNorBlock = crossThreadCopy(domainsToNeitherPartitionNorBlock)] () {

Modified: trunk/Source/WebKit/UIProcess/WebResourceLoadStatisticsStore.h (225005 => 225006)


--- trunk/Source/WebKit/UIProcess/WebResourceLoadStatisticsStore.h	2017-11-18 01:18:12 UTC (rev 225005)
+++ trunk/Source/WebKit/UIProcess/WebResourceLoadStatisticsStore.h	2017-11-18 01:27:23 UTC (rev 225006)
@@ -60,10 +60,11 @@
 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 UpdateStorageAccessForPrevalentDomainsHandler = WTF::Function<void(const String& resourceDomain, const String& firstPartyDomain, bool value, WTF::Function<void(bool wasGranted)>&& callback)>;
     using RemovePrevalentDomainsHandler = WTF::Function<void (const Vector<String>&)>;
-    static Ref<WebResourceLoadStatisticsStore> create(const String& resourceLoadStatisticsDirectory, Function<void (const String&)>&& testingCallback, UpdatePrevalentDomainsToPartitionOrBlockCookiesHandler&& updatePrevalentDomainsToPartitionOrBlockCookiesHandler = [](const Vector<String>&, const Vector<String>&, const Vector<String>&, ShouldClearFirst) { }, RemovePrevalentDomainsHandler&& removeDomainsHandler = [] (const Vector<String>&) { })
+    static Ref<WebResourceLoadStatisticsStore> create(const String& resourceLoadStatisticsDirectory, Function<void (const String&)>&& testingCallback, UpdatePrevalentDomainsToPartitionOrBlockCookiesHandler&& updatePrevalentDomainsToPartitionOrBlockCookiesHandler = [](const Vector<String>&, const Vector<String>&, const Vector<String>&, ShouldClearFirst) { }, UpdateStorageAccessForPrevalentDomainsHandler&& updateStorageAccessForPrevalentDomainsHandler = [](const String&, const String&, bool, WTF::Function<void(bool)>&&) { }, RemovePrevalentDomainsHandler&& removeDomainsHandler = [] (const Vector<String>&) { })
     {
-        return adoptRef(*new WebResourceLoadStatisticsStore(resourceLoadStatisticsDirectory, WTFMove(testingCallback), WTFMove(updatePrevalentDomainsToPartitionOrBlockCookiesHandler), WTFMove(removeDomainsHandler)));
+        return adoptRef(*new WebResourceLoadStatisticsStore(resourceLoadStatisticsDirectory, WTFMove(testingCallback), WTFMove(updatePrevalentDomainsToPartitionOrBlockCookiesHandler), WTFMove(updateStorageAccessForPrevalentDomainsHandler), WTFMove(removeDomainsHandler)));
     }
 
     ~WebResourceLoadStatisticsStore();
@@ -78,7 +79,9 @@
     void setShouldSubmitTelemetry(bool value) { m_parameters.shouldSubmitTelemetry = value; }
 
     void resourceLoadStatisticsUpdated(Vector<WebCore::ResourceLoadStatistics>&& origins);
+
     void requestStorageAccess(String&& subFrameHost, String&& topFrameHost, WTF::Function<void (bool)>&& callback);
+    void requestStorageAccessCallback(bool wasGranted, uint64_t contextId);
 
     void processWillOpenConnection(WebProcessProxy&, IPC::Connection&);
     void processDidCloseConnection(WebProcessProxy&, IPC::Connection&);
@@ -85,6 +88,7 @@
     void applicationWillTerminate();
 
     void logUserInteraction(const WebCore::URL&);
+    void logNonRecentUserInteraction(const WebCore::URL&);
     void clearUserInteraction(const WebCore::URL&);
     void hasHadUserInteraction(const WebCore::URL&, WTF::Function<void (bool)>&&);
     void setLastSeen(const WebCore::URL&, Seconds);
@@ -135,7 +139,7 @@
     void logTestingEvent(const String&);
 
 private:
-    WebResourceLoadStatisticsStore(const String&, Function<void (const String&)>&& testingCallback, UpdatePrevalentDomainsToPartitionOrBlockCookiesHandler&&, RemovePrevalentDomainsHandler&&);
+    WebResourceLoadStatisticsStore(const String&, Function<void(const String&)>&& testingCallback, UpdatePrevalentDomainsToPartitionOrBlockCookiesHandler&&, UpdateStorageAccessForPrevalentDomainsHandler&&, RemovePrevalentDomainsHandler&&);
 
     void removeDataRecords();
 
@@ -188,6 +192,7 @@
     Vector<OperatingDate> m_operatingDates;
 
     UpdatePrevalentDomainsToPartitionOrBlockCookiesHandler m_updatePrevalentDomainsToPartitionOrBlockCookiesHandler;
+    UpdateStorageAccessForPrevalentDomainsHandler m_updateStorageAccessForPrevalentDomainsHandler;
     RemovePrevalentDomainsHandler m_removeDomainsHandler;
 
     WallTime m_endOfGrandfatheringTimestamp;

Modified: trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp (225005 => 225006)


--- trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp	2017-11-18 01:18:12 UTC (rev 225005)
+++ trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp	2017-11-18 01:27:23 UTC (rev 225006)
@@ -45,6 +45,7 @@
 #include <WebCore/OriginLock.h>
 #include <WebCore/SecurityOrigin.h>
 #include <WebCore/SecurityOriginData.h>
+#include <wtf/CompletionHandler.h>
 #include <wtf/CrossThreadCopier.h>
 #include <wtf/RunLoop.h>
 
@@ -1141,6 +1142,12 @@
         processPool->sendToNetworkingProcess(Messages::NetworkProcess::UpdatePrevalentDomainsToPartitionOrBlockCookies(m_sessionID, domainsToPartition, domainsToBlock, domainsToNeitherPartitionNorBlock, shouldClearFirst == ShouldClearFirst::Yes));
 }
 
+void WebsiteDataStore::updateStorageAccessForPrevalentDomainsHandler(const String& resourceDomain, const String& firstPartyDomain, bool value, WTF::CompletionHandler<void(bool wasGranted)>&& callback)
+{
+    for (auto& processPool : processPools())
+        processPool->networkProcess()->updateStorageAccessForPrevalentDomains(m_sessionID, resourceDomain, firstPartyDomain, value, WTFMove(callback));
+}
+
 void WebsiteDataStore::removePrevalentDomains(const Vector<String>& domains)
 {
     for (auto& processPool : processPools())
@@ -1334,7 +1341,9 @@
 #if HAVE(CFNETWORK_STORAGE_PARTITIONING)
     m_resourceLoadStatistics = WebResourceLoadStatisticsStore::create(m_configuration.resourceLoadStatisticsDirectory, WTFMove(callback), [this] (const Vector<String>& domainsToPartition, const Vector<String>& domainsToBlock, const Vector<String>& domainsToNeitherPartitionNorBlock, ShouldClearFirst shouldClearFirst) {
         updatePrevalentDomainsToPartitionOrBlockCookies(domainsToPartition, domainsToBlock, domainsToNeitherPartitionNorBlock, shouldClearFirst);
-    }, [this] (const Vector<String>& domainsToRemove) {
+    }, [this, protectedThis = makeRef(*this)] (const String& resourceDomain, const String& firstPartyDomain, bool value, WTF::Function<void(bool wasGranted)>&& callback) {
+        updateStorageAccessForPrevalentDomainsHandler(resourceDomain, firstPartyDomain, value, WTFMove(callback));
+    }, [this, protectedThis = makeRef(*this)] (const Vector<String>& domainsToRemove) {
         removePrevalentDomains(domainsToRemove);
     });
 #else

Modified: trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h (225005 => 225006)


--- trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h	2017-11-18 01:18:12 UTC (rev 225005)
+++ trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h	2017-11-18 01:27:23 UTC (rev 225006)
@@ -115,6 +115,7 @@
 
 #if HAVE(CFNETWORK_STORAGE_PARTITIONING)
     void updatePrevalentDomainsToPartitionOrBlockCookies(const Vector<String>& domainsToPartition, const Vector<String>& domainsToBlock, const Vector<String>& domainsToNeitherPartitionNorBlock, ShouldClearFirst);
+    void updateStorageAccessForPrevalentDomainsHandler(const String& resourceDomain, const String& firstPartyDomain, bool value, WTF::CompletionHandler<void(bool wasGranted)>&& callback);
     void removePrevalentDomains(const Vector<String>& domains);
 #endif
     void networkProcessDidCrash();

Modified: trunk/Tools/ChangeLog (225005 => 225006)


--- trunk/Tools/ChangeLog	2017-11-18 01:18:12 UTC (rev 225005)
+++ trunk/Tools/ChangeLog	2017-11-18 01:27:23 UTC (rev 225006)
@@ -1,3 +1,29 @@
+2017-11-17  John Wilander  <[email protected]>
+
+        Storage Access API: UI process should update network process about granted access
+        https://bugs.webkit.org/show_bug.cgi?id=176943
+        <rdar://problem/34440612>
+
+        Reviewed by Alex Christensen.
+
+        This adds the TestRunner function setStatisticsHasHadNonRecentUserInteraction()
+        which enables testing of prevalent resources with user interaction outside the
+        24 hour window.
+
+        * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl:
+        * WebKitTestRunner/InjectedBundle/TestRunner.cpp:
+        (WTR::TestRunner::setStorageAccessAPIEnabled):
+        (WTR::TestRunner::setStatisticsHasHadNonRecentUserInteraction):
+        * WebKitTestRunner/InjectedBundle/TestRunner.h:
+        * WebKitTestRunner/TestController.cpp:
+        (WTR::TestController::setStatisticsHasHadNonRecentUserInteraction):
+        * WebKitTestRunner/TestController.h:
+        * WebKitTestRunner/TestInvocation.cpp:
+        (WTR::TestInvocation::didReceiveSynchronousMessageFromInjectedBundle):
+        * WebKitTestRunner/cocoa/TestControllerCocoa.mm:
+        (WTR::initializeWebViewConfiguration):
+        (WTR::TestController::setStatisticsHasHadNonRecentUserInteraction):
+
 2017-11-17  Ryan Haddad  <[email protected]>
 
         Disable failing API tests for rdar://problem/35344202.

Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl (225005 => 225006)


--- trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl	2017-11-18 01:18:12 UTC (rev 225005)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl	2017-11-18 01:27:23 UTC (rev 225006)
@@ -176,6 +176,7 @@
     // Cookies testing
     void setAlwaysAcceptCookies(boolean accept);
     void setCookieStoragePartitioningEnabled(boolean enabled);
+    void setStorageAccessAPIEnabled(boolean enabled);
 
     void overridePreference(DOMString preference, DOMString value);
 
@@ -271,6 +272,7 @@
     boolean isStatisticsRegisteredAsSubFrameUnder(DOMString subFrameHost, DOMString topFrameHost);
     boolean isStatisticsRegisteredAsRedirectingTo(DOMString hostRedirectedFrom, DOMString hostRedirectedTo);
     void setStatisticsHasHadUserInteraction(DOMString hostName, boolean value);
+    void setStatisticsHasHadNonRecentUserInteraction(DOMString hostName);
     boolean isStatisticsHasHadUserInteraction(DOMString hostName);
     void setStatisticsGrandfathered(DOMString hostName, boolean value);
     boolean isStatisticsGrandfathered(DOMString hostName);

Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp (225005 => 225006)


--- trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp	2017-11-18 01:18:12 UTC (rev 225005)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp	2017-11-18 01:27:23 UTC (rev 225006)
@@ -783,6 +783,15 @@
     WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr);
 }
 
+void TestRunner::setStorageAccessAPIEnabled(bool enabled)
+{
+    WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetStorageAccessAPIEnabled"));
+    
+    WKRetainPtr<WKBooleanRef> messageBody(AdoptWK, WKBooleanCreate(enabled));
+    
+    WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr);
+}
+    
 double TestRunner::preciseTime()
 {
     return currentTime();
@@ -1344,6 +1353,13 @@
     WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr);
 }
 
+void TestRunner::setStatisticsHasHadNonRecentUserInteraction(JSStringRef hostName)
+{
+    WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetStatisticsHasHadNonRecentUserInteraction"));
+    WKRetainPtr<WKStringRef> messageBody(AdoptWK, WKStringCreateWithJSString(hostName));
+    WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr);
+}
+
 bool TestRunner::isStatisticsHasHadUserInteraction(JSStringRef hostName)
 {
     WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("IsStatisticsHasHadUserInteraction"));

Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h (225005 => 225006)


--- trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h	2017-11-18 01:18:12 UTC (rev 225005)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h	2017-11-18 01:27:23 UTC (rev 225006)
@@ -280,6 +280,7 @@
     // Cookies testing
     void setAlwaysAcceptCookies(bool);
     void setCookieStoragePartitioningEnabled(bool);
+    void setStorageAccessAPIEnabled(bool);
 
     // Custom full screen behavior.
     void setHasCustomFullScreenBehavior(bool value) { m_customFullScreenBehavior = value; }
@@ -375,6 +376,7 @@
     bool isStatisticsRegisteredAsSubFrameUnder(JSStringRef subFrameHost, JSStringRef topFrameHost);
     bool isStatisticsRegisteredAsRedirectingTo(JSStringRef hostRedirectedFrom, JSStringRef hostRedirectedTo);
     void setStatisticsHasHadUserInteraction(JSStringRef hostName, bool value);
+    void setStatisticsHasHadNonRecentUserInteraction(JSStringRef hostName);
     bool isStatisticsHasHadUserInteraction(JSStringRef hostName);
     void setStatisticsGrandfathered(JSStringRef hostName, bool value);
     bool isStatisticsGrandfathered(JSStringRef hostName);

Modified: trunk/Tools/WebKitTestRunner/TestController.cpp (225005 => 225006)


--- trunk/Tools/WebKitTestRunner/TestController.cpp	2017-11-18 01:18:12 UTC (rev 225005)
+++ trunk/Tools/WebKitTestRunner/TestController.cpp	2017-11-18 01:27:23 UTC (rev 225006)
@@ -2484,6 +2484,12 @@
     WKWebsiteDataStoreSetStatisticsHasHadUserInteraction(dataStore, host, value);
 }
 
+void TestController::setStatisticsHasHadNonRecentUserInteraction(WKStringRef host)
+{
+    auto* dataStore = WKContextGetWebsiteDataStore(platformContext());
+    WKWebsiteDataStoreSetStatisticsHasHadNonRecentUserInteraction(dataStore, host);
+}
+
 bool TestController::isStatisticsHasHadUserInteraction(WKStringRef host)
 {
     auto* dataStore = WKContextGetWebsiteDataStore(platformContext());

Modified: trunk/Tools/WebKitTestRunner/TestController.h (225005 => 225006)


--- trunk/Tools/WebKitTestRunner/TestController.h	2017-11-18 01:18:12 UTC (rev 225005)
+++ trunk/Tools/WebKitTestRunner/TestController.h	2017-11-18 01:27:23 UTC (rev 225006)
@@ -159,6 +159,7 @@
     bool isStatisticsRegisteredAsSubFrameUnder(WKStringRef subFrameHost, WKStringRef topFrameHost);
     bool isStatisticsRegisteredAsRedirectingTo(WKStringRef hostRedirectedFrom, WKStringRef hostRedirectedTo);
     void setStatisticsHasHadUserInteraction(WKStringRef hostName, bool value);
+    void setStatisticsHasHadNonRecentUserInteraction(WKStringRef hostName);
     bool isStatisticsHasHadUserInteraction(WKStringRef hostName);
     void setStatisticsGrandfathered(WKStringRef hostName, bool value);
     bool isStatisticsGrandfathered(WKStringRef hostName);

Modified: trunk/Tools/WebKitTestRunner/TestInvocation.cpp (225005 => 225006)


--- trunk/Tools/WebKitTestRunner/TestInvocation.cpp	2017-11-18 01:18:12 UTC (rev 225005)
+++ trunk/Tools/WebKitTestRunner/TestInvocation.cpp	2017-11-18 01:27:23 UTC (rev 225006)
@@ -824,6 +824,12 @@
         return nullptr;
     }
 
+    if (WKStringIsEqualToUTF8CString(messageName, "SetStorageAccessAPIEnabled")) {
+        WKBooleanRef accept = static_cast<WKBooleanRef>(messageBody);
+        WKCookieManagerSetStorageAccessAPIEnabled(WKContextGetCookieManager(TestController::singleton().context()), WKBooleanGetValue(accept));
+        return nullptr;
+    }
+    
     if (WKStringIsEqualToUTF8CString(messageName, "SetAllowsAnySSLCertificate")) {
         TestController::singleton().setAllowsAnySSLCertificate(WKBooleanGetValue(static_cast<WKBooleanRef>(messageBody)));
         return nullptr;
@@ -1009,6 +1015,13 @@
         return nullptr;
     }
 
+    if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsHasHadNonRecentUserInteraction")) {
+        ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
+        WKStringRef hostName = static_cast<WKStringRef>(messageBody);
+        TestController::singleton().setStatisticsHasHadNonRecentUserInteraction(hostName);
+        return nullptr;
+    }
+
     if (WKStringIsEqualToUTF8CString(messageName, "IsStatisticsHasHadUserInteraction")) {
         ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
         

Modified: trunk/Tools/WebKitTestRunner/cocoa/TestControllerCocoa.mm (225005 => 225006)


--- trunk/Tools/WebKitTestRunner/cocoa/TestControllerCocoa.mm	2017-11-18 01:18:12 UTC (rev 225005)
+++ trunk/Tools/WebKitTestRunner/cocoa/TestControllerCocoa.mm	2017-11-18 01:27:23 UTC (rev 225006)
@@ -77,6 +77,7 @@
 
 #if (PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101300) || PLATFORM(IOS)
     WKCookieManagerSetCookieStoragePartitioningEnabled(WKContextGetCookieManager(context), true);
+    WKCookieManagerSetStorageAccessAPIEnabled(WKContextGetCookieManager(context), true);
 #endif
 
     WKWebsiteDataStore* poolWebsiteDataStore = (WKWebsiteDataStore *)WKContextGetWebsiteDataStore((WKContextRef)globalWebViewConfiguration.processPool);
@@ -303,6 +304,11 @@
     [globalWebViewConfiguration.websiteDataStore _resourceLoadStatisticsSetHadUserInteraction:value forHost:toNSString(hostName)];
 }
 
+void TestController::setStatisticsHasHadNonRecentUserInteraction(WKStringRef hostName)
+{
+    [globalWebViewConfiguration.websiteDataStore _resourceLoadStatisticsSetHasHadNonRecentUserInteractionForHost:toNSString(hostName)];
+}
+
 bool TestController::isStatisticsHasHadUserInteraction(WKStringRef hostName)
 {
     __block bool isDataReady = false;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to