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 "media/base/limits.h" 10 #include "ppapi/c/pp_errors.h" 11 #include "ppapi/c/pp_time.h" 12 #include "ppapi/c/pp_var.h" 13 #include "ppapi/c/ppb_audio_config.h" 14 #include "ppapi/c/ppb_instance.h" 15 #include "ppapi/c/ppb_messaging.h" 16 #include "ppapi/c/ppb_mouse_lock.h" 17 #include "ppapi/c/private/pp_content_decryptor.h" 18 #include "ppapi/proxy/broker_resource.h" 19 #include "ppapi/proxy/browser_font_singleton_resource.h" 20 #include "ppapi/proxy/content_decryptor_private_serializer.h" 21 #include "ppapi/proxy/enter_proxy.h" 22 #include "ppapi/proxy/file_mapping_resource.h" 23 #include "ppapi/proxy/flash_clipboard_resource.h" 24 #include "ppapi/proxy/flash_file_resource.h" 25 #include "ppapi/proxy/flash_fullscreen_resource.h" 26 #include "ppapi/proxy/flash_resource.h" 27 #include "ppapi/proxy/gamepad_resource.h" 28 #include "ppapi/proxy/host_dispatcher.h" 29 #include "ppapi/proxy/isolated_file_system_private_resource.h" 30 #include "ppapi/proxy/message_handler.h" 31 #include "ppapi/proxy/network_proxy_resource.h" 32 #include "ppapi/proxy/pdf_resource.h" 33 #include "ppapi/proxy/plugin_dispatcher.h" 34 #include "ppapi/proxy/ppapi_messages.h" 35 #include "ppapi/proxy/serialized_var.h" 36 #include "ppapi/proxy/truetype_font_singleton_resource.h" 37 #include "ppapi/proxy/uma_private_resource.h" 38 #include "ppapi/shared_impl/array_var.h" 39 #include "ppapi/shared_impl/ppapi_globals.h" 40 #include "ppapi/shared_impl/ppb_url_util_shared.h" 41 #include "ppapi/shared_impl/ppb_view_shared.h" 42 #include "ppapi/shared_impl/scoped_pp_var.h" 43 #include "ppapi/shared_impl/var.h" 44 #include "ppapi/thunk/enter.h" 45 #include "ppapi/thunk/ppb_compositor_api.h" 46 #include "ppapi/thunk/ppb_graphics_2d_api.h" 47 #include "ppapi/thunk/ppb_graphics_3d_api.h" 48 #include "ppapi/thunk/thunk.h" 49 50 // Windows headers interfere with this file. 51 #ifdef PostMessage 52 #undef PostMessage 53 #endif 54 55 using ppapi::thunk::EnterInstanceNoLock; 56 using ppapi::thunk::EnterResourceNoLock; 57 using ppapi::thunk::PPB_Compositor_API; 58 using ppapi::thunk::PPB_Graphics2D_API; 59 using ppapi::thunk::PPB_Graphics3D_API; 60 using ppapi::thunk::PPB_Instance_API; 61 62 namespace ppapi { 63 namespace proxy { 64 65 namespace { 66 67 #if !defined(OS_NACL) 68 const char kSerializationError[] = "Failed to convert a PostMessage " 69 "argument from a PP_Var to a Javascript value. It may have cycles or be of " 70 "an unsupported type."; 71 #endif 72 73 void RequestSurroundingText(PP_Instance instance) { 74 PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance); 75 if (!dispatcher) 76 return; // Instance has gone away while message was pending. 77 78 InstanceData* data = dispatcher->GetInstanceData(instance); 79 DCHECK(data); // Should have it, since we still have a dispatcher. 80 data->is_request_surrounding_text_pending = false; 81 if (!data->should_do_request_surrounding_text) 82 return; 83 84 // Just fake out a RequestSurroundingText message to the proxy for the PPP 85 // interface. 86 InterfaceProxy* proxy = dispatcher->GetInterfaceProxy(API_ID_PPP_TEXT_INPUT); 87 if (!proxy) 88 return; 89 proxy->OnMessageReceived(PpapiMsg_PPPTextInput_RequestSurroundingText( 90 API_ID_PPP_TEXT_INPUT, instance, 91 PPB_Instance_Shared::kExtraCharsForTextInput)); 92 } 93 94 } // namespace 95 96 PPB_Instance_Proxy::PPB_Instance_Proxy(Dispatcher* dispatcher) 97 : InterfaceProxy(dispatcher), 98 callback_factory_(this) { 99 } 100 101 PPB_Instance_Proxy::~PPB_Instance_Proxy() { 102 } 103 104 bool PPB_Instance_Proxy::OnMessageReceived(const IPC::Message& msg) { 105 // Prevent the dispatcher from going away during a call to ExecuteScript. 106 // This must happen OUTSIDE of ExecuteScript since the SerializedVars use 107 // the dispatcher upon return of the function (converting the 108 // SerializedVarReturnValue/OutParam to a SerializedVar in the destructor). 109 #if !defined(OS_NACL) 110 ScopedModuleReference death_grip(dispatcher()); 111 #endif 112 113 bool handled = true; 114 IPC_BEGIN_MESSAGE_MAP(PPB_Instance_Proxy, msg) 115 #if !defined(OS_NACL) 116 // Plugin -> Host messages. 117 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_GetWindowObject, 118 OnHostMsgGetWindowObject) 119 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_GetOwnerElementObject, 120 OnHostMsgGetOwnerElementObject) 121 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_BindGraphics, 122 OnHostMsgBindGraphics) 123 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_IsFullFrame, 124 OnHostMsgIsFullFrame) 125 IPC_MESSAGE_HANDLER( 126 PpapiHostMsg_PPBInstance_GetAudioHardwareOutputSampleRate, 127 OnHostMsgGetAudioHardwareOutputSampleRate) 128 IPC_MESSAGE_HANDLER( 129 PpapiHostMsg_PPBInstance_GetAudioHardwareOutputBufferSize, 130 OnHostMsgGetAudioHardwareOutputBufferSize) 131 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_ExecuteScript, 132 OnHostMsgExecuteScript) 133 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_GetDefaultCharSet, 134 OnHostMsgGetDefaultCharSet) 135 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_SetPluginToHandleFindRequests, 136 OnHostMsgSetPluginToHandleFindRequests); 137 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_NumberOfFindResultsChanged, 138 OnHostMsgNumberOfFindResultsChanged) 139 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_SelectFindResultChanged, 140 OnHostMsgSelectFindResultChanged) 141 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_SetTickmarks, 142 OnHostMsgSetTickmarks) 143 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_PostMessage, 144 OnHostMsgPostMessage) 145 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_SetFullscreen, 146 OnHostMsgSetFullscreen) 147 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_GetScreenSize, 148 OnHostMsgGetScreenSize) 149 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_RequestInputEvents, 150 OnHostMsgRequestInputEvents) 151 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_ClearInputEvents, 152 OnHostMsgClearInputEvents) 153 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_StartTrackingLatency, 154 OnHostMsgStartTrackingLatency) 155 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_LockMouse, 156 OnHostMsgLockMouse) 157 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_UnlockMouse, 158 OnHostMsgUnlockMouse) 159 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_SetCursor, 160 OnHostMsgSetCursor) 161 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_SetTextInputType, 162 OnHostMsgSetTextInputType) 163 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_UpdateCaretPosition, 164 OnHostMsgUpdateCaretPosition) 165 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_CancelCompositionText, 166 OnHostMsgCancelCompositionText) 167 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_UpdateSurroundingText, 168 OnHostMsgUpdateSurroundingText) 169 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_GetDocumentURL, 170 OnHostMsgGetDocumentURL) 171 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_ResolveRelativeToDocument, 172 OnHostMsgResolveRelativeToDocument) 173 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_DocumentCanRequest, 174 OnHostMsgDocumentCanRequest) 175 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_DocumentCanAccessDocument, 176 OnHostMsgDocumentCanAccessDocument) 177 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_GetPluginInstanceURL, 178 OnHostMsgGetPluginInstanceURL) 179 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_GetPluginReferrerURL, 180 OnHostMsgGetPluginReferrerURL) 181 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_PromiseResolved, 182 OnHostMsgPromiseResolved) 183 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_PromiseResolvedWithSession, 184 OnHostMsgPromiseResolvedWithSession) 185 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_PromiseResolvedWithKeyIds, 186 OnHostMsgPromiseResolvedWithKeyIds) 187 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_PromiseRejected, 188 OnHostMsgPromiseRejected) 189 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_SessionMessage, 190 OnHostMsgSessionMessage) 191 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_SessionKeysChange, 192 OnHostMsgSessionKeysChange) 193 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_SessionExpirationChange, 194 OnHostMsgSessionExpirationChange) 195 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_SessionReady, 196 OnHostMsgSessionReady) 197 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_SessionClosed, 198 OnHostMsgSessionClosed) 199 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_SessionError, 200 OnHostMsgSessionError) 201 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_DeliverBlock, 202 OnHostMsgDeliverBlock) 203 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_DecoderInitializeDone, 204 OnHostMsgDecoderInitializeDone) 205 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_DecoderDeinitializeDone, 206 OnHostMsgDecoderDeinitializeDone) 207 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_DecoderResetDone, 208 OnHostMsgDecoderResetDone) 209 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_DeliverFrame, 210 OnHostMsgDeliverFrame) 211 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_DeliverSamples, 212 OnHostMsgDeliverSamples) 213 #endif // !defined(OS_NACL) 214 215 // Host -> Plugin messages. 216 IPC_MESSAGE_HANDLER(PpapiMsg_PPBInstance_MouseLockComplete, 217 OnPluginMsgMouseLockComplete) 218 219 IPC_MESSAGE_UNHANDLED(handled = false) 220 IPC_END_MESSAGE_MAP() 221 return handled; 222 } 223 224 PP_Bool PPB_Instance_Proxy::BindGraphics(PP_Instance instance, 225 PP_Resource device) { 226 // If device is 0, pass a null HostResource. This signals the host to unbind 227 // all devices. 228 PP_Resource pp_resource = 0; 229 if (device) { 230 Resource* resource = 231 PpapiGlobals::Get()->GetResourceTracker()->GetResource(device); 232 if (!resource || resource->pp_instance() != instance) 233 return PP_FALSE; 234 // We need to pass different resource to Graphics 2D, 3D and Compositor 235 // right now. Once 3D is migrated to the new design, we should be able to 236 // unify this. 237 if (resource->AsPPB_Graphics3D_API()) { 238 pp_resource = resource->host_resource().host_resource(); 239 } else if (resource->AsPPB_Graphics2D_API() || 240 resource->AsPPB_Compositor_API()) { 241 pp_resource = resource->pp_resource(); 242 } else { 243 // A bad resource. 244 return PP_FALSE; 245 } 246 } 247 dispatcher()->Send(new PpapiHostMsg_PPBInstance_BindGraphics( 248 API_ID_PPB_INSTANCE, instance, pp_resource)); 249 return PP_TRUE; 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 = {{0}}; 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::PromiseResolvedWithKeyIds(PP_Instance instance, 590 uint32 promise_id, 591 PP_Var key_ids_var) { 592 ArrayVar* key_ids_array = ArrayVar::FromPPVar(key_ids_var); 593 if (!key_ids_array || 594 key_ids_array->GetLength() > media::limits::kMaxKeyIds) { 595 NOTREACHED(); 596 return; 597 } 598 599 std::vector<std::vector<uint8_t> > key_ids; 600 for (size_t i = 0; i < key_ids_array->GetLength(); ++i) { 601 ArrayBufferVar* key_id = ArrayBufferVar::FromPPVar(key_ids_array->Get(i)); 602 if (!key_id || key_id->ByteLength() < media::limits::kMinKeyIdLength || 603 key_id->ByteLength() > media::limits::kMaxKeyIdLength) { 604 NOTREACHED(); 605 continue; 606 } 607 608 const uint8_t* key_id_ptr = static_cast<const uint8_t*>(key_id->Map()); 609 const uint32_t key_id_size = key_id->ByteLength(); 610 std::vector<uint8_t> key_id_vector(key_id_ptr, key_id_ptr + key_id_size); 611 key_ids.push_back(key_id_vector); 612 } 613 614 dispatcher()->Send(new PpapiHostMsg_PPBInstance_PromiseResolvedWithKeyIds( 615 API_ID_PPB_INSTANCE, instance, promise_id, key_ids)); 616 } 617 618 void PPB_Instance_Proxy::PromiseRejected(PP_Instance instance, 619 uint32 promise_id, 620 PP_CdmExceptionCode exception_code, 621 uint32 system_code, 622 PP_Var error_description_var) { 623 dispatcher()->Send(new PpapiHostMsg_PPBInstance_PromiseRejected( 624 API_ID_PPB_INSTANCE, 625 instance, 626 promise_id, 627 exception_code, 628 system_code, 629 SerializedVarSendInput(dispatcher(), error_description_var))); 630 } 631 632 void PPB_Instance_Proxy::SessionMessage(PP_Instance instance, 633 PP_Var web_session_id_var, 634 PP_Var message_var, 635 PP_Var destination_url_var) { 636 dispatcher()->Send(new PpapiHostMsg_PPBInstance_SessionMessage( 637 API_ID_PPB_INSTANCE, 638 instance, 639 SerializedVarSendInput(dispatcher(), web_session_id_var), 640 SerializedVarSendInput(dispatcher(), message_var), 641 SerializedVarSendInput(dispatcher(), destination_url_var))); 642 } 643 644 void PPB_Instance_Proxy::SessionKeysChange(PP_Instance instance, 645 PP_Var web_session_id_var, 646 PP_Bool has_additional_usable_key) { 647 StringVar* session_id = StringVar::FromPPVar(web_session_id_var); 648 if (!session_id || 649 session_id->value().length() > media::limits::kMaxWebSessionIdLength) { 650 NOTREACHED(); 651 return; 652 } 653 654 dispatcher()->Send(new PpapiHostMsg_PPBInstance_SessionKeysChange( 655 API_ID_PPB_INSTANCE, 656 instance, 657 session_id->value(), 658 has_additional_usable_key)); 659 } 660 661 void PPB_Instance_Proxy::SessionExpirationChange(PP_Instance instance, 662 PP_Var web_session_id_var, 663 PP_Time new_expiry_time) { 664 StringVar* session_id = StringVar::FromPPVar(web_session_id_var); 665 if (!session_id || 666 session_id->value().length() > media::limits::kMaxWebSessionIdLength) { 667 NOTREACHED(); 668 return; 669 } 670 671 dispatcher()->Send(new PpapiHostMsg_PPBInstance_SessionExpirationChange( 672 API_ID_PPB_INSTANCE, instance, session_id->value(), new_expiry_time)); 673 } 674 675 void PPB_Instance_Proxy::SessionReady(PP_Instance instance, 676 PP_Var web_session_id_var) { 677 dispatcher()->Send(new PpapiHostMsg_PPBInstance_SessionReady( 678 API_ID_PPB_INSTANCE, 679 instance, 680 SerializedVarSendInput(dispatcher(), web_session_id_var))); 681 } 682 683 void PPB_Instance_Proxy::SessionClosed(PP_Instance instance, 684 PP_Var web_session_id_var) { 685 dispatcher()->Send(new PpapiHostMsg_PPBInstance_SessionClosed( 686 API_ID_PPB_INSTANCE, 687 instance, 688 SerializedVarSendInput(dispatcher(), web_session_id_var))); 689 } 690 691 void PPB_Instance_Proxy::SessionError(PP_Instance instance, 692 PP_Var web_session_id_var, 693 PP_CdmExceptionCode exception_code, 694 uint32 system_code, 695 PP_Var error_description_var) { 696 dispatcher()->Send(new PpapiHostMsg_PPBInstance_SessionError( 697 API_ID_PPB_INSTANCE, 698 instance, 699 SerializedVarSendInput(dispatcher(), web_session_id_var), 700 exception_code, 701 system_code, 702 SerializedVarSendInput(dispatcher(), error_description_var))); 703 } 704 705 void PPB_Instance_Proxy::DeliverBlock(PP_Instance instance, 706 PP_Resource decrypted_block, 707 const PP_DecryptedBlockInfo* block_info) { 708 PP_Resource decrypted_block_host_resource = 0; 709 710 if (decrypted_block) { 711 Resource* object = 712 PpapiGlobals::Get()->GetResourceTracker()->GetResource(decrypted_block); 713 if (!object || object->pp_instance() != instance) { 714 NOTREACHED(); 715 return; 716 } 717 decrypted_block_host_resource = object->host_resource().host_resource(); 718 } 719 720 std::string serialized_block_info; 721 if (!SerializeBlockInfo(*block_info, &serialized_block_info)) { 722 NOTREACHED(); 723 return; 724 } 725 726 dispatcher()->Send( 727 new PpapiHostMsg_PPBInstance_DeliverBlock(API_ID_PPB_INSTANCE, 728 instance, 729 decrypted_block_host_resource, 730 serialized_block_info)); 731 } 732 733 void PPB_Instance_Proxy::DecoderInitializeDone( 734 PP_Instance instance, 735 PP_DecryptorStreamType decoder_type, 736 uint32_t request_id, 737 PP_Bool success) { 738 dispatcher()->Send( 739 new PpapiHostMsg_PPBInstance_DecoderInitializeDone( 740 API_ID_PPB_INSTANCE, 741 instance, 742 decoder_type, 743 request_id, 744 success)); 745 } 746 747 void PPB_Instance_Proxy::DecoderDeinitializeDone( 748 PP_Instance instance, 749 PP_DecryptorStreamType decoder_type, 750 uint32_t request_id) { 751 dispatcher()->Send( 752 new PpapiHostMsg_PPBInstance_DecoderDeinitializeDone( 753 API_ID_PPB_INSTANCE, 754 instance, 755 decoder_type, 756 request_id)); 757 } 758 759 void PPB_Instance_Proxy::DecoderResetDone(PP_Instance instance, 760 PP_DecryptorStreamType decoder_type, 761 uint32_t request_id) { 762 dispatcher()->Send( 763 new PpapiHostMsg_PPBInstance_DecoderResetDone( 764 API_ID_PPB_INSTANCE, 765 instance, 766 decoder_type, 767 request_id)); 768 } 769 770 void PPB_Instance_Proxy::DeliverFrame(PP_Instance instance, 771 PP_Resource decrypted_frame, 772 const PP_DecryptedFrameInfo* frame_info) { 773 PP_Resource host_resource = 0; 774 if (decrypted_frame != 0) { 775 ResourceTracker* tracker = PpapiGlobals::Get()->GetResourceTracker(); 776 Resource* object = tracker->GetResource(decrypted_frame); 777 778 if (!object || object->pp_instance() != instance) { 779 NOTREACHED(); 780 return; 781 } 782 783 host_resource = object->host_resource().host_resource(); 784 } 785 786 std::string serialized_frame_info; 787 if (!SerializeBlockInfo(*frame_info, &serialized_frame_info)) { 788 NOTREACHED(); 789 return; 790 } 791 792 dispatcher()->Send( 793 new PpapiHostMsg_PPBInstance_DeliverFrame(API_ID_PPB_INSTANCE, 794 instance, 795 host_resource, 796 serialized_frame_info)); 797 } 798 799 void PPB_Instance_Proxy::DeliverSamples( 800 PP_Instance instance, 801 PP_Resource decrypted_samples, 802 const PP_DecryptedSampleInfo* sample_info) { 803 PP_Resource host_resource = 0; 804 if (decrypted_samples != 0) { 805 ResourceTracker* tracker = PpapiGlobals::Get()->GetResourceTracker(); 806 Resource* object = tracker->GetResource(decrypted_samples); 807 808 if (!object || object->pp_instance() != instance) { 809 NOTREACHED(); 810 return; 811 } 812 813 host_resource = object->host_resource().host_resource(); 814 } 815 816 std::string serialized_sample_info; 817 if (!SerializeBlockInfo(*sample_info, &serialized_sample_info)) { 818 NOTREACHED(); 819 return; 820 } 821 822 dispatcher()->Send( 823 new PpapiHostMsg_PPBInstance_DeliverSamples(API_ID_PPB_INSTANCE, 824 instance, 825 host_resource, 826 serialized_sample_info)); 827 } 828 #endif // !defined(OS_NACL) 829 830 void PPB_Instance_Proxy::PostMessage(PP_Instance instance, 831 PP_Var message) { 832 dispatcher()->Send(new PpapiHostMsg_PPBInstance_PostMessage( 833 API_ID_PPB_INSTANCE, 834 instance, SerializedVarSendInputShmem(dispatcher(), message, 835 instance))); 836 } 837 838 int32_t PPB_Instance_Proxy::RegisterMessageHandler( 839 PP_Instance instance, 840 void* user_data, 841 const PPP_MessageHandler_0_2* handler, 842 PP_Resource message_loop) { 843 InstanceData* data = 844 static_cast<PluginDispatcher*>(dispatcher())->GetInstanceData(instance); 845 if (!data) 846 return PP_ERROR_BADARGUMENT; 847 848 int32_t result = PP_ERROR_FAILED; 849 scoped_ptr<MessageHandler> message_handler = MessageHandler::Create( 850 instance, handler, user_data, message_loop, &result); 851 if (message_handler) 852 data->message_handler = message_handler.Pass(); 853 return result; 854 } 855 856 // TODO(dmichael): Remove this. crbug.com/414398 857 int32_t PPB_Instance_Proxy::RegisterMessageHandler_1_1_Deprecated( 858 PP_Instance instance, 859 void* user_data, 860 const PPP_MessageHandler_0_1_Deprecated* handler, 861 PP_Resource message_loop) { 862 InstanceData* data = 863 static_cast<PluginDispatcher*>(dispatcher())->GetInstanceData(instance); 864 if (!data) 865 return PP_ERROR_BADARGUMENT; 866 867 int32_t result = PP_ERROR_FAILED; 868 scoped_ptr<MessageHandler> message_handler = MessageHandler::CreateDeprecated( 869 instance, handler, user_data, message_loop, &result); 870 if (message_handler) 871 data->message_handler = message_handler.Pass(); 872 return result; 873 } 874 875 void PPB_Instance_Proxy::UnregisterMessageHandler(PP_Instance instance) { 876 InstanceData* data = 877 static_cast<PluginDispatcher*>(dispatcher())->GetInstanceData(instance); 878 if (!data) 879 return; 880 data->message_handler.reset(); 881 } 882 883 PP_Bool PPB_Instance_Proxy::SetCursor(PP_Instance instance, 884 PP_MouseCursor_Type type, 885 PP_Resource image, 886 const PP_Point* hot_spot) { 887 // Some of these parameters are important for security. This check is in the 888 // plugin process just for the convenience of the caller (since we don't 889 // bother returning errors from the other process with a sync message). The 890 // parameters will be validated again in the renderer. 891 if (!ValidateSetCursorParams(type, image, hot_spot)) 892 return PP_FALSE; 893 894 HostResource image_host_resource; 895 if (image) { 896 Resource* cursor_image = 897 PpapiGlobals::Get()->GetResourceTracker()->GetResource(image); 898 if (!cursor_image || cursor_image->pp_instance() != instance) 899 return PP_FALSE; 900 image_host_resource = cursor_image->host_resource(); 901 } 902 903 dispatcher()->Send(new PpapiHostMsg_PPBInstance_SetCursor( 904 API_ID_PPB_INSTANCE, instance, static_cast<int32_t>(type), 905 image_host_resource, hot_spot ? *hot_spot : PP_MakePoint(0, 0))); 906 return PP_TRUE; 907 } 908 909 int32_t PPB_Instance_Proxy::LockMouse(PP_Instance instance, 910 scoped_refptr<TrackedCallback> callback) { 911 // Save the mouse callback on the instance data. 912 InstanceData* data = static_cast<PluginDispatcher*>(dispatcher())-> 913 GetInstanceData(instance); 914 if (!data) 915 return PP_ERROR_BADARGUMENT; 916 if (TrackedCallback::IsPending(data->mouse_lock_callback)) 917 return PP_ERROR_INPROGRESS; // Already have a pending callback. 918 data->mouse_lock_callback = callback; 919 920 dispatcher()->Send(new PpapiHostMsg_PPBInstance_LockMouse( 921 API_ID_PPB_INSTANCE, instance)); 922 return PP_OK_COMPLETIONPENDING; 923 } 924 925 void PPB_Instance_Proxy::UnlockMouse(PP_Instance instance) { 926 dispatcher()->Send(new PpapiHostMsg_PPBInstance_UnlockMouse( 927 API_ID_PPB_INSTANCE, instance)); 928 } 929 930 void PPB_Instance_Proxy::SetTextInputType(PP_Instance instance, 931 PP_TextInput_Type type) { 932 CancelAnyPendingRequestSurroundingText(instance); 933 dispatcher()->Send(new PpapiHostMsg_PPBInstance_SetTextInputType( 934 API_ID_PPB_INSTANCE, instance, type)); 935 } 936 937 void PPB_Instance_Proxy::UpdateCaretPosition(PP_Instance instance, 938 const PP_Rect& caret, 939 const PP_Rect& bounding_box) { 940 dispatcher()->Send(new PpapiHostMsg_PPBInstance_UpdateCaretPosition( 941 API_ID_PPB_INSTANCE, instance, caret, bounding_box)); 942 } 943 944 void PPB_Instance_Proxy::CancelCompositionText(PP_Instance instance) { 945 CancelAnyPendingRequestSurroundingText(instance); 946 dispatcher()->Send(new PpapiHostMsg_PPBInstance_CancelCompositionText( 947 API_ID_PPB_INSTANCE, instance)); 948 } 949 950 void PPB_Instance_Proxy::SelectionChanged(PP_Instance instance) { 951 // The "right" way to do this is to send the message to the host. However, 952 // all it will do is call RequestSurroundingText with a hardcoded number of 953 // characters in response, which is an entire IPC round-trip. 954 // 955 // We can avoid this round-trip by just implementing the 956 // RequestSurroundingText logic in the plugin process. If the logic in the 957 // host becomes more complex (like a more adaptive number of characters), 958 // we'll need to reevanuate whether we want to do the round trip instead. 959 // 960 // Be careful to post a task to avoid reentering the plugin. 961 962 InstanceData* data = 963 static_cast<PluginDispatcher*>(dispatcher())->GetInstanceData(instance); 964 if (!data) 965 return; 966 data->should_do_request_surrounding_text = true; 967 968 if (!data->is_request_surrounding_text_pending) { 969 base::MessageLoop::current()->PostTask( 970 FROM_HERE, 971 RunWhileLocked(base::Bind(&RequestSurroundingText, instance))); 972 data->is_request_surrounding_text_pending = true; 973 } 974 } 975 976 void PPB_Instance_Proxy::UpdateSurroundingText(PP_Instance instance, 977 const char* text, 978 uint32_t caret, 979 uint32_t anchor) { 980 dispatcher()->Send(new PpapiHostMsg_PPBInstance_UpdateSurroundingText( 981 API_ID_PPB_INSTANCE, instance, text, caret, anchor)); 982 } 983 984 #if !defined(OS_NACL) 985 void PPB_Instance_Proxy::OnHostMsgGetWindowObject( 986 PP_Instance instance, 987 SerializedVarReturnValue result) { 988 if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE)) 989 return; 990 EnterInstanceNoLock enter(instance); 991 if (enter.succeeded()) 992 result.Return(dispatcher(), enter.functions()->GetWindowObject(instance)); 993 } 994 995 void PPB_Instance_Proxy::OnHostMsgGetOwnerElementObject( 996 PP_Instance instance, 997 SerializedVarReturnValue result) { 998 if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE)) 999 return; 1000 EnterInstanceNoLock enter(instance); 1001 if (enter.succeeded()) { 1002 result.Return(dispatcher(), 1003 enter.functions()->GetOwnerElementObject(instance)); 1004 } 1005 } 1006 1007 void PPB_Instance_Proxy::OnHostMsgBindGraphics(PP_Instance instance, 1008 PP_Resource device) { 1009 // Note that we ignroe the return value here. Otherwise, this would need to 1010 // be a slow sync call, and the plugin side of the proxy will have already 1011 // validated the resources, so we shouldn't see errors here that weren't 1012 // already caught. 1013 EnterInstanceNoLock enter(instance); 1014 if (enter.succeeded()) 1015 enter.functions()->BindGraphics(instance, device); 1016 } 1017 1018 void PPB_Instance_Proxy::OnHostMsgGetAudioHardwareOutputSampleRate( 1019 PP_Instance instance, uint32_t* result) { 1020 EnterInstanceNoLock enter(instance); 1021 if (enter.succeeded()) 1022 *result = enter.functions()->GetAudioHardwareOutputSampleRate(instance); 1023 } 1024 1025 void PPB_Instance_Proxy::OnHostMsgGetAudioHardwareOutputBufferSize( 1026 PP_Instance instance, uint32_t* result) { 1027 EnterInstanceNoLock enter(instance); 1028 if (enter.succeeded()) 1029 *result = enter.functions()->GetAudioHardwareOutputBufferSize(instance); 1030 } 1031 1032 void PPB_Instance_Proxy::OnHostMsgIsFullFrame(PP_Instance instance, 1033 PP_Bool* result) { 1034 EnterInstanceNoLock enter(instance); 1035 if (enter.succeeded()) 1036 *result = enter.functions()->IsFullFrame(instance); 1037 } 1038 1039 void PPB_Instance_Proxy::OnHostMsgExecuteScript( 1040 PP_Instance instance, 1041 SerializedVarReceiveInput script, 1042 SerializedVarOutParam out_exception, 1043 SerializedVarReturnValue result) { 1044 if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE)) 1045 return; 1046 EnterInstanceNoLock enter(instance); 1047 if (enter.failed()) 1048 return; 1049 1050 if (dispatcher()->IsPlugin()) 1051 NOTREACHED(); 1052 else 1053 static_cast<HostDispatcher*>(dispatcher())->set_allow_plugin_reentrancy(); 1054 1055 result.Return(dispatcher(), enter.functions()->ExecuteScript( 1056 instance, 1057 script.Get(dispatcher()), 1058 out_exception.OutParam(dispatcher()))); 1059 } 1060 1061 void PPB_Instance_Proxy::OnHostMsgGetDefaultCharSet( 1062 PP_Instance instance, 1063 SerializedVarReturnValue result) { 1064 if (!dispatcher()->permissions().HasPermission(PERMISSION_DEV)) 1065 return; 1066 EnterInstanceNoLock enter(instance); 1067 if (enter.succeeded()) 1068 result.Return(dispatcher(), enter.functions()->GetDefaultCharSet(instance)); 1069 } 1070 1071 void PPB_Instance_Proxy::OnHostMsgSetPluginToHandleFindRequests( 1072 PP_Instance instance) { 1073 if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE)) 1074 return; 1075 EnterInstanceNoLock enter(instance); 1076 if (enter.succeeded()) 1077 enter.functions()->SetPluginToHandleFindRequests(instance); 1078 } 1079 1080 void PPB_Instance_Proxy::OnHostMsgNumberOfFindResultsChanged( 1081 PP_Instance instance, 1082 int32_t total, 1083 PP_Bool final_result) { 1084 if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE)) 1085 return; 1086 EnterInstanceNoLock enter(instance); 1087 if (enter.succeeded()) { 1088 enter.functions()->NumberOfFindResultsChanged( 1089 instance, total, final_result); 1090 } 1091 } 1092 1093 void PPB_Instance_Proxy::OnHostMsgSelectFindResultChanged( 1094 PP_Instance instance, 1095 int32_t index) { 1096 if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE)) 1097 return; 1098 EnterInstanceNoLock enter(instance); 1099 if (enter.succeeded()) 1100 enter.functions()->SelectedFindResultChanged(instance, index); 1101 } 1102 1103 void PPB_Instance_Proxy::OnHostMsgSetTickmarks( 1104 PP_Instance instance, 1105 const std::vector<PP_Rect>& tickmarks) { 1106 if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE)) 1107 return; 1108 const PP_Rect* array = tickmarks.empty() ? NULL : &tickmarks[0]; 1109 EnterInstanceNoLock enter(instance); 1110 if (enter.succeeded()) { 1111 enter.functions()->SetTickmarks(instance, 1112 array, 1113 static_cast<uint32_t>(tickmarks.size())); 1114 } 1115 } 1116 1117 void PPB_Instance_Proxy::OnHostMsgSetFullscreen(PP_Instance instance, 1118 PP_Bool fullscreen, 1119 PP_Bool* result) { 1120 EnterInstanceNoLock enter(instance); 1121 if (enter.succeeded()) 1122 *result = enter.functions()->SetFullscreen(instance, fullscreen); 1123 } 1124 1125 1126 void PPB_Instance_Proxy::OnHostMsgGetScreenSize(PP_Instance instance, 1127 PP_Bool* result, 1128 PP_Size* size) { 1129 EnterInstanceNoLock enter(instance); 1130 if (enter.succeeded()) 1131 *result = enter.functions()->GetScreenSize(instance, size); 1132 } 1133 1134 void PPB_Instance_Proxy::OnHostMsgRequestInputEvents(PP_Instance instance, 1135 bool is_filtering, 1136 uint32_t event_classes) { 1137 EnterInstanceNoLock enter(instance); 1138 if (enter.succeeded()) { 1139 if (is_filtering) 1140 enter.functions()->RequestFilteringInputEvents(instance, event_classes); 1141 else 1142 enter.functions()->RequestInputEvents(instance, event_classes); 1143 } 1144 } 1145 1146 void PPB_Instance_Proxy::OnHostMsgClearInputEvents(PP_Instance instance, 1147 uint32_t event_classes) { 1148 EnterInstanceNoLock enter(instance); 1149 if (enter.succeeded()) 1150 enter.functions()->ClearInputEventRequest(instance, event_classes); 1151 } 1152 1153 void PPB_Instance_Proxy::OnHostMsgStartTrackingLatency(PP_Instance instance) { 1154 EnterInstanceNoLock enter(instance); 1155 if (enter.succeeded()) 1156 enter.functions()->StartTrackingLatency(instance); 1157 } 1158 1159 void PPB_Instance_Proxy::OnHostMsgPostMessage( 1160 PP_Instance instance, 1161 SerializedVarReceiveInput message) { 1162 EnterInstanceNoLock enter(instance); 1163 if (!message.is_valid_var()) { 1164 PpapiGlobals::Get()->LogWithSource( 1165 instance, PP_LOGLEVEL_ERROR, std::string(), kSerializationError); 1166 return; 1167 } 1168 1169 if (enter.succeeded()) 1170 enter.functions()->PostMessage(instance, 1171 message.GetForInstance(dispatcher(), 1172 instance)); 1173 } 1174 1175 void PPB_Instance_Proxy::OnHostMsgLockMouse(PP_Instance instance) { 1176 // Need to be careful to always issue the callback. 1177 pp::CompletionCallback cb = callback_factory_.NewCallback( 1178 &PPB_Instance_Proxy::MouseLockCompleteInHost, instance); 1179 1180 EnterInstanceNoLock enter(instance, cb.pp_completion_callback()); 1181 if (enter.succeeded()) 1182 enter.SetResult(enter.functions()->LockMouse(instance, enter.callback())); 1183 } 1184 1185 void PPB_Instance_Proxy::OnHostMsgUnlockMouse(PP_Instance instance) { 1186 EnterInstanceNoLock enter(instance); 1187 if (enter.succeeded()) 1188 enter.functions()->UnlockMouse(instance); 1189 } 1190 1191 void PPB_Instance_Proxy::OnHostMsgGetDocumentURL( 1192 PP_Instance instance, 1193 PP_URLComponents_Dev* components, 1194 SerializedVarReturnValue result) { 1195 if (!dispatcher()->permissions().HasPermission(PERMISSION_DEV)) 1196 return; 1197 EnterInstanceNoLock enter(instance); 1198 if (enter.succeeded()) { 1199 PP_Var document_url = enter.functions()->GetDocumentURL(instance, 1200 components); 1201 result.Return(dispatcher(), document_url); 1202 } 1203 } 1204 1205 void PPB_Instance_Proxy::OnHostMsgResolveRelativeToDocument( 1206 PP_Instance instance, 1207 SerializedVarReceiveInput relative, 1208 SerializedVarReturnValue result) { 1209 if (!dispatcher()->permissions().HasPermission(PERMISSION_DEV)) 1210 return; 1211 EnterInstanceNoLock enter(instance); 1212 if (enter.succeeded()) { 1213 result.Return(dispatcher(), 1214 enter.functions()->ResolveRelativeToDocument( 1215 instance, relative.Get(dispatcher()), NULL)); 1216 } 1217 } 1218 1219 void PPB_Instance_Proxy::OnHostMsgDocumentCanRequest( 1220 PP_Instance instance, 1221 SerializedVarReceiveInput url, 1222 PP_Bool* result) { 1223 if (!dispatcher()->permissions().HasPermission(PERMISSION_DEV)) 1224 return; 1225 EnterInstanceNoLock enter(instance); 1226 if (enter.succeeded()) { 1227 *result = enter.functions()->DocumentCanRequest(instance, 1228 url.Get(dispatcher())); 1229 } 1230 } 1231 1232 void PPB_Instance_Proxy::OnHostMsgDocumentCanAccessDocument(PP_Instance active, 1233 PP_Instance target, 1234 PP_Bool* result) { 1235 if (!dispatcher()->permissions().HasPermission(PERMISSION_DEV)) 1236 return; 1237 EnterInstanceNoLock enter(active); 1238 if (enter.succeeded()) 1239 *result = enter.functions()->DocumentCanAccessDocument(active, target); 1240 } 1241 1242 void PPB_Instance_Proxy::OnHostMsgGetPluginInstanceURL( 1243 PP_Instance instance, 1244 SerializedVarReturnValue result) { 1245 if (!dispatcher()->permissions().HasPermission(PERMISSION_DEV)) 1246 return; 1247 EnterInstanceNoLock enter(instance); 1248 if (enter.succeeded()) { 1249 result.Return(dispatcher(), 1250 enter.functions()->GetPluginInstanceURL(instance, NULL)); 1251 } 1252 } 1253 1254 void PPB_Instance_Proxy::OnHostMsgGetPluginReferrerURL( 1255 PP_Instance instance, 1256 SerializedVarReturnValue result) { 1257 if (!dispatcher()->permissions().HasPermission(PERMISSION_DEV)) 1258 return; 1259 EnterInstanceNoLock enter(instance); 1260 if (enter.succeeded()) { 1261 result.Return(dispatcher(), 1262 enter.functions()->GetPluginReferrerURL(instance, NULL)); 1263 } 1264 } 1265 1266 void PPB_Instance_Proxy::OnHostMsgPromiseResolved(PP_Instance instance, 1267 uint32_t promise_id) { 1268 if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE)) 1269 return; 1270 EnterInstanceNoLock enter(instance); 1271 if (enter.succeeded()) { 1272 enter.functions()->PromiseResolved(instance, promise_id); 1273 } 1274 } 1275 1276 void PPB_Instance_Proxy::OnHostMsgPromiseResolvedWithSession( 1277 PP_Instance instance, 1278 uint32_t promise_id, 1279 SerializedVarReceiveInput web_session_id) { 1280 if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE)) 1281 return; 1282 EnterInstanceNoLock enter(instance); 1283 if (enter.succeeded()) { 1284 enter.functions()->PromiseResolvedWithSession( 1285 instance, promise_id, web_session_id.Get(dispatcher())); 1286 } 1287 } 1288 1289 void PPB_Instance_Proxy::OnHostMsgPromiseResolvedWithKeyIds( 1290 PP_Instance instance, 1291 uint32_t promise_id, 1292 const std::vector<std::vector<uint8_t> >& key_ids) { 1293 if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE)) 1294 return; 1295 if (key_ids.size() > media::limits::kMaxKeyIds) { 1296 NOTREACHED(); 1297 return; 1298 } 1299 1300 scoped_refptr<ArrayVar> key_ids_array = new ArrayVar(); 1301 key_ids_array->SetLength(key_ids.size()); 1302 for (size_t i = 0; i < key_ids.size(); ++i) { 1303 const std::vector<uint8_t>& entry = key_ids[i]; 1304 if (entry.size() < media::limits::kMinKeyIdLength || 1305 entry.size() > media::limits::kMaxKeyIdLength) { 1306 NOTREACHED(); 1307 continue; 1308 } 1309 key_ids_array->Set( 1310 i, 1311 PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar(entry.size(), 1312 &entry[0])); 1313 } 1314 1315 EnterInstanceNoLock enter(instance); 1316 if (enter.succeeded()) { 1317 ScopedPPVar key_ids_var(ScopedPPVar::PassRef(), key_ids_array->GetPPVar()); 1318 enter.functions()->PromiseResolvedWithKeyIds( 1319 instance, promise_id, key_ids_var.get()); 1320 } 1321 } 1322 1323 void PPB_Instance_Proxy::OnHostMsgPromiseRejected( 1324 PP_Instance instance, 1325 uint32_t promise_id, 1326 PP_CdmExceptionCode exception_code, 1327 uint32_t system_code, 1328 SerializedVarReceiveInput error_description) { 1329 if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE)) 1330 return; 1331 EnterInstanceNoLock enter(instance); 1332 if (enter.succeeded()) { 1333 enter.functions()->PromiseRejected(instance, 1334 promise_id, 1335 exception_code, 1336 system_code, 1337 error_description.Get(dispatcher())); 1338 } 1339 } 1340 1341 void PPB_Instance_Proxy::OnHostMsgSessionMessage( 1342 PP_Instance instance, 1343 SerializedVarReceiveInput web_session_id, 1344 SerializedVarReceiveInput message, 1345 SerializedVarReceiveInput destination_url) { 1346 if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE)) 1347 return; 1348 EnterInstanceNoLock enter(instance); 1349 if (enter.succeeded()) { 1350 enter.functions()->SessionMessage(instance, 1351 web_session_id.Get(dispatcher()), 1352 message.Get(dispatcher()), 1353 destination_url.Get(dispatcher())); 1354 } 1355 } 1356 1357 void PPB_Instance_Proxy::OnHostMsgSessionKeysChange( 1358 PP_Instance instance, 1359 const std::string& web_session_id, 1360 PP_Bool has_additional_usable_key) { 1361 if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE)) 1362 return; 1363 EnterInstanceNoLock enter(instance); 1364 if (enter.succeeded()) { 1365 ScopedPPVar web_session_id_var(ScopedPPVar::PassRef(), 1366 StringVar::StringToPPVar(web_session_id)); 1367 enter.functions()->SessionKeysChange( 1368 instance, web_session_id_var.get(), has_additional_usable_key); 1369 } 1370 } 1371 1372 void PPB_Instance_Proxy::OnHostMsgSessionExpirationChange( 1373 PP_Instance instance, 1374 const std::string& web_session_id, 1375 PP_Time new_expiry_time) { 1376 if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE)) 1377 return; 1378 EnterInstanceNoLock enter(instance); 1379 if (enter.succeeded()) { 1380 ScopedPPVar web_session_id_var(ScopedPPVar::PassRef(), 1381 StringVar::StringToPPVar(web_session_id)); 1382 enter.functions()->SessionExpirationChange( 1383 instance, web_session_id_var.get(), new_expiry_time); 1384 } 1385 } 1386 1387 void PPB_Instance_Proxy::OnHostMsgSessionReady( 1388 PP_Instance instance, 1389 SerializedVarReceiveInput web_session_id) { 1390 if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE)) 1391 return; 1392 EnterInstanceNoLock enter(instance); 1393 if (enter.succeeded()) { 1394 enter.functions()->SessionReady(instance, web_session_id.Get(dispatcher())); 1395 } 1396 } 1397 1398 void PPB_Instance_Proxy::OnHostMsgSessionClosed( 1399 PP_Instance instance, 1400 SerializedVarReceiveInput web_session_id) { 1401 if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE)) 1402 return; 1403 EnterInstanceNoLock enter(instance); 1404 if (enter.succeeded()) { 1405 enter.functions()->SessionClosed(instance, 1406 web_session_id.Get(dispatcher())); 1407 } 1408 } 1409 1410 void PPB_Instance_Proxy::OnHostMsgSessionError( 1411 PP_Instance instance, 1412 SerializedVarReceiveInput web_session_id, 1413 PP_CdmExceptionCode exception_code, 1414 uint32_t system_code, 1415 SerializedVarReceiveInput error_description) { 1416 if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE)) 1417 return; 1418 EnterInstanceNoLock enter(instance); 1419 if (enter.succeeded()) { 1420 enter.functions()->SessionError(instance, 1421 web_session_id.Get(dispatcher()), 1422 exception_code, 1423 system_code, 1424 error_description.Get(dispatcher())); 1425 } 1426 } 1427 1428 void PPB_Instance_Proxy::OnHostMsgDeliverBlock( 1429 PP_Instance instance, 1430 PP_Resource decrypted_block, 1431 const std::string& serialized_block_info) { 1432 if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE)) 1433 return; 1434 PP_DecryptedBlockInfo block_info; 1435 if (!DeserializeBlockInfo(serialized_block_info, &block_info)) 1436 return; 1437 1438 EnterInstanceNoLock enter(instance); 1439 if (enter.succeeded()) 1440 enter.functions()->DeliverBlock(instance, decrypted_block, &block_info); 1441 } 1442 1443 void PPB_Instance_Proxy::OnHostMsgDecoderInitializeDone( 1444 PP_Instance instance, 1445 PP_DecryptorStreamType decoder_type, 1446 uint32_t request_id, 1447 PP_Bool success) { 1448 if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE)) 1449 return; 1450 EnterInstanceNoLock enter(instance); 1451 if (enter.succeeded()) { 1452 enter.functions()->DecoderInitializeDone(instance, 1453 decoder_type, 1454 request_id, 1455 success); 1456 } 1457 } 1458 1459 void PPB_Instance_Proxy::OnHostMsgDecoderDeinitializeDone( 1460 PP_Instance instance, 1461 PP_DecryptorStreamType decoder_type, 1462 uint32_t request_id) { 1463 if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE)) 1464 return; 1465 EnterInstanceNoLock enter(instance); 1466 if (enter.succeeded()) 1467 enter.functions()->DecoderDeinitializeDone(instance, 1468 decoder_type, 1469 request_id); 1470 } 1471 1472 void PPB_Instance_Proxy::OnHostMsgDecoderResetDone( 1473 PP_Instance instance, 1474 PP_DecryptorStreamType decoder_type, 1475 uint32_t request_id) { 1476 if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE)) 1477 return; 1478 EnterInstanceNoLock enter(instance); 1479 if (enter.succeeded()) 1480 enter.functions()->DecoderResetDone(instance, decoder_type, request_id); 1481 } 1482 1483 void PPB_Instance_Proxy::OnHostMsgDeliverFrame( 1484 PP_Instance instance, 1485 PP_Resource decrypted_frame, 1486 const std::string& serialized_frame_info) { 1487 if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE)) 1488 return; 1489 PP_DecryptedFrameInfo frame_info; 1490 if (!DeserializeBlockInfo(serialized_frame_info, &frame_info)) 1491 return; 1492 1493 EnterInstanceNoLock enter(instance); 1494 if (enter.succeeded()) 1495 enter.functions()->DeliverFrame(instance, decrypted_frame, &frame_info); 1496 } 1497 1498 void PPB_Instance_Proxy::OnHostMsgDeliverSamples( 1499 PP_Instance instance, 1500 PP_Resource audio_frames, 1501 const std::string& serialized_sample_info) { 1502 if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE)) 1503 return; 1504 PP_DecryptedSampleInfo sample_info; 1505 if (!DeserializeBlockInfo(serialized_sample_info, &sample_info)) 1506 return; 1507 1508 EnterInstanceNoLock enter(instance); 1509 if (enter.succeeded()) 1510 enter.functions()->DeliverSamples(instance, audio_frames, &sample_info); 1511 } 1512 1513 void PPB_Instance_Proxy::OnHostMsgSetCursor( 1514 PP_Instance instance, 1515 int32_t type, 1516 const ppapi::HostResource& custom_image, 1517 const PP_Point& hot_spot) { 1518 // This API serves PPB_CursorControl_Dev and PPB_MouseCursor, so is public. 1519 EnterInstanceNoLock enter(instance); 1520 if (enter.succeeded()) { 1521 enter.functions()->SetCursor( 1522 instance, static_cast<PP_MouseCursor_Type>(type), 1523 custom_image.host_resource(), &hot_spot); 1524 } 1525 } 1526 1527 void PPB_Instance_Proxy::OnHostMsgSetTextInputType(PP_Instance instance, 1528 PP_TextInput_Type type) { 1529 EnterInstanceNoLock enter(instance); 1530 if (enter.succeeded()) 1531 enter.functions()->SetTextInputType(instance, type); 1532 } 1533 1534 void PPB_Instance_Proxy::OnHostMsgUpdateCaretPosition( 1535 PP_Instance instance, 1536 const PP_Rect& caret, 1537 const PP_Rect& bounding_box) { 1538 EnterInstanceNoLock enter(instance); 1539 if (enter.succeeded()) 1540 enter.functions()->UpdateCaretPosition(instance, caret, bounding_box); 1541 } 1542 1543 void PPB_Instance_Proxy::OnHostMsgCancelCompositionText(PP_Instance instance) { 1544 EnterInstanceNoLock enter(instance); 1545 if (enter.succeeded()) 1546 enter.functions()->CancelCompositionText(instance); 1547 } 1548 1549 void PPB_Instance_Proxy::OnHostMsgUpdateSurroundingText( 1550 PP_Instance instance, 1551 const std::string& text, 1552 uint32_t caret, 1553 uint32_t anchor) { 1554 EnterInstanceNoLock enter(instance); 1555 if (enter.succeeded()) { 1556 enter.functions()->UpdateSurroundingText(instance, text.c_str(), caret, 1557 anchor); 1558 } 1559 } 1560 #endif // !defined(OS_NACL) 1561 1562 void PPB_Instance_Proxy::OnPluginMsgMouseLockComplete(PP_Instance instance, 1563 int32_t result) { 1564 if (!dispatcher()->IsPlugin()) 1565 return; 1566 1567 // Save the mouse callback on the instance data. 1568 InstanceData* data = static_cast<PluginDispatcher*>(dispatcher())-> 1569 GetInstanceData(instance); 1570 if (!data) 1571 return; // Instance was probably deleted. 1572 if (!TrackedCallback::IsPending(data->mouse_lock_callback)) { 1573 NOTREACHED(); 1574 return; 1575 } 1576 data->mouse_lock_callback->Run(result); 1577 } 1578 1579 #if !defined(OS_NACL) 1580 void PPB_Instance_Proxy::MouseLockCompleteInHost(int32_t result, 1581 PP_Instance instance) { 1582 dispatcher()->Send(new PpapiMsg_PPBInstance_MouseLockComplete( 1583 API_ID_PPB_INSTANCE, instance, result)); 1584 } 1585 #endif // !defined(OS_NACL) 1586 1587 void PPB_Instance_Proxy::CancelAnyPendingRequestSurroundingText( 1588 PP_Instance instance) { 1589 InstanceData* data = static_cast<PluginDispatcher*>(dispatcher())-> 1590 GetInstanceData(instance); 1591 if (!data) 1592 return; // Instance was probably deleted. 1593 data->should_do_request_surrounding_text = false; 1594 } 1595 1596 } // namespace proxy 1597 } // namespace ppapi 1598