Title: [262554] branches/safari-609-branch
Revision
262554
Author
[email protected]
Date
2020-06-04 12:00:47 -0700 (Thu, 04 Jun 2020)

Log Message

Apply patch. rdar://problem/63951369

Modified Paths


Added Paths

Diff

Added: branches/safari-609-branch/LayoutTests/http/tests/resourceLoadStatistics/operating-dates-all-but-cookies-removed-statistics-with-no-user-interaction-expected.txt (0 => 262554)


--- branches/safari-609-branch/LayoutTests/http/tests/resourceLoadStatistics/operating-dates-all-but-cookies-removed-statistics-with-no-user-interaction-expected.txt	                        (rev 0)
+++ branches/safari-609-branch/LayoutTests/http/tests/resourceLoadStatistics/operating-dates-all-but-cookies-removed-statistics-with-no-user-interaction-expected.txt	2020-06-04 19:00:47 UTC (rev 262554)
@@ -0,0 +1,14 @@
+
+Before statistics processing: Client-side cookie exists.
+Before statistics processing: HttpOnly cookie exists.
+Before statistics processing: Regular server-side cookie exists.
+Before statistics processing: LocalStorage entry does exist.
+Before statistics processing: IDB entry does exist.
+
+After statistics processing: HttpOnly cookie exists.
+After statistics processing: Client-side cookie exists.
+After statistics processing: Regular server-side cookie exists.
+After statistics processing: LocalStorage entry does not exist.
+After statistics processing: IDB entry does not exist.
+
+

Added: branches/safari-609-branch/LayoutTests/http/tests/resourceLoadStatistics/operating-dates-all-but-cookies-removed-statistics-with-no-user-interaction.html (0 => 262554)


--- branches/safari-609-branch/LayoutTests/http/tests/resourceLoadStatistics/operating-dates-all-but-cookies-removed-statistics-with-no-user-interaction.html	                        (rev 0)
+++ branches/safari-609-branch/LayoutTests/http/tests/resourceLoadStatistics/operating-dates-all-but-cookies-removed-statistics-with-no-user-interaction.html	2020-06-04 19:00:47 UTC (rev 262554)
@@ -0,0 +1,258 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <script src=""
+    <script src=""
+</head>
+<body _onload_="setTimeout('runTest()', 0)">
+<br>
+<div id="output"></div>
+<br>
+<script>
+    testRunner.waitUntilDone();
+    testRunner.dumpAsText();
+
+    const httpOnlyCookieName = "http-only-cookie";
+    const serverSideCookieName = "server-side-cookie";
+    const clientSideCookieName = "client-side-cookie";
+
+    function sortStringArray(a, b) {
+        a = a.toLowerCase();
+        b = b.toLowerCase();
+
+        return a > b ? 1 : b > a ? -1 : 0;
+    }
+
+    function addLinebreakToOutput() {
+        let element = document.createElement("br");
+        output.appendChild(element);
+    }
+
+    function addOutput(message) {
+        let element = document.createElement("div");
+        element.innerText = message;
+        output.appendChild(element);
+    }
+
+    function checkCookies(isAfterDeletion) {
+        let unsortedTestPassedMessages = [];
+        let cookies = internals.getCookies();
+        if (!cookies.length && isAfterDeletion)
+            addOutput("FAIL: " + "No cookies found.");
+        for (let cookie of cookies) {
+            switch (cookie.name) {
+                case httpOnlyCookieName:
+                    unsortedTestPassedMessages.push((isAfterDeletion ? "After" : "Before") + " statistics processing: " + (isAfterDeletion ? " " : "") + "HttpOnly cookie exists.");
+                    break;
+                case serverSideCookieName:
+                    unsortedTestPassedMessages.push((isAfterDeletion ? "After" : "Before") + " statistics processing: Regular server-side cookie exists.");
+                    break;
+                case clientSideCookieName:
+                    unsortedTestPassedMessages.push((isAfterDeletion ? "After" : "Before") + " statistics processing: Client-side cookie exists.");
+                    break;
+            }
+        }
+        let sortedTestPassedMessages = unsortedTestPassedMessages.sort(sortStringArray);
+        for (let testPassedMessage of sortedTestPassedMessages) {
+            addOutput(testPassedMessage);
+        }
+    }
+
+    const dbName = "TestDatabase";
+
+    function createIDBDataStore(callback) {
+        let request = indexedDB.open(dbName);
+        request._onerror_ = function() {
+            addOutput("Couldn't create indexedDB.");
+            finishTest();
+        };
+        request._onupgradeneeded_ = function(event) {
+            let db = event.target.result;
+            let objStore = db.createObjectStore("test", {autoIncrement: true});
+            objStore.add("value");
+            callback();
+        }
+    }
+
+    const maxIntervals = 20;
+
+    let intervalCounterIDB;
+    let checkIDBCallback;
+    let checkIDBIntervalID;
+    let semaphoreIDBCheck = false;
+    function checkIDBDataStoreExists(isAfterDeletion, callback) {
+        let request;
+        intervalCounterIDB = 0;
+        checkIDBCallback = callback;
+        if (!isAfterDeletion) {
+            // Check until there is a IDB.
+            checkIDBIntervalID = setInterval(function() {
+                if (semaphoreIDBCheck)
+                    return;
+                semaphoreIDBCheck = true;
+
+                if (++intervalCounterIDB >= maxIntervals) {
+                    clearInterval(checkIDBIntervalID);
+                    addOutput("Before statistics processing: IDB entry does not exist.");
+                    semaphoreIDBCheck = false;
+                    checkIDBCallback();
+                } else {
+                    request = indexedDB.open(dbName);
+                    request._onerror_ = function () {
+                        clearInterval(checkIDBIntervalID);
+                        addOutput("Couldn't open indexedDB.");
+                        semaphoreIDBCheck = false;
+                        finishTest();
+                    };
+                    request._onupgradeneeded_ = function () {
+                        // Let the next interval check again.
+                        semaphoreIDBCheck = false;
+                    };
+                    request._onsuccess_ = function () {
+                        clearInterval(checkIDBIntervalID);
+                        addOutput("Before statistics processing: IDB entry does exist.");
+                        semaphoreIDBCheck = false;
+                        checkIDBCallback();
+                    };
+                }
+            }, 200);
+        } else {
+            // Check until there is no IDB.
+            checkIDBIntervalID = setInterval(function () {
+                if (semaphoreIDBCheck)
+                    return;
+                semaphoreIDBCheck = true;
+
+                if (++intervalCounterIDB >= maxIntervals) {
+                    clearInterval(checkIDBIntervalID);
+                    addOutput("After statistics processing: IDB entry does exist.");
+                    semaphoreIDBCheck = false;
+                    checkIDBCallback();
+                } else {
+                    request = indexedDB.open(dbName);
+                    request._onerror_ = function () {
+                        clearInterval(checkIDBIntervalID);
+                        addOutput("Couldn't open indexedDB.");
+                        semaphoreIDBCheck = false;
+                        finishTest();
+                    };
+                    request._onupgradeneeded_ = function () {
+                        clearInterval(checkIDBIntervalID);
+                        addOutput("After statistics processing: IDB entry does not exist.");
+                        semaphoreIDBCheck = false;
+                        finishTest();
+                    };
+                    request._onsuccess_ = function () {
+                        // Let the next interval check again because deletion might be delayed.
+                        semaphoreIDBCheck = false;
+                    };
+                }
+            }, 200);
+        }
+    }
+
+    let intervalCounterLocalStorage;
+    let checkLocalStorageCallback;
+    let checkLocalStorageIntervalID;
+    const localStorageName = "test";
+    const localStorageValue = "value";
+    function checkLocalStorageExists(isAfterDeletion, callback) {
+        intervalCounterLocalStorage = 0;
+        checkLocalStorageCallback = callback;
+        if (!isAfterDeletion) {
+            // Check until there is LocalStorage.
+            checkLocalStorageIntervalID = setInterval(function() {
+                if (++intervalCounterLocalStorage >= maxIntervals) {
+                    clearInterval(checkLocalStorageIntervalID);
+                    let value = localStorage.getItem(localStorageName);
+                    addOutput("Before statistics processing: LocalStorage entry " + (value === localStorageValue ? "does" : "does not") + " exist.");
+                    checkLocalStorageCallback();
+                } else if (testRunner.isStatisticsHasLocalStorage(originUnderTest)) {
+                    clearInterval(checkLocalStorageIntervalID);
+                    let value = localStorage.getItem(localStorageName);
+                    addOutput("Before statistics processing: LocalStorage entry " + (value === localStorageValue ? "does" : "does not") + " exist.");
+                    checkLocalStorageCallback();
+                }
+            }, 100);
+        } else {
+            // Check until there is no LocalStorage.
+            checkLocalStorageIntervalID = setInterval(function() {
+                if (++intervalCounterLocalStorage >= maxIntervals) {
+                    clearInterval(checkLocalStorageIntervalID);
+                    let value = localStorage.getItem(localStorageName);
+                    addOutput("After statistics processing: LocalStorage entry " + (value === localStorageValue ? "does" : "does not") + " exist.");
+                    checkLocalStorageCallback();
+                } else if (!testRunner.isStatisticsHasLocalStorage(originUnderTest)) {
+                    clearInterval(checkLocalStorageIntervalID);
+                    let value = localStorage.getItem(localStorageName);
+                    addOutput("After statistics processing: LocalStorage entry " + (value === localStorageValue ? "does" : "does not") + " exist.");
+                    checkLocalStorageCallback();
+                }
+            }, 100);
+        }
+    }
+
+    async function writeWebsiteDataAndContinue() {
+        // Write cookies.
+        await fetch("/cookies/resources/set-http-only-cookie.php?cookieName=" + httpOnlyCookieName, { credentials: "same-origin" });
+        await fetch("/cookies/resources/setCookies.cgi", { headers: { "Set-Cookie": serverSideCookieName + "=1; path=/;" }, credentials: "same-origin" });
+        document.cookie = clientSideCookieName + "=1";
+
+        checkCookies(false);
+
+        // Write LocalStorage
+        localStorage.setItem(localStorageName, localStorageValue);
+        checkLocalStorageExists(false, function() {
+
+            // Write IndexedDB.
+            createIDBDataStore(function () {
+                checkIDBDataStoreExists(false, function() {
+                    addLinebreakToOutput();
+                    processWebsiteDataAndContinue();
+                });
+            });
+        });
+    }
+
+    function processWebsiteDataAndContinue() {
+        testRunner.installStatisticsDidScanDataRecordsCallback(checkWebsiteDataAndContinue);
+        testRunner.statisticsProcessStatisticsAndDataRecords();
+    }
+
+    function checkWebsiteDataAndContinue() {
+        checkCookies(true);
+        checkLocalStorageExists(true, function () {
+            checkIDBDataStoreExists(true, finishTest);
+        });
+    }
+
+    const originUnderTest  = "http://127.0.0.1:8000";
+    const otherOrigin = "http://localhost:8000"
+    const topFrameOrigin = "http://127.0.0.2:8000";
+    const timeStamp = Math.round((new Date()).getTime() / 1000);
+    function finishTest() {
+        if (testRunner.isStatisticsHasHadUserInteraction(originUnderTest))
+            addOutput("FAIL: " + originUnderTest + " still has user interaction after processing.");
+        resetCookies();
+        setEnableFeature(false, function() {
+            testRunner.notifyDone();
+        });
+    }
+
+    // Do not use setEnableFeature here because we want to make sure website data deletion is not skipped
+    // by the presence of parameters().isRunningTest.
+    function runTest() {
+        testRunner.setStatisticsMinimumTimeBetweenDataRecordsRemoval(3600);
+        // Merge a statistic with no user interaction to check the -1 case.
+        testRunner.setStatisticsMergeStatistic(otherOrigin, topFrameOrigin, "", timeStamp, false, -1, false, false, false, 0, function() {
+            testRunner.setStatisticsFirstPartyWebsiteDataRemovalMode(true, function () {
+                // insertStatisticsExpiredStatistic(domain, hasHadUserInteraction, isScheduledForAllButCookieDataRemoval, isPrevalent)
+                testRunner.setStatisticsExpiredStatistic(originUnderTest, true, true, false, function() {
+                    writeWebsiteDataAndContinue();
+                });
+            });
+        });
+    }
+</script>
+</body>
+</html>

