diff options
11 files changed, 303 insertions, 51 deletions
diff --git a/services/core/java/com/android/server/display/LogicalDisplay.java b/services/core/java/com/android/server/display/LogicalDisplay.java index 3d4209e0d6f3..a03db96f567d 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 android.view.SurfaceControl; 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 @@ final class LogicalDisplay { 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 7f80807e137b..78c1834a5ba5 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -158,6 +158,8 @@ import static com.android.server.wm.WindowState.EXCLUSION_LEFT; 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; @@ -464,11 +466,20 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp 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; @@ -622,7 +633,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp @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. */ @@ -1146,6 +1157,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp mDisplay = display; mDisplayId = display.getDisplayId(); mCurrentUniqueDisplayId = display.getUniqueId(); + mDisplayUpdater = new ImmediateDisplayUpdater(this); mOffTokenAcquirer = mRootWindowContainer.mDisplayOffTokenAcquirer; mWallpaperController = new WallpaperController(mWmService, this); mWallpaperController.resetLargestDisplay(display); @@ -2303,8 +2315,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp computeSizeRanges(mDisplayInfo, rotated, dw, dh, mDisplayMetrics.density, outConfig); - mWmService.mDisplayManagerInternal.setDisplayInfoOverrideFromWindowManager(mDisplayId, - mDisplayInfo); + setDisplayInfoOverride(); if (isDefaultDisplay) { mCompatibleScreenScale = CompatibilityInfo.computeCompatibleScaling(mDisplayMetrics, @@ -2316,6 +2327,20 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp 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) @@ -2887,12 +2912,15 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp 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); @@ -2978,9 +3006,9 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp * 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); @@ -3012,7 +3040,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp // 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(); @@ -3048,8 +3076,8 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp if (physicalDisplayChanged) { mDisplayPolicy.physicalDisplayUpdated(); - mDisplaySwitchTransitionLauncher.onDisplayUpdated(currentRotation, getRotation(), - getDisplayAreaInfo()); + mDisplayUpdater.onDisplayContentDisplayPropertiesPostChanged(currentRotation, + getRotation(), getDisplayAreaInfo()); } } } @@ -5496,8 +5524,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp mDisplayReady = true; if (mWmService.mDisplayManagerInternal != null) { - mWmService.mDisplayManagerInternal - .setDisplayInfoOverrideFromWindowManager(mDisplayId, getDisplayInfo()); + setDisplayInfoOverride(); configureDisplayPolicy(); } @@ -6134,9 +6161,17 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp 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 b34f912e1c78..c4dab1c805d3 100644 --- a/services/core/java/com/android/server/wm/DisplayPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayPolicy.java @@ -1717,11 +1717,12 @@ public class DisplayPolicy { 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 000000000000..e611177210e8 --- /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 000000000000..72e8fcb05bb9 --- /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 5227a52545f4..fa6b86f2cd39 100644 --- a/services/core/java/com/android/server/wm/RootWindowContainer.java +++ b/services/core/java/com/android/server/wm/RootWindowContainer.java @@ -2730,15 +2730,20 @@ class RootWindowContainer extends WindowContainer<DisplayContent> 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 757d6d68c3b3..56ffa643edf7 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -6261,9 +6261,11 @@ public class WindowManagerService extends IWindowManager.Stub 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, @@ -6299,7 +6301,6 @@ public class WindowManagerService extends IWindowManager.Stub 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 000000000000..8c8f6a6cb386 --- /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 5b88c8cbec92..584db878bef2 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java @@ -159,6 +159,10 @@ import java.util.Arrays; 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. @@ -2272,7 +2276,7 @@ public class DisplayContentTests extends WindowTestsBase { 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); @@ -2837,7 +2841,7 @@ public class DisplayContentTests extends WindowTestsBase { */ private DisplayContent createDisplayNoUpdateDisplayInfo() { final DisplayContent displayContent = createNewDisplay(); - doNothing().when(displayContent).updateDisplayInfo(); + doNothing().when(displayContent).updateDisplayInfo(any()); return displayContent; } @@ -2867,6 +2871,16 @@ public class DisplayContentTests extends WindowTestsBase { 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 9af5ba57d6c9..5738d246dea9 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.StrictMode; 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 @@ public class SystemServicesTestRule implements TestRule { // 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 2d5b72b3c680..d183cf720491 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.junit.runner.RunWith; 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 @@ public class WindowContextListenerControllerTests extends WindowTestsBase { 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 @@ public class WindowContextListenerControllerTests extends WindowTestsBase { 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); + } + } } |