Refactor android test results logging.
[chromium-blink-merge.git] / ppapi / proxy / ppp_instance_proxy.cc
blob077366e47c740d613acefbb71825f4884de7b19e
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_instance_proxy.h"
7 #include <algorithm>
9 #include "base/bind.h"
10 #include "ppapi/c/pp_var.h"
11 #include "ppapi/c/ppb_core.h"
12 #include "ppapi/c/ppb_fullscreen.h"
13 #include "ppapi/c/ppp_instance.h"
14 #include "ppapi/proxy/host_dispatcher.h"
15 #include "ppapi/proxy/plugin_dispatcher.h"
16 #include "ppapi/proxy/plugin_resource_tracker.h"
17 #include "ppapi/proxy/ppapi_messages.h"
18 #include "ppapi/proxy/ppb_url_loader_proxy.h"
19 #include "ppapi/shared_impl/ppapi_globals.h"
20 #include "ppapi/shared_impl/ppb_view_shared.h"
21 #include "ppapi/shared_impl/scoped_pp_resource.h"
22 #include "ppapi/thunk/enter.h"
23 #include "ppapi/thunk/ppb_flash_fullscreen_api.h"
24 #include "ppapi/thunk/ppb_view_api.h"
26 namespace ppapi {
27 namespace proxy {
29 using thunk::EnterInstanceAPINoLock;
30 using thunk::EnterInstanceNoLock;
31 using thunk::EnterResourceNoLock;
32 using thunk::PPB_Flash_Fullscreen_API;
33 using thunk::PPB_Instance_API;
34 using thunk::PPB_View_API;
36 namespace {
38 #if !defined(OS_NACL)
39 PP_Bool DidCreate(PP_Instance instance,
40 uint32_t argc,
41 const char* argn[],
42 const char* argv[]) {
43 std::vector<std::string> argn_vect;
44 std::vector<std::string> argv_vect;
45 for (uint32_t i = 0; i < argc; i++) {
46 argn_vect.push_back(std::string(argn[i]));
47 argv_vect.push_back(std::string(argv[i]));
50 PP_Bool result = PP_FALSE;
51 HostDispatcher::GetForInstance(instance)->Send(
52 new PpapiMsg_PPPInstance_DidCreate(API_ID_PPP_INSTANCE, instance,
53 argn_vect, argv_vect, &result));
54 return result;
57 void DidDestroy(PP_Instance instance) {
58 HostDispatcher::GetForInstance(instance)->Send(
59 new PpapiMsg_PPPInstance_DidDestroy(API_ID_PPP_INSTANCE, instance));
62 void DidChangeView(PP_Instance instance, PP_Resource view_resource) {
63 HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance);
65 EnterResourceNoLock<PPB_View_API> enter_view(view_resource, false);
66 if (enter_view.failed()) {
67 NOTREACHED();
68 return;
71 PP_Bool flash_fullscreen = PP_FALSE;
72 EnterInstanceNoLock enter_instance(instance);
73 if (!enter_instance.failed())
74 flash_fullscreen = enter_instance.functions()->FlashIsFullscreen(instance);
75 dispatcher->Send(new PpapiMsg_PPPInstance_DidChangeView(
76 API_ID_PPP_INSTANCE, instance, enter_view.object()->GetData(),
77 flash_fullscreen));
80 void DidChangeFocus(PP_Instance instance, PP_Bool has_focus) {
81 HostDispatcher::GetForInstance(instance)->Send(
82 new PpapiMsg_PPPInstance_DidChangeFocus(API_ID_PPP_INSTANCE,
83 instance, has_focus));
86 PP_Bool HandleDocumentLoad(PP_Instance instance,
87 PP_Resource url_loader) {
88 PP_Bool result = PP_FALSE;
89 HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance);
91 // Set up the URLLoader for proxying.
93 PPB_URLLoader_Proxy* url_loader_proxy = static_cast<PPB_URLLoader_Proxy*>(
94 dispatcher->GetInterfaceProxy(API_ID_PPB_URL_LOADER));
95 url_loader_proxy->PrepareURLLoaderForSendingToPlugin(url_loader);
97 // PluginResourceTracker in the plugin process assumes that resources that it
98 // tracks have been addrefed on behalf of the plugin at the renderer side. So
99 // we explicitly do it for |url_loader| here.
101 // Please also see comments in PPP_Instance_Proxy::OnMsgHandleDocumentLoad()
102 // about releasing of this extra reference.
103 const PPB_Core* core = reinterpret_cast<const PPB_Core*>(
104 dispatcher->local_get_interface()(PPB_CORE_INTERFACE));
105 if (!core) {
106 NOTREACHED();
107 return PP_FALSE;
109 core->AddRefResource(url_loader);
111 HostResource serialized_loader;
112 serialized_loader.SetHostResource(instance, url_loader);
113 dispatcher->Send(new PpapiMsg_PPPInstance_HandleDocumentLoad(
114 API_ID_PPP_INSTANCE, instance, serialized_loader, &result));
115 return result;
118 static const PPP_Instance_1_1 instance_interface = {
119 &DidCreate,
120 &DidDestroy,
121 &DidChangeView,
122 &DidChangeFocus,
123 &HandleDocumentLoad
125 #endif // !defined(OS_NACL)
127 } // namespace
129 PPP_Instance_Proxy::PPP_Instance_Proxy(Dispatcher* dispatcher)
130 : InterfaceProxy(dispatcher) {
131 if (dispatcher->IsPlugin()) {
132 // The PPP_Instance proxy works by always proxying the 1.1 version of the
133 // interface, and then detecting in the plugin process which one to use.
134 // PPP_Instance_Combined handles dispatching to whatever interface is
135 // supported.
137 // This means that if the plugin supports either 1.0 or 1.1 version of
138 // the interface, we want to say it supports the 1.1 version since we'll
139 // convert it here. This magic conversion code is hardcoded into
140 // PluginDispatcher::OnMsgSupportsInterface.
141 combined_interface_.reset(PPP_Instance_Combined::Create(
142 base::Bind(dispatcher->local_get_interface())));
146 PPP_Instance_Proxy::~PPP_Instance_Proxy() {
149 #if !defined(OS_NACL)
150 // static
151 const PPP_Instance* PPP_Instance_Proxy::GetInstanceInterface() {
152 return &instance_interface;
154 #endif // !defined(OS_NACL)
156 bool PPP_Instance_Proxy::OnMessageReceived(const IPC::Message& msg) {
157 bool handled = true;
158 IPC_BEGIN_MESSAGE_MAP(PPP_Instance_Proxy, msg)
159 IPC_MESSAGE_HANDLER(PpapiMsg_PPPInstance_DidCreate,
160 OnPluginMsgDidCreate)
161 IPC_MESSAGE_HANDLER(PpapiMsg_PPPInstance_DidDestroy,
162 OnPluginMsgDidDestroy)
163 IPC_MESSAGE_HANDLER(PpapiMsg_PPPInstance_DidChangeView,
164 OnPluginMsgDidChangeView)
165 IPC_MESSAGE_HANDLER(PpapiMsg_PPPInstance_DidChangeFocus,
166 OnPluginMsgDidChangeFocus)
167 IPC_MESSAGE_HANDLER(PpapiMsg_PPPInstance_HandleDocumentLoad,
168 OnPluginMsgHandleDocumentLoad)
169 IPC_MESSAGE_UNHANDLED(handled = false)
170 IPC_END_MESSAGE_MAP()
171 return handled;
174 void PPP_Instance_Proxy::OnPluginMsgDidCreate(
175 PP_Instance instance,
176 const std::vector<std::string>& argn,
177 const std::vector<std::string>& argv,
178 PP_Bool* result) {
179 *result = PP_FALSE;
180 if (argn.size() != argv.size())
181 return;
183 // Set up the routing associating this new instance with the dispatcher we
184 // just got the message from. This must be done before calling into the
185 // plugin so it can in turn call PPAPI functions.
186 PluginDispatcher* plugin_dispatcher =
187 static_cast<PluginDispatcher*>(dispatcher());
188 plugin_dispatcher->DidCreateInstance(instance);
189 PpapiGlobals::Get()->GetResourceTracker()->DidCreateInstance(instance);
191 // Make sure the arrays always have at least one element so we can take the
192 // address below.
193 std::vector<const char*> argn_array(
194 std::max(static_cast<size_t>(1), argn.size()));
195 std::vector<const char*> argv_array(
196 std::max(static_cast<size_t>(1), argn.size()));
197 for (size_t i = 0; i < argn.size(); i++) {
198 argn_array[i] = argn[i].c_str();
199 argv_array[i] = argv[i].c_str();
202 DCHECK(combined_interface_.get());
203 *result = combined_interface_->DidCreate(instance,
204 static_cast<uint32_t>(argn.size()),
205 &argn_array[0], &argv_array[0]);
208 void PPP_Instance_Proxy::OnPluginMsgDidDestroy(PP_Instance instance) {
209 combined_interface_->DidDestroy(instance);
211 PpapiGlobals* globals = PpapiGlobals::Get();
212 globals->GetResourceTracker()->DidDeleteInstance(instance);
213 globals->GetVarTracker()->DidDeleteInstance(instance);
215 static_cast<PluginDispatcher*>(dispatcher())->DidDestroyInstance(instance);
218 void PPP_Instance_Proxy::OnPluginMsgDidChangeView(
219 PP_Instance instance,
220 const ViewData& new_data,
221 PP_Bool flash_fullscreen) {
222 PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance);
223 if (!dispatcher)
224 return;
225 InstanceData* data = dispatcher->GetInstanceData(instance);
226 if (!data)
227 return;
228 data->view = new_data;
230 #if !defined(OS_NACL)
231 EnterInstanceAPINoLock<PPB_Flash_Fullscreen_API> enter(instance);
232 if (!enter.failed())
233 enter.functions()->SetLocalIsFullscreen(instance, flash_fullscreen);
234 #endif // !defined(OS_NACL)
236 ScopedPPResource resource(
237 ScopedPPResource::PassRef(),
238 (new PPB_View_Shared(OBJECT_IS_PROXY,
239 instance, new_data))->GetReference());
241 combined_interface_->DidChangeView(instance, resource,
242 &new_data.rect,
243 &new_data.clip_rect);
246 void PPP_Instance_Proxy::OnPluginMsgDidChangeFocus(PP_Instance instance,
247 PP_Bool has_focus) {
248 combined_interface_->DidChangeFocus(instance, has_focus);
251 void PPP_Instance_Proxy::OnPluginMsgHandleDocumentLoad(
252 PP_Instance instance,
253 const HostResource& url_loader,
254 PP_Bool* result) {
255 PP_Resource plugin_loader =
256 PPB_URLLoader_Proxy::TrackPluginResource(url_loader);
257 *result = combined_interface_->HandleDocumentLoad(instance, plugin_loader);
259 // This balances the one reference that TrackPluginResource() initialized it
260 // with. The plugin will normally take an additional reference which will keep
261 // the resource alive in the plugin (and the one reference in the renderer
262 // representing all plugin references).
263 // Once all references at the plugin side are released, the renderer side will
264 // be notified and release the reference added in HandleDocumentLoad() above.
265 PpapiGlobals::Get()->GetResourceTracker()->ReleaseResource(plugin_loader);
268 } // namespace proxy
269 } // namespace ppapi