Rework thumbnails in activity manager.

We now only keep a thumbnail for the task, not for each
activity.  However if you use FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET,
we will make a new secondary thumbnail for that series of
activities.  There is a new API for the app to get these
secondary thumbnails.

Also set a default thumbnail size for non-xlarge screens
so we have thumbnails on phones.  (We need some smarter
code in the platform for computing the actual thumbnail
dimensions of the current device).  And add a test app
to show recent tasks + thumbnails.

Change-Id: Ic36759f6635522118a2cb7f156662229a610c492
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index b6581e9..a9c9d9c 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -38,6 +38,7 @@
 import com.android.internal.app.IUsageStats;
 import com.android.internal.os.PkgUsageStats;
 
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -396,9 +397,71 @@
     }
 
     /** @hide */
-    public Bitmap getTaskThumbnail(int id) throws SecurityException {
+    public static class TaskThumbnails implements Parcelable {
+        public Bitmap mainThumbnail;
+
+        public int numSubThumbbails;
+
+        /** @hide */
+        public IThumbnailRetriever retriever;
+
+        /** @hide Magic for ActivityManagerService.  Not marshalled */
+        public ArrayList<Bitmap> otherThumbnails;
+
+        public TaskThumbnails() {
+        }
+
+        public Bitmap getSubThumbnail(int index) {
+            try {
+                return retriever.getThumbnail(index);
+            } catch (RemoteException e) {
+                return null;
+            }
+        }
+
+        public int describeContents() {
+            return 0;
+        }
+
+        public void writeToParcel(Parcel dest, int flags) {
+            if (mainThumbnail != null) {
+                dest.writeInt(1);
+                mainThumbnail.writeToParcel(dest, 0);
+            } else {
+                dest.writeInt(0);
+            }
+            dest.writeInt(numSubThumbbails);
+            dest.writeStrongInterface(retriever);
+        }
+
+        public void readFromParcel(Parcel source) {
+            if (source.readInt() != 0) {
+                mainThumbnail = Bitmap.CREATOR.createFromParcel(source);
+            } else {
+                mainThumbnail = null;
+            }
+            numSubThumbbails = source.readInt();
+            retriever = IThumbnailRetriever.Stub.asInterface(source.readStrongBinder());
+        }
+
+        public static final Creator<TaskThumbnails> CREATOR = new Creator<TaskThumbnails>() {
+            public TaskThumbnails createFromParcel(Parcel source) {
+                return new TaskThumbnails(source);
+            }
+            public TaskThumbnails[] newArray(int size) {
+                return new TaskThumbnails[size];
+            }
+        };
+
+        private TaskThumbnails(Parcel source) {
+            readFromParcel(source);
+        }
+    }
+
+    /** @hide */
+    public TaskThumbnails getTaskThumbnails(int id) throws SecurityException {
         try {
-            return ActivityManagerNative.getDefault().getTaskThumbnail(id);
+            return ActivityManagerNative.getDefault().getTaskThumbnails(id);
         } catch (RemoteException e) {
             // System dead, we will be dead too soon!
             return null;
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 6426635..f51e4d0 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -442,10 +442,10 @@
             return true;
         }
         
-        case GET_TASK_THUMBNAIL_TRANSACTION: {
+        case GET_TASK_THUMBNAILS_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
             int id = data.readInt();
-            Bitmap bm = getTaskThumbnail(id);
+            ActivityManager.TaskThumbnails bm = getTaskThumbnails(id);
             reply.writeNoException();
             if (bm != null) {
                 reply.writeInt(1);
@@ -1831,16 +1831,16 @@
         reply.recycle();
         return list;
     }
-    public Bitmap getTaskThumbnail(int id) throws RemoteException {
+    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
         data.writeInt(id);
-        mRemote.transact(GET_TASK_THUMBNAIL_TRANSACTION, data, reply, 0);
+        mRemote.transact(GET_TASK_THUMBNAILS_TRANSACTION, data, reply, 0);
         reply.readException();
-        Bitmap bm = null;
+        ActivityManager.TaskThumbnails bm = null;
         if (reply.readInt() != 0) {
-            bm = Bitmap.CREATOR.createFromParcel(reply);
+            bm = ActivityManager.TaskThumbnails.CREATOR.createFromParcel(reply);
         }
         data.recycle();
         reply.recycle();
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 61e6fc8..cd26a62 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -133,7 +133,7 @@
                          IThumbnailReceiver receiver) throws RemoteException;
     public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
             int flags) throws RemoteException;
-    public Bitmap getTaskThumbnail(int taskId) throws RemoteException;
+    public ActivityManager.TaskThumbnails getTaskThumbnails(int taskId) throws RemoteException;
     public List getServices(int maxNum, int flags) throws RemoteException;
     public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState()
             throws RemoteException;
@@ -515,7 +515,7 @@
     int FORCE_STOP_PACKAGE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+78;
     int KILL_PIDS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+79;
     int GET_SERVICES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+80;
-    int GET_TASK_THUMBNAIL_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+81;
+    int GET_TASK_THUMBNAILS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+81;
     int GET_RUNNING_APP_PROCESSES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+82;
     int GET_DEVICE_CONFIGURATION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+83;
     int PEEK_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+84;
diff --git a/core/java/android/app/IThumbnailRetriever.aidl b/core/java/android/app/IThumbnailRetriever.aidl
new file mode 100644
index 0000000..2a6737d
--- /dev/null
+++ b/core/java/android/app/IThumbnailRetriever.aidl
@@ -0,0 +1,24 @@
+/* Copyright 2011, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+package android.app;
+
+import android.graphics.Bitmap;
+
+/**
+ * System private API for retrieving thumbnails
+ */
+interface IThumbnailRetriever {
+    Bitmap getThumbnail(int index);
+}
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 968d99c..da1c157 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -19,9 +19,9 @@
 -->
 <resources>
     <!-- The width that is used when creating thumbnails of applications. -->
-    <dimen name="thumbnail_width">0dp</dimen>
+    <dimen name="thumbnail_width">64dp</dimen>
     <!-- The height that is used when creating thumbnails of applications. -->
-    <dimen name="thumbnail_height">0dp</dimen>
+    <dimen name="thumbnail_height">100dp</dimen>
     <!-- The standard size (both width and height) of an application icon that
          will be displayed in the app launcher and elsewhere. -->
     <dimen name="app_icon_size">48dip</dimen>