summaryrefslogtreecommitdiffstats
path: root/ppapi/proxy/host_dispatcher.h
blob: 608223dc28b6f2ce352dedaa0bbddd5f93d0b60a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef PPAPI_PROXY_HOST_DISPATCHER_H_
#define PPAPI_PROXY_HOST_DISPATCHER_H_

#include <map>
#include <string>
#include <vector>

#include "base/memory/scoped_ptr.h"
#include "base/process.h"
#include "ppapi/c/pp_instance.h"
#include "ppapi/proxy/dispatcher.h"
#include "ppapi/proxy/plugin_var_tracker.h"
#include "ppapi/shared_impl/function_group_base.h"

struct PPB_Proxy_Private;
struct PPB_Var_Deprecated;

namespace base {
class WaitableEvent;
}

namespace IPC {
class SyncChannel;
}

namespace pp {
namespace proxy {

class InterfaceProxy;
class VarSerialization;

class HostDispatcher : public Dispatcher {
 public:
  // Constructor for the renderer side.
  //
  // You must call InitHostWithChannel after the constructor.
  HostDispatcher(base::ProcessHandle host_process_handle,
                 PP_Module module,
                 GetInterfaceFunc local_get_interface);
  ~HostDispatcher();

  // You must call this function before anything else. Returns true on success.
  // The delegate pointer must outlive this class, ownership is not
  // transferred.
  virtual bool InitHostWithChannel(Delegate* delegate,
                                   const IPC::ChannelHandle& channel_handle,
                                   bool is_client);

  // The host side maintains a mapping from PP_Instance to Dispatcher so
  // that we can send the messages to the right channel.
  static HostDispatcher* GetForInstance(PP_Instance instance);
  static void SetForInstance(PP_Instance instance,
                             HostDispatcher* dispatcher);
  static void RemoveForInstance(PP_Instance instance);

  // Returns the host's notion of our PP_Module. This will be different than
  // the plugin's notion of its PP_Module because the plugin process may be
  // used by multiple renderer processes.
  //
  // Use this value instead of a value from the plugin whenever talking to the
  // host.
  PP_Module pp_module() const { return pp_module_; }

  // Dispatcher overrides.
  virtual bool IsPlugin() const;
  virtual bool Send(IPC::Message* msg);

  // IPC::Channel::Listener.
  virtual bool OnMessageReceived(const IPC::Message& msg);
  virtual void OnChannelError();

  // Proxied version of calling GetInterface on the plugin. This will check
  // if the plugin supports the given interface (with caching) and returns the
  // pointer to the proxied interface if it is supported. Returns NULL if the
  // given interface isn't supported by the plugin or the proxy.
  const void* GetProxiedInterface(const std::string& interface);

  // Returns the proxy object associated with the given interface ID, creating
  // it if necessary. This is used in cases where a proxy needs to access code
  // in the proxy for another interface. It's assumed that the interface always
  // exists, so this is only used for browser proxies.
  //
  // Will return NULL if an interface isn't supported.
  InterfaceProxy* GetOrCreatePPBInterfaceProxy(InterfaceID id);

  // See the value below. Call this when processing a scripting message from
  // the plugin that can be reentered.
  void set_allow_plugin_reentrancy() {
    allow_plugin_reentrancy_ = true;
  }

  // Returns the proxy interface for talking to the implementation.
  const PPB_Proxy_Private* ppb_proxy() const { return ppb_proxy_; }

 private:
  friend class HostDispatcherTest;

  // Makes an instance of the given PPB interface proxy, storing it in the
  // target_proxies_ array. An proxy for this interface must not exist yet.
  InterfaceProxy* CreatePPBInterfaceProxy(const InterfaceProxy::Info* info);

  PP_Module pp_module_;

  enum PluginInterfaceSupport {
    INTERFACE_UNQUERIED = 0,  // Must be 0 so memset(0) will clear the list.
    INTERFACE_SUPPORTED,
    INTERFACE_UNSUPPORTED
  };
  PluginInterfaceSupport plugin_interface_support_[INTERFACE_ID_COUNT];

  // All target proxies currently created. These are ones that receive
  // messages. They are created on demand when we receive messages.
  scoped_ptr<InterfaceProxy> target_proxies_[INTERFACE_ID_COUNT];

  // Function proxies created for "new-style" FunctionGroups.
  // TODO(brettw) this is in progress. It should be merged with the target
  // proxies so there is one list to consult.
  scoped_ptr< ::ppapi::FunctionGroupBase >
      function_proxies_[INTERFACE_ID_COUNT];

  // Guaranteed non-NULL.
  const PPB_Proxy_Private* ppb_proxy_;

  // Set to true when the plugin is in a state that it can be reentered by a
  // sync message from the host. We allow reentrancy only when we're processing
  // a sync message from the renderer that is a scripting command. When the
  // plugin is in this state, it needs to accept reentrancy since scripting may
  // ultimately call back into the plugin.
  bool allow_plugin_reentrancy_;

  DISALLOW_COPY_AND_ASSIGN(HostDispatcher);
};

// Create this object on the stack to prevent the module (and hence the
// dispatcher) from being deleted out from under you. This is necessary when
// calling some scripting functions that may delete the plugin.
//
// This may only be called in the host. The parameter is a plain Dispatcher
// since that's what most callers have.
class ScopedModuleReference {
 public:
  ScopedModuleReference(Dispatcher* dispatcher);
  ~ScopedModuleReference();

 private:
  HostDispatcher* dispatcher_;

  DISALLOW_COPY_AND_ASSIGN(ScopedModuleReference);
};

}  // namespace proxy
}  // namespace pp

#endif  // PPAPI_PROXY_HOST_DISPATCHER_H_