Added: branches/safari-609-branch/LayoutTests/http/tests/resourceLoadStatistics/operating-dates-all-website-data-removed-expected.txt (0 => 262554)


--- branches/safari-609-branch/LayoutTests/http/tests/resourceLoadStatistics/operating-dates-all-website-data-removed-expected.txt	                        (rev 0)
+++ branches/safari-609-branch/LayoutTests/http/tests/resourceLoadStatistics/operating-dates-all-website-data-removed-expected.txt	2020-06-04 19:00:47 UTC (rev 262554)
@@ -0,0 +1,12 @@
+
+Before statistics processing: Client-side cookie exists.
+Before statistics processing: HttpOnly cookie exists.
+Before statistics processing: Regular server-side cookie exists.
+Before statistics processing: LocalStorage entry does exist.
+Before statistics processing: IDB entry does exist.
+
+After statistics processing: No cookies found.
+After statistics processing: LocalStorage entry does not exist.
+After statistics processing: IDB entry does not exist.
+
+

Added: branches/safari-609-branch/LayoutTests/http/tests/resourceLoadStatistics/operating-dates-all-website-data-removed.html (0 => 262554)


--- branches/safari-609-branch/LayoutTests/http/tests/resourceLoadStatistics/operating-dates-all-website-data-removed.html	                        (rev 0)
+++ branches/safari-609-branch/LayoutTests/http/tests/resourceLoadStatistics/operating-dates-all-website-data-removed.html	2020-06-04 19:00:47 UTC (rev 262554)
@@ -0,0 +1,251 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <script src=""
+    <script src=""
+</head>
+<body _onload_="setTimeout('runTest()', 0)">
+<br>
+<div id="output"></div>
+<br>
+<script>
+    testRunner.waitUntilDone();
+    testRunner.dumpAsText();
+
+    const httpOnlyCookieName = "http-only-cookie";
+    const serverSideCookieName = "server-side-cookie";
+    const clientSideCookieName = "client-side-cookie";
+
+    function sortStringArray(a, b) {
+        a = a.toLowerCase();
+        b = b.toLowerCase();
+
+        return a > b ? 1 : b > a ? -1 : 0;
+    }
+
+    function addLinebreakToOutput() {
+        let element = document.createElement("br");
+        output.appendChild(element);
+    }
+
+    function addOutput(message) {
+        let element = document.createElement("div");
+        element.innerText = message;
+        output.appendChild(element);
+    }
+
+    function checkCookies(isAfterDeletion) {
+        let unsortedTestPassedMessages = [];
+        let cookies = internals.getCookies();
+        if (!cookies.length && isAfterDeletion)
+        unsortedTestPassedMessages.push((isAfterDeletion ? "After" : "Before") + " statistics processing: No cookies found.");
+        for (let cookie of cookies) {
+            switch (cookie.name) {
+                case httpOnlyCookieName:
+                    unsortedTestPassedMessages.push((isAfterDeletion ? "After" : "Before") + " statistics processing: " + (isAfterDeletion ? " " : "") + "HttpOnly cookie exists.");
+                    break;
+                case serverSideCookieName:
+                    unsortedTestPassedMessages.push((isAfterDeletion ? "After" : "Before") + " statistics processing: Regular server-side cookie exists.");
+                    break;
+                case clientSideCookieName:
+                    unsortedTestPassedMessages.push((isAfterDeletion ? "After" : "Before") + " statistics processing: Client-side cookie exists.");
+                    break;
+            }
+        }
+        let sortedTestPassedMessages = unsortedTestPassedMessages.sort(sortStringArray);
+        for (let testPassedMessage of sortedTestPassedMessages) {
+            addOutput(testPassedMessage);
+        }
+    }
+
+    const dbName = "TestDatabase";
+
+    function createIDBDataStore(callback) {
+        let request = indexedDB.open(dbName);
+        request._onerror_ = function() {
+            addOutput("Couldn't create indexedDB.");
+            finishTest();
+        };
+        request._onupgradeneeded_ = function(event) {
+            let db = event.target.result;
+            let objStore = db.createObjectStore("test", {autoIncrement: true});
+            objStore.add("value");
+            callback();
+        }
+    }
+
+    const maxIntervals = 20;
+
+    let intervalCounterIDB;
+    let checkIDBCallback;
+    let checkIDBIntervalID;
+    let semaphoreIDBCheck = false;
+    function checkIDBDataStoreExists(isAfterDeletion, callback) {
+        let request;
+        intervalCounterIDB = 0;
+        checkIDBCallback = callback;
+        if (!isAfterDeletion) {
+            // Check until there is a IDB.
+            checkIDBIntervalID = setInterval(function() {
+                if (semaphoreIDBCheck)
+                    return;
+                semaphoreIDBCheck = true;
+
+                if (++intervalCounterIDB >= maxIntervals) {
+                    clearInterval(checkIDBIntervalID);
+                    addOutput("Before statistics processing: IDB entry does not exist.");
+                    semaphoreIDBCheck = false;
+                    checkIDBCallback();
+                } else {
+                    request = indexedDB.open(dbName);
+                    request._onerror_ = function () {
+                        clearInterval(checkIDBIntervalID);
+                        addOutput("Couldn't open indexedDB.");
+                        semaphoreIDBCheck = false;
+                        finishTest();
+                    };
+                    request._onupgradeneeded_ = function () {
+                        // Let the next interval check again.
+                        semaphoreIDBCheck = false;
+                    };
+                    request._onsuccess_ = function () {
+                        clearInterval(checkIDBIntervalID);
+                        addOutput("Before statistics processing: IDB entry does exist.");
+                        semaphoreIDBCheck = false;
+                        checkIDBCallback();
+                    };
+                }
+            }, 200);
+        } else {
+            // Check until there is no IDB.
+            checkIDBIntervalID = setInterval(function () {
+                if (semaphoreIDBCheck)
+                    return;
+                semaphoreIDBCheck = true;
+
+                if (++intervalCounterIDB >= maxIntervals) {
+                    clearInterval(checkIDBIntervalID);
+                    addOutput("After statistics processing: IDB entry does exist.");
+                    semaphoreIDBCheck = false;
+                    checkIDBCallback();
+                } else {
+                    request = indexedDB.open(dbName);
+                    request._onerror_ = function () {
+                        clearInterval(checkIDBIntervalID);
+                        addOutput("Couldn't open indexedDB.");
+                        semaphoreIDBCheck = false;
+                        finishTest();
+                    };
+                    request._onupgradeneeded_ = function () {
+                        clearInterval(checkIDBIntervalID);
+                        addOutput("After statistics processing: IDB entry does not exist.");
+                        semaphoreIDBCheck = false;
+                        finishTest();
+                    };
+                    request._onsuccess_ = function () {
+                        // Let the next interval check again because deletion might be delayed.
+                        semaphoreIDBCheck = false;
+                    };
+                }
+            }, 200);
+        }
+    }
+
+    let intervalCounterLocalStorage;
+    let checkLocalStorageCallback;
+    let checkLocalStorageIntervalID;
+    const localStorageName = "test";
+    const localStorageValue = "value";
+    function checkLocalStorageExists(isAfterDeletion, callback) {
+        intervalCounterLocalStorage = 0;
+        checkLocalStorageCallback = callback;
+        if (!isAfterDeletion) {
+            // Check until there is LocalStorage.
+            checkLocalStorageIntervalID = setInterval(function() {
+                if (++intervalCounterLocalStorage >= maxIntervals) {
+                    clearInterval(checkLocalStorageIntervalID);
+                    let value = localStorage.getItem(localStorageName);
+                    addOutput("Before statistics processing: LocalStorage entry " + (value === localStorageValue ? "does" : "does not") + " exist.");
+                    checkLocalStorageCallback();
+                } else if (testRunner.isStatisticsHasLocalStorage(originUnderTest)) {
+                    clearInterval(checkLocalStorageIntervalID);
+                    let value = localStorage.getItem(localStorageName);
+                    addOutput("Before statistics processing: LocalStorage entry " + (value === localStorageValue ? "does" : "does not") + " exist.");
+                    checkLocalStorageCallback();
+                }
+            }, 100);
+        } else {
+            // Check until there is no LocalStorage.
+            checkLocalStorageIntervalID = setInterval(function() {
+                if (++intervalCounterLocalStorage >= maxIntervals) {
+                    clearInterval(checkLocalStorageIntervalID);
+                    let value = localStorage.getItem(localStorageName);
+                    addOutput("After statistics processing: LocalStorage entry " + (value === localStorageValue ? "does" : "does not") + " exist.");
+                    checkLocalStorageCallback();
+                } else if (!testRunner.isStatisticsHasLocalStorage(originUnderTest)) {
+                    clearInterval(checkLocalStorageIntervalID);
+                    let value = localStorage.getItem(localStorageName);
+                    addOutput("After statistics processing: LocalStorage entry " + (value === localStorageValue ? "does" : "does not") + " exist.");
+                    checkLocalStorageCallback();
+                }
+            }, 100);
+        }
+    }
+
+    async function writeWebsiteDataAndContinue() {
+        // Write cookies.
+        await fetch("/cookies/resources/set-http-only-cookie.php?cookieName=" + httpOnlyCookieName, { credentials: "same-origin" });
+        await fetch("/cookies/resources/setCookies.cgi", { headers: { "Set-Cookie": serverSideCookieName + "=1; path=/;" }, credentials: "same-origin" });
+        document.cookie = clientSideCookieName + "=1";
+
+        checkCookies(false);
+
+        // Write LocalStorage
+        localStorage.setItem(localStorageName, localStorageValue);
+        checkLocalStorageExists(false, function() {
+
+            // Write IndexedDB.
+            createIDBDataStore(function () {
+                checkIDBDataStoreExists(false, function() {
+                    addLinebreakToOutput();
+                    processWebsiteDataAndContinue();
+                });
+            });
+        });
+    }
+
+    function processWebsiteDataAndContinue() {
+        testRunner.installStatisticsDidScanDataRecordsCallback(checkWebsiteDataAndContinue);
+        testRunner.statisticsProcessStatisticsAndDataRecords();
+    }
+
+    function checkWebsiteDataAndContinue() {
+        checkCookies(true);
+        checkLocalStorageExists(true, function () {
+            checkIDBDataStoreExists(true, finishTest);
+        });
+    }
+
+    const originUnderTest  = "http://127.0.0.1:8000";
+    function finishTest() {
+        if (testRunner.isStatisticsHasHadUserInteraction(originUnderTest))
+            addOutput("FAIL: " + originUnderTest + " still has user interaction after processing.");
+        resetCookies();
+        setEnableFeature(false, function() {
+            testRunner.notifyDone();
+        });
+    }
+
+    function runTest() {
+        setEnableFeature(true, function () {
+            // insertStatisticsExpiredStatistic(domain, hasHadUserInteraction, isScheduledForAllButCookieDataRemoval, isPrevalent)
+            testRunner.setStatisticsExpiredStatistic(originUnderTest, true, false, true, function() {
+                if (!testRunner.isStatisticsPrevalentResource(originUnderTest))
+                    addOutput("FAIL: " + originUnderTest + " did not get inserted into database.");
+                writeWebsiteDataAndContinue();
+            });
+        });
+    }
+</script>
+</body>
+</html>

