Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bb147fe4 authored by Issei Suzuki's avatar Issei Suzuki
Browse files

Don't animate embedded task in app transition.

Bug: 205189147
Test: atest AppTransitionControllerTest
Change-Id: I6b317e230e16e586fb869b1bb8fd97b9cff48a0c
parent 1cd3bfd4
Loading
Loading
Loading
Loading
+30 −2
Original line number Diff line number Diff line
@@ -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.
@@ -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
@@ -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;
                    }
+60 −0
Original line number Diff line number Diff line
@@ -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,