Merge "Refactoring RecentsActivityValues into TaskDescription, and ensuring they are resolved when set. (Bug 14995928, 14832629)"
diff --git a/api/current.txt b/api/current.txt
index ed20009..b03c079 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -3348,12 +3348,12 @@
     method public final void setProgressBarIndeterminate(boolean);
     method public final void setProgressBarIndeterminateVisibility(boolean);
     method public final void setProgressBarVisibility(boolean);
-    method public void setRecentsActivityValues(android.app.ActivityManager.RecentsActivityValues);
     method public void setRequestedOrientation(int);
     method public final void setResult(int);
     method public final void setResult(int, android.content.Intent);
     method public final void setSecondaryProgress(int);
     method public void setSharedElementListener(android.app.SharedElementListener);
+    method public void setTaskDescription(android.app.ActivityManager.TaskDescription);
     method public void setTitle(java.lang.CharSequence);
     method public void setTitle(int);
     method public deprecated void setTitleColor(int);
@@ -3478,7 +3478,6 @@
     method public void readFromParcel(android.os.Parcel);
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator CREATOR;
-    field public android.app.ActivityManager.RecentsActivityValues activityValues;
     field public android.content.Intent baseIntent;
     field public java.lang.CharSequence description;
     field public int id;
@@ -3486,21 +3485,6 @@
     field public int persistentId;
   }
 
-  public static class ActivityManager.RecentsActivityValues implements android.os.Parcelable {
-    ctor public ActivityManager.RecentsActivityValues(android.app.ActivityManager.RecentsActivityValues);
-    ctor public ActivityManager.RecentsActivityValues(java.lang.CharSequence, android.graphics.Bitmap, int);
-    ctor public ActivityManager.RecentsActivityValues(java.lang.CharSequence, android.graphics.Bitmap);
-    ctor public ActivityManager.RecentsActivityValues(java.lang.CharSequence);
-    ctor public ActivityManager.RecentsActivityValues();
-    method public int describeContents();
-    method public void readFromParcel(android.os.Parcel);
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final android.os.Parcelable.Creator CREATOR;
-    field public int colorPrimary;
-    field public android.graphics.Bitmap icon;
-    field public java.lang.CharSequence label;
-  }
-
   public static class ActivityManager.RunningAppProcessInfo implements android.os.Parcelable {
     ctor public ActivityManager.RunningAppProcessInfo();
     ctor public ActivityManager.RunningAppProcessInfo(java.lang.String, int, java.lang.String[]);
@@ -3570,6 +3554,21 @@
     field public android.content.ComponentName topActivity;
   }
 
+  public static class ActivityManager.TaskDescription implements android.os.Parcelable {
+    ctor public ActivityManager.TaskDescription(android.app.ActivityManager.TaskDescription);
+    ctor public ActivityManager.TaskDescription(java.lang.CharSequence, android.graphics.Bitmap, int);
+    ctor public ActivityManager.TaskDescription(java.lang.CharSequence, android.graphics.Bitmap);
+    ctor public ActivityManager.TaskDescription(java.lang.CharSequence);
+    ctor public ActivityManager.TaskDescription();
+    method public int describeContents();
+    method public android.graphics.Bitmap getIcon();
+    method public java.lang.CharSequence getLabel();
+    method public int getPrimaryColor();
+    method public void readFromParcel(android.os.Parcel);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator CREATOR;
+  }
+
   public class ActivityOptions {
     method public static android.app.ActivityOptions makeCustomAnimation(android.content.Context, int, int);
     method public static android.app.ActivityOptions makeScaleUpAnimation(android.view.View, int, int, int, int);
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 87789de..e1a94d7 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -3613,15 +3613,15 @@
             theme.applyStyle(resid, false);
         }
 
