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