blob: 727ff9ee8dae0145bf91779ae23266b07c6884af [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"
19#include "ppapi/shared_impl/resource.h"
20
[email protected]eccf80312012-07-14 15:43:4221namespace ppapi {
22namespace proxy {
23
24class PluginDispatcher;
25
[email protected]93df81e2012-08-10 22:22:4626class PPAPI_PROXY_EXPORT PluginResource : public Resource {
[email protected]eccf80312012-07-14 15:43:4227 public:
[email protected]93df81e2012-08-10 22:22:4628 PluginResource(Connection connection, PP_Instance instance);
[email protected]eccf80312012-07-14 15:43:4229 virtual ~PluginResource();
30
[email protected]93df81e2012-08-10 22:22:4631 // Returns true if we've previously sent a create message to the browser
32 // or renderer. Generally resources will use these to tell if they should
33 // lazily send create messages.
34 bool sent_create_to_browser() const { return sent_create_to_browser_; }
[email protected]eccf80312012-07-14 15:43:4235 bool sent_create_to_renderer() const { return sent_create_to_renderer_; }
36
[email protected]e1f5c9b2012-10-04 00:07:4437 // This handles a reply to a resource call. It works by looking up the
38 // callback that was registered when CallBrowser/CallRenderer was called
39 // and calling it with |params| and |msg|.
40 virtual void OnReplyReceived(const proxy::ResourceMessageReplyParams& params,
41 const IPC::Message& msg) OVERRIDE;
[email protected]eccf80312012-07-14 15:43:4242 protected:
[email protected]58786932012-10-13 10:16:0843 enum Destination {
44 RENDERER = 0,
45 BROWSER = 1
46 };
47
48 IPC::Sender* GetSender(Destination dest) {
49 return dest == RENDERER ? connection_.renderer_sender :
50 connection_.browser_sender;
51 }
52
[email protected]93df81e2012-08-10 22:22:4653 // Sends a create message to the browser or renderer for the current resource.
54 void SendCreateToBrowser(const IPC::Message& msg);
[email protected]eccf80312012-07-14 15:43:4255 void SendCreateToRenderer(const IPC::Message& msg);
56
57 // Sends the given IPC message as a resource request to the host
58 // corresponding to this resource object and does not expect a reply.
[email protected]93df81e2012-08-10 22:22:4659 void PostToBrowser(const IPC::Message& msg);
[email protected]eccf80312012-07-14 15:43:4260 void PostToRenderer(const IPC::Message& msg);
61
[email protected]e1f5c9b2012-10-04 00:07:4462 // Like PostToBrowser/Renderer but expects a response. |callback| is
63 // a |base::Callback| that will be run when a reply message with a sequence
64 // number matching that of the call is received. |ReplyMsgClass| is the type
65 // of the reply message that is expected. An example of usage:
66 //
67 // CallBrowser<PpapiPluginMsg_MyResourceType_MyReplyMessage>(
68 // PpapiHostMsg_MyResourceType_MyRequestMessage(),
69 // base::Bind(&MyPluginResource::ReplyHandler, this));
70 //
71 // If a reply message to this call is received whose type does not match
72 // |ReplyMsgClass| (for example, in the case of an error), the callback will
73 // still be invoked but with the default values of the message parameters.
[email protected]eccf80312012-07-14 15:43:4274 //
75 // Returns the new request's sequence number which can be used to identify
[email protected]e1f5c9b2012-10-04 00:07:4476 // the callback.
[email protected]eccf80312012-07-14 15:43:4277 //
78 // Note that all integers (including 0 and -1) are valid request IDs.
[email protected]e1f5c9b2012-10-04 00:07:4479 template<typename ReplyMsgClass, typename CallbackType>
80 int32_t CallBrowser(const IPC::Message& msg, const CallbackType& callback);
81 template<typename ReplyMsgClass, typename CallbackType>
82 int32_t CallRenderer(const IPC::Message& msg, const CallbackType& callback);
[email protected]eccf80312012-07-14 15:43:4283
[email protected]58786932012-10-13 10:16:0884 // Calls the browser/renderer with sync messages. Returns the pepper error
85 // code from the call.
86 // |ReplyMsgClass| is the type of the reply message that is expected. If it
87 // carries x parameters, then the method with x out parameters should be used.
88 // An example of usage:
89 //
90 // // Assuming the reply message carries a string and an integer.
91 // std::string param_1;
92 // int param_2 = 0;
93 // int32_t result = SyncCall<PpapiPluginMsg_MyResourceType_MyReplyMessage>(
94 // RENDERER, PpapiHostMsg_MyResourceType_MyRequestMessage(),
95 // &param_1, &param_2);
96 template <class ReplyMsgClass>
97 int32_t SyncCall(Destination dest, const IPC::Message& msg);
98 template <class ReplyMsgClass, class A>
99 int32_t SyncCall(Destination dest, const IPC::Message& msg, A* a);
100 template <class ReplyMsgClass, class A, class B>
101 int32_t SyncCall(Destination dest, const IPC::Message& msg, A* a, B* b);
102 template <class ReplyMsgClass, class A, class B, class C>
103 int32_t SyncCall(Destination dest, const IPC::Message& msg, A* a, B* b, C* c);
104 template <class ReplyMsgClass, class A, class B, class C, class D>
105 int32_t SyncCall(
106 Destination dest, const IPC::Message& msg, A* a, B* b, C* c, D* d);
107 template <class ReplyMsgClass, class A, class B, class C, class D, class E>
108 int32_t SyncCall(
109 Destination dest, const IPC::Message& msg, A* a, B* b, C* c, D* d, E* e);
[email protected]ff44fc12012-10-03 00:52:16110
[email protected]eccf80312012-07-14 15:43:42111 private:
[email protected]e1f5c9b2012-10-04 00:07:44112 // Helper function to send a |PpapiHostMsg_ResourceCall| to the given sender
113 // with |nested_msg| and |call_params|.
114 bool SendResourceCall(IPC::Sender* sender,
115 const ResourceMessageCallParams& call_params,
116 const IPC::Message& nested_msg);
117
118 // Helper function to make a Resource Call to a host with a callback.
119 template<typename ReplyMsgClass, typename CallbackType>
120 int32_t CallHost(IPC::Sender* sender,
121 const IPC::Message& msg,
122 const CallbackType& callback);
123
[email protected]58786932012-10-13 10:16:08124 int32_t GenericSyncCall(Destination dest,
125 const IPC::Message& msg,
126 IPC::Message* reply_msg);
127
[email protected]93df81e2012-08-10 22:22:46128 Connection connection_;
[email protected]eccf80312012-07-14 15:43:42129
130 int32_t next_sequence_number_;
131
[email protected]93df81e2012-08-10 22:22:46132 bool sent_create_to_browser_;
[email protected]eccf80312012-07-14 15:43:42133 bool sent_create_to_renderer_;
134
[email protected]e1f5c9b2012-10-04 00:07:44135 typedef std::map<int32_t, scoped_refptr<PluginResourceCallbackBase> >
136 CallbackMap;
137 CallbackMap callbacks_;
138
[email protected]eccf80312012-07-14 15:43:42139 DISALLOW_COPY_AND_ASSIGN(PluginResource);
140};
141
[email protected]e1f5c9b2012-10-04 00:07:44142template<typename ReplyMsgClass, typename CallbackType>
143int32_t PluginResource::CallBrowser(const IPC::Message& msg,
144 const CallbackType& callback) {
145 return CallHost<ReplyMsgClass, CallbackType>(
146 connection_.browser_sender, msg, callback);
147}
148
149template<typename ReplyMsgClass, typename CallbackType>
150int32_t PluginResource::CallRenderer(const IPC::Message& msg,
151 const CallbackType& callback) {
152 return CallHost<ReplyMsgClass, CallbackType>(
153 connection_.renderer_sender, msg, callback);
154}
155
156template<typename ReplyMsgClass, typename CallbackType>
157int32_t PluginResource::CallHost(IPC::Sender* sender,
158 const IPC::Message& msg,
159 const CallbackType& callback) {
160 ResourceMessageCallParams params(pp_resource(),
161 next_sequence_number_++);
162 // Stash the |callback| in |callbacks_| identified by the sequence number of
163 // the call.
164 scoped_refptr<PluginResourceCallbackBase> plugin_callback(
165 new PluginResourceCallback<ReplyMsgClass, CallbackType>(callback));
166 callbacks_.insert(std::make_pair(params.sequence(), plugin_callback));
167 params.set_has_callback();
168 SendResourceCall(sender, params, msg);
169 return params.sequence();
170}
171
[email protected]58786932012-10-13 10:16:08172template <class ReplyMsgClass>
173int32_t PluginResource::SyncCall(Destination dest, const IPC::Message& msg) {
174 IPC::Message reply;
175 return GenericSyncCall(dest, msg, &reply);
176}
177
178template <class ReplyMsgClass, class A>
179int32_t PluginResource::SyncCall(
180 Destination dest, const IPC::Message& msg, A* a) {
181 IPC::Message reply;
182 int32_t result = GenericSyncCall(dest, msg, &reply);
183
184 if (UnpackMessage<ReplyMsgClass>(reply, a))
185 return result;
186 return PP_ERROR_FAILED;
187}
188
189template <class ReplyMsgClass, class A, class B>
190int32_t PluginResource::SyncCall(
191 Destination dest, const IPC::Message& msg, A* a, B* b) {
192 IPC::Message reply;
193 int32_t result = GenericSyncCall(dest, msg, &reply);
194
195 if (UnpackMessage<ReplyMsgClass>(reply, a, b))
196 return result;
197 return PP_ERROR_FAILED;
198}
199
200template <class ReplyMsgClass, class A, class B, class C>
201int32_t PluginResource::SyncCall(
202 Destination dest, const IPC::Message& msg, A* a, B* b, C* c) {
203 IPC::Message reply;
204 int32_t result = GenericSyncCall(dest, msg, &reply);
205
206 if (UnpackMessage<ReplyMsgClass>(reply, a, b, c))
207 return result;
208 return PP_ERROR_FAILED;
209}
210
211template <class ReplyMsgClass, class A, class B, class C, class D>
212int32_t PluginResource::SyncCall(
213 Destination dest, const IPC::Message& msg, A* a, B* b, C* c, D* d) {
214 IPC::Message reply;
215 int32_t result = GenericSyncCall(dest, msg, &reply);
216
217 if (UnpackMessage<ReplyMsgClass>(reply, a, b, c, d))
218 return result;
219 return PP_ERROR_FAILED;
220}
221
222template <class ReplyMsgClass, class A, class B, class C, class D, class E>
223int32_t PluginResource::SyncCall(
224 Destination dest, const IPC::Message& msg, A* a, B* b, C* c, D* d, E* e) {
225 IPC::Message reply;
226 int32_t result = GenericSyncCall(dest, msg, &reply);
227
228 if (UnpackMessage<ReplyMsgClass>(reply, a, b, c, d, e))
229 return result;
230 return PP_ERROR_FAILED;
231}
232
[email protected]eccf80312012-07-14 15:43:42233} // namespace proxy
234} // namespace ppapi
235
236#endif // PPAPI_PROXY_PLUGIN_RESOURCE_H_