diff options
| author | 2022-06-07 18:55:21 +0800 | |
|---|---|---|
| committer | 2022-06-07 22:15:10 +0800 | |
| commit | d95f73d9a3662bad36c862546a97699059127598 (patch) | |
| tree | c48a401faecb580782c481343e68c5653f0ce71c /libs/androidfw/StringPool.cpp | |
| parent | 0cbdd2757000aeaf5e6e2a054e4261c1801bf4ea (diff) | |
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
Diffstat (limited to 'libs/androidfw/StringPool.cpp')
0 files changed, 0 insertions, 0 deletions