<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[282711] trunk</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/282711">282711</a></dd>
<dt>Author</dt> <dd>katherine_cheney@apple.com</dd>
<dt>Date</dt> <dd>2021-09-17 16:46:14 -0700 (Fri, 17 Sep 2021)</dd>
</dl>
<h3>Log Message</h3>
<pre>Remove unnecessary ITP memory store code
https://bugs.webkit.org/show_bug.cgi?id=229512
<rdar://problem/82644309>
Reviewed by John Wilander.
Source/WebKit:
No new tests. Confirmed by existing tests.
Remove ITP Memory store. This is the first part of a two part operation,
which removes the ResourceLoadStatisticsMemoryStore class. The next
step will be reducing ResourceLoadStatisticsStore and
ResourceLoadStatisticsDatabaseStore to one single ResourceLoadStatisticsStore class.
* NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.cpp:
(WebKit::ResourceLoadStatisticsDatabaseStore::populateFromMemoryStore): Deleted.
* NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.h:
* NetworkProcess/Classifier/ResourceLoadStatisticsMemoryStore.cpp: Removed.
* NetworkProcess/Classifier/WebResourceLoadStatisticsStore.cpp:
(WebKit::WebResourceLoadStatisticsStore::WebResourceLoadStatisticsStore):
* Sources.txt:
* WebKit.xcodeproj/project.pbxproj:
Tools:
* TestWebKitAPI/Tests/WebKitCocoa/ResourceLoadStatistics.mm:
(TEST):
Deleted an extra memory store test leftover from when we still had
a functioning memory store. Now it is just a duplicate of the database
test, so we can remove it.</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebKitChangeLog">trunk/Source/WebKit/ChangeLog</a></li>
<li><a href="#trunkSourceWebKitNetworkProcessClassifierResourceLoadStatisticsDatabaseStorecpp">trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.cpp</a></li>
<li><a href="#trunkSourceWebKitNetworkProcessClassifierResourceLoadStatisticsDatabaseStoreh">trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.h</a></li>
<li><a href="#trunkSourceWebKitNetworkProcessClassifierWebResourceLoadStatisticsStorecpp">trunk/Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsStore.cpp</a></li>
<li><a href="#trunkSourceWebKitSourcestxt">trunk/Source/WebKit/Sources.txt</a></li>
<li><a href="#trunkSourceWebKitWebKitxcodeprojprojectpbxproj">trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkToolsChangeLog">trunk/Tools/ChangeLog</a></li>
<li><a href="#trunkToolsTestWebKitAPITestsWebKitCocoaResourceLoadStatisticsmm">trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ResourceLoadStatistics.mm</a></li>
</ul>
<h3>Removed Paths</h3>
<ul>
<li><a href="#trunkSourceWebKitNetworkProcessClassifierResourceLoadStatisticsMemoryStorecpp">trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsMemoryStore.cpp</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebKitChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/ChangeLog (282710 => 282711)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/ChangeLog 2021-09-17 23:45:48 UTC (rev 282710)
+++ trunk/Source/WebKit/ChangeLog 2021-09-17 23:46:14 UTC (rev 282711)
</span><span class="lines">@@ -1,3 +1,27 @@
</span><ins>+2021-09-17 Kate Cheney <katherine_cheney@apple.com>
+
+ Remove unnecessary ITP memory store code
+ https://bugs.webkit.org/show_bug.cgi?id=229512
+ <rdar://problem/82644309>
+
+ Reviewed by John Wilander.
+
+ No new tests. Confirmed by existing tests.
+
+ Remove ITP Memory store. This is the first part of a two part operation,
+ which removes the ResourceLoadStatisticsMemoryStore class. The next
+ step will be reducing ResourceLoadStatisticsStore and
+ ResourceLoadStatisticsDatabaseStore to one single ResourceLoadStatisticsStore class.
+
+ * NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.cpp:
+ (WebKit::ResourceLoadStatisticsDatabaseStore::populateFromMemoryStore): Deleted.
+ * NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.h:
+ * NetworkProcess/Classifier/ResourceLoadStatisticsMemoryStore.cpp: Removed.
+ * NetworkProcess/Classifier/WebResourceLoadStatisticsStore.cpp:
+ (WebKit::WebResourceLoadStatisticsStore::WebResourceLoadStatisticsStore):
+ * Sources.txt:
+ * WebKit.xcodeproj/project.pbxproj:
+
</ins><span class="cx"> 2021-09-17 Chris Dumez <cdumez@apple.com>
</span><span class="cx">
</span><span class="cx"> Unreviewed build fix.
</span></span></pre></div>
<a id="trunkSourceWebKitNetworkProcessClassifierResourceLoadStatisticsDatabaseStorecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.cpp (282710 => 282711)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.cpp 2021-09-17 23:45:48 UTC (rev 282710)
+++ trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.cpp 2021-09-17 23:46:14 UTC (rev 282711)
</span><span class="lines">@@ -34,7 +34,6 @@
</span><span class="cx"> #include "PluginProcessProxy.h"
</span><span class="cx"> #include "PrivateClickMeasurementManager.h"
</span><span class="cx"> #include "PrivateClickMeasurementManagerProxy.h"
</span><del>-#include "ResourceLoadStatisticsMemoryStore.h"
</del><span class="cx"> #include "StorageAccessStatus.h"
</span><span class="cx"> #include "WebProcessProxy.h"
</span><span class="cx"> #include "WebsiteDataStore.h"
</span><span class="lines">@@ -924,31 +923,6 @@
</span><span class="cx"> insertDomainRelationshipList(topFrameLoadedThirdPartyScriptsQuery, loadStatistics.topFrameLoadedThirdPartyScripts, registrableDomainID.value());
</span><span class="cx"> }
</span><span class="cx">
</span><del>-void ResourceLoadStatisticsDatabaseStore::populateFromMemoryStore(const ResourceLoadStatisticsMemoryStore& memoryStore)
-{
- ASSERT(!RunLoop::isMain());
-
- if (!isEmpty())
- return;
-
- auto transactionScope = beginTransactionIfNecessary();
-
- auto& statisticsMap = memoryStore.data();
- for (const auto& statistic : statisticsMap.values()) {
- auto result = insertObservedDomain(statistic);
- if (!result) {
- ITP_RELEASE_LOG_ERROR(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::populateFromMemoryStore insertObservedDomain failed to complete, error message: %" PRIVATE_LOG_STRING, this, m_database.lastErrorMsg());
- ASSERT_NOT_REACHED();
- return;
- }
- }
-
- // Make a separate pass for inter-domain relationships so we
- // can refer to the ObservedDomain table entries
- for (auto& statistic : statisticsMap.values())
- insertDomainRelationships(statistic);
-}
-
</del><span class="cx"> void ResourceLoadStatisticsDatabaseStore::merge(WebCore::SQLiteStatement* current, const ResourceLoadStatistics& other)
</span><span class="cx"> {
</span><span class="cx"> ASSERT(!RunLoop::isMain());
</span></span></pre></div>
<a id="trunkSourceWebKitNetworkProcessClassifierResourceLoadStatisticsDatabaseStoreh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.h (282710 => 282711)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.h 2021-09-17 23:45:48 UTC (rev 282710)
+++ trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.h 2021-09-17 23:46:14 UTC (rev 282711)
</span><span class="lines">@@ -48,8 +48,6 @@
</span><span class="cx"> static constexpr size_t numberOfStatistics = 7;
</span><span class="cx"> static constexpr std::array<unsigned, numberOfBucketsPerStatistic> bucketSizes {{ 1, 3, 10, 50, 100 }};
</span><span class="cx">
</span><del>-class ResourceLoadStatisticsMemoryStore;
-
</del><span class="cx"> typedef std::pair<String, std::optional<String>> TableAndIndexPair;
</span><span class="cx">
</span><span class="cx"> // This is always constructed / used / destroyed on the WebResourceLoadStatisticsStore's statistics queue.
</span><span class="lines">@@ -58,7 +56,6 @@
</span><span class="cx"> ResourceLoadStatisticsDatabaseStore(WebResourceLoadStatisticsStore&, SuspendableWorkQueue&, ShouldIncludeLocalhost, const String& storageDirectoryPath, PAL::SessionID);
</span><span class="cx"> ~ResourceLoadStatisticsDatabaseStore();
</span><span class="cx">
</span><del>- void populateFromMemoryStore(const ResourceLoadStatisticsMemoryStore&);
</del><span class="cx"> void mergeStatistics(Vector<ResourceLoadStatistics>&&) override;
</span><span class="cx"> void clear(CompletionHandler<void()>&&) override;
</span><span class="cx"> bool isEmpty() const override;
</span></span></pre></div>
<a id="trunkSourceWebKitNetworkProcessClassifierResourceLoadStatisticsMemoryStorecpp"></a>
<div class="delfile"><h4>Deleted: trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsMemoryStore.cpp (282710 => 282711)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsMemoryStore.cpp 2021-09-17 23:45:48 UTC (rev 282710)
+++ trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsMemoryStore.cpp 2021-09-17 23:46:14 UTC (rev 282711)
</span><span class="lines">@@ -1,1169 +0,0 @@
</span><del>-/*
- * Copyright (C) 2017-2019 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "ResourceLoadStatisticsMemoryStore.h"
-
-#if ENABLE(INTELLIGENT_TRACKING_PREVENTION)
-
-#include "Logging.h"
-#include "NetworkSession.h"
-#include "PluginProcessManager.h"
-#include "PluginProcessProxy.h"
-#include "StorageAccessStatus.h"
-#include "WebProcessProxy.h"
-#include "WebsiteDataStore.h"
-#include <JavaScriptCore/ConsoleTypes.h>
-#include <WebCore/DocumentStorageAccess.h>
-#include <WebCore/KeyedCoding.h>
-#include <WebCore/NetworkStorageSession.h>
-#include <WebCore/ResourceLoadStatistics.h>
-#include <WebCore/UserGestureIndicator.h>
-#include <wtf/CallbackAggregator.h>
-#include <wtf/CrossThreadCopier.h>
-#include <wtf/DateMath.h>
-#include <wtf/MathExtras.h>
-#include <wtf/SuspendableWorkQueue.h>
-#include <wtf/text/StringBuilder.h>
-
-namespace WebKit {
-using namespace WebCore;
-
-constexpr unsigned statisticsModelVersion { 17 };
-
-struct StatisticsLastSeen {
- RegistrableDomain domain;
- WallTime lastSeen;
-};
-
-static void pruneResources(HashMap<RegistrableDomain, UniqueRef<ResourceLoadStatistics>>& statisticsMap, Vector<StatisticsLastSeen>& statisticsToPrune, size_t& numberOfEntriesToPrune)
-{
- if (statisticsToPrune.size() > numberOfEntriesToPrune) {
- std::sort(statisticsToPrune.begin(), statisticsToPrune.end(), [](const StatisticsLastSeen& a, const StatisticsLastSeen& b) {
- return a.lastSeen < b.lastSeen;
- });
- }
-
- for (size_t i = 0, end = std::min(numberOfEntriesToPrune, statisticsToPrune.size()); i != end; ++i, --numberOfEntriesToPrune)
- statisticsMap.remove(statisticsToPrune[i].domain);
-}
-
-ResourceLoadStatisticsMemoryStore::ResourceLoadStatisticsMemoryStore(WebResourceLoadStatisticsStore& store, SuspendableWorkQueue& workQueue, ShouldIncludeLocalhost shouldIncludeLocalhost)
- : ResourceLoadStatisticsStore(store, workQueue, shouldIncludeLocalhost)
-{
- RELEASE_ASSERT(!RunLoop::isMain());
- includeTodayAsOperatingDateIfNecessary();
-}
-
-bool ResourceLoadStatisticsMemoryStore::isEmpty() const
-{
- RELEASE_ASSERT(!RunLoop::isMain());
-
- return m_resourceStatisticsMap.isEmpty();
-}
-
-static void ensureThirdPartyDataForSpecificFirstPartyDomain(Vector<WebResourceLoadStatisticsStore::ThirdPartyDataForSpecificFirstParty>& thirdPartyDataForSpecificFirstPartyDomain, const RegistrableDomain& firstPartyDomain, bool thirdPartyHasStorageAccess)
-{
- WebResourceLoadStatisticsStore::ThirdPartyDataForSpecificFirstParty thirdPartyDataForSpecificFirstParty { firstPartyDomain, thirdPartyHasStorageAccess, Seconds { ResourceLoadStatistics::NoExistingTimestamp }};
- thirdPartyDataForSpecificFirstPartyDomain.appendIfNotContains(thirdPartyDataForSpecificFirstParty);
-}
-
-static Vector<WebResourceLoadStatisticsStore::ThirdPartyDataForSpecificFirstParty> getThirdPartyDataForSpecificFirstPartyDomains(const ResourceLoadStatistics& thirdPartyStatistic)
-{
- Vector<WebResourceLoadStatisticsStore::ThirdPartyDataForSpecificFirstParty> thirdPartyDataForSpecificFirstPartyDomains;
-
- for (auto firstPartyDomain : thirdPartyStatistic.subframeUnderTopFrameDomains)
- ensureThirdPartyDataForSpecificFirstPartyDomain(thirdPartyDataForSpecificFirstPartyDomains, firstPartyDomain, thirdPartyStatistic.storageAccessUnderTopFrameDomains.contains(firstPartyDomain));
- for (auto firstPartyDomain : thirdPartyStatistic.subresourceUnderTopFrameDomains)
- ensureThirdPartyDataForSpecificFirstPartyDomain(thirdPartyDataForSpecificFirstPartyDomains, firstPartyDomain, thirdPartyStatistic.storageAccessUnderTopFrameDomains.contains(firstPartyDomain));
- for (auto firstPartyDomain : thirdPartyStatistic.subresourceUniqueRedirectsTo)
- ensureThirdPartyDataForSpecificFirstPartyDomain(thirdPartyDataForSpecificFirstPartyDomains, firstPartyDomain, thirdPartyStatistic.storageAccessUnderTopFrameDomains.contains(firstPartyDomain));
-
- return thirdPartyDataForSpecificFirstPartyDomains;
-}
-
-static bool hasBeenThirdParty(const ResourceLoadStatistics& statistic)
-{
- return !statistic.subframeUnderTopFrameDomains.isEmpty()
- || !statistic.subresourceUnderTopFrameDomains.isEmpty()
- || !statistic.subresourceUniqueRedirectsTo.isEmpty();
-}
-
-Vector<WebResourceLoadStatisticsStore::ThirdPartyData> ResourceLoadStatisticsMemoryStore::aggregatedThirdPartyData() const
-{
- ASSERT(!RunLoop::isMain());
-
- Vector<WebResourceLoadStatisticsStore::ThirdPartyData> thirdPartyDataList;
- for (const auto& statistics : m_resourceStatisticsMap.values()) {
- if (hasBeenThirdParty(statistics) && (thirdPartyCookieBlockingMode() == ThirdPartyCookieBlockingMode::All || statistics->isPrevalentResource))
- thirdPartyDataList.append(WebResourceLoadStatisticsStore::ThirdPartyData { statistics->registrableDomain, getThirdPartyDataForSpecificFirstPartyDomains(statistics) });
- }
- std::sort(thirdPartyDataList.rbegin(), thirdPartyDataList.rend());
- return thirdPartyDataList;
-}
-
-void ResourceLoadStatisticsMemoryStore::incrementRecordsDeletedCountForDomains(HashSet<RegistrableDomain>&& domainsWithDeletedWebsiteData)
-{
- ASSERT(!RunLoop::isMain());
-
- for (auto& domain : domainsWithDeletedWebsiteData) {
- auto& statistic = ensureResourceStatisticsForRegistrableDomain(domain);
- ++statistic.dataRecordsRemoved;
- }
-}
-
-unsigned ResourceLoadStatisticsMemoryStore::recursivelyGetAllDomainsThatHaveRedirectedToThisDomain(const ResourceLoadStatistics& resourceStatistic, HashSet<RegistrableDomain>& domainsThatHaveRedirectedTo, unsigned numberOfRecursiveCalls) const
-{
- ASSERT(!RunLoop::isMain());
-
- if (numberOfRecursiveCalls >= maxNumberOfRecursiveCallsInRedirectTraceBack) {
- // Model version 14 invokes a deliberate re-classification of the whole set.
- if (statisticsModelVersion != 14)
- ASSERT_NOT_REACHED();
- RELEASE_LOG(ResourceLoadStatistics, "Hit %u recursive calls in redirect backtrace. Returning early.", maxNumberOfRecursiveCallsInRedirectTraceBack);
- return numberOfRecursiveCalls;
- }
-
- numberOfRecursiveCalls++;
-
- for (auto& subresourceUniqueRedirectFromDomain : resourceStatistic.subresourceUniqueRedirectsFrom) {
- auto* statistics = m_resourceStatisticsMap.get(RegistrableDomain { subresourceUniqueRedirectFromDomain });
- if (!statistics || statistics->isPrevalentResource)
- continue;
- if (domainsThatHaveRedirectedTo.add(statistics->registrableDomain).isNewEntry)
- numberOfRecursiveCalls = recursivelyGetAllDomainsThatHaveRedirectedToThisDomain(*statistics, domainsThatHaveRedirectedTo, numberOfRecursiveCalls);
- }
- for (auto& topFrameUniqueRedirectFromDomain : resourceStatistic.topFrameUniqueRedirectsFrom) {
- auto* statistics = m_resourceStatisticsMap.get(RegistrableDomain { topFrameUniqueRedirectFromDomain });
- if (!statistics || statistics->isPrevalentResource)
- continue;
- if (domainsThatHaveRedirectedTo.add(statistics->registrableDomain).isNewEntry)
- numberOfRecursiveCalls = recursivelyGetAllDomainsThatHaveRedirectedToThisDomain(*statistics, domainsThatHaveRedirectedTo, numberOfRecursiveCalls);
- }
-
- return numberOfRecursiveCalls;
-}
-
-void ResourceLoadStatisticsMemoryStore::markAsPrevalentIfHasRedirectedToPrevalent(ResourceLoadStatistics& resourceStatistic)
-{
- ASSERT(!RunLoop::isMain());
-
- if (resourceStatistic.isPrevalentResource)
- return;
-
- for (auto& subresourceDomainRedirectedTo : resourceStatistic.subresourceUniqueRedirectsTo) {
- auto* statistics = m_resourceStatisticsMap.get(RegistrableDomain { subresourceDomainRedirectedTo });
- if (statistics && statistics->isPrevalentResource) {
- setPrevalentResource(resourceStatistic, ResourceLoadPrevalence::High);
- return;
- }
- }
-
- for (auto& topFrameDomainRedirectedTo : resourceStatistic.topFrameUniqueRedirectsTo) {
- auto* statistics = m_resourceStatisticsMap.get(RegistrableDomain { topFrameDomainRedirectedTo });
- if (statistics && statistics->isPrevalentResource) {
- setPrevalentResource(resourceStatistic, ResourceLoadPrevalence::High);
- return;
- }
- }
-}
-
-bool ResourceLoadStatisticsMemoryStore::isPrevalentDueToDebugMode(ResourceLoadStatistics& resourceStatistic)
-{
- if (!debugModeEnabled())
- return false;
-
- return resourceStatistic.registrableDomain == debugStaticPrevalentResource() || resourceStatistic.registrableDomain == debugManualPrevalentResource();
-}
-
-void ResourceLoadStatisticsMemoryStore::classifyPrevalentResources()
-{
- ASSERT(!RunLoop::isMain());
-
- for (auto& resourceStatistic : m_resourceStatisticsMap.values()) {
- if (shouldSkip(resourceStatistic->registrableDomain))
- continue;
- if (isPrevalentDueToDebugMode(resourceStatistic))
- setPrevalentResource(resourceStatistic, ResourceLoadPrevalence::High);
- else if (!resourceStatistic->isVeryPrevalentResource) {
- markAsPrevalentIfHasRedirectedToPrevalent(resourceStatistic);
- auto currentPrevalence = resourceStatistic->isPrevalentResource ? ResourceLoadPrevalence::High : ResourceLoadPrevalence::Low;
- auto newPrevalence = classifier().calculateResourcePrevalence(resourceStatistic, currentPrevalence);
- if (newPrevalence != currentPrevalence)
- setPrevalentResource(resourceStatistic, newPrevalence);
- }
- }
-}
-
-bool ResourceLoadStatisticsMemoryStore::areAllThirdPartyCookiesBlockedUnder(const TopFrameDomain& topFrameDomain)
-{
- if (thirdPartyCookieBlockingMode() == ThirdPartyCookieBlockingMode::All)
- return true;
-
- if (thirdPartyCookieBlockingMode() == ThirdPartyCookieBlockingMode::AllOnSitesWithoutUserInteraction && !hasHadUserInteraction(topFrameDomain, OperatingDatesWindow::Long))
- return true;
-
- return false;
-}
-
-CookieAccess ResourceLoadStatisticsMemoryStore::cookieAccess(const ResourceLoadStatistics& resourceStatistic, const TopFrameDomain& topFrameDomain)
-{
- bool isPrevalent = resourceStatistic.isPrevalentResource;
- bool hadUserInteraction = resourceStatistic.hadUserInteraction;
-
- if (!areAllThirdPartyCookiesBlockedUnder(topFrameDomain) && !isPrevalent)
- return CookieAccess::BasedOnCookiePolicy;
-
- if (!hadUserInteraction)
- return CookieAccess::CannotRequest;
-
- return CookieAccess::OnlyIfGranted;
-}
-
-void ResourceLoadStatisticsMemoryStore::hasStorageAccess(const SubFrameDomain& subFrameDomain, const TopFrameDomain& topFrameDomain, std::optional<FrameIdentifier> frameID, PageIdentifier pageID, CompletionHandler<void(bool)>&& completionHandler)
-{
- ASSERT(!RunLoop::isMain());
-
- auto& subFrameStatistic = ensureResourceStatisticsForRegistrableDomain(subFrameDomain);
- switch (cookieAccess(subFrameStatistic, topFrameDomain)) {
- case CookieAccess::CannotRequest:
- completionHandler(false);
- return;
- case CookieAccess::BasedOnCookiePolicy:
- RunLoop::main().dispatch([store = makeRef(store()), subFrameDomain = subFrameDomain.isolatedCopy(), completionHandler = WTFMove(completionHandler)]() mutable {
- store->hasCookies(subFrameDomain, [store, completionHandler = WTFMove(completionHandler)](bool result) mutable {
- store->statisticsQueue().dispatch([completionHandler = WTFMove(completionHandler), result] () mutable {
- completionHandler(result);
- });
- });
- });
- return;
- case CookieAccess::OnlyIfGranted:
- // Handled below.
- break;
- }
-
- RunLoop::main().dispatch([store = makeRef(store()), subFrameDomain = subFrameDomain.isolatedCopy(), topFrameDomain = topFrameDomain.isolatedCopy(), frameID, pageID, completionHandler = WTFMove(completionHandler)]() mutable {
- store->callHasStorageAccessForFrameHandler(subFrameDomain, topFrameDomain, frameID.value(), pageID, [store, completionHandler = WTFMove(completionHandler)](bool result) mutable {
- store->statisticsQueue().dispatch([completionHandler = WTFMove(completionHandler), result] () mutable {
- completionHandler(result);
- });
- });
- });
-}
-
-void ResourceLoadStatisticsMemoryStore::requestStorageAccess(SubFrameDomain&& subFrameDomain, TopFrameDomain&& topFrameDomain, FrameIdentifier frameID, PageIdentifier pageID, StorageAccessScope scope, CompletionHandler<void(StorageAccessStatus)>&& completionHandler)
-{
- ASSERT(!RunLoop::isMain());
-
- auto& subFrameStatistic = ensureResourceStatisticsForRegistrableDomain(subFrameDomain);
- switch (cookieAccess(subFrameStatistic, topFrameDomain)) {
- case CookieAccess::CannotRequest:
- if (UNLIKELY(debugLoggingEnabled())) {
- RELEASE_LOG_INFO(ITPDebug, "Cannot grant storage access to %" PUBLIC_LOG_STRING " since its cookies are blocked in third-party contexts and it has not received user interaction as first-party.", subFrameDomain.string().utf8().data());
- debugBroadcastConsoleMessage(MessageSource::ITPDebug, MessageLevel::Info, makeString("[ITP] Cannot grant storage access to '"_s, subFrameDomain.string(), "' since its cookies are blocked in third-party contexts and it has not received user interaction as first-party."_s));
- }
- completionHandler(StorageAccessStatus::CannotRequestAccess);
- return;
-
- case CookieAccess::BasedOnCookiePolicy:
- if (UNLIKELY(debugLoggingEnabled())) {
- RELEASE_LOG_INFO(ITPDebug, "No need to grant storage access to %" PUBLIC_LOG_STRING " since its cookies are not blocked in third-party contexts. Note that the underlying cookie policy may still block this third-party from setting cookies.", subFrameDomain.string().utf8().data());
- debugBroadcastConsoleMessage(MessageSource::ITPDebug, MessageLevel::Info, makeString("[ITP] No need to grant storage access to '"_s, subFrameDomain.string(), "' since its cookies are not blocked in third-party contexts. Note that the underlying cookie policy may still block this third-party from setting cookies."_s));
- }
- completionHandler(StorageAccessStatus::HasAccess);
- return;
-
- case CookieAccess::OnlyIfGranted:
- // Handled below.
- break;
- }
-
- auto userWasPromptedEarlier = hasUserGrantedStorageAccessThroughPrompt(subFrameStatistic, topFrameDomain);
- if (userWasPromptedEarlier == StorageAccessPromptWasShown::No) {
- if (UNLIKELY(debugLoggingEnabled())) {
- RELEASE_LOG_INFO(ITPDebug, "About to ask the user whether they want to grant storage access to %" PUBLIC_LOG_STRING " under %" PUBLIC_LOG_STRING " or not.", subFrameDomain.string().utf8().data(), topFrameDomain.string().utf8().data());
- debugBroadcastConsoleMessage(MessageSource::ITPDebug, MessageLevel::Info, makeString("[ITP] About to ask the user whether they want to grant storage access to '"_s, subFrameDomain.string(), "' under '"_s, topFrameDomain.string(), "' or not."_s));
- }
- completionHandler(StorageAccessStatus::RequiresUserPrompt);
- return;
- }
-
- if (userWasPromptedEarlier == StorageAccessPromptWasShown::Yes) {
- if (UNLIKELY(debugLoggingEnabled())) {
- RELEASE_LOG_INFO(ITPDebug, "Storage access was granted to %" PUBLIC_LOG_STRING " under %" PUBLIC_LOG_STRING ".", subFrameDomain.string().utf8().data(), topFrameDomain.string().utf8().data());
- debugBroadcastConsoleMessage(MessageSource::ITPDebug, MessageLevel::Info, makeString("[ITP] Storage access was granted to '"_s, subFrameDomain.string(), "' under '"_s, topFrameDomain.string(), "'."_s));
- }
- }
-
- subFrameStatistic.timesAccessedAsFirstPartyDueToStorageAccessAPI++;
-
- grantStorageAccessInternal(WTFMove(subFrameDomain), WTFMove(topFrameDomain), frameID, pageID, userWasPromptedEarlier, scope, [completionHandler = WTFMove(completionHandler)] (StorageAccessWasGranted wasGranted) mutable {
- completionHandler(wasGranted == StorageAccessWasGranted::Yes ? StorageAccessStatus::HasAccess : StorageAccessStatus::CannotRequestAccess);
- });
-}
-
-void ResourceLoadStatisticsMemoryStore::requestStorageAccessUnderOpener(DomainInNeedOfStorageAccess&& domainInNeedOfStorageAccess, PageIdentifier openerPageID, OpenerDomain&& openerDomain)
-{
- ASSERT(domainInNeedOfStorageAccess != openerDomain);
- ASSERT(!RunLoop::isMain());
-
- if (domainInNeedOfStorageAccess == openerDomain)
- return;
-
- if (UNLIKELY(debugLoggingEnabled())) {
- RELEASE_LOG_INFO(ITPDebug, "[Temporary combatibility fix] Storage access was granted for %" PUBLIC_LOG_STRING " under opener page from %" PUBLIC_LOG_STRING ", with user interaction in the opened window.", domainInNeedOfStorageAccess.string().utf8().data(), openerDomain.string().utf8().data());
- debugBroadcastConsoleMessage(MessageSource::ITPDebug, MessageLevel::Info, makeString("[ITP] Storage access was granted for '"_s, domainInNeedOfStorageAccess.string(), "' under opener page from '"_s, openerDomain.string(), "', with user interaction in the opened window."_s));
- }
-
- grantStorageAccessInternal(WTFMove(domainInNeedOfStorageAccess), WTFMove(openerDomain), std::nullopt, openerPageID, StorageAccessPromptWasShown::No, StorageAccessScope::PerPage, [](StorageAccessWasGranted) { });
-}
-
-void ResourceLoadStatisticsMemoryStore::grantStorageAccess(SubFrameDomain&& subFrameDomain, TopFrameDomain&& topFrameDomain, FrameIdentifier frameID, PageIdentifier pageID, StorageAccessPromptWasShown promptWasShown, StorageAccessScope scope, CompletionHandler<void(StorageAccessWasGranted)>&& completionHandler)
-{
- ASSERT(!RunLoop::isMain());
-
- if (promptWasShown == StorageAccessPromptWasShown::Yes) {
- auto& subFrameStatistic = ensureResourceStatisticsForRegistrableDomain(subFrameDomain);
- ASSERT(subFrameStatistic.hadUserInteraction);
- subFrameStatistic.storageAccessUnderTopFrameDomains.add(topFrameDomain);
- }
- grantStorageAccessInternal(WTFMove(subFrameDomain), WTFMove(topFrameDomain), frameID, pageID, promptWasShown, scope, WTFMove(completionHandler));
-}
-
-void ResourceLoadStatisticsMemoryStore::grantStorageAccessInternal(SubFrameDomain&& subFrameDomain, TopFrameDomain&& topFrameDomain, std::optional<FrameIdentifier> frameID, PageIdentifier pageID, StorageAccessPromptWasShown promptWasShownNowOrEarlier, StorageAccessScope scope, CompletionHandler<void(StorageAccessWasGranted)>&& completionHandler)
-{
- ASSERT(!RunLoop::isMain());
-
- if (subFrameDomain == topFrameDomain) {
- completionHandler(StorageAccessWasGranted::Yes);
- return;
- }
-
- if (promptWasShownNowOrEarlier == StorageAccessPromptWasShown::Yes) {
- auto& subFrameStatistic = ensureResourceStatisticsForRegistrableDomain(subFrameDomain);
- ASSERT(subFrameStatistic.hadUserInteraction);
- ASSERT(subFrameStatistic.storageAccessUnderTopFrameDomains.contains(topFrameDomain));
- subFrameStatistic.mostRecentUserInteractionTime = WallTime::now();
- }
-
- RunLoop::main().dispatch([subFrameDomain = subFrameDomain.isolatedCopy(), topFrameDomain = topFrameDomain.isolatedCopy(), frameID, pageID, store = makeRef(store()), scope, completionHandler = WTFMove(completionHandler)]() mutable {
- store->callGrantStorageAccessHandler(subFrameDomain, topFrameDomain, frameID, pageID, scope, [completionHandler = WTFMove(completionHandler), store](StorageAccessWasGranted wasGranted) mutable {
- store->statisticsQueue().dispatch([wasGranted, completionHandler = WTFMove(completionHandler)] () mutable {
- completionHandler(wasGranted);
- });
- });
- });
-}
-
-void ResourceLoadStatisticsMemoryStore::grandfatherDataForDomains(const HashSet<RegistrableDomain>& domains)
-{
- ASSERT(!RunLoop::isMain());
-
- for (auto& domain : domains) {
- auto& statistic = ensureResourceStatisticsForRegistrableDomain(domain);
- statistic.grandfathered = true;
- }
-}
-
-Vector<RegistrableDomain> ResourceLoadStatisticsMemoryStore::ensurePrevalentResourcesForDebugMode()
-{
- ASSERT(!RunLoop::isMain());
-
- if (!debugModeEnabled())
- return { };
-
- Vector<RegistrableDomain> domainsToBlock;
- domainsToBlock.reserveInitialCapacity(2);
-
- auto& staticSesourceStatistic = ensureResourceStatisticsForRegistrableDomain(debugStaticPrevalentResource());
- setPrevalentResource(staticSesourceStatistic, ResourceLoadPrevalence::High);
- domainsToBlock.uncheckedAppend(debugStaticPrevalentResource());
-
- if (!debugManualPrevalentResource().isEmpty()) {
- auto& manualResourceStatistic = ensureResourceStatisticsForRegistrableDomain(debugManualPrevalentResource());
- setPrevalentResource(manualResourceStatistic, ResourceLoadPrevalence::High);
- domainsToBlock.uncheckedAppend(debugManualPrevalentResource());
-
- if (debugLoggingEnabled()) {
- RELEASE_LOG_INFO(ITPDebug, "Did set %" PUBLIC_LOG_STRING " as prevalent resource for the purposes of ITP Debug Mode.", debugManualPrevalentResource().string().utf8().data());
- debugBroadcastConsoleMessage(MessageSource::ITPDebug, MessageLevel::Info, makeString("[ITP] Did set '"_s, debugManualPrevalentResource().string(), "' as prevalent resource for the purposes of ITP Debug Mode."_s));
- }
- }
-
- return domainsToBlock;
-}
-
-void ResourceLoadStatisticsMemoryStore::logFrameNavigation(const RegistrableDomain& targetDomain, const RegistrableDomain& topFrameDomain, const RegistrableDomain& sourceDomain, bool isRedirect, bool isMainFrame, Seconds delayAfterMainFrameDocumentLoad, bool wasPotentiallyInitiatedByUser)
-{
- ASSERT(!RunLoop::isMain());
-
- bool areTargetAndTopFrameDomainsSameSite = targetDomain == topFrameDomain;
- bool areTargetAndSourceDomainsSameSite = targetDomain == sourceDomain;
-
- bool statisticsWereUpdated = false;
- if (!isMainFrame && !(areTargetAndTopFrameDomainsSameSite || areTargetAndSourceDomainsSameSite)) {
- auto& targetStatistics = ensureResourceStatisticsForRegistrableDomain(targetDomain);
- targetStatistics.lastSeen = ResourceLoadStatistics::reduceTimeResolution(WallTime::now());
- if (targetStatistics.subframeUnderTopFrameDomains.add(topFrameDomain).isNewEntry)
- statisticsWereUpdated = true;
- }
-
- if (!areTargetAndSourceDomainsSameSite) {
- if (isMainFrame) {
- auto& redirectingDomainStatistics = ensureResourceStatisticsForRegistrableDomain(sourceDomain);
- bool wasNavigatedAfterShortDelayWithoutUserInteraction = !wasPotentiallyInitiatedByUser && delayAfterMainFrameDocumentLoad < parameters().minDelayAfterMainFrameDocumentLoadToNotBeARedirect;
- if (isRedirect || wasNavigatedAfterShortDelayWithoutUserInteraction) {
- if (redirectingDomainStatistics.topFrameUniqueRedirectsTo.add(targetDomain).isNewEntry)
- statisticsWereUpdated = true;
- if (isRedirect && redirectingDomainStatistics.topFrameUniqueRedirectsToSinceSameSiteStrictEnforcement.add(targetDomain).isNewEntry) {
- statisticsWereUpdated = true;
-
- if (UNLIKELY(debugLoggingEnabled())) {
- RELEASE_LOG_INFO(ITPDebug, "Did set %" PUBLIC_LOG_STRING " as making a top frame redirect to %" PUBLIC_LOG_STRING ".", sourceDomain.string().utf8().data(), targetDomain.string().utf8().data());
- debugBroadcastConsoleMessage(MessageSource::ITPDebug, MessageLevel::Info, makeString("Did set '", sourceDomain.string(), "' as making a top frame redirect to '", targetDomain.string(), "'."));
- }
- }
- auto& targetStatistics = ensureResourceStatisticsForRegistrableDomain(targetDomain);
- if (targetStatistics.topFrameUniqueRedirectsFrom.add(sourceDomain).isNewEntry)
- statisticsWereUpdated = true;
- }
- } else if (isRedirect) {
- auto& redirectingDomainStatistics = ensureResourceStatisticsForRegistrableDomain(sourceDomain);
- if (redirectingDomainStatistics.subresourceUniqueRedirectsTo.add(targetDomain).isNewEntry)
- statisticsWereUpdated = true;
- auto& targetStatistics = ensureResourceStatisticsForRegistrableDomain(targetDomain);
- if (targetStatistics.subresourceUniqueRedirectsFrom.add(sourceDomain).isNewEntry)
- statisticsWereUpdated = true;
- }
- }
-
- if (statisticsWereUpdated)
- scheduleStatisticsProcessingRequestIfNecessary();
-}
-
-void ResourceLoadStatisticsMemoryStore::logUserInteraction(const TopFrameDomain& domain, CompletionHandler<void()>&& completionHandler)
-{
- ASSERT(!RunLoop::isMain());
-
- auto& statistics = ensureResourceStatisticsForRegistrableDomain(domain);
- bool didHavePreviousUserInteraction = statistics.hadUserInteraction;
- statistics.hadUserInteraction = true;
- statistics.mostRecentUserInteractionTime = WallTime::now();
- if (didHavePreviousUserInteraction) {
- completionHandler();
- return;
- }
- updateCookieBlocking(WTFMove(completionHandler));
-}
-
-void ResourceLoadStatisticsMemoryStore::logCrossSiteLoadWithLinkDecoration(const NavigatedFromDomain& fromDomain, const NavigatedToDomain& toDomain)
-{
- ASSERT(!RunLoop::isMain());
- ASSERT(fromDomain != toDomain);
-
- auto& toStatistics = ensureResourceStatisticsForRegistrableDomain(toDomain);
- toStatistics.topFrameLinkDecorationsFrom.add(fromDomain);
-
- auto& fromStatistics = ensureResourceStatisticsForRegistrableDomain(fromDomain);
- if (fromStatistics.isPrevalentResource)
- toStatistics.gotLinkDecorationFromPrevalentResource = true;
-}
-
-void ResourceLoadStatisticsMemoryStore::clearUserInteraction(const RegistrableDomain& domain, CompletionHandler<void()>&& completionHandler)
-{
- ASSERT(!RunLoop::isMain());
-
- auto& statistics = ensureResourceStatisticsForRegistrableDomain(domain);
- bool didHavePreviousUserInteraction = statistics.hadUserInteraction;
- statistics.hadUserInteraction = false;
- statistics.mostRecentUserInteractionTime = { };
- if (!didHavePreviousUserInteraction) {
- completionHandler();
- return;
- }
- updateCookieBlocking(WTFMove(completionHandler));
-}
-
-bool ResourceLoadStatisticsMemoryStore::hasHadUserInteraction(const RegistrableDomain& domain, OperatingDatesWindow operatingDatesWindow)
-{
- ASSERT(!RunLoop::isMain());
-
- auto* statistics = m_resourceStatisticsMap.get(domain);
- return statistics ? hasHadUnexpiredRecentUserInteraction(*statistics, operatingDatesWindow) : false;
-}
-
-void ResourceLoadStatisticsMemoryStore::setPrevalentResource(ResourceLoadStatistics& resourceStatistic, ResourceLoadPrevalence newPrevalence)
-{
- ASSERT(!RunLoop::isMain());
-
- if (shouldSkip(resourceStatistic.registrableDomain))
- return;
-
- resourceStatistic.isPrevalentResource = true;
- resourceStatistic.isVeryPrevalentResource = newPrevalence == ResourceLoadPrevalence::VeryHigh;
- HashSet<RegistrableDomain> domainsThatHaveRedirectedTo;
- recursivelyGetAllDomainsThatHaveRedirectedToThisDomain(resourceStatistic, domainsThatHaveRedirectedTo, 0);
- for (auto& domain : domainsThatHaveRedirectedTo) {
- auto* statistics = m_resourceStatisticsMap.get(domain);
- if (!statistics)
- continue;
- ASSERT(!statistics->isPrevalentResource);
- statistics->isPrevalentResource = true;
- }
-}
-
-void ResourceLoadStatisticsMemoryStore::dumpResourceLoadStatistics(CompletionHandler<void(const String&)>&& completionHandler)
-{
- ASSERT(!RunLoop::isMain());
- if (dataRecordsBeingRemoved()) {
- m_dataRecordRemovalCompletionHandlers.append([this, completionHandler = WTFMove(completionHandler)]() mutable {
- dumpResourceLoadStatistics(WTFMove(completionHandler));
- });
- return;
- }
-
- StringBuilder result;
- result.append("Resource load statistics:\n\n");
- Vector<String> sortedMapEntries;
- for (auto& mapEntry : m_resourceStatisticsMap.values())
- sortedMapEntries.append(mapEntry->toString());
-
- std::sort(sortedMapEntries.begin(), sortedMapEntries.end(), WTF::codePointCompareLessThan);
-
- for (auto& entry : sortedMapEntries)
- result.append(entry);
-
- auto thirdPartyData = aggregatedThirdPartyData();
- if (!thirdPartyData.isEmpty()) {
- result.append("\nITP Data:\n");
- for (auto thirdParty : thirdPartyData) {
- result.append(thirdParty.toString());
- result.append('\n');
- }
- }
- completionHandler(result.toString());
-}
-
-bool ResourceLoadStatisticsMemoryStore::isPrevalentResource(const RegistrableDomain& domain) const
-{
- ASSERT(!RunLoop::isMain());
-
- if (shouldSkip(domain))
- return false;
-
- auto* statistics = m_resourceStatisticsMap.get(domain);
- return statistics ? statistics->isPrevalentResource : false;
-}
-
-bool ResourceLoadStatisticsMemoryStore::isVeryPrevalentResource(const RegistrableDomain& domain) const
-{
- ASSERT(!RunLoop::isMain());
-
- if (shouldSkip(domain))
- return false;
-
- auto* statistics = m_resourceStatisticsMap.get(domain);
- return statistics ? statistics->isPrevalentResource && statistics->isVeryPrevalentResource : false;
-}
-
-bool ResourceLoadStatisticsMemoryStore::isRegisteredAsSubresourceUnder(const SubResourceDomain& subresourceDomain, const TopFrameDomain& topFrameDomain) const
-{
- ASSERT(!RunLoop::isMain());
-
- auto* statistics = m_resourceStatisticsMap.get(subresourceDomain);
- return statistics ? statistics->subresourceUnderTopFrameDomains.contains(topFrameDomain) : false;
-}
-
-bool ResourceLoadStatisticsMemoryStore::isRegisteredAsSubFrameUnder(const SubFrameDomain& subFrameDomain, const TopFrameDomain& topFrameDomain) const
-{
- ASSERT(!RunLoop::isMain());
-
- auto* statistics = m_resourceStatisticsMap.get(subFrameDomain);
- return statistics ? statistics->subframeUnderTopFrameDomains.contains(topFrameDomain) : false;
-}
-
-bool ResourceLoadStatisticsMemoryStore::isRegisteredAsRedirectingTo(const RedirectedFromDomain& redirectedFromDomain, const RedirectedToDomain& redirectedToDomain) const
-{
- ASSERT(!RunLoop::isMain());
-
- auto* statistics = m_resourceStatisticsMap.get(redirectedFromDomain);
- return statistics ? statistics->subresourceUniqueRedirectsTo.contains(redirectedToDomain) : false;
-}
-
-void ResourceLoadStatisticsMemoryStore::clearPrevalentResource(const RegistrableDomain& domain)
-{
- ASSERT(!RunLoop::isMain());
-
- auto& statistics = ensureResourceStatisticsForRegistrableDomain(domain);
- statistics.isPrevalentResource = false;
- statistics.isVeryPrevalentResource = false;
-}
-
-void ResourceLoadStatisticsMemoryStore::setGrandfathered(const RegistrableDomain& domain, bool value)
-{
- ASSERT(!RunLoop::isMain());
-
- auto& statistics = ensureResourceStatisticsForRegistrableDomain(domain);
- statistics.grandfathered = value;
-}
-
-bool ResourceLoadStatisticsMemoryStore::isGrandfathered(const RegistrableDomain& domain) const
-{
- ASSERT(!RunLoop::isMain());
-
- auto* statistics = m_resourceStatisticsMap.get(domain);
- return statistics ? statistics->grandfathered : false;
-}
-
-void ResourceLoadStatisticsMemoryStore::setSubframeUnderTopFrameDomain(const SubFrameDomain& subFrameDomain, const TopFrameDomain& topFrameDomain)
-{
- ASSERT(!RunLoop::isMain());
-
- auto& statistics = ensureResourceStatisticsForRegistrableDomain(subFrameDomain);
- statistics.subframeUnderTopFrameDomains.add(topFrameDomain);
- // For consistency, make sure we also have a statistics entry for the top frame domain.
- ensureResourceStatisticsForRegistrableDomain(topFrameDomain);
-}
-
-void ResourceLoadStatisticsMemoryStore::setSubresourceUnderTopFrameDomain(const SubResourceDomain& subresourceDomain, const RegistrableDomain& topFrameDomain)
-{
- ASSERT(!RunLoop::isMain());
-
- auto& statistics = ensureResourceStatisticsForRegistrableDomain(subresourceDomain);
- statistics.subresourceUnderTopFrameDomains.add(topFrameDomain);
- // For consistency, make sure we also have a statistics entry for the top frame domain.
- ensureResourceStatisticsForRegistrableDomain(topFrameDomain);
-}
-
-void ResourceLoadStatisticsMemoryStore::setSubresourceUniqueRedirectTo(const SubResourceDomain& subresourceDomain, const RedirectDomain& redirectDomain)
-{
- ASSERT(!RunLoop::isMain());
-
- auto& statistics = ensureResourceStatisticsForRegistrableDomain(subresourceDomain);
- statistics.subresourceUniqueRedirectsTo.add(redirectDomain);
- // For consistency, make sure we also have a statistics entry for the redirect domain.
- ensureResourceStatisticsForRegistrableDomain(redirectDomain);
-}
-
-void ResourceLoadStatisticsMemoryStore::setSubresourceUniqueRedirectFrom(const SubResourceDomain& subresourceDomain, const RedirectDomain& redirectDomain)
-{
- ASSERT(!RunLoop::isMain());
-
- auto& statistics = ensureResourceStatisticsForRegistrableDomain(subresourceDomain);
- statistics.subresourceUniqueRedirectsFrom.add(redirectDomain);
- // For consistency, make sure we also have a statistics entry for the redirect domain.
- ensureResourceStatisticsForRegistrableDomain(redirectDomain);
-}
-
-void ResourceLoadStatisticsMemoryStore::setTopFrameUniqueRedirectTo(const TopFrameDomain& topFrameDomain, const RedirectDomain& redirectDomain)
-{
- ASSERT(!RunLoop::isMain());
-
- auto& statistics = ensureResourceStatisticsForRegistrableDomain(topFrameDomain);
- statistics.topFrameUniqueRedirectsTo.add(redirectDomain);
- statistics.topFrameUniqueRedirectsToSinceSameSiteStrictEnforcement.add(redirectDomain);
- // For consistency, make sure we also have a statistics entry for the redirect domain.
- ensureResourceStatisticsForRegistrableDomain(redirectDomain);
-}
-
-void ResourceLoadStatisticsMemoryStore::setTopFrameUniqueRedirectFrom(const TopFrameDomain& topFrameDomain, const RedirectDomain& redirectDomain)
-{
- ASSERT(!RunLoop::isMain());
-
- auto& statistics = ensureResourceStatisticsForRegistrableDomain(topFrameDomain);
- statistics.topFrameUniqueRedirectsFrom.add(redirectDomain);
- // For consistency, make sure we also have a statistics entry for the redirect domain.
- ensureResourceStatisticsForRegistrableDomain(redirectDomain);
-}
-
-ResourceLoadStatistics& ResourceLoadStatisticsMemoryStore::ensureResourceStatisticsForRegistrableDomain(const RegistrableDomain& domain)
-{
- ASSERT(!RunLoop::isMain());
-
- return m_resourceStatisticsMap.ensure(domain, [&domain] {
- return makeUniqueRef<ResourceLoadStatistics>(domain);
- }).iterator->value;
-}
-
-std::unique_ptr<KeyedEncoder> ResourceLoadStatisticsMemoryStore::createEncoderFromData() const
-{
- ASSERT(!RunLoop::isMain());
-
- auto encoder = KeyedEncoder::encoder();
- encoder->encodeUInt32("version", statisticsModelVersion);
- encoder->encodeDouble("endOfGrandfatheringTimestamp", endOfGrandfatheringTimestamp().secondsSinceEpoch().value());
-
- encoder->encodeObjects("browsingStatistics", m_resourceStatisticsMap.begin(), m_resourceStatisticsMap.end(), [](KeyedEncoder& encoderInner, const auto& domain) {
- domain.value->encode(encoderInner);
- });
-
- auto& operatingDates = this->operatingDates();
- encoder->encodeObjects("operatingDates", operatingDates.begin(), operatingDates.end(), [](KeyedEncoder& encoderInner, OperatingDate date) {
- encoderInner.encodeDouble("date", date.secondsSinceEpoch().value());
- });
-
- return encoder;
-}
-
-void ResourceLoadStatisticsMemoryStore::mergeWithDataFromDecoder(KeyedDecoder& decoder)
-{
- ASSERT(!RunLoop::isMain());
-
- unsigned versionOnDisk;
- if (!decoder.decodeUInt32("version", versionOnDisk))
- return;
-
- if (versionOnDisk > statisticsModelVersion) {
- WTFLogAlways("Found resource load statistics on disk with model version %u whereas the highest supported version is %u. Resetting.", versionOnDisk, statisticsModelVersion);
- return;
- }
-
- double endOfGrandfatheringTimestamp;
- if (decoder.decodeDouble("endOfGrandfatheringTimestamp", endOfGrandfatheringTimestamp))
- setEndOfGrandfatheringTimestamp(WallTime::fromRawSeconds(endOfGrandfatheringTimestamp));
- else
- clearEndOfGrandfatheringTimeStamp();
-
- Vector<ResourceLoadStatistics> loadedStatistics;
- bool succeeded = decoder.decodeObjects("browsingStatistics", loadedStatistics, [versionOnDisk](KeyedDecoder& decoderInner, ResourceLoadStatistics& statistics) {
- return statistics.decode(decoderInner, versionOnDisk);
- });
-
- if (!succeeded)
- return;
-
- mergeStatistics(WTFMove(loadedStatistics));
- updateCookieBlocking([]() { });
-
- Vector<OperatingDate> operatingDates;
- succeeded = decoder.decodeObjects("operatingDates", operatingDates, [](KeyedDecoder& decoder, OperatingDate& date) {
- double value;
- if (!decoder.decodeDouble("date", value))
- return false;
-
- date = OperatingDate::fromWallTime(WallTime::fromRawSeconds(value));
- return true;
- });
-
- if (!succeeded)
- return;
-
- mergeOperatingDates(WTFMove(operatingDates));
-}
-
-void ResourceLoadStatisticsMemoryStore::clear(CompletionHandler<void()>&& completionHandler)
-{
- ASSERT(!RunLoop::isMain());
-
- m_resourceStatisticsMap.clear();
- clearOperatingDates();
-
- auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
-
- removeAllStorageAccess([callbackAggregator] { });
-
- auto registrableDomainsToBlockAndDeleteCookiesFor = ensurePrevalentResourcesForDebugMode();
- RegistrableDomainsToBlockCookiesFor domainsToBlock { registrableDomainsToBlockAndDeleteCookiesFor, { }, { }, { }};
- updateCookieBlockingForDomains(domainsToBlock, [callbackAggregator] { });
-}
-
-void ResourceLoadStatisticsMemoryStore::mergeStatistics(Vector<ResourceLoadStatistics>&& statistics)
-{
- ASSERT(!RunLoop::isMain());
-
- for (auto& statistic : statistics) {
- auto result = m_resourceStatisticsMap.ensure(statistic.registrableDomain, [&statistic] {
- return makeUniqueRef<ResourceLoadStatistics>(WTFMove(statistic));
- });
- if (!result.isNewEntry)
- result.iterator->value->merge(statistic);
- }
-}
-
-bool ResourceLoadStatisticsMemoryStore::shouldBlockAndKeepCookies(const ResourceLoadStatistics& statistic)
-{
- return statistic.isPrevalentResource && statistic.hadUserInteraction;
-}
-
-bool ResourceLoadStatisticsMemoryStore::shouldBlockAndPurgeCookies(const ResourceLoadStatistics& statistic)
-{
- return statistic.isPrevalentResource && !statistic.hadUserInteraction;
-}
-
-StorageAccessPromptWasShown ResourceLoadStatisticsMemoryStore::hasUserGrantedStorageAccessThroughPrompt(const ResourceLoadStatistics& statistic, const RegistrableDomain& firstPartyDomain)
-{
- return statistic.storageAccessUnderTopFrameDomains.contains(firstPartyDomain) ? StorageAccessPromptWasShown::Yes : StorageAccessPromptWasShown::No;
-}
-
-void ResourceLoadStatisticsMemoryStore::updateCookieBlocking(CompletionHandler<void()>&& completionHandler)
-{
- ASSERT(!RunLoop::isMain());
-
- Vector<RegistrableDomain> domainsToBlockAndDeleteCookiesFor;
- Vector<RegistrableDomain> domainsToBlockButKeepCookiesFor;
- Vector<RegistrableDomain> domainsWithUserInteractionAsFirstParty;
- for (auto& resourceStatistic : m_resourceStatisticsMap.values()) {
- if (hasHadUnexpiredRecentUserInteraction(resourceStatistic, OperatingDatesWindow::Long)) {
- if (resourceStatistic->isPrevalentResource)
- domainsToBlockButKeepCookiesFor.append(resourceStatistic->registrableDomain.isolatedCopy());
- domainsWithUserInteractionAsFirstParty.append(resourceStatistic->registrableDomain);
- } else if (resourceStatistic->isPrevalentResource)
- domainsToBlockAndDeleteCookiesFor.append(resourceStatistic->registrableDomain);
- }
-
- if (domainsToBlockAndDeleteCookiesFor.isEmpty() && domainsToBlockButKeepCookiesFor.isEmpty() && domainsWithUserInteractionAsFirstParty.isEmpty() && !debugModeEnabled()) {
- completionHandler();
- return;
- }
-
- RegistrableDomainsToBlockCookiesFor domainsToBlock { domainsToBlockAndDeleteCookiesFor, domainsToBlockButKeepCookiesFor, domainsWithUserInteractionAsFirstParty, { } };
-
- if (debugLoggingEnabled() && (!domainsToBlockAndDeleteCookiesFor.isEmpty() || !domainsToBlockButKeepCookiesFor.isEmpty()))
- debugLogDomainsInBatches("Applying cross-site tracking restrictions", domainsToBlock);
-
- RunLoop::main().dispatch([weakThis = makeWeakPtr(*this), store = makeRef(store()), domainsToBlock = crossThreadCopy(domainsToBlock), completionHandler = WTFMove(completionHandler)] () mutable {
- store->callUpdatePrevalentDomainsToBlockCookiesForHandler(domainsToBlock, [weakThis = WTFMove(weakThis), store, completionHandler = WTFMove(completionHandler)]() mutable {
- store->statisticsQueue().dispatch([weakThis = WTFMove(weakThis), completionHandler = WTFMove(completionHandler)]() mutable {
- completionHandler();
-
- if (!weakThis)
- return;
-
- if (UNLIKELY(weakThis->debugLoggingEnabled())) {
- RELEASE_LOG_INFO(ITPDebug, "Done applying cross-site tracking restrictions.");
- weakThis->debugBroadcastConsoleMessage(MessageSource::ITPDebug, MessageLevel::Info, "[ITP] Done applying cross-site tracking restrictions."_s);
- }
- });
- });
- });
-}
-
-void ResourceLoadStatisticsMemoryStore::processStatistics(const Function<void(const ResourceLoadStatistics&)>& processFunction) const
-{
- ASSERT(!RunLoop::isMain());
-
- for (const auto& resourceStatistic : m_resourceStatisticsMap.values())
- processFunction(resourceStatistic.get());
-}
-
-bool ResourceLoadStatisticsMemoryStore::hasHadUnexpiredRecentUserInteraction(ResourceLoadStatistics& resourceStatistic, OperatingDatesWindow operatingDatesWindow) const
-{
- ASSERT(!RunLoop::isMain());
-
- if (resourceStatistic.hadUserInteraction && hasStatisticsExpired(resourceStatistic, operatingDatesWindow)) {
- if (operatingDatesWindow == OperatingDatesWindow::Long) {
- // Drop privacy sensitive data because we no longer need it.
- // Set timestamp to 0 so that statistics merge will know
- // it has been reset as opposed to its default -1.
- resourceStatistic.mostRecentUserInteractionTime = { };
- resourceStatistic.storageAccessUnderTopFrameDomains.clear();
- resourceStatistic.hadUserInteraction = false;
- }
-
- return false;
- }
-
- return resourceStatistic.hadUserInteraction;
-}
-
-bool ResourceLoadStatisticsMemoryStore::shouldRemoveAllWebsiteDataFor(ResourceLoadStatistics& resourceStatistic, bool shouldCheckForGrandfathering) const
-{
- return resourceStatistic.isPrevalentResource && !hasHadUnexpiredRecentUserInteraction(resourceStatistic, OperatingDatesWindow::Long) && (!shouldCheckForGrandfathering || !resourceStatistic.grandfathered);
-}
-
-bool ResourceLoadStatisticsMemoryStore::shouldRemoveAllButCookiesFor(ResourceLoadStatistics& resourceStatistic, bool shouldCheckForGrandfathering) const
-{
- bool isRemovalEnabled = firstPartyWebsiteDataRemovalMode() != FirstPartyWebsiteDataRemovalMode::None || resourceStatistic.gotLinkDecorationFromPrevalentResource;
- bool isResourceGrandfathered = shouldCheckForGrandfathering && resourceStatistic.grandfathered;
-
- OperatingDatesWindow window { };
- switch (firstPartyWebsiteDataRemovalMode()) {
- case FirstPartyWebsiteDataRemovalMode::AllButCookies:
- FALLTHROUGH;
- case FirstPartyWebsiteDataRemovalMode::None:
- window = OperatingDatesWindow::Short;
- break;
- case FirstPartyWebsiteDataRemovalMode::AllButCookiesLiveOnTestingTimeout:
- window = OperatingDatesWindow::ForLiveOnTesting;
- break;
- case FirstPartyWebsiteDataRemovalMode::AllButCookiesReproTestingTimeout:
- window = OperatingDatesWindow::ForReproTesting;
- }
-
- return isRemovalEnabled && !isResourceGrandfathered && !hasHadUnexpiredRecentUserInteraction(resourceStatistic, window);
-}
-
-bool ResourceLoadStatisticsMemoryStore::shouldEnforceSameSiteStrictFor(ResourceLoadStatistics& resourceStatistic, bool shouldCheckForGrandfathering)
-{
- if ((!isSameSiteStrictEnforcementEnabled() && !shouldEnforceSameSiteStrictForSpecificDomain(resourceStatistic.registrableDomain))
- || (shouldCheckForGrandfathering && resourceStatistic.grandfathered))
- return false;
-
- if (resourceStatistic.topFrameUniqueRedirectsToSinceSameSiteStrictEnforcement.size() > parameters().minimumTopFrameRedirectsForSameSiteStrictEnforcement) {
- resourceStatistic.topFrameUniqueRedirectsToSinceSameSiteStrictEnforcement.clear();
- return true;
- }
-
- return false;
-}
-
-std::optional<WallTime> ResourceLoadStatisticsMemoryStore::mostRecentUserInteractionTime(const ResourceLoadStatistics& statistic)
-{
- if (statistic.mostRecentUserInteractionTime.secondsSinceEpoch().value() <= 0)
- return std::nullopt;
-
- return statistic.mostRecentUserInteractionTime;
-}
-
-RegistrableDomainsToDeleteOrRestrictWebsiteDataFor ResourceLoadStatisticsMemoryStore::registrableDomainsToDeleteOrRestrictWebsiteDataFor()
-{
- ASSERT(!RunLoop::isMain());
-
- bool shouldCheckForGrandfathering = endOfGrandfatheringTimestamp() > WallTime::now();
- bool shouldClearGrandfathering = !shouldCheckForGrandfathering && endOfGrandfatheringTimestamp();
-
- if (shouldClearGrandfathering)
- clearEndOfGrandfatheringTimeStamp();
-
- auto now = WallTime::now();
- auto oldestUserInteraction = now;
- RegistrableDomainsToDeleteOrRestrictWebsiteDataFor toDeleteOrRestrictFor;
- for (auto& statistic : m_resourceStatisticsMap.values()) {
- if (shouldExemptFromWebsiteDataDeletion(statistic->registrableDomain))
- continue;
- if (auto mostRecentUserInteractionTime = this->mostRecentUserInteractionTime(statistic))
- oldestUserInteraction = std::min(oldestUserInteraction, *mostRecentUserInteractionTime);
- if (shouldRemoveAllWebsiteDataFor(statistic, shouldCheckForGrandfathering)) {
- toDeleteOrRestrictFor.domainsToDeleteAllCookiesFor.append(statistic->registrableDomain);
- toDeleteOrRestrictFor.domainsToDeleteAllNonCookieWebsiteDataFor.append(statistic->registrableDomain);
- } else {
- if (shouldRemoveAllButCookiesFor(statistic, shouldCheckForGrandfathering)) {
- toDeleteOrRestrictFor.domainsToDeleteAllNonCookieWebsiteDataFor.append(statistic->registrableDomain);
- statistic->gotLinkDecorationFromPrevalentResource = false;
- }
- if (shouldEnforceSameSiteStrictFor(statistic, shouldCheckForGrandfathering)) {
- toDeleteOrRestrictFor.domainsToEnforceSameSiteStrictFor.append(statistic->registrableDomain);
-
- if (UNLIKELY(debugLoggingEnabled())) {
- RELEASE_LOG_INFO(ITPDebug, "Scheduled %" PUBLIC_LOG_STRING " to have its cookies set to SameSite=strict.", statistic->registrableDomain.string().utf8().data());
- debugBroadcastConsoleMessage(MessageSource::ITPDebug, MessageLevel::Info, makeString("Scheduled '", statistic->registrableDomain.string(), "' to have its cookies set to SameSite=strict'."));
- }
- }
- }
-
- if (shouldClearGrandfathering && statistic->grandfathered)
- statistic->grandfathered = false;
- }
-
- // Give the user enough time to interact with websites until we remove non-cookie website data.
- if (!parameters().isRunningTest && now - oldestUserInteraction < parameters().minimumTimeBetweenDataRecordsRemoval)
- toDeleteOrRestrictFor.domainsToDeleteAllNonCookieWebsiteDataFor.clear();
-
- return toDeleteOrRestrictFor;
-}
-
-void ResourceLoadStatisticsMemoryStore::pruneStatisticsIfNeeded()
-{
- ASSERT(!RunLoop::isMain());
-
- if (m_resourceStatisticsMap.size() <= parameters().maxStatisticsEntries)
- return;
-
- ASSERT(parameters().pruneEntriesDownTo <= parameters().maxStatisticsEntries);
-
- size_t numberOfEntriesLeftToPrune = m_resourceStatisticsMap.size() - parameters().pruneEntriesDownTo;
- ASSERT(numberOfEntriesLeftToPrune);
-
- Vector<StatisticsLastSeen> resourcesToPrunePerImportance[maxImportance + 1];
- for (auto& resourceStatistic : m_resourceStatisticsMap.values())
- resourcesToPrunePerImportance[computeImportance(resourceStatistic)].append({ resourceStatistic->registrableDomain, resourceStatistic->lastSeen });
-
- for (unsigned importance = 0; numberOfEntriesLeftToPrune && importance <= maxImportance; ++importance)
- pruneResources(m_resourceStatisticsMap, resourcesToPrunePerImportance[importance], numberOfEntriesLeftToPrune);
-
- ASSERT(!numberOfEntriesLeftToPrune);
-}
-
-void ResourceLoadStatisticsMemoryStore::setLastSeen(const RegistrableDomain& domain, Seconds seconds)
-{
- ASSERT(!RunLoop::isMain());
-
- auto& statistics = ensureResourceStatisticsForRegistrableDomain(domain);
- statistics.lastSeen = WallTime::fromRawSeconds(seconds.seconds());
-}
-
-void ResourceLoadStatisticsMemoryStore::removeDataForDomain(const RegistrableDomain& domain)
-{
- m_resourceStatisticsMap.remove(domain);
-
- for (auto& statistic : m_resourceStatisticsMap.values()) {
- statistic->topFrameUniqueRedirectsTo.remove(domain);
- statistic->topFrameUniqueRedirectsToSinceSameSiteStrictEnforcement.remove(domain);
- statistic->topFrameUniqueRedirectsFrom.remove(domain);
- statistic->topFrameLinkDecorationsFrom.remove(domain);
- statistic->topFrameLoadedThirdPartyScripts.remove(domain);
- statistic->subframeUnderTopFrameDomains.remove(domain);
- statistic->subresourceUnderTopFrameDomains.remove(domain);
- statistic->subresourceUniqueRedirectsTo.remove(domain);
- statistic->subresourceUniqueRedirectsFrom.remove(domain);
- }
-}
-
-Vector<RegistrableDomain> ResourceLoadStatisticsMemoryStore::allDomains() const
-{
- ASSERT(!RunLoop::isMain());
-
- return copyToVector(m_resourceStatisticsMap.keys());
-}
-
-void ResourceLoadStatisticsMemoryStore::setPrevalentResource(const RegistrableDomain& domain)
-{
- ASSERT(!RunLoop::isMain());
-
- if (shouldSkip(domain))
- return;
-
- auto& resourceStatistic = ensureResourceStatisticsForRegistrableDomain(domain);
- setPrevalentResource(resourceStatistic, ResourceLoadPrevalence::High);
-}
-
-void ResourceLoadStatisticsMemoryStore::setVeryPrevalentResource(const RegistrableDomain& domain)
-{
- ASSERT(!RunLoop::isMain());
-
- if (shouldSkip(domain))
- return;
-
- auto& resourceStatistic = ensureResourceStatisticsForRegistrableDomain(domain);
- setPrevalentResource(resourceStatistic, ResourceLoadPrevalence::VeryHigh);
-}
-
-Vector<OperatingDate> ResourceLoadStatisticsMemoryStore::mergeOperatingDates(const Vector<OperatingDate>& existingDates, Vector<OperatingDate>&& newDates)
-{
- if (existingDates.isEmpty())
- return WTFMove(newDates);
-
- Vector<OperatingDate> mergedDates(existingDates.size() + newDates.size());
-
- // Merge the two sorted vectors of dates.
- std::merge(existingDates.begin(), existingDates.end(), newDates.begin(), newDates.end(), mergedDates.begin());
- // Remove duplicate dates.
- removeRepeatedElements(mergedDates);
-
- // Drop old dates until the Vector size reaches operatingDatesWindowLong.
- while (mergedDates.size() > operatingDatesWindowLong)
- mergedDates.remove(0);
-
- return mergedDates;
-}
-
-void ResourceLoadStatisticsMemoryStore::mergeOperatingDates(Vector<OperatingDate>&& newDates)
-{
- ASSERT(!RunLoop::isMain());
-
- m_operatingDates = mergeOperatingDates(m_operatingDates, WTFMove(newDates));
-}
-
-void ResourceLoadStatisticsMemoryStore::includeTodayAsOperatingDateIfNecessary()
-{
- ASSERT(!RunLoop::isMain());
-
- auto today = OperatingDate::today();
- if (!m_operatingDates.isEmpty() && today <= m_operatingDates.last())
- return;
-
- while (m_operatingDates.size() >= operatingDatesWindowLong)
- m_operatingDates.remove(0);
-
- m_operatingDates.append(today);
-}
-
-bool ResourceLoadStatisticsMemoryStore::hasStatisticsExpired(WallTime mostRecentUserInteractionTime, OperatingDatesWindow operatingDatesWindow) const
-{
- ASSERT(!RunLoop::isMain());
-
- unsigned operatingDatesWindowInDays = 0;
- switch (operatingDatesWindow) {
- case OperatingDatesWindow::Long:
- operatingDatesWindowInDays = operatingDatesWindowLong;
- break;
- case OperatingDatesWindow::Short:
- operatingDatesWindowInDays = operatingDatesWindowShort;
- break;
- case OperatingDatesWindow::ForLiveOnTesting:
- return WallTime::now() > mostRecentUserInteractionTime + operatingTimeWindowForLiveOnTesting;
- case OperatingDatesWindow::ForReproTesting:
- return true;
- }
-
- if (m_operatingDates.size() >= operatingDatesWindowInDays) {
- if (OperatingDate::fromWallTime(mostRecentUserInteractionTime) < m_operatingDates.first())
- return true;
- }
-
- // If we don't meet the real criteria for an expired statistic, check the user setting for a tighter restriction (mainly for testing).
- if (this->parameters().timeToLiveUserInteraction) {
- if (WallTime::now() > mostRecentUserInteractionTime + this->parameters().timeToLiveUserInteraction.value())
- return true;
- }
-
- return false;
-}
-
-bool ResourceLoadStatisticsMemoryStore::hasStatisticsExpired(const ResourceLoadStatistics& resourceStatistic, OperatingDatesWindow operatingDatesWindow) const
-{
- return hasStatisticsExpired(resourceStatistic.mostRecentUserInteractionTime, operatingDatesWindow);
-}
-
-void ResourceLoadStatisticsMemoryStore::insertExpiredStatisticForTesting(const RegistrableDomain& domain, unsigned numberOfOperatingDaysPassed, bool hasUserInteraction, bool isScheduledForAllButCookieDataRemoval, bool isPrevalent)
-{
- // Populate the Operating Dates table with enough days to require pruning.
- double daysAgoInSeconds = 0;
- for (unsigned i = 1; i <= numberOfOperatingDaysPassed; i++) {
- double daysToSubtract = Seconds::fromHours(24 * i).value();
- daysAgoInSeconds = WallTime::now().secondsSinceEpoch().value() - daysToSubtract;
- auto dateToInsert = OperatingDate::fromWallTime(WallTime::fromRawSeconds(daysAgoInSeconds));
- m_operatingDates.append(OperatingDate(dateToInsert.year(), dateToInsert.month(), dateToInsert.monthDay()));
- }
-
- // Make sure mostRecentUserInteractionTime is the least recent of all entries.
- daysAgoInSeconds -= Seconds::fromHours(24).value();
-
- auto statistic = ResourceLoadStatistics(domain);
- statistic.lastSeen = WallTime::fromRawSeconds(daysAgoInSeconds);
- statistic.hadUserInteraction = hasUserInteraction;
- statistic.mostRecentUserInteractionTime = WallTime::fromRawSeconds(daysAgoInSeconds);
- statistic.isPrevalentResource = isPrevalent;
- statistic.gotLinkDecorationFromPrevalentResource = isScheduledForAllButCookieDataRemoval;
-
- m_resourceStatisticsMap.ensure(statistic.registrableDomain, [&statistic] {
- return makeUniqueRef<ResourceLoadStatistics>(WTFMove(statistic));
- });
-}
-
-} // namespace WebKit
-
-#endif
</del></span></pre></div>
<a id="trunkSourceWebKitNetworkProcessClassifierWebResourceLoadStatisticsStorecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsStore.cpp (282710 => 282711)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsStore.cpp 2021-09-17 23:45:48 UTC (rev 282710)
+++ trunk/Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsStore.cpp 2021-09-17 23:46:14 UTC (rev 282711)
</span><span class="lines">@@ -35,7 +35,6 @@
</span><span class="cx"> #include "NetworkSession.h"
</span><span class="cx"> #include "PrivateClickMeasurementManager.h"
</span><span class="cx"> #include "ResourceLoadStatisticsDatabaseStore.h"
</span><del>-#include "ResourceLoadStatisticsMemoryStore.h"
</del><span class="cx"> #include "ShouldGrandfatherStatistics.h"
</span><span class="cx"> #include "StorageAccessStatus.h"
</span><span class="cx"> #include "WebFrameProxy.h"
</span><span class="lines">@@ -166,9 +165,6 @@
</span><span class="cx"> postTask([this, resourceLoadStatisticsDirectory = resourceLoadStatisticsDirectory.isolatedCopy(), shouldIncludeLocalhost, sessionID = networkSession.sessionID()] {
</span><span class="cx"> m_statisticsStore = makeUnique<ResourceLoadStatisticsDatabaseStore>(*this, m_statisticsQueue, shouldIncludeLocalhost, resourceLoadStatisticsDirectory, sessionID);
</span><span class="cx">
</span><del>- auto memoryStore = makeUnique<ResourceLoadStatisticsMemoryStore>(*this, m_statisticsQueue, shouldIncludeLocalhost);
- downcast<ResourceLoadStatisticsDatabaseStore>(*m_statisticsStore.get()).populateFromMemoryStore(*memoryStore);
-
</del><span class="cx"> auto legacyPlistFilePath = FileSystem::pathByAppendingComponent(resourceLoadStatisticsDirectory, "full_browsing_session_resourceLog.plist");
</span><span class="cx"> if (FileSystem::fileExists(legacyPlistFilePath))
</span><span class="cx"> FileSystem::deleteFile(legacyPlistFilePath);
</span></span></pre></div>
<a id="trunkSourceWebKitSourcestxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/Sources.txt (282710 => 282711)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/Sources.txt 2021-09-17 23:45:48 UTC (rev 282710)
+++ trunk/Source/WebKit/Sources.txt 2021-09-17 23:46:14 UTC (rev 282711)
</span><span class="lines">@@ -83,7 +83,6 @@
</span><span class="cx"> NetworkProcess/PreconnectTask.cpp
</span><span class="cx">
</span><span class="cx"> NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.cpp
</span><del>-NetworkProcess/Classifier/ResourceLoadStatisticsMemoryStore.cpp
</del><span class="cx"> NetworkProcess/Classifier/ResourceLoadStatisticsStore.cpp
</span><span class="cx">
</span><span class="cx"> NetworkProcess/Cookies/WebCookieManager.cpp
</span></span></pre></div>
<a id="trunkSourceWebKitWebKitxcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj (282710 => 282711)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj 2021-09-17 23:45:48 UTC (rev 282710)
+++ trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj 2021-09-17 23:46:14 UTC (rev 282711)
</span><span class="lines">@@ -1348,7 +1348,6 @@
</span><span class="cx"> 7AB6EA471EEAB6B800037B2B /* APIGeolocationProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = 7AB6EA461EEAB6B000037B2B /* APIGeolocationProvider.h */; };
</span><span class="cx"> 7AF236211E79A40800438A05 /* WebErrors.h in Headers */ = {isa = PBXBuildFile; fileRef = 7AF2361F1E79A3D800438A05 /* WebErrors.h */; };
</span><span class="cx"> 7AFBD36321E50F39005DBACB /* WebResourceLoadStatisticsStore.h in Headers */ = {isa = PBXBuildFile; fileRef = 7AFBD36221E50F39005DBACB /* WebResourceLoadStatisticsStore.h */; };
</span><del>- 7AFBD36721E51BAB005DBACB /* ResourceLoadStatisticsMemoryStore.h in Headers */ = {isa = PBXBuildFile; fileRef = 7AFBD36521E51BAB005DBACB /* ResourceLoadStatisticsMemoryStore.h */; };
</del><span class="cx"> 7AFBD36F21E546F8005DBACB /* PersistencyUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 7AFBD36D21E546E3005DBACB /* PersistencyUtils.h */; };
</span><span class="cx"> 7B1DB26625668CE1000E26BC /* ArrayReference.h in Headers */ = {isa = PBXBuildFile; fileRef = 7B1DB26525668CE0000E26BC /* ArrayReference.h */; };
</span><span class="cx"> 7B483F1F25CDDA9C00120486 /* MessageReceiveQueueMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 7B483F1B25CDDA9B00120486 /* MessageReceiveQueueMap.h */; };
</span><span class="lines">@@ -4694,8 +4693,6 @@
</span><span class="cx"> 7AF2361F1E79A3D800438A05 /* WebErrors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebErrors.h; sourceTree = "<group>"; };
</span><span class="cx"> 7AF236221E79A43100438A05 /* WebErrorsCocoa.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebErrorsCocoa.mm; sourceTree = "<group>"; };
</span><span class="cx"> 7AFBD36221E50F39005DBACB /* WebResourceLoadStatisticsStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WebResourceLoadStatisticsStore.h; path = Classifier/WebResourceLoadStatisticsStore.h; sourceTree = "<group>"; };
</span><del>- 7AFBD36421E51BAB005DBACB /* ResourceLoadStatisticsMemoryStore.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ResourceLoadStatisticsMemoryStore.cpp; path = Classifier/ResourceLoadStatisticsMemoryStore.cpp; sourceTree = "<group>"; };
- 7AFBD36521E51BAB005DBACB /* ResourceLoadStatisticsMemoryStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ResourceLoadStatisticsMemoryStore.h; path = Classifier/ResourceLoadStatisticsMemoryStore.h; sourceTree = "<group>"; };
</del><span class="cx"> 7AFBD36D21E546E3005DBACB /* PersistencyUtils.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PersistencyUtils.h; sourceTree = "<group>"; };
</span><span class="cx"> 7AFBD36E21E546E3005DBACB /* PersistencyUtils.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = PersistencyUtils.cpp; sourceTree = "<group>"; };
</span><span class="cx"> 7B1DB26525668CE0000E26BC /* ArrayReference.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArrayReference.h; sourceTree = "<group>"; };
</span><span class="lines">@@ -9482,8 +9479,6 @@
</span><span class="cx"> children = (
</span><span class="cx"> 7A0D7862220791ED00EBCF54 /* ResourceLoadStatisticsDatabaseStore.cpp */,
</span><span class="cx"> 7A0D7861220791EC00EBCF54 /* ResourceLoadStatisticsDatabaseStore.h */,
</span><del>- 7AFBD36421E51BAB005DBACB /* ResourceLoadStatisticsMemoryStore.cpp */,
- 7AFBD36521E51BAB005DBACB /* ResourceLoadStatisticsMemoryStore.h */,
</del><span class="cx"> 7ACE82E8221CAE07000DA94C /* ResourceLoadStatisticsStore.cpp */,
</span><span class="cx"> 7ACE82E7221CAE06000DA94C /* ResourceLoadStatisticsStore.h */,
</span><span class="cx"> 7A41E9FA21F81DAC00B88CDB /* ShouldGrandfatherStatistics.h */,
</span><span class="lines">@@ -12507,7 +12502,6 @@
</span><span class="cx"> 5CB7AFE723C6820700E49CF3 /* ResourceLoadInfo.h in Headers */,
</span><span class="cx"> 6BE969CD1E54E054008B7483 /* ResourceLoadStatisticsClassifier.h in Headers */,
</span><span class="cx"> 6BE969CB1E54D4CF008B7483 /* ResourceLoadStatisticsClassifierCocoa.h in Headers */,
</span><del>- 7AFBD36721E51BAB005DBACB /* ResourceLoadStatisticsMemoryStore.h in Headers */,
</del><span class="cx"> 1A30066E1110F4F70031937C /* ResponsivenessTimer.h in Headers */,
</span><span class="cx"> 410482CE1DDD324F00F006D0 /* RTCNetwork.h in Headers */,
</span><span class="cx"> 46F38E8C2416E6730059375A /* RunningBoardServicesSPI.h in Headers */,
</span></span></pre></div>
<a id="trunkToolsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Tools/ChangeLog (282710 => 282711)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/ChangeLog 2021-09-17 23:45:48 UTC (rev 282710)
+++ trunk/Tools/ChangeLog 2021-09-17 23:46:14 UTC (rev 282711)
</span><span class="lines">@@ -1,3 +1,17 @@
</span><ins>+2021-09-17 Kate Cheney <katherine_cheney@apple.com>
+
+ Remove unnecessary ITP memory store code
+ https://bugs.webkit.org/show_bug.cgi?id=229512
+ <rdar://problem/82644309>
+
+ Reviewed by John Wilander.
+
+ * TestWebKitAPI/Tests/WebKitCocoa/ResourceLoadStatistics.mm:
+ (TEST):
+ Deleted an extra memory store test leftover from when we still had
+ a functioning memory store. Now it is just a duplicate of the database
+ test, so we can remove it.
+
</ins><span class="cx"> 2021-09-17 Alex Christensen <achristensen@webkit.org>
</span><span class="cx">
</span><span class="cx"> REGRESSION: [ iOS ] 5 TestWebKitAPI.WebpagePreferences.* api tests are flaky timing out
</span></span></pre></div>
<a id="trunkToolsTestWebKitAPITestsWebKitCocoaResourceLoadStatisticsmm"></a>
<div class="modfile"><h4>Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ResourceLoadStatistics.mm (282710 => 282711)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ResourceLoadStatistics.mm 2021-09-17 23:45:48 UTC (rev 282710)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ResourceLoadStatistics.mm 2021-09-17 23:46:14 UTC (rev 282711)
</span><span class="lines">@@ -80,7 +80,7 @@
</span><span class="cx"> [dataStore _setResourceLoadStatisticsEnabled:NO];
</span><span class="cx"> }
</span><span class="cx">
</span><del>-TEST(ResourceLoadStatistics, GrandfatherCallbackDatabase)
</del><ins>+TEST(ResourceLoadStatistics, GrandfatherCallback)
</ins><span class="cx"> {
</span><span class="cx"> auto *dataStore = [WKWebsiteDataStore defaultDataStore];
</span><span class="cx">
</span><span class="lines">@@ -136,7 +136,7 @@
</span><span class="cx"> TestWebKitAPI::Util::run(&doneFlag);
</span><span class="cx"> }
</span><span class="cx">
</span><del>-TEST(ResourceLoadStatistics, ShouldNotGrandfatherOnStartupDatabase)
</del><ins>+TEST(ResourceLoadStatistics, ShouldNotGrandfatherOnStartup)
</ins><span class="cx"> {
</span><span class="cx"> auto *dataStore = [WKWebsiteDataStore defaultDataStore];
</span><span class="cx">
</span><span class="lines">@@ -157,7 +157,7 @@
</span><span class="cx"> TestWebKitAPI::Util::run(&callbackFlag);
</span><span class="cx"> }
</span><span class="cx">
</span><del>-TEST(ResourceLoadStatistics, ChildProcessesNotLaunchedDatabase)
</del><ins>+TEST(ResourceLoadStatistics, ChildProcessesNotLaunched)
</ins><span class="cx"> {
</span><span class="cx"> // Ensure the shared process pool exists so the data store operations we're about to do work with it.
</span><span class="cx"> WKProcessPool *sharedProcessPool = [WKProcessPool _sharedProcessPool];
</span><span class="lines">@@ -679,20 +679,6 @@
</span><span class="cx"> [dataStore _setResourceLoadStatisticsEnabled:YES];
</span><span class="cx">
</span><span class="cx"> __block bool doneFlag = false;
</span><del>- [dataStore _clearResourceLoadStatistics:^(void) {
- doneFlag = true;
- }];
-
- static bool statisticsUpdated = false;
- [dataStore _setResourceLoadStatisticsTestingCallback:^(WKWebsiteDataStore *, NSString *message) {
- if (![message isEqualToString:@"Statistics Updated"])
- return;
- statisticsUpdated = true;
- }];
-
- TestWebKitAPI::Util::run(&doneFlag);
-
- doneFlag = false;
</del><span class="cx"> [dataStore _setThirdPartyCookieBlockingMode:true onlyOnSitesWithoutUserInteraction:false completionHandler: ^(void) {
</span><span class="cx"> doneFlag = true;
</span><span class="cx"> }];
</span><span class="lines">@@ -699,196 +685,7 @@
</span><span class="cx">
</span><span class="cx"> TestWebKitAPI::Util::run(&doneFlag);
</span><span class="cx">
</span><del>- // Set two third parties to be prevalent, leave evil1.com as non-prevalent to ensure
- // this call returns all third parties.
</del><span class="cx"> doneFlag = false;
</span><del>- [dataStore _setPrevalentDomain:[NSURL URLWithString:@"http://evil2.com"] completionHandler: ^(void) {
- doneFlag = true;
- }];
- doneFlag = false;
- [dataStore _setPrevalentDomain:[NSURL URLWithString:@"http://evil3.com"] completionHandler: ^(void) {
- doneFlag = true;
- }];
-
- // Seed test data in the web process' observer.
-
- // evil1
- doneFlag = false;
- [sharedProcessPool _seedResourceLoadStatisticsForTestingWithFirstParty:[NSURL URLWithString:@"http://webkit.org"] thirdParty:[NSURL URLWithString:@"http://evil1.com"] shouldScheduleNotification:NO completionHandler: ^() {
- doneFlag = true;
- }];
- TestWebKitAPI::Util::run(&doneFlag);
-
- doneFlag = false;
- [sharedProcessPool _seedResourceLoadStatisticsForTestingWithFirstParty:[NSURL URLWithString:@"http://webkit2.org"] thirdParty:[NSURL URLWithString:@"http://evil1.com"] shouldScheduleNotification:NO completionHandler: ^() {
- doneFlag = true;
- }];
- TestWebKitAPI::Util::run(&doneFlag);
-
-
- // evil2
- doneFlag = false;
- [sharedProcessPool _seedResourceLoadStatisticsForTestingWithFirstParty:[NSURL URLWithString:@"http://webkit.org"] thirdParty:[NSURL URLWithString:@"http://evil2.com"] shouldScheduleNotification:NO completionHandler: ^() {
- doneFlag = true;
- }];
- TestWebKitAPI::Util::run(&doneFlag);
-
-
- // evil3
- doneFlag = false;
- [sharedProcessPool _seedResourceLoadStatisticsForTestingWithFirstParty:[NSURL URLWithString:@"http://webkit.org"] thirdParty:[NSURL URLWithString:@"http://evil3.com"] shouldScheduleNotification:NO completionHandler: ^() {
- doneFlag = true;
- }];
- TestWebKitAPI::Util::run(&doneFlag);
- doneFlag = false;
- [sharedProcessPool _seedResourceLoadStatisticsForTestingWithFirstParty:[NSURL URLWithString:@"http://webkit2.org"] thirdParty:[NSURL URLWithString:@"http://evil3.com"] shouldScheduleNotification:NO completionHandler: ^() {
- doneFlag = true;
- }];
- TestWebKitAPI::Util::run(&doneFlag);
- doneFlag = false;
- [sharedProcessPool _seedResourceLoadStatisticsForTestingWithFirstParty:[NSURL URLWithString:@"http://webkit3.org"] thirdParty:[NSURL URLWithString:@"http://evil3.com"] shouldScheduleNotification:NO completionHandler: ^() {
- doneFlag = true;
- }];
- TestWebKitAPI::Util::run(&doneFlag);
-
- statisticsUpdated = false;
- [webView1 loadHTMLString:@"<body><script>close();</script></body>" baseURL:[NSURL URLWithString:@"http://webkit.org"]];
- [webView2 loadHTMLString:@"<body><script>close();</script></body>" baseURL:[NSURL URLWithString:@"http://webkit2.org"]];
- [webView3 loadHTMLString:@"<body><script>close();</script></body>" baseURL:[NSURL URLWithString:@"http://webkit3.org"]];
-
- // Wait for the statistics to be updated in the network process.
- TestWebKitAPI::Util::run(&statisticsUpdated);
-
- // Check that the third-party evil1 is now registered as subresource.
- doneFlag = false;
- [dataStore _isRegisteredAsSubresourceUnderFirstParty:[NSURL URLWithString:@"http://webkit.org"] thirdParty:[NSURL URLWithString:@"http://evil1.com"] completionHandler: ^(BOOL isRegistered) {
- EXPECT_TRUE(isRegistered);
- doneFlag = true;
- }];
- TestWebKitAPI::Util::run(&doneFlag);
- doneFlag = false;
- [dataStore _isRegisteredAsSubresourceUnderFirstParty:[NSURL URLWithString:@"http://webkit2.org"] thirdParty:[NSURL URLWithString:@"http://evil1.com"] completionHandler: ^(BOOL isRegistered) {
- EXPECT_TRUE(isRegistered);
- doneFlag = true;
- }];
- TestWebKitAPI::Util::run(&doneFlag);
-
-
- // Check that the third-party evil2 is now registered as subresource.
- doneFlag = false;
- [dataStore _isRegisteredAsSubresourceUnderFirstParty:[NSURL URLWithString:@"http://webkit.org"] thirdParty:[NSURL URLWithString:@"http://evil2.com"] completionHandler: ^(BOOL isRegistered) {
- EXPECT_TRUE(isRegistered);
- doneFlag = true;
- }];
- TestWebKitAPI::Util::run(&doneFlag);
-
-
- // Check that the third-party evil3 is now registered as subresource.
- doneFlag = false;
- [dataStore _isRegisteredAsSubresourceUnderFirstParty:[NSURL URLWithString:@"http://webkit.org"] thirdParty:[NSURL URLWithString:@"http://evil3.com"] completionHandler: ^(BOOL isRegistered) {
- EXPECT_TRUE(isRegistered);
- doneFlag = true;
- }];
- TestWebKitAPI::Util::run(&doneFlag);
- doneFlag = false;
- [dataStore _isRegisteredAsSubresourceUnderFirstParty:[NSURL URLWithString:@"http://webkit2.org"] thirdParty:[NSURL URLWithString:@"http://evil3.com"] completionHandler: ^(BOOL isRegistered) {
- EXPECT_TRUE(isRegistered);
- doneFlag = true;
- }];
- TestWebKitAPI::Util::run(&doneFlag);
- doneFlag = false;
- [dataStore _isRegisteredAsSubresourceUnderFirstParty:[NSURL URLWithString:@"http://webkit3.org"] thirdParty:[NSURL URLWithString:@"http://evil3.com"] completionHandler: ^(BOOL isRegistered) {
- EXPECT_TRUE(isRegistered);
- doneFlag = true;
- }];
- TestWebKitAPI::Util::run(&doneFlag);
-
-
- // Collect the ITP data summary which should include all third parties in the
- // order: [evil3.com, evil1.com, evil2.com] sorted by number of first parties
- // it appears under or redirects to
- doneFlag = false;
- [dataStore _getResourceLoadStatisticsDataSummary:^void(NSArray<_WKResourceLoadStatisticsThirdParty *> *thirdPartyData)
- {
- EXPECT_EQ(static_cast<int>([thirdPartyData count]), 3);
- NSEnumerator *thirdPartyDomains = [thirdPartyData objectEnumerator];
-
- // evil3
- _WKResourceLoadStatisticsThirdParty *evil3ThirdParty = [thirdPartyDomains nextObject];
- EXPECT_WK_STREQ(evil3ThirdParty.thirdPartyDomain, @"evil3.com");
-
- NSEnumerator *evil3Enumerator = [evil3ThirdParty.underFirstParties objectEnumerator];
- _WKResourceLoadStatisticsFirstParty *evil3FirstParty1 = [evil3Enumerator nextObject];
- _WKResourceLoadStatisticsFirstParty *evil3FirstParty2 = [evil3Enumerator nextObject];
- _WKResourceLoadStatisticsFirstParty *evil3FirstParty3 = [evil3Enumerator nextObject];
-
- EXPECT_WK_STREQ(evil3FirstParty1.firstPartyDomain, @"webkit2.org");
- EXPECT_WK_STREQ(evil3FirstParty2.firstPartyDomain, @"webkit3.org");
- EXPECT_WK_STREQ(evil3FirstParty3.firstPartyDomain, @"webkit.org");
-
- EXPECT_FALSE(evil3FirstParty1.thirdPartyStorageAccessGranted);
- EXPECT_FALSE(evil3FirstParty2.thirdPartyStorageAccessGranted);
- EXPECT_FALSE(evil3FirstParty3.thirdPartyStorageAccessGranted);
-
- // evil1
- _WKResourceLoadStatisticsThirdParty *evil1ThirdParty = [thirdPartyDomains nextObject];
- EXPECT_WK_STREQ(evil1ThirdParty.thirdPartyDomain, @"evil1.com");
-
- NSEnumerator *evil1Enumerator = [evil1ThirdParty.underFirstParties objectEnumerator];
- _WKResourceLoadStatisticsFirstParty *evil1FirstParty1= [evil1Enumerator nextObject];
- _WKResourceLoadStatisticsFirstParty *evil1FirstParty2 = [evil1Enumerator nextObject];
-
- EXPECT_WK_STREQ(evil1FirstParty1.firstPartyDomain, @"webkit2.org");
- EXPECT_WK_STREQ(evil1FirstParty2.firstPartyDomain, @"webkit.org");
-
- EXPECT_FALSE(evil1FirstParty1.thirdPartyStorageAccessGranted);
- EXPECT_FALSE(evil1FirstParty2.thirdPartyStorageAccessGranted);
-
- // evil2
- _WKResourceLoadStatisticsThirdParty *evil2ThirdParty = [thirdPartyDomains nextObject];
- EXPECT_WK_STREQ(evil2ThirdParty.thirdPartyDomain, @"evil2.com");
-
- NSEnumerator *evil2Enumerator = [evil2ThirdParty.underFirstParties objectEnumerator];
- _WKResourceLoadStatisticsFirstParty *evil2FirstParty1 = [evil2Enumerator nextObject];
-
- EXPECT_WK_STREQ(evil2FirstParty1.firstPartyDomain, @"webkit.org");
- EXPECT_FALSE(evil2FirstParty1.thirdPartyStorageAccessGranted);
- doneFlag = true;
- }];
-
- TestWebKitAPI::Util::run(&doneFlag);
-}
-
-TEST(ResourceLoadStatistics, GetResourceLoadStatisticsDataSummaryDatabase)
-{
- auto *sharedProcessPool = [WKProcessPool _sharedProcessPool];
- auto *dataStore = [WKWebsiteDataStore defaultDataStore];
-
- auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
- [configuration setProcessPool: sharedProcessPool];
- configuration.get().websiteDataStore = dataStore;
-
- auto webView1 = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
- auto webView2 = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
- auto webView3 = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
-
- [webView1 loadHTMLString:@"WebKit Test" baseURL:[NSURL URLWithString:@"http://webkit.org"]];
- [webView1 _test_waitForDidFinishNavigation];
- [webView2 loadHTMLString:@"WebKit Test" baseURL:[NSURL URLWithString:@"http://webkit2.org"]];
- [webView2 _test_waitForDidFinishNavigation];
- [webView3 loadHTMLString:@"WebKit Test" baseURL:[NSURL URLWithString:@"http://webkit3.org"]];
- [webView3 _test_waitForDidFinishNavigation];
-
- [dataStore _setResourceLoadStatisticsEnabled:YES];
-
- __block bool doneFlag = false;
- [dataStore _setThirdPartyCookieBlockingMode:true onlyOnSitesWithoutUserInteraction:false completionHandler: ^(void) {
- doneFlag = true;
- }];
-
- TestWebKitAPI::Util::run(&doneFlag);
-
- doneFlag = false;
</del><span class="cx"> [dataStore _clearResourceLoadStatistics:^(void) {
</span><span class="cx"> doneFlag = true;
</span><span class="cx"> }];
</span></span></pre>
</div>
</div>
</body>
</html>