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
This commit is contained in:
Issei Suzuki
2021-02-25 16:59:31 +01:00
parent 22a93daf9f
commit 6bf846920c
3 changed files with 30 additions and 16 deletions

View File

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

View File

@@ -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;
}

View File

@@ -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));
}