diff options
5 files changed, 44 insertions, 28 deletions
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 67fe1491c48b..6d3fabc3f93d 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -1032,31 +1032,13 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo // Sets the display content for the children. onDisplayChanged(this); - // Add itself as a child to the root container. - mWmService.mRoot.addChild(this, POSITION_BOTTOM); - - // TODO(b/62541591): evaluate whether this is the best spot to declare the - // {@link DisplayContent} ready for use. - mDisplayReady = true; - - mWmService.mAnimator.addDisplayLocked(mDisplayId); - mInputMonitor = new InputMonitor(mWmService, mDisplayId); + mInputMonitor = new InputMonitor(mWmService, this); mInsetsStateController = new InsetsStateController(this); mInsetsPolicy = new InsetsPolicy(mInsetsStateController, this); - if (DEBUG_DISPLAY) Slog.v(TAG_WM, "Adding display=" + display); + if (DEBUG_DISPLAY) Slog.v(TAG_WM, "Creating display=" + display); mWmService.mDisplayWindowSettings.applySettingsToDisplayLocked(this); - - if (mWmService.mDisplayManagerInternal != null) { - mWmService.mDisplayManagerInternal - .setDisplayInfoOverrideFromWindowManager(mDisplayId, getDisplayInfo()); - configureDisplayPolicy(); - } - - reconfigureDisplayLocked(); - onRequestedOverrideConfigurationChanged(getRequestedOverrideConfiguration()); - mWmService.mDisplayNotificationController.dispatchDisplayAdded(this); } boolean isReady() { @@ -4994,6 +4976,24 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo // we create the root surfaces explicitly rather than chaining // up as the default implementation in onParentChanged does. So we // explicitly do NOT call super here. + + if (!isReady()) { + // TODO(b/62541591): evaluate whether this is the best spot to declare the + // {@link DisplayContent} ready for use. + mDisplayReady = true; + + mWmService.mAnimator.addDisplayLocked(mDisplayId); + + if (mWmService.mDisplayManagerInternal != null) { + mWmService.mDisplayManagerInternal + .setDisplayInfoOverrideFromWindowManager(mDisplayId, getDisplayInfo()); + configureDisplayPolicy(); + } + + reconfigureDisplayLocked(); + onRequestedOverrideConfigurationChanged(getRequestedOverrideConfiguration()); + mWmService.mDisplayNotificationController.dispatchDisplayAdded(this); + } } @Override diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java index a8ff5002bc58..c4b67d76607e 100644 --- a/services/core/java/com/android/server/wm/InputMonitor.java +++ b/services/core/java/com/android/server/wm/InputMonitor.java @@ -151,10 +151,10 @@ final class InputMonitor { private final UpdateInputWindows mUpdateInputWindows = new UpdateInputWindows(); - public InputMonitor(WindowManagerService service, int displayId) { + InputMonitor(WindowManagerService service, DisplayContent displayContent) { mService = service; - mDisplayContent = mService.mRoot.getDisplayContent(displayId); - mDisplayId = displayId; + mDisplayContent = displayContent; + mDisplayId = displayContent.getDisplayId(); mInputTransaction = mService.mTransactionFactory.get(); mHandler = mService.mAnimationHandler; mUpdateInputForAllWindowsConsumer = new UpdateInputForAllWindowsConsumer(); diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java index 704ab677f91d..a7bf6600d7b5 100644 --- a/services/core/java/com/android/server/wm/RootWindowContainer.java +++ b/services/core/java/com/android/server/wm/RootWindowContainer.java @@ -1377,6 +1377,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> for (int displayNdx = 0; displayNdx < displays.length; ++displayNdx) { final Display display = displays[displayNdx]; final DisplayContent displayContent = new DisplayContent(display, this); + addChild(displayContent, POSITION_BOTTOM); if (displayContent.mDisplayId == DEFAULT_DISPLAY) { mDefaultDisplay = displayContent; } @@ -1445,6 +1446,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> } // The display hasn't been added to ActivityManager yet, create a new record now. displayContent = new DisplayContent(display, this); + addChild(displayContent, POSITION_BOTTOM); return displayContent; } 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 05d1c76fed8c..e50750841e20 100644 --- a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java +++ b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java @@ -408,6 +408,16 @@ public class SystemServicesTestRule implements TestRule { } } + /** + * Throws if caller doesn't hold the given lock. + * @param lock the lock + */ + static void checkHoldsLock(Object lock) { + if (!Thread.holdsLock(lock)) { + throw new IllegalStateException("Caller doesn't hold global lock."); + } + } + protected class TestActivityTaskManagerService extends ActivityTaskManagerService { // ActivityStackSupervisor may be created more than once while setting up AMS and ATMS. // We keep the reference in order to prevent creating it twice. diff --git a/services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java b/services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java index e5121b9297e6..77af5eec2796 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java +++ b/services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java @@ -72,7 +72,7 @@ class TestDisplayContent extends DisplayContent { private final DisplayInfo mInfo; private boolean mCanRotate = true; private int mWindowingMode = WINDOWING_MODE_FULLSCREEN; - private int mPosition = POSITION_TOP; + private int mPosition = POSITION_BOTTOM; private final ActivityTaskManagerService mService; private boolean mSystemDecorations = false; @@ -127,13 +127,13 @@ class TestDisplayContent extends DisplayContent { return this; } TestDisplayContent build() { + SystemServicesTestRule.checkHoldsLock(mService.mGlobalLock); + final int displayId = SystemServicesTestRule.sNextDisplayId++; final Display display = new Display(DisplayManagerGlobal.getInstance(), displayId, mInfo, DEFAULT_DISPLAY_ADJUSTMENTS); - final TestDisplayContent newDisplay; - synchronized (mService.mGlobalLock) { - newDisplay = new TestDisplayContent(mService.mStackSupervisor, display); - } + final TestDisplayContent newDisplay = + new TestDisplayContent(mService.mStackSupervisor, display); // disable the normal system decorations final DisplayPolicy displayPolicy = newDisplay.mDisplayContent.getDisplayPolicy(); spyOn(displayPolicy); @@ -153,6 +153,10 @@ class TestDisplayContent extends DisplayContent { doReturn(false).when(newDisplay.mDisplayContent) .handlesOrientationChangeFromDescendant(); } + // Please add stubbing before this line. Services will start using this display in other + // threads immediately after adding it to hierarchy. Calling doAnswer() type of stubbing + // reduces chance of races, but still doesn't eliminate race conditions. + mService.mRootWindowContainer.addChild(newDisplay, mPosition); return newDisplay; } } |