Merge "[VRR] Still do touch boost with an ongoing press gesture" into main
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index bf5169f..a0cf203 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -1107,6 +1107,8 @@
private boolean mIsFrameRateBoosting = false;
// Used to check if it is in touch boosting period.
private boolean mIsTouchBoosting = false;
+ // Used to track if an ongoing press gesture is occurring.
+ private boolean mIsPressedGesture = false;
private boolean mDrawnThisFrame = false;
// Used to check if there is a conflict between different frame rate voting.
// Take 24 and 30 as an example, 24 is not a divisor of 30.
@@ -6912,6 +6914,7 @@
setPreferredFrameRate(mPreferredFrameRate);
setPreferredFrameRateCategory(mPreferredFrameRateCategory);
mInvalidationIdleMessagePosted = false;
+ mIsPressedGesture = false;
} else {
mInvalidationIdleMessagePosted = true;
mHandler.sendEmptyMessageDelayed(MSG_CHECK_INVALIDATION_IDLE,
@@ -7925,6 +7928,9 @@
private int processPointerEvent(QueuedInputEvent q) {
final MotionEvent event = (MotionEvent)q.mEvent;
final int action = event.getAction();
+ if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
+ mIsPressedGesture = false;
+ }
boolean handled = false;
if (!disableHandwritingInitiatorForIme()
|| mWindowAttributes.type != TYPE_INPUT_METHOD) {
@@ -7955,6 +7961,9 @@
mWindowAttributes.type)) {
// set the frame rate to the maximum value.
mIsTouchBoosting = true;
+ if (action == MotionEvent.ACTION_DOWN) {
+ mIsPressedGesture = true;
+ }
setPreferredFrameRateCategory(mLastPreferredFrameRateCategory);
}
/**
@@ -13057,7 +13066,7 @@
if (frameRate <= 0) {
return;
}
- if (frameRateCompatibility == FRAME_RATE_COMPATIBILITY_GTE) {
+ if (frameRateCompatibility == FRAME_RATE_COMPATIBILITY_GTE && !mIsPressedGesture) {
mIsTouchBoosting = false;
mIsFrameRateBoosting = false;
if (!sToolkitFrameRateVelocityMappingReadOnlyFlagValue) {
diff --git a/core/tests/coretests/src/android/view/ViewFrameRateTest.java b/core/tests/coretests/src/android/view/ViewFrameRateTest.java
index da9a6e1..c01b51d 100644
--- a/core/tests/coretests/src/android/view/ViewFrameRateTest.java
+++ b/core/tests/coretests/src/android/view/ViewFrameRateTest.java
@@ -175,6 +175,87 @@
assertEquals(0f, mViewRoot.getLastPreferredFrameRate(), 0f);
}
+
+ @Test
+ @RequiresFlagsEnabled(FLAG_VIEW_VELOCITY_API)
+ public void highHintWhenActionMove() throws Throwable {
+ if (!ViewProperties.vrr_enabled().orElse(true)) {
+ return;
+ }
+
+ mActivityRule.runOnUiThread(() -> {
+ mMovingView.setRequestedFrameRate(View.REQUESTED_FRAME_RATE_CATEGORY_LOW);
+ ViewGroup.LayoutParams layoutParams = mMovingView.getLayoutParams();
+ layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT;
+ layoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT;
+ mMovingView.setLayoutParams(layoutParams);
+ mMovingView.setOnClickListener((v) -> {});
+ });
+ waitForFrameRateCategoryToSettle();
+ mActivityRule.runOnUiThread(() -> assertEquals(FRAME_RATE_CATEGORY_LOW,
+ mViewRoot.getLastPreferredFrameRateCategory()));
+
+ int[] position = new int[2];
+ mActivityRule.runOnUiThread(() -> {
+ mMovingView.getLocationOnScreen(position);
+ position[0] += mMovingView.getWidth() / 2;
+ position[1] += mMovingView.getHeight() / 2;
+ });
+ final Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
+
+ long now = SystemClock.uptimeMillis();
+ MotionEvent down = MotionEvent.obtain(
+ now, // downTime
+ now, // eventTime
+ MotionEvent.ACTION_DOWN, // action
+ position[0], // x
+ position[1], // y
+ 0 // metaState
+ );
+ down.setSource(InputDevice.SOURCE_TOUCHSCREEN);
+ instrumentation.sendPointerSync(down);
+
+ now = SystemClock.uptimeMillis();
+ MotionEvent move = MotionEvent.obtain(
+ now, // downTime
+ now, // eventTime
+ MotionEvent.ACTION_MOVE, // action
+ position[0], // x
+ position[1], // y
+ 0 // metaState
+ );
+ move.setSource(InputDevice.SOURCE_TOUCHSCREEN);
+ instrumentation.sendPointerSync(move);
+
+ // We should continue to enable touch boost even when GTE compatibility is present.
+ mActivityRule.runOnUiThread(() -> {
+ mMovingView.offsetLeftAndRight(10);
+ assertTrue(mViewRoot.getIsTouchBoosting());
+ });
+
+ now = SystemClock.uptimeMillis();
+ MotionEvent up = MotionEvent.obtain(
+ now, // downTime
+ now, // eventTime
+ MotionEvent.ACTION_UP, // action
+ position[0], // x
+ position[1], // y
+ 0 // metaState
+ );
+ up.setSource(InputDevice.SOURCE_TOUCHSCREEN);
+ instrumentation.sendPointerSync(up);
+
+ // No touch boost when there is no ongoing pressed gesture.
+ mActivityRule.runOnUiThread(() -> {
+ mMovingView.offsetLeftAndRight(10);
+ assertFalse(mViewRoot.getIsTouchBoosting());
+ });
+
+ down.recycle();
+ move.recycle();
+ up.recycle();
+ }
+
@Test
@RequiresFlagsEnabled(FLAG_VIEW_VELOCITY_API)
public void frameBoostDisable() throws Throwable {