Don't animate embedded task in app transition.

Bug: 205189147
Test: atest AppTransitionControllerTest
Change-Id: I6b317e230e16e586fb869b1bb8fd97b9cff48a0c
This commit is contained in:
Issei Suzuki
2021-11-22 15:21:26 +01:00
parent 1cd3bfd430
commit bb147fe4d3
2 changed files with 90 additions and 2 deletions

View File

@@ -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)) {
siblings.add(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;
}

View File

@@ -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,