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 "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