diff options
| author | 2024-02-14 20:58:28 +0000 | |
|---|---|---|
| committer | 2024-02-15 04:04:40 +0000 | |
| commit | 74ba034dd1a48c4da9ae2c76219f7cf3595bdd5e (patch) | |
| tree | e4e1b0d2eab5a252268a40c6f8ff209c5324aab2 | |
| parent | c113156151ad7179f814eabd080f6a0a26aacaf1 (diff) | |
Add new attr IsFrameRatePowerSavingsBalanced to allow opt out dVRR feature.
Add new attr IsFrameRatePowerSavingsBalanced to allow opt out dVRR feature.
Bug: 324119782
API-Coverage-Bug: 324289198
Test: atest PhoneWindowTest
Change-Id: I107baf4cdb8cc1b33f897f1d24396954b3600297
| -rw-r--r-- | core/api/current.txt | 5 | ||||
| -rw-r--r-- | core/java/android/view/ViewRootImpl.java | 44 | ||||
| -rw-r--r-- | core/java/android/view/Window.java | 36 | ||||
| -rw-r--r-- | core/java/android/view/WindowManager.java | 44 | ||||
| -rw-r--r-- | core/java/com/android/internal/policy/PhoneWindow.java | 7 | ||||
| -rw-r--r-- | core/res/res/values/attrs.xml | 7 | ||||
| -rw-r--r-- | core/res/res/values/public-staging.xml | 2 | ||||
| -rw-r--r-- | core/tests/coretests/res/values/styles.xml | 6 | ||||
| -rw-r--r-- | core/tests/coretests/src/android/view/ViewRootImplTest.java | 16 | ||||
| -rw-r--r-- | core/tests/coretests/src/com/android/internal/policy/PhoneWindowTest.java | 60 |
10 files changed, 220 insertions, 7 deletions
diff --git a/core/api/current.txt b/core/api/current.txt index ed05047d546e..60eeea002705 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -1893,6 +1893,7 @@ package android { field public static final int windowFullscreen = 16843277; // 0x101020d field public static final int windowHideAnimation = 16842935; // 0x10100b7 field public static final int windowIsFloating = 16842839; // 0x1010057 + field @FlaggedApi("android.view.flags.toolkit_set_frame_rate_read_only") public static final int windowIsFrameRatePowerSavingsBalanced; field public static final int windowIsTranslucent = 16842840; // 0x1010058 field public static final int windowLayoutAffinity = 16844313; // 0x1010619 field public static final int windowLayoutInDisplayCutoutMode = 16844166; // 0x1010586 @@ -54088,6 +54089,7 @@ package android.view { method public abstract void invalidatePanelMenu(int); method public final boolean isActive(); method public abstract boolean isFloating(); + method @FlaggedApi("android.view.flags.toolkit_set_frame_rate_read_only") public boolean isFrameRatePowerSavingsBalanced(); method public boolean isNavigationBarContrastEnforced(); method public abstract boolean isShortcutKey(int, android.view.KeyEvent); method @Deprecated public boolean isStatusBarContrastEnforced(); @@ -54137,6 +54139,7 @@ package android.view { method public void setFlags(int, int); method public void setFormat(int); method @FlaggedApi("android.view.flags.toolkit_set_frame_rate_read_only") public void setFrameRateBoostOnTouchEnabled(boolean); + method @FlaggedApi("android.view.flags.toolkit_set_frame_rate_read_only") public void setFrameRatePowerSavingsBalanced(boolean); method public void setGravity(int); method @RequiresPermission(android.Manifest.permission.HIDE_OVERLAY_WINDOWS) public final void setHideOverlayWindows(boolean); method public void setIcon(@DrawableRes int); @@ -54506,6 +54509,7 @@ package android.view { method @FlaggedApi("android.view.flags.toolkit_set_frame_rate_read_only") public boolean getFrameRateBoostOnTouchEnabled(); method public final CharSequence getTitle(); method public boolean isFitInsetsIgnoringVisibility(); + method @FlaggedApi("android.view.flags.toolkit_set_frame_rate_read_only") public boolean isFrameRatePowerSavingsBalanced(); method public boolean isHdrConversionEnabled(); method public static boolean mayUseInputMethod(int); method public void setBlurBehindRadius(@IntRange(from=0) int); @@ -54516,6 +54520,7 @@ package android.view { method public void setFitInsetsSides(int); method public void setFitInsetsTypes(int); method @FlaggedApi("android.view.flags.toolkit_set_frame_rate_read_only") public void setFrameRateBoostOnTouchEnabled(boolean); + method @FlaggedApi("android.view.flags.toolkit_set_frame_rate_read_only") public void setFrameRatePowerSavingsBalanced(boolean); method public void setHdrConversionEnabled(boolean); method public final void setTitle(CharSequence); method public void setWallpaperTouchEventsEnabled(boolean); diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 9474a698c1a9..3780464f7b6b 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -1022,6 +1022,11 @@ public final class ViewRootImpl implements ViewParent, // Used to check if there is a message in the message queue // for idleness handling. private boolean mHasIdledMessage = false; + // Used to allow developers to opt out Toolkit dVRR feature. + // This feature allows device to adjust refresh rate + // as needed and can be useful for power saving. + // Should not enable the dVRR feature if the value is false. + private boolean mIsFrameRatePowerSavingsBalanced = true; // time for touch boost period. private static final int FRAME_RATE_TOUCH_BOOST_TIME = 3000; // time for checking idle status periodically. @@ -2533,8 +2538,10 @@ public final class ViewRootImpl implements ViewParent, // Set the frame rate selection strategy to FRAME_RATE_SELECTION_STRATEGY_SELF // This strategy ensures that the frame rate specifications do not cascade down to // the descendant layers. This is particularly important for applications like Chrome, - // where child surfaces should adhere to default behavior instead of no preference - if (sToolkitSetFrameRateReadOnlyFlagValue) { + // where child surfaces should adhere to default behavior instead of no preference. + // This issue only happens when ViewRootImpl calls setFrameRateCategory. This is + // no longer needed if the dVRR feature is disabled. + if (shouldEnableDvrr()) { try { mFrameRateTransaction.setFrameRateSelectionStrategy(sc, sc.FRAME_RATE_SELECTION_STRATEGY_SELF).applyAsyncUnsafe(); @@ -3258,7 +3265,7 @@ public final class ViewRootImpl implements ViewParent, destroyHardwareResources(); } - if (sToolkitSetFrameRateReadOnlyFlagValue && viewVisibility == View.VISIBLE) { + if (shouldEnableDvrr() && viewVisibility == View.VISIBLE) { // Boost frame rate when the viewVisibility becomes true. // This is mainly for lanuchers that lanuch new windows. boostFrameRate(FRAME_RATE_TOUCH_BOOST_TIME); @@ -3973,7 +3980,7 @@ public final class ViewRootImpl implements ViewParent, } } - if (sToolkitSetFrameRateReadOnlyFlagValue) { + if (shouldEnableDvrr()) { // Boost the frame rate when the ViewRootImpl first becomes available. boostFrameRate(FRAME_RATE_TOUCH_BOOST_TIME); } @@ -12340,12 +12347,12 @@ public final class ViewRootImpl implements ViewParent, private boolean shouldSetFrameRateCategory() { // use toolkitSetFrameRate flag to gate the change - return mSurface.isValid() && sToolkitSetFrameRateReadOnlyFlagValue; + return mSurface.isValid() && shouldEnableDvrr(); } private boolean shouldSetFrameRate() { // use toolkitSetFrameRate flag to gate the change - return sToolkitSetFrameRateReadOnlyFlagValue; + return mSurface.isValid() && mPreferredFrameRate > 0 && shouldEnableDvrr(); } private boolean shouldTouchBoost(int motionEventAction, int windowType) { @@ -12354,7 +12361,7 @@ public final class ViewRootImpl implements ViewParent, || motionEventAction == MotionEvent.ACTION_UP; boolean undesiredType = windowType == TYPE_INPUT_METHOD && mShouldSuppressBoostOnTyping; // use toolkitSetFrameRate flag to gate the change - return desiredAction && !undesiredType && sToolkitSetFrameRateReadOnlyFlagValue + return desiredAction && !undesiredType && shouldEnableDvrr() && getFrameRateBoostOnTouchEnabled(); } @@ -12476,4 +12483,27 @@ public final class ViewRootImpl implements ViewParent, // Record the largest view of percentage to the display size. mLargestChildPercentage = Math.max(percentage, mLargestChildPercentage); } + + /** + * Get the value of mIsFrameRatePowerSavingsBalanced + * Can be used to checked if toolkit dVRR feature is enabled. The default value is true. + */ + @VisibleForTesting + public boolean isFrameRatePowerSavingsBalanced() { + return mIsFrameRatePowerSavingsBalanced; + } + + /** + * Set the value of mIsFrameRatePowerSavingsBalanced + * Can be used to checked if toolkit dVRR feature is enabled. + */ + public void setFrameRatePowerSavingsBalanced(boolean enabled) { + if (sToolkitSetFrameRateReadOnlyFlagValue) { + mIsFrameRatePowerSavingsBalanced = enabled; + } + } + + private boolean shouldEnableDvrr() { + return sToolkitSetFrameRateReadOnlyFlagValue && mIsFrameRatePowerSavingsBalanced; + } } diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java index 4ba4ee3ffff7..6b427fc00766 100644 --- a/core/java/android/view/Window.java +++ b/core/java/android/view/Window.java @@ -1409,6 +1409,42 @@ public abstract class Window { } /** + * Set whether frameratepowersavingsbalance is enabled for this Window. + * This allows device to adjust refresh rate + * as needed and can be useful for power saving. + * + * @param enabled whether the frameratepowersavingsbalance is enabled. + * @see #isFrameRatePowerSavingsBalanced() + * @see WindowManager.LayoutParams#setFrameRatePowerSavingsBalanced(boolean) + */ + @FlaggedApi(android.view.flags.Flags.FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY) + public void setFrameRatePowerSavingsBalanced(boolean enabled) { + if (sToolkitSetFrameRateReadOnlyFlagValue) { + final WindowManager.LayoutParams attrs = getAttributes(); + attrs.setFrameRatePowerSavingsBalanced(enabled); + dispatchWindowAttributesChanged(attrs); + } + } + + /** + * Get whether frameratepowersavingsbalance is enabled for this Window. + * This allows device to adjust refresh rate + * as needed and can be useful for power saving. + * {@link #setFrameRateBoostOnTouchEnabled(boolean)} + * + * @return whether the frameratepowersavingsbalance is enabled. + * @see #setFrameRatePowerSavingsBalanced(boolean) + * @see WindowManager.LayoutParams#isFrameRatePowerSavingsBalanced() + */ + @FlaggedApi(android.view.flags.Flags.FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY) + public boolean isFrameRatePowerSavingsBalanced() { + if (sToolkitSetFrameRateReadOnlyFlagValue) { + return getAttributes().isFrameRatePowerSavingsBalanced(); + } + return false; + } + + /** * If {@code isPreferred} is true, this method requests that the connected display does minimal * post processing when this window is visible on the screen. Otherwise, it requests that the * display switches back to standard image processing. diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java index bc9b4fe37a2f..71eb8a29dc4c 100644 --- a/core/java/android/view/WindowManager.java +++ b/core/java/android/view/WindowManager.java @@ -4397,6 +4397,7 @@ public interface WindowManager extends ViewManager { * For variable refresh rate project. */ private boolean mFrameRateBoostOnTouch = true; + private boolean mIsFrameRatePowerSavingsBalanced = true; private static boolean sToolkitSetFrameRateReadOnlyFlagValue = android.view.flags.Flags.toolkitSetFrameRateReadOnly(); @@ -4861,6 +4862,36 @@ public interface WindowManager extends ViewManager { } /** + * Set the value whether frameratepowersavingsbalance is enabled for this Window. + * This allows device to adjust refresh rate + * as needed and can be useful for power saving. + * + * @param enabled Whether we should enable frameratepowersavingsbalance. + */ + @FlaggedApi(android.view.flags.Flags.FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY) + public void setFrameRatePowerSavingsBalanced(boolean enabled) { + if (sToolkitSetFrameRateReadOnlyFlagValue) { + mIsFrameRatePowerSavingsBalanced = enabled; + } + } + + /** + * Get the value whether frameratepowersavingsbalance is enabled for this Window. + * This allows device to adjust refresh rate + * as needed and can be useful for power saving. + * by {@link #setFrameRatePowerSavingsBalanced(boolean)} + * + * @return Whether we should enable frameratepowersavingsbalance. + */ + @FlaggedApi(android.view.flags.Flags.FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY) + public boolean isFrameRatePowerSavingsBalanced() { + if (sToolkitSetFrameRateReadOnlyFlagValue) { + return mIsFrameRatePowerSavingsBalanced; + } + return true; + } + + /** * <p> * Blurs the screen behind the window. The effect is similar to that of {@link #dimAmount}, * but instead of dimmed, the content behind the window will be blurred (or combined with @@ -5013,6 +5044,7 @@ public interface WindowManager extends ViewManager { out.writeFloat(mDesiredHdrHeadroom); if (sToolkitSetFrameRateReadOnlyFlagValue) { out.writeBoolean(mFrameRateBoostOnTouch); + out.writeBoolean(mIsFrameRatePowerSavingsBalanced); } } @@ -5088,6 +5120,7 @@ public interface WindowManager extends ViewManager { mDesiredHdrHeadroom = in.readFloat(); if (sToolkitSetFrameRateReadOnlyFlagValue) { mFrameRateBoostOnTouch = in.readBoolean(); + mIsFrameRatePowerSavingsBalanced = in.readBoolean(); } } @@ -5431,6 +5464,12 @@ public interface WindowManager extends ViewManager { changes |= LAYOUT_CHANGED; } + if (sToolkitSetFrameRateReadOnlyFlagValue + && mIsFrameRatePowerSavingsBalanced != o.mIsFrameRatePowerSavingsBalanced) { + mIsFrameRatePowerSavingsBalanced = o.mIsFrameRatePowerSavingsBalanced; + changes |= LAYOUT_CHANGED; + } + return changes; } @@ -5658,6 +5697,11 @@ public interface WindowManager extends ViewManager { sb.append(prefix).append(" frameRateBoostOnTouch="); sb.append(mFrameRateBoostOnTouch); } + if (sToolkitSetFrameRateReadOnlyFlagValue && mIsFrameRatePowerSavingsBalanced) { + sb.append(System.lineSeparator()); + sb.append(prefix).append(" dvrrWindowFrameRateHint="); + sb.append(mIsFrameRatePowerSavingsBalanced); + } if (paramsForRotation != null && paramsForRotation.length != 0) { sb.append(System.lineSeparator()); sb.append(prefix).append(" paramsForRotation:"); diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java index 523924566dd7..0dd01e48db0a 100644 --- a/core/java/com/android/internal/policy/PhoneWindow.java +++ b/core/java/com/android/internal/policy/PhoneWindow.java @@ -363,6 +363,8 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { private boolean mUseDecorContext = false; + private boolean mIsFrameRatePowerSavingsBalanced = true; + /** @see ViewRootImpl#mActivityConfigCallback */ private ActivityConfigCallback mActivityConfigCallback; @@ -2211,6 +2213,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { void onViewRootImplSet(ViewRootImpl viewRoot) { viewRoot.setActivityConfigCallback(mActivityConfigCallback); viewRoot.getOnBackInvokedDispatcher().updateContext(getContext()); + viewRoot.setFrameRatePowerSavingsBalanced(mIsFrameRatePowerSavingsBalanced); mProxyOnBackInvokedDispatcher.setActualDispatcher(viewRoot.getOnBackInvokedDispatcher()); applyDecorFitsSystemWindows(); } @@ -2559,6 +2562,10 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { if (a.getBoolean(R.styleable.Window_windowActivityTransitions, false)) { requestFeature(FEATURE_ACTIVITY_TRANSITIONS); } + if (a.hasValue(R.styleable.Window_windowIsFrameRatePowerSavingsBalanced)) { + mIsFrameRatePowerSavingsBalanced = + a.getBoolean(R.styleable.Window_windowIsFrameRatePowerSavingsBalanced, true); + } mIsTranslucent = a.getBoolean(R.styleable.Window_windowIsTranslucent, false); diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index cc6460ea7d4d..c1fd61948e68 100644 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -2514,6 +2514,13 @@ <!-- The icon is shown unless the launching app specified SPLASH_SCREEN_STYLE_EMPTY --> <enum name="icon_preferred" value="1" /> </attr> + <!-- Offer Window the ability to opt out the UI Toolkit discrete variable refresh rate. + This feature allows device to adjust refresh rate as needed and + can be useful for power saving. + Set to false to reduce the frame rate optimizations on devices with + variable refresh rate screens. + The default is true. --> + <attr name="windowIsFrameRatePowerSavingsBalanced" format="boolean"/> <!-- Flag indicating whether this window would opt-out the edge-to-edge enforcement. diff --git a/core/res/res/values/public-staging.xml b/core/res/res/values/public-staging.xml index 8af8cb84a217..c797210345a2 100644 --- a/core/res/res/values/public-staging.xml +++ b/core/res/res/values/public-staging.xml @@ -165,6 +165,8 @@ <public name="allowCrossUidActivitySwitchFromBelow"/> <!-- @FlaggedApi("com.android.text.flags.use_bounds_for_width") --> <public name="shiftDrawingOffsetForStartOverhang" /> + <!-- @FlaggedApi("android.view.flags.toolkit_set_frame_rate_read_only") --> + <public name="windowIsFrameRatePowerSavingsBalanced"/> </staging-public-group> <staging-public-group type="id" first-id="0x01bc0000"> diff --git a/core/tests/coretests/res/values/styles.xml b/core/tests/coretests/res/values/styles.xml index 32eebb35e0c3..78cd1e1e47e8 100644 --- a/core/tests/coretests/res/values/styles.xml +++ b/core/tests/coretests/res/values/styles.xml @@ -55,4 +55,10 @@ <style name="ViewDefaultBackground"> <item name="android:background">#00000000</item> </style> + <style name="IsFrameRatePowerSavingsBalancedDisabled"> + <item name="android:windowIsFrameRatePowerSavingsBalanced">false</item> + </style> + <style name="IsFrameRatePowerSavingsBalancedEnabled"> + <item name="android:windowIsFrameRatePowerSavingsBalanced">true</item> + </style> </resources> diff --git a/core/tests/coretests/src/android/view/ViewRootImplTest.java b/core/tests/coretests/src/android/view/ViewRootImplTest.java index 433d353e5074..038c00e3823c 100644 --- a/core/tests/coretests/src/android/view/ViewRootImplTest.java +++ b/core/tests/coretests/src/android/view/ViewRootImplTest.java @@ -953,6 +953,22 @@ public class ViewRootImplTest { }); } + /** + * Test the IsFrameRatePowerSavingsBalanced values are properly set + */ + @UiThreadTest + @Test + @RequiresFlagsEnabled(FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY) + public void votePreferredFrameRate_isFrameRatePowerSavingsBalanced() { + ViewRootImpl viewRootImpl = new ViewRootImpl(sContext, + sContext.getDisplayNoVerify()); + assertEquals(viewRootImpl.isFrameRatePowerSavingsBalanced(), true); + viewRootImpl.setFrameRatePowerSavingsBalanced(false); + assertEquals(viewRootImpl.isFrameRatePowerSavingsBalanced(), false); + viewRootImpl.setFrameRatePowerSavingsBalanced(true); + assertEquals(viewRootImpl.isFrameRatePowerSavingsBalanced(), true); + } + @Test public void forceInvertOffDarkThemeOff_forceDarkModeDisabled() { mSetFlagsRule.enableFlags(FLAG_FORCE_INVERT_COLOR); diff --git a/core/tests/coretests/src/com/android/internal/policy/PhoneWindowTest.java b/core/tests/coretests/src/com/android/internal/policy/PhoneWindowTest.java index 3df3b9d2c555..b9841ff997e7 100644 --- a/core/tests/coretests/src/com/android/internal/policy/PhoneWindowTest.java +++ b/core/tests/coretests/src/com/android/internal/policy/PhoneWindowTest.java @@ -21,17 +21,28 @@ import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_M import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER; import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_EDGE_TO_EDGE_ENFORCED; +import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; +import static android.view.flags.Flags.FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY; import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; +import android.app.Instrumentation; import android.content.Context; import android.graphics.Color; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; +import android.os.Binder; import android.platform.test.annotations.Presubmit; +import android.platform.test.annotations.RequiresFlagsEnabled; +import android.platform.test.flag.junit.CheckFlagsRule; +import android.platform.test.flag.junit.DeviceFlagsValueProvider; import android.view.ActionMode; import android.view.ContextThemeWrapper; +import android.view.ViewRootImpl; +import android.view.WindowManager; import androidx.test.InstrumentationRegistry; import androidx.test.filters.SmallTest; @@ -40,6 +51,7 @@ import androidx.test.runner.AndroidJUnit4; import com.android.frameworks.coretests.R; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -54,6 +66,12 @@ public final class PhoneWindowTest { private PhoneWindow mPhoneWindow; private Context mContext; + private static Instrumentation sInstrumentation = + InstrumentationRegistry.getInstrumentation(); + + @Rule + public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule(); + @Before public void setUp() throws Exception { mContext = InstrumentationRegistry.getContext(); @@ -154,6 +172,48 @@ public final class PhoneWindowTest { assertThat(colorDrawable.getColor(), is(Color.BLUE)); } + @Test + @RequiresFlagsEnabled(FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY) + public void testWindowFrameRateHint_disabled() { + createPhoneWindowWithTheme(R.style.IsFrameRatePowerSavingsBalancedDisabled); + installDecor(); + + DecorView decorView = (DecorView) mPhoneWindow.getDecorView(); + + WindowManager.LayoutParams wmlp = new WindowManager.LayoutParams(TYPE_APPLICATION_OVERLAY); + wmlp.token = new Binder(); // Set a fake token to bypass 'is your activity running' check + + sInstrumentation.runOnMainSync(() -> { + WindowManager wm = mContext.getSystemService(WindowManager.class); + wm.addView(decorView, wmlp); + }); + sInstrumentation.waitForIdleSync(); + + ViewRootImpl viewRootImpl = decorView.getViewRootImpl(); + assertFalse(viewRootImpl.isFrameRatePowerSavingsBalanced()); + } + + @Test + @RequiresFlagsEnabled(FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY) + public void testWindowFrameRateHint_enabled() { + createPhoneWindowWithTheme(R.style.IsFrameRatePowerSavingsBalancedEnabled); + installDecor(); + + DecorView decorView = (DecorView) mPhoneWindow.getDecorView(); + + WindowManager.LayoutParams wmlp = new WindowManager.LayoutParams(TYPE_APPLICATION_OVERLAY); + wmlp.token = new Binder(); // Set a fake token to bypass 'is your activity running' check + + sInstrumentation.runOnMainSync(() -> { + WindowManager wm = mContext.getSystemService(WindowManager.class); + wm.addView(decorView, wmlp); + }); + sInstrumentation.waitForIdleSync(); + + ViewRootImpl viewRootImpl = decorView.getViewRootImpl(); + assertTrue(viewRootImpl.isFrameRatePowerSavingsBalanced()); + } + private void createPhoneWindowWithTheme(int theme) { mPhoneWindow = new PhoneWindow(new ContextThemeWrapper(mContext, theme)); } |