Title: [243632] trunk
Revision
243632
Author
[email protected]
Date
2019-03-28 18:15:59 -0700 (Thu, 28 Mar 2019)

Log Message

Resource Load Statistics: IPC to the WebsiteDataStore in the UI process from NetworkProcess::deleteWebsiteDataForRegistrableDomains()
https://bugs.webkit.org/show_bug.cgi?id=196281
<rdar://problem/48938748>

Reviewed by Alex Christensen.

Source/WebKit:

The move of Resource Load Statistics to the network process requires that it
calls the UI process when clearing website data (previously the other way
around). This patch achieves that.

Specifically, NetworkProcess::deleteWebsiteDataForRegistrableDomains() now
filters its WebsiteDataTypes down to just the ones applicable for the UI
process and then calls DeleteWebsiteDataInUIProcessForRegistrableDomains over
IPC.

NetworkProcessProxy::deleteWebsiteDataInUIProcessForRegistrableDomains() on
the UI process side makes use of the re-introduced
WebsiteDataStore::fetchDataForRegistrableDomains() function to get the relevant
data records and call WebsiteDataStore::removeData(). The re-introduced
WebsiteDataStore::fetchDataForRegistrableDomains() was removed as dead code in
https://trac.webkit.org/changeset/242056/webkit, then under the name
WebsiteDataStore::fetchDataForTopPrivatelyControlledDomains(). The reason it
was dead code was the lack of IPC call that this patch adds.

* NetworkProcess/NetworkProcess.cpp:
(WebKit::NetworkProcess::deleteWebsiteDataForRegistrableDomains):
   Now calls DeleteWebsiteDataInUIProcessForRegistrableDomains over IPC if there
   are WebsiteDataTypes applicable to the UI process.
* NetworkProcess/NetworkProcess.h:
* Shared/WebsiteData/WebsiteData.cpp:
(WebKit::WebsiteData::ownerProcess):
(WebKit::WebsiteData::filter):
    Convenience functions to manage process ownership of website data types.
* Shared/WebsiteData/WebsiteData.h:
* UIProcess/API/C/WKWebsiteDataStoreRef.cpp:
(WKWebsiteDataStoreStatisticsHasLocalStorage):
    Test infrastructure, called by the TestRunner.
* UIProcess/API/C/WKWebsiteDataStoreRef.h:
* UIProcess/Network/NetworkProcessProxy.cpp:
(WebKit::NetworkProcessProxy::deleteWebsiteDataInUIProcessForRegistrableDomains):
    New function to be called from the network process.
* UIProcess/Network/NetworkProcessProxy.h:
* UIProcess/Network/NetworkProcessProxy.messages.in:
* UIProcess/WebsiteData/WebsiteDataRecord.cpp:
(WebKit::WebsiteDataRecord::matches const):
    Now matches with WebCore::RegistrableDomain instead of a string.
(WebKit::WebsiteDataRecord::matchesTopPrivatelyControlledDomain const): Deleted.
    Replaced by WebsiteDataRecord::matches().
* UIProcess/WebsiteData/WebsiteDataRecord.h:
* UIProcess/WebsiteData/WebsiteDataStore.cpp:
(WebKit::WebsiteDataStore::fetchDataForRegistrableDomains):
    Re-introduced. It was removed as dead code in r242056.
(WebKit::computeNetworkProcessAccessTypeForDataRemoval):
(WebKit::WebsiteDataStore::hasLocalStorageForTesting const):
    Test infrastructure, called by the TestRunner.
* UIProcess/WebsiteData/WebsiteDataStore.h:

Tools:

This patch adds the function isStatisticsHasLocalStorage() to the
TestRunner. With it, the page can query the WebsiteDataStore in the
UI process to make sure that it sees LocalStorage.

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

LayoutTests:

This test now covers LocalStorage too.

* http/tests/resourceLoadStatistics/website-data-removal-for-site-navigated-to-with-link-decoration-expected.txt:
* http/tests/resourceLoadStatistics/website-data-removal-for-site-navigated-to-with-link-decoration.html:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (243631 => 243632)


--- trunk/LayoutTests/ChangeLog	2019-03-28 23:47:00 UTC (rev 243631)
+++ trunk/LayoutTests/ChangeLog	2019-03-29 01:15:59 UTC (rev 243632)
@@ -1,3 +1,16 @@
+2019-03-28  John Wilander  <[email protected]>
+
+        Resource Load Statistics: IPC to the WebsiteDataStore in the UI process from NetworkProcess::deleteWebsiteDataForRegistrableDomains()
+        https://bugs.webkit.org/show_bug.cgi?id=196281
+        <rdar://problem/48938748>
+
+        Reviewed by Alex Christensen.
+
+        This test now covers LocalStorage too.
+
+        * http/tests/resourceLoadStatistics/website-data-removal-for-site-navigated-to-with-link-decoration-expected.txt:
+        * http/tests/resourceLoadStatistics/website-data-removal-for-site-navigated-to-with-link-decoration.html:
+
 2019-03-28  Shawn Roberts  <[email protected]>
 
         The following layout tests are flaky failures

Modified: trunk/LayoutTests/http/tests/resourceLoadStatistics/website-data-removal-for-site-navigated-to-with-link-decoration-expected.txt (243631 => 243632)


--- trunk/LayoutTests/http/tests/resourceLoadStatistics/website-data-removal-for-site-navigated-to-with-link-decoration-expected.txt	2019-03-28 23:47:00 UTC (rev 243631)
+++ trunk/LayoutTests/http/tests/resourceLoadStatistics/website-data-removal-for-site-navigated-to-with-link-decoration-expected.txt	2019-03-29 01:15:59 UTC (rev 243632)
@@ -3,13 +3,13 @@
 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 not exist.
 After deletion: IDB entry does not exist.
 
 

Modified: trunk/LayoutTests/http/tests/resourceLoadStatistics/website-data-removal-for-site-navigated-to-with-link-decoration.html (243631 => 243632)


--- trunk/LayoutTests/http/tests/resourceLoadStatistics/website-data-removal-for-site-navigated-to-with-link-decoration.html	2019-03-28 23:47:00 UTC (rev 243631)
+++ trunk/LayoutTests/http/tests/resourceLoadStatistics/website-data-removal-for-site-navigated-to-with-link-decoration.html	2019-03-29 01:15:59 UTC (rev 243632)
@@ -91,6 +91,44 @@
         };
     }
 
