Elim cr-checkbox
[chromium-blink-merge.git] / ppapi / proxy / plugin_resource.h
blob0f2124035bcc5e8644246b476d7362c8df8ead4f
1 // 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.
5 #ifndef PPAPI_PROXY_PLUGIN_RESOURCE_H_
6 #define PPAPI_PROXY_PLUGIN_RESOURCE_H_
8 #include <map>
10 #include "base/basictypes.h"
11 #include "base/compiler_specific.h"
12 #include "base/memory/ref_counted.h"
13 #include "ipc/ipc_message.h"
14 #include "ipc/ipc_sender.h"
15 #include "ppapi/c/pp_errors.h"
16 #include "ppapi/proxy/connection.h"
17 #include "ppapi/proxy/plugin_resource_callback.h"
18 #include "ppapi/proxy/ppapi_message_utils.h"
19 #include "ppapi/proxy/ppapi_proxy_export.h"
20 #include "ppapi/proxy/resource_message_params.h"
21 #include "ppapi/proxy/resource_reply_thread_registrar.h"
22 #include "ppapi/shared_impl/resource.h"
23 #include "ppapi/shared_impl/tracked_callback.h"
24 namespace ppapi {
25 namespace proxy {
27 class PluginDispatcher;
29 class PPAPI_PROXY_EXPORT PluginResource : public Resource {
30 public:
31 enum Destination {
32 RENDERER = 0,
33 BROWSER = 1
36 PluginResource(Connection connection, PP_Instance instance);
37 ~PluginResource() override;
39 // 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_; }
43 bool sent_create_to_renderer() const { return sent_create_to_renderer_; }
45 // 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 void OnReplyReceived(const proxy::ResourceMessageReplyParams& params,
49 const IPC::Message& msg) override;
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 void NotifyLastPluginRefWasDeleted() override;
56 void NotifyInstanceWasDeleted() override;
58 // Sends a create message to the browser or renderer for the current resource.
59 void SendCreate(Destination dest, const IPC::Message& msg);
61 // When the host returnes a resource to the plugin, it will create a pending
62 // ResourceHost and send an ID back to the plugin that identifies the pending
63 // object. The plugin uses this function to connect the plugin resource with
64 // the pending host resource. See also PpapiHostMsg_AttachToPendingHost. This
65 // is in lieu of sending a create message.
66 void AttachToPendingHost(Destination dest, int pending_host_id);
68 // Sends the given IPC message as a resource request to the host
69 // corresponding to this resource object and does not expect a reply.
70 void Post(Destination dest, const IPC::Message& msg);
72 // Like Post() but expects a response. |callback| is a |base::Callback| that
73 // will be run when a reply message with a sequence number matching that of
74 // the call is received. |ReplyMsgClass| is the type of the reply message that
75 // is expected. An example of usage:
77 // Call<PpapiPluginMsg_MyResourceType_MyReplyMessage>(
78 // BROWSER,
79 // PpapiHostMsg_MyResourceType_MyRequestMessage(),
80 // base::Bind(&MyPluginResource::ReplyHandler, base::Unretained(this)));
82 // If a reply message to this call is received whose type does not match
83 // |ReplyMsgClass| (for example, in the case of an error), the callback will
84 // still be invoked but with the default values of the message parameters.
86 // Returns the new request's sequence number which can be used to identify
87 // the callback. This value will never be 0, which you can use to identify
88 // an invalid callback.
90 // Note: 1) When all plugin references to this resource are gone or the
91 // corresponding plugin instance is deleted, all pending callbacks
92 // are abandoned.
93 // 2) It is *not* recommended to let |callback| hold any reference to
94 // |this|, in which it will be stored. Otherwise, this object will
95 // live forever if we fail to clean up the callback. It is safe to
96 // use base::Unretained(this) or a weak pointer, because this object
97 // will outlive the callback.
98 template<typename ReplyMsgClass, typename CallbackType>
99 int32_t Call(Destination dest,
100 const IPC::Message& msg,
101 const CallbackType& callback);
103 // Comparing with the previous Call() method, this method takes
104 // |reply_thread_hint| as a hint to determine which thread to handle the reply
105 // message.
107 // If |reply_thread_hint| is non-blocking, the reply message will be handled
108 // on the target thread of the callback; otherwise, it will be handled on the
109 // main thread.
111 // If handling a reply message will cause a TrackedCallback to be run, it is
112 // recommended to use this version of Call(). It eliminates unnecessary
113 // thread switching and therefore has better performance.
114 template<typename ReplyMsgClass, typename CallbackType>
115 int32_t Call(Destination dest,
116 const IPC::Message& msg,
117 const CallbackType& callback,
118 scoped_refptr<TrackedCallback> reply_thread_hint);
120 // Calls the browser/renderer with sync messages. Returns the pepper error
121 // code from the call.
122 // |ReplyMsgClass| is the type of the reply message that is expected. If it
123 // carries x parameters, then the method with x out parameters should be used.
124 // An example of usage:
126 // // Assuming the reply message carries a string and an integer.
127 // std::string param_1;
128 // int param_2 = 0;
129 // int32_t result = SyncCall<PpapiPluginMsg_MyResourceType_MyReplyMessage>(
130 // RENDERER, PpapiHostMsg_MyResourceType_MyRequestMessage(),
131 // &param_1, &param_2);
132 template <class ReplyMsgClass>
133 int32_t SyncCall(Destination dest, const IPC::Message& msg);
134 template <class ReplyMsgClass, class A>
135 int32_t SyncCall(Destination dest, const IPC::Message& msg, A* a);
136 template <class ReplyMsgClass, class A, class B>
137 int32_t SyncCall(Destination dest, const IPC::Message& msg, A* a, B* b);
138 template <class ReplyMsgClass, class A, class B, class C>
139 int32_t SyncCall(Destination dest, const IPC::Message& msg, A* a, B* b, C* c);
140 template <class ReplyMsgClass, class A, class B, class C, class D>
141 int32_t SyncCall(
142 Destination dest, const IPC::Message& msg, A* a, B* b, C* c, D* d);
143 template <class ReplyMsgClass, class A, class B, class C, class D, class E>
144 int32_t SyncCall(
145 Destination dest, const IPC::Message& msg, A* a, B* b, C* c, D* d, E* e);
147 int32_t GenericSyncCall(Destination dest,
148 const IPC::Message& msg,
149 IPC::Message* reply_msg,
150 ResourceMessageReplyParams* reply_params);
152 const Connection& connection() { return connection_; }
154 private:
155 IPC::Sender* GetSender(Destination dest) {
156 return dest == RENDERER ? connection_.renderer_sender :
157 connection_.browser_sender;
160 // Helper function to send a |PpapiHostMsg_ResourceCall| to the given
161 // destination with |nested_msg| and |call_params|.
162 bool SendResourceCall(Destination dest,
163 const ResourceMessageCallParams& call_params,
164 const IPC::Message& nested_msg);
166 int32_t GetNextSequence();
168 Connection connection_;
170 // Use GetNextSequence to retrieve the next value.
171 int32_t next_sequence_number_;
173 bool sent_create_to_browser_;
174 bool sent_create_to_renderer_;
176 typedef std::map<int32_t, scoped_refptr<PluginResourceCallbackBase> >
177 CallbackMap;
178 CallbackMap callbacks_;
180 scoped_refptr<ResourceReplyThreadRegistrar> resource_reply_thread_registrar_;
182 DISALLOW_COPY_AND_ASSIGN(PluginResource);
185 template<typename ReplyMsgClass, typename CallbackType>
186 int32_t PluginResource::Call(Destination dest,
187 const IPC::Message& msg,
188 const CallbackType& callback) {
189 return Call<ReplyMsgClass>(dest, msg, callback, NULL);
192 template<typename ReplyMsgClass, typename CallbackType>
193 int32_t PluginResource::Call(
194 Destination dest,
195 const IPC::Message& msg,
196 const CallbackType& callback,
197 scoped_refptr<TrackedCallback> reply_thread_hint) {
198 TRACE_EVENT2("ppapi proxy", "PluginResource::Call",
199 "Class", IPC_MESSAGE_ID_CLASS(msg.type()),
200 "Line", IPC_MESSAGE_ID_LINE(msg.type()));
201 ResourceMessageCallParams params(pp_resource(), next_sequence_number_++);
202 // Stash the |callback| in |callbacks_| identified by the sequence number of
203 // the call.
204 scoped_refptr<PluginResourceCallbackBase> plugin_callback(
205 new PluginResourceCallback<ReplyMsgClass, CallbackType>(callback));
206 callbacks_.insert(std::make_pair(params.sequence(), plugin_callback));
207 params.set_has_callback();
209 if (resource_reply_thread_registrar_.get()) {
210 resource_reply_thread_registrar_->Register(
211 pp_resource(), params.sequence(), reply_thread_hint);
213 SendResourceCall(dest, params, msg);
214 return params.sequence();
217 template <class ReplyMsgClass>
218 int32_t PluginResource::SyncCall(Destination dest, const IPC::Message& msg) {
219 IPC::Message reply;
220 ResourceMessageReplyParams reply_params;
221 return GenericSyncCall(dest, msg, &reply, &reply_params);
224 template <class ReplyMsgClass, class A>
225 int32_t PluginResource::SyncCall(
226 Destination dest, const IPC::Message& msg, A* a) {
227 IPC::Message reply;
228 ResourceMessageReplyParams reply_params;
229 int32_t result = GenericSyncCall(dest, msg, &reply, &reply_params);
231 if (UnpackMessage<ReplyMsgClass>(reply, a))
232 return result;
233 return PP_ERROR_FAILED;
236 template <class ReplyMsgClass, class A, class B>
237 int32_t PluginResource::SyncCall(
238 Destination dest, const IPC::Message& msg, A* a, B* b) {
239 IPC::Message reply;
240 ResourceMessageReplyParams reply_params;
241 int32_t result = GenericSyncCall(dest, msg, &reply, &reply_params);
243 if (UnpackMessage<ReplyMsgClass>(reply, a, b))
244 return result;
245 return PP_ERROR_FAILED;
248 template <class ReplyMsgClass, class A, class B, class C>
249 int32_t PluginResource::SyncCall(
250 Destination dest, const IPC::Message& msg, A* a, B* b, C* c) {
251 IPC::Message reply;
252 ResourceMessageReplyParams reply_params;
253 int32_t result = GenericSyncCall(dest, msg, &reply, &reply_params);
255 if (UnpackMessage<ReplyMsgClass>(reply, a, b, c))
256 return result;
257 return PP_ERROR_FAILED;
260 template <class ReplyMsgClass, class A, class B, class C, class D>
261 int32_t PluginResource::SyncCall(
262 Destination dest, const IPC::Message& msg, A* a, B* b, C* c, D* d) {
263 IPC::Message reply;
264 ResourceMessageReplyParams reply_params;
265 int32_t result = GenericSyncCall(dest, msg, &reply, &reply_params);
267 if (UnpackMessage<ReplyMsgClass>(reply, a, b, c, d))
268 return result;
269 return PP_ERROR_FAILED;
272 template <class ReplyMsgClass, class A, class B, class C, class D, class E>
273 int32_t PluginResource::SyncCall(
274 Destination dest, const IPC::Message& msg, A* a, B* b, C* c, D* d, E* e) {
275 IPC::Message reply;
276 ResourceMessageReplyParams reply_params;
277 int32_t result = GenericSyncCall(dest, msg, &reply, &reply_params);
279 if (UnpackMessage<ReplyMsgClass>(reply, a, b, c, d, e))
280 return result;
281 return PP_ERROR_FAILED;
284 } // namespace proxy
285 } // namespace ppapi
287 #endif // PPAPI_PROXY_PLUGIN_RESOURCE_H_