Title: [281480] trunk
Revision
281480
Author
wilan...@apple.com
Date
2021-08-23 17:33:32 -0700 (Mon, 23 Aug 2021)

Log Message

PCM: Support ephemeral measurement with non-persistent WebCore::PrivateClickMeasurement
https://bugs.webkit.org/show_bug.cgi?id=228984
<rdar://problem/81778213>

Reviewed by Kate Cheney.

This patch adds support for ephemeral measurement with non-persistent
WebCore::PrivateClickMeasurement for direct response advertising.
Such advertising means there is only one pending click, held in memory,
and only stored right before the triggering event causes attribution
reports to be scheduled.

Source/WebCore:

Test: http/tests/privateClickMeasurement/attribution-conversion-through-image-redirect-ephemeral.html

* loader/PrivateClickMeasurement.h:
(WebCore::PrivateClickMeasurement::SourceSite::operator!= const):
(WebCore::PrivateClickMeasurement::AttributionDestinationSite::operator!= const):
(WebCore::PrivateClickMeasurement::PrivateClickMeasurement):
    Now takes an optional PrivateClickMeasurementAttributionEphemeral
    parameter, set to PrivateClickMeasurementAttributionEphemeral::No
    by default.
(WebCore::PrivateClickMeasurement::isEphemeral const):
(WebCore::PrivateClickMeasurement::setEphemeral):
(WebCore::PrivateClickMeasurement::encode const):
(WebCore::PrivateClickMeasurement::decode):

Source/WebKit:

* NetworkProcess/Classifier/WebResourceLoadStatisticsStore.cpp:
(WebKit::WebResourceLoadStatisticsStore::attributePrivateClickMeasurement):
    Now takes an optional ephemeral PrivateClickMeasurement parameter
    and stores it right before moving on with attribution.
* NetworkProcess/Classifier/WebResourceLoadStatisticsStore.h:
* NetworkProcess/NetworkProcess.cpp:
(WebKit::NetworkProcess::setPrivateClickMeasurementEphemeralMeasurementForTesting):
    Test infrastructure.
* NetworkProcess/NetworkProcess.h:
* NetworkProcess/NetworkProcess.messages.in:
* NetworkProcess/NetworkSession.cpp:
(WebKit::NetworkSession::setPrivateClickMeasurementEphemeralMeasurementForTesting):
    Test infrastructure.
* NetworkProcess/NetworkSession.h:
* NetworkProcess/PrivateClickMeasurementManager.cpp:
(WebKit::PrivateClickMeasurementManager::storeUnattributed):
(WebKit::PrivateClickMeasurementManager::getSignedUnlinkableToken):
(WebKit::PrivateClickMeasurementManager::insertPrivateClickMeasurement):
    New convenience function. Only stores in memory if the
    PrivateClickMeasurement parameter is marked as ephemeral.
(WebKit::PrivateClickMeasurementManager::attribute):
    Checks that the triggering event matches the ephemeral measurement if
    it exists, and if so, forwards it.
(WebKit::PrivateClickMeasurementManager::clear):
    Now clears the ephemeral state too.
* NetworkProcess/PrivateClickMeasurementManager.h:
(WebKit::PrivateClickMeasurementManager::setEphemeralMeasurementForTesting):
    Test infrastructure.
* UIProcess/API/C/WKPage.cpp:
(WKPageSetPrivateClickMeasurementEphemeralMeasurementForTesting):
    Test infrastructure.
* UIProcess/API/C/WKPagePrivate.h:
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::setPrivateClickMeasurementEphemeralMeasurementForTesting):
    Test infrastructure.
* UIProcess/WebPageProxy.h:

Tools:

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

LayoutTests:

* http/tests/privateClickMeasurement/attribution-conversion-through-image-redirect-ephemeral-expected.txt: Added.
* http/tests/privateClickMeasurement/attribution-conversion-through-image-redirect-ephemeral.html: Added.
* http/tests/privateClickMeasurement/resources/util.js:
(tearDownAndFinish):
    Resets the new testRunner.setPrivateClickMeasurementEphemeralMeasurementForTesting().

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (281479 => 281480)


--- trunk/LayoutTests/ChangeLog	2021-08-24 00:20:27 UTC (rev 281479)
+++ trunk/LayoutTests/ChangeLog	2021-08-24 00:33:32 UTC (rev 281480)
@@ -1,3 +1,23 @@
+2021-08-23  John Wilander  <wilan...@apple.com>
+
+        PCM: Support ephemeral measurement with non-persistent WebCore::PrivateClickMeasurement
+        https://bugs.webkit.org/show_bug.cgi?id=228984
+        <rdar://problem/81778213>
+
+        Reviewed by Kate Cheney.
+
+        This patch adds support for ephemeral measurement with non-persistent
+        WebCore::PrivateClickMeasurement for direct response advertising.
+        Such advertising means there is only one pending click, held in memory,
+        and only stored right before the triggering event causes attribution
+        reports to be scheduled.
+
+        * http/tests/privateClickMeasurement/attribution-conversion-through-image-redirect-ephemeral-expected.txt: Added.
+        * http/tests/privateClickMeasurement/attribution-conversion-through-image-redirect-ephemeral.html: Added.
+        * http/tests/privateClickMeasurement/resources/util.js:
+        (tearDownAndFinish):
+            Resets the new testRunner.setPrivateClickMeasurementEphemeralMeasurementForTesting().
+
 2021-08-23  Ayumi Kojima  <ayumi_koj...@apple.com>
 
         [ Catalina EWS ] http/tests/media/hls/range-request.html is a flaky failure.

Added: trunk/LayoutTests/http/tests/privateClickMeasurement/attribution-conversion-through-image-redirect-ephemeral-expected.txt (0 => 281480)


--- trunk/LayoutTests/http/tests/privateClickMeasurement/attribution-conversion-through-image-redirect-ephemeral-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/http/tests/privateClickMeasurement/attribution-conversion-through-image-redirect-ephemeral-expected.txt	2021-08-24 00:33:32 UTC (rev 281480)
@@ -0,0 +1,11 @@
+Tests triggering of ephemeral private click measurement attributions.
+
+
+Attributed Private Click Measurements:
+WebCore::PrivateClickMeasurement 1
+Source site: 127.0.0.1
+Attribute on site: localhost
+Source ID: 3
+Attribution trigger data: 12
+Attribution priority: 0
+Attribution earliest time to send: Within 24-48 hours

Added: trunk/LayoutTests/http/tests/privateClickMeasurement/attribution-conversion-through-image-redirect-ephemeral.html (0 => 281480)


