Fix issue #3258849: Grab thumbnail when exiting an app via back

Also issue #3281400: Rotating a retained instance fragment leaks the fragment manager

And turn off fragment debug logging.

Change-Id: Ibdd7db82bb35618021bcba421ba92ced7cd691c2
diff --git a/api/current.xml b/api/current.xml
index 5bdb3b1..2c971ec 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -24439,6 +24439,17 @@
  visibility="public"
 >
 </field>
+<field name="RECENT_IGNORE_UNAVAILABLE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="RECENT_WITH_EXCLUDED"
  type="int"
  transient="false"
@@ -24450,6 +24461,17 @@
  visibility="public"
 >
 </field>
+<field name="TASKS_GET_THUMBNAILS"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="4096"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 </class>
 <class name="ActivityManager.MemoryInfo"
  extends="java.lang.Object"
@@ -24818,6 +24840,16 @@
  visibility="public"
 >
 </field>
+<field name="description"
+ type="java.lang.CharSequence"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="id"
  type="int"
  transient="false"
@@ -24838,6 +24870,16 @@
  visibility="public"
 >
 </field>
+<field name="thumbnail"
+ type="android.graphics.Bitmap"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 </class>
 <class name="ActivityManager.RunningAppProcessInfo"
  extends="java.lang.Object"
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index e168034..ebdc7fd 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -93,6 +93,17 @@
          * implementation that the alias referred to.  Otherwise, this is null.
          */
         public ComponentName origActivity;
+
+        /**
+         * Thumbnail representation of the task's last state.  Must
+         * use {@link ActivityManager#TASKS_GET_THUMBNAILS} to have this set.
+         */
+        public Bitmap thumbnail;
+
+        /**
+         * Description of the task's last state.
+         */
+        public CharSequence description;
         
         public RecentTaskInfo() {
         }
@@ -110,6 +121,14 @@
                 dest.writeInt(0);
             }
             ComponentName.writeToParcel(origActivity, dest);
+            if (thumbnail != null) {
+                dest.writeInt(1);
+                thumbnail.writeToParcel(dest, 0);
+            } else {
+                dest.writeInt(0);
+            }
+            TextUtils.writeToParcel(description, dest,
+                    Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
         }
 
         public void readFromParcel(Parcel source) {
@@ -120,6 +139,12 @@
                 baseIntent = null;
             }
             origActivity = ComponentName.readFromParcel(source);
+            if (source.readInt() != 0) {
+                thumbnail = Bitmap.CREATOR.createFromParcel(source);
+            } else {
+                thumbnail = null;
+            }
+            description = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
         }
         
         public static final Creator<RecentTaskInfo> CREATOR
@@ -145,11 +170,16 @@
     public static final int RECENT_WITH_EXCLUDED = 0x0001;
     
     /**
-     * @hide
-     * TODO: Make this public.  Provides a list that does not contain any
+     * Provides a list that does not contain any
      * recent tasks that currently are not available to the user.
      */
     public static final int RECENT_IGNORE_UNAVAILABLE = 0x0002;
+
+    /**
+     * Flag for use with {@link #getRecentTasks}: also return the thumbnail
+     * bitmap (if available) for each recent task.
+     */
+    public static final int TASKS_GET_THUMBNAILS = 0x0001000;
     
     /**
      * Return a list of the tasks that the user has recently launched, with
@@ -158,6 +188,9 @@
      * @param maxNum The maximum number of entries to return in the list.  The
      * actual number returned may be smaller, depending on how many tasks the
      * user has started and the maximum number the system can remember.
+     * @param flags Information about what to return.  May be any combination
+     * of {@link #RECENT_WITH_EXCLUDED}, {@link #RECENT_IGNORE_UNAVAILABLE},
+     * and {@link #TASKS_GET_THUMBNAILS}.
      * 
      * @return Returns a list of RecentTaskInfo records describing each of
      * the recent tasks.
@@ -203,7 +236,8 @@
         public ComponentName topActivity;
 
         /**
-         * Thumbnail representation of the task's current state.
+         * Thumbnail representation of the task's current state.  Must
+         * use {@link ActivityManager#TASKS_GET_THUMBNAILS} to have this set.
          */
         public Bitmap thumbnail;
 
