diff --git a/core/api/test-current.txt b/core/api/test-current.txt index becdd92b5ff6b..f7164cf3761e7 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -3234,6 +3234,7 @@ package android.window { method public int getWindowingMode(); method public boolean hasRunningActivity(); method public boolean isEmpty(); + method public boolean isTaskClearedForReuse(); method public boolean isVisible(); field @NonNull public static final android.os.Parcelable.Creator CREATOR; } diff --git a/core/java/android/window/TaskFragmentInfo.java b/core/java/android/window/TaskFragmentInfo.java index b55372b08b3af..165dcdf3a8368 100644 --- a/core/java/android/window/TaskFragmentInfo.java +++ b/core/java/android/window/TaskFragmentInfo.java @@ -71,11 +71,18 @@ public final class TaskFragmentInfo implements Parcelable { /** Relative position of the fragment's top left corner in the parent container. */ private final Point mPositionInParent; + /** + * Whether the last running activity in the TaskFragment was finished due to clearing task while + * launching an activity in the host Task. + */ + private final boolean mIsTaskClearedForReuse; + /** @hide */ public TaskFragmentInfo( @NonNull IBinder fragmentToken, @NonNull WindowContainerToken token, @NonNull Configuration configuration, boolean isEmpty, int runningActivityCount, - boolean isVisible, @NonNull List activities, @NonNull Point positionInParent) { + boolean isVisible, @NonNull List activities, @NonNull Point positionInParent, + boolean isTaskClearedForReuse) { mFragmentToken = requireNonNull(fragmentToken); mToken = requireNonNull(token); mConfiguration.setTo(configuration); @@ -84,6 +91,7 @@ public final class TaskFragmentInfo implements Parcelable { mIsVisible = isVisible; mActivities.addAll(activities); mPositionInParent = requireNonNull(positionInParent); + mIsTaskClearedForReuse = isTaskClearedForReuse; } @NonNull @@ -128,6 +136,10 @@ public final class TaskFragmentInfo implements Parcelable { return mPositionInParent; } + public boolean isTaskClearedForReuse() { + return mIsTaskClearedForReuse; + } + @WindowingMode public int getWindowingMode() { return mConfiguration.windowConfiguration.getWindowingMode(); @@ -149,7 +161,8 @@ public final class TaskFragmentInfo implements Parcelable { && mIsVisible == that.mIsVisible && getWindowingMode() == that.getWindowingMode() && mActivities.equals(that.mActivities) - && mPositionInParent.equals(that.mPositionInParent); + && mPositionInParent.equals(that.mPositionInParent) + && mIsTaskClearedForReuse == that.mIsTaskClearedForReuse; } private TaskFragmentInfo(Parcel in) { @@ -161,6 +174,7 @@ public final class TaskFragmentInfo implements Parcelable { mIsVisible = in.readBoolean(); in.readBinderList(mActivities); mPositionInParent = requireNonNull(in.readTypedObject(Point.CREATOR)); + mIsTaskClearedForReuse = in.readBoolean(); } /** @hide */ @@ -174,6 +188,7 @@ public final class TaskFragmentInfo implements Parcelable { dest.writeBoolean(mIsVisible); dest.writeBinderList(mActivities); dest.writeTypedObject(mPositionInParent, flags); + dest.writeBoolean(mIsTaskClearedForReuse); } @NonNull @@ -199,6 +214,7 @@ public final class TaskFragmentInfo implements Parcelable { + " runningActivityCount=" + mRunningActivityCount + " isVisible=" + mIsVisible + " positionInParent=" + mPositionInParent + + " isTaskClearedForReuse=" + mIsTaskClearedForReuse + "}"; } diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/organizer/SplitController.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/organizer/SplitController.java index 12c273af7989b..a783fcde4f52e 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/organizer/SplitController.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/organizer/SplitController.java @@ -134,7 +134,11 @@ 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()) { - mPresenter.cleanupContainer(container, true /* shouldFinishDependent */); + // Do not finish the dependents if this TaskFragment was cleared due to launching + // activity in the Task. + final boolean shouldFinishDependent = + !taskFragmentInfo.isTaskClearedForReuse(); + mPresenter.cleanupContainer(container, shouldFinishDependent); updateCallbackIfNecessary(); } } diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index a493e6019fce4..009794265179b 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -3505,6 +3505,11 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A finishing = true; final TaskFragment taskFragment = getTaskFragment(); if (taskFragment != null) { + final Task task = taskFragment.getTask(); + if (task != null && task.isClearingToReuseTask() + && taskFragment.getTopNonFinishingActivity() == null) { + taskFragment.mClearedTaskForReuse = true; + } taskFragment.sendTaskFragmentInfoChanged(); } if (stopped) { diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java index 7c939e67077ce..ca1d83e2bd15b 100644 --- a/services/core/java/com/android/server/wm/TaskFragment.java +++ b/services/core/java/com/android/server/wm/TaskFragment.java @@ -173,6 +173,12 @@ class TaskFragment extends WindowContainer { */ boolean mTaskFragmentAppearedSent; + /** + * The last running activity of the TaskFragment was finished due to clear task while launching + * an activity in the Task. + */ + boolean mClearedTaskForReuse; + /** * When we are in the process of pausing an activity, before starting the * next one, this variable holds the activity that is currently being paused. @@ -1587,6 +1593,8 @@ class TaskFragment extends WindowContainer { @Override void addChild(WindowContainer child, int index) { + mClearedTaskForReuse = false; + boolean isAddingActivity = child.asActivityRecord() != null; final Task task = isAddingActivity ? getTask() : null; @@ -2093,7 +2101,8 @@ class TaskFragment extends WindowContainer { runningActivityCount[0], isVisible(), childActivities, - positionInParent); + positionInParent, + mClearedTaskForReuse); } @Nullable