Log Message
IPC testing API should have the ability to test IPC::Connection send and receive through IPC::Connection https://bugs.webkit.org/show_bug.cgi?id=239495
Patch by Kimmo Kinnunen <kkinnu...@apple.com> on 2022-04-28 Reviewed by Darin Adler. Source/WebKit: Add the testing interfaces to be able to send IPC::Connection instances to other processes. Add the testing interfaces to be able to send messages through arbitrary IPC::Connection instances. Test: ipc/create-connection-and-send-async.html * CMakeLists.txt: * DerivedSources-input.xcfilelist: * DerivedSources-output.xcfilelist: * DerivedSources.make: * Platform/IPC/Connection.h: (IPC::Connection::waitForMessageForTesting): * Scripts/webkit/messages.py: (types_that_cannot_be_forward_declared): * Shared/IPCConnectionTester.cpp: Added. (WebKit::asIdentifier): (WebKit::IPCConnectionTester::create): (WebKit::IPCConnectionTester::IPCConnectionTester): (WebKit::IPCConnectionTester::initialize): (WebKit::IPCConnectionTester::stopListeningForIPC): (WebKit::IPCConnectionTester::sendAsyncMessages): (WebKit::IPCConnectionTester::didClose): (WebKit::IPCConnectionTester::didReceiveInvalidMessage): (WebKit::IPCConnectionTester::asyncMessage): (WebKit::IPCConnectionTester::syncMessage): * Shared/IPCConnectionTester.h: Copied from Source/WebKit/Shared/IPCTester.h. * Shared/IPCConnectionTester.messages.in: Copied from Source/WebKit/Shared/IPCTester.messages.in. * Shared/IPCConnectionTesterIdentifier.h: Added. * Shared/IPCTester.cpp: (WebKit::IPCTester::createConnectionTester): (WebKit::IPCTester::createConnectionTesterAndSendAsyncMessages): (WebKit::IPCTester::releaseConnectionTester): * Shared/IPCTester.h: * Shared/IPCTester.messages.in: * Sources.txt: * WebKit.xcodeproj/project.pbxproj: * WebProcess/WebPage/IPCTestingAPI.cpp: (WebKit::IPCTestingAPI::JSIPCAttachment::create): (WebKit::IPCTestingAPI::JSIPCAttachment::encode const): (WebKit::IPCTestingAPI::JSIPCAttachment::JSIPCAttachment): (WebKit::IPCTestingAPI::JSIPCConnection::create): (WebKit::IPCTestingAPI::JSIPCConnection::JSIPCConnection): (WebKit::IPCTestingAPI::createTypeError): (WebKit::IPCTestingAPI::convertToUint64): (WebKit::IPCTestingAPI::sendMessageWithJSArguments): (WebKit::IPCTestingAPI::extractSyncIPCMessageInfo): (WebKit::IPCTestingAPI::sendSyncMessageWithJSArguments): (WebKit::IPCTestingAPI::waitForMessageWithJSArguments): (WebKit::IPCTestingAPI::JSIPCSemaphore::createJSWrapper): (WebKit::IPCTestingAPI::JSIPCSemaphore::wrapperClass): (WebKit::IPCTestingAPI::JSIPCSemaphore::unwrap): (WebKit::IPCTestingAPI::JSIPCSemaphore::toWrapped): (WebKit::IPCTestingAPI::JSIPCSemaphore::initialize): (WebKit::IPCTestingAPI::JSIPCSemaphore::finalize): (WebKit::IPCTestingAPI::JSIPCSemaphore::staticFunctions): (WebKit::IPCTestingAPI::JSIPCAttachment::createJSWrapper): (WebKit::IPCTestingAPI::JSIPCAttachment::wrapperClass): (WebKit::IPCTestingAPI::JSIPCAttachment::unwrap): (WebKit::IPCTestingAPI::JSIPCAttachment::toWrapped): (WebKit::IPCTestingAPI::JSIPCAttachment::initialize): (WebKit::IPCTestingAPI::JSIPCAttachment::finalize): (WebKit::IPCTestingAPI::JSIPCAttachment::staticFunctions): (WebKit::IPCTestingAPI::JSIPCConnection::createJSWrapper): (WebKit::IPCTestingAPI::JSIPCConnection::wrapperClass): (WebKit::IPCTestingAPI::JSIPCConnection::unwrap): (WebKit::IPCTestingAPI::JSIPCConnection::toWrapped): (WebKit::IPCTestingAPI::JSIPCConnection::initialize): (WebKit::IPCTestingAPI::JSIPCConnection::finalize): (WebKit::IPCTestingAPI::JSIPCConnection::didReceiveMessage): (WebKit::IPCTestingAPI::JSIPCConnection::didReceiveSyncMessage): (WebKit::IPCTestingAPI::JSIPCConnection::didClose): (WebKit::IPCTestingAPI::JSIPCConnection::didReceiveInvalidMessage): (WebKit::IPCTestingAPI::JSIPCConnection::staticFunctions): (WebKit::IPCTestingAPI::JSIPCConnection::open): (WebKit::IPCTestingAPI::JSIPCConnection::invalidate): (WebKit::IPCTestingAPI::JSIPCConnection::sendMessage): (WebKit::IPCTestingAPI::JSIPCConnection::sendSyncMessage): (WebKit::IPCTestingAPI::JSIPCConnection::waitForMessage): (WebKit::IPCTestingAPI::JSIPCStreamClientConnection::prepareToSendOutOfStreamMessage): (WebKit::IPCTestingAPI::JSIPC::staticFunctions): (WebKit::IPCTestingAPI::encodeFrameInfoData): (WebKit::IPCTestingAPI::encodeAttachment): (WebKit::IPCTestingAPI::VectorEncodeHelper::encode const): (WebKit::IPCTestingAPI::encodeArrayArgument): (WebKit::IPCTestingAPI::encodeArgument): (WebKit::IPCTestingAPI::JSIPC::sendMessage): (WebKit::IPCTestingAPI::JSIPC::waitForMessage): (WebKit::IPCTestingAPI::JSIPC::sendSyncMessage): (WebKit::IPCTestingAPI::JSIPC::createConnectionPair): Tools: * TestWebKitAPI/Tests/WebKitCocoa/IPCTestingAPI.mm: (TEST): Change two tests to pass "IPC" object as the value of FrameInfoData. This way the argument encode functions do not need to take the JSIPC argument. LayoutTests: * ipc/create-connection-and-send-async.html: Added.
Modified Paths
- trunk/LayoutTests/ChangeLog
- trunk/Source/WebKit/CMakeLists.txt
- trunk/Source/WebKit/ChangeLog
- trunk/Source/WebKit/DerivedSources-input.xcfilelist
- trunk/Source/WebKit/DerivedSources-output.xcfilelist
- trunk/Source/WebKit/DerivedSources.make
- trunk/Source/WebKit/Platform/IPC/Connection.h
- trunk/Source/WebKit/Scripts/webkit/messages.py
- trunk/Source/WebKit/Shared/IPCTester.cpp
- trunk/Source/WebKit/Shared/IPCTester.h
- trunk/Source/WebKit/Shared/IPCTester.messages.in
- trunk/Source/WebKit/Sources.txt
- trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj
- trunk/Source/WebKit/WebProcess/WebPage/IPCTestingAPI.cpp
- trunk/Tools/ChangeLog
- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/IPCTestingAPI.mm
Added Paths
- trunk/LayoutTests/ipc/create-connection-and-send-async-expected.txt
- trunk/LayoutTests/ipc/create-connection-and-send-async.html
- trunk/Source/WebKit/Shared/IPCConnectionTester.cpp
- trunk/Source/WebKit/Shared/IPCConnectionTester.h
- trunk/Source/WebKit/Shared/IPCConnectionTester.messages.in
- trunk/Source/WebKit/Shared/IPCConnectionTesterIdentifier.h
Diff
Modified: trunk/LayoutTests/ChangeLog (293566 => 293567)
--- trunk/LayoutTests/ChangeLog 2022-04-28 05:36:41 UTC (rev 293566)
+++ trunk/LayoutTests/ChangeLog 2022-04-28 07:18:08 UTC (rev 293567)
@@ -1,3 +1,12 @@
+2022-04-28 Kimmo Kinnunen <kkinnu...@apple.com>
+
+ IPC testing API should have the ability to test IPC::Connection send and receive through IPC::Connection
+ https://bugs.webkit.org/show_bug.cgi?id=239495
+
+ Reviewed by Darin Adler.
+
+ * ipc/create-connection-and-send-async.html: Added.
+
2022-04-27 Patrick Angle <pan...@apple.com>
Web Inspector: [Flexbox] `<button>` and `<select>` elements are appearing in list of Flex containers
Added: trunk/LayoutTests/ipc/create-connection-and-send-async-expected.txt (0 => 293567)
--- trunk/LayoutTests/ipc/create-connection-and-send-async-expected.txt (rev 0)
+++ trunk/LayoutTests/ipc/create-connection-and-send-async-expected.txt 2022-04-28 07:18:08 UTC (rev 293567)
@@ -0,0 +1,4 @@
+
+PASS Sending async messages from the server immediately after opening a new connection works.
+PASS Sending async messages from the client immediately after opening the connection works.
+
Added: trunk/LayoutTests/ipc/create-connection-and-send-async.html (0 => 293567)
--- trunk/LayoutTests/ipc/create-connection-and-send-async.html (rev 0)
+++ trunk/LayoutTests/ipc/create-connection-and-send-async.html 2022-04-28 07:18:08 UTC (rev 293567)
@@ -0,0 +1,72 @@
+<!doctype html><!-- webkit-test-runner [ IPCTestingAPIEnabled=true ] -->
+<title>Test that sending messages immediately after creating a new connection works.</title>
+<script src=""
+<script src=""
+<body>
+<script>
+const defaultTimeout = 1000;
+
+promise_test(async t => {
+ if (!window.IPC)
+ return;
+ const testerID = 447;
+ for (const processTarget of IPC.processTargets) {
+ // Test starts here.
+ const [connection, clientConnectionIdentifier] = IPC.createConnectionPair();
+ connection.open();
+ const msgs = [];
+ const numMessages = 10000;
+ for (let v = 0; v < numMessages; v++)
+ msgs.push([{ type: 'uint32_t', value: v + 1}]);
+ let msgName = IPC.messages.IPCConnectionTester_AsyncMessage.name;
+
+ IPC.sendMessage(processTarget, 0, IPC.messages.IPCTester_CreateConnectionTester.name, [
+ { type: 'uint64_t', value: testerID },
+ { type: 'Attachment', value: clientConnectionIdentifier },
+ ]);
+ try {
+ for (let msg of msgs)
+ connection.sendMessage(0, msgName, msg);
+ const reply = connection.sendSyncMessage(0, IPC.messages.IPCConnectionTester_SyncMessage.name, defaultTimeout, [{ type: 'uint32_t', value: 55 }]);
+ const firstResult = reply.arguments[0];
+ assert_equals(firstResult.type, "uint32_t", `for ${ processTarget }`);
+ assert_equals(firstResult.value, 55 + numMessages, `for ${ processTarget }`);
+ } finally {
+ connection.invalidate();
+ IPC.sendSyncMessage(processTarget, 0, IPC.messages.IPCTester_ReleaseConnectionTester.name, defaultTimeout, [{ type: 'uint64_t', value: testerID }]);
+ }
+ }
+}, "Sending async messages from the server immediately after opening a new connection works.");
+
+promise_test(async t => {
+ if (!window.IPC)
+ return;
+ const testerID = 448;
+ for (const processTarget of IPC.processTargets) {
+ // Test starts here.
+ const connectionCount = 5; // FIXME: should be 100, but waiting for messages is slow.
+ for (let i = 0; i < connectionCount; ++i) {
+ const [connection, clientConnectionIdentifier] = IPC.createConnectionPair();
+ connection.open();
+ const messageCount = 3; // FIXME: should be 10000, but waiting for messages is slow.
+ IPC.sendMessage(processTarget, 0, IPC.messages.IPCTester_CreateConnectionTesterAndSendAsyncMessages.name, [
+ { type: 'uint64_t', value: testerID },
+ { type: 'Attachment', value: clientConnectionIdentifier },
+ { type: 'uint32_t', value: messageCount },
+ ]);
+ try {
+ for (let v = 0; v < messageCount; v++) {
+ const msg = connection.waitForMessage(0, IPC.messages.IPCConnectionTester_AsyncMessage.name, defaultTimeout);
+ assert_equals(msg[0].type, "uint32_t", `for ${ processTarget }`);
+ assert_equals(msg[0].value, v, `for ${ processTarget }`);
+
+ }
+ } finally {
+ connection.invalidate();
+ IPC.sendSyncMessage(processTarget, 0, IPC.messages.IPCTester_ReleaseConnectionTester.name, defaultTimeout, [{ type: 'uint64_t', value: testerID }]);
+ }
+ }
+ }
+}, "Sending async messages from the client immediately after opening the connection works.");
+</script>
+</body>
\ No newline at end of file
Modified: trunk/Source/WebKit/CMakeLists.txt (293566 => 293567)
--- trunk/Source/WebKit/CMakeLists.txt 2022-04-28 05:36:41 UTC (rev 293566)
+++ trunk/Source/WebKit/CMakeLists.txt 2022-04-28 07:18:08 UTC (rev 293567)
@@ -215,6 +215,7 @@
NetworkProcess/webrtc/RTCDataChannelRemoteManagerProxy
Shared/AuxiliaryProcess
+ Shared/IPCConnectionTester
Shared/IPCStreamTester
Shared/IPCStreamTesterProxy
Shared/IPCTester
Modified: trunk/Source/WebKit/ChangeLog (293566 => 293567)
--- trunk/Source/WebKit/ChangeLog 2022-04-28 05:36:41 UTC (rev 293566)
+++ trunk/Source/WebKit/ChangeLog 2022-04-28 07:18:08 UTC (rev 293567)
@@ -1,3 +1,101 @@
+2022-04-28 Kimmo Kinnunen <kkinnu...@apple.com>
+
+ IPC testing API should have the ability to test IPC::Connection send and receive through IPC::Connection
+ https://bugs.webkit.org/show_bug.cgi?id=239495
+
+ Reviewed by Darin Adler.
+
+ Add the testing interfaces to be able to send IPC::Connection instances
+ to other processes.
+ Add the testing interfaces to be able to send messages through arbitrary
+ IPC::Connection instances.
+
+ Test: ipc/create-connection-and-send-async.html
+
+ * CMakeLists.txt:
+ * DerivedSources-input.xcfilelist:
+ * DerivedSources-output.xcfilelist:
+ * DerivedSources.make:
+ * Platform/IPC/Connection.h:
+ (IPC::Connection::waitForMessageForTesting):
+ * Scripts/webkit/messages.py:
+ (types_that_cannot_be_forward_declared):
+ * Shared/IPCConnectionTester.cpp: Added.
+ (WebKit::asIdentifier):
+ (WebKit::IPCConnectionTester::create):
+ (WebKit::IPCConnectionTester::IPCConnectionTester):
+ (WebKit::IPCConnectionTester::initialize):
+ (WebKit::IPCConnectionTester::stopListeningForIPC):
+ (WebKit::IPCConnectionTester::sendAsyncMessages):
+ (WebKit::IPCConnectionTester::didClose):
+ (WebKit::IPCConnectionTester::didReceiveInvalidMessage):
+ (WebKit::IPCConnectionTester::asyncMessage):
+ (WebKit::IPCConnectionTester::syncMessage):
+ * Shared/IPCConnectionTester.h: Copied from Source/WebKit/Shared/IPCTester.h.
+ * Shared/IPCConnectionTester.messages.in: Copied from Source/WebKit/Shared/IPCTester.messages.in.
+ * Shared/IPCConnectionTesterIdentifier.h: Added.
+ * Shared/IPCTester.cpp:
+ (WebKit::IPCTester::createConnectionTester):
+ (WebKit::IPCTester::createConnectionTesterAndSendAsyncMessages):
+ (WebKit::IPCTester::releaseConnectionTester):
+ * Shared/IPCTester.h:
+ * Shared/IPCTester.messages.in:
+ * Sources.txt:
+ * WebKit.xcodeproj/project.pbxproj:
+ * WebProcess/WebPage/IPCTestingAPI.cpp:
+ (WebKit::IPCTestingAPI::JSIPCAttachment::create):
+ (WebKit::IPCTestingAPI::JSIPCAttachment::encode const):
+ (WebKit::IPCTestingAPI::JSIPCAttachment::JSIPCAttachment):
+ (WebKit::IPCTestingAPI::JSIPCConnection::create):
+ (WebKit::IPCTestingAPI::JSIPCConnection::JSIPCConnection):
+ (WebKit::IPCTestingAPI::createTypeError):
+ (WebKit::IPCTestingAPI::convertToUint64):
+ (WebKit::IPCTestingAPI::sendMessageWithJSArguments):
+ (WebKit::IPCTestingAPI::extractSyncIPCMessageInfo):
+ (WebKit::IPCTestingAPI::sendSyncMessageWithJSArguments):
+ (WebKit::IPCTestingAPI::waitForMessageWithJSArguments):
+ (WebKit::IPCTestingAPI::JSIPCSemaphore::createJSWrapper):
+ (WebKit::IPCTestingAPI::JSIPCSemaphore::wrapperClass):
+ (WebKit::IPCTestingAPI::JSIPCSemaphore::unwrap):
+ (WebKit::IPCTestingAPI::JSIPCSemaphore::toWrapped):
+ (WebKit::IPCTestingAPI::JSIPCSemaphore::initialize):
+ (WebKit::IPCTestingAPI::JSIPCSemaphore::finalize):
+ (WebKit::IPCTestingAPI::JSIPCSemaphore::staticFunctions):
+ (WebKit::IPCTestingAPI::JSIPCAttachment::createJSWrapper):
+ (WebKit::IPCTestingAPI::JSIPCAttachment::wrapperClass):
+ (WebKit::IPCTestingAPI::JSIPCAttachment::unwrap):
+ (WebKit::IPCTestingAPI::JSIPCAttachment::toWrapped):
+ (WebKit::IPCTestingAPI::JSIPCAttachment::initialize):
+ (WebKit::IPCTestingAPI::JSIPCAttachment::finalize):
+ (WebKit::IPCTestingAPI::JSIPCAttachment::staticFunctions):
+ (WebKit::IPCTestingAPI::JSIPCConnection::createJSWrapper):
+ (WebKit::IPCTestingAPI::JSIPCConnection::wrapperClass):
+ (WebKit::IPCTestingAPI::JSIPCConnection::unwrap):
+ (WebKit::IPCTestingAPI::JSIPCConnection::toWrapped):
+ (WebKit::IPCTestingAPI::JSIPCConnection::initialize):
+ (WebKit::IPCTestingAPI::JSIPCConnection::finalize):
+ (WebKit::IPCTestingAPI::JSIPCConnection::didReceiveMessage):
+ (WebKit::IPCTestingAPI::JSIPCConnection::didReceiveSyncMessage):
+ (WebKit::IPCTestingAPI::JSIPCConnection::didClose):
+ (WebKit::IPCTestingAPI::JSIPCConnection::didReceiveInvalidMessage):
+ (WebKit::IPCTestingAPI::JSIPCConnection::staticFunctions):
+ (WebKit::IPCTestingAPI::JSIPCConnection::open):
+ (WebKit::IPCTestingAPI::JSIPCConnection::invalidate):
+ (WebKit::IPCTestingAPI::JSIPCConnection::sendMessage):
+ (WebKit::IPCTestingAPI::JSIPCConnection::sendSyncMessage):
+ (WebKit::IPCTestingAPI::JSIPCConnection::waitForMessage):
+ (WebKit::IPCTestingAPI::JSIPCStreamClientConnection::prepareToSendOutOfStreamMessage):
+ (WebKit::IPCTestingAPI::JSIPC::staticFunctions):
+ (WebKit::IPCTestingAPI::encodeFrameInfoData):
+ (WebKit::IPCTestingAPI::encodeAttachment):
+ (WebKit::IPCTestingAPI::VectorEncodeHelper::encode const):
+ (WebKit::IPCTestingAPI::encodeArrayArgument):
+ (WebKit::IPCTestingAPI::encodeArgument):
+ (WebKit::IPCTestingAPI::JSIPC::sendMessage):
+ (WebKit::IPCTestingAPI::JSIPC::waitForMessage):
+ (WebKit::IPCTestingAPI::JSIPC::sendSyncMessage):
+ (WebKit::IPCTestingAPI::JSIPC::createConnectionPair):
+
2022-04-27 Wenson Hsieh <wenson_hs...@apple.com>
[iOS] Add a mechanism to override desktop-class browsing state in multitasking mode
Modified: trunk/Source/WebKit/DerivedSources-input.xcfilelist (293566 => 293567)
--- trunk/Source/WebKit/DerivedSources-input.xcfilelist 2022-04-28 05:36:41 UTC (rev 293566)
+++ trunk/Source/WebKit/DerivedSources-input.xcfilelist 2022-04-28 07:18:08 UTC (rev 293567)
@@ -129,6 +129,7 @@
$(PROJECT_DIR)/Shared/Authentication/AuthenticationManager.messages.in
$(PROJECT_DIR)/Shared/AuxiliaryProcess.messages.in
$(PROJECT_DIR)/Shared/HTTPSUpgrade/HTTPSUpgradeList.txt
+$(PROJECT_DIR)/Shared/IPCConnectionTester.messages.in
$(PROJECT_DIR)/Shared/IPCStreamTester.messages.in
$(PROJECT_DIR)/Shared/IPCStreamTesterProxy.messages.in
$(PROJECT_DIR)/Shared/IPCTester.messages.in
Modified: trunk/Source/WebKit/DerivedSources-output.xcfilelist (293566 => 293567)
--- trunk/Source/WebKit/DerivedSources-output.xcfilelist 2022-04-28 05:36:41 UTC (rev 293566)
+++ trunk/Source/WebKit/DerivedSources-output.xcfilelist 2022-04-28 07:18:08 UTC (rev 293567)
@@ -46,6 +46,9 @@
$(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit/GPUProcessProxyMessageReceiver.cpp
$(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit/GPUProcessProxyMessages.h
$(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit/GPUProcessProxyMessagesReplies.h
+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit/IPCConnectionTesterMessageReceiver.cpp
+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit/IPCConnectionTesterMessages.h
+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit/IPCConnectionTesterMessagesReplies.h
$(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit/IPCStreamTesterMessageReceiver.cpp
$(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit/IPCStreamTesterMessages.h
$(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit/IPCStreamTesterMessagesReplies.h
Modified: trunk/Source/WebKit/DerivedSources.make (293566 => 293567)
--- trunk/Source/WebKit/DerivedSources.make 2022-04-28 05:36:41 UTC (rev 293566)
+++ trunk/Source/WebKit/DerivedSources.make 2022-04-28 07:18:08 UTC (rev 293567)
@@ -149,6 +149,7 @@
Shared/Authentication/AuthenticationManager \
Shared/Notifications/NotificationManagerMessageHandler \
Shared/WebConnection \
+ Shared/IPCConnectionTester \
Shared/IPCStreamTester \
Shared/IPCStreamTesterProxy \
Shared/IPCTester \
Modified: trunk/Source/WebKit/Platform/IPC/Connection.h (293566 => 293567)
--- trunk/Source/WebKit/Platform/IPC/Connection.h 2022-04-28 05:36:41 UTC (rev 293566)
+++ trunk/Source/WebKit/Platform/IPC/Connection.h 2022-04-28 07:18:08 UTC (rev 293567)
@@ -57,11 +57,6 @@
#include <wtf/glib/GSocketMonitor.h>
#endif
-namespace WebKit {
-namespace IPCTestingAPI {
-class JSIPC;
-}
-}
namespace IPC {
@@ -333,6 +328,7 @@
void setIgnoreInvalidMessageForTesting() { m_ignoreInvalidMessageForTesting = true; }
bool ignoreInvalidMessageForTesting() const { return m_ignoreInvalidMessageForTesting; }
void dispatchIncomingMessageForTesting(std::unique_ptr<Decoder>&&);
+ std::unique_ptr<Decoder> waitForMessageForTesting(MessageName, uint64_t destinationID, Timeout, OptionSet<WaitForOption>);
#endif
void dispatchMessageReceiverMessage(MessageReceiver&, std::unique_ptr<Decoder>&&);
@@ -524,7 +520,6 @@
HANDLE m_connectionPipe { INVALID_HANDLE_VALUE };
#endif
friend class StreamClientConnection;
- friend class WebKit::IPCTestingAPI::JSIPC;
};
template<typename T>
@@ -657,6 +652,14 @@
return true;
}
+#if ENABLE(IPC_TESTING_API)
+inline std::unique_ptr<Decoder> Connection::waitForMessageForTesting(MessageName messageName, uint64_t destinationID, Timeout timeout, OptionSet<WaitForOption> options)
+{
+ return waitForMessage(messageName, destinationID, timeout, options);
+}
+#endif
+
+
class UnboundedSynchronousIPCScope {
public:
UnboundedSynchronousIPCScope()
Modified: trunk/Source/WebKit/Scripts/webkit/messages.py (293566 => 293567)
--- trunk/Source/WebKit/Scripts/webkit/messages.py 2022-04-28 05:36:41 UTC (rev 293566)
+++ trunk/Source/WebKit/Scripts/webkit/messages.py 2022-04-28 07:18:08 UTC (rev 293567)
@@ -324,6 +324,7 @@
'WebKit::GeolocationIdentifier',
'WebKit::GraphicsContextGLIdentifier',
'WebKit::ImageBufferBackendHandle',
+ 'WebKit::IPCConnectionTesterIdentifier',
'WebKit::IPCStreamTesterIdentifier',
'WebKit::LayerHostingContextID',
'WebKit::LegacyCustomProtocolID',
Added: trunk/Source/WebKit/Shared/IPCConnectionTester.cpp (0 => 293567)
--- trunk/Source/WebKit/Shared/IPCConnectionTester.cpp (rev 0)
+++ trunk/Source/WebKit/Shared/IPCConnectionTester.cpp 2022-04-28 07:18:08 UTC (rev 293567)
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+#include "config.h"
+#include "IPCConnectionTester.h"
+
+#if ENABLE(IPC_TESTING_API)
+#include "IPCConnectionTesterMessages.h"
+#include "IPCTester.h"
+
+namespace WebKit {
+
+// FIXME(https://webkit.org/b/239487): These ifdefs are error prone, duplicated and the lack of move semantics causes leaks.
+static IPC::Connection::Identifier asIdentifier(IPC::Attachment&& connectionIdentifier)
+{
+#if USE(UNIX_DOMAIN_SOCKETS)
+ return { connectionIdentifier.release().release() };
+#elif OS(DARWIN)
+ return { connectionIdentifier.port() };
+#elif OS(WINDOWS)
+ return { connectionIdentifier.handle() };
+#else
+ notImplemented();
+ return { };
+#endif
+}
+
+Ref<IPCConnectionTester> IPCConnectionTester::create(IPC::Connection& connection, IPCConnectionTesterIdentifier identifier, IPC::Attachment&& testedConnectionIdentifier)
+{
+ auto tester = adoptRef(*new IPCConnectionTester(connection, identifier, WTFMove(testedConnectionIdentifier)));
+ tester->initialize();
+ return tester;
+}
+
+IPCConnectionTester::IPCConnectionTester(Ref<IPC::Connection>&& connection, IPCConnectionTesterIdentifier identifier, IPC::Attachment&& testedConnectionIdentifier)
+ : m_connection(WTFMove(connection))
+ , m_testedConnection(IPC::Connection::createClientConnection(asIdentifier(WTFMove(testedConnectionIdentifier)), *this))
+ , m_identifier(identifier)
+{
+}
+
+IPCConnectionTester::~IPCConnectionTester() = default;
+
+void IPCConnectionTester::initialize()
+{
+ m_testedConnection->open();
+}
+
+void IPCConnectionTester::stopListeningForIPC(Ref<IPCConnectionTester>&& refFromConnection)
+{
+ m_testedConnection->invalidate();
+}
+
+void IPCConnectionTester::sendAsyncMessages(uint32_t messageCount)
+{
+ for (uint32_t i = 0; i < messageCount; ++i)
+ m_testedConnection->send(Messages::IPCConnectionTester::AsyncMessage(i), 0);
+}
+
+void IPCConnectionTester::didClose(IPC::Connection&)
+{
+}
+
+void IPCConnectionTester::didReceiveInvalidMessage(IPC::Connection&, IPC::MessageName)
+{
+ ASSERT_NOT_REACHED();
+}
+
+void IPCConnectionTester::asyncMessage(uint32_t value)
+{
+ if (m_previousAsyncMessageValue != value - 1) {
+ ASSERT_IS_TESTING_IPC();
+ return;
+ }
+ m_previousAsyncMessageValue = value;
+}
+
+void IPCConnectionTester::syncMessage(uint32_t value, CompletionHandler<void(uint32_t)>&& completionHandler)
+{
+ completionHandler(value + m_previousAsyncMessageValue);
+}
+
+}
+
+#endif
Added: trunk/Source/WebKit/Shared/IPCConnectionTester.h (0 => 293567)
--- trunk/Source/WebKit/Shared/IPCConnectionTester.h (rev 0)
+++ trunk/Source/WebKit/Shared/IPCConnectionTester.h 2022-04-28 07:18:08 UTC (rev 293567)
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2022 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
+
+#if ENABLE(IPC_TESTING_API)
+
+#include "Connection.h"
+#include "IPCConnectionTesterIdentifier.h"
+#include "MessageReceiver.h"
+#include <optional>
+#include <wtf/HashMap.h>
+
+namespace IPC {
+class Connection;
+}
+
+namespace WebKit {
+
+// Interface to test various IPC::Connection related activities.
+class IPCConnectionTester final : public RefCounted<IPCConnectionTester>, private IPC::Connection::Client {
+public:
+ ~IPCConnectionTester();
+ static Ref<IPCConnectionTester> create(IPC::Connection&, IPCConnectionTesterIdentifier, IPC::Attachment&& testedConnectionIdentifier);
+ void stopListeningForIPC(Ref<IPCConnectionTester>&& refFromConnection);
+
+ void sendAsyncMessages(uint32_t messageCount);
+private:
+ IPCConnectionTester(Ref<IPC::Connection>&&, IPCConnectionTesterIdentifier, IPC::Attachment&& testedConnectionIdentifier);
+ void initialize();
+
+ // IPC::Connection::Client overrides.
+ void didReceiveMessage(IPC::Connection&, IPC::Decoder&) final;
+ bool didReceiveSyncMessage(IPC::Connection&, IPC::Decoder&, UniqueRef<IPC::Encoder>&) final;
+ void didClose(IPC::Connection&) final;
+ void didReceiveInvalidMessage(IPC::Connection&, IPC::MessageName) final;
+
+ // Messages.
+ void asyncMessage(uint32_t value);
+ void syncMessage(uint32_t value, CompletionHandler<void(uint32_t sameValue)>&&);
+
+ const Ref<IPC::Connection> m_connection;
+ const Ref<IPC::Connection> m_testedConnection;
+ const IPCConnectionTesterIdentifier m_identifier;
+ uint32_t m_previousAsyncMessageValue { 0 };
+};
+
+}
+
+#endif
Copied: trunk/Source/WebKit/Shared/IPCConnectionTester.messages.in (from rev 293566, trunk/Source/WebKit/Shared/IPCTester.messages.in) (0 => 293567)
--- trunk/Source/WebKit/Shared/IPCConnectionTester.messages.in (rev 0)
+++ trunk/Source/WebKit/Shared/IPCConnectionTester.messages.in 2022-04-28 07:18:08 UTC (rev 293567)
@@ -0,0 +1,30 @@
+# Copyright (C) 2022 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.
+
+#if ENABLE(IPC_TESTING_API)
+
+messages -> IPCConnectionTester NotRefCounted {
+ AsyncMessage(uint32_t value)
+ SyncMessage(uint32_t value) -> (uint32_t sameValue) Synchronous
+}
+
+#endif
Added: trunk/Source/WebKit/Shared/IPCConnectionTesterIdentifier.h (0 => 293567)
--- trunk/Source/WebKit/Shared/IPCConnectionTesterIdentifier.h (rev 0)
+++ trunk/Source/WebKit/Shared/IPCConnectionTesterIdentifier.h 2022-04-28 07:18:08 UTC (rev 293567)
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 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
+
+#if ENABLE(IPC_TESTING_API)
+
+#include <wtf/ObjectIdentifier.h>
+
+namespace WebKit {
+
+enum IPCConnectionTesterIdentifierType { };
+using IPCConnectionTesterIdentifier = ObjectIdentifier<IPCConnectionTesterIdentifierType>;
+
+}
+
+#endif
Modified: trunk/Source/WebKit/Shared/IPCTester.cpp (293566 => 293567)
--- trunk/Source/WebKit/Shared/IPCTester.cpp 2022-04-28 05:36:41 UTC (rev 293566)
+++ trunk/Source/WebKit/Shared/IPCTester.cpp 2022-04-28 07:18:08 UTC (rev 293567)
@@ -29,6 +29,7 @@
#if ENABLE(IPC_TESTING_API)
#include "Connection.h"
#include "Decoder.h"
+#include "IPCConnectionTester.h"
#include "IPCStreamTester.h"
#include "IPCTesterMessages.h"
@@ -168,6 +169,32 @@
}
}
+void IPCTester::createConnectionTester(IPC::Connection& connection, IPCConnectionTesterIdentifier identifier, IPC::Attachment&& testedConnectionIdentifier)
+{
+ auto addResult = m_connectionTesters.ensure(identifier, [&] {
+ return IPC::ScopedActiveMessageReceiveQueue<IPCConnectionTester> { IPCConnectionTester::create(connection, identifier, WTFMove(testedConnectionIdentifier)) };
+ });
+ ASSERT_UNUSED(addResult, addResult.isNewEntry || isTestingIPC());
+}
+
+void IPCTester::createConnectionTesterAndSendAsyncMessages(IPC::Connection& connection, IPCConnectionTesterIdentifier identifier, IPC::Attachment&& testedConnectionIdentifier, uint32_t messageCount)
+{
+ auto addResult = m_connectionTesters.ensure(identifier, [&] {
+ return IPC::ScopedActiveMessageReceiveQueue<IPCConnectionTester> { IPCConnectionTester::create(connection, identifier, WTFMove(testedConnectionIdentifier)) };
+ });
+ if (!addResult.isNewEntry) {
+ ASSERT_IS_TESTING_IPC();
+ return;
+ }
+ addResult.iterator->value->sendAsyncMessages(messageCount);
+}
+
+void IPCTester::releaseConnectionTester(IPCConnectionTesterIdentifier identifier, CompletionHandler<void()>&& completionHandler)
+{
+ m_connectionTesters.remove(identifier);
+ completionHandler();
+}
+
void IPCTester::stopIfNeeded()
{
if (m_testQueue) {
Modified: trunk/Source/WebKit/Shared/IPCTester.h (293566 => 293567)
--- trunk/Source/WebKit/Shared/IPCTester.h 2022-04-28 05:36:41 UTC (rev 293566)
+++ trunk/Source/WebKit/Shared/IPCTester.h 2022-04-28 07:18:08 UTC (rev 293567)
@@ -28,6 +28,7 @@
#if ENABLE(IPC_TESTING_API)
+#include "IPCConnectionTesterIdentifier.h"
#include "IPCStreamTesterIdentifier.h"
#include "MessageReceiver.h"
#include "ScopedActiveMessageReceiveQueue.h"
@@ -52,6 +53,7 @@
// and exposes bugs underneath.
bool isTestingIPC();
+class IPCConnectionTester;
class IPCStreamTester;
// Main test interface for initiating various IPC test activities.
@@ -69,6 +71,9 @@
void stopMessageTesting(CompletionHandler<void()>);
void createStreamTester(IPC::Connection&, IPCStreamTesterIdentifier, IPC::StreamConnectionBuffer&&);
void releaseStreamTester(IPCStreamTesterIdentifier, CompletionHandler<void()>&&);
+ void createConnectionTester(IPC::Connection&, IPCConnectionTesterIdentifier, IPC::Attachment&&);
+ void createConnectionTesterAndSendAsyncMessages(IPC::Connection&, IPCConnectionTesterIdentifier, IPC::Attachment&&, uint32_t messageCount);
+ void releaseConnectionTester(IPCConnectionTesterIdentifier, CompletionHandler<void()>&&);
void sendSameSemaphoreBack(IPC::Connection&, IPC::Semaphore&&);
void sendSemaphoreBackAndSignalProtocol(IPC::Connection&, IPC::Semaphore&&);
@@ -79,6 +84,9 @@
using StreamTesterMap = HashMap<IPCStreamTesterIdentifier, IPC::ScopedActiveMessageReceiveQueue<IPCStreamTester>>;
StreamTesterMap m_streamTesters;
+
+ using ConnectionTesterMap = HashMap<IPCConnectionTesterIdentifier, IPC::ScopedActiveMessageReceiveQueue<IPCConnectionTester>>;
+ ConnectionTesterMap m_connectionTesters;
};
#else
Modified: trunk/Source/WebKit/Shared/IPCTester.messages.in (293566 => 293567)
--- trunk/Source/WebKit/Shared/IPCTester.messages.in 2022-04-28 05:36:41 UTC (rev 293566)
+++ trunk/Source/WebKit/Shared/IPCTester.messages.in 2022-04-28 07:18:08 UTC (rev 293567)
@@ -27,6 +27,9 @@
StopMessageTesting() -> () Synchronous
CreateStreamTester(WebKit::IPCStreamTesterIdentifier identifier, IPC::StreamConnectionBuffer stream) WantsConnection
ReleaseStreamTester(WebKit::IPCStreamTesterIdentifier identifier) -> () Synchronous
+ CreateConnectionTester(WebKit::IPCConnectionTesterIdentifier ideœntifier, IPC::Attachment connection) WantsConnection
+ CreateConnectionTesterAndSendAsyncMessages(WebKit::IPCConnectionTesterIdentifier identifier, IPC::Attachment connection, uint32_t messageCount) WantsConnection
+ ReleaseConnectionTester(WebKit::IPCConnectionTesterIdentifier identifier) -> () Synchronous
SendSameSemaphoreBack(IPC::Semaphore semaphore) WantsConnection
SendSemaphoreBackAndSignalProtocol(IPC::Semaphore semaphore) WantsConnection
Modified: trunk/Source/WebKit/Sources.txt (293566 => 293567)
--- trunk/Source/WebKit/Sources.txt 2022-04-28 05:36:41 UTC (rev 293566)
+++ trunk/Source/WebKit/Sources.txt 2022-04-28 07:18:08 UTC (rev 293567)
@@ -227,6 +227,7 @@
Shared/FontInfo.cpp
Shared/FrameInfoData.cpp
Shared/InspectorExtensionTypes.cpp
+Shared/IPCConnectionTester.cpp
Shared/IPCStreamTester.cpp
Shared/IPCTester.cpp
Shared/LayerTreeContext.cpp
@@ -868,6 +869,7 @@
WebProcess/XR/PlatformXRSystemProxy.cpp
+IPCConnectionTesterMessageReceiver.cpp
IPCStreamTesterMessageReceiver.cpp
IPCStreamTesterProxyMessageReceiver.cpp
IPCTesterMessageReceiver.cpp
Modified: trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj (293566 => 293567)
--- trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj 2022-04-28 05:36:41 UTC (rev 293566)
+++ trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj 2022-04-28 07:18:08 UTC (rev 293567)
@@ -1351,6 +1351,8 @@
7B73124125CC8525003B2796 /* StreamServerConnection.h in Headers */ = {isa = PBXBuildFile; fileRef = 7B73123825CC8524003B2796 /* StreamServerConnection.h */; };
7B73124225CC8525003B2796 /* StreamConnectionEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 7B73123925CC8525003B2796 /* StreamConnectionEncoder.h */; };
7BAB111025DD02B3008FC479 /* ScopedActiveMessageReceiveQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BAB110F25DD02B2008FC479 /* ScopedActiveMessageReceiveQueue.h */; };
+ 7BBA63DF280E93D200B04823 /* IPCConnectionTesterIdentifier.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BBA63DC280E93B500B04823 /* IPCConnectionTesterIdentifier.h */; };
+ 7BBA63E0280E93D600B04823 /* IPCConnectionTester.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BBA63DE280E93B600B04823 /* IPCConnectionTester.h */; };
7BCF70DE2615D06E00E4FB70 /* ScopedRenderingResourcesRequestCocoa.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7BCF70CB2614935E00E4FB70 /* ScopedRenderingResourcesRequestCocoa.mm */; };
7BE37F9327C7CA51007A6CD3 /* IPCStreamTesterIdentifier.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BE37F9227C7C518007A6CD3 /* IPCStreamTesterIdentifier.h */; };
7BE9326327F5C75A00D5FEFB /* ReceiverMatcher.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BE9326227F5C75A00D5FEFB /* ReceiverMatcher.h */; };
@@ -5535,6 +5537,9 @@
7B90416A254AFEA7006EEB8C /* RemoteGraphicsContextGL.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RemoteGraphicsContextGL.h; sourceTree = "<group>"; };
7B90416D2550108C006EEB8C /* RemoteGraphicsContextGLFunctionsGenerated.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RemoteGraphicsContextGLFunctionsGenerated.h; sourceTree = "<group>"; };
7BAB110F25DD02B2008FC479 /* ScopedActiveMessageReceiveQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScopedActiveMessageReceiveQueue.h; sourceTree = "<group>"; };
+ 7BBA63DC280E93B500B04823 /* IPCConnectionTesterIdentifier.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = IPCConnectionTesterIdentifier.h; sourceTree = "<group>"; };
+ 7BBA63DD280E93B600B04823 /* IPCConnectionTester.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = IPCConnectionTester.cpp; sourceTree = "<group>"; };
+ 7BBA63DE280E93B600B04823 /* IPCConnectionTester.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = IPCConnectionTester.h; sourceTree = "<group>"; };
7BCF70CA2614935E00E4FB70 /* ScopedRenderingResourcesRequest.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ScopedRenderingResourcesRequest.cpp; sourceTree = "<group>"; };
7BCF70CB2614935E00E4FB70 /* ScopedRenderingResourcesRequestCocoa.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ScopedRenderingResourcesRequestCocoa.mm; sourceTree = "<group>"; };
7BCF70CC2614935F00E4FB70 /* ScopedWebGLRenderingResourcesRequest.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ScopedWebGLRenderingResourcesRequest.cpp; sourceTree = "<group>"; };
@@ -7939,6 +7944,9 @@
BCCF6B2312C93E7A008F9C35 /* ImageOptions.h */,
999B7ED82550E4A800F450A4 /* InspectorExtensionTypes.cpp */,
99BE3B1625433B9400C6551C /* InspectorExtensionTypes.h */,
+ 7BBA63DD280E93B600B04823 /* IPCConnectionTester.cpp */,
+ 7BBA63DE280E93B600B04823 /* IPCConnectionTester.h */,
+ 7BBA63DC280E93B500B04823 /* IPCConnectionTesterIdentifier.h */,
7BE37F9527C7CD90007A6CD3 /* IPCStreamTester.cpp */,
7BE37F9427C7CD51007A6CD3 /* IPCStreamTester.h */,
7BE37F9227C7C518007A6CD3 /* IPCStreamTesterIdentifier.h */,
@@ -14337,6 +14345,8 @@
51E9049C27BCB9D400929E7E /* InstallCoordinationSPI.h in Headers */,
C5BCE5DF1C50766A00CDE3FA /* InteractionInformationAtPosition.h in Headers */,
2D4D2C811DF60BF3002EB10C /* InteractionInformationRequest.h in Headers */,
+ 7BBA63E0280E93D600B04823 /* IPCConnectionTester.h in Headers */,
+ 7BBA63DF280E93D200B04823 /* IPCConnectionTesterIdentifier.h in Headers */,
A31F60A425CC7DB900AF14F4 /* IPCSemaphore.h in Headers */,
7BE37F9327C7CA51007A6CD3 /* IPCStreamTesterIdentifier.h in Headers */,
9B47908F253151CC00EC11AB /* JSIPCBinding.h in Headers */,
Modified: trunk/Source/WebKit/WebProcess/WebPage/IPCTestingAPI.cpp (293566 => 293567)
--- trunk/Source/WebKit/WebProcess/WebPage/IPCTestingAPI.cpp 2022-04-28 05:36:41 UTC (rev 293566)
+++ trunk/Source/WebKit/WebProcess/WebPage/IPCTestingAPI.cpp 2022-04-28 07:18:08 UTC (rev 293567)
@@ -61,6 +61,8 @@
namespace IPCTestingAPI {
+class JSIPC;
+
static constexpr auto processTargetNameUI = "UI"_s;
#if ENABLE(GPU_PROCESS)
static constexpr auto processTargetNameGPU = "GPU"_s;
@@ -70,7 +72,7 @@
static std::optional<uint64_t> destinationIDFromArgument(JSC::JSGlobalObject*, JSValueRef, JSValueRef*);
static std::optional<uint64_t> messageIDFromArgument(JSC::JSGlobalObject*, JSValueRef, JSValueRef*);
static JSC::JSObject* jsResultFromReplyDecoder(JSC::JSGlobalObject*, IPC::MessageName, IPC::Decoder&);
-static bool encodeArgument(IPC::Encoder&, JSIPC&, JSContextRef, JSValueRef, JSValueRef* exception);
+static bool encodeArgument(IPC::Encoder&, JSContextRef, JSValueRef, JSValueRef* exception);
class JSIPCSemaphore : public RefCounted<JSIPCSemaphore> {
public:
@@ -106,6 +108,71 @@
IPC::Semaphore m_semaphore;
};
+class JSIPCAttachment : public RefCounted<JSIPCAttachment> {
+public:
+ static Ref<JSIPCAttachment> create(IPC::Attachment&& attachment)
+ {
+ return adoptRef(*new JSIPCAttachment(WTFMove(attachment)));
+ }
+
+ JSObjectRef createJSWrapper(JSContextRef);
+ static JSIPCAttachment* toWrapped(JSContextRef, JSValueRef);
+
+ void encode(IPC::Encoder& encoder) const { m_attachment.encode(encoder); }
+
+private:
+ JSIPCAttachment(IPC::Attachment&& attachment)
+ : m_attachment(WTFMove(attachment))
+ { }
+
+ static JSClassRef wrapperClass();
+ static JSIPCAttachment* unwrap(JSObjectRef);
+ static void initialize(JSContextRef, JSObjectRef);
+ static void finalize(JSObjectRef);
+
+ static const JSStaticFunction* staticFunctions();
+
+ IPC::Attachment m_attachment;
+};
+
+class JSIPCConnection : public RefCounted<JSIPCConnection>, private IPC::Connection::Client {
+public:
+ static Ref<JSIPCConnection> create(IPC::Connection::Identifier&& testedConnectionIdentifier)
+ {
+ return adoptRef(*new JSIPCConnection(WTFMove(testedConnectionIdentifier)));
+ }
+
+ JSObjectRef createJSWrapper(JSContextRef);
+ static JSIPCConnection* toWrapped(JSContextRef, JSValueRef);
+
+private:
+ JSIPCConnection(IPC::Connection::Identifier&& testedConnectionIdentifier)
+ : m_testedConnection { IPC::Connection::createServerConnection(testedConnectionIdentifier, *this) }
+ {
+ }
+
+ // IPC::Connection::Client overrides.
+ void didReceiveMessage(IPC::Connection&, IPC::Decoder&) final;
+ bool didReceiveSyncMessage(IPC::Connection&, IPC::Decoder&, UniqueRef<IPC::Encoder>&) final;
+ void didClose(IPC::Connection&) final;
+ void didReceiveInvalidMessage(IPC::Connection&, IPC::MessageName) final;
+
+ static JSClassRef wrapperClass();
+ static JSIPCConnection* unwrap(JSObjectRef);
+ static void initialize(JSContextRef, JSObjectRef);
+ static void finalize(JSObjectRef);
+
+
+ static const JSStaticFunction* staticFunctions();
+ static JSValueRef open(JSContextRef, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception);
+ static JSValueRef invalidate(JSContextRef, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception);
+ static JSValueRef sendMessage(JSContextRef, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception);
+ static JSValueRef sendSyncMessage(JSContextRef, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception);
+ static JSValueRef waitForMessage(JSContextRef, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception);
+
+ Ref<IPC::Connection> m_testedConnection;
+};
+
class JSIPCStreamClientConnection : public RefCounted<JSIPCStreamClientConnection>, public CanMakeWeakPtr<JSIPCStreamClientConnection> {
public:
static Ref<JSIPCStreamClientConnection> create(JSIPC& jsIPC, IPC::Connection& connection, size_t bufferSize)
@@ -220,8 +287,6 @@
Ref<SharedMemory> m_sharedMemory;
};
-class JSIPC;
-
class JSMessageListener final : public IPC::Connection::MessageObserver {
WTF_MAKE_FAST_ALLOCATED;
public:
@@ -246,7 +311,7 @@
{
return adoptRef(*new JSIPC(webPage, webFrame));
}
-
+ static JSIPC* toWrapped(JSContextRef, JSValueRef);
static JSClassRef wrapperClass();
WebFrame* webFrame() { return m_webFrame.get(); }
@@ -258,7 +323,6 @@
{ }
static JSIPC* unwrap(JSObjectRef);
- static JSIPC* toWrapped(JSContextRef, JSValueRef);
static void initialize(JSContextRef, JSObjectRef);
static void finalize(JSObjectRef);
static const JSStaticFunction* staticFunctions();
@@ -272,6 +336,8 @@
static JSValueRef sendSyncMessage(JSContextRef, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception);
static JSValueRef waitForMessage(JSContextRef, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception);
+ static JSValueRef createConnectionPair(JSContextRef, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception);
+
static JSValueRef createStreamClientConnection(JSContextRef, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception);
static JSValueRef createSemaphore(JSContextRef, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception);
static JSValueRef createSharedMemory(JSContextRef, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception);
@@ -311,6 +377,166 @@
return std::nullopt;
}
+
+static JSValueRef sendMessageWithJSArguments(IPC::Connection& connection, JSContextRef context, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ auto* globalObject = toJS(context);
+ JSC::JSLockHolder lock(globalObject->vm());
+
+ auto destinationID = destinationIDFromArgument(globalObject, arguments[0], exception);
+ if (!destinationID)
+ return JSValueMakeUndefined(context);
+
+ auto messageID = messageIDFromArgument(globalObject, arguments[1], exception);
+ if (!messageID)
+ return JSValueMakeUndefined(context);
+
+ auto messageName = static_cast<IPC::MessageName>(*messageID);
+ auto encoder = makeUniqueRef<IPC::Encoder>(messageName, *destinationID);
+
+ JSValueRef returnValue = JSValueMakeUndefined(context);
+
+ bool hasReply = !!messageReplyArgumentDescriptions(messageName);
+ if (hasReply) {
+ uint64_t listenerID = IPC::nextAsyncReplyHandlerID();
+ encoder.get() << listenerID;
+
+ JSObjectRef resolve;
+ JSObjectRef reject;
+ALLOW_NEW_API_WITHOUT_GUARDS_BEGIN
+ returnValue = JSObjectMakeDeferredPromise(context, &resolve, &reject, exception); // NOLINT
+ALLOW_NEW_API_WITHOUT_GUARDS_END
+ if (!returnValue) // NOLINT
+ return JSValueMakeUndefined(context);
+
+ JSGlobalContextRetain(JSContextGetGlobalContext(context));
+ JSValueProtect(context, resolve);
+ JSValueProtect(context, reject);
+ IPC::addAsyncReplyHandler(connection, listenerID, [messageName, context, resolve, reject](IPC::Decoder* replyDecoder) {
+ auto* globalObject = toJS(context);
+ auto& vm = globalObject->vm();
+ JSC::JSLockHolder lock(vm);
+
+ auto scope = DECLARE_CATCH_SCOPE(vm);
+ auto* jsResult = jsResultFromReplyDecoder(globalObject, messageName, *replyDecoder);
+ if (auto* exception = scope.exception()) {
+ scope.clearException();
+ JSValueRef arguments[] = { toRef(globalObject, exception) };
+ JSObjectCallAsFunction(context, reject, reject, 1, arguments, nullptr);
+ } else {
+ JSValueRef arguments[] = { toRef(globalObject, jsResult) };
+ JSObjectCallAsFunction(context, resolve, resolve, 1, arguments, nullptr);
+ }
+
+ JSValueUnprotect(context, reject);
+ JSValueUnprotect(context, resolve);
+ JSGlobalContextRelease(JSContextGetGlobalContext(context));
+ });
+ }
+
+ if (argumentCount > 2) {
+ if (!encodeArgument(encoder.get(), context, arguments[2], exception))
+ return JSValueMakeUndefined(context);
+ }
+
+ // FIXME: Add the support for specifying IPC options.
+
+ connection.sendMessage(WTFMove(encoder), { });
+ return returnValue;
+}
+
+namespace {
+
+struct SyncIPCMessageInfo {
+ uint64_t destinationID;
+ IPC::MessageName messageName;
+ IPC::Timeout timeout;
+};
+
+}
+
+static std::optional<SyncIPCMessageInfo> extractSyncIPCMessageInfo(JSContextRef context, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ ASSERT(argumentCount >= 2);
+ auto* globalObject = toJS(context);
+ auto destinationID = destinationIDFromArgument(globalObject, arguments[0], exception);
+ if (!destinationID)
+ return std::nullopt;
+
+ auto messageID = messageIDFromArgument(globalObject, arguments[1], exception);
+ if (!messageID)
+ return std::nullopt;
+
+ Seconds timeoutDuration;
+ {
+ auto jsValue = toJS(globalObject, arguments[2]);
+ if (!jsValue.isNumber()) {
+ *exception = createTypeError(context, "Timeout must be a number"_s);
+ return std::nullopt;
+ }
+ timeoutDuration = Seconds { jsValue.asNumber() };
+ }
+
+ return { { *destinationID, static_cast<IPC::MessageName>(*messageID), { timeoutDuration } } };
+}
+
+static JSValueRef sendSyncMessageWithJSArguments(IPC::Connection& connection, JSContextRef context, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ auto* globalObject = toJS(context);
+ JSC::JSLockHolder lock(globalObject->vm());
+ auto info = extractSyncIPCMessageInfo(context, argumentCount, arguments, exception);
+ if (!info)
+ return JSValueMakeUndefined(context);
+
+ auto [destinationID, messageName, timeout] = *info;
+
+ // FIXME: Support the options.
+
+ IPC::Connection::SyncRequestID syncRequestID;
+ auto encoder = connection.createSyncMessageEncoder(messageName, destinationID, syncRequestID);
+
+ if (argumentCount > 3) {
+ if (!encodeArgument(encoder.get(), context, arguments[3], exception))
+ return JSValueMakeUndefined(context);
+ }
+
+ if (auto replyDecoder = connection.sendSyncMessage(syncRequestID, WTFMove(encoder), timeout, { })) {
+ auto scope = DECLARE_CATCH_SCOPE(globalObject->vm());
+ auto* jsResult = jsResultFromReplyDecoder(globalObject, messageName, *replyDecoder);
+ if (scope.exception()) {
+ *exception = toRef(globalObject, scope.exception());
+ scope.clearException();
+ return JSValueMakeUndefined(context);
+ }
+ return toRef(globalObject, jsResult);
+ }
+
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef waitForMessageWithJSArguments(IPC::Connection& connection, JSContextRef context, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ auto* globalObject = toJS(context);
+ JSC::JSLockHolder lock(globalObject->vm());
+
+ auto info = extractSyncIPCMessageInfo(context, argumentCount, arguments, exception);
+ if (!info)
+ return JSValueMakeUndefined(context);
+
+ auto [destinationID, messageName, timeout] = *info;
+ if (auto decoder = connection.waitForMessageForTesting(messageName, destinationID, timeout, { })) {
+ auto scope = DECLARE_CATCH_SCOPE(globalObject->vm());
+ auto jsResult = jsValueForArguments(globalObject, messageName, *decoder);
+ if (scope.exception()) {
+ *exception = toRef(globalObject, scope.exception());
+ scope.clearException();
+ return JSValueMakeUndefined(context);
+ }
+ return jsResult ? toRef(globalObject, *jsResult) : JSValueMakeUndefined(context);
+ }
+ return JSValueMakeUndefined(context);
+}
+
JSObjectRef JSIPCSemaphore::createJSWrapper(JSContextRef context)
{
auto* globalObject = toJS(context);
@@ -370,6 +596,210 @@
return functions;
}
+
+JSObjectRef JSIPCAttachment::createJSWrapper(JSContextRef context)
+{
+ auto* globalObject = toJS(context);
+ auto& vm = globalObject->vm();
+ JSC::JSLockHolder lock(vm);
+ auto scope = DECLARE_CATCH_SCOPE(vm);
+ JSObjectRef wrapperObject = JSObjectMake(toGlobalRef(globalObject), wrapperClass(), this);
+ scope.clearException();
+ return wrapperObject;
+}
+
+JSClassRef JSIPCAttachment::wrapperClass()
+{
+ static JSClassRef jsClass;
+ if (!jsClass) {
+ JSClassDefinition definition = kJSClassDefinitionEmpty;
+ definition.className = "Attachment";
+ definition.parentClass = nullptr;
+ definition.staticValues = nullptr;
+ definition.staticFunctions = staticFunctions();
+ definition.initialize = initialize;
+ definition.finalize = finalize;
+ jsClass = JSClassCreate(&definition);
+ }
+ return jsClass;
+}
+
+inline JSIPCAttachment* JSIPCAttachment::unwrap(JSObjectRef object)
+{
+ return static_cast<JSIPCAttachment*>(JSObjectGetPrivate(object));
+}
+
+JSIPCAttachment* JSIPCAttachment::toWrapped(JSContextRef context, JSValueRef value)
+{
+ if (!context || !value || !JSValueIsObjectOfClass(context, value, wrapperClass()))
+ return nullptr;
+ return unwrap(JSValueToObject(context, value, nullptr));
+}
+
+void JSIPCAttachment::initialize(JSContextRef, JSObjectRef object)
+{
+ unwrap(object)->ref();
+}
+
+void JSIPCAttachment::finalize(JSObjectRef object)
+{
+ unwrap(object)->deref();
+}
+
+const JSStaticFunction* JSIPCAttachment::staticFunctions()
+{
+ static const JSStaticFunction functions[] = {
+ { 0, 0, 0 }
+ };
+ return functions;
+}
+
+JSObjectRef JSIPCConnection::createJSWrapper(JSContextRef context)
+{
+ auto* globalObject = toJS(context);
+ auto& vm = globalObject->vm();
+ JSC::JSLockHolder lock(vm);
+ auto scope = DECLARE_CATCH_SCOPE(vm);
+ JSObjectRef wrapperObject = JSObjectMake(toGlobalRef(globalObject), wrapperClass(), this);
+ scope.clearException();
+ return wrapperObject;
+}
+
+JSClassRef JSIPCConnection::wrapperClass()
+{
+ static JSClassRef jsClass;
+ if (!jsClass) {
+ JSClassDefinition definition = kJSClassDefinitionEmpty;
+ definition.className = "Connection";
+ definition.parentClass = nullptr;
+ definition.staticValues = nullptr;
+ definition.staticFunctions = staticFunctions();
+ definition.initialize = initialize;
+ definition.finalize = finalize;
+ jsClass = JSClassCreate(&definition);
+ }
+ return jsClass;
+}
+
+inline JSIPCConnection* JSIPCConnection::unwrap(JSObjectRef object)
+{
+ return static_cast<JSIPCConnection*>(JSObjectGetPrivate(object));
+}
+
+JSIPCConnection* JSIPCConnection::toWrapped(JSContextRef context, JSValueRef value)
+{
+ if (!context || !value || !JSValueIsObjectOfClass(context, value, wrapperClass()))
+ return nullptr;
+ return unwrap(JSValueToObject(context, value, nullptr));
+}
+
+void JSIPCConnection::initialize(JSContextRef, JSObjectRef object)
+{
+ unwrap(object)->ref();
+}
+
+void JSIPCConnection::finalize(JSObjectRef object)
+{
+ unwrap(object)->deref();
+}
+
+void JSIPCConnection::didReceiveMessage(IPC::Connection&, IPC::Decoder&)
+{
+ ASSERT_NOT_REACHED();
+}
+
+bool JSIPCConnection::didReceiveSyncMessage(IPC::Connection&, IPC::Decoder&, UniqueRef<IPC::Encoder>&)
+{
+ ASSERT_NOT_REACHED();
+}
+
+void JSIPCConnection::didClose(IPC::Connection&)
+{
+}
+
+void JSIPCConnection::didReceiveInvalidMessage(IPC::Connection&, IPC::MessageName)
+{
+ ASSERT_NOT_REACHED();
+}
+
+
+const JSStaticFunction* JSIPCConnection::staticFunctions()
+{
+ static const JSStaticFunction functions[] = {
+ { "open", open, kJSPropertyAttributeDontDelete | kJSPropertyAttributeReadOnly },
+ { "invalidate", invalidate, kJSPropertyAttributeDontDelete | kJSPropertyAttributeReadOnly },
+ { "sendMessage", sendMessage, kJSPropertyAttributeDontDelete | kJSPropertyAttributeReadOnly },
+ { "sendSyncMessage", sendSyncMessage, kJSPropertyAttributeDontDelete | kJSPropertyAttributeReadOnly },
+ { "waitForMessage", waitForMessage, kJSPropertyAttributeDontDelete | kJSPropertyAttributeReadOnly },
+ { 0, 0, 0 }
+ };
+ return functions;
+}
+
+JSValueRef JSIPCConnection::open(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t, const JSValueRef[], JSValueRef* exception)
+{
+ RefPtr self = toWrapped(context, thisObject);
+ if (!self) {
+ *exception = createTypeError(context, "Wrong type"_s);
+ return JSValueMakeUndefined(context);
+ }
+ self->m_testedConnection->open();
+ return JSValueMakeUndefined(context);
+}
+
+JSValueRef JSIPCConnection::invalidate(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t, const JSValueRef[], JSValueRef* exception)
+{
+ RefPtr self = toWrapped(context, thisObject);
+ if (!self) {
+ *exception = createTypeError(context, "Wrong type"_s);
+ return JSValueMakeUndefined(context);
+ }
+ self->m_testedConnection->invalidate();
+ return JSValueMakeUndefined(context);
+}
+
+JSValueRef JSIPCConnection::sendMessage(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ RefPtr self = toWrapped(context, thisObject);
+ if (!self) {
+ *exception = createTypeError(context, "Wrong type"_s);
+ return JSValueMakeUndefined(context);
+ }
+ if (argumentCount < 2) {
+ *exception = createTypeError(context, "Must specify the destination ID and message ID as the first two arguments"_s);
+ return JSValueMakeUndefined(context);
+ }
+ return sendMessageWithJSArguments(self->m_testedConnection, context, argumentCount, arguments, exception);
+}
+
+JSValueRef JSIPCConnection::sendSyncMessage(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ RefPtr self = toWrapped(context, thisObject);
+ if (!self) {
+ *exception = createTypeError(context, "Wrong type"_s);
+ return JSValueMakeUndefined(context);
+ }
+ if (argumentCount < 2) {
+ *exception = createTypeError(context, "Must specify the destination ID and message ID as the first two arguments"_s);
+ return JSValueMakeUndefined(context);
+ }
+ return sendSyncMessageWithJSArguments(self->m_testedConnection, context, argumentCount, arguments, exception);
+}
+
+JSValueRef JSIPCConnection::waitForMessage(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ RefPtr self = toWrapped(context, thisObject);
+ if (!self) {
+ *exception = createTypeError(context, "Wrong type"_s);
+ return JSValueMakeUndefined(context);
+ }
+ if (argumentCount < 2) {
+ *exception = createTypeError(context, "Must specify the destination ID and message ID as the first two arguments"_s);
+ return JSValueMakeUndefined(context);
+ }
+ return waitForMessageWithJSArguments(self->m_testedConnection, context, argumentCount, arguments, exception);
+}
+
JSObjectRef JSIPCStreamClientConnection::createJSWrapper(JSContextRef context)
{
auto* globalObject = toJS(context);
@@ -508,7 +938,7 @@
{
// FIXME: Add support for sending in-stream IPC messages when appropriate.
if (argumentCount > 3) {
- if (!encodeArgument(encoder, jsIPC, context, arguments[3], exception))
+ if (!encodeArgument(encoder, context, arguments[3], exception))
return false;
}
@@ -1118,6 +1548,7 @@
{ "sendMessage", sendMessage, kJSPropertyAttributeDontDelete | kJSPropertyAttributeReadOnly },
{ "sendSyncMessage", sendSyncMessage, kJSPropertyAttributeDontDelete | kJSPropertyAttributeReadOnly },
{ "waitForMessage", waitForMessage, kJSPropertyAttributeDontDelete | kJSPropertyAttributeReadOnly },
+ { "createConnectionPair", createConnectionPair, kJSPropertyAttributeDontDelete | kJSPropertyAttributeReadOnly },
{ "createStreamClientConnection", createStreamClientConnection, kJSPropertyAttributeDontDelete | kJSPropertyAttributeReadOnly },
{ "createSemaphore", createSemaphore, kJSPropertyAttributeDontDelete | kJSPropertyAttributeReadOnly },
{ "createSharedMemory", createSharedMemory, kJSPropertyAttributeDontDelete | kJSPropertyAttributeReadOnly },
@@ -1356,6 +1787,21 @@
return true;
}
+static bool encodeFrameInfoData(IPC::Encoder& encoder, JSC::JSGlobalObject* globalObject, JSC::JSObject* jsObject, JSC::CatchScope& scope)
+{
+ auto jsIPCValue = jsObject->get(globalObject, JSC::Identifier::fromString(globalObject->vm(), "value"_s));
+ if (scope.exception())
+ return false;
+ RefPtr jsIPC = JSIPC::toWrapped(toRef(globalObject), toRef(jsIPCValue));
+ if (!jsIPC)
+ return false;
+ RefPtr webFrame = jsIPC->webFrame();
+ if (!webFrame)
+ return false;
+ encoder << webFrame->info();
+ return true;
+}
+
static bool encodeStreamConnectionBuffer(IPC::Encoder& encoder, JSC::JSGlobalObject* globalObject, JSC::JSValue jsValue, JSC::CatchScope& scope)
{
RefPtr jsIPCStreamConnectionBuffer = JSIPCStreamConnectionBuffer::toWrapped(toRef(globalObject), toRef(jsValue));
@@ -1376,8 +1822,17 @@
return true;
}
+static bool encodeAttachment(IPC::Encoder& encoder, JSC::JSGlobalObject* globalObject, JSC::JSValue jsValue, JSC::CatchScope& scope)
+{
+ RefPtr jsIPCAttachment = JSIPCAttachment::toWrapped(toRef(globalObject), toRef(jsValue));
+ if (!jsIPCAttachment)
+ return false;
+
+ jsIPCAttachment->encode(encoder);
+ return true;
+}
+
struct VectorEncodeHelper {
- Ref<JSIPC> jsIPC;
JSContextRef context;
JSValueRef valueRef;
JSValueRef* exception;
@@ -1387,12 +1842,12 @@
{
if (!success)
return;
- success = encodeArgument(encoder, jsIPC.get(), context, valueRef, exception);
+ success = encodeArgument(encoder, context, valueRef, exception);
}
};
enum class ArrayMode { Tuple, Vector };
-static bool encodeArrayArgument(IPC::Encoder& encoder, JSIPC& jsIPC, ArrayMode arrayMode, JSContextRef context, JSValueRef valueRef, JSValueRef* exception)
+static bool encodeArrayArgument(IPC::Encoder& encoder, ArrayMode arrayMode, JSContextRef context, JSValueRef valueRef, JSValueRef* exception)
{
auto objectRef = JSValueToObject(context, valueRef, exception);
ASSERT(objectRef);
@@ -1418,7 +1873,7 @@
auto itemRef = JSObjectGetPropertyAtIndex(context, objectRef, i, exception);
if (!itemRef)
return false;
- vector.append(VectorEncodeHelper { jsIPC, context, itemRef, exception, success });
+ vector.append(VectorEncodeHelper { context, itemRef, exception, success });
}
if (arrayMode == ArrayMode::Tuple) {
for (auto& item : vector)
@@ -1428,7 +1883,7 @@
return success;
}
-static bool encodeArgument(IPC::Encoder& encoder, JSIPC& jsIPC, JSContextRef context, JSValueRef valueRef, JSValueRef* exception)
+static bool encodeArgument(IPC::Encoder& encoder, JSContextRef context, JSValueRef valueRef, JSValueRef* exception)
{
auto objectRef = JSValueToObject(context, valueRef, exception);
if (!objectRef)
@@ -1438,7 +1893,7 @@
return encodeTypedArray(encoder, context, objectRef, type, exception);
if (JSValueIsArray(context, objectRef))
- return encodeArrayArgument(encoder, jsIPC, ArrayMode::Tuple, context, objectRef, exception);
+ return encodeArrayArgument(encoder, ArrayMode::Tuple, context, objectRef, exception);
auto* globalObject = toJS(context);
auto& vm = globalObject->vm();
@@ -1505,12 +1960,10 @@
}
if (type == "FrameInfoData") {
- RefPtr webFrame = jsIPC.webFrame();
- if (!webFrame) {
+ if (!encodeFrameInfoData(encoder, globalObject, jsObject, scope)) {
*exception = createTypeError(context, "Failed to get the frame"_s);
return false;
}
- encoder << webFrame->info();
return true;
}
@@ -1534,12 +1987,20 @@
return true;
}
+ if (type == "Attachment") {
+ if (!encodeAttachment(encoder, globalObject, jsValue, scope)) {
+ *exception = createTypeError(context, "Failed to convert Attachment"_s);
+ return false;
+ }
+ return true;
+ }
+
if (type == "Vector") {
if (!jsValue.inherits<JSC::JSArray>()) {
*exception = createTypeError(context, "Vector value must be an array"_s);
return false;
}
- return encodeArrayArgument(encoder, jsIPC, ArrayMode::Vector, context, toRef(globalObject, jsValue), exception);
+ return encodeArrayArgument(encoder, ArrayMode::Vector, context, toRef(globalObject, jsValue), exception);
}
if (type == "String") {
@@ -1670,185 +2131,78 @@
*exception = createTypeError(context, "Wrong type"_s);
return JSValueMakeUndefined(context);
}
-
if (argumentCount < 3) {
*exception = createTypeError(context, "Must specify the target process, destination ID, and message ID as the first three arguments"_s);
return JSValueMakeUndefined(context);
}
-
auto connection = processTargetFromArgument(globalObject, arguments[0], exception);
if (!connection)
return JSValueMakeUndefined(context);
+ return sendMessageWithJSArguments(*connection, context, argumentCount - 1, arguments + 1, exception);
+}
- auto destinationID = destinationIDFromArgument(globalObject, arguments[1], exception);
- if (!destinationID)
+JSValueRef JSIPC::waitForMessage(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ RefPtr jsIPC = toWrapped(context, thisObject);
+ if (!jsIPC) {
+ *exception = createTypeError(context, "Wrong type"_s);
return JSValueMakeUndefined(context);
-
- auto messageID = messageIDFromArgument(globalObject, arguments[2], exception);
- if (!messageID)
- return JSValueMakeUndefined(context);
-
- auto messageName = static_cast<IPC::MessageName>(*messageID);
- auto encoder = makeUniqueRef<IPC::Encoder>(messageName, *destinationID);
-
- JSValueRef returnValue = JSValueMakeUndefined(context);
-
- bool hasReply = !!messageReplyArgumentDescriptions(messageName);
- if (hasReply) {
- uint64_t listenerID = IPC::nextAsyncReplyHandlerID();
- encoder.get() << listenerID;
-
- JSObjectRef resolve;
- JSObjectRef reject;
-ALLOW_NEW_API_WITHOUT_GUARDS_BEGIN
- returnValue = JSObjectMakeDeferredPromise(context, &resolve, &reject, exception);
-ALLOW_NEW_API_WITHOUT_GUARDS_END
- if (!returnValue)
- return JSValueMakeUndefined(context);
-
- JSGlobalContextRetain(JSContextGetGlobalContext(context));
- JSValueProtect(context, resolve);
- JSValueProtect(context, reject);
- IPC::addAsyncReplyHandler(*connection, listenerID, [messageName, context, resolve, reject](IPC::Decoder* replyDecoder) {
- auto* globalObject = toJS(context);
- auto& vm = globalObject->vm();
- JSC::JSLockHolder lock(vm);
-
- auto scope = DECLARE_CATCH_SCOPE(vm);
- auto* jsResult = jsResultFromReplyDecoder(globalObject, messageName, *replyDecoder);
- if (auto* exception = scope.exception()) {
- scope.clearException();
- JSValueRef arguments[] = { toRef(globalObject, exception) };
- JSObjectCallAsFunction(context, reject, reject, 1, arguments, nullptr);
- } else {
- JSValueRef arguments[] = { toRef(globalObject, jsResult) };
- JSObjectCallAsFunction(context, resolve, resolve, 1, arguments, nullptr);
- }
-
- JSValueUnprotect(context, reject);
- JSValueUnprotect(context, resolve);
- JSGlobalContextRelease(JSContextGetGlobalContext(context));
- });
}
-
- if (argumentCount > 3) {
- if (!encodeArgument(encoder.get(), *jsIPC, context, arguments[3], exception))
- return JSValueMakeUndefined(context);
- }
-
- // FIXME: Add the support for specifying IPC options.
-
- connection->sendMessage(WTFMove(encoder), { });
-
- return returnValue;
-}
-
-struct SyncIPCMessageInfo {
- Ref<IPC::Connection> connection;
- uint64_t destinationID;
- IPC::MessageName messageName;
- IPC::Timeout timeout;
-};
-
-static std::optional<SyncIPCMessageInfo> extractSyncIPCMessageInfo(JSContextRef context, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
-{
- if (argumentCount < 4) {
+ if (argumentCount < 3) {
*exception = createTypeError(context, "Must specify the target process, destination ID, and message ID as the first three arguments"_s);
- return std::nullopt;
+ return JSValueMakeUndefined(context);
}
-
auto* globalObject = toJS(context);
+ JSC::JSLockHolder lock(globalObject->vm());
auto connection = processTargetFromArgument(globalObject, arguments[0], exception);
if (!connection)
- return std::nullopt;
-
- auto destinationID = destinationIDFromArgument(globalObject, arguments[1], exception);
- if (!destinationID)
- return std::nullopt;
-
- auto messageID = messageIDFromArgument(globalObject, arguments[2], exception);
- if (!messageID)
- return std::nullopt;
-
- Seconds timeoutDuration;
- {
- auto jsValue = toJS(globalObject, arguments[3]);
- if (!jsValue.isNumber()) {
- *exception = createTypeError(context, "Timeout must be a number"_s);
- return std::nullopt;
- }
- timeoutDuration = Seconds { jsValue.asNumber() };
- }
-
- return { { connection.releaseNonNull(), *destinationID, static_cast<IPC::MessageName>(*messageID), { timeoutDuration } } };
+ return JSValueMakeUndefined(context);
+ return waitForMessageWithJSArguments(*connection, context, argumentCount - 1, arguments + 1, exception);
}
-JSValueRef JSIPC::waitForMessage(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+JSValueRef JSIPC::sendSyncMessage(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
- auto* globalObject = toJS(context);
- JSC::JSLockHolder lock(globalObject->vm());
RefPtr jsIPC = toWrapped(context, thisObject);
if (!jsIPC) {
*exception = createTypeError(context, "Wrong type"_s);
return JSValueMakeUndefined(context);
}
-
- auto info = extractSyncIPCMessageInfo(context, argumentCount, arguments, exception);
- if (!info)
+ if (argumentCount < 3) {
+ *exception = createTypeError(context, "Must specify the target process, destination ID, and message ID as the first three arguments"_s);
return JSValueMakeUndefined(context);
-
- auto [connection, destinationID, messageName, timeout] = *info;
- if (auto decoder = connection->waitForMessage(messageName, destinationID, timeout, { })) {
- auto scope = DECLARE_CATCH_SCOPE(globalObject->vm());
- auto jsResult = jsValueForArguments(globalObject, messageName, *decoder);
- if (scope.exception()) {
- *exception = toRef(globalObject, scope.exception());
- scope.clearException();
- return JSValueMakeUndefined(context);
- }
- return jsResult ? toRef(globalObject, *jsResult) : JSValueMakeUndefined(context);
}
- return JSValueMakeUndefined(context);
+ auto* globalObject = toJS(context);
+ JSC::JSLockHolder lock(globalObject->vm());
+ auto connection = processTargetFromArgument(globalObject, arguments[0], exception);
+ if (!connection)
+ return JSValueMakeUndefined(context);
+ return sendSyncMessageWithJSArguments(*connection, context, argumentCount - 1, arguments + 1, exception);
}
-JSValueRef JSIPC::sendSyncMessage(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+JSValueRef JSIPC::createConnectionPair(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
- auto* globalObject = toJS(context);
- JSC::JSLockHolder lock(globalObject->vm());
RefPtr jsIPC = toWrapped(context, thisObject);
if (!jsIPC) {
*exception = createTypeError(context, "Wrong type"_s);
return JSValueMakeUndefined(context);
}
-
- auto info = extractSyncIPCMessageInfo(context, argumentCount, arguments, exception);
- if (!info)
+ auto connectionIdentifiers = IPC::Connection::createConnectionIdentifierPair();
+ if (!connectionIdentifiers)
return JSValueMakeUndefined(context);
-
- auto [connection, destinationID, messageName, timeout] = *info;
-
- // FIXME: Support the options.
-
- IPC::Connection::SyncRequestID syncRequestID;
- auto encoder = connection->createSyncMessageEncoder(messageName, destinationID, syncRequestID);
-
- if (argumentCount > 4) {
- if (!encodeArgument(encoder.get(), *jsIPC, context, arguments[4], exception))
- return JSValueMakeUndefined(context);
- }
-
- if (auto replyDecoder = connection->sendSyncMessage(syncRequestID, WTFMove(encoder), timeout, { })) {
- auto scope = DECLARE_CATCH_SCOPE(globalObject->vm());
- auto* jsResult = jsResultFromReplyDecoder(globalObject, messageName, *replyDecoder);
- if (scope.exception()) {
- *exception = toRef(globalObject, scope.exception());
- scope.clearException();
- return JSValueMakeUndefined(context);
- }
- return toRef(globalObject, jsResult);
- }
-
- return JSValueMakeUndefined(context);
+ auto* globalObject = toJS(context);
+ JSC::JSLockHolder lock(globalObject->vm());
+ auto& vm = globalObject->vm();
+ auto scope = DECLARE_CATCH_SCOPE(vm);
+ JSC::JSObject* connectionPairObject = JSC::constructEmptyArray(globalObject, nullptr);
+ RETURN_IF_EXCEPTION(scope, JSValueMakeUndefined(context));
+ int index = 0;
+ auto jsValue = toJS(globalObject, JSIPCConnection::create(WTFMove(connectionIdentifiers->server))->createJSWrapper(context));
+ connectionPairObject->putDirectIndex(globalObject, index++, jsValue);
+ RETURN_IF_EXCEPTION(scope, JSValueMakeUndefined(context));
+ jsValue = toJS(globalObject, JSIPCAttachment::create(WTFMove(connectionIdentifiers->client))->createJSWrapper(context));
+ connectionPairObject->putDirectIndex(globalObject, index++, jsValue);
+ RETURN_IF_EXCEPTION(scope, JSValueMakeUndefined(context));
+ return toRef(vm, connectionPairObject);
}
JSValueRef JSIPC::createStreamClientConnection(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
Modified: trunk/Tools/ChangeLog (293566 => 293567)
--- trunk/Tools/ChangeLog 2022-04-28 05:36:41 UTC (rev 293566)
+++ trunk/Tools/ChangeLog 2022-04-28 07:18:08 UTC (rev 293567)
@@ -1,3 +1,15 @@
+2022-04-28 Kimmo Kinnunen <kkinnu...@apple.com>
+
+ IPC testing API should have the ability to test IPC::Connection send and receive through IPC::Connection
+ https://bugs.webkit.org/show_bug.cgi?id=239495
+
+ Reviewed by Darin Adler.
+
+ * TestWebKitAPI/Tests/WebKitCocoa/IPCTestingAPI.mm:
+ (TEST):
+ Change two tests to pass "IPC" object as the value of FrameInfoData. This way the argument encode functions
+ do not need to take the JSIPC argument.
+
2022-04-27 Sihui Liu <sihui_...@apple.com>
[ iOS ] TestWebKitAPI.IndexedDB.IndexedDBSuspendImminently is a constant timeout
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/IPCTestingAPI.mm (293566 => 293567)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/IPCTestingAPI.mm 2022-04-28 05:36:41 UTC (rev 293566)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/IPCTestingAPI.mm 2022-04-28 07:18:08 UTC (rev 293567)
@@ -177,7 +177,7 @@
done = false;
[webView synchronouslyLoadHTMLString:@"<!DOCTYPE html><script>IPC.sendSyncMessage('UI', IPC.webPageProxyID, IPC.messages.WebPageProxy_RunJavaScriptAlert.name, 100,"
- "[{type: 'uint64_t', value: IPC.frameID}, {type: 'FrameInfoData'}, {'type': 'String', 'value': 'hi'}]);</script>"];
+ "[{type: 'uint64_t', value: IPC.frameID}, {type: 'FrameInfoData', value: IPC}, {'type': 'String', 'value': 'hi'}]);</script>"];
TestWebKitAPI::Util::run(&done);
EXPECT_STREQ([alertMessage UTF8String], "hi");
@@ -345,7 +345,7 @@
done = false;
promptResult = @"foo";
[webView synchronouslyLoadHTMLString:@"<!DOCTYPE html><script>result = IPC.sendSyncMessage('UI', IPC.webPageProxyID, IPC.messages.WebPageProxy_RunJavaScriptPrompt.name, 100,"
- "[{type: 'uint64_t', value: IPC.frameID}, {type: 'FrameInfoData'}, {'type': 'String', 'value': 'hi'}, {'type': 'String', 'value': 'bar'}]);</script>"];
+ "[{type: 'uint64_t', value: IPC.frameID}, {type: 'FrameInfoData', value: IPC}, {'type': 'String', 'value': 'hi'}, {'type': 'String', 'value': 'bar'}]);</script>"];
TestWebKitAPI::Util::run(&done);
EXPECT_STREQ([promptDefault UTF8String], "bar");
_______________________________________________ webkit-changes mailing list webkit-changes@lists.webkit.org https://lists.webkit.org/mailman/listinfo/webkit-changes