+    const maxIntervals = 20;
+    let intervalCounter;
+    let checkLocalStorageCallback;
+    let checkLocalStorageIntervalID;
+    const localStorageName = "test";
+    const localStorageValue = "value";
+    function checkLocalStorageExists(isAfterDeletion, callback) {
+        intervalCounter = 0;
+        checkLocalStorageCallback = callback;
+        if (!isAfterDeletion) {
+            // Check until there is LocalStorage.
+            checkLocalStorageIntervalID = setInterval(function() {
+                if (++intervalCounter === maxIntervals) {
+                    clearInterval(checkLocalStorageIntervalID);
+                    checkLocalStorageCallback();
+                } else if (testRunner.isStatisticsHasLocalStorage(destinationOrigin)) {
+                    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 (++intervalCounter === maxIntervals) {
+                    clearInterval(checkLocalStorageIntervalID);
+                    checkLocalStorageCallback();
+                } else if (!testRunner.isStatisticsHasLocalStorage(destinationOrigin)) {
+                    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" });
@@ -98,21 +136,31 @@
         document.cookie = clientSideCookieName + "=1";
 
         checkCookies(false);
-        addLinebreakToOutput();
 
-        // Write IndexedDB.
-        createIDBDataStore(function () {
-            checkIDBDataStoreExists(false, processWebsiteDataAndContinue);
+        // Write LocalStorage
+        localStorage.setItem(localStorageName, localStorageValue);
+        checkLocalStorageExists(false, function() {
+
+            // Write IndexedDB.
+            createIDBDataStore(function () {
+                checkIDBDataStoreExists(false, function() {
+                    addLinebreakToOutput();
+                    processWebsiteDataAndContinue();
+                });
+            });
         });
     }
 
     function processWebsiteDataAndContinue() {
         testRunner.statisticsProcessStatisticsAndDataRecords();
+        checkWebsiteDataAndContinue();
+    }
 
-        addLinebreakToOutput();
+    function checkWebsiteDataAndContinue() {
         checkCookies(true);
-        addLinebreakToOutput();
-        checkIDBDataStoreExists(true, finishTest);
+        checkLocalStorageExists(true, function () {
+            checkIDBDataStoreExists(true, finishTest);
+        });
     }
 
     function finishTest() {

Modified: trunk/Source/WebKit/ChangeLog (243631 => 243632)


--- trunk/Source/WebKit/ChangeLog	2019-03-28 23:47:00 UTC (rev 243631)
+++ trunk/Source/WebKit/ChangeLog	2019-03-29 01:15:59 UTC (rev 243632)
@@ -1,3 +1,62 @@
+2019-03-28  John Wilander  <[email protected]>
+
+        Resource Load Statistics: IPC to the WebsiteDataStore in the UI process from NetworkProcess::deleteWebsiteDataForRegistrableDomains()
+        https://bugs.webkit.org/show_bug.cgi?id=196281
+        <rdar://problem/48938748>
+
+        Reviewed by Alex Christensen.
+
+        The move of Resource Load Statistics to the network process requires that it
+        calls the UI process when clearing website data (previously the other way
+        around). This patch achieves that.
+
+        Specifically, NetworkProcess::deleteWebsiteDataForRegistrableDomains() now
+        filters its WebsiteDataTypes down to just the ones applicable for the UI
+        process and then calls DeleteWebsiteDataInUIProcessForRegistrableDomains over
+        IPC.
+
+        NetworkProcessProxy::deleteWebsiteDataInUIProcessForRegistrableDomains() on
+        the UI process side makes use of the re-introduced
+        WebsiteDataStore::fetchDataForRegistrableDomains() function to get the relevant
+        data records and call WebsiteDataStore::removeData(). The re-introduced
+        WebsiteDataStore::fetchDataForRegistrableDomains() was removed as dead code in
+        https://trac.webkit.org/changeset/242056/webkit, then under the name
+        WebsiteDataStore::fetchDataForTopPrivatelyControlledDomains(). The reason it
+        was dead code was the lack of IPC call that this patch adds.
+
+        * NetworkProcess/NetworkProcess.cpp:
+        (WebKit::NetworkProcess::deleteWebsiteDataForRegistrableDomains):
+           Now calls DeleteWebsiteDataInUIProcessForRegistrableDomains over IPC if there
+           are WebsiteDataTypes applicable to the UI process.
+        * NetworkProcess/NetworkProcess.h:
+        * Shared/WebsiteData/WebsiteData.cpp:
+        (WebKit::WebsiteData::ownerProcess):
+        (WebKit::WebsiteData::filter):
+            Convenience functions to manage process ownership of website data types.
+        * Shared/WebsiteData/WebsiteData.h:
+        * UIProcess/API/C/WKWebsiteDataStoreRef.cpp:
+        (WKWebsiteDataStoreStatisticsHasLocalStorage):
+            Test infrastructure, called by the TestRunner.
+        * UIProcess/API/C/WKWebsiteDataStoreRef.h:
+        * UIProcess/Network/NetworkProcessProxy.cpp:
+        (WebKit::NetworkProcessProxy::deleteWebsiteDataInUIProcessForRegistrableDomains):
+            New function to be called from the network process.
+        * UIProcess/Network/NetworkProcessProxy.h:
+        * UIProcess/Network/NetworkProcessProxy.messages.in:
+        * UIProcess/WebsiteData/WebsiteDataRecord.cpp:
+        (WebKit::WebsiteDataRecord::matches const):
+            Now matches with WebCore::RegistrableDomain instead of a string.
+        (WebKit::WebsiteDataRecord::matchesTopPrivatelyControlledDomain const): Deleted.
+            Replaced by WebsiteDataRecord::matches().
+        * UIProcess/WebsiteData/WebsiteDataRecord.h:
+        * UIProcess/WebsiteData/WebsiteDataStore.cpp:
+        (WebKit::WebsiteDataStore::fetchDataForRegistrableDomains):
+            Re-introduced. It was removed as dead code in r242056.
+        (WebKit::computeNetworkProcessAccessTypeForDataRemoval):
+        (WebKit::WebsiteDataStore::hasLocalStorageForTesting const):
+            Test infrastructure, called by the TestRunner.
+        * UIProcess/WebsiteData/WebsiteDataStore.h:
+
 2019-03-28  Jiewen Tan  <[email protected]>
 
         API::Data::createWithoutCopying should do a null check before calling CFRelease

Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp (243631 => 243632)


--- trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp	2019-03-28 23:47:00 UTC (rev 243631)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp	2019-03-29 01:15:59 UTC (rev 243632)
@@ -57,7 +57,6 @@
 #include "WebSWOriginStore.h"
 #include "WebSWServerConnection.h"
 #include "WebSWServerToContextConnection.h"
-#include "WebsiteData.h"
 #include "WebsiteDataFetchOption.h"
 #include "WebsiteDataStore.h"
 #include "WebsiteDataStoreParameters.h"
@@ -1525,23 +1524,13 @@
         
         ~CallbackAggregator()
         {
-            RunLoop::main().dispatch([completionHandler = WTFMove(m_completionHandler), websiteData = WTFMove(m_websiteData)] () mutable {
-                HashSet<RegistrableDomain> domains;
-                for (const auto& hostnameWithCookies : websiteData.hostNamesWithCookies)
-                    domains.add(RegistrableDomain::uncheckedCreateFromHost(hostnameWithCookies));
-
-                for (const auto& hostnameWithHSTS : websiteData.hostNamesWithHSTSCache)
-                    domains.add(RegistrableDomain::uncheckedCreateFromHost(hostnameWithHSTS));
-
-                for (const auto& entry : websiteData.entries)
-                    domains.add(RegistrableDomain::uncheckedCreateFromHost(entry.origin.host));
-
+            RunLoop::main().dispatch([completionHandler = WTFMove(m_completionHandler), domains = WTFMove(m_domains)] () mutable {
                 completionHandler(domains);
             });
         }
         
         CompletionHandler<void(const HashSet<RegistrableDomain>&)> m_completionHandler;
-        WebsiteData m_websiteData;
+        HashSet<RegistrableDomain> m_domains;
     };
     
     auto callbackAggregator = adoptRef(*new CallbackAggregator([this, completionHandler = WTFMove(completionHandler), shouldNotifyPage] (const HashSet<RegistrableDomain>& domainsWithData) mutable {
@@ -1553,7 +1542,8 @@
         });
     }));
 
-    auto& websiteDataStore = callbackAggregator->m_websiteData;
+    HashSet<String> hostNamesWithCookies;
+    HashSet<String> hostNamesWithHSTSCache;
 
     Vector<RegistrableDomain> domainsToDeleteCookiesFor;
     Vector<RegistrableDomain> domainsToDeleteAllButHttpOnlyCookiesFor;
@@ -1575,13 +1565,19 @@
             }
         }
         if (auto* networkStorageSession = storageSession(sessionID)) {
-            networkStorageSession->getHostnamesWithCookies(websiteDataStore.hostNamesWithCookies);
+            networkStorageSession->getHostnamesWithCookies(hostNamesWithCookies);
 
-            hostnamesWithCookiesToDelete = filterForRegistrableDomains(domainsToDeleteCookiesFor, websiteDataStore.hostNamesWithCookies);
+            hostnamesWithCookiesToDelete = filterForRegistrableDomains(domainsToDeleteCookiesFor, hostNamesWithCookies);
             networkStorageSession->deleteCookiesForHostnames(hostnamesWithCookiesToDelete, WebCore::IncludeHttpOnlyCookies::Yes);
 
-            hostnamesWithCookiesToDelete = filterForRegistrableDomains(domainsToDeleteAllButHttpOnlyCookiesFor, websiteDataStore.hostNamesWithCookies);
+            for (const auto& host : hostnamesWithCookiesToDelete)
+                callbackAggregator->m_domains.add(RegistrableDomain::uncheckedCreateFromHost(host));
+
+            hostnamesWithCookiesToDelete = filterForRegistrableDomains(domainsToDeleteAllButHttpOnlyCookiesFor, hostNamesWithCookies);
             networkStorageSession->deleteCookiesForHostnames(hostnamesWithCookiesToDelete, WebCore::IncludeHttpOnlyCookies::No);
+
+            for (const auto& host : hostnamesWithCookiesToDelete)
+                callbackAggregator->m_domains.add(RegistrableDomain::uncheckedCreateFromHost(host));
         }
     } else {
         for (auto& domain : domains.keys())
@@ -1592,8 +1588,12 @@
 #if PLATFORM(COCOA)
     if (websiteDataTypes.contains(WebsiteDataType::HSTSCache)) {
         if (auto* networkStorageSession = storageSession(sessionID)) {
-            getHostNamesWithHSTSCache(*networkStorageSession, websiteDataStore.hostNamesWithHSTSCache);
-            hostnamesWithHSTSToDelete = filterForRegistrableDomains(domainsToDeleteAllButCookiesFor, websiteDataStore.hostNamesWithHSTSCache);
+            getHostNamesWithHSTSCache(*networkStorageSession, hostNamesWithHSTSCache);
+            hostnamesWithHSTSToDelete = filterForRegistrableDomains(domainsToDeleteAllButCookiesFor, hostNamesWithHSTSCache);
+
+            for (const auto& host : hostnamesWithHSTSToDelete)
+                callbackAggregator->m_domains.add(RegistrableDomain::uncheckedCreateFromHost(host));
+
             deleteHSTSCacheForHostNames(*networkStorageSession, hostnamesWithHSTSToDelete);
         }
     }
@@ -1601,9 +1601,10 @@
 
     /*
     // FIXME: No API to delete credentials by origin
+    HashSet<String> originsWithCredentials;
     if (websiteDataTypes.contains(WebsiteDataType::Credentials)) {
         if (storageSession(sessionID))
-            websiteDataStore.originsWithCredentials = storageSession(sessionID)->credentialStorage().originsWithCredentials();
+            originsWithCredentials = storageSession(sessionID)->credentialStorage().originsWithCredentials();
     }
     */
     
@@ -1612,8 +1613,9 @@
             
             auto entriesToDelete = filterForRegistrableDomains(domainsToDeleteAllButCookiesFor, entries);
 
-            callbackAggregator->m_websiteData.entries.appendVector(entriesToDelete);
-            
+            for (const auto& entry : entriesToDelete)
+                callbackAggregator->m_domains.add(RegistrableDomain::uncheckedCreateFromHost(entry.origin.host));
+
             for (auto& entry : entriesToDelete)
                 CacheStorage::Engine::clearCachesForOrigin(*this, sessionID, SecurityOriginData { entry.origin }, [callbackAggregator = callbackAggregator.copyRef()] { });
         });
@@ -1627,11 +1629,12 @@
             RunLoop::main().dispatch([this, sessionID, domainsToDeleteAllButCookiesFor = crossThreadCopy(domainsToDeleteAllButCookiesFor), callbackAggregator = callbackAggregator.copyRef(), securityOrigins = indexedDatabaseOrigins(path)] {
                 Vector<SecurityOriginData> entriesToDelete;
                 for (const auto& securityOrigin : securityOrigins) {
-                    if (!domainsToDeleteAllButCookiesFor.contains(RegistrableDomain::uncheckedCreateFromHost(securityOrigin.host)))
+                    auto domain = RegistrableDomain::uncheckedCreateFromHost(securityOrigin.host);
+                    if (!domainsToDeleteAllButCookiesFor.contains(domain))
                         continue;
 
                     entriesToDelete.append(securityOrigin);
-                    callbackAggregator->m_websiteData.entries.append({ securityOrigin, WebsiteDataType::IndexedDBDatabases, 0 });
+                    callbackAggregator->m_domains.add(domain);
                 }
 
                 idbServer(sessionID).closeAndDeleteDatabasesForOrigins(entriesToDelete, [callbackAggregator = callbackAggregator.copyRef()] { });
@@ -1647,7 +1650,7 @@
             for (auto& securityOrigin : securityOrigins) {
                 if (!domainsToDeleteAllButCookiesFor.contains(RegistrableDomain::uncheckedCreateFromHost(securityOrigin.host)))
                     continue;
-                callbackAggregator->m_websiteData.entries.append({ securityOrigin, WebsiteDataType::ServiceWorkerRegistrations, 0 });
+                callbackAggregator->m_domains.add(RegistrableDomain::uncheckedCreateFromHost(securityOrigin.host));
                 swServerForSession(sessionID).clear(securityOrigin, [callbackAggregator = callbackAggregator.copyRef()] { });
             }
         });
@@ -1662,11 +1665,20 @@
                 if (!domainsToDeleteAllButCookiesFor.contains(RegistrableDomain::uncheckedCreateFromHost(entry.origin.host)))
                     continue;
                 entriesToDelete.append(entry.origin);
-                callbackAggregator->m_websiteData.entries.append(entry);
+                callbackAggregator->m_domains.add(RegistrableDomain::uncheckedCreateFromHost(entry.origin.host));
             }
             clearDiskCacheEntries(cache(), entriesToDelete, [callbackAggregator = callbackAggregator.copyRef()] { });
         });
     }
