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