Title: [248640] trunk
Revision
248640
Author
wilan...@apple.com
Date
2019-08-13 15:34:29 -0700 (Tue, 13 Aug 2019)

Log Message

Resource Load Statistics: Switch NSURLSession on top navigation to prevalent resource with user interaction
https://bugs.webkit.org/show_bug.cgi?id=200642
<rdar://problem/53962073>

Reviewed by Alex Christensen.

Source/WebCore:

Tests: http/tests/resourceLoadStatistics/do-not-switch-session-on-navigation-to-prevalent-without-interaction.html
       http/tests/resourceLoadStatistics/switch-session-on-navigation-to-prevalent-with-interaction.html

This patch splits m_registrableDomainsToBlockCookieFor in WebCore:NetworkStorageSession into:
- m_registrableDomainsToBlockAndDeleteCookiesFor
- m_registrableDomainsToBlockButKeepCookiesFor
... to support different network load policies based on this distinction.

* page/RuntimeEnabledFeatures.h:
(WebCore::RuntimeEnabledFeatures::setITPSessionSwitchingEnabled):
(WebCore::RuntimeEnabledFeatures::itpSessionSwitchingEnabled const):
* page/Settings.yaml:
* platform/network/NetworkStorageSession.cpp:
(WebCore::NetworkStorageSession::shouldBlockThirdPartyCookies const):
(WebCore::NetworkStorageSession::shouldBlockThirdPartyCookiesButKeepFirstPartyCookiesFor const):
(WebCore::NetworkStorageSession::setPrevalentDomainsToBlockAndDeleteCookiesFor):
(WebCore::NetworkStorageSession::setPrevalentDomainsToBlockButKeepCookiesFor):
(WebCore::NetworkStorageSession::removePrevalentDomains):
(WebCore::NetworkStorageSession::setPrevalentDomainsToBlockCookiesFor): Deleted.
* platform/network/NetworkStorageSession.h:

Source/WebKit:

Since prevalent resources with user interaction get to keep their cookies and website
data, we should use a different NSURLSessions for when they are first-party websites
and have access to that data. This patch achieves that.

The WebKit::NetworkDataTaskCocoa constructor now checks with the network storage session
if the first party for this load should be isolated. The category for which this is true
is checked in the new function
WebCore:NetworkStorageSession::shouldBlockThirdPartyCookiesButKeepFirstPartyCookiesFor()
which in turn is backed by a new split of m_registrableDomainsToBlockCookieFor into:
- m_registrableDomainsToBlockAndDeleteCookiesFor
- m_registrableDomainsToBlockButKeepCookiesFor
... in WebCore:NetworkStorageSession.

Non-isolated sessions are now picked up through the convenience function
WebKit::NetworkSessionCocoa::session() whereas isolated sessions are created lazily and
picked up through WebKit::NetworkSessionCocoa::isolatedSession().

The number of isolated NSURLSessions in memory is capped to 10. When the cap is hit,
the session that's been unused the longest is aged out.

The C API changes are test infrastructure.

* NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.cpp:
(WebKit::ResourceLoadStatisticsDatabaseStore::clear):
(WebKit::ResourceLoadStatisticsDatabaseStore::domainsToBlockAndDeleteCookiesFor const):
(WebKit::ResourceLoadStatisticsDatabaseStore::domainsToBlockButKeepCookiesFor const):
(WebKit::ResourceLoadStatisticsDatabaseStore::updateCookieBlocking):
(WebKit::ResourceLoadStatisticsDatabaseStore::domainsToBlock const): Deleted.
* NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.h:
* NetworkProcess/Classifier/ResourceLoadStatisticsMemoryStore.cpp:
(WebKit::ResourceLoadStatisticsMemoryStore::clear):
(WebKit::ResourceLoadStatisticsMemoryStore::updateCookieBlocking):
* NetworkProcess/Classifier/ResourceLoadStatisticsStore.cpp:
(WebKit::ResourceLoadStatisticsStore::updateCookieBlockingForDomains):
(WebKit::ResourceLoadStatisticsStore::debugLogDomainsInBatches):
* NetworkProcess/Classifier/ResourceLoadStatisticsStore.h:
* NetworkProcess/Classifier/WebResourceLoadStatisticsStore.cpp:
(WebKit::WebResourceLoadStatisticsStore::callUpdatePrevalentDomainsToBlockCookiesForHandler):
(WebKit::WebResourceLoadStatisticsStore::scheduleCookieBlockingUpdateForDomains): Deleted.
(WebKit::WebResourceLoadStatisticsStore::scheduleClearBlockingStateForDomains): Deleted.
    Dead code.
* NetworkProcess/Classifier/WebResourceLoadStatisticsStore.h:
(WebKit::RegistrableDomainsToBlockCookiesFor::isolatedCopy const):
* NetworkProcess/NetworkProcess.cpp:
(WebKit::NetworkProcess::updatePrevalentDomainsToBlockCookiesFor):
(WebKit::NetworkProcess::scheduleClearInMemoryAndPersistent):
(WebKit::NetworkProcess::hasIsolatedSession const):
* NetworkProcess/NetworkProcess.h:
* NetworkProcess/NetworkProcess.messages.in:
* NetworkProcess/NetworkSession.h:
(WebKit::NetworkSession::shouldIsolateSessionsForPrevalentTopFrames const):
(WebKit::NetworkSession::hasIsolatedSession const):
(WebKit::NetworkSession::clearIsolatedSessions):
* NetworkProcess/NetworkSessionCreationParameters.cpp:
(WebKit::NetworkSessionCreationParameters::encode const):
(WebKit::NetworkSessionCreationParameters::decode):
* NetworkProcess/NetworkSessionCreationParameters.h:
* NetworkProcess/cocoa/NetworkDataTaskCocoa.mm:
(WebKit::NetworkDataTaskCocoa::NetworkDataTaskCocoa):
* NetworkProcess/cocoa/NetworkSessionCocoa.h:
* NetworkProcess/cocoa/NetworkSessionCocoa.mm:
(WebKit::NetworkSessionCocoa::NetworkSessionCocoa):
(WebKit::NetworkSessionCocoa::session):
(WebKit::NetworkSessionCocoa::isolatedSession):
(WebKit::NetworkSessionCocoa::hasIsolatedSession const):
(WebKit::NetworkSessionCocoa::clearIsolatedSessions):
(WebKit::NetworkSessionCocoa::invalidateAndCancel):
(WebKit::NetworkSessionCocoa::clearCredentials):
* Shared/WebPreferences.yaml:
* UIProcess/API/C/WKWebsiteDataStoreRef.cpp:
(WKWebsiteDataStoreStatisticsHasIsolatedSession):
* UIProcess/API/C/WKWebsiteDataStoreRef.h:
* UIProcess/Network/NetworkProcessProxy.cpp:
(WebKit::NetworkProcessProxy::hasIsolatedSession):
* UIProcess/Network/NetworkProcessProxy.h:
* UIProcess/WebsiteData/Cocoa/WebsiteDataStoreCocoa.mm:
(WebKit::WebsiteDataStore::parameters):
* UIProcess/WebsiteData/WebsiteDataStore.cpp:
(WebKit::WebsiteDataStore::hasLocalStorageForTesting const):
(WebKit::WebsiteDataStore::hasIsolatedSessionForTesting const):
* UIProcess/WebsiteData/WebsiteDataStore.h:

Tools:

This patch adds test infrastructure to query whether an origin has an
isolated NSURLSession or not.

* WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl:
* WebKitTestRunner/InjectedBundle/TestRunner.cpp:
(WTR::TestRunner::hasStatisticsIsolatedSession):
* WebKitTestRunner/InjectedBundle/TestRunner.h:
* WebKitTestRunner/TestController.cpp:
(WTR::TestController::hasStatisticsIsolatedSession):
* WebKitTestRunner/TestController.h:
* WebKitTestRunner/TestInvocation.cpp:
(WTR::TestInvocation::didReceiveSynchronousMessageFromInjectedBundle):

LayoutTests:

* http/tests/resourceLoadStatistics/do-not-switch-session-on-navigation-to-prevalent-without-interaction-expected.txt: Added.
* http/tests/resourceLoadStatistics/do-not-switch-session-on-navigation-to-prevalent-without-interaction.html: Added.
* http/tests/resourceLoadStatistics/switch-session-on-navigation-to-prevalent-with-interaction-expected.txt: Added.
* http/tests/resourceLoadStatistics/switch-session-on-navigation-to-prevalent-with-interaction.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (248639 => 248640)


--- trunk/LayoutTests/ChangeLog	2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/LayoutTests/ChangeLog	2019-08-13 22:34:29 UTC (rev 248640)
@@ -1,3 +1,16 @@
+2019-08-13  John Wilander  <wilan...@apple.com>
+
+        Resource Load Statistics: Switch NSURLSession on top navigation to prevalent resource with user interaction
+        https://bugs.webkit.org/show_bug.cgi?id=200642
+        <rdar://problem/53962073>
+
+        Reviewed by Alex Christensen.
+
+        * http/tests/resourceLoadStatistics/do-not-switch-session-on-navigation-to-prevalent-without-interaction-expected.txt: Added.
+        * http/tests/resourceLoadStatistics/do-not-switch-session-on-navigation-to-prevalent-without-interaction.html: Added.
+        * http/tests/resourceLoadStatistics/switch-session-on-navigation-to-prevalent-with-interaction-expected.txt: Added.
+        * http/tests/resourceLoadStatistics/switch-session-on-navigation-to-prevalent-with-interaction.html: Added.
+
 2019-08-13  Ryan Haddad  <ryanhad...@apple.com>
 
         [WebAuthN] Enable LocalAuthenticator for macOS

Added: trunk/LayoutTests/http/tests/resourceLoadStatistics/do-not-switch-session-on-navigation-to-prevalent-without-interaction-expected.txt (0 => 248640)


--- trunk/LayoutTests/http/tests/resourceLoadStatistics/do-not-switch-session-on-navigation-to-prevalent-without-interaction-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/http/tests/resourceLoadStatistics/do-not-switch-session-on-navigation-to-prevalent-without-interaction-expected.txt	2019-08-13 22:34:29 UTC (rev 248640)
@@ -0,0 +1,12 @@
+Tests that the session is not switched upon top frame navigation to a prevalent resource without user interaction.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS Should have and has the session cookie.
+PASS Should have and has the persistent cookie.
+PASS Origin has no isolated session.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/http/tests/resourceLoadStatistics/do-not-switch-session-on-navigation-to-prevalent-without-interaction.html (0 => 248640)


