From 2d53bb2d9abf5d740bd8e4fbe11f87704de3bbd1 Mon Sep 17 00:00:00 2001 From: xi yu Date: Mon, 20 Jun 2022 13:50:41 +0000 Subject: [Bugfix][RemoteAnimation] Fix IndexOutOfBoundsException in onAnimationFinished of RemoteAnimationController Sometimes mPendingAnimations.remove will be called more than once in one cycle (line 255 - 270) of onAnimationFinished, e.g., mPendingAnimations.remove being called again in adapters.mAdapter.mCapturedFinishCallback.onAnimationFinished, resulting in IndexOutOfBoundsException. Bug:237989368 Change-Id: Ica771f1ae4cb4ddddb7684bd964504ca9f31ea12 Test: Monkey test --- .../core/java/com/android/server/wm/RemoteAnimationController.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/services/core/java/com/android/server/wm/RemoteAnimationController.java b/services/core/java/com/android/server/wm/RemoteAnimationController.java index eeac230489f9..027f3aebc502 100644 --- a/services/core/java/com/android/server/wm/RemoteAnimationController.java +++ b/services/core/java/com/android/server/wm/RemoteAnimationController.java @@ -68,6 +68,7 @@ class RemoteAnimationController implements DeathRecipient { final ArrayList mPendingNonAppAnimations = new ArrayList<>(); private final Handler mHandler; private final Runnable mTimeoutRunnable = () -> cancelAnimation("timeoutRunnable"); + private boolean mIsFinishing; private FinishedCallback mFinishedCallback; private boolean mCanceled; @@ -246,6 +247,7 @@ class RemoteAnimationController implements DeathRecipient { mPendingAnimations.size()); mHandler.removeCallbacks(mTimeoutRunnable); synchronized (mService.mGlobalLock) { + mIsFinishing = true; unlinkToDeathOfRunner(); releaseFinishedCallback(); mService.openSurfaceTransaction(); @@ -290,6 +292,7 @@ class RemoteAnimationController implements DeathRecipient { throw e; } finally { mService.closeSurfaceTransaction("RemoteAnimationController#finished"); + mIsFinishing = false; } } setRunningRemoteAnimation(false); @@ -501,6 +504,9 @@ class RemoteAnimationController implements DeathRecipient { @Override public void onAnimationCancelled(SurfaceControl animationLeash) { + if (mIsFinishing) { + return; + } if (mRecord.mAdapter == this) { mRecord.mAdapter = null; } else { -- cgit v1.2.3-59-g8ed1b