Cast: Stop logging kVideoFrameSentToEncoder and rename a couple events.
[chromium-blink-merge.git] / content / browser / frame_host / render_widget_host_view_guest.cc
blob6742aed149a2f97716e25caf4b30d35e48e966ac
1 // Copyright 2014 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 "base/bind_helpers.h"
6 #include "base/command_line.h"
7 #include "base/logging.h"
8 #include "base/message_loop/message_loop.h"
9 #include "content/browser/browser_plugin/browser_plugin_guest.h"
10 #include "content/browser/frame_host/render_widget_host_view_guest.h"
11 #include "content/browser/renderer_host/render_view_host_impl.h"
12 #include "content/common/browser_plugin/browser_plugin_messages.h"
13 #include "content/common/frame_messages.h"
14 #include "content/common/gpu/gpu_messages.h"
15 #include "content/common/host_shared_bitmap_manager.h"
16 #include "content/common/input/web_touch_event_traits.h"
17 #include "content/common/view_messages.h"
18 #include "content/common/webplugin_geometry.h"
19 #include "content/public/common/content_switches.h"
20 #include "skia/ext/platform_canvas.h"
21 #include "third_party/WebKit/public/platform/WebScreenInfo.h"
23 #if defined(OS_MACOSX)
24 #import "content/browser/renderer_host/render_widget_host_view_mac_dictionary_helper.h"
25 #endif
27 #if defined(USE_AURA)
28 #include "content/browser/renderer_host/ui_events_helper.h"
29 #endif
31 namespace content {
33 namespace {
35 #if defined(USE_AURA)
36 blink::WebGestureEvent CreateFlingCancelEvent(double time_stamp) {
37 blink::WebGestureEvent gesture_event;
38 gesture_event.timeStampSeconds = time_stamp;
39 gesture_event.type = blink::WebGestureEvent::GestureFlingCancel;
40 gesture_event.sourceDevice = blink::WebGestureEvent::Touchscreen;
41 return gesture_event;
43 #endif // defined(USE_AURA)
45 } // namespace
47 RenderWidgetHostViewGuest::RenderWidgetHostViewGuest(
48 RenderWidgetHost* widget_host,
49 BrowserPluginGuest* guest,
50 RenderWidgetHostViewBase* platform_view)
51 : RenderWidgetHostViewChildFrame(widget_host),
52 // |guest| is NULL during test.
53 guest_(guest ? guest->AsWeakPtr() : base::WeakPtr<BrowserPluginGuest>()),
54 platform_view_(platform_view) {
55 #if defined(USE_AURA)
56 gesture_recognizer_.reset(ui::GestureRecognizer::Create());
57 gesture_recognizer_->AddGestureEventHelper(this);
58 #endif // defined(USE_AURA)
61 RenderWidgetHostViewGuest::~RenderWidgetHostViewGuest() {
62 #if defined(USE_AURA)
63 gesture_recognizer_->RemoveGestureEventHelper(this);
64 #endif // defined(USE_AURA)
67 void RenderWidgetHostViewGuest::WasShown() {
68 // If the WebContents associated with us showed an interstitial page in the
69 // beginning, the teardown path might call WasShown() while |host_| is in
70 // the process of destruction. Avoid calling WasShown below in this case.
71 // TODO(lazyboy): We shouldn't be showing interstitial pages in guests in the
72 // first place: http://crbug.com/273089.
74 // |guest_| is NULL during test.
75 if ((guest_ && guest_->is_in_destruction()) || !host_->is_hidden())
76 return;
77 host_->WasShown();
80 void RenderWidgetHostViewGuest::WasHidden() {
81 // |guest_| is NULL during test.
82 if ((guest_ && guest_->is_in_destruction()) || host_->is_hidden())
83 return;
84 host_->WasHidden();
87 void RenderWidgetHostViewGuest::SetSize(const gfx::Size& size) {
88 size_ = size;
89 host_->WasResized();
92 void RenderWidgetHostViewGuest::SetBounds(const gfx::Rect& rect) {
93 SetSize(rect.size());
96 #if defined(USE_AURA)
97 void RenderWidgetHostViewGuest::ProcessAckedTouchEvent(
98 const TouchEventWithLatencyInfo& touch, InputEventAckState ack_result) {
99 // TODO(fsamuel): Currently we will only take this codepath if the guest has
100 // requested touch events. A better solution is to always forward touchpresses
101 // to the embedder process to target a BrowserPlugin, and then route all
102 // subsequent touch points of that touchdown to the appropriate guest until
103 // that touch point is released.
104 ScopedVector<ui::TouchEvent> events;
105 if (!MakeUITouchEventsFromWebTouchEvents(touch, &events, LOCAL_COORDINATES))
106 return;
108 ui::EventResult result = (ack_result ==
109 INPUT_EVENT_ACK_STATE_CONSUMED) ? ui::ER_HANDLED : ui::ER_UNHANDLED;
110 for (ScopedVector<ui::TouchEvent>::iterator iter = events.begin(),
111 end = events.end(); iter != end; ++iter) {
112 scoped_ptr<ui::GestureRecognizer::Gestures> gestures;
113 gestures.reset(gesture_recognizer_->ProcessTouchEventForGesture(
114 *(*iter), result, this));
115 ProcessGestures(gestures.get());
118 #endif
120 gfx::Rect RenderWidgetHostViewGuest::GetViewBounds() const {
121 if (!guest_)
122 return gfx::Rect();
124 RenderWidgetHostViewBase* rwhv = GetGuestRenderWidgetHostView();
125 gfx::Rect embedder_bounds;
126 if (rwhv)
127 embedder_bounds = rwhv->GetViewBounds();
128 gfx::Rect shifted_rect = guest_->ToGuestRect(embedder_bounds);
129 shifted_rect.set_width(size_.width());
130 shifted_rect.set_height(size_.height());
131 return shifted_rect;
134 void RenderWidgetHostViewGuest::RenderProcessGone(
135 base::TerminationStatus status,
136 int error_code) {
137 platform_view_->RenderProcessGone(status, error_code);
138 // Destroy the guest view instance only, so we don't end up calling
139 // platform_view_->Destroy().
140 DestroyGuestView();
143 void RenderWidgetHostViewGuest::Destroy() {
144 // The RenderWidgetHost's destruction led here, so don't call it.
145 DestroyGuestView();
147 platform_view_->Destroy();
150 gfx::Size RenderWidgetHostViewGuest::GetPhysicalBackingSize() const {
151 return RenderWidgetHostViewBase::GetPhysicalBackingSize();
154 base::string16 RenderWidgetHostViewGuest::GetSelectedText() const {
155 return platform_view_->GetSelectedText();
158 void RenderWidgetHostViewGuest::SetTooltipText(
159 const base::string16& tooltip_text) {
160 platform_view_->SetTooltipText(tooltip_text);
163 void RenderWidgetHostViewGuest::AcceleratedSurfaceBuffersSwapped(
164 const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params,
165 int gpu_host_id) {
166 if (!guest_)
167 return;
169 FrameMsg_BuffersSwapped_Params guest_params;
170 guest_params.size = params.size;
171 guest_params.mailbox = params.mailbox;
172 guest_params.gpu_route_id = params.route_id;
173 guest_params.gpu_host_id = gpu_host_id;
174 guest_->SendMessageToEmbedder(
175 new BrowserPluginMsg_BuffersSwapped(guest_->instance_id(),
176 guest_params));
179 void RenderWidgetHostViewGuest::AcceleratedSurfacePostSubBuffer(
180 const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params,
181 int gpu_host_id) {
182 NOTREACHED();
185 void RenderWidgetHostViewGuest::OnSwapCompositorFrame(
186 uint32 output_surface_id,
187 scoped_ptr<cc::CompositorFrame> frame) {
188 if (!guest_)
189 return;
191 if (!guest_->attached()) {
192 // If the guest doesn't have an embedder then there's nothing to give the
193 // the frame to.
194 return;
196 base::SharedMemoryHandle software_frame_handle =
197 base::SharedMemory::NULLHandle();
198 if (frame->software_frame_data) {
199 cc::SoftwareFrameData* frame_data = frame->software_frame_data.get();
200 scoped_ptr<cc::SharedBitmap> bitmap =
201 HostSharedBitmapManager::current()->GetSharedBitmapFromId(
202 frame_data->size, frame_data->bitmap_id);
203 if (!bitmap)
204 return;
206 RenderWidgetHostView* embedder_rwhv =
207 guest_->GetEmbedderRenderWidgetHostView();
208 base::ProcessHandle embedder_pid =
209 embedder_rwhv->GetRenderWidgetHost()->GetProcess()->GetHandle();
211 bitmap->memory()->ShareToProcess(embedder_pid, &software_frame_handle);
214 FrameMsg_CompositorFrameSwapped_Params guest_params;
215 frame->AssignTo(&guest_params.frame);
216 guest_params.output_surface_id = output_surface_id;
217 guest_params.producing_route_id = host_->GetRoutingID();
218 guest_params.producing_host_id = host_->GetProcess()->GetID();
219 guest_params.shared_memory_handle = software_frame_handle;
221 guest_->SendMessageToEmbedder(
222 new BrowserPluginMsg_CompositorFrameSwapped(guest_->instance_id(),
223 guest_params));
226 bool RenderWidgetHostViewGuest::OnMessageReceived(const IPC::Message& msg) {
227 return platform_view_->OnMessageReceived(msg);
230 void RenderWidgetHostViewGuest::InitAsChild(
231 gfx::NativeView parent_view) {
232 platform_view_->InitAsChild(parent_view);
235 void RenderWidgetHostViewGuest::InitAsPopup(
236 RenderWidgetHostView* parent_host_view, const gfx::Rect& pos) {
237 // This should never get called.
238 NOTREACHED();
241 void RenderWidgetHostViewGuest::InitAsFullscreen(
242 RenderWidgetHostView* reference_host_view) {
243 // This should never get called.
244 NOTREACHED();
247 gfx::NativeView RenderWidgetHostViewGuest::GetNativeView() const {
248 if (!guest_)
249 return gfx::NativeView();
251 RenderWidgetHostView* rwhv = guest_->GetEmbedderRenderWidgetHostView();
252 if (!rwhv)
253 return gfx::NativeView();
254 return rwhv->GetNativeView();
257 gfx::NativeViewId RenderWidgetHostViewGuest::GetNativeViewId() const {
258 if (!guest_)
259 return static_cast<gfx::NativeViewId>(NULL);
261 RenderWidgetHostView* rwhv = guest_->GetEmbedderRenderWidgetHostView();
262 if (!rwhv)
263 return static_cast<gfx::NativeViewId>(NULL);
264 return rwhv->GetNativeViewId();
267 gfx::NativeViewAccessible RenderWidgetHostViewGuest::GetNativeViewAccessible() {
268 if (!guest_)
269 return gfx::NativeViewAccessible();
271 RenderWidgetHostView* rwhv = guest_->GetEmbedderRenderWidgetHostView();
272 if (!rwhv)
273 return gfx::NativeViewAccessible();
274 return rwhv->GetNativeViewAccessible();
277 void RenderWidgetHostViewGuest::MovePluginWindows(
278 const std::vector<WebPluginGeometry>& moves) {
279 platform_view_->MovePluginWindows(moves);
282 void RenderWidgetHostViewGuest::UpdateCursor(const WebCursor& cursor) {
283 platform_view_->UpdateCursor(cursor);
286 void RenderWidgetHostViewGuest::SetIsLoading(bool is_loading) {
287 platform_view_->SetIsLoading(is_loading);
290 void RenderWidgetHostViewGuest::TextInputTypeChanged(
291 ui::TextInputType type,
292 ui::TextInputMode input_mode,
293 bool can_compose_inline) {
294 if (!guest_)
295 return;
297 RenderWidgetHostViewBase* rwhv = GetGuestRenderWidgetHostView();
298 if (!rwhv)
299 return;
300 // Forward the information to embedding RWHV.
301 rwhv->TextInputTypeChanged(type, input_mode, can_compose_inline);
304 void RenderWidgetHostViewGuest::ImeCancelComposition() {
305 if (!guest_)
306 return;
308 RenderWidgetHostViewBase* rwhv = GetGuestRenderWidgetHostView();
309 if (!rwhv)
310 return;
311 // Forward the information to embedding RWHV.
312 rwhv->ImeCancelComposition();
315 #if defined(OS_MACOSX) || defined(USE_AURA)
316 void RenderWidgetHostViewGuest::ImeCompositionRangeChanged(
317 const gfx::Range& range,
318 const std::vector<gfx::Rect>& character_bounds) {
319 if (!guest_)
320 return;
322 RenderWidgetHostViewBase* rwhv = GetGuestRenderWidgetHostView();
323 if (!rwhv)
324 return;
325 std::vector<gfx::Rect> guest_character_bounds;
326 for (size_t i = 0; i < character_bounds.size(); ++i) {
327 gfx::Rect guest_rect = guest_->ToGuestRect(character_bounds[i]);
328 guest_character_bounds.push_back(guest_rect);
330 // Forward the information to embedding RWHV.
331 rwhv->ImeCompositionRangeChanged(range, guest_character_bounds);
333 #endif
335 void RenderWidgetHostViewGuest::SelectionChanged(const base::string16& text,
336 size_t offset,
337 const gfx::Range& range) {
338 platform_view_->SelectionChanged(text, offset, range);
341 void RenderWidgetHostViewGuest::SelectionBoundsChanged(
342 const ViewHostMsg_SelectionBounds_Params& params) {
343 if (!guest_)
344 return;
346 RenderWidgetHostViewBase* rwhv = GetGuestRenderWidgetHostView();
347 if (!rwhv)
348 return;
349 ViewHostMsg_SelectionBounds_Params guest_params(params);
350 guest_params.anchor_rect = guest_->ToGuestRect(params.anchor_rect);
351 guest_params.focus_rect = guest_->ToGuestRect(params.focus_rect);
352 rwhv->SelectionBoundsChanged(guest_params);
355 #if defined(OS_ANDROID)
356 void RenderWidgetHostViewGuest::SelectionRootBoundsChanged(
357 const gfx::Rect& bounds) {
358 if (!guest_)
359 return;
361 RenderWidgetHostViewBase* rwhv = GetGuestRenderWidgetHostView();
362 if (!rwhv)
363 return;
365 rwhv->SelectionRootBoundsChanged(guest_->ToGuestRect(bounds));
367 #endif
369 void RenderWidgetHostViewGuest::CopyFromCompositingSurface(
370 const gfx::Rect& src_subrect,
371 const gfx::Size& dst_size,
372 const base::Callback<void(bool, const SkBitmap&)>& callback,
373 const SkBitmap::Config config) {
374 CHECK(guest_);
375 guest_->CopyFromCompositingSurface(src_subrect, dst_size, callback);
378 void RenderWidgetHostViewGuest::SetBackground(const SkBitmap& background) {
379 platform_view_->SetBackground(background);
382 void RenderWidgetHostViewGuest::SetScrollOffsetPinning(
383 bool is_pinned_to_left, bool is_pinned_to_right) {
384 platform_view_->SetScrollOffsetPinning(
385 is_pinned_to_left, is_pinned_to_right);
388 bool RenderWidgetHostViewGuest::LockMouse() {
389 return platform_view_->LockMouse();
392 void RenderWidgetHostViewGuest::UnlockMouse() {
393 return platform_view_->UnlockMouse();
396 void RenderWidgetHostViewGuest::GetScreenInfo(blink::WebScreenInfo* results) {
397 if (!guest_)
398 return;
399 RenderWidgetHostViewBase* embedder_view = GetGuestRenderWidgetHostView();
400 if (embedder_view)
401 embedder_view->GetScreenInfo(results);
404 #if defined(OS_MACOSX)
405 void RenderWidgetHostViewGuest::SetActive(bool active) {
406 platform_view_->SetActive(active);
409 void RenderWidgetHostViewGuest::SetTakesFocusOnlyOnMouseDown(bool flag) {
410 platform_view_->SetTakesFocusOnlyOnMouseDown(flag);
413 void RenderWidgetHostViewGuest::SetWindowVisibility(bool visible) {
414 platform_view_->SetWindowVisibility(visible);
417 void RenderWidgetHostViewGuest::WindowFrameChanged() {
418 platform_view_->WindowFrameChanged();
421 void RenderWidgetHostViewGuest::ShowDefinitionForSelection() {
422 if (!guest_)
423 return;
425 gfx::Point origin;
426 gfx::Rect guest_bounds = GetViewBounds();
427 RenderWidgetHostView* rwhv = guest_->GetEmbedderRenderWidgetHostView();
428 gfx::Rect embedder_bounds;
429 if (rwhv)
430 embedder_bounds = rwhv->GetViewBounds();
432 gfx::Vector2d guest_offset = gfx::Vector2d(
433 // Horizontal offset of guest from embedder.
434 guest_bounds.x() - embedder_bounds.x(),
435 // Vertical offset from guest's top to embedder's bottom edge.
436 embedder_bounds.bottom() - guest_bounds.y());
438 RenderWidgetHostViewMacDictionaryHelper helper(platform_view_);
439 helper.SetTargetView(rwhv);
440 helper.set_offset(guest_offset);
441 helper.ShowDefinitionForSelection();
444 bool RenderWidgetHostViewGuest::SupportsSpeech() const {
445 return platform_view_->SupportsSpeech();
448 void RenderWidgetHostViewGuest::SpeakSelection() {
449 platform_view_->SpeakSelection();
452 bool RenderWidgetHostViewGuest::IsSpeaking() const {
453 return platform_view_->IsSpeaking();
456 void RenderWidgetHostViewGuest::StopSpeaking() {
457 platform_view_->StopSpeaking();
460 bool RenderWidgetHostViewGuest::PostProcessEventForPluginIme(
461 const NativeWebKeyboardEvent& event) {
462 return false;
465 #endif // defined(OS_MACOSX)
467 #if defined(OS_ANDROID)
468 void RenderWidgetHostViewGuest::ShowDisambiguationPopup(
469 const gfx::Rect& target_rect,
470 const SkBitmap& zoomed_bitmap) {
473 void RenderWidgetHostViewGuest::LockCompositingSurface() {
476 void RenderWidgetHostViewGuest::UnlockCompositingSurface() {
478 #endif // defined(OS_ANDROID)
480 #if defined(OS_WIN)
481 void RenderWidgetHostViewGuest::SetParentNativeViewAccessible(
482 gfx::NativeViewAccessible accessible_parent) {
485 gfx::NativeViewId RenderWidgetHostViewGuest::GetParentForWindowlessPlugin()
486 const {
487 return NULL;
489 #endif
491 void RenderWidgetHostViewGuest::DestroyGuestView() {
492 host_->SetView(NULL);
493 host_ = NULL;
494 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
497 bool RenderWidgetHostViewGuest::CanDispatchToConsumer(
498 ui::GestureConsumer* consumer) {
499 CHECK_EQ(static_cast<RenderWidgetHostViewGuest*>(consumer), this);
500 return true;
503 void RenderWidgetHostViewGuest::DispatchPostponedGestureEvent(
504 ui::GestureEvent* event) {
505 ForwardGestureEventToRenderer(event);
508 void RenderWidgetHostViewGuest::DispatchCancelTouchEvent(
509 ui::TouchEvent* event) {
510 if (!host_)
511 return;
513 blink::WebTouchEvent cancel_event;
514 // TODO(rbyers): This event has no touches in it. Don't we need to know what
515 // touches are currently active in order to cancel them all properly?
516 WebTouchEventTraits::ResetType(blink::WebInputEvent::TouchCancel,
517 event->time_stamp().InSecondsF(),
518 &cancel_event);
520 host_->ForwardTouchEventWithLatencyInfo(cancel_event, *event->latency());
523 bool RenderWidgetHostViewGuest::ForwardGestureEventToRenderer(
524 ui::GestureEvent* gesture) {
525 #if defined(USE_AURA)
526 if (!host_)
527 return false;
529 if ((gesture->type() == ui::ET_GESTURE_PINCH_BEGIN ||
530 gesture->type() == ui::ET_GESTURE_PINCH_UPDATE ||
531 gesture->type() == ui::ET_GESTURE_PINCH_END) && !pinch_zoom_enabled_) {
532 return true;
535 blink::WebGestureEvent web_gesture =
536 MakeWebGestureEventFromUIEvent(*gesture);
537 const gfx::Point& client_point = gesture->location();
538 const gfx::Point& screen_point = gesture->location();
540 web_gesture.x = client_point.x();
541 web_gesture.y = client_point.y();
542 web_gesture.globalX = screen_point.x();
543 web_gesture.globalY = screen_point.y();
545 if (web_gesture.type == blink::WebGestureEvent::Undefined)
546 return false;
547 if (web_gesture.type == blink::WebGestureEvent::GestureTapDown) {
548 host_->ForwardGestureEvent(
549 CreateFlingCancelEvent(gesture->time_stamp().InSecondsF()));
551 host_->ForwardGestureEvent(web_gesture);
552 return true;
553 #else
554 return false;
555 #endif
558 void RenderWidgetHostViewGuest::ProcessGestures(
559 ui::GestureRecognizer::Gestures* gestures) {
560 if ((gestures == NULL) || gestures->empty())
561 return;
562 for (ui::GestureRecognizer::Gestures::iterator g_it = gestures->begin();
563 g_it != gestures->end();
564 ++g_it) {
565 ForwardGestureEventToRenderer(*g_it);
569 SkBitmap::Config RenderWidgetHostViewGuest::PreferredReadbackFormat() {
570 return SkBitmap::kARGB_8888_Config;
573 RenderWidgetHostViewBase*
574 RenderWidgetHostViewGuest::GetGuestRenderWidgetHostView() const {
575 return static_cast<RenderWidgetHostViewBase*>(
576 guest_->GetEmbedderRenderWidgetHostView());
579 } // namespace content