+
+    auto dataTypesForUIProcess = WebsiteData::filter(websiteDataTypes, WebsiteDataProcessType::UI);
+    if (!dataTypesForUIProcess.isEmpty() && !domainsToDeleteAllButCookiesFor.isEmpty()) {
+        CompletionHandler<void(const HashSet<RegistrableDomain>&)> completionHandler = [callbackAggregator = callbackAggregator.copyRef()] (const HashSet<RegistrableDomain>& domains) {
+            for (auto& domain : domains)
+                callbackAggregator->m_domains.add(domain);
+        };
+        parentProcessConnection()->sendWithAsyncReply(Messages::NetworkProcessProxy::DeleteWebsiteDataInUIProcessForRegistrableDomains(sessionID, dataTypesForUIProcess, fetchOptions, domainsToDeleteAllButCookiesFor), WTFMove(completionHandler));
+    }
 }
 
 void NetworkProcess::deleteCookiesForTesting(PAL::SessionID sessionID, RegistrableDomain domain, bool includeHttpOnlyCookies, CompletionHandler<void()>&& completionHandler)

Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcess.h (243631 => 243632)


--- trunk/Source/WebKit/NetworkProcess/NetworkProcess.h	2019-03-28 23:47:00 UTC (rev 243631)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcess.h	2019-03-29 01:15:59 UTC (rev 243632)
@@ -33,6 +33,7 @@
 #include "NetworkHTTPSUpgradeChecker.h"
 #include "SandboxExtension.h"
 #include "WebResourceLoadStatisticsStore.h"
