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

Commit 23ffbdb7 authored by Riddle Hsu's avatar Riddle Hsu
Browse files

Replace mPendingRemove with hierarchy deferred removal

To eliminate the global list and simplify the path of surface placement.

This reverts commit 4ddb1d86.

Reason for revert: Fix the original CL (commit bb2efa02) by
checking "!isSelfAnimating(0 /* flags */, EXIT_ANIMATING_TYPES)"
in WindowState#handleCompleteDeferredRemoval.

Bug: 163976519
Test: WindowContainerTests#testHandleCompleteDeferredRemoval
Test: Long press power key and dismiss the power menu window.
      The window should have fade out animation.

Change-Id: I9bd75a82952ef129f528a0dba8fe740eddf60c49
parent c271def0
Loading
Loading
Loading
Loading
+0 −23
Original line number Diff line number Diff line
@@ -981,29 +981,6 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
            mWmService.checkDrawnWindowsLocked();
        }

        final int N = mWmService.mPendingRemove.size();
        if (N > 0) {
            if (mWmService.mPendingRemoveTmp.length < N) {
                mWmService.mPendingRemoveTmp = new WindowState[N + 10];
            }
            mWmService.mPendingRemove.toArray(mWmService.mPendingRemoveTmp);
            mWmService.mPendingRemove.clear();
            ArrayList<DisplayContent> displayList = new ArrayList();
            for (i = 0; i < N; i++) {
                final WindowState w = mWmService.mPendingRemoveTmp[i];
                w.removeImmediately();
                final DisplayContent displayContent = w.getDisplayContent();
                if (displayContent != null && !displayList.contains(displayContent)) {
                    displayList.add(displayContent);
                }
            }

            for (int j = displayList.size() - 1; j >= 0; --j) {
                final DisplayContent dc = displayList.get(j);
                dc.assignWindowLayers(true /*setLayoutNeeded*/);
            }
        }

        forAllDisplays(dc -> {
            dc.getInputMonitor().updateInputWindowsLw(true /*force*/);
            dc.updateSystemGestureExclusion();
+0 −33
Original line number Diff line number Diff line
@@ -224,7 +224,6 @@ import android.util.DisplayMetrics;
import android.util.EventLog;
import android.util.MergedConfiguration;
import android.util.Slog;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
import android.util.TimeUtils;
import android.util.TypedValue;
@@ -583,20 +582,6 @@ public class WindowManagerService extends IWindowManager.Stub
     */
    final ArrayList<WindowState> mResizingWindows = new ArrayList<>();

    /**
     * Windows whose animations have ended and now must be removed.
     */
    final ArrayList<WindowState> mPendingRemove = new ArrayList<>();

    /**
     * Used when processing mPendingRemove to avoid working on the original array.
     */
    WindowState[] mPendingRemoveTmp = new WindowState[20];

    // TODO: use WindowProcessController once go/wm-unified is done.
    /** Mapping of process pids to configurations */
    final SparseArray<Configuration> mProcessConfigurations = new SparseArray<>();

    /**
     * Mapping of displayId to {@link DisplayImePolicy}.
     * Note that this can be accessed without holding the lock.
@@ -2039,7 +2024,6 @@ public class WindowManagerService extends IWindowManager.Stub
            dc.mWinRemovedSinceNullFocus.add(win);
        }
        mEmbeddedWindowController.onWindowRemoved(win);
        mPendingRemove.remove(win);
        mResizingWindows.remove(win);
        updateNonSystemOverlayWindowsVisibilityIfNeeded(win, false /* surfaceShown */);
        mWindowsChanged = true;
@@ -6411,23 +6395,6 @@ public class WindowManagerService extends IWindowManager.Stub
                }
            }
        }
        if (mPendingRemove.size() > 0) {
            pw.println();
            pw.println("  Remove pending for:");
            for (int i=mPendingRemove.size()-1; i>=0; i--) {
                WindowState w = mPendingRemove.get(i);
                if (windows == null || windows.contains(w)) {
                    pw.print("  Remove #"); pw.print(i); pw.print(' ');
                            pw.print(w);
                    if (dumpAll) {
                        pw.println(":");
                        w.dump(pw, "    ", true);
                    } else {
                        pw.println();
                    }
                }
            }
        }
        if (mForceRemoves != null && mForceRemoves.size() > 0) {
            pw.println();
            pw.println("  Windows force removing:");
+9 −4
Original line number Diff line number Diff line
@@ -4910,15 +4910,20 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
            if (hasSurface) {
                mWmService.mDestroySurface.add(this);
            }
            if (mRemoveOnExit) {
                mWmService.mPendingRemove.add(this);
                mRemoveOnExit = false;
            }
        }
        mAnimatingExit = false;
        getDisplayContent().mWallpaperController.hideWallpapers(this);
    }

    @Override
    boolean handleCompleteDeferredRemoval() {
        if (mRemoveOnExit && !isSelfAnimating(0 /* flags */, EXIT_ANIMATING_TYPES)) {
            mRemoveOnExit = false;
            removeImmediately();
        }
        return super.handleCompleteDeferredRemoval();
    }

    boolean clearAnimatingFlags() {
        boolean didSomething = false;
        // We don't want to clear it out for windows that get replaced, because the
+18 −0
Original line number Diff line number Diff line
@@ -870,6 +870,24 @@ public class WindowContainerTests extends WindowTestsBase {
        final DisplayContent displayContent = createNewDisplay();
        // Do not reparent activity to default display when removing the display.
        doReturn(true).when(displayContent).shouldDestroyContentOnRemove();

        // An animating window with mRemoveOnExit can be removed by handleCompleteDeferredRemoval
        // once it no longer animates.
        final WindowState exitingWindow = createWindow(null, TYPE_APPLICATION_OVERLAY,
                displayContent, "exiting window");
        exitingWindow.startAnimation(exitingWindow.getPendingTransaction(),
                mock(AnimationAdapter.class), false /* hidden */,
                SurfaceAnimator.ANIMATION_TYPE_WINDOW_ANIMATION);
        exitingWindow.mRemoveOnExit = true;
        exitingWindow.handleCompleteDeferredRemoval();
        // The animation has not finished so the window is not removed.
        assertTrue(exitingWindow.isAnimating());
        assertTrue(exitingWindow.isAttached());
        exitingWindow.cancelAnimation();
        // The window is removed because the animation is gone.
        exitingWindow.handleCompleteDeferredRemoval();
        assertFalse(exitingWindow.isAttached());

        final ActivityRecord r = new TaskBuilder(mSupervisor).setCreateActivity(true)
                .setDisplay(displayContent).build().getTopMostActivity();
        // Add a window and make the activity animating so the removal of activity is deferred.