Title: [285121] trunk
Revision
285121
Author
beid...@apple.com
Date
2021-11-01 12:31:45 -0700 (Mon, 01 Nov 2021)

Log Message

webpushd: Add mock in-memory registration, and the WKWebsiteDataStore SPI to manage them
https://bugs.webkit.org/show_bug.cgi?id=232539

Reviewed by Alex Christensen.

Source/WebKit:

Covered by API test.

The old SPI to ask the client if notifications should be allowed will remain.

Assuming the client okays notifications, in the case of built-in notifications, the *actual*
registration interaction with the system will take place as an additional step in webpushd

This patch:
- Adds in-memory notification registration for webpushd
- Adds SPI to WKWebsiteDataStore to manage registrations
- Tests the SPI

* NetworkProcess/NetworkProcess.cpp:
(WebKit::NetworkProcess::deletePushAndNotificationRegistration):
(WebKit::NetworkProcess::getOriginsWithPushAndNotificationPermissions):
* NetworkProcess/NetworkProcess.h:
* NetworkProcess/NetworkProcess.messages.in:

* NetworkProcess/NetworkSession.h:
(WebKit::NetworkSession::notificationManager):

* NetworkProcess/Notifications/NetworkNotificationManager.cpp:
(WebKit::NetworkNotificationManager::requestSystemNotificationPermission):
(WebKit::NetworkNotificationManager::deletePushAndNotificationRegistration):
(WebKit::NetworkNotificationManager::getOriginsWithPushAndNotificationPermissions):
(WebKit::ReplyCaller<bool>::callReply):
(WebKit::ReplyCaller<Vector<String>::callReply):
* NetworkProcess/Notifications/NetworkNotificationManager.h:

* Shared/API/APISecurityOrigin.h:
(API::SecurityOrigin::create):

* Shared/Notifications/NotificationManagerMessageHandler.h:
* Shared/Notifications/NotificationManagerMessageHandler.messages.in:

* Shared/WebPushDaemonConstants.h:
(WebKit::WebPushD::messageTypeSendsReply):

* UIProcess/API/Cocoa/WKWebsiteDataStore.mm:
(-[WKWebsiteDataStore _deletePushAndNotificationRegistration:completionHandler:]):
(-[WKWebsiteDataStore _getOriginsWithPushAndNotificationPermissions:]):
* UIProcess/API/Cocoa/WKWebsiteDataStorePrivate.h:

* UIProcess/Network/NetworkProcessProxy.cpp:
(WebKit::NetworkProcessProxy::deletePushAndNotificationRegistration):
(WebKit::NetworkProcessProxy::getOriginsWithPushAndNotificationPermissions):
* UIProcess/Network/NetworkProcessProxy.h:

* UIProcess/Notifications/WebNotificationManagerMessageHandler.cpp:
(WebKit::WebNotificationManagerMessageHandler::requestSystemNotificationPermission):
* UIProcess/Notifications/WebNotificationManagerMessageHandler.h:

* WebProcess/Notifications/NotificationPermissionRequestManager.cpp:
(WebKit::NotificationPermissionRequestManager::startRequest):

* webpushd/WebPushDaemon.h:
* webpushd/WebPushDaemon.mm:
(WebPushD::MessageInfo::getOriginsWithPushAndNotificationPermissions::encodeReply):
(WebPushD::MessageInfo::deletePushAndNotificationRegistration::encodeReply):
(WebPushD::MessageInfo::requestSystemNotificationPermission::encodeReply):
(WebPushD::Daemon::decodeAndHandleMessage):
(WebPushD::Daemon::requestSystemNotificationPermission):
(WebPushD::Daemon::getOriginsWithPushAndNotificationPermissions):
(WebPushD::Daemon::deletePushAndNotificationRegistration):

Tools:

* TestWebKitAPI/Tests/WebKitCocoa/WebPushDaemon.mm:
(-[NotificationPermissionDelegate _webView:requestNotificationPermissionForSecurityOrigin:decisionHandler:]):
(-[NotificationPermissionDelegate webView:runJavaScriptAlertPanelWithMessage:initiatedByFrame:completionHandler:]):
(TestWebKitAPI::then):

Modified Paths

Diff

Modified: trunk/LayoutTests/http/tests/notifications/request.html (285120 => 285121)


--- trunk/LayoutTests/http/tests/notifications/request.html	2021-11-01 19:22:52 UTC (rev 285120)
+++ trunk/LayoutTests/http/tests/notifications/request.html	2021-11-01 19:31:45 UTC (rev 285121)
@@ -1,4 +1,5 @@
 <!DOCTYPE html>
+<!-- webkit-test-runner [ BuiltInNotifications=false ] -->
 <script src=""
 <script src=""
 <p id="description"></p>

Modified: trunk/Source/WebKit/ChangeLog (285120 => 285121)


