Moving task view layout into resource.

- Using new activity icon/labels

Change-Id: If27bf60d2df75813213e9f3095baeb03085da8f7
diff --git a/packages/SystemUI/res/layout/recents_task_view.xml b/packages/SystemUI/res/layout/recents_task_view.xml
new file mode 100644
index 0000000..f6e875c
--- /dev/null
+++ b/packages/SystemUI/res/layout/recents_task_view.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+<com.android.systemui.recents.views.TaskView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent" 
+    android:layout_height="match_parent">
+    <com.android.systemui.recents.views.TaskThumbnailView
+        android:id="@+id/task_view_thumbnail"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent" />
+    <com.android.systemui.recents.views.TaskBarView
+        android:id="@+id/task_view_bar"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_gravity="top|center_horizontal"
+        android:background="#88000000">
+        <ImageView
+            android:id="@+id/activity_icon"
+            android:layout_width="@dimen/recents_task_view_icon_size"
+            android:layout_height="@dimen/recents_task_view_icon_size"
+            android:layout_gravity="top|left"
+            android:padding="8dp" />
+        <TextView
+            android:id="@+id/activity_description"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_vertical|left"
+            android:layout_marginLeft="@dimen/recents_task_view_icon_size"
+            android:textSize="24sp"
+            android:textColor="#ffffffff"
+            android:text="@string/recents_empty_message"
+            android:fontFamily="sans-serif-thin" />
+    </com.android.systemui.recents.views.TaskBarView>
+</com.android.systemui.recents.views.TaskView>
+
+
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 65cd2319..f4bfd10 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -229,4 +229,7 @@
 
     <!-- Default distance from each snap target that GlowPadView considers a "hit" -->
     <dimen name="glowpadview_inner_radius">15dip</dimen>
+
+    <!-- The size of the icon in the recents task view. -->
+    <dimen name="recents_task_view_icon_size">60dp</dimen>
 </resources>
diff --git a/packages/SystemUI/src/com/android/systemui/recents/Constants.java b/packages/SystemUI/src/com/android/systemui/recents/Constants.java
index 2dc4b88..b5950e9 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/Constants.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/Constants.java
@@ -50,7 +50,6 @@
             public static final boolean ClickEvents = false;
             public static final boolean TouchEvents = false;
             public static final boolean MeasureAndLayout = false;
-            public static final boolean Clipping = false;
             public static final boolean HwLayers = false;
         }
 
@@ -107,14 +106,9 @@
 
             public static final boolean AnimateFrontTaskIconOnEnterRecents = true;
             public static final boolean AnimateFrontTaskIconOnLeavingRecents = true;
-            public static final boolean AnimateFrontTaskIconOnEnterUseClip = false;
-            public static final boolean AnimateFrontTaskIconOnLeavingUseClip = false;
-            public static final boolean DrawColoredTaskBars = false;
+
             public static final boolean UseRoundedCorners = true;
             public static final float RoundedCornerRadiusDps = 3;
-
-            public static final float TaskBarHeightDps = 54;
-            public static final float TaskIconSizeDps = 60;
         }
     }
 }
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsTaskLoader.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsTaskLoader.java
index cdbee82..4601b0b 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsTaskLoader.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsTaskLoader.java
@@ -21,6 +21,7 @@
 import android.content.Context;
 import android.content.pm.ActivityInfo;
 import android.content.pm.PackageManager;
+import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.drawable.BitmapDrawable;
@@ -360,6 +361,7 @@
     /** Reload the set of recent tasks */
     SpaceNode reload(Context context, int preloadCount) {
         Console.log(Constants.DebugFlags.App.TaskDataLoader, "[RecentsTaskLoader|reload]");
+        Resources res = context.getResources();
         ArrayList<Task> tasksToForceLoad = new ArrayList<Task>();
         TaskStack stack = new TaskStack(context);
         SpaceNode root = new SpaceNode(context);
@@ -415,31 +417,38 @@
                             "[RecentsTaskLoader|preloadTask]",
                             "i: " + i + " task: " + t.baseIntent.getComponent().getPackageName());
 
