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