--- trunk/LayoutTests/http/tests/privateClickMeasurement/attribution-conversion-through-image-redirect-ephemeral.html	                        (rev 0)
+++ trunk/LayoutTests/http/tests/privateClickMeasurement/attribution-conversion-through-image-redirect-ephemeral.html	2021-08-24 00:33:32 UTC (rev 281480)
@@ -0,0 +1,53 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ useFlexibleViewport=true ] -->
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
+    <script src=""
+    <script src=""
+</head>
+<body _onload_="setTimeout(runTest, 0)">
+<div id="description">Tests triggering of ephemeral private click measurement attributions.</div>
+<a id="targetLink" href="" attributionsourceid=3 attributiondestination="http://localhost:8000">Link</a><br>
+<div id="output"></div>
+<script>
+    prepareTest();
+
+    function activateElement(elementID) {
+        var element = document.getElementById(elementID);
+        var centerX = element.offsetLeft + element.offsetWidth / 2;
+        var centerY = element.offsetTop + element.offsetHeight / 2;
+        UIHelper.activateAt(centerX, centerY).then(
+            function () {
+            },
+            function () {
+                document.getElementById("output").innerText = "FAIL Promise rejected.";
+                tearDownAndFinish();
+            }
+        );
+    }
+
+    function runTest() {
+        if (window.testRunner) {
+            if (window.location.search === "?stepTwo") {
+                let imageElement = document.createElement("img");
+                imageElement.src = ""
+                imageElement.id = "pixel";
+                imageElement._onerror_ = function() {
+                    testRunner.dumpPrivateClickMeasurement();
+                    document.body.removeChild(document.getElementById("targetLink"));
+                    document.body.removeChild(document.getElementById("pixel"));
+                    tearDownAndFinish();
+                };
+                document.body.appendChild(imageElement);
+            } else {
+                testRunner.setPrivateClickMeasurementEphemeralMeasurementForTesting(true);
+                activateElement("targetLink");
+            }
+        } else {
+            document.getElementById("output").innerText = "FAIL No testRunner.";
+        }
+    }
+</script>
+</body>
+</html>

Modified: trunk/LayoutTests/http/tests/privateClickMeasurement/resources/util.js (281479 => 281480)


--- trunk/LayoutTests/http/tests/privateClickMeasurement/resources/util.js	2021-08-24 00:20:27 UTC (rev 281479)
+++ trunk/LayoutTests/http/tests/privateClickMeasurement/resources/util.js	2021-08-24 00:33:32 UTC (rev 281480)
@@ -11,6 +11,7 @@
     if (window.testRunner) {
         testRunner.setAllowsAnySSLCertificate(false);
         testRunner.setPrivateClickMeasurementOverrideTimerForTesting(false);
+        testRunner.setPrivateClickMeasurementEphemeralMeasurementForTesting(false);
         testRunner.setPrivateClickMeasurementAttributionReportURLsForTesting("", "");
         testRunner.setPrivateClickMeasurementTokenSignatureURLForTesting("");
         testRunner.setPrivateClickMeasurementTokenPublicKeyURLForTesting("");

Modified: trunk/Source/WebCore/ChangeLog (281479 => 281480)


--- trunk/Source/WebCore/ChangeLog	2021-08-24 00:20:27 UTC (rev 281479)
+++ trunk/Source/WebCore/ChangeLog	2021-08-24 00:33:32 UTC (rev 281480)
@@ -1,3 +1,31 @@
+2021-08-23  John Wilander  <wilan...@apple.com>
+
+        PCM: Support ephemeral measurement with non-persistent WebCore::PrivateClickMeasurement
+        https://bugs.webkit.org/show_bug.cgi?id=228984
+        <rdar://problem/81778213>
+
+        Reviewed by Kate Cheney.
+
+        This patch adds support for ephemeral measurement with non-persistent
+        WebCore::PrivateClickMeasurement for direct response advertising.
+        Such advertising means there is only one pending click, held in memory,
+        and only stored right before the triggering event causes attribution
+        reports to be scheduled.
+
+        Test: http/tests/privateClickMeasurement/attribution-conversion-through-image-redirect-ephemeral.html
+
+        * loader/PrivateClickMeasurement.h:
+        (WebCore::PrivateClickMeasurement::SourceSite::operator!= const):
+        (WebCore::PrivateClickMeasurement::AttributionDestinationSite::operator!= const):
+        (WebCore::PrivateClickMeasurement::PrivateClickMeasurement):
+            Now takes an optional PrivateClickMeasurementAttributionEphemeral
+            parameter, set to PrivateClickMeasurementAttributionEphemeral::No
+            by default.
+        (WebCore::PrivateClickMeasurement::isEphemeral const):
+        (WebCore::PrivateClickMeasurement::setEphemeral):
+        (WebCore::PrivateClickMeasurement::encode const):
+        (WebCore::PrivateClickMeasurement::decode):
+
 2021-08-23  Alan Bujtas  <za...@apple.com>
 
         [LFC][IFC] Decouple line box building and vertical aligning

Modified: trunk/Source/WebCore/loader/PrivateClickMeasurement.h (281479 => 281480)


--- trunk/Source/WebCore/loader/PrivateClickMeasurement.h	2021-08-24 00:20:27 UTC (rev 281479)
+++ trunk/Source/WebCore/loader/PrivateClickMeasurement.h	2021-08-24 00:33:32 UTC (rev 281480)
@@ -47,6 +47,8 @@
 
 namespace WebCore {
 
+enum class PrivateClickMeasurementAttributionEphemeral : bool { No, Yes };
+
 class PrivateClickMeasurement {
 public:
     using PriorityValue = uint32_t;
@@ -90,6 +92,11 @@
             return registrableDomain == other.registrableDomain;
         }
 
+        bool operator!=(const SourceSite& other) const
+        {
+            return registrableDomain != other.registrableDomain;
+        }
+
         bool matches(const URL& url) const
         {
             return registrableDomain.matches(url);
@@ -131,6 +138,11 @@
             return registrableDomain == other.registrableDomain;
         }
 
+        bool operator!=(const AttributionDestinationSite& other) const
+        {
+            return registrableDomain != other.registrableDomain;
+        }
+
         bool matches(const URL& url) const
         {
             return registrableDomain == RegistrableDomain { url };
@@ -300,7 +312,7 @@
     };
 
     PrivateClickMeasurement() = default;
-    PrivateClickMeasurement(SourceID sourceID, const SourceSite& sourceSite, const AttributionDestinationSite& destinationSite, String&& sourceDescription = { }, String&& purchaser = { }, WallTime timeOfAdClick = WallTime::now())
+    PrivateClickMeasurement(SourceID sourceID, const SourceSite& sourceSite, const AttributionDestinationSite& destinationSite, String&& sourceDescription = { }, String&& purchaser = { }, WallTime timeOfAdClick = WallTime::now(), PrivateClickMeasurementAttributionEphemeral isEphemeral = PrivateClickMeasurementAttributionEphemeral::No)
         : m_sourceID { sourceID }
         , m_sourceSite { sourceSite }
         , m_destinationSite { destinationSite }
@@ -307,6 +319,7 @@
         , m_sourceDescription { WTFMove(sourceDescription) }
         , m_purchaser { WTFMove(purchaser) }
         , m_timeOfAdClick { timeOfAdClick }
+        , m_isEphemeral { isEphemeral }
     {
     }
 
@@ -329,6 +342,8 @@
 
     const String& sourceDescription() const { return m_sourceDescription; }
     const String& purchaser() const { return m_purchaser; }
+    bool isEphemeral() const { return m_isEphemeral == PrivateClickMeasurementAttributionEphemeral::Yes; }
+    void setEphemeral(PrivateClickMeasurementAttributionEphemeral isEphemeral) { m_isEphemeral = isEphemeral; }
 
     // MARK: - Fraud Prevention
     WEBCORE_EXPORT URL tokenPublicKeyURL() const;
@@ -378,6 +393,7 @@
     String m_sourceDescription;
     String m_purchaser;
     WallTime m_timeOfAdClick;
+    PrivateClickMeasurementAttributionEphemeral m_isEphemeral;
 
     std::optional<AttributionTriggerData> m_attributionTriggerData;
     AttributionTimeToSendData m_timesToSend;
@@ -406,6 +422,7 @@
         << m_purchaser
         << m_timeOfAdClick
         << m_ephemeralSourceNonce
+        << m_isEphemeral
         << m_attributionTriggerData
         << m_timesToSend;
 }
@@ -448,6 +465,11 @@
     if (!ephemeralSourceNonce)
         return std::nullopt;
 
+    std::optional<PrivateClickMeasurementAttributionEphemeral> isEphemeral;
+    decoder >> isEphemeral;
+    if (!isEphemeral)
+        return std::nullopt;
+
     std::optional<std::optional<AttributionTriggerData>> attributionTriggerData;
     decoder >> attributionTriggerData;
     if (!attributionTriggerData)
@@ -464,7 +486,8 @@
         AttributionDestinationSite { WTFMove(*destinationRegistrableDomain) },
         WTFMove(*sourceDescription),
         WTFMove(*purchaser),
-        WTFMove(*timeOfAdClick)
+        WTFMove(*timeOfAdClick),
+        WTFMove(*isEphemeral)
     };
     attribution.m_ephemeralSourceNonce = WTFMove(*ephemeralSourceNonce);
     attribution.m_attributionTriggerData = WTFMove(*attributionTriggerData);

