Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / content / renderer / browser_plugin / browser_plugin.cc
1 // Copyright 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 "content/renderer/browser_plugin/browser_plugin.h"
6
7 #include "base/command_line.h"
8 #include "base/message_loop/message_loop.h"
9 #include "base/strings/string_number_conversions.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "content/common/browser_plugin/browser_plugin_constants.h"
12 #include "content/common/browser_plugin/browser_plugin_messages.h"
13 #include "content/common/view_messages.h"
14 #include "content/public/common/content_client.h"
15 #include "content/public/common/content_switches.h"
16 #include "content/public/renderer/browser_plugin_delegate.h"
17 #include "content/public/renderer/content_renderer_client.h"
18 #include "content/renderer/browser_plugin/browser_plugin_manager.h"
19 #include "content/renderer/child_frame_compositing_helper.h"
20 #include "content/renderer/cursor_utils.h"
21 #include "content/renderer/drop_data_builder.h"
22 #include "content/renderer/render_thread_impl.h"
23 #include "content/renderer/sad_plugin.h"
24 #include "third_party/WebKit/public/platform/WebRect.h"
25 #include "third_party/WebKit/public/web/WebElement.h"
26 #include "third_party/WebKit/public/web/WebInputEvent.h"
27 #include "third_party/WebKit/public/web/WebPluginContainer.h"
28 #include "third_party/WebKit/public/web/WebView.h"
29 #include "third_party/skia/include/core/SkCanvas.h"
30 #include "ui/events/keycodes/keyboard_codes.h"
31
32 using blink::WebCanvas;
33 using blink::WebPluginContainer;
34 using blink::WebPoint;
35 using blink::WebRect;
36 using blink::WebURL;
37 using blink::WebVector;
38
39 namespace {
40 typedef std::map<blink::WebPluginContainer*, content::BrowserPlugin*>
41     PluginContainerMap;
42 static base::LazyInstance<PluginContainerMap> g_plugin_container_map =
43     LAZY_INSTANCE_INITIALIZER;
44 }  // namespace
45
46 namespace content {
47
48 // static
49 BrowserPlugin* BrowserPlugin::GetFromNode(blink::WebNode& node) {
50   blink::WebPluginContainer* container = node.pluginContainer();
51   if (!container)
52     return NULL;
53
54   PluginContainerMap* browser_plugins = g_plugin_container_map.Pointer();
55   PluginContainerMap::iterator it = browser_plugins->find(container);
56   return it == browser_plugins->end() ? NULL : it->second;
57 }
58
59 BrowserPlugin::BrowserPlugin(RenderViewImpl* render_view,
60                              blink::WebFrame* frame,
61                              scoped_ptr<BrowserPluginDelegate> delegate)
62     : attached_(false),
63       attach_pending_(false),
64       render_view_(render_view->AsWeakPtr()),
65       render_view_routing_id_(render_view->GetRoutingID()),
66       container_(NULL),
67       last_device_scale_factor_(GetDeviceScaleFactor()),
68       sad_guest_(NULL),
69       guest_crashed_(false),
70       plugin_focused_(false),
71       visible_(true),
72       mouse_locked_(false),
73       browser_plugin_manager_(render_view->GetBrowserPluginManager()),
74       browser_plugin_instance_id_(browser_plugin::kInstanceIDNone),
75       contents_opaque_(true),
76       delegate_(delegate.Pass()),
77       weak_ptr_factory_(this) {
78   browser_plugin_instance_id_ = browser_plugin_manager()->GetNextInstanceID();
79
80   if (delegate_)
81     delegate_->SetElementInstanceID(browser_plugin_instance_id_);
82 }
83
84 BrowserPlugin::~BrowserPlugin() {
85   browser_plugin_manager()->RemoveBrowserPlugin(browser_plugin_instance_id_);
86
87   if (!ready())
88     return;
89
90   browser_plugin_manager()->Send(
91       new BrowserPluginHostMsg_PluginDestroyed(render_view_routing_id_,
92                                                browser_plugin_instance_id_));
93 }
94
95 bool BrowserPlugin::OnMessageReceived(const IPC::Message& message) {
96   bool handled = true;
97   IPC_BEGIN_MESSAGE_MAP(BrowserPlugin, message)
98     IPC_MESSAGE_HANDLER(BrowserPluginMsg_Attach_ACK, OnAttachACK)
99     IPC_MESSAGE_HANDLER(BrowserPluginMsg_AdvanceFocus, OnAdvanceFocus)
100     IPC_MESSAGE_HANDLER_GENERIC(BrowserPluginMsg_CompositorFrameSwapped,
101                                 OnCompositorFrameSwapped(message))
102     IPC_MESSAGE_HANDLER(BrowserPluginMsg_CopyFromCompositingSurface,
103                         OnCopyFromCompositingSurface)
104     IPC_MESSAGE_HANDLER(BrowserPluginMsg_GuestGone, OnGuestGone)
105     IPC_MESSAGE_HANDLER(BrowserPluginMsg_SetContentsOpaque, OnSetContentsOpaque)
106     IPC_MESSAGE_HANDLER(BrowserPluginMsg_SetCursor, OnSetCursor)
107     IPC_MESSAGE_HANDLER(BrowserPluginMsg_SetMouseLock, OnSetMouseLock)
108     IPC_MESSAGE_HANDLER(BrowserPluginMsg_ShouldAcceptTouchEvents,
109                         OnShouldAcceptTouchEvents)
110     IPC_MESSAGE_UNHANDLED(handled = false)
111   IPC_END_MESSAGE_MAP()
112   return handled;
113 }
114
115 void BrowserPlugin::UpdateDOMAttribute(const std::string& attribute_name,
116                                        const std::string& attribute_value) {
117   if (!container())
118     return;
119
120   blink::WebElement element = container()->element();
121   blink::WebString web_attribute_name =
122       blink::WebString::fromUTF8(attribute_name);
123   element.setAttribute(web_attribute_name,
124       blink::WebString::fromUTF8(attribute_value));
125 }
126
127 void BrowserPlugin::Attach() {
128   if (ready()) {
129     attached_ = false;
130     guest_crashed_ = false;
131     EnableCompositing(false);
132     if (compositing_helper_.get()) {
133       compositing_helper_->OnContainerDestroy();
134       compositing_helper_ = NULL;
135     }
136   }
137
138   // TODO(fsamuel): Add support for reattachment.
139   BrowserPluginHostMsg_Attach_Params attach_params;
140   attach_params.focused = ShouldGuestBeFocused();
141   attach_params.visible = visible_;
142   attach_params.origin = plugin_rect().origin();
143   gfx::Size view_size(width(), height());
144   if (!view_size.IsEmpty()) {
145     PopulateResizeGuestParameters(view_size,
146                                   &attach_params.resize_guest_params);
147   }
148   browser_plugin_manager()->Send(new BrowserPluginHostMsg_Attach(
149       render_view_routing_id_,
150       browser_plugin_instance_id_,
151       attach_params));
152
153   attach_pending_ = true;
154 }
155
156 void BrowserPlugin::DidCommitCompositorFrame() {
157   if (compositing_helper_.get())
158     compositing_helper_->DidCommitCompositorFrame();
159 }
160
161 void BrowserPlugin::OnAdvanceFocus(int browser_plugin_instance_id,
162                                    bool reverse) {
163   DCHECK(render_view_);
164   render_view_->GetWebView()->advanceFocus(reverse);
165 }
166
167 void BrowserPlugin::OnAttachACK(int browser_plugin_instance_id) {
168   DCHECK(!attached());
169   attached_ = true;
170   attach_pending_ = false;
171 }
172
173 void BrowserPlugin::OnCompositorFrameSwapped(const IPC::Message& message) {
174   BrowserPluginMsg_CompositorFrameSwapped::Param param;
175   if (!BrowserPluginMsg_CompositorFrameSwapped::Read(&message, &param))
176     return;
177
178   // Note that there is no need to send ACK for this message.
179   // If the guest has updated pixels then it is no longer crashed.
180   guest_crashed_ = false;
181
182   scoped_ptr<cc::CompositorFrame> frame(new cc::CompositorFrame);
183   param.b.frame.AssignTo(frame.get());
184
185   EnableCompositing(true);
186   compositing_helper_->OnCompositorFrameSwapped(frame.Pass(),
187                                                 param.b.producing_route_id,
188                                                 param.b.output_surface_id,
189                                                 param.b.producing_host_id,
190                                                 param.b.shared_memory_handle);
191 }
192
193 void BrowserPlugin::OnCopyFromCompositingSurface(int browser_plugin_instance_id,
194                                                  int request_id,
195                                                  gfx::Rect source_rect,
196                                                  gfx::Size dest_size) {
197   if (!compositing_helper_.get()) {
198     browser_plugin_manager()->Send(
199         new BrowserPluginHostMsg_CopyFromCompositingSurfaceAck(
200             render_view_routing_id_,
201             browser_plugin_instance_id_,
202             request_id,
203             SkBitmap()));
204     return;
205   }
206   compositing_helper_->CopyFromCompositingSurface(request_id, source_rect,
207                                                   dest_size);
208 }
209
210 void BrowserPlugin::OnGuestGone(int browser_plugin_instance_id) {
211   guest_crashed_ = true;
212
213   // Turn off compositing so we can display the sad graphic. Changes to
214   // compositing state will show up at a later time after a layout and commit.
215   EnableCompositing(false);
216
217   // Queue up showing the sad graphic to give content embedders an opportunity
218   // to fire their listeners and potentially overlay the webview with custom
219   // behavior. If the BrowserPlugin is destroyed in the meantime, then the
220   // task will not be executed.
221   base::MessageLoop::current()->PostTask(
222       FROM_HERE,
223       base::Bind(&BrowserPlugin::ShowSadGraphic,
224                  weak_ptr_factory_.GetWeakPtr()));
225 }
226
227 void BrowserPlugin::OnSetContentsOpaque(int browser_plugin_instance_id,
228                                         bool opaque) {
229   if (contents_opaque_ == opaque)
230     return;
231   contents_opaque_ = opaque;
232   if (compositing_helper_.get())
233     compositing_helper_->SetContentsOpaque(opaque);
234 }
235
236 void BrowserPlugin::OnSetCursor(int browser_plugin_instance_id,
237                                 const WebCursor& cursor) {
238   cursor_ = cursor;
239 }
240
241 void BrowserPlugin::OnSetMouseLock(int browser_plugin_instance_id,
242                                    bool enable) {
243   if (enable) {
244     if (mouse_locked_)
245       return;
246     render_view_->mouse_lock_dispatcher()->LockMouse(this);
247   } else {
248     if (!mouse_locked_) {
249       OnLockMouseACK(false);
250       return;
251     }
252     render_view_->mouse_lock_dispatcher()->UnlockMouse(this);
253   }
254 }
255
256 void BrowserPlugin::OnShouldAcceptTouchEvents(int browser_plugin_instance_id,
257                                               bool accept) {
258   if (container()) {
259     container()->requestTouchEventType(
260         accept ? WebPluginContainer::TouchEventRequestTypeRaw
261                : WebPluginContainer::TouchEventRequestTypeNone);
262   }
263 }
264
265 void BrowserPlugin::ShowSadGraphic() {
266   // If the BrowserPlugin is scheduled to be deleted, then container_ will be
267   // NULL so we shouldn't attempt to access it.
268   if (container_)
269     container_->invalidate();
270 }
271
272 float BrowserPlugin::GetDeviceScaleFactor() const {
273   if (!render_view_)
274     return 1.0f;
275   return render_view_->GetWebView()->deviceScaleFactor();
276 }
277
278 void BrowserPlugin::UpdateDeviceScaleFactor() {
279   if (last_device_scale_factor_ == GetDeviceScaleFactor())
280     return;
281
282   BrowserPluginHostMsg_ResizeGuest_Params params;
283   PopulateResizeGuestParameters(plugin_size(), &params);
284   browser_plugin_manager()->Send(new BrowserPluginHostMsg_ResizeGuest(
285       render_view_routing_id_,
286       browser_plugin_instance_id_,
287       params));
288 }
289
290 void BrowserPlugin::UpdateGuestFocusState() {
291   if (!ready())
292     return;
293   bool should_be_focused = ShouldGuestBeFocused();
294   browser_plugin_manager()->Send(new BrowserPluginHostMsg_SetFocus(
295       render_view_routing_id_,
296       browser_plugin_instance_id_,
297       should_be_focused));
298 }
299
300 bool BrowserPlugin::ShouldGuestBeFocused() const {
301   bool embedder_focused = false;
302   if (render_view_)
303     embedder_focused = render_view_->has_focus();
304   return plugin_focused_ && embedder_focused;
305 }
306
307 WebPluginContainer* BrowserPlugin::container() const {
308   return container_;
309 }
310
311 bool BrowserPlugin::initialize(WebPluginContainer* container) {
312   if (!container)
313     return false;
314
315   container_ = container;
316   container_->setWantsWheelEvents(true);
317
318   g_plugin_container_map.Get().insert(std::make_pair(container_, this));
319
320   // This is a way to notify observers of our attributes that this plugin is
321   // available in render tree.
322   // TODO(lazyboy): This should be done through the delegate instead. Perhaps
323   // by firing an event from there.
324   UpdateDOMAttribute("internalinstanceid",
325                      base::IntToString(browser_plugin_instance_id_));
326
327   browser_plugin_manager()->AddBrowserPlugin(browser_plugin_instance_id_, this);
328   return true;
329 }
330
331 void BrowserPlugin::EnableCompositing(bool enable) {
332   bool enabled = !!compositing_helper_.get();
333   if (enabled == enable)
334     return;
335
336   if (enable) {
337     DCHECK(!compositing_helper_.get());
338     if (!compositing_helper_.get()) {
339       compositing_helper_ = ChildFrameCompositingHelper::CreateForBrowserPlugin(
340           weak_ptr_factory_.GetWeakPtr());
341     }
342   }
343   compositing_helper_->EnableCompositing(enable);
344   compositing_helper_->SetContentsOpaque(contents_opaque_);
345
346   if (!enable) {
347     DCHECK(compositing_helper_.get());
348     compositing_helper_->OnContainerDestroy();
349     compositing_helper_ = NULL;
350   }
351 }
352
353 void BrowserPlugin::destroy() {
354   if (container_) {
355     //container_->clearScriptObjects();
356
357     // The BrowserPlugin's WebPluginContainer is deleted immediately after this
358     // call returns, so let's not keep a reference to it around.
359     g_plugin_container_map.Get().erase(container_);
360   }
361
362   if (compositing_helper_.get())
363     compositing_helper_->OnContainerDestroy();
364   container_ = NULL;
365   // Will be a no-op if the mouse is not currently locked.
366   if (render_view_)
367     render_view_->mouse_lock_dispatcher()->OnLockTargetDestroyed(this);
368   base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
369 }
370
371 bool BrowserPlugin::supportsKeyboardFocus() const {
372   return true;
373 }
374
375 bool BrowserPlugin::supportsEditCommands() const {
376   return true;
377 }
378
379 bool BrowserPlugin::supportsInputMethod() const {
380   return true;
381 }
382
383 bool BrowserPlugin::canProcessDrag() const {
384   return true;
385 }
386
387 void BrowserPlugin::paint(WebCanvas* canvas, const WebRect& rect) {
388   if (guest_crashed_) {
389     if (!sad_guest_)  // Lazily initialize bitmap.
390       sad_guest_ = content::GetContentClient()->renderer()->
391           GetSadWebViewBitmap();
392     // content_shell does not have the sad plugin bitmap, so we'll paint black
393     // instead to make it clear that something went wrong.
394     if (sad_guest_) {
395       PaintSadPlugin(canvas, plugin_rect_, *sad_guest_);
396       return;
397     }
398   }
399   SkAutoCanvasRestore auto_restore(canvas, true);
400   canvas->translate(plugin_rect_.x(), plugin_rect_.y());
401   SkRect image_data_rect = SkRect::MakeXYWH(
402       SkIntToScalar(0),
403       SkIntToScalar(0),
404       SkIntToScalar(plugin_rect_.width()),
405       SkIntToScalar(plugin_rect_.height()));
406   canvas->clipRect(image_data_rect);
407   // Paint black or white in case we have nothing in our backing store or we
408   // need to show a gutter.
409   SkPaint paint;
410   paint.setStyle(SkPaint::kFill_Style);
411   paint.setColor(guest_crashed_ ? SK_ColorBLACK : SK_ColorWHITE);
412   canvas->drawRect(image_data_rect, paint);
413 }
414
415 // static
416 bool BrowserPlugin::ShouldForwardToBrowserPlugin(
417     const IPC::Message& message) {
418   switch (message.type()) {
419     case BrowserPluginMsg_Attach_ACK::ID:
420     case BrowserPluginMsg_AdvanceFocus::ID:
421     case BrowserPluginMsg_CompositorFrameSwapped::ID:
422     case BrowserPluginMsg_CopyFromCompositingSurface::ID:
423     case BrowserPluginMsg_GuestGone::ID:
424     case BrowserPluginMsg_SetContentsOpaque::ID:
425     case BrowserPluginMsg_SetCursor::ID:
426     case BrowserPluginMsg_SetMouseLock::ID:
427     case BrowserPluginMsg_ShouldAcceptTouchEvents::ID:
428       return true;
429     default:
430       break;
431   }
432   return false;
433 }
434
435 void BrowserPlugin::updateGeometry(
436     const WebRect& window_rect,
437     const WebRect& clip_rect,
438     const WebVector<WebRect>& cut_outs_rects,
439     bool is_visible) {
440   int old_width = width();
441   int old_height = height();
442   plugin_rect_ = window_rect;
443   if (!attached())
444     return;
445
446   if (old_width == window_rect.width && old_height == window_rect.height) {
447     // Let the browser know about the updated view rect.
448     browser_plugin_manager()->Send(new BrowserPluginHostMsg_UpdateGeometry(
449         render_view_routing_id_, browser_plugin_instance_id_, plugin_rect_));
450     return;
451   }
452
453   BrowserPluginHostMsg_ResizeGuest_Params params;
454   PopulateResizeGuestParameters(plugin_size(), &params);
455   browser_plugin_manager()->Send(new BrowserPluginHostMsg_ResizeGuest(
456       render_view_routing_id_,
457       browser_plugin_instance_id_,
458       params));
459 }
460
461 void BrowserPlugin::PopulateResizeGuestParameters(
462     const gfx::Size& view_size,
463     BrowserPluginHostMsg_ResizeGuest_Params* params) {
464   params->view_size = view_size;
465   params->scale_factor = GetDeviceScaleFactor();
466   if (last_device_scale_factor_ != params->scale_factor) {
467     last_device_scale_factor_ = params->scale_factor;
468     params->repaint = true;
469   }
470 }
471
472 void BrowserPlugin::updateFocus(bool focused) {
473   plugin_focused_ = focused;
474   UpdateGuestFocusState();
475 }
476
477 void BrowserPlugin::updateVisibility(bool visible) {
478   if (visible_ == visible)
479     return;
480
481   visible_ = visible;
482   if (!ready())
483     return;
484
485   if (compositing_helper_.get())
486     compositing_helper_->UpdateVisibility(visible);
487
488   browser_plugin_manager()->Send(new BrowserPluginHostMsg_SetVisibility(
489       render_view_routing_id_,
490       browser_plugin_instance_id_,
491       visible));
492 }
493
494 bool BrowserPlugin::acceptsInputEvents() {
495   return true;
496 }
497
498 bool BrowserPlugin::handleInputEvent(const blink::WebInputEvent& event,
499                                      blink::WebCursorInfo& cursor_info) {
500   if (guest_crashed_ || !ready())
501     return false;
502
503   if (event.type == blink::WebInputEvent::ContextMenu)
504     return true;
505
506   if (blink::WebInputEvent::isKeyboardEventType(event.type) &&
507       !edit_commands_.empty()) {
508     browser_plugin_manager()->Send(
509         new BrowserPluginHostMsg_SetEditCommandsForNextKeyEvent(
510             render_view_routing_id_,
511             browser_plugin_instance_id_,
512             edit_commands_));
513     edit_commands_.clear();
514   }
515
516   browser_plugin_manager()->Send(
517       new BrowserPluginHostMsg_HandleInputEvent(render_view_routing_id_,
518                                                 browser_plugin_instance_id_,
519                                                 plugin_rect_,
520                                                 &event));
521   GetWebKitCursorInfo(cursor_, &cursor_info);
522   return true;
523 }
524
525 bool BrowserPlugin::handleDragStatusUpdate(blink::WebDragStatus drag_status,
526                                            const blink::WebDragData& drag_data,
527                                            blink::WebDragOperationsMask mask,
528                                            const blink::WebPoint& position,
529                                            const blink::WebPoint& screen) {
530   if (guest_crashed_ || !ready())
531     return false;
532   browser_plugin_manager()->Send(
533       new BrowserPluginHostMsg_DragStatusUpdate(
534         render_view_routing_id_,
535         browser_plugin_instance_id_,
536         drag_status,
537         DropDataBuilder::Build(drag_data),
538         mask,
539         position));
540   return true;
541 }
542
543 void BrowserPlugin::didReceiveResponse(
544     const blink::WebURLResponse& response) {
545 }
546
547 void BrowserPlugin::didReceiveData(const char* data, int data_length) {
548   if (delegate_)
549     delegate_->DidReceiveData(data, data_length);
550 }
551
552 void BrowserPlugin::didFinishLoading() {
553   if (delegate_)
554     delegate_->DidFinishLoading();
555 }
556
557 void BrowserPlugin::didFailLoading(const blink::WebURLError& error) {
558 }
559
560 void BrowserPlugin::didFinishLoadingFrameRequest(const blink::WebURL& url,
561                                                  void* notify_data) {
562 }
563
564 void BrowserPlugin::didFailLoadingFrameRequest(
565     const blink::WebURL& url,
566     void* notify_data,
567     const blink::WebURLError& error) {
568 }
569
570 bool BrowserPlugin::executeEditCommand(const blink::WebString& name) {
571   browser_plugin_manager()->Send(new BrowserPluginHostMsg_ExecuteEditCommand(
572       render_view_routing_id_,
573       browser_plugin_instance_id_,
574       name.utf8()));
575
576   // BrowserPlugin swallows edit commands.
577   return true;
578 }
579
580 bool BrowserPlugin::executeEditCommand(const blink::WebString& name,
581                                        const blink::WebString& value) {
582   edit_commands_.push_back(EditCommand(name.utf8(), value.utf8()));
583   // BrowserPlugin swallows edit commands.
584   return true;
585 }
586
587 bool BrowserPlugin::setComposition(
588     const blink::WebString& text,
589     const blink::WebVector<blink::WebCompositionUnderline>& underlines,
590     int selectionStart,
591     int selectionEnd) {
592   if (!ready())
593     return false;
594   std::vector<blink::WebCompositionUnderline> std_underlines;
595   for (size_t i = 0; i < underlines.size(); ++i) {
596     std_underlines.push_back(underlines[i]);
597   }
598   browser_plugin_manager()->Send(new BrowserPluginHostMsg_ImeSetComposition(
599       render_view_routing_id_,
600       browser_plugin_instance_id_,
601       text.utf8(),
602       std_underlines,
603       selectionStart,
604       selectionEnd));
605   // TODO(kochi): This assumes the IPC handling always succeeds.
606   return true;
607 }
608
609 bool BrowserPlugin::confirmComposition(
610     const blink::WebString& text,
611     blink::WebWidget::ConfirmCompositionBehavior selectionBehavior) {
612   if (!ready())
613     return false;
614   bool keep_selection = (selectionBehavior == blink::WebWidget::KeepSelection);
615   browser_plugin_manager()->Send(new BrowserPluginHostMsg_ImeConfirmComposition(
616       render_view_routing_id_,
617       browser_plugin_instance_id_,
618       text.utf8(),
619       keep_selection));
620   // TODO(kochi): This assumes the IPC handling always succeeds.
621   return true;
622 }
623
624 void BrowserPlugin::extendSelectionAndDelete(int before, int after) {
625   if (!ready())
626     return;
627   browser_plugin_manager()->Send(
628       new BrowserPluginHostMsg_ExtendSelectionAndDelete(
629           render_view_routing_id_,
630           browser_plugin_instance_id_,
631           before,
632           after));
633 }
634
635 void BrowserPlugin::OnLockMouseACK(bool succeeded) {
636   mouse_locked_ = succeeded;
637   browser_plugin_manager()->Send(new BrowserPluginHostMsg_LockMouse_ACK(
638       render_view_routing_id_,
639       browser_plugin_instance_id_,
640       succeeded));
641 }
642
643 void BrowserPlugin::OnMouseLockLost() {
644   mouse_locked_ = false;
645   browser_plugin_manager()->Send(new BrowserPluginHostMsg_UnlockMouse_ACK(
646       render_view_routing_id_,
647       browser_plugin_instance_id_));
648 }
649
650 bool BrowserPlugin::HandleMouseLockedInputEvent(
651     const blink::WebMouseEvent& event) {
652   browser_plugin_manager()->Send(
653       new BrowserPluginHostMsg_HandleInputEvent(render_view_routing_id_,
654                                                 browser_plugin_instance_id_,
655                                                 plugin_rect_,
656                                                 &event));
657   return true;
658 }
659
660 }  // namespace content