1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be found
3 // in the LICENSE file.
4 
5 #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_WEB_VIEW_FRAME_WIDGET_H_
6 #define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_WEB_VIEW_FRAME_WIDGET_H_
7 
8 #include "base/macros.h"
9 #include "base/memory/scoped_refptr.h"
10 #include "base/single_thread_task_runner.h"
11 #include "base/util/type_safety/pass_key.h"
12 #include "third_party/blink/renderer/core/core_export.h"
13 #include "third_party/blink/renderer/core/exported/web_page_popup_impl.h"
14 #include "third_party/blink/renderer/core/frame/web_frame_widget_base.h"
15 #include "third_party/blink/renderer/core/frame/web_local_frame_impl.h"
16 #include "third_party/blink/renderer/platform/graphics/apply_viewport_changes.h"
17 #include "third_party/blink/renderer/platform/heap/member.h"
18 #include "third_party/blink/renderer/platform/heap/self_keep_alive.h"
19 
20 namespace blink {
21 
22 class WebFrameWidget;
23 class WebViewImpl;
24 class WebWidgetClient;
25 
26 // Shim class to help normalize the widget interfaces in the Blink public API.
27 // For OOPI, subframes have WebFrameWidgets for input and rendering.
28 // Unfortunately, the main frame still uses WebView's WebWidget for input and
29 // rendering. This results in complex code, since there are two different
30 // implementations of WebWidget and code needs to have branches to handle both
31 // cases.
32 // This class allows a Blink embedder to create a WebFrameWidget that can be
33 // used for the main frame. Internally, it currently wraps WebView's WebWidget
34 // and just forwards almost everything to it.
35 // After the embedder starts using a WebFrameWidget for the main frame,
36 // WebView will be updated to no longer inherit WebWidget. The eventual goal is
37 // to unfork the widget code duplicated in WebFrameWidgetImpl and WebViewImpl
38 // into one class.
39 // A more detailed writeup of this transition can be read at
40 // https://goo.gl/7yVrnb.
41 class CORE_EXPORT WebViewFrameWidget : public WebFrameWidgetBase {
42  public:
43   WebViewFrameWidget(
44       util::PassKey<WebFrameWidget>,
45       WebWidgetClient&,
46       WebViewImpl&,
47       CrossVariantMojoAssociatedRemote<
48           mojom::blink::FrameWidgetHostInterfaceBase> frame_widget_host,
49       CrossVariantMojoAssociatedReceiver<mojom::blink::FrameWidgetInterfaceBase>
50           frame_widget,
51       CrossVariantMojoAssociatedRemote<mojom::blink::WidgetHostInterfaceBase>
52           widget_host,
53       CrossVariantMojoAssociatedReceiver<mojom::blink::WidgetInterfaceBase>
54           widget,
55       scoped_refptr<base::SingleThreadTaskRunner> task_runner,
56       const viz::FrameSinkId& frame_sink_id,
57       bool is_for_nested_main_frame,
58       bool hidden,
59       bool never_composited);
60   ~WebViewFrameWidget() override;
61 
62   // WebWidget overrides:
63   void Close(
64       scoped_refptr<base::SingleThreadTaskRunner> cleanup_runner) override;
65   gfx::Size Size() override;
66   void Resize(const gfx::Size& size_with_dsf) override;
67   void UpdateLifecycle(WebLifecycleUpdate requested_update,
68                        DocumentUpdateReason reason) override;
69   void MouseCaptureLost() override;
70 
71   // blink::mojom::FrameWidget
72   void EnableDeviceEmulation(const DeviceEmulationParams& parameters) override;
73   void DisableDeviceEmulation() override;
74 
75   // WebFrameWidget overrides:
76   bool ScrollFocusedEditableElementIntoView() override;
77   void SetZoomLevelForTesting(double zoom_level) override;
78   void ResetZoomLevelForTesting() override;
79   void SetDeviceScaleFactorForTesting(float factor) override;
80 
81   // WebFrameWidgetBase overrides:
ForSubframe()82   bool ForSubframe() const override { return false; }
ForTopLevelFrame()83   bool ForTopLevelFrame() const override { return !is_for_nested_main_frame_; }
84   void ZoomToFindInPageRect(const WebRect& rect_in_root_frame) override;
85   void SetZoomLevel(double zoom_level) override;
86   void SetAutoResizeMode(bool auto_resize,
87                          const gfx::Size& min_size_before_dsf,
88                          const gfx::Size& max_size_before_dsf,
89                          float device_scale_factor) override;
90   void SetPageScaleStateAndLimits(float page_scale_factor,
91                                   bool is_pinch_gesture_active,
92                                   float minimum,
93                                   float maximum) override;
94   ScreenMetricsEmulator* DeviceEmulator() override;
95   const ScreenInfo& GetOriginalScreenInfo() override;
96   void ApplyVisualPropertiesSizing(
97       const VisualProperties& visual_properties) override;
98   void CalculateSelectionBounds(gfx::Rect& anchor, gfx::Rect& focus) override;
99 
100   // FrameWidget overrides:
101   void SetRootLayer(scoped_refptr<cc::Layer>) override;
102   bool ShouldHandleImeEvents() override;
103   float GetEmulatorScale() override;
104 
105   // WidgetBaseClient overrides:
106   void ApplyViewportChanges(const cc::ApplyViewportChangesArgs& args) override;
107   void RecordManipulationTypeCounts(cc::ManipulationInfo info) override;
108   void FocusChanged(bool enabled) override;
109   float GetDeviceScaleFactorForTesting() override;
110   gfx::Rect ViewportVisibleRect() override;
111   bool UpdateScreenRects(const gfx::Rect& widget_screen_rect,
112                          const gfx::Rect& window_screen_rect) override;
113   void RunPaintBenchmark(int repeat_count,
114                          cc::PaintBenchmarkResult& result) override;
115 
116   void SetScreenMetricsEmulationParameters(
117       bool enabled,
118       const blink::DeviceEmulationParams& params);
119   void SetScreenInfoAndSize(const blink::ScreenInfo& screen_info,
120                             const gfx::Size& widget_size,
121                             const gfx::Size& visible_viewport_size);
122 
123   void Trace(Visitor*) const override;
124 
125   void SetIsNestedMainFrameWidget(bool is_nested);
126   void DidAutoResize(const gfx::Size& size);
127   void SetDeviceColorSpaceForTesting(const gfx::ColorSpace& color_space);
128   bool AutoResizeMode();
129   void SetWindowRect(const gfx::Rect& window_rect);
130   void SetWindowRectSynchronouslyForTesting(const gfx::Rect& new_window_rect);
131   void UseSynchronousResizeModeForTesting(bool enable);
132 
133   // Converts from DIPs to Blink coordinate space (ie. Viewport/Physical
134   // pixels).
135   gfx::Size DIPsToCeiledBlinkSpace(const gfx::Size& size);
136 
137  private:
138   // PageWidgetEventHandler overrides:
139   void HandleMouseLeave(LocalFrame&, const WebMouseEvent&) override;
140   WebInputEventResult HandleGestureEvent(const WebGestureEvent&) override;
141   WebInputEventResult HandleKeyEvent(const WebKeyboardEvent&) override;
142 
143   LocalFrameView* GetLocalFrameViewForAnimationScrolling() override;
144   void SetWindowRectSynchronously(const gfx::Rect& new_window_rect);
145 
146   scoped_refptr<WebViewImpl> web_view_;
147 
148   // Web tests override the zoom factor in the renderer with this. We store it
149   // to keep the override if the browser passes along VisualProperties with the
150   // real device scale factor. A value of -INFINITY means this is ignored.
151   double zoom_level_for_testing_ = -INFINITY;
152 
153   // Web tests override the device scale factor in the renderer with this. We
154   // store it to keep the override if the browser passes along VisualProperties
155   // with the real device scale factor. A value of 0.f means this is ignored.
156   float device_scale_factor_for_testing_ = 0;
157 
158   // This bit is used to tell if this is a nested widget (an "inner web
159   // contents") like a <webview> or <portal> widget. If false, the widget is the
160   // top level widget.
161   bool is_for_nested_main_frame_ = false;
162 
163   // Present when emulation is enabled, only in a main frame WidgetBase. Used
164   // to override values given from the browser such as ScreenInfo,
165   // WidgetScreenRect, WindowScreenRect, and the widget's size.
166   Member<ScreenMetricsEmulator> device_emulator_;
167 
168   // In web tests, synchronous resizing mode may be used. Normally each widget's
169   // size is controlled by IPC from the browser. In synchronous resize mode the
170   // renderer controls the size directly, and IPCs from the browser must be
171   // ignored. This was deprecated but then later undeprecated, so it is now
172   // called unfortunate instead. See https://crbug.com/309760. When this is
173   // enabled the various size properties will be controlled directly when
174   // SetWindowRect() is called instead of needing a round trip through the
175   // browser.
176   // Note that SetWindowRectSynchronouslyForTesting() provides a secondary way
177   // to control the size of the FrameWidget independently from the renderer
178   // process, without the use of this mode, however it would be overridden by
179   // the browser if they disagree.
180   bool synchronous_resize_mode_for_testing_ = false;
181 
182   // The size of the widget in viewport coordinates. This is slightly different
183   // than the WebViewImpl::size_ since isn't set in auto resize mode.
184   gfx::Size size_;
185 
186   // This stores the last hidden page popup. If a GestureTap attempts to open
187   // the popup that is closed by its previous GestureTapDown, the popup remains
188   // closed.
189   scoped_refptr<WebPagePopupImpl> last_hidden_page_popup_;
190 
191   SelfKeepAlive<WebViewFrameWidget> self_keep_alive_;
192 
193   DISALLOW_COPY_AND_ASSIGN(WebViewFrameWidget);
194 };
195 
196 // Convenience type for creation method taken by
197 // InstallCreateWebViewFrameWidgetHook(). The method signature matches the
198 // WebViewFrameWidget constructor.
199 using CreateWebViewFrameWidgetFunction =
200     WebViewFrameWidget* (*)(util::PassKey<WebFrameWidget>,
201                             WebWidgetClient&,
202                             WebViewImpl&,
203                             CrossVariantMojoAssociatedRemote<
204                                 mojom::blink::FrameWidgetHostInterfaceBase>
205                                 frame_widget_host,
206                             CrossVariantMojoAssociatedReceiver<
207                                 mojom::blink::FrameWidgetInterfaceBase>
208                                 frame_widget,
209                             CrossVariantMojoAssociatedRemote<
210                                 mojom::blink::WidgetHostInterfaceBase>
211                                 widget_host,
212                             CrossVariantMojoAssociatedReceiver<
213                                 mojom::blink::WidgetInterfaceBase> widget,
214                             scoped_refptr<base::SingleThreadTaskRunner>
215                                 task_runner,
216                             const viz::FrameSinkId& frame_sink_id,
217                             bool is_for_nested_main_frame,
218                             bool hidden,
219                             bool never_composited);
220 // Overrides the implementation of WebFrameWidget::CreateForMainFrame() function
221 // below. Used by tests to override some functionality on WebViewFrameWidget.
222 void CORE_EXPORT InstallCreateWebViewFrameWidgetHook(
223     CreateWebViewFrameWidgetFunction create_widget);
224 
225 }  // namespace blink
226 
227 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_WEB_VIEW_FRAME_WIDGET_H_
228