-        // Get the primary color and update the RecentsActivityValues for this activity
+        // Get the primary color and update the TaskDescription for this activity
         if (theme != null) {
             TypedArray a = theme.obtainStyledAttributes(com.android.internal.R.styleable.Theme);
             int colorPrimary = a.getColor(com.android.internal.R.styleable.Theme_colorPrimary, 0);
             a.recycle();
             if (colorPrimary != 0) {
-                ActivityManager.RecentsActivityValues v = new ActivityManager.RecentsActivityValues();
-                v.colorPrimary = colorPrimary;
-                setRecentsActivityValues(v);
+                ActivityManager.TaskDescription v = new ActivityManager.TaskDescription(null, null,
+                        colorPrimary);
+                setTaskDescription(v);
             }
         }
     }
@@ -4926,27 +4926,30 @@
     }
 
     /**
-     * Sets information describing this Activity for presentation inside the Recents System UI. When
-     * {@link ActivityManager#getRecentTasks} is called, the activities of each task are
-     * traversed in order from the topmost activity to the bottommost. The traversal continues for
-     * each property until a suitable value is found. For each task those values will be returned in
-     * {@link android.app.ActivityManager.RecentsActivityValues}.
+     * Sets information describing the task with this activity for presentation inside the Recents
+     * System UI. When {@link ActivityManager#getRecentTasks} is called, the activities of each task
+     * are traversed in order from the topmost activity to the bottommost. The traversal continues
+     * for each property until a suitable value is found. For each task the taskDescription will be
+     * returned in {@link android.app.ActivityManager.TaskDescription}.
      *
      * @see ActivityManager#getRecentTasks
-     * @see android.app.ActivityManager.RecentsActivityValues
+     * @see android.app.ActivityManager.TaskDescription
      *
-     * @param values The Recents values that describe this activity.
+     * @param taskDescription The TaskDescription properties that describe the task with this activity
      */
