From b8a9cbe4d8f7d2af99e487fe89ca2c42578c6f88 Mon Sep 17 00:00:00 2001 From: Jorim Jaggi Date: Tue, 27 Mar 2018 18:02:18 +0200 Subject: Fix issue with animations that couldn't be started If we can't create a remote animation target for some reason (removed from task, no main window, etc), SurfaceAnimator called startAnimation but we never invoke the finish callback. Thus, we need to make sure to also invoke the finish callback when not using the AppWindowToken as part of the remote animation. This actually happens if the main intent clears the task, like Settings. In that case, it removes all sub activities, which then get added to mClosingApps, which then are part of a transition. It's questionable why this would need to happen, but we don't have the risk budget to go down that rabbit hole. Test: RemoteAnimationControllerTest Test: Open Settings -> Network -> Wifi, press home, reopen Settings, repeat 10x Test: adb shell dumpsys window -a Fixes: 76438155 Change-Id: Ib528d5c0d3559eb20522799af68ebbfb17b9801b --- .../android/server/wm/AnimatingAppWindowTokenRegistry.java | 10 ++++++++++ .../com/android/server/wm/RemoteAnimationController.java | 7 +++++++ services/core/java/com/android/server/wm/TaskStack.java | 1 + .../com/android/server/wm/RemoteAnimationControllerTest.java | 12 ++++++++++++ 4 files changed, 30 insertions(+) diff --git a/services/core/java/com/android/server/wm/AnimatingAppWindowTokenRegistry.java b/services/core/java/com/android/server/wm/AnimatingAppWindowTokenRegistry.java index ae343da30c74..416469bd3be1 100644 --- a/services/core/java/com/android/server/wm/AnimatingAppWindowTokenRegistry.java +++ b/services/core/java/com/android/server/wm/AnimatingAppWindowTokenRegistry.java @@ -19,6 +19,7 @@ package com.android.server.wm; import android.util.ArrayMap; import android.util.ArraySet; +import java.io.PrintWriter; import java.util.ArrayList; /** @@ -88,4 +89,13 @@ class AnimatingAppWindowTokenRegistry { } mTmpRunnableList.clear(); } + + void dump(PrintWriter pw, String header, String prefix) { + if (!mAnimatingTokens.isEmpty() || !mFinishedTokens.isEmpty()) { + pw.print(prefix); pw.println(header); + prefix = prefix + " "; + pw.print(prefix); pw.print("mAnimatingTokens="); pw.println(mAnimatingTokens); + pw.print(prefix); pw.print("mFinishedTokens="); pw.println(mFinishedTokens); + } + } } diff --git a/services/core/java/com/android/server/wm/RemoteAnimationController.java b/services/core/java/com/android/server/wm/RemoteAnimationController.java index 88577d075b4a..541a6f6213b6 100644 --- a/services/core/java/com/android/server/wm/RemoteAnimationController.java +++ b/services/core/java/com/android/server/wm/RemoteAnimationController.java @@ -133,11 +133,18 @@ class RemoteAnimationController { private RemoteAnimationTarget[] createAnimations() { final ArrayList targets = new ArrayList<>(); for (int i = mPendingAnimations.size() - 1; i >= 0; i--) { + final RemoteAnimationAdapterWrapper wrapper = mPendingAnimations.get(i); final RemoteAnimationTarget target = mPendingAnimations.get(i).createRemoteAppAnimation(); if (target != null) { targets.add(target); } else { + + // We can't really start an animation but we still need to make sure to finish the + // pending animation that was started by SurfaceAnimator + if (wrapper.mCapturedFinishCallback != null) { + wrapper.mCapturedFinishCallback.onAnimationFinished(wrapper); + } mPendingAnimations.remove(i); } } diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java index 900e2df1258d..62754ada7900 100644 --- a/services/core/java/com/android/server/wm/TaskStack.java +++ b/services/core/java/com/android/server/wm/TaskStack.java @@ -1387,6 +1387,7 @@ public class TaskStack extends WindowContainer implements token.dump(pw, " ", dumpAll); } } + mAnimatingAppWindowTokenRegistry.dump(pw, "AnimatingApps:", prefix); } @Override diff --git a/services/tests/servicestests/src/com/android/server/wm/RemoteAnimationControllerTest.java b/services/tests/servicestests/src/com/android/server/wm/RemoteAnimationControllerTest.java index 64501e49a9a8..553d65824c54 100644 --- a/services/tests/servicestests/src/com/android/server/wm/RemoteAnimationControllerTest.java +++ b/services/tests/servicestests/src/com/android/server/wm/RemoteAnimationControllerTest.java @@ -197,4 +197,16 @@ public class RemoteAnimationControllerTest extends WindowTestsBase { assertEquals(1, appsCaptor.getValue().length); assertEquals(mMockLeash, appsCaptor.getValue()[0].leash); } + + @Test + public void testRemovedBeforeStarted() throws Exception { + final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin"); + final AnimationAdapter adapter = mController.createAnimationAdapter(win.mAppToken, + new Point(50, 100), new Rect(50, 100, 150, 150)); + adapter.startAnimation(mMockLeash, mMockTransaction, mFinishedCallback); + win.mAppToken.removeImmediately(); + mController.goodToGo(); + verifyZeroInteractions(mMockRunner); + verify(mFinishedCallback).onAnimationFinished(eq(adapter)); + } } -- cgit v1.2.3-59-g8ed1b