blob: 54aa2b5352c2601808ba6ebbbd6101e1fefb86a1 [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
avie029c4132015-12-23 06:45:228#include <stdint.h>
9
[email protected]e1f5c9b2012-10-04 00:07:4410#include <map>
11
[email protected]eccf80312012-07-14 15:43:4212#include "base/compiler_specific.h"
avie029c4132015-12-23 06:45:2213#include "base/macros.h"
[email protected]511c58e2013-12-12 12:25:3314#include "base/memory/ref_counted.h"
[email protected]58786932012-10-13 10:16:0815#include "ipc/ipc_message.h"
[email protected]eccf80312012-07-14 15:43:4216#include "ipc/ipc_sender.h"
[email protected]58786932012-10-13 10:16:0817#include "ppapi/c/pp_errors.h"
[email protected]93df81e2012-08-10 22:22:4618#include "ppapi/proxy/connection.h"
[email protected]e1f5c9b2012-10-04 00:07:4419#include "ppapi/proxy/plugin_resource_callback.h"
[email protected]58786932012-10-13 10:16:0820#include "ppapi/proxy/ppapi_message_utils.h"
[email protected]eccf80312012-07-14 15:43:4221#include "ppapi/proxy/ppapi_proxy_export.h"
[email protected]9164da32012-10-16 03:40:5722#include "ppapi/proxy/resource_message_params.h"
[email protected]511c58e2013-12-12 12:25:3323#include "ppapi/proxy/resource_reply_thread_registrar.h"
[email protected]eccf80312012-07-14 15:43:4224#include "ppapi/shared_impl/resource.h"
[email protected]511c58e2013-12-12 12:25:3325#include "ppapi/shared_impl/tracked_callback.h"
[email protected]eccf80312012-07-14 15:43:4226namespace ppapi {
27namespace proxy {
28
Daniel Bratelleb5dcde2018-10-25 08:39:5029// A "safe" way to run callbacks, doing nothing if they are not
30// pending (active).
31void SafeRunCallback(scoped_refptr<TrackedCallback>* callback, int32_t error);
32
[email protected]93df81e2012-08-10 22:22:4633class PPAPI_PROXY_EXPORT PluginResource : public Resource {
[email protected]eccf80312012-07-14 15:43:4234 public:
[email protected]4f01c762012-12-05 02:44:1835 enum Destination {
36 RENDERER = 0,
37 BROWSER = 1
38 };
39
[email protected]93df81e2012-08-10 22:22:4640 PluginResource(Connection connection, PP_Instance instance);
nicke4784432015-04-23 14:01:4841 ~PluginResource() override;
[email protected]eccf80312012-07-14 15:43:4242
[email protected]93df81e2012-08-10 22:22:4643 // Returns true if we've previously sent a create message to the browser
44 // or renderer. Generally resources will use these to tell if they should
45 // lazily send create messages.
46 bool sent_create_to_browser() const { return sent_create_to_browser_; }
[email protected]eccf80312012-07-14 15:43:4247 bool sent_create_to_renderer() const { return sent_create_to_renderer_; }
48
[email protected]e1f5c9b2012-10-04 00:07:4449 // This handles a reply to a resource call. It works by looking up the
50 // callback that was registered when CallBrowser/CallRenderer was called
51 // and calling it with |params| and |msg|.
nicke4784432015-04-23 14:01:4852 void OnReplyReceived(const proxy::ResourceMessageReplyParams& params,
53 const IPC::Message& msg) override;
[email protected]28df6a02012-11-08 07:29:4554
55 // Resource overrides.
56 // Note: Subclasses shouldn't override these methods directly. Instead, they
57 // should implement LastPluginRefWasDeleted() or InstanceWasDeleted() to get
58 // notified.
nicke4784432015-04-23 14:01:4859 void NotifyLastPluginRefWasDeleted() override;
60 void NotifyInstanceWasDeleted() override;
[email protected]58786932012-10-13 10:16:0861
[email protected]93df81e2012-08-10 22:22:4662 // Sends a create message to the browser or renderer for the current resource.
[email protected]9164da32012-10-16 03:40:5763 void SendCreate(Destination dest, const IPC::Message& msg);
[email protected]eccf80312012-07-14 15:43:4264
[email protected]db70c132012-12-05 00:41:2065 // When the host returnes a resource to the plugin, it will create a pending
66 // ResourceHost and send an ID back to the plugin that identifies the pending
67 // object. The plugin uses this function to connect the plugin resource with
68 // the pending host resource. See also PpapiHostMsg_AttachToPendingHost. This
69 // is in lieu of sending a create message.
70 void AttachToPendingHost(Destination dest, int pending_host_id);
71
[email protected]eccf80312012-07-14 15:43:4272 // Sends the given IPC message as a resource request to the host
73 // corresponding to this resource object and does not expect a reply.
[email protected]9164da32012-10-16 03:40:5774 void Post(Destination dest, const IPC::Message& msg);
[email protected]eccf80312012-07-14 15:43:4275
[email protected]9164da32012-10-16 03:40:5776 // Like Post() but expects a response. |callback| is a |base::Callback| that
77 // will be run when a reply message with a sequence number matching that of
78 // the call is received. |ReplyMsgClass| is the type of the reply message that
79 // is expected. An example of usage:
[email protected]e1f5c9b2012-10-04 00:07:4480 //
[email protected]9164da32012-10-16 03:40:5781 // Call<PpapiPluginMsg_MyResourceType_MyReplyMessage>(
82 // BROWSER,
[email protected]e1f5c9b2012-10-04 00:07:4483 // PpapiHostMsg_MyResourceType_MyRequestMessage(),
[email protected]28df6a02012-11-08 07:29:4584 // base::Bind(&MyPluginResource::ReplyHandler, base::Unretained(this)));
[email protected]e1f5c9b2012-10-04 00:07:4485 //
86 // If a reply message to this call is received whose type does not match
87 // |ReplyMsgClass| (for example, in the case of an error), the callback will
88 // still be invoked but with the default values of the message parameters.
[email protected]eccf80312012-07-14 15:43:4289 //
90 // Returns the new request's sequence number which can be used to identify
[email protected]d84e9992012-11-08 22:13:2891 // the callback. This value will never be 0, which you can use to identify
92 // an invalid callback.
[email protected]eccf80312012-07-14 15:43:4293 //
[email protected]d84e9992012-11-08 22:13:2894 // Note: 1) When all plugin references to this resource are gone or the
[email protected]28df6a02012-11-08 07:29:4595 // corresponding plugin instance is deleted, all pending callbacks
96 // are abandoned.
[email protected]d84e9992012-11-08 22:13:2897 // 2) It is *not* recommended to let |callback| hold any reference to
[email protected]28df6a02012-11-08 07:29:4598 // |this|, in which it will be stored. Otherwise, this object will
99 // live forever if we fail to clean up the callback. It is safe to
100 // use base::Unretained(this) or a weak pointer, because this object
101 // will outlive the callback.
[email protected]e1f5c9b2012-10-04 00:07:44102 template<typename ReplyMsgClass, typename CallbackType>
[email protected]9164da32012-10-16 03:40:57103 int32_t Call(Destination dest,
104 const IPC::Message& msg,
105 const CallbackType& callback);
[email protected]eccf80312012-07-14 15:43:42106
[email protected]511c58e2013-12-12 12:25:33107 // Comparing with the previous Call() method, this method takes
108 // |reply_thread_hint| as a hint to determine which thread to handle the reply
109 // message.
110 //
111 // If |reply_thread_hint| is non-blocking, the reply message will be handled
112 // on the target thread of the callback; otherwise, it will be handled on the
113 // main thread.
114 //
115 // If handling a reply message will cause a TrackedCallback to be run, it is
116 // recommended to use this version of Call(). It eliminates unnecessary
117 // thread switching and therefore has better performance.
118 template<typename ReplyMsgClass, typename CallbackType>
119 int32_t Call(Destination dest,
120 const IPC::Message& msg,
121 const CallbackType& callback,
122 scoped_refptr<TrackedCallback> reply_thread_hint);
123
[email protected]58786932012-10-13 10:16:08124 // Calls the browser/renderer with sync messages. Returns the pepper error
125 // code from the call.
126 // |ReplyMsgClass| is the type of the reply message that is expected. If it
127 // carries x parameters, then the method with x out parameters should be used.
128 // An example of usage:
129 //
130 // // Assuming the reply message carries a string and an integer.
131 // std::string param_1;
132 // int param_2 = 0;
133 // int32_t result = SyncCall<PpapiPluginMsg_MyResourceType_MyReplyMessage>(
134 // RENDERER, PpapiHostMsg_MyResourceType_MyRequestMessage(),
135 // &param_1, &param_2);
136 template <class ReplyMsgClass>
137 int32_t SyncCall(Destination dest, const IPC::Message& msg);
138 template <class ReplyMsgClass, class A>
139 int32_t SyncCall(Destination dest, const IPC::Message& msg, A* a);
140 template <class ReplyMsgClass, class A, class B>
141 int32_t SyncCall(Destination dest, const IPC::Message& msg, A* a, B* b);
142 template <class ReplyMsgClass, class A, class B, class C>
143 int32_t SyncCall(Destination dest, const IPC::Message& msg, A* a, B* b, C* c);
144 template <class ReplyMsgClass, class A, class B, class C, class D>
145 int32_t SyncCall(
146 Destination dest, const IPC::Message& msg, A* a, B* b, C* c, D* d);
147 template <class ReplyMsgClass, class A, class B, class C, class D, class E>
148 int32_t SyncCall(
149 Destination dest, const IPC::Message& msg, A* a, B* b, C* c, D* d, E* e);
[email protected]ff44fc12012-10-03 00:52:16150
[email protected]0c92b0d2012-12-08 00:46:23151 int32_t GenericSyncCall(Destination dest,
152 const IPC::Message& msg,
153 IPC::Message* reply_msg,
154 ResourceMessageReplyParams* reply_params);
155
[email protected]47cb253f2013-05-16 01:50:40156 const Connection& connection() { return connection_; }
157
[email protected]eccf80312012-07-14 15:43:42158 private:
[email protected]4f01c762012-12-05 02:44:18159 IPC::Sender* GetSender(Destination dest) {
Raymes Khoury982b7eb22017-07-26 09:40:24160 return dest == RENDERER ? connection_.GetRendererSender()
161 : connection_.browser_sender();
[email protected]4f01c762012-12-05 02:44:18162 }
163
[email protected]9164da32012-10-16 03:40:57164 // Helper function to send a |PpapiHostMsg_ResourceCall| to the given
165 // destination with |nested_msg| and |call_params|.
166 bool SendResourceCall(Destination dest,
[email protected]e1f5c9b2012-10-04 00:07:44167 const ResourceMessageCallParams& call_params,
168 const IPC::Message& nested_msg);
169
[email protected]d84e9992012-11-08 22:13:28170 int32_t GetNextSequence();
171
[email protected]93df81e2012-08-10 22:22:46172 Connection connection_;
[email protected]eccf80312012-07-14 15:43:42173
[email protected]d84e9992012-11-08 22:13:28174 // Use GetNextSequence to retrieve the next value.
[email protected]eccf80312012-07-14 15:43:42175 int32_t next_sequence_number_;
176
[email protected]93df81e2012-08-10 22:22:46177 bool sent_create_to_browser_;
[email protected]eccf80312012-07-14 15:43:42178 bool sent_create_to_renderer_;
179
[email protected]e1f5c9b2012-10-04 00:07:44180 typedef std::map<int32_t, scoped_refptr<PluginResourceCallbackBase> >
181 CallbackMap;
182 CallbackMap callbacks_;
183
[email protected]511c58e2013-12-12 12:25:33184 scoped_refptr<ResourceReplyThreadRegistrar> resource_reply_thread_registrar_;
185
[email protected]eccf80312012-07-14 15:43:42186 DISALLOW_COPY_AND_ASSIGN(PluginResource);
187};
188
[email protected]e1f5c9b2012-10-04 00:07:44189template<typename ReplyMsgClass, typename CallbackType>
[email protected]9164da32012-10-16 03:40:57190int32_t PluginResource::Call(Destination dest,
191 const IPC::Message& msg,
192 const CallbackType& callback) {
[email protected]511c58e2013-12-12 12:25:33193 return Call<ReplyMsgClass>(dest, msg, callback, NULL);
194}
195
196template<typename ReplyMsgClass, typename CallbackType>
197int32_t PluginResource::Call(
198 Destination dest,
199 const IPC::Message& msg,
200 const CallbackType& callback,
201 scoped_refptr<TrackedCallback> reply_thread_hint) {
[email protected]278f5eb92013-03-27 00:26:18202 TRACE_EVENT2("ppapi proxy", "PluginResource::Call",
203 "Class", IPC_MESSAGE_ID_CLASS(msg.type()),
204 "Line", IPC_MESSAGE_ID_LINE(msg.type()));
[email protected]9164da32012-10-16 03:40:57205 ResourceMessageCallParams params(pp_resource(), next_sequence_number_++);
[email protected]e1f5c9b2012-10-04 00:07:44206 // Stash the |callback| in |callbacks_| identified by the sequence number of
207 // the call.
208 scoped_refptr<PluginResourceCallbackBase> plugin_callback(
209 new PluginResourceCallback<ReplyMsgClass, CallbackType>(callback));
210 callbacks_.insert(std::make_pair(params.sequence(), plugin_callback));
211 params.set_has_callback();
[email protected]511c58e2013-12-12 12:25:33212
Daniel Cheng6d3ae972014-08-26 00:27:38213 if (resource_reply_thread_registrar_.get()) {
[email protected]511c58e2013-12-12 12:25:33214 resource_reply_thread_registrar_->Register(
215 pp_resource(), params.sequence(), reply_thread_hint);
216 }
[email protected]9164da32012-10-16 03:40:57217 SendResourceCall(dest, params, msg);
[email protected]e1f5c9b2012-10-04 00:07:44218 return params.sequence();
219}
220
[email protected]58786932012-10-13 10:16:08221template <class ReplyMsgClass>
222int32_t PluginResource::SyncCall(Destination dest, const IPC::Message& msg) {
223 IPC::Message reply;
[email protected]0c92b0d2012-12-08 00:46:23224 ResourceMessageReplyParams reply_params;
225 return GenericSyncCall(dest, msg, &reply, &reply_params);
[email protected]58786932012-10-13 10:16:08226}
227
228template <class ReplyMsgClass, class A>
229int32_t PluginResource::SyncCall(
230 Destination dest, const IPC::Message& msg, A* a) {
231 IPC::Message reply;
[email protected]0c92b0d2012-12-08 00:46:23232 ResourceMessageReplyParams reply_params;
233 int32_t result = GenericSyncCall(dest, msg, &reply, &reply_params);
[email protected]58786932012-10-13 10:16:08234
235 if (UnpackMessage<ReplyMsgClass>(reply, a))
236 return result;
237 return PP_ERROR_FAILED;
238}
239
240template <class ReplyMsgClass, class A, class B>
241int32_t PluginResource::SyncCall(
242 Destination dest, const IPC::Message& msg, A* a, B* b) {
243 IPC::Message reply;
[email protected]0c92b0d2012-12-08 00:46:23244 ResourceMessageReplyParams reply_params;
245 int32_t result = GenericSyncCall(dest, msg, &reply, &reply_params);
[email protected]58786932012-10-13 10:16:08246
247 if (UnpackMessage<ReplyMsgClass>(reply, a, b))
248 return result;
249 return PP_ERROR_FAILED;
250}
251
252template <class ReplyMsgClass, class A, class B, class C>
253int32_t PluginResource::SyncCall(
254 Destination dest, const IPC::Message& msg, A* a, B* b, C* c) {
255 IPC::Message reply;
[email protected]0c92b0d2012-12-08 00:46:23256 ResourceMessageReplyParams reply_params;
257 int32_t result = GenericSyncCall(dest, msg, &reply, &reply_params);
[email protected]58786932012-10-13 10:16:08258
259 if (UnpackMessage<ReplyMsgClass>(reply, a, b, c))
260 return result;
261 return PP_ERROR_FAILED;
262}
263
264template <class ReplyMsgClass, class A, class B, class C, class D>
265int32_t PluginResource::SyncCall(
266 Destination dest, const IPC::Message& msg, A* a, B* b, C* c, D* d) {
267 IPC::Message reply;
[email protected]0c92b0d2012-12-08 00:46:23268 ResourceMessageReplyParams reply_params;
269 int32_t result = GenericSyncCall(dest, msg, &reply, &reply_params);
[email protected]58786932012-10-13 10:16:08270
271 if (UnpackMessage<ReplyMsgClass>(reply, a, b, c, d))
272 return result;
273 return PP_ERROR_FAILED;
274}
275
276template <class ReplyMsgClass, class A, class B, class C, class D, class E>
277int32_t PluginResource::SyncCall(
278 Destination dest, const IPC::Message& msg, A* a, B* b, C* c, D* d, E* e) {
279 IPC::Message reply;
[email protected]0c92b0d2012-12-08 00:46:23280 ResourceMessageReplyParams reply_params;
281 int32_t result = GenericSyncCall(dest, msg, &reply, &reply_params);
[email protected]58786932012-10-13 10:16:08282
283 if (UnpackMessage<ReplyMsgClass>(reply, a, b, c, d, e))
284 return result;
285 return PP_ERROR_FAILED;
286}
287
[email protected]eccf80312012-07-14 15:43:42288} // namespace proxy
289} // namespace ppapi
290
291#endif // PPAPI_PROXY_PLUGIN_RESOURCE_H_