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 <utility>
8 
9 #include "base/bind.h"
10 #include "base/memory/ref_counted.h"
11 #include "base/numerics/safe_conversions.h"
12 #include "build/build_config.h"
13 #include "media/base/limits.h"
14 #include "ppapi/c/pp_errors.h"
15 #include "ppapi/c/pp_time.h"
16 #include "ppapi/c/pp_var.h"
17 #include "ppapi/c/ppb_audio_config.h"
18 #include "ppapi/c/ppb_instance.h"
19 #include "ppapi/c/ppb_messaging.h"
20 #include "ppapi/c/ppb_mouse_lock.h"
21 #include "ppapi/proxy/browser_font_singleton_resource.h"
22 #include "ppapi/proxy/enter_proxy.h"
23 #include "ppapi/proxy/flash_fullscreen_resource.h"
24 #include "ppapi/proxy/gamepad_resource.h"
25 #include "ppapi/proxy/host_dispatcher.h"
26 #include "ppapi/proxy/isolated_file_system_private_resource.h"
27 #include "ppapi/proxy/message_handler.h"
28 #include "ppapi/proxy/network_proxy_resource.h"
29 #include "ppapi/proxy/pdf_resource.h"
30 #include "ppapi/proxy/plugin_dispatcher.h"
31 #include "ppapi/proxy/ppapi_messages.h"
32 #include "ppapi/proxy/serialized_var.h"
33 #include "ppapi/proxy/uma_private_resource.h"
34 #include "ppapi/shared_impl/array_var.h"
35 #include "ppapi/shared_impl/ppapi_globals.h"
36 #include "ppapi/shared_impl/ppb_url_util_shared.h"
37 #include "ppapi/shared_impl/ppb_view_shared.h"
38 #include "ppapi/shared_impl/scoped_pp_var.h"
39 #include "ppapi/shared_impl/var.h"
40 #include "ppapi/thunk/enter.h"
41 #include "ppapi/thunk/ppb_graphics_2d_api.h"
42 #include "ppapi/thunk/ppb_graphics_3d_api.h"
43 #include "ppapi/thunk/thunk.h"
44 
45 // Windows headers interfere with this file.
46 #ifdef PostMessage
47 #undef PostMessage
48 #endif
49 
50 using ppapi::thunk::EnterInstanceNoLock;
51 using ppapi::thunk::EnterResourceNoLock;
52 using ppapi::thunk::PPB_Graphics2D_API;
53 using ppapi::thunk::PPB_Graphics3D_API;
54 using ppapi::thunk::PPB_Instance_API;
55 
56 namespace ppapi {
57 namespace proxy {
58 
59 namespace {
60 
61 #if !defined(OS_NACL)
62 const char kSerializationError[] = "Failed to convert a PostMessage "
63     "argument from a PP_Var to a Javascript value. It may have cycles or be of "
64     "an unsupported type.";
65 #endif
66 
RequestSurroundingText(PP_Instance instance)67 void RequestSurroundingText(PP_Instance instance) {
68   PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance);
69   if (!dispatcher)
70     return;  // Instance has gone away while message was pending.
71 
72   InstanceData* data = dispatcher->GetInstanceData(instance);
73   DCHECK(data);  // Should have it, since we still have a dispatcher.
74   data->is_request_surrounding_text_pending = false;
75   if (!data->should_do_request_surrounding_text)
76     return;
77 
78   // Just fake out a RequestSurroundingText message to the proxy for the PPP
79   // interface.
80   InterfaceProxy* proxy = dispatcher->GetInterfaceProxy(API_ID_PPP_TEXT_INPUT);
81   if (!proxy)
82     return;
83   proxy->OnMessageReceived(PpapiMsg_PPPTextInput_RequestSurroundingText(
84       API_ID_PPP_TEXT_INPUT, instance,
85       PPB_Instance_Shared::kExtraCharsForTextInput));
86 }
87 
88 }  // namespace
89 
PPB_Instance_Proxy(Dispatcher * dispatcher)90 PPB_Instance_Proxy::PPB_Instance_Proxy(Dispatcher* dispatcher)
91     : InterfaceProxy(dispatcher),
92       callback_factory_(this) {
93 }
94 
~PPB_Instance_Proxy()95 PPB_Instance_Proxy::~PPB_Instance_Proxy() {
96 }
97 
OnMessageReceived(const IPC::Message & msg)98 bool PPB_Instance_Proxy::OnMessageReceived(const IPC::Message& msg) {
99   // Prevent the dispatcher from going away during a call to ExecuteScript.
100   // This must happen OUTSIDE of ExecuteScript since the SerializedVars use
101   // the dispatcher upon return of the function (converting the
102   // SerializedVarReturnValue/OutParam to a SerializedVar in the destructor).
103 #if !defined(OS_NACL)
104   ScopedModuleReference death_grip(dispatcher());
105 #endif
106 
107   bool handled = true;
108   IPC_BEGIN_MESSAGE_MAP(PPB_Instance_Proxy, msg)
109 #if !defined(OS_NACL)
110     // Plugin -> Host messages.
111     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_GetWindowObject,
112                         OnHostMsgGetWindowObject)
113     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_GetOwnerElementObject,
114                         OnHostMsgGetOwnerElementObject)
115     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_BindGraphics,
116                         OnHostMsgBindGraphics)
117     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_IsFullFrame,
118                         OnHostMsgIsFullFrame)
119     IPC_MESSAGE_HANDLER(
120         PpapiHostMsg_PPBInstance_GetAudioHardwareOutputSampleRate,
121         OnHostMsgGetAudioHardwareOutputSampleRate)
122     IPC_MESSAGE_HANDLER(
123         PpapiHostMsg_PPBInstance_GetAudioHardwareOutputBufferSize,
124         OnHostMsgGetAudioHardwareOutputBufferSize)
125     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_ExecuteScript,
126                         OnHostMsgExecuteScript)
127     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_GetDefaultCharSet,
128                         OnHostMsgGetDefaultCharSet)
129     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_SetPluginToHandleFindRequests,
130                         OnHostMsgSetPluginToHandleFindRequests);
131     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_NumberOfFindResultsChanged,
132                         OnHostMsgNumberOfFindResultsChanged)
133     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_SelectFindResultChanged,
134                         OnHostMsgSelectFindResultChanged)
135     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_SetTickmarks,
136                         OnHostMsgSetTickmarks)
137     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_PostMessage,
138                         OnHostMsgPostMessage)
139     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_SetFullscreen,
140                         OnHostMsgSetFullscreen)
141     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_GetScreenSize,
142                         OnHostMsgGetScreenSize)
143     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_RequestInputEvents,
144                         OnHostMsgRequestInputEvents)
145     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_ClearInputEvents,
146                         OnHostMsgClearInputEvents)
147     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_LockMouse,
148                         OnHostMsgLockMouse)
149     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_UnlockMouse,
150                         OnHostMsgUnlockMouse)
151     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_SetCursor,
152                         OnHostMsgSetCursor)
153     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_SetTextInputType,
154                         OnHostMsgSetTextInputType)
155     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_UpdateCaretPosition,
156                         OnHostMsgUpdateCaretPosition)
157     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_CancelCompositionText,
158                         OnHostMsgCancelCompositionText)
159     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_UpdateSurroundingText,
160                         OnHostMsgUpdateSurroundingText)
161     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_GetDocumentURL,
162                         OnHostMsgGetDocumentURL)
163     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_ResolveRelativeToDocument,
164                         OnHostMsgResolveRelativeToDocument)
165     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_DocumentCanRequest,
166                         OnHostMsgDocumentCanRequest)
167     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_DocumentCanAccessDocument,
168                         OnHostMsgDocumentCanAccessDocument)
169     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_GetPluginInstanceURL,
170                         OnHostMsgGetPluginInstanceURL)
171     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_GetPluginReferrerURL,
172                         OnHostMsgGetPluginReferrerURL)
173 #endif  // !defined(OS_NACL)
174 
175     // Host -> Plugin messages.
176     IPC_MESSAGE_HANDLER(PpapiMsg_PPBInstance_MouseLockComplete,
177                         OnPluginMsgMouseLockComplete)
178 
179     IPC_MESSAGE_UNHANDLED(handled = false)
180   IPC_END_MESSAGE_MAP()
181   return handled;
182 }
183 
BindGraphics(PP_Instance instance,PP_Resource device)184 PP_Bool PPB_Instance_Proxy::BindGraphics(PP_Instance instance,
185                                          PP_Resource device) {
186   // If device is 0, pass a null HostResource. This signals the host to unbind
187   // all devices.
188   PP_Resource pp_resource = 0;
189   if (device) {
190     Resource* resource =
191         PpapiGlobals::Get()->GetResourceTracker()->GetResource(device);
192     if (!resource || resource->pp_instance() != instance)
193       return PP_FALSE;
194     // We need to pass different resource to Graphics 2D and 3D right now.  Once
195     // 3D is migrated to the new design, we should be able to unify this.
196     if (resource->AsPPB_Graphics3D_API()) {
197       pp_resource = resource->host_resource().host_resource();
198     } else if (resource->AsPPB_Graphics2D_API()) {
199       pp_resource = resource->pp_resource();
200     } else {
201       // A bad resource.
202       return PP_FALSE;
203     }
204   }
205   dispatcher()->Send(new PpapiHostMsg_PPBInstance_BindGraphics(
206         API_ID_PPB_INSTANCE, instance, pp_resource));
207   return PP_TRUE;
208 }
209 
IsFullFrame(PP_Instance instance)210 PP_Bool PPB_Instance_Proxy::IsFullFrame(PP_Instance instance) {
211   PP_Bool result = PP_FALSE;
212   dispatcher()->Send(new PpapiHostMsg_PPBInstance_IsFullFrame(
213       API_ID_PPB_INSTANCE, instance, &result));
214   return result;
215 }
216 
GetViewData(PP_Instance instance)217 const ViewData* PPB_Instance_Proxy::GetViewData(PP_Instance instance) {
218   InstanceData* data = static_cast<PluginDispatcher*>(dispatcher())->
219       GetInstanceData(instance);
220   if (!data)
221     return NULL;
222   return &data->view;
223 }
224 
GetWindowObject(PP_Instance instance)225 PP_Var PPB_Instance_Proxy::GetWindowObject(PP_Instance instance) {
226   ReceiveSerializedVarReturnValue result;
227   dispatcher()->Send(new PpapiHostMsg_PPBInstance_GetWindowObject(
228       API_ID_PPB_INSTANCE, instance, &result));
229   return result.Return(dispatcher());
230 }
231 
GetOwnerElementObject(PP_Instance instance)232 PP_Var PPB_Instance_Proxy::GetOwnerElementObject(PP_Instance instance) {
233   ReceiveSerializedVarReturnValue result;
234   dispatcher()->Send(new PpapiHostMsg_PPBInstance_GetOwnerElementObject(
235       API_ID_PPB_INSTANCE, instance, &result));
236   return result.Return(dispatcher());
237 }
238 
ExecuteScript(PP_Instance instance,PP_Var script,PP_Var * exception)239 PP_Var PPB_Instance_Proxy::ExecuteScript(PP_Instance instance,
240                                          PP_Var script,
241                                          PP_Var* exception) {
242   ReceiveSerializedException se(dispatcher(), exception);
243   if (se.IsThrown())
244     return PP_MakeUndefined();
245 
246   ReceiveSerializedVarReturnValue result;
247   dispatcher()->Send(new PpapiHostMsg_PPBInstance_ExecuteScript(
248       API_ID_PPB_INSTANCE, instance,
249       SerializedVarSendInput(dispatcher(), script), &se, &result));
250   return result.Return(dispatcher());
251 }
252 
GetAudioHardwareOutputSampleRate(PP_Instance instance)253 uint32_t PPB_Instance_Proxy::GetAudioHardwareOutputSampleRate(
254     PP_Instance instance) {
255   uint32_t result = PP_AUDIOSAMPLERATE_NONE;
256   dispatcher()->Send(
257       new PpapiHostMsg_PPBInstance_GetAudioHardwareOutputSampleRate(
258           API_ID_PPB_INSTANCE, instance, &result));
259   return result;
260 }
261 
GetAudioHardwareOutputBufferSize(PP_Instance instance)262 uint32_t PPB_Instance_Proxy::GetAudioHardwareOutputBufferSize(
263     PP_Instance instance) {
264   uint32_t result = 0;
265   dispatcher()->Send(
266       new PpapiHostMsg_PPBInstance_GetAudioHardwareOutputBufferSize(
267           API_ID_PPB_INSTANCE, instance, &result));
268   return result;
269 }
270 
GetDefaultCharSet(PP_Instance instance)271 PP_Var PPB_Instance_Proxy::GetDefaultCharSet(PP_Instance instance) {
272   PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance);
273   if (!dispatcher)
274     return PP_MakeUndefined();
275 
276   ReceiveSerializedVarReturnValue result;
277   dispatcher->Send(new PpapiHostMsg_PPBInstance_GetDefaultCharSet(
278       API_ID_PPB_INSTANCE, instance, &result));
279   return result.Return(dispatcher);
280 }
281 
SetPluginToHandleFindRequests(PP_Instance instance)282 void PPB_Instance_Proxy::SetPluginToHandleFindRequests(PP_Instance instance) {
283   dispatcher()->Send(new PpapiHostMsg_PPBInstance_SetPluginToHandleFindRequests(
284       API_ID_PPB_INSTANCE, instance));
285 }
286 
NumberOfFindResultsChanged(PP_Instance instance,int32_t total,PP_Bool final_result)287 void PPB_Instance_Proxy::NumberOfFindResultsChanged(PP_Instance instance,
288                                                     int32_t total,
289                                                     PP_Bool final_result) {
290   dispatcher()->Send(new PpapiHostMsg_PPBInstance_NumberOfFindResultsChanged(
291       API_ID_PPB_INSTANCE, instance, total, final_result));
292 }
293 
SelectedFindResultChanged(PP_Instance instance,int32_t index)294 void PPB_Instance_Proxy::SelectedFindResultChanged(PP_Instance instance,
295                                                    int32_t index) {
296   dispatcher()->Send(new PpapiHostMsg_PPBInstance_SelectFindResultChanged(
297       API_ID_PPB_INSTANCE, instance, index));
298 }
299 
SetTickmarks(PP_Instance instance,const PP_Rect * tickmarks,uint32_t count)300 void PPB_Instance_Proxy::SetTickmarks(PP_Instance instance,
301                                       const PP_Rect* tickmarks,
302                                       uint32_t count) {
303   dispatcher()->Send(new PpapiHostMsg_PPBInstance_SetTickmarks(
304       API_ID_PPB_INSTANCE, instance,
305       std::vector<PP_Rect>(tickmarks, tickmarks + count)));
306 }
307 
IsFullscreen(PP_Instance instance)308 PP_Bool PPB_Instance_Proxy::IsFullscreen(PP_Instance instance) {
309   InstanceData* data = static_cast<PluginDispatcher*>(dispatcher())->
310       GetInstanceData(instance);
311   if (!data)
312     return PP_FALSE;
313   return PP_FromBool(data->view.is_fullscreen);
314 }
315 
SetFullscreen(PP_Instance instance,PP_Bool fullscreen)316 PP_Bool PPB_Instance_Proxy::SetFullscreen(PP_Instance instance,
317                                           PP_Bool fullscreen) {
318   PP_Bool result = PP_FALSE;
319   dispatcher()->Send(new PpapiHostMsg_PPBInstance_SetFullscreen(
320       API_ID_PPB_INSTANCE, instance, fullscreen, &result));
321   return result;
322 }
323 
GetScreenSize(PP_Instance instance,PP_Size * size)324 PP_Bool PPB_Instance_Proxy::GetScreenSize(PP_Instance instance,
325                                           PP_Size* size) {
326   PP_Bool result = PP_FALSE;
327   dispatcher()->Send(new PpapiHostMsg_PPBInstance_GetScreenSize(
328       API_ID_PPB_INSTANCE, instance, &result, size));
329   return result;
330 }
331 
GetSingletonResource(PP_Instance instance,SingletonResourceID id)332 Resource* PPB_Instance_Proxy::GetSingletonResource(PP_Instance instance,
333                                                    SingletonResourceID id) {
334   InstanceData* data = static_cast<PluginDispatcher*>(dispatcher())->
335       GetInstanceData(instance);
336 
337   InstanceData::SingletonResourceMap::iterator it =
338       data->singleton_resources.find(id);
339   if (it != data->singleton_resources.end())
340     return it->second.get();
341 
342   scoped_refptr<Resource> new_singleton;
343   Connection connection(PluginGlobals::Get()->GetBrowserSender(),
344                         static_cast<PluginDispatcher*>(dispatcher())->sender());
345 
346   switch (id) {
347     case GAMEPAD_SINGLETON_ID:
348       new_singleton = new GamepadResource(connection, instance);
349       break;
350     case ISOLATED_FILESYSTEM_SINGLETON_ID:
351       new_singleton =
352           new IsolatedFileSystemPrivateResource(connection, instance);
353       break;
354     case NETWORK_PROXY_SINGLETON_ID:
355       new_singleton = new NetworkProxyResource(connection, instance);
356       break;
357     case UMA_SINGLETON_ID:
358       new_singleton = new UMAPrivateResource(connection, instance);
359       break;
360 // Flash/trusted resources aren't needed for NaCl.
361 #if !defined(OS_NACL) && !defined(NACL_WIN64)
362     case BROWSER_FONT_SINGLETON_ID:
363       new_singleton = new BrowserFontSingletonResource(connection, instance);
364       break;
365     case FLASH_FULLSCREEN_SINGLETON_ID:
366       new_singleton = new FlashFullscreenResource(connection, instance);
367       break;
368     case PDF_SINGLETON_ID:
369       new_singleton = new PDFResource(connection, instance);
370       break;
371 #else
372     case BROWSER_FONT_SINGLETON_ID:
373     case FLASH_FULLSCREEN_SINGLETON_ID:
374     case PDF_SINGLETON_ID:
375       NOTREACHED();
376       break;
377 #endif  // !defined(OS_NACL) && !defined(NACL_WIN64)
378   }
379 
380   if (!new_singleton.get()) {
381     // Getting here implies that a constructor is missing in the above switch.
382     NOTREACHED();
383     return NULL;
384   }
385 
386   data->singleton_resources[id] = new_singleton;
387   return new_singleton.get();
388 }
389 
RequestInputEvents(PP_Instance instance,uint32_t event_classes)390 int32_t PPB_Instance_Proxy::RequestInputEvents(PP_Instance instance,
391                                                uint32_t event_classes) {
392   dispatcher()->Send(new PpapiHostMsg_PPBInstance_RequestInputEvents(
393       API_ID_PPB_INSTANCE, instance, false, event_classes));
394 
395   // We always register for the classes we can handle, this function validates
396   // the flags so we can notify it if anything was invalid, without requiring
397   // a sync reply.
398   return ValidateRequestInputEvents(false, event_classes);
399 }
400 
RequestFilteringInputEvents(PP_Instance instance,uint32_t event_classes)401 int32_t PPB_Instance_Proxy::RequestFilteringInputEvents(
402     PP_Instance instance,
403     uint32_t event_classes) {
404   dispatcher()->Send(new PpapiHostMsg_PPBInstance_RequestInputEvents(
405       API_ID_PPB_INSTANCE, instance, true, event_classes));
406 
407   // We always register for the classes we can handle, this function validates
408   // the flags so we can notify it if anything was invalid, without requiring
409   // a sync reply.
410   return ValidateRequestInputEvents(true, event_classes);
411 }
412 
ClearInputEventRequest(PP_Instance instance,uint32_t event_classes)413 void PPB_Instance_Proxy::ClearInputEventRequest(PP_Instance instance,
414                                                 uint32_t event_classes) {
415   dispatcher()->Send(new PpapiHostMsg_PPBInstance_ClearInputEvents(
416       API_ID_PPB_INSTANCE, instance, event_classes));
417 }
418 
GetDocumentURL(PP_Instance instance,PP_URLComponents_Dev * components)419 PP_Var PPB_Instance_Proxy::GetDocumentURL(PP_Instance instance,
420                                           PP_URLComponents_Dev* components) {
421   ReceiveSerializedVarReturnValue result;
422   PP_URLComponents_Dev url_components = {{0}};
423   dispatcher()->Send(new PpapiHostMsg_PPBInstance_GetDocumentURL(
424       API_ID_PPB_INSTANCE, instance, &url_components, &result));
425   if (components)
426     *components = url_components;
427   return result.Return(dispatcher());
428 }
429 
430 #if !defined(OS_NACL)
ResolveRelativeToDocument(PP_Instance instance,PP_Var relative,PP_URLComponents_Dev * components)431 PP_Var PPB_Instance_Proxy::ResolveRelativeToDocument(
432     PP_Instance instance,
433     PP_Var relative,
434     PP_URLComponents_Dev* components) {
435   ReceiveSerializedVarReturnValue result;
436   dispatcher()->Send(new PpapiHostMsg_PPBInstance_ResolveRelativeToDocument(
437       API_ID_PPB_INSTANCE, instance,
438       SerializedVarSendInput(dispatcher(), relative),
439       &result));
440   return PPB_URLUtil_Shared::ConvertComponentsAndReturnURL(
441       result.Return(dispatcher()),
442       components);
443 }
444 
DocumentCanRequest(PP_Instance instance,PP_Var url)445 PP_Bool PPB_Instance_Proxy::DocumentCanRequest(PP_Instance instance,
446                                                PP_Var url) {
447   PP_Bool result = PP_FALSE;
448   dispatcher()->Send(new PpapiHostMsg_PPBInstance_DocumentCanRequest(
449       API_ID_PPB_INSTANCE, instance,
450       SerializedVarSendInput(dispatcher(), url),
451       &result));
452   return result;
453 }
454 
DocumentCanAccessDocument(PP_Instance instance,PP_Instance target)455 PP_Bool PPB_Instance_Proxy::DocumentCanAccessDocument(PP_Instance instance,
456                                                       PP_Instance target) {
457   PP_Bool result = PP_FALSE;
458   dispatcher()->Send(new PpapiHostMsg_PPBInstance_DocumentCanAccessDocument(
459       API_ID_PPB_INSTANCE, instance, target, &result));
460   return result;
461 }
462 
GetPluginInstanceURL(PP_Instance instance,PP_URLComponents_Dev * components)463 PP_Var PPB_Instance_Proxy::GetPluginInstanceURL(
464       PP_Instance instance,
465       PP_URLComponents_Dev* components) {
466   ReceiveSerializedVarReturnValue result;
467   dispatcher()->Send(new PpapiHostMsg_PPBInstance_GetPluginInstanceURL(
468       API_ID_PPB_INSTANCE, instance, &result));
469   return PPB_URLUtil_Shared::ConvertComponentsAndReturnURL(
470       result.Return(dispatcher()),
471       components);
472 }
473 
GetPluginReferrerURL(PP_Instance instance,PP_URLComponents_Dev * components)474 PP_Var PPB_Instance_Proxy::GetPluginReferrerURL(
475       PP_Instance instance,
476       PP_URLComponents_Dev* components) {
477   ReceiveSerializedVarReturnValue result;
478   dispatcher()->Send(new PpapiHostMsg_PPBInstance_GetPluginReferrerURL(
479       API_ID_PPB_INSTANCE, instance, &result));
480   return PPB_URLUtil_Shared::ConvertComponentsAndReturnURL(
481       result.Return(dispatcher()),
482       components);
483 }
484 #endif  // !defined(OS_NACL)
485 
PostMessage(PP_Instance instance,PP_Var message)486 void PPB_Instance_Proxy::PostMessage(PP_Instance instance,
487                                      PP_Var message) {
488   dispatcher()->Send(new PpapiHostMsg_PPBInstance_PostMessage(
489       API_ID_PPB_INSTANCE,
490       instance, SerializedVarSendInputShmem(dispatcher(), message,
491                                             instance)));
492 }
493 
RegisterMessageHandler(PP_Instance instance,void * user_data,const PPP_MessageHandler_0_2 * handler,PP_Resource message_loop)494 int32_t PPB_Instance_Proxy::RegisterMessageHandler(
495     PP_Instance instance,
496     void* user_data,
497     const PPP_MessageHandler_0_2* handler,
498     PP_Resource message_loop) {
499   InstanceData* data =
500       static_cast<PluginDispatcher*>(dispatcher())->GetInstanceData(instance);
501   if (!data)
502     return PP_ERROR_BADARGUMENT;
503 
504   int32_t result = PP_ERROR_FAILED;
505   std::unique_ptr<MessageHandler> message_handler = MessageHandler::Create(
506       instance, handler, user_data, message_loop, &result);
507   if (message_handler)
508     data->message_handler = std::move(message_handler);
509   return result;
510 }
511 
UnregisterMessageHandler(PP_Instance instance)512 void PPB_Instance_Proxy::UnregisterMessageHandler(PP_Instance instance) {
513   InstanceData* data =
514       static_cast<PluginDispatcher*>(dispatcher())->GetInstanceData(instance);
515   if (!data)
516     return;
517   data->message_handler.reset();
518 }
519 
SetCursor(PP_Instance instance,PP_MouseCursor_Type type,PP_Resource image,const PP_Point * hot_spot)520 PP_Bool PPB_Instance_Proxy::SetCursor(PP_Instance instance,
521                                       PP_MouseCursor_Type type,
522                                       PP_Resource image,
523                                       const PP_Point* hot_spot) {
524   // Some of these parameters are important for security. This check is in the
525   // plugin process just for the convenience of the caller (since we don't
526   // bother returning errors from the other process with a sync message). The
527   // parameters will be validated again in the renderer.
528   if (!ValidateSetCursorParams(type, image, hot_spot))
529     return PP_FALSE;
530 
531   HostResource image_host_resource;
532   if (image) {
533     Resource* cursor_image =
534         PpapiGlobals::Get()->GetResourceTracker()->GetResource(image);
535     if (!cursor_image || cursor_image->pp_instance() != instance)
536       return PP_FALSE;
537     image_host_resource = cursor_image->host_resource();
538   }
539 
540   dispatcher()->Send(new PpapiHostMsg_PPBInstance_SetCursor(
541       API_ID_PPB_INSTANCE, instance, static_cast<int32_t>(type),
542       image_host_resource, hot_spot ? *hot_spot : PP_MakePoint(0, 0)));
543   return PP_TRUE;
544 }
545 
LockMouse(PP_Instance instance,scoped_refptr<TrackedCallback> callback)546 int32_t PPB_Instance_Proxy::LockMouse(PP_Instance instance,
547                                       scoped_refptr<TrackedCallback> callback) {
548   // Save the mouse callback on the instance data.
549   InstanceData* data = static_cast<PluginDispatcher*>(dispatcher())->
550       GetInstanceData(instance);
551   if (!data)
552     return PP_ERROR_BADARGUMENT;
553   if (TrackedCallback::IsPending(data->mouse_lock_callback))
554     return PP_ERROR_INPROGRESS;  // Already have a pending callback.
555   data->mouse_lock_callback = callback;
556 
557   dispatcher()->Send(new PpapiHostMsg_PPBInstance_LockMouse(
558       API_ID_PPB_INSTANCE, instance));
559   return PP_OK_COMPLETIONPENDING;
560 }
561 
UnlockMouse(PP_Instance instance)562 void PPB_Instance_Proxy::UnlockMouse(PP_Instance instance) {
563   dispatcher()->Send(new PpapiHostMsg_PPBInstance_UnlockMouse(
564       API_ID_PPB_INSTANCE, instance));
565 }
566 
SetTextInputType(PP_Instance instance,PP_TextInput_Type type)567 void PPB_Instance_Proxy::SetTextInputType(PP_Instance instance,
568                                           PP_TextInput_Type type) {
569   CancelAnyPendingRequestSurroundingText(instance);
570   dispatcher()->Send(new PpapiHostMsg_PPBInstance_SetTextInputType(
571       API_ID_PPB_INSTANCE, instance, type));
572 }
573 
UpdateCaretPosition(PP_Instance instance,const PP_Rect & caret,const PP_Rect & bounding_box)574 void PPB_Instance_Proxy::UpdateCaretPosition(PP_Instance instance,
575                                              const PP_Rect& caret,
576                                              const PP_Rect& bounding_box) {
577   dispatcher()->Send(new PpapiHostMsg_PPBInstance_UpdateCaretPosition(
578       API_ID_PPB_INSTANCE, instance, caret, bounding_box));
579 }
580 
CancelCompositionText(PP_Instance instance)581 void PPB_Instance_Proxy::CancelCompositionText(PP_Instance instance) {
582   CancelAnyPendingRequestSurroundingText(instance);
583   dispatcher()->Send(new PpapiHostMsg_PPBInstance_CancelCompositionText(
584       API_ID_PPB_INSTANCE, instance));
585 }
586 
SelectionChanged(PP_Instance instance)587 void PPB_Instance_Proxy::SelectionChanged(PP_Instance instance) {
588   // The "right" way to do this is to send the message to the host. However,
589   // all it will do is call RequestSurroundingText with a hardcoded number of
590   // characters in response, which is an entire IPC round-trip.
591   //
592   // We can avoid this round-trip by just implementing the
593   // RequestSurroundingText logic in the plugin process. If the logic in the
594   // host becomes more complex (like a more adaptive number of characters),
595   // we'll need to reevanuate whether we want to do the round trip instead.
596   //
597   // Be careful to post a task to avoid reentering the plugin.
598 
599   InstanceData* data =
600       static_cast<PluginDispatcher*>(dispatcher())->GetInstanceData(instance);
601   if (!data)
602     return;
603   data->should_do_request_surrounding_text = true;
604 
605   if (!data->is_request_surrounding_text_pending) {
606     PpapiGlobals::Get()->GetMainThreadMessageLoop()->PostTask(
607         FROM_HERE,
608         RunWhileLocked(base::BindOnce(&RequestSurroundingText, instance)));
609     data->is_request_surrounding_text_pending = true;
610   }
611 }
612 
UpdateSurroundingText(PP_Instance instance,const char * text,uint32_t caret,uint32_t anchor)613 void PPB_Instance_Proxy::UpdateSurroundingText(PP_Instance instance,
614                                                const char* text,
615                                                uint32_t caret,
616                                                uint32_t anchor) {
617   dispatcher()->Send(new PpapiHostMsg_PPBInstance_UpdateSurroundingText(
618       API_ID_PPB_INSTANCE, instance, text, caret, anchor));
619 }
620 
621 #if !defined(OS_NACL)
OnHostMsgGetWindowObject(PP_Instance instance,SerializedVarReturnValue result)622 void PPB_Instance_Proxy::OnHostMsgGetWindowObject(
623     PP_Instance instance,
624     SerializedVarReturnValue result) {
625   if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE))
626     return;
627   EnterInstanceNoLock enter(instance);
628   if (enter.succeeded())
629     result.Return(dispatcher(), enter.functions()->GetWindowObject(instance));
630 }
631 
OnHostMsgGetOwnerElementObject(PP_Instance instance,SerializedVarReturnValue result)632 void PPB_Instance_Proxy::OnHostMsgGetOwnerElementObject(
633     PP_Instance instance,
634     SerializedVarReturnValue result) {
635   if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE))
636     return;
637   EnterInstanceNoLock enter(instance);
638   if (enter.succeeded()) {
639     result.Return(dispatcher(),
640                   enter.functions()->GetOwnerElementObject(instance));
641   }
642 }
643 
OnHostMsgBindGraphics(PP_Instance instance,PP_Resource device)644 void PPB_Instance_Proxy::OnHostMsgBindGraphics(PP_Instance instance,
645                                                PP_Resource device) {
646   // Note that we ignroe the return value here. Otherwise, this would need to
647   // be a slow sync call, and the plugin side of the proxy will have already
648   // validated the resources, so we shouldn't see errors here that weren't
649   // already caught.
650   EnterInstanceNoLock enter(instance);
651   if (enter.succeeded())
652     enter.functions()->BindGraphics(instance, device);
653 }
654 
OnHostMsgGetAudioHardwareOutputSampleRate(PP_Instance instance,uint32_t * result)655 void PPB_Instance_Proxy::OnHostMsgGetAudioHardwareOutputSampleRate(
656     PP_Instance instance, uint32_t* result) {
657   EnterInstanceNoLock enter(instance);
658   if (enter.succeeded())
659     *result = enter.functions()->GetAudioHardwareOutputSampleRate(instance);
660 }
661 
OnHostMsgGetAudioHardwareOutputBufferSize(PP_Instance instance,uint32_t * result)662 void PPB_Instance_Proxy::OnHostMsgGetAudioHardwareOutputBufferSize(
663     PP_Instance instance, uint32_t* result) {
664   EnterInstanceNoLock enter(instance);
665   if (enter.succeeded())
666     *result = enter.functions()->GetAudioHardwareOutputBufferSize(instance);
667 }
668 
OnHostMsgIsFullFrame(PP_Instance instance,PP_Bool * result)669 void PPB_Instance_Proxy::OnHostMsgIsFullFrame(PP_Instance instance,
670                                               PP_Bool* result) {
671   EnterInstanceNoLock enter(instance);
672   if (enter.succeeded())
673     *result = enter.functions()->IsFullFrame(instance);
674 }
675 
OnHostMsgExecuteScript(PP_Instance instance,SerializedVarReceiveInput script,SerializedVarOutParam out_exception,SerializedVarReturnValue result)676 void PPB_Instance_Proxy::OnHostMsgExecuteScript(
677     PP_Instance instance,
678     SerializedVarReceiveInput script,
679     SerializedVarOutParam out_exception,
680     SerializedVarReturnValue result) {
681   if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE))
682     return;
683   EnterInstanceNoLock enter(instance);
684   if (enter.failed())
685     return;
686 
687   if (dispatcher()->IsPlugin())
688     NOTREACHED();
689   else
690     static_cast<HostDispatcher*>(dispatcher())->set_allow_plugin_reentrancy();
691 
692   result.Return(dispatcher(), enter.functions()->ExecuteScript(
693       instance,
694       script.Get(dispatcher()),
695       out_exception.OutParam(dispatcher())));
696 }
697 
OnHostMsgGetDefaultCharSet(PP_Instance instance,SerializedVarReturnValue result)698 void PPB_Instance_Proxy::OnHostMsgGetDefaultCharSet(
699     PP_Instance instance,
700     SerializedVarReturnValue result) {
701   if (!dispatcher()->permissions().HasPermission(PERMISSION_DEV))
702     return;
703   EnterInstanceNoLock enter(instance);
704   if (enter.succeeded())
705     result.Return(dispatcher(), enter.functions()->GetDefaultCharSet(instance));
706 }
707 
OnHostMsgSetPluginToHandleFindRequests(PP_Instance instance)708 void PPB_Instance_Proxy::OnHostMsgSetPluginToHandleFindRequests(
709     PP_Instance instance) {
710   if (!dispatcher()->permissions().HasPermission(PERMISSION_PDF))
711     return;
712   EnterInstanceNoLock enter(instance);
713   if (enter.succeeded())
714     enter.functions()->SetPluginToHandleFindRequests(instance);
715 }
716 
OnHostMsgNumberOfFindResultsChanged(PP_Instance instance,int32_t total,PP_Bool final_result)717 void PPB_Instance_Proxy::OnHostMsgNumberOfFindResultsChanged(
718     PP_Instance instance,
719     int32_t total,
720     PP_Bool final_result) {
721   if (!dispatcher()->permissions().HasPermission(PERMISSION_PDF))
722     return;
723   EnterInstanceNoLock enter(instance);
724   if (enter.succeeded()) {
725     enter.functions()->NumberOfFindResultsChanged(
726         instance, total, final_result);
727   }
728 }
729 
OnHostMsgSelectFindResultChanged(PP_Instance instance,int32_t index)730 void PPB_Instance_Proxy::OnHostMsgSelectFindResultChanged(
731     PP_Instance instance,
732     int32_t index) {
733   if (!dispatcher()->permissions().HasPermission(PERMISSION_PDF))
734     return;
735   EnterInstanceNoLock enter(instance);
736   if (enter.succeeded())
737     enter.functions()->SelectedFindResultChanged(instance, index);
738 }
739 
OnHostMsgSetTickmarks(PP_Instance instance,const std::vector<PP_Rect> & tickmarks)740 void PPB_Instance_Proxy::OnHostMsgSetTickmarks(
741     PP_Instance instance,
742     const std::vector<PP_Rect>& tickmarks) {
743   if (!dispatcher()->permissions().HasPermission(PERMISSION_PDF))
744     return;
745   const PP_Rect* array = tickmarks.empty() ? NULL : &tickmarks[0];
746   EnterInstanceNoLock enter(instance);
747   if (enter.succeeded()) {
748     enter.functions()->SetTickmarks(instance,
749                                     array,
750                                     static_cast<uint32_t>(tickmarks.size()));
751   }
752 }
753 
OnHostMsgSetFullscreen(PP_Instance instance,PP_Bool fullscreen,PP_Bool * result)754 void PPB_Instance_Proxy::OnHostMsgSetFullscreen(PP_Instance instance,
755                                                 PP_Bool fullscreen,
756                                                 PP_Bool* result) {
757   EnterInstanceNoLock enter(instance);
758   if (enter.succeeded())
759     *result = enter.functions()->SetFullscreen(instance, fullscreen);
760 }
761 
762 
OnHostMsgGetScreenSize(PP_Instance instance,PP_Bool * result,PP_Size * size)763 void PPB_Instance_Proxy::OnHostMsgGetScreenSize(PP_Instance instance,
764                                                 PP_Bool* result,
765                                                 PP_Size* size) {
766   EnterInstanceNoLock enter(instance);
767   if (enter.succeeded())
768     *result = enter.functions()->GetScreenSize(instance, size);
769 }
770 
OnHostMsgRequestInputEvents(PP_Instance instance,bool is_filtering,uint32_t event_classes)771 void PPB_Instance_Proxy::OnHostMsgRequestInputEvents(PP_Instance instance,
772                                                      bool is_filtering,
773                                                      uint32_t event_classes) {
774   EnterInstanceNoLock enter(instance);
775   if (enter.succeeded()) {
776     if (is_filtering)
777       enter.functions()->RequestFilteringInputEvents(instance, event_classes);
778     else
779       enter.functions()->RequestInputEvents(instance, event_classes);
780   }
781 }
782 
OnHostMsgClearInputEvents(PP_Instance instance,uint32_t event_classes)783 void PPB_Instance_Proxy::OnHostMsgClearInputEvents(PP_Instance instance,
784                                                    uint32_t event_classes) {
785   EnterInstanceNoLock enter(instance);
786   if (enter.succeeded())
787     enter.functions()->ClearInputEventRequest(instance, event_classes);
788 }
789 
OnHostMsgPostMessage(PP_Instance instance,SerializedVarReceiveInput message)790 void PPB_Instance_Proxy::OnHostMsgPostMessage(
791     PP_Instance instance,
792     SerializedVarReceiveInput message) {
793   EnterInstanceNoLock enter(instance);
794   if (!message.is_valid_var()) {
795     PpapiGlobals::Get()->LogWithSource(
796         instance, PP_LOGLEVEL_ERROR, std::string(), kSerializationError);
797     return;
798   }
799 
800   if (enter.succeeded())
801     enter.functions()->PostMessage(instance,
802                                    message.GetForInstance(dispatcher(),
803                                                           instance));
804 }
805 
OnHostMsgLockMouse(PP_Instance instance)806 void PPB_Instance_Proxy::OnHostMsgLockMouse(PP_Instance instance) {
807   // Need to be careful to always issue the callback.
808   pp::CompletionCallback cb = callback_factory_.NewCallback(
809       &PPB_Instance_Proxy::MouseLockCompleteInHost, instance);
810 
811   EnterInstanceNoLock enter(instance, cb.pp_completion_callback());
812   if (enter.succeeded())
813     enter.SetResult(enter.functions()->LockMouse(instance, enter.callback()));
814 }
815 
OnHostMsgUnlockMouse(PP_Instance instance)816 void PPB_Instance_Proxy::OnHostMsgUnlockMouse(PP_Instance instance) {
817   EnterInstanceNoLock enter(instance);
818   if (enter.succeeded())
819     enter.functions()->UnlockMouse(instance);
820 }
821 
OnHostMsgGetDocumentURL(PP_Instance instance,PP_URLComponents_Dev * components,SerializedVarReturnValue result)822 void PPB_Instance_Proxy::OnHostMsgGetDocumentURL(
823     PP_Instance instance,
824     PP_URLComponents_Dev* components,
825     SerializedVarReturnValue result) {
826   if (!dispatcher()->permissions().HasPermission(PERMISSION_DEV))
827     return;
828   EnterInstanceNoLock enter(instance);
829   if (enter.succeeded()) {
830     PP_Var document_url = enter.functions()->GetDocumentURL(instance,
831                                                             components);
832     result.Return(dispatcher(), document_url);
833   }
834 }
835 
OnHostMsgResolveRelativeToDocument(PP_Instance instance,SerializedVarReceiveInput relative,SerializedVarReturnValue result)836 void PPB_Instance_Proxy::OnHostMsgResolveRelativeToDocument(
837     PP_Instance instance,
838     SerializedVarReceiveInput relative,
839     SerializedVarReturnValue result) {
840   if (!dispatcher()->permissions().HasPermission(PERMISSION_DEV))
841     return;
842   EnterInstanceNoLock enter(instance);
843   if (enter.succeeded()) {
844     result.Return(dispatcher(),
845                   enter.functions()->ResolveRelativeToDocument(
846                       instance, relative.Get(dispatcher()), NULL));
847   }
848 }
849 
OnHostMsgDocumentCanRequest(PP_Instance instance,SerializedVarReceiveInput url,PP_Bool * result)850 void PPB_Instance_Proxy::OnHostMsgDocumentCanRequest(
851     PP_Instance instance,
852     SerializedVarReceiveInput url,
853     PP_Bool* result) {
854   if (!dispatcher()->permissions().HasPermission(PERMISSION_DEV))
855     return;
856   EnterInstanceNoLock enter(instance);
857   if (enter.succeeded()) {
858     *result = enter.functions()->DocumentCanRequest(instance,
859                                                     url.Get(dispatcher()));
860   }
861 }
862 
OnHostMsgDocumentCanAccessDocument(PP_Instance active,PP_Instance target,PP_Bool * result)863 void PPB_Instance_Proxy::OnHostMsgDocumentCanAccessDocument(PP_Instance active,
864                                                             PP_Instance target,
865                                                             PP_Bool* result) {
866   if (!dispatcher()->permissions().HasPermission(PERMISSION_DEV))
867     return;
868   EnterInstanceNoLock enter(active);
869   if (enter.succeeded())
870     *result = enter.functions()->DocumentCanAccessDocument(active, target);
871 }
872 
OnHostMsgGetPluginInstanceURL(PP_Instance instance,SerializedVarReturnValue result)873 void PPB_Instance_Proxy::OnHostMsgGetPluginInstanceURL(
874     PP_Instance instance,
875     SerializedVarReturnValue result) {
876   if (!dispatcher()->permissions().HasPermission(PERMISSION_DEV))
877     return;
878   EnterInstanceNoLock enter(instance);
879   if (enter.succeeded()) {
880     result.Return(dispatcher(),
881                   enter.functions()->GetPluginInstanceURL(instance, NULL));
882   }
883 }
884 
OnHostMsgGetPluginReferrerURL(PP_Instance instance,SerializedVarReturnValue result)885 void PPB_Instance_Proxy::OnHostMsgGetPluginReferrerURL(
886     PP_Instance instance,
887     SerializedVarReturnValue result) {
888   if (!dispatcher()->permissions().HasPermission(PERMISSION_DEV))
889     return;
890   EnterInstanceNoLock enter(instance);
891   if (enter.succeeded()) {
892     result.Return(dispatcher(),
893                   enter.functions()->GetPluginReferrerURL(instance, NULL));
894   }
895 }
896 
OnHostMsgSetCursor(PP_Instance instance,int32_t type,const ppapi::HostResource & custom_image,const PP_Point & hot_spot)897 void PPB_Instance_Proxy::OnHostMsgSetCursor(
898     PP_Instance instance,
899     int32_t type,
900     const ppapi::HostResource& custom_image,
901     const PP_Point& hot_spot) {
902   // This API serves PPB_CursorControl_Dev and PPB_MouseCursor, so is public.
903   EnterInstanceNoLock enter(instance);
904   if (enter.succeeded()) {
905     enter.functions()->SetCursor(
906         instance, static_cast<PP_MouseCursor_Type>(type),
907         custom_image.host_resource(), &hot_spot);
908   }
909 }
910 
OnHostMsgSetTextInputType(PP_Instance instance,PP_TextInput_Type type)911 void PPB_Instance_Proxy::OnHostMsgSetTextInputType(PP_Instance instance,
912                                                    PP_TextInput_Type type) {
913   EnterInstanceNoLock enter(instance);
914   if (enter.succeeded())
915     enter.functions()->SetTextInputType(instance, type);
916 }
917 
OnHostMsgUpdateCaretPosition(PP_Instance instance,const PP_Rect & caret,const PP_Rect & bounding_box)918 void PPB_Instance_Proxy::OnHostMsgUpdateCaretPosition(
919     PP_Instance instance,
920     const PP_Rect& caret,
921     const PP_Rect& bounding_box) {
922   EnterInstanceNoLock enter(instance);
923   if (enter.succeeded())
924     enter.functions()->UpdateCaretPosition(instance, caret, bounding_box);
925 }
926 
OnHostMsgCancelCompositionText(PP_Instance instance)927 void PPB_Instance_Proxy::OnHostMsgCancelCompositionText(PP_Instance instance) {
928   EnterInstanceNoLock enter(instance);
929   if (enter.succeeded())
930     enter.functions()->CancelCompositionText(instance);
931 }
932 
OnHostMsgUpdateSurroundingText(PP_Instance instance,const std::string & text,uint32_t caret,uint32_t anchor)933 void PPB_Instance_Proxy::OnHostMsgUpdateSurroundingText(
934     PP_Instance instance,
935     const std::string& text,
936     uint32_t caret,
937     uint32_t anchor) {
938   EnterInstanceNoLock enter(instance);
939   if (enter.succeeded()) {
940     enter.functions()->UpdateSurroundingText(instance, text.c_str(), caret,
941                                              anchor);
942   }
943 }
944 #endif  // !defined(OS_NACL)
945 
OnPluginMsgMouseLockComplete(PP_Instance instance,int32_t result)946 void PPB_Instance_Proxy::OnPluginMsgMouseLockComplete(PP_Instance instance,
947                                                       int32_t result) {
948   if (!dispatcher()->IsPlugin())
949     return;
950 
951   // Save the mouse callback on the instance data.
952   InstanceData* data = static_cast<PluginDispatcher*>(dispatcher())->
953       GetInstanceData(instance);
954   if (!data)
955     return;  // Instance was probably deleted.
956   if (!TrackedCallback::IsPending(data->mouse_lock_callback)) {
957     NOTREACHED();
958     return;
959   }
960   data->mouse_lock_callback->Run(result);
961 }
962 
963 #if !defined(OS_NACL)
MouseLockCompleteInHost(int32_t result,PP_Instance instance)964 void PPB_Instance_Proxy::MouseLockCompleteInHost(int32_t result,
965                                                  PP_Instance instance) {
966   dispatcher()->Send(new PpapiMsg_PPBInstance_MouseLockComplete(
967       API_ID_PPB_INSTANCE, instance, result));
968 }
969 #endif  // !defined(OS_NACL)
970 
CancelAnyPendingRequestSurroundingText(PP_Instance instance)971 void PPB_Instance_Proxy::CancelAnyPendingRequestSurroundingText(
972     PP_Instance instance) {
973   InstanceData* data = static_cast<PluginDispatcher*>(dispatcher())->
974       GetInstanceData(instance);
975   if (!data)
976     return;  // Instance was probably deleted.
977   data->should_do_request_surrounding_text = false;
978 }
979 
980 }  // namespace proxy
981 }  // namespace ppapi
982