From 153ba910d4f19e57664298439578066cf8f8e828 Mon Sep 17 00:00:00 2001 From: Ming-Shin Lu Date: Sun, 20 Feb 2022 21:55:45 +0800 Subject: [PATCH] [Shell-transition]: More checking animating state methods As IME snapshot will be attached during the IME target window in app transition or quick-switch, it still requires in WM core since IME visiblity/insets state is controlled by WM. As the reason, with migrating to Shell-transition, WM needs an alternitive way to check if the IME target is transitioning by app-transition or recents animation. This CL introduces TransitionController#inRecentsTransition and WindowContainer#inAppOrRecentsTransition utility method as for IME snapshot mechanism preparation. Bug: 201139553 Bug: 212570341 Test: build Change-Id: Icd702ff47859ca2f0982b877177098b304ff3b8c --- .../com/android/server/wm/ActivityRecord.java | 3 ++- .../server/wm/TaskSnapshotController.java | 9 +++++-- .../server/wm/TransitionController.java | 24 ++++++++++++++++++- .../android/server/wm/WindowContainer.java | 22 +++++++++++++++++ 4 files changed, 54 insertions(+), 4 deletions(-) diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 287248f311a86..9e24f4f15a12d 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -3247,7 +3247,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A // 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()) { + && !(task.isAnimatingByRecents() + || mTransitionController.inRecentsTransition(task))) { final ArraySet tasks = Sets.newArraySet(task); mAtmService.mWindowManager.mTaskSnapshotController.snapshotTasks(tasks); mAtmService.mWindowManager.mTaskSnapshotController diff --git a/services/core/java/com/android/server/wm/TaskSnapshotController.java b/services/core/java/com/android/server/wm/TaskSnapshotController.java index 6a23eb5881022..cde99271b0aeb 100644 --- a/services/core/java/com/android/server/wm/TaskSnapshotController.java +++ b/services/core/java/com/android/server/wm/TaskSnapshotController.java @@ -534,7 +534,7 @@ class TaskSnapshotController { // 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()) { + if (isAnimatingByRecents(task)) { mSkipClosingAppSnapshotTasks.add(task); } // If the task of the app is not visible anymore, it means no other app in that task @@ -686,7 +686,7 @@ class TaskSnapshotController { // 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()) { + if (task.isVisible() && !isAnimatingByRecents(task)) { mTmpTasks.add(task); } }); @@ -717,6 +717,11 @@ class TaskSnapshotController { frame, Type.systemBars(), false /* ignoreVisibility */).toRect(); } + private boolean isAnimatingByRecents(@NonNull Task task) { + return task.isAnimatingByRecents() + || mService.mAtmService.getTransitionController().inRecentsTransition(task); + } + void dump(PrintWriter pw, String prefix) { pw.println(prefix + "mHighResTaskSnapshotScale=" + mHighResTaskSnapshotScale); pw.println(prefix + "mTaskSnapshotEnabled=" + mTaskSnapshotEnabled); diff --git a/services/core/java/com/android/server/wm/TransitionController.java b/services/core/java/com/android/server/wm/TransitionController.java index b0532c2a15520..eee8b98cba2b3 100644 --- a/services/core/java/com/android/server/wm/TransitionController.java +++ b/services/core/java/com/android/server/wm/TransitionController.java @@ -246,7 +246,7 @@ class TransitionController { /** @return {@code true} if wc is in a participant subtree */ boolean inTransition(@NonNull WindowContainer wc) { - if (isCollecting(wc)) return true; + if (isCollecting(wc)) return true; for (int i = mPlayingTransitions.size() - 1; i >= 0; --i) { for (WindowContainer p = wc; p != null; p = p.getParent()) { if (mPlayingTransitions.get(i).mParticipants.contains(p)) { @@ -257,6 +257,28 @@ class TransitionController { return false; } + boolean inRecentsTransition(@NonNull WindowContainer wc) { + for (WindowContainer p = wc; p != null; p = p.getParent()) { + // TODO(b/221417431): replace this with deterministic snapshots + if (mCollectingTransition == null) break; + if ((mCollectingTransition.getFlags() & TRANSIT_FLAG_IS_RECENTS) != 0 + && mCollectingTransition.mParticipants.contains(wc)) { + return true; + } + } + + for (int i = mPlayingTransitions.size() - 1; i >= 0; --i) { + for (WindowContainer p = wc; p != null; p = p.getParent()) { + // TODO(b/221417431): replace this with deterministic snapshots + if ((mPlayingTransitions.get(i).getFlags() & TRANSIT_FLAG_IS_RECENTS) != 0 + && mPlayingTransitions.get(i).mParticipants.contains(p)) { + return true; + } + } + } + return false; + } + /** @return {@code true} if wc is in a participant subtree */ boolean isTransitionOnDisplay(@NonNull DisplayContent dc) { if (mCollectingTransition != null && mCollectingTransition.isOnDisplay(dc)) { diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java index a67f92332d8e2..3dac7708a1170 100644 --- a/services/core/java/com/android/server/wm/WindowContainer.java +++ b/services/core/java/com/android/server/wm/WindowContainer.java @@ -47,6 +47,7 @@ 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_ALL; import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITION; +import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_RECENTS; import static com.android.server.wm.WindowContainer.AnimationFlags.CHILDREN; import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS; import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION; @@ -1173,6 +1174,27 @@ class WindowContainer extends ConfigurationContainer< return mTransitionController.inTransition(this); } + boolean inAppOrRecentsTransition() { + if (!mTransitionController.isShellTransitionsEnabled()) { + return isAnimating(PARENTS | TRANSITION, + ANIMATION_TYPE_APP_TRANSITION | ANIMATION_TYPE_RECENTS); + } + for (WindowContainer p = this; p != null; p = p.getParent()) { + if (mTransitionController.isCollecting(p)) { + return true; + } + } + if (inTransition() || mTransitionController.inRecentsTransition(this)) return true; + + for (int i = mChildren.size() - 1; i >= 0; --i) { + WindowContainer child = mChildren.get(i); + if (child.inAppOrRecentsTransition()) { + return true; + } + } + return false; + } + void sendAppVisibilityToClients() { for (int i = mChildren.size() - 1; i >= 0; --i) { final WindowContainer wc = mChildren.get(i);