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

Commit 40314fe5 authored by Winson Chung's avatar Winson Chung
Browse files

Skip evicting children that are opening when entering split

- When launching a trampoline activity into split, the trampolining can
  result in the launch of the next activity in the same transition as
  the launch transition (but in an incorrect order), which can result
  in the wrong child being retained (the original activity which will
  end up being closed).  Instead, track all the opening tasks in the
  enter transition (not just the top most), and only evict the other
  tasks but those

Bug: 385674612
Flag: EXEMPT bugfix
Test: Manual, launch trampoline activity into split, quickswitch
      split again with same trampoline activity (repeat multiple times)
Change-Id: Id08cceef94b109cc6bc43add263bbe2ccc5148fc
parent 29967216
Loading
Loading
Loading
Loading
+22 −11
Original line number Diff line number Diff line
@@ -3756,6 +3756,9 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
        // First, verify that we actually have opened apps in both splits.
        TransitionInfo.Change mainChild = null;
        TransitionInfo.Change sideChild = null;
        // Tracks the set of opening tasks in the transition
        final Set<Integer> openingMainTaskIds = new HashSet<>();
        final Set<Integer> openingSideTaskIds = new HashSet<>();
        StageTaskListener firstAppStage = null;
        StageTaskListener secondAppStage = null;
        boolean foundPausingTask = false;
@@ -3770,21 +3773,30 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
            }
            StageTaskListener stage = getStageOfTask(taskInfo);
            final @StageType int stageType = getStageType(stage);
            if (mainChild == null
                    && stageType == (enableFlexibleSplit() ? STAGE_TYPE_A : STAGE_TYPE_MAIN)
                    && (isOpeningType(change.getMode()) || change.getMode() == TRANSIT_CHANGE)) {
            final boolean isMainStage = stageType
                    == (enableFlexibleSplit() ? STAGE_TYPE_A : STAGE_TYPE_MAIN);
            final boolean isSideStage = stageType
                    == (enableFlexibleSplit() ? STAGE_TYPE_B : STAGE_TYPE_SIDE);
            final boolean isVisibleTask = isOpeningType(change.getMode())
                    || change.getMode() == TRANSIT_CHANGE;
            if (mainChild == null && isMainStage && isVisibleTask) {
                // Includes TRANSIT_CHANGE to cover reparenting top-most task to split.
                mainChild = change;
                firstAppStage = getStageOfTask(taskInfo);
            } else if (sideChild == null
                    && stageType == (enableFlexibleSplit() ? STAGE_TYPE_B : STAGE_TYPE_SIDE)
                    && (isOpeningType(change.getMode()) || change.getMode() == TRANSIT_CHANGE)) {
            } else if (sideChild == null && isSideStage && isVisibleTask) {
                sideChild = change;
                secondAppStage = stage;
            } else if (stageType != STAGE_TYPE_UNDEFINED && change.getMode() == TRANSIT_TO_BACK) {
                // Collect all to back task's and evict them when transition finished.
                evictWct.reparent(taskInfo.token, null /* parent */, false /* onTop */);
            }
            if (isVisibleTask) {
                if (isMainStage) {
                    openingMainTaskIds.add(taskInfo.taskId);
                } else if (isSideStage) {
                    openingSideTaskIds.add(taskInfo.taskId);
                }
            }
        }

        SplitScreenTransitions.EnterSession pendingEnter = mSplitTransitions.mPendingEnter;
@@ -3860,16 +3872,14 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
            }
            if (finalMainChild != null) {
                if (!mainNotContainOpenTask) {
                    finalFirstAppStage.evictOtherChildren(callbackWct,
                            finalMainChild.getTaskInfo().taskId);
                    finalFirstAppStage.evictOtherChildren(callbackWct, openingMainTaskIds);
                } else {
                    finalFirstAppStage.evictInvisibleChildren(callbackWct);
                }
            }
            if (finalSideChild != null) {
                if (!sideNotContainOpenTask) {
                    finalSecondAppStage.evictOtherChildren(callbackWct,
                            finalSideChild.getTaskInfo().taskId);
                    finalSecondAppStage.evictOtherChildren(callbackWct, openingSideTaskIds);
                } else {
                    finalSecondAppStage.evictInvisibleChildren(callbackWct);
                }
@@ -3971,7 +3981,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
        }

        boolean replacingMainStage = getMainStagePosition() == mSplitRequest.mActivatePosition;
        (replacingMainStage ? mMainStage : mSideStage).evictOtherChildren(wct, taskInfo.taskId);
        (replacingMainStage ? mMainStage : mSideStage).evictOtherChildren(wct,
                Set.of(taskInfo.taskId));
    }

    boolean isLaunchToSplit(TaskInfo taskInfo) {
+4 −3
Original line number Diff line number Diff line
@@ -60,6 +60,7 @@ import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.stream.Collectors;
@@ -432,11 +433,11 @@ public class StageTaskListener implements ShellTaskOrganizer.TaskListener {
        }
    }

    void evictOtherChildren(WindowContainerTransaction wct, int taskId) {
    void evictOtherChildren(WindowContainerTransaction wct, Set<Integer> keepTaskIds) {
        for (int i = mChildrenTaskInfo.size() - 1; i >= 0; i--) {
            final ActivityManager.RunningTaskInfo taskInfo = mChildrenTaskInfo.valueAt(i);
            if (taskId == taskInfo.taskId) continue;
            evictChild(wct, taskInfo, "other");
            if (keepTaskIds.contains(taskInfo.taskId)) continue;
            evictChild(wct, taskInfo, "other_" + stageTypeToString(mId));
        }
    }