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

Commit 6cc1a1d6 authored by Andrii Kulian's avatar Andrii Kulian
Browse files

Fix crash when removing a display with activities

When secondary display is removed current behavior is to
move its stacks to the primary display. This requires app
windows to be reparented, and there was a check missing
for app windows in DisplayContent.reParentWindowToken.

Test: bit FrameworksServicesTests:com.android.server.wm.DisplayContentTests
Test: #testMoveStackBetweenDisplays
Bug: 33677605
Change-Id: I2ac2cdba273134438c63385887a09c37d42017bb
parent d276563b
Loading
Loading
Loading
Loading
+5 −13
Original line number Diff line number Diff line
@@ -712,19 +712,11 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
        if (prevDc == this) {
            return;
        }
        if (prevDc != null && prevDc.mTokenMap.remove(token.token) != null) {
            switch (token.windowType) {
                case TYPE_WALLPAPER:
                    prevDc.mBelowAppWindowsContainers.removeChild(token);
                    break;
                case TYPE_INPUT_METHOD:
                case TYPE_INPUT_METHOD_DIALOG:
                    prevDc.mImeWindowsContainers.removeChild(token);
                    break;
                default:
                    prevDc.mAboveAppWindowsContainers.removeChild(token);
                    break;
            }
        if (prevDc != null && prevDc.mTokenMap.remove(token.token) != null
                && token.asAppWindowToken() == null) {
            // Removed the token from the map, but made sure it's not an app token before removing
            // from parent.
            token.getParent().removeChild(token);
        }

        addWindowToken(token.token, token);
+35 −0
Original line number Diff line number Diff line
@@ -19,12 +19,16 @@ package com.android.server.wm;
import org.junit.Test;
import org.junit.runner.RunWith;

import android.hardware.display.DisplayManagerGlobal;
import android.platform.test.annotations.Presubmit;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
import android.view.Display;
import android.view.DisplayInfo;

import java.util.ArrayList;

import static android.view.DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS;
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION;
import static org.junit.Assert.assertEquals;
@@ -203,4 +207,35 @@ public class DisplayContentTests extends WindowTestsBase {

        voiceInteractionWindow.removeImmediately();
    }

    @Test
    public void testMoveStackBetweenDisplays() throws Exception {
        // Create second display.
        final Display display = new Display(DisplayManagerGlobal.getInstance(),
                sDisplayContent.getDisplayId() + 1, new DisplayInfo(),
                DEFAULT_DISPLAY_ADJUSTMENTS);
        final DisplayContent dc = new DisplayContent(display, sWm, sLayersController,
                new WallpaperController(sWm));
        sWm.mRoot.addChild(dc, 1);

        // Add stack with activity.
        final TaskStack stack = createTaskStackOnDisplay(dc);
        assertEquals(dc.getDisplayId(), stack.getDisplayContent().getDisplayId());
        assertEquals(dc, stack.getParent().getParent());
        assertEquals(dc, stack.getDisplayContent());

        final Task task = createTaskInStack(stack, 0 /* userId */);
        final TestAppWindowToken token = new TestAppWindowToken(dc);
        task.addChild(token, 0);
        assertEquals(dc, task.getDisplayContent());
        assertEquals(dc, token.getDisplayContent());

        // Move stack to first display.
        sWm.moveStackToDisplay(stack.mStackId, sDisplayContent.getDisplayId());
        assertEquals(sDisplayContent.getDisplayId(), stack.getDisplayContent().getDisplayId());
        assertEquals(sDisplayContent, stack.getParent().getParent());
        assertEquals(sDisplayContent, stack.getDisplayContent());
        assertEquals(sDisplayContent, task.getDisplayContent());
        assertEquals(sDisplayContent, token.getDisplayContent());
    }
}