Diff
Modified: trunk/Source/WebKit/ChangeLog (272659 => 272660)
--- trunk/Source/WebKit/ChangeLog 2021-02-10 17:07:58 UTC (rev 272659)
+++ trunk/Source/WebKit/ChangeLog 2021-02-10 17:38:10 UTC (rev 272660)
@@ -1,3 +1,66 @@
+2021-02-10 Kate Cheney <katherine_che...@apple.com>
+
+ PCM: Expired reports get sent at the same time after a session restart
+ https://bugs.webkit.org/show_bug.cgi?id=221555
+ <rdar://problem/73724816>
+
+ Reviewed by John Wilander.
+
+ Since PCM data is now persisted, we need to address the case of a
+ session-restart after 24-48+ hours. We should not send all overdue
+ attributions in the same burst in case multiple have the same destination
+ and could identify a user cross-site.
+
+ This patch kicks off the timer to fire pending attributions on session-start
+ and sends one report at a time. If more than one overdue report exists
+ at any time, we schedule the timer for a random interval between 15 and
+ 30 minutes.
+
+ In theory this could result in some attributions never being sent if a
+ user keeps quitting and restarting a session. In practice this is
+ probably unlikely. Protecting the user's privacy is a hard requirement,
+ so we think possible starvation of some reports is the right tradeoff.
+
+ * NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.cpp:
+ (WebKit::ResourceLoadStatisticsDatabaseStore::clearSentAttribution):
+ (WebKit::ResourceLoadStatisticsDatabaseStore::clearSentAttributions): Deleted.
+ * NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.h:
+ * NetworkProcess/Classifier/ResourceLoadStatisticsMemoryStore.h:
+ * NetworkProcess/Classifier/ResourceLoadStatisticsStore.h:
+ * NetworkProcess/Classifier/WebResourceLoadStatisticsStore.cpp:
+ (WebKit::WebResourceLoadStatisticsStore::clearSentAttribution):
+ (WebKit::WebResourceLoadStatisticsStore::clearSentAttributions): Deleted.
+ * NetworkProcess/Classifier/WebResourceLoadStatisticsStore.h:
+ Remove unused SQLite query. Update the query to sort attributed PCM
+ by earliestTimeToSend, which seems important now that we send only
+ one overdue report at a time. Change the clearSentAttributions
+ function to take only a single attribution.
+
+ * NetworkProcess/NetworkSession.cpp:
+ (WebKit::NetworkSession::NetworkSession):
+ Convert m_privateClickMeasurement to a unique_ptr so we can wait to
+ create it after WebResourceLoadStatisticsStore is created. This ensures
+ that the call to create the SQLite database will run on a
+ background thread before we try to collect overdue PCM attributions.
+
+ (WebKit::NetworkSession::storePrivateClickMeasurement):
+ (WebKit::NetworkSession::handlePrivateClickMeasurementConversion):
+ (WebKit::NetworkSession::dumpPrivateClickMeasurement):
+ (WebKit::NetworkSession::clearPrivateClickMeasurement):
+ (WebKit::NetworkSession::clearPrivateClickMeasurementForRegistrableDomain):
+ (WebKit::NetworkSession::setPrivateClickMeasurementOverrideTimerForTesting):
+ (WebKit::NetworkSession::markAttributedPrivateClickMeasurementsAsExpiredForTesting):
+ (WebKit::NetworkSession::setPrivateClickMeasurementConversionURLForTesting):
+ (WebKit::NetworkSession::markPrivateClickMeasurementsAsExpiredForTesting):
+ (WebKit::NetworkSession::firePrivateClickMeasurementTimerImmediately):
+ * NetworkProcess/NetworkSession.h:
+ * NetworkProcess/PrivateClickMeasurementManager.cpp:
+ (WebKit::PrivateClickMeasurementManager::PrivateClickMeasurementManager):
+ (WebKit::PrivateClickMeasurementManager::firePendingAttributionRequest):
+ (WebKit::PrivateClickMeasurementManager::attribute):
+ Drive-by fixes to add protectedThis and check if PrivateClickMeasurementManager
+ is still alive when this lambda is called.
+
2021-02-10 Wenson Hsieh <wenson_hs...@apple.com>
[watchOS] Adopt PUICQuickboardController for text input
Modified: trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.cpp (272659 => 272660)
--- trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.cpp 2021-02-10 17:07:58 UTC (rev 272659)
+++ trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.cpp 2021-02-10 17:38:10 UTC (rev 272660)
@@ -116,10 +116,6 @@
constexpr auto updateGrandfatheredQuery = "UPDATE ObservedDomains SET grandfathered = ? WHERE registrableDomain = ?"_s;
constexpr auto updateIsScheduledForAllButCookieDataRemovalQuery = "UPDATE ObservedDomains SET isScheduledForAllButCookieDataRemoval = ? WHERE registrableDomain = ?"_s;
constexpr auto setUnattributedPrivateClickMeasurementAsExpiredQuery = "UPDATE UnattributedPrivateClickMeasurement SET timeOfAdClick = -1.0"_s;
-constexpr auto updateAttributionsEarliestTimeToSendQuery = "UPDATE AttributedPrivateClickMeasurement as c SET "
- "earliestTimeToSend = (SELECT MAX(0.0, newTime) FROM (SELECT (earliestTimeToSend - ?) as newTime FROM "
- "AttributedPrivateClickMeasurement as d WHERE c.sourceSiteDomainID = d.sourceSiteDomainID AND c.attributeOnSiteDomainID = "
- "d.attributeOnSiteDomainID))"_s;
// SELECT Queries
constexpr auto domainIDFromStringQuery = "SELECT domainID FROM ObservedDomains WHERE registrableDomain = ?"_s;
@@ -139,7 +135,7 @@
"UNION ALL SELECT topFrameDomainID FROM SubresourceUnderTopFrameDomains WHERE subresourceDomainID = ?"
"UNION ALL SELECT toDomainID FROM SubresourceUniqueRedirectsTo WHERE subresourceDomainID = ?"_s;
constexpr auto allUnattributedPrivateClickMeasurementAttributionsQuery = "SELECT * FROM UnattributedPrivateClickMeasurement"_s;
-constexpr auto allAttributedPrivateClickMeasurementQuery = "SELECT * FROM AttributedPrivateClickMeasurement"_s;
+constexpr auto allAttributedPrivateClickMeasurementQuery = "SELECT * FROM AttributedPrivateClickMeasurement ORDER BY earliestTimeToSend"_s;
constexpr auto findUnattributedQuery = "SELECT * FROM UnattributedPrivateClickMeasurement WHERE sourceSiteDomainID = ? AND attributeOnSiteDomainID = ?"_s;
constexpr auto findAttributedQuery = "SELECT * FROM AttributedPrivateClickMeasurement WHERE sourceSiteDomainID = ? AND attributeOnSiteDomainID = ?"_s;
@@ -3237,24 +3233,21 @@
return builder.toString();
}
-void ResourceLoadStatisticsDatabaseStore::clearSentAttributions(Vector<WebCore::PrivateClickMeasurement>&& attributions)
+void ResourceLoadStatisticsDatabaseStore::clearSentAttribution(WebCore::PrivateClickMeasurement&& attribution)
{
- for (auto& attribution : attributions) {
- auto sourceSiteDomainID = domainID(attribution.sourceSite().registrableDomain);
- auto attributeOnSiteDomainID = domainID(attribution.attributeOnSite().registrableDomain);
+ auto sourceSiteDomainID = domainID(attribution.sourceSite().registrableDomain);
+ auto attributeOnSiteDomainID = domainID(attribution.attributeOnSite().registrableDomain);
- if (!sourceSiteDomainID || !attributeOnSiteDomainID)
- return;
+ if (!sourceSiteDomainID || !attributeOnSiteDomainID)
+ return;
- SQLiteStatement clearAttributedStatement(m_database, "DELETE FROM AttributedPrivateClickMeasurement WHERE sourceSiteDomainID = ? AND attributeOnSiteDomainID = ?"_s);
- if (clearAttributedStatement.prepare() != SQLITE_OK
- || clearAttributedStatement.bindInt(1, *sourceSiteDomainID) != SQLITE_OK
- || clearAttributedStatement.bindInt(2, *attributeOnSiteDomainID) != SQLITE_OK
- || clearAttributedStatement.step() != SQLITE_DONE) {
- RELEASE_LOG_ERROR_IF_ALLOWED(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::clearSentAttributions failed to step, error message: %{private}s", this, m_database.lastErrorMsg());
- ASSERT_NOT_REACHED();
- }
- clearAttributedStatement.reset();
+ SQLiteStatement clearAttributedStatement(m_database, "DELETE FROM AttributedPrivateClickMeasurement WHERE sourceSiteDomainID = ? AND attributeOnSiteDomainID = ?"_s);
+ if (clearAttributedStatement.prepare() != SQLITE_OK
+ || clearAttributedStatement.bindInt(1, *sourceSiteDomainID) != SQLITE_OK
+ || clearAttributedStatement.bindInt(2, *attributeOnSiteDomainID) != SQLITE_OK
+ || clearAttributedStatement.step() != SQLITE_DONE) {
+ RELEASE_LOG_ERROR_IF_ALLOWED(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::clearSentAttribution failed to step, error message: %{private}s", this, m_database.lastErrorMsg());
+ ASSERT_NOT_REACHED();
}
}
Modified: trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.h (272659 => 272660)
--- trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.h 2021-02-10 17:07:58 UTC (rev 272659)
+++ trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.h 2021-02-10 17:38:10 UTC (rev 272660)
@@ -139,7 +139,7 @@
void clearPrivateClickMeasurement(Optional<RegistrableDomain>) override;
void clearExpiredPrivateClickMeasurement() override;
String privateClickMeasurementToString() override;
- void clearSentAttributions(Vector<WebCore::PrivateClickMeasurement>&&) override;
+ void clearSentAttribution(WebCore::PrivateClickMeasurement&&) override;
void markAttributedPrivateClickMeasurementsAsExpiredForTesting() override;
private:
Modified: trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsMemoryStore.h (272659 => 272660)
--- trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsMemoryStore.h 2021-02-10 17:07:58 UTC (rev 272659)
+++ trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsMemoryStore.h 2021-02-10 17:38:10 UTC (rev 272660)
@@ -116,7 +116,7 @@
void clearPrivateClickMeasurement(Optional<RegistrableDomain>) override { };
void clearExpiredPrivateClickMeasurement() override { };
String privateClickMeasurementToString() override { return String(); };
- void clearSentAttributions(Vector<WebCore::PrivateClickMeasurement>&&) override { };
+ void clearSentAttribution(WebCore::PrivateClickMeasurement&&) override { };
void markAttributedPrivateClickMeasurementsAsExpiredForTesting() override { };
private:
Modified: trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsStore.h (272659 => 272660)
--- trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsStore.h 2021-02-10 17:07:58 UTC (rev 272659)
+++ trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsStore.h 2021-02-10 17:38:10 UTC (rev 272660)
@@ -211,7 +211,7 @@
virtual void clearPrivateClickMeasurement(Optional<RegistrableDomain>) = 0;
virtual void clearExpiredPrivateClickMeasurement() = 0;
virtual String privateClickMeasurementToString() = 0;
- virtual void clearSentAttributions(Vector<WebCore::PrivateClickMeasurement>&&) = 0;
+ virtual void clearSentAttribution(WebCore::PrivateClickMeasurement&&) = 0;
virtual void markAttributedPrivateClickMeasurementsAsExpiredForTesting() = 0;
protected:
Modified: trunk/Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsStore.cpp (272659 => 272660)
--- trunk/Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsStore.cpp 2021-02-10 17:07:58 UTC (rev 272659)
+++ trunk/Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsStore.cpp 2021-02-10 17:38:10 UTC (rev 272660)
@@ -1622,7 +1622,7 @@
});
}
-void WebResourceLoadStatisticsStore::clearSentAttributions(Vector<WebCore::PrivateClickMeasurement>&& attributionsToClear)
+void WebResourceLoadStatisticsStore::clearSentAttribution(WebCore::PrivateClickMeasurement&& attributionToClear)
{
ASSERT(RunLoop::isMain());
@@ -1629,11 +1629,11 @@
if (isEphemeral())
return;
- postTask([this, attributionsToClear = WTFMove(attributionsToClear)]() mutable {
+ postTask([this, attributionToClear = WTFMove(attributionToClear)]() mutable {
if (!m_statisticsStore)
return;
- m_statisticsStore->clearSentAttributions(WTFMove(attributionsToClear));
+ m_statisticsStore->clearSentAttribution(WTFMove(attributionToClear));
});
}
Modified: trunk/Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsStore.h (272659 => 272660)
--- trunk/Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsStore.h 2021-02-10 17:07:58 UTC (rev 272659)
+++ trunk/Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsStore.h 2021-02-10 17:38:10 UTC (rev 272660)
@@ -315,7 +315,7 @@
void clearPrivateClickMeasurementForRegistrableDomain(const WebCore::RegistrableDomain&);
void clearExpiredPrivateClickMeasurement();
void privateClickMeasurementToString(CompletionHandler<void(String)>&&);
- void clearSentAttributions(Vector<WebCore::PrivateClickMeasurement>&&);
+ void clearSentAttribution(WebCore::PrivateClickMeasurement&&);
void markAttributedPrivateClickMeasurementsAsExpiredForTesting(CompletionHandler<void()>&&);
private:
Modified: trunk/Source/WebKit/NetworkProcess/NetworkSession.cpp (272659 => 272660)
--- trunk/Source/WebKit/NetworkProcess/NetworkSession.cpp 2021-02-10 17:07:58 UTC (rev 272659)
+++ trunk/Source/WebKit/NetworkProcess/NetworkSession.cpp 2021-02-10 17:38:10 UTC (rev 272660)
@@ -91,7 +91,6 @@
, m_firstPartyWebsiteDataRemovalMode(parameters.resourceLoadStatisticsParameters.firstPartyWebsiteDataRemovalMode)
, m_standaloneApplicationDomain(parameters.resourceLoadStatisticsParameters.standaloneApplicationDomain)
#endif
- , m_privateClickMeasurement(makeUniqueRef<PrivateClickMeasurementManager>(*this, networkProcess, parameters.sessionID))
, m_testSpeedMultiplier(parameters.testSpeedMultiplier)
, m_allowsServerPreconnect(parameters.allowsServerPreconnect)
{
@@ -120,6 +119,9 @@
m_isStaleWhileRevalidateEnabled = parameters.staleWhileRevalidateEnabled;
+#if ENABLE(RESOURCE_LOAD_STATISTICS)
+ setResourceLoadStatisticsEnabled(parameters.resourceLoadStatisticsParameters.enabled);
+ m_privateClickMeasurement = makeUnique<PrivateClickMeasurementManager>(*this, networkProcess, parameters.sessionID);
m_privateClickMeasurement->setPingLoadFunction([this, weakThis = makeWeakPtr(this)](NetworkResourceLoadParameters&& loadParameters, CompletionHandler<void(const WebCore::ResourceError&, const WebCore::ResourceResponse&)>&& completionHandler) {
if (!weakThis)
return;
@@ -126,9 +128,6 @@
// PingLoad manages its own lifetime, deleting itself when its purpose has been fulfilled.
new PingLoad(m_networkProcess, m_sessionID, WTFMove(loadParameters), WTFMove(completionHandler));
});
-
-#if ENABLE(RESOURCE_LOAD_STATISTICS)
- setResourceLoadStatisticsEnabled(parameters.resourceLoadStatisticsParameters.enabled);
#endif
}
@@ -304,54 +303,54 @@
}
#endif // ENABLE(RESOURCE_LOAD_STATISTICS)
-void NetworkSession::storePrivateClickMeasurement(WebCore::PrivateClickMeasurement&& privateClickMeasurement)
+void NetworkSession::storePrivateClickMeasurement(WebCore::PrivateClickMeasurement&& unattributedPrivateClickMeasurement)
{
- m_privateClickMeasurement->storeUnattributed(WTFMove(privateClickMeasurement));
+ privateClickMeasurement().storeUnattributed(WTFMove(unattributedPrivateClickMeasurement));
}
void NetworkSession::handlePrivateClickMeasurementConversion(PrivateClickMeasurement::AttributionTriggerData&& attributionTriggerData, const URL& requestURL, const WebCore::ResourceRequest& redirectRequest)
{
- m_privateClickMeasurement->handleAttribution(WTFMove(attributionTriggerData), requestURL, redirectRequest);
+ privateClickMeasurement().handleAttribution(WTFMove(attributionTriggerData), requestURL, redirectRequest);
}
void NetworkSession::dumpPrivateClickMeasurement(CompletionHandler<void(String)>&& completionHandler)
{
- m_privateClickMeasurement->toString(WTFMove(completionHandler));
+ privateClickMeasurement().toString(WTFMove(completionHandler));
}
void NetworkSession::clearPrivateClickMeasurement()
{
- m_privateClickMeasurement->clear();
+ privateClickMeasurement().clear();
}
void NetworkSession::clearPrivateClickMeasurementForRegistrableDomain(WebCore::RegistrableDomain&& domain)
{
- m_privateClickMeasurement->clearForRegistrableDomain(WTFMove(domain));
+ privateClickMeasurement().clearForRegistrableDomain(WTFMove(domain));
}
void NetworkSession::setPrivateClickMeasurementOverrideTimerForTesting(bool value)
{
- m_privateClickMeasurement->setOverrideTimerForTesting(value);
+ privateClickMeasurement().setOverrideTimerForTesting(value);
}
void NetworkSession::markAttributedPrivateClickMeasurementsAsExpiredForTesting(CompletionHandler<void()>&& completionHandler)
{
- m_privateClickMeasurement->markAttributedPrivateClickMeasurementsAsExpiredForTesting(WTFMove(completionHandler));
+ privateClickMeasurement().markAttributedPrivateClickMeasurementsAsExpiredForTesting(WTFMove(completionHandler));
}
void NetworkSession::setPrivateClickMeasurementConversionURLForTesting(URL&& url)
{
- m_privateClickMeasurement->setConversionURLForTesting(WTFMove(url));
+ privateClickMeasurement().setConversionURLForTesting(WTFMove(url));
}
void NetworkSession::markPrivateClickMeasurementsAsExpiredForTesting()
{
- m_privateClickMeasurement->markAllUnattributedAsExpiredForTesting();
+ privateClickMeasurement().markAllUnattributedAsExpiredForTesting();
}
void NetworkSession::firePrivateClickMeasurementTimerImmediately()
{
- m_privateClickMeasurement->startTimer(0_s);
+ privateClickMeasurement().startTimer(0_s);
}
void NetworkSession::addKeptAliveLoad(Ref<NetworkResourceLoader>&& loader)
Modified: trunk/Source/WebKit/NetworkProcess/NetworkSession.h (272659 => 272660)
--- trunk/Source/WebKit/NetworkProcess/NetworkSession.h 2021-02-10 17:07:58 UTC (rev 272659)
+++ trunk/Source/WebKit/NetworkProcess/NetworkSession.h 2021-02-10 17:38:10 UTC (rev 272660)
@@ -152,6 +152,7 @@
#endif
NetworkLoadScheduler& networkLoadScheduler();
+ PrivateClickMeasurementManager& privateClickMeasurement() { return *m_privateClickMeasurement; }
protected:
NetworkSession(NetworkProcess&, const NetworkSessionCreationParameters&);
@@ -179,7 +180,7 @@
Optional<WebCore::RegistrableDomain> m_thirdPartyCNAMEDomainForTesting;
#endif
bool m_isStaleWhileRevalidateEnabled { false };
- UniqueRef<PrivateClickMeasurementManager> m_privateClickMeasurement;
+ std::unique_ptr<PrivateClickMeasurementManager> m_privateClickMeasurement;
HashSet<Ref<NetworkResourceLoader>> m_keptAliveLoads;
Modified: trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurementManager.cpp (272659 => 272660)
--- trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurementManager.cpp 2021-02-10 17:07:58 UTC (rev 272659)
+++ trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurementManager.cpp 2021-02-10 17:38:10 UTC (rev 272660)
@@ -178,7 +178,7 @@
});
}
-void PrivateClickMeasurementManager::clearSentAttributions(Vector<PrivateClickMeasurement>&& sentConversions)
+void PrivateClickMeasurementManager::clearSentAttribution(PrivateClickMeasurement&& sentConversion)
{
#if ENABLE(RESOURCE_LOAD_STATISTICS)
if (!featureEnabled())
@@ -185,7 +185,7 @@
return;
if (auto* resourceLoadStatistics = m_networkSession->resourceLoadStatistics())
- resourceLoadStatistics->clearSentAttributions(WTFMove(sentConversions));
+ resourceLoadStatistics->clearSentAttribution(WTFMove(sentConversion));
#endif
}
@@ -201,8 +201,8 @@
resourceLoadStatistics->allAttributedPrivateClickMeasurement([this] (auto&& attributions) {
auto nextTimeToFire = Seconds::infinity();
- Vector<PrivateClickMeasurement> sentAttributions;
-
+ bool hasSentAttribution = false;
+
for (auto& attribution : attributions) {
auto earliestTimeToSend = attribution.earliestTimeToSend();
if (!earliestTimeToSend) {
@@ -212,16 +212,28 @@
auto now = WallTime::now();
if (*earliestTimeToSend <= now || m_isRunningTest || debugModeEnabled()) {
+ if (hasSentAttribution) {
+ // We've already sent an attribution this round. We should send additional overdue attributions at
+ // a random time between 15 and 30 minutes to avoid a burst of simultaneous attributions. If debug
+ // mode is enabled, this should be every minute for easy testing.
+ auto interval = debugModeEnabled() ? 1_min : 15_min + Seconds(cryptographicallyRandomNumber() % 900);
+ startTimer(interval);
+ return;
+ }
+
fireConversionRequest(attribution);
- sentAttributions.append(WTFMove(attribution));
+ clearSentAttribution(WTFMove(attribution));
+ hasSentAttribution = true;
continue;
}
auto seconds = *earliestTimeToSend - now;
nextTimeToFire = std::min(nextTimeToFire, seconds);
+
+ // Attributions are sorted by earliestTimeToSend, so the first time we hit this there can be no further attributions
+ // due for reporting, and nextTimeToFire is the minimum earliestTimeToSend value for any pending attribution.
+ break;
}
-
- clearSentAttributions(WTFMove(sentAttributions));
if (nextTimeToFire < Seconds::infinity())
startTimer(nextTimeToFire);
Modified: trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurementManager.h (272659 => 272660)
--- trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurementManager.h 2021-02-10 17:07:58 UTC (rev 272659)
+++ trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurementManager.h 2021-02-10 17:38:10 UTC (rev 272660)
@@ -67,7 +67,7 @@
void startTimer(Seconds);
private:
- void clearSentAttributions(Vector<PrivateClickMeasurement>&&);
+ void clearSentAttribution(PrivateClickMeasurement&&);
void attribute(const SourceSite&, const AttributeOnSite&, AttributionTriggerData&&);
void fireConversionRequest(const PrivateClickMeasurement&);
void firePendingAttributionRequests();