Modified: branches/safari-609-branch/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsMemoryStore.cpp (262553 => 262554)


--- branches/safari-609-branch/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsMemoryStore.cpp	2020-06-04 19:00:39 UTC (rev 262553)
+++ branches/safari-609-branch/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsMemoryStore.cpp	2020-06-04 19:00:47 UTC (rev 262554)
@@ -908,6 +908,14 @@
     return isRemovalEnabled && !isResourceGrandfathered && !hasHadUnexpiredRecentUserInteraction(resourceStatistic, window);
 }
 
+Optional<WallTime> ResourceLoadStatisticsMemoryStore::mostRecentUserInteractionTime(const ResourceLoadStatistics& statistic)
+{
+    if (statistic.mostRecentUserInteractionTime.secondsSinceEpoch().value() <= 0)
+        return WTF::nullopt;
+
+    return statistic.mostRecentUserInteractionTime;
+}
+
 Vector<std::pair<RegistrableDomain, WebsiteDataToRemove>> ResourceLoadStatisticsMemoryStore::registrableDomainsToRemoveWebsiteDataFor()
 {
     ASSERT(!RunLoop::isMain());
@@ -922,7 +930,8 @@
     auto oldestUserInteraction = now;
     Vector<std::pair<RegistrableDomain, WebsiteDataToRemove>> domainsToRemoveWebsiteDataFor;
     for (auto& statistic : m_resourceStatisticsMap.values()) {
-        oldestUserInteraction = std::min(oldestUserInteraction, statistic.mostRecentUserInteractionTime);
+        if (auto mostRecentUserInteractionTime = this->mostRecentUserInteractionTime(statistic))
+            oldestUserInteraction = std::min(oldestUserInteraction, *mostRecentUserInteractionTime);
         if (shouldRemoveAllWebsiteDataFor(statistic, shouldCheckForGrandfathering))
             domainsToRemoveWebsiteDataFor.append(std::make_pair(statistic.registrableDomain, WebsiteDataToRemove::All));
         else if (shouldRemoveAllButCookiesFor(statistic, shouldCheckForGrandfathering)) {
@@ -935,7 +944,7 @@
     }
 
     // Give the user enough time to interact with websites until we remove non-cookie website data.
-    if (!parameters().isRunningTest && now - oldestUserInteraction > parameters().minimumTimeBetweenDataRecordsRemoval) {
+    if (!parameters().isRunningTest && now - oldestUserInteraction < parameters().minimumTimeBetweenDataRecordsRemoval) {
         domainsToRemoveWebsiteDataFor.removeAllMatching([&] (auto& pair) {
             return pair.second == WebsiteDataToRemove::AllButCookies;
         });

Modified: branches/safari-609-branch/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsMemoryStore.h (262553 => 262554)


--- branches/safari-609-branch/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsMemoryStore.h	2020-06-04 19:00:39 UTC (rev 262553)
+++ branches/safari-609-branch/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsMemoryStore.h	2020-06-04 19:00:47 UTC (rev 262554)
@@ -112,6 +112,7 @@
     bool hasHadUserInteraction(const RegistrableDomain&, OperatingDatesWindow) override;
 
     void setLastSeen(const RegistrableDomain&, Seconds) override;
+    Optional<WallTime> mostRecentUserInteractionTime(const ResourceLoadStatistics&);
 
 private:
     static bool shouldBlockAndKeepCookies(const ResourceLoadStatistics&);

Modified: branches/safari-609-branch/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsStore.cpp (262553 => 262554)


--- branches/safari-609-branch/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsStore.cpp	2020-06-04 19:00:39 UTC (rev 262553)
+++ branches/safari-609-branch/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsStore.cpp	2020-06-04 19:00:47 UTC (rev 262554)
@@ -619,6 +619,33 @@
         RELEASE_LOG_INFO(ITPDebug, "About to %{public}s cookies in third-party contexts for (%{public}d of %u): %{public}s.", action, batchNumber, numberOfBatches, domainsToString(batch).utf8().data());
 }
 
+void ResourceLoadStatisticsStore::insertExpiredStatisticForTesting(const RegistrableDomain& domain, bool hasUserInteraction, bool isScheduledForAllButCookieDataRemoval, bool isPrevalent)
+{
+    // Populate the Operating Dates table with enough days to require pruning.
+    double daysAgoInSeconds = 0;
+    for (unsigned i = 1; i <= operatingDatesWindowLong; i++) {
+        double daysToSubtract = Seconds::fromHours(24 * i).value();
+        daysAgoInSeconds = WallTime::now().secondsSinceEpoch().value() - daysToSubtract;
+        auto dateToInsert = OperatingDate::fromWallTime(WallTime::fromRawSeconds(daysAgoInSeconds));
+        m_operatingDates.append(OperatingDate(dateToInsert.year(), dateToInsert.month(), dateToInsert.monthDay()));
+    }
+
+    // Make sure mostRecentUserInteractionTime is the least recent of all entries.
+    daysAgoInSeconds -= Seconds::fromHours(24).value();
+
+    auto statistic = ResourceLoadStatistics(domain);
+    statistic.lastSeen = WallTime::fromRawSeconds(daysAgoInSeconds);
+    statistic.hadUserInteraction = hasUserInteraction;
+    statistic.mostRecentUserInteractionTime = WallTime::fromRawSeconds(daysAgoInSeconds);
+    statistic.isPrevalentResource = isPrevalent;
+    statistic.gotLinkDecorationFromPrevalentResource = isScheduledForAllButCookieDataRemoval;
+
+    Vector<ResourceLoadStatistics> statistics;
+    statistics.append(WTFMove(statistic));
+
+    mergeStatistics(WTFMove(statistics));
+}
+
 } // namespace WebKit
 
 #endif

Modified: branches/safari-609-branch/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsStore.h (262553 => 262554)


--- branches/safari-609-branch/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsStore.h	2020-06-04 19:00:39 UTC (rev 262553)
+++ branches/safari-609-branch/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsStore.h	2020-06-04 19:00:47 UTC (rev 262554)
@@ -58,11 +58,14 @@
     static OperatingDate fromWallTime(WallTime);
     static OperatingDate today();
     Seconds secondsSinceEpoch() const;
+    int year() { return m_year; }
+    int month() { return m_month; }
+    int monthDay() { return m_monthDay; }
+
     bool operator==(const OperatingDate& other) const;
     bool operator<(const OperatingDate& other) const;
     bool operator<=(const OperatingDate& other) const;
     
-private:
     OperatingDate(int year, int month, int monthDay)
         : m_year(year)
         , m_month(month)
@@ -69,6 +72,7 @@
         , m_monthDay(monthDay)
     { }
 
+private:
     int m_year { 0 };
     int m_month { 0 }; // [0, 11].
     int m_monthDay { 0 }; // [1, 31].
@@ -188,6 +192,7 @@
 
     virtual bool isMemoryStore() const { return false; }
     virtual bool isDatabaseStore()const { return false; }
+    void insertExpiredStatisticForTesting(const RegistrableDomain&, bool hasUserInteraction, bool isScheduledForAllButCookieDataRemoval, bool);
 
 protected:
     static unsigned computeImportance(const WebCore::ResourceLoadStatistics&);

Modified: branches/safari-609-branch/Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsStore.cpp (262553 => 262554)


--- branches/safari-609-branch/Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsStore.cpp	2020-06-04 19:00:39 UTC (rev 262553)
+++ branches/safari-609-branch/Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsStore.cpp	2020-06-04 19:00:47 UTC (rev 262554)
@@ -1179,6 +1179,17 @@
         m_stateChangeCondition.notifyOne();
 }
 
+void WebResourceLoadStatisticsStore::insertExpiredStatisticForTesting(const RegistrableDomain& domain, bool hadUserInteraction, bool isScheduledForAllButCookieDataRemoval, bool isPrevalent, CompletionHandler<void()>&& completionHandler)
+{
+    ASSERT(RunLoop::isMain());
+
+    postTask([this, domain = domain.isolatedCopy(), hadUserInteraction, isScheduledForAllButCookieDataRemoval, isPrevalent, completionHandler = WTFMove(completionHandler)]() mutable {
+        if (m_statisticsStore)
+            m_statisticsStore->insertExpiredStatisticForTesting(WTFMove(domain), hadUserInteraction, isScheduledForAllButCookieDataRemoval, isPrevalent);
+        postTaskReply(WTFMove(completionHandler));
+    });
+}
+
 } // namespace WebKit
 
 #endif

