blob: b638c3402cbe100ed3271bf6aa3a48ba4e035ba1 [file] [log] [blame]
/*
* Copyright (C) 2014 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_WEB_FRAME_WIDGET_IMPL_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_WEB_FRAME_WIDGET_IMPL_H_
#include "base/memory/weak_ptr.h"
#include "base/single_thread_task_runner.h"
#include "base/types/pass_key.h"
#include "build/build_config.h"
#include "cc/input/event_listener_properties.h"
#include "cc/input/layer_selection_bound.h"
#include "cc/input/overscroll_behavior.h"
#include "cc/trees/layer_tree_host.h"
#include "services/viz/public/mojom/hit_test/input_target_client.mojom-blink.h"
#include "third_party/blink/public/common/input/web_coalesced_input_event.h"
#include "third_party/blink/public/common/input/web_gesture_device.h"
#include "third_party/blink/public/mojom/input/input_handler.mojom-blink.h"
#include "third_party/blink/public/mojom/manifest/display_mode.mojom-blink.h"
#include "third_party/blink/public/mojom/page/drag.mojom-blink.h"
#include "third_party/blink/public/mojom/page/widget.mojom-blink.h"
#include "third_party/blink/public/mojom/scroll/scroll_into_view_params.mojom-blink-forward.h"
#include "third_party/blink/public/platform/cross_variant_mojo_util.h"
#include "third_party/blink/public/platform/web_drag_data.h"
#include "third_party/blink/public/web/web_frame_widget.h"
#include "third_party/blink/public/web/web_meaningful_layout.h"
#include "third_party/blink/renderer/core/clipboard/data_object.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/exported/web_page_popup_impl.h"
#include "third_party/blink/renderer/core/frame/web_local_frame_impl.h"
#include "third_party/blink/renderer/core/html/battery_savings.h"
#include "third_party/blink/renderer/core/page/event_with_hit_test_results.h"
#include "third_party/blink/renderer/core/page/page_widget_delegate.h"
#include "third_party/blink/renderer/platform/graphics/apply_viewport_changes.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_image.h"
#include "third_party/blink/renderer/platform/heap/member.h"
#include "third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver.h"
#include "third_party/blink/renderer/platform/mojo/heap_mojo_associated_remote.h"
#include "third_party/blink/renderer/platform/mojo/heap_mojo_receiver.h"
#include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h"
#include "third_party/blink/renderer/platform/text/text_direction.h"
#include "third_party/blink/renderer/platform/widget/frame_widget.h"
#include "third_party/blink/renderer/platform/widget/widget_base_client.h"
#include "third_party/blink/renderer/platform/wtf/casting.h"
#include "ui/base/dragdrop/mojom/drag_drop_types.mojom-shared.h"
#include "ui/base/mojom/ui_base_types.mojom-shared.h"
namespace gfx {
class Point;
class PointF;
} // namespace gfx
namespace blink {
class AnimationWorkletMutatorDispatcherImpl;
class FloatPoint;
class HitTestResult;
class HTMLPlugInElement;
class Page;
class PageWidgetEventHandler;
class PaintWorkletPaintDispatcher;
class RemoteFrame;
class WebLocalFrameImpl;
class WebPlugin;
class WebViewImpl;
class WidgetBase;
class ScreenMetricsEmulator;
// Implements WebFrameWidget for both main frames and child local root frame
// (OOPIF).
class CORE_EXPORT WebFrameWidgetImpl
: public GarbageCollected<WebFrameWidgetImpl>,
public WebFrameWidget,
public WidgetBaseClient,
public mojom::blink::FrameWidget,
public viz::mojom::blink::InputTargetClient,
public mojom::blink::FrameWidgetInputHandler,
public FrameWidget,
public PageWidgetEventHandler {
public:
WebFrameWidgetImpl(
base::PassKey<WebLocalFrame>,
CrossVariantMojoAssociatedRemote<
mojom::blink::FrameWidgetHostInterfaceBase> frame_widget_host,
CrossVariantMojoAssociatedReceiver<mojom::blink::FrameWidgetInterfaceBase>
frame_widget,
CrossVariantMojoAssociatedRemote<mojom::blink::WidgetHostInterfaceBase>
widget_host,
CrossVariantMojoAssociatedReceiver<mojom::blink::WidgetInterfaceBase>
widget,
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
const viz::FrameSinkId& frame_sink_id,
bool hidden,
bool never_composited,
bool is_for_child_local_root,
bool is_for_nested_main_frame);
~WebFrameWidgetImpl() override;
virtual void Trace(Visitor*) const;
// Shutdown the widget.
void Close();
// Returns the WebFrame that this widget is attached to. It will be a local
// root since only local roots have a widget attached.
WebLocalFrameImpl* LocalRootImpl() const { return local_root_; }
// Returns the bounding box of the block type node touched by the WebPoint.
gfx::Rect ComputeBlockBound(const gfx::Point& point_in_root_frame,
bool ignore_clipping) const;
virtual void BindLocalRoot(WebLocalFrame&);
// If this widget is for the top most main frame. This is different than
// |ForMainFrame| because |ForMainFrame| could return true but this method
// returns false. If this widget is a MainFrame widget embedded in another
// widget, for example embedding a portal.
bool ForTopMostMainFrame() const;
// Adjusts whether the widget is nested or not. This is called during portal
// transitions.
void SetIsNestedMainFrameWidget(bool is_nested);
// Returns true if this widget is for a local root that is a child frame,
// false otherwise.
bool ForSubframe() const { return is_for_child_local_root_; }
// Opposite of |ForSubframe|. If this widget is for the local main frame.
bool ForMainFrame() const { return !ForSubframe(); }
// Called when the intrinsic size of the owning container is changing its
// size. This should only be called when `ForSubframe` is true.
void IntrinsicSizingInfoChanged(mojom::blink::IntrinsicSizingInfoPtr);
void AutoscrollStart(const gfx::PointF& position);
void AutoscrollFling(const gfx::Vector2dF& position);
void AutoscrollEnd();
bool HandleCurrentKeyboardEvent();
// Creates or returns cached mutator dispatcher. This usually requires a
// round trip to the compositor. The returned WeakPtr must only be
// dereferenced on the output |mutator_task_runner|.
base::WeakPtr<AnimationWorkletMutatorDispatcherImpl>
EnsureCompositorMutatorDispatcher(
scoped_refptr<base::SingleThreadTaskRunner> mutator_task_runner);
// TODO: consider merge the input and return value to be one parameter.
// Creates or returns cached paint dispatcher. The returned WeakPtr must only
// be dereferenced on the output |paint_task_runner|.
base::WeakPtr<PaintWorkletPaintDispatcher> EnsureCompositorPaintDispatcher(
scoped_refptr<base::SingleThreadTaskRunner>* paint_task_runner);
HitTestResult CoreHitTestResultAt(const gfx::PointF&);
// FrameWidget overrides.
cc::AnimationHost* AnimationHost() const final;
void SetOverscrollBehavior(
const cc::OverscrollBehavior& overscroll_behavior) final;
void RequestAnimationAfterDelay(const base::TimeDelta&) final;
void SetRootLayer(scoped_refptr<cc::Layer>) override;
void RegisterSelection(cc::LayerSelection selection) final;
void RequestDecode(const cc::PaintImage&,
base::OnceCallback<void(bool)>) override;
void NotifyPresentationTimeInBlink(
WebReportTimeCallback presentation_callback) final;
void RequestBeginMainFrameNotExpected(bool request) final;
int GetLayerTreeId() final;
const cc::LayerTreeSettings& GetLayerTreeSettings() final;
void UpdateBrowserControlsState(cc::BrowserControlsState constraints,
cc::BrowserControlsState current,
bool animate) final;
void SetEventListenerProperties(cc::EventListenerClass,
cc::EventListenerProperties) final;
cc::EventListenerProperties EventListenerProperties(
cc::EventListenerClass) const final;
mojom::blink::DisplayMode DisplayMode() const override;
const WebVector<gfx::Rect>& WindowSegments() const override;
void SetDelegatedInkMetadata(
std::unique_ptr<viz::DelegatedInkMetadata> metadata) final;
void DidOverscroll(const gfx::Vector2dF& overscroll_delta,
const gfx::Vector2dF& accumulated_overscroll,
const gfx::PointF& position,
const gfx::Vector2dF& velocity) override;
void InjectGestureScrollEvent(WebGestureDevice device,
const gfx::Vector2dF& delta,
ui::ScrollGranularity granularity,
cc::ElementId scrollable_area_element_id,
WebInputEvent::Type injected_type) override;
void DidChangeCursor(const ui::Cursor&) override;
void GetCompositionCharacterBoundsInWindow(
Vector<gfx::Rect>* bounds_in_dips) override;
gfx::Range CompositionRange() override;
WebTextInputInfo TextInputInfo() override;
ui::mojom::VirtualKeyboardVisibilityRequest
GetLastVirtualKeyboardVisibilityRequest() override;
bool ShouldSuppressKeyboardForFocusedElement() override;
void GetEditContextBoundsInWindow(
base::Optional<gfx::Rect>* control_bounds,
base::Optional<gfx::Rect>* selection_bounds) override;
int32_t ComputeWebTextInputNextPreviousFlags() override;
void ResetVirtualKeyboardVisibilityRequest() override;
bool GetSelectionBoundsInWindow(gfx::Rect* focus,
gfx::Rect* anchor,
base::i18n::TextDirection* focus_dir,
base::i18n::TextDirection* anchor_dir,
bool* is_anchor_first) override;
void ClearTextInputState() override;
bool SetComposition(const String& text,
const Vector<ui::ImeTextSpan>& ime_text_spans,
const gfx::Range& replacement_range,
int selection_start,
int selection_end) override;
void CommitText(const String& text,
const Vector<ui::ImeTextSpan>& ime_text_spans,
const gfx::Range& replacement_range,
int relative_cursor_pos) override;
void FinishComposingText(bool keep_selection) override;
bool IsProvisional() override;
uint64_t GetScrollableContainerIdAt(
const gfx::PointF& point_in_dips) override;
bool ShouldHandleImeEvents() override;
void SetEditCommandsForNextKeyEvent(
Vector<mojom::blink::EditCommandPtr> edit_commands) override;
Vector<ui::mojom::blink::ImeTextSpanInfoPtr> GetImeTextSpansInfo(
const WebVector<ui::ImeTextSpan>& ime_text_spans) override;
void RequestMouseLock(
bool has_transient_user_activation,
bool request_unadjusted_movement,
mojom::blink::WidgetInputHandlerHost::RequestMouseLockCallback callback)
override;
gfx::RectF BlinkSpaceToDIPs(const gfx::RectF& rect) override;
gfx::Rect BlinkSpaceToEnclosedDIPs(const gfx::Rect& rect) override;
gfx::Size BlinkSpaceToFlooredDIPs(const gfx::Size& size) override;
gfx::RectF DIPsToBlinkSpace(const gfx::RectF& rect) override;
gfx::PointF DIPsToBlinkSpace(const gfx::PointF& point) override;
gfx::Point DIPsToRoundedBlinkSpace(const gfx::Point& point) override;
float DIPsToBlinkSpace(float scalar) override;
void MouseCaptureLost() override;
bool CanComposeInline() override;
bool ShouldDispatchImeEventsToPlugin() override;
void ImeSetCompositionForPlugin(const String& text,
const Vector<ui::ImeTextSpan>& ime_text_spans,
const gfx::Range& replacement_range,
int selection_start,
int selection_end) override;
void ImeCommitTextForPlugin(const String& text,
const Vector<ui::ImeTextSpan>& ime_text_spans,
const gfx::Range& replacement_range,
int relative_cursor_pos) override;
void ImeFinishComposingTextForPlugin(bool keep_selection) override;
float GetCompositingScaleFactor() override;
const cc::LayerTreeDebugState& GetLayerTreeDebugState() override;
void SetLayerTreeDebugState(const cc::LayerTreeDebugState& state) override;
// WebFrameWidget overrides.
void InitializeNonCompositing(WebNonCompositedWidgetClient* client) override;
WebLocalFrame* LocalRoot() const override;
void UpdateCompositorScrollState(
const cc::CompositorCommitData& commit_data) override;
WebInputMethodController* GetActiveWebInputMethodController() const override;
void DisableDragAndDrop() override;
WebLocalFrameImpl* FocusedWebLocalFrameInWidget() const override;
bool ScrollFocusedEditableElementIntoView() override;
void ApplyViewportChangesForTesting(
const ApplyViewportChangesArgs& args) override;
void ApplyViewportIntersectionForTesting(
mojom::blink::ViewportIntersectionStatePtr intersection_state);
void NotifySwapAndPresentationTime(
WebReportTimeCallback swap_callback,
WebReportTimeCallback presentation_callback) override;
scheduler::WebRenderWidgetSchedulingState* RendererWidgetSchedulingState()
override;
void WaitForDebuggerWhenShown() override;
void SetTextZoomFactor(float text_zoom_factor) override;
float TextZoomFactor() override;
void SetMainFrameOverlayColor(SkColor) override;
void AddEditCommandForNextKeyEvent(const WebString& name,
const WebString& value) override;
void ClearEditCommands() override;
bool IsPasting() override;
bool HandlingSelectRange() override;
void ReleaseMouseLockAndPointerCaptureForTesting() override;
const viz::FrameSinkId& GetFrameSinkId() override;
WebHitTestResult HitTestResultAt(const gfx::PointF&) override;
void SetZoomLevelForTesting(double zoom_level) override;
void ResetZoomLevelForTesting() override;
void SetDeviceScaleFactorForTesting(float factor) override;
FrameWidgetTestHelper* GetFrameWidgetTestHelperForTesting() override;
// Called when a drag-n-drop operation should begin.
virtual void StartDragging(const WebDragData&,
DragOperationsMask,
const SkBitmap& drag_image,
const gfx::Point& drag_image_offset);
bool DoingDragAndDrop() { return doing_drag_and_drop_; }
static void SetIgnoreInputEvents(bool value) { ignore_input_events_ = value; }
static bool IgnoreInputEvents() { return ignore_input_events_; }
// Resets the layout tracking steps for the main frame. When
// `UpdateLifecycle()` is called it generates `WebMeaningfulLayout` events
// only once. This resets the state back to the default so it will fire new
// events.
void ResetMeaningfulLayoutStateForMainFrame();
// WebWidget overrides.
void InitializeCompositing(
scheduler::WebAgentGroupScheduler& agent_group_scheduler,
cc::TaskGraphRunner* task_graph_runner,
const ScreenInfo& screen_info,
std::unique_ptr<cc::UkmRecorderFactory> ukm_recorder_factory,
const cc::LayerTreeSettings* settings) override;
void SetCompositorVisible(bool visible) override;
gfx::Size Size() override;
void Resize(const gfx::Size& size_with_dsf) override;
void SetCursor(const ui::Cursor& cursor) override;
bool HandlingInputEvent() override;
void SetHandlingInputEvent(bool handling) override;
void ProcessInputEventSynchronouslyForTesting(const WebCoalescedInputEvent&,
HandledEventCallback) override;
WebInputEventResult DispatchBufferedTouchEvents() override;
WebInputEventResult HandleInputEvent(const WebCoalescedInputEvent&) override;
void UpdateTextInputState() override;
void UpdateSelectionBounds() override;
void ShowVirtualKeyboard() override;
bool HasFocus() override;
void SetFocus(bool focus) override;
void FlushInputProcessedCallback() override;
void CancelCompositionForPepper() override;
void ApplyVisualProperties(
const VisualProperties& visual_properties) override;
bool PinchGestureActiveInMainFrame() override;
float PageScaleInMainFrame() override;
const ScreenInfo& GetScreenInfo() override;
gfx::Rect WindowRect() override;
gfx::Rect ViewRect() override;
void SetScreenRects(const gfx::Rect& widget_screen_rect,
const gfx::Rect& window_screen_rect) override;
gfx::Size VisibleViewportSizeInDIPs() override;
bool IsHidden() const override;
WebString GetLastToolTipTextForTesting() const override;
float GetEmulatorScale() override;
// WidgetBaseClient overrides:
void BeginMainFrame(base::TimeTicks last_frame_time) override;
void UpdateLifecycle(WebLifecycleUpdate requested_update,
DocumentUpdateReason reason) override;
// mojom::blink::FrameWidget overrides:
void ShowContextMenu(ui::mojom::MenuSourceType source_type,
const gfx::Point& location) override;
void SetViewportIntersection(
mojom::blink::ViewportIntersectionStatePtr intersection_state,
const base::Optional<VisualProperties>& visual_properties) override;
void DragSourceEndedAt(const gfx::PointF& point_in_viewport,
const gfx::PointF& screen_point,
ui::mojom::blink::DragOperation) override;
// Sets the display mode, which comes from the top-level browsing context and
// is applied to all widgets.
void SetDisplayMode(mojom::blink::DisplayMode);
base::Optional<gfx::Point> GetAndResetContextMenuLocation();
void BindWidgetCompositor(
mojo::PendingReceiver<mojom::blink::WidgetCompositor> receiver) override;
void BindInputTargetClient(
mojo::PendingReceiver<viz::mojom::blink::InputTargetClient> receiver)
override;
// viz::mojom::blink::InputTargetClient:
void FrameSinkIdAt(const gfx::PointF& point,
const uint64_t trace_id,
FrameSinkIdAtCallback callback) override;
// Called when the FrameView for this Widget's local root is created.
void DidCreateLocalRootView();
void SetZoomLevel(double zoom_level);
// Called when the View has auto resized.
void DidAutoResize(const gfx::Size& size);
// This method returns the focused frame belonging to this WebWidget, that
// is, a focused frame with the same local root as the one corresponding
// to this widget. It will return nullptr if no frame is focused or, the
// focused frame has a different local root.
LocalFrame* FocusedLocalFrameInWidget() const;
// For when the embedder itself change scales on the page (e.g. devtools)
// and wants all of the content at the new scale to be crisp
void SetNeedsRecalculateRasterScales();
// Sets the background color to be filled in as gutter behind/around the
// painted content. Non-composited WebViews need not implement this, as they
// paint into another widget which has a background color of its own.
void SetBackgroundColor(SkColor color);
// Starts an animation of the page scale to a target scale factor and scroll
// offset.
// If use_anchor is true, destination is a point on the screen that will
// remain fixed for the duration of the animation.
// If use_anchor is false, destination is the final top-left scroll position.
void StartPageScaleAnimation(const gfx::Vector2d& destination,
bool use_anchor,
float new_page_scale,
base::TimeDelta duration);
// Called to update if scroll events should be sent.
void SetHaveScrollEventHandlers(bool);
// Start deferring commits to the compositor, allowing document lifecycle
// updates without committing the layer tree. Commits are deferred
// until at most the given |timeout| has passed. If multiple calls are made
// when deferral is active then the initial timeout applies.
void StartDeferringCommits(base::TimeDelta timeout);
// Immediately stop deferring commits.
void StopDeferringCommits(cc::PaintHoldingCommitTrigger);
// Prevents any updates to the input for the layer tree, and the layer tree
// itself, and the layer tree from becoming visible.
std::unique_ptr<cc::ScopedDeferMainFrameUpdate> DeferMainFrameUpdate();
// Sets the amount that the top and bottom browser controls are showing, from
// 0 (hidden) to 1 (fully shown).
void SetBrowserControlsShownRatio(float top_ratio, float bottom_ratio);
// Set browser controls params. These params consist of top and bottom
// heights, min-heights, browser_controls_shrink_blink_size, and
// animate_browser_controls_height_changes. If
// animate_browser_controls_height_changes is set to true, changes to the
// browser controls height will be animated. If
// browser_controls_shrink_blink_size is set to true, then Blink shrunk the
// viewport clip layers by the top and bottom browser controls height. Top
// controls will translate the web page down and do not immediately scroll
// when hiding. The bottom controls scroll immediately and never translate the
// content (only clip it).
void SetBrowserControlsParams(cc::BrowserControlsParams params);
// This function provides zooming for find in page results when browsing with
// page autosize.
void ZoomToFindInPageRect(const gfx::Rect& rect_in_root_frame);
// Return the compositor LayerTreeHost.
cc::LayerTreeHost* LayerTreeHostForTesting() const;
// Ask compositor to composite a frame for testing. This will generate a
// BeginMainFrame, and update the document lifecycle.
void SynchronouslyCompositeForTesting(base::TimeTicks frame_time);
// Adjust the synchronous resize mode for testing. Normally resizes are
// asynchronous with sending the resize to the browser, however some tests
// still need the resize to happen in a synchronous fashion.
void UseSynchronousResizeModeForTesting(bool enable);
// Sets the device color space for testing.
void SetDeviceColorSpaceForTesting(const gfx::ColorSpace& color_space);
// Converts from DIPs to Blink coordinate space (ie. Viewport/Physical
// pixels).
gfx::Size DIPsToCeiledBlinkSpace(const gfx::Size& size);
void SetWindowRect(const gfx::Rect& window_rect);
void SetWindowRectSynchronouslyForTesting(const gfx::Rect& new_window_rect);
void SetToolTipText(const String& tooltip_text, TextDirection dir);
void ShowVirtualKeyboardOnElementFocus();
void ProcessTouchAction(WebTouchAction touch_action);
// Called to update whether low latency input mode is enabled or not.
void SetNeedsLowLatencyInput(bool);
// Requests unbuffered (ie. low latency) input until a pointerup
// event occurs.
void RequestUnbufferedInputEvents();
// Requests unbuffered (ie. low latency) input due to debugger being
// attached. Debugger needs to paint when stopped in the event handler.
void SetNeedsUnbufferedInputForDebugger(bool);
// Called when the main frame navigates.
void DidNavigate();
// Called when the widget should get targeting input.
void SetMouseCapture(bool capture);
// Sets the current page scale factor and minimum / maximum limits. Both
// limits are initially 1 (no page scale allowed).
void SetPageScaleStateAndLimits(float page_scale_factor,
bool is_pinch_gesture_active,
float minimum,
float maximum);
// The value of the applied battery-savings META element in the document
// changed.
void BatterySavingsChanged(BatterySavingsFlags savings);
const viz::LocalSurfaceId& LocalSurfaceIdFromParent();
ScreenMetricsEmulator* DeviceEmulator();
// Calculates the selection bounds in the root frame. Returns bounds unchanged
// when there is no focused frame or no selection.
void CalculateSelectionBounds(gfx::Rect& anchor_in_root_frame,
gfx::Rect& focus_in_root_frame);
// Returns if auto resize mode is enabled.
bool AutoResizeMode();
void SetScreenMetricsEmulationParameters(
bool enabled,
const blink::DeviceEmulationParams& params);
void SetScreenInfoAndSize(const blink::ScreenInfo& screen_info,
const gfx::Size& widget_size,
const gfx::Size& visible_viewport_size);
// Update the surface allocation information, compositor viewport rect and
// screen info on the widget.
void UpdateSurfaceAndScreenInfo(
const viz::LocalSurfaceId& new_local_surface_id,
const gfx::Rect& compositor_viewport_pixel_rect,
const ScreenInfo& new_screen_info);
// Similar to UpdateSurfaceAndScreenInfo but the surface allocation
// and compositor viewport rect remains the same.
void UpdateScreenInfo(const ScreenInfo& screen_info);
void UpdateSurfaceAndCompositorRect(
const viz::LocalSurfaceId& new_local_surface_id,
const gfx::Rect& compositor_viewport_pixel_rect);
void UpdateCompositorViewportRect(
const gfx::Rect& compositor_viewport_pixel_rect);
void SetWindowSegments(const std::vector<gfx::Rect>& window_segments);
viz::FrameSinkId GetFrameSinkIdAtPoint(const gfx::PointF& point,
gfx::PointF* local_point);
// Set the pending window rect. For every SetPendingWindowRect
// call there must be an AckPendingWindowRect call.
void SetPendingWindowRect(const gfx::Rect& window_screen_rect);
// Clear a previously set pending window rect. For every SetPendingWindowRect
// call there must be an AckPendingWindowRect call.
void AckPendingWindowRect();
// Return the focused WebPlugin if there is one.
WebPlugin* GetFocusedPluginContainer();
// Return if there is a pending scale animation.
bool HasPendingPageScaleAnimation();
// Set the source URL for the compositor.
void SetSourceURLForCompositor(ukm::SourceId source_id, const KURL& url);
// Ask compositor to create the shared memory for smoothness ukm region.
base::ReadOnlySharedMemoryRegion CreateSharedMemoryForSmoothnessUkm();
protected:
// WidgetBaseClient overrides:
void ScheduleAnimation() override;
void DidBeginMainFrame() override;
std::unique_ptr<cc::LayerTreeFrameSink> AllocateNewLayerTreeFrameSink()
override;
const ScreenInfo& GetOriginalScreenInfo() override;
// Whether compositing to LCD text should be auto determined. This can be
// overridden by tests to disable this.
virtual bool ShouldAutoDetermineCompositingToLCDTextSetting();
// WebFrameWidget overrides.
cc::LayerTreeHost* LayerTreeHost() override;
bool doing_drag_and_drop_ = false;
private:
friend class WebViewImpl;
friend class ReportTimeSwapPromise;
// WidgetBaseClient overrides.
void BeginCommitCompositorFrame() override;
void EndCommitCompositorFrame(base::TimeTicks commit_start_time) override;
void ApplyViewportChanges(const cc::ApplyViewportChangesArgs& args) override;
void RecordDispatchRafAlignedInputTime(
base::TimeTicks raf_aligned_input_start_time) override;
void SetSuppressFrameRequestsWorkaroundFor704763Only(bool) override;
void RecordStartOfFrameMetrics() override;
void RecordEndOfFrameMetrics(
base::TimeTicks,
cc::ActiveFrameSequenceTrackers trackers) override;
std::unique_ptr<cc::BeginMainFrameMetrics> GetBeginMainFrameMetrics()
override;
std::unique_ptr<cc::WebVitalMetrics> GetWebVitalMetrics() override;
void BeginUpdateLayers() override;
void EndUpdateLayers() override;
void DidCommitAndDrawCompositorFrame() override;
void DidObserveFirstScrollDelay(
base::TimeDelta first_scroll_delay,
base::TimeTicks first_scroll_timestamp) override;
void DidCompletePageScaleAnimation() override;
void FocusChangeComplete() override;
bool WillHandleGestureEvent(const WebGestureEvent& event) override;
void WillHandleMouseEvent(const WebMouseEvent& event) override;
void ObserveGestureEventAndResult(
const WebGestureEvent& gesture_event,
const gfx::Vector2dF& unused_delta,
const cc::OverscrollBehavior& overscroll_behavior,
bool event_processed) override;
bool SupportsBufferedTouchEvents() override { return true; }
void DidHandleKeyEvent() override;
WebTextInputType GetTextInputType() override;
void SetCursorVisibilityState(bool is_visible) override;
blink::FrameWidget* FrameWidget() override { return this; }
void FocusChanged(bool enable) override;
bool ShouldAckSyntheticInputImmediately() override;
void UpdateVisualProperties(
const VisualProperties& visual_properties) override;
bool UpdateScreenRects(const gfx::Rect& widget_screen_rect,
const gfx::Rect& window_screen_rect) override;
void OrientationChanged() override;
void DidUpdateSurfaceAndScreen(
const ScreenInfo& previous_original_screen_info) override;
gfx::Rect ViewportVisibleRect() override;
base::Optional<blink::mojom::ScreenOrientation> ScreenOrientationOverride()
override;
void WasHidden() override;
void WasShown(bool was_evicted) override;
void RunPaintBenchmark(int repeat_count,
cc::PaintBenchmarkResult& result) override;
KURL GetURLForDebugTrace() override;
float GetTestingDeviceScaleFactorOverride() override;
// mojom::blink::FrameWidget overrides.
void DragTargetDragEnter(const WebDragData&,
const gfx::PointF& point_in_viewport,
const gfx::PointF& screen_point,
DragOperationsMask operations_allowed,
uint32_t key_modifiers,
DragTargetDragEnterCallback callback) override;
void DragTargetDragOver(const gfx::PointF& point_in_viewport,
const gfx::PointF& screen_point,
DragOperationsMask operations_allowed,
uint32_t key_modifiers,
DragTargetDragOverCallback callback) override;
void DragTargetDragLeave(const gfx::PointF& point_in_viewport,
const gfx::PointF& screen_point) override;
void DragTargetDrop(const WebDragData&,
const gfx::PointF& point_in_viewport,
const gfx::PointF& screen_point,
uint32_t key_modifiers) override;
void DragSourceSystemDragEnded() override;
void SetBackgroundOpaque(bool opaque) override;
void SetActive(bool active) override;
// For both mainframe and childframe change the text direction of the
// currently selected input field (if any).
void SetTextDirection(base::i18n::TextDirection direction) override;
// Sets the inherited effective touch action on an out-of-process iframe.
void SetInheritedEffectiveTouchActionForSubFrame(
WebTouchAction touch_action) override;
// Toggles render throttling for an out-of-process iframe. Local frames are
// throttled based on their visibility in the viewport, but remote frames
// have to have throttling information propagated from parent to child
// across processes.
void UpdateRenderThrottlingStatusForSubFrame(bool is_throttled,
bool subtree_throttled,
bool display_locked) override;
void EnableDeviceEmulation(const DeviceEmulationParams& parameters) override;
void DisableDeviceEmulation() override;
// Sets the inert bit on an out-of-process iframe, causing it to ignore
// input.
void SetIsInertForSubFrame(bool inert) override;
#if defined(OS_MAC)
void GetStringAtPoint(const gfx::Point& point_in_local_root,
GetStringAtPointCallback callback) override;
#endif
// mojom::blink::FrameWidgetInputHandler overrides.
void AddImeTextSpansToExistingText(
uint32_t start,
uint32_t end,
const Vector<ui::ImeTextSpan>& ime_text_spans) override;
void ClearImeTextSpansByType(uint32_t start,
uint32_t end,
ui::ImeTextSpan::Type type) override;
void SetCompositionFromExistingText(
int32_t start,
int32_t end,
const Vector<ui::ImeTextSpan>& ime_text_spans) override;
void ExtendSelectionAndDelete(int32_t before, int32_t after) override;
void DeleteSurroundingText(int32_t before, int32_t after) override;
void DeleteSurroundingTextInCodePoints(int32_t before,
int32_t after) override;
void SetEditableSelectionOffsets(int32_t start, int32_t end) override;
void ExecuteEditCommand(const String& command, const String& value) override;
void Undo() override;
void Redo() override;
void Cut() override;
void Copy() override;
void CopyToFindPboard() override;
void Paste() override;
void PasteAndMatchStyle() override;
void Delete() override;
void SelectAll() override;
void CollapseSelection() override;
void Replace(const String& word) override;
void ReplaceMisspelling(const String& word) override;
void SelectRange(const gfx::Point& base_in_dips,
const gfx::Point& extent_in_dips) override;
void AdjustSelectionByCharacterOffset(
int32_t start,
int32_t end,
mojom::blink::SelectionMenuBehavior behavior) override;
void MoveRangeSelectionExtent(const gfx::Point& extent_in_dips) override;
void ScrollFocusedEditableNodeIntoRect(
const gfx::Rect& rect_in_dips) override;
void MoveCaret(const gfx::Point& point_in_dips) override;
#if defined(OS_ANDROID)
void SelectWordAroundCaret(SelectWordAroundCaretCallback callback) override;
#endif
// PageWidgetEventHandler overrides:
WebInputEventResult HandleKeyEvent(const WebKeyboardEvent&) override;
void HandleMouseDown(LocalFrame&, const WebMouseEvent&) override;
void HandleMouseLeave(LocalFrame&, const WebMouseEvent&) override;
WebInputEventResult HandleMouseUp(LocalFrame&, const WebMouseEvent&) override;
WebInputEventResult HandleGestureEvent(const WebGestureEvent&) override;
WebInputEventResult HandleMouseWheel(LocalFrame&,
const WebMouseWheelEvent&) override;
WebInputEventResult HandleCharEvent(const WebKeyboardEvent&) override;
WebInputEventResult HandleCapturedMouseEvent(const WebCoalescedInputEvent&);
void MouseContextMenu(const WebMouseEvent&);
void CancelDrag();
void PresentationCallbackForMeaningfulLayout(blink::WebSwapResult,
base::TimeTicks);
void ForEachRemoteFrameControlledByWidget(
const base::RepeatingCallback<void(RemoteFrame*)>& callback);
void SetWindowRectSynchronously(const gfx::Rect& new_window_rect);
void SendOverscrollEventFromImplSide(const gfx::Vector2dF& overscroll_delta,
cc::ElementId scroll_latched_element_id);
void SendScrollEndEventFromImplSide(cc::ElementId scroll_latched_element_id);
void RecordManipulationTypeCounts(cc::ManipulationInfo info);
// Finds the parameters required for scrolling the focused editable |element|
// into view. |out_rect_to_scroll| is used for recursive scrolling of the
// element into view and contains all or part of element's bounding box and
// always includes the caret and is with respect to absolute coordinates.
mojom::blink::ScrollIntoViewParamsPtr
GetScrollParamsForFocusedEditableElement(const Element& element,
PhysicalRect& out_rect_to_scroll);
enum DragAction { kDragEnter, kDragOver };
// Consolidate some common code between starting a drag over a target and
// updating a drag over a target. If we're starting a drag, |isEntering|
// should be true.
ui::mojom::blink::DragOperation DragTargetDragEnterOrOver(
const gfx::PointF& point_in_viewport,
const gfx::PointF& screen_point,
DragAction,
uint32_t key_modifiers);
// Helper function to call VisualViewport::viewportToRootFrame().
gfx::PointF ViewportToRootFrame(const gfx::PointF& point_in_viewport) const;
WebViewImpl* View() const;
// Returns the page object associated with this widget. This may be null when
// the page is shutting down, but will be valid at all other times.
Page* GetPage() const;
mojom::blink::FrameWidgetHost* GetAssociatedFrameWidgetHost() const;
// Notifies RenderWidgetHostImpl that the frame widget has painted something.
void DidMeaningfulLayout(WebMeaningfulLayout layout_type);
// Enable or disable auto-resize. This is part of
// UpdateVisualProperties though tests may call to it more directly.
void SetAutoResizeMode(bool auto_resize,
const gfx::Size& min_size_before_dsf,
const gfx::Size& max_size_before_dsf,
float device_scale_factor);
void ApplyViewportIntersection(
mojom::blink::ViewportIntersectionStatePtr intersection_state);
// Called when a gesture event has been processed.
void DidHandleGestureEvent(const WebGestureEvent& event);
// Called to update if pointerrawupdate events should be sent.
void SetHasPointerRawUpdateEventHandlers(bool);
// Helper function to process events while pointer locked.
void PointerLockMouseEvent(const WebCoalescedInputEvent&);
bool IsPointerLocked();
// The fullscreen granted status from the most recent VisualProperties update.
bool IsFullscreenGranted();
// Set the compositing scale factor for this widget and notify remote frames
// to update their compositing scale factor.
void NotifyCompositingScaleFactorChanged(float compositing_scale_factor);
void NotifyPageScaleFactorChanged(float page_scale_factor,
bool is_pinch_gesture_active);
// Helper for notifying frame-level objects that care about input events.
// TODO: With some effort, this could be folded into a common implementation
// of WebViewImpl::HandleInputEvent and WebFrameWidgetImpl::HandleInputEvent.
void NotifyInputObservers(const WebCoalescedInputEvent& coalesced_event);
Frame* FocusedCoreFrame() const;
// Returns the currently focused `Element` in any `LocalFrame` owned by the
// associated `WebView`.
Element* FocusedElement() const;
// Perform a hit test for a point relative to the root frame of the page.
HitTestResult HitTestResultForRootFramePos(
const FloatPoint& pos_in_root_frame);
// Called during |UpdateVisualProperties| to apply the new size to the widget.
void ApplyVisualPropertiesSizing(const VisualProperties& visual_properties);
// Returns the current state of synchronous resize mode for testing.
bool SynchronousResizeModeForTestingEnabled();
// A copy of the web drop data object we received from the browser.
Member<DataObject> current_drag_data_;
// The available drag operations (copy, move link...) allowed by the source.
DragOperationsMask operations_allowed_ = kDragOperationNone;
// The current drag operation as negotiated by the source and destination.
// When not equal to DragOperationNone, the drag data can be dropped onto the
// current drop target in this WebView (the drop target can accept the drop).
ui::mojom::blink::DragOperation drag_operation_ =
ui::mojom::blink::DragOperation::kNone;
// This field stores drag/drop related info for the event that is currently
// being handled. If the current event results in starting a drag/drop
// session, this info is sent to the browser along with other drag/drop info.
mojom::blink::DragEventSourceInfo possible_drag_event_info_;
// Base functionality all widgets have. This is a member as to avoid
// complicated inheritance structures.
std::unique_ptr<WidgetBase> widget_base_;
// Compositing scale factor for all frames attached to this widget sent from
// the remote parent frame.
float compositing_scale_factor_ = 1.f;
// The last seen page scale state, which comes from the main frame if we're
// in a child frame. This state is propagated through the RenderWidget tree
// passed to any new child RenderWidget.
float page_scale_factor_in_mainframe_ = 1.f;
bool is_pinch_gesture_active_in_mainframe_ = false;
// If set, the (plugin) element which has mouse capture.
Member<HTMLPlugInElement> mouse_capture_element_;
// The size of the widget in viewport coordinates. This is slightly different
// than the WebViewImpl::size_ since isn't set in auto resize mode.
base::Optional<gfx::Size> size_;
static bool ignore_input_events_;
const viz::FrameSinkId frame_sink_id_;
// WebFrameWidget is associated with a subtree of the frame tree,
// corresponding to a maximal connected tree of LocalFrames. This member
// points to the root of that subtree.
Member<WebLocalFrameImpl> local_root_;
mojom::blink::DisplayMode display_mode_;
WebVector<gfx::Rect> window_segments_;
// This is owned by the LayerTreeHostImpl, and should only be used on the
// compositor thread, so we keep the TaskRunner where you post tasks to
// make that happen.
base::WeakPtr<AnimationWorkletMutatorDispatcherImpl> mutator_dispatcher_;
scoped_refptr<base::SingleThreadTaskRunner> mutator_task_runner_;
// The |paint_dispatcher_| should only be dereferenced on the
// |paint_task_runner_| (in practice this is the compositor thread). We keep a
// copy of it here to provide to new PaintWorkletProxyClient objects (which
// run on the worklet thread) so that they can talk to the
// PaintWorkletPaintDispatcher on the compositor thread.
base::WeakPtr<PaintWorkletPaintDispatcher> paint_dispatcher_;
scoped_refptr<base::SingleThreadTaskRunner> paint_task_runner_;
// WebFrameWidgetImpl is not tied to ExecutionContext
HeapMojoAssociatedRemote<mojom::blink::FrameWidgetHost,
HeapMojoWrapperMode::kWithoutContextObserver>
frame_widget_host_{nullptr};
// WebFrameWidgetImpl is not tied to ExecutionContext
HeapMojoAssociatedReceiver<mojom::blink::FrameWidget,
WebFrameWidgetImpl,
HeapMojoWrapperMode::kWithoutContextObserver>
receiver_{this, nullptr};
HeapMojoReceiver<viz::mojom::blink::InputTargetClient,
WebFrameWidgetImpl,
HeapMojoWrapperMode::kWithoutContextObserver>
input_target_receiver_{this, nullptr};
// Different consumers in the browser process makes different assumptions, so
// must always send the first IPC regardless of value.
base::Optional<bool> has_touch_handlers_;
Vector<mojom::blink::EditCommandPtr> edit_commands_;
base::Optional<gfx::Point> host_context_menu_location_;
uint32_t last_capture_sequence_number_ = 0u;
// Indicates whether tab-initiated fullscreen was granted.
bool is_fullscreen_granted_ = false;
// Indicates whether we need to consume scroll gestures to move cursor.
bool swipe_to_move_cursor_activated_ = false;
// Set when a measurement begins, reset when the measurement is taken.
base::Optional<base::TimeTicks> update_layers_start_time_;
// Metrics for gathering time for commit of compositor frame.
base::Optional<base::TimeTicks> commit_compositor_frame_start_time_;
// Present when emulation is enabled, only on a main frame's WebFrameWidget.
// Used to override values given from the browser such as ScreenInfo,
// WidgetScreenRect, WindowScreenRect, and the widget's size.
Member<ScreenMetricsEmulator> device_emulator_;
// keyPress events to be suppressed if the associated keyDown event was
// handled.
bool suppress_next_keypress_event_ = false;
// Whether drag and drop is supported by this widget. When disabled
// any drag operation that is started will be canceled immediately.
bool drag_and_drop_disabled_ = false;
// A callback client for non-composited frame widgets.
WebNonCompositedWidgetClient* non_composited_client_ = nullptr;
// This struct contains data that is only valid for child local root widgets.
// You should use `child_data()` to access it.
struct ChildLocalRootData {
gfx::Rect compositor_visible_rect;
bool did_suspend_parsing = false;
} child_local_root_data_;
ChildLocalRootData& child_data() {
DCHECK(ForSubframe());
return child_local_root_data_;
}
// Web tests override the zoom factor in the renderer with this. We store it
// to keep the override if the browser passes along VisualProperties with the
// real device scale factor. A value of -INFINITY means this is ignored.
// It is always valid to read this variable but it can only be set for main
// frame widgets.
double zoom_level_for_testing_ = -INFINITY;
// Web tests override the device scale factor in the renderer with this. We
// store it to keep the override if the browser passes along VisualProperties
// with the real device scale factor. A value of 0.f means this is ignored.
// It is always valid to read this variable but it can only be set for main
// frame widgets.
float device_scale_factor_for_testing_ = 0;
// This struct contains data that is only valid for main frame widgets.
// You should use `main_data()` to access it.
struct MainFrameData {
// `UpdateLifecycle()` generates `WebMeaningfulLayout` events these
// variables track what events should be generated. They are only applicable
// for main frame widgets.
bool should_dispatch_first_visually_non_empty_layout = false;
bool should_dispatch_first_layout_after_finished_parsing = false;
bool should_dispatch_first_layout_after_finished_loading = false;
// Last background color sent to the browser. Only set for main frames.
base::Optional<SkColor> last_background_color;
// This bit is used to tell if this is a nested widget (an "inner web
// contents") like a <webview> or <portal> widget. If false, the widget is
// the top level widget.
bool is_for_nested_main_frame = false;
// In web tests, synchronous resizing mode may be used. Normally each
// widget's size is controlled by IPC from the browser. In synchronous
// resize mode the renderer controls the size directly, and IPCs from the
// browser must be ignored. This was deprecated but then later undeprecated,
// so it is now called unfortunate instead. See https://crbug.com/309760.
// When this is enabled the various size properties will be controlled
// directly when SetWindowRect() is called instead of needing a round trip
// through the browser. Note that SetWindowRectSynchronouslyForTesting()
// provides a secondary way to control the size of the FrameWidget
// independently from the renderer process, without the use of this mode,
// however it would be overridden by the browser if they disagree.
bool synchronous_resize_mode_for_testing = false;
} main_frame_data_;
MainFrameData& main_data() {
DCHECK(ForMainFrame());
return main_frame_data_;
}
const MainFrameData& main_data() const {
DCHECK(ForMainFrame());
return main_frame_data_;
}
// Whether this widget is for a child local root, or otherwise a main frame.
const bool is_for_child_local_root_;
// This stores the last hidden page popup. If a GestureTap attempts to open
// the popup that is closed by its previous GestureTapDown, the popup remains
// closed.
scoped_refptr<WebPagePopupImpl> last_hidden_page_popup_;
base::WeakPtrFactory<mojom::blink::FrameWidgetInputHandler>
input_handler_weak_ptr_factory_{this};
};
} // namespace blink
#endif