--- trunk/Source/WebKit/ChangeLog	2021-11-01 19:22:52 UTC (rev 285120)
+++ trunk/Source/WebKit/ChangeLog	2021-11-01 19:31:45 UTC (rev 285121)
@@ -1,3 +1,75 @@
+2021-11-01  Brady Eidson  <beid...@apple.com>
+
+        webpushd: Add mock in-memory registration, and the WKWebsiteDataStore SPI to manage them
+        https://bugs.webkit.org/show_bug.cgi?id=232539
+
+        Reviewed by Alex Christensen.
+
+        Covered by API test.
+        
+        The old SPI to ask the client if notifications should be allowed will remain.
+        
+        Assuming the client okays notifications, in the case of built-in notifications, the *actual*
+        registration interaction with the system will take place as an additional step in webpushd
+        
+        This patch:
+        - Adds in-memory notification registration for webpushd
+        - Adds SPI to WKWebsiteDataStore to manage registrations
+        - Tests the SPI
+        
+        * NetworkProcess/NetworkProcess.cpp:
+        (WebKit::NetworkProcess::deletePushAndNotificationRegistration):
+        (WebKit::NetworkProcess::getOriginsWithPushAndNotificationPermissions):
+        * NetworkProcess/NetworkProcess.h:
+        * NetworkProcess/NetworkProcess.messages.in:
+
+        * NetworkProcess/NetworkSession.h:
+        (WebKit::NetworkSession::notificationManager):
+
+        * NetworkProcess/Notifications/NetworkNotificationManager.cpp:
+        (WebKit::NetworkNotificationManager::requestSystemNotificationPermission):
+        (WebKit::NetworkNotificationManager::deletePushAndNotificationRegistration):
+        (WebKit::NetworkNotificationManager::getOriginsWithPushAndNotificationPermissions):
+        (WebKit::ReplyCaller<bool>::callReply):
+        (WebKit::ReplyCaller<Vector<String>::callReply):
+        * NetworkProcess/Notifications/NetworkNotificationManager.h:
+
+        * Shared/API/APISecurityOrigin.h:
+        (API::SecurityOrigin::create):
+
+        * Shared/Notifications/NotificationManagerMessageHandler.h:
+        * Shared/Notifications/NotificationManagerMessageHandler.messages.in:
+
+        * Shared/WebPushDaemonConstants.h:
+        (WebKit::WebPushD::messageTypeSendsReply):
+
+        * UIProcess/API/Cocoa/WKWebsiteDataStore.mm:
+        (-[WKWebsiteDataStore _deletePushAndNotificationRegistration:completionHandler:]):
+        (-[WKWebsiteDataStore _getOriginsWithPushAndNotificationPermissions:]):
+        * UIProcess/API/Cocoa/WKWebsiteDataStorePrivate.h:
+
+        * UIProcess/Network/NetworkProcessProxy.cpp:
+        (WebKit::NetworkProcessProxy::deletePushAndNotificationRegistration):
+        (WebKit::NetworkProcessProxy::getOriginsWithPushAndNotificationPermissions):
+        * UIProcess/Network/NetworkProcessProxy.h:
+
+        * UIProcess/Notifications/WebNotificationManagerMessageHandler.cpp:
+        (WebKit::WebNotificationManagerMessageHandler::requestSystemNotificationPermission):
+        * UIProcess/Notifications/WebNotificationManagerMessageHandler.h:
+
+        * WebProcess/Notifications/NotificationPermissionRequestManager.cpp:
+        (WebKit::NotificationPermissionRequestManager::startRequest):
+
+        * webpushd/WebPushDaemon.h:
+        * webpushd/WebPushDaemon.mm:
+        (WebPushD::MessageInfo::getOriginsWithPushAndNotificationPermissions::encodeReply):
+        (WebPushD::MessageInfo::deletePushAndNotificationRegistration::encodeReply):
+        (WebPushD::MessageInfo::requestSystemNotificationPermission::encodeReply):
+        (WebPushD::Daemon::decodeAndHandleMessage):
+        (WebPushD::Daemon::requestSystemNotificationPermission):
+        (WebPushD::Daemon::getOriginsWithPushAndNotificationPermissions):
+        (WebPushD::Daemon::deletePushAndNotificationRegistration):
+
 2021-11-01  Kimmo Kinnunen  <kkinnu...@apple.com>
 
         GPU process WebKit logging is not initialised

Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp (285120 => 285121)


--- trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp	2021-11-01 19:22:52 UTC (rev 285120)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp	2021-11-01 19:31:45 UTC (rev 285121)
@@ -2529,6 +2529,28 @@
 }
 #endif // ENABLE(SERVICE_WORKER)
 
+void NetworkProcess::deletePushAndNotificationRegistration(PAL::SessionID sessionID, const SecurityOriginData& origin, CompletionHandler<void(const String&)>&& callback)
+{
+#if ENABLE(BUILT_IN_NOTIFICATIONS)
+    if (auto* session = networkSession(sessionID)) {
+        session->notificationManager().deletePushAndNotificationRegistration(origin, WTFMove(callback));
+        return;
+    }
+#endif
+    callback("Cannot find network session");
+}
+
+void NetworkProcess::getOriginsWithPushAndNotificationPermissions(PAL::SessionID sessionID, CompletionHandler<void(const Vector<WebCore::SecurityOriginData>&)>&& callback)
+{
+#if ENABLE(BUILT_IN_NOTIFICATIONS)
+    if (auto* session = networkSession(sessionID)) {
+        session->notificationManager().getOriginsWithPushAndNotificationPermissions(WTFMove(callback));
+        return;
+    }
+#endif
+    callback({ });
+}
+
 void NetworkProcess::requestStorageSpace(PAL::SessionID sessionID, const ClientOrigin& origin, uint64_t quota, uint64_t currentSize, uint64_t spaceRequired, CompletionHandler<void(std::optional<uint64_t>)>&& callback)
 {
     parentProcessConnection()->sendWithAsyncReply(Messages::NetworkProcessProxy::RequestStorageSpace { sessionID, origin, quota, currentSize, spaceRequired }, WTFMove(callback), 0);

Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcess.h (285120 => 285121)


--- trunk/Source/WebKit/NetworkProcess/NetworkProcess.h	2021-11-01 19:22:52 UTC (rev 285120)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcess.h	2021-11-01 19:31:45 UTC (rev 285121)
@@ -400,6 +400,9 @@
     void processPushMessage(PAL::SessionID, const std::optional<IPC::DataReference>&, URL&&, CompletionHandler<void(bool)>&&);
 #endif
 
+    void deletePushAndNotificationRegistration(PAL::SessionID, const WebCore::SecurityOriginData&, CompletionHandler<void(const String&)>&&);
+    void getOriginsWithPushAndNotificationPermissions(PAL::SessionID, CompletionHandler<void(const Vector<WebCore::SecurityOriginData>&)>&&);
+
 private:
     void platformInitializeNetworkProcess(const NetworkProcessCreationParameters&);
 

Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcess.messages.in (285120 => 285121)


--- trunk/Source/WebKit/NetworkProcess/NetworkProcess.messages.in	2021-11-01 19:22:52 UTC (rev 285120)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcess.messages.in	2021-11-01 19:31:45 UTC (rev 285121)
@@ -208,4 +208,6 @@
 #if ENABLE(SERVICE_WORKER)
     ProcessPushMessage(PAL::SessionID sessionID, std::optional<IPC::DataReference> data, URL registrationURL) -> (bool didSucceed) Async
 #endif
+    DeletePushAndNotificationRegistration(PAL::SessionID sessionID, struct WebCore::SecurityOriginData origin) -> (String errorMessage) Async
+    GetOriginsWithPushAndNotificationPermissions(PAL::SessionID sessionID) -> (Vector<WebCore::SecurityOriginData> origins) Async
 }