--- trunk/LayoutTests/http/tests/resourceLoadStatistics/do-not-switch-session-on-navigation-to-prevalent-without-interaction.html	                        (rev 0)
+++ trunk/LayoutTests/http/tests/resourceLoadStatistics/do-not-switch-session-on-navigation-to-prevalent-without-interaction.html	2019-08-13 22:34:29 UTC (rev 248640)
@@ -0,0 +1,108 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <script src=""
+    <script src=""
+</head>
+<body _onload_="runTest()">
+<script>
+    description("Tests that the session is not switched upon top frame navigation to a prevalent resource without user interaction.");
+    jsTestIsAsync = true;
+
+    const prevalentOrigin = "http://127.0.0.1:8000";
+    const nonPrevalentOrigin = "http://localhost:8000";
+    const sessionCookieName = "sessionCookie";
+    const persistentCookieName = "persistentCookie";
+    const twoMinutesInSeconds = 120;
+
+    function setSessionCookie() {
+        document.cookie = sessionCookieName + "=1; path=/";
+    }
+
+    function setPersistentCookie() {
+        document.cookie = persistentCookieName + "=1; path=/; Max-Age=" + twoMinutesInSeconds + ";";
+    }
+
+    function checkCookies(shouldHaveSessionCookie, shouldHavePersistentCookie) {
+        let hasSessionCookie = (document.cookie + "").includes(sessionCookieName),
+            hasPersistentCookie = (document.cookie + "").includes(persistentCookieName);
+
+        if (shouldHaveSessionCookie && hasSessionCookie)
+            testPassed("Should have and has the session cookie.");
+        else if (shouldHaveSessionCookie && !hasSessionCookie) {
+            testFailed("Should have but doesn't have the session cookie.");
+            setEnableFeature(false, finishJSTest);
+        } else if (!shouldHaveSessionCookie && hasSessionCookie) {
+            testFailed("Shouldn't have but has the session cookie.");
+            setEnableFeature(false, finishJSTest);
+        } else
+            testPassed("Shouldn't have and doesn't have the session cookie.");
+
+
+        if (shouldHavePersistentCookie && hasPersistentCookie)
+            testPassed("Should have and has the persistent cookie.");
+        else if (shouldHavePersistentCookie && !hasPersistentCookie) {
+            testFailed("Should have but doesn't have the persistent cookie.");
+            setEnableFeature(false, finishJSTest);
+        } else if (!shouldHavePersistentCookie && hasPersistentCookie) {
+            testFailed("Shouldn't have but has the persistent cookie.");
+            setEnableFeature(false, finishJSTest);
+        } else
+            testPassed("Shouldn't have and doesn't have the persistent cookie.");
+    }
+
+    function runTest() {
+        switch (document.location.hash) {
+            case "#step1":
+                setSessionCookie();
+                setPersistentCookie();
+                checkCookies(true, true);
+                if (testRunner.hasStatisticsIsolatedSession(prevalentOrigin)) {
+                    testFailed("Origin has isolated session.");
+                    setEnableFeature(false, finishJSTest);
+                } else
+                    testPassed("Origin has no isolated session.");
+                document.location.href = "" + "/resourceLoadStatistics/do-not-switch-session-on-navigation-to-prevalent-without-interaction.html#step2";
+                break;
+            case "#step2":
+                document.location.hash = "step3";
+                if (document.location.origin !== nonPrevalentOrigin)
+                    testFailed("Step 2 is not on " + nonPrevalentOrigin + ".");
+                testRunner.setStatisticsPrevalentResource(prevalentOrigin, true, function() {
+                    if (!testRunner.isStatisticsPrevalentResource(prevalentOrigin)) {
+                        testFailed(prevalentOrigin + " did not get set as prevalent resource.");
+                        setEnableFeature(false, finishJSTest);
+                    }
+                    testRunner.statisticsUpdateCookieBlocking(runTest);
+                });
+                break;
+            case "#step3":
+                document.location.href = "" + "/resourceLoadStatistics/do-not-switch-session-on-navigation-to-prevalent-without-interaction.html#step4";
+                break;
+            case "#step4":
+                checkCookies(true, true);
+                if (testRunner.hasStatisticsIsolatedSession(prevalentOrigin))
+                    testFailed("Origin has isolated session.");
+                else
+                    testPassed("Origin has no isolated session.");
+                setEnableFeature(false, finishJSTest);
+                break;
+            default:
+                testFailed("Unknown hash.");
+                setEnableFeature(false, finishJSTest);
+        }
+    }
+
+    if (document.location.hash === "") {
+        if (document.location.origin !== prevalentOrigin)
+            testFailed("Test is not starting out on " + prevalentOrigin + ".");
+        setEnableFeature(true, function () {
+            if (testRunner.isStatisticsPrevalentResource(prevalentOrigin))
+                testFailed(prevalentOrigin + " was classified as prevalent resource before the test starts.");
+            document.location.hash = "step1";
+        });
+    }
+</script>
+</body>
+</html>

Added: trunk/LayoutTests/http/tests/resourceLoadStatistics/switch-session-on-navigation-to-prevalent-with-interaction-expected.txt (0 => 248640)


--- trunk/LayoutTests/http/tests/resourceLoadStatistics/switch-session-on-navigation-to-prevalent-with-interaction-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/http/tests/resourceLoadStatistics/switch-session-on-navigation-to-prevalent-with-interaction-expected.txt	2019-08-13 22:34:29 UTC (rev 248640)
@@ -0,0 +1,12 @@
+Tests that the session is switched upon top frame navigation to a prevalent resource with user interaction.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS Should have and has the session cookie.
+PASS Should have and has the persistent cookie.
+PASS Origin has isolated session.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/http/tests/resourceLoadStatistics/switch-session-on-navigation-to-prevalent-with-interaction.html (0 => 248640)


--- trunk/LayoutTests/http/tests/resourceLoadStatistics/switch-session-on-navigation-to-prevalent-with-interaction.html	                        (rev 0)
+++ trunk/LayoutTests/http/tests/resourceLoadStatistics/switch-session-on-navigation-to-prevalent-with-interaction.html	2019-08-13 22:34:29 UTC (rev 248640)
@@ -0,0 +1,110 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <script src=""
+    <script src=""
+</head>
+<body _onload_="runTest()">
+<script>
+    description("Tests that the session is switched upon top frame navigation to a prevalent resource with user interaction.");
+    jsTestIsAsync = true;
+
+    const prevalentOrigin = "http://127.0.0.1:8000";
+    const nonPrevalentOrigin = "http://localhost:8000";
+    const sessionCookieName = "sessionCookie";
+    const persistentCookieName = "persistentCookie";
+    const twoMinutesInSeconds = 120;
+
+    function setSessionCookie() {
+        document.cookie = sessionCookieName + "=1; path=/";
+    }
+
+    function setPersistentCookie() {
+        document.cookie = persistentCookieName + "=1; path=/; Max-Age=" + twoMinutesInSeconds + ";";
+    }
+
+    function checkCookies(shouldHaveSessionCookie, shouldHavePersistentCookie) {
+        let hasSessionCookie = (document.cookie + "").includes(sessionCookieName),
+            hasPersistentCookie = (document.cookie + "").includes(persistentCookieName);
+
+        if (shouldHaveSessionCookie && hasSessionCookie)
+            testPassed("Should have and has the session cookie.");
+        else if (shouldHaveSessionCookie && !hasSessionCookie) {
+            testFailed("Should have but doesn't have the session cookie.");
+            setEnableFeature(false, finishJSTest);
+        } else if (!shouldHaveSessionCookie && hasSessionCookie) {
+            testFailed("Shouldn't have but has the session cookie.");
+            setEnableFeature(false, finishJSTest);
+        } else
+            testPassed("Shouldn't have and doesn't have the session cookie.");
+
+
+        if (shouldHavePersistentCookie && hasPersistentCookie)
+            testPassed("Should have and has the persistent cookie.");
+        else if (shouldHavePersistentCookie && !hasPersistentCookie) {
+            testFailed("Should have but doesn't have the persistent cookie.");
+            setEnableFeature(false, finishJSTest);
+        } else if (!shouldHavePersistentCookie && hasPersistentCookie) {
+            testFailed("Shouldn't have but has the persistent cookie.");
+            setEnableFeature(false, finishJSTest);
+        } else
+            testPassed("Shouldn't have and doesn't have the persistent cookie.");
+    }
+
+    function runTest() {
+        switch (document.location.hash) {
+            case "#step1":
+                testRunner.setStatisticsHasHadUserInteraction(prevalentOrigin, true, function() {
+                    setSessionCookie();
+                    setPersistentCookie();
+                    checkCookies(true, true);
+                    if (testRunner.hasStatisticsIsolatedSession(prevalentOrigin)) {
+                        testFailed("Origin has isolated session.");
+                        setEnableFeature(false, finishJSTest);
+                    } else
+                        testPassed("Origin has no isolated session.");
+                    document.location.href = "" + "/resourceLoadStatistics/switch-session-on-navigation-to-prevalent-with-interaction.html#step2";
+                });
+                break;
+            case "#step2":
+                document.location.hash = "step3";
+                if (document.location.origin !== nonPrevalentOrigin)
+                    testFailed("Step 2 is not on " + nonPrevalentOrigin + ".");
+                testRunner.setStatisticsPrevalentResource(prevalentOrigin, true, function() {
+                    if (!testRunner.isStatisticsPrevalentResource(prevalentOrigin)) {
+                        testFailed(prevalentOrigin + " did not get set as prevalent resource.");
+                        setEnableFeature(false, finishJSTest);
+                    }
+                    testRunner.statisticsUpdateCookieBlocking(runTest);
+                });
+                break;
+            case "#step3":
+                document.location.href = "" + "/resourceLoadStatistics/switch-session-on-navigation-to-prevalent-with-interaction.html#step4";
+                break;
+            case "#step4":
+                checkCookies(true, true);
+                if (testRunner.hasStatisticsIsolatedSession(prevalentOrigin))
+                    testPassed("Origin has isolated session.");
+                else
+                    testFailed("Origin has no isolated session.");
+                setEnableFeature(false, finishJSTest);
+                break;
+            default:
+                testFailed("Unknown hash.");
+                setEnableFeature(false, finishJSTest);
+        }
+    }
+
+    if (document.location.hash === "") {
+        if (document.location.origin !== prevalentOrigin)
+            testFailed("Test is not starting out on " + prevalentOrigin + ".");
+        setEnableFeature(true, function () {
+            if (testRunner.isStatisticsPrevalentResource(prevalentOrigin))
+                testFailed(prevalentOrigin + " was classified as prevalent resource before the test starts.");
+            document.location.hash = "step1";
+        });
+    }
+</script>
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (248639 => 248640)


--- trunk/Source/WebCore/ChangeLog	2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Source/WebCore/ChangeLog	2019-08-13 22:34:29 UTC (rev 248640)
@@ -1,3 +1,32 @@
+2019-08-13  John Wilander  <wilan...@apple.com>
+
+        Resource Load Statistics: Switch NSURLSession on top navigation to prevalent resource with user interaction
+        https://bugs.webkit.org/show_bug.cgi?id=200642
+        <rdar://problem/53962073>
+
+        Reviewed by Alex Christensen.
+
+        Tests: http/tests/resourceLoadStatistics/do-not-switch-session-on-navigation-to-prevalent-without-interaction.html
+               http/tests/resourceLoadStatistics/switch-session-on-navigation-to-prevalent-with-interaction.html
+
+        This patch splits m_registrableDomainsToBlockCookieFor in WebCore:NetworkStorageSession into:
+        - m_registrableDomainsToBlockAndDeleteCookiesFor
+        - m_registrableDomainsToBlockButKeepCookiesFor
+        ... to support different network load policies based on this distinction.
+
+        * page/RuntimeEnabledFeatures.h:
+        (WebCore::RuntimeEnabledFeatures::setITPSessionSwitchingEnabled):
+        (WebCore::RuntimeEnabledFeatures::itpSessionSwitchingEnabled const):
+        * page/Settings.yaml:
+        * platform/network/NetworkStorageSession.cpp:
+        (WebCore::NetworkStorageSession::shouldBlockThirdPartyCookies const):
+        (WebCore::NetworkStorageSession::shouldBlockThirdPartyCookiesButKeepFirstPartyCookiesFor const):
+        (WebCore::NetworkStorageSession::setPrevalentDomainsToBlockAndDeleteCookiesFor):
+        (WebCore::NetworkStorageSession::setPrevalentDomainsToBlockButKeepCookiesFor):
+        (WebCore::NetworkStorageSession::removePrevalentDomains):
+        (WebCore::NetworkStorageSession::setPrevalentDomainsToBlockCookiesFor): Deleted.
+        * platform/network/NetworkStorageSession.h:
+
 2019-08-13  Zalan Bujtas  <za...@apple.com>
 
         [ContentChangeObserver] setShouldObserveDOMTimerScheduling and setShouldObserveTransitions are always called in pairs.