+#include "WebsiteData.h"
 #include <WebCore/AdClickAttribution.h>
 #include <WebCore/ClientOrigin.h>
 #include <WebCore/DiagnosticLoggingClient.h>

Modified: trunk/Source/WebKit/Shared/WebsiteData/WebsiteData.cpp (243631 => 243632)


--- trunk/Source/WebKit/Shared/WebsiteData/WebsiteData.cpp	2019-03-28 23:47:00 UTC (rev 243631)
+++ trunk/Source/WebKit/Shared/WebsiteData/WebsiteData.cpp	2019-03-29 01:15:59 UTC (rev 243632)
@@ -27,6 +27,7 @@
 #include "WebsiteData.h"
 
 #include "ArgumentCoders.h"
+#include "WebsiteDataType.h"
 #include <WebCore/SecurityOriginData.h>
 #include <wtf/text/StringHash.h>
 
@@ -86,4 +87,59 @@
     return true;
 }
 
+WebsiteDataProcessType WebsiteData::ownerProcess(WebsiteDataType dataType)
+{
+    switch (dataType) {
+    case WebsiteDataType::Cookies:
+        return WebsiteDataProcessType::Network;
+    case WebsiteDataType::DiskCache:
+        return WebsiteDataProcessType::Network;
+    case WebsiteDataType::MemoryCache:
+        return WebsiteDataProcessType::Web;
+    case WebsiteDataType::OfflineWebApplicationCache:
+        return WebsiteDataProcessType::UI;
+    case WebsiteDataType::SessionStorage:
+        return WebsiteDataProcessType::UI;
+    case WebsiteDataType::LocalStorage:
+        return WebsiteDataProcessType::UI;
+    case WebsiteDataType::WebSQLDatabases:
+        return WebsiteDataProcessType::UI;
+    case WebsiteDataType::IndexedDBDatabases:
+        return WebsiteDataProcessType::Network;
+    case WebsiteDataType::MediaKeys:
+        return WebsiteDataProcessType::UI;
+    case WebsiteDataType::HSTSCache:
+        return WebsiteDataProcessType::Network;
+    case WebsiteDataType::SearchFieldRecentSearches:
+        return WebsiteDataProcessType::UI;
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    case WebsiteDataType::PlugInData:
+        return WebsiteDataProcessType::UI;
+#endif
+    case WebsiteDataType::ResourceLoadStatistics:
+        return WebsiteDataProcessType::Network;
+    case WebsiteDataType::Credentials:
+        return WebsiteDataProcessType::Network;
+#if ENABLE(SERVICE_WORKER)
+    case WebsiteDataType::ServiceWorkerRegistrations:
+        return WebsiteDataProcessType::Network;
+#endif
+    case WebsiteDataType::DOMCache:
+        return WebsiteDataProcessType::Network;
+    case WebsiteDataType::DeviceIdHashSalt:
+        return WebsiteDataProcessType::UI;
+    }
 }
