Home | History | Annotate | Download | only in host
      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