summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Ming-Shin Lu <lumark@google.com> 2020-09-14 12:35:41 +0800
committer Ming-Shin Lu <lumark@google.com> 2020-10-23 13:25:34 +0800
commit73aab1dc1fce55a544f5ecffe1c4cb7939d77be9 (patch)
treefc975885363b75ef5df08440a87eebab8a531900
parentae31181f133dba251225d95169d95ee1574599af (diff)
Better IME transition while switching app with recents (2/N)
In TaskSnapshotController#handleClosingApps will capture task snapshot while applying closing animation or during screen turning-off. this will overwrite the captured task from RecentsAnimationController, and makes while quick switching tasks, sometimes will not see the IME surface on the task snapshot. Add a check in places which triggers task snapshot to ignore addidnal snapshot request while RecentsAnimation is active. Also refined Task#isTaskAnimating as isAnimatingByRecents to simplify the logic and add the test for its behavior. Bug: 166736352 Test: manual by: 1) Tapping EditText in app and make keyboard shown 2) Quick switch back and force between apps by swiping navbar 3) Verify if the task snapshot with IME persists shown during switching apps Test: atest RecentsAnimationControllerTest#testIsAnimatingByRecents Change-Id: Icc7abd3338f472e263042f46502615f0446b46eb
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java6
-rw-r--r--services/core/java/com/android/server/wm/Task.java12
-rw-r--r--services/core/java/com/android/server/wm/TaskDisplayArea.java2
-rw-r--r--services/core/java/com/android/server/wm/TaskSnapshotController.java15
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java20
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)