Modified: branches/safari-609-branch/Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsStore.h (262553 => 262554)


--- branches/safari-609-branch/Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsStore.h	2020-06-04 19:00:39 UTC (rev 262553)
+++ branches/safari-609-branch/Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsStore.h	2020-06-04 19:00:47 UTC (rev 262554)
@@ -289,6 +289,7 @@
     void aggregatedThirdPartyData(CompletionHandler<void(Vector<WebResourceLoadStatisticsStore::ThirdPartyData>&&)>&&);
     void suspend(CompletionHandler<void()>&&);
     void resume();
+    void insertExpiredStatisticForTesting(const RegistrableDomain&, bool hadUserInteraction, bool isScheduledForAllButCookieDataRemoval, bool isPrevalent, CompletionHandler<void()>&&);
 
 private:
     explicit WebResourceLoadStatisticsStore(NetworkSession&, const String&, ShouldIncludeLocalhost);

Modified: branches/safari-609-branch/Source/WebKit/NetworkProcess/NetworkProcess.cpp (262553 => 262554)


--- branches/safari-609-branch/Source/WebKit/NetworkProcess/NetworkProcess.cpp	2020-06-04 19:00:39 UTC (rev 262553)
+++ branches/safari-609-branch/Source/WebKit/NetworkProcess/NetworkProcess.cpp	2020-06-04 19:00:47 UTC (rev 262554)
@@ -993,6 +993,19 @@
     }
 }
 
