Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d9ea032b authored by Charles Chen's avatar Charles Chen
Browse files

Fix WindowContext is removed unexpectedly

Previously WindowContext is removed if the associated WindowContainer
is removed. However, it causes an issue that WindowContext is removed
unexpectedly after the last window is removed by WM#removeView().
When the last view is removed, WMS will remove the WindowToken
in postWindowRemoveCleanupLocked(), and if the WindowToken is created
by WindowContext, the associated WindowContext is also removed
unexpectedly.

This CL makes WindowContext switch back to listen to the previous
DisplayArea if the last window is removed.

Test: atest WindowContextListenerControllerTests
Bug: 185460076

Change-Id: I9c1d0c15c77bbfb3662355f8c72f0d8c70ed6748
parent 6db5c607
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -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 {
+23 −0
Original line number Diff line number Diff line
@@ -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;