-    public void setRecentsActivityValues(ActivityManager.RecentsActivityValues values) {
-        ActivityManager.RecentsActivityValues activityValues =
-                new ActivityManager.RecentsActivityValues(values);
-        // Scale the icon down to something reasonable
-        if (values.icon != null) {
+    public void setTaskDescription(ActivityManager.TaskDescription taskDescription) {
+        ActivityManager.TaskDescription td;
+        // Scale the icon down to something reasonable if it is provided
+        if (taskDescription.getIcon() != null) {
             final int size = ActivityManager.getLauncherLargeIconSizeInner(this);
-            activityValues.icon = Bitmap.createScaledBitmap(values.icon, size, size, true);
+            final Bitmap icon = Bitmap.createScaledBitmap(taskDescription.getIcon(), size, size, true);
+            td = new ActivityManager.TaskDescription(taskDescription.getLabel(), icon,
+                    taskDescription.getPrimaryColor());
+        } else {
+            td = taskDescription;
         }
         try {
-            ActivityManagerNative.getDefault().setRecentsActivityValues(mToken, activityValues);
+            ActivityManagerNative.getDefault().setTaskDescription(mToken, td);
         } catch (RemoteException e) {
         }
     }
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 1d05320..abcb0d0 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -33,6 +33,7 @@
 import android.content.pm.UserInfo;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
+import android.graphics.Color;
 import android.graphics.Rect;
 import android.os.Bundle;
 import android.os.Debug;
@@ -477,65 +478,84 @@
     /**
      * Information you can set and retrieve about the current activity within the recent task list.
      */
-    public static class RecentsActivityValues implements Parcelable {
-        public CharSequence label;
-        public Bitmap icon;
-        public int colorPrimary;
-
-        public RecentsActivityValues(RecentsActivityValues values) {
-            copyFrom(values);
-        }
+    public static class TaskDescription implements Parcelable {
+        private String mLabel;
+        private Bitmap mIcon;
+        private int mColorPrimary;
 
         /**
-         * Creates the RecentsActivityValues to the specified values.
+         * Creates the TaskDescription to the specified values.
          *
-         * @param label A label and description of the current state of this activity.
-         * @param icon An icon that represents the current state of this activity.
-         * @param color A color to override the theme's primary color.
+         * @param label A label and description of the current state of this task.
+         * @param icon An icon that represents the current state of this task.
+         * @param colorPrimary A color to override the theme's primary color.  This color must be opaque.
          */
-        public RecentsActivityValues(CharSequence label, Bitmap icon, int color) {
-            this.label = label;
-            this.icon = icon;
-            this.colorPrimary = color;
+        public TaskDescription(String label, Bitmap icon, int colorPrimary) {
+            if ((colorPrimary != 0) && (Color.alpha(colorPrimary) != 255)) {
+                throw new RuntimeException("A TaskDescription's primary color should be opaque");
+            }
+
+            mLabel = label;
+            mIcon = icon;
+            mColorPrimary = colorPrimary;
         }
 
         /**
-         * Creates the RecentsActivityValues to the specified values.
+         * Creates the TaskDescription to the specified values.
          *
          * @param label A label and description of the current state of this activity.
          * @param icon An icon that represents the current state of this activity.
          */
-        public RecentsActivityValues(CharSequence label, Bitmap icon) {
+        public TaskDescription(String label, Bitmap icon) {
             this(label, icon, 0);
         }
 
         /**
-         * Creates the RecentsActivityValues to the specified values.
+         * Creates the TaskDescription to the specified values.
          *
          * @param label A label and description of the current state of this activity.
          */
-        public RecentsActivityValues(CharSequence label) {
+        public TaskDescription(String label) {
             this(label, null, 0);
         }
 
-        public RecentsActivityValues() {
+        /**
+         * Creates an empty TaskDescription.
+         */
+        public TaskDescription() {
             this(null, null, 0);
         }
 
-        private RecentsActivityValues(Parcel source) {
+        /**
+         * Creates a copy of another TaskDescription.
+         */
+        public TaskDescription(TaskDescription td) {
+            this(td.getLabel(), td.getIcon(), td.getPrimaryColor());
+        }
+
+        private TaskDescription(Parcel source) {
             readFromParcel(source);
         }
 
         /**
-         * Do a shallow copy of another set of activity values.
-         * @hide
+         * @return The label and description of the current state of this task.
          */
-        public void copyFrom(RecentsActivityValues v) {
-            if (v != null) {
-                label = v.label;
-                icon = v.icon;
-                colorPrimary = v.colorPrimary;
-            }
+        public String getLabel() {
+            return mLabel;
+        }
+
+        /**
+         * @return The icon that represents the current state of this task.
+         */
+        public Bitmap getIcon() {
+            return mIcon;
+        }
+
+        /**
+         * @return The color override on the theme's primary color.
+         */
+        public int getPrimaryColor() {
+            return mColorPrimary;
         }
 
         @Override
@@ -545,37 +565,41 @@
 
         @Override
         public void writeToParcel(Parcel dest, int flags) {
-            TextUtils.writeToParcel(label, dest,
-                    Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
-            if (icon == null) {
+            if (mLabel == null) {
                 dest.writeInt(0);
             } else {
                 dest.writeInt(1);
-                icon.writeToParcel(dest, 0);
+                dest.writeString(mLabel);
             }
-            dest.writeInt(colorPrimary);
+            if (mIcon == null) {
+                dest.writeInt(0);
+            } else {
+                dest.writeInt(1);
+                mIcon.writeToParcel(dest, 0);
+            }
+            dest.writeInt(mColorPrimary);
         }
 
         public void readFromParcel(Parcel source) {
-            label = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
-            icon = source.readInt() > 0 ? Bitmap.CREATOR.createFromParcel(source) : null;
-            colorPrimary = source.readInt();
+            mLabel = source.readInt() > 0 ? source.readString() : null;
+            mIcon = source.readInt() > 0 ? Bitmap.CREATOR.createFromParcel(source) : null;
+            mColorPrimary = source.readInt();
         }
 
-        public static final Creator<RecentsActivityValues> CREATOR
-                = new Creator<RecentsActivityValues>() {
-            public RecentsActivityValues createFromParcel(Parcel source) {
-                return new RecentsActivityValues(source);
+        public static final Creator<TaskDescription> CREATOR
+                = new Creator<TaskDescription>() {
+            public TaskDescription createFromParcel(Parcel source) {
+                return new TaskDescription(source);
             }
-            public RecentsActivityValues[] newArray(int size) {
-                return new RecentsActivityValues[size];
+            public TaskDescription[] newArray(int size) {
+                return new TaskDescription[size];
             }
         };
 
         @Override
         public String toString() {
-            return "RecentsActivityValues Label: " + label + " Icon: " + icon +
-                    " colorPrimary: " + colorPrimary;
+            return "TaskDescription Label: " + mLabel + " Icon: " + mIcon +
+                    " colorPrimary: " + mColorPrimary;
         }
     }
 
@@ -629,9 +653,11 @@
 
         /**
          * The recent activity values for the highest activity in the stack to have set the values.
-         * {@link Activity#setRecentsActivityValues(android.app.ActivityManager.RecentsActivityValues)}.
+         * {@link Activity#setTaskDescription(android.app.ActivityManager.TaskDescription)}.
+         *
+         * @hide
          */
-        public RecentsActivityValues activityValues;
+        public TaskDescription taskDescription;
 
         public RecentTaskInfo() {
         }
@@ -654,9 +680,9 @@
             ComponentName.writeToParcel(origActivity, dest);
             TextUtils.writeToParcel(description, dest,
                     Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
-            if (activityValues != null) {
+            if (taskDescription != null) {
                 dest.writeInt(1);
-                activityValues.writeToParcel(dest, 0);
+                taskDescription.writeToParcel(dest, 0);
             } else {
                 dest.writeInt(0);
             }
@@ -670,8 +696,8 @@
             baseIntent = source.readInt() > 0 ? Intent.CREATOR.createFromParcel(source) : null;
             origActivity = ComponentName.readFromParcel(source);
             description = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
-            activityValues = source.readInt() > 0 ?
-                    RecentsActivityValues.CREATOR.createFromParcel(source) : null;
+            taskDescription = source.readInt() > 0 ?
+                    TaskDescription.CREATOR.createFromParcel(source) : null;
             stackId = source.readInt();
             userId = source.readInt();
         }
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index e704a1c..0f65454 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -2158,12 +2158,12 @@
             return true;
         }
 
-        case SET_RECENTS_ACTIVITY_VALUES_TRANSACTION: {
+        case SET_TASK_DESCRIPTION_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
             IBinder token = data.readStrongBinder();
-            ActivityManager.RecentsActivityValues values =
-                    ActivityManager.RecentsActivityValues.CREATOR.createFromParcel(data);
-            setRecentsActivityValues(token, values);
+            ActivityManager.TaskDescription values =
+                    ActivityManager.TaskDescription.CREATOR.createFromParcel(data);
+            setTaskDescription(token, values);
             reply.writeNoException();
             return true;
         }
@@ -4967,14 +4967,14 @@
     }
 
     @Override
-    public void setRecentsActivityValues(IBinder token, ActivityManager.RecentsActivityValues values)
+    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription values)
             throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
         data.writeStrongBinder(token);
         values.writeToParcel(data, 0);
-        mRemote.transact(SET_RECENTS_ACTIVITY_VALUES_TRANSACTION, data, reply, IBinder.FLAG_ONEWAY);
+        mRemote.transact(SET_TASK_DESCRIPTION_TRANSACTION, data, reply, IBinder.FLAG_ONEWAY);
         reply.readException();
         data.recycle();
         reply.recycle();
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 8753312..8434c2a0 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -440,7 +440,7 @@
     public boolean isInLockTaskMode() throws RemoteException;
 
     /** @hide */
-    public void setRecentsActivityValues(IBinder token, ActivityManager.RecentsActivityValues values)
+    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription values)
             throws RemoteException;
 
     /*
@@ -739,7 +739,7 @@
     int START_LOCK_TASK_BY_TOKEN_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+214;
     int STOP_LOCK_TASK_MODE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+215;
     int IS_IN_LOCK_TASK_MODE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+216;
-    int SET_RECENTS_ACTIVITY_VALUES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+217;
+    int SET_TASK_DESCRIPTION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+217;
     int START_VOICE_ACTIVITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+218;
     int GET_ACTIVITY_OPTIONS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+219;
     int GET_APP_TASKS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+220;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsTaskLoader.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsTaskLoader.java
index 1ca0476..1c12ac2 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsTaskLoader.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsTaskLoader.java
@@ -400,15 +400,14 @@
             ActivityInfo info = ssp.getActivityInfo(t.baseIntent.getComponent(), t.userId);
             if (info == null) continue;
 
-            ActivityManager.RecentsActivityValues av = t.activityValues;
+            ActivityManager.TaskDescription av = t.taskDescription;
             String activityLabel = null;
             BitmapDrawable activityIcon = null;
             int activityColor = 0;
             if (av != null) {
-                activityLabel = (av.label != null ? av.label.toString() :
-                        ssp.getActivityLabel(info));
-                activityIcon = (av.icon != null) ? new BitmapDrawable(res, av.icon) : null;
-                activityColor = av.colorPrimary;
+                activityLabel = (av.getLabel() != null ? av.getLabel() : ssp.getActivityLabel(info));
+                activityIcon = (av.getIcon() != null) ? new BitmapDrawable(res, av.getIcon()) : null;
+                activityColor = av.getPrimaryColor();
             } else {
                 activityLabel = ssp.getActivityLabel(info);
             }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/SystemServicesProxy.java b/packages/SystemUI/src/com/android/systemui/recents/SystemServicesProxy.java
index 8d82883..59d0ea6 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/SystemServicesProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/SystemServicesProxy.java
@@ -96,18 +96,19 @@
                 int packageIndex = i % Constants.DebugFlags.App.SystemServicesProxyMockPackageCount;
                 ComponentName cn = new ComponentName("com.android.test" + packageIndex,
                         "com.android.test" + i + ".Activity");
+                String description = "" + i + " - " +
+                        Long.toString(Math.abs(new Random().nextLong()), 36);
                 // Create the recent task info
                 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
                 rti.id = rti.persistentId = i;
                 rti.baseIntent = new Intent();
                 rti.baseIntent.setComponent(cn);
-                rti.activityValues = new ActivityManager.RecentsActivityValues();
-                rti.description = "" + i + " - " +
-                        Long.toString(Math.abs(new Random().nextLong()), 36);
+                rti.description = description;
                 if (i % 2 == 0) {
-                    rti.activityValues.label = rti.description;
-                    rti.activityValues.icon = Bitmap.createBitmap(mDummyIcon);
-                    rti.activityValues.colorPrimary = new Random().nextInt();
+                    rti.taskDescription = new ActivityManager.TaskDescription(description,
+                        Bitmap.createBitmap(mDummyIcon), new Random().nextInt());
+                } else {
+                    rti.taskDescription = new ActivityManager.TaskDescription();
                 }
                 tasks.add(rti);
             }
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index bab5b9c..7abc75f 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -7087,50 +7087,7 @@
         rti.description = tr.lastDescription;
         rti.stackId = tr.stack.mStackId;
         rti.userId = tr.userId;
-
-        // Traverse upwards looking for any break between main task activities and
-        // utility activities.
-        final ArrayList<ActivityRecord> activities = tr.mActivities;
-        int activityNdx;
-        final int numActivities = activities.size();
-        for (activityNdx = Math.min(numActivities, 1); activityNdx < numActivities;
-             ++activityNdx) {
-            final ActivityRecord r = activities.get(activityNdx);
-            if (r.intent != null &&
-                    (r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET)
-                            != 0) {
-                break;
-            }
-        }
-        if (activityNdx > 0) {
-            // Traverse downwards starting below break looking for set label, icon.
-            // Note that if there are activities in the task but none of them set the
-            // recent activity values, then we do not fall back to the last set
-            // values in the TaskRecord.
-            rti.activityValues = new ActivityManager.RecentsActivityValues();
-            for (--activityNdx; activityNdx >= 0; --activityNdx) {
-                final ActivityRecord r = activities.get(activityNdx);
-                if (r.activityValues != null) {
-                    if (rti.activityValues.label == null) {
-                        rti.activityValues.label = r.activityValues.label;
-                        tr.lastActivityValues.label = r.activityValues.label;
-                    }
-                    if (rti.activityValues.icon == null) {
-                        rti.activityValues.icon = r.activityValues.icon;
-                        tr.lastActivityValues.icon = r.activityValues.icon;
-                    }
-                    if (rti.activityValues.colorPrimary == 0) {
-                        rti.activityValues.colorPrimary = r.activityValues.colorPrimary;
-                        tr.lastActivityValues.colorPrimary = r.activityValues.colorPrimary;
-                    }
-                }
-            }
-        } else {
-            // If there are no activity records in this task, then we use the last
-            // resolved values
-            rti.activityValues =
-                    new ActivityManager.RecentsActivityValues(tr.lastActivityValues);
-        }
+        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
         return rti;
     }
 
@@ -7261,11 +7218,12 @@
     }
 
     @Override
-    public void setRecentsActivityValues(IBinder token, ActivityManager.RecentsActivityValues rav) {
+    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
         synchronized (this) {
             ActivityRecord r = ActivityRecord.isInStackLocked(token);
             if (r != null) {
-                r.activityValues = rav;
+                r.taskDescription = td;
+                r.task.updateTaskDescription();
             }
         }
     }
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 9582ac7..dbe2ca1 100755
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -149,7 +149,7 @@
     boolean mStartingWindowShown = false;
     ActivityContainer mInitialActivityContainer;
 
-    ActivityManager.RecentsActivityValues activityValues; // the recents information for this activity
+    ActivityManager.TaskDescription taskDescription; // the recents information for this activity
 
     void dump(PrintWriter pw, String prefix) {
         final long now = SystemClock.uptimeMillis();
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index be884e7..6d66b29 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -58,8 +58,8 @@
 
     // This represents the last resolved activity values for this task
     // NOTE: This value needs to be persisted with each task
-    ActivityManager.RecentsActivityValues lastActivityValues =
-            new ActivityManager.RecentsActivityValues();
+    ActivityManager.TaskDescription lastTaskDescription =
+            new ActivityManager.TaskDescription();
 
     /** List of all activities in the task arranged in history order */
     final ArrayList<ActivityRecord> mActivities = new ArrayList<ActivityRecord>();
@@ -486,6 +486,48 @@
         return null;
     }
 
+    /** Updates the last task description values. */
+    void updateTaskDescription() {
+        // Traverse upwards looking for any break between main task activities and
+        // utility activities.
+        int activityNdx;
+        final int numActivities = mActivities.size();
+        for (activityNdx = Math.min(numActivities, 1); activityNdx < numActivities;
+             ++activityNdx) {
+            final ActivityRecord r = mActivities.get(activityNdx);
+            if (r.intent != null &&
+                    (r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET)
+                            != 0) {
+                break;
+            }
+        }
+        if (activityNdx > 0) {
+            // Traverse downwards starting below break looking for set label, icon.
+            // Note that if there are activities in the task but none of them set the
+            // recent activity values, then we do not fall back to the last set
+            // values in the TaskRecord.
+            String label = null;
+            Bitmap icon = null;
+            int colorPrimary = 0;
+            for (--activityNdx; activityNdx >= 0; --activityNdx) {
+                final ActivityRecord r = mActivities.get(activityNdx);
+                if (r.taskDescription != null) {
+                    if (label == null) {
+                        label = r.taskDescription.getLabel();
+                    }
+                    if (icon == null) {
+                        icon = r.taskDescription.getIcon();
+                    }
+                    if (colorPrimary == 0) {
+                        colorPrimary = r.taskDescription.getPrimaryColor();
+
+                    }
+                }
+            }
+            lastTaskDescription = new ActivityManager.TaskDescription(label, icon, colorPrimary);
+        }
+    }
+
     void dump(PrintWriter pw, String prefix) {
         if (numActivities != 0 || rootWasReset || userId != 0 || numFullscreen != 0) {
             pw.print(prefix); pw.print("numActivities="); pw.print(numActivities);