Copy child window list when destroying surface
When removing a child window, we may trigger a layout pass via: WindowState.removeImmediately calls WMS.postWindowRemoveCleanupLocked calls WindowPlacer.performSurfacePlacement Then, under certain conditions, we either remove a window from mService.mForceRemoves or mService.mPendingRemove. If a child is in any of these two lists, it will lead to a crash. Test: go/wm-smoke Change-Id: I4eac6a6ec9092521542590fad1aa9643818b2fe6 Fixes: 71499373
This commit is contained in:
@@ -645,8 +645,7 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree
|
||||
boolean destroyedSomething = false;
|
||||
|
||||
// Copying to a different list as multiple children can be removed.
|
||||
// TODO: Not sure why this is needed.
|
||||
final LinkedList<WindowState> children = new LinkedList<>(mChildren);
|
||||
final ArrayList<WindowState> children = new ArrayList<>(mChildren);
|
||||
for (int i = children.size() - 1; i >= 0; i--) {
|
||||
final WindowState win = children.get(i);
|
||||
destroyedSomething |= win.destroySurface(cleanupOnResume, mAppStopped);
|
||||
|
||||
@@ -2642,8 +2642,11 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
|
||||
|
||||
boolean destroySurface(boolean cleanupOnResume, boolean appStopped) {
|
||||
boolean destroyedSomething = false;
|
||||
for (int i = mChildren.size() - 1; i >= 0; --i) {
|
||||
final WindowState c = mChildren.get(i);
|
||||
|
||||
// Copying to a different list as multiple children can be removed.
|
||||
final ArrayList<WindowState> childWindows = new ArrayList<>(mChildren);
|
||||
for (int i = childWindows.size() - 1; i >= 0; --i) {
|
||||
final WindowState c = childWindows.get(i);
|
||||
destroyedSomething |= c.destroySurface(cleanupOnResume, appStopped);
|
||||
}
|
||||
|
||||
@@ -3873,8 +3876,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
|
||||
|
||||
if (!mChildren.isEmpty()) {
|
||||
// Copying to a different list as multiple children can be removed.
|
||||
// TODO: Not sure if we really need to copy this into a different list.
|
||||
final LinkedList<WindowState> childWindows = new LinkedList(mChildren);
|
||||
final ArrayList<WindowState> childWindows = new ArrayList<>(mChildren);
|
||||
for (int i = childWindows.size() - 1; i >= 0; i--) {
|
||||
childWindows.get(i).onExitAnimationDone();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user