Home | History | Annotate | Download | only in proxy
      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