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_HOST_DISPATCHER_H_
      6 #define PPAPI_PROXY_HOST_DISPATCHER_H_
      7 
      8 #include <map>
      9 #include <string>
     10 #include <vector>
     11 
     12 #include "base/compiler_specific.h"
     13 #include "base/memory/ref_counted.h"
     14 #include "base/process/process.h"
     15 #include "ipc/ipc_channel_proxy.h"
     16 #include "ppapi/c/pp_instance.h"
     17 #include "ppapi/proxy/dispatcher.h"
     18 
     19 struct PPB_Proxy_Private;
     20 
     21 namespace ppapi {
     22 
     23 struct Preferences;
     24 
     25 namespace proxy {
     26 
     27 class PPAPI_PROXY_EXPORT HostDispatcher : public Dispatcher {
     28  public:
     29   // This interface receives notifications about sync messages being sent by
     30   // the dispatcher to the plugin process. It is used to detect a hung plugin.
     31   //
     32   // Note that there can be nested sync messages, so the begin/end status
     33   // actually represents a stack of blocking messages.
     34   class SyncMessageStatusReceiver : public IPC::ChannelProxy::MessageFilter {
     35    public:
     36     // Notification that a sync message is about to be sent out.
     37     virtual void BeginBlockOnSyncMessage() = 0;
     38 
     39     // Notification that a sync message reply was received and the dispatcher
     40     // is no longer blocked on a sync message.
     41     virtual void EndBlockOnSyncMessage() = 0;
     42 
     43    protected:
     44     virtual ~SyncMessageStatusReceiver() {}
     45   };
     46 
     47   // Constructor for the renderer side. This will take a reference to the
     48   // SyncMessageStatusReceiver.
     49   //
     50   // You must call InitHostWithChannel after the constructor.
     51   HostDispatcher(PP_Module module,
     52                  PP_GetInterface_Func local_get_interface,
     53                  SyncMessageStatusReceiver* sync_status,
     54                  const PpapiPermissions& permissions);
     55   ~HostDispatcher();
     56 
     57   // You must call this function before anything else. Returns true on success.
     58   // The delegate pointer must outlive this class, ownership is not
     59   // transferred.
     60   virtual bool InitHostWithChannel(Delegate* delegate,
     61                                    base::ProcessId peer_pid,
     62                                    const IPC::ChannelHandle& channel_handle,
     63                                    bool is_client,
     64                                    const Preferences& preferences);
     65 
     66   // The host side maintains a mapping from PP_Instance to Dispatcher so
     67   // that we can send the messages to the right channel.
     68   static HostDispatcher* GetForInstance(PP_Instance instance);
     69   static void SetForInstance(PP_Instance instance,
     70                              HostDispatcher* dispatcher);
     71   static void RemoveForInstance(PP_Instance instance);
     72 
     73   // Returns the host's notion of our PP_Module. This will be different than
     74   // the plugin's notion of its PP_Module because the plugin process may be
     75   // used by multiple renderer processes.
     76   //
     77   // Use this value instead of a value from the plugin whenever talking to the
     78   // host.
     79   PP_Module pp_module() const { return pp_module_; }
     80 
     81   // Dispatcher overrides.
     82   virtual bool IsPlugin() const;
     83   virtual bool Send(IPC::Message* msg);
     84 
     85   // IPC::Listener.
     86   virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE;
     87   virtual void OnChannelError() OVERRIDE;
     88 
     89   // Proxied version of calling GetInterface on the plugin. This will check
     90   // if the plugin supports the given interface (with caching) and returns the
     91   // pointer to the proxied interface if it is supported. Returns NULL if the
     92   // given interface isn't supported by the plugin or the proxy.
     93   const void* GetProxiedInterface(const std::string& iface_name);
     94 
     95   // See the value below. Call this when processing a scripting message from
     96   // the plugin that can be reentered. This is set to false at the beginning
     97   // of processing of each message from the plugin.
     98   void set_allow_plugin_reentrancy() {
     99     allow_plugin_reentrancy_ = true;
    100   }
    101 
    102   // Returns the proxy interface for talking to the implementation.
    103   const PPB_Proxy_Private* ppb_proxy() const { return ppb_proxy_; }
    104 
    105  protected:
    106   // Overridden from Dispatcher.
    107   virtual void OnInvalidMessageReceived();
    108 
    109  private:
    110   void OnHostMsgLogWithSource(PP_Instance instance,
    111                               int int_log_level,
    112                               const std::string& source,
    113                               const std::string& value);
    114 
    115   scoped_refptr<SyncMessageStatusReceiver> sync_status_;
    116 
    117   PP_Module pp_module_;
    118 
    119   // Maps interface name to whether that interface is supported. If an interface
    120   // name is not in the map, that implies that we haven't queried for it yet.
    121   typedef base::hash_map<std::string, bool> PluginSupportedMap;
    122   PluginSupportedMap plugin_supported_;
    123 
    124   // Guaranteed non-NULL.
    125   const PPB_Proxy_Private* ppb_proxy_;
    126 
    127   // Set to true when the plugin is in a state that it can be reentered by a
    128   // sync message from the host. We allow reentrancy only when we're processing
    129   // a sync message from the renderer that is a scripting command. When the
    130   // plugin is in this state, it needs to accept reentrancy since scripting may
    131   // ultimately call back into the plugin.
    132   bool allow_plugin_reentrancy_;
    133 
    134   DISALLOW_COPY_AND_ASSIGN(HostDispatcher);
    135 };
    136 
    137 // Create this object on the stack to prevent the module (and hence the
    138 // dispatcher) from being deleted out from under you. This is necessary when
    139 // calling some scripting functions that may delete the plugin.
    140 //
    141 // This class does nothing if used on the plugin side.
    142 class ScopedModuleReference {
    143  public:
    144   explicit ScopedModuleReference(Dispatcher* dispatcher);
    145   ~ScopedModuleReference();
    146 
    147  private:
    148   HostDispatcher* dispatcher_;
    149 
    150   DISALLOW_COPY_AND_ASSIGN(ScopedModuleReference);
    151 };
    152 
    153 }  // namespace proxy
    154 }  // namespace ppapi
    155 
    156 #endif  // PPAPI_PROXY_HOST_DISPATCHER_H_
    157