Loading core/java/android/view/View.java +8 −1 Original line number Diff line number Diff line Loading @@ -33933,6 +33933,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback, float velocity = mFrameContentVelocity; final float frameRate = mPreferredFrameRate; ViewParent parent = mParent; boolean isInputMethodWindowType = false; if (mAttachInfo != null && mAttachInfo.mViewRootImpl != null) { isInputMethodWindowType = mAttachInfo.mViewRootImpl.mWindowAttributes.type == TYPE_INPUT_METHOD; } if (velocity <= 0 && Float.isNaN(frameRate)) { // The most common case is when nothing is set, so this special case is called // often. Loading @@ -33942,7 +33947,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, || mLastFrameTop != mTop) && viewRootImpl.shouldCheckFrameRate(false) && parent instanceof View && ((View) parent).mFrameContentVelocity <= 0) { && ((View) parent).mFrameContentVelocity <= 0 && !isInputMethodWindowType) { viewRootImpl.votePreferredFrameRate(MAX_FRAME_RATE, FRAME_RATE_COMPATIBILITY_GTE); } if (viewRootImpl.shouldCheckFrameRateCategory()) { Loading @@ -33965,6 +33971,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, || mLastFrameTop != mTop) && mParent instanceof View && ((View) mParent).mFrameContentVelocity <= 0 && !isInputMethodWindowType ) { // This current calculation is very simple. If something on the screen // moved, then it votes for the highest velocity. core/tests/coretests/src/android/view/ViewFrameRateTest.java +48 −1 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static android.view.Surface.FRAME_RATE_CATEGORY_HIGH_HINT; import static android.view.Surface.FRAME_RATE_CATEGORY_LOW; import static android.view.Surface.FRAME_RATE_CATEGORY_NORMAL; 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_VELOCITY_MAPPING_READ_ONLY; 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; Loading Loading @@ -121,6 +122,52 @@ public class ViewFrameRateTest { waitForAfterDraw(); } @Test @RequiresFlagsEnabled({FLAG_VIEW_VELOCITY_API, FLAG_TOOLKIT_FRAME_RATE_VIEW_ENABLING_READ_ONLY}) public void inputMethodWithContentMoves() throws Throwable { if (!ViewProperties.vrr_enabled().orElse(true)) { return; } 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); waitForFrameRateCategoryToSettle(); mActivityRule.runOnUiThread(() -> { mMovingView.offsetLeftAndRight(100); runAfterDraw(() -> { if (toolkitFrameRateVelocityMappingReadOnly()) { float frameRate = mViewRoot.getLastPreferredFrameRate(); // frame rate shouldn't be boost with TYPE_INPUT_METHOD window type assertTrue(frameRate == 0); } else { assertEquals(FRAME_RATE_CATEGORY_HIGH, mViewRoot.getLastPreferredFrameRateCategory()); } }); }); waitForAfterDraw(); // 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); } @UiThreadTest @Test @RequiresFlagsEnabled(FLAG_VIEW_VELOCITY_API) Loading Loading @@ -161,7 +208,7 @@ public class ViewFrameRateTest { @RequiresFlagsEnabled({FLAG_VIEW_VELOCITY_API, FLAG_TOOLKIT_FRAME_RATE_VELOCITY_MAPPING_READ_ONLY, FLAG_TOOLKIT_FRAME_RATE_VIEW_ENABLING_READ_ONLY}) public void lowVelocity60() throws Throwable { public void lowVelocity80() throws Throwable { if (!ViewProperties.vrr_enabled().orElse(true)) { return; } Loading Loading
core/java/android/view/View.java +8 −1 Original line number Diff line number Diff line Loading @@ -33933,6 +33933,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback, float velocity = mFrameContentVelocity; final float frameRate = mPreferredFrameRate; ViewParent parent = mParent; boolean isInputMethodWindowType = false; if (mAttachInfo != null && mAttachInfo.mViewRootImpl != null) { isInputMethodWindowType = mAttachInfo.mViewRootImpl.mWindowAttributes.type == TYPE_INPUT_METHOD; } if (velocity <= 0 && Float.isNaN(frameRate)) { // The most common case is when nothing is set, so this special case is called // often. Loading @@ -33942,7 +33947,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, || mLastFrameTop != mTop) && viewRootImpl.shouldCheckFrameRate(false) && parent instanceof View && ((View) parent).mFrameContentVelocity <= 0) { && ((View) parent).mFrameContentVelocity <= 0 && !isInputMethodWindowType) { viewRootImpl.votePreferredFrameRate(MAX_FRAME_RATE, FRAME_RATE_COMPATIBILITY_GTE); } if (viewRootImpl.shouldCheckFrameRateCategory()) { Loading @@ -33965,6 +33971,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, || mLastFrameTop != mTop) && mParent instanceof View && ((View) mParent).mFrameContentVelocity <= 0 && !isInputMethodWindowType ) { // This current calculation is very simple. If something on the screen // moved, then it votes for the highest velocity.
core/tests/coretests/src/android/view/ViewFrameRateTest.java +48 −1 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static android.view.Surface.FRAME_RATE_CATEGORY_HIGH_HINT; import static android.view.Surface.FRAME_RATE_CATEGORY_LOW; import static android.view.Surface.FRAME_RATE_CATEGORY_NORMAL; 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_VELOCITY_MAPPING_READ_ONLY; 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; Loading Loading @@ -121,6 +122,52 @@ public class ViewFrameRateTest { waitForAfterDraw(); } @Test @RequiresFlagsEnabled({FLAG_VIEW_VELOCITY_API, FLAG_TOOLKIT_FRAME_RATE_VIEW_ENABLING_READ_ONLY}) public void inputMethodWithContentMoves() throws Throwable { if (!ViewProperties.vrr_enabled().orElse(true)) { return; } 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); waitForFrameRateCategoryToSettle(); mActivityRule.runOnUiThread(() -> { mMovingView.offsetLeftAndRight(100); runAfterDraw(() -> { if (toolkitFrameRateVelocityMappingReadOnly()) { float frameRate = mViewRoot.getLastPreferredFrameRate(); // frame rate shouldn't be boost with TYPE_INPUT_METHOD window type assertTrue(frameRate == 0); } else { assertEquals(FRAME_RATE_CATEGORY_HIGH, mViewRoot.getLastPreferredFrameRateCategory()); } }); }); waitForAfterDraw(); // 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); } @UiThreadTest @Test @RequiresFlagsEnabled(FLAG_VIEW_VELOCITY_API) Loading Loading @@ -161,7 +208,7 @@ public class ViewFrameRateTest { @RequiresFlagsEnabled({FLAG_VIEW_VELOCITY_API, FLAG_TOOLKIT_FRAME_RATE_VELOCITY_MAPPING_READ_ONLY, FLAG_TOOLKIT_FRAME_RATE_VIEW_ENABLING_READ_ONLY}) public void lowVelocity60() throws Throwable { public void lowVelocity80() throws Throwable { if (!ViewProperties.vrr_enabled().orElse(true)) { return; } Loading