Modified: trunk/Source/WebKit/ChangeLog (281479 => 281480)


--- trunk/Source/WebKit/ChangeLog	2021-08-24 00:20:27 UTC (rev 281479)
+++ trunk/Source/WebKit/ChangeLog	2021-08-24 00:33:32 UTC (rev 281480)
@@ -1,3 +1,54 @@
+2021-08-23  John Wilander  <wilan...@apple.com>
+
+        PCM: Support ephemeral measurement with non-persistent WebCore::PrivateClickMeasurement
+        https://bugs.webkit.org/show_bug.cgi?id=228984
+        <rdar://problem/81778213>
+
+        Reviewed by Kate Cheney.
+
+        This patch adds support for ephemeral measurement with non-persistent
+        WebCore::PrivateClickMeasurement for direct response advertising.
+        Such advertising means there is only one pending click, held in memory,
+        and only stored right before the triggering event causes attribution
+        reports to be scheduled.
+
+        * NetworkProcess/Classifier/WebResourceLoadStatisticsStore.cpp:
+        (WebKit::WebResourceLoadStatisticsStore::attributePrivateClickMeasurement):
+            Now takes an optional ephemeral PrivateClickMeasurement parameter
+            and stores it right before moving on with attribution.
+        * NetworkProcess/Classifier/WebResourceLoadStatisticsStore.h:
+        * NetworkProcess/NetworkProcess.cpp:
+        (WebKit::NetworkProcess::setPrivateClickMeasurementEphemeralMeasurementForTesting):
+            Test infrastructure.
+        * NetworkProcess/NetworkProcess.h:
+        * NetworkProcess/NetworkProcess.messages.in:
+        * NetworkProcess/NetworkSession.cpp:
+        (WebKit::NetworkSession::setPrivateClickMeasurementEphemeralMeasurementForTesting):
+            Test infrastructure.
+        * NetworkProcess/NetworkSession.h:
+        * NetworkProcess/PrivateClickMeasurementManager.cpp:
+        (WebKit::PrivateClickMeasurementManager::storeUnattributed):
+        (WebKit::PrivateClickMeasurementManager::getSignedUnlinkableToken):
+        (WebKit::PrivateClickMeasurementManager::insertPrivateClickMeasurement):
+            New convenience function. Only stores in memory if the
+            PrivateClickMeasurement parameter is marked as ephemeral.
+        (WebKit::PrivateClickMeasurementManager::attribute):
+            Checks that the triggering event matches the ephemeral measurement if
+            it exists, and if so, forwards it.
+        (WebKit::PrivateClickMeasurementManager::clear):
+            Now clears the ephemeral state too.
+        * NetworkProcess/PrivateClickMeasurementManager.h:
+        (WebKit::PrivateClickMeasurementManager::setEphemeralMeasurementForTesting):
+            Test infrastructure.
+        * UIProcess/API/C/WKPage.cpp:
+        (WKPageSetPrivateClickMeasurementEphemeralMeasurementForTesting):
+            Test infrastructure.
+        * UIProcess/API/C/WKPagePrivate.h:
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::setPrivateClickMeasurementEphemeralMeasurementForTesting):
+            Test infrastructure.
+        * UIProcess/WebPageProxy.h:
+
 2021-08-23  Cameron McCormack  <hey...@apple.com>
 
         Preserve color space when getting current color in DisplayList::DrawGlyphsRecorder

Modified: trunk/Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsStore.cpp (281479 => 281480)


--- trunk/Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsStore.cpp	2021-08-24 00:20:27 UTC (rev 281479)
+++ trunk/Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsStore.cpp	2021-08-24 00:33:32 UTC (rev 281480)
@@ -33,6 +33,7 @@
 #include "NetworkProcess.h"
 #include "NetworkProcessProxyMessages.h"
 #include "NetworkSession.h"
+#include "PrivateClickMeasurementManager.h"
 #include "ResourceLoadStatisticsDatabaseStore.h"
 #include "ResourceLoadStatisticsMemoryStore.h"
 #include "ShouldGrandfatherStatistics.h"
@@ -1500,7 +1501,7 @@
     });
 }
 
