summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/view/View.java15
-rw-r--r--core/tests/coretests/src/android/view/ViewRootImplTest.java75
2 files changed, 88 insertions, 2 deletions
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 3df72e8b142a..7a1ab7bca6c0 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -33898,8 +33898,19 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
protected int calculateFrameRateCategory() {
int category;
switch (getViewRootImpl().intermittentUpdateState()) {
- case ViewRootImpl.INTERMITTENT_STATE_INTERMITTENT -> category =
- FRAME_RATE_CATEGORY_NORMAL | FRAME_RATE_CATEGORY_REASON_INTERMITTENT;
+ case ViewRootImpl.INTERMITTENT_STATE_INTERMITTENT -> {
+ if (!sToolkitFrameRateBySizeReadOnlyFlagValue) {
+ category = FRAME_RATE_CATEGORY_NORMAL;
+ } else {
+ // The size based frame rate category can only be LOW or NORMAL. If the size
+ // based frame rate category is LOW, we shouldn't vote for NORMAL for
+ // intermittent.
+ category = Math.min(
+ mSizeBasedFrameRateCategoryAndReason & ~FRAME_RATE_CATEGORY_REASON_MASK,
+ FRAME_RATE_CATEGORY_NORMAL);
+ }
+ category |= FRAME_RATE_CATEGORY_REASON_INTERMITTENT;
+ }
case ViewRootImpl.INTERMITTENT_STATE_NOT_INTERMITTENT ->
category = mSizeBasedFrameRateCategoryAndReason;
default -> category = mLastFrameRateCategory;
diff --git a/core/tests/coretests/src/android/view/ViewRootImplTest.java b/core/tests/coretests/src/android/view/ViewRootImplTest.java
index 06cb0eea811b..b15370049176 100644
--- a/core/tests/coretests/src/android/view/ViewRootImplTest.java
+++ b/core/tests/coretests/src/android/view/ViewRootImplTest.java
@@ -1250,6 +1250,81 @@ public class ViewRootImplTest {
});
}
+ @Test
+ @RequiresFlagsEnabled({FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY,
+ FLAG_TOOLKIT_FRAME_RATE_FUNCTION_ENABLING_READ_ONLY,
+ FLAG_TOOLKIT_FRAME_RATE_VIEW_ENABLING_READ_ONLY,
+ FLAG_TOOLKIT_FRAME_RATE_BY_SIZE_READ_ONLY})
+ public void votePreferredFrameRate_infrequentLayer_smallView_voteForLow() throws Throwable {
+ if (!ViewProperties.vrr_enabled().orElse(true)) {
+ return;
+ }
+ final long delay = 200L;
+
+ mView = new View(sContext);
+ WindowManager.LayoutParams wmlp = new WindowManager.LayoutParams(TYPE_APPLICATION_OVERLAY);
+ wmlp.token = new Binder(); // Set a fake token to bypass 'is your activity running' check
+ wmlp.width = 1;
+ wmlp.height = 1;
+
+ // The view is a small view, and it should vote for category low only.
+ int expected = FRAME_RATE_CATEGORY_LOW;
+
+ sInstrumentation.runOnMainSync(() -> {
+ WindowManager wm = sContext.getSystemService(WindowManager.class);
+ wm.addView(mView, wmlp);
+ });
+ sInstrumentation.waitForIdleSync();
+
+ mViewRootImpl = mView.getViewRootImpl();
+ waitForFrameRateCategoryToSettle(mView);
+
+ // In transition from frequent update to infrequent update
+ Thread.sleep(delay);
+ sInstrumentation.runOnMainSync(() -> {
+ mView.invalidate();
+ runAfterDraw(() -> assertEquals(expected,
+ mViewRootImpl.getLastPreferredFrameRateCategory()));
+ });
+ waitForAfterDraw();
+
+ // In transition from frequent update to infrequent update
+ Thread.sleep(delay);
+ sInstrumentation.runOnMainSync(() -> {
+ mView.invalidate();
+ runAfterDraw(() -> assertEquals(expected,
+ mViewRootImpl.getLastPreferredFrameRateCategory()));
+ });
+
+ // Infrequent update
+ Thread.sleep(delay);
+
+ // The view is small, the expected category is still low for intermittent.
+ int intermittentExpected = FRAME_RATE_CATEGORY_LOW;
+
+ sInstrumentation.runOnMainSync(() -> {
+ mView.invalidate();
+ runAfterDraw(() -> assertEquals(intermittentExpected,
+ mViewRootImpl.getLastPreferredFrameRateCategory()));
+ });
+ waitForAfterDraw();
+
+ // When the View vote, it's still considered as intermittent update state
+ sInstrumentation.runOnMainSync(() -> {
+ mView.invalidate();
+ runAfterDraw(() -> assertEquals(intermittentExpected,
+ mViewRootImpl.getLastPreferredFrameRateCategory()));
+ });
+ waitForAfterDraw();
+
+ // Becomes frequent update state
+ sInstrumentation.runOnMainSync(() -> {
+ mView.invalidate();
+ runAfterDraw(() -> assertEquals(expected,
+ mViewRootImpl.getLastPreferredFrameRateCategory()));
+ });
+ }
+
/**
* Test the IsFrameRatePowerSavingsBalanced values are properly set
*/