Modified: trunk/Source/WebCore/page/RuntimeEnabledFeatures.h (248639 => 248640)


--- trunk/Source/WebCore/page/RuntimeEnabledFeatures.h	2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Source/WebCore/page/RuntimeEnabledFeatures.h	2019-08-13 22:34:29 UTC (rev 248640)
@@ -147,6 +147,9 @@
     void setIsITPDatabaseEnabled(bool isEnabled) { m_isITPDatabaseEnabled = isEnabled; }
     bool isITPDatabaseEnabled() const { return m_isITPDatabaseEnabled; }
 
+    void setIsITPSessionSwitchingEnabled(bool isEnabled) { m_isITPSessionSwitchingEnabled = isEnabled; }
+    bool isITPSessionSwitchingEnabled() const { return m_isITPSessionSwitchingEnabled; }
+
     void setRestrictedHTTPResponseAccess(bool isEnabled) { m_isRestrictedHTTPResponseAccess = isEnabled; }
     bool restrictedHTTPResponseAccess() const { return m_isRestrictedHTTPResponseAccess; }
 
@@ -410,6 +413,7 @@
     bool m_accessibilityObjectModelEnabled { false };
     bool m_ariaReflectionEnabled { true };
     bool m_itpDebugMode { false };
+    bool m_isITPSessionSwitchingEnabled { true };
     bool m_isRestrictedHTTPResponseAccess { true };
     bool m_crossOriginResourcePolicyEnabled { true };
     bool m_isWebGLCompressedTextureASTCSupportEnabled { false };

Modified: trunk/Source/WebCore/page/Settings.yaml (248639 => 248640)


--- trunk/Source/WebCore/page/Settings.yaml	2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Source/WebCore/page/Settings.yaml	2019-08-13 22:34:29 UTC (rev 248640)
@@ -861,6 +861,9 @@
   initial: true
   inspectorOverride: true
 
+isITPSessionSwitchingEnabled:
+  initial: true
+
 # Deprecated
 
 iceCandidateFilteringEnabled:

Modified: trunk/Source/WebCore/platform/network/NetworkStorageSession.cpp (248639 => 248640)


--- trunk/Source/WebCore/platform/network/NetworkStorageSession.cpp	2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Source/WebCore/platform/network/NetworkStorageSession.cpp	2019-08-13 22:34:29 UTC (rev 248640)
@@ -63,9 +63,22 @@
     if (registrableDomain.isEmpty())
         return false;
 
-    return m_registrableDomainsToBlockCookieFor.contains(registrableDomain);
+    ASSERT(!(m_registrableDomainsToBlockAndDeleteCookiesFor.contains(registrableDomain) && m_registrableDomainsToBlockButKeepCookiesFor.contains(registrableDomain)));
+
+    return m_registrableDomainsToBlockAndDeleteCookiesFor.contains(registrableDomain)
+        || m_registrableDomainsToBlockButKeepCookiesFor.contains(registrableDomain);
 }
 
+bool NetworkStorageSession::shouldBlockThirdPartyCookiesButKeepFirstPartyCookiesFor(const RegistrableDomain& registrableDomain) const
+{
+    if (registrableDomain.isEmpty())
+        return false;
+
+    ASSERT(!(m_registrableDomainsToBlockAndDeleteCookiesFor.contains(registrableDomain) && m_registrableDomainsToBlockButKeepCookiesFor.contains(registrableDomain)));
+
+    return m_registrableDomainsToBlockButKeepCookiesFor.contains(registrableDomain);
+}
+
 bool NetworkStorageSession::shouldBlockCookies(const ResourceRequest& request, Optional<uint64_t> frameID, Optional<PageIdentifier> pageID) const
 {
     return shouldBlockCookies(request.firstPartyForCookies(), request.url(), frameID, pageID);
@@ -103,16 +116,24 @@
     m_ageCapForClientSideCookiesShort = seconds ? Seconds { seconds->seconds() / 7. } : seconds;
 }
 
-void NetworkStorageSession::setPrevalentDomainsToBlockCookiesFor(const Vector<RegistrableDomain>& domains)
+void NetworkStorageSession::setPrevalentDomainsToBlockAndDeleteCookiesFor(const Vector<RegistrableDomain>& domains)
 {
-    m_registrableDomainsToBlockCookieFor.clear();
-    m_registrableDomainsToBlockCookieFor.add(domains.begin(), domains.end());
+    m_registrableDomainsToBlockAndDeleteCookiesFor.clear();
+    m_registrableDomainsToBlockAndDeleteCookiesFor.add(domains.begin(), domains.end());
 }
 
+void NetworkStorageSession::setPrevalentDomainsToBlockButKeepCookiesFor(const Vector<RegistrableDomain>& domains)
+{
+    m_registrableDomainsToBlockButKeepCookiesFor.clear();
+    m_registrableDomainsToBlockButKeepCookiesFor.add(domains.begin(), domains.end());
+}
+
 void NetworkStorageSession::removePrevalentDomains(const Vector<RegistrableDomain>& domains)
 {
-    for (auto& domain : domains)
-        m_registrableDomainsToBlockCookieFor.remove(domain);
+    for (auto& domain : domains) {
+        m_registrableDomainsToBlockAndDeleteCookiesFor.remove(domain);
+        m_registrableDomainsToBlockButKeepCookiesFor.remove(domain);
+    }
 }
 
 bool NetworkStorageSession::hasStorageAccess(const RegistrableDomain& resourceDomain, const RegistrableDomain& firstPartyDomain, Optional<uint64_t> frameID, PageIdentifier pageID) const

Modified: trunk/Source/WebCore/platform/network/NetworkStorageSession.h (248639 => 248640)


--- trunk/Source/WebCore/platform/network/NetworkStorageSession.h	2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Source/WebCore/platform/network/NetworkStorageSession.h	2019-08-13 22:34:29 UTC (rev 248640)
@@ -143,7 +143,9 @@
     WEBCORE_EXPORT bool shouldBlockCookies(const ResourceRequest&, Optional<uint64_t> frameID, Optional<PageIdentifier>) const;
     WEBCORE_EXPORT bool shouldBlockCookies(const URL& firstPartyForCookies, const URL& resource, Optional<uint64_t> frameID, Optional<PageIdentifier>) const;
     WEBCORE_EXPORT bool shouldBlockThirdPartyCookies(const RegistrableDomain&) const;
-    WEBCORE_EXPORT void setPrevalentDomainsToBlockCookiesFor(const Vector<RegistrableDomain>&);
+    WEBCORE_EXPORT bool shouldBlockThirdPartyCookiesButKeepFirstPartyCookiesFor(const RegistrableDomain&) const;
+    WEBCORE_EXPORT void setPrevalentDomainsToBlockAndDeleteCookiesFor(const Vector<RegistrableDomain>&);
+    WEBCORE_EXPORT void setPrevalentDomainsToBlockButKeepCookiesFor(const Vector<RegistrableDomain>&);
     WEBCORE_EXPORT void setAgeCapForClientSideCookies(Optional<Seconds>);
     WEBCORE_EXPORT void removePrevalentDomains(const Vector<RegistrableDomain>& domains);
     WEBCORE_EXPORT bool hasStorageAccess(const RegistrableDomain& resourceDomain, const RegistrableDomain& firstPartyDomain, Optional<uint64_t> frameID, PageIdentifier) const;
@@ -181,7 +183,8 @@
 
 #if ENABLE(RESOURCE_LOAD_STATISTICS)
     Optional<Seconds> clientSideCookieCap(const RegistrableDomain& firstParty, Optional<PageIdentifier>) const;
-    HashSet<RegistrableDomain> m_registrableDomainsToBlockCookieFor;
+    HashSet<RegistrableDomain> m_registrableDomainsToBlockAndDeleteCookiesFor;
+    HashSet<RegistrableDomain> m_registrableDomainsToBlockButKeepCookiesFor;
     HashMap<PageIdentifier, HashMap<uint64_t, RegistrableDomain, DefaultHash<uint64_t>::Hash, WTF::UnsignedWithZeroKeyHashTraits<uint64_t>>> m_framesGrantedStorageAccess;
     HashMap<PageIdentifier, HashMap<RegistrableDomain, RegistrableDomain>> m_pagesGrantedStorageAccess;
     Optional<Seconds> m_cacheMaxAgeCapForPrevalentResources { };

Modified: trunk/Source/WebKit/ChangeLog (248639 => 248640)


