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