summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Riddle Hsu <riddlehsu@google.com> 2023-05-25 22:40:23 +0800
committer Riddle Hsu <riddlehsu@google.com> 2023-05-26 09:26:27 +0000
commit2f95cf02db412c355d779eb9d7088912c635cb2b (patch)
treeaafa2af4ef69bb01d29cf82d7aec225fb3a74a62
parent61f4503d08d106370e7c885ad3a0f62c7df4b875 (diff)
Update decor insets when the amount of insets source is changed
For example, a display cutout has a top insets with 50px. Then when adding status bar with 20px, the size of insets is still 50px so no need to trigger display size change. But for a different rotation, the display cutout will be at another side, then the top insets will become 20px from status bar. The problem will be an additional display config change when the first time orientation change happens. The case will only happen once per boot. This change ensures that the insets in non-current rotation are updated when the insets source is added or removed. Though the count is not 100% accurate for any layout param changes, it is the most efficient way to correct the state only once when initializing (usually only when booting) the insets windows instead of re-compute for every layout change. Fix: 280930112 Test: DisplayPolicyTests#testUpdateDisplayConfigurationByDecor Change-Id: Ieedcc6388237b7feccd8a869105a5f8e70ff4afd
-rw-r--r--services/core/java/com/android/server/wm/DisplayPolicy.java18
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java32
2 files changed, 50 insertions, 0 deletions
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 77e70a25d497..65771d1ce373 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -1854,6 +1854,9 @@ public class DisplayPolicy {
*/
final Rect mConfigFrame = new Rect();
+ /** The count of insets sources when calculating this info. */
+ int mLastInsetsSourceCount;
+
private boolean mNeedUpdate = true;
void update(DisplayContent dc, int rotation, int w, int h) {
@@ -1875,6 +1878,7 @@ public class DisplayPolicy {
mNonDecorFrame.inset(mNonDecorInsets);
mConfigFrame.set(displayFrame);
mConfigFrame.inset(mConfigInsets);
+ mLastInsetsSourceCount = dc.getDisplayPolicy().mInsetsSourceWindowsExceptIme.size();
mNeedUpdate = false;
}
@@ -1883,6 +1887,7 @@ public class DisplayPolicy {
mConfigInsets.set(other.mConfigInsets);
mNonDecorFrame.set(other.mNonDecorFrame);
mConfigFrame.set(other.mConfigFrame);
+ mLastInsetsSourceCount = other.mLastInsetsSourceCount;
mNeedUpdate = false;
}
@@ -1981,6 +1986,19 @@ public class DisplayPolicy {
newInfo.update(mDisplayContent, rotation, dw, dh);
final DecorInsets.Info currentInfo = getDecorInsetsInfo(rotation, dw, dh);
if (newInfo.mConfigFrame.equals(currentInfo.mConfigFrame)) {
+ // Even if the config frame is not changed in current rotation, it may change the
+ // insets in other rotations if the source count is changed.
+ if (newInfo.mLastInsetsSourceCount != currentInfo.mLastInsetsSourceCount) {
+ for (int i = mDecorInsets.mInfoForRotation.length - 1; i >= 0; i--) {
+ if (i != rotation) {
+ final boolean flipSize = (i + rotation) % 2 == 1;
+ final int w = flipSize ? dh : dw;
+ final int h = flipSize ? dw : dh;
+ mDecorInsets.mInfoForRotation[i].update(mDisplayContent, i, w, h);
+ }
+ }
+ mDecorInsets.mInfoForRotation[rotation].set(newInfo);
+ }
return false;
}
if (mCachedDecorInsets != null && !mCachedDecorInsets.canPreserve()
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 5ec36048234b..d0eb1b2ec220 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
@@ -51,14 +51,18 @@ import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
+import android.graphics.Insets;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.platform.test.annotations.Presubmit;
import android.view.DisplayInfo;
import android.view.DisplayShape;
+import android.view.InsetsFrameProvider;
import android.view.InsetsSource;
import android.view.InsetsState;
import android.view.PrivacyIndicatorBounds;
+import android.view.Surface;
+import android.view.WindowInsets;
import android.view.WindowInsets.Side;
import android.view.WindowManager;
@@ -350,6 +354,34 @@ public class DisplayPolicyTests extends WindowTestsBase {
&& displayPolicy.updateDecorInsetsInfo());
assertEquals(STATUS_BAR_HEIGHT, displayPolicy.getDecorInsetsInfo(di.rotation,
di.logicalWidth, di.logicalHeight).mConfigInsets.top);
+
+ // Add a window that provides the same insets in current rotation. But it specifies
+ // different insets in other rotations.
+ final WindowState bar2 = createWindow(null, statusBar.mAttrs.type, "bar2");
+ bar2.mAttrs.providedInsets = new InsetsFrameProvider[] {
+ new InsetsFrameProvider(bar2, 0, WindowInsets.Type.statusBars())
+ .setInsetsSize(Insets.of(0, STATUS_BAR_HEIGHT, 0, 0))
+ };
+ bar2.mAttrs.paramsForRotation = new WindowManager.LayoutParams[4];
+ final int doubleHeightFor90 = STATUS_BAR_HEIGHT * 2;
+ for (int i = ROTATION_0; i <= Surface.ROTATION_270; i++) {
+ final WindowManager.LayoutParams params = new WindowManager.LayoutParams();
+ if (i == Surface.ROTATION_90) {
+ params.providedInsets = new InsetsFrameProvider[] {
+ new InsetsFrameProvider(bar2, 0, WindowInsets.Type.statusBars())
+ .setInsetsSize(Insets.of(0, doubleHeightFor90, 0, 0))
+ };
+ } else {
+ params.providedInsets = bar2.mAttrs.providedInsets;
+ }
+ bar2.mAttrs.paramsForRotation[i] = params;
+ }
+ displayPolicy.addWindowLw(bar2, bar2.mAttrs);
+ // Current rotation is 0 and the top insets is still STATUS_BAR_HEIGHT, so no change.
+ assertFalse(displayPolicy.updateDecorInsetsInfo());
+ // The insets in other rotations should be still updated.
+ assertEquals(doubleHeightFor90, displayPolicy.getDecorInsetsInfo(Surface.ROTATION_90,
+ di.logicalHeight, di.logicalWidth).mConfigInsets.top);
}
@SetupWindows(addWindows = { W_NAVIGATION_BAR, W_INPUT_METHOD })