summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/view/WindowManager.java17
-rw-r--r--services/core/java/com/android/server/wm/AccessibilityController.java1
-rw-r--r--services/core/java/com/android/server/wm/AppTransition.java23
-rw-r--r--services/core/java/com/android/server/wm/AppTransitionController.java67
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java2
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java10
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java124
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java88
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java8
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/LaunchParamsPersisterTests.java6
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java39
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/RootTaskTests.java6
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java5
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java2
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java2
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java2
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TaskTests.java6
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java106
18 files changed, 445 insertions, 69 deletions
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 9b3550477aaa..329ea4a02145 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -320,6 +320,19 @@ public interface WindowManager extends ViewManager {
int TRANSIT_OLD_TASK_CHANGE_WINDOWING_MODE = 27;
/**
+ * A window in a new task fragment is being opened.
+ * @hide
+ */
+ int TRANSIT_OLD_TASK_FRAGMENT_OPEN = 28;
+
+ /**
+ * A window in the top-most activity of task fragment is being closed to reveal the activity
+ * below.
+ * @hide
+ */
+ int TRANSIT_OLD_TASK_FRAGMENT_CLOSE = 29;
+
+ /**
* @hide
*/
@IntDef(prefix = { "TRANSIT_OLD_" }, value = {
@@ -344,7 +357,9 @@ public interface WindowManager extends ViewManager {
TRANSIT_OLD_TRANSLUCENT_ACTIVITY_OPEN,
TRANSIT_OLD_TRANSLUCENT_ACTIVITY_CLOSE,
TRANSIT_OLD_CRASHING_ACTIVITY_CLOSE,
- TRANSIT_OLD_TASK_CHANGE_WINDOWING_MODE
+ TRANSIT_OLD_TASK_CHANGE_WINDOWING_MODE,
+ TRANSIT_OLD_TASK_FRAGMENT_OPEN,
+ TRANSIT_OLD_TASK_FRAGMENT_CLOSE
})
@Retention(RetentionPolicy.SOURCE)
@interface TransitionOldType {}
diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java
index f1644e9cfa5a..a4d2348d03f1 100644
--- a/services/core/java/com/android/server/wm/AccessibilityController.java
+++ b/services/core/java/com/android/server/wm/AccessibilityController.java
@@ -756,6 +756,7 @@ final class AccessibilityController {
if (magnifying) {
switch (transition) {
case WindowManager.TRANSIT_OLD_ACTIVITY_OPEN:
+ case WindowManager.TRANSIT_OLD_TASK_FRAGMENT_OPEN:
case WindowManager.TRANSIT_OLD_TASK_OPEN:
case WindowManager.TRANSIT_OLD_TASK_TO_FRONT:
case WindowManager.TRANSIT_OLD_WALLPAPER_OPEN:
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index 174b3965f11a..6aea848b12f7 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -40,6 +40,8 @@ import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_UNOCCLUDE;
import static android.view.WindowManager.TRANSIT_OLD_NONE;
import static android.view.WindowManager.TRANSIT_OLD_TASK_CHANGE_WINDOWING_MODE;
import static android.view.WindowManager.TRANSIT_OLD_TASK_CLOSE;
+import static android.view.WindowManager.TRANSIT_OLD_TASK_FRAGMENT_CLOSE;
+import static android.view.WindowManager.TRANSIT_OLD_TASK_FRAGMENT_OPEN;
import static android.view.WindowManager.TRANSIT_OLD_TASK_OPEN;
import static android.view.WindowManager.TRANSIT_OLD_TASK_OPEN_BEHIND;
import static android.view.WindowManager.TRANSIT_OLD_TASK_TO_BACK;
@@ -1005,6 +1007,21 @@ public class AppTransition implements Dump {
animAttr = enter
? WindowAnimation_launchTaskBehindSourceAnimation
: WindowAnimation_launchTaskBehindTargetAnimation;
+ break;
+ // TODO(b/189386466): Use activity transition as the fallback. Investigate if we
+ // need new TaskFragment transition.
+ case TRANSIT_OLD_TASK_FRAGMENT_OPEN:
+ animAttr = enter
+ ? WindowAnimation_activityOpenEnterAnimation
+ : WindowAnimation_activityOpenExitAnimation;
+ break;
+ // TODO(b/189386466): Use activity transition as the fallback. Investigate if we
+ // need new TaskFragment transition.
+ case TRANSIT_OLD_TASK_FRAGMENT_CLOSE:
+ animAttr = enter
+ ? WindowAnimation_activityCloseEnterAnimation
+ : WindowAnimation_activityCloseExitAnimation;
+ break;
}
a = animAttr != 0 ? loadAnimationAttr(lp, animAttr, transit) : null;
ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM,
@@ -1315,6 +1332,12 @@ public class AppTransition implements Dump {
case TRANSIT_OLD_CRASHING_ACTIVITY_CLOSE: {
return "TRANSIT_OLD_CRASHING_ACTIVITY_CLOSE";
}
+ case TRANSIT_OLD_TASK_FRAGMENT_OPEN: {
+ return "TRANSIT_OLD_TASK_FRAGMENT_OPEN";
+ }
+ case TRANSIT_OLD_TASK_FRAGMENT_CLOSE: {
+ return "TRANSIT_OLD_TASK_FRAGMENT_CLOSE";
+ }
default: {
return "<UNKNOWN: " + transition + ">";
}
diff --git a/services/core/java/com/android/server/wm/AppTransitionController.java b/services/core/java/com/android/server/wm/AppTransitionController.java
index d6b0086d8dd9..eeadabde1476 100644
--- a/services/core/java/com/android/server/wm/AppTransitionController.java
+++ b/services/core/java/com/android/server/wm/AppTransitionController.java
@@ -39,6 +39,8 @@ import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_UNOCCLUDE;
import static android.view.WindowManager.TRANSIT_OLD_NONE;
import static android.view.WindowManager.TRANSIT_OLD_TASK_CHANGE_WINDOWING_MODE;
import static android.view.WindowManager.TRANSIT_OLD_TASK_CLOSE;
+import static android.view.WindowManager.TRANSIT_OLD_TASK_FRAGMENT_CLOSE;
+import static android.view.WindowManager.TRANSIT_OLD_TASK_FRAGMENT_OPEN;
import static android.view.WindowManager.TRANSIT_OLD_TASK_OPEN;
import static android.view.WindowManager.TRANSIT_OLD_TASK_OPEN_BEHIND;
import static android.view.WindowManager.TRANSIT_OLD_TASK_TO_BACK;
@@ -68,6 +70,7 @@ import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACT
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
+import android.annotation.IntDef;
import android.annotation.Nullable;
import android.os.Trace;
import android.util.ArrayMap;
@@ -86,6 +89,8 @@ import android.view.animation.Animation;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.protolog.common.ProtoLog;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.function.Predicate;
@@ -102,6 +107,20 @@ public class AppTransitionController {
private RemoteAnimationDefinition mRemoteAnimationDefinition = null;
private static final int KEYGUARD_GOING_AWAY_ANIMATION_DURATION = 400;
+ private static final int TYPE_NONE = 0;
+ private static final int TYPE_ACTIVITY = 1;
+ private static final int TYPE_TASK_FRAGMENT = 2;
+ private static final int TYPE_TASK = 3;
+
+ @IntDef(prefix = { "TYPE_" }, value = {
+ TYPE_NONE,
+ TYPE_ACTIVITY,
+ TYPE_TASK_FRAGMENT,
+ TYPE_TASK
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ @interface TransitContainerType {}
+
private final ArrayMap<WindowContainer, Integer> mTempTransitionReasons = new ArrayMap<>();
AppTransitionController(WindowManagerService service, DisplayContent displayContent) {
@@ -387,33 +406,38 @@ public class AppTransitionController {
openingApps, closingApps, true /* visible */);
final ArraySet<WindowContainer> closingWcs = getAnimationTargets(
openingApps, closingApps, false /* visible */);
- final boolean isActivityOpening = !openingWcs.isEmpty()
- && openingWcs.valueAt(0).asActivityRecord() != null;
- final boolean isActivityClosing = !closingWcs.isEmpty()
- && closingWcs.valueAt(0).asActivityRecord() != null;
- final boolean isTaskOpening = !openingWcs.isEmpty() && !isActivityOpening;
- final boolean isTaskClosing = !closingWcs.isEmpty() && !isActivityClosing;
-
- if (appTransition.containsTransitRequest(TRANSIT_TO_FRONT) && isTaskOpening) {
+ final WindowContainer<?> openingContainer = !openingWcs.isEmpty()
+ ? openingWcs.valueAt(0) : null;
+ final WindowContainer<?> closingContainer = !closingWcs.isEmpty()
+ ? closingWcs.valueAt(0) : null;
+ @TransitContainerType int openingType = getTransitContainerType(openingContainer);
+ @TransitContainerType int closingType = getTransitContainerType(closingContainer);
+ if (appTransition.containsTransitRequest(TRANSIT_TO_FRONT) && openingType == TYPE_TASK) {
return TRANSIT_OLD_TASK_TO_FRONT;
}
- if (appTransition.containsTransitRequest(TRANSIT_TO_BACK) && isTaskClosing) {
+ if (appTransition.containsTransitRequest(TRANSIT_TO_BACK) && closingType == TYPE_TASK) {
return TRANSIT_OLD_TASK_TO_BACK;
}
if (appTransition.containsTransitRequest(TRANSIT_OPEN)) {
- if (isTaskOpening) {
+ if (openingType == TYPE_TASK) {
return (appTransition.getTransitFlags() & TRANSIT_FLAG_OPEN_BEHIND) != 0
? TRANSIT_OLD_TASK_OPEN_BEHIND : TRANSIT_OLD_TASK_OPEN;
}
- if (isActivityOpening) {
+ if (openingType == TYPE_ACTIVITY) {
return TRANSIT_OLD_ACTIVITY_OPEN;
}
+ if (openingType == TYPE_TASK_FRAGMENT) {
+ return TRANSIT_OLD_TASK_FRAGMENT_OPEN;
+ }
}
if (appTransition.containsTransitRequest(TRANSIT_CLOSE)) {
- if (isTaskClosing) {
+ if (closingType == TYPE_TASK) {
return TRANSIT_OLD_TASK_CLOSE;
}
- if (isActivityClosing) {
+ if (closingType == TYPE_TASK_FRAGMENT) {
+ return TRANSIT_OLD_TASK_FRAGMENT_CLOSE;
+ }
+ if (closingType == TYPE_ACTIVITY) {
for (int i = closingApps.size() - 1; i >= 0; i--) {
if (closingApps.valueAt(i).visibleIgnoringKeyguard) {
return TRANSIT_OLD_ACTIVITY_CLOSE;
@@ -430,6 +454,23 @@ public class AppTransitionController {
return TRANSIT_OLD_NONE;
}
+ @TransitContainerType
+ private static int getTransitContainerType(@Nullable WindowContainer<?> container) {
+ if (container == null) {
+ return TYPE_NONE;
+ }
+ if (container.asTask() != null) {
+ return TYPE_TASK;
+ }
+ if (container.asTaskFragment() != null) {
+ return TYPE_TASK_FRAGMENT;
+ }
+ if (container.asActivityRecord() != null) {
+ return TYPE_ACTIVITY;
+ }
+ return TYPE_NONE;
+ }
+
private static WindowManager.LayoutParams getAnimLp(ActivityRecord activity) {
final WindowState mainWindow = activity != null ? activity.findMainWindow() : null;
return mainWindow != null ? mainWindow.mAttrs : null;
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index 9ca09d20cd49..b35f74876eeb 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -218,7 +218,7 @@ public class ActivityRecordTests extends WindowTestsBase {
public void testNoCleanupMovingActivityInSameStack() {
final ActivityRecord activity = createActivityWith2LevelTask();
final Task rootTask = activity.getRootTask();
- final Task newTask = new TaskBuilder(mAtm.mTaskSupervisor).setParentTask(rootTask).build();
+ final Task newTask = createTaskInRootTask(rootTask, 0 /* userId */);
activity.reparent(newTask, 0, null /*reason*/);
verify(rootTask, times(0)).cleanUpActivityReferences(any());
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
index 1b4d0a4ab5a4..3e8a2e9b7b17 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
@@ -478,7 +478,7 @@ public class ActivityStarterTests extends WindowTestsBase {
final ActivityRecord splitSecondActivity =
new ActivityBuilder(mAtm).setCreateTask(true).build();
final ActivityRecord splitPrimaryActivity = new TaskBuilder(mSupervisor)
- .setParentTask(splitOrg.mPrimary)
+ .setParentTaskFragment(splitOrg.mPrimary)
.setCreateActivity(true)
.build()
.getTopMostActivity();
@@ -856,7 +856,7 @@ public class ActivityStarterTests extends WindowTestsBase {
// Create another activity on top of the secondary display.
final Task topStack = secondaryTaskContainer.createRootTask(WINDOWING_MODE_FULLSCREEN,
ACTIVITY_TYPE_STANDARD, true /* onTop */);
- final Task topTask = new TaskBuilder(mSupervisor).setParentTask(topStack).build();
+ final Task topTask = new TaskBuilder(mSupervisor).setParentTaskFragment(topStack).build();
new ActivityBuilder(mAtm).setTask(topTask).build();
doReturn(mActivityMetricsLogger).when(mSupervisor).getActivityMetricsLogger();
@@ -920,7 +920,7 @@ public class ActivityStarterTests extends WindowTestsBase {
DEFAULT_COMPONENT_PACKAGE_NAME + ".SingleTaskActivity");
final Task task = new TaskBuilder(mSupervisor)
.setComponent(componentName)
- .setParentTask(stack)
+ .setParentTaskFragment(stack)
.build();
return new ActivityBuilder(mAtm)
.setComponent(componentName)
@@ -1056,8 +1056,8 @@ public class ActivityStarterTests extends WindowTestsBase {
final ActivityStarter starter = prepareStarter(0 /* flags */);
starter.mStartActivity = new ActivityBuilder(mAtm).build();
final Task task = new TaskBuilder(mAtm.mTaskSupervisor)
- .setParentTask(mAtm.mRootWindowContainer.getDefaultTaskDisplayArea().createRootTask(
- WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */))
+ .setParentTaskFragment(createTask(mDisplayContent, WINDOWING_MODE_FULLSCREEN,
+ ACTIVITY_TYPE_STANDARD))
.setUserId(10)
.build();
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
index 3a6aac9d03d5..11e3fd4e050a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
@@ -375,7 +375,7 @@ public class AppTransitionControllerTest extends WindowTestsBase {
final ArraySet<ActivityRecord> closing = new ArraySet<>();
closing.add(activity3);
- // Promote animation targets to TaskStack level. Invisible ActivityRecords don't affect
+ // Promote animation targets to root Task level. Invisible ActivityRecords don't affect
// promotion decision.
assertEquals(
new ArraySet<>(new WindowContainer[]{activity1.getRootTask()}),
@@ -520,6 +520,128 @@ public class AppTransitionControllerTest extends WindowTestsBase {
opening, closing, false /* visible */));
}
+ @Test
+ public void testGetAnimationTargets_openingClosingTaskFragment() {
+ // [DefaultTDA] - [Task] -+- [TaskFragment1] - [ActivityRecord1] (opening, invisible)
+ // +- [TaskFragment2] - [ActivityRecord2] (closing, visible)
+ final Task parentTask = createTask(mDisplayContent);
+ final TaskFragment taskFragment1 = createTaskFragmentWithParentTask(parentTask,
+ false /* createEmbeddedTask */);
+ final ActivityRecord activity1 = taskFragment1.getTopMostActivity();
+ activity1.setVisible(false);
+ activity1.mVisibleRequested = true;
+
+ final TaskFragment taskFragment2 = createTaskFragmentWithParentTask(parentTask,
+ false /* createEmbeddedTask */);
+ final ActivityRecord activity2 = taskFragment2.getTopMostActivity();
+ activity2.setVisible(true);
+ activity2.mVisibleRequested = false;
+
+ final ArraySet<ActivityRecord> opening = new ArraySet<>();
+ opening.add(activity1);
+ final ArraySet<ActivityRecord> closing = new ArraySet<>();
+ closing.add(activity2);
+
+ // Promote animation targets up to TaskFragment level, not beyond.
+ assertEquals(new ArraySet<>(new WindowContainer[]{taskFragment1}),
+ AppTransitionController.getAnimationTargets(
+ opening, closing, true /* visible */));
+ assertEquals(new ArraySet<>(new WindowContainer[]{taskFragment2}),
+ AppTransitionController.getAnimationTargets(
+ opening, closing, false /* visible */));
+ }
+
+ @Test
+ public void testGetAnimationTargets_openingClosingTaskFragmentWithEmbeddedTask() {
+ // [DefaultTDA] - [Task] -+- [TaskFragment1] - [ActivityRecord1] (opening, invisible)
+ // +- [TaskFragment2] - [ActivityRecord2] (closing, visible)
+ final Task parentTask = createTask(mDisplayContent);
+ final TaskFragment taskFragment1 = createTaskFragmentWithParentTask(parentTask,
+ true /* createEmbeddedTask */);
+ final ActivityRecord activity1 = taskFragment1.getTopMostActivity();
+ activity1.setVisible(false);
+ activity1.mVisibleRequested = true;
+
+ final TaskFragment taskFragment2 = createTaskFragmentWithParentTask(parentTask,
+ true /* createEmbeddedTask */);
+ final ActivityRecord activity2 = taskFragment2.getTopMostActivity();
+ activity2.setVisible(true);
+ activity2.mVisibleRequested = false;
+
+ final ArraySet<ActivityRecord> opening = new ArraySet<>();
+ opening.add(activity1);
+ final ArraySet<ActivityRecord> closing = new ArraySet<>();
+ closing.add(activity2);
+
+ // Promote animation targets up to TaskFragment level, not beyond.
+ assertEquals(new ArraySet<>(new WindowContainer[]{taskFragment1}),
+ AppTransitionController.getAnimationTargets(
+ opening, closing, true /* visible */));
+ assertEquals(new ArraySet<>(new WindowContainer[]{taskFragment2}),
+ AppTransitionController.getAnimationTargets(
+ opening, closing, false /* visible */));
+ }
+
+ @Test
+ public void testGetAnimationTargets_openingTheOnlyTaskFragmentInTask() {
+ // [DefaultTDA] -+- [Task1] - [TaskFragment1] - [ActivityRecord1] (opening, invisible)
+ // +- [Task2] - [ActivityRecord2] (closing, visible)
+ final Task task1 = createTask(mDisplayContent);
+ final TaskFragment taskFragment1 = createTaskFragmentWithParentTask(task1,
+ false /* createEmbeddedTask */);
+ final ActivityRecord activity1 = taskFragment1.getTopMostActivity();
+ activity1.setVisible(false);
+ activity1.mVisibleRequested = true;
+
+ final ActivityRecord activity2 = createActivityRecord(mDisplayContent);
+ activity2.setVisible(true);
+ activity2.mVisibleRequested = false;
+
+ final ArraySet<ActivityRecord> opening = new ArraySet<>();
+ opening.add(activity1);
+ final ArraySet<ActivityRecord> closing = new ArraySet<>();
+ closing.add(activity2);
+
+ // Promote animation targets up to leaf Task level because there's only one TaskFragment in
+ // the Task.
+ assertEquals(new ArraySet<>(new WindowContainer[]{task1}),
+ AppTransitionController.getAnimationTargets(
+ opening, closing, true /* visible */));
+ assertEquals(new ArraySet<>(new WindowContainer[]{activity2.getTask()}),
+ AppTransitionController.getAnimationTargets(
+ opening, closing, false /* visible */));
+ }
+
+ @Test
+ public void testGetAnimationTargets_closingTheOnlyTaskFragmentInTask() {
+ // [DefaultTDA] -+- [Task1] - [TaskFragment1] - [ActivityRecord1] (closing, visible)
+ // +- [Task2] - [ActivityRecord2] (opening, invisible)
+ final Task task1 = createTask(mDisplayContent);
+ final TaskFragment taskFragment1 = createTaskFragmentWithParentTask(task1,
+ false /* createEmbeddedTask */);
+ final ActivityRecord activity1 = taskFragment1.getTopMostActivity();
+ activity1.setVisible(true);
+ activity1.mVisibleRequested = false;
+
+ final ActivityRecord activity2 = createActivityRecord(mDisplayContent);
+ activity2.setVisible(false);
+ activity2.mVisibleRequested = true;
+
+ final ArraySet<ActivityRecord> opening = new ArraySet<>();
+ opening.add(activity2);
+ final ArraySet<ActivityRecord> closing = new ArraySet<>();
+ closing.add(activity1);
+
+ // Promote animation targets up to leaf Task level because there's only one TaskFragment in
+ // the Task.
+ assertEquals(new ArraySet<>(new WindowContainer[]{activity2.getTask()}),
+ AppTransitionController.getAnimationTargets(
+ opening, closing, true /* visible */));
+ assertEquals(new ArraySet<>(new WindowContainer[]{task1}),
+ AppTransitionController.getAnimationTargets(
+ opening, closing, false /* visible */));
+ }
+
static class TestRemoteAnimationRunner implements IRemoteAnimationRunner {
@Override
public void onAnimationStart(int transit, RemoteAnimationTarget[] apps,
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java b/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java
index c3279bf05737..67aac13e3734 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java
@@ -23,6 +23,8 @@ import static android.view.WindowManager.TRANSIT_FLAG_APP_CRASHED;
import static android.view.WindowManager.TRANSIT_KEYGUARD_GOING_AWAY;
import static android.view.WindowManager.TRANSIT_OLD_CRASHING_ACTIVITY_CLOSE;
import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_GOING_AWAY;
+import static android.view.WindowManager.TRANSIT_OLD_TASK_FRAGMENT_CLOSE;
+import static android.view.WindowManager.TRANSIT_OLD_TASK_FRAGMENT_OPEN;
import static android.view.WindowManager.TRANSIT_OLD_UNSET;
import static android.view.WindowManager.TRANSIT_OPEN;
@@ -40,6 +42,7 @@ import static org.mockito.ArgumentMatchers.any;
import android.os.IBinder;
import android.os.RemoteException;
import android.platform.test.annotations.Presubmit;
+import android.util.ArraySet;
import android.view.Display;
import android.view.IRemoteAnimationFinishedCallback;
import android.view.IRemoteAnimationRunner;
@@ -147,6 +150,91 @@ public class AppTransitionTests extends WindowTestsBase {
}
@Test
+ public void testTaskFragmentOpeningTransition() {
+ final ActivityRecord activity = createHierarchyForTaskFragmentTest(
+ false /* createEmbeddedTask */);
+ activity.setVisible(false);
+
+ mDisplayContent.prepareAppTransition(TRANSIT_OPEN);
+ mDisplayContent.mOpeningApps.add(activity);
+ assertEquals(TRANSIT_OLD_TASK_FRAGMENT_OPEN,
+ AppTransitionController.getTransitCompatType(mDisplayContent.mAppTransition,
+ mDisplayContent.mOpeningApps, mDisplayContent.mClosingApps,
+ null /* wallpaperTarget */, null /* oldWallpaper */,
+ false /* skipAppTransitionAnimation */));
+ }
+
+ @Test
+ public void testEmbeddedTaskOpeningTransition() {
+ final ActivityRecord activity = createHierarchyForTaskFragmentTest(
+ true /* createEmbeddedTask */);
+ activity.setVisible(false);
+
+ mDisplayContent.prepareAppTransition(TRANSIT_OPEN);
+ mDisplayContent.mOpeningApps.add(activity);
+ assertEquals(TRANSIT_OLD_TASK_FRAGMENT_OPEN,
+ AppTransitionController.getTransitCompatType(mDisplayContent.mAppTransition,
+ mDisplayContent.mOpeningApps, mDisplayContent.mClosingApps,
+ null /* wallpaperTarget */, null /* oldWallpaper */,
+ false /* skipAppTransitionAnimation */));
+ }
+
+ @Test
+ public void testTaskFragmentClosingTransition() {
+ final ActivityRecord activity = createHierarchyForTaskFragmentTest(
+ false /* createEmbeddedTask */);
+ activity.setVisible(true);
+
+ mDisplayContent.prepareAppTransition(TRANSIT_CLOSE);
+ mDisplayContent.mClosingApps.add(activity);
+ assertEquals(TRANSIT_OLD_TASK_FRAGMENT_CLOSE,
+ AppTransitionController.getTransitCompatType(mDisplayContent.mAppTransition,
+ mDisplayContent.mOpeningApps, mDisplayContent.mClosingApps,
+ null /* wallpaperTarget */, null /* oldWallpaper */,
+ false /* skipAppTransitionAnimation */));
+ }
+
+ @Test
+ public void testEmbeddedTaskClosingTransition() {
+ final ActivityRecord activity = createHierarchyForTaskFragmentTest(
+ true /* createEmbeddedTask */);
+ activity.setVisible(true);
+
+ mDisplayContent.prepareAppTransition(TRANSIT_CLOSE);
+ mDisplayContent.mClosingApps.add(activity);
+ assertEquals(TRANSIT_OLD_TASK_FRAGMENT_CLOSE,
+ AppTransitionController.getTransitCompatType(mDisplayContent.mAppTransition,
+ mDisplayContent.mOpeningApps, mDisplayContent.mClosingApps,
+ null /* wallpaperTarget */, null /* oldWallpaper */,
+ false /* skipAppTransitionAnimation */));
+ }
+
+ /**
+ * Creates a {@link Task} with two {@link TaskFragment TaskFragments}.
+ * The bottom TaskFragment is to prevent
+ * {@link AppTransitionController#getAnimationTargets(ArraySet, ArraySet, boolean) the animation
+ * target} to promote to Task or above.
+ *
+ * @param createEmbeddedTask {@code true} to create embedded Task for verified TaskFragment
+ * @return The Activity to be put in either opening or closing Activity
+ */
+ private ActivityRecord createHierarchyForTaskFragmentTest(boolean createEmbeddedTask) {
+ final Task parentTask = createTask(mDisplayContent);
+ final TaskFragment bottomTaskFragment = createTaskFragmentWithParentTask(parentTask,
+ false /* createEmbeddedTask */);
+ final ActivityRecord bottomActivity = bottomTaskFragment.getTopMostActivity();
+ bottomActivity.setOccludesParent(true);
+ bottomActivity.setVisible(true);
+
+ final TaskFragment verifiedTaskFragment = createTaskFragmentWithParentTask(parentTask,
+ createEmbeddedTask);
+ final ActivityRecord activity = verifiedTaskFragment.getTopMostActivity();
+ activity.setOccludesParent(true);
+
+ return activity;
+ }
+
+ @Test
public void testAppTransitionStateForMultiDisplay() {
// Create 2 displays & presume both display the state is ON for ready to display & animate.
final DisplayContent dc1 = createNewDisplay(Display.STATE_ON);
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
index 473d3038e3dc..14dc33e5840b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -2352,10 +2352,10 @@ public class DisplayContentTests extends WindowTestsBase {
ACTIVITY_TYPE_STANDARD, ON_TOP);
final Task rootTask4 = taskDisplayArea.createRootTask(WINDOWING_MODE_FULLSCREEN,
ACTIVITY_TYPE_STANDARD, ON_TOP);
- final Task task1 = new TaskBuilder(mAtm.mTaskSupervisor).setParentTask(rootTask1).build();
- final Task task2 = new TaskBuilder(mAtm.mTaskSupervisor).setParentTask(rootTask2).build();
- final Task task3 = new TaskBuilder(mAtm.mTaskSupervisor).setParentTask(rootTask3).build();
- final Task task4 = new TaskBuilder(mAtm.mTaskSupervisor).setParentTask(rootTask4).build();
+ final Task task1 = new TaskBuilder(mSupervisor).setParentTaskFragment(rootTask1).build();
+ final Task task2 = new TaskBuilder(mSupervisor).setParentTaskFragment(rootTask2).build();
+ final Task task3 = new TaskBuilder(mSupervisor).setParentTaskFragment(rootTask3).build();
+ final Task task4 = new TaskBuilder(mSupervisor).setParentTaskFragment(rootTask4).build();
// Reordering root tasks while removing root tasks.
doAnswer(invocation -> {
diff --git a/services/tests/wmtests/src/com/android/server/wm/LaunchParamsPersisterTests.java b/services/tests/wmtests/src/com/android/server/wm/LaunchParamsPersisterTests.java
index 7cb7c79d63a0..8a6db2c62a10 100644
--- a/services/tests/wmtests/src/com/android/server/wm/LaunchParamsPersisterTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/LaunchParamsPersisterTests.java
@@ -117,7 +117,7 @@ public class LaunchParamsPersisterTests extends WindowTestsBase {
Task rootTask = mTestDisplay.getDefaultTaskDisplayArea()
.createRootTask(TEST_WINDOWING_MODE, ACTIVITY_TYPE_STANDARD, /* onTop */ true);
mTestTask = new TaskBuilder(mSupervisor).setComponent(TEST_COMPONENT)
- .setParentTask(rootTask).build();
+ .setParentTaskFragment(rootTask).build();
mTestTask.mUserId = TEST_USER_ID;
mTestTask.mLastNonFullscreenBounds = TEST_BOUNDS;
mTestTask.setHasBeenVisible(true);
@@ -353,7 +353,7 @@ public class LaunchParamsPersisterTests extends WindowTestsBase {
final Task anotherTaskOfTheSameUser = new TaskBuilder(mSupervisor)
.setComponent(ALTERNATIVE_COMPONENT)
.setUserId(TEST_USER_ID)
- .setParentTask(stack)
+ .setParentTaskFragment(stack)
.build();
anotherTaskOfTheSameUser.setWindowingMode(WINDOWING_MODE_FREEFORM);
anotherTaskOfTheSameUser.setBounds(200, 300, 400, 500);
@@ -365,7 +365,7 @@ public class LaunchParamsPersisterTests extends WindowTestsBase {
final Task anotherTaskOfDifferentUser = new TaskBuilder(mSupervisor)
.setComponent(TEST_COMPONENT)
.setUserId(ALTERNATIVE_USER_ID)
- .setParentTask(stack)
+ .setParentTaskFragment(stack)
.build();
anotherTaskOfDifferentUser.setWindowingMode(WINDOWING_MODE_FREEFORM);
anotherTaskOfDifferentUser.setBounds(300, 400, 500, 600);
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
index 1b078b7454b2..22e687a0bb15 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
@@ -331,7 +331,7 @@ public class RecentTasksTest extends WindowTestsBase {
// other task
Task task1 = createTaskBuilder(".Task1")
.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK)
- .setParentTask(mTaskContainer.getRootHomeTask()).build();
+ .setParentTaskFragment(mTaskContainer.getRootHomeTask()).build();
Task task2 = createTaskBuilder(".Task1")
.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK)
.build();
@@ -471,8 +471,8 @@ public class RecentTasksTest extends WindowTestsBase {
final Task root = createTaskBuilder(".CreatedByOrganizerRoot").build();
root.mCreatedByOrganizer = true;
// Add organized and non-organized child.
- final Task child1 = createTaskBuilder(".Task1").setParentTask(root).build();
- final Task child2 = createTaskBuilder(".Task2").setParentTask(root).build();
+ final Task child1 = createTaskBuilder(".Task1").setParentTaskFragment(root).build();
+ final Task child2 = createTaskBuilder(".Task2").setParentTaskFragment(root).build();
doReturn(true).when(child1).isOrganized();
doReturn(false).when(child2).isOrganized();
mRecentTasks.add(root);
@@ -508,7 +508,8 @@ public class RecentTasksTest extends WindowTestsBase {
// tasks because their intents are identical.
mRecentTasks.add(task1);
// Go home to trigger the removal of untracked tasks.
- mRecentTasks.add(createTaskBuilder(".Home").setParentTask(mTaskContainer.getRootHomeTask())
+ mRecentTasks.add(createTaskBuilder(".Home")
+ .setParentTaskFragment(mTaskContainer.getRootHomeTask())
.build());
triggerIdleToTrim();
@@ -675,7 +676,7 @@ public class RecentTasksTest extends WindowTestsBase {
public void testVisibleTasks_excludedFromRecents_firstTaskNotVisible() {
// Create some set of tasks, some of which are visible and some are not
Task homeTask = createTaskBuilder("com.android.pkg1", ".HomeTask")
- .setParentTask(mTaskContainer.getRootHomeTask())
+ .setParentTaskFragment(mTaskContainer.getRootHomeTask())
.build();
homeTask.mUserSetupComplete = true;
mRecentTasks.add(homeTask);
@@ -696,7 +697,7 @@ public class RecentTasksTest extends WindowTestsBase {
t1.mUserSetupComplete = true;
mRecentTasks.add(t1);
Task homeTask = createTaskBuilder("com.android.pkg1", ".HomeTask")
- .setParentTask(mTaskContainer.getRootHomeTask())
+ .setParentTaskFragment(mTaskContainer.getRootHomeTask())
.build();
homeTask.mUserSetupComplete = true;
mRecentTasks.add(homeTask);
@@ -949,10 +950,10 @@ public class RecentTasksTest extends WindowTestsBase {
// Add a number of tasks (beyond the max) but ensure that nothing is trimmed because all
// the tasks belong in stacks above the home stack
- mRecentTasks.add(createTaskBuilder(".HomeTask1").setParentTask(homeStack).build());
- mRecentTasks.add(createTaskBuilder(".Task1").setParentTask(aboveHomeStack).build());
- mRecentTasks.add(createTaskBuilder(".Task2").setParentTask(aboveHomeStack).build());
- mRecentTasks.add(createTaskBuilder(".Task3").setParentTask(aboveHomeStack).build());
+ mRecentTasks.add(createTaskBuilder(".HomeTask1").setParentTaskFragment(homeStack).build());
+ mRecentTasks.add(createTaskBuilder(".Task1").setParentTaskFragment(aboveHomeStack).build());
+ mRecentTasks.add(createTaskBuilder(".Task2").setParentTaskFragment(aboveHomeStack).build());
+ mRecentTasks.add(createTaskBuilder(".Task3").setParentTaskFragment(aboveHomeStack).build());
triggerTrimAndAssertNoTasksTrimmed();
}
@@ -970,11 +971,11 @@ public class RecentTasksTest extends WindowTestsBase {
// Add a number of tasks (beyond the max) but ensure that only the task in the stack behind
// the home stack is trimmed once a new task is added
final Task behindHomeTask = createTaskBuilder(".Task1")
- .setParentTask(behindHomeStack)
+ .setParentTaskFragment(behindHomeStack)
.build();
mRecentTasks.add(behindHomeTask);
- mRecentTasks.add(createTaskBuilder(".HomeTask1").setParentTask(homeStack).build());
- mRecentTasks.add(createTaskBuilder(".Task2").setParentTask(aboveHomeStack).build());
+ mRecentTasks.add(createTaskBuilder(".HomeTask1").setParentTaskFragment(homeStack).build());
+ mRecentTasks.add(createTaskBuilder(".Task2").setParentTaskFragment(aboveHomeStack).build());
triggerTrimAndAssertTrimmed(behindHomeTask);
}
@@ -990,10 +991,12 @@ public class RecentTasksTest extends WindowTestsBase {
// Add a number of tasks (beyond the max) on each display, ensure that the tasks are not
// removed
- mRecentTasks.add(createTaskBuilder(".HomeTask1").setParentTask(homeTask).build());
- mRecentTasks.add(createTaskBuilder(".Task1").setParentTask(otherDisplayRootTask).build());
- mRecentTasks.add(createTaskBuilder(".Task2").setParentTask(otherDisplayRootTask).build());
- mRecentTasks.add(createTaskBuilder(".HomeTask2").setParentTask(homeTask).build());
+ mRecentTasks.add(createTaskBuilder(".HomeTask1").setParentTaskFragment(homeTask).build());
+ mRecentTasks.add(createTaskBuilder(".Task1").setParentTaskFragment(otherDisplayRootTask)
+ .build());
+ mRecentTasks.add(createTaskBuilder(".Task2").setParentTaskFragment(otherDisplayRootTask)
+ .build());
+ mRecentTasks.add(createTaskBuilder(".HomeTask2").setParentTaskFragment(homeTask).build());
triggerTrimAndAssertNoTasksTrimmed();
}
@@ -1023,7 +1026,7 @@ public class RecentTasksTest extends WindowTestsBase {
Task t1 = createTaskBuilder("com.android.pkg1", ".Task1").build();
mRecentTasks.add(t1);
mRecentTasks.add(createTaskBuilder("com.android.pkg1", ".HomeTask")
- .setParentTask(mTaskContainer.getRootHomeTask()).build());
+ .setParentTaskFragment(mTaskContainer.getRootHomeTask()).build());
Task t2 = createTaskBuilder("com.android.pkg2", ".Task2").build();
mRecentTasks.add(t2);
mRecentTasks.add(createTaskBuilder("com.android.pkg1", ".PipTask")
diff --git a/services/tests/wmtests/src/com/android/server/wm/RootTaskTests.java b/services/tests/wmtests/src/com/android/server/wm/RootTaskTests.java
index 56d01cd34e01..030733bf4424 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RootTaskTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RootTaskTests.java
@@ -329,7 +329,7 @@ public class RootTaskTests extends WindowTestsBase {
// Create primary splitscreen root task.
final Task primarySplitScreen = new TaskBuilder(mAtm.mTaskSupervisor)
- .setParentTask(organizer.mPrimary)
+ .setParentTaskFragment(organizer.mPrimary)
.setOnTop(true)
.build();
@@ -505,8 +505,8 @@ public class RootTaskTests extends WindowTestsBase {
targetActivity);
final ComponentName alias = new ComponentName(DEFAULT_COMPONENT_PACKAGE_NAME,
aliasActivity);
- final Task parentTask = new TaskBuilder(mAtm.mTaskSupervisor).build();
- final Task task = new TaskBuilder(mAtm.mTaskSupervisor).setParentTask(parentTask).build();
+ final Task parentTask = new TaskBuilder(mSupervisor).build();
+ final Task task = new TaskBuilder(mSupervisor).setParentTaskFragment(parentTask).build();
task.origActivity = alias;
task.realActivity = target;
new ActivityBuilder(mAtm).setComponent(target).setTask(task).setTargetActivity(
diff --git a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
index 8d4acbbac993..f2eb709b4bb8 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
@@ -168,7 +168,7 @@ public class RootWindowContainerTests extends WindowTestsBase {
@Test
public void testTaskLayerRank() {
final Task rootTask = new TaskBuilder(mSupervisor).build();
- final Task task1 = new TaskBuilder(mSupervisor).setParentTask(rootTask).build();
+ final Task task1 = new TaskBuilder(mSupervisor).setParentTaskFragment(rootTask).build();
new ActivityBuilder(mAtm).setTask(task1).build().mVisibleRequested = true;
mWm.mRoot.rankTaskLayers();
@@ -523,7 +523,8 @@ public class RootWindowContainerTests extends WindowTestsBase {
final TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
final Task targetRootTask = taskDisplayArea.createRootTask(WINDOWING_MODE_FULLSCREEN,
ACTIVITY_TYPE_STANDARD, false /* onTop */);
- final Task targetTask = new TaskBuilder(mSupervisor).setParentTask(targetRootTask).build();
+ final Task targetTask = new TaskBuilder(mSupervisor).setParentTaskFragment(targetRootTask)
+ .build();
// Create Recents on secondary display.
final TestDisplayContent secondDisplay = addNewDisplayContentAt(
diff --git a/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java
index c44c22fefd7a..cb858845e03e 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java
@@ -166,7 +166,7 @@ public class RunningTasksTest extends WindowTestsBase {
final Task task = new TaskBuilder(mAtm.mTaskSupervisor)
.setComponent(new ComponentName(mContext.getPackageName(), className))
.setTaskId(taskId)
- .setParentTask(stack)
+ .setParentTaskFragment(stack)
.build();
task.lastActiveTime = lastActiveTime;
final ActivityRecord activity = new ActivityBuilder(mAtm)
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java
index c45c18d16c38..d68edbafb592 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java
@@ -620,7 +620,7 @@ public class TaskDisplayAreaTests extends WindowTestsBase {
final Task pinnedRootTask = mRootWindowContainer.getDefaultTaskDisplayArea()
.createRootTask(WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, ON_TOP);
final Task pinnedTask = new TaskBuilder(mAtm.mTaskSupervisor)
- .setParentTask(pinnedRootTask).build();
+ .setParentTaskFragment(pinnedRootTask).build();
new ActivityBuilder(mAtm).setActivityFlags(FLAG_ALWAYS_FOCUSABLE)
.setTask(pinnedTask).build();
pinnedRootTask.moveToFront("movePinnedRootTaskToFront");
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java
index 5e4c67ce9e5c..e528a4a23e45 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java
@@ -1716,7 +1716,7 @@ public class TaskLaunchParamsModifierTests extends WindowTestsBase {
final Task rootTask = display.getDefaultTaskDisplayArea()
.createRootTask(display.getWindowingMode(), ACTIVITY_TYPE_STANDARD, true);
rootTask.setWindowingMode(WINDOWING_MODE_FREEFORM);
- final Task task = new TaskBuilder(mSupervisor).setParentTask(rootTask).build();
+ final Task task = new TaskBuilder(mSupervisor).setParentTaskFragment(rootTask).build();
// Just work around the unnecessary adjustments for bounds.
task.getWindowConfiguration().setBounds(bounds);
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
index 807494429999..67e8c879a3e0 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
@@ -427,7 +427,7 @@ public class TaskTests extends WindowTestsBase {
TaskDisplayArea taskDisplayArea = mAtm.mRootWindowContainer.getDefaultTaskDisplayArea();
Task rootTask = taskDisplayArea.createRootTask(WINDOWING_MODE_FREEFORM,
ACTIVITY_TYPE_STANDARD, true /* onTop */);
- Task task = new TaskBuilder(mSupervisor).setParentTask(rootTask).build();
+ Task task = new TaskBuilder(mSupervisor).setParentTaskFragment(rootTask).build();
final Configuration parentConfig = rootTask.getConfiguration();
parentConfig.windowConfiguration.setBounds(parentBounds);
parentConfig.densityDpi = DisplayMetrics.DENSITY_DEFAULT;
@@ -757,7 +757,7 @@ public class TaskTests extends WindowTestsBase {
DisplayInfo displayInfo = new DisplayInfo();
mAtm.mContext.getDisplay().getDisplayInfo(displayInfo);
final int displayHeight = displayInfo.logicalHeight;
- final Task task = new TaskBuilder(mSupervisor).setParentTask(rootTask).build();
+ final Task task = new TaskBuilder(mSupervisor).setParentTaskFragment(rootTask).build();
final Configuration inOutConfig = new Configuration();
final Configuration parentConfig = new Configuration();
final int longSide = 1200;
@@ -1375,7 +1375,7 @@ public class TaskTests extends WindowTestsBase {
TaskDisplayArea taskDisplayArea = mAtm.mRootWindowContainer.getDefaultTaskDisplayArea();
Task rootTask = taskDisplayArea.createRootTask(windowingMode, ACTIVITY_TYPE_STANDARD,
true /* onTop */);
- Task task = new TaskBuilder(mSupervisor).setParentTask(rootTask).build();
+ Task task = new TaskBuilder(mSupervisor).setParentTaskFragment(rootTask).build();
final Configuration parentConfig = rootTask.getConfiguration();
parentConfig.windowConfiguration.setAppBounds(parentBounds);
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
index 050fd80411fc..e7ef6ae7cc0a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
@@ -56,6 +56,7 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.server.wm.StartingSurfaceController.DEBUG_ENABLE_SHELL_DRAWER;
import static com.android.server.wm.WindowContainer.POSITION_BOTTOM;
+import static com.android.server.wm.WindowContainer.POSITION_TOP;
import static com.android.server.wm.WindowStateAnimator.HAS_DRAWN;
import static org.junit.Assert.assertEquals;
@@ -589,7 +590,7 @@ class WindowTestsBase extends SystemServiceTestsBase {
Task createTaskInRootTask(Task rootTask, int userId) {
final Task task = new TaskBuilder(rootTask.mTaskSupervisor)
.setUserId(userId)
- .setParentTask(rootTask)
+ .setParentTaskFragment(rootTask)
.build();
return task;
}
@@ -675,6 +676,26 @@ class WindowTestsBase extends SystemServiceTestsBase {
activity.mVisibleRequested = true;
}
+ /**
+ * Creates a {@link TaskFragment} and attach it to the {@code parentTask}.
+ *
+ * @param parentTask the {@link Task} this TaskFragment is going to be attached
+ * @param createEmbeddedTask Sets to {@code true} to create an embedded Task for this
+ * TaskFragment. Otherwise, create a {@link ActivityRecord}.
+ * @return the created TaskFragment
+ */
+ static TaskFragment createTaskFragmentWithParentTask(@NonNull Task parentTask,
+ boolean createEmbeddedTask) {
+ final TaskFragmentBuilder builder = new TaskFragmentBuilder(parentTask.mAtmService)
+ .setParentTask(parentTask);
+ if (createEmbeddedTask) {
+ builder.createEmbeddedTask();
+ } else {
+ builder.createActivityCount(1);
+ }
+ return builder.build();
+ }
+
/** Creates a {@link DisplayContent} that supports IME and adds it to the system. */
DisplayContent createNewDisplay() {
return createNewDisplayWithImeSupport(DISPLAY_IME_POLICY_LOCAL);
@@ -1042,7 +1063,7 @@ class WindowTestsBase extends SystemServiceTestsBase {
// Apply the root activity info and intent
.setActivityInfo(aInfo)
.setIntent(intent)
- .setParentTask(mParentTask).build();
+ .setParentTaskFragment(mParentTask).build();
} else if (mTask == null && mParentTask != null && DisplayContent.alwaysCreateRootTask(
mParentTask.getWindowingMode(), mParentTask.getActivityType())) {
// The parent task can be the task root.
@@ -1101,6 +1122,64 @@ class WindowTestsBase extends SystemServiceTestsBase {
}
}
+ static class TaskFragmentBuilder {
+ private final ActivityTaskManagerService mAtm;
+ private Task mParentTask;
+ private boolean mCreateParentTask;
+ private boolean mCreateEmbeddedTask;
+ private int mCreateActivityCount = 0;
+
+ TaskFragmentBuilder(ActivityTaskManagerService service) {
+ mAtm = service;
+ }
+
+ TaskFragmentBuilder setCreateParentTask() {
+ mCreateParentTask = true;
+ return this;
+ }
+
+ TaskFragmentBuilder setParentTask(Task task) {
+ mParentTask = task;
+ return this;
+ }
+
+ /** Creates a child embedded Task and its Activity */
+ TaskFragmentBuilder createEmbeddedTask() {
+ mCreateEmbeddedTask = true;
+ return this;
+ }
+
+ TaskFragmentBuilder createActivityCount(int count) {
+ mCreateActivityCount = count;
+ return this;
+ }
+
+ TaskFragment build() {
+ SystemServicesTestRule.checkHoldsLock(mAtm.mGlobalLock);
+
+ final TaskFragment taskFragment = new TaskFragment(mAtm, null /* fragmentToken */,
+ false /* createdByOrganizer */);
+ if (mParentTask == null && mCreateParentTask) {
+ mParentTask = new TaskBuilder(mAtm.mTaskSupervisor).build();
+ }
+ if (mParentTask != null) {
+ mParentTask.addChild(taskFragment, POSITION_TOP);
+ }
+ if (mCreateEmbeddedTask) {
+ new TaskBuilder(mAtm.mTaskSupervisor)
+ .setParentTaskFragment(taskFragment)
+ .setCreateActivity(true)
+ .build();
+ }
+ while (mCreateActivityCount > 0) {
+ final ActivityRecord activity = new ActivityBuilder(mAtm).build();
+ taskFragment.addChild(activity);
+ mCreateActivityCount--;
+ }
+ return taskFragment;
+ }
+ }
+
/**
* Builder for creating new tasks.
*/
@@ -1121,7 +1200,7 @@ class WindowTestsBase extends SystemServiceTestsBase {
private IVoiceInteractionSession mVoiceSession;
private boolean mCreateParentTask = false;
- private Task mParentTask;
+ private TaskFragment mParentTaskFragment;
private boolean mCreateActivity = false;
@@ -1205,8 +1284,8 @@ class WindowTestsBase extends SystemServiceTestsBase {
return this;
}
- TaskBuilder setParentTask(Task parentTask) {
- mParentTask = parentTask;
+ TaskBuilder setParentTaskFragment(TaskFragment parentTaskFragment) {
+ mParentTaskFragment = parentTaskFragment;
return this;
}
@@ -1219,12 +1298,13 @@ class WindowTestsBase extends SystemServiceTestsBase {
SystemServicesTestRule.checkHoldsLock(mSupervisor.mService.mGlobalLock);
// Create parent task.
- if (mParentTask == null && mCreateParentTask) {
- mParentTask = mTaskDisplayArea.createRootTask(
+ if (mParentTaskFragment == null && mCreateParentTask) {
+ mParentTaskFragment = mTaskDisplayArea.createRootTask(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
}
- if (mParentTask != null && !Mockito.mockingDetails(mParentTask).isSpy()) {
- spyOn(mParentTask);
+ if (mParentTaskFragment != null
+ && !Mockito.mockingDetails(mParentTaskFragment).isSpy()) {
+ spyOn(mParentTaskFragment);
}
// Create task.
@@ -1252,13 +1332,15 @@ class WindowTestsBase extends SystemServiceTestsBase {
.setOnTop(mOnTop)
.setVoiceSession(mVoiceSession);
final Task task;
- if (mParentTask == null) {
+ if (mParentTaskFragment == null) {
task = builder.setActivityType(mActivityType)
.setParent(mTaskDisplayArea)
.build();
} else {
- task = builder.setParent(mParentTask).build();
- mParentTask.moveToFront("build-task");
+ task = builder.setParent(mParentTaskFragment).build();
+ if (mParentTaskFragment.asTask() != null) {
+ mParentTaskFragment.asTask().moveToFront("build-task");
+ }
}
spyOn(task);
task.mUserId = mUserId;