blob: 153527801a4c7b8832a506c75b2026c43ddf7e73 [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]58786932012-10-13 10:16:0812#include "ipc/ipc_message.h"
[email protected]eccf80312012-07-14 15:43:4213#include "ipc/ipc_sender.h"
[email protected]58786932012-10-13 10:16:0814#include "ppapi/c/pp_errors.h"
[email protected]93df81e2012-08-10 22:22:4615#include "ppapi/proxy/connection.h"
[email protected]e1f5c9b2012-10-04 00:07:4416#include "ppapi/proxy/plugin_resource_callback.h"
[email protected]58786932012-10-13 10:16:0817#include "ppapi/proxy/ppapi_message_utils.h"
[email protected]eccf80312012-07-14 15:43:4218#include "ppapi/proxy/ppapi_proxy_export.h"
[email protected]9164da32012-10-16 03:40:5719#include "ppapi/proxy/resource_message_params.h"
[email protected]eccf80312012-07-14 15:43:4220#include "ppapi/shared_impl/resource.h"
21
[email protected]eccf80312012-07-14 15:43:4222namespace ppapi {
23namespace proxy {
24
25class PluginDispatcher;
26
[email protected]93df81e2012-08-10 22:22:4627class PPAPI_PROXY_EXPORT PluginResource : public Resource {
[email protected]eccf80312012-07-14 15:43:4228 public:
[email protected]4f01c762012-12-05 02:44:1829 enum Destination {
30 RENDERER = 0,
31 BROWSER = 1
32 };
33
[email protected]93df81e2012-08-10 22:22:4634 PluginResource(Connection connection, PP_Instance instance);
[email protected]eccf80312012-07-14 15:43:4235 virtual ~PluginResource();
36
[email protected]93df81e2012-08-10 22:22:4637 // Returns true if we've previously sent a create message to the browser
38 // or renderer. Generally resources will use these to tell if they should
39 // lazily send create messages.
40 bool sent_create_to_browser() const { return sent_create_to_browser_; }
[email protected]eccf80312012-07-14 15:43:4241 bool sent_create_to_renderer() const { return sent_create_to_renderer_; }
42
[email protected]e1f5c9b2012-10-04 00:07:4443 // This handles a reply to a resource call. It works by looking up the
44 // callback that was registered when CallBrowser/CallRenderer was called
45 // and calling it with |params| and |msg|.
46 virtual void OnReplyReceived(const proxy::ResourceMessageReplyParams& params,
47 const IPC::Message& msg) OVERRIDE;
[email protected]28df6a02012-11-08 07:29:4548
49 // Resource overrides.
50 // Note: Subclasses shouldn't override these methods directly. Instead, they
51 // should implement LastPluginRefWasDeleted() or InstanceWasDeleted() to get
52 // notified.
53 virtual void NotifyLastPluginRefWasDeleted() OVERRIDE;
54 virtual void NotifyInstanceWasDeleted() OVERRIDE;
55
[email protected]58786932012-10-13 10:16:0856
[email protected]93df81e2012-08-10 22:22:4657 // Sends a create message to the browser or renderer for the current resource.
[email protected]9164da32012-10-16 03:40:5758 void SendCreate(Destination dest, const IPC::Message& msg);
[email protected]eccf80312012-07-14 15:43:4259
[email protected]db70c132012-12-05 00:41:2060 // When the host returnes a resource to the plugin, it will create a pending
61 // ResourceHost and send an ID back to the plugin that identifies the pending
62 // object. The plugin uses this function to connect the plugin resource with
63 // the pending host resource. See also PpapiHostMsg_AttachToPendingHost. This
64 // is in lieu of sending a create message.
65 void AttachToPendingHost(Destination dest, int pending_host_id);
66
[email protected]eccf80312012-07-14 15:43:4267 // Sends the given IPC message as a resource request to the host
68 // corresponding to this resource object and does not expect a reply.
[email protected]9164da32012-10-16 03:40:5769 void Post(Destination dest, const IPC::Message& msg);
[email protected]eccf80312012-07-14 15:43:4270
[email protected]9164da32012-10-16 03:40:5771 // Like Post() but expects a response. |callback| is a |base::Callback| that
72 // will be run when a reply message with a sequence number matching that of
73 // the call is received. |ReplyMsgClass| is the type of the reply message that
74 // is expected. An example of usage:
[email protected]e1f5c9b2012-10-04 00:07:4475 //
[email protected]9164da32012-10-16 03:40:5776 // Call<PpapiPluginMsg_MyResourceType_MyReplyMessage>(
77 // BROWSER,
[email protected]e1f5c9b2012-10-04 00:07:4478 // PpapiHostMsg_MyResourceType_MyRequestMessage(),
[email protected]28df6a02012-11-08 07:29:4579 // base::Bind(&MyPluginResource::ReplyHandler, base::Unretained(this)));
[email protected]e1f5c9b2012-10-04 00:07:4480 //
81 // If a reply message to this call is received whose type does not match
82 // |ReplyMsgClass| (for example, in the case of an error), the callback will
83 // still be invoked but with the default values of the message parameters.
[email protected]eccf80312012-07-14 15:43:4284 //
85 // Returns the new request's sequence number which can be used to identify
[email protected]d84e9992012-11-08 22:13:2886 // the callback. This value will never be 0, which you can use to identify
87 // an invalid callback.
[email protected]eccf80312012-07-14 15:43:4288 //
[email protected]d84e9992012-11-08 22:13:2889 // Note: 1) When all plugin references to this resource are gone or the
[email protected]28df6a02012-11-08 07:29:4590 // corresponding plugin instance is deleted, all pending callbacks
91 // are abandoned.
[email protected]d84e9992012-11-08 22:13:2892 // 2) It is *not* recommended to let |callback| hold any reference to
[email protected]28df6a02012-11-08 07:29:4593 // |this|, in which it will be stored. Otherwise, this object will
94 // live forever if we fail to clean up the callback. It is safe to
95 // use base::Unretained(this) or a weak pointer, because this object
96 // will outlive the callback.
[email protected]e1f5c9b2012-10-04 00:07:4497 template<typename ReplyMsgClass, typename CallbackType>
[email protected]9164da32012-10-16 03:40:5798 int32_t Call(Destination dest,
99 const IPC::Message& msg,
100 const CallbackType& callback);
[email protected]eccf80312012-07-14 15:43:42101
[email protected]58786932012-10-13 10:16:08102 // Calls the browser/renderer with sync messages. Returns the pepper error
103 // code from the call.
104 // |ReplyMsgClass| is the type of the reply message that is expected. If it
105 // carries x parameters, then the method with x out parameters should be used.
106 // An example of usage:
107 //
108 // // Assuming the reply message carries a string and an integer.
109 // std::string param_1;
110 // int param_2 = 0;
111 // int32_t result = SyncCall<PpapiPluginMsg_MyResourceType_MyReplyMessage>(
112 // RENDERER, PpapiHostMsg_MyResourceType_MyRequestMessage(),
113 // &param_1, &param_2);
114 template <class ReplyMsgClass>
115 int32_t SyncCall(Destination dest, const IPC::Message& msg);
116 template <class ReplyMsgClass, class A>
117 int32_t SyncCall(Destination dest, const IPC::Message& msg, A* a);
118 template <class ReplyMsgClass, class A, class B>
119 int32_t SyncCall(Destination dest, const IPC::Message& msg, A* a, B* b);
120 template <class ReplyMsgClass, class A, class B, class C>
121 int32_t SyncCall(Destination dest, const IPC::Message& msg, A* a, B* b, C* c);
122 template <class ReplyMsgClass, class A, class B, class C, class D>
123 int32_t SyncCall(
124 Destination dest, const IPC::Message& msg, A* a, B* b, C* c, D* d);
125 template <class ReplyMsgClass, class A, class B, class C, class D, class E>
126 int32_t SyncCall(
127 Destination dest, const IPC::Message& msg, A* a, B* b, C* c, D* d, E* e);
[email protected]ff44fc12012-10-03 00:52:16128
[email protected]0c92b0d2012-12-08 00:46:23129 int32_t GenericSyncCall(Destination dest,
130 const IPC::Message& msg,
131 IPC::Message* reply_msg,
132 ResourceMessageReplyParams* reply_params);
133
[email protected]eccf80312012-07-14 15:43:42134 private:
[email protected]4f01c762012-12-05 02:44:18135 IPC::Sender* GetSender(Destination dest) {
136 return dest == RENDERER ? connection_.renderer_sender :
137 connection_.browser_sender;
138 }
139
[email protected]9164da32012-10-16 03:40:57140 // Helper function to send a |PpapiHostMsg_ResourceCall| to the given
141 // destination with |nested_msg| and |call_params|.
142 bool SendResourceCall(Destination dest,
[email protected]e1f5c9b2012-10-04 00:07:44143 const ResourceMessageCallParams& call_params,
144 const IPC::Message& nested_msg);
145
[email protected]d84e9992012-11-08 22:13:28146 int32_t GetNextSequence();
147
[email protected]93df81e2012-08-10 22:22:46148 Connection connection_;
[email protected]eccf80312012-07-14 15:43:42149
[email protected]d84e9992012-11-08 22:13:28150 // Use GetNextSequence to retrieve the next value.
[email protected]eccf80312012-07-14 15:43:42151 int32_t next_sequence_number_;
152
[email protected]93df81e2012-08-10 22:22:46153 bool sent_create_to_browser_;
[email protected]eccf80312012-07-14 15:43:42154 bool sent_create_to_renderer_;
155
[email protected]e1f5c9b2012-10-04 00:07:44156 typedef std::map<int32_t, scoped_refptr<PluginResourceCallbackBase> >
157 CallbackMap;
158 CallbackMap callbacks_;
159
[email protected]eccf80312012-07-14 15:43:42160 DISALLOW_COPY_AND_ASSIGN(PluginResource);
161};
162
[email protected]e1f5c9b2012-10-04 00:07:44163template<typename ReplyMsgClass, typename CallbackType>
[email protected]9164da32012-10-16 03:40:57164int32_t PluginResource::Call(Destination dest,
165 const IPC::Message& msg,
166 const CallbackType& callback) {
[email protected]278f5eb92013-03-27 00:26:18167 TRACE_EVENT2("ppapi proxy", "PluginResource::Call",
168 "Class", IPC_MESSAGE_ID_CLASS(msg.type()),
169 "Line", IPC_MESSAGE_ID_LINE(msg.type()));
[email protected]9164da32012-10-16 03:40:57170 ResourceMessageCallParams params(pp_resource(), next_sequence_number_++);
[email protected]e1f5c9b2012-10-04 00:07:44171 // Stash the |callback| in |callbacks_| identified by the sequence number of
172 // the call.
173 scoped_refptr<PluginResourceCallbackBase> plugin_callback(
174 new PluginResourceCallback<ReplyMsgClass, CallbackType>(callback));
175 callbacks_.insert(std::make_pair(params.sequence(), plugin_callback));
176 params.set_has_callback();
[email protected]9164da32012-10-16 03:40:57177 SendResourceCall(dest, params, msg);
[email protected]e1f5c9b2012-10-04 00:07:44178 return params.sequence();
179}
180
[email protected]58786932012-10-13 10:16:08181template <class ReplyMsgClass>
182int32_t PluginResource::SyncCall(Destination dest, const IPC::Message& msg) {
183 IPC::Message reply;
[email protected]0c92b0d2012-12-08 00:46:23184 ResourceMessageReplyParams reply_params;
185 return GenericSyncCall(dest, msg, &reply, &reply_params);
[email protected]58786932012-10-13 10:16:08186}
187
188template <class ReplyMsgClass, class A>
189int32_t PluginResource::SyncCall(
190 Destination dest, const IPC::Message& msg, A* a) {
191 IPC::Message reply;
[email protected]0c92b0d2012-12-08 00:46:23192 ResourceMessageReplyParams reply_params;
193 int32_t result = GenericSyncCall(dest, msg, &reply, &reply_params);
[email protected]58786932012-10-13 10:16:08194
195 if (UnpackMessage<ReplyMsgClass>(reply, a))
196 return result;
197 return PP_ERROR_FAILED;
198}
199
200template <class ReplyMsgClass, class A, class B>
201int32_t PluginResource::SyncCall(
202 Destination dest, const IPC::Message& msg, A* a, B* b) {
203 IPC::Message reply;
[email protected]0c92b0d2012-12-08 00:46:23204 ResourceMessageReplyParams reply_params;
205 int32_t result = GenericSyncCall(dest, msg, &reply, &reply_params);
[email protected]58786932012-10-13 10:16:08206
207 if (UnpackMessage<ReplyMsgClass>(reply, a, b))
208 return result;
209 return PP_ERROR_FAILED;
210}
211
212template <class ReplyMsgClass, class A, class B, class C>
213int32_t PluginResource::SyncCall(
214 Destination dest, const IPC::Message& msg, A* a, B* b, C* c) {
215 IPC::Message reply;
[email protected]0c92b0d2012-12-08 00:46:23216 ResourceMessageReplyParams reply_params;
217 int32_t result = GenericSyncCall(dest, msg, &reply, &reply_params);
[email protected]58786932012-10-13 10:16:08218
219 if (UnpackMessage<ReplyMsgClass>(reply, a, b, c))
220 return result;
221 return PP_ERROR_FAILED;
222}
223
224template <class ReplyMsgClass, class A, class B, class C, class D>
225int32_t PluginResource::SyncCall(
226 Destination dest, const IPC::Message& msg, A* a, B* b, C* c, D* d) {
227 IPC::Message reply;
[email protected]0c92b0d2012-12-08 00:46:23228 ResourceMessageReplyParams reply_params;
229 int32_t result = GenericSyncCall(dest, msg, &reply, &reply_params);
[email protected]58786932012-10-13 10:16:08230
231 if (UnpackMessage<ReplyMsgClass>(reply, a, b, c, d))
232 return result;
233 return PP_ERROR_FAILED;
234}
235
236template <class ReplyMsgClass, class A, class B, class C, class D, class E>
237int32_t PluginResource::SyncCall(
238 Destination dest, const IPC::Message& msg, A* a, B* b, C* c, D* d, E* e) {
239 IPC::Message reply;
[email protected]0c92b0d2012-12-08 00:46:23240 ResourceMessageReplyParams reply_params;
241 int32_t result = GenericSyncCall(dest, msg, &reply, &reply_params);
[email protected]58786932012-10-13 10:16:08242
243 if (UnpackMessage<ReplyMsgClass>(reply, a, b, c, d, e))
244 return result;
245 return PP_ERROR_FAILED;
246}
247
[email protected]eccf80312012-07-14 15:43:42248} // namespace proxy
249} // namespace ppapi
250
251#endif // PPAPI_PROXY_PLUGIN_RESOURCE_H_