RemoteAnimations: Add failsafe
Adds failsafe mechanisms to RemoteAnimation and RecentsAnimation:
- cancel animations on binder death
- schedule a short timeout for RecentsAnimation after HOME and POWER events
Also enables RemoteAnimationControllerTest for presubmit, since it's turned
out to be reliable.
Change-Id: Id0bfdbee7d36f662eb386727195da8de2ed1684a
Fixes: 73496879
Test: kill / suspend launcher during animations; verify animations get aborted as expected.
Test: atest RemoteAnimationControllerTest
diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java
index 1018848..7274aee 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimationController.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java
@@ -34,6 +34,7 @@
import android.graphics.Point;
import android.graphics.Rect;
import android.os.Binder;
+import android.os.IBinder.DeathRecipient;
import android.os.RemoteException;
import android.os.SystemClock;
import android.util.ArraySet;
@@ -61,15 +62,17 @@
* window manager when the animation is completed. In addition, window manager may also notify the
* app if it requires the animation to be canceled at any time (ie. due to timeout, etc.)
*/
-public class RecentsAnimationController {
+public class RecentsAnimationController implements DeathRecipient {
private static final String TAG = TAG_WITH_CLASS_NAME ? "RecentsAnimationController" : TAG_WM;
private static final boolean DEBUG = false;
+ private static final long FAILSAFE_DELAY = 1000;
private final WindowManagerService mService;
private final IRecentsAnimationRunner mRunner;
private final RecentsAnimationCallbacks mCallbacks;
private final ArrayList<TaskAnimationAdapter> mPendingAnimations = new ArrayList<>();
private final int mDisplayId;
+ private final Runnable mFailsafeRunnable = this::cancelAnimation;
// The recents component app token that is shown behind the visibile tasks
private AppWindowToken mHomeAppToken;
@@ -223,6 +226,13 @@
return;
}
+ try {
+ mRunner.asBinder().linkToDeath(this, 0);
+ } catch (RemoteException e) {
+ cancelAnimation();
+ return;
+ }
+
// Adjust the wallpaper visibility for the showing home activity
final AppWindowToken recentsComponentAppToken =
dc.getHomeStack().getTopChild().getTopFullscreenAppToken();
@@ -296,6 +306,7 @@
// We've already canceled the animation
return;
}
+ mService.mH.removeCallbacks(mFailsafeRunnable);
mCanceled = true;
try {
mRunner.onAnimationCanceled();
@@ -321,10 +332,21 @@
}
mPendingAnimations.clear();
+ mRunner.asBinder().unlinkToDeath(this, 0);
+
mService.mInputMonitor.updateInputWindowsLw(true /*force*/);
mService.destroyInputConsumer(INPUT_CONSUMER_RECENTS_ANIMATION);
}
+ void scheduleFailsafe() {
+ mService.mH.postDelayed(mFailsafeRunnable, FAILSAFE_DELAY);
+ }
+
+ @Override
+ public void binderDied() {
+ cancelAnimation();
+ }
+
void checkAnimationReady(WallpaperController wallpaperController) {
if (mPendingStart) {
final boolean wallpaperReady = !isHomeAppOverWallpaper()