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