Remove PlatformFile from profile_browsertest
[chromium-blink-merge.git] / content / browser / frame_host / render_widget_host_view_guest.cc
blob4501efab5d0cfd01511c2e1695eb8f25026edd97
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/view_messages.h"
16 #include "content/common/webplugin_geometry.h"
17 #include "content/public/common/content_switches.h"
18 #include "skia/ext/platform_canvas.h"
19 #include "third_party/WebKit/public/platform/WebScreenInfo.h"
21 #if defined(OS_MACOSX)
22 #import "content/browser/renderer_host/render_widget_host_view_mac_dictionary_helper.h"
23 #endif
25 #if defined(OS_WIN) || defined(USE_AURA)
26 #include "content/browser/renderer_host/ui_events_helper.h"
27 #endif
29 namespace content {
31 namespace {
33 #if defined(OS_WIN) || defined(USE_AURA)
34 blink::WebGestureEvent CreateFlingCancelEvent(double time_stamp) {
35 blink::WebGestureEvent gesture_event;
36 gesture_event.timeStampSeconds = time_stamp;
37 gesture_event.type = blink::WebGestureEvent::GestureFlingCancel;
38 gesture_event.sourceDevice = blink::WebGestureEvent::Touchscreen;
39 return gesture_event;
41 #endif // defined(OS_WIN) || defined(USE_AURA)
43 } // namespace
45 RenderWidgetHostViewGuest::RenderWidgetHostViewGuest(
46 RenderWidgetHost* widget_host,
47 BrowserPluginGuest* guest,
48 RenderWidgetHostView* platform_view)
49 : RenderWidgetHostViewChildFrame(widget_host),
50 // |guest| is NULL during test.
51 guest_(guest ? guest->AsWeakPtr() : base::WeakPtr<BrowserPluginGuest>()),
52 platform_view_(static_cast<RenderWidgetHostViewPort*>(platform_view)) {
53 #if defined(OS_WIN) || defined(USE_AURA)
54 gesture_recognizer_.reset(ui::GestureRecognizer::Create());
55 gesture_recognizer_->AddGestureEventHelper(this);
56 #endif // defined(OS_WIN) || defined(USE_AURA)
59 RenderWidgetHostViewGuest::~RenderWidgetHostViewGuest() {
60 #if defined(OS_WIN) || defined(USE_AURA)
61 gesture_recognizer_->RemoveGestureEventHelper(this);
62 #endif // defined(OS_WIN) || defined(USE_AURA)
65 void RenderWidgetHostViewGuest::WasShown() {
66 // If the WebContents associated with us showed an interstitial page in the
67 // beginning, the teardown path might call WasShown() while |host_| is in
68 // the process of destruction. Avoid calling WasShown below in this case.
69 // TODO(lazyboy): We shouldn't be showing interstitial pages in guests in the
70 // first place: http://crbug.com/273089.
72 // |guest_| is NULL during test.
73 if ((guest_ && guest_->is_in_destruction()) || !host_->is_hidden())
74 return;
75 host_->WasShown();
78 void RenderWidgetHostViewGuest::WasHidden() {
79 // |guest_| is NULL during test.
80 if ((guest_ && guest_->is_in_destruction()) || host_->is_hidden())
81 return;
82 host_->WasHidden();
85 void RenderWidgetHostViewGuest::SetSize(const gfx::Size& size) {
86 size_ = size;
87 host_->WasResized();
90 void RenderWidgetHostViewGuest::SetBounds(const gfx::Rect& rect) {
91 SetSize(rect.size());
94 #if defined(OS_WIN) || defined(USE_AURA)
95 void RenderWidgetHostViewGuest::ProcessAckedTouchEvent(
96 const TouchEventWithLatencyInfo& touch, InputEventAckState ack_result) {
97 // TODO(fsamuel): Currently we will only take this codepath if the guest has
98 // requested touch events. A better solution is to always forward touchpresses
99 // to the embedder process to target a BrowserPlugin, and then route all
100 // subsequent touch points of that touchdown to the appropriate guest until
101 // that touch point is released.
102 ScopedVector<ui::TouchEvent> events;
103 if (!MakeUITouchEventsFromWebTouchEvents(touch, &events, LOCAL_COORDINATES))
104 return;
106 ui::EventResult result = (ack_result ==
107 INPUT_EVENT_ACK_STATE_CONSUMED) ? ui::ER_HANDLED : ui::ER_UNHANDLED;
108 for (ScopedVector<ui::TouchEvent>::iterator iter = events.begin(),
109 end = events.end(); iter != end; ++iter) {
110 scoped_ptr<ui::GestureRecognizer::Gestures> gestures;
111 gestures.reset(gesture_recognizer_->ProcessTouchEventForGesture(
112 *(*iter), result, this));
113 ProcessGestures(gestures.get());
116 #endif
118 gfx::Rect RenderWidgetHostViewGuest::GetViewBounds() const {
119 if (!guest_)
120 return gfx::Rect();
122 RenderWidgetHostViewPort* rwhv = static_cast<RenderWidgetHostViewPort*>(
123 guest_->GetEmbedderRenderWidgetHostView());
124 gfx::Rect embedder_bounds;
125 if (rwhv)
126 embedder_bounds = rwhv->GetViewBounds();
127 gfx::Rect shifted_rect = guest_->ToGuestRect(embedder_bounds);
128 shifted_rect.set_width(size_.width());
129 shifted_rect.set_height(size_.height());
130 return shifted_rect;
133 void RenderWidgetHostViewGuest::RenderProcessGone(
134 base::TerminationStatus status,
135 int error_code) {
136 platform_view_->RenderProcessGone(status, error_code);
137 // Destroy the guest view instance only, so we don't end up calling
138 // platform_view_->Destroy().
139 DestroyGuestView();
142 void RenderWidgetHostViewGuest::Destroy() {
143 // The RenderWidgetHost's destruction led here, so don't call it.
144 DestroyGuestView();
146 platform_view_->Destroy();
149 gfx::Size RenderWidgetHostViewGuest::GetPhysicalBackingSize() const {
150 return RenderWidgetHostViewBase::GetPhysicalBackingSize();
153 base::string16 RenderWidgetHostViewGuest::GetSelectedText() const {
154 return platform_view_->GetSelectedText();
157 void RenderWidgetHostViewGuest::SetTooltipText(
158 const base::string16& tooltip_text) {
159 platform_view_->SetTooltipText(tooltip_text);
162 void RenderWidgetHostViewGuest::AcceleratedSurfaceBuffersSwapped(
163 const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params,
164 int gpu_host_id) {
165 if (!guest_)
166 return;
168 // If accelerated surface buffers are getting swapped then we're not using
169 // the software path.
170 guest_->clear_damage_buffer();
171 FrameMsg_BuffersSwapped_Params guest_params;
172 guest_params.size = params.size;
173 guest_params.mailbox = params.mailbox;
174 guest_params.gpu_route_id = params.route_id;
175 guest_params.gpu_host_id = gpu_host_id;
176 guest_->SendMessageToEmbedder(
177 new BrowserPluginMsg_BuffersSwapped(guest_->instance_id(),
178 guest_params));
181 void RenderWidgetHostViewGuest::AcceleratedSurfacePostSubBuffer(
182 const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params,
183 int gpu_host_id) {
184 NOTREACHED();
187 void RenderWidgetHostViewGuest::OnSwapCompositorFrame(
188 uint32 output_surface_id,
189 scoped_ptr<cc::CompositorFrame> frame) {
190 if (!guest_)
191 return;
193 guest_->clear_damage_buffer();
195 if (!guest_->attached()) {
196 // If the guest doesn't have an embedder then there's nothing to give the
197 // the frame to.
198 return;
200 if (frame->software_frame_data) {
201 cc::SoftwareFrameData* frame_data = frame->software_frame_data.get();
202 #ifdef OS_WIN
203 base::SharedMemory shared_memory(frame_data->handle, true,
204 host_->GetProcess()->GetHandle());
205 #else
206 base::SharedMemory shared_memory(frame_data->handle, true);
207 #endif
209 RenderWidgetHostView* embedder_rwhv =
210 guest_->GetEmbedderRenderWidgetHostView();
211 base::ProcessHandle embedder_pid =
212 embedder_rwhv->GetRenderWidgetHost()->GetProcess()->GetHandle();
214 shared_memory.GiveToProcess(embedder_pid, &frame_data->handle);
217 FrameMsg_CompositorFrameSwapped_Params guest_params;
218 frame->AssignTo(&guest_params.frame);
219 guest_params.output_surface_id = output_surface_id;
220 guest_params.producing_route_id = host_->GetRoutingID();
221 guest_params.producing_host_id = host_->GetProcess()->GetID();
223 guest_->SendMessageToEmbedder(
224 new BrowserPluginMsg_CompositorFrameSwapped(guest_->instance_id(),
225 guest_params));
228 bool RenderWidgetHostViewGuest::OnMessageReceived(const IPC::Message& msg) {
229 return platform_view_->OnMessageReceived(msg);
232 void RenderWidgetHostViewGuest::InitAsChild(
233 gfx::NativeView parent_view) {
234 platform_view_->InitAsChild(parent_view);
237 void RenderWidgetHostViewGuest::InitAsPopup(
238 RenderWidgetHostView* parent_host_view, const gfx::Rect& pos) {
239 // This should never get called.
240 NOTREACHED();
243 void RenderWidgetHostViewGuest::InitAsFullscreen(
244 RenderWidgetHostView* reference_host_view) {
245 // This should never get called.
246 NOTREACHED();
249 gfx::NativeView RenderWidgetHostViewGuest::GetNativeView() const {
250 if (!guest_)
251 return gfx::NativeView();
253 RenderWidgetHostView* rwhv = guest_->GetEmbedderRenderWidgetHostView();
254 if (!rwhv)
255 return gfx::NativeView();
256 return rwhv->GetNativeView();
259 gfx::NativeViewId RenderWidgetHostViewGuest::GetNativeViewId() const {
260 if (!guest_)
261 return static_cast<gfx::NativeViewId>(NULL);
263 RenderWidgetHostView* rwhv = guest_->GetEmbedderRenderWidgetHostView();
264 if (!rwhv)
265 return static_cast<gfx::NativeViewId>(NULL);
266 return rwhv->GetNativeViewId();
269 gfx::NativeViewAccessible RenderWidgetHostViewGuest::GetNativeViewAccessible() {
270 if (!guest_)
271 return gfx::NativeViewAccessible();
273 RenderWidgetHostView* rwhv = guest_->GetEmbedderRenderWidgetHostView();
274 if (!rwhv)
275 return gfx::NativeViewAccessible();
276 return rwhv->GetNativeViewAccessible();
279 void RenderWidgetHostViewGuest::MovePluginWindows(
280 const gfx::Vector2d& scroll_offset,
281 const std::vector<WebPluginGeometry>& moves) {
282 platform_view_->MovePluginWindows(scroll_offset, moves);
285 void RenderWidgetHostViewGuest::UpdateCursor(const WebCursor& cursor) {
286 platform_view_->UpdateCursor(cursor);
289 void RenderWidgetHostViewGuest::SetIsLoading(bool is_loading) {
290 platform_view_->SetIsLoading(is_loading);
293 void RenderWidgetHostViewGuest::TextInputTypeChanged(
294 ui::TextInputType type,
295 ui::TextInputMode input_mode,
296 bool can_compose_inline) {
297 if (!guest_)
298 return;
300 RenderWidgetHostViewPort* rwhv = RenderWidgetHostViewPort::FromRWHV(
301 guest_->GetEmbedderRenderWidgetHostView());
302 if (!rwhv)
303 return;
304 // Forward the information to embedding RWHV.
305 rwhv->TextInputTypeChanged(type, input_mode, can_compose_inline);
308 void RenderWidgetHostViewGuest::ImeCancelComposition() {
309 if (!guest_)
310 return;
312 RenderWidgetHostViewPort* rwhv = RenderWidgetHostViewPort::FromRWHV(
313 guest_->GetEmbedderRenderWidgetHostView());
314 if (!rwhv)
315 return;
316 // Forward the information to embedding RWHV.
317 rwhv->ImeCancelComposition();
320 #if defined(OS_MACOSX) || defined(OS_WIN) || defined(USE_AURA)
321 void RenderWidgetHostViewGuest::ImeCompositionRangeChanged(
322 const gfx::Range& range,
323 const std::vector<gfx::Rect>& character_bounds) {
324 if (!guest_)
325 return;
327 RenderWidgetHostViewPort* rwhv = RenderWidgetHostViewPort::FromRWHV(
328 guest_->GetEmbedderRenderWidgetHostView());
329 if (!rwhv)
330 return;
331 std::vector<gfx::Rect> guest_character_bounds;
332 for (size_t i = 0; i < character_bounds.size(); ++i) {
333 gfx::Rect guest_rect = guest_->ToGuestRect(character_bounds[i]);
334 guest_character_bounds.push_back(guest_rect);
336 // Forward the information to embedding RWHV.
337 rwhv->ImeCompositionRangeChanged(range, guest_character_bounds);
339 #endif
341 void RenderWidgetHostViewGuest::DidUpdateBackingStore(
342 const gfx::Rect& scroll_rect,
343 const gfx::Vector2d& scroll_delta,
344 const std::vector<gfx::Rect>& copy_rects,
345 const std::vector<ui::LatencyInfo>& latency_info) {
346 NOTREACHED();
349 void RenderWidgetHostViewGuest::SelectionChanged(const base::string16& text,
350 size_t offset,
351 const gfx::Range& range) {
352 platform_view_->SelectionChanged(text, offset, range);
355 void RenderWidgetHostViewGuest::SelectionBoundsChanged(
356 const ViewHostMsg_SelectionBounds_Params& params) {
357 if (!guest_)
358 return;
360 RenderWidgetHostViewPort* rwhv = RenderWidgetHostViewPort::FromRWHV(
361 guest_->GetEmbedderRenderWidgetHostView());
362 if (!rwhv)
363 return;
364 ViewHostMsg_SelectionBounds_Params guest_params(params);
365 guest_params.anchor_rect = guest_->ToGuestRect(params.anchor_rect);
366 guest_params.focus_rect = guest_->ToGuestRect(params.focus_rect);
367 rwhv->SelectionBoundsChanged(guest_params);
370 #if defined(OS_ANDROID)
371 void RenderWidgetHostViewGuest::SelectionRootBoundsChanged(
372 const gfx::Rect& bounds) {
373 if (!guest_)
374 return;
376 RenderWidgetHostViewPort* rwhv = RenderWidgetHostViewPort::FromRWHV(
377 guest_->GetEmbedderRenderWidgetHostView());
378 if (!rwhv)
379 return;
381 rwhv->SelectionRootBoundsChanged(guest_->ToGuestRect(bounds));
383 #endif
385 void RenderWidgetHostViewGuest::CopyFromCompositingSurface(
386 const gfx::Rect& src_subrect,
387 const gfx::Size& dst_size,
388 const base::Callback<void(bool, const SkBitmap&)>& callback,
389 const SkBitmap::Config config) {
390 CHECK(guest_);
391 guest_->CopyFromCompositingSurface(src_subrect, dst_size, callback);
394 void RenderWidgetHostViewGuest::SetBackground(const SkBitmap& background) {
395 platform_view_->SetBackground(background);
398 void RenderWidgetHostViewGuest::SetHasHorizontalScrollbar(
399 bool has_horizontal_scrollbar) {
400 platform_view_->SetHasHorizontalScrollbar(has_horizontal_scrollbar);
403 void RenderWidgetHostViewGuest::SetScrollOffsetPinning(
404 bool is_pinned_to_left, bool is_pinned_to_right) {
405 platform_view_->SetScrollOffsetPinning(
406 is_pinned_to_left, is_pinned_to_right);
409 bool RenderWidgetHostViewGuest::LockMouse() {
410 return platform_view_->LockMouse();
413 void RenderWidgetHostViewGuest::UnlockMouse() {
414 return platform_view_->UnlockMouse();
417 void RenderWidgetHostViewGuest::GetScreenInfo(blink::WebScreenInfo* results) {
418 if (!guest_)
419 return;
420 RenderWidgetHostViewPort* embedder_view =
421 RenderWidgetHostViewPort::FromRWHV(
422 guest_->GetEmbedderRenderWidgetHostView());
423 if (embedder_view)
424 embedder_view->GetScreenInfo(results);
427 #if defined(OS_MACOSX)
428 void RenderWidgetHostViewGuest::SetActive(bool active) {
429 platform_view_->SetActive(active);
432 void RenderWidgetHostViewGuest::SetTakesFocusOnlyOnMouseDown(bool flag) {
433 platform_view_->SetTakesFocusOnlyOnMouseDown(flag);
436 void RenderWidgetHostViewGuest::SetWindowVisibility(bool visible) {
437 platform_view_->SetWindowVisibility(visible);
440 void RenderWidgetHostViewGuest::WindowFrameChanged() {
441 platform_view_->WindowFrameChanged();
444 void RenderWidgetHostViewGuest::ShowDefinitionForSelection() {
445 if (!guest_)
446 return;
448 gfx::Point origin;
449 gfx::Rect guest_bounds = GetViewBounds();
450 RenderWidgetHostView* rwhv = guest_->GetEmbedderRenderWidgetHostView();
451 gfx::Rect embedder_bounds;
452 if (rwhv)
453 embedder_bounds = rwhv->GetViewBounds();
455 gfx::Vector2d guest_offset = gfx::Vector2d(
456 // Horizontal offset of guest from embedder.
457 guest_bounds.x() - embedder_bounds.x(),
458 // Vertical offset from guest's top to embedder's bottom edge.
459 embedder_bounds.bottom() - guest_bounds.y());
461 RenderWidgetHostViewMacDictionaryHelper helper(platform_view_);
462 helper.SetTargetView(rwhv);
463 helper.set_offset(guest_offset);
464 helper.ShowDefinitionForSelection();
467 bool RenderWidgetHostViewGuest::SupportsSpeech() const {
468 return platform_view_->SupportsSpeech();
471 void RenderWidgetHostViewGuest::SpeakSelection() {
472 platform_view_->SpeakSelection();
475 bool RenderWidgetHostViewGuest::IsSpeaking() const {
476 return platform_view_->IsSpeaking();
479 void RenderWidgetHostViewGuest::StopSpeaking() {
480 platform_view_->StopSpeaking();
483 bool RenderWidgetHostViewGuest::PostProcessEventForPluginIme(
484 const NativeWebKeyboardEvent& event) {
485 return false;
488 #endif // defined(OS_MACOSX)
490 #if defined(OS_ANDROID)
491 void RenderWidgetHostViewGuest::ShowDisambiguationPopup(
492 const gfx::Rect& target_rect,
493 const SkBitmap& zoomed_bitmap) {
495 #endif // defined(OS_ANDROID)
497 #if defined(TOOLKIT_GTK)
498 GdkEventButton* RenderWidgetHostViewGuest::GetLastMouseDown() {
499 return NULL;
502 gfx::NativeView RenderWidgetHostViewGuest::BuildInputMethodsGtkMenu() {
503 return platform_view_->BuildInputMethodsGtkMenu();
505 #endif // defined(TOOLKIT_GTK)
507 #if defined(OS_WIN)
508 void RenderWidgetHostViewGuest::SetParentNativeViewAccessible(
509 gfx::NativeViewAccessible accessible_parent) {
512 gfx::NativeViewId RenderWidgetHostViewGuest::GetParentForWindowlessPlugin()
513 const {
514 return NULL;
516 #endif
518 void RenderWidgetHostViewGuest::DestroyGuestView() {
519 host_->SetView(NULL);
520 host_ = NULL;
521 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
524 bool RenderWidgetHostViewGuest::CanDispatchToConsumer(
525 ui::GestureConsumer* consumer) {
526 CHECK_EQ(static_cast<RenderWidgetHostViewGuest*>(consumer), this);
527 return true;
530 void RenderWidgetHostViewGuest::DispatchPostponedGestureEvent(
531 ui::GestureEvent* event) {
532 ForwardGestureEventToRenderer(event);
535 void RenderWidgetHostViewGuest::DispatchCancelTouchEvent(
536 ui::TouchEvent* event) {
537 if (!host_)
538 return;
540 blink::WebTouchEvent cancel_event;
541 cancel_event.type = blink::WebInputEvent::TouchCancel;
542 cancel_event.timeStampSeconds = event->time_stamp().InSecondsF();
543 host_->ForwardTouchEventWithLatencyInfo(cancel_event, *event->latency());
546 bool RenderWidgetHostViewGuest::ForwardGestureEventToRenderer(
547 ui::GestureEvent* gesture) {
548 #if defined(OS_WIN) || defined(USE_AURA)
549 if (!host_)
550 return false;
552 if ((gesture->type() == ui::ET_GESTURE_PINCH_BEGIN ||
553 gesture->type() == ui::ET_GESTURE_PINCH_UPDATE ||
554 gesture->type() == ui::ET_GESTURE_PINCH_END) && !pinch_zoom_enabled_) {
555 return true;
558 blink::WebGestureEvent web_gesture =
559 MakeWebGestureEventFromUIEvent(*gesture);
560 const gfx::Point& client_point = gesture->location();
561 const gfx::Point& screen_point = gesture->location();
563 web_gesture.x = client_point.x();
564 web_gesture.y = client_point.y();
565 web_gesture.globalX = screen_point.x();
566 web_gesture.globalY = screen_point.y();
568 if (web_gesture.type == blink::WebGestureEvent::Undefined)
569 return false;
570 if (web_gesture.type == blink::WebGestureEvent::GestureTapDown) {
571 host_->ForwardGestureEvent(
572 CreateFlingCancelEvent(gesture->time_stamp().InSecondsF()));
574 host_->ForwardGestureEvent(web_gesture);
575 return true;
576 #else
577 return false;
578 #endif
581 void RenderWidgetHostViewGuest::ProcessGestures(
582 ui::GestureRecognizer::Gestures* gestures) {
583 if ((gestures == NULL) || gestures->empty())
584 return;
585 for (ui::GestureRecognizer::Gestures::iterator g_it = gestures->begin();
586 g_it != gestures->end();
587 ++g_it) {
588 ForwardGestureEventToRenderer(*g_it);
592 SkBitmap::Config RenderWidgetHostViewGuest::PreferredReadbackFormat() {
593 return SkBitmap::kARGB_8888_Config;
596 } // namespace content