From 542af13cf51d3d814f2a813204e8d424ae45a28f Mon Sep 17 00:00:00 2001 From: Louis Chang Date: Tue, 31 Aug 2021 11:04:38 +0800 Subject: [PATCH] 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 --- core/api/test-current.txt | 1 + .../java/android/window/TaskFragmentInfo.java | 22 +++++++++++-------- .../extensions/organizer/SplitContainer.java | 10 ++++++++- .../organizer/TaskFragmentContainer.java | 8 +++++++ .../com/android/server/wm/TaskFragment.java | 8 ++++++- 5 files changed, 38 insertions(+), 11 deletions(-) diff --git a/core/api/test-current.txt b/core/api/test-current.txt index 0732c61364016..becdd92b5ff6b 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -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(); diff --git a/core/java/android/window/TaskFragmentInfo.java b/core/java/android/window/TaskFragmentInfo.java index dac420b6190df..b55372b08b3af 100644 --- a/core/java/android/window/TaskFragmentInfo.java +++ b/core/java/android/window/TaskFragmentInfo.java @@ -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 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 + "}"; diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/organizer/SplitContainer.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/organizer/SplitContainer.java index 4fd2126dfa27d..a41557d41e30f 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/organizer/SplitContainer.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/organizer/SplitContainer.java @@ -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); diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/organizer/TaskFragmentContainer.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/organizer/TaskFragmentContainer.java index a4f5c75276f5e..a9155cf152fe8 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/organizer/TaskFragmentContainer.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/organizer/TaskFragmentContainer.java @@ -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; diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java index 242693b758fb2..bd59f6b2174e2 100644 --- a/services/core/java/com/android/server/wm/TaskFragment.java +++ b/services/core/java/com/android/server/wm/TaskFragment.java @@ -2078,12 +2078,18 @@ class TaskFragment extends 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);