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.
4 
5 #include "content/browser/renderer_host/render_widget_host_view_base.h"
6 
7 #include "base/bind.h"
8 #include "base/logging.h"
9 #include "base/unguessable_token.h"
10 #include "build/build_config.h"
11 #include "components/viz/common/features.h"
12 #include "components/viz/host/host_frame_sink_manager.h"
13 #include "content/browser/compositor/surface_utils.h"
14 #include "content/browser/gpu/gpu_data_manager_impl.h"
15 #include "content/browser/renderer_host/delegated_frame_host.h"
16 #include "content/browser/renderer_host/display_util.h"
17 #include "content/browser/renderer_host/event_with_latency_info.h"
18 #include "content/browser/renderer_host/input/mouse_wheel_phase_handler.h"
19 #include "content/browser/renderer_host/input/synthetic_gesture_target_base.h"
20 #include "content/browser/renderer_host/render_process_host_impl.h"
21 #include "content/browser/renderer_host/render_widget_host_delegate.h"
22 #include "content/browser/renderer_host/render_widget_host_impl.h"
23 #include "content/browser/renderer_host/render_widget_host_input_event_router.h"
24 #include "content/browser/renderer_host/render_widget_host_owner_delegate.h"
25 #include "content/browser/renderer_host/render_widget_host_view_base_observer.h"
26 #include "content/browser/renderer_host/render_widget_host_view_child_frame.h"
27 #include "content/browser/renderer_host/text_input_manager.h"
28 #include "content/common/content_switches_internal.h"
29 #include "third_party/blink/public/mojom/page/record_content_to_visible_time_request.mojom.h"
30 #include "ui/base/layout.h"
31 #include "ui/base/ui_base_types.h"
32 #include "ui/display/screen.h"
33 #include "ui/events/event.h"
34 #include "ui/events/keycodes/dom/dom_code.h"
35 #include "ui/gfx/geometry/dip_util.h"
36 #include "ui/gfx/geometry/point_conversions.h"
37 #include "ui/gfx/geometry/size_conversions.h"
38 #include "ui/gfx/geometry/size_f.h"
39 
40 namespace content {
41 
RenderWidgetHostViewBase(RenderWidgetHost * host)42 RenderWidgetHostViewBase::RenderWidgetHostViewBase(RenderWidgetHost* host)
43     : host_(RenderWidgetHostImpl::From(host)) {
44 }
45 
~RenderWidgetHostViewBase()46 RenderWidgetHostViewBase::~RenderWidgetHostViewBase() {
47   DCHECK(!keyboard_locked_);
48   DCHECK(!IsMouseLocked());
49   // We call this here to guarantee that observers are notified before we go
50   // away. However, some subclasses may wish to call this earlier in their
51   // shutdown process, e.g. to force removal from
52   // RenderWidgetHostInputEventRouter's surface map before relinquishing a
53   // host pointer. There is no harm in calling NotifyObserversAboutShutdown()
54   // twice, as the observers are required to de-register on the first call, and
55   // so the second call does nothing.
56   NotifyObserversAboutShutdown();
57   // If we have a live reference to |text_input_manager_|, we should unregister
58   // so that the |text_input_manager_| will free its state.
59   if (text_input_manager_)
60     text_input_manager_->Unregister(this);
61 }
62 
GetFocusedWidget() const63 RenderWidgetHostImpl* RenderWidgetHostViewBase::GetFocusedWidget() const {
64   return host() && host()->delegate()
65              ? host()->delegate()->GetFocusedRenderWidgetHost(host())
66              : nullptr;
67 }
68 
GetRenderWidgetHost()69 RenderWidgetHost* RenderWidgetHostViewBase::GetRenderWidgetHost() {
70   return host();
71 }
72 
SetContentBackgroundColor(SkColor color)73 void RenderWidgetHostViewBase::SetContentBackgroundColor(SkColor color) {
74   if (content_background_color_ == color)
75     return;
76 
77   content_background_color_ = color;
78   UpdateBackgroundColor();
79 }
80 
NotifyObserversAboutShutdown()81 void RenderWidgetHostViewBase::NotifyObserversAboutShutdown() {
82   // Note: RenderWidgetHostInputEventRouter is an observer, and uses the
83   // following notification to remove this view from its surface owners map.
84   for (auto& observer : observers_)
85     observer.OnRenderWidgetHostViewBaseDestroyed(this);
86   // All observers are required to disconnect after they are notified.
87   DCHECK(!observers_.might_have_observers());
88 }
89 
GetMouseWheelPhaseHandler()90 MouseWheelPhaseHandler* RenderWidgetHostViewBase::GetMouseWheelPhaseHandler() {
91   return nullptr;
92 }
93 
StopFlingingIfNecessary(const blink::WebGestureEvent & event,blink::mojom::InputEventResultState ack_result)94 void RenderWidgetHostViewBase::StopFlingingIfNecessary(
95     const blink::WebGestureEvent& event,
96     blink::mojom::InputEventResultState ack_result) {
97   // Reset view_stopped_flinging_for_test_ at the beginning of the scroll
98   // sequence.
99   if (event.GetType() == blink::WebInputEvent::Type::kGestureScrollBegin)
100     view_stopped_flinging_for_test_ = false;
101 
102   bool processed = blink::mojom::InputEventResultState::kConsumed == ack_result;
103   if (!processed &&
104       event.GetType() == blink::WebInputEvent::Type::kGestureScrollUpdate &&
105       event.data.scroll_update.inertial_phase ==
106           blink::WebGestureEvent::InertialPhaseState::kMomentum &&
107       event.SourceDevice() != blink::WebGestureDevice::kSyntheticAutoscroll) {
108     StopFling();
109     view_stopped_flinging_for_test_ = true;
110   }
111 }
112 
UpdateIntrinsicSizingInfo(blink::mojom::IntrinsicSizingInfoPtr sizing_info)113 void RenderWidgetHostViewBase::UpdateIntrinsicSizingInfo(
114     blink::mojom::IntrinsicSizingInfoPtr sizing_info) {}
115 
GetCompositorViewportPixelSize()116 gfx::Size RenderWidgetHostViewBase::GetCompositorViewportPixelSize() {
117   return gfx::ScaleToCeiledSize(GetRequestedRendererSize(),
118                                 GetDeviceScaleFactor());
119 }
120 
SelectionBoundsChanged(const gfx::Rect & anchor_rect,base::i18n::TextDirection anchor_dir,const gfx::Rect & focus_rect,base::i18n::TextDirection focus_dir,bool is_anchor_first)121 void RenderWidgetHostViewBase::SelectionBoundsChanged(
122     const gfx::Rect& anchor_rect,
123     base::i18n::TextDirection anchor_dir,
124     const gfx::Rect& focus_rect,
125     base::i18n::TextDirection focus_dir,
126     bool is_anchor_first) {
127 #if !defined(OS_ANDROID)
128   if (GetTextInputManager())
129     GetTextInputManager()->SelectionBoundsChanged(
130         this, anchor_rect, anchor_dir, focus_rect, focus_dir, is_anchor_first);
131 #else
132   NOTREACHED() << "Selection bounds should be routed through the compositor.";
133 #endif
134 }
135 
GetMouseWheelMinimumGranularity() const136 int RenderWidgetHostViewBase::GetMouseWheelMinimumGranularity() const {
137   // Most platforms can specify the floating-point delta in the wheel event so
138   // they don't have a minimum granularity. Android is currently the only
139   // platform that overrides this.
140   return 0;
141 }
142 
GetRootView()143 RenderWidgetHostViewBase* RenderWidgetHostViewBase::GetRootView() {
144   return this;
145 }
146 
SelectionChanged(const base::string16 & text,size_t offset,const gfx::Range & range)147 void RenderWidgetHostViewBase::SelectionChanged(const base::string16& text,
148                                                 size_t offset,
149                                                 const gfx::Range& range) {
150   if (GetTextInputManager())
151     GetTextInputManager()->SelectionChanged(this, text, offset, range);
152 }
153 
GetRequestedRendererSize()154 gfx::Size RenderWidgetHostViewBase::GetRequestedRendererSize() {
155   return GetViewBounds().size();
156 }
157 
GetCaptureSequenceNumber() const158 uint32_t RenderWidgetHostViewBase::GetCaptureSequenceNumber() const {
159   // TODO(vmpstr): Implement this for overrides other than aura and child frame.
160   NOTIMPLEMENTED_LOG_ONCE();
161   return 0u;
162 }
163 
GetTextInputClient()164 ui::TextInputClient* RenderWidgetHostViewBase::GetTextInputClient() {
165   NOTREACHED();
166   return nullptr;
167 }
168 
SetIsInVR(bool is_in_vr)169 void RenderWidgetHostViewBase::SetIsInVR(bool is_in_vr) {
170   NOTIMPLEMENTED_LOG_ONCE();
171 }
172 
IsInVR() const173 bool RenderWidgetHostViewBase::IsInVR() const {
174   return false;
175 }
176 
GetRootFrameSinkId()177 viz::FrameSinkId RenderWidgetHostViewBase::GetRootFrameSinkId() {
178   return viz::FrameSinkId();
179 }
180 
IsSurfaceAvailableForCopy()181 bool RenderWidgetHostViewBase::IsSurfaceAvailableForCopy() {
182   return false;
183 }
184 
CopyMainAndPopupFromSurface(base::WeakPtr<RenderWidgetHostImpl> main_host,base::WeakPtr<DelegatedFrameHost> main_frame_host,base::WeakPtr<RenderWidgetHostImpl> popup_host,base::WeakPtr<DelegatedFrameHost> popup_frame_host,const gfx::Rect & src_subrect,const gfx::Size & dst_size,float scale_factor,base::OnceCallback<void (const SkBitmap &)> callback)185 void RenderWidgetHostViewBase::CopyMainAndPopupFromSurface(
186     base::WeakPtr<RenderWidgetHostImpl> main_host,
187     base::WeakPtr<DelegatedFrameHost> main_frame_host,
188     base::WeakPtr<RenderWidgetHostImpl> popup_host,
189     base::WeakPtr<DelegatedFrameHost> popup_frame_host,
190     const gfx::Rect& src_subrect,
191     const gfx::Size& dst_size,
192     float scale_factor,
193     base::OnceCallback<void(const SkBitmap&)> callback) {
194   if (!main_host || !main_frame_host)
195     return;
196 
197 #if defined(OS_ANDROID)
198   NOTREACHED()
199       << "RenderWidgetHostViewAndroid::CopyFromSurface calls "
200          "DelegatedFrameHostAndroid::CopyFromCompositingSurface directly, "
201          "and popups are not supported.";
202   return;
203 #else
204   if (!popup_host || !popup_frame_host) {
205     // No popup - just call CopyFromCompositingSurface once.
206     main_frame_host->CopyFromCompositingSurface(src_subrect, dst_size,
207                                                 std::move(callback));
208     return;
209   }
210 
211   // First locate the popup relative to the main page, in DIPs
212   const gfx::Point parent_location =
213       main_host->GetView()->GetBoundsInRootWindow().origin();
214   const gfx::Point popup_location =
215       popup_host->GetView()->GetBoundsInRootWindow().origin();
216   const gfx::Point offset_dips =
217       PointAtOffsetFromOrigin(popup_location - parent_location);
218   const gfx::Vector2d offset_physical =
219       ScaleToFlooredPoint(offset_dips, scale_factor).OffsetFromOrigin();
220 
221   // Queue up the request for the MAIN frame image first, but with a
222   // callback that launches a second request for the popup image.
223   //  1. Call CopyFromCompositingSurface for the main frame, with callback
224   //     |main_image_done_callback|. Inside |main_image_done_callback|:
225   //    a. Call CopyFromCompositingSurface again, this time on the popup
226   //       frame. For this call, build a new callback, |popup_done_callback|,
227   //       which:
228   //      i. Takes the main image as a parameter, combines the main image with
229   //         the just-acquired popup image, and then calls the original
230   //         (outer) callback with the combined image.
231   auto main_image_done_callback = base::BindOnce(
232       [](base::OnceCallback<void(const SkBitmap&)> final_callback,
233          const gfx::Vector2d offset,
234          base::WeakPtr<DelegatedFrameHost> popup_frame_host,
235          const gfx::Rect src_subrect, const gfx::Size dst_size,
236          const SkBitmap& main_image) {
237         if (!popup_frame_host)
238           return;
239 
240         // Build a new callback that actually combines images.
241         auto popup_done_callback = base::BindOnce(
242             [](base::OnceCallback<void(const SkBitmap&)> final_callback,
243                const gfx::Vector2d offset, const SkBitmap& main_image,
244                const SkBitmap& popup_image) {
245               // Draw popup_image into main_image.
246               SkCanvas canvas(main_image, SkSurfaceProps{});
247               canvas.drawBitmap(popup_image, offset.x(), offset.y());
248               std::move(final_callback).Run(main_image);
249             },
250             std::move(final_callback), offset, std::move(main_image));
251 
252         // Second, request the popup image.
253         gfx::Rect popup_subrect(src_subrect - offset);
254         popup_frame_host->CopyFromCompositingSurface(
255             popup_subrect, dst_size, std::move(popup_done_callback));
256       },
257       std::move(callback), offset_physical, popup_frame_host, src_subrect,
258       dst_size);
259 
260   // Request the main image (happens first).
261   main_frame_host->CopyFromCompositingSurface(
262       src_subrect, dst_size, std::move(main_image_done_callback));
263 #endif
264 }
265 
CopyFromSurface(const gfx::Rect & src_rect,const gfx::Size & output_size,base::OnceCallback<void (const SkBitmap &)> callback)266 void RenderWidgetHostViewBase::CopyFromSurface(
267     const gfx::Rect& src_rect,
268     const gfx::Size& output_size,
269     base::OnceCallback<void(const SkBitmap&)> callback) {
270   NOTIMPLEMENTED_LOG_ONCE();
271   std::move(callback).Run(SkBitmap());
272 }
273 
274 std::unique_ptr<viz::ClientFrameSinkVideoCapturer>
CreateVideoCapturer()275 RenderWidgetHostViewBase::CreateVideoCapturer() {
276   std::unique_ptr<viz::ClientFrameSinkVideoCapturer> video_capturer =
277       GetHostFrameSinkManager()->CreateVideoCapturer();
278   video_capturer->ChangeTarget(GetFrameSinkId());
279   return video_capturer;
280 }
281 
GetSelectedText()282 base::string16 RenderWidgetHostViewBase::GetSelectedText() {
283   if (!GetTextInputManager())
284     return base::string16();
285   return GetTextInputManager()->GetTextSelection(this)->selected_text();
286 }
287 
SetBackgroundColor(SkColor color)288 void RenderWidgetHostViewBase::SetBackgroundColor(SkColor color) {
289   // TODO(danakj): OPAQUE colors only make sense for main frame widgets,
290   // as child frames are always transparent background. We should move this to
291   // RenderView instead.
292   DCHECK(SkColorGetA(color) == SK_AlphaOPAQUE ||
293          SkColorGetA(color) == SK_AlphaTRANSPARENT);
294   if (default_background_color_ == color)
295     return;
296 
297   bool opaque = default_background_color_
298                     ? SkColorGetA(*default_background_color_)
299                     : SK_AlphaOPAQUE;
300   default_background_color_ = color;
301   UpdateBackgroundColor();
302   if (opaque != (SkColorGetA(color) == SK_AlphaOPAQUE)) {
303     if (host()->owner_delegate()) {
304       host()->owner_delegate()->SetBackgroundOpaque(SkColorGetA(color) ==
305                                                     SK_AlphaOPAQUE);
306     }
307   }
308 }
309 
GetBackgroundColor()310 base::Optional<SkColor> RenderWidgetHostViewBase::GetBackgroundColor() {
311   if (content_background_color_)
312     return content_background_color_;
313   return default_background_color_;
314 }
315 
IsMouseLocked()316 bool RenderWidgetHostViewBase::IsMouseLocked() {
317   return false;
318 }
319 
GetIsMouseLockedUnadjustedMovementForTesting()320 bool RenderWidgetHostViewBase::GetIsMouseLockedUnadjustedMovementForTesting() {
321   return false;
322 }
323 
LockKeyboard(base::Optional<base::flat_set<ui::DomCode>> codes)324 bool RenderWidgetHostViewBase::LockKeyboard(
325     base::Optional<base::flat_set<ui::DomCode>> codes) {
326   NOTIMPLEMENTED_LOG_ONCE();
327   return false;
328 }
329 
UnlockKeyboard()330 void RenderWidgetHostViewBase::UnlockKeyboard() {
331   NOTIMPLEMENTED_LOG_ONCE();
332 }
333 
IsKeyboardLocked()334 bool RenderWidgetHostViewBase::IsKeyboardLocked() {
335   return keyboard_locked_;
336 }
337 
338 base::flat_map<std::string, std::string>
GetKeyboardLayoutMap()339 RenderWidgetHostViewBase::GetKeyboardLayoutMap() {
340   NOTIMPLEMENTED_LOG_ONCE();
341   return base::flat_map<std::string, std::string>();
342 }
343 
FilterInputEvent(const blink::WebInputEvent & input_event)344 blink::mojom::InputEventResultState RenderWidgetHostViewBase::FilterInputEvent(
345     const blink::WebInputEvent& input_event) {
346   // By default, input events are simply forwarded to the renderer.
347   return blink::mojom::InputEventResultState::kNotConsumed;
348 }
349 
WheelEventAck(const blink::WebMouseWheelEvent & event,blink::mojom::InputEventResultState ack_result)350 void RenderWidgetHostViewBase::WheelEventAck(
351     const blink::WebMouseWheelEvent& event,
352     blink::mojom::InputEventResultState ack_result) {}
353 
GestureEventAck(const blink::WebGestureEvent & event,blink::mojom::InputEventResultState ack_result)354 void RenderWidgetHostViewBase::GestureEventAck(
355     const blink::WebGestureEvent& event,
356     blink::mojom::InputEventResultState ack_result) {}
357 
ChildDidAckGestureEvent(const blink::WebGestureEvent & event,blink::mojom::InputEventResultState ack_result)358 void RenderWidgetHostViewBase::ChildDidAckGestureEvent(
359     const blink::WebGestureEvent& event,
360     blink::mojom::InputEventResultState ack_result) {}
361 
ForwardTouchpadZoomEventIfNecessary(const blink::WebGestureEvent & event,blink::mojom::InputEventResultState ack_result)362 void RenderWidgetHostViewBase::ForwardTouchpadZoomEventIfNecessary(
363     const blink::WebGestureEvent& event,
364     blink::mojom::InputEventResultState ack_result) {
365   if (!event.IsTouchpadZoomEvent())
366     return;
367   if (!event.NeedsWheelEvent())
368     return;
369 
370   switch (event.GetType()) {
371     case blink::WebInputEvent::Type::kGesturePinchBegin:
372       // Don't send the begin event until we get the first unconsumed update, so
373       // that we elide pinch gesture steams consisting of only a begin and end.
374       pending_touchpad_pinch_begin_ = event;
375       pending_touchpad_pinch_begin_->SetNeedsWheelEvent(false);
376       break;
377     case blink::WebInputEvent::Type::kGesturePinchUpdate:
378       if (ack_result != blink::mojom::InputEventResultState::kConsumed &&
379           !event.data.pinch_update.zoom_disabled) {
380         if (pending_touchpad_pinch_begin_) {
381           host()->ForwardGestureEvent(*pending_touchpad_pinch_begin_);
382           pending_touchpad_pinch_begin_.reset();
383         }
384         // Now that the synthetic wheel event has gone unconsumed, we have the
385         // pinch event actually change the page scale.
386         blink::WebGestureEvent pinch_event(event);
387         pinch_event.SetNeedsWheelEvent(false);
388         host()->ForwardGestureEvent(pinch_event);
389       }
390       break;
391     case blink::WebInputEvent::Type::kGesturePinchEnd:
392       if (pending_touchpad_pinch_begin_) {
393         pending_touchpad_pinch_begin_.reset();
394       } else {
395         blink::WebGestureEvent pinch_end_event(event);
396         pinch_end_event.SetNeedsWheelEvent(false);
397         host()->ForwardGestureEvent(pinch_end_event);
398       }
399       break;
400     case blink::WebInputEvent::Type::kGestureDoubleTap:
401       if (ack_result != blink::mojom::InputEventResultState::kConsumed) {
402         blink::WebGestureEvent double_tap(event);
403         double_tap.SetNeedsWheelEvent(false);
404         // TODO(mcnee): Support double-tap zoom gesture for OOPIFs. For now,
405         // we naively send this to the main frame. If this is over an OOPIF,
406         // then the iframe element will incorrectly be used for the scale
407         // calculation rather than the element in the OOPIF.
408         // https://crbug.com/758348
409         host()->ForwardGestureEvent(double_tap);
410       }
411       break;
412     default:
413       NOTREACHED();
414   }
415 }
416 
HasFallbackSurface() const417 bool RenderWidgetHostViewBase::HasFallbackSurface() const {
418   NOTREACHED();
419   return false;
420 }
421 
SetWidgetType(WidgetType widget_type)422 void RenderWidgetHostViewBase::SetWidgetType(WidgetType widget_type) {
423   widget_type_ = widget_type;
424 }
425 
GetWidgetType()426 WidgetType RenderWidgetHostViewBase::GetWidgetType() {
427   return widget_type_;
428 }
429 
430 BrowserAccessibilityManager*
CreateBrowserAccessibilityManager(BrowserAccessibilityDelegate * delegate,bool for_root_frame)431 RenderWidgetHostViewBase::CreateBrowserAccessibilityManager(
432     BrowserAccessibilityDelegate* delegate,
433     bool for_root_frame) {
434   NOTREACHED();
435   return nullptr;
436 }
437 
438 gfx::AcceleratedWidget
AccessibilityGetAcceleratedWidget()439     RenderWidgetHostViewBase::AccessibilityGetAcceleratedWidget() {
440   return gfx::kNullAcceleratedWidget;
441 }
442 
443 gfx::NativeViewAccessible
AccessibilityGetNativeViewAccessible()444     RenderWidgetHostViewBase::AccessibilityGetNativeViewAccessible() {
445   return nullptr;
446 }
447 
448 gfx::NativeViewAccessible
AccessibilityGetNativeViewAccessibleForWindow()449 RenderWidgetHostViewBase::AccessibilityGetNativeViewAccessibleForWindow() {
450   return nullptr;
451 }
452 
RequestRepaintForTesting()453 bool RenderWidgetHostViewBase::RequestRepaintForTesting() {
454   return false;
455 }
456 
ProcessAckedTouchEvent(const TouchEventWithLatencyInfo & touch,blink::mojom::InputEventResultState ack_result)457 void RenderWidgetHostViewBase::ProcessAckedTouchEvent(
458     const TouchEventWithLatencyInfo& touch,
459     blink::mojom::InputEventResultState ack_result) {
460   NOTREACHED();
461 }
462 
UpdateScreenInfo(gfx::NativeView view)463 void RenderWidgetHostViewBase::UpdateScreenInfo(gfx::NativeView view) {
464   if (host() && host()->delegate())
465     host()->delegate()->SendScreenRects();
466 
467   if (HasDisplayPropertyChanged(view) && host()) {
468     OnSynchronizedDisplayPropertiesChanged();
469     host()->NotifyScreenInfoChanged();
470   }
471 }
472 
HasDisplayPropertyChanged(gfx::NativeView view)473 bool RenderWidgetHostViewBase::HasDisplayPropertyChanged(gfx::NativeView view) {
474   display::Display display =
475       display::Screen::GetScreen()->GetDisplayNearestView(view);
476   if (current_display_area_ == display.work_area() &&
477       current_device_scale_factor_ == display.device_scale_factor() &&
478       current_display_rotation_ == display.rotation() &&
479       current_display_color_spaces_ == display.color_spaces()) {
480     return false;
481   }
482 
483   current_display_area_ = display.work_area();
484   current_device_scale_factor_ = display.device_scale_factor();
485   current_display_rotation_ = display.rotation();
486   current_display_color_spaces_ = display.color_spaces();
487   return true;
488 }
489 
DidUnregisterFromTextInputManager(TextInputManager * text_input_manager)490 void RenderWidgetHostViewBase::DidUnregisterFromTextInputManager(
491     TextInputManager* text_input_manager) {
492   DCHECK(text_input_manager && text_input_manager_ == text_input_manager);
493 
494   text_input_manager_ = nullptr;
495 }
496 
EnableAutoResize(const gfx::Size & min_size,const gfx::Size & max_size)497 void RenderWidgetHostViewBase::EnableAutoResize(const gfx::Size& min_size,
498                                                 const gfx::Size& max_size) {
499   host()->SetAutoResize(true, min_size, max_size);
500   host()->SynchronizeVisualProperties();
501 }
502 
DisableAutoResize(const gfx::Size & new_size)503 void RenderWidgetHostViewBase::DisableAutoResize(const gfx::Size& new_size) {
504   if (!new_size.IsEmpty())
505     SetSize(new_size);
506   host()->SetAutoResize(false, gfx::Size(), gfx::Size());
507   host()->SynchronizeVisualProperties();
508 }
509 
510 viz::ScopedSurfaceIdAllocator
DidUpdateVisualProperties(const cc::RenderFrameMetadata & metadata)511 RenderWidgetHostViewBase::DidUpdateVisualProperties(
512     const cc::RenderFrameMetadata& metadata) {
513   // This doesn't suppress allocation. Derived classes that need suppression
514   // should override this function.
515   base::OnceCallback<void()> allocation_task =
516       base::BindOnce(&RenderWidgetHostViewBase::SynchronizeVisualProperties,
517                      weak_factory_.GetWeakPtr());
518   return viz::ScopedSurfaceIdAllocator(std::move(allocation_task));
519 }
520 
GetWeakPtr()521 base::WeakPtr<RenderWidgetHostViewBase> RenderWidgetHostViewBase::GetWeakPtr() {
522   return weak_factory_.GetWeakPtr();
523 }
524 
GetScreenInfo(blink::ScreenInfo * screen_info)525 void RenderWidgetHostViewBase::GetScreenInfo(blink::ScreenInfo* screen_info) {
526   DisplayUtil::GetNativeViewScreenInfo(screen_info, GetNativeView());
527 }
528 
GetDeviceScaleFactor()529 float RenderWidgetHostViewBase::GetDeviceScaleFactor() {
530   blink::ScreenInfo screen_info;
531   GetScreenInfo(&screen_info);
532   return screen_info.device_scale_factor;
533 }
534 
OnAutoscrollStart()535 void RenderWidgetHostViewBase::OnAutoscrollStart() {
536   if (!GetMouseWheelPhaseHandler())
537     return;
538 
539   // End the current scrolling seqeunce when autoscrolling starts.
540   GetMouseWheelPhaseHandler()->DispatchPendingWheelEndEvent();
541 }
542 
GetVisibleViewportSize()543 gfx::Size RenderWidgetHostViewBase::GetVisibleViewportSize() {
544   return GetViewBounds().size();
545 }
546 
SetInsets(const gfx::Insets & insets)547 void RenderWidgetHostViewBase::SetInsets(const gfx::Insets& insets) {
548   NOTIMPLEMENTED_LOG_ONCE();
549 }
550 
DisplayCursor(const WebCursor & cursor)551 void RenderWidgetHostViewBase::DisplayCursor(const WebCursor& cursor) {
552   return;
553 }
554 
GetCursorManager()555 CursorManager* RenderWidgetHostViewBase::GetCursorManager() {
556   return nullptr;
557 }
558 
TransformPointToRootSurface(gfx::PointF * point)559 void RenderWidgetHostViewBase::TransformPointToRootSurface(gfx::PointF* point) {
560   return;
561 }
562 
OnDidNavigateMainFrameToNewPage()563 void RenderWidgetHostViewBase::OnDidNavigateMainFrameToNewPage() {
564 }
565 
OnFrameTokenChangedForView(uint32_t frame_token)566 void RenderWidgetHostViewBase::OnFrameTokenChangedForView(
567     uint32_t frame_token) {
568   if (host())
569     host()->DidProcessFrame(frame_token);
570 }
571 
ScreenRectIsUnstableFor(const blink::WebInputEvent & event)572 bool RenderWidgetHostViewBase::ScreenRectIsUnstableFor(
573     const blink::WebInputEvent& event) {
574   return false;
575 }
576 
ProcessMouseEvent(const blink::WebMouseEvent & event,const ui::LatencyInfo & latency)577 void RenderWidgetHostViewBase::ProcessMouseEvent(
578     const blink::WebMouseEvent& event,
579     const ui::LatencyInfo& latency) {
580   // TODO(crbug.com/814674): Figure out the reason |host| is null here in all
581   // Process* functions.
582   if (!host())
583     return;
584 
585   PreProcessMouseEvent(event);
586   host()->ForwardMouseEventWithLatencyInfo(event, latency);
587 }
588 
ProcessMouseWheelEvent(const blink::WebMouseWheelEvent & event,const ui::LatencyInfo & latency)589 void RenderWidgetHostViewBase::ProcessMouseWheelEvent(
590     const blink::WebMouseWheelEvent& event,
591     const ui::LatencyInfo& latency) {
592   if (!host())
593     return;
594   host()->ForwardWheelEventWithLatencyInfo(event, latency);
595 }
596 
ProcessTouchEvent(const blink::WebTouchEvent & event,const ui::LatencyInfo & latency)597 void RenderWidgetHostViewBase::ProcessTouchEvent(
598     const blink::WebTouchEvent& event,
599     const ui::LatencyInfo& latency) {
600   if (!host())
601     return;
602 
603   PreProcessTouchEvent(event);
604   host()->ForwardTouchEventWithLatencyInfo(event, latency);
605 }
606 
ProcessGestureEvent(const blink::WebGestureEvent & event,const ui::LatencyInfo & latency)607 void RenderWidgetHostViewBase::ProcessGestureEvent(
608     const blink::WebGestureEvent& event,
609     const ui::LatencyInfo& latency) {
610   if (!host())
611     return;
612   host()->ForwardGestureEventWithLatencyInfo(event, latency);
613 }
614 
TransformPointToRootCoordSpaceF(const gfx::PointF & point)615 gfx::PointF RenderWidgetHostViewBase::TransformPointToRootCoordSpaceF(
616     const gfx::PointF& point) {
617   return point;
618 }
619 
TransformRootPointToViewCoordSpace(const gfx::PointF & point)620 gfx::PointF RenderWidgetHostViewBase::TransformRootPointToViewCoordSpace(
621     const gfx::PointF& point) {
622   return point;
623 }
624 
TransformPointToCoordSpaceForView(const gfx::PointF & point,RenderWidgetHostViewBase * target_view,gfx::PointF * transformed_point)625 bool RenderWidgetHostViewBase::TransformPointToCoordSpaceForView(
626     const gfx::PointF& point,
627     RenderWidgetHostViewBase* target_view,
628     gfx::PointF* transformed_point) {
629   NOTREACHED();
630   return true;
631 }
632 
IsRenderWidgetHostViewChildFrame()633 bool RenderWidgetHostViewBase::IsRenderWidgetHostViewChildFrame() {
634   return false;
635 }
636 
HasSize() const637 bool RenderWidgetHostViewBase::HasSize() const {
638   return true;
639 }
640 
Destroy()641 void RenderWidgetHostViewBase::Destroy() {
642   host_ = nullptr;
643 }
644 
CanSynchronizeVisualProperties()645 bool RenderWidgetHostViewBase::CanSynchronizeVisualProperties() {
646   return true;
647 }
648 
649 std::vector<std::unique_ptr<ui::TouchEvent>>
ExtractAndCancelActiveTouches()650 RenderWidgetHostViewBase::ExtractAndCancelActiveTouches() {
651   return {};
652 }
653 
TextInputStateChanged(const ui::mojom::TextInputState & text_input_state)654 void RenderWidgetHostViewBase::TextInputStateChanged(
655     const ui::mojom::TextInputState& text_input_state) {
656   if (GetTextInputManager())
657     GetTextInputManager()->UpdateTextInputState(this, text_input_state);
658 }
659 
ImeCancelComposition()660 void RenderWidgetHostViewBase::ImeCancelComposition() {
661   if (GetTextInputManager())
662     GetTextInputManager()->ImeCancelComposition(this);
663 }
664 
ImeCompositionRangeChanged(const gfx::Range & range,const std::vector<gfx::Rect> & character_bounds)665 void RenderWidgetHostViewBase::ImeCompositionRangeChanged(
666     const gfx::Range& range,
667     const std::vector<gfx::Rect>& character_bounds) {
668   if (GetTextInputManager()) {
669     GetTextInputManager()->ImeCompositionRangeChanged(this, range,
670                                                       character_bounds);
671   }
672 }
673 
GetTextInputManager()674 TextInputManager* RenderWidgetHostViewBase::GetTextInputManager() {
675   if (text_input_manager_)
676     return text_input_manager_;
677 
678   if (!host() || !host()->delegate())
679     return nullptr;
680 
681   // This RWHV needs to be registered with the TextInputManager so that the
682   // TextInputManager starts tracking its state, and observing its lifetime.
683   text_input_manager_ = host()->delegate()->GetTextInputManager();
684   if (text_input_manager_)
685     text_input_manager_->Register(this);
686 
687   return text_input_manager_;
688 }
689 
StopFling()690 void RenderWidgetHostViewBase::StopFling() {
691   if (!host())
692     return;
693 
694   host()->StopFling();
695 
696   // In case of scroll bubbling tells the child's fling controller which is in
697   // charge of generating GSUs to stop flinging.
698   if (host()->delegate() && host()->delegate()->GetInputEventRouter()) {
699     host()->delegate()->GetInputEventRouter()->StopFling();
700   }
701 }
702 
AddObserver(RenderWidgetHostViewBaseObserver * observer)703 void RenderWidgetHostViewBase::AddObserver(
704     RenderWidgetHostViewBaseObserver* observer) {
705   observers_.AddObserver(observer);
706 }
707 
RemoveObserver(RenderWidgetHostViewBaseObserver * observer)708 void RenderWidgetHostViewBase::RemoveObserver(
709     RenderWidgetHostViewBaseObserver* observer) {
710   observers_.RemoveObserver(observer);
711 }
712 
713 TouchSelectionControllerClientManager*
GetTouchSelectionControllerClientManager()714 RenderWidgetHostViewBase::GetTouchSelectionControllerClientManager() {
715   return nullptr;
716 }
717 
SetRecordContentToVisibleTimeRequest(base::TimeTicks start_time,bool destination_is_loaded,bool show_reason_tab_switching,bool show_reason_unoccluded,bool show_reason_bfcache_restore)718 void RenderWidgetHostViewBase::SetRecordContentToVisibleTimeRequest(
719     base::TimeTicks start_time,
720     bool destination_is_loaded,
721     bool show_reason_tab_switching,
722     bool show_reason_unoccluded,
723     bool show_reason_bfcache_restore) {
724   auto record_tab_switch_time_request =
725       blink::mojom::RecordContentToVisibleTimeRequest::New(
726           start_time, destination_is_loaded, show_reason_tab_switching,
727           show_reason_unoccluded, show_reason_bfcache_restore);
728 
729   if (last_record_tab_switch_time_request_) {
730     blink::UpdateRecordContentToVisibleTimeRequest(
731         *record_tab_switch_time_request, *last_record_tab_switch_time_request_);
732   } else {
733     last_record_tab_switch_time_request_ =
734         std::move(record_tab_switch_time_request);
735   }
736 }
737 
738 blink::mojom::RecordContentToVisibleTimeRequestPtr
TakeRecordContentToVisibleTimeRequest()739 RenderWidgetHostViewBase::TakeRecordContentToVisibleTimeRequest() {
740   return std::move(last_record_tab_switch_time_request_);
741 }
742 
SynchronizeVisualProperties()743 void RenderWidgetHostViewBase::SynchronizeVisualProperties() {
744   if (host())
745     host()->SynchronizeVisualProperties();
746 }
747 
DidNavigate()748 void RenderWidgetHostViewBase::DidNavigate() {
749   if (host())
750     host()->SynchronizeVisualProperties();
751 }
752 
753 // TODO(wjmaclean): Would it simplify this function if we re-implemented it
754 // using GetTransformToViewCoordSpace()?
TransformPointToTargetCoordSpace(RenderWidgetHostViewBase * original_view,RenderWidgetHostViewBase * target_view,const gfx::PointF & point,gfx::PointF * transformed_point) const755 bool RenderWidgetHostViewBase::TransformPointToTargetCoordSpace(
756     RenderWidgetHostViewBase* original_view,
757     RenderWidgetHostViewBase* target_view,
758     const gfx::PointF& point,
759     gfx::PointF* transformed_point) const {
760   DCHECK(original_view);
761   DCHECK(target_view);
762   viz::FrameSinkId root_frame_sink_id = original_view->GetRootFrameSinkId();
763   if (!root_frame_sink_id.is_valid())
764     return false;
765   const auto& display_hit_test_query_map =
766       GetHostFrameSinkManager()->display_hit_test_query();
767   const auto iter = display_hit_test_query_map.find(root_frame_sink_id);
768   if (iter == display_hit_test_query_map.end())
769     return false;
770   viz::HitTestQuery* query = iter->second.get();
771 
772   std::vector<viz::FrameSinkId> target_ancestors;
773   target_ancestors.push_back(target_view->GetFrameSinkId());
774 
775   RenderWidgetHostViewBase* cur_view = target_view;
776   while (cur_view->IsRenderWidgetHostViewChildFrame()) {
777     cur_view =
778         static_cast<RenderWidgetHostViewChildFrame*>(cur_view)->GetParentView();
779     if (!cur_view)
780       return false;
781     target_ancestors.push_back(cur_view->GetFrameSinkId());
782   }
783   target_ancestors.push_back(root_frame_sink_id);
784 
785   float device_scale_factor = original_view->GetDeviceScaleFactor();
786   DCHECK_GT(device_scale_factor, 0.0f);
787   gfx::Point3F point_in_pixels =
788       gfx::Point3F(gfx::ConvertPointToPixels(point, device_scale_factor));
789   // TODO(crbug.com/966995): Optimize so that |point_in_pixels| doesn't need to
790   // be in the coordinate space of the root surface in HitTestQuery.
791   gfx::Transform transform_root_to_original;
792   query->GetTransformToTarget(original_view->GetFrameSinkId(),
793                               &transform_root_to_original);
794   if (!transform_root_to_original.TransformPointReverse(&point_in_pixels))
795     return false;
796   gfx::PointF transformed_point_in_physical_pixels;
797   if (!query->TransformLocationForTarget(
798           target_ancestors, point_in_pixels.AsPointF(),
799           &transformed_point_in_physical_pixels)) {
800     return false;
801   }
802   *transformed_point = gfx::ConvertPointToDips(
803       transformed_point_in_physical_pixels, device_scale_factor);
804   return true;
805 }
806 
GetTransformToViewCoordSpace(RenderWidgetHostViewBase * target_view,gfx::Transform * transform)807 bool RenderWidgetHostViewBase::GetTransformToViewCoordSpace(
808     RenderWidgetHostViewBase* target_view,
809     gfx::Transform* transform) {
810   DCHECK(transform);
811   if (target_view == this) {
812     transform->MakeIdentity();
813     return true;
814   }
815 
816   viz::FrameSinkId root_frame_sink_id = GetRootFrameSinkId();
817   if (!root_frame_sink_id.is_valid())
818     return false;
819 
820   const auto& display_hit_test_query_map =
821       GetHostFrameSinkManager()->display_hit_test_query();
822   const auto iter = display_hit_test_query_map.find(root_frame_sink_id);
823   if (iter == display_hit_test_query_map.end())
824     return false;
825   viz::HitTestQuery* query = iter->second.get();
826 
827   gfx::Transform transform_this_to_root;
828   if (GetFrameSinkId() != root_frame_sink_id) {
829     gfx::Transform transform_root_to_this;
830     if (!query->GetTransformToTarget(GetFrameSinkId(), &transform_root_to_this))
831       return false;
832     if (!transform_root_to_this.GetInverse(&transform_this_to_root))
833       return false;
834   }
835   gfx::Transform transform_root_to_target;
836   if (!query->GetTransformToTarget(target_view->GetFrameSinkId(),
837                                    &transform_root_to_target)) {
838     return false;
839   }
840 
841   // TODO(wjmaclean): In TransformPointToTargetCoordSpace the device scale
842   // factor is taken from the original view ... does that matter? Presumably
843   // all the views have the same dsf.
844   float device_scale_factor = GetDeviceScaleFactor();
845   gfx::Transform transform_to_pixel;
846   transform_to_pixel.Scale(device_scale_factor, device_scale_factor);
847   gfx::Transform transform_from_pixel;
848   transform_from_pixel.Scale(1.f / device_scale_factor,
849                              1.f / device_scale_factor);
850 
851   // Note: gfx::Transform includes optimizations to early-out for scale = 1 or
852   // concatenating an identity matrix, so we don't add those checks here.
853   transform->MakeIdentity();
854 
855   transform->ConcatTransform(transform_to_pixel);
856   transform->ConcatTransform(transform_this_to_root);
857   transform->ConcatTransform(transform_root_to_target);
858   transform->ConcatTransform(transform_from_pixel);
859 
860   return true;
861 }
862 
TransformPointToLocalCoordSpace(const gfx::PointF & point,const viz::SurfaceId & original_surface,gfx::PointF * transformed_point)863 bool RenderWidgetHostViewBase::TransformPointToLocalCoordSpace(
864     const gfx::PointF& point,
865     const viz::SurfaceId& original_surface,
866     gfx::PointF* transformed_point) {
867   viz::FrameSinkId original_frame_sink_id = original_surface.frame_sink_id();
868   viz::FrameSinkId target_frame_sink_id = GetFrameSinkId();
869   if (!original_frame_sink_id.is_valid() || !target_frame_sink_id.is_valid())
870     return false;
871   if (original_frame_sink_id == target_frame_sink_id)
872     return true;
873   if (!host() || !host()->delegate())
874     return false;
875   auto* router = host()->delegate()->GetInputEventRouter();
876   if (!router)
877     return false;
878   *transformed_point = point;
879   return TransformPointToTargetCoordSpace(
880       router->FindViewFromFrameSinkId(original_frame_sink_id),
881       router->FindViewFromFrameSinkId(target_frame_sink_id), point,
882       transformed_point);
883 }
884 
885 }  // namespace content
886