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