From 7b4655dbbebd9e6e9394efe145a35db41a6fbfd4 Mon Sep 17 00:00:00 2001 From: Craig Mautner Date: Thu, 20 Nov 2014 12:13:22 -0800 Subject: [PATCH] Ensure arraylist index is montonically decreasing A previous fix for IndexOutOfBoundsException (ag/584621) left a situation where the index would not decrement if the arraylist size didn't change. The size doesn't change if the window being removed is animating away. That caused window manager to remain in an infinite loop within removeAllWindows. This change ensures that the index diminishes each pass through the loop and doesn't exceed the bounds of the arraylist. Fixes bug 18362246. Change-Id: Ibca70d95622f3b152ede14857f0e913099dc7b88 --- .../java/com/android/server/wm/AppWindowToken.java | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java index 1086eb2ceaadd..f859fd2e44bbd 100644 --- a/services/core/java/com/android/server/wm/AppWindowToken.java +++ b/services/core/java/com/android/server/wm/AppWindowToken.java @@ -254,15 +254,18 @@ class AppWindowToken extends WindowToken { @Override void removeAllWindows() { - int winNdx; - while ((winNdx = allAppWindows.size()) > 0) { - WindowState win = allAppWindows.get(winNdx - 1); + for (int winNdx = allAppWindows.size() - 1; winNdx >= 0; + // removeWindowLocked at bottom of loop may remove multiple entries from + // allAppWindows if the window to be removed has child windows. It also may + // not remove any windows from allAppWindows at all if win is exiting and + // currently animating away. This ensures that winNdx is monotonically decreasing + // and never beyond allAppWindows bounds. + winNdx = Math.min(winNdx - 1, allAppWindows.size() - 1)) { + WindowState win = allAppWindows.get(winNdx); if (WindowManagerService.DEBUG_WINDOW_MOVEMENT) { Slog.w(WindowManagerService.TAG, "removeAllWindows: removing win=" + win); } - // {@link WindowManagerService.removeWindowLocked} may remove multiple entries from - // {@link #allAppWindows} if the window to be removed has child windows. win.mService.removeWindowLocked(win.mSession, win); } }