Diff
Modified: trunk/Source/WebKit/ChangeLog (286272 => 286273)
--- trunk/Source/WebKit/ChangeLog 2021-11-30 00:20:30 UTC (rev 286272)
+++ trunk/Source/WebKit/ChangeLog 2021-11-30 00:20:57 UTC (rev 286273)
@@ -1,3 +1,96 @@
+2021-11-29 Brady Eidson <beid...@apple.com>
+
+ Make webpushd "fake registration for testing" much more complicated by adding a "mock app bundle" install
+ https://bugs.webkit.org/show_bug.cgi?id=233454
+
+ Reviewed by Alex Christensen.
+
+ Covered by API tests.
+
+ Before this patch, webpushd remembered "registrations" using a simple in-memory HashMap.
+
+ In the near future, registrations will actually be represented with a placeholder app bundle on disk.
+
+ The process of installing placeholders (and checking for existing ones) is complicated and asynchronous.
+
+ This patch shifts the in-memory testing implementation from a simple HashMap to a "complicated and asynchronous"
+ registration mechanism that simulates how app-bundle installs will work.
+
+ Once the "real" mechanisms are in place there will be much more in-depth testing that we can do.
+ For now, this is a "no behavior change" patch.
+
+ * NetworkProcess/Notifications/Cocoa/WebPushDaemonConnectionCocoa.mm:
+ (WebKit::WebPushD::Connection::connectionReceivedEvent const):
+ * UIProcess/API/Cocoa/WKUIDelegatePrivate.h:
+
+ * WebKit.xcodeproj/project.pbxproj:
+
+ "PushAppBundle" is an abstract base class for representing a placeholder application bundle for a registration.
+ Eventually there will be a native one for each platform that actually does system operations.
+ For now, the concrete implementation is the in-memory "Mock" app bundle.
+
+ * webpushd/PushAppBundle.h: Copied from Source/WebKit/webpushd/PushClientConnection.h.
+ * webpushd/PushAppBundle.mm: Copied from Source/WebKit/webpushd/PushClientConnection.h.
+ (WebPushD::PushAppBundleClient::~PushAppBundleClient):
+ (WebPushD::PushAppBundle::PushAppBundle):
+ (WebPushD::PushAppBundle::~PushAppBundle):
+ (WebPushD::PushAppBundle::detachFromClient):
+
+ An "AppBundleRequest" is a queable operation meant to do something with an "App bundle".
+ For now the operations are "create" and "delete"
+
+ * webpushd/AppBundleRequest.h: Added.
+ (WebPushD::AppBundleRequestImpl::AppBundleRequestImpl):
+ (WebPushD::AppBundleRequestImpl::~AppBundleRequestImpl):
+ (WebPushD::AppBundleRequestImpl::callCompletionHandlerAndCleanup):
+ (WebPushD::AppBundlePermissionsRequest::AppBundlePermissionsRequest):
+ (WebPushD::AppBundleDeletionRequest::AppBundleDeletionRequest):
+ * webpushd/AppBundleRequest.mm: Added.
+ (WebPushD::AppBundleRequest::AppBundleRequest):
+ (WebPushD::AppBundleRequest::~AppBundleRequest):
+ (WebPushD::AppBundleRequest::start):
+ (WebPushD::AppBundleRequest::cancel):
+ (WebPushD::AppBundleRequest::cleanupAfterCompletionHandler):
+ (WebPushD::AppBundlePermissionsRequest::startInternal):
+ (WebPushD::AppBundlePermissionsRequest::didCheckForExistingBundle):
+ (WebPushD::AppBundlePermissionsRequest::didCreateAppBundle):
+ (WebPushD::AppBundleDeletionRequest::startInternal):
+ (WebPushD::AppBundleDeletionRequest::didDeleteExistingBundleWithError):
+
+ * webpushd/MockAppBundleForTesting.h: Copied from Source/WebKit/webpushd/PushClientConnection.h.
+ (WebPushD::MockAppBundleForTesting::create):
+ * webpushd/MockAppBundleForTesting.mm: Added.
+ (WebPushD::MockAppBundleForTesting::MockAppBundleForTesting):
+ (WebPushD::MockAppBundleForTesting::~MockAppBundleForTesting):
+ (WebPushD::MockAppBundleForTesting::checkForExistingBundle):
+ (WebPushD::MockAppBundleForTesting::deleteExistingBundle):
+ (WebPushD::MockAppBundleForTesting::createBundle):
+ (WebPushD::MockAppBundleForTesting::stop):
+
+ * webpushd/MockAppBundleRegistry.h: Copied from Source/WebKit/webpushd/PushClientConnection.h.
+ * webpushd/MockAppBundleRegistry.mm: Added.
+ (WebPushD::MockAppBundleRegistry::singleton):
+ (WebPushD::MockAppBundleRegistry::getOriginsWithRegistrations):
+ (WebPushD::MockAppBundleRegistry::doesBundleExist):
+ (WebPushD::MockAppBundleRegistry::createBundle):
+ (WebPushD::MockAppBundleRegistry::deleteBundle):
+
+ * webpushd/PushClientConnection.h:
+ * webpushd/PushClientConnection.mm:
+ (WebPushD::ClientConnection::create):
+ (WebPushD::ClientConnection::enqueueAppBundleRequest):
+ (WebPushD::ClientConnection::maybeStartNextAppBundleRequest):
+ (WebPushD::ClientConnection::didCompleteAppBundleRequest):
+ (WebPushD::ClientConnection::connectionClosed):
+
+ * webpushd/WebPushDaemon.h:
+ * webpushd/WebPushDaemon.mm:
+ (WebPushD::Daemon::connectionAdded):
+ (WebPushD::Daemon::connectionRemoved):
+ (WebPushD::Daemon::requestSystemNotificationPermission):
+ (WebPushD::Daemon::getOriginsWithPushAndNotificationPermissions):
+ (WebPushD::Daemon::deletePushAndNotificationRegistration):
+
2021-11-29 David Kilzer <ddkil...@apple.com>
Disable experimental web features on platforms without UI to enable them
Modified: trunk/Source/WebKit/NetworkProcess/Notifications/Cocoa/WebPushDaemonConnectionCocoa.mm (286272 => 286273)
--- trunk/Source/WebKit/NetworkProcess/Notifications/Cocoa/WebPushDaemonConnectionCocoa.mm 2021-11-30 00:20:30 UTC (rev 286272)
+++ trunk/Source/WebKit/NetworkProcess/Notifications/Cocoa/WebPushDaemonConnectionCocoa.mm 2021-11-30 00:20:57 UTC (rev 286273)
@@ -61,7 +61,7 @@
if (!debugMessage)
return;
auto messageLevel = static_cast<JSC::MessageLevel>(xpc_dictionary_get_uint64(request, protocolDebugMessageLevelKey));
- networkSession().networkProcess().broadcastConsoleMessage(networkSession().sessionID(), MessageSource::PrivateClickMeasurement, messageLevel, String::fromUTF8(debugMessage));
+ networkSession().networkProcess().broadcastConsoleMessage(networkSession().sessionID(), MessageSource::Other, messageLevel, String::fromUTF8(debugMessage));
}
RetainPtr<xpc_object_t> Connection::dictionaryFromMessage(MessageType messageType, EncodedMessage&& message) const
Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKUIDelegatePrivate.h (286272 => 286273)
--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKUIDelegatePrivate.h 2021-11-30 00:20:30 UTC (rev 286272)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKUIDelegatePrivate.h 2021-11-30 00:20:57 UTC (rev 286273)
@@ -159,7 +159,7 @@
- (void)_webViewDidDisableInspectorBrowserDomain:(WKWebView *)webView WK_API_AVAILABLE(macos(12.0), ios(15.0));
- (void)_webView:(WKWebView *)webView startXRSessionWithCompletionHandler:(void (^)(id))completionHandler WK_API_AVAILABLE(macos(12.0), ios(15.0));
-- (void)_webView:(WKWebView *)webView requestNotificationPermissionForSecurityOrigin:(WKSecurityOrigin *)securityOrigin decisionHandler:(void (^)(BOOL))decisionHandler WK_API_AVAILABLE(macos(10.13.4));
+- (void)_webView:(WKWebView *)webView requestNotificationPermissionForSecurityOrigin:(WKSecurityOrigin *)securityOrigin decisionHandler:(void (^)(BOOL))decisionHandler WK_API_AVAILABLE(macos(10.13.4), ios(WK_IOS_TBA));
#if TARGET_OS_IPHONE
Modified: trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj (286272 => 286273)
--- trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj 2021-11-30 00:20:30 UTC (rev 286272)
+++ trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj 2021-11-30 00:20:57 UTC (rev 286273)
@@ -1005,6 +1005,12 @@
515BE1AB1D555AA000DD7C68 /* WebGamepad.h in Headers */ = {isa = PBXBuildFile; fileRef = 515BE1A01D550AB000DD7C68 /* WebGamepad.h */; };
515BE1B31D5902DD00DD7C68 /* GamepadData.h in Headers */ = {isa = PBXBuildFile; fileRef = 515BE1B01D59006900DD7C68 /* GamepadData.h */; };
515BE1B51D5917FF00DD7C68 /* UIGamepad.h in Headers */ = {isa = PBXBuildFile; fileRef = 515BE1AD1D555C5100DD7C68 /* UIGamepad.h */; };
+ 5160E955274B887200567388 /* AppBundleRequest.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5160E953274B887100567388 /* AppBundleRequest.mm */; };
+ 5160E956274B887200567388 /* AppBundleRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = 5160E954274B887100567388 /* AppBundleRequest.h */; };
+ 5160E959274C0D8900567388 /* PushAppBundle.h in Headers */ = {isa = PBXBuildFile; fileRef = 5160E957274C0D8800567388 /* PushAppBundle.h */; };
+ 5160E95A274C0D8900567388 /* PushAppBundle.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5160E958274C0D8800567388 /* PushAppBundle.mm */; };
+ 5160E95E274C2A0300567388 /* MockAppBundleRegistry.h in Headers */ = {isa = PBXBuildFile; fileRef = 5160E95C274C2A0300567388 /* MockAppBundleRegistry.h */; };
+ 5160E960274C2A4000567388 /* MockAppBundleRegistry.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5160E95F274C2A3F00567388 /* MockAppBundleRegistry.mm */; };
5163199416289A6000E22F00 /* NetworkProcessMessageReceiver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51ACC9341628064800342550 /* NetworkProcessMessageReceiver.cpp */; };
5163199516289A6300E22F00 /* NetworkProcessMessages.h in Headers */ = {isa = PBXBuildFile; fileRef = 51ACC9351628064800342550 /* NetworkProcessMessages.h */; };
516A4A5D120A2CCD00C05B7F /* APIError.h in Headers */ = {isa = PBXBuildFile; fileRef = 516A4A5B120A2CCD00C05B7F /* APIError.h */; };
@@ -1056,6 +1062,8 @@
51F060E11654318500F3282E /* NetworkRTCProviderMessageReceiver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51F060DD1654317500F3282E /* NetworkRTCProviderMessageReceiver.cpp */; };
51F060E11654318500F3282F /* WebMDNSRegisterMessageReceiver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51F060DD1654317500F3282F /* WebMDNSRegisterMessageReceiver.cpp */; };
51F060E11654318500F3283F /* NetworkMDNSRegisterMessageReceiver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51F060DD1654317500F3283F /* NetworkMDNSRegisterMessageReceiver.cpp */; };
+ 51F7BB76274498BB00C45A72 /* MockAppBundleForTesting.mm in Sources */ = {isa = PBXBuildFile; fileRef = 51F7BB74274498BA00C45A72 /* MockAppBundleForTesting.mm */; };
+ 51F7BB77274498BB00C45A72 /* MockAppBundleForTesting.h in Headers */ = {isa = PBXBuildFile; fileRef = 51F7BB75274498BB00C45A72 /* MockAppBundleForTesting.h */; };
51F7BB7B2744C50700C45A72 /* PushClientConnection.h in Headers */ = {isa = PBXBuildFile; fileRef = 51F7BB792744C50700C45A72 /* PushClientConnection.h */; };
51F7BB7C2744C50700C45A72 /* PushClientConnection.mm in Sources */ = {isa = PBXBuildFile; fileRef = 51F7BB7A2744C50700C45A72 /* PushClientConnection.mm */; };
51F7BB7D2745640400C45A72 /* CodeSigning.mm in Sources */ = {isa = PBXBuildFile; fileRef = CE11AD4F1CBC47F800681EE5 /* CodeSigning.mm */; };
@@ -4338,6 +4346,12 @@
515C415A207D74E000726E02 /* SuspendedPageProxy.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SuspendedPageProxy.cpp; sourceTree = "<group>"; };
515C415B207D74E100726E02 /* SuspendedPageProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SuspendedPageProxy.h; sourceTree = "<group>"; };
5160BFE013381DF900918999 /* LoggingFoundation.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = LoggingFoundation.mm; sourceTree = "<group>"; };
+ 5160E953274B887100567388 /* AppBundleRequest.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AppBundleRequest.mm; sourceTree = "<group>"; };
+ 5160E954274B887100567388 /* AppBundleRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppBundleRequest.h; sourceTree = "<group>"; };
+ 5160E957274C0D8800567388 /* PushAppBundle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PushAppBundle.h; sourceTree = "<group>"; };
+ 5160E958274C0D8800567388 /* PushAppBundle.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PushAppBundle.mm; sourceTree = "<group>"; };
+ 5160E95C274C2A0300567388 /* MockAppBundleRegistry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MockAppBundleRegistry.h; sourceTree = "<group>"; };
+ 5160E95F274C2A3F00567388 /* MockAppBundleRegistry.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MockAppBundleRegistry.mm; sourceTree = "<group>"; };
5164C0941B05B757004F102A /* AuxiliaryProcess.messages.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = AuxiliaryProcess.messages.in; sourceTree = "<group>"; };
516A4A5B120A2CCD00C05B7F /* APIError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = APIError.h; sourceTree = "<group>"; };
517A33B3130B308C00F80CB5 /* WKApplicationCacheManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WKApplicationCacheManager.cpp; sourceTree = "<group>"; };
@@ -4445,6 +4459,8 @@
51F060DD1654317500F3282F /* WebMDNSRegisterMessageReceiver.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = WebMDNSRegisterMessageReceiver.cpp; path = DerivedSources/WebKit2/WebMDNSRegisterMessageReceiver.cpp; sourceTree = BUILT_PRODUCTS_DIR; };
51F060DD1654317500F3283F /* NetworkMDNSRegisterMessageReceiver.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = NetworkMDNSRegisterMessageReceiver.cpp; path = DerivedSources/WebKit2/NetworkMDNSRegisterMessageReceiver.cpp; sourceTree = BUILT_PRODUCTS_DIR; };
51F060DE1654317500F3281B /* WebResourceLoaderMessages.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = WebResourceLoaderMessages.h; path = DerivedSources/WebKit2/WebResourceLoaderMessages.h; sourceTree = BUILT_PRODUCTS_DIR; };
+ 51F7BB74274498BA00C45A72 /* MockAppBundleForTesting.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MockAppBundleForTesting.mm; sourceTree = "<group>"; };
+ 51F7BB75274498BB00C45A72 /* MockAppBundleForTesting.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MockAppBundleForTesting.h; sourceTree = "<group>"; };
51F7BB792744C50700C45A72 /* PushClientConnection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PushClientConnection.h; sourceTree = "<group>"; };
51F7BB7A2744C50700C45A72 /* PushClientConnection.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PushClientConnection.mm; sourceTree = "<group>"; };
51F7BB7E274564A100C45A72 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };
@@ -9858,6 +9874,14 @@
isa = PBXGroup;
children = (
5CBB6D4D271F67CC00FD1A5D /* com.apple.webkit.webpushd.plist */,
+ 5160E954274B887100567388 /* AppBundleRequest.h */,
+ 5160E953274B887100567388 /* AppBundleRequest.mm */,
+ 51F7BB75274498BB00C45A72 /* MockAppBundleForTesting.h */,
+ 51F7BB74274498BA00C45A72 /* MockAppBundleForTesting.mm */,
+ 5160E95C274C2A0300567388 /* MockAppBundleRegistry.h */,
+ 5160E95F274C2A3F00567388 /* MockAppBundleRegistry.mm */,
+ 5160E957274C0D8800567388 /* PushAppBundle.h */,
+ 5160E958274C0D8800567388 /* PushAppBundle.mm */,
51F7BB792744C50700C45A72 /* PushClientConnection.h */,
51F7BB7A2744C50700C45A72 /* PushClientConnection.mm */,
512CD69D2723393A00F7F8EC /* WebPushDaemon.h */,
@@ -12399,9 +12423,13 @@
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
+ 5160E959274C0D8900567388 /* PushAppBundle.h in Headers */,
+ 51F7BB7B2744C50700C45A72 /* PushClientConnection.h in Headers */,
+ 5160E95E274C2A0300567388 /* MockAppBundleRegistry.h in Headers */,
5C1579FC2717AF5000ED5280 /* DaemonUtilities.h in Headers */,
- 51F7BB7B2744C50700C45A72 /* PushClientConnection.h in Headers */,
+ 5160E956274B887200567388 /* AppBundleRequest.h in Headers */,
512CD69F2723393A00F7F8EC /* WebPushDaemon.h in Headers */,
+ 51F7BB77274498BB00C45A72 /* MockAppBundleForTesting.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -14938,9 +14966,13 @@
5C157A012717B7FB00ED5280 /* ArgumentCoders.cpp in Sources */,
51F7BB7D2745640400C45A72 /* CodeSigning.mm in Sources */,
5C1579FF2717B6D200ED5280 /* DaemonDecoder.cpp in Sources */,
+ 51F7BB76274498BB00C45A72 /* MockAppBundleForTesting.mm in Sources */,
+ 5160E955274B887200567388 /* AppBundleRequest.mm in Sources */,
+ 5160E95A274C0D8900567388 /* PushAppBundle.mm in Sources */,
+ 5160E960274C2A4000567388 /* MockAppBundleRegistry.mm in Sources */,
+ 51F7BB7C2744C50700C45A72 /* PushClientConnection.mm in Sources */,
5C1579FE2717B6C100ED5280 /* DaemonEncoder.cpp in Sources */,
5C1579FB2717AF5000ED5280 /* DaemonUtilities.mm in Sources */,
- 51F7BB7C2744C50700C45A72 /* PushClientConnection.mm in Sources */,
512CD6A02723393A00F7F8EC /* WebPushDaemon.mm in Sources */,
5C157A0C2717CA1D00ED5280 /* WebPushDaemonMain.mm in Sources */,
);
Added: trunk/Source/WebKit/webpushd/AppBundleRequest.h (0 => 286273)
--- trunk/Source/WebKit/webpushd/AppBundleRequest.h (rev 0)
+++ trunk/Source/WebKit/webpushd/AppBundleRequest.h 2021-11-30 00:20:57 UTC (rev 286273)
@@ -0,0 +1,125 @@
+/*
+ * 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
+
+#import "PushAppBundle.h"
+#import "PushClientConnection.h"
+#import <wtf/CompletionHandler.h>
+#import <wtf/OSObjectPtr.h>
+#import <wtf/spi/darwin/XPCSPI.h>
+#import <wtf/text/WTFString.h>
+
+namespace WebPushD {
+
+class PushAppBundle;
+class ClientConnection;
+
+class AppBundleRequest : public PushAppBundleClient {
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ virtual ~AppBundleRequest();
+
+ virtual const char* transactionDescription() const = 0;
+
+ void start();
+ void cancel();
+
+protected:
+ AppBundleRequest(ClientConnection&, const String& originString);
+
+ void cleanupAfterCompletionHandler();
+
+ WeakPtr<ClientConnection> m_connection;
+ String m_originString;
+ RefPtr<PushAppBundle> m_appBundle;
+ OSObjectPtr<os_transaction_t> m_transaction;
+
+private:
+ virtual void startInternal() = 0;
+};
+
+template<typename CompletionType>
+class AppBundleRequestImpl : public AppBundleRequest {
+protected:
+ AppBundleRequestImpl(ClientConnection& connection, const String& originString, CompletionHandler<void(CompletionType)>&& completionHandler)
+ : AppBundleRequest(connection, originString)
+ , m_completionHandler(WTFMove(completionHandler))
+ {
+ }
+
+ virtual ~AppBundleRequestImpl()
+ {
+ ASSERT(!m_appBundle);
+ }
+
+ void callCompletionHandlerAndCleanup(CompletionType result)
+ {
+ ASSERT(m_completionHandler);
+ m_completionHandler(result);
+
+ cleanupAfterCompletionHandler();
+ }
+
+ virtual void startInternal() = 0;
+ virtual const char* transactionDescription() const = 0;
+
+private:
+ CompletionHandler<void(CompletionType)> m_completionHandler;
+};
+
+class AppBundlePermissionsRequest : public AppBundleRequestImpl<bool> {
+public:
+ AppBundlePermissionsRequest(ClientConnection& connection, const String& originString, CompletionHandler<void(bool)>&& completionHandler)
+ : AppBundleRequestImpl(connection, originString, WTFMove(completionHandler))
+ {
+ }
+
+private:
+ const char* transactionDescription() const final { return "WebPush Permissions Bundle Request"; }
+
+ void startInternal() final;
+ void didCheckForExistingBundle(PushAppBundle&, PushAppBundleExists) final;
+ void didDeleteExistingBundleWithError(PushAppBundle&, NSError *) final { RELEASE_ASSERT_NOT_REACHED(); }
+ void didCreateAppBundle(PushAppBundle&, PushAppBundleCreationResult) final;
+};
+
+class AppBundleDeletionRequest : public AppBundleRequestImpl<const String&> {
+public:
+ AppBundleDeletionRequest(ClientConnection& connection, const String& originString, CompletionHandler<void(const String&)>&& completionHandler)
+ : AppBundleRequestImpl(connection, originString, WTFMove(completionHandler))
+ {
+ }
+
+private:
+ const char* transactionDescription() const final { return "WebPush Bundle Deletion Request"; }
+
+ void startInternal() final;
+ void didCheckForExistingBundle(PushAppBundle&, PushAppBundleExists) final { RELEASE_ASSERT_NOT_REACHED(); }
+ void didDeleteExistingBundleWithError(PushAppBundle&, NSError *) final;
+ void didCreateAppBundle(PushAppBundle&, PushAppBundleCreationResult) final { RELEASE_ASSERT_NOT_REACHED(); }
+};
+
+} // namespace WebPushD
Added: trunk/Source/WebKit/webpushd/AppBundleRequest.mm (0 => 286273)
--- trunk/Source/WebKit/webpushd/AppBundleRequest.mm (rev 0)
+++ trunk/Source/WebKit/webpushd/AppBundleRequest.mm 2021-11-30 00:20:57 UTC (rev 286273)
@@ -0,0 +1,123 @@
+/*
+ * 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 "AppBundleRequest.h"
+
+#import "MockAppBundleForTesting.h"
+#import "WebPushDaemon.h"
+#import <_javascript_Core/ConsoleTypes.h>
+
+namespace WebPushD {
+
+AppBundleRequest::AppBundleRequest(ClientConnection& connection, const String& originString)
+ : m_connection(&connection)
+ , m_originString(originString)
+{
+}
+
+AppBundleRequest::~AppBundleRequest()
+{
+ ASSERT(!m_appBundle);
+}
+
+void AppBundleRequest::start()
+{
+ ASSERT(m_connection);
+
+ m_transaction = adoptOSObject(os_transaction_create(transactionDescription()));
+
+ m_appBundle = MockAppBundleForTesting::create(m_originString, m_connection->hostAppCodeSigningIdentifier(), *this);
+ startInternal();
+}
+
+void AppBundleRequest::cancel()
+{
+ ASSERT(m_connection);
+
+ if (m_appBundle) {
+ m_appBundle->stop();
+ m_appBundle = nullptr;
+ }
+}
+
+void AppBundleRequest::cleanupAfterCompletionHandler()
+{
+ if (m_appBundle) {
+ m_appBundle->detachFromClient();
+ m_appBundle = nullptr;
+ }
+
+ m_transaction = nullptr;
+
+ if (m_connection)
+ m_connection->didCompleteAppBundleRequest(*this);
+}
+
+// App bundle permissions
+
+void AppBundlePermissionsRequest::startInternal()
+{
+ m_appBundle->checkForExistingBundle();
+}
+
+void AppBundlePermissionsRequest::didCheckForExistingBundle(PushAppBundle& bundle, PushAppBundleExists exists)
+{
+ ASSERT_UNUSED(bundle, &bundle == m_appBundle.get());
+
+ if (exists == PushAppBundleExists::Yes)
+ return callCompletionHandlerAndCleanup(true);
+
+ m_appBundle->createBundle();
+}
+
+void AppBundlePermissionsRequest::didCreateAppBundle(PushAppBundle& bundle, PushAppBundleCreationResult result)
+{
+ ASSERT_UNUSED(bundle, &bundle == m_appBundle.get());
+
+ if (result == PushAppBundleCreationResult::Failure)
+ return callCompletionHandlerAndCleanup(false);
+
+ callCompletionHandlerAndCleanup(true);
+}
+
+// App bundle deletion
+
+void AppBundleDeletionRequest::startInternal()
+{
+ m_appBundle->deleteExistingBundle();
+}
+
+void AppBundleDeletionRequest::didDeleteExistingBundleWithError(PushAppBundle& bundle, NSError *error)
+{
+ ASSERT_UNUSED(bundle, &bundle == m_appBundle.get());
+
+ if (error)
+ Daemon::singleton().broadcastDebugMessage(MessageLevel::Info, makeString("Failed to delete app bundle: ", String([error description])));
+
+ callCompletionHandlerAndCleanup(error ? String([error description]) : "");
+}
+
+} // namespace WebPushD
Copied: trunk/Source/WebKit/webpushd/MockAppBundleForTesting.h (from rev 286272, trunk/Source/WebKit/webpushd/PushClientConnection.h) (0 => 286273)
--- trunk/Source/WebKit/webpushd/MockAppBundleForTesting.h (rev 0)
+++ trunk/Source/WebKit/webpushd/MockAppBundleForTesting.h 2021-11-30 00:20:57 UTC (rev 286273)
@@ -0,0 +1,57 @@
+/*
+ * 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 "PushAppBundle.h"
+#include <wtf/Vector.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebPushD {
+
+class MockAppBundleForTesting : public PushAppBundle {
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ static Ref<MockAppBundleForTesting> create(const String& originString, const String& hostAppBundleIdentifier, PushAppBundleClient& client)
+ {
+ return adoptRef(*new MockAppBundleForTesting(originString, hostAppBundleIdentifier, client));
+ }
+
+ ~MockAppBundleForTesting() final = default;
+
+private:
+ MockAppBundleForTesting(const String& originString, const String& hostAppBundleIdentifier, PushAppBundleClient&);
+
+ void checkForExistingBundle() final;
+ void deleteExistingBundle() final;
+ void createBundle() final;
+ void stop() final;
+
+ String m_originString;
+ String m_hostAppBundleIdentifier;
+};
+
+
+} // namespace WebPushD
Added: trunk/Source/WebKit/webpushd/MockAppBundleForTesting.mm (0 => 286273)
--- trunk/Source/WebKit/webpushd/MockAppBundleForTesting.mm (rev 0)
+++ trunk/Source/WebKit/webpushd/MockAppBundleForTesting.mm 2021-11-30 00:20:57 UTC (rev 286273)
@@ -0,0 +1,72 @@
+/*
+ * 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 "MockAppBundleForTesting.h"
+
+#import "MockAppBundleRegistry.h"
+#import <wtf/MainThread.h>
+
+namespace WebPushD {
+
+MockAppBundleForTesting::MockAppBundleForTesting(const String& originString, const String& hostAppBundleIdentifier, PushAppBundleClient& client)
+ : PushAppBundle(client)
+ , m_originString(originString)
+ , m_hostAppBundleIdentifier(hostAppBundleIdentifier)
+{
+}
+
+void MockAppBundleForTesting::checkForExistingBundle()
+{
+ callOnMainRunLoop([protectedThis = Ref { *this }, this] {
+ bool exists = MockAppBundleRegistry::singleton().doesBundleExist(m_hostAppBundleIdentifier, m_originString);
+ if (m_client)
+ m_client->didCheckForExistingBundle(*this, exists ? PushAppBundleExists::Yes : PushAppBundleExists::No);
+ });
+}
+
+void MockAppBundleForTesting::deleteExistingBundle()
+{
+ callOnMainRunLoop([protectedThis = Ref { *this }, this] {
+ MockAppBundleRegistry::singleton().deleteBundle(m_hostAppBundleIdentifier, m_originString);
+ if (m_client)
+ m_client->didDeleteExistingBundleWithError(*this, nil);
+ });
+}
+
+void MockAppBundleForTesting::createBundle()
+{
+ callOnMainRunLoop([protectedThis = Ref { *this }, this] {
+ MockAppBundleRegistry::singleton().createBundle(m_hostAppBundleIdentifier, m_originString);
+ if (m_client)
+ m_client->didCreateAppBundle(*this, PushAppBundleCreationResult::Success);
+ });
+}
+
+void MockAppBundleForTesting::stop()
+{
+}
+
+} // namespace WebPushD
Copied: trunk/Source/WebKit/webpushd/MockAppBundleRegistry.h (from rev 286272, trunk/Source/WebKit/webpushd/PushClientConnection.h) (0 => 286273)
--- trunk/Source/WebKit/webpushd/MockAppBundleRegistry.h (rev 0)
+++ trunk/Source/WebKit/webpushd/MockAppBundleRegistry.h 2021-11-30 00:20:57 UTC (rev 286273)
@@ -0,0 +1,52 @@
+/*
+ * 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/HashSet.h>
+#include <wtf/text/StringHash.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebPushD {
+
+class MockAppBundleForTesting;
+
+class MockAppBundleRegistry {
+ friend class MockAppBundleForTesting;
+public:
+ static MockAppBundleRegistry& singleton();
+
+ Vector<String> getOriginsWithRegistrations(const String& hostAppBundleIdentifier);
+
+private:
+ bool doesBundleExist(const String& hostAppBundleIdentifier, const String& originString);
+ void createBundle(const String& hostAppBundleIdentifier, const String& originString);
+ void deleteBundle(const String& hostAppBundleIdentifier, const String& originString);
+
+ HashMap<String, HashSet<String>> m_registeredBundleMap;
+};
+
+} // namespace WebPushD
Added: trunk/Source/WebKit/webpushd/MockAppBundleRegistry.mm (0 => 286273)
--- trunk/Source/WebKit/webpushd/MockAppBundleRegistry.mm (rev 0)
+++ trunk/Source/WebKit/webpushd/MockAppBundleRegistry.mm 2021-11-30 00:20:57 UTC (rev 286273)
@@ -0,0 +1,71 @@
+/*
+ * 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 "MockAppBundleRegistry.h"
+
+#import <wtf/NeverDestroyed.h>
+
+namespace WebPushD {
+
+MockAppBundleRegistry& MockAppBundleRegistry::singleton()
+{
+ static NeverDestroyed<MockAppBundleRegistry> registry;
+ return registry;
+}
+
+Vector<String> MockAppBundleRegistry::getOriginsWithRegistrations(const String& hostAppBundleIdentifier)
+{
+ Vector<String> results;
+ auto iterator = m_registeredBundleMap.find(hostAppBundleIdentifier);
+ if (iterator != m_registeredBundleMap.end())
+ results = copyToVector(iterator->value);
+ return results;
+}
+
+bool MockAppBundleRegistry::doesBundleExist(const String& hostAppBundleIdentifier, const String& originString)
+{
+ auto iterator = m_registeredBundleMap.find(hostAppBundleIdentifier);
+ return iterator != m_registeredBundleMap.end() && iterator->value.contains(originString);
+}
+
+void MockAppBundleRegistry::createBundle(const String& hostAppBundleIdentifier, const String& originString)
+{
+ m_registeredBundleMap.add(hostAppBundleIdentifier, HashSet<String> { }).iterator->value.add(originString);
+}
+
+void MockAppBundleRegistry::deleteBundle(const String& hostAppBundleIdentifier, const String& originString)
+{
+ auto iterator = m_registeredBundleMap.find(hostAppBundleIdentifier);
+ if (iterator == m_registeredBundleMap.end())
+ return;
+
+ iterator->value.remove(originString);
+
+ if (iterator->value.isEmpty())
+ m_registeredBundleMap.remove(iterator);
+}
+
+} // namespace WebPushD
Copied: trunk/Source/WebKit/webpushd/PushAppBundle.h (from rev 286272, trunk/Source/WebKit/webpushd/PushClientConnection.h) (0 => 286273)
--- trunk/Source/WebKit/webpushd/PushAppBundle.h (rev 0)
+++ trunk/Source/WebKit/webpushd/PushAppBundle.h 2021-11-30 00:20:57 UTC (rev 286273)
@@ -0,0 +1,72 @@
+/*
+ * 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/RefCounted.h>
+
+@class NSError;
+
+namespace WebPushD {
+
+enum class PushAppBundleExists : bool {
+ No,
+ Yes,
+};
+
+enum class PushAppBundleCreationResult : bool {
+ Failure,
+ Success,
+};
+
+class PushAppBundle;
+
+class PushAppBundleClient {
+public:
+ virtual ~PushAppBundleClient();
+
+ virtual void didCheckForExistingBundle(PushAppBundle&, PushAppBundleExists) = 0;
+ virtual void didDeleteExistingBundleWithError(PushAppBundle&, NSError *) = 0;
+ virtual void didCreateAppBundle(PushAppBundle&, PushAppBundleCreationResult) = 0;
+};
+
+class PushAppBundle : public RefCounted<PushAppBundle> {
+public:
+ virtual ~PushAppBundle();
+ void detachFromClient();
+
+ virtual void checkForExistingBundle() = 0;
+ virtual void deleteExistingBundle() = 0;
+ virtual void createBundle() = 0;
+ virtual void stop() = 0;
+
+protected:
+ PushAppBundle(PushAppBundleClient&);
+
+ PushAppBundleClient* m_client;
+};
+
+
+} // namespace WebPushD
Copied: trunk/Source/WebKit/webpushd/PushAppBundle.mm (from rev 286272, trunk/Source/WebKit/webpushd/PushClientConnection.h) (0 => 286273)
--- trunk/Source/WebKit/webpushd/PushAppBundle.mm (rev 0)
+++ trunk/Source/WebKit/webpushd/PushAppBundle.mm 2021-11-30 00:20:57 UTC (rev 286273)
@@ -0,0 +1,51 @@
+/*
+ * 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 "PushAppBundle.h"
+
+namespace WebPushD {
+
+PushAppBundleClient::~PushAppBundleClient()
+{
+}
+
+PushAppBundle::PushAppBundle(PushAppBundleClient& client)
+ : m_client(&client)
+{
+}
+
+PushAppBundle::~PushAppBundle()
+{
+ ASSERT(!m_client);
+}
+
+void PushAppBundle::detachFromClient()
+{
+ stop();
+ m_client = nullptr;
+}
+
+} // namespace WebPushD
Modified: trunk/Source/WebKit/webpushd/PushClientConnection.h (286272 => 286273)
--- trunk/Source/WebKit/webpushd/PushClientConnection.h 2021-11-30 00:20:30 UTC (rev 286272)
+++ trunk/Source/WebKit/webpushd/PushClientConnection.h 2021-11-30 00:20:57 UTC (rev 286273)
@@ -26,17 +26,22 @@
#pragma once
#include <optional>
+#include <wtf/Deque.h>
#include <wtf/Forward.h>
#include <wtf/OSObjectPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/WeakPtr.h>
#include <wtf/spi/darwin/XPCSPI.h>
#include <wtf/text/WTFString.h>
namespace WebPushD {
-class ClientConnection {
+class AppBundleRequest;
+
+class ClientConnection : public RefCounted<ClientConnection>, public CanMakeWeakPtr<ClientConnection> {
WTF_MAKE_FAST_ALLOCATED;
public:
- ClientConnection(xpc_connection_t);
+ static Ref<ClientConnection> create(xpc_connection_t);
bool hasHostAppAuditToken() const { return !!m_hostAppAuditToken; }
void setHostAppAuditTokenData(const Vector<uint8_t>&);
@@ -47,7 +52,16 @@
bool debugModeIsEnabled() const { return m_debugModeEnabled; }
void setDebugModeIsEnabled(bool);
+ void enqueueAppBundleRequest(std::unique_ptr<AppBundleRequest>&&);
+ void didCompleteAppBundleRequest(AppBundleRequest&);
+
+ void connectionClosed();
+
private:
+ ClientConnection(xpc_connection_t);
+
+ void maybeStartNextAppBundleRequest();
+
OSObjectPtr<xpc_connection_t> m_xpcConnection;
std::optional<audit_token_t> m_hostAppAuditToken;
@@ -54,6 +68,9 @@
std::optional<String> m_hostAppCodeSigningIdentifier;
std::optional<bool> m_hostAppHasPushEntitlement;
+ Deque<std::unique_ptr<AppBundleRequest>> m_pendingBundleRequests;
+ std::unique_ptr<AppBundleRequest> m_currentBundleRequest;
+
bool m_debugModeEnabled { false };
};
Modified: trunk/Source/WebKit/webpushd/PushClientConnection.mm (286272 => 286273)
--- trunk/Source/WebKit/webpushd/PushClientConnection.mm 2021-11-30 00:20:30 UTC (rev 286272)
+++ trunk/Source/WebKit/webpushd/PushClientConnection.mm 2021-11-30 00:20:57 UTC (rev 286273)
@@ -26,6 +26,7 @@
#import "config.h"
#import "PushClientConnection.h"
+#import "AppBundleRequest.h"
#import "CodeSigning.h"
#import "WebPushDaemon.h"
#import <_javascript_Core/ConsoleTypes.h>
@@ -34,6 +35,11 @@
namespace WebPushD {
+Ref<ClientConnection> ClientConnection::create(xpc_connection_t connection)
+{
+ return adoptRef(*new ClientConnection(connection));
+}
+
ClientConnection::ClientConnection(xpc_connection_t connection)
: m_xpcConnection(connection)
{
@@ -93,4 +99,49 @@
Daemon::singleton().broadcastDebugMessage(MessageLevel::Info, message);
}
+void ClientConnection::enqueueAppBundleRequest(std::unique_ptr<AppBundleRequest>&& request)
+{
+ RELEASE_ASSERT(m_xpcConnection);
+ m_pendingBundleRequests.append(WTFMove(request));
+ maybeStartNextAppBundleRequest();
+}
+
+void ClientConnection::maybeStartNextAppBundleRequest()
+{
+ RELEASE_ASSERT(m_xpcConnection);
+
+ if (m_currentBundleRequest || m_pendingBundleRequests.isEmpty())
+ return;
+
+ m_currentBundleRequest = m_pendingBundleRequests.takeFirst();
+ m_currentBundleRequest->start();
+}
+
+void ClientConnection::didCompleteAppBundleRequest(AppBundleRequest& request)
+{
+ // If our connection was closed there should be no in-progress bundle requests.
+ RELEASE_ASSERT(m_xpcConnection);
+
+ ASSERT(m_currentBundleRequest.get() == &request);
+ m_currentBundleRequest = nullptr;
+
+ maybeStartNextAppBundleRequest();
+}
+
+void ClientConnection::connectionClosed()
+{
+ RELEASE_ASSERT(m_xpcConnection);
+ m_xpcConnection = nullptr;
+
+ if (m_currentBundleRequest) {
+ m_currentBundleRequest->cancel();
+ m_currentBundleRequest = nullptr;
+ }
+
+ Deque<std::unique_ptr<AppBundleRequest>> pendingBundleRequests;
+ pendingBundleRequests.swap(m_pendingBundleRequests);
+ for (auto& requst : pendingBundleRequests)
+ requst->cancel();
+}
+
} // namespace WebPushD
Modified: trunk/Source/WebKit/webpushd/WebPushDaemon.h (286272 => 286273)
--- trunk/Source/WebKit/webpushd/WebPushDaemon.h 2021-11-30 00:20:30 UTC (rev 286272)
+++ trunk/Source/WebKit/webpushd/WebPushDaemon.h 2021-11-30 00:20:57 UTC (rev 286273)
@@ -71,10 +71,7 @@
bool canRegisterForNotifications(ClientConnection&);
ClientConnection* toClientConnection(xpc_connection_t);
-
- HashSet<String> m_inMemoryOriginStringsWithPermissionForTesting;
-
- HashMap<xpc_connection_t, std::unique_ptr<ClientConnection>> m_connectionMap;
+ HashMap<xpc_connection_t, Ref<ClientConnection>> m_connectionMap;
};
} // namespace WebPushD
Modified: trunk/Source/WebKit/webpushd/WebPushDaemon.mm (286272 => 286273)
--- trunk/Source/WebKit/webpushd/WebPushDaemon.mm 2021-11-30 00:20:30 UTC (rev 286272)
+++ trunk/Source/WebKit/webpushd/WebPushDaemon.mm 2021-11-30 00:20:57 UTC (rev 286273)
@@ -26,10 +26,12 @@
#import "config.h"
#import "WebPushDaemon.h"
+#import "AppBundleRequest.h"
#import "DaemonDecoder.h"
#import "DaemonEncoder.h"
#import "DaemonUtilities.h"
#import "HandleMessage.h"
+#import "MockAppBundleRegistry.h"
#import "WebPushDaemonConstants.h"
#import <wtf/CompletionHandler.h>
@@ -180,13 +182,14 @@
void Daemon::connectionAdded(xpc_connection_t connection)
{
RELEASE_ASSERT(!m_connectionMap.contains(connection));
- m_connectionMap.set(connection, WTF::makeUnique<ClientConnection>(connection));
+ m_connectionMap.set(connection, ClientConnection::create(connection));
}
void Daemon::connectionRemoved(xpc_connection_t connection)
{
RELEASE_ASSERT(m_connectionMap.contains(connection));
- m_connectionMap.remove(connection);
+ auto clientConnection = m_connectionMap.take(connection);
+ clientConnection->connectionClosed();
}
CompletionHandler<void(EncodedMessage&&)> Daemon::createReplySender(MessageType messageType, OSObjectPtr<xpc_object_t>&& request)
@@ -253,10 +256,7 @@
return;
}
- // 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);
+ connection->enqueueAppBundleRequest(makeUnique<AppBundlePermissionsRequest>(*connection, originString, WTFMove(replySender)));
}
void Daemon::getOriginsWithPushAndNotificationPermissions(ClientConnection* connection, CompletionHandler<void(const Vector<String>&)>&& replySender)
@@ -266,9 +266,8 @@
return;
}
- // 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));
+ // FIXME: This will need platform-specific implementations for real world bundles once implemented.
+ replySender(MockAppBundleRegistry::singleton().getOriginsWithRegistrations(connection->hostAppCodeSigningIdentifier()));
}
void Daemon::deletePushAndNotificationRegistration(ClientConnection* connection, const String& originString, CompletionHandler<void(const String&)>&& replySender)
@@ -278,12 +277,7 @@
return;
}
- // 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"));
+ connection->enqueueAppBundleRequest(makeUnique<AppBundleDeletionRequest>(*connection, originString, WTFMove(replySender)));
}
void Daemon::setHostAppAuditToken(ClientConnection* clientConnection, const Vector<uint8_t>& tokenData)
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WebPushDaemon.mm (286272 => 286273)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WebPushDaemon.mm 2021-11-30 00:20:30 UTC (rev 286272)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WebPushDaemon.mm 2021-11-30 00:20:57 UTC (rev 286273)
@@ -158,7 +158,7 @@
}
// FIXME: Re-enable this test for Monterey+ once webkit.org/232857 is resolved.
-#if __MAC_OS_X_VERSION_MIN_REQUIRED < 110000 || __MAC_OS_X_VERSION_MIN_REQUIRED >= 120000
+#if PLATFORM(MAC) && (__MAC_OS_X_VERSION_MIN_REQUIRED < 110000 || __MAC_OS_X_VERSION_MIN_REQUIRED >= 120000)
TEST(WebPushD, DISABLED_BasicCommunication)
#else
TEST(WebPushD, BasicCommunication)
@@ -255,7 +255,7 @@
)WEBPUSHRESOURCE";
// FIXME: Re-enable this test for Monterey+ once webkit.org/232857 is resolved.
-#if __MAC_OS_X_VERSION_MIN_REQUIRED < 110000 || __MAC_OS_X_VERSION_MIN_REQUIRED >= 120000
+#if PLATFORM(MAC) && (__MAC_OS_X_VERSION_MIN_REQUIRED < 110000 || __MAC_OS_X_VERSION_MIN_REQUIRED >= 120000)
TEST(WebPushD, DISABLED_PermissionManagement)
#else
TEST(WebPushD, PermissionManagement)