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
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user