+void NetworkProcess::insertExpiredStatisticForTesting(PAL::SessionID sessionID, const RegistrableDomain& domain, bool hadUserInteraction, bool isScheduledForAllButCookieDataRemoval, bool isPrevalent, CompletionHandler<void()>&& completionHandler)
+{
+    if (auto* networkSession = this->networkSession(sessionID)) {
+        if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
+            resourceLoadStatistics->insertExpiredStatisticForTesting(domain, hadUserInteraction, isScheduledForAllButCookieDataRemoval, isPrevalent, WTFMove(completionHandler));
+        else
+            completionHandler();
+    } else {
+        ASSERT_NOT_REACHED();
+        completionHandler();
+    }
+}
+
 void NetworkProcess::getAllStorageAccessEntries(PAL::SessionID sessionID, CompletionHandler<void(Vector<String> domains)>&& completionHandler)
 {
     if (auto* networkStorageSession = storageSession(sessionID))

Modified: branches/safari-609-branch/Source/WebKit/NetworkProcess/NetworkProcess.h (262553 => 262554)


--- branches/safari-609-branch/Source/WebKit/NetworkProcess/NetworkProcess.h	2020-06-04 19:00:39 UTC (rev 262553)
+++ branches/safari-609-branch/Source/WebKit/NetworkProcess/NetworkProcess.h	2020-06-04 19:00:47 UTC (rev 262554)
@@ -241,6 +241,7 @@
     void setGrandfatheringTime(PAL::SessionID, Seconds, CompletionHandler<void()>&&);
     void setLastSeen(PAL::SessionID, const RegistrableDomain&, Seconds, CompletionHandler<void()>&&);
     void mergeStatisticForTesting(PAL::SessionID, const RegistrableDomain&, const TopFrameDomain& topFrameDomain1, const TopFrameDomain& topFrameDomain2, Seconds lastSeen, bool hadUserInteraction, Seconds mostRecentUserInteraction, bool isGrandfathered, bool isPrevalent, bool isVeryPrevalent, unsigned dataRecordsRemoved, CompletionHandler<void()>&&);
+    void insertExpiredStatisticForTesting(PAL::SessionID, const RegistrableDomain&, bool hadUserInteraction, bool isScheduledForAllButCookieDataRemoval, bool isPrevalent, CompletionHandler<void()>&&);
     void setMinimumTimeBetweenDataRecordsRemoval(PAL::SessionID, Seconds, CompletionHandler<void()>&&);
     void setNotifyPagesWhenDataRecordsWereScanned(PAL::SessionID, bool value, CompletionHandler<void()>&&);
     void setIsRunningResourceLoadStatisticsTest(PAL::SessionID, bool value, CompletionHandler<void()>&&);

Modified: branches/safari-609-branch/Source/WebKit/NetworkProcess/NetworkProcess.messages.in (262553 => 262554)


--- branches/safari-609-branch/Source/WebKit/NetworkProcess/NetworkProcess.messages.in	2020-06-04 19:00:39 UTC (rev 262553)
+++ branches/safari-609-branch/Source/WebKit/NetworkProcess/NetworkProcess.messages.in	2020-06-04 19:00:47 UTC (rev 262554)
@@ -93,6 +93,7 @@
     SetAgeCapForClientSideCookies(PAL::SessionID sessionID, Optional<Seconds> seconds) -> () Async
     SetLastSeen(PAL::SessionID sessionID, WebCore::RegistrableDomain resourceDomain, Seconds seconds) -> () Async
     MergeStatisticForTesting(PAL::SessionID sessionID, WebCore::RegistrableDomain resourceDomain, WebCore::RegistrableDomain topFrameDomain1, WebCore::RegistrableDomain topFrameDomain2, Seconds lastSeen, bool hadUserInteraction, Seconds mostRecentUserInteraction, bool isGrandfathered, bool isPrevalent, bool isVeryPrevalent, uint64_t dataRecordsRemoved) -> () Async
+    InsertExpiredStatisticForTesting(PAL::SessionID sessionID, WebCore::RegistrableDomain resourceDomain, bool hadUserInteraction, bool isScheduledForAllButCookieDataRemoval, bool isPrevalent) -> () Async
     SetPrevalentResource(PAL::SessionID sessionID, WebCore::RegistrableDomain resourceDomain) -> () Async
     SetPrevalentResourceForDebugMode(PAL::SessionID sessionID, WebCore::RegistrableDomain resourceDomain) -> () Async
     HadUserInteraction(PAL::SessionID sessionID, WebCore::RegistrableDomain resourceDomain) -> (bool hadUserInteraction) Async

Modified: branches/safari-609-branch/Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreRef.cpp (262553 => 262554)


--- branches/safari-609-branch/Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreRef.cpp	2020-06-04 19:00:39 UTC (rev 262553)
+++ branches/safari-609-branch/Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreRef.cpp	2020-06-04 19:00:47 UTC (rev 262554)
@@ -129,6 +129,17 @@
 #endif
 }
 