@@ -273,7 +307,7 @@
             readFromParcel(source);
         }
     }
-
+    
     /**
      * Return a list of the tasks that are currently running, with
      * the most recent being first and older ones after in order.  Note that
diff --git a/core/java/android/app/BackStackRecord.java b/core/java/android/app/BackStackRecord.java
index b47aefd..33b747c 100644
--- a/core/java/android/app/BackStackRecord.java
+++ b/core/java/android/app/BackStackRecord.java
@@ -233,19 +233,25 @@
             Op op = mHead;
             int num = 0;
             while (op != null) {
-                writer.print(prefix); writer.print("  #"); writer.print(num);
-                        writer.print(" "); writer.print(op); writer.println(":");
+                writer.print(prefix); writer.print("  Op #"); writer.print(num);
+                        writer.println(":");
                 writer.print(innerPrefix); writer.print("cmd="); writer.print(op.cmd);
-                        writer.println("fragment="); writer.println(op.fragment);
+                        writer.print(" fragment="); writer.println(op.fragment);
                 if (op.enterAnim != 0 || op.exitAnim != 0) {
                     writer.print(prefix); writer.print("enterAnim="); writer.print(op.enterAnim);
                             writer.print(" exitAnim="); writer.println(op.exitAnim);
                 }
                 if (op.removed != null && op.removed.size() > 0) {
                     for (int i=0; i<op.removed.size(); i++) {
-                        writer.print(innerPrefix); writer.println("Removed:");
-                        writer.print(innerPrefix); writer.print("  #"); writer.print(num);
-                                writer.print(": "); writer.println(op.removed.get(i));
+                        writer.print(innerPrefix);
+                        if (op.removed.size() == 1) {
+                            writer.print("Removed: ");
+                        } else {
+                            writer.println("Removed:");
+                            writer.print(innerPrefix); writer.print("  #"); writer.print(num);
+                                    writer.print(": "); 
+                        }
+                        writer.println(op.removed.get(i));
                     }
                 }
                 op = op.next;
diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java
index eaa1e05..348149e 100644
--- a/core/java/android/app/Fragment.java
+++ b/core/java/android/app/Fragment.java
@@ -526,7 +526,16 @@
     @Override
     public String toString() {
         StringBuilder sb = new StringBuilder(128);
-        sb.append("Fragment{");
+        String simpleName = getClass().getSimpleName();
+        if (simpleName == null || simpleName.isEmpty()) {
+            simpleName = getClass().getName();
+            int end = simpleName.lastIndexOf('.');
+            if (end > 0) {
+                simpleName = simpleName.substring(end+1);
+            }
+        }
+        sb.append(simpleName);
+        sb.append("{");
         sb.append(Integer.toHexString(System.identityHashCode(this)));
         if (mIndex >= 0) {
             sb.append(" #");
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index 196e7b2..488b673 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -293,7 +293,7 @@
  * Container for fragments associated with an activity.
  */
 final class FragmentManagerImpl extends FragmentManager {
-    static final boolean DEBUG = true;
+    static final boolean DEBUG = false;
     static final String TAG = "FragmentManager";
     
     static final String TARGET_REQUEST_CODE_STATE_TAG = "android:target_req_state";
@@ -562,6 +562,7 @@
                         }
                     }
                     f.mActivity = mActivity;
+                    f.mFragmentManager = mActivity.mFragments;
                     f.mCalled = false;
                     f.onAttach(mActivity);
                     if (!f.mCalled) {
@@ -737,6 +738,7 @@
                         }
                         f.mImmediateActivity = null;
                         f.mActivity = null;
+                        f.mFragmentManager = null;
                     }
             }
         }
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 2c8ca8b..8bdc1f8 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -186,5 +186,5 @@
 	/**
 	 * Create a screenshot of the applications currently displayed.
 	 */
