Merge "Prepare an interface for deferred display updates" into main
diff --git a/services/core/java/com/android/server/display/LogicalDisplay.java b/services/core/java/com/android/server/display/LogicalDisplay.java
index ba321ae..db636d6 100644
--- a/services/core/java/com/android/server/display/LogicalDisplay.java
+++ b/services/core/java/com/android/server/display/LogicalDisplay.java
@@ -17,6 +17,8 @@
package com.android.server.display;
import static com.android.server.display.DisplayDeviceInfo.TOUCH_NONE;
+import static com.android.server.wm.utils.DisplayInfoOverrides.WM_OVERRIDE_FIELDS;
+import static com.android.server.wm.utils.DisplayInfoOverrides.copyDisplayInfoFields;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -33,6 +35,7 @@
import com.android.server.display.layout.Layout;
import com.android.server.display.mode.DisplayModeDirector;
+import com.android.server.wm.utils.DisplayInfoOverrides;
import com.android.server.wm.utils.InsetUtils;
import java.io.PrintWriter;
@@ -252,24 +255,8 @@
public DisplayInfo getDisplayInfoLocked() {
if (mInfo.get() == null) {
DisplayInfo info = new DisplayInfo();
- info.copyFrom(mBaseDisplayInfo);
- if (mOverrideDisplayInfo != null) {
- info.appWidth = mOverrideDisplayInfo.appWidth;
- info.appHeight = mOverrideDisplayInfo.appHeight;
- info.smallestNominalAppWidth = mOverrideDisplayInfo.smallestNominalAppWidth;
- info.smallestNominalAppHeight = mOverrideDisplayInfo.smallestNominalAppHeight;
- info.largestNominalAppWidth = mOverrideDisplayInfo.largestNominalAppWidth;
- info.largestNominalAppHeight = mOverrideDisplayInfo.largestNominalAppHeight;
- info.logicalWidth = mOverrideDisplayInfo.logicalWidth;
- info.logicalHeight = mOverrideDisplayInfo.logicalHeight;
- info.physicalXDpi = mOverrideDisplayInfo.physicalXDpi;
- info.physicalYDpi = mOverrideDisplayInfo.physicalYDpi;
- info.rotation = mOverrideDisplayInfo.rotation;
- info.displayCutout = mOverrideDisplayInfo.displayCutout;
- info.logicalDensityDpi = mOverrideDisplayInfo.logicalDensityDpi;
- info.roundedCorners = mOverrideDisplayInfo.roundedCorners;
- info.displayShape = mOverrideDisplayInfo.displayShape;
- }
+ copyDisplayInfoFields(info, mBaseDisplayInfo, mOverrideDisplayInfo,
+ WM_OVERRIDE_FIELDS);
mInfo.set(info);
}
return mInfo.get();
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 0c4ca5f..07cbd58 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -156,6 +156,8 @@
import static com.android.server.wm.WindowState.EXCLUSION_RIGHT;
import static com.android.server.wm.WindowState.RESIZE_HANDLE_WIDTH_IN_DP;
import static com.android.server.wm.WindowStateAnimator.READY_TO_SHOW;
+import static com.android.server.wm.utils.DisplayInfoOverrides.WM_OVERRIDE_FIELDS;
+import static com.android.server.wm.utils.DisplayInfoOverrides.copyDisplayInfoFields;
import static com.android.server.wm.utils.RegionUtils.forEachRectReverse;
import static com.android.server.wm.utils.RegionUtils.rectListToRegion;
import static com.android.window.flags.Flags.explicitRefreshRateHints;
@@ -463,11 +465,20 @@
boolean mDisplayScalingDisabled;
final Display mDisplay;
private final DisplayInfo mDisplayInfo = new DisplayInfo();
+
+ /**
+ * Contains the last DisplayInfo override that was sent to DisplayManager or null if we haven't
+ * set an override yet
+ */
+ @Nullable
+ private DisplayInfo mLastDisplayInfoOverride;
+
private final DisplayMetrics mDisplayMetrics = new DisplayMetrics();
private final DisplayPolicy mDisplayPolicy;
private final DisplayRotation mDisplayRotation;
@Nullable final DisplayRotationCompatPolicy mDisplayRotationCompatPolicy;
DisplayFrames mDisplayFrames;
+ private final DisplayUpdater mDisplayUpdater;
private boolean mInTouchMode;
@@ -621,7 +632,7 @@
@VisibleForTesting
final DeviceStateController mDeviceStateController;
final Consumer<DeviceStateController.DeviceState> mDeviceStateConsumer;
- private final PhysicalDisplaySwitchTransitionLauncher mDisplaySwitchTransitionLauncher;
+ final PhysicalDisplaySwitchTransitionLauncher mDisplaySwitchTransitionLauncher;
final RemoteDisplayChangeController mRemoteDisplayChangeController;
/** Windows added since {@link #mCurrentFocus} was set to null. Used for ANR blaming. */
@@ -1142,6 +1153,7 @@
mDisplay = display;
mDisplayId = display.getDisplayId();
mCurrentUniqueDisplayId = display.getUniqueId();
+ mDisplayUpdater = new ImmediateDisplayUpdater(this);
mOffTokenAcquirer = mRootWindowContainer.mDisplayOffTokenAcquirer;
mWallpaperController = new WallpaperController(mWmService, this);
mWallpaperController.resetLargestDisplay(display);
@@ -2277,8 +2289,7 @@
computeSizeRanges(mDisplayInfo, rotated, dw, dh, mDisplayMetrics.density, outConfig);
- mWmService.mDisplayManagerInternal.setDisplayInfoOverrideFromWindowManager(mDisplayId,
- mDisplayInfo);
+ setDisplayInfoOverride();
if (isDefaultDisplay) {
mCompatibleScreenScale = CompatibilityInfo.computeCompatibleScaling(mDisplayMetrics,
@@ -2290,6 +2301,20 @@
return mDisplayInfo;
}
+ /**
+ * Sets the current DisplayInfo in DisplayContent as an override to DisplayManager
+ */
+ private void setDisplayInfoOverride() {
+ mWmService.mDisplayManagerInternal.setDisplayInfoOverrideFromWindowManager(mDisplayId,
+ mDisplayInfo);
+
+ if (mLastDisplayInfoOverride == null) {
+ mLastDisplayInfoOverride = new DisplayInfo();
+ }
+
+ mLastDisplayInfoOverride.copyFrom(mDisplayInfo);
+ }
+
DisplayCutout calculateDisplayCutoutForRotation(int rotation) {
return mDisplayCutoutCache.getOrCompute(
mIsSizeForced ? mBaseDisplayCutout : mInitialDisplayCutout, rotation)
@@ -2861,12 +2886,15 @@
return orientation;
}
- void updateDisplayInfo() {
+ void updateDisplayInfo(@NonNull DisplayInfo newDisplayInfo) {
// Check if display metrics changed and update base values if needed.
- updateBaseDisplayMetricsIfNeeded();
+ updateBaseDisplayMetricsIfNeeded(newDisplayInfo);
- mDisplay.getDisplayInfo(mDisplayInfo);
- mDisplay.getMetrics(mDisplayMetrics);
+ // Update mDisplayInfo with (newDisplayInfo + mLastDisplayInfoOverride) as
+ // updateBaseDisplayMetricsIfNeeded could have updated mLastDisplayInfoOverride
+ copyDisplayInfoFields(/* out= */ mDisplayInfo, /* base= */ newDisplayInfo,
+ /* override= */ mLastDisplayInfoOverride, /* fields= */ WM_OVERRIDE_FIELDS);
+ mDisplayInfo.getAppMetrics(mDisplayMetrics, mDisplay.getDisplayAdjustments());
onDisplayInfoChanged();
onDisplayChanged(this);
@@ -2952,9 +2980,9 @@
* If display metrics changed, overrides are not set and it's not just a rotation - update base
* values.
*/
- private void updateBaseDisplayMetricsIfNeeded() {
+ private void updateBaseDisplayMetricsIfNeeded(DisplayInfo newDisplayInfo) {
// Get real display metrics without overrides from WM.
- mWmService.mDisplayManagerInternal.getNonOverrideDisplayInfo(mDisplayId, mDisplayInfo);
+ mDisplayInfo.copyFrom(newDisplayInfo);
final int currentRotation = getRotation();
final int orientation = mDisplayInfo.rotation;
final boolean rotated = (orientation == ROTATION_90 || orientation == ROTATION_270);
@@ -2986,7 +3014,7 @@
// metrics are updated as rotation settings might depend on them
mWmService.mDisplayWindowSettings.applySettingsToDisplayLocked(this,
/* includeRotationSettings */ false);
- mDisplaySwitchTransitionLauncher.requestDisplaySwitchTransitionIfNeeded(mDisplayId,
+ mDisplayUpdater.onDisplayContentDisplayPropertiesPreChanged(mDisplayId,
mInitialDisplayWidth, mInitialDisplayHeight, newWidth, newHeight);
mDisplayRotation.physicalDisplayChanged();
mDisplayPolicy.physicalDisplayChanged();
@@ -3022,8 +3050,8 @@
if (physicalDisplayChanged) {
mDisplayPolicy.physicalDisplayUpdated();
- mDisplaySwitchTransitionLauncher.onDisplayUpdated(currentRotation, getRotation(),
- getDisplayAreaInfo());
+ mDisplayUpdater.onDisplayContentDisplayPropertiesPostChanged(currentRotation,
+ getRotation(), getDisplayAreaInfo());
}
}
}
@@ -5470,8 +5498,7 @@
mDisplayReady = true;
if (mWmService.mDisplayManagerInternal != null) {
- mWmService.mDisplayManagerInternal
- .setDisplayInfoOverrideFromWindowManager(mDisplayId, getDisplayInfo());
+ setDisplayInfoOverride();
configureDisplayPolicy();
}
@@ -6114,9 +6141,17 @@
return mMetricsLogger;
}
- void onDisplayChanged() {
+ /**
+ * Triggers an update of DisplayInfo from DisplayManager
+ * @param onDisplayChangeApplied callback that is called when the changes are applied
+ */
+ void requestDisplayUpdate(@NonNull Runnable onDisplayChangeApplied) {
+ mDisplayUpdater.updateDisplayInfo(onDisplayChangeApplied);
+ }
+
+ void onDisplayInfoUpdated(@NonNull DisplayInfo newDisplayInfo) {
final int lastDisplayState = mDisplayInfo.state;
- updateDisplayInfo();
+ updateDisplayInfo(newDisplayInfo);
// The window policy is responsible for stopping activities on the default display.
final int displayId = mDisplay.getDisplayId();
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 708ee7f..b862d7c 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -1737,11 +1737,12 @@
void onOverlayChanged() {
updateCurrentUserResources();
// Update the latest display size, cutout.
- mDisplayContent.updateDisplayInfo();
- onConfigurationChanged();
- if (!CLIENT_TRANSIENT) {
- mSystemGestures.onConfigurationChanged();
- }
+ mDisplayContent.requestDisplayUpdate(() -> {
+ onConfigurationChanged();
+ if (!CLIENT_TRANSIENT) {
+ mSystemGestures.onConfigurationChanged();
+ }
+ });
}
/**
diff --git a/services/core/java/com/android/server/wm/DisplayUpdater.java b/services/core/java/com/android/server/wm/DisplayUpdater.java
new file mode 100644
index 0000000..e611177
--- /dev/null
+++ b/services/core/java/com/android/server/wm/DisplayUpdater.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import android.annotation.NonNull;
+import android.view.Surface;
+import android.window.DisplayAreaInfo;
+
+/**
+ * Interface for a helper class that manages updates of DisplayInfo coming from DisplayManager
+ */
+interface DisplayUpdater {
+ /**
+ * Reads the latest display parameters from the display manager and returns them in a callback.
+ * If there are pending display updates, it will wait for them to finish first and only then it
+ * will call the callback with the latest display parameters.
+ *
+ * @param callback is called when all pending display updates are finished
+ */
+ void updateDisplayInfo(@NonNull Runnable callback);
+
+ /**
+ * Called when physical display has changed and before DisplayContent has applied new display
+ * properties
+ */
+ default void onDisplayContentDisplayPropertiesPreChanged(int displayId, int initialDisplayWidth,
+ int initialDisplayHeight, int newWidth, int newHeight) {
+ }
+
+ /**
+ * Called after physical display has changed and after DisplayContent applied new display
+ * properties
+ */
+ default void onDisplayContentDisplayPropertiesPostChanged(
+ @Surface.Rotation int previousRotation, @Surface.Rotation int newRotation,
+ @NonNull DisplayAreaInfo newDisplayAreaInfo) {
+ }
+}
diff --git a/services/core/java/com/android/server/wm/ImmediateDisplayUpdater.java b/services/core/java/com/android/server/wm/ImmediateDisplayUpdater.java
new file mode 100644
index 0000000..72e8fcb
--- /dev/null
+++ b/services/core/java/com/android/server/wm/ImmediateDisplayUpdater.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import android.annotation.NonNull;
+import android.view.DisplayInfo;
+import android.window.DisplayAreaInfo;
+
+/**
+ * DisplayUpdater that immediately applies new DisplayInfo properties
+ */
+public class ImmediateDisplayUpdater implements DisplayUpdater {
+
+ private final DisplayContent mDisplayContent;
+ private final DisplayInfo mDisplayInfo = new DisplayInfo();
+
+ public ImmediateDisplayUpdater(@NonNull DisplayContent displayContent) {
+ mDisplayContent = displayContent;
+ }
+
+ @Override
+ public void updateDisplayInfo(Runnable callback) {
+ mDisplayContent.mWmService.mDisplayManagerInternal.getNonOverrideDisplayInfo(
+ mDisplayContent.mDisplayId, mDisplayInfo);
+ mDisplayContent.onDisplayInfoUpdated(mDisplayInfo);
+ callback.run();
+ }
+
+ @Override
+ public void onDisplayContentDisplayPropertiesPreChanged(int displayId, int initialDisplayWidth,
+ int initialDisplayHeight, int newWidth, int newHeight) {
+ mDisplayContent.mDisplaySwitchTransitionLauncher.requestDisplaySwitchTransitionIfNeeded(
+ displayId, initialDisplayWidth, initialDisplayHeight, newWidth, newHeight);
+ }
+
+ @Override
+ public void onDisplayContentDisplayPropertiesPostChanged(int previousRotation, int newRotation,
+ DisplayAreaInfo newDisplayAreaInfo) {
+ mDisplayContent.mDisplaySwitchTransitionLauncher.onDisplayUpdated(previousRotation,
+ newRotation,
+ newDisplayAreaInfo);
+ }
+}
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 0c235ba..d65d778 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -2716,15 +2716,20 @@
synchronized (mService.mGlobalLock) {
final DisplayContent displayContent = getDisplayContent(displayId);
if (displayContent != null) {
- displayContent.onDisplayChanged();
+ displayContent.requestDisplayUpdate(() -> clearDisplayInfoCaches(displayId));
+ } else {
+ clearDisplayInfoCaches(displayId);
}
- // Drop any cached DisplayInfos associated with this display id - the values are now
- // out of date given this display changed event.
- mWmService.mPossibleDisplayInfoMapper.removePossibleDisplayInfos(displayId);
- updateDisplayImePolicyCache();
}
}
+ private void clearDisplayInfoCaches(int displayId) {
+ // Drop any cached DisplayInfos associated with this display id - the values are now
+ // out of date given this display changed event.
+ mWmService.mPossibleDisplayInfoMapper.removePossibleDisplayInfos(displayId);
+ updateDisplayImePolicyCache();
+ }
+
void updateDisplayImePolicyCache() {
ArrayMap<Integer, Integer> displayImePolicyMap = new ArrayMap<>();
forAllDisplays(dc -> displayImePolicyMap.put(dc.getDisplayId(), dc.getImePolicy()));
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index a69a07f..575ae69b 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -6238,9 +6238,11 @@
return;
}
- Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "WMS.doStartFreezingDisplay");
- doStartFreezingDisplay(exitAnim, enterAnim, displayContent, overrideOriginalRotation);
- Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
+ displayContent.requestDisplayUpdate(() -> {
+ Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "WMS.doStartFreezingDisplay");
+ doStartFreezingDisplay(exitAnim, enterAnim, displayContent, overrideOriginalRotation);
+ Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
+ });
}
private void doStartFreezingDisplay(int exitAnim, int enterAnim, DisplayContent displayContent,
@@ -6276,7 +6278,6 @@
mExitAnimId = exitAnim;
mEnterAnimId = enterAnim;
- displayContent.updateDisplayInfo();
final int originalRotation = overrideOriginalRotation != ROTATION_UNDEFINED
? overrideOriginalRotation
: displayContent.getDisplayInfo().rotation;
diff --git a/services/core/java/com/android/server/wm/utils/DisplayInfoOverrides.java b/services/core/java/com/android/server/wm/utils/DisplayInfoOverrides.java
new file mode 100644
index 0000000..8c8f6a6
--- /dev/null
+++ b/services/core/java/com/android/server/wm/utils/DisplayInfoOverrides.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.utils;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.view.DisplayInfo;
+
+/**
+ * Helper class to copy only subset of fields of DisplayInfo object or to perform
+ * comparison operation between DisplayInfo objects only with a subset of fields.
+ */
+public class DisplayInfoOverrides {
+
+ /**
+ * Set of DisplayInfo fields that are overridden in DisplayManager using values from
+ * WindowManager
+ */
+ public static final DisplayInfoFields WM_OVERRIDE_FIELDS = (out, source) -> {
+ out.appWidth = source.appWidth;
+ out.appHeight = source.appHeight;
+ out.smallestNominalAppWidth = source.smallestNominalAppWidth;
+ out.smallestNominalAppHeight = source.smallestNominalAppHeight;
+ out.largestNominalAppWidth = source.largestNominalAppWidth;
+ out.largestNominalAppHeight = source.largestNominalAppHeight;
+ out.logicalWidth = source.logicalWidth;
+ out.logicalHeight = source.logicalHeight;
+ out.physicalXDpi = source.physicalXDpi;
+ out.physicalYDpi = source.physicalYDpi;
+ out.rotation = source.rotation;
+ out.displayCutout = source.displayCutout;
+ out.logicalDensityDpi = source.logicalDensityDpi;
+ out.roundedCorners = source.roundedCorners;
+ out.displayShape = source.displayShape;
+ };
+
+ /**
+ * Gets {@param base} DisplayInfo, overrides WindowManager-specific overrides using
+ * {@param override} and writes the result to {@param out}
+ */
+ public static void copyDisplayInfoFields(@NonNull DisplayInfo out,
+ @NonNull DisplayInfo base,
+ @Nullable DisplayInfo override,
+ @NonNull DisplayInfoFields fields) {
+ out.copyFrom(base);
+
+ if (override != null) {
+ fields.setFields(out, override);
+ }
+ }
+
+ /**
+ * Callback interface that allows to specify a subset of fields of DisplayInfo object
+ */
+ public interface DisplayInfoFields {
+ /**
+ * Copies a subset of fields from {@param source} to {@param out}
+ *
+ * @param out resulting DisplayInfo object
+ * @param source source DisplayInfo to copy fields from
+ */
+ void setFields(@NonNull DisplayInfo out, @NonNull DisplayInfo source);
+ }
+}
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
index 3ede135..acce2e2 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -157,6 +157,10 @@
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
/**
* Tests for the {@link DisplayContent} class.
@@ -2285,7 +2289,7 @@
0 /* userId */);
dc.mCurrentUniqueDisplayId = mDisplayInfo.uniqueId + "-test";
// Trigger display changed.
- dc.onDisplayChanged();
+ updateDisplay(dc);
// Ensure overridden size and denisty match the most up-to-date values in settings for the
// display.
verifySizes(dc, forcedWidth, forcedHeight, forcedDensity);
@@ -2830,7 +2834,7 @@
*/
private DisplayContent createDisplayNoUpdateDisplayInfo() {
final DisplayContent displayContent = createNewDisplay();
- doNothing().when(displayContent).updateDisplayInfo();
+ doNothing().when(displayContent).updateDisplayInfo(any());
return displayContent;
}
@@ -2860,6 +2864,16 @@
return result;
}
+ private void updateDisplay(DisplayContent displayContent) {
+ CompletableFuture<Object> future = new CompletableFuture<>();
+ displayContent.requestDisplayUpdate(() -> future.complete(new Object()));
+ try {
+ future.get(15, TimeUnit.SECONDS);
+ } catch (InterruptedException | ExecutionException | TimeoutException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
private void tapOnDisplay(final DisplayContent dc) {
final DisplayMetrics dm = dc.getDisplayMetrics();
final float x = dm.widthPixels / 2;
diff --git a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
index 9af5ba5..5738d24 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
@@ -69,6 +69,7 @@
import android.os.UserHandle;
import android.provider.DeviceConfig;
import android.util.Log;
+import android.view.DisplayInfo;
import android.view.InputChannel;
import android.view.SurfaceControl;
@@ -267,6 +268,12 @@
// DisplayManagerInternal
final DisplayManagerInternal dmi = mock(DisplayManagerInternal.class);
doReturn(dmi).when(() -> LocalServices.getService(eq(DisplayManagerInternal.class)));
+ doAnswer(invocation -> {
+ int displayId = invocation.getArgument(0);
+ DisplayInfo displayInfo = invocation.getArgument(1);
+ mWmService.mRoot.getDisplayContent(displayId).getDisplay().getDisplayInfo(displayInfo);
+ return null;
+ }).when(dmi).getNonOverrideDisplayInfo(anyInt(), any());
// ColorDisplayServiceInternal
final ColorDisplayService.ColorDisplayServiceInternal cds =
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowContextListenerControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowContextListenerControllerTests.java
index 2d5b72b..d183cf7 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowContextListenerControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowContextListenerControllerTests.java
@@ -60,6 +60,11 @@
import org.mockito.Mock;
import org.mockito.Mockito;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
/**
* Build/Install/Run:
* atest WmTests:WindowContextListenerControllerTests
@@ -309,7 +314,7 @@
return null;
}).when(display).getDisplayInfo(any(DisplayInfo.class));
- mContainer.getDisplayContent().onDisplayChanged();
+ updateDisplay(mContainer.getDisplayContent());
assertThat(mockToken.mConfiguration).isEqualTo(config1);
assertThat(mockToken.mDisplayId).isEqualTo(mContainer.getDisplayContent().getDisplayId());
@@ -352,4 +357,14 @@
mRemoved = true;
}
}
+
+ private void updateDisplay(DisplayContent displayContent) {
+ CompletableFuture<Object> future = new CompletableFuture<>();
+ displayContent.requestDisplayUpdate(() -> future.complete(new Object()));
+ try {
+ future.get(15, TimeUnit.SECONDS);
+ } catch (InterruptedException | ExecutionException | TimeoutException e) {
+ throw new RuntimeException(e);
+ }
+ }
}