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