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_
10 #include "base/basictypes.h"
11 #include "base/compiler_specific.h"
12 #include "ipc/ipc_message.h"
13 #include "ipc/ipc_sender.h"
14 #include "ppapi/c/pp_errors.h"
15 #include "ppapi/proxy/connection.h"
16 #include "ppapi/proxy/plugin_resource_callback.h"
17 #include "ppapi/proxy/ppapi_message_utils.h"
18 #include "ppapi/proxy/ppapi_proxy_export.h"
19 #include "ppapi/proxy/resource_message_params.h"
20 #include "ppapi/shared_impl/resource.h"
25 class PluginDispatcher
;
27 class PPAPI_PROXY_EXPORT PluginResource
: public Resource
{
34 PluginResource(Connection connection
, PP_Instance instance
);
35 virtual ~PluginResource();
37 // 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_
; }
41 bool sent_create_to_renderer() const { return sent_create_to_renderer_
; }
43 // 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
;
49 // Resource overrides.
50 // Note: Subclasses shouldn't override these methods directly. Instead, they
51 // should implement LastPluginRefWasDeleted() or InstanceWasDeleted() to get
53 virtual void NotifyLastPluginRefWasDeleted() OVERRIDE
;
54 virtual void NotifyInstanceWasDeleted() OVERRIDE
;
57 // Sends a create message to the browser or renderer for the current resource.
58 void SendCreate(Destination dest
, const IPC::Message
& msg
);
60 // 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
);
67 // Sends the given IPC message as a resource request to the host
68 // corresponding to this resource object and does not expect a reply.
69 void Post(Destination dest
, const IPC::Message
& msg
);
71 // 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:
76 // Call<PpapiPluginMsg_MyResourceType_MyReplyMessage>(
78 // PpapiHostMsg_MyResourceType_MyRequestMessage(),
79 // base::Bind(&MyPluginResource::ReplyHandler, base::Unretained(this)));
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.
85 // Returns the new request's sequence number which can be used to identify
86 // the callback. This value will never be 0, which you can use to identify
87 // an invalid callback.
89 // Note: 1) When all plugin references to this resource are gone or the
90 // corresponding plugin instance is deleted, all pending callbacks
92 // 2) It is *not* recommended to let |callback| hold any reference to
93 // |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.
97 template<typename ReplyMsgClass
, typename CallbackType
>
98 int32_t Call(Destination dest
,
99 const IPC::Message
& msg
,
100 const CallbackType
& callback
);
102 // 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:
108 // // Assuming the reply message carries a string and an integer.
109 // std::string param_1;
111 // int32_t result = SyncCall<PpapiPluginMsg_MyResourceType_MyReplyMessage>(
112 // RENDERER, PpapiHostMsg_MyResourceType_MyRequestMessage(),
113 // ¶m_1, ¶m_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
>
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
>
127 Destination dest
, const IPC::Message
& msg
, A
* a
, B
* b
, C
* c
, D
* d
, E
* e
);
129 int32_t GenericSyncCall(Destination dest
,
130 const IPC::Message
& msg
,
131 IPC::Message
* reply_msg
,
132 ResourceMessageReplyParams
* reply_params
);
134 const Connection
& connection() { return connection_
; }
137 IPC::Sender
* GetSender(Destination dest
) {
138 return dest
== RENDERER
? connection_
.renderer_sender
:
139 connection_
.browser_sender
;
142 // Helper function to send a |PpapiHostMsg_ResourceCall| to the given
143 // destination with |nested_msg| and |call_params|.
144 bool SendResourceCall(Destination dest
,
145 const ResourceMessageCallParams
& call_params
,
146 const IPC::Message
& nested_msg
);
148 int32_t GetNextSequence();
150 Connection connection_
;
152 // Use GetNextSequence to retrieve the next value.
153 int32_t next_sequence_number_
;
155 bool sent_create_to_browser_
;
156 bool sent_create_to_renderer_
;
158 typedef std::map
<int32_t, scoped_refptr
<PluginResourceCallbackBase
> >
160 CallbackMap callbacks_
;
162 DISALLOW_COPY_AND_ASSIGN(PluginResource
);
165 template<typename ReplyMsgClass
, typename CallbackType
>
166 int32_t PluginResource::Call(Destination dest
,
167 const IPC::Message
& msg
,
168 const CallbackType
& callback
) {
169 TRACE_EVENT2("ppapi proxy", "PluginResource::Call",
170 "Class", IPC_MESSAGE_ID_CLASS(msg
.type()),
171 "Line", IPC_MESSAGE_ID_LINE(msg
.type()));
172 ResourceMessageCallParams
params(pp_resource(), next_sequence_number_
++);
173 // Stash the |callback| in |callbacks_| identified by the sequence number of
175 scoped_refptr
<PluginResourceCallbackBase
> plugin_callback(
176 new PluginResourceCallback
<ReplyMsgClass
, CallbackType
>(callback
));
177 callbacks_
.insert(std::make_pair(params
.sequence(), plugin_callback
));
178 params
.set_has_callback();
179 SendResourceCall(dest
, params
, msg
);
180 return params
.sequence();
183 template <class ReplyMsgClass
>
184 int32_t PluginResource::SyncCall(Destination dest
, const IPC::Message
& msg
) {
186 ResourceMessageReplyParams reply_params
;
187 return GenericSyncCall(dest
, msg
, &reply
, &reply_params
);
190 template <class ReplyMsgClass
, class A
>
191 int32_t PluginResource::SyncCall(
192 Destination dest
, const IPC::Message
& msg
, A
* a
) {
194 ResourceMessageReplyParams reply_params
;
195 int32_t result
= GenericSyncCall(dest
, msg
, &reply
, &reply_params
);
197 if (UnpackMessage
<ReplyMsgClass
>(reply
, a
))
199 return PP_ERROR_FAILED
;
202 template <class ReplyMsgClass
, class A
, class B
>
203 int32_t PluginResource::SyncCall(
204 Destination dest
, const IPC::Message
& msg
, A
* a
, B
* b
) {
206 ResourceMessageReplyParams reply_params
;
207 int32_t result
= GenericSyncCall(dest
, msg
, &reply
, &reply_params
);
209 if (UnpackMessage
<ReplyMsgClass
>(reply
, a
, b
))
211 return PP_ERROR_FAILED
;
214 template <class ReplyMsgClass
, class A
, class B
, class C
>
215 int32_t PluginResource::SyncCall(
216 Destination dest
, const IPC::Message
& msg
, A
* a
, B
* b
, C
* c
) {
218 ResourceMessageReplyParams reply_params
;
219 int32_t result
= GenericSyncCall(dest
, msg
, &reply
, &reply_params
);
221 if (UnpackMessage
<ReplyMsgClass
>(reply
, a
, b
, c
))
223 return PP_ERROR_FAILED
;
226 template <class ReplyMsgClass
, class A
, class B
, class C
, class D
>
227 int32_t PluginResource::SyncCall(
228 Destination dest
, const IPC::Message
& msg
, A
* a
, B
* b
, C
* c
, D
* d
) {
230 ResourceMessageReplyParams reply_params
;
231 int32_t result
= GenericSyncCall(dest
, msg
, &reply
, &reply_params
);
233 if (UnpackMessage
<ReplyMsgClass
>(reply
, a
, b
, c
, d
))
235 return PP_ERROR_FAILED
;
238 template <class ReplyMsgClass
, class A
, class B
, class C
, class D
, class E
>
239 int32_t PluginResource::SyncCall(
240 Destination dest
, const IPC::Message
& msg
, A
* a
, B
* b
, C
* c
, D
* d
, E
* e
) {
242 ResourceMessageReplyParams reply_params
;
243 int32_t result
= GenericSyncCall(dest
, msg
, &reply
, &reply_params
);
245 if (UnpackMessage
<ReplyMsgClass
>(reply
, a
, b
, c
, d
, e
))
247 return PP_ERROR_FAILED
;
253 #endif // PPAPI_PROXY_PLUGIN_RESOURCE_H_