--- trunk/Source/WebKit/ChangeLog	2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Source/WebKit/ChangeLog	2019-08-13 22:34:29 UTC (rev 248640)
@@ -1,3 +1,93 @@
+2019-08-13  John Wilander  <wilan...@apple.com>
+
+        Resource Load Statistics: Switch NSURLSession on top navigation to prevalent resource with user interaction
+        https://bugs.webkit.org/show_bug.cgi?id=200642
+        <rdar://problem/53962073>
+
+        Reviewed by Alex Christensen.
+
+        Since prevalent resources with user interaction get to keep their cookies and website
+        data, we should use a different NSURLSessions for when they are first-party websites
+        and have access to that data. This patch achieves that.
+
+        The WebKit::NetworkDataTaskCocoa constructor now checks with the network storage session
+        if the first party for this load should be isolated. The category for which this is true
+        is checked in the new function
+        WebCore:NetworkStorageSession::shouldBlockThirdPartyCookiesButKeepFirstPartyCookiesFor()
+        which in turn is backed by a new split of m_registrableDomainsToBlockCookieFor into:
+        - m_registrableDomainsToBlockAndDeleteCookiesFor
+        - m_registrableDomainsToBlockButKeepCookiesFor
+        ... in WebCore:NetworkStorageSession.
+
+        Non-isolated sessions are now picked up through the convenience function
+        WebKit::NetworkSessionCocoa::session() whereas isolated sessions are created lazily and
+        picked up through WebKit::NetworkSessionCocoa::isolatedSession().
+
+        The number of isolated NSURLSessions in memory is capped to 10. When the cap is hit,
+        the session that's been unused the longest is aged out.
+
+        The C API changes are test infrastructure.
+
+        * NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.cpp:
+        (WebKit::ResourceLoadStatisticsDatabaseStore::clear):
+        (WebKit::ResourceLoadStatisticsDatabaseStore::domainsToBlockAndDeleteCookiesFor const):
+        (WebKit::ResourceLoadStatisticsDatabaseStore::domainsToBlockButKeepCookiesFor const):
+        (WebKit::ResourceLoadStatisticsDatabaseStore::updateCookieBlocking):
+        (WebKit::ResourceLoadStatisticsDatabaseStore::domainsToBlock const): Deleted.
+        * NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.h:
+        * NetworkProcess/Classifier/ResourceLoadStatisticsMemoryStore.cpp:
+        (WebKit::ResourceLoadStatisticsMemoryStore::clear):
+        (WebKit::ResourceLoadStatisticsMemoryStore::updateCookieBlocking):
+        * NetworkProcess/Classifier/ResourceLoadStatisticsStore.cpp:
+        (WebKit::ResourceLoadStatisticsStore::updateCookieBlockingForDomains):
+        (WebKit::ResourceLoadStatisticsStore::debugLogDomainsInBatches):
+        * NetworkProcess/Classifier/ResourceLoadStatisticsStore.h:
+        * NetworkProcess/Classifier/WebResourceLoadStatisticsStore.cpp:
+        (WebKit::WebResourceLoadStatisticsStore::callUpdatePrevalentDomainsToBlockCookiesForHandler):
+        (WebKit::WebResourceLoadStatisticsStore::scheduleCookieBlockingUpdateForDomains): Deleted.
+        (WebKit::WebResourceLoadStatisticsStore::scheduleClearBlockingStateForDomains): Deleted.
+            Dead code.
+        * NetworkProcess/Classifier/WebResourceLoadStatisticsStore.h:
+        (WebKit::RegistrableDomainsToBlockCookiesFor::isolatedCopy const):
+        * NetworkProcess/NetworkProcess.cpp:
+        (WebKit::NetworkProcess::updatePrevalentDomainsToBlockCookiesFor):
+        (WebKit::NetworkProcess::scheduleClearInMemoryAndPersistent):
+        (WebKit::NetworkProcess::hasIsolatedSession const):
+        * NetworkProcess/NetworkProcess.h:
+        * NetworkProcess/NetworkProcess.messages.in:
+        * NetworkProcess/NetworkSession.h:
+        (WebKit::NetworkSession::shouldIsolateSessionsForPrevalentTopFrames const):
+        (WebKit::NetworkSession::hasIsolatedSession const):
+        (WebKit::NetworkSession::clearIsolatedSessions):
+        * NetworkProcess/NetworkSessionCreationParameters.cpp:
+        (WebKit::NetworkSessionCreationParameters::encode const):
+        (WebKit::NetworkSessionCreationParameters::decode):
+        * NetworkProcess/NetworkSessionCreationParameters.h:
+        * NetworkProcess/cocoa/NetworkDataTaskCocoa.mm:
+        (WebKit::NetworkDataTaskCocoa::NetworkDataTaskCocoa):
+        * NetworkProcess/cocoa/NetworkSessionCocoa.h:
+        * NetworkProcess/cocoa/NetworkSessionCocoa.mm:
+        (WebKit::NetworkSessionCocoa::NetworkSessionCocoa):
+        (WebKit::NetworkSessionCocoa::session):
+        (WebKit::NetworkSessionCocoa::isolatedSession):
+        (WebKit::NetworkSessionCocoa::hasIsolatedSession const):
+        (WebKit::NetworkSessionCocoa::clearIsolatedSessions):
+        (WebKit::NetworkSessionCocoa::invalidateAndCancel):
+        (WebKit::NetworkSessionCocoa::clearCredentials):
+        * Shared/WebPreferences.yaml:
+        * UIProcess/API/C/WKWebsiteDataStoreRef.cpp:
+        (WKWebsiteDataStoreStatisticsHasIsolatedSession):
+        * UIProcess/API/C/WKWebsiteDataStoreRef.h:
+        * UIProcess/Network/NetworkProcessProxy.cpp:
+        (WebKit::NetworkProcessProxy::hasIsolatedSession):
+        * UIProcess/Network/NetworkProcessProxy.h:
+        * UIProcess/WebsiteData/Cocoa/WebsiteDataStoreCocoa.mm:
+        (WebKit::WebsiteDataStore::parameters):
+        * UIProcess/WebsiteData/WebsiteDataStore.cpp:
+        (WebKit::WebsiteDataStore::hasLocalStorageForTesting const):
+        (WebKit::WebsiteDataStore::hasIsolatedSessionForTesting const):
+        * UIProcess/WebsiteData/WebsiteDataStore.h:
+
 2019-08-13  Chris Dumez  <cdu...@apple.com>
 
         Fix potential thread safety issue under WebResourceLoadStatisticsStore::hasHadUserInteraction()

Modified: trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.cpp (248639 => 248640)


--- trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.cpp	2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.cpp	2019-08-13 22:34:29 UTC (rev 248640)
@@ -1317,8 +1317,9 @@
 
     removeAllStorageAccess([callbackAggregator = callbackAggregator.copyRef()] { });
 
-    auto primaryDomainsToBlock = ensurePrevalentResourcesForDebugMode();
-    updateCookieBlockingForDomains(primaryDomainsToBlock, [callbackAggregator = callbackAggregator.copyRef()] { });
+    auto registrableDomainsToBlockAndDeleteCookiesFor = ensurePrevalentResourcesForDebugMode();
+    RegistrableDomainsToBlockCookiesFor domainsToBlock { registrableDomainsToBlockAndDeleteCookiesFor, { } };
+    updateCookieBlockingForDomains(domainsToBlock, [callbackAggregator = callbackAggregator.copyRef()] { });
 }
 
 ResourceLoadStatisticsDatabaseStore::CookieTreatmentResult ResourceLoadStatisticsDatabaseStore::cookieTreatmentForOrigin(const RegistrableDomain& domain) const
@@ -1353,12 +1354,27 @@
     return !statement.getColumnInt(0) ? StorageAccessPromptWasShown::Yes : StorageAccessPromptWasShown::No;
 }
 
-Vector<RegistrableDomain> ResourceLoadStatisticsDatabaseStore::domainsToBlock() const
+Vector<RegistrableDomain> ResourceLoadStatisticsDatabaseStore::domainsToBlockAndDeleteCookiesFor() const
 {
     ASSERT(!RunLoop::isMain());
+    
+    Vector<RegistrableDomain> results;
+    SQLiteStatement statement(m_database, "SELECT registrableDomain FROM ObservedDomains WHERE isPrevalent = 1 AND hadUserInteraction = 0"_s);
+    if (statement.prepare() != SQLITE_OK)
+        return results;
+    
+    while (statement.step() == SQLITE_ROW)
+        results.append(RegistrableDomain::uncheckedCreateFromRegistrableDomainString(statement.getColumnText(0)));
+    
+    return results;
+}
 
