[email protected] | b697e1a | 2011-01-06 22:20:28 | [diff] [blame] | 1 | // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
[email protected] | 43a4020 | 2010-11-12 16:25:01 | [diff] [blame] | 2 | // 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] | 7358d57 | 2011-02-15 18:44:40 | [diff] [blame] | 8 | #include "base/message_loop.h" |
[email protected] | a1d19d74 | 2011-04-19 23:11:00 | [diff] [blame] | 9 | #include "base/time.h" |
[email protected] | fb35dcf | 2010-11-14 17:08:00 | [diff] [blame] | 10 | #include "ppapi/c/dev/ppb_font_dev.h" |
[email protected] | 747ab0d4 | 2011-05-03 19:13:43 | [diff] [blame] | 11 | #include "ppapi/c/dev/ppb_var_deprecated.h" |
[email protected] | 181220ba | 2011-03-28 18:21:05 | [diff] [blame] | 12 | #include "ppapi/c/pp_errors.h" |
[email protected] | 43a4020 | 2010-11-12 16:25:01 | [diff] [blame] | 13 | #include "ppapi/c/pp_resource.h" |
[email protected] | b697e1a | 2011-01-06 22:20:28 | [diff] [blame] | 14 | #include "ppapi/c/private/ppb_flash.h" |
[email protected] | bd65a3da | 2011-04-08 04:21:30 | [diff] [blame] | 15 | #include "ppapi/proxy/host_dispatcher.h" |
[email protected] | 43a4020 | 2010-11-12 16:25:01 | [diff] [blame] | 16 | #include "ppapi/proxy/plugin_dispatcher.h" |
| 17 | #include "ppapi/proxy/plugin_resource.h" |
| 18 | #include "ppapi/proxy/ppapi_messages.h" |
[email protected] | 747ab0d4 | 2011-05-03 19:13:43 | [diff] [blame] | 19 | #include "ppapi/proxy/proxy_module.h" |
[email protected] | 43a4020 | 2010-11-12 16:25:01 | [diff] [blame] | 20 | #include "ppapi/proxy/serialized_var.h" |
[email protected] | 43a4020 | 2010-11-12 16:25:01 | [diff] [blame] | 21 | |
[email protected] | be0a84b | 2011-08-13 04:18:44 | [diff] [blame] | 22 | using ppapi::HostResource; |
| 23 | |
[email protected] | 43a4020 | 2010-11-12 16:25:01 | [diff] [blame] | 24 | namespace pp { |
| 25 | namespace proxy { |
| 26 | |
| 27 | namespace { |
| 28 | |
[email protected] | 4614f19 | 2011-01-21 00:26:43 | [diff] [blame] | 29 | void 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] | 43a4020 | 2010-11-12 16:25:01 | [diff] [blame] | 35 | } |
| 36 | |
[email protected] | 4614f19 | 2011-01-21 00:26:43 | [diff] [blame] | 37 | PP_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] | f24448db | 2011-01-27 20:40:39 | [diff] [blame] | 47 | 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] | 4614f19 | 2011-01-21 00:26:43 | [diff] [blame] | 58 | if (!dispatcher) |
| 59 | return PP_FALSE; |
[email protected] | fb35dcf | 2010-11-14 17:08:00 | [diff] [blame] | 60 | |
| 61 | PPBFlash_DrawGlyphs_Params params; |
[email protected] | f24448db | 2011-01-27 20:40:39 | [diff] [blame] | 62 | params.image_data = image_data->host_resource(); |
[email protected] | fb35dcf | 2010-11-14 17:08:00 | [diff] [blame] | 63 | 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] | 4614f19 | 2011-01-21 00:26:43 | [diff] [blame] | 79 | PP_Bool result = PP_FALSE; |
[email protected] | fb35dcf | 2010-11-14 17:08:00 | [diff] [blame] | 80 | dispatcher->Send(new PpapiHostMsg_PPBFlash_DrawGlyphs( |
[email protected] | 99627bcf | 2010-12-02 23:59:53 | [diff] [blame] | 81 | INTERFACE_ID_PPB_FLASH, params, &result)); |
| 82 | return result; |
[email protected] | 43a4020 | 2010-11-12 16:25:01 | [diff] [blame] | 83 | } |
| 84 | |
[email protected] | 859a7f3 | 2011-01-15 03:44:13 | [diff] [blame] | 85 | PP_Var GetProxyForURL(PP_Instance instance, const char* url) { |
[email protected] | 4614f19 | 2011-01-21 00:26:43 | [diff] [blame] | 86 | PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance); |
| 87 | if (!dispatcher) |
| 88 | return PP_MakeUndefined(); |
| 89 | |
[email protected] | 43a4020 | 2010-11-12 16:25:01 | [diff] [blame] | 90 | ReceiveSerializedVarReturnValue result; |
[email protected] | 4614f19 | 2011-01-21 00:26:43 | [diff] [blame] | 91 | dispatcher->Send(new PpapiHostMsg_PPBFlash_GetProxyForURL( |
[email protected] | 859a7f3 | 2011-01-15 03:44:13 | [diff] [blame] | 92 | INTERFACE_ID_PPB_FLASH, instance, url, &result)); |
[email protected] | 4614f19 | 2011-01-21 00:26:43 | [diff] [blame] | 93 | return result.Return(dispatcher); |
[email protected] | 43a4020 | 2010-11-12 16:25:01 | [diff] [blame] | 94 | } |
| 95 | |
[email protected] | 181220ba | 2011-03-28 18:21:05 | [diff] [blame] | 96 | int32_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] | 4614f19 | 2011-01-21 00:26:43 | [diff] [blame] | 103 | |
[email protected] | 181220ba | 2011-03-28 18:21:05 | [diff] [blame] | 104 | 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] | 43a4020 | 2010-11-12 16:25:01 | [diff] [blame] | 114 | return result; |
| 115 | } |
| 116 | |
[email protected] | 7358d57 | 2011-02-15 18:44:40 | [diff] [blame] | 117 | void 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] | 4d3aec1 | 2011-04-21 23:07:45 | [diff] [blame] | 122 | INTERFACE_ID_PPB_FLASH, instance); |
[email protected] | 7358d57 | 2011-02-15 18:44:40 | [diff] [blame] | 123 | msg->EnableMessagePumping(); |
| 124 | dispatcher->Send(msg); |
| 125 | } |
| 126 | |
| 127 | void QuitMessageLoop(PP_Instance instance) { |
| 128 | PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance); |
| 129 | if (!dispatcher) |
| 130 | return; |
| 131 | dispatcher->Send(new PpapiHostMsg_PPBFlash_QuitMessageLoop( |
[email protected] | 4d3aec1 | 2011-04-21 23:07:45 | [diff] [blame] | 132 | INTERFACE_ID_PPB_FLASH, instance)); |
[email protected] | 7358d57 | 2011-02-15 18:44:40 | [diff] [blame] | 133 | } |
| 134 | |
[email protected] | 4d3aec1 | 2011-04-21 23:07:45 | [diff] [blame] | 135 | double 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] | a1d19d74 | 2011-04-19 23:11:00 | [diff] [blame] | 143 | // |
[email protected] | 4d3aec1 | 2011-04-21 23:07:45 | [diff] [blame] | 144 | // 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] | a1d19d74 | 2011-04-19 23:11:00 | [diff] [blame] | 150 | } |
| 151 | |
[email protected] | 747ab0d4 | 2011-05-03 19:13:43 | [diff] [blame] | 152 | PP_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] | 465faa2 | 2011-02-08 16:31:46 | [diff] [blame] | 162 | const PPB_Flash flash_interface = { |
[email protected] | 43a4020 | 2010-11-12 16:25:01 | [diff] [blame] | 163 | &SetInstanceAlwaysOnTop, |
| 164 | &DrawGlyphs, |
| 165 | &GetProxyForURL, |
[email protected] | 181220ba | 2011-03-28 18:21:05 | [diff] [blame] | 166 | &Navigate, |
[email protected] | 7358d57 | 2011-02-15 18:44:40 | [diff] [blame] | 167 | &RunMessageLoop, |
| 168 | &QuitMessageLoop, |
[email protected] | 747ab0d4 | 2011-05-03 19:13:43 | [diff] [blame] | 169 | &GetLocalTimeZoneOffset, |
| 170 | &GetCommandLineArgs |
[email protected] | 43a4020 | 2010-11-12 16:25:01 | [diff] [blame] | 171 | }; |
| 172 | |
[email protected] | 465faa2 | 2011-02-08 16:31:46 | [diff] [blame] | 173 | InterfaceProxy* CreateFlashProxy(Dispatcher* dispatcher, |
| 174 | const void* target_interface) { |
| 175 | return new PPB_Flash_Proxy(dispatcher, target_interface); |
| 176 | } |
| 177 | |
[email protected] | 43a4020 | 2010-11-12 16:25:01 | [diff] [blame] | 178 | } // namespace |
| 179 | |
| 180 | PPB_Flash_Proxy::PPB_Flash_Proxy(Dispatcher* dispatcher, |
[email protected] | 4614f19 | 2011-01-21 00:26:43 | [diff] [blame] | 181 | const void* target_interface) |
[email protected] | 43a4020 | 2010-11-12 16:25:01 | [diff] [blame] | 182 | : InterfaceProxy(dispatcher, target_interface) { |
| 183 | } |
| 184 | |
| 185 | PPB_Flash_Proxy::~PPB_Flash_Proxy() { |
| 186 | } |
| 187 | |
[email protected] | 465faa2 | 2011-02-08 16:31:46 | [diff] [blame] | 188 | // static |
| 189 | const 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] | 43a4020 | 2010-11-12 16:25:01 | [diff] [blame] | 198 | } |
| 199 | |
[email protected] | a95986a8 | 2010-12-24 06:19:28 | [diff] [blame] | 200 | bool PPB_Flash_Proxy::OnMessageReceived(const IPC::Message& msg) { |
[email protected] | 96fe50e3 | 2011-05-10 03:47:58 | [diff] [blame] | 201 | // 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] | a95986a8 | 2010-12-24 06:19:28 | [diff] [blame] | 206 | bool handled = true; |
[email protected] | 43a4020 | 2010-11-12 16:25:01 | [diff] [blame] | 207 | 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] | 181220ba | 2011-03-28 18:21:05 | [diff] [blame] | 214 | IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFlash_Navigate, OnMsgNavigate) |
[email protected] | 7358d57 | 2011-02-15 18:44:40 | [diff] [blame] | 215 | IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFlash_RunMessageLoop, |
| 216 | OnMsgRunMessageLoop) |
| 217 | IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFlash_QuitMessageLoop, |
| 218 | OnMsgQuitMessageLoop) |
[email protected] | 83216ff | 2011-04-22 15:33:40 | [diff] [blame] | 219 | IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFlash_GetLocalTimeZoneOffset, |
| 220 | OnMsgGetLocalTimeZoneOffset) |
[email protected] | a95986a8 | 2010-12-24 06:19:28 | [diff] [blame] | 221 | IPC_MESSAGE_UNHANDLED(handled = false) |
[email protected] | 43a4020 | 2010-11-12 16:25:01 | [diff] [blame] | 222 | IPC_END_MESSAGE_MAP() |
| 223 | // TODO(brettw) handle bad messages! |
[email protected] | a95986a8 | 2010-12-24 06:19:28 | [diff] [blame] | 224 | return handled; |
[email protected] | 43a4020 | 2010-11-12 16:25:01 | [diff] [blame] | 225 | } |
| 226 | |
| 227 | void PPB_Flash_Proxy::OnMsgSetInstanceAlwaysOnTop( |
| 228 | PP_Instance instance, |
[email protected] | 4614f19 | 2011-01-21 00:26:43 | [diff] [blame] | 229 | PP_Bool on_top) { |
[email protected] | 43a4020 | 2010-11-12 16:25:01 | [diff] [blame] | 230 | ppb_flash_target()->SetInstanceAlwaysOnTop(instance, on_top); |
| 231 | } |
| 232 | |
| 233 | void PPB_Flash_Proxy::OnMsgDrawGlyphs( |
[email protected] | 99627bcf | 2010-12-02 23:59:53 | [diff] [blame] | 234 | const pp::proxy::PPBFlash_DrawGlyphs_Params& params, |
[email protected] | 4614f19 | 2011-01-21 00:26:43 | [diff] [blame] | 235 | PP_Bool* result) { |
| 236 | *result = PP_FALSE; |
[email protected] | 99627bcf | 2010-12-02 23:59:53 | [diff] [blame] | 237 | |
[email protected] | fb35dcf | 2010-11-14 17:08:00 | [diff] [blame] | 238 | 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] | 99627bcf | 2010-12-02 23:59:53 | [diff] [blame] | 245 | *result = ppb_flash_target()->DrawGlyphs( |
[email protected] | f24448db | 2011-01-27 20:40:39 | [diff] [blame] | 246 | 0, // Unused instance param. |
| 247 | params.image_data.host_resource(), &font_desc, |
| 248 | params.color, params.position, params.clip, |
[email protected] | fb35dcf | 2010-11-14 17:08:00 | [diff] [blame] | 249 | const_cast<float(*)[3]>(params.transformation), |
| 250 | static_cast<uint32_t>(params.glyph_indices.size()), |
| 251 | const_cast<uint16_t*>(¶ms.glyph_indices[0]), |
| 252 | const_cast<PP_Point*>(¶ms.glyph_advances[0])); |
[email protected] | 43a4020 | 2010-11-12 16:25:01 | [diff] [blame] | 253 | } |
| 254 | |
[email protected] | 859a7f3 | 2011-01-15 03:44:13 | [diff] [blame] | 255 | void PPB_Flash_Proxy::OnMsgGetProxyForURL(PP_Instance instance, |
[email protected] | 43a4020 | 2010-11-12 16:25:01 | [diff] [blame] | 256 | const std::string& url, |
| 257 | SerializedVarReturnValue result) { |
| 258 | result.Return(dispatcher(), ppb_flash_target()->GetProxyForURL( |
[email protected] | 859a7f3 | 2011-01-15 03:44:13 | [diff] [blame] | 259 | instance, url.c_str())); |
[email protected] | 43a4020 | 2010-11-12 16:25:01 | [diff] [blame] | 260 | } |
| 261 | |
[email protected] | 181220ba | 2011-03-28 18:21:05 | [diff] [blame] | 262 | void PPB_Flash_Proxy::OnMsgNavigate(const HostResource& request_info, |
| 263 | const std::string& target, |
| 264 | bool from_user_action, |
| 265 | int32_t* result) { |
[email protected] | bd65a3da | 2011-04-08 04:21:30 | [diff] [blame] | 266 | 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] | 181220ba | 2011-03-28 18:21:05 | [diff] [blame] | 273 | *result = ppb_flash_target()->Navigate(request_info.host_resource(), |
| 274 | target.c_str(), |
| 275 | from_user_action); |
[email protected] | 43a4020 | 2010-11-12 16:25:01 | [diff] [blame] | 276 | } |
| 277 | |
[email protected] | 7358d57 | 2011-02-15 18:44:40 | [diff] [blame] | 278 | void PPB_Flash_Proxy::OnMsgRunMessageLoop(PP_Instance instance) { |
| 279 | ppb_flash_target()->RunMessageLoop(instance); |
| 280 | } |
| 281 | |
| 282 | void PPB_Flash_Proxy::OnMsgQuitMessageLoop(PP_Instance instance) { |
| 283 | ppb_flash_target()->QuitMessageLoop(instance); |
| 284 | } |
| 285 | |
[email protected] | 4d3aec1 | 2011-04-21 23:07:45 | [diff] [blame] | 286 | void 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] | 43a4020 | 2010-11-12 16:25:01 | [diff] [blame] | 292 | } // namespace proxy |
| 293 | } // namespace pp |