Delete dependent TaskFragments in the same transaction

When finishing the last activity in a container that has dependent
containers, make sure to delete those in addition to just finishing
activities. This will ensure that containers with activities from
different apps will be properly cleaned up.

Bug: 195108809
Test: Launch a container to side with 'finishSecondaryWithPrimary'
configuration, finish the primary container with swipe from side.
Test: Do the above for activities in different apps.

Change-Id: I746055fd02894d8221cace10d556992e2dba31b5
This commit is contained in:
Andrii Kulian
2021-08-03 14:29:35 -07:00
parent 10f3936af2
commit e82c67504d
3 changed files with 22 additions and 17 deletions

View File

@@ -128,7 +128,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
// Check if there are no running activities - consider the container empty if there are no
// non-finishing activities left.
if (!taskFragmentInfo.hasRunningActivity()) {
cleanupContainer(container, true /* shouldFinishDependent */);
mPresenter.cleanupContainer(container, true /* shouldFinishDependent */);
updateCallbackIfNecessary();
}
}
@@ -140,7 +140,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
return;
}
cleanupContainer(container, true /* shouldFinishDependent */);
mPresenter.cleanupContainer(container, true /* shouldFinishDependent */);
updateCallbackIfNecessary();
}
@@ -307,13 +307,10 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
mSplitContainers.add(splitContainer);
}
void cleanupContainer(@NonNull TaskFragmentContainer container, boolean shouldFinishDependent) {
if (container.isFinished()) {
return;
}
container.finish(shouldFinishDependent);
/**
* Removes the container from bookkeeping records.
*/
void removeContainer(@NonNull TaskFragmentContainer container) {
// Remove all split containers that included this one
mContainers.remove(container);
List<SplitContainer> containersToRemove = new ArrayList<>();
@@ -324,8 +321,6 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
}
}
mSplitContainers.removeAll(containersToRemove);
mPresenter.deleteContainer(container);
}
/**
@@ -462,7 +457,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
return false;
}
cleanupContainer(splitContainer.getSecondaryContainer(),
mPresenter.cleanupContainer(splitContainer.getSecondaryContainer(),
false /* shouldFinishDependent */);
return true;
}

View File

@@ -68,11 +68,13 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
}
/**
* Deletes the provided container and updates the presentation if necessary.
* Deletes the specified container and all other associated and dependent containers in the same
* transaction.
*/
void deleteContainer(TaskFragmentContainer container) {
void cleanupContainer(@NonNull TaskFragmentContainer container, boolean shouldFinishDependent) {
final WindowContainerTransaction wct = new WindowContainerTransaction();
deleteTaskFragment(wct, container.getTaskFragmentToken());
container.finish(shouldFinishDependent, this, wct, mController);
final TaskFragmentContainer newTopContainer = mController.getTopActiveContainer();
if (newTopContainer != null) {

View File

@@ -24,6 +24,7 @@ import android.graphics.Rect;
import android.os.Binder;
import android.os.IBinder;
import android.window.TaskFragmentInfo;
import android.window.WindowContainerTransaction;
import java.util.ArrayList;
import java.util.List;
@@ -179,7 +180,8 @@ class TaskFragmentContainer {
* Removes all activities that belong to this process and finishes other containers/activities
* configured to finish together.
*/
void finish(boolean shouldFinishDependent) {
void finish(boolean shouldFinishDependent, @NonNull SplitPresenter presenter,
@NonNull WindowContainerTransaction wct, @NonNull SplitController controller) {
if (mIsFinished) {
return;
}
@@ -190,13 +192,19 @@ class TaskFragmentContainer {
activity.finish();
}
// Cleanup the visuals
presenter.deleteTaskFragment(wct, getTaskFragmentToken());
// Cleanup the records
controller.removeContainer(this);
if (!shouldFinishDependent) {
return;
}
// Finish dependent containers
for (TaskFragmentContainer container : mContainersToFinishOnExit) {
container.finish(true /* shouldFinishDependent */);
container.finish(true /* shouldFinishDependent */, presenter,
wct, controller);
}
mContainersToFinishOnExit.clear();