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
This commit is contained in:
Louis Chang
2021-08-26 11:32:04 +08:00
parent 506fa0bebd
commit c5024fc2b4
5 changed files with 39 additions and 4 deletions

View File

@@ -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;
}

View File

@@ -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
+ "}";
}

View File

@@ -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();
}
}

View File

@@ -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) {

View File

@@ -173,6 +173,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