Preserve decor insets cache if screen is not turned on
Currently, the steps of display switch could be:
1. Awake
2. Transition
3. Screen on fully
The order of 2 and 3 is not always the same.
The condition "mDisplayContent.isSleeping()" depends on 1.
So to avoid the cache from being cleared too early which may
cause additional display configuration changes, preserve the
cache until 2+3 is done rather than 1+2.
Remove the validator after transition because it can be called
before the insets provider windows update new layout, then it
doesn't really help to validate but trigger extra configuration
changes.
Bug: 266197298
Test: DisplayPolicyTests#testSwitchDecorInsets
Change-Id: Iab5fbeb8685a306d5e57c5d4923cf7ad6ed0f454
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index a7bbc25..9601964 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -2070,8 +2070,7 @@
}
return false;
}
- if (mCachedDecorInsets != null && !mCachedDecorInsets.canPreserve()
- && !mDisplayContent.isSleeping()) {
+ if (mCachedDecorInsets != null && !mCachedDecorInsets.canPreserve() && mScreenOnFully) {
mCachedDecorInsets = null;
}
mDecorInsets.invalidate();
@@ -2136,16 +2135,6 @@
}
mCachedDecorInsets.mPreserveId =
mDisplayContent.mTransitionController.getCollectingTransitionId();
- // The validator will run after the transition is finished. So if the insets are changed
- // during the transition, it can update to the latest state.
- mDisplayContent.mTransitionController.mStateValidators.add(() -> {
- // The insets provider client may defer to change its window until screen is on. So
- // only validate when awake to avoid the cache being always dropped.
- if (!mDisplayContent.isSleeping() && updateDecorInsetsInfo()) {
- Slog.d(TAG, "Insets changed after display switch transition");
- mDisplayContent.sendNewConfiguration();
- }
- });
}
@NavigationBarPosition
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
index 5d14334..5965fae 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
@@ -39,6 +39,7 @@
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.server.policy.WindowManagerPolicy.NAV_BAR_BOTTOM;
import static org.junit.Assert.assertEquals;
@@ -388,6 +389,24 @@
// The current insets are restored from cache directly.
assertEquals(prevConfigFrame, displayPolicy.getDecorInsetsInfo(info.rotation,
info.logicalWidth, info.logicalHeight).mConfigFrame);
+
+ // If screen is not fully turned on, then the cache should be preserved.
+ displayPolicy.screenTurnedOff();
+ final TransitionController transitionController = mDisplayContent.mTransitionController;
+ spyOn(transitionController);
+ doReturn(true).when(transitionController).isCollecting();
+ doReturn(Integer.MAX_VALUE).when(transitionController).getCollectingTransitionId();
+ // Make CachedDecorInsets.canPreserve return false.
+ displayPolicy.physicalDisplayUpdated();
+ assertFalse(displayPolicy.shouldKeepCurrentDecorInsets());
+ displayPolicy.getDecorInsetsInfo(info.rotation, info.logicalWidth, info.logicalHeight)
+ .mConfigFrame.offset(1, 1);
+ // Even if CachedDecorInsets.canPreserve returns false, the cache won't be cleared.
+ displayPolicy.updateDecorInsetsInfo();
+ // Successful to restore from cache.
+ displayPolicy.updateCachedDecorInsets();
+ assertEquals(prevConfigFrame, displayPolicy.getDecorInsetsInfo(info.rotation,
+ info.logicalWidth, info.logicalHeight).mConfigFrame);
}
@Test