blob: 2aec49cc09aaad8a9e03bbd141ff63267e5467e0 [file] [log] [blame]
[email protected]c2932f5e2010-11-03 03:22:331// Copyright (c) 2010 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_DISPATCHER_H_
6#define PPAPI_PROXY_DISPATCHER_H_
7
8#include <map>
9#include <string>
10#include <vector>
11
12#include "base/linked_ptr.h"
[email protected]5d84d012010-12-02 17:17:2113#include "base/process.h"
[email protected]c2932f5e2010-11-03 03:22:3314#include "base/scoped_ptr.h"
15#include "ipc/ipc_channel.h"
16#include "ipc/ipc_channel_handle.h"
17#include "ipc/ipc_message.h"
18#include "ppapi/c/pp_module.h"
19#include "ppapi/proxy/callback_tracker.h"
20#include "ppapi/proxy/interface_id.h"
21#include "ppapi/proxy/plugin_resource_tracker.h"
22#include "ppapi/proxy/plugin_var_tracker.h"
23
24class MessageLoop;
25struct PPB_Var_Deprecated;
26
27namespace base {
28class WaitableEvent;
29}
30
31namespace IPC {
32class SyncChannel;
33}
34
35namespace pp {
36namespace proxy {
37
38class InterfaceProxy;
39class VarSerializationRules;
40
41// An interface proxy can represent either end of a cross-process interface
42// call. The "source" side is where the call is invoked, and the "target" side
43// is where the call ends up being executed.
44//
45// Plugin side | Browser side
46// -------------------------------------|--------------------------------------
47// |
48// "Source" | "Target"
49// InterfaceProxy ----------------------> InterfaceProxy
50// |
51// |
52// "Target" | "Source"
53// InterfaceProxy <---------------------- InterfaceProxy
54// |
55class Dispatcher : public IPC::Channel::Listener,
56 public IPC::Message::Sender {
57 public:
58 typedef const void* (*GetInterfaceFunc)(const char*);
[email protected]9c7baaef2010-11-10 05:42:4659 typedef int32_t (*InitModuleFunc)(PP_Module, GetInterfaceFunc);
60 typedef void (*ShutdownModuleFunc)();
[email protected]c2932f5e2010-11-03 03:22:3361
62 ~Dispatcher();
63
64 bool InitWithChannel(MessageLoop* ipc_message_loop,
[email protected]42ce94e2010-12-08 19:28:0965 const IPC::ChannelHandle& channel_handle,
[email protected]c2932f5e2010-11-03 03:22:3366 bool is_client,
67 base::WaitableEvent* shutdown_event);
68
69 // Returns true if the dispatcher is on the plugin side, or false if it's the
70 // browser side.
71 virtual bool IsPlugin() const = 0;
72
73 VarSerializationRules* serialization_rules() const {
74 return serialization_rules_.get();
75 }
76 PP_Module pp_module() const {
77 return pp_module_;
78 }
79
80 // Wrapper for calling the local GetInterface function.
81 const void* GetLocalInterface(const char* interface);
82
83 // Implements PPP_GetInterface and PPB_GetInterface on the "source" side. It
84 // will check if the remote side supports this interface as a target, and
85 // create a proxy if it does. A local implementation of that interface backed
86 // by the proxy will be returned on success. If the interface is unproxyable
87 // or not supported by the remote side, returns NULL.
88 const void* GetProxiedInterface(const std::string& interface);
89
[email protected]5d84d012010-12-02 17:17:2190 // Returns the remote process' handle. For the host dispatcher, this will be
91 // the plugin process, and for the plugin dispatcher, this will be the
92 // renderer process. This is used for sharing memory and such and is
93 // guaranteed valid (unless the remote process has suddenly died).
94 base::ProcessHandle remote_process_handle() const {
95 return remote_process_handle_;
96 }
97
[email protected]c2932f5e2010-11-03 03:22:3398 // Called if the remote side is declaring to us which interfaces it supports
99 // so we don't have to query for each one. We'll pre-create proxies for
100 // each of the given interfaces.
101
102 // IPC::Message::Sender implementation.
103 virtual bool Send(IPC::Message* msg);
104
105 // IPC::Channel::Listener implementation.
[email protected]a95986a82010-12-24 06:19:28106 virtual bool OnMessageReceived(const IPC::Message& msg);
[email protected]c2932f5e2010-11-03 03:22:33107
108 IPC::SyncChannel* channel() const {
109 return channel_.get();
110 }
111
112 CallbackTracker& callback_tracker() {
113 return callback_tracker_;
114 }
115
116 protected:
[email protected]5d84d012010-12-02 17:17:21117 Dispatcher(base::ProcessHandle remote_process_handle,
118 GetInterfaceFunc local_get_interface);
[email protected]c2932f5e2010-11-03 03:22:33119
120 // Setter for the derived classes to set the appropriate var serialization.
121 // Takes ownership of the given pointer, which must be on the heap.
122 void SetSerializationRules(VarSerializationRules* var_serialization_rules);
123
124 void set_pp_module(PP_Module module) {
125 pp_module_ = module;
126 }
127
128 // Allows the PluginDispatcher to add a magic proxy for PPP_Class, bypassing
129 // the normal "do you support this proxy" stuff and the big lookup of
130 // name to proxy object. Takes ownership of the pointer.
131 void InjectProxy(InterfaceID id,
132 const std::string& name,
133 InterfaceProxy* proxy);
134
135 private:
136 typedef std::map< std::string, linked_ptr<InterfaceProxy> > ProxyMap;
137
138 // Message handlers
139 void OnMsgSupportsInterface(const std::string& interface_name, bool* result);
140 void OnMsgDeclareInterfaces(const std::vector<std::string>& interfaces);
141
142 // Allocates a new proxy on the heap corresponding to the given interface
143 // name, or returns NULL if that interface name isn't known proxyable. The
144 // caller owns the returned pointer.
145 //
146 // The interface_functions gives the pointer to the local interfece when this
147 // is a target proxy. When creating a source proxy, set this to NULL.
148 InterfaceProxy* CreateProxyForInterface(
149 const std::string& interface_name,
150 const void* interface_functions);
151
152 // Returns true if the remote side supports the given interface as the
153 // target of an IPC call.
154 bool RemoteSupportsTargetInterface(const std::string& interface);
155
156 // Sets up a proxy as the target for the given interface, if it is supported.
157 // Returns true if this process implements the given interface and it is
158 // proxyable.
159 bool SetupProxyForTargetInterface(const std::string& interface);
160
161 bool IsInterfaceTrusted(const std::string& interface);
162
163 // Set by the derived classed to indicate the module ID corresponding to
164 // this dispatcher.
165 PP_Module pp_module_;
166
[email protected]5d84d012010-12-02 17:17:21167 base::ProcessHandle remote_process_handle_; // See getter above.
[email protected]c2932f5e2010-11-03 03:22:33168 scoped_ptr<IPC::SyncChannel> channel_;
169
170 bool disallow_trusted_interfaces_;
171
172 GetInterfaceFunc local_get_interface_;
173
174 ProxyMap proxies_;
175 InterfaceProxy* id_to_proxy_[INTERFACE_ID_COUNT];
176
177 // True if the remote side has declared which interfaces it supports in
178 // advance. When set, it means if we don't already have a source proxy for
179 // the requested interface, that the remote side doesn't support it and
180 // we don't need to query.
181 //
182 // This is just an optimization. The browser has a fixed set of interfaces
183 // it supports, and the many plugins will end up querying many of them. By
184 // having the browser just send all of those interfaces in one message, we
185 // can avoid a bunch of IPC chatter to set up each interface.
186 bool declared_supported_remote_interfaces_;
187
188 CallbackTracker callback_tracker_;
189
190 scoped_ptr<VarSerializationRules> serialization_rules_;
191
192 DISALLOW_COPY_AND_ASSIGN(Dispatcher);
193};
194
195} // namespace proxy
196} // namespace pp
197
198#endif // PPAPI_PROXY_DISPATCHER_H_