diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-10-12 14:27:29 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-10-13 09:35:20 +0000 |
commit | c30a6232df03e1efbd9f3b226777b07e087a1122 (patch) | |
tree | e992f45784689f373bcc38d1b79a239ebe17ee23 /chromium/content/browser/renderer_host | |
parent | 7b5b123ac58f58ffde0f4f6e488bcd09aa4decd3 (diff) | |
download | qtwebengine-chromium-85-based.tar.gz |
BASELINE: Update Chromium to 85.0.4183.14085-based
Change-Id: Iaa42f4680837c57725b1344f108c0196741f6057
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/content/browser/renderer_host')
171 files changed, 3679 insertions, 2508 deletions
diff --git a/chromium/content/browser/renderer_host/DEPS b/chromium/content/browser/renderer_host/DEPS index 94dca6230e4..ad7f91b632b 100644 --- a/chromium/content/browser/renderer_host/DEPS +++ b/chromium/content/browser/renderer_host/DEPS @@ -11,7 +11,6 @@ include_rules = [ # The renderer_host files should only call upwards in the layering via the # delegate interfaces. - "-content/browser/frame_host", "-content/browser/web_contents", "-content/public/browser/web_contents.h", "-content/public/browser/web_contents_delegate.h", @@ -21,7 +20,6 @@ include_rules = [ specific_include_rules = { ".*_(unit|browser)test\.(cc|mm)": [ "+components/rappor/test_rappor_service.h", - "+content/browser/frame_host", "+content/browser/web_contents", "+content/public/browser/web_contents.h", "+content/public/browser/web_contents_delegate.h", @@ -35,28 +33,12 @@ specific_include_rules = { "+components/viz/service", ], "render_process_host_impl\.cc": [ - "+content/browser/frame_host/render_frame_message_filter.h", "+google_apis/gaia/gaia_switches.h", # TODO(crbug.com/734668): Dependencies on ozone should be removed, as content # embedded in mus won't be able to talk to the native ozone. "+ui/ozone/public/ozone_switches.h", ], "render_widget_host_view_mac\.mm": [ - "+content/browser/frame_host", "+content/public/browser/web_contents.h", ], - "text_input_client_mac\.mm": [ - "+content/browser/frame_host" - ], - # TODO(nasko): Remove these exceptions once we've untangled the dependency - # of RenderViewHost on the FrameTree. - "render_view_host_impl\.(cc|h)": [ - "+content/browser/frame_host/frame_tree.h", - ], - "render_widget_host_view_aura\.cc": [ - "+content/browser/frame_host", - ], - "render_widget_host_view_event_handler\.cc": [ - "+content/browser/frame_host", - ], } diff --git a/chromium/content/browser/renderer_host/accessibility_object_lifetime_win_browsertest.cc b/chromium/content/browser/renderer_host/accessibility_object_lifetime_win_browsertest.cc index ba7236c5ced..0076517d22b 100644 --- a/chromium/content/browser/renderer_host/accessibility_object_lifetime_win_browsertest.cc +++ b/chromium/content/browser/renderer_host/accessibility_object_lifetime_win_browsertest.cc @@ -27,16 +27,19 @@ class AccessibilityObjectLifetimeWinBrowserTest shell()->web_contents()->GetRenderWidgetHostView()); } + LegacyRenderWidgetHostHWND* GetLegacyRenderWidgetHostHWND() { + return GetView()->legacy_render_widget_host_HWND_; + } + void CacheRootNode(bool is_uia_request) { - GetView() - ->legacy_render_widget_host_HWND_ + GetLegacyRenderWidgetHostHWND() ->GetOrCreateWindowRootAccessible(is_uia_request) ->QueryInterface(IID_PPV_ARGS(&test_node_)); } void CacheCaretNode() { - GetView() - ->legacy_render_widget_host_HWND_->ax_system_caret_->GetCaret() + GetLegacyRenderWidgetHostHWND() + ->ax_system_caret_->GetCaret() ->QueryInterface(IID_PPV_ARGS(&test_node_)); } @@ -100,9 +103,10 @@ IN_PROC_BROWSER_TEST_F(AccessibilityObjectLifetimeWinBrowserTest, // this narrow window; see crbug.com/945584 for one example. class AccessibilityTeardownTestMessageFilter : public ui::HWNDMessageFilter { public: - AccessibilityTeardownTestMessageFilter(RenderWidgetHostViewAura* view) - : view_(view) { - HWND hwnd = view->AccessibilityGetAcceleratedWidget(); + AccessibilityTeardownTestMessageFilter( + LegacyRenderWidgetHostHWND* legacy_render_widget_host_HWND) + : legacy_render_widget_host_HWND_(legacy_render_widget_host_HWND) { + HWND hwnd = legacy_render_widget_host_HWND->hwnd(); CHECK(hwnd); ui::HWNDSubclass::AddFilterToTarget(hwnd, this); } @@ -115,8 +119,9 @@ class AccessibilityTeardownTestMessageFilter : public ui::HWNDMessageFilter { LPARAM l_param, LRESULT* l_result) override { if (message == WM_DESTROY) { - // Verify that the view no longer exposes a NativeViewAccessible. - EXPECT_EQ(view_->GetNativeViewAccessible(), nullptr); + // Verify that the legacy window does not crash when asked for an + // accessibility object. + legacy_render_widget_host_HWND_->GetOrCreateWindowRootAccessible(false); // Remove ourselves as a subclass. ui::HWNDSubclass::RemoveFilterFromAllTargets(this); @@ -126,16 +131,17 @@ class AccessibilityTeardownTestMessageFilter : public ui::HWNDMessageFilter { } private: - RenderWidgetHostViewAura* view_; + LegacyRenderWidgetHostHWND* legacy_render_widget_host_HWND_; }; IN_PROC_BROWSER_TEST_F(AccessibilityObjectLifetimeWinBrowserTest, - DoNotReturnObjectDuringTeardown) { + DoNotCrashDuringLegacyWindowDestroy) { EXPECT_TRUE(NavigateToURL(shell(), GURL(url::kAboutBlankURL))); - AccessibilityTeardownTestMessageFilter test_message_filter(GetView()); + AccessibilityTeardownTestMessageFilter test_message_filter( + GetLegacyRenderWidgetHostHWND()); - shell()->Close(); + GetView()->Destroy(); } class AccessibilityObjectLifetimeUiaWinBrowserTest diff --git a/chromium/content/browser/renderer_host/compositor_dependencies_android.cc b/chromium/content/browser/renderer_host/compositor_dependencies_android.cc index da271b9e65a..d5f5e081f93 100644 --- a/chromium/content/browser/renderer_host/compositor_dependencies_android.cc +++ b/chromium/content/browser/renderer_host/compositor_dependencies_android.cc @@ -8,7 +8,6 @@ #include "base/bind.h" #include "base/system/sys_info.h" -#include "base/task/post_task.h" #include "base/threading/thread_task_runner_handle.h" #include "base/time/time.h" #include "cc/raster/single_thread_task_graph_runner.h" @@ -127,8 +126,8 @@ viz::FrameSinkId CompositorDependenciesAndroid::AllocateFrameSinkId() { void CompositorDependenciesAndroid::TryEstablishVizConnectionIfNeeded() { if (!pending_connect_viz_on_io_thread_) return; - base::PostTask(FROM_HERE, {BrowserThread::IO}, - std::move(pending_connect_viz_on_io_thread_)); + GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, std::move(pending_connect_viz_on_io_thread_)); } // Called on IO thread, after a GPU connection has already been established. diff --git a/chromium/content/browser/renderer_host/compositor_impl_android.cc b/chromium/content/browser/renderer_host/compositor_impl_android.cc index e094050c27a..eda28b5dada 100644 --- a/chromium/content/browser/renderer_host/compositor_impl_android.cc +++ b/chromium/content/browser/renderer_host/compositor_impl_android.cc @@ -519,6 +519,10 @@ void CompositorImpl::SetWindowBounds(const gfx::Size& size) { root_window_->GetLayer()->SetBounds(size); } +const gfx::Size& CompositorImpl::GetWindowBounds() { + return size_; +} + void CompositorImpl::SetRequiresAlphaChannel(bool flag) { requires_alpha_channel_ = flag; } diff --git a/chromium/content/browser/renderer_host/compositor_impl_android.h b/chromium/content/browser/renderer_host/compositor_impl_android.h index ed52cd263a6..dc76a7cd125 100644 --- a/chromium/content/browser/renderer_host/compositor_impl_android.h +++ b/chromium/content/browser/renderer_host/compositor_impl_android.h @@ -98,6 +98,7 @@ class CONTENT_EXPORT CompositorImpl bool can_be_used_with_surface_control) override; void SetBackgroundColor(int color) override; void SetWindowBounds(const gfx::Size& size) override; + const gfx::Size& GetWindowBounds() override; void SetRequiresAlphaChannel(bool flag) override; void SetNeedsComposite() override; void SetNeedsRedraw() override; @@ -146,6 +147,13 @@ class CONTENT_EXPORT CompositorImpl override; void NotifyThroughputTrackerResults( cc::CustomTrackerResults results) override {} + void SubmitThroughputData(ukm::SourceId source_id, + int aggregated_percent, + int impl_percent, + base::Optional<int> main_percent) override {} + void DidObserveFirstScrollDelay( + base::TimeDelta first_scroll_delay, + base::TimeTicks first_scroll_timestamp) override {} // LayerTreeHostSingleThreadClient implementation. void DidSubmitCompositorFrame() override; diff --git a/chromium/content/browser/renderer_host/direct_manipulation_event_handler_win.cc b/chromium/content/browser/renderer_host/direct_manipulation_event_handler_win.cc index 5e5d832d521..3a1f9432721 100644 --- a/chromium/content/browser/renderer_host/direct_manipulation_event_handler_win.cc +++ b/chromium/content/browser/renderer_host/direct_manipulation_event_handler_win.cc @@ -5,6 +5,7 @@ #include "content/browser/renderer_host/direct_manipulation_event_handler_win.h" #include "base/logging.h" +#include "base/notreached.h" #include "base/strings/string_number_conversions.h" #include "content/browser/renderer_host/direct_manipulation_helper_win.h" #include "ui/base/ui_base_features.h" diff --git a/chromium/content/browser/renderer_host/direct_manipulation_test_helper_win.h b/chromium/content/browser/renderer_host/direct_manipulation_test_helper_win.h index 156d6a1014e..73b622be982 100644 --- a/chromium/content/browser/renderer_host/direct_manipulation_test_helper_win.h +++ b/chromium/content/browser/renderer_host/direct_manipulation_test_helper_win.h @@ -10,7 +10,6 @@ #include <wrl.h> #include <array> -#include "base/logging.h" #include "base/macros.h" namespace content { diff --git a/chromium/content/browser/renderer_host/display_feature.cc b/chromium/content/browser/renderer_host/display_feature.cc new file mode 100644 index 00000000000..3f3ca652f5e --- /dev/null +++ b/chromium/content/browser/renderer_host/display_feature.cc @@ -0,0 +1,18 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/renderer_host/display_feature.h" + +namespace content { + +bool DisplayFeature::operator==(const DisplayFeature& other) const { + return orientation == other.orientation && offset == other.offset && + mask_length == other.mask_length; +} + +bool DisplayFeature::operator!=(const DisplayFeature& other) const { + return !(*this == other); +} + +} // namespace content diff --git a/chromium/content/browser/renderer_host/display_feature.h b/chromium/content/browser/renderer_host/display_feature.h new file mode 100644 index 00000000000..f8d110274dd --- /dev/null +++ b/chromium/content/browser/renderer_host/display_feature.h @@ -0,0 +1,55 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_BROWSER_RENDERER_HOST_DISPLAY_FEATURE_H_ +#define CONTENT_BROWSER_RENDERER_HOST_DISPLAY_FEATURE_H_ + +#include "build/build_config.h" +#include "content/common/content_export.h" + +namespace content { + +// Information about a physical attribute of the screen which that creates a +// Logical separator or divider (e.g. a fold or mask). +// This is a visual example of a vertically oriented display feature that masks +// content underneath +// +// Orientation: vertical +// +// offset +// | +// +---------|===|---------+ +// | | | | +// | | | | +// | | | | +// | | | | +// | | | | +// +---------|===|---------+ +// \ +// mask_length +// +// Note that the implicit height of the display feature is the entire height of +// the screen on which it exists. +struct CONTENT_EXPORT DisplayFeature { + enum class Orientation { kVertical, kHorizontal, kMaxValue = kHorizontal }; + + // The orientation of the display feature in relation to the screen. + Orientation orientation = Orientation::kVertical; + + // The offset from the screen origin in either the x (for vertical + // orientation) or y (for horizontal orientation) direction. + int offset = 0; + + // A display feature may mask content such that it is not physically + // displayed - this length along with the offset describes this area. + // A display feature that only splits content will have a 0 |mask_length|. + int mask_length = 0; + + bool operator==(const DisplayFeature& other) const; + bool operator!=(const DisplayFeature& other) const; +}; + +} // namespace content + +#endif // CONTENT_BROWSER_RENDERER_HOST_DISPLAY_FEATURE_H_ diff --git a/chromium/content/browser/renderer_host/display_util.cc b/chromium/content/browser/renderer_host/display_util.cc index 9ee2ff10ffe..b8b0c236cbb 100644 --- a/chromium/content/browser/renderer_host/display_util.cc +++ b/chromium/content/browser/renderer_host/display_util.cc @@ -53,21 +53,7 @@ void DisplayUtil::DisplayToScreenInfo(ScreenInfo* screen_info, // static void DisplayUtil::GetDefaultScreenInfo(ScreenInfo* screen_info) { - // Some tests are run with no Screen initialized. - display::Screen* screen = display::Screen::GetScreen(); - if (!screen) { - *screen_info = ScreenInfo(); - return; - } -#if defined(USE_AURA) - // This behavior difference between Aura and other platforms may or may not - // be intentional, and may or may not have any effect. - gfx::NativeView null_native_view = nullptr; - display::Display display = screen->GetDisplayNearestView(null_native_view); -#else - display::Display display = screen->GetPrimaryDisplay(); -#endif - DisplayToScreenInfo(screen_info, display); + return GetNativeViewScreenInfo(screen_info, nullptr); } // static diff --git a/chromium/content/browser/renderer_host/frame_connector_delegate.cc b/chromium/content/browser/renderer_host/frame_connector_delegate.cc index ab73d3d5824..1df2484fe77 100644 --- a/chromium/content/browser/renderer_host/frame_connector_delegate.cc +++ b/chromium/content/browser/renderer_host/frame_connector_delegate.cc @@ -50,7 +50,8 @@ void FrameConnectorDelegate::SynchronizeVisualProperties( visual_properties.page_scale_factor, visual_properties.is_pinch_gesture_active, visual_properties.visible_viewport_size, - visual_properties.compositor_viewport); + visual_properties.compositor_viewport, + visual_properties.root_widget_window_segments); render_widget_host->SynchronizeVisualProperties(); } diff --git a/chromium/content/browser/renderer_host/frame_connector_delegate.h b/chromium/content/browser/renderer_host/frame_connector_delegate.h index 4dacdbbc736..2c8a21c2f97 100644 --- a/chromium/content/browser/renderer_host/frame_connector_delegate.h +++ b/chromium/content/browser/renderer_host/frame_connector_delegate.h @@ -12,10 +12,10 @@ #include "components/viz/host/hit_test/hit_test_query.h" #include "content/browser/renderer_host/event_with_latency_info.h" #include "content/common/content_export.h" -#include "content/common/input/input_handler.mojom.h" #include "content/public/common/screen_info.h" #include "third_party/blink/public/mojom/frame/intrinsic_sizing_info.mojom-forward.h" #include "third_party/blink/public/mojom/input/input_event_result.mojom-shared.h" +#include "third_party/blink/public/mojom/input/pointer_lock_result.mojom-shared.h" #include "third_party/blink/public/platform/viewport_intersection_state.h" #include "ui/gfx/geometry/rect.h" diff --git a/chromium/content/browser/renderer_host/frame_token_message_queue.cc b/chromium/content/browser/renderer_host/frame_token_message_queue.cc index a48ea522703..08cadbc57bf 100644 --- a/chromium/content/browser/renderer_host/frame_token_message_queue.cc +++ b/chromium/content/browser/renderer_host/frame_token_message_queue.cc @@ -35,6 +35,14 @@ void FrameTokenMessageQueue::DidProcessFrame(uint32_t frame_token) { base::NumberToString(frame_token)); base::debug::DumpWithoutCrashing(); + // TODO(jonross): Remove this once root cause of flaking tests is found. + // (crbug.com/1087744) + DCHECK(false) << "FrameTokenMessageQueue invalid order of acknowledged " + "token. Current: " + << frame_token + << " Last Received: " << last_received_frame_token_ + << " Last Before Reset: " << last_received_frame_token_reset_ + << " queue size " << callback_map_.size(); client_->OnInvalidFrameToken(frame_token); return; } @@ -59,6 +67,11 @@ void FrameTokenMessageQueue::EnqueueOrRunFrameTokenCallback( base::OnceClosure callback) { // Zero token is invalid. if (!frame_token) { + // TODO(jonross): Remove this once root cause of flaking tests is found. + // (crbug.com/1087744) + DCHECK(false) << "FrameTokenMessageQueue invalid enqueued frame token. " + "Last Received: " + << last_received_frame_token_; client_->OnInvalidFrameToken(frame_token); return; } @@ -84,6 +97,7 @@ void FrameTokenMessageQueue::OnFrameSwapMessagesReceived( } void FrameTokenMessageQueue::Reset() { + last_received_frame_token_reset_ = last_received_frame_token_; last_received_frame_token_ = 0; callback_map_.clear(); } diff --git a/chromium/content/browser/renderer_host/frame_token_message_queue.h b/chromium/content/browser/renderer_host/frame_token_message_queue.h index 8e5c4805a79..1745bc12786 100644 --- a/chromium/content/browser/renderer_host/frame_token_message_queue.h +++ b/chromium/content/browser/renderer_host/frame_token_message_queue.h @@ -93,6 +93,12 @@ class CONTENT_EXPORT FrameTokenMessageQueue { // Sorted by frame token. std::multimap<uint32_t, base::OnceClosure> callback_map_; + // TODO(jonross): Remove this once root cause of flaking tests is found. + // (crbug.com/1087744) + // The frame token last seen when Reset() is called. To determine if we are + // getting delayed frame acknowledgements after a reset. + uint32_t last_received_frame_token_reset_ = 0u; + DISALLOW_COPY_AND_ASSIGN(FrameTokenMessageQueue); }; diff --git a/chromium/content/browser/renderer_host/frame_token_message_queue_unittest.cc b/chromium/content/browser/renderer_host/frame_token_message_queue_unittest.cc index 6a3cd5e8301..815ce5ad0c6 100644 --- a/chromium/content/browser/renderer_host/frame_token_message_queue_unittest.cc +++ b/chromium/content/browser/renderer_host/frame_token_message_queue_unittest.cc @@ -476,9 +476,11 @@ TEST_F(FrameTokenMessageQueueTest, DifferentFrameTokensEnqueuedNonIPC) { EXPECT_TRUE(second_enqueuer.frame_token_callback_called()); } +// TODO(jonross): Re-enable this once the DCHECKs have been removed. +// (crbug.com/1087744) // An empty frame token is considered invalid, so this tests that attempting to // enqueue for that is rejected. -TEST_F(FrameTokenMessageQueueTest, EmptyTokenForIPCMessageIsRejected) { +TEST_F(FrameTokenMessageQueueTest, DISABLED_EmptyTokenForIPCMessageIsRejected) { FrameTokenMessageQueue* queue = frame_token_message_queue(); TestFrameTokenMessageQueueClient* client = test_client(); ASSERT_EQ(0u, queue->size()); @@ -526,9 +528,12 @@ TEST_F(FrameTokenMessageQueueTest, EarlierTokenForIPCMessageIsNotRejected) { EXPECT_EQ(0, client->on_process_swap_message_count()); } +// TODO(jonross): Re-enable this once the DCHECKs have been removed. +// (crbug.com/1087744) // Tests that if DidProcessFrame is called with an invalid token, that it is // rejected, and that no callbacks are processed. -TEST_F(FrameTokenMessageQueueTest, InvalidDidProcessFrameTokenNotProcessed) { +TEST_F(FrameTokenMessageQueueTest, + DISABLED_InvalidDidProcessFrameTokenNotProcessed) { FrameTokenMessageQueue* queue = frame_token_message_queue(); TestFrameTokenMessageQueueClient* client = test_client(); TestNonIPCMessageEnqueuer* enqueuer = test_non_ipc_enqueuer(); @@ -561,9 +566,12 @@ TEST_F(FrameTokenMessageQueueTest, InvalidDidProcessFrameTokenNotProcessed) { EXPECT_FALSE(enqueuer->frame_token_callback_called()); } +// TODO(jonross): Re-enable this once the DCHECKs have been removed. +// (crbug.com/1087744) // Test that if DidProcessFrame is called with an earlier frame token, that it // is rejected, and that no callbacks are processed. -TEST_F(FrameTokenMessageQueueTest, EarlierTokenForDidProcessFrameRejected) { +TEST_F(FrameTokenMessageQueueTest, + DISABLED_EarlierTokenForDidProcessFrameRejected) { FrameTokenMessageQueue* queue = frame_token_message_queue(); TestFrameTokenMessageQueueClient* client = test_client(); TestNonIPCMessageEnqueuer* enqueuer = test_non_ipc_enqueuer(); diff --git a/chromium/content/browser/renderer_host/input/autoscroll_browsertest.cc b/chromium/content/browser/renderer_host/input/autoscroll_browsertest.cc index 9bc610581d5..c0663aa3d79 100644 --- a/chromium/content/browser/renderer_host/input/autoscroll_browsertest.cc +++ b/chromium/content/browser/renderer_host/input/autoscroll_browsertest.cc @@ -12,6 +12,7 @@ #include "content/public/test/content_browser_test.h" #include "content/public/test/content_browser_test_utils.h" #include "content/shell/browser/shell.h" +#include "third_party/blink/public/common/input/synthetic_web_input_event_builders.h" #include "ui/events/base_event_utils.h" using blink::WebInputEvent; @@ -125,8 +126,7 @@ class AutoscrollBrowserTest : public ContentBrowserTest { RenderFrameSubmissionObserver observer( GetWidgetHost()->render_frame_metadata_provider()); for (int i = 0; i < num_repeat; i++) { - GetWidgetHost()->Send( - new WidgetMsg_ForceRedraw(GetWidgetHost()->GetRoutingID(), i)); + GetWidgetHost()->RequestForceRedraw(i); observer.WaitForAnyFrameSubmission(); } } @@ -135,15 +135,16 @@ class AutoscrollBrowserTest : public ContentBrowserTest { bool is_autoscroll_in_progress = GetWidgetHost()->IsAutoscrollInProgress(); // Simulate and send middle click mouse down. - blink::WebMouseEvent down_event = SyntheticWebMouseEventBuilder::Build( - blink::WebInputEvent::Type::kMouseDown, x, y, modifiers); + blink::WebMouseEvent down_event = + blink::SyntheticWebMouseEventBuilder::Build( + blink::WebInputEvent::Type::kMouseDown, x, y, modifiers); down_event.button = blink::WebMouseEvent::Button::kMiddle; down_event.SetTimeStamp(ui::EventTimeForNow()); down_event.SetPositionInScreen(x, y); GetWidgetHost()->ForwardMouseEvent(down_event); // Simulate and send middle click mouse up. - blink::WebMouseEvent up_event = SyntheticWebMouseEventBuilder::Build( + blink::WebMouseEvent up_event = blink::SyntheticWebMouseEventBuilder::Build( blink::WebInputEvent::Type::kMouseUp, x, y, modifiers); up_event.button = blink::WebMouseEvent::Button::kMiddle; up_event.SetTimeStamp(ui::EventTimeForNow()); @@ -184,7 +185,7 @@ IN_PROC_BROWSER_TEST_F(AutoscrollBrowserTest, AutoscrollFling) { // The page should start scrolling with mouse move. RenderFrameSubmissionObserver observer( GetWidgetHost()->render_frame_metadata_provider()); - blink::WebMouseEvent move_event = SyntheticWebMouseEventBuilder::Build( + blink::WebMouseEvent move_event = blink::SyntheticWebMouseEventBuilder::Build( blink::WebInputEvent::Type::kMouseMove, 50, 50, blink::WebInputEvent::kNoModifiers); move_event.SetTimeStamp(ui::EventTimeForNow()); @@ -205,7 +206,7 @@ IN_PROC_BROWSER_TEST_F(AutoscrollBrowserTest, AutoscrollFlingGSBDeltaHints) { SimulateMiddleClick(10, 10, blink::WebInputEvent::kNoModifiers); // A GSB will be sent on first mouse move. - blink::WebMouseEvent move_event = SyntheticWebMouseEventBuilder::Build( + blink::WebMouseEvent move_event = blink::SyntheticWebMouseEventBuilder::Build( blink::WebInputEvent::Type::kMouseMove, 50, 50, blink::WebInputEvent::kNoModifiers); move_event.SetTimeStamp(ui::EventTimeForNow()); @@ -232,7 +233,7 @@ IN_PROC_BROWSER_TEST_F(AutoscrollBrowserTest, SimulateMiddleClick(10, 10, blink::WebInputEvent::kNoModifiers); // Check that the generated GSU has non-zero position in widget. - blink::WebMouseEvent move_event = SyntheticWebMouseEventBuilder::Build( + blink::WebMouseEvent move_event = blink::SyntheticWebMouseEventBuilder::Build( blink::WebInputEvent::Type::kMouseMove, 50, 50, blink::WebInputEvent::kNoModifiers); move_event.SetTimeStamp(ui::EventTimeForNow()); @@ -271,7 +272,7 @@ IN_PROC_BROWSER_TEST_F(AutoscrollBrowserTest, RenderFrameSubmissionObserver observer( GetWidgetHost()->render_frame_metadata_provider()); blink::WebMouseWheelEvent wheel_event = - SyntheticWebMouseWheelEventBuilder::Build( + blink::SyntheticWebMouseWheelEventBuilder::Build( 10, 10, 0, -53, 0, ui::ScrollGranularity::kScrollByPrecisePixel); wheel_event.phase = blink::WebMouseWheelEvent::kPhaseBegan; GetWidgetHost()->ForwardWheelEvent(wheel_event); @@ -291,7 +292,7 @@ IN_PROC_BROWSER_TEST_F(AutoscrollBrowserTest, RenderFrameSubmissionObserver observer( GetWidgetHost()->render_frame_metadata_provider()); blink::WebMouseWheelEvent wheel_event = - SyntheticWebMouseWheelEventBuilder::Build( + blink::SyntheticWebMouseWheelEventBuilder::Build( 10, 10, 0, -53, 0, ui::ScrollGranularity::kScrollByPrecisePixel); wheel_event.phase = blink::WebMouseWheelEvent::kPhaseBegan; GetWidgetHost()->ForwardWheelEvent(wheel_event); @@ -319,7 +320,7 @@ IN_PROC_BROWSER_TEST_F(AutoscrollBrowserTest, // Move the mouse up, no scrolling happens since the page is at its extent. auto scroll_update_watcher = std::make_unique<InputMsgWatcher>( GetWidgetHost(), blink::WebInputEvent::Type::kGestureScrollUpdate); - blink::WebMouseEvent move_up = SyntheticWebMouseEventBuilder::Build( + blink::WebMouseEvent move_up = blink::SyntheticWebMouseEventBuilder::Build( blink::WebInputEvent::Type::kMouseMove, 20, 20, blink::WebInputEvent::kNoModifiers); move_up.SetTimeStamp(ui::EventTimeForNow()); @@ -336,7 +337,7 @@ IN_PROC_BROWSER_TEST_F(AutoscrollBrowserTest, // timeout if autoscrolling does not work after direction change. RenderFrameSubmissionObserver observer( GetWidgetHost()->render_frame_metadata_provider()); - blink::WebMouseEvent move_down = SyntheticWebMouseEventBuilder::Build( + blink::WebMouseEvent move_down = blink::SyntheticWebMouseEventBuilder::Build( blink::WebInputEvent::Type::kMouseMove, 180, 180, blink::WebInputEvent::kNoModifiers); move_down.SetTimeStamp(ui::EventTimeForNow()); diff --git a/chromium/content/browser/renderer_host/input/compositor_event_ack_browsertest.cc b/chromium/content/browser/renderer_host/input/compositor_event_ack_browsertest.cc index 0300adb8e03..7169c2df905 100644 --- a/chromium/content/browser/renderer_host/input/compositor_event_ack_browsertest.cc +++ b/chromium/content/browser/renderer_host/input/compositor_event_ack_browsertest.cc @@ -16,7 +16,6 @@ #include "content/browser/renderer_host/render_widget_host_input_event_router.h" #include "content/browser/renderer_host/render_widget_host_view_base.h" #include "content/browser/web_contents/web_contents_impl.h" -#include "content/common/input/synthetic_web_input_event_builders.h" #include "content/common/input_messages.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/render_widget_host_view.h" @@ -28,6 +27,7 @@ #include "content/public/test/hit_test_region_observer.h" #include "content/public/test/test_utils.h" #include "content/shell/browser/shell.h" +#include "third_party/blink/public/common/input/synthetic_web_input_event_builders.h" #include "third_party/blink/public/common/input/web_input_event.h" #include "ui/events/base_event_utils.h" #include "ui/events/event_switches.h" @@ -166,7 +166,7 @@ class CompositorEventAckBrowserTest : public ContentBrowserTest { // This event never completes its processing. As kCompositorEventAckDataURL // will block the renderer's main thread once it is received. blink::WebMouseWheelEvent wheel_event = - SyntheticWebMouseWheelEventBuilder::Build( + blink::SyntheticWebMouseWheelEventBuilder::Build( 10, 10, 0, -53, 0, ui::ScrollGranularity::kScrollByPrecisePixel); wheel_event.phase = blink::WebMouseWheelEvent::kPhaseBegan; GetWidgetHost()->ForwardWheelEvent(wheel_event); @@ -255,7 +255,7 @@ IN_PROC_BROWSER_TEST_F(CompositorEventAckBrowserTest, auto* input_event_router = GetWidgetHost()->delegate()->GetInputEventRouter(); // Send a TouchStart so that we can set allowed touch action to Auto. - SyntheticWebTouchEvent touch_event; + blink::SyntheticWebTouchEvent touch_event; touch_event.PressPoint(50, 50); touch_event.SetTimeStamp(ui::EventTimeForNow()); input_event_router->RouteTouchEvent(root_view, &touch_event, diff --git a/chromium/content/browser/renderer_host/input/event_latency_aura_browsertest.cc b/chromium/content/browser/renderer_host/input/event_latency_aura_browsertest.cc index 3a86f59f27b..7ce2be8b615 100644 --- a/chromium/content/browser/renderer_host/input/event_latency_aura_browsertest.cc +++ b/chromium/content/browser/renderer_host/input/event_latency_aura_browsertest.cc @@ -64,7 +64,8 @@ class EventLatencyBrowserTest : public ContentBrowserTest { // Tests that if a key-press on a page causes a visual update, appropriate event // latency metrics are reported. -IN_PROC_BROWSER_TEST_F(EventLatencyBrowserTest, KeyPressOnButton) { +// TODO(crbug.com/1085046): flaky test. +IN_PROC_BROWSER_TEST_F(EventLatencyBrowserTest, DISABLED_KeyPressOnButton) { base::HistogramTester histogram_tester; ASSERT_NO_FATAL_FAILURE(LoadTestPage()); diff --git a/chromium/content/browser/renderer_host/input/fling_browsertest.cc b/chromium/content/browser/renderer_host/input/fling_browsertest.cc index ba9bbc9b4d5..c63608e368a 100644 --- a/chromium/content/browser/renderer_host/input/fling_browsertest.cc +++ b/chromium/content/browser/renderer_host/input/fling_browsertest.cc @@ -16,6 +16,7 @@ #include "content/shell/browser/shell.h" #include "content/test/content_browser_test_utils_internal.h" #include "net/dns/mock_host_resolver.h" +#include "third_party/blink/public/common/input/synthetic_web_input_event_builders.h" #include "third_party/blink/public/common/input/web_input_event.h" #include "ui/base/ui_base_features.h" #include "ui/events/base_event_utils.h" @@ -199,7 +200,7 @@ class BrowserSideFlingBrowserTest : public ContentBrowserTest { render_widget_host, blink::WebInputEvent::Type::kGestureScrollBegin); blink::WebMouseWheelEvent wheel_event = - SyntheticWebMouseWheelEventBuilder::Build( + blink::SyntheticWebMouseWheelEventBuilder::Build( 10, 10, fling_velocity.x() / 1000, fling_velocity.y() / 1000, 0, ui::ScrollGranularity::kScrollByPrecisePixel); wheel_event.phase = blink::WebMouseWheelEvent::kPhaseBegan; diff --git a/chromium/content/browser/renderer_host/input/gesture_event_queue_unittest.cc b/chromium/content/browser/renderer_host/input/gesture_event_queue_unittest.cc index b6c72126ffd..bdd4a78e781 100644 --- a/chromium/content/browser/renderer_host/input/gesture_event_queue_unittest.cc +++ b/chromium/content/browser/renderer_host/input/gesture_event_queue_unittest.cc @@ -20,8 +20,8 @@ #include "build/build_config.h" #include "content/browser/renderer_host/input/input_router_config_helper.h" #include "content/browser/renderer_host/input/touchpad_tap_suppression_controller.h" -#include "content/common/input/synthetic_web_input_event_builders.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/common/input/synthetic_web_input_event_builders.h" #include "third_party/blink/public/common/input/web_input_event.h" #include "third_party/blink/public/mojom/input/input_event_result.mojom-shared.h" #include "ui/events/blink/blink_features.h" @@ -129,37 +129,38 @@ class GestureEventQueueTest : public testing::Test, void SimulateGestureEvent(WebInputEvent::Type type, WebGestureDevice sourceDevice) { SimulateGestureEvent( - SyntheticWebGestureEventBuilder::Build(type, sourceDevice)); + blink::SyntheticWebGestureEventBuilder::Build(type, sourceDevice)); } void SimulateGSEGeneratedByFlingController(WebGestureDevice sourceDevice) { - WebGestureEvent gesture_scroll_end = SyntheticWebGestureEventBuilder::Build( - WebInputEvent::Type::kGestureScrollEnd, sourceDevice); + WebGestureEvent gesture_scroll_end = + blink::SyntheticWebGestureEventBuilder::Build( + WebInputEvent::Type::kGestureScrollEnd, sourceDevice); gesture_scroll_end.data.scroll_end.generated_by_fling_controller = true; SimulateGestureEvent(gesture_scroll_end); } void SimulateGestureScrollUpdateEvent(float dX, float dY, int modifiers) { - SimulateGestureEvent(SyntheticWebGestureEventBuilder::BuildScrollUpdate( - dX, dY, modifiers, blink::WebGestureDevice::kTouchscreen)); + SimulateGestureEvent( + blink::SyntheticWebGestureEventBuilder::BuildScrollUpdate( + dX, dY, modifiers, blink::WebGestureDevice::kTouchscreen)); } void SimulateGesturePinchUpdateEvent(float scale, float anchorX, float anchorY, int modifiers) { - SimulateGestureEvent(SyntheticWebGestureEventBuilder::BuildPinchUpdate( - scale, anchorX, anchorY, modifiers, - blink::WebGestureDevice::kTouchscreen)); + SimulateGestureEvent( + blink::SyntheticWebGestureEventBuilder::BuildPinchUpdate( + scale, anchorX, anchorY, modifiers, + blink::WebGestureDevice::kTouchscreen)); } void SimulateGestureFlingStartEvent(float velocityX, float velocityY, WebGestureDevice sourceDevice) { - SimulateGestureEvent( - SyntheticWebGestureEventBuilder::BuildFling(velocityX, - velocityY, - sourceDevice)); + SimulateGestureEvent(blink::SyntheticWebGestureEventBuilder::BuildFling( + velocityX, velocityY, sourceDevice)); } void SendInputEventACK(WebInputEvent::Type type, @@ -194,7 +195,7 @@ class GestureEventQueueTest : public testing::Test, void set_sync_followup_event(WebInputEvent::Type type, WebGestureDevice sourceDevice) { sync_followup_event_.reset(new WebGestureEvent( - SyntheticWebGestureEventBuilder::Build(type, sourceDevice))); + blink::SyntheticWebGestureEventBuilder::Build(type, sourceDevice))); } unsigned GestureEventQueueSize() { diff --git a/chromium/content/browser/renderer_host/input/input_router.h b/chromium/content/browser/renderer_host/input/input_router.h index 8d09e00cca5..ee162263d21 100644 --- a/chromium/content/browser/renderer_host/input/input_router.h +++ b/chromium/content/browser/renderer_host/input/input_router.h @@ -10,11 +10,11 @@ #include "content/browser/renderer_host/event_with_latency_info.h" #include "content/browser/renderer_host/input/gesture_event_queue.h" #include "content/browser/renderer_host/input/passthrough_touch_event_queue.h" -#include "content/common/widget.mojom.h" #include "content/public/browser/native_web_keyboard_event.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "third_party/blink/public/common/input/web_input_event.h" #include "third_party/blink/public/mojom/input/input_event_result.mojom-shared.h" +#include "third_party/blink/public/mojom/input/input_handler.mojom.h" namespace content { @@ -86,11 +86,8 @@ class InputRouter { virtual void SetForceEnableZoom(bool enabled) = 0; // Create and bind a new host channel. - virtual mojo::PendingRemote<mojom::WidgetInputHandlerHost> BindNewHost() = 0; - - // Create and bind a new frame based host channel. - virtual mojo::PendingRemote<mojom::WidgetInputHandlerHost> - BindNewFrameHost() = 0; + virtual mojo::PendingRemote<blink::mojom::WidgetInputHandlerHost> + BindNewHost() = 0; // Used to stop an active fling if such exists. virtual void StopFling() = 0; diff --git a/chromium/content/browser/renderer_host/input/input_router_client.h b/chromium/content/browser/renderer_host/input/input_router_client.h index 137975ca6db..fea6b9e9dc8 100644 --- a/chromium/content/browser/renderer_host/input/input_router_client.h +++ b/chromium/content/browser/renderer_host/input/input_router_client.h @@ -8,10 +8,10 @@ #include "cc/input/touch_action.h" #include "content/browser/renderer_host/event_with_latency_info.h" #include "content/common/content_export.h" -#include "content/common/input/input_handler.mojom.h" #include "content/public/browser/native_web_keyboard_event.h" #include "third_party/blink/public/common/input/web_input_event.h" #include "third_party/blink/public/mojom/input/input_event_result.mojom-shared.h" +#include "third_party/blink/public/mojom/input/input_handler.mojom.h" namespace ui { class LatencyInfo; @@ -45,9 +45,9 @@ class CONTENT_EXPORT InputRouterClient { // renderer. virtual void DidOverscroll(const ui::DidOverscrollParams& params) = 0; - // Called when the router has received a whitelisted touch action notification + // Called when the router has received an allowed touch action notification // from the renderer. - virtual void OnSetWhiteListedTouchAction(cc::TouchAction touch_action) = 0; + virtual void OnSetCompositorAllowedTouchAction(cc::TouchAction) = 0; // Called when a GSB has started scrolling a viewport. virtual void DidStartScrollingViewport() = 0; @@ -82,7 +82,8 @@ class CONTENT_EXPORT InputRouterClient { bool from_user_gesture, bool privileged, bool unadjusted_movement, - mojom::WidgetInputHandlerHost::RequestMouseLockCallback response) = 0; + blink::mojom::WidgetInputHandlerHost::RequestMouseLockCallback + response) = 0; // Returns the size of visible viewport in screen space, in DIPs. virtual gfx::Size GetRootWidgetViewportSize() = 0; diff --git a/chromium/content/browser/renderer_host/input/input_router_impl.cc b/chromium/content/browser/renderer_host/input/input_router_impl.cc index a7a2b26cd94..fffec86cf97 100644 --- a/chromium/content/browser/renderer_host/input/input_router_impl.cc +++ b/chromium/content/browser/renderer_host/input/input_router_impl.cc @@ -17,7 +17,6 @@ #include "content/browser/renderer_host/input/input_disposition_handler.h" #include "content/browser/renderer_host/input/input_router_client.h" #include "content/common/content_constants_internal.h" -#include "content/common/input/input_handler.mojom.h" #include "content/common/input/web_touch_event_traits.h" #include "content/common/input_messages.h" #include "content/public/browser/notification_service.h" @@ -26,7 +25,9 @@ #include "content/public/common/input_event_ack_state.h" #include "ipc/ipc_sender.h" #include "services/tracing/public/cpp/perfetto/flow_event_utils.h" +#include "third_party/blink/public/common/input/web_coalesced_input_event.h" #include "third_party/blink/public/mojom/input/input_event_result.mojom-shared.h" +#include "third_party/blink/public/mojom/input/input_handler.mojom-shared.h" #include "ui/events/blink/blink_event_util.h" #include "ui/events/blink/blink_features.h" #include "ui/events/blink/web_input_event_traits.h" @@ -58,18 +59,23 @@ bool WasHandled(blink::mojom::InputEventResultState state) { } } -std::unique_ptr<InputEvent> ScaleEvent(const WebInputEvent& event, - double scale, - const ui::LatencyInfo& latency_info) { +std::unique_ptr<blink::WebCoalescedInputEvent> ScaleEvent( + const WebInputEvent& event, + double scale, + const ui::LatencyInfo& latency_info) { std::unique_ptr<blink::WebInputEvent> event_in_viewport = ui::ScaleWebInputEvent(event, scale); if (event_in_viewport) { - return std::make_unique<InputEvent>( - ui::WebScopedInputEvent(event_in_viewport.release()), + return std::make_unique<blink::WebCoalescedInputEvent>( + std::move(event_in_viewport), + std::vector<std::unique_ptr<WebInputEvent>>(), + std::vector<std::unique_ptr<WebInputEvent>>(), latency_info.ScaledBy(scale)); } - return std::make_unique<InputEvent>(event.Clone(), latency_info); + return std::make_unique<blink::WebCoalescedInputEvent>( + event.Clone(), std::vector<std::unique_ptr<WebInputEvent>>(), + std::vector<std::unique_ptr<WebInputEvent>>(), latency_info); } } // namespace @@ -128,7 +134,7 @@ void InputRouterImpl::SendKeyboardEvent( const NativeWebKeyboardEventWithLatencyInfo& key_event, KeyboardEventCallback event_result_callback) { gesture_event_queue_.StopFling(); - mojom::WidgetInputHandler::DispatchEventCallback callback = + blink::mojom::WidgetInputHandler::DispatchEventCallback callback = base::BindOnce(&InputRouterImpl::KeyboardEventHandled, weak_this_, key_event, std::move(event_result_callback)); FilterAndSendWebInputEvent(key_event.event, key_event.latency, @@ -250,18 +256,12 @@ base::Optional<cc::TouchAction> InputRouterImpl::ActiveTouchAction() { return touch_action_filter_.active_touch_action(); } -mojo::PendingRemote<mojom::WidgetInputHandlerHost> +mojo::PendingRemote<blink::mojom::WidgetInputHandlerHost> InputRouterImpl::BindNewHost() { host_receiver_.reset(); return host_receiver_.BindNewPipeAndPassRemote(); } -mojo::PendingRemote<mojom::WidgetInputHandlerHost> -InputRouterImpl::BindNewFrameHost() { - frame_host_receiver_.reset(); - return frame_host_receiver_.BindNewPipeAndPassRemote(); -} - void InputRouterImpl::StopFling() { gesture_event_queue_.StopFling(); } @@ -286,12 +286,12 @@ void InputRouterImpl::SetTouchActionFromMain(cc::TouchAction touch_action) { UpdateTouchAckTimeoutEnabled(); } -void InputRouterImpl::OnSetWhiteListedTouchAction( +void InputRouterImpl::OnSetCompositorAllowedTouchAction( cc::TouchAction touch_action) { - TRACE_EVENT1("input", "InputRouterImpl::OnSetWhiteListedTouchAction", + TRACE_EVENT1("input", "InputRouterImpl::OnSetCompositorAllowedTouchAction", "action", cc::TouchActionToString(touch_action)); - touch_action_filter_.OnSetWhiteListedTouchAction(touch_action); - client_->OnSetWhiteListedTouchAction(touch_action); + touch_action_filter_.OnSetCompositorAllowedTouchAction(touch_action); + client_->OnSetCompositorAllowedTouchAction(touch_action); if (touch_action == cc::TouchAction::kAuto) FlushDeferredGestureQueue(); UpdateTouchAckTimeoutEnabled(); @@ -370,7 +370,7 @@ void InputRouterImpl::SetMovementXYForTouchPoints(blink::WebTouchEvent* event) { void InputRouterImpl::SendMouseEventImmediately( const MouseEventWithLatencyInfo& mouse_event, MouseEventCallback event_result_callback) { - mojom::WidgetInputHandler::DispatchEventCallback callback = + blink::mojom::WidgetInputHandler::DispatchEventCallback callback = base::BindOnce(&InputRouterImpl::MouseEventHandled, weak_this_, mouse_event, std::move(event_result_callback)); FilterAndSendWebInputEvent(mouse_event.event, mouse_event.latency, @@ -379,8 +379,9 @@ void InputRouterImpl::SendMouseEventImmediately( void InputRouterImpl::SendTouchEventImmediately( const TouchEventWithLatencyInfo& touch_event) { - mojom::WidgetInputHandler::DispatchEventCallback callback = base::BindOnce( - &InputRouterImpl::TouchEventHandled, weak_this_, touch_event); + blink::mojom::WidgetInputHandler::DispatchEventCallback callback = + base::BindOnce(&InputRouterImpl::TouchEventHandled, weak_this_, + touch_event); FilterAndSendWebInputEvent(touch_event.event, touch_event.latency, std::move(callback)); } @@ -427,8 +428,9 @@ void InputRouterImpl::OnFilteringTouchEvent(const WebTouchEvent& touch_event) { void InputRouterImpl::SendGestureEventImmediately( const GestureEventWithLatencyInfo& gesture_event) { - mojom::WidgetInputHandler::DispatchEventCallback callback = base::BindOnce( - &InputRouterImpl::GestureEventHandled, weak_this_, gesture_event); + blink::mojom::WidgetInputHandler::DispatchEventCallback callback = + base::BindOnce(&InputRouterImpl::GestureEventHandled, weak_this_, + gesture_event); FilterAndSendWebInputEvent(gesture_event.event, gesture_event.latency, std::move(callback)); } @@ -461,7 +463,7 @@ void InputRouterImpl::SendMouseWheelEventImmediately( const MouseWheelEventWithLatencyInfo& wheel_event, MouseWheelEventQueueClient::MouseWheelEventHandledCallback callee_callback) { - mojom::WidgetInputHandler::DispatchEventCallback callback = + blink::mojom::WidgetInputHandler::DispatchEventCallback callback = base::BindOnce(&InputRouterImpl::MouseWheelEventHandled, weak_this_, wheel_event, std::move(callee_callback)); FilterAndSendWebInputEvent(wheel_event.event, wheel_event.latency, @@ -506,7 +508,7 @@ bool InputRouterImpl::IsAutoscrollInProgress() { void InputRouterImpl::FilterAndSendWebInputEvent( const WebInputEvent& input_event, const ui::LatencyInfo& latency_info, - mojom::WidgetInputHandler::DispatchEventCallback callback) { + blink::mojom::WidgetInputHandler::DispatchEventCallback callback) { TRACE_EVENT1("input", "InputRouterImpl::FilterAndSendWebInputEvent", "type", WebInputEvent::GetName(input_event.GetType())); TRACE_EVENT("input,benchmark,devtools.timeline", "LatencyInfo.Flow", @@ -537,15 +539,15 @@ void InputRouterImpl::FilterAndSendWebInputEvent( return; } - std::unique_ptr<InputEvent> event = + std::unique_ptr<blink::WebCoalescedInputEvent> event = ScaleEvent(input_event, device_scale_factor_, latency_info); if (WebInputEventTraits::ShouldBlockEventStream(input_event)) { TRACE_EVENT_INSTANT0("input", "InputEventSentBlocking", TRACE_EVENT_SCOPE_THREAD); client_->IncrementInFlightEventCount(); - mojom::WidgetInputHandler::DispatchEventCallback renderer_callback = + blink::mojom::WidgetInputHandler::DispatchEventCallback renderer_callback = base::BindOnce( - [](mojom::WidgetInputHandler::DispatchEventCallback callback, + [](blink::mojom::WidgetInputHandler::DispatchEventCallback callback, base::WeakPtr<InputRouterImpl> input_router, blink::mojom::InputEventResultSource source, const ui::LatencyInfo& latency, @@ -638,7 +640,7 @@ void InputRouterImpl::TouchEventHandled( // time the ACK is handled. if (touch_action) { if (source == blink::mojom::InputEventResultSource::kCompositorThread) - OnSetWhiteListedTouchAction(touch_action->touch_action); + OnSetCompositorAllowedTouchAction(touch_action->touch_action); else if (source == blink::mojom::InputEventResultSource::kMainThread) OnSetTouchAction(touch_action->touch_action); else @@ -759,12 +761,12 @@ void InputRouterImpl::UpdateTouchAckTimeoutEnabled() { // to page functionality, so the timeout could do more harm than good. base::Optional<cc::TouchAction> allowed_touch_action = touch_action_filter_.allowed_touch_action(); - cc::TouchAction white_listed_touch_action = - touch_action_filter_.white_listed_touch_action(); + cc::TouchAction compositor_allowed_touch_action = + touch_action_filter_.compositor_allowed_touch_action(); const bool touch_ack_timeout_disabled = (allowed_touch_action.has_value() && allowed_touch_action.value() == cc::TouchAction::kNone) || - (white_listed_touch_action == cc::TouchAction::kNone); + (compositor_allowed_touch_action == cc::TouchAction::kNone); touch_event_queue_.SetAckTimeoutEnabled(!touch_ack_timeout_disabled); } diff --git a/chromium/content/browser/renderer_host/input/input_router_impl.h b/chromium/content/browser/renderer_host/input/input_router_impl.h index 47961159c83..bb3186bb930 100644 --- a/chromium/content/browser/renderer_host/input/input_router_impl.h +++ b/chromium/content/browser/renderer_host/input/input_router_impl.h @@ -24,12 +24,11 @@ #include "content/browser/renderer_host/input/touch_action_filter.h" #include "content/browser/renderer_host/input/touchpad_pinch_event_queue.h" #include "content/common/input/input_event_stream_validator.h" -#include "content/common/input/input_handler.mojom.h" -#include "content/common/widget.mojom.h" #include "content/public/browser/native_web_keyboard_event.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/receiver.h" #include "third_party/blink/public/mojom/input/input_event_result.mojom-shared.h" +#include "third_party/blink/public/mojom/input/input_handler.mojom.h" namespace ui { class LatencyInfo; @@ -43,7 +42,7 @@ class MockRenderWidgetHost; class CONTENT_EXPORT InputRouterImplClient : public InputRouterClient { public: - virtual mojom::WidgetInputHandler* GetWidgetInputHandler() = 0; + virtual blink::mojom::WidgetInputHandler* GetWidgetInputHandler() = 0; virtual void OnImeCancelComposition() = 0; virtual void OnImeCompositionRangeChanged( const gfx::Range& range, @@ -51,13 +50,14 @@ class CONTENT_EXPORT InputRouterImplClient : public InputRouterClient { }; // A default implementation for browser input event routing. -class CONTENT_EXPORT InputRouterImpl : public InputRouter, - public GestureEventQueueClient, - public FlingControllerEventSenderClient, - public MouseWheelEventQueueClient, - public PassthroughTouchEventQueueClient, - public TouchpadPinchEventQueueClient, - public mojom::WidgetInputHandlerHost { +class CONTENT_EXPORT InputRouterImpl + : public InputRouter, + public GestureEventQueueClient, + public FlingControllerEventSenderClient, + public MouseWheelEventQueueClient, + public PassthroughTouchEventQueueClient, + public TouchpadPinchEventQueueClient, + public blink::mojom::WidgetInputHandlerHost { public: InputRouterImpl(InputRouterImplClient* client, InputDispositionHandler* disposition_handler, @@ -82,8 +82,7 @@ class CONTENT_EXPORT InputRouterImpl : public InputRouter, void SetForceEnableZoom(bool enabled) override; base::Optional<cc::TouchAction> AllowedTouchAction() override; base::Optional<cc::TouchAction> ActiveTouchAction() override; - mojo::PendingRemote<mojom::WidgetInputHandlerHost> BindNewHost() override; - mojo::PendingRemote<mojom::WidgetInputHandlerHost> BindNewFrameHost() + mojo::PendingRemote<blink::mojom::WidgetInputHandlerHost> BindNewHost() override; void StopFling() override; void OnSetTouchAction(cc::TouchAction touch_action) override; @@ -107,9 +106,9 @@ class CONTENT_EXPORT InputRouterImpl : public InputRouter, void FlushTouchEventQueue() override; // Exposed so that tests can swap out the implementation and intercept calls. - mojo::Receiver<mojom::WidgetInputHandlerHost>& - frame_host_receiver_for_testing() { - return frame_host_receiver_; + mojo::Receiver<blink::mojom::WidgetInputHandlerHost>& + host_receiver_for_testing() { + return host_receiver_; } void ForceResetTouchActionForTest(); @@ -181,7 +180,7 @@ class CONTENT_EXPORT InputRouterImpl : public InputRouter, void FilterAndSendWebInputEvent( const blink::WebInputEvent& input_event, const ui::LatencyInfo& latency_info, - mojom::WidgetInputHandler::DispatchEventCallback callback); + blink::mojom::WidgetInputHandler::DispatchEventCallback callback); void KeyboardEventHandled(const NativeWebKeyboardEventWithLatencyInfo& event, KeyboardEventCallback event_result_callback, @@ -229,7 +228,7 @@ class CONTENT_EXPORT InputRouterImpl : public InputRouter, GestureEventWithLatencyInfo& gesture_event, const FilterGestureEventResult& existing_result); void ProcessDeferredGestureEventQueue(); - void OnSetWhiteListedTouchAction(cc::TouchAction touch_action); + void OnSetCompositorAllowedTouchAction(cc::TouchAction touch_action); InputRouterImplClient* client_; InputDispositionHandler* disposition_handler_; @@ -254,11 +253,7 @@ class CONTENT_EXPORT InputRouterImpl : public InputRouter, // The host receiver associated with the widget input handler from // the widget. - mojo::Receiver<mojom::WidgetInputHandlerHost> host_receiver_{this}; - - // The host receiver associated with the widget input handler from - // the frame. - mojo::Receiver<mojom::WidgetInputHandlerHost> frame_host_receiver_{this}; + mojo::Receiver<blink::mojom::WidgetInputHandlerHost> host_receiver_{this}; base::WeakPtr<InputRouterImpl> weak_this_; base::WeakPtrFactory<InputRouterImpl> weak_ptr_factory_{this}; diff --git a/chromium/content/browser/renderer_host/input/input_router_impl_unittest.cc b/chromium/content/browser/renderer_host/input/input_router_impl_unittest.cc index d70d6c359f8..9461366b199 100644 --- a/chromium/content/browser/renderer_host/input/input_router_impl_unittest.cc +++ b/chromium/content/browser/renderer_host/input/input_router_impl_unittest.cc @@ -28,7 +28,6 @@ #include "content/browser/renderer_host/input/mock_input_disposition_handler.h" #include "content/browser/renderer_host/input/mock_input_router_client.h" #include "content/common/content_constants_internal.h" -#include "content/common/input/synthetic_web_input_event_builders.h" #include "content/common/input_messages.h" #include "content/public/common/content_features.h" #include "content/public/common/content_switches.h" @@ -36,6 +35,7 @@ #include "content/public/test/test_browser_context.h" #include "content/test/mock_widget_input_handler.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/common/input/synthetic_web_input_event_builders.h" #include "ui/events/base_event_utils.h" #include "ui/events/blink/blink_features.h" #include "ui/events/blink/web_input_event_traits.h" @@ -50,10 +50,14 @@ #include "ui/display/win/test/scoped_screen_win.h" #endif +using blink::SyntheticWebGestureEventBuilder; +using blink::SyntheticWebMouseEventBuilder; +using blink::SyntheticWebMouseWheelEventBuilder; +using blink::SyntheticWebTouchEvent; using blink::WebGestureDevice; using blink::WebGestureEvent; -using blink::WebKeyboardEvent; using blink::WebInputEvent; +using blink::WebKeyboardEvent; using blink::WebMouseEvent; using blink::WebMouseWheelEvent; using blink::WebTouchEvent; @@ -98,7 +102,7 @@ WebInputEvent& GetEventWithType(WebInputEvent::Type type) { // of InputRouters. class MockInputRouterImplClient : public InputRouterImplClient { public: - mojom::WidgetInputHandler* GetWidgetInputHandler() override { + blink::mojom::WidgetInputHandler* GetWidgetInputHandler() override { return &widget_input_handler_; } @@ -110,11 +114,12 @@ class MockInputRouterImplClient : public InputRouterImplClient { void SetMouseCapture(bool capture) override {} - void RequestMouseLock(bool from_user_gesture, - bool privileged, - bool unadjusted_movement, - mojom::WidgetInputHandlerHost::RequestMouseLockCallback - response) override {} + void RequestMouseLock( + bool from_user_gesture, + bool privileged, + bool unadjusted_movement, + blink::mojom::WidgetInputHandlerHost::RequestMouseLockCallback response) + override {} gfx::Size GetRootWidgetViewportSize() override { return gfx::Size(1920, 1080); @@ -171,8 +176,9 @@ class MockInputRouterImplClient : public InputRouterImplClient { return input_router_client_.IsAutoscrollInProgress(); } - void OnSetWhiteListedTouchAction(cc::TouchAction touch_action) override { - input_router_client_.OnSetWhiteListedTouchAction(touch_action); + void OnSetCompositorAllowedTouchAction( + cc::TouchAction touch_action) override { + input_router_client_.OnSetCompositorAllowedTouchAction(touch_action); } bool GetAndResetFilterEventCalled() { @@ -183,8 +189,8 @@ class MockInputRouterImplClient : public InputRouterImplClient { return input_router_client_.GetAndResetOverscroll(); } - cc::TouchAction GetAndResetWhiteListedTouchAction() { - return input_router_client_.GetAndResetWhiteListedTouchAction(); + cc::TouchAction GetAndResetCompositorAllowedTouchAction() { + return input_router_client_.GetAndResetCompositorAllowedTouchAction(); } void set_input_router(InputRouter* input_router) { @@ -474,7 +480,7 @@ class InputRouterImplTestBase : public testing::Test { blink::mojom::InputEventResultSource source, blink::mojom::InputEventResultState ack_state, base::Optional<cc::TouchAction> expected_touch_action, - base::Optional<cc::TouchAction> expected_white_listed_touch_action) { + base::Optional<cc::TouchAction> expected_allowed_touch_action) { input_router_->OnHasTouchEventHandlers(true); EXPECT_FALSE(input_router_->AllowedTouchAction().has_value()); PressTouchPoint(1, 1); @@ -482,8 +488,9 @@ class InputRouterImplTestBase : public testing::Test { input_router_->OnTouchEventAck(TouchEventWithLatencyInfo(touch_event_), source, ack_state); EXPECT_EQ(input_router_->AllowedTouchAction(), expected_touch_action); - EXPECT_EQ(input_router_->touch_action_filter_.white_listed_touch_action(), - expected_white_listed_touch_action.value()); + EXPECT_EQ( + input_router_->touch_action_filter_.compositor_allowed_touch_action(), + expected_allowed_touch_action.value()); } const float radius_x_ = 20.0f; @@ -506,8 +513,8 @@ class InputRouterImplTest : public InputRouterImplTestBase { return input_router_->touch_action_filter_.allowed_touch_action_; } - cc::TouchAction WhiteListedTouchAction() { - return input_router_->touch_action_filter_.white_listed_touch_action_; + cc::TouchAction CompositorAllowedTouchAction() { + return input_router_->touch_action_filter_.compositor_allowed_touch_action_; } }; @@ -588,10 +595,10 @@ TEST_F(InputRouterImplTest, CoalescesWheelEvents) { ASSERT_EQ(1u, dispatched_messages.size()); ASSERT_TRUE(dispatched_messages[0]->ToEvent()); ASSERT_EQ(WebInputEvent::Type::kMouseWheel, - dispatched_messages[0]->ToEvent()->Event()->web_event->GetType()); + dispatched_messages[0]->ToEvent()->Event()->Event().GetType()); const WebMouseWheelEvent* wheel_event = static_cast<const WebMouseWheelEvent*>( - dispatched_messages[0]->ToEvent()->Event()->web_event.get()); + &dispatched_messages[0]->ToEvent()->Event()->Event()); EXPECT_EQ(0, wheel_event->delta_x); EXPECT_EQ(-5, wheel_event->delta_y); @@ -607,9 +614,9 @@ TEST_F(InputRouterImplTest, CoalescesWheelEvents) { ASSERT_EQ(1u, dispatched_messages.size()); ASSERT_TRUE(dispatched_messages[0]->ToEvent()); ASSERT_EQ(WebInputEvent::Type::kMouseWheel, - dispatched_messages[0]->ToEvent()->Event()->web_event->GetType()); + dispatched_messages[0]->ToEvent()->Event()->Event().GetType()); wheel_event = static_cast<const WebMouseWheelEvent*>( - dispatched_messages[0]->ToEvent()->Event()->web_event.get()); + &dispatched_messages[0]->ToEvent()->Event()->Event()); EXPECT_EQ(8, wheel_event->delta_x); EXPECT_EQ(-10 + -6, wheel_event->delta_y); // coalesced @@ -622,9 +629,9 @@ TEST_F(InputRouterImplTest, CoalescesWheelEvents) { ASSERT_EQ(1u, dispatched_messages.size()); ASSERT_TRUE(dispatched_messages[0]->ToEvent()); ASSERT_EQ(WebInputEvent::Type::kMouseWheel, - dispatched_messages[0]->ToEvent()->Event()->web_event->GetType()); + dispatched_messages[0]->ToEvent()->Event()->Event().GetType()); wheel_event = static_cast<const WebMouseWheelEvent*>( - dispatched_messages[0]->ToEvent()->Event()->web_event.get()); + &dispatched_messages[0]->ToEvent()->Event()->Event()); EXPECT_EQ(9, wheel_event->delta_x); EXPECT_EQ(-7, wheel_event->delta_y); @@ -637,9 +644,9 @@ TEST_F(InputRouterImplTest, CoalescesWheelEvents) { ASSERT_EQ(1u, dispatched_messages.size()); ASSERT_TRUE(dispatched_messages[0]->ToEvent()); ASSERT_EQ(WebInputEvent::Type::kMouseWheel, - dispatched_messages[0]->ToEvent()->Event()->web_event->GetType()); + dispatched_messages[0]->ToEvent()->Event()->Event().GetType()); wheel_event = static_cast<const WebMouseWheelEvent*>( - dispatched_messages[0]->ToEvent()->Event()->web_event.get()); + &dispatched_messages[0]->ToEvent()->Event()->Event()); EXPECT_EQ(0, wheel_event->delta_x); EXPECT_EQ(-10, wheel_event->delta_y); @@ -652,9 +659,9 @@ TEST_F(InputRouterImplTest, CoalescesWheelEvents) { ASSERT_EQ(1u, dispatched_messages.size()); ASSERT_TRUE(dispatched_messages[0]->ToEvent()); ASSERT_EQ(WebInputEvent::Type::kMouseWheel, - dispatched_messages[0]->ToEvent()->Event()->web_event->GetType()); + dispatched_messages[0]->ToEvent()->Event()->Event().GetType()); wheel_event = static_cast<const WebMouseWheelEvent*>( - dispatched_messages[0]->ToEvent()->Event()->web_event.get()); + &dispatched_messages[0]->ToEvent()->Event()->Event()); EXPECT_EQ(0, wheel_event->delta_x); EXPECT_EQ(0, wheel_event->delta_y); EXPECT_EQ(WebMouseWheelEvent::kPhaseEnded, wheel_event->phase); @@ -845,13 +852,13 @@ TEST_F(InputRouterImplTest, UnhandledWheelEvent) { ASSERT_TRUE(dispatched_messages[2]->ToEvent()); ASSERT_TRUE(dispatched_messages[3]->ToEvent()); ASSERT_EQ(WebInputEvent::Type::kGestureScrollBegin, - dispatched_messages[0]->ToEvent()->Event()->web_event->GetType()); + dispatched_messages[0]->ToEvent()->Event()->Event().GetType()); ASSERT_EQ(WebInputEvent::Type::kGestureScrollUpdate, - dispatched_messages[1]->ToEvent()->Event()->web_event->GetType()); + dispatched_messages[1]->ToEvent()->Event()->Event().GetType()); ASSERT_EQ(WebInputEvent::Type::kMouseWheel, - dispatched_messages[2]->ToEvent()->Event()->web_event->GetType()); + dispatched_messages[2]->ToEvent()->Event()->Event().GetType()); ASSERT_EQ(WebInputEvent::Type::kGestureScrollUpdate, - dispatched_messages[3]->ToEvent()->Event()->web_event->GetType()); + dispatched_messages[3]->ToEvent()->Event()->Event().GetType()); // Indicate that the GestureScrollBegin event was consumed. dispatched_messages[0]->ToEvent()->CallCallback( @@ -1620,6 +1627,9 @@ TEST_F(InputRouterImplTest, AsyncTouchMoveAckedImmediately) { dispatched_messages[0]->ToEvent()->CallCallback( blink::mojom::InputEventResultState::kConsumed); EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount()); + EXPECT_EQ(WebInputEvent::Type::kTouchStart, + disposition_handler_->ack_event_type()); + SimulateGestureEvent(WebInputEvent::Type::kGestureScrollBegin, blink::WebGestureDevice::kTouchscreen); dispatched_messages = GetAndResetDispatchedMessages(); @@ -1628,14 +1638,55 @@ TEST_F(InputRouterImplTest, AsyncTouchMoveAckedImmediately) { dispatched_messages[0]->ToEvent()->CallCallback( blink::mojom::InputEventResultState::kConsumed); EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount()); + EXPECT_EQ(WebInputEvent::Type::kGestureScrollBegin, + disposition_handler_->ack_event_type()); + SimulateGestureEvent(WebInputEvent::Type::kGestureScrollUpdate, blink::WebGestureDevice::kTouchscreen); EXPECT_EQ(0U, disposition_handler_->GetAndResetAckCount()); - EXPECT_EQ(2U, GetAndResetDispatchedMessages().size()); + dispatched_messages = GetAndResetDispatchedMessages(); + EXPECT_EQ(2U, dispatched_messages.size()); + EXPECT_EQ(WebInputEvent::Type::kTouchScrollStarted, + dispatched_messages[0]->ToEvent()->Event()->Event().GetType()); + EXPECT_EQ(WebInputEvent::Type::kGestureScrollUpdate, + dispatched_messages[1]->ToEvent()->Event()->Event().GetType()); + // Ack the GestureScrollUpdate. + dispatched_messages[1]->ToEvent()->CallCallback( + blink::mojom::InputEventResultState::kConsumed); + EXPECT_EQ(WebInputEvent::Type::kGestureScrollUpdate, + disposition_handler_->ack_event_type()); + EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount()); - // Now send an async move. + // Now since we're scrolling send an async move. MoveTouchPoint(0, 5, 5); SendTouchEvent(); + EXPECT_EQ(WebInputEvent::Type::kTouchMove, + disposition_handler_->ack_event_type()); + EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount()); + EXPECT_EQ(1U, GetAndResetDispatchedMessages().size()); + + // To catch crbug/1072364 send another scroll which returns kNoConsumerExists + // and ensure we're still async scrolling since we've already started the + // scroll. + SimulateGestureEvent(WebInputEvent::Type::kGestureScrollUpdate, + blink::WebGestureDevice::kTouchscreen); + EXPECT_EQ(0U, disposition_handler_->GetAndResetAckCount()); + dispatched_messages = GetAndResetDispatchedMessages(); + EXPECT_EQ(1U, dispatched_messages.size()); + EXPECT_EQ(WebInputEvent::Type::kGestureScrollUpdate, + dispatched_messages[0]->ToEvent()->Event()->Event().GetType()); + // Ack the GestureScrollUpdate. + dispatched_messages[0]->ToEvent()->CallCallback( + blink::mojom::InputEventResultState::kNoConsumerExists); + EXPECT_EQ(WebInputEvent::Type::kGestureScrollUpdate, + disposition_handler_->ack_event_type()); + EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount()); + + // Now since we're scrolling (even with NoConsumerExists) send an async move. + MoveTouchPoint(0, 10, 5); + SendTouchEvent(); + EXPECT_EQ(WebInputEvent::Type::kTouchMove, + disposition_handler_->ack_event_type()); EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount()); EXPECT_EQ(1U, GetAndResetDispatchedMessages().size()); } @@ -1766,7 +1817,7 @@ TEST_P(TouchpadPinchInputRouterImplTest, TouchpadPinchUpdate) { ASSERT_EQ(1U, dispatched_messages.size()); ASSERT_TRUE(dispatched_messages[0]->ToEvent()); const WebInputEvent* input_event = - dispatched_messages[0]->ToEvent()->Event()->web_event.get(); + &dispatched_messages[0]->ToEvent()->Event()->Event(); ASSERT_EQ(WebInputEvent::Type::kMouseWheel, input_event->GetType()); const WebMouseWheelEvent* synthetic_wheel = static_cast<const WebMouseWheelEvent*>(input_event); @@ -1800,7 +1851,7 @@ TEST_P(TouchpadPinchInputRouterImplTest, TouchpadPinchUpdate) { dispatched_messages = GetAndResetDispatchedMessages(); ASSERT_EQ(1U, dispatched_messages.size()); ASSERT_TRUE(dispatched_messages[0]->ToEvent()); - input_event = dispatched_messages[0]->ToEvent()->Event()->web_event.get(); + input_event = &dispatched_messages[0]->ToEvent()->Event()->Event(); ASSERT_EQ(WebInputEvent::Type::kMouseWheel, input_event->GetType()); synthetic_wheel = static_cast<const WebMouseWheelEvent*>(input_event); EXPECT_EQ(blink::WebMouseWheelEvent::kPhaseChanged, synthetic_wheel->phase); @@ -1840,7 +1891,7 @@ TEST_P(TouchpadPinchInputRouterImplTest, TouchpadPinchUpdate) { dispatched_messages = GetAndResetDispatchedMessages(); ASSERT_EQ(1U, dispatched_messages.size()); ASSERT_TRUE(dispatched_messages[0]->ToEvent()); - input_event = dispatched_messages[0]->ToEvent()->Event()->web_event.get(); + input_event = &dispatched_messages[0]->ToEvent()->Event()->Event(); ASSERT_EQ(WebInputEvent::Type::kMouseWheel, input_event->GetType()); synthetic_wheel = static_cast<const WebMouseWheelEvent*>(input_event); EXPECT_EQ(blink::WebMouseWheelEvent::kPhaseEnded, synthetic_wheel->phase); @@ -1870,7 +1921,7 @@ TEST_P(TouchpadPinchInputRouterImplTest, TouchpadPinchUpdate) { dispatched_messages = GetAndResetDispatchedMessages(); ASSERT_EQ(1U, dispatched_messages.size()); ASSERT_TRUE(dispatched_messages[0]->ToEvent()); - input_event = dispatched_messages[0]->ToEvent()->Event()->web_event.get(); + input_event = &dispatched_messages[0]->ToEvent()->Event()->Event(); ASSERT_EQ(WebInputEvent::Type::kMouseWheel, input_event->GetType()); synthetic_wheel = static_cast<const WebMouseWheelEvent*>(input_event); EXPECT_TRUE(synthetic_wheel->GetModifiers() & @@ -1899,7 +1950,7 @@ TEST_P(TouchpadPinchInputRouterImplTest, TouchpadPinchUpdate) { dispatched_messages = GetAndResetDispatchedMessages(); ASSERT_EQ(1U, dispatched_messages.size()); ASSERT_TRUE(dispatched_messages[0]->ToEvent()); - input_event = dispatched_messages[0]->ToEvent()->Event()->web_event.get(); + input_event = &dispatched_messages[0]->ToEvent()->Event()->Event(); ASSERT_EQ(WebInputEvent::Type::kMouseWheel, input_event->GetType()); synthetic_wheel = static_cast<const WebMouseWheelEvent*>(input_event); EXPECT_EQ(blink::WebMouseWheelEvent::kPhaseChanged, synthetic_wheel->phase); @@ -2094,9 +2145,10 @@ TEST_F(InputRouterImplTest, TouchActionInCallback) { nullptr, blink::mojom::TouchActionOptional::New(cc::TouchAction::kPan)); ASSERT_EQ(1U, disposition_handler_->GetAndResetAckCount()); base::Optional<cc::TouchAction> allowed_touch_action = AllowedTouchAction(); - cc::TouchAction white_listed_touch_action = WhiteListedTouchAction(); + cc::TouchAction compositor_allowed_touch_action = + CompositorAllowedTouchAction(); EXPECT_FALSE(allowed_touch_action.has_value()); - EXPECT_EQ(expected_touch_action.value(), white_listed_touch_action); + EXPECT_EQ(expected_touch_action.value(), compositor_allowed_touch_action); } // TODO(crbug.com/953547): enable this when the bug is fixed. @@ -2123,7 +2175,7 @@ class InputRouterImplScaleEventTest : public InputRouterImplTestBase { EXPECT_EQ(1u, dispatched_messages_.size()); return static_cast<const T*>( - dispatched_messages_[0]->ToEvent()->Event()->web_event.get()); + &dispatched_messages_[0]->ToEvent()->Event()->Event()); } template <typename T> @@ -2417,9 +2469,8 @@ class InputRouterImplScaleGestureEventTest ASSERT_EQ(expected_types.size(), dispatched_messages_.size()); for (size_t i = 0; i < dispatched_messages_.size(); i++) { ASSERT_TRUE(dispatched_messages_[i]->ToEvent()); - ASSERT_EQ( - expected_types[i], - dispatched_messages_[i]->ToEvent()->Event()->web_event->GetType()); + ASSERT_EQ(expected_types[i], + dispatched_messages_[i]->ToEvent()->Event()->Event().GetType()); dispatched_messages_[i]->ToEvent()->CallCallback( blink::mojom::InputEventResultState::kConsumed); } diff --git a/chromium/content/browser/renderer_host/input/main_thread_event_queue_browsertest.cc b/chromium/content/browser/renderer_host/input/main_thread_event_queue_browsertest.cc index 95cc5860200..f2518c5dcac 100644 --- a/chromium/content/browser/renderer_host/input/main_thread_event_queue_browsertest.cc +++ b/chromium/content/browser/renderer_host/input/main_thread_event_queue_browsertest.cc @@ -16,7 +16,6 @@ #include "content/browser/renderer_host/render_widget_host_input_event_router.h" #include "content/browser/renderer_host/render_widget_host_view_base.h" #include "content/browser/web_contents/web_contents_impl.h" -#include "content/common/input/synthetic_web_input_event_builders.h" #include "content/common/input_messages.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/render_widget_host_view.h" @@ -28,6 +27,7 @@ #include "content/public/test/hit_test_region_observer.h" #include "content/public/test/test_utils.h" #include "content/shell/browser/shell.h" +#include "third_party/blink/public/common/input/synthetic_web_input_event_builders.h" #include "third_party/blink/public/common/input/web_input_event.h" #include "ui/events/event_switches.h" #include "ui/latency/latency_info.h" @@ -117,12 +117,15 @@ class MainThreadEventQueueBrowserTest : public ContentBrowserTest { blink::WebPointerProperties::Button::kLeft); auto input_msg_watcher = std::make_unique<InputMsgWatcher>( GetWidgetHost(), blink::WebInputEvent::Type::kMouseMove); - GetWidgetHost()->ForwardMouseEvent(SyntheticWebMouseEventBuilder::Build( - blink::WebInputEvent::Type::kMouseMove, 10, 10, 0)); - GetWidgetHost()->ForwardMouseEvent(SyntheticWebMouseEventBuilder::Build( - blink::WebInputEvent::Type::kMouseMove, 15, 15, 0)); - GetWidgetHost()->ForwardMouseEvent(SyntheticWebMouseEventBuilder::Build( - blink::WebInputEvent::Type::kMouseMove, 20, 25, 0)); + GetWidgetHost()->ForwardMouseEvent( + blink::SyntheticWebMouseEventBuilder::Build( + blink::WebInputEvent::Type::kMouseMove, 10, 10, 0)); + GetWidgetHost()->ForwardMouseEvent( + blink::SyntheticWebMouseEventBuilder::Build( + blink::WebInputEvent::Type::kMouseMove, 15, 15, 0)); + GetWidgetHost()->ForwardMouseEvent( + blink::SyntheticWebMouseEventBuilder::Build( + blink::WebInputEvent::Type::kMouseMove, 20, 25, 0)); // Runs until we get the InputMsgAck callback. EXPECT_EQ(blink::mojom::InputEventResultState::kConsumed, @@ -145,7 +148,7 @@ class MainThreadEventQueueBrowserTest : public ContentBrowserTest { } void DoTouchMove() { - SyntheticWebTouchEvent events[4]; + blink::SyntheticWebTouchEvent events[4]; events[0].PressPoint(10, 10); events[1].PressPoint(10, 10); events[1].MovePoint(0, 20, 20); diff --git a/chromium/content/browser/renderer_host/input/mock_input_router.cc b/chromium/content/browser/renderer_host/input/mock_input_router.cc index 40557631617..22abfeeb336 100644 --- a/chromium/content/browser/renderer_host/input/mock_input_router.cc +++ b/chromium/content/browser/renderer_host/input/mock_input_router.cc @@ -45,16 +45,11 @@ base::Optional<cc::TouchAction> MockInputRouter::ActiveTouchAction() { return cc::TouchAction::kAuto; } -mojo::PendingRemote<mojom::WidgetInputHandlerHost> +mojo::PendingRemote<blink::mojom::WidgetInputHandlerHost> MockInputRouter::BindNewHost() { return mojo::NullRemote(); } -mojo::PendingRemote<mojom::WidgetInputHandlerHost> -MockInputRouter::BindNewFrameHost() { - return mojo::NullRemote(); -} - void MockInputRouter::OnHasTouchEventHandlers(bool has_handlers) { has_handlers_ = has_handlers; } diff --git a/chromium/content/browser/renderer_host/input/mock_input_router.h b/chromium/content/browser/renderer_host/input/mock_input_router.h index 1e09ca7b05f..de9cd9972e3 100644 --- a/chromium/content/browser/renderer_host/input/mock_input_router.h +++ b/chromium/content/browser/renderer_host/input/mock_input_router.h @@ -44,8 +44,7 @@ class MockInputRouter : public InputRouter { base::Optional<cc::TouchAction> AllowedTouchAction() override; base::Optional<cc::TouchAction> ActiveTouchAction() override; void SetForceEnableZoom(bool enabled) override {} - mojo::PendingRemote<mojom::WidgetInputHandlerHost> BindNewHost() override; - mojo::PendingRemote<mojom::WidgetInputHandlerHost> BindNewFrameHost() + mojo::PendingRemote<blink::mojom::WidgetInputHandlerHost> BindNewHost() override; void StopFling() override {} void OnSetTouchAction(cc::TouchAction touch_action) override {} diff --git a/chromium/content/browser/renderer_host/input/mock_input_router_client.cc b/chromium/content/browser/renderer_host/input/mock_input_router_client.cc index 7c1102b7ad5..95c94ab58cc 100644 --- a/chromium/content/browser/renderer_host/input/mock_input_router_client.cc +++ b/chromium/content/browser/renderer_host/input/mock_input_router_client.cc @@ -5,7 +5,6 @@ #include "content/browser/renderer_host/input/mock_input_router_client.h" #include "content/browser/renderer_host/input/input_router.h" -#include "content/common/input/input_event.h" #include "testing/gtest/include/gtest/gtest.h" using base::TimeDelta; @@ -23,7 +22,7 @@ MockInputRouterClient::MockInputRouterClient() in_flight_event_count_(0), filter_state_(blink::mojom::InputEventResultState::kNotConsumed), filter_input_event_called_(false), - white_listed_touch_action_(cc::TouchAction::kAuto) {} + compositor_allowed_touch_action_(cc::TouchAction::kAuto) {} MockInputRouterClient::~MockInputRouterClient() {} @@ -31,7 +30,7 @@ blink::mojom::InputEventResultState MockInputRouterClient::FilterInputEvent( const WebInputEvent& input_event, const ui::LatencyInfo& latency_info) { filter_input_event_called_ = true; - last_filter_event_.reset(new InputEvent(input_event, latency_info)); + last_filter_event_ = input_event.Clone(); return filter_state_; } @@ -49,9 +48,9 @@ void MockInputRouterClient::DidOverscroll( overscroll_ = params; } -void MockInputRouterClient::OnSetWhiteListedTouchAction( - cc::TouchAction white_listed_touch_action) { - white_listed_touch_action_ = white_listed_touch_action; +void MockInputRouterClient::OnSetCompositorAllowedTouchAction( + cc::TouchAction compositor_allowed_touch_action) { + compositor_allowed_touch_action_ = compositor_allowed_touch_action; } void MockInputRouterClient::DidStartScrollingViewport() {} @@ -107,10 +106,11 @@ ui::DidOverscrollParams MockInputRouterClient::GetAndResetOverscroll() { return overscroll; } -cc::TouchAction MockInputRouterClient::GetAndResetWhiteListedTouchAction() { - cc::TouchAction white_listed_touch_action = white_listed_touch_action_; - white_listed_touch_action_ = cc::TouchAction::kAuto; - return white_listed_touch_action; +cc::TouchAction +MockInputRouterClient::GetAndResetCompositorAllowedTouchAction() { + cc::TouchAction allowed = compositor_allowed_touch_action_; + compositor_allowed_touch_action_ = cc::TouchAction::kAuto; + return allowed; } bool MockInputRouterClient::NeedsBeginFrameForFlingProgress() { diff --git a/chromium/content/browser/renderer_host/input/mock_input_router_client.h b/chromium/content/browser/renderer_host/input/mock_input_router_client.h index 333a84c6b58..4830d5a845d 100644 --- a/chromium/content/browser/renderer_host/input/mock_input_router_client.h +++ b/chromium/content/browser/renderer_host/input/mock_input_router_client.h @@ -11,7 +11,6 @@ #include "content/browser/renderer_host/input/fling_controller.h" #include "content/browser/renderer_host/input/input_router_client.h" -#include "content/common/input/input_event.h" #include "ui/events/blink/did_overscroll_params.h" namespace content { @@ -32,7 +31,7 @@ class MockInputRouterClient : public InputRouterClient, void DecrementInFlightEventCount( blink::mojom::InputEventResultSource ack_source) override; void DidOverscroll(const ui::DidOverscrollParams& params) override; - void OnSetWhiteListedTouchAction(cc::TouchAction touch_action) override; + void OnSetCompositorAllowedTouchAction(cc::TouchAction touch_action) override; void DidStartScrollingViewport() override; void ForwardWheelEventWithLatencyInfo( const blink::WebMouseWheelEvent& wheel_event, @@ -43,17 +42,18 @@ class MockInputRouterClient : public InputRouterClient, bool IsWheelScrollInProgress() override; bool IsAutoscrollInProgress() override; void SetMouseCapture(bool capture) override {} - void RequestMouseLock(bool user_gesture, - bool privileged, - bool unadjusted_movement, - mojom::WidgetInputHandlerHost::RequestMouseLockCallback - response) override {} + void RequestMouseLock( + bool user_gesture, + bool privileged, + bool unadjusted_movement, + blink::mojom::WidgetInputHandlerHost::RequestMouseLockCallback response) + override {} gfx::Size GetRootWidgetViewportSize() override; void OnInvalidInputEventSource() override {} bool GetAndResetFilterEventCalled(); ui::DidOverscrollParams GetAndResetOverscroll(); - cc::TouchAction GetAndResetWhiteListedTouchAction(); + cc::TouchAction GetAndResetCompositorAllowedTouchAction(); void set_input_router(InputRouter* input_router) { input_router_ = input_router; @@ -72,7 +72,7 @@ class MockInputRouterClient : public InputRouterClient, filter_state_ = blink::mojom::InputEventResultState::kNoConsumerExists; } const blink::WebInputEvent* last_filter_event() const { - return last_filter_event_->web_event.get(); + return last_filter_event_.get(); } // FlingControllerSchedulerClient @@ -89,11 +89,11 @@ class MockInputRouterClient : public InputRouterClient, blink::mojom::InputEventResultState filter_state_; bool filter_input_event_called_; - std::unique_ptr<InputEvent> last_filter_event_; + std::unique_ptr<blink::WebInputEvent> last_filter_event_; ui::DidOverscrollParams overscroll_; - cc::TouchAction white_listed_touch_action_; + cc::TouchAction compositor_allowed_touch_action_; bool is_wheel_scroll_in_progress_ = false; }; diff --git a/chromium/content/browser/renderer_host/input/mouse_latency_browsertest.cc b/chromium/content/browser/renderer_host/input/mouse_latency_browsertest.cc index cfc239f3fd6..d134d4d7673 100644 --- a/chromium/content/browser/renderer_host/input/mouse_latency_browsertest.cc +++ b/chromium/content/browser/renderer_host/input/mouse_latency_browsertest.cc @@ -78,12 +78,10 @@ class TracingRenderWidgetHost : public RenderWidgetHostImpl { TracingRenderWidgetHost(RenderWidgetHostDelegate* delegate, RenderProcessHost* process, int32_t routing_id, - mojo::PendingRemote<mojom::Widget> widget, bool hidden) : RenderWidgetHostImpl(delegate, process, routing_id, - std::move(widget), hidden, std::make_unique<FrameTokenMessageQueue>()) { } @@ -112,10 +110,9 @@ class TracingRenderWidgetHostFactory : public RenderWidgetHostFactory { RenderWidgetHostDelegate* delegate, RenderProcessHost* process, int32_t routing_id, - mojo::PendingRemote<mojom::Widget> widget_interface, bool hidden) override { - return std::make_unique<TracingRenderWidgetHost>( - delegate, process, routing_id, std::move(widget_interface), hidden); + return std::make_unique<TracingRenderWidgetHost>(delegate, process, + routing_id, hidden); } private: diff --git a/chromium/content/browser/renderer_host/input/mouse_wheel_event_queue.cc b/chromium/content/browser/renderer_host/input/mouse_wheel_event_queue.cc index 35da2e0a436..600af684d53 100644 --- a/chromium/content/browser/renderer_host/input/mouse_wheel_event_queue.cc +++ b/chromium/content/browser/renderer_host/input/mouse_wheel_event_queue.cc @@ -8,7 +8,6 @@ #include "base/metrics/histogram_macros.h" #include "build/build_config.h" #include "content/common/input/input_event_dispatch_type.h" -#include "content/common/input/web_mouse_wheel_event_traits.h" #include "content/public/common/content_features.h" #include "ui/events/base_event_utils.h" #include "ui/events/blink/web_input_event_traits.h" @@ -44,7 +43,8 @@ void MouseWheelEventQueue::QueueEvent( // The deltas for the coalesced event change; the corresponding action // might be different now. last_event->event.event_action = - WebMouseWheelEventTraits::GetEventAction(last_event->event); + WebMouseWheelEvent::GetPlatformSpecificDefaultEventAction( + last_event->event); TRACE_EVENT_INSTANT2("input", "MouseWheelEventQueue::CoalescedWheelEvent", TRACE_EVENT_SCOPE_THREAD, "total_dx", last_event->event.delta_x, "total_dy", @@ -55,7 +55,7 @@ void MouseWheelEventQueue::QueueEvent( MouseWheelEventWithLatencyInfo event_with_action(event.event, event.latency); event_with_action.event.event_action = - WebMouseWheelEventTraits::GetEventAction(event.event); + WebMouseWheelEvent::GetPlatformSpecificDefaultEventAction(event.event); // Update the expected event action before queuing the event. From this point // on, the action should not change. wheel_queue_.push_back( diff --git a/chromium/content/browser/renderer_host/input/mouse_wheel_event_queue_unittest.cc b/chromium/content/browser/renderer_host/input/mouse_wheel_event_queue_unittest.cc index 7d6707bfa28..a2452530a8d 100644 --- a/chromium/content/browser/renderer_host/input/mouse_wheel_event_queue_unittest.cc +++ b/chromium/content/browser/renderer_host/input/mouse_wheel_event_queue_unittest.cc @@ -17,8 +17,8 @@ #include "base/threading/thread_task_runner_handle.h" #include "build/build_config.h" #include "content/browser/renderer_host/input/timeout_monitor.h" -#include "content/common/input/synthetic_web_input_event_builders.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/common/input/synthetic_web_input_event_builders.h" #include "third_party/blink/public/common/input/web_input_event.h" #include "ui/events/base_event_utils.h" @@ -254,7 +254,7 @@ class MouseWheelEventQueueTest : public testing::Test, blink::WebMouseWheelEvent::Phase momentum_phase, WebInputEvent::RailsMode rails_mode, bool has_synthetic_phase = false) { - WebMouseWheelEvent event = SyntheticWebMouseWheelEventBuilder::Build( + WebMouseWheelEvent event = blink::SyntheticWebMouseWheelEventBuilder::Build( x, y, global_x, global_y, dX, dY, modifiers, high_precision ? ui::ScrollGranularity::kScrollByPrecisePixel : ui::ScrollGranularity::kScrollByPixel); diff --git a/chromium/content/browser/renderer_host/input/passthrough_touch_event_queue.cc b/chromium/content/browser/renderer_host/input/passthrough_touch_event_queue.cc index dcc3fdf2e21..558fc1872de 100644 --- a/chromium/content/browser/renderer_host/input/passthrough_touch_event_queue.cc +++ b/chromium/content/browser/renderer_host/input/passthrough_touch_event_queue.cc @@ -156,6 +156,7 @@ void PassthroughTouchEventQueue::ProcessTouchAck( void PassthroughTouchEventQueue::OnGestureScrollEvent( const GestureEventWithLatencyInfo& gesture_event) { + // Turn events sent during gesture scrolls to be async. if (gesture_event.event.GetType() == blink::WebInputEvent::Type::kGestureScrollUpdate) { send_touch_events_async_ = true; @@ -165,11 +166,12 @@ void PassthroughTouchEventQueue::OnGestureScrollEvent( void PassthroughTouchEventQueue::OnGestureEventAck( const GestureEventWithLatencyInfo& event, blink::mojom::InputEventResultState ack_result) { - // Turn events sent during gesture scrolls to be async. - if (event.event.GetType() == - blink::WebInputEvent::Type::kGestureScrollUpdate) { - send_touch_events_async_ = - (ack_result == blink::mojom::InputEventResultState::kConsumed); + // When the scroll finishes allow TouchEvents to be blocking again. + if (event.event.GetType() == blink::WebInputEvent::Type::kGestureScrollEnd) { + send_touch_events_async_ = false; + } else if (event.event.GetType() == + blink::WebInputEvent::Type::kGestureScrollUpdate) { + send_touch_events_async_ = true; } } diff --git a/chromium/content/browser/renderer_host/input/passthrough_touch_event_queue_unittest.cc b/chromium/content/browser/renderer_host/input/passthrough_touch_event_queue_unittest.cc index b4c2e2df629..7f67166e2bf 100644 --- a/chromium/content/browser/renderer_host/input/passthrough_touch_event_queue_unittest.cc +++ b/chromium/content/browser/renderer_host/input/passthrough_touch_event_queue_unittest.cc @@ -19,13 +19,14 @@ #include "base/test/task_environment.h" #include "base/threading/thread_task_runner_handle.h" #include "content/browser/renderer_host/input/timeout_monitor.h" -#include "content/common/input/synthetic_web_input_event_builders.h" #include "content/common/input/web_touch_event_traits.h" #include "content/public/common/content_features.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/common/input/synthetic_web_input_event_builders.h" #include "third_party/blink/public/common/input/web_input_event.h" #include "ui/events/base_event_utils.h" +using blink::SyntheticWebTouchEvent; using blink::WebGestureEvent; using blink::WebInputEvent; using blink::WebTouchEvent; diff --git a/chromium/content/browser/renderer_host/input/render_widget_host_latency_tracker.cc b/chromium/content/browser/renderer_host/input/render_widget_host_latency_tracker.cc index 341e7a7d2dc..dd3766c4406 100644 --- a/chromium/content/browser/renderer_host/input/render_widget_host_latency_tracker.cc +++ b/chromium/content/browser/renderer_host/input/render_widget_host_latency_tracker.cc @@ -90,72 +90,6 @@ RenderWidgetHostLatencyTracker::RenderWidgetHostLatencyTracker( RenderWidgetHostLatencyTracker::~RenderWidgetHostLatencyTracker() {} -void RenderWidgetHostLatencyTracker::ComputeInputLatencyHistograms( - WebInputEvent::Type type, - const LatencyInfo& latency, - blink::mojom::InputEventResultState ack_result, - base::TimeTicks ack_timestamp) { - DCHECK(!ack_timestamp.is_null()); - // If this event was coalesced into another event, ignore it, as the event it - // was coalesced into will reflect the full latency. - if (latency.coalesced()) - return; - - if (latency.source_event_type() == ui::SourceEventType::UNKNOWN || - latency.source_event_type() == ui::SourceEventType::OTHER) { - return; - } - - // The event will have gone through OnInputEvent(). So the BEGIN_RWH component - // should always be available here. - base::TimeTicks rwh_timestamp; - bool found_component = latency.FindLatency( - ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, &rwh_timestamp); - DCHECK(found_component); - - bool multi_finger_touch_gesture = - WebInputEvent::IsTouchEventType(type) && active_multi_finger_gesture_; - - bool action_prevented = - ack_result == blink::mojom::InputEventResultState::kConsumed; - // Touchscreen tap and scroll gestures depend on the disposition of the touch - // start and the current touch. For touch start, - // touch_start_default_prevented_ == (ack_result == - // blink::mojom::InputEventResultState::kConsumed). - if (WebInputEvent::IsTouchEventType(type)) - action_prevented |= touch_start_default_prevented_; - - std::string event_name = WebInputEvent::GetName(type); - - if (latency.source_event_type() == ui::SourceEventType::KEY_PRESS) { - event_name = "KeyPress"; - } else if (event_name != "TouchEnd" && event_name != "TouchMove" && - event_name != "TouchStart") { - // Only log events we care about (that are documented in histograms.xml), - // to avoid using memory and bandwidth for metrics that are not important. - return; - } - - std::string default_action_status = - action_prevented ? "DefaultPrevented" : "DefaultAllowed"; - - base::TimeTicks main_thread_timestamp; - if (latency.FindLatency(ui::INPUT_EVENT_LATENCY_RENDERER_MAIN_COMPONENT, - &main_thread_timestamp)) { - if (!multi_finger_touch_gesture) { - UMA_HISTOGRAM_INPUT_LATENCY_MILLISECONDS( - "Event.Latency.QueueingTime." + event_name + default_action_status, - rwh_timestamp, main_thread_timestamp); - } - } - - if (!multi_finger_touch_gesture && !main_thread_timestamp.is_null()) { - UMA_HISTOGRAM_INPUT_LATENCY_MILLISECONDS( - "Event.Latency.BlockingTime." + event_name + default_action_status, - main_thread_timestamp, ack_timestamp); - } -} - void RenderWidgetHostLatencyTracker::OnInputEvent( const blink::WebInputEvent& event, LatencyInfo* latency) { @@ -270,9 +204,6 @@ void RenderWidgetHostLatencyTracker::OnInputEventAck( ack_result == blink::mojom::InputEventResultState::kNoConsumerExists)) { latency->Terminate(); } - - ComputeInputLatencyHistograms(event.GetType(), *latency, ack_result, - base::TimeTicks::Now()); } void RenderWidgetHostLatencyTracker::OnEventStart(ui::LatencyInfo* latency) { diff --git a/chromium/content/browser/renderer_host/input/render_widget_host_latency_tracker.h b/chromium/content/browser/renderer_host/input/render_widget_host_latency_tracker.h index 5c88d696eea..e2528c10fb2 100644 --- a/chromium/content/browser/renderer_host/input/render_widget_host_latency_tracker.h +++ b/chromium/content/browser/renderer_host/input/render_widget_host_latency_tracker.h @@ -27,12 +27,6 @@ class CONTENT_EXPORT RenderWidgetHostLatencyTracker { explicit RenderWidgetHostLatencyTracker(RenderWidgetHostDelegate* delegate); virtual ~RenderWidgetHostLatencyTracker(); - void ComputeInputLatencyHistograms( - blink::WebInputEvent::Type type, - const ui::LatencyInfo& latency, - blink::mojom::InputEventResultState ack_result, - base::TimeTicks ack_timestamp); - // Populates the LatencyInfo with relevant entries for latency tracking. // Called when an event is received by the RenderWidgetHost, prior to // that event being forwarded to the renderer (via the InputRouter). diff --git a/chromium/content/browser/renderer_host/input/render_widget_host_latency_tracker_unittest.cc b/chromium/content/browser/renderer_host/input/render_widget_host_latency_tracker_unittest.cc index 64308c5f3db..574220301fa 100644 --- a/chromium/content/browser/renderer_host/input/render_widget_host_latency_tracker_unittest.cc +++ b/chromium/content/browser/renderer_host/input/render_widget_host_latency_tracker_unittest.cc @@ -12,7 +12,6 @@ #include "build/build_config.h" #include "components/ukm/test_ukm_recorder.h" #include "content/browser/web_contents/web_contents_impl.h" -#include "content/common/input/synthetic_web_input_event_builders.h" #include "content/public/browser/native_web_keyboard_event.h" #include "content/public/common/content_client.h" #include "content/test/test_content_browser_client.h" @@ -21,6 +20,8 @@ #include "services/metrics/public/cpp/ukm_source.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/common/input/synthetic_web_input_event_builders.h" +#include "ui/events/base_event_utils.h" using base::Bucket; using blink::WebInputEvent; @@ -190,7 +191,7 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, TestValidEventTiming) { latency_info.AddLatencyNumberWithTimestamp( ui::INPUT_EVENT_LATENCY_FRAME_SWAP_COMPONENT, now); - viz_tracker()->OnGpuSwapBuffersCompleted(latency_info); + viz_tracker()->OnGpuSwapBuffersCompleted({latency_info}); // When last_event_time of the end_component is less than the first_event_time // of the start_component, zero is recorded instead of a negative value. @@ -232,7 +233,7 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, for (bool rendering_on_main : {false, true}) { ResetHistograms(); { - auto wheel = SyntheticWebMouseWheelEventBuilder::Build( + auto wheel = blink::SyntheticWebMouseWheelEventBuilder::Build( blink::WebMouseWheelEvent::kPhaseChanged); base::TimeTicks now = base::TimeTicks::Now(); wheel.SetTimeStamp(now); @@ -249,7 +250,7 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, tracker()->OnInputEventAck( wheel, &wheel_latency, blink::mojom::InputEventResultState::kNotConsumed); - viz_tracker()->OnGpuSwapBuffersCompleted(wheel_latency); + viz_tracker()->OnGpuSwapBuffersCompleted({wheel_latency}); // UKM metrics. total_ukm_entry_count++; @@ -346,7 +347,7 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, MAYBE_TestWheelToScrollHistograms) { for (bool rendering_on_main : {false, true}) { ResetHistograms(); { - auto wheel = SyntheticWebMouseWheelEventBuilder::Build( + auto wheel = blink::SyntheticWebMouseWheelEventBuilder::Build( blink::WebMouseWheelEvent::kPhaseChanged); base::TimeTicks now = base::TimeTicks::Now(); wheel.SetTimeStamp(now); @@ -363,7 +364,7 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, MAYBE_TestWheelToScrollHistograms) { tracker()->OnInputEventAck( wheel, &wheel_latency, blink::mojom::InputEventResultState::kNotConsumed); - viz_tracker()->OnGpuSwapBuffersCompleted(wheel_latency); + viz_tracker()->OnGpuSwapBuffersCompleted({wheel_latency}); // UKM metrics. total_ukm_entry_count++; @@ -458,7 +459,7 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, for (bool rendering_on_main : {false, true}) { ResetHistograms(); { - auto scroll = SyntheticWebGestureEventBuilder::BuildScrollUpdate( + auto scroll = blink::SyntheticWebGestureEventBuilder::BuildScrollUpdate( 5.f, -5.f, 0, blink::WebGestureDevice::kTouchscreen); base::TimeTicks now = base::TimeTicks::Now(); scroll.SetTimeStamp(now); @@ -473,7 +474,7 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, tracker()->OnInputEventAck( scroll, &scroll_latency, blink::mojom::InputEventResultState::kNotConsumed); - viz_tracker()->OnGpuSwapBuffersCompleted(scroll_latency); + viz_tracker()->OnGpuSwapBuffersCompleted({scroll_latency}); } // UMA histograms. @@ -524,7 +525,7 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, for (bool rendering_on_main : {false, true}) { ResetHistograms(); { - auto scroll = SyntheticWebGestureEventBuilder::BuildScrollUpdate( + auto scroll = blink::SyntheticWebGestureEventBuilder::BuildScrollUpdate( 5.f, -5.f, 0, blink::WebGestureDevice::kTouchscreen); base::TimeTicks now = base::TimeTicks::Now(); scroll.SetTimeStamp(now); @@ -542,7 +543,7 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, } { - SyntheticWebTouchEvent touch; + blink::SyntheticWebTouchEvent touch; touch.PressPoint(0, 0); touch.PressPoint(1, 1); ui::LatencyInfo touch_latency(ui::SourceEventType::TOUCH); @@ -561,7 +562,7 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, tracker()->OnInputEventAck( touch, &touch_latency, blink::mojom::InputEventResultState::kNotConsumed); - viz_tracker()->OnGpuSwapBuffersCompleted(touch_latency); + viz_tracker()->OnGpuSwapBuffersCompleted({touch_latency}); } // UKM metrics. @@ -643,7 +644,7 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, MAYBE_TestTouchToScrollHistograms) { for (bool rendering_on_main : {false, true}) { ResetHistograms(); { - auto scroll = SyntheticWebGestureEventBuilder::BuildScrollUpdate( + auto scroll = blink::SyntheticWebGestureEventBuilder::BuildScrollUpdate( 5.f, -5.f, 0, blink::WebGestureDevice::kTouchscreen); base::TimeTicks now = base::TimeTicks::Now(); scroll.SetTimeStamp(now); @@ -661,7 +662,7 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, MAYBE_TestTouchToScrollHistograms) { } { - SyntheticWebTouchEvent touch; + blink::SyntheticWebTouchEvent touch; touch.PressPoint(0, 0); touch.PressPoint(1, 1); ui::LatencyInfo touch_latency(ui::SourceEventType::TOUCH); @@ -680,7 +681,7 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, MAYBE_TestTouchToScrollHistograms) { tracker()->OnInputEventAck( touch, &touch_latency, blink::mojom::InputEventResultState::kNotConsumed); - viz_tracker()->OnGpuSwapBuffersCompleted(touch_latency); + viz_tracker()->OnGpuSwapBuffersCompleted({touch_latency}); } // UKM metrics. @@ -756,7 +757,7 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, MAYBE_ScrollbarEndToEndHistograms) { contents()->NavigateAndCommit(url); ResetHistograms(); { - auto mouse_move = SyntheticWebMouseEventBuilder::Build( + auto mouse_move = blink::SyntheticWebMouseEventBuilder::Build( blink::WebMouseEvent::Type::kMouseMove); base::TimeTicks now = base::TimeTicks::Now(); @@ -779,7 +780,7 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, MAYBE_ScrollbarEndToEndHistograms) { tracker()->OnInputEventAck( mouse_move, &scrollbar_latency, blink::mojom::InputEventResultState::kNotConsumed); - viz_tracker()->OnGpuSwapBuffersCompleted(scrollbar_latency); + viz_tracker()->OnGpuSwapBuffersCompleted({scrollbar_latency}); } } } @@ -811,7 +812,7 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, MAYBE_ScrollbarEndToEndHistograms) { TEST_F(RenderWidgetHostLatencyTrackerTest, LatencyTerminatedOnAckIfRenderingNotScheduled) { { - auto scroll = SyntheticWebGestureEventBuilder::BuildScrollBegin( + auto scroll = blink::SyntheticWebGestureEventBuilder::BuildScrollBegin( 5.f, -5.f, blink::WebGestureDevice::kTouchscreen); ui::LatencyInfo scroll_latency; AddFakeComponents(*tracker(), &scroll_latency); @@ -825,7 +826,7 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, } { - auto wheel = SyntheticWebMouseWheelEventBuilder::Build( + auto wheel = blink::SyntheticWebMouseWheelEventBuilder::Build( blink::WebMouseWheelEvent::kPhaseChanged); ui::LatencyInfo wheel_latency; wheel_latency.set_source_event_type(ui::SourceEventType::WHEEL); @@ -838,7 +839,7 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, } { - SyntheticWebTouchEvent touch; + blink::SyntheticWebTouchEvent touch; touch.PressPoint(0, 0); ui::LatencyInfo touch_latency; touch_latency.set_source_event_type(ui::SourceEventType::TOUCH); @@ -851,7 +852,7 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, } { - auto mouse_move = SyntheticWebMouseEventBuilder::Build( + auto mouse_move = blink::SyntheticWebMouseEventBuilder::Build( blink::WebMouseEvent::Type::kMouseMove); ui::LatencyInfo mouse_latency; AddFakeComponents(*tracker(), &mouse_latency); @@ -863,8 +864,10 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, } { - auto key_event = SyntheticWebKeyboardEventBuilder::Build( - blink::WebKeyboardEvent::Type::kChar); + auto key_event = blink::WebKeyboardEvent( + blink::WebKeyboardEvent::Type::kChar, WebInputEvent::kNoModifiers, + ui::EventTimeForNow()); + key_event.windows_key_code = ui::VKEY_L; // non-null made up value. ui::LatencyInfo key_latency; key_latency.set_source_event_type(ui::SourceEventType::KEY_PRESS); AddFakeComponents(*tracker(), &key_latency); @@ -895,7 +898,7 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, LatencyTerminatedOnAckIfGSUIgnored) { {blink::WebGestureDevice::kTouchscreen, blink::WebGestureDevice::kTouchpad}) { for (bool rendering_on_main : {false, true}) { - auto scroll = SyntheticWebGestureEventBuilder::BuildScrollUpdate( + auto scroll = blink::SyntheticWebGestureEventBuilder::BuildScrollUpdate( 5.f, -5.f, 0, source_device); base::TimeTicks now = base::TimeTicks::Now(); scroll.SetTimeStamp(now); @@ -916,7 +919,7 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, LatencyTerminatedOnAckIfGSUIgnored) { } TEST_F(RenderWidgetHostLatencyTrackerTest, ScrollLatency) { - auto scroll_begin = SyntheticWebGestureEventBuilder::BuildScrollBegin( + auto scroll_begin = blink::SyntheticWebGestureEventBuilder::BuildScrollBegin( 5, -5, blink::WebGestureDevice::kTouchscreen); ui::LatencyInfo scroll_latency; scroll_latency.AddLatencyNumber(ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT); @@ -927,8 +930,9 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, ScrollLatency) { // The first GestureScrollUpdate should be provided with // INPUT_EVENT_LATENCY_FIRST_SCROLL_UPDATE_ORIGINAL_COMPONENT. - auto first_scroll_update = SyntheticWebGestureEventBuilder::BuildScrollUpdate( - 5.f, -5.f, 0, blink::WebGestureDevice::kTouchscreen); + auto first_scroll_update = + blink::SyntheticWebGestureEventBuilder::BuildScrollUpdate( + 5.f, -5.f, 0, blink::WebGestureDevice::kTouchscreen); scroll_latency = ui::LatencyInfo(); scroll_latency.AddLatencyNumber(ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT); tracker()->OnInputEvent(first_scroll_update, &scroll_latency); @@ -944,8 +948,9 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, ScrollLatency) { // Subsequent GestureScrollUpdates should be provided with // INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL_COMPONENT. - auto scroll_update = SyntheticWebGestureEventBuilder::BuildScrollUpdate( - -5.f, 5.f, 0, blink::WebGestureDevice::kTouchscreen); + auto scroll_update = + blink::SyntheticWebGestureEventBuilder::BuildScrollUpdate( + -5.f, 5.f, 0, blink::WebGestureDevice::kTouchscreen); scroll_latency = ui::LatencyInfo(); scroll_latency.AddLatencyNumber(ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT); tracker()->OnInputEvent(scroll_update, &scroll_latency); @@ -960,241 +965,6 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, ScrollLatency) { EXPECT_EQ(4U, scroll_latency.latency_components().size()); } -TEST_F(RenderWidgetHostLatencyTrackerTest, TouchBlockingAndQueueingTime) { - // These numbers are sensitive to where the histogram buckets are. - int touchstart_timestamps_ms[] = {11, 25, 35}; - int touchmove_timestamps_ms[] = {1, 5, 12}; - int touchend_timestamps_ms[] = {3, 8, 12}; - - for (blink::mojom::InputEventResultState blocking : - {blink::mojom::InputEventResultState::kNotConsumed, - blink::mojom::InputEventResultState::kConsumed}) { - SyntheticWebTouchEvent event; - { - // Touch start. - event.PressPoint(1, 1); - - ui::LatencyInfo latency; - latency.set_source_event_type(ui::SourceEventType::TOUCH); - tracker()->OnInputEvent(event, &latency); - - ui::LatencyInfo fake_latency; - fake_latency.set_trace_id(kTraceEventId); - fake_latency.set_source_event_type(ui::SourceEventType::TOUCH); - fake_latency.AddLatencyNumberWithTimestamp( - ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, - base::TimeTicks() + - base::TimeDelta::FromMilliseconds(touchstart_timestamps_ms[0])); - - fake_latency.AddLatencyNumberWithTimestamp( - ui::INPUT_EVENT_LATENCY_RENDERER_MAIN_COMPONENT, - base::TimeTicks() + - base::TimeDelta::FromMilliseconds(touchstart_timestamps_ms[1])); - - auto ack_timestamp = - base::TimeTicks() + - base::TimeDelta::FromMilliseconds(touchstart_timestamps_ms[2]); - - // Call ComputeInputLatencyHistograms directly to avoid OnInputEventAck - // overwriting components. - tracker()->ComputeInputLatencyHistograms(event.GetType(), fake_latency, - blocking, ack_timestamp); - tracker()->OnInputEventAck(event, &latency, blocking); - } - - { - // Touch move. - ui::LatencyInfo latency; - latency.set_source_event_type(ui::SourceEventType::TOUCH); - event.MovePoint(0, 20, 20); - tracker()->OnInputEvent(event, &latency); - - EXPECT_TRUE(latency.FindLatency( - ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, nullptr)); - EXPECT_TRUE(latency.FindLatency( - ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, nullptr)); - - EXPECT_EQ(2U, latency.latency_components().size()); - - ui::LatencyInfo fake_latency; - fake_latency.set_trace_id(kTraceEventId); - fake_latency.set_source_event_type(ui::SourceEventType::TOUCH); - fake_latency.AddLatencyNumberWithTimestamp( - ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, - base::TimeTicks() + - base::TimeDelta::FromMilliseconds(touchmove_timestamps_ms[0])); - - fake_latency.AddLatencyNumberWithTimestamp( - ui::INPUT_EVENT_LATENCY_RENDERER_MAIN_COMPONENT, - base::TimeTicks() + - base::TimeDelta::FromMilliseconds(touchmove_timestamps_ms[1])); - - auto ack_timestamp = - base::TimeTicks() + - base::TimeDelta::FromMilliseconds(touchmove_timestamps_ms[2]); - - // Call ComputeInputLatencyHistograms directly to avoid OnInputEventAck - // overwriting components. - tracker()->ComputeInputLatencyHistograms(event.GetType(), fake_latency, - blocking, ack_timestamp); - } - - { - // Touch end. - ui::LatencyInfo latency; - latency.set_source_event_type(ui::SourceEventType::TOUCH); - event.ReleasePoint(0); - tracker()->OnInputEvent(event, &latency); - - EXPECT_TRUE(latency.FindLatency( - ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, nullptr)); - EXPECT_TRUE(latency.FindLatency( - ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, nullptr)); - - EXPECT_EQ(2U, latency.latency_components().size()); - - ui::LatencyInfo fake_latency; - fake_latency.set_trace_id(kTraceEventId); - fake_latency.set_source_event_type(ui::SourceEventType::TOUCH); - fake_latency.AddLatencyNumberWithTimestamp( - ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, - base::TimeTicks() + - base::TimeDelta::FromMilliseconds(touchend_timestamps_ms[0])); - - fake_latency.AddLatencyNumberWithTimestamp( - ui::INPUT_EVENT_LATENCY_RENDERER_MAIN_COMPONENT, - base::TimeTicks() + - base::TimeDelta::FromMilliseconds(touchend_timestamps_ms[1])); - - auto ack_timestamp = - base::TimeTicks() + - base::TimeDelta::FromMilliseconds(touchend_timestamps_ms[2]); - - // Call ComputeInputLatencyHistograms directly to avoid OnInputEventAck - // overwriting components. - tracker()->ComputeInputLatencyHistograms(event.GetType(), fake_latency, - blocking, ack_timestamp); - } - } - - // Touch start. - EXPECT_THAT( - histogram_tester().GetAllSamples( - "Event.Latency.QueueingTime.TouchStartDefaultPrevented"), - ElementsAre(Bucket( - touchstart_timestamps_ms[1] - touchstart_timestamps_ms[0], 1))); - EXPECT_THAT( - histogram_tester().GetAllSamples( - "Event.Latency.QueueingTime.TouchStartDefaultAllowed"), - ElementsAre(Bucket( - touchstart_timestamps_ms[1] - touchstart_timestamps_ms[0], 1))); - EXPECT_THAT( - histogram_tester().GetAllSamples( - "Event.Latency.BlockingTime.TouchStartDefaultPrevented"), - ElementsAre(Bucket( - touchstart_timestamps_ms[2] - touchstart_timestamps_ms[1], 1))); - EXPECT_THAT( - histogram_tester().GetAllSamples( - "Event.Latency.BlockingTime.TouchStartDefaultAllowed"), - ElementsAre(Bucket( - touchstart_timestamps_ms[2] - touchstart_timestamps_ms[1], 1))); - - // Touch move. - EXPECT_THAT(histogram_tester().GetAllSamples( - "Event.Latency.QueueingTime.TouchMoveDefaultPrevented"), - ElementsAre(Bucket( - touchmove_timestamps_ms[1] - touchmove_timestamps_ms[0], 1))); - EXPECT_THAT(histogram_tester().GetAllSamples( - "Event.Latency.QueueingTime.TouchMoveDefaultAllowed"), - ElementsAre(Bucket( - touchmove_timestamps_ms[1] - touchmove_timestamps_ms[0], 1))); - EXPECT_THAT(histogram_tester().GetAllSamples( - "Event.Latency.BlockingTime.TouchMoveDefaultPrevented"), - ElementsAre(Bucket( - touchmove_timestamps_ms[2] - touchmove_timestamps_ms[1], 1))); - EXPECT_THAT(histogram_tester().GetAllSamples( - "Event.Latency.BlockingTime.TouchMoveDefaultAllowed"), - ElementsAre(Bucket( - touchmove_timestamps_ms[2] - touchmove_timestamps_ms[1], 1))); - - // Touch end. - EXPECT_THAT(histogram_tester().GetAllSamples( - "Event.Latency.QueueingTime.TouchEndDefaultPrevented"), - ElementsAre(Bucket( - touchend_timestamps_ms[1] - touchend_timestamps_ms[0], 1))); - EXPECT_THAT(histogram_tester().GetAllSamples( - "Event.Latency.QueueingTime.TouchEndDefaultAllowed"), - ElementsAre(Bucket( - touchend_timestamps_ms[1] - touchend_timestamps_ms[0], 1))); - EXPECT_THAT(histogram_tester().GetAllSamples( - "Event.Latency.BlockingTime.TouchEndDefaultPrevented"), - ElementsAre(Bucket( - touchend_timestamps_ms[2] - touchend_timestamps_ms[1], 1))); - EXPECT_THAT(histogram_tester().GetAllSamples( - "Event.Latency.BlockingTime.TouchEndDefaultAllowed"), - ElementsAre(Bucket( - touchend_timestamps_ms[2] - touchend_timestamps_ms[1], 1))); -} - -TEST_F(RenderWidgetHostLatencyTrackerTest, KeyBlockingAndQueueingTime) { - // These numbers are sensitive to where the histogram buckets are. - int event_timestamps_ms[] = {11, 25, 35}; - - for (blink::mojom::InputEventResultState blocking : - {blink::mojom::InputEventResultState::kNotConsumed, - blink::mojom::InputEventResultState::kConsumed}) { - { - NativeWebKeyboardEvent event(blink::WebKeyboardEvent::Type::kRawKeyDown, - blink::WebInputEvent::kNoModifiers, - base::TimeTicks::Now()); - ui::LatencyInfo latency_info; - latency_info.set_source_event_type(ui::SourceEventType::KEY_PRESS); - tracker()->OnInputEvent(event, &latency_info); - - ui::LatencyInfo fake_latency; - fake_latency.set_trace_id(kTraceEventId); - fake_latency.set_source_event_type(ui::SourceEventType::KEY_PRESS); - fake_latency.AddLatencyNumberWithTimestamp( - ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, - base::TimeTicks() + - base::TimeDelta::FromMilliseconds(event_timestamps_ms[0])); - - fake_latency.AddLatencyNumberWithTimestamp( - ui::INPUT_EVENT_LATENCY_RENDERER_MAIN_COMPONENT, - base::TimeTicks() + - base::TimeDelta::FromMilliseconds(event_timestamps_ms[1])); - - auto ack_timestamp = - base::TimeTicks() + - base::TimeDelta::FromMilliseconds(event_timestamps_ms[2]); - - // Call ComputeInputLatencyHistograms directly to avoid OnInputEventAck - // overwriting components. - tracker()->ComputeInputLatencyHistograms(event.GetType(), fake_latency, - blocking, ack_timestamp); - - tracker()->OnInputEventAck(event, &latency_info, blocking); - } - } - - EXPECT_THAT( - histogram_tester().GetAllSamples( - "Event.Latency.QueueingTime.KeyPressDefaultPrevented"), - ElementsAre(Bucket(event_timestamps_ms[1] - event_timestamps_ms[0], 1))); - EXPECT_THAT( - histogram_tester().GetAllSamples( - "Event.Latency.QueueingTime.KeyPressDefaultAllowed"), - ElementsAre(Bucket(event_timestamps_ms[1] - event_timestamps_ms[0], 1))); - EXPECT_THAT( - histogram_tester().GetAllSamples( - "Event.Latency.BlockingTime.KeyPressDefaultPrevented"), - ElementsAre(Bucket(event_timestamps_ms[2] - event_timestamps_ms[1], 1))); - EXPECT_THAT( - histogram_tester().GetAllSamples( - "Event.Latency.BlockingTime.KeyPressDefaultAllowed"), - ElementsAre(Bucket(event_timestamps_ms[2] - event_timestamps_ms[1], 1))); -} - TEST_F(RenderWidgetHostLatencyTrackerTest, KeyEndToEndLatency) { // These numbers are sensitive to where the histogram buckets are. int event_timestamps_microseconds[] = {11, 24}; @@ -1222,7 +992,7 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, KeyEndToEndLatency) { base::TimeTicks() + base::TimeDelta::FromMicroseconds(event_timestamps_microseconds[1])); - viz_tracker()->OnGpuSwapBuffersCompleted(latency_info); + viz_tracker()->OnGpuSwapBuffersCompleted({latency_info}); EXPECT_THAT( histogram_tester().GetAllSamples("Event.Latency.EndToEnd.KeyPress"), @@ -1231,58 +1001,6 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, KeyEndToEndLatency) { 1))); } -// Event.Latency.(Queueing|Blocking)Time.* histograms shouldn't be reported for -// multi-finger touch. -TEST_F(RenderWidgetHostLatencyTrackerTest, - MultiFingerTouchIgnoredForQueueingAndBlockingTimeMetrics) { - SyntheticWebTouchEvent event; - blink::mojom::InputEventResultState ack_state = - blink::mojom::InputEventResultState::kNotConsumed; - - { - // First touch start. - ui::LatencyInfo latency; - event.PressPoint(1, 1); - tracker()->OnInputEvent(event, &latency); - tracker()->OnInputEventAck(event, &latency, ack_state); - } - - { - // Additional touch start will be ignored for queueing and blocking time - // metrics. - int touchstart_timestamps_ms[] = {11, 25, 35}; - ui::LatencyInfo latency; - event.PressPoint(1, 1); - tracker()->OnInputEvent(event, &latency); - - ui::LatencyInfo fake_latency; - fake_latency.set_trace_id(kTraceEventId); - fake_latency.AddLatencyNumberWithTimestamp( - ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, - base::TimeTicks() + - base::TimeDelta::FromMilliseconds(touchstart_timestamps_ms[0])); - - fake_latency.AddLatencyNumberWithTimestamp( - ui::INPUT_EVENT_LATENCY_RENDERER_MAIN_COMPONENT, - base::TimeTicks() + - base::TimeDelta::FromMilliseconds(touchstart_timestamps_ms[1])); - - auto ack_timestamp = base::TimeTicks() + base::TimeDelta::FromMilliseconds( - touchstart_timestamps_ms[2]); - - // Call ComputeInputLatencyHistograms directly to avoid OnInputEventAck - // overwriting components. - tracker()->ComputeInputLatencyHistograms(event.GetType(), fake_latency, - ack_state, ack_timestamp); - - tracker()->OnInputEventAck(event, &latency, ack_state); - } - - EXPECT_THAT(histogram_tester().GetAllSamples( - "Event.Latency.QueueingTime.TouchStartDefaultAllowed"), - ElementsAre()); -} - TEST_F(RenderWidgetHostLatencyTrackerTest, TouchpadPinchEvents) { ui::LatencyInfo latency; latency.set_trace_id(kTraceEventId); @@ -1296,7 +1014,7 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, TouchpadPinchEvents) { AddFakeComponentsWithTimeStamp( *tracker(), &latency, base::TimeTicks() + base::TimeDelta::FromMilliseconds(5)); - viz_tracker()->OnGpuSwapBuffersCompleted(latency); + viz_tracker()->OnGpuSwapBuffersCompleted({latency}); EXPECT_TRUE(HistogramSizeEq("Event.Latency.EventToRender.TouchpadPinch", 1)); EXPECT_TRUE(HistogramSizeEq("Event.Latency.EndToEnd.TouchpadPinch", 1)); diff --git a/chromium/content/browser/renderer_host/input/scroll_latency_browsertest.cc b/chromium/content/browser/renderer_host/input/scroll_latency_browsertest.cc index 4474ae7c66c..32aa02b70fa 100644 --- a/chromium/content/browser/renderer_host/input/scroll_latency_browsertest.cc +++ b/chromium/content/browser/renderer_host/input/scroll_latency_browsertest.cc @@ -28,6 +28,7 @@ #include "content/public/test/hit_test_region_observer.h" #include "content/shell/browser/shell.h" #include "third_party/blink/public/common/features.h" +#include "third_party/blink/public/common/input/synthetic_web_input_event_builders.h" #include "ui/base/ui_base_features.h" #include "ui/native_theme/native_theme_features.h" @@ -125,7 +126,7 @@ class ScrollLatencyBrowserTest : public ContentBrowserTest { // which support it. void DoSmoothWheelScroll(const gfx::Vector2d& distance) { blink::WebGestureEvent event = - SyntheticWebGestureEventBuilder::BuildScrollBegin( + blink::SyntheticWebGestureEventBuilder::BuildScrollBegin( distance.x(), -distance.y(), blink::WebGestureDevice::kTouchpad, 1); event.data.scroll_begin.delta_hint_units = ui::ScrollGranularity::kScrollByPixel; @@ -144,7 +145,7 @@ class ScrollLatencyBrowserTest : public ContentBrowserTest { base::Unretained(this))); blink::WebGestureEvent event2 = - SyntheticWebGestureEventBuilder::BuildScrollUpdate( + blink::SyntheticWebGestureEventBuilder::BuildScrollUpdate( distance.x(), -distance.y(), 0, blink::WebGestureDevice::kTouchpad); event2.data.scroll_update.delta_units = @@ -354,9 +355,10 @@ class ScrollLatencyScrollbarBrowserTest : public ScrollLatencyBrowserTest { // Click on the forward scrollbar button to induce a compositor thread // scrollbar scroll. gfx::PointF scrollbar_forward_button(795, 595); - blink::WebMouseEvent mouse_event = SyntheticWebMouseEventBuilder::Build( - blink::WebInputEvent::Type::kMouseDown, scrollbar_forward_button.x(), - scrollbar_forward_button.y(), 0); + blink::WebMouseEvent mouse_event = + blink::SyntheticWebMouseEventBuilder::Build( + blink::WebInputEvent::Type::kMouseDown, + scrollbar_forward_button.x(), scrollbar_forward_button.y(), 0); mouse_event.button = blink::WebMouseEvent::Button::kLeft; mouse_event.SetTimeStamp(base::TimeTicks::Now()); GetWidgetHost()->ForwardMouseEvent(mouse_event); @@ -395,9 +397,10 @@ class ScrollLatencyScrollbarBrowserTest : public ScrollLatencyBrowserTest { // Click on the scrollbar thumb and drag it twice to induce a compositor // thread scrollbar ScrollBegin and ScrollUpdate. gfx::PointF scrollbar_thumb(795, 30); - blink::WebMouseEvent mouse_down = SyntheticWebMouseEventBuilder::Build( - blink::WebInputEvent::Type::kMouseDown, scrollbar_thumb.x(), - scrollbar_thumb.y(), 0); + blink::WebMouseEvent mouse_down = + blink::SyntheticWebMouseEventBuilder::Build( + blink::WebInputEvent::Type::kMouseDown, scrollbar_thumb.x(), + scrollbar_thumb.y(), 0); mouse_down.button = blink::WebMouseEvent::Button::kLeft; mouse_down.SetTimeStamp(base::TimeTicks::Now()); GetWidgetHost()->ForwardMouseEvent(mouse_down); @@ -411,9 +414,10 @@ class ScrollLatencyScrollbarBrowserTest : public ScrollLatencyBrowserTest { // and this can lead to nullptr derefernces. RunUntilInputProcessed(GetWidgetHost()); - blink::WebMouseEvent mouse_move = SyntheticWebMouseEventBuilder::Build( - blink::WebInputEvent::Type::kMouseMove, scrollbar_thumb.x(), - scrollbar_thumb.y() + 10, 0); + blink::WebMouseEvent mouse_move = + blink::SyntheticWebMouseEventBuilder::Build( + blink::WebInputEvent::Type::kMouseMove, scrollbar_thumb.x(), + scrollbar_thumb.y() + 10, 0); mouse_move.button = blink::WebMouseEvent::Button::kLeft; mouse_move.SetTimeStamp(base::TimeTicks::Now()); GetWidgetHost()->ForwardMouseEvent(mouse_move); @@ -426,7 +430,7 @@ class ScrollLatencyScrollbarBrowserTest : public ScrollLatencyBrowserTest { GetWidgetHost()->ForwardMouseEvent(mouse_move); RunUntilInputProcessed(GetWidgetHost()); - blink::WebMouseEvent mouse_up = SyntheticWebMouseEventBuilder::Build( + blink::WebMouseEvent mouse_up = blink::SyntheticWebMouseEventBuilder::Build( blink::WebInputEvent::Type::kMouseUp, scrollbar_thumb.x(), scrollbar_thumb.y() + 20, 0); mouse_up.button = blink::WebMouseEvent::Button::kLeft; diff --git a/chromium/content/browser/renderer_host/input/synthetic_gesture_target_android.cc b/chromium/content/browser/renderer_host/input/synthetic_gesture_target_android.cc index a42e5b53dad..871e9ec34d8 100644 --- a/chromium/content/browser/renderer_host/input/synthetic_gesture_target_android.cc +++ b/chromium/content/browser/renderer_host/input/synthetic_gesture_target_android.cc @@ -38,8 +38,8 @@ SyntheticGestureTargetAndroid::SyntheticGestureTargetAndroid( SyntheticGestureTargetAndroid::~SyntheticGestureTargetAndroid() = default; void SyntheticGestureTargetAndroid::TouchSetPointer(int index, - int x, - int y, + float x, + float y, int id) { TRACE_EVENT0("input", "SyntheticGestureTargetAndroid::TouchSetPointer"); JNIEnv* env = base::android::AttachCurrentThread(); @@ -48,10 +48,10 @@ void SyntheticGestureTargetAndroid::TouchSetPointer(int index, env, java_ref_, index, x * scale_factor, y * scale_factor, id); } -void SyntheticGestureTargetAndroid::TouchSetScrollDeltas(int x, - int y, - int dx, - int dy) { +void SyntheticGestureTargetAndroid::TouchSetScrollDeltas(float x, + float y, + float dx, + float dy) { TRACE_EVENT0("input", "SyntheticGestureTargetAndroid::TouchSetScrollDeltas"); JNIEnv* env = base::android::AttachCurrentThread(); diff --git a/chromium/content/browser/renderer_host/input/synthetic_gesture_target_android.h b/chromium/content/browser/renderer_host/input/synthetic_gesture_target_android.h index 5f203ae19e4..6dbe2c79ae0 100644 --- a/chromium/content/browser/renderer_host/input/synthetic_gesture_target_android.h +++ b/chromium/content/browser/renderer_host/input/synthetic_gesture_target_android.h @@ -47,8 +47,8 @@ class SyntheticGestureTargetAndroid : public SyntheticGestureTargetBase { float GetMinScalingSpanInDips() const override; private: - void TouchSetPointer(int index, int x, int y, int id); - void TouchSetScrollDeltas(int x, int y, int dx, int dy); + void TouchSetPointer(int index, float x, float y, int id); + void TouchSetScrollDeltas(float x, float y, float dx, float dy); void TouchInject(MotionEventAction action, int pointer_count, base::TimeTicks time); diff --git a/chromium/content/browser/renderer_host/input/synthetic_gesture_target_aura.cc b/chromium/content/browser/renderer_host/input/synthetic_gesture_target_aura.cc index ac603a8a1c5..93a1bd66115 100644 --- a/chromium/content/browser/renderer_host/input/synthetic_gesture_target_aura.cc +++ b/chromium/content/browser/renderer_host/input/synthetic_gesture_target_aura.cc @@ -90,10 +90,13 @@ void SyntheticGestureTargetAura::DispatchWebMouseWheelEventToPlatform( modifiers |= ui::EF_SCROLL_BY_PAGE; } + float delta_x = web_wheel.delta_x + wheel_precision_x_; + float delta_y = web_wheel.delta_y + wheel_precision_y_; ui::MouseWheelEvent wheel_event( - gfx::Vector2d(web_wheel.delta_x, web_wheel.delta_y), - web_wheel.PositionInWidget(), web_wheel.PositionInWidget(), timestamp, - modifiers, ui::EF_NONE); + gfx::Vector2d(delta_x, delta_y), web_wheel.PositionInWidget(), + web_wheel.PositionInWidget(), timestamp, modifiers, ui::EF_NONE); + wheel_precision_x_ = delta_x - wheel_event.x_offset(); + wheel_precision_y_ = delta_y - wheel_event.y_offset(); aura::Window* window = GetWindow(); wheel_event.ConvertLocationToTarget(window, window->GetRootWindow()); @@ -170,7 +173,7 @@ void SyntheticGestureTargetAura::DispatchWebMouseEventToPlatform( SyntheticGestureParams::GestureSourceType SyntheticGestureTargetAura::GetDefaultSyntheticGestureSourceType() const { - return SyntheticGestureParams::TOUCH_INPUT; + return SyntheticGestureParams::MOUSE_INPUT; } float SyntheticGestureTargetAura::GetTouchSlopInDips() const { diff --git a/chromium/content/browser/renderer_host/input/synthetic_gesture_target_aura.h b/chromium/content/browser/renderer_host/input/synthetic_gesture_target_aura.h index 3117e31ac3f..75b7fa52744 100644 --- a/chromium/content/browser/renderer_host/input/synthetic_gesture_target_aura.h +++ b/chromium/content/browser/renderer_host/input/synthetic_gesture_target_aura.h @@ -58,6 +58,9 @@ class SyntheticGestureTargetAura : public SyntheticGestureTargetBase { // before dispatching it into platform. float device_scale_factor_; + float wheel_precision_x_ = 0.f; + float wheel_precision_y_ = 0.f; + aura::EventInjector event_injector_; DISALLOW_COPY_AND_ASSIGN(SyntheticGestureTargetAura); diff --git a/chromium/content/browser/renderer_host/input/synthetic_gesture_target_base.cc b/chromium/content/browser/renderer_host/input/synthetic_gesture_target_base.cc index 6a357327057..2a7866fd9e8 100644 --- a/chromium/content/browser/renderer_host/input/synthetic_gesture_target_base.cc +++ b/chromium/content/browser/renderer_host/input/synthetic_gesture_target_base.cc @@ -5,6 +5,7 @@ #include "content/browser/renderer_host/input/synthetic_gesture_target_base.h" #include "content/browser/renderer_host/render_widget_host_impl.h" +#include "content/browser/renderer_host/render_widget_host_input_event_router.h" #include "content/browser/renderer_host/render_widget_host_view_base.h" #include "content/browser/renderer_host/ui_events_helper.h" #include "content/common/input_messages.h" @@ -78,8 +79,16 @@ void SyntheticGestureTargetBase::DispatchInputEventToPlatform( // from the ui::MouseWheelEvent. ui::MouseWheelEvent does // not have a float value for delta, so that codepath ends up truncating. // So instead, dispatch the WebMouseWheelEvent directly through the - // RenderWidgetHostImpl. - host_->ForwardWheelEventWithLatencyInfo(web_wheel, latency_info); + // RenderWidgetHostInputEventRouter attached to the RenderWidgetHostImpl. + + DCHECK(host_->delegate()); + DCHECK(host_->delegate()->IsWidgetForMainFrame(host_)); + DCHECK(host_->delegate()->GetInputEventRouter()); + + std::unique_ptr<WebInputEvent> wheel_evt_ptr = web_wheel.Clone(); + host_->delegate()->GetInputEventRouter()->RouteMouseWheelEvent( + host_->GetView(), + static_cast<WebMouseWheelEvent*>(wheel_evt_ptr.get()), latency_info); } } else if (WebInputEvent::IsMouseEventType(event.GetType())) { const WebMouseEvent& web_mouse = diff --git a/chromium/content/browser/renderer_host/input/synthetic_input_browsertest.cc b/chromium/content/browser/renderer_host/input/synthetic_input_browsertest.cc index 39c9a8eda68..9a3c016fd6a 100644 --- a/chromium/content/browser/renderer_host/input/synthetic_input_browsertest.cc +++ b/chromium/content/browser/renderer_host/input/synthetic_input_browsertest.cc @@ -6,12 +6,12 @@ #include "base/callback.h" #include "base/run_loop.h" #include "base/test/test_timeouts.h" +#include "build/build_config.h" #include "cc/base/switches.h" #include "content/browser/renderer_host/input/synthetic_gesture.h" #include "content/browser/renderer_host/input/synthetic_smooth_scroll_gesture.h" #include "content/browser/renderer_host/render_widget_host_impl.h" #include "content/browser/web_contents/web_contents_impl.h" -#include "content/common/input/input_event.h" #include "content/common/input/synthetic_gesture_params.h" #include "content/common/input/synthetic_smooth_scroll_gesture_params.h" #include "content/public/browser/render_view_host.h" @@ -93,9 +93,10 @@ IN_PROC_BROWSER_TEST_F(SyntheticInputTest, DestroyWidgetWithOngoingGesture) { // By starting a gesture, there's a Mojo callback that the renderer is // waiting on the browser to resolve. If the browser is shutdown before // ACKing the callback or closing the channel, we'll DCHECK. - ASSERT_TRUE(ExecJs(shell()->web_contents(), - "chrome.gpuBenchmarking.smoothScrollBy(10000, ()=>{}, " - "100, 100, chrome.gpuBenchmarking.TOUCH_INPUT);")); + ASSERT_TRUE( + ExecJs(shell()->web_contents(), + "chrome.gpuBenchmarking.smoothScrollByXY(0, 10000, ()=>{}, " + "100, 100, chrome.gpuBenchmarking.TOUCH_INPUT);")); while (!gesture_observer.HasSeenGestureScrollBegin()) { base::RunLoop run_loop; @@ -134,7 +135,7 @@ IN_PROC_BROWSER_TEST_F(SyntheticInputTest, SmoothScrollWheel) { // Use a speed that's fast enough that the entire scroll occurs in a single // GSU, avoiding precision loss. SyntheticGestures can lose delta over time - // in slower scrolls. + // in slower scrolls on some platforms. params.speed_in_pixels_s = 10000000.f; // Use PrecisePixel to avoid animating. @@ -157,4 +158,57 @@ IN_PROC_BROWSER_TEST_F(SyntheticInputTest, SmoothScrollWheel) { "document.scrollingElement.scrollTop")); } +// This test ensures that slow synthetic wheel scrolling does not lose precision +// over time. +IN_PROC_BROWSER_TEST_F(SyntheticInputTest, SlowSmoothScrollWheel) { + LoadURL(R"HTML( + data:text/html;charset=utf-8, + <!DOCTYPE html> + <meta name='viewport' content='width=device-width'> + <style> + body { + width: 10px; + height: 2000px; + } + </style> + <script> + document.title = 'ready'; + </script> + )HTML"); + + SyntheticSmoothScrollGestureParams params; + params.gesture_source_type = SyntheticGestureParams::MOUSE_INPUT; + params.anchor = gfx::PointF(1, 1); + + // Note: 1024 is precisely chosen since Android's minimum granularity is 64px. + // All other platforms can specify the delta per-pixel. + params.distances.push_back(gfx::Vector2d(0, -1024)); + + // Use a speed that's slow enough that it requires the browser to require + // multiple wheel-events to be dispatched, so that precision is needed to + // scroll the correct amount. + params.speed_in_pixels_s = 1000.f; + + // Use PrecisePixel to avoid animating. + params.granularity = ui::ScrollGranularity::kScrollByPrecisePixel; + + runner_ = std::make_unique<base::RunLoop>(); + + auto* web_contents = shell()->web_contents(); + RenderFrameSubmissionObserver scroll_offset_wait(web_contents); + std::unique_ptr<SyntheticSmoothScrollGesture> gesture( + new SyntheticSmoothScrollGesture(params)); + GetRenderWidgetHost()->QueueSyntheticGesture( + std::move(gesture), + base::BindOnce(&SyntheticInputTest::OnSyntheticGestureCompleted, + base::Unretained(this))); + float device_scale_factor = + web_contents->GetRenderWidgetHostView()->GetDeviceScaleFactor(); + scroll_offset_wait.WaitForScrollOffset( + gfx::Vector2dF(0.f, 1024.f * device_scale_factor)); + + EXPECT_EQ(1024, EvalJs(shell()->web_contents(), + "document.scrollingElement.scrollTop")); +} + } // namespace content diff --git a/chromium/content/browser/renderer_host/input/synthetic_mouse_driver.cc b/chromium/content/browser/renderer_host/input/synthetic_mouse_driver.cc index 44772997cfd..f8a4a16e8c2 100644 --- a/chromium/content/browser/renderer_host/input/synthetic_mouse_driver.cc +++ b/chromium/content/browser/renderer_host/input/synthetic_mouse_driver.cc @@ -5,6 +5,7 @@ #include "content/browser/renderer_host/input/synthetic_mouse_driver.h" #include "content/browser/renderer_host/input/synthetic_gesture_target.h" +#include "third_party/blink/public/common/input/synthetic_web_input_event_builders.h" namespace content { @@ -36,7 +37,7 @@ void SyntheticMouseDriver::Press(float x, DCHECK_EQ(index, 0); int modifiers = SyntheticPointerActionParams::GetWebMouseEventModifier(button); - mouse_event_ = SyntheticWebMouseEventBuilder::Build( + mouse_event_ = blink::SyntheticWebMouseEventBuilder::Build( blink::WebInputEvent::Type::kMouseDown, x, y, modifiers | key_modifiers | last_modifiers_, mouse_event_.pointer_type); mouse_event_.button = @@ -59,7 +60,7 @@ void SyntheticMouseDriver::Move(float x, float rotation_angle, float force) { DCHECK_EQ(index, 0); - mouse_event_ = SyntheticWebMouseEventBuilder::Build( + mouse_event_ = blink::SyntheticWebMouseEventBuilder::Build( blink::WebInputEvent::Type::kMouseMove, x, y, key_modifiers | last_modifiers_, mouse_event_.pointer_type); mouse_event_.button = @@ -72,7 +73,7 @@ void SyntheticMouseDriver::Release(int index, SyntheticPointerActionParams::Button button, int key_modifiers) { DCHECK_EQ(index, 0); - mouse_event_ = SyntheticWebMouseEventBuilder::Build( + mouse_event_ = blink::SyntheticWebMouseEventBuilder::Build( blink::WebInputEvent::Type::kMouseUp, mouse_event_.PositionInWidget().x(), mouse_event_.PositionInWidget().y(), key_modifiers | last_modifiers_, mouse_event_.pointer_type); diff --git a/chromium/content/browser/renderer_host/input/synthetic_mouse_driver.h b/chromium/content/browser/renderer_host/input/synthetic_mouse_driver.h index c08be40af11..145323f6f93 100644 --- a/chromium/content/browser/renderer_host/input/synthetic_mouse_driver.h +++ b/chromium/content/browser/renderer_host/input/synthetic_mouse_driver.h @@ -8,7 +8,6 @@ #include "base/macros.h" #include "content/browser/renderer_host/input/synthetic_pointer_driver.h" #include "content/common/content_export.h" -#include "content/common/input/synthetic_web_input_event_builders.h" namespace content { diff --git a/chromium/content/browser/renderer_host/input/synthetic_pen_driver.cc b/chromium/content/browser/renderer_host/input/synthetic_pen_driver.cc index d848fe89f82..1733681fc74 100644 --- a/chromium/content/browser/renderer_host/input/synthetic_pen_driver.cc +++ b/chromium/content/browser/renderer_host/input/synthetic_pen_driver.cc @@ -4,6 +4,8 @@ #include "content/browser/renderer_host/input/synthetic_pen_driver.h" +#include "third_party/blink/public/common/input/synthetic_web_input_event_builders.h" + namespace content { SyntheticPenDriver::SyntheticPenDriver() : SyntheticMouseDriver() { @@ -14,7 +16,7 @@ SyntheticPenDriver::~SyntheticPenDriver() {} void SyntheticPenDriver::Leave(int index) { DCHECK_EQ(index, 0); - mouse_event_ = SyntheticWebMouseEventBuilder::Build( + mouse_event_ = blink::SyntheticWebMouseEventBuilder::Build( blink::WebInputEvent::Type::kMouseLeave, mouse_event_.PositionInWidget().x(), mouse_event_.PositionInWidget().y(), last_modifiers_, mouse_event_.pointer_type); diff --git a/chromium/content/browser/renderer_host/input/synthetic_pointer_driver.h b/chromium/content/browser/renderer_host/input/synthetic_pointer_driver.h index 197489dc90e..94b3cf0f372 100644 --- a/chromium/content/browser/renderer_host/input/synthetic_pointer_driver.h +++ b/chromium/content/browser/renderer_host/input/synthetic_pointer_driver.h @@ -11,7 +11,6 @@ #include "content/common/content_export.h" #include "content/common/input/synthetic_gesture_params.h" #include "content/common/input/synthetic_pointer_action_params.h" -#include "content/common/input/synthetic_web_input_event_builders.h" namespace content { diff --git a/chromium/content/browser/renderer_host/input/synthetic_smooth_move_gesture.cc b/chromium/content/browser/renderer_host/input/synthetic_smooth_move_gesture.cc index e44ed3e504b..2216d73704c 100644 --- a/chromium/content/browser/renderer_host/input/synthetic_smooth_move_gesture.cc +++ b/chromium/content/browser/renderer_host/input/synthetic_smooth_move_gesture.cc @@ -8,6 +8,7 @@ #include "base/check_op.h" #include "base/notreached.h" +#include "third_party/blink/public/common/input/synthetic_web_input_event_builders.h" #include "ui/gfx/geometry/point_f.h" namespace content { @@ -172,23 +173,6 @@ void SyntheticSmoothMoveGesture::ForwardMouseWheelInputEvents( base::TimeTicks event_timestamp = ClampTimestamp(timestamp); gfx::Vector2dF delta = GetPositionDeltaAtTime(event_timestamp) - current_move_segment_total_delta_; - - // Android MotionEvents that carry mouse wheel ticks and the tick - // granularity. Since it's not easy to change this granularity, it means - // we can only scroll in terms of number of these ticks. Note also: if - // the delta is smaller than one tick size we wont send an event or - // accumulate it in current_move_segment_total_delta_ so that we don't - // consider that delta applied. If we did, slow scrolls would be entirely - // lost since we'd send 0 ticks in each event but assume delta was - // applied. - int pixels_per_wheel_tick = target->GetMouseWheelMinimumGranularity(); - if (pixels_per_wheel_tick) { - int wheel_ticks_x = static_cast<int>(delta.x() / pixels_per_wheel_tick); - int wheel_ticks_y = static_cast<int>(delta.y() / pixels_per_wheel_tick); - delta = gfx::Vector2dF(wheel_ticks_x * pixels_per_wheel_tick, - wheel_ticks_y * pixels_per_wheel_tick); - } - if (delta.x() || delta.y()) { blink::WebMouseWheelEvent::Phase phase = needs_scroll_begin_ ? blink::WebMouseWheelEvent::kPhaseBegan @@ -287,7 +271,7 @@ void SyntheticSmoothMoveGesture::ForwardMouseWheelEvent( const base::TimeTicks& timestamp, int key_modifiers) const { blink::WebMouseWheelEvent mouse_wheel_event = - SyntheticWebMouseWheelEventBuilder::Build( + blink::SyntheticWebMouseWheelEventBuilder::Build( 0, 0, delta.x(), delta.y(), key_modifiers, params_.granularity); mouse_wheel_event.SetPositionInWidget( @@ -304,7 +288,7 @@ void SyntheticSmoothMoveGesture::ForwardFlingGestureEvent( SyntheticGestureTarget* target, const blink::WebInputEvent::Type type) const { blink::WebGestureEvent fling_gesture_event = - SyntheticWebGestureEventBuilder::Build( + blink::SyntheticWebGestureEventBuilder::Build( type, blink::WebGestureDevice::kTouchpad); fling_gesture_event.data.fling_start.velocity_x = params_.fling_velocity_x; fling_gesture_event.data.fling_start.velocity_y = params_.fling_velocity_y; diff --git a/chromium/content/browser/renderer_host/input/synthetic_smooth_move_gesture.h b/chromium/content/browser/renderer_host/input/synthetic_smooth_move_gesture.h index 3781656327b..7161ee78e43 100644 --- a/chromium/content/browser/renderer_host/input/synthetic_smooth_move_gesture.h +++ b/chromium/content/browser/renderer_host/input/synthetic_smooth_move_gesture.h @@ -16,6 +16,7 @@ #include "content/common/input/synthetic_smooth_drag_gesture_params.h" #include "content/common/input/synthetic_smooth_scroll_gesture_params.h" #include "third_party/blink/public/common/input/web_input_event.h" +#include "third_party/blink/public/common/input/web_mouse_wheel_event.h" #include "ui/events/types/scroll_types.h" #include "ui/gfx/geometry/vector2d.h" #include "ui/gfx/geometry/vector2d_f.h" diff --git a/chromium/content/browser/renderer_host/input/synthetic_tap_gesture.cc b/chromium/content/browser/renderer_host/input/synthetic_tap_gesture.cc index ff92b5de359..8f790c52911 100644 --- a/chromium/content/browser/renderer_host/input/synthetic_tap_gesture.cc +++ b/chromium/content/browser/renderer_host/input/synthetic_tap_gesture.cc @@ -17,6 +17,8 @@ SyntheticTapGesture::SyntheticTapGesture( gesture_source_type_(SyntheticGestureParams::DEFAULT_INPUT), state_(SETUP) { DCHECK_GE(params_.duration_ms, 0); + if (params_.gesture_source_type == SyntheticGestureParams::DEFAULT_INPUT) + params_.gesture_source_type = SyntheticGestureParams::TOUCH_INPUT; } SyntheticTapGesture::~SyntheticTapGesture() {} diff --git a/chromium/content/browser/renderer_host/input/synthetic_touch_driver.cc b/chromium/content/browser/renderer_host/input/synthetic_touch_driver.cc index d8f8becfd07..4cacab90cc2 100644 --- a/chromium/content/browser/renderer_host/input/synthetic_touch_driver.cc +++ b/chromium/content/browser/renderer_host/input/synthetic_touch_driver.cc @@ -10,7 +10,8 @@ namespace content { SyntheticTouchDriver::SyntheticTouchDriver() {} -SyntheticTouchDriver::SyntheticTouchDriver(SyntheticWebTouchEvent touch_event) +SyntheticTouchDriver::SyntheticTouchDriver( + blink::SyntheticWebTouchEvent touch_event) : touch_event_(touch_event) {} SyntheticTouchDriver::~SyntheticTouchDriver() {} diff --git a/chromium/content/browser/renderer_host/input/synthetic_touch_driver.h b/chromium/content/browser/renderer_host/input/synthetic_touch_driver.h index 40445caad92..279134eccf3 100644 --- a/chromium/content/browser/renderer_host/input/synthetic_touch_driver.h +++ b/chromium/content/browser/renderer_host/input/synthetic_touch_driver.h @@ -9,14 +9,14 @@ #include "base/macros.h" #include "content/browser/renderer_host/input/synthetic_pointer_driver.h" #include "content/common/content_export.h" -#include "content/common/input/synthetic_web_input_event_builders.h" +#include "third_party/blink/public/common/input/synthetic_web_input_event_builders.h" namespace content { class CONTENT_EXPORT SyntheticTouchDriver : public SyntheticPointerDriver { public: SyntheticTouchDriver(); - explicit SyntheticTouchDriver(SyntheticWebTouchEvent touch_event); + explicit SyntheticTouchDriver(blink::SyntheticWebTouchEvent touch_event); ~SyntheticTouchDriver() override; void DispatchEvent(SyntheticGestureTarget* target, @@ -61,7 +61,7 @@ class CONTENT_EXPORT SyntheticTouchDriver : public SyntheticPointerDriver { void ResetPointerIdIndexMap(); int GetIndexFromMap(int value) const; - SyntheticWebTouchEvent touch_event_; + blink::SyntheticWebTouchEvent touch_event_; PointerIdIndexMap pointer_id_map_; DISALLOW_COPY_AND_ASSIGN(SyntheticTouchDriver); diff --git a/chromium/content/browser/renderer_host/input/synthetic_touchpad_pinch_gesture.cc b/chromium/content/browser/renderer_host/input/synthetic_touchpad_pinch_gesture.cc index bbb71098e8b..8a4d6be4173 100644 --- a/chromium/content/browser/renderer_host/input/synthetic_touchpad_pinch_gesture.cc +++ b/chromium/content/browser/renderer_host/input/synthetic_touchpad_pinch_gesture.cc @@ -6,6 +6,7 @@ #include "base/callback.h" #include "content/browser/renderer_host/input/synthetic_touchpad_pinch_gesture.h" +#include "third_party/blink/public/common/input/synthetic_web_input_event_builders.h" namespace content { namespace { @@ -23,6 +24,11 @@ SyntheticTouchpadPinchGesture::SyntheticTouchpadPinchGesture( state_(SETUP), current_scale_(1.0f) { DCHECK_GT(params_.scale_factor, 0.0f); + if (params_.gesture_source_type != SyntheticGestureParams::TOUCHPAD_INPUT) { + DCHECK_EQ(params_.gesture_source_type, + SyntheticGestureParams::DEFAULT_INPUT); + params_.gesture_source_type = SyntheticGestureParams::TOUCHPAD_INPUT; + } } SyntheticTouchpadPinchGesture::~SyntheticTouchpadPinchGesture() {} @@ -73,7 +79,7 @@ void SyntheticTouchpadPinchGesture::ForwardGestureEvents( // Send the start event. target->DispatchInputEventToPlatform( - SyntheticWebGestureEventBuilder::Build( + blink::SyntheticWebGestureEventBuilder::Build( blink::WebGestureEvent::Type::kGesturePinchBegin, blink::WebGestureDevice::kTouchpad)); state_ = IN_PROGRESS; @@ -87,13 +93,13 @@ void SyntheticTouchpadPinchGesture::ForwardGestureEvents( // Send the incremental scale event. target->DispatchInputEventToPlatform( - SyntheticWebGestureEventBuilder::BuildPinchUpdate( + blink::SyntheticWebGestureEventBuilder::BuildPinchUpdate( incremental_scale, params_.anchor.x(), params_.anchor.y(), 0 /* modifierFlags */, blink::WebGestureDevice::kTouchpad)); if (HasReachedTarget(event_timestamp)) { target->DispatchInputEventToPlatform( - SyntheticWebGestureEventBuilder::Build( + blink::SyntheticWebGestureEventBuilder::Build( blink::WebGestureEvent::Type::kGesturePinchEnd, blink::WebGestureDevice::kTouchpad)); state_ = DONE; diff --git a/chromium/content/browser/renderer_host/input/synthetic_touchpad_pinch_gesture.h b/chromium/content/browser/renderer_host/input/synthetic_touchpad_pinch_gesture.h index 3a587439a7a..d66c0332361 100644 --- a/chromium/content/browser/renderer_host/input/synthetic_touchpad_pinch_gesture.h +++ b/chromium/content/browser/renderer_host/input/synthetic_touchpad_pinch_gesture.h @@ -11,7 +11,7 @@ #include "content/browser/renderer_host/input/synthetic_gesture_target.h" #include "content/common/content_export.h" #include "content/common/input/synthetic_pinch_gesture_params.h" -#include "content/common/input/synthetic_web_input_event_builders.h" +#include "third_party/blink/public/common/input/synthetic_web_input_event_builders.h" #include "third_party/blink/public/common/input/web_input_event.h" namespace content { diff --git a/chromium/content/browser/renderer_host/input/synthetic_touchscreen_pinch_gesture.cc b/chromium/content/browser/renderer_host/input/synthetic_touchscreen_pinch_gesture.cc index d620a9f3a3b..f48eb3cf534 100644 --- a/chromium/content/browser/renderer_host/input/synthetic_touchscreen_pinch_gesture.cc +++ b/chromium/content/browser/renderer_host/input/synthetic_touchscreen_pinch_gesture.cc @@ -23,6 +23,11 @@ SyntheticTouchscreenPinchGesture::SyntheticTouchscreenPinchGesture( gesture_source_type_(SyntheticGestureParams::DEFAULT_INPUT), state_(SETUP) { DCHECK_GT(params_.scale_factor, 0.0f); + if (params_.gesture_source_type != SyntheticGestureParams::TOUCH_INPUT) { + DCHECK_EQ(params_.gesture_source_type, + SyntheticGestureParams::DEFAULT_INPUT); + params_.gesture_source_type = SyntheticGestureParams::TOUCH_INPUT; + } } SyntheticTouchscreenPinchGesture::~SyntheticTouchscreenPinchGesture() {} diff --git a/chromium/content/browser/renderer_host/input/synthetic_touchscreen_pinch_gesture.h b/chromium/content/browser/renderer_host/input/synthetic_touchscreen_pinch_gesture.h index 2350eadab28..96547047512 100644 --- a/chromium/content/browser/renderer_host/input/synthetic_touchscreen_pinch_gesture.h +++ b/chromium/content/browser/renderer_host/input/synthetic_touchscreen_pinch_gesture.h @@ -12,7 +12,7 @@ #include "content/browser/renderer_host/input/synthetic_pointer_driver.h" #include "content/common/content_export.h" #include "content/common/input/synthetic_pinch_gesture_params.h" -#include "content/common/input/synthetic_web_input_event_builders.h" +#include "third_party/blink/public/common/input/synthetic_web_input_event_builders.h" #include "third_party/blink/public/common/input/web_input_event.h" namespace content { diff --git a/chromium/content/browser/renderer_host/input/touch_action_browsertest.cc b/chromium/content/browser/renderer_host/input/touch_action_browsertest.cc index 4c0d99b042a..b56634b2283 100644 --- a/chromium/content/browser/renderer_host/input/touch_action_browsertest.cc +++ b/chromium/content/browser/renderer_host/input/touch_action_browsertest.cc @@ -346,11 +346,10 @@ class TouchActionBrowserTest : public ContentBrowserTest { { "name": "pointerUp"}]}] )HTML"; - base::JSONReader json_reader; - base::Optional<base::Value> params = - json_reader.ReadToValue(pointer_actions_json); - ASSERT_TRUE(params.has_value()) << json_reader.GetErrorMessage(); - ActionsParser actions_parser(std::move(params.value())); + base::JSONReader::ValueWithError parsed_json = + base::JSONReader::ReadAndReturnValueWithError(pointer_actions_json); + ASSERT_TRUE(parsed_json.value) << parsed_json.error_message; + ActionsParser actions_parser(std::move(*parsed_json.value)); ASSERT_TRUE(actions_parser.ParsePointerActionSequence()); @@ -385,11 +384,10 @@ class TouchActionBrowserTest : public ContentBrowserTest { }] )HTML"; - base::JSONReader json_reader; - base::Optional<base::Value> params = - json_reader.ReadToValue(pointer_actions_json); - ASSERT_TRUE(params.has_value()) << json_reader.GetErrorMessage(); - ActionsParser actions_parser(std::move(params.value())); + base::JSONReader::ValueWithError parsed_json = + base::JSONReader::ReadAndReturnValueWithError(pointer_actions_json); + ASSERT_TRUE(parsed_json.value) << parsed_json.error_message; + ActionsParser actions_parser(std::move(*parsed_json.value)); ASSERT_TRUE(actions_parser.ParsePointerActionSequence()); diff --git a/chromium/content/browser/renderer_host/input/touch_action_filter.cc b/chromium/content/browser/renderer_host/input/touch_action_filter.cc index 1398ad469d3..772db2e5fbf 100644 --- a/chromium/content/browser/renderer_host/input/touch_action_filter.cc +++ b/chromium/content/browser/renderer_host/input/touch_action_filter.cc @@ -9,7 +9,6 @@ #include "base/check_op.h" #include "base/debug/crash_logging.h" #include "base/debug/dump_without_crashing.h" -#include "base/metrics/histogram_macros.h" #include "base/notreached.h" #include "base/strings/string_number_conversions.h" #include "base/trace_event/trace_event.h" @@ -34,68 +33,6 @@ bool IsXAxisActionDisallowed(cc::TouchAction action) { ((action & cc::TouchAction::kPanX) == cc::TouchAction::kNone); } -// Report how often the gesture event is or is not dropped due to the current -// allowed touch action state not matching the gesture event. -void ReportGestureEventFiltered(bool event_filtered) { - UMA_HISTOGRAM_BOOLEAN("TouchAction.GestureEventFiltered", event_filtered); -} - -// These values are persisted to logs. Entries should not be renumbered and -// numeric values should never be reused. -enum class GestureEventFilterResults { - kGSBAllowedByMain = 0, - kGSBAllowedByCC = 1, - kGSBFilteredByMain = 2, - kGSBFilteredByCC = 3, - kGSBDeferred = 4, - kGSUAllowedByMain = 5, - kGSUAllowedByCC = 6, - kGSUFilteredByMain = 7, - kGSUFilteredByCC = 8, - kGSUDeferred = 9, - kFilterResultsCount = 10, - kMaxValue = kFilterResultsCount -}; - -void ReportGestureEventFilterResults(bool is_gesture_scroll_begin, - bool active_touch_action_known, - FilterGestureEventResult result) { - GestureEventFilterResults report_type; - if (is_gesture_scroll_begin) { - if (result == FilterGestureEventResult::kFilterGestureEventAllowed) { - if (active_touch_action_known) - report_type = GestureEventFilterResults::kGSBAllowedByMain; - else - report_type = GestureEventFilterResults::kGSBAllowedByCC; - } else if (result == - FilterGestureEventResult::kFilterGestureEventFiltered) { - if (active_touch_action_known) - report_type = GestureEventFilterResults::kGSBFilteredByMain; - else - report_type = GestureEventFilterResults::kGSBFilteredByCC; - } else { - report_type = GestureEventFilterResults::kGSBDeferred; - } - } else { - if (result == FilterGestureEventResult::kFilterGestureEventAllowed) { - if (active_touch_action_known) - report_type = GestureEventFilterResults::kGSUAllowedByMain; - else - report_type = GestureEventFilterResults::kGSUAllowedByCC; - } else if (result == - FilterGestureEventResult::kFilterGestureEventFiltered) { - if (active_touch_action_known) - report_type = GestureEventFilterResults::kGSUFilteredByMain; - else - report_type = GestureEventFilterResults::kGSUFilteredByCC; - } else { - report_type = GestureEventFilterResults::kGSUDeferred; - } - } - UMA_HISTOGRAM_ENUMERATION("TouchAction.GestureEventFilterResults", - report_type, GestureEventFilterResults::kMaxValue); -} - } // namespace TouchActionFilter::TouchActionFilter() { @@ -112,13 +49,6 @@ FilterGestureEventResult TouchActionFilter::FilterGestureEvent( if (has_deferred_events_) { TRACE_EVENT_INSTANT0("input", "Has Deferred", TRACE_EVENT_SCOPE_THREAD); - WebInputEvent::Type type = gesture_event->GetType(); - if (type == WebInputEvent::Type::kGestureScrollBegin || - type == WebInputEvent::Type::kGestureScrollUpdate) { - ReportGestureEventFilterResults( - type == WebInputEvent::Type::kGestureScrollBegin, false, - FilterGestureEventResult::kFilterGestureEventDelayed); - } return FilterGestureEventResult::kFilterGestureEventDelayed; } @@ -132,13 +62,13 @@ FilterGestureEventResult TouchActionFilter::FilterGestureEvent( (allowed_touch_action_.has_value() ? cc::TouchActionToString(allowed_touch_action_.value()) : "n/a")); - TRACE_EVENT_INSTANT1("input", "whitelisted_action", TRACE_EVENT_SCOPE_THREAD, - "action", - cc::TouchActionToString(white_listed_touch_action_)); + TRACE_EVENT_INSTANT1( + "input", "compositor_allowed_action", TRACE_EVENT_SCOPE_THREAD, "action", + cc::TouchActionToString(compositor_allowed_touch_action_)); cc::TouchAction touch_action = active_touch_action_.has_value() ? active_touch_action_.value() - : white_listed_touch_action_; + : compositor_allowed_touch_action_; // Filter for allowable touch actions first (eg. before the TouchEventQueue // can decide to send a touch cancel event). @@ -150,9 +80,8 @@ FilterGestureEventResult TouchActionFilter::FilterGestureEvent( // filtering out the GestureTapDown due to tap suppression (i.e. tapping // during a fling should stop the fling, not be sent to the page). We // should not reset the touch action in this case! We currently work - // around this by resetting the whitelisted touch action from the - // compositor in this case as well but we should investigate not - // filtering the TapDown. + // around this by resetting the compositor allowed touch action in this + // case as well but we should investigate not filtering the TapDown. if (!gesture_sequence_in_progress_) { TRACE_EVENT_INSTANT0("input", "No Sequence at GSB!", TRACE_EVENT_SCOPE_THREAD); @@ -161,7 +90,7 @@ FilterGestureEventResult TouchActionFilter::FilterGestureEvent( active_touch_action_ = allowed_touch_action_; touch_action = allowed_touch_action_.value(); } else { - touch_action = white_listed_touch_action_; + touch_action = compositor_allowed_touch_action_; } } drop_scroll_events_ = @@ -177,17 +106,12 @@ FilterGestureEventResult TouchActionFilter::FilterGestureEvent( has_deferred_events_ = true; res = FilterGestureEventResult::kFilterGestureEventDelayed; } - ReportGestureEventFilterResults(true, active_touch_action_.has_value(), - res); return res; } case WebInputEvent::Type::kGestureScrollUpdate: { if (drop_scroll_events_) { TRACE_EVENT_INSTANT0("input", "Drop Events", TRACE_EVENT_SCOPE_THREAD); - ReportGestureEventFilterResults( - false, active_touch_action_.has_value(), - FilterGestureEventResult::kFilterGestureEventFiltered); return FilterGestureEventResult::kFilterGestureEventFiltered; } @@ -206,9 +130,6 @@ FilterGestureEventResult TouchActionFilter::FilterGestureEvent( TRACE_EVENT_INSTANT0("input", "Defer Due to YAxis", TRACE_EVENT_SCOPE_THREAD); has_deferred_events_ = true; - ReportGestureEventFilterResults( - false, active_touch_action_.has_value(), - FilterGestureEventResult::kFilterGestureEventDelayed); return FilterGestureEventResult::kFilterGestureEventDelayed; } gesture_event->data.scroll_update.delta_y = 0; @@ -219,17 +140,11 @@ FilterGestureEventResult TouchActionFilter::FilterGestureEvent( TRACE_EVENT_INSTANT0("input", "Defer Due to XAxis", TRACE_EVENT_SCOPE_THREAD); has_deferred_events_ = true; - ReportGestureEventFilterResults( - false, active_touch_action_.has_value(), - FilterGestureEventResult::kFilterGestureEventDelayed); return FilterGestureEventResult::kFilterGestureEventDelayed; } gesture_event->data.scroll_update.delta_x = 0; gesture_event->data.scroll_update.velocity_x = 0; } - ReportGestureEventFilterResults( - false, active_touch_action_.has_value(), - FilterGestureEventResult::kFilterGestureEventAllowed); break; } @@ -243,12 +158,12 @@ FilterGestureEventResult TouchActionFilter::FilterGestureEvent( if (gesture_sequence_.size() >= 1000) gesture_sequence_.erase(gesture_sequence_.begin(), gesture_sequence_.end() - 250); - // Do not reset |white_listed_touch_action_|. In the fling cancel case, - // the ack for the second touch sequence start, which sets the white - // listed touch action, could arrive before the GSE of the first fling - // sequence, we do not want to reset the white listed touch action. + // Do not reset |compositor_allowed_touch_action_|. In the fling cancel + // case, the ack for the second touch sequence start, which sets the + // compositor allowed touch action, could arrive before the GSE of the + // first fling sequence, we do not want to reset the compositor allowed + // touch action. gesture_sequence_in_progress_ = false; - ReportGestureEventFiltered(drop_scroll_events_); return FilterScrollEventAndResetState(); // Evaluate the |drop_pinch_events_| here instead of GSB because pinch @@ -267,7 +182,6 @@ FilterGestureEventResult TouchActionFilter::FilterGestureEvent( } return FilterGestureEventResult::kFilterGestureEventFiltered; case WebInputEvent::Type::kGesturePinchEnd: - ReportGestureEventFiltered(drop_pinch_events_); return FilterPinchEventAndResetState(); // The double tap gesture is a tap ending event. If a double-tap gesture is @@ -361,7 +275,7 @@ void TouchActionFilter::SetTouchAction(cc::TouchAction touch_action) { cc::TouchActionToString(touch_action)); allowed_touch_action_ = touch_action; active_touch_action_ = allowed_touch_action_; - white_listed_touch_action_ = touch_action; + compositor_allowed_touch_action_ = touch_action; } FilterGestureEventResult TouchActionFilter::FilterPinchEventAndResetState() { @@ -434,33 +348,10 @@ void TouchActionFilter::ReportAndResetTouchAction() { gesture_sequence_.append("RY"); else gesture_sequence_.append("RN"); - ReportTouchAction(); if (num_of_active_touches_ <= 0) ResetTouchAction(); } -void TouchActionFilter::ReportTouchAction() { - // Report the effective touch action computed by blink such as - // TouchAction::kNone, TouchAction::kPanX, etc. - // Since |cc::TouchAction::kAuto| is equivalent to |cc::TouchAction::kMax|, we - // must add one to the upper bound to be able to visualize the number of - // times |cc::TouchAction::kAuto| is hit. - // https://crbug.com/879511, remove this temporary fix. - if (!active_touch_action_.has_value()) - return; - - UMA_HISTOGRAM_ENUMERATION("TouchAction.EffectiveTouchAction", - active_touch_action_.value(), - static_cast<int>(cc::TouchAction::kMax) + 1); - - // Report how often the effective touch action computed by blink is or is - // not equivalent to the whitelisted touch action computed by the - // compositor. - UMA_HISTOGRAM_BOOLEAN( - "TouchAction.EquivalentEffectiveAndWhiteListed", - active_touch_action_.value() == white_listed_touch_action_); -} - void TouchActionFilter::AppendToGestureSequenceForDebugging(const char* str) { gesture_sequence_.append(str); } @@ -468,11 +359,10 @@ void TouchActionFilter::AppendToGestureSequenceForDebugging(const char* str) { void TouchActionFilter::ResetTouchAction() { TRACE_EVENT0("input", "TouchActionFilter::ResetTouchAction"); // Note that resetting the action mid-sequence is tolerated. Gestures that had - // their begin event(s) suppressed will be suppressed until the next - // sequenceo. + // their begin event(s) suppressed will be suppressed until the next sequence. if (has_touch_event_handler_) { allowed_touch_action_.reset(); - white_listed_touch_action_ = cc::TouchAction::kAuto; + compositor_allowed_touch_action_ = cc::TouchAction::kAuto; } else { // Lack of a touch handler indicates that the page either has no // touch-action modifiers or that all its touch-action modifiers are auto. @@ -482,15 +372,15 @@ void TouchActionFilter::ResetTouchAction() { } } -void TouchActionFilter::OnSetWhiteListedTouchAction( - cc::TouchAction white_listed_touch_action) { - TRACE_EVENT2("input", "TouchActionFilter::OnSetWhiteListedTouchAction", - "action", cc::TouchActionToString(white_listed_touch_action), - "current", cc::TouchActionToString(white_listed_touch_action_)); +void TouchActionFilter::OnSetCompositorAllowedTouchAction( + cc::TouchAction allowed_touch_action) { + TRACE_EVENT2("input", "TouchActionFilter::OnSetCompositorAllowedTouchAction", + "action", cc::TouchActionToString(allowed_touch_action), + "current", cc::TouchActionToString(allowed_touch_action)); // We use '&' here to account for the multiple-finger case, which is the same // as OnSetTouchAction. - white_listed_touch_action_ = - white_listed_touch_action_ & white_listed_touch_action; + compositor_allowed_touch_action_ = + compositor_allowed_touch_action_ & allowed_touch_action; } bool TouchActionFilter::ShouldSuppressScrolling( diff --git a/chromium/content/browser/renderer_host/input/touch_action_filter.h b/chromium/content/browser/renderer_host/input/touch_action_filter.h index 4d2ff433c67..e967cc17344 100644 --- a/chromium/content/browser/renderer_host/input/touch_action_filter.h +++ b/chromium/content/browser/renderer_host/input/touch_action_filter.h @@ -47,13 +47,13 @@ class CONTENT_EXPORT TouchActionFilter { void OnSetTouchAction(cc::TouchAction touch_action); // Called at the end of a touch action sequence in order to log when a - // whitelisted touch action is or is not equivalent to the allowed touch - // action. + // compositor allowed touch action is or is not equivalent to the allowed + // touch action. void ReportAndResetTouchAction(); - // Called when a set-white-listed-touch-action message is received from the - // renderer for a touch start event that is currently in flight. - void OnSetWhiteListedTouchAction(cc::TouchAction white_listed_touch_action); + // Called when a set-compositor-allowed-touch-action message is received from + // the renderer for a touch start event that is currently in flight. + void OnSetCompositorAllowedTouchAction(cc::TouchAction); base::Optional<cc::TouchAction> allowed_touch_action() const { return allowed_touch_action_; @@ -63,8 +63,8 @@ class CONTENT_EXPORT TouchActionFilter { return active_touch_action_; } - cc::TouchAction white_listed_touch_action() const { - return white_listed_touch_action_; + cc::TouchAction compositor_allowed_touch_action() const { + return compositor_allowed_touch_action_; } void SetForceEnableZoom(bool enabled) { force_enable_zoom_ = enabled; } @@ -91,7 +91,6 @@ class CONTENT_EXPORT TouchActionFilter { cc::TouchAction touch_action); FilterGestureEventResult FilterScrollEventAndResetState(); FilterGestureEventResult FilterPinchEventAndResetState(); - void ReportTouchAction(); void ResetTouchAction(); void SetTouchAction(cc::TouchAction touch_action); @@ -138,8 +137,8 @@ class CONTENT_EXPORT TouchActionFilter { // sequence due to fling. base::Optional<cc::TouchAction> active_touch_action_; - // Whitelisted touch action received from the compositor. - cc::TouchAction white_listed_touch_action_; + // Allowed touch action received from the compositor. + cc::TouchAction compositor_allowed_touch_action_; // Debugging only. std::string gesture_sequence_; diff --git a/chromium/content/browser/renderer_host/input/touch_action_filter_unittest.cc b/chromium/content/browser/renderer_host/input/touch_action_filter_unittest.cc index e0903a59d2e..75353694cff 100644 --- a/chromium/content/browser/renderer_host/input/touch_action_filter_unittest.cc +++ b/chromium/content/browser/renderer_host/input/touch_action_filter_unittest.cc @@ -5,12 +5,13 @@ #include "content/browser/renderer_host/input/touch_action_filter.h" #include "base/test/scoped_feature_list.h" #include "content/browser/renderer_host/event_with_latency_info.h" -#include "content/common/input/synthetic_web_input_event_builders.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/common/input/synthetic_web_input_event_builders.h" #include "third_party/blink/public/common/input/web_input_event.h" #include "third_party/blink/public/mojom/input/input_event_result.mojom-shared.h" #include "ui/events/blink/blink_features.h" +using blink::SyntheticWebGestureEventBuilder; using blink::WebGestureEvent; using blink::WebInputEvent; @@ -33,8 +34,8 @@ class TouchActionFilterTest : public testing::Test { } void ResetTouchAction() { filter_.ResetTouchAction(); } void ResetActiveTouchAction() { filter_.active_touch_action_.reset(); } - void ResetWhiteListedTouchAction() { - filter_.white_listed_touch_action_ = cc::TouchAction::kAuto; + void ResetCompositorAllowedTouchAction() { + filter_.compositor_allowed_touch_action_ = cc::TouchAction::kAuto; } void SetNoDeferredEvents() { filter_.has_deferred_events_ = false; } void SetGestureSequenceInProgress() { @@ -1179,13 +1180,14 @@ TEST_F(TouchActionFilterTest, GestureArrivesBeforeHasHandlerSet) { FilterGestureEventResult::kFilterGestureEventAllowed); } -TEST_F(TouchActionFilterTest, PinchGesturesAllowedByWhiteListedTouchAction) { +TEST_F(TouchActionFilterTest, + PinchGesturesAllowedByCompositorAllowedTouchAction) { filter_.OnHasTouchEventHandlers(true); EXPECT_FALSE(ActiveTouchAction().has_value()); EXPECT_FALSE(filter_.allowed_touch_action().has_value()); - // white listed touch action has a default value of Auto, and pinch related - // gestures should be allowed. + // Compositor allowed touch action has a default value of Auto, and pinch + // related gestures should be allowed. WebGestureEvent pinch_begin = SyntheticWebGestureEventBuilder::Build( WebInputEvent::Type::kGesturePinchBegin, kSourceDevice); WebGestureEvent pinch_update = @@ -1201,9 +1203,9 @@ TEST_F(TouchActionFilterTest, PinchGesturesAllowedByWhiteListedTouchAction) { FilterGestureEventResult::kFilterGestureEventAllowed); } -// Test gesture event filtering with white listed touch action. It should test -// all 3 kinds of results: Allowed / Dropped / Delayed. -TEST_F(TouchActionFilterTest, FilterWithWhiteListedTouchAction) { +// Test gesture event filtering with compositor allowed touch action. It should +// test all 3 kinds of results: Allowed / Dropped / Delayed. +TEST_F(TouchActionFilterTest, FilterWithCompositorAllowedListedTouchAction) { filter_.OnHasTouchEventHandlers(true); EXPECT_FALSE(ActiveTouchAction().has_value()); EXPECT_FALSE(filter_.allowed_touch_action().has_value()); @@ -1218,8 +1220,8 @@ TEST_F(TouchActionFilterTest, FilterWithWhiteListedTouchAction) { WebGestureEvent scroll_end = SyntheticWebGestureEventBuilder::Build( WebInputEvent::Type::kGestureScrollEnd, kSourceDevice); - filter_.OnSetWhiteListedTouchAction(cc::TouchAction::kPan); - EXPECT_EQ(filter_.white_listed_touch_action(), cc::TouchAction::kPan); + filter_.OnSetCompositorAllowedTouchAction(cc::TouchAction::kPan); + EXPECT_EQ(filter_.compositor_allowed_touch_action(), cc::TouchAction::kPan); SetGestureSequenceInProgress(); EXPECT_EQ(filter_.FilterGestureEvent(&scroll_begin), FilterGestureEventResult::kFilterGestureEventAllowed); @@ -1231,9 +1233,9 @@ TEST_F(TouchActionFilterTest, FilterWithWhiteListedTouchAction) { // Pinch related gestures are always delayed. ResetTouchAction(); ResetActiveTouchAction(); - ResetWhiteListedTouchAction(); - filter_.OnSetWhiteListedTouchAction(cc::TouchAction::kPan); - EXPECT_EQ(filter_.white_listed_touch_action(), cc::TouchAction::kPan); + ResetCompositorAllowedTouchAction(); + filter_.OnSetCompositorAllowedTouchAction(cc::TouchAction::kPan); + EXPECT_EQ(filter_.compositor_allowed_touch_action(), cc::TouchAction::kPan); WebGestureEvent pinch_begin = SyntheticWebGestureEventBuilder::Build( WebInputEvent::Type::kGesturePinchBegin, kSourceDevice); WebGestureEvent pinch_update = @@ -1248,14 +1250,15 @@ TEST_F(TouchActionFilterTest, FilterWithWhiteListedTouchAction) { EXPECT_EQ(filter_.FilterGestureEvent(&pinch_end), FilterGestureEventResult::kFilterGestureEventDelayed); - // Scroll updates should be delayed if white listed touch action is PanY, - // because there are delta along the direction that is not allowed. + // Scroll updates should be delayed if the compositor allowed listed touch + // action is PanY, because there are delta along the direction that is not + // allowed. ResetTouchAction(); ResetActiveTouchAction(); - ResetWhiteListedTouchAction(); - filter_.OnSetWhiteListedTouchAction(cc::TouchAction::kPanY); + ResetCompositorAllowedTouchAction(); + filter_.OnSetCompositorAllowedTouchAction(cc::TouchAction::kPanY); SetNoDeferredEvents(); - EXPECT_EQ(filter_.white_listed_touch_action(), cc::TouchAction::kPanY); + EXPECT_EQ(filter_.compositor_allowed_touch_action(), cc::TouchAction::kPanY); SetGestureSequenceInProgress(); EXPECT_EQ(filter_.FilterGestureEvent(&scroll_begin), FilterGestureEventResult::kFilterGestureEventAllowed); @@ -1266,10 +1269,10 @@ TEST_F(TouchActionFilterTest, FilterWithWhiteListedTouchAction) { ResetTouchAction(); ResetActiveTouchAction(); - ResetWhiteListedTouchAction(); - filter_.OnSetWhiteListedTouchAction(cc::TouchAction::kPanX); + ResetCompositorAllowedTouchAction(); + filter_.OnSetCompositorAllowedTouchAction(cc::TouchAction::kPanX); SetNoDeferredEvents(); - EXPECT_EQ(filter_.white_listed_touch_action(), cc::TouchAction::kPanX); + EXPECT_EQ(filter_.compositor_allowed_touch_action(), cc::TouchAction::kPanX); dy = 0; scroll_begin = @@ -1290,8 +1293,8 @@ TEST_F(TouchActionFilterTest, FilterWithWhiteListedTouchAction) { SyntheticWebGestureEventBuilder::BuildScrollBegin(dx, dy, kSourceDevice); scroll_update = SyntheticWebGestureEventBuilder::BuildScrollUpdate( dx, dy, 0, kSourceDevice); - filter_.OnSetWhiteListedTouchAction(cc::TouchAction::kPanX); - EXPECT_EQ(filter_.white_listed_touch_action(), cc::TouchAction::kPanX); + filter_.OnSetCompositorAllowedTouchAction(cc::TouchAction::kPanX); + EXPECT_EQ(filter_.compositor_allowed_touch_action(), cc::TouchAction::kPanX); SetGestureSequenceInProgress(); EXPECT_EQ(filter_.FilterGestureEvent(&scroll_begin), FilterGestureEventResult::kFilterGestureEventDelayed); @@ -1301,21 +1304,21 @@ TEST_F(TouchActionFilterTest, FilterWithWhiteListedTouchAction) { FilterGestureEventResult::kFilterGestureEventDelayed); } -TEST_F(TouchActionFilterTest, WhiteListedTouchActionResetToAuto) { +TEST_F(TouchActionFilterTest, CompositorAllowedTouchActionResetToAuto) { filter_.OnHasTouchEventHandlers(true); - filter_.OnSetWhiteListedTouchAction(cc::TouchAction::kPan); - EXPECT_EQ(filter_.white_listed_touch_action(), cc::TouchAction::kPan); + filter_.OnSetCompositorAllowedTouchAction(cc::TouchAction::kPan); + EXPECT_EQ(filter_.compositor_allowed_touch_action(), cc::TouchAction::kPan); ResetTouchAction(); - EXPECT_EQ(filter_.white_listed_touch_action(), cc::TouchAction::kAuto); + EXPECT_EQ(filter_.compositor_allowed_touch_action(), cc::TouchAction::kAuto); } -TEST_F(TouchActionFilterTest, WhiteListedTouchActionAutoNoHasHandlers) { +TEST_F(TouchActionFilterTest, CompositorAllowedTouchActionAutoNoHasHandlers) { filter_.OnHasTouchEventHandlers(false); - EXPECT_EQ(filter_.white_listed_touch_action(), cc::TouchAction::kAuto); + EXPECT_EQ(filter_.compositor_allowed_touch_action(), cc::TouchAction::kAuto); ResetTouchAction(); - EXPECT_EQ(filter_.white_listed_touch_action(), cc::TouchAction::kAuto); + EXPECT_EQ(filter_.compositor_allowed_touch_action(), cc::TouchAction::kAuto); } TEST_F(TouchActionFilterTest, ResetBeforeHasHandlerSet) { @@ -1328,11 +1331,11 @@ TEST_F(TouchActionFilterTest, ResetBeforeHasHandlerSet) { } TEST_F(TouchActionFilterTest, - WhiteListedTouchActionNotResetAtGestureScrollEnd) { + CompositorAllowedTouchActionNotResetAtGestureScrollEnd) { filter_.OnHasTouchEventHandlers(true); - filter_.OnSetWhiteListedTouchAction(cc::TouchAction::kPan); - EXPECT_EQ(filter_.white_listed_touch_action(), cc::TouchAction::kPan); + filter_.OnSetCompositorAllowedTouchAction(cc::TouchAction::kPan); + EXPECT_EQ(filter_.compositor_allowed_touch_action(), cc::TouchAction::kPan); int dx = 2, dy = 5; WebGestureEvent scroll_begin = @@ -1351,7 +1354,7 @@ TEST_F(TouchActionFilterTest, EXPECT_EQ(filter_.FilterGestureEvent(&scroll_end), FilterGestureEventResult::kFilterGestureEventAllowed); - EXPECT_EQ(filter_.white_listed_touch_action(), cc::TouchAction::kPan); + EXPECT_EQ(filter_.compositor_allowed_touch_action(), cc::TouchAction::kPan); } // Having a gesture scroll begin without tap down should set touch action to @@ -1361,12 +1364,12 @@ TEST_F(TouchActionFilterTest, ScrollBeginWithoutTapDown) { EXPECT_FALSE(ActiveTouchAction().has_value()); EXPECT_FALSE(filter_.allowed_touch_action().has_value()); - filter_.OnSetWhiteListedTouchAction(cc::TouchAction::kPan); + filter_.OnSetCompositorAllowedTouchAction(cc::TouchAction::kPan); WebGestureEvent scroll_begin = SyntheticWebGestureEventBuilder::BuildScrollBegin(5, 0, kSourceDevice); EXPECT_EQ(filter_.FilterGestureEvent(&scroll_begin), FilterGestureEventResult::kFilterGestureEventAllowed); - EXPECT_EQ(filter_.white_listed_touch_action(), cc::TouchAction::kPan); + EXPECT_EQ(filter_.compositor_allowed_touch_action(), cc::TouchAction::kPan); ResetTouchAction(); ResetActiveTouchAction(); @@ -1376,7 +1379,7 @@ TEST_F(TouchActionFilterTest, ScrollBeginWithoutTapDown) { // Ensure that there is no crash at GSB if both |allowed_| and |active_| // touch action have no value. - filter_.OnSetWhiteListedTouchAction(cc::TouchAction::kPan); + filter_.OnSetCompositorAllowedTouchAction(cc::TouchAction::kPan); EXPECT_EQ(filter_.FilterGestureEvent(&scroll_begin), FilterGestureEventResult::kFilterGestureEventAllowed); } diff --git a/chromium/content/browser/renderer_host/input/touch_input_browsertest.cc b/chromium/content/browser/renderer_host/input/touch_input_browsertest.cc index 59ee4394413..54d60e31bd6 100644 --- a/chromium/content/browser/renderer_host/input/touch_input_browsertest.cc +++ b/chromium/content/browser/renderer_host/input/touch_input_browsertest.cc @@ -15,7 +15,6 @@ #include "content/browser/renderer_host/render_widget_host_impl.h" #include "content/browser/renderer_host/render_widget_host_input_event_router.h" #include "content/browser/web_contents/web_contents_impl.h" -#include "content/common/input/synthetic_web_input_event_builders.h" #include "content/common/input_messages.h" #include "content/public/browser/browser_message_filter.h" #include "content/public/browser/render_view_host.h" @@ -27,6 +26,7 @@ #include "content/public/test/content_browser_test_utils.h" #include "content/public/test/hit_test_region_observer.h" #include "content/shell/browser/shell.h" +#include "third_party/blink/public/common/input/synthetic_web_input_event_builders.h" #include "third_party/blink/public/common/input/web_input_event.h" #include "ui/latency/latency_info.h" @@ -100,7 +100,7 @@ class TouchInputBrowserTest : public ContentBrowserTest { } protected: - void SendTouchEvent(SyntheticWebTouchEvent* event) { + void SendTouchEvent(blink::SyntheticWebTouchEvent* event) { auto* root_view = GetWidgetHost()->GetView(); auto* input_event_router = GetWidgetHost()->delegate()->GetInputEventRouter(); @@ -138,7 +138,7 @@ class TouchInputBrowserTest : public ContentBrowserTest { IN_PROC_BROWSER_TEST_F(TouchInputBrowserTest, TouchNoHandler) { LoadURL(); - SyntheticWebTouchEvent touch; + blink::SyntheticWebTouchEvent touch; // A press on |first| should be acked with NO_CONSUMER_EXISTS since there is // no touch-handler on it. @@ -157,7 +157,7 @@ IN_PROC_BROWSER_TEST_F(TouchInputBrowserTest, TouchNoHandler) { IN_PROC_BROWSER_TEST_F(TouchInputBrowserTest, TouchHandlerNoConsume) { LoadURL(); - SyntheticWebTouchEvent touch; + blink::SyntheticWebTouchEvent touch; // Press on |second| should be acked with NOT_CONSUMED since there is a // touch-handler on |second|, but it doesn't consume the event. @@ -175,7 +175,7 @@ IN_PROC_BROWSER_TEST_F(TouchInputBrowserTest, TouchHandlerNoConsume) { IN_PROC_BROWSER_TEST_F(TouchInputBrowserTest, TouchHandlerConsume) { LoadURL(); - SyntheticWebTouchEvent touch; + blink::SyntheticWebTouchEvent touch; // Press on |third| should be acked with CONSUMED since the touch-handler on // |third| consimes the event. @@ -193,7 +193,7 @@ IN_PROC_BROWSER_TEST_F(TouchInputBrowserTest, TouchHandlerConsume) { IN_PROC_BROWSER_TEST_F(TouchInputBrowserTest, MultiPointTouchPress) { LoadURL(); - SyntheticWebTouchEvent touch; + blink::SyntheticWebTouchEvent touch; // Press on |first|, which sould be acked with NO_CONSUMER_EXISTS. Then press // on |third|. That point should be acked with CONSUMED. diff --git a/chromium/content/browser/renderer_host/input/web_input_event_builders_android_unittest.cc b/chromium/content/browser/renderer_host/input/web_input_event_builders_android_unittest.cc index 47d7d475576..7dee79afd75 100644 --- a/chromium/content/browser/renderer_host/input/web_input_event_builders_android_unittest.cc +++ b/chromium/content/browser/renderer_host/input/web_input_event_builders_android_unittest.cc @@ -215,7 +215,7 @@ TEST(WebInputEventBuilderAndroidTest, WebMouseEventCoordinates) { ui::MotionEventAndroid motion_event( AttachCurrentThread(), nullptr, kPixToDip, 0.f, 0.f, 0.f, kEventTimeMs, - AMOTION_EVENT_ACTION_DOWN, 1, 0, -1, 0, 1, AMETA_ALT_ON, raw_offset_x, + AMOTION_EVENT_ACTION_DOWN, 1, 0, -1, 0, 0, 1, AMETA_ALT_ON, raw_offset_x, raw_offset_y, false, &p0, nullptr); WebMouseEvent web_event = content::WebMouseEventBuilder::Build( diff --git a/chromium/content/browser/renderer_host/input/web_input_event_builders_mac.mm b/chromium/content/browser/renderer_host/input/web_input_event_builders_mac.mm index 9d420f190a7..940757ca1eb 100644 --- a/chromium/content/browser/renderer_host/input/web_input_event_builders_mac.mm +++ b/chromium/content/browser/renderer_host/input/web_input_event_builders_mac.mm @@ -241,15 +241,14 @@ blink::WebKeyboardEvent WebKeyboardEventBuilder::Build(NSEvent* event, ui::EventTimeStampFromSeconds([event timestamp]); if (record_debug_uma) { if (ui::EventTypeFromNative(event) == ui::ET_KEY_PRESSED) { + base::TimeDelta diff = (now - hardware_timestamp).magnitude(); UMA_HISTOGRAM_CUSTOM_TIMES( - now > hardware_timestamp - ? "Event.Latency.OS_NO_VALIDATION.POSITIVE.KEY_PRESSED" - : "Event.Latency.OS_NO_VALIDATION.NEGATIVE.KEY_PRESSED", - (now - hardware_timestamp).magnitude(), + "Event.Latency.OS_NO_VALIDATION.POSITIVE.KEY_PRESSED", diff, base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromSeconds(60), 50); } } + ui::DomCode dom_code = ui::DomCodeFromNSEvent(event); int modifiers = ModifiersFromEvent(event) | ui::DomCodeToWebInputEventModifiers(dom_code); @@ -310,11 +309,9 @@ blink::WebMouseEvent WebMouseEventBuilder::Build( base::TimeTicks hardware_timestamp = ui::EventTimeStampFromSeconds([event timestamp]); if (ui::EventTypeFromNative(event) == ui::ET_MOUSE_PRESSED) { + base::TimeDelta diff = (now - hardware_timestamp).magnitude(); UMA_HISTOGRAM_CUSTOM_TIMES( - now > hardware_timestamp - ? "Event.Latency.OS_NO_VALIDATION.POSITIVE.MOUSE_PRESSED" - : "Event.Latency.OS_NO_VALIDATION.NEGATIVE.MOUSE_PRESSED", - (now - hardware_timestamp).magnitude(), + "Event.Latency.OS_NO_VALIDATION.POSITIVE.MOUSE_PRESSED", diff, base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromSeconds(60), 50); } @@ -430,11 +427,9 @@ blink::WebMouseWheelEvent WebMouseWheelEventBuilder::Build( base::TimeTicks now = ui::EventTimeForNow(); base::TimeTicks hardware_timestamp = ui::EventTimeStampFromSeconds([event timestamp]); + base::TimeDelta diff = (now - hardware_timestamp).magnitude(); UMA_HISTOGRAM_CUSTOM_TIMES( - now > hardware_timestamp - ? "Event.Latency.OS_NO_VALIDATION.POSITIVE.MOUSE_WHEEL" - : "Event.Latency.OS_NO_VALIDATION.NEGATIVE.MOUSE_WHEEL", - (now - hardware_timestamp).magnitude(), + "Event.Latency.OS_NO_VALIDATION.POSITIVE.MOUSE_WHEEL", diff, base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromSeconds(60), 50); blink::WebMouseWheelEvent result( @@ -673,9 +668,7 @@ blink::WebTouchEvent WebTouchEventBuilder::Build(NSEvent* event, NSView* view) { base::TimeTicks hardware_timestamp = ui::EventTimeStampFromSeconds([event timestamp]); UMA_HISTOGRAM_CUSTOM_TIMES( - now > hardware_timestamp - ? "Event.Latency.OS.NO_VALIDATION.POSITIVE.TOUCH_PRESSED" - : "Event.Latency.OS.NO_VALIDATION.NEGATIVE.TOUCH_PRESSED", + "Event.Latency.OS.NO_VALIDATION.POSITIVE.TOUCH_PRESSED", (now - hardware_timestamp).magnitude(), base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromSeconds(60), 50); diff --git a/chromium/content/browser/renderer_host/input/web_input_event_util_unittest.cc b/chromium/content/browser/renderer_host/input/web_input_event_util_unittest.cc index 7026fd449f7..f0d9983973e 100644 --- a/chromium/content/browser/renderer_host/input/web_input_event_util_unittest.cc +++ b/chromium/content/browser/renderer_host/input/web_input_event_util_unittest.cc @@ -5,8 +5,8 @@ #include <stddef.h> #include "base/numerics/math_constants.h" -#include "content/common/input/synthetic_web_input_event_builders.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/common/input/synthetic_web_input_event_builders.h" #include "ui/events/blink/blink_event_util.h" #include "ui/events/blink/web_input_event_traits.h" #include "ui/events/event_constants.h" diff --git a/chromium/content/browser/renderer_host/input/wheel_event_listener_browsertest.cc b/chromium/content/browser/renderer_host/input/wheel_event_listener_browsertest.cc index cfbe402cf7e..80d9c9d9f1f 100644 --- a/chromium/content/browser/renderer_host/input/wheel_event_listener_browsertest.cc +++ b/chromium/content/browser/renderer_host/input/wheel_event_listener_browsertest.cc @@ -10,6 +10,7 @@ #include "content/public/test/content_browser_test.h" #include "content/public/test/content_browser_test_utils.h" #include "content/shell/browser/shell.h" +#include "third_party/blink/public/common/input/synthetic_web_input_event_builders.h" #include "third_party/blink/public/common/input/web_input_event.h" using blink::WebInputEvent; @@ -82,7 +83,7 @@ class WheelEventListenerBrowserTest : public ContentBrowserTest { double x = 10; double y = 10; blink::WebMouseWheelEvent wheel_event = - SyntheticWebMouseWheelEventBuilder::Build( + blink::SyntheticWebMouseWheelEventBuilder::Build( x, y, x, y, -20, -20, 0, ui::ScrollGranularity::kScrollByPrecisePixel); wheel_event.phase = blink::WebMouseWheelEvent::kPhaseBegan; diff --git a/chromium/content/browser/renderer_host/input/wheel_scroll_latching_browsertest.cc b/chromium/content/browser/renderer_host/input/wheel_scroll_latching_browsertest.cc index 97e202bdc4c..5ff317dc6f2 100644 --- a/chromium/content/browser/renderer_host/input/wheel_scroll_latching_browsertest.cc +++ b/chromium/content/browser/renderer_host/input/wheel_scroll_latching_browsertest.cc @@ -7,13 +7,13 @@ #include "content/browser/renderer_host/render_widget_host_impl.h" #include "content/browser/renderer_host/render_widget_host_input_event_router.h" #include "content/browser/web_contents/web_contents_impl.h" -#include "content/common/input/synthetic_web_input_event_builders.h" #include "content/public/test/browser_test.h" #include "content/public/test/browser_test_utils.h" #include "content/public/test/content_browser_test.h" #include "content/public/test/content_browser_test_utils.h" #include "content/public/test/hit_test_region_observer.h" #include "content/shell/browser/shell.h" +#include "third_party/blink/public/common/input/synthetic_web_input_event_builders.h" #include "ui/events/gesture_detection/gesture_configuration.h" #if defined(OS_ANDROID) @@ -167,7 +167,7 @@ IN_PROC_BROWSER_TEST_F(WheelScrollLatchingBrowserTest, MAYBE_WheelEventTarget) { float delta_x = 0; float delta_y = -0.6 * scrollable_div_top; blink::WebMouseWheelEvent wheel_event = - SyntheticWebMouseWheelEventBuilder::Build( + blink::SyntheticWebMouseWheelEventBuilder::Build( x, y, x, y, delta_x, delta_y, 0, ui::ScrollGranularity::kScrollByPrecisePixel); @@ -221,7 +221,7 @@ IN_PROC_BROWSER_TEST_F(WheelScrollLatchingBrowserTest, float delta_x = 0; float delta_y = -0.6 * scrollable_div_top; blink::WebMouseWheelEvent wheel_event = - SyntheticWebMouseWheelEventBuilder::Build( + blink::SyntheticWebMouseWheelEventBuilder::Build( x, y, x, y, delta_x, delta_y, 0, ui::ScrollGranularity::kScrollByPrecisePixel); wheel_event.phase = blink::WebMouseWheelEvent::kPhaseBegan; @@ -257,16 +257,10 @@ IN_PROC_BROWSER_TEST_F(WheelScrollLatchingBrowserTest, EXPECT_EQ(1, ExecuteScriptAndExtractInt("scrollableDivWheelEventCounter")); } -// crbug.com/777258 Flaky on Android and Chrome OS. -#if defined(OS_ANDROID) || defined(OS_CHROMEOS) -#define MAYBE_WheelScrollingRelatchWhenLatchedScrollerRemoved \ - DISABLED_WheelScrollingRelatchWhenLatchedScrollerRemoved -#else -#define MAYBE_WheelScrollingRelatchWhenLatchedScrollerRemoved \ - WheelScrollingRelatchWhenLatchedScrollerRemoved -#endif -IN_PROC_BROWSER_TEST_F(WheelScrollLatchingBrowserTest, - MAYBE_WheelScrollingRelatchWhenLatchedScrollerRemoved) { +// crbug.com/777258 Flaky everywhere. +IN_PROC_BROWSER_TEST_F( + WheelScrollLatchingBrowserTest, + DISABLED_WheelScrollingRelatchWhenLatchedScrollerRemoved) { LoadURL(kWheelEventLatchingDataURL); EXPECT_EQ( ExecuteScriptAndExtractDouble("document.scrollingElement.scrollTop"), 0); @@ -384,7 +378,7 @@ IN_PROC_BROWSER_TEST_F(WheelScrollLatchingBrowserTest, auto wheel_msg_watcher = std::make_unique<InputMsgWatcher>( GetWidgetHost(), blink::WebInputEvent::Type::kMouseWheel); blink::WebMouseWheelEvent wheel_event = - SyntheticWebMouseWheelEventBuilder::Build( + blink::SyntheticWebMouseWheelEventBuilder::Build( x, y, x, y, 1, 1, 0, ui::ScrollGranularity::kScrollByPrecisePixel); wheel_event.phase = blink::WebMouseWheelEvent::kPhaseBegan; GetRouter()->RouteMouseWheelEvent(GetRootView(), &wheel_event, diff --git a/chromium/content/browser/renderer_host/input_event_shim.h b/chromium/content/browser/renderer_host/input_event_shim.h index cf1144147e1..4e1e98b1514 100644 --- a/chromium/content/browser/renderer_host/input_event_shim.h +++ b/chromium/content/browser/renderer_host/input_event_shim.h @@ -5,7 +5,7 @@ #ifndef CONTENT_BROWSER_RENDERER_HOST_INPUT_EVENT_SHIM_H_ #define CONTENT_BROWSER_RENDERER_HOST_INPUT_EVENT_SHIM_H_ -#include "content/common/text_input_state.h" +#include "ui/base/ime/mojom/text_input_state.mojom.h" namespace content { @@ -18,7 +18,8 @@ class InputEventShim { public: virtual ~InputEventShim() {} virtual void DidSetHasTouchEventHandlers(bool accept) = 0; - virtual void DidTextInputStateChange(const TextInputState& params) = 0; + virtual void DidTextInputStateChange( + const ui::mojom::TextInputState& params) = 0; virtual void DidLockMouse(bool user_gesture, bool privileged) = 0; virtual void DidUnlockMouse() = 0; }; diff --git a/chromium/content/browser/renderer_host/legacy_render_widget_host_win.cc b/chromium/content/browser/renderer_host/legacy_render_widget_host_win.cc index 62db60a3494..3d926d8ff1b 100644 --- a/chromium/content/browser/renderer_host/legacy_render_widget_host_win.cc +++ b/chromium/content/browser/renderer_host/legacy_render_widget_host_win.cc @@ -120,7 +120,9 @@ void LegacyRenderWidgetHostHWND::OnFinalMessage(HWND hwnd) { } LegacyRenderWidgetHostHWND::LegacyRenderWidgetHostHWND(HWND parent) - : mouse_tracking_enabled_(false), host_(nullptr) { + : mouse_tracking_enabled_(false), + host_(nullptr), + did_return_uia_object_(false) { RECT rect = {0}; Base::Create(parent, rect, L"Chrome Legacy Window", WS_CHILDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, @@ -216,6 +218,10 @@ LRESULT LegacyRenderWidgetHostHWND::OnGetObject(UINT message, if (is_uia_request) { Microsoft::WRL::ComPtr<IRawElementProviderSimple> root_uia; root->QueryInterface(IID_PPV_ARGS(&root_uia)); + + // Return the UIA object via UiaReturnRawElementProvider(). See: + // https://docs.microsoft.com/en-us/windows/win32/winauto/wm-getobject + did_return_uia_object_ = true; return UiaReturnRawElementProvider(hwnd(), w_param, l_param, root_uia.Get()); } else { @@ -477,11 +483,12 @@ LRESULT LegacyRenderWidgetHostHWND::OnSize(UINT message, LRESULT LegacyRenderWidgetHostHWND::OnDestroy(UINT message, WPARAM w_param, LPARAM l_param) { - if (::switches::IsExperimentalAccessibilityPlatformUIAEnabled()) { - // Signal to UIA that all objects associated with this HWND can be - // discarded. + // If we have ever returned a UIA object via WM_GETOBJECT, signal that all + // objects associated with this HWND can be discarded. See: + // https://docs.microsoft.com/en-us/windows/win32/api/uiautomationcoreapi/nf-uiautomationcoreapi-uiareturnrawelementprovider#remarks + if (did_return_uia_object_) UiaReturnRawElementProvider(hwnd(), 0, 0, nullptr); - } + return 0; } diff --git a/chromium/content/browser/renderer_host/legacy_render_widget_host_win.h b/chromium/content/browser/renderer_host/legacy_render_widget_host_win.h index d13b593c16d..d43ddddf7ed 100644 --- a/chromium/content/browser/renderer_host/legacy_render_widget_host_win.h +++ b/chromium/content/browser/renderer_host/legacy_render_widget_host_win.h @@ -186,9 +186,15 @@ class CONTENT_EXPORT LegacyRenderWidgetHostHWND // Some assistive software need to track the location of the caret. std::unique_ptr<ui::AXSystemCaretWin> ax_system_caret_; - // Implements IRawElementProviderFragmentRoot when UIA is enabled + // Implements IRawElementProviderFragmentRoot when UIA is enabled. std::unique_ptr<ui::AXFragmentRootWin> ax_fragment_root_; + // Set to true when we return a UIA object. Determines whether we need to + // call UIA to clean up object references on window destruction. + // This is important to avoid triggering a cross-thread COM call which could + // cause re-entrancy during teardown. https://crbug.com/1087553 + bool did_return_uia_object_; + // This class provides functionality to register the legacy window as a // Direct Manipulation consumer. This allows us to support smooth scroll // in Chrome on Windows 10. diff --git a/chromium/content/browser/renderer_host/media/audio_input_device_manager.cc b/chromium/content/browser/renderer_host/media/audio_input_device_manager.cc index f32a49429ae..b86fbf71e23 100644 --- a/chromium/content/browser/renderer_host/media/audio_input_device_manager.cc +++ b/chromium/content/browser/renderer_host/media/audio_input_device_manager.cc @@ -12,7 +12,6 @@ #include "base/command_line.h" #include "base/metrics/histogram_macros.h" #include "base/strings/stringprintf.h" -#include "base/task/post_task.h" #include "build/build_config.h" #include "content/browser/renderer_host/media/media_stream_manager.h" #include "content/public/browser/browser_task_traits.h" @@ -136,7 +135,6 @@ base::UnguessableToken AudioInputDeviceManager::Open( audio_system_->GetAssociatedOutputDeviceID( device.id, base::BindOnce(&AudioInputDeviceManager::OpenedOnIOThread, base::Unretained(this), session_id, device, - base::TimeTicks::Now(), base::Optional<media::AudioParameters>())); } else { // TODO(tommi): As is, we hit this code path when device.type is @@ -152,8 +150,7 @@ base::UnguessableToken AudioInputDeviceManager::Open( audio_system_->GetInputDeviceInfo( device.id, base::BindOnce(&AudioInputDeviceManager::OpenedOnIOThread, - base::Unretained(this), session_id, device, - base::TimeTicks::Now())); + base::Unretained(this), session_id, device)); } return session_id; @@ -170,8 +167,8 @@ void AudioInputDeviceManager::Close(const base::UnguessableToken& session_id) { // Post a callback through the listener on IO thread since // MediaStreamManager is expecting the callback asynchronously. - base::PostTask(FROM_HERE, {BrowserThread::IO}, - base::BindOnce(&AudioInputDeviceManager::ClosedOnIOThread, + GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&AudioInputDeviceManager::ClosedOnIOThread, this, stream_type, session_id)); } @@ -200,8 +197,8 @@ void AudioInputDeviceManager::KeyboardMicRegistration::DeregisterIfNeeded() { --*shared_registration_count_; DCHECK_GE(*shared_registration_count_, 0); if (*shared_registration_count_ == 0) { - base::PostTask( - FROM_HERE, {BrowserThread::UI}, + GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&SetKeyboardMicStreamActiveOnUIThread, false)); } } @@ -217,9 +214,8 @@ void AudioInputDeviceManager::RegisterKeyboardMicStream( ++keyboard_mic_streams_count_; if (keyboard_mic_streams_count_ == 1) { - base::PostTaskAndReply( - FROM_HERE, {BrowserThread::UI}, - base::BindOnce(&SetKeyboardMicStreamActiveOnUIThread, true), + GetUIThreadTaskRunner({})->PostTaskAndReply( + FROM_HERE, base::BindOnce(&SetKeyboardMicStreamActiveOnUIThread, true), base::BindOnce(std::move(callback), KeyboardMicRegistration(&keyboard_mic_streams_count_))); } else { @@ -232,7 +228,6 @@ void AudioInputDeviceManager::RegisterKeyboardMicStream( void AudioInputDeviceManager::OpenedOnIOThread( const base::UnguessableToken& session_id, const blink::MediaStreamDevice& device, - base::TimeTicks start_time, const base::Optional<media::AudioParameters>& input_params, const base::Optional<std::string>& matched_output_device_id) { DCHECK_CURRENTLY_ON(BrowserThread::IO); @@ -240,10 +235,7 @@ void AudioInputDeviceManager::OpenedOnIOThread( DCHECK(!input_params || input_params->IsValid()); DCHECK(!matched_output_device_id || !matched_output_device_id->empty()); - UMA_HISTOGRAM_TIMES("Media.AudioInputDeviceManager.OpenOnDeviceThreadTime", - base::TimeTicks::Now() - start_time); SendAudioLogMessage("Opened({session_id=" + session_id.ToString() + "})"); - blink::MediaStreamDevice media_stream_device(device.type, device.id, device.name); media_stream_device.set_session_id(session_id); diff --git a/chromium/content/browser/renderer_host/media/audio_input_device_manager.h b/chromium/content/browser/renderer_host/media/audio_input_device_manager.h index c534ea09c63..17008e13bec 100644 --- a/chromium/content/browser/renderer_host/media/audio_input_device_manager.h +++ b/chromium/content/browser/renderer_host/media/audio_input_device_manager.h @@ -94,7 +94,6 @@ class CONTENT_EXPORT AudioInputDeviceManager : public MediaStreamProvider { void OpenedOnIOThread( const base::UnguessableToken& session_id, const blink::MediaStreamDevice& device, - base::TimeTicks start_time, const base::Optional<media::AudioParameters>& input_params, const base::Optional<std::string>& matched_output_device_id); diff --git a/chromium/content/browser/renderer_host/media/audio_output_authorization_handler.cc b/chromium/content/browser/renderer_host/media/audio_output_authorization_handler.cc index 760a8169262..adfe08bc33f 100644 --- a/chromium/content/browser/renderer_host/media/audio_output_authorization_handler.cc +++ b/chromium/content/browser/renderer_host/media/audio_output_authorization_handler.cc @@ -6,7 +6,6 @@ #include "base/bind.h" #include "base/metrics/histogram_macros.h" -#include "base/task/post_task.h" #include "base/task_runner_util.h" #include "base/trace_event/trace_event.h" #include "content/browser/media/media_devices_permission_checker.h" @@ -170,8 +169,8 @@ void AudioOutputAuthorizationHandler::RequestDeviceAuthorization( trace_scope->UsingSessionId(session_id, device->id); // We don't need the origin for authorization in this case, but it's used // for hashing the device id before sending it back to the renderer. - base::PostTaskAndReplyWithResult( - FROM_HERE, {BrowserThread::UI}, + GetUIThreadTaskRunner({})->PostTaskAndReplyWithResult( + FROM_HERE, base::BindOnce(&GetMediaDeviceSaltAndOrigin, render_process_id_, render_frame_id), base::BindOnce(&AudioOutputAuthorizationHandler::HashDeviceId, @@ -191,8 +190,8 @@ void AudioOutputAuthorizationHandler::RequestDeviceAuthorization( trace_scope->CheckAccessStart(device_id); // Check device permissions if nondefault device is requested. - base::PostTask( - FROM_HERE, {BrowserThread::UI}, + GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&CheckAccessOnUIThread, render_process_id_, render_frame_id, override_permissions_, permissions_override_value_, diff --git a/chromium/content/browser/renderer_host/media/audio_output_authorization_handler_unittest.cc b/chromium/content/browser/renderer_host/media/audio_output_authorization_handler_unittest.cc index 3ae089addba..173428c097b 100644 --- a/chromium/content/browser/renderer_host/media/audio_output_authorization_handler_unittest.cc +++ b/chromium/content/browser/renderer_host/media/audio_output_authorization_handler_unittest.cc @@ -9,9 +9,9 @@ #include "base/bind.h" #include "base/command_line.h" #include "base/run_loop.h" -#include "base/task/post_task.h" #include "base/test/mock_callback.h" #include "content/public/browser/browser_task_traits.h" +#include "content/public/browser/browser_thread.h" #include "content/public/test/mock_render_process_host.h" #include "content/public/test/test_browser_context.h" #include "content/public/test/test_renderer_host.h" @@ -118,15 +118,15 @@ class AudioOutputAuthorizationHandlerTest : public RenderViewHostTestHarness { // enough for our code. for (int i = 0; i < 20; ++i) { base::RunLoop().RunUntilIdle(); - SyncWith(base::CreateSingleThreadTaskRunner({BrowserThread::IO})); + SyncWith(GetIOThreadTaskRunner({})); SyncWith(audio_manager_->GetWorkerTaskRunner()); } } std::string GetRawNondefaultId() { std::string id; - base::PostTask( - FROM_HERE, {BrowserThread::IO}, + GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce( &AudioOutputAuthorizationHandlerTest::GetRawNondefaultIdOnIOThread, base::Unretained(this), base::Unretained(&id))); @@ -187,15 +187,15 @@ TEST_F(AudioOutputAuthorizationHandlerTest, AuthorizeDefaultDevice_Ok) { std::make_unique<AudioOutputAuthorizationHandler>( GetAudioSystem(), GetMediaStreamManager(), process()->GetID()); - base::PostTask( - FROM_HERE, {BrowserThread::IO}, + GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce( &AudioOutputAuthorizationHandler::RequestDeviceAuthorization, base::Unretained(handler.get()), main_rfh()->GetRoutingID(), base::UnguessableToken(), kDefaultDeviceId, listener.Get())); SyncWithAllThreads(); - base::DeleteSoon(FROM_HERE, {BrowserThread::IO}, handler.release()); + GetIOThreadTaskRunner({})->DeleteSoon(FROM_HERE, handler.release()); SyncWithAllThreads(); } @@ -209,15 +209,15 @@ TEST_F(AudioOutputAuthorizationHandlerTest, std::make_unique<AudioOutputAuthorizationHandler>( GetAudioSystem(), GetMediaStreamManager(), process()->GetID()); - base::PostTask( - FROM_HERE, {BrowserThread::IO}, + GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce( &AudioOutputAuthorizationHandler::RequestDeviceAuthorization, base::Unretained(handler.get()), main_rfh()->GetRoutingID(), base::UnguessableToken(), kEmptyDeviceId, listener.Get())); SyncWithAllThreads(); - base::DeleteSoon(FROM_HERE, {BrowserThread::IO}, handler.release()); + GetIOThreadTaskRunner({})->DeleteSoon(FROM_HERE, handler.release()); SyncWithAllThreads(); } @@ -234,8 +234,8 @@ TEST_F(AudioOutputAuthorizationHandlerTest, std::unique_ptr<AudioOutputAuthorizationHandler> handler = std::make_unique<AudioOutputAuthorizationHandler>( GetAudioSystem(), GetMediaStreamManager(), process()->GetID()); - base::PostTask( - FROM_HERE, {BrowserThread::IO}, + GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce( &AudioOutputAuthorizationHandler::OverridePermissionsForTesting, base::Unretained(handler.get()), false)); @@ -245,15 +245,15 @@ TEST_F(AudioOutputAuthorizationHandlerTest, std::string(), std::string())) .Times(1); - base::PostTask( - FROM_HERE, {BrowserThread::IO}, + GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce( &AudioOutputAuthorizationHandler::RequestDeviceAuthorization, base::Unretained(handler.get()), main_rfh()->GetRoutingID(), base::UnguessableToken(), hashed_id, listener.Get())); SyncWithAllThreads(); - base::DeleteSoon(FROM_HERE, {BrowserThread::IO}, handler.release()); + GetIOThreadTaskRunner({})->DeleteSoon(FROM_HERE, handler.release()); SyncWithAllThreads(); } @@ -269,8 +269,8 @@ TEST_F(AudioOutputAuthorizationHandlerTest, std::unique_ptr<AudioOutputAuthorizationHandler> handler = std::make_unique<AudioOutputAuthorizationHandler>( GetAudioSystem(), GetMediaStreamManager(), process()->GetID()); - base::PostTask( - FROM_HERE, {BrowserThread::IO}, + GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce( &AudioOutputAuthorizationHandler::OverridePermissionsForTesting, base::Unretained(handler.get()), true)); @@ -279,15 +279,15 @@ TEST_F(AudioOutputAuthorizationHandlerTest, raw_nondefault_id, std::string())) .Times(1); - base::PostTask( - FROM_HERE, {BrowserThread::IO}, + GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce( &AudioOutputAuthorizationHandler::RequestDeviceAuthorization, base::Unretained(handler.get()), main_rfh()->GetRoutingID(), base::UnguessableToken(), hashed_id, listener.Get())); SyncWithAllThreads(); - base::DeleteSoon(FROM_HERE, {BrowserThread::IO}, handler.release()); + GetIOThreadTaskRunner({})->DeleteSoon(FROM_HERE, handler.release()); SyncWithAllThreads(); } @@ -301,8 +301,8 @@ TEST_F(AudioOutputAuthorizationHandlerTest, AuthorizeInvalidDeviceId_NotFound) { std::string(), std::string())) .Times(1); - base::PostTask( - FROM_HERE, {BrowserThread::IO}, + GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce( &AudioOutputAuthorizationHandler::RequestDeviceAuthorization, base::Unretained(handler.get()), main_rfh()->GetRoutingID(), @@ -312,7 +312,7 @@ TEST_F(AudioOutputAuthorizationHandlerTest, AuthorizeInvalidDeviceId_NotFound) { // It is possible to request an invalid device id from JS APIs, // so we don't want to crash the renderer for this. EXPECT_EQ(process()->bad_msg_count(), 0); - base::DeleteSoon(FROM_HERE, {BrowserThread::IO}, handler.release()); + GetIOThreadTaskRunner({})->DeleteSoon(FROM_HERE, handler.release()); SyncWithAllThreads(); } @@ -336,8 +336,8 @@ TEST_F(AudioOutputAuthorizationHandlerTest, std::string(), std::string())) .Times(1); - base::PostTask( - FROM_HERE, {BrowserThread::IO}, + GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce( &AudioOutputAuthorizationHandler::RequestDeviceAuthorization, base::Unretained(handler.get()), main_rfh()->GetRoutingID(), @@ -345,7 +345,7 @@ TEST_F(AudioOutputAuthorizationHandlerTest, SyncWithAllThreads(); EXPECT_EQ(process()->bad_msg_count(), 0); - base::DeleteSoon(FROM_HERE, {BrowserThread::IO}, handler.release()); + GetIOThreadTaskRunner({})->DeleteSoon(FROM_HERE, handler.release()); SyncWithAllThreads(); } @@ -360,15 +360,15 @@ TEST_F(AudioOutputAuthorizationHandlerTest, std::string())) .Times(1); - base::PostTask( - FROM_HERE, {BrowserThread::IO}, + GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce( &AudioOutputAuthorizationHandler::RequestDeviceAuthorization, base::Unretained(handler.get()), main_rfh()->GetRoutingID(), base::UnguessableToken::Create(), std::string(), listener.Get())); SyncWithAllThreads(); - base::DeleteSoon(FROM_HERE, {BrowserThread::IO}, handler.release()); + GetIOThreadTaskRunner({})->DeleteSoon(FROM_HERE, handler.release()); SyncWithAllThreads(); } @@ -384,16 +384,16 @@ TEST_F(AudioOutputAuthorizationHandlerTest, std::unique_ptr<AudioOutputAuthorizationHandler> handler = std::make_unique<AudioOutputAuthorizationHandler>( GetAudioSystem(), GetMediaStreamManager(), process()->GetID()); - base::PostTask( - FROM_HERE, {BrowserThread::IO}, + GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce( &AudioOutputAuthorizationHandler::OverridePermissionsForTesting, base::Unretained(handler.get()), true)); EXPECT_CALL(listener, Run(media::OUTPUT_DEVICE_STATUS_OK, _, raw_nondefault_id, std::string())); - base::PostTask( - FROM_HERE, {BrowserThread::IO}, + GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce( &AudioOutputAuthorizationHandler::RequestDeviceAuthorization, base::Unretained(handler.get()), main_rfh()->GetRoutingID(), @@ -408,15 +408,15 @@ TEST_F(AudioOutputAuthorizationHandlerTest, context->set_media_device_id_salt("new salt"); EXPECT_CALL(listener, Run(media::OUTPUT_DEVICE_STATUS_ERROR_NOT_FOUND, _, _, std::string())); - base::PostTask( - FROM_HERE, {BrowserThread::IO}, + GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce( &AudioOutputAuthorizationHandler::RequestDeviceAuthorization, base::Unretained(handler.get()), main_rfh()->GetRoutingID(), base::UnguessableToken(), hashed_id, listener.Get())); SyncWithAllThreads(); - base::DeleteSoon(FROM_HERE, {BrowserThread::IO}, handler.release()); + GetIOThreadTaskRunner({})->DeleteSoon(FROM_HERE, handler.release()); SyncWithAllThreads(); } diff --git a/chromium/content/browser/renderer_host/media/in_process_video_capture_device_launcher.cc b/chromium/content/browser/renderer_host/media/in_process_video_capture_device_launcher.cc index def79b7ed57..a0d5196417f 100644 --- a/chromium/content/browser/renderer_host/media/in_process_video_capture_device_launcher.cc +++ b/chromium/content/browser/renderer_host/media/in_process_video_capture_device_launcher.cc @@ -11,7 +11,6 @@ #include "base/command_line.h" #include "base/metrics/histogram_macros.h" #include "base/strings/stringprintf.h" -#include "base/task/post_task.h" #include "build/build_config.h" #include "content/browser/renderer_host/media/in_process_launched_video_capture_device.h" #include "content/browser/renderer_host/media/video_capture_controller.h" @@ -55,8 +54,7 @@ namespace { std::unique_ptr<media::VideoCaptureJpegDecoder> CreateGpuJpegDecoder( media::VideoCaptureJpegDecoder::DecodeDoneCB decode_done_cb, base::RepeatingCallback<void(const std::string&)> send_log_message_cb) { - auto io_task_runner = - base::CreateSingleThreadTaskRunner({content::BrowserThread::IO}); + auto io_task_runner = content::GetIOThreadTaskRunner({}); return std::make_unique<media::ScopedVideoCaptureJpegDecoder>( std::make_unique<media::VideoCaptureJpegDecoderImpl>( base::BindRepeating( @@ -111,8 +109,7 @@ void InProcessVideoCaptureDeviceLauncher::LaunchDeviceAsync( // Wrap the receiver, to trampoline all its method calls from the device // to the IO thread. auto receiver = std::make_unique<media::VideoFrameReceiverOnTaskRunner>( - receiver_on_io_thread, - base::CreateSingleThreadTaskRunner({BrowserThread::IO})); + receiver_on_io_thread, GetIOThreadTaskRunner({})); base::OnceClosure start_capture_closure; // Use of Unretained |this| is safe, because |done_cb| guarantees that |this| diff --git a/chromium/content/browser/renderer_host/media/media_capture_devices_impl.cc b/chromium/content/browser/renderer_host/media/media_capture_devices_impl.cc index 41d390bd896..a00bedff6e0 100644 --- a/chromium/content/browser/renderer_host/media/media_capture_devices_impl.cc +++ b/chromium/content/browser/renderer_host/media/media_capture_devices_impl.cc @@ -5,7 +5,6 @@ #include "content/browser/renderer_host/media/media_capture_devices_impl.h" #include "base/bind.h" -#include "base/task/post_task.h" #include "content/browser/browser_main_loop.h" #include "content/browser/renderer_host/media/media_stream_manager.h" #include "content/public/browser/browser_task_traits.h" @@ -17,8 +16,8 @@ namespace { void EnsureMonitorCaptureDevices() { DCHECK_CURRENTLY_ON(BrowserThread::UI); - base::PostTask( - FROM_HERE, {BrowserThread::IO}, + GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce( &MediaStreamManager::EnsureDeviceMonitorStarted, base::Unretained( @@ -60,8 +59,8 @@ void MediaCaptureDevicesImpl::AddVideoCaptureObserver( MediaStreamManager* media_stream_manager = BrowserMainLoop::GetInstance()->media_stream_manager(); if (media_stream_manager != nullptr) { - base::PostTask( - FROM_HERE, {BrowserThread::IO}, + GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&MediaStreamManager::AddVideoCaptureObserver, base::Unretained(media_stream_manager), observer)); } else { @@ -73,8 +72,8 @@ void MediaCaptureDevicesImpl::RemoveAllVideoCaptureObservers() { MediaStreamManager* media_stream_manager = BrowserMainLoop::GetInstance()->media_stream_manager(); if (media_stream_manager != nullptr) { - base::PostTask( - FROM_HERE, {BrowserThread::IO}, + GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&MediaStreamManager::RemoveAllVideoCaptureObservers, base::Unretained(media_stream_manager))); } else { @@ -87,8 +86,8 @@ void MediaCaptureDevicesImpl::OnAudioCaptureDevicesChanged( if (BrowserThread::CurrentlyOn(BrowserThread::UI)) { UpdateAudioDevicesOnUIThread(devices); } else { - base::PostTask( - FROM_HERE, {BrowserThread::UI}, + GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&MediaCaptureDevicesImpl::UpdateAudioDevicesOnUIThread, base::Unretained(this), devices)); } @@ -99,8 +98,8 @@ void MediaCaptureDevicesImpl::OnVideoCaptureDevicesChanged( if (BrowserThread::CurrentlyOn(BrowserThread::UI)) { UpdateVideoDevicesOnUIThread(devices); } else { - base::PostTask( - FROM_HERE, {BrowserThread::UI}, + GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&MediaCaptureDevicesImpl::UpdateVideoDevicesOnUIThread, base::Unretained(this), devices)); } diff --git a/chromium/content/browser/renderer_host/media/media_devices_dispatcher_host.cc b/chromium/content/browser/renderer_host/media/media_devices_dispatcher_host.cc index a06e23c2aa4..eb26134fc0f 100644 --- a/chromium/content/browser/renderer_host/media/media_devices_dispatcher_host.cc +++ b/chromium/content/browser/renderer_host/media/media_devices_dispatcher_host.cc @@ -12,9 +12,12 @@ #include "base/bind.h" #include "base/bind_helpers.h" #include "base/command_line.h" +#include "base/run_loop.h" #include "base/task/post_task.h" #include "base/task_runner_util.h" #include "content/browser/bad_message.h" +#include "content/browser/frame_host/back_forward_cache_impl.h" +#include "content/browser/frame_host/render_frame_host_impl.h" #include "content/browser/media/media_devices_permission_checker.h" #include "content/browser/renderer_host/media/media_stream_manager.h" #include "content/browser/renderer_host/media/video_capture_manager.h" @@ -22,7 +25,6 @@ #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/media_device_id.h" -#include "content/public/browser/render_frame_host.h" #include "media/audio/audio_system.h" #include "media/base/media_switches.h" #include "media/base/video_facing.h" @@ -71,6 +73,21 @@ void MediaDevicesDispatcherHost::Create( std::make_unique<MediaDevicesDispatcherHost>( render_process_id, render_frame_id, media_stream_manager), std::move(receiver)); + + base::PostTask(FROM_HERE, {BrowserThread::UI}, + base::BindOnce( + [](int render_process_id, int render_frame_id) { + RenderFrameHost* render_frame_host = + RenderFrameHost::FromID(render_process_id, + render_frame_id); + + if (!render_frame_host) + return; + + BackForwardCache::DisableForRenderFrameHost( + render_frame_host, "MediaDevicesDispatcherHost"); + }, + render_process_id, render_frame_id)); } MediaDevicesDispatcherHost::MediaDevicesDispatcherHost( @@ -132,7 +149,7 @@ void MediaDevicesDispatcherHost::GetVideoInputCapabilities( GetVideoInputCapabilitiesCallback client_callback) { DCHECK_CURRENTLY_ON(BrowserThread::IO); base::PostTaskAndReplyWithResult( - base::CreateSingleThreadTaskRunner({BrowserThread::UI}).get(), FROM_HERE, + GetUIThreadTaskRunner({}).get(), FROM_HERE, base::BindOnce(media_stream_manager_->media_devices_manager() ->salt_and_origin_callback(), render_process_id_, render_frame_id_), @@ -159,7 +176,7 @@ void MediaDevicesDispatcherHost::GetAvailableVideoInputDeviceFormats( void MediaDevicesDispatcherHost::GetAudioInputCapabilities( GetAudioInputCapabilitiesCallback client_callback) { base::PostTaskAndReplyWithResult( - base::CreateSingleThreadTaskRunner({BrowserThread::UI}).get(), FROM_HERE, + GetUIThreadTaskRunner({}).get(), FROM_HERE, base::BindOnce(media_stream_manager_->media_devices_manager() ->salt_and_origin_callback(), render_process_id_, render_frame_id_), @@ -249,6 +266,8 @@ void MediaDevicesDispatcherHost::FinalizeGetVideoInputCapabilities( media_stream_manager_->media_devices_manager()->GetVideoInputFormats( device_info.device_id, true /* try_in_use_first */); capabilities->facing_mode = device_info.video_facing; + capabilities->pan_tilt_zoom_supported = + device_info.pan_tilt_zoom_supported.value_or(false); if (device_info.device_id == default_device_id) { video_input_capabilities.insert(video_input_capabilities.begin(), std::move(capabilities)); @@ -266,7 +285,7 @@ void MediaDevicesDispatcherHost::GetVideoInputDeviceFormats( GetVideoInputDeviceFormatsCallback client_callback) { DCHECK_CURRENTLY_ON(BrowserThread::IO); base::PostTaskAndReplyWithResult( - base::CreateSingleThreadTaskRunner({BrowserThread::UI}).get(), FROM_HERE, + GetUIThreadTaskRunner({}).get(), FROM_HERE, base::BindOnce(media_stream_manager_->media_devices_manager() ->salt_and_origin_callback(), render_process_id_, render_frame_id_), diff --git a/chromium/content/browser/renderer_host/media/media_devices_manager.cc b/chromium/content/browser/renderer_host/media/media_devices_manager.cc index 10610f0c455..c3337edfa39 100644 --- a/chromium/content/browser/renderer_host/media/media_devices_manager.cc +++ b/chromium/content/browser/renderer_host/media/media_devices_manager.cc @@ -334,8 +334,8 @@ class MediaDevicesManager::AudioServiceDeviceListener DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(!mojo_audio_device_notifier_); DCHECK(!receiver_.is_bound()); - base::PostTask( - FROM_HERE, {BrowserThread::UI}, + GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce( &BindDeviceNotifierFromUIThread, mojo_audio_device_notifier_.BindNewPipeAndPassReceiver())); @@ -439,7 +439,7 @@ void MediaDevicesManager::EnumerateDevices( request_video_input_capabilities ? "true" : "false")); base::PostTaskAndReplyWithResult( - base::CreateSingleThreadTaskRunner({BrowserThread::UI}).get(), FROM_HERE, + GetUIThreadTaskRunner({}).get(), FROM_HERE, base::BindOnce(salt_and_origin_callback_, render_process_id, render_frame_id), base::BindOnce(&MediaDevicesManager::CheckPermissionsForEnumerateDevices, @@ -525,8 +525,8 @@ void MediaDevicesManager::StartMonitoring() { } #if defined(OS_MACOSX) - base::PostTask(FROM_HERE, {BrowserThread::UI}, - base::BindOnce(&MediaDevicesManager::StartMonitoringOnUIThread, + GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&MediaDevicesManager::StartMonitoringOnUIThread, base::Unretained(this))); #endif } @@ -769,8 +769,8 @@ void MediaDevicesManager::GetAudioInputCapabilities( size_t capabilities_index = enumeration_states_[state_id].audio_capabilities.size() - 1; if (use_fake_devices_) { - base::PostTask( - FROM_HERE, {BrowserThread::IO}, + GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&MediaDevicesManager::GotAudioInputCapabilities, weak_factory_.GetWeakPtr(), state_id, capabilities_index, @@ -1111,8 +1111,7 @@ void MediaDevicesManager::NotifyDeviceChangeSubscribers( const SubscriptionRequest& request = subscription.second; if (request.subscribe_types[type]) { base::PostTaskAndReplyWithResult( - base::CreateSingleThreadTaskRunner({BrowserThread::UI}).get(), - FROM_HERE, + GetUIThreadTaskRunner({}).get(), FROM_HERE, base::BindOnce(salt_and_origin_callback_, request.render_process_id, request.render_frame_id), base::BindOnce(&MediaDevicesManager::CheckPermissionForDeviceChange, diff --git a/chromium/content/browser/renderer_host/media/media_stream_dispatcher_host.cc b/chromium/content/browser/renderer_host/media/media_stream_dispatcher_host.cc index cf2716e593b..3e43ba7ad5c 100644 --- a/chromium/content/browser/renderer_host/media/media_stream_dispatcher_host.cc +++ b/chromium/content/browser/renderer_host/media/media_stream_dispatcher_host.cc @@ -102,8 +102,8 @@ MediaStreamDispatcherHost::GetMediaStreamDeviceObserver() { media_stream_device_observer_.set_disconnect_handler(base::BindOnce( &MediaStreamDispatcherHost::OnMediaStreamDeviceObserverConnectionError, weak_factory_.GetWeakPtr())); - base::PostTask( - FROM_HERE, {BrowserThread::UI}, + GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&BindMediaStreamDeviceObserverReceiver, render_process_id_, render_frame_id_, std::move(dispatcher_receiver))); return media_stream_device_observer_; @@ -138,7 +138,7 @@ void MediaStreamDispatcherHost::GenerateStream( } base::PostTaskAndReplyWithResult( - base::CreateSingleThreadTaskRunner({BrowserThread::UI}).get(), FROM_HERE, + GetUIThreadTaskRunner({}).get(), FROM_HERE, base::BindOnce(salt_and_origin_callback_, render_process_id_, render_frame_id_), base::BindOnce(&MediaStreamDispatcherHost::DoGenerateStream, @@ -159,8 +159,8 @@ void MediaStreamDispatcherHost::DoGenerateStream( salt_and_origin.origin)) { std::move(callback).Run( blink::mojom::MediaStreamRequestResult::INVALID_SECURITY_ORIGIN, - std::string(), blink::MediaStreamDevices(), - blink::MediaStreamDevices()); + std::string(), blink::MediaStreamDevices(), blink::MediaStreamDevices(), + /*pan_tilt_zoom_allowed=*/false); return; } @@ -198,7 +198,7 @@ void MediaStreamDispatcherHost::OpenDevice(int32_t page_request_id, DCHECK_CURRENTLY_ON(BrowserThread::IO); base::PostTaskAndReplyWithResult( - base::CreateSingleThreadTaskRunner({BrowserThread::UI}).get(), FROM_HERE, + GetUIThreadTaskRunner({}).get(), FROM_HERE, base::BindOnce(salt_and_origin_callback_, render_process_id_, render_frame_id_), base::BindOnce(&MediaStreamDispatcherHost::DoOpenDevice, diff --git a/chromium/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc b/chromium/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc index beccf8a5425..d1e3cf88016 100644 --- a/chromium/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc +++ b/chromium/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc @@ -160,7 +160,8 @@ class MockMediaStreamDispatcherHost blink::mojom::MediaStreamRequestResult result, const std::string& label, const blink::MediaStreamDevices& audio_devices, - const blink::MediaStreamDevices& video_devices) { + const blink::MediaStreamDevices& video_devices, + bool pan_tilt_zoom_allowed) { if (result != blink::mojom::MediaStreamRequestResult::OK) { OnStreamGenerationFailed(request_id, result); return; diff --git a/chromium/content/browser/renderer_host/media/media_stream_manager.cc b/chromium/content/browser/renderer_host/media/media_stream_manager.cc index 3d4610db625..0929cab302e 100644 --- a/chromium/content/browser/renderer_host/media/media_stream_manager.cc +++ b/chromium/content/browser/renderer_host/media/media_stream_manager.cc @@ -19,12 +19,12 @@ #include "base/logging.h" #include "base/memory/ptr_util.h" #include "base/power_monitor/power_monitor.h" +#include "base/power_monitor/power_monitor_source.h" #include "base/rand_util.h" #include "base/stl_util.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" -#include "base/task/post_task.h" #include "base/task_runner_util.h" #include "base/threading/thread.h" #include "base/threading/thread_local.h" @@ -32,6 +32,7 @@ #include "content/browser/child_process_security_policy_impl.h" #include "content/browser/gpu/gpu_process_host.h" #include "content/browser/media/capture/desktop_capture_device_uma_types.h" +#include "content/browser/media/media_devices_permission_checker.h" #include "content/browser/renderer_host/media/audio_input_device_manager.h" #include "content/browser/renderer_host/media/audio_service_listener.h" #include "content/browser/renderer_host/media/in_process_video_capture_provider.h" @@ -605,7 +606,8 @@ class MediaStreamManager::DeviceRequest { if (generate_stream_cb) { std::move(generate_stream_cb) .Run(MediaStreamRequestResult::FAILED_DUE_TO_SHUTDOWN, std::string(), - MediaStreamDevices(), MediaStreamDevices()); + MediaStreamDevices(), MediaStreamDevices(), + /*pan_tilt_zoom_allowed=*/false); } if (open_device_cb) { @@ -679,8 +681,8 @@ class MediaStreamManager::DeviceRequest { // static void MediaStreamManager::SendMessageToNativeLog(const std::string& message) { if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { - base::PostTask( - FROM_HERE, {BrowserThread::IO}, + GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&MediaStreamManager::SendMessageToNativeLog, message)); return; } @@ -767,7 +769,7 @@ MediaStreamManager::MediaStreamManager( video_capture_provider = InProcessVideoCaptureProvider::CreateInstance( std::make_unique<media::VideoCaptureSystemImpl>( media::CreateVideoCaptureDeviceFactory( - base::CreateSingleThreadTaskRunner({BrowserThread::UI}))), + GetUIThreadTaskRunner({}))), std::move(device_task_runner), base::BindRepeating(&SendVideoCaptureLogMessage)); } @@ -859,8 +861,8 @@ std::string MediaStreamManager::MakeMediaAccessRequest( // and thus can not handle a response. Using base::Unretained is safe since // MediaStreamManager is deleted on the UI thread, after the IO thread has // been stopped. - base::PostTask(FROM_HERE, {BrowserThread::IO}, - base::BindOnce(&MediaStreamManager::SetUpRequest, + GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&MediaStreamManager::SetUpRequest, base::Unretained(this), label)); return label; } @@ -910,8 +912,8 @@ void MediaStreamManager::GenerateStream( // and thus can not handle a response. Using base::Unretained is safe since // MediaStreamManager is deleted on the UI thread, after the IO thread has // been stopped. - base::PostTask(FROM_HERE, {BrowserThread::IO}, - base::BindOnce(&MediaStreamManager::SetUpRequest, + GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&MediaStreamManager::SetUpRequest, base::Unretained(this), label)); } @@ -1133,8 +1135,8 @@ void MediaStreamManager::OpenDevice(int render_process_id, // and thus can not handle a response. Using base::Unretained is safe since // MediaStreamManager is deleted on the UI thread, after the IO thread has // been stopped. - base::PostTask(FROM_HERE, {BrowserThread::IO}, - base::BindOnce(&MediaStreamManager::SetUpRequest, + GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&MediaStreamManager::SetUpRequest, base::Unretained(this), label)); } @@ -1333,8 +1335,6 @@ void MediaStreamManager::ReadOutputParamsAndPostRequestToUI( // Actual audio parameters are required only for // MEDIA_GUM_TAB_AUDIO_CAPTURE. - // TODO(guidou): MEDIA_GUM_TAB_AUDIO_CAPTURE should not be a special - // case. See https://crbug.com/584287. if (request->audio_type() == MediaStreamType::GUM_TAB_AUDIO_CAPTURE) { // Using base::Unretained is safe: |audio_system_| will post // PostRequestToUI() to IO thread, and MediaStreamManager is deleted on the @@ -1555,8 +1555,8 @@ bool MediaStreamManager::SetUpTabCaptureRequest(DeviceRequest* request, return false; } - base::PostTaskAndReplyWithResult( - FROM_HERE, {BrowserThread::UI}, + GetUIThreadTaskRunner({})->PostTaskAndReplyWithResult( + FROM_HERE, base::BindOnce(&MediaStreamManager::ResolveTabCaptureDeviceIdOnUIThread, base::Unretained(this), capture_device_id, request->requesting_process_id, @@ -1763,8 +1763,38 @@ void MediaStreamManager::FinalizeGenerateStream(const std::string& label, NOTREACHED(); } + // It is safe to bind base::Unretained(this) because MediaStreamManager is + // owned by BrowserMainLoop and so outlives the IO thread. + GetUIThreadTaskRunner({})->PostTaskAndReplyWithResult( + FROM_HERE, + base::BindOnce(&MediaDevicesPermissionChecker:: + HasPanTiltZoomPermissionGrantedOnUIThread, + request->requesting_process_id, + request->requesting_frame_id), + base::BindOnce(&MediaStreamManager::PanTiltZoomPermissionChecked, + base::Unretained(this), label, audio_devices, + video_devices)); +} + +void MediaStreamManager::PanTiltZoomPermissionChecked( + const std::string& label, + MediaStreamDevices audio_devices, + MediaStreamDevices video_devices, + bool pan_tilt_zoom_allowed) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + DeviceRequest* request = FindRequest(label); + if (!request) + return; + + SendLogMessage(base::StringPrintf( + "PanTiltZoomPermissionChecked({label=%s}, {requester_id=" + "%d}, {request_type=%s}, {pan_tilt_zoom_allowed=%d})", + label.c_str(), request->requester_id, + RequestTypeToString(request->request_type()), pan_tilt_zoom_allowed)); + std::move(request->generate_stream_cb) - .Run(MediaStreamRequestResult::OK, label, audio_devices, video_devices); + .Run(MediaStreamRequestResult::OK, label, audio_devices, video_devices, + pan_tilt_zoom_allowed); } void MediaStreamManager::FinalizeRequestFailed( @@ -1781,7 +1811,7 @@ void MediaStreamManager::FinalizeRequestFailed( DCHECK(request->generate_stream_cb); std::move(request->generate_stream_cb) .Run(result, std::string(), MediaStreamDevices(), - MediaStreamDevices()); + MediaStreamDevices(), /*pan_tilt_zoom_allowed=*/false); break; } case blink::MEDIA_OPEN_DEVICE_PEPPER_ONLY: { @@ -1804,8 +1834,8 @@ void MediaStreamManager::FinalizeRequestFailed( if (device.type == MediaStreamType::GUM_DESKTOP_VIDEO_CAPTURE) { DesktopMediaID source = DesktopMediaID::Parse(device.id); DCHECK(source.type == DesktopMediaID::TYPE_WEB_CONTENTS); - base::PostTask( - FROM_HERE, {BrowserThread::UI}, + GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&MediaStreamManager::ActivateTabOnUIThread, base::Unretained(this), source)); break; @@ -1891,8 +1921,8 @@ void MediaStreamManager::InitializeMaybeAsync( // initialization is done synchronously. Other clients call this from a // different thread and expect initialization to run asynchronously. if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { - base::PostTask(FROM_HERE, {BrowserThread::IO}, - base::BindOnce(&MediaStreamManager::InitializeMaybeAsync, + GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&MediaStreamManager::InitializeMaybeAsync, base::Unretained(this), std::move(video_capture_provider))); return; @@ -2068,6 +2098,14 @@ void MediaStreamManager::OnResume() { SendLogMessage(base::StringPrintf("OnResume([this=%p])", this)); } +void MediaStreamManager::OnThermalStateChange( + base::PowerObserver::DeviceThermalState new_state) { + const char* state_name = + base::PowerMonitorSource::DeviceThermalStateToString(new_state); + SendLogMessage(base::StringPrintf( + "OnThermalStateChange({this=%p}, {new_state=%s})", this, state_name)); +} + void MediaStreamManager::UseFakeUIFactoryForTests( base::RepeatingCallback<std::unique_ptr<FakeMediaStreamUIProxy>(void)> fake_ui_factory) { @@ -2510,7 +2548,8 @@ MediaStreamDevices MediaStreamManager::ConvertToMediaStreamDevices( MediaStreamDevices devices; for (const auto& info : device_infos) { devices.emplace_back(stream_type, info.device_id, info.label, - info.video_facing, info.group_id); + info.video_facing, info.group_id, + info.pan_tilt_zoom_supported); } return devices; diff --git a/chromium/content/browser/renderer_host/media/media_stream_manager.h b/chromium/content/browser/renderer_host/media/media_stream_manager.h index e0057e5727f..4468b5c9064 100644 --- a/chromium/content/browser/renderer_host/media/media_stream_manager.h +++ b/chromium/content/browser/renderer_host/media/media_stream_manager.h @@ -90,7 +90,8 @@ class CONTENT_EXPORT MediaStreamManager base::OnceCallback<void(blink::mojom::MediaStreamRequestResult result, const std::string& label, const blink::MediaStreamDevices& audio_devices, - const blink::MediaStreamDevices& video_devices)>; + const blink::MediaStreamDevices& video_devices, + bool pan_tilt_zoom_allowed)>; using OpenDeviceCallback = base::OnceCallback<void(bool success, @@ -278,6 +279,8 @@ class CONTENT_EXPORT MediaStreamManager // base::PowerObserver overrides. void OnSuspend() override; void OnResume() override; + void OnThermalStateChange( + base::PowerObserver::DeviceThermalState new_state) override; // Called by the tests to specify a factory for creating // FakeMediaStreamUIProxys to be used for generated streams. @@ -456,6 +459,10 @@ class CONTENT_EXPORT MediaStreamManager MediaRequestState* existing_request_state) const; void FinalizeGenerateStream(const std::string& label, DeviceRequest* request); + void PanTiltZoomPermissionChecked(const std::string& label, + blink::MediaStreamDevices audio_devices, + blink::MediaStreamDevices video_devices, + bool pan_tilt_zoom_allowed); void FinalizeRequestFailed(const std::string& label, DeviceRequest* request, blink::mojom::MediaStreamRequestResult result); diff --git a/chromium/content/browser/renderer_host/media/media_stream_manager_unittest.cc b/chromium/content/browser/renderer_host/media/media_stream_manager_unittest.cc index a6489ccad9e..53722c38ca3 100644 --- a/chromium/content/browser/renderer_host/media/media_stream_manager_unittest.cc +++ b/chromium/content/browser/renderer_host/media/media_stream_manager_unittest.cc @@ -325,7 +325,8 @@ class MediaStreamManagerTest : public ::testing::Test { blink::mojom::MediaStreamRequestResult result, const std::string& label, const blink::MediaStreamDevices& audio_devices, - const blink::MediaStreamDevices& video_devices) { + const blink::MediaStreamDevices& video_devices, + bool pan_tilt_zoom_allowed) { if (request_audio) { EXPECT_EQ(1u, audio_devices.size()); *audio_device = audio_devices[0]; @@ -697,7 +698,8 @@ TEST_F(MediaStreamManagerTest, GetDisplayMediaRequestCallsUIProxy) { base::BindOnce([](blink::mojom::MediaStreamRequestResult result, const std::string& label, const blink::MediaStreamDevices& audio_devices, - const blink::MediaStreamDevices& video_devices) {}); + const blink::MediaStreamDevices& video_devices, + bool pan_tilt_zoom_allowed) {}); EXPECT_CALL( *media_observer_, OnMediaRequestStateChanged( diff --git a/chromium/content/browser/renderer_host/media/media_stream_ui_proxy.cc b/chromium/content/browser/renderer_host/media/media_stream_ui_proxy.cc index 4966540938f..63d1744a77c 100644 --- a/chromium/content/browser/renderer_host/media/media_stream_ui_proxy.cc +++ b/chromium/content/browser/renderer_host/media/media_stream_ui_proxy.cc @@ -9,7 +9,6 @@ #include "base/bind.h" #include "base/command_line.h" #include "base/macros.h" -#include "base/task/post_task.h" #include "content/browser/frame_host/frame_tree_node.h" #include "content/browser/frame_host/render_frame_host_delegate.h" #include "content/browser/frame_host/render_frame_host_impl.h" @@ -183,8 +182,8 @@ void MediaStreamUIProxy::Core::ProcessAccessRequestResponse( if (host && result == blink::mojom::MediaStreamRequestResult::OK) host->OnGrantedMediaStreamAccess(); - base::PostTask( - FROM_HERE, {BrowserThread::IO}, + GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&MediaStreamUIProxy::ProcessAccessRequestResponse, proxy_, filtered_devices, result)); } @@ -192,8 +191,8 @@ void MediaStreamUIProxy::Core::ProcessAccessRequestResponse( void MediaStreamUIProxy::Core::ProcessStopRequestFromUI() { DCHECK_CURRENTLY_ON(BrowserThread::UI); - base::PostTask( - FROM_HERE, {BrowserThread::IO}, + GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&MediaStreamUIProxy::ProcessStopRequestFromUI, proxy_)); } @@ -201,8 +200,8 @@ void MediaStreamUIProxy::Core::ProcessChangeSourceRequestFromUI( const DesktopMediaID& media_id) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - base::PostTask( - FROM_HERE, {BrowserThread::IO}, + GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&MediaStreamUIProxy::ProcessChangeSourceRequestFromUI, proxy_, media_id)); } @@ -245,8 +244,8 @@ void MediaStreamUIProxy::RequestAccess( DCHECK_CURRENTLY_ON(BrowserThread::IO); response_callback_ = std::move(response_callback); - base::PostTask( - FROM_HERE, {BrowserThread::UI}, + GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&Core::RequestAccess, base::Unretained(core_.get()), std::move(request))); } @@ -263,8 +262,8 @@ void MediaStreamUIProxy::OnStarted( // Owned by the PostTaskAndReply callback. gfx::NativeViewId* window_id = new gfx::NativeViewId(0); - base::PostTaskAndReply( - FROM_HERE, {BrowserThread::UI}, + GetUIThreadTaskRunner({})->PostTaskAndReply( + FROM_HERE, base::BindOnce(&Core::OnStarted, base::Unretained(core_.get()), window_id, !!source_callback_), base::BindOnce(&MediaStreamUIProxy::OnWindowId, @@ -334,8 +333,8 @@ void FakeMediaStreamUIProxy::RequestAccess( if (base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( switches::kUseFakeUIForMediaStream) == "deny") { // Immediately deny the request. - base::PostTask( - FROM_HERE, {BrowserThread::UI}, + GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce( &MediaStreamUIProxy::Core::ProcessAccessRequestResponse, base::Unretained(core_.get()), request->render_process_id, @@ -377,8 +376,8 @@ void FakeMediaStreamUIProxy::RequestAccess( devices_to_use.clear(); } - base::PostTask( - FROM_HERE, {BrowserThread::UI}, + GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&MediaStreamUIProxy::Core::ProcessAccessRequestResponse, base::Unretained(core_.get()), request->render_process_id, request->render_frame_id, devices_to_use, diff --git a/chromium/content/browser/renderer_host/media/media_stream_ui_proxy_unittest.cc b/chromium/content/browser/renderer_host/media/media_stream_ui_proxy_unittest.cc index d8bd747edd1..802c06f0d90 100644 --- a/chromium/content/browser/renderer_host/media/media_stream_ui_proxy_unittest.cc +++ b/chromium/content/browser/renderer_host/media/media_stream_ui_proxy_unittest.cc @@ -10,11 +10,11 @@ #include "base/bind.h" #include "base/callback_helpers.h" #include "base/run_loop.h" -#include "base/task/post_task.h" #include "base/test/gmock_move_support.h" #include "build/build_config.h" #include "content/browser/frame_host/render_frame_host_delegate.h" #include "content/public/browser/browser_task_traits.h" +#include "content/public/browser/browser_thread.h" #include "content/public/browser/media_stream_request.h" #include "content/public/test/browser_task_environment.h" #include "content/test/test_render_frame_host.h" @@ -393,8 +393,8 @@ class MediaStreamUIProxyFeaturePolicyTest DCHECK_CURRENTLY_ON(BrowserThread::UI); base::RunLoop run_loop; quit_closure_ = run_loop.QuitClosure(); - base::PostTask( - FROM_HERE, {BrowserThread::IO}, + GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce( &MediaStreamUIProxyFeaturePolicyTest::GetResultForRequestOnIOThread, base::Unretained(this), std::move(request))); @@ -453,8 +453,8 @@ class MediaStreamUIProxyFeaturePolicyTest blink::mojom::MediaStreamRequestResult result) { DCHECK_CURRENTLY_ON(BrowserThread::IO); proxy_.reset(); - base::PostTask( - FROM_HERE, {BrowserThread::UI}, + GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&MediaStreamUIProxyFeaturePolicyTest::FinishedGetResult, base::Unretained(this), devices, result)); } diff --git a/chromium/content/browser/renderer_host/media/peer_connection_tracker_host.cc b/chromium/content/browser/renderer_host/media/peer_connection_tracker_host.cc index 87c9ea24fe9..a1d323a6c63 100644 --- a/chromium/content/browser/renderer_host/media/peer_connection_tracker_host.cc +++ b/chromium/content/browser/renderer_host/media/peer_connection_tracker_host.cc @@ -21,6 +21,13 @@ PeerConnectionTrackerHost::PeerConnectionTrackerHost(RenderProcessHost* rph) DCHECK_CURRENTLY_ON(BrowserThread::UI); base::PowerMonitor::AddObserver(this); rph->BindReceiver(tracker_.BindNewPipeAndPassReceiver()); + // Ensure that the initial thermal state is known by the |tracker_|. + base::PowerObserver::DeviceThermalState initial_thermal_state = + base::PowerMonitor::GetCurrentThermalState(); + if (initial_thermal_state != + base::PowerObserver::DeviceThermalState::kUnknown) { + OnThermalStateChange(initial_thermal_state); + } } PeerConnectionTrackerHost::~PeerConnectionTrackerHost() { @@ -143,6 +150,12 @@ void PeerConnectionTrackerHost::OnSuspend() { tracker_->OnSuspend(); } +void PeerConnectionTrackerHost::OnThermalStateChange( + base::PowerObserver::DeviceThermalState new_state) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + tracker_->OnThermalStateChange(new_state); +} + void PeerConnectionTrackerHost::StartEventLog(int lid, int output_period_ms) { DCHECK_CURRENTLY_ON(BrowserThread::UI); tracker_->StartEventLog(lid, output_period_ms); diff --git a/chromium/content/browser/renderer_host/media/peer_connection_tracker_host.h b/chromium/content/browser/renderer_host/media/peer_connection_tracker_host.h index 65045c68b60..fecc08dfcd5 100644 --- a/chromium/content/browser/renderer_host/media/peer_connection_tracker_host.h +++ b/chromium/content/browser/renderer_host/media/peer_connection_tracker_host.h @@ -36,6 +36,8 @@ class PeerConnectionTrackerHost // base::PowerObserver override. void OnSuspend() override; + void OnThermalStateChange( + base::PowerObserver::DeviceThermalState new_state) override; // These methods call out to blink::mojom::PeerConnectionManager on renderer // side. diff --git a/chromium/content/browser/renderer_host/media/render_frame_audio_input_stream_factory.cc b/chromium/content/browser/renderer_host/media/render_frame_audio_input_stream_factory.cc index fd591ee5428..acc14c66913 100644 --- a/chromium/content/browser/renderer_host/media/render_frame_audio_input_stream_factory.cc +++ b/chromium/content/browser/renderer_host/media/render_frame_audio_input_stream_factory.cc @@ -13,7 +13,6 @@ #include "base/check_op.h" #include "base/location.h" #include "base/memory/weak_ptr.h" -#include "base/task/post_task.h" #include "base/trace_event/trace_event.h" #include "base/unguessable_token.h" #include "content/browser/media/audio_stream_broker.h" @@ -91,8 +90,8 @@ void GetSaltOriginAndPermissionsOnUIThread( auto salt_and_origin = GetMediaDeviceSaltAndOrigin(process_id, frame_id); bool access = MediaDevicesPermissionChecker().CheckPermissionOnUIThread( blink::MEDIA_DEVICE_TYPE_AUDIO_OUTPUT, process_id, frame_id); - base::PostTask( - FROM_HERE, {BrowserThread::IO}, + GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(std::move(cb), std::move(salt_and_origin), access)); } @@ -169,8 +168,8 @@ RenderFrameAudioInputStreamFactory::~RenderFrameAudioInputStreamFactory() { // as it doesn't post in case it is already executed on the right thread. That // causes issues in unit tests where the UI thread and the IO thread are the // same. - base::PostTask( - FROM_HERE, {BrowserThread::IO}, + GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce([](std::unique_ptr<Core>) {}, std::move(core_))); } @@ -198,8 +197,8 @@ RenderFrameAudioInputStreamFactory::Core::Core( // Unretained is safe since the destruction of |this| is posted to the IO // thread. - base::PostTask( - FROM_HERE, {BrowserThread::IO}, + GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&Core::Init, base::Unretained(this), std::move(receiver))); } @@ -244,8 +243,8 @@ void RenderFrameAudioInputStreamFactory::Core::CreateStream( // TODO(qiangchen): Analyze audio constraints to make a duplicating or // diverting decision. It would give web developer more flexibility. - base::PostTaskAndReplyWithResult( - FROM_HERE, {BrowserThread::UI}, + GetUIThreadTaskRunner({})->PostTaskAndReplyWithResult( + FROM_HERE, base::BindOnce(&GetLoopbackSourceOnUIThread, capture_id.render_process_id, capture_id.main_render_frame_id), @@ -294,8 +293,8 @@ void RenderFrameAudioInputStreamFactory::Core::AssociateInputAndOutputForAec( if (!IsValidDeviceId(output_device_id)) return; - base::PostTask( - FROM_HERE, {BrowserThread::UI}, + GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce( &GetSaltOriginAndPermissionsOnUIThread, process_id_, frame_id_, base::BindOnce( diff --git a/chromium/content/browser/renderer_host/media/render_frame_audio_input_stream_factory_unittest.cc b/chromium/content/browser/renderer_host/media/render_frame_audio_input_stream_factory_unittest.cc index 115a2967682..e62a47e5b25 100644 --- a/chromium/content/browser/renderer_host/media/render_frame_audio_input_stream_factory_unittest.cc +++ b/chromium/content/browser/renderer_host/media/render_frame_audio_input_stream_factory_unittest.cc @@ -11,7 +11,6 @@ #include "base/bind_helpers.h" #include "base/macros.h" #include "base/run_loop.h" -#include "base/task/post_task.h" #include "build/build_config.h" #include "content/browser/media/forwarding_audio_stream_factory.h" #include "content/browser/renderer_host/media/audio_input_device_manager.h" @@ -61,9 +60,9 @@ class MAYBE_RenderFrameAudioInputStreamFactoryTest audio_manager_(std::make_unique<media::TestAudioThread>(), &log_factory_), audio_system_(media::AudioSystemImpl::CreateInstance()), - media_stream_manager_(std::make_unique<MediaStreamManager>( - audio_system_.get(), - base::CreateSingleThreadTaskRunner({BrowserThread::UI}))) {} + media_stream_manager_( + std::make_unique<MediaStreamManager>(audio_system_.get(), + GetUIThreadTaskRunner({}))) {} ~MAYBE_RenderFrameAudioInputStreamFactoryTest() override {} diff --git a/chromium/content/browser/renderer_host/media/render_frame_audio_output_stream_factory.cc b/chromium/content/browser/renderer_host/media/render_frame_audio_output_stream_factory.cc index 6c2363b02ef..5f2a7fc6859 100644 --- a/chromium/content/browser/renderer_host/media/render_frame_audio_output_stream_factory.cc +++ b/chromium/content/browser/renderer_host/media/render_frame_audio_output_stream_factory.cc @@ -16,7 +16,6 @@ #include "base/location.h" #include "base/memory/weak_ptr.h" #include "base/optional.h" -#include "base/task/post_task.h" #include "base/time/time.h" #include "base/trace_event/trace_event.h" #include "base/unguessable_token.h" @@ -170,8 +169,8 @@ RenderFrameAudioOutputStreamFactory::~RenderFrameAudioOutputStreamFactory() { // as it doesn't post in case it is already executed on the right thread. That // causes issues in unit tests where the UI thread and the IO thread are the // same. - base::PostTask( - FROM_HERE, {BrowserThread::IO}, + GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce([](std::unique_ptr<Core>) {}, std::move(core_))); } @@ -204,8 +203,8 @@ RenderFrameAudioOutputStreamFactory::Core::Core( // Unretained is safe since the destruction of |this| is posted to the IO // thread. - base::PostTask( - FROM_HERE, {BrowserThread::IO}, + GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&Core::Init, base::Unretained(this), std::move(receiver))); } diff --git a/chromium/content/browser/renderer_host/media/render_frame_audio_output_stream_factory_unittest.cc b/chromium/content/browser/renderer_host/media/render_frame_audio_output_stream_factory_unittest.cc index 1950b393af9..dbe40d2e00a 100644 --- a/chromium/content/browser/renderer_host/media/render_frame_audio_output_stream_factory_unittest.cc +++ b/chromium/content/browser/renderer_host/media/render_frame_audio_output_stream_factory_unittest.cc @@ -12,7 +12,6 @@ #include "base/bind_helpers.h" #include "base/macros.h" #include "base/run_loop.h" -#include "base/task/post_task.h" #include "base/test/mock_callback.h" #include "base/test/task_environment.h" #include "base/unguessable_token.h" @@ -53,9 +52,9 @@ class RenderFrameAudioOutputStreamFactoryTest : audio_manager_(std::make_unique<media::TestAudioThread>(), &log_factory_), audio_system_(media::AudioSystemImpl::CreateInstance()), - media_stream_manager_(std::make_unique<MediaStreamManager>( - audio_system_.get(), - base::CreateSingleThreadTaskRunner({BrowserThread::UI}))) {} + media_stream_manager_( + std::make_unique<MediaStreamManager>(audio_system_.get(), + GetUIThreadTaskRunner({}))) {} ~RenderFrameAudioOutputStreamFactoryTest() override {} diff --git a/chromium/content/browser/renderer_host/media/service_video_capture_device_launcher.cc b/chromium/content/browser/renderer_host/media/service_video_capture_device_launcher.cc index 9d85f8cbd22..b953c5d85c4 100644 --- a/chromium/content/browser/renderer_host/media/service_video_capture_device_launcher.cc +++ b/chromium/content/browser/renderer_host/media/service_video_capture_device_launcher.cc @@ -9,7 +9,6 @@ #include "base/bind.h" #include "base/bind_helpers.h" #include "base/command_line.h" -#include "base/task/post_task.h" #include "content/browser/renderer_host/media/service_launched_video_capture_device.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" @@ -117,8 +116,7 @@ void ServiceVideoCaptureDeviceLauncher::LaunchDeviceAsync( auto receiver_adapter = std::make_unique<video_capture::ReceiverMediaToMojoAdapter>( std::make_unique<media::VideoFrameReceiverOnTaskRunner>( - std::move(receiver), - base::CreateSingleThreadTaskRunner({BrowserThread::IO}))); + std::move(receiver), GetIOThreadTaskRunner({}))); mojo::PendingRemote<video_capture::mojom::VideoFrameHandler> pending_remote_proxy; mojo::MakeSelfOwnedReceiver( diff --git a/chromium/content/browser/renderer_host/media/service_video_capture_provider.cc b/chromium/content/browser/renderer_host/media/service_video_capture_provider.cc index e3f8cea24ec..38164896644 100644 --- a/chromium/content/browser/renderer_host/media/service_video_capture_provider.cc +++ b/chromium/content/browser/renderer_host/media/service_video_capture_provider.cc @@ -8,7 +8,6 @@ #include "base/bind.h" #include "base/bind_helpers.h" -#include "base/task/post_task.h" #include "build/build_config.h" #include "content/browser/renderer_host/media/service_video_capture_device_launcher.h" #include "content/browser/renderer_host/media/virtual_video_capture_devices_changed_observer.h" @@ -59,8 +58,7 @@ class ServiceVideoCaptureProvider::ServiceProcessObserver public: ServiceProcessObserver(base::RepeatingClosure start_callback, base::RepeatingClosure stop_callback) - : io_task_runner_( - base::CreateSingleThreadTaskRunner({BrowserThread::IO})), + : io_task_runner_(GetIOThreadTaskRunner({})), start_callback_(std::move(start_callback)), stop_callback_(std::move(stop_callback)) { DCHECK_CURRENTLY_ON(BrowserThread::UI); @@ -117,18 +115,17 @@ ServiceVideoCaptureProvider::ServiceVideoCaptureProvider( #endif // defined(OS_CHROMEOS) if (features::IsVideoCaptureServiceEnabledForOutOfProcess()) { service_process_observer_.emplace( - base::CreateSingleThreadTaskRunner({BrowserThread::UI}), + GetUIThreadTaskRunner({}), base::BindRepeating(&ServiceVideoCaptureProvider::OnServiceStarted, weak_ptr_factory_.GetWeakPtr()), base::BindRepeating(&ServiceVideoCaptureProvider::OnServiceStopped, weak_ptr_factory_.GetWeakPtr())); } else if (features::IsVideoCaptureServiceEnabledForBrowserProcess()) { // Connect immediately and permanently when the service runs in-process. - base::CreateSingleThreadTaskRunner({BrowserThread::IO}) - ->PostTask( - FROM_HERE, - base::BindOnce(&ServiceVideoCaptureProvider::OnServiceStarted, - weak_ptr_factory_.GetWeakPtr())); + GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, + base::BindOnce(&ServiceVideoCaptureProvider::OnServiceStarted, + weak_ptr_factory_.GetWeakPtr())); } } @@ -216,7 +213,7 @@ ServiceVideoCaptureProvider::LazyConnectToService() { launcher_has_connected_to_source_provider_ = false; time_of_last_connect_ = base::TimeTicks::Now(); - auto ui_task_runner = base::CreateSingleThreadTaskRunner({BrowserThread::UI}); + auto ui_task_runner = GetUIThreadTaskRunner({}); #if defined(OS_CHROMEOS) mojo::PendingRemote<video_capture::mojom::AcceleratorFactory> accelerator_factory; diff --git a/chromium/content/browser/renderer_host/media/video_capture_browsertest.cc b/chromium/content/browser/renderer_host/media/video_capture_browsertest.cc index f0373bbb0b4..a5039b99ae7 100644 --- a/chromium/content/browser/renderer_host/media/video_capture_browsertest.cc +++ b/chromium/content/browser/renderer_host/media/video_capture_browsertest.cc @@ -6,7 +6,6 @@ #include "base/bind_helpers.h" #include "base/command_line.h" #include "base/run_loop.h" -#include "base/task/post_task.h" #include "base/test/scoped_feature_list.h" #include "build/build_config.h" #include "content/browser/browser_main_loop.h" @@ -254,8 +253,8 @@ IN_PROC_BROWSER_TEST_P(VideoCaptureBrowserTest, StartAndImmediatelyStop) { base::BindOnce(&VideoCaptureBrowserTest::TearDownCaptureDeviceOnIOThread, base::Unretained(this), std::move(quit_run_loop_on_current_thread_cb), true); - base::PostTask( - FROM_HERE, {content::BrowserThread::IO}, + content::GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce( &VideoCaptureBrowserTest::SetUpAndStartCaptureDeviceOnIOThread, base::Unretained(this), std::move(after_start_continuation))); @@ -338,8 +337,8 @@ IN_PROC_BROWSER_TEST_P(VideoCaptureBrowserTest, } })); - base::PostTask( - FROM_HERE, {content::BrowserThread::IO}, + content::GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce( &VideoCaptureBrowserTest::SetUpAndStartCaptureDeviceOnIOThread, base::Unretained(this), base::DoNothing::Once())); diff --git a/chromium/content/browser/renderer_host/media/video_capture_controller.cc b/chromium/content/browser/renderer_host/media/video_capture_controller.cc index 8a3f1c3be3d..09afd022035 100644 --- a/chromium/content/browser/renderer_host/media/video_capture_controller.cc +++ b/chromium/content/browser/renderer_host/media/video_capture_controller.cc @@ -548,11 +548,8 @@ void VideoCaptureController::OnFrameReadyInBuffer( frame_info->coded_size.height()); double frame_rate = 0.0f; if (video_capture_format_) { - media::VideoFrameMetadata metadata; - metadata.MergeInternalValuesFrom(frame_info->metadata); - if (!metadata.GetDouble(VideoFrameMetadata::FRAME_RATE, &frame_rate)) { - frame_rate = video_capture_format_->frame_rate; - } + frame_rate = frame_info->metadata.frame_rate.value_or( + video_capture_format_->frame_rate); } UMA_HISTOGRAM_COUNTS_1M("Media.VideoCapture.FrameRate", frame_rate); UMA_HISTOGRAM_TIMES("Media.VideoCapture.DelayUntilFirstFrame", @@ -709,6 +706,10 @@ void VideoCaptureController::ReleaseDeviceAsync(base::OnceClosure done_cb) { device_launcher_->AbortLaunch(); return; } + // |buffer_contexts_| contain references to |launched_device_| as observers. + // Clear those observer references prior to resetting |launced_device_|. + for (auto& entry : buffer_contexts_) + entry.set_consumer_feedback_observer(nullptr); launched_device_.reset(); } diff --git a/chromium/content/browser/renderer_host/media/video_capture_controller_unittest.cc b/chromium/content/browser/renderer_host/media/video_capture_controller_unittest.cc index c4db5b9877f..2a487b37a22 100644 --- a/chromium/content/browser/renderer_host/media/video_capture_controller_unittest.cc +++ b/chromium/content/browser/renderer_host/media/video_capture_controller_unittest.cc @@ -19,7 +19,6 @@ #include "base/memory/ref_counted.h" #include "base/run_loop.h" #include "base/single_thread_task_runner.h" -#include "base/task/post_task.h" #include "base/test/bind_test_util.h" #include "base/test/metrics/histogram_tester.h" #include "base/threading/thread_task_runner_handle.h" @@ -109,11 +108,7 @@ class MockVideoCaptureControllerEventHandler const media::mojom::VideoFrameInfoPtr& frame_info) override { EXPECT_EQ(expected_pixel_format_, frame_info->pixel_format); EXPECT_EQ(expected_color_space_, frame_info->color_space); - media::VideoFrameMetadata metadata; - metadata.MergeInternalValuesFrom(frame_info->metadata); - base::TimeTicks reference_time; - EXPECT_TRUE(metadata.GetTimeTicks(media::VideoFrameMetadata::REFERENCE_TIME, - &reference_time)); + EXPECT_TRUE(frame_info->metadata.reference_time.has_value()); DoBufferReady(id, frame_info->coded_size); if (enable_auto_return_buffer_on_buffer_ready_) { base::ThreadTaskRunnerHandle::Get()->PostTask( @@ -188,15 +183,13 @@ class VideoCaptureControllerTest device_client_.reset(new media::VideoCaptureDeviceClient( media::VideoCaptureBufferType::kSharedMemory, std::make_unique<media::VideoFrameReceiverOnTaskRunner>( - controller_->GetWeakPtrForIOThread(), - base::CreateSingleThreadTaskRunner({BrowserThread::IO})), + controller_->GetWeakPtrForIOThread(), GetIOThreadTaskRunner({})), buffer_pool_, media::VideoCaptureJpegDecoderFactoryCB())); #else device_client_.reset(new media::VideoCaptureDeviceClient( media::VideoCaptureBufferType::kSharedMemory, std::make_unique<media::VideoFrameReceiverOnTaskRunner>( - controller_->GetWeakPtrForIOThread(), - base::CreateSingleThreadTaskRunner({BrowserThread::IO})), + controller_->GetWeakPtrForIOThread(), GetIOThreadTaskRunner({})), buffer_pool_)); #endif // defined(OS_CHROMEOS) } diff --git a/chromium/content/browser/renderer_host/media/video_capture_host.cc b/chromium/content/browser/renderer_host/media/video_capture_host.cc index c726b06c722..a5b883c7eef 100644 --- a/chromium/content/browser/renderer_host/media/video_capture_host.cc +++ b/chromium/content/browser/renderer_host/media/video_capture_host.cc @@ -8,7 +8,6 @@ #include "base/bind.h" #include "base/bind_helpers.h" -#include "base/task/post_task.h" #include "content/browser/browser_main_loop.h" #include "content/browser/renderer_host/media/media_stream_manager.h" #include "content/browser/renderer_host/media/video_capture_manager.h" @@ -103,16 +102,16 @@ VideoCaptureHost::~VideoCaptureHost() { } NotifyAllStreamsRemoved(); - base::DeleteSoon(FROM_HERE, {BrowserThread::UI}, - render_process_host_delegate_.release()); + GetUIThreadTaskRunner({})->DeleteSoon( + FROM_HERE, render_process_host_delegate_.release()); } void VideoCaptureHost::OnError(const VideoCaptureControllerID& controller_id, media::VideoCaptureError error) { DVLOG(1) << __func__; DCHECK_CURRENTLY_ON(BrowserThread::IO); - base::PostTask( - FROM_HERE, {BrowserThread::IO}, + GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&VideoCaptureHost::DoError, weak_factory_.GetWeakPtr(), controller_id, error)); } @@ -160,8 +159,8 @@ void VideoCaptureHost::OnBufferReady( void VideoCaptureHost::OnEnded(const VideoCaptureControllerID& controller_id) { DVLOG(1) << __func__; DCHECK_CURRENTLY_ON(BrowserThread::IO); - base::PostTask(FROM_HERE, {BrowserThread::IO}, - base::BindOnce(&VideoCaptureHost::DoEnded, + GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&VideoCaptureHost::DoEnded, weak_factory_.GetWeakPtr(), controller_id)); } @@ -434,8 +433,8 @@ void VideoCaptureHost::NotifyStreamAdded() { ++number_of_active_streams_; // base::Unretained() usage is safe because |render_process_host_delegate_| // is destroyed on UI thread. - base::PostTask( - FROM_HERE, {BrowserThread::UI}, + GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&RenderProcessHostDelegate::NotifyStreamAdded, base::Unretained(render_process_host_delegate_.get()))); } @@ -451,8 +450,8 @@ void VideoCaptureHost::NotifyStreamRemoved() { --number_of_active_streams_; // base::Unretained() usage is safe because |render_process_host_delegate_| is // destroyed on UI thread. - base::PostTask( - FROM_HERE, {BrowserThread::UI}, + GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&RenderProcessHostDelegate::NotifyStreamRemoved, base::Unretained(render_process_host_delegate_.get()))); } diff --git a/chromium/content/browser/renderer_host/mock_render_widget_host.cc b/chromium/content/browser/renderer_host/mock_render_widget_host.cc index 0f89709e10e..ac444ae28b9 100644 --- a/chromium/content/browser/renderer_host/mock_render_widget_host.cc +++ b/chromium/content/browser/renderer_host/mock_render_widget_host.cc @@ -71,15 +71,11 @@ MockRenderWidgetHost* MockRenderWidgetHost::Create( RenderWidgetHostDelegate* delegate, RenderProcessHost* process, int32_t routing_id) { - mojo::PendingRemote<mojom::Widget> widget; - std::unique_ptr<MockWidgetImpl> widget_impl = - std::make_unique<MockWidgetImpl>(widget.InitWithNewPipeAndPassReceiver()); - - return new MockRenderWidgetHost(delegate, process, routing_id, - std::move(widget_impl), std::move(widget)); + return new MockRenderWidgetHost(delegate, process, routing_id); } -mojom::WidgetInputHandler* MockRenderWidgetHost::GetWidgetInputHandler() { +blink::mojom::WidgetInputHandler* +MockRenderWidgetHost::GetWidgetInputHandler() { return &mock_widget_input_handler_; } @@ -87,22 +83,24 @@ void MockRenderWidgetHost::NotifyNewContentRenderingTimeoutForTesting() { new_content_rendering_timeout_fired_ = true; } -MockRenderWidgetHost::MockRenderWidgetHost( - RenderWidgetHostDelegate* delegate, - RenderProcessHost* process, - int routing_id, - std::unique_ptr<MockWidgetImpl> widget_impl, - mojo::PendingRemote<mojom::Widget> widget) +MockRenderWidgetHost::MockRenderWidgetHost(RenderWidgetHostDelegate* delegate, + RenderProcessHost* process, + int routing_id) : RenderWidgetHostImpl(delegate, process, routing_id, - std::move(widget), /*hidden=*/false, std::make_unique<TestFrameTokenMessageQueue>()), new_content_rendering_timeout_fired_(false), - widget_impl_(std::move(widget_impl)), fling_scheduler_(std::make_unique<FlingScheduler>(this)) { acked_touch_event_type_ = blink::WebInputEvent::Type::kUndefined; + mojo::AssociatedRemote<blink::mojom::WidgetHost> blink_widget_host; + mojo::AssociatedRemote<blink::mojom::Widget> blink_widget; + auto blink_widget_receiver = + blink_widget.BindNewEndpointAndPassDedicatedReceiverForTesting(); + BindWidgetInterfaces( + blink_widget_host.BindNewEndpointAndPassDedicatedReceiverForTesting(), + blink_widget.Unbind()); } } // namespace content diff --git a/chromium/content/browser/renderer_host/mock_render_widget_host.h b/chromium/content/browser/renderer_host/mock_render_widget_host.h index 4579309695f..ea4c29d7ae8 100644 --- a/chromium/content/browser/renderer_host/mock_render_widget_host.h +++ b/chromium/content/browser/renderer_host/mock_render_widget_host.h @@ -9,12 +9,11 @@ #include "content/browser/renderer_host/input/mock_input_router.h" #include "content/common/input/event_with_latency_info.h" -#include "content/common/input/input_handler.mojom.h" -#include "content/test/mock_widget_impl.h" #include "content/test/mock_widget_input_handler.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "third_party/blink/public/common/input/web_input_event.h" #include "third_party/blink/public/mojom/input/input_event_result.mojom-shared.h" +#include "third_party/blink/public/mojom/input/input_handler.mojom.h" namespace content { @@ -65,7 +64,7 @@ class MockRenderWidgetHost : public RenderWidgetHostImpl { RenderProcessHost* process, int32_t routing_id); - mojom::WidgetInputHandler* GetWidgetInputHandler() override; + blink::mojom::WidgetInputHandler* GetWidgetInputHandler() override; MockWidgetInputHandler mock_widget_input_handler_; @@ -78,11 +77,7 @@ class MockRenderWidgetHost : public RenderWidgetHostImpl { private: MockRenderWidgetHost(RenderWidgetHostDelegate* delegate, RenderProcessHost* process, - int routing_id, - std::unique_ptr<MockWidgetImpl> widget_impl, - mojo::PendingRemote<mojom::Widget> widget); - - std::unique_ptr<MockWidgetImpl> widget_impl_; + int routing_id); std::unique_ptr<FlingScheduler> fling_scheduler_; DISALLOW_COPY_AND_ASSIGN(MockRenderWidgetHost); diff --git a/chromium/content/browser/renderer_host/overscroll_controller_unittest.cc b/chromium/content/browser/renderer_host/overscroll_controller_unittest.cc index 39d9e76be2b..986a654f3b5 100644 --- a/chromium/content/browser/renderer_host/overscroll_controller_unittest.cc +++ b/chromium/content/browser/renderer_host/overscroll_controller_unittest.cc @@ -9,12 +9,12 @@ #include "base/containers/queue.h" #include "base/test/scoped_feature_list.h" #include "content/browser/renderer_host/overscroll_controller_delegate.h" -#include "content/common/input/synthetic_web_input_event_builders.h" #include "content/public/browser/overscroll_configuration.h" #include "content/public/common/content_features.h" #include "content/public/test/scoped_overscroll_modes.h" #include "content/test/test_overscroll_delegate.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/common/input/synthetic_web_input_event_builders.h" #include "third_party/blink/public/common/input/web_input_event.h" namespace content { @@ -43,7 +43,7 @@ class OverscrollControllerTest : public ::testing::Test { bool SimulateMouseWheel(float dx, float dy) { DCHECK(!current_event_); current_event_ = std::make_unique<blink::WebMouseWheelEvent>( - SyntheticWebMouseWheelEventBuilder::Build( + blink::SyntheticWebMouseWheelEventBuilder::Build( 0, 0, dx, dy, 0, ui::ScrollGranularity::kScrollByPrecisePixel)); return controller_->WillHandleEvent(*current_event_); } @@ -55,7 +55,7 @@ class OverscrollControllerTest : public ::testing::Test { base::TimeTicks timestamp) { DCHECK(!current_event_); current_event_ = std::make_unique<blink::WebGestureEvent>( - SyntheticWebGestureEventBuilder::Build(type, source_device)); + blink::SyntheticWebGestureEventBuilder::Build(type, source_device)); current_event_->SetTimeStamp(timestamp); return controller_->WillHandleEvent(*current_event_); } @@ -70,7 +70,8 @@ class OverscrollControllerTest : public ::testing::Test { bool inertial_update) { DCHECK(!current_event_); auto event = std::make_unique<blink::WebGestureEvent>( - SyntheticWebGestureEventBuilder::BuildScrollUpdate(dx, dy, 0, device)); + blink::SyntheticWebGestureEventBuilder::BuildScrollUpdate(dx, dy, 0, + device)); event->SetTimeStamp(timestamp); if (inertial_update) { event->data.scroll_update.inertial_phase = @@ -88,8 +89,8 @@ class OverscrollControllerTest : public ::testing::Test { base::TimeTicks timestamp) { DCHECK(!current_event_); current_event_ = std::make_unique<blink::WebGestureEvent>( - SyntheticWebGestureEventBuilder::BuildFling(velocity_x, velocity_y, - device)); + blink::SyntheticWebGestureEventBuilder::BuildFling(velocity_x, + velocity_y, device)); current_event_->SetTimeStamp(timestamp); return controller_->WillHandleEvent(*current_event_); } diff --git a/chromium/content/browser/renderer_host/p2p/socket_dispatcher_host.cc b/chromium/content/browser/renderer_host/p2p/socket_dispatcher_host.cc index 8c71b7989d0..67a67f7a844 100644 --- a/chromium/content/browser/renderer_host/p2p/socket_dispatcher_host.cc +++ b/chromium/content/browser/renderer_host/p2p/socket_dispatcher_host.cc @@ -75,7 +75,11 @@ void P2PSocketDispatcherHost::BindReceiver( auto trusted_socket_manager_client = receiver_.BindNewPipeAndPassRemote(); trusted_socket_manager_.reset(); + // TODO(https://crbug.com/1085022): Make this interface per-frame instead of + // per-process, and grab the correct NetworkIsolationKey from the associated + // RenderFrameHost. rph->GetStoragePartition()->GetNetworkContext()->CreateP2PSocketManager( + net::NetworkIsolationKey::Todo(), std::move(trusted_socket_manager_client), trusted_socket_manager_.BindNewPipeAndPassReceiver(), std::move(receiver)); diff --git a/chromium/content/browser/renderer_host/page_lifecycle_state_manager.cc b/chromium/content/browser/renderer_host/page_lifecycle_state_manager.cc index 50acabe3752..4be5301c97f 100644 --- a/chromium/content/browser/renderer_host/page_lifecycle_state_manager.cc +++ b/chromium/content/browser/renderer_host/page_lifecycle_state_manager.cc @@ -8,53 +8,112 @@ #include "content/public/browser/render_process_host.h" #include "services/service_manager/public/cpp/interface_provider.h" +namespace { +constexpr base::TimeDelta kBackForwardCacheTimeoutInSeconds = + base::TimeDelta::FromSeconds(3); +} + namespace content { PageLifecycleStateManager::PageLifecycleStateManager( RenderViewHostImpl* render_view_host_impl, - blink::mojom::PageVisibilityState visibility_state) - : is_frozen_(false), - render_view_host_impl_(render_view_host_impl), - visibility_(visibility_state) {} + blink::mojom::PageVisibilityState web_contents_visibility_state) + : web_contents_visibility_(web_contents_visibility_state), + render_view_host_impl_(render_view_host_impl) { + last_acknowledged_state_ = CalculatePageLifecycleState(); + last_state_sent_to_renderer_ = last_acknowledged_state_.Clone(); +} PageLifecycleStateManager::~PageLifecycleStateManager() = default; void PageLifecycleStateManager::SetIsFrozen(bool frozen) { - if (is_frozen_ == frozen) + if (is_set_frozen_called_ == frozen) return; - is_frozen_ = frozen; - SendUpdatesToRenderer(); + is_set_frozen_called_ = frozen; + + SendUpdatesToRendererIfNeeded(base::nullopt); } -void PageLifecycleStateManager::SetVisibility( +void PageLifecycleStateManager::SetWebContentsVisibility( blink::mojom::PageVisibilityState visibility) { - if (visibility_ == visibility) + if (web_contents_visibility_ == visibility) return; - visibility_ = visibility; - SendUpdatesToRenderer(); + + web_contents_visibility_ = visibility; + SendUpdatesToRendererIfNeeded(base::nullopt); // TODO(yuzus): When a page is frozen and made visible, the page should // automatically resume. } -void PageLifecycleStateManager::SendUpdatesToRenderer() { +void PageLifecycleStateManager::SetIsInBackForwardCache( + bool is_in_back_forward_cache, + base::Optional<base::TimeTicks> navigation_start) { + if (is_in_back_forward_cache_ == is_in_back_forward_cache) + return; + is_in_back_forward_cache_ = is_in_back_forward_cache; + if (is_in_back_forward_cache) { + // When a page is put into BackForwardCache, the page can run a busy loop. + // Set a timeout monitor to check that the transition finishes within the + // time limit. + back_forward_cache_timeout_monitor_ = + std::make_unique<OneShotTimeoutMonitor>( + base::BindOnce( + &PageLifecycleStateManager::OnBackForwardCacheTimeout, + weak_ptr_factory_.GetWeakPtr()), + kBackForwardCacheTimeoutInSeconds); + } + SendUpdatesToRendererIfNeeded(navigation_start); +} + +void PageLifecycleStateManager::SendUpdatesToRendererIfNeeded( + base::Optional<base::TimeTicks> navigation_start) { if (!render_view_host_impl_->GetAssociatedPageBroadcast()) { // For some tests, |render_view_host_impl_| does not have the associated // page. return; } - auto state = blink::mojom::PageLifecycleState::New(); - state->is_frozen = is_frozen_; - state->visibility = visibility_; + auto new_state = CalculatePageLifecycleState(); + if (last_state_sent_to_renderer_ && + last_state_sent_to_renderer_.Equals(new_state)) { + // TODO(yuzus): Send updates to renderer only when the effective state (per + // page lifecycle state) has changed since last sent to renderer. It is + // possible that the web contents state has changed but the effective state + // has not. + } + + last_state_sent_to_renderer_ = new_state.Clone(); + auto state = new_state.Clone(); render_view_host_impl_->GetAssociatedPageBroadcast()->SetPageLifecycleState( - std::move(state), - base::BindOnce(&PageLifecycleStateManager::OnLifecycleChangedAck, - weak_ptr_factory_.GetWeakPtr())); + std::move(state), std::move(navigation_start), + base::BindOnce(&PageLifecycleStateManager::OnPageLifecycleChangedAck, + weak_ptr_factory_.GetWeakPtr(), std::move(new_state))); +} + +blink::mojom::PageLifecycleStatePtr +PageLifecycleStateManager::CalculatePageLifecycleState() { + auto state = blink::mojom::PageLifecycleState::New(); + state->is_in_back_forward_cache = is_in_back_forward_cache_; + state->is_frozen = is_in_back_forward_cache_ ? true : is_set_frozen_called_; + state->visibility = is_in_back_forward_cache_ + ? blink::mojom::PageVisibilityState::kHidden + : web_contents_visibility_; + return state; +} + +void PageLifecycleStateManager::OnPageLifecycleChangedAck( + blink::mojom::PageLifecycleStatePtr acknowledged_state) { + last_acknowledged_state_ = std::move(acknowledged_state); + + if (last_acknowledged_state_->is_in_back_forward_cache) { + back_forward_cache_timeout_monitor_.reset(nullptr); + } } -void PageLifecycleStateManager::OnLifecycleChangedAck() { - // TODO(yuzus): Implement OnLifecycleChangedAck and send changes to the - // observers. +void PageLifecycleStateManager::OnBackForwardCacheTimeout() { + DCHECK(!last_acknowledged_state_->is_in_back_forward_cache); + render_view_host_impl_->OnBackForwardCacheTimeout(); + back_forward_cache_timeout_monitor_.reset(nullptr); } } // namespace content diff --git a/chromium/content/browser/renderer_host/page_lifecycle_state_manager.h b/chromium/content/browser/renderer_host/page_lifecycle_state_manager.h index 1203a1b5bee..2891a875d65 100644 --- a/chromium/content/browser/renderer_host/page_lifecycle_state_manager.h +++ b/chromium/content/browser/renderer_host/page_lifecycle_state_manager.h @@ -5,6 +5,7 @@ #ifndef CONTENT_BROWSER_RENDERER_HOST_PAGE_LIFECYCLE_STATE_MANAGER_H_ #define CONTENT_BROWSER_RENDERER_HOST_PAGE_LIFECYCLE_STATE_MANAGER_H_ +#include "content/browser/renderer_host/input/one_shot_timeout_monitor.h" #include "content/common/content_export.h" #include "content/public/common/page_visibility_state.h" #include "mojo/public/cpp/bindings/remote.h" @@ -20,20 +21,55 @@ class CONTENT_EXPORT PageLifecycleStateManager { public: explicit PageLifecycleStateManager( RenderViewHostImpl* render_view_host_impl, - blink::mojom::PageVisibilityState visibility_state); + blink::mojom::PageVisibilityState web_contents_visibility_state); ~PageLifecycleStateManager(); void SetIsFrozen(bool frozen); - void SetVisibility(blink::mojom::PageVisibilityState visibility_state); + void SetWebContentsVisibility( + blink::mojom::PageVisibilityState visibility_state); + void SetIsInBackForwardCache( + bool is_in_back_forward_cache, + base::Optional<base::TimeTicks> navigation_start); private: - void SendUpdatesToRenderer(); - void OnLifecycleChangedAck(); + // Send mojo message to renderer if the effective (page) lifecycle state has + // changed. + void SendUpdatesToRendererIfNeeded( + base::Optional<base::TimeTicks> navigation_start); + + // Calculates the per-page lifecycle state based on the per-tab / web contents + // lifecycle state saved in this instance. + blink::mojom::PageLifecycleStatePtr CalculatePageLifecycleState(); + + void OnPageLifecycleChangedAck( + blink::mojom::PageLifecycleStatePtr acknowledged_state); + void OnBackForwardCacheTimeout(); + + // This represents the frozen state set by |SetIsFrozen|, which corresponds to + // WebContents::SetPageFrozen. Effective frozen state, i.e. per-page frozen + // state is computed based on |is_in_back_forward_cache_| and + // |is_set_frozen_called_|. + bool is_set_frozen_called_ = false; + + bool is_in_back_forward_cache_ = false; + + // This represents the visibility set by |SetVisibility|, which is web + // contents visibility state. Effective visibility, i.e. per-page visibility + // is computed based on |is_in_back_forward_cache_| and + // |web_contents_visibility_|. + blink::mojom::PageVisibilityState web_contents_visibility_; - bool is_frozen_; RenderViewHostImpl* render_view_host_impl_; - blink::mojom::PageVisibilityState visibility_; + // This is the per-page state computed based on web contents / tab lifecycle + // states, i.e. |is_set_frozen_called_|, |is_in_back_forward_cache_| and + // |web_contents_visibility_|. + blink::mojom::PageLifecycleStatePtr last_acknowledged_state_; + + // This is the per-page state that is sent to renderer most lately. + blink::mojom::PageLifecycleStatePtr last_state_sent_to_renderer_; + + std::unique_ptr<OneShotTimeoutMonitor> back_forward_cache_timeout_monitor_; // NOTE: This must be the last member. base::WeakPtrFactory<PageLifecycleStateManager> weak_ptr_factory_{this}; }; diff --git a/chromium/content/browser/renderer_host/page_lifecycle_state_manager_browsertest.cc b/chromium/content/browser/renderer_host/page_lifecycle_state_manager_browsertest.cc index 8c2220541ec..d5e302c2b41 100644 --- a/chromium/content/browser/renderer_host/page_lifecycle_state_manager_browsertest.cc +++ b/chromium/content/browser/renderer_host/page_lifecycle_state_manager_browsertest.cc @@ -8,11 +8,13 @@ #include "content/browser/renderer_host/render_view_host_impl.h" #include "content/browser/web_contents/web_contents_impl.h" #include "content/public/browser/render_frame_host.h" +#include "content/public/browser/site_isolation_policy.h" #include "content/public/test/browser_test.h" #include "content/public/test/browser_test_utils.h" #include "content/public/test/content_browser_test.h" #include "content/public/test/content_browser_test_utils.h" #include "content/shell/browser/shell.h" +#include "content/test/content_browser_test_utils_internal.h" #include "net/dns/mock_host_resolver.h" #include "net/test/embedded_test_server/embedded_test_server.h" @@ -160,4 +162,33 @@ IN_PROC_BROWSER_TEST_F(PageLifecycleStateManagerBrowserTest, EXPECT_EQ(PageVisibilityState::kVisible, rfh_child->GetVisibilityState()); } +IN_PROC_BROWSER_TEST_F(PageLifecycleStateManagerBrowserTest, + CreateNewWindowVisibilityChange) { + if (!SiteIsolationPolicy::UseDedicatedProcessesForAllSites()) + return; + + ASSERT_TRUE(embedded_test_server()->Start()); + GURL url_a(embedded_test_server()->GetURL("a.com", "/title1.html")); + + // 1) Navigate to A and open a popup. + EXPECT_TRUE(NavigateToURL(shell(), url_a)); + EXPECT_TRUE(WaitForLoadStop(shell()->web_contents())); + RenderFrameHostImpl* rfh_a = current_frame_host(); + EXPECT_EQ(1u, rfh_a->GetSiteInstance()->GetRelatedActiveContentsCount()); + Shell* popup = OpenPopup(rfh_a, url_a, ""); + EXPECT_EQ(2u, rfh_a->GetSiteInstance()->GetRelatedActiveContentsCount()); + + RenderFrameHostImpl* popup_frame = + static_cast<RenderFrameHostImpl*>(popup->web_contents()->GetMainFrame()); + StartRecordingEvents(popup_frame); + + popup->web_contents()->WasHidden(); + EXPECT_EQ(PageVisibilityState::kHidden, popup_frame->GetVisibilityState()); + popup->web_contents()->WasShown(); + EXPECT_EQ(PageVisibilityState::kVisible, popup_frame->GetVisibilityState()); + + MatchEventList(popup_frame, ListValueOf("document.visibilitychange", + "document.visibilitychange")); +} + } // namespace content diff --git a/chromium/content/browser/renderer_host/pepper/pepper_file_io_host.cc b/chromium/content/browser/renderer_host/pepper/pepper_file_io_host.cc index bd68358ddb4..28fba2fc56d 100644 --- a/chromium/content/browser/renderer_host/pepper/pepper_file_io_host.cc +++ b/chromium/content/browser/renderer_host/pepper/pepper_file_io_host.cc @@ -205,8 +205,8 @@ int32_t PepperFileIOHost::OnHostMsgOpen( if (!CanOpenFileSystemURLWithPepperFlags( open_flags, render_process_id_, file_system_url_)) return PP_ERROR_NOACCESS; - base::PostTaskAndReplyWithResult( - FROM_HERE, {BrowserThread::UI}, + GetUIThreadTaskRunner({})->PostTaskAndReplyWithResult( + FROM_HERE, base::BindOnce(&GetUIThreadStuffForInternalFileSystems, render_process_id_), base::BindOnce( @@ -217,8 +217,8 @@ int32_t PepperFileIOHost::OnHostMsgOpen( base::FilePath path = file_ref_host->GetExternalFilePath(); if (!CanOpenWithPepperFlags(open_flags, render_process_id_, path)) return PP_ERROR_NOACCESS; - base::PostTaskAndReplyWithResult( - FROM_HERE, {BrowserThread::UI}, + GetUIThreadTaskRunner({})->PostTaskAndReplyWithResult( + FROM_HERE, base::BindOnce(&GetResolvedRenderProcessId, render_process_id_), base::BindOnce(&PepperFileIOHost::GotResolvedRenderProcessId, AsWeakPtr(), context->MakeReplyMessageContext(), path, @@ -395,8 +395,8 @@ int32_t PepperFileIOHost::OnHostMsgRequestOSFileHandle( GURL document_url = browser_ppapi_host_->GetDocumentURLForInstance(pp_instance()); - base::PostTaskAndReplyWithResult( - FROM_HERE, {BrowserThread::UI}, + GetUIThreadTaskRunner({})->PostTaskAndReplyWithResult( + FROM_HERE, base::BindOnce(&GetPluginAllowedToCallRequestOSFileHandle, render_process_id_, document_url), base::BindOnce( diff --git a/chromium/content/browser/renderer_host/pepper/pepper_file_system_browser_host.cc b/chromium/content/browser/renderer_host/pepper/pepper_file_system_browser_host.cc index 79c7375ff33..5bc0d12b6c7 100644 --- a/chromium/content/browser/renderer_host/pepper/pepper_file_system_browser_host.cc +++ b/chromium/content/browser/renderer_host/pepper/pepper_file_system_browser_host.cc @@ -105,8 +105,8 @@ void PepperFileSystemBrowserHost::OpenExisting(const GURL& root_url, called_open_ = true; // Get the file system context asynchronously, and then complete the Open // operation by calling |callback|. - base::PostTaskAndReplyWithResult( - FROM_HERE, {BrowserThread::UI}, + GetUIThreadTaskRunner({})->PostTaskAndReplyWithResult( + FROM_HERE, base::BindOnce(&GetFileSystemContextFromRenderId, render_process_id), base::BindOnce(&PepperFileSystemBrowserHost::OpenExistingFileSystem, weak_factory_.GetWeakPtr(), std::move(callback))); @@ -187,8 +187,8 @@ int32_t PepperFileSystemBrowserHost::OnHostMsgOpen( return PP_ERROR_FAILED; } - base::PostTaskAndReplyWithResult( - FROM_HERE, {BrowserThread::UI}, + GetUIThreadTaskRunner({})->PostTaskAndReplyWithResult( + FROM_HERE, base::BindOnce(&GetFileSystemContextFromRenderId, render_process_id), base::BindOnce(&PepperFileSystemBrowserHost::OpenFileSystem, weak_factory_.GetWeakPtr(), @@ -353,8 +353,8 @@ int32_t PepperFileSystemBrowserHost::OnHostMsgInitIsolatedFileSystem( fsid, ppapi::IsolatedFileSystemTypeToRootName(type))); - base::PostTaskAndReplyWithResult( - FROM_HERE, {BrowserThread::UI}, + GetUIThreadTaskRunner({})->PostTaskAndReplyWithResult( + FROM_HERE, base::BindOnce(&GetFileSystemContextFromRenderId, render_process_id), base::BindOnce(&PepperFileSystemBrowserHost::OpenIsolatedFileSystem, weak_factory_.GetWeakPtr(), diff --git a/chromium/content/browser/renderer_host/pepper/pepper_host_resolver_message_filter.cc b/chromium/content/browser/renderer_host/pepper/pepper_host_resolver_message_filter.cc index 4504ed06d41..ed36e45f6bb 100644 --- a/chromium/content/browser/renderer_host/pepper/pepper_host_resolver_message_filter.cc +++ b/chromium/content/browser/renderer_host/pepper/pepper_host_resolver_message_filter.cc @@ -12,7 +12,6 @@ #include "base/bind.h" #include "base/check_op.h" #include "base/notreached.h" -#include "base/task/post_task.h" #include "content/browser/renderer_host/pepper/browser_ppapi_host_impl.h" #include "content/browser/renderer_host/pepper/pepper_socket_utils.h" #include "content/public/browser/browser_context.h" @@ -105,7 +104,7 @@ scoped_refptr<base::SequencedTaskRunner> PepperHostResolverMessageFilter::OverrideTaskRunnerForMessage( const IPC::Message& message) { if (message.type() == PpapiHostMsg_HostResolver_Resolve::ID) - return base::CreateSingleThreadTaskRunner({BrowserThread::UI}); + return GetUIThreadTaskRunner({}); return nullptr; } @@ -173,8 +172,8 @@ void PepperHostResolverMessageFilter::OnComplete( DCHECK_CURRENTLY_ON(BrowserThread::UI); receiver_.reset(); - base::PostTask( - FROM_HERE, {BrowserThread::IO}, + GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&PepperHostResolverMessageFilter::OnLookupFinished, this, resolve_error_info.error, std::move(resolved_addresses), host_resolve_context_)); diff --git a/chromium/content/browser/renderer_host/pepper/pepper_network_monitor_host.cc b/chromium/content/browser/renderer_host/pepper/pepper_network_monitor_host.cc index 9b444bb0b4c..bd55cb259d1 100644 --- a/chromium/content/browser/renderer_host/pepper/pepper_network_monitor_host.cc +++ b/chromium/content/browser/renderer_host/pepper/pepper_network_monitor_host.cc @@ -9,7 +9,6 @@ #include "base/bind.h" #include "base/bind_helpers.h" -#include "base/task/post_task.h" #include "base/task_runner_util.h" #include "content/browser/renderer_host/pepper/browser_ppapi_host_impl.h" #include "content/browser/renderer_host/pepper/pepper_socket_utils.h" @@ -43,8 +42,8 @@ void OnGetNetworkList( base::OnceCallback<void(const net::NetworkInterfaceList&)> callback, const base::Optional<net::NetworkInterfaceList>& networks) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - base::PostTask( - FROM_HERE, {BrowserThread::IO}, + GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(std::move(callback), networks.has_value() ? *networks : net::NetworkInterfaceList())); @@ -70,8 +69,8 @@ PepperNetworkMonitorHost::PepperNetworkMonitorHost(BrowserPpapiHostImpl* host, host->GetRenderFrameIDsForInstance( instance, &render_process_id, &render_frame_id); - base::PostTaskAndReplyWithResult( - FROM_HERE, {BrowserThread::UI}, + GetUIThreadTaskRunner({})->PostTaskAndReplyWithResult( + FROM_HERE, base::BindOnce(&CanUseNetworkMonitor, host->external_plugin(), render_process_id, render_frame_id), base::BindOnce(&PepperNetworkMonitorHost::OnPermissionCheckResult, @@ -100,9 +99,8 @@ void PepperNetworkMonitorHost::OnPermissionCheckResult( return; } - base::PostTaskAndReplyWithResult( - FROM_HERE, {BrowserThread::UI}, - base::BindOnce(&content::GetNetworkConnectionTracker), + GetUIThreadTaskRunner({})->PostTaskAndReplyWithResult( + FROM_HERE, base::BindOnce(&content::GetNetworkConnectionTracker), base::BindOnce(&PepperNetworkMonitorHost::SetNetworkConnectionTracker, weak_factory_.GetWeakPtr())); GetAndSendNetworkList(); @@ -117,8 +115,8 @@ void PepperNetworkMonitorHost::SetNetworkConnectionTracker( void PepperNetworkMonitorHost::GetAndSendNetworkList() { DCHECK_CURRENTLY_ON(BrowserThread::IO); - base::PostTask( - FROM_HERE, {BrowserThread::UI}, + GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&GetNetworkList, base::BindOnce(&PepperNetworkMonitorHost::SendNetworkList, weak_factory_.GetWeakPtr()))); diff --git a/chromium/content/browser/renderer_host/pepper/pepper_network_proxy_host.cc b/chromium/content/browser/renderer_host/pepper/pepper_network_proxy_host.cc index 37ec5a3af97..b3a236cae2e 100644 --- a/chromium/content/browser/renderer_host/pepper/pepper_network_proxy_host.cc +++ b/chromium/content/browser/renderer_host/pepper/pepper_network_proxy_host.cc @@ -5,7 +5,6 @@ #include "content/browser/renderer_host/pepper/pepper_network_proxy_host.h" #include "base/bind.h" -#include "base/task/post_task.h" #include "content/browser/renderer_host/pepper/browser_ppapi_host_impl.h" #include "content/browser/renderer_host/pepper/pepper_proxy_lookup_helper.h" #include "content/browser/renderer_host/pepper/pepper_socket_utils.h" @@ -46,9 +45,9 @@ bool LookUpProxyForURLCallback( StoragePartition* storage_partition = BrowserContext::GetStoragePartition( site_instance->GetBrowserContext(), site_instance); - // TODO(https://crbug.com/1021661): Pass in a non-empty NetworkIsolationKey. storage_partition->GetNetworkContext()->LookUpProxyForURL( - url, net::NetworkIsolationKey::Todo(), std::move(proxy_lookup_client)); + url, render_frame_host->GetNetworkIsolationKey(), + std::move(proxy_lookup_client)); return true; } @@ -64,8 +63,8 @@ PepperNetworkProxyHost::PepperNetworkProxyHost(BrowserPpapiHostImpl* host, waiting_for_ui_thread_data_(true) { host->GetRenderFrameIDsForInstance(instance, &render_process_id_, &render_frame_id_); - base::PostTaskAndReplyWithResult( - FROM_HERE, {BrowserThread::UI}, + GetUIThreadTaskRunner({})->PostTaskAndReplyWithResult( + FROM_HERE, base::BindOnce(&GetUIThreadDataOnUIThread, render_process_id_, render_frame_id_, host->external_plugin()), base::BindOnce(&PepperNetworkProxyHost::DidGetUIThreadData, diff --git a/chromium/content/browser/renderer_host/pepper/pepper_print_settings_manager.cc b/chromium/content/browser/renderer_host/pepper/pepper_print_settings_manager.cc index 6a7e4f5eff7..46539874af9 100644 --- a/chromium/content/browser/renderer_host/pepper/pepper_print_settings_manager.cc +++ b/chromium/content/browser/renderer_host/pepper/pepper_print_settings_manager.cc @@ -4,7 +4,6 @@ #include "content/browser/renderer_host/pepper/pepper_print_settings_manager.h" -#include "base/task/post_task.h" #include "build/build_config.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" @@ -126,9 +125,9 @@ PepperPrintSettingsManagerImpl::ComputeDefaultPrintSettings() { void PepperPrintSettingsManagerImpl::GetDefaultPrintSettings( PepperPrintSettingsManager::Callback callback) { - base::PostTaskAndReplyWithResult(FROM_HERE, {BrowserThread::UI}, - base::BindOnce(ComputeDefaultPrintSettings), - std::move(callback)); + GetUIThreadTaskRunner({})->PostTaskAndReplyWithResult( + FROM_HERE, base::BindOnce(ComputeDefaultPrintSettings), + std::move(callback)); } } // namespace content diff --git a/chromium/content/browser/renderer_host/pepper/pepper_proxy_lookup_helper.cc b/chromium/content/browser/renderer_host/pepper/pepper_proxy_lookup_helper.cc index e00862f55d7..afc11223ef5 100644 --- a/chromium/content/browser/renderer_host/pepper/pepper_proxy_lookup_helper.cc +++ b/chromium/content/browser/renderer_host/pepper/pepper_proxy_lookup_helper.cc @@ -9,7 +9,6 @@ #include "base/location.h" #include "base/memory/ref_counted.h" #include "base/sequenced_task_runner.h" -#include "base/task/post_task.h" #include "base/threading/sequenced_task_runner_handle.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" @@ -30,8 +29,8 @@ class PepperProxyLookupHelper::UIThreadHelper LookUpCompleteCallback look_up_complete_callback) : look_up_complete_callback_(std::move(look_up_complete_callback)), callback_task_runner_(base::SequencedTaskRunnerHandle::Get()) { - base::PostTask( - FROM_HERE, {BrowserThread::UI}, + GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&UIThreadHelper::StartLookup, base::Unretained(this), url, std::move(look_up_proxy_for_url_callback))); } @@ -78,8 +77,8 @@ PepperProxyLookupHelper::PepperProxyLookupHelper() {} PepperProxyLookupHelper::~PepperProxyLookupHelper() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - base::DeleteSoon(FROM_HERE, {BrowserThread::UI}, - std::move(ui_thread_helper_)); + GetUIThreadTaskRunner({})->DeleteSoon(FROM_HERE, + std::move(ui_thread_helper_)); } void PepperProxyLookupHelper::Start( diff --git a/chromium/content/browser/renderer_host/pepper/pepper_proxy_lookup_helper_unittest.cc b/chromium/content/browser/renderer_host/pepper/pepper_proxy_lookup_helper_unittest.cc index df616d801d7..d16d8d32676 100644 --- a/chromium/content/browser/renderer_host/pepper/pepper_proxy_lookup_helper_unittest.cc +++ b/chromium/content/browser/renderer_host/pepper/pepper_proxy_lookup_helper_unittest.cc @@ -14,7 +14,6 @@ #include "base/memory/weak_ptr.h" #include "base/optional.h" #include "base/run_loop.h" -#include "base/task/post_task.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" #include "content/public/test/browser_task_environment.h" @@ -41,8 +40,8 @@ class PepperProxyLookupHelperTest : public testing::Test { DCHECK_CURRENTLY_ON(BrowserThread::UI); base::RunLoop run_loop; - base::PostTask( - FROM_HERE, {BrowserThread::IO}, + GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&PepperProxyLookupHelperTest::StartLookupOnIOThread, base::Unretained(this), run_loop.QuitClosure())); run_loop.Run(); @@ -64,8 +63,8 @@ class PepperProxyLookupHelperTest : public testing::Test { DCHECK_CURRENTLY_ON(BrowserThread::UI); base::RunLoop run_loop; - base::PostTaskAndReply( - FROM_HERE, {BrowserThread::IO}, + GetIOThreadTaskRunner({})->PostTaskAndReply( + FROM_HERE, base::BindOnce( &PepperProxyLookupHelperTest::DestroyLookupHelperOnIOThread, base::Unretained(this)), diff --git a/chromium/content/browser/renderer_host/pepper/pepper_tcp_server_socket_message_filter.cc b/chromium/content/browser/renderer_host/pepper/pepper_tcp_server_socket_message_filter.cc index 87a4150faa0..4197106c166 100644 --- a/chromium/content/browser/renderer_host/pepper/pepper_tcp_server_socket_message_filter.cc +++ b/chromium/content/browser/renderer_host/pepper/pepper_tcp_server_socket_message_filter.cc @@ -10,7 +10,6 @@ #include "base/bind.h" #include "base/bind_helpers.h" #include "base/logging.h" -#include "base/task/post_task.h" #include "build/build_config.h" #include "content/browser/renderer_host/pepper/browser_ppapi_host_impl.h" #include "content/browser/renderer_host/pepper/content_browser_pepper_host_factory.h" @@ -99,8 +98,8 @@ void PepperTCPServerSocketMessageFilter::OnFilterDestroyed() { // also ensures that future messages will be ignored, so the mojo pipes won't // be re-created, so after Close() runs, |this| can be safely deleted on the // IO thread. - base::PostTask( - FROM_HERE, {BrowserThread::UI}, + GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&PepperTCPServerSocketMessageFilter::Close, this)); } @@ -111,7 +110,7 @@ PepperTCPServerSocketMessageFilter::OverrideTaskRunnerForMessage( case PpapiHostMsg_TCPServerSocket_Listen::ID: case PpapiHostMsg_TCPServerSocket_Accept::ID: case PpapiHostMsg_TCPServerSocket_StopListening::ID: - return base::CreateSingleThreadTaskRunner({BrowserThread::UI}); + return GetUIThreadTaskRunner({}); } return nullptr; } @@ -328,8 +327,8 @@ void PepperTCPServerSocketMessageFilter::OnAcceptCompleted( return; } - base::PostTask( - FROM_HERE, {BrowserThread::IO}, + GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce( &PepperTCPServerSocketMessageFilter::OnAcceptCompletedOnIOThread, this, context, std::move(connected_socket), diff --git a/chromium/content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.cc b/chromium/content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.cc index f2835886fa9..1d1104ed5e4 100644 --- a/chromium/content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.cc +++ b/chromium/content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.cc @@ -12,7 +12,6 @@ #include "base/logging.h" #include "base/memory/ptr_util.h" #include "base/metrics/histogram_macros.h" -#include "base/task/post_task.h" #include "build/build_config.h" #include "content/browser/renderer_host/pepper/content_browser_pepper_host_factory.h" #include "content/browser/renderer_host/pepper/pepper_socket_utils.h" @@ -114,8 +113,8 @@ void PepperTCPSocketMessageFilter::SetConnectedSocket( // thread to prevent the object from being deleted before this method returns. DCHECK(HasOneRef()); - base::PostTask( - FROM_HERE, {BrowserThread::UI}, + GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce( &PepperTCPSocketMessageFilter::SetConnectedSocketOnUIThread, this, std::move(connected_socket), std::move(socket_observer_receiver), @@ -129,7 +128,7 @@ PepperTCPSocketMessageFilter::~PepperTCPSocketMessageFilter() { #if defined(OS_CHROMEOS) // Close the firewall hole on UI thread if there is one. if (firewall_hole_) { - base::DeleteSoon(FROM_HERE, {BrowserThread::UI}, std::move(firewall_hole_)); + GetUIThreadTaskRunner({})->DeleteSoon(FROM_HERE, std::move(firewall_hole_)); } #endif // defined(OS_CHROMEOS) --g_num_tcp_filter_instances; @@ -171,8 +170,8 @@ void PepperTCPSocketMessageFilter::OnFilterDestroyed() { // also ensures that future messages will be ignored, so the mojo pipes won't // be re-created, so after Close() runs, |this| can be safely deleted on the // IO thread. - base::PostTask(FROM_HERE, {BrowserThread::UI}, - base::BindOnce(&PepperTCPSocketMessageFilter::Close, this)); + GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&PepperTCPSocketMessageFilter::Close, this)); } scoped_refptr<base::SequencedTaskRunner> @@ -189,7 +188,7 @@ PepperTCPSocketMessageFilter::OverrideTaskRunnerForMessage( case PpapiHostMsg_TCPSocket_Accept::ID: case PpapiHostMsg_TCPSocket_Close::ID: case PpapiHostMsg_TCPSocket_SetOption::ID: - return base::CreateSingleThreadTaskRunner({BrowserThread::UI}); + return GetUIThreadTaskRunner({}); } return nullptr; } @@ -221,8 +220,8 @@ int32_t PepperTCPSocketMessageFilter::OnResourceMessageReceived( } void PepperTCPSocketMessageFilter::OnThrottleStateChanged(bool is_throttled) { - base::PostTask( - FROM_HERE, {BrowserThread::UI}, + GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce( &PepperTCPSocketMessageFilter::ThrottleStateChangedOnUIThread, this, is_throttled)); @@ -1123,8 +1122,8 @@ void PepperTCPSocketMessageFilter::OnAcceptCompleted( // already. DCHECK(success); - base::PostTask( - FROM_HERE, {BrowserThread::IO}, + GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&PepperTCPSocketMessageFilter::OnAcceptCompletedOnIOThread, this, context, std::move(connected_socket), std::move(socket_observer_receiver), diff --git a/chromium/content/browser/renderer_host/pepper/pepper_udp_socket_message_filter.cc b/chromium/content/browser/renderer_host/pepper/pepper_udp_socket_message_filter.cc index 7cc8709182a..5c2711aabd2 100644 --- a/chromium/content/browser/renderer_host/pepper/pepper_udp_socket_message_filter.cc +++ b/chromium/content/browser/renderer_host/pepper/pepper_udp_socket_message_filter.cc @@ -12,7 +12,6 @@ #include "base/compiler_specific.h" #include "base/logging.h" #include "base/metrics/histogram_macros.h" -#include "base/task/post_task.h" #include "build/build_config.h" #include "content/browser/renderer_host/pepper/browser_ppapi_host_impl.h" #include "content/browser/renderer_host/pepper/pepper_socket_utils.h" @@ -128,8 +127,8 @@ void PepperUDPSocketMessageFilter::OnFilterDestroyed() { // that future messages will be ignored, so the mojo pipes won't be // re-created, so after Close() runs, |this| can be safely deleted on the IO // thread. - base::PostTask(FROM_HERE, {BrowserThread::UI}, - base::BindOnce(&PepperUDPSocketMessageFilter::Close, this)); + GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&PepperUDPSocketMessageFilter::Close, this)); } scoped_refptr<base::SequencedTaskRunner> @@ -143,7 +142,7 @@ PepperUDPSocketMessageFilter::OverrideTaskRunnerForMessage( case PpapiHostMsg_UDPSocket_SendTo::ID: case PpapiHostMsg_UDPSocket_JoinGroup::ID: case PpapiHostMsg_UDPSocket_LeaveGroup::ID: - return base::CreateSingleThreadTaskRunner({BrowserThread::UI}); + return GetUIThreadTaskRunner({}); } return nullptr; } @@ -714,8 +713,8 @@ void PepperUDPSocketMessageFilter::SendRecvFromResult( const PP_NetAddress_Private& addr) { // Unlike SendReply, which is safe to call on any thread, SendUnsolicitedReply // calls are only safe to make on the IO thread. - base::PostTask( - FROM_HERE, {BrowserThread::IO}, + GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce( &PepperUDPSocketMessageFilter::SendRecvFromResultOnIOThread, this, result, data, addr)); diff --git a/chromium/content/browser/renderer_host/pepper/pepper_vpn_provider_message_filter_chromeos.cc b/chromium/content/browser/renderer_host/pepper/pepper_vpn_provider_message_filter_chromeos.cc index c97315580bb..f2134959abb 100644 --- a/chromium/content/browser/renderer_host/pepper/pepper_vpn_provider_message_filter_chromeos.cc +++ b/chromium/content/browser/renderer_host/pepper/pepper_vpn_provider_message_filter_chromeos.cc @@ -5,7 +5,6 @@ #include "content/browser/renderer_host/pepper/pepper_vpn_provider_message_filter_chromeos.h" #include "base/bind.h" -#include "base/task/post_task.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/content_browser_client.h" @@ -96,7 +95,7 @@ PepperVpnProviderMessageFilter::OverrideTaskRunnerForMessage( case PpapiHostMsg_VpnProvider_Bind::ID: case PpapiHostMsg_VpnProvider_SendPacket::ID: case PpapiHostMsg_VpnProvider_OnPacketReceivedReply::ID: - return base::CreateSingleThreadTaskRunner({BrowserThread::UI}); + return GetUIThreadTaskRunner({}); } return nullptr; } diff --git a/chromium/content/browser/renderer_host/pepper/quota_reservation.cc b/chromium/content/browser/renderer_host/pepper/quota_reservation.cc index 545df15897b..9441b0c6757 100644 --- a/chromium/content/browser/renderer_host/pepper/quota_reservation.cc +++ b/chromium/content/browser/renderer_host/pepper/quota_reservation.cc @@ -8,7 +8,6 @@ #include "base/bind.h" #include "base/callback.h" -#include "base/task/post_task.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" #include "storage/browser/file_system/file_system_operation_runner.h" @@ -122,8 +121,8 @@ void QuotaReservation::GotReservedQuota(ReserveQuotaCallback callback, file_sizes[it->first] = it->second->GetMaxWrittenOffset(); if (file_system_context_) { - base::PostTask( - FROM_HERE, {BrowserThread::IO}, + GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(std::move(callback), quota_reservation_->remaining_quota(), file_sizes)); } else { diff --git a/chromium/content/browser/renderer_host/render_frame_metadata_provider_impl.cc b/chromium/content/browser/renderer_host/render_frame_metadata_provider_impl.cc index 498d3330486..6726b888b64 100644 --- a/chromium/content/browser/renderer_host/render_frame_metadata_provider_impl.cc +++ b/chromium/content/browser/renderer_host/render_frame_metadata_provider_impl.cc @@ -36,10 +36,9 @@ void RenderFrameMetadataProviderImpl::Bind( std::move(client_receiver), task_runner_); #if defined(OS_ANDROID) - if (pending_report_all_root_scrolls_for_accessibility_.has_value()) { - ReportAllRootScrollsForAccessibility( - *pending_report_all_root_scrolls_for_accessibility_); - pending_report_all_root_scrolls_for_accessibility_.reset(); + if (pending_report_all_root_scrolls_.has_value()) { + ReportAllRootScrolls(*pending_report_all_root_scrolls_); + pending_report_all_root_scrolls_.reset(); } #endif if (pending_report_all_frame_submission_for_testing_.has_value()) { @@ -50,15 +49,13 @@ void RenderFrameMetadataProviderImpl::Bind( } #if defined(OS_ANDROID) -void RenderFrameMetadataProviderImpl::ReportAllRootScrollsForAccessibility( - bool enabled) { +void RenderFrameMetadataProviderImpl::ReportAllRootScrolls(bool enabled) { if (!render_frame_metadata_observer_remote_) { - pending_report_all_root_scrolls_for_accessibility_ = enabled; + pending_report_all_root_scrolls_ = enabled; return; } - render_frame_metadata_observer_remote_->ReportAllRootScrollsForAccessibility( - enabled); + render_frame_metadata_observer_remote_->ReportAllRootScrolls(enabled); } #endif @@ -130,4 +127,12 @@ void RenderFrameMetadataProviderImpl::OnFrameSubmissionForTesting( weak_factory_.GetWeakPtr())); } +#if defined(OS_ANDROID) +void RenderFrameMetadataProviderImpl::OnRootScrollOffsetChanged( + const gfx::Vector2dF& root_scroll_offset) { + for (Observer& observer : observers_) + observer.OnRootScrollOffsetChanged(root_scroll_offset); +} +#endif + } // namespace content diff --git a/chromium/content/browser/renderer_host/render_frame_metadata_provider_impl.h b/chromium/content/browser/renderer_host/render_frame_metadata_provider_impl.h index 9c0f9c8e716..87e20b92576 100644 --- a/chromium/content/browser/renderer_host/render_frame_metadata_provider_impl.h +++ b/chromium/content/browser/renderer_host/render_frame_metadata_provider_impl.h @@ -47,8 +47,9 @@ class CONTENT_EXPORT RenderFrameMetadataProviderImpl #if defined(OS_ANDROID) // Notifies the renderer to begin sending a notification on all root scroll - // changes, which is needed for accessibility on Android. - void ReportAllRootScrollsForAccessibility(bool enabled); + // changes, which is needed for accessibility and GestureListenerManager on + // Android. + void ReportAllRootScrolls(bool enabled); #endif // Notifies the renderer to begin sending a notification on all frame @@ -75,6 +76,10 @@ class CONTENT_EXPORT RenderFrameMetadataProviderImpl uint32_t frame_token, const cc::RenderFrameMetadata& metadata) override; void OnFrameSubmissionForTesting(uint32_t frame_token) override; +#if defined(OS_ANDROID) + void OnRootScrollOffsetChanged( + const gfx::Vector2dF& root_scroll_offset) override; +#endif base::ObserverList<Observer>::Unchecked observers_; @@ -94,7 +99,7 @@ class CONTENT_EXPORT RenderFrameMetadataProviderImpl render_frame_metadata_observer_remote_; #if defined(OS_ANDROID) - base::Optional<bool> pending_report_all_root_scrolls_for_accessibility_; + base::Optional<bool> pending_report_all_root_scrolls_; #endif base::Optional<bool> pending_report_all_frame_submission_for_testing_; diff --git a/chromium/content/browser/renderer_host/render_process_host_browsertest.cc b/chromium/content/browser/renderer_host/render_process_host_browsertest.cc index a7bcc88c619..477d582c228 100644 --- a/chromium/content/browser/renderer_host/render_process_host_browsertest.cc +++ b/chromium/content/browser/renderer_host/render_process_host_browsertest.cc @@ -7,7 +7,6 @@ #include "base/command_line.h" #include "base/run_loop.h" #include "base/synchronization/waitable_event.h" -#include "base/task/post_task.h" #include "base/test/metrics/histogram_tester.h" #include "base/test/scoped_feature_list.h" #include "base/test/simple_test_tick_clock.h" @@ -187,11 +186,6 @@ class RenderProcessHostTest : public ContentBrowserTest, } void SetUpCommandLine(base::CommandLine* command_line) override { -#if defined(OS_LINUX) - // Due to problems with PulseAudio failing to start, use a fake audio - // stream. https://crbug.com/1047655#c70 - command_line->AppendSwitch(switches::kDisableAudioOutput); -#endif command_line->AppendSwitchASCII( switches::kAutoplayPolicy, switches::autoplay::kNoUserGestureRequiredPolicy); @@ -505,24 +499,17 @@ class CustomStoragePartitionForSomeSites : public TestContentBrowserClient { explicit CustomStoragePartitionForSomeSites(const GURL& site_to_isolate) : site_to_isolate_(site_to_isolate) {} - void GetStoragePartitionConfigForSite(BrowserContext* browser_context, - const GURL& site, - bool can_be_default, - std::string* partition_domain, - std::string* partition_name, - bool* in_memory) override { - // Default to the browser-wide storage partition and override based on - // |site| below. - partition_domain->clear(); - partition_name->clear(); - *in_memory = false; - + StoragePartitionConfig GetStoragePartitionConfigForSite( + BrowserContext* browser_context, + const GURL& site) override { // Override for |site_to_isolate_|. if (site == site_to_isolate_) { - *partition_domain = "blah_isolated_storage"; - *partition_name = "blah_isolated_storage"; - *in_memory = false; + return StoragePartitionConfig::Create("blah_isolated_storage", + "blah_isolated_storage", + false /* in_memory */); } + + return StoragePartitionConfig::CreateDefault(); } std::string GetStoragePartitionIdForSite(BrowserContext* browser_context, @@ -820,21 +807,47 @@ IN_PROC_BROWSER_TEST_F(RenderProcessHostTest, KillProcessOnBadMojoMessage) { rph->RemoveObserver(this); } +// Observes a WebContents and a specific frame within it, and waits until they +// both indicate that they are audible. class AudioStartObserver : public WebContentsObserver { public: AudioStartObserver(WebContents* web_contents, + RenderFrameHost* render_frame_host, base::OnceClosure audible_closure) : WebContentsObserver(web_contents), - audible_closure_(std::move(audible_closure)) {} - ~AudioStartObserver() override {} + render_frame_host_( + static_cast<RenderFrameHostImpl*>(render_frame_host)), + contents_audible_(web_contents->IsCurrentlyAudible()), + frame_audible_(render_frame_host_->is_audible()), + audible_closure_(std::move(audible_closure)) { + MaybeFireClosure(); + } + ~AudioStartObserver() override = default; // WebContentsObserver: void OnAudioStateChanged(bool audible) override { - if (audible && audible_closure_) - std::move(audible_closure_).Run(); + DCHECK_NE(audible, contents_audible_); + contents_audible_ = audible; + MaybeFireClosure(); + } + void OnFrameAudioStateChanged(RenderFrameHost* render_frame_host, + bool audible) override { + if (render_frame_host_ != render_frame_host) + return; + DCHECK_NE(frame_audible_, audible); + frame_audible_ = audible; + MaybeFireClosure(); } private: + void MaybeFireClosure() { + if (contents_audible_ && frame_audible_) + std::move(audible_closure_).Run(); + } + + RenderFrameHostImpl* render_frame_host_ = nullptr; + bool contents_audible_ = false; + bool frame_audible_ = false; base::OnceClosure audible_closure_; }; @@ -861,9 +874,11 @@ IN_PROC_BROWSER_TEST_F(RenderProcessHostTest, KillProcessZerosAudioStreams) { shell()->web_contents()->GetMainFrame()->GetProcess()); { - // Start audio and wait for it to become audible. + // Start audio and wait for it to become audible, in both the frame *and* + // the page. base::RunLoop run_loop; AudioStartObserver observer(shell()->web_contents(), + shell()->web_contents()->GetMainFrame(), run_loop.QuitClosure()); std::string result; @@ -899,8 +914,8 @@ IN_PROC_BROWSER_TEST_F(RenderProcessHostTest, KillProcessZerosAudioStreams) { // Cycle UI and IO loop once to ensure OnChannelClosing() has been delivered // to audio stream owners and they get a chance to notify of stream closure. base::RunLoop run_loop; - base::PostTask(FROM_HERE, {BrowserThread::IO}, - media::BindToCurrentLoop(run_loop.QuitClosure())); + GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, media::BindToCurrentLoop(run_loop.QuitClosure())); run_loop.Run(); } @@ -998,8 +1013,8 @@ IN_PROC_BROWSER_TEST_F(CaptureStreamRenderProcessHostTest, // Cycle UI and IO loop once to ensure OnChannelClosing() has been delivered // to audio stream owners and they get a chance to notify of stream closure. base::RunLoop run_loop; - base::PostTask(FROM_HERE, {BrowserThread::IO}, - media::BindToCurrentLoop(run_loop.QuitClosure())); + GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, media::BindToCurrentLoop(run_loop.QuitClosure())); run_loop.Run(); } @@ -1064,8 +1079,8 @@ IN_PROC_BROWSER_TEST_F(CaptureStreamRenderProcessHostTest, // Cycle UI and IO loop once to ensure OnChannelClosing() has been delivered // to audio stream owners and they get a chance to notify of stream closure. base::RunLoop run_loop; - base::PostTask(FROM_HERE, {BrowserThread::IO}, - media::BindToCurrentLoop(run_loop.QuitClosure())); + GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, media::BindToCurrentLoop(run_loop.QuitClosure())); run_loop.Run(); } diff --git a/chromium/content/browser/renderer_host/render_process_host_impl.cc b/chromium/content/browser/renderer_host/render_process_host_impl.cc index a37c3125a34..bf902312d46 100644 --- a/chromium/content/browser/renderer_host/render_process_host_impl.cc +++ b/chromium/content/browser/renderer_host/render_process_host_impl.cc @@ -77,10 +77,6 @@ #include "components/viz/common/switches.h" #include "components/viz/host/gpu_client.h" #include "content/browser/appcache/chrome_appcache_service.h" -#include "content/browser/background_fetch/background_fetch_context.h" -#include "content/browser/background_fetch/background_fetch_service_impl.h" -#include "content/browser/background_sync/one_shot_background_sync_service_impl.h" -#include "content/browser/background_sync/periodic_background_sync_service_impl.h" #include "content/browser/bad_message.h" #include "content/browser/blob_storage/blob_registry_wrapper.h" #include "content/browser/broadcast_channel/broadcast_channel_provider.h" @@ -100,6 +96,7 @@ #include "content/browser/frame_host/render_frame_message_filter.h" #include "content/browser/gpu/browser_gpu_client_delegate.h" #include "content/browser/gpu/compositor_util.h" +#include "content/browser/gpu/gpu_data_manager_impl.h" #include "content/browser/gpu/gpu_process_host.h" #include "content/browser/gpu/shader_cache_factory.h" #include "content/browser/histogram_controller.h" @@ -133,7 +130,6 @@ #include "content/browser/renderer_host/render_message_filter.h" #include "content/browser/renderer_host/render_widget_helper.h" #include "content/browser/renderer_host/render_widget_host_impl.h" -#include "content/browser/renderer_host/text_input_client_message_filter.h" #include "content/browser/renderer_host/web_database_host_impl.h" #include "content/browser/resolve_proxy_helper.h" #include "content/browser/service_worker/service_worker_context_wrapper.h" @@ -182,6 +178,7 @@ #include "content/public/common/service_names.mojom.h" #include "content/public/common/url_constants.h" #include "content/public/common/web_preferences.h" +#include "content/public/common/zygote/zygote_buildflags.h" #include "device/gamepad/gamepad_haptics_manager.h" #include "google_apis/gaia/gaia_switches.h" #include "gpu/GLES2/gl2extchromium.h" @@ -219,10 +216,11 @@ #include "services/service_manager/public/cpp/binder_registry.h" #include "services/service_manager/public/cpp/interface_provider.h" #include "services/service_manager/sandbox/switches.h" -#include "services/service_manager/zygote/common/zygote_buildflags.h" #include "storage/browser/database/database_tracker.h" #include "storage/browser/file_system/sandbox_file_system_backend.h" +#include "third_party/blink/public/common/features.h" #include "third_party/blink/public/common/page/launching_process_state.h" +#include "third_party/blink/public/common/switches.h" #include "third_party/blink/public/common/user_agent/user_agent_metadata.h" #include "third_party/blink/public/mojom/disk_allocator.mojom.h" #include "third_party/blink/public/public_buildflags.h" @@ -239,8 +237,6 @@ #include "content/public/browser/android/java_interfaces.h" #include "ipc/ipc_sync_channel.h" #include "media/audio/android/audio_manager_android.h" -#else -#include "content/browser/gpu/gpu_data_manager_impl.h" #endif #if defined(OS_LINUX) @@ -254,6 +250,7 @@ #if defined(OS_MACOSX) #include "content/browser/child_process_task_port_provider_mac.h" +#include "content/browser/renderer_host/text_input_client_message_filter.h" #include "content/browser/sandbox_support_mac_impl.h" #include "content/common/sandbox_support_mac.mojom.h" #endif @@ -291,7 +288,7 @@ #endif #if BUILDFLAG(USE_ZYGOTE_HANDLE) -#include "services/service_manager/zygote/common/zygote_handle.h" // nogncheck +#include "content/public/common/zygote/zygote_handle.h" // nogncheck #endif #if BUILDFLAG(CLANG_PROFILING_INSIDE_SANDBOX) @@ -436,14 +433,14 @@ class RendererSandboxedProcessLauncherDelegate #endif // OS_WIN #if BUILDFLAG(USE_ZYGOTE_HANDLE) - service_manager::ZygoteHandle GetZygote() override { + ZygoteHandle GetZygote() override { const base::CommandLine& browser_command_line = *base::CommandLine::ForCurrentProcess(); base::CommandLine::StringType renderer_prefix = browser_command_line.GetSwitchValueNative(switches::kRendererCmdPrefix); if (!renderer_prefix.empty()) return nullptr; - return service_manager::GetGenericZygote(); + return GetGenericZygote(); } #endif // BUILDFLAG(USE_ZYGOTE_HANDLE) @@ -468,8 +465,8 @@ class SessionStorageHolder : public base::SupportsUserData::Data { ~SessionStorageHolder() override { // Its important to delete the map on the IO thread to avoid deleting // the underlying namespaces prior to processing ipcs referring to them. - base::DeleteSoon(FROM_HERE, {BrowserThread::IO}, - session_storage_namespaces_awaiting_close_.release()); + GetIOThreadTaskRunner({})->DeleteSoon( + FROM_HERE, session_storage_namespaces_awaiting_close_.release()); } void Hold(const SessionStorageNamespaceMap& sessions, int widget_route_id) { @@ -546,6 +543,9 @@ class SpareRenderProcessHostManager : public RenderProcessHostObserver { nullptr /* site_instance */); spare_render_process_host_->AddObserver(this); spare_render_process_host_->Init(); + + // The spare render process isn't ready, so wait and do the "spare render + // process changed" callback in RenderProcessReady(). } RenderProcessHost* MaybeTakeSpareRenderProcessHost( @@ -568,7 +568,7 @@ class SpareRenderProcessHostManager : public RenderProcessHostObserver { // scenarios). bool embedder_allows_spare_usage = GetContentClient()->browser()->ShouldUseSpareRenderProcessHost( - browser_context, site_instance->GetSiteURL()); + browser_context, site_instance->GetSiteInfo().site_url()); // We shouldn't use the spare if: // 1. The SiteInstance has already got an associated process. This is @@ -668,6 +668,7 @@ class SpareRenderProcessHostManager : public RenderProcessHostObserver { // Drop reference to the RenderProcessHost object. spare_render_process_host_ = nullptr; + spare_render_process_host_changed_callback_list_.Notify(nullptr); } } @@ -675,6 +676,15 @@ class SpareRenderProcessHostManager : public RenderProcessHostObserver { return spare_render_process_host_; } + std::unique_ptr<base::CallbackList<void(RenderProcessHost*)>::Subscription> + RegisterSpareRenderProcessHostChangedCallback( + const base::RepeatingCallback<void(RenderProcessHost*)>& cb) { + // Do an initial notification, as the subscriber will need to know what the + // current spare host is. + cb.Run(spare_render_process_host_); + return spare_render_process_host_changed_callback_list_.Add(cb); + } + private: // Release ownership of |host| as a possible spare renderer. Called when // |host| has either been 1) claimed to be used in a navigation or 2) shutdown @@ -683,6 +693,14 @@ class SpareRenderProcessHostManager : public RenderProcessHostObserver { if (spare_render_process_host_ && spare_render_process_host_ == host) { spare_render_process_host_->RemoveObserver(this); spare_render_process_host_ = nullptr; + spare_render_process_host_changed_callback_list_.Notify(nullptr); + } + } + + void RenderProcessReady(RenderProcessHost* host) override { + if (host == spare_render_process_host_) { + spare_render_process_host_changed_callback_list_.Notify( + spare_render_process_host_); } } @@ -696,6 +714,11 @@ class SpareRenderProcessHostManager : public RenderProcessHostObserver { ReleaseSpareRenderProcessHost(host); } + // The clients who want to know when the spare render process host has + // changed. + base::CallbackList<void(RenderProcessHost*)> + spare_render_process_host_changed_callback_list_; + // This is a bare pointer, because RenderProcessHost manages the lifetime of // all its instances; see GetAllHosts(). RenderProcessHost* spare_render_process_host_ = nullptr; @@ -725,8 +748,8 @@ class RenderProcessHostIsReadyObserver : public RenderProcessHostObserver { private: void PostTask() { - base::PostTask(FROM_HERE, {BrowserThread::UI}, - base::BindOnce(&RenderProcessHostIsReadyObserver::CallTask, + GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&RenderProcessHostIsReadyObserver::CallTask, weak_factory_.GetWeakPtr())); } @@ -773,9 +796,9 @@ class SiteProcessCountTracker : public base::SupportsUserData::Data, SiteProcessCountTracker() {} ~SiteProcessCountTracker() override { DCHECK(map_.empty()); } - void IncrementSiteProcessCount(const GURL& site_url, + void IncrementSiteProcessCount(const SiteInfo& site_info, int render_process_host_id) { - std::map<ProcessID, Count>& counts_per_process = map_[site_url]; + std::map<ProcessID, Count>& counts_per_process = map_[site_info.site_url()]; ++counts_per_process[render_process_host_id]; #ifndef NDEBUG @@ -787,9 +810,9 @@ class SiteProcessCountTracker : public base::SupportsUserData::Data, #endif } - void DecrementSiteProcessCount(const GURL& site_url, + void DecrementSiteProcessCount(const SiteInfo& site_info, int render_process_host_id) { - auto result = map_.find(site_url); + auto result = map_.find(site_info.site_url()); DCHECK(result != map_.end()); std::map<ProcessID, Count>& counts_per_process = result->second; @@ -800,14 +823,14 @@ class SiteProcessCountTracker : public base::SupportsUserData::Data, counts_per_process.erase(render_process_host_id); if (counts_per_process.empty()) - map_.erase(site_url); + map_.erase(site_info.site_url()); } void FindRenderProcessesForSiteInstance( SiteInstanceImpl* site_instance, std::set<RenderProcessHost*>* foreground_processes, std::set<RenderProcessHost*>* background_processes) { - auto result = map_.find(site_instance->GetSiteURL()); + auto result = map_.find(site_instance->GetSiteInfo().site_url()); if (result == map_.end()) return; @@ -824,14 +847,14 @@ class SiteProcessCountTracker : public base::SupportsUserData::Data, } // It's possible that |host| has become unsuitable for hosting - // |site_url|, for example if it was reused by a navigation to a - // different site, and |site_url| requires a dedicated process. Do not - // allow such hosts to be reused. See https://crbug.com/780661. + // |site_instance|, for example if it was reused by a navigation to a + // different site, and |site_instance| requires a dedicated process. Do + // not allow such hosts to be reused. See https://crbug.com/780661. if (!host->MayReuseHost() || !RenderProcessHostImpl::IsSuitableHost( host, site_instance->GetIsolationContext(), - site_instance->GetSiteURL(), site_instance->lock_url(), - site_instance->IsGuest())) { + site_instance->GetSiteInfo().site_url(), + site_instance->lock_url(), site_instance->IsGuest())) { continue; } @@ -888,13 +911,13 @@ class SiteProcessCountTracker : public base::SupportsUserData::Data, using ProcessID = int; using Count = int; + // TODO(wjmaclean): Convert the key from GURL to a SiteInfo hashkey. using CountPerProcessPerSiteMap = std::map<GURL, std::map<ProcessID, Count>>; CountPerProcessPerSiteMap map_; }; bool ShouldUseSiteProcessTracking(BrowserContext* browser_context, - StoragePartition* dest_partition, - const GURL& site_url) { + StoragePartition* dest_partition) { // TODO(alexmos): Sites should be tracked separately for each // StoragePartition. For now, track them only in the default one. StoragePartition* default_partition = @@ -907,23 +930,22 @@ bool ShouldUseSiteProcessTracking(BrowserContext* browser_context, bool ShouldTrackProcessForSite(BrowserContext* browser_context, RenderProcessHost* render_process_host, - const GURL& site_url) { - if (site_url.is_empty()) + const SiteInfo& site_info) { + if (site_info.site_url().is_empty()) return false; return ShouldUseSiteProcessTracking( - browser_context, render_process_host->GetStoragePartition(), site_url); + browser_context, render_process_host->GetStoragePartition()); } bool ShouldFindReusableProcessHostForSite(BrowserContext* browser_context, - const GURL& site_url) { - if (site_url.is_empty()) + const SiteInfo& site_info) { + if (site_info.site_url().is_empty()) return false; return ShouldUseSiteProcessTracking( - browser_context, - BrowserContext::GetStoragePartitionForSite(browser_context, site_url), - site_url); + browser_context, BrowserContext::GetStoragePartitionForSite( + browser_context, site_info.site_url())); } const void* const kUnmatchedServiceWorkerProcessTrackerKey = @@ -953,9 +975,9 @@ class UnmatchedServiceWorkerProcessTracker static void Register(RenderProcessHost* render_process_host, SiteInstanceImpl* site_instance) { BrowserContext* browser_context = site_instance->GetBrowserContext(); - DCHECK(!site_instance->GetSiteURL().is_empty()); + DCHECK(!site_instance->GetSiteInfo().site_url().is_empty()); if (!ShouldTrackProcessForSite(browser_context, render_process_host, - site_instance->GetSiteURL())) + site_instance->GetSiteInfo())) return; UnmatchedServiceWorkerProcessTracker* tracker = @@ -975,7 +997,7 @@ class UnmatchedServiceWorkerProcessTracker static RenderProcessHost* MatchWithSite(SiteInstanceImpl* site_instance) { BrowserContext* browser_context = site_instance->GetBrowserContext(); if (!ShouldFindReusableProcessHostForSite(browser_context, - site_instance->GetSiteURL())) + site_instance->GetSiteInfo())) return nullptr; UnmatchedServiceWorkerProcessTracker* tracker = @@ -1009,6 +1031,7 @@ class UnmatchedServiceWorkerProcessTracker private: using ProcessID = int; + // TODO(wjmaclean): Convert the pair to use SiteInfo hashkey instead of GURL. using SiteProcessIDPair = std::pair<GURL, ProcessID>; using SiteProcessIDPairSet = std::set<SiteProcessIDPair>; @@ -1016,8 +1039,8 @@ class UnmatchedServiceWorkerProcessTracker SiteInstanceImpl* site_instance) { if (!HasProcess(host)) host->AddObserver(this); - site_process_set_.insert( - SiteProcessIDPair(site_instance->GetSiteURL(), host->GetID())); + site_process_set_.insert(SiteProcessIDPair( + site_instance->GetSiteInfo().site_url(), host->GetID())); } RenderProcessHost* TakeFreshestProcessForSite( @@ -1038,7 +1061,7 @@ class UnmatchedServiceWorkerProcessTracker // |site_url|, for example if it was used for a ServiceWorker for a // nonexistent extension URL. See https://crbug.com/782349 and // https://crbug.com/780661. - GURL site_url(site_instance->GetSiteURL()); + GURL site_url(site_instance->GetSiteInfo().site_url()); if (!host->MayReuseHost() || !RenderProcessHostImpl::IsSuitableHost( host, site_instance->GetIsolationContext(), site_url, @@ -1063,7 +1086,7 @@ class UnmatchedServiceWorkerProcessTracker return site_process_pair; } } else { - const GURL site_url(site_instance->GetSiteURL()); + const GURL site_url(site_instance->GetSiteInfo().site_url()); for (const auto& site_process_pair : reversed_site_process_set) { if (site_process_pair.first == site_url) return site_process_pair; @@ -1255,8 +1278,8 @@ GetBadMojoMessageCallbackForTesting() { void InvokeBadMojoMessageCallbackForTesting(int render_process_id, const std::string& error) { if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { - base::PostTask(FROM_HERE, {BrowserThread::UI}, - base::BindOnce(&InvokeBadMojoMessageCallbackForTesting, + GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&InvokeBadMojoMessageCallbackForTesting, render_process_id, error)); return; } @@ -1349,8 +1372,8 @@ class RenderProcessHostImpl::IOThreadHostImpl if (!receiver) return; - base::PostTask(FROM_HERE, {BrowserThread::UI}, - base::BindOnce(&IOThreadHostImpl::BindHostReceiverOnUIThread, + GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&IOThreadHostImpl::BindHostReceiverOnUIThread, weak_host_, std::move(receiver))); } @@ -1481,7 +1504,7 @@ int RenderProcessHost::GetCurrentRenderProcessCountForTesting() { RenderProcessHost* RenderProcessHostImpl::CreateRenderProcessHost( BrowserContext* browser_context, StoragePartitionImpl* storage_partition_impl, - SiteInstance* site_instance) { + SiteInstanceImpl* site_instance) { if (g_render_process_host_factory_) { return g_render_process_host_factory_->CreateRenderProcessHost( browser_context, site_instance); @@ -1501,7 +1524,7 @@ RenderProcessHost* RenderProcessHostImpl::CreateRenderProcessHost( if (is_for_guests_only && storage_partition_impl->site_for_guest_service_worker().is_empty()) { storage_partition_impl->set_site_for_guest_service_worker( - site_instance->GetSiteURL()); + site_instance->GetSiteInfo().site_url()); } return new RenderProcessHostImpl(browser_context, storage_partition_impl, @@ -1575,8 +1598,8 @@ RenderProcessHostImpl::RenderProcessHostImpl( if (!GetBrowserContext()->IsOffTheRecord() && !base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kDisableGpuShaderDiskCache)) { - base::PostTask(FROM_HERE, {BrowserThread::IO}, - base::BindOnce(&CacheShaderInfo, GetID(), + GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&CacheShaderInfo, GetID(), storage_partition_impl_->GetPath())); } @@ -1597,9 +1620,9 @@ RenderProcessHostImpl::RenderProcessHostImpl( const int id = GetID(); const uint64_t tracing_id = ChildProcessHostImpl::ChildProcessUniqueIdToTracingProcessId(id); - gpu_client_.reset(new viz::GpuClient( - std::make_unique<BrowserGpuClientDelegate>(), id, tracing_id, - base::CreateSingleThreadTaskRunner({BrowserThread::IO}))); + gpu_client_.reset( + new viz::GpuClient(std::make_unique<BrowserGpuClientDelegate>(), id, + tracing_id, GetIOThreadTaskRunner({}))); } // static @@ -1681,8 +1704,8 @@ RenderProcessHostImpl::~RenderProcessHostImpl() { if (!base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kDisableGpuShaderDiskCache)) { - base::PostTask(FROM_HERE, {BrowserThread::IO}, - base::BindOnce(&RemoveShaderInfo, GetID())); + GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&RemoveShaderInfo, GetID())); } if (cleanup_network_service_plugin_exceptions_upon_destruction_) @@ -1800,9 +1823,8 @@ bool RenderProcessHostImpl::Init() { // make blocking calls to the UI thread (i.e. this thread), they need to run // on separate threads. in_process_renderer_.reset(g_renderer_main_thread_factory( - InProcessChildThreadParams( - base::CreateSingleThreadTaskRunner({BrowserThread::IO}), - &mojo_invitation_), + InProcessChildThreadParams(GetIOThreadTaskRunner({}), + &mojo_invitation_), base::checked_cast<int32_t>(id_))); base::Thread::Options options; @@ -1870,7 +1892,7 @@ bool RenderProcessHostImpl::HasOnlyLowPriorityFrames() { void RenderProcessHostImpl::InitializeChannelProxy() { scoped_refptr<base::SingleThreadTaskRunner> io_task_runner = - base::CreateSingleThreadTaskRunner({BrowserThread::IO}); + GetIOThreadTaskRunner({}); // Establish a ChildProcess interface connection to the new renderer. This is // connected as the primordial message pipe via a Mojo invitation to the @@ -2015,8 +2037,8 @@ void RenderProcessHostImpl::BindFileSystemManager( // Note, the base::Unretained() is safe because the target object has an IO // thread deleter and the callback is also targeting the IO thread. // TODO(https://crbug.com/873661): Pass origin to FileSystemManager. - base::PostTask( - FROM_HERE, {BrowserThread::IO}, + GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&FileSystemManagerImpl::BindReceiver, base::Unretained(file_system_manager_impl_.get()), std::move(receiver))); @@ -2039,7 +2061,7 @@ void RenderProcessHostImpl::BindNativeFileSystemManager( // URL for workers instead of the origin as source url. // This URL will be used for SafeBrowsing checks and for // the Quarantine Service. - origin.GetURL(), GetID(), MSG_ROUTING_NONE), + origin.GetURL(), GetID()), std::move(receiver)); } @@ -2160,8 +2182,8 @@ void RenderProcessHostImpl::DelayProcessShutdownForUnload( return; IncrementKeepAliveRefCount(); - base::PostDelayedTask( - FROM_HERE, {BrowserThread::UI}, + GetUIThreadTaskRunner({})->PostDelayedTask( + FROM_HERE, base::BindOnce( &RenderProcessHostImpl::CancelProcessShutdownDelayForUnload, weak_factory_.GetWeakPtr()), @@ -2172,8 +2194,8 @@ void RenderProcessHostImpl::DelayProcessShutdownForUnload( void RenderProcessHostImpl::AddCorbExceptionForPlugin(int process_id) { DCHECK_CURRENTLY_ON(BrowserThread::IO); - base::PostTask( - FROM_HERE, {BrowserThread::UI}, + GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&AddCorbExceptionForPluginOnUIThread, process_id)); } @@ -2183,8 +2205,8 @@ void RenderProcessHostImpl::AddAllowedRequestInitiatorForPlugin( const url::Origin& allowed_request_initiator) { DCHECK_CURRENTLY_ON(BrowserThread::IO); - base::PostTask(FROM_HERE, {BrowserThread::UI}, - base::BindOnce(&AddAllowedRequestInitiatorForPluginOnUIThread, + GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&AddAllowedRequestInitiatorForPluginOnUIThread, process_id, allowed_request_initiator)); } @@ -2375,6 +2397,9 @@ void RenderProcessHostImpl::RegisterMojoInterfaces() { &viz::GpuClient::Add, base::Unretained(gpu_client_.get()))); } + registry->AddInterface( + base::BindRepeating(&GpuDataManagerImpl::BindReceiver)); + MediaStreamManager* media_stream_manager = BrowserMainLoop::GetInstance()->media_stream_manager(); @@ -2498,9 +2523,8 @@ void RenderProcessHostImpl::RegisterMojoInterfaces() { mojo::PendingRemote<mojom::ChildProcessHostBootstrap> bootstrap_remote; io_thread_host_impl_.emplace( - base::CreateSingleThreadTaskRunner({BrowserThread::IO}), GetID(), - instance_weak_factory_->GetWeakPtr(), std::move(registry), - bootstrap_remote.InitWithNewPipeAndPassReceiver()); + GetIOThreadTaskRunner({}), GetID(), instance_weak_factory_->GetWeakPtr(), + std::move(registry), bootstrap_remote.InitWithNewPipeAndPassReceiver()); child_process_->Initialize(std::move(bootstrap_remote)); } @@ -3000,9 +3024,9 @@ RenderProcessHostImpl::get_render_process_host_factory_for_testing() { void RenderProcessHostImpl::AddFrameWithSite( BrowserContext* browser_context, RenderProcessHost* render_process_host, - const GURL& site_url) { + const SiteInfo& site_info) { if (!ShouldTrackProcessForSite(browser_context, render_process_host, - site_url)) + site_info)) return; SiteProcessCountTracker* tracker = static_cast<SiteProcessCountTracker*>( @@ -3012,16 +3036,16 @@ void RenderProcessHostImpl::AddFrameWithSite( browser_context->SetUserData(kCommittedSiteProcessCountTrackerKey, base::WrapUnique(tracker)); } - tracker->IncrementSiteProcessCount(site_url, render_process_host->GetID()); + tracker->IncrementSiteProcessCount(site_info, render_process_host->GetID()); } // static void RenderProcessHostImpl::RemoveFrameWithSite( BrowserContext* browser_context, RenderProcessHost* render_process_host, - const GURL& site_url) { + const SiteInfo& site_info) { if (!ShouldTrackProcessForSite(browser_context, render_process_host, - site_url)) + site_info)) return; SiteProcessCountTracker* tracker = static_cast<SiteProcessCountTracker*>( @@ -3031,16 +3055,16 @@ void RenderProcessHostImpl::RemoveFrameWithSite( browser_context->SetUserData(kCommittedSiteProcessCountTrackerKey, base::WrapUnique(tracker)); } - tracker->DecrementSiteProcessCount(site_url, render_process_host->GetID()); + tracker->DecrementSiteProcessCount(site_info, render_process_host->GetID()); } // static void RenderProcessHostImpl::AddExpectedNavigationToSite( BrowserContext* browser_context, RenderProcessHost* render_process_host, - const GURL& site_url) { + const SiteInfo& site_info) { if (!ShouldTrackProcessForSite(browser_context, render_process_host, - site_url)) + site_info)) return; SiteProcessCountTracker* tracker = static_cast<SiteProcessCountTracker*>( @@ -3050,16 +3074,16 @@ void RenderProcessHostImpl::AddExpectedNavigationToSite( browser_context->SetUserData(kPendingSiteProcessCountTrackerKey, base::WrapUnique(tracker)); } - tracker->IncrementSiteProcessCount(site_url, render_process_host->GetID()); + tracker->IncrementSiteProcessCount(site_info, render_process_host->GetID()); } // static void RenderProcessHostImpl::RemoveExpectedNavigationToSite( BrowserContext* browser_context, RenderProcessHost* render_process_host, - const GURL& site_url) { + const SiteInfo& site_info) { if (!ShouldTrackProcessForSite(browser_context, render_process_host, - site_url)) + site_info)) return; SiteProcessCountTracker* tracker = static_cast<SiteProcessCountTracker*>( @@ -3069,7 +3093,7 @@ void RenderProcessHostImpl::RemoveExpectedNavigationToSite( browser_context->SetUserData(kPendingSiteProcessCountTrackerKey, base::WrapUnique(tracker)); } - tracker->DecrementSiteProcessCount(site_url, render_process_host->GetID()); + tracker->DecrementSiteProcessCount(site_info, render_process_host->GetID()); } // static @@ -3086,6 +3110,14 @@ RenderProcessHost* RenderProcessHost::GetSpareRenderProcessHostForTesting() { } // static +std::unique_ptr<base::CallbackList<void(RenderProcessHost*)>::Subscription> +RenderProcessHost::RegisterSpareRenderProcessHostChangedCallback( + const base::RepeatingCallback<void(RenderProcessHost*)>& cb) { + return SpareRenderProcessHostManager::GetInstance() + .RegisterSpareRenderProcessHostChangedCallback(cb); +} + +// static void RenderProcessHostImpl::DiscardSpareRenderProcessHostForTesting() { SpareRenderProcessHostManager::GetInstance().CleanupSpareRenderProcessHost(); } @@ -3130,6 +3162,12 @@ void RenderProcessHostImpl::LockToOrigin( NotifyRendererIfLockedToSite(); } +bool RenderProcessHostImpl::IsLockedToOriginForTesting() { + GURL lock_url = + ChildProcessSecurityPolicyImpl::GetInstance()->GetOriginLock(GetID()); + return !lock_url.is_empty(); +} + void RenderProcessHostImpl::NotifyRendererIfLockedToSite() { GURL lock_url = ChildProcessSecurityPolicyImpl::GetInstance()->GetOriginLock(GetID()); @@ -3157,18 +3195,19 @@ static void AppendCompositorCommandLineFlags(base::CommandLine* command_line) { int msaa_sample_count = GpuRasterizationMSAASampleCount(); if (msaa_sample_count >= 0) { - command_line->AppendSwitchASCII(switches::kGpuRasterizationMSAASampleCount, - base::NumberToString(msaa_sample_count)); + command_line->AppendSwitchASCII( + blink::switches::kGpuRasterizationMSAASampleCount, + base::NumberToString(msaa_sample_count)); } if (IsZeroCopyUploadEnabled()) - command_line->AppendSwitch(switches::kEnableZeroCopy); + command_line->AppendSwitch(blink::switches::kEnableZeroCopy); if (!IsPartialRasterEnabled()) - command_line->AppendSwitch(switches::kDisablePartialRaster); + command_line->AppendSwitch(blink::switches::kDisablePartialRaster); if (IsGpuMemoryBufferCompositorResourcesEnabled()) { command_line->AppendSwitch( - switches::kEnableGpuMemoryBufferCompositorResources); + blink::switches::kEnableGpuMemoryBufferCompositorResources); } if (IsMainFrameBeforeActivationEnabled()) @@ -3240,15 +3279,12 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer( service_manager::switches::kEnableSandboxLogging, #endif switches::kAgcStartupMinVolume, - switches::kAllowPreCommitInput, switches::kAllowLoopbackInPeerConnection, switches::kAndroidFontsPath, switches::kAudioBufferSize, switches::kAutoplayPolicy, switches::kBlinkSettings, - switches::kDefaultTileWidth, - switches::kDefaultTileHeight, - switches::kMinHeightForGpuRasterTile, + switches::kMojoCoreLibraryPath, switches::kDisable2dCanvasImageChromium, switches::kDisableYUVImageDecoding, switches::kDisableAcceleratedVideoDecode, @@ -3260,8 +3296,6 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer( switches::kDisableFileSystem, switches::kDisableFrameRateLimit, switches::kDisableGpuMemoryBufferVideoFrames, - switches::kDisableImageAnimationResync, - switches::kDisableLowResTiling, switches::kDisableHistogramCustomizer, switches::kDisableLCDText, switches::kDisableLogging, @@ -3273,7 +3307,6 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer( switches::kDisablePepper3DImageChromium, switches::kDisablePermissionsAPI, switches::kDisablePresentationAPI, - switches::kDisableRGBA4444Textures, switches::kDisableRTCSmoothnessAlgorithm, switches::kDisableScrollToTextFragment, switches::kDisableSharedWorkers, @@ -3296,7 +3329,6 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer( switches::kEnableGpuClientTracing, switches::kEnableGpuMemoryBufferVideoFrames, switches::kEnableGPUServiceLogging, - switches::kEnableLowResTiling, switches::kEnableLCDText, switches::kEnableLogging, switches::kEnableNetworkInformationDownlinkMax, @@ -3304,7 +3336,6 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer( switches::kEnablePluginPlaceholderTesting, switches::kEnablePreciseMemoryInfo, switches::kEnablePreferCompositingToLCDText, - switches::kEnableRGBA4444Textures, switches::kEnableSkiaBenchmarking, switches::kEnableThreadedCompositing, switches::kEnableTouchDragDrop, @@ -3330,8 +3361,6 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer( switches::kLogFile, switches::kLoggingLevel, switches::kMaxActiveWebGLContexts, - switches::kMaxUntiledLayerWidth, - switches::kMaxUntiledLayerHeight, switches::kMSEAudioBufferSizeLimitMb, switches::kMSEVideoBufferSizeLimitMb, switches::kNetworkQuietTimeout, @@ -3348,8 +3377,6 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer( switches::kRemoteDebuggingPort, switches::kRendererStartupDialog, switches::kReportVp9AsAnUnsupportedMimeType, - switches::kShowLayoutShiftRegions, - switches::kShowPaintRects, switches::kStatsCollectionController, switches::kSkiaFontCacheLimitMb, switches::kSkiaResourceCacheLimitMb, @@ -3359,7 +3386,6 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer( switches::kTraceToConsole, switches::kUseFakeCodecForPeerConnection, switches::kUseFakeUIForMediaStream, - switches::kUseLegacyFormControls, switches::kUseMobileUserAgent, switches::kV, switches::kVideoCaptureUseGpuMemoryBuffer, @@ -3368,6 +3394,20 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer( switches::kVModule, switches::kWebglAntialiasingMode, switches::kWebglMSAASampleCount, + // Please keep these in alphabetical order. + blink::switches::kAllowPreCommitInput, + blink::switches::kDefaultTileWidth, + blink::switches::kDefaultTileHeight, + blink::switches::kDisableImageAnimationResync, + blink::switches::kDisableLowResTiling, + blink::switches::kDisableRGBA4444Textures, + blink::switches::kEnableLowResTiling, + blink::switches::kEnableRGBA4444Textures, + blink::switches::kMinHeightForGpuRasterTile, + blink::switches::kMaxUntiledLayerWidth, + blink::switches::kMaxUntiledLayerHeight, + blink::switches::kShowLayoutShiftRegions, + blink::switches::kShowPaintRects, // Please keep these in alphabetical order. Compositor switches here // should also be added to // chrome/browser/chromeos/login/chrome_restart_request.cc. @@ -3405,6 +3445,7 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer( #if defined(OS_ANDROID) switches::kDisableMediaSessionAPI, switches::kEnableReachedCodeProfiler, + switches::kReachedCodeSamplingIntervalUs, switches::kRendererWaitForJavaDebugger, #endif #if defined(OS_WIN) @@ -3766,8 +3807,8 @@ void RenderProcessHostImpl::Cleanup() { "browser_context", browser_context_); if (is_initialized_) { - base::PostTask( - FROM_HERE, {BrowserThread::IO}, + GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&WebRtcLog::ClearLogMessageCallback, GetID())); } @@ -3794,11 +3835,9 @@ void RenderProcessHostImpl::Cleanup() { info.status = base::TERMINATION_STATUS_NORMAL_TERMINATION; info.exit_code = 0; PopulateTerminationInfoRendererFields(&info); - within_cleanup_process_died_observer_ = true; for (auto& observer : observers_) { observer.RenderProcessExited(this, info); } - within_cleanup_process_died_observer_ = false; } for (auto& observer : observers_) observer.RenderProcessHostDestroyed(this); @@ -3819,8 +3858,8 @@ void RenderProcessHostImpl::Cleanup() { // that destroys the ResourceContext. Therefore the ClearResourceContext // task must be posted now to ensure it gets ahead of the destruction of // the ResourceContext in the IOThread sequence. - base::PostTask( - FROM_HERE, {BrowserThread::IO}, + GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&RenderFrameMessageFilter::ClearResourceContext, render_frame_message_filter_)); } @@ -4199,7 +4238,7 @@ RenderProcessHost* RenderProcessHostImpl::GetExistingProcessHost( if (iter.GetCurrentValue()->MayReuseHost() && RenderProcessHostImpl::IsSuitableHost( iter.GetCurrentValue(), site_instance->GetIsolationContext(), - site_instance->GetSiteURL(), site_instance->lock_url(), + site_instance->GetSiteInfo().site_url(), site_instance->lock_url(), site_instance->IsGuest())) { // The spare is always considered before process reuse. DCHECK_NE(iter.GetCurrentValue(), @@ -4246,7 +4285,7 @@ RenderProcessHost* RenderProcessHostImpl::GetUnusedProcessHostForServiceWorker( iter.GetCurrentValue()->IsUnused() && RenderProcessHostImpl::IsSuitableHost( iter.GetCurrentValue(), site_instance->GetIsolationContext(), - site_instance->GetSiteURL(), site_instance->lock_url(), + site_instance->GetSiteInfo().site_url(), site_instance->lock_url(), site_instance->IsGuest())) { return host; } @@ -4256,8 +4295,9 @@ RenderProcessHost* RenderProcessHostImpl::GetUnusedProcessHostForServiceWorker( } // static -bool RenderProcessHost::ShouldUseProcessPerSite(BrowserContext* browser_context, - const GURL& site_url) { +bool RenderProcessHostImpl::ShouldUseProcessPerSite( + BrowserContext* browser_context, + const SiteInfo& site_info) { // Returns true if we should use the process-per-site model. This will be // the case if the --process-per-site switch is specified, or in // process-per-site-instance for particular sites (e.g., NTP). Note that @@ -4270,29 +4310,30 @@ bool RenderProcessHost::ShouldUseProcessPerSite(BrowserContext* browser_context, // Error pages should use process-per-site model, as it is useful to // consolidate them to minimize resource usage and there is no security // drawback to combining them all in the same process. - if (site_url.SchemeIs(kChromeErrorScheme)) + if (site_info.site_url().SchemeIs(kChromeErrorScheme)) return true; // Otherwise let the content client decide, defaulting to false. - return GetContentClient()->browser()->ShouldUseProcessPerSite(browser_context, - site_url); + return GetContentClient()->browser()->ShouldUseProcessPerSite( + browser_context, site_info.site_url()); } // static RenderProcessHost* RenderProcessHostImpl::GetSoleProcessHostForURL( const IsolationContext& isolation_context, const GURL& url) { - GURL site_url = SiteInstanceImpl::GetSiteForURL(isolation_context, url); + SiteInfo site_info = + SiteInstanceImpl::ComputeSiteInfo(isolation_context, url); GURL lock_url = SiteInstanceImpl::DetermineProcessLockURL(isolation_context, url); - return GetSoleProcessHostForSite(isolation_context, site_url, lock_url, + return GetSoleProcessHostForSite(isolation_context, site_info, lock_url, /* is_guest */ false); } // static RenderProcessHost* RenderProcessHostImpl::GetSoleProcessHostForSite( const IsolationContext& isolation_context, - const GURL& site_url, + const SiteInfo& site_info, const GURL& lock_url, const bool is_guest) { // Look up the map of site to process for the given browser_context. @@ -4302,6 +4343,7 @@ RenderProcessHost* RenderProcessHostImpl::GetSoleProcessHostForSite( // See if we have an existing process with appropriate bindings for this // site. If not, the caller should create a new process and register it. // Note that IsSuitableHost expects a site URL rather than the full |url|. + const GURL& site_url = site_info.site_url(); RenderProcessHost* host = map->FindProcess(site_url.possibly_invalid_spec()); if (host && (!host->MayReuseHost() || !IsSuitableHost(host, isolation_context, site_url, lock_url, @@ -4331,7 +4373,8 @@ void RenderProcessHostImpl::RegisterSoleProcessHostForSite( // use process-per-site mode. We cannot check whether the process has // appropriate bindings here, because the bindings have not yet been // granted. - std::string site = site_instance->GetSiteURL().possibly_invalid_spec(); + std::string site = + site_instance->GetSiteInfo().site_url().possibly_invalid_spec(); if (!site.empty()) map->RegisterProcess(site, process); } @@ -4339,7 +4382,7 @@ void RenderProcessHostImpl::RegisterSoleProcessHostForSite( // static RenderProcessHost* RenderProcessHostImpl::GetProcessHostForSiteInstance( SiteInstanceImpl* site_instance) { - const GURL site_url = site_instance->GetSiteURL(); + const SiteInfo& site_info = site_instance->GetSiteInfo(); SiteInstanceImpl::ProcessReusePolicy process_reuse_policy = site_instance->process_reuse_policy(); RenderProcessHost* render_process_host = nullptr; @@ -4351,7 +4394,7 @@ RenderProcessHost* RenderProcessHostImpl::GetProcessHostForSiteInstance( switch (process_reuse_policy) { case SiteInstanceImpl::ProcessReusePolicy::PROCESS_PER_SITE: render_process_host = GetSoleProcessHostForSite( - site_instance->GetIsolationContext(), site_url, + site_instance->GetIsolationContext(), site_info, site_instance->lock_url(), site_instance->IsGuest()); break; case SiteInstanceImpl::ProcessReusePolicy::REUSE_PENDING_OR_COMMITTED_SITE: @@ -4410,8 +4453,8 @@ RenderProcessHost* RenderProcessHostImpl::GetProcessHostForSiteInstance( } // If not (or if none found), see if we should reuse an existing process. - if (!render_process_host && - ShouldTryToUseExistingProcessHost(browser_context, site_url)) { + if (!render_process_host && ShouldTryToUseExistingProcessHost( + browser_context, site_info.site_url())) { render_process_host = GetExistingProcessHost(site_instance); } @@ -4421,13 +4464,14 @@ RenderProcessHost* RenderProcessHostImpl::GetProcessHostForSiteInstance( // site. if (render_process_host && !RenderProcessHostImpl::IsSuitableHost( - render_process_host, site_instance->GetIsolationContext(), site_url, - site_instance->lock_url(), site_instance->IsGuest())) { + render_process_host, site_instance->GetIsolationContext(), + site_info.site_url(), site_instance->lock_url(), + site_instance->IsGuest())) { base::debug::SetCrashKeyString(bad_message::GetRequestedSiteURLKey(), - site_url.possibly_invalid_spec()); + site_info.GetDebugString()); ChildProcessSecurityPolicyImpl::GetInstance()->LogKilledProcessOriginLock( render_process_host->GetID()); - CHECK(false) << "Unsuitable process reused for site " << site_url; + CHECK(false) << "Unsuitable process reused for site " << site_info; } // Otherwise, create a new RenderProcessHost. @@ -4906,15 +4950,14 @@ void RenderProcessHostImpl::OnProcessLaunched() { } // Pass bits of global renderer state to the renderer. + GetRendererInterface()->SetIsCrossOriginIsolated(cross_origin_isolated_); GetRendererInterface()->SetUserAgent( GetContentClient()->browser()->GetUserAgent()); GetRendererInterface()->SetUserAgentMetadata( GetContentClient()->browser()->GetUserAgentMetadata()); + GetRendererInterface()->SetCorsExemptHeaderList( + storage_partition_impl_->cors_exempt_header_list()); NotifyRendererIfLockedToSite(); - if (SiteIsolationPolicy::UseDedicatedProcessesForAllSites() && - base::FeatureList::IsEnabled(features::kV8LowMemoryModeForSubframes)) { - GetRendererInterface()->EnableV8LowMemoryMode(); - } // Send the initial system color info to the renderer. ThemeHelper::GetInstance()->SendSystemColorInfo(GetRendererInterface()); @@ -4985,9 +5028,10 @@ RenderProcessHost* RenderProcessHostImpl::FindReusableProcessHostForSiteInstance( SiteInstanceImpl* site_instance) { BrowserContext* browser_context = site_instance->GetBrowserContext(); - GURL site_url(site_instance->GetSiteURL()); - if (!ShouldFindReusableProcessHostForSite(browser_context, site_url)) + if (!ShouldFindReusableProcessHostForSite(browser_context, + site_instance->GetSiteInfo())) { return nullptr; + } std::set<RenderProcessHost*> eligible_foreground_hosts; std::set<RenderProcessHost*> eligible_background_hosts; @@ -5135,35 +5179,37 @@ void RenderProcessHostImpl::ProvideStatusFileForRenderer() { #endif void RenderProcessHostImpl::ProvideSwapFileForRenderer() { - if (!base::FeatureList::IsEnabled(features::kParkableStringsToDisk)) + if (!base::FeatureList::IsEnabled(blink::features::kParkableStringsToDisk)) return; - mojo::Remote<blink::mojom::DiskAllocator> allocator; - BindReceiver(allocator.BindNewPipeAndPassReceiver()); - // In Incognito, nothing should be written to disk. Providing an invalid file - // prevents the renderer from doing so. - if (GetBrowserContext()->IsOffTheRecord()) { - allocator->ProvideTemporaryFile(base::File()); + // In Incognito, nothing should be written to disk. Don't provide a file.. + if (GetBrowserContext()->IsOffTheRecord()) return; - } + + mojo::Remote<blink::mojom::DiskAllocator> allocator; + BindReceiver(allocator.BindNewPipeAndPassReceiver()); // File creation done on a background thread. The renderer side will behave // correctly even if the file is provided later or never. base::ThreadPool::PostTaskAndReplyWithResult( FROM_HERE, {base::MayBlock()}, base::BindOnce([]() { base::FilePath path; - CHECK(base::CreateTemporaryFile(&path)); + if (!base::CreateTemporaryFile(&path)) + return base::File(); int flags = base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_READ | base::File::FLAG_WRITE | base::File::FLAG_DELETE_ON_CLOSE; - auto file = base::File(base::FilePath(path), flags); - CHECK(file.IsValid()); - return file; + return base::File(base::FilePath(path), flags); }), base::BindOnce( [](mojo::Remote<blink::mojom::DiskAllocator> allocator, base::File file) { - allocator->ProvideTemporaryFile(std::move(file)); + // File creation failed in the background. In this case, don't + // provide a file, the renderer will not wait for one (see the + // incognito case above, the renderer deals with no file being + // provided). + if (file.IsValid()) + allocator->ProvideTemporaryFile(std::move(file)); }, std::move(allocator))); } diff --git a/chromium/content/browser/renderer_host/render_process_host_impl.h b/chromium/content/browser/renderer_host/render_process_host_impl.h index 391355c38d1..734767f1555 100644 --- a/chromium/content/browser/renderer_host/render_process_host_impl.h +++ b/chromium/content/browser/renderer_host/render_process_host_impl.h @@ -28,7 +28,6 @@ #include "base/sequenced_task_runner.h" #include "base/single_thread_task_runner.h" #include "base/synchronization/waitable_event.h" -#include "base/task/post_task.h" #include "base/threading/sequence_bound.h" #include "build/build_config.h" #include "content/browser/child_process_launcher.h" @@ -97,7 +96,7 @@ namespace base { class CommandLine; class PersistentMemoryAllocator; -} +} // namespace base namespace url { class Origin; @@ -125,6 +124,7 @@ class RenderProcessHostFactory; class RenderProcessHostTest; class RenderWidgetHelper; class ResolveProxyHelper; +class SiteInfo; class SiteInstance; class SiteInstanceImpl; class StoragePartition; @@ -173,7 +173,13 @@ class CONTENT_EXPORT RenderProcessHostImpl static RenderProcessHost* CreateRenderProcessHost( BrowserContext* browser_context, StoragePartitionImpl* storage_partition_impl, - SiteInstance* site_instance); + SiteInstanceImpl* site_instance); + + // Returns whether the process-per-site model is in use (globally or just for + // the current site), in which case we should ensure there is only one + // RenderProcessHost per site for the entire browser context. + static bool ShouldUseProcessPerSite(BrowserContext* browser_context, + const SiteInfo& site_info); ~RenderProcessHostImpl() override; @@ -255,6 +261,7 @@ class CONTENT_EXPORT RenderProcessHostImpl bool HostHasNotBeenUsed() override; void LockToOrigin(const IsolationContext& isolation_context, const GURL& lock_url) override; + bool IsLockedToOriginForTesting() override; void BindCacheStorage( const network::CrossOriginEmbedderPolicy& cross_origin_embedder_policy, mojo::PendingRemote<network::mojom::CrossOriginEmbedderPolicyReporter> @@ -302,16 +309,6 @@ class CONTENT_EXPORT RenderProcessHostImpl child_process_activity_time_ = base::TimeTicks::Now(); } - // TODO(https://crbug.com/1006814): Delete this. - bool GetWithinProcessDiedObserverForCrbug1006814() { - return within_process_died_observer_; - } - - // TODO(https://crbug.com/1006814): Delete this. - bool GetWithinCleanupProcessDiedObserverForCrbug1006814() { - return within_cleanup_process_died_observer_; - } - // Used to extend the lifetime of the sessions until the render view // in the renderer is fully closed. This is static because its also called // with mock hosts as input in test cases. The RenderWidget routing associated @@ -341,6 +338,9 @@ class CONTENT_EXPORT RenderProcessHostImpl // not the actual site that the process is locked to, which happens for // hosted apps. |is_guest| should be set to true if the call is being made // for a <webview> guest SiteInstance. + // TODO(wjmaclean): Rethink |how site_url|/|lock_url| parameters are passed. + // |site_url| will probably become a SiteInfo, but whether we want to combine + // |lock_url| into that or keep it separate needs to be decided. static bool IsSuitableHost(RenderProcessHost* host, const IsolationContext& isolation_context, const GURL& site_url, @@ -353,7 +353,7 @@ class CONTENT_EXPORT RenderProcessHostImpl // This should only be used for process-per-site mode, which can be enabled // globally with a command line flag or per-site, as determined by // SiteInstanceImpl::ShouldUseProcessPerSite. - // Important: |url| should be a full URL and *not* a site URL. + // Important: |url| should be a full URL and *not* a SiteInfo. static RenderProcessHost* GetSoleProcessHostForURL( const IsolationContext& isolation_context, const GURL& url); @@ -363,7 +363,7 @@ class CONTENT_EXPORT RenderProcessHostImpl // to true if the call is being made for a <webview> guest SiteInstance. static RenderProcessHost* GetSoleProcessHostForSite( const IsolationContext& isolation_context, - const GURL& site_url, + const SiteInfo& site_info, const GURL& lock_url, const bool is_guest); @@ -504,25 +504,25 @@ class CONTENT_EXPORT RenderProcessHostImpl static RenderProcessHostFactory* get_render_process_host_factory_for_testing(); - // Tracks which sites frames are hosted in which RenderProcessHosts. + // Tracks which sites' frames are hosted in which RenderProcessHosts. // TODO(ericrobinson): These don't need to be static. static void AddFrameWithSite(BrowserContext* browser_context, RenderProcessHost* render_process_host, - const GURL& site_url); + const SiteInfo& site_info); static void RemoveFrameWithSite(BrowserContext* browser_context, RenderProcessHost* render_process_host, - const GURL& site_url); + const SiteInfo& site_info); // Tracks which sites navigations are expected to commit in which // RenderProcessHosts. static void AddExpectedNavigationToSite( BrowserContext* browser_context, RenderProcessHost* render_process_host, - const GURL& site_url); + const SiteInfo& site_info); static void RemoveExpectedNavigationToSite( BrowserContext* browser_context, RenderProcessHost* render_process_host, - const GURL& site_url); + const SiteInfo& site_info); // Discards the spare RenderProcessHost. After this call, // GetSpareRenderProcessHostForTesting will return nullptr. @@ -924,7 +924,7 @@ class CONTENT_EXPORT RenderProcessHostImpl base::BindRepeating( &InterfaceGetter<CallbackType>::GetInterfaceOnUIThread, instance_weak_factory_->GetWeakPtr(), std::move(callback)), - base::CreateSingleThreadTaskRunner({BrowserThread::UI})); + GetUIThreadTaskRunner({})); } // Callback to unblock process shutdown after waiting for unload handlers to @@ -1121,11 +1121,6 @@ class CONTENT_EXPORT RenderProcessHostImpl // and calling through RenderProcessHostObserver::RenderProcessExited. bool within_process_died_observer_; - // Indicates whether RenderProcessHostImpl::Cleanup is currently iterating and - // calling through RenderProcessHostObserver::RenderProcessExited. - // TODO(https://crbug.com/1006814): Delete this. - bool within_cleanup_process_died_observer_ = false; - std::unique_ptr<P2PSocketDispatcherHost> p2p_socket_dispatcher_host_; // Must be accessed on UI thread. @@ -1219,6 +1214,13 @@ class CONTENT_EXPORT RenderProcessHostImpl friend class IOThreadHostImpl; base::Optional<base::SequenceBound<IOThreadHostImpl>> io_thread_host_impl_; + // Representing agent cluster's "cross-origin isolated" concept. + // TODO(yhirano): Have the spec URL. + // This property is renderer process global because we ensure that a + // renderer process host only cross-origin isolated agents or only + // non-cross-origin isolated agents, not both. + const bool cross_origin_isolated_ = false; + base::WeakPtrFactory<RenderProcessHostImpl> weak_factory_{this}; DISALLOW_COPY_AND_ASSIGN(RenderProcessHostImpl); diff --git a/chromium/content/browser/renderer_host/render_process_host_unittest.cc b/chromium/content/browser/renderer_host/render_process_host_unittest.cc index 6426b5865b2..dbf083b804c 100644 --- a/chromium/content/browser/renderer_host/render_process_host_unittest.cc +++ b/chromium/content/browser/renderer_host/render_process_host_unittest.cc @@ -773,20 +773,15 @@ class StoragePartitionContentBrowserClient : public ContentBrowserClient { ~StoragePartitionContentBrowserClient() override {} private: - void GetStoragePartitionConfigForSite(BrowserContext* browser_context, - const GURL& site, - bool can_be_default, - std::string* partition_domain, - std::string* partition_name, - bool* in_memory) override { - partition_domain->clear(); - partition_name->clear(); - *in_memory = false; - + StoragePartitionConfig GetStoragePartitionConfigForSite( + BrowserContext* browser_context, + const GURL& site) override { if (site == site_) { - *partition_domain = partition_domain_; - *partition_name = partition_name_; + return StoragePartitionConfig::Create(partition_domain_, partition_name_, + false /* in_memory */); } + + return StoragePartitionConfig::CreateDefault(); } GURL site_; diff --git a/chromium/content/browser/renderer_host/render_view_host_delegate.h b/chromium/content/browser/renderer_host/render_view_host_delegate.h index c34293bd704..3dee9eb0ad0 100644 --- a/chromium/content/browser/renderer_host/render_view_host_delegate.h +++ b/chromium/content/browser/renderer_host/render_view_host_delegate.h @@ -15,7 +15,6 @@ #include "content/browser/dom_storage/session_storage_namespace_impl.h" #include "content/common/content_export.h" #include "content/common/render_message_filter.mojom.h" -#include "content/common/widget.mojom.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "net/base/load_states.h" diff --git a/chromium/content/browser/renderer_host/render_view_host_delegate_view.h b/chromium/content/browser/renderer_host/render_view_host_delegate_view.h index a0456b2020d..33d70dde9a2 100644 --- a/chromium/content/browser/renderer_host/render_view_host_delegate_view.h +++ b/chromium/content/browser/renderer_host/render_view_host_delegate_view.h @@ -12,9 +12,9 @@ #include "content/common/buildflags.h" #include "content/common/content_export.h" #include "content/common/drag_event_source_info.h" +#include "third_party/blink/public/common/page/web_drag_operation.h" #include "third_party/blink/public/mojom/choosers/popup_menu.mojom.h" #include "third_party/blink/public/mojom/input/input_event_result.mojom-shared.h" -#include "third_party/blink/public/platform/web_drag_operation.h" namespace blink { class WebGestureEvent; diff --git a/chromium/content/browser/renderer_host/render_view_host_factory.cc b/chromium/content/browser/renderer_host/render_view_host_factory.cc index 305aba1bb7f..1db0c391dab 100644 --- a/chromium/content/browser/renderer_host/render_view_host_factory.cc +++ b/chromium/content/browser/renderer_host/render_view_host_factory.cc @@ -38,7 +38,7 @@ RenderViewHost* RenderViewHostFactory::Create( RenderViewHostImpl* view_host = new RenderViewHostImpl( instance, RenderWidgetHostFactory::Create(widget_delegate, instance->GetProcess(), - widget_routing_id, mojo::NullRemote(), + widget_routing_id, /*hidden=*/true), delegate, routing_id, main_frame_routing_id, swapped_out, true /* has_initialized_audio_host */); diff --git a/chromium/content/browser/renderer_host/render_view_host_impl.cc b/chromium/content/browser/renderer_host/render_view_host_impl.cc index 8c6deced5a7..c5140471ec2 100644 --- a/chromium/content/browser/renderer_host/render_view_host_impl.cc +++ b/chromium/content/browser/renderer_host/render_view_host_impl.cc @@ -36,6 +36,9 @@ #include "content/browser/child_process_security_policy_impl.h" #include "content/browser/dom_storage/session_storage_namespace_impl.h" #include "content/browser/frame_host/frame_tree.h" +#include "content/browser/frame_host/frame_tree_node.h" +#include "content/browser/frame_host/navigation_controller_impl.h" +#include "content/browser/frame_host/render_frame_proxy_host.h" #include "content/browser/gpu/compositor_util.h" #include "content/browser/gpu/gpu_data_manager_impl.h" #include "content/browser/gpu/gpu_process_host.h" @@ -331,11 +334,8 @@ SiteInstanceImpl* RenderViewHostImpl::GetSiteInstance() { } bool RenderViewHostImpl::CreateRenderView( - int opener_frame_route_id, + const base::Optional<base::UnguessableToken>& opener_frame_token, int proxy_route_id, - const base::UnguessableToken& frame_token, - const base::UnguessableToken& devtools_frame_token, - const FrameReplicationState& replicated_frame_state, bool window_was_created_with_opener) { TRACE_EVENT0("renderer_host,navigation", "RenderViewHostImpl::CreateRenderView"); @@ -357,14 +357,19 @@ bool RenderViewHostImpl::CreateRenderView( proxy_route_id != MSG_ROUTING_NONE)); RenderFrameHostImpl* main_rfh = nullptr; + RenderFrameProxyHost* main_rfph = nullptr; if (main_frame_routing_id_ != MSG_ROUTING_NONE) { main_rfh = RenderFrameHostImpl::FromID(GetProcess()->GetID(), main_frame_routing_id_); DCHECK(main_rfh); + } else { + main_rfph = + RenderFrameProxyHost::FromID(GetProcess()->GetID(), proxy_route_id); } + const FrameTreeNode* const frame_tree_node = + main_rfh ? main_rfh->frame_tree_node() : main_rfph->frame_tree_node(); - GetWidget()->SetRendererInitialized( - true, RenderWidgetHostImpl::RendererInitializer::kCreateRenderView); + GetWidget()->set_renderer_initialized(true); mojom::CreateViewParamsPtr params = mojom::CreateViewParams::New(); params->renderer_preferences = @@ -391,12 +396,13 @@ bool RenderViewHostImpl::CreateRenderView( std::tie(params->frame_widget_host, params->frame_widget) = main_rfh->GetRenderWidgetHost()->BindNewFrameWidgetInterfaces(); } - params->main_frame_frame_token = frame_token; + params->main_frame_frame_token = + main_rfh ? main_rfh->GetFrameToken() : main_rfph->GetFrameToken(); params->session_storage_namespace_id = delegate_->GetSessionStorageNamespace(instance_.get())->id(); // Ensure the RenderView sets its opener correctly. - params->opener_frame_route_id = opener_frame_route_id; - params->replicated_frame_state = replicated_frame_state; + params->opener_frame_token = opener_frame_token; + params->replicated_frame_state = frame_tree_node->current_replication_state(); params->proxy_routing_id = proxy_route_id; params->hidden = GetWidget()->delegate()->IsHidden(); params->never_composited = delegate_->IsNeverComposited(); @@ -404,9 +410,9 @@ bool RenderViewHostImpl::CreateRenderView( if (main_rfh) { params->has_committed_real_load = main_rfh->frame_tree_node()->has_committed_real_load(); - DCHECK_EQ(params->main_frame_frame_token, main_rfh->frame_token()); + DCHECK_EQ(params->main_frame_frame_token, main_rfh->GetFrameToken()); } - params->devtools_main_frame_token = devtools_frame_token; + params->devtools_main_frame_token = frame_tree_node->devtools_frame_token(); // GuestViews in the same StoragePartition need to find each other's frames. params->renderer_wide_named_frame_lookup = GetSiteInstance()->IsGuest(); params->inside_portal = delegate_->IsPortal(); @@ -443,11 +449,6 @@ void RenderViewHostImpl::SetMainFrameRoutingId(int routing_id) { GetWidget()->UpdatePriority(); } -// TODO(https://crbug.com/1006814): Delete this. -int RenderViewHostImpl::GetMainFrameRoutingIdForCrbug1006814() { - return main_frame_routing_id_; -} - void RenderViewHostImpl::EnterBackForwardCache() { if (!will_enter_back_forward_cache_callback_for_testing_.is_null()) will_enter_back_forward_cache_callback_for_testing_.Run(); @@ -456,8 +457,9 @@ void RenderViewHostImpl::EnterBackForwardCache() { FrameTree* frame_tree = GetDelegate()->GetFrameTree(); frame_tree->UnregisterRenderViewHost(this); is_in_back_forward_cache_ = true; - // TODO(altimin, dcheng): This should be a ViewMsg. - Send(new PageMsg_PutPageIntoBackForwardCache(GetRoutingID())); + page_lifecycle_state_manager_->SetIsInBackForwardCache( + is_in_back_forward_cache_, + /*navigation_start=*/base::nullopt); } void RenderViewHostImpl::LeaveBackForwardCache( @@ -468,17 +470,37 @@ void RenderViewHostImpl::LeaveBackForwardCache( // guaranteed to be committed, so it should be reused going forward. frame_tree->RegisterRenderViewHost(this); is_in_back_forward_cache_ = false; - Send(new PageMsg_RestorePageFromBackForwardCache(GetRoutingID(), - navigation_start)); + page_lifecycle_state_manager_->SetIsInBackForwardCache( + is_in_back_forward_cache_, navigation_start); +} + +void RenderViewHostImpl::SetVisibility( + blink::mojom::PageVisibilityState visibility) { + page_lifecycle_state_manager_->SetWebContentsVisibility(visibility); } void RenderViewHostImpl::SetIsFrozen(bool frozen) { page_lifecycle_state_manager_->SetIsFrozen(frozen); } -void RenderViewHostImpl::SetVisibility( - blink::mojom::PageVisibilityState visibility) { - page_lifecycle_state_manager_->SetVisibility(visibility); +void RenderViewHostImpl::OnBackForwardCacheTimeout() { + // TODO(yuzus): Implement a method to get a list of RenderFrameHosts + // associated with |this|, instead of iterating through all the + // RenderFrameHosts in bfcache. + const auto& entries = delegate_->GetFrameTree() + ->controller() + ->GetBackForwardCache() + .GetEntries(); + for (auto& entry : entries) { + for (auto* const rvh : entry->render_view_hosts) { + if (rvh == this) { + RenderFrameHostImpl* rfh = entry->render_frame_host.get(); + rfh->EvictFromBackForwardCacheWithReason( + BackForwardCacheMetrics::NotRestoredReason::kTimeoutPuttingInCache); + break; + } + } + } } bool RenderViewHostImpl::IsRenderViewLive() { @@ -559,9 +581,6 @@ const WebPreferences RenderViewHostImpl::ComputeWebPreferences() { command_line.HasSwitch(switches::kDisable2dCanvasAntialiasing); prefs.antialiased_clips_2d_canvas_enabled = !command_line.HasSwitch(switches::kDisable2dCanvasClipAntialiasing); - prefs.accelerated_2d_canvas_msaa_sample_count = - atoi(command_line.GetSwitchValueASCII( - switches::kAcceleratedCanvas2dMSAASampleCount).c_str()); prefs.disable_ipc_flooding_protection = command_line.HasSwitch(switches::kDisableIpcFloodingProtection) || @@ -897,7 +916,6 @@ bool RenderViewHostImpl::OnMessageReceived(const IPC::Message& msg) { IPC_MESSAGE_HANDLER(ViewHostMsg_RouteCloseEvent, OnRouteCloseEvent) IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateTargetURL, OnUpdateTargetURL) IPC_MESSAGE_HANDLER(ViewHostMsg_TakeFocus, OnTakeFocus) - IPC_MESSAGE_HANDLER(ViewHostMsg_Focus, OnFocus) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() @@ -964,6 +982,12 @@ void RenderViewHostImpl::OnFocus() { delegate_->Activate(); } +void RenderViewHostImpl::BindPageBroadcast( + mojo::PendingAssociatedRemote<blink::mojom::PageBroadcast> page_broadcast) { + page_broadcast_.reset(); + page_broadcast_.Bind(std::move(page_broadcast)); +} + const mojo::AssociatedRemote<blink::mojom::PageBroadcast>& RenderViewHostImpl::GetAssociatedPageBroadcast() { return page_broadcast_; @@ -1123,6 +1147,10 @@ void RenderViewHostImpl::OnThemeColorChanged( delegate_->OnThemeColorChanged(this); } +void RenderViewHostImpl::SetContentsMimeType(const std::string mime_type) { + contents_mime_type_ = mime_type; +} + void RenderViewHostImpl::DocumentOnLoadCompletedInMainFrame() { is_document_on_load_completed_in_main_frame_ = true; } diff --git a/chromium/content/browser/renderer_host/render_view_host_impl.h b/chromium/content/browser/renderer_host/render_view_host_impl.h index 9d3783d1b99..e1f95d70284 100644 --- a/chromium/content/browser/renderer_host/render_view_host_impl.h +++ b/chromium/content/browser/renderer_host/render_view_host_impl.h @@ -16,9 +16,9 @@ #include "base/callback.h" #include "base/compiler_specific.h" #include "base/gtest_prod_util.h" -#include "base/logging.h" #include "base/macros.h" #include "base/memory/ref_counted.h" +#include "base/optional.h" #include "base/process/kill.h" #include "build/build_config.h" #include "content/browser/renderer_host/input/input_device_change_observer.h" @@ -27,6 +27,7 @@ #include "content/browser/renderer_host/render_widget_host_owner_delegate.h" #include "content/browser/site_instance_impl.h" #include "content/common/render_message_filter.mojom.h" +#include "content/public/browser/global_routing_id.h" #include "content/public/browser/notification_observer.h" #include "content/public/browser/render_process_host_observer.h" #include "content/public/browser/render_view_host.h" @@ -42,7 +43,6 @@ namespace content { -struct FrameReplicationState; class TimeoutMonitor; // A callback which will be called immediately before EnterBackForwardCache @@ -129,18 +129,9 @@ class CONTENT_EXPORT RenderViewHostImpl // created with an opener. (The opener may have been closed since.) // |proxy_route_id| is only used when creating a RenderView in an inactive // state. - // |frame_token| contains the frame token for the associated - // RenderFrameHostImpl or RenderFrameProxyHost. - // |devtools_frame_token| contains the devtools token for tagging requests - // and attributing them to the context frame. - // |replicated_frame_state| contains replicated data for the top-level - // frame, such as its name and sandbox flags. virtual bool CreateRenderView( - int opener_frame_route_id, + const base::Optional<base::UnguessableToken>& opener_frame_token, int proxy_route_id, - const base::UnguessableToken& frame_token, - const base::UnguessableToken& devtools_frame_token, - const FrameReplicationState& replicated_frame_state, bool window_was_created_with_opener); // Tracks whether this RenderViewHost is in an active state (rather than @@ -209,10 +200,6 @@ class CONTENT_EXPORT RenderViewHostImpl // view is not considered active. void SetMainFrameRoutingId(int routing_id); - // TODO(https://crbug.com/1006814): Delete this. - // Do not use this for anything except debugging. - int GetMainFrameRoutingIdForCrbug1006814(); - // Called when the RenderFrameHostImpls/RenderFrameProxyHosts that own this // RenderViewHost enter the BackForwardCache. void EnterBackForwardCache(); @@ -225,9 +212,11 @@ class CONTENT_EXPORT RenderViewHostImpl // to allow it to record the latency of this navigation. void LeaveBackForwardCache(base::TimeTicks navigation_start); - void SetIsFrozen(bool frozen); void SetVisibility(blink::mojom::PageVisibilityState visibility); + void SetIsFrozen(bool frozen); + void OnBackForwardCacheTimeout(); + // Called during frame eviction to return all SurfaceIds in the frame tree. // Marks all views in the frame tree as evicted. std::vector<viz::SurfaceId> CollectSurfaceIdsForEviction(); @@ -249,6 +238,9 @@ class CONTENT_EXPORT RenderViewHostImpl return main_frame_theme_color_; } + void SetContentsMimeType(std::string mime_type); + const std::string& contents_mime_type() { return contents_mime_type_; } + // Notifies that / returns whether main document's onload() handler was // completed. void DocumentOnLoadCompletedInMainFrame(); @@ -260,6 +252,10 @@ class CONTENT_EXPORT RenderViewHostImpl void SetWillEnterBackForwardCacheCallbackForTesting( const WillEnterBackForwardCacheCallbackForTesting& callback); + void BindPageBroadcast( + mojo::PendingAssociatedRemote<blink::mojom::PageBroadcast> + page_broadcast); + // The remote mojom::PageBroadcast interface that is used to send messages to // the renderer's blink::WebViewImpl when broadcasting messages to all // renderers hosting frames in the frame tree. @@ -416,6 +412,10 @@ class CONTENT_EXPORT RenderViewHostImpl // by theme-color meta tag. base::Optional<SkColor> main_frame_theme_color_; + // Contents MIME type for the main document. It can be used to check whether + // we can do something for special contents. + std::string contents_mime_type_; + // ---------- Per page state END -------------------------------------------- // BackForwardCache: diff --git a/chromium/content/browser/renderer_host/render_view_host_unittest.cc b/chromium/content/browser/renderer_host/render_view_host_unittest.cc index bee3742a8ba..5539341344b 100644 --- a/chromium/content/browser/renderer_host/render_view_host_unittest.cc +++ b/chromium/content/browser/renderer_host/render_view_host_unittest.cc @@ -26,14 +26,13 @@ #include "content/public/common/url_constants.h" #include "content/public/test/mock_render_process_host.h" #include "content/public/test/navigation_simulator.h" -#include "content/test/mock_widget_impl.h" #include "content/test/navigation_simulator_impl.h" #include "content/test/test_content_browser_client.h" #include "content/test/test_render_view_host.h" #include "content/test/test_web_contents.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "net/base/filename_util.h" -#include "third_party/blink/public/platform/web_drag_operation.h" +#include "third_party/blink/public/common/page/web_drag_operation.h" #include "ui/base/page_transition_types.h" namespace content { @@ -82,65 +81,6 @@ TEST_F(RenderViewHostTest, FilterAbout) { EXPECT_EQ(GURL(kBlockedURL), controller().GetVisibleEntry()->GetURL()); } -// The RenderViewHost tells the renderer process about SetBackgroundOpaque() -// changes. - -class FakeFrameWidget : public blink::mojom::FrameWidget { - public: - explicit FakeFrameWidget( - mojo::PendingAssociatedReceiver<blink::mojom::FrameWidget> frame_widget) - : receiver_(this, std::move(frame_widget)) {} - FakeFrameWidget(const FakeFrameWidget&) = delete; - void operator=(const FakeFrameWidget&) = delete; - - bool GetBackgroundOpaque() const { - DCHECK_NE(value_, -1); - return value_; - } - void Reset() { value_ = -1; } - - private: - void DragSourceSystemDragEnded() override {} - void SetBackgroundOpaque(bool value) override { value_ = value; } - void SetInheritedEffectiveTouchActionForSubFrame( - const cc::TouchAction touch_action) override {} - void UpdateRenderThrottlingStatusForSubFrame( - bool is_throttled, - bool subtree_throttled) override {} - void SetIsInertForSubFrame(bool inert) override {} - - mojo::AssociatedReceiver<blink::mojom::FrameWidget> receiver_; - int value_ = -1; -}; - -TEST_F(RenderViewHostTest, SetBackgroundOpaque) { - mojo::AssociatedRemote<blink::mojom::FrameWidgetHost> blink_frame_widget_host; - auto blink_frame_widget_host_receiver = - blink_frame_widget_host - .BindNewEndpointAndPassDedicatedReceiverForTesting(); - mojo::AssociatedRemote<blink::mojom::FrameWidget> blink_frame_widget; - auto blink_frame_widget_receiver = - blink_frame_widget.BindNewEndpointAndPassDedicatedReceiverForTesting(); - - test_rvh()->GetWidget()->BindFrameWidgetInterfaces( - std::move(blink_frame_widget_host_receiver), blink_frame_widget.Unbind()); - - FakeFrameWidget fake_frame_widget(std::move(blink_frame_widget_receiver)); - - for (bool value : {true, false}) { - SCOPED_TRACE(value); - // This method is part of RenderWidgetHostOwnerDelegate, provided to the - // main frame RenderWidgetHost, which uses it to inform the RenderView - // in the renderer process of the background opaque state. - test_rvh()->GetWidget()->GetAssociatedFrameWidget()->SetBackgroundOpaque( - value); - base::RunLoop().RunUntilIdle(); - - EXPECT_EQ(fake_frame_widget.GetBackgroundOpaque(), value); - fake_frame_widget.Reset(); - } -} - // Ensure we do not grant bindings to a process shared with unprivileged views. TEST_F(RenderViewHostTest, DontGrantBindingsToSharedProcess) { // Create another view in the same process. diff --git a/chromium/content/browser/renderer_host/render_widget_helper.cc b/chromium/content/browser/renderer_host/render_widget_helper.cc index 7bc045c0ef9..6956acd048e 100644 --- a/chromium/content/browser/renderer_host/render_widget_helper.cc +++ b/chromium/content/browser/renderer_host/render_widget_helper.cc @@ -8,7 +8,6 @@ #include "base/bind_helpers.h" #include "base/lazy_instance.h" #include "base/posix/eintr_wrapper.h" -#include "base/task/post_task.h" #include "base/threading/thread.h" #include "base/threading/thread_restrictions.h" #include "content/browser/renderer_host/render_view_host_impl.h" @@ -47,8 +46,8 @@ RenderWidgetHelper::~RenderWidgetHelper() { void RenderWidgetHelper::Init(int render_process_id) { render_process_id_ = render_process_id; - base::PostTask(FROM_HERE, {BrowserThread::IO}, - base::BindOnce(&AddWidgetHelper, render_process_id_, + GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&AddWidgetHelper, render_process_id_, base::WrapRefCounted(this))); } diff --git a/chromium/content/browser/renderer_host/render_widget_host_browsertest.cc b/chromium/content/browser/renderer_host/render_widget_host_browsertest.cc index 17927da5571..37bef5f7e14 100644 --- a/chromium/content/browser/renderer_host/render_widget_host_browsertest.cc +++ b/chromium/content/browser/renderer_host/render_widget_host_browsertest.cc @@ -17,7 +17,6 @@ #include "content/browser/renderer_host/render_widget_host_input_event_router.h" #include "content/browser/renderer_host/render_widget_host_view_base.h" #include "content/browser/web_contents/web_contents_impl.h" -#include "content/common/input/synthetic_web_input_event_builders.h" #include "content/common/view_messages.h" #include "content/common/widget_messages.h" #include "content/public/browser/notification_types.h" @@ -34,6 +33,7 @@ #include "net/dns/mock_host_resolver.h" #include "net/test/embedded_test_server/embedded_test_server.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/common/input/synthetic_web_input_event_builders.h" #include "third_party/blink/public/common/input/web_input_event.h" #include "third_party/blink/public/common/input/web_mouse_event.h" #include "ui/events/base_event_utils.h" @@ -164,7 +164,7 @@ class RenderWidgetHostTouchEmulatorBrowserTest : public ContentBrowserTest { int modifiers, bool pressed) { blink::WebMouseEvent event = - SyntheticWebMouseEventBuilder::Build(type, x, y, modifiers); + blink::SyntheticWebMouseEventBuilder::Build(type, x, y, modifiers); if (pressed) event.button = blink::WebMouseEvent::Button::kLeft; event.SetTimeStamp(GetNextSimulatedEventTime()); @@ -177,6 +177,7 @@ class RenderWidgetHostTouchEmulatorBrowserTest : public ContentBrowserTest { } RenderWidgetHostImpl* host() { return host_; } + RenderWidgetHostViewBase* view() { return view_; } private: RenderWidgetHostViewBase* view_; @@ -679,4 +680,39 @@ IN_PROC_BROWSER_TEST_F(RenderWidgetHostBrowserTest, EvalJs(web_contents(), "`${screen.width}x${screen.height}`")); } +class RenderWidgetHostDelegatedInkMetadataTest + : public RenderWidgetHostTouchEmulatorBrowserTest { + public: + RenderWidgetHostDelegatedInkMetadataTest() = default; + + void SetUpCommandLine(base::CommandLine* command_line) override { + ContentBrowserTest::SetUpCommandLine(command_line); + command_line->AppendSwitchASCII(switches::kEnableBlinkFeatures, + "DelegatedInkTrails"); + } +}; + +// Confirm that using the |updateInkTrailStartPoint| JS API results in the +// |request_points_for_delegated_ink_| flag being set on the RWHVB. +IN_PROC_BROWSER_TEST_F(RenderWidgetHostDelegatedInkMetadataTest, + FlagGetsSetFromRenderFrameMetadata) { + ASSERT_TRUE(ExecJs(shell()->web_contents(), R"( + let presenter = navigator.ink.requestPresenter('delegated-ink-trail'); + let style = { color: 'green', diameter: 21 }; + window.addEventListener('pointermove' , evt => { + presenter.then( function(v) { + v.updateInkTrailStartPoint(evt, style); + }); + }); + )")); + SimulateRoutedMouseEvent(blink::WebInputEvent::Type::kMouseMove, 10, 10, 0, + false); + RunUntilInputProcessed(host()); + EXPECT_TRUE(view()->is_drawing_delegated_ink_trails_); + + // Confirm that the flag is set back to false when the JS API isn't called. + RunUntilInputProcessed(host()); + EXPECT_FALSE(view()->is_drawing_delegated_ink_trails_); +} + } // namespace content diff --git a/chromium/content/browser/renderer_host/render_widget_host_delegate.cc b/chromium/content/browser/renderer_host/render_widget_host_delegate.cc index 1c24e3dbe71..a8998ff6713 100644 --- a/chromium/content/browser/renderer_host/render_widget_host_delegate.cc +++ b/chromium/content/browser/renderer_host/render_widget_host_delegate.cc @@ -162,4 +162,8 @@ bool RenderWidgetHostDelegate::IsPortal() { return false; } +FrameTree* RenderWidgetHostDelegate::GetFrameTree() { + return nullptr; +} + } // namespace content diff --git a/chromium/content/browser/renderer_host/render_widget_host_delegate.h b/chromium/content/browser/renderer_host/render_widget_host_delegate.h index 2edad626684..2cf28550517 100644 --- a/chromium/content/browser/renderer_host/render_widget_host_delegate.h +++ b/chromium/content/browser/renderer_host/render_widget_host_delegate.h @@ -19,9 +19,9 @@ #include "content/public/common/drop_data.h" #include "services/metrics/public/cpp/ukm_recorder.h" #include "third_party/blink/public/common/input/web_input_event.h" +#include "third_party/blink/public/common/page/web_drag_operation.h" #include "third_party/blink/public/mojom/frame/lifecycle.mojom.h" #include "third_party/blink/public/mojom/manifest/display_mode.mojom.h" -#include "third_party/blink/public/platform/web_drag_operation.h" #include "ui/gfx/native_widget_types.h" namespace blink { @@ -42,6 +42,7 @@ class Sample; namespace content { class BrowserAccessibilityManager; +class FrameTree; class RenderFrameHostImpl; class RenderWidgetHostImpl; class RenderWidgetHostInputEventRouter; @@ -338,6 +339,12 @@ class CONTENT_EXPORT RenderWidgetHostDelegate { // Notify the delegate that the screen orientation has been changed. virtual void DidChangeScreenOrientation() {} + // Returns the FrameTree that this RenderWidgetHost is attached to. If the + // RenderWidgetHost is attached to a frame, then its RenderFrameHost will be + // in the tree. Otherwise, the RenderWidgetHost is for a popup which was + // opened by a frame in the FrameTree. + virtual FrameTree* GetFrameTree(); + protected: virtual ~RenderWidgetHostDelegate() {} }; diff --git a/chromium/content/browser/renderer_host/render_widget_host_factory.cc b/chromium/content/browser/renderer_host/render_widget_host_factory.cc index d13c1a724b0..c1c147679c9 100644 --- a/chromium/content/browser/renderer_host/render_widget_host_factory.cc +++ b/chromium/content/browser/renderer_host/render_widget_host_factory.cc @@ -17,14 +17,13 @@ std::unique_ptr<RenderWidgetHostImpl> RenderWidgetHostFactory::Create( RenderWidgetHostDelegate* delegate, RenderProcessHost* process, int32_t routing_id, - mojo::PendingRemote<mojom::Widget> widget_interface, bool hidden) { if (factory_) { - return factory_->CreateRenderWidgetHost( - delegate, process, routing_id, std::move(widget_interface), hidden); + return factory_->CreateRenderWidgetHost(delegate, process, routing_id, + hidden); } return std::make_unique<RenderWidgetHostImpl>( - delegate, process, routing_id, std::move(widget_interface), hidden, + delegate, process, routing_id, hidden, std::make_unique<FrameTokenMessageQueue>()); } diff --git a/chromium/content/browser/renderer_host/render_widget_host_factory.h b/chromium/content/browser/renderer_host/render_widget_host_factory.h index 1032e4a45b0..3e263d6a4b0 100644 --- a/chromium/content/browser/renderer_host/render_widget_host_factory.h +++ b/chromium/content/browser/renderer_host/render_widget_host_factory.h @@ -10,7 +10,6 @@ #include "base/macros.h" #include "content/common/content_export.h" -#include "content/common/widget.mojom.h" #include "mojo/public/cpp/bindings/pending_remote.h" namespace content { @@ -30,7 +29,6 @@ class RenderWidgetHostFactory { RenderWidgetHostDelegate* delegate, RenderProcessHost* process, int32_t routing_id, - mojo::PendingRemote<mojom::Widget> widget_interface, bool hidden); // Returns true if there is currently a globally-registered factory. @@ -46,7 +44,6 @@ class RenderWidgetHostFactory { RenderWidgetHostDelegate* delegate, RenderProcessHost* process, int32_t routing_id, - mojo::PendingRemote<mojom::Widget> widget_interface, bool hidden) = 0; // Registers your factory to be called when new RenderWidgetHostImpls are diff --git a/chromium/content/browser/renderer_host/render_widget_host_impl.cc b/chromium/content/browser/renderer_host/render_widget_host_impl.cc index a0e62a06462..1bce7961d24 100644 --- a/chromium/content/browser/renderer_host/render_widget_host_impl.cc +++ b/chromium/content/browser/renderer_host/render_widget_host_impl.cc @@ -24,6 +24,7 @@ #include "base/message_loop/message_loop_current.h" #include "base/metrics/field_trial.h" #include "base/metrics/histogram_macros.h" +#include "base/optional.h" #include "base/single_thread_task_runner.h" #include "base/strings/string_number_conversions.h" #include "base/strings/utf_string_conversions.h" @@ -46,6 +47,7 @@ #include "content/browser/file_system/browser_file_system_helper.h" #include "content/browser/gpu/compositor_util.h" #include "content/browser/renderer_host/dip_util.h" +#include "content/browser/renderer_host/display_feature.h" #include "content/browser/renderer_host/display_util.h" #include "content/browser/renderer_host/frame_token_message_queue.h" #include "content/browser/renderer_host/input/fling_scheduler.h" @@ -69,7 +71,6 @@ #include "content/common/drag_messages.h" #include "content/common/frame_messages.h" #include "content/common/input_messages.h" -#include "content/common/text_input_state.h" #include "content/common/view_messages.h" #include "content/common/visual_properties.h" #include "content/common/widget_messages.h" @@ -100,7 +101,7 @@ #include "skia/ext/image_operations.h" #include "skia/ext/platform_canvas.h" #include "storage/browser/file_system/isolated_context.h" -#include "third_party/blink/public/web/web_ime_text_span.h" +#include "third_party/blink/public/common/input/synthetic_web_input_event_builders.h" #include "ui/base/clipboard/clipboard_constants.h" #include "ui/base/ui_base_switches.h" #include "ui/display/display_switches.h" @@ -141,6 +142,11 @@ using blink::WebMouseWheelEvent; namespace content { namespace { +// How long to wait for newly loaded content to send a compositor frame +// before clearing previously displayed graphics. +constexpr base::TimeDelta kNewContentRenderingDelay = + base::TimeDelta::FromSeconds(4); + bool g_check_for_pending_visual_properties_ack = true; bool ShouldDisableHangMonitor() { @@ -193,7 +199,7 @@ class RenderWidgetHostIteratorImpl : public RenderWidgetHostIterator { std::vector<DropData::Metadata> DropDataToMetaData(const DropData& drop_data) { std::vector<DropData::Metadata> metadata; - if (!drop_data.text.is_null()) { + if (drop_data.text) { metadata.push_back(DropData::Metadata::CreateForMimeType( DropData::Kind::STRING, base::ASCIIToUTF16(ui::kMimeTypeText))); } @@ -203,7 +209,7 @@ std::vector<DropData::Metadata> DropDataToMetaData(const DropData& drop_data) { DropData::Kind::STRING, base::ASCIIToUTF16(ui::kMimeTypeURIList))); } - if (!drop_data.html.is_null()) { + if (drop_data.html) { metadata.push_back(DropData::Metadata::CreateForMimeType( DropData::Kind::STRING, base::ASCIIToUTF16(ui::kMimeTypeHTML))); } @@ -238,7 +244,7 @@ std::vector<DropData::Metadata> DropDataToMetaData(const DropData& drop_data) { return metadata; } -class UnboundWidgetInputHandler : public mojom::WidgetInputHandler { +class UnboundWidgetInputHandler : public blink::mojom::WidgetInputHandler { public: void SetFocus(bool focused) override { DLOG(WARNING) << "Input request on unbound interface"; @@ -277,24 +283,31 @@ class UnboundWidgetInputHandler : public mojom::WidgetInputHandler { bool monitor_request) override { DLOG(WARNING) << "Input request on unbound interface"; } - void DispatchEvent(std::unique_ptr<content::InputEvent> event, + void DispatchEvent(std::unique_ptr<blink::WebCoalescedInputEvent> event, DispatchEventCallback callback) override { DLOG(WARNING) << "Input request on unbound interface"; } void DispatchNonBlockingEvent( - std::unique_ptr<content::InputEvent> event) override { + std::unique_ptr<blink::WebCoalescedInputEvent> event) override { DLOG(WARNING) << "Input request on unbound interface"; } void WaitForInputProcessed(WaitForInputProcessedCallback callback) override { DLOG(WARNING) << "Input request on unbound interface"; } void AttachSynchronousCompositor( - mojo::PendingRemote<mojom::SynchronousCompositorControlHost> control_host, - mojo::PendingAssociatedRemote<mojom::SynchronousCompositorHost> host, - mojo::PendingAssociatedReceiver<mojom::SynchronousCompositor> + mojo::PendingRemote<blink::mojom::SynchronousCompositorControlHost> + control_host, + mojo::PendingAssociatedRemote<blink::mojom::SynchronousCompositorHost> + host, + mojo::PendingAssociatedReceiver<blink::mojom::SynchronousCompositor> compositor_request) override { NOTREACHED() << "Input request on unbound interface"; } + void GetFrameWidgetInputHandler( + mojo::PendingAssociatedReceiver<blink::mojom::FrameWidgetInputHandler> + request) override { + NOTREACHED() << "Input request on unbound interface"; + } }; base::LazyInstance<UnboundWidgetInputHandler>::Leaky g_unbound_input_handler = @@ -309,7 +322,6 @@ RenderWidgetHostImpl::RenderWidgetHostImpl( RenderWidgetHostDelegate* delegate, RenderProcessHost* process, int32_t routing_id, - mojo::PendingRemote<mojom::Widget> widget, bool hidden, std::unique_ptr<FrameTokenMessageQueue> frame_token_message_queue) : delegate_(delegate), @@ -318,9 +330,8 @@ RenderWidgetHostImpl::RenderWidgetHostImpl( clock_(base::DefaultTickClock::GetInstance()), is_hidden_(hidden), latency_tracker_(delegate_), - hung_renderer_delay_(TimeDelta::FromMilliseconds(kHungRendererDelayMs)), - new_content_rendering_delay_( - TimeDelta::FromMilliseconds(kNewContentRenderingDelayMs)), + hung_renderer_delay_(kHungRendererDelay), + new_content_rendering_delay_(kNewContentRenderingDelay), frame_token_message_queue_(std::move(frame_token_message_queue)), render_frame_metadata_provider_( #if defined(OS_MACOSX) @@ -359,7 +370,6 @@ RenderWidgetHostImpl::RenderWidgetHostImpl( process_->AddPriorityClient(this); SetupInputRouter(); - SetWidget(std::move(widget)); const auto* command_line = base::CommandLine::ForCurrentProcess(); if (!command_line->HasSwitch(switches::kDisableNewContentRenderingTimeout)) { @@ -510,7 +520,16 @@ void RenderWidgetHostImpl::UpdatePriority() { void RenderWidgetHostImpl::Init() { DCHECK(process_->IsInitializedAndNotDead()); - SetRendererInitialized(true, RendererInitializer::kInit); + set_renderer_initialized(true); + + blink_widget_->GetWidgetInputHandler( + widget_input_handler_.BindNewPipeAndPassReceiver(), + input_router_->BindNewHost()); + // If this is for a frame be sure to connect that handler too. + if (blink_frame_widget_) { + widget_input_handler_->GetFrameWidgetInputHandler( + frame_widget_input_handler_.BindNewEndpointAndPassReceiver()); + } SendScreenRects(); SynchronizeVisualProperties(); @@ -529,6 +548,7 @@ RenderWidgetHostImpl::BindNewWidgetInterfaces() { // reused RenderViewHostImpl so we need to ensure old channels are dropped. blink_widget_host_receiver_.reset(); blink_widget_.reset(); + widget_input_handler_.reset(); return std::make_pair( blink_widget_host_receiver_.BindNewEndpointAndPassRemote(), blink_widget_.BindNewEndpointAndPassReceiver()); @@ -541,6 +561,7 @@ void RenderWidgetHostImpl::BindWidgetInterfaces( // reused RenderViewHostImpl so we need to ensure old channels are dropped. blink_widget_host_receiver_.reset(); blink_widget_.reset(); + widget_input_handler_.reset(); blink_widget_host_receiver_.Bind(std::move(widget_host)); blink_widget_.Bind(std::move(widget)); } @@ -552,6 +573,7 @@ RenderWidgetHostImpl::BindNewFrameWidgetInterfaces() { // reused RenderViewHostImpl so we need to ensure old channels are dropped. blink_frame_widget_host_receiver_.reset(); blink_frame_widget_.reset(); + frame_widget_input_handler_.reset(); return std::make_pair( blink_frame_widget_host_receiver_.BindNewEndpointAndPassRemote(), blink_frame_widget_.BindNewEndpointAndPassReceiver()); @@ -565,13 +587,26 @@ void RenderWidgetHostImpl::BindFrameWidgetInterfaces( // reused RenderViewHostImpl so we need to ensure old channels are dropped. blink_frame_widget_host_receiver_.reset(); blink_frame_widget_.reset(); + frame_widget_input_handler_.reset(); blink_frame_widget_host_receiver_.Bind(std::move(frame_widget_host)); blink_frame_widget_.Bind(std::move(frame_widget)); } void RenderWidgetHostImpl::InitForFrame() { DCHECK(process_->IsInitializedAndNotDead()); - SetRendererInitialized(true, RendererInitializer::kInitForFrame); + set_renderer_initialized(true); + + // In situations where RenderFrameHostImpl::CreateNewFrame calls this + // the |blink_widget_| will not be bound before this method is called. + // However RenderWidgetHostImpl::Init will be called once the widget + // is shown and these handlers will be bound there. + if (blink_widget_) { + blink_widget_->GetWidgetInputHandler( + widget_input_handler_.BindNewPipeAndPassReceiver(), + input_router_->BindNewHost()); + widget_input_handler_->GetFrameWidgetInputHandler( + frame_widget_input_handler_.BindNewEndpointAndPassReceiver()); + } if (view_) view_->OnRenderWidgetInit(); @@ -608,19 +643,10 @@ bool RenderWidgetHostImpl::OnMessageReceived(const IPC::Message &msg) { IPC_MESSAGE_HANDLER(WidgetHostMsg_UpdateScreenRects_ACK, OnUpdateScreenRectsAck) IPC_MESSAGE_HANDLER(WidgetHostMsg_RequestSetBounds, OnRequestSetBounds) - IPC_MESSAGE_HANDLER(WidgetHostMsg_SetTooltipText, OnSetTooltipText) - IPC_MESSAGE_HANDLER(WidgetHostMsg_TextInputStateChanged, - OnTextInputStateChanged) - IPC_MESSAGE_HANDLER(WidgetHostMsg_SelectionBoundsChanged, - OnSelectionBoundsChanged) IPC_MESSAGE_HANDLER(DragHostMsg_StartDragging, OnStartDragging) IPC_MESSAGE_HANDLER(DragHostMsg_UpdateDragCursor, OnUpdateDragCursor) IPC_MESSAGE_HANDLER(WidgetHostMsg_FrameSwapMessages, OnFrameSwapMessagesReceived) - IPC_MESSAGE_HANDLER(WidgetHostMsg_ForceRedrawComplete, - OnForceRedrawComplete) - IPC_MESSAGE_HANDLER(WidgetHostMsg_DidFirstVisuallyNonEmptyPaint, - OnFirstVisuallyNonEmptyPaint) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() @@ -906,6 +932,17 @@ VisualProperties RenderWidgetHostImpl::GetVisualProperties() { viewport = view_->GetVisibleViewportSize(); visual_properties.visible_viewport_size = viewport; + // The root widget's window segments are computed here - child frames just + // use the value provided from the parent. + if (is_top_most_widget) { + const DisplayFeature* display_feature = view_->GetDisplayFeature(); + visual_properties.root_widget_window_segments = ComputeRootWindowSegments( + visual_properties.visible_viewport_size, display_feature); + } else { + visual_properties.root_widget_window_segments = + properties_from_parent_local_root_.root_widget_window_segments; + } + visual_properties.capture_sequence_number = view_->GetCaptureSequenceNumber(); // TODO(ccameron): GetLocalSurfaceId is not synchronized with the device @@ -1028,6 +1065,43 @@ bool RenderWidgetHostImpl::SynchronizeVisualProperties( return true; } +std::vector<gfx::Rect> RenderWidgetHostImpl::ComputeRootWindowSegments( + const gfx::Size& visible_viewport_size, + const DisplayFeature* display_feature) const { + std::vector<gfx::Rect> window_segments; + + if (!display_feature) { + window_segments.emplace_back(visible_viewport_size); + return window_segments; + } + + int display_feature_end = + display_feature->offset + display_feature->mask_length; + if (display_feature->orientation == DisplayFeature::Orientation::kVertical) { + // If the display feature is vertically oriented, it splits or masks + // the widget into two side-by-side segments. Note that in the masking + // scenario, there is an area of the widget that are not covered by the + // union of the window segments - this area's pixels will not be visible + // to the user. + window_segments.emplace_back(0, 0, display_feature->offset, + visible_viewport_size.height()); + window_segments.emplace_back( + display_feature_end, 0, + visible_viewport_size.width() - display_feature_end, + visible_viewport_size.height()); + } else { + // If the display feature is offset in the y direction, it splits or masks + // the widget into two stacked segments. + window_segments.emplace_back(0, 0, visible_viewport_size.width(), + display_feature->offset); + window_segments.emplace_back( + 0, display_feature_end, visible_viewport_size.width(), + visible_viewport_size.height() - display_feature_end); + } + + return window_segments; +} + void RenderWidgetHostImpl::GotFocus() { Focus(); if (owner_delegate_) @@ -1063,8 +1137,6 @@ void RenderWidgetHostImpl::Blur() { } void RenderWidgetHostImpl::FlushForTesting() { - if (associated_widget_input_handler_) - return associated_widget_input_handler_.FlushForTesting(); if (widget_input_handler_) return widget_input_handler_.FlushForTesting(); } @@ -1694,18 +1766,34 @@ void RenderWidgetHostImpl::DragTargetDragEnterWithMetaData( } void RenderWidgetHostImpl::DragTargetDragOver( - const gfx::PointF& client_pt, - const gfx::PointF& screen_pt, + const gfx::PointF& client_point, + const gfx::PointF& screen_point, WebDragOperationsMask operations_allowed, int key_modifiers) { - Send(new DragMsg_TargetDragOver(GetRoutingID(), client_pt, screen_pt, - operations_allowed, key_modifiers)); + // TODO(dtapuska): Remove this null check once all of the Drag IPCs + // come over the mojo channels. It will be guaranteed that this + // will be non-null. + if (blink_frame_widget_) { + blink_frame_widget_->DragTargetDragOver( + ConvertWindowPointToViewport(client_point), screen_point, + operations_allowed, key_modifiers, + base::BindOnce(&RenderWidgetHostImpl::OnUpdateDragCursor, + weak_factory_.GetWeakPtr())); + } } void RenderWidgetHostImpl::DragTargetDragLeave( const gfx::PointF& client_point, const gfx::PointF& screen_point) { - Send(new DragMsg_TargetDragLeave(GetRoutingID(), client_point, screen_point)); + // TODO(dtapuska): Remove this null check once all of the Drag IPCs + // come over the mojo channels. It will be guaranteed that this + // will be non-null. + if (blink_frame_widget_) { + gfx::PointF viewport_point = client_point; + if (IsUseZoomForDSFEnabled()) + viewport_point.Scale(GetScaleFactorForView(GetView())); + blink_frame_widget_->DragTargetDragLeave(viewport_point, screen_point); + } } void RenderWidgetHostImpl::DragTargetDrop(const DropData& drop_data, @@ -1719,13 +1807,16 @@ void RenderWidgetHostImpl::DragTargetDrop(const DropData& drop_data, } void RenderWidgetHostImpl::DragSourceEndedAt( - const gfx::PointF& client_pt, - const gfx::PointF& screen_pt, + const gfx::PointF& client_point, + const gfx::PointF& screen_point, blink::WebDragOperation operation) { - Send(new DragMsg_SourceEnded(GetRoutingID(), - client_pt, - screen_pt, - operation)); + // TODO(dtapuska): Remove this null check once all of the Drag IPCs + // come over the mojo channels. It will be guaranteed that this + // will be non-null. + if (blink_frame_widget_) { + blink_frame_widget_->DragSourceEndedAt( + ConvertWindowPointToViewport(client_point), screen_point, operation); + } } void RenderWidgetHostImpl::DragSourceSystemDragEnded() { @@ -1787,9 +1878,8 @@ void RenderWidgetHostImpl::RenderProcessExited( Destroy(true); } -mojom::WidgetInputHandler* RenderWidgetHostImpl::GetWidgetInputHandler() { - if (associated_widget_input_handler_) - return associated_widget_input_handler_.get(); +blink::mojom::WidgetInputHandler* +RenderWidgetHostImpl::GetWidgetInputHandler() { if (widget_input_handler_) return widget_input_handler_.get(); // TODO(dtapuska): Remove the need for the unbound interface. It is @@ -1823,7 +1913,7 @@ void RenderWidgetHostImpl::GetSnapshotFromBrowser( if (from_surface) { pending_surface_browser_snapshots_.insert( std::make_pair(snapshot_id, std::move(callback))); - Send(new WidgetMsg_ForceRedraw(GetRoutingID(), snapshot_id)); + RequestForceRedraw(snapshot_id); return; } @@ -1837,7 +1927,7 @@ void RenderWidgetHostImpl::GetSnapshotFromBrowser( // TODO(nzolghadr): Remove the duplication here and the if block just above. pending_browser_snapshots_.insert( std::make_pair(snapshot_id, std::move(callback))); - Send(new WidgetMsg_ForceRedraw(GetRoutingID(), snapshot_id)); + RequestForceRedraw(snapshot_id); } void RenderWidgetHostImpl::SelectionChanged(const base::string16& text, @@ -1847,10 +1937,15 @@ void RenderWidgetHostImpl::SelectionChanged(const base::string16& text, view_->SelectionChanged(text, static_cast<size_t>(offset), range); } -void RenderWidgetHostImpl::OnSelectionBoundsChanged( - const WidgetHostMsg_SelectionBounds_Params& params) { +void RenderWidgetHostImpl::SelectionBoundsChanged( + const gfx::Rect& anchor_rect, + base::i18n::TextDirection anchor_dir, + const gfx::Rect& focus_rect, + base::i18n::TextDirection focus_dir, + bool is_anchor_first) { if (view_) - view_->SelectionBoundsChanged(params); + view_->SelectionBoundsChanged(anchor_rect, anchor_dir, focus_rect, + focus_dir, is_anchor_first); } void RenderWidgetHostImpl::OnStartDragging( @@ -1921,35 +2016,13 @@ void RenderWidgetHostImpl::OnFrameSwapMessagesReceived( std::move(messages)); } -void RenderWidgetHostImpl::OnForceRedrawComplete(int snapshot_id) { -#if defined(OS_MACOSX) || defined(OS_WIN) - // On Mac, when using CoreAnimation, or Win32 when using GDI, there is a - // delay between when content is drawn to the screen, and when the - // snapshot will actually pick up that content. Insert a manual delay of - // 1/6th of a second (to simulate 10 frames at 60 fps) before actually - // taking the snapshot. - base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( - FROM_HERE, - base::BindOnce(&RenderWidgetHostImpl::WindowSnapshotReachedScreen, - weak_factory_.GetWeakPtr(), snapshot_id), - TimeDelta::FromSecondsD(1. / 6)); -#else - WindowSnapshotReachedScreen(snapshot_id); -#endif -} - -void RenderWidgetHostImpl::OnFirstVisuallyNonEmptyPaint() { - if (owner_delegate_) - owner_delegate_->RenderWidgetDidFirstVisuallyNonEmptyPaint(); -} - void RenderWidgetHostImpl::RendererExited() { if (!renderer_initialized_) return; // Clearing this flag causes us to re-create the renderer when recovering // from a crashed renderer. - SetRendererInitialized(false, RendererInitializer::kUnknown); + set_renderer_initialized(false); // After the renderer crashes, the view is destroyed and so the // RenderWidgetHost cannot track its visibility anymore. We assume such @@ -2003,7 +2076,7 @@ void RenderWidgetHostImpl::UpdateTextDirection( void RenderWidgetHostImpl::NotifyTextDirection() { if (!text_direction_updated_) return; - Send(new WidgetMsg_SetTextDirection(GetRoutingID(), text_direction_)); + blink_frame_widget_->SetTextDirection(text_direction_); text_direction_updated_ = false; } @@ -2107,13 +2180,16 @@ void RenderWidgetHostImpl::SetVisualPropertiesFromParentFrame( float page_scale_factor, bool is_pinch_gesture_active, const gfx::Size& visible_viewport_size, - const gfx::Rect& compositor_viewport) { + const gfx::Rect& compositor_viewport, + std::vector<gfx::Rect> root_widget_window_segments) { properties_from_parent_local_root_.page_scale_factor = page_scale_factor; properties_from_parent_local_root_.is_pinch_gesture_active = is_pinch_gesture_active; properties_from_parent_local_root_.visible_viewport_size = visible_viewport_size; properties_from_parent_local_root_.compositor_viewport = compositor_viewport; + properties_from_parent_local_root_.root_widget_window_segments = + std::move(root_widget_window_segments); } void RenderWidgetHostImpl::SetAutoResize(bool enable, @@ -2227,7 +2303,7 @@ void RenderWidgetHostImpl::OnClose() { } } -void RenderWidgetHostImpl::OnSetTooltipText( +void RenderWidgetHostImpl::SetToolTipText( const base::string16& tooltip_text, base::i18n::TextDirection text_direction_hint) { if (!GetView()) @@ -2404,8 +2480,6 @@ bool RenderWidgetHostImpl::StoredVisualPropertiesNeedsUpdate( new_visual_properties.screen_info || old_visual_properties->compositor_viewport_pixel_rect != new_visual_properties.compositor_viewport_pixel_rect || - old_visual_properties->compositor_viewport_pixel_rect != - new_visual_properties.compositor_viewport_pixel_rect || old_visual_properties->is_fullscreen_granted != new_visual_properties.is_fullscreen_granted || old_visual_properties->display_mode != @@ -2419,7 +2493,9 @@ bool RenderWidgetHostImpl::StoredVisualPropertiesNeedsUpdate( old_visual_properties->page_scale_factor != new_visual_properties.page_scale_factor || old_visual_properties->is_pinch_gesture_active != - new_visual_properties.is_pinch_gesture_active; + new_visual_properties.is_pinch_gesture_active || + old_visual_properties->root_widget_window_segments != + new_visual_properties.root_widget_window_segments; } void RenderWidgetHostImpl::AutoscrollStart(const gfx::PointF& position) { @@ -2435,9 +2511,10 @@ void RenderWidgetHostImpl::AutoscrollFling(const gfx::Vector2dF& velocity) { DCHECK(autoscroll_in_progress_); if (!sent_autoscroll_scroll_begin_ && velocity != gfx::Vector2dF()) { // Send a GSB event with valid delta hints. - WebGestureEvent scroll_begin = SyntheticWebGestureEventBuilder::Build( - WebInputEvent::Type::kGestureScrollBegin, - blink::WebGestureDevice::kSyntheticAutoscroll); + WebGestureEvent scroll_begin = + blink::SyntheticWebGestureEventBuilder::Build( + WebInputEvent::Type::kGestureScrollBegin, + blink::WebGestureDevice::kSyntheticAutoscroll); scroll_begin.SetPositionInWidget(autoscroll_start_position_); scroll_begin.data.scroll_begin.delta_x_hint = velocity.x(); scroll_begin.data.scroll_begin.delta_y_hint = velocity.y(); @@ -2447,7 +2524,7 @@ void RenderWidgetHostImpl::AutoscrollFling(const gfx::Vector2dF& velocity) { sent_autoscroll_scroll_begin_ = true; } - WebGestureEvent event = SyntheticWebGestureEventBuilder::Build( + WebGestureEvent event = blink::SyntheticWebGestureEventBuilder::Build( WebInputEvent::Type::kGestureFlingStart, blink::WebGestureDevice::kSyntheticAutoscroll); event.SetPositionInWidget(autoscroll_start_position_); @@ -2468,7 +2545,7 @@ void RenderWidgetHostImpl::AutoscrollEnd() { return; sent_autoscroll_scroll_begin_ = false; - WebGestureEvent cancel_event = SyntheticWebGestureEventBuilder::Build( + WebGestureEvent cancel_event = blink::SyntheticWebGestureEventBuilder::Build( WebInputEvent::Type::kGestureFlingCancel, blink::WebGestureDevice::kSyntheticAutoscroll); cancel_event.data.fling_cancel.prevent_boosting = true; @@ -2478,6 +2555,11 @@ void RenderWidgetHostImpl::AutoscrollEnd() { cancel_event, ui::LatencyInfo(ui::SourceEventType::OTHER)); } +void RenderWidgetHostImpl::DidFirstVisuallyNonEmptyPaint() { + if (owner_delegate_) + owner_delegate_->RenderWidgetDidFirstVisuallyNonEmptyPaint(); +} + bool RenderWidgetHostImpl::IsAutoscrollInProgress() { return autoscroll_in_progress_; } @@ -2498,10 +2580,10 @@ TouchEmulator* RenderWidgetHostImpl::GetExistingTouchEmulator() { return delegate_->GetInputEventRouter()->GetTouchEmulator(); } -void RenderWidgetHostImpl::OnTextInputStateChanged( - const TextInputState& params) { +void RenderWidgetHostImpl::TextInputStateChanged( + ui::mojom::TextInputStatePtr state) { if (view_) - view_->TextInputStateChanged(params); + view_->TextInputStateChanged(*state); } void RenderWidgetHostImpl::OnImeCompositionRangeChanged( @@ -2649,6 +2731,15 @@ RenderWidgetHostImpl::GetKeyboardLayoutMap() { return view_->GetKeyboardLayoutMap(); } +void RenderWidgetHostImpl::RequestForceRedraw(int snapshot_id) { + if (!blink_widget_) + return; + + blink_widget_->ForceRedraw( + base::BindOnce(&RenderWidgetHostImpl::GotResponseToForceRedraw, + base::Unretained(this), snapshot_id)); +} + bool RenderWidgetHostImpl::KeyPressListenersHandleEvent( const NativeWebKeyboardEvent& event) { if (event.skip_in_browser || @@ -2775,6 +2866,13 @@ RenderWidgetHostImpl::GetAssociatedFrameWidget() { return blink_frame_widget_; } +blink::mojom::FrameWidgetInputHandler* +RenderWidgetHostImpl::GetFrameWidgetInputHandler() { + if (!frame_widget_input_handler_) + return nullptr; + return frame_widget_input_handler_.get(); +} + void RenderWidgetHostImpl::DispatchInputEventWithLatencyInfo( const blink::WebInputEvent& event, ui::LatencyInfo* latency) { @@ -2895,6 +2993,23 @@ void RenderWidgetHostImpl::GotResponseToKeyboardLockRequest(bool allowed) { UnlockKeyboard(); } +void RenderWidgetHostImpl::GotResponseToForceRedraw(int snapshot_id) { +#if defined(OS_MACOSX) || defined(OS_WIN) + // On Mac, when using CoreAnimation, or Win32 when using GDI, there is a + // delay between when content is drawn to the screen, and when the + // snapshot will actually pick up that content. Insert a manual delay of + // 1/6th of a second (to simulate 10 frames at 60 fps) before actually + // taking the snapshot. + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + base::BindOnce(&RenderWidgetHostImpl::WindowSnapshotReachedScreen, + weak_factory_.GetWeakPtr(), snapshot_id), + TimeDelta::FromSecondsD(1. / 6)); +#else + WindowSnapshotReachedScreen(snapshot_id); +#endif +} + void RenderWidgetHostImpl::DetachDelegate() { delegate_ = nullptr; latency_tracker_.reset_delegate(); @@ -3091,8 +3206,6 @@ void RenderWidgetHostImpl::SetupInputRouter() { suppress_events_until_keydown_ = false; monitoring_composition_info_ = false; StopInputEventAckTimeout(); - associated_widget_input_handler_.reset(); - widget_input_handler_.reset(); input_router_ = std::make_unique<InputRouterImpl>( this, this, fling_scheduler_.get(), GetInputRouterConfigForPlatform()); @@ -3110,36 +3223,11 @@ void RenderWidgetHostImpl::SetForceEnableZoom(bool enabled) { input_router_->SetForceEnableZoom(enabled); } -void RenderWidgetHostImpl::SetFrameInputHandler( - mojom::FrameInputHandler* frame_input_handler) { - if (!frame_input_handler) - return; - frame_input_handler->GetWidgetInputHandler( - associated_widget_input_handler_.BindNewEndpointAndPassReceiver(), - input_router_->BindNewFrameHost()); -} - void RenderWidgetHostImpl::SetInputTargetClient( mojo::Remote<viz::mojom::InputTargetClient> input_target_client) { input_target_client_ = std::move(input_target_client); } -void RenderWidgetHostImpl::SetWidget( - mojo::PendingRemote<mojom::Widget> widget_remote) { - if (!widget_remote) - return; - - // If we have a bound handler ensure that we destroy the old input router - // while we reset the |widget_input_handler_|. - if (widget_input_handler_.is_bound()) - SetupInputRouter(); - - mojo::Remote<mojom::Widget> widget(std::move(widget_remote)); - widget->SetupWidgetInputHandler( - widget_input_handler_.BindNewPipeAndPassReceiver(), - input_router_->BindNewHost()); -} - void RenderWidgetHostImpl::ProgressFlingIfNeeded(TimeTicks current_time) { fling_scheduler_->ProgressFlingOnBeginFrameIfneeded(current_time); } @@ -3324,16 +3412,22 @@ gfx::Size RenderWidgetHostImpl::GetRootWidgetViewportSize() { return root_view->GetVisibleViewportSize(); } -void RenderWidgetHostImpl::SetRendererInitialized( - bool renderer_initialized, - RendererInitializer initializer) { - renderer_initialized_ = renderer_initialized; - // We want to record the first initializer. If this is called again, don't - // overwrite the existing value. - if (initializer != RendererInitializer::kUnknown && - initializer_ != RendererInitializer::kUnknown) - return; - initializer_ = initializer; +// This method was copied from RenderWidget::ConvertWindowToViewport() when +// porting drag-and-drop calls to Mojo, so that RenderWidgetHostImpl bypasses +// RenderWidget to talk the the WebFrameWidget and needs to perform the scale +// operation itself. +gfx::PointF RenderWidgetHostImpl::ConvertWindowPointToViewport( + const gfx::PointF& window_point) { + gfx::PointF viewport_point = window_point; + if (IsUseZoomForDSFEnabled()) + viewport_point.Scale(GetScaleFactorForView(GetView())); + return viewport_point; } +RenderWidgetHostImpl::MainFramePropagationProperties:: + MainFramePropagationProperties() = default; + +RenderWidgetHostImpl::MainFramePropagationProperties:: + ~MainFramePropagationProperties() = default; + } // namespace content diff --git a/chromium/content/browser/renderer_host/render_widget_host_impl.h b/chromium/content/browser/renderer_host/render_widget_host_impl.h index 950fc6e8e5e..5f3f2feec8c 100644 --- a/chromium/content/browser/renderer_host/render_widget_host_impl.h +++ b/chromium/content/browser/renderer_host/render_widget_host_impl.h @@ -45,9 +45,7 @@ #include "content/browser/renderer_host/render_widget_host_delegate.h" #include "content/browser/renderer_host/render_widget_host_view_base.h" #include "content/common/drag_event_source_info.h" -#include "content/common/input/input_handler.mojom.h" #include "content/common/render_frame_metadata.mojom.h" -#include "content/common/widget.mojom.h" #include "content/public/browser/render_process_host_observer.h" #include "content/public/browser/render_widget_host.h" #include "content/public/common/page_zoom.h" @@ -61,6 +59,8 @@ #include "services/viz/public/mojom/compositing/compositor_frame_sink.mojom.h" #include "services/viz/public/mojom/hit_test/input_target_client.mojom.h" #include "third_party/blink/public/mojom/input/input_event_result.mojom-shared.h" +#include "third_party/blink/public/mojom/input/input_handler.mojom.h" +#include "third_party/blink/public/mojom/input/pointer_lock_context.mojom.h" #include "third_party/blink/public/mojom/manifest/display_mode.mojom.h" #include "third_party/blink/public/mojom/page/widget.mojom.h" #include "ui/base/ime/text_input_mode.h" @@ -78,7 +78,6 @@ #endif class SkBitmap; -struct WidgetHostMsg_SelectionBounds_Params; namespace blink { class WebInputEvent; @@ -106,9 +105,9 @@ class SyntheticGestureController; class TimeoutMonitor; class TouchEmulator; class WebCursor; +struct DisplayFeature; struct VisualProperties; struct ScreenInfo; -struct TextInputState; // This implements the RenderWidgetHost interface that is exposed to // embedders of content, and adds things only visible to content. @@ -161,7 +160,6 @@ class CONTENT_EXPORT RenderWidgetHostImpl RenderWidgetHostDelegate* delegate, RenderProcessHost* process, int32_t routing_id, - mojo::PendingRemote<mojom::Widget> widget_interface, bool hidden, std::unique_ptr<FrameTokenMessageQueue> frame_token_message_queue); @@ -241,8 +239,8 @@ class CONTENT_EXPORT RenderWidgetHostImpl const gfx::PointF& screen_pt, blink::WebDragOperationsMask operations_allowed, int key_modifiers) override; - void DragTargetDragOver(const gfx::PointF& client_pt, - const gfx::PointF& screen_pt, + void DragTargetDragOver(const gfx::PointF& client_point, + const gfx::PointF& screen_point, blink::WebDragOperationsMask operations_allowed, int key_modifiers) override; void DragTargetDragLeave(const gfx::PointF& client_point, @@ -269,6 +267,16 @@ class CONTENT_EXPORT RenderWidgetHostImpl void RenderProcessExited(RenderProcessHost* host, const ChildProcessTerminationInfo& info) override; + // blink::mojom::WidgetHost implementation. + void SetToolTipText(const base::string16& tooltip_text, + base::i18n::TextDirection text_direction_hint) override; + void TextInputStateChanged(ui::mojom::TextInputStatePtr state) override; + void SelectionBoundsChanged(const gfx::Rect& anchor_rect, + base::i18n::TextDirection anchor_dir, + const gfx::Rect& focus_rect, + base::i18n::TextDirection focus_dir, + bool is_anchor_first) override; + // Notification that the screen info has changed. void NotifyScreenInfoChanged(); @@ -555,6 +563,10 @@ class CONTENT_EXPORT RenderWidgetHostImpl // mode. void GotResponseToKeyboardLockRequest(bool allowed); + // Called when the response to an earlier WidgetMsg_ForceRedraw message has + // arrived. The reply includes the snapshot-id from the request. + void GotResponseToForceRedraw(int snapshot_id); + // When the WebContents (which acts as the Delegate) is destroyed, this object // may still outlive it while the renderer is shutting down. In that case the // delegate pointer is removed (since it would be a UAF). @@ -594,23 +606,10 @@ class CONTENT_EXPORT RenderWidgetHostImpl void RejectMouseLockOrUnlockIfNecessary( blink::mojom::PointerLockResult reason); - // The places in our codebase that call SetRendererInitialized or set the - // state to true directly. - // TODO(https://crbug.com/1006814): Delete this. - enum class RendererInitializer { - kUnknown, - kTest, // We don't care about tests, this can be used for any test call. - kInit, // RenderWidgetHostImpl - kInitForFrame, // RenderWidgetHostImpl - kWebContentsInit, - kCreateRenderView, - }; - void SetRendererInitialized(bool renderer_initialized, - RendererInitializer initializer); - // TODO(https://crbug.com/1006814): Delete this. - RendererInitializer get_initializer_for_crbug_1006814() { - return initializer_; + void set_renderer_initialized(bool renderer_initialized) { + renderer_initialized_ = renderer_initialized; } + // Store values received in a child frame RenderWidgetHost from a parent // RenderWidget, in order to pass them to the renderer and continue their // propagation down the RenderWidget tree. @@ -618,7 +617,8 @@ class CONTENT_EXPORT RenderWidgetHostImpl float page_scale_factor, bool is_pinch_gesture_active, const gfx::Size& visible_viewport_size, - const gfx::Rect& compositor_viewport); + const gfx::Rect& compositor_viewport, + std::vector<gfx::Rect> root_widget_window_segments); // Indicates if the render widget host should track the render widget's size // as opposed to visa versa. @@ -699,19 +699,15 @@ class CONTENT_EXPORT RenderWidgetHostImpl // there are any queued messages belonging to it, they will be processed. void DidProcessFrame(uint32_t frame_token); - // Indicate the frame input handler is now available. - void SetFrameInputHandler(mojom::FrameInputHandler*); - void SetWidget(mojo::PendingRemote<mojom::Widget> widget_remote); - - viz::mojom::InputTargetClient* input_target_client() { - return input_target_client_.get(); + mojo::Remote<viz::mojom::InputTargetClient>& input_target_client() { + return input_target_client_; } void SetInputTargetClient( mojo::Remote<viz::mojom::InputTargetClient> input_target_client); // InputRouterImplClient overrides. - mojom::WidgetInputHandler* GetWidgetInputHandler() override; + blink::mojom::WidgetInputHandler* GetWidgetInputHandler() override; void OnImeCompositionRangeChanged( const gfx::Range& range, const std::vector<gfx::Rect>& character_bounds) override; @@ -764,6 +760,8 @@ class CONTENT_EXPORT RenderWidgetHostImpl // Returns the keyboard layout mapping. base::flat_map<std::string, std::string> GetKeyboardLayoutMap(); + void RequestForceRedraw(int snapshot_id); + void DidStopFlinging(); void GetContentRenderingTimeoutFrom(RenderWidgetHostImpl* other); @@ -792,6 +790,8 @@ class CONTENT_EXPORT RenderWidgetHostImpl const mojo::AssociatedRemote<blink::mojom::FrameWidget>& GetAssociatedFrameWidget(); + blink::mojom::FrameWidgetInputHandler* GetFrameWidgetInputHandler(); + // Exposed so that tests can swap the implementation and intercept calls. mojo::AssociatedReceiver<blink::mojom::FrameWidgetHost>& frame_widget_host_receiver_for_testing() { @@ -833,6 +833,14 @@ class CONTENT_EXPORT RenderWidgetHostImpl bool IsMouseLocked() const; + // Computes logical segments of the |visible_viewport_size|, based on the + // optional DisplayFeature. These segments are in DIPs relative to the widget + // origin. If a DisplayFeature is not provided, a vector with a single rect, + // the size of the visible viewport will be returned. + std::vector<gfx::Rect> ComputeRootWindowSegments( + const gfx::Size& visible_viewport_size, + const DisplayFeature* display_feature) const; + // The View associated with the RenderWidgetHost. The lifetime of this object // is associated with the lifetime of the Render process. If the Renderer // crashes, its View is destroyed and this pointer becomes NULL, even though @@ -902,11 +910,6 @@ class CONTENT_EXPORT RenderWidgetHostImpl void OnClose(); void OnUpdateScreenRectsAck(); void OnRequestSetBounds(const gfx::Rect& bounds); - void OnSetTooltipText(const base::string16& tooltip_text, - base::i18n::TextDirection text_direction_hint); - void OnTextInputStateChanged(const TextInputState& params); - void OnSelectionBoundsChanged( - const WidgetHostMsg_SelectionBounds_Params& params); void OnStartDragging(const DropData& drop_data, blink::WebDragOperationsMask operations_allowed, const SkBitmap& bitmap, @@ -915,8 +918,6 @@ class CONTENT_EXPORT RenderWidgetHostImpl void OnUpdateDragCursor(blink::WebDragOperation current_op); void OnFrameSwapMessagesReceived(uint32_t frame_token, std::vector<IPC::Message> messages); - void OnForceRedrawComplete(int snapshot_id); - void OnFirstVisuallyNonEmptyPaint(); // blink::mojom::FrameWidgetHost overrides. void AnimateDoubleTapZoomInMainFrame(const gfx::Point& tap_point, @@ -928,6 +929,7 @@ class CONTENT_EXPORT RenderWidgetHostImpl void AutoscrollStart(const gfx::PointF& position) override; void AutoscrollFling(const gfx::Vector2dF& velocity) override; void AutoscrollEnd() override; + void DidFirstVisuallyNonEmptyPaint() override; // When the RenderWidget is destroyed and recreated, this resets states in the // browser to match the clean start for the renderer side. @@ -968,8 +970,7 @@ class CONTENT_EXPORT RenderWidgetHostImpl blink::mojom::InputEventResultSource ack_source) override; void DidOverscroll(const ui::DidOverscrollParams& params) override; void DidStartScrollingViewport() override; - void OnSetWhiteListedTouchAction( - cc::TouchAction white_listed_touch_action) override {} + void OnSetCompositorAllowedTouchAction(cc::TouchAction) override {} void OnInvalidInputEventSource() override; // Dispatch input events with latency information @@ -1039,6 +1040,12 @@ class CONTENT_EXPORT RenderWidgetHostImpl void CreateSyntheticGestureControllerIfNecessary(); + // Converts the |window_point| from the coordinates in native window in DIP + // to Blink's Viewport coordinates. They're identical in tradional world, + // but will differ when use-zoom-for-dsf feature is enabled. + // TODO(oshima): Update the comment when the migration is completed. + gfx::PointF ConvertWindowPointToViewport(const gfx::PointF& window_point); + // The following functions are used to keep track of pending user activation // events, which are input events (e.g., mousedown or keydown) that allow a // renderer to gain user activation. AddPendingUserActivation() increments @@ -1126,6 +1133,9 @@ class CONTENT_EXPORT RenderWidgetHostImpl // that the renderer receives updates in an atomic fashion along with a // synchronization token for the compositor in a LocalSurfaceIdAllocation. struct MainFramePropagationProperties { + MainFramePropagationProperties(); + ~MainFramePropagationProperties(); + // The page-scale factor of the main-frame. float page_scale_factor = 1.f; @@ -1136,6 +1146,10 @@ class CONTENT_EXPORT RenderWidgetHostImpl gfx::Size visible_viewport_size; gfx::Rect compositor_viewport; + + // The logical segments of the root widget, in DIPs relative to the root + // RenderWidgetHost. + std::vector<gfx::Rect> root_widget_window_segments; } properties_from_parent_local_root_; bool waiting_for_screen_rects_ack_ = false; @@ -1271,14 +1285,9 @@ class CONTENT_EXPORT RenderWidgetHostImpl std::unique_ptr<FrameTokenMessageQueue> frame_token_message_queue_; - // If the |associated_widget_input_handler_| is set it should always be - // used to ensure in order delivery of related messages that may occur - // at the frame input level; see FrameInputHandler. Note that when the - // RWHI wraps a WebPagePopup widget it will only have a - // a |widget_input_handler_|. - mojo::AssociatedRemote<mojom::WidgetInputHandler> - associated_widget_input_handler_; - mojo::Remote<mojom::WidgetInputHandler> widget_input_handler_; + mojo::Remote<blink::mojom::WidgetInputHandler> widget_input_handler_; + mojo::AssociatedRemote<blink::mojom::FrameWidgetInputHandler> + frame_widget_input_handler_; mojo::Remote<viz::mojom::InputTargetClient> input_target_client_; base::Optional<uint16_t> screen_orientation_angle_for_testing_; @@ -1320,10 +1329,6 @@ class CONTENT_EXPORT RenderWidgetHostImpl blink_widget_host_receiver_{this}; mojo::AssociatedRemote<blink::mojom::Widget> blink_widget_; - // Who initialized us. - // TODO(https://crbug.com/1006814): Delete this. - RendererInitializer initializer_ = RendererInitializer::kUnknown; - base::WeakPtrFactory<RenderWidgetHostImpl> weak_factory_{this}; DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostImpl); diff --git a/chromium/content/browser/renderer_host/render_widget_host_input_event_router.cc b/chromium/content/browser/renderer_host/render_widget_host_input_event_router.cc index 879dd09fe5a..f45da60a8f8 100644 --- a/chromium/content/browser/renderer_host/render_widget_host_input_event_router.cc +++ b/chromium/content/browser/renderer_host/render_widget_host_input_event_router.cc @@ -471,10 +471,9 @@ RenderWidgetTargetResult RenderWidgetHostInputEventRouter::FindMouseEventTarget( // the OOPIF renderer. Instead of using the coordinate transformation in the // browser process process, use the cached coordinates that were determined // by the renderer process on the previous MouseDown. - // TODO(yigu): Currently there is a mismatch between the coordinate - // transforms from browser process and renderer process. We need to fix it - // so that we don't need to cache the transform from MouseDown. - // https://crbug.com/934434. + // TODO(crbug.com/989109): Currently there is a mismatch between the + // coordinate transforms from browser process and renderer process. We need + // to fix it so that we don't need to cache the transform from MouseDown. if (event.GetType() == blink::WebInputEvent::Type::kMouseUp && target == last_mouse_down_target_ && mouse_down_pre_transformed_coordinate_ == event.PositionInWidget()) { @@ -627,8 +626,8 @@ void RenderWidgetHostInputEventRouter::DispatchMouseEvent( auto hit_test_result = FindViewAtLocation(root_view, mouse_event.PositionInWidget(), viz::EventSource::MOUSE, &transformed_point); - // TODO(kenrb, yigu): This is skipped if the HitTestResult is requiring an - // asynchronous hit test to the renderer process, because it might mean + // TODO(crbug.com/893101): This is skipped if the HitTestResult is requiring + // an asynchronous hit test to the renderer process, because it might mean // sending extra MouseMoves to renderers that don't need the event updates // which is a worse outcome than the cursor being delayed in updating. // An asynchronous hit test can be added here to fix the problem. diff --git a/chromium/content/browser/renderer_host/render_widget_host_input_event_router_unittest.cc b/chromium/content/browser/renderer_host/render_widget_host_input_event_router_unittest.cc index 632b7742e1e..b0766cd832a 100644 --- a/chromium/content/browser/renderer_host/render_widget_host_input_event_router_unittest.cc +++ b/chromium/content/browser/renderer_host/render_widget_host_input_event_router_unittest.cc @@ -21,12 +21,12 @@ #include "content/public/test/mock_render_process_host.h" #include "content/public/test/test_browser_context.h" #include "content/test/mock_render_widget_host_delegate.h" -#include "content/test/mock_widget_impl.h" #include "content/test/test_render_view_host.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/remote.h" #include "services/viz/public/mojom/hit_test/input_target_client.mojom.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/common/input/synthetic_web_input_event_builders.h" namespace content { @@ -204,12 +204,9 @@ class RenderWidgetHostInputEventRouterTest : public testing::Test { process_host_root_ = std::make_unique<MockRenderProcessHost>(browser_context_.get()); - mojo::PendingRemote<mojom::Widget> widget_root; - widget_impl_root_ = std::make_unique<MockWidgetImpl>( - widget_root.InitWithNewPipeAndPassReceiver()); widget_host_root_ = std::make_unique<RenderWidgetHostImpl>( &delegate_, process_host_root_.get(), - process_host_root_->GetNextRoutingID(), std::move(widget_root), + process_host_root_->GetNextRoutingID(), /*hidden=*/false, std::make_unique<FrameTokenMessageQueue>()); view_root_ = std::make_unique<MockRootRenderWidgetHostView>(widget_host_root_.get()); @@ -228,7 +225,6 @@ class RenderWidgetHostInputEventRouterTest : public testing::Test { struct ChildViewState { std::unique_ptr<MockRenderProcessHost> process_host; - std::unique_ptr<MockWidgetImpl> widget_impl; std::unique_ptr<RenderWidgetHostImpl> widget_host; std::unique_ptr<TestRenderWidgetHostViewChildFrame> view; std::unique_ptr<MockFrameConnectorDelegate> frame_connector; @@ -239,12 +235,9 @@ class RenderWidgetHostInputEventRouterTest : public testing::Test { child.process_host = std::make_unique<MockRenderProcessHost>(browser_context_.get()); - mojo::PendingRemote<mojom::Widget> widget_child; - child.widget_impl = std::make_unique<MockWidgetImpl>( - widget_child.InitWithNewPipeAndPassReceiver()); child.widget_host = std::make_unique<RenderWidgetHostImpl>( &delegate_, child.process_host.get(), - child.process_host->GetNextRoutingID(), std::move(widget_child), + child.process_host->GetNextRoutingID(), /*hidden=*/false, std::make_unique<FrameTokenMessageQueue>()); child.view = std::make_unique<TestRenderWidgetHostViewChildFrame>( child.widget_host.get()); @@ -291,7 +284,6 @@ class RenderWidgetHostInputEventRouterTest : public testing::Test { std::unique_ptr<BrowserContext> browser_context_; std::unique_ptr<MockRenderProcessHost> process_host_root_; - std::unique_ptr<MockWidgetImpl> widget_impl_root_; std::unique_ptr<RenderWidgetHostImpl> widget_host_root_; std::unique_ptr<MockRootRenderWidgetHostView> view_root_; @@ -610,7 +602,7 @@ TEST_F(RenderWidgetHostInputEventRouterTest, CancelScrollBubblingWhenChildDetaches) { gfx::Vector2dF delta(0.f, 10.f); blink::WebGestureEvent scroll_begin = - SyntheticWebGestureEventBuilder::BuildScrollBegin( + blink::SyntheticWebGestureEventBuilder::BuildScrollBegin( delta.x(), delta.y(), blink::WebGestureDevice::kTouchscreen); { @@ -663,7 +655,7 @@ TEST_F(RenderWidgetHostInputEventRouterTest, ContinueScrollBubblingWhenIrrelevantChildDetaches) { gfx::Vector2dF delta(0.f, 10.f); blink::WebGestureEvent scroll_begin = - SyntheticWebGestureEventBuilder::BuildScrollBegin( + blink::SyntheticWebGestureEventBuilder::BuildScrollBegin( delta.x(), delta.y(), blink::WebGestureDevice::kTouchscreen); ChildViewState outer = MakeChildView(view_root_.get()); @@ -689,7 +681,7 @@ void RenderWidgetHostInputEventRouterTest::TestSendNewGestureWhileBubbling( bool should_cancel) { gfx::Vector2dF delta(0.f, 10.f); blink::WebGestureEvent scroll_begin = - SyntheticWebGestureEventBuilder::BuildScrollBegin( + blink::SyntheticWebGestureEventBuilder::BuildScrollBegin( delta.x(), delta.y(), blink::WebGestureDevice::kTouchscreen); TestRenderWidgetHostViewChildFrame* cur_target = bubbling_origin; @@ -800,7 +792,7 @@ TEST_F(RenderWidgetHostInputEventRouterTest, TEST_F(RenderWidgetHostInputEventRouterTest, DoNotBubbleMultipleSequences) { gfx::Vector2dF delta(0.f, 10.f); blink::WebGestureEvent scroll_begin = - SyntheticWebGestureEventBuilder::BuildScrollBegin( + blink::SyntheticWebGestureEventBuilder::BuildScrollBegin( delta.x(), delta.y(), blink::WebGestureDevice::kTouchscreen); ChildViewState outer1 = MakeChildView(view_root_.get()); @@ -828,7 +820,7 @@ TEST_F(RenderWidgetHostInputEventRouterTest, DoNotBubbleIfUnrelatedGestureInTarget) { gfx::Vector2dF delta(0.f, 10.f); blink::WebGestureEvent scroll_begin = - SyntheticWebGestureEventBuilder::BuildScrollBegin( + blink::SyntheticWebGestureEventBuilder::BuildScrollBegin( delta.x(), delta.y(), blink::WebGestureDevice::kTouchscreen); ChildViewState child = MakeChildView(view_root_.get()); @@ -874,7 +866,7 @@ TEST_F(RenderWidgetHostInputEventRouterTest, NestedDoNotBubbleIfUnrelatedGestureInTarget) { gfx::Vector2dF delta(0.f, 10.f); blink::WebGestureEvent scroll_begin = - SyntheticWebGestureEventBuilder::BuildScrollBegin( + blink::SyntheticWebGestureEventBuilder::BuildScrollBegin( delta.x(), delta.y(), blink::WebGestureDevice::kTouchscreen); ChildViewState outer = MakeChildView(view_root_.get()); diff --git a/chromium/content/browser/renderer_host/render_widget_host_unittest.cc b/chromium/content/browser/renderer_host/render_widget_host_unittest.cc index 9a0bdaba2d5..ec971bf9ae8 100644 --- a/chromium/content/browser/renderer_host/render_widget_host_unittest.cc +++ b/chromium/content/browser/renderer_host/render_widget_host_unittest.cc @@ -14,6 +14,7 @@ #include "base/macros.h" #include "base/run_loop.h" #include "base/single_thread_task_runner.h" +#include "base/stl_util.h" #include "base/test/metrics/histogram_tester.h" #include "base/test/scoped_feature_list.h" #include "base/test/simple_test_tick_clock.h" @@ -26,6 +27,7 @@ #include "components/viz/common/surfaces/parent_local_surface_id_allocator.h" #include "components/viz/test/begin_frame_args_test.h" #include "content/browser/gpu/compositor_util.h" +#include "content/browser/renderer_host/display_feature.h" #include "content/browser/renderer_host/frame_token_message_queue.h" #include "content/browser/renderer_host/input/mock_input_router.h" #include "content/browser/renderer_host/input/touch_emulator.h" @@ -34,7 +36,6 @@ #include "content/browser/renderer_host/render_widget_host_delegate.h" #include "content/browser/renderer_host/render_widget_host_view_base.h" #include "content/common/content_constants_internal.h" -#include "content/common/input/synthetic_web_input_event_builders.h" #include "content/common/input_messages.h" #include "content/common/render_frame_metadata.mojom.h" #include "content/common/visual_properties.h" @@ -45,7 +46,6 @@ #include "content/public/test/browser_task_environment.h" #include "content/public/test/mock_render_process_host.h" #include "content/public/test/test_browser_context.h" -#include "content/test/mock_widget_impl.h" #include "content/test/mock_widget_input_handler.h" #include "content/test/stub_render_widget_host_owner_delegate.h" #include "content/test/test_render_view_host.h" @@ -55,6 +55,7 @@ #include "mojo/public/cpp/bindings/remote.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/common/input/synthetic_web_input_event_builders.h" #include "third_party/blink/public/common/page/page_zoom.h" #include "third_party/blink/public/mojom/input/input_handler.mojom-shared.h" #include "ui/display/screen.h" @@ -191,6 +192,13 @@ class TestView : public TestRenderWidgetHostView { return local_surface_id_allocator_.GetCurrentLocalSurfaceIdAllocation(); } + void SetInsets(const gfx::Insets& insets) override { insets_ = insets; } + gfx::Size GetVisibleViewportSize() override { + gfx::Rect requested_rect(GetRequestedRendererSize()); + requested_rect.Inset(insets_); + return requested_rect.size(); + } + void ProcessAckedTouchEvent( const TouchEventWithLatencyInfo& touch, blink::mojom::InputEventResultState ack_result) override { @@ -228,6 +236,7 @@ class TestView : public TestRenderWidgetHostView { blink::mojom::InputEventResultState ack_result_; viz::ParentLocalSurfaceIdAllocator local_surface_id_allocator_; ScreenInfo screen_info_; + gfx::Insets insets_; private: DISALLOW_COPY_AND_ASSIGN(TestView); @@ -274,7 +283,7 @@ class FakeRenderFrameMetadataObserver ~FakeRenderFrameMetadataObserver() override {} #if defined(OS_ANDROID) - void ReportAllRootScrollsForAccessibility(bool enabled) override {} + void ReportAllRootScrolls(bool enabled) override {} #endif void ReportAllFrameSubmissionsForTesting(bool enabled) override {} @@ -583,6 +592,26 @@ class RenderWidgetHostTest : public testing::Test { virtual void ConfigureView(TestView* view) { } + void ReinitalizeHost() { + mojo::AssociatedRemote<blink::mojom::WidgetHost> widget_host; + mojo::AssociatedRemote<blink::mojom::Widget> widget; + auto widget_receiver = + widget.BindNewEndpointAndPassDedicatedReceiverForTesting(); + host_->BindWidgetInterfaces( + widget_host.BindNewEndpointAndPassDedicatedReceiverForTesting(), + widget.Unbind()); + + mojo::AssociatedRemote<blink::mojom::FrameWidgetHost> frame_widget_host; + mojo::AssociatedRemote<blink::mojom::FrameWidget> frame_widget; + auto frame_widget_receiver = + frame_widget.BindNewEndpointAndPassDedicatedReceiverForTesting(); + host_->BindFrameWidgetInterfaces( + frame_widget_host.BindNewEndpointAndPassDedicatedReceiverForTesting(), + frame_widget.Unbind()); + + host_->Init(); + } + base::TimeTicks GetNextSimulatedEventTime() { last_simulated_event_time_ += simulated_event_time_delta_; return last_simulated_event_time_; @@ -607,18 +636,17 @@ class RenderWidgetHostTest : public testing::Test { } void SimulateMouseEvent(WebInputEvent::Type type) { - host_->ForwardMouseEvent(SyntheticWebMouseEventBuilder::Build(type)); + host_->ForwardMouseEvent(blink::SyntheticWebMouseEventBuilder::Build(type)); } void SimulateMouseEventWithLatencyInfo(WebInputEvent::Type type, const ui::LatencyInfo& ui_latency) { host_->ForwardMouseEventWithLatencyInfo( - SyntheticWebMouseEventBuilder::Build(type), - ui_latency); + blink::SyntheticWebMouseEventBuilder::Build(type), ui_latency); } void SimulateWheelEvent(float dX, float dY, int modifiers, bool precise) { - host_->ForwardWheelEvent(SyntheticWebMouseWheelEventBuilder::Build( + host_->ForwardWheelEvent(blink::SyntheticWebMouseWheelEventBuilder::Build( 0, 0, dX, dY, modifiers, precise ? ui::ScrollGranularity::kScrollByPrecisePixel : ui::ScrollGranularity::kScrollByPixel)); @@ -629,10 +657,11 @@ class RenderWidgetHostTest : public testing::Test { int modifiers, bool precise, WebMouseWheelEvent::Phase phase) { - WebMouseWheelEvent wheel_event = SyntheticWebMouseWheelEventBuilder::Build( - 0, 0, dX, dY, modifiers, - precise ? ui::ScrollGranularity::kScrollByPrecisePixel - : ui::ScrollGranularity::kScrollByPixel); + WebMouseWheelEvent wheel_event = + blink::SyntheticWebMouseWheelEventBuilder::Build( + 0, 0, dX, dY, modifiers, + precise ? ui::ScrollGranularity::kScrollByPrecisePixel + : ui::ScrollGranularity::kScrollByPixel); wheel_event.phase = phase; host_->ForwardWheelEvent(wheel_event); } @@ -643,7 +672,7 @@ class RenderWidgetHostTest : public testing::Test { bool precise, const ui::LatencyInfo& ui_latency) { host_->ForwardWheelEventWithLatencyInfo( - SyntheticWebMouseWheelEventBuilder::Build( + blink::SyntheticWebMouseWheelEventBuilder::Build( 0, 0, dX, dY, modifiers, precise ? ui::ScrollGranularity::kScrollByPrecisePixel : ui::ScrollGranularity::kScrollByPixel), @@ -656,10 +685,11 @@ class RenderWidgetHostTest : public testing::Test { bool precise, const ui::LatencyInfo& ui_latency, WebMouseWheelEvent::Phase phase) { - WebMouseWheelEvent wheel_event = SyntheticWebMouseWheelEventBuilder::Build( - 0, 0, dX, dY, modifiers, - precise ? ui::ScrollGranularity::kScrollByPrecisePixel - : ui::ScrollGranularity::kScrollByPixel); + WebMouseWheelEvent wheel_event = + blink::SyntheticWebMouseWheelEventBuilder::Build( + 0, 0, dX, dY, modifiers, + precise ? ui::ScrollGranularity::kScrollByPrecisePixel + : ui::ScrollGranularity::kScrollByPixel); wheel_event.phase = phase; host_->ForwardWheelEventWithLatencyInfo(wheel_event, ui_latency); } @@ -671,7 +701,7 @@ class RenderWidgetHostTest : public testing::Test { void SimulateMouseEvent( WebInputEvent::Type type, int x, int y, int modifiers, bool pressed) { WebMouseEvent event = - SyntheticWebMouseEventBuilder::Build(type, x, y, modifiers); + blink::SyntheticWebMouseEventBuilder::Build(type, x, y, modifiers); if (pressed) event.button = WebMouseEvent::Button::kLeft; event.SetTimeStamp(GetNextSimulatedEventTime()); @@ -682,14 +712,15 @@ class RenderWidgetHostTest : public testing::Test { void SimulateGestureEvent(WebInputEvent::Type type, WebGestureDevice sourceDevice) { host_->ForwardGestureEvent( - SyntheticWebGestureEventBuilder::Build(type, sourceDevice)); + blink::SyntheticWebGestureEventBuilder::Build(type, sourceDevice)); } void SimulateGestureEventWithLatencyInfo(WebInputEvent::Type type, WebGestureDevice sourceDevice, const ui::LatencyInfo& ui_latency) { host_->ForwardGestureEventWithLatencyInfo( - SyntheticWebGestureEventBuilder::Build(type, sourceDevice), ui_latency); + blink::SyntheticWebGestureEventBuilder::Build(type, sourceDevice), + ui_latency); } // Set the timestamp for the touch-event. @@ -746,7 +777,7 @@ class RenderWidgetHostTest : public testing::Test { renderer_render_frame_metadata_observer_; private: - SyntheticWebTouchEvent touch_event_; + blink::SyntheticWebTouchEvent touch_event_; DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostTest); }; @@ -1025,6 +1056,117 @@ TEST_F(RenderWidgetHostTest, OverrideScreenInfoDuringFullscreenMode) { EXPECT_EQ(kScreenBounds, props.screen_info.available_rect); } +TEST_F(RenderWidgetHostTest, RootWindowSegments) { + gfx::Rect screen_rect(0, 0, 800, 600); + ScreenInfo screen_info; + screen_info.device_scale_factor = 1.f; + screen_info.rect = screen_rect; + screen_info.available_rect = screen_rect; + screen_info.orientation_angle = 0; + screen_info.orientation_type = SCREEN_ORIENTATION_VALUES_PORTRAIT_PRIMARY; + view_->SetScreenInfo(screen_info); + + // Set a vertical display feature which must result in two window segments, + // side-by-side. + const int kDisplayFeatureLength = 20; + DisplayFeature emulated_display_feature{ + DisplayFeature::Orientation::kVertical, + /* offset */ screen_rect.width() / 2 - kDisplayFeatureLength / 2, + /* mask_length */ kDisplayFeatureLength}; + view_->SetDisplayFeatureForTesting(emulated_display_feature); + + // Flush initial state (Init ends up leaving a pending UpdateScreenRects ACK - + // we need this cleared so that the below call to SendScreenRects updates + // RenderWidgetHostImpl members). + host_->OnMessageReceived( + WidgetHostMsg_UpdateScreenRects_ACK(host_->GetRoutingID())); + + view_->SetBounds(screen_rect); + host_->SendScreenRects(); + + sink_->ClearMessages(); + ASSERT_EQ(0u, sink_->message_count()); + + // Run SynchronizeVisualProperties and validate the window segments sent to + // the renderer are correct. + EXPECT_TRUE(host_->SynchronizeVisualProperties()); + ASSERT_EQ(1u, sink_->message_count()); + const IPC::Message* msg = sink_->GetMessageAt(0); + ASSERT_EQ(WidgetMsg_UpdateVisualProperties::ID, msg->type()); + WidgetMsg_UpdateVisualProperties::Param params; + WidgetMsg_UpdateVisualProperties::Read(msg, ¶ms); + auto window_segments = std::get<0>(params).root_widget_window_segments; + EXPECT_EQ(window_segments.size(), 2u); + gfx::Rect expected_first_rect(0, 0, 390, 600); + EXPECT_EQ(window_segments[0], expected_first_rect); + gfx::Rect expected_second_rect(410, 0, 390, 600); + EXPECT_EQ(window_segments[1], expected_second_rect); + sink_->ClearMessages(); + ASSERT_EQ(0u, sink_->message_count()); + + // Setting a bottom inset (simulating virtual keyboard displaying on Aura) + // should result in 'shorter' segments. + gfx::Insets insets(0, 0, 100, 0); + view_->SetInsets(insets); + expected_first_rect.Inset(insets); + expected_second_rect.Inset(insets); + host_->SynchronizeVisualPropertiesIgnoringPendingAck(); + ASSERT_EQ(1u, sink_->message_count()); + msg = sink_->GetMessageAt(0); + ASSERT_EQ(WidgetMsg_UpdateVisualProperties::ID, msg->type()); + WidgetMsg_UpdateVisualProperties::Read(msg, ¶ms); + auto inset_window_segments = std::get<0>(params).root_widget_window_segments; + EXPECT_EQ(inset_window_segments.size(), 2u); + EXPECT_EQ(inset_window_segments[0], expected_first_rect); + EXPECT_EQ(inset_window_segments[1], expected_second_rect); + sink_->ClearMessages(); + ASSERT_EQ(0u, sink_->message_count()); + + view_->SetInsets(gfx::Insets(0, 0, 0, 0)); + + // Setting back to empty should result in a single rect. The previous call + // resized the widget and causes a pending ack. This is unrelated to what + // we're testing here so ignore the pending ack by using + // |SynchronizeVisualPropertiesIgnoringPendingAck()|. + view_->SetDisplayFeatureForTesting(base::nullopt); + host_->SynchronizeVisualPropertiesIgnoringPendingAck(); + ASSERT_EQ(1u, sink_->message_count()); + msg = sink_->GetMessageAt(0); + ASSERT_EQ(WidgetMsg_UpdateVisualProperties::ID, msg->type()); + WidgetMsg_UpdateVisualProperties::Read(msg, ¶ms); + auto single_window_segments = std::get<0>(params).root_widget_window_segments; + EXPECT_EQ(single_window_segments.size(), 1u); + EXPECT_EQ(single_window_segments[0], gfx::Rect(0, 0, 800, 600)); + sink_->ClearMessages(); + ASSERT_EQ(0u, sink_->message_count()); + + // Set a horizontal display feature which results in two window segments + // stacked on top of each other. + emulated_display_feature = { + DisplayFeature::Orientation::kHorizontal, + /* offset */ screen_rect.height() / 2 - kDisplayFeatureLength / 2, + /* mask_length */ kDisplayFeatureLength}; + view_->SetDisplayFeatureForTesting(emulated_display_feature); + host_->SynchronizeVisualPropertiesIgnoringPendingAck(); + ASSERT_EQ(1u, sink_->message_count()); + msg = sink_->GetMessageAt(0); + ASSERT_EQ(WidgetMsg_UpdateVisualProperties::ID, msg->type()); + WidgetMsg_UpdateVisualProperties::Read(msg, ¶ms); + auto vertical_window_segments = + std::get<0>(params).root_widget_window_segments; + EXPECT_EQ(vertical_window_segments.size(), 2u); + expected_first_rect = gfx::Rect(0, 0, 800, 290); + EXPECT_EQ(vertical_window_segments[0], expected_first_rect); + expected_second_rect = gfx::Rect(0, 310, 800, 290); + EXPECT_EQ(vertical_window_segments[1], expected_second_rect); + sink_->ClearMessages(); + ASSERT_EQ(0u, sink_->message_count()); + + // If the segments don't change, there should be no IPC message sent. + host_->SynchronizeVisualPropertiesIgnoringPendingAck(); + EXPECT_EQ(0u, sink_->message_count()); +} + TEST_F(RenderWidgetHostTest, ReceiveFrameTokenFromCrashedRenderer) { // The Renderer sends a monotonically increasing frame token. host_->DidProcessFrame(2); @@ -1043,7 +1185,7 @@ TEST_F(RenderWidgetHostTest, ReceiveFrameTokenFromCrashedRenderer) { // RenderWidget is being created. VisualProperties props = host_->GetInitialVisualProperties(); // The RenderWidget is recreated with the initial VisualProperties. - host_->Init(); + ReinitalizeHost(); // The new RenderWidget sends a frame token, which is lower than what the // previous RenderWidget sent. This should be okay, as the expected token has @@ -1230,7 +1372,7 @@ TEST_F(RenderWidgetHostTest, PreHandleRawKeyDownEvent) { ASSERT_EQ(1u, dispatched_events.size()); ASSERT_TRUE(dispatched_events[0]->ToEvent()); EXPECT_EQ(WebInputEvent::Type::kRawKeyDown, - dispatched_events[0]->ToEvent()->Event()->web_event->GetType()); + dispatched_events[0]->ToEvent()->Event()->Event().GetType()); // Send the simulated response from the renderer back. dispatched_events[0]->ToEvent()->CallCallback( @@ -1259,7 +1401,7 @@ TEST_F(RenderWidgetHostTest, RawKeyDownShortcutEvent) { ASSERT_EQ(1u, dispatched_events.size()); ASSERT_TRUE(dispatched_events[0]->ToEvent()); EXPECT_EQ(WebInputEvent::Type::kRawKeyDown, - dispatched_events[0]->ToEvent()->Event()->web_event->GetType()); + dispatched_events[0]->ToEvent()->Event()->Event().GetType()); // Send the simulated response from the renderer back. dispatched_events[0]->ToEvent()->CallCallback( @@ -1280,7 +1422,7 @@ TEST_F(RenderWidgetHostTest, RawKeyDownShortcutEvent) { ASSERT_EQ(1u, dispatched_events.size()); ASSERT_TRUE(dispatched_events[0]->ToEvent()); EXPECT_EQ(WebInputEvent::Type::kChar, - dispatched_events[0]->ToEvent()->Event()->web_event->GetType()); + dispatched_events[0]->ToEvent()->Event()->Event().GetType()); // Send the simulated response from the renderer back. dispatched_events[0]->ToEvent()->CallCallback( @@ -1297,7 +1439,7 @@ TEST_F(RenderWidgetHostTest, RawKeyDownShortcutEvent) { ASSERT_EQ(1u, dispatched_events.size()); ASSERT_TRUE(dispatched_events[0]->ToEvent()); EXPECT_EQ(WebInputEvent::Type::kKeyUp, - dispatched_events[0]->ToEvent()->Event()->web_event->GetType()); + dispatched_events[0]->ToEvent()->Event()->Event().GetType()); // Send the simulated response from the renderer back. dispatched_events[0]->ToEvent()->CallCallback( @@ -1314,7 +1456,7 @@ TEST_F(RenderWidgetHostTest, UnhandledWheelEvent) { ASSERT_EQ(1u, dispatched_events.size()); ASSERT_TRUE(dispatched_events[0]->ToEvent()); EXPECT_EQ(WebInputEvent::Type::kMouseWheel, - dispatched_events[0]->ToEvent()->Event()->web_event->GetType()); + dispatched_events[0]->ToEvent()->Event()->Event().GetType()); // Send the simulated response from the renderer back. dispatched_events[0]->ToEvent()->CallCallback( @@ -1336,7 +1478,7 @@ TEST_F(RenderWidgetHostTest, HandleWheelEvent) { ASSERT_EQ(1u, dispatched_events.size()); ASSERT_TRUE(dispatched_events[0]->ToEvent()); EXPECT_EQ(WebInputEvent::Type::kMouseWheel, - dispatched_events[0]->ToEvent()->Event()->web_event->GetType()); + dispatched_events[0]->ToEvent()->Event()->Event().GetType()); // Send the simulated response from the renderer back. dispatched_events[0]->ToEvent()->CallCallback( @@ -1379,7 +1521,7 @@ TEST_F(RenderWidgetHostTest, UnhandledGestureEvent) { ASSERT_EQ(1u, dispatched_events.size()); ASSERT_TRUE(dispatched_events[0]->ToEvent()); EXPECT_EQ(WebInputEvent::Type::kGestureTwoFingerTap, - dispatched_events[0]->ToEvent()->Event()->web_event->GetType()); + dispatched_events[0]->ToEvent()->Event()->Event().GetType()); // Send the simulated response from the renderer back. dispatched_events[0]->ToEvent()->CallCallback( @@ -1394,8 +1536,7 @@ TEST_F(RenderWidgetHostTest, UnhandledGestureEvent) { // Test that the hang monitor timer expires properly if a new timer is started // while one is in progress (see crbug.com/11007). TEST_F(RenderWidgetHostTest, DontPostponeInputEventAckTimeout) { - base::TimeDelta delay = - base::TimeDelta::FromMilliseconds(kHungRendererDelayMs); + base::TimeDelta delay = kHungRendererDelay; // Start a timeout. host_->StartInputEventAckTimeout(); @@ -1423,8 +1564,8 @@ TEST_F(RenderWidgetHostTest, StopAndStartInputEventAckTimeout) { host_->StartInputEventAckTimeout(); // Wait long enough for first timeout and see if it fired. - task_environment_.FastForwardBy( - base::TimeDelta::FromMilliseconds(kHungRendererDelayMs + 10)); + task_environment_.FastForwardBy(kHungRendererDelay + + base::TimeDelta::FromMilliseconds(10)); EXPECT_TRUE(delegate_->unresponsive_timer_fired()); } @@ -1438,21 +1579,21 @@ TEST_F(RenderWidgetHostTest, InputEventAckTimeoutDisabledForInputWhenHidden) { // The timeout should not fire. EXPECT_FALSE(delegate_->unresponsive_timer_fired()); - task_environment_.FastForwardBy( - base::TimeDelta::FromMilliseconds(kHungRendererDelayMs + 10)); + task_environment_.FastForwardBy(kHungRendererDelay + + base::TimeDelta::FromMilliseconds(10)); EXPECT_FALSE(delegate_->unresponsive_timer_fired()); // The timeout should never reactivate while hidden. SimulateMouseEvent(WebInputEvent::Type::kMouseMove, 10, 10, 0, false); - task_environment_.FastForwardBy( - base::TimeDelta::FromMilliseconds(kHungRendererDelayMs + 10)); + task_environment_.FastForwardBy(kHungRendererDelay + + base::TimeDelta::FromMilliseconds(10)); EXPECT_FALSE(delegate_->unresponsive_timer_fired()); // Showing the widget should restore the timeout, as the events have // not yet been ack'ed. host_->WasShown(base::nullopt /* record_tab_switch_time_request */); - task_environment_.FastForwardBy( - base::TimeDelta::FromMilliseconds(kHungRendererDelayMs + 10)); + task_environment_.FastForwardBy(kHungRendererDelay + + base::TimeDelta::FromMilliseconds(10)); EXPECT_TRUE(delegate_->unresponsive_timer_fired()); } @@ -1462,8 +1603,7 @@ TEST_F(RenderWidgetHostTest, InputEventAckTimeoutDisabledForInputWhenHidden) { TEST_F(RenderWidgetHostTest, MultipleInputEvents) { // Send two events but only one ack. SimulateKeyboardEvent(WebInputEvent::Type::kRawKeyDown); - task_environment_.FastForwardBy( - base::TimeDelta::FromMilliseconds(kHungRendererDelayMs / 2)); + task_environment_.FastForwardBy(kHungRendererDelay / 2); SimulateKeyboardEvent(WebInputEvent::Type::kRawKeyDown); MockWidgetInputHandler::MessageVector dispatched_events = @@ -1476,8 +1616,8 @@ TEST_F(RenderWidgetHostTest, MultipleInputEvents) { blink::mojom::InputEventResultState::kConsumed); // Wait long enough for second timeout and see if it fired. - task_environment_.FastForwardBy( - base::TimeDelta::FromMilliseconds(kHungRendererDelayMs + 10)); + task_environment_.FastForwardBy(kHungRendererDelay + + base::TimeDelta::FromMilliseconds(10)); EXPECT_TRUE(delegate_->unresponsive_timer_fired()); } @@ -1574,10 +1714,10 @@ void CheckLatencyInfoComponentInMessage( ASSERT_EQ(1u, dispatched_events.size()); ASSERT_TRUE(dispatched_events[0]->ToEvent()); - EXPECT_TRUE(dispatched_events[0]->ToEvent()->Event()->web_event->GetType() == + EXPECT_TRUE(dispatched_events[0]->ToEvent()->Event()->Event().GetType() == expected_type); EXPECT_TRUE( - dispatched_events[0]->ToEvent()->Event()->latency_info.FindLatency( + dispatched_events[0]->ToEvent()->Event()->latency_info().FindLatency( ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, nullptr)); dispatched_events[0]->ToEvent()->CallCallback( blink::mojom::InputEventResultState::kConsumed); @@ -1589,12 +1729,12 @@ void CheckLatencyInfoComponentInGestureScrollUpdate( ASSERT_TRUE(dispatched_events[0]->ToEvent()); ASSERT_TRUE(dispatched_events[1]->ToEvent()); EXPECT_EQ(WebInputEvent::Type::kTouchScrollStarted, - dispatched_events[0]->ToEvent()->Event()->web_event->GetType()); + dispatched_events[0]->ToEvent()->Event()->Event().GetType()); EXPECT_EQ(WebInputEvent::Type::kGestureScrollUpdate, - dispatched_events[1]->ToEvent()->Event()->web_event->GetType()); + dispatched_events[1]->ToEvent()->Event()->Event().GetType()); EXPECT_TRUE( - dispatched_events[1]->ToEvent()->Event()->latency_info.FindLatency( + dispatched_events[1]->ToEvent()->Event()->latency_info().FindLatency( ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, nullptr)); dispatched_events[1]->ToEvent()->CallCallback( blink::mojom::InputEventResultState::kConsumed); @@ -1696,7 +1836,7 @@ TEST_F(RenderWidgetHostTest, RendererExitedResetsInputRouter) { // RenderWidget is being created. VisualProperties props = host_->GetInitialVisualProperties(); // The RenderWidget is recreated with the initial VisualProperties. - host_->Init(); + ReinitalizeHost(); // Make sure the input router is in a fresh state. ASSERT_FALSE(host_->input_router()->HasPendingEvents()); @@ -1765,7 +1905,7 @@ TEST_F(RenderWidgetHostTest, RendererExitedResetsScreenRectsAck) { // RenderWidget is being created. VisualProperties props = host_->GetInitialVisualProperties(); // The RenderWidget is recreated with the initial VisualProperties. - host_->Init(); + ReinitalizeHost(); // The RenderWidget is shown when navigation completes. This sends screen // rects again. The IPC is sent as it's not waiting for an ack. @@ -1933,7 +2073,7 @@ TEST_F(RenderWidgetHostTest, EventDispatchPostDetach) { TEST_F(RenderWidgetHostTest, FrameToken_MessageThenFrame) { constexpr uint32_t frame_token = 1; std::vector<IPC::Message> messages; - messages.push_back(WidgetHostMsg_DidFirstVisuallyNonEmptyPaint(5)); + messages.push_back(WidgetHostMsg_Close(5)); EXPECT_EQ(0u, host_->frame_token_message_queue_->size()); EXPECT_EQ(0u, host_->processed_frame_messages_count()); @@ -1953,7 +2093,7 @@ TEST_F(RenderWidgetHostTest, FrameToken_MessageThenFrame) { TEST_F(RenderWidgetHostTest, FrameToken_FrameThenMessage) { constexpr uint32_t frame_token = 1; std::vector<IPC::Message> messages; - messages.push_back(WidgetHostMsg_DidFirstVisuallyNonEmptyPaint(5)); + messages.push_back(WidgetHostMsg_Close(5)); EXPECT_EQ(0u, host_->frame_token_message_queue_->size()); EXPECT_EQ(0u, host_->processed_frame_messages_count()); @@ -1975,8 +2115,8 @@ TEST_F(RenderWidgetHostTest, FrameToken_MultipleMessagesThenTokens) { constexpr uint32_t frame_token2 = 2; std::vector<IPC::Message> messages1; std::vector<IPC::Message> messages2; - messages1.push_back(WidgetHostMsg_DidFirstVisuallyNonEmptyPaint(5)); - messages2.push_back(WidgetHostMsg_DidFirstVisuallyNonEmptyPaint(6)); + messages1.push_back(WidgetHostMsg_Close(5)); + messages2.push_back(WidgetHostMsg_Close(6)); EXPECT_EQ(0u, host_->frame_token_message_queue_->size()); EXPECT_EQ(0u, host_->processed_frame_messages_count()); @@ -2006,8 +2146,8 @@ TEST_F(RenderWidgetHostTest, FrameToken_MultipleTokensThenMessages) { constexpr uint32_t frame_token2 = 2; std::vector<IPC::Message> messages1; std::vector<IPC::Message> messages2; - messages1.push_back(WidgetHostMsg_DidFirstVisuallyNonEmptyPaint(5)); - messages2.push_back(WidgetHostMsg_DidFirstVisuallyNonEmptyPaint(6)); + messages1.push_back(WidgetHostMsg_Close(5)); + messages2.push_back(WidgetHostMsg_Close(6)); EXPECT_EQ(0u, host_->frame_token_message_queue_->size()); EXPECT_EQ(0u, host_->processed_frame_messages_count()); @@ -2038,8 +2178,8 @@ TEST_F(RenderWidgetHostTest, FrameToken_DroppedFrame) { constexpr uint32_t frame_token2 = 2; std::vector<IPC::Message> messages1; std::vector<IPC::Message> messages2; - messages1.push_back(WidgetHostMsg_DidFirstVisuallyNonEmptyPaint(5)); - messages2.push_back(WidgetHostMsg_DidFirstVisuallyNonEmptyPaint(6)); + messages1.push_back(WidgetHostMsg_Close(5)); + messages2.push_back(WidgetHostMsg_Close(6)); EXPECT_EQ(0u, host_->frame_token_message_queue_->size()); EXPECT_EQ(0u, host_->processed_frame_messages_count()); @@ -2059,26 +2199,6 @@ TEST_F(RenderWidgetHostTest, FrameToken_DroppedFrame) { EXPECT_EQ(2u, host_->processed_frame_messages_count()); } -TEST_F(RenderWidgetHostTest, ForceEnableZoomShouldUpdateAfterRebind) { - SCOPED_TRACE("force_enable_zoom is false at start."); - host_->ExpectForceEnableZoom(false); - - // Set force_enable_zoom true. - host_->SetForceEnableZoom(true); - - SCOPED_TRACE("force_enable_zoom is true after set."); - host_->ExpectForceEnableZoom(true); - - // Rebind should also update to the latest force_enable_zoom state. - mojo::PendingRemote<mojom::Widget> widget; - std::unique_ptr<MockWidgetImpl> widget_impl = - std::make_unique<MockWidgetImpl>(widget.InitWithNewPipeAndPassReceiver()); - host_->SetWidget(std::move(widget)); - - SCOPED_TRACE("force_enable_zoom is true after rebind."); - host_->ExpectForceEnableZoom(true); -} - // If a navigation happens while the widget is hidden, we shouldn't show // contents of the previous page when we become visible. TEST_F(RenderWidgetHostTest, NavigateInBackgroundShowsBlank) { diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_android.cc b/chromium/content/browser/renderer_host/render_widget_host_view_android.cc index 34f614accf1..059badcaad7 100644 --- a/chromium/content/browser/renderer_host/render_widget_host_view_android.cc +++ b/chromium/content/browser/renderer_host/render_widget_host_view_android.cc @@ -6,6 +6,7 @@ #include <android/bitmap.h> +#include <limits> #include <utility> #include "base/android/build_info.h" @@ -84,8 +85,6 @@ #include "ui/android/view_android_observer.h" #include "ui/android/window_android.h" #include "ui/android/window_android_compositor.h" -#include "ui/base/cursor/cursor.h" -#include "ui/base/cursor/cursor_lookup.h" #include "ui/base/layout.h" #include "ui/base/ui_base_types.h" #include "ui/events/android/gesture_event_android.h" @@ -233,8 +232,10 @@ RenderWidgetHostViewAndroid::RenderWidgetHostViewAndroid( observing_root_window_(false), prev_top_shown_pix_(0.f), prev_top_controls_translate_(0.f), + prev_top_controls_min_height_offset_pix_(0.f), prev_bottom_shown_pix_(0.f), prev_bottom_controls_translate_(0.f), + prev_bottom_controls_min_height_offset_pix_(0.f), page_scale_(1.f), min_page_scale_(1.f), max_page_scale_(1.f), @@ -492,6 +493,23 @@ void RenderWidgetHostViewAndroid::OnRenderFrameMetadataChangedBeforeActivation( // change. We must still call UpdateWebViewBackgroundColorIfNecessary to // maintain the associated background color changes. UpdateWebViewBackgroundColorIfNecessary(); + + if (metadata.new_vertical_scroll_direction != + viz::VerticalScrollDirection::kNull) { + bool can_scroll = metadata.root_layer_size.height() - + metadata.viewport_size_in_pixels.height() > + std::numeric_limits<float>::epsilon(); + float scroll_ratio = 0.f; + if (can_scroll && metadata.root_scroll_offset) { + scroll_ratio = metadata.root_scroll_offset.value().y() / + (metadata.root_layer_size.height() - + metadata.viewport_size_in_pixels.height()); + } + view_.OnVerticalScrollDirectionChanged( + metadata.new_vertical_scroll_direction == + viz::VerticalScrollDirection::kUp, + scroll_ratio); + } } base::android::ScopedJavaLocalRef<jobject> @@ -580,6 +598,16 @@ void RenderWidgetHostViewAndroid:: RenderWidgetHostViewBase::OnRenderFrameMetadataChangedAfterActivation(); } +void RenderWidgetHostViewAndroid::OnRootScrollOffsetChanged( + const gfx::Vector2dF& root_scroll_offset) { + if (!gesture_listener_manager_) + return; + gfx::Vector2dF root_scroll_offset_dip = root_scroll_offset; + if (IsUseZoomForDSFEnabled()) + root_scroll_offset_dip.Scale(1 / view_.GetDipScale()); + gesture_listener_manager_->OnRootScrollOffsetChanged(root_scroll_offset_dip); +} + void RenderWidgetHostViewAndroid::Focus() { if (view_.HasFocus()) GotFocus(); @@ -684,9 +712,7 @@ int RenderWidgetHostViewAndroid::GetMouseWheelMinimumGranularity() const { } void RenderWidgetHostViewAndroid::UpdateCursor(const WebCursor& webcursor) { - const ui::Cursor& cursor = webcursor.cursor(); - view_.OnCursorChanged(static_cast<int>(cursor.type()), - GetCursorBitmap(cursor), GetCursorHotspot(cursor)); + view_.OnCursorChanged(webcursor.cursor()); } void RenderWidgetHostViewAndroid::SetIsLoading(bool is_loading) { @@ -703,10 +729,10 @@ void RenderWidgetHostViewAndroid::OnUpdateTextInputStateCalled( DCHECK_EQ(text_input_manager_, text_input_manager); // If there are no active widgets, the TextInputState.type should be reported // as none. - const TextInputState& state = + const ui::mojom::TextInputState& state = GetTextInputManager()->GetActiveWidget() ? *GetTextInputManager()->GetTextInputState() - : TextInputState(); + : ui::mojom::TextInputState(); if (!ime_adapter_android_) return; @@ -789,6 +815,20 @@ bool RenderWidgetHostViewAndroid::TransformPointToCoordSpaceForView( transformed_point); } +void RenderWidgetHostViewAndroid::SetGestureListenerManager( + GestureListenerManager* manager) { + gesture_listener_manager_ = manager; + UpdateReportAllRootScrolls(); +} + +void RenderWidgetHostViewAndroid::UpdateReportAllRootScrolls() { + if (!host()) + return; + + host()->render_frame_metadata_provider()->ReportAllRootScrolls( + ShouldReportAllRootScrolls()); +} + base::WeakPtr<RenderWidgetHostViewAndroid> RenderWidgetHostViewAndroid::GetWeakPtrAndroid() { return weak_ptr_factory_.GetWeakPtr(); @@ -1321,6 +1361,7 @@ bool RenderWidgetHostViewAndroid::UpdateControls( top_min_height_offset_pix); prev_top_shown_pix_ = top_shown_pix; prev_top_controls_translate_ = top_translate; + prev_top_controls_min_height_offset_pix_ = top_min_height_offset_pix; float bottom_controls_pix = bottom_controls_height * to_pix; float bottom_shown_pix = bottom_controls_pix * bottom_controls_shown_ratio; @@ -1339,6 +1380,7 @@ bool RenderWidgetHostViewAndroid::UpdateControls( bottom_min_height_offset_pix); prev_bottom_shown_pix_ = bottom_shown_pix; prev_bottom_controls_translate_ = bottom_translate; + prev_bottom_controls_min_height_offset_pix_ = bottom_min_height_offset_pix; controls_initialized_ = true; return top_changed || bottom_changed; } @@ -1973,6 +2015,15 @@ void RenderWidgetHostViewAndroid::UpdateNativeViewTree( CreateOverscrollControllerIfPossible(); } +bool RenderWidgetHostViewAndroid::ShouldReportAllRootScrolls() { + // In order to provide support for onScrollOffsetOrExtentChanged() + // GestureListenerManager needs root-scroll-offsets. This is only necessary + // if a GestureStateListenerWithScroll is added. + return web_contents_accessibility_ != nullptr || + (gesture_listener_manager_ && + gesture_listener_manager_->has_listeners_attached()); +} + MouseWheelPhaseHandler* RenderWidgetHostViewAndroid::GetMouseWheelPhaseHandler() { return &mouse_wheel_phase_handler_; @@ -2363,12 +2414,7 @@ void RenderWidgetHostViewAndroid::OnUpdateScopedSelectionHandles() { void RenderWidgetHostViewAndroid::SetWebContentsAccessibility( WebContentsAccessibilityAndroid* web_contents_accessibility) { web_contents_accessibility_ = web_contents_accessibility; - - if (host()) { - host() - ->render_frame_metadata_provider() - ->ReportAllRootScrollsForAccessibility(!!web_contents_accessibility_); - } + UpdateReportAllRootScrolls(); } void RenderWidgetHostViewAndroid::SetNeedsBeginFrameForFlingProgress() { diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_android.h b/chromium/content/browser/renderer_host/render_widget_host_view_android.h index 86a35ef6f0f..f0f243f7b67 100644 --- a/chromium/content/browser/renderer_host/render_widget_host_view_android.h +++ b/chromium/content/browser/renderer_host/render_widget_host_view_android.h @@ -248,9 +248,9 @@ class CONTENT_EXPORT RenderWidgetHostViewAndroid TextSuggestionHostAndroid* text_suggestion_host() const { return text_suggestion_host_; } - void set_gesture_listener_manager(GestureListenerManager* manager) { - gesture_listener_manager_ = manager; - } + void SetGestureListenerManager(GestureListenerManager* manager); + + void UpdateReportAllRootScrolls(); base::WeakPtr<RenderWidgetHostViewAndroid> GetWeakPtrAndroid(); @@ -317,6 +317,8 @@ class CONTENT_EXPORT RenderWidgetHostViewAndroid void OnRenderFrameMetadataChangedBeforeActivation( const cc::RenderFrameMetadata& metadata) override; void OnRenderFrameMetadataChangedAfterActivation() override; + void OnRootScrollOffsetChanged( + const gfx::Vector2dF& root_scroll_offset) override; void WasEvicted(); @@ -371,6 +373,8 @@ class CONTENT_EXPORT RenderWidgetHostViewAndroid FRIEND_TEST_ALL_PREFIXES(SitePerProcessBrowserTest, GestureManagerListensToChildFrames); + bool ShouldReportAllRootScrolls(); + MouseWheelPhaseHandler* GetMouseWheelPhaseHandler() override; void EvictDelegatedFrame(); diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_aura.cc b/chromium/content/browser/renderer_host/render_widget_host_view_aura.cc index f22bf425526..338fd87a55c 100644 --- a/chromium/content/browser/renderer_host/render_widget_host_view_aura.cc +++ b/chromium/content/browser/renderer_host/render_widget_host_view_aura.cc @@ -45,7 +45,6 @@ #include "content/browser/renderer_host/render_widget_host_view_event_handler.h" #include "content/browser/renderer_host/ui_events_helper.h" #include "content/common/input_messages.h" -#include "content/common/text_input_state.h" #include "content/common/view_messages.h" #include "content/public/browser/content_browser_client.h" #include "content/public/browser/render_view_host.h" @@ -54,7 +53,6 @@ #include "gpu/ipc/common/gpu_messages.h" #include "services/service_manager/public/cpp/interface_provider.h" #include "third_party/blink/public/common/input/web_input_event.h" -#include "third_party/blink/public/web/web_ime_text_span.h" #include "ui/accessibility/accessibility_switches.h" #include "ui/accessibility/aura/aura_window_properties.h" #include "ui/accessibility/platform/ax_platform_node.h" @@ -74,6 +72,7 @@ #include "ui/base/cursor/mojom/cursor_type.mojom-shared.h" #include "ui/base/hit_test.h" #include "ui/base/ime/input_method.h" +#include "ui/base/ime/mojom/text_input_state.mojom.h" #include "ui/base/ui_base_switches.h" #include "ui/base/ui_base_types.h" #include "ui/compositor/dip_util.h" @@ -116,8 +115,8 @@ #endif #if defined(OS_LINUX) && !defined(OS_CHROMEOS) -#include "ui/base/ime/linux/text_edit_command_auralinux.h" -#include "ui/base/ime/linux/text_edit_key_bindings_delegate_auralinux.h" +#include "ui/base/ime/linux/text_edit_command_auralinux.h" // nogncheck +#include "ui/base/ime/linux/text_edit_key_bindings_delegate_auralinux.h" // nogncheck #endif #if defined(OS_CHROMEOS) @@ -137,72 +136,6 @@ using blink::WebTouchEvent; namespace content { -namespace { - -mojom::FrameInputHandler* GetFrameInputHandlerForFocusedFrame( - RenderWidgetHostImpl* host) { - if (!host || !host->delegate()) { - return nullptr; - } - RenderFrameHostImpl* render_frame_host = - host->delegate()->GetFocusedFrameFromFocusedDelegate(); - if (!render_frame_host) - return nullptr; - return render_frame_host->GetFrameInputHandler(); -} - -} // namespace - -#if defined(OS_WIN) - -// This class implements the ui::InputMethodKeyboardControllerObserver interface -// which provides notifications about the on screen keyboard on Windows getting -// displayed or hidden in response to taps on editable fields. -// It provides functionality to request blink to scroll the input field if it -// is obscured by the on screen keyboard. -class WinScreenKeyboardObserver - : public ui::InputMethodKeyboardControllerObserver { - public: - explicit WinScreenKeyboardObserver(RenderWidgetHostViewAura* host_view) - : host_view_(host_view) { - host_view_->SetInsets(gfx::Insets()); - if (auto* input_method = host_view_->GetInputMethod()) - input_method->GetInputMethodKeyboardController()->AddObserver(this); - } - - ~WinScreenKeyboardObserver() override { - if (auto* input_method = host_view_->GetInputMethod()) - input_method->GetInputMethodKeyboardController()->RemoveObserver(this); - } - - // InputMethodKeyboardControllerObserver overrides. - void OnKeyboardVisible(const gfx::Rect& keyboard_rect) override { - // If the software input panel(SIP) is manually raised by the user, the flag - // should be set so we don't call TryShow API again. - host_view_->SetVirtualKeyboardRequested(true); - host_view_->SetInsets(gfx::Insets( - 0, 0, keyboard_rect.IsEmpty() ? 0 : keyboard_rect.height(), 0)); - } - - void OnKeyboardHidden() override { - // If the software input panel(SIP) is manually closed by the user, the flag - // should be reset so we don't call TryHide API again. Also, - // next time user taps on an editable element after manually dismissing the - // keyboard, this flag is used to determine whether TryShow needs to be - // called or not. Calling TryShow/TryHide multiple times leads to SIP - // flickering. - host_view_->SetVirtualKeyboardRequested(false); - // Restore the viewport. - host_view_->SetInsets(gfx::Insets()); - } - - private: - RenderWidgetHostViewAura* host_view_; - - DISALLOW_COPY_AND_ASSIGN(WinScreenKeyboardObserver); -}; -#endif // defined(OS_WIN) - // We need to watch for mouse events outside a Web Popup or its parent // and dismiss the popup for certain events. class RenderWidgetHostViewAura::EventObserverForPopupExit @@ -367,7 +300,6 @@ RenderWidgetHostViewAura::RenderWidgetHostViewAura( #if defined(OS_WIN) legacy_render_widget_host_HWND_(nullptr), legacy_window_destroyed_(false), - virtual_keyboard_requested_(false), #endif device_scale_factor_(0.0f), event_handler_(new RenderWidgetHostViewEventHandler(host(), this, this)), @@ -646,7 +578,6 @@ void RenderWidgetHostViewAura::WasUnOccluded() { SetRecordContentToVisibleTimeRequest( base::TimeTicks::Now(), base::Optional<bool>() /* destination_is_loaded */, - base::Optional<bool>() /* destination_is_frozen */, false /* show_reason_tab_switching */, true /* show_reason_unoccluded */, false /* show_reason_bfcache_restore */); @@ -876,6 +807,7 @@ void RenderWidgetHostViewAura::OnLegacyWindowDestroyed() { legacy_render_widget_host_HWND_ = nullptr; legacy_window_destroyed_ = true; } +#endif gfx::NativeViewAccessible RenderWidgetHostViewAura::GetParentNativeViewAccessible() { @@ -893,7 +825,6 @@ RenderWidgetHostViewAura::GetParentNativeViewAccessible() { return nullptr; } -#endif void RenderWidgetHostViewAura::ResetFallbackToFirstNavigationSurface() { if (delegated_frame_host_) @@ -1369,12 +1300,13 @@ bool RenderWidgetHostViewAura::GetTextRange(gfx::Range* range) const { if (!text_input_manager_ || !GetFocusedWidget()) return false; - const TextInputState* state = text_input_manager_->GetTextInputState(); + const ui::mojom::TextInputState* state = + text_input_manager_->GetTextInputState(); if (!state) return false; range->set_start(0); - range->set_end(state->value.length()); + range->set_end(state->value ? state->value->length() : 0); return true; } @@ -1383,13 +1315,13 @@ bool RenderWidgetHostViewAura::GetCompositionTextRange( if (!text_input_manager_ || !GetFocusedWidget()) return false; - const TextInputState* state = text_input_manager_->GetTextInputState(); + const ui::mojom::TextInputState* state = + text_input_manager_->GetTextInputState(); // Return false when there is no composition. - if (!state || state->composition_start == -1) + if (!state || !state->composition) return false; - range->set_start(state->composition_start); - range->set_end(state->composition_end); + *range = state->composition.value(); return true; } @@ -1398,22 +1330,19 @@ bool RenderWidgetHostViewAura::GetEditableSelectionRange( if (!text_input_manager_ || !GetFocusedWidget()) return false; - const TextInputState* state = text_input_manager_->GetTextInputState(); + const ui::mojom::TextInputState* state = + text_input_manager_->GetTextInputState(); if (!state) return false; - range->set_start(state->selection_start); - range->set_end(state->selection_end); + *range = state->selection; return true; } bool RenderWidgetHostViewAura::SetEditableSelectionRange( const gfx::Range& range) { // TODO(crbug.com/915630): Write an unit test for this method. - RenderFrameHostImpl* rfh = GetFocusedFrame(); - if (!rfh) - return false; - auto* input_handler = rfh->GetFrameInputHandler(); + auto* input_handler = GetFrameWidgetInputHandlerForFocusedWidget(); if (!input_handler) return false; input_handler->SetEditableSelectionOffsets(range.start(), range.end()); @@ -1432,7 +1361,8 @@ bool RenderWidgetHostViewAura::GetTextFromRange( if (!text_input_manager_ || !GetFocusedWidget()) return false; - const TextInputState* state = text_input_manager_->GetTextInputState(); + const ui::mojom::TextInputState* state = + text_input_manager_->GetTextInputState(); if (!state) return false; @@ -1443,11 +1373,15 @@ bool RenderWidgetHostViewAura::GetTextFromRange( text->clear(); return false; } + if (!state->value) { + text->clear(); + return true; + } if (text_range.EqualsIgnoringDirection(range)) { // Avoid calling substr whose performance is low. - *text = state->value; + *text = *state->value; } else { - *text = state->value.substr(range.GetMin(), range.length()); + *text = state->value->substr(range.GetMin(), range.length()); } return true; } @@ -1469,7 +1403,7 @@ bool RenderWidgetHostViewAura::ChangeTextDirectionAndLayoutAlignment( void RenderWidgetHostViewAura::ExtendSelectionAndDelete( size_t before, size_t after) { - auto* input_handler = GetFrameInputHandlerForFocusedFrame(host()); + auto* input_handler = GetFrameWidgetInputHandlerForFocusedWidget(); if (!input_handler) return; input_handler->ExtendSelectionAndDelete(before, after); @@ -1519,7 +1453,7 @@ bool RenderWidgetHostViewAura::ShouldDoLearning() { bool RenderWidgetHostViewAura::SetCompositionFromExistingText( const gfx::Range& range, const std::vector<ui::ImeTextSpan>& ui_ime_text_spans) { - auto* input_handler = GetFrameInputHandlerForFocusedFrame(host()); + auto* input_handler = GetFrameWidgetInputHandlerForFocusedWidget(); if (!input_handler) return false; input_handler->SetCompositionFromExistingText(range.start(), range.end(), @@ -1530,12 +1464,22 @@ bool RenderWidgetHostViewAura::SetCompositionFromExistingText( #endif +#if defined(OS_CHROMEOS) +// TODO(crbug.com/1091088) Implement setAutocorrectRange +bool RenderWidgetHostViewAura::SetAutocorrectRange( + const base::string16& autocorrect_text, + const gfx::Range& range) { + return false; +} +#endif + #if defined(OS_WIN) void RenderWidgetHostViewAura::GetActiveTextInputControlLayoutBounds( base::Optional<gfx::Rect>* control_bounds, base::Optional<gfx::Rect>* selection_bounds) { if (text_input_manager_) { - const TextInputState* state = text_input_manager_->GetTextInputState(); + const ui::mojom::TextInputState* state = + text_input_manager_->GetTextInputState(); if (state) { if (state->edit_context_control_bounds) *control_bounds = @@ -1683,7 +1627,7 @@ void RenderWidgetHostViewAura::OnWindowDestroying(aura::Window* window) { // Make sure that the input method no longer references to this object before // this object is removed from the root window (i.e. this object loses access // to the input method). - DetachFromInputMethod(); + DetachFromInputMethod(true); if (overscroll_controller_) overscroll_controller_->Reset(); @@ -1784,13 +1728,8 @@ void RenderWidgetHostViewAura::FocusedNodeChanged( has_composition_text_ = false; #if defined(OS_WIN) - bool dismiss_virtual_keyboard = - last_pointer_type_ == ui::EventPointerType::kTouch; - if (dismiss_virtual_keyboard && !editable && virtual_keyboard_requested_ && - window_) { - virtual_keyboard_requested_ = false; - if (auto* controller = GetInputMethod()->GetInputMethodKeyboardController()) - controller->DismissVirtualKeyboard(); + if (window_ && virtual_keyboard_controller_win_) { + virtual_keyboard_controller_win_->FocusedNodeChanged(editable); } #elif defined(OS_FUCHSIA) if (!editable && window_) { @@ -1873,7 +1812,7 @@ void RenderWidgetHostViewAura::OnWindowFocused(aura::Window* gained_focus, host()->SetActive(false); host()->LostFocus(); - DetachFromInputMethod(); + DetachFromInputMethod(false); // TODO(wjmaclean): Do we need to let TouchSelectionControllerClientAura // handle this, just in case it stomps on a new highlight in another view @@ -1984,7 +1923,7 @@ RenderWidgetHostViewAura::~RenderWidgetHostViewAura() { // This call is usually no-op since |this| object is already removed from // the Aura root window and we don't have a way to get an input method // object associated with the window, but just in case. - DetachFromInputMethod(); + DetachFromInputMethod(true); } if (popup_parent_host_view_) { DCHECK(!popup_parent_host_view_->popup_child_host_view_ || @@ -2177,6 +2116,30 @@ void RenderWidgetHostViewAura::Shutdown() { } } +bool RenderWidgetHostViewAura::ShouldVirtualKeyboardOverlayContent() const { + RenderFrameHostImpl* frame = GetFocusedFrame(); + if (!frame) + return false; + + return frame->ShouldVirtualKeyboardOverlayContent(); +} + +void RenderWidgetHostViewAura::NotifyVirtualKeyboardOverlayRect( + const gfx::Rect& keyboard_rect) { + RenderFrameHostImpl* frame = GetFocusedFrame(); + if (!frame) + return; + frame->NotifyVirtualKeyboardOverlayRect(keyboard_rect); +} + +bool RenderWidgetHostViewAura::FocusedFrameHasStickyActivation() const { + RenderFrameHostImpl* frame = GetFocusedFrame(); + if (!frame) + return false; + + return frame->frame_tree_node()->HasStickyUserActivation(); +} + TouchSelectionControllerClientManager* RenderWidgetHostViewAura::GetTouchSelectionControllerClientManager() { return selection_controller_client_.get(); @@ -2314,7 +2277,7 @@ void RenderWidgetHostViewAura::RemovingFromRootWindow() { if (cursor_client) cursor_client->RemoveObserver(this); - DetachFromInputMethod(); + DetachFromInputMethod(true); window_->GetHost()->RemoveObserver(this); if (delegated_frame_host_) @@ -2328,7 +2291,7 @@ void RenderWidgetHostViewAura::RemovingFromRootWindow() { #endif } -void RenderWidgetHostViewAura::DetachFromInputMethod() { +void RenderWidgetHostViewAura::DetachFromInputMethod(bool is_removed) { ui::InputMethod* input_method = GetInputMethod(); if (input_method) { input_method->DetachTextInputClient(this); @@ -2338,9 +2301,15 @@ void RenderWidgetHostViewAura::DetachFromInputMethod() { } #if defined(OS_WIN) - // Reset the keyboard observer because it attaches to the input method. - virtual_keyboard_requested_ = false; - keyboard_observer_.reset(); + // If window is getting destroyed, then reset the VK controller, else, + // dismiss the VK and notify about the keyboard inset since window has lost + // focus. + if (virtual_keyboard_controller_win_) { + if (is_removed) + virtual_keyboard_controller_win_.reset(); + else + virtual_keyboard_controller_win_->HideAndNotifyKeyboardInset(); + } #endif // defined(OS_WIN) } @@ -2420,16 +2389,14 @@ void RenderWidgetHostViewAura::OnUpdateTextInputStateCalled( if (did_update_state) GetInputMethod()->OnTextInputTypeChanged(this); - const TextInputState* state = text_input_manager_->GetTextInputState(); + const ui::mojom::TextInputState* state = + text_input_manager_->GetTextInputState(); if (state && state->type != ui::TEXT_INPUT_TYPE_NONE && state->mode != ui::TEXT_INPUT_MODE_NONE) { bool show_virtual_keyboard = true; #if defined(OS_FUCHSIA) - show_virtual_keyboard = last_pointer_type_ == ui::EventPointerType::kTouch; -#elif defined(OS_WIN) show_virtual_keyboard = - last_pointer_type_ == ui::EventPointerType::kTouch || - last_pointer_type_ == ui::EventPointerType::kPen; + GetLastPointerType() == ui::EventPointerType::kTouch; #endif #if !defined(OS_WIN) @@ -2441,14 +2408,12 @@ void RenderWidgetHostViewAura::OnUpdateTextInputStateCalled( // TODO(crbug.com/1031786): Remove this once TSF fix for input pane policy // is serviced #elif defined(OS_WIN) - auto* controller = GetInputMethod()->GetInputMethodKeyboardController(); - if (controller && state->show_ime_if_needed && host()->GetView() && - host()->delegate()) { - if (show_virtual_keyboard && !virtual_keyboard_requested_) { - keyboard_observer_.reset(new WinScreenKeyboardObserver(this)); - GetInputMethod()->ShowVirtualKeyboardIfEnabled(); - virtual_keyboard_requested_ = keyboard_observer_.get(); + if (GetInputMethod() && show_virtual_keyboard) { + if (!virtual_keyboard_controller_win_) { + virtual_keyboard_controller_win_.reset( + new VirtualKeyboardControllerWin(this, GetInputMethod())); } + virtual_keyboard_controller_win_->UpdateTextInputState(state); } #endif // Ensure that accessibility events are fired when the selection location @@ -2531,11 +2496,7 @@ void RenderWidgetHostViewAura::SetPopupChild( void RenderWidgetHostViewAura::ScrollFocusedEditableNodeIntoRect( const gfx::Rect& node_rect) { - RenderFrameHostImpl* rfh = GetFocusedFrame(); - if (!rfh) - return; - - auto* input_handler = rfh->GetFrameInputHandler(); + auto* input_handler = GetFrameWidgetInputHandlerForFocusedWidget(); if (!input_handler) return; input_handler->ScrollFocusedEditableNodeIntoRect(node_rect); @@ -2617,6 +2578,11 @@ void RenderWidgetHostViewAura::TransferTouches( env->gesture_recognizer()->TransferTouches(window(), touches); } +void RenderWidgetHostViewAura::SetLastPointerType( + ui::EventPointerType last_pointer_type) { + last_pointer_type_ = last_pointer_type; +} + void RenderWidgetHostViewAura::InvalidateLocalSurfaceIdOnEviction() { window_->InvalidateLocalSurfaceId(); } @@ -2634,4 +2600,12 @@ void RenderWidgetHostViewAura::CancelActiveTouches() { env->gesture_recognizer()->CancelActiveTouches(window()); } +blink::mojom::FrameWidgetInputHandler* +RenderWidgetHostViewAura::GetFrameWidgetInputHandlerForFocusedWidget() { + auto* focused_widget = GetFocusedWidget(); + if (!focused_widget) + return nullptr; + return focused_widget->GetFrameWidgetInputHandler(); +} + } // namespace content diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_aura.h b/chromium/content/browser/renderer_host/render_widget_host_view_aura.h index 8e6ff0ad899..7e29da79bde 100644 --- a/chromium/content/browser/renderer_host/render_widget_host_view_aura.h +++ b/chromium/content/browser/renderer_host/render_widget_host_view_aura.h @@ -29,6 +29,7 @@ #include "content/browser/renderer_host/render_widget_host_view_base.h" #include "content/browser/renderer_host/render_widget_host_view_event_handler.h" #include "content/browser/renderer_host/text_input_manager.h" +#include "content/browser/renderer_host/virtual_keyboard_controller_win.h" #include "content/common/content_export.h" #include "content/common/cursors/webcursor.h" #include "content/public/browser/context_menu_params.h" @@ -186,6 +187,9 @@ class CONTENT_EXPORT RenderWidgetHostViewAura override; void TransferTouches( const std::vector<std::unique_ptr<ui::TouchEvent>>& touches) override; + // TODO(lanwei): Use TestApi interface to write functions that are used in + // tests and remove FRIEND_TEST_ALL_PREFIXES. + void SetLastPointerType(ui::EventPointerType last_pointer_type) override; // Overridden from ui::TextInputClient: void SetCompositionText(const ui::CompositionText& composition) override; @@ -226,6 +230,12 @@ class CONTENT_EXPORT RenderWidgetHostViewAura const std::vector<ui::ImeTextSpan>& ui_ime_text_spans) override; #endif +#if defined(OS_CHROMEOS) + // Set the autocorrect range + bool SetAutocorrectRange(const base::string16& autocorrect_text, + const gfx::Range& range) override; +#endif + #if defined(OS_WIN) // Returns the control and selection bounds of the EditContext or control // bounds of the active editable element. This is used to report the layout @@ -302,14 +312,10 @@ class CONTENT_EXPORT RenderWidgetHostViewAura // Notification that the LegacyRenderWidgetHostHWND was destroyed. void OnLegacyWindowDestroyed(); +#endif gfx::NativeViewAccessible GetParentNativeViewAccessible(); - void SetVirtualKeyboardRequested(bool virtual_keyboard_requested) { - virtual_keyboard_requested_ = virtual_keyboard_requested; - } -#endif - // Method to indicate if this instance is shutting down or closing. // TODO(shrikant): Discuss around to see if it makes sense to add this method // as part of RenderWidgetHostView. @@ -336,17 +342,17 @@ class CONTENT_EXPORT RenderWidgetHostViewAura void ShowContextMenu(const ContextMenuParams& params) override; void Shutdown() override; + bool ShouldVirtualKeyboardOverlayContent() const; + void NotifyVirtualKeyboardOverlayRect(const gfx::Rect& keyboard_rect); + bool FocusedFrameHasStickyActivation() const; + RenderWidgetHostViewEventHandler* event_handler() { return event_handler_.get(); } void ScrollFocusedEditableNodeIntoRect(const gfx::Rect& rect); - // TODO(lanwei): Use TestApi interface to write functions that are used in - // tests and remove FRIEND_TEST_ALL_PREFIXES. - void SetLastPointerType(ui::EventPointerType last_pointer_type) { - last_pointer_type_ = last_pointer_type; - } + ui::EventPointerType GetLastPointerType() const { return last_pointer_type_; } MouseWheelPhaseHandler* GetMouseWheelPhaseHandler() override; @@ -430,6 +436,8 @@ class CONTENT_EXPORT RenderWidgetHostViewAura KeyboardObserverForFocusedNodeChanged); FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraKeyboardTest, KeyboardObserverForPenInput); + FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraKeyboardTest, + KeyboardObserverDetachDuringWindowDestroy); FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraTest, DropFallbackWhenHidden); FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraTest, @@ -528,7 +536,9 @@ class CONTENT_EXPORT RenderWidgetHostViewAura RenderWidgetHostViewBase* updated_view) override; // Detaches |this| from the input method object. - void DetachFromInputMethod(); + // is_removed flag is true if this is called while the window is + // getting removed/destroyed, false, otherwise. + void DetachFromInputMethod(bool is_removed); // Dismisses a Web Popup on a mouse or touch press outside the popup and its // parent. @@ -563,6 +573,9 @@ class CONTENT_EXPORT RenderWidgetHostViewAura // Common part of Occluded() and Hide(). void HideImpl(); + blink::mojom::FrameWidgetInputHandler* + GetFrameWidgetInputHandlerForFocusedWidget(); + // NOTE: this is null if |is_mus_browser_plugin_guest_| is true. aura::Window* window_; @@ -637,11 +650,10 @@ class CONTENT_EXPORT RenderWidgetHostViewAura // we receive a request to show the context menu on a long press. std::unique_ptr<ContextMenuParams> last_context_menu_params_; - // Set to true if we requested the on screen keyboard to be displayed. - bool virtual_keyboard_requested_; - - friend class WinScreenKeyboardObserver; - std::unique_ptr<WinScreenKeyboardObserver> keyboard_observer_; + // Handles the showing/hiding of the VK on Windows. + friend class VirtualKeyboardControllerWin; + std::unique_ptr<VirtualKeyboardControllerWin> + virtual_keyboard_controller_win_; gfx::Point last_mouse_move_location_; #endif diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc b/chromium/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc index a11075d66ff..8d55ba30fe8 100644 --- a/chromium/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc +++ b/chromium/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc @@ -52,9 +52,7 @@ #include "content/browser/renderer_host/render_widget_host_view_event_handler.h" #include "content/browser/renderer_host/text_input_manager.h" #include "content/browser/web_contents/web_contents_view_aura.h" -#include "content/common/input/synthetic_web_input_event_builders.h" #include "content/common/input_messages.h" -#include "content/common/text_input_state.h" #include "content/common/view_messages.h" #include "content/common/widget_messages.h" #include "content/public/browser/context_menu_params.h" @@ -62,10 +60,10 @@ #include "content/public/browser/render_widget_host_view.h" #include "content/public/browser/web_contents_view_delegate.h" #include "content/public/common/content_features.h" +#include "content/public/test/fake_frame_widget.h" #include "content/public/test/mock_render_process_host.h" #include "content/public/test/test_browser_context.h" #include "content/test/mock_render_widget_host_delegate.h" -#include "content/test/mock_widget_impl.h" #include "content/test/test_overscroll_delegate.h" #include "content/test/test_render_view_host.h" #include "content/test/test_web_contents.h" @@ -76,6 +74,7 @@ #include "mojo/public/cpp/bindings/remote.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/common/input/synthetic_web_input_event_builders.h" #include "ui/aura/client/aura_constants.h" #include "ui/aura/client/window_parenting_client.h" #include "ui/aura/env.h" @@ -95,6 +94,7 @@ #include "ui/base/ime/input_method.h" #include "ui/base/ime/input_method_keyboard_controller.h" #include "ui/base/ime/mock_input_method.h" +#include "ui/base/ime/mojom/text_input_state.mojom.h" #include "ui/base/ui_base_switches.h" #include "ui/base/ui_base_types.h" #include "ui/compositor/compositor.h" @@ -125,6 +125,10 @@ #include "ui/display/win/test/scoped_screen_win.h" #endif +#if defined(USE_X11) +#include "ui/base/ui_base_features.h" +#endif + using testing::_; using blink::WebGestureEvent; @@ -362,19 +366,14 @@ class MockRenderWidgetHostImpl : public RenderWidgetHostImpl { static MockRenderWidgetHostImpl* Create(RenderWidgetHostDelegate* delegate, RenderProcessHost* process, int32_t routing_id) { - mojo::PendingRemote<mojom::Widget> widget; - std::unique_ptr<MockWidgetImpl> widget_impl = - std::make_unique<MockWidgetImpl>( - widget.InitWithNewPipeAndPassReceiver()); - - return new MockRenderWidgetHostImpl(delegate, process, routing_id, - std::move(widget_impl), - std::move(widget)); + return new MockRenderWidgetHostImpl(delegate, process, routing_id); } ui::LatencyInfo lastWheelOrTouchEventLatencyInfo; - MockWidgetInputHandler* input_handler() { - return widget_impl_->input_handler(); + MockWidgetInputHandler* input_handler() { return &input_handler_; } + + blink::mojom::WidgetInputHandler* GetWidgetInputHandler() override { + return &input_handler_; } void reset_new_content_rendering_timeout_fired() { @@ -388,17 +387,20 @@ class MockRenderWidgetHostImpl : public RenderWidgetHostImpl { private: MockRenderWidgetHostImpl(RenderWidgetHostDelegate* delegate, RenderProcessHost* process, - int32_t routing_id, - std::unique_ptr<MockWidgetImpl> widget_impl, - mojo::PendingRemote<mojom::Widget> widget) + int32_t routing_id) : RenderWidgetHostImpl(delegate, process, routing_id, - std::move(widget), /*hidden=*/false, - std::make_unique<FrameTokenMessageQueue>()), - widget_impl_(std::move(widget_impl)) { + std::make_unique<FrameTokenMessageQueue>()) { lastWheelOrTouchEventLatencyInfo = ui::LatencyInfo(); + mojo::AssociatedRemote<blink::mojom::WidgetHost> blink_widget_host; + mojo::AssociatedRemote<blink::mojom::Widget> blink_widget; + auto blink_widget_receiver = + blink_widget.BindNewEndpointAndPassDedicatedReceiverForTesting(); + BindWidgetInterfaces( + blink_widget_host.BindNewEndpointAndPassDedicatedReceiverForTesting(), + blink_widget.Unbind()); } void NotifyNewContentRenderingTimeoutForTesting() override { @@ -406,7 +408,7 @@ class MockRenderWidgetHostImpl : public RenderWidgetHostImpl { } bool new_content_rendering_timeout_fired_ = false; - std::unique_ptr<MockWidgetImpl> widget_impl_; + MockWidgetInputHandler input_handler_; base::Optional<WebGestureEvent> last_forwarded_gesture_event_; }; @@ -594,13 +596,13 @@ class RenderWidgetHostViewAuraTest : public testing::Test { ->GetTextInputManager(); if (manager->GetActiveWidget()) { manager->active_view_for_testing()->TextInputStateChanged( - TextInputState()); + ui::mojom::TextInputState()); } if (!view) return; - TextInputState state_with_type_text; + ui::mojom::TextInputState state_with_type_text; state_with_type_text.type = type; state_with_type_text.show_ime_if_needed = true; view->TextInputStateChanged(state_with_type_text); @@ -655,7 +657,7 @@ class RenderWidgetHostViewAuraOverscrollTest MockWidgetInputHandler::DispatchedEventMessage* event = messages[i]->ToEvent(); if (event && - event->Event()->web_event->GetType() == + event->Event()->Event().GetType() == WebInputEvent::Type::kGestureScrollUpdate && event->HasCallback()) { event->CallCallback(ack_result); @@ -672,7 +674,7 @@ class RenderWidgetHostViewAuraOverscrollTest MockWidgetInputHandler::DispatchedEventMessage* event = messages[i]->ToEvent(); // GSB events are blocking, send the ack. - if (event && event->Event()->web_event->GetType() == + if (event && event->Event()->Event().GetType() == WebInputEvent::Type::kGestureScrollBegin) { event->CallCallback(ack_result); return; @@ -719,14 +721,15 @@ class RenderWidgetHostViewAuraOverscrollTest // TODO(jdduke): Simulate ui::Events, injecting through the view. void SimulateMouseEvent(WebInputEvent::Type type) { - widget_host_->ForwardMouseEvent(SyntheticWebMouseEventBuilder::Build(type)); + widget_host_->ForwardMouseEvent( + blink::SyntheticWebMouseEventBuilder::Build(type)); base::RunLoop().RunUntilIdle(); } void SimulateMouseEventWithLatencyInfo(WebInputEvent::Type type, const ui::LatencyInfo& ui_latency) { widget_host_->ForwardMouseEventWithLatencyInfo( - SyntheticWebMouseEventBuilder::Build(type), ui_latency); + blink::SyntheticWebMouseEventBuilder::Build(type), ui_latency); base::RunLoop().RunUntilIdle(); } @@ -735,10 +738,11 @@ class RenderWidgetHostViewAuraOverscrollTest int modifiers, bool precise, WebMouseWheelEvent::Phase phase) { - WebMouseWheelEvent wheel_event = SyntheticWebMouseWheelEventBuilder::Build( - 0, 0, dX, dY, modifiers, - precise ? ui::ScrollGranularity::kScrollByPrecisePixel - : ui::ScrollGranularity::kScrollByPixel); + WebMouseWheelEvent wheel_event = + blink::SyntheticWebMouseWheelEventBuilder::Build( + 0, 0, dX, dY, modifiers, + precise ? ui::ScrollGranularity::kScrollByPrecisePixel + : ui::ScrollGranularity::kScrollByPixel); wheel_event.phase = phase; widget_host_->ForwardWheelEvent(wheel_event); base::RunLoop().RunUntilIdle(); @@ -754,7 +758,7 @@ class RenderWidgetHostViewAuraOverscrollTest int modifiers, bool pressed) { WebMouseEvent event = - SyntheticWebMouseEventBuilder::Build(type, x, y, modifiers); + blink::SyntheticWebMouseEventBuilder::Build(type, x, y, modifiers); if (pressed) event.button = WebMouseEvent::Button::kLeft; widget_host_->ForwardMouseEvent(event); @@ -778,35 +782,38 @@ class RenderWidgetHostViewAuraOverscrollTest void SimulateGestureEvent(WebInputEvent::Type type, blink::WebGestureDevice sourceDevice) { SimulateGestureEventCore( - SyntheticWebGestureEventBuilder::Build(type, sourceDevice)); + blink::SyntheticWebGestureEventBuilder::Build(type, sourceDevice)); } void SimulateGestureEventWithLatencyInfo(WebInputEvent::Type type, blink::WebGestureDevice sourceDevice, const ui::LatencyInfo& ui_latency) { SimulateGestureEventCoreWithLatencyInfo( - SyntheticWebGestureEventBuilder::Build(type, sourceDevice), ui_latency); + blink::SyntheticWebGestureEventBuilder::Build(type, sourceDevice), + ui_latency); } void SimulateGestureScrollUpdateEvent(float dX, float dY, int modifiers) { - SimulateGestureEventCore(SyntheticWebGestureEventBuilder::BuildScrollUpdate( - dX, dY, modifiers, blink::WebGestureDevice::kTouchscreen)); + SimulateGestureEventCore( + blink::SyntheticWebGestureEventBuilder::BuildScrollUpdate( + dX, dY, modifiers, blink::WebGestureDevice::kTouchscreen)); } void SimulateGesturePinchUpdateEvent(float scale, float anchorX, float anchorY, int modifiers) { - SimulateGestureEventCore(SyntheticWebGestureEventBuilder::BuildPinchUpdate( - scale, anchorX, anchorY, modifiers, - blink::WebGestureDevice::kTouchscreen)); + SimulateGestureEventCore( + blink::SyntheticWebGestureEventBuilder::BuildPinchUpdate( + scale, anchorX, anchorY, modifiers, + blink::WebGestureDevice::kTouchscreen)); } // Inject synthetic GestureFlingStart events. void SimulateGestureFlingStartEvent(float velocityX, float velocityY, blink::WebGestureDevice sourceDevice) { - SimulateGestureEventCore(SyntheticWebGestureEventBuilder::BuildFling( + SimulateGestureEventCore(blink::SyntheticWebGestureEventBuilder::BuildFling( velocityX, velocityY, sourceDevice)); } @@ -938,7 +945,7 @@ class RenderWidgetHostViewAuraOverscrollTest // GestureScrollUpdate since the ack for the wheel event is non-blocking. EXPECT_TRUE(events[0]->ToEvent()); EXPECT_EQ(WebInputEvent::Type::kMouseWheel, - events[0]->ToEvent()->Event()->web_event->GetType()); + events[0]->ToEvent()->Event()->Event().GetType()); gesture_scroll_update_index = 1; } EXPECT_EQ(gesture_scroll_update_index + 1, events.size()); @@ -947,11 +954,12 @@ class RenderWidgetHostViewAuraOverscrollTest events[gesture_scroll_update_index] ->ToEvent() ->Event() - ->web_event->GetType()); + ->Event() + .GetType()); return events; } - SyntheticWebTouchEvent touch_event_; + blink::SyntheticWebTouchEvent touch_event_; std::unique_ptr<TestOverscrollDelegate> overscroll_delegate_; @@ -1497,7 +1505,7 @@ TEST_F(RenderWidgetHostViewAuraTest, ASSERT_FALSE(events.empty()); const blink::WebKeyboardEvent* blink_key_event1 = static_cast<const blink::WebKeyboardEvent*>( - events[0]->ToEvent()->Event()->web_event.get()); + &events[0]->ToEvent()->Event()->Event()); ASSERT_TRUE(blink_key_event1); ASSERT_EQ(key_event1.key_code(), blink_key_event1->windows_key_code); ASSERT_EQ(ui::KeycodeConverter::DomCodeToNativeKeycode(key_event1.code()), @@ -1589,7 +1597,7 @@ TEST_F(RenderWidgetHostViewAuraTest, << ui::KeycodeConverter::DomCodeToCodeString(dom_code); const blink::WebKeyboardEvent* blink_key_event = static_cast<const blink::WebKeyboardEvent*>( - events[0]->ToEvent()->Event()->web_event.get()); + &events[0]->ToEvent()->Event()->Event()); ASSERT_TRUE(blink_key_event) << "Failed for DomCode: " << ui::KeycodeConverter::DomCodeToCodeString(dom_code); @@ -1692,21 +1700,21 @@ TEST_F(RenderWidgetHostViewAuraTest, TimerBasedWheelEventPhaseInfo) { EXPECT_TRUE(events[0]->ToEvent()); const WebMouseWheelEvent* wheel_event = static_cast<const WebMouseWheelEvent*>( - events[0]->ToEvent()->Event()->web_event.get()); + &events[0]->ToEvent()->Event()->Event()); EXPECT_EQ(WebMouseWheelEvent::kPhaseBegan, wheel_event->phase); events[0]->ToEvent()->CallCallback( blink::mojom::InputEventResultState::kNotConsumed); events = GetAndResetDispatchedMessages(); const WebGestureEvent* gesture_event = static_cast<const WebGestureEvent*>( - events[0]->ToEvent()->Event()->web_event.get()); + &events[0]->ToEvent()->Event()->Event()); EXPECT_EQ(WebInputEvent::Type::kGestureScrollBegin, gesture_event->GetType()); EXPECT_TRUE(gesture_event->data.scroll_begin.synthetic); events[0]->ToEvent()->CallCallback( blink::mojom::InputEventResultState::kConsumed); gesture_event = static_cast<const WebGestureEvent*>( - events[1]->ToEvent()->Event()->web_event.get()); + &events[1]->ToEvent()->Event()->Event()); EXPECT_EQ(WebInputEvent::Type::kGestureScrollUpdate, gesture_event->GetType()); EXPECT_EQ(0U, gesture_event->data.scroll_update.delta_x); @@ -1722,12 +1730,12 @@ TEST_F(RenderWidgetHostViewAuraTest, TimerBasedWheelEventPhaseInfo) { base::RunLoop().RunUntilIdle(); events = GetAndResetDispatchedMessages(); wheel_event = static_cast<const WebMouseWheelEvent*>( - events[0]->ToEvent()->Event()->web_event.get()); + &events[0]->ToEvent()->Event()->Event()); base::TimeTicks wheel_event_timestamp = wheel_event->TimeStamp(); EXPECT_EQ(WebMouseWheelEvent::kPhaseChanged, wheel_event->phase); gesture_event = static_cast<const WebGestureEvent*>( - events[1]->ToEvent()->Event()->web_event.get()); + &events[1]->ToEvent()->Event()->Event()); EXPECT_EQ(WebInputEvent::Type::kGestureScrollUpdate, gesture_event->GetType()); EXPECT_EQ(0U, gesture_event->data.scroll_update.delta_x); @@ -1743,7 +1751,7 @@ TEST_F(RenderWidgetHostViewAuraTest, TimerBasedWheelEventPhaseInfo) { events = GetAndResetDispatchedMessages(); const WebMouseWheelEvent* wheel_end_event = static_cast<const WebMouseWheelEvent*>( - events[0]->ToEvent()->Event()->web_event.get()); + &events[0]->ToEvent()->Event()->Event()); EXPECT_EQ(WebMouseWheelEvent::kPhaseEnded, wheel_end_event->phase); EXPECT_EQ(0U, wheel_end_event->delta_x); EXPECT_EQ(0U, wheel_end_event->delta_y); @@ -1752,7 +1760,7 @@ TEST_F(RenderWidgetHostViewAuraTest, TimerBasedWheelEventPhaseInfo) { EXPECT_GT(wheel_end_event->TimeStamp(), wheel_event_timestamp); gesture_event = static_cast<const WebGestureEvent*>( - events[1]->ToEvent()->Event()->web_event.get()); + &events[1]->ToEvent()->Event()->Event()); EXPECT_EQ(WebInputEvent::Type::kGestureScrollEnd, gesture_event->GetType()); EXPECT_TRUE(gesture_event->data.scroll_end.synthetic); } @@ -1781,7 +1789,7 @@ TEST_F(RenderWidgetHostViewAuraTest, TimerBasedLatchingBreaksWithMouseMove) { EXPECT_TRUE(events[0]->ToEvent()); const WebMouseWheelEvent* wheel_event = static_cast<const WebMouseWheelEvent*>( - events[0]->ToEvent()->Event()->web_event.get()); + &events[0]->ToEvent()->Event()->Event()); EXPECT_EQ(WebMouseWheelEvent::kPhaseBegan, wheel_event->phase); events[0]->ToEvent()->CallCallback( blink::mojom::InputEventResultState::kNotConsumed); @@ -1800,7 +1808,7 @@ TEST_F(RenderWidgetHostViewAuraTest, TimerBasedLatchingBreaksWithMouseMove) { EXPECT_EQ("MouseWheel GestureScrollUpdate", GetMessageNames(events)); wheel_event = static_cast<const WebMouseWheelEvent*>( - events[0]->ToEvent()->Event()->web_event.get()); + &events[0]->ToEvent()->Event()->Event()); EXPECT_EQ(WebMouseWheelEvent::kPhaseChanged, wheel_event->phase); events = GetAndResetDispatchedMessages(); @@ -1815,11 +1823,11 @@ TEST_F(RenderWidgetHostViewAuraTest, TimerBasedLatchingBreaksWithMouseMove) { events = GetAndResetDispatchedMessages(); EXPECT_EQ("MouseWheel GestureScrollEnd MouseWheel", GetMessageNames(events)); wheel_event = static_cast<const WebMouseWheelEvent*>( - events[0]->ToEvent()->Event()->web_event.get()); + &events[0]->ToEvent()->Event()->Event()); EXPECT_EQ(WebMouseWheelEvent::kPhaseEnded, wheel_event->phase); wheel_event = static_cast<const WebMouseWheelEvent*>( - events[2]->ToEvent()->Event()->web_event.get()); + &events[2]->ToEvent()->Event()->Event()); EXPECT_EQ(WebMouseWheelEvent::kPhaseBegan, wheel_event->phase); } @@ -1847,7 +1855,7 @@ TEST_F(RenderWidgetHostViewAuraTest, EXPECT_TRUE(events[0]->ToEvent()); const WebMouseWheelEvent* wheel_event = static_cast<const WebMouseWheelEvent*>( - events[0]->ToEvent()->Event()->web_event.get()); + &events[0]->ToEvent()->Event()->Event()); EXPECT_EQ(WebMouseWheelEvent::kPhaseBegan, wheel_event->phase); events[0]->ToEvent()->CallCallback( blink::mojom::InputEventResultState::kNotConsumed); @@ -1863,7 +1871,7 @@ TEST_F(RenderWidgetHostViewAuraTest, EXPECT_EQ("MouseWheel GestureScrollUpdate", GetMessageNames(events)); wheel_event = static_cast<const WebMouseWheelEvent*>( - events[0]->ToEvent()->Event()->web_event.get()); + &events[0]->ToEvent()->Event()->Event()); EXPECT_EQ(WebMouseWheelEvent::kPhaseChanged, wheel_event->phase); events = GetAndResetDispatchedMessages(); @@ -1877,11 +1885,11 @@ TEST_F(RenderWidgetHostViewAuraTest, events = GetAndResetDispatchedMessages(); EXPECT_EQ("MouseWheel GestureScrollEnd MouseWheel", GetMessageNames(events)); wheel_event = static_cast<const WebMouseWheelEvent*>( - events[0]->ToEvent()->Event()->web_event.get()); + &events[0]->ToEvent()->Event()->Event()); EXPECT_EQ(WebMouseWheelEvent::kPhaseEnded, wheel_event->phase); wheel_event = static_cast<const WebMouseWheelEvent*>( - events[2]->ToEvent()->Event()->web_event.get()); + &events[2]->ToEvent()->Event()->Event()); EXPECT_EQ(WebMouseWheelEvent::kPhaseBegan, wheel_event->phase); } @@ -1910,7 +1918,7 @@ TEST_F(RenderWidgetHostViewAuraTest, EXPECT_TRUE(events[0]->ToEvent()); const WebMouseWheelEvent* wheel_event = static_cast<const WebMouseWheelEvent*>( - events[0]->ToEvent()->Event()->web_event.get()); + &events[0]->ToEvent()->Event()->Event()); EXPECT_EQ(WebMouseWheelEvent::kPhaseBegan, wheel_event->phase); events[0]->ToEvent()->CallCallback( blink::mojom::InputEventResultState::kNotConsumed); @@ -1935,11 +1943,11 @@ TEST_F(RenderWidgetHostViewAuraTest, events = GetAndResetDispatchedMessages(); EXPECT_EQ("MouseWheel GestureScrollEnd MouseWheel", GetMessageNames(events)); wheel_event = static_cast<const WebMouseWheelEvent*>( - events[0]->ToEvent()->Event()->web_event.get()); + &events[0]->ToEvent()->Event()->Event()); EXPECT_EQ(WebMouseWheelEvent::kPhaseEnded, wheel_event->phase); wheel_event = static_cast<const WebMouseWheelEvent*>( - events[2]->ToEvent()->Event()->web_event.get()); + &events[2]->ToEvent()->Event()->Event()); EXPECT_EQ(WebMouseWheelEvent::kPhaseBegan, wheel_event->phase); } @@ -1964,7 +1972,7 @@ TEST_F(RenderWidgetHostViewAuraTest, EXPECT_TRUE(events[0]->ToEvent()); const WebMouseWheelEvent* wheel_event = static_cast<const WebMouseWheelEvent*>( - events[0]->ToEvent()->Event()->web_event.get()); + &events[0]->ToEvent()->Event()->Event()); EXPECT_EQ(WebMouseWheelEvent::kPhaseBegan, wheel_event->phase); events[0]->ToEvent()->CallCallback( blink::mojom::InputEventResultState::kNotConsumed); @@ -1985,11 +1993,11 @@ TEST_F(RenderWidgetHostViewAuraTest, EXPECT_EQ("MouseWheel GestureScrollEnd MouseWheel", GetMessageNames(events)); EXPECT_TRUE(events[0]->ToEvent()); wheel_event = static_cast<const WebMouseWheelEvent*>( - events[0]->ToEvent()->Event()->web_event.get()); + &events[0]->ToEvent()->Event()->Event()); EXPECT_EQ(WebMouseWheelEvent::kPhaseEnded, wheel_event->phase); EXPECT_TRUE(events[2]->ToEvent()); wheel_event = static_cast<const WebMouseWheelEvent*>( - events[2]->ToEvent()->Event()->web_event.get()); + &events[2]->ToEvent()->Event()->Event()); EXPECT_EQ(WebMouseWheelEvent::kPhaseBegan, wheel_event->phase); } @@ -2020,7 +2028,7 @@ TEST_F(RenderWidgetHostViewAuraTest, TouchpadFlingStartResetsWheelPhaseState) { const WebMouseWheelEvent* wheel_event = static_cast<const WebMouseWheelEvent*>( - events[0]->ToEvent()->Event()->web_event.get()); + &events[0]->ToEvent()->Event()->Event()); EXPECT_EQ("MouseWheel", GetMessageNames(events)); EXPECT_EQ(WebMouseWheelEvent::kPhaseBegan, wheel_event->phase); events[0]->ToEvent()->CallCallback( @@ -2029,13 +2037,13 @@ TEST_F(RenderWidgetHostViewAuraTest, TouchpadFlingStartResetsWheelPhaseState) { events = GetAndResetDispatchedMessages(); EXPECT_EQ("GestureScrollBegin GestureScrollUpdate", GetMessageNames(events)); const WebGestureEvent* gesture_event = static_cast<const WebGestureEvent*>( - events[0]->ToEvent()->Event()->web_event.get()); + &events[0]->ToEvent()->Event()->Event()); EXPECT_EQ(WebInputEvent::Type::kGestureScrollBegin, gesture_event->GetType()); events[0]->ToEvent()->CallCallback( blink::mojom::InputEventResultState::kConsumed); gesture_event = static_cast<const WebGestureEvent*>( - events[1]->ToEvent()->Event()->web_event.get()); + &events[1]->ToEvent()->Event()->Event()); EXPECT_EQ(WebInputEvent::Type::kGestureScrollUpdate, gesture_event->GetType()); EXPECT_EQ(0U, gesture_event->data.scroll_update.delta_x); @@ -2057,11 +2065,11 @@ TEST_F(RenderWidgetHostViewAuraTest, TouchpadFlingStartResetsWheelPhaseState) { events = GetAndResetDispatchedMessages(); EXPECT_EQ(2U, events.size()); wheel_event = static_cast<const WebMouseWheelEvent*>( - events[0]->ToEvent()->Event()->web_event.get()); + &events[0]->ToEvent()->Event()->Event()); EXPECT_EQ(WebMouseWheelEvent::kPhaseChanged, wheel_event->phase); EXPECT_EQ("MouseWheel GestureScrollUpdate", GetMessageNames(events)); gesture_event = static_cast<const WebGestureEvent*>( - events[1]->ToEvent()->Event()->web_event.get()); + &events[1]->ToEvent()->Event()->Event()); events[1]->ToEvent()->CallCallback( blink::mojom::InputEventResultState::kConsumed); EXPECT_EQ(WebInputEvent::Type::kGestureScrollUpdate, @@ -2099,10 +2107,10 @@ TEST_F(RenderWidgetHostViewAuraTest, TouchpadFlingStartResetsWheelPhaseState) { events = GetAndResetDispatchedMessages(); EXPECT_EQ("MouseWheel GestureScrollEnd MouseWheel", GetMessageNames(events)); wheel_event = static_cast<const WebMouseWheelEvent*>( - events[0]->ToEvent()->Event()->web_event.get()); + &events[0]->ToEvent()->Event()->Event()); EXPECT_EQ(WebMouseWheelEvent::kPhaseEnded, wheel_event->momentum_phase); wheel_event = static_cast<const WebMouseWheelEvent*>( - events[2]->ToEvent()->Event()->web_event.get()); + &events[2]->ToEvent()->Event()->Event()); EXPECT_EQ(WebMouseWheelEvent::kPhaseBegan, wheel_event->phase); } @@ -2149,7 +2157,7 @@ TEST_F(RenderWidgetHostViewAuraTest, MouseWheelScrollingAfterGFCWithoutGFS) { GetAndResetDispatchedMessages(); const WebMouseWheelEvent* wheel_event = static_cast<const WebMouseWheelEvent*>( - events[0]->ToEvent()->Event()->web_event.get()); + &events[0]->ToEvent()->Event()->Event()); EXPECT_EQ("MouseWheel", GetMessageNames(events)); EXPECT_EQ(WebMouseWheelEvent::kPhaseBegan, wheel_event->phase); @@ -2188,7 +2196,7 @@ TEST_F(RenderWidgetHostViewAuraTest, const WebMouseWheelEvent* wheel_event = static_cast<const WebMouseWheelEvent*>( - events[0]->ToEvent()->Event()->web_event.get()); + &events[0]->ToEvent()->Event()->Event()); EXPECT_EQ("MouseWheel", GetMessageNames(events)); EXPECT_EQ(WebMouseWheelEvent::kPhaseBegan, wheel_event->phase); events[0]->ToEvent()->CallCallback( @@ -2202,12 +2210,12 @@ TEST_F(RenderWidgetHostViewAuraTest, events = GetAndResetDispatchedMessages(); EXPECT_EQ("GestureScrollBegin GestureScrollUpdate", GetMessageNames(events)); const WebGestureEvent* gesture_event = static_cast<const WebGestureEvent*>( - events[0]->ToEvent()->Event()->web_event.get()); + &events[0]->ToEvent()->Event()->Event()); EXPECT_EQ(WebInputEvent::Type::kGestureScrollBegin, gesture_event->GetType()); events[0]->ToEvent()->CallCallback( blink::mojom::InputEventResultState::kConsumed); gesture_event = static_cast<const WebGestureEvent*>( - events[1]->ToEvent()->Event()->web_event.get()); + &events[1]->ToEvent()->Event()->Event()); EXPECT_EQ(WebInputEvent::Type::kGestureScrollUpdate, gesture_event->GetType()); events[1]->ToEvent()->CallCallback( @@ -2224,11 +2232,11 @@ TEST_F(RenderWidgetHostViewAuraTest, EXPECT_EQ("MouseWheel GestureScrollEnd MouseWheel", GetMessageNames(events)); EXPECT_TRUE(events[0]->ToEvent()); wheel_event = static_cast<const WebMouseWheelEvent*>( - events[0]->ToEvent()->Event()->web_event.get()); + &events[0]->ToEvent()->Event()->Event()); EXPECT_EQ(WebMouseWheelEvent::kPhaseEnded, wheel_event->phase); EXPECT_TRUE(events[2]->ToEvent()); wheel_event = static_cast<const WebMouseWheelEvent*>( - events[2]->ToEvent()->Event()->web_event.get()); + &events[2]->ToEvent()->Event()->Event()); EXPECT_EQ(WebMouseWheelEvent::kPhaseBegan, wheel_event->phase); // The mouse_wheel_phase_handler's timer will be running during mouse wheel @@ -2253,7 +2261,7 @@ TEST_F(RenderWidgetHostViewAuraTest, EXPECT_EQ("MouseWheel", GetMessageNames(events)); const WebMouseWheelEvent* wheel_event = static_cast<const WebMouseWheelEvent*>( - events[0]->ToEvent()->Event()->web_event.get()); + &events[0]->ToEvent()->Event()->Event()); EXPECT_EQ(WebMouseWheelEvent::kPhaseBegan, wheel_event->phase); events[0]->ToEvent()->CallCallback( blink::mojom::InputEventResultState::kNotConsumed); @@ -2261,12 +2269,12 @@ TEST_F(RenderWidgetHostViewAuraTest, events = GetAndResetDispatchedMessages(); EXPECT_EQ("GestureScrollBegin GestureScrollUpdate", GetMessageNames(events)); const WebGestureEvent* gesture_event = static_cast<const WebGestureEvent*>( - events[0]->ToEvent()->Event()->web_event.get()); + &events[0]->ToEvent()->Event()->Event()); events[0]->ToEvent()->CallCallback( blink::mojom::InputEventResultState::kConsumed); gesture_event = static_cast<const WebGestureEvent*>( - events[1]->ToEvent()->Event()->web_event.get()); + &events[1]->ToEvent()->Event()->Event()); EXPECT_EQ(0U, gesture_event->data.scroll_update.delta_x); EXPECT_EQ(5U, gesture_event->data.scroll_update.delta_y); events[1]->ToEvent()->CallCallback( @@ -2294,18 +2302,18 @@ TEST_F(RenderWidgetHostViewAuraTest, EXPECT_EQ(3U, events.size()); wheel_event = static_cast<const WebMouseWheelEvent*>( - events[0]->ToEvent()->Event()->web_event.get()); + &events[0]->ToEvent()->Event()->Event()); EXPECT_EQ(WebMouseWheelEvent::kPhaseEnded, wheel_event->phase); EXPECT_EQ(0U, wheel_event->delta_x); EXPECT_EQ(0U, wheel_event->delta_y); gesture_event = static_cast<const WebGestureEvent*>( - events[1]->ToEvent()->Event()->web_event.get()); + &events[1]->ToEvent()->Event()->Event()); EXPECT_EQ(WebInputEvent::Type::kGestureScrollEnd, gesture_event->GetType()); EXPECT_EQ(blink::WebGestureDevice::kTouchpad, gesture_event->SourceDevice()); gesture_event = static_cast<const WebGestureEvent*>( - events[2]->ToEvent()->Event()->web_event.get()); + &events[2]->ToEvent()->Event()->Event()); EXPECT_EQ(WebInputEvent::Type::kGestureScrollBegin, gesture_event->GetType()); EXPECT_EQ(blink::WebGestureDevice::kTouchscreen, gesture_event->SourceDevice()); @@ -3818,15 +3826,14 @@ TEST_F(RenderWidgetHostViewAuraOverscrollTest, events = GetAndResetDispatchedMessages(); for (const auto& event : events) { EXPECT_NE(WebInputEvent::Type::kGestureFlingStart, - event->ToEvent()->Event()->web_event->GetType()); + event->ToEvent()->Event()->Event().GetType()); } // Fling controller handles the GFS with touchpad source and zero velocity and // sends a nonblocking wheel end event. The GSE generated from wheel end event // resets scroll state. - EXPECT_EQ( - WebInputEvent::Type::kGestureScrollEnd, - events[events.size() - 1]->ToEvent()->Event()->web_event->GetType()); + EXPECT_EQ(WebInputEvent::Type::kGestureScrollEnd, + events[events.size() - 1]->ToEvent()->Event()->Event().GetType()); EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode()); EXPECT_EQ(OverscrollSource::NONE, overscroll_source()); @@ -3835,7 +3842,7 @@ TEST_F(RenderWidgetHostViewAuraOverscrollTest, // Tests that a fling in the opposite direction of the overscroll cancels the // overscroll instead of completing it. // Flaky on Fuchsia: http://crbug.com/810690. -#if defined(OS_FUCHSIA) +#if defined(OS_FUCHSIA) || defined(OS_LINUX) #define MAYBE_ReverseFlingCancelsOverscroll \ DISABLED_ReverseFlingCancelsOverscroll #else @@ -4758,15 +4765,14 @@ TEST_F(RenderWidgetHostViewAuraOverscrollTest, events = GetAndResetDispatchedMessages(); for (const auto& event : events) { EXPECT_NE(WebInputEvent::Type::kGestureFlingStart, - event->ToEvent()->Event()->web_event->GetType()); + event->ToEvent()->Event()->Event().GetType()); } // Fling controller handles a GFS with touchpad source and zero velocity and // sends a nonblocking wheel end event. The GSE generated from wheel end event // resets scroll state. - EXPECT_EQ( - WebInputEvent::Type::kGestureScrollEnd, - events[events.size() - 1]->ToEvent()->Event()->web_event->GetType()); + EXPECT_EQ(WebInputEvent::Type::kGestureScrollEnd, + events[events.size() - 1]->ToEvent()->Event()->Event().GetType()); EXPECT_TRUE(ScrollStateIsUnknown()); // Dropped flings should neither propagate *nor* indicate that they were @@ -4805,15 +4811,14 @@ TEST_F(RenderWidgetHostViewAuraOverscrollTest, for (const auto& event : events) { EXPECT_NE(WebInputEvent::Type::kGestureFlingStart, - event->ToEvent()->Event()->web_event->GetType()); + event->ToEvent()->Event()->Event().GetType()); } // Fling controller handles a GFS with touchpad source and zero velocity and // sends a nonblocking wheel end event. The GSE generated from wheel end event // resets scroll state. - EXPECT_EQ( - WebInputEvent::Type::kGestureScrollEnd, - events[events.size() - 1]->ToEvent()->Event()->web_event->GetType()); + EXPECT_EQ(WebInputEvent::Type::kGestureScrollEnd, + events[events.size() - 1]->ToEvent()->Event()->Event().GetType()); EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode()); EXPECT_EQ(OverscrollSource::NONE, overscroll_source()); @@ -4920,7 +4925,7 @@ TEST_F(RenderWidgetHostViewAuraTest, VirtualKeyboardFocusEnsureCaretInRect) { EXPECT_EQ(view_->GetNativeView()->bounds(), shifted_view_bounds); // Detach the RenderWidgetHostViewAura from the IME. - view_->DetachFromInputMethod(); + view_->DetachFromInputMethod(false); // Window should be restored. EXPECT_EQ(view_->GetNativeView()->bounds(), orig_view_bounds); @@ -5015,7 +5020,7 @@ TEST_F(RenderWidgetHostViewAuraTest, SetCanScrollForWebMouseWheelEvent) { GetAndResetDispatchedMessages(); const WebMouseWheelEvent* wheel_event = static_cast<const WebMouseWheelEvent*>( - events[0]->ToEvent()->Event()->web_event.get()); + &events[0]->ToEvent()->Event()->Event()); // Check if scroll is caused when ctrl-scroll is generated from // mouse wheel event. EXPECT_EQ(blink::WebMouseWheelEvent::EventAction::kPageZoom, @@ -5037,13 +5042,13 @@ TEST_F(RenderWidgetHostViewAuraTest, SetCanScrollForWebMouseWheelEvent) { // dispatching the wheel event. EXPECT_EQ(2u, events.size()); wheel_event = static_cast<const WebMouseWheelEvent*>( - events[0]->ToEvent()->Event()->web_event.get()); + &events[0]->ToEvent()->Event()->Event()); EXPECT_EQ(WebMouseWheelEvent::kPhaseEnded, wheel_event->phase); // Check if scroll is caused when no modifier is applied to the // mouse wheel event. wheel_event = static_cast<const WebMouseWheelEvent*>( - events[1]->ToEvent()->Event()->web_event.get()); + &events[1]->ToEvent()->Event()->Event()); EXPECT_NE(blink::WebMouseWheelEvent::EventAction::kPageZoom, wheel_event->event_action); @@ -5061,12 +5066,12 @@ TEST_F(RenderWidgetHostViewAuraTest, SetCanScrollForWebMouseWheelEvent) { // dispatching the wheel event. EXPECT_EQ(2u, events.size()); wheel_event = static_cast<const WebMouseWheelEvent*>( - events[0]->ToEvent()->Event()->web_event.get()); + &events[0]->ToEvent()->Event()->Event()); EXPECT_EQ(WebMouseWheelEvent::kPhaseEnded, wheel_event->phase); // Check if scroll is caused when ctrl-touchpad-scroll is generated // from scroll event. wheel_event = static_cast<const WebMouseWheelEvent*>( - events[1]->ToEvent()->Event()->web_event.get()); + &events[1]->ToEvent()->Event()->Event()); EXPECT_NE(blink::WebMouseWheelEvent::EventAction::kPageZoom, wheel_event->event_action); } @@ -5344,7 +5349,7 @@ TEST_F(RenderWidgetHostViewAuraTest, const WebMouseWheelEvent* wheel_event = static_cast<const WebMouseWheelEvent*>( - events[4]->ToEvent()->Event()->web_event.get()); + &events[4]->ToEvent()->Event()->Event()); EXPECT_EQ(blink::WebMouseWheelEvent::kPhaseBlocked, wheel_event->momentum_phase); @@ -5402,7 +5407,7 @@ TEST_F(RenderWidgetHostViewAuraTest, GestureTapFromStylusHasPointerType) { EXPECT_EQ("GestureTapDown GestureShowPress GestureTap", GetMessageNames(events)); const WebGestureEvent* gesture_event = static_cast<const WebGestureEvent*>( - events[2]->ToEvent()->Event()->web_event.get()); + &events[2]->ToEvent()->Event()->Event()); EXPECT_EQ(WebInputEvent::Type::kGestureTap, gesture_event->GetType()); EXPECT_EQ(blink::WebPointerProperties::PointerType::kPen, gesture_event->primary_pointer_type); @@ -5953,9 +5958,25 @@ TEST_F(InputMethodResultAuraTest, ChangeTextDirectionAndLayoutAlignment) { base::Unretained(tab_view()), base::i18n::LEFT_TO_RIGHT); for (auto index : active_view_sequence_) { ActivateViewForTextInputManager(views_[index], ui::TEXT_INPUT_TYPE_TEXT); - EXPECT_TRUE(!!RunAndReturnIPCSent(ime_finish_session_call, - processes_[index], - WidgetMsg_SetTextDirection::ID)); + + mojo::AssociatedRemote<blink::mojom::FrameWidgetHost> + blink_frame_widget_host; + auto blink_frame_widget_host_receiver = + blink_frame_widget_host + .BindNewEndpointAndPassDedicatedReceiverForTesting(); + mojo::AssociatedRemote<blink::mojom::FrameWidget> blink_frame_widget; + auto blink_frame_widget_receiver = + blink_frame_widget.BindNewEndpointAndPassDedicatedReceiverForTesting(); + + static_cast<RenderWidgetHostImpl*>(views_[index]->GetRenderWidgetHost()) + ->BindFrameWidgetInterfaces(std::move(blink_frame_widget_host_receiver), + blink_frame_widget.Unbind()); + + FakeFrameWidget fake_frame_widget(std::move(blink_frame_widget_receiver)); + + ime_finish_session_call.Run(); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(fake_frame_widget.GetTextDirection(), base::i18n::LEFT_TO_RIGHT); } } @@ -5990,21 +6011,19 @@ class InputMethodStateAuraTest : public InputMethodAuraTestBase { // This test is for caret bounds which are calculated based on the tracked value // for selection bounds. TEST_F(InputMethodStateAuraTest, GetCaretBounds) { - WidgetHostMsg_SelectionBounds_Params params; - params.is_anchor_first = true; - params.anchor_dir = base::i18n::LEFT_TO_RIGHT; - params.focus_dir = base::i18n::LEFT_TO_RIGHT; - params.anchor_rect = gfx::Rect(0, 0, 10, 10); for (auto index : active_view_sequence_) { ActivateViewForTextInputManager(views_[index], ui::TEXT_INPUT_TYPE_TEXT); - params.focus_rect = gfx::Rect(10 + index, 10 + index, 10, 10); - views_[index]->SelectionBoundsChanged(params); + gfx::Rect anchor_rect = gfx::Rect(0, 0, 10, 10); + gfx::Rect focus_rect = gfx::Rect(10 + index, 10 + index, 10, 10); + views_[index]->SelectionBoundsChanged(anchor_rect, + base::i18n::LEFT_TO_RIGHT, focus_rect, + base::i18n::LEFT_TO_RIGHT, true); // Calculate the bounds. gfx::SelectionBound anchor_bound = GetSelectionBoundFromRect( - TransformRectToViewsRootCoordSpace(params.anchor_rect, views_[index])); + TransformRectToViewsRootCoordSpace(anchor_rect, views_[index])); gfx::SelectionBound focus_bound = GetSelectionBoundFromRect( - TransformRectToViewsRootCoordSpace(params.focus_rect, views_[index])); + TransformRectToViewsRootCoordSpace(focus_rect, views_[index])); anchor_bound.set_type(gfx::SelectionBound::LEFT); focus_bound.set_type(gfx::SelectionBound::RIGHT); gfx::Rect measured_rect = @@ -6061,7 +6080,7 @@ TEST_F(InputMethodStateAuraTest, GetTextRange) { for (auto index : active_view_sequence_) { ActivateViewForTextInputManager(views_[index], ui::TEXT_INPUT_TYPE_TEXT); - TextInputState state; + ui::mojom::TextInputState state; state.type = ui::TEXT_INPUT_TYPE_TEXT; state.value = text; gfx::Range expected_range(0, 22); @@ -6083,10 +6102,9 @@ TEST_F(InputMethodStateAuraTest, GetCompositionTextRange) { for (auto index : active_view_sequence_) { ActivateViewForTextInputManager(views_[index], ui::TEXT_INPUT_TYPE_TEXT); gfx::Range expected_range(1, 2 + index); - TextInputState state; + ui::mojom::TextInputState state; state.type = ui::TEXT_INPUT_TYPE_TEXT; - state.composition_start = expected_range.start(); - state.composition_end = expected_range.end(); + state.composition = expected_range; views_[index]->TextInputStateChanged(state); gfx::Range range_from_client; @@ -6102,10 +6120,9 @@ TEST_F(InputMethodStateAuraTest, GetEditableSelectionRange) { for (auto index : active_view_sequence_) { ActivateViewForTextInputManager(views_[index], ui::TEXT_INPUT_TYPE_TEXT); - TextInputState state_with_selection; + ui::mojom::TextInputState state_with_selection; state_with_selection.type = ui::TEXT_INPUT_TYPE_TEXT; - state_with_selection.selection_start = expected_range.start(); - state_with_selection.selection_end = expected_range.end(); + state_with_selection.selection = expected_range; views_[index]->TextInputStateChanged(state_with_selection); gfx::Range range_from_client; @@ -6125,7 +6142,7 @@ TEST_F(InputMethodStateAuraTest, GetTextFromRange) { for (auto index : active_view_sequence_) { ActivateViewForTextInputManager(views_[index], ui::TEXT_INPUT_TYPE_TEXT); - TextInputState state; + ui::mojom::TextInputState state; state.type = ui::TEXT_INPUT_TYPE_TEXT; state.value = text; views_[index]->TextInputStateChanged(state); @@ -6143,6 +6160,8 @@ TEST_F(InputMethodStateAuraTest, GetTextFromRange) { // This test will verify that after selection, the selected text is written to // the clipboard from the focused widget. TEST_F(InputMethodStateAuraTest, SelectedTextCopiedToClipboard) { + if (features::IsUsingOzonePlatform()) + return; ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread(); EXPECT_TRUE(!!clipboard); std::vector<std::string> texts = {"text0", "text1", "text2", "text3"}; @@ -6323,13 +6342,9 @@ TEST_F(RenderWidgetHostViewAuraInputMethodTest, OnCaretBoundsChanged) { text_input_client_ = nullptr; - WidgetHostMsg_SelectionBounds_Params params; - params.is_anchor_first = true; - params.anchor_dir = base::i18n::LEFT_TO_RIGHT; - params.focus_dir = base::i18n::LEFT_TO_RIGHT; - params.anchor_rect = gfx::Rect(0, 0, 10, 10); - params.focus_rect = gfx::Rect(10, 10, 10, 10); - parent_view_->SelectionBoundsChanged(params); + parent_view_->SelectionBoundsChanged( + gfx::Rect(0, 0, 10, 10), base::i18n::LEFT_TO_RIGHT, + gfx::Rect(10, 10, 10, 10), base::i18n::LEFT_TO_RIGHT, true); EXPECT_EQ(parent_view_, text_input_client_); input_method->RemoveObserver(this); @@ -6418,12 +6433,12 @@ class RenderWidgetHostViewAuraKeyboardTest TEST_F(RenderWidgetHostViewAuraKeyboardTest, KeyboardObserverDestroyed) { parent_view_->SetLastPointerType(ui::EventPointerType::kTouch); ActivateViewForTextInputManager(parent_view_, ui::TEXT_INPUT_TYPE_TEXT); - EXPECT_NE(parent_view_->keyboard_observer_.get(), nullptr); + EXPECT_NE(parent_view_->virtual_keyboard_controller_win_.get(), nullptr); EXPECT_EQ(keyboard_controller_observer_count(), 1u); EXPECT_EQ(IsKeyboardVisible(), true); // Detach the RenderWidgetHostViewAura from the IME. - parent_view_->DetachFromInputMethod(); - EXPECT_EQ(parent_view_->keyboard_observer_.get(), nullptr); + parent_view_->DetachFromInputMethod(true); + EXPECT_EQ(parent_view_->virtual_keyboard_controller_win_.get(), nullptr); EXPECT_EQ(keyboard_controller_observer_count(), 0u); } @@ -6435,7 +6450,6 @@ TEST_F(RenderWidgetHostViewAuraKeyboardTest, NoKeyboardObserverForMouseInput) { // Do not show virtual keyboard for mouse inputs. parent_view_->SetLastPointerType(ui::EventPointerType::kMouse); ActivateViewForTextInputManager(parent_view_, ui::TEXT_INPUT_TYPE_TEXT); - EXPECT_EQ(parent_view_->keyboard_observer_.get(), nullptr); EXPECT_EQ(keyboard_controller_observer_count(), 0u); EXPECT_EQ(IsKeyboardVisible(), false); } @@ -6445,7 +6459,7 @@ TEST_F(RenderWidgetHostViewAuraKeyboardTest, // Show virtual keyboard for touch inputs. parent_view_->SetLastPointerType(ui::EventPointerType::kTouch); ActivateViewForTextInputManager(parent_view_, ui::TEXT_INPUT_TYPE_TEXT); - EXPECT_NE(parent_view_->keyboard_observer_.get(), nullptr); + EXPECT_NE(parent_view_->virtual_keyboard_controller_win_.get(), nullptr); EXPECT_EQ(keyboard_controller_observer_count(), 1u); EXPECT_EQ(IsKeyboardVisible(), true); } @@ -6456,18 +6470,18 @@ TEST_F(RenderWidgetHostViewAuraKeyboardTest, parent_view_->SetLastPointerType(ui::EventPointerType::kTouch); ActivateViewForTextInputManager(parent_view_, ui::TEXT_INPUT_TYPE_TEXT); EXPECT_EQ(IsKeyboardVisible(), true); - EXPECT_NE(parent_view_->keyboard_observer_.get(), nullptr); + EXPECT_NE(parent_view_->virtual_keyboard_controller_win_.get(), nullptr); EXPECT_EQ(keyboard_controller_observer_count(), 1u); // Change the focused node to a read-only node so the keyboard is dismissed, // but the keyboard observer should still be valid. parent_view_->FocusedNodeChanged(false, gfx::Rect()); - EXPECT_NE(parent_view_->keyboard_observer_.get(), nullptr); + EXPECT_NE(parent_view_->virtual_keyboard_controller_win_.get(), nullptr); EXPECT_EQ(keyboard_controller_observer_count(), 1u); EXPECT_EQ(IsKeyboardVisible(), false); // Detaching the input method should destroy the keyboard observer. - parent_view_->DetachFromInputMethod(); - EXPECT_EQ(parent_view_->keyboard_observer_.get(), nullptr); + parent_view_->DetachFromInputMethod(true); + EXPECT_EQ(parent_view_->virtual_keyboard_controller_win_.get(), nullptr); EXPECT_EQ(keyboard_controller_observer_count(), 0u); } @@ -6475,8 +6489,28 @@ TEST_F(RenderWidgetHostViewAuraKeyboardTest, KeyboardObserverForPenInput) { // Show virtual keyboard for pen inputs. parent_view_->SetLastPointerType(ui::EventPointerType::kPen); ActivateViewForTextInputManager(parent_view_, ui::TEXT_INPUT_TYPE_TEXT); - EXPECT_NE(parent_view_->keyboard_observer_.get(), nullptr); + EXPECT_NE(parent_view_->virtual_keyboard_controller_win_.get(), nullptr); + EXPECT_EQ(keyboard_controller_observer_count(), 1u); +} + +TEST_F(RenderWidgetHostViewAuraKeyboardTest, + KeyboardObserverDetachDuringWindowDestroy) { + parent_view_->SetLastPointerType(ui::EventPointerType::kTouch); + ActivateViewForTextInputManager(parent_view_, ui::TEXT_INPUT_TYPE_TEXT); + EXPECT_NE(parent_view_->virtual_keyboard_controller_win_.get(), nullptr); EXPECT_EQ(keyboard_controller_observer_count(), 1u); + EXPECT_EQ(IsKeyboardVisible(), true); + // Detach the RenderWidgetHostViewAura from the IME, but don't destroy the + // Vk controller as it might need to notify about VK hide so the sites can + // reflow their content. + parent_view_->DetachFromInputMethod(false); + EXPECT_EQ(IsKeyboardVisible(), false); + EXPECT_NE(parent_view_->virtual_keyboard_controller_win_.get(), nullptr); + EXPECT_EQ(keyboard_controller_observer_count(), 1u); + // Detach the keyboard observer as the window is getting destroyed. + parent_view_->DetachFromInputMethod(true); + EXPECT_EQ(parent_view_->virtual_keyboard_controller_win_.get(), nullptr); + EXPECT_EQ(keyboard_controller_observer_count(), 0u); } #endif // defined(OS_WIN) diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_aura_vk_browsertest.cc b/chromium/content/browser/renderer_host/render_widget_host_view_aura_vk_browsertest.cc new file mode 100644 index 00000000000..c7efee177cf --- /dev/null +++ b/chromium/content/browser/renderer_host/render_widget_host_view_aura_vk_browsertest.cc @@ -0,0 +1,412 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/observer_list.h" +#include "base/win/windows_version.h" +#include "content/browser/accessibility/browser_accessibility.h" +#include "content/browser/accessibility/browser_accessibility_manager.h" +#include "content/browser/renderer_host/delegated_frame_host.h" +#include "content/browser/renderer_host/render_widget_host_impl.h" +#include "content/browser/renderer_host/render_widget_host_view_aura.h" +#include "content/browser/web_contents/web_contents_impl.h" +#include "content/public/browser/render_frame_host.h" +#include "content/public/browser/render_view_host.h" +#include "content/public/browser/web_contents.h" +#include "content/public/browser/web_contents_delegate.h" +#include "content/public/common/content_switches.h" +#include "content/public/test/accessibility_notification_waiter.h" +#include "content/public/test/browser_test.h" +#include "content/public/test/browser_test_utils.h" +#include "content/public/test/content_browser_test.h" +#include "content/public/test/content_browser_test_utils.h" +#include "content/shell/browser/shell.h" +#include "ui/base/ime/init/input_method_factory.h" +#include "ui/base/ime/input_method_keyboard_controller.h" +#include "ui/base/ime/input_method_keyboard_controller_observer.h" +#include "ui/base/ime/input_method_observer.h" +#include "ui/base/ime/mock_input_method.h" +#include "ui/base/ime/text_input_type.h" + +namespace content { + +class MockKeyboardController : public ui::InputMethodKeyboardController { + public: + bool DisplayVirtualKeyboard() override { + is_keyboard_visible_ = true; + return true; + } + void DismissVirtualKeyboard() override {} + void AddObserver( + ui::InputMethodKeyboardControllerObserver* observer) override { + observers_.AddObserver(observer); + } + void RemoveObserver( + ui::InputMethodKeyboardControllerObserver* observer) override { + observers_.RemoveObserver(observer); + } + + void NotifyObserversOnKeyboardShown(gfx::Rect dip_rect) { + is_keyboard_visible_ = true; + for (ui::InputMethodKeyboardControllerObserver& observer : observers_) + observer.OnKeyboardVisible(dip_rect); + } + + void NotifyObserversOnKeyboardHidden() { + is_keyboard_visible_ = false; + for (ui::InputMethodKeyboardControllerObserver& observer : observers_) + observer.OnKeyboardHidden(); + } + + bool IsKeyboardVisible() override { return is_keyboard_visible_; } + + private: + base::ObserverList<ui::InputMethodKeyboardControllerObserver, + false>::Unchecked observers_; + bool is_keyboard_visible_ = false; +}; + +class InputMethodKeyboardObserver : public ui::InputMethodObserver { + public: + // ui::InputMethodObserver: + void OnFocus() override {} + void OnBlur() override {} + void OnInputMethodDestroyed(const ui::InputMethod* input_method) override {} + void OnShowVirtualKeyboardIfEnabled() override { + is_keyboard_display_called_ = true; + } + void OnTextInputStateChanged(const ui::TextInputClient* client) override {} + void OnCaretBoundsChanged(const ui::TextInputClient* client) override {} + bool IsKeyboardDisplayCalled() { return is_keyboard_display_called_; } + + private: + bool is_keyboard_display_called_ = false; +}; + +class KeyboardControllerMockInputMethod : public ui::MockInputMethod { + public: + KeyboardControllerMockInputMethod() : ui::MockInputMethod(nullptr) {} + ui::InputMethodKeyboardController* GetInputMethodKeyboardController() + override { + return &mock_keyboard_controller_; + } + + MockKeyboardController* GetMockKeyboardController() { + return &mock_keyboard_controller_; + } + + private: + MockKeyboardController mock_keyboard_controller_; +}; + +class RenderWidgetHostViewAuraBrowserMockIMETest : public ContentBrowserTest { + public: + void SetUp() override { + input_method_ = new KeyboardControllerMockInputMethod; + mock_keyboard_observer_ = new InputMethodKeyboardObserver; + input_method_->AddObserver(mock_keyboard_observer_); + // transfers ownership. + ui::SetUpInputMethodForTesting(input_method_); + ContentBrowserTest::SetUp(); + } + + void SetUpCommandLine(base::CommandLine* command_line) override { + command_line->AppendSwitchASCII(switches::kEnableBlinkFeatures, + "VirtualKeyboard"); + ContentBrowserTest::SetUpCommandLine(command_line); + } + + RenderViewHost* GetRenderViewHost() const { + RenderViewHost* const rvh = shell()->web_contents()->GetRenderViewHost(); + CHECK(rvh); + return rvh; + } + + RenderWidgetHostViewAura* GetRenderWidgetHostView() const { + return static_cast<RenderWidgetHostViewAura*>( + GetRenderViewHost()->GetWidget()->GetView()); + } + + BrowserAccessibility* FindNode(ax::mojom::Role role, + const std::string& name_or_value) { + BrowserAccessibility* root = GetManager()->GetRoot(); + CHECK(root); + return FindNodeInSubtree(*root, role, name_or_value); + } + + BrowserAccessibilityManager* GetManager() { + WebContentsImpl* web_contents = + static_cast<WebContentsImpl*>(shell()->web_contents()); + return web_contents->GetRootBrowserAccessibilityManager(); + } + + void LoadInitialAccessibilityTreeFromHtml(const std::string& html) { + AccessibilityNotificationWaiter waiter(shell()->web_contents(), + ui::kAXModeComplete, + ax::mojom::Event::kLoadComplete); + GURL html_data_url("data:text/html," + html); + EXPECT_TRUE(NavigateToURL(shell(), html_data_url)); + waiter.WaitForNotification(); + } + + protected: + KeyboardControllerMockInputMethod* input_method_ = nullptr; + InputMethodKeyboardObserver* mock_keyboard_observer_ = nullptr; + + private: + BrowserAccessibility* FindNodeInSubtree(BrowserAccessibility& node, + ax::mojom::Role role, + const std::string& name_or_value) { + const std::string& name = + node.GetStringAttribute(ax::mojom::StringAttribute::kName); + const std::string& value = base::UTF16ToUTF8(node.GetValue()); + if (node.GetRole() == role && + (name == name_or_value || value == name_or_value)) { + return &node; + } + + for (unsigned int i = 0; i < node.PlatformChildCount(); ++i) { + BrowserAccessibility* result = + FindNodeInSubtree(*node.PlatformGetChild(i), role, name_or_value); + if (result) + return result; + } + return nullptr; + } +}; + +#ifdef OS_WIN +IN_PROC_BROWSER_TEST_F(RenderWidgetHostViewAuraBrowserMockIMETest, + VirtualKeyboardIntegrationTest) { + // The keyboard input pane events are not supported on Win7. + if (base::win::GetVersion() <= base::win::Version::WIN7) { + return; + } + const char kVirtualKeyboardDataURL[] = + "data:text/html,<!DOCTYPE html>" + "<script>" + " let VKRect, x, y, width, height, numEvents = 0;" + " navigator.virtualKeyboard.overlaysContent = true;" + " navigator.virtualKeyboard.addEventListener('geometrychange'," + " evt => {" + " numEvents++;" + " let r = evt.boundingRect;" + " x = r.x; y = r.y; width = r.width; height = r.height;" + " VKRect = navigator.virtualKeyboard.boundingRect" + " }, false);" + "</script>"; + EXPECT_TRUE(NavigateToURL(shell(), GURL(kVirtualKeyboardDataURL))); + + RenderWidgetHostViewAura* rwhvi = GetRenderWidgetHostView(); + + // Send a touch event so that RenderWidgetHostViewAura will create the + // keyboard observer (requires last_pointer_type_ to be TOUCH). + ui::TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(30, 30), + base::TimeTicks::Now(), + ui::PointerDetails(ui::EventPointerType::kTouch, 0)); + rwhvi->OnTouchEvent(&press); + + // Emulate input type text focus in the root frame (the only frame), by + // setting frame focus and updating TextInputState. This is a more direct way + // of triggering focus in a textarea in the web page. + WebContentsImpl* web_contents = + static_cast<WebContentsImpl*>(shell()->web_contents()); + auto* root = web_contents->GetFrameTree()->root(); + web_contents->GetFrameTree()->SetFocusedFrame( + root, root->current_frame_host()->GetSiteInstance()); + + ui::mojom::TextInputState text_input_state; + text_input_state.show_ime_if_needed = true; + text_input_state.type = ui::TEXT_INPUT_TYPE_TEXT; + + TextInputManager* text_input_manager = rwhvi->GetTextInputManager(); + text_input_manager->UpdateTextInputState(rwhvi, text_input_state); + + // Send through a keyboard showing event with a rect, and verify the + // javascript event fires with the appropriate values. + constexpr int kKeyboardX = 0; + constexpr int kKeyboardY = 200; + constexpr int kKeyboardWidth = 200; + constexpr int kKeyboardHeight = 200; + gfx::Rect keyboard_rect(kKeyboardX, kKeyboardY, kKeyboardWidth, + kKeyboardHeight); + input_method_->GetMockKeyboardController()->NotifyObserversOnKeyboardShown( + keyboard_rect); + + // There are x and y-offsets for the main frame in content_browsertest + // hosting. We need to take these into account for the expected values. + gfx::PointF root_widget_origin(0.f, 0.f); + rwhvi->TransformPointToRootSurface(&root_widget_origin); + const int expected_width = kKeyboardWidth - root_widget_origin.x(); + const int expected_y = kKeyboardY - root_widget_origin.y(); + + EXPECT_EQ(1, EvalJs(shell(), "numEvents")); + EXPECT_EQ(0, EvalJs(shell(), "x")); + EXPECT_EQ(expected_y, EvalJs(shell(), "y")); + EXPECT_EQ(expected_width, EvalJs(shell(), "width")); + EXPECT_EQ(kKeyboardHeight, EvalJs(shell(), "height")); + EXPECT_EQ(0, EvalJs(shell(), "VKRect.x")); + EXPECT_EQ(expected_y, EvalJs(shell(), "VKRect.y")); + EXPECT_EQ(expected_width, EvalJs(shell(), "VKRect.width")); + EXPECT_EQ(kKeyboardHeight, EvalJs(shell(), "VKRect.height")); + + input_method_->GetMockKeyboardController()->NotifyObserversOnKeyboardHidden(); + EXPECT_EQ(2, EvalJs(shell(), "numEvents")); + EXPECT_EQ(0, EvalJs(shell(), "width")); + EXPECT_EQ(0, EvalJs(shell(), "height")); + EXPECT_EQ(0, EvalJs(shell(), "x")); + EXPECT_EQ(0, EvalJs(shell(), "y")); + EXPECT_EQ(0, EvalJs(shell(), "VKRect.x")); + EXPECT_EQ(0, EvalJs(shell(), "VKRect.y")); + EXPECT_EQ(0, EvalJs(shell(), "VKRect.width")); + EXPECT_EQ(0, EvalJs(shell(), "VKRect.height")); + + // Flip the policy back to non-overlay, verify the event doesn't fire + ignore_result( + EvalJs(shell(), "navigator.virtualKeyboard.overlaysContent = false")); + input_method_->GetMockKeyboardController()->NotifyObserversOnKeyboardShown( + keyboard_rect); + EXPECT_EQ(2, EvalJs(shell(), "numEvents")); +} + +IN_PROC_BROWSER_TEST_F(RenderWidgetHostViewAuraBrowserMockIMETest, + VirtualKeyboardCSSEnvVarIntegrationTest) { + // The keyboard input pane events are not supported on Win7. + if (base::win::GetVersion() <= base::win::Version::WIN7) { + return; + } + const char kVirtualKeyboardDataURL[] = + "data:text/html,<!DOCTYPE html>" + "<style>" + " .target {" + " margin-top: env(keyboard-inset-top);" + " margin-left: env(keyboard-inset-left);" + " margin-bottom: env(keyboard-inset-bottom);" + " margin-right: env(keyboard-inset-right);" + " }" + "</style>" + "<body>" + "<div class='target'></div>" + "<script>" + " let numEvents = 0;" + " navigator.virtualKeyboard.overlaysContent = true;" + " const e = document.getElementsByClassName('target')[0];" + " const style = window.getComputedStyle(e, null);" + " navigator.virtualKeyboard.addEventListener('geometrychange'," + " evt => {" + " numEvents++;" + " }, false);" + "</script></body>"; + EXPECT_TRUE(NavigateToURL(shell(), GURL(kVirtualKeyboardDataURL))); + + EXPECT_EQ( + "0px", + EvalJs(shell(), "style.getPropertyValue('margin-top')").ExtractString()); + EXPECT_EQ( + "0px", + EvalJs(shell(), "style.getPropertyValue('margin-left')").ExtractString()); + EXPECT_EQ("0px", EvalJs(shell(), "style.getPropertyValue('margin-bottom')") + .ExtractString()); + EXPECT_EQ("0px", EvalJs(shell(), "style.getPropertyValue('margin-right')") + .ExtractString()); + + RenderWidgetHostViewAura* rwhvi = GetRenderWidgetHostView(); + + // Send a touch event so that RenderWidgetHostViewAura will create the + // keyboard observer (requires last_pointer_type_ to be TOUCH). + ui::TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(30, 30), + base::TimeTicks::Now(), + ui::PointerDetails(ui::EventPointerType::kTouch, 0)); + rwhvi->OnTouchEvent(&press); + + // Emulate input type text focus in the root frame (the only frame), by + // setting frame focus and updating TextInputState. This is a more direct way + // of triggering focus in a textarea in the web page. + WebContentsImpl* web_contents = + static_cast<WebContentsImpl*>(shell()->web_contents()); + auto* root = web_contents->GetFrameTree()->root(); + web_contents->GetFrameTree()->SetFocusedFrame( + root, root->current_frame_host()->GetSiteInstance()); + + ui::mojom::TextInputState text_input_state; + text_input_state.show_ime_if_needed = true; + text_input_state.type = ui::TEXT_INPUT_TYPE_TEXT; + + TextInputManager* text_input_manager = rwhvi->GetTextInputManager(); + text_input_manager->UpdateTextInputState(rwhvi, text_input_state); + + // Send through a keyboard showing event with a rect, and verify the + // javascript event fires with the appropriate values. + constexpr int kKeyboardX = 0; + constexpr int kKeyboardY = 200; + constexpr int kKeyboardWidth = 200; + constexpr int kKeyboardHeight = 200; + gfx::Rect keyboard_rect(kKeyboardX, kKeyboardY, kKeyboardWidth, + kKeyboardHeight); + input_method_->GetMockKeyboardController()->NotifyObserversOnKeyboardShown( + keyboard_rect); + + // There are x and y-offsets for the main frame in content_browsertest + // hosting. We need to take these into account for the expected values. + gfx::PointF root_widget_origin(0.f, 0.f); + rwhvi->TransformPointToRootSurface(&root_widget_origin); + + EXPECT_EQ(1, EvalJs(shell(), "numEvents")); + EXPECT_EQ( + "161px", + EvalJs(shell(), "style.getPropertyValue('margin-top')").ExtractString()); + EXPECT_EQ( + "0px", + EvalJs(shell(), "style.getPropertyValue('margin-left')").ExtractString()); + EXPECT_EQ("198px", EvalJs(shell(), "style.getPropertyValue('margin-right')") + .ExtractString()); + EXPECT_EQ("361px", EvalJs(shell(), "style.getPropertyValue('margin-bottom')") + .ExtractString()); + + input_method_->GetMockKeyboardController()->NotifyObserversOnKeyboardHidden(); + EXPECT_EQ(2, EvalJs(shell(), "numEvents")); + EXPECT_EQ( + "0px", + EvalJs(shell(), "style.getPropertyValue('margin-top')").ExtractString()); + EXPECT_EQ( + "0px", + EvalJs(shell(), "style.getPropertyValue('margin-left')").ExtractString()); + EXPECT_EQ("0px", EvalJs(shell(), "style.getPropertyValue('margin-right')") + .ExtractString()); + EXPECT_EQ("0px", EvalJs(shell(), "style.getPropertyValue('margin-bottom')") + .ExtractString()); +} +IN_PROC_BROWSER_TEST_F(RenderWidgetHostViewAuraBrowserMockIMETest, + VirtualKeyboardAccessibilityFocusTest) { + // The keyboard input pane events are not supported on Win7. + if (base::win::GetVersion() <= base::win::Version::WIN7) { + return; + } + LoadInitialAccessibilityTreeFromHtml(R"HTML( + <div><button>Before</button></div> + <div contenteditable>Editable text</div> + <div><button>After</button></div> + )HTML"); + + BrowserAccessibility* target = + FindNode(ax::mojom::Role::kGenericContainer, "Editable text"); + ASSERT_NE(nullptr, target); + WebContentsImpl* web_contents = + static_cast<WebContentsImpl*>(shell()->web_contents()); + auto* root = web_contents->GetFrameTree()->root(); + web_contents->GetFrameTree()->SetFocusedFrame( + root, root->current_frame_host()->GetSiteInstance()); + + AccessibilityNotificationWaiter waiter2( + shell()->web_contents(), ui::kAXModeComplete, ax::mojom::Event::kFocus); + GetManager()->DoDefaultAction(*target); + waiter2.WaitForNotification(); + + BrowserAccessibility* focus = GetManager()->GetFocus(); + EXPECT_EQ(focus->GetId(), target->GetId()); + + EXPECT_EQ(true, mock_keyboard_observer_->IsKeyboardDisplayCalled()); +} +#endif // #ifdef OS_WIN + +} // namespace content diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_base.cc b/chromium/content/browser/renderer_host/render_widget_host_view_base.cc index 403a8c870a5..85b265f7004 100644 --- a/chromium/content/browser/renderer_host/render_widget_host_view_base.cc +++ b/chromium/content/browser/renderer_host/render_widget_host_view_base.cc @@ -125,6 +125,8 @@ void RenderWidgetHostViewBase::OnRenderFrameMetadataChangedAfterActivation() { host()->GetRootBrowserAccessibilityManager(); if (manager) manager->SetPageScaleFactor(metadata.page_scale_factor); + + is_drawing_delegated_ink_trails_ = metadata.has_delegated_ink_metadata; } void RenderWidgetHostViewBase::OnRenderFrameSubmission() {} @@ -141,10 +143,15 @@ gfx::Size RenderWidgetHostViewBase::GetCompositorViewportPixelSize() { } void RenderWidgetHostViewBase::SelectionBoundsChanged( - const WidgetHostMsg_SelectionBounds_Params& params) { + const gfx::Rect& anchor_rect, + base::i18n::TextDirection anchor_dir, + const gfx::Rect& focus_rect, + base::i18n::TextDirection focus_dir, + bool is_anchor_first) { #if !defined(OS_ANDROID) if (GetTextInputManager()) - GetTextInputManager()->SelectionBoundsChanged(this, params); + GetTextInputManager()->SelectionBoundsChanged( + this, anchor_rect, anchor_dir, focus_rect, focus_dir, is_anchor_first); #else NOTREACHED() << "Selection bounds should be routed through the compositor."; #endif @@ -594,6 +601,15 @@ void RenderWidgetHostViewBase::TransformPointToRootSurface(gfx::PointF* point) { return; } +const DisplayFeature* RenderWidgetHostViewBase::GetDisplayFeature() { + return base::OptionalOrNullptr(display_feature_); +} + +void RenderWidgetHostViewBase::SetDisplayFeatureForTesting( + base::Optional<DisplayFeature> display_feature) { + display_feature_ = std::move(display_feature); +} + void RenderWidgetHostViewBase::OnDidNavigateMainFrameToNewPage() { } @@ -689,7 +705,7 @@ RenderWidgetHostViewBase::ExtractAndCancelActiveTouches() { } void RenderWidgetHostViewBase::TextInputStateChanged( - const TextInputState& text_input_state) { + const ui::mojom::TextInputState& text_input_state) { if (GetTextInputManager()) GetTextInputManager()->UpdateTextInputState(this, text_input_state); } @@ -755,21 +771,18 @@ RenderWidgetHostViewBase::GetTouchSelectionControllerClientManager() { void RenderWidgetHostViewBase::SetRecordContentToVisibleTimeRequest( base::TimeTicks start_time, base::Optional<bool> destination_is_loaded, - base::Optional<bool> destination_is_frozen, bool show_reason_tab_switching, bool show_reason_unoccluded, bool show_reason_bfcache_restore) { if (last_record_tab_switch_time_request_.has_value()) { last_record_tab_switch_time_request_.value().UpdateRequest( RecordContentToVisibleTimeRequest( - start_time, destination_is_loaded, destination_is_frozen, - show_reason_tab_switching, show_reason_unoccluded, - show_reason_bfcache_restore)); + start_time, destination_is_loaded, show_reason_tab_switching, + show_reason_unoccluded, show_reason_bfcache_restore)); } else { last_record_tab_switch_time_request_.emplace( - start_time, destination_is_loaded, destination_is_frozen, - show_reason_tab_switching, show_reason_unoccluded, - show_reason_bfcache_restore); + start_time, destination_is_loaded, show_reason_tab_switching, + show_reason_unoccluded, show_reason_bfcache_restore); } } diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_base.h b/chromium/content/browser/renderer_host/render_widget_host_view_base.h index 39f1c8d6ee4..73078c6123c 100644 --- a/chromium/content/browser/renderer_host/render_widget_host_view_base.h +++ b/chromium/content/browser/renderer_host/render_widget_host_view_base.h @@ -12,6 +12,7 @@ #include <vector> #include "base/callback_forward.h" +#include "base/i18n/rtl.h" #include "base/macros.h" #include "base/observer_list.h" #include "base/optional.h" @@ -22,6 +23,7 @@ #include "components/viz/common/surfaces/scoped_surface_id_allocator.h" #include "components/viz/common/surfaces/surface_id.h" #include "components/viz/host/hit_test/hit_test_query.h" +#include "content/browser/renderer_host/display_feature.h" #include "content/browser/renderer_host/event_with_latency_info.h" #include "content/common/content_export.h" #include "content/common/content_to_visible_time_reporter.h" @@ -35,16 +37,16 @@ #include "third_party/blink/public/mojom/input/input_event_result.mojom-shared.h" #include "third_party/skia/include/core/SkImageInfo.h" #include "ui/accessibility/ax_tree_id_registry.h" +#include "ui/base/ime/mojom/text_input_state.mojom-forward.h" #include "ui/base/ime/text_input_mode.h" #include "ui/base/ime/text_input_type.h" #include "ui/display/display.h" +#include "ui/events/event_constants.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/native_widget_types.h" #include "ui/gfx/range/range.h" #include "ui/surface/transport_dib.h" -struct WidgetHostMsg_SelectionBounds_Params; - namespace blink { class WebMouseEvent; class WebMouseWheelEvent; @@ -70,7 +72,7 @@ class TextInputManager; class TouchSelectionControllerClientManager; class WebCursor; class DelegatedFrameHost; -struct TextInputState; +struct DisplayFeature; // Basic implementation shared by concrete RenderWidgetHostView subclasses. class CONTENT_EXPORT RenderWidgetHostViewBase @@ -121,7 +123,6 @@ class CONTENT_EXPORT RenderWidgetHostViewBase void SetRecordContentToVisibleTimeRequest( base::TimeTicks start_time, base::Optional<bool> destination_is_loaded, - base::Optional<bool> destination_is_frozen, bool show_reason_tab_switching, bool show_reason_unoccluded, bool show_reason_bfcache_restore) final; @@ -395,6 +396,8 @@ class CONTENT_EXPORT RenderWidgetHostViewBase virtual void TransferTouches( const std::vector<std::unique_ptr<ui::TouchEvent>>& touches) {} + virtual void SetLastPointerType(ui::EventPointerType last_pointer_type) {} + //---------------------------------------------------------------------------- // The following methods are related to IME. // TODO(ekaramad): Most of the IME methods should not stay virtual after IME @@ -402,7 +405,8 @@ class CONTENT_EXPORT RenderWidgetHostViewBase // non-virtual (https://crbug.com/578168). // Updates the state of the input method attached to the view. - virtual void TextInputStateChanged(const TextInputState& text_input_state); + virtual void TextInputStateChanged( + const ui::mojom::TextInputState& text_input_state); // Cancel the ongoing composition of the input method attached to the view. virtual void ImeCancelComposition(); @@ -413,8 +417,11 @@ class CONTENT_EXPORT RenderWidgetHostViewBase // starting position of the selection. The coordinates are with respect to // RenderWidget's window's origin. Focus and anchor bound are represented as // gfx::Rect. - virtual void SelectionBoundsChanged( - const WidgetHostMsg_SelectionBounds_Params& params); + virtual void SelectionBoundsChanged(const gfx::Rect& anchor_rect, + base::i18n::TextDirection anchor_dir, + const gfx::Rect& focus_rect, + base::i18n::TextDirection focus_dir, + bool is_anchor_first); // Updates the range of the marked text in an IME composition. virtual void ImeCompositionRangeChanged( @@ -481,6 +488,13 @@ class CONTENT_EXPORT RenderWidgetHostViewBase virtual void OnAutoscrollStart(); + // Gets the DisplayFeature whose offset and mask_length are expressed in DIPs + // relative to the view. See display_feature.h for more details. + virtual const DisplayFeature* GetDisplayFeature(); + + void SetDisplayFeatureForTesting( + base::Optional<DisplayFeature> display_feature); + // Returns the associated RenderWidgetHostImpl. RenderWidgetHostImpl* host() const { return host_; } @@ -600,6 +614,11 @@ class CONTENT_EXPORT RenderWidgetHostViewBase bool is_currently_scrolling_viewport_ = false; + // TODO(crbug.com/1039050) Remove this member that is set for testing once + // support for returning the actual DisplayFeature is added to the platform + // specific RenderWidgetHostView. + base::Optional<DisplayFeature> display_feature_; + private: FRIEND_TEST_ALL_PREFIXES( BrowserSideFlingBrowserTest, @@ -607,6 +626,8 @@ class CONTENT_EXPORT RenderWidgetHostViewBase FRIEND_TEST_ALL_PREFIXES( BrowserSideFlingBrowserTest, EarlyTouchpadFlingCancelationOnInertialGSUAckNotConsumed); + FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostDelegatedInkMetadataTest, + FlagGetsSetFromRenderFrameMetadata); void SynchronizeVisualProperties(); @@ -647,6 +668,12 @@ class CONTENT_EXPORT RenderWidgetHostViewBase bool is_evicted_ = false; + // True when points should be forwarded from the + // RenderWidgetHostViewEventHandler directly to viz for use in a delegated + // ink trail. + // TODO(1052145): Use this to begin forwarding the points to viz. + bool is_drawing_delegated_ink_trails_ = false; + base::WeakPtrFactory<RenderWidgetHostViewBase> weak_factory_{this}; DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewBase); diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_child_frame.cc b/chromium/content/browser/renderer_host/render_widget_host_view_child_frame.cc index 379252e8e61..f7bb9288c81 100644 --- a/chromium/content/browser/renderer_host/render_widget_host_view_child_frame.cc +++ b/chromium/content/browser/renderer_host/render_widget_host_view_child_frame.cc @@ -33,11 +33,11 @@ #include "content/browser/renderer_host/render_widget_host_input_event_router.h" #include "content/browser/renderer_host/render_widget_host_view_event_handler.h" #include "content/browser/renderer_host/text_input_manager.h" -#include "content/common/text_input_state.h" #include "content/common/widget_messages.h" #include "content/public/browser/render_process_host.h" #include "gpu/ipc/common/gpu_messages.h" #include "third_party/blink/public/common/input/web_touch_event.h" +#include "ui/base/ime/mojom/text_input_state.mojom.h" #include "ui/gfx/geometry/dip_util.h" #include "ui/gfx/geometry/size_conversions.h" #include "ui/gfx/geometry/size_f.h" diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_child_frame_browsertest.cc b/chromium/content/browser/renderer_host/render_widget_host_view_child_frame_browsertest.cc index e27673fe912..4a537c179f0 100644 --- a/chromium/content/browser/renderer_host/render_widget_host_view_child_frame_browsertest.cc +++ b/chromium/content/browser/renderer_host/render_widget_host_view_child_frame_browsertest.cc @@ -34,6 +34,7 @@ #include "content/test/test_content_browser_client.h" #include "net/dns/mock_host_resolver.h" #include "net/test/embedded_test_server/embedded_test_server.h" +#include "testing/gmock/include/gmock/gmock.h" #include "third_party/blink/public/common/features.h" #include "ui/gfx/geometry/size.h" @@ -484,7 +485,7 @@ IN_PROC_BROWSER_TEST_F(RenderWidgetHostViewChildFrameBrowserTest, child_rwh_impl->WasHidden(); child_rwh_impl->WasShown(RecordContentToVisibleTimeRequest{ base::TimeTicks::Now(), /* destination_is_loaded */ true, - /* destination_is_frozen */ false, /* show_reason_tab_switching */ true, + /* show_reason_tab_switching */ true, /* show_reason_unoccluded */ false, /* show_reason_bfcache_restore */ false}); // Force the child to submit a new frame. @@ -594,4 +595,182 @@ IN_PROC_BROWSER_TEST_F(RenderWidgetHostViewChildFrameBrowserTest, "window.matchMedia('(display-mode: standalone)').matches")); } +// Validate that the root widget's window segments are correctly propagated +// via the SynchronizeVisualProperties cascade. +IN_PROC_BROWSER_TEST_F(RenderWidgetHostViewChildFrameBrowserTest, + VisualPropertiesPropagation_RootWindowSegments) { + GURL main_url(embedded_test_server()->GetURL( + "a.com", "/cross_site_iframe_factory.html?a(b(c),a)")); + EXPECT_TRUE(NavigateToURL(shell(), main_url)); + + auto* web_contents = static_cast<WebContentsImpl*>(shell()->web_contents()); + + // Main frame/root view. + FrameTreeNode* root = web_contents->GetFrameTree()->root(); + RenderWidgetHostImpl* root_widget = + root->current_frame_host()->GetRenderWidgetHost(); + RenderWidgetHostViewBase* root_view = root_widget->GetView(); + // Out-of-process child frame. + FrameTreeNode* oopchild = root->child_at(0); + auto* oopchild_rph = static_cast<RenderProcessHostImpl*>( + oopchild->current_frame_host()->GetProcess()); + // Out-of-process descendant frame (child of the first oop-iframe). + FrameTreeNode* oopdescendant = oopchild->child_at(0); + auto* oopdescendant_rph = static_cast<RenderProcessHostImpl*>( + oopdescendant->current_frame_host()->GetProcess()); + + const gfx::Size root_view_size = root_view->GetVisibleViewportSize(); + const int kDisplayFeatureLength = 10; + DisplayFeature emulated_display_feature{ + DisplayFeature::Orientation::kVertical, + /* offset */ root_view_size.width() / 2 - kDisplayFeatureLength / 2, + /* mask_length */ kDisplayFeatureLength}; + std::vector<gfx::Rect> expected_segments; + expected_segments.emplace_back(0, 0, emulated_display_feature.offset, + root_view_size.height()); + expected_segments.emplace_back( + emulated_display_feature.offset + emulated_display_feature.mask_length, 0, + emulated_display_feature.offset, root_view_size.height()); + + { + base::RunLoop loop; + + // Watch for visual properties changes, first to the child oop-iframe, then + // to the descendant (at which point we're done and can validate the + // values). + std::vector<gfx::Rect> oopchild_root_window_segments; + OutgoingVisualPropertiesIPCWatcher oopchild_watcher( + oopchild_rph, root, + base::BindLambdaForTesting([&](const VisualProperties& props) { + oopchild_root_window_segments = props.root_widget_window_segments; + })); + + std::vector<gfx::Rect> oopdescendant_root_window_segments; + OutgoingVisualPropertiesIPCWatcher oopdescendant_watcher( + oopdescendant_rph, root, + base::BindLambdaForTesting([&](const VisualProperties& props) { + oopdescendant_root_window_segments = + props.root_widget_window_segments; + if (oopdescendant_root_window_segments == expected_segments) + loop.Quit(); + })); + + root_view->SetDisplayFeatureForTesting(emulated_display_feature); + root_widget->SynchronizeVisualProperties(); + + loop.Run(); + + // The child widgets must be informed of the changed window segments. + EXPECT_THAT(oopchild_root_window_segments, + ::testing::ContainerEq(expected_segments)); + EXPECT_THAT(oopdescendant_root_window_segments, + ::testing::ContainerEq(expected_segments)); + } + + { + base::RunLoop loop; + std::vector<gfx::Rect> new_frame_root_window_segments; + OutgoingVisualPropertiesIPCWatcher oopdescendant_watcher( + oopdescendant_rph, root, + base::BindLambdaForTesting([&](const VisualProperties& props) { + new_frame_root_window_segments = props.root_widget_window_segments; + // This check is needed, since we'll get an IPC originating from + // RenderWidgetHostImpl immediately after the frame is added with the + // incorrect value (the segments are cascaded from the parent renderer + // when the frame is added in that process). So we need to wait for + // the outgoing VisualProperties triggered from the parent renderer + // and comes in via the CrossProcessFrameConnector, which can happen + // after NavigateFrameToURL completes. + if (new_frame_root_window_segments == expected_segments) + loop.Quit(); + })); + + // Creating a new local frame root (navigating a.com to c.com) should also + // propagate the property to the new local frame root. Note that we're + // re-using the existing RenderProcessHost from c.com (aka + // |oopdescendant_rph|). + GURL new_frame_url(embedded_test_server()->GetURL("c.com", "/title2.html")); + NavigateFrameToURL(root->child_at(1), new_frame_url); + + loop.Run(); + + EXPECT_THAT(new_frame_root_window_segments, + ::testing::ContainerEq(expected_segments)); + } +} + +IN_PROC_BROWSER_TEST_F(RenderWidgetHostViewChildFrameBrowserTest, + SetTextDirection) { + GURL main_url(embedded_test_server()->GetURL( + "a.com", "/cross_site_iframe_factory.html?a(a,b)")); + EXPECT_TRUE(NavigateToURL(shell(), main_url)); + + auto* web_contents = static_cast<WebContentsImpl*>(shell()->web_contents()); + + // Main frame. + FrameTreeNode* root = web_contents->GetFrameTree()->root(); + RenderWidgetHostImpl* root_widget = + root->current_frame_host()->GetRenderWidgetHost(); + ASSERT_TRUE( + ExecuteScript(root->current_frame_host(), + "var elem = document.createElement('input'); " + "elem.id = 'mainframe_input_id';" + "document.body.appendChild(elem);" + "document.getElementById('mainframe_input_id').focus();")); + root_widget->UpdateTextDirection(base::i18n::RIGHT_TO_LEFT); + root_widget->NotifyTextDirection(); + std::string mainframe_input_element_dir = + ExecuteScriptAndGetValue( + root->current_frame_host(), + "document.getElementById('mainframe_input_id').dir") + .GetString(); + EXPECT_EQ(mainframe_input_element_dir, "rtl"); + + // In-process frame. + FrameTreeNode* ipchild = root->child_at(0); + RenderWidgetHostImpl* ipchild_widget = + ipchild->current_frame_host()->GetRenderWidgetHost(); + ASSERT_TRUE( + ExecuteScript(ipchild->current_frame_host(), + "var elem = document.createElement('input'); " + "elem.id = 'ipchild_input_id';" + "document.body.appendChild(elem);" + "document.getElementById('ipchild_input_id').focus();")); + ipchild_widget->UpdateTextDirection(base::i18n::LEFT_TO_RIGHT); + ipchild_widget->NotifyTextDirection(); + std::string ip_input_element_dir = + ExecuteScriptAndGetValue( + ipchild->current_frame_host(), + "document.getElementById('ipchild_input_id').dir") + .GetString(); + EXPECT_EQ(ip_input_element_dir, "ltr"); + + // Out-of-process frame. + FrameTreeNode* oopchild = root->child_at(1); + RenderWidgetHostImpl* oopchild_widget = + oopchild->current_frame_host()->GetRenderWidgetHost(); + ASSERT_TRUE( + ExecuteScript(oopchild->current_frame_host(), + "var elem = document.createElement('input'); " + "elem.id = 'oop_input_id';" + "document.body.appendChild(elem);" + "document.getElementById('oop_input_id').focus();")); + oopchild_widget->UpdateTextDirection(base::i18n::RIGHT_TO_LEFT); + oopchild_widget->NotifyTextDirection(); + std::string oop_input_element_dir = + ExecuteScriptAndGetValue(oopchild->current_frame_host(), + "document.getElementById('oop_input_id').dir") + .GetString(); + EXPECT_EQ(oop_input_element_dir, "rtl"); + + // In case of UNKNOWN_DIRECTION, old value of direction is maintained. + oopchild_widget->UpdateTextDirection(base::i18n::UNKNOWN_DIRECTION); + oopchild_widget->NotifyTextDirection(); + oop_input_element_dir = + ExecuteScriptAndGetValue(oopchild->current_frame_host(), + "document.getElementById('oop_input_id').dir") + .GetString(); + EXPECT_EQ(oop_input_element_dir, "rtl"); +} + } // namespace content diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_child_frame_unittest.cc b/chromium/content/browser/renderer_host/render_widget_host_view_child_frame_unittest.cc index 276ad19cbbc..1bf0658b886 100644 --- a/chromium/content/browser/renderer_host/render_widget_host_view_child_frame_unittest.cc +++ b/chromium/content/browser/renderer_host/render_widget_host_view_child_frame_unittest.cc @@ -33,12 +33,12 @@ #include "content/public/test/mock_render_process_host.h" #include "content/public/test/test_browser_context.h" #include "content/test/mock_render_widget_host_delegate.h" -#include "content/test/mock_widget_impl.h" #include "content/test/test_render_view_host.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/remote.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/common/input/synthetic_web_input_event_builders.h" #include "third_party/blink/public/platform/viewport_intersection_state.h" #include "ui/base/ui_base_features.h" #include "ui/compositor/compositor.h" @@ -122,21 +122,25 @@ class RenderWidgetHostViewChildFrameTest : public testing::Test { int32_t routing_id = process_host->GetNextRoutingID(); sink_ = &process_host->sink(); - mojo::PendingRemote<mojom::Widget> widget; - widget_impl_ = std::make_unique<MockWidgetImpl>( - widget.InitWithNewPipeAndPassReceiver()); widget_host_ = new RenderWidgetHostImpl( - &delegate_, process_host, routing_id, std::move(widget), + &delegate_, process_host, routing_id, /*hidden=*/false, std::make_unique<FrameTokenMessageQueue>()); + mojo::AssociatedRemote<blink::mojom::WidgetHost> blink_widget_host; + mojo::AssociatedRemote<blink::mojom::Widget> blink_widget; + auto blink_widget_receiver = + blink_widget.BindNewEndpointAndPassDedicatedReceiverForTesting(); + widget_host_->BindWidgetInterfaces( + blink_widget_host.BindNewEndpointAndPassDedicatedReceiverForTesting(), + blink_widget.Unbind()); + mojo::AssociatedRemote<blink::mojom::FrameWidgetHost> frame_widget_host; - auto frame_widget_host_receiver = - frame_widget_host.BindNewEndpointAndPassDedicatedReceiverForTesting(); mojo::AssociatedRemote<blink::mojom::FrameWidget> frame_widget; auto frame_widget_receiver = frame_widget.BindNewEndpointAndPassDedicatedReceiverForTesting(); widget_host_->BindFrameWidgetInterfaces( - std::move(frame_widget_host_receiver), frame_widget.Unbind()); + frame_widget_host.BindNewEndpointAndPassDedicatedReceiverForTesting(), + frame_widget.Unbind()); view_ = RenderWidgetHostViewChildFrame::Create(widget_host_); @@ -180,7 +184,6 @@ class RenderWidgetHostViewChildFrameTest : public testing::Test { // Tests should set these to NULL if they've already triggered their // destruction. - std::unique_ptr<MockWidgetImpl> widget_impl_; RenderWidgetHostImpl* widget_host_; RenderWidgetHostViewChildFrame* view_; MockFrameConnectorDelegate* test_frame_connector_; @@ -291,6 +294,7 @@ TEST_F(RenderWidgetHostViewChildFrameTest, visual_properties.local_frame_size = compositor_viewport_pixel_rect.size(); visual_properties.capture_sequence_number = 123u; visual_properties.local_surface_id_allocation = local_surface_id_allocation; + visual_properties.root_widget_window_segments.emplace_back(1, 2, 3, 4); sink_->ClearMessages(); test_frame_connector_->SynchronizeVisualProperties(frame_sink_id, @@ -311,6 +315,9 @@ TEST_F(RenderWidgetHostViewChildFrameTest, EXPECT_EQ(local_surface_id_allocation, sent_visual_properties.local_surface_id_allocation); EXPECT_EQ(123u, sent_visual_properties.capture_sequence_number); + EXPECT_EQ(1u, sent_visual_properties.root_widget_window_segments.size()); + EXPECT_EQ(gfx::Rect(1, 2, 3, 4), + sent_visual_properties.root_widget_window_segments[0]); } } @@ -318,14 +325,15 @@ TEST_F(RenderWidgetHostViewChildFrameTest, // child, the events are bubbled so that the parent may consume them. TEST_F(RenderWidgetHostViewChildFrameTest, UncomsumedGestureScrollBubbled) { blink::WebGestureEvent scroll_begin = - SyntheticWebGestureEventBuilder::BuildScrollBegin( + blink::SyntheticWebGestureEventBuilder::BuildScrollBegin( 0.f, 10.f, blink::WebGestureDevice::kTouchscreen); blink::WebGestureEvent scroll_update = - SyntheticWebGestureEventBuilder::BuildScrollUpdate( + blink::SyntheticWebGestureEventBuilder::BuildScrollUpdate( 0.f, 10.f, 0, blink::WebGestureDevice::kTouchscreen); - blink::WebGestureEvent scroll_end = SyntheticWebGestureEventBuilder::Build( - blink::WebInputEvent::Type::kGestureScrollEnd, - blink::WebGestureDevice::kTouchscreen); + blink::WebGestureEvent scroll_end = + blink::SyntheticWebGestureEventBuilder::Build( + blink::WebInputEvent::Type::kGestureScrollEnd, + blink::WebGestureDevice::kTouchscreen); view_->GestureEventAck( scroll_begin, blink::mojom::InputEventResultState::kNoConsumerExists); @@ -345,14 +353,15 @@ TEST_F(RenderWidgetHostViewChildFrameTest, UncomsumedGestureScrollBubbled) { // child, the events are not bubbled to the parent. TEST_F(RenderWidgetHostViewChildFrameTest, ConsumedGestureScrollNotBubbled) { blink::WebGestureEvent scroll_begin = - SyntheticWebGestureEventBuilder::BuildScrollBegin( + blink::SyntheticWebGestureEventBuilder::BuildScrollBegin( 0.f, 10.f, blink::WebGestureDevice::kTouchscreen); blink::WebGestureEvent scroll_update = - SyntheticWebGestureEventBuilder::BuildScrollUpdate( + blink::SyntheticWebGestureEventBuilder::BuildScrollUpdate( 0.f, 10.f, 0, blink::WebGestureDevice::kTouchscreen); - blink::WebGestureEvent scroll_end = SyntheticWebGestureEventBuilder::Build( - blink::WebInputEvent::Type::kGestureScrollEnd, - blink::WebGestureDevice::kTouchscreen); + blink::WebGestureEvent scroll_end = + blink::SyntheticWebGestureEventBuilder::Build( + blink::WebInputEvent::Type::kGestureScrollEnd, + blink::WebGestureDevice::kTouchscreen); view_->GestureEventAck(scroll_begin, blink::mojom::InputEventResultState::kConsumed); @@ -381,14 +390,15 @@ TEST_F(RenderWidgetHostViewChildFrameTest, ConsumedGestureScrollNotBubbled) { TEST_F(RenderWidgetHostViewChildFrameTest, DoNotBubbleRemainingEventsOfRejectedScrollGesture) { blink::WebGestureEvent scroll_begin = - SyntheticWebGestureEventBuilder::BuildScrollBegin( + blink::SyntheticWebGestureEventBuilder::BuildScrollBegin( 0.f, 10.f, blink::WebGestureDevice::kTouchscreen); blink::WebGestureEvent scroll_update = - SyntheticWebGestureEventBuilder::BuildScrollUpdate( + blink::SyntheticWebGestureEventBuilder::BuildScrollUpdate( 0.f, 10.f, 0, blink::WebGestureDevice::kTouchscreen); - blink::WebGestureEvent scroll_end = SyntheticWebGestureEventBuilder::Build( - blink::WebInputEvent::Type::kGestureScrollEnd, - blink::WebGestureDevice::kTouchscreen); + blink::WebGestureEvent scroll_end = + blink::SyntheticWebGestureEventBuilder::Build( + blink::WebInputEvent::Type::kGestureScrollEnd, + blink::WebGestureDevice::kTouchscreen); test_frame_connector_->SetCanBubble(false); diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_event_handler.cc b/chromium/content/browser/renderer_host/render_widget_host_view_event_handler.cc index a21600fc77a..df6f607a65a 100644 --- a/chromium/content/browser/renderer_host/render_widget_host_view_event_handler.cc +++ b/chromium/content/browser/renderer_host/render_widget_host_view_event_handler.cc @@ -7,6 +7,7 @@ #include "base/command_line.h" #include "base/metrics/user_metrics.h" #include "base/metrics/user_metrics_action.h" +#include "build/build_config.h" #include "components/viz/common/features.h" #include "content/browser/renderer_host/hit_test_debug_key_event_observer.h" #include "content/browser/renderer_host/input/touch_selection_controller_client_aura.h" @@ -335,6 +336,47 @@ void RenderWidgetHostViewEventHandler::OnKeyEvent(ui::KeyEvent* event) { event->SetHandled(); } +void RenderWidgetHostViewEventHandler::HandleMouseWheelEvent( + ui::MouseEvent* event) { + DCHECK(event); + DCHECK_EQ(event->type(), ui::ET_MOUSEWHEEL); + +#if defined(OS_WIN) + if (!mouse_locked_) { + // We get mouse wheel/scroll messages even if we are not in the foreground. + // So here we check if we have any owned popup windows in the foreground and + // dismiss them. + aura::WindowTreeHost* host = window_->GetHost(); + if (host) { + HWND parent = host->GetAcceleratedWidget(); + HWND toplevel_hwnd = ::GetAncestor(parent, GA_ROOT); + EnumThreadWindows(GetCurrentThreadId(), DismissOwnedPopups, + reinterpret_cast<LPARAM>(toplevel_hwnd)); + } + } +#endif + + blink::WebMouseWheelEvent mouse_wheel_event = + ui::MakeWebMouseWheelEvent(*event->AsMouseWheelEvent()); + + if (mouse_wheel_event.delta_x != 0 || mouse_wheel_event.delta_y != 0) { + const bool should_route_event = ShouldRouteEvents(); + // End the touchpad scrolling sequence (if such exists) before handling + // a ui::ET_MOUSEWHEEL event. + mouse_wheel_phase_handler_.SendWheelEndForTouchpadScrollingIfNeeded( + should_route_event); + + mouse_wheel_phase_handler_.AddPhaseIfNeededAndScheduleEndEvent( + mouse_wheel_event, should_route_event); + if (should_route_event) { + host_->delegate()->GetInputEventRouter()->RouteMouseWheelEvent( + host_view_, &mouse_wheel_event, *event->latency()); + } else { + ProcessMouseWheelEvent(mouse_wheel_event, *event->latency()); + } + } +} + void RenderWidgetHostViewEventHandler::OnMouseEvent(ui::MouseEvent* event) { TRACE_EVENT0("input", "RenderWidgetHostViewBase::OnMouseEvent"); @@ -372,39 +414,9 @@ void RenderWidgetHostViewEventHandler::OnMouseEvent(ui::MouseEvent* event) { return; } - if (event->type() == ui::ET_MOUSEWHEEL) { -#if defined(OS_WIN) - // We get mouse wheel/scroll messages even if we are not in the foreground. - // So here we check if we have any owned popup windows in the foreground and - // dismiss them. - aura::WindowTreeHost* host = window_->GetHost(); - if (host) { - HWND parent = host->GetAcceleratedWidget(); - HWND toplevel_hwnd = ::GetAncestor(parent, GA_ROOT); - EnumThreadWindows(GetCurrentThreadId(), DismissOwnedPopups, - reinterpret_cast<LPARAM>(toplevel_hwnd)); - } -#endif - blink::WebMouseWheelEvent mouse_wheel_event = - ui::MakeWebMouseWheelEvent(*event->AsMouseWheelEvent()); - - if (mouse_wheel_event.delta_x != 0 || mouse_wheel_event.delta_y != 0) { - const bool should_route_event = ShouldRouteEvents(); - // End the touchpad scrolling sequence (if such exists) before handling - // a ui::ET_MOUSEWHEEL event. - mouse_wheel_phase_handler_.SendWheelEndForTouchpadScrollingIfNeeded( - should_route_event); - - mouse_wheel_phase_handler_.AddPhaseIfNeededAndScheduleEndEvent( - mouse_wheel_event, should_route_event); - if (should_route_event) { - host_->delegate()->GetInputEventRouter()->RouteMouseWheelEvent( - host_view_, &mouse_wheel_event, *event->latency()); - } else { - ProcessMouseWheelEvent(mouse_wheel_event, *event->latency()); - } - } - } else { + if (event->type() == ui::ET_MOUSEWHEEL) + HandleMouseWheelEvent(event); + else { bool is_selection_popup = NeedsInputGrab(popup_child_host_view_); if (CanRendererHandleEvent(event, mouse_locked_, is_selection_popup) && !(event->flags() & ui::EF_FROM_TOUCH)) { @@ -746,18 +758,9 @@ void RenderWidgetHostViewEventHandler::HandleMouseEventWhileLocked( DCHECK(!cursor_client || !cursor_client->IsCursorVisible()); - if (event->type() == ui::ET_MOUSEWHEEL) { - blink::WebMouseWheelEvent mouse_wheel_event = - ui::MakeWebMouseWheelEvent(*event->AsMouseWheelEvent()); - if (mouse_wheel_event.delta_x != 0 || mouse_wheel_event.delta_y != 0) { - if (ShouldRouteEvents()) { - host_->delegate()->GetInputEventRouter()->RouteMouseWheelEvent( - host_view_, &mouse_wheel_event, *event->latency()); - } else { - ProcessMouseWheelEvent(mouse_wheel_event, *event->latency()); - } - } - } else { + if (event->type() == ui::ET_MOUSEWHEEL) + HandleMouseWheelEvent(event); + else { // If we receive non client mouse messages while we are in the locked state // it probably means that the mouse left the borders of our window and // needs to be moved back to the center. diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_event_handler.h b/chromium/content/browser/renderer_host/render_widget_host_view_event_handler.h index 6c306f4a8de..76f49788e8d 100644 --- a/chromium/content/browser/renderer_host/render_widget_host_view_event_handler.h +++ b/chromium/content/browser/renderer_host/render_widget_host_view_event_handler.h @@ -251,6 +251,8 @@ class CONTENT_EXPORT RenderWidgetHostViewEventHandler // Returns true if event is a reserved key for an active KeyboardLock request. bool IsKeyLocked(const ui::KeyEvent& event); + void HandleMouseWheelEvent(ui::MouseEvent* event); + // Whether return characters should be passed on to the RenderWidgetHostImpl. bool accept_return_character_ = false; diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_mac.h b/chromium/content/browser/renderer_host/render_widget_host_view_mac.h index 336ac58d9f5..51f91581aff 100644 --- a/chromium/content/browser/renderer_host/render_widget_host_view_mac.h +++ b/chromium/content/browser/renderer_host/render_widget_host_view_mac.h @@ -28,6 +28,7 @@ #include "ui/accelerated_widget_mac/accelerated_widget_mac.h" #include "ui/base/cocoa/accessibility_focus_overrider.h" #include "ui/base/cocoa/remote_layer_api.h" +#include "ui/base/mojom/attributed_string.mojom-forward.h" #include "ui/display/mac/display_link_mac.h" #include "ui/events/gesture_detection/filtered_gesture_provider.h" @@ -333,20 +334,28 @@ class CONTENT_EXPORT RenderWidgetHostViewMac void BeginKeyboardEvent() override; void EndKeyboardEvent() override; void ForwardKeyboardEventWithCommands( - std::unique_ptr<InputEvent> event, + std::unique_ptr<blink::WebCoalescedInputEvent> event, const std::vector<uint8_t>& native_event_data, bool skip_in_browser, std::vector<blink::mojom::EditCommandPtr> commands) override; - void RouteOrProcessMouseEvent(std::unique_ptr<InputEvent> event) override; - void RouteOrProcessTouchEvent(std::unique_ptr<InputEvent> event) override; - void RouteOrProcessWheelEvent(std::unique_ptr<InputEvent> event) override; - void ForwardMouseEvent(std::unique_ptr<InputEvent> event) override; - void ForwardWheelEvent(std::unique_ptr<InputEvent> event) override; - void GestureBegin(std::unique_ptr<InputEvent> event, + void RouteOrProcessMouseEvent( + std::unique_ptr<blink::WebCoalescedInputEvent> event) override; + void RouteOrProcessTouchEvent( + std::unique_ptr<blink::WebCoalescedInputEvent> event) override; + void RouteOrProcessWheelEvent( + std::unique_ptr<blink::WebCoalescedInputEvent> event) override; + void ForwardMouseEvent( + std::unique_ptr<blink::WebCoalescedInputEvent> event) override; + void ForwardWheelEvent( + std::unique_ptr<blink::WebCoalescedInputEvent> event) override; + void GestureBegin(std::unique_ptr<blink::WebCoalescedInputEvent> event, bool is_synthetically_injected) override; - void GestureUpdate(std::unique_ptr<InputEvent> event) override; - void GestureEnd(std::unique_ptr<InputEvent> event) override; - void SmartMagnify(std::unique_ptr<InputEvent> event) override; + void GestureUpdate( + std::unique_ptr<blink::WebCoalescedInputEvent> event) override; + void GestureEnd( + std::unique_ptr<blink::WebCoalescedInputEvent> event) override; + void SmartMagnify( + std::unique_ptr<blink::WebCoalescedInputEvent> event) override; void ImeSetComposition(const base::string16& text, const std::vector<ui::ImeTextSpan>& ime_text_spans, const gfx::Range& replacement_range, @@ -488,8 +497,8 @@ class CONTENT_EXPORT RenderWidgetHostViewMac void OnGotStringForDictionaryOverlay( int32_t targetWidgetProcessId, int32_t targetWidgetRoutingId, - const mac::AttributedStringCoder::EncodedString& encodedString, - gfx::Point baselinePoint); + ui::mojom::AttributedStringPtr attributed_string, + const gfx::Point& baselinePoint); // RenderWidgetHostViewBase: void UpdateBackgroundColor() override; diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_mac.mm b/chromium/content/browser/renderer_host/render_widget_host_view_mac.mm index aaa5daecf14..026bb184e3e 100644 --- a/chromium/content/browser/renderer_host/render_widget_host_view_mac.mm +++ b/chromium/content/browser/renderer_host/render_widget_host_view_mac.mm @@ -39,7 +39,6 @@ #include "content/browser/renderer_host/render_widget_host_input_event_router.h" #import "content/browser/renderer_host/text_input_client_mac.h" #import "content/browser/renderer_host/ui_events_helper.h" -#include "content/common/text_input_state.h" #include "content/common/view_messages.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_plugin_guest_manager.h" @@ -55,6 +54,8 @@ #include "ui/base/cocoa/remote_accessibility_api.h" #import "ui/base/cocoa/secure_password_input.h" #include "ui/base/cocoa/text_services_context_menu.h" +#include "ui/base/ime/mojom/text_input_state.mojom.h" +#include "ui/base/mojom/attributed_string.mojom.h" #include "ui/base/ui_base_features.h" #include "ui/display/display.h" #include "ui/display/screen.h" @@ -555,7 +556,8 @@ void RenderWidgetHostViewMac::OnUpdateTextInputStateCalled( if (!did_update_state) return; - const TextInputState* state = text_input_manager->GetTextInputState(); + const ui::mojom::TextInputState* state = + text_input_manager->GetTextInputState(); if (state) ns_view_->SetTextInputState(state->type, state->flags); else @@ -1890,18 +1892,17 @@ void RenderWidgetHostViewMac::SetRemoteAccessibilityWindowToken( // forward them to the RenderWidgetHostNSViewHostHelper implementation: void RenderWidgetHostViewMac::ForwardKeyboardEventWithCommands( - std::unique_ptr<InputEvent> input_event, + std::unique_ptr<blink::WebCoalescedInputEvent> input_event, const std::vector<uint8_t>& native_event_data, bool skip_in_browser, std::vector<blink::mojom::EditCommandPtr> edit_commands) { - if (!input_event || !input_event->web_event || - !blink::WebInputEvent::IsKeyboardEventType( - input_event->web_event->GetType())) { + if (!input_event || !blink::WebInputEvent::IsKeyboardEventType( + input_event->Event().GetType())) { DLOG(ERROR) << "Absent or non-KeyboardEventType event."; return; } const blink::WebKeyboardEvent& keyboard_event = - static_cast<const blink::WebKeyboardEvent&>(*input_event->web_event); + static_cast<const blink::WebKeyboardEvent&>(input_event->Event()); NativeWebKeyboardEvent native_event(keyboard_event, nil); native_event.skip_in_browser = skip_in_browser; // The NSEvent constructed from the InputEvent sent over mojo is not even @@ -1910,136 +1911,127 @@ void RenderWidgetHostViewMac::ForwardKeyboardEventWithCommands( // https://crbug.com/919167,943197,964052 [native_event.os_event release]; native_event.os_event = [ui::EventFromData(native_event_data) retain]; - ForwardKeyboardEventWithCommands(native_event, input_event->latency_info, + ForwardKeyboardEventWithCommands(native_event, input_event->latency_info(), std::move(edit_commands)); } void RenderWidgetHostViewMac::RouteOrProcessMouseEvent( - std::unique_ptr<InputEvent> input_event) { - if (!input_event || !input_event->web_event || - !blink::WebInputEvent::IsMouseEventType( - input_event->web_event->GetType())) { + std::unique_ptr<blink::WebCoalescedInputEvent> input_event) { + if (!input_event || + !blink::WebInputEvent::IsMouseEventType(input_event->Event().GetType())) { DLOG(ERROR) << "Absent or non-MouseEventType event."; return; } const blink::WebMouseEvent& mouse_event = - static_cast<const blink::WebMouseEvent&>(*input_event->web_event); + static_cast<const blink::WebMouseEvent&>(input_event->Event()); RouteOrProcessMouseEvent(mouse_event); } void RenderWidgetHostViewMac::RouteOrProcessTouchEvent( - std::unique_ptr<InputEvent> input_event) { - if (!input_event || !input_event->web_event || - !blink::WebInputEvent::IsTouchEventType( - input_event->web_event->GetType())) { + std::unique_ptr<blink::WebCoalescedInputEvent> input_event) { + if (!input_event || + !blink::WebInputEvent::IsTouchEventType(input_event->Event().GetType())) { DLOG(ERROR) << "Absent or non-TouchEventType event."; return; } const blink::WebTouchEvent& touch_event = - static_cast<const blink::WebTouchEvent&>(*input_event->web_event); + static_cast<const blink::WebTouchEvent&>(input_event->Event()); RouteOrProcessTouchEvent(touch_event); } void RenderWidgetHostViewMac::RouteOrProcessWheelEvent( - std::unique_ptr<InputEvent> input_event) { - if (!input_event || !input_event->web_event || - input_event->web_event->GetType() != - blink::WebInputEvent::Type::kMouseWheel) { + std::unique_ptr<blink::WebCoalescedInputEvent> input_event) { + if (!input_event || input_event->Event().GetType() != + blink::WebInputEvent::Type::kMouseWheel) { DLOG(ERROR) << "Absent or non-MouseWheel event."; return; } const blink::WebMouseWheelEvent& wheel_event = - static_cast<const blink::WebMouseWheelEvent&>(*input_event->web_event); + static_cast<const blink::WebMouseWheelEvent&>(input_event->Event()); RouteOrProcessWheelEvent(wheel_event); } void RenderWidgetHostViewMac::ForwardMouseEvent( - std::unique_ptr<InputEvent> input_event) { - if (!input_event || !input_event->web_event || - !blink::WebInputEvent::IsMouseEventType( - input_event->web_event->GetType())) { + std::unique_ptr<blink::WebCoalescedInputEvent> input_event) { + if (!input_event || + !blink::WebInputEvent::IsMouseEventType(input_event->Event().GetType())) { DLOG(ERROR) << "Absent or non-MouseEventType event."; return; } const blink::WebMouseEvent& mouse_event = - static_cast<const blink::WebMouseEvent&>(*input_event->web_event); + static_cast<const blink::WebMouseEvent&>(input_event->Event()); ForwardMouseEvent(mouse_event); } void RenderWidgetHostViewMac::ForwardWheelEvent( - std::unique_ptr<InputEvent> input_event) { - if (!input_event || !input_event->web_event || - input_event->web_event->GetType() != - blink::WebInputEvent::Type::kMouseWheel) { + std::unique_ptr<blink::WebCoalescedInputEvent> input_event) { + if (!input_event || input_event->Event().GetType() != + blink::WebInputEvent::Type::kMouseWheel) { DLOG(ERROR) << "Absent or non-MouseWheel event."; return; } const blink::WebMouseWheelEvent& wheel_event = - static_cast<const blink::WebMouseWheelEvent&>(*input_event->web_event); + static_cast<const blink::WebMouseWheelEvent&>(input_event->Event()); ForwardWheelEvent(wheel_event); } void RenderWidgetHostViewMac::GestureBegin( - std::unique_ptr<InputEvent> input_event, + std::unique_ptr<blink::WebCoalescedInputEvent> input_event, bool is_synthetically_injected) { - if (!input_event || !input_event->web_event || - !blink::WebInputEvent::IsGestureEventType( - input_event->web_event->GetType())) { + if (!input_event || !blink::WebInputEvent::IsGestureEventType( + input_event->Event().GetType())) { DLOG(ERROR) << "Absent or non-GestureEventType event."; return; } blink::WebGestureEvent gesture_event = - *static_cast<const blink::WebGestureEvent*>(input_event->web_event.get()); + static_cast<const blink::WebGestureEvent&>(input_event->Event()); // Strip the gesture type, because it is not known. gesture_event.SetType(blink::WebInputEvent::Type::kUndefined); GestureBegin(gesture_event, is_synthetically_injected); } void RenderWidgetHostViewMac::GestureUpdate( - std::unique_ptr<InputEvent> input_event) { - if (!input_event || !input_event->web_event || - !blink::WebInputEvent::IsGestureEventType( - input_event->web_event->GetType())) { + std::unique_ptr<blink::WebCoalescedInputEvent> input_event) { + if (!input_event || !blink::WebInputEvent::IsGestureEventType( + input_event->Event().GetType())) { DLOG(ERROR) << "Absent or non-GestureEventType event."; return; } const blink::WebGestureEvent& gesture_event = - static_cast<const blink::WebGestureEvent&>(*input_event->web_event); + static_cast<const blink::WebGestureEvent&>(input_event->Event()); GestureUpdate(gesture_event); } void RenderWidgetHostViewMac::GestureEnd( - std::unique_ptr<InputEvent> input_event) { - if (!input_event || !input_event->web_event || - !blink::WebInputEvent::IsGestureEventType( - input_event->web_event->GetType())) { + std::unique_ptr<blink::WebCoalescedInputEvent> input_event) { + if (!input_event || !blink::WebInputEvent::IsGestureEventType( + input_event->Event().GetType())) { DLOG(ERROR) << "Absent or non-GestureEventType event."; return; } blink::WebGestureEvent gesture_event = - *static_cast<const blink::WebGestureEvent*>(input_event->web_event.get()); + static_cast<const blink::WebGestureEvent&>(input_event->Event()); GestureEnd(gesture_event); } void RenderWidgetHostViewMac::SmartMagnify( - std::unique_ptr<InputEvent> input_event) { - if (!input_event || !input_event->web_event || - !blink::WebInputEvent::IsGestureEventType( - input_event->web_event->GetType())) { + std::unique_ptr<blink::WebCoalescedInputEvent> input_event) { + if (!input_event || !blink::WebInputEvent::IsGestureEventType( + input_event->Event().GetType())) { DLOG(ERROR) << "Absent or non-GestureEventType event."; return; } const blink::WebGestureEvent& gesture_event = - static_cast<const blink::WebGestureEvent&>(*input_event->web_event); + static_cast<const blink::WebGestureEvent&>(input_event->Event()); SmartMagnify(gesture_event); } void RenderWidgetHostViewMac::OnGotStringForDictionaryOverlay( int32_t target_widget_process_id, int32_t target_widget_routing_id, - const mac::AttributedStringCoder::EncodedString& encoded_string, - gfx::Point baseline_point) { - if (encoded_string.string().empty()) { + ui::mojom::AttributedStringPtr attributed_string, + const gfx::Point& baseline_point) { + if (attributed_string->string.empty()) { // The PDF plugin does not support getting the attributed string at point. // Until it does, use NSPerformService(), which opens Dictionary.app. // TODO(shuchen): Support GetStringAtPoint() & GetStringFromRange() for PDF. @@ -2065,11 +2057,15 @@ void RenderWidgetHostViewMac::OnGotStringForDictionaryOverlay( // https://crbug.com/737032 auto* widget_host = content::RenderWidgetHost::FromID( target_widget_process_id, target_widget_routing_id); + gfx::Point updated_baseline_point = baseline_point; if (widget_host) { - if (auto* rwhv = widget_host->GetView()) - baseline_point = rwhv->TransformPointToRootCoordSpace(baseline_point); + if (auto* rwhv = widget_host->GetView()) { + updated_baseline_point = + rwhv->TransformPointToRootCoordSpace(baseline_point); + } } - ns_view_->ShowDictionaryOverlay(encoded_string, baseline_point); + ns_view_->ShowDictionaryOverlay(std::move(attributed_string), + updated_baseline_point); } } diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper_unittest.mm b/chromium/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper_unittest.mm index 2b0f1135e58..3ed2a550c4b 100644 --- a/chromium/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper_unittest.mm +++ b/chromium/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper_unittest.mm @@ -20,7 +20,6 @@ #include "content/public/test/browser_task_environment.h" #include "content/public/test/mock_render_process_host.h" #include "content/public/test/test_browser_context.h" -#include "content/test/mock_widget_impl.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -147,13 +146,8 @@ TEST_F(RenderWidgetHostViewMacEditCommandHelperWithTaskEnvTest, @autoreleasepool { int32_t routing_id = process_host->GetNextRoutingID(); - mojo::PendingRemote<mojom::Widget> widget; - std::unique_ptr<MockWidgetImpl> widget_impl = - std::make_unique<MockWidgetImpl>( - widget.InitWithNewPipeAndPassReceiver()); - RenderWidgetHostImpl* render_widget = new RenderWidgetHostImpl( - &delegate, process_host, routing_id, std::move(widget), + &delegate, process_host, routing_id, /*hidden=*/false, std::make_unique<FrameTokenMessageQueue>()); ui::WindowResizeHelperMac::Get()->Init(base::ThreadTaskRunnerHandle::Get()); diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm b/chromium/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm index 6286ed4d9e3..b6f3c58d695 100644 --- a/chromium/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm +++ b/chromium/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm @@ -31,7 +31,6 @@ #include "content/browser/renderer_host/render_widget_host_delegate.h" #include "content/browser/renderer_host/text_input_manager.h" #include "content/common/input_messages.h" -#include "content/common/text_input_state.h" #include "content/common/view_messages.h" #include "content/common/widget_messages.h" #include "content/public/browser/browser_task_traits.h" @@ -44,7 +43,7 @@ #include "content/public/test/test_browser_context.h" #include "content/public/test/test_utils.h" #include "content/test/mock_render_widget_host_delegate.h" -#include "content/test/mock_widget_impl.h" +#include "content/test/mock_widget_input_handler.h" #include "content/test/stub_render_widget_host_owner_delegate.h" #include "content/test/test_render_view_host.h" #include "gpu/ipc/common/gpu_messages.h" @@ -56,6 +55,7 @@ #import "third_party/ocmock/OCMock/OCMock.h" #import "third_party/ocmock/ocmock_extensions.h" #include "ui/base/cocoa/secure_password_input.h" +#include "ui/base/ime/mojom/text_input_state.mojom.h" #import "ui/base/test/cocoa_helper.h" #import "ui/base/test/scoped_fake_nswindow_focus.h" #include "ui/base/ui_base_features.h" @@ -221,17 +221,15 @@ blink::WebPointerProperties::PointerType GetPointerType( return blink::WebPointerProperties::PointerType::kUnknown; if (blink::WebInputEvent::IsMouseEventType( - event->Event()->web_event->GetType())) { - return static_cast<const blink::WebMouseEvent*>( - event->Event()->web_event.get()) - ->pointer_type; + event->Event()->Event().GetType())) { + return static_cast<const blink::WebMouseEvent&>(event->Event()->Event()) + .pointer_type; } if (blink::WebInputEvent::IsTouchEventType( - event->Event()->web_event->GetType())) { - return static_cast<const blink::WebTouchEvent*>( - event->Event()->web_event.get()) - ->touches[0] + event->Event()->Event().GetType())) { + return static_cast<const blink::WebTouchEvent&>(event->Event()->Event()) + .touches[0] .pointer_type; } return blink::WebPointerProperties::PointerType::kUnknown; @@ -341,37 +339,28 @@ class MockRenderWidgetHostImpl : public RenderWidgetHostImpl { static MockRenderWidgetHostImpl* Create(RenderWidgetHostDelegate* delegate, RenderProcessHost* process, int32_t routing_id) { - mojo::PendingRemote<mojom::Widget> widget; - std::unique_ptr<MockWidgetImpl> widget_impl = - std::make_unique<MockWidgetImpl>( - widget.InitWithNewPipeAndPassReceiver()); - - return new MockRenderWidgetHostImpl(delegate, process, routing_id, - std::move(widget_impl), - std::move(widget)); + return new MockRenderWidgetHostImpl(delegate, process, routing_id); } - MockWidgetInputHandler* input_handler() { - return widget_impl_->input_handler(); - } + MockWidgetInputHandler* input_handler() { return &input_handler_; } MockWidgetInputHandler::MessageVector GetAndResetDispatchedMessages() { - return input_handler()->GetAndResetDispatchedMessages(); + return input_handler_.GetAndResetDispatchedMessages(); + } + + blink::mojom::WidgetInputHandler* GetWidgetInputHandler() override { + return &input_handler_; } private: MockRenderWidgetHostImpl(RenderWidgetHostDelegate* delegate, RenderProcessHost* process, - int32_t routing_id, - std::unique_ptr<MockWidgetImpl> widget_impl, - mojo::PendingRemote<mojom::Widget> widget) + int32_t routing_id) : RenderWidgetHostImpl(delegate, process, routing_id, - std::move(widget), /*hidden=*/false, - std::make_unique<FrameTokenMessageQueue>()), - widget_impl_(std::move(widget_impl)) { - SetRendererInitialized(true, RendererInitializer::kTest); + std::make_unique<FrameTokenMessageQueue>()) { + set_renderer_initialized(true); lastWheelEventLatencyInfo = ui::LatencyInfo(); ON_CALL(*this, Focus()) @@ -385,7 +374,7 @@ class MockRenderWidgetHostImpl : public RenderWidgetHostImpl { void FocusImpl() { RenderWidgetHostImpl::Focus(); } void BlurImpl() { RenderWidgetHostImpl::Blur(); } - std::unique_ptr<MockWidgetImpl> widget_impl_; + MockWidgetInputHandler input_handler_; DISALLOW_COPY_AND_ASSIGN(MockRenderWidgetHostImpl); }; @@ -532,7 +521,7 @@ class RenderWidgetHostViewMacTest : public RenderViewHostImplTestHarness { void ActivateViewWithTextInputManager(RenderWidgetHostViewBase* view, ui::TextInputType type) { - TextInputState state; + ui::mojom::TextInputState state; state.type = type; view->TextInputStateChanged(state); } @@ -649,14 +638,13 @@ TEST_F(RenderWidgetHostViewMacTest, GetFirstRectForCharacterRangeCaretCase) { gfx::Rect caret_rect(10, 11, 0, 10); gfx::Range caret_range(0, 0); - WidgetHostMsg_SelectionBounds_Params params; gfx::Rect rect; gfx::Range actual_range; rwhv_mac_->SelectionChanged(kDummyString, kDummyOffset, caret_range); - params.anchor_rect = params.focus_rect = caret_rect; - params.anchor_dir = params.focus_dir = base::i18n::LEFT_TO_RIGHT; - rwhv_mac_->SelectionBoundsChanged(params); + rwhv_mac_->SelectionBoundsChanged(caret_rect, base::i18n::LEFT_TO_RIGHT, + caret_rect, base::i18n::LEFT_TO_RIGHT, + false); EXPECT_TRUE(rwhv_mac_->GetCachedFirstRectForCharacterRange(caret_range, &rect, &actual_range)); EXPECT_EQ(caret_rect, rect); @@ -672,9 +660,10 @@ TEST_F(RenderWidgetHostViewMacTest, GetFirstRectForCharacterRangeCaretCase) { // Caret moved. caret_rect = gfx::Rect(20, 11, 0, 10); caret_range = gfx::Range(1, 1); - params.anchor_rect = params.focus_rect = caret_rect; rwhv_mac_->SelectionChanged(kDummyString, kDummyOffset, caret_range); - rwhv_mac_->SelectionBoundsChanged(params); + rwhv_mac_->SelectionBoundsChanged(caret_rect, base::i18n::LEFT_TO_RIGHT, + caret_rect, base::i18n::LEFT_TO_RIGHT, + false); EXPECT_TRUE(rwhv_mac_->GetCachedFirstRectForCharacterRange(caret_range, &rect, &actual_range)); EXPECT_EQ(caret_rect, rect); @@ -690,9 +679,9 @@ TEST_F(RenderWidgetHostViewMacTest, GetFirstRectForCharacterRangeCaretCase) { // No caret. caret_range = gfx::Range(1, 2); rwhv_mac_->SelectionChanged(kDummyString, kDummyOffset, caret_range); - params.anchor_rect = caret_rect; - params.focus_rect = gfx::Rect(30, 11, 0, 10); - rwhv_mac_->SelectionBoundsChanged(params); + rwhv_mac_->SelectionBoundsChanged(caret_rect, base::i18n::LEFT_TO_RIGHT, + gfx::Rect(30, 11, 0, 10), + base::i18n::LEFT_TO_RIGHT, false); EXPECT_FALSE(rwhv_mac_->GetCachedFirstRectForCharacterRange( gfx::Range(0, 0), &rect, &actual_range)); EXPECT_FALSE(rwhv_mac_->GetCachedFirstRectForCharacterRange( @@ -944,6 +933,12 @@ TEST_F(RenderWidgetHostViewMacTest, LastWheelEventLatencyInfoExists) { ASSERT_TRUE(host_->lastWheelEventLatencyInfo.FindLatency( ui::INPUT_EVENT_LATENCY_UI_COMPONENT, nullptr)); + MockWidgetInputHandler::MessageVector events = + host_->GetAndResetDispatchedMessages(); + EXPECT_EQ("MouseWheel", GetMessageNames(events)); + events[0]->ToEvent()->CallCallback( + blink::mojom::InputEventResultState::kNotConsumed); + // Send a wheel event with phaseEnded. // Verifies that ui::INPUT_EVENT_LATENCY_UI_COMPONENT is added // properly in shortCircuitScrollWheelEvent function which is called @@ -952,6 +947,9 @@ TEST_F(RenderWidgetHostViewMacTest, LastWheelEventLatencyInfoExists) { [rwhv_mac_->GetInProcessNSView() scrollWheel:wheelEvent2]; ASSERT_TRUE(host_->lastWheelEventLatencyInfo.FindLatency( ui::INPUT_EVENT_LATENCY_UI_COMPONENT, nullptr)); + + events = host_->GetAndResetDispatchedMessages(); + EXPECT_EQ("GestureScrollBegin GestureScrollUpdate", GetMessageNames(events)); } TEST_F(RenderWidgetHostViewMacTest, SourceEventTypeExistsInLatencyInfo) { @@ -961,6 +959,13 @@ TEST_F(RenderWidgetHostViewMacTest, SourceEventTypeExistsInLatencyInfo) { // Verifies that SourceEventType exists in forwarded LatencyInfo object. NSEvent* wheelEvent = MockScrollWheelEventWithPhase(@selector(phaseBegan), 3); [rwhv_mac_->GetInProcessNSView() scrollWheel:wheelEvent]; + + MockWidgetInputHandler::MessageVector events = + host_->GetAndResetDispatchedMessages(); + EXPECT_EQ("MouseWheel", GetMessageNames(events)); + events[0]->ToEvent()->CallCallback( + blink::mojom::InputEventResultState::kConsumed); + ASSERT_TRUE(host_->lastWheelEventLatencyInfo.source_event_type() == ui::SourceEventType::WHEEL); } @@ -1053,9 +1058,9 @@ TEST_F(RenderWidgetHostViewMacTest, PointerEventWithPenTypeNoTabletEvent) { events = host_->GetAndResetDispatchedMessages(); ASSERT_EQ("MouseMove", GetMessageNames(events)); EXPECT_EQ(blink::WebPointerProperties::PointerType::kPen, - static_cast<const blink::WebMouseEvent*>( - events[0]->ToEvent()->Event()->web_event.get()) - ->pointer_type); + static_cast<const blink::WebMouseEvent&>( + events[0]->ToEvent()->Event()->Event()) + .pointer_type); } TEST_F(RenderWidgetHostViewMacTest, PointerEventWithMouseType) { @@ -1119,9 +1124,9 @@ TEST_F(RenderWidgetHostViewMacTest, PointerEventWithPenTypeSendAsTouch) { events = host_->GetAndResetDispatchedMessages(); ASSERT_EQ("TouchEnd GestureScrollEnd", GetMessageNames(events)); EXPECT_EQ(blink::WebPointerProperties::PointerType::kPen, - static_cast<const blink::WebTouchEvent*>( - events[0]->ToEvent()->Event()->web_event.get()) - ->touches[0] + static_cast<const blink::WebTouchEvent&>( + events[0]->ToEvent()->Event()->Event()) + .touches[0] .pointer_type); events.clear(); @@ -1264,9 +1269,9 @@ TEST_F(RenderWidgetHostViewMacTest, TimerBasedPhaseInfo) { // Both GSB and GSU will be sent since GestureEventQueue allows multiple // in-flight events. ASSERT_EQ("GestureScrollBegin GestureScrollUpdate", GetMessageNames(events)); - ASSERT_TRUE(static_cast<const blink::WebGestureEvent*>( - events[0]->ToEvent()->Event()->web_event.get()) - ->data.scroll_begin.synthetic); + ASSERT_TRUE(static_cast<const blink::WebGestureEvent&>( + events[0]->ToEvent()->Event()->Event()) + .data.scroll_begin.synthetic); events.clear(); // Wait for the mouse_wheel_end_dispatch_timer_ to expire, the pending wheel @@ -1279,9 +1284,9 @@ TEST_F(RenderWidgetHostViewMacTest, TimerBasedPhaseInfo) { events = host_->GetAndResetDispatchedMessages(); ASSERT_EQ("MouseWheel GestureScrollEnd", GetMessageNames(events)); - ASSERT_TRUE(static_cast<const blink::WebGestureEvent*>( - events[1]->ToEvent()->Event()->web_event.get()) - ->data.scroll_end.synthetic); + ASSERT_TRUE(static_cast<const blink::WebGestureEvent&>( + events[1]->ToEvent()->Event()->Event()) + .data.scroll_end.synthetic); } // With wheel scroll latching wheel end events are not sent immediately, instead @@ -1682,6 +1687,13 @@ TEST_F(RenderWidgetHostViewMacTest, EventLatencyOSMouseWheelHistogram) { // Verify that Event.Latency.OS.MOUSE_WHEEL histogram is computed properly. NSEvent* wheelEvent = MockScrollWheelEventWithPhase(@selector(phaseBegan),3); [rwhv_mac_->GetInProcessNSView() scrollWheel:wheelEvent]; + + MockWidgetInputHandler::MessageVector events = + host_->GetAndResetDispatchedMessages(); + EXPECT_EQ("MouseWheel", GetMessageNames(events)); + events[0]->ToEvent()->CallCallback( + blink::mojom::InputEventResultState::kConsumed); + histogram_tester.ExpectTotalCount("Event.Latency.OS.MOUSE_WHEEL", 1); } @@ -1737,7 +1749,7 @@ class InputMethodMacTest : public RenderWidgetHostViewMacTest { void SetTextInputType(RenderWidgetHostViewBase* view, ui::TextInputType type) { - TextInputState state; + ui::mojom::TextInputState state; state.type = type; view->TextInputStateChanged(state); } @@ -1975,7 +1987,7 @@ TEST_F(InputMethodMacTest, MonitorCompositionRangeForActiveWidget) { [window_ makeFirstResponder:tab_GetInProcessNSView()]; EXPECT_TRUE(tab_view()->HasFocus()); - TextInputState state; + ui::mojom::TextInputState state; state.type = ui::TEXT_INPUT_TYPE_TEXT; // Make the tab's widget active. diff --git a/chromium/content/browser/renderer_host/render_widget_targeter.cc b/chromium/content/browser/renderer_host/render_widget_targeter.cc index 61923072729..0d1dd07d192 100644 --- a/chromium/content/browser/renderer_host/render_widget_targeter.cc +++ b/chromium/content/browser/renderer_host/render_widget_targeter.cc @@ -46,6 +46,9 @@ bool IsMouseMiddleClick(const blink::WebInputEvent& event) { constexpr const char kTracingCategory[] = "input,latency"; +constexpr base::TimeDelta kAsyncHitTestTimeout = + base::TimeDelta::FromSeconds(5); + } // namespace class TracingUmaTracker { @@ -169,7 +172,8 @@ const ui::LatencyInfo& RenderWidgetTargeter::TargetingRequest::GetLatency() } RenderWidgetTargeter::RenderWidgetTargeter(Delegate* delegate) - : trace_id_(base::RandUint64()), + : async_hit_test_timeout_delay_(kAsyncHitTestTimeout), + trace_id_(base::RandUint64()), is_viz_hit_testing_debug_enabled_( features::IsVizHitTestingDebugEnabled()), delegate_(delegate) { @@ -293,11 +297,11 @@ void RenderWidgetTargeter::QueryClient( RenderWidgetHostViewBase* last_request_target, const gfx::PointF& last_target_location, TargetingRequest request) { - auto* target_client = target->host()->input_target_client(); + auto& target_client = target->host()->input_target_client(); // |target_client| may not be set yet for this |target| on Mac, need to // understand why this happens. https://crbug.com/859492. // We do not verify hit testing result under this circumstance. - if (!target_client) { + if (!target_client.get() || !target_client.is_connected()) { FoundTarget(target, target_location, false, &request); return; } @@ -314,6 +318,10 @@ void RenderWidgetTargeter::QueryClient( last_target_location), async_hit_test_timeout_delay_)); + target_client.set_disconnect_handler(base::BindOnce( + &RenderWidgetTargeter::OnInputTargetDisconnect, + weak_ptr_factory_.GetWeakPtr(), target->GetWeakPtr(), target_location)); + TRACE_EVENT_WITH_FLOW2( "viz,benchmark", "Event.Pipeline", TRACE_ID_GLOBAL(trace_id_), TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "step", @@ -370,6 +378,8 @@ void RenderWidgetTargeter::FoundFrameSinkId( request_in_flight_.reset(); async_hit_test_timeout_.reset(nullptr); + target->host()->input_target_client().set_disconnect_handler( + base::OnceClosure()); if (is_viz_hit_testing_debug_enabled_ && request.IsWebInputEventRequest() && request.GetEvent()->GetType() == blink::WebInputEvent::Type::kMouseDown) { @@ -455,10 +465,16 @@ void RenderWidgetTargeter::AsyncHitTestTimedOut( if (!request.GetRootView()) return; - // Mark view as unresponsive so further events will not be sent to it. - if (current_request_target) + if (current_request_target) { + // Mark view as unresponsive so further events will not be sent to it. unresponsive_views_.insert(current_request_target.get()); + // Reset disconnect handler for view. + current_request_target->host() + ->input_target_client() + .set_disconnect_handler(base::OnceClosure()); + } + if (request.GetRootView() == current_request_target.get()) { // When a request to the top-level frame times out then the event gets // sent there anyway. It will trigger the hung renderer dialog if the @@ -471,4 +487,19 @@ void RenderWidgetTargeter::AsyncHitTestTimedOut( } } +void RenderWidgetTargeter::OnInputTargetDisconnect( + base::WeakPtr<RenderWidgetHostViewBase> target, + const gfx::PointF& location) { + if (!async_hit_test_timeout_) + return; + + async_hit_test_timeout_.reset(nullptr); + TargetingRequest request = std::move(request_in_flight_.value()); + request_in_flight_.reset(); + + // Since we couldn't find the target frame among the child-frames + // we process the event in the current frame. + FoundTarget(target.get(), location, false, &request); +} + } // namespace content diff --git a/chromium/content/browser/renderer_host/render_widget_targeter.h b/chromium/content/browser/renderer_host/render_widget_targeter.h index 7b29f17ba03..f10c18ba9c5 100644 --- a/chromium/content/browser/renderer_host/render_widget_targeter.h +++ b/chromium/content/browser/renderer_host/render_widget_targeter.h @@ -12,7 +12,6 @@ #include "base/time/time.h" #include "components/viz/common/surfaces/frame_sink_id.h" #include "content/browser/renderer_host/render_widget_host_view_base.h" -#include "content/common/content_constants_internal.h" #include "content/common/content_export.h" #include "ui/events/blink/web_input_event_traits.h" #include "ui/latency/latency_info.h" @@ -218,6 +217,9 @@ class RenderWidgetTargeter { base::WeakPtr<RenderWidgetHostViewBase> last_request_target, const gfx::PointF& last_target_location); + void OnInputTargetDisconnect(base::WeakPtr<RenderWidgetHostViewBase> target, + const gfx::PointF& location); + HitTestResultsMatch GetHitTestResultsMatchBucket( RenderWidgetHostViewBase* target, TargetingRequest* request) const; @@ -244,8 +246,7 @@ class RenderWidgetTargeter { // This value limits how long to wait for a response from the renderer // process before giving up and resuming event processing. - base::TimeDelta async_hit_test_timeout_delay_ = - base::TimeDelta::FromMilliseconds(kAsyncHitTestTimeoutMs); + base::TimeDelta async_hit_test_timeout_delay_; std::unique_ptr<OneShotTimeoutMonitor> async_hit_test_timeout_; diff --git a/chromium/content/browser/renderer_host/text_input_client_mac.h b/chromium/content/browser/renderer_host/text_input_client_mac.h index 8efa3de2f68..0f7abe46c59 100644 --- a/chromium/content/browser/renderer_host/text_input_client_mac.h +++ b/chromium/content/browser/renderer_host/text_input_client_mac.h @@ -5,12 +5,13 @@ #ifndef CONTENT_BROWSER_RENDERER_HOST_TEXT_INPUT_CLIENT_MAC_H_ #define CONTENT_BROWSER_RENDERER_HOST_TEXT_INPUT_CLIENT_MAC_H_ +#include "base/callback.h" #include "base/mac/scoped_block.h" #include "base/macros.h" #include "base/synchronization/condition_variable.h" #include "base/synchronization/lock.h" #include "content/common/content_export.h" -#include "content/common/mac/attributed_string_coder.h" +#include "ui/base/mojom/attributed_string.mojom-forward.h" #include "ui/gfx/geometry/point.h" #include "ui/gfx/geometry/rect.h" @@ -73,8 +74,8 @@ class CONTENT_EXPORT TextInputClientMac { void SetCharacterIndexAndSignal(uint32_t index); void SetFirstRectAndSignal(const gfx::Rect& first_rect); - typedef base::OnceCallback< - void(const mac::AttributedStringCoder::EncodedString&, gfx::Point)> + typedef base::OnceCallback<void(ui::mojom::AttributedStringPtr, + const gfx::Point&)> GetStringCallback; // This async method is invoked from RenderWidgetHostViewCocoa's @@ -89,9 +90,8 @@ class CONTENT_EXPORT TextInputClientMac { // This is called on the IO thread when we get the renderer's reply for // GetStringAtPoint. - void GetStringAtPointReply( - const mac::AttributedStringCoder::EncodedString& string, - const gfx::Point& point); + void GetStringAtPointReply(ui::mojom::AttributedStringPtr string, + const gfx::Point& point); // This async method is invoked when browser tries to retreive the text for // certain range and doesn't want to wait for the reply from blink. @@ -105,9 +105,8 @@ class CONTENT_EXPORT TextInputClientMac { // This is called on the IO thread when we get the renderer's reply for // GetStringFromRange. - void GetStringFromRangeReply( - const mac::AttributedStringCoder::EncodedString& string, - const gfx::Point& point); + void GetStringFromRangeReply(ui::mojom::AttributedStringPtr string, + const gfx::Point& point); private: friend struct base::DefaultSingletonTraits<TextInputClientMac>; diff --git a/chromium/content/browser/renderer_host/text_input_client_mac.mm b/chromium/content/browser/renderer_host/text_input_client_mac.mm index dfeda3de781..07a1b7a18ef 100644 --- a/chromium/content/browser/renderer_host/text_input_client_mac.mm +++ b/chromium/content/browser/renderer_host/text_input_client_mac.mm @@ -13,11 +13,10 @@ #include "content/browser/frame_host/frame_tree.h" #include "content/browser/frame_host/frame_tree_node.h" #include "content/browser/frame_host/render_frame_host_impl.h" -#include "content/browser/renderer_host/render_view_host_delegate.h" -#include "content/browser/renderer_host/render_view_host_impl.h" #include "content/browser/renderer_host/render_widget_host_delegate.h" #include "content/browser/renderer_host/render_widget_host_impl.h" #include "content/common/text_input_client_messages.h" +#include "ui/base/mojom/attributed_string.mojom.h" namespace content { @@ -51,15 +50,14 @@ bool IsFullScreenRenderWidget(RenderWidgetHost* widget) { } RenderFrameHostImpl* GetFocusedRenderFrameHostImpl(RenderWidgetHost* widget) { - RenderViewHostImpl* rvhi = RenderViewHostImpl::From(widget); - if (!rvhi || !rvhi->GetDelegate()->GetFrameTree()) - return nullptr; - FrameTreeNode* frame_tree_node = - rvhi->GetDelegate()->GetFrameTree()->GetFocusedFrame(); - return frame_tree_node ? frame_tree_node->current_frame_host() : nullptr; -} + RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From(widget); + FrameTree* tree = rwhi->delegate()->GetFrameTree(); + FrameTreeNode* focused_node = tree->GetFocusedFrame(); + return focused_node ? focused_node->current_frame_host() : nullptr; } +} // namespace + // The amount of time in milliseconds that the browser process will wait for a // response from the renderer. // TODO(rsesek): Using the histogram data, find the best upper-bound for this @@ -92,10 +90,10 @@ void TextInputClientMac::GetStringAtPoint(RenderWidgetHost* rwh, } void TextInputClientMac::GetStringAtPointReply( - const mac::AttributedStringCoder::EncodedString& string, + ui::mojom::AttributedStringPtr string, const gfx::Point& point) { if (replyForPointHandler_) { - std::move(replyForPointHandler_).Run(string, point); + std::move(replyForPointHandler_).Run(std::move(string), point); } } @@ -110,10 +108,10 @@ void TextInputClientMac::GetStringFromRange(RenderWidgetHost* rwh, } void TextInputClientMac::GetStringFromRangeReply( - const mac::AttributedStringCoder::EncodedString& string, + ui::mojom::AttributedStringPtr string, const gfx::Point& point) { if (replyForRangeHandler_) { - std::move(replyForRangeHandler_).Run(string, point); + std::move(replyForRangeHandler_).Run(std::move(string), point); } } diff --git a/chromium/content/browser/renderer_host/text_input_client_mac_unittest.mm b/chromium/content/browser/renderer_host/text_input_client_mac_unittest.mm index feefe3cbcb2..67121d5758e 100644 --- a/chromium/content/browser/renderer_host/text_input_client_mac_unittest.mm +++ b/chromium/content/browser/renderer_host/text_input_client_mac_unittest.mm @@ -8,6 +8,7 @@ #include <stdint.h> #include "base/bind.h" +#include "base/optional.h" #include "base/run_loop.h" #include "base/single_thread_task_runner.h" #include "base/threading/thread.h" @@ -74,7 +75,7 @@ class TextInputClientMacTest : public content::RenderViewHostTestHarness { content::RenderViewHostTestHarness::SetUp(); local_frame_ = std::make_unique<TextInputClientLocalFrame>(web_contents()); RenderViewHostTester::For(rvh())->CreateTestRenderView( - base::string16(), MSG_ROUTING_NONE, MSG_ROUTING_NONE, false); + base::nullopt, MSG_ROUTING_NONE, false); widget_ = rvh()->GetWidget(); FocusWebContentsOnMainFrame(); } diff --git a/chromium/content/browser/renderer_host/text_input_client_message_filter.h b/chromium/content/browser/renderer_host/text_input_client_message_filter.h index 218266845dc..73e07a92a71 100644 --- a/chromium/content/browser/renderer_host/text_input_client_message_filter.h +++ b/chromium/content/browser/renderer_host/text_input_client_message_filter.h @@ -8,9 +8,9 @@ #include <stddef.h> #include "base/macros.h" -#include "content/common/mac/attributed_string_coder.h" #include "content/public/browser/browser_message_filter.h" #include "content/public/browser/browser_thread.h" +#include "ui/base/mojom/attributed_string.mojom-forward.h" namespace gfx { class Point; @@ -36,11 +36,10 @@ class CONTENT_EXPORT TextInputClientMessageFilter private: // IPC Message handlers: - void OnGotStringAtPoint( - const mac::AttributedStringCoder::EncodedString& encoded_string, - const gfx::Point& point); + void OnGotStringAtPoint(const ui::mojom::AttributedString& attributed_string, + const gfx::Point& point); void OnGotStringFromRange( - const mac::AttributedStringCoder::EncodedString& string, + const ui::mojom::AttributedString& attributed_string, const gfx::Point& point); DISALLOW_COPY_AND_ASSIGN(TextInputClientMessageFilter); diff --git a/chromium/content/browser/renderer_host/text_input_client_message_filter.mm b/chromium/content/browser/renderer_host/text_input_client_message_filter.mm index 11c4f93d479..270dff9cf0e 100644 --- a/chromium/content/browser/renderer_host/text_input_client_message_filter.mm +++ b/chromium/content/browser/renderer_host/text_input_client_message_filter.mm @@ -10,6 +10,7 @@ #include "content/common/text_input_client_messages.h" #include "content/public/browser/render_widget_host_view.h" #include "ipc/ipc_message_macros.h" +#include "ui/base/mojom/attributed_string.mojom.h" #include "ui/gfx/geometry/point.h" #include "ui/gfx/range/range.h" @@ -45,17 +46,17 @@ void TextInputClientMessageFilter::OverrideThreadForMessage( TextInputClientMessageFilter::~TextInputClientMessageFilter() {} void TextInputClientMessageFilter::OnGotStringAtPoint( - const mac::AttributedStringCoder::EncodedString& encoded_string, + const ui::mojom::AttributedString& attributed_string, const gfx::Point& point) { TextInputClientMac* service = TextInputClientMac::GetInstance(); - service->GetStringAtPointReply(encoded_string, point); + service->GetStringAtPointReply(attributed_string.Clone(), point); } void TextInputClientMessageFilter::OnGotStringFromRange( - const mac::AttributedStringCoder::EncodedString& encoded_string, + const ui::mojom::AttributedString& attributed_string, const gfx::Point& point) { TextInputClientMac* service = TextInputClientMac::GetInstance(); - service->GetStringFromRangeReply(encoded_string, point); + service->GetStringFromRangeReply(attributed_string.Clone(), point); } } // namespace content diff --git a/chromium/content/browser/renderer_host/text_input_manager.cc b/chromium/content/browser/renderer_host/text_input_manager.cc index cab2b8c321f..d6915460fb1 100644 --- a/chromium/content/browser/renderer_host/text_input_manager.cc +++ b/chromium/content/browser/renderer_host/text_input_manager.cc @@ -14,8 +14,8 @@ namespace content { namespace { -bool ShouldUpdateTextInputState(const content::TextInputState& old_state, - const content::TextInputState& new_state) { +bool ShouldUpdateTextInputState(const ui::mojom::TextInputState& old_state, + const ui::mojom::TextInputState& new_state) { #if defined(USE_AURA) return old_state.type != new_state.type || old_state.mode != new_state.mode || old_state.flags != new_state.flags || @@ -61,7 +61,7 @@ RenderWidgetHostImpl* TextInputManager::GetActiveWidget() const { : nullptr; } -const TextInputState* TextInputManager::GetTextInputState() const { +const ui::mojom::TextInputState* TextInputManager::GetTextInputState() const { return !!active_view_ ? &text_input_state_map_.at(active_view_) : nullptr; } @@ -91,7 +91,7 @@ const TextInputManager::TextSelection* TextInputManager::GetTextSelection( void TextInputManager::UpdateTextInputState( RenderWidgetHostViewBase* view, - const TextInputState& text_input_state) { + const ui::mojom::TextInputState& text_input_state) { DCHECK(IsRegistered(view)); if (text_input_state.type == ui::TEXT_INPUT_TYPE_NONE && @@ -153,40 +153,42 @@ void TextInputManager::ImeCancelComposition(RenderWidgetHostViewBase* view) { void TextInputManager::SelectionBoundsChanged( RenderWidgetHostViewBase* view, - const WidgetHostMsg_SelectionBounds_Params& params) { + const gfx::Rect& anchor_rect, + base::i18n::TextDirection anchor_dir, + const gfx::Rect& focus_rect, + base::i18n::TextDirection focus_dir, + bool is_anchor_first) { DCHECK(IsRegistered(view)); // Converting the anchor point to root's coordinate space (for child frame // views). gfx::Point anchor_origin_transformed = - view->TransformPointToRootCoordSpace(params.anchor_rect.origin()); + view->TransformPointToRootCoordSpace(anchor_rect.origin()); gfx::SelectionBound anchor_bound, focus_bound; anchor_bound.SetEdge(gfx::PointF(anchor_origin_transformed), gfx::PointF(view->TransformPointToRootCoordSpace( - params.anchor_rect.bottom_left()))); - focus_bound.SetEdge(gfx::PointF(view->TransformPointToRootCoordSpace( - params.focus_rect.origin())), - gfx::PointF(view->TransformPointToRootCoordSpace( - params.focus_rect.bottom_left()))); + anchor_rect.bottom_left()))); + focus_bound.SetEdge( + gfx::PointF(view->TransformPointToRootCoordSpace(focus_rect.origin())), + gfx::PointF( + view->TransformPointToRootCoordSpace(focus_rect.bottom_left()))); - if (params.anchor_rect == params.focus_rect) { + if (anchor_rect == focus_rect) { anchor_bound.set_type(gfx::SelectionBound::CENTER); focus_bound.set_type(gfx::SelectionBound::CENTER); } else { // Whether text is LTR at the anchor handle. - bool anchor_LTR = params.anchor_dir == base::i18n::LEFT_TO_RIGHT; + bool anchor_LTR = anchor_dir == base::i18n::LEFT_TO_RIGHT; // Whether text is LTR at the focus handle. - bool focus_LTR = params.focus_dir == base::i18n::LEFT_TO_RIGHT; + bool focus_LTR = focus_dir == base::i18n::LEFT_TO_RIGHT; - if ((params.is_anchor_first && anchor_LTR) || - (!params.is_anchor_first && !anchor_LTR)) { + if ((is_anchor_first && anchor_LTR) || (!is_anchor_first && !anchor_LTR)) { anchor_bound.set_type(gfx::SelectionBound::LEFT); } else { anchor_bound.set_type(gfx::SelectionBound::RIGHT); } - if ((params.is_anchor_first && focus_LTR) || - (!params.is_anchor_first && !focus_LTR)) { + if ((is_anchor_first && focus_LTR) || (!is_anchor_first && !focus_LTR)) { focus_bound.set_type(gfx::SelectionBound::RIGHT); } else { focus_bound.set_type(gfx::SelectionBound::LEFT); @@ -200,15 +202,14 @@ void TextInputManager::SelectionBoundsChanged( selection_region_map_[view].anchor = anchor_bound; selection_region_map_[view].focus = focus_bound; - if (params.anchor_rect == params.focus_rect) { + if (anchor_rect == focus_rect) { selection_region_map_[view].caret_rect.set_origin( anchor_origin_transformed); - selection_region_map_[view].caret_rect.set_size(params.anchor_rect.size()); + selection_region_map_[view].caret_rect.set_size(anchor_rect.size()); } selection_region_map_[view].first_selection_rect.set_origin( anchor_origin_transformed); - selection_region_map_[view].first_selection_rect.set_size( - params.anchor_rect.size()); + selection_region_map_[view].first_selection_rect.set_size(anchor_rect.size()); NotifySelectionBoundsChanged(view); } @@ -256,7 +257,7 @@ void TextInputManager::SelectionChanged(RenderWidgetHostViewBase* view, void TextInputManager::Register(RenderWidgetHostViewBase* view) { DCHECK(!IsRegistered(view)); - text_input_state_map_[view] = TextInputState(); + text_input_state_map_[view] = ui::mojom::TextInputState(); selection_region_map_[view] = SelectionRegion(); composition_range_info_map_[view] = CompositionRangeInfo(); text_selection_map_[view] = TextSelection(); diff --git a/chromium/content/browser/renderer_host/text_input_manager.h b/chromium/content/browser/renderer_host/text_input_manager.h index ff2aac26c4f..8afe82074cb 100644 --- a/chromium/content/browser/renderer_host/text_input_manager.h +++ b/chromium/content/browser/renderer_host/text_input_manager.h @@ -8,16 +8,15 @@ #include <unordered_map> #include <utility> +#include "base/i18n/rtl.h" #include "base/observer_list.h" #include "base/strings/string16.h" #include "content/common/content_export.h" -#include "content/common/text_input_state.h" +#include "ui/base/ime/mojom/text_input_state.mojom.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/range/range.h" #include "ui/gfx/selection_bound.h" -struct WidgetHostMsg_SelectionBounds_Params; - namespace content { class RenderWidgetHostImpl; @@ -148,7 +147,7 @@ class CONTENT_EXPORT TextInputManager { // Returns the currently stored TextInputState for |active_view_|. A state of // nullptr can be interpreted as a ui::TextInputType of // ui::TEXT_INPUT_TYPE_NONE. - const TextInputState* GetTextInputState() const; + const ui::mojom::TextInputState* GetTextInputState() const; // Returns the selection bounds information for |view|. If |view| == nullptr, // it will return the corresponding information for |active_view_| or nullptr @@ -172,7 +171,7 @@ class CONTENT_EXPORT TextInputManager { // Updates the TextInputState for |view|. void UpdateTextInputState(RenderWidgetHostViewBase* view, - const TextInputState& state); + const ui::mojom::TextInputState& state); // The current IME composition has been cancelled on the renderer side for // the widget corresponding to |view|. @@ -181,9 +180,12 @@ class CONTENT_EXPORT TextInputManager { // Updates the selection bounds for the |view|. In Aura, selection bounds are // used to provide the InputMethod with the position of the caret, e.g., in // setting the position of the ui::ImeWindow. - void SelectionBoundsChanged( - RenderWidgetHostViewBase* view, - const WidgetHostMsg_SelectionBounds_Params& params); + void SelectionBoundsChanged(RenderWidgetHostViewBase* view, + const gfx::Rect& anchor_rect, + base::i18n::TextDirection anchor_dir, + const gfx::Rect& focus_rect, + base::i18n::TextDirection focus_dir, + bool is_anchor_first); // Notify observers that the selection bounds have been updated. This is also // called when a view with a selection is reactivated. @@ -251,7 +253,7 @@ class CONTENT_EXPORT TextInputManager { // The following maps track corresponding IME state for views. For each view, // the values in the map are initialized and cleared in Register and // Unregister methods, respectively. - ViewMap<TextInputState> text_input_state_map_; + ViewMap<ui::mojom::TextInputState> text_input_state_map_; ViewMap<SelectionRegion> selection_region_map_; ViewMap<CompositionRangeInfo> composition_range_info_map_; ViewMap<TextSelection> text_selection_map_; diff --git a/chromium/content/browser/renderer_host/virtual_keyboard_controller_win.cc b/chromium/content/browser/renderer_host/virtual_keyboard_controller_win.cc new file mode 100644 index 00000000000..da7df8a8e09 --- /dev/null +++ b/chromium/content/browser/renderer_host/virtual_keyboard_controller_win.cc @@ -0,0 +1,155 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/renderer_host/virtual_keyboard_controller_win.h" + +#include "base/trace_event/trace_event.h" +#include "content/browser/renderer_host/render_widget_host_view_aura.h" +#include "ui/base/ime/input_method.h" +#include "ui/base/ime/input_method_keyboard_controller.h" +#include "ui/base/ime/mojom/text_input_state.mojom.h" +#include "ui/events/event_utils.h" +#include "ui/gfx/geometry/rect.h" + +namespace content { + +VirtualKeyboardControllerWin::VirtualKeyboardControllerWin( + RenderWidgetHostViewAura* host_view, + ui::InputMethod* input_method) + : host_view_(host_view), input_method_(input_method) { + host_view_->SetInsets(gfx::Insets()); +} + +VirtualKeyboardControllerWin::~VirtualKeyboardControllerWin() { + if (observers_registered_) { + // De-register the input pane observers. + if (auto* controller = input_method_->GetInputMethodKeyboardController()) + controller->RemoveObserver(this); + } +} + +void VirtualKeyboardControllerWin::HideAndNotifyKeyboardInset() { + if (auto* controller = input_method_->GetInputMethodKeyboardController()) { + if (virtual_keyboard_shown_) { + // If the VK is already showing, then dismiss it first. + controller->DismissVirtualKeyboard(); + // Should also scroll the content into view after the VK dismisses. + OnKeyboardHidden(); + } + } +} + +void VirtualKeyboardControllerWin::OnKeyboardVisible( + const gfx::Rect& keyboard_rect) { + TRACE_EVENT0("vk", "VirtualKeyboardControllerWin::OnKeyboardVisible"); + // If the software input panel (SIP) is manually raised by the user, the flag + // should be set so we don't call TryShow API again. + virtual_keyboard_shown_ = true; + if (!host_view_->ShouldVirtualKeyboardOverlayContent()) { + host_view_->SetInsets(gfx::Insets( + 0, 0, keyboard_rect.IsEmpty() ? 0 : keyboard_rect.height(), 0)); + } else { + host_view_->NotifyVirtualKeyboardOverlayRect(keyboard_rect); + } +} + +void VirtualKeyboardControllerWin::OnKeyboardHidden() { + TRACE_EVENT0("vk", "VirtualKeyboardControllerWin::OnKeyboardHidden"); + // If the software input panel (SIP) is manually closed by the user, the flag + // should be reset so we don't call TryHide API again. Also, + // next time user taps on an editable element after manually dismissing the + // keyboard, this flag is used to determine whether TryShow needs to be + // called or not. Calling TryShow/TryHide multiple times leads to SIP + // flickering. + virtual_keyboard_shown_ = false; + if (!host_view_->ShouldVirtualKeyboardOverlayContent()) { + // Restore the viewport. + host_view_->SetInsets(gfx::Insets()); + } else { + host_view_->NotifyVirtualKeyboardOverlayRect(gfx::Rect()); + } +} + +void VirtualKeyboardControllerWin::ShowVirtualKeyboard() { + TRACE_EVENT0("vk", "VirtualKeyboardControllerWin::ShowVirtualKeyboard"); + if (auto* controller = input_method_->GetInputMethodKeyboardController()) { + if (!virtual_keyboard_shown_) { + virtual_keyboard_shown_ = true; + input_method_->ShowVirtualKeyboardIfEnabled(); + } + } +} + +void VirtualKeyboardControllerWin::HideVirtualKeyboard() { + TRACE_EVENT0("vk", "VirtualKeyboardControllerWin::HideVirtualKeyboard"); + if (auto* controller = input_method_->GetInputMethodKeyboardController()) { + if (virtual_keyboard_shown_) { + virtual_keyboard_shown_ = false; + controller->DismissVirtualKeyboard(); + } + } +} + +void VirtualKeyboardControllerWin::UpdateTextInputState( + const ui::mojom::TextInputState* state) { + // Conditions to show the VK: + // 1. User has to interact with the editable element. + // 2. Pointer type has to be either touch or pen. + // 3. Accessibility has set focus on an editable element. + // 4. If virtualkeyboardpolicy is manual, leave the SIP in its current state - + // script authors need to call show() or hide() explicitly to trigger SIP + // actions. + // 5. If virtualkeyboardpolicy is auto, show the SIP. + // If there are no keyboard controllers or the pointer type is neither pen or + // touch or accessibility has not set focus into an editable element, then + // don't change the state of the keyboard. + auto* controller = input_method_->GetInputMethodKeyboardController(); + is_manual_policy_ = + state->vk_policy == ui::mojom::VirtualKeyboardPolicy::MANUAL; + if (!controller || + !(IsPointerTypeValidForVirtualKeyboard() || is_manual_policy_) || + !host_view_->host()->GetView() || !host_view_->host()->delegate()) { + return; + } + // Register the observers if the pointer type is pen/touch. + if (!observers_registered_) { + controller->AddObserver(this); + observers_registered_ = true; + } + if (state->show_ime_if_needed && + state->vk_policy == ui::mojom::VirtualKeyboardPolicy::AUTO) { + ShowVirtualKeyboard(); + return; + } + + if (is_manual_policy_) { + switch (state->last_vk_visibility_request) { + case ui::mojom::VirtualKeyboardVisibilityRequest::SHOW: + if (host_view_->FocusedFrameHasStickyActivation()) + ShowVirtualKeyboard(); + break; + case ui::mojom::VirtualKeyboardVisibilityRequest::HIDE: + HideVirtualKeyboard(); + break; + default: + // Don't change the state of the VK. + break; + } + } +} + +void VirtualKeyboardControllerWin::FocusedNodeChanged(bool is_editable) { + if (!is_editable) { + HideVirtualKeyboard(); + return; + } +} + +bool VirtualKeyboardControllerWin::IsPointerTypeValidForVirtualKeyboard() + const { + return (host_view_->GetLastPointerType() == ui::EventPointerType::kTouch || + host_view_->GetLastPointerType() == ui::EventPointerType::kPen); +} + +} // namespace content diff --git a/chromium/content/browser/renderer_host/virtual_keyboard_controller_win.h b/chromium/content/browser/renderer_host/virtual_keyboard_controller_win.h new file mode 100644 index 00000000000..fc84199c261 --- /dev/null +++ b/chromium/content/browser/renderer_host/virtual_keyboard_controller_win.h @@ -0,0 +1,68 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_BROWSER_RENDERER_HOST_VIRTUAL_KEYBOARD_CONTROLLER_WIN_H_ +#define CONTENT_BROWSER_RENDERER_HOST_VIRTUAL_KEYBOARD_CONTROLLER_WIN_H_ + +#include "base/macros.h" +#include "content/browser/renderer_host/render_widget_host_impl.h" +#include "ui/base/ime/input_method_keyboard_controller_observer.h" + +namespace gfx { +class Rect; +} + +namespace ui { +namespace mojom { +class TextInputState; +} +class InputMethod; +} + +namespace content { + +class RenderWidgetHostViewAura; + +// This class implements the ui::InputMethodKeyboardControllerObserver interface +// which provides notifications about the on-screen keyboard on Windows getting +// displayed or hidden in response to taps on editable fields. +// It provides functionality to request blink to scroll the input field if it +// is obscured by the on screen keyboard. +// TryShow/TryHide APIs are Windows system APIs that are used to show/hide VK +// respectively. +// https://docs.microsoft.com/en-us/uwp/api/windows.ui.viewmanagement.inputpane?view=winrt-18362 +class VirtualKeyboardControllerWin + : public ui::InputMethodKeyboardControllerObserver { + public: + VirtualKeyboardControllerWin(RenderWidgetHostViewAura* host_view, + ui::InputMethod* input_method); + VirtualKeyboardControllerWin(const VirtualKeyboardControllerWin&) = delete; + ~VirtualKeyboardControllerWin() override; + + VirtualKeyboardControllerWin& operator=(const VirtualKeyboardControllerWin&) = + delete; + + void UpdateTextInputState(const ui::mojom::TextInputState* state); + void FocusedNodeChanged(bool is_editable); + void HideAndNotifyKeyboardInset(); + + // InputMethodKeyboardControllerObserver overrides. + void OnKeyboardVisible(const gfx::Rect& keyboard_rect) override; + void OnKeyboardHidden() override; + + private: + void ShowVirtualKeyboard(); + void HideVirtualKeyboard(); + bool IsPointerTypeValidForVirtualKeyboard() const; + + RenderWidgetHostViewAura* host_view_; + ui::InputMethod* input_method_; + bool observers_registered_ = false; + bool virtual_keyboard_shown_ = false; + bool is_manual_policy_ = false; +}; + +} // namespace content + +#endif // CONTENT_BROWSER_RENDERER_HOST_VIRTUAL_KEYBOARD_CONTROLLER_WIN_H_ diff --git a/chromium/content/browser/renderer_host/web_database_host_impl.cc b/chromium/content/browser/renderer_host/web_database_host_impl.cc index 4da497e7265..dc49916a2ed 100644 --- a/chromium/content/browser/renderer_host/web_database_host_impl.cc +++ b/chromium/content/browser/renderer_host/web_database_host_impl.cc @@ -11,7 +11,6 @@ #include "base/check_op.h" #include "base/metrics/histogram_macros.h" #include "base/strings/utf_string_conversions.h" -#include "base/task/post_task.h" #include "content/browser/child_process_security_policy_impl.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" @@ -446,8 +445,8 @@ blink::mojom::WebDatabase& WebDatabaseHostImpl::GetWebDatabase() { if (!database_provider_) { // The interface binding needs to occur on the UI thread, as we can // only call RenderProcessHost::FromID() on the UI thread. - base::PostTask( - FROM_HERE, {BrowserThread::UI}, + GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce( [](int process_id, mojo::PendingReceiver<blink::mojom::WebDatabase> receiver) { @@ -467,8 +466,8 @@ void WebDatabaseHostImpl::ValidateOrigin(const url::Origin& origin, return; } - base::PostTask( - FROM_HERE, {BrowserThread::UI}, + GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&ValidateOriginOnUIThread, process_id_, origin, base::RetainedRef(db_tracker_->task_runner()), std::move(callback), mojo::GetBadMessageCallback())); diff --git a/chromium/content/browser/renderer_host/web_database_host_impl_unittest.cc b/chromium/content/browser/renderer_host/web_database_host_impl_unittest.cc index 85e2788d6e2..f588d8a993a 100644 --- a/chromium/content/browser/renderer_host/web_database_host_impl_unittest.cc +++ b/chromium/content/browser/renderer_host/web_database_host_impl_unittest.cc @@ -15,7 +15,7 @@ #include "content/public/test/mock_render_process_host.h" #include "content/public/test/test_browser_context.h" #include "content/test/fake_mojo_message_dispatch_context.h" -#include "mojo/core/embedder/embedder.h" +#include "mojo/public/cpp/system/functions.h" #include "mojo/public/cpp/test_support/test_utils.h" #include "storage/common/database/database_identifier.h" #include "testing/gtest/include/gtest/gtest.h" @@ -115,8 +115,8 @@ class WebDatabaseHostImplTest : public ::testing::Test { }; TEST_F(WebDatabaseHostImplTest, BadMessagesUnauthorized) { - const url::Origin correct_origin = - url::Origin::Create(GURL("http://correct.com")); + const GURL correct_url("http://correct.com"); + const url::Origin correct_origin = url::Origin::Create(correct_url); const url::Origin incorrect_origin = url::Origin::Create(GURL("http://incorrect.net")); const base::string16 db_name(base::ASCIIToUTF16("db_name")); @@ -128,9 +128,8 @@ TEST_F(WebDatabaseHostImplTest, BadMessagesUnauthorized) { security_policy->AddIsolatedOrigins( {correct_origin, incorrect_origin}, ChildProcessSecurityPolicy::IsolatedOriginSource::TEST); - - security_policy->LockToOrigin(IsolationContext(browser_context()), - process_id(), correct_origin.GetURL()); + security_policy->LockProcessForTesting(IsolationContext(browser_context()), + process_id(), correct_url); ASSERT_TRUE( security_policy->CanAccessDataForOrigin(process_id(), correct_origin)); ASSERT_FALSE( @@ -202,8 +201,8 @@ TEST_F(WebDatabaseHostImplTest, BadMessagesInvalid) { } TEST_F(WebDatabaseHostImplTest, ProcessShutdown) { - const url::Origin correct_origin = - url::Origin::Create(GURL("http://correct.com")); + const GURL correct_url("http://correct.com"); + const url::Origin correct_origin = url::Origin::Create(correct_url); const url::Origin incorrect_origin = url::Origin::Create(GURL("http://incorrect.net")); const base::string16 db_name(base::ASCIIToUTF16("db_name")); @@ -215,15 +214,15 @@ TEST_F(WebDatabaseHostImplTest, ProcessShutdown) { security_policy->AddIsolatedOrigins( {correct_origin, incorrect_origin}, ChildProcessSecurityPolicy::IsolatedOriginSource::TEST); - security_policy->LockToOrigin(IsolationContext(browser_context()), - process_id(), correct_origin.GetURL()); + security_policy->LockProcessForTesting(IsolationContext(browser_context()), + process_id(), correct_url); bool success_callback_was_called = false; auto success_callback = base::BindLambdaForTesting( [&](base::File) { success_callback_was_called = true; }); base::Optional<std::string> error_callback_message; - mojo::core::SetDefaultProcessErrorCallback(base::BindLambdaForTesting( + mojo::SetDefaultProcessErrorHandler(base::BindLambdaForTesting( [&](const std::string& message) { error_callback_message = message; })); // Verify that an error occurs with OpenFile() call before process shutdown. @@ -269,8 +268,7 @@ TEST_F(WebDatabaseHostImplTest, ProcessShutdown) { EXPECT_FALSE(error_callback_message.has_value()); } - mojo::core::SetDefaultProcessErrorCallback( - mojo::core::ProcessErrorCallback()); + mojo::SetDefaultProcessErrorHandler(base::NullCallback()); } } // namespace content |