Upstream version 10.39.225.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 "media/base/limits.h"
10 #include "ppapi/c/pp_errors.h"
11 #include "ppapi/c/pp_time.h"
12 #include "ppapi/c/pp_var.h"
13 #include "ppapi/c/ppb_audio_config.h"
14 #include "ppapi/c/ppb_instance.h"
15 #include "ppapi/c/ppb_messaging.h"
16 #include "ppapi/c/ppb_mouse_lock.h"
17 #include "ppapi/c/private/pp_content_decryptor.h"
18 #include "ppapi/proxy/broker_resource.h"
19 #include "ppapi/proxy/browser_font_singleton_resource.h"
20 #include "ppapi/proxy/content_decryptor_private_serializer.h"
21 #include "ppapi/proxy/enter_proxy.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/message_handler.h"
31 #include "ppapi/proxy/network_proxy_resource.h"
32 #include "ppapi/proxy/pdf_resource.h"
33 #include "ppapi/proxy/plugin_dispatcher.h"
34 #include "ppapi/proxy/ppapi_messages.h"
35 #include "ppapi/proxy/serialized_var.h"
36 #include "ppapi/proxy/truetype_font_singleton_resource.h"
37 #include "ppapi/proxy/uma_private_resource.h"
38 #include "ppapi/shared_impl/array_var.h"
39 #include "ppapi/shared_impl/ppapi_globals.h"
40 #include "ppapi/shared_impl/ppb_url_util_shared.h"
41 #include "ppapi/shared_impl/ppb_view_shared.h"
42 #include "ppapi/shared_impl/scoped_pp_var.h"
43 #include "ppapi/shared_impl/var.h"
44 #include "ppapi/thunk/enter.h"
45 #include "ppapi/thunk/ppb_compositor_api.h"
46 #include "ppapi/thunk/ppb_graphics_2d_api.h"
47 #include "ppapi/thunk/ppb_graphics_3d_api.h"
48 #include "ppapi/thunk/thunk.h"
49
50 // Windows headers interfere with this file.
51 #ifdef PostMessage
52 #undef PostMessage
53 #endif
54
55 using ppapi::thunk::EnterInstanceNoLock;
56 using ppapi::thunk::EnterResourceNoLock;
57 using ppapi::thunk::PPB_Compositor_API;
58 using ppapi::thunk::PPB_Graphics2D_API;
59 using ppapi::thunk::PPB_Graphics3D_API;
60 using ppapi::thunk::PPB_Instance_API;
61
62 namespace ppapi {
63 namespace proxy {
64
65 namespace {
66
67 #if !defined(OS_NACL)
68 const char kSerializationError[] = "Failed to convert a PostMessage "
69     "argument from a PP_Var to a Javascript value. It may have cycles or be of "
70     "an unsupported type.";
71 #endif
72
73 void RequestSurroundingText(PP_Instance instance) {
74   PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance);
75   if (!dispatcher)
76     return;  // Instance has gone away while message was pending.
77
78   InstanceData* data = dispatcher->GetInstanceData(instance);
79   DCHECK(data);  // Should have it, since we still have a dispatcher.
80   data->is_request_surrounding_text_pending = false;
81   if (!data->should_do_request_surrounding_text)
82     return;
83
84   // Just fake out a RequestSurroundingText message to the proxy for the PPP
85   // interface.
86   InterfaceProxy* proxy = dispatcher->GetInterfaceProxy(API_ID_PPP_TEXT_INPUT);
87   if (!proxy)
88     return;
89   proxy->OnMessageReceived(PpapiMsg_PPPTextInput_RequestSurroundingText(
90       API_ID_PPP_TEXT_INPUT, instance,
91       PPB_Instance_Shared::kExtraCharsForTextInput));
92 }
93
94 }  // namespace
95
96 PPB_Instance_Proxy::PPB_Instance_Proxy(Dispatcher* dispatcher)
97     : InterfaceProxy(dispatcher),
98       callback_factory_(this) {
99 }
100
101 PPB_Instance_Proxy::~PPB_Instance_Proxy() {
102 }
103
104 bool PPB_Instance_Proxy::OnMessageReceived(const IPC::Message& msg) {
105   // Prevent the dispatcher from going away during a call to ExecuteScript.
106   // This must happen OUTSIDE of ExecuteScript since the SerializedVars use
107   // the dispatcher upon return of the function (converting the
108   // SerializedVarReturnValue/OutParam to a SerializedVar in the destructor).
109 #if !defined(OS_NACL)
110   ScopedModuleReference death_grip(dispatcher());
111 #endif
112
113   bool handled = true;
114   IPC_BEGIN_MESSAGE_MAP(PPB_Instance_Proxy, msg)
115 #if !defined(OS_NACL)
116     // Plugin -> Host messages.
117     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_GetWindowObject,
118                         OnHostMsgGetWindowObject)
119     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_GetOwnerElementObject,
120                         OnHostMsgGetOwnerElementObject)
121     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_BindGraphics,
122                         OnHostMsgBindGraphics)
123     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_IsFullFrame,
124                         OnHostMsgIsFullFrame)
125     IPC_MESSAGE_HANDLER(
126         PpapiHostMsg_PPBInstance_GetAudioHardwareOutputSampleRate,
127         OnHostMsgGetAudioHardwareOutputSampleRate)
128     IPC_MESSAGE_HANDLER(
129         PpapiHostMsg_PPBInstance_GetAudioHardwareOutputBufferSize,
130         OnHostMsgGetAudioHardwareOutputBufferSize)
131     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_ExecuteScript,
132                         OnHostMsgExecuteScript)
133     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_GetDefaultCharSet,
134                         OnHostMsgGetDefaultCharSet)
135     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_SetPluginToHandleFindRequests,
136                         OnHostMsgSetPluginToHandleFindRequests);
137     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_NumberOfFindResultsChanged,
138                         OnHostMsgNumberOfFindResultsChanged)
139     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_SelectFindResultChanged,
140                         OnHostMsgSelectFindResultChanged)
141     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_SetTickmarks,
142                         OnHostMsgSetTickmarks)
143     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_PostMessage,
144                         OnHostMsgPostMessage)
145     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_SetFullscreen,
146                         OnHostMsgSetFullscreen)
147     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_GetScreenSize,
148                         OnHostMsgGetScreenSize)
149     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_RequestInputEvents,
150                         OnHostMsgRequestInputEvents)
151     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_ClearInputEvents,
152                         OnHostMsgClearInputEvents)
153     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_StartTrackingLatency,
154                         OnHostMsgStartTrackingLatency)
155     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_LockMouse,
156                         OnHostMsgLockMouse)
157     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_UnlockMouse,
158                         OnHostMsgUnlockMouse)
159     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_SetCursor,
160                         OnHostMsgSetCursor)
161     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_SetTextInputType,
162                         OnHostMsgSetTextInputType)
163     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_UpdateCaretPosition,
164                         OnHostMsgUpdateCaretPosition)
165     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_CancelCompositionText,
166                         OnHostMsgCancelCompositionText)
167     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_UpdateSurroundingText,
168                         OnHostMsgUpdateSurroundingText)
169     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_GetDocumentURL,
170                         OnHostMsgGetDocumentURL)
171     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_ResolveRelativeToDocument,
172                         OnHostMsgResolveRelativeToDocument)
173     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_DocumentCanRequest,
174                         OnHostMsgDocumentCanRequest)
175     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_DocumentCanAccessDocument,
176                         OnHostMsgDocumentCanAccessDocument)
177     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_GetPluginInstanceURL,
178                         OnHostMsgGetPluginInstanceURL)
179     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_GetPluginReferrerURL,
180                         OnHostMsgGetPluginReferrerURL)
181     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_PromiseResolved,
182                         OnHostMsgPromiseResolved)
183     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_PromiseResolvedWithSession,
184                         OnHostMsgPromiseResolvedWithSession)
185     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_PromiseResolvedWithKeyIds,
186                         OnHostMsgPromiseResolvedWithKeyIds)
187     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_PromiseRejected,
188                         OnHostMsgPromiseRejected)
189     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_SessionMessage,
190                         OnHostMsgSessionMessage)
191     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_SessionKeysChange,
192                         OnHostMsgSessionKeysChange)
193     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_SessionExpirationChange,
194                         OnHostMsgSessionExpirationChange)
195     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_SessionReady,
196                         OnHostMsgSessionReady)
197     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_SessionClosed,
198                         OnHostMsgSessionClosed)
199     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_SessionError,
200                         OnHostMsgSessionError)
201     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_DeliverBlock,
202                         OnHostMsgDeliverBlock)
203     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_DecoderInitializeDone,
204                         OnHostMsgDecoderInitializeDone)
205     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_DecoderDeinitializeDone,
206                         OnHostMsgDecoderDeinitializeDone)
207     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_DecoderResetDone,
208                         OnHostMsgDecoderResetDone)
209     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_DeliverFrame,
210                         OnHostMsgDeliverFrame)
211     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_DeliverSamples,
212                         OnHostMsgDeliverSamples)
213 #endif  // !defined(OS_NACL)
214
215     // Host -> Plugin messages.
216     IPC_MESSAGE_HANDLER(PpapiMsg_PPBInstance_MouseLockComplete,
217                         OnPluginMsgMouseLockComplete)
218
219     IPC_MESSAGE_UNHANDLED(handled = false)
220   IPC_END_MESSAGE_MAP()
221   return handled;
222 }
223
224 PP_Bool PPB_Instance_Proxy::BindGraphics(PP_Instance instance,
225                                          PP_Resource device) {
226   // If device is 0, pass a null HostResource. This signals the host to unbind
227   // all devices.
228   PP_Resource pp_resource = 0;
229   if (device) {
230     Resource* resource =
231         PpapiGlobals::Get()->GetResourceTracker()->GetResource(device);
232     if (!resource || resource->pp_instance() != instance)
233       return PP_FALSE;
234     // We need to pass different resource to Graphics 2D, 3D and Compositor
235     // right now.  Once 3D is migrated to the new design, we should be able to
236     // unify this.
237     if (resource->AsPPB_Graphics3D_API()) {
238       pp_resource = resource->host_resource().host_resource();
239     } else if (resource->AsPPB_Graphics2D_API() ||
240                resource->AsPPB_Compositor_API()) {
241       pp_resource = resource->pp_resource();
242     } else {
243       // A bad resource.
244       return PP_FALSE;
245     }
246   }
247   dispatcher()->Send(new PpapiHostMsg_PPBInstance_BindGraphics(
248         API_ID_PPB_INSTANCE, instance, pp_resource));
249   return PP_TRUE;
250 }
251
252 PP_Bool PPB_Instance_Proxy::IsFullFrame(PP_Instance instance) {
253   PP_Bool result = PP_FALSE;
254   dispatcher()->Send(new PpapiHostMsg_PPBInstance_IsFullFrame(
255       API_ID_PPB_INSTANCE, instance, &result));
256   return result;
257 }
258
259 const ViewData* PPB_Instance_Proxy::GetViewData(PP_Instance instance) {
260   InstanceData* data = static_cast<PluginDispatcher*>(dispatcher())->
261       GetInstanceData(instance);
262   if (!data)
263     return NULL;
264   return &data->view;
265 }
266
267 PP_Bool PPB_Instance_Proxy::FlashIsFullscreen(PP_Instance instance) {
268   // This function is only used for proxying in the renderer process. It is not
269   // implemented in the plugin process.
270   NOTREACHED();
271   return PP_FALSE;
272 }
273
274 PP_Var PPB_Instance_Proxy::GetWindowObject(PP_Instance instance) {
275   ReceiveSerializedVarReturnValue result;
276   dispatcher()->Send(new PpapiHostMsg_PPBInstance_GetWindowObject(
277       API_ID_PPB_INSTANCE, instance, &result));
278   return result.Return(dispatcher());
279 }
280
281 PP_Var PPB_Instance_Proxy::GetOwnerElementObject(PP_Instance instance) {
282   ReceiveSerializedVarReturnValue result;
283   dispatcher()->Send(new PpapiHostMsg_PPBInstance_GetOwnerElementObject(
284       API_ID_PPB_INSTANCE, instance, &result));
285   return result.Return(dispatcher());
286 }
287
288 PP_Var PPB_Instance_Proxy::ExecuteScript(PP_Instance instance,
289                                          PP_Var script,
290                                          PP_Var* exception) {
291   ReceiveSerializedException se(dispatcher(), exception);
292   if (se.IsThrown())
293     return PP_MakeUndefined();
294
295   ReceiveSerializedVarReturnValue result;
296   dispatcher()->Send(new PpapiHostMsg_PPBInstance_ExecuteScript(
297       API_ID_PPB_INSTANCE, instance,
298       SerializedVarSendInput(dispatcher(), script), &se, &result));
299   return result.Return(dispatcher());
300 }
301
302 uint32_t PPB_Instance_Proxy::GetAudioHardwareOutputSampleRate(
303     PP_Instance instance) {
304   uint32_t result = PP_AUDIOSAMPLERATE_NONE;
305   dispatcher()->Send(
306       new PpapiHostMsg_PPBInstance_GetAudioHardwareOutputSampleRate(
307           API_ID_PPB_INSTANCE, instance, &result));
308   return result;
309 }
310
311 uint32_t PPB_Instance_Proxy::GetAudioHardwareOutputBufferSize(
312     PP_Instance instance) {
313   uint32_t result = 0;
314   dispatcher()->Send(
315       new PpapiHostMsg_PPBInstance_GetAudioHardwareOutputBufferSize(
316           API_ID_PPB_INSTANCE, instance, &result));
317   return result;
318 }
319
320 PP_Var PPB_Instance_Proxy::GetDefaultCharSet(PP_Instance instance) {
321   PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance);
322   if (!dispatcher)
323     return PP_MakeUndefined();
324
325   ReceiveSerializedVarReturnValue result;
326   dispatcher->Send(new PpapiHostMsg_PPBInstance_GetDefaultCharSet(
327       API_ID_PPB_INSTANCE, instance, &result));
328   return result.Return(dispatcher);
329 }
330
331 void PPB_Instance_Proxy::SetPluginToHandleFindRequests(PP_Instance instance) {
332   dispatcher()->Send(new PpapiHostMsg_PPBInstance_SetPluginToHandleFindRequests(
333       API_ID_PPB_INSTANCE, instance));
334 }
335
336 void PPB_Instance_Proxy::NumberOfFindResultsChanged(PP_Instance instance,
337                                                     int32_t total,
338                                                     PP_Bool final_result) {
339   dispatcher()->Send(new PpapiHostMsg_PPBInstance_NumberOfFindResultsChanged(
340       API_ID_PPB_INSTANCE, instance, total, final_result));
341 }
342
343 void PPB_Instance_Proxy::SelectedFindResultChanged(PP_Instance instance,
344                                                    int32_t index) {
345   dispatcher()->Send(new PpapiHostMsg_PPBInstance_SelectFindResultChanged(
346       API_ID_PPB_INSTANCE, instance, index));
347 }
348
349 void PPB_Instance_Proxy::SetTickmarks(PP_Instance instance,
350                                       const PP_Rect* tickmarks,
351                                       uint32_t count) {
352   dispatcher()->Send(new PpapiHostMsg_PPBInstance_SetTickmarks(
353       API_ID_PPB_INSTANCE, instance,
354       std::vector<PP_Rect>(tickmarks, tickmarks + count)));
355 }
356
357 PP_Bool PPB_Instance_Proxy::IsFullscreen(PP_Instance instance) {
358   InstanceData* data = static_cast<PluginDispatcher*>(dispatcher())->
359       GetInstanceData(instance);
360   if (!data)
361     return PP_FALSE;
362   return PP_FromBool(data->view.is_fullscreen);
363 }
364
365 PP_Bool PPB_Instance_Proxy::SetFullscreen(PP_Instance instance,
366                                           PP_Bool fullscreen) {
367   PP_Bool result = PP_FALSE;
368   dispatcher()->Send(new PpapiHostMsg_PPBInstance_SetFullscreen(
369       API_ID_PPB_INSTANCE, instance, fullscreen, &result));
370   return result;
371 }
372
373 PP_Bool PPB_Instance_Proxy::GetScreenSize(PP_Instance instance,
374                                           PP_Size* size) {
375   PP_Bool result = PP_FALSE;
376   dispatcher()->Send(new PpapiHostMsg_PPBInstance_GetScreenSize(
377       API_ID_PPB_INSTANCE, instance, &result, size));
378   return result;
379 }
380
381 Resource* PPB_Instance_Proxy::GetSingletonResource(PP_Instance instance,
382                                                    SingletonResourceID id) {
383   InstanceData* data = static_cast<PluginDispatcher*>(dispatcher())->
384       GetInstanceData(instance);
385
386   InstanceData::SingletonResourceMap::iterator it =
387       data->singleton_resources.find(id);
388   if (it != data->singleton_resources.end())
389     return it->second.get();
390
391   scoped_refptr<Resource> new_singleton;
392   Connection connection(PluginGlobals::Get()->GetBrowserSender(), dispatcher());
393
394   switch (id) {
395     case BROKER_SINGLETON_ID:
396       new_singleton = new BrokerResource(connection, instance);
397       break;
398     case FILE_MAPPING_SINGLETON_ID:
399       new_singleton = new FileMappingResource(connection, instance);
400       break;
401     case GAMEPAD_SINGLETON_ID:
402       new_singleton = new GamepadResource(connection, instance);
403       break;
404     case ISOLATED_FILESYSTEM_SINGLETON_ID:
405       new_singleton =
406           new IsolatedFileSystemPrivateResource(connection, instance);
407       break;
408     case NETWORK_PROXY_SINGLETON_ID:
409       new_singleton = new NetworkProxyResource(connection, instance);
410       break;
411     case TRUETYPE_FONT_SINGLETON_ID:
412       new_singleton = new TrueTypeFontSingletonResource(connection, instance);
413       break;
414     case UMA_SINGLETON_ID:
415       new_singleton = new UMAPrivateResource(connection, instance);
416       break;
417 // Flash/trusted resources aren't needed for NaCl.
418 #if !defined(OS_NACL) && !defined(NACL_WIN64)
419     case BROWSER_FONT_SINGLETON_ID:
420       new_singleton = new BrowserFontSingletonResource(connection, instance);
421       break;
422     case FLASH_CLIPBOARD_SINGLETON_ID:
423       new_singleton = new FlashClipboardResource(connection, instance);
424       break;
425     case FLASH_FILE_SINGLETON_ID:
426       new_singleton = new FlashFileResource(connection, instance);
427       break;
428     case FLASH_FULLSCREEN_SINGLETON_ID:
429       new_singleton = new FlashFullscreenResource(connection, instance);
430       break;
431     case FLASH_SINGLETON_ID:
432       new_singleton = new FlashResource(connection, instance,
433           static_cast<PluginDispatcher*>(dispatcher()));
434       break;
435     case PDF_SINGLETON_ID:
436       new_singleton = new PDFResource(connection, instance);
437       break;
438 #else
439     case BROWSER_FONT_SINGLETON_ID:
440     case FLASH_CLIPBOARD_SINGLETON_ID:
441     case FLASH_FILE_SINGLETON_ID:
442     case FLASH_FULLSCREEN_SINGLETON_ID:
443     case FLASH_SINGLETON_ID:
444     case PDF_SINGLETON_ID:
445       NOTREACHED();
446       break;
447 #endif  // !defined(OS_NACL) && !defined(NACL_WIN64)
448   }
449
450   if (!new_singleton.get()) {
451     // Getting here implies that a constructor is missing in the above switch.
452     NOTREACHED();
453     return NULL;
454   }
455
456   data->singleton_resources[id] = new_singleton;
457   return new_singleton.get();
458 }
459
460 int32_t PPB_Instance_Proxy::RequestInputEvents(PP_Instance instance,
461                                                uint32_t event_classes) {
462   dispatcher()->Send(new PpapiHostMsg_PPBInstance_RequestInputEvents(
463       API_ID_PPB_INSTANCE, instance, false, event_classes));
464
465   // We always register for the classes we can handle, this function validates
466   // the flags so we can notify it if anything was invalid, without requiring
467   // a sync reply.
468   return ValidateRequestInputEvents(false, event_classes);
469 }
470
471 int32_t PPB_Instance_Proxy::RequestFilteringInputEvents(
472     PP_Instance instance,
473     uint32_t event_classes) {
474   dispatcher()->Send(new PpapiHostMsg_PPBInstance_RequestInputEvents(
475       API_ID_PPB_INSTANCE, instance, true, event_classes));
476
477   // We always register for the classes we can handle, this function validates
478   // the flags so we can notify it if anything was invalid, without requiring
479   // a sync reply.
480   return ValidateRequestInputEvents(true, event_classes);
481 }
482
483 void PPB_Instance_Proxy::ClearInputEventRequest(PP_Instance instance,
484                                                 uint32_t event_classes) {
485   dispatcher()->Send(new PpapiHostMsg_PPBInstance_ClearInputEvents(
486       API_ID_PPB_INSTANCE, instance, event_classes));
487 }
488
489 void PPB_Instance_Proxy::StartTrackingLatency(PP_Instance instance) {
490   dispatcher()->Send(new PpapiHostMsg_PPBInstance_StartTrackingLatency(
491       API_ID_PPB_INSTANCE, instance));
492 }
493
494 void PPB_Instance_Proxy::ZoomChanged(PP_Instance instance,
495                                      double factor) {
496   // Not proxied yet.
497   NOTIMPLEMENTED();
498 }
499
500 void PPB_Instance_Proxy::ZoomLimitsChanged(PP_Instance instance,
501                                            double minimum_factor,
502                                            double maximium_factor) {
503   // Not proxied yet.
504   NOTIMPLEMENTED();
505 }
506
507 PP_Var PPB_Instance_Proxy::GetDocumentURL(PP_Instance instance,
508                                           PP_URLComponents_Dev* components) {
509   ReceiveSerializedVarReturnValue result;
510   PP_URLComponents_Dev url_components = {{0}};
511   dispatcher()->Send(new PpapiHostMsg_PPBInstance_GetDocumentURL(
512       API_ID_PPB_INSTANCE, instance, &url_components, &result));
513   if (components)
514     *components = url_components;
515   return result.Return(dispatcher());
516 }
517
518 #if !defined(OS_NACL)
519 PP_Var PPB_Instance_Proxy::ResolveRelativeToDocument(
520     PP_Instance instance,
521     PP_Var relative,
522     PP_URLComponents_Dev* components) {
523   ReceiveSerializedVarReturnValue result;
524   dispatcher()->Send(new PpapiHostMsg_PPBInstance_ResolveRelativeToDocument(
525       API_ID_PPB_INSTANCE, instance,
526       SerializedVarSendInput(dispatcher(), relative),
527       &result));
528   return PPB_URLUtil_Shared::ConvertComponentsAndReturnURL(
529       result.Return(dispatcher()),
530       components);
531 }
532
533 PP_Bool PPB_Instance_Proxy::DocumentCanRequest(PP_Instance instance,
534                                                PP_Var url) {
535   PP_Bool result = PP_FALSE;
536   dispatcher()->Send(new PpapiHostMsg_PPBInstance_DocumentCanRequest(
537       API_ID_PPB_INSTANCE, instance,
538       SerializedVarSendInput(dispatcher(), url),
539       &result));
540   return result;
541 }
542
543 PP_Bool PPB_Instance_Proxy::DocumentCanAccessDocument(PP_Instance instance,
544                                                       PP_Instance target) {
545   PP_Bool result = PP_FALSE;
546   dispatcher()->Send(new PpapiHostMsg_PPBInstance_DocumentCanAccessDocument(
547       API_ID_PPB_INSTANCE, instance, target, &result));
548   return result;
549 }
550
551 PP_Var PPB_Instance_Proxy::GetPluginInstanceURL(
552       PP_Instance instance,
553       PP_URLComponents_Dev* components) {
554   ReceiveSerializedVarReturnValue result;
555   dispatcher()->Send(new PpapiHostMsg_PPBInstance_GetPluginInstanceURL(
556       API_ID_PPB_INSTANCE, instance, &result));
557   return PPB_URLUtil_Shared::ConvertComponentsAndReturnURL(
558       result.Return(dispatcher()),
559       components);
560 }
561
562 PP_Var PPB_Instance_Proxy::GetPluginReferrerURL(
563       PP_Instance instance,
564       PP_URLComponents_Dev* components) {
565   ReceiveSerializedVarReturnValue result;
566   dispatcher()->Send(new PpapiHostMsg_PPBInstance_GetPluginReferrerURL(
567       API_ID_PPB_INSTANCE, instance, &result));
568   return PPB_URLUtil_Shared::ConvertComponentsAndReturnURL(
569       result.Return(dispatcher()),
570       components);
571 }
572
573 void PPB_Instance_Proxy::PromiseResolved(PP_Instance instance,
574                                          uint32 promise_id) {
575   dispatcher()->Send(new PpapiHostMsg_PPBInstance_PromiseResolved(
576       API_ID_PPB_INSTANCE, instance, promise_id));
577 }
578
579 void PPB_Instance_Proxy::PromiseResolvedWithSession(PP_Instance instance,
580                                                     uint32 promise_id,
581                                                     PP_Var web_session_id_var) {
582   dispatcher()->Send(new PpapiHostMsg_PPBInstance_PromiseResolvedWithSession(
583       API_ID_PPB_INSTANCE,
584       instance,
585       promise_id,
586       SerializedVarSendInput(dispatcher(), web_session_id_var)));
587 }
588
589 void PPB_Instance_Proxy::PromiseResolvedWithKeyIds(PP_Instance instance,
590                                                    uint32 promise_id,
591                                                    PP_Var key_ids_var) {
592   ArrayVar* key_ids_array = ArrayVar::FromPPVar(key_ids_var);
593   if (!key_ids_array ||
594       key_ids_array->GetLength() > media::limits::kMaxKeyIds) {
595     NOTREACHED();
596     return;
597   }
598
599   std::vector<std::vector<uint8_t> > key_ids;
600   for (size_t i = 0; i < key_ids_array->GetLength(); ++i) {
601     ArrayBufferVar* key_id = ArrayBufferVar::FromPPVar(key_ids_array->Get(i));
602     if (!key_id || key_id->ByteLength() < media::limits::kMinKeyIdLength ||
603         key_id->ByteLength() > media::limits::kMaxKeyIdLength) {
604       NOTREACHED();
605       continue;
606     }
607
608     const uint8_t* key_id_ptr = static_cast<const uint8_t*>(key_id->Map());
609     const uint32_t key_id_size = key_id->ByteLength();
610     std::vector<uint8_t> key_id_vector(key_id_ptr, key_id_ptr + key_id_size);
611     key_ids.push_back(key_id_vector);
612   }
613
614   dispatcher()->Send(new PpapiHostMsg_PPBInstance_PromiseResolvedWithKeyIds(
615       API_ID_PPB_INSTANCE, instance, promise_id, key_ids));
616 }
617
618 void PPB_Instance_Proxy::PromiseRejected(PP_Instance instance,
619                                          uint32 promise_id,
620                                          PP_CdmExceptionCode exception_code,
621                                          uint32 system_code,
622                                          PP_Var error_description_var) {
623   dispatcher()->Send(new PpapiHostMsg_PPBInstance_PromiseRejected(
624       API_ID_PPB_INSTANCE,
625       instance,
626       promise_id,
627       exception_code,
628       system_code,
629       SerializedVarSendInput(dispatcher(), error_description_var)));
630 }
631
632 void PPB_Instance_Proxy::SessionMessage(PP_Instance instance,
633                                         PP_Var web_session_id_var,
634                                         PP_Var message_var,
635                                         PP_Var destination_url_var) {
636   dispatcher()->Send(new PpapiHostMsg_PPBInstance_SessionMessage(
637       API_ID_PPB_INSTANCE,
638       instance,
639       SerializedVarSendInput(dispatcher(), web_session_id_var),
640       SerializedVarSendInput(dispatcher(), message_var),
641       SerializedVarSendInput(dispatcher(), destination_url_var)));
642 }
643
644 void PPB_Instance_Proxy::SessionKeysChange(PP_Instance instance,
645                                            PP_Var web_session_id_var,
646                                            PP_Bool has_additional_usable_key) {
647   StringVar* session_id = StringVar::FromPPVar(web_session_id_var);
648   if (!session_id ||
649       session_id->value().length() > media::limits::kMaxWebSessionIdLength) {
650     NOTREACHED();
651     return;
652   }
653
654   dispatcher()->Send(new PpapiHostMsg_PPBInstance_SessionKeysChange(
655       API_ID_PPB_INSTANCE,
656       instance,
657       session_id->value(),
658       has_additional_usable_key));
659 }
660
661 void PPB_Instance_Proxy::SessionExpirationChange(PP_Instance instance,
662                                                  PP_Var web_session_id_var,
663                                                  PP_Time new_expiry_time) {
664   StringVar* session_id = StringVar::FromPPVar(web_session_id_var);
665   if (!session_id ||
666       session_id->value().length() > media::limits::kMaxWebSessionIdLength) {
667     NOTREACHED();
668     return;
669   }
670
671   dispatcher()->Send(new PpapiHostMsg_PPBInstance_SessionExpirationChange(
672       API_ID_PPB_INSTANCE, instance, session_id->value(), new_expiry_time));
673 }
674
675 void PPB_Instance_Proxy::SessionReady(PP_Instance instance,
676                                       PP_Var web_session_id_var) {
677   dispatcher()->Send(new PpapiHostMsg_PPBInstance_SessionReady(
678       API_ID_PPB_INSTANCE,
679       instance,
680       SerializedVarSendInput(dispatcher(), web_session_id_var)));
681 }
682
683 void PPB_Instance_Proxy::SessionClosed(PP_Instance instance,
684                                        PP_Var web_session_id_var) {
685   dispatcher()->Send(new PpapiHostMsg_PPBInstance_SessionClosed(
686       API_ID_PPB_INSTANCE,
687       instance,
688       SerializedVarSendInput(dispatcher(), web_session_id_var)));
689 }
690
691 void PPB_Instance_Proxy::SessionError(PP_Instance instance,
692                                       PP_Var web_session_id_var,
693                                       PP_CdmExceptionCode exception_code,
694                                       uint32 system_code,
695                                       PP_Var error_description_var) {
696   dispatcher()->Send(new PpapiHostMsg_PPBInstance_SessionError(
697       API_ID_PPB_INSTANCE,
698       instance,
699       SerializedVarSendInput(dispatcher(), web_session_id_var),
700       exception_code,
701       system_code,
702       SerializedVarSendInput(dispatcher(), error_description_var)));
703 }
704
705 void PPB_Instance_Proxy::DeliverBlock(PP_Instance instance,
706                                       PP_Resource decrypted_block,
707                                       const PP_DecryptedBlockInfo* block_info) {
708   PP_Resource decrypted_block_host_resource = 0;
709
710   if (decrypted_block) {
711     Resource* object =
712         PpapiGlobals::Get()->GetResourceTracker()->GetResource(decrypted_block);
713     if (!object || object->pp_instance() != instance) {
714       NOTREACHED();
715       return;
716     }
717     decrypted_block_host_resource = object->host_resource().host_resource();
718   }
719
720   std::string serialized_block_info;
721   if (!SerializeBlockInfo(*block_info, &serialized_block_info)) {
722     NOTREACHED();
723     return;
724   }
725
726   dispatcher()->Send(
727       new PpapiHostMsg_PPBInstance_DeliverBlock(API_ID_PPB_INSTANCE,
728           instance,
729           decrypted_block_host_resource,
730           serialized_block_info));
731 }
732
733 void PPB_Instance_Proxy::DecoderInitializeDone(
734     PP_Instance instance,
735     PP_DecryptorStreamType decoder_type,
736     uint32_t request_id,
737     PP_Bool success) {
738   dispatcher()->Send(
739       new PpapiHostMsg_PPBInstance_DecoderInitializeDone(
740           API_ID_PPB_INSTANCE,
741           instance,
742           decoder_type,
743           request_id,
744           success));
745 }
746
747 void PPB_Instance_Proxy::DecoderDeinitializeDone(
748     PP_Instance instance,
749     PP_DecryptorStreamType decoder_type,
750     uint32_t request_id) {
751   dispatcher()->Send(
752       new PpapiHostMsg_PPBInstance_DecoderDeinitializeDone(
753           API_ID_PPB_INSTANCE,
754           instance,
755           decoder_type,
756           request_id));
757 }
758
759 void PPB_Instance_Proxy::DecoderResetDone(PP_Instance instance,
760                                           PP_DecryptorStreamType decoder_type,
761                                           uint32_t request_id) {
762   dispatcher()->Send(
763       new PpapiHostMsg_PPBInstance_DecoderResetDone(
764           API_ID_PPB_INSTANCE,
765           instance,
766           decoder_type,
767           request_id));
768 }
769
770 void PPB_Instance_Proxy::DeliverFrame(PP_Instance instance,
771                                       PP_Resource decrypted_frame,
772                                       const PP_DecryptedFrameInfo* frame_info) {
773   PP_Resource host_resource = 0;
774   if (decrypted_frame != 0) {
775     ResourceTracker* tracker = PpapiGlobals::Get()->GetResourceTracker();
776     Resource* object = tracker->GetResource(decrypted_frame);
777
778     if (!object || object->pp_instance() != instance) {
779       NOTREACHED();
780       return;
781     }
782
783     host_resource = object->host_resource().host_resource();
784   }
785
786   std::string serialized_frame_info;
787   if (!SerializeBlockInfo(*frame_info, &serialized_frame_info)) {
788     NOTREACHED();
789     return;
790   }
791
792   dispatcher()->Send(
793       new PpapiHostMsg_PPBInstance_DeliverFrame(API_ID_PPB_INSTANCE,
794                                                 instance,
795                                                 host_resource,
796                                                 serialized_frame_info));
797 }
798
799 void PPB_Instance_Proxy::DeliverSamples(
800     PP_Instance instance,
801     PP_Resource decrypted_samples,
802     const PP_DecryptedSampleInfo* sample_info) {
803   PP_Resource host_resource = 0;
804   if (decrypted_samples != 0) {
805     ResourceTracker* tracker = PpapiGlobals::Get()->GetResourceTracker();
806     Resource* object = tracker->GetResource(decrypted_samples);
807
808     if (!object || object->pp_instance() != instance) {
809       NOTREACHED();
810       return;
811     }
812
813     host_resource = object->host_resource().host_resource();
814   }
815
816   std::string serialized_sample_info;
817   if (!SerializeBlockInfo(*sample_info, &serialized_sample_info)) {
818     NOTREACHED();
819     return;
820   }
821
822   dispatcher()->Send(
823       new PpapiHostMsg_PPBInstance_DeliverSamples(API_ID_PPB_INSTANCE,
824                                                   instance,
825                                                   host_resource,
826                                                   serialized_sample_info));
827 }
828 #endif  // !defined(OS_NACL)
829
830 void PPB_Instance_Proxy::PostMessage(PP_Instance instance,
831                                      PP_Var message) {
832   dispatcher()->Send(new PpapiHostMsg_PPBInstance_PostMessage(
833       API_ID_PPB_INSTANCE,
834       instance, SerializedVarSendInputShmem(dispatcher(), message,
835                                             instance)));
836 }
837
838 int32_t PPB_Instance_Proxy::RegisterMessageHandler(
839     PP_Instance instance,
840     void* user_data,
841     const PPP_MessageHandler_0_2* handler,
842     PP_Resource message_loop) {
843   InstanceData* data =
844       static_cast<PluginDispatcher*>(dispatcher())->GetInstanceData(instance);
845   if (!data)
846     return PP_ERROR_BADARGUMENT;
847
848   int32_t result = PP_ERROR_FAILED;
849   scoped_ptr<MessageHandler> message_handler = MessageHandler::Create(
850       instance, handler, user_data, message_loop, &result);
851   if (message_handler)
852     data->message_handler = message_handler.Pass();
853   return result;
854 }
855
856 // TODO(dmichael): Remove this. crbug.com/414398
857 int32_t PPB_Instance_Proxy::RegisterMessageHandler_1_1_Deprecated(
858     PP_Instance instance,
859     void* user_data,
860     const PPP_MessageHandler_0_1_Deprecated* handler,
861     PP_Resource message_loop) {
862   InstanceData* data =
863       static_cast<PluginDispatcher*>(dispatcher())->GetInstanceData(instance);
864   if (!data)
865     return PP_ERROR_BADARGUMENT;
866
867   int32_t result = PP_ERROR_FAILED;
868   scoped_ptr<MessageHandler> message_handler = MessageHandler::CreateDeprecated(
869       instance, handler, user_data, message_loop, &result);
870   if (message_handler)
871     data->message_handler = message_handler.Pass();
872   return result;
873 }
874
875 void PPB_Instance_Proxy::UnregisterMessageHandler(PP_Instance instance) {
876   InstanceData* data =
877       static_cast<PluginDispatcher*>(dispatcher())->GetInstanceData(instance);
878   if (!data)
879     return;
880   data->message_handler.reset();
881 }
882
883 PP_Bool PPB_Instance_Proxy::SetCursor(PP_Instance instance,
884                                       PP_MouseCursor_Type type,
885                                       PP_Resource image,
886                                       const PP_Point* hot_spot) {
887   // Some of these parameters are important for security. This check is in the
888   // plugin process just for the convenience of the caller (since we don't
889   // bother returning errors from the other process with a sync message). The
890   // parameters will be validated again in the renderer.
891   if (!ValidateSetCursorParams(type, image, hot_spot))
892     return PP_FALSE;
893
894   HostResource image_host_resource;
895   if (image) {
896     Resource* cursor_image =
897         PpapiGlobals::Get()->GetResourceTracker()->GetResource(image);
898     if (!cursor_image || cursor_image->pp_instance() != instance)
899       return PP_FALSE;
900     image_host_resource = cursor_image->host_resource();
901   }
902
903   dispatcher()->Send(new PpapiHostMsg_PPBInstance_SetCursor(
904       API_ID_PPB_INSTANCE, instance, static_cast<int32_t>(type),
905       image_host_resource, hot_spot ? *hot_spot : PP_MakePoint(0, 0)));
906   return PP_TRUE;
907 }
908
909 int32_t PPB_Instance_Proxy::LockMouse(PP_Instance instance,
910                                       scoped_refptr<TrackedCallback> callback) {
911   // Save the mouse callback on the instance data.
912   InstanceData* data = static_cast<PluginDispatcher*>(dispatcher())->
913       GetInstanceData(instance);
914   if (!data)
915     return PP_ERROR_BADARGUMENT;
916   if (TrackedCallback::IsPending(data->mouse_lock_callback))
917     return PP_ERROR_INPROGRESS;  // Already have a pending callback.
918   data->mouse_lock_callback = callback;
919
920   dispatcher()->Send(new PpapiHostMsg_PPBInstance_LockMouse(
921       API_ID_PPB_INSTANCE, instance));
922   return PP_OK_COMPLETIONPENDING;
923 }
924
925 void PPB_Instance_Proxy::UnlockMouse(PP_Instance instance) {
926   dispatcher()->Send(new PpapiHostMsg_PPBInstance_UnlockMouse(
927       API_ID_PPB_INSTANCE, instance));
928 }
929
930 void PPB_Instance_Proxy::SetTextInputType(PP_Instance instance,
931                                           PP_TextInput_Type type) {
932   CancelAnyPendingRequestSurroundingText(instance);
933   dispatcher()->Send(new PpapiHostMsg_PPBInstance_SetTextInputType(
934       API_ID_PPB_INSTANCE, instance, type));
935 }
936
937 void PPB_Instance_Proxy::UpdateCaretPosition(PP_Instance instance,
938                                              const PP_Rect& caret,
939                                              const PP_Rect& bounding_box) {
940   dispatcher()->Send(new PpapiHostMsg_PPBInstance_UpdateCaretPosition(
941       API_ID_PPB_INSTANCE, instance, caret, bounding_box));
942 }
943
944 void PPB_Instance_Proxy::CancelCompositionText(PP_Instance instance) {
945   CancelAnyPendingRequestSurroundingText(instance);
946   dispatcher()->Send(new PpapiHostMsg_PPBInstance_CancelCompositionText(
947       API_ID_PPB_INSTANCE, instance));
948 }
949
950 void PPB_Instance_Proxy::SelectionChanged(PP_Instance instance) {
951   // The "right" way to do this is to send the message to the host. However,
952   // all it will do is call RequestSurroundingText with a hardcoded number of
953   // characters in response, which is an entire IPC round-trip.
954   //
955   // We can avoid this round-trip by just implementing the
956   // RequestSurroundingText logic in the plugin process. If the logic in the
957   // host becomes more complex (like a more adaptive number of characters),
958   // we'll need to reevanuate whether we want to do the round trip instead.
959   //
960   // Be careful to post a task to avoid reentering the plugin.
961
962   InstanceData* data =
963       static_cast<PluginDispatcher*>(dispatcher())->GetInstanceData(instance);
964   if (!data)
965     return;
966   data->should_do_request_surrounding_text = true;
967
968   if (!data->is_request_surrounding_text_pending) {
969     base::MessageLoop::current()->PostTask(
970         FROM_HERE,
971         RunWhileLocked(base::Bind(&RequestSurroundingText, instance)));
972     data->is_request_surrounding_text_pending = true;
973   }
974 }
975
976 void PPB_Instance_Proxy::UpdateSurroundingText(PP_Instance instance,
977                                                const char* text,
978                                                uint32_t caret,
979                                                uint32_t anchor) {
980   dispatcher()->Send(new PpapiHostMsg_PPBInstance_UpdateSurroundingText(
981       API_ID_PPB_INSTANCE, instance, text, caret, anchor));
982 }
983
984 #if !defined(OS_NACL)
985 void PPB_Instance_Proxy::OnHostMsgGetWindowObject(
986     PP_Instance instance,
987     SerializedVarReturnValue result) {
988   if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE))
989     return;
990   EnterInstanceNoLock enter(instance);
991   if (enter.succeeded())
992     result.Return(dispatcher(), enter.functions()->GetWindowObject(instance));
993 }
994
995 void PPB_Instance_Proxy::OnHostMsgGetOwnerElementObject(
996     PP_Instance instance,
997     SerializedVarReturnValue result) {
998   if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE))
999     return;
1000   EnterInstanceNoLock enter(instance);
1001   if (enter.succeeded()) {
1002     result.Return(dispatcher(),
1003                   enter.functions()->GetOwnerElementObject(instance));
1004   }
1005 }
1006
1007 void PPB_Instance_Proxy::OnHostMsgBindGraphics(PP_Instance instance,
1008                                                PP_Resource device) {
1009   // Note that we ignroe the return value here. Otherwise, this would need to
1010   // be a slow sync call, and the plugin side of the proxy will have already
1011   // validated the resources, so we shouldn't see errors here that weren't
1012   // already caught.
1013   EnterInstanceNoLock enter(instance);
1014   if (enter.succeeded())
1015     enter.functions()->BindGraphics(instance, device);
1016 }
1017
1018 void PPB_Instance_Proxy::OnHostMsgGetAudioHardwareOutputSampleRate(
1019     PP_Instance instance, uint32_t* result) {
1020   EnterInstanceNoLock enter(instance);
1021   if (enter.succeeded())
1022     *result = enter.functions()->GetAudioHardwareOutputSampleRate(instance);
1023 }
1024
1025 void PPB_Instance_Proxy::OnHostMsgGetAudioHardwareOutputBufferSize(
1026     PP_Instance instance, uint32_t* result) {
1027   EnterInstanceNoLock enter(instance);
1028   if (enter.succeeded())
1029     *result = enter.functions()->GetAudioHardwareOutputBufferSize(instance);
1030 }
1031
1032 void PPB_Instance_Proxy::OnHostMsgIsFullFrame(PP_Instance instance,
1033                                               PP_Bool* result) {
1034   EnterInstanceNoLock enter(instance);
1035   if (enter.succeeded())
1036     *result = enter.functions()->IsFullFrame(instance);
1037 }
1038
1039 void PPB_Instance_Proxy::OnHostMsgExecuteScript(
1040     PP_Instance instance,
1041     SerializedVarReceiveInput script,
1042     SerializedVarOutParam out_exception,
1043     SerializedVarReturnValue result) {
1044   if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE))
1045     return;
1046   EnterInstanceNoLock enter(instance);
1047   if (enter.failed())
1048     return;
1049
1050   if (dispatcher()->IsPlugin())
1051     NOTREACHED();
1052   else
1053     static_cast<HostDispatcher*>(dispatcher())->set_allow_plugin_reentrancy();
1054
1055   result.Return(dispatcher(), enter.functions()->ExecuteScript(
1056       instance,
1057       script.Get(dispatcher()),
1058       out_exception.OutParam(dispatcher())));
1059 }
1060
1061 void PPB_Instance_Proxy::OnHostMsgGetDefaultCharSet(
1062     PP_Instance instance,
1063     SerializedVarReturnValue result) {
1064   if (!dispatcher()->permissions().HasPermission(PERMISSION_DEV))
1065     return;
1066   EnterInstanceNoLock enter(instance);
1067   if (enter.succeeded())
1068     result.Return(dispatcher(), enter.functions()->GetDefaultCharSet(instance));
1069 }
1070
1071 void PPB_Instance_Proxy::OnHostMsgSetPluginToHandleFindRequests(
1072     PP_Instance instance) {
1073   if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE))
1074     return;
1075   EnterInstanceNoLock enter(instance);
1076   if (enter.succeeded())
1077     enter.functions()->SetPluginToHandleFindRequests(instance);
1078 }
1079
1080 void PPB_Instance_Proxy::OnHostMsgNumberOfFindResultsChanged(
1081     PP_Instance instance,
1082     int32_t total,
1083     PP_Bool final_result) {
1084   if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE))
1085     return;
1086   EnterInstanceNoLock enter(instance);
1087   if (enter.succeeded()) {
1088     enter.functions()->NumberOfFindResultsChanged(
1089         instance, total, final_result);
1090   }
1091 }
1092
1093 void PPB_Instance_Proxy::OnHostMsgSelectFindResultChanged(
1094     PP_Instance instance,
1095     int32_t index) {
1096   if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE))
1097     return;
1098   EnterInstanceNoLock enter(instance);
1099   if (enter.succeeded())
1100     enter.functions()->SelectedFindResultChanged(instance, index);
1101 }
1102
1103 void PPB_Instance_Proxy::OnHostMsgSetTickmarks(
1104     PP_Instance instance,
1105     const std::vector<PP_Rect>& tickmarks) {
1106   if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE))
1107     return;
1108   const PP_Rect* array = tickmarks.empty() ? NULL : &tickmarks[0];
1109   EnterInstanceNoLock enter(instance);
1110   if (enter.succeeded()) {
1111     enter.functions()->SetTickmarks(instance,
1112                                     array,
1113                                     static_cast<uint32_t>(tickmarks.size()));
1114   }
1115 }
1116
1117 void PPB_Instance_Proxy::OnHostMsgSetFullscreen(PP_Instance instance,
1118                                                 PP_Bool fullscreen,
1119                                                 PP_Bool* result) {
1120   EnterInstanceNoLock enter(instance);
1121   if (enter.succeeded())
1122     *result = enter.functions()->SetFullscreen(instance, fullscreen);
1123 }
1124
1125
1126 void PPB_Instance_Proxy::OnHostMsgGetScreenSize(PP_Instance instance,
1127                                                 PP_Bool* result,
1128                                                 PP_Size* size) {
1129   EnterInstanceNoLock enter(instance);
1130   if (enter.succeeded())
1131     *result = enter.functions()->GetScreenSize(instance, size);
1132 }
1133
1134 void PPB_Instance_Proxy::OnHostMsgRequestInputEvents(PP_Instance instance,
1135                                                      bool is_filtering,
1136                                                      uint32_t event_classes) {
1137   EnterInstanceNoLock enter(instance);
1138   if (enter.succeeded()) {
1139     if (is_filtering)
1140       enter.functions()->RequestFilteringInputEvents(instance, event_classes);
1141     else
1142       enter.functions()->RequestInputEvents(instance, event_classes);
1143   }
1144 }
1145
1146 void PPB_Instance_Proxy::OnHostMsgClearInputEvents(PP_Instance instance,
1147                                                    uint32_t event_classes) {
1148   EnterInstanceNoLock enter(instance);
1149   if (enter.succeeded())
1150     enter.functions()->ClearInputEventRequest(instance, event_classes);
1151 }
1152
1153 void PPB_Instance_Proxy::OnHostMsgStartTrackingLatency(PP_Instance instance) {
1154   EnterInstanceNoLock enter(instance);
1155   if (enter.succeeded())
1156     enter.functions()->StartTrackingLatency(instance);
1157 }
1158
1159 void PPB_Instance_Proxy::OnHostMsgPostMessage(
1160     PP_Instance instance,
1161     SerializedVarReceiveInput message) {
1162   EnterInstanceNoLock enter(instance);
1163   if (!message.is_valid_var()) {
1164     PpapiGlobals::Get()->LogWithSource(
1165         instance, PP_LOGLEVEL_ERROR, std::string(), kSerializationError);
1166     return;
1167   }
1168
1169   if (enter.succeeded())
1170     enter.functions()->PostMessage(instance,
1171                                    message.GetForInstance(dispatcher(),
1172                                                           instance));
1173 }
1174
1175 void PPB_Instance_Proxy::OnHostMsgLockMouse(PP_Instance instance) {
1176   // Need to be careful to always issue the callback.
1177   pp::CompletionCallback cb = callback_factory_.NewCallback(
1178       &PPB_Instance_Proxy::MouseLockCompleteInHost, instance);
1179
1180   EnterInstanceNoLock enter(instance, cb.pp_completion_callback());
1181   if (enter.succeeded())
1182     enter.SetResult(enter.functions()->LockMouse(instance, enter.callback()));
1183 }
1184
1185 void PPB_Instance_Proxy::OnHostMsgUnlockMouse(PP_Instance instance) {
1186   EnterInstanceNoLock enter(instance);
1187   if (enter.succeeded())
1188     enter.functions()->UnlockMouse(instance);
1189 }
1190
1191 void PPB_Instance_Proxy::OnHostMsgGetDocumentURL(
1192     PP_Instance instance,
1193     PP_URLComponents_Dev* components,
1194     SerializedVarReturnValue result) {
1195   if (!dispatcher()->permissions().HasPermission(PERMISSION_DEV))
1196     return;
1197   EnterInstanceNoLock enter(instance);
1198   if (enter.succeeded()) {
1199     PP_Var document_url = enter.functions()->GetDocumentURL(instance,
1200                                                             components);
1201     result.Return(dispatcher(), document_url);
1202   }
1203 }
1204
1205 void PPB_Instance_Proxy::OnHostMsgResolveRelativeToDocument(
1206     PP_Instance instance,
1207     SerializedVarReceiveInput relative,
1208     SerializedVarReturnValue result) {
1209   if (!dispatcher()->permissions().HasPermission(PERMISSION_DEV))
1210     return;
1211   EnterInstanceNoLock enter(instance);
1212   if (enter.succeeded()) {
1213     result.Return(dispatcher(),
1214                   enter.functions()->ResolveRelativeToDocument(
1215                       instance, relative.Get(dispatcher()), NULL));
1216   }
1217 }
1218
1219 void PPB_Instance_Proxy::OnHostMsgDocumentCanRequest(
1220     PP_Instance instance,
1221     SerializedVarReceiveInput url,
1222     PP_Bool* result) {
1223   if (!dispatcher()->permissions().HasPermission(PERMISSION_DEV))
1224     return;
1225   EnterInstanceNoLock enter(instance);
1226   if (enter.succeeded()) {
1227     *result = enter.functions()->DocumentCanRequest(instance,
1228                                                     url.Get(dispatcher()));
1229   }
1230 }
1231
1232 void PPB_Instance_Proxy::OnHostMsgDocumentCanAccessDocument(PP_Instance active,
1233                                                             PP_Instance target,
1234                                                             PP_Bool* result) {
1235   if (!dispatcher()->permissions().HasPermission(PERMISSION_DEV))
1236     return;
1237   EnterInstanceNoLock enter(active);
1238   if (enter.succeeded())
1239     *result = enter.functions()->DocumentCanAccessDocument(active, target);
1240 }
1241
1242 void PPB_Instance_Proxy::OnHostMsgGetPluginInstanceURL(
1243     PP_Instance instance,
1244     SerializedVarReturnValue result) {
1245   if (!dispatcher()->permissions().HasPermission(PERMISSION_DEV))
1246     return;
1247   EnterInstanceNoLock enter(instance);
1248   if (enter.succeeded()) {
1249     result.Return(dispatcher(),
1250                   enter.functions()->GetPluginInstanceURL(instance, NULL));
1251   }
1252 }
1253
1254 void PPB_Instance_Proxy::OnHostMsgGetPluginReferrerURL(
1255     PP_Instance instance,
1256     SerializedVarReturnValue result) {
1257   if (!dispatcher()->permissions().HasPermission(PERMISSION_DEV))
1258     return;
1259   EnterInstanceNoLock enter(instance);
1260   if (enter.succeeded()) {
1261     result.Return(dispatcher(),
1262                   enter.functions()->GetPluginReferrerURL(instance, NULL));
1263   }
1264 }
1265
1266 void PPB_Instance_Proxy::OnHostMsgPromiseResolved(PP_Instance instance,
1267                                                   uint32_t promise_id) {
1268   if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE))
1269     return;
1270   EnterInstanceNoLock enter(instance);
1271   if (enter.succeeded()) {
1272     enter.functions()->PromiseResolved(instance, promise_id);
1273   }
1274 }
1275
1276 void PPB_Instance_Proxy::OnHostMsgPromiseResolvedWithSession(
1277     PP_Instance instance,
1278     uint32_t promise_id,
1279     SerializedVarReceiveInput web_session_id) {
1280   if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE))
1281     return;
1282   EnterInstanceNoLock enter(instance);
1283   if (enter.succeeded()) {
1284     enter.functions()->PromiseResolvedWithSession(
1285         instance, promise_id, web_session_id.Get(dispatcher()));
1286   }
1287 }
1288
1289 void PPB_Instance_Proxy::OnHostMsgPromiseResolvedWithKeyIds(
1290     PP_Instance instance,
1291     uint32_t promise_id,
1292     const std::vector<std::vector<uint8_t> >& key_ids) {
1293   if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE))
1294     return;
1295   if (key_ids.size() > media::limits::kMaxKeyIds) {
1296     NOTREACHED();
1297     return;
1298   }
1299
1300   scoped_refptr<ArrayVar> key_ids_array = new ArrayVar();
1301   key_ids_array->SetLength(key_ids.size());
1302   for (size_t i = 0; i < key_ids.size(); ++i) {
1303     const std::vector<uint8_t>& entry = key_ids[i];
1304     if (entry.size() < media::limits::kMinKeyIdLength ||
1305         entry.size() > media::limits::kMaxKeyIdLength) {
1306       NOTREACHED();
1307       continue;
1308     }
1309     key_ids_array->Set(
1310         i,
1311         PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar(entry.size(),
1312                                                                    &entry[0]));
1313   }
1314
1315   EnterInstanceNoLock enter(instance);
1316   if (enter.succeeded()) {
1317     ScopedPPVar key_ids_var(ScopedPPVar::PassRef(), key_ids_array->GetPPVar());
1318     enter.functions()->PromiseResolvedWithKeyIds(
1319         instance, promise_id, key_ids_var.get());
1320   }
1321 }
1322
1323 void PPB_Instance_Proxy::OnHostMsgPromiseRejected(
1324     PP_Instance instance,
1325     uint32_t promise_id,
1326     PP_CdmExceptionCode exception_code,
1327     uint32_t system_code,
1328     SerializedVarReceiveInput error_description) {
1329   if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE))
1330     return;
1331   EnterInstanceNoLock enter(instance);
1332   if (enter.succeeded()) {
1333     enter.functions()->PromiseRejected(instance,
1334                                        promise_id,
1335                                        exception_code,
1336                                        system_code,
1337                                        error_description.Get(dispatcher()));
1338   }
1339 }
1340
1341 void PPB_Instance_Proxy::OnHostMsgSessionMessage(
1342     PP_Instance instance,
1343     SerializedVarReceiveInput web_session_id,
1344     SerializedVarReceiveInput message,
1345     SerializedVarReceiveInput destination_url) {
1346   if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE))
1347     return;
1348   EnterInstanceNoLock enter(instance);
1349   if (enter.succeeded()) {
1350     enter.functions()->SessionMessage(instance,
1351                                       web_session_id.Get(dispatcher()),
1352                                       message.Get(dispatcher()),
1353                                       destination_url.Get(dispatcher()));
1354   }
1355 }
1356
1357 void PPB_Instance_Proxy::OnHostMsgSessionKeysChange(
1358     PP_Instance instance,
1359     const std::string& web_session_id,
1360     PP_Bool has_additional_usable_key) {
1361   if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE))
1362     return;
1363   EnterInstanceNoLock enter(instance);
1364   if (enter.succeeded()) {
1365     ScopedPPVar web_session_id_var(ScopedPPVar::PassRef(),
1366                                    StringVar::StringToPPVar(web_session_id));
1367     enter.functions()->SessionKeysChange(
1368         instance, web_session_id_var.get(), has_additional_usable_key);
1369   }
1370 }
1371
1372 void PPB_Instance_Proxy::OnHostMsgSessionExpirationChange(
1373     PP_Instance instance,
1374     const std::string& web_session_id,
1375     PP_Time new_expiry_time) {
1376   if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE))
1377     return;
1378   EnterInstanceNoLock enter(instance);
1379   if (enter.succeeded()) {
1380     ScopedPPVar web_session_id_var(ScopedPPVar::PassRef(),
1381                                    StringVar::StringToPPVar(web_session_id));
1382     enter.functions()->SessionExpirationChange(
1383         instance, web_session_id_var.get(), new_expiry_time);
1384   }
1385 }
1386
1387 void PPB_Instance_Proxy::OnHostMsgSessionReady(
1388     PP_Instance instance,
1389     SerializedVarReceiveInput web_session_id) {
1390   if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE))
1391     return;
1392   EnterInstanceNoLock enter(instance);
1393   if (enter.succeeded()) {
1394     enter.functions()->SessionReady(instance, web_session_id.Get(dispatcher()));
1395   }
1396 }
1397
1398 void PPB_Instance_Proxy::OnHostMsgSessionClosed(
1399     PP_Instance instance,
1400     SerializedVarReceiveInput web_session_id) {
1401   if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE))
1402     return;
1403   EnterInstanceNoLock enter(instance);
1404   if (enter.succeeded()) {
1405     enter.functions()->SessionClosed(instance,
1406                                      web_session_id.Get(dispatcher()));
1407   }
1408 }
1409
1410 void PPB_Instance_Proxy::OnHostMsgSessionError(
1411     PP_Instance instance,
1412     SerializedVarReceiveInput web_session_id,
1413     PP_CdmExceptionCode exception_code,
1414     uint32_t system_code,
1415     SerializedVarReceiveInput error_description) {
1416   if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE))
1417     return;
1418   EnterInstanceNoLock enter(instance);
1419   if (enter.succeeded()) {
1420     enter.functions()->SessionError(instance,
1421                                     web_session_id.Get(dispatcher()),
1422                                     exception_code,
1423                                     system_code,
1424                                     error_description.Get(dispatcher()));
1425   }
1426 }
1427
1428 void PPB_Instance_Proxy::OnHostMsgDeliverBlock(
1429     PP_Instance instance,
1430     PP_Resource decrypted_block,
1431     const std::string& serialized_block_info) {
1432   if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE))
1433     return;
1434   PP_DecryptedBlockInfo block_info;
1435   if (!DeserializeBlockInfo(serialized_block_info, &block_info))
1436     return;
1437
1438   EnterInstanceNoLock enter(instance);
1439   if (enter.succeeded())
1440     enter.functions()->DeliverBlock(instance, decrypted_block, &block_info);
1441 }
1442
1443 void PPB_Instance_Proxy::OnHostMsgDecoderInitializeDone(
1444     PP_Instance instance,
1445     PP_DecryptorStreamType decoder_type,
1446     uint32_t request_id,
1447     PP_Bool success) {
1448   if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE))
1449     return;
1450   EnterInstanceNoLock enter(instance);
1451   if (enter.succeeded()) {
1452     enter.functions()->DecoderInitializeDone(instance,
1453                                              decoder_type,
1454                                              request_id,
1455                                              success);
1456   }
1457 }
1458
1459 void PPB_Instance_Proxy::OnHostMsgDecoderDeinitializeDone(
1460     PP_Instance instance,
1461     PP_DecryptorStreamType decoder_type,
1462     uint32_t request_id) {
1463   if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE))
1464     return;
1465   EnterInstanceNoLock enter(instance);
1466   if (enter.succeeded())
1467     enter.functions()->DecoderDeinitializeDone(instance,
1468                                                decoder_type,
1469                                                request_id);
1470 }
1471
1472 void PPB_Instance_Proxy::OnHostMsgDecoderResetDone(
1473     PP_Instance instance,
1474     PP_DecryptorStreamType decoder_type,
1475     uint32_t request_id) {
1476   if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE))
1477     return;
1478   EnterInstanceNoLock enter(instance);
1479   if (enter.succeeded())
1480     enter.functions()->DecoderResetDone(instance, decoder_type, request_id);
1481 }
1482
1483 void PPB_Instance_Proxy::OnHostMsgDeliverFrame(
1484     PP_Instance instance,
1485     PP_Resource decrypted_frame,
1486     const std::string& serialized_frame_info) {
1487   if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE))
1488     return;
1489   PP_DecryptedFrameInfo frame_info;
1490   if (!DeserializeBlockInfo(serialized_frame_info, &frame_info))
1491     return;
1492
1493   EnterInstanceNoLock enter(instance);
1494   if (enter.succeeded())
1495     enter.functions()->DeliverFrame(instance, decrypted_frame, &frame_info);
1496 }
1497
1498 void PPB_Instance_Proxy::OnHostMsgDeliverSamples(
1499     PP_Instance instance,
1500     PP_Resource audio_frames,
1501     const std::string& serialized_sample_info) {
1502   if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE))
1503     return;
1504   PP_DecryptedSampleInfo sample_info;
1505   if (!DeserializeBlockInfo(serialized_sample_info, &sample_info))
1506     return;
1507
1508   EnterInstanceNoLock enter(instance);
1509   if (enter.succeeded())
1510     enter.functions()->DeliverSamples(instance, audio_frames, &sample_info);
1511 }
1512
1513 void PPB_Instance_Proxy::OnHostMsgSetCursor(
1514     PP_Instance instance,
1515     int32_t type,
1516     const ppapi::HostResource& custom_image,
1517     const PP_Point& hot_spot) {
1518   // This API serves PPB_CursorControl_Dev and PPB_MouseCursor, so is public.
1519   EnterInstanceNoLock enter(instance);
1520   if (enter.succeeded()) {
1521     enter.functions()->SetCursor(
1522         instance, static_cast<PP_MouseCursor_Type>(type),
1523         custom_image.host_resource(), &hot_spot);
1524   }
1525 }
1526
1527 void PPB_Instance_Proxy::OnHostMsgSetTextInputType(PP_Instance instance,
1528                                                    PP_TextInput_Type type) {
1529   EnterInstanceNoLock enter(instance);
1530   if (enter.succeeded())
1531     enter.functions()->SetTextInputType(instance, type);
1532 }
1533
1534 void PPB_Instance_Proxy::OnHostMsgUpdateCaretPosition(
1535     PP_Instance instance,
1536     const PP_Rect& caret,
1537     const PP_Rect& bounding_box) {
1538   EnterInstanceNoLock enter(instance);
1539   if (enter.succeeded())
1540     enter.functions()->UpdateCaretPosition(instance, caret, bounding_box);
1541 }
1542
1543 void PPB_Instance_Proxy::OnHostMsgCancelCompositionText(PP_Instance instance) {
1544   EnterInstanceNoLock enter(instance);
1545   if (enter.succeeded())
1546     enter.functions()->CancelCompositionText(instance);
1547 }
1548
1549 void PPB_Instance_Proxy::OnHostMsgUpdateSurroundingText(
1550     PP_Instance instance,
1551     const std::string& text,
1552     uint32_t caret,
1553     uint32_t anchor) {
1554   EnterInstanceNoLock enter(instance);
1555   if (enter.succeeded()) {
1556     enter.functions()->UpdateSurroundingText(instance, text.c_str(), caret,
1557                                              anchor);
1558   }
1559 }
1560 #endif  // !defined(OS_NACL)
1561
1562 void PPB_Instance_Proxy::OnPluginMsgMouseLockComplete(PP_Instance instance,
1563                                                       int32_t result) {
1564   if (!dispatcher()->IsPlugin())
1565     return;
1566
1567   // Save the mouse callback on the instance data.
1568   InstanceData* data = static_cast<PluginDispatcher*>(dispatcher())->
1569       GetInstanceData(instance);
1570   if (!data)
1571     return;  // Instance was probably deleted.
1572   if (!TrackedCallback::IsPending(data->mouse_lock_callback)) {
1573     NOTREACHED();
1574     return;
1575   }
1576   data->mouse_lock_callback->Run(result);
1577 }
1578
1579 #if !defined(OS_NACL)
1580 void PPB_Instance_Proxy::MouseLockCompleteInHost(int32_t result,
1581                                                  PP_Instance instance) {
1582   dispatcher()->Send(new PpapiMsg_PPBInstance_MouseLockComplete(
1583       API_ID_PPB_INSTANCE, instance, result));
1584 }
1585 #endif  // !defined(OS_NACL)
1586
1587 void PPB_Instance_Proxy::CancelAnyPendingRequestSurroundingText(
1588     PP_Instance instance) {
1589   InstanceData* data = static_cast<PluginDispatcher*>(dispatcher())->
1590       GetInstanceData(instance);
1591   if (!data)
1592     return;  // Instance was probably deleted.
1593   data->should_do_request_surrounding_text = false;
1594 }
1595
1596 }  // namespace proxy
1597 }  // namespace ppapi