blob: ee00de73c68de5db0a829880c318660e7dbde503 [file] [log] [blame]
Avi Drissman4e1b7bc32022-09-15 14:03:501// Copyright 2017 The Chromium Authors
sunyunjiabbea8a92017-08-31 11:18:542// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "content/browser/android/overscroll_controller_android.h"
Kartar Singh30ae5d52024-11-28 17:13:166
sunyunjiabbea8a92017-08-31 11:18:547#include <memory>
Kartar Singh30ae5d52024-11-28 17:13:168
Keishi Hattori0e45c022021-11-27 09:25:529#include "base/memory/raw_ptr.h"
Jinsuk Kimd04b59e42019-01-25 02:44:3610#include "cc/input/overscroll_behavior.h"
sunyunjiabbea8a92017-08-31 11:18:5411#include "cc/layers/layer.h"
Kartar Singh30ae5d52024-11-28 17:13:1612#include "gpu/ipc/common/surface_handle.h"
sunyunjiabbea8a92017-08-31 11:18:5413#include "testing/gmock/include/gmock/gmock.h"
14#include "testing/gtest/include/gtest/gtest.h"
Dave Tapuska129cef82019-12-19 16:36:4815#include "third_party/blink/public/common/input/web_gesture_event.h"
16#include "third_party/blink/public/common/input/web_input_event.h"
sunyunjiabbea8a92017-08-31 11:18:5417#include "ui/android/overscroll_glow.h"
18#include "ui/android/overscroll_refresh.h"
19#include "ui/android/resources/resource_manager_impl.h"
20#include "ui/android/window_android_compositor.h"
Sandra Sun3fbdd1632017-09-05 15:01:4721#include "ui/events/base_event_utils.h"
sunyunjiabbea8a92017-08-31 11:18:5422#include "ui/events/blink/did_overscroll_params.h"
23
Andrew Grieve68dd21b42020-07-16 17:54:0724using ::testing::_;
25using ::testing::Return;
26using ui::EdgeEffect;
sunyunjiabbea8a92017-08-31 11:18:5427using ui::OverscrollGlow;
28using ui::OverscrollGlowClient;
29using ui::OverscrollRefresh;
Andrew Grieve68dd21b42020-07-16 17:54:0730using ui::ResourceManager;
sunyunjiabbea8a92017-08-31 11:18:5431using ui::WindowAndroidCompositor;
sunyunjiabbea8a92017-08-31 11:18:5432
33namespace content {
34
sunyunjiabbea8a92017-08-31 11:18:5435class MockCompositor : public WindowAndroidCompositor {
36 public:
William Liu3ac45a3c2023-05-11 18:35:2837 ~MockCompositor() override = default;
William Liuf38f2a72024-10-06 04:02:4438 ui::WindowAndroidCompositor::ScopedKeepSurfaceAliveCallback
39 TakeScopedKeepSurfaceAliveCallback(const viz::SurfaceId&) override {
40 return base::OnceClosure();
William Liu3ac45a3c2023-05-11 18:35:2841 }
sunyunjiabbea8a92017-08-31 11:18:5442 void RequestCopyOfOutputOnRootLayer(
43 std::unique_ptr<viz::CopyOutputRequest>) override {}
44 void SetNeedsAnimate() override {}
45 MOCK_METHOD0(GetResourceManager, ResourceManager&());
46 MOCK_METHOD0(GetFrameSinkId, viz::FrameSinkId());
Kartar Singh30ae5d52024-11-28 17:13:1647 gpu::SurfaceHandle GetSurfaceHandle() override {
48 return gpu::kNullSurfaceHandle;
49 }
sunyunjiabbea8a92017-08-31 11:18:5450 void AddChildFrameSink(const viz::FrameSinkId& frame_sink_id) override {}
51 void RemoveChildFrameSink(const viz::FrameSinkId& frame_sink_id) override {}
Eric Karl465a5252018-01-10 21:16:2752 bool IsDrawingFirstVisibleFrame() const override { return false; }
Khushala0424812019-03-13 10:05:4353 void OnUpdateRefreshRate(float refresh_rate) override {}
Khushal51874322019-04-18 23:55:4054 void OnUpdateSupportedRefreshRates(
55 const std::vector<float>& supported_refresh_rates) override {}
Bo Liu15828fe42025-03-13 01:34:4456 void OnAdaptiveRefreshRateInfoChanged() override {}
Clark DuVall3d91432d2021-12-07 20:29:4457 std::unique_ptr<ui::CompositorLock> GetCompositorLock(
58 base::TimeDelta timeout) override {
59 return nullptr;
60 }
sangheon77.kimdd441f92022-08-31 01:15:0861 void OnUpdateOverlayTransform() override {}
Mohsen Izadicc482292023-02-01 16:18:5762 void PostRequestSuccessfulPresentationTimeForNextFrame(
63 SuccessfulPresentationTimeCallback callback) override {}
Peilin Wanga1e9e2ea2024-05-14 14:44:5964 void AddFrameSubmissionObserver(FrameSubmissionObserver* observer) override {}
65 void RemoveFrameSubmissionObserver(
66 FrameSubmissionObserver* observer) override {}
sunyunjiabbea8a92017-08-31 11:18:5467};
68
69class MockGlowClient : public OverscrollGlowClient {
70 public:
Andrew Grieve68dd21b42020-07-16 17:54:0771 MOCK_METHOD0(CreateEdgeEffect, std::unique_ptr<EdgeEffect>());
sunyunjiabbea8a92017-08-31 11:18:5472};
73
74class MockGlow : public OverscrollGlow {
75 public:
76 MockGlow() : OverscrollGlow(new MockGlowClient()) {}
77 MOCK_METHOD5(OnOverscrolled,
78 bool(base::TimeTicks,
79 gfx::Vector2dF,
80 gfx::Vector2dF,
81 gfx::Vector2dF,
82 gfx::Vector2dF));
83};
84
85class MockRefresh : public OverscrollRefresh {
86 public:
87 MockRefresh() : OverscrollRefresh() {}
Aman Verma5508a3bc02025-03-24 13:15:3988 MOCK_METHOD2(OnOverscrolled,
89 void(const cc::OverscrollBehavior& behavior,
90 gfx::Vector2dF accumulated_overscroll));
sunyunjiabbea8a92017-08-31 11:18:5491 MOCK_METHOD0(Reset, void());
92 MOCK_CONST_METHOD0(IsActive, bool());
93 MOCK_CONST_METHOD0(IsAwaitingScrollUpdateAck, bool());
94};
95
96class OverscrollControllerAndroidUnitTest : public testing::Test {
97 public:
98 OverscrollControllerAndroidUnitTest() {
Jaebaek Seod055eca2018-01-31 00:57:4299 dip_scale_ = 560;
Jeremy Roman04f27c372017-10-27 15:20:55100 std::unique_ptr<MockGlow> glow_ptr = std::make_unique<MockGlow>();
101 std::unique_ptr<MockRefresh> refresh_ptr = std::make_unique<MockRefresh>();
102 compositor_ = std::make_unique<MockCompositor>();
sunyunjiabbea8a92017-08-31 11:18:54103 glow_ = glow_ptr.get();
104 refresh_ = refresh_ptr.get();
105 controller_ = OverscrollControllerAndroid::CreateForTests(
Jaebaek Seod055eca2018-01-31 00:57:42106 compositor_.get(), dip_scale_, std::move(glow_ptr),
107 std::move(refresh_ptr));
sunyunjiabbea8a92017-08-31 11:18:54108 }
109
110 ui::DidOverscrollParams CreateVerticalOverscrollParams() {
111 ui::DidOverscrollParams params;
112 params.accumulated_overscroll = gfx::Vector2dF(0, 1);
113 params.latest_overscroll_delta = gfx::Vector2dF(0, 1);
114 params.current_fling_velocity = gfx::Vector2dF(0, 1);
115 params.causal_event_viewport_point = gfx::PointF(100, 100);
Chris Harrelson317f1842022-03-23 19:04:17116 params.accumulated_overscroll.Scale(dip_scale_);
117 params.latest_overscroll_delta.Scale(dip_scale_);
118 params.current_fling_velocity.Scale(dip_scale_);
119 params.causal_event_viewport_point.Scale(dip_scale_);
120
sunyunjiabbea8a92017-08-31 11:18:54121 return params;
122 }
123
124 protected:
Keishi Hattori0e45c022021-11-27 09:25:52125 raw_ptr<MockGlow> glow_;
Nan Lin3c319052024-06-13 17:18:38126 raw_ptr<MockRefresh> refresh_;
sunyunjiabbea8a92017-08-31 11:18:54127 std::unique_ptr<MockCompositor> compositor_;
128 std::unique_ptr<OverscrollControllerAndroid> controller_;
Jaebaek Seod055eca2018-01-31 00:57:42129 float dip_scale_;
sunyunjiabbea8a92017-08-31 11:18:54130};
131
132TEST_F(OverscrollControllerAndroidUnitTest,
Jinsuk Kimd04b59e42019-01-25 02:44:36133 OverscrollBehaviorYAutoAllowsRefresh) {
sunyunjiabbea8a92017-08-31 11:18:54134 ui::DidOverscrollParams params = CreateVerticalOverscrollParams();
Xida Chen209548b2020-09-01 16:18:51135 params.overscroll_behavior.y = cc::OverscrollBehavior::Type::kAuto;
sunyunjiabbea8a92017-08-31 11:18:54136
Jinsuk Kimd04b59e42019-01-25 02:44:36137 // Test that refresh is activated but glow is not rendered.
sunyunjiabbea8a92017-08-31 11:18:54138 EXPECT_CALL(*refresh_, IsActive()).WillOnce(Return(true));
139 EXPECT_CALL(*refresh_, IsAwaitingScrollUpdateAck()).Times(0);
140 EXPECT_CALL(*glow_, OnOverscrolled(_, _, _, _, _)).Times(0);
141
142 controller_->OnOverscrolled(params);
143 testing::Mock::VerifyAndClearExpectations(&refresh_);
144}
145
146TEST_F(OverscrollControllerAndroidUnitTest,
Jinsuk Kimd04b59e42019-01-25 02:44:36147 OverscrollBehaviorYContainAllowsGlowOnly) {
sunyunjiabbea8a92017-08-31 11:18:54148 ui::DidOverscrollParams params = CreateVerticalOverscrollParams();
Xida Chen209548b2020-09-01 16:18:51149 params.overscroll_behavior.y = cc::OverscrollBehavior::Type::kContain;
sunyunjiabbea8a92017-08-31 11:18:54150
sunyunjiabbea8a92017-08-31 11:18:54151 EXPECT_CALL(*refresh_, IsActive()).WillOnce(Return(false));
152 EXPECT_CALL(*refresh_, IsAwaitingScrollUpdateAck()).WillOnce(Return(false));
153 EXPECT_CALL(*glow_,
154 OnOverscrolled(_, gfx::Vector2dF(0, 560), gfx::Vector2dF(0, 560),
155 gfx::Vector2dF(0, 560), _));
156
157 controller_->OnOverscrolled(params);
158 testing::Mock::VerifyAndClearExpectations(refresh_);
159 testing::Mock::VerifyAndClearExpectations(glow_);
160
161 // Test that the "contain" set on x-axis would not affect navigation.
Xida Chen209548b2020-09-01 16:18:51162 params.overscroll_behavior.y = cc::OverscrollBehavior::Type::kAuto;
163 params.overscroll_behavior.x = cc::OverscrollBehavior::Type::kContain;
sunyunjiabbea8a92017-08-31 11:18:54164
sunyunjiabbea8a92017-08-31 11:18:54165 EXPECT_CALL(*refresh_, IsActive()).WillOnce(Return(true));
166 EXPECT_CALL(*refresh_, IsAwaitingScrollUpdateAck()).Times(0);
167 EXPECT_CALL(*glow_, OnOverscrolled(_, _, _, _, _)).Times(0);
168
169 controller_->OnOverscrolled(params);
170 testing::Mock::VerifyAndClearExpectations(refresh_);
171 testing::Mock::VerifyAndClearExpectations(glow_);
172}
173
174TEST_F(OverscrollControllerAndroidUnitTest,
Jinsuk Kimd04b59e42019-01-25 02:44:36175 OverscrollBehaviorYNonePreventsGlowAndRefresh) {
sunyunjiabbea8a92017-08-31 11:18:54176 ui::DidOverscrollParams params = CreateVerticalOverscrollParams();
Xida Chen209548b2020-09-01 16:18:51177 params.overscroll_behavior.y = cc::OverscrollBehavior::Type::kNone;
sunyunjiabbea8a92017-08-31 11:18:54178
sunyunjiabbea8a92017-08-31 11:18:54179 EXPECT_CALL(*refresh_, IsActive()).WillOnce(Return(false));
180 EXPECT_CALL(*refresh_, IsAwaitingScrollUpdateAck()).WillOnce(Return(false));
181 EXPECT_CALL(*glow_, OnOverscrolled(_, gfx::Vector2dF(), gfx::Vector2dF(),
182 gfx::Vector2dF(), _));
183
184 controller_->OnOverscrolled(params);
185 testing::Mock::VerifyAndClearExpectations(refresh_);
186 testing::Mock::VerifyAndClearExpectations(glow_);
187
188 // Test that the "none" set on y-axis would not affect glow on x-axis.
189 params.accumulated_overscroll = gfx::Vector2dF(1, 1);
190 params.latest_overscroll_delta = gfx::Vector2dF(1, 1);
191 params.current_fling_velocity = gfx::Vector2dF(1, 1);
Chris Harrelson317f1842022-03-23 19:04:17192 params.accumulated_overscroll.Scale(dip_scale_);
193 params.latest_overscroll_delta.Scale(dip_scale_);
194 params.current_fling_velocity.Scale(dip_scale_);
sunyunjiabbea8a92017-08-31 11:18:54195
sunyunjiabbea8a92017-08-31 11:18:54196 EXPECT_CALL(*refresh_, IsActive()).WillOnce(Return(false));
197 EXPECT_CALL(*refresh_, IsAwaitingScrollUpdateAck()).WillOnce(Return(false));
198 EXPECT_CALL(*glow_,
199 OnOverscrolled(_, gfx::Vector2dF(560, 0), gfx::Vector2dF(560, 0),
200 gfx::Vector2dF(560, 0), _));
201
202 controller_->OnOverscrolled(params);
203 testing::Mock::VerifyAndClearExpectations(refresh_);
204 testing::Mock::VerifyAndClearExpectations(glow_);
205}
206
Sandra Sun3fbdd1632017-09-05 15:01:47207TEST_F(OverscrollControllerAndroidUnitTest,
Aman Verma5508a3bc02025-03-24 13:15:39208 ConsumedBeginDoesNotResetEnabledRefresh) {
Sandra Sun3fbdd1632017-09-05 15:01:47209 ui::DidOverscrollParams params = CreateVerticalOverscrollParams();
Xida Chen209548b2020-09-01 16:18:51210 params.overscroll_behavior.y = cc::OverscrollBehavior::Type::kAuto;
Sandra Sun3fbdd1632017-09-05 15:01:47211
Sandra Sun3fbdd1632017-09-05 15:01:47212 EXPECT_CALL(*refresh_, IsActive()).WillOnce(Return(true));
213 EXPECT_CALL(*refresh_, IsAwaitingScrollUpdateAck()).WillOnce(Return(false));
Sandra Sun3fbdd1632017-09-05 15:01:47214
215 // Enable the refresh effect.
216 controller_->OnOverscrolled(params);
217
Aman Verma5508a3bc02025-03-24 13:15:39218 // Generate a consumed scroll begin.
219 blink::WebGestureEvent event(blink::WebInputEvent::Type::kGestureScrollBegin,
Daniel Cheng224569ee2018-04-25 05:45:06220 blink::WebInputEvent::kNoModifiers,
221 ui::EventTimeForNow());
Dave Tapuskae01e0fde2020-04-20 18:28:41222 controller_->OnGestureEventAck(
223 event, blink::mojom::InputEventResultState::kConsumed);
Sandra Sun3fbdd1632017-09-05 15:01:47224
225 testing::Mock::VerifyAndClearExpectations(&refresh_);
226}
227
Sandra Sun2288e8532017-11-30 22:50:16228} // namespace content