[M120 Migration][VD] Fix some focus issues for offscreen mode
[platform/framework/web/chromium-efl.git] / content / browser / renderer_host / render_widget_host_view_aura.cc
1 // Copyright 2012 The Chromium Authors
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_aura.h"
6
7 #include <limits>
8 #include <memory>
9 #include <set>
10 #include <utility>
11
12 #include "base/auto_reset.h"
13 #include "base/command_line.h"
14 #include "base/feature_list.h"
15 #include "base/functional/bind.h"
16 #include "base/functional/callback_helpers.h"
17 #include "base/logging.h"
18 #include "base/memory/raw_ptr.h"
19 #include "base/metrics/histogram_functions.h"
20 #include "base/strings/strcat.h"
21 #include "base/strings/string_number_conversions.h"
22 #include "base/strings/utf_string_conversions.h"
23 #include "base/trace_event/trace_event.h"
24 #include "build/build_config.h"
25 #include "build/chromeos_buildflags.h"
26 #include "cc/layers/layer.h"
27 #include "cc/trees/layer_tree_settings.h"
28 #include "components/viz/common/features.h"
29 #include "components/viz/common/frame_sinks/copy_output_request.h"
30 #include "components/viz/common/frame_sinks/copy_output_result.h"
31 #include "components/viz/common/surfaces/local_surface_id.h"
32 #include "content/browser/accessibility/browser_accessibility_manager.h"
33 #include "content/browser/accessibility/browser_accessibility_state_impl.h"
34 #include "content/browser/bad_message.h"
35 #include "content/browser/gpu/compositor_util.h"
36 #include "content/browser/renderer_host/cursor_manager.h"
37 #include "content/browser/renderer_host/delegated_frame_host_client_aura.h"
38 #include "content/browser/renderer_host/dip_util.h"
39 #include "content/browser/renderer_host/frame_tree.h"
40 #include "content/browser/renderer_host/frame_tree_node.h"
41 #include "content/browser/renderer_host/input/synthetic_gesture_target_aura.h"
42 #include "content/browser/renderer_host/input/touch_selection_controller_client_aura.h"
43 #include "content/browser/renderer_host/overscroll_controller.h"
44 #include "content/browser/renderer_host/render_frame_host_impl.h"
45 #include "content/browser/renderer_host/render_view_host_delegate.h"
46 #include "content/browser/renderer_host/render_view_host_delegate_view.h"
47 #include "content/browser/renderer_host/render_view_host_impl.h"
48 #include "content/browser/renderer_host/render_widget_host_delegate.h"
49 #include "content/browser/renderer_host/render_widget_host_impl.h"
50 #include "content/browser/renderer_host/render_widget_host_input_event_router.h"
51 #include "content/browser/renderer_host/render_widget_host_view_event_handler.h"
52 #include "content/browser/renderer_host/ui_events_helper.h"
53 #include "content/browser/renderer_host/visible_time_request_trigger.h"
54 #include "content/public/browser/content_browser_client.h"
55 #include "content/public/browser/device_service.h"
56 #include "content/public/browser/render_view_host.h"
57 #include "content/public/common/content_features.h"
58 #include "content/public/common/page_visibility_state.h"
59 #include "services/service_manager/public/cpp/interface_provider.h"
60 #include "third_party/blink/public/common/input/web_input_event.h"
61 #include "third_party/blink/public/mojom/input/input_handler.mojom-forward.h"
62 #include "third_party/blink/public/mojom/widget/record_content_to_visible_time_request.mojom.h"
63 #include "ui/accessibility/aura/aura_window_properties.h"
64 #include "ui/accessibility/platform/ax_platform_node.h"
65 #include "ui/aura/client/aura_constants.h"
66 #include "ui/aura/client/cursor_client.h"
67 #include "ui/aura/client/cursor_client_observer.h"
68 #include "ui/aura/client/focus_client.h"
69 #include "ui/aura/client/screen_position_client.h"
70 #include "ui/aura/client/transient_window_client.h"
71 #include "ui/aura/client/window_parenting_client.h"
72 #include "ui/aura/env.h"
73 #include "ui/aura/window.h"
74 #include "ui/aura/window_event_dispatcher.h"
75 #include "ui/aura/window_observer.h"
76 #include "ui/aura/window_tree_host.h"
77 #include "ui/aura_extra/window_position_in_root_monitor.h"
78 #include "ui/base/clipboard/clipboard.h"
79 #include "ui/base/clipboard/scoped_clipboard_writer.h"
80 #include "ui/base/cursor/cursor.h"
81 #include "ui/base/cursor/mojom/cursor_type.mojom-shared.h"
82 #include "ui/base/hit_test.h"
83 #include "ui/base/ime/input_method.h"
84 #include "ui/base/ime/mojom/text_input_state.mojom.h"
85 #include "ui/base/owned_window_anchor.h"
86 #include "ui/base/ui_base_features.h"
87 #include "ui/base/ui_base_switches.h"
88 #include "ui/base/ui_base_types.h"
89 #include "ui/display/screen.h"
90 #include "ui/events/blink/blink_event_util.h"
91 #include "ui/events/blink/did_overscroll_params.h"
92 #include "ui/events/blink/web_input_event.h"
93 #include "ui/events/event.h"
94 #include "ui/events/event_observer.h"
95 #include "ui/events/event_utils.h"
96 #include "ui/events/gesture_detection/gesture_configuration.h"
97 #include "ui/events/gestures/gesture_recognizer.h"
98 #include "ui/events/keycodes/dom/dom_code.h"
99 #include "ui/gfx/canvas.h"
100 #include "ui/gfx/color_palette.h"
101 #include "ui/gfx/geometry/dip_util.h"
102 #include "ui/gfx/geometry/rect_conversions.h"
103 #include "ui/gfx/geometry/size_conversions.h"
104 #include "ui/gfx/geometry/skia_conversions.h"
105 #include "ui/touch_selection/touch_selection_controller.h"
106 #include "ui/wm/core/coordinate_conversion.h"
107 #include "ui/wm/public/activation_client.h"
108 #include "ui/wm/public/scoped_tooltip_disabler.h"
109 #include "ui/wm/public/tooltip_client.h"
110
111 #if BUILDFLAG(IS_WIN)
112 #include "base/time/time.h"
113 #include "content/browser/accessibility/browser_accessibility_manager_win.h"
114 #include "content/browser/accessibility/browser_accessibility_win.h"
115 #include "content/browser/renderer_host/legacy_render_widget_host_win.h"
116 #include "ui/accessibility/platform/ax_fragment_root_win.h"
117 #include "ui/base/ime/virtual_keyboard_controller.h"
118 #include "ui/base/ime/virtual_keyboard_controller_observer.h"
119 #include "ui/base/win/hidden_window.h"
120 #include "ui/display/win/screen_win.h"
121 #include "ui/gfx/gdi_util.h"
122 #endif
123
124 #if BUILDFLAG(IS_LINUX)
125 #include "content/browser/accessibility/browser_accessibility_auralinux.h"
126 #include "ui/base/ime/linux/text_edit_command_auralinux.h"
127 #include "ui/base/ime/text_input_flags.h"
128 #include "ui/linux/linux_ui.h"
129 #endif
130
131 #if BUILDFLAG(IS_CHROMEOS_ASH)
132 #include "ui/wm/core/ime_util_chromeos.h"
133 #endif
134
135 #if BUILDFLAG(IS_CHROMEOS_ASH)
136 #include "ui/base/ime/ash/extension_ime_util.h"
137 #include "ui/base/ime/ash/input_method_manager.h"
138 #endif
139
140 #if BUILDFLAG(IS_CHROMEOS)
141 #include "ui/base/ime/mojom/virtual_keyboard_types.mojom.h"
142 #endif
143
144 #if BUILDFLAG(IS_EFL)
145 #include "base/base_switches.h"
146 #endif
147
148 using gfx::RectToSkIRect;
149 using gfx::SkIRectToRect;
150
151 using blink::WebInputEvent;
152 using blink::WebGestureEvent;
153 using blink::WebTouchEvent;
154
155 namespace content {
156
157 // We need to watch for mouse events outside a Web Popup or its parent
158 // and dismiss the popup for certain events.
159 class RenderWidgetHostViewAura::EventObserverForPopupExit
160     : public ui::EventObserver {
161  public:
162   explicit EventObserverForPopupExit(RenderWidgetHostViewAura* rwhva)
163       : rwhva_(rwhva) {
164     aura::Env* env = aura::Env::GetInstance();
165     env->AddEventObserver(this, env,
166                           {ui::ET_MOUSE_PRESSED, ui::ET_TOUCH_PRESSED});
167   }
168
169   EventObserverForPopupExit(const EventObserverForPopupExit&) = delete;
170   EventObserverForPopupExit& operator=(const EventObserverForPopupExit&) =
171       delete;
172
173   ~EventObserverForPopupExit() override {
174     aura::Env::GetInstance()->RemoveEventObserver(this);
175   }
176
177   // ui::EventObserver:
178   void OnEvent(const ui::Event& event) override {
179     rwhva_->ApplyEventObserverForPopupExit(*event.AsLocatedEvent());
180   }
181
182  private:
183   raw_ptr<RenderWidgetHostViewAura> rwhva_;
184 };
185
186 void RenderWidgetHostViewAura::ApplyEventObserverForPopupExit(
187     const ui::LocatedEvent& event) {
188   DCHECK(event.type() == ui::ET_MOUSE_PRESSED ||
189          event.type() == ui::ET_TOUCH_PRESSED);
190
191   if (in_shutdown_)
192     return;
193
194   // |target| may be null.
195   aura::Window* target = static_cast<aura::Window*>(event.target());
196   if (target != window_ &&
197       (!popup_parent_host_view_ ||
198        target != popup_parent_host_view_->window_)) {
199     // If we enter this code path it means that we did not receive any focus
200     // lost notifications for the popup window. Ensure that blink is aware
201     // of the fact that focus was lost for the host window by sending a Blur
202     // notification. We also set a flag in the view indicating that we need
203     // to force a Focus notification on the next mouse down.
204     if (popup_parent_host_view_ && popup_parent_host_view_->host()) {
205       popup_parent_host_view_->event_handler()
206           ->set_focus_on_mouse_down_or_key_event(true);
207       popup_parent_host_view_->host()->Blur();
208     }
209     // Note: popup_parent_host_view_ may be NULL when there are multiple
210     // popup children per view. See: RenderWidgetHostViewAura::InitAsPopup().
211     Shutdown();
212   }
213 }
214
215 // We have to implement the WindowObserver interface on a separate object
216 // because clang doesn't like implementing multiple interfaces that have
217 // methods with the same name. This object is owned by the
218 // RenderWidgetHostViewAura.
219 class RenderWidgetHostViewAura::WindowObserver : public aura::WindowObserver {
220  public:
221   explicit WindowObserver(RenderWidgetHostViewAura* view)
222       : view_(view) {
223     view_->window_->AddObserver(this);
224   }
225
226   WindowObserver(const WindowObserver&) = delete;
227   WindowObserver& operator=(const WindowObserver&) = delete;
228
229   ~WindowObserver() override { view_->window_->RemoveObserver(this); }
230
231   // Overridden from aura::WindowObserver:
232   void OnWindowAddedToRootWindow(aura::Window* window) override {
233     if (window == view_->window_)
234       view_->AddedToRootWindow();
235   }
236
237   void OnWindowRemovingFromRootWindow(aura::Window* window,
238                                       aura::Window* new_root) override {
239     if (window == view_->window_)
240       view_->RemovingFromRootWindow();
241   }
242
243   void OnWindowHierarchyChanged(const HierarchyChangeParams& params) override {
244     view_->ParentHierarchyChanged();
245   }
246
247   void OnWindowTitleChanged(aura::Window* window) override {
248     if (window == view_->window_)
249       view_->WindowTitleChanged();
250   }
251
252  private:
253   raw_ptr<RenderWidgetHostViewAura> view_;
254 };
255
256 ////////////////////////////////////////////////////////////////////////////////
257 // RenderWidgetHostViewAura, public:
258
259 RenderWidgetHostViewAura::RenderWidgetHostViewAura(
260     RenderWidgetHost* widget_host,
261     WebContents& web_contents)
262     : RenderWidgetHostViewBase(widget_host),
263       window_(nullptr),
264       in_shutdown_(false),
265       in_bounds_changed_(false),
266       popup_parent_host_view_(nullptr),
267       popup_child_host_view_(nullptr),
268       is_loading_(false),
269       has_composition_text_(false),
270       added_frame_observer_(false),
271       cursor_visibility_state_in_renderer_(UNKNOWN),
272 #if BUILDFLAG(IS_WIN)
273       legacy_render_widget_host_HWND_(nullptr),
274       legacy_window_destroyed_(false),
275 #endif
276       device_scale_factor_(0.0f),
277       event_handler_(new RenderWidgetHostViewEventHandler(host(), this, this)),
278       frame_sink_id_(host()->GetFrameSinkId()),
279       visibility_(host()->is_hidden() ? Visibility::HIDDEN
280                                       : Visibility::VISIBLE) {
281   // CreateDelegatedFrameHostClient() and CreateAuraWindow() assume that the
282   // FrameSinkId is valid. RenderWidgetHostImpl::GetFrameSinkId() always returns
283   // a valid FrameSinkId.
284   DCHECK(frame_sink_id_.is_valid());
285
286   CreateDelegatedFrameHostClient();
287
288   host()->SetView(this);
289
290   // We should start observing the TextInputManager for IME-related events as
291   // well as monitoring its lifetime.
292   if (GetTextInputManager())
293     GetTextInputManager()->AddObserver(this);
294
295   cursor_manager_ = std::make_unique<CursorManager>(this);
296
297   selection_controller_client_ =
298       std::make_unique<TouchSelectionControllerClientAura>(this);
299   CreateSelectionController();
300
301   RenderWidgetHostOwnerDelegate* owner_delegate = host()->owner_delegate();
302   if (owner_delegate) {
303     // NOTE: This will not be run for child frame widgets, which do not have
304     // an owner delegate and won't get a RenderViewHost here.
305     double_tap_to_zoom_enabled_ =
306         owner_delegate->GetWebkitPreferencesForWidget()
307             .double_tap_to_zoom_enabled;
308   }
309
310   host()->render_frame_metadata_provider()->AddObserver(this);
311
312 #if BUILDFLAG(IS_EFL)
313   efl_helper_ =
314       base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableOffscreenRendering)
315       ? std::make_unique<RWHVAuraOffscreenHelperEfl>(this, &web_contents)
316       : std::make_unique<RWHVAuraCommonHelperEfl>(this, &web_contents);
317 #endif
318 }
319
320 ////////////////////////////////////////////////////////////////////////////////
321 // RenderWidgetHostViewAura, RenderWidgetHostView implementation:
322
323 void RenderWidgetHostViewAura::InitAsChild(gfx::NativeView parent_view) {
324   DCHECK_EQ(widget_type_, WidgetType::kFrame);
325   CreateAuraWindow(aura::client::WINDOW_TYPE_CONTROL);
326
327   if (parent_view)
328     parent_view->AddChild(GetNativeView());
329
330 #if BUILDFLAG(IS_EFL)
331   efl_helper_->SetAuraParentWindow(parent_view);
332 #endif
333
334   device_scale_factor_ = GetDeviceScaleFactor();
335
336   aura::Window* root = window_->GetRootWindow();
337   if (root) {
338     auto* cursor_client = aura::client::GetCursorClient(root);
339     if (cursor_client)
340       UpdateSystemCursorSize(cursor_client->GetSystemCursorSize());
341   }
342
343 #if BUILDFLAG(IS_WIN)
344   // This will fetch and set the display features.
345   EnsureDevicePostureServiceConnection();
346 #endif
347 }
348
349 void RenderWidgetHostViewAura::InitAsPopup(
350     RenderWidgetHostView* parent_host_view,
351     const gfx::Rect& bounds_in_screen,
352     const gfx::Rect& anchor_rect) {
353   DCHECK_EQ(widget_type_, WidgetType::kPopup);
354   DCHECK(!static_cast<RenderWidgetHostViewBase*>(parent_host_view)
355               ->IsRenderWidgetHostViewChildFrame());
356
357   popup_parent_host_view_ =
358       static_cast<RenderWidgetHostViewAura*>(parent_host_view);
359
360   // TransientWindowClient may be NULL during tests.
361   aura::client::TransientWindowClient* transient_window_client =
362       aura::client::GetTransientWindowClient();
363   RenderWidgetHostViewAura* old_child =
364       popup_parent_host_view_->popup_child_host_view_;
365   if (old_child) {
366     // TODO(jhorwich): Allow multiple popup_child_host_view_ per view, or
367     // similar mechanism to ensure a second popup doesn't cause the first one
368     // to never get a chance to filter events. See crbug.com/160589.
369     DCHECK(old_child->popup_parent_host_view_ == popup_parent_host_view_);
370     if (transient_window_client) {
371       transient_window_client->RemoveTransientChild(
372         popup_parent_host_view_->window_, old_child->window_);
373     }
374     old_child->popup_parent_host_view_ = nullptr;
375   }
376   popup_parent_host_view_->SetPopupChild(this);
377   CreateAuraWindow(aura::client::WINDOW_TYPE_MENU);
378   // Use transparent background color for the popup in order to avoid flashing
379   // the white background on popup open when dark color-scheme is used.
380   SetContentBackgroundColor(SK_ColorTRANSPARENT);
381
382   // Setting the transient child allows for the popup to get mouse events when
383   // in a system modal dialog. Do this before calling ParentWindowWithContext
384   // below so that the transient parent is visible to WindowTreeClient.
385   // This fixes crbug.com/328593.
386   if (transient_window_client) {
387     transient_window_client->AddTransientChild(
388         popup_parent_host_view_->window_, window_);
389   }
390
391   ui::OwnedWindowAnchor owned_window_anchor = {
392       anchor_rect, ui::OwnedWindowAnchorPosition::kBottomLeft,
393       ui::OwnedWindowAnchorGravity::kBottomRight,
394       ui::OwnedWindowConstraintAdjustment::kAdjustmentFlipY};
395   window_->SetProperty(aura::client::kOwnedWindowAnchor, owned_window_anchor);
396
397   aura::Window* root = popup_parent_host_view_->window_->GetRootWindow();
398   aura::client::ParentWindowWithContext(window_, root, bounds_in_screen,
399                                         display::kInvalidDisplayId);
400
401   SetBounds(bounds_in_screen);
402   Show();
403   if (NeedsMouseCapture())
404     window_->SetCapture();
405
406   event_observer_for_popup_exit_ =
407       std::make_unique<EventObserverForPopupExit>(this);
408
409   device_scale_factor_ = GetDeviceScaleFactor();
410
411   // If HiDPI capture mode is active for the parent, propagate the scale
412   // override to the popup window also. Its content was created assuming
413   // that the new window will share the parent window's scale. See
414   // https://crbug.com/1354703 .
415   SetScaleOverrideForCapture(
416       popup_parent_host_view_->GetScaleOverrideForCapture());
417
418   auto* cursor_client = aura::client::GetCursorClient(root);
419   if (cursor_client)
420     UpdateSystemCursorSize(cursor_client->GetSystemCursorSize());
421
422 #if BUILDFLAG(IS_WIN)
423   // This will fetch and set the display features.
424   EnsureDevicePostureServiceConnection();
425 #endif
426 }
427
428 void RenderWidgetHostViewAura::Hide() {
429   window_->Hide();
430   visibility_ = Visibility::HIDDEN;
431   HideImpl();
432 }
433
434 void RenderWidgetHostViewAura::SetSize(const gfx::Size& size) {
435   // For a SetSize operation, we don't care what coordinate system the origin
436   // of the window is in, it's only important to make sure that the origin
437   // remains constant after the operation.
438   InternalSetBounds(gfx::Rect(window_->bounds().origin(), size));
439 }
440
441 void RenderWidgetHostViewAura::SetBounds(const gfx::Rect& rect) {
442   gfx::Point relative_origin(rect.origin());
443
444   // RenderWidgetHostViewAura::SetBounds() takes screen coordinates, but
445   // Window::SetBounds() takes parent coordinates, so do the conversion here.
446   aura::Window* root = window_->GetRootWindow();
447   if (root) {
448     aura::client::ScreenPositionClient* screen_position_client =
449         aura::client::GetScreenPositionClient(root);
450     if (screen_position_client) {
451       screen_position_client->ConvertPointFromScreen(window_->parent(),
452                                                      &relative_origin);
453     }
454   }
455
456   InternalSetBounds(gfx::Rect(relative_origin, rect.size()));
457 }
458
459 gfx::NativeView RenderWidgetHostViewAura::GetNativeView() {
460   return window_;
461 }
462
463 #if BUILDFLAG(IS_WIN)
464 HWND RenderWidgetHostViewAura::GetHostWindowHWND() const {
465   aura::WindowTreeHost* host = window_->GetHost();
466   return host ? host->GetAcceleratedWidget() : nullptr;
467 }
468 #endif
469
470 gfx::NativeViewAccessible RenderWidgetHostViewAura::GetNativeViewAccessible() {
471 #if BUILDFLAG(IS_WIN)
472   aura::WindowTreeHost* window_host = window_->GetHost();
473   if (!window_host)
474     return static_cast<gfx::NativeViewAccessible>(NULL);
475
476   BrowserAccessibilityManager* manager =
477       host()->GetOrCreateRootBrowserAccessibilityManager();
478   if (manager)
479     return ToBrowserAccessibilityWin(manager->GetBrowserAccessibilityRoot())
480         ->GetCOM();
481
482 #elif BUILDFLAG(IS_LINUX)
483   BrowserAccessibilityManager* manager =
484       host()->GetOrCreateRootBrowserAccessibilityManager();
485   if (manager && manager->GetBrowserAccessibilityRoot())
486     return manager->GetBrowserAccessibilityRoot()->GetNativeViewAccessible();
487 #endif
488
489   NOTIMPLEMENTED_LOG_ONCE();
490   return static_cast<gfx::NativeViewAccessible>(nullptr);
491 }
492
493 ui::TextInputClient* RenderWidgetHostViewAura::GetTextInputClient() {
494   return this;
495 }
496
497 RenderFrameHostImpl* RenderWidgetHostViewAura::GetFocusedFrame() const {
498   FrameTreeNode* focused_frame = host()->frame_tree()->GetFocusedFrame();
499   if (!focused_frame)
500     return nullptr;
501   return focused_frame->current_frame_host();
502 }
503
504 void RenderWidgetHostViewAura::HandleBoundsInRootChanged() {
505 #if BUILDFLAG(IS_WIN)
506   if (legacy_render_widget_host_HWND_) {
507     legacy_render_widget_host_HWND_->SetBounds(
508         window_->GetBoundsInRootWindow());
509   }
510 #endif
511   if (!in_shutdown_) {
512     // Send screen rects through the delegate if there is one. Not every
513     // RenderWidgetHost has a delegate (for example, drop-down widgets).
514     if (host_->delegate())
515       host_->delegate()->SendScreenRects();
516     else
517       host_->SendScreenRects();
518   }
519
520   UpdateInsetsWithVirtualKeyboardEnabled();
521 }
522
523 void RenderWidgetHostViewAura::ParentHierarchyChanged() {
524   if (window_->parent()) {
525     // Track changes of the window relative to the root. This is done to snap
526     // `window_` to a pixel boundary, which could change when the bounds
527     // relative to the root changes. An example where this happens:
528     // The fast resize code path for bookmarks where in the parent of RWHVA
529     // which is WCV has its bounds changed before the bookmark is hidden. This
530     // results in the traditional bounds change notification for the WCV
531     // reporting the old bounds as the bookmark is still around. Observing all
532     // the ancestors of the RWHVA window enables us to know when the bounds of
533     // the window relative to root changes and allows us to snap accordingly.
534     position_in_root_observer_ =
535         std::make_unique<aura_extra::WindowPositionInRootMonitor>(
536             window_->parent(),
537             base::BindRepeating(
538                 &RenderWidgetHostViewAura::HandleBoundsInRootChanged,
539                 base::Unretained(this)));
540   } else {
541     position_in_root_observer_.reset();
542   }
543   // Snap when we receive a hierarchy changed. http://crbug.com/388908.
544   HandleBoundsInRootChanged();
545 }
546
547 void RenderWidgetHostViewAura::Focus() {
548   // Make sure we have a FocusClient before attempting to Focus(). In some
549   // situations we may not yet be in a valid Window hierarchy (such as reloading
550   // after out of memory discarded the tab).
551   aura::client::FocusClient* client = aura::client::GetFocusClient(window_);
552   if (client)
553     window_->Focus();
554
555 #if BUILDFLAG(IS_EFL)
556   if (!efl_helper_->HasFocus())
557     efl_helper_->Focus(true);
558 #endif
559 }
560
561 bool RenderWidgetHostViewAura::HasFocus() {
562   return window_->HasFocus();
563 }
564
565 bool RenderWidgetHostViewAura::IsSurfaceAvailableForCopy() {
566   DCHECK(delegated_frame_host_) << "Cannot be invoked during destruction.";
567   return delegated_frame_host_->CanCopyFromCompositingSurface();
568 }
569
570 #if BUILDFLAG(IS_EFL)
571 void RenderWidgetHostViewAura::BackgroundColorReceived(int callback_id,
572                                                        SkColor bg_color) {
573   efl_helper_->BackgroundColorReceived(callback_id, bg_color);
574 }
575
576 void RenderWidgetHostViewAura::DidGetContentSnapshot(const SkBitmap& bitmap,
577                                                      int request_id) {
578   efl_helper_->DidGetContentSnapshot(bitmap, request_id);
579 }
580
581 void RenderWidgetHostViewAura::DidHandleKeyEvent(
582     blink::WebInputEvent::Type input_event_type,
583     bool processed) {
584   efl_helper_->DidHandleKeyEvent(input_event_type, processed);
585 }
586
587 void RenderWidgetHostViewAura::SelectionChanged(const std::u16string& text,
588                                                 size_t offset,
589                                                 const gfx::Range& range) {
590   RenderWidgetHostViewBase::SelectionChanged(text, offset, range);
591   efl_helper_->SelectionChanged(text, offset, range);
592 }
593
594 void RenderWidgetHostViewAura::TextInputStateChanged(
595     const ui::mojom::TextInputState& params) {
596   RenderWidgetHostViewBase::TextInputStateChanged(params);
597   efl_helper_->TextInputStateChanged(params);
598 }
599 #endif
600
601 void RenderWidgetHostViewAura::EnsureSurfaceSynchronizedForWebTest() {
602   ++latest_capture_sequence_number_;
603   SynchronizeVisualProperties(cc::DeadlinePolicy::UseInfiniteDeadline(),
604                               absl::nullopt);
605 }
606
607 bool RenderWidgetHostViewAura::IsShowing() {
608   return window_->IsVisible();
609 }
610
611 void RenderWidgetHostViewAura::WasUnOccluded() {
612   ShowImpl(PageVisibilityState::kVisible);
613 }
614
615 void RenderWidgetHostViewAura::ShowImpl(PageVisibilityState page_visibility) {
616   // OnShowWithPageVisibility will not call NotifyHostAndDelegateOnWasShown,
617   // which updates `visibility_`, unless the host is hidden. Make sure no update
618   // is needed.
619   DCHECK(host_->is_hidden() || visibility_ == Visibility::VISIBLE);
620   OnShowWithPageVisibility(page_visibility);
621 }
622
623 void RenderWidgetHostViewAura::NotifyHostAndDelegateOnWasShown(
624     blink::mojom::RecordContentToVisibleTimeRequestPtr tab_switch_start_state) {
625   DCHECK(delegated_frame_host_) << "Cannot be invoked during destruction.";
626   DCHECK(host_->is_hidden());
627   DCHECK_NE(visibility_, Visibility::VISIBLE);
628
629   auto* wth = window()->GetHost();
630   if (wth && allocate_local_surface_id_on_next_show_) {
631     wth->window()->AllocateLocalSurfaceId();
632     wth->compositor()->SetLocalSurfaceIdFromParent(
633         wth->window()->GetLocalSurfaceId());
634   }
635   allocate_local_surface_id_on_next_show_ = false;
636
637   visibility_ = Visibility::VISIBLE;
638
639   bool has_saved_frame = delegated_frame_host_->HasSavedFrame();
640
641   bool show_reason_bfcache_restore =
642       tab_switch_start_state
643           ? tab_switch_start_state->show_reason_bfcache_restore
644           : false;
645
646   // No need to check for saved frames for the case of bfcache restore.
647   if (show_reason_bfcache_restore) {
648     host()->WasShown(tab_switch_start_state.Clone());
649   } else {
650     host()->WasShown(has_saved_frame
651                          ? blink::mojom::RecordContentToVisibleTimeRequestPtr()
652                          : tab_switch_start_state.Clone());
653   }
654   aura::Window* root = window_->GetRootWindow();
655   if (root) {
656     aura::client::CursorClient* cursor_client =
657         aura::client::GetCursorClient(root);
658     if (cursor_client) {
659       NotifyRendererOfCursorVisibilityState(cursor_client->IsCursorVisible());
660     }
661   }
662
663   // If the frame for the renderer is already available, then the
664   // tab-switching time is the presentation time for the browser-compositor.
665   delegated_frame_host_->WasShown(
666       GetLocalSurfaceId(), window_->bounds().size(),
667       has_saved_frame ? std::move(tab_switch_start_state)
668                       : blink::mojom::RecordContentToVisibleTimeRequestPtr());
669
670 #if BUILDFLAG(IS_WIN)
671   UpdateLegacyWin();
672 #endif
673 }
674
675 void RenderWidgetHostViewAura::HideImpl() {
676   DCHECK(delegated_frame_host_) << "Cannot be invoked during destruction.";
677   DCHECK(visibility_ == Visibility::HIDDEN ||
678          visibility_ == Visibility::OCCLUDED);
679
680 #if BUILDFLAG(IS_EFL)
681   efl_helper_->Hide();
682 #endif
683
684   if (!host()->is_hidden()) {
685     host()->WasHidden();
686     aura::WindowTreeHost* host = window_->GetHost();
687       aura::Window* parent = window_->parent();
688       aura::Window::OcclusionState parent_occl_state =
689           parent ? parent->GetOcclusionState()
690                  : aura::Window::OcclusionState::UNKNOWN;
691       aura::Window::OcclusionState native_win_occlusion_state =
692           host ? host->GetNativeWindowOcclusionState()
693                : aura::Window::OcclusionState::UNKNOWN;
694       DelegatedFrameHost::HiddenCause cause;
695       if (parent_occl_state == aura::Window::OcclusionState::OCCLUDED &&
696           native_win_occlusion_state ==
697               aura::Window::OcclusionState::OCCLUDED) {
698         cause = DelegatedFrameHost::HiddenCause::kOccluded;
699       } else {
700         cause = DelegatedFrameHost::HiddenCause::kOther;
701       }
702       delegated_frame_host_->WasHidden(cause);
703 #if BUILDFLAG(IS_WIN)
704       if (host) {
705         // We reparent the legacy Chrome_RenderWidgetHostHWND window to the
706         // global hidden window on the same lines as Windowed plugin windows.
707         if (legacy_render_widget_host_HWND_)
708           legacy_render_widget_host_HWND_->UpdateParent(ui::GetHiddenWindow());
709       }
710 #endif
711   }
712
713 #if BUILDFLAG(IS_WIN)
714   if (legacy_render_widget_host_HWND_)
715     legacy_render_widget_host_HWND_->Hide();
716 #endif
717 }
718
719 void RenderWidgetHostViewAura::WasOccluded() {
720   visibility_ = Visibility::OCCLUDED;
721   HideImpl();
722 }
723
724 void RenderWidgetHostViewAura::
725     RequestSuccessfulPresentationTimeFromHostOrDelegate(
726         blink::mojom::RecordContentToVisibleTimeRequestPtr
727             visible_time_request) {
728   DCHECK(delegated_frame_host_) << "Cannot be invoked during destruction.";
729   DCHECK(!host_->is_hidden());
730   DCHECK_EQ(visibility_, Visibility::VISIBLE);
731   DCHECK(visible_time_request);
732
733   bool has_saved_frame = delegated_frame_host_->HasSavedFrame();
734
735   // No need to check for saved frames for the case of bfcache restore.
736   if (visible_time_request->show_reason_bfcache_restore || !has_saved_frame) {
737     host()->RequestSuccessfulPresentationTimeForNextFrame(
738         visible_time_request.Clone());
739   }
740
741   // If the frame for the renderer is already available, then the
742   // tab-switching time is the presentation time for the browser-compositor.
743   if (has_saved_frame) {
744     delegated_frame_host_->RequestSuccessfulPresentationTimeForNextFrame(
745         std::move(visible_time_request));
746   }
747 }
748
749 void RenderWidgetHostViewAura::
750     CancelSuccessfulPresentationTimeRequestForHostAndDelegate() {
751   DCHECK(delegated_frame_host_) << "Cannot be invoked during destruction.";
752   DCHECK(!host_->is_hidden());
753   DCHECK_EQ(visibility_, Visibility::VISIBLE);
754
755   host()->CancelSuccessfulPresentationTimeRequest();
756   delegated_frame_host_->CancelSuccessfulPresentationTimeRequest();
757 }
758
759 bool RenderWidgetHostViewAura::ShouldSkipCursorUpdate() const {
760   aura::Window* root_window = window_->GetRootWindow();
761   DCHECK(root_window);
762   display::Screen* screen = display::Screen::GetScreen();
763   DCHECK(screen);
764
765   // Ignore cursor update messages if the window under the cursor is not us.
766 #if BUILDFLAG(IS_WIN)
767   gfx::Point cursor_screen_point = screen->GetCursorScreenPoint();
768   aura::Window* window_at_screen_point =
769       screen->GetWindowAtScreenPoint(cursor_screen_point);
770   // On Windows we may fail to retrieve the aura Window at the current cursor
771   // position. This is because the WindowFromPoint API may return the legacy
772   // window which is not associated with an aura Window. In this case we need
773   // to get the aura window for the parent of the legacy window.
774   if (!window_at_screen_point && legacy_render_widget_host_HWND_) {
775     HWND hwnd_at_point = ::WindowFromPoint(cursor_screen_point.ToPOINT());
776
777     if (hwnd_at_point == legacy_render_widget_host_HWND_->hwnd())
778       hwnd_at_point = legacy_render_widget_host_HWND_->GetParent();
779
780     display::win::ScreenWin* screen_win =
781         static_cast<display::win::ScreenWin*>(screen);
782     window_at_screen_point = screen_win->GetNativeWindowFromHWND(hwnd_at_point);
783   }
784   if (!window_at_screen_point ||
785       (window_at_screen_point->GetRootWindow() != root_window)) {
786     return true;
787   }
788 #elif !BUILDFLAG(IS_CHROMEOS_ASH)
789   if (!screen->IsWindowUnderCursor(root_window))
790     return true;
791 #endif  // !BUILDFLAG(IS_CHROMEOS_ASH)
792   return false;
793 }
794
795 bool RenderWidgetHostViewAura::ShouldShowStaleContentOnEviction() {
796   return host() && host()->ShouldShowStaleContentOnEviction();
797 }
798
799 gfx::Rect RenderWidgetHostViewAura::GetViewBounds() {
800 #if BUILDFLAG(IS_EFL)
801   if (offscreen_helper())
802     return offscreen_helper()->GetViewBounds();
803 #endif
804   return window_->GetBoundsInScreen();
805 }
806
807 void RenderWidgetHostViewAura::UpdateBackgroundColor() {
808   DCHECK(GetBackgroundColor());
809
810   SkColor color = *GetBackgroundColor();
811   // Set transparent bg for Browser process
812   if (color == SK_ColorTRANSPARENT && GetCompositor()) {
813     GetCompositor()->SetBackgroundColor(SK_ColorTRANSPARENT);
814   }
815
816   bool opaque = SkColorGetA(color) == SK_AlphaOPAQUE;
817   window_->layer()->SetFillsBoundsOpaquely(opaque);
818   window_->layer()->SetColor(color);
819 }
820
821 #if BUILDFLAG(IS_WIN)
822 void RenderWidgetHostViewAura::EnsureDevicePostureServiceConnection() {
823   if (device_posture_provider_.is_bound() &&
824       device_posture_provider_.is_connected()) {
825     return;
826   }
827   GetDeviceService().BindDevicePostureProvider(
828       device_posture_provider_.BindNewPipeAndPassReceiver());
829   device_posture_provider_->AddListenerAndGetCurrentViewportSegments(
830       device_posture_receiver_.BindNewPipeAndPassRemote(),
831       base::BindOnce(&RenderWidgetHostViewAura::OnViewportSegmentsChanged,
832                      base::Unretained(this)));
833 }
834 #endif
835
836 void RenderWidgetHostViewAura::OnViewportSegmentsChanged(
837     const std::vector<gfx::Rect>& segments) {
838   display_feature_ = absl::nullopt;
839   viewport_segments_.clear();
840   if (segments.empty()) {
841     SynchronizeVisualProperties(cc::DeadlinePolicy::UseDefaultDeadline(),
842                                 window_->GetLocalSurfaceId());
843     return;
844   }
845
846   if (segments.size() >= 2) {
847     viewport_segments_ = std::move(segments);
848     ComputeDisplayFeature();
849   }
850   SynchronizeVisualProperties(cc::DeadlinePolicy::UseDefaultDeadline(),
851                               window_->GetLocalSurfaceId());
852 }
853
854 void RenderWidgetHostViewAura::ComputeDisplayFeature() {
855   if (viewport_segments_.size() < 2) {
856     return;
857   }
858
859   display_feature_ = absl::nullopt;
860   if (!window_->GetRootWindow()) {
861     return;
862   }
863
864   const display::Display display =
865       display::Screen::GetScreen()->GetDisplayNearestWindow(window_);
866   // Set the display feature only if the browser window is maximized or
867   // fullscreen.
868   if (window_->GetRootWindow()->GetBoundsInScreen() != display.work_area() &&
869       window_->GetRootWindow()->GetBoundsInScreen() != display.bounds()) {
870     return;
871   }
872
873   float dip_scale = 1 / device_scale_factor_;
874   // Segments coming from the platform are in native resolution.
875   gfx::Rect transformed_display_feature =
876       gfx::ScaleToRoundedRect(viewport_segments_[1], dip_scale);
877   transformed_display_feature.Offset(-GetViewBounds().x(),
878                                      -GetViewBounds().y());
879   transformed_display_feature.Intersect(gfx::Rect(GetVisibleViewportSize()));
880   if (transformed_display_feature.x() == 0) {
881     display_feature_ = {DisplayFeature::Orientation::kHorizontal,
882                         transformed_display_feature.y(),
883                         transformed_display_feature.height()};
884   } else if (transformed_display_feature.y() == 0) {
885     display_feature_ = {DisplayFeature::Orientation::kVertical,
886                         transformed_display_feature.x(),
887                         transformed_display_feature.width()};
888   }
889 }
890
891 absl::optional<DisplayFeature> RenderWidgetHostViewAura::GetDisplayFeature() {
892   return display_feature_;
893 }
894
895 void RenderWidgetHostViewAura::SetDisplayFeatureForTesting(
896     const DisplayFeature* display_feature) {
897   if (display_feature)
898     display_feature_ = *display_feature;
899   else
900     display_feature_ = absl::nullopt;
901 }
902
903 void RenderWidgetHostViewAura::WindowTitleChanged() {
904   DCHECK(delegated_frame_host_) << "Cannot be invoked during destruction.";
905   delegated_frame_host_->WindowTitleChanged(
906       base::UTF16ToUTF8(window_->GetTitle()));
907 }
908
909 bool RenderWidgetHostViewAura::IsMouseLocked() {
910   return event_handler_->mouse_locked();
911 }
912
913 gfx::Size RenderWidgetHostViewAura::GetVisibleViewportSize() {
914 #if BUILDFLAG(IS_EFL)
915   if (efl_helper_->IsOffscreenMode())
916     return efl_helper_->GetVisibleViewportSize();
917 #endif
918   gfx::Rect requested_rect(GetRequestedRendererSize());
919   requested_rect.Inset(insets_);
920   return requested_rect.size();
921 }
922
923 void RenderWidgetHostViewAura::SetInsets(const gfx::Insets& insets) {
924   TRACE_EVENT0("vk", "RenderWidgetHostViewAura::SetInsets");
925   if (insets != insets_) {
926     insets_ = insets;
927     window_->AllocateLocalSurfaceId();
928     if (!insets.IsEmpty()) {
929       inset_surface_id_ = window_->GetLocalSurfaceId();
930     } else {
931       inset_surface_id_ = viz::LocalSurfaceId();
932     }
933     SynchronizeVisualProperties(cc::DeadlinePolicy::UseDefaultDeadline(),
934                                 window_->GetLocalSurfaceId());
935   }
936 }
937
938 void RenderWidgetHostViewAura::UpdateCursor(const ui::Cursor& cursor) {
939   GetCursorManager()->UpdateCursor(this, cursor);
940 }
941
942 void RenderWidgetHostViewAura::DisplayCursor(const ui::Cursor& cursor) {
943   current_cursor_ = WebCursor(cursor);
944   const display::Display display =
945       display::Screen::GetScreen()->GetDisplayNearestWindow(window_);
946   current_cursor_.SetDisplayInfo(display);
947   UpdateCursorIfOverSelf();
948 }
949
950 CursorManager* RenderWidgetHostViewAura::GetCursorManager() {
951   return cursor_manager_.get();
952 }
953
954 void RenderWidgetHostViewAura::SetIsLoading(bool is_loading) {
955   is_loading_ = is_loading;
956   UpdateCursorIfOverSelf();
957 }
958
959 void RenderWidgetHostViewAura::RenderProcessGone() {
960   UpdateCursorIfOverSelf();
961   Destroy();
962 }
963
964 void RenderWidgetHostViewAura::ShowWithVisibility(
965     PageVisibilityState page_visibility) {
966   // Make sure we grab updated ScreenInfos before synchronizing visual
967   // properties, in case they have changed or this is the initial show.
968   UpdateScreenInfo();
969
970 #if BUILDFLAG(IS_EFL)
971   efl_helper_->Show();
972 #endif
973
974   // If the viz::LocalSurfaceId is invalid, we may have been evicted,
975   // and no other visual properties have since been changed. Allocate a new id
976   // and start synchronizing.
977   if (!window_->GetLocalSurfaceId().is_valid()) {
978     window_->AllocateLocalSurfaceId();
979     SynchronizeVisualProperties(cc::DeadlinePolicy::UseDefaultDeadline(),
980                                 window_->GetLocalSurfaceId());
981   }
982
983   window_->Show();
984   ShowImpl(page_visibility);
985 #if BUILDFLAG(IS_WIN)
986   if (page_visibility != PageVisibilityState::kVisible &&
987       legacy_render_widget_host_HWND_) {
988     legacy_render_widget_host_HWND_->Hide();
989   }
990 #endif  // BUILDFLAG(IS_WIN)
991 }
992
993 void RenderWidgetHostViewAura::Destroy() {
994   // Beware, this function is not called on all destruction paths. If |window_|
995   // has been created, then it will implicitly end up calling
996   // ~RenderWidgetHostViewAura when |window_| is destroyed. Otherwise, The
997   // destructor is invoked directly from here. So all destruction/cleanup code
998   // should happen there, not here.
999   in_shutdown_ = true;
1000   // Call this here in case any observers need access to `this` before we
1001   // destruct the derived class.
1002   NotifyObserversAboutShutdown();
1003
1004   if (window_)
1005     delete window_;
1006   else
1007     delete this;
1008 }
1009
1010 void RenderWidgetHostViewAura::UpdateTooltipUnderCursor(
1011     const std::u16string& tooltip_text) {
1012   if (GetCursorManager()->IsViewUnderCursor(this))
1013     UpdateTooltip(tooltip_text);
1014 }
1015
1016 void RenderWidgetHostViewAura::UpdateTooltip(
1017     const std::u16string& tooltip_text) {
1018   SetTooltipText(tooltip_text);
1019
1020   wm::TooltipClient* tooltip_client =
1021       wm::GetTooltipClient(window_->GetRootWindow());
1022   if (tooltip_client) {
1023     // Content tooltips should be visible indefinitely.
1024     tooltip_client->SetHideTooltipTimeout(window_, {});
1025     tooltip_client->UpdateTooltip(window_);
1026   }
1027 }
1028
1029 void RenderWidgetHostViewAura::UpdateTooltipFromKeyboard(
1030     const std::u16string& tooltip_text,
1031     const gfx::Rect& bounds) {
1032   SetTooltipText(tooltip_text);
1033
1034   wm::TooltipClient* tooltip_client =
1035       wm::GetTooltipClient(window_->GetRootWindow());
1036   if (tooltip_client) {
1037     // Content tooltips should be visible indefinitely.
1038     tooltip_client->SetHideTooltipTimeout(window_, {});
1039     tooltip_client->UpdateTooltipFromKeyboard(bounds, window_);
1040   }
1041 }
1042
1043 void RenderWidgetHostViewAura::ClearKeyboardTriggeredTooltip() {
1044   if (!window_ || !window_->GetHost())
1045     return;
1046
1047   wm::TooltipClient* tooltip_client =
1048       wm::GetTooltipClient(window_->GetRootWindow());
1049   if (!tooltip_client || !tooltip_client->IsTooltipSetFromKeyboard(window_))
1050     return;
1051
1052   SetTooltipText(std::u16string());
1053   tooltip_client->UpdateTooltipFromKeyboard(gfx::Rect(), window_);
1054 }
1055
1056 uint32_t RenderWidgetHostViewAura::GetCaptureSequenceNumber() const {
1057   return latest_capture_sequence_number_;
1058 }
1059
1060 void RenderWidgetHostViewAura::CopyFromSurface(
1061     const gfx::Rect& src_subrect,
1062     const gfx::Size& dst_size,
1063     base::OnceCallback<void(const SkBitmap&)> callback) {
1064   base::WeakPtr<RenderWidgetHostImpl> popup_host;
1065   base::WeakPtr<DelegatedFrameHost> popup_frame_host;
1066   if (popup_child_host_view_) {
1067     popup_host = popup_child_host_view_->host()->GetWeakPtr();
1068     popup_frame_host =
1069         popup_child_host_view_->GetDelegatedFrameHost()->GetWeakPtr();
1070   }
1071   RenderWidgetHostViewBase::CopyMainAndPopupFromSurface(
1072       host()->GetWeakPtr(), delegated_frame_host_->GetWeakPtr(), popup_host,
1073       popup_frame_host, src_subrect, dst_size, device_scale_factor_,
1074       std::move(callback));
1075 }
1076
1077 #if BUILDFLAG(IS_WIN)
1078 bool RenderWidgetHostViewAura::UsesNativeWindowFrame() const {
1079   return (legacy_render_widget_host_HWND_ != nullptr);
1080 }
1081
1082 void RenderWidgetHostViewAura::UpdateMouseLockRegion() {
1083   RECT window_rect =
1084       display::Screen::GetScreen()
1085           ->DIPToScreenRectInWindow(window_, window_->GetBoundsInScreen())
1086           .ToRECT();
1087   ::ClipCursor(&window_rect);
1088 }
1089
1090 void RenderWidgetHostViewAura::OnLegacyWindowDestroyed() {
1091   legacy_render_widget_host_HWND_ = nullptr;
1092   legacy_window_destroyed_ = true;
1093 }
1094 #endif
1095
1096 gfx::NativeViewAccessible
1097 RenderWidgetHostViewAura::GetParentNativeViewAccessible() {
1098   // If a popup_parent_host_view_ exists, that means we are in a popup (such as
1099   // datetime) and our accessible parent window is popup_parent_host_view_
1100   if (popup_parent_host_view_) {
1101     DCHECK_EQ(widget_type_, WidgetType::kPopup);
1102     return popup_parent_host_view_->GetParentNativeViewAccessible();
1103   }
1104
1105   if (window_->parent()) {
1106     return window_->parent()->GetProperty(
1107         aura::client::kParentNativeViewAccessibleKey);
1108   }
1109
1110   return nullptr;
1111 }
1112
1113 void RenderWidgetHostViewAura::ClearFallbackSurfaceForCommitPending() {
1114   delegated_frame_host_->ClearFallbackSurfaceForCommitPending();
1115   window_->InvalidateLocalSurfaceId();
1116 }
1117
1118 void RenderWidgetHostViewAura::ResetFallbackToFirstNavigationSurface() {
1119   DCHECK(delegated_frame_host_) << "Cannot be invoked during destruction.";
1120   delegated_frame_host_->ResetFallbackToFirstNavigationSurface();
1121 }
1122
1123 bool RenderWidgetHostViewAura::RequestRepaintForTesting() {
1124   return SynchronizeVisualProperties(cc::DeadlinePolicy::UseDefaultDeadline(),
1125                                      absl::nullopt);
1126 }
1127
1128 void RenderWidgetHostViewAura::DidStopFlinging() {
1129   selection_controller_client_->OnScrollCompleted();
1130 }
1131
1132 void RenderWidgetHostViewAura::TransformPointToRootSurface(gfx::PointF* point) {
1133   aura::Window* root = window_->GetRootWindow();
1134   aura::Window::ConvertPointToTarget(window_, root, point);
1135   *point = root->GetRootWindow()->transform().MapPoint(*point);
1136 }
1137
1138 gfx::Rect RenderWidgetHostViewAura::GetBoundsInRootWindow() {
1139   aura::Window* top_level = window_->GetToplevelWindow();
1140   gfx::Rect bounds(top_level->GetBoundsInScreen());
1141
1142 #if BUILDFLAG(IS_WIN)
1143   // TODO(zturner,iyengar): This will break when we remove support for NPAPI and
1144   // remove the legacy hwnd, so a better fix will need to be decided when that
1145   // happens.
1146   if (UsesNativeWindowFrame()) {
1147     // aura::Window doesn't take into account non-client area of native windows
1148     // (e.g. HWNDs), so for that case ask Windows directly what the bounds are.
1149     aura::WindowTreeHost* host = top_level->GetHost();
1150     if (!host)
1151       return top_level->GetBoundsInScreen();
1152
1153     // If this is a headless window return the headless window bounds stored in
1154     // Aura window properties instead of the actual platform window bounds which
1155     // may be different.
1156     if (gfx::Rect* headless_bounds =
1157             host->window()->GetProperty(aura::client::kHeadlessBoundsKey)) {
1158       return *headless_bounds;
1159     }
1160
1161     RECT window_rect = {0};
1162     HWND hwnd = host->GetAcceleratedWidget();
1163     ::GetWindowRect(hwnd, &window_rect);
1164     bounds = gfx::Rect(window_rect);
1165
1166     // Maximized windows are outdented from the work area by the frame thickness
1167     // even though this "frame" is not painted.  This confuses code (and people)
1168     // that think of a maximized window as corresponding exactly to the work
1169     // area.  Correct for this by subtracting the frame thickness back off.
1170     if (::IsZoomed(hwnd)) {
1171       bounds.Inset(gfx::Insets::VH(GetSystemMetrics(SM_CYSIZEFRAME),
1172                                    GetSystemMetrics(SM_CXSIZEFRAME)));
1173       bounds.Inset(GetSystemMetrics(SM_CXPADDEDBORDER));
1174     }
1175
1176     // Pixels come back from GetWindowHost, so we need to convert those back to
1177     // DIPs here.
1178     bounds = display::Screen::GetScreen()->ScreenToDIPRectInWindow(top_level,
1179                                                                    bounds);
1180   }
1181
1182 #endif
1183
1184   return bounds;
1185 }
1186
1187 void RenderWidgetHostViewAura::WheelEventAck(
1188     const blink::WebMouseWheelEvent& event,
1189     blink::mojom::InputEventResultState ack_result) {
1190   if (overscroll_controller_) {
1191     overscroll_controller_->ReceivedEventACK(
1192         event, (blink::mojom::InputEventResultState::kConsumed == ack_result));
1193   }
1194 }
1195
1196 void RenderWidgetHostViewAura::DidOverscroll(
1197     const ui::DidOverscrollParams& params) {
1198   if (overscroll_controller_)
1199     overscroll_controller_->OnDidOverscroll(params);
1200 #if BUILDFLAG(IS_EFL)
1201   efl_helper_->DidOverscroll(params);
1202 #endif
1203 }
1204
1205 void RenderWidgetHostViewAura::GestureEventAck(
1206     const blink::WebGestureEvent& event,
1207     blink::mojom::InputEventResultState ack_result,
1208     blink::mojom::ScrollResultDataPtr scroll_result_data) {
1209   const blink::WebInputEvent::Type event_type = event.GetType();
1210   if (event_type == blink::WebGestureEvent::Type::kGestureScrollBegin ||
1211       event_type == blink::WebGestureEvent::Type::kGestureScrollEnd) {
1212     if (host()->delegate()) {
1213       host()->delegate()->SetTopControlsGestureScrollInProgress(
1214           event_type == blink::WebGestureEvent::Type::kGestureScrollBegin);
1215     }
1216   }
1217
1218   if (overscroll_controller_) {
1219     overscroll_controller_->ReceivedEventACK(
1220         event, (blink::mojom::InputEventResultState::kConsumed == ack_result));
1221     // Terminate an active fling when the ACK for a GSU generated from the fling
1222     // progress (GSU with inertial state) is consumed and the overscrolling mode
1223     // is not |OVERSCROLL_NONE|. The early fling termination generates a GSE
1224     // which completes the overscroll action. Without this change the overscroll
1225     // action would complete at the end of the active fling progress which
1226     // causes noticeable delay in cases that the fling velocity is large.
1227     // https://crbug.com/797855
1228     if (event_type == blink::WebInputEvent::Type::kGestureScrollUpdate &&
1229         event.data.scroll_update.inertial_phase ==
1230             blink::WebGestureEvent::InertialPhaseState::kMomentum &&
1231         overscroll_controller_->overscroll_mode() != OVERSCROLL_NONE) {
1232       StopFling();
1233     }
1234   }
1235
1236   // Stop flinging if a GSU event with momentum phase is sent to the renderer
1237   // but not consumed.
1238   StopFlingingIfNecessary(event, ack_result);
1239
1240   event_handler_->GestureEventAck(event, ack_result);
1241
1242   ForwardTouchpadZoomEventIfNecessary(event, ack_result);
1243 }
1244
1245 void RenderWidgetHostViewAura::ProcessAckedTouchEvent(
1246     const TouchEventWithLatencyInfo& touch,
1247     blink::mojom::InputEventResultState ack_result) {
1248   aura::WindowTreeHost* window_host = window_->GetHost();
1249   // |host| is NULL during tests.
1250   if (!window_host)
1251     return;
1252
1253   // The TouchScrollStarted event is generated & consumed downstream from the
1254   // TouchEventQueue. So we don't expect an ACK up here.
1255   DCHECK(touch.event.GetType() !=
1256          blink::WebInputEvent::Type::kTouchScrollStarted);
1257
1258   ui::EventResult result =
1259       (ack_result == blink::mojom::InputEventResultState::kConsumed)
1260           ? ui::ER_HANDLED
1261           : ui::ER_UNHANDLED;
1262
1263   blink::WebTouchPoint::State required_state;
1264   switch (touch.event.GetType()) {
1265     case blink::WebInputEvent::Type::kTouchStart:
1266       required_state = blink::WebTouchPoint::State::kStatePressed;
1267       break;
1268     case blink::WebInputEvent::Type::kTouchEnd:
1269       required_state = blink::WebTouchPoint::State::kStateReleased;
1270       break;
1271     case blink::WebInputEvent::Type::kTouchMove:
1272       required_state = blink::WebTouchPoint::State::kStateMoved;
1273       break;
1274     case blink::WebInputEvent::Type::kTouchCancel:
1275       required_state = blink::WebTouchPoint::State::kStateCancelled;
1276       break;
1277     default:
1278       required_state = blink::WebTouchPoint::State::kStateUndefined;
1279       NOTREACHED();
1280       break;
1281   }
1282
1283 #if BUILDFLAG(IS_EFL)
1284   if (touch.event.GetType() == blink::WebInputEvent::Type::kTouchStart)
1285     efl_helper_->SetTouchStartConsumed(result == ui::ER_HANDLED);
1286
1287   if (touch.event.GetType() == blink::WebInputEvent::Type::kTouchEnd)
1288     efl_helper_->SetTouchEndConsumed(result == ui::ER_HANDLED);
1289 #endif
1290
1291   // Only send acks for one changed touch point.
1292   bool sent_ack = false;
1293   for (size_t i = 0; i < touch.event.touches_length; ++i) {
1294     if (touch.event.touches[i].state == required_state) {
1295       DCHECK(!sent_ack);
1296       window_host->dispatcher()->ProcessedTouchEvent(
1297           touch.event.unique_touch_event_id, window_, result,
1298           InputEventResultStateIsSetBlocking(ack_result));
1299       if (touch.event.touch_start_or_first_touch_move &&
1300           result == ui::ER_HANDLED && host()->delegate() &&
1301           host()->delegate()->GetInputEventRouter()) {
1302         host()
1303             ->delegate()
1304             ->GetInputEventRouter()
1305             ->OnHandledTouchStartOrFirstTouchMove(
1306                 touch.event.unique_touch_event_id);
1307       }
1308       sent_ack = true;
1309     }
1310   }
1311 }
1312
1313 std::unique_ptr<SyntheticGestureTarget>
1314 RenderWidgetHostViewAura::CreateSyntheticGestureTarget() {
1315   return std::unique_ptr<SyntheticGestureTarget>(
1316       new SyntheticGestureTargetAura(host()));
1317 }
1318
1319 blink::mojom::InputEventResultState RenderWidgetHostViewAura::FilterInputEvent(
1320     const blink::WebInputEvent& input_event) {
1321   bool consumed = false;
1322   if (input_event.GetType() == WebInputEvent::Type::kGestureFlingStart) {
1323     const WebGestureEvent& gesture_event =
1324         static_cast<const WebGestureEvent&>(input_event);
1325     // Zero-velocity touchpad flings are an Aura-specific signal that the
1326     // touchpad scroll has ended, and should not be forwarded to the renderer.
1327     if (gesture_event.SourceDevice() == blink::WebGestureDevice::kTouchpad &&
1328         !gesture_event.data.fling_start.velocity_x &&
1329         !gesture_event.data.fling_start.velocity_y) {
1330       consumed = true;
1331     }
1332   }
1333
1334   if (overscroll_controller_)
1335     consumed |= overscroll_controller_->WillHandleEvent(input_event);
1336
1337   // Touch events should always propagate to the renderer.
1338   if (WebTouchEvent::IsTouchEventType(input_event.GetType()))
1339     return blink::mojom::InputEventResultState::kNotConsumed;
1340
1341   if (consumed &&
1342       input_event.GetType() == blink::WebInputEvent::Type::kGestureFlingStart) {
1343     // Here we indicate that there was no consumer for this event, as
1344     // otherwise the fling animation system will try to run an animation
1345     // and will also expect a notification when the fling ends. Since
1346     // CrOS just uses the GestureFlingStart with zero-velocity as a means
1347     // of indicating that touchpad scroll has ended, we don't actually want
1348     // a fling animation. Note: Similar code exists in
1349     // RenderWidgetHostViewChildFrame::FilterInputEvent()
1350     return blink::mojom::InputEventResultState::kNoConsumerExists;
1351   }
1352
1353   return consumed ? blink::mojom::InputEventResultState::kConsumed
1354                   : blink::mojom::InputEventResultState::kNotConsumed;
1355 }
1356
1357 gfx::AcceleratedWidget
1358 RenderWidgetHostViewAura::AccessibilityGetAcceleratedWidget() {
1359 #if BUILDFLAG(IS_WIN)
1360   if (legacy_render_widget_host_HWND_)
1361     return legacy_render_widget_host_HWND_->hwnd();
1362 #endif
1363   return gfx::kNullAcceleratedWidget;
1364 }
1365
1366 gfx::NativeViewAccessible
1367 RenderWidgetHostViewAura::AccessibilityGetNativeViewAccessible() {
1368 #if BUILDFLAG(IS_WIN)
1369   if (legacy_render_widget_host_HWND_) {
1370     return legacy_render_widget_host_HWND_->window_accessible();
1371   }
1372 #endif
1373
1374   if (window_->parent()) {
1375     return window_->parent()->GetProperty(
1376         aura::client::kParentNativeViewAccessibleKey);
1377   }
1378
1379   return nullptr;
1380 }
1381
1382 void RenderWidgetHostViewAura::SetMainFrameAXTreeID(ui::AXTreeID id) {
1383   window_->SetProperty(ui::kChildAXTreeID, id.ToString());
1384 }
1385
1386 blink::mojom::PointerLockResult RenderWidgetHostViewAura::LockMouse(
1387     bool request_unadjusted_movement) {
1388   return event_handler_->LockMouse(request_unadjusted_movement);
1389 }
1390
1391 blink::mojom::PointerLockResult RenderWidgetHostViewAura::ChangeMouseLock(
1392     bool request_unadjusted_movement) {
1393   return event_handler_->ChangeMouseLock(request_unadjusted_movement);
1394 }
1395
1396 void RenderWidgetHostViewAura::UnlockMouse() {
1397   event_handler_->UnlockMouse();
1398 }
1399
1400 bool RenderWidgetHostViewAura::GetIsMouseLockedUnadjustedMovementForTesting() {
1401   return event_handler_->mouse_locked_unadjusted_movement();
1402 }
1403
1404 bool RenderWidgetHostViewAura::LockKeyboard(
1405     absl::optional<base::flat_set<ui::DomCode>> codes) {
1406   return event_handler_->LockKeyboard(std::move(codes));
1407 }
1408
1409 void RenderWidgetHostViewAura::UnlockKeyboard() {
1410   event_handler_->UnlockKeyboard();
1411 }
1412
1413 bool RenderWidgetHostViewAura::IsKeyboardLocked() {
1414   return event_handler_->IsKeyboardLocked();
1415 }
1416
1417 base::flat_map<std::string, std::string>
1418 RenderWidgetHostViewAura::GetKeyboardLayoutMap() {
1419   aura::WindowTreeHost* host = window_->GetHost();
1420   if (host)
1421     return host->GetKeyboardLayoutMap();
1422   return {};
1423 }
1424
1425 ////////////////////////////////////////////////////////////////////////////////
1426 // RenderWidgetHostViewAura, ui::TextInputClient implementation:
1427 void RenderWidgetHostViewAura::SetCompositionText(
1428     const ui::CompositionText& composition) {
1429   if (!text_input_manager_ || !text_input_manager_->GetActiveWidget())
1430     return;
1431
1432   // TODO(suzhe): due to a bug of webkit, we can't use selection range with
1433   // composition string. See: https://bugs.webkit.org/show_bug.cgi?id=37788
1434   text_input_manager_->GetActiveWidget()->ImeSetComposition(
1435       composition.text, composition.ime_text_spans, gfx::Range::InvalidRange(),
1436       composition.selection.end(), composition.selection.end());
1437
1438   has_composition_text_ = !composition.text.empty();
1439 }
1440
1441 size_t RenderWidgetHostViewAura::ConfirmCompositionText(bool keep_selection) {
1442   if (text_input_manager_ && text_input_manager_->GetActiveWidget() &&
1443       has_composition_text_) {
1444     text_input_manager_->GetActiveWidget()->ImeFinishComposingText(
1445         keep_selection);
1446   }
1447   has_composition_text_ = false;
1448   // TODO(crbug/1109604): Return the number of characters committed by this
1449   // function.
1450   return std::numeric_limits<size_t>::max();
1451 }
1452
1453 void RenderWidgetHostViewAura::ClearCompositionText() {
1454   if (text_input_manager_ && text_input_manager_->GetActiveWidget() &&
1455       has_composition_text_)
1456     text_input_manager_->GetActiveWidget()->ImeCancelComposition();
1457   has_composition_text_ = false;
1458 }
1459
1460 void RenderWidgetHostViewAura::InsertText(
1461     const std::u16string& text,
1462     InsertTextCursorBehavior cursor_behavior) {
1463   DCHECK_NE(GetTextInputType(), ui::TEXT_INPUT_TYPE_NONE);
1464
1465   if (text_input_manager_ && text_input_manager_->GetActiveWidget()) {
1466     const int relative_cursor_position =
1467         cursor_behavior == InsertTextCursorBehavior::kMoveCursorBeforeText
1468             ? -text.length()
1469             : 0;
1470     text_input_manager_->GetActiveWidget()->ImeCommitText(
1471         text, std::vector<ui::ImeTextSpan>(), gfx::Range::InvalidRange(),
1472         relative_cursor_position);
1473   }
1474   has_composition_text_ = false;
1475 }
1476
1477 void RenderWidgetHostViewAura::InsertChar(const ui::KeyEvent& event) {
1478   if (popup_child_host_view_ && popup_child_host_view_->NeedsInputGrab()) {
1479     popup_child_host_view_->InsertChar(event);
1480     return;
1481   }
1482
1483   // Ignore character messages for VKEY_RETURN sent on CTRL+M. crbug.com/315547
1484   if (event_handler_->accept_return_character() ||
1485       event.GetCharacter() != ui::VKEY_RETURN) {
1486     // Send a blink::WebInputEvent::Char event to |host_|.
1487     ForwardKeyboardEventWithLatencyInfo(
1488         NativeWebKeyboardEvent(event, event.GetCharacter()), *event.latency(),
1489         nullptr);
1490   }
1491 }
1492
1493 bool RenderWidgetHostViewAura::CanInsertImage() {
1494   RenderFrameHostImpl* render_frame_host = GetFocusedFrame();
1495
1496   if (!render_frame_host) {
1497     return false;
1498   }
1499
1500   return render_frame_host->has_focused_richly_editable_element();
1501 }
1502
1503 void RenderWidgetHostViewAura::InsertImage(const GURL& src) {
1504   auto* input_handler = GetFrameWidgetInputHandlerForFocusedWidget();
1505
1506   if (!input_handler) {
1507     return;
1508   }
1509
1510   input_handler->ExecuteEditCommand("PasteFromImageURL",
1511                                     base::UTF8ToUTF16(src.spec()));
1512 }
1513
1514 ui::TextInputType RenderWidgetHostViewAura::GetTextInputType() const {
1515   if (text_input_manager_ && text_input_manager_->GetTextInputState())
1516     return text_input_manager_->GetTextInputState()->type;
1517   return ui::TEXT_INPUT_TYPE_NONE;
1518 }
1519
1520 ui::TextInputMode RenderWidgetHostViewAura::GetTextInputMode() const {
1521   if (text_input_manager_ && text_input_manager_->GetTextInputState())
1522     return text_input_manager_->GetTextInputState()->mode;
1523   return ui::TEXT_INPUT_MODE_DEFAULT;
1524 }
1525
1526 base::i18n::TextDirection RenderWidgetHostViewAura::GetTextDirection() const {
1527   NOTIMPLEMENTED_LOG_ONCE();
1528   return base::i18n::UNKNOWN_DIRECTION;
1529 }
1530
1531 int RenderWidgetHostViewAura::GetTextInputFlags() const {
1532   if (text_input_manager_ && text_input_manager_->GetTextInputState())
1533     return text_input_manager_->GetTextInputState()->flags;
1534   return 0;
1535 }
1536
1537 bool RenderWidgetHostViewAura::CanComposeInline() const {
1538   if (text_input_manager_ && text_input_manager_->GetTextInputState())
1539     return text_input_manager_->GetTextInputState()->can_compose_inline;
1540   return true;
1541 }
1542
1543 gfx::Rect RenderWidgetHostViewAura::ConvertRectToScreen(
1544     const gfx::Rect& rect) const {
1545   gfx::Point origin = rect.origin();
1546   gfx::Point end = gfx::Point(rect.right(), rect.bottom());
1547
1548   aura::Window* root_window = window_->GetRootWindow();
1549   if (!root_window)
1550     return rect;
1551   aura::client::ScreenPositionClient* screen_position_client =
1552       aura::client::GetScreenPositionClient(root_window);
1553   if (!screen_position_client)
1554     return rect;
1555   screen_position_client->ConvertPointToScreen(window_, &origin);
1556   screen_position_client->ConvertPointToScreen(window_, &end);
1557   return gfx::Rect(origin.x(), origin.y(), base::ClampSub(end.x(), origin.x()),
1558                    base::ClampSub(end.y(), origin.y()));
1559 }
1560
1561 gfx::Rect RenderWidgetHostViewAura::ConvertRectFromScreen(
1562     const gfx::Rect& rect) const {
1563   gfx::Rect result = rect;
1564   if (window_->GetRootWindow() &&
1565       aura::client::GetScreenPositionClient(window_->GetRootWindow()))
1566     wm::ConvertRectFromScreen(window_, &result);
1567   return result;
1568 }
1569
1570 gfx::Rect RenderWidgetHostViewAura::GetCaretBounds() const {
1571   if (!text_input_manager_ || !text_input_manager_->GetActiveWidget())
1572     return gfx::Rect();
1573
1574   // Check selection bound first (currently populated only for EditContext)
1575   const absl::optional<gfx::Rect> text_selection_bound =
1576       text_input_manager_->GetTextSelectionBounds();
1577   if (text_selection_bound)
1578     return ConvertRectToScreen(text_selection_bound.value());
1579
1580   // If no selection bound, we fall back to use selection region.
1581   const TextInputManager::SelectionRegion* region =
1582       text_input_manager_->GetSelectionRegion();
1583   gfx::Rect caret_rect = ConvertRectToScreen(
1584       gfx::RectBetweenSelectionBounds(region->anchor, region->focus));
1585   TRACE_EVENT1("ime", "RenderWidgetHostViewAura::GetCaretBounds", "caret_rect",
1586                caret_rect.ToString());
1587   return caret_rect;
1588 }
1589
1590 gfx::Rect RenderWidgetHostViewAura::GetSelectionBoundingBox() const {
1591   auto* focused_view = GetFocusedViewForTextSelection();
1592   if (!focused_view)
1593     return gfx::Rect();
1594
1595   const gfx::Rect bounding_box =
1596       text_input_manager_->GetSelectionRegion(focused_view)->bounding_box;
1597   if (bounding_box.IsEmpty())
1598     return gfx::Rect();
1599
1600   return ConvertRectToScreen(bounding_box);
1601 }
1602
1603 bool RenderWidgetHostViewAura::GetCompositionCharacterBounds(
1604     size_t index,
1605     gfx::Rect* rect) const {
1606   DCHECK(rect);
1607
1608   if (!text_input_manager_ || !text_input_manager_->GetActiveWidget())
1609     return false;
1610
1611   const TextInputManager::CompositionRangeInfo* composition_range_info =
1612       text_input_manager_->GetCompositionRangeInfo();
1613
1614   if (index >= composition_range_info->character_bounds.size())
1615     return false;
1616   *rect = ConvertRectToScreen(composition_range_info->character_bounds[index]);
1617   TRACE_EVENT1("ime", "RenderWidgetHostViewAura::GetCompositionCharacterBounds",
1618                "comp_char_rect", rect->ToString());
1619   return true;
1620 }
1621
1622 bool RenderWidgetHostViewAura::HasCompositionText() const {
1623   return has_composition_text_;
1624 }
1625
1626 ui::TextInputClient::FocusReason RenderWidgetHostViewAura::GetFocusReason()
1627     const {
1628   if (!window_->HasFocus())
1629     return ui::TextInputClient::FOCUS_REASON_NONE;
1630
1631   switch (last_pointer_type_before_focus_) {
1632     case ui::EventPointerType::kMouse:
1633       return ui::TextInputClient::FOCUS_REASON_MOUSE;
1634     case ui::EventPointerType::kPen:
1635       return ui::TextInputClient::FOCUS_REASON_PEN;
1636     case ui::EventPointerType::kTouch:
1637       return ui::TextInputClient::FOCUS_REASON_TOUCH;
1638     default:
1639       return ui::TextInputClient::FOCUS_REASON_OTHER;
1640   }
1641 }
1642
1643 bool RenderWidgetHostViewAura::GetTextRange(gfx::Range* range) const {
1644   if (!text_input_manager_ || !GetFocusedWidget())
1645     return false;
1646
1647   const ui::mojom::TextInputState* state =
1648       text_input_manager_->GetTextInputState();
1649   if (!state)
1650     return false;
1651
1652   range->set_start(0);
1653   range->set_end(state->value ? state->value->length() : 0);
1654   return true;
1655 }
1656
1657 bool RenderWidgetHostViewAura::GetCompositionTextRange(
1658     gfx::Range* range) const {
1659   if (!text_input_manager_ || !GetFocusedWidget())
1660     return false;
1661
1662   const ui::mojom::TextInputState* state =
1663       text_input_manager_->GetTextInputState();
1664   // Return false when there is no composition.
1665   if (!state || !state->composition)
1666     return false;
1667
1668   *range = state->composition.value();
1669   return true;
1670 }
1671
1672 bool RenderWidgetHostViewAura::GetEditableSelectionRange(
1673     gfx::Range* range) const {
1674   if (!text_input_manager_ || !GetFocusedWidget())
1675     return false;
1676
1677   const ui::mojom::TextInputState* state =
1678       text_input_manager_->GetTextInputState();
1679   if (!state)
1680     return false;
1681
1682   *range = state->selection;
1683   return true;
1684 }
1685
1686 bool RenderWidgetHostViewAura::SetEditableSelectionRange(
1687     const gfx::Range& range) {
1688   // TODO(crbug.com/915630): Write an unit test for this method.
1689   auto* input_handler = GetFrameWidgetInputHandlerForFocusedWidget();
1690   if (!input_handler)
1691     return false;
1692   input_handler->SetEditableSelectionOffsets(range.start(), range.end());
1693   return true;
1694 }
1695
1696 bool RenderWidgetHostViewAura::GetTextFromRange(const gfx::Range& range,
1697                                                 std::u16string* text) const {
1698   if (!text_input_manager_ || !GetFocusedWidget())
1699     return false;
1700
1701   const ui::mojom::TextInputState* state =
1702       text_input_manager_->GetTextInputState();
1703   if (!state)
1704     return false;
1705
1706   gfx::Range text_range;
1707   GetTextRange(&text_range);
1708
1709   if (!text_range.Contains(range)) {
1710     text->clear();
1711     return false;
1712   }
1713   if (!state->value) {
1714     text->clear();
1715     return true;
1716   }
1717   if (text_range.EqualsIgnoringDirection(range)) {
1718     // Avoid calling substr whose performance is low.
1719     *text = *state->value;
1720   } else {
1721     *text = state->value->substr(range.GetMin(), range.length());
1722   }
1723   return true;
1724 }
1725
1726 void RenderWidgetHostViewAura::OnInputMethodChanged() {
1727   // TODO(suzhe): implement the newly added "locale" property of HTML DOM
1728   // TextEvent.
1729 }
1730
1731 bool RenderWidgetHostViewAura::ChangeTextDirectionAndLayoutAlignment(
1732       base::i18n::TextDirection direction) {
1733   if (!GetTextInputManager() && !GetTextInputManager()->GetActiveWidget())
1734     return false;
1735
1736   GetTextInputManager()->GetActiveWidget()->UpdateTextDirection(direction);
1737   GetTextInputManager()->GetActiveWidget()->NotifyTextDirection();
1738   return true;
1739 }
1740
1741 void RenderWidgetHostViewAura::ExtendSelectionAndDelete(
1742     size_t before, size_t after) {
1743   auto* input_handler = GetFrameWidgetInputHandlerForFocusedWidget();
1744   if (!input_handler)
1745     return;
1746   input_handler->ExtendSelectionAndDelete(before, after);
1747 }
1748
1749 #if BUILDFLAG(IS_CHROMEOS)
1750 void RenderWidgetHostViewAura::ExtendSelectionAndReplace(
1751     size_t before,
1752     size_t after,
1753     const base::StringPiece16 replacement_text) {
1754   auto* input_handler = GetFrameWidgetInputHandlerForFocusedWidget();
1755   if (!input_handler) {
1756     return;
1757   }
1758   input_handler->ExtendSelectionAndReplace(before, after,
1759                                            std::u16string(replacement_text));
1760 }
1761 #endif
1762
1763 void RenderWidgetHostViewAura::EnsureCaretNotInRect(
1764     const gfx::Rect& rect_in_screen) {
1765   keyboard_occluded_bounds_ = rect_in_screen;
1766
1767   // If keyboard is disabled, reset the insets_.
1768   if (keyboard_occluded_bounds_.IsEmpty()) {
1769     SetInsets(gfx::Insets());
1770   } else {
1771     UpdateInsetsWithVirtualKeyboardEnabled();
1772   }
1773
1774   aura::Window* top_level_window = window_->GetToplevelWindow();
1775 #if BUILDFLAG(IS_CHROMEOS_ASH)
1776   wm::EnsureWindowNotInRect(top_level_window, keyboard_occluded_bounds_);
1777 #endif
1778
1779   // Perform overscroll if the caret is still hidden by the keyboard.
1780   const gfx::Rect hidden_window_bounds_in_screen = gfx::IntersectRects(
1781       keyboard_occluded_bounds_, top_level_window->GetBoundsInScreen());
1782
1783   if (hidden_window_bounds_in_screen.IsEmpty())
1784     return;
1785
1786   ScrollFocusedEditableNodeIntoView();
1787 }
1788
1789 bool RenderWidgetHostViewAura::IsTextEditCommandEnabled(
1790     ui::TextEditCommand command) const {
1791   return false;
1792 }
1793
1794 void RenderWidgetHostViewAura::SetTextEditCommandForNextKeyEvent(
1795     ui::TextEditCommand command) {}
1796
1797 ukm::SourceId RenderWidgetHostViewAura::GetClientSourceForMetrics() const {
1798   RenderFrameHostImpl* frame = GetFocusedFrame();
1799   // ukm::SourceId is not available while prerendering.
1800   if (frame && !frame->IsInLifecycleState(
1801                    RenderFrameHost::LifecycleState::kPrerendering)) {
1802     return frame->GetPageUkmSourceId();
1803   }
1804   return ukm::SourceId();
1805 }
1806
1807 bool RenderWidgetHostViewAura::ShouldDoLearning() {
1808   return GetTextInputManager() && GetTextInputManager()->should_do_learning();
1809 }
1810
1811 #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
1812 bool RenderWidgetHostViewAura::SetCompositionFromExistingText(
1813     const gfx::Range& range,
1814     const std::vector<ui::ImeTextSpan>& ui_ime_text_spans) {
1815   auto* input_handler = GetFrameWidgetInputHandlerForFocusedWidget();
1816   if (!input_handler)
1817     return false;
1818   input_handler->SetCompositionFromExistingText(range.start(), range.end(),
1819                                                 ui_ime_text_spans);
1820   has_composition_text_ = true;
1821   return true;
1822 }
1823
1824 #endif
1825
1826 #if BUILDFLAG(IS_CHROMEOS)
1827 gfx::Range RenderWidgetHostViewAura::GetAutocorrectRange() const {
1828   if (!text_input_manager_ || !text_input_manager_->GetActiveWidget())
1829     return gfx::Range();
1830   return text_input_manager_->GetAutocorrectRange();
1831 }
1832
1833 gfx::Rect RenderWidgetHostViewAura::GetAutocorrectCharacterBounds() const {
1834   if (!text_input_manager_ || !text_input_manager_->GetActiveWidget())
1835     return gfx::Rect();
1836
1837   const std::vector<ui::mojom::ImeTextSpanInfoPtr>& ime_text_spans_info =
1838       text_input_manager_->GetTextInputState()->ime_text_spans_info;
1839
1840   unsigned autocorrect_span_found = 0;
1841   gfx::Rect bounds;
1842   for (const auto& ime_text_span_info : ime_text_spans_info) {
1843     if (ime_text_span_info->span.type == ui::ImeTextSpan::Type::kAutocorrect) {
1844       bounds = ConvertRectToScreen(ime_text_span_info->bounds);
1845       autocorrect_span_found++;
1846     }
1847   }
1848   // Assuming there is only one autocorrect span at any point in time.
1849   DCHECK_LE(autocorrect_span_found, 1u);
1850   return bounds;
1851 }
1852
1853 bool RenderWidgetHostViewAura::SetAutocorrectRange(
1854     const gfx::Range& range) {
1855   if (!range.is_empty()) {
1856     base::UmaHistogramEnumeration(
1857         "InputMethod.Assistive.Autocorrect.Count",
1858         TextInputClient::SubClass::kRenderWidgetHostViewAura);
1859
1860 #if BUILDFLAG(IS_CHROMEOS_ASH)
1861     auto* input_method_manager = ash::input_method::InputMethodManager::Get();
1862     if (input_method_manager &&
1863         ash::extension_ime_util::IsExperimentalMultilingual(
1864             input_method_manager->GetActiveIMEState()
1865                 ->GetCurrentInputMethod()
1866                 .id())) {
1867       base::UmaHistogramEnumeration(
1868           "InputMethod.MultilingualExperiment.Autocorrect.Count",
1869           TextInputClient::SubClass::kRenderWidgetHostViewAura);
1870     }
1871 #endif
1872   }
1873
1874   auto* input_handler = GetFrameWidgetInputHandlerForFocusedWidget();
1875   if (!input_handler)
1876     return false;
1877
1878   input_handler->ClearImeTextSpansByType(0,
1879                                          std::numeric_limits<uint32_t>::max(),
1880                                          ui::ImeTextSpan::Type::kAutocorrect);
1881
1882   if (range.is_empty())
1883     return true;
1884
1885   ui::ImeTextSpan ui_ime_text_span;
1886   ui_ime_text_span.type = ui::ImeTextSpan::Type::kAutocorrect;
1887   ui_ime_text_span.start_offset = 0;
1888   ui_ime_text_span.end_offset = range.length();
1889   ui_ime_text_span.underline_style = ui::ImeTextSpan::UnderlineStyle::kDot;
1890   ui_ime_text_span.underline_color =
1891       SkColorSetA(gfx::kGoogleGrey700, SK_AlphaOPAQUE * 0.7);
1892   ui_ime_text_span.thickness = ui::ImeTextSpan::Thickness::kThick;
1893
1894   input_handler->AddImeTextSpansToExistingText(range.start(), range.end(),
1895                                                {ui_ime_text_span});
1896   return true;
1897 }
1898
1899 absl::optional<ui::GrammarFragment>
1900 RenderWidgetHostViewAura::GetGrammarFragmentAtCursor() const {
1901   if (!text_input_manager_ || !text_input_manager_->GetActiveWidget())
1902     return absl::nullopt;
1903   gfx::Range selection_range;
1904   if (GetEditableSelectionRange(&selection_range)) {
1905     return text_input_manager_->GetGrammarFragment(selection_range);
1906   } else {
1907     return absl::nullopt;
1908   }
1909 }
1910
1911 bool RenderWidgetHostViewAura::ClearGrammarFragments(const gfx::Range& range) {
1912   auto* input_handler = GetFrameWidgetInputHandlerForFocusedWidget();
1913   if (!input_handler)
1914     return false;
1915
1916   input_handler->ClearImeTextSpansByType(
1917       range.start(), range.end(), ui::ImeTextSpan::Type::kGrammarSuggestion);
1918   return true;
1919 }
1920
1921 bool RenderWidgetHostViewAura::AddGrammarFragments(
1922     const std::vector<ui::GrammarFragment>& fragments) {
1923   if (!fragments.empty()) {
1924     base::UmaHistogramEnumeration(
1925         "InputMethod.Assistive.Grammar.Count",
1926         TextInputClient::SubClass::kRenderWidgetHostViewAura);
1927   }
1928
1929   auto* input_handler = GetFrameWidgetInputHandlerForFocusedWidget();
1930   if (!input_handler || fragments.empty())
1931     return false;
1932
1933   unsigned max_fragment_end = 0;
1934   std::vector<::ui::ImeTextSpan> ime_text_spans;
1935   ime_text_spans.reserve(fragments.size());
1936   for (auto& fragment : fragments) {
1937     ui::ImeTextSpan ui_ime_text_span;
1938     ui_ime_text_span.type = ui::ImeTextSpan::Type::kGrammarSuggestion;
1939     ui_ime_text_span.start_offset = fragment.range.start();
1940     ui_ime_text_span.end_offset = fragment.range.end();
1941     ui_ime_text_span.thickness = ui::ImeTextSpan::Thickness::kThick;
1942     ui_ime_text_span.underline_style = ui::ImeTextSpan::UnderlineStyle::kDot;
1943     ui_ime_text_span.underline_color = gfx::kGoogleBlue400;
1944     ui_ime_text_span.suggestions = {fragment.suggestion};
1945
1946     ime_text_spans.push_back(ui_ime_text_span);
1947     if (fragment.range.end() > max_fragment_end) {
1948       max_fragment_end = fragment.range.end();
1949     }
1950   }
1951   input_handler->AddImeTextSpansToExistingText(0, max_fragment_end,
1952                                                ime_text_spans);
1953
1954   return true;
1955 }
1956
1957 #endif
1958
1959 #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_CHROMEOS)
1960 void RenderWidgetHostViewAura::GetActiveTextInputControlLayoutBounds(
1961     absl::optional<gfx::Rect>* control_bounds,
1962     absl::optional<gfx::Rect>* selection_bounds) {
1963   if (text_input_manager_) {
1964     const absl::optional<gfx::Rect> text_control_bounds =
1965         text_input_manager_->GetTextControlBounds();
1966     if (text_control_bounds) {
1967       *control_bounds = ConvertRectToScreen(text_control_bounds.value());
1968       TRACE_EVENT1(
1969           "ime",
1970           "RenderWidgetHostViewAura::GetActiveTextInputControlLayoutBounds",
1971           "control_bounds_rect", control_bounds->value().ToString());
1972     }
1973     // Selection bounds are currently populated only for EditContext.
1974     // For editable elements we use GetCompositionCharacterBounds.
1975     const absl::optional<gfx::Rect> text_selection_bounds =
1976         text_input_manager_->GetTextSelectionBounds();
1977     if (text_selection_bounds) {
1978       *selection_bounds = ConvertRectToScreen(text_selection_bounds.value());
1979     }
1980   }
1981 }
1982 #endif
1983
1984 #if BUILDFLAG(IS_WIN)
1985 void RenderWidgetHostViewAura::SetActiveCompositionForAccessibility(
1986     const gfx::Range& range,
1987     const std::u16string& active_composition_text,
1988     bool is_composition_committed) {
1989   BrowserAccessibilityManager* manager =
1990       host()->GetRootBrowserAccessibilityManager();
1991   if (manager) {
1992     ui::AXPlatformNodeWin* focus_node = static_cast<ui::AXPlatformNodeWin*>(
1993         ui::AXPlatformNode::FromNativeViewAccessible(
1994             manager->GetFocus()->GetNativeViewAccessible()));
1995     if (focus_node) {
1996       // Notify accessibility object about this composition
1997       focus_node->OnActiveComposition(range, active_composition_text,
1998                                       is_composition_committed);
1999     }
2000   }
2001 }
2002 #endif
2003
2004 #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_CHROMEOS_ASH)
2005 ui::TextInputClient::EditingContext
2006 RenderWidgetHostViewAura::GetTextEditingContext() {
2007   ui::TextInputClient::EditingContext editing_context;
2008   // We use the focused frame's URL here and not the main frame because
2009   // TSF(Windows Text Service Framework) works on the active editable element
2010   // context and it uses this information to assist the UIA(Microsoft UI
2011   // Automation) service to determine the character that is being typed by the
2012   // user via IME composition, the URL of the site that the user is typing on
2013   // and other text related services that are used by the UIA clients to power
2014   // accessibility features on Windows. We want to expose the focused frame's
2015   // URL to TSF that notifies the UIA service which uses this info and the
2016   // focused element's data to provide better screen reading capabilities.
2017   RenderFrameHostImpl* frame = GetFocusedFrame();
2018   if (frame)
2019     editing_context.page_url = frame->GetLastCommittedURL();
2020   return editing_context;
2021 }
2022 #endif
2023
2024 #if BUILDFLAG(IS_WIN)
2025 void RenderWidgetHostViewAura::NotifyOnFrameFocusChanged() {
2026   if (GetInputMethod()) {
2027     GetInputMethod()->OnUrlChanged();
2028   }
2029 }
2030 #endif
2031
2032 ////////////////////////////////////////////////////////////////////////////////
2033 // RenderWidgetHostViewAura, display::DisplayObserver implementation:
2034
2035 void RenderWidgetHostViewAura::OnDisplayMetricsChanged(
2036     const display::Display& display,
2037     uint32_t metrics) {
2038   display::Screen* screen = display::Screen::GetScreen();
2039   if (display.id() != screen->GetDisplayNearestWindow(window_).id())
2040     return;
2041
2042   if (window_->GetHost() && window_->GetHost()->device_scale_factor() !=
2043                                 display.device_scale_factor()) {
2044     // The DisplayMetrics changed, but the Compositor hasn't been updated yet.
2045     // Delay updating until the Compositor is updated as well, otherwise we
2046     // are likely to hit surface invariants (LocalSurfaceId generated with a
2047     // size/scale-factor that differs from scale-factor used by Compositor).
2048     needs_to_update_display_metrics_ = true;
2049     return;
2050   }
2051   ProcessDisplayMetricsChanged();
2052 }
2053
2054 ////////////////////////////////////////////////////////////////////////////////
2055 // RenderWidgetHostViewAura, aura::WindowDelegate implementation:
2056
2057 gfx::Size RenderWidgetHostViewAura::GetMinimumSize() const {
2058   return gfx::Size();
2059 }
2060
2061 gfx::Size RenderWidgetHostViewAura::GetMaximumSize() const {
2062   return gfx::Size();
2063 }
2064
2065 void RenderWidgetHostViewAura::OnBoundsChanged(const gfx::Rect& old_bounds,
2066                                                const gfx::Rect& new_bounds) {
2067   base::AutoReset<bool> in_bounds_changed(&in_bounds_changed_, true);
2068   // We care about this whenever RenderWidgetHostViewAura is not owned by a
2069   // WebContentsViewAura since changes to the Window's bounds need to be
2070   // messaged to the renderer.  WebContentsViewAura invokes SetSize() or
2071   // SetBounds() itself.  No matter how we got here, any redundant calls are
2072   // harmless.
2073   SetSize(new_bounds.size());
2074
2075   if (GetInputMethod()) {
2076     GetInputMethod()->OnCaretBoundsChanged(this);
2077     UpdateInsetsWithVirtualKeyboardEnabled();
2078   }
2079 }
2080
2081 gfx::NativeCursor RenderWidgetHostViewAura::GetCursor(const gfx::Point& point) {
2082   if (IsMouseLocked())
2083     return ui::mojom::CursorType::kNone;
2084   return current_cursor_.GetNativeCursor();
2085 }
2086
2087 int RenderWidgetHostViewAura::GetNonClientComponent(
2088     const gfx::Point& point) const {
2089   return HTCLIENT;
2090 }
2091
2092 bool RenderWidgetHostViewAura::ShouldDescendIntoChildForEventHandling(
2093     aura::Window* child,
2094     const gfx::Point& location) {
2095   return true;
2096 }
2097
2098 bool RenderWidgetHostViewAura::CanFocus() {
2099   return widget_type_ == WidgetType::kFrame;
2100 }
2101
2102 void RenderWidgetHostViewAura::OnCaptureLost() {
2103   host()->LostCapture();
2104 }
2105
2106 void RenderWidgetHostViewAura::OnPaint(const ui::PaintContext& context) {
2107   NOTREACHED();
2108 }
2109
2110 void RenderWidgetHostViewAura::OnDeviceScaleFactorChanged(
2111     float old_device_scale_factor,
2112     float new_device_scale_factor) {
2113   if (!window_->GetRootWindow())
2114     return;
2115
2116   // TODO(crbug.com/1446142): Add unittest for lacros.
2117   if (needs_to_update_display_metrics_ ||
2118       old_device_scale_factor != new_device_scale_factor) {
2119     ProcessDisplayMetricsChanged();
2120   }
2121
2122   SynchronizeVisualProperties(cc::DeadlinePolicy::UseDefaultDeadline(),
2123                               window_->GetLocalSurfaceId());
2124
2125   device_scale_factor_ = new_device_scale_factor;
2126   const display::Display display =
2127       display::Screen::GetScreen()->GetDisplayNearestWindow(window_);
2128   // Sometimes GetDisplayNearestWindow returns the default monitor. We don't
2129   // want to use that here.
2130   if (display.is_valid()) {
2131     DCHECK_EQ(new_device_scale_factor, display.device_scale_factor());
2132     current_cursor_.SetDisplayInfo(display);
2133   }
2134 }
2135
2136 void RenderWidgetHostViewAura::OnWindowDestroying(aura::Window* window) {
2137 #if BUILDFLAG(IS_WIN)
2138   // The LegacyRenderWidgetHostHWND instance is destroyed when its window is
2139   // destroyed. Normally we control when that happens via the Destroy call
2140   // in the dtor. However there may be cases where the window is destroyed
2141   // by Windows, i.e. the parent window is destroyed before the
2142   // RenderWidgetHostViewAura instance goes away etc. To avoid that we
2143   // destroy the LegacyRenderWidgetHostHWND instance here.
2144   if (legacy_render_widget_host_HWND_) {
2145     // The Destroy call below will delete the LegacyRenderWidgetHostHWND
2146     // instance.
2147     legacy_render_widget_host_HWND_.ExtractAsDangling()->Destroy();
2148   }
2149 #endif
2150
2151   // Make sure that the input method no longer references to this object before
2152   // this object is removed from the root window (i.e. this object loses access
2153   // to the input method).
2154   DetachFromInputMethod(true);
2155
2156   if (overscroll_controller_)
2157     overscroll_controller_->Reset();
2158 }
2159
2160 void RenderWidgetHostViewAura::OnWindowDestroyed(aura::Window* window) {
2161   // This is not called on all destruction paths (e.g. if this view was never
2162   // inialized properly to create the window). So the destruction/cleanup code
2163   // that do not depend on |window_| should happen in the destructor, not here.
2164   delete this;
2165 }
2166
2167 void RenderWidgetHostViewAura::OnWindowTargetVisibilityChanged(bool visible) {
2168 }
2169
2170 bool RenderWidgetHostViewAura::HasHitTestMask() const {
2171   return false;
2172 }
2173
2174 void RenderWidgetHostViewAura::GetHitTestMask(SkPath* mask) const {}
2175
2176 bool RenderWidgetHostViewAura::RequiresDoubleTapGestureEvents() const {
2177   RenderWidgetHostOwnerDelegate* owner_delegate = host()->owner_delegate();
2178   // TODO(crbug.com/916715): Child local roots do not work here?
2179   if (!owner_delegate)
2180     return false;
2181   return double_tap_to_zoom_enabled_;
2182 }
2183
2184 ////////////////////////////////////////////////////////////////////////////////
2185 // RenderWidgetHostViewAura, ui::EventHandler implementation:
2186
2187 void RenderWidgetHostViewAura::OnKeyEvent(ui::KeyEvent* event) {
2188   last_pointer_type_ = ui::EventPointerType::kUnknown;
2189   event_handler_->OnKeyEvent(event);
2190 }
2191
2192 void RenderWidgetHostViewAura::OnMouseEvent(ui::MouseEvent* event) {
2193 #if BUILDFLAG(IS_WIN)
2194   if (event->type() == ui::ET_MOUSE_MOVED) {
2195     if (event->location() == last_mouse_move_location_ &&
2196         event->movement().IsZero()) {
2197       event->SetHandled();
2198       return;
2199     }
2200     last_mouse_move_location_ = event->location();
2201   }
2202 #endif
2203 #if BUILDFLAG(IS_EFL)
2204   if (efl_helper_)
2205     efl_helper_->OnMouseOrTouchEvent(event);
2206 #endif
2207   last_pointer_type_ = ui::EventPointerType::kMouse;
2208   event_handler_->OnMouseEvent(event);
2209 }
2210
2211 bool RenderWidgetHostViewAura::HasFallbackSurface() const {
2212   DCHECK(delegated_frame_host_) << "Cannot be invoked during destruction.";
2213   return delegated_frame_host_->HasFallbackSurface();
2214 }
2215
2216 bool RenderWidgetHostViewAura::TransformPointToCoordSpaceForView(
2217     const gfx::PointF& point,
2218     RenderWidgetHostViewBase* target_view,
2219     gfx::PointF* transformed_point) {
2220   DCHECK(delegated_frame_host_) << "Cannot be invoked during destruction.";
2221
2222   if (target_view == this) {
2223     *transformed_point = point;
2224     return true;
2225   }
2226
2227   // In TransformPointToLocalCoordSpace() there is a Point-to-Pixel conversion,
2228   // but it is not necessary here because the final target view is responsible
2229   // for converting before computing the final transform.
2230   return target_view->TransformPointToLocalCoordSpace(
2231       point, GetCurrentSurfaceId(), transformed_point);
2232 }
2233
2234 viz::FrameSinkId RenderWidgetHostViewAura::GetRootFrameSinkId() {
2235   if (!GetCompositor())
2236     return viz::FrameSinkId();
2237
2238   return GetCompositor()->frame_sink_id();
2239 }
2240
2241 viz::SurfaceId RenderWidgetHostViewAura::GetCurrentSurfaceId() const {
2242   DCHECK(delegated_frame_host_) << "Cannot be invoked during destruction.";
2243   return delegated_frame_host_->GetCurrentSurfaceId();
2244 }
2245
2246 void RenderWidgetHostViewAura::FocusedNodeChanged(
2247     bool editable,
2248     const gfx::Rect& node_bounds_in_screen
2249 #if BUILDFLAG(IS_TIZEN_TV)
2250     ,
2251     bool is_radio_or_checkbox,
2252     int password_input_minlength,
2253     int input_maxlength
2254 #endif
2255 #if BUILDFLAG(IS_EFL)
2256     ,
2257     bool is_content_editable
2258 #endif
2259 ) {
2260   // The last gesture most likely caused the focus change. The focus reason will
2261   // be incorrect if the focus was triggered without a user gesture.
2262   // TODO(https://crbug.com/824604): Get the focus reason from the renderer
2263   // process instead to get the true focus reason.
2264   last_pointer_type_before_focus_ = last_pointer_type_;
2265
2266   auto* input_method = GetInputMethod();
2267   if (input_method)
2268     input_method->CancelComposition(this);
2269   has_composition_text_ = false;
2270
2271 #if defined(USE_EFL)
2272   efl_helper_->FocusedNodeChanged(
2273       editable
2274 #if BUILDFLAG(IS_TIZEN_TV)
2275       ,
2276       is_radio_or_checkbox, password_input_minlength, input_maxlength
2277 #endif
2278       ,
2279       is_content_editable);
2280 #endif
2281
2282 #if BUILDFLAG(IS_WIN)
2283   if (window_ && virtual_keyboard_controller_win_) {
2284     virtual_keyboard_controller_win_->FocusedNodeChanged(editable);
2285   }
2286 #endif
2287 }
2288
2289 #if defined(TIZEN_VIDEO_HOLE)
2290 void RenderWidgetHostViewAura::DidMoveWebView() {
2291   if (!on_webview_moved_callback_.is_null())
2292     on_webview_moved_callback_.Run();
2293 }
2294
2295 void RenderWidgetHostViewAura::SetWebViewMovedCallback(
2296   const base::RepeatingClosure on_webview_moved) {
2297   on_webview_moved_callback_ = std::move(on_webview_moved);
2298 }
2299 #endif
2300
2301 #if BUILDFLAG(IS_TIZEN_TV)
2302 void RenderWidgetHostViewAura::DidEdgeScrollBy(const gfx::Point& offset,
2303     bool handled) {
2304     efl_helper_->DidEdgeScrollBy(offset, handled);
2305 }
2306 #endif
2307
2308 void RenderWidgetHostViewAura::OnScrollEvent(ui::ScrollEvent* event) {
2309   event_handler_->OnScrollEvent(event);
2310 }
2311
2312 void RenderWidgetHostViewAura::OnTouchEvent(ui::TouchEvent* event) {
2313 #if BUILDFLAG(IS_EFL)
2314   if (efl_helper_)
2315     efl_helper_->OnMouseOrTouchEvent(event);
2316 #endif
2317   last_pointer_type_ = event->pointer_details().pointer_type;
2318   ui::InputMethod* input_method = GetInputMethod();
2319   if (window_ && window_->HasFocus() && input_method) {
2320     input_method->OnTouch(event->pointer_details().pointer_type);
2321   }
2322   event_handler_->OnTouchEvent(event);
2323 }
2324
2325 void RenderWidgetHostViewAura::OnGestureEvent(ui::GestureEvent* event) {
2326   last_pointer_type_ = event->details().primary_pointer_type();
2327 #if BUILDFLAG(IS_EFL)
2328   // Gesture event will be processed and forwarded via efl helper.
2329   efl_helper_->OnGestureEvent(event);
2330   return;
2331 #endif
2332   event_handler_->OnGestureEvent(event);
2333 }
2334
2335 base::StringPiece RenderWidgetHostViewAura::GetLogContext() const {
2336   return "RenderWidgetHostViewAura";
2337 }
2338
2339 ////////////////////////////////////////////////////////////////////////////////
2340 // RenderWidgetHostViewAura, wm::ActivationDelegate implementation:
2341
2342 bool RenderWidgetHostViewAura::ShouldActivate() const {
2343   aura::WindowTreeHost* host = window_->GetHost();
2344   if (!host)
2345     return true;
2346   const ui::Event* event = host->dispatcher()->current_event();
2347   return !event;
2348 }
2349
2350 ////////////////////////////////////////////////////////////////////////////////
2351 // RenderWidgetHostViewAura, aura::client::CursorClientObserver implementation:
2352
2353 void RenderWidgetHostViewAura::OnCursorVisibilityChanged(bool is_visible) {
2354   NotifyRendererOfCursorVisibilityState(is_visible);
2355 }
2356
2357 void RenderWidgetHostViewAura::OnSystemCursorSizeChanged(
2358     const gfx::Size& system_cursor_size) {
2359   UpdateSystemCursorSize(system_cursor_size);
2360 }
2361
2362 ////////////////////////////////////////////////////////////////////////////////
2363 // RenderWidgetHostViewAura, aura::client::FocusChangeObserver implementation:
2364
2365 void RenderWidgetHostViewAura::OnWindowFocused(aura::Window* gained_focus,
2366                                                aura::Window* lost_focus) {
2367   LOG(INFO) << "OnWindowFocused, Gained : " << gained_focus
2368             << ", Lost : " << lost_focus;
2369   if (window_ == gained_focus) {
2370 #if !BUILDFLAG(IS_TIZEN_TV)
2371     // We need to honor input bypass if the associated tab does not want input.
2372     // This gives the current focused window a chance to be the text input
2373     // client and handle events.
2374     if (host()->IsIgnoringInputEvents())
2375       return;
2376 #endif
2377
2378     host()->GotFocus();
2379     UpdateActiveState(true);
2380
2381     ui::InputMethod* input_method = GetInputMethod();
2382     if (input_method) {
2383       // Ask the system-wide IME to send all TextInputClient messages to |this|
2384       // object.
2385       input_method->SetFocusedTextInputClient(this);
2386     }
2387
2388     BrowserAccessibilityManager* manager =
2389         host()->GetRootBrowserAccessibilityManager();
2390     if (manager)
2391       manager->OnWindowFocused();
2392     return;
2393   }
2394
2395   if (window_ != lost_focus) {
2396     NOTREACHED();
2397     return;
2398   }
2399
2400   UpdateActiveState(false);
2401   host()->LostFocus();
2402
2403   DetachFromInputMethod(false);
2404
2405   // TODO(wjmaclean): Do we need to let TouchSelectionControllerClientAura
2406   // handle this, just in case it stomps on a new highlight in another view
2407   // that has just become focused? So far it doesn't appear to be a problem,
2408   // but we should keep an eye on it.
2409   selection_controller_->HideAndDisallowShowingAutomatically();
2410
2411   if (overscroll_controller_)
2412     overscroll_controller_->Cancel();
2413
2414   BrowserAccessibilityManager* manager =
2415       host()->GetRootBrowserAccessibilityManager();
2416   if (manager)
2417     manager->OnWindowBlurred();
2418
2419   // Close the child popup window if we lose focus (e.g. due to a JS alert or
2420   // system modal dialog). This is particularly important if
2421   // |popup_child_host_view_| has mouse capture.
2422   if (popup_child_host_view_)
2423     popup_child_host_view_->Shutdown();
2424 }
2425
2426 ////////////////////////////////////////////////////////////////////////////////
2427 // RenderWidgetHostViewAura, aura::WindowTreeHostObserver implementation:
2428
2429 void RenderWidgetHostViewAura::OnHostMovedInPixels(aura::WindowTreeHost* host) {
2430   TRACE_EVENT0("ui", "RenderWidgetHostViewAura::OnHostMovedInPixels");
2431
2432   UpdateScreenInfo();
2433 }
2434
2435 ////////////////////////////////////////////////////////////////////////////////
2436 // RenderWidgetHostViewAura, RenderFrameMetadataProvider::Observer
2437 // implementation:
2438 void RenderWidgetHostViewAura::OnRenderFrameMetadataChangedAfterActivation(
2439     base::TimeTicks activation_time) {
2440   const cc::RenderFrameMetadata& metadata =
2441       host()->render_frame_metadata_provider()->LastRenderFrameMetadata();
2442
2443   // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f.
2444   SetContentBackgroundColor(metadata.root_background_color.toSkColor());
2445   if (inset_surface_id_.is_valid() && metadata.local_surface_id &&
2446       metadata.local_surface_id.value().is_valid() &&
2447       metadata.local_surface_id.value().IsSameOrNewerThan(inset_surface_id_)) {
2448     inset_surface_id_ = viz::LocalSurfaceId();
2449     ScrollFocusedEditableNodeIntoView();
2450   }
2451
2452   if (metadata.selection.start != selection_start_ ||
2453       metadata.selection.end != selection_end_) {
2454     selection_start_ = metadata.selection.start;
2455     selection_end_ = metadata.selection.end;
2456     selection_controller_client_->UpdateClientSelectionBounds(selection_start_,
2457                                                               selection_end_);
2458   }
2459 }
2460
2461 #if BUILDFLAG(IS_EFL)
2462 RWHVAuraOffscreenHelperEfl* RenderWidgetHostViewAura::offscreen_helper() {
2463   if (!efl_helper_->IsOffscreenMode()) {
2464     DLOG(INFO) << "Onscreen rendering mode is set";
2465     return nullptr;
2466   }
2467
2468   return static_cast<RWHVAuraOffscreenHelperEfl*>(efl_helper_.get());
2469 }
2470
2471 void RenderWidgetHostViewAura::DidChangeInputType(bool is_password_field) {
2472   efl_helper_->DidChangeInputType(is_password_field);
2473 }
2474
2475 void RenderWidgetHostViewAura::OnGetFocusedNodeBounds(const gfx::RectF& rect) {
2476   efl_helper_->OnGetFocusedNodeBounds(rect);
2477 }
2478
2479 void RenderWidgetHostViewAura::OnGetMainFrameScrollbarVisible(int callback_id,
2480                                                               bool visible) {
2481   efl_helper_->OnGetMainFrameScrollbarVisible(callback_id, visible);
2482 }
2483 #endif
2484
2485 ////////////////////////////////////////////////////////////////////////////////
2486 // RenderWidgetHostViewAura, private:
2487
2488 RenderWidgetHostViewAura::~RenderWidgetHostViewAura() {
2489   host()->render_frame_metadata_provider()->RemoveObserver(this);
2490
2491   // Ask the RWH to drop reference to us.
2492   host()->ViewDestroyed();
2493
2494   // Dismiss any visible touch selection handles or touch selection menu.
2495   selection_controller_->HideAndDisallowShowingAutomatically();
2496   selection_controller_.reset();
2497   selection_controller_client_.reset();
2498
2499   GetCursorManager()->ViewBeingDestroyed(this);
2500
2501   delegated_frame_host_.reset();
2502   window_observer_.reset();
2503   if (window_) {
2504     if (window_->GetHost())
2505       window_->GetHost()->RemoveObserver(this);
2506     UnlockMouse();
2507     wm::SetTooltipText(window_, nullptr);
2508
2509     // This call is usually no-op since |this| object is already removed from
2510     // the Aura root window and we don't have a way to get an input method
2511     // object associated with the window, but just in case.
2512     DetachFromInputMethod(true);
2513   }
2514   if (popup_parent_host_view_) {
2515     DCHECK(!popup_parent_host_view_->popup_child_host_view_ ||
2516            popup_parent_host_view_->popup_child_host_view_ == this);
2517     popup_parent_host_view_->SetPopupChild(nullptr);
2518   }
2519   if (popup_child_host_view_) {
2520     DCHECK(!popup_child_host_view_->popup_parent_host_view_ ||
2521            popup_child_host_view_->popup_parent_host_view_ == this);
2522     popup_child_host_view_->popup_parent_host_view_ = nullptr;
2523   }
2524   event_observer_for_popup_exit_.reset();
2525
2526 #if BUILDFLAG(IS_WIN)
2527   // The LegacyRenderWidgetHostHWND window should have been destroyed in
2528   // RenderWidgetHostViewAura::OnWindowDestroying and the pointer should
2529   // be set to NULL.
2530   DCHECK(!legacy_render_widget_host_HWND_);
2531 #endif
2532
2533   if (text_input_manager_)
2534     text_input_manager_->RemoveObserver(this);
2535 }
2536
2537 void RenderWidgetHostViewAura::CreateAuraWindow(aura::client::WindowType type) {
2538   DCHECK(!window_);
2539   window_ = new aura::Window(this);
2540   window_->SetName("RenderWidgetHostViewAura");
2541   event_handler_->set_window(window_);
2542   window_observer_ = std::make_unique<WindowObserver>(this);
2543
2544   wm::SetTooltipText(window_, &tooltip_);
2545   wm::SetActivationDelegate(window_, this);
2546   aura::client::SetFocusChangeObserver(window_, this);
2547   display_observer_.emplace(this);
2548
2549   window_->SetType(type);
2550   window_->Init(ui::LAYER_SOLID_COLOR);
2551   window_->layer()->SetColor(GetBackgroundColor() ? *GetBackgroundColor()
2552                                                   : SK_ColorWHITE);
2553   // This needs to happen only after |window_| has been initialized using
2554   // Init(), because it needs to have the layer.
2555   window_->SetEmbedFrameSinkId(frame_sink_id_);
2556 }
2557
2558 void RenderWidgetHostViewAura::CreateDelegatedFrameHostClient() {
2559   delegated_frame_host_client_ =
2560       std::make_unique<DelegatedFrameHostClientAura>(this);
2561   delegated_frame_host_ = std::make_unique<DelegatedFrameHost>(
2562       frame_sink_id_, delegated_frame_host_client_.get(),
2563       false /* should_register_frame_sink_id */);
2564 }
2565
2566 void RenderWidgetHostViewAura::UpdateCursorIfOverSelf() {
2567   if (host()->GetProcess()->FastShutdownStarted())
2568     return;
2569
2570   aura::Window* root_window = window_->GetRootWindow();
2571   if (!root_window)
2572     return;
2573
2574   if (ShouldSkipCursorUpdate())
2575     return;
2576
2577   display::Screen* screen = display::Screen::GetScreen();
2578   DCHECK(screen);
2579   gfx::Point root_window_point = screen->GetCursorScreenPoint();
2580   aura::client::ScreenPositionClient* screen_position_client =
2581       aura::client::GetScreenPositionClient(root_window);
2582   if (screen_position_client) {
2583     screen_position_client->ConvertPointFromScreen(
2584         root_window, &root_window_point);
2585   }
2586
2587   if (root_window->GetEventHandlerForPoint(root_window_point) != window_)
2588     return;
2589
2590   gfx::NativeCursor cursor = current_cursor_.GetNativeCursor();
2591   // Do not show loading cursor when the cursor is currently hidden.
2592   if (is_loading_ && cursor != ui::mojom::CursorType::kNone)
2593     cursor = ui::Cursor(ui::mojom::CursorType::kPointer);
2594
2595   aura::client::CursorClient* cursor_client =
2596       aura::client::GetCursorClient(root_window);
2597   if (cursor_client) {
2598     cursor_client->SetCursor(cursor);
2599   }
2600 }
2601
2602 bool RenderWidgetHostViewAura::SynchronizeVisualProperties(
2603     const cc::DeadlinePolicy& deadline_policy,
2604     const absl::optional<viz::LocalSurfaceId>& child_local_surface_id) {
2605   DCHECK(window_);
2606   DCHECK(delegated_frame_host_) << "Cannot be invoked during destruction.";
2607
2608   window_->UpdateLocalSurfaceIdFromEmbeddedClient(child_local_surface_id);
2609   // If the viz::LocalSurfaceId is invalid, we may have been evicted,
2610   // allocate a new one to establish bounds.
2611   if (!GetLocalSurfaceId().is_valid())
2612     window_->AllocateLocalSurfaceId();
2613
2614   delegated_frame_host_->EmbedSurface(
2615       GetLocalSurfaceId(), window_->bounds().size(), deadline_policy);
2616
2617   return host()->SynchronizeVisualProperties();
2618 }
2619
2620 void RenderWidgetHostViewAura::OnDidUpdateVisualPropertiesComplete(
2621     const cc::RenderFrameMetadata& metadata) {
2622   DCHECK(window_);
2623
2624   if (host()->delegate()) {
2625     host()->delegate()->SetTopControlsShownRatio(
2626         host(), metadata.top_controls_shown_ratio);
2627   }
2628
2629   if (host()->is_hidden()) {
2630     // When an embedded child responds, we want to accept its changes to the
2631     // viz::LocalSurfaceId. However we do not want to embed surfaces while
2632     // hidden. Nor do we want to embed invalid ids when we are evicted. Becoming
2633     // visible will generate a new id, if necessary, and begin embedding.
2634     window_->UpdateLocalSurfaceIdFromEmbeddedClient(metadata.local_surface_id);
2635   } else {
2636     SynchronizeVisualProperties(cc::DeadlinePolicy::UseDefaultDeadline(),
2637                                 metadata.local_surface_id);
2638   }
2639 }
2640
2641 ui::InputMethod* RenderWidgetHostViewAura::GetInputMethod() const {
2642   if (!window_)
2643     return nullptr;
2644   aura::Window* root_window = window_->GetRootWindow();
2645   if (!root_window)
2646     return nullptr;
2647   return root_window->GetHost()->GetInputMethod();
2648 }
2649
2650 RenderWidgetHostViewBase*
2651 RenderWidgetHostViewAura::GetFocusedViewForTextSelection() const {
2652   // We obtain the TextSelection from focused RWH which is obtained from the
2653   // frame tree.
2654   return GetFocusedWidget() ? GetFocusedWidget()->GetView() : nullptr;
2655 }
2656
2657 void RenderWidgetHostViewAura::Shutdown() {
2658   if (!in_shutdown_) {
2659     in_shutdown_ = true;
2660     host()->ShutdownAndDestroyWidget(true);
2661   }
2662 }
2663
2664 ui::mojom::VirtualKeyboardMode
2665 RenderWidgetHostViewAura::GetVirtualKeyboardMode() {
2666   // overlaycontent flag can only be set from main frame.
2667   RenderFrameHostImpl* frame = host()->frame_tree()->GetMainFrame();
2668   if (!frame)
2669     return ui::mojom::VirtualKeyboardMode::kUnset;
2670
2671   return frame->GetPage().virtual_keyboard_mode();
2672 }
2673
2674 void RenderWidgetHostViewAura::NotifyVirtualKeyboardOverlayRect(
2675     const gfx::Rect& keyboard_rect) {
2676   // geometrychange event can only be fired on main frame and not focused frame
2677   // which could be an iframe.
2678   RenderFrameHostImpl* frame = host()->frame_tree()->GetMainFrame();
2679   if (!frame)
2680     return;
2681
2682   if (GetVirtualKeyboardMode() !=
2683       ui::mojom::VirtualKeyboardMode::kOverlaysContent) {
2684     return;
2685   }
2686   gfx::Rect keyboard_root_relative_rect = keyboard_rect;
2687   if (!keyboard_root_relative_rect.IsEmpty()) {
2688     // If the rect is non-empty, we need to transform it to be widget-relative
2689     // window (DIP coordinates). The input is client coordinates for the root
2690     // window.
2691     // Transform the widget rect origin to root relative coords.
2692     gfx::PointF root_widget_origin(0.f, 0.f);
2693     TransformPointToRootSurface(&root_widget_origin);
2694     gfx::Rect root_widget_rect =
2695         gfx::Rect(root_widget_origin.x(), root_widget_origin.y(),
2696                   GetViewBounds().width(), GetViewBounds().height());
2697     // Intersect the keyboard rect with the root widget bounds and transform
2698     // back to widget-relative coordinates, which will be sent to the renderer.
2699     keyboard_root_relative_rect.Intersect(root_widget_rect);
2700     keyboard_root_relative_rect.Offset(-root_widget_origin.x(),
2701                                        -root_widget_origin.y());
2702   }
2703   frame->GetPage().NotifyVirtualKeyboardOverlayRect(
2704       keyboard_root_relative_rect);
2705 }
2706
2707 bool RenderWidgetHostViewAura::IsHTMLFormPopup() const {
2708   return !!popup_parent_host_view_;
2709 }
2710
2711 bool RenderWidgetHostViewAura::FocusedFrameHasStickyActivation() const {
2712   // Unless user has interacted with the iframe, we shouldn't be displaying VK
2713   // or fire geometrychange event.
2714   RenderFrameHostImpl* frame = GetFocusedFrame();
2715   if (!frame)
2716     return false;
2717
2718   return frame->frame_tree_node()->HasStickyUserActivation();
2719 }
2720
2721 TouchSelectionControllerClientManager*
2722 RenderWidgetHostViewAura::GetTouchSelectionControllerClientManager() {
2723   return selection_controller_client_.get();
2724 }
2725
2726 bool RenderWidgetHostViewAura::NeedsInputGrab() {
2727   return widget_type_ == WidgetType::kPopup;
2728 }
2729
2730 bool RenderWidgetHostViewAura::NeedsMouseCapture() {
2731 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
2732   return NeedsInputGrab();
2733 #else
2734   return false;
2735 #endif
2736 }
2737
2738 void RenderWidgetHostViewAura::SetTooltipsEnabled(bool enable) {
2739   if (enable) {
2740     tooltip_disabler_.reset();
2741   } else {
2742     tooltip_disabler_ =
2743         std::make_unique<wm::ScopedTooltipDisabler>(window_->GetRootWindow());
2744   }
2745 }
2746
2747 void RenderWidgetHostViewAura::NotifyRendererOfCursorVisibilityState(
2748     bool is_visible) {
2749   if (host()->is_hidden() ||
2750       (cursor_visibility_state_in_renderer_ == VISIBLE && is_visible) ||
2751       (cursor_visibility_state_in_renderer_ == NOT_VISIBLE && !is_visible))
2752     return;
2753
2754   cursor_visibility_state_in_renderer_ = is_visible ? VISIBLE : NOT_VISIBLE;
2755   host()->OnCursorVisibilityStateChanged(is_visible);
2756 }
2757
2758 void RenderWidgetHostViewAura::SetOverscrollControllerEnabled(bool enabled) {
2759   if (!enabled)
2760     overscroll_controller_.reset();
2761   else if (!overscroll_controller_)
2762     overscroll_controller_ = std::make_unique<OverscrollController>();
2763 }
2764
2765 void RenderWidgetHostViewAura::SetSelectionControllerClientForTest(
2766     std::unique_ptr<TouchSelectionControllerClientAura> client) {
2767   selection_controller_client_.swap(client);
2768   CreateSelectionController();
2769 }
2770
2771 void RenderWidgetHostViewAura::InternalSetBounds(const gfx::Rect& rect) {
2772   // Don't recursively call SetBounds if this bounds update is the result of
2773   // a Window::SetBoundsInternal call.
2774   if (!in_bounds_changed_)
2775     window_->SetBounds(rect);
2776
2777   if (!viewport_segments_.empty()) {
2778     // The view bounds have changed so if we have viewport segments from the
2779     // platform we need to make sure display_feature_ is updated considering the
2780     // new view bounds.
2781     ComputeDisplayFeature();
2782   }
2783
2784   // Even if not showing yet, we need to synchronize on size. As the renderer
2785   // needs to begin layout. Waiting until we show to start layout leads to
2786   // significant delays in embedding the first shown surface (500+ ms.)
2787   SynchronizeVisualProperties(cc::DeadlinePolicy::UseDefaultDeadline(),
2788                               window_->GetLocalSurfaceId());
2789
2790 #if BUILDFLAG(IS_WIN)
2791   UpdateLegacyWin();
2792
2793   if (IsMouseLocked())
2794     UpdateMouseLockRegion();
2795 #endif
2796 }
2797
2798 void RenderWidgetHostViewAura::UpdateInsetsWithVirtualKeyboardEnabled() {
2799   // Update insets if the keyboard is shown.
2800   if (!keyboard_occluded_bounds_.IsEmpty()) {
2801     SetInsets(gfx::Insets::TLBR(
2802         0, 0,
2803         gfx::IntersectRects(GetViewBounds(), keyboard_occluded_bounds_)
2804             .height(),
2805         0));
2806   }
2807 }
2808
2809 #if BUILDFLAG(IS_WIN)
2810 void RenderWidgetHostViewAura::UpdateLegacyWin() {
2811   if (legacy_window_destroyed_ || !GetHostWindowHWND())
2812     return;
2813
2814   if (!legacy_render_widget_host_HWND_) {
2815     legacy_render_widget_host_HWND_ =
2816         LegacyRenderWidgetHostHWND::Create(GetHostWindowHWND(), this);
2817   }
2818
2819   if (legacy_render_widget_host_HWND_) {
2820     legacy_render_widget_host_HWND_->UpdateParent(GetHostWindowHWND());
2821     legacy_render_widget_host_HWND_->SetBounds(
2822         window_->GetBoundsInRootWindow());
2823     // There are cases where the parent window is created, made visible and
2824     // the associated RenderWidget is also visible before the
2825     // LegacyRenderWidgetHostHWND instace is created. Ensure that it is shown
2826     // here.
2827     if (!host()->is_hidden())
2828       legacy_render_widget_host_HWND_->Show();
2829   }
2830 }
2831 #endif
2832
2833 void RenderWidgetHostViewAura::AddedToRootWindow() {
2834   DCHECK(delegated_frame_host_) << "Cannot be invoked during destruction.";
2835
2836 #if BUILDFLAG(IS_EFL)
2837   efl_helper_->AuraChildWindowAdded();
2838 #endif
2839
2840   window_->GetHost()->AddObserver(this);
2841   UpdateScreenInfo();
2842
2843   aura::client::CursorClient* cursor_client =
2844       aura::client::GetCursorClient(window_->GetRootWindow());
2845   if (cursor_client) {
2846     cursor_client->AddObserver(this);
2847     NotifyRendererOfCursorVisibilityState(cursor_client->IsCursorVisible());
2848   }
2849   if (HasFocus()) {
2850     ui::InputMethod* input_method = GetInputMethod();
2851     if (input_method)
2852       input_method->SetFocusedTextInputClient(this);
2853   }
2854
2855 #if BUILDFLAG(IS_WIN)
2856   UpdateLegacyWin();
2857 #endif
2858
2859   delegated_frame_host_->AttachToCompositor(GetCompositor());
2860 }
2861
2862 void RenderWidgetHostViewAura::RemovingFromRootWindow() {
2863   DCHECK(delegated_frame_host_) << "Cannot be invoked during destruction.";
2864
2865   aura::client::CursorClient* cursor_client =
2866       aura::client::GetCursorClient(window_->GetRootWindow());
2867   if (cursor_client)
2868     cursor_client->RemoveObserver(this);
2869
2870   DetachFromInputMethod(true);
2871
2872   window_->GetHost()->RemoveObserver(this);
2873   delegated_frame_host_->DetachFromCompositor();
2874
2875 #if BUILDFLAG(IS_WIN)
2876     // Update the legacy window's parent temporarily to the hidden window. It
2877     // will eventually get reparented to the right root.
2878     if (legacy_render_widget_host_HWND_)
2879       legacy_render_widget_host_HWND_->UpdateParent(ui::GetHiddenWindow());
2880 #endif
2881 }
2882
2883 void RenderWidgetHostViewAura::DetachFromInputMethod(bool is_removed) {
2884   ui::InputMethod* input_method = GetInputMethod();
2885   if (input_method) {
2886     input_method->DetachTextInputClient(this);
2887 #if BUILDFLAG(IS_CHROMEOS_ASH)
2888     wm::RestoreWindowBoundsOnClientFocusLost(window_->GetToplevelWindow());
2889 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
2890   }
2891
2892 #if BUILDFLAG(IS_WIN)
2893   // If window is getting destroyed, then reset the VK controller, else,
2894   // dismiss the VK and notify about the keyboard inset since window has lost
2895   // focus.
2896   if (virtual_keyboard_controller_win_) {
2897     if (is_removed)
2898       virtual_keyboard_controller_win_.reset();
2899     else
2900       virtual_keyboard_controller_win_->HideAndNotifyKeyboardInset();
2901   }
2902 #endif  // BUILDFLAG(IS_WIN)
2903 }
2904
2905 void RenderWidgetHostViewAura::ForwardKeyboardEventWithLatencyInfo(
2906     const NativeWebKeyboardEvent& event,
2907     const ui::LatencyInfo& latency,
2908     bool* update_event) {
2909   RenderWidgetHostImpl* target_host = host();
2910
2911   // If there are multiple widgets on the page (such as when there are
2912   // out-of-process iframes), pick the one that should process this event.
2913   if (host()->delegate())
2914     target_host = host()->delegate()->GetFocusedRenderWidgetHost(host());
2915   if (!target_host)
2916     return;
2917
2918 #if BUILDFLAG(IS_LINUX)
2919   auto* linux_ui = ui::LinuxUi::instance();
2920   std::vector<ui::TextEditCommandAuraLinux> commands;
2921   if (!event.skip_if_unhandled && linux_ui && event.os_event &&
2922       linux_ui->GetTextEditCommandsForEvent(
2923           *event.os_event,
2924           base::FeatureList::IsEnabled(
2925               blink::features::kArrowKeysInVerticalWritingModes)
2926               ? GetTextInputFlags()
2927               : ui::TEXT_INPUT_FLAG_NONE,
2928           &commands)) {
2929     // Transform from ui/ types to content/ types.
2930     std::vector<blink::mojom::EditCommandPtr> edit_commands;
2931     for (std::vector<ui::TextEditCommandAuraLinux>::const_iterator it =
2932              commands.begin(); it != commands.end(); ++it) {
2933       edit_commands.push_back(blink::mojom::EditCommand::New(
2934           it->GetCommandString(), it->argument()));
2935     }
2936
2937     target_host->ForwardKeyboardEventWithCommands(
2938         event, latency, std::move(edit_commands), update_event);
2939     return;
2940   }
2941 #endif
2942
2943   target_host->ForwardKeyboardEventWithCommands(
2944       event, latency, std::vector<blink::mojom::EditCommandPtr>(),
2945       update_event);
2946 }
2947
2948 void RenderWidgetHostViewAura::CreateSelectionController() {
2949   ui::TouchSelectionController::Config tsc_config;
2950   tsc_config.max_tap_duration = base::Milliseconds(
2951       ui::GestureConfiguration::GetInstance()->long_press_time_in_ms());
2952   tsc_config.tap_slop = ui::GestureConfiguration::GetInstance()
2953                             ->max_touch_move_in_pixels_for_click();
2954   tsc_config.enable_longpress_drag_selection =
2955       features::IsTouchTextEditingRedesignEnabled();
2956   selection_controller_ = std::make_unique<ui::TouchSelectionController>(
2957       selection_controller_client_.get(), tsc_config);
2958 }
2959
2960 void RenderWidgetHostViewAura::DidNavigateMainFramePreCommit() {
2961   DCHECK(delegated_frame_host_) << "Cannot be invoked during destruction.";
2962
2963   // Invalidate the surface so that we don't attempt to evict it multiple times.
2964   window_->InvalidateLocalSurfaceId();
2965   delegated_frame_host_->DidNavigateMainFramePreCommit();
2966   CancelActiveTouches();
2967 }
2968
2969 void RenderWidgetHostViewAura::DidEnterBackForwardCache() {
2970   CHECK(delegated_frame_host_) << "Cannot be invoked during destruction.";
2971
2972   window_->AllocateLocalSurfaceId();
2973   delegated_frame_host_->DidEnterBackForwardCache();
2974   // If we have the fallback content timer running, force it to stop. Else, when
2975   // the page is restored the timer could also fire, setting whatever
2976   // `DelegatedFrameHost::first_local_surface_id_after_navigation_` as the
2977   // fallback to our Surfacelayer.
2978   //
2979   // This is safe for BFCache restore because we will supply specific fallback
2980   // surfaces for BFCache.
2981   //
2982   // We do not want to call this in `RWHImpl::WasHidden()` because in the case
2983   // of `Visibility::OCCLUDED` we still want to keep the timer running.
2984   //
2985   // Called after to prevent prematurely evict the BFCached surface.
2986   host()->ForceFirstFrameAfterNavigationTimeout();
2987 }
2988
2989 const viz::FrameSinkId& RenderWidgetHostViewAura::GetFrameSinkId() const {
2990   return frame_sink_id_;
2991 }
2992
2993 const viz::LocalSurfaceId& RenderWidgetHostViewAura::GetLocalSurfaceId() const {
2994   return window_->GetLocalSurfaceId();
2995 }
2996
2997 void RenderWidgetHostViewAura::OnUpdateTextInputStateCalled(
2998     TextInputManager* text_input_manager,
2999     RenderWidgetHostViewBase* updated_view,
3000     bool did_update_state) {
3001   DCHECK_EQ(text_input_manager_, text_input_manager);
3002
3003   if (!GetInputMethod())
3004     return;
3005
3006   if (did_update_state)
3007     GetInputMethod()->OnTextInputTypeChanged(this);
3008
3009   const ui::mojom::TextInputState* state =
3010       text_input_manager_->GetTextInputState();
3011
3012 #if BUILDFLAG(IS_CHROMEOS)
3013   if (state && state->type != ui::TEXT_INPUT_TYPE_NONE) {
3014     if (state->last_vk_visibility_request ==
3015         ui::mojom::VirtualKeyboardVisibilityRequest::SHOW) {
3016       GetInputMethod()->SetVirtualKeyboardVisibilityIfEnabled(true);
3017     } else if (state->last_vk_visibility_request ==
3018                ui::mojom::VirtualKeyboardVisibilityRequest::HIDE) {
3019       GetInputMethod()->SetVirtualKeyboardVisibilityIfEnabled(false);
3020     }
3021   }
3022 #endif
3023
3024   // Show the virtual keyboard if needed.
3025   if (state && state->type != ui::TEXT_INPUT_TYPE_NONE &&
3026       state->mode != ui::TEXT_INPUT_MODE_NONE) {
3027 #if !BUILDFLAG(IS_WIN)
3028     if (state->show_ime_if_needed &&
3029         GetInputMethod()->GetTextInputClient() == this) {
3030       GetInputMethod()->SetVirtualKeyboardVisibilityIfEnabled(true);
3031     }
3032 // TODO(crbug.com/1031786): Remove this once TSF fix for input pane policy
3033 // is serviced
3034 #elif BUILDFLAG(IS_WIN)
3035     if (GetInputMethod()) {
3036       if (!virtual_keyboard_controller_win_) {
3037         virtual_keyboard_controller_win_ =
3038             std::make_unique<VirtualKeyboardControllerWin>(this,
3039                                                            GetInputMethod());
3040       }
3041       virtual_keyboard_controller_win_->UpdateTextInputState(state);
3042     }
3043 #endif
3044   }
3045
3046   // Ensure that selection bounds changes are sent to the IME.
3047   if (state && state->type != ui::TEXT_INPUT_TYPE_NONE) {
3048     text_input_manager->NotifySelectionBoundsChanged(updated_view);
3049   }
3050
3051   if (auto* render_widget_host = updated_view->host()) {
3052     // Monitor the composition information if there is a focused editable node.
3053     render_widget_host->RequestCompositionUpdates(
3054         false /* immediate_request */,
3055         state &&
3056             (state->type != ui::TEXT_INPUT_TYPE_NONE) /* monitor_updates */);
3057   }
3058 }
3059
3060 void RenderWidgetHostViewAura::OnImeCancelComposition(
3061     TextInputManager* text_input_manager,
3062     RenderWidgetHostViewBase* view) {
3063   // |view| is not necessarily the one corresponding to
3064   // TextInputManager::GetActiveWidget() as RenderWidgetHostViewAura can call
3065   // this method to finish any ongoing composition in response to a mouse down
3066   // event.
3067   if (GetInputMethod())
3068     GetInputMethod()->CancelComposition(this);
3069   has_composition_text_ = false;
3070 }
3071
3072 void RenderWidgetHostViewAura::OnSelectionBoundsChanged(
3073     TextInputManager* text_input_manager,
3074     RenderWidgetHostViewBase* updated_view) {
3075   // Note: accessibility caret move events are no longer fired directly here,
3076   // because they were redundant with the events fired by the top level window
3077   // by HWNDMessageHandler::OnCaretBoundsChanged().
3078   if (GetInputMethod())
3079     GetInputMethod()->OnCaretBoundsChanged(this);
3080 }
3081
3082 void RenderWidgetHostViewAura::OnTextSelectionChanged(
3083     TextInputManager* text_input_manager,
3084     RenderWidgetHostViewBase* updated_view) {
3085   if (!GetTextInputManager())
3086     return;
3087
3088   // We obtain the TextSelection from focused RWH which is obtained from the
3089   // frame tree.
3090   RenderWidgetHostViewBase* focused_view =
3091       GetFocusedWidget() ? GetFocusedWidget()->GetView() : nullptr;
3092
3093   if (!focused_view)
3094     return;
3095
3096   // IMF relies on the |OnCaretBoundsChanged| for the surrounding text changed
3097   // events to IME. Explicitly call |OnCaretBoundsChanged| here so that IMF can
3098   // know about the surrounding text changes when the caret bounds are not
3099   // changed. e.g. When the rendered text is wider than the input field,
3100   // deleting the last character won't change the caret bounds but will change
3101   // the surrounding text.
3102   if (GetInputMethod())
3103     GetInputMethod()->OnCaretBoundsChanged(this);
3104
3105   if (ui::Clipboard::IsSupportedClipboardBuffer(
3106           ui::ClipboardBuffer::kSelection)) {
3107     const TextInputManager::TextSelection* selection =
3108         GetTextInputManager()->GetTextSelection(focused_view);
3109     if (selection->selected_text().length()) {
3110       // Set the ClipboardBuffer::kSelection to the ui::Clipboard.
3111       ui::ScopedClipboardWriter clipboard_writer(
3112           ui::ClipboardBuffer::kSelection);
3113       clipboard_writer.WriteText(selection->selected_text());
3114     }
3115   }
3116 }
3117
3118 void RenderWidgetHostViewAura::SetPopupChild(
3119     RenderWidgetHostViewAura* popup_child_host_view) {
3120   popup_child_host_view_ = popup_child_host_view;
3121   event_handler_->SetPopupChild(
3122       popup_child_host_view,
3123       popup_child_host_view ? popup_child_host_view->event_handler() : nullptr);
3124 }
3125
3126 void RenderWidgetHostViewAura::ScrollFocusedEditableNodeIntoView() {
3127   auto* input_handler = GetFrameWidgetInputHandlerForFocusedWidget();
3128   if (!input_handler)
3129     return;
3130   input_handler->ScrollFocusedEditableNodeIntoView();
3131 }
3132
3133 void RenderWidgetHostViewAura::OnSynchronizedDisplayPropertiesChanged(
3134     bool rotation) {
3135   SynchronizeVisualProperties(cc::DeadlinePolicy::UseDefaultDeadline(),
3136                               absl::nullopt);
3137 }
3138
3139 viz::ScopedSurfaceIdAllocator
3140 RenderWidgetHostViewAura::DidUpdateVisualProperties(
3141     const cc::RenderFrameMetadata& metadata) {
3142   base::OnceCallback<void()> allocation_task = base::BindOnce(
3143       &RenderWidgetHostViewAura::OnDidUpdateVisualPropertiesComplete,
3144       weak_ptr_factory_.GetWeakPtr(), metadata);
3145   return window_->GetSurfaceIdAllocator(std::move(allocation_task));
3146 }
3147
3148 void RenderWidgetHostViewAura::DidNavigate() {
3149   DCHECK(delegated_frame_host_) << "Cannot be invoked during destruction.";
3150
3151   if (!IsShowing()) {
3152     // Navigating while hidden should not allocate a new LocalSurfaceID. Once
3153     // sizes are ready, or we begin to Show, we can then allocate the new
3154     // LocalSurfaceId.
3155     window_->InvalidateLocalSurfaceId();
3156   } else {
3157     if (is_first_navigation_) {
3158       // The first navigation does not need a new LocalSurfaceID. The renderer
3159       // can use the ID that was already provided.
3160       SynchronizeVisualProperties(cc::DeadlinePolicy::UseExistingDeadline(),
3161                                   window_->GetLocalSurfaceId());
3162     } else {
3163       SynchronizeVisualProperties(cc::DeadlinePolicy::UseExistingDeadline(),
3164                                   absl::nullopt);
3165     }
3166   }
3167   delegated_frame_host_->DidNavigate();
3168   is_first_navigation_ = false;
3169 }
3170
3171 MouseWheelPhaseHandler* RenderWidgetHostViewAura::GetMouseWheelPhaseHandler() {
3172   return &event_handler_->mouse_wheel_phase_handler();
3173 }
3174
3175 void RenderWidgetHostViewAura::TakeFallbackContentFrom(
3176     RenderWidgetHostView* view) {
3177   DCHECK(!static_cast<RenderWidgetHostViewBase*>(view)
3178               ->IsRenderWidgetHostViewChildFrame());
3179   RenderWidgetHostViewAura* view_aura =
3180       static_cast<RenderWidgetHostViewAura*>(view);
3181   CopyBackgroundColorIfPresentFrom(*view);
3182
3183   DCHECK(delegated_frame_host_) << "Cannot be invoked during destruction.";
3184   DCHECK(view_aura->delegated_frame_host_);
3185   delegated_frame_host_->TakeFallbackContentFrom(
3186       view_aura->delegated_frame_host_.get());
3187 }
3188
3189 bool RenderWidgetHostViewAura::CanSynchronizeVisualProperties() {
3190   return !needs_to_update_display_metrics_;
3191 }
3192
3193 std::vector<std::unique_ptr<ui::TouchEvent>>
3194 RenderWidgetHostViewAura::ExtractAndCancelActiveTouches() {
3195   aura::Env* env = aura::Env::GetInstance();
3196   std::vector<std::unique_ptr<ui::TouchEvent>> touches =
3197       env->gesture_recognizer()->ExtractTouches(window());
3198   CancelActiveTouches();
3199   return touches;
3200 }
3201
3202 void RenderWidgetHostViewAura::TransferTouches(
3203     const std::vector<std::unique_ptr<ui::TouchEvent>>& touches) {
3204   aura::Env* env = aura::Env::GetInstance();
3205   env->gesture_recognizer()->TransferTouches(window(), touches);
3206 }
3207
3208 void RenderWidgetHostViewAura::SetLastPointerType(
3209     ui::EventPointerType last_pointer_type) {
3210   last_pointer_type_ = last_pointer_type;
3211 }
3212
3213 void RenderWidgetHostViewAura::InvalidateLocalSurfaceIdAndAllocationGroup() {
3214   window_->InvalidateLocalSurfaceId(/*also_invalidate_allocation_group=*/true);
3215 }
3216
3217 void RenderWidgetHostViewAura::InvalidateLocalSurfaceIdOnEviction() {
3218   window_->InvalidateLocalSurfaceId();
3219 }
3220
3221 void RenderWidgetHostViewAura::ProcessDisplayMetricsChanged() {
3222   // TODO(crbug.com/1169291): Unify per-platform DisplayObserver instances.
3223   needs_to_update_display_metrics_ = false;
3224   UpdateScreenInfo();
3225   current_cursor_.SetDisplayInfo(
3226       display::Screen::GetScreen()->GetDisplayNearestWindow(window_));
3227   UpdateCursorIfOverSelf();
3228 }
3229
3230 void RenderWidgetHostViewAura::CancelActiveTouches() {
3231   aura::Env* env = aura::Env::GetInstance();
3232   env->gesture_recognizer()->CancelActiveTouches(window());
3233 }
3234
3235 blink::mojom::FrameWidgetInputHandler*
3236 RenderWidgetHostViewAura::GetFrameWidgetInputHandlerForFocusedWidget() {
3237   auto* focused_widget = GetFocusedWidget();
3238   if (!focused_widget)
3239     return nullptr;
3240   return focused_widget->GetFrameWidgetInputHandler();
3241 }
3242
3243 void RenderWidgetHostViewAura::SetTooltipText(
3244     const std::u16string& tooltip_text) {
3245   tooltip_ = tooltip_text;
3246   if (tooltip_observer_for_testing_)
3247     tooltip_observer_for_testing_->OnTooltipTextUpdated(tooltip_text);
3248 }
3249
3250 ui::Compositor* RenderWidgetHostViewAura::GetCompositor() {
3251   if (!window_ || !window_->GetHost())
3252     return nullptr;
3253
3254   return window_->GetHost()->compositor();
3255 }
3256
3257 }  // namespace content