diff --git a/services/core/java/com/android/server/wm/WindowContextListenerController.java b/services/core/java/com/android/server/wm/WindowContextListenerController.java index 5e75996b00120..a127611b2cce7 100644 --- a/services/core/java/com/android/server/wm/WindowContextListenerController.java +++ b/services/core/java/com/android/server/wm/WindowContextListenerController.java @@ -271,6 +271,21 @@ class WindowContextListenerController { if (mDeathRecipient == null) { throw new IllegalStateException("Invalid client token: " + mClientToken); } + final WindowToken windowToken = mContainer.asWindowToken(); + if (windowToken != null && windowToken.isFromClient()) { + // If the WindowContext created WindowToken is removed by + // WMS#postWindowRemoveCleanupLocked, the WindowContext should switch back to + // listen to previous associated DisplayArea. + final DisplayContent dc = windowToken.mWmService.mRoot + .getDisplayContent(mLastReportedDisplay); + // If we cannot obtain the DisplayContent, the DisplayContent may also be removed. + // We should proceed the removal process. + if (dc != null) { + final DisplayArea da = dc.findAreaForToken(windowToken); + updateContainer(da); + return; + } + } mDeathRecipient.unlinkToDeath(); IWindowToken windowTokenClient = IWindowToken.Stub.asInterface(mClientToken); try { 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 73b9173ba1438..5d0fe170885a2 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowContextListenerControllerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowContextListenerControllerTests.java @@ -17,8 +17,11 @@ package com.android.server.wm; import static android.view.Display.DEFAULT_DISPLAY; +import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; +import static com.google.common.truth.Truth.assertThat; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @@ -162,6 +165,26 @@ public class WindowContextListenerControllerTests extends WindowTestsBase { false /* callerCanManagerAppTokens */, ANOTHER_UID); } + @Test + public void testWindowContextCreatedWindowTokenRemoved_SwitchToListenToDA() { + WindowToken windowContextCreatedToken = new WindowToken.Builder(mWm, mClientToken, + TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY) + .setDisplayContent(mDefaultDisplay) + .setFromClientToken(true) + .build(); + final DisplayArea da = windowContextCreatedToken.getDisplayArea(); + + mController.registerWindowContainerListener(mClientToken, windowContextCreatedToken, + TEST_UID, TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY, null /* options */); + + assertThat(mController.getContainer(mClientToken)).isEqualTo(windowContextCreatedToken); + + // Remove WindowToken + windowContextCreatedToken.removeImmediately(); + + assertThat(mController.getContainer(mClientToken)).isEqualTo(da); + } + private class TestWindowTokenClient extends IWindowToken.Stub { private Configuration mConfiguration; private int mDisplayId;