Loading services/core/java/com/android/server/wm/AppTransitionController.java +30 −2 Original line number Diff line number Diff line Loading @@ -798,6 +798,22 @@ public class AppTransitionController { } } /** * Returns {@code true} if a given {@link WindowContainer} is an embedded Task. * * Note that this is a short term workaround to support Android Auto until it migrate to * ShellTransition. This should only be used by {@link #getAnimationTargets}. * * TODO(b/213312721): Remove this predicate and its callers once ShellTransition is enabled. */ private static boolean isEmbeddedTask(WindowContainer wc) { // We use Task#mRemoveWithTaskOrganizer to identify an embedded Task, but this is a hack and // it is not guaranteed to work this logic in the future version. return !WindowManagerService.sEnableShellTransitions && wc instanceof Task && ((Task) wc).mRemoveWithTaskOrganizer; } /** * Find WindowContainers to be animated from a set of opening and closing apps. We will promote * animation targets to higher level in the window hierarchy if possible. Loading Loading @@ -844,7 +860,13 @@ public class AppTransitionController { siblings.add(current); boolean canPromote = true; if (parent == null || !parent.canCreateRemoteAnimationTarget() if (isEmbeddedTask(current)) { // Don't animate an embedded Task in app transition. This is a short term workaround // to prevent conflict of surface hierarchy changes between legacy app transition // and TaskView (b/205189147). // TODO(b/213312721): Remove this once ShellTransition is enabled. continue; } else if (parent == null || !parent.canCreateRemoteAnimationTarget() || !parent.canBeAnimationTarget() // We cannot promote the animation on Task's parent when the task is in // clearing task in case the animating get stuck when performing the opening Loading Loading @@ -887,7 +909,13 @@ public class AppTransitionController { for (int j = 0; j < parent.getChildCount(); ++j) { final WindowContainer sibling = parent.getChildAt(j); if (candidates.remove(sibling)) { if (!isEmbeddedTask(sibling)) { // Don't animate an embedded Task in app transition. This is a short // term workaround to prevent conflict of surface hierarchy changes // between legacy app transition and TaskView (b/205189147). // TODO(b/213312721): Remove this once ShellTransition is enabled. siblings.add(sibling); } } else if (sibling != current && sibling.isVisible()) { canPromote = false; } Loading services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java +60 −0 Original line number Diff line number Diff line Loading @@ -678,6 +678,66 @@ public class AppTransitionControllerTest extends WindowTestsBase { opening, closing, false /* visible */)); } @Test public void testGetAnimationTargets_embeddedTask() { // [DisplayContent] -+- [Task1] - [ActivityRecord1] (opening, invisible) // +- [Task2] (embedded) - [ActivityRecord2] (opening, invisible) final ActivityRecord activity1 = createActivityRecord(mDisplayContent); activity1.setVisible(false); activity1.mVisibleRequested = true; final Task task2 = createTask(mDisplayContent); task2.mRemoveWithTaskOrganizer = true; final ActivityRecord activity2 = createActivityRecord(task2); activity2.setVisible(false); activity2.mVisibleRequested = true; final ArraySet<ActivityRecord> opening = new ArraySet<>(); opening.add(activity1); opening.add(activity2); final ArraySet<ActivityRecord> closing = new ArraySet<>(); // No animation on the embedded task. assertEquals( new ArraySet<>(new WindowContainer[]{activity1.getTask()}), AppTransitionController.getAnimationTargets( opening, closing, true /* visible */)); assertEquals( new ArraySet<>(), AppTransitionController.getAnimationTargets( opening, closing, false /* visible */)); } @Test public void testGetAnimationTargets_activityInEmbeddedTask() { // [DisplayContent] - [Task] (embedded)-+- [ActivityRecord1] (opening, invisible) // +- [ActivityRecord2] (closing, visible) final Task task = createTask(mDisplayContent); task.mRemoveWithTaskOrganizer = true; final ActivityRecord activity1 = createActivityRecord(task); activity1.setVisible(false); activity1.mVisibleRequested = true; final ActivityRecord activity2 = createActivityRecord(task); final ArraySet<ActivityRecord> opening = new ArraySet<>(); opening.add(activity1); final ArraySet<ActivityRecord> closing = new ArraySet<>(); closing.add(activity2); // Even though embedded task itself doesn't animate, activities in an embedded task // animate. assertEquals( new ArraySet<>(new WindowContainer[]{activity1}), AppTransitionController.getAnimationTargets( opening, closing, true /* visible */)); assertEquals( new ArraySet<>(new WindowContainer[]{activity2}), AppTransitionController.getAnimationTargets( opening, closing, false /* visible */)); } static class TestRemoteAnimationRunner implements IRemoteAnimationRunner { @Override public void onAnimationStart(int transit, RemoteAnimationTarget[] apps, Loading Loading
services/core/java/com/android/server/wm/AppTransitionController.java +30 −2 Original line number Diff line number Diff line Loading @@ -798,6 +798,22 @@ public class AppTransitionController { } } /** * Returns {@code true} if a given {@link WindowContainer} is an embedded Task. * * Note that this is a short term workaround to support Android Auto until it migrate to * ShellTransition. This should only be used by {@link #getAnimationTargets}. * * TODO(b/213312721): Remove this predicate and its callers once ShellTransition is enabled. */ private static boolean isEmbeddedTask(WindowContainer wc) { // We use Task#mRemoveWithTaskOrganizer to identify an embedded Task, but this is a hack and // it is not guaranteed to work this logic in the future version. return !WindowManagerService.sEnableShellTransitions && wc instanceof Task && ((Task) wc).mRemoveWithTaskOrganizer; } /** * Find WindowContainers to be animated from a set of opening and closing apps. We will promote * animation targets to higher level in the window hierarchy if possible. Loading Loading @@ -844,7 +860,13 @@ public class AppTransitionController { siblings.add(current); boolean canPromote = true; if (parent == null || !parent.canCreateRemoteAnimationTarget() if (isEmbeddedTask(current)) { // Don't animate an embedded Task in app transition. This is a short term workaround // to prevent conflict of surface hierarchy changes between legacy app transition // and TaskView (b/205189147). // TODO(b/213312721): Remove this once ShellTransition is enabled. continue; } else if (parent == null || !parent.canCreateRemoteAnimationTarget() || !parent.canBeAnimationTarget() // We cannot promote the animation on Task's parent when the task is in // clearing task in case the animating get stuck when performing the opening Loading Loading @@ -887,7 +909,13 @@ public class AppTransitionController { for (int j = 0; j < parent.getChildCount(); ++j) { final WindowContainer sibling = parent.getChildAt(j); if (candidates.remove(sibling)) { if (!isEmbeddedTask(sibling)) { // Don't animate an embedded Task in app transition. This is a short // term workaround to prevent conflict of surface hierarchy changes // between legacy app transition and TaskView (b/205189147). // TODO(b/213312721): Remove this once ShellTransition is enabled. siblings.add(sibling); } } else if (sibling != current && sibling.isVisible()) { canPromote = false; } Loading
services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java +60 −0 Original line number Diff line number Diff line Loading @@ -678,6 +678,66 @@ public class AppTransitionControllerTest extends WindowTestsBase { opening, closing, false /* visible */)); } @Test public void testGetAnimationTargets_embeddedTask() { // [DisplayContent] -+- [Task1] - [ActivityRecord1] (opening, invisible) // +- [Task2] (embedded) - [ActivityRecord2] (opening, invisible) final ActivityRecord activity1 = createActivityRecord(mDisplayContent); activity1.setVisible(false); activity1.mVisibleRequested = true; final Task task2 = createTask(mDisplayContent); task2.mRemoveWithTaskOrganizer = true; final ActivityRecord activity2 = createActivityRecord(task2); activity2.setVisible(false); activity2.mVisibleRequested = true; final ArraySet<ActivityRecord> opening = new ArraySet<>(); opening.add(activity1); opening.add(activity2); final ArraySet<ActivityRecord> closing = new ArraySet<>(); // No animation on the embedded task. assertEquals( new ArraySet<>(new WindowContainer[]{activity1.getTask()}), AppTransitionController.getAnimationTargets( opening, closing, true /* visible */)); assertEquals( new ArraySet<>(), AppTransitionController.getAnimationTargets( opening, closing, false /* visible */)); } @Test public void testGetAnimationTargets_activityInEmbeddedTask() { // [DisplayContent] - [Task] (embedded)-+- [ActivityRecord1] (opening, invisible) // +- [ActivityRecord2] (closing, visible) final Task task = createTask(mDisplayContent); task.mRemoveWithTaskOrganizer = true; final ActivityRecord activity1 = createActivityRecord(task); activity1.setVisible(false); activity1.mVisibleRequested = true; final ActivityRecord activity2 = createActivityRecord(task); final ArraySet<ActivityRecord> opening = new ArraySet<>(); opening.add(activity1); final ArraySet<ActivityRecord> closing = new ArraySet<>(); closing.add(activity2); // Even though embedded task itself doesn't animate, activities in an embedded task // animate. assertEquals( new ArraySet<>(new WindowContainer[]{activity1}), AppTransitionController.getAnimationTargets( opening, closing, true /* visible */)); assertEquals( new ArraySet<>(new WindowContainer[]{activity2}), AppTransitionController.getAnimationTargets( opening, closing, false /* visible */)); } static class TestRemoteAnimationRunner implements IRemoteAnimationRunner { @Override public void onAnimationStart(int transit, RemoteAnimationTarget[] apps, Loading