Title: [283559] trunk
Revision
283559
Author
[email protected]
Date
2021-10-05 11:12:24 -0700 (Tue, 05 Oct 2021)

Log Message

Implement missing functions in PrivateClickMeasurementDaemonClient
https://bugs.webkit.org/show_bug.cgi?id=231060

Reviewed by Chris Dumez.

Source/WebKit:

Enable debug mode in the daemon if any connected clients have debug mode enabled.
Broadcast debug messages to all clients, which will then broadcast them to all web processes.
Add an API test that turns it on then off and checks that the debug messages make it all the way to the inspector.

* NetworkProcess/NetworkSession.cpp:
(WebKit::managerOrProxy):
(WebKit::NetworkSession::setPrivateClickMeasurementDebugMode):
* NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementConnection.cpp:
(WebKit::PCM::ConnectionToMachService::ConnectionToMachService):
(WebKit::PCM::ConnectionToMachService::send const):
(WebKit::PCM::ConnectionToMachService::sendWithReply const):
(WebKit::PCM::Connection::Connection): Deleted.
(WebKit::PCM::Connection::send const): Deleted.
(WebKit::PCM::Connection::sendWithReply const): Deleted.
* NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementConnection.h:
(WebKit::PCM::Connection::Connection):
(WebKit::PCM::Connection::get const):
* NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementDaemonClient.cpp:
(WebKit::PCM::DaemonClient::broadcastConsoleMessage):
(WebKit::PCM::DaemonClient::debugModeEnabled const):
* NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementManager.cpp:
(WebKit::PrivateClickMeasurementManager::setDebugModeIsEnabled):
* NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementManager.h:
* NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementManagerInterface.cpp:
(WebKit::PCM::messageTypeSendsReply):
(WebKit::PCM::handlePCMMessageSetDebugModeIsEnabled):
(WebKit::PCM::decodeMessageAndSendToManager):
* NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementManagerInterface.h:
* NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementManagerProxy.cpp:
(WebKit::PCM::ManagerProxy::ManagerProxy):
(WebKit::PCM::ManagerProxy::setDebugModeIsEnabled):
* NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementManagerProxy.h:
* NetworkProcess/PrivateClickMeasurement/cocoa/PrivateClickMeasurementConnectionCocoa.mm: Renamed from Source/WebKit/NetworkProcess/PrivateClickMeasurement/cocoa/PrivateClickMeasurementDaemonConnectionCocoa.mm.
(WebKit::PCM::ConnectionToMachService::initializeConnectionIfNeeded const):
(WebKit::PCM::ConnectionToMachService::sendDebugModeIsEnabledMessageIfNecessary const):
(WebKit::PCM::ConnectionToMachService::checkForDebugMessageBroadcast const):
(WebKit::PCM::Connection::send const):
(WebKit::PCM::Connection::sendWithReply const):
(WebKit::PCM::ConnectionToMachService::send const):
(WebKit::PCM::ConnectionToMachService::sendWithReply const):
* Shared/EntryPointUtilities/Cocoa/Daemon/PCMDaemonConnectionSet.h: Copied from Source/WebKit/NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementConnection.h.
* Shared/EntryPointUtilities/Cocoa/Daemon/PCMDaemonConnectionSet.mm: Added.
(WebKit::PCM::DaemonConnectionSet::singleton):
(WebKit::PCM::DaemonConnectionSet::add):
(WebKit::PCM::DaemonConnectionSet::remove):
(WebKit::PCM::DaemonConnectionSet::setConnectedNetworkProcessHasDebugModeEnabled):
(WebKit::PCM::DaemonConnectionSet::debugModeEnabled const):
(WebKit::PCM::DaemonConnectionSet::broadcastConsoleMessage):
* Shared/EntryPointUtilities/Cocoa/Daemon/PCMDaemonEntryPoint.mm:
(WebKit::connectionEventHandler):
(WebKit::startListeningForMachServiceConnections):
(WebKit::peers): Deleted.
* SourcesCocoa.txt:
* UIProcess/API/Cocoa/WKWebsiteDataStore.mm:
(-[WKWebsiteDataStore _setPrivateClickMeasurementDebugModeEnabledForTesting:]):
* UIProcess/API/Cocoa/WKWebsiteDataStorePrivate.h:
* WebKit.xcodeproj/project.pbxproj:

Tools:

* TestWebKitAPI/Tests/WebKitCocoa/EventAttribution.mm:
(TestWebKitAPI::testDaemonPList):
(TestWebKitAPI::cleanUpDaemon):
(TestWebKitAPI::TEST):
* TestWebKitAPI/cocoa/TestUIDelegate.h:
* TestWebKitAPI/cocoa/TestUIDelegate.mm:
(-[TestUIDelegate _webView:didAttachLocalInspector:]):
(-[TestUIDelegate waitForInspectorToShow]):
(-[WKWebView _test_waitForInspectorToShow]):

Modified Paths

Added Paths

Removed Paths

Diff

Modified: trunk/Source/WebKit/ChangeLog (283558 => 283559)


--- trunk/Source/WebKit/ChangeLog	2021-10-05 17:59:46 UTC (rev 283558)
+++ trunk/Source/WebKit/ChangeLog	2021-10-05 18:12:24 UTC (rev 283559)
@@ -1,3 +1,68 @@
+2021-10-05  Alex Christensen  <[email protected]>
+
+        Implement missing functions in PrivateClickMeasurementDaemonClient
+        https://bugs.webkit.org/show_bug.cgi?id=231060
+
+        Reviewed by Chris Dumez.
+
+        Enable debug mode in the daemon if any connected clients have debug mode enabled.
+        Broadcast debug messages to all clients, which will then broadcast them to all web processes.
+        Add an API test that turns it on then off and checks that the debug messages make it all the way to the inspector.
+
+        * NetworkProcess/NetworkSession.cpp:
+        (WebKit::managerOrProxy):
+        (WebKit::NetworkSession::setPrivateClickMeasurementDebugMode):
+        * NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementConnection.cpp:
+        (WebKit::PCM::ConnectionToMachService::ConnectionToMachService):
+        (WebKit::PCM::ConnectionToMachService::send const):
+        (WebKit::PCM::ConnectionToMachService::sendWithReply const):
+        (WebKit::PCM::Connection::Connection): Deleted.
+        (WebKit::PCM::Connection::send const): Deleted.
+        (WebKit::PCM::Connection::sendWithReply const): Deleted.
+        * NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementConnection.h:
+        (WebKit::PCM::Connection::Connection):
+        (WebKit::PCM::Connection::get const):
+        * NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementDaemonClient.cpp:
+        (WebKit::PCM::DaemonClient::broadcastConsoleMessage):
+        (WebKit::PCM::DaemonClient::debugModeEnabled const):
+        * NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementManager.cpp:
+        (WebKit::PrivateClickMeasurementManager::setDebugModeIsEnabled):
+        * NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementManager.h:
+        * NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementManagerInterface.cpp:
+        (WebKit::PCM::messageTypeSendsReply):
+        (WebKit::PCM::handlePCMMessageSetDebugModeIsEnabled):
+        (WebKit::PCM::decodeMessageAndSendToManager):
+        * NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementManagerInterface.h:
+        * NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementManagerProxy.cpp:
+        (WebKit::PCM::ManagerProxy::ManagerProxy):
+        (WebKit::PCM::ManagerProxy::setDebugModeIsEnabled):
+        * NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementManagerProxy.h:
+        * NetworkProcess/PrivateClickMeasurement/cocoa/PrivateClickMeasurementConnectionCocoa.mm: Renamed from Source/WebKit/NetworkProcess/PrivateClickMeasurement/cocoa/PrivateClickMeasurementDaemonConnectionCocoa.mm.
+        (WebKit::PCM::ConnectionToMachService::initializeConnectionIfNeeded const):
+        (WebKit::PCM::ConnectionToMachService::sendDebugModeIsEnabledMessageIfNecessary const):
+        (WebKit::PCM::ConnectionToMachService::checkForDebugMessageBroadcast const):
+        (WebKit::PCM::Connection::send const):
+        (WebKit::PCM::Connection::sendWithReply const):
+        (WebKit::PCM::ConnectionToMachService::send const):
+        (WebKit::PCM::ConnectionToMachService::sendWithReply const):
+        * Shared/EntryPointUtilities/Cocoa/Daemon/PCMDaemonConnectionSet.h: Copied from Source/WebKit/NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementConnection.h.
+        * Shared/EntryPointUtilities/Cocoa/Daemon/PCMDaemonConnectionSet.mm: Added.
+        (WebKit::PCM::DaemonConnectionSet::singleton):
+        (WebKit::PCM::DaemonConnectionSet::add):
+        (WebKit::PCM::DaemonConnectionSet::remove):
+        (WebKit::PCM::DaemonConnectionSet::setConnectedNetworkProcessHasDebugModeEnabled):
+        (WebKit::PCM::DaemonConnectionSet::debugModeEnabled const):
+        (WebKit::PCM::DaemonConnectionSet::broadcastConsoleMessage):
+        * Shared/EntryPointUtilities/Cocoa/Daemon/PCMDaemonEntryPoint.mm:
+        (WebKit::connectionEventHandler):
+        (WebKit::startListeningForMachServiceConnections):
+        (WebKit::peers): Deleted.
+        * SourcesCocoa.txt:
+        * UIProcess/API/Cocoa/WKWebsiteDataStore.mm:
+        (-[WKWebsiteDataStore _setPrivateClickMeasurementDebugModeEnabledForTesting:]):
+        * UIProcess/API/Cocoa/WKWebsiteDataStorePrivate.h:
+        * WebKit.xcodeproj/project.pbxproj:
+
 2021-10-04  Chris Dumez  <[email protected]>
 
         Add SPI to launch a service service worker in a WKWebView and expose service worker to injected bundle

