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. 4 5 #include "ppapi/proxy/ppb_instance_proxy.h" 6 7 #include "base/memory/ref_counted.h" 8 #include "build/build_config.h" 9 #include "ppapi/c/pp_errors.h" 10 #include "ppapi/c/pp_time.h" 11 #include "ppapi/c/pp_var.h" 12 #include "ppapi/c/ppb_audio_config.h" 13 #include "ppapi/c/ppb_instance.h" 14 #include "ppapi/c/ppb_messaging.h" 15 #include "ppapi/c/ppb_mouse_lock.h" 16 #include "ppapi/c/private/pp_content_decryptor.h" 17 #include "ppapi/proxy/broker_resource.h" 18 #include "ppapi/proxy/browser_font_singleton_resource.h" 19 #include "ppapi/proxy/content_decryptor_private_serializer.h" 20 #include "ppapi/proxy/enter_proxy.h" 21 #include "ppapi/proxy/file_mapping_resource.h" 22 #include "ppapi/proxy/flash_clipboard_resource.h" 23 #include "ppapi/proxy/flash_file_resource.h" 24 #include "ppapi/proxy/flash_fullscreen_resource.h" 25 #include "ppapi/proxy/flash_resource.h" 26 #include "ppapi/proxy/gamepad_resource.h" 27 #include "ppapi/proxy/host_dispatcher.h" 28 #include "ppapi/proxy/isolated_file_system_private_resource.h" 29 #include "ppapi/proxy/message_handler.h" 30 #include "ppapi/proxy/network_proxy_resource.h" 31 #include "ppapi/proxy/pdf_resource.h" 32 #include "ppapi/proxy/plugin_dispatcher.h" 33 #include "ppapi/proxy/ppapi_messages.h" 34 #include "ppapi/proxy/serialized_var.h" 35 #include "ppapi/proxy/truetype_font_singleton_resource.h" 36 #include "ppapi/proxy/uma_private_resource.h" 37 #include "ppapi/shared_impl/ppapi_globals.h" 38 #include "ppapi/shared_impl/ppb_url_util_shared.h" 39 #include "ppapi/shared_impl/ppb_view_shared.h" 40 #include "ppapi/shared_impl/var.h" 41 #include "ppapi/thunk/enter.h" 42 #include "ppapi/thunk/ppb_compositor_api.h" 43 #include "ppapi/thunk/ppb_graphics_2d_api.h" 44 #include "ppapi/thunk/ppb_graphics_3d_api.h" 45 #include "ppapi/thunk/thunk.h" 46 47 // Windows headers interfere with this file. 48 #ifdef PostMessage 49 #undef PostMessage 50 #endif 51 52 using ppapi::thunk::EnterInstanceNoLock; 53 using ppapi::thunk::EnterResourceNoLock; 54 using ppapi::thunk::PPB_Compositor_API; 55 using ppapi::thunk::PPB_Graphics2D_API; 56 using ppapi::thunk::PPB_Graphics3D_API; 57 using ppapi::thunk::PPB_Instance_API; 58 59 namespace ppapi { 60 namespace proxy { 61 62 namespace { 63 64 #if !defined(OS_NACL) 65 const char kSerializationError[] = "Failed to convert a PostMessage " 66 "argument from a PP_Var to a Javascript value. It may have cycles or be of " 67 "an unsupported type."; 68 #endif 69 70 void RequestSurroundingText(PP_Instance instance) { 71 PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance); 72 if (!dispatcher) 73 return; // Instance has gone away while message was pending. 74 75 InstanceData* data = dispatcher->GetInstanceData(instance); 76 DCHECK(data); // Should have it, since we still have a dispatcher. 77 data->is_request_surrounding_text_pending = false; 78 if (!data->should_do_request_surrounding_text) 79 return; 80 81 // Just fake out a RequestSurroundingText message to the proxy for the PPP 82 // interface. 83 InterfaceProxy* proxy = dispatcher->GetInterfaceProxy(API_ID_PPP_TEXT_INPUT); 84 if (!proxy) 85 return; 86 proxy->OnMessageReceived(PpapiMsg_PPPTextInput_RequestSurroundingText( 87 API_ID_PPP_TEXT_INPUT, instance, 88 PPB_Instance_Shared::kExtraCharsForTextInput)); 89 } 90 91 } // namespace 92 93 PPB_Instance_Proxy::PPB_Instance_Proxy(Dispatcher* dispatcher) 94 : InterfaceProxy(dispatcher), 95 callback_factory_(this) { 96 } 97 98 PPB_Instance_Proxy::~PPB_Instance_Proxy() { 99 } 100 101 bool PPB_Instance_Proxy::OnMessageReceived(const IPC::Message& msg) { 102 // Prevent the dispatcher from going away during a call to ExecuteScript. 103 // This must happen OUTSIDE of ExecuteScript since the SerializedVars use 104 // the dispatcher upon return of the function (converting the 105 // SerializedVarReturnValue/OutParam to a SerializedVar in the destructor). 106 #if !defined(OS_NACL) 107 ScopedModuleReference death_grip(dispatcher()); 108 #endif 109 110 bool handled = true; 111 IPC_BEGIN_MESSAGE_MAP(PPB_Instance_Proxy, msg) 112 #if !defined(OS_NACL) 113 // Plugin -> Host messages. 114 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_GetWindowObject, 115 OnHostMsgGetWindowObject) 116 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_GetOwnerElementObject, 117 OnHostMsgGetOwnerElementObject) 118 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_BindGraphics, 119 OnHostMsgBindGraphics) 120 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_IsFullFrame, 121 OnHostMsgIsFullFrame) 122 IPC_MESSAGE_HANDLER( 123 PpapiHostMsg_PPBInstance_GetAudioHardwareOutputSampleRate, 124 OnHostMsgGetAudioHardwareOutputSampleRate) 125 IPC_MESSAGE_HANDLER( 126 PpapiHostMsg_PPBInstance_GetAudioHardwareOutputBufferSize, 127 OnHostMsgGetAudioHardwareOutputBufferSize) 128 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_ExecuteScript, 129 OnHostMsgExecuteScript) 130 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_GetDefaultCharSet, 131 OnHostMsgGetDefaultCharSet) 132 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_SetPluginToHandleFindRequests, 133 OnHostMsgSetPluginToHandleFindRequests); 134 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_NumberOfFindResultsChanged, 135 OnHostMsgNumberOfFindResultsChanged) 136 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_SelectFindResultChanged, 137 OnHostMsgSelectFindResultChanged) 138 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_SetTickmarks, 139 OnHostMsgSetTickmarks) 140 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_PostMessage, 141 OnHostMsgPostMessage) 142 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_SetFullscreen, 143 OnHostMsgSetFullscreen) 144 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_GetScreenSize, 145 OnHostMsgGetScreenSize) 146 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_RequestInputEvents, 147 OnHostMsgRequestInputEvents) 148 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_ClearInputEvents, 149 OnHostMsgClearInputEvents) 150 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_StartTrackingLatency, 151 OnHostMsgStartTrackingLatency) 152 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_LockMouse, 153 OnHostMsgLockMouse) 154 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_UnlockMouse, 155 OnHostMsgUnlockMouse) 156 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_SetCursor, 157 OnHostMsgSetCursor) 158 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_SetTextInputType, 159 OnHostMsgSetTextInputType) 160 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_UpdateCaretPosition, 161 OnHostMsgUpdateCaretPosition) 162 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_CancelCompositionText, 163 OnHostMsgCancelCompositionText) 164 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_UpdateSurroundingText, 165 OnHostMsgUpdateSurroundingText) 166 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_GetDocumentURL, 167 OnHostMsgGetDocumentURL) 168 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_ResolveRelativeToDocument, 169 OnHostMsgResolveRelativeToDocument) 170 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_DocumentCanRequest, 171 OnHostMsgDocumentCanRequest) 172 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_DocumentCanAccessDocument, 173 OnHostMsgDocumentCanAccessDocument) 174 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_GetPluginInstanceURL, 175 OnHostMsgGetPluginInstanceURL) 176 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_GetPluginReferrerURL, 177 OnHostMsgGetPluginReferrerURL) 178 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_PromiseResolved, 179 OnHostMsgPromiseResolved) 180 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_PromiseResolvedWithSession, 181 OnHostMsgPromiseResolvedWithSession) 182 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_PromiseRejected, 183 OnHostMsgPromiseRejected) 184 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_SessionMessage, 185 OnHostMsgSessionMessage) 186 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_SessionReady, 187 OnHostMsgSessionReady) 188 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_SessionClosed, 189 OnHostMsgSessionClosed) 190 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_SessionError, 191 OnHostMsgSessionError) 192 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_DeliverBlock, 193 OnHostMsgDeliverBlock) 194 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_DecoderInitializeDone, 195 OnHostMsgDecoderInitializeDone) 196 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_DecoderDeinitializeDone, 197 OnHostMsgDecoderDeinitializeDone) 198 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_DecoderResetDone, 199 OnHostMsgDecoderResetDone) 200 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_DeliverFrame, 201 OnHostMsgDeliverFrame) 202 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_DeliverSamples, 203 OnHostMsgDeliverSamples) 204 #endif // !defined(OS_NACL) 205 206 // Host -> Plugin messages. 207 IPC_MESSAGE_HANDLER(PpapiMsg_PPBInstance_MouseLockComplete, 208 OnPluginMsgMouseLockComplete) 209 210 IPC_MESSAGE_UNHANDLED(handled = false) 211 IPC_END_MESSAGE_MAP() 212 return handled; 213 } 214 215 PP_Bool PPB_Instance_Proxy::BindGraphics(PP_Instance instance, 216 PP_Resource device) { 217 // If device is 0, pass a null HostResource. This signals the host to unbind 218 // all devices. 219 HostResource host_resource; 220 PP_Resource pp_resource = 0; 221 if (device) { 222 Resource* resource = 223 PpapiGlobals::Get()->GetResourceTracker()->GetResource(device); 224 if (!resource || resource->pp_instance() != instance) 225 return PP_FALSE; 226 host_resource = resource->host_resource(); 227 pp_resource = resource->pp_resource(); 228 } else { 229 // Passing 0 means unbinding all devices. 230 dispatcher()->Send(new PpapiHostMsg_PPBInstance_BindGraphics( 231 API_ID_PPB_INSTANCE, instance, 0)); 232 return PP_TRUE; 233 } 234 235 // We need to pass different resource to Graphics 2D and 3D right now. Once 236 // 3D is migrated to the new design, we should be able to unify this. 237 EnterResourceNoLock<PPB_Compositor_API> enter_compositor(device, false); 238 EnterResourceNoLock<PPB_Graphics2D_API> enter_2d(device, false); 239 EnterResourceNoLock<PPB_Graphics3D_API> enter_3d(device, false); 240 if (enter_compositor.succeeded() || enter_2d.succeeded()) { 241 dispatcher()->Send(new PpapiHostMsg_PPBInstance_BindGraphics( 242 API_ID_PPB_INSTANCE, instance, pp_resource)); 243 return PP_TRUE; 244 } else if (enter_3d.succeeded()) { 245 dispatcher()->Send(new PpapiHostMsg_PPBInstance_BindGraphics( 246 API_ID_PPB_INSTANCE, instance, host_resource.host_resource())); 247 return PP_TRUE; 248 } 249 return PP_FALSE; 250 } 251 252 PP_Bool PPB_Instance_Proxy::IsFullFrame(PP_Instance instance) { 253 PP_Bool result = PP_FALSE; 254 dispatcher()->Send(new PpapiHostMsg_PPBInstance_IsFullFrame( 255 API_ID_PPB_INSTANCE, instance, &result)); 256 return result; 257 } 258 259 const ViewData* PPB_Instance_Proxy::GetViewData(PP_Instance instance) { 260 InstanceData* data = static_cast<PluginDispatcher*>(dispatcher())-> 261 GetInstanceData(instance); 262 if (!data) 263 return NULL; 264 return &data->view; 265 } 266 267 PP_Bool PPB_Instance_Proxy::FlashIsFullscreen(PP_Instance instance) { 268 // This function is only used for proxying in the renderer process. It is not 269 // implemented in the plugin process. 270 NOTREACHED(); 271 return PP_FALSE; 272 } 273 274 PP_Var PPB_Instance_Proxy::GetWindowObject(PP_Instance instance) { 275 ReceiveSerializedVarReturnValue result; 276 dispatcher()->Send(new PpapiHostMsg_PPBInstance_GetWindowObject( 277 API_ID_PPB_INSTANCE, instance, &result)); 278 return result.Return(dispatcher()); 279 } 280 281 PP_Var PPB_Instance_Proxy::GetOwnerElementObject(PP_Instance instance) { 282 ReceiveSerializedVarReturnValue result; 283 dispatcher()->Send(new PpapiHostMsg_PPBInstance_GetOwnerElementObject( 284 API_ID_PPB_INSTANCE, instance, &result)); 285 return result.Return(dispatcher()); 286 } 287 288 PP_Var PPB_Instance_Proxy::ExecuteScript(PP_Instance instance, 289 PP_Var script, 290 PP_Var* exception) { 291 ReceiveSerializedException se(dispatcher(), exception); 292 if (se.IsThrown()) 293 return PP_MakeUndefined(); 294 295 ReceiveSerializedVarReturnValue result; 296 dispatcher()->Send(new PpapiHostMsg_PPBInstance_ExecuteScript( 297 API_ID_PPB_INSTANCE, instance, 298 SerializedVarSendInput(dispatcher(), script), &se, &result)); 299 return result.Return(dispatcher()); 300 } 301 302 uint32_t PPB_Instance_Proxy::GetAudioHardwareOutputSampleRate( 303 PP_Instance instance) { 304 uint32_t result = PP_AUDIOSAMPLERATE_NONE; 305 dispatcher()->Send( 306 new PpapiHostMsg_PPBInstance_GetAudioHardwareOutputSampleRate( 307 API_ID_PPB_INSTANCE, instance, &result)); 308 return result; 309 } 310 311 uint32_t PPB_Instance_Proxy::GetAudioHardwareOutputBufferSize( 312 PP_Instance instance) { 313 uint32_t result = 0; 314 dispatcher()->Send( 315 new PpapiHostMsg_PPBInstance_GetAudioHardwareOutputBufferSize( 316 API_ID_PPB_INSTANCE, instance, &result)); 317 return result; 318 } 319 320 PP_Var PPB_Instance_Proxy::GetDefaultCharSet(PP_Instance instance) { 321 PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance); 322 if (!dispatcher) 323 return PP_MakeUndefined(); 324 325 ReceiveSerializedVarReturnValue result; 326 dispatcher->Send(new PpapiHostMsg_PPBInstance_GetDefaultCharSet( 327 API_ID_PPB_INSTANCE, instance, &result)); 328 return result.Return(dispatcher); 329 } 330 331 void PPB_Instance_Proxy::SetPluginToHandleFindRequests(PP_Instance instance) { 332 dispatcher()->Send(new PpapiHostMsg_PPBInstance_SetPluginToHandleFindRequests( 333 API_ID_PPB_INSTANCE, instance)); 334 } 335 336 void PPB_Instance_Proxy::NumberOfFindResultsChanged(PP_Instance instance, 337 int32_t total, 338 PP_Bool final_result) { 339 dispatcher()->Send(new PpapiHostMsg_PPBInstance_NumberOfFindResultsChanged( 340 API_ID_PPB_INSTANCE, instance, total, final_result)); 341 } 342 343 void PPB_Instance_Proxy::SelectedFindResultChanged(PP_Instance instance, 344 int32_t index) { 345 dispatcher()->Send(new PpapiHostMsg_PPBInstance_SelectFindResultChanged( 346 API_ID_PPB_INSTANCE, instance, index)); 347 } 348 349 void PPB_Instance_Proxy::SetTickmarks(PP_Instance instance, 350 const PP_Rect* tickmarks, 351 uint32_t count) { 352 dispatcher()->Send(new PpapiHostMsg_PPBInstance_SetTickmarks( 353 API_ID_PPB_INSTANCE, instance, 354 std::vector<PP_Rect>(tickmarks, tickmarks + count))); 355 } 356 357 PP_Bool PPB_Instance_Proxy::IsFullscreen(PP_Instance instance) { 358 InstanceData* data = static_cast<PluginDispatcher*>(dispatcher())-> 359 GetInstanceData(instance); 360 if (!data) 361 return PP_FALSE; 362 return PP_FromBool(data->view.is_fullscreen); 363 } 364 365 PP_Bool PPB_Instance_Proxy::SetFullscreen(PP_Instance instance, 366 PP_Bool fullscreen) { 367 PP_Bool result = PP_FALSE; 368 dispatcher()->Send(new PpapiHostMsg_PPBInstance_SetFullscreen( 369 API_ID_PPB_INSTANCE, instance, fullscreen, &result)); 370 return result; 371 } 372 373 PP_Bool PPB_Instance_Proxy::GetScreenSize(PP_Instance instance, 374 PP_Size* size) { 375 PP_Bool result = PP_FALSE; 376 dispatcher()->Send(new PpapiHostMsg_PPBInstance_GetScreenSize( 377 API_ID_PPB_INSTANCE, instance, &result, size)); 378 return result; 379 } 380 381 Resource* PPB_Instance_Proxy::GetSingletonResource(PP_Instance instance, 382 SingletonResourceID id) { 383 InstanceData* data = static_cast<PluginDispatcher*>(dispatcher())-> 384 GetInstanceData(instance); 385 386 InstanceData::SingletonResourceMap::iterator it = 387 data->singleton_resources.find(id); 388 if (it != data->singleton_resources.end()) 389 return it->second.get(); 390 391 scoped_refptr<Resource> new_singleton; 392 Connection connection(PluginGlobals::Get()->GetBrowserSender(), dispatcher()); 393 394 switch (id) { 395 case BROKER_SINGLETON_ID: 396 new_singleton = new BrokerResource(connection, instance); 397 break; 398 case FILE_MAPPING_SINGLETON_ID: 399 new_singleton = new FileMappingResource(connection, instance); 400 break; 401 case GAMEPAD_SINGLETON_ID: 402 new_singleton = new GamepadResource(connection, instance); 403 break; 404 case ISOLATED_FILESYSTEM_SINGLETON_ID: 405 new_singleton = 406 new IsolatedFileSystemPrivateResource(connection, instance); 407 break; 408 case NETWORK_PROXY_SINGLETON_ID: 409 new_singleton = new NetworkProxyResource(connection, instance); 410 break; 411 case TRUETYPE_FONT_SINGLETON_ID: 412 new_singleton = new TrueTypeFontSingletonResource(connection, instance); 413 break; 414 case UMA_SINGLETON_ID: 415 new_singleton = new UMAPrivateResource(connection, instance); 416 break; 417 // Flash/trusted resources aren't needed for NaCl. 418 #if !defined(OS_NACL) && !defined(NACL_WIN64) 419 case BROWSER_FONT_SINGLETON_ID: 420 new_singleton = new BrowserFontSingletonResource(connection, instance); 421 break; 422 case FLASH_CLIPBOARD_SINGLETON_ID: 423 new_singleton = new FlashClipboardResource(connection, instance); 424 break; 425 case FLASH_FILE_SINGLETON_ID: 426 new_singleton = new FlashFileResource(connection, instance); 427 break; 428 case FLASH_FULLSCREEN_SINGLETON_ID: 429 new_singleton = new FlashFullscreenResource(connection, instance); 430 break; 431 case FLASH_SINGLETON_ID: 432 new_singleton = new FlashResource(connection, instance, 433 static_cast<PluginDispatcher*>(dispatcher())); 434 break; 435 case PDF_SINGLETON_ID: 436 new_singleton = new PDFResource(connection, instance); 437 break; 438 #else 439 case BROWSER_FONT_SINGLETON_ID: 440 case FLASH_CLIPBOARD_SINGLETON_ID: 441 case FLASH_FILE_SINGLETON_ID: 442 case FLASH_FULLSCREEN_SINGLETON_ID: 443 case FLASH_SINGLETON_ID: 444 case PDF_SINGLETON_ID: 445 NOTREACHED(); 446 break; 447 #endif // !defined(OS_NACL) && !defined(NACL_WIN64) 448 } 449 450 if (!new_singleton.get()) { 451 // Getting here implies that a constructor is missing in the above switch. 452 NOTREACHED(); 453 return NULL; 454 } 455 456 data->singleton_resources[id] = new_singleton; 457 return new_singleton.get(); 458 } 459 460 int32_t PPB_Instance_Proxy::RequestInputEvents(PP_Instance instance, 461 uint32_t event_classes) { 462 dispatcher()->Send(new PpapiHostMsg_PPBInstance_RequestInputEvents( 463 API_ID_PPB_INSTANCE, instance, false, event_classes)); 464 465 // We always register for the classes we can handle, this function validates 466 // the flags so we can notify it if anything was invalid, without requiring 467 // a sync reply. 468 return ValidateRequestInputEvents(false, event_classes); 469 } 470 471 int32_t PPB_Instance_Proxy::RequestFilteringInputEvents( 472 PP_Instance instance, 473 uint32_t event_classes) { 474 dispatcher()->Send(new PpapiHostMsg_PPBInstance_RequestInputEvents( 475 API_ID_PPB_INSTANCE, instance, true, event_classes)); 476 477 // We always register for the classes we can handle, this function validates 478 // the flags so we can notify it if anything was invalid, without requiring 479 // a sync reply. 480 return ValidateRequestInputEvents(true, event_classes); 481 } 482 483 void PPB_Instance_Proxy::ClearInputEventRequest(PP_Instance instance, 484 uint32_t event_classes) { 485 dispatcher()->Send(new PpapiHostMsg_PPBInstance_ClearInputEvents( 486 API_ID_PPB_INSTANCE, instance, event_classes)); 487 } 488 489 void PPB_Instance_Proxy::StartTrackingLatency(PP_Instance instance) { 490 dispatcher()->Send(new PpapiHostMsg_PPBInstance_StartTrackingLatency( 491 API_ID_PPB_INSTANCE, instance)); 492 } 493 494 void PPB_Instance_Proxy::ZoomChanged(PP_Instance instance, 495 double factor) { 496 // Not proxied yet. 497 NOTIMPLEMENTED(); 498 } 499 500 void PPB_Instance_Proxy::ZoomLimitsChanged(PP_Instance instance, 501 double minimum_factor, 502 double maximium_factor) { 503 // Not proxied yet. 504 NOTIMPLEMENTED(); 505 } 506 507 PP_Var PPB_Instance_Proxy::GetDocumentURL(PP_Instance instance, 508 PP_URLComponents_Dev* components) { 509 ReceiveSerializedVarReturnValue result; 510 PP_URLComponents_Dev url_components; 511 dispatcher()->Send(new PpapiHostMsg_PPBInstance_GetDocumentURL( 512 API_ID_PPB_INSTANCE, instance, &url_components, &result)); 513 if (components) 514 *components = url_components; 515 return result.Return(dispatcher()); 516 } 517 518 #if !defined(OS_NACL) 519 PP_Var PPB_Instance_Proxy::ResolveRelativeToDocument( 520 PP_Instance instance, 521 PP_Var relative, 522 PP_URLComponents_Dev* components) { 523 ReceiveSerializedVarReturnValue result; 524 dispatcher()->Send(new PpapiHostMsg_PPBInstance_ResolveRelativeToDocument( 525 API_ID_PPB_INSTANCE, instance, 526 SerializedVarSendInput(dispatcher(), relative), 527 &result)); 528 return PPB_URLUtil_Shared::ConvertComponentsAndReturnURL( 529 result.Return(dispatcher()), 530 components); 531 } 532 533 PP_Bool PPB_Instance_Proxy::DocumentCanRequest(PP_Instance instance, 534 PP_Var url) { 535 PP_Bool result = PP_FALSE; 536 dispatcher()->Send(new PpapiHostMsg_PPBInstance_DocumentCanRequest( 537 API_ID_PPB_INSTANCE, instance, 538 SerializedVarSendInput(dispatcher(), url), 539 &result)); 540 return result; 541 } 542 543 PP_Bool PPB_Instance_Proxy::DocumentCanAccessDocument(PP_Instance instance, 544 PP_Instance target) { 545 PP_Bool result = PP_FALSE; 546 dispatcher()->Send(new PpapiHostMsg_PPBInstance_DocumentCanAccessDocument( 547 API_ID_PPB_INSTANCE, instance, target, &result)); 548 return result; 549 } 550 551 PP_Var PPB_Instance_Proxy::GetPluginInstanceURL( 552 PP_Instance instance, 553 PP_URLComponents_Dev* components) { 554 ReceiveSerializedVarReturnValue result; 555 dispatcher()->Send(new PpapiHostMsg_PPBInstance_GetPluginInstanceURL( 556 API_ID_PPB_INSTANCE, instance, &result)); 557 return PPB_URLUtil_Shared::ConvertComponentsAndReturnURL( 558 result.Return(dispatcher()), 559 components); 560 } 561 562 PP_Var PPB_Instance_Proxy::GetPluginReferrerURL( 563 PP_Instance instance, 564 PP_URLComponents_Dev* components) { 565 ReceiveSerializedVarReturnValue result; 566 dispatcher()->Send(new PpapiHostMsg_PPBInstance_GetPluginReferrerURL( 567 API_ID_PPB_INSTANCE, instance, &result)); 568 return PPB_URLUtil_Shared::ConvertComponentsAndReturnURL( 569 result.Return(dispatcher()), 570 components); 571 } 572 573 void PPB_Instance_Proxy::PromiseResolved(PP_Instance instance, 574 uint32 promise_id) { 575 dispatcher()->Send(new PpapiHostMsg_PPBInstance_PromiseResolved( 576 API_ID_PPB_INSTANCE, instance, promise_id)); 577 } 578 579 void PPB_Instance_Proxy::PromiseResolvedWithSession(PP_Instance instance, 580 uint32 promise_id, 581 PP_Var web_session_id_var) { 582 dispatcher()->Send(new PpapiHostMsg_PPBInstance_PromiseResolvedWithSession( 583 API_ID_PPB_INSTANCE, 584 instance, 585 promise_id, 586 SerializedVarSendInput(dispatcher(), web_session_id_var))); 587 } 588 589 void PPB_Instance_Proxy::PromiseRejected(PP_Instance instance, 590 uint32 promise_id, 591 PP_CdmExceptionCode exception_code, 592 uint32 system_code, 593 PP_Var error_description_var) { 594 dispatcher()->Send(new PpapiHostMsg_PPBInstance_PromiseRejected( 595 API_ID_PPB_INSTANCE, 596 instance, 597 promise_id, 598 exception_code, 599 system_code, 600 SerializedVarSendInput(dispatcher(), error_description_var))); 601 } 602 603 void PPB_Instance_Proxy::SessionMessage(PP_Instance instance, 604 PP_Var web_session_id_var, 605 PP_Var message_var, 606 PP_Var destination_url_var) { 607 dispatcher()->Send(new PpapiHostMsg_PPBInstance_SessionMessage( 608 API_ID_PPB_INSTANCE, 609 instance, 610 SerializedVarSendInput(dispatcher(), web_session_id_var), 611 SerializedVarSendInput(dispatcher(), message_var), 612 SerializedVarSendInput(dispatcher(), destination_url_var))); 613 } 614 615 void PPB_Instance_Proxy::SessionReady(PP_Instance instance, 616 PP_Var web_session_id_var) { 617 dispatcher()->Send(new PpapiHostMsg_PPBInstance_SessionReady( 618 API_ID_PPB_INSTANCE, 619 instance, 620 SerializedVarSendInput(dispatcher(), web_session_id_var))); 621 } 622 623 void PPB_Instance_Proxy::SessionClosed(PP_Instance instance, 624 PP_Var web_session_id_var) { 625 dispatcher()->Send(new PpapiHostMsg_PPBInstance_SessionClosed( 626 API_ID_PPB_INSTANCE, 627 instance, 628 SerializedVarSendInput(dispatcher(), web_session_id_var))); 629 } 630 631 void PPB_Instance_Proxy::SessionError(PP_Instance instance, 632 PP_Var web_session_id_var, 633 PP_CdmExceptionCode exception_code, 634 uint32 system_code, 635 PP_Var error_description_var) { 636 dispatcher()->Send(new PpapiHostMsg_PPBInstance_SessionError( 637 API_ID_PPB_INSTANCE, 638 instance, 639 SerializedVarSendInput(dispatcher(), web_session_id_var), 640 exception_code, 641 system_code, 642 SerializedVarSendInput(dispatcher(), error_description_var))); 643 } 644 645 void PPB_Instance_Proxy::DeliverBlock(PP_Instance instance, 646 PP_Resource decrypted_block, 647 const PP_DecryptedBlockInfo* block_info) { 648 PP_Resource decrypted_block_host_resource = 0; 649 650 if (decrypted_block) { 651 Resource* object = 652 PpapiGlobals::Get()->GetResourceTracker()->GetResource(decrypted_block); 653 if (!object || object->pp_instance() != instance) { 654 NOTREACHED(); 655 return; 656 } 657 decrypted_block_host_resource = object->host_resource().host_resource(); 658 } 659 660 std::string serialized_block_info; 661 if (!SerializeBlockInfo(*block_info, &serialized_block_info)) { 662 NOTREACHED(); 663 return; 664 } 665 666 dispatcher()->Send( 667 new PpapiHostMsg_PPBInstance_DeliverBlock(API_ID_PPB_INSTANCE, 668 instance, 669 decrypted_block_host_resource, 670 serialized_block_info)); 671 } 672 673 void PPB_Instance_Proxy::DecoderInitializeDone( 674 PP_Instance instance, 675 PP_DecryptorStreamType decoder_type, 676 uint32_t request_id, 677 PP_Bool success) { 678 dispatcher()->Send( 679 new PpapiHostMsg_PPBInstance_DecoderInitializeDone( 680 API_ID_PPB_INSTANCE, 681 instance, 682 decoder_type, 683 request_id, 684 success)); 685 } 686 687 void PPB_Instance_Proxy::DecoderDeinitializeDone( 688 PP_Instance instance, 689 PP_DecryptorStreamType decoder_type, 690 uint32_t request_id) { 691 dispatcher()->Send( 692 new PpapiHostMsg_PPBInstance_DecoderDeinitializeDone( 693 API_ID_PPB_INSTANCE, 694 instance, 695 decoder_type, 696 request_id)); 697 } 698 699 void PPB_Instance_Proxy::DecoderResetDone(PP_Instance instance, 700 PP_DecryptorStreamType decoder_type, 701 uint32_t request_id) { 702 dispatcher()->Send( 703 new PpapiHostMsg_PPBInstance_DecoderResetDone( 704 API_ID_PPB_INSTANCE, 705 instance, 706 decoder_type, 707 request_id)); 708 } 709 710 void PPB_Instance_Proxy::DeliverFrame(PP_Instance instance, 711 PP_Resource decrypted_frame, 712 const PP_DecryptedFrameInfo* frame_info) { 713 PP_Resource host_resource = 0; 714 if (decrypted_frame != 0) { 715 ResourceTracker* tracker = PpapiGlobals::Get()->GetResourceTracker(); 716 Resource* object = tracker->GetResource(decrypted_frame); 717 718 if (!object || object->pp_instance() != instance) { 719 NOTREACHED(); 720 return; 721 } 722 723 host_resource = object->host_resource().host_resource(); 724 } 725 726 std::string serialized_frame_info; 727 if (!SerializeBlockInfo(*frame_info, &serialized_frame_info)) { 728 NOTREACHED(); 729 return; 730 } 731 732 dispatcher()->Send( 733 new PpapiHostMsg_PPBInstance_DeliverFrame(API_ID_PPB_INSTANCE, 734 instance, 735 host_resource, 736 serialized_frame_info)); 737 } 738 739 void PPB_Instance_Proxy::DeliverSamples( 740 PP_Instance instance, 741 PP_Resource decrypted_samples, 742 const PP_DecryptedSampleInfo* sample_info) { 743 PP_Resource host_resource = 0; 744 if (decrypted_samples != 0) { 745 ResourceTracker* tracker = PpapiGlobals::Get()->GetResourceTracker(); 746 Resource* object = tracker->GetResource(decrypted_samples); 747 748 if (!object || object->pp_instance() != instance) { 749 NOTREACHED(); 750 return; 751 } 752 753 host_resource = object->host_resource().host_resource(); 754 } 755 756 std::string serialized_sample_info; 757 if (!SerializeBlockInfo(*sample_info, &serialized_sample_info)) { 758 NOTREACHED(); 759 return; 760 } 761 762 dispatcher()->Send( 763 new PpapiHostMsg_PPBInstance_DeliverSamples(API_ID_PPB_INSTANCE, 764 instance, 765 host_resource, 766 serialized_sample_info)); 767 } 768 #endif // !defined(OS_NACL) 769 770 void PPB_Instance_Proxy::PostMessage(PP_Instance instance, 771 PP_Var message) { 772 dispatcher()->Send(new PpapiHostMsg_PPBInstance_PostMessage( 773 API_ID_PPB_INSTANCE, 774 instance, SerializedVarSendInputShmem(dispatcher(), message, 775 instance))); 776 } 777 778 int32_t PPB_Instance_Proxy::RegisterMessageHandler( 779 PP_Instance instance, 780 void* user_data, 781 const PPP_MessageHandler_0_1* handler, 782 PP_Resource message_loop) { 783 InstanceData* data = 784 static_cast<PluginDispatcher*>(dispatcher())->GetInstanceData(instance); 785 if (!data) 786 return PP_ERROR_BADARGUMENT; 787 788 int32_t result = PP_ERROR_FAILED; 789 scoped_ptr<MessageHandler> message_handler = MessageHandler::Create( 790 instance, handler, user_data, message_loop, &result); 791 if (message_handler) 792 data->message_handler = message_handler.Pass(); 793 return result; 794 } 795 796 void PPB_Instance_Proxy::UnregisterMessageHandler(PP_Instance instance) { 797 InstanceData* data = 798 static_cast<PluginDispatcher*>(dispatcher())->GetInstanceData(instance); 799 if (!data) 800 return; 801 data->message_handler.reset(); 802 } 803 804 PP_Bool PPB_Instance_Proxy::SetCursor(PP_Instance instance, 805 PP_MouseCursor_Type type, 806 PP_Resource image, 807 const PP_Point* hot_spot) { 808 // Some of these parameters are important for security. This check is in the 809 // plugin process just for the convenience of the caller (since we don't 810 // bother returning errors from the other process with a sync message). The 811 // parameters will be validated again in the renderer. 812 if (!ValidateSetCursorParams(type, image, hot_spot)) 813 return PP_FALSE; 814 815 HostResource image_host_resource; 816 if (image) { 817 Resource* cursor_image = 818 PpapiGlobals::Get()->GetResourceTracker()->GetResource(image); 819 if (!cursor_image || cursor_image->pp_instance() != instance) 820 return PP_FALSE; 821 image_host_resource = cursor_image->host_resource(); 822 } 823 824 dispatcher()->Send(new PpapiHostMsg_PPBInstance_SetCursor( 825 API_ID_PPB_INSTANCE, instance, static_cast<int32_t>(type), 826 image_host_resource, hot_spot ? *hot_spot : PP_MakePoint(0, 0))); 827 return PP_TRUE; 828 } 829 830 int32_t PPB_Instance_Proxy::LockMouse(PP_Instance instance, 831 scoped_refptr<TrackedCallback> callback) { 832 // Save the mouse callback on the instance data. 833 InstanceData* data = static_cast<PluginDispatcher*>(dispatcher())-> 834 GetInstanceData(instance); 835 if (!data) 836 return PP_ERROR_BADARGUMENT; 837 if (TrackedCallback::IsPending(data->mouse_lock_callback)) 838 return PP_ERROR_INPROGRESS; // Already have a pending callback. 839 data->mouse_lock_callback = callback; 840 841 dispatcher()->Send(new PpapiHostMsg_PPBInstance_LockMouse( 842 API_ID_PPB_INSTANCE, instance)); 843 return PP_OK_COMPLETIONPENDING; 844 } 845 846 void PPB_Instance_Proxy::UnlockMouse(PP_Instance instance) { 847 dispatcher()->Send(new PpapiHostMsg_PPBInstance_UnlockMouse( 848 API_ID_PPB_INSTANCE, instance)); 849 } 850 851 void PPB_Instance_Proxy::SetTextInputType(PP_Instance instance, 852 PP_TextInput_Type type) { 853 CancelAnyPendingRequestSurroundingText(instance); 854 dispatcher()->Send(new PpapiHostMsg_PPBInstance_SetTextInputType( 855 API_ID_PPB_INSTANCE, instance, type)); 856 } 857 858 void PPB_Instance_Proxy::UpdateCaretPosition(PP_Instance instance, 859 const PP_Rect& caret, 860 const PP_Rect& bounding_box) { 861 dispatcher()->Send(new PpapiHostMsg_PPBInstance_UpdateCaretPosition( 862 API_ID_PPB_INSTANCE, instance, caret, bounding_box)); 863 } 864 865 void PPB_Instance_Proxy::CancelCompositionText(PP_Instance instance) { 866 CancelAnyPendingRequestSurroundingText(instance); 867 dispatcher()->Send(new PpapiHostMsg_PPBInstance_CancelCompositionText( 868 API_ID_PPB_INSTANCE, instance)); 869 } 870 871 void PPB_Instance_Proxy::SelectionChanged(PP_Instance instance) { 872 // The "right" way to do this is to send the message to the host. However, 873 // all it will do is call RequestSurroundingText with a hardcoded number of 874 // characters in response, which is an entire IPC round-trip. 875 // 876 // We can avoid this round-trip by just implementing the 877 // RequestSurroundingText logic in the plugin process. If the logic in the 878 // host becomes more complex (like a more adaptive number of characters), 879 // we'll need to reevanuate whether we want to do the round trip instead. 880 // 881 // Be careful to post a task to avoid reentering the plugin. 882 883 InstanceData* data = 884 static_cast<PluginDispatcher*>(dispatcher())->GetInstanceData(instance); 885 if (!data) 886 return; 887 data->should_do_request_surrounding_text = true; 888 889 if (!data->is_request_surrounding_text_pending) { 890 base::MessageLoop::current()->PostTask( 891 FROM_HERE, 892 RunWhileLocked(base::Bind(&RequestSurroundingText, instance))); 893 data->is_request_surrounding_text_pending = true; 894 } 895 } 896 897 void PPB_Instance_Proxy::UpdateSurroundingText(PP_Instance instance, 898 const char* text, 899 uint32_t caret, 900 uint32_t anchor) { 901 dispatcher()->Send(new PpapiHostMsg_PPBInstance_UpdateSurroundingText( 902 API_ID_PPB_INSTANCE, instance, text, caret, anchor)); 903 } 904 905 #if !defined(OS_NACL) 906 void PPB_Instance_Proxy::OnHostMsgGetWindowObject( 907 PP_Instance instance, 908 SerializedVarReturnValue result) { 909 if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE)) 910 return; 911 EnterInstanceNoLock enter(instance); 912 if (enter.succeeded()) 913 result.Return(dispatcher(), enter.functions()->GetWindowObject(instance)); 914 } 915 916 void PPB_Instance_Proxy::OnHostMsgGetOwnerElementObject( 917 PP_Instance instance, 918 SerializedVarReturnValue result) { 919 if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE)) 920 return; 921 EnterInstanceNoLock enter(instance); 922 if (enter.succeeded()) { 923 result.Return(dispatcher(), 924 enter.functions()->GetOwnerElementObject(instance)); 925 } 926 } 927 928 void PPB_Instance_Proxy::OnHostMsgBindGraphics(PP_Instance instance, 929 PP_Resource device) { 930 // Note that we ignroe the return value here. Otherwise, this would need to 931 // be a slow sync call, and the plugin side of the proxy will have already 932 // validated the resources, so we shouldn't see errors here that weren't 933 // already caught. 934 EnterInstanceNoLock enter(instance); 935 if (enter.succeeded()) 936 enter.functions()->BindGraphics(instance, device); 937 } 938 939 void PPB_Instance_Proxy::OnHostMsgGetAudioHardwareOutputSampleRate( 940 PP_Instance instance, uint32_t* result) { 941 EnterInstanceNoLock enter(instance); 942 if (enter.succeeded()) 943 *result = enter.functions()->GetAudioHardwareOutputSampleRate(instance); 944 } 945 946 void PPB_Instance_Proxy::OnHostMsgGetAudioHardwareOutputBufferSize( 947 PP_Instance instance, uint32_t* result) { 948 EnterInstanceNoLock enter(instance); 949 if (enter.succeeded()) 950 *result = enter.functions()->GetAudioHardwareOutputBufferSize(instance); 951 } 952 953 void PPB_Instance_Proxy::OnHostMsgIsFullFrame(PP_Instance instance, 954 PP_Bool* result) { 955 EnterInstanceNoLock enter(instance); 956 if (enter.succeeded()) 957 *result = enter.functions()->IsFullFrame(instance); 958 } 959 960 void PPB_Instance_Proxy::OnHostMsgExecuteScript( 961 PP_Instance instance, 962 SerializedVarReceiveInput script, 963 SerializedVarOutParam out_exception, 964 SerializedVarReturnValue result) { 965 if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE)) 966 return; 967 EnterInstanceNoLock enter(instance); 968 if (enter.failed()) 969 return; 970 971 if (dispatcher()->IsPlugin()) 972 NOTREACHED(); 973 else 974 static_cast<HostDispatcher*>(dispatcher())->set_allow_plugin_reentrancy(); 975 976 result.Return(dispatcher(), enter.functions()->ExecuteScript( 977 instance, 978 script.Get(dispatcher()), 979 out_exception.OutParam(dispatcher()))); 980 } 981 982 void PPB_Instance_Proxy::OnHostMsgGetDefaultCharSet( 983 PP_Instance instance, 984 SerializedVarReturnValue result) { 985 if (!dispatcher()->permissions().HasPermission(PERMISSION_DEV)) 986 return; 987 EnterInstanceNoLock enter(instance); 988 if (enter.succeeded()) 989 result.Return(dispatcher(), enter.functions()->GetDefaultCharSet(instance)); 990 } 991 992 void PPB_Instance_Proxy::OnHostMsgSetPluginToHandleFindRequests( 993 PP_Instance instance) { 994 if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE)) 995 return; 996 EnterInstanceNoLock enter(instance); 997 if (enter.succeeded()) 998 enter.functions()->SetPluginToHandleFindRequests(instance); 999 } 1000 1001 void PPB_Instance_Proxy::OnHostMsgNumberOfFindResultsChanged( 1002 PP_Instance instance, 1003 int32_t total, 1004 PP_Bool final_result) { 1005 if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE)) 1006 return; 1007 EnterInstanceNoLock enter(instance); 1008 if (enter.succeeded()) { 1009 enter.functions()->NumberOfFindResultsChanged( 1010 instance, total, final_result); 1011 } 1012 } 1013 1014 void PPB_Instance_Proxy::OnHostMsgSelectFindResultChanged( 1015 PP_Instance instance, 1016 int32_t index) { 1017 if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE)) 1018 return; 1019 EnterInstanceNoLock enter(instance); 1020 if (enter.succeeded()) 1021 enter.functions()->SelectedFindResultChanged(instance, index); 1022 } 1023 1024 void PPB_Instance_Proxy::OnHostMsgSetTickmarks( 1025 PP_Instance instance, 1026 const std::vector<PP_Rect>& tickmarks) { 1027 if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE)) 1028 return; 1029 const PP_Rect* array = tickmarks.empty() ? NULL : &tickmarks[0]; 1030 EnterInstanceNoLock enter(instance); 1031 if (enter.succeeded()) { 1032 enter.functions()->SetTickmarks(instance, 1033 array, 1034 static_cast<uint32_t>(tickmarks.size())); 1035 } 1036 } 1037 1038 void PPB_Instance_Proxy::OnHostMsgSetFullscreen(PP_Instance instance, 1039 PP_Bool fullscreen, 1040 PP_Bool* result) { 1041 EnterInstanceNoLock enter(instance); 1042 if (enter.succeeded()) 1043 *result = enter.functions()->SetFullscreen(instance, fullscreen); 1044 } 1045 1046 1047 void PPB_Instance_Proxy::OnHostMsgGetScreenSize(PP_Instance instance, 1048 PP_Bool* result, 1049 PP_Size* size) { 1050 EnterInstanceNoLock enter(instance); 1051 if (enter.succeeded()) 1052 *result = enter.functions()->GetScreenSize(instance, size); 1053 } 1054 1055 void PPB_Instance_Proxy::OnHostMsgRequestInputEvents(PP_Instance instance, 1056 bool is_filtering, 1057 uint32_t event_classes) { 1058 EnterInstanceNoLock enter(instance); 1059 if (enter.succeeded()) { 1060 if (is_filtering) 1061 enter.functions()->RequestFilteringInputEvents(instance, event_classes); 1062 else 1063 enter.functions()->RequestInputEvents(instance, event_classes); 1064 } 1065 } 1066 1067 void PPB_Instance_Proxy::OnHostMsgClearInputEvents(PP_Instance instance, 1068 uint32_t event_classes) { 1069 EnterInstanceNoLock enter(instance); 1070 if (enter.succeeded()) 1071 enter.functions()->ClearInputEventRequest(instance, event_classes); 1072 } 1073 1074 void PPB_Instance_Proxy::OnHostMsgStartTrackingLatency(PP_Instance instance) { 1075 EnterInstanceNoLock enter(instance); 1076 if (enter.succeeded()) 1077 enter.functions()->StartTrackingLatency(instance); 1078 } 1079 1080 void PPB_Instance_Proxy::OnHostMsgPostMessage( 1081 PP_Instance instance, 1082 SerializedVarReceiveInput message) { 1083 EnterInstanceNoLock enter(instance); 1084 if (!message.is_valid_var()) { 1085 PpapiGlobals::Get()->LogWithSource( 1086 instance, PP_LOGLEVEL_ERROR, std::string(), kSerializationError); 1087 return; 1088 } 1089 1090 if (enter.succeeded()) 1091 enter.functions()->PostMessage(instance, 1092 message.GetForInstance(dispatcher(), 1093 instance)); 1094 } 1095 1096 void PPB_Instance_Proxy::OnHostMsgLockMouse(PP_Instance instance) { 1097 // Need to be careful to always issue the callback. 1098 pp::CompletionCallback cb = callback_factory_.NewCallback( 1099 &PPB_Instance_Proxy::MouseLockCompleteInHost, instance); 1100 1101 EnterInstanceNoLock enter(instance, cb.pp_completion_callback()); 1102 if (enter.succeeded()) 1103 enter.SetResult(enter.functions()->LockMouse(instance, enter.callback())); 1104 } 1105 1106 void PPB_Instance_Proxy::OnHostMsgUnlockMouse(PP_Instance instance) { 1107 EnterInstanceNoLock enter(instance); 1108 if (enter.succeeded()) 1109 enter.functions()->UnlockMouse(instance); 1110 } 1111 1112 void PPB_Instance_Proxy::OnHostMsgGetDocumentURL( 1113 PP_Instance instance, 1114 PP_URLComponents_Dev* components, 1115 SerializedVarReturnValue result) { 1116 if (!dispatcher()->permissions().HasPermission(PERMISSION_DEV)) 1117 return; 1118 EnterInstanceNoLock enter(instance); 1119 if (enter.succeeded()) { 1120 PP_Var document_url = enter.functions()->GetDocumentURL(instance, 1121 components); 1122 result.Return(dispatcher(), document_url); 1123 } 1124 } 1125 1126 void PPB_Instance_Proxy::OnHostMsgResolveRelativeToDocument( 1127 PP_Instance instance, 1128 SerializedVarReceiveInput relative, 1129 SerializedVarReturnValue result) { 1130 if (!dispatcher()->permissions().HasPermission(PERMISSION_DEV)) 1131 return; 1132 EnterInstanceNoLock enter(instance); 1133 if (enter.succeeded()) { 1134 result.Return(dispatcher(), 1135 enter.functions()->ResolveRelativeToDocument( 1136 instance, relative.Get(dispatcher()), NULL)); 1137 } 1138 } 1139 1140 void PPB_Instance_Proxy::OnHostMsgDocumentCanRequest( 1141 PP_Instance instance, 1142 SerializedVarReceiveInput url, 1143 PP_Bool* result) { 1144 if (!dispatcher()->permissions().HasPermission(PERMISSION_DEV)) 1145 return; 1146 EnterInstanceNoLock enter(instance); 1147 if (enter.succeeded()) { 1148 *result = enter.functions()->DocumentCanRequest(instance, 1149 url.Get(dispatcher())); 1150 } 1151 } 1152 1153 void PPB_Instance_Proxy::OnHostMsgDocumentCanAccessDocument(PP_Instance active, 1154 PP_Instance target, 1155 PP_Bool* result) { 1156 if (!dispatcher()->permissions().HasPermission(PERMISSION_DEV)) 1157 return; 1158 EnterInstanceNoLock enter(active); 1159 if (enter.succeeded()) 1160 *result = enter.functions()->DocumentCanAccessDocument(active, target); 1161 } 1162 1163 void PPB_Instance_Proxy::OnHostMsgGetPluginInstanceURL( 1164 PP_Instance instance, 1165 SerializedVarReturnValue result) { 1166 if (!dispatcher()->permissions().HasPermission(PERMISSION_DEV)) 1167 return; 1168 EnterInstanceNoLock enter(instance); 1169 if (enter.succeeded()) { 1170 result.Return(dispatcher(), 1171 enter.functions()->GetPluginInstanceURL(instance, NULL)); 1172 } 1173 } 1174 1175 void PPB_Instance_Proxy::OnHostMsgGetPluginReferrerURL( 1176 PP_Instance instance, 1177 SerializedVarReturnValue result) { 1178 if (!dispatcher()->permissions().HasPermission(PERMISSION_DEV)) 1179 return; 1180 EnterInstanceNoLock enter(instance); 1181 if (enter.succeeded()) { 1182 result.Return(dispatcher(), 1183 enter.functions()->GetPluginReferrerURL(instance, NULL)); 1184 } 1185 } 1186 1187 void PPB_Instance_Proxy::OnHostMsgPromiseResolved(PP_Instance instance, 1188 uint32_t promise_id) { 1189 if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE)) 1190 return; 1191 EnterInstanceNoLock enter(instance); 1192 if (enter.succeeded()) { 1193 enter.functions()->PromiseResolved(instance, promise_id); 1194 } 1195 } 1196 1197 void PPB_Instance_Proxy::OnHostMsgPromiseResolvedWithSession( 1198 PP_Instance instance, 1199 uint32_t promise_id, 1200 SerializedVarReceiveInput web_session_id) { 1201 if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE)) 1202 return; 1203 EnterInstanceNoLock enter(instance); 1204 if (enter.succeeded()) { 1205 enter.functions()->PromiseResolvedWithSession( 1206 instance, promise_id, web_session_id.Get(dispatcher())); 1207 } 1208 } 1209 1210 void PPB_Instance_Proxy::OnHostMsgPromiseRejected( 1211 PP_Instance instance, 1212 uint32_t promise_id, 1213 PP_CdmExceptionCode exception_code, 1214 uint32_t system_code, 1215 SerializedVarReceiveInput error_description) { 1216 if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE)) 1217 return; 1218 EnterInstanceNoLock enter(instance); 1219 if (enter.succeeded()) { 1220 enter.functions()->PromiseRejected(instance, 1221 promise_id, 1222 exception_code, 1223 system_code, 1224 error_description.Get(dispatcher())); 1225 } 1226 } 1227 1228 void PPB_Instance_Proxy::OnHostMsgSessionMessage( 1229 PP_Instance instance, 1230 SerializedVarReceiveInput web_session_id, 1231 SerializedVarReceiveInput message, 1232 SerializedVarReceiveInput destination_url) { 1233 if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE)) 1234 return; 1235 EnterInstanceNoLock enter(instance); 1236 if (enter.succeeded()) { 1237 enter.functions()->SessionMessage(instance, 1238 web_session_id.Get(dispatcher()), 1239 message.Get(dispatcher()), 1240 destination_url.Get(dispatcher())); 1241 } 1242 } 1243 1244 void PPB_Instance_Proxy::OnHostMsgSessionReady( 1245 PP_Instance instance, 1246 SerializedVarReceiveInput web_session_id) { 1247 if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE)) 1248 return; 1249 EnterInstanceNoLock enter(instance); 1250 if (enter.succeeded()) { 1251 enter.functions()->SessionReady(instance, web_session_id.Get(dispatcher())); 1252 } 1253 } 1254 1255 void PPB_Instance_Proxy::OnHostMsgSessionClosed( 1256 PP_Instance instance, 1257 SerializedVarReceiveInput web_session_id) { 1258 if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE)) 1259 return; 1260 EnterInstanceNoLock enter(instance); 1261 if (enter.succeeded()) { 1262 enter.functions()->SessionClosed(instance, 1263 web_session_id.Get(dispatcher())); 1264 } 1265 } 1266 1267 void PPB_Instance_Proxy::OnHostMsgSessionError( 1268 PP_Instance instance, 1269 SerializedVarReceiveInput web_session_id, 1270 PP_CdmExceptionCode exception_code, 1271 uint32_t system_code, 1272 SerializedVarReceiveInput error_description) { 1273 if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE)) 1274 return; 1275 EnterInstanceNoLock enter(instance); 1276 if (enter.succeeded()) { 1277 enter.functions()->SessionError(instance, 1278 web_session_id.Get(dispatcher()), 1279 exception_code, 1280 system_code, 1281 error_description.Get(dispatcher())); 1282 } 1283 } 1284 1285 void PPB_Instance_Proxy::OnHostMsgDeliverBlock( 1286 PP_Instance instance, 1287 PP_Resource decrypted_block, 1288 const std::string& serialized_block_info) { 1289 if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE)) 1290 return; 1291 PP_DecryptedBlockInfo block_info; 1292 if (!DeserializeBlockInfo(serialized_block_info, &block_info)) 1293 return; 1294 1295 EnterInstanceNoLock enter(instance); 1296 if (enter.succeeded()) 1297 enter.functions()->DeliverBlock(instance, decrypted_block, &block_info); 1298 } 1299 1300 void PPB_Instance_Proxy::OnHostMsgDecoderInitializeDone( 1301 PP_Instance instance, 1302 PP_DecryptorStreamType decoder_type, 1303 uint32_t request_id, 1304 PP_Bool success) { 1305 if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE)) 1306 return; 1307 EnterInstanceNoLock enter(instance); 1308 if (enter.succeeded()) { 1309 enter.functions()->DecoderInitializeDone(instance, 1310 decoder_type, 1311 request_id, 1312 success); 1313 } 1314 } 1315 1316 void PPB_Instance_Proxy::OnHostMsgDecoderDeinitializeDone( 1317 PP_Instance instance, 1318 PP_DecryptorStreamType decoder_type, 1319 uint32_t request_id) { 1320 if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE)) 1321 return; 1322 EnterInstanceNoLock enter(instance); 1323 if (enter.succeeded()) 1324 enter.functions()->DecoderDeinitializeDone(instance, 1325 decoder_type, 1326 request_id); 1327 } 1328 1329 void PPB_Instance_Proxy::OnHostMsgDecoderResetDone( 1330 PP_Instance instance, 1331 PP_DecryptorStreamType decoder_type, 1332 uint32_t request_id) { 1333 if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE)) 1334 return; 1335 EnterInstanceNoLock enter(instance); 1336 if (enter.succeeded()) 1337 enter.functions()->DecoderResetDone(instance, decoder_type, request_id); 1338 } 1339 1340 void PPB_Instance_Proxy::OnHostMsgDeliverFrame( 1341 PP_Instance instance, 1342 PP_Resource decrypted_frame, 1343 const std::string& serialized_frame_info) { 1344 if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE)) 1345 return; 1346 PP_DecryptedFrameInfo frame_info; 1347 if (!DeserializeBlockInfo(serialized_frame_info, &frame_info)) 1348 return; 1349 1350 EnterInstanceNoLock enter(instance); 1351 if (enter.succeeded()) 1352 enter.functions()->DeliverFrame(instance, decrypted_frame, &frame_info); 1353 } 1354 1355 void PPB_Instance_Proxy::OnHostMsgDeliverSamples( 1356 PP_Instance instance, 1357 PP_Resource audio_frames, 1358 const std::string& serialized_sample_info) { 1359 if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE)) 1360 return; 1361 PP_DecryptedSampleInfo sample_info; 1362 if (!DeserializeBlockInfo(serialized_sample_info, &sample_info)) 1363 return; 1364 1365 EnterInstanceNoLock enter(instance); 1366 if (enter.succeeded()) 1367 enter.functions()->DeliverSamples(instance, audio_frames, &sample_info); 1368 } 1369 1370 void PPB_Instance_Proxy::OnHostMsgSetCursor( 1371 PP_Instance instance, 1372 int32_t type, 1373 const ppapi::HostResource& custom_image, 1374 const PP_Point& hot_spot) { 1375 // This API serves PPB_CursorControl_Dev and PPB_MouseCursor, so is public. 1376 EnterInstanceNoLock enter(instance); 1377 if (enter.succeeded()) { 1378 enter.functions()->SetCursor( 1379 instance, static_cast<PP_MouseCursor_Type>(type), 1380 custom_image.host_resource(), &hot_spot); 1381 } 1382 } 1383 1384 void PPB_Instance_Proxy::OnHostMsgSetTextInputType(PP_Instance instance, 1385 PP_TextInput_Type type) { 1386 EnterInstanceNoLock enter(instance); 1387 if (enter.succeeded()) 1388 enter.functions()->SetTextInputType(instance, type); 1389 } 1390 1391 void PPB_Instance_Proxy::OnHostMsgUpdateCaretPosition( 1392 PP_Instance instance, 1393 const PP_Rect& caret, 1394 const PP_Rect& bounding_box) { 1395 EnterInstanceNoLock enter(instance); 1396 if (enter.succeeded()) 1397 enter.functions()->UpdateCaretPosition(instance, caret, bounding_box); 1398 } 1399 1400 void PPB_Instance_Proxy::OnHostMsgCancelCompositionText(PP_Instance instance) { 1401 EnterInstanceNoLock enter(instance); 1402 if (enter.succeeded()) 1403 enter.functions()->CancelCompositionText(instance); 1404 } 1405 1406 void PPB_Instance_Proxy::OnHostMsgUpdateSurroundingText( 1407 PP_Instance instance, 1408 const std::string& text, 1409 uint32_t caret, 1410 uint32_t anchor) { 1411 EnterInstanceNoLock enter(instance); 1412 if (enter.succeeded()) { 1413 enter.functions()->UpdateSurroundingText(instance, text.c_str(), caret, 1414 anchor); 1415 } 1416 } 1417 #endif // !defined(OS_NACL) 1418 1419 void PPB_Instance_Proxy::OnPluginMsgMouseLockComplete(PP_Instance instance, 1420 int32_t result) { 1421 if (!dispatcher()->IsPlugin()) 1422 return; 1423 1424 // Save the mouse callback on the instance data. 1425 InstanceData* data = static_cast<PluginDispatcher*>(dispatcher())-> 1426 GetInstanceData(instance); 1427 if (!data) 1428 return; // Instance was probably deleted. 1429 if (!TrackedCallback::IsPending(data->mouse_lock_callback)) { 1430 NOTREACHED(); 1431 return; 1432 } 1433 data->mouse_lock_callback->Run(result); 1434 } 1435 1436 #if !defined(OS_NACL) 1437 void PPB_Instance_Proxy::MouseLockCompleteInHost(int32_t result, 1438 PP_Instance instance) { 1439 dispatcher()->Send(new PpapiMsg_PPBInstance_MouseLockComplete( 1440 API_ID_PPB_INSTANCE, instance, result)); 1441 } 1442 #endif // !defined(OS_NACL) 1443 1444 void PPB_Instance_Proxy::CancelAnyPendingRequestSurroundingText( 1445 PP_Instance instance) { 1446 InstanceData* data = static_cast<PluginDispatcher*>(dispatcher())-> 1447 GetInstanceData(instance); 1448 if (!data) 1449 return; // Instance was probably deleted. 1450 data->should_do_request_surrounding_text = false; 1451 } 1452 1453 } // namespace proxy 1454 } // namespace ppapi 1455