WebKit Bugzilla
Attachment 362388 Details for
Bug 193806
: [PlayStation] Upstream playstation's remote inspector server
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Inspector Server
rwi-patch-post-review.diff (text/plain), 66.71 KB, created by
Christopher Reid
on 2019-02-19 09:49:05 PST
(
hide
)
Description:
Inspector Server
Filename:
MIME Type:
Creator:
Christopher Reid
Created:
2019-02-19 09:49:05 PST
Size:
66.71 KB
patch
obsolete
>diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog >index 5efd343acdb..a57e179312d 100644 >--- a/Source/JavaScriptCore/ChangeLog >+++ b/Source/JavaScriptCore/ChangeLog >@@ -1,3 +1,33 @@ >+2019-02-19 Christopher Reid <chris.reid@sony.com> >+ >+ [PlayStation] Upstream playstation's remote inspector server >+ https://bugs.webkit.org/show_bug.cgi?id=193806 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Upstreaming PlayStation's Remote Inspector implementation. >+ It is using a JSON RPC protocol over TCP sockets. >+ This inspector implementation is planned to also support running on a WinCairo Client and Server. >+ >+ * PlatformPlayStation.cmake: >+ * SourcesGTK.txt: >+ * SourcesWPE.txt: >+ * inspector/remote/RemoteConnectionToTarget.cpp: Renamed from Source/JavaScriptCore/inspector/remote/glib/RemoteConnectionToTargetGlib.cpp. >+ * inspector/remote/RemoteInspector.h: >+ * inspector/remote/playstation/RemoteInspectorConnectionClient.h: Added. >+ * inspector/remote/playstation/RemoteInspectorConnectionClientPlayStation.cpp: Added. >+ * inspector/remote/playstation/RemoteInspectorMessageParser.h: Added. >+ * inspector/remote/playstation/RemoteInspectorMessageParserPlayStation.cpp: Added. >+ * inspector/remote/playstation/RemoteInspectorPlayStation.cpp: Added. >+ * inspector/remote/playstation/RemoteInspectorServer.h: Added. >+ * inspector/remote/playstation/RemoteInspectorServerPlayStation.cpp: Added. >+ * inspector/remote/playstation/RemoteInspectorSocket.h: Added. >+ * inspector/remote/playstation/RemoteInspectorSocketClient.h: Added. >+ * inspector/remote/playstation/RemoteInspectorSocketClientPlayStation.cpp: Added. >+ * inspector/remote/playstation/RemoteInspectorSocketPlayStation.cpp: Added. >+ * inspector/remote/playstation/RemoteInspectorSocketServer.h: Added. >+ * inspector/remote/playstation/RemoteInspectorSocketServerPlayStation.cpp: Added. >+ > 2019-02-04 Mark Lam <mark.lam@apple.com> > > DFG's doesGC() is incorrect about the SameValue node's behavior. >diff --git a/Source/JavaScriptCore/PlatformPlayStation.cmake b/Source/JavaScriptCore/PlatformPlayStation.cmake >index 02fcb4e01e2..edb21fb65f1 100644 >--- a/Source/JavaScriptCore/PlatformPlayStation.cmake >+++ b/Source/JavaScriptCore/PlatformPlayStation.cmake >@@ -1,3 +1,40 @@ >+list(APPEND JavaScriptCore_PRIVATE_INCLUDE_DIRECTORIES >+ "${JAVASCRIPTCORE_DIR}/inspector/remote/playstation" >+) >+ >+list(APPEND JavaScriptCore_PRIVATE_FRAMEWORK_HEADERS >+ inspector/remote/RemoteAutomationTarget.h >+ inspector/remote/RemoteConnectionToTarget.h >+ inspector/remote/RemoteControllableTarget.h >+ inspector/remote/RemoteInspectionTarget.h >+ inspector/remote/RemoteInspector.h >+ >+ inspector/remote/playstation/RemoteInspectorConnectionClient.h >+ inspector/remote/playstation/RemoteInspectorMessageParser.h >+ inspector/remote/playstation/RemoteInspectorServer.h >+ inspector/remote/playstation/RemoteInspectorSocket.h >+ inspector/remote/playstation/RemoteInspectorSocketClient.h >+ inspector/remote/playstation/RemoteInspectorSocketServer.h >+) >+ >+list(APPEND JavaScriptCore_SOURCES >+ API/JSRemoteInspector.cpp >+ >+ inspector/remote/RemoteAutomationTarget.cpp >+ inspector/remote/RemoteConnectionToTarget.cpp >+ inspector/remote/RemoteControllableTarget.cpp >+ inspector/remote/RemoteInspectionTarget.cpp >+ inspector/remote/RemoteInspector.cpp >+ >+ inspector/remote/playstation/RemoteInspectorConnectionClientPlayStation.cpp >+ inspector/remote/playstation/RemoteInspectorMessageParserPlayStation.cpp >+ inspector/remote/playstation/RemoteInspectorPlayStation.cpp >+ inspector/remote/playstation/RemoteInspectorServerPlayStation.cpp >+ inspector/remote/playstation/RemoteInspectorSocketClientPlayStation.cpp >+ inspector/remote/playstation/RemoteInspectorSocketPlayStation.cpp >+ inspector/remote/playstation/RemoteInspectorSocketServerPlayStation.cpp >+) >+ > if (${WTF_LIBRARY_TYPE} STREQUAL "STATIC") > add_definitions(-DSTATICALLY_LINKED_WITH_WTF) > endif () >diff --git a/Source/JavaScriptCore/SourcesGTK.txt b/Source/JavaScriptCore/SourcesGTK.txt >index d72613fb2f9..974e9d24c1f 100644 >--- a/Source/JavaScriptCore/SourcesGTK.txt >+++ b/Source/JavaScriptCore/SourcesGTK.txt >@@ -24,11 +24,11 @@ > API/JSRemoteInspector.cpp > > inspector/remote/RemoteAutomationTarget.cpp >+inspector/remote/RemoteConnectionToTarget.cpp > inspector/remote/RemoteControllableTarget.cpp > inspector/remote/RemoteInspectionTarget.cpp > inspector/remote/RemoteInspector.cpp > >-inspector/remote/glib/RemoteConnectionToTargetGlib.cpp > inspector/remote/glib/RemoteInspectorGlib.cpp > inspector/remote/glib/RemoteInspectorServer.cpp > inspector/remote/glib/RemoteInspectorUtils.cpp >diff --git a/Source/JavaScriptCore/SourcesWPE.txt b/Source/JavaScriptCore/SourcesWPE.txt >index d72613fb2f9..6680eacdfa1 100644 >--- a/Source/JavaScriptCore/SourcesWPE.txt >+++ b/Source/JavaScriptCore/SourcesWPE.txt >@@ -24,11 +24,12 @@ > API/JSRemoteInspector.cpp > > inspector/remote/RemoteAutomationTarget.cpp >+inspector/remote/RemoteConnectionToTarget.cpp > inspector/remote/RemoteControllableTarget.cpp > inspector/remote/RemoteInspectionTarget.cpp > inspector/remote/RemoteInspector.cpp > >-inspector/remote/glib/RemoteConnectionToTargetGlib.cpp >+ > inspector/remote/glib/RemoteInspectorGlib.cpp > inspector/remote/glib/RemoteInspectorServer.cpp > inspector/remote/glib/RemoteInspectorUtils.cpp >diff --git a/Source/JavaScriptCore/inspector/remote/glib/RemoteConnectionToTargetGlib.cpp b/Source/JavaScriptCore/inspector/remote/RemoteConnectionToTarget.cpp >similarity index 100% >rename from Source/JavaScriptCore/inspector/remote/glib/RemoteConnectionToTargetGlib.cpp >rename to Source/JavaScriptCore/inspector/remote/RemoteConnectionToTarget.cpp >diff --git a/Source/JavaScriptCore/inspector/remote/RemoteInspector.h b/Source/JavaScriptCore/inspector/remote/RemoteInspector.h >index 389e843fab6..b3ddf956415 100644 >--- a/Source/JavaScriptCore/inspector/remote/RemoteInspector.h >+++ b/Source/JavaScriptCore/inspector/remote/RemoteInspector.h >@@ -51,6 +51,18 @@ typedef struct _GDBusConnection GDBusConnection; > typedef struct _GDBusInterfaceVTable GDBusInterfaceVTable; > #endif > >+#if PLATFORM(PLAYSTATION) >+#include "RemoteInspectorConnectionClient.h" >+#include "RemoteInspectorSocketClient.h" >+#include <wtf/JSONValues.h> >+#include <wtf/RefCounted.h> >+#include <wtf/RefPtr.h> >+ >+namespace Inspector { >+using TargetListing = RefPtr<JSON::Object>; >+} >+#endif >+ > namespace Inspector { > > class RemoteAutomationTarget; >@@ -62,6 +74,8 @@ class RemoteInspectorClient; > class JS_EXPORT_PRIVATE RemoteInspector final > #if PLATFORM(COCOA) > : public RemoteInspectorXPCConnection::Client >+#elif PLATFORM(PLAYSTATION) >+ : public RemoteInspectorConnectionClient > #endif > { > public: >@@ -128,9 +142,14 @@ public: > > #if USE(GLIB) > void requestAutomationSession(const char* sessionID, const Client::SessionCapabilities&); >+#endif >+#if USE(GLIB) || PLATFORM(PLAYSTATION) > void setup(unsigned targetIdentifier); > void sendMessageToTarget(unsigned targetIdentifier, const char* message); > #endif >+#if PLATFORM(PLAYSTATION) >+ static void setConnectionIdentifier(PlatformSocketType); >+#endif > > private: > RemoteInspector(); >@@ -184,7 +203,17 @@ private: > void receivedAutomaticInspectionRejectMessage(NSDictionary *userInfo); > void receivedAutomationSessionRequestMessage(NSDictionary *userInfo); > #endif >+#if PLATFORM(PLAYSTATION) >+ HashMap<String, CallHandler>& dispatchMap() override; >+ void didClose(ClientID) override; >+ >+ void sendWebInspectorEvent(const String&); > >+ void receivedGetTargetListMessage(const struct InspectorEvent&); >+ void receivedSetupMessage(const struct InspectorEvent&); >+ void receivedDataMessage(const struct InspectorEvent&); >+ void receivedCloseMessage(const struct InspectorEvent&); >+#endif > static bool startEnabled; > > // Targets can be registered from any thread at any time. >@@ -205,6 +234,12 @@ private: > GRefPtr<GCancellable> m_cancellable; > #endif > >+#if PLATFORM(PLAYSTATION) >+ std::unique_ptr<RemoteInspectorSocketClient> m_socketConnection; >+ static PlatformSocketType s_connectionIdentifier; >+ Optional<ClientID> m_clientID; >+#endif >+ > RemoteInspector::Client* m_client { nullptr }; > Optional<RemoteInspector::Client::Capabilities> m_clientCapabilities; > >diff --git a/Source/JavaScriptCore/inspector/remote/playstation/RemoteInspectorConnectionClient.h b/Source/JavaScriptCore/inspector/remote/playstation/RemoteInspectorConnectionClient.h >new file mode 100644 >index 00000000000..cb0b1dd906a >--- /dev/null >+++ b/Source/JavaScriptCore/inspector/remote/playstation/RemoteInspectorConnectionClient.h >@@ -0,0 +1,59 @@ >+/* >+ * Copyright (C) 2019 Sony Interactive Entertainment Inc. >+ * >+ * 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(REMOTE_INSPECTOR) >+ >+#include "RemoteInspectorSocket.h" >+#include <wtf/WeakPtr.h> >+#include <wtf/text/WTFString.h> >+ >+namespace Inspector { >+ >+class RemoteInspectorConnectionClient : public CanMakeWeakPtr<RemoteInspectorConnectionClient> { >+public: >+ >+ void didReceiveWebInspectorEvent(ClientID, Vector<uint8_t>&&); >+ virtual void didAccept(ClientID, RemoteInspectorSocket::DomainType) { }; >+ virtual void didClose(ClientID) = 0; >+ >+protected: >+ struct InspectorEvent { >+ ClientID clientID; >+ Optional<uint64_t> connectionID; >+ Optional<uint64_t> targetID; >+ Optional<String> message; >+ }; >+ >+ >+public: >+ using CallHandler = void (RemoteInspectorConnectionClient::*)(const struct InspectorEvent&); >+ virtual HashMap<String, CallHandler>& dispatchMap() = 0; >+}; >+ >+} // namespace Inspector >+ >+#endif // ENABLE(REMOTE_INSPECTOR) >diff --git a/Source/JavaScriptCore/inspector/remote/playstation/RemoteInspectorConnectionClientPlayStation.cpp b/Source/JavaScriptCore/inspector/remote/playstation/RemoteInspectorConnectionClientPlayStation.cpp >new file mode 100644 >index 00000000000..2bb5ae20409 >--- /dev/null >+++ b/Source/JavaScriptCore/inspector/remote/playstation/RemoteInspectorConnectionClientPlayStation.cpp >@@ -0,0 +1,85 @@ >+/* >+ * Copyright (C) 2019 Sony Interactive Entertainment Inc. >+ * >+ * 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 "RemoteInspectorConnectionClient.h" >+ >+#if ENABLE(REMOTE_INSPECTOR) >+ >+#include "RemoteInspectorSocket.h" >+#include <wtf/JSONValues.h> >+#include <wtf/RunLoop.h> >+ >+namespace Inspector { >+ >+void RemoteInspectorConnectionClient::didReceiveWebInspectorEvent(ClientID clientID, Vector<uint8_t>&& data) >+{ >+ ASSERT(!isMainThread()); >+ >+ if (data.isEmpty()) >+ return; >+ >+ String jsonData = String::fromUTF8(data); >+ >+ RefPtr<JSON::Value> messageValue; >+ if (!JSON::Value::parseJSON(jsonData, messageValue)) >+ return; >+ >+ RefPtr<JSON::Object> messageObject; >+ if (!messageValue->asObject(messageObject)) >+ return; >+ >+ String methodName; >+ if (!messageObject->getString("event"_s, methodName)) >+ return; >+ >+ struct InspectorEvent event; >+ event.clientID = clientID; >+ >+ uint64_t connectionID; >+ if (messageObject->getInteger("connectionID"_s, connectionID)) >+ event.connectionID = connectionID; >+ >+ uint64_t targetID; >+ if (messageObject->getInteger("targetID"_s, targetID)) >+ event.targetID = targetID; >+ >+ String message; >+ if (messageObject->getString("message"_s, message)) >+ event.message = message; >+ >+ RunLoop::main().dispatch([this, methodName, event = WTFMove(event)] { >+ auto& methods = dispatchMap(); >+ if (methods.contains(methodName)) { >+ auto call = methods.get(methodName); >+ (this->*call)(event); >+ } else >+ LOG_ERROR("Unknown event: %s", methodName.utf8().data()); >+ }); >+} >+ >+} // namespace Inspector >+ >+#endif // ENABLE(REMOTE_INSPECTOR) >diff --git a/Source/JavaScriptCore/inspector/remote/playstation/RemoteInspectorMessageParser.h b/Source/JavaScriptCore/inspector/remote/playstation/RemoteInspectorMessageParser.h >new file mode 100644 >index 00000000000..cfa49782919 >--- /dev/null >+++ b/Source/JavaScriptCore/inspector/remote/playstation/RemoteInspectorMessageParser.h >@@ -0,0 +1,61 @@ >+/* >+ * Copyright (C) 2019 Sony Interactive Entertainment Inc. >+ * >+ * 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(REMOTE_INSPECTOR) >+ >+namespace Inspector { >+ >+ /* >+ | <--- one message for send / didReceiveData ---> | >+ +--------------+----------------------------------+-------------- >+ | size | data | (next message) >+ | 4byte | variable length | >+ +--------------+----------------------------------+-------------- >+ | <------------ size ------------> | >+ */ >+ >+class MessageParser { >+public: >+ static Vector<uint8_t> createMessage(const uint8_t*, size_t); >+ >+ MessageParser(ClientID, size_t); >+ void pushReceivedData(const uint8_t*, size_t); >+ void setDidParseMessageListener(Function<void(ClientID, Vector<uint8_t>)>&& listener) { m_didParseMessageListener = >+WTFMove(listener); } >+ >+ void clearReceivedData(); >+ >+private: >+ bool parse(); >+ Function<void(ClientID, Vector<uint8_t>&&)> m_didParseMessageListener; >+ Vector<uint8_t> m_buffer; >+ ClientID m_clientID; >+}; >+ >+} // namespace Inspector >+ >+#endif // ENABLE(REMOTE_INSPECTOR) >diff --git a/Source/JavaScriptCore/inspector/remote/playstation/RemoteInspectorMessageParserPlayStation.cpp b/Source/JavaScriptCore/inspector/remote/playstation/RemoteInspectorMessageParserPlayStation.cpp >new file mode 100644 >index 00000000000..8540170489d >--- /dev/null >+++ b/Source/JavaScriptCore/inspector/remote/playstation/RemoteInspectorMessageParserPlayStation.cpp >@@ -0,0 +1,113 @@ >+/* >+ * Copyright (C) 2019 Sony Interactive Entertainment Inc. >+ * >+ * 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 "RemoteInspectorMessageParser.h" >+ >+#if ENABLE(REMOTE_INSPECTOR) >+ >+namespace Inspector { >+ >+/* >+| <--- one message for send / didReceiveData ---> | >++--------------+----------------------------------+-------------- >+| size | data | (next message) >+| 4byte | variable length | >++--------------+----------------------------------+-------------- >+ | <------------ size ------------> | >+*/ >+ >+MessageParser::MessageParser(ClientID clientID, size_t bufferSize) >+ : m_clientID(clientID) >+{ >+ m_buffer.reserveCapacity(bufferSize); >+} >+ >+Vector<uint8_t> MessageParser::createMessage(const uint8_t* data, size_t size) >+{ >+ if (!data || !size || size > UINT_MAX) >+ return Vector<uint8_t>(); >+ >+ auto messageBuffer = Vector<uint8_t>(size + sizeof(uint32_t)); >+ uint32_t uintSize = static_cast<uint32_t>(size); >+ memcpy(&messageBuffer[0], &uintSize, sizeof(uint32_t)); >+ memcpy(&messageBuffer[sizeof(uint32_t)], data, uintSize); >+ return messageBuffer; >+} >+ >+void MessageParser::pushReceivedData(const uint8_t* data, size_t size) >+{ >+ if (!data || !size) >+ return; >+ >+ m_buffer.reserveCapacity(m_buffer.size() + size); >+ m_buffer.append(data, size); >+ >+ if (!parse()) >+ clearReceivedData(); >+} >+ >+void MessageParser::clearReceivedData() >+{ >+ m_buffer.clear(); >+} >+ >+bool MessageParser::parse() >+{ >+ while (!m_buffer.isEmpty()) { >+ if (m_buffer.size() < sizeof(uint32_t)) { >+ // Wait for more data. >+ return true; >+ } >+ >+ uint32_t dataSize = 0; >+ memcpy(&dataSize, &m_buffer[0], sizeof(uint32_t)); >+ if (!dataSize) { >+ LOG_ERROR("Message Parser received an invalid message size"); >+ return false; >+ } >+ >+ size_t messageSize = (sizeof(uint32_t) + dataSize); >+ if (m_buffer.size() < messageSize) { >+ // Wait for more data. >+ return true; >+ } >+ >+ // FIXME: This should avoid re-creating a new data Vector. >+ auto dataBuffer = Vector<uint8_t>(dataSize); >+ memcpy(&dataBuffer[0], &m_buffer[sizeof(uint32_t)], dataSize); >+ >+ if (m_didParseMessageListener) >+ m_didParseMessageListener(m_clientID, WTFMove(dataBuffer)); >+ >+ m_buffer.remove(0, messageSize); >+ } >+ >+ return true; >+} >+ >+} // namespace Inspector >+ >+#endif // ENABLE(REMOTE_INSPECTOR) >diff --git a/Source/JavaScriptCore/inspector/remote/playstation/RemoteInspectorPlayStation.cpp b/Source/JavaScriptCore/inspector/remote/playstation/RemoteInspectorPlayStation.cpp >new file mode 100644 >index 00000000000..5e3c2322e53 >--- /dev/null >+++ b/Source/JavaScriptCore/inspector/remote/playstation/RemoteInspectorPlayStation.cpp >@@ -0,0 +1,300 @@ >+/* >+ * Copyright (C) 2019 Sony Interactive Entertainment Inc. >+ * >+ * 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 "RemoteInspector.h" >+ >+#if ENABLE(REMOTE_INSPECTOR) >+ >+#include "RemoteAutomationTarget.h" >+#include "RemoteConnectionToTarget.h" >+#include "RemoteInspectionTarget.h" >+#include <wtf/JSONValues.h> >+#include <wtf/MainThread.h> >+#include <wtf/NeverDestroyed.h> >+#include <wtf/RunLoop.h> >+ >+namespace Inspector { >+ >+PlatformSocketType RemoteInspector::s_connectionIdentifier = INVALID_SOCKET_VALUE; >+ >+RemoteInspector& RemoteInspector::singleton() >+{ >+ static NeverDestroyed<RemoteInspector> shared; >+ return shared; >+} >+ >+RemoteInspector::RemoteInspector() >+{ >+ start(); >+} >+ >+void RemoteInspector::didClose(ClientID clientID) >+{ >+ if (clientID != m_clientID.value()) >+ return; >+ >+ RunLoop::current().dispatch([=] { >+ std::lock_guard<Lock> lock(m_mutex); >+ stopInternal(StopSource::API); >+ }); >+} >+ >+HashMap<String, RemoteInspector::CallHandler>& RemoteInspector::dispatchMap() >+{ >+ static NeverDestroyed<HashMap<String, CallHandler>> methods = HashMap<String, CallHandler>({ >+ {"GetTargetList"_s, static_cast<CallHandler>(&RemoteInspector::receivedGetTargetListMessage)}, >+ {"Setup"_s, static_cast<CallHandler>(&RemoteInspector::receivedSetupMessage)}, >+ {"SendMessageToTarget"_s, static_cast<CallHandler>(&RemoteInspector::receivedDataMessage)}, >+ {"FrontendDidClose"_s, static_cast<CallHandler>(&RemoteInspector::receivedCloseMessage)}, >+ }); >+ >+ return methods; >+} >+ >+void RemoteInspector::sendWebInspectorEvent(const String& event) >+{ >+ if (!m_clientID) >+ return; >+ >+ const CString message = event.utf8(); >+ m_socketConnection->send(m_clientID.value(), reinterpret_cast<const uint8_t*>(message.data()), message.length()); >+} >+ >+void RemoteInspector::start() >+{ >+ std::lock_guard<Lock> lock(m_mutex); >+ >+ if (m_enabled || s_connectionIdentifier == INVALID_SOCKET_VALUE) >+ return; >+ >+ m_enabled = true; >+ >+ m_socketConnection = RemoteInspectorSocketClient::create(this); >+ >+ m_clientID = m_socketConnection->createClient(s_connectionIdentifier); >+ >+ if (!m_targetMap.isEmpty()) >+ pushListingsSoon(); >+} >+ >+void RemoteInspector::stopInternal(StopSource) >+{ >+ if (!m_enabled) >+ return; >+ >+ m_enabled = false; >+ m_pushScheduled = false; >+ >+ for (auto targetConnection : m_targetConnectionMap.values()) >+ targetConnection->close(); >+ m_targetConnectionMap.clear(); >+ >+ updateHasActiveDebugSession(); >+ >+ m_automaticInspectionPaused = false; >+ m_socketConnection = nullptr; >+ m_clientID = WTF::nullopt; >+ s_connectionIdentifier = INVALID_SOCKET_VALUE; >+} >+ >+TargetListing RemoteInspector::listingForInspectionTarget(const RemoteInspectionTarget& target) const >+{ >+ if (!target.remoteDebuggingAllowed()) >+ return nullptr; >+ >+ // FIXME: Support remote debugging of a ServiceWorker. >+ if (target.type() == RemoteInspectionTarget::Type::ServiceWorker) >+ return nullptr; >+ >+ TargetListing targetListing = JSON::Object::create(); >+ >+ targetListing->setString("name"_s, target.name()); >+ targetListing->setString("url"_s, target.name()); >+ targetListing->setInteger("targetID"_s, target.targetIdentifier()); >+ targetListing->setBoolean("hasLocalDebugger"_s, target.hasLocalDebugger()); >+ if (target.type() == RemoteInspectionTarget::Type::Web) >+ targetListing->setString("type"_s, "Web"_s); >+ else if (target.type() == RemoteInspectionTarget::Type::JavaScript) >+ targetListing->setString("type"_s, "JavaScript"_s); >+ else if (target.type() == RemoteInspectionTarget::Type::ServiceWorker) >+ targetListing->setString("type"_s, "ServiceWorker"_s); >+ >+ return targetListing; >+} >+ >+TargetListing RemoteInspector::listingForAutomationTarget(const RemoteAutomationTarget&) const >+{ >+ return nullptr; >+} >+ >+void RemoteInspector::pushListingsNow() >+{ >+ if (!m_socketConnection) >+ return; >+ >+ m_pushScheduled = false; >+ >+ auto targetListJSON = JSON::Array::create(); >+ for (auto listing : m_targetListingMap.values()) >+ targetListJSON->pushObject(listing); >+ >+ auto jsonEvent = JSON::Object::create(); >+ jsonEvent->setString("event"_s, "SetTargetList"_s); >+ jsonEvent->setString("message"_s, targetListJSON->toJSONString()); >+ sendWebInspectorEvent(jsonEvent->toJSONString()); >+} >+ >+void RemoteInspector::pushListingsSoon() >+{ >+ if (!m_socketConnection) >+ return; >+ >+ if (m_pushScheduled) >+ return; >+ >+ m_pushScheduled = true; >+ >+ RunLoop::current().dispatch([=] { >+ std::lock_guard<Lock> lock(m_mutex); >+ if (m_pushScheduled) >+ pushListingsNow(); >+ }); >+} >+ >+void RemoteInspector::updateAutomaticInspectionCandidate(RemoteInspectionTarget*) >+{ >+} >+ >+void RemoteInspector::sendAutomaticInspectionCandidateMessage() >+{ >+} >+ >+void RemoteInspector::sendMessageToRemote(unsigned targetIdentifier, const String& message) >+{ >+ std::lock_guard<Lock> lock(m_mutex); >+ if (!m_socketConnection) >+ return; >+ >+ auto sendMessageEvent = JSON::Object::create(); >+ sendMessageEvent->setInteger("targetID"_s, targetIdentifier); >+ sendMessageEvent->setString("event"_s, "SendMessageToFrontend"_s); >+ sendMessageEvent->setString("message"_s, message); >+ sendWebInspectorEvent(sendMessageEvent->toJSONString()); >+} >+ >+void RemoteInspector::receivedGetTargetListMessage(const InspectorEvent&) >+{ >+ ASSERT(isMainThread()); >+ >+ std::lock_guard<Lock> lock(m_mutex); >+ pushListingsNow(); >+} >+ >+void RemoteInspector::receivedSetupMessage(const InspectorEvent& event) >+{ >+ ASSERT(isMainThread()); >+ >+ if (event.targetID) >+ setup(event.targetID.value()); >+} >+ >+void RemoteInspector::receivedDataMessage(const InspectorEvent& event) >+{ >+ ASSERT(isMainThread()); >+ >+ if (!event.targetID || !event.message) >+ return; >+ >+ RefPtr<RemoteConnectionToTarget> connectionToTarget; >+ { >+ std::lock_guard<Lock> lock(m_mutex); >+ connectionToTarget = m_targetConnectionMap.get(event.targetID.value()); >+ if (!connectionToTarget) >+ return; >+ } >+ >+ connectionToTarget->sendMessageToTarget(event.message.value()); >+} >+ >+void RemoteInspector::receivedCloseMessage(const InspectorEvent& event) >+{ >+ ASSERT(isMainThread()); >+ >+ if (!event.targetID) >+ return; >+ >+ RefPtr<RemoteConnectionToTarget> connectionToTarget; >+ { >+ std::lock_guard<Lock> lock(m_mutex); >+ RemoteControllableTarget* target = m_targetMap.get(event.targetID.value()); >+ if (!target) >+ return; >+ >+ connectionToTarget = m_targetConnectionMap.take(event.targetID.value()); >+ updateHasActiveDebugSession(); >+ } >+ >+ if (connectionToTarget) >+ connectionToTarget->close(); >+} >+ >+void RemoteInspector::setup(unsigned targetIdentifier) >+{ >+ RemoteControllableTarget* target; >+ { >+ std::lock_guard<Lock> lock(m_mutex); >+ target = m_targetMap.get(targetIdentifier); >+ if (!target) >+ return; >+ } >+ >+ auto connectionToTarget = adoptRef(*new RemoteConnectionToTarget(*target)); >+ ASSERT(is<RemoteInspectionTarget>(target) || is<RemoteAutomationTarget>(target)); >+ if (!connectionToTarget->setup()) { >+ connectionToTarget->close(); >+ return; >+ } >+ >+ std::lock_guard<Lock> lock(m_mutex); >+ m_targetConnectionMap.set(targetIdentifier, WTFMove(connectionToTarget)); >+ >+ updateHasActiveDebugSession(); >+} >+ >+void RemoteInspector::sendMessageToTarget(unsigned targetIdentifier, const char* message) >+{ >+ if (auto connectionToTarget = m_targetConnectionMap.get(targetIdentifier)) >+ connectionToTarget->sendMessageToTarget(String::fromUTF8(message)); >+} >+ >+void RemoteInspector::setConnectionIdentifier(PlatformSocketType connectionIdentifier) >+{ >+ RemoteInspector::s_connectionIdentifier = connectionIdentifier; >+} >+ >+} // namespace Inspector >+ >+#endif // ENABLE(REMOTE_INSPECTOR) >diff --git a/Source/JavaScriptCore/inspector/remote/playstation/RemoteInspectorServer.h b/Source/JavaScriptCore/inspector/remote/playstation/RemoteInspectorServer.h >new file mode 100644 >index 00000000000..bb1b7758896 >--- /dev/null >+++ b/Source/JavaScriptCore/inspector/remote/playstation/RemoteInspectorServer.h >@@ -0,0 +1,81 @@ >+/* >+ * Copyright (C) 2019 Sony Interactive Entertainment Inc. >+ * >+ * 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(REMOTE_INSPECTOR) >+ >+#include "RemoteInspector.h" >+ >+#include "RemoteInspectorConnectionClient.h" >+#include "RemoteInspectorSocketServer.h" >+#include <wtf/HashMap.h> >+#include <wtf/HashSet.h> >+ >+namespace Inspector { >+ >+class RemoteInspectorServer : public RemoteInspectorConnectionClient { >+public: >+ JS_EXPORT_PRIVATE static RemoteInspectorServer& singleton(); >+ >+ JS_EXPORT_PRIVATE bool start(unsigned); >+ bool isRunning() const { return !!m_server; } >+ >+ JS_EXPORT_PRIVATE void addServerConnection(PlatformSocketType); >+ >+private: >+ void connectionClosed(uint64_t connectionID); >+ >+ void setTargetList(const struct InspectorEvent&); >+ void setupInspectorClient(const struct InspectorEvent&); >+ void setup(const struct InspectorEvent&); >+ void close(const struct InspectorEvent&); >+ void sendMessageToFrontend(const struct InspectorEvent&); >+ void sendMessageToBackend(const struct InspectorEvent&); >+ >+ void sendCloseEvent(uint64_t connectionID, uint64_t targetID); >+ void clientConnectionClosed(); >+ >+ void didAccept(ClientID, RemoteInspectorSocket::DomainType) override; >+ void didClose(ClientID) override; >+ >+ void sendWebInspectorEvent(ClientID, const String&); >+ >+ HashMap<String, CallHandler>& dispatchMap(); >+ >+ HashSet<std::pair<uint64_t, uint64_t>> m_inspectionTargets; >+ >+ std::unique_ptr<RemoteInspectorSocketServer> m_server; >+ >+ // Connections to the WebProcess. >+ Vector<ClientID> m_inspectorConnections; >+ >+ // Connections from RemoteInspectorClient. >+ Optional<ClientID> m_clientConnection; >+}; >+ >+} // namespace Inspector >+ >+#endif // ENABLE(REMOTE_INSPECTOR) >diff --git a/Source/JavaScriptCore/inspector/remote/playstation/RemoteInspectorServerPlayStation.cpp b/Source/JavaScriptCore/inspector/remote/playstation/RemoteInspectorServerPlayStation.cpp >new file mode 100644 >index 00000000000..f061f466a79 >--- /dev/null >+++ b/Source/JavaScriptCore/inspector/remote/playstation/RemoteInspectorServerPlayStation.cpp >@@ -0,0 +1,232 @@ >+/* >+ * Copyright (C) 2019 Sony Interactive Entertainment Inc. >+ * >+ * 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 "RemoteInspectorServer.h" >+ >+#if ENABLE(REMOTE_INSPECTOR) >+ >+#include <wtf/JSONValues.h> >+#include <wtf/MainThread.h> >+ >+namespace Inspector { >+ >+void RemoteInspectorServer::addServerConnection(PlatformSocketType identifier) >+{ >+ if (!m_server) >+ return; >+ >+ if (auto id = m_server->createClient(identifier)) >+ m_inspectorConnections.append(id.value()); >+} >+ >+void RemoteInspectorServer::didAccept(ClientID clientID, RemoteInspectorSocket::DomainType type) >+{ >+ ASSERT(!isMainThread()); >+ >+ if (type == RemoteInspectorSocket::DomainType::Inet) { >+ if (m_clientConnection) { >+ LOG_ERROR("Inspector server can accept only 1 client"); >+ return; >+ } >+ m_clientConnection = clientID; >+ } else if (type == RemoteInspectorSocket::DomainType::Unix) >+ m_inspectorConnections.append(clientID); >+} >+ >+void RemoteInspectorServer::didClose(ClientID clientID) >+{ >+ ASSERT(!isMainThread()); >+ >+ if (clientID == m_clientConnection) { >+ // Connection from the remote client closed. >+ callOnMainThread([this] { >+ clientConnectionClosed(); >+ }); >+ return; >+ } >+ >+ // Connection from WebProcess closed. >+ callOnMainThread([this, clientID] { >+ connectionClosed(clientID); >+ }); >+} >+ >+HashMap<String, RemoteInspectorConnectionClient::CallHandler>& RemoteInspectorServer::dispatchMap() >+{ >+ static NeverDestroyed<HashMap<String, CallHandler>> dispatchMap = HashMap<String, CallHandler>({ >+ {"SetTargetList"_s, static_cast<CallHandler>(&RemoteInspectorServer::setTargetList)}, >+ {"SetupInspectorClient"_s, static_cast<CallHandler>(&RemoteInspectorServer::setupInspectorClient)}, >+ {"Setup"_s, static_cast<CallHandler>(&RemoteInspectorServer::setup)}, >+ {"FrontendDidClose"_s, static_cast<CallHandler>(&RemoteInspectorServer::close)}, >+ {"SendMessageToFrontend"_s, static_cast<CallHandler>(&RemoteInspectorServer::sendMessageToFrontend)}, >+ {"SendMessageToBackend"_s, static_cast<CallHandler>(&RemoteInspectorServer::sendMessageToBackend)}, >+ }); >+ >+ return dispatchMap; >+} >+ >+void RemoteInspectorServer::sendWebInspectorEvent(ClientID clientID, const String& event) >+{ >+ const CString message = event.utf8(); >+ m_server->send(clientID, reinterpret_cast<const uint8_t*>(message.data()), message.length()); >+} >+ >+RemoteInspectorServer& RemoteInspectorServer::singleton() >+{ >+ static NeverDestroyed<RemoteInspectorServer> server; >+ return server; >+} >+ >+bool RemoteInspectorServer::start(unsigned port) >+{ >+ m_server = RemoteInspectorSocketServer::create(this); >+ >+ if (!m_server->listenInet(port)) { >+ m_server = nullptr; >+ return false; >+ } >+ >+ return true; >+} >+ >+void RemoteInspectorServer::setTargetList(const InspectorEvent& event) >+{ >+ ASSERT(isMainThread()); >+ >+ if (!m_clientConnection || !event.message) >+ return; >+ >+ auto targetListEvent = JSON::Object::create(); >+ targetListEvent->setString("event"_s, "SetTargetList"_s); >+ targetListEvent->setInteger("connectionID"_s, event.clientID); >+ targetListEvent->setString("message"_s, event.message.value()); >+ sendWebInspectorEvent(m_clientConnection.value(), targetListEvent->toJSONString()); >+} >+ >+void RemoteInspectorServer::setupInspectorClient(const InspectorEvent&) >+{ >+ ASSERT(isMainThread()); >+ >+ auto setupEvent = JSON::Object::create(); >+ setupEvent->setString("event"_s, "GetTargetList"_s); >+ >+ for (auto connection : m_inspectorConnections) >+ sendWebInspectorEvent(connection, setupEvent->toJSONString()); >+} >+ >+void RemoteInspectorServer::setup(const InspectorEvent& event) >+{ >+ ASSERT(isMainThread()); >+ >+ if (!event.targetID || !event.connectionID) >+ return; >+ >+ m_inspectionTargets.add(std::make_pair(event.connectionID.value(), event.targetID.value())); >+ >+ auto setupEvent = JSON::Object::create(); >+ setupEvent->setString("event"_s, "Setup"_s); >+ setupEvent->setInteger("targetID"_s, event.targetID.value()); >+ sendWebInspectorEvent(event.connectionID.value(), setupEvent->toJSONString()); >+} >+ >+void RemoteInspectorServer::sendCloseEvent(uint64_t connectionID, uint64_t targetID) >+{ >+ ASSERT(isMainThread()); >+ >+ auto closeEvent = JSON::Object::create(); >+ closeEvent->setString("event"_s, "FrontendDidClose"_s); >+ closeEvent->setInteger("targetID"_s, targetID); >+ sendWebInspectorEvent(connectionID, closeEvent->toJSONString()); >+} >+ >+void RemoteInspectorServer::close(const InspectorEvent& event) >+{ >+ ASSERT(isMainThread()); >+ >+ sendCloseEvent(event.connectionID.value(), event.targetID.value()); >+ m_inspectionTargets.remove(std::make_pair(event.connectionID.value(), event.targetID.value())); >+} >+ >+void RemoteInspectorServer::clientConnectionClosed() >+{ >+ ASSERT(isMainThread()); >+ >+ for (auto connectionTargetPair : m_inspectionTargets) >+ sendCloseEvent(connectionTargetPair.first, connectionTargetPair.second); >+ >+ m_inspectionTargets.clear(); >+ m_clientConnection = WTF::nullopt; >+} >+ >+void RemoteInspectorServer::connectionClosed(uint64_t clientID) >+{ >+ ASSERT(isMainThread()); >+ >+ if (m_inspectorConnections.removeFirst(clientID) && m_clientConnection) { >+ auto closedEvent = JSON::Object::create(); >+ closedEvent->setString("event"_s, "SetTargetList"_s); >+ closedEvent->setInteger("connectionID"_s, clientID); >+ auto targetList = JSON::Array::create(); >+ closedEvent->setString("message"_s, targetList->toJSONString()); >+ sendWebInspectorEvent(m_clientConnection.value(), closedEvent->toJSONString()); >+ } >+} >+ >+void RemoteInspectorServer::sendMessageToBackend(const InspectorEvent& event) >+{ >+ ASSERT(isMainThread()); >+ >+ if (!event.connectionID || !event.targetID || !event.message) >+ return; >+ >+ auto sendEvent = JSON::Object::create(); >+ sendEvent->setString("event"_s, "SendMessageToTarget"_s); >+ sendEvent->setInteger("targetID"_s, event.targetID.value()); >+ sendEvent->setString("message"_s, event.message.value()); >+ sendWebInspectorEvent(event.connectionID.value(), sendEvent->toJSONString()); >+} >+ >+void RemoteInspectorServer::sendMessageToFrontend(const InspectorEvent& event) >+{ >+ if (!m_clientConnection) >+ return; >+ >+ ASSERT(isMainThread()); >+ >+ if (!event.targetID || !event.message) >+ return; >+ >+ auto sendEvent = JSON::Object::create(); >+ sendEvent->setString("event"_s, "SendMessageToFrontend"_s); >+ sendEvent->setInteger("targetID"_s, event.targetID.value()); >+ sendEvent->setInteger("connectionID"_s, event.clientID); >+ sendEvent->setString("message"_s, event.message.value()); >+ sendWebInspectorEvent(m_clientConnection.value(), sendEvent->toJSONString()); >+} >+ >+} // namespace Inspector >+ >+#endif // ENABLE(REMOTE_INSPECTOR) >diff --git a/Source/JavaScriptCore/inspector/remote/playstation/RemoteInspectorSocket.h b/Source/JavaScriptCore/inspector/remote/playstation/RemoteInspectorSocket.h >new file mode 100644 >index 00000000000..5f23f9f49c2 >--- /dev/null >+++ b/Source/JavaScriptCore/inspector/remote/playstation/RemoteInspectorSocket.h >@@ -0,0 +1,92 @@ >+/* >+ * Copyright (C) 2019 Sony Interactive Entertainment Inc. >+ * >+ * 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(REMOTE_INSPECTOR) >+ >+#include <poll.h> >+#include <thread> >+#include <wtf/Condition.h> >+#include <wtf/Function.h> >+#include <wtf/HashMap.h> >+#include <wtf/Lock.h> >+#include <wtf/Threading.h> >+#include <wtf/Vector.h> >+#include <wtf/WeakPtr.h> >+ >+namespace Inspector { >+ >+using ClientID = unsigned; >+using PlatformSocketType = int; >+constexpr PlatformSocketType INVALID_SOCKET_VALUE = -1; >+ >+class MessageParser; >+class RemoteInspectorConnectionClient; >+ >+class JS_EXPORT_PRIVATE RemoteInspectorSocket { >+public: >+ RemoteInspectorSocket(RemoteInspectorConnectionClient*); >+ ~RemoteInspectorSocket(); >+ >+ enum class DomainType { >+ Unix, >+ Inet, >+ }; >+ >+ void send(ClientID, const uint8_t* data, size_t); >+ >+ Optional<ClientID> createClient(PlatformSocketType fd); >+ >+protected: >+ void recvIfEnabled(ClientID); >+ void sendIfEnabled(ClientID); >+ void workerThread(); >+ void wakeupWorkerThread(); >+ void acceptInetSocketIfEnabled(ClientID); >+ bool isListening(ClientID); >+ >+ struct connection { >+ std::unique_ptr<MessageParser> parser; >+ Vector<uint8_t> sendBuffer; >+ struct pollfd poll; >+ PlatformSocketType socket { INVALID_SOCKET_VALUE }; >+ }; >+ >+ Lock m_connectionsLock; >+ HashMap<ClientID, std::unique_ptr<struct connection>> m_connections; >+ >+ PlatformSocketType m_wakeupSendSocket { INVALID_SOCKET_VALUE }; >+ PlatformSocketType m_wakeupReceiveSocket { INVALID_SOCKET_VALUE }; >+ >+ RefPtr<Thread> m_workerThread; >+ std::atomic<bool> m_shouldAbortWorkerThread { false }; >+ >+ WeakPtr<RemoteInspectorConnectionClient> m_inspectorClient; >+}; >+ >+} // namespace Inspector >+ >+#endif // ENABLE(REMOTE_INSPECTOR) >diff --git a/Source/JavaScriptCore/inspector/remote/playstation/RemoteInspectorSocketClient.h b/Source/JavaScriptCore/inspector/remote/playstation/RemoteInspectorSocketClient.h >new file mode 100644 >index 00000000000..e04f7cfe034 >--- /dev/null >+++ b/Source/JavaScriptCore/inspector/remote/playstation/RemoteInspectorSocketClient.h >@@ -0,0 +1,49 @@ >+/* >+ * Copyright (C) 2019 Sony Interactive Entertainment Inc. >+ * >+ * 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(REMOTE_INSPECTOR) >+ >+#include "RemoteInspectorSocket.h" >+ >+namespace Inspector { >+ >+class JS_EXPORT_PRIVATE RemoteInspectorSocketClient : public RemoteInspectorSocket { >+public: >+ >+ static std::unique_ptr<RemoteInspectorSocketClient> create(RemoteInspectorConnectionClient* inspectorClient) >+ { >+ return std::make_unique<RemoteInspectorSocketClient>(inspectorClient); >+ } >+ >+ RemoteInspectorSocketClient(RemoteInspectorConnectionClient*); >+ >+ Optional<ClientID> connectInet(const char* serverAddr, int serverPort); >+}; >+ >+} // namespace Inspector >+ >+#endif // ENABLE(REMOTE_INSPECTOR) >diff --git a/Source/JavaScriptCore/inspector/remote/playstation/RemoteInspectorSocketClientPlayStation.cpp b/Source/JavaScriptCore/inspector/remote/playstation/RemoteInspectorSocketClientPlayStation.cpp >new file mode 100644 >index 00000000000..47ed116dbd8 >--- /dev/null >+++ b/Source/JavaScriptCore/inspector/remote/playstation/RemoteInspectorSocketClientPlayStation.cpp >@@ -0,0 +1,70 @@ >+/* >+ * Copyright (C) 2019 Sony Interactive Entertainment Inc. >+ * >+ * 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 "RemoteInspectorSocketClient.h" >+ >+#if ENABLE(REMOTE_INSPECTOR) >+ >+#include <arpa/inet.h> >+#include <fcntl.h> >+#include <netinet/in.h> >+#include <sys/socket.h> >+#include <sys/un.h> >+#include <unistd.h> >+ >+namespace Inspector { >+ >+RemoteInspectorSocketClient::RemoteInspectorSocketClient(RemoteInspectorConnectionClient* inspectorClient) >+ : RemoteInspectorSocket(inspectorClient) >+{ >+} >+ >+Optional<ClientID> RemoteInspectorSocketClient::connectInet(const char* serverAddress, int serverPort) >+{ >+ struct sockaddr_in saServer = { 0 }; >+ saServer.sin_family = AF_INET; >+ inet_aton(serverAddress, &saServer.sin_addr); >+ saServer.sin_port = htons(serverPort); >+ >+ int fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); >+ if (fd < 0) { >+ LOG_ERROR("socket() failed, server = %s:%d, ret = %d, errno = %d", serverAddress, serverPort, fd, errno); >+ return WTF::nullopt; >+ } >+ >+ int ret = connect(fd, (struct sockaddr *)&saServer, sizeof(saServer)); >+ if (ret < 0) { >+ LOG_ERROR("connect() failed, server = %s:%d, ret = %d, errno = %d", serverAddress, serverPort, ret, errno); >+ ::close(fd); >+ return WTF::nullopt; >+ } >+ >+ return createClient(fd); >+} >+ >+} // namespace Inspector >+ >+#endif // ENABLE(REMOTE_INSPECTOR) >diff --git a/Source/JavaScriptCore/inspector/remote/playstation/RemoteInspectorSocketPlayStation.cpp b/Source/JavaScriptCore/inspector/remote/playstation/RemoteInspectorSocketPlayStation.cpp >new file mode 100644 >index 00000000000..b231591df40 >--- /dev/null >+++ b/Source/JavaScriptCore/inspector/remote/playstation/RemoteInspectorSocketPlayStation.cpp >@@ -0,0 +1,279 @@ >+/* >+ * Copyright (C) 2019 Sony Interactive Entertainment Inc. >+ * >+ * 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 "RemoteInspectorSocket.h" >+ >+#if ENABLE(REMOTE_INSPECTOR) >+ >+#include "RemoteInspectorConnectionClient.h" >+#include "RemoteInspectorMessageParser.h" >+#include <arpa/inet.h> >+#include <fcntl.h> >+#include <netinet/in.h> >+#include <sys/socket.h> >+#include <sys/un.h> >+#include <unistd.h> >+#include <wtf/CryptographicallyRandomNumber.h> >+#include <wtf/MainThread.h> >+#include <wtf/text/WTFString.h> >+ >+namespace Inspector { >+ >+constexpr size_t SocketBufferSize = 65536; >+ >+static void initializeSocket(PlatformSocketType sockfd) >+{ >+ fcntl(sockfd, F_SETFD, FD_CLOEXEC); >+ int flags = fcntl(sockfd, F_GETFL, 0); >+ fcntl(sockfd, F_SETFL, flags | O_NONBLOCK); >+ >+ setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &SocketBufferSize, sizeof(SocketBufferSize)); >+ setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &SocketBufferSize, sizeof(SocketBufferSize)); >+} >+ >+RemoteInspectorSocket::RemoteInspectorSocket(RemoteInspectorConnectionClient* inspectorClient) >+ : m_inspectorClient(makeWeakPtr(inspectorClient)) >+{ >+ PlatformSocketType sockets[2]; >+ if (!socketpair(AF_UNIX, SOCK_STREAM, 0, sockets)) { >+ m_wakeupSendSocket = sockets[0]; >+ m_wakeupReceiveSocket = sockets[1]; >+ } >+ >+ m_workerThread = Thread::create("Remote Inspector Worker", [this] { >+ workerThread(); >+ }); >+} >+ >+RemoteInspectorSocket::~RemoteInspectorSocket() >+{ >+ ASSERT(m_workerThread.get() != &Thread::current()); >+ >+ m_shouldAbortWorkerThread = true; >+ wakeupWorkerThread(); >+ m_workerThread->waitForCompletion(); >+ >+ ::close(m_wakeupSendSocket); >+ ::close(m_wakeupReceiveSocket); >+ for (const auto& connection : m_connections.values()) { >+ if (connection->socket != INVALID_SOCKET_VALUE) >+ ::close(connection->socket); >+ } >+} >+ >+void RemoteInspectorSocket::wakeupWorkerThread() >+{ >+ if (m_wakeupSendSocket != INVALID_SOCKET_VALUE) >+ ::write(m_wakeupSendSocket, "1", 1); >+} >+ >+bool RemoteInspectorSocket::isListening(ClientID id) >+{ >+ LockHolder lock(m_connectionsLock); >+ if (const auto& connection = m_connections.get(id)) { >+ int out; >+ socklen_t outSize = sizeof(out); >+ if (getsockopt(connection->socket, SOL_SOCKET, SO_ACCEPTCONN, &out, &outSize) != -1) >+ return out != 0; >+ >+ LOG_ERROR("getsockopt errno = %d", errno); >+ } >+ return false; >+} >+ >+void RemoteInspectorSocket::workerThread() >+{ >+ struct pollfd wakeup; >+ wakeup.fd = m_wakeupReceiveSocket; >+ wakeup.events = POLLIN; >+ >+ while (!m_shouldAbortWorkerThread) { >+ Vector<struct pollfd> pollfds; >+ Vector<ClientID> ids; >+ { >+ LockHolder lock(m_connectionsLock); >+ for (const auto& connection : m_connections) { >+ pollfds.append(connection.value->poll); >+ ids.append(connection.key); >+ } >+ } >+ pollfds.append(wakeup); >+ >+ int ret = poll(pollfds.data(), pollfds.size(), -1); >+ if (ret > 0) { >+ if (pollfds.last().revents & POLLIN) { >+ char wakeMessage; >+ ::read(m_wakeupReceiveSocket, &wakeMessage, sizeof(wakeMessage)); >+ continue; >+ } >+ >+ for (size_t i = 0; i < ids.size(); i++) { >+ auto id = ids[i]; >+ >+ if ((pollfds[i].revents & POLLIN) && isListening(id)) >+ acceptInetSocketIfEnabled(id); >+ else if (pollfds[i].revents & POLLIN) >+ recvIfEnabled(id); >+ else if (pollfds[i].revents & POLLOUT) >+ sendIfEnabled(id); >+ } >+ } >+ } >+} >+ >+Optional<ClientID> RemoteInspectorSocket::createClient(PlatformSocketType fd) >+{ >+ if (fd == INVALID_SOCKET_VALUE) >+ return WTF::nullopt; >+ >+ LockHolder lock(m_connectionsLock); >+ >+ ClientID id; >+ do { >+ id = cryptographicallyRandomNumber(); >+ } while (!id || m_connections.contains(id)); >+ >+ initializeSocket(fd); >+ >+ auto connection = std::make_unique<struct connection>(); >+ connection->poll.fd = fd; >+ connection->poll.events = POLLIN; >+ connection->parser = std::make_unique<MessageParser>(id, SocketBufferSize); >+ connection->socket = fd; >+ connection->parser->setDidParseMessageListener([this](ClientID id, Vector<uint8_t>&& data) { >+ if (m_inspectorClient) >+ m_inspectorClient->didReceiveWebInspectorEvent(id, WTFMove(data)); >+ }); >+ >+ m_connections.add(id, WTFMove(connection)); >+ wakeupWorkerThread(); >+ >+ return id; >+} >+ >+void RemoteInspectorSocket::recvIfEnabled(ClientID clientID) >+{ >+ LockHolder lock(m_connectionsLock); >+ if (const auto& connection = m_connections.get(clientID)) { >+ Vector<uint8_t> recvBuffer(SocketBufferSize); >+ ssize_t readSize = ::read(connection->socket, recvBuffer.data(), recvBuffer.size()); >+ >+ if (readSize > 0) { >+ connection->parser->pushReceivedData(recvBuffer.data(), readSize); >+ return; >+ } >+ if (readSize < 0) >+ LOG_ERROR("read error (errno = %d)", errno); >+ >+ ::close(connection->socket); >+ m_connections.remove(clientID); >+ if (m_inspectorClient) >+ m_inspectorClient->didClose(clientID); >+ } >+} >+ >+void RemoteInspectorSocket::sendIfEnabled(ClientID clientID) >+{ >+ LockHolder lock(m_connectionsLock); >+ if (const auto& connection = m_connections.get(clientID)) { >+ connection->poll.events &= ~POLLOUT; >+ if (connection->sendBuffer.isEmpty()) >+ return; >+ >+ ssize_t writeSize = ::write(connection->socket, connection->sendBuffer.data(), std::min(connection->sendBuffer.size(), SocketBufferSize)); >+ if (writeSize > 0 && static_cast<size_t>(writeSize) == connection->sendBuffer.size()) { >+ connection->sendBuffer.clear(); >+ return; >+ } >+ >+ if (writeSize > 0) >+ connection->sendBuffer.remove(0, writeSize); >+ else >+ LOG_ERROR("write error (errno = %d)", errno); >+ >+ connection->poll.events |= POLLOUT; >+ } >+} >+ >+void RemoteInspectorSocket::send(ClientID clientID, const uint8_t* data, size_t size) >+{ >+ LockHolder lock(m_connectionsLock); >+ if (const auto& connection = m_connections.get(clientID)) { >+ auto message = MessageParser::createMessage(data, size); >+ if (message.isEmpty()) >+ return; >+ >+ ssize_t writeSize = 0; >+ if (connection->sendBuffer.isEmpty()) { >+ // Try to call send() directly if buffer is empty. >+ writeSize = ::write(connection->socket, message.data(), std::min(message.size(), SocketBufferSize)); >+ if (writeSize > 0 && static_cast<size_t>(writeSize) == message.size()) { >+ // All data is sent. >+ return; >+ } >+ if (writeSize < 0) { >+ LOG_ERROR("write error (errno = %d)", errno); >+ writeSize = 0; >+ } >+ } >+ >+ // Copy remaining data to send later. >+ connection->sendBuffer.appendRange(message.begin() + writeSize, message.end()); >+ connection->poll.events |= POLLOUT; >+ >+ wakeupWorkerThread(); >+ } >+} >+ >+void RemoteInspectorSocket::acceptInetSocketIfEnabled(ClientID id) >+{ >+ if (!isListening(id)) >+ return; >+ >+ LockHolder lock(m_connectionsLock); >+ if (const auto& connection = m_connections.get(id)) { >+ struct sockaddr_in saClient; >+ memset(&saClient, 0, sizeof(saClient)); >+ socklen_t len = sizeof(struct sockaddr_in); >+ int fd = accept(connection->socket, (struct sockaddr*)&saClient, &len); >+ if (fd < 0) { >+ LOG_ERROR("accept(inet) error (errno = %d)", errno); >+ return; >+ } >+ >+ // Need to unlock before calling createClient as it also attempts to lock. >+ lock.unlockEarly(); >+ auto newID = createClient(fd); >+ if (newID && m_inspectorClient) >+ m_inspectorClient->didAccept(newID.value(), DomainType::Inet); >+ else >+ ::close(fd); >+ } >+} >+ >+} // namespace Inspector >+ >+#endif // ENABLE(REMOTE_INSPECTOR) >diff --git a/Source/JavaScriptCore/inspector/remote/playstation/RemoteInspectorSocketServer.h b/Source/JavaScriptCore/inspector/remote/playstation/RemoteInspectorSocketServer.h >new file mode 100644 >index 00000000000..4e9e4bd6cc7 >--- /dev/null >+++ b/Source/JavaScriptCore/inspector/remote/playstation/RemoteInspectorSocketServer.h >@@ -0,0 +1,48 @@ >+/* >+ * Copyright (C) 2019 Sony Interactive Entertainment Inc. >+ * >+ * 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(REMOTE_INSPECTOR) >+ >+#include "RemoteInspectorSocket.h" >+ >+namespace Inspector { >+ >+class JS_EXPORT_PRIVATE RemoteInspectorSocketServer : public RemoteInspectorSocket { >+public: >+ static std::unique_ptr<RemoteInspectorSocketServer> create(RemoteInspectorConnectionClient* inspectorClient) >+ { >+ return std::make_unique<RemoteInspectorSocketServer>(inspectorClient); >+ } >+ >+ RemoteInspectorSocketServer(RemoteInspectorConnectionClient*); >+ >+ bool listenInet(int port); >+}; >+ >+} // namespace Inspector >+ >+#endif // ENABLE(REMOTE_INSPECTOR) >diff --git a/Source/JavaScriptCore/inspector/remote/playstation/RemoteInspectorSocketServerPlayStation.cpp b/Source/JavaScriptCore/inspector/remote/playstation/RemoteInspectorSocketServerPlayStation.cpp >new file mode 100644 >index 00000000000..4f590d7bfdc >--- /dev/null >+++ b/Source/JavaScriptCore/inspector/remote/playstation/RemoteInspectorSocketServerPlayStation.cpp >@@ -0,0 +1,93 @@ >+/* >+ * Copyright (C) 2019 Sony Interactive Entertainment Inc. >+ * >+ * 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 "RemoteInspectorSocketServer.h" >+ >+#if ENABLE(REMOTE_INSPECTOR) >+ >+namespace Inspector { >+ >+#include <arpa/inet.h> >+#include <fcntl.h> >+#include <netinet/in.h> >+#include <sys/socket.h> >+#include <sys/un.h> >+#include <unistd.h> >+ >+RemoteInspectorSocketServer::RemoteInspectorSocketServer(RemoteInspectorConnectionClient* inspectorClient) >+ : RemoteInspectorSocket(inspectorClient) >+{ >+} >+ >+bool RemoteInspectorSocketServer::listenInet(int port) >+{ >+ struct sockaddr_in saServer = { 0 }; >+ >+ int fdListen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); >+ if (fdListen < 0) { >+ LOG_ERROR("socket() failed, ret = %d, errno = %d", fdListen, errno); >+ return false; >+ } >+ >+ const int enabled = 1; >+ int ret = setsockopt(fdListen, SOL_SOCKET, SO_REUSEADDR, &enabled, sizeof(enabled)); >+ if (ret < 0) { >+ LOG_ERROR("setsockopt() SO_REUSEADDR failed, ret = %d, errno = %d", fdListen, errno); >+ return false; >+ } >+ ret = setsockopt(fdListen, SOL_SOCKET, SO_REUSEPORT, &enabled, sizeof(enabled)); >+ if (ret < 0) { >+ LOG_ERROR("setsockopt() SO_REUSEPORT, ret = %d, errno = %d", fdListen, errno); >+ return false; >+ } >+ >+ // FIXME: Support AF_INET6 connections. >+ saServer.sin_family = AF_INET; >+ saServer.sin_addr.s_addr = htonl(INADDR_ANY); >+ saServer.sin_port = htons(port); >+ ret = bind(fdListen, (struct sockaddr *)&saServer, sizeof(saServer)); >+ if (ret < 0) { >+ LOG_ERROR("bind() failed, ret = %d, errno = %d", ret, errno); >+ ::close(fdListen); >+ return false; >+ } >+ >+ ret = listen(fdListen, 1); >+ if (ret < 0) { >+ LOG_ERROR("listen() failed, ret = %d errno = %d", ret, errno); >+ ::close(fdListen); >+ return false; >+ } >+ >+ if (createClient(fdListen)) >+ return true; >+ >+ return false; >+} >+ >+} // namespace Inspector >+ >+#endif // ENABLE(REMOTE_INSPECTOR)
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 193806
:
360074
|
360938
|
360940
|
361665
|
361668
|
361701
|
361707
|
362388
|
362940
|
363397
|
363398