Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 59f3e926 authored by Jorim Jaggi's avatar Jorim Jaggi
Browse files

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
parent 88f62053
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -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);
+6 −4
Original line number Diff line number Diff line
@@ -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();
            }