diff options
| author | 2021-08-26 11:32:04 +0800 | |
|---|---|---|
| committer | 2021-09-09 15:09:17 +0800 | |
| commit | c5024fc2b453b80db43cf56130f8e01150e343be (patch) | |
| tree | 75c12faf222d64f0444f6f61ee3eb9d7c379d4c4 | |
| parent | 506fa0bebd0e9ee013eaa5b15868a2ea4a379493 (diff) | |
Not removing primary TaskFragment when clear task
Placeholder activity was finished while starting the
task root activity from launcher because the task
root activity was set as singleTask launch mode.
Meanwhile, the primary TaskFragment was also removed
because of the split-rule finishPrimaryWithSecondary.
Sending the information of whether the last activity
on the TaskFragment was finished due to launch other
activity to client. So that the organizer can decide
whether the primary TaskFragment should removed.
Bug: 196179714
Test: relaunch singleTask activity with placeholder
Change-Id: I9a0369285adfbdef1edc5a7f2af944ec5b434566
5 files changed, 39 insertions, 4 deletions
diff --git a/core/api/test-current.txt b/core/api/test-current.txt index becdd92b5ff6..f7164cf3761e 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<android.window.TaskFragmentInfo> CREATOR; } diff --git a/core/java/android/window/TaskFragmentInfo.java b/core/java/android/window/TaskFragmentInfo.java index b55372b08b3a..165dcdf3a836 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<IBinder> activities, @NonNull Point positionInParent) { + boolean isVisible, @NonNull List<IBinder> 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 05c6792a3fc7..756255017d9f 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/organizer/SplitController.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/organizer/SplitController.java @@ -130,7 +130,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 73faca70de6b..d1d33c5846e7 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 7c939e67077c..ca1d83e2bd15 100644 --- a/services/core/java/com/android/server/wm/TaskFragment.java +++ b/services/core/java/com/android/server/wm/TaskFragment.java @@ -174,6 +174,12 @@ class TaskFragment extends WindowContainer<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<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<WindowContainer> { runningActivityCount[0], isVisible(), childActivities, - positionInParent); + positionInParent, + mClearedTaskForReuse); } @Nullable |