Bug 1912358 - Set a proper APZHandledResult in the case of fast-fling. r=botond,geckoview-reviewers,m_kato

During fast-fling, any event isn't delivered to contents, but fast-fling
causes scrolling, thus we need to tell the state to GeckoView via
the APZHandledResult.

The JUnit test case causes an assertion (bug 1852854) without this change.

Differential Revision: https://phabricator.services.mozilla.com/D218898
This commit is contained in:
Hiroyuki Ikezoe 2024-08-26 01:10:18 +00:00
parent c08b67a77c
commit d0e79f1b8c
4 changed files with 144 additions and 0 deletions

View File

@ -207,6 +207,10 @@ void APZEventResult::SetStatusForFastFling(
// to content at all.
mStatus = nsEventStatus_eConsumeNoDefault;
// Re-initialize with DispatchToContent::No, since being in a fast fling
// means the event will definitely not be dispatched to content.
mHandledResult = APZHandledResult::Initialize(aTarget, DispatchToContent::No);
// In the case of fast fling, the event will never be sent to content, so we
// want a result where `aDispatchToContent` is false whatever the original
// `aFlags.mDispatchToContent` is.

View File

@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style>
body {
margin: 0px;
padding: 0px;
}
div {
height: 2000vh;
}
</style>
<div></div>
<script>
window.addEventListener("wheel", () => {}, { passive: false });
</script>
</html>

View File

@ -146,6 +146,7 @@ open class BaseSessionTest(
const val INTERSECTION_OBSERVER_HTML_PATH = "/assets/www/intersection-observer.html"
const val INTERSECTION_OBSERVER_DESKTOP_HTML_PATH = "/assets/www/intersection-observer-desktop.html"
const val BUG1909181_HTML_PATH = "/assets/www/bug1909181.html"
const val BUG1912358_HTML_PATH = "/assets/www/bug1912358.html"
const val TEST_ENDPOINT = GeckoSessionTestRule.TEST_ENDPOINT
const val TEST_HOST = GeckoSessionTestRule.TEST_HOST

View File

@ -607,4 +607,125 @@ class InputResultDetailTest : BaseSessionTest() {
PanZoomController.OVERSCROLL_FLAG_HORIZONTAL,
)
}
@WithDisplay(width = 100, height = 100)
@Test
fun testOppositeTouchScrollingDuringFastFling() {
sessionRule.setPrefsUntilTestEnd(
mapOf(
"apz.touch_start_tolerance" to "0", // To avoid touch events fall into slop state.
"apz.fling_min_velocity_threshold" to "0", // To trigger fling animations easier.
"apz.android.chrome_fling_physics.friction" to "0.0001", // To keep the fling animation alive for a while.
),
)
setupDocument(BUG1912358_HTML_PATH)
// Prepare a scroll event listener.
val scrollPromise = mainSession.evaluatePromiseJS(
"""
new Promise(resolve => {
window.addEventListener('scroll', () => {
resolve(true);
}, { once: true });
});
""".trimIndent(),
)
// Send a series of touch events to trigger a fast fling animation.
var downTime = SystemClock.uptimeMillis()
var down = MotionEvent.obtain(
downTime,
SystemClock.uptimeMillis(),
MotionEvent.ACTION_DOWN,
50f,
50f,
0,
)
var result = mainSession.panZoomController.onTouchEventForDetailResult(down)
// Send two touch move events here since with "apz.touch_start_tolerance=0"
// a touch move event doesn't scroll.
var move = MotionEvent.obtain(
downTime,
SystemClock.uptimeMillis(),
MotionEvent.ACTION_MOVE,
50f,
40f,
0,
)
mainSession.panZoomController.onTouchEvent(move)
move = MotionEvent.obtain(
downTime,
SystemClock.uptimeMillis(),
MotionEvent.ACTION_MOVE,
50f,
30f,
0,
)
mainSession.panZoomController.onTouchEvent(move)
// Make sure the content has been scrolled.
assertThat("scroll", scrollPromise.value as Boolean, equalTo(true))
var value = sessionRule.waitForResult(result)
assertResultDetail(
"testOppositeTouchScrollingDuringFastFling",
value,
PanZoomController.INPUT_RESULT_HANDLED,
PanZoomController.SCROLLABLE_FLAG_BOTTOM,
(PanZoomController.OVERSCROLL_FLAG_HORIZONTAL or PanZoomController.OVERSCROLL_FLAG_VERTICAL),
)
var up = MotionEvent.obtain(
downTime,
SystemClock.uptimeMillis(),
MotionEvent.ACTION_UP,
50f,
10f,
0,
)
mainSession.panZoomController.onTouchEvent(up)
// Send a new series of upward touch events during the fling animation.
downTime = SystemClock.uptimeMillis()
down = MotionEvent.obtain(
downTime,
SystemClock.uptimeMillis(),
MotionEvent.ACTION_DOWN,
50f,
50f,
0,
)
result = mainSession.panZoomController.onTouchEventForDetailResult(down)
move = MotionEvent.obtain(
downTime,
SystemClock.uptimeMillis(),
MotionEvent.ACTION_MOVE,
50f,
60f,
0,
)
mainSession.panZoomController.onTouchEvent(move)
up = MotionEvent.obtain(
downTime,
SystemClock.uptimeMillis(),
MotionEvent.ACTION_UP,
50f,
60f,
0,
)
mainSession.panZoomController.onTouchEvent(up)
value = sessionRule.waitForResult(result)
assertResultDetail(
"testOppositeTouchScrollingDuringFastFling",
value,
PanZoomController.INPUT_RESULT_HANDLED,
(PanZoomController.SCROLLABLE_FLAG_BOTTOM or PanZoomController.SCROLLABLE_FLAG_TOP),
(PanZoomController.OVERSCROLL_FLAG_HORIZONTAL or PanZoomController.OVERSCROLL_FLAG_VERTICAL),
)
}
}