Loading core/java/android/view/TextureView.java +0 −2 Original line number Diff line number Diff line Loading @@ -196,8 +196,6 @@ public class TextureView extends View { private Canvas mCanvas; private int mSaveCount; @Surface.FrameRateCompatibility int mFrameRateCompatibility; private final Object[] mNativeWindowLock = new Object[0]; // Set by native code, do not write! @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) Loading core/java/android/view/View.java +6 −1 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import static android.view.Surface.FRAME_RATE_CATEGORY_HIGH; 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.Surface.FRAME_RATE_COMPATIBILITY_FIXED_SOURCE; import static android.view.accessibility.AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED; import static android.view.displayhash.DisplayHashResultCallback.DISPLAY_HASH_ERROR_INVALID_BOUNDS; import static android.view.displayhash.DisplayHashResultCallback.DISPLAY_HASH_ERROR_MISSING_WINDOW; Loading Loading @@ -2368,6 +2369,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, private static boolean sToolkitSetFrameRateReadOnlyFlagValue; private static boolean sToolkitMetricsForFrameRateDecisionFlagValue; // Used to set frame rate compatibility. @Surface.FrameRateCompatibility int mFrameRateCompatibility = FRAME_RATE_COMPATIBILITY_FIXED_SOURCE; static { EMPTY_STATE_SET = StateSet.get(0); Loading Loading @@ -33538,7 +33542,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, frameRateCateogry = FRAME_RATE_CATEGORY_HIGH; } } else { viewRootImpl.votePreferredFrameRate(mPreferredFrameRate); viewRootImpl.votePreferredFrameRate(mPreferredFrameRate, mFrameRateCompatibility); return; } } core/java/android/view/ViewRootImpl.java +63 −13 Original line number Diff line number Diff line Loading @@ -30,6 +30,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.Surface.FRAME_RATE_COMPATIBILITY_FIXED_SOURCE; import static android.view.View.PFLAG_DRAW_ANIMATION; import static android.view.View.SYSTEM_UI_FLAG_FULLSCREEN; import static android.view.View.SYSTEM_UI_FLAG_HIDE_NAVIGATION; Loading Loading @@ -1027,6 +1028,13 @@ public final class ViewRootImpl implements ViewParent, // as needed and can be useful for power saving. // Should not enable the dVRR feature if the value is false. private boolean mIsFrameRatePowerSavingsBalanced = true; // 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. // We consider there is a conflict. private boolean mIsFrameRateConflicted = false; // Used to set frame rate compatibility. @Surface.FrameRateCompatibility int mFrameRateCompatibility = FRAME_RATE_COMPATIBILITY_FIXED_SOURCE; // time for touch boost period. private static final int FRAME_RATE_TOUCH_BOOST_TIME = 3000; // time for checking idle status periodically. Loading Loading @@ -4110,6 +4118,7 @@ public final class ViewRootImpl implements ViewParent, ? mFrameRateCategoryLowCount - 1 : mFrameRateCategoryLowCount; mPreferredFrameRateCategory = FRAME_RATE_CATEGORY_NO_PREFERENCE; mPreferredFrameRate = -1; mIsFrameRateConflicted = false; } private void createSyncIfNeeded() { Loading Loading @@ -6508,6 +6517,7 @@ public final class ViewRootImpl implements ViewParent, break; case MSG_FRAME_RATE_SETTING: mPreferredFrameRate = 0; mFrameRateCompatibility = FRAME_RATE_COMPATIBILITY_FIXED_SOURCE; setPreferredFrameRate(mPreferredFrameRate); break; } Loading Loading @@ -12286,9 +12296,15 @@ public final class ViewRootImpl implements ViewParent, if (!shouldSetFrameRateCategory()) { return; } int categoryFromConflictedFrameRates = FRAME_RATE_CATEGORY_NO_PREFERENCE; if (mIsFrameRateConflicted) { categoryFromConflictedFrameRates = mPreferredFrameRate > 60 ? FRAME_RATE_CATEGORY_HIGH : FRAME_RATE_CATEGORY_NORMAL; } int frameRateCategory = mIsTouchBoosting ? FRAME_RATE_CATEGORY_HIGH_HINT : preferredFrameRateCategory; ? FRAME_RATE_CATEGORY_HIGH_HINT : Math.max(preferredFrameRateCategory, categoryFromConflictedFrameRates); // FRAME_RATE_CATEGORY_HIGH has a higher precedence than FRAME_RATE_CATEGORY_HIGH_HINT // For now, FRAME_RATE_CATEGORY_HIGH_HINT is used for boosting with user interaction. Loading Loading @@ -12338,7 +12354,7 @@ public final class ViewRootImpl implements ViewParent, + preferredFrameRate); } mFrameRateTransaction.setFrameRate(mSurfaceControl, preferredFrameRate, Surface.FRAME_RATE_COMPATIBILITY_DEFAULT).applyAsyncUnsafe(); mFrameRateCompatibility).applyAsyncUnsafe(); mLastPreferredFrameRate = preferredFrameRate; } } catch (Exception e) { Loading @@ -12361,7 +12377,8 @@ public final class ViewRootImpl implements ViewParent, private boolean shouldSetFrameRate() { // use toolkitSetFrameRate flag to gate the change return mSurface.isValid() && mPreferredFrameRate > 0 && shouldEnableDvrr(); return mSurface.isValid() && mPreferredFrameRate > 0 && shouldEnableDvrr() && !mIsFrameRateConflicted; } private boolean shouldTouchBoost(int motionEventAction, int windowType) { Loading Loading @@ -12404,30 +12421,46 @@ public final class ViewRootImpl implements ViewParent, } /** * Allow Views to vote for the preferred frame rate * Allow Views to vote for the preferred frame rate and compatibility. * When determining the preferred frame rate value, * we follow this logic: If no preferred frame rate has been set yet, * we assign the value of frameRate as the preferred frame rate. * If either the current or the new preferred frame rate exceeds 60 Hz, * we select the higher value between them. * However, if both values are 60 Hz or lower, we set the preferred frame rate * to 60 Hz to maintain optimal performance. * IF there are multiple frame rates are voted: * 1. There is a frame rate is a multiple of all other frame rates. * We choose this frmae rate to be the one to be set. * 2. There is no frame rate can be a multiple of others * We set category to HIGH if the maximum frame rate is greater than 60. * Otherwise, we set category to NORMAL. * * Use FRAME_RATE_COMPATIBILITY_GTE for velocity and FRAME_RATE_COMPATIBILITY_FIXED_SOURCE * for TextureView video play and user requested frame rate. * * @param frameRate the preferred frame rate of a View * @param frameRateCompatibility the preferred frame rate compatibility of a View */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PROTECTED) public void votePreferredFrameRate(float frameRate) { public void votePreferredFrameRate(float frameRate, int frameRateCompatibility) { if (frameRate <= 0) { return; } if (mPreferredFrameRate > 0 && mPreferredFrameRate % frameRate != 0 && frameRate % mPreferredFrameRate != 0) { mIsFrameRateConflicted = true; mFrameRateCompatibility = FRAME_RATE_COMPATIBILITY_FIXED_SOURCE; } if (frameRate > mPreferredFrameRate) { mFrameRateCompatibility = frameRateCompatibility; } mPreferredFrameRate = Math.max(mPreferredFrameRate, frameRate); mHasInvalidation = true; if (!mIsFrameRateConflicted) { mHandler.removeMessages(MSG_FRAME_RATE_SETTING); mHandler.sendEmptyMessageDelayed(MSG_FRAME_RATE_SETTING, FRAME_RATE_SETTING_REEVALUATE_TIME); } } /** * Get the value of mPreferredFrameRateCategory Loading @@ -12453,6 +12486,14 @@ public final class ViewRootImpl implements ViewParent, return mPreferredFrameRate >= 0 ? mPreferredFrameRate : mLastPreferredFrameRate; } /** * Get the value of mFrameRateCompatibility */ @VisibleForTesting public int getFrameRateCompatibility() { return mFrameRateCompatibility; } /** * Get the value of mIsFrameRateBoosting */ Loading Loading @@ -12502,6 +12543,15 @@ public final class ViewRootImpl implements ViewParent, return mIsFrameRatePowerSavingsBalanced; } /** * Get the value of mIsFrameRateConflicted * Can be used to checked if there is a conflict of frame rate votes. */ @VisibleForTesting public boolean isFrameRateConflicted() { return mIsFrameRateConflicted; } /** * Set the value of mIsFrameRatePowerSavingsBalanced * Can be used to checked if toolkit dVRR feature is enabled. core/tests/coretests/src/android/view/ViewRootImplTest.java +54 −6 Original line number Diff line number Diff line Loading @@ -24,6 +24,8 @@ 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.Surface.FRAME_RATE_COMPATIBILITY_FIXED_SOURCE; import static android.view.Surface.FRAME_RATE_COMPATIBILITY_GTE; import static android.view.View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY; import static android.view.View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN; import static android.view.View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION; Loading Loading @@ -705,17 +707,51 @@ public class ViewRootImplTest { public void votePreferredFrameRate_voteFrameRate_aggregate() { View view = new View(sContext); attachViewToWindow(view); sInstrumentation.runOnMainSync(() -> { ViewRootImpl viewRootImpl = view.getViewRootImpl(); sInstrumentation.runOnMainSync(() -> { assertEquals(viewRootImpl.getPreferredFrameRate(), 0, 0.1); viewRootImpl.votePreferredFrameRate(24); assertEquals(viewRootImpl.getFrameRateCompatibility(), FRAME_RATE_COMPATIBILITY_FIXED_SOURCE); assertEquals(viewRootImpl.isFrameRateConflicted(), false); viewRootImpl.votePreferredFrameRate(24, FRAME_RATE_COMPATIBILITY_GTE); assertEquals(viewRootImpl.getPreferredFrameRate(), 24, 0.1); viewRootImpl.votePreferredFrameRate(30); assertEquals(viewRootImpl.getFrameRateCompatibility(), FRAME_RATE_COMPATIBILITY_GTE); assertEquals(viewRootImpl.isFrameRateConflicted(), false); viewRootImpl.votePreferredFrameRate(30, FRAME_RATE_COMPATIBILITY_FIXED_SOURCE); assertEquals(viewRootImpl.getPreferredFrameRate(), 30, 0.1); viewRootImpl.votePreferredFrameRate(60); // If there is a conflict, then set compatibility to // FRAME_RATE_COMPATIBILITY_FIXED_SOURCE assertEquals(viewRootImpl.getFrameRateCompatibility(), FRAME_RATE_COMPATIBILITY_FIXED_SOURCE); // Should be true since there is a conflict between 24 and 30. assertEquals(viewRootImpl.isFrameRateConflicted(), true); view.invalidate(); }); sInstrumentation.waitForIdleSync(); sInstrumentation.runOnMainSync(() -> { assertEquals(viewRootImpl.isFrameRateConflicted(), false); viewRootImpl.votePreferredFrameRate(60, FRAME_RATE_COMPATIBILITY_GTE); assertEquals(viewRootImpl.getPreferredFrameRate(), 60, 0.1); viewRootImpl.votePreferredFrameRate(120); assertEquals(viewRootImpl.getFrameRateCompatibility(), FRAME_RATE_COMPATIBILITY_GTE); assertEquals(viewRootImpl.isFrameRateConflicted(), false); viewRootImpl.votePreferredFrameRate(120, FRAME_RATE_COMPATIBILITY_FIXED_SOURCE); assertEquals(viewRootImpl.getPreferredFrameRate(), 120, 0.1); assertEquals(viewRootImpl.getFrameRateCompatibility(), FRAME_RATE_COMPATIBILITY_FIXED_SOURCE); // Should be false since 60 is a divisor of 120. assertEquals(viewRootImpl.isFrameRateConflicted(), false); viewRootImpl.votePreferredFrameRate(60, FRAME_RATE_COMPATIBILITY_GTE); assertEquals(viewRootImpl.getPreferredFrameRate(), 120, 0.1); // compatibility should be remained the same (FRAME_RATE_COMPATIBILITY_FIXED_SOURCE) // since the frame rate 60 is smaller than 120. assertEquals(viewRootImpl.getFrameRateCompatibility(), FRAME_RATE_COMPATIBILITY_FIXED_SOURCE); // Should be false since 60 is a divisor of 120. assertEquals(viewRootImpl.isFrameRateConflicted(), false); }); } Loading Loading @@ -842,14 +878,26 @@ public class ViewRootImplTest { sInstrumentation.runOnMainSync(() -> { assertEquals(viewRootImpl.getPreferredFrameRate(), 0, 0.1); viewRootImpl.votePreferredFrameRate(24); assertEquals(viewRootImpl.getFrameRateCompatibility(), FRAME_RATE_COMPATIBILITY_FIXED_SOURCE); assertEquals(viewRootImpl.isFrameRateConflicted(), false); viewRootImpl.votePreferredFrameRate(24, FRAME_RATE_COMPATIBILITY_FIXED_SOURCE); assertEquals(viewRootImpl.getPreferredFrameRate(), 24, 0.1); assertEquals(viewRootImpl.getFrameRateCompatibility(), FRAME_RATE_COMPATIBILITY_FIXED_SOURCE); assertEquals(viewRootImpl.isFrameRateConflicted(), false); view.invalidate(); assertEquals(viewRootImpl.getPreferredFrameRate(), 24, 0.1); assertEquals(viewRootImpl.getFrameRateCompatibility(), FRAME_RATE_COMPATIBILITY_FIXED_SOURCE); assertEquals(viewRootImpl.isFrameRateConflicted(), false); }); Thread.sleep(delay); assertEquals(viewRootImpl.getPreferredFrameRate(), 0, 0.1); assertEquals(viewRootImpl.getFrameRateCompatibility(), FRAME_RATE_COMPATIBILITY_FIXED_SOURCE); assertEquals(viewRootImpl.isFrameRateConflicted(), false); } /** Loading Loading
core/java/android/view/TextureView.java +0 −2 Original line number Diff line number Diff line Loading @@ -196,8 +196,6 @@ public class TextureView extends View { private Canvas mCanvas; private int mSaveCount; @Surface.FrameRateCompatibility int mFrameRateCompatibility; private final Object[] mNativeWindowLock = new Object[0]; // Set by native code, do not write! @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) Loading
core/java/android/view/View.java +6 −1 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import static android.view.Surface.FRAME_RATE_CATEGORY_HIGH; 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.Surface.FRAME_RATE_COMPATIBILITY_FIXED_SOURCE; import static android.view.accessibility.AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED; import static android.view.displayhash.DisplayHashResultCallback.DISPLAY_HASH_ERROR_INVALID_BOUNDS; import static android.view.displayhash.DisplayHashResultCallback.DISPLAY_HASH_ERROR_MISSING_WINDOW; Loading Loading @@ -2368,6 +2369,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, private static boolean sToolkitSetFrameRateReadOnlyFlagValue; private static boolean sToolkitMetricsForFrameRateDecisionFlagValue; // Used to set frame rate compatibility. @Surface.FrameRateCompatibility int mFrameRateCompatibility = FRAME_RATE_COMPATIBILITY_FIXED_SOURCE; static { EMPTY_STATE_SET = StateSet.get(0); Loading Loading @@ -33538,7 +33542,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, frameRateCateogry = FRAME_RATE_CATEGORY_HIGH; } } else { viewRootImpl.votePreferredFrameRate(mPreferredFrameRate); viewRootImpl.votePreferredFrameRate(mPreferredFrameRate, mFrameRateCompatibility); return; } }
core/java/android/view/ViewRootImpl.java +63 −13 Original line number Diff line number Diff line Loading @@ -30,6 +30,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.Surface.FRAME_RATE_COMPATIBILITY_FIXED_SOURCE; import static android.view.View.PFLAG_DRAW_ANIMATION; import static android.view.View.SYSTEM_UI_FLAG_FULLSCREEN; import static android.view.View.SYSTEM_UI_FLAG_HIDE_NAVIGATION; Loading Loading @@ -1027,6 +1028,13 @@ public final class ViewRootImpl implements ViewParent, // as needed and can be useful for power saving. // Should not enable the dVRR feature if the value is false. private boolean mIsFrameRatePowerSavingsBalanced = true; // 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. // We consider there is a conflict. private boolean mIsFrameRateConflicted = false; // Used to set frame rate compatibility. @Surface.FrameRateCompatibility int mFrameRateCompatibility = FRAME_RATE_COMPATIBILITY_FIXED_SOURCE; // time for touch boost period. private static final int FRAME_RATE_TOUCH_BOOST_TIME = 3000; // time for checking idle status periodically. Loading Loading @@ -4110,6 +4118,7 @@ public final class ViewRootImpl implements ViewParent, ? mFrameRateCategoryLowCount - 1 : mFrameRateCategoryLowCount; mPreferredFrameRateCategory = FRAME_RATE_CATEGORY_NO_PREFERENCE; mPreferredFrameRate = -1; mIsFrameRateConflicted = false; } private void createSyncIfNeeded() { Loading Loading @@ -6508,6 +6517,7 @@ public final class ViewRootImpl implements ViewParent, break; case MSG_FRAME_RATE_SETTING: mPreferredFrameRate = 0; mFrameRateCompatibility = FRAME_RATE_COMPATIBILITY_FIXED_SOURCE; setPreferredFrameRate(mPreferredFrameRate); break; } Loading Loading @@ -12286,9 +12296,15 @@ public final class ViewRootImpl implements ViewParent, if (!shouldSetFrameRateCategory()) { return; } int categoryFromConflictedFrameRates = FRAME_RATE_CATEGORY_NO_PREFERENCE; if (mIsFrameRateConflicted) { categoryFromConflictedFrameRates = mPreferredFrameRate > 60 ? FRAME_RATE_CATEGORY_HIGH : FRAME_RATE_CATEGORY_NORMAL; } int frameRateCategory = mIsTouchBoosting ? FRAME_RATE_CATEGORY_HIGH_HINT : preferredFrameRateCategory; ? FRAME_RATE_CATEGORY_HIGH_HINT : Math.max(preferredFrameRateCategory, categoryFromConflictedFrameRates); // FRAME_RATE_CATEGORY_HIGH has a higher precedence than FRAME_RATE_CATEGORY_HIGH_HINT // For now, FRAME_RATE_CATEGORY_HIGH_HINT is used for boosting with user interaction. Loading Loading @@ -12338,7 +12354,7 @@ public final class ViewRootImpl implements ViewParent, + preferredFrameRate); } mFrameRateTransaction.setFrameRate(mSurfaceControl, preferredFrameRate, Surface.FRAME_RATE_COMPATIBILITY_DEFAULT).applyAsyncUnsafe(); mFrameRateCompatibility).applyAsyncUnsafe(); mLastPreferredFrameRate = preferredFrameRate; } } catch (Exception e) { Loading @@ -12361,7 +12377,8 @@ public final class ViewRootImpl implements ViewParent, private boolean shouldSetFrameRate() { // use toolkitSetFrameRate flag to gate the change return mSurface.isValid() && mPreferredFrameRate > 0 && shouldEnableDvrr(); return mSurface.isValid() && mPreferredFrameRate > 0 && shouldEnableDvrr() && !mIsFrameRateConflicted; } private boolean shouldTouchBoost(int motionEventAction, int windowType) { Loading Loading @@ -12404,30 +12421,46 @@ public final class ViewRootImpl implements ViewParent, } /** * Allow Views to vote for the preferred frame rate * Allow Views to vote for the preferred frame rate and compatibility. * When determining the preferred frame rate value, * we follow this logic: If no preferred frame rate has been set yet, * we assign the value of frameRate as the preferred frame rate. * If either the current or the new preferred frame rate exceeds 60 Hz, * we select the higher value between them. * However, if both values are 60 Hz or lower, we set the preferred frame rate * to 60 Hz to maintain optimal performance. * IF there are multiple frame rates are voted: * 1. There is a frame rate is a multiple of all other frame rates. * We choose this frmae rate to be the one to be set. * 2. There is no frame rate can be a multiple of others * We set category to HIGH if the maximum frame rate is greater than 60. * Otherwise, we set category to NORMAL. * * Use FRAME_RATE_COMPATIBILITY_GTE for velocity and FRAME_RATE_COMPATIBILITY_FIXED_SOURCE * for TextureView video play and user requested frame rate. * * @param frameRate the preferred frame rate of a View * @param frameRateCompatibility the preferred frame rate compatibility of a View */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PROTECTED) public void votePreferredFrameRate(float frameRate) { public void votePreferredFrameRate(float frameRate, int frameRateCompatibility) { if (frameRate <= 0) { return; } if (mPreferredFrameRate > 0 && mPreferredFrameRate % frameRate != 0 && frameRate % mPreferredFrameRate != 0) { mIsFrameRateConflicted = true; mFrameRateCompatibility = FRAME_RATE_COMPATIBILITY_FIXED_SOURCE; } if (frameRate > mPreferredFrameRate) { mFrameRateCompatibility = frameRateCompatibility; } mPreferredFrameRate = Math.max(mPreferredFrameRate, frameRate); mHasInvalidation = true; if (!mIsFrameRateConflicted) { mHandler.removeMessages(MSG_FRAME_RATE_SETTING); mHandler.sendEmptyMessageDelayed(MSG_FRAME_RATE_SETTING, FRAME_RATE_SETTING_REEVALUATE_TIME); } } /** * Get the value of mPreferredFrameRateCategory Loading @@ -12453,6 +12486,14 @@ public final class ViewRootImpl implements ViewParent, return mPreferredFrameRate >= 0 ? mPreferredFrameRate : mLastPreferredFrameRate; } /** * Get the value of mFrameRateCompatibility */ @VisibleForTesting public int getFrameRateCompatibility() { return mFrameRateCompatibility; } /** * Get the value of mIsFrameRateBoosting */ Loading Loading @@ -12502,6 +12543,15 @@ public final class ViewRootImpl implements ViewParent, return mIsFrameRatePowerSavingsBalanced; } /** * Get the value of mIsFrameRateConflicted * Can be used to checked if there is a conflict of frame rate votes. */ @VisibleForTesting public boolean isFrameRateConflicted() { return mIsFrameRateConflicted; } /** * Set the value of mIsFrameRatePowerSavingsBalanced * Can be used to checked if toolkit dVRR feature is enabled.
core/tests/coretests/src/android/view/ViewRootImplTest.java +54 −6 Original line number Diff line number Diff line Loading @@ -24,6 +24,8 @@ 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.Surface.FRAME_RATE_COMPATIBILITY_FIXED_SOURCE; import static android.view.Surface.FRAME_RATE_COMPATIBILITY_GTE; import static android.view.View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY; import static android.view.View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN; import static android.view.View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION; Loading Loading @@ -705,17 +707,51 @@ public class ViewRootImplTest { public void votePreferredFrameRate_voteFrameRate_aggregate() { View view = new View(sContext); attachViewToWindow(view); sInstrumentation.runOnMainSync(() -> { ViewRootImpl viewRootImpl = view.getViewRootImpl(); sInstrumentation.runOnMainSync(() -> { assertEquals(viewRootImpl.getPreferredFrameRate(), 0, 0.1); viewRootImpl.votePreferredFrameRate(24); assertEquals(viewRootImpl.getFrameRateCompatibility(), FRAME_RATE_COMPATIBILITY_FIXED_SOURCE); assertEquals(viewRootImpl.isFrameRateConflicted(), false); viewRootImpl.votePreferredFrameRate(24, FRAME_RATE_COMPATIBILITY_GTE); assertEquals(viewRootImpl.getPreferredFrameRate(), 24, 0.1); viewRootImpl.votePreferredFrameRate(30); assertEquals(viewRootImpl.getFrameRateCompatibility(), FRAME_RATE_COMPATIBILITY_GTE); assertEquals(viewRootImpl.isFrameRateConflicted(), false); viewRootImpl.votePreferredFrameRate(30, FRAME_RATE_COMPATIBILITY_FIXED_SOURCE); assertEquals(viewRootImpl.getPreferredFrameRate(), 30, 0.1); viewRootImpl.votePreferredFrameRate(60); // If there is a conflict, then set compatibility to // FRAME_RATE_COMPATIBILITY_FIXED_SOURCE assertEquals(viewRootImpl.getFrameRateCompatibility(), FRAME_RATE_COMPATIBILITY_FIXED_SOURCE); // Should be true since there is a conflict between 24 and 30. assertEquals(viewRootImpl.isFrameRateConflicted(), true); view.invalidate(); }); sInstrumentation.waitForIdleSync(); sInstrumentation.runOnMainSync(() -> { assertEquals(viewRootImpl.isFrameRateConflicted(), false); viewRootImpl.votePreferredFrameRate(60, FRAME_RATE_COMPATIBILITY_GTE); assertEquals(viewRootImpl.getPreferredFrameRate(), 60, 0.1); viewRootImpl.votePreferredFrameRate(120); assertEquals(viewRootImpl.getFrameRateCompatibility(), FRAME_RATE_COMPATIBILITY_GTE); assertEquals(viewRootImpl.isFrameRateConflicted(), false); viewRootImpl.votePreferredFrameRate(120, FRAME_RATE_COMPATIBILITY_FIXED_SOURCE); assertEquals(viewRootImpl.getPreferredFrameRate(), 120, 0.1); assertEquals(viewRootImpl.getFrameRateCompatibility(), FRAME_RATE_COMPATIBILITY_FIXED_SOURCE); // Should be false since 60 is a divisor of 120. assertEquals(viewRootImpl.isFrameRateConflicted(), false); viewRootImpl.votePreferredFrameRate(60, FRAME_RATE_COMPATIBILITY_GTE); assertEquals(viewRootImpl.getPreferredFrameRate(), 120, 0.1); // compatibility should be remained the same (FRAME_RATE_COMPATIBILITY_FIXED_SOURCE) // since the frame rate 60 is smaller than 120. assertEquals(viewRootImpl.getFrameRateCompatibility(), FRAME_RATE_COMPATIBILITY_FIXED_SOURCE); // Should be false since 60 is a divisor of 120. assertEquals(viewRootImpl.isFrameRateConflicted(), false); }); } Loading Loading @@ -842,14 +878,26 @@ public class ViewRootImplTest { sInstrumentation.runOnMainSync(() -> { assertEquals(viewRootImpl.getPreferredFrameRate(), 0, 0.1); viewRootImpl.votePreferredFrameRate(24); assertEquals(viewRootImpl.getFrameRateCompatibility(), FRAME_RATE_COMPATIBILITY_FIXED_SOURCE); assertEquals(viewRootImpl.isFrameRateConflicted(), false); viewRootImpl.votePreferredFrameRate(24, FRAME_RATE_COMPATIBILITY_FIXED_SOURCE); assertEquals(viewRootImpl.getPreferredFrameRate(), 24, 0.1); assertEquals(viewRootImpl.getFrameRateCompatibility(), FRAME_RATE_COMPATIBILITY_FIXED_SOURCE); assertEquals(viewRootImpl.isFrameRateConflicted(), false); view.invalidate(); assertEquals(viewRootImpl.getPreferredFrameRate(), 24, 0.1); assertEquals(viewRootImpl.getFrameRateCompatibility(), FRAME_RATE_COMPATIBILITY_FIXED_SOURCE); assertEquals(viewRootImpl.isFrameRateConflicted(), false); }); Thread.sleep(delay); assertEquals(viewRootImpl.getPreferredFrameRate(), 0, 0.1); assertEquals(viewRootImpl.getFrameRateCompatibility(), FRAME_RATE_COMPATIBILITY_FIXED_SOURCE); assertEquals(viewRootImpl.isFrameRateConflicted(), false); } /** Loading