+void WKWebsiteDataStoreSetStatisticsExpiredStatistic(WKWebsiteDataStoreRef dataStoreRef, WKStringRef host, bool hadUserInteraction, bool isScheduledForAllButCookieDataRemoval, bool isPrevalent, void* context, WKWebsiteDataStoreStatisticsMergeStatisticFunction completionHandler)
+{
+#if ENABLE(RESOURCE_LOAD_STATISTICS)
+    WebKit::toImpl(dataStoreRef)->insertExpiredStatisticForTesting(URL(URL(), WebKit::toImpl(host)->string()), hadUserInteraction, isScheduledForAllButCookieDataRemoval, isPrevalent, [context, completionHandler] {
+        completionHandler(context);
+    });
+#else
+    completionHandler(context);
+#endif
+}
+
 void WKWebsiteDataStoreSetStatisticsPrevalentResource(WKWebsiteDataStoreRef dataStoreRef, WKStringRef host, bool value, void* context, WKWebsiteDataStoreStatisticsPrevalentResourceFunction completionHandler)
 {
 #if ENABLE(RESOURCE_LOAD_STATISTICS)

Modified: branches/safari-609-branch/Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreRef.h (262553 => 262554)


--- branches/safari-609-branch/Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreRef.h	2020-06-04 19:00:39 UTC (rev 262553)
+++ branches/safari-609-branch/Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreRef.h	2020-06-04 19:00:47 UTC (rev 262554)
@@ -53,6 +53,8 @@
 WK_EXPORT void WKWebsiteDataStoreSetStatisticsLastSeen(WKWebsiteDataStoreRef dataStoreRef, WKStringRef host, double seconds, void* context, WKWebsiteDataStoreStatisticsLastSeenFunction completionHandler);
 typedef void (*WKWebsiteDataStoreStatisticsMergeStatisticFunction)(void* functionContext);
 WK_EXPORT void WKWebsiteDataStoreSetStatisticsMergeStatistic(WKWebsiteDataStoreRef dataStoreRef, WKStringRef host, WKStringRef topFrameDomain1, WKStringRef topFrameDomain2, double lastSeen, bool hadUserInteraction, double mostRecentUserInteraction, bool isGrandfathered, bool isPrevalent, bool isVeryPrevalent, unsigned dataRecordsRemoved, void* context, WKWebsiteDataStoreStatisticsMergeStatisticFunction completionHandler);
+typedef void (*WKWebsiteDataStoreStatisticsExpiredStatisticFunction)(void* functionContext);
+WK_EXPORT void WKWebsiteDataStoreSetStatisticsExpiredStatistic(WKWebsiteDataStoreRef dataStoreRef, WKStringRef host, bool hadUserInteraction, bool isScheduledForAllButCookieDataRemoval, bool isPrevalent, void* context, WKWebsiteDataStoreStatisticsExpiredStatisticFunction completionHandler);
 typedef void (*WKWebsiteDataStoreStatisticsPrevalentResourceFunction)(void* functionContext);
 WK_EXPORT void WKWebsiteDataStoreSetStatisticsPrevalentResource(WKWebsiteDataStoreRef dataStoreRef, WKStringRef host, bool value, void* context, WKWebsiteDataStoreStatisticsPrevalentResourceFunction completionHandler);
 typedef void (*WKWebsiteDataStoreStatisticsVeryPrevalentResourceFunction)(void* functionContext);

Modified: branches/safari-609-branch/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp (262553 => 262554)


--- branches/safari-609-branch/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp	2020-06-04 19:00:39 UTC (rev 262553)
+++ branches/safari-609-branch/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp	2020-06-04 19:00:47 UTC (rev 262554)
@@ -559,6 +559,11 @@
     sendWithAsyncReply(Messages::NetworkProcess::MergeStatisticForTesting(sessionID, resourceDomain, topFrameDomain1, topFrameDomain2, lastSeen, hadUserInteraction, mostRecentUserInteraction, isGrandfathered, isPrevalent, isVeryPrevalent, dataRecordsRemoved), WTFMove(completionHandler));
 }
 
+void NetworkProcessProxy::insertExpiredStatisticForTesting(PAL::SessionID sessionID, const RegistrableDomain& resourceDomain, bool hadUserInteraction, bool isScheduledForAllButCookieDataRemoval, bool isPrevalent, CompletionHandler<void()>&& completionHandler)
+{
+    sendWithAsyncReply(Messages::NetworkProcess::InsertExpiredStatisticForTesting(sessionID, resourceDomain, hadUserInteraction, isScheduledForAllButCookieDataRemoval, isPrevalent), WTFMove(completionHandler));
+}
+
 void NetworkProcessProxy::clearPrevalentResource(PAL::SessionID sessionID, const RegistrableDomain& resourceDomain, CompletionHandler<void()>&& completionHandler)
 {
     if (!canSendMessage()) {

Modified: branches/safari-609-branch/Source/WebKit/UIProcess/Network/NetworkProcessProxy.h (262553 => 262554)


--- branches/safari-609-branch/Source/WebKit/UIProcess/Network/NetworkProcessProxy.h	2020-06-04 19:00:39 UTC (rev 262553)
+++ branches/safari-609-branch/Source/WebKit/UIProcess/Network/NetworkProcessProxy.h	2020-06-04 19:00:47 UTC (rev 262554)
@@ -121,6 +121,7 @@
     void scheduleStatisticsAndDataRecordsProcessing(PAL::SessionID, CompletionHandler<void()>&&);
     void setLastSeen(PAL::SessionID, const RegistrableDomain&, Seconds, CompletionHandler<void()>&&);
     void mergeStatisticForTesting(PAL::SessionID, const RegistrableDomain&, const TopFrameDomain& topFrameDomain1, const TopFrameDomain& topFrameDomain2, Seconds lastSeen, bool hadUserInteraction, Seconds mostRecentUserInteraction, bool isGrandfathered, bool isPrevalent, bool isVeryPrevalent, unsigned dataRecordsRemoved, CompletionHandler<void()>&&);
+    void insertExpiredStatisticForTesting(PAL::SessionID, const RegistrableDomain&, bool hadUserInteraction, bool isScheduledForAllButCookieDataRemoval, bool isPrevalent, CompletionHandler<void()>&&);
     void setAgeCapForClientSideCookies(PAL::SessionID, Optional<Seconds>, CompletionHandler<void()>&&);
     void setCacheMaxAgeCap(PAL::SessionID, Seconds, CompletionHandler<void()>&&);
     void setGrandfathered(PAL::SessionID, const RegistrableDomain&, bool isGrandfathered, CompletionHandler<void()>&&);

Modified: branches/safari-609-branch/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp (262553 => 262554)


--- branches/safari-609-branch/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp	2020-06-04 19:00:39 UTC (rev 262553)
+++ branches/safari-609-branch/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp	2020-06-04 19:00:47 UTC (rev 262554)
@@ -1584,6 +1584,21 @@
     }
 }
 
