
There are two headers to declare features in content. - the public one: `content/public/common/content_features.h` - the private one: `content/common/features.h`. Unfortunately, most are declared in the public one, despite being used privately exclusively. This violate the `content/public/` rules. This patches provides a fix. Parts of this patch was made programmatically using this script: https://paste.googleplex.com/6699322946093056, with the following output: https://paste.googleplex.com/5591288895242240 This patch: 1. Update `docs/how_to_add_your_feature_flag.md` to incentive developers to the non public versions. 2. Move ~70 features back into the private version. 3. Programmatically update the includes to include the correct #include header(s). 4. For consistency and minimizing the amount of files modified, the two headers to use the `features::` namespace. AX-Relnotes: n/a. Change-Id: Id9126a95dfbc533d4778b188b659b5acc9b3d9e3 Bug: None Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4836057 Reviewed-by: Alex Moshchuk <alexmos@chromium.org> Commit-Queue: Arthur Sonzogni <arthursonzogni@chromium.org> Cr-Commit-Position: refs/heads/main@{#1194718}
779 lines
33 KiB
C++
779 lines
33 KiB
C++
// Copyright 2017 The Chromium Authors
|
|
// 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/overscroll_controller.h"
|
|
|
|
#include <memory>
|
|
|
|
#include "base/containers/queue.h"
|
|
#include "base/test/scoped_feature_list.h"
|
|
#include "content/browser/renderer_host/overscroll_controller_delegate.h"
|
|
#include "content/common/features.h"
|
|
#include "content/public/browser/overscroll_configuration.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 {
|
|
|
|
class OverscrollControllerTest : public ::testing::Test {
|
|
public:
|
|
OverscrollControllerTest(const OverscrollControllerTest&) = delete;
|
|
OverscrollControllerTest& operator=(const OverscrollControllerTest&) = delete;
|
|
|
|
protected:
|
|
OverscrollControllerTest() {}
|
|
~OverscrollControllerTest() override {}
|
|
|
|
void SetUp() override {
|
|
OverscrollConfig::ResetTouchpadOverscrollHistoryNavigationEnabled();
|
|
scoped_feature_list_.InitAndEnableFeature(
|
|
features::kTouchpadOverscrollHistoryNavigation);
|
|
delegate_ = std::make_unique<TestOverscrollDelegate>(gfx::Size(400, 300));
|
|
controller_ = std::make_unique<OverscrollController>();
|
|
controller_->set_delegate(delegate_->GetWeakPtr());
|
|
}
|
|
|
|
void TearDown() override {
|
|
controller_ = nullptr;
|
|
delegate_ = nullptr;
|
|
}
|
|
|
|
// Creates and sends a mouse-wheel event to the overscroll controller. Returns
|
|
// |true| if the event is consumed by the overscroll controller.
|
|
bool SimulateMouseWheel(float dx, float dy) {
|
|
DCHECK(!current_event_);
|
|
current_event_ = std::make_unique<blink::WebMouseWheelEvent>(
|
|
blink::SyntheticWebMouseWheelEventBuilder::Build(
|
|
0, 0, dx, dy, 0, ui::ScrollGranularity::kScrollByPrecisePixel));
|
|
return controller_->WillHandleEvent(*current_event_);
|
|
}
|
|
|
|
// Creates and sends a gesture event to the overscroll controller. Returns
|
|
// |true| if the event is consumed by the overscroll controller.
|
|
bool SimulateGestureEvent(blink::WebInputEvent::Type type,
|
|
blink::WebGestureDevice source_device,
|
|
base::TimeTicks timestamp) {
|
|
DCHECK(!current_event_);
|
|
current_event_ = std::make_unique<blink::WebGestureEvent>(
|
|
blink::SyntheticWebGestureEventBuilder::Build(type, source_device));
|
|
current_event_->SetTimeStamp(timestamp);
|
|
return controller_->WillHandleEvent(*current_event_);
|
|
}
|
|
|
|
// Creates and sends a gesture-scroll-update event to the overscroll
|
|
// controller. Returns |true| if the event is consumed by the overscroll
|
|
// controller.
|
|
bool SimulateGestureScrollUpdate(float dx,
|
|
float dy,
|
|
blink::WebGestureDevice device,
|
|
base::TimeTicks timestamp,
|
|
bool inertial_update) {
|
|
DCHECK(!current_event_);
|
|
auto event = std::make_unique<blink::WebGestureEvent>(
|
|
blink::SyntheticWebGestureEventBuilder::BuildScrollUpdate(dx, dy, 0,
|
|
device));
|
|
event->SetTimeStamp(timestamp);
|
|
if (inertial_update) {
|
|
event->data.scroll_update.inertial_phase =
|
|
blink::WebGestureEvent::InertialPhaseState::kMomentum;
|
|
}
|
|
current_event_ = std::move(event);
|
|
return controller_->WillHandleEvent(*current_event_);
|
|
}
|
|
|
|
// Creates and sends a gesture-fling-start event to the overscroll controller.
|
|
// Returns |true| if the event is consumed by the overscroll controller.
|
|
bool SimulateGestureFlingStart(float velocity_x,
|
|
float velocity_y,
|
|
blink::WebGestureDevice device,
|
|
base::TimeTicks timestamp) {
|
|
DCHECK(!current_event_);
|
|
current_event_ = std::make_unique<blink::WebGestureEvent>(
|
|
blink::SyntheticWebGestureEventBuilder::BuildFling(velocity_x,
|
|
velocity_y, device));
|
|
current_event_->SetTimeStamp(timestamp);
|
|
return controller_->WillHandleEvent(*current_event_);
|
|
}
|
|
|
|
// Notifies the overscroll controller that the current event is ACKed.
|
|
void SimulateAck(bool processed) {
|
|
DCHECK(current_event_);
|
|
controller_->ReceivedEventACK(*current_event_, processed);
|
|
current_event_ = nullptr;
|
|
}
|
|
|
|
TestOverscrollDelegate* delegate() const { return delegate_.get(); }
|
|
|
|
OverscrollMode controller_mode() const {
|
|
return controller_->overscroll_mode_;
|
|
}
|
|
|
|
OverscrollSource controller_source() const {
|
|
return controller_->overscroll_source_;
|
|
}
|
|
|
|
private:
|
|
std::unique_ptr<TestOverscrollDelegate> delegate_;
|
|
std::unique_ptr<OverscrollController> controller_;
|
|
|
|
// Keeps track of the last event that has been processed by the overscroll
|
|
// controller which is not yet ACKed. Will be null if no event is processed or
|
|
// the last event is ACKed.
|
|
std::unique_ptr<blink::WebInputEvent> current_event_;
|
|
|
|
base::test::ScopedFeatureList scoped_feature_list_;
|
|
};
|
|
|
|
// Tests that if a mouse-wheel is consumed by content before overscroll is
|
|
// initiated, overscroll will not initiate anymore.
|
|
TEST_F(OverscrollControllerTest, MouseWheelConsumedPreventsOverscroll) {
|
|
const base::TimeTicks timestamp =
|
|
blink::WebInputEvent::GetStaticTimeStampForTests();
|
|
|
|
// Simulate a mouse-wheel, ACK it as not processed, simulate the corresponding
|
|
// gesture scroll-update event, and ACK it as not processed. Since it is not
|
|
// passing the start threshold, no overscroll should happen.
|
|
EXPECT_FALSE(SimulateMouseWheel(10, 0));
|
|
SimulateAck(false);
|
|
EXPECT_FALSE(SimulateGestureScrollUpdate(
|
|
10, 0, blink::WebGestureDevice::kTouchpad, timestamp, false));
|
|
SimulateAck(false);
|
|
EXPECT_EQ(OVERSCROLL_NONE, controller_mode());
|
|
EXPECT_EQ(OverscrollSource::NONE, controller_source());
|
|
EXPECT_EQ(OVERSCROLL_NONE, delegate()->current_mode());
|
|
EXPECT_EQ(OVERSCROLL_NONE, delegate()->completed_mode());
|
|
|
|
// Simulate a mouse-wheel and ACK it as processed. No gesture scroll-update
|
|
// needs to be simulated. Still no overscroll.
|
|
EXPECT_FALSE(SimulateMouseWheel(10, 0));
|
|
SimulateAck(true);
|
|
EXPECT_EQ(OVERSCROLL_NONE, controller_mode());
|
|
EXPECT_EQ(OverscrollSource::NONE, controller_source());
|
|
EXPECT_EQ(OVERSCROLL_NONE, delegate()->current_mode());
|
|
EXPECT_EQ(OVERSCROLL_NONE, delegate()->completed_mode());
|
|
|
|
// Simulate a mouse-wheel and the corresponding gesture scroll-update both
|
|
// ACKed as not processed. Although the scroll passes overscroll start
|
|
// threshold, no overscroll should happen since the previous mouse-wheel was
|
|
// marked as processed.
|
|
EXPECT_FALSE(SimulateMouseWheel(100, 0));
|
|
SimulateAck(false);
|
|
EXPECT_FALSE(SimulateGestureScrollUpdate(
|
|
100, 0, blink::WebGestureDevice::kTouchpad, timestamp, false));
|
|
SimulateAck(false);
|
|
EXPECT_EQ(OVERSCROLL_NONE, controller_mode());
|
|
EXPECT_EQ(OverscrollSource::NONE, controller_source());
|
|
EXPECT_EQ(OVERSCROLL_NONE, delegate()->current_mode());
|
|
EXPECT_EQ(OVERSCROLL_NONE, delegate()->completed_mode());
|
|
}
|
|
|
|
// Verifying the inertial scroll event completes overscroll. After that we will
|
|
// ignore the following inertial scroll events until new sequence start.
|
|
TEST_F(OverscrollControllerTest,
|
|
InertialGestureScrollUpdateCompletesOverscroll) {
|
|
const base::TimeTicks timestamp =
|
|
blink::WebInputEvent::GetStaticTimeStampForTests();
|
|
|
|
EXPECT_FALSE(
|
|
SimulateGestureEvent(blink::WebInputEvent::Type::kGestureScrollBegin,
|
|
blink::WebGestureDevice::kTouchpad, timestamp));
|
|
SimulateAck(false);
|
|
|
|
EXPECT_FALSE(SimulateGestureScrollUpdate(
|
|
200, 0, blink::WebGestureDevice::kTouchpad, timestamp, false));
|
|
SimulateAck(false);
|
|
EXPECT_EQ(OVERSCROLL_EAST, controller_mode());
|
|
EXPECT_EQ(OverscrollSource::TOUCHPAD, controller_source());
|
|
EXPECT_EQ(OVERSCROLL_EAST, delegate()->current_mode());
|
|
EXPECT_EQ(OVERSCROLL_NONE, delegate()->completed_mode());
|
|
|
|
// Inertial update event complete the overscroll action.
|
|
EXPECT_FALSE(SimulateGestureScrollUpdate(
|
|
100, 0, blink::WebGestureDevice::kTouchpad, timestamp, true));
|
|
SimulateAck(false);
|
|
EXPECT_EQ(OVERSCROLL_NONE, controller_mode());
|
|
EXPECT_EQ(OverscrollSource::NONE, controller_source());
|
|
EXPECT_EQ(OVERSCROLL_NONE, delegate()->current_mode());
|
|
EXPECT_EQ(OVERSCROLL_EAST, delegate()->completed_mode());
|
|
|
|
// Next Inertial update event would be consumed by overscroll controller.
|
|
EXPECT_TRUE(SimulateGestureScrollUpdate(
|
|
100, 0, blink::WebGestureDevice::kTouchpad, timestamp, true));
|
|
}
|
|
|
|
// Ensure inertial gesture scroll update can not start overscroll.
|
|
TEST_F(OverscrollControllerTest, InertialGSUsDoNotStartOverscroll) {
|
|
base::TimeTicks timestamp =
|
|
blink::WebInputEvent::GetStaticTimeStampForTests();
|
|
// Inertial update event complete the overscroll action.
|
|
EXPECT_FALSE(SimulateGestureScrollUpdate(
|
|
100, 0, blink::WebGestureDevice::kTouchpad, timestamp, true));
|
|
SimulateAck(false);
|
|
EXPECT_EQ(OVERSCROLL_NONE, controller_mode());
|
|
EXPECT_EQ(OverscrollSource::NONE, controller_source());
|
|
EXPECT_EQ(OVERSCROLL_NONE, delegate()->current_mode());
|
|
EXPECT_EQ(OVERSCROLL_NONE, delegate()->completed_mode());
|
|
}
|
|
|
|
// After 300ms inertial gesture scroll updates, overscroll must get cancelled
|
|
// if not completed.
|
|
TEST_F(OverscrollControllerTest, OnlyProcessLimitedInertialGSUEvents) {
|
|
base::TimeTicks timestamp =
|
|
blink::WebInputEvent::GetStaticTimeStampForTests();
|
|
|
|
EXPECT_FALSE(
|
|
SimulateGestureEvent(blink::WebInputEvent::Type::kGestureScrollBegin,
|
|
blink::WebGestureDevice::kTouchpad, timestamp));
|
|
SimulateAck(false);
|
|
|
|
EXPECT_FALSE(SimulateGestureScrollUpdate(
|
|
61, 0, blink::WebGestureDevice::kTouchpad, timestamp, false));
|
|
SimulateAck(false);
|
|
EXPECT_EQ(OVERSCROLL_EAST, controller_mode());
|
|
EXPECT_EQ(OverscrollSource::TOUCHPAD, controller_source());
|
|
EXPECT_EQ(OVERSCROLL_EAST, delegate()->current_mode());
|
|
EXPECT_EQ(OVERSCROLL_NONE, delegate()->completed_mode());
|
|
|
|
// First inertial.
|
|
timestamp += base::Seconds(1);
|
|
EXPECT_TRUE(SimulateGestureScrollUpdate(
|
|
1, 0, blink::WebGestureDevice::kTouchpad, timestamp, true));
|
|
SimulateAck(true);
|
|
EXPECT_EQ(OVERSCROLL_EAST, controller_mode());
|
|
EXPECT_EQ(OverscrollSource::TOUCHPAD, controller_source());
|
|
EXPECT_EQ(OVERSCROLL_EAST, delegate()->current_mode());
|
|
EXPECT_EQ(OVERSCROLL_NONE, delegate()->completed_mode());
|
|
|
|
// Not cancel in 10ms.
|
|
timestamp += base::Milliseconds(10);
|
|
EXPECT_TRUE(SimulateGestureScrollUpdate(
|
|
1, 0, blink::WebGestureDevice::kTouchpad, timestamp, true));
|
|
SimulateAck(true);
|
|
EXPECT_EQ(OVERSCROLL_EAST, controller_mode());
|
|
EXPECT_EQ(OverscrollSource::TOUCHPAD, controller_source());
|
|
EXPECT_EQ(OVERSCROLL_EAST, delegate()->current_mode());
|
|
EXPECT_EQ(OVERSCROLL_NONE, delegate()->completed_mode());
|
|
|
|
// Cancel after 300ms.
|
|
timestamp += base::Milliseconds(291);
|
|
EXPECT_TRUE(SimulateGestureScrollUpdate(
|
|
1, 0, blink::WebGestureDevice::kTouchpad, timestamp, true));
|
|
SimulateAck(true);
|
|
EXPECT_EQ(OVERSCROLL_NONE, controller_mode());
|
|
EXPECT_EQ(OverscrollSource::NONE, controller_source());
|
|
EXPECT_EQ(OVERSCROLL_NONE, delegate()->current_mode());
|
|
EXPECT_EQ(OVERSCROLL_NONE, delegate()->completed_mode());
|
|
|
|
// Next event should be ignored.
|
|
timestamp += base::Milliseconds(100);
|
|
EXPECT_TRUE(SimulateGestureScrollUpdate(
|
|
1, 0, blink::WebGestureDevice::kTouchpad, timestamp, true));
|
|
}
|
|
|
|
// Verifies that when pull-to-refresh is disabled, it is not triggered for
|
|
// neither touchpad nor touchscreen.
|
|
TEST_F(OverscrollControllerTest, PullToRefreshDisabled) {
|
|
ScopedPullToRefreshMode scoped_mode(
|
|
OverscrollConfig::PullToRefreshMode::kDisabled);
|
|
|
|
base::TimeTicks timestamp =
|
|
blink::WebInputEvent::GetStaticTimeStampForTests();
|
|
|
|
EXPECT_FALSE(
|
|
SimulateGestureEvent(blink::WebInputEvent::Type::kGestureScrollBegin,
|
|
blink::WebGestureDevice::kTouchpad, timestamp));
|
|
SimulateAck(false);
|
|
|
|
// Simulate a touchpad gesture scroll-update event that passes the start
|
|
// threshold and ACK it as not processed. Pull-to-refresh should not be
|
|
// triggered.
|
|
EXPECT_FALSE(SimulateGestureScrollUpdate(
|
|
0, 80, blink::WebGestureDevice::kTouchpad, timestamp, false));
|
|
SimulateAck(false);
|
|
EXPECT_EQ(OVERSCROLL_NONE, controller_mode());
|
|
EXPECT_EQ(OverscrollSource::NONE, controller_source());
|
|
EXPECT_EQ(OVERSCROLL_NONE, delegate()->current_mode());
|
|
EXPECT_EQ(OVERSCROLL_NONE, delegate()->completed_mode());
|
|
|
|
timestamp += base::Seconds(1);
|
|
|
|
// Simulate a touchpad zero-velocity fling-start which would normally end
|
|
// pull-to-refresh, and ACK it as not processed. Nothing should happen.
|
|
EXPECT_FALSE(SimulateGestureFlingStart(
|
|
0, 0, blink::WebGestureDevice::kTouchpad, timestamp));
|
|
SimulateAck(false);
|
|
EXPECT_EQ(OVERSCROLL_NONE, controller_mode());
|
|
EXPECT_EQ(OverscrollSource::NONE, controller_source());
|
|
EXPECT_EQ(OVERSCROLL_NONE, delegate()->current_mode());
|
|
EXPECT_EQ(OVERSCROLL_NONE, delegate()->completed_mode());
|
|
|
|
timestamp += base::Seconds(1);
|
|
|
|
EXPECT_FALSE(
|
|
SimulateGestureEvent(blink::WebInputEvent::Type::kGestureScrollBegin,
|
|
blink::WebGestureDevice::kTouchscreen, timestamp));
|
|
SimulateAck(false);
|
|
|
|
// Simulate a touchscreen gesture scroll-update event that passes the start
|
|
// threshold and ACK it as not processed. Pull-to-refresh should not be
|
|
// triggered.
|
|
EXPECT_FALSE(SimulateGestureScrollUpdate(
|
|
0, 80, blink::WebGestureDevice::kTouchscreen, timestamp, false));
|
|
SimulateAck(false);
|
|
EXPECT_EQ(OVERSCROLL_NONE, controller_mode());
|
|
EXPECT_EQ(OverscrollSource::NONE, controller_source());
|
|
EXPECT_EQ(OVERSCROLL_NONE, delegate()->current_mode());
|
|
EXPECT_EQ(OVERSCROLL_NONE, delegate()->completed_mode());
|
|
|
|
timestamp += base::Seconds(1);
|
|
|
|
// Simulate a touchscreen gesture scroll-end which would normally end
|
|
// pull-to-refresh, and ACK it as not processed. Nothing should happen.
|
|
EXPECT_FALSE(
|
|
SimulateGestureEvent(blink::WebInputEvent::Type::kGestureScrollEnd,
|
|
blink::WebGestureDevice::kTouchscreen, timestamp));
|
|
SimulateAck(false);
|
|
EXPECT_EQ(OVERSCROLL_NONE, controller_mode());
|
|
EXPECT_EQ(OverscrollSource::NONE, controller_source());
|
|
EXPECT_EQ(OVERSCROLL_NONE, delegate()->current_mode());
|
|
EXPECT_EQ(OVERSCROLL_NONE, delegate()->completed_mode());
|
|
}
|
|
|
|
// Verifies that when pull-to-refresh is enabled, it is triggered for both
|
|
// touchpad and touchscreen.
|
|
TEST_F(OverscrollControllerTest, PullToRefreshEnabled) {
|
|
ScopedPullToRefreshMode scoped_mode(
|
|
OverscrollConfig::PullToRefreshMode::kEnabled);
|
|
|
|
base::TimeTicks timestamp =
|
|
blink::WebInputEvent::GetStaticTimeStampForTests();
|
|
|
|
EXPECT_FALSE(
|
|
SimulateGestureEvent(blink::WebInputEvent::Type::kGestureScrollBegin,
|
|
blink::WebGestureDevice::kTouchpad, timestamp));
|
|
SimulateAck(false);
|
|
|
|
// Simulate a touchpad gesture scroll-update event that passes the start
|
|
// threshold and ACK it as not processed. Pull-to-refresh should be triggered.
|
|
EXPECT_FALSE(SimulateGestureScrollUpdate(
|
|
0, 80, blink::WebGestureDevice::kTouchpad, timestamp, false));
|
|
SimulateAck(false);
|
|
EXPECT_EQ(OVERSCROLL_SOUTH, controller_mode());
|
|
EXPECT_EQ(OverscrollSource::TOUCHPAD, controller_source());
|
|
EXPECT_EQ(OVERSCROLL_SOUTH, delegate()->current_mode());
|
|
EXPECT_EQ(OVERSCROLL_NONE, delegate()->completed_mode());
|
|
|
|
timestamp += base::Seconds(1);
|
|
|
|
// Simulate a touchpad zero-velocity fling-start and ACK it as not processed..
|
|
// It should abort pull-to-refresh.
|
|
EXPECT_FALSE(SimulateGestureFlingStart(
|
|
0, 0, blink::WebGestureDevice::kTouchpad, timestamp));
|
|
SimulateAck(false);
|
|
EXPECT_EQ(OVERSCROLL_NONE, controller_mode());
|
|
EXPECT_EQ(OverscrollSource::NONE, controller_source());
|
|
EXPECT_EQ(OVERSCROLL_NONE, delegate()->current_mode());
|
|
EXPECT_EQ(OVERSCROLL_NONE, delegate()->completed_mode());
|
|
|
|
timestamp += base::Seconds(1);
|
|
|
|
EXPECT_FALSE(
|
|
SimulateGestureEvent(blink::WebInputEvent::Type::kGestureScrollBegin,
|
|
blink::WebGestureDevice::kTouchscreen, timestamp));
|
|
SimulateAck(false);
|
|
|
|
// Simulate a touchscreen gesture scroll-update event that passes the start
|
|
// threshold and ACK it as not processed. Pull-to-refresh should be triggered.
|
|
EXPECT_FALSE(SimulateGestureScrollUpdate(
|
|
0, 80, blink::WebGestureDevice::kTouchscreen, timestamp, false));
|
|
SimulateAck(false);
|
|
EXPECT_EQ(OVERSCROLL_SOUTH, controller_mode());
|
|
EXPECT_EQ(OverscrollSource::TOUCHSCREEN, controller_source());
|
|
EXPECT_EQ(OVERSCROLL_SOUTH, delegate()->current_mode());
|
|
EXPECT_EQ(OVERSCROLL_NONE, delegate()->completed_mode());
|
|
|
|
timestamp += base::Seconds(1);
|
|
|
|
// Simulate a touchscreen gesture scroll-end and ACK it as not processed. It
|
|
// should abort pull-to-refresh.
|
|
EXPECT_FALSE(
|
|
SimulateGestureEvent(blink::WebInputEvent::Type::kGestureScrollEnd,
|
|
blink::WebGestureDevice::kTouchscreen, timestamp));
|
|
SimulateAck(false);
|
|
EXPECT_EQ(OVERSCROLL_NONE, controller_mode());
|
|
EXPECT_EQ(OverscrollSource::NONE, controller_source());
|
|
EXPECT_EQ(OVERSCROLL_NONE, delegate()->current_mode());
|
|
EXPECT_EQ(OVERSCROLL_NONE, delegate()->completed_mode());
|
|
}
|
|
|
|
// Verifies that when pull-to-refresh is enabled only for touchscreen, it is
|
|
// triggered for touchscreen but not for touchpad.
|
|
TEST_F(OverscrollControllerTest, PullToRefreshEnabledTouchscreen) {
|
|
ScopedPullToRefreshMode scoped_mode(
|
|
OverscrollConfig::PullToRefreshMode::kEnabledTouchschreen);
|
|
|
|
base::TimeTicks timestamp =
|
|
blink::WebInputEvent::GetStaticTimeStampForTests();
|
|
|
|
EXPECT_FALSE(
|
|
SimulateGestureEvent(blink::WebInputEvent::Type::kGestureScrollBegin,
|
|
blink::WebGestureDevice::kTouchpad, timestamp));
|
|
SimulateAck(false);
|
|
|
|
// Simulate a touchpad gesture scroll-update event that passes the start
|
|
// threshold and ACK it as not processed. Pull-to-refresh should not be
|
|
// triggered.
|
|
EXPECT_FALSE(SimulateGestureScrollUpdate(
|
|
0, 80, blink::WebGestureDevice::kTouchpad, timestamp, false));
|
|
SimulateAck(false);
|
|
EXPECT_EQ(OVERSCROLL_NONE, controller_mode());
|
|
EXPECT_EQ(OverscrollSource::NONE, controller_source());
|
|
EXPECT_EQ(OVERSCROLL_NONE, delegate()->current_mode());
|
|
EXPECT_EQ(OVERSCROLL_NONE, delegate()->completed_mode());
|
|
|
|
timestamp += base::Seconds(1);
|
|
|
|
// Simulate a touchpad zero-velocity fling-start which would normally end
|
|
// pull-to-refresh, and ACK it as not processed. Nothing should happen.
|
|
EXPECT_FALSE(SimulateGestureFlingStart(
|
|
0, 0, blink::WebGestureDevice::kTouchpad, timestamp));
|
|
SimulateAck(false);
|
|
EXPECT_EQ(OVERSCROLL_NONE, controller_mode());
|
|
EXPECT_EQ(OverscrollSource::NONE, controller_source());
|
|
EXPECT_EQ(OVERSCROLL_NONE, delegate()->current_mode());
|
|
EXPECT_EQ(OVERSCROLL_NONE, delegate()->completed_mode());
|
|
|
|
timestamp += base::Seconds(1);
|
|
|
|
EXPECT_FALSE(
|
|
SimulateGestureEvent(blink::WebInputEvent::Type::kGestureScrollBegin,
|
|
blink::WebGestureDevice::kTouchscreen, timestamp));
|
|
SimulateAck(false);
|
|
|
|
// Simulate a touchscreen gesture scroll-update event that passes the start
|
|
// threshold and ACK it as not processed. Pull-to-refresh should be triggered.
|
|
EXPECT_FALSE(SimulateGestureScrollUpdate(
|
|
0, 80, blink::WebGestureDevice::kTouchscreen, timestamp, false));
|
|
SimulateAck(false);
|
|
EXPECT_EQ(OVERSCROLL_SOUTH, controller_mode());
|
|
EXPECT_EQ(OverscrollSource::TOUCHSCREEN, controller_source());
|
|
EXPECT_EQ(OVERSCROLL_SOUTH, delegate()->current_mode());
|
|
EXPECT_EQ(OVERSCROLL_NONE, delegate()->completed_mode());
|
|
|
|
timestamp += base::Seconds(1);
|
|
|
|
// Simulate a touchscreen gesture scroll-end and ACK it as not processed. It
|
|
// should abort pull-to-refresh.
|
|
EXPECT_FALSE(
|
|
SimulateGestureEvent(blink::WebInputEvent::Type::kGestureScrollEnd,
|
|
blink::WebGestureDevice::kTouchscreen, timestamp));
|
|
SimulateAck(false);
|
|
EXPECT_EQ(OVERSCROLL_NONE, controller_mode());
|
|
EXPECT_EQ(OverscrollSource::NONE, controller_source());
|
|
EXPECT_EQ(OVERSCROLL_NONE, delegate()->current_mode());
|
|
EXPECT_EQ(OVERSCROLL_NONE, delegate()->completed_mode());
|
|
}
|
|
|
|
// Ensure disabling kTouchpadOverscrollHistoryNavigation will prevent overscroll
|
|
// from touchpad.
|
|
TEST_F(OverscrollControllerTest, DisableTouchpadOverscrollHistoryNavigation) {
|
|
base::test::ScopedFeatureList feature_list;
|
|
feature_list.InitAndDisableFeature(
|
|
features::kTouchpadOverscrollHistoryNavigation);
|
|
ASSERT_FALSE(OverscrollConfig::TouchpadOverscrollHistoryNavigationEnabled());
|
|
|
|
const base::TimeTicks timestamp =
|
|
blink::WebInputEvent::GetStaticTimeStampForTests();
|
|
|
|
EXPECT_FALSE(SimulateGestureScrollUpdate(
|
|
200, 0, blink::WebGestureDevice::kTouchpad, timestamp, false));
|
|
SimulateAck(false);
|
|
|
|
EXPECT_EQ(OVERSCROLL_NONE, controller_mode());
|
|
EXPECT_EQ(OverscrollSource::NONE, controller_source());
|
|
EXPECT_EQ(OVERSCROLL_NONE, delegate()->current_mode());
|
|
EXPECT_EQ(OVERSCROLL_NONE, delegate()->completed_mode());
|
|
}
|
|
|
|
// Verifies that if an overscroll happens before cool off period after a page
|
|
// scroll, it does not trigger pull-to-refresh. Verifies following sequence of
|
|
// scrolls:
|
|
// 1) Page scroll;
|
|
// 2) Scroll before cool off -> PTR not triggered;
|
|
// 3) Scroll before cool off -> PTR not triggered;
|
|
// 4) Scroll after cool off -> PTR triggered;
|
|
// 5) Scroll before cool off -> PTR triggered.
|
|
TEST_F(OverscrollControllerTest, PullToRefreshBeforeCoolOff) {
|
|
ScopedPullToRefreshMode scoped_mode(
|
|
OverscrollConfig::PullToRefreshMode::kEnabled);
|
|
|
|
// 1) Page scroll.
|
|
base::TimeTicks timestamp =
|
|
blink::WebInputEvent::GetStaticTimeStampForTests();
|
|
|
|
EXPECT_FALSE(
|
|
SimulateGestureEvent(blink::WebInputEvent::Type::kGestureScrollBegin,
|
|
blink::WebGestureDevice::kTouchscreen, timestamp));
|
|
SimulateAck(false);
|
|
|
|
// Simulate a touchscreen gesture scroll-update event that passes the start
|
|
// threshold and ACK it as processed. Pull-to-refresh should not be triggered.
|
|
EXPECT_FALSE(SimulateGestureScrollUpdate(
|
|
0, 80, blink::WebGestureDevice::kTouchscreen, timestamp, false));
|
|
SimulateAck(true);
|
|
EXPECT_EQ(OVERSCROLL_NONE, controller_mode());
|
|
EXPECT_EQ(OverscrollSource::NONE, controller_source());
|
|
EXPECT_EQ(OVERSCROLL_NONE, delegate()->current_mode());
|
|
EXPECT_EQ(OVERSCROLL_NONE, delegate()->completed_mode());
|
|
|
|
timestamp += base::Seconds(1);
|
|
|
|
// Simulate a touchscreen gesture scroll-end which would normally end
|
|
// pull-to-refresh, and ACK it as not processed. Nothing should happen.
|
|
EXPECT_FALSE(
|
|
SimulateGestureEvent(blink::WebInputEvent::Type::kGestureScrollEnd,
|
|
blink::WebGestureDevice::kTouchscreen, timestamp));
|
|
SimulateAck(false);
|
|
EXPECT_EQ(OVERSCROLL_NONE, controller_mode());
|
|
EXPECT_EQ(OverscrollSource::NONE, controller_source());
|
|
EXPECT_EQ(OVERSCROLL_NONE, delegate()->current_mode());
|
|
EXPECT_EQ(OVERSCROLL_NONE, delegate()->completed_mode());
|
|
|
|
// 2) Scroll before cool off -> PTR not triggered.
|
|
timestamp += base::Milliseconds(500);
|
|
|
|
EXPECT_FALSE(
|
|
SimulateGestureEvent(blink::WebInputEvent::Type::kGestureScrollBegin,
|
|
blink::WebGestureDevice::kTouchscreen, timestamp));
|
|
SimulateAck(false);
|
|
|
|
// Simulate a touchscreen gesture scroll-update event that passes the start
|
|
// threshold and ACK it as not processed. Pull-to-refresh should not be
|
|
// triggered.
|
|
EXPECT_FALSE(SimulateGestureScrollUpdate(
|
|
0, 80, blink::WebGestureDevice::kTouchscreen, timestamp, false));
|
|
SimulateAck(false);
|
|
EXPECT_EQ(OVERSCROLL_NONE, controller_mode());
|
|
EXPECT_EQ(OverscrollSource::NONE, controller_source());
|
|
EXPECT_EQ(OVERSCROLL_NONE, delegate()->current_mode());
|
|
EXPECT_EQ(OVERSCROLL_NONE, delegate()->completed_mode());
|
|
|
|
timestamp += base::Seconds(1);
|
|
|
|
// Simulate a touchscreen gesture scroll-end which would normally end
|
|
// pull-to-refresh, and ACK it as not processed. Nothing should happen.
|
|
EXPECT_FALSE(
|
|
SimulateGestureEvent(blink::WebInputEvent::Type::kGestureScrollEnd,
|
|
blink::WebGestureDevice::kTouchscreen, timestamp));
|
|
SimulateAck(false);
|
|
EXPECT_EQ(OVERSCROLL_NONE, controller_mode());
|
|
EXPECT_EQ(OverscrollSource::NONE, controller_source());
|
|
EXPECT_EQ(OVERSCROLL_NONE, delegate()->current_mode());
|
|
EXPECT_EQ(OVERSCROLL_NONE, delegate()->completed_mode());
|
|
|
|
// 3) Scroll before cool off -> PTR not triggered.
|
|
timestamp += base::Milliseconds(500);
|
|
|
|
EXPECT_FALSE(
|
|
SimulateGestureEvent(blink::WebInputEvent::Type::kGestureScrollBegin,
|
|
blink::WebGestureDevice::kTouchscreen, timestamp));
|
|
SimulateAck(false);
|
|
|
|
// Simulate a touchscreen gesture scroll-update event that passes the start
|
|
// threshold and ACK it as not processed. Pull-to-refresh should not be
|
|
// triggered.
|
|
EXPECT_FALSE(SimulateGestureScrollUpdate(
|
|
0, 80, blink::WebGestureDevice::kTouchscreen, timestamp, false));
|
|
SimulateAck(false);
|
|
EXPECT_EQ(OVERSCROLL_NONE, controller_mode());
|
|
EXPECT_EQ(OverscrollSource::NONE, controller_source());
|
|
EXPECT_EQ(OVERSCROLL_NONE, delegate()->current_mode());
|
|
EXPECT_EQ(OVERSCROLL_NONE, delegate()->completed_mode());
|
|
|
|
timestamp += base::Seconds(1);
|
|
|
|
// Simulate a touchscreen gesture scroll-end which would normally end
|
|
// pull-to-refresh, and ACK it as not processed. Nothing should happen.
|
|
EXPECT_FALSE(
|
|
SimulateGestureEvent(blink::WebInputEvent::Type::kGestureScrollEnd,
|
|
blink::WebGestureDevice::kTouchscreen, timestamp));
|
|
SimulateAck(false);
|
|
EXPECT_EQ(OVERSCROLL_NONE, controller_mode());
|
|
EXPECT_EQ(OverscrollSource::NONE, controller_source());
|
|
EXPECT_EQ(OVERSCROLL_NONE, delegate()->current_mode());
|
|
EXPECT_EQ(OVERSCROLL_NONE, delegate()->completed_mode());
|
|
|
|
// 4) Scroll after cool off -> PTR triggered.
|
|
timestamp += base::Seconds(1);
|
|
|
|
EXPECT_FALSE(
|
|
SimulateGestureEvent(blink::WebInputEvent::Type::kGestureScrollBegin,
|
|
blink::WebGestureDevice::kTouchscreen, timestamp));
|
|
SimulateAck(false);
|
|
|
|
// Simulate a touchscreen gesture scroll-update event that passes the start
|
|
// threshold and ACK it as not processed. Pull-to-refresh should be triggered.
|
|
EXPECT_FALSE(SimulateGestureScrollUpdate(
|
|
0, 80, blink::WebGestureDevice::kTouchscreen, timestamp, false));
|
|
SimulateAck(false);
|
|
EXPECT_EQ(OVERSCROLL_SOUTH, controller_mode());
|
|
EXPECT_EQ(OverscrollSource::TOUCHSCREEN, controller_source());
|
|
EXPECT_EQ(OVERSCROLL_SOUTH, delegate()->current_mode());
|
|
EXPECT_EQ(OVERSCROLL_NONE, delegate()->completed_mode());
|
|
|
|
timestamp += base::Seconds(1);
|
|
|
|
// Simulate a touchscreen gesture scroll-end which will end pull-to-refresh,
|
|
// and ACK it as not processed. Pull-to-refresh should be aborted.
|
|
EXPECT_FALSE(
|
|
SimulateGestureEvent(blink::WebInputEvent::Type::kGestureScrollEnd,
|
|
blink::WebGestureDevice::kTouchscreen, timestamp));
|
|
SimulateAck(false);
|
|
EXPECT_EQ(OVERSCROLL_NONE, controller_mode());
|
|
EXPECT_EQ(OverscrollSource::NONE, controller_source());
|
|
EXPECT_EQ(OVERSCROLL_NONE, delegate()->current_mode());
|
|
EXPECT_EQ(OVERSCROLL_NONE, delegate()->completed_mode());
|
|
|
|
// 5) Scroll before cool off -> PTR triggered.
|
|
timestamp += base::Milliseconds(500);
|
|
|
|
EXPECT_FALSE(
|
|
SimulateGestureEvent(blink::WebInputEvent::Type::kGestureScrollBegin,
|
|
blink::WebGestureDevice::kTouchscreen, timestamp));
|
|
SimulateAck(false);
|
|
|
|
// Simulate a touchscreen gesture scroll-update event that passes the start
|
|
// threshold and ACK it as not processed. Pull-to-refresh should be triggered.
|
|
EXPECT_FALSE(SimulateGestureScrollUpdate(
|
|
0, 80, blink::WebGestureDevice::kTouchscreen, timestamp, false));
|
|
SimulateAck(false);
|
|
EXPECT_EQ(OVERSCROLL_SOUTH, controller_mode());
|
|
EXPECT_EQ(OverscrollSource::TOUCHSCREEN, controller_source());
|
|
EXPECT_EQ(OVERSCROLL_SOUTH, delegate()->current_mode());
|
|
EXPECT_EQ(OVERSCROLL_NONE, delegate()->completed_mode());
|
|
|
|
timestamp += base::Seconds(1);
|
|
|
|
// Simulate a touchscreen gesture scroll-end which will end pull-to-refresh,
|
|
// and ACK it as not processed. Pull-to-refresh should be aborted.
|
|
EXPECT_FALSE(
|
|
SimulateGestureEvent(blink::WebInputEvent::Type::kGestureScrollEnd,
|
|
blink::WebGestureDevice::kTouchscreen, timestamp));
|
|
SimulateAck(false);
|
|
EXPECT_EQ(OVERSCROLL_NONE, controller_mode());
|
|
EXPECT_EQ(OverscrollSource::NONE, controller_source());
|
|
EXPECT_EQ(OVERSCROLL_NONE, delegate()->current_mode());
|
|
EXPECT_EQ(OVERSCROLL_NONE, delegate()->completed_mode());
|
|
}
|
|
|
|
// Verifies that if an overscroll happens after cool off period after a page
|
|
// scroll, it triggers pull-to-refresh. Verifies the following sequence of
|
|
// scrolls:
|
|
// 1) Page scroll;
|
|
// 2) Scroll after cool off -> PTR triggered;
|
|
// 3) Scroll before cool off -> PTR triggered;
|
|
TEST_F(OverscrollControllerTest, PullToRefreshAfterCoolOff) {
|
|
ScopedPullToRefreshMode scoped_mode(
|
|
OverscrollConfig::PullToRefreshMode::kEnabled);
|
|
|
|
// 1) Page scroll.
|
|
base::TimeTicks timestamp =
|
|
blink::WebInputEvent::GetStaticTimeStampForTests();
|
|
|
|
EXPECT_FALSE(
|
|
SimulateGestureEvent(blink::WebInputEvent::Type::kGestureScrollBegin,
|
|
blink::WebGestureDevice::kTouchscreen, timestamp));
|
|
SimulateAck(false);
|
|
|
|
// Simulate a touchscreen gesture scroll-update event that passes the start
|
|
// threshold and ACK it as processed. Pull-to-refresh should not be triggered.
|
|
EXPECT_FALSE(SimulateGestureScrollUpdate(
|
|
0, 80, blink::WebGestureDevice::kTouchscreen, timestamp, false));
|
|
SimulateAck(true);
|
|
EXPECT_EQ(OVERSCROLL_NONE, controller_mode());
|
|
EXPECT_EQ(OverscrollSource::NONE, controller_source());
|
|
EXPECT_EQ(OVERSCROLL_NONE, delegate()->current_mode());
|
|
EXPECT_EQ(OVERSCROLL_NONE, delegate()->completed_mode());
|
|
|
|
timestamp += base::Seconds(1);
|
|
|
|
// Simulate a touchscreen gesture scroll-end which would normally end
|
|
// pull-to-refresh, and ACK it as not processed. Nothing should happen.
|
|
EXPECT_FALSE(
|
|
SimulateGestureEvent(blink::WebInputEvent::Type::kGestureScrollEnd,
|
|
blink::WebGestureDevice::kTouchscreen, timestamp));
|
|
SimulateAck(false);
|
|
EXPECT_EQ(OVERSCROLL_NONE, controller_mode());
|
|
EXPECT_EQ(OverscrollSource::NONE, controller_source());
|
|
EXPECT_EQ(OVERSCROLL_NONE, delegate()->current_mode());
|
|
EXPECT_EQ(OVERSCROLL_NONE, delegate()->completed_mode());
|
|
|
|
// 2) Scroll after cool off -> PTR triggered.
|
|
timestamp += base::Seconds(1);
|
|
|
|
EXPECT_FALSE(
|
|
SimulateGestureEvent(blink::WebInputEvent::Type::kGestureScrollBegin,
|
|
blink::WebGestureDevice::kTouchscreen, timestamp));
|
|
SimulateAck(false);
|
|
|
|
// Simulate a touchscreen gesture scroll-update event that passes the start
|
|
// threshold and ACK it as not processed. Pull-to-refresh should be triggered.
|
|
EXPECT_FALSE(SimulateGestureScrollUpdate(
|
|
0, 80, blink::WebGestureDevice::kTouchscreen, timestamp, false));
|
|
SimulateAck(false);
|
|
EXPECT_EQ(OVERSCROLL_SOUTH, controller_mode());
|
|
EXPECT_EQ(OverscrollSource::TOUCHSCREEN, controller_source());
|
|
EXPECT_EQ(OVERSCROLL_SOUTH, delegate()->current_mode());
|
|
EXPECT_EQ(OVERSCROLL_NONE, delegate()->completed_mode());
|
|
|
|
timestamp += base::Seconds(1);
|
|
|
|
// Simulate a touchscreen gesture scroll-end which will end pull-to-refresh,
|
|
// and ACK it as not processed. Pull-to-refresh should be aborted.
|
|
EXPECT_FALSE(
|
|
SimulateGestureEvent(blink::WebInputEvent::Type::kGestureScrollEnd,
|
|
blink::WebGestureDevice::kTouchscreen, timestamp));
|
|
SimulateAck(false);
|
|
EXPECT_EQ(OVERSCROLL_NONE, controller_mode());
|
|
EXPECT_EQ(OverscrollSource::NONE, controller_source());
|
|
EXPECT_EQ(OVERSCROLL_NONE, delegate()->current_mode());
|
|
EXPECT_EQ(OVERSCROLL_NONE, delegate()->completed_mode());
|
|
|
|
// 3) Scroll before cool off -> PTR triggered.
|
|
timestamp += base::Milliseconds(500);
|
|
|
|
EXPECT_FALSE(
|
|
SimulateGestureEvent(blink::WebInputEvent::Type::kGestureScrollBegin,
|
|
blink::WebGestureDevice::kTouchscreen, timestamp));
|
|
SimulateAck(false);
|
|
|
|
// Simulate a touchscreen gesture scroll-update event that passes the start
|
|
// threshold and ACK it as not processed. Pull-to-refresh should be triggered.
|
|
EXPECT_FALSE(SimulateGestureScrollUpdate(
|
|
0, 80, blink::WebGestureDevice::kTouchscreen, timestamp, false));
|
|
SimulateAck(false);
|
|
EXPECT_EQ(OVERSCROLL_SOUTH, controller_mode());
|
|
EXPECT_EQ(OverscrollSource::TOUCHSCREEN, controller_source());
|
|
EXPECT_EQ(OVERSCROLL_SOUTH, delegate()->current_mode());
|
|
EXPECT_EQ(OVERSCROLL_NONE, delegate()->completed_mode());
|
|
|
|
timestamp += base::Seconds(1);
|
|
|
|
// Simulate a touchscreen gesture scroll-end which will end pull-to-refresh,
|
|
// and ACK it as not processed. Pull-to-refresh should be aborted.
|
|
EXPECT_FALSE(
|
|
SimulateGestureEvent(blink::WebInputEvent::Type::kGestureScrollEnd,
|
|
blink::WebGestureDevice::kTouchscreen, timestamp));
|
|
SimulateAck(false);
|
|
EXPECT_EQ(OVERSCROLL_NONE, controller_mode());
|
|
EXPECT_EQ(OverscrollSource::NONE, controller_source());
|
|
EXPECT_EQ(OVERSCROLL_NONE, delegate()->current_mode());
|
|
EXPECT_EQ(OVERSCROLL_NONE, delegate()->completed_mode());
|
|
}
|
|
|
|
} // namespace content
|