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

Commit 00af9fe6 authored by Craig Mautner's avatar Craig Mautner
Browse files

Modify StackBox and TaskStack methods.

Also add dump() throughout.

Change-Id: I5369d2e71262645d9b1015bd4e72fad395cc7547
parent 27084307
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1991,7 +1991,7 @@ final class ActivityStack {
                group.tokens.add(r.appToken);
            }
        }
        mService.mWindowManager.validateAppTokens(mValidateAppTokens);
        mService.mWindowManager.validateAppTokens(mStackId, mValidateAppTokens);
    }

    /**
+35 −5
Original line number Diff line number Diff line
@@ -80,7 +80,7 @@ class DisplayContent {
     */
    final AppTokenList mExitingAppTokens = new AppTokenList();

    ArrayList<StackBox> mStackBoxes = new ArrayList<StackBox>();
    private ArrayList<StackBox> mStackBoxes = new ArrayList<StackBox>();

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

    /**
     * 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.
     * @return All the Tasks, in order, on this display.
     */
    ArrayList<Task> getTasks() {
        mTmpTasks.clear();
        int numBoxes = mStackBoxes.size();
@@ -126,6 +131,7 @@ class DisplayContent {
        mDisplay.getDisplayInfo(mDisplayInfo);
    }

    /** @return The number of tokens in all of the Tasks on this display. */
    int numTokens() {
        getTasks();
        int count = 0;
@@ -135,6 +141,7 @@ class DisplayContent {
        return count;
    }

    /** Refer to {@link WindowManagerService#createStack(int, int, int, float)} */
    TaskStack createStack(int stackId, int relativeStackId, int position, float weight) {
        TaskStack newStack = null;
        if (mStackBoxes.isEmpty()) {
@@ -150,8 +157,7 @@ class DisplayContent {
                if (position == StackBox.TASK_STACK_GOES_OVER
                        || position == StackBox.TASK_STACK_GOES_UNDER) {
                    // Position indicates a new box is added at top level only.
                    final TaskStack stack = box.mStack;
                    if (stack != null && stack.mStackId == relativeStackId) {
                    if (box.contains(relativeStackId)) {
                        final int offset = position == StackBox.TASK_STACK_GOES_OVER ? 1 : 0;
                        StackBox newBox = new StackBox(this, box.mBounds);
                        newStack = new TaskStack(stackId, newBox);
@@ -167,13 +173,15 @@ class DisplayContent {
                    }
                }
            }
            if (stackBoxNdx >= 0) {
                throw new IllegalArgumentException("createStack: stackId " + stackId + " not found.");
            if (stackBoxNdx < 0) {
                throw new IllegalArgumentException("createStack: stackId " + relativeStackId
                        + " not found.");
            }
        }
        return newStack;
    }

    /** Refer to {@link WindowManagerService#resizeStack(int, float)} */
    boolean resizeStack(int stackId, float weight) {
        int stackBoxNdx;
        for (stackBoxNdx = mStackBoxes.size() - 1; stackBoxNdx >= 0; --stackBoxNdx) {
@@ -185,6 +193,24 @@ class DisplayContent {
        return false;
    }

    /**
     * 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.
     */
    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;
            }
        }
    }

    public void dump(String prefix, PrintWriter pw) {
        pw.print(prefix); pw.print("Display: mDisplayId="); pw.println(mDisplayId);
        final String subPrefix = "  " + prefix;
@@ -209,6 +235,10 @@ class DisplayContent {
            pw.print("-"); pw.print(mDisplayInfo.largestNominalAppWidth);
            pw.print("x"); pw.println(mDisplayInfo.largestNominalAppHeight);
            pw.print(subPrefix); pw.print("layoutNeeded="); pw.println(layoutNeeded);
            for (int boxNdx = 0; boxNdx < mStackBoxes.size(); ++boxNdx) {
                pw.print(prefix); pw.print("StackBox #"); pw.println(boxNdx);
                mStackBoxes.get(boxNdx).dump(prefix + "  ", pw);
            }
            int ndx = numTokens();
            if (ndx > 0) {
                pw.println();
+87 −68
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.server.wm;

import android.graphics.Rect;

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

public class StackBox {
@@ -29,15 +30,32 @@ public class StackBox {
    public static final int TASK_STACK_GOES_OVER = 4;
    public static final int TASK_STACK_GOES_UNDER = 5;

    /** The display this box sits in. */
    final DisplayContent mDisplayContent;

    /** Non-null indicates this is mFirst or mSecond of a parent StackBox. Null indicates this
     * is this entire size of mDisplayContent. */
    StackBox mParent;
    boolean mVertical;

    /** First child, this is null exactly when mStack is non-null. */
    StackBox mFirst;

    /** Second child, this is null exactly when mStack is non-null. */
    StackBox mSecond;
    float mWeight;

    /** Stack of Tasks, this is null exactly when mFirst and mSecond are non-null. */
    TaskStack mStack;

    /** Content limits relative to the DisplayContent this sits in. */
    Rect mBounds;

    /** Relative orientation of mFirst and mSecond. */
    boolean mVertical;

    /** Dirty flag. Something inside this or some descendant of this has changed. */
    boolean layoutNeeded;

    /** Used to keep from reallocating a temporary array to hold the list of Tasks below */
    ArrayList<Task> mTmpTasks = new ArrayList<Task>();

    StackBox(DisplayContent displayContent, Rect bounds) {
@@ -62,6 +80,28 @@ public class StackBox {
        }
    }

    /**
     * Detremine if a particular TaskStack is in this StackBox or any of its descendants.
     * @param stackId The TaskStack being considered.
     * @return true if the specified TaskStack is in this box or its descendants. False otherwise.
     */
    boolean contains(int stackId) {
        if (mStack != null) {
            return mStack.mStackId == stackId;
        }
        return mFirst.contains(stackId) || mSecond.contains(stackId);
    }

    /**
     * Create a new TaskStack relative to a specified one by splitting the StackBox containing
     * the specified TaskStack into two children. The size and position each of the new StackBoxes
     * is determined by the passed parameters.
     * @param stackId The id of the new TaskStack to create.
     * @param relativeStackId The id of the TaskStack to place the new one next to.
     * @param position One of the static TASK_STACK_GOES_xxx positions defined in this class.
     * @param weight The percentage size of the parent StackBox to devote to the new TaskStack.
     * @return The new TaskStack.
     */
    TaskStack split(int stackId, int relativeStackId, int position, float weight) {
        if (mStack != null) {
            if (mStack.mStackId == relativeStackId) {
@@ -112,6 +152,7 @@ public class StackBox {
                mStack = null;
                return stack;
            }
            // Not the intended TaskStack.
            return null;
        }

@@ -123,51 +164,11 @@ public class StackBox {
        return mSecond.split(stackId, relativeStackId, position, weight);
    }

    TaskStack merge(int position) {
        TaskStack stack = null;
        if (mFirst != null) {
            switch (position) {
                default:
                case TASK_STACK_GOES_BEFORE:
                case TASK_STACK_GOES_ABOVE:
                    stack = mFirst.merge(position);
                    stack.merge(mSecond.merge(position));
                    break;
                case TASK_STACK_GOES_AFTER:
                case TASK_STACK_GOES_BELOW:
                    stack = mSecond.merge(position);
                    stack.merge(mFirst.merge(position));
                    break;
            }
            return stack;
        }
        return mStack;
    }

    boolean merge(int stackId, int position, StackBox primary, StackBox secondary) {
        TaskStack stack = primary.mStack;
        if (stack != null && stack.mStackId == stackId) {
            stack.merge(secondary.merge(position));
            mStack = stack;
            mFirst = null;
            mSecond = null;
            return true;
        }
        return false;
    }

    boolean merge(int stackId, int position) {
        if (mFirst != null) {
            if (merge(stackId, position, mFirst, mSecond)
                    || merge(stackId, position, mSecond, mFirst)
                    || mFirst.merge(stackId, position)
                    || mSecond.merge(stackId, position)) {
                return true;
            }
        }
        return false;
    }

    /**
     * @return List of all Tasks underneath this StackBox. The order is currently mFirst followed
     * by mSecond putting mSecond Tasks more recent than mFirst Tasks.
     * TODO: Change to MRU ordering.
     */
    ArrayList<Task> getTasks() {
        mTmpTasks.clear();
        if (mStack != null) {
@@ -179,37 +180,55 @@ public class StackBox {
        return mTmpTasks;
    }

    void absorb(StackBox box) {
        mFirst = box.mFirst;
        mSecond = box.mSecond;
        mStack = box.mStack;
    /** Combine a child StackBox into its parent.
     * @param child The surviving child to be merge up into this StackBox. */
    void absorb(StackBox child) {
        mFirst = child.mFirst;
        mSecond = child.mSecond;
        mStack = child.mStack;
        layoutNeeded = true;
    }

    void removeStack() {
        if (mParent != null) {
    /** Return the stackId of the first mFirst StackBox with a non-null mStack */
    int getStackId() {
        if (mStack != null) {
            return mStack.mStackId;
        }
        return mFirst.getStackId();
    }

    /** Remove this box and propagate its sibling's content up to their parent.
     * @return The first stackId of the resulting StackBox. */
    int removeStack() {
        if (mParent.mFirst == this) {
            mParent.absorb(mParent.mSecond);
        } else {
            mParent.absorb(mParent.mFirst);
        }
        mParent.makeDirty();
        }
        return getStackId();
    }

    boolean addTaskToStack(Task task, int stackId, boolean toTop) {
        if (mStack != null) {
            if (mStack.mStackId == stackId) {
                mStack.addTask(task, toTop);
                return true;
            }
    /** TODO: */
    boolean resize(int stackId, float weight) {
        return false;
    }
        return mFirst.addTaskToStack(task, stackId, toTop)
                || mSecond.addTaskToStack(task, stackId, toTop);
    }

    boolean resize(int stackId, float weight) {
        return false;
    public void dump(String prefix, PrintWriter pw) {
        pw.print(prefix); pw.print("mParent="); pw.println(mParent);
        pw.print(prefix); pw.print("mFirst="); pw.println(mFirst);
        pw.print(prefix); pw.print("mSecond="); pw.println(mSecond);
        pw.print(prefix); pw.print("mBounds="); pw.print(mBounds.toShortString());
            pw.print("mVertical="); pw.print(mVertical);
            pw.print("layoutNeeded="); pw.println(layoutNeeded);
        if (mStack != null) {
            pw.print(prefix); pw.print("mStack="); pw.println(mStack);
            mStack.dump(prefix + "  ", pw);
        } else {
            pw.print(prefix); pw.print("mFirst="); pw.println(mStack);
            mFirst.dump(prefix + "  ", pw);
            pw.print(prefix); pw.print("mSecond="); pw.println(mStack);
            mSecond.dump(prefix + "  ", pw);
        }
    }
}
+34 −3
Original line number Diff line number Diff line
@@ -16,14 +16,22 @@

package com.android.server.wm;

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

public class TaskStack {
    /** Unique identifier */
    final int mStackId;
    final DisplayContent mDisplayContent;

    /** The display this stack sits under. */
    private final DisplayContent mDisplayContent;

    /** The Tasks that define this stack. Oldest Tasks are at the bottom. The ordering must match
     * mTaskHistory in the ActivityStack with the same mStackId */
    private ArrayList<Task> mTasks = new ArrayList<Task>();
    int mLayer;
    StackBox mParent;

    /** The StackBox this sits in. */
    private final StackBox mParent;

    TaskStack(int stackId, StackBox parent) {
        mStackId = stackId;
@@ -46,9 +54,15 @@ public class TaskStack {
        return taskLists;
    }

    /**
     * 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) {
        mParent.makeDirty();
        mTasks.add(toTop ? mTasks.size() : 0, task);
        mDisplayContent.moveStackBox(mStackId, toTop);
    }

    void moveTaskToTop(Task task) {
@@ -61,6 +75,12 @@ public class TaskStack {
        addTask(task, false);
    }

    /**
     * Delete a Task from this stack. If it is the last Task in the stack, remove this stack from
     * its parent StackBox and merge the parent.
     * @param task The Task to delete.
     * @return True if #task was in this stack.
     */
    boolean removeTask(Task task) {
        mParent.makeDirty();
        if (mTasks.remove(task)) {
@@ -72,6 +92,10 @@ public class TaskStack {
        return false;
    }

    int remove() {
        return mParent.removeStack();
    }

    int numTokens() {
        int count = 0;
        for (int taskNdx = mTasks.size() - 1; taskNdx >= 0; --taskNdx) {
@@ -79,4 +103,11 @@ public class TaskStack {
        }
        return count;
    }

    public void dump(String prefix, PrintWriter pw) {
        pw.print(prefix); pw.print("mStackId="); pw.println(mStackId);
        for (int taskNdx = 0; taskNdx < mTasks.size(); ++taskNdx) {
            pw.print(prefix); pw.println(mTasks.get(taskNdx));
        }
    }
}
+15 −3
Original line number Diff line number Diff line
@@ -3169,7 +3169,7 @@ public class WindowManagerService extends IWindowManager.Stub
    // Application Window Tokens
    // -------------------------------------------------------------

    public void validateAppTokens(List<TaskGroup> tasks) {
    public void validateAppTokens(int stackId, List<TaskGroup> tasks) {
        synchronized (mWindowMap) {
            int t = tasks.size() - 1;
            if (t < 0) {
@@ -3186,7 +3186,7 @@ public class WindowManagerService extends IWindowManager.Stub
                return;
            }

            final ArrayList<Task> localTasks = displayContent.getTasks();
            final ArrayList<Task> localTasks = mStackIdToStack.get(stackId).getTasks();
            int taskNdx;
            for (taskNdx = localTasks.size() - 1; taskNdx >= 0 && t >= 0; --taskNdx, --t) {
                AppTokenList localTokens = localTasks.get(taskNdx).mAppTokens;
@@ -3230,6 +3230,10 @@ public class WindowManagerService extends IWindowManager.Stub
        }
    }

    public void validateStackOrder(Integer[] remoteStackIds) {
        // TODO:
    }

    boolean checkCallingPermission(String permission, String func) {
        // Quick check: if the calling permission is me, it's all okay.
        if (Binder.getCallingPid() == Process.myPid()) {
@@ -4685,10 +4689,18 @@ public class WindowManagerService extends IWindowManager.Stub
            TaskStack stack = getDefaultDisplayContentLocked().createStack(stackId,
                    relativeStackId, position, weight);
            mStackIdToStack.put(stackId, stack);
            performLayoutAndPlaceSurfacesLocked();
        }
    }

    public int removeStack(int stackId) {
        final TaskStack stack = mStackIdToStack.get(stackId);
        if (stack != null) {
            mStackIdToStack.delete(stackId);
            return stack.remove();
        }
        return -1;
    }

    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
        synchronized (mWindowMap) {
            Task task = mTaskIdToTask.get(taskId);