blob: 289a864fad08ead907d543d1ea5b0354ebf77e57 [file] [log] [blame]
[email protected]b697e1a2011-01-06 22:20:281// Copyright (c) 2011 The Chromium Authors. All rights reserved.
[email protected]43a40202010-11-12 16:25:012// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "ppapi/proxy/ppb_flash_proxy.h"
6
7#include "base/logging.h"
[email protected]7358d572011-02-15 18:44:408#include "base/message_loop.h"
[email protected]a1d19d742011-04-19 23:11:009#include "base/time.h"
[email protected]fb35dcf2010-11-14 17:08:0010#include "ppapi/c/dev/ppb_font_dev.h"
[email protected]747ab0d42011-05-03 19:13:4311#include "ppapi/c/dev/ppb_var_deprecated.h"
[email protected]181220ba2011-03-28 18:21:0512#include "ppapi/c/pp_errors.h"
[email protected]43a40202010-11-12 16:25:0113#include "ppapi/c/pp_resource.h"
[email protected]b697e1a2011-01-06 22:20:2814#include "ppapi/c/private/ppb_flash.h"
[email protected]bd65a3da2011-04-08 04:21:3015#include "ppapi/proxy/host_dispatcher.h"
[email protected]43a40202010-11-12 16:25:0116#include "ppapi/proxy/plugin_dispatcher.h"
17#include "ppapi/proxy/plugin_resource.h"
18#include "ppapi/proxy/ppapi_messages.h"
[email protected]747ab0d42011-05-03 19:13:4319#include "ppapi/proxy/proxy_module.h"
[email protected]43a40202010-11-12 16:25:0120#include "ppapi/proxy/serialized_var.h"
[email protected]43a40202010-11-12 16:25:0121
[email protected]be0a84b2011-08-13 04:18:4422using ppapi::HostResource;
23
[email protected]43a40202010-11-12 16:25:0124namespace pp {
25namespace proxy {
26
27namespace {
28
[email protected]4614f192011-01-21 00:26:4329void SetInstanceAlwaysOnTop(PP_Instance pp_instance, PP_Bool on_top) {
30 PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(pp_instance);
31 if (dispatcher) {
32 dispatcher->Send(new PpapiHostMsg_PPBFlash_SetInstanceAlwaysOnTop(
33 INTERFACE_ID_PPB_FLASH, pp_instance, on_top));
34 }
[email protected]43a40202010-11-12 16:25:0135}
36
[email protected]4614f192011-01-21 00:26:4337PP_Bool DrawGlyphs(PP_Instance instance,
38 PP_Resource pp_image_data,
39 const PP_FontDescription_Dev* font_desc,
40 uint32_t color,
41 PP_Point position,
42 PP_Rect clip,
43 const float transformation[3][3],
44 uint32_t glyph_count,
45 const uint16_t glyph_indices[],
46 const PP_Point glyph_advances[]) {
[email protected]f24448db2011-01-27 20:40:3947 PluginResource* image_data = PluginResourceTracker::GetInstance()->
48 GetResourceObject(pp_image_data);
49 if (!image_data)
50 return PP_FALSE;
51 // The instance parameter isn't strictly necessary but we check that it
52 // matches anyway.
53 if (image_data->instance() != instance)
54 return PP_FALSE;
55
56 PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(
57 image_data->instance());
[email protected]4614f192011-01-21 00:26:4358 if (!dispatcher)
59 return PP_FALSE;
[email protected]fb35dcf2010-11-14 17:08:0060
61 PPBFlash_DrawGlyphs_Params params;
[email protected]f24448db2011-01-27 20:40:3962 params.image_data = image_data->host_resource();
[email protected]fb35dcf2010-11-14 17:08:0063 params.font_desc.SetFromPPFontDescription(dispatcher, *font_desc, true);
64 params.color = color;
65 params.position = position;
66 params.clip = clip;
67 for (int i = 0; i < 3; i++) {
68 for (int j = 0; j < 3; j++)
69 params.transformation[i][j] = transformation[i][j];
70 }
71
72 params.glyph_indices.insert(params.glyph_indices.begin(),
73 &glyph_indices[0],
74 &glyph_indices[glyph_count]);
75 params.glyph_advances.insert(params.glyph_advances.begin(),
76 &glyph_advances[0],
77 &glyph_advances[glyph_count]);
78
[email protected]4614f192011-01-21 00:26:4379 PP_Bool result = PP_FALSE;
[email protected]fb35dcf2010-11-14 17:08:0080 dispatcher->Send(new PpapiHostMsg_PPBFlash_DrawGlyphs(
[email protected]99627bcf2010-12-02 23:59:5381 INTERFACE_ID_PPB_FLASH, params, &result));
82 return result;
[email protected]43a40202010-11-12 16:25:0183}
84
[email protected]859a7f32011-01-15 03:44:1385PP_Var GetProxyForURL(PP_Instance instance, const char* url) {
[email protected]4614f192011-01-21 00:26:4386 PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance);
87 if (!dispatcher)
88 return PP_MakeUndefined();
89
[email protected]43a40202010-11-12 16:25:0190 ReceiveSerializedVarReturnValue result;
[email protected]4614f192011-01-21 00:26:4391 dispatcher->Send(new PpapiHostMsg_PPBFlash_GetProxyForURL(
[email protected]859a7f32011-01-15 03:44:1392 INTERFACE_ID_PPB_FLASH, instance, url, &result));
[email protected]4614f192011-01-21 00:26:4393 return result.Return(dispatcher);
[email protected]43a40202010-11-12 16:25:0194}
95
[email protected]181220ba2011-03-28 18:21:0596int32_t Navigate(PP_Resource request_id,
97 const char* target,
98 bool from_user_action) {
99 PluginResource* request_object =
100 PluginResourceTracker::GetInstance()->GetResourceObject(request_id);
101 if (!request_object)
102 return PP_ERROR_BADRESOURCE;
[email protected]4614f192011-01-21 00:26:43103
[email protected]181220ba2011-03-28 18:21:05104 PluginDispatcher* dispatcher =
105 PluginDispatcher::GetForInstance(request_object->instance());
106 if (!dispatcher)
107 return PP_ERROR_FAILED;
108
109 int32_t result = PP_ERROR_FAILED;
110 dispatcher->Send(new PpapiHostMsg_PPBFlash_Navigate(
111 INTERFACE_ID_PPB_FLASH,
112 request_object->host_resource(), target, from_user_action,
113 &result));
[email protected]43a40202010-11-12 16:25:01114 return result;
115}
116
[email protected]7358d572011-02-15 18:44:40117void RunMessageLoop(PP_Instance instance) {
118 PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance);
119 if (!dispatcher)
120 return;
121 IPC::SyncMessage* msg = new PpapiHostMsg_PPBFlash_RunMessageLoop(
[email protected]4d3aec12011-04-21 23:07:45122 INTERFACE_ID_PPB_FLASH, instance);
[email protected]7358d572011-02-15 18:44:40123 msg->EnableMessagePumping();
124 dispatcher->Send(msg);
125}
126
127void QuitMessageLoop(PP_Instance instance) {
128 PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance);
129 if (!dispatcher)
130 return;
131 dispatcher->Send(new PpapiHostMsg_PPBFlash_QuitMessageLoop(
[email protected]4d3aec12011-04-21 23:07:45132 INTERFACE_ID_PPB_FLASH, instance));
[email protected]7358d572011-02-15 18:44:40133}
134
[email protected]4d3aec12011-04-21 23:07:45135double GetLocalTimeZoneOffset(PP_Instance instance, PP_Time t) {
136 PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance);
137 if (!dispatcher)
138 return 0.0;
139
140 // TODO(brettw) on Windows it should be possible to do the time calculation
141 // in-process since it doesn't need to read files on disk. This will improve
142 // performance.
[email protected]a1d19d742011-04-19 23:11:00143 //
[email protected]4d3aec12011-04-21 23:07:45144 // On Linux, it would be better to go directly to the browser process for
145 // this message rather than proxy it through some instance in a renderer.
146 double result = 0;
147 dispatcher->Send(new PpapiHostMsg_PPBFlash_GetLocalTimeZoneOffset(
148 INTERFACE_ID_PPB_FLASH, instance, t, &result));
149 return result;
[email protected]a1d19d742011-04-19 23:11:00150}
151
[email protected]747ab0d42011-05-03 19:13:43152PP_Var GetCommandLineArgs(PP_Module pp_module) {
153 const PPB_Var_Deprecated* var_deprecated =
154 static_cast<const PPB_Var_Deprecated*>(
155 PluginDispatcher::GetInterfaceFromDispatcher(
156 PPB_VAR_DEPRECATED_INTERFACE));
157 std::string args =
158 pp::proxy::ProxyModule::GetInstance()->GetFlashCommandLineArgs();
159 return var_deprecated->VarFromUtf8(pp_module, args.data(), args.length());
160}
161
[email protected]465faa22011-02-08 16:31:46162const PPB_Flash flash_interface = {
[email protected]43a40202010-11-12 16:25:01163 &SetInstanceAlwaysOnTop,
164 &DrawGlyphs,
165 &GetProxyForURL,
[email protected]181220ba2011-03-28 18:21:05166 &Navigate,
[email protected]7358d572011-02-15 18:44:40167 &RunMessageLoop,
168 &QuitMessageLoop,
[email protected]747ab0d42011-05-03 19:13:43169 &GetLocalTimeZoneOffset,
170 &GetCommandLineArgs
[email protected]43a40202010-11-12 16:25:01171};
172
[email protected]465faa22011-02-08 16:31:46173InterfaceProxy* CreateFlashProxy(Dispatcher* dispatcher,
174 const void* target_interface) {
175 return new PPB_Flash_Proxy(dispatcher, target_interface);
176}
177
[email protected]43a40202010-11-12 16:25:01178} // namespace
179
180PPB_Flash_Proxy::PPB_Flash_Proxy(Dispatcher* dispatcher,
[email protected]4614f192011-01-21 00:26:43181 const void* target_interface)
[email protected]43a40202010-11-12 16:25:01182 : InterfaceProxy(dispatcher, target_interface) {
183}
184
185PPB_Flash_Proxy::~PPB_Flash_Proxy() {
186}
187
[email protected]465faa22011-02-08 16:31:46188// static
189const InterfaceProxy::Info* PPB_Flash_Proxy::GetInfo() {
190 static const Info info = {
191 &flash_interface,
192 PPB_FLASH_INTERFACE,
193 INTERFACE_ID_PPB_FLASH,
194 true,
195 &CreateFlashProxy,
196 };
197 return &info;
[email protected]43a40202010-11-12 16:25:01198}
199
[email protected]a95986a82010-12-24 06:19:28200bool PPB_Flash_Proxy::OnMessageReceived(const IPC::Message& msg) {
[email protected]96fe50e32011-05-10 03:47:58201 // Prevent the dispatcher from going away during a call to Navigate.
202 // This must happen OUTSIDE of OnMsgNavigate since the handling code use
203 // the dispatcher upon return of the function (sending the reply message).
204 ScopedModuleReference death_grip(dispatcher());
205
[email protected]a95986a82010-12-24 06:19:28206 bool handled = true;
[email protected]43a40202010-11-12 16:25:01207 IPC_BEGIN_MESSAGE_MAP(PPB_Flash_Proxy, msg)
208 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFlash_SetInstanceAlwaysOnTop,
209 OnMsgSetInstanceAlwaysOnTop)
210 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFlash_DrawGlyphs,
211 OnMsgDrawGlyphs)
212 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFlash_GetProxyForURL,
213 OnMsgGetProxyForURL)
[email protected]181220ba2011-03-28 18:21:05214 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFlash_Navigate, OnMsgNavigate)
[email protected]7358d572011-02-15 18:44:40215 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFlash_RunMessageLoop,
216 OnMsgRunMessageLoop)
217 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFlash_QuitMessageLoop,
218 OnMsgQuitMessageLoop)
[email protected]83216ff2011-04-22 15:33:40219 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFlash_GetLocalTimeZoneOffset,
220 OnMsgGetLocalTimeZoneOffset)
[email protected]a95986a82010-12-24 06:19:28221 IPC_MESSAGE_UNHANDLED(handled = false)
[email protected]43a40202010-11-12 16:25:01222 IPC_END_MESSAGE_MAP()
223 // TODO(brettw) handle bad messages!
[email protected]a95986a82010-12-24 06:19:28224 return handled;
[email protected]43a40202010-11-12 16:25:01225}
226
227void PPB_Flash_Proxy::OnMsgSetInstanceAlwaysOnTop(
228 PP_Instance instance,
[email protected]4614f192011-01-21 00:26:43229 PP_Bool on_top) {
[email protected]43a40202010-11-12 16:25:01230 ppb_flash_target()->SetInstanceAlwaysOnTop(instance, on_top);
231}
232
233void PPB_Flash_Proxy::OnMsgDrawGlyphs(
[email protected]99627bcf2010-12-02 23:59:53234 const pp::proxy::PPBFlash_DrawGlyphs_Params& params,
[email protected]4614f192011-01-21 00:26:43235 PP_Bool* result) {
236 *result = PP_FALSE;
[email protected]99627bcf2010-12-02 23:59:53237
[email protected]fb35dcf2010-11-14 17:08:00238 PP_FontDescription_Dev font_desc;
239 params.font_desc.SetToPPFontDescription(dispatcher(), &font_desc, false);
240
241 if (params.glyph_indices.size() != params.glyph_advances.size() ||
242 params.glyph_indices.empty())
243 return;
244
[email protected]99627bcf2010-12-02 23:59:53245 *result = ppb_flash_target()->DrawGlyphs(
[email protected]f24448db2011-01-27 20:40:39246 0, // Unused instance param.
247 params.image_data.host_resource(), &font_desc,
248 params.color, params.position, params.clip,
[email protected]fb35dcf2010-11-14 17:08:00249 const_cast<float(*)[3]>(params.transformation),
250 static_cast<uint32_t>(params.glyph_indices.size()),
251 const_cast<uint16_t*>(&params.glyph_indices[0]),
252 const_cast<PP_Point*>(&params.glyph_advances[0]));
[email protected]43a40202010-11-12 16:25:01253}
254
[email protected]859a7f32011-01-15 03:44:13255void PPB_Flash_Proxy::OnMsgGetProxyForURL(PP_Instance instance,
[email protected]43a40202010-11-12 16:25:01256 const std::string& url,
257 SerializedVarReturnValue result) {
258 result.Return(dispatcher(), ppb_flash_target()->GetProxyForURL(
[email protected]859a7f32011-01-15 03:44:13259 instance, url.c_str()));
[email protected]43a40202010-11-12 16:25:01260}
261
[email protected]181220ba2011-03-28 18:21:05262void PPB_Flash_Proxy::OnMsgNavigate(const HostResource& request_info,
263 const std::string& target,
264 bool from_user_action,
265 int32_t* result) {
[email protected]bd65a3da2011-04-08 04:21:30266 DCHECK(!dispatcher()->IsPlugin());
267 // We need to allow re-entrancy here, because this may call into Javascript
268 // (e.g. with a "javascript:" URL), or do things like navigate away from the
269 // page, either one of which will need to re-enter into the plugin.
270 // It is safe, because it is essentially equivalent to NPN_GetURL, where Flash
271 // would expect re-entrancy. When running in-process, it does re-enter here.
272 static_cast<HostDispatcher*>(dispatcher())->set_allow_plugin_reentrancy();
[email protected]181220ba2011-03-28 18:21:05273 *result = ppb_flash_target()->Navigate(request_info.host_resource(),
274 target.c_str(),
275 from_user_action);
[email protected]43a40202010-11-12 16:25:01276}
277
[email protected]7358d572011-02-15 18:44:40278void PPB_Flash_Proxy::OnMsgRunMessageLoop(PP_Instance instance) {
279 ppb_flash_target()->RunMessageLoop(instance);
280}
281
282void PPB_Flash_Proxy::OnMsgQuitMessageLoop(PP_Instance instance) {
283 ppb_flash_target()->QuitMessageLoop(instance);
284}
285
[email protected]4d3aec12011-04-21 23:07:45286void PPB_Flash_Proxy::OnMsgGetLocalTimeZoneOffset(PP_Instance instance,
287 PP_Time t,
288 double* result) {
289 *result = ppb_flash_target()->GetLocalTimeZoneOffset(instance, t);
290}
291
[email protected]43a40202010-11-12 16:25:01292} // namespace proxy
293} // namespace pp