• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/message_filter.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::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:
~SyncMessageStatusReceiver()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.
pp_module()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.
set_allow_plugin_reentrancy()98   void set_allow_plugin_reentrancy() {
99     allow_plugin_reentrancy_ = true;
100   }
101 
102   // Returns the proxy interface for talking to the implementation.
ppb_proxy()103   const PPB_Proxy_Private* ppb_proxy() const { return ppb_proxy_; }
104 
105   void AddFilter(IPC::Listener* listener);
106 
107  protected:
108   // Overridden from Dispatcher.
109   virtual void OnInvalidMessageReceived();
110 
111  private:
112   void OnHostMsgLogWithSource(PP_Instance instance,
113                               int int_log_level,
114                               const std::string& source,
115                               const std::string& value);
116 
117   scoped_refptr<SyncMessageStatusReceiver> sync_status_;
118 
119   PP_Module pp_module_;
120 
121   // Maps interface name to whether that interface is supported. If an interface
122   // name is not in the map, that implies that we haven't queried for it yet.
123   typedef base::hash_map<std::string, bool> PluginSupportedMap;
124   PluginSupportedMap plugin_supported_;
125 
126   // Guaranteed non-NULL.
127   const PPB_Proxy_Private* ppb_proxy_;
128 
129   // Set to true when the plugin is in a state that it can be reentered by a
130   // sync message from the host. We allow reentrancy only when we're processing
131   // a sync message from the renderer that is a scripting command. When the
132   // plugin is in this state, it needs to accept reentrancy since scripting may
133   // ultimately call back into the plugin.
134   bool allow_plugin_reentrancy_;
135 
136   std::vector<IPC::Listener*> filters_;
137 
138   DISALLOW_COPY_AND_ASSIGN(HostDispatcher);
139 };
140 
141 // Create this object on the stack to prevent the module (and hence the
142 // dispatcher) from being deleted out from under you. This is necessary when
143 // calling some scripting functions that may delete the plugin.
144 //
145 // This class does nothing if used on the plugin side.
146 class ScopedModuleReference {
147  public:
148   explicit ScopedModuleReference(Dispatcher* dispatcher);
149   ~ScopedModuleReference();
150 
151  private:
152   HostDispatcher* dispatcher_;
153 
154   DISALLOW_COPY_AND_ASSIGN(ScopedModuleReference);
155 };
156 
157 }  // namespace proxy
158 }  // namespace ppapi
159 
160 #endif  // PPAPI_PROXY_HOST_DISPATCHER_H_
161