1/*
2 * Copyright (C) 2013, 2015 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 "InspectorFrontendChannel.h"
31#include "RemoteControllableTarget.h"
32#include <wtf/Lock.h>
33#include <wtf/ThreadSafeRefCounted.h>
34
35#if PLATFORM(COCOA)
36#include <wtf/BlockPtr.h>
37#include <wtf/RetainPtr.h>
38
39OBJC_CLASS NSString;
40#endif
41
42namespace Inspector {
43
44class RemoteControllableTarget;
45
46#if PLATFORM(COCOA)
47typedef Vector<BlockPtr<void ()>> RemoteTargetQueue;
48#endif
49
50class RemoteConnectionToTarget final : public ThreadSafeRefCounted<RemoteConnectionToTarget>, public FrontendChannel {
51public:
52#if PLATFORM(COCOA)
53 RemoteConnectionToTarget(RemoteControllableTarget*, NSString* connectionIdentifier, NSString* destination);
54#else
55 RemoteConnectionToTarget(RemoteControllableTarget&);
56#endif
57 virtual ~RemoteConnectionToTarget();
58
59 // Main API.
60 bool setup(bool isAutomaticInspection = false, bool automaticallyPause = false);
61#if PLATFORM(COCOA)
62 void sendMessageToTarget(NSString *);
63#else
64 void sendMessageToTarget(const String&);
65#endif
66 void close();
67 void targetClosed();
68
69 Optional<TargetID> targetIdentifier() const;
70#if PLATFORM(COCOA)
71 NSString *connectionIdentifier() const;
72 NSString *destination() const;
73
74 Lock& queueMutex() { return m_queueMutex; }
75 const RemoteTargetQueue& queue() const { return m_queue; }
76 void clearQueue() { m_queue.clear(); }
77#endif
78
79 // FrontendChannel overrides.
80 ConnectionType connectionType() const override { return ConnectionType::Remote; }
81 void sendMessageToFrontend(const String&) override;
82
83private:
84#if PLATFORM(COCOA)
85 void dispatchAsyncOnTarget(void (^block)());
86
87 void setupRunLoop();
88 void teardownRunLoop();
89 void queueTaskOnPrivateRunLoop(void (^block)());
90#endif
91
92 // This connection from the RemoteInspector singleton to the InspectionTarget
93 // can be used on multiple threads. So any access to the target
94 // itself must take this mutex to ensure m_target is valid.
95 Lock m_targetMutex;
96
97#if PLATFORM(COCOA)
98 // If a target has a specific run loop it wants to evaluate on
99 // we setup our run loop sources on that specific run loop.
100 RetainPtr<CFRunLoopRef> m_runLoop;
101 RetainPtr<CFRunLoopSourceRef> m_runLoopSource;
102 RemoteTargetQueue m_queue;
103 Lock m_queueMutex;
104#endif
105
106 RemoteControllableTarget* m_target { nullptr };
107 bool m_connected { false };
108
109#if PLATFORM(COCOA)
110 RetainPtr<NSString> m_connectionIdentifier;
111 RetainPtr<NSString> m_destination;
112#endif
113};
114
115} // namespace Inspector
116
117#endif // ENABLE(REMOTE_INSPECTOR)
118