diff options
5 files changed, 42 insertions, 13 deletions
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index aea944cd52d3..9df31d6d0c5e 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -2590,7 +2590,11 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A // When finishing the activity preemptively take the snapshot before the app window // is marked as hidden and any configuration changes take place - if (mAtmService.mWindowManager.mTaskSnapshotController != null) { + // Note that RecentsAnimation will handle task snapshot while switching apps with + // the best capture timing (e.g. IME window capture), + // No need additional task capture while task is controlled by RecentsAnimation. + if (mAtmService.mWindowManager.mTaskSnapshotController != null + && !task.isAnimatingByRecents()) { final ArraySet<Task> tasks = Sets.newArraySet(task); mAtmService.mWindowManager.mTaskSnapshotController.snapshotTasks(tasks); mAtmService.mWindowManager.mTaskSnapshotController diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index ecee46e895d0..e584d8cf45dd 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -114,6 +114,7 @@ import static com.android.server.wm.ActivityTaskManagerService.H.FIRST_ACTIVITY_ import static com.android.server.wm.IdentifierProto.HASH_CODE; import static com.android.server.wm.IdentifierProto.TITLE; import static com.android.server.wm.IdentifierProto.USER_ID; +import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_RECENTS; import static com.android.server.wm.Task.ActivityState.PAUSED; import static com.android.server.wm.Task.ActivityState.PAUSING; import static com.android.server.wm.Task.ActivityState.RESUMED; @@ -3661,14 +3662,9 @@ class Task extends WindowContainer<WindowContainer> { super.setInitialSurfaceControlProperties(b); } - boolean isTaskAnimating() { - final RecentsAnimationController recentsAnim = mWmService.getRecentsAnimationController(); - if (recentsAnim != null) { - if (recentsAnim.isAnimatingTask(this)) { - return true; - } - } - return forAllTasks((t) -> { return t != this && t.isTaskAnimating(); }); + /** Checking if self or its child tasks are animated by recents animation. */ + boolean isAnimatingByRecents() { + return isAnimating(CHILDREN, ANIMATION_TYPE_RECENTS); } @Override diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java index 830ad5d6043b..da68ebbc4ecf 100644 --- a/services/core/java/com/android/server/wm/TaskDisplayArea.java +++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java @@ -754,7 +754,7 @@ final class TaskDisplayArea extends DisplayArea<Task> { // The split screen divider anchor is located above the split screen window. mTmpLayerForSplitScreenDividerAnchor = layer++; } - if (s.isTaskAnimating() || s.isAppTransitioning()) { + if (s.isAnimatingByRecents() || s.isAppTransitioning()) { // The animation layer is located above the highest animating stack and no // higher. mTmpLayerForAnimationLayer = layer++; diff --git a/services/core/java/com/android/server/wm/TaskSnapshotController.java b/services/core/java/com/android/server/wm/TaskSnapshotController.java index 01adb8b35c3b..3ce04aff5301 100644 --- a/services/core/java/com/android/server/wm/TaskSnapshotController.java +++ b/services/core/java/com/android/server/wm/TaskSnapshotController.java @@ -157,7 +157,6 @@ class TaskSnapshotController { if (shouldDisableSnapshots()) { return; } - // We need to take a snapshot of the task if and only if all activities of the task are // either closing or hidden. getClosingTasks(closingApps, mTmpTasks); @@ -445,10 +444,17 @@ class TaskSnapshotController { for (int i = closingApps.size() - 1; i >= 0; i--) { final ActivityRecord activity = closingApps.valueAt(i); final Task task = activity.getTask(); + if (task == null) continue; + // Since RecentsAnimation will handle task snapshot while switching apps with the + // best capture timing (e.g. IME window capture), + // No need additional task capture while task is controlled by RecentsAnimation. + if (task.isAnimatingByRecents()) { + mSkipClosingAppSnapshotTasks.add(task); + } // If the task of the app is not visible anymore, it means no other app in that task // is opening. Thus, the task is closing. - if (task != null && !task.isVisible() && !mSkipClosingAppSnapshotTasks.contains(task)) { + if (!task.isVisible() && !mSkipClosingAppSnapshotTasks.contains(task)) { outClosingTasks.add(task); } } @@ -571,7 +577,10 @@ class TaskSnapshotController { synchronized (mService.mGlobalLock) { mTmpTasks.clear(); mService.mRoot.forAllTasks(task -> { - if (task.isVisible()) { + // Since RecentsAnimation will handle task snapshot while switching apps + // with the best capture timing (e.g. IME window capture), No need + // additional task capture while task is controlled by RecentsAnimation. + if (task.isVisible() && !task.isAnimatingByRecents()) { mTmpTasks.add(task); } }); diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java index 7fb7d40f0bd2..2985796d005f 100644 --- a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java @@ -476,6 +476,26 @@ public class RecentsAnimationControllerTest extends WindowTestsBase { assertFalse(wallpaperWindowToken.hasFixedRotationTransform()); } + @Test + public void testIsAnimatingByRecents() { + final ActivityRecord homeActivity = createHomeActivity(); + final Task rootTask = createTaskStackOnDisplay(mDefaultDisplay); + final Task childTask = createTaskInStack(rootTask, 0 /* userId */); + final Task leafTask = createTaskInStack(childTask, 0 /* userId */); + spyOn(leafTask); + doReturn(true).when(leafTask).isVisible(); + + initializeRecentsAnimationController(mController, homeActivity); + + // Verify RecentsAnimationController will animate visible leaf task by default. + verify(mController).addAnimation(eq(leafTask), anyBoolean(), anyBoolean(), eq(null)); + assertTrue(leafTask.isAnimatingByRecents()); + + // Make sure isAnimatingByRecents will also return true when it called by the parent task. + assertTrue(rootTask.isAnimatingByRecents()); + assertTrue(childTask.isAnimatingByRecents()); + } + private ActivityRecord createHomeActivity() { final ActivityRecord homeActivity = new ActivityBuilder(mWm.mAtmService) .setStack(mRootHomeTask) |