+
+OptionSet<WebsiteDataType> WebsiteData::filter(OptionSet<WebsiteDataType> unfilteredWebsiteDataTypes, WebsiteDataProcessType WebsiteDataProcessType)
+{
+    OptionSet<WebsiteDataType> filtered;
+    for (auto dataType : unfilteredWebsiteDataTypes) {
+        if (ownerProcess(dataType) == WebsiteDataProcessType)
+            filtered.add(dataType);
+    }
+    
+    return filtered;
+}
+
+}

Modified: trunk/Source/WebKit/Shared/WebsiteData/WebsiteData.h (243631 => 243632)


--- trunk/Source/WebKit/Shared/WebsiteData/WebsiteData.h	2019-03-28 23:47:00 UTC (rev 243631)
+++ trunk/Source/WebKit/Shared/WebsiteData/WebsiteData.h	2019-03-29 01:15:59 UTC (rev 243632)
@@ -28,6 +28,7 @@
 #include <WebCore/SecurityOriginData.h>
 #include <wtf/HashMap.h>
 #include <wtf/HashSet.h>
+#include <wtf/OptionSet.h>
 #include <wtf/Vector.h>
 
 namespace IPC {
@@ -39,6 +40,8 @@
 
 enum class WebsiteDataType;
 
+enum class WebsiteDataProcessType { Network, UI, Web };
+
 struct WebsiteData {
     struct Entry {
         WebCore::SecurityOriginData origin;
@@ -62,6 +65,8 @@
 
     void encode(IPC::Encoder&) const;
     static bool decode(IPC::Decoder&, WebsiteData&);
+    static WebsiteDataProcessType ownerProcess(WebsiteDataType);
+    static OptionSet<WebsiteDataType> filter(OptionSet<WebsiteDataType>, WebsiteDataProcessType);
 };
 
 }

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


--- trunk/Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreRef.cpp	2019-03-28 23:47:00 UTC (rev 243631)
+++ trunk/Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreRef.cpp	2019-03-29 01:15:59 UTC (rev 243632)
@@ -449,6 +449,17 @@
 #endif
 }
 
+void WKWebsiteDataStoreStatisticsHasLocalStorage(WKWebsiteDataStoreRef dataStoreRef, WKStringRef host, void* context, WKWebsiteDataStoreStatisticsHasLocalStorageFunction callback)
+{
+#if ENABLE(RESOURCE_LOAD_STATISTICS)
+    WebKit::toImpl(dataStoreRef)->websiteDataStore().hasLocalStorageForTesting(URL(URL(), WebKit::toImpl(host)->string()), [context, callback](bool hasLocalStorage) {
+        callback(hasLocalStorage, context);
+    });
+#else
+    callback(false, context);
+#endif
+}
+
 void WKWebsiteDataStoreSetStatisticsCacheMaxAgeCap(WKWebsiteDataStoreRef dataStoreRef, double seconds, void* context, WKWebsiteDataStoreSetStatisticsCacheMaxAgeCapFunction callback)
 {
 #if ENABLE(RESOURCE_LOAD_STATISTICS)

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


--- trunk/Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreRef.h	2019-03-28 23:47:00 UTC (rev 243631)
+++ trunk/Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreRef.h	2019-03-29 01:15:59 UTC (rev 243632)
@@ -99,6 +99,8 @@
 WK_EXPORT void WKWebsiteDataStoreStatisticsClearThroughWebsiteDataRemoval(WKWebsiteDataStoreRef dataStoreRef, void* context, WKWebsiteDataStoreStatisticsClearThroughWebsiteDataRemovalFunction callback);
 typedef void (*WKWebsiteDataStoreStatisticsDeleteCookiesForTestingFunction)(void* functionContext);
 WK_EXPORT void WKWebsiteDataStoreStatisticsDeleteCookiesForTesting(WKWebsiteDataStoreRef dataStoreRef, WKStringRef host, bool includeHttpOnlyCookies, void* context, WKWebsiteDataStoreStatisticsDeleteCookiesForTestingFunction callback);
+typedef void (*WKWebsiteDataStoreStatisticsHasLocalStorageFunction)(bool hasLocalStorage, void* functionContext);
+WK_EXPORT void WKWebsiteDataStoreStatisticsHasLocalStorage(WKWebsiteDataStoreRef dataStoreRef, WKStringRef host, void* context, WKWebsiteDataStoreStatisticsHasLocalStorageFunction callback);
 typedef void (*WKWebsiteDataStoreSetStatisticsCacheMaxAgeCapFunction)(void* functionContext);
 WK_EXPORT void WKWebsiteDataStoreSetStatisticsCacheMaxAgeCap(WKWebsiteDataStoreRef dataStoreRef, double seconds, void* context, WKWebsiteDataStoreSetStatisticsCacheMaxAgeCapFunction);
 typedef void (*WKWebsiteDataStoreStatisticsResetToConsistentStateFunction)(void* functionContext);

Modified: trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp (243631 => 243632)


--- trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp	2019-03-28 23:47:00 UTC (rev 243631)
+++ trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp	2019-03-29 01:15:59 UTC (rev 243632)
@@ -991,6 +991,22 @@
     
     sendWithAsyncReply(Messages::NetworkProcess::DeleteCookiesForTesting(sessionID, domain, includeHttpOnlyCookies), WTFMove(completionHandler));
 }
+
+void NetworkProcessProxy::deleteWebsiteDataInUIProcessForRegistrableDomains(PAL::SessionID sessionID, OptionSet<WebsiteDataType> dataTypes, OptionSet<WebsiteDataFetchOption> fetchOptions, Vector<RegistrableDomain> domains, CompletionHandler<void(HashSet<WebCore::RegistrableDomain>&&)>&& completionHandler)
+{
+    auto* websiteDataStore = websiteDataStoreFromSessionID(sessionID);
+    if (!websiteDataStore || dataTypes.isEmpty() || domains.isEmpty()) {
+        completionHandler({ });
+        return;
+    }
+
+    websiteDataStore->fetchDataForRegistrableDomains(dataTypes, fetchOptions, domains, [dataTypes, websiteDataStore = makeRef(*websiteDataStore), completionHandler = WTFMove(completionHandler)] (Vector<WebsiteDataRecord>&& matchingDataRecords, HashSet<WebCore::RegistrableDomain>&& domainsWithMatchingDataRecords) mutable {
+        websiteDataStore->removeData(dataTypes, WTFMove(matchingDataRecords), [domainsWithMatchingDataRecords = WTFMove(domainsWithMatchingDataRecords), completionHandler = WTFMove(completionHandler)] () mutable {
+            completionHandler(WTFMove(domainsWithMatchingDataRecords));
+        });
+    });
+}
+
 #endif // ENABLE(RESOURCE_LOAD_STATISTICS)
 
 void NetworkProcessProxy::sendProcessWillSuspendImminently()