-                    Task task = new Task(t.persistentId, t.baseIntent, title);
+                    String label = (t.activityLabel == null ? title : t.activityLabel.toString());
+                    BitmapDrawable bd = null;
+                    if (t.activityIcon != null) {
+                        bd = new BitmapDrawable(res, t.activityIcon);
+                    }
+                    Task task = new Task(t.persistentId, t.baseIntent, label, bd);
 
                     // Load the icon (if possible and not the foremost task, from the cache)
-                    if (!isForemostTask) {
-                        task.icon = mIconCache.get(task.key);
-
-                        if (task.icon != null) {
-                            // Even though we get things from the cache, we should update them if
-                            // they've changed in the bg
-                            tasksToForceLoad.add(task);
+                    if (task.icon != null) {
+                        mIconCache.put(task.key, task.icon);
+                    } else {
+                        if (!isForemostTask) {
+                            task.icon = mIconCache.get(task.key);
+                            if (task.icon != null) {
+                                // Even though we get things from the cache, we should update them
+                                // if they've changed in the bg
+                                tasksToForceLoad.add(task);
+                            }
                         }
-                    }
-                    if (task.icon == null) {
-                        task.icon = info.loadIcon(pm);
-                        if (task.icon != null) {
-                            mIconCache.put(task.key, task.icon);
-                        } else {
-                            task.icon = mDefaultIcon;
+                        if (task.icon == null) {
+                            task.icon = info.loadIcon(pm);
+                            if (task.icon != null) {
+                                mIconCache.put(task.key, task.icon);
+                            } else {
+                                task.icon = mDefaultIcon;
+                            }
                         }
                     }
 
                     // Load the thumbnail (if possible and not the foremost task, from the cache)
                     if (!isForemostTask) {
                         task.thumbnail = mThumbnailCache.get(task.key);
-
                         if (task.thumbnail != null) {
                             // Even though we get things from the cache, we should update them if
                             // they've changed in the bg
@@ -468,7 +477,7 @@
                     for (int j = 0; j < Constants.Values.RecentsTaskLoader.TaskEntryMultiplier; j++) {
                         Console.log(Constants.DebugFlags.App.TaskDataLoader,
                                 "  [RecentsTaskLoader|task]", t.baseIntent.getComponent().getPackageName());
-                        stack.addTask(new Task(t.persistentId, t.baseIntent, title));
+                        stack.addTask(new Task(t.persistentId, t.baseIntent, title, null, null));
                     }
                 }
             }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/Task.java b/packages/SystemUI/src/com/android/systemui/recents/model/Task.java
index edcf9b2..7b335af 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/Task.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/Task.java
@@ -67,8 +67,8 @@
 
     TaskCallbacks mCb;
 
-    public Task(int id, Intent intent, String activityTitle) {
-        this(id, intent, activityTitle, null, null);
+    public Task(int id, Intent intent, String activityTitle, Drawable icon) {
+        this(id, intent, activityTitle, icon, null);
     }
 
     public Task(int id, Intent intent, String activityTitle, Drawable icon, Bitmap thumbnail) {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskBarView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskBarView.java
new file mode 100644
index 0000000..235c6cc
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskBarView.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2014 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 com.android.systemui.recents.views;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.graphics.Typeface;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.animation.AccelerateDecelerateInterpolator;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+import android.widget.TextView;
+import com.android.systemui.R;
+import com.android.systemui.recents.Constants;
+import com.android.systemui.recents.RecentsConfiguration;
+import com.android.systemui.recents.model.Task;
+
+
+/* The task bar view */
+class TaskBarView extends FrameLayout {
+    Task mTask;
+
+    ImageView mActivityIcon;
+    TextView mActivityDescription;
+
+    public TaskBarView(Context context) {
+        this(context, null);
+    }
+
+    public TaskBarView(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public TaskBarView(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public TaskBarView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+    }
+
+    @Override
+    protected void onFinishInflate() {
+        // Initialize the icon and description views
+        mActivityIcon = (ImageView) findViewById(R.id.activity_icon);
+        mActivityDescription = (TextView) findViewById(R.id.activity_description);
+    }
+
+    /** Binds the bar view to the task */
+    void rebindToTask(Task t, boolean animate) {
+        mTask = t;
+        if (t.icon != null) {
+            mActivityIcon.setImageDrawable(t.icon);
+            mActivityDescription.setText(t.title);
+            if (animate) {
+                // XXX: Investigate how expensive it will be to create a second bitmap and crossfade
+            }
+        }
+    }
+
+    /** Unbinds the bar view from the task */
+    void unbindFromTask() {
+        mTask = null;
+        mActivityIcon.setImageDrawable(null);
+        mActivityDescription.setText("");
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
index 2b27a06..e7f517f 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -26,6 +26,7 @@
 import android.graphics.Canvas;
 import android.graphics.Rect;
 import android.graphics.Region;
+import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.VelocityTracker;
 import android.view.View;
@@ -40,6 +41,7 @@
 import com.android.systemui.recents.Utilities;
 import com.android.systemui.recents.model.Task;
 import com.android.systemui.recents.model.TaskStack;
+import com.android.systemui.R;
 
 import java.util.ArrayList;
 
@@ -77,6 +79,7 @@
     int mStackViewsAnimationDuration;
     boolean mStackViewsDirty = true;
     boolean mAwaitingFirstLayout = true;
+    LayoutInflater mInflater;
 
     public TaskStackView(Context context, TaskStack stack) {
         super(context);
@@ -85,6 +88,7 @@
         mScroller = new OverScroller(context);
         mTouchHandler = new TaskStackViewTouchHandler(context, this);
         mViewPool = new ViewPool<TaskView, Task>(context, this);
+        mInflater = LayoutInflater.from(context);
     }
 
     /** Sets the callbacks */
@@ -580,7 +584,7 @@
     @Override
     public TaskView createView(Context context) {
         Console.log(Constants.DebugFlags.ViewPool.PoolCallbacks, "[TaskStackView|createPoolView]");
-        return new TaskView(context);
+        return (TaskView) mInflater.inflate(R.layout.recents_task_view, this, false);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskThumbnailView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskThumbnailView.java
new file mode 100644
index 0000000..8a9250a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskThumbnailView.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2014 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 com.android.systemui.recents.views;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.ImageView;
+import com.android.systemui.recents.model.Task;
+
+
+/** The task thumbnail view */
+public class TaskThumbnailView extends ImageView {
+    Task mTask;
+
+    public TaskThumbnailView(Context context) {
+        this(context, null);
+    }
+
+    public TaskThumbnailView(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public TaskThumbnailView(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public TaskThumbnailView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+        setScaleType(ScaleType.FIT_XY);
+    }
+
+    /** Binds the thumbnail view to the task */
+    void rebindToTask(Task t, boolean animate) {
+        mTask = t;
+        if (t.thumbnail != null) {
+            setImageBitmap(t.thumbnail);
+            if (animate) {
+                // XXX: Investigate how expensive it will be to create a second bitmap and crossfade
+            }
+        }
+    }
+
+    /** Unbinds the thumbnail view from the task */
+    void unbindFromTask() {
+        mTask = null;
+        setImageDrawable(null);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
index e6dce37..c86b0e1 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
@@ -16,66 +16,67 @@
 
 package com.android.systemui.recents.views;
 
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ObjectAnimator;
-import android.animation.TimeInterpolator;
 import android.content.Context;
 import android.graphics.Canvas;
-import android.graphics.Paint;
 import android.graphics.Path;
-import android.graphics.Point;
 import android.graphics.Rect;
 import android.graphics.RectF;
-import android.graphics.Typeface;
-import android.view.Gravity;
+import android.util.AttributeSet;
 import android.view.View;
 import android.view.animation.AccelerateDecelerateInterpolator;
-import android.view.animation.AccelerateInterpolator;
 import android.view.animation.DecelerateInterpolator;
 import android.widget.FrameLayout;
-import android.widget.ImageView;
-import com.android.systemui.recents.Console;
+import com.android.systemui.R;
 import com.android.systemui.recents.Constants;
 import com.android.systemui.recents.RecentsConfiguration;
 import com.android.systemui.recents.model.Task;
 
 
-/** The task thumbnail view */
-class TaskThumbnailView extends ImageView {
+/* A task view */
+public class TaskView extends FrameLayout implements View.OnClickListener, Task.TaskCallbacks {
+    /** The TaskView callbacks */
+    interface TaskViewCallbacks {
+        public void onTaskIconClicked(TaskView tv);
+        // public void onTaskViewReboundToTask(TaskView tv, Task t);
+    }
+
     Task mTask;
-    int mBarColor;
+    boolean mTaskDataLoaded;
+
+    TaskThumbnailView mThumbnailView;
+    TaskBarView mBarView;
+    TaskViewCallbacks mCb;
 
     Path mRoundedRectClipPath = new Path();
 
-    public TaskThumbnailView(Context context) {
-        super(context);
-        setScaleType(ScaleType.FIT_XY);
+
+    public TaskView(Context context) {
+        this(context, null);
     }
 
-    /** Binds the thumbnail view to the task */
-    void rebindToTask(Task t, boolean animate) {
-        mTask = t;
-        if (t.thumbnail != null) {
-            // Update the bar color
-            if (Constants.Values.TaskView.DrawColoredTaskBars) {
-                int[] colors = {0xFFCC0C39, 0xFFE6781E, 0xFFC8CF02, 0xFF1693A7};
-                mBarColor = colors[mTask.key.intent.getComponent().getPackageName().length() % colors.length];
-            }
+    public TaskView(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
 
-            setImageBitmap(t.thumbnail);
-            if (animate) {
-                // XXX: Investigate how expensive it will be to create a second bitmap and crossfade
-            }
+    public TaskView(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public TaskView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+        setWillNotDraw(false);
+    }
+
+    @Override
+    protected void onFinishInflate() {
+        // Bind the views
+        mThumbnailView = (TaskThumbnailView) findViewById(R.id.task_view_thumbnail);
+        mBarView = (TaskBarView) findViewById(R.id.task_view_bar);
+        if (mTaskDataLoaded) {
+            onTaskDataLoaded(false);
         }
     }
 
-    /** Unbinds the thumbnail view from the task */
-    void unbindFromTask() {
-        mTask = null;
-        setImageDrawable(null);
-    }
-
     @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
@@ -95,150 +96,6 @@
         }
 
         super.onDraw(canvas);
-
-        if (Constants.Values.TaskView.DrawColoredTaskBars) {
-            RecentsConfiguration config = RecentsConfiguration.getInstance();
-            int taskBarHeight = config.pxFromDp(Constants.Values.TaskView.TaskBarHeightDps);
-            // XXX: If we actually use this, this should be pulled out into a TextView that we
-            // inflate
-
-            // Draw the task bar
-            Rect r = new Rect();
-            Paint p = new Paint();
-            p.setAntiAlias(true);
-            p.setSubpixelText(true);
-            p.setColor(mBarColor);
-            p.setTypeface(Typeface.create("sans-serif-light", Typeface.NORMAL));
-            canvas.drawRect(0, 0, getMeasuredWidth(), taskBarHeight, p);
-            p.setColor(0xFFffffff);
-            p.setTextSize(68);
-            p.getTextBounds("X", 0, 1, r);
-            int offset = (int) (taskBarHeight - r.height()) / 2;
-            canvas.drawText(mTask.title, offset, offset + r.height(), p);
-        }
-    }
-}
-
-/* The task icon view */
-class TaskIconView extends ImageView {
-    Task mTask;
-
-    Path mClipPath = new Path();
-    float mClipRadius;
-    Point mClipOrigin = new Point();
-    ObjectAnimator mCircularClipAnimator;
-
-    public TaskIconView(Context context) {
-        super(context);
-        mClipPath = new Path();
-        mClipRadius = 1f;
-    }
-
-    /** Binds the icon view to the task */
-    void rebindToTask(Task t, boolean animate) {
-        mTask = t;
-        if (t.icon != null) {
-            setImageDrawable(t.icon);
-            if (animate) {
-                // XXX: Investigate how expensive it will be to create a second bitmap and crossfade
-            }
-        }
-    }
-
-    /** Unbinds the icon view from the task */
-    void unbindFromTask() {
-        mTask = null;
-        setImageDrawable(null);
-    }
-
-    /** Sets the circular clip radius on the icon */
-    public void setCircularClipRadius(float r) {
-        Console.log(Constants.DebugFlags.UI.Clipping, "[TaskView|setCircularClip]", "" + r);
-        mClipRadius = r;
-        invalidate();
-    }
-
-    /** Gets the circular clip radius on the icon */
-    public float getCircularClipRadius() {
-        return mClipRadius;
-    }
-
-    /** Animates the circular clip radius on the icon */
-    void animateCircularClip(boolean brNotTl, float newRadius, int duration, int startDelay,
-                             TimeInterpolator interpolator,
-                             AnimatorListenerAdapter listener) {
-        if (mCircularClipAnimator != null) {
-            mCircularClipAnimator.cancel();
-            mCircularClipAnimator.removeAllListeners();
-        }
-        if (brNotTl) {
-            mClipOrigin.set(0, 0);
-        } else {
-            mClipOrigin.set(getMeasuredWidth(), getMeasuredHeight());
-        }
-        mCircularClipAnimator = ObjectAnimator.ofFloat(this, "circularClipRadius", newRadius);
-        mCircularClipAnimator.setStartDelay(startDelay);
-        mCircularClipAnimator.setDuration(duration);
-        mCircularClipAnimator.setInterpolator(interpolator);
-        if (listener != null) {
-            mCircularClipAnimator.addListener(listener);
-        }
-        mCircularClipAnimator.start();
-    }
-
-    @Override
-    protected void onDraw(Canvas canvas) {
-        int saveCount = canvas.save(Canvas.CLIP_SAVE_FLAG);
-        int width = getMeasuredWidth();
-        int height = getMeasuredHeight();
-        int maxSize = (int) Math.ceil(Math.sqrt(width * width + height * height));
-        mClipPath.reset();
-        mClipPath.addCircle(mClipOrigin.x, mClipOrigin.y, mClipRadius * maxSize, Path.Direction.CW);
-        canvas.clipPath(mClipPath);
-        super.onDraw(canvas);
-        canvas.restoreToCount(saveCount);
-    }
-}
-
-/* A task view */
-public class TaskView extends FrameLayout implements View.OnClickListener, Task.TaskCallbacks {
-    /** The TaskView callbacks */
-    interface TaskViewCallbacks {
-        public void onTaskIconClicked(TaskView tv);
-        // public void onTaskViewReboundToTask(TaskView tv, Task t);
-    }
-
-    Task mTask;
-    TaskThumbnailView mThumbnailView;
-    TaskIconView mIconView;
-    TaskViewCallbacks mCb;
-
-    public TaskView(Context context) {
-        super(context);
-        mThumbnailView = new TaskThumbnailView(context);
-        mIconView = new TaskIconView(context);
-        mIconView.setOnClickListener(this);
-        addView(mThumbnailView);
-        addView(mIconView);
-
-        RecentsConfiguration config = RecentsConfiguration.getInstance();
-        int barHeight = config.pxFromDp(Constants.Values.TaskView.TaskBarHeightDps);
-        int iconSize = config.pxFromDp(Constants.Values.TaskView.TaskIconSizeDps);
-        int offset = barHeight - (iconSize / 2);
-
-        // XXX: Lets keep the icon in the corner for the time being
-        offset = iconSize / 4;
-
-        /*
-        ((LayoutParams) mThumbnailView.getLayoutParams()).leftMargin = barHeight / 2;
-        ((LayoutParams) mThumbnailView.getLayoutParams()).rightMargin = barHeight / 2;
-        ((LayoutParams) mThumbnailView.getLayoutParams()).bottomMargin = barHeight;
-        */
-        ((LayoutParams) mIconView.getLayoutParams()).gravity = Gravity.END;
-        ((LayoutParams) mIconView.getLayoutParams()).width = iconSize;
-        ((LayoutParams) mIconView.getLayoutParams()).height = iconSize;
-        ((LayoutParams) mIconView.getLayoutParams()).topMargin = offset;
-        ((LayoutParams) mIconView.getLayoutParams()).rightMargin = offset;
     }
 
     /** Set callback */
@@ -284,54 +141,41 @@
 
     /** Animates this task view as it enters recents */
     public void animateOnEnterRecents() {
-        if (Constants.Values.TaskView.AnimateFrontTaskIconOnEnterUseClip) {
-            mIconView.setCircularClipRadius(0f);
-            mIconView.animateCircularClip(true, 1f,
-                Constants.Values.TaskView.Animation.TaskIconOnEnterDuration,
-                300, new AccelerateInterpolator(), null);
-        } else {
-            RecentsConfiguration config = RecentsConfiguration.getInstance();
-            int translate = config.pxFromDp(10);
-            mIconView.setScaleX(1.25f);
-            mIconView.setScaleY(1.25f);
-            mIconView.setAlpha(0f);
-            mIconView.setTranslationX(translate / 2);
-            mIconView.setTranslationY(-translate);
-            mIconView.animate()
-                    .alpha(1f)
-                    .scaleX(1f)
-                    .scaleY(1f)
-                    .translationX(0)
-                    .translationY(0)
-                    .setStartDelay(235)
-                    .setDuration(Constants.Values.TaskView.Animation.TaskIconOnEnterDuration)
-                    .withLayer()
-                    .start();
-        }
+        RecentsConfiguration config = RecentsConfiguration.getInstance();
+        int translate = config.pxFromDp(10);
+        mBarView.setScaleX(1.25f);
+        mBarView.setScaleY(1.25f);
+        mBarView.setAlpha(0f);
+        mBarView.setTranslationX(translate / 2);
+        mBarView.setTranslationY(-translate);
+        mBarView.animate()
+                .alpha(1f)
+                .scaleX(1f)
+                .scaleY(1f)
+                .translationX(0)
+                .translationY(0)
+                .setStartDelay(235)
+                .setDuration(Constants.Values.TaskView.Animation.TaskIconOnEnterDuration)
+                .withLayer()
+                .start();
     }
 
     /** Animates this task view as it exits recents */
     public void animateOnLeavingRecents(final Runnable r) {
-        if (Constants.Values.TaskView.AnimateFrontTaskIconOnLeavingUseClip) {
-            mIconView.animateCircularClip(false, 0f,
-                Constants.Values.TaskView.Animation.TaskIconOnLeavingDuration, 0,
-                new DecelerateInterpolator(),
-                new AnimatorListenerAdapter() {
-                    @Override
-                    public void onAnimationEnd(Animator animation) {
-                        r.run();
-                    }
-                });
-        } else {
-            mIconView.animate()
-                .alpha(0f)
-                .setStartDelay(0)
-                .setDuration(Constants.Values.TaskView.Animation.TaskIconOnLeavingDuration)
-                .setInterpolator(new DecelerateInterpolator())
-                .withLayer()
-                .withEndAction(r)
-                .start();
-        }
+        RecentsConfiguration config = RecentsConfiguration.getInstance();
+        int translate = config.pxFromDp(10);
+        mBarView.animate()
+            .alpha(0f)
+            .scaleX(1.1f)
+            .scaleY(1.1f)
+            .translationX(translate / 2)
+            .translationY(-translate)
+            .setStartDelay(0)
+            .setDuration(Constants.Values.TaskView.Animation.TaskIconOnLeavingDuration)
+            .setInterpolator(new DecelerateInterpolator())
+            .withLayer()
+            .withEndAction(r)
+            .start();
     }
 
     /** Returns the rect we want to clip (it may not be the full rect) */
@@ -370,17 +214,23 @@
 
     @Override
     public void onTaskDataLoaded(boolean reloadingTaskData) {
-        // Bind each of the views to the new task data
-        mThumbnailView.rebindToTask(mTask, reloadingTaskData);
-        mIconView.rebindToTask(mTask, reloadingTaskData);
+        if (mThumbnailView != null && mBarView != null) {
+            // Bind each of the views to the new task data
+            mThumbnailView.rebindToTask(mTask, reloadingTaskData);
+            mBarView.rebindToTask(mTask, reloadingTaskData);
+        }
+        mTaskDataLoaded = true;
     }
 
     @Override
     public void onTaskDataUnloaded() {
-        // Unbind each of the views from the task data and remove the task callback
-        mTask.setCallbacks(null);
-        mThumbnailView.unbindFromTask();
-        mIconView.unbindFromTask();
+        if (mThumbnailView != null && mBarView != null) {
+            // Unbind each of the views from the task data and remove the task callback
+            mTask.setCallbacks(null);
+            mThumbnailView.unbindFromTask();
+            mBarView.unbindFromTask();
+        }
+        mTaskDataLoaded = false;
     }
 
     @Override