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

Commit d697ceac authored by Wale Ogunwale's avatar Wale Ogunwale
Browse files

Improved back button behavior in multi-window mode.

Pressing the back button on the last activity in a stack that isn't
full screen causes the home stack to move forward and hide all other
visible stacks. This change allows the affected stack to be removed
while keeping the other stack visible.

Bug: 19423645
Change-Id: I30d84f84d525c114ee4993c1e4178af70fe47440
parent 8ee1d64c
Loading
Loading
Loading
Loading
+64 −10
Original line number Diff line number Diff line
@@ -1154,6 +1154,23 @@ final class ActivityStack {
        return null;
    }

    private ActivityStack getNextVisibleStackLocked() {
        ArrayList<ActivityStack> stacks = mStacks;
        final ActivityRecord parent = mActivityContainer.mParentActivity;
        if (parent != null) {
            stacks = parent.task.stack.mStacks;
        }
        if (stacks != null) {
            for (int i = stacks.size() - 1; i >= 0; --i) {
                ActivityStack stack = stacks.get(i);
                if (stack != this && stack.isStackVisibleLocked()) {
                    return stack;
                }
            }
        }
        return null;
    }

    // Checks if any of the stacks above this one has a fullscreen activity behind it.
    // If so, this stack is hidden, otherwise it is visible.
    private boolean isStackVisibleLocked() {
@@ -1482,7 +1499,7 @@ final class ActivityStack {
        return result;
    }

    final boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) {
    private boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) {
        if (ActivityManagerService.DEBUG_LOCKSCREEN) mService.logLockScreen("");

        if (!mService.mBooting && !mService.mBooted) {
@@ -1510,8 +1527,17 @@ final class ActivityStack {

        final TaskRecord prevTask = prev != null ? prev.task : null;
        if (next == null) {
            // There are no more activities!  Let's just start up the
            // Launcher...
            // There are no more activities!
            final String reason = "noMoreActivities";
            if (!mFullscreen) {
                // Try to move focus to the next visible stack with a running activity if this
                // stack is not covering the entire screen.
                final ActivityStack stack = getNextVisibleStackLocked();
                if (adjustFocusToNextVisibleStackLocked(stack, reason)) {
                    return mStackSupervisor.resumeTopActivitiesLocked(stack, prev, null);
                }
            }
            // Let's just start up the Launcher...
            ActivityOptions.abort(options);
            if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: No more activities go home");
            if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
@@ -1519,7 +1545,7 @@ final class ActivityStack {
            final int returnTaskType = prevTask == null || !prevTask.isOverHomeStack() ?
                    HOME_ACTIVITY_TYPE : prevTask.getTaskToReturnTo();
            return isOnHomeDisplay() &&
                    mStackSupervisor.resumeHomeStackTask(returnTaskType, prev, "noMoreActivities");
                    mStackSupervisor.resumeHomeStackTask(returnTaskType, prev, reason);
        }

        next.delayedResume = false;
@@ -2516,20 +2542,45 @@ final class ActivityStack {
    private void adjustFocusedActivityLocked(ActivityRecord r, String reason) {
        if (mStackSupervisor.isFrontStack(this) && mService.mFocusedActivity == r) {
            ActivityRecord next = topRunningActivityLocked(null);
            final String myReason = reason + " adjustFocus";
            if (next != r) {
                final TaskRecord task = r.task;
                if (r.frontOfTask && task == topTask() && task.isOverHomeStack()) {
                    mStackSupervisor.moveHomeStackTaskToTop(task.getTaskToReturnTo(),
                            reason + " adjustFocus");
                    // For non-fullscreen stack, we want to move the focus to the next visible
                    // stack to prevent the home screen from moving to the top and obscuring
                    // other visible stacks.
                    if (!mFullscreen
                            && adjustFocusToNextVisibleStackLocked(null, myReason)) {
                        return;
                    }
                    // Move the home stack to the top if this stack is fullscreen or there is no
                    // other visible stack.
                    mStackSupervisor.moveHomeStackTaskToTop(task.getTaskToReturnTo(), myReason);
                }
            }
            ActivityRecord top = mStackSupervisor.topRunningActivityLocked();

            final ActivityRecord top = mStackSupervisor.topRunningActivityLocked();
            if (top != null) {
                mService.setFocusedActivityLocked(top, reason + " adjustTopFocus");
                mService.setFocusedActivityLocked(top, myReason);
            }
        }
    }

    private boolean adjustFocusToNextVisibleStackLocked(ActivityStack inStack, String reason) {
        final ActivityStack stack = (inStack != null) ? inStack : getNextVisibleStackLocked();
        final String myReason = reason + " adjustFocusToNextVisibleStack";
        if (stack == null) {
            return false;
        }
        final ActivityRecord top = stack.topRunningActivityLocked(null);
        if (top == null) {
            return false;
        }
        stack.moveToFront(myReason);
        mService.setFocusedActivityLocked(top, myReason);
        return true;
    }

    final void stopActivityLocked(ActivityRecord r) {
        if (DEBUG_SWITCH) Slog.d(TAG, "Stopping: " + r);
        if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
@@ -4161,10 +4212,13 @@ final class ActivityStack {
        }

        if (mTaskHistory.isEmpty()) {
            if (DEBUG_STACK) Slog.i(TAG, "removeTask: moving to back stack=" + this);
            if (DEBUG_STACK) Slog.i(TAG, "removeTask: removing stack=" + this);
            final boolean notHomeStack = !isHomeStack();
            if (isOnHomeDisplay()) {
                mStackSupervisor.moveHomeStack(notHomeStack, reason + " leftTaskHistoryEmpty");
                String myReason = reason + " leftTaskHistoryEmpty";
                if (mFullscreen || !adjustFocusToNextVisibleStackLocked(null, myReason)) {
                    mStackSupervisor.moveHomeStack(notHomeStack, myReason);
                }
            }
            if (mStacks != null) {
                mStacks.remove(this);
+12 −11
Original line number Diff line number Diff line
@@ -386,8 +386,8 @@ public final class ActivityStackSupervisor implements DisplayListener {
        return mLastFocusedStack;
    }

    // TODO: Split into two methods isFrontStack for any visible stack and isFrontmostStack for the
    // top of all visible stacks.
    /** Top of all visible stacks. Use {@link ActivityStack#isStackVisibleLocked} to determine if a
     * specific stack is visible or not. */
    boolean isFrontStack(ActivityStack stack) {
        final ActivityRecord parent = stack.mActivityContainer.mParentActivity;
        if (parent != null) {
@@ -535,7 +535,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
    }

    ActivityRecord resumedAppLocked() {
        ActivityStack stack = getFocusedStack();
        ActivityStack stack = mFocusedStack;
        if (stack == null) {
            return null;
        }
@@ -739,7 +739,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
    }

    ActivityRecord topRunningActivityLocked() {
        final ActivityStack focusedStack = getFocusedStack();
        final ActivityStack focusedStack = mFocusedStack;
        ActivityRecord r = focusedStack.topRunningActivityLocked(null);
        if (r != null) {
            return r;
@@ -885,7 +885,7 @@ public final class ActivityStackSupervisor implements DisplayListener {

            final ActivityStack stack;
            if (container == null || container.mStack.isOnHomeDisplay()) {
                stack = getFocusedStack();
                stack = mFocusedStack;
            } else {
                stack = container.mStack;
            }
@@ -1502,7 +1502,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
            outActivity[0] = r;
        }

        final ActivityStack stack = getFocusedStack();
        final ActivityStack stack = mFocusedStack;
        if (voiceSession == null && (stack.mResumedActivity == null
                || stack.mResumedActivity.info.applicationInfo.uid != callingUid)) {
            if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid,
@@ -1706,7 +1706,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
        if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
            ActivityRecord checkedCaller = sourceRecord;
            if (checkedCaller == null) {
                checkedCaller = getFocusedStack().topRunningNonDelayedActivityLocked(notTop);
                checkedCaller = mFocusedStack.topRunningNonDelayedActivityLocked(notTop);
            }
            if (!checkedCaller.realActivity.equals(r.realActivity)) {
                // Caller is not the same as launcher, so always needed.
@@ -2030,7 +2030,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
            // If the activity being launched is the same as the one currently
            // at the top, then we need to check if it should only be launched
            // once.
            ActivityStack topStack = getFocusedStack();
            ActivityStack topStack = mFocusedStack;
            ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop);
            if (top != null && r.resultTo == null) {
                if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
@@ -2482,13 +2482,14 @@ public final class ActivityStackSupervisor implements DisplayListener {
    boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
            Bundle targetOptions) {
        if (targetStack == null) {
            targetStack = getFocusedStack();
            targetStack = mFocusedStack;
        }
        // Do targetStack first.
        boolean result = false;
        if (isFrontStack(targetStack)) {
            result = targetStack.resumeTopActivityLocked(target, targetOptions);
        }

        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
@@ -3068,7 +3069,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
    }

    boolean switchUserLocked(int userId, UserStartedState uss) {
        mUserStackInFront.put(mCurrentUser, getFocusedStack().getStackId());
        mUserStackInFront.put(mCurrentUser, mFocusedStack.getStackId());
        final int restoreStackId = mUserStackInFront.get(userId, HOME_STACK_ID);
        mCurrentUser = userId;

@@ -3192,7 +3193,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
    }

    ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
        return getFocusedStack().getDumpActivitiesLocked(name);
        return mFocusedStack.getDumpActivitiesLocked(name);
    }

    static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage,