GestureNav: Adjust edge width for triggering navigation
This CL reduces the width of the area used for triggering
gesture navigation. The reported conflicts with other UI
can be alleviated.
Bug: 1128629
TBR: [email protected]
(cherry picked from commit 245022d0f27873e9a51de5be1ba304f83a50acaf)
Change-Id: I726453adc3dfd1848332ee668d11662c44afdb55
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2448070
Commit-Queue: Jinsuk Kim <[email protected]>
Reviewed-by: Theresa <[email protected]>
Cr-Original-Commit-Position: refs/heads/master@{#814586}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2469416
Reviewed-by: Jinsuk Kim <[email protected]>
Cr-Commit-Position: refs/branch-heads/4280@{#353}
Cr-Branched-From: ea420fb963f9658c9969b6513c56b8f47efa1a2a-refs/heads/master@{#812852}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/gesturenav/NavigationHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/gesturenav/NavigationHandler.java
index 5888f0e..23ee6510 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/gesturenav/NavigationHandler.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/gesturenav/NavigationHandler.java
@@ -24,6 +24,7 @@
import org.chromium.base.supplier.Supplier;
import org.chromium.chrome.browser.compositor.CompositorViewHolder.TouchEventObserver;
+import org.chromium.chrome.browser.flags.ChromeFeatureList;
import org.chromium.chrome.browser.gesturenav.NavigationBubble.CloseTarget;
import org.chromium.ui.modelutil.PropertyModel;
@@ -34,10 +35,13 @@
* Handles history overscroll navigation controlling the underlying UI widget.
*/
class NavigationHandler implements TouchEventObserver {
- // Width of a rectangluar area in dp on the left/right edge used for navigation.
+ // Default width of a rectangluar area in dp on the left/right edge used for navigation.
// Swipe beginning from a point within these rects triggers the operation.
@VisibleForTesting
- static final float EDGE_WIDTH_DP = 48;
+ static final int DEFAULT_EDGE_WIDTH_DP = 24;
+
+ // Key name of the server-controlled parameter for the edge width.
+ private static final String EDGE_WIDTH_KEY = "gesture_navigation_triggering_area_width";
// Weighted value to determine when to trigger an edge swipe. Initial scroll
// vector should form 30 deg or below to initiate swipe action.
@@ -145,7 +149,12 @@
mIsNativePage = isNativePage;
mIsSheetExpanded = isSheetExpanded;
mState = GestureState.NONE;
- mEdgeWidthPx = EDGE_WIDTH_DP * parentView.getResources().getDisplayMetrics().density;
+
+ int edgeWidthDp = ChromeFeatureList.getFieldTrialParamByFeatureAsInt(
+ ChromeFeatureList.OVERSCROLL_HISTORY_NAVIGATION, EDGE_WIDTH_KEY,
+ DEFAULT_EDGE_WIDTH_DP);
+
+ mEdgeWidthPx = edgeWidthDp * parentView.getResources().getDisplayMetrics().density;
mDetector = new GestureDetector(mContext, new SideNavGestureListener());
mAttachStateListener = new View.OnAttachStateChangeListener() {
@Override
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/gesturenav/NavigationHandlerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/gesturenav/NavigationHandlerTest.java
index f8ecafe..ed8c78e 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/gesturenav/NavigationHandlerTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/gesturenav/NavigationHandlerTest.java
@@ -47,8 +47,11 @@
* Tests {@link NavigationHandler} navigating back/forward using overscroll history navigation.
*/
@RunWith(ChromeJUnit4ClassRunner.class)
-@CommandLineFlags.
-Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE, "enable-features=OverscrollHistoryNavigation"})
[email protected]({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+ "enable-features=OverscrollHistoryNavigation<GestureNavigation",
+ "force-fieldtrials=GestureNavigation/Enabled",
+ "force-fieldtrial-params=GestureNavigation.Enabled:"
+ + "gesture_navigation_triggering_area_width/36"})
public class NavigationHandlerTest {
private static final String RENDERED_PAGE = "/chrome/test/data/android/navigate/simple.html";
private static final boolean LEFT_EDGE = true;
@@ -70,7 +73,7 @@
DisplayMetrics displayMetrics = new DisplayMetrics();
mActivityTestRule.getActivity().getWindowManager().getDefaultDisplay().getMetrics(
displayMetrics);
- mEdgeWidthPx = displayMetrics.density * NavigationHandler.EDGE_WIDTH_DP;
+ mEdgeWidthPx = displayMetrics.density * NavigationHandler.DEFAULT_EDGE_WIDTH_DP;
HistoryNavigationCoordinator coordinator = getNavigationCoordinator();
mNavigationLayout = coordinator.getLayoutForTesting();
mNavigationHandler = coordinator.getNavigationHandlerForTesting();
diff --git a/content/browser/android/overscroll_controller_android.cc b/content/browser/android/overscroll_controller_android.cc
index 6decf98..24703c8 100644
--- a/content/browser/android/overscroll_controller_android.cc
+++ b/content/browser/android/overscroll_controller_android.cc
@@ -5,9 +5,11 @@
#include "content/browser/android/overscroll_controller_android.h"
#include "base/command_line.h"
+#include "base/metrics/field_trial_params.h"
#include "cc/layers/layer.h"
#include "components/viz/common/quads/compositor_frame_metadata.h"
#include "content/public/browser/navigation_controller.h"
+#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/use_zoom_for_dsf_policy.h"
#include "third_party/blink/public/common/input/web_gesture_event.h"
@@ -58,8 +60,13 @@
return nullptr;
}
+ float edge_width = base::GetFieldTrialParamByFeatureAsInt(
+ features::kOverscrollHistoryNavigation,
+ "gesture_navigation_triggering_area_width",
+ OverscrollRefresh::kDefaultNavigationEdgeWidth) *
+ dpi_scale;
return std::make_unique<OverscrollRefresh>(overscroll_refresh_handler,
- dpi_scale);
+ edge_width);
}
} // namespace
diff --git a/ui/android/overscroll_refresh.cc b/ui/android/overscroll_refresh.cc
index 9d7a443..311774e 100644
--- a/ui/android/overscroll_refresh.cc
+++ b/ui/android/overscroll_refresh.cc
@@ -17,10 +17,6 @@
// release results in a small upward fling (quite common during a slow scroll).
const float kMinFlingVelocityForActivation = -500.f;
-// The default distance in dp from a side of the device to start a navigation
-// from.
-const float kNavigationEdgeWidth = 48.f;
-
// Weighted value used to determine whether a scroll should trigger vertical
// scroll or horizontal navigation.
const float kWeightAngle30 = 1.73f;
@@ -28,12 +24,12 @@
} // namespace
OverscrollRefresh::OverscrollRefresh(OverscrollRefreshHandler* handler,
- float dpi_scale)
+ float edge_width)
: scrolled_to_top_(true),
top_at_scroll_start_(true),
overflow_y_hidden_(false),
scroll_consumption_state_(DISABLED),
- edge_width_(kNavigationEdgeWidth * dpi_scale),
+ edge_width_(edge_width),
handler_(handler) {
DCHECK(handler);
}
@@ -42,7 +38,7 @@
: scrolled_to_top_(true),
overflow_y_hidden_(false),
scroll_consumption_state_(DISABLED),
- edge_width_(kNavigationEdgeWidth * 1.f),
+ edge_width_(kDefaultNavigationEdgeWidth * 1.f),
handler_(nullptr) {}
OverscrollRefresh::~OverscrollRefresh() {
diff --git a/ui/android/overscroll_refresh.h b/ui/android/overscroll_refresh.h
index b650d46..57c9c7a 100644
--- a/ui/android/overscroll_refresh.h
+++ b/ui/android/overscroll_refresh.h
@@ -36,12 +36,11 @@
// provided refresh handler.
class UI_ANDROID_EXPORT OverscrollRefresh {
public:
- // Minmum number of overscrolling pull events required to activate the effect.
- // Useful for avoiding accidental triggering when a scroll janks (is delayed),
- // capping the impulse per event.
- enum { kMinPullsToActivate = 3 };
+ // The default distance in dp from a side of the device to start a navigation
+ // from.
+ enum { kDefaultNavigationEdgeWidth = 24 };
- OverscrollRefresh(OverscrollRefreshHandler* handler, float dpi_scale);
+ OverscrollRefresh(OverscrollRefreshHandler* handler, float edge_width);
virtual ~OverscrollRefresh();
@@ -105,7 +104,7 @@
float viewport_width_;
float scroll_begin_x_;
float scroll_begin_y_;
- const float edge_width_;
+ const float edge_width_; // in px
gfx::Vector2dF cumulative_scroll_;
OverscrollRefreshHandler* const handler_;
diff --git a/ui/android/overscroll_refresh_unittest.cc b/ui/android/overscroll_refresh_unittest.cc
index df9184f..2253156 100644
--- a/ui/android/overscroll_refresh_unittest.cc
+++ b/ui/android/overscroll_refresh_unittest.cc
@@ -13,6 +13,8 @@
const float kDipScale = 1.f;
const gfx::PointF kStartPos(2.f, 2.f);
+const float kDefaultEdgeWidth =
+ OverscrollRefresh::kDefaultNavigationEdgeWidth * kDipScale;
class OverscrollRefreshTest : public OverscrollRefreshHandler,
public testing::Test {
@@ -70,7 +72,7 @@
void TestOverscrollBehavior(const cc::OverscrollBehavior& ob,
const gfx::Vector2dF& scroll_delta,
bool started) {
- OverscrollRefresh effect(this, 1.f);
+ OverscrollRefresh effect(this, kDefaultEdgeWidth);
effect.OnScrollBegin(kStartPos);
EXPECT_FALSE(effect.WillHandleScrollUpdate(scroll_delta));
EXPECT_FALSE(effect.IsActive());
@@ -89,7 +91,7 @@
};
TEST_F(OverscrollRefreshTest, Basic) {
- OverscrollRefresh effect(this, kDipScale);
+ OverscrollRefresh effect(this, kDefaultEdgeWidth);
EXPECT_FALSE(effect.IsActive());
EXPECT_FALSE(effect.IsAwaitingScrollUpdateAck());
@@ -131,7 +133,7 @@
}
TEST_F(OverscrollRefreshTest, NotTriggeredIfInitialYOffsetIsNotZero) {
- OverscrollRefresh effect(this, kDipScale);
+ OverscrollRefresh effect(this, kDefaultEdgeWidth);
// A positive y scroll offset at the start of scroll will prevent activation,
// even if the subsequent scroll overscrolls upward.
@@ -155,7 +157,7 @@
}
TEST_F(OverscrollRefreshTest, NotTriggeredIfOverflowYHidden) {
- OverscrollRefresh effect(this, kDipScale);
+ OverscrollRefresh effect(this, kDefaultEdgeWidth);
// overflow-y:hidden at the start of scroll will prevent activation.
gfx::Vector2dF zero_offset;
@@ -177,7 +179,7 @@
}
TEST_F(OverscrollRefreshTest, NotTriggeredIfInitialScrollDownward) {
- OverscrollRefresh effect(this, kDipScale);
+ OverscrollRefresh effect(this, kDefaultEdgeWidth);
effect.OnScrollBegin(kStartPos);
// A downward initial scroll will prevent activation, even if the subsequent
@@ -195,7 +197,7 @@
}
TEST_F(OverscrollRefreshTest, NotTriggeredIfInitialScrollOrTouchConsumed) {
- OverscrollRefresh effect(this, kDipScale);
+ OverscrollRefresh effect(this, kDefaultEdgeWidth);
effect.OnScrollBegin(kStartPos);
ASSERT_FALSE(effect.WillHandleScrollUpdate(gfx::Vector2dF(0, 10)));
ASSERT_TRUE(effect.IsAwaitingScrollUpdateAck());
@@ -217,7 +219,7 @@
}
TEST_F(OverscrollRefreshTest, NotTriggeredIfFlungDownward) {
- OverscrollRefresh effect(this, kDipScale);
+ OverscrollRefresh effect(this, kDefaultEdgeWidth);
effect.OnScrollBegin(kStartPos);
ASSERT_FALSE(effect.WillHandleScrollUpdate(gfx::Vector2dF(0, 10)));
ASSERT_TRUE(effect.IsAwaitingScrollUpdateAck());
@@ -232,7 +234,7 @@
}
TEST_F(OverscrollRefreshTest, NotTriggeredIfReleasedWithoutActivation) {
- OverscrollRefresh effect(this, kDipScale);
+ OverscrollRefresh effect(this, kDefaultEdgeWidth);
effect.OnScrollBegin(kStartPos);
ASSERT_FALSE(effect.WillHandleScrollUpdate(gfx::Vector2dF(0, 10)));
ASSERT_TRUE(effect.IsAwaitingScrollUpdateAck());
@@ -248,7 +250,7 @@
}
TEST_F(OverscrollRefreshTest, NotTriggeredIfReset) {
- OverscrollRefresh effect(this, kDipScale);
+ OverscrollRefresh effect(this, kDefaultEdgeWidth);
effect.OnScrollBegin(kStartPos);
ASSERT_FALSE(effect.WillHandleScrollUpdate(gfx::Vector2dF(0, 10)));
ASSERT_TRUE(effect.IsAwaitingScrollUpdateAck());