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 #include "ppapi/proxy/ppp_class_proxy.h"
7 #include "ppapi/c/dev/ppb_var_deprecated.h"
8 #include "ppapi/c/dev/ppp_class_deprecated.h"
9 #include "ppapi/c/pp_var.h"
10 #include "ppapi/proxy/dispatcher.h"
11 #include "ppapi/proxy/plugin_globals.h"
12 #include "ppapi/proxy/ppapi_messages.h"
13 #include "ppapi/proxy/serialized_var.h"
14 #include "ppapi/shared_impl/proxy_lock.h"
15 #include "ppapi/shared_impl/api_id.h"
22 // PPP_Class in the browser implementation -------------------------------------
24 // Represents a plugin-implemented class in the browser process. This just
25 // stores the data necessary to call back the plugin.
27 ObjectProxy(Dispatcher
* d
, int64 p
, int64 ud
)
33 Dispatcher
* dispatcher
;
38 ObjectProxy
* ToObjectProxy(void* data
) {
39 return reinterpret_cast<ObjectProxy
*>(data
);
42 bool HasProperty(void* object
, PP_Var name
, PP_Var
* exception
) {
43 ObjectProxy
* obj
= ToObjectProxy(object
);
45 ReceiveSerializedException
se(obj
->dispatcher
, exception
);
46 obj
->dispatcher
->Send(new PpapiMsg_PPPClass_HasProperty(
47 API_ID_PPP_CLASS
, obj
->ppp_class
, obj
->user_data
,
48 SerializedVarSendInput(obj
->dispatcher
, name
), &se
, &result
));
52 bool HasMethod(void* object
, PP_Var name
, PP_Var
* exception
) {
53 ObjectProxy
* obj
= ToObjectProxy(object
);
55 ReceiveSerializedException
se(obj
->dispatcher
, exception
);
56 obj
->dispatcher
->Send(new PpapiMsg_PPPClass_HasMethod(
57 API_ID_PPP_CLASS
, obj
->ppp_class
, obj
->user_data
,
58 SerializedVarSendInput(obj
->dispatcher
, name
), &se
, &result
));
62 PP_Var
GetProperty(void* object
,
65 ObjectProxy
* obj
= ToObjectProxy(object
);
66 ReceiveSerializedException
se(obj
->dispatcher
, exception
);
67 ReceiveSerializedVarReturnValue result
;
68 obj
->dispatcher
->Send(new PpapiMsg_PPPClass_GetProperty(
69 API_ID_PPP_CLASS
, obj
->ppp_class
, obj
->user_data
,
70 SerializedVarSendInput(obj
->dispatcher
, name
), &se
, &result
));
71 return result
.Return(obj
->dispatcher
);
74 void GetAllPropertyNames(void* object
,
75 uint32_t* property_count
,
79 // TODO(brettw) implement this.
82 void SetProperty(void* object
,
86 ObjectProxy
* obj
= ToObjectProxy(object
);
87 ReceiveSerializedException
se(obj
->dispatcher
, exception
);
88 obj
->dispatcher
->Send(new PpapiMsg_PPPClass_SetProperty(
89 API_ID_PPP_CLASS
, obj
->ppp_class
, obj
->user_data
,
90 SerializedVarSendInput(obj
->dispatcher
, name
),
91 SerializedVarSendInput(obj
->dispatcher
, value
), &se
));
94 void RemoveProperty(void* object
,
97 ObjectProxy
* obj
= ToObjectProxy(object
);
98 ReceiveSerializedException
se(obj
->dispatcher
, exception
);
99 obj
->dispatcher
->Send(new PpapiMsg_PPPClass_RemoveProperty(
100 API_ID_PPP_CLASS
, obj
->ppp_class
, obj
->user_data
,
101 SerializedVarSendInput(obj
->dispatcher
, name
), &se
));
104 PP_Var
Call(void* object
,
109 ObjectProxy
* obj
= ToObjectProxy(object
);
111 ReceiveSerializedVarReturnValue result
;
112 ReceiveSerializedException
se(obj
->dispatcher
, exception
);
113 std::vector
<SerializedVar
> argv_vect
;
114 SerializedVarSendInput::ConvertVector(obj
->dispatcher
, argv
, argc
,
117 obj
->dispatcher
->Send(new PpapiMsg_PPPClass_Call(
118 API_ID_PPP_CLASS
, obj
->ppp_class
, obj
->user_data
,
119 SerializedVarSendInput(obj
->dispatcher
, method_name
), argv_vect
,
121 return result
.Return(obj
->dispatcher
);
124 PP_Var
Construct(void* object
,
128 ObjectProxy
* obj
= ToObjectProxy(object
);
130 ReceiveSerializedVarReturnValue result
;
131 ReceiveSerializedException
se(obj
->dispatcher
, exception
);
132 std::vector
<SerializedVar
> argv_vect
;
133 SerializedVarSendInput::ConvertVector(obj
->dispatcher
, argv
, argc
,
136 obj
->dispatcher
->Send(new PpapiMsg_PPPClass_Construct(
138 obj
->ppp_class
, obj
->user_data
, argv_vect
, &se
, &result
));
139 return result
.Return(obj
->dispatcher
);
142 void Deallocate(void* object
) {
143 ObjectProxy
* obj
= ToObjectProxy(object
);
144 obj
->dispatcher
->Send(new PpapiMsg_PPPClass_Deallocate(
145 API_ID_PPP_CLASS
, obj
->ppp_class
, obj
->user_data
));
149 const PPP_Class_Deprecated class_interface
= {
153 &GetAllPropertyNames
,
161 // Plugin helper functions -----------------------------------------------------
163 // Converts an int64 object from IPC to a PPP_Class* for calling into the
164 // plugin's implementation.
165 const PPP_Class_Deprecated
* ToPPPClass(int64 value
) {
166 return reinterpret_cast<const PPP_Class_Deprecated
*>(
167 static_cast<intptr_t>(value
));
170 // Converts an int64 object from IPC to a void* for calling into the plugin's
171 // implementation as the user data.
172 void* ToUserData(int64 value
) {
173 return reinterpret_cast<void*>(static_cast<intptr_t>(value
));
178 // PPP_Class_Proxy -------------------------------------------------------------
180 PPP_Class_Proxy::PPP_Class_Proxy(Dispatcher
* dispatcher
)
181 : InterfaceProxy(dispatcher
) {
184 PPP_Class_Proxy::~PPP_Class_Proxy() {
188 InterfaceProxy
* PPP_Class_Proxy::Create(Dispatcher
* dispatcher
) {
189 return new PPP_Class_Proxy(dispatcher
);
193 PP_Var
PPP_Class_Proxy::CreateProxiedObject(const PPB_Var_Deprecated
* var
,
194 Dispatcher
* dispatcher
,
195 PP_Instance instance_id
,
198 ObjectProxy
* object_proxy
= new ObjectProxy(dispatcher
,
199 ppp_class
, class_data
);
200 return var
->CreateObject(instance_id
, &class_interface
, object_proxy
);
204 PP_Bool
PPP_Class_Proxy::IsInstanceOf(const PPB_Var_Deprecated
* ppb_var_impl
,
207 int64
* ppp_class_data
) {
208 void* proxied_object
= NULL
;
209 if (ppb_var_impl
->IsInstanceOf(var
,
212 if (static_cast<ObjectProxy
*>(proxied_object
)->ppp_class
== ppp_class
) {
213 DCHECK(ppp_class_data
);
214 *ppp_class_data
= static_cast<ObjectProxy
*>(proxied_object
)->user_data
;
221 bool PPP_Class_Proxy::OnMessageReceived(const IPC::Message
& msg
) {
223 IPC_BEGIN_MESSAGE_MAP(PPP_Class_Proxy
, msg
)
224 IPC_MESSAGE_HANDLER(PpapiMsg_PPPClass_HasProperty
,
226 IPC_MESSAGE_HANDLER(PpapiMsg_PPPClass_HasMethod
,
228 IPC_MESSAGE_HANDLER(PpapiMsg_PPPClass_GetProperty
,
230 IPC_MESSAGE_HANDLER(PpapiMsg_PPPClass_EnumerateProperties
,
231 OnMsgEnumerateProperties
)
232 IPC_MESSAGE_HANDLER(PpapiMsg_PPPClass_SetProperty
,
234 IPC_MESSAGE_HANDLER(PpapiMsg_PPPClass_Call
,
236 IPC_MESSAGE_HANDLER(PpapiMsg_PPPClass_Construct
,
238 IPC_MESSAGE_HANDLER(PpapiMsg_PPPClass_Deallocate
,
240 IPC_MESSAGE_UNHANDLED(handled
= false)
241 IPC_END_MESSAGE_MAP()
245 void PPP_Class_Proxy::OnMsgHasProperty(int64 ppp_class
, int64 object
,
246 SerializedVarReceiveInput property
,
247 SerializedVarOutParam exception
,
249 if (!ValidateUserData(ppp_class
, object
, &exception
))
251 *result
= CallWhileUnlocked(ToPPPClass(ppp_class
)->HasProperty
,
253 property
.Get(dispatcher()),
254 exception
.OutParam(dispatcher()));
257 void PPP_Class_Proxy::OnMsgHasMethod(int64 ppp_class
, int64 object
,
258 SerializedVarReceiveInput property
,
259 SerializedVarOutParam exception
,
261 if (!ValidateUserData(ppp_class
, object
, &exception
))
263 *result
= CallWhileUnlocked(ToPPPClass(ppp_class
)->HasMethod
,
265 property
.Get(dispatcher()),
266 exception
.OutParam(dispatcher()));
269 void PPP_Class_Proxy::OnMsgGetProperty(int64 ppp_class
, int64 object
,
270 SerializedVarReceiveInput property
,
271 SerializedVarOutParam exception
,
272 SerializedVarReturnValue result
) {
273 if (!ValidateUserData(ppp_class
, object
, &exception
))
275 result
.Return(dispatcher(), CallWhileUnlocked(
276 ToPPPClass(ppp_class
)->GetProperty
,
277 ToUserData(object
), property
.Get(dispatcher()),
278 exception
.OutParam(dispatcher())));
281 void PPP_Class_Proxy::OnMsgEnumerateProperties(
282 int64 ppp_class
, int64 object
,
283 std::vector
<SerializedVar
>* props
,
284 SerializedVarOutParam exception
) {
285 if (!ValidateUserData(ppp_class
, object
, &exception
))
288 // TODO(brettw) implement this.
291 void PPP_Class_Proxy::OnMsgSetProperty(int64 ppp_class
, int64 object
,
292 SerializedVarReceiveInput property
,
293 SerializedVarReceiveInput value
,
294 SerializedVarOutParam exception
) {
295 if (!ValidateUserData(ppp_class
, object
, &exception
))
297 CallWhileUnlocked(ToPPPClass(ppp_class
)->SetProperty
,
298 ToUserData(object
), property
.Get(dispatcher()), value
.Get(dispatcher()),
299 exception
.OutParam(dispatcher()));
302 void PPP_Class_Proxy::OnMsgRemoveProperty(int64 ppp_class
, int64 object
,
303 SerializedVarReceiveInput property
,
304 SerializedVarOutParam exception
) {
305 if (!ValidateUserData(ppp_class
, object
, &exception
))
307 CallWhileUnlocked(ToPPPClass(ppp_class
)->RemoveProperty
,
308 ToUserData(object
), property
.Get(dispatcher()),
309 exception
.OutParam(dispatcher()));
312 void PPP_Class_Proxy::OnMsgCall(
313 int64 ppp_class
, int64 object
,
314 SerializedVarReceiveInput method_name
,
315 SerializedVarVectorReceiveInput arg_vector
,
316 SerializedVarOutParam exception
,
317 SerializedVarReturnValue result
) {
318 if (!ValidateUserData(ppp_class
, object
, &exception
))
320 uint32_t arg_count
= 0;
321 PP_Var
* args
= arg_vector
.Get(dispatcher(), &arg_count
);
322 result
.Return(dispatcher(), CallWhileUnlocked(ToPPPClass(ppp_class
)->Call
,
323 ToUserData(object
), method_name
.Get(dispatcher()),
324 arg_count
, args
, exception
.OutParam(dispatcher())));
327 void PPP_Class_Proxy::OnMsgConstruct(
328 int64 ppp_class
, int64 object
,
329 SerializedVarVectorReceiveInput arg_vector
,
330 SerializedVarOutParam exception
,
331 SerializedVarReturnValue result
) {
332 if (!ValidateUserData(ppp_class
, object
, &exception
))
334 uint32_t arg_count
= 0;
335 PP_Var
* args
= arg_vector
.Get(dispatcher(), &arg_count
);
336 result
.Return(dispatcher(), CallWhileUnlocked(
337 ToPPPClass(ppp_class
)->Construct
,
338 ToUserData(object
), arg_count
, args
, exception
.OutParam(dispatcher())));
341 void PPP_Class_Proxy::OnMsgDeallocate(int64 ppp_class
, int64 object
) {
342 if (!ValidateUserData(ppp_class
, object
, NULL
))
344 PluginGlobals::Get()->plugin_var_tracker()->PluginImplementedObjectDestroyed(
346 CallWhileUnlocked(ToPPPClass(ppp_class
)->Deallocate
, ToUserData(object
));
349 bool PPP_Class_Proxy::ValidateUserData(int64 ppp_class
, int64 class_data
,
350 SerializedVarOutParam
* exception
) {
351 if (!PluginGlobals::Get()->plugin_var_tracker()->ValidatePluginObjectCall(
352 ToPPPClass(ppp_class
), ToUserData(class_data
))) {
353 // Set the exception. This is so the caller will know about the error and
354 // also that we won't assert that somebody forgot to call OutParam on the
355 // output parameter. Although this exception of "1" won't be very useful
356 // this shouldn't happen in normal usage, only when the renderer is being
359 *exception
->OutParam(dispatcher()) = PP_MakeInt32(1);