-void WebResourceLoadStatisticsStore::attributePrivateClickMeasurement(const PrivateClickMeasurement::SourceSite& sourceSite, const PrivateClickMeasurement::AttributionDestinationSite& destinationSite, PrivateClickMeasurement::AttributionTriggerData&& attributionTriggerData, CompletionHandler<void(std::optional<WebCore::PrivateClickMeasurement::AttributionSecondsUntilSendData>)>&& completionHandler)
+void WebResourceLoadStatisticsStore::attributePrivateClickMeasurement(const PrivateClickMeasurement::SourceSite& sourceSite, const PrivateClickMeasurement::AttributionDestinationSite& destinationSite, PrivateClickMeasurement::AttributionTriggerData&& attributionTriggerData, std::optional<PrivateClickMeasurement>&& ephemeralMeasurement, CompletionHandler<void(std::optional<WebCore::PrivateClickMeasurement::AttributionSecondsUntilSendData>)>&& completionHandler)
 {
     ASSERT(RunLoop::isMain());
 
@@ -1509,7 +1510,7 @@
         return;
     }
 
-    postTask([this, sourceSite = sourceSite.isolatedCopy(), destinationSite = destinationSite.isolatedCopy(), attributionTriggerData = WTFMove(attributionTriggerData), completionHandler = WTFMove(completionHandler)]() mutable {
+    postTask([this, sourceSite = sourceSite.isolatedCopy(), destinationSite = destinationSite.isolatedCopy(), attributionTriggerData = WTFMove(attributionTriggerData), ephemeralMeasurement = WTFMove(ephemeralMeasurement), completionHandler = WTFMove(completionHandler)]() mutable {
         if (!m_statisticsStore) {
             postTaskReply([completionHandler = WTFMove(completionHandler)]() mutable {
                 completionHandler(std::nullopt);
@@ -1517,6 +1518,12 @@
             return;
         }
 
+        // Insert ephemeral measurement right before attribution.
+        if (ephemeralMeasurement) {
+            RELEASE_ASSERT(ephemeralMeasurement->isEphemeral());
+            m_statisticsStore->insertPrivateClickMeasurement(WTFMove(*ephemeralMeasurement), PrivateClickMeasurementAttributionType::Unattributed);
+        }
+
         auto seconds = m_statisticsStore->attributePrivateClickMeasurement(sourceSite, destinationSite, WTFMove(attributionTriggerData));
         postTaskReply([seconds, completionHandler = WTFMove(completionHandler)]() mutable {
             completionHandler(seconds);

Modified: trunk/Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsStore.h (281479 => 281480)


--- trunk/Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsStore.h	2021-08-24 00:20:27 UTC (rev 281479)
+++ trunk/Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsStore.h	2021-08-24 00:33:32 UTC (rev 281480)
@@ -242,7 +242,7 @@
     // Private Click Measurement.
     void insertPrivateClickMeasurement(WebCore::PrivateClickMeasurement&&, PrivateClickMeasurementAttributionType);
     void markAllUnattributedPrivateClickMeasurementAsExpiredForTesting();
-    void attributePrivateClickMeasurement(const WebCore::PrivateClickMeasurement::SourceSite&, const WebCore::PrivateClickMeasurement::AttributionDestinationSite&, WebCore::PrivateClickMeasurement::AttributionTriggerData&&, CompletionHandler<void(std::optional<WebCore::PrivateClickMeasurement::AttributionSecondsUntilSendData>)>&&);
+    void attributePrivateClickMeasurement(const WebCore::PrivateClickMeasurement::SourceSite&, const WebCore::PrivateClickMeasurement::AttributionDestinationSite&, WebCore::PrivateClickMeasurement::AttributionTriggerData&&, std::optional<WebCore::PrivateClickMeasurement>&& ephemeralMeasurement, CompletionHandler<void(std::optional<WebCore::PrivateClickMeasurement::AttributionSecondsUntilSendData>)>&&);
     void allAttributedPrivateClickMeasurement(CompletionHandler<void(Vector<WebCore::PrivateClickMeasurement>&&)>&&);
     void clearPrivateClickMeasurement();
     void clearPrivateClickMeasurementForRegistrableDomain(const WebCore::RegistrableDomain&);

Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp (281479 => 281480)


--- trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp	2021-08-24 00:20:27 UTC (rev 281479)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp	2021-08-24 00:33:32 UTC (rev 281480)
@@ -2611,6 +2611,15 @@
     completionHandler();
 }
 
+void NetworkProcess::setPrivateClickMeasurementEphemeralMeasurementForTesting(PAL::SessionID sessionID, bool value, CompletionHandler<void()>&& completionHandler)
+{
+    if (auto* session = networkSession(sessionID))
+        session->setPrivateClickMeasurementEphemeralMeasurementForTesting(value);
+    
+    completionHandler();
+}
+
+
 void NetworkProcess::setPrivateClickMeasurementTokenPublicKeyURLForTesting(PAL::SessionID sessionID, URL&& url, CompletionHandler<void()>&& completionHandler)
 {
     if (auto* session = networkSession(sessionID))

Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcess.h (281479 => 281480)


--- trunk/Source/WebKit/NetworkProcess/NetworkProcess.h	2021-08-24 00:20:27 UTC (rev 281479)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcess.h	2021-08-24 00:33:32 UTC (rev 281480)
@@ -342,6 +342,7 @@
     void clearPrivateClickMeasurement(PAL::SessionID, CompletionHandler<void()>&&);
     void setPrivateClickMeasurementOverrideTimerForTesting(PAL::SessionID, bool value, CompletionHandler<void()>&&);
     void markAttributedPrivateClickMeasurementsAsExpiredForTesting(PAL::SessionID, CompletionHandler<void()>&&);
+    void setPrivateClickMeasurementEphemeralMeasurementForTesting(PAL::SessionID, bool value, CompletionHandler<void()>&&);
     void simulateResourceLoadStatisticsSessionRestart(PAL::SessionID, CompletionHandler<void()>&&);
     void setPrivateClickMeasurementTokenPublicKeyURLForTesting(PAL::SessionID, URL&&, CompletionHandler<void()>&&);
     void setPrivateClickMeasurementTokenSignatureURLForTesting(PAL::SessionID, URL&&, CompletionHandler<void()>&&);

Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcess.messages.in (281479 => 281480)


--- trunk/Source/WebKit/NetworkProcess/NetworkProcess.messages.in	2021-08-24 00:20:27 UTC (rev 281479)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcess.messages.in	2021-08-24 00:33:32 UTC (rev 281480)
@@ -164,6 +164,7 @@
     ClearPrivateClickMeasurement(PAL::SessionID sessionID) -> () Async
     SetPrivateClickMeasurementOverrideTimerForTesting(PAL::SessionID sessionID, bool value) -> () Async
     MarkAttributedPrivateClickMeasurementsAsExpiredForTesting(PAL::SessionID sessionID) -> () Async
+    SetPrivateClickMeasurementEphemeralMeasurementForTesting(PAL::SessionID sessionID, bool value) -> () Async
     SimulateResourceLoadStatisticsSessionRestart(PAL::SessionID sessionID) -> () Async
     SetPrivateClickMeasurementTokenPublicKeyURLForTesting(PAL::SessionID sessionID, URL url) -> () Async
     SetPrivateClickMeasurementTokenSignatureURLForTesting(PAL::SessionID sessionID, URL url) -> () Async

Modified: trunk/Source/WebKit/NetworkProcess/NetworkSession.cpp (281479 => 281480)


--- trunk/Source/WebKit/NetworkProcess/NetworkSession.cpp	2021-08-24 00:20:27 UTC (rev 281479)
+++ trunk/Source/WebKit/NetworkProcess/NetworkSession.cpp	2021-08-24 00:33:32 UTC (rev 281480)
@@ -361,6 +361,11 @@
     privateClickMeasurement().markAllUnattributedAsExpiredForTesting();
 }
 
+void NetworkSession::setPrivateClickMeasurementEphemeralMeasurementForTesting(bool value)
+{
+    privateClickMeasurement().setEphemeralMeasurementForTesting(value);
+}
+
 // FIXME: Switch to non-mocked test data once the right cryptography library is available in open source.
 void NetworkSession::setPCMFraudPreventionValuesForTesting(String&& unlinkableToken, String&& secretToken, String&& signature, String&& keyID)
 {

Modified: trunk/Source/WebKit/NetworkProcess/NetworkSession.h (281479 => 281480)


--- trunk/Source/WebKit/NetworkProcess/NetworkSession.h	2021-08-24 00:20:27 UTC (rev 281479)
+++ trunk/Source/WebKit/NetworkProcess/NetworkSession.h	2021-08-24 00:33:32 UTC (rev 281480)
@@ -133,6 +133,7 @@
     void setPrivateClickMeasurementTokenSignatureURLForTesting(URL&&);
     void setPrivateClickMeasurementAttributionReportURLsForTesting(URL&& sourceURL, URL&& destinationURL);
     void markPrivateClickMeasurementsAsExpiredForTesting();
+    void setPrivateClickMeasurementEphemeralMeasurementForTesting(bool);
     void setPCMFraudPreventionValuesForTesting(String&& unlinkableToken, String&& secretToken, String&& signature, String&& keyID);
     void firePrivateClickMeasurementTimerImmediately();
 

Modified: trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurementManager.cpp (281479 => 281480)


--- trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurementManager.cpp	2021-08-24 00:20:27 UTC (rev 281479)
+++ trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurementManager.cpp	2021-08-24 00:33:32 UTC (rev 281480)
@@ -67,7 +67,7 @@
     startTimer(5_s);
 }
 
-void PrivateClickMeasurementManager::storeUnattributed(PrivateClickMeasurement&& attribution)
+void PrivateClickMeasurementManager::storeUnattributed(PrivateClickMeasurement&& measurement)
 {
     if (!featureEnabled())
         return;
@@ -74,10 +74,10 @@
 
     clearExpired();
 
-    if (attribution.ephemeralSourceNonce()) {
-        auto attributionCopy = attribution;
+    if (measurement.ephemeralSourceNonce()) {
+        auto measurementCopy = measurement;
         // This is guaranteed to be close in time to the navigational click which makes it likely to be personally identifiable.
-        getTokenPublicKey(WTFMove(attributionCopy), PrivateClickMeasurement::AttributionReportEndpoint::Source, PrivateClickMeasurement::PcmDataCarried::PersonallyIdentifiable, [weakThis = makeWeakPtr(*this), this] (PrivateClickMeasurement&& attribution, const String& publicKeyBase64URL) {
+        getTokenPublicKey(WTFMove(measurementCopy), PrivateClickMeasurement::AttributionReportEndpoint::Source, PrivateClickMeasurement::PcmDataCarried::PersonallyIdentifiable, [weakThis = makeWeakPtr(*this), this] (PrivateClickMeasurement&& measurement, const String& publicKeyBase64URL) {
             if (!weakThis)
                 return;
 
@@ -85,10 +85,10 @@
                 return;
 
             if (m_fraudPreventionValuesForTesting)
-                attribution.setSourceUnlinkableTokenValue(m_fraudPreventionValuesForTesting->unlinkableToken);
+                measurement.setSourceUnlinkableTokenValue(m_fraudPreventionValuesForTesting->unlinkableToken);
 #if PLATFORM(COCOA)
             else {
-                if (auto errorMessage = attribution.calculateAndUpdateSourceUnlinkableToken(publicKeyBase64URL)) {
+                if (auto errorMessage = measurement.calculateAndUpdateSourceUnlinkableToken(publicKeyBase64URL)) {
                     RELEASE_LOG_INFO(PrivateClickMeasurement, "Got the following error in calculateAndUpdateSourceUnlinkableToken(): '%{public}s", errorMessage->utf8().data());
                     m_networkProcess->broadcastConsoleMessage(m_sessionID, MessageSource::PrivateClickMeasurement, MessageLevel::Error, makeString("[Private Click Measurement] "_s, *errorMessage));
                     return;
@@ -96,7 +96,7 @@
             }
 #endif
 
-            getSignedUnlinkableToken(WTFMove(attribution));
+            getSignedUnlinkableToken(WTFMove(measurement));
             return;
         });
     }
@@ -103,10 +103,7 @@
 
     m_networkProcess->broadcastConsoleMessage(m_sessionID, MessageSource::PrivateClickMeasurement, MessageLevel::Log, "[Private Click Measurement] Storing a click."_s);
 
-#if ENABLE(RESOURCE_LOAD_STATISTICS)
-    if (auto* resourceLoadStatistics = m_networkSession->resourceLoadStatistics())
-        resourceLoadStatistics->insertPrivateClickMeasurement(WTFMove(attribution), PrivateClickMeasurementAttributionType::Unattributed);
-#endif
+    insertPrivateClickMeasurement(WTFMove(measurement), PrivateClickMeasurementAttributionType::Unattributed);
 }
 
 static NetworkLoadParameters generateNetworkLoadParameters(URL&& url, const String& httpMethod, RefPtr<JSON::Object>&& jsonPayload, PrivateClickMeasurement::PcmDataCarried dataTypeCarried, bool isDebugModeEnabled)
@@ -182,7 +179,7 @@
 
 }
 
-void PrivateClickMeasurementManager::getSignedUnlinkableToken(PrivateClickMeasurement&& attribution)
+void PrivateClickMeasurementManager::getSignedUnlinkableToken(PrivateClickMeasurement&& measurement)
 {
     if (!featureEnabled())
         return;
@@ -189,7 +186,7 @@
 
     // This is guaranteed to be close in time to the navigational click which makes it likely to be personally identifiable.
     auto pcmDataCarried = PrivateClickMeasurement::PcmDataCarried::PersonallyIdentifiable;
-    auto tokenSignatureURL = attribution.tokenSignatureURL();
+    auto tokenSignatureURL = measurement.tokenSignatureURL();
     if (m_tokenSignatureURLForTesting) {
         tokenSignatureURL = *m_tokenSignatureURLForTesting;
         // FIXME(225364)
@@ -199,12 +196,12 @@
     if (tokenSignatureURL.isEmpty() || !tokenSignatureURL.isValid())
         return;
 
-    auto loadParameters = generateNetworkLoadParametersForHttpPost(WTFMove(tokenSignatureURL), attribution.tokenSignatureJSON(), pcmDataCarried, debugModeEnabled());
+    auto loadParameters = generateNetworkLoadParametersForHttpPost(WTFMove(tokenSignatureURL), measurement.tokenSignatureJSON(), pcmDataCarried, debugModeEnabled());
 
     RELEASE_LOG_INFO(PrivateClickMeasurement, "About to fire a unlinkable token signing request.");
     m_networkProcess->broadcastConsoleMessage(m_sessionID, MessageSource::PrivateClickMeasurement, MessageLevel::Log, "[Private Click Measurement] About to fire a unlinkable token signing request."_s);
 
-    m_networkLoadFunction(WTFMove(loadParameters), [weakThis = makeWeakPtr(*this), this, attribution = WTFMove(attribution)] (auto& error, auto& response, auto& jsonObject) mutable {
+    m_networkLoadFunction(WTFMove(loadParameters), [weakThis = makeWeakPtr(*this), this, measurement = WTFMove(measurement)] (auto& error, auto& response, auto& jsonObject) mutable {
         if (!weakThis)
             return;
 
@@ -225,10 +222,10 @@
         }
         // FIX NOW!
         if (m_fraudPreventionValuesForTesting)
-            attribution.setSourceSecretToken({ m_fraudPreventionValuesForTesting->secretToken, m_fraudPreventionValuesForTesting->signature, m_fraudPreventionValuesForTesting->keyID });
+            measurement.setSourceSecretToken({ m_fraudPreventionValuesForTesting->secretToken, m_fraudPreventionValuesForTesting->signature, m_fraudPreventionValuesForTesting->keyID });
 #if PLATFORM(COCOA)
         else {
-            if (auto errorMessage = attribution.calculateAndUpdateSourceSecretToken(signatureBase64URL)) {
+            if (auto errorMessage = measurement.calculateAndUpdateSourceSecretToken(signatureBase64URL)) {
                 RELEASE_LOG_INFO(PrivateClickMeasurement, "Got the following error in calculateAndUpdateSourceSecretToken(): '%{public}s", errorMessage->utf8().data());
                 m_networkProcess->broadcastConsoleMessage(m_sessionID, MessageSource::PrivateClickMeasurement, MessageLevel::Error, makeString("[Private Click Measurement] "_s, *errorMessage));
                 return;
@@ -238,12 +235,23 @@
 
         m_networkProcess->broadcastConsoleMessage(m_sessionID, MessageSource::PrivateClickMeasurement, MessageLevel::Log, "[Private Click Measurement] Storing a secret token."_s);
 
+        insertPrivateClickMeasurement(WTFMove(measurement), PrivateClickMeasurementAttributionType::Unattributed);
+    });
+
+}
+
+void PrivateClickMeasurementManager::insertPrivateClickMeasurement(PrivateClickMeasurement&& measurement, PrivateClickMeasurementAttributionType type)
+{
+    if (m_isRunningEphemeralMeasurementTest)
+        measurement.setEphemeral(PrivateClickMeasurementAttributionEphemeral::Yes);
+    if (measurement.isEphemeral()) {
+        m_ephemeralMeasurement = WTFMove(measurement);
+        return;
+    }
 #if ENABLE(RESOURCE_LOAD_STATISTICS)
         if (auto* resourceLoadStatistics = m_networkSession->resourceLoadStatistics())
-            resourceLoadStatistics->insertPrivateClickMeasurement(WTFMove(attribution), PrivateClickMeasurementAttributionType::Unattributed);
+            resourceLoadStatistics->insertPrivateClickMeasurement(WTFMove(measurement), type);
 #endif
-    });
-
 }
 
 void PrivateClickMeasurementManager::handleAttribution(AttributionTriggerData&& attributionTriggerData, const URL& requestURL, const WebCore::ResourceRequest& redirectRequest)
@@ -280,8 +288,16 @@
     if (!featureEnabled())
         return;
 
+    if (m_ephemeralMeasurement) {
+        // Ephemeral measurement can only have one pending click.
+        if (m_ephemeralMeasurement->sourceSite() != sourceSite)
+            return;
+        if (m_ephemeralMeasurement->destinationSite() != destinationSite)
+            return;
+    }
+        
     if (auto* resourceLoadStatistics = m_networkSession->resourceLoadStatistics()) {
-        resourceLoadStatistics->attributePrivateClickMeasurement(sourceSite, destinationSite, WTFMove(attributionTriggerData), [this, weakThis = makeWeakPtr(*this)] (auto attributionSecondsUntilSendData) {
+        resourceLoadStatistics->attributePrivateClickMeasurement(sourceSite, destinationSite, WTFMove(attributionTriggerData), std::exchange(m_ephemeralMeasurement, std::nullopt), [this, weakThis = makeWeakPtr(*this)] (auto attributionSecondsUntilSendData) {
             if (!weakThis)
                 return;
             
@@ -449,6 +465,8 @@
 void PrivateClickMeasurementManager::clear()
 {
     m_firePendingAttributionRequestsTimer.stop();
+    m_ephemeralMeasurement = std::nullopt;
+    m_isRunningEphemeralMeasurementTest = false;
 
 #if ENABLE(RESOURCE_LOAD_STATISTICS)
     if (!featureEnabled())

Modified: trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurementManager.h (281479 => 281480)


--- trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurementManager.h	2021-08-24 00:20:27 UTC (rev 281479)
+++ trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurementManager.h	2021-08-24 00:33:32 UTC (rev 281480)
@@ -65,6 +65,7 @@
     void setAttributionReportURLsForTesting(URL&& sourceURL, URL&& destinationURL);
     void markAllUnattributedAsExpiredForTesting();
     void markAttributedPrivateClickMeasurementsAsExpiredForTesting(CompletionHandler<void()>&&);
+    void setEphemeralMeasurementForTesting(bool value) { m_isRunningEphemeralMeasurementTest = value; }
     void setPCMFraudPreventionValuesForTesting(String&& unlinkableToken, String&& secretToken, String&& signature, String&& keyID);
     void startTimer(Seconds);
 
@@ -71,6 +72,7 @@
 private:
     void getTokenPublicKey(PrivateClickMeasurement&&, PrivateClickMeasurement::AttributionReportEndpoint, PrivateClickMeasurement::PcmDataCarried, Function<void(PrivateClickMeasurement&& attribution, const String& publicKeyBase64URL)>&&);
     void getSignedUnlinkableToken(PrivateClickMeasurement&&);
+    void insertPrivateClickMeasurement(PrivateClickMeasurement&&, PrivateClickMeasurementAttributionType);
     void clearSentAttribution(PrivateClickMeasurement&&, PrivateClickMeasurement::AttributionReportEndpoint);
     void attribute(const SourceSite&, const AttributionDestinationSite&, AttributionTriggerData&&);
     void fireConversionRequest(const PrivateClickMeasurement&, PrivateClickMeasurement::AttributionReportEndpoint);
@@ -80,8 +82,10 @@
     bool featureEnabled() const;
     bool debugModeEnabled() const;
 
+    std::optional<PrivateClickMeasurement> m_ephemeralMeasurement;
     WebCore::Timer m_firePendingAttributionRequestsTimer;
     bool m_isRunningTest { false };
+    bool m_isRunningEphemeralMeasurementTest { false };
     std::optional<URL> m_tokenPublicKeyURLForTesting;
     std::optional<URL> m_tokenSignatureURLForTesting;
     WeakPtr<NetworkSession> m_networkSession;

Modified: trunk/Source/WebKit/UIProcess/API/C/WKPage.cpp (281479 => 281480)


--- trunk/Source/WebKit/UIProcess/API/C/WKPage.cpp	2021-08-24 00:20:27 UTC (rev 281479)
+++ trunk/Source/WebKit/UIProcess/API/C/WKPage.cpp	2021-08-24 00:33:32 UTC (rev 281480)
@@ -3082,6 +3082,14 @@
     });
 }
 
+void WKPageSetPrivateClickMeasurementEphemeralMeasurementForTesting(WKPageRef pageRef, bool value, WKPageSetPrivateClickMeasurementEphemeralMeasurementForTestingFunction callback, void* callbackContext)
+{
+    CRASH_IF_SUSPENDED;
+    toImpl(pageRef)->setPrivateClickMeasurementEphemeralMeasurementForTesting(value, [callbackContext, callback] () {
+        callback(callbackContext);
+    });
+}
+
 void WKPageSimulateResourceLoadStatisticsSessionRestart(WKPageRef pageRef, WKPageSimulateResourceLoadStatisticsSessionRestartFunction callback, void* callbackContext)
 {
     CRASH_IF_SUSPENDED;

Modified: trunk/Source/WebKit/UIProcess/API/C/WKPagePrivate.h (281479 => 281480)


--- trunk/Source/WebKit/UIProcess/API/C/WKPagePrivate.h	2021-08-24 00:20:27 UTC (rev 281479)
+++ trunk/Source/WebKit/UIProcess/API/C/WKPagePrivate.h	2021-08-24 00:33:32 UTC (rev 281480)
@@ -178,6 +178,8 @@
 WK_EXPORT void WKPageSetPrivateClickMeasurementOverrideTimerForTesting(WKPageRef page, bool value, WKPageSetPrivateClickMeasurementOverrideTimerForTestingFunction callback, void* callbackContext);
 typedef void (*WKPageMarkAttributedPrivateClickMeasurementsAsExpiredForTestingFunction)(void* functionContext);
 WK_EXPORT void WKPageMarkAttributedPrivateClickMeasurementsAsExpiredForTesting(WKPageRef page, WKPageMarkAttributedPrivateClickMeasurementsAsExpiredForTestingFunction callback, void* callbackContext);
+typedef void (*WKPageSetPrivateClickMeasurementEphemeralMeasurementForTestingFunction)(void* functionContext);
+WK_EXPORT void WKPageSetPrivateClickMeasurementEphemeralMeasurementForTesting(WKPageRef page, bool value, WKPageSetPrivateClickMeasurementEphemeralMeasurementForTestingFunction callback, void* callbackContext);
 typedef void (*WKPageSimulateResourceLoadStatisticsSessionRestartFunction)(void* functionContext);
 WK_EXPORT void WKPageSimulateResourceLoadStatisticsSessionRestart(WKPageRef page, WKPageSimulateResourceLoadStatisticsSessionRestartFunction callback, void* callbackContext);
 typedef void (*WKPageSetPrivateClickMeasurementTokenPublicKeyURLForTestingFunction)(void* functionContext);

Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.cpp (281479 => 281480)


--- trunk/Source/WebKit/UIProcess/WebPageProxy.cpp	2021-08-24 00:20:27 UTC (rev 281479)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.cpp	2021-08-24 00:33:32 UTC (rev 281480)
@@ -10404,6 +10404,11 @@
     websiteDataStore().networkProcess().sendWithAsyncReply(Messages::NetworkProcess::MarkAttributedPrivateClickMeasurementsAsExpiredForTesting(m_websiteDataStore->sessionID()), WTFMove(completionHandler));
 }
 
+void WebPageProxy::setPrivateClickMeasurementEphemeralMeasurementForTesting(bool value, CompletionHandler<void()>&& completionHandler)
+{
+    websiteDataStore().networkProcess().sendWithAsyncReply(Messages::NetworkProcess::SetPrivateClickMeasurementEphemeralMeasurementForTesting(m_websiteDataStore->sessionID(), value), WTFMove(completionHandler));
+}
+
 void WebPageProxy::simulateResourceLoadStatisticsSessionRestart(CompletionHandler<void()>&& completionHandler)
 {
     websiteDataStore().networkProcess().sendWithAsyncReply(Messages::NetworkProcess::SimulateResourceLoadStatisticsSessionRestart(m_websiteDataStore->sessionID()), WTFMove(completionHandler));

Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.h (281479 => 281480)


--- trunk/Source/WebKit/UIProcess/WebPageProxy.h	2021-08-24 00:20:27 UTC (rev 281479)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.h	2021-08-24 00:33:32 UTC (rev 281480)
@@ -1758,6 +1758,7 @@
     void clearPrivateClickMeasurement(CompletionHandler<void()>&&);
     void setPrivateClickMeasurementOverrideTimerForTesting(bool value, CompletionHandler<void()>&&);
     void markAttributedPrivateClickMeasurementsAsExpiredForTesting(CompletionHandler<void()>&&);
+    void setPrivateClickMeasurementEphemeralMeasurementForTesting(bool value, CompletionHandler<void()>&&);
     void simulateResourceLoadStatisticsSessionRestart(CompletionHandler<void()>&&);
     void setPrivateClickMeasurementTokenPublicKeyURLForTesting(const URL&, CompletionHandler<void()>&&);
     void setPrivateClickMeasurementTokenSignatureURLForTesting(const URL&, CompletionHandler<void()>&&);

Modified: trunk/Tools/ChangeLog (281479 => 281480)


--- trunk/Tools/ChangeLog	2021-08-24 00:20:27 UTC (rev 281479)
+++ trunk/Tools/ChangeLog	2021-08-24 00:33:32 UTC (rev 281480)
@@ -1,3 +1,27 @@
+2021-08-23  John Wilander  <wilan...@apple.com>
+
+        PCM: Support ephemeral measurement with non-persistent WebCore::PrivateClickMeasurement
+        https://bugs.webkit.org/show_bug.cgi?id=228984
+        <rdar://problem/81778213>
+
+        Reviewed by Kate Cheney.
+
+        This patch adds support for ephemeral measurement with non-persistent
+        WebCore::PrivateClickMeasurement for direct response advertising.
+        Such advertising means there is only one pending click, held in memory,
+        and only stored right before the triggering event causes attribution
+        reports to be scheduled.
+
+        * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl:
+        * WebKitTestRunner/InjectedBundle/TestRunner.cpp:
+        (WTR::TestRunner::setPrivateClickMeasurementEphemeralMeasurementForTesting):
+        * WebKitTestRunner/InjectedBundle/TestRunner.h:
+        * WebKitTestRunner/TestController.cpp:
+        (WTR::TestController::setPrivateClickMeasurementEphemeralMeasurementForTesting):
+        * WebKitTestRunner/TestController.h:
+        * WebKitTestRunner/TestInvocation.cpp:
+        (WTR::TestInvocation::didReceiveSynchronousMessageFromInjectedBundle):
+
 2021-08-23  Cameron McCormack  <hey...@apple.com>
 
         Preserve color space when getting current color in DisplayList::DrawGlyphsRecorder

Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl (281479 => 281480)


--- trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl	2021-08-24 00:20:27 UTC (rev 281479)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl	2021-08-24 00:33:32 UTC (rev 281480)
@@ -408,6 +408,7 @@
     undefined clearPrivateClickMeasurementsThroughWebsiteDataRemoval();
     undefined setPrivateClickMeasurementOverrideTimerForTesting(boolean value);
     undefined markAttributedPrivateClickMeasurementsAsExpiredForTesting();
+    undefined setPrivateClickMeasurementEphemeralMeasurementForTesting(boolean value);
     undefined simulateResourceLoadStatisticsSessionRestart();
     undefined setPrivateClickMeasurementTokenPublicKeyURLForTesting(DOMString url);
     undefined setPrivateClickMeasurementTokenSignatureURLForTesting(DOMString url);

Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp (281479 => 281480)


--- trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp	2021-08-24 00:20:27 UTC (rev 281479)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp	2021-08-24 00:33:32 UTC (rev 281480)
@@ -2058,6 +2058,11 @@
     postSynchronousPageMessage("MarkAttributedPrivateClickMeasurementsAsExpiredForTesting");
 }
 
+void TestRunner::setPrivateClickMeasurementEphemeralMeasurementForTesting(bool value)
+{
+    postSynchronousPageMessage("SetPrivateClickMeasurementEphemeralMeasurementForTesting", value);
+}
+
 void TestRunner::simulateResourceLoadStatisticsSessionRestart()
 {
     postSynchronousPageMessage("SimulateResourceLoadStatisticsSessionRestart");

Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h (281479 => 281480)


--- trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h	2021-08-24 00:20:27 UTC (rev 281479)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h	2021-08-24 00:33:32 UTC (rev 281480)
@@ -531,6 +531,7 @@
     void setPrivateClickMeasurementAttributionReportURLsForTesting(JSStringRef sourceURL, JSStringRef destinationURL);
     void markPrivateClickMeasurementsAsExpiredForTesting();
     void markAttributedPrivateClickMeasurementsAsExpiredForTesting();
+    void setPrivateClickMeasurementEphemeralMeasurementForTesting(bool value);
     void setPrivateClickMeasurementFraudPreventionValuesForTesting(JSStringRef unlinkableToken, JSStringRef secretToken, JSStringRef signature, JSStringRef keyID);
     void simulateResourceLoadStatisticsSessionRestart();
 

Modified: trunk/Tools/WebKitTestRunner/TestController.cpp (281479 => 281480)


--- trunk/Tools/WebKitTestRunner/TestController.cpp	2021-08-24 00:20:27 UTC (rev 281479)
+++ trunk/Tools/WebKitTestRunner/TestController.cpp	2021-08-24 00:33:32 UTC (rev 281480)
@@ -3658,6 +3658,13 @@
     runUntil(callbackContext.done, noTimeout);
 }
 
+void TestController::setPrivateClickMeasurementEphemeralMeasurementForTesting(bool value)
+{
+    PrivateClickMeasurementVoidCallbackContext callbackContext(*this);
+    WKPageSetPrivateClickMeasurementEphemeralMeasurementForTesting(m_mainWebView->page(), value, privateClickMeasurementVoidCallback, &callbackContext);
+    runUntil(callbackContext.done, noTimeout);
+}
+
 void TestController::simulateResourceLoadStatisticsSessionRestart()
 {
     PrivateClickMeasurementVoidCallbackContext callbackContext(*this);

Modified: trunk/Tools/WebKitTestRunner/TestController.h (281479 => 281480)


--- trunk/Tools/WebKitTestRunner/TestController.h	2021-08-24 00:20:27 UTC (rev 281479)
+++ trunk/Tools/WebKitTestRunner/TestController.h	2021-08-24 00:33:32 UTC (rev 281480)
@@ -345,6 +345,7 @@
     void clearPrivateClickMeasurementsThroughWebsiteDataRemoval();
     void setPrivateClickMeasurementOverrideTimerForTesting(bool value);
     void markAttributedPrivateClickMeasurementsAsExpiredForTesting();
+    void setPrivateClickMeasurementEphemeralMeasurementForTesting(bool value);
     void simulateResourceLoadStatisticsSessionRestart();
     void setPrivateClickMeasurementTokenPublicKeyURLForTesting(WKURLRef);
     void setPrivateClickMeasurementTokenSignatureURLForTesting(WKURLRef);

Modified: trunk/Tools/WebKitTestRunner/TestInvocation.cpp (281479 => 281480)


--- trunk/Tools/WebKitTestRunner/TestInvocation.cpp	2021-08-24 00:20:27 UTC (rev 281479)
+++ trunk/Tools/WebKitTestRunner/TestInvocation.cpp	2021-08-24 00:33:32 UTC (rev 281480)
@@ -1360,6 +1360,11 @@
         return nullptr;
     }
     
+    if (WKStringIsEqualToUTF8CString(messageName, "SetPrivateClickMeasurementEphemeralMeasurementForTesting")) {
+        TestController::singleton().setPrivateClickMeasurementEphemeralMeasurementForTesting(booleanValue(messageBody));
+        return nullptr;
+    }
+    
     if (WKStringIsEqualToUTF8CString(messageName, "SimulateResourceLoadStatisticsSessionRestart")) {
         TestController::singleton().simulateResourceLoadStatisticsSessionRestart();
         return nullptr;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to