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

Commit d5d5d0f4 authored by Craig Mautner's avatar Craig Mautner
Browse files

Prepare WindowManager for multiple stacks.

Create concept of home stack. When moving a new task to the top
move the home stack back.

Change-Id: I2e352722da0c4785b19227713bc30c0850d187b1
parent 9e4f28cf
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -18,6 +18,8 @@ package com.android.server.am;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
import android.app.AppOpsManager;
import android.appwidget.AppWidgetManager;
import com.android.internal.R;
@@ -210,8 +212,6 @@ public final class ActivityManagerService extends ActivityManagerNative
    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
    static final boolean MONITOR_THREAD_CPU_USAGE = false;
    static final int HOME_ACTIVITY_STACK = 0;
    // The flags that are set for all calls we make to the package manager.
    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
@@ -1443,7 +1443,7 @@ public final class ActivityManagerService extends ActivityManagerNative
    public void setWindowManager(WindowManagerService wm) {
        mWindowManager = wm;
        wm.createStack(HOME_ACTIVITY_STACK, -1, StackBox.TASK_STACK_GOES_OVER, 1.0f);
        wm.createStack(HOME_STACK_ID, -1, StackBox.TASK_STACK_GOES_OVER, 1.0f);
    }
    public void startObservingNativeCrashes() {
+1 −1
Original line number Diff line number Diff line
@@ -84,7 +84,7 @@ public class ActivityStackSupervisor {
    private boolean mDismissKeyguardOnNextActivity = false;

    /** Identifier counter for all ActivityStacks */
    private int mLastStackId = 0;
    private int mLastStackId = HOME_STACK_ID;

    /** Task identifier that activities are currently being started in.  Incremented each time a
     * new task is created. */
+31 −15
Original line number Diff line number Diff line
@@ -16,12 +16,12 @@

package com.android.server.wm;

import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;

import android.graphics.Rect;
import android.view.Display;
import android.view.DisplayInfo;

import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;

import java.io.PrintWriter;
import java.util.ArrayList;

@@ -82,8 +82,12 @@ class DisplayContent {
     */
    final AppTokenList mExitingAppTokens = new AppTokenList();

    /** Array containing the home StackBox and possibly one more which would contain apps */
    private ArrayList<StackBox> mStackBoxes = new ArrayList<StackBox>();

    /** True when the home StackBox is at the top of mStackBoxes, false otherwise */
    private boolean mHomeOnTop = true;

    /**
     * Sorted most recent at top, oldest at [0].
     */
@@ -115,6 +119,10 @@ class DisplayContent {
        return mDisplayInfo;
    }

    boolean homeOnTop() {
        return mHomeOnTop;
    }

    /**
     * Retrieve the tasks on this display in stack order from the topmost TaskStack down.
     * Note that the order of TaskStacks in the same StackBox is defined within StackBox.
@@ -129,6 +137,10 @@ class DisplayContent {
        return mTmpTasks;
    }

    TaskStack getHomeStack() {
        return mStackBoxes.get(mHomeOnTop ? mStackBoxes.size() - 1 : 0).mStack;
    }

    public void updateDisplayInfo() {
        mDisplay.getDisplayInfo(mDisplayInfo);
    }
@@ -205,20 +217,24 @@ class DisplayContent {
    }

    /**
     * Reorder a StackBox within mStackBox. The StackBox to reorder is the one containing the
     * specified TaskStack.
     * @param stackId The TaskStack to reorder.
     * @param toTop Move to the top of all StackBoxes if true, to the bottom if false. Only the
     * topmost layer of StackBoxes, those in mStackBoxes can be reordered.
     * Move the home StackBox to the top or bottom of mStackBoxes. That is the only place
     * it is allowed to be. This is a nop if the home StackBox is already in the correct position.
     * @param toTop Move home to the top of mStackBoxes if true, to the bottom if false.
     * @return true if a change was made, false otherwise.
     */
    void moveStackBox(int stackId, boolean toTop) {
        for (int stackBoxNdx = mStackBoxes.size() - 1; stackBoxNdx >= 0; --stackBoxNdx) {
            final StackBox box = mStackBoxes.get(stackBoxNdx);
            if (box.contains(stackId)) {
                mStackBoxes.remove(box);
                mStackBoxes.add(toTop ? mStackBoxes.size() : 0, box);
                return;
    boolean moveHomeStackBox(boolean toTop) {
        switch (mStackBoxes.size()) {
            case 0: throw new RuntimeException("moveHomeStackBox: No home StackBox!");
            case 1: return false; // Only the home StackBox exists.
            case 2: 
                if (mHomeOnTop != toTop) {
                    final StackBox home = mStackBoxes.remove(toTop ? 0 : 1);
                    mStackBoxes.add(toTop ? 1 : 0, home);
                    mHomeOnTop = toTop;
                    return true;
                }
                return false;
            default: throw new RuntimeException("moveHomeStackBox: Too many toplevel StackBoxes!");
        }
    }

+12 −6
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.server.wm;

import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;

import java.io.PrintWriter;
import java.util.ArrayList;

@@ -54,25 +56,29 @@ public class TaskStack {
        return taskLists;
    }

    boolean isHomeStack() {
        return mStackId == HOME_STACK_ID;
    }

    /**
     * Put a Task in this stack. Used for adding and moving.
     * @param task The task to add.
     * @param toTop Whether to add it to the top or bottom.
     */
    void addTask(Task task, boolean toTop) {
    boolean addTask(Task task, boolean toTop) {
        mParent.makeDirty();
        mTasks.add(toTop ? mTasks.size() : 0, task);
        mDisplayContent.moveStackBox(mStackId, toTop);
        return mDisplayContent.moveHomeStackBox(mStackId == HOME_STACK_ID);
    }

    void moveTaskToTop(Task task) {
    boolean moveTaskToTop(Task task) {
        mTasks.remove(task);
        addTask(task, true);
        return addTask(task, true);
    }

    void moveTaskToBottom(Task task) {
    boolean moveTaskToBottom(Task task) {
        mTasks.remove(task);
        addTask(task, false);
        return addTask(task, false);
    }

    /**
+31 −1
Original line number Diff line number Diff line
@@ -4578,6 +4578,23 @@ public class WindowManagerService extends IWindowManager.Stub
        return index;
    }

    private void moveHomeTasksLocked(boolean toTop) {
        final DisplayContent displayContent = getDefaultDisplayContentLocked();
        if (toTop ^ displayContent.homeOnTop()) {
            final ArrayList<Task> tasks = displayContent.getHomeStack().getTasks();
            final int numTasks = tasks.size();
            for (int i = 0; i < numTasks; ++i) {
                if (toTop) {
                    // Keep pulling the bottom task off and moving it to the top.
                    moveTaskToTop(tasks.get(0).taskId);
                } else {
                    // Keep pulling the top task off and moving it to the bottom.
                    moveTaskToBottom(tasks.get(numTasks - 1).taskId);
                }
            }
        }
    }

    private void moveTaskWindowsLocked(Task task) {
        DisplayContent displayContent = task.getDisplayContent();

@@ -4624,7 +4641,20 @@ public class WindowManagerService extends IWindowManager.Stub
                    Slog.e(TAG, "moveTaskToTop: taskId=" + taskId + " not found in mTaskIdToTask");
                    return;
                }
                task.mStack.moveTaskToTop(task);
                final TaskStack stack = task.mStack;
                final DisplayContent displayContent = task.getDisplayContent();
                final boolean isHomeStackTask = stack.isHomeStack();
                final boolean homeIsOnTop = displayContent.homeOnTop();
                if (!isHomeStackTask && homeIsOnTop) {
                    // First move move the home tasks all to the bottom to rearrange the windows.
                    moveHomeTasksLocked(false);
                    // Now move the stack itself.
                    displayContent.moveHomeStackBox(false);
                } else if (isHomeStackTask && !homeIsOnTop) {
                    // Move the stack to the top.
                    displayContent.moveHomeStackBox(true);
                }
                stack.moveTaskToTop(task);
                moveTaskWindowsLocked(task);
            }
        } finally {