diff --git a/core/java/android/view/DisplayInfo.java b/core/java/android/view/DisplayInfo.java index fc42cd07950ee..ab35af89f0b39 100644 --- a/core/java/android/view/DisplayInfo.java +++ b/core/java/android/view/DisplayInfo.java @@ -547,16 +547,17 @@ public final class DisplayInfo implements Parcelable { * Returns the id of the "default" mode with the given refresh rate, or {@code 0} if no suitable * mode could be found. */ - public int findDefaultModeByRefreshRate(float refreshRate) { + @Nullable + public Display.Mode findDefaultModeByRefreshRate(float refreshRate) { Display.Mode[] modes = supportedModes; Display.Mode defaultMode = getDefaultMode(); for (int i = 0; i < modes.length; i++) { if (modes[i].matches( defaultMode.getPhysicalWidth(), defaultMode.getPhysicalHeight(), refreshRate)) { - return modes[i].getModeId(); + return modes[i]; } } - return 0; + return null; } /** diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java index a2777fe985d50..24bc308743181 100644 --- a/core/java/android/view/Surface.java +++ b/core/java/android/view/Surface.java @@ -217,6 +217,15 @@ public class Surface implements Parcelable { */ public static final int FRAME_RATE_COMPATIBILITY_FIXED_SOURCE = 1; + /** + * This surface belongs to an app on the High Refresh Rate Deny list, and needs the display + * to operate at the exact frame rate. + * + * This is used internally by the platform and should not be used by apps. + * @hide + */ + public static final int FRAME_RATE_COMPATIBILITY_EXACT = 100; + /** * Create an empty surface, which will later be filled in by readFromParcel(). * @hide diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java index 55103ca6cd1c9..481c3c7a5d967 100644 --- a/services/core/java/com/android/server/display/DisplayManagerService.java +++ b/services/core/java/com/android/server/display/DisplayManagerService.java @@ -1357,7 +1357,7 @@ public final class DisplayManagerService extends SystemService { // Scan supported modes returned by display.getInfo() to find a mode with the same // size as the default display mode but with the specified refresh rate instead. requestedModeId = display.getDisplayInfoLocked().findDefaultModeByRefreshRate( - requestedRefreshRate); + requestedRefreshRate).getModeId(); } mDisplayModeDirector.getAppRequestObserver().setAppRequestedMode( displayId, requestedModeId); diff --git a/services/core/java/com/android/server/wm/RefreshRatePolicy.java b/services/core/java/com/android/server/wm/RefreshRatePolicy.java index 91014aa698313..26871d130fbf0 100644 --- a/services/core/java/com/android/server/wm/RefreshRatePolicy.java +++ b/services/core/java/com/android/server/wm/RefreshRatePolicy.java @@ -28,7 +28,7 @@ import android.view.DisplayInfo; */ class RefreshRatePolicy { - private final int mLowRefreshRateId; + private final Mode mLowRefreshRateMode; private final ArraySet mNonHighRefreshRatePackages = new ArraySet<>(); private final HighRefreshRateDenylist mHighRefreshRateDenylist; private final WindowManagerService mWmService; @@ -56,7 +56,7 @@ class RefreshRatePolicy { RefreshRatePolicy(WindowManagerService wmService, DisplayInfo displayInfo, HighRefreshRateDenylist denylist) { - mLowRefreshRateId = findLowRefreshRateModeId(displayInfo); + mLowRefreshRateMode = findLowRefreshRateMode(displayInfo); mHighRefreshRateDenylist = denylist; mWmService = wmService; } @@ -65,7 +65,7 @@ class RefreshRatePolicy { * Finds the mode id with the lowest refresh rate which is >= 60hz and same resolution as the * default mode. */ - private int findLowRefreshRateModeId(DisplayInfo displayInfo) { + private Mode findLowRefreshRateMode(DisplayInfo displayInfo) { Mode mode = displayInfo.getDefaultMode(); float[] refreshRates = displayInfo.getDefaultRefreshRates(); float bestRefreshRate = mode.getRefreshRate(); @@ -104,13 +104,9 @@ class RefreshRatePolicy { // If app is using Camera, force it to default (lower) refresh rate. if (mNonHighRefreshRatePackages.contains(packageName)) { - return mLowRefreshRateId; + return mLowRefreshRateMode.getModeId(); } - // If app is denylisted using higher refresh rate, return default (lower) refresh rate - if (mHighRefreshRateDenylist.isDenylisted(packageName)) { - return mLowRefreshRateId; - } return 0; } @@ -137,4 +133,18 @@ class RefreshRatePolicy { } return LAYER_PRIORITY_UNSET; } + + float getPreferredRefreshRate(WindowState w) { + // If app is animating, it's not able to control refresh rate because we want the animation + // to run in default refresh rate. + if (w.isAnimating(TRANSITION | PARENTS)) { + return 0; + } + + final String packageName = w.getOwningPackage(); + if (mHighRefreshRateDenylist.isDenylisted(packageName)) { + return mLowRefreshRateMode.getRefreshRate(); + } + return 0; + } } diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 3be4e78a122bc..d0afa2ae2a738 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -233,6 +233,7 @@ import android.view.InputWindowHandle; import android.view.InsetsSource; import android.view.InsetsState; import android.view.InsetsState.InternalInsetsType; +import android.view.Surface; import android.view.Surface.Rotation; import android.view.SurfaceControl; import android.view.SurfaceSession; @@ -730,6 +731,13 @@ class WindowState extends WindowContainer implements WindowManagerP */ int mFrameRateSelectionPriority = RefreshRatePolicy.LAYER_PRIORITY_UNSET; + /** + * This is the frame rate which is passed to SurfaceFlinger if the window is part of the + * high refresh rate deny list. The variable is cached, so we do not send too many updates to + * SF. + */ + float mDenyListFrameRate = 0f; + static final int BLAST_TIMEOUT_DURATION = 5000; /* milliseconds */ private final WindowProcessController mWpcForDisplayAreaConfigChanges; @@ -5233,7 +5241,6 @@ class WindowState extends WindowContainer implements WindowManagerP return (mAttrs.flags & FLAG_BLUR_BEHIND) != 0 && mOwnerCanUseBackgroundBlur; } - /** * Notifies SF about the priority of the window, if it changed. SF then uses this information * to decide which window's desired rendering rate should have a priority when deciding about @@ -5242,13 +5249,21 @@ class WindowState extends WindowContainer implements WindowManagerP */ @VisibleForTesting void updateFrameRateSelectionPriorityIfNeeded() { - final int priority = getDisplayContent().getDisplayPolicy().getRefreshRatePolicy() - .calculatePriority(this); + RefreshRatePolicy refreshRatePolicy = + getDisplayContent().getDisplayPolicy().getRefreshRatePolicy(); + final int priority = refreshRatePolicy.calculatePriority(this); if (mFrameRateSelectionPriority != priority) { mFrameRateSelectionPriority = priority; getPendingTransaction().setFrameRateSelectionPriority(mSurfaceControl, mFrameRateSelectionPriority); } + + final float refreshRate = refreshRatePolicy.getPreferredRefreshRate(this); + if (mDenyListFrameRate != refreshRate) { + mDenyListFrameRate = refreshRate; + getPendingTransaction().setFrameRate( + mSurfaceControl, mDenyListFrameRate, Surface.FRAME_RATE_COMPATIBILITY_EXACT); + } } private void updateGlobalScaleIfNeeded() { diff --git a/services/tests/wmtests/src/com/android/server/wm/FrameRateSelectionPriorityTests.java b/services/tests/wmtests/src/com/android/server/wm/FrameRateSelectionPriorityTests.java index 032edde61becf..325bca418d130 100644 --- a/services/tests/wmtests/src/com/android/server/wm/FrameRateSelectionPriorityTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/FrameRateSelectionPriorityTests.java @@ -18,15 +18,24 @@ package com.android.server.wm; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.any; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyInt; import static com.android.dx.mockito.inline.extended.ExtendedMockito.never; import static com.android.dx.mockito.inline.extended.ExtendedMockito.times; import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; import android.platform.test.annotations.Presubmit; +import android.view.Display.Mode; +import android.view.DisplayInfo; +import android.view.Surface; +import android.view.SurfaceControl; +import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -40,16 +49,40 @@ import org.junit.runner.RunWith; @Presubmit @RunWith(WindowTestRunner.class) public class FrameRateSelectionPriorityTests extends WindowTestsBase { + private static final float FLOAT_TOLERANCE = 0.01f; + private static final int LOW_MODE_ID = 3; + + private DisplayPolicy mDisplayPolicy = mock(DisplayPolicy.class); + private RefreshRatePolicy mRefreshRatePolicy; + private HighRefreshRateDenylist mDenylist = mock(HighRefreshRateDenylist.class); + + @Before + public void setUp() { + DisplayInfo di = new DisplayInfo(mDisplayInfo); + Mode defaultMode = di.getDefaultMode(); + di.supportedModes = new Mode[] { + new Mode(1, defaultMode.getPhysicalWidth(), defaultMode.getPhysicalHeight(), 90), + new Mode(2, defaultMode.getPhysicalWidth(), defaultMode.getPhysicalHeight(), 70), + new Mode(LOW_MODE_ID, + defaultMode.getPhysicalWidth(), defaultMode.getPhysicalHeight(), 60), + }; + di.defaultModeId = 1; + mRefreshRatePolicy = new RefreshRatePolicy(mWm, di, mDenylist); + when(mDisplayPolicy.getRefreshRatePolicy()).thenReturn(mRefreshRatePolicy); + } @Test public void basicTest() { final WindowState appWindow = createWindow(null, TYPE_APPLICATION, "appWindow"); assertNotNull("Window state is created", appWindow); + assertEquals(appWindow.mFrameRateSelectionPriority, RefreshRatePolicy.LAYER_PRIORITY_UNSET); + assertEquals(appWindow.mDenyListFrameRate, 0, FLOAT_TOLERANCE); appWindow.updateFrameRateSelectionPriorityIfNeeded(); // Priority doesn't change. assertEquals(appWindow.mFrameRateSelectionPriority, RefreshRatePolicy.LAYER_PRIORITY_UNSET); + assertEquals(appWindow.mDenyListFrameRate, 0, FLOAT_TOLERANCE); // Call the function a few times. appWindow.updateFrameRateSelectionPriorityIfNeeded(); @@ -57,7 +90,9 @@ public class FrameRateSelectionPriorityTests extends WindowTestsBase { // Since nothing changed in the priority state, the transaction should not be updating. verify(appWindow.getPendingTransaction(), never()).setFrameRateSelectionPriority( - appWindow.getSurfaceControl(), RefreshRatePolicy.LAYER_PRIORITY_UNSET); + any(SurfaceControl.class), anyInt()); + verify(appWindow.getPendingTransaction(), never()).setFrameRate( + any(SurfaceControl.class), anyInt(), anyInt()); } @Test @@ -66,10 +101,16 @@ public class FrameRateSelectionPriorityTests extends WindowTestsBase { assertEquals(appWindow.mFrameRateSelectionPriority, RefreshRatePolicy.LAYER_PRIORITY_UNSET); assertEquals(appWindow.getDisplayContent().getDisplayPolicy().getRefreshRatePolicy() .getPreferredModeId(appWindow), 0); + assertEquals(appWindow.mDenyListFrameRate, 0, FLOAT_TOLERANCE); + assertEquals(appWindow.getDisplayContent().getDisplayPolicy().getRefreshRatePolicy() + .getPreferredRefreshRate(appWindow), 0, FLOAT_TOLERANCE); + + assertEquals(appWindow.mDenyListFrameRate, 0, FLOAT_TOLERANCE); appWindow.updateFrameRateSelectionPriorityIfNeeded(); // Priority stays MAX_VALUE. assertEquals(appWindow.mFrameRateSelectionPriority, RefreshRatePolicy.LAYER_PRIORITY_UNSET); + assertEquals(appWindow.mDenyListFrameRate, 0, FLOAT_TOLERANCE); verify(appWindow.getPendingTransaction(), never()).setFrameRateSelectionPriority( appWindow.getSurfaceControl(), RefreshRatePolicy.LAYER_PRIORITY_UNSET); @@ -78,31 +119,38 @@ public class FrameRateSelectionPriorityTests extends WindowTestsBase { appWindow.updateFrameRateSelectionPriorityIfNeeded(); // Priority changes to 1. assertEquals(appWindow.mFrameRateSelectionPriority, 1); + assertEquals(appWindow.mDenyListFrameRate, 0, FLOAT_TOLERANCE); verify(appWindow.getPendingTransaction()).setFrameRateSelectionPriority( appWindow.getSurfaceControl(), 1); + verify(appWindow.getPendingTransaction(), never()).setFrameRate( + any(SurfaceControl.class), anyInt(), anyInt()); } @Test public void testApplicationInFocusWithModeId() { final WindowState appWindow = createWindow(null, TYPE_APPLICATION, "appWindow"); assertEquals(appWindow.mFrameRateSelectionPriority, RefreshRatePolicy.LAYER_PRIORITY_UNSET); + assertEquals(appWindow.mDenyListFrameRate, 0, FLOAT_TOLERANCE); // Application is in focus. appWindow.mToken.mDisplayContent.mCurrentFocus = appWindow; appWindow.updateFrameRateSelectionPriorityIfNeeded(); // Priority changes. assertEquals(appWindow.mFrameRateSelectionPriority, 1); + assertEquals(appWindow.mDenyListFrameRate, 0, FLOAT_TOLERANCE); // Update the mode ID to a requested number. appWindow.mAttrs.preferredDisplayModeId = 1; appWindow.updateFrameRateSelectionPriorityIfNeeded(); // Priority changes. assertEquals(appWindow.mFrameRateSelectionPriority, 0); + assertEquals(appWindow.mDenyListFrameRate, 0, FLOAT_TOLERANCE); // Remove the mode ID request. appWindow.mAttrs.preferredDisplayModeId = 0; appWindow.updateFrameRateSelectionPriorityIfNeeded(); // Priority changes. assertEquals(appWindow.mFrameRateSelectionPriority, 1); + assertEquals(appWindow.mDenyListFrameRate, 0, FLOAT_TOLERANCE); // Verify we called actions on Transactions correctly. verify(appWindow.getPendingTransaction(), never()).setFrameRateSelectionPriority( @@ -111,12 +159,15 @@ public class FrameRateSelectionPriorityTests extends WindowTestsBase { appWindow.getSurfaceControl(), 0); verify(appWindow.getPendingTransaction(), times(2)).setFrameRateSelectionPriority( appWindow.getSurfaceControl(), 1); + verify(appWindow.getPendingTransaction(), never()).setFrameRate( + any(SurfaceControl.class), anyInt(), anyInt()); } @Test public void testApplicationNotInFocusWithModeId() { final WindowState appWindow = createWindow(null, TYPE_APPLICATION, "appWindow"); assertEquals(appWindow.mFrameRateSelectionPriority, RefreshRatePolicy.LAYER_PRIORITY_UNSET); + assertEquals(appWindow.mDenyListFrameRate, 0, FLOAT_TOLERANCE); final WindowState inFocusWindow = createWindow(null, TYPE_APPLICATION, "inFocus"); appWindow.mToken.mDisplayContent.mCurrentFocus = inFocusWindow; @@ -124,23 +175,28 @@ public class FrameRateSelectionPriorityTests extends WindowTestsBase { appWindow.updateFrameRateSelectionPriorityIfNeeded(); // The window is not in focus. assertEquals(appWindow.mFrameRateSelectionPriority, RefreshRatePolicy.LAYER_PRIORITY_UNSET); + assertEquals(appWindow.mDenyListFrameRate, 0, FLOAT_TOLERANCE); // Update the mode ID to a requested number. appWindow.mAttrs.preferredDisplayModeId = 1; appWindow.updateFrameRateSelectionPriorityIfNeeded(); // Priority changes. assertEquals(appWindow.mFrameRateSelectionPriority, 2); + assertEquals(appWindow.mDenyListFrameRate, 0, FLOAT_TOLERANCE); verify(appWindow.getPendingTransaction()).setFrameRateSelectionPriority( appWindow.getSurfaceControl(), RefreshRatePolicy.LAYER_PRIORITY_UNSET); verify(appWindow.getPendingTransaction()).setFrameRateSelectionPriority( appWindow.getSurfaceControl(), 2); + verify(appWindow.getPendingTransaction(), never()).setFrameRate( + any(SurfaceControl.class), anyInt(), anyInt()); } @Test public void testApplicationNotInFocusWithoutModeId() { final WindowState appWindow = createWindow(null, TYPE_APPLICATION, "appWindow"); assertEquals(appWindow.mFrameRateSelectionPriority, RefreshRatePolicy.LAYER_PRIORITY_UNSET); + assertEquals(appWindow.mDenyListFrameRate, 0, FLOAT_TOLERANCE); final WindowState inFocusWindow = createWindow(null, TYPE_APPLICATION, "inFocus"); appWindow.mToken.mDisplayContent.mCurrentFocus = inFocusWindow; @@ -148,14 +204,45 @@ public class FrameRateSelectionPriorityTests extends WindowTestsBase { appWindow.updateFrameRateSelectionPriorityIfNeeded(); // The window is not in focus. assertEquals(appWindow.mFrameRateSelectionPriority, RefreshRatePolicy.LAYER_PRIORITY_UNSET); + assertEquals(appWindow.mDenyListFrameRate, 0, FLOAT_TOLERANCE); // Make sure that the mode ID is not set. appWindow.mAttrs.preferredDisplayModeId = 0; appWindow.updateFrameRateSelectionPriorityIfNeeded(); // Priority doesn't change. assertEquals(appWindow.mFrameRateSelectionPriority, RefreshRatePolicy.LAYER_PRIORITY_UNSET); + assertEquals(appWindow.mDenyListFrameRate, 0, FLOAT_TOLERANCE); verify(appWindow.getPendingTransaction()).setFrameRateSelectionPriority( appWindow.getSurfaceControl(), RefreshRatePolicy.LAYER_PRIORITY_UNSET); + verify(appWindow.getPendingTransaction(), never()).setFrameRate( + any(SurfaceControl.class), anyInt(), anyInt()); + } + + @Test + public void testPreferredRefreshRate() { + final WindowState appWindow = createWindow(null, TYPE_APPLICATION, "appWindow"); + assertNotNull("Window state is created", appWindow); + when(appWindow.getDisplayContent().getDisplayPolicy()).thenReturn(mDisplayPolicy); + + appWindow.mAttrs.packageName = "com.android.test"; + when(mDenylist.isDenylisted("com.android.test")).thenReturn(true); + + assertEquals(0, mRefreshRatePolicy.getPreferredModeId(appWindow)); + assertEquals(60, mRefreshRatePolicy.getPreferredRefreshRate(appWindow), FLOAT_TOLERANCE); + + appWindow.updateFrameRateSelectionPriorityIfNeeded(); + assertEquals(RefreshRatePolicy.LAYER_PRIORITY_UNSET, appWindow.mFrameRateSelectionPriority); + assertEquals(60, appWindow.mDenyListFrameRate, FLOAT_TOLERANCE); + + // Call the function a few times. + appWindow.updateFrameRateSelectionPriorityIfNeeded(); + appWindow.updateFrameRateSelectionPriorityIfNeeded(); + + // Since nothing changed in the priority state, the transaction should not be updating. + verify(appWindow.getPendingTransaction(), never()).setFrameRateSelectionPriority( + any(SurfaceControl.class), anyInt()); + verify(appWindow.getPendingTransaction(), times(1)).setFrameRate( + appWindow.getSurfaceControl(), 60, Surface.FRAME_RATE_COMPATIBILITY_EXACT); } } diff --git a/services/tests/wmtests/src/com/android/server/wm/RefreshRatePolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/RefreshRatePolicyTest.java index 77a4b0507a420..ef3c7ae91fedc 100644 --- a/services/tests/wmtests/src/com/android/server/wm/RefreshRatePolicyTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/RefreshRatePolicyTest.java @@ -44,7 +44,7 @@ import org.junit.runner.RunWith; @RunWith(WindowTestRunner.class) @FlakyTest public class RefreshRatePolicyTest extends WindowTestsBase { - + private static final float FLOAT_TOLERANCE = 0.01f; private static final int LOW_MODE_ID = 3; private RefreshRatePolicy mPolicy; @@ -70,28 +70,34 @@ public class RefreshRatePolicyTest extends WindowTestsBase { "cameraUsingWindow"); cameraUsingWindow.mAttrs.packageName = "com.android.test"; assertEquals(0, mPolicy.getPreferredModeId(cameraUsingWindow)); + assertEquals(0, mPolicy.getPreferredRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE); mPolicy.addNonHighRefreshRatePackage("com.android.test"); assertEquals(LOW_MODE_ID, mPolicy.getPreferredModeId(cameraUsingWindow)); + assertEquals(0, mPolicy.getPreferredRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE); mPolicy.removeNonHighRefreshRatePackage("com.android.test"); assertEquals(0, mPolicy.getPreferredModeId(cameraUsingWindow)); + assertEquals(0, mPolicy.getPreferredRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE); } @Test - public void testBlacklist() { - final WindowState blacklistedWindow = createWindow(null, TYPE_BASE_APPLICATION, - "blacklistedWindow"); - blacklistedWindow.mAttrs.packageName = "com.android.test"; + public void testDenyList() { + final WindowState denylistedWindow = createWindow(null, TYPE_BASE_APPLICATION, + "denylistedWindow"); + denylistedWindow.mAttrs.packageName = "com.android.test"; when(mDenylist.isDenylisted("com.android.test")).thenReturn(true); - assertEquals(LOW_MODE_ID, mPolicy.getPreferredModeId(blacklistedWindow)); + assertEquals(0, mPolicy.getPreferredModeId(denylistedWindow)); + assertEquals(60, mPolicy.getPreferredRefreshRate(denylistedWindow), FLOAT_TOLERANCE); } @Test public void testAppOverride_blacklist() { final WindowState overrideWindow = createWindow(null, TYPE_BASE_APPLICATION, "overrideWindow"); + overrideWindow.mAttrs.packageName = "com.android.test"; overrideWindow.mAttrs.preferredDisplayModeId = LOW_MODE_ID; when(mDenylist.isDenylisted("com.android.test")).thenReturn(true); assertEquals(LOW_MODE_ID, mPolicy.getPreferredModeId(overrideWindow)); + assertEquals(60, mPolicy.getPreferredRefreshRate(overrideWindow), FLOAT_TOLERANCE); } @Test @@ -102,6 +108,7 @@ public class RefreshRatePolicyTest extends WindowTestsBase { overrideWindow.mAttrs.preferredDisplayModeId = LOW_MODE_ID; mPolicy.addNonHighRefreshRatePackage("com.android.test"); assertEquals(LOW_MODE_ID, mPolicy.getPreferredModeId(overrideWindow)); + assertEquals(0, mPolicy.getPreferredRefreshRate(overrideWindow), FLOAT_TOLERANCE); } @Test @@ -115,6 +122,7 @@ public class RefreshRatePolicyTest extends WindowTestsBase { false /* hidden */, ANIMATION_TYPE_APP_TRANSITION); mPolicy.addNonHighRefreshRatePackage("com.android.test"); assertEquals(0, mPolicy.getPreferredModeId(overrideWindow)); + assertEquals(0, mPolicy.getPreferredRefreshRate(overrideWindow), FLOAT_TOLERANCE); } @Test @@ -125,10 +133,12 @@ public class RefreshRatePolicyTest extends WindowTestsBase { mPolicy.addNonHighRefreshRatePackage("com.android.test"); assertEquals(LOW_MODE_ID, mPolicy.getPreferredModeId(cameraUsingWindow)); + assertEquals(0, mPolicy.getPreferredRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE); cameraUsingWindow.mActivityRecord.mSurfaceAnimator.startAnimation( cameraUsingWindow.getPendingTransaction(), mock(AnimationAdapter.class), false /* hidden */, ANIMATION_TYPE_APP_TRANSITION); assertEquals(0, mPolicy.getPreferredModeId(cameraUsingWindow)); + assertEquals(0, mPolicy.getPreferredRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE); } } diff --git a/services/tests/wmtests/src/com/android/server/wm/StubTransaction.java b/services/tests/wmtests/src/com/android/server/wm/StubTransaction.java index c308fdbf84919..b8d44f605bca6 100644 --- a/services/tests/wmtests/src/com/android/server/wm/StubTransaction.java +++ b/services/tests/wmtests/src/com/android/server/wm/StubTransaction.java @@ -244,6 +244,12 @@ public class StubTransaction extends SurfaceControl.Transaction { return this; } + @Override + public SurfaceControl.Transaction setFrameRate(SurfaceControl sc, float frameRate, + int compatibility) { + return this; + } + @Override public SurfaceControl.Transaction unsetColor(SurfaceControl sc) { return this;