blob: a9c68c9c363dd4ad99af40278b89606a6112ca3d [file] [log] [blame]
[email protected]eccf80312012-07-14 15:43:421// 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_PLUGIN_RESOURCE_H_
6#define PPAPI_PROXY_PLUGIN_RESOURCE_H_
7
[email protected]e1f5c9b2012-10-04 00:07:448#include <map>
9
[email protected]58786932012-10-13 10:16:0810#include "base/basictypes.h"
[email protected]eccf80312012-07-14 15:43:4211#include "base/compiler_specific.h"
[email protected]511c58e2013-12-12 12:25:3312#include "base/memory/ref_counted.h"
[email protected]58786932012-10-13 10:16:0813#include "ipc/ipc_message.h"
[email protected]eccf80312012-07-14 15:43:4214#include "ipc/ipc_sender.h"
[email protected]58786932012-10-13 10:16:0815#include "ppapi/c/pp_errors.h"
[email protected]93df81e2012-08-10 22:22:4616#include "ppapi/proxy/connection.h"
[email protected]e1f5c9b2012-10-04 00:07:4417#include "ppapi/proxy/plugin_resource_callback.h"
[email protected]58786932012-10-13 10:16:0818#include "ppapi/proxy/ppapi_message_utils.h"
[email protected]eccf80312012-07-14 15:43:4219#include "ppapi/proxy/ppapi_proxy_export.h"
[email protected]9164da32012-10-16 03:40:5720#include "ppapi/proxy/resource_message_params.h"
[email protected]511c58e2013-12-12 12:25:3321#include "ppapi/proxy/resource_reply_thread_registrar.h"
[email protected]eccf80312012-07-14 15:43:4222#include "ppapi/shared_impl/resource.h"
[email protected]511c58e2013-12-12 12:25:3323#include "ppapi/shared_impl/tracked_callback.h"
[email protected]eccf80312012-07-14 15:43:4224namespace ppapi {
25namespace proxy {
26
27class PluginDispatcher;
28
[email protected]93df81e2012-08-10 22:22:4629class PPAPI_PROXY_EXPORT PluginResource : public Resource {
[email protected]eccf80312012-07-14 15:43:4230 public:
[email protected]4f01c762012-12-05 02:44:1831 enum Destination {
32 RENDERER = 0,
33 BROWSER = 1
34 };
35
[email protected]93df81e2012-08-10 22:22:4636 PluginResource(Connection connection, PP_Instance instance);
[email protected]eccf80312012-07-14 15:43:4237 virtual ~PluginResource();
38
[email protected]93df81e2012-08-10 22:22:4639 // Returns true if we've previously sent a create message to the browser
40 // or renderer. Generally resources will use these to tell if they should
41 // lazily send create messages.
42 bool sent_create_to_browser() const { return sent_create_to_browser_; }
[email protected]eccf80312012-07-14 15:43:4243 bool sent_create_to_renderer() const { return sent_create_to_renderer_; }
44
[email protected]e1f5c9b2012-10-04 00:07:4445 // This handles a reply to a resource call. It works by looking up the
46 // callback that was registered when CallBrowser/CallRenderer was called
47 // and calling it with |params| and |msg|.
48 virtual void OnReplyReceived(const proxy::ResourceMessageReplyParams& params,
49 const IPC::Message& msg) OVERRIDE;
[email protected]28df6a02012-11-08 07:29:4550
51 // Resource overrides.
52 // Note: Subclasses shouldn't override these methods directly. Instead, they
53 // should implement LastPluginRefWasDeleted() or InstanceWasDeleted() to get
54 // notified.
55 virtual void NotifyLastPluginRefWasDeleted() OVERRIDE;
56 virtual void NotifyInstanceWasDeleted() OVERRIDE;
57
[email protected]58786932012-10-13 10:16:0858
[email protected]93df81e2012-08-10 22:22:4659 // Sends a create message to the browser or renderer for the current resource.
[email protected]9164da32012-10-16 03:40:5760 void SendCreate(Destination dest, const IPC::Message& msg);
[email protected]eccf80312012-07-14 15:43:4261
[email protected]db70c132012-12-05 00:41:2062 // When the host returnes a resource to the plugin, it will create a pending
63 // ResourceHost and send an ID back to the plugin that identifies the pending
64 // object. The plugin uses this function to connect the plugin resource with
65 // the pending host resource. See also PpapiHostMsg_AttachToPendingHost. This
66 // is in lieu of sending a create message.
67 void AttachToPendingHost(Destination dest, int pending_host_id);
68
[email protected]eccf80312012-07-14 15:43:4269 // Sends the given IPC message as a resource request to the host
70 // corresponding to this resource object and does not expect a reply.
[email protected]9164da32012-10-16 03:40:5771 void Post(Destination dest, const IPC::Message& msg);
[email protected]eccf80312012-07-14 15:43:4272
[email protected]9164da32012-10-16 03:40:5773 // Like Post() but expects a response. |callback| is a |base::Callback| that
74 // will be run when a reply message with a sequence number matching that of
75 // the call is received. |ReplyMsgClass| is the type of the reply message that
76 // is expected. An example of usage:
[email protected]e1f5c9b2012-10-04 00:07:4477 //
[email protected]9164da32012-10-16 03:40:5778 // Call<PpapiPluginMsg_MyResourceType_MyReplyMessage>(
79 // BROWSER,
[email protected]e1f5c9b2012-10-04 00:07:4480 // PpapiHostMsg_MyResourceType_MyRequestMessage(),
[email protected]28df6a02012-11-08 07:29:4581 // base::Bind(&MyPluginResource::ReplyHandler, base::Unretained(this)));
[email protected]e1f5c9b2012-10-04 00:07:4482 //
83 // If a reply message to this call is received whose type does not match
84 // |ReplyMsgClass| (for example, in the case of an error), the callback will
85 // still be invoked but with the default values of the message parameters.
[email protected]eccf80312012-07-14 15:43:4286 //
87 // Returns the new request's sequence number which can be used to identify
[email protected]d84e9992012-11-08 22:13:2888 // the callback. This value will never be 0, which you can use to identify
89 // an invalid callback.
[email protected]eccf80312012-07-14 15:43:4290 //
[email protected]d84e9992012-11-08 22:13:2891 // Note: 1) When all plugin references to this resource are gone or the
[email protected]28df6a02012-11-08 07:29:4592 // corresponding plugin instance is deleted, all pending callbacks
93 // are abandoned.
[email protected]d84e9992012-11-08 22:13:2894 // 2) It is *not* recommended to let |callback| hold any reference to
[email protected]28df6a02012-11-08 07:29:4595 // |this|, in which it will be stored. Otherwise, this object will
96 // live forever if we fail to clean up the callback. It is safe to
97 // use base::Unretained(this) or a weak pointer, because this object
98 // will outlive the callback.
[email protected]e1f5c9b2012-10-04 00:07:4499 template<typename ReplyMsgClass, typename CallbackType>
[email protected]9164da32012-10-16 03:40:57100 int32_t Call(Destination dest,
101 const IPC::Message& msg,
102 const CallbackType& callback);
[email protected]eccf80312012-07-14 15:43:42103
[email protected]511c58e2013-12-12 12:25:33104 // Comparing with the previous Call() method, this method takes
105 // |reply_thread_hint| as a hint to determine which thread to handle the reply
106 // message.
107 //
108 // If |reply_thread_hint| is non-blocking, the reply message will be handled
109 // on the target thread of the callback; otherwise, it will be handled on the
110 // main thread.
111 //
112 // If handling a reply message will cause a TrackedCallback to be run, it is
113 // recommended to use this version of Call(). It eliminates unnecessary
114 // thread switching and therefore has better performance.
115 template<typename ReplyMsgClass, typename CallbackType>
116 int32_t Call(Destination dest,
117 const IPC::Message& msg,
118 const CallbackType& callback,
119 scoped_refptr<TrackedCallback> reply_thread_hint);
120
[email protected]58786932012-10-13 10:16:08121 // Calls the browser/renderer with sync messages. Returns the pepper error
122 // code from the call.
123 // |ReplyMsgClass| is the type of the reply message that is expected. If it
124 // carries x parameters, then the method with x out parameters should be used.
125 // An example of usage:
126 //
127 // // Assuming the reply message carries a string and an integer.
128 // std::string param_1;
129 // int param_2 = 0;
130 // int32_t result = SyncCall<PpapiPluginMsg_MyResourceType_MyReplyMessage>(
131 // RENDERER, PpapiHostMsg_MyResourceType_MyRequestMessage(),
132 // &param_1, &param_2);
133 template <class ReplyMsgClass>
134 int32_t SyncCall(Destination dest, const IPC::Message& msg);
135 template <class ReplyMsgClass, class A>
136 int32_t SyncCall(Destination dest, const IPC::Message& msg, A* a);
137 template <class ReplyMsgClass, class A, class B>
138 int32_t SyncCall(Destination dest, const IPC::Message& msg, A* a, B* b);
139 template <class ReplyMsgClass, class A, class B, class C>
140 int32_t SyncCall(Destination dest, const IPC::Message& msg, A* a, B* b, C* c);
141 template <class ReplyMsgClass, class A, class B, class C, class D>
142 int32_t SyncCall(
143 Destination dest, const IPC::Message& msg, A* a, B* b, C* c, D* d);
144 template <class ReplyMsgClass, class A, class B, class C, class D, class E>
145 int32_t SyncCall(
146 Destination dest, const IPC::Message& msg, A* a, B* b, C* c, D* d, E* e);
[email protected]ff44fc12012-10-03 00:52:16147
[email protected]0c92b0d2012-12-08 00:46:23148 int32_t GenericSyncCall(Destination dest,
149 const IPC::Message& msg,
150 IPC::Message* reply_msg,
151 ResourceMessageReplyParams* reply_params);
152
[email protected]47cb253f2013-05-16 01:50:40153 const Connection& connection() { return connection_; }
154
[email protected]eccf80312012-07-14 15:43:42155 private:
[email protected]4f01c762012-12-05 02:44:18156 IPC::Sender* GetSender(Destination dest) {
157 return dest == RENDERER ? connection_.renderer_sender :
158 connection_.browser_sender;
159 }
160
[email protected]9164da32012-10-16 03:40:57161 // Helper function to send a |PpapiHostMsg_ResourceCall| to the given
162 // destination with |nested_msg| and |call_params|.
163 bool SendResourceCall(Destination dest,
[email protected]e1f5c9b2012-10-04 00:07:44164 const ResourceMessageCallParams& call_params,
165 const IPC::Message& nested_msg);
166
[email protected]d84e9992012-11-08 22:13:28167 int32_t GetNextSequence();
168
[email protected]93df81e2012-08-10 22:22:46169 Connection connection_;
[email protected]eccf80312012-07-14 15:43:42170
[email protected]d84e9992012-11-08 22:13:28171 // Use GetNextSequence to retrieve the next value.
[email protected]eccf80312012-07-14 15:43:42172 int32_t next_sequence_number_;
173
[email protected]93df81e2012-08-10 22:22:46174 bool sent_create_to_browser_;
[email protected]eccf80312012-07-14 15:43:42175 bool sent_create_to_renderer_;
176
[email protected]e1f5c9b2012-10-04 00:07:44177 typedef std::map<int32_t, scoped_refptr<PluginResourceCallbackBase> >
178 CallbackMap;
179 CallbackMap callbacks_;
180
[email protected]511c58e2013-12-12 12:25:33181 scoped_refptr<ResourceReplyThreadRegistrar> resource_reply_thread_registrar_;
182
[email protected]eccf80312012-07-14 15:43:42183 DISALLOW_COPY_AND_ASSIGN(PluginResource);
184};
185
[email protected]e1f5c9b2012-10-04 00:07:44186template<typename ReplyMsgClass, typename CallbackType>
[email protected]9164da32012-10-16 03:40:57187int32_t PluginResource::Call(Destination dest,
188 const IPC::Message& msg,
189 const CallbackType& callback) {
[email protected]511c58e2013-12-12 12:25:33190 return Call<ReplyMsgClass>(dest, msg, callback, NULL);
191}
192
193template<typename ReplyMsgClass, typename CallbackType>
194int32_t PluginResource::Call(
195 Destination dest,
196 const IPC::Message& msg,
197 const CallbackType& callback,
198 scoped_refptr<TrackedCallback> reply_thread_hint) {
[email protected]278f5eb92013-03-27 00:26:18199 TRACE_EVENT2("ppapi proxy", "PluginResource::Call",
200 "Class", IPC_MESSAGE_ID_CLASS(msg.type()),
201 "Line", IPC_MESSAGE_ID_LINE(msg.type()));
[email protected]9164da32012-10-16 03:40:57202 ResourceMessageCallParams params(pp_resource(), next_sequence_number_++);
[email protected]e1f5c9b2012-10-04 00:07:44203 // Stash the |callback| in |callbacks_| identified by the sequence number of
204 // the call.
205 scoped_refptr<PluginResourceCallbackBase> plugin_callback(
206 new PluginResourceCallback<ReplyMsgClass, CallbackType>(callback));
207 callbacks_.insert(std::make_pair(params.sequence(), plugin_callback));
208 params.set_has_callback();
[email protected]511c58e2013-12-12 12:25:33209
Daniel Cheng6d3ae972014-08-26 00:27:38210 if (resource_reply_thread_registrar_.get()) {
[email protected]511c58e2013-12-12 12:25:33211 resource_reply_thread_registrar_->Register(
212 pp_resource(), params.sequence(), reply_thread_hint);
213 }
[email protected]9164da32012-10-16 03:40:57214 SendResourceCall(dest, params, msg);
[email protected]e1f5c9b2012-10-04 00:07:44215 return params.sequence();
216}
217
[email protected]58786932012-10-13 10:16:08218template <class ReplyMsgClass>
219int32_t PluginResource::SyncCall(Destination dest, const IPC::Message& msg) {
220 IPC::Message reply;
[email protected]0c92b0d2012-12-08 00:46:23221 ResourceMessageReplyParams reply_params;
222 return GenericSyncCall(dest, msg, &reply, &reply_params);
[email protected]58786932012-10-13 10:16:08223}
224
225template <class ReplyMsgClass, class A>
226int32_t PluginResource::SyncCall(
227 Destination dest, const IPC::Message& msg, A* a) {
228 IPC::Message reply;
[email protected]0c92b0d2012-12-08 00:46:23229 ResourceMessageReplyParams reply_params;
230 int32_t result = GenericSyncCall(dest, msg, &reply, &reply_params);
[email protected]58786932012-10-13 10:16:08231
232 if (UnpackMessage<ReplyMsgClass>(reply, a))
233 return result;
234 return PP_ERROR_FAILED;
235}
236
237template <class ReplyMsgClass, class A, class B>
238int32_t PluginResource::SyncCall(
239 Destination dest, const IPC::Message& msg, A* a, B* b) {
240 IPC::Message reply;
[email protected]0c92b0d2012-12-08 00:46:23241 ResourceMessageReplyParams reply_params;
242 int32_t result = GenericSyncCall(dest, msg, &reply, &reply_params);
[email protected]58786932012-10-13 10:16:08243
244 if (UnpackMessage<ReplyMsgClass>(reply, a, b))
245 return result;
246 return PP_ERROR_FAILED;
247}
248
249template <class ReplyMsgClass, class A, class B, class C>
250int32_t PluginResource::SyncCall(
251 Destination dest, const IPC::Message& msg, A* a, B* b, C* c) {
252 IPC::Message reply;
[email protected]0c92b0d2012-12-08 00:46:23253 ResourceMessageReplyParams reply_params;
254 int32_t result = GenericSyncCall(dest, msg, &reply, &reply_params);
[email protected]58786932012-10-13 10:16:08255
256 if (UnpackMessage<ReplyMsgClass>(reply, a, b, c))
257 return result;
258 return PP_ERROR_FAILED;
259}
260
261template <class ReplyMsgClass, class A, class B, class C, class D>
262int32_t PluginResource::SyncCall(
263 Destination dest, const IPC::Message& msg, A* a, B* b, C* c, D* d) {
264 IPC::Message reply;
[email protected]0c92b0d2012-12-08 00:46:23265 ResourceMessageReplyParams reply_params;
266 int32_t result = GenericSyncCall(dest, msg, &reply, &reply_params);
[email protected]58786932012-10-13 10:16:08267
268 if (UnpackMessage<ReplyMsgClass>(reply, a, b, c, d))
269 return result;
270 return PP_ERROR_FAILED;
271}
272
273template <class ReplyMsgClass, class A, class B, class C, class D, class E>
274int32_t PluginResource::SyncCall(
275 Destination dest, const IPC::Message& msg, A* a, B* b, C* c, D* d, E* e) {
276 IPC::Message reply;
[email protected]0c92b0d2012-12-08 00:46:23277 ResourceMessageReplyParams reply_params;
278 int32_t result = GenericSyncCall(dest, msg, &reply, &reply_params);
[email protected]58786932012-10-13 10:16:08279
280 if (UnpackMessage<ReplyMsgClass>(reply, a, b, c, d, e))
281 return result;
282 return PP_ERROR_FAILED;
283}
284
[email protected]eccf80312012-07-14 15:43:42285} // namespace proxy
286} // namespace ppapi
287
288#endif // PPAPI_PROXY_PLUGIN_RESOURCE_H_