+void WebsiteDataStore::insertExpiredStatisticForTesting(const URL& url, bool hadUserInteraction, bool isScheduledForAllButCookieDataRemoval, bool isPrevalent, CompletionHandler<void()>&& completionHandler)
+{
+    if (url.protocolIsAbout() || url.isEmpty()) {
+        completionHandler();
+        return;
+    }
+
+    auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
+
+    for (auto& processPool : processPools()) {
+        if (auto* process = processPool->networkProcess())
+            process->insertExpiredStatisticForTesting(m_sessionID, WebCore::RegistrableDomain { url }, hadUserInteraction, isScheduledForAllButCookieDataRemoval, isPrevalent, [processPool, callbackAggregator = callbackAggregator.copyRef()] { });
+    }
+}
+
 void WebsiteDataStore::setNotifyPagesWhenDataRecordsWereScanned(bool value, CompletionHandler<void()>&& completionHandler)
 {
     auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));

Modified: branches/safari-609-branch/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h (262553 => 262554)


--- branches/safari-609-branch/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h	2020-06-04 19:00:39 UTC (rev 262553)
+++ branches/safari-609-branch/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h	2020-06-04 19:00:47 UTC (rev 262554)
@@ -169,6 +169,7 @@
     void setGrandfatheringTime(Seconds, CompletionHandler<void()>&&);
     void setLastSeen(const URL&, Seconds, CompletionHandler<void()>&&);
     void mergeStatisticForTesting(const URL&, const URL& topFrameUrl1, const URL& topFrameUrl2, Seconds lastSeen, bool hadUserInteraction, Seconds mostRecentUserInteraction, bool isGrandfathered, bool isPrevalent, bool isVeryPrevalent, unsigned dataRecordsRemoved, CompletionHandler<void()>&&);
+    void insertExpiredStatisticForTesting(const URL&, bool hadUserInteraction, bool isScheduledForAllButCookieDataRemoval, bool isPrevalent, CompletionHandler<void()>&&);
     void setNotifyPagesWhenDataRecordsWereScanned(bool, CompletionHandler<void()>&&);
     void setIsRunningResourceLoadStatisticsTest(bool, CompletionHandler<void()>&&);
     void setPruneEntriesDownTo(size_t, CompletionHandler<void()>&&);

Modified: branches/safari-609-branch/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl (262553 => 262554)


--- branches/safari-609-branch/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl	2020-06-04 19:00:39 UTC (rev 262553)
+++ branches/safari-609-branch/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl	2020-06-04 19:00:47 UTC (rev 262554)
@@ -300,6 +300,7 @@
     void setStatisticsPrevalentResourceForDebugMode(DOMString hostName, object completionHandler);
     void setStatisticsLastSeen(DOMString hostName, double seconds, object completionHandler);
     void setStatisticsMergeStatistic(DOMString hostName, DOMString topFrameDomain1, DOMString topFrameDomain2, double lastSeen, boolean hadUserInteraction, double mostRecentUserInteraction, boolean isGrandfathered, boolean isPrevalent, boolean isVeryPrevalent, unsigned long dataRecordsRemoved, object completionHandler);
+    void setStatisticsExpiredStatistic(DOMString hostName, boolean hadUserInteraction, boolean isScheduledForAllButCookieDataRemoval, boolean isPrevalent, object completionHandler);
     void setStatisticsPrevalentResource(DOMString hostName, boolean value, object completionHandler);
     void setStatisticsVeryPrevalentResource(DOMString hostName, boolean value, object completionHandler);
     boolean isStatisticsPrevalentResource(DOMString hostName);

Modified: branches/safari-609-branch/Tools/WebKitTestRunner/InjectedBundle/InjectedBundle.cpp (262553 => 262554)


--- branches/safari-609-branch/Tools/WebKitTestRunner/InjectedBundle/InjectedBundle.cpp	2020-06-04 19:00:39 UTC (rev 262553)
+++ branches/safari-609-branch/Tools/WebKitTestRunner/InjectedBundle/InjectedBundle.cpp	2020-06-04 19:00:47 UTC (rev 262554)
@@ -371,6 +371,11 @@
         m_testRunner->statisticsCallDidSetMergeStatisticCallback();
         return;
     }
+    
+    if (WKStringIsEqualToUTF8CString(messageName, "CallDidSetExpiredStatistic")) {
+        m_testRunner->statisticsCallDidSetExpiredStatisticCallback();
+        return;
+    }
 
     if (WKStringIsEqualToUTF8CString(messageName, "CallDidSetPrevalentResource")) {
         m_testRunner->statisticsCallDidSetPrevalentResourceCallback();

Modified: branches/safari-609-branch/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp (262553 => 262554)


--- branches/safari-609-branch/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp	2020-06-04 19:00:39 UTC (rev 262553)
+++ branches/safari-609-branch/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp	2020-06-04 19:00:47 UTC (rev 262554)
@@ -741,6 +741,7 @@
     SetStatisticsPrevalentResourceForDebugModeCallbackID,
     SetStatisticsLastSeenCallbackID,
     SetStatisticsMergeStatisticCallbackID,
+    SetStatisticsExpiredStatisticCallbackID,
     SetStatisticsPrevalentResourceCallbackID,
     SetStatisticsVeryPrevalentResourceCallbackID,
     SetStatisticsHasHadUserInteractionCallbackID,
@@ -1531,6 +1532,42 @@
     callTestRunnerCallback(SetStatisticsMergeStatisticCallbackID);
 }
 
