From 48458e1d8b86ec067d921876fdf45e1ee725395b Mon Sep 17 00:00:00 2001 From: Wale Ogunwale Date: Tue, 6 Jun 2017 10:07:58 -0700 Subject: [PATCH] Fixed NPE in TaskStack.stepAppWindowAnimation It is possible for an app token to be removed from the list if its last window is removed. The problem was probably exposed by ag/2267916 Change-Id: Ie4f36dfd0977e8a47b987e47a6ca97889bd3ef27 Fixes: 62368998 Test: go/wm-smoke --- .../core/java/com/android/server/wm/TaskStack.java | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java index eff8ed9a4defb..39878ccb07ddf 100644 --- a/services/core/java/com/android/server/wm/TaskStack.java +++ b/services/core/java/com/android/server/wm/TaskStack.java @@ -109,6 +109,7 @@ public class TaskStack extends WindowContainer implements DimLayer.DimLaye /** Application tokens that are exiting, but still on screen for animations. */ final AppTokenList mExitingAppTokens = new AppTokenList(); + final AppTokenList mTmpAppTokens = new AppTokenList(); /** Detach this stack from its display when animation completes. */ // TODO: maybe tie this to WindowContainer#removeChild some how... @@ -1626,9 +1627,14 @@ public class TaskStack extends WindowContainer implements DimLayer.DimLaye // TODO: Why aren't we just using the loop above for this? mAppAnimator.animating isn't set // below but is set in the loop above. See if it really matters... - final int exitingCount = mExitingAppTokens.size(); - for (int i = 0; i < exitingCount; i++) { - final AppWindowAnimator appAnimator = mExitingAppTokens.get(i).mAppAnimator; + + // Clear before using. + mTmpAppTokens.clear(); + // We copy the list as things can be removed from the exiting token list while we are + // processing. + mTmpAppTokens.addAll(mExitingAppTokens); + for (int i = 0; i < mTmpAppTokens.size(); i++) { + final AppWindowAnimator appAnimator = mTmpAppTokens.get(i).mAppAnimator; appAnimator.wasAnimating = appAnimator.animating; if (appAnimator.stepAnimationLocked(currentTime)) { mService.mAnimator.setAnimating(true); @@ -1641,6 +1647,8 @@ public class TaskStack extends WindowContainer implements DimLayer.DimLaye "updateWindowsApps...: done animating exiting " + appAnimator.mAppToken); } } + // Clear to avoid holding reference to tokens. + mTmpAppTokens.clear(); } @Override