Home | History | Annotate | Download | only in proxy
      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 PPAPI_PROXY_PROXY_CHANNEL_H_
      6 #define PPAPI_PROXY_PROXY_CHANNEL_H_
      7 
      8 #include "base/memory/scoped_ptr.h"
      9 #include "base/process/process.h"
     10 #include "ipc/ipc_listener.h"
     11 #include "ipc/ipc_platform_file.h"
     12 #include "ipc/ipc_sender.h"
     13 #include "ipc/ipc_sync_channel.h"
     14 #include "ppapi/proxy/ppapi_proxy_export.h"
     15 
     16 namespace base {
     17 class MessageLoopProxy;
     18 class WaitableEvent;
     19 }
     20 
     21 namespace IPC {
     22 class TestSink;
     23 }
     24 
     25 namespace ppapi {
     26 namespace proxy {
     27 
     28 class PPAPI_PROXY_EXPORT ProxyChannel
     29     : public IPC::Listener,
     30       public IPC::Sender {
     31  public:
     32   class PPAPI_PROXY_EXPORT Delegate {
     33    public:
     34     virtual ~Delegate() {}
     35 
     36     // Returns the dedicated message loop for processing IPC requests.
     37     virtual base::MessageLoopProxy* GetIPCMessageLoop() = 0;
     38 
     39     // Returns the event object that becomes signalled when the main thread's
     40     // message loop exits.
     41     virtual base::WaitableEvent* GetShutdownEvent() = 0;
     42 
     43     // Duplicates a handle to the provided object, returning one that is valid
     44     // on the other side of the channel. This is part of the delegate interface
     45     // because both sides of the channel may not have sufficient permission to
     46     // duplicate handles directly. The implementation must provide the same
     47     // guarantees as ProxyChannel::ShareHandleWithRemote below.
     48     virtual IPC::PlatformFileForTransit ShareHandleWithRemote(
     49         base::PlatformFile handle,
     50         base::ProcessId remote_pid,
     51         bool should_close_source) = 0;
     52   };
     53 
     54   virtual ~ProxyChannel();
     55 
     56   // Alternative to InitWithChannel() for unit tests that want to send all
     57   // messages sent via this channel to the given test sink. The test sink
     58   // must outlive this class. In this case, the peer PID will be the current
     59   // process ID.
     60   void InitWithTestSink(IPC::TestSink* test_sink);
     61 
     62   // Shares a file handle (HANDLE / file descriptor) with the remote side. It
     63   // returns a handle that should be sent in exactly one IPC message. Upon
     64   // receipt, the remote side then owns that handle. Note: if sending the
     65   // message fails, the returned handle is properly closed by the IPC system. If
     66   // should_close_source is set to true, the original handle is closed by this
     67   // operation and should not be used again.
     68   IPC::PlatformFileForTransit ShareHandleWithRemote(
     69       base::PlatformFile handle,
     70       bool should_close_source);
     71 
     72   // IPC::Sender implementation.
     73   virtual bool Send(IPC::Message* msg) OVERRIDE;
     74 
     75   // IPC::Listener implementation.
     76   virtual void OnChannelError() OVERRIDE;
     77 
     78   // Will be NULL in some unit tests and if the remote side has crashed.
     79   IPC::SyncChannel* channel() const {
     80     return channel_.get();
     81   }
     82 
     83 #if defined(OS_POSIX) && !defined(OS_NACL)
     84   int TakeRendererFD();
     85 #endif
     86 
     87  protected:
     88   explicit ProxyChannel();
     89 
     90   // You must call this function before anything else. Returns true on success.
     91   // The delegate pointer must outlive this class, ownership is not
     92   // transferred.
     93   virtual bool InitWithChannel(Delegate* delegate,
     94                                base::ProcessId peer_pid,
     95                                const IPC::ChannelHandle& channel_handle,
     96                                bool is_client);
     97 
     98   ProxyChannel::Delegate* delegate() const {
     99     return delegate_;
    100   }
    101 
    102  private:
    103   // Non-owning pointer. Guaranteed non-NULL after init is called.
    104   ProxyChannel::Delegate* delegate_;
    105 
    106   // PID of the remote process. Use this instead of the Channel::peer_pid since
    107   // this is set synchronously on construction rather than waiting on the
    108   // "hello" message from the peer (which introduces a race condition).
    109   base::ProcessId peer_pid_;
    110 
    111   // When we're unit testing, this will indicate the sink for the messages to
    112   // be deposited so they can be inspected by the test. When non-NULL, this
    113   // indicates that the channel should not be used.
    114   IPC::TestSink* test_sink_;
    115 
    116   // Will be null for some tests when there is a test_sink_, and if the
    117   // remote side has crashed.
    118   scoped_ptr<IPC::SyncChannel> channel_;
    119 
    120   DISALLOW_COPY_AND_ASSIGN(ProxyChannel);
    121 };
    122 
    123 }  // namespace proxy
    124 }  // namespace ppapi
    125 
    126 #endif  // PPAPI_PROXY_PROXY_CHANNEL_H_
    127