Modified: trunk/Source/WebKit/NetworkProcess/NetworkSession.h (285120 => 285121)


--- trunk/Source/WebKit/NetworkProcess/NetworkSession.h	2021-11-01 19:22:52 UTC (rev 285120)
+++ trunk/Source/WebKit/NetworkProcess/NetworkSession.h	2021-11-01 19:31:45 UTC (rev 285121)
@@ -191,6 +191,10 @@
 
     String attributedBundleIdentifierFromPageIdentifier(WebPageProxyIdentifier) const;
 
+#if ENABLE(BUILT_IN_NOTIFICATIONS)
+    NetworkNotificationManager& notificationManager() { return m_notificationManager; }
+#endif
+
 protected:
     NetworkSession(NetworkProcess&, const NetworkSessionCreationParameters&);
 

Modified: trunk/Source/WebKit/NetworkProcess/Notifications/NetworkNotificationManager.cpp (285120 => 285121)


--- trunk/Source/WebKit/NetworkProcess/Notifications/NetworkNotificationManager.cpp	2021-11-01 19:22:52 UTC (rev 285120)
+++ trunk/Source/WebKit/NetworkProcess/Notifications/NetworkNotificationManager.cpp	2021-11-01 19:31:45 UTC (rev 285121)
@@ -31,6 +31,7 @@
 #include "DaemonDecoder.h"
 #include "DaemonEncoder.h"
 #include "NetworkSession.h"
+#include <WebCore/SecurityOriginData.h>
 
 namespace WebKit {
 using namespace WebCore;
@@ -42,6 +43,28 @@
         m_connection = makeUnique<WebPushD::Connection>(webPushMachServiceName.utf8(), *this);
 }
 
+void NetworkNotificationManager::requestSystemNotificationPermission(const String& originString, CompletionHandler<void(bool)>&& completionHandler)
+{
+    sendMessageWithReply<WebPushD::MessageType::RequestSystemNotificationPermission>(WTFMove(completionHandler), originString);
+}
+
+void NetworkNotificationManager::deletePushAndNotificationRegistration(const SecurityOriginData& origin, CompletionHandler<void(const String&)>&& completionHandler)
+{
+    sendMessageWithReply<WebPushD::MessageType::DeletePushAndNotificationRegistration>(WTFMove(completionHandler), origin.toString());
+}
+
+void NetworkNotificationManager::getOriginsWithPushAndNotificationPermissions(CompletionHandler<void(const Vector<SecurityOriginData>&)>&& completionHandler)
+{
+    CompletionHandler<void(Vector<String>&&)> replyHandler = [completionHandler = WTFMove(completionHandler)] (Vector<String> originStrings) mutable {
+        Vector<SecurityOriginData> origins;
+        for (auto& originString : originStrings)
+            origins.append(SecurityOriginData::fromURL({ { }, originString }));
+        completionHandler(WTFMove(origins));
+    };
+
+    sendMessageWithReply<WebPushD::MessageType::GetOriginsWithPushAndNotificationPermissions>(WTFMove(replyHandler));
+}
+
 void NetworkNotificationManager::showNotification(const String&, const String&, const String&, const String&, const String&, WebCore::NotificationDirection, const String&, uint64_t)
 {
     if (!m_connection)
@@ -76,7 +99,6 @@
         return;
 }
 
-
 template<WebPushD::MessageType messageType, typename... Args>
 void NetworkNotificationManager::sendMessage(Args&&... args) const
 {
@@ -93,6 +115,7 @@
         completionHandler();
     }
 };
+
 template<> struct ReplyCaller<String> {
     static void callReply(Daemon::Decoder&& decoder, CompletionHandler<void(String&&)>&& completionHandler)
     {
@@ -104,6 +127,39 @@
     }
 };
 
