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

Commit 9ef471f7 authored by Craig Mautner's avatar Craig Mautner
Browse files

Don't remove Activities and Tasks until animation done

Just like stacks and displays, activities and tasks need to stick
around until animations have completed.

Change-Id: I54fe8f6855d60cbc3a25cbc6e762defd5ac50bf5
parent 8ff1f285
Loading
Loading
Loading
Loading
+5 −5
Original line number Diff line number Diff line
@@ -1150,7 +1150,11 @@ public final class ActivityStackSupervisor implements DisplayListener {
        if (err == ActivityManager.START_SUCCESS) {
            final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
            Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false)
                    + "} from pid " + (callerApp != null ? callerApp.pid : callingPid));
                    + "} from pid " + (callerApp != null ? callerApp.pid : callingPid)
                    + " on display " + (container == null ? (mFocusedStack == null ?
                            Display.DEFAULT_DISPLAY : mFocusedStack.mDisplayId) :
                            (container.mActivityDisplay == null ? Display.DEFAULT_DISPLAY :
                                    container.mActivityDisplay.mDisplayId)));
        }

        ActivityRecord sourceRecord = null;
@@ -3068,10 +3072,6 @@ public final class ActivityStackSupervisor implements DisplayListener {
            init(mDisplayManager.getDisplay(displayId));
        }

        ActivityDisplay(Display display) {
            init(display);
        }

        ActivityDisplay(Surface surface, int width, int height, int density) {
            DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
            long ident = Binder.clearCallingIdentity();
+2 −0
Original line number Diff line number Diff line
@@ -105,6 +105,8 @@ class AppWindowToken extends WindowToken {
    // Input application handle used by the input dispatcher.
    final InputApplicationHandle mInputApplicationHandle;

    boolean mDeferRemoval;

    AppWindowToken(WindowManagerService _service, IApplicationToken _token) {
        super(_service, _token.asBinder(),
                WindowManager.LayoutParams.TYPE_APPLICATION, true);
+1 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ class Task {
    final AppTokenList mAppTokens = new AppTokenList();
    final int taskId;
    final int mUserId;
    boolean mDeferRemoval = false;

    Task(AppWindowToken wtoken, TaskStack stack, int userId) {
        taskId = wtoken.groupId;
+16 −1
Original line number Diff line number Diff line
@@ -366,7 +366,7 @@ public class TaskStack {
        mAnimationBackgroundSurface.mDimSurface.destroy();
    }

    void checkForDeferredDetach() {
    void checkForDeferredActions() {
        if (mDisplayContent != null &&
                (mDisplayContent.mDeferredActions & DisplayContent.DEFER_DETACH) != 0 &&
                !isAnimating()) {
@@ -377,6 +377,21 @@ public class TaskStack {
                mService.onDisplayRemoved(mDisplayContent.getDisplayId());
            }
        }
        for (int taskNdx = mTasks.size() - 1; taskNdx >= 0; --taskNdx) {
            final Task task = mTasks.get(taskNdx);
            AppTokenList tokens = task.mAppTokens;
            for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
                AppWindowToken wtoken = tokens.get(tokenNdx);
                if (wtoken.mDeferRemoval) {
                    wtoken.mDeferRemoval = false;
                    mService.removeAppFromTaskLocked(wtoken);
                }
            }
            if (task.mDeferRemoval) {
                task.mDeferRemoval = false;
                mService.removeTaskLocked(task);
            }
        }
    }

    public void dump(String prefix, PrintWriter pw) {
+38 −10
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import static android.view.WindowManager.LayoutParams.*;
import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;

import android.app.AppOpsManager;
import android.util.ArraySet;
import android.util.TimeUtils;
import android.view.IWindowId;

@@ -365,6 +366,11 @@ public class WindowManagerService extends IWindowManager.Stub
     */
    final ArrayList<WindowState> mPendingRemove = new ArrayList<WindowState>();

    /**
     * Stacks whose animations have ended and whose tasks, apps, selves may now be removed.
     */
    final ArraySet<TaskStack> mPendingStacksRemove = new ArraySet<TaskStack>();

    /**
     * Used when processing mPendingRemove to avoid working on the original array.
     */
@@ -3425,6 +3431,8 @@ public class WindowManagerService extends IWindowManager.Stub
    }

    private Task createTask(int taskId, int stackId, int userId, AppWindowToken atoken) {
        if (DEBUG_STACK) Slog.i(TAG, "createTask: taskId=" + taskId + " stackId=" + stackId
                + " atoken=" + atoken);
        final TaskStack stack = mStackIdToStack.get(stackId);
        if (stack == null) {
            throw new IllegalArgumentException("addAppToken: invalid stackId=" + stackId);
@@ -3507,7 +3515,7 @@ public class WindowManagerService extends IWindowManager.Stub
                return;
            }
            final Task oldTask = mTaskIdToTask.get(atoken.groupId);
            removeAppFromTask(atoken);
            removeAppFromTaskLocked(atoken);

            atoken.groupId = groupId;
            Task newTask = mTaskIdToTask.get(groupId);
@@ -4517,11 +4525,10 @@ public class WindowManagerService extends IWindowManager.Stub
        }
    }

    void removeAppFromTask(AppWindowToken wtoken) {
    void removeAppFromTaskLocked(AppWindowToken wtoken) {
        final Task task = mTaskIdToTask.get(wtoken.groupId);
        if (task != null && task.removeAppToken(wtoken)) {
            task.mStack.removeTask(task);
            mTaskIdToTask.delete(wtoken.groupId);
        if (!wtoken.mDeferRemoval && task != null && task.removeAppToken(wtoken)) {
            removeTaskLocked(task);
        }
    }

@@ -4563,17 +4570,18 @@ public class WindowManagerService extends IWindowManager.Stub
                    if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
                            "removeAppToken make exiting: " + wtoken);
                    stack.mExitingAppTokens.add(wtoken);
                    wtoken.mDeferRemoval = true;
                } else {
                    // Make sure there is no animation running on this token,
                    // so any windows associated with it will be removed as
                    // soon as their animations are complete
                    wtoken.mAppAnimator.clearAnimation();
                    wtoken.mAppAnimator.animating = false;
                    removeAppFromTaskLocked(wtoken);
                }
                if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
                        "removeAppToken: " + wtoken);

                removeAppFromTask(wtoken);

                wtoken.removed = true;
                if (wtoken.startingData != null) {
@@ -4928,6 +4936,21 @@ public class WindowManagerService extends IWindowManager.Stub
        }
    }

    void removeTaskLocked(Task task) {
        final int taskId = task.taskId;
        final TaskStack stack = task.mStack;
        if (stack.isAnimating()) {
            if (DEBUG_STACK) Slog.i(TAG, "removeTask: deferring removing taskId=" + taskId);
            task.mDeferRemoval = true;
            return;
        }
        if (DEBUG_STACK) Slog.i(TAG, "removeTask: removing taskId=" + taskId);
        EventLog.writeEvent(EventLogTags.WM_TASK_REMOVED, taskId, "removeTask");
        task.mDeferRemoval = false;
        task.mStack.removeTask(task);
        mTaskIdToTask.delete(task.taskId);
    }

    public void removeTask(int taskId) {
        synchronized (mWindowMap) {
            Task task = mTaskIdToTask.get(taskId);
@@ -4935,14 +4958,14 @@ public class WindowManagerService extends IWindowManager.Stub
                if (DEBUG_STACK) Slog.i(TAG, "removeTask: could not find taskId=" + taskId);
                return;
            }
            final TaskStack stack = task.mStack;
            EventLog.writeEvent(EventLogTags.WM_TASK_REMOVED, taskId, "removeTask");
            stack.removeTask(task);
            removeTaskLocked(task);
        }
    }

    public void addTask(int taskId, int stackId, boolean toTop) {
        synchronized (mWindowMap) {
            if (DEBUG_STACK) Slog.i(TAG, "addTask: adding taskId=" + taskId
                    + " to " + (toTop ? "top" : "bottom"));
            Task task = mTaskIdToTask.get(taskId);
            if (task == null) {
                return;
@@ -9367,7 +9390,7 @@ public class WindowManagerService extends IWindowManager.Stub
                    token.mAppAnimator.animating = false;
                    if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
                            "performLayout: App token exiting now removed" + token);
                    removeAppFromTask(token);
                    removeAppFromTaskLocked(token);
                    exitingAppTokens.remove(i);
                }
            }
@@ -9460,6 +9483,11 @@ public class WindowManagerService extends IWindowManager.Stub
            }
        }

        // Remove all deferred Stacks, tasks, and activities.
        for (int stackNdx = mPendingStacksRemove.size() - 1; stackNdx >= 0; --stackNdx) {
            mPendingStacksRemove.removeAt(stackNdx).checkForDeferredActions();
        }

        setFocusedStackFrame();

        // Check to see if we are now in a state where the screen should
Loading