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