Allow stacks to hold tasks on various sizes.

Tasks are now resizeable just like stacks. Adjusting the size
of a stack will also adjust the size of all it's containing
tasks. This model allows us to be more flexible
in using stacks as workspaces (like you would have in a
desktop environment) and tasks as the resizeable windows
within the workspace.

Also added "adb shell dumpsys window visible-apps" for
getting the list of visible app windows.

Bug: 22068114
Bug: 19182363

Change-Id: I5bf77063252a5abae4e327f6fc42e607091749f9
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index b2f068b..5974fcf 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -1789,6 +1789,7 @@
         public Rect bounds = new Rect();
         public int[] taskIds;
         public String[] taskNames;
+        public Rect[] taskBounds;
         public int displayId;
 
         @Override
@@ -1805,6 +1806,14 @@
             dest.writeInt(bounds.bottom);
             dest.writeIntArray(taskIds);
             dest.writeStringArray(taskNames);
+            final int boundsCount = taskBounds == null ? 0 : taskBounds.length;
+            dest.writeInt(boundsCount);
+            for (int i = 0; i < boundsCount; i++) {
+                dest.writeInt(taskBounds[i].left);
+                dest.writeInt(taskBounds[i].top);
+                dest.writeInt(taskBounds[i].right);
+                dest.writeInt(taskBounds[i].bottom);
+            }
             dest.writeInt(displayId);
         }
 
@@ -1814,6 +1823,17 @@
                     source.readInt(), source.readInt(), source.readInt(), source.readInt());
             taskIds = source.createIntArray();
             taskNames = source.createStringArray();
+            final int boundsCount = source.readInt();
+            if (boundsCount > 0) {
+                taskBounds = new Rect[boundsCount];
+                for (int i = 0; i < boundsCount; i++) {
+                    taskBounds[i] = new Rect();
+                    taskBounds[i].set(
+                            source.readInt(), source.readInt(), source.readInt(), source.readInt());
+                }
+            } else {
+                taskBounds = null;
+            }
             displayId = source.readInt();
         }
 
@@ -1844,7 +1864,11 @@
             prefix = prefix + "  ";
             for (int i = 0; i < taskIds.length; ++i) {
                 sb.append(prefix); sb.append("taskId="); sb.append(taskIds[i]);
-                        sb.append(": "); sb.append(taskNames[i]); sb.append("\n");
+                        sb.append(": "); sb.append(taskNames[i]);
+                        if (taskBounds != null) {
+                            sb.append(" bounds="); sb.append(taskBounds[i].toShortString());
+                        }
+                        sb.append("\n");
             }
             return sb.toString();
         }
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index e83d635..facaee4 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -799,6 +799,14 @@
             return true;
         }
 
+        case SET_FOCUSED_TASK_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            int taskId = data.readInt();
+            setFocusedStack(taskId);
+            reply.writeNoException();
+            return true;
+        }
+
         case REGISTER_TASK_STACK_LISTENER_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
             IBinder token = data.readStrongBinder();
@@ -2429,6 +2437,15 @@
             return true;
         }
 
+        case GET_TASK_BOUNDS_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            int taskId = data.readInt();
+            Rect r = getTaskBounds(taskId);
+            reply.writeNoException();
+            r.writeToParcel(reply, 0);
+            return true;
+        }
+
         case GET_TASK_DESCRIPTION_ICON_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
             String filename = data.readString();
@@ -3520,6 +3537,18 @@
         return focusedStackId;
     }
     @Override
+    public void setFocusedTask(int taskId) throws RemoteException
+    {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeInt(taskId);
+        mRemote.transact(SET_FOCUSED_TASK_TRANSACTION, data, reply, 0);
+        reply.readException();
+        data.recycle();
+        reply.recycle();
+    }
+    @Override
     public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException
     {
         Parcel data = Parcel.obtain();
@@ -5790,6 +5819,21 @@
     }
 
     @Override
+    public Rect getTaskBounds(int taskId) throws RemoteException
+    {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeInt(taskId);
+        mRemote.transact(GET_TASK_BOUNDS_TRANSACTION, data, reply, 0);
+        reply.readException();
+        Rect rect = Rect.CREATOR.createFromParcel(reply);
+        data.recycle();
+        reply.recycle();
+        return rect;
+    }
+
+    @Override
     public Bitmap getTaskDescriptionIcon(String filename) throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 55cf3462..c3e55f1 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -144,6 +144,7 @@
     public boolean isInHomeStack(int taskId) throws RemoteException;
     public void setFocusedStack(int stackId) throws RemoteException;
     public int getFocusedStackId() throws RemoteException;
+    public void setFocusedTask(int taskId) throws RemoteException;
     public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException;
     public int getTaskForActivity(IBinder token, boolean onlyRoot) throws RemoteException;
     public ContentProviderHolder getContentProvider(IApplicationThread caller,
@@ -486,6 +487,7 @@
             throws RemoteException;
     public void setTaskResizeable(int taskId, boolean resizeable) throws RemoteException;
     public void resizeTask(int taskId, Rect bounds) throws RemoteException;
+    public Rect getTaskBounds(int taskId) throws RemoteException;
     public Bitmap getTaskDescriptionIcon(String filename) throws RemoteException;
 
     public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
@@ -752,7 +754,7 @@
     int GET_PACKAGE_ASK_SCREEN_COMPAT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+127;
     int SET_PACKAGE_ASK_SCREEN_COMPAT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+128;
     int SWITCH_USER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+129;
-    int ___AVAILABLE_1___ = IBinder.FIRST_CALL_TRANSACTION+130;
+    int SET_FOCUSED_TASK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+130;
     int REMOVE_TASK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+131;
     int REGISTER_PROCESS_OBSERVER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+132;
     int UNREGISTER_PROCESS_OBSERVER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+133;
@@ -804,7 +806,7 @@
     int RELEASE_PERSISTABLE_URI_PERMISSION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+180;
     int GET_PERSISTED_URI_PERMISSIONS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+181;
     int APP_NOT_RESPONDING_VIA_PROVIDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+182;
-    // Available
+    int GET_TASK_BOUNDS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+183;
     int GET_ACTIVITY_DISPLAY_ID_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+184;
     int DELETE_ACTIVITY_CONTAINER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+185;
     int SET_PROCESS_MEMORY_TRIM_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+186;