Modified: trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.h (243631 => 243632)


--- trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.h	2019-03-28 23:47:00 UTC (rev 243631)
+++ trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.h	2019-03-29 01:15:59 UTC (rev 243632)
@@ -149,6 +149,7 @@
     void setCrossSiteLoadWithLinkDecorationForTesting(PAL::SessionID, const NavigatedFromDomain&, const NavigatedToDomain&, CompletionHandler<void()>&&);
     void resetCrossSiteLoadsWithLinkDecorationForTesting(PAL::SessionID, CompletionHandler<void()>&&);
     void deleteCookiesForTesting(PAL::SessionID, const RegistrableDomain&, bool includeHttpOnlyCookies, CompletionHandler<void()>&&);
+    void deleteWebsiteDataInUIProcessForRegistrableDomains(PAL::SessionID, OptionSet<WebsiteDataType>, OptionSet<WebsiteDataFetchOption>, Vector<RegistrableDomain>, CompletionHandler<void(HashSet<WebCore::RegistrableDomain>&&)>&&);
 #endif
 
     void processReadyToSuspend();

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


--- trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.messages.in	2019-03-28 23:47:00 UTC (rev 243631)
+++ trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.messages.in	2019-03-29 01:15:59 UTC (rev 243632)
@@ -48,6 +48,7 @@
     NotifyWebsiteDataScanForRegistrableDomainsFinished()
     NotifyResourceLoadStatisticsTelemetryFinished(unsigned totalPrevalentResources, unsigned totalPrevalentResourcesWithUserInteraction, unsigned top3SubframeUnderTopFrameOrigins)
     RequestStorageAccessConfirm(uint64_t pageID, uint64_t frameID, WebCore::RegistrableDomain subFrameDomain, WebCore::RegistrableDomain topFrameDomain) -> (bool userDidGrantAccess) Async
+    DeleteWebsiteDataInUIProcessForRegistrableDomains(PAL::SessionID sessionID, OptionSet<WebKit::WebsiteDataType> dataTypes, OptionSet<WebKit::WebsiteDataFetchOption> fetchOptions, Vector<WebCore::RegistrableDomain> domains) -> (HashSet<WebCore::RegistrableDomain> domainsWithMatchingDataRecords) Async
 #endif
 #if ENABLE(CONTENT_EXTENSIONS)
     ContentExtensionRules(WebKit::UserContentControllerIdentifier identifier)

Modified: trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataRecord.cpp (243631 => 243632)


--- trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataRecord.cpp	2019-03-28 23:47:00 UTC (rev 243631)
+++ trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataRecord.cpp	2019-03-29 01:15:59 UTC (rev 243632)
@@ -28,6 +28,7 @@
 
 #include <WebCore/LocalizedStrings.h>
 #include <WebCore/PublicSuffix.h>
+#include <WebCore/RegistrableDomain.h>
 #include <WebCore/SecurityOrigin.h>
 
 #if PLATFORM(COCOA)
@@ -113,20 +114,20 @@
     return !suffixOffset || host[suffixOffset - 1] == '.';
 }
 
-bool WebsiteDataRecord::matchesTopPrivatelyControlledDomain(const String& topPrivatelyControlledDomain) const
+bool WebsiteDataRecord::matches(const WebCore::RegistrableDomain& domain) const
 {
-    if (topPrivatelyControlledDomain.isEmpty())
+    if (domain.isEmpty())
         return false;
 
     if (types.contains(WebsiteDataType::Cookies)) {
         for (const auto& hostName : cookieHostNames) {
-            if (hostIsInDomain(hostName, topPrivatelyControlledDomain))
+            if (hostIsInDomain(hostName, domain.string()))
                 return true;
         }
     }
 
     for (const auto& dataRecordOriginData : origins) {
-        if (hostIsInDomain(dataRecordOriginData.host, topPrivatelyControlledDomain))
+        if (hostIsInDomain(dataRecordOriginData.host, domain.string()))
             return true;
     }
 

Modified: trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataRecord.h (243631 => 243632)


--- trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataRecord.h	2019-03-28 23:47:00 UTC (rev 243631)
+++ trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataRecord.h	2019-03-29 01:15:59 UTC (rev 243632)
@@ -36,6 +36,7 @@
 #include <wtf/text/WTFString.h>
 
 namespace WebCore {
+class RegistrableDomain;
 class SecurityOrigin;
 }
 
@@ -72,7 +73,7 @@
     HashSet<String> originsWithCredentials;
     HashSet<String> HSTSCacheHostNames;
 
-    bool matchesTopPrivatelyControlledDomain(const String&) const;
+    bool matches(const WebCore::RegistrableDomain&) const;
     String topPrivatelyControlledDomain();
 };
 

Modified: trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp (243631 => 243632)


--- trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp	2019-03-28 23:47:00 UTC (rev 243631)
+++ trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp	2019-03-29 01:15:59 UTC (rev 243632)
@@ -623,37 +623,44 @@
     callbackAggregator->callIfNeeded();
 }
 
+#if ENABLE(RESOURCE_LOAD_STATISTICS)
+void WebsiteDataStore::fetchDataForRegistrableDomains(OptionSet<WebsiteDataType> dataTypes, OptionSet<WebsiteDataFetchOption> fetchOptions, const Vector<WebCore::RegistrableDomain>& domains, CompletionHandler<void(Vector<WebsiteDataRecord>&&, HashSet<WebCore::RegistrableDomain>&&)>&& completionHandler)
+{
+    fetchDataAndApply(dataTypes, fetchOptions, m_queue.copyRef(), [domains = crossThreadCopy(domains), completionHandler = WTFMove(completionHandler)] (auto&& existingDataRecords) mutable {
+        ASSERT(!RunLoop::isMain());
+        
+        Vector<WebsiteDataRecord> matchingDataRecords;
+        HashSet<WebCore::RegistrableDomain> domainsWithMatchingDataRecords;
+        for (auto&& dataRecord : existingDataRecords) {
+            for (auto& domain : domains) {
+                if (dataRecord.matches(domain)) {
+                    matchingDataRecords.append(WTFMove(dataRecord));
+                    domainsWithMatchingDataRecords.add(domain.isolatedCopy());
+                    break;
+                }
+            }
+        }
+        RunLoop::main().dispatch([completionHandler = WTFMove(completionHandler), matchingDataRecords = WTFMove(matchingDataRecords), domainsWithMatchingDataRecords = WTFMove(domainsWithMatchingDataRecords)] () mutable {
+            completionHandler(WTFMove(matchingDataRecords), WTFMove(domainsWithMatchingDataRecords));
+        });
+    });
+}
+#endif
+
 static ProcessAccessType computeNetworkProcessAccessTypeForDataRemoval(OptionSet<WebsiteDataType> dataTypes, bool isNonPersistentStore)
 {
     ProcessAccessType processAccessType = ProcessAccessType::None;
 
-    if (dataTypes.contains(WebsiteDataType::Cookies)) {
-        if (isNonPersistentStore)
-            processAccessType = std::max(processAccessType, ProcessAccessType::OnlyIfLaunched);
-        else
-            processAccessType = std::max(processAccessType, ProcessAccessType::Launch);
+    for (auto dataType : dataTypes) {
+        if (dataType == WebsiteDataType::Cookies) {
+            if (isNonPersistentStore)
+                processAccessType = std::max(processAccessType, ProcessAccessType::OnlyIfLaunched);
+            else
+                processAccessType = std::max(processAccessType, ProcessAccessType::Launch);
+        } else if (WebsiteData::ownerProcess(dataType) == WebsiteDataProcessType::Network)
+            return ProcessAccessType::Launch;
     }
-
-    if (dataTypes.contains(WebsiteDataType::DiskCache) && !isNonPersistentStore)
-        processAccessType = std::max(processAccessType, ProcessAccessType::Launch);
-
-    if (dataTypes.contains(WebsiteDataType::HSTSCache))
-        processAccessType = std::max(processAccessType, ProcessAccessType::Launch);
-
-    if (dataTypes.contains(WebsiteDataType::Credentials))
-        processAccessType = std::max(processAccessType, ProcessAccessType::Launch);
-
-    if (dataTypes.contains(WebsiteDataType::DOMCache))
-        processAccessType = std::max(processAccessType, ProcessAccessType::Launch);
-
-    if (dataTypes.contains(WebsiteDataType::IndexedDBDatabases) && !isNonPersistentStore)
-        processAccessType = std::max(processAccessType, ProcessAccessType::Launch);
     
-#if ENABLE(SERVICE_WORKER)
-    if (dataTypes.contains(WebsiteDataType::ServiceWorkerRegistrations) && !isNonPersistentStore)
-        processAccessType = std::max(processAccessType, ProcessAccessType::Launch);
-#endif
-
     return processAccessType;
 }
 
@@ -1795,6 +1802,25 @@
             networkProcess->deleteCookiesForTesting(m_sessionID, WebCore::RegistrableDomain { url }, includeHttpOnlyCookies, [callbackAggregator = callbackAggregator.copyRef()] { });
     }
 }
+
+void WebsiteDataStore::hasLocalStorageForTesting(const URL& url, CompletionHandler<void(bool)>&& completionHandler) const
+{
+    if (!m_storageManager) {
+        completionHandler(false);
+        return;
+    }
+
+    m_storageManager->getLocalStorageOrigins([url, completionHandler = WTFMove(completionHandler)](HashSet<WebCore::SecurityOriginData>&& origins) mutable {
+        for (auto& origin : origins) {
+            if (origin.host == url.host()) {
+                completionHandler(true);
+                return;
+            }
+        }
+
+        completionHandler(false);
+    });
+}
 #endif // ENABLE(RESOURCE_LOAD_STATISTICS)
 
 void WebsiteDataStore::setCacheMaxAgeCapForPrevalentResources(Seconds seconds, CompletionHandler<void()>&& completionHandler)

Modified: trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h (243631 => 243632)


--- trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h	2019-03-28 23:47:00 UTC (rev 243631)
+++ trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h	2019-03-29 01:15:59 UTC (rev 243632)
@@ -61,6 +61,7 @@
 }
 
 namespace WebCore {
+class RegistrableDomain;
 class SecurityOrigin;
 }
 
@@ -125,6 +126,7 @@
     void removeData(OptionSet<WebsiteDataType>, const Vector<WebsiteDataRecord>&, Function<void()>&& completionHandler);
 
 #if ENABLE(RESOURCE_LOAD_STATISTICS)
+    void fetchDataForRegistrableDomains(OptionSet<WebsiteDataType>, OptionSet<WebsiteDataFetchOption>, const Vector<WebCore::RegistrableDomain>&, CompletionHandler<void(Vector<WebsiteDataRecord>&&, HashSet<WebCore::RegistrableDomain>&&)>&&);
     void clearPrevalentResource(const URL&, CompletionHandler<void()>&&);
     void clearUserInteraction(const URL&, CompletionHandler<void()>&&);
     void dumpResourceLoadStatistics(CompletionHandler<void(const String&)>&&);
@@ -171,6 +173,7 @@
     void setCrossSiteLoadWithLinkDecorationForTesting(const URL& fromURL, const URL& toURL, CompletionHandler<void()>&&);
     void resetCrossSiteLoadsWithLinkDecorationForTesting(CompletionHandler<void()>&&);
     void deleteCookiesForTesting(const URL&, bool includeHttpOnlyCookies, CompletionHandler<void()>&&);
+    void hasLocalStorageForTesting(const URL&, CompletionHandler<void(bool)>&&) const;
 #endif
     void setCacheMaxAgeCapForPrevalentResources(Seconds, CompletionHandler<void()>&&);
     void resetCacheMaxAgeCapForPrevalentResources(CompletionHandler<void()>&&);

Modified: trunk/Tools/ChangeLog (243631 => 243632)