+void TestRunner::setStatisticsExpiredStatistic(JSStringRef hostName, bool hadUserInteraction, bool isScheduledForAllButCookieDataRemoval, bool isPrevalent, JSValueRef completionHandler)
+{
+    cacheTestRunnerCallback(SetStatisticsExpiredStatisticCallbackID, completionHandler);
+
+    Vector<WKRetainPtr<WKStringRef>> keys;
+    Vector<WKRetainPtr<WKTypeRef>> values;
+
+    keys.append(adoptWK(WKStringCreateWithUTF8CString("HostName")));
+    values.append(adoptWK(WKStringCreateWithJSString(hostName)));
+
+    keys.append(adoptWK(WKStringCreateWithUTF8CString("HadUserInteraction")));
+    values.append(adoptWK(WKBooleanCreate(hadUserInteraction)));
+
+    keys.append(adoptWK(WKStringCreateWithUTF8CString("IsScheduledForAllButCookieDataRemoval")));
+    values.append(adoptWK(WKBooleanCreate(isScheduledForAllButCookieDataRemoval)));
+
+    keys.append(adoptWK(WKStringCreateWithUTF8CString("IsPrevalent")));
+    values.append(adoptWK(WKBooleanCreate(isPrevalent)));
+
+    Vector<WKStringRef> rawKeys(keys.size());
+    Vector<WKTypeRef> rawValues(values.size());
+
+    for (size_t i = 0; i < keys.size(); ++i) {
+        rawKeys[i] = keys[i].get();
+        rawValues[i] = values[i].get();
+    }
+    WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("SetStatisticsExpiredStatistic"));
+    WKRetainPtr<WKDictionaryRef> messageBody = adoptWK(WKDictionaryCreate(rawKeys.data(), rawValues.data(), rawKeys.size()));
+    WKBundlePostMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get());
+}
+
+void TestRunner::statisticsCallDidSetExpiredStatisticCallback()
+{
+    callTestRunnerCallback(SetStatisticsExpiredStatisticCallbackID);
+}
+
 void TestRunner::setStatisticsPrevalentResource(JSStringRef hostName, bool value, JSValueRef completionHandler)
 {
     cacheTestRunnerCallback(SetStatisticsPrevalentResourceCallbackID, completionHandler);

Modified: branches/safari-609-branch/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h (262553 => 262554)


--- branches/safari-609-branch/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h	2020-06-04 19:00:39 UTC (rev 262553)
+++ branches/safari-609-branch/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h	2020-06-04 19:00:47 UTC (rev 262554)
@@ -400,6 +400,8 @@
     void statisticsCallDidSetLastSeenCallback();
     void setStatisticsMergeStatistic(JSStringRef hostName, JSStringRef topFrameDomain1, JSStringRef topFrameDomain2, double lastSeen, bool hadUserInteraction, double mostRecentUserInteraction, bool isGrandfathered, bool isPrevalent, bool isVeryPrevalent, unsigned dataRecordsRemoved, JSValueRef completionHandler);
     void statisticsCallDidSetMergeStatisticCallback();
+    void setStatisticsExpiredStatistic(JSStringRef hostName, bool hadUserInteraction, bool isScheduledForAllButCookieDataRemoval, bool isPrevalent, JSValueRef completionHandler);
+    void statisticsCallDidSetExpiredStatisticCallback();
     void setStatisticsPrevalentResource(JSStringRef hostName, bool value, JSValueRef completionHandler);
     void statisticsCallDidSetPrevalentResourceCallback();
     void setStatisticsVeryPrevalentResource(JSStringRef hostName, bool value, JSValueRef completionHandler);

Modified: branches/safari-609-branch/Tools/WebKitTestRunner/TestController.cpp (262553 => 262554)


--- branches/safari-609-branch/Tools/WebKitTestRunner/TestController.cpp	2020-06-04 19:00:39 UTC (rev 262553)
+++ branches/safari-609-branch/Tools/WebKitTestRunner/TestController.cpp	2020-06-04 19:00:47 UTC (rev 262554)
@@ -3351,6 +3351,14 @@
     m_currentInvocation->didMergeStatistic();
 }
 
+void TestController::setStatisticsExpiredStatistic(WKStringRef host, bool hadUserInteraction, bool isScheduledForAllButCookieDataRemoval, bool isPrevalent)
+{
+    ResourceStatisticsCallbackContext context(*this);
+    WKWebsiteDataStoreSetStatisticsExpiredStatistic(websiteDataStore(), host, hadUserInteraction, isScheduledForAllButCookieDataRemoval, isPrevalent, &context, resourceStatisticsVoidResultCallback);
+    runUntil(context.done, noTimeout);
+    m_currentInvocation->didSetExpiredStatistic();
+}
+
 void TestController::setStatisticsPrevalentResource(WKStringRef host, bool value)
 {
     ResourceStatisticsCallbackContext context(*this);

Modified: branches/safari-609-branch/Tools/WebKitTestRunner/TestController.h (262553 => 262554)


--- branches/safari-609-branch/Tools/WebKitTestRunner/TestController.h	2020-06-04 19:00:39 UTC (rev 262553)
+++ branches/safari-609-branch/Tools/WebKitTestRunner/TestController.h	2020-06-04 19:00:47 UTC (rev 262554)
@@ -212,6 +212,7 @@
     void setStatisticsPrevalentResourceForDebugMode(WKStringRef hostName);
     void setStatisticsLastSeen(WKStringRef hostName, double seconds);
     void setStatisticsMergeStatistic(WKStringRef host, WKStringRef topFrameDomain1, WKStringRef topFrameDomain2, double lastSeen, bool hadUserInteraction, double mostRecentUserInteraction, bool isGrandfathered, bool isPrevalent, bool isVeryPrevalent, int dataRecordsRemoved);
+    void setStatisticsExpiredStatistic(WKStringRef host, bool hadUserInteraction, bool isScheduledForAllButCookieDataRemoval, bool isPrevalent);
     void setStatisticsPrevalentResource(WKStringRef hostName, bool value);
     void setStatisticsVeryPrevalentResource(WKStringRef hostName, bool value);
     String dumpResourceLoadStatistics();

Modified: branches/safari-609-branch/Tools/WebKitTestRunner/TestInvocation.cpp (262553 => 262554)


--- branches/safari-609-branch/Tools/WebKitTestRunner/TestInvocation.cpp	2020-06-04 19:00:39 UTC (rev 262553)
+++ branches/safari-609-branch/Tools/WebKitTestRunner/TestInvocation.cpp	2020-06-04 19:00:47 UTC (rev 262554)
@@ -787,6 +787,25 @@
         return;
     }
 
+    if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsExpiredStatistic")) {
+        ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
+
+        WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
+        WKRetainPtr<WKStringRef> hostNameKey = adoptWK(WKStringCreateWithUTF8CString("HostName"));
+        WKRetainPtr<WKStringRef> hadUserInteractionKey = adoptWK(WKStringCreateWithUTF8CString("HadUserInteraction"));
+        WKRetainPtr<WKStringRef> mostRecentUserInteractionKey = adoptWK(WKStringCreateWithUTF8CString("MostRecentUserInteraction"));
+        WKRetainPtr<WKStringRef> isScheduledForAllButCookieDataRemovalKey = adoptWK(WKStringCreateWithUTF8CString("IsScheduledForAllButCookieDataRemoval"));
+        WKRetainPtr<WKStringRef> isPrevalentKey = adoptWK(WKStringCreateWithUTF8CString("IsPrevalent"));
+
+        WKStringRef hostName = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, hostNameKey.get()));
+        WKBooleanRef hadUserInteraction = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, hadUserInteractionKey.get()));
+        WKBooleanRef isScheduledForAllButCookieDataRemoval = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, isScheduledForAllButCookieDataRemovalKey.get()));
+        WKBooleanRef isPrevalent = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, isPrevalentKey.get()));
+
+        TestController::singleton().setStatisticsExpiredStatistic(hostName, WKBooleanGetValue(hadUserInteraction), WKBooleanGetValue(isScheduledForAllButCookieDataRemoval), WKBooleanGetValue(isPrevalent));
+        return;
+    }
+
 #if PLATFORM(IOS_FAMILY)
     if (WKStringIsEqualToUTF8CString(messageName, "SetOpenPanelFileURLsMediaIcon")) {
         TestController::singleton().setOpenPanelFileURLsMediaIcon(static_cast<WKDataRef>(messageBody));
@@ -1911,6 +1930,12 @@
     WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
 }
 
+void TestInvocation::didSetExpiredStatistic()
+{
+    WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallDidSetExpiredStatistic"));
+    WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
+}
+
 void TestInvocation::didSetPrevalentResource()
 {
     WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallDidSetPrevalentResource"));

Modified: branches/safari-609-branch/Tools/WebKitTestRunner/TestInvocation.h (262553 => 262554)


--- branches/safari-609-branch/Tools/WebKitTestRunner/TestInvocation.h	2020-06-04 19:00:39 UTC (rev 262553)
+++ branches/safari-609-branch/Tools/WebKitTestRunner/TestInvocation.h	2020-06-04 19:00:47 UTC (rev 262554)
@@ -82,6 +82,7 @@
     void didSetPrevalentResourceForDebugMode();
     void didSetLastSeen();
     void didMergeStatistic();
+    void didSetExpiredStatistic();
     void didSetPrevalentResource();
     void didSetVeryPrevalentResource();
     void didSetHasHadUserInteraction();
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to