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