Loading core/java/android/view/ViewRootImpl.java +6 −0 Original line number Diff line number Diff line Loading @@ -118,6 +118,7 @@ import static android.view.flags.Flags.disableDrawWakeLock; import static android.view.flags.Flags.sensitiveContentAppProtection; import static android.view.flags.Flags.sensitiveContentPrematureProtectionRemovedFix; import static android.view.flags.Flags.toolkitFrameRateFunctionEnablingReadOnly; import static android.view.flags.Flags.toolkitFrameRateTouchBoost25q1; import static android.view.flags.Flags.toolkitFrameRateTypingReadOnly; import static android.view.flags.Flags.toolkitFrameRateVelocityMappingReadOnly; import static android.view.flags.Flags.toolkitFrameRateViewEnablingReadOnly; Loading Loading @@ -13109,6 +13110,11 @@ public final class ViewRootImpl implements ViewParent, boolean desiredAction = motionEventAction != MotionEvent.ACTION_OUTSIDE; boolean undesiredType = windowType == TYPE_INPUT_METHOD && sToolkitFrameRateTypingReadOnlyFlagValue; // don't suppress touch boost for TYPE_INPUT_METHOD in ViewRootImpl if (toolkitFrameRateTouchBoost25q1()) { return desiredAction && shouldEnableDvrr() && getFrameRateBoostOnTouchEnabled(); } // use toolkitSetFrameRate flag to gate the change return desiredAction && !undesiredType && shouldEnableDvrr() && getFrameRateBoostOnTouchEnabled(); core/java/android/view/flags/refresh_rate_flags.aconfig +8 −0 Original line number Diff line number Diff line Loading @@ -120,3 +120,11 @@ flag { bug: "335874198" is_fixed_read_only: true } flag { name: "toolkit_frame_rate_touch_boost_25q1" namespace: "toolkit" description: "Feature flag to not suppress touch boost for specific windowTypes in VRR V QPR2" bug: "335874198" is_exported: true } No newline at end of file core/tests/coretests/src/android/view/ViewFrameRateTest.java +62 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import static android.view.Surface.FRAME_RATE_CATEGORY_NO_PREFERENCE; import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; import static android.view.flags.Flags.FLAG_TOOLKIT_FRAME_RATE_ANIMATION_BUGFIX_25Q1; import static android.view.flags.Flags.FLAG_TOOLKIT_FRAME_RATE_VELOCITY_MAPPING_READ_ONLY; import static android.view.flags.Flags.FLAG_TOOLKIT_FRAME_RATE_TOUCH_BOOST_25Q1; import static android.view.flags.Flags.FLAG_TOOLKIT_FRAME_RATE_VIEW_ENABLING_READ_ONLY; import static android.view.flags.Flags.FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY; import static android.view.flags.Flags.FLAG_VIEW_VELOCITY_API; Loading Loading @@ -117,6 +118,67 @@ public class ViewFrameRateTest { waitForAfterDraw(); } @Test @RequiresFlagsEnabled(FLAG_TOOLKIT_FRAME_RATE_TOUCH_BOOST_25Q1) public void shouldNotSuppressTouchBoost() 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(); // update the window type to TYPE_INPUT_METHOD int windowType = mViewRoot.mWindowAttributes.type; final WindowManager.LayoutParams attrs = mViewRoot.mWindowAttributes; attrs.type = TYPE_INPUT_METHOD; instrumentation.runOnMainSync(() -> { mViewRoot.setLayoutParams(attrs, false); }); instrumentation.waitForIdleSync(); final WindowManager.LayoutParams newAttrs = mViewRoot.mWindowAttributes; assertTrue(newAttrs.type == TYPE_INPUT_METHOD); 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); down.recycle(); // should have touch boost assertTrue(mViewRoot.getIsTouchBoosting()); // Reset the window type back to the original one. newAttrs.type = windowType; instrumentation.runOnMainSync(() -> { mViewRoot.setLayoutParams(newAttrs, false); }); instrumentation.waitForIdleSync(); assertTrue(mViewRoot.mWindowAttributes.type == windowType); } @Test @RequiresFlagsEnabled(FLAG_TOOLKIT_FRAME_RATE_VIEW_ENABLING_READ_ONLY) public void inputMethodWithContentMoves() throws Throwable { Loading Loading
core/java/android/view/ViewRootImpl.java +6 −0 Original line number Diff line number Diff line Loading @@ -118,6 +118,7 @@ import static android.view.flags.Flags.disableDrawWakeLock; import static android.view.flags.Flags.sensitiveContentAppProtection; import static android.view.flags.Flags.sensitiveContentPrematureProtectionRemovedFix; import static android.view.flags.Flags.toolkitFrameRateFunctionEnablingReadOnly; import static android.view.flags.Flags.toolkitFrameRateTouchBoost25q1; import static android.view.flags.Flags.toolkitFrameRateTypingReadOnly; import static android.view.flags.Flags.toolkitFrameRateVelocityMappingReadOnly; import static android.view.flags.Flags.toolkitFrameRateViewEnablingReadOnly; Loading Loading @@ -13109,6 +13110,11 @@ public final class ViewRootImpl implements ViewParent, boolean desiredAction = motionEventAction != MotionEvent.ACTION_OUTSIDE; boolean undesiredType = windowType == TYPE_INPUT_METHOD && sToolkitFrameRateTypingReadOnlyFlagValue; // don't suppress touch boost for TYPE_INPUT_METHOD in ViewRootImpl if (toolkitFrameRateTouchBoost25q1()) { return desiredAction && shouldEnableDvrr() && getFrameRateBoostOnTouchEnabled(); } // use toolkitSetFrameRate flag to gate the change return desiredAction && !undesiredType && shouldEnableDvrr() && getFrameRateBoostOnTouchEnabled();
core/java/android/view/flags/refresh_rate_flags.aconfig +8 −0 Original line number Diff line number Diff line Loading @@ -120,3 +120,11 @@ flag { bug: "335874198" is_fixed_read_only: true } flag { name: "toolkit_frame_rate_touch_boost_25q1" namespace: "toolkit" description: "Feature flag to not suppress touch boost for specific windowTypes in VRR V QPR2" bug: "335874198" is_exported: true } No newline at end of file
core/tests/coretests/src/android/view/ViewFrameRateTest.java +62 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import static android.view.Surface.FRAME_RATE_CATEGORY_NO_PREFERENCE; import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; import static android.view.flags.Flags.FLAG_TOOLKIT_FRAME_RATE_ANIMATION_BUGFIX_25Q1; import static android.view.flags.Flags.FLAG_TOOLKIT_FRAME_RATE_VELOCITY_MAPPING_READ_ONLY; import static android.view.flags.Flags.FLAG_TOOLKIT_FRAME_RATE_TOUCH_BOOST_25Q1; import static android.view.flags.Flags.FLAG_TOOLKIT_FRAME_RATE_VIEW_ENABLING_READ_ONLY; import static android.view.flags.Flags.FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY; import static android.view.flags.Flags.FLAG_VIEW_VELOCITY_API; Loading Loading @@ -117,6 +118,67 @@ public class ViewFrameRateTest { waitForAfterDraw(); } @Test @RequiresFlagsEnabled(FLAG_TOOLKIT_FRAME_RATE_TOUCH_BOOST_25Q1) public void shouldNotSuppressTouchBoost() 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(); // update the window type to TYPE_INPUT_METHOD int windowType = mViewRoot.mWindowAttributes.type; final WindowManager.LayoutParams attrs = mViewRoot.mWindowAttributes; attrs.type = TYPE_INPUT_METHOD; instrumentation.runOnMainSync(() -> { mViewRoot.setLayoutParams(attrs, false); }); instrumentation.waitForIdleSync(); final WindowManager.LayoutParams newAttrs = mViewRoot.mWindowAttributes; assertTrue(newAttrs.type == TYPE_INPUT_METHOD); 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); down.recycle(); // should have touch boost assertTrue(mViewRoot.getIsTouchBoosting()); // Reset the window type back to the original one. newAttrs.type = windowType; instrumentation.runOnMainSync(() -> { mViewRoot.setLayoutParams(newAttrs, false); }); instrumentation.waitForIdleSync(); assertTrue(mViewRoot.mWindowAttributes.type == windowType); } @Test @RequiresFlagsEnabled(FLAG_TOOLKIT_FRAME_RATE_VIEW_ENABLING_READ_ONLY) public void inputMethodWithContentMoves() throws Throwable { Loading