+template<> struct ReplyCaller<const String&> {
+    static void callReply(Daemon::Decoder&& decoder, CompletionHandler<void(const String&)>&& completionHandler)
+    {
+        std::optional<String> string;
+        decoder >> string;
+        if (!string)
+            return completionHandler({ });
+        completionHandler(WTFMove(*string));
+    }
+};
+
+template<> struct ReplyCaller<bool> {
+    static void callReply(Daemon::Decoder&& decoder, CompletionHandler<void(bool)>&& completionHandler)
+    {
+        std::optional<bool> boolean;
+        decoder >> boolean;
+        if (!boolean)
+            return completionHandler(false);
+        completionHandler(*boolean);
+    }
+};
+
+template<> struct ReplyCaller<Vector<String>&&> {
+    static void callReply(Daemon::Decoder&& decoder, CompletionHandler<void(Vector<String>&&)>&& completionHandler)
+    {
+        std::optional<Vector<String>> strings;
+        decoder >> strings;
+        if (!strings)
+            return completionHandler({ });
+        completionHandler(WTFMove(*strings));
+    }
+};
+
 template<WebPushD::MessageType messageType, typename... Args, typename... ReplyArgs>
 void NetworkNotificationManager::sendMessageWithReply(CompletionHandler<void(ReplyArgs...)>&& completionHandler, Args&&... args) const
 {

Modified: trunk/Source/WebKit/NetworkProcess/Notifications/NetworkNotificationManager.h (285120 => 285121)


--- trunk/Source/WebKit/NetworkProcess/Notifications/NetworkNotificationManager.h	2021-11-01 19:22:52 UTC (rev 285120)
+++ trunk/Source/WebKit/NetworkProcess/Notifications/NetworkNotificationManager.h	2021-11-01 19:31:45 UTC (rev 285121)
@@ -32,6 +32,10 @@
 #include <WebCore/NotificationDirection.h>
 #include <wtf/text/WTFString.h>
 
+namespace WebCore {
+struct SecurityOriginData;
+}
+
 namespace WebKit {
 
 namespace WebPushD {
@@ -46,9 +50,13 @@
 public:
     NetworkSession& networkSession() const { return m_networkSession; }
 
+    void deletePushAndNotificationRegistration(const WebCore::SecurityOriginData&, CompletionHandler<void(const String&)>&&);
+    void getOriginsWithPushAndNotificationPermissions(CompletionHandler<void(const Vector<WebCore::SecurityOriginData>&)>&&);
+
 private:
     NetworkNotificationManager(NetworkSession&, const String& webPushMachServiceName);
 
+    void requestSystemNotificationPermission(const String& originString, CompletionHandler<void(bool)>&&) final;
     void showNotification(const String& title, const String& body, const String& iconURL, const String& tag, const String& lang, WebCore::NotificationDirection, const String& originString, uint64_t notificationID) final;
     void cancelNotification(uint64_t notificationID) final;
     void clearNotifications(const Vector<uint64_t>& notificationIDs) final;

Modified: trunk/Source/WebKit/Shared/API/APISecurityOrigin.h (285120 => 285121)


--- trunk/Source/WebKit/Shared/API/APISecurityOrigin.h	2021-11-01 19:22:52 UTC (rev 285120)
+++ trunk/Source/WebKit/Shared/API/APISecurityOrigin.h	2021-11-01 19:31:45 UTC (rev 285121)
@@ -48,6 +48,11 @@
         return adoptRef(*new SecurityOrigin(securityOrigin.data().isolatedCopy()));
     }
 
+    static Ref<SecurityOrigin> create(const WebCore::SecurityOriginData& securityOriginData)
+    {
+        return adoptRef(*new SecurityOrigin(securityOriginData.isolatedCopy()));
+    }
+
     const WebCore::SecurityOriginData& securityOrigin() const { return m_securityOrigin; }
 
 private:

Modified: trunk/Source/WebKit/Shared/Notifications/NotificationManagerMessageHandler.h (285120 => 285121)


--- trunk/Source/WebKit/Shared/Notifications/NotificationManagerMessageHandler.h	2021-11-01 19:22:52 UTC (rev 285120)
+++ trunk/Source/WebKit/Shared/Notifications/NotificationManagerMessageHandler.h	2021-11-01 19:31:45 UTC (rev 285121)
@@ -35,6 +35,7 @@
 public:
     virtual ~NotificationManagerMessageHandler() = default;
 
+    virtual void requestSystemNotificationPermission(const String& securityOrigin, CompletionHandler<void(bool)>&&) = 0;
     virtual void showNotification(const String& title, const String& body, const String& iconURL, const String& tag, const String& language, WebCore::NotificationDirection, const String& originString, uint64_t notificationID) = 0;
     virtual void cancelNotification(uint64_t notificationID) = 0;
     virtual void clearNotifications(const Vector<uint64_t>& notificationIDs) = 0;

Modified: trunk/Source/WebKit/Shared/Notifications/NotificationManagerMessageHandler.messages.in (285120 => 285121)


--- trunk/Source/WebKit/Shared/Notifications/NotificationManagerMessageHandler.messages.in	2021-11-01 19:22:52 UTC (rev 285120)
+++ trunk/Source/WebKit/Shared/Notifications/NotificationManagerMessageHandler.messages.in	2021-11-01 19:31:45 UTC (rev 285121)
@@ -21,6 +21,7 @@
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 messages -> NotificationManagerMessageHandler NotRefCounted {
+    RequestSystemNotificationPermission(String originIdentifier) -> (bool allowed) Async
     ShowNotification(String title, String body, String iconURL, String tag, String language, enum:uint8_t WebCore::NotificationDirection direction, String originIdentifier, uint64_t notificationID)
     CancelNotification(uint64_t notificationID)
     ClearNotifications(Vector<uint64_t> notificationIDs)

Modified: trunk/Source/WebKit/Shared/WebPushDaemonConstants.h (285120 => 285121)


--- trunk/Source/WebKit/Shared/WebPushDaemonConstants.h	2021-11-01 19:22:52 UTC (rev 285120)
+++ trunk/Source/WebKit/Shared/WebPushDaemonConstants.h	2021-11-01 19:31:45 UTC (rev 285121)
@@ -37,6 +37,9 @@
 constexpr const char* protocolMessageTypeKey { "message type" };
 enum class MessageType : uint8_t {
     EchoTwice = 1,
+    RequestSystemNotificationPermission,
+    DeletePushAndNotificationRegistration,
+    GetOriginsWithPushAndNotificationPermissions,
 };
 
 inline bool messageTypeSendsReply(MessageType messageType)
@@ -43,6 +46,9 @@
 {
     switch (messageType) {
     case MessageType::EchoTwice:
+    case MessageType::GetOriginsWithPushAndNotificationPermissions:
+    case MessageType::DeletePushAndNotificationRegistration:
+    case MessageType::RequestSystemNotificationPermission:
         return true;
     }
     ASSERT_NOT_REACHED();

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


--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.mm	2021-11-01 19:22:52 UTC (rev 285120)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.mm	2021-11-01 19:31:45 UTC (rev 285121)
@@ -31,9 +31,11 @@
 #import "CompletionHandlerCallChecker.h"
 #import "NetworkProcessProxy.h"
 #import "ShouldGrandfatherStatistics.h"
+#import "WKError.h"
 #import "WKHTTPCookieStoreInternal.h"
 #import "WKNSArray.h"
 #import "WKNSURLAuthenticationChallenge.h"
+#import "WKSecurityOriginInternal.h"
 #import "WKWebViewInternal.h"
 #import "WKWebsiteDataRecordInternal.h"
 #import "WebPageProxy.h"
@@ -770,4 +772,29 @@
 #endif
 }
 
+-(void)_deletePushAndNotificationRegistration:(WKSecurityOrigin *)securityOrigin completionHandler:(void(^)(NSError *))completionHandler
+{
+    auto completionHandlerCopy = makeBlockPtr(completionHandler);
+    _websiteDataStore->networkProcess().deletePushAndNotificationRegistration(_websiteDataStore->sessionID(), securityOrigin->_securityOrigin->securityOrigin(), [completionHandlerCopy](const String& errorString) {
+        if (errorString.isEmpty()) {
+            completionHandlerCopy(nil);
+            return;
+        }
+        completionHandlerCopy([NSError errorWithDomain:@"WKWebSiteDataStore" code:WKErrorUnknown userInfo:@{ NSLocalizedDescriptionKey:(NSString *)errorString }]);
+    });
+}
+
+-(void)_getOriginsWithPushAndNotificationPermissions:(void(^)(NSSet<WKSecurityOrigin *> *))completionHandler
+{
+    auto completionHandlerCopy = makeBlockPtr(completionHandler);
+    _websiteDataStore->networkProcess().getOriginsWithPushAndNotificationPermissions(_websiteDataStore->sessionID(), [completionHandlerCopy](const Vector<WebCore::SecurityOriginData>& origins) {
+        auto set = adoptNS([[NSMutableSet alloc] initWithCapacity:origins.size()]);
+        for (auto& origin : origins) {
+            auto apiOrigin = API::SecurityOrigin::create(origin);
+            [set addObject:wrapper(apiOrigin.get())];
+        }
+        completionHandlerCopy(set.get());
+    });
+}
+
 @end

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


--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStorePrivate.h	2021-11-01 19:22:52 UTC (rev 285120)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStorePrivate.h	2021-11-01 19:31:45 UTC (rev 285121)
@@ -28,6 +28,7 @@
 
 NS_ASSUME_NONNULL_BEGIN
 
+@class WKSecurityOrigin;
 @class WKWebView;
 @class _WKResourceLoadStatisticsThirdParty;
 @class _WKWebsiteDataStoreConfiguration;
@@ -108,7 +109,8 @@
 
 -(bool)_hasServiceWorkerBackgroundActivityForTesting WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
 -(void)_processPushMessage:(NSData*)data registration:(NSURL *)registration completionHandler:(void(^)(bool))completionHandler WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
-
+-(void)_deletePushAndNotificationRegistration:(WKSecurityOrigin *)securityOrigin completionHandler:(void(^)(NSError *))completionHandler WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
+-(void)_getOriginsWithPushAndNotificationPermissions:(void(^)(NSSet<WKSecurityOrigin *> *))completionHandler WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
 @end
 
 NS_ASSUME_NONNULL_END

Modified: trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp (285120 => 285121)


--- trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp	2021-11-01 19:22:52 UTC (rev 285120)
+++ trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp	2021-11-01 19:31:45 UTC (rev 285121)
@@ -1658,6 +1658,16 @@
 }
 #endif // ENABLE(SERVICE_WORKER)
 
+void NetworkProcessProxy::deletePushAndNotificationRegistration(PAL::SessionID sessionID, const SecurityOriginData& origin, CompletionHandler<void(const String&)>&& callback)
+{
+    sendWithAsyncReply(Messages::NetworkProcess::DeletePushAndNotificationRegistration { sessionID, origin }, WTFMove(callback));
+}
+
+void NetworkProcessProxy::getOriginsWithPushAndNotificationPermissions(PAL::SessionID sessionID, CompletionHandler<void(const Vector<SecurityOriginData>&)>&& callback)
+{
+    sendWithAsyncReply(Messages::NetworkProcess::GetOriginsWithPushAndNotificationPermissions { sessionID }, WTFMove(callback));
+}
+
 } // namespace WebKit
 
 #undef MESSAGE_CHECK

Modified: trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.h (285120 => 285121)


--- trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.h	2021-11-01 19:22:52 UTC (rev 285120)
+++ trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.h	2021-11-01 19:31:45 UTC (rev 285121)
@@ -275,6 +275,9 @@
     void processPushMessage(PAL::SessionID, std::optional<Span<const uint8_t>>, const URL&, CompletionHandler<void(bool wasProcessed)>&&);
 #endif
 
+    void deletePushAndNotificationRegistration(PAL::SessionID, const WebCore::SecurityOriginData&, CompletionHandler<void(const String&)>&&);
+    void getOriginsWithPushAndNotificationPermissions(PAL::SessionID, CompletionHandler<void(const Vector<WebCore::SecurityOriginData>&)>&&);
+
 private:
     explicit NetworkProcessProxy();
 

Modified: trunk/Source/WebKit/UIProcess/Notifications/WebNotificationManagerMessageHandler.cpp (285120 => 285121)


--- trunk/Source/WebKit/UIProcess/Notifications/WebNotificationManagerMessageHandler.cpp	2021-11-01 19:22:52 UTC (rev 285120)
+++ trunk/Source/WebKit/UIProcess/Notifications/WebNotificationManagerMessageHandler.cpp	2021-11-01 19:31:45 UTC (rev 285121)
@@ -35,6 +35,11 @@
 {
 }
 
+void WebNotificationManagerMessageHandler::requestSystemNotificationPermission(const String&, CompletionHandler<void(bool)>&&)
+{
+    RELEASE_ASSERT_NOT_REACHED();
+}
+
 void WebNotificationManagerMessageHandler::showNotification(const String& title, const String& body, const String& iconURL, const String& tag, const String& language, WebCore::NotificationDirection direction, const String& originString, uint64_t notificationID)
 {
     m_webPageProxy.showNotification(title, body, iconURL, tag, language, direction, originString, notificationID);

Modified: trunk/Source/WebKit/UIProcess/Notifications/WebNotificationManagerMessageHandler.h (285120 => 285121)


--- trunk/Source/WebKit/UIProcess/Notifications/WebNotificationManagerMessageHandler.h	2021-11-01 19:22:52 UTC (rev 285120)
+++ trunk/Source/WebKit/UIProcess/Notifications/WebNotificationManagerMessageHandler.h	2021-11-01 19:31:45 UTC (rev 285121)
@@ -36,6 +36,7 @@
 private:
     explicit WebNotificationManagerMessageHandler(WebPageProxy&);
 
+    void requestSystemNotificationPermission(const String&, CompletionHandler<void(bool)>&&) final;
     void showNotification(const String& title, const String& body, const String& iconURL, const String& tag, const String& language, WebCore::NotificationDirection, const String& originString, uint64_t notificationID) final;
     void cancelNotification(uint64_t notificationID) final;
     void clearNotifications(const Vector<uint64_t>& notificationIDs) final;

Modified: trunk/Source/WebKit/WebProcess/Notifications/NotificationPermissionRequestManager.cpp (285120 => 285121)


--- trunk/Source/WebKit/WebProcess/Notifications/NotificationPermissionRequestManager.cpp	2021-11-01 19:22:52 UTC (rev 285120)
+++ trunk/Source/WebKit/WebProcess/Notifications/NotificationPermissionRequestManager.cpp	2021-11-01 19:31:45 UTC (rev 285121)
@@ -26,6 +26,7 @@
 #include "config.h"
 #include "NotificationPermissionRequestManager.h"
 
+#include "NotificationManagerMessageHandlerMessages.h"
 #include "WebCoreArgumentCoders.h"
 #include "WebPage.h"
 #include "WebPageProxyMessages.h"
@@ -80,11 +81,22 @@
     if (!addResult.isNewEntry)
         return;
 
-    m_page->sendWithAsyncReply(Messages::WebPageProxy::RequestNotificationPermission(securityOrigin.toString()), [this, protectedThis = Ref { *this }, permissionHandler = WTFMove(permissionHandler), securityOrigin](bool allowed) mutable {
-        WebProcess::singleton().supplement<WebNotificationManager>()->didUpdateNotificationDecision(securityOrigin.toString(), allowed);
+    m_page->sendWithAsyncReply(Messages::WebPageProxy::RequestNotificationPermission(securityOrigin.toString()), [this, protectedThis = Ref { *this }, securityOrigin, permissionHandler = WTFMove(permissionHandler)](bool allowed) mutable {
 
-        auto permissionHandlers = m_requestsPerOrigin.take(securityOrigin);
-        callPermissionHandlersWith(permissionHandlers, allowed ? Permission::Granted : Permission::Denied);
+        auto innerPermissionHandler = [this, protectedThis = Ref { *this }, securityOrigin, permissionHandler = WTFMove(permissionHandler)] (bool allowed) mutable {
+            WebProcess::singleton().supplement<WebNotificationManager>()->didUpdateNotificationDecision(securityOrigin.toString(), allowed);
+
+            auto permissionHandlers = m_requestsPerOrigin.take(securityOrigin);
+            callPermissionHandlersWith(permissionHandlers, allowed ? Permission::Granted : Permission::Denied);
+        };
+
+#if ENABLE(BUILT_IN_NOTIFICATIONS)
+        if (RuntimeEnabledFeatures::sharedFeatures().builtInNotificationsEnabled() && allowed) {
+            WebProcess::singleton().ensureNetworkProcessConnection().connection().sendWithAsyncReply(Messages::NotificationManagerMessageHandler::RequestSystemNotificationPermission(securityOrigin.toString()), WTFMove(innerPermissionHandler), m_page->sessionID().toUInt64());
+            return;
+        }
+#endif
+        innerPermissionHandler(allowed);
     });
 }
 

Modified: trunk/Source/WebKit/webpushd/WebPushDaemon.h (285120 => 285121)


--- trunk/Source/WebKit/webpushd/WebPushDaemon.h	2021-11-01 19:22:52 UTC (rev 285120)
+++ trunk/Source/WebKit/webpushd/WebPushDaemon.h	2021-11-01 19:31:45 UTC (rev 285121)
@@ -27,6 +27,7 @@
 
 #include "WebPushDaemonConstants.h"
 #include <wtf/Forward.h>
+#include <wtf/HashSet.h>
 #include <wtf/OSObjectPtr.h>
 #include <wtf/Span.h>
 #include <wtf/spi/darwin/XPCSPI.h>
@@ -48,6 +49,9 @@
 
     // Message handlers
     void echoTwice(const String&, CompletionHandler<void(const String&)>&& replySender);
+    void requestSystemNotificationPermission(const String&, CompletionHandler<void(bool)>&& replySender);
+    void getOriginsWithPushAndNotificationPermissions(CompletionHandler<void(const Vector<String>&)>&& replySender);
+    void deletePushAndNotificationRegistration(const String& originString, CompletionHandler<void(const String&)>&& replySender);
 
 private:
     Daemon() = default;
@@ -54,6 +58,8 @@
 
     CompletionHandler<void(EncodedMessage&&)> createReplySender(MessageType, OSObjectPtr<xpc_object_t>&& request);
     void decodeAndHandleMessage(MessageType, Span<const uint8_t> encodedMessage, CompletionHandler<void(EncodedMessage&&)>&&);
+
+    HashSet<String> m_inMemoryOriginStringsWithPermissionForTesting;
 };
 
 } // namespace WebPushD

Modified: trunk/Source/WebKit/webpushd/WebPushDaemon.mm (285120 => 285121)


--- trunk/Source/WebKit/webpushd/WebPushDaemon.mm	2021-11-01 19:22:52 UTC (rev 285120)
+++ trunk/Source/WebKit/webpushd/WebPushDaemon.mm	2021-11-01 19:31:45 UTC (rev 285121)
@@ -53,6 +53,21 @@
 REPLY(String)
 END
 
+FUNCTION(getOriginsWithPushAndNotificationPermissions)
+ARGUMENTS()
+REPLY(const Vector<String>&)
+END
+
+FUNCTION(deletePushAndNotificationRegistration)
+ARGUMENTS(String)
+REPLY(String)
+END
+
+FUNCTION(requestSystemNotificationPermission)
+ARGUMENTS(String)
+REPLY(bool)
+END
+
 #undef FUNCTION
 #undef ARGUMENTS
 #undef REPLY
@@ -65,6 +80,27 @@
     return encoder.takeBuffer();
 }
 
