[WinCairo] Move remote communication handling from RemoteInspectorServer to RemoteIns...
[WebKit.git] / Source / JavaScriptCore / inspector / remote / RemoteInspector.h
1 /*
2  * Copyright (C) 2013, 2015, 2016 Apple Inc. All Rights Reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #pragma once
27
28 #if ENABLE(REMOTE_INSPECTOR)
29
30 #include "RemoteControllableTarget.h"
31
32 #include <utility>
33 #include <wtf/Forward.h>
34 #include <wtf/HashMap.h>
35 #include <wtf/Lock.h>
36 #include <wtf/ProcessID.h>
37 #include <wtf/text/WTFString.h>
38
39 #if PLATFORM(COCOA)
40 #include "RemoteInspectorXPCConnection.h"
41 #include <wtf/RetainPtr.h>
42
43 OBJC_CLASS NSDictionary;
44 OBJC_CLASS NSString;
45 typedef RetainPtr<NSDictionary> TargetListing;
46 #endif
47
48 #if USE(GLIB)
49 #include <wtf/glib/GRefPtr.h>
50 typedef GRefPtr<GVariant> TargetListing;
51 typedef struct _GCancellable GCancellable;
52 typedef struct _GDBusConnection GDBusConnection;
53 typedef struct _GDBusInterfaceVTable GDBusInterfaceVTable;
54 #endif
55
56 #if USE(INSPECTOR_SOCKET_SERVER)
57 #include "RemoteConnectionToTarget.h"
58 #include "RemoteInspectorConnectionClient.h"
59 #include <wtf/JSONValues.h>
60 #include <wtf/RefPtr.h>
61
62 namespace Inspector {
63 using TargetListing = RefPtr<JSON::Object>;
64 }
65 #endif
66
67 namespace Inspector {
68
69 class RemoteAutomationTarget;
70 class RemoteConnectionToTarget;
71 class RemoteControllableTarget;
72 class RemoteInspectionTarget;
73 class RemoteInspectorClient;
74
75 class JS_EXPORT_PRIVATE RemoteInspector final
76 #if PLATFORM(COCOA)
77     : public RemoteInspectorXPCConnection::Client
78 #elif USE(INSPECTOR_SOCKET_SERVER)
79     : public RemoteInspectorConnectionClient
80 #endif
81 {
82 public:
83     class Client {
84     public:
85         struct Capabilities {
86             bool remoteAutomationAllowed : 1;
87             String browserName;
88             String browserVersion;
89         };
90
91         struct SessionCapabilities {
92             bool acceptInsecureCertificates { false };
93 #if USE(GLIB)
94             Vector<std::pair<String, String>> certificates;
95 #endif
96 #if PLATFORM(COCOA)
97             Optional<bool> allowInsecureMediaCapture;
98             Optional<bool> suppressICECandidateFiltering;
99 #endif
100         };
101
102         virtual ~Client();
103         virtual bool remoteAutomationAllowed() const = 0;
104         virtual String browserName() const { return { }; }
105         virtual String browserVersion() const { return { }; }
106         virtual void requestAutomationSession(const String& sessionIdentifier, const SessionCapabilities&) = 0;
107     };
108
109     static void startDisabled();
110     static RemoteInspector& singleton();
111     friend class NeverDestroyed<RemoteInspector>;
112
113     void registerTarget(RemoteControllableTarget*);
114     void unregisterTarget(RemoteControllableTarget*);
115     void updateTarget(RemoteControllableTarget*);
116     void sendMessageToRemote(TargetID, const String& message);
117
118     RemoteInspector::Client* client() const { return m_client; }
119     void setClient(RemoteInspector::Client*);
120     void clientCapabilitiesDidChange();
121     Optional<RemoteInspector::Client::Capabilities> clientCapabilities() const { return m_clientCapabilities; }
122
123     void setupFailed(TargetID);
124     void setupCompleted(TargetID);
125     bool waitingForAutomaticInspection(TargetID);
126     void updateAutomaticInspectionCandidate(RemoteInspectionTarget*);
127
128     bool enabled() const { return m_enabled; }
129     bool hasActiveDebugSession() const { return m_hasActiveDebugSession; }
130
131     void start();
132     void stop();
133
134 #if PLATFORM(COCOA)
135     bool hasParentProcessInformation() const { return m_parentProcessIdentifier != 0; }
136     ProcessID parentProcessIdentifier() const { return m_parentProcessIdentifier; }
137     RetainPtr<CFDataRef> parentProcessAuditData() const { return m_parentProcessAuditData; }
138     void setParentProcessInformation(ProcessID, RetainPtr<CFDataRef> auditData);
139     void setParentProcessInfomationIsDelayed();
140 #endif
141
142     void updateTargetListing(TargetID);
143
144 #if USE(GLIB)
145     void requestAutomationSession(const char* sessionID, const Client::SessionCapabilities&);
146 #endif
147 #if USE(GLIB) || USE(INSPECTOR_SOCKET_SERVER)
148     void setup(TargetID);
149     void sendMessageToTarget(TargetID, const char* message);
150 #endif
151 #if USE(INSPECTOR_SOCKET_SERVER)
152     void requestAutomationSession(String&& sessionID, const Client::SessionCapabilities&);
153
154     bool isConnected() const { return !!m_clientConnection; }
155     void connect(ConnectionID);
156
157     void setBackendCommandsPath(const String& backendCommandsPath) { m_backendCommandsPath = backendCommandsPath; }
158 #endif
159
160 private:
161     RemoteInspector();
162
163     TargetID nextAvailableTargetIdentifier();
164
165     enum class StopSource { API, XPCMessage };
166     void stopInternal(StopSource);
167
168 #if PLATFORM(COCOA)
169     void setupXPCConnectionIfNeeded();
170 #endif
171 #if USE(GLIB)
172     void setupConnection(GRefPtr<GDBusConnection>&&);
173     static const GDBusInterfaceVTable s_interfaceVTable;
174
175     void receivedGetTargetListMessage();
176     void receivedSetupMessage(TargetID);
177     void receivedDataMessage(TargetID, const char* message);
178     void receivedCloseMessage(TargetID);
179     void receivedAutomationSessionRequestMessage(const char* sessionID);
180 #endif
181
182     TargetListing listingForTarget(const RemoteControllableTarget&) const;
183     TargetListing listingForInspectionTarget(const RemoteInspectionTarget&) const;
184     TargetListing listingForAutomationTarget(const RemoteAutomationTarget&) const;
185
186     bool updateTargetMap(RemoteControllableTarget*);
187
188     void pushListingsNow();
189     void pushListingsSoon();
190
191     void updateTargetListing(const RemoteControllableTarget&);
192
193     void updateHasActiveDebugSession();
194     void updateClientCapabilities();
195
196     void sendAutomaticInspectionCandidateMessage();
197
198 #if PLATFORM(COCOA)
199     void xpcConnectionReceivedMessage(RemoteInspectorXPCConnection*, NSString *messageName, NSDictionary *userInfo) override;
200     void xpcConnectionFailed(RemoteInspectorXPCConnection*) override;
201     void xpcConnectionUnhandledMessage(RemoteInspectorXPCConnection*, xpc_object_t) override;
202
203     void receivedSetupMessage(NSDictionary *userInfo);
204     void receivedDataMessage(NSDictionary *userInfo);
205     void receivedDidCloseMessage(NSDictionary *userInfo);
206     void receivedGetListingMessage(NSDictionary *userInfo);
207     void receivedIndicateMessage(NSDictionary *userInfo);
208     void receivedProxyApplicationSetupMessage(NSDictionary *userInfo);
209     void receivedConnectionDiedMessage(NSDictionary *userInfo);
210     void receivedAutomaticInspectionConfigurationMessage(NSDictionary *userInfo);
211     void receivedAutomaticInspectionRejectMessage(NSDictionary *userInfo);
212     void receivedAutomationSessionRequestMessage(NSDictionary *userInfo);
213 #endif
214 #if USE(INSPECTOR_SOCKET_SERVER)
215     HashMap<String, CallHandler>& dispatchMap() override;
216     void didClose(ConnectionID) override;
217
218     void sendWebInspectorEvent(const String&);
219
220     void setupInspectorClient(const Event&);
221     void setupTarget(const Event&);
222     void frontendDidClose(const Event&);
223     void sendMessageToBackend(const Event&);
224
225     String backendCommands() const;
226 #endif
227     static bool startEnabled;
228
229     // Targets can be registered from any thread at any time.
230     // Any target can send messages over the XPC connection.
231     // So lock access to all maps and state as they can change
232     // from any thread.
233     Lock m_mutex;
234
235     HashMap<TargetID, RemoteControllableTarget*> m_targetMap;
236     HashMap<TargetID, RefPtr<RemoteConnectionToTarget>> m_targetConnectionMap;
237     HashMap<TargetID, TargetListing> m_targetListingMap;
238
239 #if PLATFORM(COCOA)
240     RefPtr<RemoteInspectorXPCConnection> m_relayConnection;
241 #endif
242 #if USE(GLIB)
243     GRefPtr<GDBusConnection> m_dbusConnection;
244     GRefPtr<GCancellable> m_cancellable;
245 #endif
246
247 #if USE(INSPECTOR_SOCKET_SERVER)
248     // Connection from RemoteInspectorClient or WebDriver.
249     Optional<ConnectionID> m_clientConnection;
250     bool m_readyToPushListings { false };
251
252     String m_backendCommandsPath;
253 #endif
254
255     RemoteInspector::Client* m_client { nullptr };
256     Optional<RemoteInspector::Client::Capabilities> m_clientCapabilities;
257
258 #if PLATFORM(COCOA)
259     dispatch_queue_t m_xpcQueue;
260 #endif
261     TargetID m_nextAvailableTargetIdentifier { 1 };
262     int m_notifyToken { 0 };
263     bool m_enabled { false };
264     bool m_hasActiveDebugSession { false };
265     bool m_pushScheduled { false };
266
267     ProcessID m_parentProcessIdentifier { 0 };
268 #if PLATFORM(COCOA)
269     RetainPtr<CFDataRef> m_parentProcessAuditData;
270 #endif
271     bool m_shouldSendParentProcessInformation { false };
272     bool m_automaticInspectionEnabled { false };
273     bool m_automaticInspectionPaused { false };
274     TargetID m_automaticInspectionCandidateTargetIdentifier { 0 };
275 };
276
277 } // namespace Inspector
278
279 #endif // ENABLE(REMOTE_INSPECTOR)