diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitContainer.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitContainer.java index 1e9fda6599d5a..06918d1e2aa4a 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitContainer.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitContainer.java @@ -84,6 +84,13 @@ class SplitContainer { return shouldFinishSecondaryWithPrimary || isPlaceholderContainer; } + static boolean isStickyPlaceholderRule(@NonNull SplitRule splitRule) { + if (!(splitRule instanceof SplitPlaceholderRule)) { + return false; + } + return ((SplitPlaceholderRule) splitRule).isSticky(); + } + @Override public String toString() { return "SplitContainer{" diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java index 9014102d3f552..45041bc3cc7f0 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java @@ -16,6 +16,8 @@ package androidx.window.extensions.embedding; +import static androidx.window.extensions.embedding.SplitContainer.isStickyPlaceholderRule; + import android.annotation.NonNull; import android.annotation.Nullable; import android.app.Activity; @@ -460,6 +462,11 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen return false; } + if (isStickyPlaceholderRule(splitContainer.getSplitRule())) { + // The placeholder should remain after it was first shown. + return false; + } + if (mPresenter.shouldShowSideBySide(splitContainer)) { return false; } @@ -643,6 +650,46 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen return false; } + /** + * Checks whether the associated container should be destroyed together with a finishing + * container. There is a case when primary containers for placeholders should be retained + * despite the rule configuration to finish primary with secondary - if they are marked as + * 'sticky' and the placeholder was finished when fully overlapping the primary container. + * @return {@code true} if the associated container should be retained (and not be finished). + */ + boolean shouldRetainAssociatedContainer(@NonNull TaskFragmentContainer finishingContainer, + @NonNull TaskFragmentContainer associatedContainer) { + SplitContainer splitContainer = getActiveSplitForContainers(associatedContainer, + finishingContainer); + if (splitContainer == null) { + // Containers are not in the same split, no need to retain. + return false; + } + + if (!isStickyPlaceholderRule(splitContainer.getSplitRule())) { + // Currently only the containers associated with sticky placeholders can be retained. + return false; + } + + // When sticky placeholder is stacked on top of the main container it should not cause the + // destruction of the primary one. + return !mPresenter.shouldShowSideBySide(splitContainer); + } + + /** + * @see #shouldRetainAssociatedContainer(TaskFragmentContainer, TaskFragmentContainer) + */ + boolean shouldRetainAssociatedActivity(@NonNull TaskFragmentContainer finishingContainer, + @NonNull Activity associatedActivity) { + TaskFragmentContainer associatedContainer = getContainerWithActivity( + associatedActivity.getActivityToken()); + if (associatedContainer == null) { + return false; + } + + return shouldRetainAssociatedContainer(finishingContainer, associatedContainer); + } + private final class LifecycleCallbacks implements ActivityLifecycleCallbacks { @Override diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java index 6805fde685b09..a1a53bc937811 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java @@ -228,6 +228,9 @@ class TaskFragmentContainer { // Finish dependent containers for (TaskFragmentContainer container : mContainersToFinishOnExit) { + if (controller.shouldRetainAssociatedContainer(this, container)) { + continue; + } container.finish(true /* shouldFinishDependent */, presenter, wct, controller); } @@ -235,6 +238,9 @@ class TaskFragmentContainer { // Finish associated activities for (Activity activity : mActivitiesToFinishOnExit) { + if (controller.shouldRetainAssociatedActivity(this, activity)) { + continue; + } activity.finish(); } mActivitiesToFinishOnExit.clear(); diff --git a/libs/WindowManager/Jetpack/window-extensions-release.aar b/libs/WindowManager/Jetpack/window-extensions-release.aar index 830d13dd6dc52..b7ccfe541d359 100644 Binary files a/libs/WindowManager/Jetpack/window-extensions-release.aar and b/libs/WindowManager/Jetpack/window-extensions-release.aar differ