--- trunk/Tools/ChangeLog	2019-03-28 23:47:00 UTC (rev 243631)
+++ trunk/Tools/ChangeLog	2019-03-29 01:15:59 UTC (rev 243632)
@@ -1,3 +1,25 @@
+2019-03-28  John Wilander  <[email protected]>
+
+        Resource Load Statistics: IPC to the WebsiteDataStore in the UI process from NetworkProcess::deleteWebsiteDataForRegistrableDomains()
+        https://bugs.webkit.org/show_bug.cgi?id=196281
+        <rdar://problem/48938748>
+
+        Reviewed by Alex Christensen.
+
+        This patch adds the function isStatisticsHasLocalStorage() to the
+        TestRunner. With it, the page can query the WebsiteDataStore in the
+        UI process to make sure that it sees LocalStorage.
+
+        * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl:
+        * WebKitTestRunner/InjectedBundle/TestRunner.cpp:
+        (WTR::TestRunner::isStatisticsHasLocalStorage):
+        * WebKitTestRunner/InjectedBundle/TestRunner.h:
+        * WebKitTestRunner/TestController.cpp:
+        (WTR::TestController::isStatisticsHasLocalStorage):
+        * WebKitTestRunner/TestController.h:
+        * WebKitTestRunner/TestInvocation.cpp:
+        (WTR::TestInvocation::didReceiveSynchronousMessageFromInjectedBundle):
+
 2019-03-28  Jiewen Tan  <[email protected]>
 
         API::Data::createWithoutCopying should do a null check before calling CFRelease

Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl (243631 => 243632)


--- trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl	2019-03-28 23:47:00 UTC (rev 243631)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl	2019-03-29 01:15:59 UTC (rev 243632)
@@ -321,6 +321,7 @@
     void statisticsClearInMemoryAndPersistentStoreModifiedSinceHours(unsigned long hours, object callback);
     void statisticsClearThroughWebsiteDataRemoval(object callback);
     void statisticsDeleteCookiesForHost(DOMString hostName, boolean includeHttpOnlyCookies);
+    boolean isStatisticsHasLocalStorage(DOMString hostName);
     void setStatisticsCacheMaxAgeCap(double seconds);
     void statisticsResetToConsistentState(object completionHandler);
 

Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp (243631 => 243632)


--- trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp	2019-03-28 23:47:00 UTC (rev 243631)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp	2019-03-29 01:15:59 UTC (rev 243632)
@@ -2070,6 +2070,16 @@
     WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr);
 }
 
+bool TestRunner::isStatisticsHasLocalStorage(JSStringRef hostName)
+{
+    auto messageName = adoptWK(WKStringCreateWithUTF8CString("IsStatisticsHasLocalStorage"));
+    auto messageBody = adoptWK(WKStringCreateWithJSString(hostName));
+    WKTypeRef returnData = nullptr;
+    WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), messageName.get(), messageBody.get(), &returnData);
+    ASSERT(WKGetTypeID(returnData) == WKBooleanGetTypeID());
+    return WKBooleanGetValue(adoptWK(static_cast<WKBooleanRef>(returnData)).get());
+}
+
 void TestRunner::setStatisticsCacheMaxAgeCap(double seconds)
 {
     WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetStatisticsCacheMaxAgeCap"));

Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h (243631 => 243632)


--- trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h	2019-03-28 23:47:00 UTC (rev 243631)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h	2019-03-29 01:15:59 UTC (rev 243632)
@@ -431,6 +431,7 @@
     void statisticsClearThroughWebsiteDataRemoval(JSValueRef callback);
     void statisticsDeleteCookiesForHost(JSStringRef hostName, bool includeHttpOnlyCookies);
     void statisticsCallClearThroughWebsiteDataRemovalCallback();
+    bool isStatisticsHasLocalStorage(JSStringRef hostName);
     void setStatisticsCacheMaxAgeCap(double seconds);
     void statisticsResetToConsistentState(JSValueRef completionHandler);
     void statisticsCallDidResetToConsistentStateCallback();

Modified: trunk/Tools/WebKitTestRunner/TestController.cpp (243631 => 243632)


--- trunk/Tools/WebKitTestRunner/TestController.cpp	2019-03-28 23:47:00 UTC (rev 243631)
+++ trunk/Tools/WebKitTestRunner/TestController.cpp	2019-03-29 01:15:59 UTC (rev 243632)
@@ -3420,6 +3420,15 @@
     runUntil(context.done, noTimeout);
 }
 
+bool TestController::isStatisticsHasLocalStorage(WKStringRef host)
+{
+    auto* dataStore = WKContextGetWebsiteDataStore(platformContext());
+    ResourceStatisticsCallbackContext context(*this);
+    WKWebsiteDataStoreStatisticsHasLocalStorage(dataStore, host, &context, resourceStatisticsBooleanResultCallback);
+    runUntil(context.done, noTimeout);
+    return context.result;
+}
+
 void TestController::setStatisticsCacheMaxAgeCap(double seconds)
 {
     auto* dataStore = WKContextGetWebsiteDataStore(platformContext());

Modified: trunk/Tools/WebKitTestRunner/TestController.h (243631 => 243632)


--- trunk/Tools/WebKitTestRunner/TestController.h	2019-03-28 23:47:00 UTC (rev 243631)
+++ trunk/Tools/WebKitTestRunner/TestController.h	2019-03-29 01:15:59 UTC (rev 243632)
@@ -242,6 +242,7 @@
     void statisticsClearInMemoryAndPersistentStoreModifiedSinceHours(unsigned);
     void statisticsClearThroughWebsiteDataRemoval();
     void statisticsDeleteCookiesForHost(WKStringRef host, bool includeHttpOnlyCookies);
+    bool isStatisticsHasLocalStorage(WKStringRef hostName);
     void setStatisticsCacheMaxAgeCap(double seconds);
     void statisticsResetToConsistentState();
 

Modified: trunk/Tools/WebKitTestRunner/TestInvocation.cpp (243631 => 243632)


--- trunk/Tools/WebKitTestRunner/TestInvocation.cpp	2019-03-28 23:47:00 UTC (rev 243631)
+++ trunk/Tools/WebKitTestRunner/TestInvocation.cpp	2019-03-29 01:15:59 UTC (rev 243632)
@@ -1427,6 +1427,15 @@
         return nullptr;
     }
 
+    if (WKStringIsEqualToUTF8CString(messageName, "IsStatisticsHasLocalStorage")) {
+        ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
+        
+        WKStringRef hostName = static_cast<WKStringRef>(messageBody);
+        bool hasLocalStorage = TestController::singleton().isStatisticsHasLocalStorage(hostName);
+        auto result = adoptWK(WKBooleanCreate(hasLocalStorage));
+        return result;
+    }
+
     if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsCacheMaxAgeCap")) {
         ASSERT(WKGetTypeID(messageBody) == WKDoubleGetTypeID());
         WKDoubleRef seconds = static_cast<WKDoubleRef>(messageBody);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to