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

Commit 6d41026f authored by Bryce Lee's avatar Bryce Lee
Browse files

Clean up closing apps list when clearing anAppWindowToken's task.

Previously it was possible for an AppWindowToken to be removed while
on the closing apps list, used in transition animations. During these
transitions, the visibility of the token is modified. Since
visibility relies on the WindowContainer parent, a
NullPointerException would occur.

This changelist addresses the issue by making sure to remove any
AppWindowToken from this list when its task is set to null.

Change-Id: Id9234822b228f4658f04d42ac0fe7b49ded6f5a1
Fixes: 35352214
Test: manual (primarily code inspection)
parent 5a7c7b8e
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -525,7 +525,8 @@ public class AppWindowContainerController

    private boolean createSnapshot() {
        final TaskSnapshot snapshot = mService.mTaskSnapshotController.getSnapshot(
                mContainer.mTask.mTaskId, mContainer.mTask.mUserId, false /* restoreFromDisk */);
                mContainer.getTask().mTaskId, mContainer.getTask().mUserId,
            false /* restoreFromDisk */);

        if (snapshot == null) {
            return false;
+49 −5
Original line number Diff line number Diff line
@@ -85,13 +85,17 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree
    final boolean mVoiceInteraction;

    // TODO: Use getParent instead?
    Task mTask;
    private Task mTask;
    /** @see WindowContainer#fillsParent() */
    private boolean mFillsParent;
    boolean layoutConfigChanges;
    boolean mShowForAllUsers;
    int mTargetSdk;

    // Flag set while reparenting to prevent actions normally triggered by an individual parent
    // change.
    private boolean mReparenting;

    // The input dispatching timeout for this application token in nanoseconds.
    long mInputDispatchingTimeoutNanos;

@@ -426,11 +430,8 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree
    void removeIfPossible() {
        mIsExiting = false;
        removeAllWindowsIfPossible();
        if (mTask != null) {
            mTask.mStack.mExitingAppTokens.remove(this);
        removeImmediately();
    }
    }

    @Override
    boolean checkCompleteDeferredRemoval() {
@@ -483,6 +484,7 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree

        removed = true;
        stopFreezingScreen(true, true);

        if (mService.mFocusedApp == this) {
            if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "Removing focused app token:" + this);
            mService.mFocusedApp = null;
@@ -664,6 +666,37 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree
        allDrawnExcludingSaved = false;
    }

    Task getTask() {
        return mTask;
    }

    /**
     * Sets the associated task, cleaning up dependencies when unset.
     */
    void setTask(Task task) {
        // Note: the following code assumes that the previous task's stack is the same as the
        // new task's stack.
        if (!mReparenting && mTask != null && mTask.mStack != null) {
            mTask.mStack.mExitingAppTokens.remove(this);
        }

        mTask = task;
    }

    @Override
    void onParentSet() {
        super.onParentSet();

        // When the associated task is {@code null}, the {@link AppWindowToken} can no longer
        // access visual elements like the {@link DisplayContent}. We must remove any associations
        // such as animations.
        if (!mReparenting && mTask == null) {
            // It is possible we have been marked as a closing app earlier. We must remove ourselves
            // from this list so we do not participate in any future animations.
            mService.mClosingApps.remove(this);
        }
    }

    void postWindowRemoveStartingWindowCleanup(WindowState win) {
        // TODO: Something smells about the code below...Is there a better way?
        if (startingWindow == win) {
@@ -866,13 +899,24 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree
            throw new IllegalArgumentException(
                    "window token=" + this + " already child of task=" + mTask);
        }

        if (mTask.mStack != task.mStack) {
            throw new IllegalArgumentException(
                    "window token=" + this + " current task=" + mTask
                        + " belongs to a different stack than " + task);
        }

        if (DEBUG_ADD_REMOVE) Slog.i(TAG, "reParentWindowToken: removing window token=" + this
                + " from task=" + mTask);
        final DisplayContent prevDisplayContent = getDisplayContent();

        mReparenting = true;

        getParent().removeChild(this);
        task.addChild(this, position);

        mReparenting = false;

        // Relayout display(s).
        final DisplayContent displayContent = task.getDisplayContent();
        displayContent.setLayoutNeeded();
+1 −1
Original line number Diff line number Diff line
@@ -588,7 +588,7 @@ public class DockedStackDividerController implements DimLayerUser {
    private boolean containsAppInDockedStack(ArraySet<AppWindowToken> apps) {
        for (int i = apps.size() - 1; i >= 0; i--) {
            final AppWindowToken token = apps.valueAt(i);
            if (token.mTask != null && token.mTask.mStack.mStackId == DOCKED_STACK_ID) {
            if (token.getTask() != null && token.getTask().mStack.mStackId == DOCKED_STACK_ID) {
                return true;
            }
        }
+3 −2
Original line number Diff line number Diff line
@@ -133,7 +133,7 @@ class Task extends WindowContainer<AppWindowToken> implements DimLayer.DimLayerU
    void addChild(AppWindowToken wtoken, int position) {
        position = getAdjustedAddPosition(position);
        super.addChild(wtoken, position);
        wtoken.mTask = this;
        wtoken.setTask(this);
        mDeferRemoval = false;
    }

@@ -244,7 +244,8 @@ class Task extends WindowContainer<AppWindowToken> implements DimLayer.DimLayerU
                removeIfPossible();
            }
        }
        token.mTask = null;

        token.setTask(null /*task*/);
    }

    void setSendingToBottom(boolean toBottom) {
+2 −2
Original line number Diff line number Diff line
@@ -106,8 +106,8 @@ class TaskSnapshotCache {
        if (taskId != null) {
            removeRunningEntry(taskId);
        }
        if (wtoken.mTask != null) {
            mRetrievalCache.remove(wtoken.mTask.mTaskId);
        if (wtoken.getTask() != null) {
            mRetrievalCache.remove(wtoken.getTask().mTaskId);
        }
    }

Loading