+Vector<RegistrableDomain> ResourceLoadStatisticsDatabaseStore::domainsToBlockButKeepCookiesFor() const
+{
+    ASSERT(!RunLoop::isMain());
+
     Vector<RegistrableDomain> results;
-    SQLiteStatement statement(m_database, "SELECT registrableDomain FROM ObservedDomains WHERE isPrevalent = 1"_s);
+    SQLiteStatement statement(m_database, "SELECT registrableDomain FROM ObservedDomains WHERE isPrevalent = 1 AND hadUserInteraction = 1"_s);
     if (statement.prepare() != SQLITE_OK)
         return results;
     
@@ -1372,14 +1388,17 @@
 {
     ASSERT(!RunLoop::isMain());
 
-    auto domainsToBlock = this->domainsToBlock();
+    auto domainsToBlockAndDeleteCookiesFor = this->domainsToBlockAndDeleteCookiesFor();
+    auto domainsToBlockButKeepCookiesFor = this->domainsToBlockButKeepCookiesFor();
 
-    if (domainsToBlock.isEmpty()) {
+    if (domainsToBlockAndDeleteCookiesFor.isEmpty() && domainsToBlockButKeepCookiesFor.isEmpty()) {
         completionHandler();
         return;
     }
 
-    if (debugLoggingEnabled() && !domainsToBlock.isEmpty())
+    RegistrableDomainsToBlockCookiesFor domainsToBlock { domainsToBlockAndDeleteCookiesFor, domainsToBlockButKeepCookiesFor };
+
+    if (debugLoggingEnabled() && !domainsToBlockAndDeleteCookiesFor.isEmpty() && !domainsToBlockButKeepCookiesFor.isEmpty())
         debugLogDomainsInBatches("block", domainsToBlock);
 
     RunLoop::main().dispatch([weakThis = makeWeakPtr(*this), store = makeRef(store()), domainsToBlock = crossThreadCopy(domainsToBlock), completionHandler = WTFMove(completionHandler)] () mutable {

Modified: trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.h (248639 => 248640)


--- trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.h	2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.h	2019-08-13 22:34:29 UTC (rev 248640)
@@ -117,7 +117,8 @@
 #endif
     void updateLastSeen(const RegistrableDomain&, WallTime);
     void setUserInteraction(const RegistrableDomain&, bool hadUserInteraction, WallTime);
-    Vector<RegistrableDomain> domainsToBlock() const;
+    Vector<RegistrableDomain> domainsToBlockAndDeleteCookiesFor() const;
+    Vector<RegistrableDomain> domainsToBlockButKeepCookiesFor() const;
 
     struct PrevalentDomainData {
         unsigned domainID;

Modified: trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsMemoryStore.cpp (248639 => 248640)


--- trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsMemoryStore.cpp	2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsMemoryStore.cpp	2019-08-13 22:34:29 UTC (rev 248640)
@@ -712,8 +712,9 @@
 
     removeAllStorageAccess([callbackAggregator = callbackAggregator.copyRef()] { });
 
-    auto primaryDomainsToBlock = ensurePrevalentResourcesForDebugMode();
-    updateCookieBlockingForDomains(primaryDomainsToBlock, [callbackAggregator = callbackAggregator.copyRef()] { });
+    auto registrableDomainsToBlockAndDeleteCookiesFor = ensurePrevalentResourcesForDebugMode();
+    RegistrableDomainsToBlockCookiesFor domainsToBlock { registrableDomainsToBlockAndDeleteCookiesFor, { } };
+    updateCookieBlockingForDomains(domainsToBlock, [callbackAggregator = callbackAggregator.copyRef()] { });
 }
 
 bool ResourceLoadStatisticsMemoryStore::wasAccessedAsFirstPartyDueToUserInteraction(const ResourceLoadStatistics& current, const ResourceLoadStatistics& updated) const
@@ -761,18 +762,25 @@
 {
     ASSERT(!RunLoop::isMain());
 
-    Vector<RegistrableDomain> domainsToBlock;
+    Vector<RegistrableDomain> domainsToBlockAndDeleteCookiesFor;
+    Vector<RegistrableDomain> domainsToBlockButKeepCookiesFor;
     for (auto& resourceStatistic : m_resourceStatisticsMap.values()) {
-        if (resourceStatistic.isPrevalentResource)
-            domainsToBlock.append(resourceStatistic.registrableDomain);
+        if (resourceStatistic.isPrevalentResource) {
+            if (hasHadUnexpiredRecentUserInteraction(resourceStatistic, OperatingDatesWindow::Long))
+                domainsToBlockButKeepCookiesFor.append(resourceStatistic.registrableDomain);
+            else
+                domainsToBlockAndDeleteCookiesFor.append(resourceStatistic.registrableDomain);
+        }
     }
 
-    if (domainsToBlock.isEmpty() && !debugModeEnabled()) {
+    if (domainsToBlockAndDeleteCookiesFor.isEmpty() && domainsToBlockButKeepCookiesFor.isEmpty() && !debugModeEnabled()) {
         completionHandler();
         return;
     }
 
-    if (debugLoggingEnabled() && !domainsToBlock.isEmpty())
+    RegistrableDomainsToBlockCookiesFor domainsToBlock { domainsToBlockAndDeleteCookiesFor, domainsToBlockButKeepCookiesFor };
+
+    if (debugLoggingEnabled() && !domainsToBlockAndDeleteCookiesFor.isEmpty() && !domainsToBlockButKeepCookiesFor.isEmpty())
         debugLogDomainsInBatches("block", domainsToBlock);
 
     RunLoop::main().dispatch([weakThis = makeWeakPtr(*this), store = makeRef(store()), domainsToBlock = crossThreadCopy(domainsToBlock), completionHandler = WTFMove(completionHandler)] () mutable {

Modified: trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsStore.cpp (248639 => 248640)


--- trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsStore.cpp	2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsStore.cpp	2019-08-13 22:34:29 UTC (rev 248640)
@@ -413,7 +413,7 @@
         m_lastTimeDataRecordsWereRemoved = MonotonicTime::now();
 }
 
-void ResourceLoadStatisticsStore::updateCookieBlockingForDomains(const Vector<RegistrableDomain>& domainsToBlock, CompletionHandler<void()>&& completionHandler)
+void ResourceLoadStatisticsStore::updateCookieBlockingForDomains(const RegistrableDomainsToBlockCookiesFor& domainsToBlock, CompletionHandler<void()>&& completionHandler)
 {
     ASSERT(!RunLoop::isMain());
     
@@ -571,8 +571,11 @@
     updateClientSideCookiesAgeCap();
 }
 
-void ResourceLoadStatisticsStore::debugLogDomainsInBatches(const char* action, const Vector<RegistrableDomain>& domains)
+void ResourceLoadStatisticsStore::debugLogDomainsInBatches(const char* action, const RegistrableDomainsToBlockCookiesFor& domainsToBlock)
 {
+    Vector<RegistrableDomain> domains;
+    domains.appendVector(domainsToBlock.domainsToBlockAndDeleteCookiesFor);
+    domains.appendVector(domainsToBlock.domainsToBlockButKeepCookiesFor);
     static const auto maxNumberOfDomainsInOneLogStatement = 50;
     if (domains.isEmpty())
         return;

Modified: trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsStore.h (248639 => 248640)


--- trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsStore.h	2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsStore.h	2019-08-13 22:34:29 UTC (rev 248640)
@@ -98,7 +98,7 @@
     virtual bool isEmpty() const = 0;
 
     virtual void updateCookieBlocking(CompletionHandler<void()>&&) = 0;
-    void updateCookieBlockingForDomains(const Vector<RegistrableDomain>& domainsToBlock, CompletionHandler<void()>&&);
+    void updateCookieBlockingForDomains(const RegistrableDomainsToBlockCookiesFor&, CompletionHandler<void()>&&);
     void clearBlockingStateForDomains(const Vector<RegistrableDomain>& domains, CompletionHandler<void()>&&);
 
     void includeTodayAsOperatingDateIfNecessary();
@@ -186,7 +186,7 @@
 protected:
     static unsigned computeImportance(const WebCore::ResourceLoadStatistics&);
     static Vector<OperatingDate> mergeOperatingDates(const Vector<OperatingDate>& existingDates, Vector<OperatingDate>&& newDates);
-    static void debugLogDomainsInBatches(const char* action, const Vector<RegistrableDomain>& domains);
+    static void debugLogDomainsInBatches(const char* action, const RegistrableDomainsToBlockCookiesFor&);
 
     ResourceLoadStatisticsStore(WebResourceLoadStatisticsStore&, WorkQueue&, ShouldIncludeLocalhost);
     

Modified: trunk/Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsStore.cpp (248639 => 248640)


--- trunk/Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsStore.cpp	2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsStore.cpp	2019-08-13 22:34:29 UTC (rev 248640)
@@ -840,38 +840,6 @@
     });
 }
 
-void WebResourceLoadStatisticsStore::scheduleCookieBlockingUpdateForDomains(const Vector<RegistrableDomain>& domainsToBlock, CompletionHandler<void()>&& completionHandler)
-{
-    // Helper function used by testing system. Should only be called from the main thread.
-    ASSERT(RunLoop::isMain());
-    postTask([this, domainsToBlock = crossThreadCopy(domainsToBlock), completionHandler = WTFMove(completionHandler)]() mutable {
-        if (!m_statisticsStore) {
-            postTaskReply(WTFMove(completionHandler));
-            return;
-        }
-
-        m_statisticsStore->updateCookieBlockingForDomains(domainsToBlock, [completionHandler = WTFMove(completionHandler)]() mutable {
-            postTaskReply(WTFMove(completionHandler));
-        });
-    });
-}
-
-void WebResourceLoadStatisticsStore::scheduleClearBlockingStateForDomains(const Vector<RegistrableDomain>& domains, CompletionHandler<void()>&& completionHandler)
-{
-    // Helper function used by testing system. Should only be called from the main thread.
-    ASSERT(RunLoop::isMain());
-    postTask([this, domains = crossThreadCopy(domains), completionHandler = WTFMove(completionHandler)]() mutable {
-        if (!m_statisticsStore) {
-            postTaskReply(WTFMove(completionHandler));
-            return;
-        }
-
-        m_statisticsStore->clearBlockingStateForDomains(domains, [completionHandler = WTFMove(completionHandler)]() mutable {
-            postTaskReply(WTFMove(completionHandler));
-        });
-    });
-}
-
 void WebResourceLoadStatisticsStore::scheduleClearInMemoryAndPersistent(ShouldGrandfatherStatistics shouldGrandfather, CompletionHandler<void()>&& completionHandler)
 {
     ASSERT(RunLoop::isMain());
@@ -956,13 +924,15 @@
     completionHandler();
 }
 
-void WebResourceLoadStatisticsStore::callUpdatePrevalentDomainsToBlockCookiesForHandler(const Vector<RegistrableDomain>& domainsToBlock, CompletionHandler<void()>&& completionHandler)
+void WebResourceLoadStatisticsStore::callUpdatePrevalentDomainsToBlockCookiesForHandler(const RegistrableDomainsToBlockCookiesFor& domainsToBlock, CompletionHandler<void()>&& completionHandler)
 {
     ASSERT(RunLoop::isMain());
 
     if (m_networkSession) {
-        if (auto* storageSession = m_networkSession->networkStorageSession())
-            storageSession->setPrevalentDomainsToBlockCookiesFor(domainsToBlock);
+        if (auto* storageSession = m_networkSession->networkStorageSession()) {
+            storageSession->setPrevalentDomainsToBlockAndDeleteCookiesFor(domainsToBlock.domainsToBlockAndDeleteCookiesFor);
+            storageSession->setPrevalentDomainsToBlockButKeepCookiesFor(domainsToBlock.domainsToBlockButKeepCookiesFor);
+        }
     }
 
     completionHandler();

Modified: trunk/Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsStore.h (248639 => 248640)


--- trunk/Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsStore.h	2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsStore.h	2019-08-13 22:34:29 UTC (rev 248640)
@@ -63,11 +63,17 @@
 enum class ShouldGrandfatherStatistics : bool;
 enum class ShouldIncludeLocalhost : bool { No, Yes };
 enum class EnableResourceLoadStatisticsDebugMode : bool { No, Yes };
+enum class EnableResourceLoadStatisticsNSURLSessionSwitching : bool { No, Yes };
 enum class WebsiteDataToRemove : uint8_t {
     All,
     AllButHttpOnlyCookies,
     AllButCookies
 };
+struct RegistrableDomainsToBlockCookiesFor {
+    Vector<WebCore::RegistrableDomain> domainsToBlockAndDeleteCookiesFor;
+    Vector<WebCore::RegistrableDomain> domainsToBlockButKeepCookiesFor;
+    RegistrableDomainsToBlockCookiesFor isolatedCopy() const { return { domainsToBlockAndDeleteCookiesFor.isolatedCopy(), domainsToBlockButKeepCookiesFor.isolatedCopy() }; }
+};
 
 class WebResourceLoadStatisticsStore final : public ThreadSafeRefCounted<WebResourceLoadStatisticsStore, WTF::DestructionThread::Main> {
 public:
@@ -168,7 +174,7 @@
     void logTestingEvent(const String&);
     void callGrantStorageAccessHandler(const SubFrameDomain&, const TopFrameDomain&, Optional<FrameID>, WebCore::PageIdentifier, CompletionHandler<void(StorageAccessWasGranted)>&&);
     void removeAllStorageAccess(CompletionHandler<void()>&&);
-    void callUpdatePrevalentDomainsToBlockCookiesForHandler(const Vector<RegistrableDomain>&, CompletionHandler<void()>&&);
+    void callUpdatePrevalentDomainsToBlockCookiesForHandler(const RegistrableDomainsToBlockCookiesFor&, CompletionHandler<void()>&&);
     void callRemoveDomainsHandler(const Vector<RegistrableDomain>&);
     void callHasStorageAccessForFrameHandler(const SubFrameDomain&, const TopFrameDomain&, FrameID, WebCore::PageIdentifier, CompletionHandler<void(bool)>&&);
 

Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp (248639 => 248640)


--- trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp	2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp	2019-08-13 22:34:29 UTC (rev 248640)
@@ -636,7 +636,7 @@
 void NetworkProcess::updatePrevalentDomainsToBlockCookiesFor(PAL::SessionID sessionID, const Vector<RegistrableDomain>& domainsToBlock, CompletionHandler<void()>&& completionHandler)
 {
     if (auto* networkStorageSession = storageSession(sessionID))
-        networkStorageSession->setPrevalentDomainsToBlockCookiesFor(domainsToBlock);
+        networkStorageSession->setPrevalentDomainsToBlockAndDeleteCookiesFor(domainsToBlock);
     completionHandler();
 }
 
@@ -780,6 +780,7 @@
 void NetworkProcess::scheduleClearInMemoryAndPersistent(PAL::SessionID sessionID, Optional<WallTime> modifiedSince, ShouldGrandfatherStatistics shouldGrandfather, CompletionHandler<void()>&& completionHandler)
 {
     if (auto* networkSession = this->networkSession(sessionID)) {
+        networkSession->clearIsolatedSessions();
         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics()) {
             if (modifiedSince)
                 resourceLoadStatistics->scheduleClearInMemoryAndPersistent(modifiedSince.value(), shouldGrandfather, WTFMove(completionHandler));
@@ -1235,6 +1236,14 @@
         ASSERT_NOT_REACHED();
     completionHandler();
 }
+
+void NetworkProcess::hasIsolatedSession(PAL::SessionID sessionID, const WebCore::RegistrableDomain& domain, CompletionHandler<void(bool)>&& completionHandler) const
+{
+    bool result = false;
+    if (auto* networkSession = this->networkSession(sessionID))
+        result = networkSession->hasIsolatedSession(domain);
+    completionHandler(result);
+}
 #endif // ENABLE(RESOURCE_LOAD_STATISTICS)
 
 bool NetworkProcess::sessionIsControlledByAutomation(PAL::SessionID sessionID) const

Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcess.h (248639 => 248640)


--- trunk/Source/WebKit/NetworkProcess/NetworkProcess.h	2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcess.h	2019-08-13 22:34:29 UTC (rev 248640)
@@ -259,6 +259,7 @@
     void didCommitCrossSiteLoadWithDataTransfer(PAL::SessionID, const RegistrableDomain& fromDomain, const RegistrableDomain& toDomain, OptionSet<WebCore::CrossSiteNavigationDataTransfer::Flag>, WebCore::PageIdentifier);
     void setCrossSiteLoadWithLinkDecorationForTesting(PAL::SessionID, const RegistrableDomain& fromDomain, const RegistrableDomain& toDomain, CompletionHandler<void()>&&);
     void resetCrossSiteLoadsWithLinkDecorationForTesting(PAL::SessionID, CompletionHandler<void()>&&);
+    void hasIsolatedSession(PAL::SessionID, const WebCore::RegistrableDomain&, CompletionHandler<void(bool)>&&) const;
 #endif
 
     using CacheStorageRootPathCallback = CompletionHandler<void(String&&)>;

Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcess.messages.in (248639 => 248640)


--- trunk/Source/WebKit/NetworkProcess/NetworkProcess.messages.in	2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcess.messages.in	2019-08-13 22:34:29 UTC (rev 248640)
@@ -137,6 +137,7 @@
     SetCrossSiteLoadWithLinkDecorationForTesting(PAL::SessionID sessionID, WebCore::RegistrableDomain fromDomain, WebCore::RegistrableDomain toDomain) -> () Async
     ResetCrossSiteLoadsWithLinkDecorationForTesting(PAL::SessionID sessionID) -> () Async
     DeleteCookiesForTesting(PAL::SessionID sessionID, WebCore::RegistrableDomain domain, bool includeHttpOnlyCookies) -> () Async
+    HasIsolatedSession(PAL::SessionID sessionID, WebCore::RegistrableDomain domain) -> (bool hasIsolatedSession) Async
 #endif
 
     SetSessionIsControlledByAutomation(PAL::SessionID sessionID, bool controlled);

Modified: trunk/Source/WebKit/NetworkProcess/NetworkSession.h (248639 => 248640)


--- trunk/Source/WebKit/NetworkProcess/NetworkSession.h	2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Source/WebKit/NetworkProcess/NetworkSession.h	2019-08-13 22:34:29 UTC (rev 248640)
@@ -93,6 +93,9 @@
     void notifyPageStatisticsTelemetryFinished(unsigned totalPrevalentResources, unsigned totalPrevalentResourcesWithUserInteraction, unsigned top3SubframeUnderTopFrameOrigins);
     bool enableResourceLoadStatisticsLogTestingEvent() const { return m_enableResourceLoadStatisticsLogTestingEvent; }
     void setResourceLoadStatisticsLogTestingEvent(bool log) { m_enableResourceLoadStatisticsLogTestingEvent = log; }
+    bool shouldIsolateSessionsForPrevalentTopFrames() const { return m_enableResourceLoadStatisticsNSURLSessionSwitching == EnableResourceLoadStatisticsNSURLSessionSwitching::Yes; }
+    virtual bool hasIsolatedSession(const WebCore::RegistrableDomain) const { return false; }
+    virtual void clearIsolatedSessions() { }
 #endif
     void storeAdClickAttribution(WebCore::AdClickAttribution&&);
     void handleAdClickAttributionConversion(WebCore::AdClickAttribution::Conversion&&, const URL& requestURL, const WebCore::ResourceRequest& redirectRequest);
@@ -133,6 +136,7 @@
     ShouldIncludeLocalhost m_shouldIncludeLocalhostInResourceLoadStatistics { ShouldIncludeLocalhost::Yes };
     EnableResourceLoadStatisticsDebugMode m_enableResourceLoadStatisticsDebugMode { EnableResourceLoadStatisticsDebugMode::No };
     WebCore::RegistrableDomain m_resourceLoadStatisticsManualPrevalentResource;
+    EnableResourceLoadStatisticsNSURLSessionSwitching m_enableResourceLoadStatisticsNSURLSessionSwitching { EnableResourceLoadStatisticsNSURLSessionSwitching::No };
     bool m_enableResourceLoadStatisticsLogTestingEvent;
 #endif
     UniqueRef<AdClickAttributionManager> m_adClickAttribution;

Modified: trunk/Source/WebKit/NetworkProcess/NetworkSessionCreationParameters.cpp (248639 => 248640)


--- trunk/Source/WebKit/NetworkProcess/NetworkSessionCreationParameters.cpp	2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Source/WebKit/NetworkProcess/NetworkSessionCreationParameters.cpp	2019-08-13 22:34:29 UTC (rev 248640)
@@ -50,7 +50,7 @@
 #if USE(CURL)
         , { }, { }
 #endif
-        , { }, { }, false, false, { }, { }, { }, { }, { }, { }, { }, { }, { }
+        , { }, { }, false, false, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }
     };
 }
 
@@ -84,6 +84,7 @@
     encoder << shouldIncludeLocalhostInResourceLoadStatistics;
     encoder << enableResourceLoadStatisticsDebugMode;
     encoder << resourceLoadStatisticsManualPrevalentResource;
+    encoder << enableResourceLoadStatisticsNSURLSessionSwitching;
 
     encoder << localStorageDirectory << localStorageDirectoryExtensionHandle;
     encoder << networkCacheDirectory << networkCacheDirectoryExtensionHandle;
@@ -208,6 +209,11 @@
     if (!resourceLoadStatisticsManualPrevalentResource)
         return WTF::nullopt;
 
+    Optional<bool> enableResourceLoadStatisticsNSURLSessionSwitching;
+    decoder >> enableResourceLoadStatisticsNSURLSessionSwitching;
+    if (!enableResourceLoadStatisticsNSURLSessionSwitching)
+        return WTF::nullopt;
+    
     Optional<String> localStorageDirectory;
     decoder >> localStorageDirectory;
     if (!localStorageDirectory)
@@ -266,6 +272,7 @@
         , WTFMove(*enableResourceLoadStatisticsLogTestingEvent)
         , WTFMove(*shouldIncludeLocalhostInResourceLoadStatistics)
         , WTFMove(*enableResourceLoadStatisticsDebugMode)
+        , WTFMove(*enableResourceLoadStatisticsNSURLSessionSwitching)
         , WTFMove(*deviceManagementRestrictionsEnabled)
         , WTFMove(*allLoadsBlockedByDeviceManagementRestrictionsForTesting)
         , WTFMove(*resourceLoadStatisticsManualPrevalentResource)

Modified: trunk/Source/WebKit/NetworkProcess/NetworkSessionCreationParameters.h (248639 => 248640)


--- trunk/Source/WebKit/NetworkProcess/NetworkSessionCreationParameters.h	2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Source/WebKit/NetworkProcess/NetworkSessionCreationParameters.h	2019-08-13 22:34:29 UTC (rev 248640)
@@ -87,6 +87,7 @@
     bool enableResourceLoadStatisticsLogTestingEvent { false };
     bool shouldIncludeLocalhostInResourceLoadStatistics { true };
     bool enableResourceLoadStatisticsDebugMode { false };
+    bool enableResourceLoadStatisticsNSURLSessionSwitching { true };
     bool deviceManagementRestrictionsEnabled { false };
     bool allLoadsBlockedByDeviceManagementRestrictionsForTesting { false };
     WebCore::RegistrableDomain resourceLoadStatisticsManualPrevalentResource { };

Modified: trunk/Source/WebKit/NetworkProcess/cocoa/NetworkDataTaskCocoa.mm (248639 => 248640)


--- trunk/Source/WebKit/NetworkProcess/cocoa/NetworkDataTaskCocoa.mm	2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Source/WebKit/NetworkProcess/cocoa/NetworkDataTaskCocoa.mm	2019-08-13 22:34:29 UTC (rev 248640)
@@ -38,6 +38,7 @@
 #import <WebCore/AuthenticationChallenge.h>
 #import <WebCore/NetworkStorageSession.h>
 #import <WebCore/NotImplemented.h>
+#import <WebCore/RegistrableDomain.h>
 #import <WebCore/ResourceRequest.h>
 #import <pal/spi/cf/CFNetworkSPI.h>
 #import <wtf/BlockPtr.h>
@@ -205,9 +206,15 @@
 #endif
 
     bool shouldBlockCookies = false;
+    bool needsIsolatedSession = false;
+    auto firstParty = WebCore::RegistrableDomain(request.firstPartyForCookies());
 #if ENABLE(RESOURCE_LOAD_STATISTICS)
-    shouldBlockCookies = storedCredentialsPolicy == WebCore::StoredCredentialsPolicy::EphemeralStatelessCookieless
-        || (session.networkStorageSession() && session.networkStorageSession()->shouldBlockCookies(request, frameID, pageID));
+    shouldBlockCookies = storedCredentialsPolicy == WebCore::StoredCredentialsPolicy::EphemeralStatelessCookieless;
+    if (auto* networkStorageSession = session.networkStorageSession()) {
+        if (!shouldBlockCookies)
+            shouldBlockCookies = networkStorageSession->shouldBlockCookies(request, frameID, pageID);
+        needsIsolatedSession = session.shouldIsolateSessionsForPrevalentTopFrames() && networkStorageSession->shouldBlockThirdPartyCookiesButKeepFirstPartyCookiesFor(firstParty);
+    }
 #endif
     restrictRequestReferrerToOriginIfNeeded(request, shouldBlockCookies);
 
@@ -215,23 +222,22 @@
     applySniffingPoliciesAndBindRequestToInferfaceIfNeeded(nsRequest, shouldContentSniff == WebCore::ContentSniffingPolicy::SniffContent && !url.isLocalFile(), shouldContentEncodingSniff == WebCore::ContentEncodingSniffingPolicy::Sniff);
 
     auto& cocoaSession = static_cast<NetworkSessionCocoa&>(*m_session);
+    if (needsIsolatedSession)
+        m_task = [cocoaSession.isolatedSession(storedCredentialsPolicy, firstParty) dataTaskWithRequest:nsRequest];
+    else
+        m_task = [cocoaSession.session(storedCredentialsPolicy) dataTaskWithRequest:nsRequest];
     switch (storedCredentialsPolicy) {
     case WebCore::StoredCredentialsPolicy::Use:
-        m_task = [cocoaSession.m_sessionWithCredentialStorage dataTaskWithRequest:nsRequest];
         ASSERT(!cocoaSession.m_dataTaskMapWithCredentials.contains([m_task taskIdentifier]));
         cocoaSession.m_dataTaskMapWithCredentials.add([m_task taskIdentifier], this);
         LOG(NetworkSession, "%llu Creating stateful NetworkDataTask with URL %s", [m_task taskIdentifier], nsRequest.URL.absoluteString.UTF8String);
         break;
     case WebCore::StoredCredentialsPolicy::DoNotUse:
-        m_task = [cocoaSession.m_statelessSession dataTaskWithRequest:nsRequest];
         ASSERT(!cocoaSession.m_dataTaskMapWithoutState.contains([m_task taskIdentifier]));
         cocoaSession.m_dataTaskMapWithoutState.add([m_task taskIdentifier], this);
         LOG(NetworkSession, "%llu Creating stateless NetworkDataTask with URL %s", [m_task taskIdentifier], nsRequest.URL.absoluteString.UTF8String);
         break;
     case WebCore::StoredCredentialsPolicy::EphemeralStatelessCookieless:
-        if (!cocoaSession.m_ephemeralStatelessCookielessSession)
-            cocoaSession.initializeEphemeralStatelessCookielessSession();
-        m_task = [cocoaSession.m_ephemeralStatelessCookielessSession dataTaskWithRequest:nsRequest];
         ASSERT(!cocoaSession.m_dataTaskMapEphemeralStatelessCookieless.contains([m_task taskIdentifier]));
         cocoaSession.m_dataTaskMapEphemeralStatelessCookieless.add([m_task taskIdentifier], this);
         LOG(NetworkSession, "%llu Creating ephemeral, stateless, cookieless NetworkDataTask with URL %s", [m_task taskIdentifier], nsRequest.URL.absoluteString.UTF8String);

Modified: trunk/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.h (248639 => 248640)


--- trunk/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.h	2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.h	2019-08-13 22:34:29 UTC (rev 248640)
@@ -38,7 +38,9 @@
 #include "NetworkSession.h"
 #include "WebSocketTask.h"
 #include <WebCore/NetworkLoadMetrics.h>
+#include <WebCore/RegistrableDomain.h>
 #include <wtf/HashMap.h>
+#include <wtf/Seconds.h>
 
 namespace WebKit {
 
@@ -83,6 +85,11 @@
 
     CFDictionaryRef proxyConfiguration() const { return m_proxyConfiguration.get(); }
 
+    NSURLSession* session(WebCore::StoredCredentialsPolicy);
+    NSURLSession* isolatedSession(WebCore::StoredCredentialsPolicy, const WebCore::RegistrableDomain);
+    bool hasIsolatedSession(const WebCore::RegistrableDomain) const override;
+    void clearIsolatedSessions() override;
+
 private:
     void invalidateAndCancel() override;
     void clearCredentials() override;
@@ -103,6 +110,16 @@
     HashMap<NetworkDataTaskCocoa::TaskIdentifier, WebSocketTask*> m_webSocketDataTaskMap;
 #endif
 
+    struct IsolatedSession {
+        RetainPtr<NSURLSession> sessionWithCredentialStorage;
+        RetainPtr<WKNetworkSessionDelegate> sessionWithCredentialStorageDelegate;
+        RetainPtr<NSURLSession> statelessSession;
+        RetainPtr<WKNetworkSessionDelegate> statelessSessionDelegate;
+        WallTime lastUsed;
+    };
+
+    HashMap<WebCore::RegistrableDomain, IsolatedSession> m_isolatedSessions;
+
     RetainPtr<NSURLSession> m_sessionWithCredentialStorage;
     RetainPtr<WKNetworkSessionDelegate> m_sessionWithCredentialStorageDelegate;
     RetainPtr<NSURLSession> m_statelessSession;

Modified: trunk/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm (248639 => 248640)


--- trunk/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm	2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm	2019-08-13 22:34:29 UTC (rev 248640)
@@ -67,6 +67,8 @@
 CFStringRef const WebKit2HTTPProxyDefaultsKey = static_cast<CFStringRef>(@"WebKit2HTTPProxy");
 CFStringRef const WebKit2HTTPSProxyDefaultsKey = static_cast<CFStringRef>(@"WebKit2HTTPSProxy");
 
+constexpr unsigned maxNumberOfIsolatedSessions { 10 };
+
 static NSURLSessionResponseDisposition toNSURLSessionResponseDisposition(WebCore::PolicyAction disposition)
 {
     switch (disposition) {
@@ -1034,6 +1036,7 @@
     m_shouldIncludeLocalhostInResourceLoadStatistics = parameters.shouldIncludeLocalhostInResourceLoadStatistics ? ShouldIncludeLocalhost::Yes : ShouldIncludeLocalhost::No;
     m_enableResourceLoadStatisticsDebugMode = parameters.enableResourceLoadStatisticsDebugMode ? EnableResourceLoadStatisticsDebugMode::Yes : EnableResourceLoadStatisticsDebugMode::No;
     m_resourceLoadStatisticsManualPrevalentResource = parameters.resourceLoadStatisticsManualPrevalentResource;
+    m_enableResourceLoadStatisticsNSURLSessionSwitching = parameters.enableResourceLoadStatisticsNSURLSessionSwitching ? EnableResourceLoadStatisticsNSURLSessionSwitching::Yes : EnableResourceLoadStatisticsNSURLSessionSwitching::No;
     setResourceLoadStatisticsEnabled(parameters.enableResourceLoadStatistics);
 #endif
 
@@ -1068,6 +1071,75 @@
     m_ephemeralStatelessCookielessSession = [NSURLSession sessionWithConfiguration:configuration delegate:static_cast<id>(m_ephemeralStatelessCookielessSessionDelegate.get()) delegateQueue:[NSOperationQueue mainQueue]];
 }
 
+NSURLSession* NetworkSessionCocoa::session(WebCore::StoredCredentialsPolicy storedCredentialsPolicy)
+{
+    switch (storedCredentialsPolicy) {
+    case WebCore::StoredCredentialsPolicy::Use:
+        return m_sessionWithCredentialStorage.get();
+    case WebCore::StoredCredentialsPolicy::DoNotUse:
+        return m_statelessSession.get();
+    case WebCore::StoredCredentialsPolicy::EphemeralStatelessCookieless:
+        if (!m_ephemeralStatelessCookielessSession)
+            initializeEphemeralStatelessCookielessSession();
+        return m_ephemeralStatelessCookielessSession.get();
+    }
+}
+
+NSURLSession* NetworkSessionCocoa::isolatedSession(WebCore::StoredCredentialsPolicy storedCredentialsPolicy, const WebCore::RegistrableDomain firstPartyDomain)
+{
+    auto entry = m_isolatedSessions.ensure(firstPartyDomain, [this] {
+        IsolatedSession newEntry { };
+        newEntry.sessionWithCredentialStorageDelegate = adoptNS([[WKNetworkSessionDelegate alloc] initWithNetworkSession:*this withCredentials:true]);
+        newEntry.sessionWithCredentialStorage = [NSURLSession sessionWithConfiguration:m_sessionWithCredentialStorage.get().configuration delegate:static_cast<id>(newEntry.sessionWithCredentialStorageDelegate.get()) delegateQueue:[NSOperationQueue mainQueue]];
+
+        newEntry.statelessSessionDelegate = adoptNS([[WKNetworkSessionDelegate alloc] initWithNetworkSession:*this withCredentials:false]);
+        newEntry.statelessSession = [NSURLSession sessionWithConfiguration:m_statelessSession.get().configuration delegate:static_cast<id>(newEntry.statelessSessionDelegate.get()) delegateQueue:[NSOperationQueue mainQueue]];
+
+        return newEntry;
+    }).iterator->value;
+
+    entry.lastUsed = WallTime::now();
+
+    if (m_isolatedSessions.size() > maxNumberOfIsolatedSessions) {
+        WebCore::RegistrableDomain keyToRemove;
+        auto oldestTimestamp = WallTime::now();
+        for (auto& key : m_isolatedSessions.keys()) {
+            auto timestamp = m_isolatedSessions.get(key).lastUsed;
+            if (timestamp < oldestTimestamp) {
+                oldestTimestamp = timestamp;
+                keyToRemove = key;
+            }
+        }
+        LOG(NetworkSession, "About to remove isolated NSURLSession.");
+        m_isolatedSessions.remove(keyToRemove);
+    }
+
+    RELEASE_ASSERT(m_isolatedSessions.size() <= maxNumberOfIsolatedSessions);
+
+    switch (storedCredentialsPolicy) {
+    case WebCore::StoredCredentialsPolicy::Use:
+        LOG(NetworkSession, "Using isolated NSURLSession with credential storage.");
+        return entry.sessionWithCredentialStorage.get();
+    case WebCore::StoredCredentialsPolicy::DoNotUse:
+        LOG(NetworkSession, "Using isolated NSURLSession without credential storage.");
+        return entry.statelessSession.get();
+    case WebCore::StoredCredentialsPolicy::EphemeralStatelessCookieless:
+        if (!m_ephemeralStatelessCookielessSession)
+            initializeEphemeralStatelessCookielessSession();
+        return m_ephemeralStatelessCookielessSession.get();
+    }
+}
+
+bool NetworkSessionCocoa::hasIsolatedSession(const WebCore::RegistrableDomain domain) const
+{
+    return m_isolatedSessions.contains(domain);
+}
+
+void NetworkSessionCocoa::clearIsolatedSessions()
+{
+    m_isolatedSessions.clear();
+}
+
 void NetworkSessionCocoa::invalidateAndCancel()
 {
     NetworkSession::invalidateAndCancel();
@@ -1078,6 +1150,12 @@
     [m_sessionWithCredentialStorageDelegate sessionInvalidated];
     [m_statelessSessionDelegate sessionInvalidated];
     [m_ephemeralStatelessCookielessSessionDelegate sessionInvalidated];
+
+    for (auto& session : m_isolatedSessions.values()) {
+        [session.sessionWithCredentialStorage invalidateAndCancel];
+        [session.sessionWithCredentialStorageDelegate sessionInvalidated];
+    }
+    m_isolatedSessions.clear();
 }
 
 void NetworkSessionCocoa::clearCredentials()
@@ -1089,6 +1167,8 @@
     // FIXME: Use resetWithCompletionHandler instead.
     m_sessionWithCredentialStorage = [NSURLSession sessionWithConfiguration:m_sessionWithCredentialStorage.get().configuration delegate:static_cast<id>(m_sessionWithCredentialStorageDelegate.get()) delegateQueue:[NSOperationQueue mainQueue]];
     m_statelessSession = [NSURLSession sessionWithConfiguration:m_statelessSession.get().configuration delegate:static_cast<id>(m_statelessSessionDelegate.get()) delegateQueue:[NSOperationQueue mainQueue]];
+    for (auto& entry : m_isolatedSessions.values())
+        entry.session = [NSURLSession sessionWithConfiguration:entry.session.get().configuration delegate:static_cast<id>(entry.delegate.get()) delegateQueue:[NSOperationQueue mainQueue]];
 #endif
 }
 

Modified: trunk/Source/WebKit/Shared/WebPreferences.yaml (248639 => 248640)


--- trunk/Source/WebKit/Shared/WebPreferences.yaml	2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Source/WebKit/Shared/WebPreferences.yaml	2019-08-13 22:34:29 UTC (rev 248640)
@@ -1723,6 +1723,14 @@
   webcoreBinding: RuntimeEnabledFeatures
   category: experimental
 
+IsITPSessionSwitchingEnabled:
+  type: bool
+  defaultValue: true
+  humanReadableName: "ITP Session Switching"
+  humanReadableDescription: "Enable session switching for domains classified by ITP"
+  webcoreBinding: RuntimeEnabledFeatures
+  category: internal
+
 # Deprecated
 
 ICECandidateFilteringEnabled:

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


--- trunk/Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreRef.cpp	2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreRef.cpp	2019-08-13 22:34:29 UTC (rev 248640)
@@ -472,6 +472,17 @@
 #endif
 }
 
+void WKWebsiteDataStoreStatisticsHasIsolatedSession(WKWebsiteDataStoreRef dataStoreRef, WKStringRef host, void* context, WKWebsiteDataStoreStatisticsHasIsolatedSessionFunction callback)
+{
+#if ENABLE(RESOURCE_LOAD_STATISTICS)
+    WebKit::toImpl(dataStoreRef)->websiteDataStore().hasIsolatedSessionForTesting(URL(URL(), WebKit::toImpl(host)->string()), [context, callback](bool hasIsolatedSession) {
+        callback(hasIsolatedSession, context);
+    });
+#else
+    callback(false, context);
+#endif
+}
+
 void WKWebsiteDataStoreStatisticsResetToConsistentState(WKWebsiteDataStoreRef dataStoreRef, void* context, WKWebsiteDataStoreStatisticsResetToConsistentStateFunction completionHandler)
 {
 #if ENABLE(RESOURCE_LOAD_STATISTICS)

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


--- trunk/Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreRef.h	2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreRef.h	2019-08-13 22:34:29 UTC (rev 248640)
@@ -103,6 +103,8 @@
 WK_EXPORT void WKWebsiteDataStoreStatisticsHasLocalStorage(WKWebsiteDataStoreRef dataStoreRef, WKStringRef host, void* context, WKWebsiteDataStoreStatisticsHasLocalStorageFunction callback);
 typedef void (*WKWebsiteDataStoreSetStatisticsCacheMaxAgeCapFunction)(void* functionContext);
 WK_EXPORT void WKWebsiteDataStoreSetStatisticsCacheMaxAgeCap(WKWebsiteDataStoreRef dataStoreRef, double seconds, void* context, WKWebsiteDataStoreSetStatisticsCacheMaxAgeCapFunction);
+typedef void (*WKWebsiteDataStoreStatisticsHasIsolatedSessionFunction)(bool hasIsolatedSession, void* functionContext);
+WK_EXPORT void WKWebsiteDataStoreStatisticsHasIsolatedSession(WKWebsiteDataStoreRef dataStoreRef, WKStringRef host, void* context, WKWebsiteDataStoreStatisticsHasIsolatedSessionFunction callback);
 typedef void (*WKWebsiteDataStoreStatisticsResetToConsistentStateFunction)(void* functionContext);
 WK_EXPORT void WKWebsiteDataStoreStatisticsResetToConsistentState(WKWebsiteDataStoreRef dataStoreRef, void* context, WKWebsiteDataStoreStatisticsResetToConsistentStateFunction completionHandler);
 

Modified: trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp (248639 => 248640)


--- trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp	2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp	2019-08-13 22:34:29 UTC (rev 248640)
@@ -974,6 +974,16 @@
     });
 }
 
+void NetworkProcessProxy::hasIsolatedSession(PAL::SessionID sessionID, const RegistrableDomain& domain, CompletionHandler<void(bool)>&& completionHandler)
+{
+    if (!canSendMessage()) {
+        completionHandler(false);
+        return;
+    }
+    
+    sendWithAsyncReply(Messages::NetworkProcess::HasIsolatedSession(sessionID, domain), WTFMove(completionHandler));
+}
+
 #endif // ENABLE(RESOURCE_LOAD_STATISTICS)
 
 void NetworkProcessProxy::sendProcessWillSuspendImminently()

Modified: trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.h (248639 => 248640)


--- trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.h	2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.h	2019-08-13 22:34:29 UTC (rev 248640)
@@ -150,6 +150,7 @@
     void resetCrossSiteLoadsWithLinkDecorationForTesting(PAL::SessionID, CompletionHandler<void()>&&);
     void deleteCookiesForTesting(PAL::SessionID, const RegistrableDomain&, bool includeHttpOnlyCookies, CompletionHandler<void()>&&);
     void deleteWebsiteDataInUIProcessForRegistrableDomains(PAL::SessionID, OptionSet<WebsiteDataType>, OptionSet<WebsiteDataFetchOption>, Vector<RegistrableDomain>, CompletionHandler<void(HashSet<WebCore::RegistrableDomain>&&)>&&);
+    void hasIsolatedSession(PAL::SessionID, const RegistrableDomain&, CompletionHandler<void(bool)>&&);
 #endif
 
     void processReadyToSuspend();

Modified: trunk/Source/WebKit/UIProcess/WebsiteData/Cocoa/WebsiteDataStoreCocoa.mm (248639 => 248640)


--- trunk/Source/WebKit/UIProcess/WebsiteData/Cocoa/WebsiteDataStoreCocoa.mm	2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Source/WebKit/UIProcess/WebsiteData/Cocoa/WebsiteDataStoreCocoa.mm	2019-08-13 22:34:29 UTC (rev 248640)
@@ -32,6 +32,7 @@
 #import "WebsiteDataStoreParameters.h"
 #import <WebCore/RegistrableDomain.h>
 #import <WebCore/RuntimeApplicationChecks.h>
+#import <WebCore/RuntimeEnabledFeatures.h>
 #import <WebCore/SearchPopupMenuCocoa.h>
 #import <pal/spi/cf/CFNetworkSPI.h>
 #import <wtf/FileSystem.h>
@@ -66,6 +67,7 @@
     NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
     bool shouldLogCookieInformation = false;
     bool enableResourceLoadStatisticsDebugMode = false;
+    bool enableResourceLoadStatisticsNSURLSessionSwitching = WebCore::RuntimeEnabledFeatures::sharedFeatures().isITPSessionSwitchingEnabled();
     WebCore::RegistrableDomain resourceLoadStatisticsManualPrevalentResource { };
 #if ENABLE(RESOURCE_LOAD_STATISTICS)
     enableResourceLoadStatisticsDebugMode = [defaults boolForKey:@"ITPDebugMode"];
@@ -137,6 +139,7 @@
         false,
         shouldIncludeLocalhostInResourceLoadStatistics,
         enableResourceLoadStatisticsDebugMode,
+        enableResourceLoadStatisticsNSURLSessionSwitching,
         m_configuration->deviceManagementRestrictionsEnabled(),
         m_configuration->allLoadsBlockedByDeviceManagementRestrictionsForTesting(),
         WTFMove(resourceLoadStatisticsManualPrevalentResource),

Modified: trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp (248639 => 248640)


--- trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp	2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp	2019-08-13 22:34:29 UTC (rev 248640)
@@ -1684,6 +1684,18 @@
     }
     ASSERT(!completionHandler);
 }
+
+void WebsiteDataStore::hasIsolatedSessionForTesting(const URL& url, CompletionHandler<void(bool)>&& completionHandler) const
+{
+    for (auto& processPool : processPools()) {
+        if (auto* networkProcess = processPool->networkProcess()) {
+            networkProcess->hasIsolatedSession(m_sessionID, WebCore::RegistrableDomain { url }, WTFMove(completionHandler));
+            ASSERT(processPools().size() == 1);
+            break;
+        }
+    }
+    ASSERT(!completionHandler);
+}
 #endif // ENABLE(RESOURCE_LOAD_STATISTICS)
 
 void WebsiteDataStore::setCacheMaxAgeCapForPrevalentResources(Seconds seconds, CompletionHandler<void()>&& completionHandler)

Modified: trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h (248639 => 248640)


--- trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h	2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h	2019-08-13 22:34:29 UTC (rev 248640)
@@ -179,6 +179,7 @@
     void resetCrossSiteLoadsWithLinkDecorationForTesting(CompletionHandler<void()>&&);
     void deleteCookiesForTesting(const URL&, bool includeHttpOnlyCookies, CompletionHandler<void()>&&);
     void hasLocalStorageForTesting(const URL&, CompletionHandler<void(bool)>&&) const;
+    void hasIsolatedSessionForTesting(const URL&, CompletionHandler<void(bool)>&&) const;
 #endif
     void setCacheMaxAgeCapForPrevalentResources(Seconds, CompletionHandler<void()>&&);
     void resetCacheMaxAgeCapForPrevalentResources(CompletionHandler<void()>&&);

Modified: trunk/Tools/ChangeLog (248639 => 248640)


--- trunk/Tools/ChangeLog	2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Tools/ChangeLog	2019-08-13 22:34:29 UTC (rev 248640)
@@ -1,3 +1,24 @@
+2019-08-13  John Wilander  <wilan...@apple.com>
+
+        Resource Load Statistics: Switch NSURLSession on top navigation to prevalent resource with user interaction
+        https://bugs.webkit.org/show_bug.cgi?id=200642
+        <rdar://problem/53962073>
+
+        Reviewed by Alex Christensen.
+
+        This patch adds test infrastructure to query whether an origin has an
+        isolated NSURLSession or not.
+
+        * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl:
+        * WebKitTestRunner/InjectedBundle/TestRunner.cpp:
+        (WTR::TestRunner::hasStatisticsIsolatedSession):
+        * WebKitTestRunner/InjectedBundle/TestRunner.h:
+        * WebKitTestRunner/TestController.cpp:
+        (WTR::TestController::hasStatisticsIsolatedSession):
+        * WebKitTestRunner/TestController.h:
+        * WebKitTestRunner/TestInvocation.cpp:
+        (WTR::TestInvocation::didReceiveSynchronousMessageFromInjectedBundle):
+
 2019-08-13  Zhifei Fang  <zhifei_f...@apple.com>
 
         Update my status in contributors.json to committer.

Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl (248639 => 248640)


--- trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl	2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl	2019-08-13 22:34:29 UTC (rev 248640)
@@ -333,6 +333,7 @@
     boolean isStatisticsHasLocalStorage(DOMString hostName);
     void setStatisticsCacheMaxAgeCap(double seconds);
     void statisticsResetToConsistentState(object completionHandler);
+    boolean hasStatisticsIsolatedSession(DOMString hostName);
 
     // Injected bundle form client.
     void installTextDidChangeInTextFieldCallback(object callback);

Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp (248639 => 248640)


--- trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp	2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp	2019-08-13 22:34:29 UTC (rev 248640)
@@ -2066,6 +2066,16 @@
     WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr);
 }
 
+bool TestRunner::hasStatisticsIsolatedSession(JSStringRef hostName)
+{
+    auto messageName = adoptWK(WKStringCreateWithUTF8CString("HasStatisticsIsolatedSession"));
+    auto messageBody = adoptWK(WKStringCreateWithJSString(hostName));
+    WKTypeRef returnData = nullptr;
+    WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), messageName.get(), messageBody.get(), &returnData);
+    ASSERT(WKGetTypeID(returnData) == WKBooleanGetTypeID());
+    return WKBooleanGetValue(adoptWK(static_cast<WKBooleanRef>(returnData)).get());
+}
+
 void TestRunner::statisticsCallClearThroughWebsiteDataRemovalCallback()
 {
     callTestRunnerCallback(StatisticsDidClearThroughWebsiteDataRemovalCallbackID);

Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h (248639 => 248640)


--- trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h	2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h	2019-08-13 22:34:29 UTC (rev 248640)
@@ -431,6 +431,7 @@
     void statisticsCallClearThroughWebsiteDataRemovalCallback();
     bool isStatisticsHasLocalStorage(JSStringRef hostName);
     void setStatisticsCacheMaxAgeCap(double seconds);
+    bool hasStatisticsIsolatedSession(JSStringRef hostName);
     void statisticsResetToConsistentState(JSValueRef completionHandler);
     void statisticsCallDidResetToConsistentStateCallback();
 

Modified: trunk/Tools/WebKitTestRunner/TestController.cpp (248639 => 248640)


--- trunk/Tools/WebKitTestRunner/TestController.cpp	2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Tools/WebKitTestRunner/TestController.cpp	2019-08-13 22:34:29 UTC (rev 248640)
@@ -3511,6 +3511,15 @@
     runUntil(context.done, noTimeout);
 }
 
