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/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