Loading core/java/android/view/ViewRootImpl.java +15 −0 Original line number Diff line number Diff line Loading @@ -1132,6 +1132,8 @@ public final class ViewRootImpl implements ViewParent, // time for evaluating the interval between current time and // the time when frame rate was set previously. private static final int FRAME_RATE_SETTING_REEVALUATE_TIME = 100; // timeout for surface replaced. private static final int FRAME_RATE_SURFACE_REPLACED_TIME = 3000; /* * The variables below are used to update frame rate category Loading Loading @@ -3831,6 +3833,9 @@ public final class ViewRootImpl implements ViewParent, if (surfaceReplaced) { mSurfaceReplaced = true; mSurfaceSequenceId++; mHandler.removeMessages(MSG_SURFACE_REPLACED_TIMEOUT); mHandler.sendEmptyMessageDelayed(MSG_SURFACE_REPLACED_TIMEOUT, FRAME_RATE_SURFACE_REPLACED_TIME); } if (alwaysConsumeSystemBarsChanged) { mAttachInfo.mAlwaysConsumeSystemBars = mPendingAlwaysConsumeSystemBars; Loading Loading @@ -6696,6 +6701,7 @@ public final class ViewRootImpl implements ViewParent, private static final int MSG_CHECK_INVALIDATION_IDLE = 40; private static final int MSG_REFRESH_POINTER_ICON = 41; private static final int MSG_FRAME_RATE_SETTING = 42; private static final int MSG_SURFACE_REPLACED_TIMEOUT = 43; final class ViewRootHandler extends Handler { @Override Loading Loading @@ -6767,6 +6773,8 @@ public final class ViewRootImpl implements ViewParent, return "MSG_TOUCH_BOOST_TIMEOUT"; case MSG_FRAME_RATE_SETTING: return "MSG_FRAME_RATE_SETTING"; case MSG_SURFACE_REPLACED_TIMEOUT: return "MSG_SURFACE_REPLACED_TIMEOUT"; } return super.getMessageName(message); } Loading Loading @@ -7038,6 +7046,9 @@ public final class ViewRootImpl implements ViewParent, */ mIsFrameRateBoosting = false; mIsTouchBoosting = false; if (!mDrawnThisFrame) { setPreferredFrameRateCategory(FRAME_RATE_CATEGORY_NO_PREFERENCE); } break; case MSG_REFRESH_POINTER_ICON: if (mPointerIconEvent == null) { Loading @@ -7049,6 +7060,9 @@ public final class ViewRootImpl implements ViewParent, mPreferredFrameRate = 0; mFrameRateCompatibility = FRAME_RATE_COMPATIBILITY_FIXED_SOURCE; break; case MSG_SURFACE_REPLACED_TIMEOUT: mSurfaceReplaced = false; break; } } } Loading Loading @@ -13392,6 +13406,7 @@ public final class ViewRootImpl implements ViewParent, private void removeVrrMessages() { mHandler.removeMessages(MSG_TOUCH_BOOST_TIMEOUT); mHandler.removeMessages(MSG_FRAME_RATE_SETTING); mHandler.removeMessages(MSG_SURFACE_REPLACED_TIMEOUT); if (mInvalidationIdleMessagePosted && sSurfaceFlingerBugfixFlagValue) { mInvalidationIdleMessagePosted = false; mHandler.removeMessages(MSG_CHECK_INVALIDATION_IDLE); core/tests/coretests/src/android/view/ViewFrameRateTest.java +59 −0 Original line number Diff line number Diff line Loading @@ -891,6 +891,65 @@ public class ViewFrameRateTest { }); } @Test @RequiresFlagsEnabled({FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY, FLAG_TOOLKIT_FRAME_RATE_VIEW_ENABLING_READ_ONLY }) public void testTouchBoostReset() throws Throwable { if (!ViewProperties.vrr_enabled().orElse(true)) { return; } mActivityRule.runOnUiThread(() -> { ViewGroup.LayoutParams layoutParams = mMovingView.getLayoutParams(); layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT; layoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT; mMovingView.setLayoutParams(layoutParams); mMovingView.setOnClickListener((v) -> {}); }); waitForFrameRateCategoryToSettle(); 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); assertEquals(FRAME_RATE_CATEGORY_HIGH_HINT, mViewRoot.getLastPreferredFrameRateCategory()); 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); // Wait for idle timeout - 100 ms logner to avoid flaky Thread.sleep(3100); // Should not touch boost after the time out assertEquals(false, mViewRoot.getIsTouchBoosting()); assertEquals(FRAME_RATE_CATEGORY_NO_PREFERENCE, mViewRoot.getLastPreferredFrameRateCategory()); } @LargeTest @Test @RequiresFlagsEnabled({FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY, Loading Loading
core/java/android/view/ViewRootImpl.java +15 −0 Original line number Diff line number Diff line Loading @@ -1132,6 +1132,8 @@ public final class ViewRootImpl implements ViewParent, // time for evaluating the interval between current time and // the time when frame rate was set previously. private static final int FRAME_RATE_SETTING_REEVALUATE_TIME = 100; // timeout for surface replaced. private static final int FRAME_RATE_SURFACE_REPLACED_TIME = 3000; /* * The variables below are used to update frame rate category Loading Loading @@ -3831,6 +3833,9 @@ public final class ViewRootImpl implements ViewParent, if (surfaceReplaced) { mSurfaceReplaced = true; mSurfaceSequenceId++; mHandler.removeMessages(MSG_SURFACE_REPLACED_TIMEOUT); mHandler.sendEmptyMessageDelayed(MSG_SURFACE_REPLACED_TIMEOUT, FRAME_RATE_SURFACE_REPLACED_TIME); } if (alwaysConsumeSystemBarsChanged) { mAttachInfo.mAlwaysConsumeSystemBars = mPendingAlwaysConsumeSystemBars; Loading Loading @@ -6696,6 +6701,7 @@ public final class ViewRootImpl implements ViewParent, private static final int MSG_CHECK_INVALIDATION_IDLE = 40; private static final int MSG_REFRESH_POINTER_ICON = 41; private static final int MSG_FRAME_RATE_SETTING = 42; private static final int MSG_SURFACE_REPLACED_TIMEOUT = 43; final class ViewRootHandler extends Handler { @Override Loading Loading @@ -6767,6 +6773,8 @@ public final class ViewRootImpl implements ViewParent, return "MSG_TOUCH_BOOST_TIMEOUT"; case MSG_FRAME_RATE_SETTING: return "MSG_FRAME_RATE_SETTING"; case MSG_SURFACE_REPLACED_TIMEOUT: return "MSG_SURFACE_REPLACED_TIMEOUT"; } return super.getMessageName(message); } Loading Loading @@ -7038,6 +7046,9 @@ public final class ViewRootImpl implements ViewParent, */ mIsFrameRateBoosting = false; mIsTouchBoosting = false; if (!mDrawnThisFrame) { setPreferredFrameRateCategory(FRAME_RATE_CATEGORY_NO_PREFERENCE); } break; case MSG_REFRESH_POINTER_ICON: if (mPointerIconEvent == null) { Loading @@ -7049,6 +7060,9 @@ public final class ViewRootImpl implements ViewParent, mPreferredFrameRate = 0; mFrameRateCompatibility = FRAME_RATE_COMPATIBILITY_FIXED_SOURCE; break; case MSG_SURFACE_REPLACED_TIMEOUT: mSurfaceReplaced = false; break; } } } Loading Loading @@ -13392,6 +13406,7 @@ public final class ViewRootImpl implements ViewParent, private void removeVrrMessages() { mHandler.removeMessages(MSG_TOUCH_BOOST_TIMEOUT); mHandler.removeMessages(MSG_FRAME_RATE_SETTING); mHandler.removeMessages(MSG_SURFACE_REPLACED_TIMEOUT); if (mInvalidationIdleMessagePosted && sSurfaceFlingerBugfixFlagValue) { mInvalidationIdleMessagePosted = false; mHandler.removeMessages(MSG_CHECK_INVALIDATION_IDLE);
core/tests/coretests/src/android/view/ViewFrameRateTest.java +59 −0 Original line number Diff line number Diff line Loading @@ -891,6 +891,65 @@ public class ViewFrameRateTest { }); } @Test @RequiresFlagsEnabled({FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY, FLAG_TOOLKIT_FRAME_RATE_VIEW_ENABLING_READ_ONLY }) public void testTouchBoostReset() throws Throwable { if (!ViewProperties.vrr_enabled().orElse(true)) { return; } mActivityRule.runOnUiThread(() -> { ViewGroup.LayoutParams layoutParams = mMovingView.getLayoutParams(); layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT; layoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT; mMovingView.setLayoutParams(layoutParams); mMovingView.setOnClickListener((v) -> {}); }); waitForFrameRateCategoryToSettle(); 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); assertEquals(FRAME_RATE_CATEGORY_HIGH_HINT, mViewRoot.getLastPreferredFrameRateCategory()); 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); // Wait for idle timeout - 100 ms logner to avoid flaky Thread.sleep(3100); // Should not touch boost after the time out assertEquals(false, mViewRoot.getIsTouchBoosting()); assertEquals(FRAME_RATE_CATEGORY_NO_PREFERENCE, mViewRoot.getLastPreferredFrameRateCategory()); } @LargeTest @Test @RequiresFlagsEnabled({FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY, Loading