1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef REMOTING_HOST_DESKTOP_SESSION_PROXY_H_ 6 #define REMOTING_HOST_DESKTOP_SESSION_PROXY_H_ 7 8 #include <map> 9 10 #include "base/basictypes.h" 11 #include "base/memory/ref_counted.h" 12 #include "base/memory/scoped_ptr.h" 13 #include "base/memory/weak_ptr.h" 14 #include "base/process/process.h" 15 #include "base/sequenced_task_runner_helpers.h" 16 #include "ipc/ipc_listener.h" 17 #include "ipc/ipc_platform_file.h" 18 #include "remoting/host/audio_capturer.h" 19 #include "remoting/host/desktop_environment.h" 20 #include "remoting/host/screen_resolution.h" 21 #include "remoting/proto/event.pb.h" 22 #include "remoting/protocol/clipboard_stub.h" 23 #include "third_party/skia/include/core/SkRegion.h" 24 #include "third_party/webrtc/modules/desktop_capture/screen_capturer.h" 25 26 namespace base { 27 class SingleThreadTaskRunner; 28 } // namespace base 29 30 namespace IPC { 31 class ChannelProxy; 32 class Message; 33 } // namespace IPC 34 35 struct SerializedDesktopFrame; 36 37 namespace remoting { 38 39 class AudioPacket; 40 class ClientSession; 41 class ClientSessionControl; 42 class DesktopSessionConnector; 43 struct DesktopSessionProxyTraits; 44 class IpcAudioCapturer; 45 class IpcVideoFrameCapturer; 46 class ScreenControls; 47 48 // DesktopSessionProxy is created by an owning DesktopEnvironment to route 49 // requests from stubs to the DesktopSessionAgent instance through 50 // the IPC channel. DesktopSessionProxy is owned both by the DesktopEnvironment 51 // and the stubs, since stubs can out-live their DesktopEnvironment. 52 // 53 // DesktopSessionProxy objects are ref-counted but are always deleted on 54 // the |caller_tast_runner_| thread. This makes it possible to continue 55 // to receive IPC messages after the ref-count has dropped to zero, until 56 // the proxy is deleted. DesktopSessionProxy must therefore avoid creating new 57 // references to the itself while handling IPC messages and desktop 58 // attach/detach notifications. 59 // 60 // All public methods of DesktopSessionProxy are called on 61 // the |caller_task_runner_| thread unless it is specified otherwise. 62 class DesktopSessionProxy 63 : public base::RefCountedThreadSafe<DesktopSessionProxy, 64 DesktopSessionProxyTraits>, 65 public IPC::Listener { 66 public: 67 DesktopSessionProxy( 68 scoped_refptr<base::SingleThreadTaskRunner> audio_capture_task_runner, 69 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, 70 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, 71 scoped_refptr<base::SingleThreadTaskRunner> video_capture_task_runner, 72 base::WeakPtr<ClientSessionControl> client_session_control, 73 base::WeakPtr<DesktopSessionConnector> desktop_session_connector, 74 bool virtual_terminal); 75 76 // Mirrors DesktopEnvironment. 77 scoped_ptr<AudioCapturer> CreateAudioCapturer(); 78 scoped_ptr<InputInjector> CreateInputInjector(); 79 scoped_ptr<ScreenControls> CreateScreenControls(); 80 scoped_ptr<webrtc::ScreenCapturer> CreateVideoCapturer(); 81 std::string GetCapabilities() const; 82 void SetCapabilities(const std::string& capabilities); 83 84 // IPC::Listener implementation. 85 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; 86 virtual void OnChannelConnected(int32 peer_pid) OVERRIDE; 87 virtual void OnChannelError() OVERRIDE; 88 89 // Connects to the desktop session agent. 90 bool AttachToDesktop(base::ProcessHandle desktop_process, 91 IPC::PlatformFileForTransit desktop_pipe); 92 93 // Closes the connection to the desktop session agent and cleans up 94 // the associated resources. 95 void DetachFromDesktop(); 96 97 // Disconnects the client session that owns |this|. 98 void DisconnectSession(); 99 100 // Stores |audio_capturer| to be used to post captured audio packets. Called 101 // on the |audio_capture_task_runner_| thread. 102 void SetAudioCapturer(const base::WeakPtr<IpcAudioCapturer>& audio_capturer); 103 104 // APIs used to implement the webrtc::ScreenCapturer interface. These must be 105 // called on the |video_capture_task_runner_| thread. 106 void InvalidateRegion(const SkRegion& invalid_region); 107 void CaptureFrame(); 108 109 // Stores |video_capturer| to be used to post captured video frames. Called on 110 // the |video_capture_task_runner_| thread. 111 void SetVideoCapturer( 112 const base::WeakPtr<IpcVideoFrameCapturer> video_capturer); 113 114 // APIs used to implement the InputInjector interface. 115 void InjectClipboardEvent(const protocol::ClipboardEvent& event); 116 void InjectKeyEvent(const protocol::KeyEvent& event); 117 void InjectMouseEvent(const protocol::MouseEvent& event); 118 void StartInputInjector(scoped_ptr<protocol::ClipboardStub> client_clipboard); 119 120 // API used to implement the SessionController interface. 121 void SetScreenResolution(const ScreenResolution& resolution); 122 123 private: 124 friend class base::DeleteHelper<DesktopSessionProxy>; 125 friend struct DesktopSessionProxyTraits; 126 127 class IpcSharedBufferCore; 128 class IpcSharedBuffer; 129 typedef std::map<int, scoped_refptr<IpcSharedBufferCore> > SharedBuffers; 130 131 virtual ~DesktopSessionProxy(); 132 133 // Returns a shared buffer from the list of known buffers. 134 scoped_refptr<IpcSharedBufferCore> GetSharedBufferCore(int id); 135 136 // Handles AudioPacket notification from the desktop session agent. 137 void OnAudioPacket(const std::string& serialized_packet); 138 139 // Registers a new shared buffer created by the desktop process. 140 void OnCreateSharedBuffer(int id, 141 IPC::PlatformFileForTransit handle, 142 uint32 size); 143 144 // Drops a cached reference to the shared buffer. 145 void OnReleaseSharedBuffer(int id); 146 147 // Handles CaptureCompleted notification from the desktop session agent. 148 void OnCaptureCompleted(const SerializedDesktopFrame& serialized_frame); 149 150 // Handles CursorShapeChanged notification from the desktop session agent. 151 void OnCursorShapeChanged(const webrtc::MouseCursorShape& cursor_shape); 152 153 // Handles InjectClipboardEvent request from the desktop integration process. 154 void OnInjectClipboardEvent(const std::string& serialized_event); 155 156 // Posts OnCaptureCompleted() to |video_capturer_| on the video thread, 157 // passing |frame|. 158 void PostCaptureCompleted(scoped_ptr<webrtc::DesktopFrame> frame); 159 160 // Posts OnCursorShapeChanged() to |video_capturer_| on the video thread, 161 // passing |cursor_shape|. 162 void PostCursorShape(scoped_ptr<webrtc::MouseCursorShape> cursor_shape); 163 164 // Sends a message to the desktop session agent. The message is silently 165 // deleted if the channel is broken. 166 void SendToDesktop(IPC::Message* message); 167 168 // Task runners: 169 // - |audio_capturer_| is called back on |audio_capture_task_runner_|. 170 // - public methods of this class (with some exceptions) are called on 171 // |caller_task_runner_|. 172 // - background I/O is served on |io_task_runner_|. 173 // - |video_capturer_| is called back on |video_capture_task_runner_|. 174 scoped_refptr<base::SingleThreadTaskRunner> audio_capture_task_runner_; 175 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner_; 176 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_; 177 scoped_refptr<base::SingleThreadTaskRunner> video_capture_task_runner_; 178 179 // Points to the audio capturer receiving captured audio packets. 180 base::WeakPtr<IpcAudioCapturer> audio_capturer_; 181 182 // Points to the client stub passed to StartInputInjector(). 183 scoped_ptr<protocol::ClipboardStub> client_clipboard_; 184 185 // Used to disconnect the client session. 186 base::WeakPtr<ClientSessionControl> client_session_control_; 187 188 // Used to create a desktop session and receive notifications every time 189 // the desktop process is replaced. 190 base::WeakPtr<DesktopSessionConnector> desktop_session_connector_; 191 192 // Points to the video capturer receiving captured video frames. 193 base::WeakPtr<IpcVideoFrameCapturer> video_capturer_; 194 195 // IPC channel to the desktop session agent. 196 scoped_ptr<IPC::ChannelProxy> desktop_channel_; 197 198 // Handle of the desktop process. 199 base::ProcessHandle desktop_process_; 200 201 int pending_capture_frame_requests_; 202 203 // Shared memory buffers by Id. Each buffer is owned by the corresponding 204 // frame. 205 SharedBuffers shared_buffers_; 206 207 // Keeps the desired screen resolution so it can be passed to a newly attached 208 // desktop session agent. 209 ScreenResolution screen_resolution_; 210 211 // True if |this| has been connected to the desktop session. 212 bool is_desktop_session_connected_; 213 214 bool virtual_terminal_; 215 216 DISALLOW_COPY_AND_ASSIGN(DesktopSessionProxy); 217 }; 218 219 // Destroys |DesktopSessionProxy| instances on the caller's thread. 220 struct DesktopSessionProxyTraits { 221 static void Destruct(const DesktopSessionProxy* desktop_session_proxy); 222 }; 223 224 } // namespace remoting 225 226 #endif // REMOTING_HOST_DESKTOP_SESSION_PROXY_H_ 227