Add retrieval of StackBox info for more flexibility

First step in permitting StackBoxes to be manipulated by user.
Necessary for Configuration changes coming down.

Change-Id: I4029926a35e4fdc59a5759fd9e4bae10bb308413
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index dcb2984..603a6ed 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -58,6 +58,8 @@
 import android.app.Activity;
 import android.app.ActivityManager;
 import android.app.ActivityManager.RunningTaskInfo;
+import android.app.ActivityManager.StackBoxInfo;
+import android.app.ActivityManager.StackInfo;
 import android.app.ActivityManagerNative;
 import android.app.ActivityOptions;
 import android.app.ActivityThread;
@@ -6352,7 +6354,7 @@
     }
 
     @Override
-    public List<ActivityManager.StackInfo> getStacks() {
+    public List<StackInfo> getStacks() {
         synchronized (this) {
             ArrayList<ActivityManager.StackInfo> list = new ArrayList<ActivityManager.StackInfo>();
             ArrayList<ActivityStack> stacks = mStackSupervisor.getStacks();
@@ -6381,6 +6383,34 @@
         }
     }
 
+    private void addStackInfoToStackBoxInfo(StackBoxInfo stackBoxInfo, List<StackInfo> stackInfos) {
+        final int stackId = stackBoxInfo.stackId;
+        if (stackId >= 0) {
+            for (StackInfo stackInfo : stackInfos) {
+                if (stackId == stackInfo.stackId) {
+                    stackBoxInfo.stack = stackInfo;
+                    stackInfos.remove(stackInfo);
+                    return;
+                }
+            }
+        } else {
+            addStackInfoToStackBoxInfo(stackBoxInfo.children[0], stackInfos);
+            addStackInfoToStackBoxInfo(stackBoxInfo.children[1], stackInfos);
+        }
+    }
+
+    @Override
+    public List<StackBoxInfo> getStackBoxes() {
+        List<StackBoxInfo> stackBoxInfos = mWindowManager.getStackBoxInfos();
+        synchronized (this) {
+            List<StackInfo> stackInfos = getStacks();
+            for (StackBoxInfo stackBoxInfo : stackBoxInfos) {
+                addStackInfoToStackBoxInfo(stackBoxInfo, stackInfos);
+            }
+        }
+        return stackBoxInfos;
+    }
+
     @Override
     public int getTaskForActivity(IBinder token, boolean onlyRoot) {
         synchronized(this) {
diff --git a/services/java/com/android/server/wm/DisplayContent.java b/services/java/com/android/server/wm/DisplayContent.java
index 0dbcfb8..8ad2ef1 100644
--- a/services/java/com/android/server/wm/DisplayContent.java
+++ b/services/java/com/android/server/wm/DisplayContent.java
@@ -21,6 +21,7 @@
 import static com.android.server.wm.WindowManagerService.DEBUG_VISIBILITY;
 import static com.android.server.wm.WindowManagerService.TAG;
 
+import android.app.ActivityManager.StackBoxInfo;
 import android.graphics.Rect;
 import android.graphics.Region;
 import android.util.Slog;
@@ -284,6 +285,32 @@
         mStackBoxes.remove(box);
     }
 
+    StackBoxInfo getStackBoxInfo(StackBox box) {
+        StackBoxInfo info = new StackBoxInfo();
+        info.stackBoxId = box.mStackBoxId;
+        info.weight = box.mWeight;
+        info.vertical = box.mVertical;
+        info.bounds = new Rect(box.mBounds);
+        if (box.mStack != null) {
+            info.stackId = box.mStack.mStackId;
+            // ActivityManagerService will fill in the StackInfo.
+        } else {
+            info.stackId = -1;
+            info.children = new StackBoxInfo[2];
+            info.children[0] = getStackBoxInfo(box.mFirst);
+            info.children[1] = getStackBoxInfo(box.mSecond);
+        }
+        return info;
+    }
+
+    ArrayList<StackBoxInfo> getStackBoxInfos() {
+        ArrayList<StackBoxInfo> list = new ArrayList<StackBoxInfo>();
+        for (int stackBoxNdx = mStackBoxes.size() - 1; stackBoxNdx >= 0; --stackBoxNdx) {
+            list.add(getStackBoxInfo(mStackBoxes.get(stackBoxNdx)));
+        }
+        return list;
+    }
+
     /**
      * 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.
diff --git a/services/java/com/android/server/wm/StackBox.java b/services/java/com/android/server/wm/StackBox.java
index 3bd1d4c..e2fd105e 100644
--- a/services/java/com/android/server/wm/StackBox.java
+++ b/services/java/com/android/server/wm/StackBox.java
@@ -39,6 +39,11 @@
     /** Used with {@link WindowManagerService#createStack}. Put on a lower layer on display. */
     public static final int TASK_STACK_GOES_UNDER = 5;
 
+    static int sCurrentBoxId = 0;
+
+    /** Unique id for this box */
+    final int mStackBoxId;
+
     /** The service */
     final WindowManagerService mService;
 
@@ -74,6 +79,10 @@
     Rect mTmpRect = new Rect();
 
     StackBox(WindowManagerService service, DisplayContent displayContent, StackBox parent) {
+        synchronized (StackBox.class) {
+            mStackBoxId = sCurrentBoxId++;
+        }
+
         mService = service;
         mDisplayContent = displayContent;
         mParent = parent;
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 3ebe083..d19fb2d 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -43,6 +43,7 @@
 import com.android.server.power.ShutdownThread;
 
 import android.Manifest;
+import android.app.ActivityManager.StackBoxInfo;
 import android.app.ActivityManagerNative;
 import android.app.IActivityManager;
 import android.app.StatusBarManager;
@@ -4882,6 +4883,12 @@
         }
     }
 
+    public ArrayList<StackBoxInfo> getStackBoxInfos() {
+        synchronized(mWindowMap) {
+            return getDefaultDisplayContentLocked().getStackBoxInfos();
+        }
+    }
+
     public Rect getStackBounds(int stackId) {
         DisplayContentsIterator iterator = new DisplayContentsIterator();
         while (iterator.hasNext()) {