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