+WebPushD::EncodedMessage getOriginsWithPushAndNotificationPermissions::encodeReply(const Vector<String>& reply)
+{
+    WebKit::Daemon::Encoder encoder;
+    encoder << reply;
+    return encoder.takeBuffer();
+}
+
+WebPushD::EncodedMessage deletePushAndNotificationRegistration::encodeReply(String reply)
+{
+    WebKit::Daemon::Encoder encoder;
+    encoder << reply;
+    return encoder.takeBuffer();
+}
+
+WebPushD::EncodedMessage requestSystemNotificationPermission::encodeReply(bool reply)
+{
+    WebKit::Daemon::Encoder encoder;
+    encoder << reply;
+    return encoder.takeBuffer();
+}
+
 } // namespace MessageInfo
 
 template<typename Info>
@@ -141,6 +177,15 @@
     case MessageType::EchoTwice:
         handleWebPushDMessageWithReply<MessageInfo::echoTwice>(encodedMessage, WTFMove(replySender));
         break;
+    case MessageType::GetOriginsWithPushAndNotificationPermissions:
+        handleWebPushDMessageWithReply<MessageInfo::getOriginsWithPushAndNotificationPermissions>(encodedMessage, WTFMove(replySender));
+        break;
+    case MessageType::DeletePushAndNotificationRegistration:
+        handleWebPushDMessageWithReply<MessageInfo::deletePushAndNotificationRegistration>(encodedMessage, WTFMove(replySender));
+        break;
+    case MessageType::RequestSystemNotificationPermission:
+        handleWebPushDMessageWithReply<MessageInfo::requestSystemNotificationPermission>(encodedMessage, WTFMove(replySender));
+        break;
     }
 }
 
