From 6bf846920c9a78da71454108ed72e884c510b3f8 Mon Sep 17 00:00:00 2001 From: Issei Suzuki Date: Thu, 25 Feb 2021 16:59:31 +0100 Subject: [PATCH] Make sure that IRemoteAnimationController is always triggered. When an app transition is executed, RemoteAnimationTarget instance is created for apps and IRemoteAnimationController#onAnimationStart is called. However it's possible that no valid app exists when an app transition is executed, for example, an activity doesn't resume before timeout. If it happens, RemoteAnimationController triggers IRemoteAnimationController#onAnimationCancelled. Test: atest RemoteAnimationControllerTest Bug: 175687166 Change-Id: I50ddc91f7bd7ed24a977fa3face9c6e56e1bea02 --- data/etc/services.core.protolog.json | 18 ++++++++++++------ .../server/wm/RemoteAnimationController.java | 11 +++++++---- .../wm/RemoteAnimationControllerTest.java | 17 +++++++++++------ 3 files changed, 30 insertions(+), 16 deletions(-) diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json index b7bf8ab757991..b14db786ddcc7 100644 --- a/data/etc/services.core.protolog.json +++ b/data/etc/services.core.protolog.json @@ -307,6 +307,12 @@ "group": "WM_DEBUG_STARTING_WINDOW", "at": "com\/android\/server\/wm\/ActivityRecord.java" }, + "-1777196134": { + "message": "goodToGo(): No apps to animate, mPendingAnimations=%d", + "level": "DEBUG", + "group": "WM_DEBUG_REMOTE_ANIMATIONS", + "at": "com\/android\/server\/wm\/RemoteAnimationController.java" + }, "-1770075711": { "message": "Adding window client %s that is dead, aborting.", "level": "WARN", @@ -1981,12 +1987,6 @@ "group": "WM_DEBUG_STATES", "at": "com\/android\/server\/wm\/ActivityRecord.java" }, - "194124419": { - "message": "goodToGo(): Animation finished already, canceled=%s mPendingAnimations=%d", - "level": "DEBUG", - "group": "WM_DEBUG_REMOTE_ANIMATIONS", - "at": "com\/android\/server\/wm\/RemoteAnimationController.java" - }, "200829729": { "message": "ScreenRotationAnimation onAnimationEnd", "level": "DEBUG", @@ -2083,6 +2083,12 @@ "group": "WM_DEBUG_ORIENTATION", "at": "com\/android\/server\/wm\/DragState.java" }, + "269976641": { + "message": "goodToGo(): Animation canceled already", + "level": "DEBUG", + "group": "WM_DEBUG_REMOTE_ANIMATIONS", + "at": "com\/android\/server\/wm\/RemoteAnimationController.java" + }, "274773837": { "message": "applyAnimation: anim=%s nextAppTransition=ANIM_CLIP_REVEAL transit=%s Callers=%s", "level": "VERBOSE", diff --git a/services/core/java/com/android/server/wm/RemoteAnimationController.java b/services/core/java/com/android/server/wm/RemoteAnimationController.java index 42cb96f65738c..6fc585e473a94 100644 --- a/services/core/java/com/android/server/wm/RemoteAnimationController.java +++ b/services/core/java/com/android/server/wm/RemoteAnimationController.java @@ -104,11 +104,11 @@ class RemoteAnimationController implements DeathRecipient { */ void goodToGo(@WindowManager.TransitionOldType int transit) { ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "goodToGo()"); - if (mPendingAnimations.isEmpty() || mCanceled) { + if (mCanceled) { ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, - "goodToGo(): Animation finished already, canceled=%s mPendingAnimations=%d", - mCanceled, mPendingAnimations.size()); + "goodToGo(): Animation canceled already"); onAnimationFinished(); + invokeAnimationCancelled(); return; } @@ -120,8 +120,11 @@ class RemoteAnimationController implements DeathRecipient { // Create the app targets final RemoteAnimationTarget[] appTargets = createAppAnimations(); if (appTargets.length == 0) { - ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "goodToGo(): No apps to animate"); + ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, + "goodToGo(): No apps to animate, mPendingAnimations=%d", + mPendingAnimations.size()); onAnimationFinished(); + invokeAnimationCancelled(); return; } diff --git a/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java index 2fdd63ed93d52..c98e013479f48 100644 --- a/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java @@ -36,6 +36,8 @@ import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_WINDOW_ANIMAT import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; @@ -208,18 +210,20 @@ public class RemoteAnimationControllerTest extends WindowTestsBase { } @Test - public void testZeroAnimations() { + public void testZeroAnimations() throws Exception { mController.goodToGo(TRANSIT_OLD_NONE); - verifyNoMoreInteractionsExceptAsBinder(mMockRunner); + verify(mMockRunner, never()).onAnimationStart(anyInt(), any(), any(), any(), any()); + verify(mMockRunner).onAnimationCancelled(); } @Test - public void testNotReallyStarted() { + public void testNotReallyStarted() throws Exception { final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin"); mController.createRemoteAnimationRecord(win.mActivityRecord, new Point(50, 100), null, new Rect(50, 100, 150, 150), null); mController.goodToGo(TRANSIT_OLD_ACTIVITY_OPEN); - verifyNoMoreInteractionsExceptAsBinder(mMockRunner); + verify(mMockRunner, never()).onAnimationStart(anyInt(), any(), any(), any(), any()); + verify(mMockRunner).onAnimationCancelled(); } @Test @@ -250,7 +254,7 @@ public class RemoteAnimationControllerTest extends WindowTestsBase { } @Test - public void testRemovedBeforeStarted() { + public void testRemovedBeforeStarted() throws Exception { final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin"); final AnimationAdapter adapter = mController.createRemoteAnimationRecord(win.mActivityRecord, new Point(50, 100), null, new Rect(50, 100, 150, 150), null).mAdapter; @@ -258,7 +262,8 @@ public class RemoteAnimationControllerTest extends WindowTestsBase { mFinishedCallback); win.mActivityRecord.removeImmediately(); mController.goodToGo(TRANSIT_OLD_ACTIVITY_OPEN); - verifyNoMoreInteractionsExceptAsBinder(mMockRunner); + verify(mMockRunner, never()).onAnimationStart(anyInt(), any(), any(), any(), any()); + verify(mMockRunner).onAnimationCancelled(); verify(mFinishedCallback).onAnimationFinished(eq(ANIMATION_TYPE_APP_TRANSITION), eq(adapter)); }