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 ObjectProxy
* obj
= reinterpret_cast<ObjectProxy
*>(data
);
40 if (!obj
|| !obj
->dispatcher
)
42 if (!obj
->dispatcher
->permissions().HasPermission(PERMISSION_DEV
))
47 bool HasProperty(void* object
, PP_Var name
, PP_Var
* exception
) {
48 ObjectProxy
* obj
= ToObjectProxy(object
);
53 ReceiveSerializedException
se(obj
->dispatcher
, exception
);
54 obj
->dispatcher
->Send(new PpapiMsg_PPPClass_HasProperty(
55 API_ID_PPP_CLASS
, obj
->ppp_class
, obj
->user_data
,
56 SerializedVarSendInput(obj
->dispatcher
, name
), &se
, &result
));
60 bool HasMethod(void* object
, PP_Var name
, PP_Var
* exception
) {
61 ObjectProxy
* obj
= ToObjectProxy(object
);
66 ReceiveSerializedException
se(obj
->dispatcher
, exception
);
67 obj
->dispatcher
->Send(new PpapiMsg_PPPClass_HasMethod(
68 API_ID_PPP_CLASS
, obj
->ppp_class
, obj
->user_data
,
69 SerializedVarSendInput(obj
->dispatcher
, name
), &se
, &result
));
73 PP_Var
GetProperty(void* object
,
76 ObjectProxy
* obj
= ToObjectProxy(object
);
78 return PP_MakeUndefined();
80 ReceiveSerializedException
se(obj
->dispatcher
, exception
);
81 ReceiveSerializedVarReturnValue result
;
82 obj
->dispatcher
->Send(new PpapiMsg_PPPClass_GetProperty(
83 API_ID_PPP_CLASS
, obj
->ppp_class
, obj
->user_data
,
84 SerializedVarSendInput(obj
->dispatcher
, name
), &se
, &result
));
85 return result
.Return(obj
->dispatcher
);
88 void GetAllPropertyNames(void* object
,
89 uint32_t* property_count
,
93 // TODO(brettw) implement this.
96 void SetProperty(void* object
,
100 ObjectProxy
* obj
= ToObjectProxy(object
);
104 ReceiveSerializedException
se(obj
->dispatcher
, exception
);
105 obj
->dispatcher
->Send(new PpapiMsg_PPPClass_SetProperty(
106 API_ID_PPP_CLASS
, obj
->ppp_class
, obj
->user_data
,
107 SerializedVarSendInput(obj
->dispatcher
, name
),
108 SerializedVarSendInput(obj
->dispatcher
, value
), &se
));
111 void RemoveProperty(void* object
,
114 ObjectProxy
* obj
= ToObjectProxy(object
);
118 ReceiveSerializedException
se(obj
->dispatcher
, exception
);
119 obj
->dispatcher
->Send(new PpapiMsg_PPPClass_RemoveProperty(
120 API_ID_PPP_CLASS
, obj
->ppp_class
, obj
->user_data
,
121 SerializedVarSendInput(obj
->dispatcher
, name
), &se
));
124 PP_Var
Call(void* object
,
129 ObjectProxy
* obj
= ToObjectProxy(object
);
131 return PP_MakeUndefined();
133 ReceiveSerializedVarReturnValue result
;
134 ReceiveSerializedException
se(obj
->dispatcher
, exception
);
135 std::vector
<SerializedVar
> argv_vect
;
136 SerializedVarSendInput::ConvertVector(obj
->dispatcher
, argv
, argc
,
139 obj
->dispatcher
->Send(new PpapiMsg_PPPClass_Call(
140 API_ID_PPP_CLASS
, obj
->ppp_class
, obj
->user_data
,
141 SerializedVarSendInput(obj
->dispatcher
, method_name
), argv_vect
,
143 return result
.Return(obj
->dispatcher
);
146 PP_Var
Construct(void* object
,
150 ObjectProxy
* obj
= ToObjectProxy(object
);
152 return PP_MakeUndefined();
154 ReceiveSerializedVarReturnValue result
;
155 ReceiveSerializedException
se(obj
->dispatcher
, exception
);
156 std::vector
<SerializedVar
> argv_vect
;
157 SerializedVarSendInput::ConvertVector(obj
->dispatcher
, argv
, argc
,
160 obj
->dispatcher
->Send(new PpapiMsg_PPPClass_Construct(
162 obj
->ppp_class
, obj
->user_data
, argv_vect
, &se
, &result
));
163 return result
.Return(obj
->dispatcher
);
166 void Deallocate(void* object
) {
167 ObjectProxy
* obj
= ToObjectProxy(object
);
171 obj
->dispatcher
->Send(new PpapiMsg_PPPClass_Deallocate(
172 API_ID_PPP_CLASS
, obj
->ppp_class
, obj
->user_data
));
176 const PPP_Class_Deprecated class_interface
= {
180 &GetAllPropertyNames
,
188 // Plugin helper functions -----------------------------------------------------
190 // Converts an int64 object from IPC to a PPP_Class* for calling into the
191 // plugin's implementation.
192 const PPP_Class_Deprecated
* ToPPPClass(int64 value
) {
193 return reinterpret_cast<const PPP_Class_Deprecated
*>(
194 static_cast<intptr_t>(value
));
197 // Converts an int64 object from IPC to a void* for calling into the plugin's
198 // implementation as the user data.
199 void* ToUserData(int64 value
) {
200 return reinterpret_cast<void*>(static_cast<intptr_t>(value
));
205 // PPP_Class_Proxy -------------------------------------------------------------
207 PPP_Class_Proxy::PPP_Class_Proxy(Dispatcher
* dispatcher
)
208 : InterfaceProxy(dispatcher
) {
211 PPP_Class_Proxy::~PPP_Class_Proxy() {
215 InterfaceProxy
* PPP_Class_Proxy::Create(Dispatcher
* dispatcher
) {
216 return new PPP_Class_Proxy(dispatcher
);
220 PP_Var
PPP_Class_Proxy::CreateProxiedObject(const PPB_Var_Deprecated
* var
,
221 Dispatcher
* dispatcher
,
222 PP_Instance instance_id
,
225 ObjectProxy
* object_proxy
= new ObjectProxy(dispatcher
,
226 ppp_class
, class_data
);
227 return var
->CreateObject(instance_id
, &class_interface
, object_proxy
);
231 PP_Bool
PPP_Class_Proxy::IsInstanceOf(const PPB_Var_Deprecated
* ppb_var_impl
,
234 int64
* ppp_class_data
) {
235 void* proxied_object
= NULL
;
236 if (ppb_var_impl
->IsInstanceOf(var
,
239 if (static_cast<ObjectProxy
*>(proxied_object
)->ppp_class
== ppp_class
) {
240 DCHECK(ppp_class_data
);
241 *ppp_class_data
= static_cast<ObjectProxy
*>(proxied_object
)->user_data
;
248 bool PPP_Class_Proxy::OnMessageReceived(const IPC::Message
& msg
) {
250 IPC_BEGIN_MESSAGE_MAP(PPP_Class_Proxy
, msg
)
251 IPC_MESSAGE_HANDLER(PpapiMsg_PPPClass_HasProperty
,
253 IPC_MESSAGE_HANDLER(PpapiMsg_PPPClass_HasMethod
,
255 IPC_MESSAGE_HANDLER(PpapiMsg_PPPClass_GetProperty
,
257 IPC_MESSAGE_HANDLER(PpapiMsg_PPPClass_EnumerateProperties
,
258 OnMsgEnumerateProperties
)
259 IPC_MESSAGE_HANDLER(PpapiMsg_PPPClass_SetProperty
,
261 IPC_MESSAGE_HANDLER(PpapiMsg_PPPClass_Call
,
263 IPC_MESSAGE_HANDLER(PpapiMsg_PPPClass_Construct
,
265 IPC_MESSAGE_HANDLER(PpapiMsg_PPPClass_Deallocate
,
267 IPC_MESSAGE_UNHANDLED(handled
= false)
268 IPC_END_MESSAGE_MAP()
272 void PPP_Class_Proxy::OnMsgHasProperty(int64 ppp_class
, int64 object
,
273 SerializedVarReceiveInput property
,
274 SerializedVarOutParam exception
,
276 if (!ValidateUserData(ppp_class
, object
, &exception
))
278 *result
= CallWhileUnlocked(ToPPPClass(ppp_class
)->HasProperty
,
280 property
.Get(dispatcher()),
281 exception
.OutParam(dispatcher()));
284 void PPP_Class_Proxy::OnMsgHasMethod(int64 ppp_class
, int64 object
,
285 SerializedVarReceiveInput property
,
286 SerializedVarOutParam exception
,
288 if (!ValidateUserData(ppp_class
, object
, &exception
))
290 *result
= CallWhileUnlocked(ToPPPClass(ppp_class
)->HasMethod
,
292 property
.Get(dispatcher()),
293 exception
.OutParam(dispatcher()));
296 void PPP_Class_Proxy::OnMsgGetProperty(int64 ppp_class
, int64 object
,
297 SerializedVarReceiveInput property
,
298 SerializedVarOutParam exception
,
299 SerializedVarReturnValue result
) {
300 if (!ValidateUserData(ppp_class
, object
, &exception
))
302 result
.Return(dispatcher(), CallWhileUnlocked(
303 ToPPPClass(ppp_class
)->GetProperty
,
304 ToUserData(object
), property
.Get(dispatcher()),
305 exception
.OutParam(dispatcher())));
308 void PPP_Class_Proxy::OnMsgEnumerateProperties(
309 int64 ppp_class
, int64 object
,
310 std::vector
<SerializedVar
>* props
,
311 SerializedVarOutParam exception
) {
312 if (!ValidateUserData(ppp_class
, object
, &exception
))
315 // TODO(brettw) implement this.
318 void PPP_Class_Proxy::OnMsgSetProperty(int64 ppp_class
, int64 object
,
319 SerializedVarReceiveInput property
,
320 SerializedVarReceiveInput value
,
321 SerializedVarOutParam exception
) {
322 if (!ValidateUserData(ppp_class
, object
, &exception
))
324 CallWhileUnlocked(ToPPPClass(ppp_class
)->SetProperty
,
325 ToUserData(object
), property
.Get(dispatcher()), value
.Get(dispatcher()),
326 exception
.OutParam(dispatcher()));
329 void PPP_Class_Proxy::OnMsgRemoveProperty(int64 ppp_class
, int64 object
,
330 SerializedVarReceiveInput property
,
331 SerializedVarOutParam exception
) {
332 if (!ValidateUserData(ppp_class
, object
, &exception
))
334 CallWhileUnlocked(ToPPPClass(ppp_class
)->RemoveProperty
,
335 ToUserData(object
), property
.Get(dispatcher()),
336 exception
.OutParam(dispatcher()));
339 void PPP_Class_Proxy::OnMsgCall(
340 int64 ppp_class
, int64 object
,
341 SerializedVarReceiveInput method_name
,
342 SerializedVarVectorReceiveInput arg_vector
,
343 SerializedVarOutParam exception
,
344 SerializedVarReturnValue result
) {
345 if (!ValidateUserData(ppp_class
, object
, &exception
))
347 uint32_t arg_count
= 0;
348 PP_Var
* args
= arg_vector
.Get(dispatcher(), &arg_count
);
349 result
.Return(dispatcher(), CallWhileUnlocked(ToPPPClass(ppp_class
)->Call
,
350 ToUserData(object
), method_name
.Get(dispatcher()),
351 arg_count
, args
, exception
.OutParam(dispatcher())));
354 void PPP_Class_Proxy::OnMsgConstruct(
355 int64 ppp_class
, int64 object
,
356 SerializedVarVectorReceiveInput arg_vector
,
357 SerializedVarOutParam exception
,
358 SerializedVarReturnValue result
) {
359 if (!ValidateUserData(ppp_class
, object
, &exception
))
361 uint32_t arg_count
= 0;
362 PP_Var
* args
= arg_vector
.Get(dispatcher(), &arg_count
);
363 result
.Return(dispatcher(), CallWhileUnlocked(
364 ToPPPClass(ppp_class
)->Construct
,
365 ToUserData(object
), arg_count
, args
, exception
.OutParam(dispatcher())));
368 void PPP_Class_Proxy::OnMsgDeallocate(int64 ppp_class
, int64 object
) {
369 if (!ValidateUserData(ppp_class
, object
, NULL
))
371 PluginGlobals::Get()->plugin_var_tracker()->PluginImplementedObjectDestroyed(
373 CallWhileUnlocked(ToPPPClass(ppp_class
)->Deallocate
, ToUserData(object
));
376 bool PPP_Class_Proxy::ValidateUserData(int64 ppp_class
, int64 class_data
,
377 SerializedVarOutParam
* exception
) {
378 if (!PluginGlobals::Get()->plugin_var_tracker()->ValidatePluginObjectCall(
379 ToPPPClass(ppp_class
), ToUserData(class_data
))) {
380 // Set the exception. This is so the caller will know about the error and
381 // also that we won't assert that somebody forgot to call OutParam on the
382 // output parameter. Although this exception of "1" won't be very useful
383 // this shouldn't happen in normal usage, only when the renderer is being
386 *exception
->OutParam(dispatcher()) = PP_MakeInt32(1);