+bool TestController::hasStatisticsIsolatedSession(WKStringRef host)
+{
+    auto* dataStore = WKContextGetWebsiteDataStore(platformContext());
+    ResourceStatisticsCallbackContext context(*this);
+    WKWebsiteDataStoreStatisticsHasIsolatedSession(dataStore, host, &context, resourceStatisticsBooleanResultCallback);
+    runUntil(context.done, noTimeout);
+    return context.result;
+}
+
 void TestController::statisticsResetToConsistentState()
 {
     auto* dataStore = WKContextGetWebsiteDataStore(platformContext());

Modified: trunk/Tools/WebKitTestRunner/TestController.h (248639 => 248640)


--- trunk/Tools/WebKitTestRunner/TestController.h	2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Tools/WebKitTestRunner/TestController.h	2019-08-13 22:34:29 UTC (rev 248640)
@@ -244,6 +244,7 @@
     void statisticsDeleteCookiesForHost(WKStringRef host, bool includeHttpOnlyCookies);
     bool isStatisticsHasLocalStorage(WKStringRef hostName);
     void setStatisticsCacheMaxAgeCap(double seconds);
+    bool hasStatisticsIsolatedSession(WKStringRef hostName);
     void statisticsResetToConsistentState();
 
     void getAllStorageAccessEntries();

Modified: trunk/Tools/WebKitTestRunner/TestInvocation.cpp (248639 => 248640)


--- trunk/Tools/WebKitTestRunner/TestInvocation.cpp	2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Tools/WebKitTestRunner/TestInvocation.cpp	2019-08-13 22:34:29 UTC (rev 248640)
@@ -1462,6 +1462,15 @@
         return nullptr;
     }
 
+    if (WKStringIsEqualToUTF8CString(messageName, "HasStatisticsIsolatedSession")) {
+        ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
+        
+        WKStringRef hostName = static_cast<WKStringRef>(messageBody);
+        bool hasIsolatedSession = TestController::singleton().hasStatisticsIsolatedSession(hostName);
+        auto result = adoptWK(WKBooleanCreate(hasIsolatedSession));
+        return result;
+    }
+    
     if (WKStringIsEqualToUTF8CString(messageName, "RemoveAllSessionCredentials")) {
         TestController::singleton().removeAllSessionCredentials();
         return nullptr;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to