Updating trunk VERSION from 2139.0 to 2140.0
[chromium-blink-merge.git] / content / renderer / browser_plugin / browser_plugin.cc
blob4bd18307617782f42cb7ec55573853cb7097de1c
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;
39 using blink::WebRect;
40 using blink::WebURL;
41 using blink::WebVector;
43 namespace content {
45 BrowserPlugin::BrowserPlugin(RenderViewImpl* render_view,
46 blink::WebFrame* frame,
47 bool auto_navigate)
48 : attached_(false),
49 attach_pending_(false),
50 render_view_(render_view->AsWeakPtr()),
51 render_view_routing_id_(render_view->GetRoutingID()),
52 container_(NULL),
53 paint_ack_received_(true),
54 last_device_scale_factor_(GetDeviceScaleFactor()),
55 sad_guest_(NULL),
56 guest_crashed_(false),
57 content_window_routing_id_(MSG_ROUTING_NONE),
58 plugin_focused_(false),
59 visible_(true),
60 auto_navigate_(auto_navigate),
61 mouse_locked_(false),
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_);
70 if (!ready())
71 return;
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) {
79 bool handled = true;
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)
97 IPC_END_MESSAGE_MAP()
98 return handled;
101 void BrowserPlugin::UpdateDOMAttribute(const std::string& attribute_name,
102 const std::string& attribute_value) {
103 if (!container())
104 return;
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()) !=
111 attribute_value)) {
112 element.setAttribute(web_attribute_name,
113 blink::WebString::fromUTF8(attribute_value));
117 void BrowserPlugin::RemoveDOMAttribute(const std::string& attribute_name) {
118 if (!container())
119 return;
121 container()->element().removeAttribute(
122 blink::WebString::fromUTF8(attribute_name));
125 std::string BrowserPlugin::GetDOMAttributeValue(
126 const std::string& attribute_name) const {
127 if (!container())
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 {
135 if (!container())
136 return false;
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() {
147 if (!ready())
148 return;
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_,
158 opaque));
161 void BrowserPlugin::Attach() {
162 if (ready()) {
163 attached_ = false;
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_,
183 attach_params));
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,
194 bool reverse) {
195 DCHECK(render_view_.get());
196 render_view_->GetWebView()->advanceFocus(reverse);
199 void BrowserPlugin::OnAttachACK(int browser_plugin_instance_id) {
200 DCHECK(!attached());
201 attached_ = true;
202 attach_pending_ = false;
205 void BrowserPlugin::OnBuffersSwapped(
206 int instance_id,
207 const FrameMsg_BuffersSwapped_Params& params) {
208 EnableCompositing(true);
210 compositing_helper_->OnBuffersSwapped(params.size,
211 params.mailbox,
212 params.gpu_route_id,
213 params.gpu_host_id,
214 GetDeviceScaleFactor());
217 void BrowserPlugin::OnCompositorFrameSwapped(const IPC::Message& message) {
218 BrowserPluginMsg_CompositorFrameSwapped::Param param;
219 if (!BrowserPluginMsg_CompositorFrameSwapped::Read(&message, &param))
220 return;
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,
233 int request_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_,
241 request_id,
242 SkBitmap()));
243 return;
245 compositing_helper_->CopyFromCompositingSurface(request_id, source_rect,
246 dest_size);
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(
267 FROM_HERE,
268 base::Bind(&BrowserPlugin::ShowSadGraphic,
269 weak_ptr_factory_.GetWeakPtr()));
272 void BrowserPlugin::OnSetCursor(int browser_plugin_instance_id,
273 const WebCursor& cursor) {
274 cursor_ = cursor;
277 void BrowserPlugin::OnSetMouseLock(int browser_plugin_instance_id,
278 bool enable) {
279 if (enable) {
280 if (mouse_locked_)
281 return;
282 render_view_->mouse_lock_dispatcher()->LockMouse(this);
283 } else {
284 if (!mouse_locked_) {
285 OnLockMouseACK(false);
286 return;
288 render_view_->mouse_lock_dispatcher()->UnlockMouse(this);
292 void BrowserPlugin::OnShouldAcceptTouchEvents(int browser_plugin_instance_id,
293 bool accept) {
294 if (container()) {
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()) {
316 return;
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_,
325 resize_params));
328 NPObject* BrowserPlugin::GetContentWindow() const {
329 if (content_window_routing_id_ == MSG_ROUTING_NONE)
330 return NULL;
331 RenderViewImpl* guest_render_view = RenderViewImpl::FromRoutingID(
332 content_window_routing_id_);
333 if (!guest_render_view)
334 return NULL;
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.
342 if (container_)
343 container_->invalidate();
346 float BrowserPlugin::GetDeviceScaleFactor() const {
347 if (!render_view_.get())
348 return 1.0f;
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_)
354 return;
356 BrowserPluginHostMsg_ResizeGuest_Params params;
357 PopulateResizeGuestParameters(&params, plugin_size(), true);
358 browser_plugin_manager()->Send(new BrowserPluginHostMsg_ResizeGuest(
359 render_view_routing_id_,
360 browser_plugin_instance_id_,
361 params));
364 void BrowserPlugin::UpdateGuestFocusState() {
365 if (!ready())
366 return;
367 bool should_be_focused = ShouldGuestBeFocused();
368 browser_plugin_manager()->Send(new BrowserPluginHostMsg_SetFocus(
369 render_view_routing_id_,
370 browser_plugin_instance_id_,
371 should_be_focused));
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 {
382 return container_;
385 bool BrowserPlugin::initialize(WebPluginContainer* container) {
386 if (!container)
387 return false;
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);
404 return true;
407 void BrowserPlugin::EnableCompositing(bool enable) {
408 bool enabled = !!compositing_helper_.get();
409 if (enabled == enable)
410 return;
412 if (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());
422 if (!enable) {
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_);
433 if (container_)
434 container_->clearScriptObjects();
436 if (compositing_helper_.get())
437 compositing_helper_->OnContainerDestroy();
438 container_ = NULL;
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() {
446 if (!bindings_)
447 return NULL;
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() {
456 return npp_.get();
459 bool BrowserPlugin::supportsKeyboardFocus() const {
460 return true;
463 bool BrowserPlugin::supportsEditCommands() const {
464 return true;
467 bool BrowserPlugin::supportsInputMethod() const {
468 return true;
471 bool BrowserPlugin::canProcessDrag() const {
472 return true;
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.
482 if (sad_guest_) {
483 PaintSadPlugin(canvas, plugin_rect_, *sad_guest_);
484 return;
487 SkAutoCanvasRestore auto_restore(canvas, true);
488 canvas->translate(plugin_rect_.x(), plugin_rect_.y());
489 SkRect image_data_rect = SkRect::MakeXYWH(
490 SkIntToScalar(0),
491 SkIntToScalar(0),
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.
497 SkPaint paint;
498 paint.setStyle(SkPaint::kFill_Style);
499 paint.setColor(guest_crashed_ ? SK_ColorBLACK : SK_ColorWHITE);
500 canvas->drawRect(image_data_rect, paint);
503 // static
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:
518 return true;
519 default:
520 break;
522 return false;
525 void BrowserPlugin::updateGeometry(
526 const WebRect& window_rect,
527 const WebRect& clip_rect,
528 const WebVector<WebRect>& cut_outs_rects,
529 bool is_visible) {
530 int old_width = width();
531 int old_height = height();
532 plugin_rect_ = window_rect;
533 if (!attached())
534 return;
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
541 // resize.
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_));
547 return;
550 BrowserPluginHostMsg_ResizeGuest_Params params;
551 PopulateResizeGuestParameters(&params, 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_,
556 params));
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())
578 return;
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)
590 return;
592 visible_ = visible;
593 if (!ready())
594 return;
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_,
602 visible));
605 bool BrowserPlugin::acceptsInputEvents() {
606 return true;
609 bool BrowserPlugin::handleInputEvent(const blink::WebInputEvent& event,
610 blink::WebCursorInfo& cursor_info) {
611 if (guest_crashed_ || !ready())
612 return false;
614 if (event.type == blink::WebInputEvent::ContextMenu)
615 return true;
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;
640 break;
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_,
666 edit_commands_));
667 edit_commands_.clear();
670 browser_plugin_manager()->Send(
671 new BrowserPluginHostMsg_HandleInputEvent(render_view_routing_id_,
672 browser_plugin_instance_id_,
673 plugin_rect_,
674 modified_event));
675 GetWebKitCursorInfo(cursor_, &cursor_info);
676 return true;
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())
685 return false;
686 browser_plugin_manager()->Send(
687 new BrowserPluginHostMsg_DragStatusUpdate(
688 render_view_routing_id_,
689 browser_plugin_instance_id_,
690 drag_status,
691 DropDataBuilder::Build(drag_data),
692 mask,
693 position));
694 return true;
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,
719 void* notify_data) {
722 void BrowserPlugin::didFailLoadingFrameRequest(
723 const blink::WebURL& url,
724 void* notify_data,
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_,
732 name.utf8()));
734 // BrowserPlugin swallows edit commands.
735 return true;
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.
742 return true;
745 bool BrowserPlugin::setComposition(
746 const blink::WebString& text,
747 const blink::WebVector<blink::WebCompositionUnderline>& underlines,
748 int selectionStart,
749 int selectionEnd) {
750 if (!ready())
751 return false;
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_,
759 text.utf8(),
760 std_underlines,
761 selectionStart,
762 selectionEnd));
763 // TODO(kochi): This assumes the IPC handling always succeeds.
764 return true;
767 bool BrowserPlugin::confirmComposition(
768 const blink::WebString& text,
769 blink::WebWidget::ConfirmCompositionBehavior selectionBehavior) {
770 if (!ready())
771 return false;
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_,
776 text.utf8(),
777 keep_selection));
778 // TODO(kochi): This assumes the IPC handling always succeeds.
779 return true;
782 void BrowserPlugin::extendSelectionAndDelete(int before, int after) {
783 if (!ready())
784 return;
785 browser_plugin_manager()->Send(
786 new BrowserPluginHostMsg_ExtendSelectionAndDelete(
787 render_view_routing_id_,
788 browser_plugin_instance_id_,
789 before,
790 after));
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_,
798 succeeded));
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_,
813 plugin_rect_,
814 &event));
815 return true;
818 } // namespace content