-	Bitmap screenshotApplications(int maxWidth, int maxHeight);
+	Bitmap screenshotApplications(IBinder appToken, int maxWidth, int maxHeight);
 }
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java
index 86cd3b0..b8d72a6 100644
--- a/core/java/android/view/Surface.java
+++ b/core/java/android/view/Surface.java
@@ -377,17 +377,29 @@
     }
     
     /**
+     * Like {@link #screenshot(int, int, int, int)} but includes all
+     * Surfaces in the screenshot.
+     *
+     * @hide
+     */
+    public static native Bitmap screenshot(int width, int height);
+    
+    /**
      * Copy the current screen contents into a bitmap and return it.
      *
      * @param width The desired width of the returned bitmap; the raw
      * screen will be scaled down to this size.
      * @param height The desired height of the returned bitmap; the raw
      * screen will be scaled down to this size.
+     * @param minLayer The lowest (bottom-most Z order) surface layer to
+     * include in the screenshot.
+     * @param maxLayer The highest (top-most Z order) surface layer to
+     * include in the screenshot.
      * @return Returns a Bitmap containing the screen contents.
      *
      * @hide
      */
-    public static native Bitmap screenshot(int width, int height);
+    public static native Bitmap screenshot(int width, int height, int minLayer, int maxLayer);
 
     /**
      * set surface parameters.
diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp
index 206e320..8c30987 100644
--- a/core/jni/android_view_Surface.cpp
+++ b/core/jni/android_view_Surface.cpp
@@ -449,9 +449,11 @@
         SkSafeUnref(fCTable);
     }
 
-    status_t update(int width, int height) {
+    status_t update(int width, int height, int minLayer, int maxLayer, bool allLayers) {
         status_t res = (width > 0 && height > 0)
-                ? mScreenshot.update(width, height)
+                ? (allLayers
+                        ? mScreenshot.update(width, height)
+                        : mScreenshot.update(width, height, minLayer, maxLayer))
                 : mScreenshot.update();
         if (res != NO_ERROR) {
             return res;
@@ -493,10 +495,11 @@
     typedef SkPixelRef INHERITED;
 };
 
-static jobject Surface_screenshot(JNIEnv* env, jobject clazz, jint width, jint height)
+static jobject doScreenshot(JNIEnv* env, jobject clazz, jint width, jint height,
+        jint minLayer, jint maxLayer, bool allLayers)
 {
     ScreenshotPixelRef* pixels = new ScreenshotPixelRef(NULL);
-    if (pixels->update(width, height) != NO_ERROR) {
+    if (pixels->update(width, height, minLayer, maxLayer, allLayers) != NO_ERROR) {
         delete pixels;
         return 0;
     }
@@ -525,6 +528,17 @@
     return GraphicsJNI::createBitmap(env, bitmap, false, NULL);
 }
 
+static jobject Surface_screenshotAll(JNIEnv* env, jobject clazz, jint width, jint height)
+{
+    return doScreenshot(env, clazz, width, height, 0, 0, true);
+}
+
+static jobject Surface_screenshot(JNIEnv* env, jobject clazz, jint width, jint height,
+        jint minLayer, jint maxLayer, bool allLayers)
+{
+    return doScreenshot(env, clazz, width, height, minLayer, maxLayer, false);
+}
+
 static void Surface_setLayer(
         JNIEnv* env, jobject clazz, jint zorder)
 {
@@ -750,7 +764,8 @@
     {"setOrientation",      "(III)V", (void*)Surface_setOrientation },
     {"freezeDisplay",       "(I)V", (void*)Surface_freezeDisplay },
     {"unfreezeDisplay",     "(I)V", (void*)Surface_unfreezeDisplay },
-    {"screenshot",          "(II)Landroid/graphics/Bitmap;", (void*)Surface_screenshot },
+    {"screenshot",          "(II)Landroid/graphics/Bitmap;", (void*)Surface_screenshotAll },
+    {"screenshot",          "(IIII)Landroid/graphics/Bitmap;", (void*)Surface_screenshot },
     {"setLayer",            "(I)V", (void*)Surface_setLayer },
     {"setPosition",         "(II)V",(void*)Surface_setPosition },
     {"setSize",             "(II)V",(void*)Surface_setSize },
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentApplicationsActivity.java b/packages/SystemUI/src/com/android/systemui/recent/RecentApplicationsActivity.java
index a98ef0b..8c6eefb3 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentApplicationsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentApplicationsActivity.java
@@ -409,7 +409,8 @@
     }
 
     void updateRunningTasks() {
-        mRunningTaskList = mActivityManager.getRunningTasks(MAX_TASKS, 0, mThumbnailReceiver);
+        mRunningTaskList = mActivityManager.getRunningTasks(MAX_TASKS,
+                ActivityManager.TASKS_GET_THUMBNAILS, mThumbnailReceiver);
         if (DBG) Log.v(TAG, "Portrait: " + mPortraitMode);
         for (RunningTaskInfo r : mRunningTaskList) {
             if (r.thumbnail != null) {
@@ -440,7 +441,8 @@
         final ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
 
         final List<ActivityManager.RecentTaskInfo> recentTasks =
-                am.getRecentTasks(MAX_TASKS, ActivityManager.RECENT_IGNORE_UNAVAILABLE);
+                am.getRecentTasks(MAX_TASKS, ActivityManager.RECENT_IGNORE_UNAVAILABLE
+                        | ActivityManager.TASKS_GET_THUMBNAILS);
 
         ActivityInfo homeInfo = new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME)
                     .resolveActivityInfo(pm, 0);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/RecentAppsPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/RecentAppsPanel.java
index 87d73ad..1301329 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/RecentAppsPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/RecentAppsPanel.java
@@ -58,7 +58,7 @@
     private static final boolean DEBUG = TabletStatusBar.DEBUG;
     private static final int DISPLAY_TASKS_PORTRAIT = 8;
     private static final int DISPLAY_TASKS_LANDSCAPE = 5; // number of recent tasks to display
-    private static final int MAX_TASKS = 2 * DISPLAY_TASKS_PORTRAIT; // allow extra for non-apps
+    private static final int MAX_TASKS = DISPLAY_TASKS_PORTRAIT + 2; // allow extra for non-apps
     private TabletStatusBar mBar;
     private TextView mNoRecents;
     private LinearLayout mRecentsContainer;
@@ -80,8 +80,8 @@
         int position; // position in list
 
         public ActivityDescription(Bitmap _thumbnail,
-                Drawable _icon, String _label, String _desc, Intent _intent, int _id, int _pos,
-                String _packageName)
+                Drawable _icon, String _label, CharSequence _desc, Intent _intent,
+                int _id, int _pos, String _packageName)
         {
             thumbnail = _thumbnail;
             icon = _icon;
@@ -94,21 +94,6 @@
         }
     };
 
-    private final IThumbnailReceiver mThumbnailReceiver = new IThumbnailReceiver.Stub() {
-
-        public void finished() throws RemoteException {
-        }
-
-        public void newThumbnail(final int id, final Bitmap bitmap, CharSequence description)
-                throws RemoteException {
-            ActivityDescription info = findActivityDescription(id);
-            if (info != null) {
-                info.thumbnail = bitmap;
-                info.description = description;
-            }
-        }
-    };
-
     public boolean isInContentArea(int x, int y) {
         final int l = mRecentsContainer.getPaddingLeft();
         final int r = mRecentsContainer.getWidth() - mRecentsContainer.getPaddingRight();
@@ -201,7 +186,8 @@
                 mContext.getSystemService(Context.ACTIVITY_SERVICE);
 
         final List<ActivityManager.RecentTaskInfo> recentTasks =
-                am.getRecentTasks(MAX_TASKS, ActivityManager.RECENT_IGNORE_UNAVAILABLE);
+                am.getRecentTasks(MAX_TASKS, ActivityManager.RECENT_IGNORE_UNAVAILABLE
+                        | ActivityManager.TASKS_GET_THUMBNAILS);
 
         ActivityInfo homeInfo = new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME)
                     .resolveActivityInfo(pm, 0);
@@ -234,7 +220,8 @@
                 if (title != null && title.length() > 0 && icon != null) {
                     if (DEBUG) Log.v(TAG, "creating activity desc for id=" + id + ", label=" + title);
                     ActivityDescription item = new ActivityDescription(
-                            null, icon, title, null, intent, id, index, info.packageName);
+                            crop(recentInfo.thumbnail), icon, title, recentInfo.description,
+                            intent, id, index, info.packageName);
                     activityDescriptions.add(item);
                     ++index;
                 } else {
@@ -258,28 +245,8 @@
         return desc;
     }
 
-    private void getThumbnails(ArrayList<ActivityDescription> tasks) {
-        ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
-        List<RunningTaskInfo> runningTasks = am.getRunningTasks(MAX_TASKS, 0, mThumbnailReceiver);
-        for (RunningTaskInfo runningTaskInfo : runningTasks) {
-            // Find the activity description associted with the given id
-            ActivityDescription desc = findActivityDescription(runningTaskInfo.id);
-            if (desc != null) {
-                if (runningTaskInfo.thumbnail != null) {
-                    desc.thumbnail = crop(runningTaskInfo.thumbnail);
-                    desc.description = runningTaskInfo.description;
-                } else {
-                    if (DEBUG) Log.v(TAG, "*** RUNNING THUMBNAIL WAS NULL ***");
-                }
-            } else {
-                if (DEBUG) Log.v(TAG, "Couldn't find ActivityDesc for id=" + runningTaskInfo.id);
-            }
-        }
-    }
-
     private void refreshApplicationList() {
         mActivityDescriptions = getRecentTasks();
-        getThumbnails(mActivityDescriptions);
         updateUiElements(getResources().getConfiguration(), true);
     }
 
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index 8e33011..ba7692d 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -4908,7 +4908,7 @@
         SystemProperties.set(StrictMode.VISUAL_PROPERTY, value);
     }
 
-    public Bitmap screenshotApplications(int maxWidth, int maxHeight) {
+    public Bitmap screenshotApplications(IBinder appToken, int maxWidth, int maxHeight) {
         if (!checkCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
                 "screenshotApplications()")) {
             throw new SecurityException("Requires READ_FRAME_BUFFER permission");
@@ -4916,6 +4916,8 @@
 
         Bitmap rawss;
 
+        int maxLayer = 0;
+        boolean foundApp;
         final Rect frame = new Rect();
 
         float scale;
@@ -4939,6 +4941,13 @@
                 if (ws.mLayer >= aboveAppLayer) {
                     break;
                 }
+                if (appToken != null && (ws.mAppToken == null
+                        || ws.mAppToken.token != appToken)) {
+                    continue;
+                }
+                if (maxLayer < ws.mAnimLayer) {
+                    maxLayer = ws.mAnimLayer;
+                }
                 final Rect wf = ws.mFrame;
                 final Rect cr = ws.mContentInsets;
                 int left = wf.left + cr.left;
@@ -4978,7 +4987,7 @@
                 dh = tmp;
                 rot = (rot == Surface.ROTATION_90) ? Surface.ROTATION_270 : Surface.ROTATION_90;
             }
-            rawss = Surface.screenshot(dw, dh);
+            rawss = Surface.screenshot(dw, dh, 0, maxLayer);
         }
 
         Bitmap bm = Bitmap.createBitmap(sw, sh, rawss.getConfig());
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 44029cd..a26fe5f 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -3808,8 +3808,14 @@
                 r.haveState = true;
                 if (thumbnail != null) {
                     r.thumbnail = thumbnail;
+                    if (r.task != null) {
+                        r.task.lastThumbnail = r.thumbnail;
+                    }
                 }
                 r.description = description;
+                if (r.task != null) {
+                    r.task.lastDescription = r.description;
+                }
                 r.stopped = true;
                 r.state = ActivityState.STOPPED;
                 if (!r.finishing) {
@@ -4826,9 +4832,10 @@
                 throw new SecurityException(msg);
             }
 
-            final boolean canReadFb = checkCallingPermission(
-                    android.Manifest.permission.READ_FRAME_BUFFER)
-                    == PackageManager.PERMISSION_GRANTED;
+            final boolean canReadFb = (flags&ActivityManager.TASKS_GET_THUMBNAILS) != 0
+                    && checkCallingPermission(
+                            android.Manifest.permission.READ_FRAME_BUFFER)
+                            == PackageManager.PERMISSION_GRANTED;
 
             int pos = mMainStack.mHistory.size()-1;
             ActivityRecord next =
@@ -4878,7 +4885,7 @@
                         if (top.thumbnail != null) {
                             ci.thumbnail = top.thumbnail;
                         } else if (top.state == ActivityState.RESUMED) {
-                            ci.thumbnail = top.stack.screenshotActivities();
+                            ci.thumbnail = top.stack.screenshotActivities(top);
                         }
                     }
                     ci.description = topDescription;
@@ -4949,8 +4956,15 @@
             enforceCallingPermission(android.Manifest.permission.GET_TASKS,
                     "getRecentTasks()");
 
+            final boolean canReadFb = (flags&ActivityManager.TASKS_GET_THUMBNAILS) != 0
+                    && checkCallingPermission(
+                            android.Manifest.permission.READ_FRAME_BUFFER)
+                            == PackageManager.PERMISSION_GRANTED;
+            
             IPackageManager pm = AppGlobals.getPackageManager();
             
+            ActivityRecord resumed = mMainStack.mResumedActivity;
+            
             final int N = mRecentTasks.size();
             ArrayList<ActivityManager.RecentTaskInfo> res
                     = new ArrayList<ActivityManager.RecentTaskInfo>(
@@ -4968,6 +4982,15 @@
                             tr.intent != null ? tr.intent : tr.affinityIntent);
                     rti.origActivity = tr.origActivity;
                     
+                    if (canReadFb) {
+                        if (resumed != null && resumed.task == tr) {
+                            rti.thumbnail = resumed.stack.screenshotActivities(resumed);
+                        } else {
+                            rti.thumbnail = tr.lastThumbnail;
+                        }
+                    }
+                    rti.description = tr.lastDescription;
+                    
                     if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
                         // Check whether this activity is currently available.
                         try {
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index d92695c..920bbc9 100644
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -650,7 +650,7 @@
         }
     }
     
-    public final Bitmap screenshotActivities() {
+    public final Bitmap screenshotActivities(ActivityRecord who) {
         Resources res = mService.mContext.getResources();
         int w = mThumbnailWidth;
         int h = mThumbnailHeight;
@@ -662,7 +662,7 @@
         }
 
         if (w > 0) {
-            //return mService.mWindowManager.screenshotApplications(w, h);
+            //return mService.mWindowManager.screenshotApplications(who, w, h);
         }
         return null;
     }
@@ -686,7 +686,10 @@
         mLastPausedActivity = prev;
         prev.state = ActivityState.PAUSING;
         prev.task.touchActiveTime();
-        prev.thumbnail = screenshotActivities();
+        prev.thumbnail = screenshotActivities(prev);
+        if (prev.task != null) {
+            prev.task.lastThumbnail = prev.thumbnail;
+        }
 
         mService.updateCpuStats();
         
diff --git a/services/java/com/android/server/am/TaskRecord.java b/services/java/com/android/server/am/TaskRecord.java
index 09d9c3b6..86cec42 100644
--- a/services/java/com/android/server/am/TaskRecord.java
+++ b/services/java/com/android/server/am/TaskRecord.java
@@ -19,7 +19,7 @@
 import android.content.ComponentName;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
-import android.os.SystemClock;
+import android.graphics.Bitmap;
 
 import java.io.PrintWriter;
 
@@ -34,6 +34,8 @@
     long lastActiveTime;    // Last time this task was active, including sleep.
     boolean rootWasReset;   // True if the intent at the root of the task had
                             // the FLAG_ACTIVITY_RESET_TASK_IF_NEEDED flag.
+    Bitmap lastThumbnail;   // Last thumbnail captured for this task.
+    CharSequence lastDescription; // Last description captured for this task.
 
     String stringName;      // caching of toString() result.