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.
5 #include "content/renderer/browser_plugin/browser_plugin.h"
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/content_renderer_client.h"
17 #include "content/renderer/browser_plugin/browser_plugin_bindings.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/WebBindings.h"
26 #include "third_party/WebKit/public/web/WebDocument.h"
27 #include "third_party/WebKit/public/web/WebElement.h"
28 #include "third_party/WebKit/public/web/WebInputEvent.h"
29 #include "third_party/WebKit/public/web/WebPluginContainer.h"
30 #include "third_party/WebKit/public/web/WebPluginParams.h"
31 #include "third_party/WebKit/public/web/WebView.h"
32 #include "third_party/skia/include/core/SkCanvas.h"
33 #include "ui/events/keycodes/keyboard_codes.h"
35 using blink::WebCanvas
;
36 using blink::WebPluginContainer
;
37 using blink::WebPluginParams
;
38 using blink::WebPoint
;
41 using blink::WebVector
;
45 BrowserPlugin::BrowserPlugin(RenderViewImpl
* render_view
,
46 blink::WebFrame
* frame
,
49 attach_pending_(false),
50 render_view_(render_view
->AsWeakPtr()),
51 render_view_routing_id_(render_view
->GetRoutingID()),
53 paint_ack_received_(true),
54 last_device_scale_factor_(GetDeviceScaleFactor()),
56 guest_crashed_(false),
57 content_window_routing_id_(MSG_ROUTING_NONE
),
58 plugin_focused_(false),
60 auto_navigate_(auto_navigate
),
62 browser_plugin_manager_(render_view
->GetBrowserPluginManager()),
63 browser_plugin_instance_id_(browser_plugin::kInstanceIDNone
),
64 weak_ptr_factory_(this) {
67 BrowserPlugin::~BrowserPlugin() {
68 browser_plugin_manager()->RemoveBrowserPlugin(browser_plugin_instance_id_
);
73 browser_plugin_manager()->Send(
74 new BrowserPluginHostMsg_PluginDestroyed(render_view_routing_id_
,
75 browser_plugin_instance_id_
));
78 bool BrowserPlugin::OnMessageReceived(const IPC::Message
& message
) {
80 IPC_BEGIN_MESSAGE_MAP(BrowserPlugin
, message
)
81 IPC_MESSAGE_HANDLER(BrowserPluginMsg_Attach_ACK
, OnAttachACK
)
82 IPC_MESSAGE_HANDLER(BrowserPluginMsg_AdvanceFocus
, OnAdvanceFocus
)
83 IPC_MESSAGE_HANDLER(BrowserPluginMsg_BuffersSwapped
, OnBuffersSwapped
)
84 IPC_MESSAGE_HANDLER_GENERIC(BrowserPluginMsg_CompositorFrameSwapped
,
85 OnCompositorFrameSwapped(message
))
86 IPC_MESSAGE_HANDLER(BrowserPluginMsg_CopyFromCompositingSurface
,
87 OnCopyFromCompositingSurface
)
88 IPC_MESSAGE_HANDLER(BrowserPluginMsg_GuestContentWindowReady
,
89 OnGuestContentWindowReady
)
90 IPC_MESSAGE_HANDLER(BrowserPluginMsg_GuestGone
, OnGuestGone
)
91 IPC_MESSAGE_HANDLER(BrowserPluginMsg_SetCursor
, OnSetCursor
)
92 IPC_MESSAGE_HANDLER(BrowserPluginMsg_SetMouseLock
, OnSetMouseLock
)
93 IPC_MESSAGE_HANDLER(BrowserPluginMsg_ShouldAcceptTouchEvents
,
94 OnShouldAcceptTouchEvents
)
95 IPC_MESSAGE_HANDLER(BrowserPluginMsg_UpdateRect
, OnUpdateRect
)
96 IPC_MESSAGE_UNHANDLED(handled
= false)
101 void BrowserPlugin::UpdateDOMAttribute(const std::string
& attribute_name
,
102 const std::string
& attribute_value
) {
106 blink::WebElement element
= container()->element();
107 blink::WebString web_attribute_name
=
108 blink::WebString::fromUTF8(attribute_name
);
109 if (!HasDOMAttribute(attribute_name
) ||
110 (std::string(element
.getAttribute(web_attribute_name
).utf8()) !=
112 element
.setAttribute(web_attribute_name
,
113 blink::WebString::fromUTF8(attribute_value
));
117 void BrowserPlugin::RemoveDOMAttribute(const std::string
& attribute_name
) {
121 container()->element().removeAttribute(
122 blink::WebString::fromUTF8(attribute_name
));
125 std::string
BrowserPlugin::GetDOMAttributeValue(
126 const std::string
& attribute_name
) const {
128 return std::string();
130 return container()->element().getAttribute(
131 blink::WebString::fromUTF8(attribute_name
)).utf8();
134 bool BrowserPlugin::HasDOMAttribute(const std::string
& attribute_name
) const {
138 return container()->element().hasAttribute(
139 blink::WebString::fromUTF8(attribute_name
));
142 bool BrowserPlugin::GetAllowTransparencyAttribute() const {
143 return HasDOMAttribute(browser_plugin::kAttributeAllowTransparency
);
146 void BrowserPlugin::ParseAllowTransparencyAttribute() {
150 bool opaque
= !GetAllowTransparencyAttribute();
152 if (compositing_helper_
.get())
153 compositing_helper_
->SetContentsOpaque(opaque
);
155 browser_plugin_manager()->Send(new BrowserPluginHostMsg_SetContentsOpaque(
156 render_view_routing_id_
,
157 browser_plugin_instance_id_
,
161 void BrowserPlugin::Attach() {
164 guest_crashed_
= false;
165 EnableCompositing(false);
166 if (compositing_helper_
.get()) {
167 compositing_helper_
->OnContainerDestroy();
168 compositing_helper_
= NULL
;
172 // TODO(fsamuel): Add support for reattachment.
173 BrowserPluginHostMsg_Attach_Params attach_params
;
174 attach_params
.focused
= ShouldGuestBeFocused();
175 attach_params
.visible
= visible_
;
176 attach_params
.opaque
= !GetAllowTransparencyAttribute();
177 attach_params
.origin
= plugin_rect().origin();
178 GetSizeParams(&attach_params
.resize_guest_params
, false);
180 browser_plugin_manager()->Send(new BrowserPluginHostMsg_Attach(
181 render_view_routing_id_
,
182 browser_plugin_instance_id_
,
185 attach_pending_
= true;
188 void BrowserPlugin::DidCommitCompositorFrame() {
189 if (compositing_helper_
.get())
190 compositing_helper_
->DidCommitCompositorFrame();
193 void BrowserPlugin::OnAdvanceFocus(int browser_plugin_instance_id
,
195 DCHECK(render_view_
.get());
196 render_view_
->GetWebView()->advanceFocus(reverse
);
199 void BrowserPlugin::OnAttachACK(int browser_plugin_instance_id
) {
202 attach_pending_
= false;
205 void BrowserPlugin::OnBuffersSwapped(
207 const FrameMsg_BuffersSwapped_Params
& params
) {
208 EnableCompositing(true);
210 compositing_helper_
->OnBuffersSwapped(params
.size
,
214 GetDeviceScaleFactor());
217 void BrowserPlugin::OnCompositorFrameSwapped(const IPC::Message
& message
) {
218 BrowserPluginMsg_CompositorFrameSwapped::Param param
;
219 if (!BrowserPluginMsg_CompositorFrameSwapped::Read(&message
, ¶m
))
221 scoped_ptr
<cc::CompositorFrame
> frame(new cc::CompositorFrame
);
222 param
.b
.frame
.AssignTo(frame
.get());
224 EnableCompositing(true);
225 compositing_helper_
->OnCompositorFrameSwapped(frame
.Pass(),
226 param
.b
.producing_route_id
,
227 param
.b
.output_surface_id
,
228 param
.b
.producing_host_id
,
229 param
.b
.shared_memory_handle
);
232 void BrowserPlugin::OnCopyFromCompositingSurface(int browser_plugin_instance_id
,
234 gfx::Rect source_rect
,
235 gfx::Size dest_size
) {
236 if (!compositing_helper_
.get()) {
237 browser_plugin_manager()->Send(
238 new BrowserPluginHostMsg_CopyFromCompositingSurfaceAck(
239 render_view_routing_id_
,
240 browser_plugin_instance_id_
,
245 compositing_helper_
->CopyFromCompositingSurface(request_id
, source_rect
,
249 void BrowserPlugin::OnGuestContentWindowReady(int browser_plugin_instance_id
,
250 int content_window_routing_id
) {
251 DCHECK(content_window_routing_id
!= MSG_ROUTING_NONE
);
252 content_window_routing_id_
= content_window_routing_id
;
255 void BrowserPlugin::OnGuestGone(int browser_plugin_instance_id
) {
256 guest_crashed_
= true;
258 // Turn off compositing so we can display the sad graphic. Changes to
259 // compositing state will show up at a later time after a layout and commit.
260 EnableCompositing(false);
262 // Queue up showing the sad graphic to give content embedders an opportunity
263 // to fire their listeners and potentially overlay the webview with custom
264 // behavior. If the BrowserPlugin is destroyed in the meantime, then the
265 // task will not be executed.
266 base::MessageLoop::current()->PostTask(
268 base::Bind(&BrowserPlugin::ShowSadGraphic
,
269 weak_ptr_factory_
.GetWeakPtr()));
272 void BrowserPlugin::OnSetCursor(int browser_plugin_instance_id
,
273 const WebCursor
& cursor
) {
277 void BrowserPlugin::OnSetMouseLock(int browser_plugin_instance_id
,
282 render_view_
->mouse_lock_dispatcher()->LockMouse(this);
284 if (!mouse_locked_
) {
285 OnLockMouseACK(false);
288 render_view_
->mouse_lock_dispatcher()->UnlockMouse(this);
292 void BrowserPlugin::OnShouldAcceptTouchEvents(int browser_plugin_instance_id
,
295 container()->requestTouchEventType(
296 accept
? WebPluginContainer::TouchEventRequestTypeRaw
297 : WebPluginContainer::TouchEventRequestTypeNone
);
301 void BrowserPlugin::OnUpdateRect(
302 int browser_plugin_instance_id
,
303 const BrowserPluginMsg_UpdateRect_Params
& params
) {
304 // Note that there is no need to send ACK for this message.
305 // If the guest has updated pixels then it is no longer crashed.
306 guest_crashed_
= false;
308 // We receive a resize ACK in regular mode, but not in autosize.
309 // In Compositing mode, we need to do it here so we can continue sending
310 // resize messages when needed.
311 if (params
.is_resize_ack
)
312 paint_ack_received_
= true;
314 if (params
.view_size
.width() == width() &&
315 params
.view_size
.height() == height()) {
319 BrowserPluginHostMsg_ResizeGuest_Params resize_params
;
320 PopulateResizeGuestParameters(&resize_params
, plugin_size(), false);
321 paint_ack_received_
= false;
322 browser_plugin_manager()->Send(new BrowserPluginHostMsg_ResizeGuest(
323 render_view_routing_id_
,
324 browser_plugin_instance_id_
,
328 NPObject
* BrowserPlugin::GetContentWindow() const {
329 if (content_window_routing_id_
== MSG_ROUTING_NONE
)
331 RenderViewImpl
* guest_render_view
= RenderViewImpl::FromRoutingID(
332 content_window_routing_id_
);
333 if (!guest_render_view
)
335 blink::WebFrame
* guest_frame
= guest_render_view
->GetWebView()->mainFrame();
336 return guest_frame
->windowObject();
339 void BrowserPlugin::ShowSadGraphic() {
340 // If the BrowserPlugin is scheduled to be deleted, then container_ will be
341 // NULL so we shouldn't attempt to access it.
343 container_
->invalidate();
346 float BrowserPlugin::GetDeviceScaleFactor() const {
347 if (!render_view_
.get())
349 return render_view_
->GetWebView()->deviceScaleFactor();
352 void BrowserPlugin::UpdateDeviceScaleFactor(float device_scale_factor
) {
353 if (last_device_scale_factor_
== device_scale_factor
|| !paint_ack_received_
)
356 BrowserPluginHostMsg_ResizeGuest_Params params
;
357 PopulateResizeGuestParameters(¶ms
, plugin_size(), true);
358 browser_plugin_manager()->Send(new BrowserPluginHostMsg_ResizeGuest(
359 render_view_routing_id_
,
360 browser_plugin_instance_id_
,
364 void BrowserPlugin::UpdateGuestFocusState() {
367 bool should_be_focused
= ShouldGuestBeFocused();
368 browser_plugin_manager()->Send(new BrowserPluginHostMsg_SetFocus(
369 render_view_routing_id_
,
370 browser_plugin_instance_id_
,
374 bool BrowserPlugin::ShouldGuestBeFocused() const {
375 bool embedder_focused
= false;
376 if (render_view_
.get())
377 embedder_focused
= render_view_
->has_focus();
378 return plugin_focused_
&& embedder_focused
;
381 WebPluginContainer
* BrowserPlugin::container() const {
385 bool BrowserPlugin::initialize(WebPluginContainer
* container
) {
389 // Tell |container| to allow this plugin to use script objects.
390 npp_
.reset(new NPP_t
);
391 container
->allowScriptObjects();
393 bindings_
.reset(new BrowserPluginBindings(this));
394 container_
= container
;
395 container_
->setWantsWheelEvents(true);
397 // This is a way to notify observers of our attributes that this plugin is
398 // available in render tree.
399 browser_plugin_instance_id_
= browser_plugin_manager()->GetNextInstanceID();
400 UpdateDOMAttribute("internalinstanceid",
401 base::IntToString(browser_plugin_instance_id_
));
403 browser_plugin_manager()->AddBrowserPlugin(browser_plugin_instance_id_
, this);
407 void BrowserPlugin::EnableCompositing(bool enable
) {
408 bool enabled
= !!compositing_helper_
.get();
409 if (enabled
== enable
)
413 DCHECK(!compositing_helper_
.get());
414 if (!compositing_helper_
.get()) {
415 compositing_helper_
= ChildFrameCompositingHelper::CreateForBrowserPlugin(
416 weak_ptr_factory_
.GetWeakPtr());
419 compositing_helper_
->EnableCompositing(enable
);
420 compositing_helper_
->SetContentsOpaque(!GetAllowTransparencyAttribute());
423 DCHECK(compositing_helper_
.get());
424 compositing_helper_
->OnContainerDestroy();
425 compositing_helper_
= NULL
;
429 void BrowserPlugin::destroy() {
430 // If the plugin was initialized then it has a valid |npp_| identifier, and
431 // the |container_| must clear references to the plugin's script objects.
432 DCHECK(!npp_
|| container_
);
434 container_
->clearScriptObjects();
436 if (compositing_helper_
.get())
437 compositing_helper_
->OnContainerDestroy();
439 // Will be a no-op if the mouse is not currently locked.
440 if (render_view_
.get())
441 render_view_
->mouse_lock_dispatcher()->OnLockTargetDestroyed(this);
442 base::MessageLoop::current()->DeleteSoon(FROM_HERE
, this);
445 NPObject
* BrowserPlugin::scriptableObject() {
449 NPObject
* browser_plugin_np_object(bindings_
->np_object());
450 // The object is expected to be retained before it is returned.
451 blink::WebBindings::retainObject(browser_plugin_np_object
);
452 return browser_plugin_np_object
;
455 NPP
BrowserPlugin::pluginNPP() {
459 bool BrowserPlugin::supportsKeyboardFocus() const {
463 bool BrowserPlugin::supportsEditCommands() const {
467 bool BrowserPlugin::supportsInputMethod() const {
471 bool BrowserPlugin::canProcessDrag() const {
475 void BrowserPlugin::paint(WebCanvas
* canvas
, const WebRect
& rect
) {
476 if (guest_crashed_
) {
477 if (!sad_guest_
) // Lazily initialize bitmap.
478 sad_guest_
= content::GetContentClient()->renderer()->
479 GetSadWebViewBitmap();
480 // content_shell does not have the sad plugin bitmap, so we'll paint black
481 // instead to make it clear that something went wrong.
483 PaintSadPlugin(canvas
, plugin_rect_
, *sad_guest_
);
487 SkAutoCanvasRestore
auto_restore(canvas
, true);
488 canvas
->translate(plugin_rect_
.x(), plugin_rect_
.y());
489 SkRect image_data_rect
= SkRect::MakeXYWH(
492 SkIntToScalar(plugin_rect_
.width()),
493 SkIntToScalar(plugin_rect_
.height()));
494 canvas
->clipRect(image_data_rect
);
495 // Paint black or white in case we have nothing in our backing store or we
496 // need to show a gutter.
498 paint
.setStyle(SkPaint::kFill_Style
);
499 paint
.setColor(guest_crashed_
? SK_ColorBLACK
: SK_ColorWHITE
);
500 canvas
->drawRect(image_data_rect
, paint
);
504 bool BrowserPlugin::ShouldForwardToBrowserPlugin(
505 const IPC::Message
& message
) {
506 switch (message
.type()) {
507 case BrowserPluginMsg_Attach_ACK::ID
:
508 case BrowserPluginMsg_AdvanceFocus::ID
:
509 case BrowserPluginMsg_BuffersSwapped::ID
:
510 case BrowserPluginMsg_CompositorFrameSwapped::ID
:
511 case BrowserPluginMsg_CopyFromCompositingSurface::ID
:
512 case BrowserPluginMsg_GuestContentWindowReady::ID
:
513 case BrowserPluginMsg_GuestGone::ID
:
514 case BrowserPluginMsg_SetCursor::ID
:
515 case BrowserPluginMsg_SetMouseLock::ID
:
516 case BrowserPluginMsg_ShouldAcceptTouchEvents::ID
:
517 case BrowserPluginMsg_UpdateRect::ID
:
525 void BrowserPlugin::updateGeometry(
526 const WebRect
& window_rect
,
527 const WebRect
& clip_rect
,
528 const WebVector
<WebRect
>& cut_outs_rects
,
530 int old_width
= width();
531 int old_height
= height();
532 plugin_rect_
= window_rect
;
536 // In AutoSize mode, guests don't care when the BrowserPlugin container is
537 // resized. If |!paint_ack_received_|, then we are still waiting on a
538 // previous resize to be ACK'ed and so we don't issue additional resizes
539 // until the previous one is ACK'ed.
540 // TODO(mthiesse): Assess the performance of calling GetAutoSizeAttribute() on
542 if (!paint_ack_received_
||
543 (old_width
== window_rect
.width
&& old_height
== window_rect
.height
)) {
544 // Let the browser know about the updated view rect.
545 browser_plugin_manager()->Send(new BrowserPluginHostMsg_UpdateGeometry(
546 render_view_routing_id_
, browser_plugin_instance_id_
, plugin_rect_
));
550 BrowserPluginHostMsg_ResizeGuest_Params params
;
551 PopulateResizeGuestParameters(¶ms
, plugin_size(), false);
552 paint_ack_received_
= false;
553 browser_plugin_manager()->Send(new BrowserPluginHostMsg_ResizeGuest(
554 render_view_routing_id_
,
555 browser_plugin_instance_id_
,
559 void BrowserPlugin::PopulateResizeGuestParameters(
560 BrowserPluginHostMsg_ResizeGuest_Params
* params
,
561 const gfx::Size
& view_size
,
562 bool needs_repaint
) {
563 params
->size_changed
= true;
564 params
->view_size
= view_size
;
565 params
->repaint
= needs_repaint
;
566 params
->scale_factor
= GetDeviceScaleFactor();
567 if (last_device_scale_factor_
!= params
->scale_factor
) {
568 DCHECK(params
->repaint
);
569 last_device_scale_factor_
= params
->scale_factor
;
573 void BrowserPlugin::GetSizeParams(
574 BrowserPluginHostMsg_ResizeGuest_Params
* resize_guest_params
,
575 bool needs_repaint
) {
576 gfx::Size
view_size(width(), height());
577 if (view_size
.IsEmpty())
579 paint_ack_received_
= false;
580 PopulateResizeGuestParameters(resize_guest_params
, view_size
, needs_repaint
);
583 void BrowserPlugin::updateFocus(bool focused
) {
584 plugin_focused_
= focused
;
585 UpdateGuestFocusState();
588 void BrowserPlugin::updateVisibility(bool visible
) {
589 if (visible_
== visible
)
596 if (compositing_helper_
.get())
597 compositing_helper_
->UpdateVisibility(visible
);
599 browser_plugin_manager()->Send(new BrowserPluginHostMsg_SetVisibility(
600 render_view_routing_id_
,
601 browser_plugin_instance_id_
,
605 bool BrowserPlugin::acceptsInputEvents() {
609 bool BrowserPlugin::handleInputEvent(const blink::WebInputEvent
& event
,
610 blink::WebCursorInfo
& cursor_info
) {
611 if (guest_crashed_
|| !ready())
614 if (event
.type
== blink::WebInputEvent::ContextMenu
)
617 const blink::WebInputEvent
* modified_event
= &event
;
618 scoped_ptr
<blink::WebTouchEvent
> touch_event
;
619 if (blink::WebInputEvent::isTouchEventType(event
.type
)) {
620 const blink::WebTouchEvent
* orig_touch_event
=
621 static_cast<const blink::WebTouchEvent
*>(&event
);
623 touch_event
.reset(new blink::WebTouchEvent());
624 memcpy(touch_event
.get(), orig_touch_event
, sizeof(blink::WebTouchEvent
));
626 // TODO(bokan): Blink passes back a WebGestureEvent with a touches,
627 // changedTouches, and targetTouches lists; however, it doesn't set
628 // the state field on the touches which is what the RenderWidget uses
629 // to create a WebCore::TouchEvent. crbug.com/358132 tracks removing
630 // these multiple lists from WebTouchEvent since they lead to misuse
631 // like this and are functionally unused. In the mean time we'll setup
632 // the state field here manually to fix multi-touch BrowserPlugins.
633 for (size_t i
= 0; i
< touch_event
->touchesLength
; ++i
) {
634 blink::WebTouchPoint
& touch
= touch_event
->touches
[i
];
635 touch
.state
= blink::WebTouchPoint::StateStationary
;
636 for (size_t j
= 0; j
< touch_event
->changedTouchesLength
; ++j
) {
637 blink::WebTouchPoint
& changed_touch
= touch_event
->changedTouches
[j
];
638 if (touch
.id
== changed_touch
.id
) {
639 touch
.state
= changed_touch
.state
;
645 // For End and Cancel, Blink gives BrowserPlugin a list of touches that
646 // are down, but the browser process expects a list of all touches. We
647 // modify these events here to match these expectations.
648 if (event
.type
== blink::WebInputEvent::TouchEnd
||
649 event
.type
== blink::WebInputEvent::TouchCancel
) {
650 if (touch_event
->changedTouchesLength
> 0) {
651 memcpy(&touch_event
->touches
[touch_event
->touchesLength
],
652 &touch_event
->changedTouches
,
653 touch_event
->changedTouchesLength
* sizeof(blink::WebTouchPoint
));
654 touch_event
->touchesLength
+= touch_event
->changedTouchesLength
;
657 modified_event
= touch_event
.get();
660 if (blink::WebInputEvent::isKeyboardEventType(event
.type
) &&
661 !edit_commands_
.empty()) {
662 browser_plugin_manager()->Send(
663 new BrowserPluginHostMsg_SetEditCommandsForNextKeyEvent(
664 render_view_routing_id_
,
665 browser_plugin_instance_id_
,
667 edit_commands_
.clear();
670 browser_plugin_manager()->Send(
671 new BrowserPluginHostMsg_HandleInputEvent(render_view_routing_id_
,
672 browser_plugin_instance_id_
,
675 GetWebKitCursorInfo(cursor_
, &cursor_info
);
679 bool BrowserPlugin::handleDragStatusUpdate(blink::WebDragStatus drag_status
,
680 const blink::WebDragData
& drag_data
,
681 blink::WebDragOperationsMask mask
,
682 const blink::WebPoint
& position
,
683 const blink::WebPoint
& screen
) {
684 if (guest_crashed_
|| !ready())
686 browser_plugin_manager()->Send(
687 new BrowserPluginHostMsg_DragStatusUpdate(
688 render_view_routing_id_
,
689 browser_plugin_instance_id_
,
691 DropDataBuilder::Build(drag_data
),
697 void BrowserPlugin::didReceiveResponse(
698 const blink::WebURLResponse
& response
) {
701 void BrowserPlugin::didReceiveData(const char* data
, int data_length
) {
702 if (auto_navigate_
) {
703 std::string
value(data
, data_length
);
704 html_string_
+= value
;
708 void BrowserPlugin::didFinishLoading() {
709 if (auto_navigate_
) {
710 // TODO(lazyboy): Make |auto_navigate_| stuff work.
711 UpdateDOMAttribute(content::browser_plugin::kAttributeSrc
, html_string_
);
715 void BrowserPlugin::didFailLoading(const blink::WebURLError
& error
) {
718 void BrowserPlugin::didFinishLoadingFrameRequest(const blink::WebURL
& url
,
722 void BrowserPlugin::didFailLoadingFrameRequest(
723 const blink::WebURL
& url
,
725 const blink::WebURLError
& error
) {
728 bool BrowserPlugin::executeEditCommand(const blink::WebString
& name
) {
729 browser_plugin_manager()->Send(new BrowserPluginHostMsg_ExecuteEditCommand(
730 render_view_routing_id_
,
731 browser_plugin_instance_id_
,
734 // BrowserPlugin swallows edit commands.
738 bool BrowserPlugin::executeEditCommand(const blink::WebString
& name
,
739 const blink::WebString
& value
) {
740 edit_commands_
.push_back(EditCommand(name
.utf8(), value
.utf8()));
741 // BrowserPlugin swallows edit commands.
745 bool BrowserPlugin::setComposition(
746 const blink::WebString
& text
,
747 const blink::WebVector
<blink::WebCompositionUnderline
>& underlines
,
752 std::vector
<blink::WebCompositionUnderline
> std_underlines
;
753 for (size_t i
= 0; i
< underlines
.size(); ++i
) {
754 std_underlines
.push_back(underlines
[i
]);
756 browser_plugin_manager()->Send(new BrowserPluginHostMsg_ImeSetComposition(
757 render_view_routing_id_
,
758 browser_plugin_instance_id_
,
763 // TODO(kochi): This assumes the IPC handling always succeeds.
767 bool BrowserPlugin::confirmComposition(
768 const blink::WebString
& text
,
769 blink::WebWidget::ConfirmCompositionBehavior selectionBehavior
) {
772 bool keep_selection
= (selectionBehavior
== blink::WebWidget::KeepSelection
);
773 browser_plugin_manager()->Send(new BrowserPluginHostMsg_ImeConfirmComposition(
774 render_view_routing_id_
,
775 browser_plugin_instance_id_
,
778 // TODO(kochi): This assumes the IPC handling always succeeds.
782 void BrowserPlugin::extendSelectionAndDelete(int before
, int after
) {
785 browser_plugin_manager()->Send(
786 new BrowserPluginHostMsg_ExtendSelectionAndDelete(
787 render_view_routing_id_
,
788 browser_plugin_instance_id_
,
793 void BrowserPlugin::OnLockMouseACK(bool succeeded
) {
794 mouse_locked_
= succeeded
;
795 browser_plugin_manager()->Send(new BrowserPluginHostMsg_LockMouse_ACK(
796 render_view_routing_id_
,
797 browser_plugin_instance_id_
,
801 void BrowserPlugin::OnMouseLockLost() {
802 mouse_locked_
= false;
803 browser_plugin_manager()->Send(new BrowserPluginHostMsg_UnlockMouse_ACK(
804 render_view_routing_id_
,
805 browser_plugin_instance_id_
));
808 bool BrowserPlugin::HandleMouseLockedInputEvent(
809 const blink::WebMouseEvent
& event
) {
810 browser_plugin_manager()->Send(
811 new BrowserPluginHostMsg_HandleInputEvent(render_view_routing_id_
,
812 browser_plugin_instance_id_
,
818 } // namespace content