Fix issue with where display is removed while creating it in AM and WM
It is possible to a display to be removed while we are in the ctor of
ActivityDisplay in AM, but before we can get the Display object in the
ctor of DisplayWindowController in WM. This causes us to throw an
exception becuase the caller is trying to add a display we can't find in
display manager. Unfortunately there isn't a good way to handle this race.
To work around it we will now pass the Display object from AM to WM to use
and depend on the fact that AM will remove the display shortly after.
Change-Id: Ie3f9d86bad67f5a023e3e7dfce5219b98c796864
Fixes: 72893961
Test: go/wm-smoke
diff --git a/services/core/java/com/android/server/am/ActivityDisplay.java b/services/core/java/com/android/server/am/ActivityDisplay.java
index dd83a36..4498077 100644
--- a/services/core/java/com/android/server/am/ActivityDisplay.java
+++ b/services/core/java/com/android/server/am/ActivityDisplay.java
@@ -106,21 +106,21 @@
private DisplayWindowController mWindowContainerController;
+ @VisibleForTesting
ActivityDisplay(ActivityStackSupervisor supervisor, int displayId) {
+ this(supervisor, supervisor.mDisplayManager.getDisplay(displayId));
+ }
+
+ ActivityDisplay(ActivityStackSupervisor supervisor, Display display) {
mSupervisor = supervisor;
- mDisplayId = displayId;
- final Display display = supervisor.mDisplayManager.getDisplay(displayId);
- if (display == null) {
- throw new IllegalStateException("Display does not exist displayId=" + displayId);
- }
+ mDisplayId = display.getDisplayId();
mDisplay = display;
mWindowContainerController = createWindowContainerController();
-
updateBounds();
}
protected DisplayWindowController createWindowContainerController() {
- return new DisplayWindowController(mDisplayId, this);
+ return new DisplayWindowController(mDisplay, this);
}
void updateBounds() {
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 740a312..d372bd8 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -652,9 +652,9 @@
Display[] displays = mDisplayManager.getDisplays();
for (int displayNdx = displays.length - 1; displayNdx >= 0; --displayNdx) {
- final int displayId = displays[displayNdx].getDisplayId();
- ActivityDisplay activityDisplay = new ActivityDisplay(this, displayId);
- mActivityDisplays.put(displayId, activityDisplay);
+ final Display display = displays[displayNdx];
+ ActivityDisplay activityDisplay = new ActivityDisplay(this, display);
+ mActivityDisplays.put(display.getDisplayId(), activityDisplay);
calculateDefaultMinimalSizeOfResizeableTasks(activityDisplay);
}
@@ -4085,7 +4085,7 @@
return null;
}
// The display hasn't been added to ActivityManager yet, create a new record now.
- activityDisplay = new ActivityDisplay(this, displayId);
+ activityDisplay = new ActivityDisplay(this, display);
attachDisplay(activityDisplay);
calculateDefaultMinimalSizeOfResizeableTasks(activityDisplay);
mWindowManager.onDisplayAdded(displayId);
diff --git a/services/core/java/com/android/server/wm/DisplayWindowController.java b/services/core/java/com/android/server/wm/DisplayWindowController.java
index e3e4a46..ba8ec69 100644
--- a/services/core/java/com/android/server/wm/DisplayWindowController.java
+++ b/services/core/java/com/android/server/wm/DisplayWindowController.java
@@ -34,25 +34,21 @@
private final int mDisplayId;
- public DisplayWindowController(int displayId, WindowContainerListener listener) {
+ public DisplayWindowController(Display display, WindowContainerListener listener) {
super(listener, WindowManagerService.getInstance());
- mDisplayId = displayId;
+ mDisplayId = display.getDisplayId();
synchronized (mWindowMap) {
- final Display display = mService.mDisplayManager.getDisplay(displayId);
- if (display != null) {
- final long callingIdentity = Binder.clearCallingIdentity();
- try {
- mRoot.createDisplayContent(display, this /* controller */);
- } finally {
- Binder.restoreCallingIdentity(callingIdentity);
- }
+ final long callingIdentity = Binder.clearCallingIdentity();
+ try {
+ mRoot.createDisplayContent(display, this /* controller */);
+ } finally {
+ Binder.restoreCallingIdentity(callingIdentity);
}
if (mContainer == null) {
- throw new IllegalArgumentException("Trying to add displayId=" + displayId
- + " display=" + display
- + " dc=" + mRoot.getDisplayContent(displayId));
+ throw new IllegalArgumentException("Trying to add display=" + display
+ + " dc=" + mRoot.getDisplayContent(mDisplayId));
}
}
}