Fix stack reference is not updated if the task is organized

There is an additional stack level for split-screen mode, the child
of the organizer may be the instance referenced by task display area.
So if the child is removed, the stack reference should also be updated.

The corresponding operations of removeChild should be put in the
redirected implementation method, otherwise it will be missed when
propagating the removal to parent, that may cause reusing a detached
task and then crash because it does not have parent and display.

Bug: 154679904
Test: ActivityStackTests#testRemoveOrganizedTask_UpdateStackReference
Change-Id: I9c4032409345c772baa055e32da9eaba9a274b53
This commit is contained in:
Riddle Hsu
2020-04-28 17:07:33 +08:00
parent c65d2c3e06
commit 9adc55fdc6
2 changed files with 24 additions and 5 deletions

View File

@@ -1431,15 +1431,15 @@ class Task extends WindowContainer<WindowContainer> {
@Override
void removeChild(WindowContainer child) {
// A rootable child task that is now being removed from an organized task. Making sure
// the stack references is keep updated.
if (mTaskOrganizer != null && mCreatedByOrganizer && child.asTask() != null) {
getDisplayArea().removeStackReferenceIfNeeded((ActivityStack) child);
}
removeChild(child, "removeChild");
}
void removeChild(WindowContainer r, String reason) {
// A rootable child task that is now being removed from an organized task. Making sure
// the stack references is keep updated.
if (mTaskOrganizer != null && mCreatedByOrganizer && r.asTask() != null) {
getDisplayArea().removeStackReferenceIfNeeded((ActivityStack) r);
}
if (!mChildren.contains(r)) {
Slog.e(TAG, "removeChild: r=" + r + " not found in t=" + this);
return;

View File

@@ -233,6 +233,25 @@ public class ActivityStackTests extends ActivityTestsBase {
assertEquals(homeRoot.getParent(), secondaryTask.getParent());
}
@Test
public void testRemoveOrganizedTask_UpdateStackReference() {
final ActivityStack rootHomeTask = mDefaultTaskDisplayArea.getRootHomeTask();
final ActivityRecord homeActivity = new ActivityBuilder(mService)
.setStack(rootHomeTask)
.setCreateTask(true)
.build();
final ActivityStack secondaryStack = (ActivityStack) WindowContainer.fromBinder(
mService.mTaskOrganizerController.createRootTask(rootHomeTask.getDisplayId(),
WINDOWING_MODE_SPLIT_SCREEN_SECONDARY).token.asBinder());
rootHomeTask.reparent(secondaryStack, POSITION_TOP);
assertEquals(secondaryStack, rootHomeTask.getParent());
// This should call to {@link TaskDisplayArea#removeStackReferenceIfNeeded}.
homeActivity.removeImmediately();
assertNull(mDefaultTaskDisplayArea.getRootHomeTask());
}
@Test
public void testStackInheritsDisplayWindowingMode() {
final ActivityStack primarySplitScreen = mDefaultTaskDisplayArea.createStack(