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

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

Merge "Support for pinned stack to always be on-top of visible stacks"

parents 41b10518 1e60e0c6
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -5409,7 +5409,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
     * @Return Returns true if the window should show a non client decor.
     **/
    private static boolean hasNonClientDecor(int workspaceId) {
        return workspaceId == FREEFORM_WORKSPACE_STACK_ID || workspaceId == PINNED_STACK_ID;
        return workspaceId == FREEFORM_WORKSPACE_STACK_ID;
    }

    /**
+34 −29
Original line number Diff line number Diff line
@@ -530,16 +530,27 @@ final class ActivityStack {
     * @param task If non-null, the task will be moved to the top of the stack.
     * */
    void moveToFront(String reason, TaskRecord task) {
        if (isAttached()) {
            final ActivityStack lastFocusStack = mStacks.get(mStacks.size() - 1);
            // Need to move this stack to the front before calling
            // {@link ActivityStackSupervisor#setFocusStack} below.
        if (!isAttached()) {
            return;
        }

        mStacks.remove(this);
            mStacks.add(this);
        int addIndex = mStacks.size();

        if (addIndex > 0) {
            final ActivityStack topStack = mStacks.get(addIndex - 1);
            if (topStack.mStackId == PINNED_STACK_ID && topStack != this) {
                // The pinned stack is always the top most stack (always-on-top).
                // So, stack is moved just below the pinned stack.
                addIndex--;
            }
        }

        mStacks.add(addIndex, this);

        // TODO(multi-display): Needs to also work if focus is moving to the non-home display.
        if (isOnHomeDisplay()) {
                mStackSupervisor.setFocusStack(reason, lastFocusStack);
            mStackSupervisor.setFocusStack(reason, this);
        }
        if (task != null) {
            insertTaskAtTop(task, null);
@@ -550,7 +561,6 @@ final class ActivityStack {
            mWindowManager.moveTaskToTop(task.taskId);
        }
    }
    }

    final boolean isAttached() {
        return mStacks != null;
@@ -1304,12 +1314,7 @@ final class ActivityStack {
            return false;
        }

        if (mStackSupervisor.isFrontStack(this)) {
            return true;
        }

        if (mStackId == PINNED_STACK_ID) {
            // Pinned stack is always visible if it exist.
        if (mStackSupervisor.isFrontStack(this) || mStackSupervisor.isFocusedStack(this)) {
            return true;
        }

@@ -2041,7 +2046,7 @@ final class ActivityStack {
            // Have the window manager re-evaluate the orientation of
            // the screen based on the new activity order.
            boolean notUpdated = true;
            if (mStackSupervisor.isFrontStack(this)) {
            if (mStackSupervisor.isFocusedStack(this)) {
                Configuration config = mWindowManager.updateOrientationFromAppTokens(
                        mService.mConfiguration,
                        next.mayFreezeScreenLocked(next.app) ? next.appToken : null);
@@ -2788,7 +2793,7 @@ final class ActivityStack {
    }

    private void adjustFocusedActivityLocked(ActivityRecord r, String reason) {
        if (mStackSupervisor.isFrontStack(this) && mService.mFocusedActivity == r) {
        if (mStackSupervisor.isFocusedStack(this) && mService.mFocusedActivity == r) {
            ActivityRecord next = topRunningActivityLocked();
            final String myReason = reason + " adjustFocus";
            if (next != r) {
@@ -3395,7 +3400,7 @@ final class ActivityStack {
        if (task != null && task.removeActivity(r)) {
            if (DEBUG_STACK) Slog.i(TAG_STACK,
                    "removeActivityFromHistoryLocked: last activity removed from " + this);
            if (mStackSupervisor.isFrontStack(this) && task == topTask() &&
            if (mStackSupervisor.isFocusedStack(this) && task == topTask() &&
                    task.isOverHomeStack()) {
                mStackSupervisor.moveHomeStackTaskToTop(task.getTaskToReturnTo(), reason);
            }
@@ -4569,7 +4574,7 @@ final class ActivityStack {
        if (mTaskHistory.isEmpty()) {
            if (DEBUG_STACK) Slog.i(TAG_STACK, "removeTask: removing stack=" + this);
            // We only need to adjust focused stack if this stack is in focus.
            if (isOnHomeDisplay() && mStackSupervisor.isFrontStack(this)) {
            if (isOnHomeDisplay() && mStackSupervisor.isFocusedStack(this)) {
                String myReason = reason + " leftTaskHistoryEmpty";
                if (mFullscreen || !adjustFocusToNextVisibleStackLocked(null, myReason)) {
                    mStackSupervisor.moveHomeStackToFront(myReason);
@@ -4677,7 +4682,7 @@ final class ActivityStack {
            return;
        }

        final boolean wasFocused = mStackSupervisor.isFrontStack(prevStack)
        final boolean wasFocused = mStackSupervisor.isFocusedStack(prevStack)
                && (mStackSupervisor.topRunningActivityLocked() == r);
        final boolean wasResumed = wasFocused && (prevStack.mResumedActivity == r);

+27 −26
Original line number Diff line number Diff line
@@ -458,10 +458,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
        return mLastFocusedStack;
    }

    /** Top of all visible stacks is/should always be equal to the focused stack.
     * Use {@link ActivityStack#isStackVisibleLocked} to determine if a specific
     * stack is visible or not. */
    boolean isFrontStack(ActivityStack stack) {
    boolean isFocusedStack(ActivityStack stack) {
        if (stack == null) {
            return false;
        }
@@ -473,19 +470,23 @@ public final class ActivityStackSupervisor implements DisplayListener {
        return stack == mFocusedStack;
    }

    void setFocusStack(String reason, ActivityStack lastFocusedStack) {
        ArrayList<ActivityStack> stacks = mHomeStack.mStacks;
        final int topNdx = stacks.size() - 1;
        if (topNdx <= 0) {
            return;
    /** The top most stack. */
    boolean isFrontStack(ActivityStack stack) {
        if (stack == null) {
            return false;
        }

        final ActivityStack topStack = stacks.get(topNdx);
        mFocusedStack = topStack;
        if (lastFocusedStack != null) {
            mLastFocusedStack = lastFocusedStack;
        final ActivityRecord parent = stack.mActivityContainer.mParentActivity;
        if (parent != null) {
            stack = parent.task.stack;
        }
        return stack == mHomeStack.mStacks.get((mHomeStack.mStacks.size() - 1));
    }

    void setFocusStack(String reason, ActivityStack focusedStack) {
        mLastFocusedStack = mFocusedStack;
        mFocusedStack = focusedStack;

        EventLogTags.writeAmFocusedStack(
                mCurrentUser, mFocusedStack == null ? -1 : mFocusedStack.getStackId(),
                mLastFocusedStack == null ? -1 : mLastFocusedStack.getStackId(), reason);
@@ -642,7 +643,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
                final ActivityStack stack = stacks.get(stackNdx);
                if (!isFrontStack(stack)) {
                if (!isFocusedStack(stack)) {
                    continue;
                }
                ActivityRecord hr = stack.topRunningActivityLocked();
@@ -673,7 +674,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
                final ActivityStack stack = stacks.get(stackNdx);
                if (!isFrontStack(stack) || stack.numActivities() == 0) {
                if (!isFocusedStack(stack) || stack.numActivities() == 0) {
                    continue;
                }
                final ActivityRecord resumedActivity = stack.mResumedActivity;
@@ -692,7 +693,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
                final ActivityStack stack = stacks.get(stackNdx);
                if (isFrontStack(stack)) {
                if (isFocusedStack(stack)) {
                    final ActivityRecord r = stack.mResumedActivity;
                    if (r != null && r.state != RESUMED) {
                        return false;
@@ -737,7 +738,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
                final ActivityStack stack = stacks.get(stackNdx);
                if (!isFrontStack(stack) && stack.mResumedActivity != null) {
                if (!isFocusedStack(stack) && stack.mResumedActivity != null) {
                    if (DEBUG_STATES) Slog.d(TAG_STATES, "pauseBackStacks: stack=" + stack +
                            " mResumedActivity=" + stack.mResumedActivity);
                    someActivityPaused |= stack.startPausingLocked(userLeaving, false, resuming,
@@ -1374,7 +1375,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
        // launching the initial activity (that is, home), so that it can have
        // a chance to initialize itself while in the background, making the
        // switch back to it faster and look better.
        if (isFrontStack(stack)) {
        if (isFocusedStack(stack)) {
            mService.startSetupActivityLocked();
        }

@@ -2621,7 +2622,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
            r.idle = true;

            //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
            if (isFrontStack(r.task.stack) || fromTimeout) {
            if (isFocusedStack(r.task.stack) || fromTimeout) {
                booting = checkFinishBootingLocked();
            }
        }
@@ -2773,7 +2774,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
                final ActivityStack stack = stacks.get(stackNdx);
                if (isFrontStack(stack)) {
                if (isFocusedStack(stack)) {
                    if (stack.mResumedActivity != null) {
                        fgApp = stack.mResumedActivity.app;
                    } else if (stack.mPausingActivity != null) {
@@ -2805,7 +2806,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
        }
        // Do targetStack first.
        boolean result = false;
        if (isFrontStack(targetStack)) {
        if (isFocusedStack(targetStack)) {
            result = targetStack.resumeTopActivityLocked(target, targetOptions);
        }

@@ -2817,7 +2818,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
                    // Already started above.
                    continue;
                }
                if (isFrontStack(stack)) {
                if (isFocusedStack(stack)) {
                    stack.resumeTopActivityLocked(null);
                }
            }
@@ -3243,7 +3244,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
    ActivityStack moveTaskToStackUncheckedLocked(
            TaskRecord task, int stackId, boolean toTop, boolean forceFocus, String reason) {
        final ActivityRecord r = task.getTopActivity();
        final boolean wasFocused = isFrontStack(task.stack) && (topRunningActivityLocked() == r);
        final boolean wasFocused = isFocusedStack(task.stack) && (topRunningActivityLocked() == r);
        final boolean wasResumed = wasFocused && (task.stack.mResumedActivity == r);

        final boolean resizeable = task.mResizeable;
@@ -3469,7 +3470,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
                final ActivityStack stack = stacks.get(stackNdx);
                stack.awakeFromSleepingLocked();
                if (isFrontStack(stack)) {
                if (isFocusedStack(stack)) {
                    resumeTopActivitiesLocked();
                }
            }
@@ -3536,7 +3537,7 @@ public final class ActivityStackSupervisor implements DisplayListener {

    boolean reportResumedActivityLocked(ActivityRecord r) {
        final ActivityStack stack = r.task.stack;
        if (isFrontStack(stack)) {
        if (isFocusedStack(stack)) {
            mService.updateUsageStats(r, true);
        }
        if (allResumedActivitiesComplete()) {
@@ -3829,7 +3830,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
                final ActivityStack stack = stacks.get(stackNdx);
                final ActivityRecord r = stack.topRunningActivityLocked();
                final ActivityState state = r == null ? DESTROYED : r.state;
                if (isFrontStack(stack)) {
                if (isFocusedStack(stack)) {
                    if (r == null) Slog.e(TAG,
                            "validateTop...: null top activity, stack=" + stack);
                    else {
+22 −2
Original line number Diff line number Diff line
@@ -18,7 +18,7 @@ package com.android.server.wm;

import static android.app.ActivityManager.DOCKED_STACK_ID;
import static android.app.ActivityManager.HOME_STACK_ID;

import static android.app.ActivityManager.PINNED_STACK_ID;
import static com.android.server.wm.WindowManagerService.DEBUG_VISIBILITY;
import static com.android.server.wm.WindowManagerService.TAG;
import static com.android.server.wm.WindowState.RESIZE_HANDLE_WIDTH_IN_DP;
@@ -243,10 +243,30 @@ class DisplayContent {
    }

    void moveStack(TaskStack stack, boolean toTop) {
        if (stack.mStackId == PINNED_STACK_ID && !toTop) {
            // Pinned stack is always-on-top silly...
            Slog.w(TAG, "Ignoring move of always-on-top stack=" + stack + " to bottom");
            return;
        }

        if (!mStacks.remove(stack)) {
            Slog.wtf(TAG, "moving stack that was not added: " + stack, new Throwable());
        }
        mStacks.add(toTop ? mStacks.size() : 0, stack);

        int addIndex = toTop ? mStacks.size() : 0;

        if (toTop
                && mService.isStackVisibleLocked(PINNED_STACK_ID)
                && stack.mStackId != PINNED_STACK_ID) {
            // The pinned stack is always the top most stack (always-on-top) when it is visible.
            // So, stack is moved just below the pinned stack.
            addIndex--;
            TaskStack topStack = mStacks.get(addIndex);
            if (topStack.mStackId != PINNED_STACK_ID) {
                throw new IllegalStateException("Pinned stack isn't top stack??? " + mStacks);
            }
        }
        mStacks.add(addIndex, stack);
    }

    void detachStack(TaskStack stack) {
+8 −6
Original line number Diff line number Diff line
@@ -3283,10 +3283,8 @@ public class WindowManagerService extends IWindowManager.Stub
            }
        }

        final TaskStack dockedStack = mStackIdToStack.get(DOCKED_STACK_ID);
        final TaskStack freeformStack = mStackIdToStack.get(FREEFORM_WORKSPACE_STACK_ID);
        if ((dockedStack != null && dockedStack.isVisibleLocked())
                || (freeformStack != null && freeformStack.isVisibleLocked())) {
        if (isStackVisibleLocked(DOCKED_STACK_ID)
                || isStackVisibleLocked(FREEFORM_WORKSPACE_STACK_ID)) {
            // We don't let app affect the system orientation when in freeform or docked mode since
            // they don't occupy the entire display and their request can conflict with other apps.
            return SCREEN_ORIENTATION_UNSPECIFIED;
@@ -4517,6 +4515,11 @@ public class WindowManagerService extends IWindowManager.Stub
        }
    }

    boolean isStackVisibleLocked(int stackId) {
        final TaskStack stack = mStackIdToStack.get(stackId);
        return (stack != null && stack.isVisibleLocked());
    }

    public void setDockedStackCreateMode(int mode) {
        synchronized (mWindowMap) {
            sDockedStackCreateMode = mode;
@@ -10219,8 +10222,7 @@ public class WindowManagerService extends IWindowManager.Stub
        @Override
        public boolean isStackVisible(int stackId) {
            synchronized (mWindowMap) {
                final TaskStack stack = mStackIdToStack.get(stackId);
                return (stack != null && stack.isVisibleLocked());
                return WindowManagerService.this.isStackVisibleLocked(stackId);
            }
        }
    }