Android media: VideoFrame should not store so many sync points.
[chromium-blink-merge.git] / content / browser / browser_plugin / browser_plugin_guest.cc
blob1da2fdd3f1525206597a0251e8920740ec887dcb
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.
5 #include "content/browser/browser_plugin/browser_plugin_guest.h"
7 #include <algorithm>
9 #include "base/message_loop/message_loop.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "content/browser/browser_plugin/browser_plugin_embedder.h"
12 #include "content/browser/browser_thread_impl.h"
13 #include "content/browser/child_process_security_policy_impl.h"
14 #include "content/browser/frame_host/render_frame_host_impl.h"
15 #include "content/browser/frame_host/render_widget_host_view_guest.h"
16 #include "content/browser/loader/resource_dispatcher_host_impl.h"
17 #include "content/browser/renderer_host/render_view_host_impl.h"
18 #include "content/browser/renderer_host/render_widget_host_impl.h"
19 #include "content/browser/renderer_host/render_widget_host_view_base.h"
20 #include "content/browser/web_contents/web_contents_impl.h"
21 #include "content/browser/web_contents/web_contents_view_guest.h"
22 #include "content/common/browser_plugin/browser_plugin_messages.h"
23 #include "content/common/content_constants_internal.h"
24 #include "content/common/drag_messages.h"
25 #include "content/common/input_messages.h"
26 #include "content/common/view_messages.h"
27 #include "content/public/browser/browser_context.h"
28 #include "content/public/browser/browser_plugin_guest_manager.h"
29 #include "content/public/browser/content_browser_client.h"
30 #include "content/public/browser/render_widget_host_view.h"
31 #include "content/public/browser/user_metrics.h"
32 #include "content/public/browser/web_contents_observer.h"
33 #include "content/public/common/drop_data.h"
34 #include "third_party/WebKit/public/platform/WebCursorInfo.h"
36 #if defined(OS_MACOSX)
37 #include "content/browser/browser_plugin/browser_plugin_popup_menu_helper_mac.h"
38 #endif
40 namespace content {
42 class BrowserPluginGuest::EmbedderWebContentsObserver
43 : public WebContentsObserver {
44 public:
45 explicit EmbedderWebContentsObserver(BrowserPluginGuest* guest)
46 : WebContentsObserver(guest->embedder_web_contents()),
47 browser_plugin_guest_(guest) {
50 virtual ~EmbedderWebContentsObserver() {
53 // WebContentsObserver implementation.
54 virtual void WasShown() OVERRIDE {
55 browser_plugin_guest_->EmbedderVisibilityChanged(true);
58 virtual void WasHidden() OVERRIDE {
59 browser_plugin_guest_->EmbedderVisibilityChanged(false);
62 private:
63 BrowserPluginGuest* browser_plugin_guest_;
65 DISALLOW_COPY_AND_ASSIGN(EmbedderWebContentsObserver);
68 BrowserPluginGuest::BrowserPluginGuest(
69 int instance_id,
70 bool has_render_view,
71 WebContentsImpl* web_contents,
72 BrowserPluginGuestDelegate* delegate)
73 : WebContentsObserver(web_contents),
74 embedder_web_contents_(NULL),
75 instance_id_(instance_id),
76 guest_device_scale_factor_(1.0f),
77 focused_(false),
78 mouse_locked_(false),
79 pending_lock_request_(false),
80 guest_visible_(false),
81 guest_opaque_(true),
82 embedder_visible_(true),
83 auto_size_enabled_(false),
84 copy_request_id_(0),
85 has_render_view_(has_render_view),
86 last_seen_auto_size_enabled_(false),
87 is_in_destruction_(false),
88 last_text_input_type_(ui::TEXT_INPUT_TYPE_NONE),
89 last_input_mode_(ui::TEXT_INPUT_MODE_DEFAULT),
90 last_can_compose_inline_(true),
91 delegate_(delegate),
92 weak_ptr_factory_(this) {
93 DCHECK(web_contents);
94 DCHECK(delegate);
95 RecordAction(base::UserMetricsAction("BrowserPlugin.Guest.Create"));
96 web_contents->SetBrowserPluginGuest(this);
97 delegate->RegisterDestructionCallback(
98 base::Bind(&BrowserPluginGuest::WillDestroy, AsWeakPtr()));
101 void BrowserPluginGuest::WillDestroy() {
102 is_in_destruction_ = true;
103 embedder_web_contents_ = NULL;
106 base::WeakPtr<BrowserPluginGuest> BrowserPluginGuest::AsWeakPtr() {
107 return weak_ptr_factory_.GetWeakPtr();
110 bool BrowserPluginGuest::LockMouse(bool allowed) {
111 if (!attached() || (mouse_locked_ == allowed))
112 return false;
114 return embedder_web_contents()->GotResponseToLockMouseRequest(allowed);
117 void BrowserPluginGuest::Destroy() {
118 delegate_->Destroy();
121 WebContentsImpl* BrowserPluginGuest::CreateNewGuestWindow(
122 const WebContents::CreateParams& params) {
123 WebContentsImpl* new_contents =
124 static_cast<WebContentsImpl*>(delegate_->CreateNewGuestWindow(params));
125 DCHECK(new_contents);
126 return new_contents;
129 bool BrowserPluginGuest::OnMessageReceivedFromEmbedder(
130 const IPC::Message& message) {
131 bool handled = true;
132 IPC_BEGIN_MESSAGE_MAP(BrowserPluginGuest, message)
133 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_CompositorFrameSwappedACK,
134 OnCompositorFrameSwappedACK)
135 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_CopyFromCompositingSurfaceAck,
136 OnCopyFromCompositingSurfaceAck)
137 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_DragStatusUpdate,
138 OnDragStatusUpdate)
139 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_ExecuteEditCommand,
140 OnExecuteEditCommand)
141 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_ExtendSelectionAndDelete,
142 OnExtendSelectionAndDelete)
143 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_HandleInputEvent,
144 OnHandleInputEvent)
145 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_ImeConfirmComposition,
146 OnImeConfirmComposition)
147 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_ImeSetComposition,
148 OnImeSetComposition)
149 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_LockMouse_ACK, OnLockMouseAck)
150 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_PluginDestroyed, OnPluginDestroyed)
151 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_ReclaimCompositorResources,
152 OnReclaimCompositorResources)
153 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_ResizeGuest, OnResizeGuest)
154 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_SetAutoSize, OnSetAutoSize)
155 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_SetEditCommandsForNextKeyEvent,
156 OnSetEditCommandsForNextKeyEvent)
157 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_SetFocus, OnSetFocus)
158 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_SetContentsOpaque,
159 OnSetContentsOpaque)
160 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_SetVisibility, OnSetVisibility)
161 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_UnlockMouse_ACK, OnUnlockMouseAck)
162 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_UpdateGeometry, OnUpdateGeometry)
163 IPC_MESSAGE_UNHANDLED(handled = false)
164 IPC_END_MESSAGE_MAP()
165 return handled;
168 void BrowserPluginGuest::Initialize(
169 const BrowserPluginHostMsg_Attach_Params& params,
170 WebContentsImpl* embedder_web_contents,
171 const base::DictionaryValue& extra_params) {
172 focused_ = params.focused;
173 guest_visible_ = params.visible;
174 guest_opaque_ = params.opaque;
175 guest_window_rect_ = gfx::Rect(params.origin,
176 params.resize_guest_params.view_size);
178 auto_size_enabled_ = params.auto_size_params.enable;
179 max_auto_size_ = params.auto_size_params.max_size;
180 min_auto_size_ = params.auto_size_params.min_size;
182 // Once a BrowserPluginGuest has an embedder WebContents, it's considered to
183 // be attached.
184 embedder_web_contents_ = embedder_web_contents;
186 WebContentsViewGuest* new_view =
187 static_cast<WebContentsViewGuest*>(GetWebContents()->GetView());
188 new_view->OnGuestInitialized(embedder_web_contents->GetView());
190 RendererPreferences* renderer_prefs =
191 GetWebContents()->GetMutableRendererPrefs();
192 std::string guest_user_agent_override = renderer_prefs->user_agent_override;
193 // Copy renderer preferences (and nothing else) from the embedder's
194 // WebContents to the guest.
196 // For GTK and Aura this is necessary to get proper renderer configuration
197 // values for caret blinking interval, colors related to selection and
198 // focus.
199 *renderer_prefs = *embedder_web_contents_->GetMutableRendererPrefs();
200 renderer_prefs->user_agent_override = guest_user_agent_override;
202 // We would like the guest to report changes to frame names so that we can
203 // update the BrowserPlugin's corresponding 'name' attribute.
204 // TODO(fsamuel): Remove this once http://crbug.com/169110 is addressed.
205 renderer_prefs->report_frame_name_changes = true;
206 // Navigation is disabled in Chrome Apps. We want to make sure guest-initiated
207 // navigations still continue to function inside the app.
208 renderer_prefs->browser_handles_all_top_level_requests = false;
209 // Disable "client blocked" error page for browser plugin.
210 renderer_prefs->disable_client_blocked_error_page = true;
212 embedder_web_contents_observer_.reset(new EmbedderWebContentsObserver(this));
214 OnSetAutoSize(
215 instance_id_, params.auto_size_params, params.resize_guest_params);
217 // Create a swapped out RenderView for the guest in the embedder render
218 // process, so that the embedder can access the guest's window object.
219 int guest_routing_id =
220 GetWebContents()->CreateSwappedOutRenderView(
221 embedder_web_contents_->GetSiteInstance());
222 SendMessageToEmbedder(
223 new BrowserPluginMsg_GuestContentWindowReady(instance_id_,
224 guest_routing_id));
226 // TODO(chrishtr): this code is wrong. The navigate_on_drag_drop field will
227 // be reset again the next time preferences are updated.
228 WebPreferences prefs =
229 GetWebContents()->GetRenderViewHost()->GetWebkitPreferences();
230 prefs.navigate_on_drag_drop = false;
231 GetWebContents()->GetRenderViewHost()->UpdateWebkitPreferences(prefs);
233 // Enable input method for guest if it's enabled for the embedder.
234 if (static_cast<RenderViewHostImpl*>(
235 embedder_web_contents_->GetRenderViewHost())->input_method_active()) {
236 RenderViewHostImpl* guest_rvh = static_cast<RenderViewHostImpl*>(
237 GetWebContents()->GetRenderViewHost());
238 guest_rvh->SetInputMethodActive(true);
241 // Inform the embedder of the guest's attachment.
242 SendMessageToEmbedder(new BrowserPluginMsg_Attach_ACK(instance_id_));
245 BrowserPluginGuest::~BrowserPluginGuest() {
248 // static
249 BrowserPluginGuest* BrowserPluginGuest::Create(
250 int instance_id,
251 WebContentsImpl* web_contents,
252 BrowserPluginGuestDelegate* delegate) {
253 return new BrowserPluginGuest(
254 instance_id, web_contents->opener() != NULL, web_contents, delegate);
257 // static
258 bool BrowserPluginGuest::IsGuest(WebContentsImpl* web_contents) {
259 return web_contents && web_contents->GetBrowserPluginGuest();
262 // static
263 bool BrowserPluginGuest::IsGuest(RenderViewHostImpl* render_view_host) {
264 return render_view_host && IsGuest(
265 static_cast<WebContentsImpl*>(WebContents::FromRenderViewHost(
266 render_view_host)));
269 RenderWidgetHostView* BrowserPluginGuest::GetEmbedderRenderWidgetHostView() {
270 if (!attached())
271 return NULL;
272 return embedder_web_contents_->GetRenderWidgetHostView();
275 void BrowserPluginGuest::UpdateVisibility() {
276 OnSetVisibility(instance_id_, visible());
279 void BrowserPluginGuest::CopyFromCompositingSurface(
280 gfx::Rect src_subrect,
281 gfx::Size dst_size,
282 const base::Callback<void(bool, const SkBitmap&)>& callback) {
283 copy_request_callbacks_.insert(std::make_pair(++copy_request_id_, callback));
284 SendMessageToEmbedder(
285 new BrowserPluginMsg_CopyFromCompositingSurface(instance_id(),
286 copy_request_id_, src_subrect, dst_size));
289 BrowserPluginGuestManager*
290 BrowserPluginGuest::GetBrowserPluginGuestManager() const {
291 return GetWebContents()->GetBrowserContext()->GetGuestManager();
294 // screen.
295 gfx::Rect BrowserPluginGuest::ToGuestRect(const gfx::Rect& bounds) {
296 gfx::Rect guest_rect(bounds);
297 guest_rect.Offset(guest_window_rect_.OffsetFromOrigin());
298 if (embedder_web_contents()->GetBrowserPluginGuest()) {
299 BrowserPluginGuest* embedder_guest =
300 embedder_web_contents()->GetBrowserPluginGuest();
301 guest_rect.Offset(embedder_guest->guest_window_rect_.OffsetFromOrigin());
303 return guest_rect;
306 void BrowserPluginGuest::EmbedderVisibilityChanged(bool visible) {
307 embedder_visible_ = visible;
308 UpdateVisibility();
311 void BrowserPluginGuest::PointerLockPermissionResponse(bool allow) {
312 SendMessageToEmbedder(
313 new BrowserPluginMsg_SetMouseLock(instance_id(), allow));
316 WebContentsImpl* BrowserPluginGuest::GetWebContents() const {
317 return static_cast<WebContentsImpl*>(web_contents());
320 gfx::Point BrowserPluginGuest::GetScreenCoordinates(
321 const gfx::Point& relative_position) const {
322 if (!attached())
323 return relative_position;
325 gfx::Point screen_pos(relative_position);
326 screen_pos += guest_window_rect_.OffsetFromOrigin();
327 if (embedder_web_contents()->GetBrowserPluginGuest()) {
328 BrowserPluginGuest* embedder_guest =
329 embedder_web_contents()->GetBrowserPluginGuest();
330 screen_pos += embedder_guest->guest_window_rect_.OffsetFromOrigin();
332 return screen_pos;
335 bool BrowserPluginGuest::InAutoSizeBounds(const gfx::Size& size) const {
336 return size.width() <= max_auto_size_.width() &&
337 size.height() <= max_auto_size_.height();
340 void BrowserPluginGuest::SendMessageToEmbedder(IPC::Message* msg) {
341 if (!attached()) {
342 // Some pages such as data URLs, javascript URLs, and about:blank
343 // do not load external resources and so they load prior to attachment.
344 // As a result, we must save all these IPCs until attachment and then
345 // forward them so that the embedder gets a chance to see and process
346 // the load events.
347 pending_messages_.push_back(linked_ptr<IPC::Message>(msg));
348 return;
350 msg->set_routing_id(embedder_web_contents_->GetRoutingID());
351 embedder_web_contents_->Send(msg);
354 void BrowserPluginGuest::DragSourceEndedAt(int client_x, int client_y,
355 int screen_x, int screen_y, blink::WebDragOperation operation) {
356 web_contents()->GetRenderViewHost()->DragSourceEndedAt(client_x, client_y,
357 screen_x, screen_y, operation);
360 void BrowserPluginGuest::EndSystemDrag() {
361 RenderViewHostImpl* guest_rvh = static_cast<RenderViewHostImpl*>(
362 GetWebContents()->GetRenderViewHost());
363 guest_rvh->DragSourceSystemDragEnded();
366 void BrowserPluginGuest::SendQueuedMessages() {
367 if (!attached())
368 return;
370 while (!pending_messages_.empty()) {
371 linked_ptr<IPC::Message> message_ptr = pending_messages_.front();
372 pending_messages_.pop_front();
373 SendMessageToEmbedder(message_ptr.release());
377 void BrowserPluginGuest::DidCommitProvisionalLoadForFrame(
378 RenderFrameHost* render_frame_host,
379 const GURL& url,
380 PageTransition transition_type) {
381 RecordAction(base::UserMetricsAction("BrowserPlugin.Guest.DidNavigate"));
384 void BrowserPluginGuest::RenderViewReady() {
385 RenderViewHost* rvh = GetWebContents()->GetRenderViewHost();
386 // TODO(fsamuel): Investigate whether it's possible to update state earlier
387 // here (see http://crbug.com/158151).
388 Send(new InputMsg_SetFocus(routing_id(), focused_));
389 UpdateVisibility();
390 if (auto_size_enabled_)
391 rvh->EnableAutoResize(min_auto_size_, max_auto_size_);
392 else
393 rvh->DisableAutoResize(full_size_);
395 OnSetContentsOpaque(instance_id_, guest_opaque_);
397 RenderWidgetHostImpl::From(rvh)->set_hung_renderer_delay_ms(
398 base::TimeDelta::FromMilliseconds(kHungRendererDelayMs));
401 void BrowserPluginGuest::RenderProcessGone(base::TerminationStatus status) {
402 SendMessageToEmbedder(new BrowserPluginMsg_GuestGone(instance_id()));
403 switch (status) {
404 case base::TERMINATION_STATUS_PROCESS_WAS_KILLED:
405 RecordAction(base::UserMetricsAction("BrowserPlugin.Guest.Killed"));
406 break;
407 case base::TERMINATION_STATUS_PROCESS_CRASHED:
408 RecordAction(base::UserMetricsAction("BrowserPlugin.Guest.Crashed"));
409 break;
410 case base::TERMINATION_STATUS_ABNORMAL_TERMINATION:
411 RecordAction(
412 base::UserMetricsAction("BrowserPlugin.Guest.AbnormalDeath"));
413 break;
414 default:
415 break;
419 // static
420 bool BrowserPluginGuest::ShouldForwardToBrowserPluginGuest(
421 const IPC::Message& message) {
422 switch (message.type()) {
423 case BrowserPluginHostMsg_CompositorFrameSwappedACK::ID:
424 case BrowserPluginHostMsg_CopyFromCompositingSurfaceAck::ID:
425 case BrowserPluginHostMsg_DragStatusUpdate::ID:
426 case BrowserPluginHostMsg_ExecuteEditCommand::ID:
427 case BrowserPluginHostMsg_ExtendSelectionAndDelete::ID:
428 case BrowserPluginHostMsg_HandleInputEvent::ID:
429 case BrowserPluginHostMsg_ImeConfirmComposition::ID:
430 case BrowserPluginHostMsg_ImeSetComposition::ID:
431 case BrowserPluginHostMsg_LockMouse_ACK::ID:
432 case BrowserPluginHostMsg_PluginDestroyed::ID:
433 case BrowserPluginHostMsg_ReclaimCompositorResources::ID:
434 case BrowserPluginHostMsg_ResizeGuest::ID:
435 case BrowserPluginHostMsg_SetAutoSize::ID:
436 case BrowserPluginHostMsg_SetEditCommandsForNextKeyEvent::ID:
437 case BrowserPluginHostMsg_SetFocus::ID:
438 case BrowserPluginHostMsg_SetContentsOpaque::ID:
439 case BrowserPluginHostMsg_SetVisibility::ID:
440 case BrowserPluginHostMsg_UnlockMouse_ACK::ID:
441 case BrowserPluginHostMsg_UpdateGeometry::ID:
442 return true;
443 default:
444 return false;
448 bool BrowserPluginGuest::OnMessageReceived(const IPC::Message& message) {
449 bool handled = true;
450 IPC_BEGIN_MESSAGE_MAP(BrowserPluginGuest, message)
451 IPC_MESSAGE_HANDLER(InputHostMsg_ImeCancelComposition,
452 OnImeCancelComposition)
453 #if defined(OS_MACOSX) || defined(USE_AURA)
454 IPC_MESSAGE_HANDLER(InputHostMsg_ImeCompositionRangeChanged,
455 OnImeCompositionRangeChanged)
456 #endif
457 IPC_MESSAGE_HANDLER(ViewHostMsg_HasTouchEventHandlers,
458 OnHasTouchEventHandlers)
459 IPC_MESSAGE_HANDLER(ViewHostMsg_LockMouse, OnLockMouse)
460 IPC_MESSAGE_HANDLER(ViewHostMsg_SetCursor, OnSetCursor)
461 #if defined(OS_MACOSX)
462 // MacOSX creates and populates platform-specific select drop-down menus
463 // whereas other platforms merely create a popup window that the guest
464 // renderer process paints inside.
465 IPC_MESSAGE_HANDLER(ViewHostMsg_ShowPopup, OnShowPopup)
466 #endif
467 IPC_MESSAGE_HANDLER(ViewHostMsg_ShowWidget, OnShowWidget)
468 IPC_MESSAGE_HANDLER(ViewHostMsg_TakeFocus, OnTakeFocus)
469 IPC_MESSAGE_HANDLER(ViewHostMsg_TextInputStateChanged,
470 OnTextInputStateChanged)
471 IPC_MESSAGE_HANDLER(ViewHostMsg_UnlockMouse, OnUnlockMouse)
472 IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateRect, OnUpdateRect)
473 IPC_MESSAGE_UNHANDLED(handled = false)
474 IPC_END_MESSAGE_MAP()
475 return handled;
478 void BrowserPluginGuest::Attach(
479 WebContentsImpl* embedder_web_contents,
480 const BrowserPluginHostMsg_Attach_Params& params,
481 const base::DictionaryValue& extra_params) {
482 if (attached())
483 return;
485 if (delegate_)
486 delegate_->WillAttach(embedder_web_contents, extra_params);
488 // If a RenderView has already been created for this new window, then we need
489 // to initialize the browser-side state now so that the RenderFrameHostManager
490 // does not create a new RenderView on navigation.
491 if (has_render_view_) {
492 static_cast<RenderViewHostImpl*>(
493 GetWebContents()->GetRenderViewHost())->Init();
494 WebContentsViewGuest* new_view =
495 static_cast<WebContentsViewGuest*>(GetWebContents()->GetView());
496 new_view->CreateViewForWidget(web_contents()->GetRenderViewHost());
499 Initialize(params, embedder_web_contents, extra_params);
501 SendQueuedMessages();
503 if (delegate_)
504 delegate_->DidAttach();
506 RecordAction(base::UserMetricsAction("BrowserPlugin.Guest.Attached"));
509 void BrowserPluginGuest::OnCompositorFrameSwappedACK(
510 int instance_id,
511 const FrameHostMsg_CompositorFrameSwappedACK_Params& params) {
512 RenderWidgetHostImpl::SendSwapCompositorFrameAck(params.producing_route_id,
513 params.output_surface_id,
514 params.producing_host_id,
515 params.ack);
518 void BrowserPluginGuest::OnDragStatusUpdate(int instance_id,
519 blink::WebDragStatus drag_status,
520 const DropData& drop_data,
521 blink::WebDragOperationsMask mask,
522 const gfx::Point& location) {
523 RenderViewHost* host = GetWebContents()->GetRenderViewHost();
524 switch (drag_status) {
525 case blink::WebDragStatusEnter:
526 embedder_web_contents_->GetBrowserPluginEmbedder()->DragEnteredGuest(
527 this);
528 host->DragTargetDragEnter(drop_data, location, location, mask, 0);
529 break;
530 case blink::WebDragStatusOver:
531 host->DragTargetDragOver(location, location, mask, 0);
532 break;
533 case blink::WebDragStatusLeave:
534 embedder_web_contents_->GetBrowserPluginEmbedder()->DragLeftGuest(this);
535 host->DragTargetDragLeave();
536 break;
537 case blink::WebDragStatusDrop:
538 host->DragTargetDrop(location, location, 0);
539 EndSystemDrag();
540 break;
541 case blink::WebDragStatusUnknown:
542 NOTREACHED();
546 void BrowserPluginGuest::OnExecuteEditCommand(int instance_id,
547 const std::string& name) {
548 Send(new InputMsg_ExecuteEditCommand(routing_id(), name, std::string()));
551 void BrowserPluginGuest::OnImeSetComposition(
552 int instance_id,
553 const std::string& text,
554 const std::vector<blink::WebCompositionUnderline>& underlines,
555 int selection_start,
556 int selection_end) {
557 Send(new InputMsg_ImeSetComposition(routing_id(),
558 base::UTF8ToUTF16(text), underlines,
559 selection_start, selection_end));
562 void BrowserPluginGuest::OnImeConfirmComposition(
563 int instance_id,
564 const std::string& text,
565 bool keep_selection) {
566 Send(new InputMsg_ImeConfirmComposition(routing_id(),
567 base::UTF8ToUTF16(text),
568 gfx::Range::InvalidRange(),
569 keep_selection));
572 void BrowserPluginGuest::OnExtendSelectionAndDelete(
573 int instance_id,
574 int before,
575 int after) {
576 RenderFrameHostImpl* rfh = static_cast<RenderFrameHostImpl*>(
577 web_contents()->GetFocusedFrame());
578 if (rfh)
579 rfh->ExtendSelectionAndDelete(before, after);
582 void BrowserPluginGuest::OnReclaimCompositorResources(
583 int instance_id,
584 const FrameHostMsg_ReclaimCompositorResources_Params& params) {
585 RenderWidgetHostImpl::SendReclaimCompositorResources(params.route_id,
586 params.output_surface_id,
587 params.renderer_host_id,
588 params.ack);
591 void BrowserPluginGuest::OnHandleInputEvent(
592 int instance_id,
593 const gfx::Rect& guest_window_rect,
594 const blink::WebInputEvent* event) {
595 guest_window_rect_ = guest_window_rect;
596 // If the embedder's RWHV is destroyed then that means that the embedder's
597 // window has been closed but the embedder's WebContents has not yet been
598 // destroyed. Computing screen coordinates of a BrowserPlugin only makes sense
599 // if there is a visible embedder.
600 if (embedder_web_contents_->GetRenderWidgetHostView()) {
601 guest_screen_rect_ = guest_window_rect;
602 guest_screen_rect_.Offset(
603 embedder_web_contents_->GetRenderWidgetHostView()->
604 GetViewBounds().OffsetFromOrigin());
606 RenderViewHostImpl* guest_rvh = static_cast<RenderViewHostImpl*>(
607 GetWebContents()->GetRenderViewHost());
609 if (blink::WebInputEvent::isMouseEventType(event->type)) {
610 guest_rvh->ForwardMouseEvent(
611 *static_cast<const blink::WebMouseEvent*>(event));
612 return;
615 if (event->type == blink::WebInputEvent::MouseWheel) {
616 guest_rvh->ForwardWheelEvent(
617 *static_cast<const blink::WebMouseWheelEvent*>(event));
618 return;
621 if (blink::WebInputEvent::isKeyboardEventType(event->type)) {
622 RenderViewHostImpl* embedder_rvh = static_cast<RenderViewHostImpl*>(
623 embedder_web_contents_->GetRenderViewHost());
624 if (!embedder_rvh->GetLastKeyboardEvent())
625 return;
626 NativeWebKeyboardEvent keyboard_event(
627 *embedder_rvh->GetLastKeyboardEvent());
628 guest_rvh->ForwardKeyboardEvent(keyboard_event);
629 return;
632 if (blink::WebInputEvent::isTouchEventType(event->type)) {
633 guest_rvh->ForwardTouchEventWithLatencyInfo(
634 *static_cast<const blink::WebTouchEvent*>(event),
635 ui::LatencyInfo());
636 return;
639 if (blink::WebInputEvent::isGestureEventType(event->type)) {
640 guest_rvh->ForwardGestureEvent(
641 *static_cast<const blink::WebGestureEvent*>(event));
642 return;
646 void BrowserPluginGuest::OnLockMouse(bool user_gesture,
647 bool last_unlocked_by_target,
648 bool privileged) {
649 if (pending_lock_request_) {
650 // Immediately reject the lock because only one pointerLock may be active
651 // at a time.
652 Send(new ViewMsg_LockMouse_ACK(routing_id(), false));
653 return;
656 pending_lock_request_ = true;
658 delegate_->RequestPointerLockPermission(
659 user_gesture,
660 last_unlocked_by_target,
661 base::Bind(&BrowserPluginGuest::PointerLockPermissionResponse,
662 weak_ptr_factory_.GetWeakPtr()));
665 void BrowserPluginGuest::OnLockMouseAck(int instance_id, bool succeeded) {
666 Send(new ViewMsg_LockMouse_ACK(routing_id(), succeeded));
667 pending_lock_request_ = false;
668 if (succeeded)
669 mouse_locked_ = true;
672 void BrowserPluginGuest::OnPluginDestroyed(int instance_id) {
673 Destroy();
676 void BrowserPluginGuest::OnResizeGuest(
677 int instance_id,
678 const BrowserPluginHostMsg_ResizeGuest_Params& params) {
679 if (!params.size_changed)
680 return;
681 // BrowserPlugin manages resize flow control itself and does not depend
682 // on RenderWidgetHost's mechanisms for flow control, so we reset those flags
683 // here. If we are setting the size for the first time before navigating then
684 // BrowserPluginGuest does not yet have a RenderViewHost.
685 if (GetWebContents()->GetRenderViewHost()) {
686 RenderWidgetHostImpl* render_widget_host =
687 RenderWidgetHostImpl::From(GetWebContents()->GetRenderViewHost());
688 render_widget_host->ResetSizeAndRepaintPendingFlags();
690 if (guest_device_scale_factor_ != params.scale_factor) {
691 guest_device_scale_factor_ = params.scale_factor;
692 render_widget_host->NotifyScreenInfoChanged();
695 // When autosize is turned off and as a result there is a layout change, we
696 // send a sizechanged event.
697 if (!auto_size_enabled_ && last_seen_auto_size_enabled_ &&
698 !params.view_size.IsEmpty()) {
699 delegate_->SizeChanged(last_seen_view_size_, params.view_size);
700 last_seen_auto_size_enabled_ = false;
702 // Just resize the WebContents and repaint if needed.
703 full_size_ = params.view_size;
704 if (!params.view_size.IsEmpty())
705 GetWebContents()->GetView()->SizeContents(params.view_size);
706 if (params.repaint)
707 Send(new ViewMsg_Repaint(routing_id(), params.view_size));
710 void BrowserPluginGuest::OnSetFocus(int instance_id, bool focused) {
711 focused_ = focused;
712 Send(new InputMsg_SetFocus(routing_id(), focused));
713 if (!focused && mouse_locked_)
714 OnUnlockMouse();
716 // Restore the last seen state of text input to the view.
717 RenderWidgetHostViewBase* rwhv = static_cast<RenderWidgetHostViewBase*>(
718 web_contents()->GetRenderWidgetHostView());
719 if (rwhv) {
720 ViewHostMsg_TextInputState_Params params;
721 params.type = last_text_input_type_;
722 params.mode = last_input_mode_;
723 params.can_compose_inline = last_can_compose_inline_;
724 rwhv->TextInputStateChanged(params);
728 void BrowserPluginGuest::OnSetAutoSize(
729 int instance_id,
730 const BrowserPluginHostMsg_AutoSize_Params& auto_size_params,
731 const BrowserPluginHostMsg_ResizeGuest_Params& resize_guest_params) {
732 bool old_auto_size_enabled = auto_size_enabled_;
733 gfx::Size old_max_size = max_auto_size_;
734 gfx::Size old_min_size = min_auto_size_;
735 auto_size_enabled_ = auto_size_params.enable;
736 max_auto_size_ = auto_size_params.max_size;
737 min_auto_size_ = auto_size_params.min_size;
738 if (auto_size_enabled_ && (!old_auto_size_enabled ||
739 (old_max_size != max_auto_size_) ||
740 (old_min_size != min_auto_size_))) {
741 RecordAction(
742 base::UserMetricsAction("BrowserPlugin.Guest.EnableAutoResize"));
743 GetWebContents()->GetRenderViewHost()->EnableAutoResize(
744 min_auto_size_, max_auto_size_);
745 // TODO(fsamuel): If we're changing autosize parameters, then we force
746 // the guest to completely repaint itself.
747 // Ideally, we shouldn't need to do this unless |max_auto_size_| has
748 // changed.
749 // However, even in that case, layout may not change and so we may
750 // not get a full frame worth of pixels.
751 Send(new ViewMsg_Repaint(routing_id(), max_auto_size_));
752 } else if (!auto_size_enabled_ && old_auto_size_enabled) {
753 GetWebContents()->GetRenderViewHost()->DisableAutoResize(
754 resize_guest_params.view_size);
756 OnResizeGuest(instance_id_, resize_guest_params);
759 void BrowserPluginGuest::OnSetEditCommandsForNextKeyEvent(
760 int instance_id,
761 const std::vector<EditCommand>& edit_commands) {
762 Send(new InputMsg_SetEditCommandsForNextKeyEvent(routing_id(),
763 edit_commands));
766 void BrowserPluginGuest::OnSetContentsOpaque(int instance_id, bool opaque) {
767 guest_opaque_ = opaque;
768 Send(new ViewMsg_SetBackgroundOpaque(routing_id(), guest_opaque_));
771 void BrowserPluginGuest::OnSetVisibility(int instance_id, bool visible) {
772 guest_visible_ = visible;
773 if (embedder_visible_ && guest_visible_)
774 GetWebContents()->WasShown();
775 else
776 GetWebContents()->WasHidden();
779 void BrowserPluginGuest::OnUnlockMouse() {
780 SendMessageToEmbedder(
781 new BrowserPluginMsg_SetMouseLock(instance_id(), false));
784 void BrowserPluginGuest::OnUnlockMouseAck(int instance_id) {
785 // mouse_locked_ could be false here if the lock attempt was cancelled due
786 // to window focus, or for various other reasons before the guest was informed
787 // of the lock's success.
788 if (mouse_locked_)
789 Send(new ViewMsg_MouseLockLost(routing_id()));
790 mouse_locked_ = false;
793 void BrowserPluginGuest::OnCopyFromCompositingSurfaceAck(
794 int instance_id,
795 int request_id,
796 const SkBitmap& bitmap) {
797 CHECK(copy_request_callbacks_.count(request_id));
798 if (!copy_request_callbacks_.count(request_id))
799 return;
800 const CopyRequestCallback& callback = copy_request_callbacks_[request_id];
801 callback.Run(!bitmap.empty() && !bitmap.isNull(), bitmap);
802 copy_request_callbacks_.erase(request_id);
805 void BrowserPluginGuest::OnUpdateGeometry(int instance_id,
806 const gfx::Rect& view_rect) {
807 // The plugin has moved within the embedder without resizing or the
808 // embedder/container's view rect changing.
809 guest_window_rect_ = view_rect;
810 RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>(
811 GetWebContents()->GetRenderViewHost());
812 if (rvh)
813 rvh->SendScreenRects();
816 void BrowserPluginGuest::OnHasTouchEventHandlers(bool accept) {
817 SendMessageToEmbedder(
818 new BrowserPluginMsg_ShouldAcceptTouchEvents(instance_id(), accept));
821 void BrowserPluginGuest::OnSetCursor(const WebCursor& cursor) {
822 SendMessageToEmbedder(new BrowserPluginMsg_SetCursor(instance_id(), cursor));
825 #if defined(OS_MACOSX)
826 void BrowserPluginGuest::OnShowPopup(
827 const ViewHostMsg_ShowPopup_Params& params) {
828 gfx::Rect translated_bounds(params.bounds);
829 translated_bounds.Offset(guest_window_rect_.OffsetFromOrigin());
830 BrowserPluginPopupMenuHelper popup_menu_helper(
831 embedder_web_contents_->GetRenderViewHost(),
832 GetWebContents()->GetRenderViewHost());
833 popup_menu_helper.ShowPopupMenu(translated_bounds,
834 params.item_height,
835 params.item_font_size,
836 params.selected_item,
837 params.popup_items,
838 params.right_aligned,
839 params.allow_multiple_selection);
841 #endif
843 void BrowserPluginGuest::OnShowWidget(int route_id,
844 const gfx::Rect& initial_pos) {
845 GetWebContents()->ShowCreatedWidget(route_id, initial_pos);
848 void BrowserPluginGuest::OnTakeFocus(bool reverse) {
849 SendMessageToEmbedder(
850 new BrowserPluginMsg_AdvanceFocus(instance_id(), reverse));
853 void BrowserPluginGuest::OnUpdateRect(
854 const ViewHostMsg_UpdateRect_Params& params) {
855 BrowserPluginMsg_UpdateRect_Params relay_params;
856 relay_params.view_size = params.view_size;
857 relay_params.scale_factor = params.scale_factor;
858 relay_params.is_resize_ack = ViewHostMsg_UpdateRect_Flags::is_resize_ack(
859 params.flags);
861 bool size_changed = last_seen_view_size_ != params.view_size;
862 gfx::Size old_size = last_seen_view_size_;
863 last_seen_view_size_ = params.view_size;
865 if ((auto_size_enabled_ || last_seen_auto_size_enabled_) &&
866 size_changed) {
867 delegate_->SizeChanged(old_size, last_seen_view_size_);
869 last_seen_auto_size_enabled_ = auto_size_enabled_;
871 SendMessageToEmbedder(
872 new BrowserPluginMsg_UpdateRect(instance_id(), relay_params));
875 void BrowserPluginGuest::OnTextInputStateChanged(
876 const ViewHostMsg_TextInputState_Params& params) {
877 // Save the state of text input so we can restore it on focus.
878 last_text_input_type_ = params.type;
879 last_input_mode_ = params.mode;
880 last_can_compose_inline_ = params.can_compose_inline;
882 static_cast<RenderWidgetHostViewBase*>(
883 web_contents()->GetRenderWidgetHostView())->TextInputStateChanged(params);
886 void BrowserPluginGuest::OnImeCancelComposition() {
887 static_cast<RenderWidgetHostViewBase*>(
888 web_contents()->GetRenderWidgetHostView())->ImeCancelComposition();
891 #if defined(OS_MACOSX) || defined(USE_AURA)
892 void BrowserPluginGuest::OnImeCompositionRangeChanged(
893 const gfx::Range& range,
894 const std::vector<gfx::Rect>& character_bounds) {
895 static_cast<RenderWidgetHostViewBase*>(
896 web_contents()->GetRenderWidgetHostView())->ImeCompositionRangeChanged(
897 range, character_bounds);
899 #endif
901 } // namespace content