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/message_loop.h"
8 #include "ppapi/c/private/ppb_testing_private.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 base::MessageLoop::ScopedNestableTaskAllower
allow(
55 base::MessageLoop::current());
56 CHECK(PpapiGlobals::Get()->GetMainThreadMessageLoop()->
57 BelongsToCurrentThread());
58 base::MessageLoop::current()->Run();
61 void QuitMessageLoop(PP_Instance instance
) {
62 CHECK(PpapiGlobals::Get()->GetMainThreadMessageLoop()->
63 BelongsToCurrentThread());
64 base::MessageLoop::current()->QuitNow();
67 uint32_t GetLiveObjectsForInstance(PP_Instance instance_id
) {
69 PluginDispatcher
* dispatcher
= PluginDispatcher::GetForInstance(instance_id
);
71 return static_cast<uint32_t>(-1);
74 dispatcher
->Send(new PpapiHostMsg_PPBTesting_GetLiveObjectsForInstance(
75 API_ID_PPB_TESTING
, instance_id
, &result
));
79 PP_Bool
IsOutOfProcess() {
83 void PostPowerSaverStatus(PP_Instance instance_id
) {
85 PluginDispatcher
* dispatcher
= PluginDispatcher::GetForInstance(instance_id
);
89 dispatcher
->Send(new PpapiHostMsg_PPBTesting_PostPowerSaverStatus(
90 API_ID_PPB_TESTING
, instance_id
));
93 void SubscribeToPowerSaverNotifications(PP_Instance instance_id
) {
95 PluginDispatcher
* dispatcher
= PluginDispatcher::GetForInstance(instance_id
);
100 new PpapiHostMsg_PPBTesting_SubscribeToPowerSaverNotifications(
101 API_ID_PPB_TESTING
, instance_id
));
104 void SimulateInputEvent(PP_Instance instance_id
, PP_Resource input_event
) {
106 PluginDispatcher
* dispatcher
= PluginDispatcher::GetForInstance(instance_id
);
109 EnterResourceNoLock
<PPB_InputEvent_API
> enter(input_event
, false);
113 const InputEventData
& input_event_data
= enter
.object()->GetInputEventData();
114 dispatcher
->Send(new PpapiHostMsg_PPBTesting_SimulateInputEvent(
115 API_ID_PPB_TESTING
, instance_id
, input_event_data
));
118 PP_Var
GetDocumentURL(PP_Instance instance
, PP_URLComponents_Dev
* components
) {
119 EnterInstance
enter(instance
);
121 return PP_MakeUndefined();
122 return enter
.functions()->GetDocumentURL(instance
, components
);
125 // TODO(dmichael): Ideally we could get a way to check the number of vars in the
126 // host-side tracker when running out-of-process, to make sure the proxy does
127 // not leak host-side vars.
128 uint32_t GetLiveVars(PP_Var live_vars
[], uint32_t array_size
) {
130 std::vector
<PP_Var
> vars
=
131 PpapiGlobals::Get()->GetVarTracker()->GetLiveVars();
133 i
< std::min(static_cast<size_t>(array_size
), vars
.size());
135 live_vars
[i
] = vars
[i
];
136 return static_cast<uint32_t>(vars
.size());
139 void SetMinimumArrayBufferSizeForShmem(PP_Instance instance
,
140 uint32_t threshold
) {
142 RawVarDataGraph::SetMinimumArrayBufferSizeForShmemForTest(threshold
);
143 PluginDispatcher
* dispatcher
= PluginDispatcher::GetForInstance(instance
);
147 new PpapiHostMsg_PPBTesting_SetMinimumArrayBufferSizeForShmem(
148 API_ID_PPB_TESTING
, threshold
));
151 void RunV8GC(PP_Instance instance
) {
152 // TODO(raymes): Implement this if we need it.
156 const PPB_Testing_Private testing_interface
= {
160 &GetLiveObjectsForInstance
,
162 &PostPowerSaverStatus
,
163 &SubscribeToPowerSaverNotifications
,
167 &SetMinimumArrayBufferSizeForShmem
,
172 PPB_Testing_Proxy::PPB_Testing_Proxy(Dispatcher
* dispatcher
)
173 : InterfaceProxy(dispatcher
),
174 ppb_testing_impl_(NULL
) {
175 if (!dispatcher
->IsPlugin()) {
176 ppb_testing_impl_
= static_cast<const PPB_Testing_Private
*>(
177 dispatcher
->local_get_interface()(PPB_TESTING_PRIVATE_INTERFACE
));
181 PPB_Testing_Proxy::~PPB_Testing_Proxy() {
185 const PPB_Testing_Private
* PPB_Testing_Proxy::GetProxyInterface() {
186 return &testing_interface
;
189 bool PPB_Testing_Proxy::OnMessageReceived(const IPC::Message
& msg
) {
190 if (!dispatcher()->permissions().HasPermission(PERMISSION_TESTING
))
194 IPC_BEGIN_MESSAGE_MAP(PPB_Testing_Proxy
, msg
)
195 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBTesting_ReadImageData
,
197 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBTesting_GetLiveObjectsForInstance
,
198 OnMsgGetLiveObjectsForInstance
)
199 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBTesting_PostPowerSaverStatus
,
200 OnMsgPostPowerSaverStatus
)
202 PpapiHostMsg_PPBTesting_SubscribeToPowerSaverNotifications
,
203 OnMsgSubscribeToPowerSaverNotifications
)
204 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBTesting_SimulateInputEvent
,
205 OnMsgSimulateInputEvent
)
207 PpapiHostMsg_PPBTesting_SetMinimumArrayBufferSizeForShmem
,
208 OnMsgSetMinimumArrayBufferSizeForShmem
)
209 IPC_MESSAGE_UNHANDLED(handled
= false)
210 IPC_END_MESSAGE_MAP()
214 void PPB_Testing_Proxy::OnMsgReadImageData(
215 const HostResource
& device_context_2d
,
216 const HostResource
& image
,
217 const PP_Point
& top_left
,
219 *result
= ppb_testing_impl_
->ReadImageData(
220 device_context_2d
.host_resource(), image
.host_resource(), &top_left
);
223 void PPB_Testing_Proxy::OnMsgRunMessageLoop(PP_Instance instance
) {
224 ppb_testing_impl_
->RunMessageLoop(instance
);
227 void PPB_Testing_Proxy::OnMsgQuitMessageLoop(PP_Instance instance
) {
228 ppb_testing_impl_
->QuitMessageLoop(instance
);
231 void PPB_Testing_Proxy::OnMsgGetLiveObjectsForInstance(PP_Instance instance
,
233 *result
= ppb_testing_impl_
->GetLiveObjectsForInstance(instance
);
236 void PPB_Testing_Proxy::OnMsgPostPowerSaverStatus(PP_Instance instance
) {
237 ppb_testing_impl_
->PostPowerSaverStatus(instance
);
240 void PPB_Testing_Proxy::OnMsgSubscribeToPowerSaverNotifications(
241 PP_Instance instance
) {
242 ppb_testing_impl_
->SubscribeToPowerSaverNotifications(instance
);
245 void PPB_Testing_Proxy::OnMsgSimulateInputEvent(
246 PP_Instance instance
,
247 const InputEventData
& input_event
) {
248 scoped_refptr
<PPB_InputEvent_Shared
> input_event_impl(
249 new PPB_InputEvent_Shared(OBJECT_IS_PROXY
, instance
, input_event
));
250 ppb_testing_impl_
->SimulateInputEvent(instance
,
251 input_event_impl
->pp_resource());
254 void PPB_Testing_Proxy::OnMsgSetMinimumArrayBufferSizeForShmem(
255 uint32_t threshold
) {
256 RawVarDataGraph::SetMinimumArrayBufferSizeForShmemForTest(threshold
);