Avoid recursive destruction from exit animation done
All WindowState belonging to an activity have non-null mActivityRecord. The original code may attempt to destroy parent surface from a child window's onExitAnimationDone(). Then it could have a case: removing parent -> remove child -> remove parent. The case is prevented by not destroying all surfaces under the activity if the animated window is not the main window of activity. Also move the check of mRemoved to avoid duplicated invocation of super.removeImmediately(). Assume the hierarchy: Activity - W (activity window) - X (dialog window) - Y (popup window) Y is IME layer target. The steps in WindowState: X onAnimationFinished(onExitAnimationDone) X destroySurface X removeImmediately Y removeImmediately (*) Y cancelAnimation Y onAnimationFinished(onExitAnimationDone) X destroySurface X removeImmediately CRASH in imeTarget.compareTo(this) (from needsRelativeLayeringToIme()) Because (*) hasn't reached setImeLayeringTarget(null) yet, Y is still imeTarget but its parent is cleared. With this change: X onAnimationFinished(onExitAnimationDone) X destroySurface X removeImmediately Y removeImmediately Y cancelAnimation Y onAnimationFinished(onExitAnimationDone) [NO destroySurface X] <- The exact fix Y destroySurface Y removeImmediately (early return) Fix: 232092201 Test: atest WindowStateTests#testOnExitAnimationDone Change-Id: I91781fa79dfdf414108803fac714930a20385780
Loading
Please register or sign in to comment