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

Commit 94cee2b6 authored by Wale Ogunwale's avatar Wale Ogunwale Committed by Android (Google) Code Review
Browse files

Merge "Added WindowContainer.removeImmediately to support immediate removal"

parents 31526ac9 571771c3
Loading
Loading
Loading
Loading
+7 −11
Original line number Diff line number Diff line
@@ -75,6 +75,7 @@ class AppWindowToken extends WindowToken {
    final boolean voiceInteraction;

    Task mTask;
    // TODO: Have a fillParent variable in WindowContainer to this?
    boolean appFullscreen;
    int requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
    boolean layoutConfigChanges;
@@ -100,7 +101,7 @@ class AppWindowToken extends WindowToken {
    // These are to track the app's real drawing status if there were no saved surfaces.
    boolean allDrawnExcludingSaved;
    int numInterestingWindowsExcludingSaved;
    int numDrawnWindowsExclusingSaved;
    int numDrawnWindowsExcludingSaved;

    // Is this window's surface needed?  This is almost like hidden, except
    // it will sometimes be true a little earlier: when the token has
@@ -133,6 +134,7 @@ class AppWindowToken extends WindowToken {
    // Input application handle used by the input dispatcher.
    final InputApplicationHandle mInputApplicationHandle;

    // TODO: Have a WindowContainer state for tracking exiting/deferred removal.
    boolean mIsExiting;

    boolean mLaunchTaskBehind;
@@ -356,18 +358,12 @@ class AppWindowToken extends WindowToken {
        return StackId.canReceiveKeys(mTask.mStack.mStackId) || mAlwaysFocusable;
    }

    void removeAppFromTaskLocked() {
    @Override
    void removeIfPossible() {
        mIsExiting = false;
        removeAllWindows();

        // Use local variable because removeAppToken will null out mTask.
        final Task task = mTask;
        if (task != null) {
            if (!task.removeAppToken(this)) {
                Slog.e(TAG, "removeAppFromTaskLocked: token=" + this
                        + " not found.");
            }
            task.mStack.mExitingAppTokens.remove(this);
        if (mTask != null) {
            mTask.detachChild(this);
        }
    }

+1 −1
Original line number Diff line number Diff line
@@ -515,7 +515,7 @@ class DisplayContent {
                    for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
                        AppWindowToken wtoken = tokens.get(tokenNdx);
                        if (wtoken.mIsExiting) {
                            wtoken.removeAppFromTaskLocked();
                            wtoken.removeIfPossible();
                        }
                    }
                }
+8 −0
Original line number Diff line number Diff line
@@ -179,6 +179,14 @@ class Task implements DimLayer.DimLayerUser {
        }
    }

    // TODO: Don't forget to switch to WC.detachChild
    void detachChild(AppWindowToken wtoken) {
        if (!removeAppToken(wtoken)) {
            Slog.e(TAG, "detachChild: token=" + this + " not found.");
        }
        mStack.mExitingAppTokens.remove(wtoken);
    }

    boolean removeAppToken(AppWindowToken wtoken) {
        boolean removed = mAppTokens.remove(wtoken);
        if (mAppTokens.size() == 0) {
+39 −6
Original line number Diff line number Diff line
@@ -67,17 +67,50 @@ class WindowContainer {
        mChildren.add(child);
    }

    /** Removes this window container and its children */
    /**
     * Removes this window container and its children with no regard for what else might be going on
     * in the system. For example, the container will be removed during animation if this method is
     * called which isn't desirable. For most cases you want to call {@link #removeIfPossible()}
     * which allows the system to defer removal until a suitable time.
     */
    @CallSuper
    void remove() {
    void removeImmediately() {
        while (!mChildren.isEmpty()) {
            final WindowContainer child = mChildren.removeLast();
            child.remove();
            final WindowContainer child = mChildren.peekLast();
            child.removeImmediately();
            // Need to do this after calling remove on the child because the child might try to
            // remove/detach itself from its parent which will cause an exception if we remove
            // it before calling remove on the child.
            mChildren.remove(child);
        }

        if (mParent != null) {
            mParent.mChildren.remove(this);
            mParent = null;
            mParent.detachChild(this);
        }
    }

    /**
     * Removes this window container and its children taking care not to remove them during a
     * critical stage in the system. For example, some containers will not be removed during
     * animation if this method is called.
     */
    // TODO: figure-out implementation that works best for this.
    // E.g. when do we remove from parent list? maybe not...
    void removeIfPossible() {
        for (int i = mChildren.size() - 1; i >= 0; --i) {
            final WindowContainer wc = mChildren.get(i);
            wc.removeIfPossible();
        }
    }

    /** Detaches the input child container from this container which is its parent. */
    @CallSuper
    void detachChild(WindowContainer child) {
        if (mChildren.remove(child)) {
            child.mParent = null;
        } else {
            throw new IllegalArgumentException("detachChild: container=" + child
                    + " is not a child of container=" + this);
        }
    }

+6 −4
Original line number Diff line number Diff line
@@ -249,7 +249,6 @@ import static com.android.server.wm.WindowManagerDebugConfig.TAG_KEEP_SCREEN_ON;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import static com.android.server.wm.WindowStateAnimator.DRAW_PENDING;
import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_NONE;

/** {@hide} */
public class WindowManagerService extends IWindowManager.Stub
@@ -1971,7 +1970,10 @@ public class WindowManagerService extends IWindowManager.Stub

    /**
     * Performs some centralized bookkeeping clean-up on the window that is being removed.
     * NOTE: Should only be called from {@link WindowState#remove()}
     * NOTE: Should only be called from {@link WindowState#removeImmediately()}
     * TODO: Maybe better handled with a method {@link WindowContainer#detachChild} if we can
     * figure-out a good way to have all parents of a WindowState doing the same thing without
     * forgetting to add the wiring when a new parent of WindowState is added.
     */
    void postWindowRemoveCleanupLocked(WindowState win) {
        if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "postWindowRemoveCleanupLocked: " + win);
@@ -3831,7 +3833,7 @@ public class WindowManagerService extends IWindowManager.Stub
                    // soon as their animations are complete
                    wtoken.mAppAnimator.clearAnimation();
                    wtoken.mAppAnimator.animating = false;
                    wtoken.removeAppFromTaskLocked();
                    wtoken.removeIfPossible();
                }

                wtoken.removed = true;
@@ -10533,7 +10535,7 @@ public class WindowManagerService extends IWindowManager.Stub
        public void removeWindowToken(IBinder token, boolean removeWindows) {
            synchronized(mWindowMap) {
                if (removeWindows) {
                    WindowToken wtoken = mTokenMap.remove(token);
                    final WindowToken wtoken = mTokenMap.remove(token);
                    if (wtoken != null) {
                        wtoken.removeAllWindows();
                    }
Loading