@@ -149,4 +194,29 @@
     replySender(makeString(message, message));
 }
 
+void Daemon::requestSystemNotificationPermission(const String& originString, CompletionHandler<void(bool)>&& replySender)
+{
+    // FIXME: This is for an API testing checkpoint
+    // Next step is actually perform a persistent permissions request on a per-platform basis
+    m_inMemoryOriginStringsWithPermissionForTesting.add(originString);
+    replySender(true);
+}
+
+void Daemon::getOriginsWithPushAndNotificationPermissions(CompletionHandler<void(const Vector<String>&)>&& replySender)
+{
+    // FIXME: This is for an API testing checkpoint
+    // Next step is actually gather persistent permissions from the system on a per-platform basis
+    replySender(copyToVector(m_inMemoryOriginStringsWithPermissionForTesting));
+}
+
+void Daemon::deletePushAndNotificationRegistration(const String& originString, CompletionHandler<void(const String&)>&& replySender)
+{
+    // FIXME: This is for an API testing checkpoint
+    // Next step is actually delete any persistent permissions on a per-platform basis
+    if (m_inMemoryOriginStringsWithPermissionForTesting.remove(originString))
+        replySender("");
+    else
+        replySender(makeString("Origin ", originString, " not registered for push or notifications"));
+}
+
 } // namespace WebPushD

