summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Charles Chen <charlesccchen@google.com> 2023-11-23 17:09:02 +0800
committer Charles Chen <charlesccchen@google.com> 2023-12-19 16:36:49 +0800
commit219afd3bf97557940a1d038247453083705d00d7 (patch)
treebb1bf4ea5ce351fe8d8d2bbefb126740026a120f
parent9b7b17eedf3dd6e0b401d8c6b9e45b8e423af6cc (diff)
Calculate launched overlay bounds by calculator
Before, we pass Activity to OverlayCreateParams to calculate overlay bounds, but it may lead to memory leak since OverlayCreateParams stores Activity as a property. This CL changes to calculate overlay bounds by ActivityStackAttributesCalculator. When there's an overlay container to be launched, calculator will be triggered, and pass ParentContainerInfo based on launching Activity for the overlay bounds calculation. Bug: 243518738 Test: OverlayPresentationTest Change-Id: I113b6a31e175b0396f490075546449a9205bcb7e
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/OverlayCreateParams.java119
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java96
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java10
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java26
-rw-r--r--libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/OverlayPresentationTest.java120
-rw-r--r--libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java6
6 files changed, 146 insertions, 231 deletions
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/OverlayCreateParams.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/OverlayCreateParams.java
deleted file mode 100644
index ff49cdcab349..000000000000
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/OverlayCreateParams.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.window.extensions.embedding;
-
-import static java.util.Objects.requireNonNull;
-
-import android.graphics.Rect;
-import android.os.Bundle;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-
-/**
- * The parameter to create an overlay container that retrieved from
- * {@link android.app.ActivityOptions} bundle.
- */
-class OverlayCreateParams {
-
- // TODO(b/295803704): Move them to WM Extensions so that we can reuse in WM Jetpack.
- @VisibleForTesting
- static final String KEY_OVERLAY_CREATE_PARAMS =
- "androidx.window.extensions.OverlayCreateParams";
-
- @VisibleForTesting
- static final String KEY_OVERLAY_CREATE_PARAMS_TASK_ID =
- "androidx.window.extensions.OverlayCreateParams.taskId";
-
- @VisibleForTesting
- static final String KEY_OVERLAY_CREATE_PARAMS_TAG =
- "androidx.window.extensions.OverlayCreateParams.tag";
-
- @VisibleForTesting
- static final String KEY_OVERLAY_CREATE_PARAMS_BOUNDS =
- "androidx.window.extensions.OverlayCreateParams.bounds";
-
- private final int mTaskId;
-
- @NonNull
- private final String mTag;
-
- @NonNull
- private final Rect mBounds;
-
- OverlayCreateParams(int taskId, @NonNull String tag, @NonNull Rect bounds) {
- mTaskId = taskId;
- mTag = requireNonNull(tag);
- mBounds = requireNonNull(bounds);
- }
-
- int getTaskId() {
- return mTaskId;
- }
-
- @NonNull
- String getTag() {
- return mTag;
- }
-
- @NonNull
- Rect getBounds() {
- return mBounds;
- }
-
- @Override
- public int hashCode() {
- int result = mTaskId;
- result = 31 * result + mTag.hashCode();
- result = 31 * result + mBounds.hashCode();
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == this) return true;
- if (!(obj instanceof OverlayCreateParams thatParams)) return false;
- return mTaskId == thatParams.mTaskId
- && mTag.equals(thatParams.mTag)
- && mBounds.equals(thatParams.mBounds);
- }
-
- @Override
- public String toString() {
- return OverlayCreateParams.class.getSimpleName() + ": {"
- + "taskId=" + mTaskId
- + ", tag=" + mTag
- + ", bounds=" + mBounds
- + "}";
- }
-
- /** Retrieves the {@link OverlayCreateParams} from {@link android.app.ActivityOptions} bundle */
- @Nullable
- static OverlayCreateParams fromBundle(@NonNull Bundle bundle) {
- final Bundle paramsBundle = bundle.getBundle(KEY_OVERLAY_CREATE_PARAMS);
- if (paramsBundle == null) {
- return null;
- }
- final int taskId = paramsBundle.getInt(KEY_OVERLAY_CREATE_PARAMS_TASK_ID);
- final String tag = requireNonNull(paramsBundle.getString(KEY_OVERLAY_CREATE_PARAMS_TAG));
- final Rect bounds = requireNonNull(paramsBundle.getParcelable(
- KEY_OVERLAY_CREATE_PARAMS_BOUNDS, Rect.class));
-
- return new OverlayCreateParams(taskId, tag, bounds);
- }
-}
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 4973a4d85af7..15ee4e1d4adf 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
@@ -34,6 +34,7 @@ import static android.window.TaskFragmentTransaction.TYPE_TASK_FRAGMENT_INFO_CHA
import static android.window.TaskFragmentTransaction.TYPE_TASK_FRAGMENT_PARENT_INFO_CHANGED;
import static android.window.TaskFragmentTransaction.TYPE_TASK_FRAGMENT_VANISHED;
+import static androidx.window.extensions.embedding.ActivityEmbeddingOptionsProperties.KEY_OVERLAY_TAG;
import static androidx.window.extensions.embedding.SplitContainer.getFinishPrimaryWithSecondaryBehavior;
import static androidx.window.extensions.embedding.SplitContainer.getFinishSecondaryWithPrimaryBehavior;
import static androidx.window.extensions.embedding.SplitContainer.isStickyPlaceholderRule;
@@ -136,6 +137,15 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
private Function<SplitAttributesCalculatorParams, SplitAttributes> mSplitAttributesCalculator;
/**
+ * A calculator function to compute {@link ActivityStack} attributes in a task, which is called
+ * when there's {@link #onTaskFragmentParentInfoChanged} or folding state changed.
+ */
+ @GuardedBy("mLock")
+ @Nullable
+ private Function<ActivityStackAttributesCalculatorParams, ActivityStackAttributes>
+ mActivityStackAttributesCalculator;
+
+ /**
* Map from Task id to {@link TaskContainer} which contains all TaskFragment and split pair info
* below it.
* When the app is host of multiple Tasks, there can be multiple splits controlled by the same
@@ -319,6 +329,22 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
}
}
+ @Override
+ public void setActivityStackAttributesCalculator(
+ @NonNull Function<ActivityStackAttributesCalculatorParams, ActivityStackAttributes>
+ calculator) {
+ synchronized (mLock) {
+ mActivityStackAttributesCalculator = calculator;
+ }
+ }
+
+ @Override
+ public void clearActivityStackAttributesCalculator() {
+ synchronized (mLock) {
+ mActivityStackAttributesCalculator = null;
+ }
+ }
+
@GuardedBy("mLock")
@Nullable
Function<SplitAttributesCalculatorParams, SplitAttributes> getSplitAttributesCalculator() {
@@ -1412,7 +1438,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
@NonNull WindowContainerTransaction wct, @NonNull Intent intent, int taskId,
@Nullable Activity launchingActivity) {
return createEmptyContainer(wct, intent, taskId, new Rect(), launchingActivity,
- null /* overlayTag */);
+ null /* overlayTag */, null /* launchOptions */);
}
/**
@@ -1426,7 +1452,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
TaskFragmentContainer createEmptyContainer(
@NonNull WindowContainerTransaction wct, @NonNull Intent intent, int taskId,
@NonNull Rect bounds, @Nullable Activity launchingActivity,
- @Nullable String overlayTag) {
+ @Nullable String overlayTag, @Nullable Bundle launchOptions) {
// We need an activity in the organizer process in the same Task to use as the owner
// activity, as well as to get the Task window info.
final Activity activityInTask;
@@ -1443,7 +1469,8 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
return null;
}
final TaskFragmentContainer container = newContainer(null /* pendingAppearedActivity */,
- intent, activityInTask, taskId, null /* pairedPrimaryContainer*/, overlayTag);
+ intent, activityInTask, taskId, null /* pairedPrimaryContainer*/, overlayTag,
+ launchOptions);
final IBinder taskFragmentToken = container.getTaskFragmentToken();
// Note that taskContainer will not exist before calling #newContainer if the container
// is the first embedded TF in the task.
@@ -1570,14 +1597,16 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
TaskFragmentContainer newContainer(@NonNull Activity pendingAppearedActivity,
@NonNull Activity activityInTask, int taskId) {
return newContainer(pendingAppearedActivity, null /* pendingAppearedIntent */,
- activityInTask, taskId, null /* pairedPrimaryContainer */, null /* tag */);
+ activityInTask, taskId, null /* pairedPrimaryContainer */, null /* tag */,
+ null /* launchOptions */);
}
@GuardedBy("mLock")
TaskFragmentContainer newContainer(@NonNull Intent pendingAppearedIntent,
@NonNull Activity activityInTask, int taskId) {
return newContainer(null /* pendingAppearedActivity */, pendingAppearedIntent,
- activityInTask, taskId, null /* pairedPrimaryContainer */, null /* tag */);
+ activityInTask, taskId, null /* pairedPrimaryContainer */, null /* tag */,
+ null /* launchOptions */);
}
@GuardedBy("mLock")
@@ -1585,7 +1614,8 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
@NonNull Activity activityInTask, int taskId,
@NonNull TaskFragmentContainer pairedPrimaryContainer) {
return newContainer(null /* pendingAppearedActivity */, pendingAppearedIntent,
- activityInTask, taskId, pairedPrimaryContainer, null /* tag */);
+ activityInTask, taskId, pairedPrimaryContainer, null /* tag */,
+ null /* launchOptions */);
}
/**
@@ -1602,11 +1632,14 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
* @param overlayTag The tag for the new created overlay container. It must be
* needed if {@code isOverlay} is {@code true}. Otherwise,
* it should be {@code null}.
+ * @param launchOptions The launch options bundle to create a container. Must be
+ * specified for overlay container.
*/
@GuardedBy("mLock")
TaskFragmentContainer newContainer(@Nullable Activity pendingAppearedActivity,
@Nullable Intent pendingAppearedIntent, @NonNull Activity activityInTask, int taskId,
- @Nullable TaskFragmentContainer pairedPrimaryContainer, @Nullable String overlayTag) {
+ @Nullable TaskFragmentContainer pairedPrimaryContainer, @Nullable String overlayTag,
+ @Nullable Bundle launchOptions) {
if (activityInTask == null) {
throw new IllegalArgumentException("activityInTask must not be null,");
}
@@ -1615,7 +1648,8 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
}
final TaskContainer taskContainer = mTaskContainers.get(taskId);
final TaskFragmentContainer container = new TaskFragmentContainer(pendingAppearedActivity,
- pendingAppearedIntent, taskContainer, this, pairedPrimaryContainer, overlayTag);
+ pendingAppearedIntent, taskContainer, this, pairedPrimaryContainer, overlayTag,
+ launchOptions);
return container;
}
@@ -2345,28 +2379,28 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
@GuardedBy("mLock")
@Nullable
TaskFragmentContainer createOrUpdateOverlayTaskFragmentIfNeeded(
- @NonNull WindowContainerTransaction wct,
- @NonNull OverlayCreateParams overlayCreateParams, int launchTaskId,
+ @NonNull WindowContainerTransaction wct, @NonNull Bundle options,
@NonNull Intent intent, @NonNull Activity launchActivity) {
- final int taskId = overlayCreateParams.getTaskId();
- if (taskId != launchTaskId) {
- // The task ID doesn't match the launch activity's. Cannot determine the host task
- // to launch the overlay.
- throw new IllegalArgumentException("The task ID of "
- + "OverlayCreateParams#launchingActivity must match the task ID of "
- + "the activity to #startActivity with the activity options that takes "
- + "OverlayCreateParams.");
- }
final List<TaskFragmentContainer> overlayContainers =
getAllOverlayTaskFragmentContainers();
- final String overlayTag = overlayCreateParams.getTag();
+ final String overlayTag = Objects.requireNonNull(options.getString(KEY_OVERLAY_TAG));
// If the requested bounds of OverlayCreateParams are smaller than minimum dimensions
// specified by Intent, expand the overlay container to fill the parent task instead.
- final Rect bounds = overlayCreateParams.getBounds();
- final Size minDimensions = getMinDimensions(intent);
- final boolean shouldExpandContainer = boundsSmallerThanMinDimensions(bounds,
- minDimensions);
+ final ActivityStackAttributesCalculatorParams params =
+ new ActivityStackAttributesCalculatorParams(mPresenter.toParentContainerInfo(
+ mPresenter.getTaskProperties(launchActivity)), overlayTag, options);
+ // Fallback to expand the bounds if there's no activityStackAttributes calculator.
+ final Rect relativeBounds = mActivityStackAttributesCalculator != null
+ ? new Rect(mActivityStackAttributesCalculator.apply(params).getRelativeBounds())
+ : new Rect();
+ final boolean shouldExpandContainer = boundsSmallerThanMinDimensions(relativeBounds,
+ getMinDimensions(intent));
+ // Expand the bounds if the requested bounds are smaller than minimum dimensions.
+ if (shouldExpandContainer) {
+ relativeBounds.setEmpty();
+ }
+ final int taskId = getTaskId(launchActivity);
if (!overlayContainers.isEmpty()) {
for (final TaskFragmentContainer overlayContainer : overlayContainers) {
if (!overlayTag.equals(overlayContainer.getOverlayTag())
@@ -2390,7 +2424,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
final Rect taskBounds = overlayContainer.getTaskContainer().getTaskProperties()
.getTaskMetrics().getBounds();
final IBinder overlayToken = overlayContainer.getTaskFragmentToken();
- final Rect sanitizedBounds = sanitizeBounds(bounds, intent, taskBounds);
+ final Rect sanitizedBounds = sanitizeBounds(relativeBounds, intent, taskBounds);
mPresenter.resizeTaskFragment(wct, overlayToken, sanitizedBounds);
mPresenter.setTaskFragmentIsolatedNavigation(wct, overlayToken,
!sanitizedBounds.isEmpty());
@@ -2402,8 +2436,9 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
}
}
}
- return createEmptyContainer(wct, intent, taskId,
- (shouldExpandContainer ? new Rect() : bounds), launchActivity, overlayTag);
+ // Launch the overlay container to the task with taskId.
+ return createEmptyContainer(wct, intent, taskId, relativeBounds, launchActivity, overlayTag,
+ options);
}
private final class LifecycleCallbacks extends EmptyLifecycleCallbacksAdapter {
@@ -2568,12 +2603,11 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
final TaskFragmentContainer launchedInTaskFragment;
if (launchingActivity != null) {
final int taskId = getTaskId(launchingActivity);
- final OverlayCreateParams overlayCreateParams =
- OverlayCreateParams.fromBundle(options);
+ final String overlayTag = options.getString(KEY_OVERLAY_TAG);
if (Flags.activityEmbeddingOverlayPresentationFlag()
- && overlayCreateParams != null) {
+ && overlayTag != null) {
launchedInTaskFragment = createOrUpdateOverlayTaskFragmentIfNeeded(wct,
- overlayCreateParams, taskId, intent, launchingActivity);
+ options, intent, launchingActivity);
} else {
launchedInTaskFragment = resolveStartActivityIntent(wct, taskId, intent,
launchingActivity);
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java
index b5c32bbe78fa..acfd8e4314bf 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java
@@ -1084,4 +1084,14 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
WindowMetrics getTaskWindowMetrics(@NonNull Activity activity) {
return getTaskProperties(activity).getTaskMetrics();
}
+
+ @NonNull
+ ParentContainerInfo toParentContainerInfo(@NonNull TaskProperties taskProperties) {
+ final Configuration configuration = taskProperties.getConfiguration();
+ final WindowLayoutInfo windowLayoutInfo = mWindowLayoutComponent
+ .getCurrentWindowLayoutInfo(taskProperties.getDisplayId(),
+ configuration.windowConfiguration);
+ return new ParentContainerInfo(taskProperties.getTaskMetrics(), configuration,
+ windowLayoutInfo);
+ }
}
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 ed8c4f31306b..da87339b01a7 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java
@@ -24,6 +24,7 @@ import android.app.WindowConfiguration.WindowingMode;
import android.content.Intent;
import android.graphics.Rect;
import android.os.Binder;
+import android.os.Bundle;
import android.os.IBinder;
import android.util.Size;
import android.window.TaskFragmentAnimationParams;
@@ -105,6 +106,13 @@ class TaskFragmentContainer {
@Nullable
private final String mOverlayTag;
+ /**
+ * The launch options that was used to create this container. Must not be {@code null} for
+ * {@link #isOverlay()} container.
+ */
+ @Nullable
+ private final Bundle mLaunchOptions;
+
/** Indicates whether the container was cleaned up after the last activity was removed. */
private boolean mIsFinished;
@@ -165,7 +173,7 @@ class TaskFragmentContainer {
/**
* @see #TaskFragmentContainer(Activity, Intent, TaskContainer, SplitController,
- * TaskFragmentContainer, String)
+ * TaskFragmentContainer, String, Bundle)
*/
TaskFragmentContainer(@Nullable Activity pendingAppearedActivity,
@Nullable Intent pendingAppearedIntent,
@@ -173,7 +181,8 @@ class TaskFragmentContainer {
@NonNull SplitController controller,
@Nullable TaskFragmentContainer pairedPrimaryContainer) {
this(pendingAppearedActivity, pendingAppearedIntent, taskContainer,
- controller, pairedPrimaryContainer, null /* overlayTag */);
+ controller, pairedPrimaryContainer, null /* overlayTag */,
+ null /* launchOptions */);
}
/**
@@ -181,11 +190,14 @@ class TaskFragmentContainer {
* container transaction.
* @param pairedPrimaryContainer when it is set, the new container will be add right above it
* @param overlayTag Sets to indicate this taskFragment is an overlay container
+ * @param launchOptions The launch options to create this container. Must not be
+ * {@code null} for an overlay container
*/
TaskFragmentContainer(@Nullable Activity pendingAppearedActivity,
@Nullable Intent pendingAppearedIntent, @NonNull TaskContainer taskContainer,
@NonNull SplitController controller,
- @Nullable TaskFragmentContainer pairedPrimaryContainer, @Nullable String overlayTag) {
+ @Nullable TaskFragmentContainer pairedPrimaryContainer, @Nullable String overlayTag,
+ @Nullable Bundle launchOptions) {
if ((pendingAppearedActivity == null && pendingAppearedIntent == null)
|| (pendingAppearedActivity != null && pendingAppearedIntent != null)) {
throw new IllegalArgumentException(
@@ -195,6 +207,10 @@ class TaskFragmentContainer {
mToken = new Binder("TaskFragmentContainer");
mTaskContainer = taskContainer;
mOverlayTag = overlayTag;
+ if (overlayTag != null) {
+ Objects.requireNonNull(launchOptions);
+ }
+ mLaunchOptions = launchOptions;
if (pairedPrimaryContainer != null) {
// The TaskFragment will be positioned right above the paired container.
@@ -903,8 +919,8 @@ class TaskFragmentContainer {
}
/**
- * Returns the tag specified in {@link OverlayCreateParams#getTag()}. {@code null} if this
- * taskFragment container is not an overlay container.
+ * Returns the tag specified in launch options. {@code null} if this taskFragment container is
+ * not an overlay container.
*/
@Nullable
String getOverlayTag() {
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/OverlayPresentationTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/OverlayPresentationTest.java
index 4c2433fab2f8..678bdef3df92 100644
--- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/OverlayPresentationTest.java
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/OverlayPresentationTest.java
@@ -18,14 +18,11 @@ package androidx.window.extensions.embedding;
import static android.view.Display.DEFAULT_DISPLAY;
+import static androidx.window.extensions.embedding.ActivityEmbeddingOptionsProperties.KEY_OVERLAY_TAG;
import static androidx.window.extensions.embedding.EmbeddingTestUtils.TASK_BOUNDS;
import static androidx.window.extensions.embedding.EmbeddingTestUtils.TASK_ID;
import static androidx.window.extensions.embedding.EmbeddingTestUtils.createMockTaskFragmentInfo;
import static androidx.window.extensions.embedding.EmbeddingTestUtils.createSplitPairRuleBuilder;
-import static androidx.window.extensions.embedding.OverlayCreateParams.KEY_OVERLAY_CREATE_PARAMS;
-import static androidx.window.extensions.embedding.OverlayCreateParams.KEY_OVERLAY_CREATE_PARAMS_BOUNDS;
-import static androidx.window.extensions.embedding.OverlayCreateParams.KEY_OVERLAY_CREATE_PARAMS_TAG;
-import static androidx.window.extensions.embedding.OverlayCreateParams.KEY_OVERLAY_CREATE_PARAMS_TASK_ID;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
@@ -45,6 +42,7 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import android.app.Activity;
+import android.app.ActivityOptions;
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.ActivityInfo;
@@ -98,9 +96,6 @@ public class OverlayPresentationTest {
@Rule
public final SetFlagsRule mSetFlagRule = new SetFlagsRule();
- private static final OverlayCreateParams TEST_OVERLAY_CREATE_PARAMS =
- new OverlayCreateParams(TASK_ID, "test,", new Rect(0, 0, 200, 200));
-
private SplitController.ActivityStartMonitor mMonitor;
private Intent mIntent;
@@ -165,37 +160,15 @@ public class OverlayPresentationTest {
}
@Test
- public void testOverlayCreateParamsFromBundle() {
- assertThat(OverlayCreateParams.fromBundle(new Bundle())).isNull();
-
- assertThat(OverlayCreateParams.fromBundle(createOverlayCreateParamsTestBundle()))
- .isEqualTo(TEST_OVERLAY_CREATE_PARAMS);
- }
-
- @Test
public void testStartActivity_overlayFeatureDisabled_notInvokeCreateOverlayContainer() {
mSetFlagRule.disableFlags(Flags.FLAG_ACTIVITY_EMBEDDING_OVERLAY_PRESENTATION_FLAG);
- mMonitor.onStartActivity(mActivity, mIntent, createOverlayCreateParamsTestBundle());
+ final Bundle optionsBundle = ActivityOptions.makeBasic().toBundle();
+ optionsBundle.putString(KEY_OVERLAY_TAG, "test");
+ mMonitor.onStartActivity(mActivity, mIntent, optionsBundle);
verify(mSplitController, never()).createOrUpdateOverlayTaskFragmentIfNeeded(any(), any(),
- anyInt(), any(), any());
- }
-
- @NonNull
- private static Bundle createOverlayCreateParamsTestBundle() {
- final Bundle bundle = new Bundle();
-
- final Bundle paramsBundle = new Bundle();
- paramsBundle.putInt(KEY_OVERLAY_CREATE_PARAMS_TASK_ID,
- TEST_OVERLAY_CREATE_PARAMS.getTaskId());
- paramsBundle.putString(KEY_OVERLAY_CREATE_PARAMS_TAG, TEST_OVERLAY_CREATE_PARAMS.getTag());
- paramsBundle.putObject(KEY_OVERLAY_CREATE_PARAMS_BOUNDS,
- TEST_OVERLAY_CREATE_PARAMS.getBounds());
-
- bundle.putBundle(KEY_OVERLAY_CREATE_PARAMS, paramsBundle);
-
- return bundle;
+ any(), any());
}
@Test
@@ -221,19 +194,11 @@ public class OverlayPresentationTest {
}
@Test
- public void testCreateOrUpdateOverlayTaskFragmentIfNeeded_taskIdNotMatch_throwException() {
- assertThrows("The method must return null due to task mismatch between"
- + " launchingActivity and OverlayCreateParams", IllegalArgumentException.class,
- () -> createOrUpdateOverlayTaskFragmentIfNeeded(
- TEST_OVERLAY_CREATE_PARAMS, TASK_ID + 1));
- }
-
- @Test
public void testCreateOrUpdateOverlayTaskFragmentIfNeeded_anotherTagInTask_dismissOverlay() {
createExistingOverlayContainers();
- final TaskFragmentContainer overlayContainer = createOrUpdateOverlayTaskFragmentIfNeeded(
- new OverlayCreateParams(TASK_ID, "test3", new Rect(0, 0, 100, 100)), TASK_ID);
+ final TaskFragmentContainer overlayContainer =
+ createOrUpdateOverlayTaskFragmentIfNeeded("test3");
assertWithMessage("overlayContainer1 must be dismissed since the new overlay container"
+ " is launched to the same task")
@@ -245,9 +210,9 @@ public class OverlayPresentationTest {
public void testCreateOrUpdateOverlayTaskFragmentIfNeeded_sameTagAnotherTask_dismissOverlay() {
createExistingOverlayContainers();
- final TaskFragmentContainer overlayContainer = createOrUpdateOverlayTaskFragmentIfNeeded(
- new OverlayCreateParams(TASK_ID + 2, "test1", new Rect(0, 0, 100, 100)),
- TASK_ID + 2);
+ doReturn(TASK_ID + 2).when(mActivity).getTaskId();
+ final TaskFragmentContainer overlayContainer =
+ createOrUpdateOverlayTaskFragmentIfNeeded("test1");
assertWithMessage("overlayContainer1 must be dismissed since the new overlay container"
+ " is launched with the same tag as an existing overlay container in a different "
@@ -261,9 +226,10 @@ public class OverlayPresentationTest {
createExistingOverlayContainers();
final Rect bounds = new Rect(0, 0, 100, 100);
+ mSplitController.setActivityStackAttributesCalculator(params ->
+ new ActivityStackAttributes.Builder().setRelativeBounds(bounds).build());
final TaskFragmentContainer overlayContainer = createOrUpdateOverlayTaskFragmentIfNeeded(
- new OverlayCreateParams(TASK_ID, "test1", bounds),
- TASK_ID);
+ "test1");
assertWithMessage("overlayContainer1 must be updated since the new overlay container"
+ " is launched with the same tag and task")
@@ -279,9 +245,8 @@ public class OverlayPresentationTest {
public void testCreateOrUpdateOverlayTaskFragmentIfNeeded_dismissMultipleOverlays() {
createExistingOverlayContainers();
- final TaskFragmentContainer overlayContainer = createOrUpdateOverlayTaskFragmentIfNeeded(
- new OverlayCreateParams(TASK_ID, "test2", new Rect(0, 0, 100, 100)),
- TASK_ID);
+ final TaskFragmentContainer overlayContainer =
+ createOrUpdateOverlayTaskFragmentIfNeeded("test2");
// OverlayContainer1 is dismissed since new container is launched in the same task with
// different tag. OverlayContainer2 is dismissed since new container is launched with the
@@ -304,8 +269,11 @@ public class OverlayPresentationTest {
mIntent.setComponent(new ComponentName(ApplicationProvider.getApplicationContext(),
MinimumDimensionActivity.class));
- final TaskFragmentContainer overlayContainer = createOrUpdateOverlayTaskFragmentIfNeeded(
- TEST_OVERLAY_CREATE_PARAMS, TASK_ID);
+ final Rect bounds = new Rect(0, 0, 100, 100);
+ mSplitController.setActivityStackAttributesCalculator(params ->
+ new ActivityStackAttributes.Builder().setRelativeBounds(bounds).build());
+ final TaskFragmentContainer overlayContainer =
+ createOrUpdateOverlayTaskFragmentIfNeeded("test");
final IBinder overlayToken = overlayContainer.getTaskFragmentToken();
assertThat(mSplitController.getAllOverlayTaskFragmentContainers())
@@ -316,7 +284,7 @@ public class OverlayPresentationTest {
// Call createOrUpdateOverlayTaskFragmentIfNeeded again to check the update case.
clearInvocations(mSplitPresenter);
- createOrUpdateOverlayTaskFragmentIfNeeded(TEST_OVERLAY_CREATE_PARAMS, TASK_ID);
+ createOrUpdateOverlayTaskFragmentIfNeeded("test");
verify(mSplitPresenter).resizeTaskFragment(mTransaction, overlayToken, new Rect());
verify(mSplitPresenter).setTaskFragmentIsolatedNavigation(mTransaction, overlayToken,
@@ -329,11 +297,11 @@ public class OverlayPresentationTest {
public void testCreateOrUpdateOverlayTaskFragmentIfNeeded_notInTaskBounds_expandOverlay() {
final Rect bounds = new Rect(TASK_BOUNDS);
bounds.offset(10, 10);
- final OverlayCreateParams paramsOutsideTaskBounds = new OverlayCreateParams(TASK_ID,
- "test", bounds);
+ mSplitController.setActivityStackAttributesCalculator(params ->
+ new ActivityStackAttributes.Builder().setRelativeBounds(bounds).build());
- final TaskFragmentContainer overlayContainer = createOrUpdateOverlayTaskFragmentIfNeeded(
- paramsOutsideTaskBounds, TASK_ID);
+ final TaskFragmentContainer overlayContainer =
+ createOrUpdateOverlayTaskFragmentIfNeeded("test");
final IBinder overlayToken = overlayContainer.getTaskFragmentToken();
assertThat(mSplitController.getAllOverlayTaskFragmentContainers())
@@ -344,7 +312,7 @@ public class OverlayPresentationTest {
// Call createOrUpdateOverlayTaskFragmentIfNeeded again to check the update case.
clearInvocations(mSplitPresenter);
- createOrUpdateOverlayTaskFragmentIfNeeded(paramsOutsideTaskBounds, TASK_ID);
+ createOrUpdateOverlayTaskFragmentIfNeeded("test");
verify(mSplitPresenter).resizeTaskFragment(mTransaction, overlayToken, new Rect());
verify(mSplitPresenter).setTaskFragmentIsolatedNavigation(mTransaction, overlayToken,
@@ -355,15 +323,17 @@ public class OverlayPresentationTest {
@Test
public void testCreateOrUpdateOverlayTaskFragmentIfNeeded_createOverlay() {
- final TaskFragmentContainer overlayContainer = createOrUpdateOverlayTaskFragmentIfNeeded(
- TEST_OVERLAY_CREATE_PARAMS, TASK_ID);
+ final Rect bounds = new Rect(0, 0, 100, 100);
+ mSplitController.setActivityStackAttributesCalculator(params ->
+ new ActivityStackAttributes.Builder().setRelativeBounds(bounds).build());
+ final TaskFragmentContainer overlayContainer =
+ createOrUpdateOverlayTaskFragmentIfNeeded("test");
assertThat(mSplitController.getAllOverlayTaskFragmentContainers())
.containsExactly(overlayContainer);
assertThat(overlayContainer.getTaskId()).isEqualTo(TASK_ID);
- assertThat(overlayContainer
- .areLastRequestedBoundsEqual(TEST_OVERLAY_CREATE_PARAMS.getBounds())).isTrue();
- assertThat(overlayContainer.getOverlayTag()).isEqualTo(TEST_OVERLAY_CREATE_PARAMS.getTag());
+ assertThat(overlayContainer.areLastRequestedBoundsEqual(bounds)).isTrue();
+ assertThat(overlayContainer.getOverlayTag()).isEqualTo("test");
}
@Test
@@ -416,12 +386,14 @@ public class OverlayPresentationTest {
@Test
public void testGetTopNonFinishingActivityWithOverlay() {
- createTestOverlayContainer(TASK_ID, "test1");
+ TaskFragmentContainer overlayContainer = createTestOverlayContainer(TASK_ID, "test1");
+
final Activity activity = createMockActivity();
final TaskFragmentContainer container = createMockTaskFragmentContainer(activity);
final TaskContainer task = container.getTaskContainer();
- assertThat(task.getTopNonFinishingActivity(true /* includeOverlay */)).isEqualTo(mActivity);
+ assertThat(task.getTopNonFinishingActivity(true /* includeOverlay */))
+ .isEqualTo(overlayContainer.getTopNonFinishingActivity());
assertThat(task.getTopNonFinishingActivity(false /* includeOverlay */)).isEqualTo(activity);
}
@@ -458,10 +430,11 @@ public class OverlayPresentationTest {
* #createOrUpdateOverlayTaskFragmentIfNeeded}
*/
@Nullable
- private TaskFragmentContainer createOrUpdateOverlayTaskFragmentIfNeeded(
- @NonNull OverlayCreateParams params, int taskId) {
- return mSplitController.createOrUpdateOverlayTaskFragmentIfNeeded(mTransaction, params,
- taskId, mIntent, mActivity);
+ private TaskFragmentContainer createOrUpdateOverlayTaskFragmentIfNeeded(@NonNull String tag) {
+ final Bundle launchOptions = new Bundle();
+ launchOptions.putString(KEY_OVERLAY_TAG, tag);
+ return mSplitController.createOrUpdateOverlayTaskFragmentIfNeeded(mTransaction,
+ launchOptions, mIntent, mActivity);
}
/** Creates a mock TaskFragment that has been registered and appeared in the organizer. */
@@ -475,10 +448,11 @@ public class OverlayPresentationTest {
@NonNull
private TaskFragmentContainer createTestOverlayContainer(int taskId, @NonNull String tag) {
+ Activity activity = createMockActivity();
TaskFragmentContainer overlayContainer = mSplitController.newContainer(
- null /* pendingAppearedActivity */, mIntent, mActivity, taskId,
- null /* pairedPrimaryContainer */, tag);
- setupTaskFragmentInfo(overlayContainer, mActivity);
+ null /* pendingAppearedActivity */, mIntent, activity, taskId,
+ null /* pairedPrimaryContainer */, tag, Bundle.EMPTY);
+ setupTaskFragmentInfo(overlayContainer, activity);
return overlayContainer;
}
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java
index 8c274a26177d..bab4e9195880 100644
--- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java
@@ -590,7 +590,7 @@ public class SplitControllerTest {
assertFalse(result);
verify(mSplitController, never()).newContainer(any(), any(), any(), anyInt(), any(),
- anyString());
+ anyString(), any());
}
@Test
@@ -753,7 +753,7 @@ public class SplitControllerTest {
assertTrue(result);
verify(mSplitController, never()).newContainer(any(), any(), any(), anyInt(), any(),
- anyString());
+ anyString(), any());
verify(mSplitController, never()).registerSplit(any(), any(), any(), any(), any(), any());
}
@@ -796,7 +796,7 @@ public class SplitControllerTest {
assertTrue(result);
verify(mSplitController, never()).newContainer(any(), any(), any(), anyInt(), any(),
- anyString());
+ anyString(), any());
verify(mSplitController, never()).registerSplit(any(), any(), any(), any(), any(), any());
}