summaryrefslogtreecommitdiffstats
path: root/ppapi/proxy/dispatcher.h
blob: 356dbcf446a16980675c8f006e2d529e57d0d5c6 (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
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
// Copyright (c) 2010 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_DISPATCHER_H_
#define PPAPI_PROXY_DISPATCHER_H_

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

#include "base/linked_ptr.h"
#include "base/scoped_ptr.h"
#include "ipc/ipc_channel.h"
#include "ipc/ipc_channel_handle.h"
#include "ipc/ipc_message.h"
#include "ppapi/c/pp_module.h"
#include "ppapi/proxy/callback_tracker.h"
#include "ppapi/proxy/interface_id.h"
#include "ppapi/proxy/plugin_resource_tracker.h"
#include "ppapi/proxy/plugin_var_tracker.h"

class MessageLoop;
struct PPB_Var_Deprecated;

namespace base {
class WaitableEvent;
}

namespace IPC {
class SyncChannel;
}

namespace pp {
namespace proxy {

class InterfaceProxy;
class VarSerializationRules;

// An interface proxy can represent either end of a cross-process interface
// call. The "source" side is where the call is invoked, and the "target" side
// is where the call ends up being executed.
//
// Plugin side                          | Browser side
// -------------------------------------|--------------------------------------
//                                      |
//    "Source"                          |    "Target"
//    InterfaceProxy ----------------------> InterfaceProxy
//                                      |
//                                      |
//    "Target"                          |    "Source"
//    InterfaceProxy <---------------------- InterfaceProxy
//                                      |
class Dispatcher : public IPC::Channel::Listener,
                   public IPC::Message::Sender {
 public:
  typedef const void* (*GetInterfaceFunc)(const char*);
  typedef int32_t (*InitModuleFunc)(PP_Module, GetInterfaceFunc);
  typedef void (*ShutdownModuleFunc)();

  ~Dispatcher();

  bool InitWithChannel(MessageLoop* ipc_message_loop,
                       const std::string& channel_name,
                       bool is_client,
                       base::WaitableEvent* shutdown_event);

  // Returns true if the dispatcher is on the plugin side, or false if it's the
  // browser side.
  virtual bool IsPlugin() const = 0;

  VarSerializationRules* serialization_rules() const {
    return serialization_rules_.get();
  }
  PP_Module pp_module() const {
    return pp_module_;
  }

  // Wrapper for calling the local GetInterface function.
  const void* GetLocalInterface(const char* interface);

  // Implements PPP_GetInterface and PPB_GetInterface on the "source" side. It
  // will check if the remote side supports this interface as a target, and
  // create a proxy if it does. A local implementation of that interface backed
  // by the proxy will be returned on success. If the interface is unproxyable
  // or not supported by the remote side, returns NULL.
  const void* GetProxiedInterface(const std::string& interface);

  // Called if the remote side is declaring to us which interfaces it supports
  // so we don't have to query for each one. We'll pre-create proxies for
  // each of the given interfaces.

  // IPC::Message::Sender implementation.
  virtual bool Send(IPC::Message* msg);

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

  IPC::SyncChannel* channel() const {
    return channel_.get();
  }

  CallbackTracker& callback_tracker() {
    return callback_tracker_;
  }

 protected:
  Dispatcher(GetInterfaceFunc local_get_interface);

  // Setter for the derived classes to set the appropriate var serialization.
  // Takes ownership of the given pointer, which must be on the heap.
  void SetSerializationRules(VarSerializationRules* var_serialization_rules);

  void set_pp_module(PP_Module module) {
    pp_module_ = module;
  }

  // Allows the PluginDispatcher to add a magic proxy for PPP_Class, bypassing
  // the normal "do you support this proxy" stuff and the big lookup of
  // name to proxy object. Takes ownership of the pointer.
  void InjectProxy(InterfaceID id,
                   const std::string& name,
                   InterfaceProxy* proxy);

 private:
  typedef std::map< std::string, linked_ptr<InterfaceProxy> > ProxyMap;

  // Message handlers
  void OnMsgSupportsInterface(const std::string& interface_name, bool* result);
  void OnMsgDeclareInterfaces(const std::vector<std::string>& interfaces);

  // Allocates a new proxy on the heap corresponding to the given interface
  // name, or returns NULL if that interface name isn't known proxyable. The
  // caller owns the returned pointer.
  //
  // The interface_functions gives the pointer to the local interfece when this
  // is a target proxy. When creating a source proxy, set this to NULL.
  InterfaceProxy* CreateProxyForInterface(
      const std::string& interface_name,
      const void* interface_functions);

  // Returns true if the remote side supports the given interface as the
  // target of an IPC call.
  bool RemoteSupportsTargetInterface(const std::string& interface);

  // Sets up a proxy as the target for the given interface, if it is supported.
  // Returns true if this process implements the given interface and it is
  // proxyable.
  bool SetupProxyForTargetInterface(const std::string& interface);

  bool IsInterfaceTrusted(const std::string& interface);

  // Set by the derived classed to indicate the module ID corresponding to
  // this dispatcher.
  PP_Module pp_module_;

  scoped_ptr<IPC::SyncChannel> channel_;

  bool disallow_trusted_interfaces_;

  GetInterfaceFunc local_get_interface_;

  ProxyMap proxies_;
  InterfaceProxy* id_to_proxy_[INTERFACE_ID_COUNT];

  // True if the remote side has declared which interfaces it supports in
  // advance. When set, it means if we don't already have a source proxy for
  // the requested interface, that the remote side doesn't support it and
  // we don't need to query.
  //
  // This is just an optimization. The browser has a fixed set of interfaces
  // it supports, and the many plugins will end up querying many of them. By
  // having the browser just send all of those interfaces in one message, we
  // can avoid a bunch of IPC chatter to set up each interface.
  bool declared_supported_remote_interfaces_;

  CallbackTracker callback_tracker_;

  scoped_ptr<VarSerializationRules> serialization_rules_;

  DISALLOW_COPY_AND_ASSIGN(Dispatcher);
};

}  // namespace proxy
}  // namespace pp

#endif  // PPAPI_PROXY_DISPATCHER_H_