Diff
Modified: trunk/LayoutTests/ChangeLog (261241 => 261242)
--- trunk/LayoutTests/ChangeLog 2020-05-06 18:43:19 UTC (rev 261241)
+++ trunk/LayoutTests/ChangeLog 2020-05-06 18:44:26 UTC (rev 261242)
@@ -1,3 +1,18 @@
+2020-05-06 John Wilander <wilan...@apple.com>
+
+ Exempt app-bound domains from ITP's website data deletion and third-party cookie blocking between themselves
+ https://bugs.webkit.org/show_bug.cgi?id=210674
+ <rdar://problem/61950767>
+
+ Reviewed by Chris Dumez.
+
+ * http/tests/resourceLoadStatistics/exemptDomains/app-bound-domains-exempt-from-cookie-blocking-between-each-other-expected.txt: Added.
+ * http/tests/resourceLoadStatistics/exemptDomains/app-bound-domains-exempt-from-cookie-blocking-between-each-other.html: Added.
+ * http/tests/resourceLoadStatistics/exemptDomains/app-bound-domains-exempt-from-website-data-deletion-database-expected.txt: Added.
+ * http/tests/resourceLoadStatistics/exemptDomains/app-bound-domains-exempt-from-website-data-deletion-database.html: Added.
+ * http/tests/resourceLoadStatistics/exemptDomains/app-bound-domains-exempt-from-website-data-deletion-expected.txt: Added.
+ * http/tests/resourceLoadStatistics/exemptDomains/app-bound-domains-exempt-from-website-data-deletion.html: Added.
+
2020-05-06 Daniel Bates <daba...@apple.com>
[iOS] ASSERTION FAILED: !(_keyboardFlags & WebEventKeyboardInputModifierFlagsChanged) in -[WebEvent charactersIgnoringModifiers] when pressing modifier on PDF
Added: trunk/LayoutTests/http/tests/resourceLoadStatistics/exemptDomains/app-bound-domains-exempt-from-cookie-blocking-between-each-other-expected.txt (0 => 261242)
--- trunk/LayoutTests/http/tests/resourceLoadStatistics/exemptDomains/app-bound-domains-exempt-from-cookie-blocking-between-each-other-expected.txt (rev 0)
+++ trunk/LayoutTests/http/tests/resourceLoadStatistics/exemptDomains/app-bound-domains-exempt-from-cookie-blocking-between-each-other-expected.txt 2020-05-06 18:44:26 UTC (rev 261242)
@@ -0,0 +1,33 @@
+Tests that app-bound domains are exempt from third-party cookie blocking between themselves.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
+
+--------
+Frame: '<!--frame1-->'
+--------
+Should not receive cookie.
+Did not receive cookie named 'firstPartyCookie'.
+Did not receive cookie named 'partitionedCookie'.
+Client-side document.cookie:
+
+--------
+Frame: '<!--frame2-->'
+--------
+Should not receive cookie.
+Did not receive cookie named 'firstPartyCookie'.
+Did not receive cookie named 'partitionedCookie'.
+Client-side document.cookie:
+
+--------
+Frame: '<!--frame3-->'
+--------
+Should receive cookie.
+Received cookie named 'firstPartyCookie'.
+Did not receive cookie named 'partitionedCookie'.
+Client-side document.cookie: firstPartyCookie=value
Added: trunk/LayoutTests/http/tests/resourceLoadStatistics/exemptDomains/app-bound-domains-exempt-from-cookie-blocking-between-each-other.html (0 => 261242)
--- trunk/LayoutTests/http/tests/resourceLoadStatistics/exemptDomains/app-bound-domains-exempt-from-cookie-blocking-between-each-other.html (rev 0)
+++ trunk/LayoutTests/http/tests/resourceLoadStatistics/exemptDomains/app-bound-domains-exempt-from-cookie-blocking-between-each-other.html 2020-05-06 18:44:26 UTC (rev 261242)
@@ -0,0 +1,83 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <script src=""
+ <script src=""
+</head>
+<body>
+<script>
+ description("Tests that app-bound domains are exempt from third-party cookie blocking between themselves.");
+ jsTestIsAsync = true;
+
+ const firstPartyOrigin = "http://127.0.0.1:8000";
+ const thirdPartyOrigin = "http://localhost:8000";
+ const thirdPartyResourceUrl = thirdPartyOrigin + "/resourceLoadStatistics/resources";
+ const firstPartyCookieName = "firstPartyCookie";
+ const subPathToSetFirstPartyCookie = "/set-cookie.php?name=" + firstPartyCookieName + "&value=value";
+ const partitionedCookieName = "partitionedCookie";
+ const subPathToSetPartitionedCookie = "/set-cookie.php?name=" + partitionedCookieName + "&value=value";
+ const returnUrl = firstPartyOrigin + "/resourceLoadStatistics/exemptDomains/app-bound-domains-exempt-from-cookie-blocking-between-each-other.html";
+ const subPathToGetCookies = "/get-cookies.php?name1=" + firstPartyCookieName + "&name2=" + partitionedCookieName;
+ const redirectChainUrl = thirdPartyResourceUrl + "/redirect.php?redirectTo=" + thirdPartyResourceUrl + subPathToGetCookies;
+
+ function openIframe(url, onLoadHandler) {
+ const element = document.createElement("iframe");
+ element.src = ""
+ if (onLoadHandler) {
+ element._onload_ = onLoadHandler;
+ }
+ document.body.appendChild(element);
+ }
+
+ function runTest() {
+ switch (document.location.hash) {
+ case "#step1":
+ // Set first-party cookie for localhost.
+ document.location.href = "" + subPathToSetFirstPartyCookie + "#" + returnUrl + "#step2";
+ break;
+ case "#step2":
+ // Check that the cookie doesn't get sent for localhost under 127.0.0.1 since only localhost is configured as an app-bound domain.
+ document.location.hash = "step3";
+ testRunner.setAppBoundDomains([ thirdPartyOrigin ], function() {
+ openIframe(thirdPartyResourceUrl + subPathToGetCookies + "&message=Should not receive cookie.", function() {
+ runTest();
+ });
+ });
+ break;
+ case "#step3":
+ // Check that the cookie doesn't get sent for localhost under 127.0.0.1 since only 127.0.0.1 is configured as an app-bound domain.
+ document.location.hash = "step4";
+ testRunner.setAppBoundDomains([ firstPartyOrigin ], function() {
+ openIframe(thirdPartyResourceUrl + subPathToGetCookies + "&message=Should not receive cookie.", function() {
+ runTest();
+ });
+ });
+ break;
+ case "#step4":
+ // Check that the cookie gets sent for localhost under 127.0.0.1 since they are now both configured as app-bound domains.
+ document.location.hash = "step5";
+ testRunner.setAppBoundDomains([ firstPartyOrigin, thirdPartyOrigin ], function() {
+ openIframe(thirdPartyResourceUrl + subPathToGetCookies + "&message=Should receive cookie.", runTest);
+ });
+ break;
+ case "#step5":
+ testRunner.setStatisticsShouldBlockThirdPartyCookies(false, function() {
+ setEnableFeature(false, finishJSTest);
+ });
+ break;
+ }
+ }
+
+ if (document.location.hash === "") {
+ setEnableFeature(true, function () {
+ testRunner.dumpChildFramesAsText();
+ document.location.hash = "step1";
+ runTest();
+ });
+ } else {
+ runTest();
+ }
+</script>
+</body>
+</html>
Added: trunk/LayoutTests/http/tests/resourceLoadStatistics/exemptDomains/app-bound-domains-exempt-from-website-data-deletion-database-expected.txt (0 => 261242)
--- trunk/LayoutTests/http/tests/resourceLoadStatistics/exemptDomains/app-bound-domains-exempt-from-website-data-deletion-database-expected.txt (rev 0)
+++ trunk/LayoutTests/http/tests/resourceLoadStatistics/exemptDomains/app-bound-domains-exempt-from-website-data-deletion-database-expected.txt 2020-05-06 18:44:26 UTC (rev 261242)
@@ -0,0 +1,15 @@
+Check that website data does not get removed after a period of no user interaction if the website is app-bound.
+
+Before deletion: Client-side cookie exists.
+Before deletion: HttpOnly cookie exists.
+Before deletion: Regular server-side cookie exists.
+Before deletion: LocalStorage entry does exist.
+Before deletion: IDB entry does exist.
+
+After deletion: HttpOnly cookie exists.
+After deletion: Client-side cookie exists.
+After deletion: Regular server-side cookie exists.
+After deletion: LocalStorage entry does exist.
+After deletion: IDB entry does exist.
+
+
Added: trunk/LayoutTests/http/tests/resourceLoadStatistics/exemptDomains/app-bound-domains-exempt-from-website-data-deletion-database.html (0 => 261242)
--- trunk/LayoutTests/http/tests/resourceLoadStatistics/exemptDomains/app-bound-domains-exempt-from-website-data-deletion-database.html (rev 0)
+++ trunk/LayoutTests/http/tests/resourceLoadStatistics/exemptDomains/app-bound-domains-exempt-from-website-data-deletion-database.html 2020-05-06 18:44:26 UTC (rev 261242)
@@ -0,0 +1,256 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src=""
+ <script src=""
+</head>
+<body _onload_="setTimeout('runTest()', 0)">
+<div id="description">Check that website data does not get removed after a period of no user interaction if the website is app-bound.</div>
+<br>
+<div id="output"></div>
+<br>
+<script>
+ testRunner.waitUntilDone();
+ testRunner.dumpAsText();
+ testRunner.setUseITPDatabase(true);
+
+ 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)
+ addOutput((isAfterDeletion ? "After" : "Before") + " script-accessible deletion: No cookies found.");
+ for (let cookie of cookies) {
+ switch (cookie.name) {
+ case httpOnlyCookieName:
+ unsortedTestPassedMessages.push((isAfterDeletion ? "After" : "Before") + " deletion: " + (isAfterDeletion ? " " : "") + "HttpOnly cookie exists.");
+ break;
+ case serverSideCookieName:
+ unsortedTestPassedMessages.push((isAfterDeletion ? "After" : "Before") + " deletion: Regular server-side cookie exists.");
+ break;
+ case clientSideCookieName:
+ unsortedTestPassedMessages.push((isAfterDeletion ? "After" : "Before") + " deletion: 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 deletion: 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 deletion: IDB entry does exist.");
+ semaphoreIDBCheck = false;
+ checkIDBCallback();
+ };
+ }
+ }, 200);
+ } else {
+ // Check until there is a IDB.
+ checkIDBIntervalID = setInterval(function () {
+ if (semaphoreIDBCheck)
+ return;
+ semaphoreIDBCheck = true;
+
+ if (++intervalCounterIDB >= maxIntervals) {
+ clearInterval(checkIDBIntervalID);
+ addOutput("After deletion: IDB entry checks exhausted.");
+ 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("After deletion: IDB entry does exist.");
+ semaphoreIDBCheck = false;
+ checkIDBCallback();
+ };
+ }
+ }, 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 deletion: LocalStorage entry " + (value === localStorageValue ? "does" : "does not") + " exist.");
+ checkLocalStorageCallback();
+ } else if (testRunner.isStatisticsHasLocalStorage(originUnderTest)) {
+ clearInterval(checkLocalStorageIntervalID);
+ let value = localStorage.getItem(localStorageName);
+ addOutput("Before deletion: 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 deletion: LocalStorage entry " + (value === localStorageValue ? "does" : "does not") + " exist.");
+ checkLocalStorageCallback();
+ } else if (!testRunner.isStatisticsHasLocalStorage(originUnderTest)) {
+ clearInterval(checkLocalStorageIntervalID);
+ let value = localStorage.getItem(localStorageName);
+ addOutput("After deletion: 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);
+ });
+ }
+
+ function finishTest() {
+ resetCookies();
+ testRunner.setStatisticsFirstPartyWebsiteDataRemovalMode(false, function() {
+ setEnableFeature(false, function() {
+ testRunner.notifyDone();
+ });
+ });
+ }
+
+ const originUnderTest = "http://127.0.0.1:8000";
+ function runTest() {
+ setEnableFeature(true, function () {
+ testRunner.setAppBoundDomains([ originUnderTest ], function() {
+ testRunner.setStatisticsFirstPartyWebsiteDataRemovalMode(true, function() {
+ testRunner.setStatisticsPrevalentResource(originUnderTest, true, function() {
+ if (!testRunner.isStatisticsPrevalentResource(originUnderTest))
+ addOutput("FAIL: " + originUnderTest + " didn't get classified as prevalent.");
+ writeWebsiteDataAndContinue();
+ });
+ });
+ });
+ });
+ }
+</script>
+</body>
+</html>
Added: trunk/LayoutTests/http/tests/resourceLoadStatistics/exemptDomains/app-bound-domains-exempt-from-website-data-deletion-expected.txt (0 => 261242)
--- trunk/LayoutTests/http/tests/resourceLoadStatistics/exemptDomains/app-bound-domains-exempt-from-website-data-deletion-expected.txt (rev 0)
+++ trunk/LayoutTests/http/tests/resourceLoadStatistics/exemptDomains/app-bound-domains-exempt-from-website-data-deletion-expected.txt 2020-05-06 18:44:26 UTC (rev 261242)
@@ -0,0 +1,15 @@
+Check that website data does not get removed after a period of no user interaction if the website is app-bound.
+
+Before deletion: Client-side cookie exists.
+Before deletion: HttpOnly cookie exists.
+Before deletion: Regular server-side cookie exists.
+Before deletion: LocalStorage entry does exist.
+Before deletion: IDB entry does exist.
+
+After deletion: HttpOnly cookie exists.
+After deletion: Client-side cookie exists.
+After deletion: Regular server-side cookie exists.
+After deletion: LocalStorage entry does exist.
+After deletion: IDB entry does exist.
+
+
Added: trunk/LayoutTests/http/tests/resourceLoadStatistics/exemptDomains/app-bound-domains-exempt-from-website-data-deletion.html (0 => 261242)
--- trunk/LayoutTests/http/tests/resourceLoadStatistics/exemptDomains/app-bound-domains-exempt-from-website-data-deletion.html (rev 0)
+++ trunk/LayoutTests/http/tests/resourceLoadStatistics/exemptDomains/app-bound-domains-exempt-from-website-data-deletion.html 2020-05-06 18:44:26 UTC (rev 261242)
@@ -0,0 +1,255 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src=""
+ <script src=""
+</head>
+<body _onload_="setTimeout('runTest()', 0)">
+<div id="description">Check that website data does not get removed after a period of no user interaction if the website is app-bound.</div>
+<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)
+ addOutput((isAfterDeletion ? "After" : "Before") + " script-accessible deletion: No cookies found.");
+ for (let cookie of cookies) {
+ switch (cookie.name) {
+ case httpOnlyCookieName:
+ unsortedTestPassedMessages.push((isAfterDeletion ? "After" : "Before") + " deletion: " + (isAfterDeletion ? " " : "") + "HttpOnly cookie exists.");
+ break;
+ case serverSideCookieName:
+ unsortedTestPassedMessages.push((isAfterDeletion ? "After" : "Before") + " deletion: Regular server-side cookie exists.");
+ break;
+ case clientSideCookieName:
+ unsortedTestPassedMessages.push((isAfterDeletion ? "After" : "Before") + " deletion: 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 deletion: 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 deletion: IDB entry does exist.");
+ semaphoreIDBCheck = false;
+ checkIDBCallback();
+ };
+ }
+ }, 200);
+ } else {
+ // Check until there is a IDB.
+ checkIDBIntervalID = setInterval(function () {
+ if (semaphoreIDBCheck)
+ return;
+ semaphoreIDBCheck = true;
+
+ if (++intervalCounterIDB >= maxIntervals) {
+ clearInterval(checkIDBIntervalID);
+ addOutput("After deletion: IDB entry checks exhausted.");
+ 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("After deletion: IDB entry does exist.");
+ semaphoreIDBCheck = false;
+ checkIDBCallback();
+ };
+ }
+ }, 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 deletion: LocalStorage entry " + (value === localStorageValue ? "does" : "does not") + " exist.");
+ checkLocalStorageCallback();
+ } else if (testRunner.isStatisticsHasLocalStorage(originUnderTest)) {
+ clearInterval(checkLocalStorageIntervalID);
+ let value = localStorage.getItem(localStorageName);
+ addOutput("Before deletion: 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 deletion: LocalStorage entry " + (value === localStorageValue ? "does" : "does not") + " exist.");
+ checkLocalStorageCallback();
+ } else if (!testRunner.isStatisticsHasLocalStorage(originUnderTest)) {
+ clearInterval(checkLocalStorageIntervalID);
+ let value = localStorage.getItem(localStorageName);
+ addOutput("After deletion: 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);
+ });
+ }
+
+ function finishTest() {
+ resetCookies();
+ testRunner.setStatisticsFirstPartyWebsiteDataRemovalMode(false, function() {
+ setEnableFeature(false, function() {
+ testRunner.notifyDone();
+ });
+ });
+ }
+
+ const originUnderTest = "http://127.0.0.1:8000";
+ function runTest() {
+ setEnableFeature(true, function () {
+ testRunner.setAppBoundDomains([ originUnderTest ], function() {
+ testRunner.setStatisticsFirstPartyWebsiteDataRemovalMode(true, function() {
+ testRunner.setStatisticsPrevalentResource(originUnderTest, true, function() {
+ if (!testRunner.isStatisticsPrevalentResource(originUnderTest))
+ addOutput("FAIL: " + originUnderTest + " didn't get classified as prevalent.");
+ writeWebsiteDataAndContinue();
+ });
+ });
+ });
+ });
+ }
+</script>
+</body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (261241 => 261242)
--- trunk/Source/WebCore/ChangeLog 2020-05-06 18:43:19 UTC (rev 261241)
+++ trunk/Source/WebCore/ChangeLog 2020-05-06 18:44:26 UTC (rev 261242)
@@ -1,3 +1,25 @@
+2020-05-06 John Wilander <wilan...@apple.com>
+
+ Exempt app-bound domains from ITP's website data deletion and third-party cookie blocking between themselves
+ https://bugs.webkit.org/show_bug.cgi?id=210674
+ <rdar://problem/61950767>
+
+ Reviewed by Chris Dumez.
+
+ This change adds functionality to NetworkStorageSession to allow it to exempt
+ app-bound domains from third-party cookie blocking.
+
+ Tests: http/tests/resourceLoadStatistics/exemptDomains/app-bound-domains-exempt-from-cookie-blocking-between-each-other.html
+ http/tests/resourceLoadStatistics/exemptDomains/app-bound-domains-exempt-from-website-data-deletion-database.html
+ http/tests/resourceLoadStatistics/exemptDomains/app-bound-domains-exempt-from-website-data-deletion.html
+
+ * platform/network/NetworkStorageSession.cpp:
+ (WebCore::NetworkStorageSession::shouldBlockCookies const):
+ (WebCore::NetworkStorageSession::shouldExemptDomainPairFromThirdPartyCookieBlocking const):
+ (WebCore::NetworkStorageSession::setAppBoundDomains):
+ (WebCore::NetworkStorageSession::resetAppBoundDomains):
+ * platform/network/NetworkStorageSession.h:
+
2020-05-06 Antti Koivisto <an...@apple.com>
Add basic support for generating accurate wheel event listener region
Modified: trunk/Source/WebCore/platform/network/NetworkStorageSession.cpp (261241 => 261242)
--- trunk/Source/WebCore/platform/network/NetworkStorageSession.cpp 2020-05-06 18:43:19 UTC (rev 261241)
+++ trunk/Source/WebCore/platform/network/NetworkStorageSession.cpp 2020-05-06 18:44:26 UTC (rev 261242)
@@ -134,6 +134,8 @@
switch (m_thirdPartyCookieBlockingMode) {
case ThirdPartyCookieBlockingMode::All:
return true;
+ case ThirdPartyCookieBlockingMode::AllExceptBetweenAppBoundDomains:
+ return !shouldExemptDomainPairFromThirdPartyCookieBlocking(firstPartyDomain, resourceDomain);
case ThirdPartyCookieBlockingMode::AllOnSitesWithoutUserInteraction:
if (!hasHadUserInteractionAsFirstParty(firstPartyDomain))
return true;
@@ -145,6 +147,15 @@
return false;
}
+bool NetworkStorageSession::shouldExemptDomainPairFromThirdPartyCookieBlocking(const RegistrableDomain& topFrameDomain, const RegistrableDomain& resourceDomain) const
+{
+ ASSERT(topFrameDomain != resourceDomain);
+ if (topFrameDomain.isEmpty() || resourceDomain.isEmpty())
+ return false;
+
+ return topFrameDomain == resourceDomain || (m_appBoundDomains.contains(topFrameDomain) && m_appBoundDomains.contains(resourceDomain));
+}
+
Optional<Seconds> NetworkStorageSession::maxAgeCacheCap(const ResourceRequest& request)
{
if (m_cacheMaxAgeCapForPrevalentResources && shouldBlockCookies(request, WTF::nullopt, WTF::nullopt))
@@ -292,6 +303,16 @@
m_thirdPartyCookieBlockingMode = blockingMode;
}
+void NetworkStorageSession::setAppBoundDomains(HashSet<RegistrableDomain>&& domains)
+{
+ m_appBoundDomains = WTFMove(domains);
+}
+
+void NetworkStorageSession::resetAppBoundDomains()
+{
+ m_appBoundDomains.clear();
+}
+
Optional<Seconds> NetworkStorageSession::clientSideCookieCap(const RegistrableDomain& firstParty, Optional<PageIdentifier> pageID) const
{
if (!m_ageCapForClientSideCookies || !pageID || m_navigatedToWithLinkDecorationByPrevalentResource.isEmpty())
Modified: trunk/Source/WebCore/platform/network/NetworkStorageSession.h (261241 => 261242)
--- trunk/Source/WebCore/platform/network/NetworkStorageSession.h 2020-05-06 18:43:19 UTC (rev 261241)
+++ trunk/Source/WebCore/platform/network/NetworkStorageSession.h 2020-05-06 18:44:26 UTC (rev 261242)
@@ -77,7 +77,7 @@
enum class HTTPCookieAcceptPolicy : uint8_t;
enum class IncludeSecureCookies : bool;
enum class IncludeHttpOnlyCookies : bool;
-enum class ThirdPartyCookieBlockingMode : uint8_t { All, AllOnSitesWithoutUserInteraction, OnlyAccordingToPerDomainPolicy };
+enum class ThirdPartyCookieBlockingMode : uint8_t { All, AllExceptBetweenAppBoundDomains, AllOnSitesWithoutUserInteraction, OnlyAccordingToPerDomainPolicy };
enum class SameSiteStrictEnforcementEnabled : bool { Yes, No };
enum class FirstPartyWebsiteDataRemovalMode : uint8_t { AllButCookies, None, AllButCookiesLiveOnTestingTimeout, AllButCookiesReproTestingTimeout };
enum class ShouldAskITP : bool { No, Yes };
@@ -95,6 +95,9 @@
class NetworkStorageSession {
WTF_MAKE_NONCOPYABLE(NetworkStorageSession); WTF_MAKE_FAST_ALLOCATED;
public:
+ using TopFrameDomain = WebCore::RegistrableDomain;
+ using SubResourceDomain = WebCore::RegistrableDomain;
+
WEBCORE_EXPORT static void permitProcessToUseCookieAPI(bool);
WEBCORE_EXPORT static bool processMayUseCookieAPI();
@@ -196,6 +199,8 @@
WEBCORE_EXPORT void didCommitCrossSiteLoadWithDataTransferFromPrevalentResource(const RegistrableDomain& toDomain, PageIdentifier);
WEBCORE_EXPORT void resetCrossSiteLoadsWithLinkDecorationForTesting();
WEBCORE_EXPORT void setThirdPartyCookieBlockingMode(ThirdPartyCookieBlockingMode);
+ WEBCORE_EXPORT void setAppBoundDomains(HashSet<RegistrableDomain>&&);
+ WEBCORE_EXPORT void resetAppBoundDomains();
#endif
private:
@@ -241,7 +246,8 @@
#if ENABLE(RESOURCE_LOAD_STATISTICS)
bool m_isResourceLoadStatisticsEnabled = false;
- Optional<Seconds> clientSideCookieCap(const RegistrableDomain& firstParty, Optional<PageIdentifier>) const;
+ Optional<Seconds> clientSideCookieCap(const TopFrameDomain&, Optional<PageIdentifier>) const;
+ bool shouldExemptDomainPairFromThirdPartyCookieBlocking(const TopFrameDomain&, const SubResourceDomain&) const;
HashSet<RegistrableDomain> m_registrableDomainsToBlockAndDeleteCookiesFor;
HashSet<RegistrableDomain> m_registrableDomainsToBlockButKeepCookiesFor;
HashSet<RegistrableDomain> m_registrableDomainsWithUserInteractionAsFirstParty;
@@ -253,6 +259,7 @@
HashMap<WebCore::PageIdentifier, RegistrableDomain> m_navigatedToWithLinkDecorationByPrevalentResource;
bool m_navigationWithLinkDecorationTestMode = false;
ThirdPartyCookieBlockingMode m_thirdPartyCookieBlockingMode { ThirdPartyCookieBlockingMode::All };
+ HashSet<RegistrableDomain> m_appBoundDomains;
#endif
#if PLATFORM(COCOA)
@@ -277,6 +284,7 @@
using values = EnumValues<
WebCore::ThirdPartyCookieBlockingMode,
WebCore::ThirdPartyCookieBlockingMode::All,
+ WebCore::ThirdPartyCookieBlockingMode::AllExceptBetweenAppBoundDomains,
WebCore::ThirdPartyCookieBlockingMode::AllOnSitesWithoutUserInteraction,
WebCore::ThirdPartyCookieBlockingMode::OnlyAccordingToPerDomainPolicy
>;
Modified: trunk/Source/WebKit/ChangeLog (261241 => 261242)
--- trunk/Source/WebKit/ChangeLog 2020-05-06 18:43:19 UTC (rev 261241)
+++ trunk/Source/WebKit/ChangeLog 2020-05-06 18:44:26 UTC (rev 261242)
@@ -1,3 +1,99 @@
+2020-05-06 John Wilander <wilan...@apple.com>
+
+ Exempt app-bound domains from ITP's website data deletion and third-party cookie blocking between themselves
+ https://bugs.webkit.org/show_bug.cgi?id=210674
+ <rdar://problem/61950767>
+
+ Reviewed by Chris Dumez.
+
+ This change forwards information about app-bound domains to ITP and web
+ processes so that they can be exempt from website data deletion and
+ third-party cookie blocking between themselves.
+
+ App-bound domains are configured statically and apply to all website
+ data stores. Therefore the setting needs to be forwarded to all
+ website data stores and ITP functionality in all network and web
+ content processes. This is done through the new static function
+ WebsiteDataStore::setAppBoundDomainsForITPIfInitialized().
+
+ Since app-bound domains are loaded lazily from disk and on a background
+ thread, this patch forwards them in ResourceLoadStatisticsParameters if
+ they've already been loaded. Then every time app-bound domains are
+ updated, they are forwarded to ITP. This ensures that ITP will have them
+ as soon as possible.
+
+ Setting app-bound domains for the purposes of ITP automatically switches
+ ITP's cookie blocking policy to the new
+ WebCore::ThirdPartyCookieBlockingMode::AllExceptBetweenAppBoundDomains.
+ This is done in WebResourceLoadStatisticsStore::setAppBoundDomains().
+
+ The C API changes are for test purposes.
+
+ * NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.cpp:
+ * NetworkProcess/Classifier/ResourceLoadStatisticsMemoryStore.cpp:
+ (WebKit::ResourceLoadStatisticsMemoryStore::registrableDomainsToDeleteOrRestrictWebsiteDataFor):
+ * NetworkProcess/Classifier/ResourceLoadStatisticsStore.cpp:
+ (WebKit::ResourceLoadStatisticsStore::setAppBoundDomains):
+ (WebKit::ResourceLoadStatisticsStore::resetParametersToDefaultValues):
+ (WebKit::ResourceLoadStatisticsStore::shouldExemptFromWebsiteDataDeletion const):
+ * NetworkProcess/Classifier/ResourceLoadStatisticsStore.h:
+ (WebKit::ResourceLoadStatisticsStore::standaloneApplicationDomain const): Deleted.
+ * NetworkProcess/Classifier/WebResourceLoadStatisticsStore.cpp:
+ (WebKit::WebResourceLoadStatisticsStore::setAppBoundDomains):
+ (WebKit::WebResourceLoadStatisticsStore::resetParametersToDefaultValues):
+ * NetworkProcess/Classifier/WebResourceLoadStatisticsStore.h:
+ * NetworkProcess/NetworkProcess.cpp:
+ (WebKit::NetworkProcess::setAppBoundDomainsForResourceLoadStatistics):
+ (WebKit::NetworkProcess::setThirdPartyCookieBlockingMode):
+ (WebKit::NetworkProcess::setShouldBlockThirdPartyCookiesForTesting): Deleted.
+ Renamed setThirdPartyCookieBlockingMode.
+ * NetworkProcess/NetworkProcess.h:
+ * NetworkProcess/NetworkProcess.messages.in:
+ * NetworkProcess/cocoa/NetworkSessionCocoa.mm:
+ (WebKit::NetworkSessionCocoa::NetworkSessionCocoa):
+ * Shared/ResourceLoadStatisticsParameters.h:
+ (WebKit::ResourceLoadStatisticsParameters::encode const):
+ (WebKit::ResourceLoadStatisticsParameters::decode):
+ * UIProcess/API/C/WKWebsiteDataStoreRef.cpp:
+ (WKWebsiteDataStoreSetAppBoundDomainsForTesting):
+ * UIProcess/API/C/WKWebsiteDataStoreRef.h:
+ * UIProcess/Network/NetworkProcessProxy.cpp:
+ (WebKit::NetworkProcessProxy::setAppBoundDomainsForResourceLoadStatistics):
+ (WebKit::NetworkProcessProxy::setThirdPartyCookieBlockingMode):
+ (WebKit::NetworkProcessProxy::setShouldBlockThirdPartyCookiesForTesting): Deleted.
+ Renamed setThirdPartyCookieBlockingMode.
+ * UIProcess/Network/NetworkProcessProxy.h:
+ * UIProcess/WebProcessPool.cpp:
+ (WebKit::WebProcessPool::ensureNetworkProcess):
+ * UIProcess/WebProcessProxy.cpp:
+ (WebKit::WebProcessProxy::setThirdPartyCookieBlockingMode):
+ (WebKit::WebProcessProxy::setShouldBlockThirdPartyCookiesForTesting): Deleted.
+ Renamed setThirdPartyCookieBlockingMode.
+ * UIProcess/WebProcessProxy.h:
+ * UIProcess/WebsiteData/Cocoa/WebsiteDataStoreCocoa.mm:
+ (WebKit::WebsiteDataStore::initializeAppBoundDomains):
+ (WebKit::WebsiteDataStore::ensureAppBoundDomains const):
+ (WebKit::WebsiteDataStore::appBoundDomainsIfInitialized):
+ This function allows fetching of app-bound domains without triggering
+ the lazy loading. This is just to allow speculative configuration of ITP
+ right when it's created — if any app-bound domains are already configured,
+ forward them to ITP via ResourceLoadStatisticsParameters.
+ (WebKit::WebsiteDataStore::setAppBoundDomainsForTesting):
+ This function is Cocoa-specific and only accepts localhost and 127.0.0.1
+ to be configured as app-bound domains.
+ * UIProcess/WebsiteData/WebsiteDataStore.cpp:
+ (WebKit::WebsiteDataStore::setResourceLoadStatisticsShouldBlockThirdPartyCookiesForTesting):
+ (WebKit::WebsiteDataStore::setThirdPartyCookieBlockingMode):
+ (WebKit::WebsiteDataStore::parameters):
+ (WebKit::WebsiteDataStore::forwardAppBoundDomainsToITPIfInitialized):
+ (WebKit::WebsiteDataStore::setAppBoundDomainsForITP):
+ * UIProcess/WebsiteData/WebsiteDataStore.h:
+ * WebProcess/WebProcess.cpp:
+ (WebKit::WebProcess::setThirdPartyCookieBlockingMode):
+ (WebKit::WebProcess::setShouldBlockThirdPartyCookiesForTesting): Deleted.
+ * WebProcess/WebProcess.h:
+ * WebProcess/WebProcess.messages.in:
+
2020-05-06 Daniel Bates <daba...@apple.com>
[iOS] ASSERTION FAILED: !(_keyboardFlags & WebEventKeyboardInputModifierFlagsChanged) in -[WebEvent charactersIgnoringModifiers] when pressing modifier on PDF
Modified: trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.cpp (261241 => 261242)
--- trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.cpp 2020-05-06 18:43:19 UTC (rev 261241)
+++ trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.cpp 2020-05-06 18:44:26 UTC (rev 261242)
@@ -2621,7 +2621,7 @@
Vector<DomainData> domains = this->domains();
Vector<unsigned> domainIDsToClearGrandfathering;
for (auto& statistic : domains) {
- if (statistic.registrableDomain == standaloneApplicationDomain())
+ if (shouldExemptFromWebsiteDataDeletion(statistic.registrableDomain))
continue;
oldestUserInteraction = std::min(oldestUserInteraction, statistic.mostRecentUserInteractionTime);
if (shouldRemoveAllWebsiteDataFor(statistic, shouldCheckForGrandfathering)) {
Modified: trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsMemoryStore.cpp (261241 => 261242)
--- trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsMemoryStore.cpp 2020-05-06 18:43:19 UTC (rev 261241)
+++ trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsMemoryStore.cpp 2020-05-06 18:44:26 UTC (rev 261242)
@@ -980,7 +980,7 @@
auto oldestUserInteraction = now;
RegistrableDomainsToDeleteOrRestrictWebsiteDataFor toDeleteOrRestrictFor;
for (auto& statistic : m_resourceStatisticsMap.values()) {
- if (statistic.registrableDomain == standaloneApplicationDomain())
+ if (shouldExemptFromWebsiteDataDeletion(statistic.registrableDomain))
continue;
oldestUserInteraction = std::min(oldestUserInteraction, statistic.mostRecentUserInteractionTime);
if (shouldRemoveAllWebsiteDataFor(statistic, shouldCheckForGrandfathering)) {
Modified: trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsStore.cpp (261241 => 261242)
--- trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsStore.cpp 2020-05-06 18:43:19 UTC (rev 261241)
+++ trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsStore.cpp 2020-05-06 18:44:26 UTC (rev 261242)
@@ -317,6 +317,11 @@
m_debugManualPrevalentResource = domain;
}
+void ResourceLoadStatisticsStore::setAppBoundDomains(HashSet<RegistrableDomain>&& domains)
+{
+ m_appBoundDomains = WTFMove(domains);
+}
+
void ResourceLoadStatisticsStore::scheduleStatisticsProcessingRequestIfNecessary()
{
ASSERT(!RunLoop::isMain());
@@ -568,6 +573,7 @@
ASSERT(!RunLoop::isMain());
m_parameters = { };
+ m_appBoundDomains.clear();
}
void ResourceLoadStatisticsStore::logTestingEvent(const String& event)
@@ -652,6 +658,11 @@
RELEASE_LOG_INFO(ITPDebug, "%" PUBLIC_LOG_STRING " to (%{public}d of %u): %" PUBLIC_LOG_STRING ".", action, batchNumber, numberOfBatches, domainsToString(batch).utf8().data());
}
+bool ResourceLoadStatisticsStore::shouldExemptFromWebsiteDataDeletion(const RegistrableDomain& domain) const
+{
+ return !domain.isEmpty() && (domain == m_standaloneApplicationDomain || m_appBoundDomains.contains(domain));
+}
+
} // namespace WebKit
#endif
Modified: trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsStore.h (261241 => 261242)
--- trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsStore.h 2020-05-06 18:43:19 UTC (rev 261241)
+++ trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsStore.h 2020-05-06 18:44:26 UTC (rev 261242)
@@ -169,6 +169,7 @@
bool isSameSiteStrictEnforcementEnabled() const { return m_sameSiteStrictEnforcementEnabled == WebCore::SameSiteStrictEnforcementEnabled::Yes; };
void setFirstPartyWebsiteDataRemovalMode(WebCore::FirstPartyWebsiteDataRemovalMode mode) { m_firstPartyWebsiteDataRemovalMode = mode; }
void setStandaloneApplicationDomain(RegistrableDomain&& domain) { m_standaloneApplicationDomain = WTFMove(domain); }
+ void setAppBoundDomains(HashSet<RegistrableDomain>&&);
virtual bool areAllThirdPartyCookiesBlockedUnder(const TopFrameDomain&) = 0;
virtual void hasStorageAccess(const SubFrameDomain&, const TopFrameDomain&, Optional<WebCore::FrameIdentifier>, WebCore::PageIdentifier, CompletionHandler<void(bool)>&&) = 0;
@@ -249,7 +250,7 @@
bool debugLoggingEnabled() const { return m_debugLoggingEnabled; };
bool debugModeEnabled() const { return m_debugModeEnabled; }
WebCore::FirstPartyWebsiteDataRemovalMode firstPartyWebsiteDataRemovalMode() const { return m_firstPartyWebsiteDataRemovalMode; }
- RegistrableDomain standaloneApplicationDomain() const { return m_standaloneApplicationDomain; }
+ bool shouldExemptFromWebsiteDataDeletion(const RegistrableDomain&) const;
static constexpr unsigned maxNumberOfRecursiveCallsInRedirectTraceBack { 50 };
@@ -291,6 +292,7 @@
ShouldIncludeLocalhost m_shouldIncludeLocalhost { ShouldIncludeLocalhost::Yes };
WebCore::FirstPartyWebsiteDataRemovalMode m_firstPartyWebsiteDataRemovalMode { WebCore::FirstPartyWebsiteDataRemovalMode::AllButCookies };
RegistrableDomain m_standaloneApplicationDomain;
+ HashSet<RegistrableDomain> m_appBoundDomains;
};
} // namespace WebKit
Modified: trunk/Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsStore.cpp (261241 => 261242)
--- trunk/Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsStore.cpp 2020-05-06 18:43:19 UTC (rev 261241)
+++ trunk/Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsStore.cpp 2020-05-06 18:44:26 UTC (rev 261242)
@@ -678,6 +678,33 @@
});
}
+void WebResourceLoadStatisticsStore::setAppBoundDomains(HashSet<RegistrableDomain>&& domains, CompletionHandler<void()>&& completionHandler)
+{
+ ASSERT(RunLoop::isMain());
+
+ if (isEphemeral() || domains.isEmpty()) {
+ completionHandler();
+ return;
+ }
+
+ auto domainsCopy = crossThreadCopy(domains);
+
+ if (m_networkSession) {
+ if (auto* storageSession = m_networkSession->networkStorageSession()) {
+ storageSession->setAppBoundDomains(WTFMove(domains));
+ storageSession->setThirdPartyCookieBlockingMode(ThirdPartyCookieBlockingMode::AllExceptBetweenAppBoundDomains);
+ }
+ }
+
+ postTask([this, domains = WTFMove(domainsCopy), completionHandler = WTFMove(completionHandler)]() mutable {
+ if (m_statisticsStore) {
+ m_statisticsStore->setAppBoundDomains(WTFMove(domains));
+ m_statisticsStore->setThirdPartyCookieBlockingMode(ThirdPartyCookieBlockingMode::AllExceptBetweenAppBoundDomains);
+ }
+ postTaskReply(WTFMove(completionHandler));
+ });
+}
+
void WebResourceLoadStatisticsStore::didCreateNetworkProcess()
{
ASSERT(RunLoop::isMain());
@@ -1280,6 +1307,11 @@
return;
}
+ if (m_networkSession) {
+ if (auto* storageSession = m_networkSession->networkStorageSession())
+ storageSession->resetAppBoundDomains();
+ }
+
postTask([this, completionHandler = WTFMove(completionHandler)]() mutable {
if (m_statisticsStore)
m_statisticsStore->resetParametersToDefaultValues();
Modified: trunk/Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsStore.h (261241 => 261242)
--- trunk/Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsStore.h 2020-05-06 18:43:19 UTC (rev 261241)
+++ trunk/Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsStore.h 2020-05-06 18:44:26 UTC (rev 261242)
@@ -279,6 +279,7 @@
void setSameSiteStrictEnforcementEnabled(WebCore::SameSiteStrictEnforcementEnabled);
void setFirstPartyWebsiteDataRemovalMode(WebCore::FirstPartyWebsiteDataRemovalMode, CompletionHandler<void()>&&);
void setStandaloneApplicationDomain(const RegistrableDomain&, CompletionHandler<void()>&&);
+ void setAppBoundDomains(HashSet<RegistrableDomain>&&, CompletionHandler<void()>&&);
void didCreateNetworkProcess();
void notifyResourceLoadStatisticsProcessed();
Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp (261241 => 261242)
--- trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp 2020-05-06 18:43:19 UTC (rev 261241)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp 2020-05-06 18:44:26 UTC (rev 261242)
@@ -1307,6 +1307,18 @@
completionHandler(result);
}
+void NetworkProcess::setAppBoundDomainsForResourceLoadStatistics(PAL::SessionID sessionID, HashSet<WebCore::RegistrableDomain>&& appBoundDomains, CompletionHandler<void()>&& completionHandler)
+{
+ if (auto* networkSession = this->networkSession(sessionID)) {
+ if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics()) {
+ resourceLoadStatistics->setAppBoundDomains(WTFMove(appBoundDomains), WTFMove(completionHandler));
+ return;
+ }
+ }
+ ASSERT_NOT_REACHED();
+ completionHandler();
+}
+
void NetworkProcess::setShouldDowngradeReferrerForTesting(bool enabled, CompletionHandler<void()>&& completionHandler)
{
forEachNetworkSession([enabled](auto& networkSession) {
@@ -1315,7 +1327,7 @@
completionHandler();
}
-void NetworkProcess::setShouldBlockThirdPartyCookiesForTesting(PAL::SessionID sessionID, WebCore::ThirdPartyCookieBlockingMode blockingMode, CompletionHandler<void()>&& completionHandler)
+void NetworkProcess::setThirdPartyCookieBlockingMode(PAL::SessionID sessionID, WebCore::ThirdPartyCookieBlockingMode blockingMode, CompletionHandler<void()>&& completionHandler)
{
if (auto* networkSession = this->networkSession(sessionID))
networkSession->setThirdPartyCookieBlockingMode(blockingMode);
Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcess.h (261241 => 261242)
--- trunk/Source/WebKit/NetworkProcess/NetworkProcess.h 2020-05-06 18:43:19 UTC (rev 261241)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcess.h 2020-05-06 18:44:26 UTC (rev 261242)
@@ -261,9 +261,10 @@
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;
+ void setAppBoundDomainsForResourceLoadStatistics(PAL::SessionID, HashSet<WebCore::RegistrableDomain>&&, CompletionHandler<void()>&&);
bool isITPDatabaseEnabled() const { return m_isITPDatabaseEnabled; }
void setShouldDowngradeReferrerForTesting(bool, CompletionHandler<void()>&&);
- void setShouldBlockThirdPartyCookiesForTesting(PAL::SessionID, WebCore::ThirdPartyCookieBlockingMode, CompletionHandler<void()>&&);
+ void setThirdPartyCookieBlockingMode(PAL::SessionID, WebCore::ThirdPartyCookieBlockingMode, CompletionHandler<void()>&&);
void setShouldEnbleSameSiteStrictEnforcementForTesting(PAL::SessionID, WebCore::SameSiteStrictEnforcementEnabled, CompletionHandler<void()>&&);
void setFirstPartyWebsiteDataRemovalModeForTesting(PAL::SessionID, WebCore::FirstPartyWebsiteDataRemovalMode, CompletionHandler<void()>&&);
void setToSameSiteStrictCookiesForTesting(PAL::SessionID, const WebCore::RegistrableDomain&, CompletionHandler<void()>&&);
Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcess.messages.in (261241 => 261242)
--- trunk/Source/WebKit/NetworkProcess/NetworkProcess.messages.in 2020-05-06 18:43:19 UTC (rev 261241)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcess.messages.in 2020-05-06 18:44:26 UTC (rev 261242)
@@ -141,8 +141,9 @@
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
+ SetAppBoundDomainsForResourceLoadStatistics(PAL::SessionID sessionID, HashSet<WebCore::RegistrableDomain> appBoundDomains) -> () Async
SetShouldDowngradeReferrerForTesting(bool enabled) -> () Async
- SetShouldBlockThirdPartyCookiesForTesting(PAL::SessionID sessionID, enum:uint8_t WebCore::ThirdPartyCookieBlockingMode blockingMode) -> () Async
+ SetThirdPartyCookieBlockingMode(PAL::SessionID sessionID, enum:uint8_t WebCore::ThirdPartyCookieBlockingMode blockingMode) -> () Async
SetShouldEnbleSameSiteStrictEnforcementForTesting(PAL::SessionID sessionID, enum:bool WebCore::SameSiteStrictEnforcementEnabled enabled) -> () Async
SetFirstPartyWebsiteDataRemovalModeForTesting(PAL::SessionID sessionID, enum:uint8_t WebCore::FirstPartyWebsiteDataRemovalMode mode) -> () Async
SetToSameSiteStrictCookiesForTesting(PAL::SessionID sessionID, WebCore::RegistrableDomain domain) -> () Async
Modified: trunk/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm (261241 => 261242)
--- trunk/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm 2020-05-06 18:43:19 UTC (rev 261241)
+++ trunk/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm 2020-05-06 18:44:26 UTC (rev 261242)
@@ -1227,6 +1227,8 @@
m_deviceManagementRestrictionsEnabled = parameters.deviceManagementRestrictionsEnabled;
m_allLoadsBlockedByDeviceManagementRestrictionsForTesting = parameters.allLoadsBlockedByDeviceManagementRestrictionsForTesting;
+ if (m_resourceLoadStatistics && !parameters.resourceLoadStatisticsParameters.appBoundDomains.isEmpty())
+ m_resourceLoadStatistics->setAppBoundDomains(WTFMove(parameters.resourceLoadStatisticsParameters.appBoundDomains), [] { });
#if HAVE(SESSION_CLEANUP)
activateSessionCleanup(*this, parameters);
#endif
Modified: trunk/Source/WebKit/Shared/ResourceLoadStatisticsParameters.h (261241 => 261242)
--- trunk/Source/WebKit/Shared/ResourceLoadStatisticsParameters.h 2020-05-06 18:43:19 UTC (rev 261241)
+++ trunk/Source/WebKit/Shared/ResourceLoadStatisticsParameters.h 2020-05-06 18:44:26 UTC (rev 261242)
@@ -47,8 +47,9 @@
WebCore::SameSiteStrictEnforcementEnabled sameSiteStrictEnforcementEnabled { WebCore::SameSiteStrictEnforcementEnabled::No };
#endif
WebCore::FirstPartyWebsiteDataRemovalMode firstPartyWebsiteDataRemovalMode { WebCore::FirstPartyWebsiteDataRemovalMode::AllButCookies };
- WebCore::RegistrableDomain standaloneApplicationDomain { };
- WebCore::RegistrableDomain manualPrevalentResource { };
+ WebCore::RegistrableDomain standaloneApplicationDomain;
+ HashSet<WebCore::RegistrableDomain> appBoundDomains;
+ WebCore::RegistrableDomain manualPrevalentResource;
void encode(IPC::Encoder& encoder) const
{
@@ -65,6 +66,7 @@
#endif
encoder << firstPartyWebsiteDataRemovalMode;
encoder << standaloneApplicationDomain;
+ encoder << appBoundDomains;
encoder << manualPrevalentResource;
}
@@ -127,6 +129,11 @@
if (!standaloneApplicationDomain)
return WTF::nullopt;
+ Optional<HashSet<WebCore::RegistrableDomain>> appBoundDomains;
+ decoder >> appBoundDomains;
+ if (!appBoundDomains)
+ return WTF::nullopt;
+
Optional<WebCore::RegistrableDomain> manualPrevalentResource;
decoder >> manualPrevalentResource;
if (!manualPrevalentResource)
@@ -146,6 +153,7 @@
#endif
WTFMove(*firstPartyWebsiteDataRemovalMode),
WTFMove(*standaloneApplicationDomain),
+ WTFMove(*appBoundDomains),
WTFMove(*manualPrevalentResource),
}};
}
Modified: trunk/Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreRef.cpp (261241 => 261242)
--- trunk/Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreRef.cpp 2020-05-06 18:43:19 UTC (rev 261241)
+++ trunk/Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreRef.cpp 2020-05-06 18:44:26 UTC (rev 261242)
@@ -42,6 +42,7 @@
#include "WebsiteDataRecord.h"
#include "WebsiteDataStore.h"
#include "WebsiteDataType.h"
+#include <WebCore/RegistrableDomain.h>
#include <wtf/CallbackAggregator.h>
#include <wtf/URL.h>
@@ -617,6 +618,31 @@
#endif
}
+void WKWebsiteDataStoreSetAppBoundDomainsForTesting(WKArrayRef originURLsRef, void* context, WKWebsiteDataStoreSetAppBoundDomainsForTestingFunction completionHandler)
+{
+#if PLATFORM(COCOA)
+ RefPtr<API::Array> originURLsArray = toImpl(originURLsRef);
+ size_t newSize = originURLsArray ? originURLsArray->size() : 0;
+ HashSet<WebCore::RegistrableDomain> domains;
+ domains.reserveInitialCapacity(newSize);
+ for (size_t i = 0; i < newSize; ++i) {
+ auto* originURL = originURLsArray->at<API::URL>(i);
+ if (!originURL)
+ continue;
+
+ domains.add(WebCore::RegistrableDomain { URL(URL(), originURL->string()) });
+ }
+
+ WebKit::WebsiteDataStore::setAppBoundDomainsForTesting(WTFMove(domains), [context, completionHandler] {
+ completionHandler(context);
+ });
+#else
+ UNUSED_PARAM(originURLsRef);
+ UNUSED_PARAM(context);
+ UNUSED_PARAM(completionHandler);
+#endif
+}
+
void WKWebsiteDataStoreStatisticsResetToConsistentState(WKWebsiteDataStoreRef dataStoreRef, void* context, WKWebsiteDataStoreStatisticsResetToConsistentStateFunction completionHandler)
{
#if ENABLE(RESOURCE_LOAD_STATISTICS)
Modified: trunk/Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreRef.h (261241 => 261242)
--- trunk/Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreRef.h 2020-05-06 18:43:19 UTC (rev 261241)
+++ trunk/Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreRef.h 2020-05-06 18:44:26 UTC (rev 261242)
@@ -129,6 +129,8 @@
WK_EXPORT void WKWebsiteDataStoreSetResourceLoadStatisticsFirstPartyWebsiteDataRemovalModeForTesting(WKWebsiteDataStoreRef dataStoreRef, bool enabled, void* context, WKWebsiteDataStoreSetResourceLoadStatisticsFirstPartyWebsiteDataRemovalModeForTestingFunction completionHandler);
typedef void (*WKWebsiteDataStoreSetResourceLoadStatisticsToSameSiteStrictCookiesForTestingFunction)(void* functionContext);
WK_EXPORT void WKWebsiteDataStoreSetResourceLoadStatisticsToSameSiteStrictCookiesForTesting(WKWebsiteDataStoreRef dataStoreRef, WKStringRef hostName, void* context, WKWebsiteDataStoreSetResourceLoadStatisticsToSameSiteStrictCookiesForTestingFunction completionHandler);
+typedef void (*WKWebsiteDataStoreSetAppBoundDomainsForTestingFunction)(void* functionContext);
+WK_EXPORT void WKWebsiteDataStoreSetAppBoundDomainsForTesting(WKArrayRef originURLsRef, void* context, WKWebsiteDataStoreSetAppBoundDomainsForTestingFunction completionHandler);
typedef void (*WKWebsiteDataStoreStatisticsResetToConsistentStateFunction)(void* functionContext);
WK_EXPORT void WKWebsiteDataStoreStatisticsResetToConsistentState(WKWebsiteDataStoreRef dataStoreRef, void* context, WKWebsiteDataStoreStatisticsResetToConsistentStateFunction completionHandler);
Modified: trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp (261241 => 261242)
--- trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp 2020-05-06 18:43:19 UTC (rev 261241)
+++ trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp 2020-05-06 18:44:26 UTC (rev 261242)
@@ -1136,6 +1136,13 @@
sendWithAsyncReply(Messages::NetworkProcess::HasIsolatedSession(sessionID, domain), WTFMove(completionHandler));
}
+void NetworkProcessProxy::setAppBoundDomainsForResourceLoadStatistics(PAL::SessionID sessionID, const HashSet<RegistrableDomain>& appBoundDomains, CompletionHandler<void()>&& completionHandler)
+{
+ sendWithAsyncReply(Messages::NetworkProcess::SetAppBoundDomainsForResourceLoadStatistics(sessionID, appBoundDomains), [activity = throttler().backgroundActivity("NetworkProcessProxy::setAppBoundDomainsForResourceLoadStatistics"_s), completionHandler = WTFMove(completionHandler)]() mutable {
+ completionHandler();
+ });
+}
+
void NetworkProcessProxy::setShouldDowngradeReferrerForTesting(bool enabled, CompletionHandler<void()>&& completionHandler)
{
if (!canSendMessage()) {
@@ -1148,9 +1155,9 @@
});
}
-void NetworkProcessProxy::setShouldBlockThirdPartyCookiesForTesting(PAL::SessionID sessionID, ThirdPartyCookieBlockingMode blockingMode, CompletionHandler<void()>&& completionHandler)
+void NetworkProcessProxy::setThirdPartyCookieBlockingMode(PAL::SessionID sessionID, ThirdPartyCookieBlockingMode blockingMode, CompletionHandler<void()>&& completionHandler)
{
- sendWithAsyncReply(Messages::NetworkProcess::SetShouldBlockThirdPartyCookiesForTesting(sessionID, blockingMode), [activity = throttler().backgroundActivity("NetworkProcessProxy::setShouldBlockThirdPartyCookiesForTesting"_s), completionHandler = WTFMove(completionHandler)]() mutable {
+ sendWithAsyncReply(Messages::NetworkProcess::SetThirdPartyCookieBlockingMode(sessionID, blockingMode), [activity = throttler().backgroundActivity("NetworkProcessProxy::setThirdPartyCookieBlockingMode"_s), completionHandler = WTFMove(completionHandler)]() mutable {
completionHandler();
});
}
Modified: trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.h (261241 => 261242)
--- trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.h 2020-05-06 18:43:19 UTC (rev 261241)
+++ trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.h 2020-05-06 18:44:26 UTC (rev 261242)
@@ -175,8 +175,9 @@
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)>&&);
+ void setAppBoundDomainsForResourceLoadStatistics(PAL::SessionID, const HashSet<RegistrableDomain>&, CompletionHandler<void()>&&);
void setShouldDowngradeReferrerForTesting(bool, CompletionHandler<void()>&&);
- void setShouldBlockThirdPartyCookiesForTesting(PAL::SessionID, WebCore::ThirdPartyCookieBlockingMode, CompletionHandler<void()>&&);
+ void setThirdPartyCookieBlockingMode(PAL::SessionID, WebCore::ThirdPartyCookieBlockingMode, CompletionHandler<void()>&&);
void setShouldEnbleSameSiteStrictEnforcementForTesting(PAL::SessionID, WebCore::SameSiteStrictEnforcementEnabled, CompletionHandler<void()>&&);
void setFirstPartyWebsiteDataRemovalModeForTesting(PAL::SessionID, WebCore::FirstPartyWebsiteDataRemovalMode, CompletionHandler<void()>&&);
void setToSameSiteStrictCookiesForTesting(PAL::SessionID, const RegistrableDomain&, CompletionHandler<void()>&&);
Modified: trunk/Source/WebKit/UIProcess/WebProcessPool.cpp (261241 => 261242)
--- trunk/Source/WebKit/UIProcess/WebProcessPool.cpp 2020-05-06 18:43:19 UTC (rev 261241)
+++ trunk/Source/WebKit/UIProcess/WebProcessPool.cpp 2020-05-06 18:44:26 UTC (rev 261242)
@@ -605,9 +605,10 @@
WebCore::ThirdPartyCookieBlockingMode thirdPartyCookieBlockingMode = WebCore::ThirdPartyCookieBlockingMode::All;
WebCore::SameSiteStrictEnforcementEnabled sameSiteStrictEnforcementEnabled = WebCore::SameSiteStrictEnforcementEnabled::No;
#endif
- WebCore::RegistrableDomain standaloneApplicationDomain { };
WebCore::FirstPartyWebsiteDataRemovalMode firstPartyWebsiteDataRemovalMode = WebCore::FirstPartyWebsiteDataRemovalMode::AllButCookies;
- WebCore::RegistrableDomain manualPrevalentResource { };
+ WebCore::RegistrableDomain standaloneApplicationDomain;
+ HashSet<WebCore::RegistrableDomain> appBoundDomains;
+ WebCore::RegistrableDomain manualPrevalentResource;
WEB_PROCESS_POOL_ADDITIONS_2
if (withWebsiteDataStore) {
enableResourceLoadStatistics = withWebsiteDataStore->resourceLoadStatisticsEnabled();
@@ -624,6 +625,7 @@
#endif
firstPartyWebsiteDataRemovalMode = networkSessionParameters.resourceLoadStatisticsParameters.firstPartyWebsiteDataRemovalMode;
standaloneApplicationDomain = networkSessionParameters.resourceLoadStatisticsParameters.standaloneApplicationDomain;
+ appBoundDomains = networkSessionParameters.resourceLoadStatisticsParameters.appBoundDomains;
manualPrevalentResource = networkSessionParameters.resourceLoadStatisticsParameters.manualPrevalentResource;
}
@@ -650,6 +652,7 @@
#endif
firstPartyWebsiteDataRemovalMode = networkSessionParameters.resourceLoadStatisticsParameters.firstPartyWebsiteDataRemovalMode;
standaloneApplicationDomain = networkSessionParameters.resourceLoadStatisticsParameters.standaloneApplicationDomain;
+ appBoundDomains = networkSessionParameters.resourceLoadStatisticsParameters.appBoundDomains;
manualPrevalentResource = networkSessionParameters.resourceLoadStatisticsParameters.manualPrevalentResource;
}
@@ -689,6 +692,8 @@
sameSiteStrictEnforcementEnabled,
#endif
firstPartyWebsiteDataRemovalMode,
+ standaloneApplicationDomain,
+ appBoundDomains,
manualPrevalentResource,
};
Modified: trunk/Source/WebKit/UIProcess/WebProcessProxy.cpp (261241 => 261242)
--- trunk/Source/WebKit/UIProcess/WebProcessProxy.cpp 2020-05-06 18:43:19 UTC (rev 261241)
+++ trunk/Source/WebKit/UIProcess/WebProcessProxy.cpp 2020-05-06 18:44:26 UTC (rev 261242)
@@ -458,9 +458,9 @@
page.value->postMessageToInjectedBundle("ResourceLoadStatisticsTelemetryFinished", messageBody);
}
-void WebProcessProxy::setShouldBlockThirdPartyCookiesForTesting(ThirdPartyCookieBlockingMode thirdPartyCookieBlockingMode, CompletionHandler<void()>&& completionHandler)
+void WebProcessProxy::setThirdPartyCookieBlockingMode(ThirdPartyCookieBlockingMode thirdPartyCookieBlockingMode, CompletionHandler<void()>&& completionHandler)
{
- sendWithAsyncReply(Messages::WebProcess::SetShouldBlockThirdPartyCookiesForTesting(thirdPartyCookieBlockingMode), [activity = throttler().backgroundActivity("WebProcessProxy::setShouldBlockThirdPartyCookiesForTesting"_s), completionHandler = WTFMove(completionHandler)]() mutable {
+ sendWithAsyncReply(Messages::WebProcess::SetThirdPartyCookieBlockingMode(thirdPartyCookieBlockingMode), [activity = throttler().backgroundActivity("WebProcessProxy::setThirdPartyCookieBlockingMode"_s), completionHandler = WTFMove(completionHandler)]() mutable {
completionHandler();
});
}
Modified: trunk/Source/WebKit/UIProcess/WebProcessProxy.h (261241 => 261242)
--- trunk/Source/WebKit/UIProcess/WebProcessProxy.h 2020-05-06 18:43:19 UTC (rev 261241)
+++ trunk/Source/WebKit/UIProcess/WebProcessProxy.h 2020-05-06 18:44:26 UTC (rev 261242)
@@ -219,7 +219,7 @@
static void notifyWebsiteDataDeletionForRegistrableDomainsFinished();
static void notifyWebsiteDataScanForRegistrableDomainsFinished();
- void setShouldBlockThirdPartyCookiesForTesting(WebCore::ThirdPartyCookieBlockingMode, CompletionHandler<void()>&&);
+ void setThirdPartyCookieBlockingMode(WebCore::ThirdPartyCookieBlockingMode, CompletionHandler<void()>&&);
#endif
void enableSuddenTermination();
Modified: trunk/Source/WebKit/UIProcess/WebsiteData/Cocoa/WebsiteDataStoreCocoa.mm (261241 => 261242)
--- trunk/Source/WebKit/UIProcess/WebsiteData/Cocoa/WebsiteDataStoreCocoa.mm 2020-05-06 18:43:19 UTC (rev 261241)
+++ trunk/Source/WebKit/UIProcess/WebsiteData/Cocoa/WebsiteDataStoreCocoa.mm 2020-05-06 18:44:26 UTC (rev 261242)
@@ -413,6 +413,9 @@
keyExists = domains ? true : false;
RunLoop::main().dispatch([isInAppBrowserPrivacyEnabled, forceReinitialization, domains = retainPtr(domains)] {
+ if (hasInitializedAppBoundDomains && forceReinitialization != ForceReinitialization::Yes)
+ return;
+
if (forceReinitialization == ForceReinitialization::Yes)
appBoundDomains().clear();
@@ -433,6 +436,8 @@
WEBSITE_DATA_STORE_ADDITIONS
}
hasInitializedAppBoundDomains = true;
+ if (isAppBoundITPRelaxationEnabled)
+ forwardAppBoundDomainsToITPIfInitialized([] { });
});
});
}
@@ -444,6 +449,8 @@
return;
}
+ // Hopping to the background thread then back to the main thread
+ // ensures that initializeAppBoundDomains() has finished.
appBoundDomainQueue().dispatch([completionHandler = WTFMove(completionHandler)] () mutable {
RunLoop::main().dispatch([completionHandler = WTFMove(completionHandler)] () mutable {
ASSERT(hasInitializedAppBoundDomains);
@@ -486,6 +493,24 @@
});
}
+Optional<HashSet<WebCore::RegistrableDomain>> WebsiteDataStore::appBoundDomainsIfInitialized()
+{
+ ASSERT(RunLoop::isMain());
+ if (!hasInitializedAppBoundDomains)
+ return WTF::nullopt;
+ return appBoundDomains();
+}
+
+void WebsiteDataStore::setAppBoundDomainsForTesting(HashSet<WebCore::RegistrableDomain>&& domains, CompletionHandler<void()>&& completionHandler)
+{
+ for (auto& domain : domains)
+ RELEASE_ASSERT(domain == "localhost"_s || domain == "127.0.0.1"_s);
+
+ appBoundDomains() = WTFMove(domains);
+ hasInitializedAppBoundDomains = true;
+ forwardAppBoundDomainsToITPIfInitialized(WTFMove(completionHandler));
+}
+
void WebsiteDataStore::reinitializeAppBoundDomains()
{
hasInitializedAppBoundDomains = false;
Modified: trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp (261241 => 261242)
--- trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp 2020-05-06 18:43:19 UTC (rev 261241)
+++ trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp 2020-05-06 18:44:26 UTC (rev 261242)
@@ -1862,16 +1862,22 @@
WebCore::ThirdPartyCookieBlockingMode blockingMode = WebCore::ThirdPartyCookieBlockingMode::OnlyAccordingToPerDomainPolicy;
if (enabled)
blockingMode = onlyOnSitesWithoutUserInteraction ? WebCore::ThirdPartyCookieBlockingMode::AllOnSitesWithoutUserInteraction : WebCore::ThirdPartyCookieBlockingMode::All;
+ setThirdPartyCookieBlockingMode(blockingMode, WTFMove(completionHandler));
+}
+void WebsiteDataStore::setThirdPartyCookieBlockingMode(WebCore::ThirdPartyCookieBlockingMode blockingMode, CompletionHandler<void()>&& completionHandler)
+{
+ auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
+
if (thirdPartyCookieBlockingMode() != blockingMode) {
m_thirdPartyCookieBlockingMode = blockingMode;
for (auto& webProcess : processes())
- webProcess.setShouldBlockThirdPartyCookiesForTesting(blockingMode, [callbackAggregator = callbackAggregator.copyRef()] { });
+ webProcess.setThirdPartyCookieBlockingMode(blockingMode, [callbackAggregator = callbackAggregator.copyRef()] { });
}
for (auto& processPool : processPools()) {
if (auto* networkProcess = processPool->networkProcess())
- networkProcess->setShouldBlockThirdPartyCookiesForTesting(m_sessionID, blockingMode, [callbackAggregator = callbackAggregator.copyRef()] { });
+ networkProcess->setThirdPartyCookieBlockingMode(m_sessionID, blockingMode, [callbackAggregator = callbackAggregator.copyRef()] { });
}
}
@@ -2225,8 +2231,13 @@
bool shouldIncludeLocalhostInResourceLoadStatistics = false;
bool enableResourceLoadStatisticsDebugMode = false;
auto firstPartyWebsiteDataRemovalMode = WebCore::FirstPartyWebsiteDataRemovalMode::AllButCookies;
- WebCore::RegistrableDomain resourceLoadStatisticsManualPrevalentResource { };
-
+ WebCore::RegistrableDomain standaloneApplicationDomain;
+ HashSet<WebCore::RegistrableDomain> appBoundDomains;
+#if PLATFORM(COCOA)
+ if (isAppBoundITPRelaxationEnabled)
+ appBoundDomains = appBoundDomainsIfInitialized().valueOr(HashSet<WebCore::RegistrableDomain> { });
+#endif
+ WebCore::RegistrableDomain resourceLoadStatisticsManualPrevalentResource;
ResourceLoadStatisticsParameters resourceLoadStatisticsParameters = {
WTFMove(resourceLoadStatisticsDirectory),
WTFMove(resourceLoadStatisticsDirectoryHandle),
@@ -2245,6 +2256,8 @@
WebCore::SameSiteStrictEnforcementEnabled::No,
#endif
firstPartyWebsiteDataRemovalMode,
+ WTFMove(standaloneApplicationDomain),
+ WTFMove(appBoundDomains),
WTFMove(resourceLoadStatisticsManualPrevalentResource),
};
@@ -2424,4 +2437,39 @@
}
}
+#if PLATFORM(COCOA)
+void WebsiteDataStore::forwardAppBoundDomainsToITPIfInitialized(CompletionHandler<void()>&& completionHandler)
+{
+ auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
+ auto appBoundDomains = appBoundDomainsIfInitialized();
+ if (!appBoundDomains)
+ return;
+
+ auto propagateAppBoundDomains = [callbackAggregator = callbackAggregator.copyRef()] (WebsiteDataStore* store, const HashSet<WebCore::RegistrableDomain>& domains) {
+ if (!store)
+ return;
+
+ if (store->thirdPartyCookieBlockingMode() != WebCore::ThirdPartyCookieBlockingMode::AllExceptBetweenAppBoundDomains)
+ store->setThirdPartyCookieBlockingMode(WebCore::ThirdPartyCookieBlockingMode::AllExceptBetweenAppBoundDomains, [callbackAggregator = callbackAggregator.copyRef()] { });
+
+ store->setAppBoundDomainsForITP(domains, [callbackAggregator = callbackAggregator.copyRef()] { });
+ };
+
+ propagateAppBoundDomains(globalDefaultDataStore().get(), *appBoundDomains);
+
+ for (auto* store : nonDefaultDataStores().values())
+ propagateAppBoundDomains(store, *appBoundDomains);
}
+
+void WebsiteDataStore::setAppBoundDomainsForITP(const HashSet<WebCore::RegistrableDomain>& domains, CompletionHandler<void()>&& completionHandler)
+{
+ auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
+
+ for (auto& processPool : processPools()) {
+ if (auto* networkProcess = processPool->networkProcess())
+ networkProcess->setAppBoundDomainsForResourceLoadStatistics(m_sessionID, domains, [callbackAggregator = callbackAggregator.copyRef()] { });
+ }
+}
+#endif
+
+}
Modified: trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h (261241 => 261242)
--- trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h 2020-05-06 18:43:19 UTC (rev 261241)
+++ trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h 2020-05-06 18:44:26 UTC (rev 261242)
@@ -199,6 +199,7 @@
void hasIsolatedSessionForTesting(const URL&, CompletionHandler<void(bool)>&&) const;
void setResourceLoadStatisticsShouldDowngradeReferrerForTesting(bool, CompletionHandler<void()>&&);
void setResourceLoadStatisticsShouldBlockThirdPartyCookiesForTesting(bool enabled, bool onlyOnSitesWithoutUserInteraction, CompletionHandler<void()>&&);
+ void setThirdPartyCookieBlockingMode(WebCore::ThirdPartyCookieBlockingMode, CompletionHandler<void()>&&);
void setResourceLoadStatisticsShouldEnbleSameSiteStrictEnforcementForTesting(bool enabled, CompletionHandler<void()>&&);
void setResourceLoadStatisticsFirstPartyWebsiteDataRemovalModeForTesting(bool enabled, CompletionHandler<void()>&&);
void setResourceLoadStatisticsToSameSiteStrictCookiesForTesting(const URL&, CompletionHandler<void()>&&);
@@ -296,6 +297,7 @@
void getAppBoundDomains(CompletionHandler<void(const HashSet<WebCore::RegistrableDomain>&)>&&) const;
void ensureAppBoundDomains(CompletionHandler<void(const HashSet<WebCore::RegistrableDomain>&)>&&) const;
void reinitializeAppBoundDomains();
+ static void setAppBoundDomainsForTesting(HashSet<WebCore::RegistrableDomain>&&, CompletionHandler<void()>&&);
private:
enum class ForceReinitialization : bool { No, Yes };
@@ -331,6 +333,13 @@
void maybeRegisterWithSessionIDMap();
+#if PLATFORM(COCOA)
+ static Optional<HashSet<WebCore::RegistrableDomain>> appBoundDomainsIfInitialized();
+ constexpr static const std::atomic<bool> isAppBoundITPRelaxationEnabled = false;
+ static void forwardAppBoundDomainsToITPIfInitialized(CompletionHandler<void()>&&);
+ void setAppBoundDomainsForITP(const HashSet<WebCore::RegistrableDomain>&, CompletionHandler<void()>&&);
+#endif
+
const PAL::SessionID m_sessionID;
Ref<WebsiteDataStoreConfiguration> m_resolvedConfiguration;
Modified: trunk/Source/WebKit/WebProcess/WebProcess.cpp (261241 => 261242)
--- trunk/Source/WebKit/WebProcess/WebProcess.cpp 2020-05-06 18:43:19 UTC (rev 261241)
+++ trunk/Source/WebKit/WebProcess/WebProcess.cpp 2020-05-06 18:44:26 UTC (rev 261242)
@@ -1895,7 +1895,7 @@
}
#if ENABLE(RESOURCE_LOAD_STATISTICS)
-void WebProcess::setShouldBlockThirdPartyCookiesForTesting(ThirdPartyCookieBlockingMode thirdPartyCookieBlockingMode, CompletionHandler<void()>&& completionHandler)
+void WebProcess::setThirdPartyCookieBlockingMode(ThirdPartyCookieBlockingMode thirdPartyCookieBlockingMode, CompletionHandler<void()>&& completionHandler)
{
m_thirdPartyCookieBlockingMode = thirdPartyCookieBlockingMode;
completionHandler();
Modified: trunk/Source/WebKit/WebProcess/WebProcess.h (261241 => 261242)
--- trunk/Source/WebKit/WebProcess/WebProcess.h 2020-05-06 18:43:19 UTC (rev 261241)
+++ trunk/Source/WebKit/WebProcess/WebProcess.h 2020-05-06 18:44:26 UTC (rev 261242)
@@ -458,7 +458,7 @@
#endif
#if ENABLE(RESOURCE_LOAD_STATISTICS)
- void setShouldBlockThirdPartyCookiesForTesting(WebCore::ThirdPartyCookieBlockingMode, CompletionHandler<void()>&&);
+ void setThirdPartyCookieBlockingMode(WebCore::ThirdPartyCookieBlockingMode, CompletionHandler<void()>&&);
#endif
void platformInitializeProcess(const AuxiliaryProcessInitializationParameters&);
Modified: trunk/Source/WebKit/WebProcess/WebProcess.messages.in (261241 => 261242)
--- trunk/Source/WebKit/WebProcess/WebProcess.messages.in 2020-05-06 18:43:19 UTC (rev 261241)
+++ trunk/Source/WebKit/WebProcess/WebProcess.messages.in 2020-05-06 18:44:26 UTC (rev 261242)
@@ -157,7 +157,7 @@
#if ENABLE(RESOURCE_LOAD_STATISTICS)
SeedResourceLoadStatisticsForTesting(WebCore::RegistrableDomain firstPartyDomain, WebCore::RegistrableDomain thirdPartyDomain, bool shouldScheduleNotification) -> () Async
- SetShouldBlockThirdPartyCookiesForTesting(enum:uint8_t WebCore::ThirdPartyCookieBlockingMode blockingMode) -> () Async
+ SetThirdPartyCookieBlockingMode(enum:uint8_t WebCore::ThirdPartyCookieBlockingMode blockingMode) -> () Async
#endif
#if PLATFORM(IOS)
Modified: trunk/Tools/ChangeLog (261241 => 261242)
--- trunk/Tools/ChangeLog 2020-05-06 18:43:19 UTC (rev 261241)
+++ trunk/Tools/ChangeLog 2020-05-06 18:44:26 UTC (rev 261242)
@@ -1,3 +1,32 @@
+2020-05-06 John Wilander <wilan...@apple.com>
+
+ Exempt app-bound domains from ITP's website data deletion and third-party cookie blocking between themselves
+ https://bugs.webkit.org/show_bug.cgi?id=210674
+ <rdar://problem/61950767>
+
+ Reviewed by Chris Dumez.
+
+ This change adds a new TestRunner function
+ setAppBoundDomain() which takes an array of origin
+ strings and sets them to app-bound domains.
+
+ * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl:
+ * WebKitTestRunner/InjectedBundle/InjectedBundle.cpp:
+ (WTR::InjectedBundle::didReceiveMessageToPage):
+ * WebKitTestRunner/InjectedBundle/TestRunner.cpp:
+ (WTR::TestRunner::setAppBoundDomains):
+ (WTR::TestRunner::didSetAppBoundDomainsCallback):
+ * WebKitTestRunner/InjectedBundle/TestRunner.h:
+ * WebKitTestRunner/TestController.cpp:
+ (WTR::AppBoundDomainsCallbackContext::AppBoundDomainsCallbackContext):
+ (WTR::didSetAppBoundDomainsCallback):
+ (WTR::TestController::setAppBoundDomains):
+ * WebKitTestRunner/TestController.h:
+ * WebKitTestRunner/TestInvocation.cpp:
+ (WTR::TestInvocation::didReceiveMessageFromInjectedBundle):
+ (WTR::TestInvocation::didSetAppBoundDomains):
+ * WebKitTestRunner/TestInvocation.h:
+
2020-05-06 Aakash Jain <aakash_j...@apple.com>
Delete code for feeder queue
Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl (261241 => 261242)
--- trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl 2020-05-06 18:43:19 UTC (rev 261241)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl 2020-05-06 18:44:26 UTC (rev 261242)
@@ -393,7 +393,9 @@
void resetMockMediaDevices();
void setMockCameraOrientation(unsigned long orientation);
boolean isMockRealtimeMediaSourceCenterEnabled();
+
boolean hasAppBoundSession();
+ void setAppBoundDomains(object originsArray, object callback);
void injectUserScript(DOMString string);
readonly attribute unsigned long userScriptInjectedCount;
Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/InjectedBundle.cpp (261241 => 261242)
--- trunk/Tools/WebKitTestRunner/InjectedBundle/InjectedBundle.cpp 2020-05-06 18:43:19 UTC (rev 261241)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/InjectedBundle.cpp 2020-05-06 18:44:26 UTC (rev 261242)
@@ -518,7 +518,12 @@
m_testRunner->performCustomMenuAction();
return;
}
-
+
+ if (WKStringIsEqualToUTF8CString(messageName, "CallDidSetAppBoundDomains")) {
+ m_testRunner->didSetAppBoundDomainsCallback();
+ return;
+ }
+
WKRetainPtr<WKStringRef> errorMessageName = adoptWK(WKStringCreateWithUTF8CString("Error"));
WKRetainPtr<WKStringRef> errorMessageBody = adoptWK(WKStringCreateWithUTF8CString("Unknown"));
WKBundlePagePostMessage(page, errorMessageName.get(), errorMessageBody.get());
Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp (261241 => 261242)
--- trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp 2020-05-06 18:43:19 UTC (rev 261241)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp 2020-05-06 18:44:26 UTC (rev 261242)
@@ -763,6 +763,7 @@
TextFieldDidBeginEditingCallbackID,
TextFieldDidEndEditingCallbackID,
CustomMenuActionCallbackID,
+ DidSetAppBoundDomainsCallbackID,
FirstUIScriptCallbackID = 100
};
@@ -2975,4 +2976,43 @@
return WKBooleanGetValue(adoptWK(static_cast<WKBooleanRef>(returnData)).get());
}
+void TestRunner::setAppBoundDomains(JSValueRef originArray, JSValueRef completionHandler)
+{
+ cacheTestRunnerCallback(DidSetAppBoundDomainsCallbackID, completionHandler);
+
+ JSContextRef context = WKBundleFrameGetJavaScriptContext(WKBundlePageGetMainFrame(InjectedBundle::singleton().page()->page()));
+
+ if (!JSValueIsArray(context, originArray))
+ return;
+
+ JSObjectRef origins = JSValueToObject(context, originArray, nullptr);
+ static auto lengthProperty = adopt(JSStringCreateWithUTF8CString("length"));
+ JSValueRef originsLengthValue = JSObjectGetProperty(context, origins, lengthProperty.get(), nullptr);
+ if (!JSValueIsNumber(context, originsLengthValue))
+ return;
+
+ auto originURLs = adoptWK(WKMutableArrayCreate());
+ auto originsLength = static_cast<size_t>(JSValueToNumber(context, originsLengthValue, nullptr));
+ for (size_t i = 0; i < originsLength; ++i) {
+ JSValueRef originValue = JSObjectGetPropertyAtIndex(context, origins, i, nullptr);
+ if (!JSValueIsString(context, originValue))
+ continue;
+
+ auto origin = adopt(JSValueToStringCopy(context, originValue, nullptr));
+ size_t originBufferSize = JSStringGetMaximumUTF8CStringSize(origin.get()) + 1;
+ auto originBuffer = makeUniqueArray<char>(originBufferSize);
+ JSStringGetUTF8CString(origin.get(), originBuffer.get(), originBufferSize);
+
+ WKArrayAppendItem(originURLs.get(), adoptWK(WKURLCreateWithUTF8CString(originBuffer.get())).get());
+ }
+
+ auto messageName = adoptWK(WKStringCreateWithUTF8CString("SetAppBoundDomains"));
+ WKBundlePostMessage(InjectedBundle::singleton().bundle(), messageName.get(), originURLs.get());
+}
+
+void TestRunner::didSetAppBoundDomainsCallback()
+{
+ callTestRunnerCallback(DidSetAppBoundDomainsCallbackID);
+}
+
} // namespace WTR
Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h (261241 => 261242)
--- trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h 2020-05-06 18:43:19 UTC (rev 261241)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h 2020-05-06 18:44:26 UTC (rev 261242)
@@ -500,7 +500,10 @@
void resetMockMediaDevices();
void setMockCameraOrientation(unsigned);
bool isMockRealtimeMediaSourceCenterEnabled();
+
bool hasAppBoundSession();
+ void setAppBoundDomains(JSValueRef originArray, JSValueRef callback);
+ void didSetAppBoundDomainsCallback();
size_t userScriptInjectedCount() const;
void injectUserScript(JSStringRef);
Modified: trunk/Tools/WebKitTestRunner/TestController.cpp (261241 => 261242)
--- trunk/Tools/WebKitTestRunner/TestController.cpp 2020-05-06 18:43:19 UTC (rev 261241)
+++ trunk/Tools/WebKitTestRunner/TestController.cpp 2020-05-06 18:44:26 UTC (rev 261242)
@@ -3777,6 +3777,30 @@
m_currentInvocation->didSetToSameSiteStrictCookies();
}
+struct AppBoundDomainsCallbackContext {
+ explicit AppBoundDomainsCallbackContext(TestController& controller)
+ : testController(controller)
+ {
+ }
+
+ bool done { false };
+ TestController& testController;
+};
+
+static void didSetAppBoundDomainsCallback(void* callbackContext)
+{
+ auto* context = static_cast<AppBoundDomainsCallbackContext*>(callbackContext);
+ context->done = true;
+}
+
+void TestController::setAppBoundDomains(WKArrayRef originURLs)
+{
+ AppBoundDomainsCallbackContext context(*this);
+ WKWebsiteDataStoreSetAppBoundDomainsForTesting(originURLs, &context, didSetAppBoundDomainsCallback);
+ runUntil(context.done, noTimeout);
+ m_currentInvocation->didSetAppBoundDomains();
+}
+
void TestController::statisticsResetToConsistentState()
{
ResourceStatisticsCallbackContext context(*this);
Modified: trunk/Tools/WebKitTestRunner/TestController.h (261241 => 261242)
--- trunk/Tools/WebKitTestRunner/TestController.h 2020-05-06 18:43:19 UTC (rev 261241)
+++ trunk/Tools/WebKitTestRunner/TestController.h 2020-05-06 18:44:26 UTC (rev 261242)
@@ -266,6 +266,7 @@
void setStatisticsShouldBlockThirdPartyCookies(bool value, bool onlyOnSitesWithoutUserInteraction);
void setStatisticsFirstPartyWebsiteDataRemovalMode(bool value);
void setStatisticsToSameSiteStrictCookies(WKStringRef hostName);
+ void setAppBoundDomains(WKArrayRef originURLs);
void statisticsResetToConsistentState();
void getAllStorageAccessEntries();
@@ -352,6 +353,8 @@
void setAdClickAttributionConversionURLForTesting(WKURLRef);
void markAdClickAttributionsAsExpiredForTesting();
+ void didSetAppBoundDomains() const;
+
private:
WKRetainPtr<WKPageConfigurationRef> generatePageConfiguration(const TestOptions&);
WKRetainPtr<WKContextConfigurationRef> generateContextConfiguration(const TestOptions::ContextOptions&) const;
Modified: trunk/Tools/WebKitTestRunner/TestInvocation.cpp (261241 => 261242)
--- trunk/Tools/WebKitTestRunner/TestInvocation.cpp 2020-05-06 18:43:19 UTC (rev 261241)
+++ trunk/Tools/WebKitTestRunner/TestInvocation.cpp 2020-05-06 18:44:26 UTC (rev 261242)
@@ -994,6 +994,13 @@
return;
}
+ if (WKStringIsEqualToUTF8CString(messageName, "SetAppBoundDomains")) {
+ ASSERT(WKGetTypeID(messageBody) == WKArrayGetTypeID());
+ WKArrayRef originURLs = static_cast<WKArrayRef>(messageBody);
+ TestController::singleton().setAppBoundDomains(originURLs);
+ return;
+ }
+
ASSERT_NOT_REACHED();
}
@@ -2011,6 +2018,12 @@
WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
}
+void TestInvocation::didSetAppBoundDomains()
+{
+ WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallDidSetAppBoundDomains"));
+ WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), nullptr);
+}
+
void TestInvocation::dumpResourceLoadStatistics()
{
m_shouldDumpResourceLoadStatistics = true;
Modified: trunk/Tools/WebKitTestRunner/TestInvocation.h (261241 => 261242)
--- trunk/Tools/WebKitTestRunner/TestInvocation.h 2020-05-06 18:43:19 UTC (rev 261241)
+++ trunk/Tools/WebKitTestRunner/TestInvocation.h 2020-05-06 18:44:26 UTC (rev 261242)
@@ -90,7 +90,9 @@
void didReceiveLoadedThirdPartyDomains(Vector<String>&& domains);
void didRemoveAllSessionCredentials();
-
+
+ void didSetAppBoundDomains();
+
void dumpResourceLoadStatistics();
bool canOpenWindows() const { return m_canOpenWindows; }