Modified: trunk/Source/WebKit/NetworkProcess/NetworkSession.cpp (283558 => 283559)


--- trunk/Source/WebKit/NetworkProcess/NetworkSession.cpp	2021-10-05 17:59:46 UTC (rev 283558)
+++ trunk/Source/WebKit/NetworkProcess/NetworkSession.cpp	2021-10-05 18:12:24 UTC (rev 283559)
@@ -98,7 +98,7 @@
 static UniqueRef<PCM::ManagerInterface> managerOrProxy(NetworkSession& networkSession, NetworkProcess& networkProcess, const NetworkSessionCreationParameters& parameters)
 {
     if (!parameters.pcmMachServiceName.isEmpty())
-        return makeUniqueRef<PCM::ManagerProxy>(parameters.pcmMachServiceName);
+        return makeUniqueRef<PCM::ManagerProxy>(parameters.pcmMachServiceName, networkSession);
     return makeUniqueRef<PrivateClickMeasurementManager>(makeUniqueRef<PCM::ClientImpl>(networkSession, networkProcess), pcmStoreDirectory(networkSession, parameters.resourceLoadStatisticsParameters.directory, parameters.resourceLoadStatisticsParameters.privateClickMeasurementStorageDirectory));
 }
 
@@ -427,9 +427,7 @@
         return;
 
     m_privateClickMeasurementDebugModeEnabled = enabled;
-
-    auto message = enabled ? "[Private Click Measurement] Turned Debug Mode on."_s : "[Private Click Measurement] Turned Debug Mode off."_s;
-    m_networkProcess->broadcastConsoleMessage(sessionID(), MessageSource::PrivateClickMeasurement, MessageLevel::Info, message);
+    m_privateClickMeasurement->setDebugModeIsEnabled(enabled);
 }
 
 void NetworkSession::firePrivateClickMeasurementTimerImmediatelyForTesting()

Modified: trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementConnection.cpp (283558 => 283559)


--- trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementConnection.cpp	2021-10-05 17:59:46 UTC (rev 283558)
+++ trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementConnection.cpp	2021-10-05 18:12:24 UTC (rev 283559)
@@ -32,21 +32,20 @@
 
 namespace PCM {
 
+ConnectionToMachService::ConnectionToMachService(CString&& machServiceName, NetworkSession& networkSession)
+    : m_machServiceName(WTFMove(machServiceName))
+    , m_networkSession(makeWeakPtr(networkSession)) { }
+
 #if !PLATFORM(COCOA)
 
-Connection::Connection(CString&&)
+void ConnectionToMachService::send(MessageType, EncodedMessage&&) const
 {
     notImplemented();
 }
 
-void Connection::send(MessageType, EncodedMessage&&) const
+void ConnectionToMachService::sendWithReply(MessageType, EncodedMessage&&, CompletionHandler<void(EncodedMessage&&)>&& completionHandler) const
 {
     notImplemented();
-}
-
-void Connection::sendWithReply(MessageType, EncodedMessage&&, CompletionHandler<void(EncodedMessage&&)>&& completionHandler) const
-{
-    notImplemented();
     completionHandler({ });
 }
 

Modified: trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementConnection.h (283558 => 283559)


--- trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementConnection.h	2021-10-05 17:59:46 UTC (rev 283558)
+++ trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementConnection.h	2021-10-05 18:12:24 UTC (rev 283559)
@@ -28,14 +28,17 @@
 #include <wtf/CompletionHandler.h>
 #include <wtf/Vector.h>
 #include <wtf/WeakPtr.h>
+#include <wtf/text/CString.h>
 
 #if PLATFORM(COCOA)
-#include <wtf/OSObjectPtr.h>
+#include <wtf/RetainPtr.h>
 #include <wtf/spi/darwin/XPCSPI.h>
 #endif
 
 namespace WebKit {
 
+class NetworkSession;
+
 namespace PCM {
 
 enum class MessageType : uint8_t;
@@ -43,18 +46,34 @@
 
 class Connection : public CanMakeWeakPtr<Connection> {
 public:
-    explicit Connection(CString&& machServiceName);
+    Connection() = default;
+#if PLATFORM(COCOA)
+    explicit Connection(RetainPtr<xpc_connection_t>&& connection)
+        : m_connection(WTFMove(connection)) { }
+    xpc_connection_t get() const { return m_connection.get(); }
+    void send(xpc_object_t) const;
+    void sendWithReply(xpc_object_t, CompletionHandler<void(xpc_object_t)>&&) const;
+protected:
+    mutable RetainPtr<xpc_connection_t> m_connection;
+#endif
+};
 
+class ConnectionToMachService : public Connection {
+public:
+    ConnectionToMachService(CString&& machServiceName, NetworkSession&);
+
     void send(MessageType, EncodedMessage&&) const;
     void sendWithReply(MessageType, EncodedMessage&&, CompletionHandler<void(EncodedMessage&&)>&&) const;
 
 private:
+    void initializeConnectionIfNeeded() const;
 #if PLATFORM(COCOA)
-    void initializeConnectionIfNeeded() const;
+    void checkForDebugMessageBroadcast(xpc_object_t) const;
+#endif
+    void sendDebugModeIsEnabledMessageIfNecessary() const;
 
     const CString m_machServiceName;
-    mutable OSObjectPtr<xpc_connection_t> m_connection;
-#endif
+    WeakPtr<NetworkSession> m_networkSession;
 };
 
 } // namespace PCM

Modified: trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementDaemonClient.cpp (283558 => 283559)


--- trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementDaemonClient.cpp	2021-10-05 17:59:46 UTC (rev 283558)
+++ trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementDaemonClient.cpp	2021-10-05 18:12:24 UTC (rev 283559)
@@ -26,15 +26,22 @@
 #include "config.h"
 #include "PrivateClickMeasurementDaemonClient.h"
 
-#include <WebCore/NotImplemented.h>
+#if PLATFORM(COCOA)
+#include "PCMDaemonConnectionSet.h"
+#endif
 
 namespace WebKit {
 
 namespace PCM {
 
-void DaemonClient::broadcastConsoleMessage(JSC::MessageLevel, const String&)
+void DaemonClient::broadcastConsoleMessage(JSC::MessageLevel level, const String& message)
 {
-    notImplemented();
+#if PLATFORM(COCOA)
+    DaemonConnectionSet::singleton().broadcastConsoleMessage(level, message);
+#else
+    UNUSED_PARAM(level);
+    UNUSED_PARAM(message);
+#endif
 }
 
 bool DaemonClient::featureEnabled() const
@@ -44,8 +51,11 @@
 
 bool DaemonClient::debugModeEnabled() const
 {
-    notImplemented();
+#if PLATFORM(COCOA)
+    return DaemonConnectionSet::singleton().debugModeEnabled();
+#else
     return false;
+#endif
 }
 
 } // namespace PCM

Modified: trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementManager.cpp (283558 => 283559)


--- trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementManager.cpp	2021-10-05 17:59:46 UTC (rev 283558)
+++ trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementManager.cpp	2021-10-05 18:12:24 UTC (rev 283559)
@@ -227,6 +227,16 @@
     store().insertPrivateClickMeasurement(WTFMove(measurement), type, [] { });
 }
 
+void PrivateClickMeasurementManager::setDebugModeIsEnabled(bool enabled)
+{
+    // This doesn't maintain global state, it just broadcasts a message when debug mode enabled changes.
+    // The state is either stored in NetworkSession when not using the daemon
+    // or in DaemonConnectionSet per-connection when using the daemon.
+
+    auto message = enabled ? "[Private Click Measurement] Turned Debug Mode on."_s : "[Private Click Measurement] Turned Debug Mode off."_s;
+    m_client->broadcastConsoleMessage(MessageLevel::Info, message);
+}
+
 void PrivateClickMeasurementManager::handleAttribution(AttributionTriggerData&& attributionTriggerData, const URL& requestURL, WebCore::RegistrableDomain&& redirectDomain, const URL& firstPartyURL, const ApplicationBundleIdentifier& applicationBundleIdentifier)
 {
     if (!featureEnabled())

Modified: trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementManager.h (283558 => 283559)


--- trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementManager.h	2021-10-05 17:59:46 UTC (rev 283558)
+++ trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementManager.h	2021-10-05 18:12:24 UTC (rev 283559)
@@ -52,6 +52,7 @@
     void clear(CompletionHandler<void()>&&) final;
     void clearForRegistrableDomain(const RegistrableDomain&, CompletionHandler<void()>&&) final;
     void migratePrivateClickMeasurementFromLegacyStorage(PrivateClickMeasurement&&, PrivateClickMeasurementAttributionType) final;
+    void setDebugModeIsEnabled(bool) final;
 
     void toStringForTesting(CompletionHandler<void(String)>&&) const final;
     void setOverrideTimerForTesting(bool value) final { m_isRunningTest = value; }

Modified: trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementManagerInterface.cpp (283558 => 283559)


--- trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementManagerInterface.cpp	2021-10-05 17:59:46 UTC (rev 283558)
+++ trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementManagerInterface.cpp	2021-10-05 18:12:24 UTC (rev 283559)
@@ -34,6 +34,10 @@
 #include "PrivateClickMeasurementManager.h"
 #include "WebCoreArgumentCoders.h"
 
+#if PLATFORM(COCOA)
+#include "PCMDaemonConnectionSet.h"
+#endif
+
 namespace WebKit {
 
 namespace PCM {
@@ -69,6 +73,10 @@
 ARGUMENTS(WebCore::PrivateClickMeasurement, PrivateClickMeasurementAttributionType)
 END
 
+FUNCTION(setDebugModeIsEnabled)
+ARGUMENTS(bool)
+END
+
 FUNCTION(toStringForTesting)
 ARGUMENTS()
 REPLY(String)
@@ -147,6 +155,7 @@
     switch (messageType) {
     case MessageType::HandleAttribution:
     case MessageType::MigratePrivateClickMeasurementFromLegacyStorage:
+    case MessageType::SetDebugModeIsEnabled:
     case MessageType::SetOverrideTimerForTesting:
     case MessageType::SetTokenPublicKeyURLForTesting:
     case MessageType::SetTokenSignatureURLForTesting:
@@ -200,6 +209,26 @@
     IPC::callMemberFunction(WTFMove(*arguments), &daemonManager(), Info::MemberFunction);
 }
 
+static void handlePCMMessageSetDebugModeIsEnabled(const Connection& connection, PCM::EncodedMessage&& encodedMessage)
+{
+#if PLATFORM(COCOA)
+    PCM::Decoder decoder(WTFMove(encodedMessage));
+    std::optional<bool> enabled;
+    decoder >> enabled;
+    if (UNLIKELY(!enabled))
+        return;
+
+    auto& connectionSet = DaemonConnectionSet::singleton();
+    bool debugModeWasEnabled = connectionSet.debugModeEnabled();
+    connectionSet.setConnectedNetworkProcessHasDebugModeEnabled(connection, *enabled);
+    if (debugModeWasEnabled != connectionSet.debugModeEnabled())
+        daemonManager().setDebugModeIsEnabled(*enabled);
+#else
+    UNUSED_PARAM(connection);
+    UNUSED_PARAM(encodedMessage);
+#endif
+}
+
 template<typename Info>
 void handlePCMMessageWithReply(PCM::EncodedMessage&& encodedMessage, CompletionHandler<void(PCM::EncodedMessage&&)>&& replySender)
 {
@@ -217,7 +246,7 @@
     IPC::callMemberFunction(WTFMove(*arguments), WTFMove(completionHandler), &daemonManager(), Info::MemberFunction);
 }
 
-void decodeMessageAndSendToManager(MessageType messageType, Vector<uint8_t>&& encodedMessage, CompletionHandler<void(Vector<uint8_t>&&)>&& replySender)
+void decodeMessageAndSendToManager(const Connection& connection, MessageType messageType, Vector<uint8_t>&& encodedMessage, CompletionHandler<void(Vector<uint8_t>&&)>&& replySender)
 {
     ASSERT(messageTypeSendsReply(messageType) == !!replySender);
     switch (messageType) {
@@ -233,6 +262,9 @@
     case PCM::MessageType::ClearForRegistrableDomain:
         handlePCMMessageWithReply<MessageInfo::clearForRegistrableDomain>(WTFMove(encodedMessage), WTFMove(replySender));
         break;
+    case PCM::MessageType::SetDebugModeIsEnabled:
+        handlePCMMessageSetDebugModeIsEnabled(connection, WTFMove(encodedMessage));
+        break;
     case PCM::MessageType::MigratePrivateClickMeasurementFromLegacyStorage:
         handlePCMMessage<MessageInfo::migratePrivateClickMeasurementFromLegacyStorage>(WTFMove(encodedMessage));
         break;

Modified: trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementManagerInterface.h (283558 => 283559)


--- trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementManagerInterface.h	2021-10-05 17:59:46 UTC (rev 283558)
+++ trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementManagerInterface.h	2021-10-05 18:12:24 UTC (rev 283559)
@@ -41,6 +41,8 @@
 
 namespace PCM {
 
+class Connection;
+
 class ManagerInterface {
 public:
     virtual ~ManagerInterface() { };
@@ -57,6 +59,7 @@
     virtual void clear(CompletionHandler<void()>&&) = 0;
     virtual void clearForRegistrableDomain(const RegistrableDomain&, CompletionHandler<void()>&&) = 0;
     virtual void migratePrivateClickMeasurementFromLegacyStorage(PrivateClickMeasurement&&, PrivateClickMeasurementAttributionType) = 0;
+    virtual void setDebugModeIsEnabled(bool) = 0;
 
     virtual void toStringForTesting(CompletionHandler<void(String)>&&) const = 0;
     virtual void setOverrideTimerForTesting(bool value) = 0;
@@ -75,6 +78,9 @@
 constexpr const char* protocolVersionKey { "version" };
 constexpr uint64_t protocolVersionValue { 1 };
 
+constexpr const char* protocolDebugMessageLevelKey { "debug message level" };
+constexpr const char* protocolDebugMessageKey { "debug message" };
+
 constexpr const char* protocolMessageTypeKey { "message type" };
 enum class MessageType : uint8_t {
     StoreUnattributed,
@@ -82,6 +88,7 @@
     Clear,
     ClearForRegistrableDomain,
     MigratePrivateClickMeasurementFromLegacyStorage,
+    SetDebugModeIsEnabled,
     ToStringForTesting,
     SetOverrideTimerForTesting,
     SetTokenPublicKeyURLForTesting,
@@ -99,7 +106,7 @@
 constexpr const char* protocolEncodedMessageKey { "encoded message" };
 using EncodedMessage = Vector<uint8_t>;
 
-void decodeMessageAndSendToManager(MessageType, Vector<uint8_t>&& message, CompletionHandler<void(Vector<uint8_t>&&)>&&);
+void decodeMessageAndSendToManager(const Connection&, MessageType, Vector<uint8_t>&& message, CompletionHandler<void(Vector<uint8_t>&&)>&&);
 bool messageTypeSendsReply(MessageType);
 
 void initializePCMStorageInDirectory(const String&);
@@ -118,6 +125,7 @@
         WebKit::PCM::MessageType::Clear,
         WebKit::PCM::MessageType::ClearForRegistrableDomain,
         WebKit::PCM::MessageType::MigratePrivateClickMeasurementFromLegacyStorage,
+        WebKit::PCM::MessageType::SetDebugModeIsEnabled,
         WebKit::PCM::MessageType::ToStringForTesting,
         WebKit::PCM::MessageType::SetOverrideTimerForTesting,
         WebKit::PCM::MessageType::SetTokenPublicKeyURLForTesting,

Modified: trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementManagerProxy.cpp (283558 => 283559)


--- trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementManagerProxy.cpp	2021-10-05 17:59:46 UTC (rev 283558)
+++ trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementManagerProxy.cpp	2021-10-05 18:12:24 UTC (rev 283559)
@@ -72,8 +72,8 @@
     });
 }
 
-ManagerProxy::ManagerProxy(const String& machServiceName)
-    : m_connection(machServiceName.utf8()) { }
+ManagerProxy::ManagerProxy(const String& machServiceName, NetworkSession& networkSession)
+    : m_connection(machServiceName.utf8(), networkSession) { }
 
 void ManagerProxy::storeUnattributed(WebCore::PrivateClickMeasurement&& pcm, CompletionHandler<void()>&& completionHandler)
 {
@@ -95,6 +95,11 @@
     sendMessageWithReply<MessageType::ClearForRegistrableDomain>(WTFMove(completionHandler), domain);
 }
 
+void ManagerProxy::setDebugModeIsEnabled(bool enabled)
+{
+    sendMessage<MessageType::SetDebugModeIsEnabled>(enabled);
+}
+
 void ManagerProxy::migratePrivateClickMeasurementFromLegacyStorage(WebCore::PrivateClickMeasurement&& pcm, PrivateClickMeasurementAttributionType type)
 {
     sendMessage<MessageType::MigratePrivateClickMeasurementFromLegacyStorage>(pcm, type);

Modified: trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementManagerProxy.h (283558 => 283559)


--- trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementManagerProxy.h	2021-10-05 17:59:46 UTC (rev 283558)
+++ trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementManagerProxy.h	2021-10-05 18:12:24 UTC (rev 283559)
@@ -32,12 +32,14 @@
 
 namespace WebKit {
 
+class NetworkSession;
+
 namespace PCM {
 
 class ManagerProxy : public ManagerInterface {
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    ManagerProxy(const String& machServiceName);
+    ManagerProxy(const String& machServiceName, NetworkSession&);
 
     using ApplicationBundleIdentifier = String;
 
@@ -46,6 +48,7 @@
     void clear(CompletionHandler<void()>&&) final;
     void clearForRegistrableDomain(const WebCore::RegistrableDomain&, CompletionHandler<void()>&&) final;
     void migratePrivateClickMeasurementFromLegacyStorage(WebCore::PrivateClickMeasurement&&, PrivateClickMeasurementAttributionType) final;
+    void setDebugModeIsEnabled(bool) final;
 
     void toStringForTesting(CompletionHandler<void(String)>&&) const final;
     void setOverrideTimerForTesting(bool) final;
@@ -66,7 +69,7 @@
     template<MessageType messageType, typename... Args, typename... ReplyArgs>
     void sendMessageWithReply(CompletionHandler<void(ReplyArgs...)>&&, Args&&...) const;
 
-    Connection m_connection;
+    ConnectionToMachService m_connection;
 };
 
 } // namespace PCM

Added: trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurement/cocoa/PrivateClickMeasurementConnectionCocoa.mm (0 => 283559)


--- trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurement/cocoa/PrivateClickMeasurementConnectionCocoa.mm	                        (rev 0)
+++ trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurement/cocoa/PrivateClickMeasurementConnectionCocoa.mm	2021-10-05 18:12:24 UTC (rev 283559)
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#import "config.h"
+#import "PrivateClickMeasurementConnection.h"
+
+#import "PrivateClickMeasurementEncoder.h"
+#import "PrivateClickMeasurementXPCUtilities.h"
+#import <wtf/NeverDestroyed.h>
+
+namespace WebKit {
+
+namespace PCM {
+
+void ConnectionToMachService::initializeConnectionIfNeeded() const
+{
+    if (m_connection)
+        return;
+    m_connection = adoptNS(xpc_connection_create_mach_service(m_machServiceName.data(), dispatch_get_main_queue(), 0));
+    xpc_connection_set_event_handler(m_connection.get(), [weakThis = makeWeakPtr(*this)](xpc_object_t event) {
+        if (!weakThis)
+            return;
+        if (event == XPC_ERROR_CONNECTION_INVALID)
+            WTFLogAlways("Failed to connect to mach service %s, likely because it is not registered with launchd", weakThis->m_machServiceName.data());
+        if (event == XPC_ERROR_CONNECTION_INTERRUPTED) {
+            // Daemon crashed, we will need to make a new connection to a new instance of the daemon.
+            weakThis->m_connection = nullptr;
+        }
+        weakThis->checkForDebugMessageBroadcast(event);
+    });
+    xpc_connection_activate(m_connection.get());
+
+    sendDebugModeIsEnabledMessageIfNecessary();
+}
+
+void ConnectionToMachService::sendDebugModeIsEnabledMessageIfNecessary() const
+{
+    ASSERT(m_connection);
+    if (!m_networkSession
+        || m_networkSession->sessionID().isEphemeral()
+        || !m_networkSession->privateClickMeasurementDebugModeEnabled())
+        return;
+
+    Encoder encoder;
+    encoder.encode(true);
+    send(MessageType::SetDebugModeIsEnabled, encoder.takeBuffer());
+}
+
+void ConnectionToMachService::checkForDebugMessageBroadcast(xpc_object_t request) const
+{
+    if (xpc_get_type(request) != XPC_TYPE_DICTIONARY)
+        return;
+    const char* debugMessage = xpc_dictionary_get_string(request, protocolDebugMessageKey);
+    if (!debugMessage)
+        return;
+    auto messageLevel = static_cast<JSC::MessageLevel>(xpc_dictionary_get_uint64(request, protocolDebugMessageLevelKey));
+    auto* networkSession = m_networkSession.get();
+    if (!networkSession)
+        return;
+    m_networkSession->networkProcess().broadcastConsoleMessage(m_networkSession->sessionID(), MessageSource::PrivateClickMeasurement, messageLevel, String::fromUTF8(debugMessage));
+}
+
+static OSObjectPtr<xpc_object_t> dictionaryFromMessage(MessageType messageType, EncodedMessage&& message)
+{
+    auto dictionary = adoptOSObject(xpc_dictionary_create(nullptr, nullptr, 0));
+    addVersionAndEncodedMessageToDictionary(WTFMove(message), dictionary.get());
+    xpc_dictionary_set_uint64(dictionary.get(), protocolMessageTypeKey, static_cast<uint64_t>(messageType));
+    return dictionary;
+}
+
+void Connection::send(xpc_object_t message) const
+{
+    ASSERT(RunLoop::isMain());
+    ASSERT(m_connection.get());
+    ASSERT(xpc_get_type(message) == XPC_TYPE_DICTIONARY);
+    xpc_connection_send_message(m_connection.get(), message);
+}
+
+void Connection::sendWithReply(xpc_object_t message, CompletionHandler<void(xpc_object_t)>&& completionHandler) const
+{
+    ASSERT(RunLoop::isMain());
+    ASSERT(m_connection.get());
+    ASSERT(xpc_get_type(message) == XPC_TYPE_DICTIONARY);
+    xpc_connection_send_message_with_reply(m_connection.get(), message, dispatch_get_main_queue(), makeBlockPtr([completionHandler = WTFMove(completionHandler)] (xpc_object_t reply) mutable {
+        ASSERT(RunLoop::isMain());
+        completionHandler(reply);
+    }).get());
+}
+
+void ConnectionToMachService::send(MessageType messageType, EncodedMessage&& message) const
+{
+    initializeConnectionIfNeeded();
+    Connection::send(dictionaryFromMessage(messageType, WTFMove(message)).get());
+}
+
+void ConnectionToMachService::sendWithReply(MessageType messageType, EncodedMessage&& message, CompletionHandler<void(EncodedMessage&&)>&& completionHandler) const
+{
+    ASSERT(RunLoop::isMain());
+    initializeConnectionIfNeeded();
+
+    Connection::sendWithReply(dictionaryFromMessage(messageType, WTFMove(message)).get(), [completionHandler = WTFMove(completionHandler)] (xpc_object_t reply) mutable {
+        if (xpc_get_type(reply) != XPC_TYPE_DICTIONARY) {
+            ASSERT_NOT_REACHED();
+            return completionHandler({ });
+        }
+        if (xpc_dictionary_get_uint64(reply, protocolVersionKey) != protocolVersionValue) {
+            ASSERT_NOT_REACHED();
+            return completionHandler({ });
+        }
+        size_t dataSize { 0 };
+        const void* data = "" protocolEncodedMessageKey, &dataSize);
+        completionHandler({ static_cast<const uint8_t*>(data), dataSize });
+    });
+}
+
+} // namespace PCM
+
+} // namespace WebKit

Deleted: trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurement/cocoa/PrivateClickMeasurementDaemonConnectionCocoa.mm (283558 => 283559)


--- trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurement/cocoa/PrivateClickMeasurementDaemonConnectionCocoa.mm	2021-10-05 17:59:46 UTC (rev 283558)
+++ trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurement/cocoa/PrivateClickMeasurementDaemonConnectionCocoa.mm	2021-10-05 18:12:24 UTC (rev 283559)
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2021 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.
- */
-
-#import "config.h"
-#import "PrivateClickMeasurementConnection.h"
-
-#import "PrivateClickMeasurementXPCUtilities.h"
-#import <wtf/NeverDestroyed.h>
-
-namespace WebKit {
-
-namespace PCM {
-
-Connection::Connection(CString&& machServiceName)
-    : m_machServiceName(WTFMove(machServiceName)) { }
-
-void Connection::initializeConnectionIfNeeded() const
-{
-    if (m_connection)
-        return;
-    m_connection = adoptOSObject(xpc_connection_create_mach_service(m_machServiceName.data(), dispatch_get_main_queue(), 0));
-    xpc_connection_set_event_handler(m_connection.get(), [weakThis = makeWeakPtr(*this)](xpc_object_t event) {
-        if (!weakThis)
-            return;
-        if (event == XPC_ERROR_CONNECTION_INVALID)
-            WTFLogAlways("Failed to connect to mach service %s, likely because it is not registered with launchd", weakThis->m_machServiceName.data());
-        if (event == XPC_ERROR_CONNECTION_INTERRUPTED) {
-            // Daemon crashed, we will need to make a new connection to a new instance of the daemon.
-            weakThis->m_connection = nullptr;
-        }
-    });
-    xpc_connection_activate(m_connection.get());
-}
-
-static OSObjectPtr<xpc_object_t> dictionaryFromMessage(MessageType messageType, EncodedMessage&& message)
-{
-    auto dictionary = adoptOSObject(xpc_dictionary_create(nullptr, nullptr, 0));
-    addVersionAndEncodedMessageToDictionary(WTFMove(message), dictionary.get());
-    xpc_dictionary_set_uint64(dictionary.get(), protocolMessageTypeKey, static_cast<uint64_t>(messageType));
-    return dictionary;
-}
-
-void Connection::send(MessageType messageType, EncodedMessage&& message) const
-{
-    ASSERT(RunLoop::isMain());
-    initializeConnectionIfNeeded();
-
-    xpc_connection_send_message(m_connection.get(), dictionaryFromMessage(messageType, WTFMove(message)).get());
-}
-
-void Connection::sendWithReply(MessageType messageType, EncodedMessage&& message, CompletionHandler<void(EncodedMessage&&)>&& completionHandler) const
-{
-    ASSERT(RunLoop::isMain());
-    initializeConnectionIfNeeded();
-
-    auto dictionary = dictionaryFromMessage(messageType, WTFMove(message));
-    xpc_connection_send_message_with_reply(m_connection.get(), dictionary.get(), dispatch_get_main_queue(), makeBlockPtr([completionHandler = WTFMove(completionHandler)] (xpc_object_t reply) mutable {
-        ASSERT(RunLoop::isMain());
-        if (xpc_get_type(reply) != XPC_TYPE_DICTIONARY) {
-            ASSERT_NOT_REACHED();
-            return completionHandler({ });
-        }
-        if (xpc_dictionary_get_uint64(reply, protocolVersionKey) != protocolVersionValue) {
-            ASSERT_NOT_REACHED();
-            return completionHandler({ });
-        }
-        size_t dataSize { 0 };
-        const void* data = "" protocolEncodedMessageKey, &dataSize);
-        completionHandler({ static_cast<const uint8_t*>(data), dataSize });
-    }).get());
-}
-
-} // namespace PCM
-
-} // namespace WebKit

Added: trunk/Source/WebKit/Shared/EntryPointUtilities/Cocoa/Daemon/PCMDaemonConnectionSet.h (0 => 283559)


--- trunk/Source/WebKit/Shared/EntryPointUtilities/Cocoa/Daemon/PCMDaemonConnectionSet.h	                        (rev 0)
+++ trunk/Source/WebKit/Shared/EntryPointUtilities/Cocoa/Daemon/PCMDaemonConnectionSet.h	2021-10-05 18:12:24 UTC (rev 283559)
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#pragma once
+
+#include <wtf/HashMap.h>
+#include <wtf/RetainPtr.h>
+#include <wtf/spi/darwin/XPCSPI.h>
+
+namespace JSC {
+enum class MessageLevel : uint8_t;
+}
+
+namespace WebKit {
+namespace PCM {
+
+class Connection;
+
+class DaemonConnectionSet {
+public:
+    static DaemonConnectionSet& singleton();
+    
+    void add(xpc_connection_t);
+    void remove(xpc_connection_t);
+
+    void setConnectedNetworkProcessHasDebugModeEnabled(const Connection&, bool);
+    bool debugModeEnabled() const;
+    void broadcastConsoleMessage(JSC::MessageLevel, const String&);
+    
+private:
+    enum class DebugModeEnabled : bool { No, Yes };
+    HashMap<RetainPtr<xpc_connection_t>, DebugModeEnabled> m_connections;
+    size_t m_connectionsWithDebugModeEnabled { 0 };
+};
+
+} // namespace PCM
+} // namespace WebKit

Added: trunk/Source/WebKit/Shared/EntryPointUtilities/Cocoa/Daemon/PCMDaemonConnectionSet.mm (0 => 283559)


--- trunk/Source/WebKit/Shared/EntryPointUtilities/Cocoa/Daemon/PCMDaemonConnectionSet.mm	                        (rev 0)
+++ trunk/Source/WebKit/Shared/EntryPointUtilities/Cocoa/Daemon/PCMDaemonConnectionSet.mm	2021-10-05 18:12:24 UTC (rev 283559)
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#import "config.h"
+#import "PCMDaemonConnectionSet.h"
+
+#import "PrivateClickMeasurementConnection.h"
+#import "PrivateClickMeasurementManagerInterface.h"
+#import <wtf/OSObjectPtr.h>
+#import <wtf/RunLoop.h>
+
+namespace WebKit {
+namespace PCM {
+
+DaemonConnectionSet& DaemonConnectionSet::singleton()
+{
+    ASSERT(RunLoop::isMain());
+    static NeverDestroyed<DaemonConnectionSet> set;
+    return set.get();
+}
+    
+void DaemonConnectionSet::add(xpc_connection_t connection)
+{
+    ASSERT(!m_connections.contains(connection));
+    m_connections.add(connection, DebugModeEnabled::No);
+}
+
+void DaemonConnectionSet::remove(xpc_connection_t connection)
+{
+    ASSERT(m_connections.contains(connection));
+    auto hadDebugModeEnabled = m_connections.take(connection);
+    if (hadDebugModeEnabled == DebugModeEnabled::Yes) {
+        ASSERT(m_connectionsWithDebugModeEnabled);
+        m_connectionsWithDebugModeEnabled--;
+    }
+}
+
+void DaemonConnectionSet::setConnectedNetworkProcessHasDebugModeEnabled(const Connection& connection, bool enabled)
+{
+    auto iterator = m_connections.find(connection.get());
+    if (iterator == m_connections.end()) {
+        ASSERT_NOT_REACHED();
+        return;
+    }
+    bool wasEnabled = iterator->value == DebugModeEnabled::Yes;
+    if (wasEnabled == enabled)
+        return;
+
+    if (enabled) {
+        iterator->value = DebugModeEnabled::Yes;
+        m_connectionsWithDebugModeEnabled++;
+    } else {
+        iterator->value = DebugModeEnabled::No;
+        m_connectionsWithDebugModeEnabled--;
+    }
+}
+
+bool DaemonConnectionSet::debugModeEnabled() const
+{
+    return !!m_connectionsWithDebugModeEnabled;
+}
+
+void DaemonConnectionSet::broadcastConsoleMessage(JSC::MessageLevel messageLevel, const String& message)
+{
+    auto dictionary = adoptOSObject(xpc_dictionary_create(nullptr, nullptr, 0));
+    xpc_dictionary_set_uint64(dictionary.get(), protocolDebugMessageLevelKey, static_cast<uint64_t>(messageLevel));
+    xpc_dictionary_set_string(dictionary.get(), protocolDebugMessageKey, message.utf8().data());
+    for (auto& connection : m_connections.keys())
+        xpc_connection_send_message(connection.get(), dictionary.get());
+}
+
+} // namespace PCM
+} // namespace WebKit

Modified: trunk/Source/WebKit/Shared/EntryPointUtilities/Cocoa/Daemon/PCMDaemonEntryPoint.mm (283558 => 283559)


--- trunk/Source/WebKit/Shared/EntryPointUtilities/Cocoa/Daemon/PCMDaemonEntryPoint.mm	2021-10-05 17:59:46 UTC (rev 283558)
+++ trunk/Source/WebKit/Shared/EntryPointUtilities/Cocoa/Daemon/PCMDaemonEntryPoint.mm	2021-10-05 18:12:24 UTC (rev 283559)
@@ -26,7 +26,9 @@
 #import "config.h"
 #import "PCMDaemonEntryPoint.h"
 
+#import "PCMDaemonConnectionSet.h"
 #import "PrivateClickMeasurementConnection.h"
+#import "PrivateClickMeasurementDecoder.h"
 #import "PrivateClickMeasurementManagerInterface.h"
 #import "PrivateClickMeasurementXPCUtilities.h"
 #import <Foundation/Foundation.h>
@@ -43,13 +45,6 @@
 
 namespace WebKit {
 
-static HashSet<RetainPtr<xpc_connection_t>>& peers()
-{
-    ASSERT(RunLoop::isMain());
-    static NeverDestroyed<HashSet<RetainPtr<xpc_connection_t>>> set;
-    return set.get();
-}
-
 static CompletionHandler<void(PCM::EncodedMessage&&)> replySender(PCM::MessageType messageType, OSObjectPtr<xpc_object_t>&& request)
 {
     if (!PCM::messageTypeSendsReply(messageType))
@@ -74,7 +69,7 @@
     size_t dataSize { 0 };
     const void* data = "" PCM::protocolEncodedMessageKey, &dataSize);
     PCM::EncodedMessage encodedMessage { static_cast<const uint8_t*>(data), dataSize };
-    decodeMessageAndSendToManager(messageType, WTFMove(encodedMessage), replySender(messageType, request));
+    decodeMessageAndSendToManager(PCM::Connection(xpc_dictionary_get_remote_connection(request)), messageType, WTFMove(encodedMessage), replySender(messageType, request));
 }
 
 static void startListeningForMachServiceConnections(const char* serviceName)
@@ -91,7 +86,7 @@
                 NSLog(@"Failed to start listening for connections to mach service %s, likely because it is not registered with launchd", serviceName);
             if (event == XPC_ERROR_CONNECTION_INTERRUPTED) {
                 NSLog(@"removing peer connection %p", peer);
-                peers().remove(peer);
+                PCM::DaemonConnectionSet::singleton().remove(peer);
                 return;
             }
             connectionEventHandler(event);
@@ -100,7 +95,7 @@
         xpc_connection_activate(peer);
 
         NSLog(@"adding peer connection %p", peer);
-        peers().add(peer);
+        PCM::DaemonConnectionSet::singleton().add(peer);
     });
     xpc_connection_activate(listener.get().get());
 }

Modified: trunk/Source/WebKit/SourcesCocoa.txt (283558 => 283559)


--- trunk/Source/WebKit/SourcesCocoa.txt	2021-10-05 17:59:46 UTC (rev 283558)
+++ trunk/Source/WebKit/SourcesCocoa.txt	2021-10-05 18:12:24 UTC (rev 283559)
@@ -41,7 +41,7 @@
 NetworkProcess/EntryPoint/Cocoa/Daemon/DaemonEntryPoint.mm
 NetworkProcess/EntryPoint/Cocoa/XPCService/NetworkServiceEntryPoint.mm
 
-NetworkProcess/PrivateClickMeasurement/cocoa/PrivateClickMeasurementDaemonConnectionCocoa.mm
+NetworkProcess/PrivateClickMeasurement/cocoa/PrivateClickMeasurementConnectionCocoa.mm
 NetworkProcess/PrivateClickMeasurement/cocoa/PrivateClickMeasurementNetworkLoaderCocoa.mm
 NetworkProcess/PrivateClickMeasurement/cocoa/PrivateClickMeasurementXPCUtilities.mm
 
@@ -193,6 +193,7 @@
 Shared/Cocoa/WKObject.mm
 Shared/Cocoa/WebPreferencesDefaultValuesCocoa.mm
 
+Shared/EntryPointUtilities/Cocoa/Daemon/PCMDaemonConnectionSet.mm
 Shared/EntryPointUtilities/Cocoa/Daemon/PCMDaemonEntryPoint.mm
 
 Shared/EntryPointUtilities/Cocoa/XPCService/XPCServiceEntryPoint.mm

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.mm (283558 => 283559)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.mm	2021-10-05 17:59:46 UTC (rev 283558)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.mm	2021-10-05 18:12:24 UTC (rev 283559)
@@ -658,6 +658,11 @@
     _websiteDataStore->allowTLSCertificateChainForLocalPCMTesting(WebCore::CertificateInfo(serverTrust));
 }
 
+- (void)_setPrivateClickMeasurementDebugModeEnabledForTesting:(BOOL)enabled
+{
+    _websiteDataStore->setPrivateClickMeasurementDebugMode(enabled);
+}
+
 - (void)_appBoundDomains:(void (^)(NSArray<NSString *> *))completionHandler
 {
 #if ENABLE(APP_BOUND_DOMAINS)

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStorePrivate.h (283558 => 283559)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStorePrivate.h	2021-10-05 17:59:46 UTC (rev 283558)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStorePrivate.h	2021-10-05 18:12:24 UTC (rev 283559)
@@ -85,6 +85,7 @@
 
 - (void)_allowTLSCertificateChain:(NSArray *)certificateChain forHost:(NSString *)host WK_API_AVAILABLE(macos(12.0), ios(15.0));
 - (void)_trustServerForLocalPCMTesting:(SecTrustRef)serverTrust WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
+- (void)_setPrivateClickMeasurementDebugModeEnabledForTesting:(BOOL)enabled WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
 
 - (void)_renameOrigin:(NSURL *)oldName to:(NSURL *)newName forDataOfTypes:(NSSet<NSString *> *)dataTypes completionHandler:(void (^)(void))completionHandler;
 

Modified: trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj (283558 => 283559)


--- trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj	2021-10-05 17:59:46 UTC (rev 283558)
+++ trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj	2021-10-05 18:12:24 UTC (rev 283559)
@@ -4537,6 +4537,8 @@
 		5C5D2388227A1892000B9BDA /* _WKCustomHeaderFields.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = _WKCustomHeaderFields.mm; sourceTree = "<group>"; };
 		5C5D2389227A1892000B9BDA /* _WKCustomHeaderFields.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _WKCustomHeaderFields.h; sourceTree = "<group>"; };
 		5C5D238A227A1D9B000B9BDA /* APICustomHeaderFields.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = APICustomHeaderFields.h; sourceTree = "<group>"; };
+		5C6289A827068EC000CF5EC6 /* PCMDaemonConnectionSet.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PCMDaemonConnectionSet.h; sourceTree = "<group>"; };
+		5C6289A927068EC000CF5EC6 /* PCMDaemonConnectionSet.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = PCMDaemonConnectionSet.mm; sourceTree = "<group>"; };
 		5C62FDF81EFC263C00CE072E /* WKURLSchemeTaskPrivate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WKURLSchemeTaskPrivate.h; sourceTree = "<group>"; };
 		5C66A4B32320961300EA4D44 /* WKHTTPCookieStoreRef.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WKHTTPCookieStoreRef.cpp; sourceTree = "<group>"; };
 		5C66A4B42320961400EA4D44 /* WKHTTPCookieStoreRef.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKHTTPCookieStoreRef.h; sourceTree = "<group>"; };
@@ -4600,7 +4602,7 @@
 		5CB930C026E0542F0032B1C0 /* PrivateClickMeasurementClientImpl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PrivateClickMeasurementClientImpl.cpp; sourceTree = "<group>"; };
 		5CB930C126E054B80032B1C0 /* PrivateClickMeasurementClientImpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PrivateClickMeasurementClientImpl.h; sourceTree = "<group>"; };
 		5CB930F226E7EEE00032B1C0 /* PrivateClickMeasurementNetworkLoaderCocoa.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PrivateClickMeasurementNetworkLoaderCocoa.mm; sourceTree = "<group>"; };
-		5CB930F426E801E80032B1C0 /* PrivateClickMeasurementDaemonConnectionCocoa.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = PrivateClickMeasurementDaemonConnectionCocoa.mm; sourceTree = "<group>"; };
+		5CB930F426E801E80032B1C0 /* PrivateClickMeasurementConnectionCocoa.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = PrivateClickMeasurementConnectionCocoa.mm; sourceTree = "<group>"; };
 		5CB930F526E802150032B1C0 /* PrivateClickMeasurementManagerProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PrivateClickMeasurementManagerProxy.h; sourceTree = "<group>"; };
 		5CB930F626E802150032B1C0 /* PrivateClickMeasurementDaemonClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PrivateClickMeasurementDaemonClient.h; sourceTree = "<group>"; };
 		5CB930F726E802150032B1C0 /* PrivateClickMeasurementDaemonClient.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PrivateClickMeasurementDaemonClient.cpp; sourceTree = "<group>"; };
@@ -9468,7 +9470,7 @@
 		5CB930F126E7EE890032B1C0 /* cocoa */ = {
 			isa = PBXGroup;
 			children = (
-				5CB930F426E801E80032B1C0 /* PrivateClickMeasurementDaemonConnectionCocoa.mm */,
+				5CB930F426E801E80032B1C0 /* PrivateClickMeasurementConnectionCocoa.mm */,
 				5CB930F226E7EEE00032B1C0 /* PrivateClickMeasurementNetworkLoaderCocoa.mm */,
 				5CB9310726E841CB0032B1C0 /* PrivateClickMeasurementXPCUtilities.h */,
 				5CB9310826E841CB0032B1C0 /* PrivateClickMeasurementXPCUtilities.mm */,
@@ -9480,6 +9482,8 @@
 			isa = PBXGroup;
 			children = (
 				5CAF7AA526F93A950003F19E /* AdAttributionDaemon.c */,
+				5C6289A827068EC000CF5EC6 /* PCMDaemonConnectionSet.h */,
+				5C6289A927068EC000CF5EC6 /* PCMDaemonConnectionSet.mm */,
 				5CB9310426E837FC0032B1C0 /* PCMDaemonEntryPoint.h */,
 				5CB9310526E837FD0032B1C0 /* PCMDaemonEntryPoint.mm */,
 			);

Modified: trunk/Tools/ChangeLog (283558 => 283559)


--- trunk/Tools/ChangeLog	2021-10-05 17:59:46 UTC (rev 283558)
+++ trunk/Tools/ChangeLog	2021-10-05 18:12:24 UTC (rev 283559)
@@ -1,3 +1,20 @@
+2021-10-05  Alex Christensen  <[email protected]>
+
+        Implement missing functions in PrivateClickMeasurementDaemonClient
+        https://bugs.webkit.org/show_bug.cgi?id=231060
+
+        Reviewed by Chris Dumez.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/EventAttribution.mm:
+        (TestWebKitAPI::testDaemonPList):
+        (TestWebKitAPI::cleanUpDaemon):
+        (TestWebKitAPI::TEST):
+        * TestWebKitAPI/cocoa/TestUIDelegate.h:
+        * TestWebKitAPI/cocoa/TestUIDelegate.mm:
+        (-[TestUIDelegate _webView:didAttachLocalInspector:]):
+        (-[TestUIDelegate waitForInspectorToShow]):
+        (-[WKWebView _test_waitForInspectorToShow]):
+
 2021-10-05  David Kilzer  <[email protected]>
 
         REGRESSION (r283476): [ iOS macOS Debug ] TestWTF failures in RetainPtrARC and TypeCastsCocoaARC

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/EventAttribution.mm (283558 => 283559)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/EventAttribution.mm	2021-10-05 17:59:46 UTC (rev 283558)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/EventAttribution.mm	2021-10-05 18:12:24 UTC (rev 283559)
@@ -29,12 +29,19 @@
 #import "PlatformUtilities.h"
 #import "Test.h"
 #import "TestNavigationDelegate.h"
+#import "TestUIDelegate.h"
 #import "TestWKWebView.h"
 #import "Utilities.h"
+#import "WKWebViewConfigurationExtras.h"
 #import <WebKit/WKMain.h>
+#import <WebKit/WKPage.h>
+#import <WebKit/WKPageInjectedBundleClient.h>
+#import <WebKit/WKPreferencesPrivate.h>
+#import <WebKit/WKString.h>
 #import <WebKit/WKWebViewPrivate.h>
 #import <WebKit/WKWebViewPrivateForTesting.h>
 #import <WebKit/WKWebsiteDataStorePrivate.h>
+#import <WebKit/_WKInspector.h>
 #import <WebKit/_WKWebsiteDataStoreConfiguration.h>
 #import <mach-o/dyld.h>
 #import <wtf/OSObjectPtr.h>
@@ -49,6 +56,10 @@
 
 #endif // HAVE(RSA_BSSA)
 
+@interface WKWebView ()
+- (WKPageRef)_pageForTesting;
+@end
+
 @interface MockEventAttribution : NSObject
 
 @property (nonatomic, assign, readonly) uint8_t sourceIdentifier;
@@ -110,7 +121,7 @@
     [[NSFileManager defaultManager] removeItemAtURL:adoptNS([[_WKWebsiteDataStoreConfiguration alloc] init]).get()._resourceLoadStatisticsDirectory error:nil];
 }
 
-void runBasicEventAttributionTest(WKWebViewConfiguration *configuration, Function<void(WKWebView *, const HTTPServer&)>&& addAttributionToWebView)
+void runBasicPCMTest(WKWebViewConfiguration *configuration, Function<void(WKWebView *, const HTTPServer&)>&& addAttributionToWebView)
 {
     clearState();
     [WKWebsiteDataStore _setNetworkProcessSuspensionAllowedForTesting:NO];
@@ -163,7 +174,7 @@
 }
 
 #if HAVE(RSA_BSSA)
-TEST(EventAttribution, FraudPrevention)
+TEST(PrivateClickMeasurement, FraudPrevention)
 {
     [WKWebsiteDataStore _setNetworkProcessSuspensionAllowedForTesting:NO];
     bool done = false;
@@ -317,14 +328,14 @@
 }
 #endif
 
-TEST(EventAttribution, Basic)
+TEST(PrivateClickMeasurement, Basic)
 {
-    runBasicEventAttributionTest(nil, [](WKWebView *webView, const HTTPServer& server) {
+    runBasicPCMTest(nil, [](WKWebView *webView, const HTTPServer& server) {
         [webView _addEventAttributionWithSourceID:42 destinationURL:exampleURL() sourceDescription:@"test source description" purchaser:@"test purchaser" reportEndpoint:server.request().URL optionalNonce:nil applicationBundleID:@"test.bundle.id"];
     });
 }
 
-TEST(EventAttribution, DatabaseLocation)
+TEST(PrivateClickMeasurement, DatabaseLocation)
 {
     NSFileManager *fileManager = [NSFileManager defaultManager];
     NSURL *tempDir = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:@"EventAttributionDatabaseLocationTest"] isDirectory:YES];
@@ -341,7 +352,7 @@
         auto viewConfiguration = adoptNS([WKWebViewConfiguration new]);
         auto dataStore = adoptNS([[WKWebsiteDataStore alloc] _initWithConfiguration:dataStoreConfiguration.get()]);
         viewConfiguration.get().websiteDataStore = dataStore.get();
-        runBasicEventAttributionTest(viewConfiguration.get(), [](WKWebView *webView, const HTTPServer& server) {
+        runBasicPCMTest(viewConfiguration.get(), [](WKWebView *webView, const HTTPServer& server) {
             [webView _addEventAttributionWithSourceID:42 destinationURL:exampleURL() sourceDescription:@"test source description" purchaser:@"test purchaser" reportEndpoint:server.request().URL optionalNonce:nil applicationBundleID:@"test.bundle.id"];
         });
         originalNetworkProcessPid = [dataStore _networkProcessIdentifier];
@@ -400,6 +411,7 @@
     xpc_dictionary_set_string(plist.get(), "_ManagedBy", "TestWebKitAPI");
     xpc_dictionary_set_string(plist.get(), "Label", "org.webkit.pcmtestdaemon");
     xpc_dictionary_set_bool(plist.get(), "LaunchOnlyOnce", true);
+    xpc_dictionary_set_string(plist.get(), "StandardErrorPath", [storageLocation URLByAppendingPathComponent:@"daemon_stderr"].path.fileSystemRepresentation);
 
     {
         auto environmentVariables = adoptOSObject(xpc_dictionary_create(nullptr, nullptr, 0));
@@ -431,6 +443,7 @@
     return @{
         @"Label" : @"org.webkit.pcmtestdaemon",
         @"LaunchOnlyOnce" : @YES,
+        @"StandardErrorPath" : [storageLocation URLByAppendingPathComponent:@"daemon_stderr"].path,
         @"EnvironmentVariables" : @{ @"DYLD_FRAMEWORK_PATH" : currentExecutableDirectory().get().path },
         @"MachServices" : @{ @"org.webkit.pcmtestdaemon.service" : @YES },
         @"ProgramArguments" : @[
@@ -445,7 +458,7 @@
 
 #endif
 
-TEST(EventAttribution, Daemon)
+static std::pair<NSURL *, WKWebViewConfiguration *> setUpDaemon(WKWebViewConfiguration *viewConfiguration)
 {
     NSFileManager *fileManager = [NSFileManager defaultManager];
     NSURL *tempDir = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:@"EventAttributionDaemonTest"] isDirectory:YES];
@@ -467,32 +480,99 @@
     EXPECT_NULL(error);
     success = [plist writeToURL:plistLocation error:&error];
     EXPECT_TRUE(success);
-    system([NSString stringWithFormat:@"launchctl load %@", plistLocation.path].UTF8String);
+    system([NSString stringWithFormat:@"launchctl load %@", plistLocation.path].fileSystemRepresentation);
 #endif
     EXPECT_NULL(error);
 
     auto dataStoreConfiguration = adoptNS([_WKWebsiteDataStoreConfiguration new]);
     dataStoreConfiguration.get().pcmMachServiceName = @"org.webkit.pcmtestdaemon.service";
-    auto viewConfiguration = adoptNS([WKWebViewConfiguration new]);
-    viewConfiguration.get().websiteDataStore = adoptNS([[WKWebsiteDataStore alloc] _initWithConfiguration:dataStoreConfiguration.get()]).get();
-    runBasicEventAttributionTest(viewConfiguration.get(), [](WKWebView *webView, const HTTPServer& server) {
-        [webView _addEventAttributionWithSourceID:42 destinationURL:exampleURL() sourceDescription:@"test source description" purchaser:@"test purchaser" reportEndpoint:server.request().URL optionalNonce:nil applicationBundleID:@"test.bundle.id"];
-    });
+    viewConfiguration.websiteDataStore = adoptNS([[WKWebsiteDataStore alloc] _initWithConfiguration:dataStoreConfiguration.get()]).get();
 
+    return std::make_pair(tempDir, viewConfiguration);
+}
+
+static void cleanUpDaemon(NSURL *tempDir)
+{
     system("killall AdAttributionDaemon -9");
 
-    EXPECT_TRUE([fileManager fileExistsAtPath:tempDir.path]);
-    [fileManager removeItemAtURL:tempDir error:&error];
+    EXPECT_TRUE([[NSFileManager defaultManager] fileExistsAtPath:tempDir.path]);
+    NSError *error = nil;
+    [[NSFileManager defaultManager] removeItemAtURL:tempDir error:&error];
     EXPECT_NULL(error);
 }
 
+TEST(PrivateClickMeasurement, DaemonBasicFunctionality)
+{
+    auto [tempDir, configuration] = setUpDaemon(adoptNS([WKWebViewConfiguration new]).autorelease());
+    runBasicPCMTest(configuration, [](WKWebView *webView, const HTTPServer& server) {
+        [webView _addEventAttributionWithSourceID:42 destinationURL:exampleURL() sourceDescription:@"test source description" purchaser:@"test purchaser" reportEndpoint:server.request().URL optionalNonce:nil applicationBundleID:@"test.bundle.id"];
+    });
+    cleanUpDaemon(tempDir);
+}
+
+static void setInjectedBundleClient(WKWebView *webView, Vector<String>& consoleMessages)
+{
+    WKPageInjectedBundleClientV0 injectedBundleClient = {
+        { 0, &consoleMessages },
+        [] (WKPageRef, WKStringRef messageName, WKTypeRef message, const void* clientInfo) {
+            auto& consoleMessages = *reinterpret_cast<Vector<String>*>(const_cast<void*>(clientInfo));
+            if (WKStringIsEqualToUTF8CString(messageName, "ConsoleMessage"))
+                consoleMessages.append(Util::toNS((WKStringRef)message));
+        },
+        nullptr,
+    };
+    WKPageSetPageInjectedBundleClient(webView._pageForTesting, &injectedBundleClient.base);
+};
+
+static RetainPtr<TestWKWebView> webViewWithOpenInspector(WKWebViewConfiguration *configuration)
+{
+    configuration.preferences._developerExtrasEnabled = YES;
+    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSZeroRect configuration:configuration]);
+    [webView synchronouslyLoadHTMLString:@"start processes"];
+    [[webView _inspector] show];
+    [webView _test_waitForInspectorToShow];
+    return webView;
+}
+
+TEST(PrivateClickMeasurement, DaemonDebugMode)
+{
+    auto [tempDir, configuration] = setUpDaemon([WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"BundlePageConsoleMessage"]);
+    Vector<String> consoleMessages;
+    auto webView = webViewWithOpenInspector(configuration);
+    setInjectedBundleClient(webView.get(), consoleMessages);
+    [configuration.websiteDataStore _setPrivateClickMeasurementDebugModeEnabledForTesting:YES];
+    while (consoleMessages.isEmpty())
+        Util::spinRunLoop();
+    EXPECT_WK_STREQ(consoleMessages[0], "[Private Click Measurement] Turned Debug Mode on.");
+    [configuration.websiteDataStore _setPrivateClickMeasurementDebugModeEnabledForTesting:NO];
+    while (consoleMessages.size() < 2)
+        Util::spinRunLoop();
+    EXPECT_WK_STREQ(consoleMessages[1], "[Private Click Measurement] Turned Debug Mode off.");
+}
+
+TEST(PrivateClickMeasurement, NetworkProcessDebugMode)
+{
+    auto configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"BundlePageConsoleMessage"];
+    Vector<String> consoleMessages;
+    auto webView = webViewWithOpenInspector(configuration);
+    setInjectedBundleClient(webView.get(), consoleMessages);
+    [configuration.websiteDataStore _setPrivateClickMeasurementDebugModeEnabledForTesting:YES];
+    while (consoleMessages.isEmpty())
+        Util::spinRunLoop();
+    EXPECT_WK_STREQ(consoleMessages[0], "[Private Click Measurement] Turned Debug Mode on.");
+    [configuration.websiteDataStore _setPrivateClickMeasurementDebugModeEnabledForTesting:NO];
+    while (consoleMessages.size() < 2)
+        Util::spinRunLoop();
+    EXPECT_WK_STREQ(consoleMessages[1], "[Private Click Measurement] Turned Debug Mode off.");
+}
+
 #endif // PLATFORM(MAC)
 
 #if HAVE(UI_EVENT_ATTRIBUTION)
 
-TEST(EventAttribution, BasicWithIOSSPI)
+TEST(PrivateClickMeasurement, BasicWithIOSSPI)
 {
-    runBasicEventAttributionTest(nil, [](WKWebView *webView, const HTTPServer& server) {
+    runBasicPCMTest(nil, [](WKWebView *webView, const HTTPServer& server) {
         auto attribution = adoptNS([[MockEventAttribution alloc] initWithReportEndpoint:server.request().URL destinationURL:exampleURL()]);
         webView._uiEventAttribution = (UIEventAttribution *)attribution.get();
         EXPECT_WK_STREQ(webView._uiEventAttribution.sourceDescription, "test source description");
@@ -500,9 +580,9 @@
     });
 }
 
-TEST(EventAttribution, BasicWithEphemeralIOSSPI)
+TEST(PrivateClickMeasurement, BasicWithEphemeralIOSSPI)
 {
-    runBasicEventAttributionTest(nil, [](WKWebView *webView, const HTTPServer& server) {
+    runBasicPCMTest(nil, [](WKWebView *webView, const HTTPServer& server) {
         auto attribution = adoptNS([[MockEventAttribution alloc] initWithReportEndpoint:server.request().URL destinationURL:exampleURL()]);
         webView._ephemeralUIEventAttribution = (UIEventAttribution *)attribution.get();
     });

Modified: trunk/Tools/TestWebKitAPI/cocoa/TestUIDelegate.h (283558 => 283559)


--- trunk/Tools/TestWebKitAPI/cocoa/TestUIDelegate.h	2021-10-05 17:59:46 UTC (rev 283558)
+++ trunk/Tools/TestWebKitAPI/cocoa/TestUIDelegate.h	2021-10-05 18:12:24 UTC (rev 283559)
@@ -40,4 +40,5 @@
 
 @interface WKWebView (TestUIDelegateExtras)
 - (NSString *)_test_waitForAlert;
+- (void)_test_waitForInspectorToShow;
 @end

Modified: trunk/Tools/TestWebKitAPI/cocoa/TestUIDelegate.mm (283558 => 283559)


--- trunk/Tools/TestWebKitAPI/cocoa/TestUIDelegate.mm	2021-10-05 17:59:46 UTC (rev 283558)
+++ trunk/Tools/TestWebKitAPI/cocoa/TestUIDelegate.mm	2021-10-05 18:12:24 UTC (rev 283559)
@@ -30,7 +30,9 @@
 #import <WebKit/WKWebViewPrivateForTesting.h>
 #import <wtf/RetainPtr.h>
 
-@implementation TestUIDelegate
+@implementation TestUIDelegate {
+    BOOL _showedInspector;
+}
 
 - (WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures
 {
@@ -81,6 +83,17 @@
     return result.autorelease();
 }
 
+- (void)_webView:(WKWebView *)webView didAttachLocalInspector:(_WKInspector *)inspector
+{
+    _showedInspector = YES;
+}
+
+- (void)waitForInspectorToShow
+{
+    while (!_showedInspector)
+        TestWebKitAPI::Util::spinRunLoop();
+}
+
 @end
 
 @implementation WKWebView (TestUIDelegateExtras)
@@ -95,4 +108,13 @@
     return alert;
 }
 
+- (void)_test_waitForInspectorToShow
+{
+    EXPECT_FALSE(self.UIDelegate);
+    auto uiDelegate = adoptNS([TestUIDelegate new]);
+    self.UIDelegate = uiDelegate.get();
+    [uiDelegate waitForInspectorToShow];
+    self.UIDelegate = nil;
+}
+
 @end
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to