Modified: trunk/Tools/ChangeLog (285120 => 285121)


--- trunk/Tools/ChangeLog	2021-11-01 19:22:52 UTC (rev 285120)
+++ trunk/Tools/ChangeLog	2021-11-01 19:31:45 UTC (rev 285121)
@@ -1,3 +1,15 @@
+2021-11-01  Brady Eidson  <beid...@apple.com>
+
+        webpushd: Add mock in-memory registration, and the WKWebsiteDataStore SPI to manage them
+        https://bugs.webkit.org/show_bug.cgi?id=232539
+
+        Reviewed by Alex Christensen.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/WebPushDaemon.mm:
+        (-[NotificationPermissionDelegate _webView:requestNotificationPermissionForSecurityOrigin:decisionHandler:]):
+        (-[NotificationPermissionDelegate webView:runJavaScriptAlertPanelWithMessage:initiatedByFrame:completionHandler:]):
+        (TestWebKitAPI::then):
+
 2021-11-01  Devin Rousso  <drou...@apple.com>
 
         [ iOS15 EWS ] TestWebKitAPI.CSSViewportUnits.SameUnobscuredSizeOverrides flaky fails on EWS

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WebPushDaemon.mm (285120 => 285121)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WebPushDaemon.mm	2021-11-01 19:22:52 UTC (rev 285120)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WebPushDaemon.mm	2021-11-01 19:31:45 UTC (rev 285121)
@@ -26,7 +26,30 @@
 #import "config.h"
 
 #import "DaemonTestUtilities.h"
