Finish the primary container while secondary exited

When finishing a placeholder activity, the secondary container was
clean up, and the primary activity was also finished. However, the
primary container didn't remove and therefore was expanded to
fullscreen before the activity within completely being removed.

Which resulted in TRANSIT_OLD_TASK_FRAGMENT_CHANGE transition
after commit 118428b merged.

Bug: 198228078
Test: finishing placeholder activity and back to launcher
Change-Id: I3d55f0be8c7f6ab3970450d7b90dd95f3cfdd463
This commit is contained in:
Louis Chang
2021-08-31 11:04:38 +08:00
parent 61babbcfb5
commit 542af13cf5
5 changed files with 38 additions and 11 deletions

View File

@@ -3229,6 +3229,7 @@ package android.window {
method @NonNull public android.content.res.Configuration getConfiguration();
method @NonNull public android.os.IBinder getFragmentToken();
method @NonNull public android.graphics.Point getPositionInParent();
method public int getRunningActivityCount();
method @NonNull public android.window.WindowContainerToken getToken();
method public int getWindowingMode();
method public boolean hasRunningActivity();

View File

@@ -55,8 +55,8 @@ public final class TaskFragmentInfo implements Parcelable {
/** Whether the TaskFragment contains any child Window Container. */
private final boolean mIsEmpty;
/** Whether the TaskFragment contains any running Activity. */
private final boolean mHasRunningActivity;
/** The number of the running activities in the TaskFragment. */
private final int mRunningActivityCount;
/** Whether this TaskFragment is visible on the window hierarchy. */
private final boolean mIsVisible;
@@ -74,13 +74,13 @@ public final class TaskFragmentInfo implements Parcelable {
/** @hide */
public TaskFragmentInfo(
@NonNull IBinder fragmentToken, @NonNull WindowContainerToken token,
@NonNull Configuration configuration, boolean isEmpty, boolean hasRunningActivity,
@NonNull Configuration configuration, boolean isEmpty, int runningActivityCount,
boolean isVisible, @NonNull List<IBinder> activities, @NonNull Point positionInParent) {
mFragmentToken = requireNonNull(fragmentToken);
mToken = requireNonNull(token);
mConfiguration.setTo(configuration);
mIsEmpty = isEmpty;
mHasRunningActivity = hasRunningActivity;
mRunningActivityCount = runningActivityCount;
mIsVisible = isVisible;
mActivities.addAll(activities);
mPositionInParent = requireNonNull(positionInParent);
@@ -106,7 +106,11 @@ public final class TaskFragmentInfo implements Parcelable {
}
public boolean hasRunningActivity() {
return mHasRunningActivity;
return mRunningActivityCount > 0;
}
public int getRunningActivityCount() {
return mRunningActivityCount;
}
public boolean isVisible() {
@@ -141,7 +145,7 @@ public final class TaskFragmentInfo implements Parcelable {
return mFragmentToken.equals(that.mFragmentToken)
&& mToken.equals(that.mToken)
&& mIsEmpty == that.mIsEmpty
&& mHasRunningActivity == that.mHasRunningActivity
&& mRunningActivityCount == that.mRunningActivityCount
&& mIsVisible == that.mIsVisible
&& getWindowingMode() == that.getWindowingMode()
&& mActivities.equals(that.mActivities)
@@ -153,7 +157,7 @@ public final class TaskFragmentInfo implements Parcelable {
mToken = in.readTypedObject(WindowContainerToken.CREATOR);
mConfiguration.readFromParcel(in);
mIsEmpty = in.readBoolean();
mHasRunningActivity = in.readBoolean();
mRunningActivityCount = in.readInt();
mIsVisible = in.readBoolean();
in.readBinderList(mActivities);
mPositionInParent = requireNonNull(in.readTypedObject(Point.CREATOR));
@@ -166,7 +170,7 @@ public final class TaskFragmentInfo implements Parcelable {
dest.writeTypedObject(mToken, flags);
mConfiguration.writeToParcel(dest, flags);
dest.writeBoolean(mIsEmpty);
dest.writeBoolean(mHasRunningActivity);
dest.writeInt(mRunningActivityCount);
dest.writeBoolean(mIsVisible);
dest.writeBinderList(mActivities);
dest.writeTypedObject(mPositionInParent, flags);
@@ -192,7 +196,7 @@ public final class TaskFragmentInfo implements Parcelable {
+ " fragmentToken=" + mFragmentToken
+ " token=" + mToken
+ " isEmpty=" + mIsEmpty
+ " hasRunningActivity=" + mHasRunningActivity
+ " runningActivityCount=" + mRunningActivityCount
+ " isVisible=" + mIsVisible
+ " positionInParent=" + mPositionInParent
+ "}";

View File

@@ -40,7 +40,15 @@ class SplitContainer {
mSplitRule = splitRule;
if (shouldFinishPrimaryWithSecondary(splitRule)) {
mSecondaryContainer.addActivityToFinishOnExit(primaryActivity);
if (mPrimaryContainer.getRunningActivityCount() == 1
&& mPrimaryContainer.hasActivity(primaryActivity.getActivityToken())) {
mSecondaryContainer.addContainerToFinishOnExit(mPrimaryContainer);
} else {
// Only adding the activity to be finished vs. the entire TaskFragment while
// the secondary container exits because there are other unrelated activities in the
// primary TaskFragment.
mSecondaryContainer.addActivityToFinishOnExit(primaryActivity);
}
}
if (shouldFinishSecondaryWithPrimary(splitRule)) {
mPrimaryContainer.addContainerToFinishOnExit(mSecondaryContainer);

View File

@@ -125,6 +125,14 @@ class TaskFragmentContainer {
return false;
}
int getRunningActivityCount() {
int count = mPendingAppearedActivities.size();
if (mInfo != null) {
count += mInfo.getRunningActivityCount();
}
return count;
}
@Nullable
TaskFragmentInfo getInfo() {
return mInfo;

View File

@@ -2078,12 +2078,18 @@ class TaskFragment extends WindowContainer<WindowContainer> {
}
final Point positionInParent = new Point();
getRelativePosition(positionInParent);
final int[] runningActivityCount = new int[1];
forAllActivities(a -> {
if (!a.finishing) {
runningActivityCount[0]++;
}
});
return new TaskFragmentInfo(
mFragmentToken,
mRemoteToken.toWindowContainerToken(),
getConfiguration(),
getChildCount() == 0,
hasRunningActivity(this),
runningActivityCount[0],
isVisible(),
childActivities,
positionInParent);