diff options
3 files changed, 53 insertions, 13 deletions
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 5767730abd82..0a565ba7e38e 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -2119,6 +2119,10 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp w.seamlesslyRotateIfAllowed(transaction, oldRotation, rotation, rotateSeamlessly); }, true /* traverseTopToBottom */); mPinnedTaskController.startSeamlessRotationIfNeeded(transaction, oldRotation, rotation); + if (!mDisplayRotation.hasSeamlessRotatingWindow()) { + // Make sure DisplayRotation#isRotatingSeamlessly() will return false. + mDisplayRotation.cancelSeamlessRotation(); + } } mWmService.mDisplayManagerInternal.performTraversal(transaction); @@ -4827,7 +4831,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp mInsetsStateController.getImeSourceProvider().checkShowImePostLayout(); mLastHasContent = mTmpApplySurfaceChangesTransactionState.displayHasContent; - if (!mWmService.mDisplayFrozen) { + if (!mWmService.mDisplayFrozen && !mDisplayRotation.isRotatingSeamlessly()) { mWmService.mDisplayManagerInternal.setDisplayProperties(mDisplayId, mLastHasContent, mTmpApplySurfaceChangesTransactionState.preferredRefreshRate, diff --git a/services/core/java/com/android/server/wm/RefreshRatePolicy.java b/services/core/java/com/android/server/wm/RefreshRatePolicy.java index f3713eb7f474..6b3c5332d3c9 100644 --- a/services/core/java/com/android/server/wm/RefreshRatePolicy.java +++ b/services/core/java/com/android/server/wm/RefreshRatePolicy.java @@ -53,6 +53,8 @@ class RefreshRatePolicy { } } + private final DisplayInfo mDisplayInfo; + private final Mode mDefaultMode; private final Mode mLowRefreshRateMode; private final PackageRefreshRate mNonHighRefreshRatePackages = new PackageRefreshRate(); private final HighRefreshRateDenylist mHighRefreshRateDenylist; @@ -83,7 +85,9 @@ class RefreshRatePolicy { RefreshRatePolicy(WindowManagerService wmService, DisplayInfo displayInfo, HighRefreshRateDenylist denylist) { - mLowRefreshRateMode = findLowRefreshRateMode(displayInfo); + mDisplayInfo = displayInfo; + mDefaultMode = displayInfo.getDefaultMode(); + mLowRefreshRateMode = findLowRefreshRateMode(displayInfo, mDefaultMode); mHighRefreshRateDenylist = denylist; mWmService = wmService; } @@ -92,10 +96,9 @@ class RefreshRatePolicy { * Finds the mode id with the lowest refresh rate which is >= 60hz and same resolution as the * default mode. */ - private Mode findLowRefreshRateMode(DisplayInfo displayInfo) { - Mode mode = displayInfo.getDefaultMode(); + private Mode findLowRefreshRateMode(DisplayInfo displayInfo, Mode defaultMode) { float[] refreshRates = displayInfo.getDefaultRefreshRates(); - float bestRefreshRate = mode.getRefreshRate(); + float bestRefreshRate = defaultMode.getRefreshRate(); mMinSupportedRefreshRate = bestRefreshRate; mMaxSupportedRefreshRate = bestRefreshRate; for (int i = refreshRates.length - 1; i >= 0; i--) { @@ -121,13 +124,39 @@ class RefreshRatePolicy { } int getPreferredModeId(WindowState w) { + final int preferredDisplayModeId = w.mAttrs.preferredDisplayModeId; + if (preferredDisplayModeId <= 0) { + // Unspecified, use default mode. + return 0; + } + // If app is animating, it's not able to control refresh rate because we want the animation - // to run in default refresh rate. + // to run in default refresh rate. But if the display size of default mode is different + // from the using preferred mode, then still keep the preferred mode to avoid disturbing + // the animation. if (w.isAnimating(TRANSITION | PARENTS)) { + Display.Mode preferredMode = null; + for (Display.Mode mode : mDisplayInfo.supportedModes) { + if (preferredDisplayModeId == mode.getModeId()) { + preferredMode = mode; + break; + } + } + if (preferredMode != null) { + final int pW = preferredMode.getPhysicalWidth(); + final int pH = preferredMode.getPhysicalHeight(); + if ((pW != mDefaultMode.getPhysicalWidth() + || pH != mDefaultMode.getPhysicalHeight()) + && pW == mDisplayInfo.getNaturalWidth() + && pH == mDisplayInfo.getNaturalHeight()) { + // Prefer not to change display size when animating. + return preferredDisplayModeId; + } + } return 0; } - return w.mAttrs.preferredDisplayModeId; + return preferredDisplayModeId; } /** @@ -165,12 +194,9 @@ class RefreshRatePolicy { // of that mode id. final int preferredModeId = w.mAttrs.preferredDisplayModeId; if (preferredModeId > 0) { - DisplayInfo info = w.getDisplayInfo(); - if (info != null) { - for (Display.Mode mode : info.supportedModes) { - if (preferredModeId == mode.getModeId()) { - return mode.getRefreshRate(); - } + for (Display.Mode mode : mDisplayInfo.supportedModes) { + if (preferredModeId == mode.getModeId()) { + return mode.getRefreshRate(); } } } 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 9d2eb26f5f21..63797778f748 100644 --- a/services/tests/wmtests/src/com/android/server/wm/RefreshRatePolicyTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/RefreshRatePolicyTest.java @@ -21,7 +21,9 @@ import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITION; import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; import android.os.Parcel; @@ -258,6 +260,14 @@ public class RefreshRatePolicyTest extends WindowTestsBase { assertEquals(0, mPolicy.getPreferredRefreshRate(overrideWindow), FLOAT_TOLERANCE); assertEquals(0, mPolicy.getPreferredMinRefreshRate(overrideWindow), FLOAT_TOLERANCE); assertEquals(0, mPolicy.getPreferredMaxRefreshRate(overrideWindow), FLOAT_TOLERANCE); + + // If there will be display size change when switching from preferred mode to default mode, + // then keep the current preferred mode during animating. + mDisplayInfo = spy(mDisplayInfo); + final Mode defaultMode = new Mode(4321 /* width */, 1234 /* height */, LOW_REFRESH_RATE); + doReturn(defaultMode).when(mDisplayInfo).getDefaultMode(); + mPolicy = new RefreshRatePolicy(mWm, mDisplayInfo, mDenylist); + assertEquals(LOW_MODE_ID, mPolicy.getPreferredModeId(overrideWindow)); } @Test |