+#import "TestURLSchemeHandler.h"
+#import "TestWKWebView.h"
+#import <WebKit/WKUIDelegatePrivate.h>
+#import <WebKit/_WKExperimentalFeature.h>
 
+static bool alertReceived = false;
+@interface NotificationPermissionDelegate : NSObject<WKUIDelegatePrivate>
+@end
+
+@implementation NotificationPermissionDelegate
+
+- (void)_webView:(WKWebView *)webView requestNotificationPermissionForSecurityOrigin:(WKSecurityOrigin *)securityOrigin decisionHandler:(void (^)(BOOL))decisionHandler
+{
+    decisionHandler(true);
+}
+
+- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler
+{
+    alertReceived = true;
+    completionHandler();
+}
+
+@end
+
 namespace TestWebKitAPI {
 
 // FIXME: Get this working in the iOS simulator.
@@ -147,6 +170,75 @@
     cleanUpTestWebPushD(tempDir);
 }
 
+static const char* mainBytes = R"WEBPUSHRESOURCE(
+<script>
+    Notification.requestPermission().then(() => { alert("done") })
+</script>
+)WEBPUSHRESOURCE";
+
+TEST(WebPushD, PermissionManagement)
+{
+    NSURL *tempDirectory = setUpTestWebPushD();
+
+    auto dataStoreConfiguration = adoptNS([_WKWebsiteDataStoreConfiguration new]);
+    dataStoreConfiguration.get().webPushMachServiceName = @"org.webkit.webpushtestdaemon.service";
+    auto dataStore = adoptNS([[WKWebsiteDataStore alloc] _initWithConfiguration:dataStoreConfiguration.get()]);
+
+    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+    configuration.get().websiteDataStore = dataStore.get();
+    for (_WKExperimentalFeature *feature in [WKPreferences _experimentalFeatures]) {
+        if ([feature.key isEqualToString:@"BuiltInNotificationsEnabled"])
+            [[configuration preferences] _setEnabled:YES forFeature:feature];
+    }
+
+    auto handler = adoptNS([[TestURLSchemeHandler alloc] init]);
+    [configuration setURLSchemeHandler:handler.get() forURLScheme:@"testing"];
+
+    [handler setStartURLSchemeTaskHandler:^(WKWebView *, id<WKURLSchemeTask> task) {
+        auto response = adoptNS([[NSURLResponse alloc] initWithURL:task.request.URL MIMEType:@"text/html" expectedContentLength:0 textEncodingName:nil]);
+        [task didReceiveResponse:response.get()];
+        [task didReceiveData:[NSData dataWithBytes:mainBytes length:strlen(mainBytes)]];
+        [task didFinish];
+    }];
+
+    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 800, 600) configuration:configuration.get()]);
+    auto uiDelegate = adoptNS([[NotificationPermissionDelegate alloc] init]);
+    [webView setUIDelegate:uiDelegate.get()];
+
+    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"testing://main/index.html"]]];
+    TestWebKitAPI::Util::run(&alertReceived);
+
+    static bool originOperationDone = false;
+    static RetainPtr<WKSecurityOrigin> origin;
+    [dataStore _getOriginsWithPushAndNotificationPermissions:^(NSSet<WKSecurityOrigin *> *origins) {
+        EXPECT_EQ([origins count], 1u);
+        origin = [origins anyObject];
+        originOperationDone = true;
+    }];
+
+    TestWebKitAPI::Util::run(&originOperationDone);
+
+    EXPECT_TRUE([origin.get().protocol isEqualToString:@"testing"]);
+    EXPECT_TRUE([origin.get().host isEqualToString:@"main"]);
+
+    originOperationDone = false;
+    [dataStore _deletePushAndNotificationRegistration:origin.get() completionHandler:^(NSError *error) {
+        EXPECT_FALSE(!!error);
+        originOperationDone = true;
+    }];
+
+    TestWebKitAPI::Util::run(&originOperationDone);
+
+    originOperationDone = false;
+    [dataStore _getOriginsWithPushAndNotificationPermissions:^(NSSet<WKSecurityOrigin *> *origins) {
+        EXPECT_EQ([origins count], 0u);
+        originOperationDone = true;
+    }];
+    TestWebKitAPI::Util::run(&originOperationDone);
+
+    cleanUpTestWebPushD(tempDirectory);
+}
+
 #endif // PLATFORM(MAC)
 
 } // namespace TestWebKitAPI
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to