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/ppb_testing_proxy.h"
7 #include "base/message_loop.h"
8 #include "ppapi/c/dev/ppb_testing_dev.h"
9 #include "ppapi/proxy/enter_proxy.h"
10 #include "ppapi/proxy/plugin_dispatcher.h"
11 #include "ppapi/proxy/ppapi_messages.h"
12 #include "ppapi/shared_impl/ppapi_globals.h"
13 #include "ppapi/shared_impl/proxy_lock.h"
14 #include "ppapi/shared_impl/resource.h"
15 #include "ppapi/shared_impl/resource_tracker.h"
16 #include "ppapi/thunk/enter.h"
17 #include "ppapi/thunk/ppb_graphics_2d_api.h"
18 #include "ppapi/thunk/ppb_input_event_api.h"
20 using ppapi::thunk::EnterInstance
;
21 using ppapi::thunk::EnterResource
;
22 using ppapi::thunk::EnterResourceNoLock
;
23 using ppapi::thunk::PPB_Graphics2D_API
;
24 using ppapi::thunk::PPB_InputEvent_API
;
31 PP_Bool
ReadImageData(PP_Resource graphics_2d
,
33 const PP_Point
* top_left
) {
35 Resource
* image_object
=
36 PpapiGlobals::Get()->GetResourceTracker()->GetResource(image
);
39 Resource
* graphics_2d_object
=
40 PpapiGlobals::Get()->GetResourceTracker()->GetResource(graphics_2d
);
41 if (!graphics_2d_object
||
42 image_object
->pp_instance() != graphics_2d_object
->pp_instance())
45 EnterResourceNoLock
<PPB_Graphics2D_API
> enter(graphics_2d
, true);
48 const HostResource
& host_image
= image_object
->host_resource();
49 return enter
.object()->ReadImageData(host_image
.host_resource(), top_left
) ?
53 void RunMessageLoop(PP_Instance instance
) {
54 MessageLoop::ScopedNestableTaskAllower
allow(MessageLoop::current());
55 CHECK(PpapiGlobals::Get()->GetMainThreadMessageLoop()->
56 BelongsToCurrentThread());
57 MessageLoop::current()->Run();
60 void QuitMessageLoop(PP_Instance instance
) {
61 CHECK(PpapiGlobals::Get()->GetMainThreadMessageLoop()->
62 BelongsToCurrentThread());
63 MessageLoop::current()->QuitNow();
66 uint32_t GetLiveObjectsForInstance(PP_Instance instance_id
) {
68 PluginDispatcher
* dispatcher
= PluginDispatcher::GetForInstance(instance_id
);
70 return static_cast<uint32_t>(-1);
73 dispatcher
->Send(new PpapiHostMsg_PPBTesting_GetLiveObjectsForInstance(
74 API_ID_PPB_TESTING
, instance_id
, &result
));
78 PP_Bool
IsOutOfProcess() {
82 void SimulateInputEvent(PP_Instance instance_id
, PP_Resource input_event
) {
84 PluginDispatcher
* dispatcher
= PluginDispatcher::GetForInstance(instance_id
);
87 EnterResourceNoLock
<PPB_InputEvent_API
> enter(input_event
, false);
91 const InputEventData
& input_event_data
= enter
.object()->GetInputEventData();
92 dispatcher
->Send(new PpapiHostMsg_PPBTesting_SimulateInputEvent(
93 API_ID_PPB_TESTING
, instance_id
, input_event_data
));
96 PP_Var
GetDocumentURL(PP_Instance instance
, PP_URLComponents_Dev
* components
) {
97 EnterInstance
enter(instance
);
99 return PP_MakeUndefined();
100 return enter
.functions()->GetDocumentURL(instance
, components
);
103 // TODO(dmichael): Ideally we could get a way to check the number of vars in the
104 // host-side tracker when running out-of-process, to make sure the proxy does
105 // not leak host-side vars.
106 uint32_t GetLiveVars(PP_Var live_vars
[], uint32_t array_size
) {
108 std::vector
<PP_Var
> vars
=
109 PpapiGlobals::Get()->GetVarTracker()->GetLiveVars();
111 i
< std::min(static_cast<size_t>(array_size
), vars
.size());
113 live_vars
[i
] = vars
[i
];
117 const PPB_Testing_Dev testing_interface
= {
121 &GetLiveObjectsForInstance
,
128 InterfaceProxy
* CreateTestingProxy(Dispatcher
* dispatcher
) {
129 return new PPB_Testing_Proxy(dispatcher
);
134 PPB_Testing_Proxy::PPB_Testing_Proxy(Dispatcher
* dispatcher
)
135 : InterfaceProxy(dispatcher
),
136 ppb_testing_impl_(NULL
) {
137 if (!dispatcher
->IsPlugin()) {
138 ppb_testing_impl_
= static_cast<const PPB_Testing_Dev
*>(
139 dispatcher
->local_get_interface()(PPB_TESTING_DEV_INTERFACE
));
143 PPB_Testing_Proxy::~PPB_Testing_Proxy() {
147 const InterfaceProxy::Info
* PPB_Testing_Proxy::GetInfo() {
148 static const Info info
= {
150 PPB_TESTING_DEV_INTERFACE
,
158 bool PPB_Testing_Proxy::OnMessageReceived(const IPC::Message
& msg
) {
159 if (!dispatcher()->permissions().HasPermission(PERMISSION_TESTING
))
163 IPC_BEGIN_MESSAGE_MAP(PPB_Testing_Proxy
, msg
)
164 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBTesting_ReadImageData
,
166 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBTesting_GetLiveObjectsForInstance
,
167 OnMsgGetLiveObjectsForInstance
)
168 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBTesting_SimulateInputEvent
,
169 OnMsgSimulateInputEvent
)
170 IPC_MESSAGE_UNHANDLED(handled
= false)
171 IPC_END_MESSAGE_MAP()
175 void PPB_Testing_Proxy::OnMsgReadImageData(
176 const HostResource
& device_context_2d
,
177 const HostResource
& image
,
178 const PP_Point
& top_left
,
180 *result
= ppb_testing_impl_
->ReadImageData(
181 device_context_2d
.host_resource(), image
.host_resource(), &top_left
);
184 void PPB_Testing_Proxy::OnMsgRunMessageLoop(PP_Instance instance
) {
185 ppb_testing_impl_
->RunMessageLoop(instance
);
188 void PPB_Testing_Proxy::OnMsgQuitMessageLoop(PP_Instance instance
) {
189 ppb_testing_impl_
->QuitMessageLoop(instance
);
192 void PPB_Testing_Proxy::OnMsgGetLiveObjectsForInstance(PP_Instance instance
,
194 *result
= ppb_testing_impl_
->GetLiveObjectsForInstance(instance
);
197 void PPB_Testing_Proxy::OnMsgSimulateInputEvent(
198 PP_Instance instance
,
199 const InputEventData
& input_event
) {
200 scoped_refptr
<PPB_InputEvent_Shared
> input_event_impl(
201 new PPB_InputEvent_Shared(OBJECT_IS_PROXY
, instance
, input_event
));
202 ppb_testing_impl_
->SimulateInputEvent(instance
,
203 input_event_impl
->pp_resource());