Merge "Updating layouts to use frame vs translation and clipping."
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/AnimateableViewBounds.java b/packages/SystemUI/src/com/android/systemui/recents/views/AnimateableViewBounds.java
index 757d2aa..f646a92 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/AnimateableViewBounds.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/AnimateableViewBounds.java
@@ -46,19 +46,6 @@
                 }
             };
 
-    public static final Property<AnimateableViewBounds, Integer> CLIP_RIGHT =
-            new IntProperty<AnimateableViewBounds>("clipRight") {
-                @Override
-                public void setValue(AnimateableViewBounds object, int clip) {
-                    object.setClipRight(clip, false /* force */);
-                }
-
-                @Override
-                public Integer get(AnimateableViewBounds object) {
-                    return object.getClipRight();
-                }
-            };
-
     public AnimateableViewBounds(View source, int cornerRadius) {
         mSourceView = source;
         mCornerRadius = cornerRadius;
@@ -102,19 +89,6 @@
         return mClipRect.bottom;
     }
 
-    /** Sets the right clip. */
-    public void setClipRight(int right, boolean force) {
-        if (right != mClipRect.right || force) {
-            mClipRect.right = right;
-            updateClipBounds();
-        }
-    }
-
-    /** Returns the right clip. */
-    public int getClipRight() {
-        return mClipRect.right;
-    }
-
     private void updateClipBounds() {
         mClipBounds.set(mClipRect.left, mClipRect.top,
                 mSourceView.getWidth() - mClipRect.right,
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/FreeformWorkspaceLayoutAlgorithm.java b/packages/SystemUI/src/com/android/systemui/recents/views/FreeformWorkspaceLayoutAlgorithm.java
index 9b9d58c..25f9e80 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/FreeformWorkspaceLayoutAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/FreeformWorkspaceLayoutAlgorithm.java
@@ -19,7 +19,6 @@
 import android.graphics.Rect;
 import android.graphics.RectF;
 import android.util.Log;
-import com.android.systemui.recents.misc.Utilities;
 import com.android.systemui.recents.model.Task;
 
 import java.util.Collections;
@@ -80,7 +79,6 @@
                 float width = normalizedTaskWidths[i] * rowScale;
                 if (rowWidth + width > normalizedWorkspaceWidth) {
                     // That is too long for this row, create new row
-                    rowWidth = 0f;
                     if ((rowCount + 1) * rowScale > normalizedWorkspaceHeight) {
                         // The new row is too high, so we need to try fitting again.  Update the
                         // scale to be the smaller of the scale needed to fit the task in the
@@ -88,9 +86,11 @@
                         rowScale = Math.min(normalizedWorkspaceWidth / (rowWidth + width),
                                 normalizedWorkspaceHeight / (rowCount + 1));
                         rowCount = 1;
+                        rowWidth = 0;
                         i = 0;
                     } else {
                         // The new row fits, so continue
+                        rowWidth = width;
                         rowCount++;
                         i++;
                     }
@@ -103,20 +103,20 @@
             }
 
             // Normalize each of the actual rects to that scale
-            int height = (int) (rowScale * workspaceHeight);
-            float rowTop = ((1f - (rowScale * rowCount)) * workspaceHeight) / 2f;
             float defaultRowLeft = ((1f - (maxRowWidth / normalizedWorkspaceWidth)) *
                     workspaceWidth) / 2f;
             float rowLeft = defaultRowLeft;
+            float rowTop = ((1f - (rowScale * rowCount)) * workspaceHeight) / 2f;
+            float rowHeight = rowScale * workspaceHeight;
             for (int i = 0; i < numFreeformTasks; i++) {
                 Task task = freeformTasks.get(i);
-                int width = (int) (height * normalizedTaskWidths[i]);
+                float width = rowHeight * normalizedTaskWidths[i];
                 if (rowLeft + width > workspaceWidth) {
                     // This goes on the next line
-                    rowTop += height;
+                    rowTop += rowHeight;
                     rowLeft = defaultRowLeft;
                 }
-                RectF rect = new RectF(rowLeft, rowTop, rowLeft + width, rowTop + height);
+                RectF rect = new RectF(rowLeft, rowTop, rowLeft + width, rowTop + rowHeight);
                 rowLeft += width;
                 mTaskRectMap.put(task.key, rect);
             }
@@ -140,34 +140,29 @@
     public TaskViewTransform getTransform(Task task, TaskViewTransform transformOut,
             TaskStackLayoutAlgorithm stackLayout) {
         if (mTaskRectMap.containsKey(task.key)) {
-            Rect taskRect = stackLayout.mTaskRect;
-            RectF ffRect = mTaskRectMap.get(task.key);
-            float scale = Math.max(ffRect.width() / taskRect.width(),
-                    ffRect.height() / taskRect.height());
-            int topOffset = (stackLayout.mFreeformRect.top - taskRect.top);
-            int scaleXOffset = (int) (((1f - scale) * taskRect.width()) / 2);
-            int scaleYOffset = (int) (((1f - scale) * taskRect.height()) / 2);
+            final Rect taskRect = stackLayout.mTaskRect;
+            final RectF ffRect = mTaskRectMap.get(task.key);
 
-            transformOut.scale = scale * 0.95f;
-            transformOut.translationX = (int) (ffRect.left - scaleXOffset);
-            transformOut.translationY = (int) (topOffset + ffRect.top - scaleYOffset);
+            transformOut.scale = 0.95f;
+            transformOut.alpha = 1f;
             transformOut.translationZ = stackLayout.mMaxTranslationZ;
-            transformOut.clipBottom = (int) (taskRect.height() - (ffRect.height() / scale));
-            transformOut.clipRight = (int) (taskRect.width() - (ffRect.width() / scale));
             if (task.thumbnail != null) {
-                transformOut.thumbnailScale = Math.min(
-                        ((float) taskRect.width() - transformOut.clipRight) /
-                                task.thumbnail.getWidth(),
-                        ((float) taskRect.height() - transformOut.clipBottom) /
-                                task.thumbnail.getHeight());
+                if (task.bounds == null) {
+                    // This is a stack task that has no freeform thumbnail, so keep the same bitmap
+                    // scale as it had in the stack
+                    transformOut.thumbnailScale = (float) taskRect.width() /
+                            task.thumbnail.getWidth();
+                } else {
+                    // This is a freeform rect so fit the bitmap to the task bounds
+                    transformOut.thumbnailScale = Math.min(
+                            ffRect.width() / task.thumbnail.getWidth(),
+                            ffRect.height() / task.thumbnail.getHeight());
+                }
             } else {
                 transformOut.thumbnailScale = 1f;
             }
-            transformOut.rect.set(taskRect);
-            transformOut.rect.offset(transformOut.translationX, transformOut.translationY);
-            Utilities.scaleRectAboutCenter(transformOut.rect, transformOut.scale);
-            transformOut.rect.right -= transformOut.clipRight * scale;
-            transformOut.rect.bottom -= transformOut.clipBottom * scale;
+            transformOut.rect.set(ffRect);
+            transformOut.rect.offset(stackLayout.mFreeformRect.left, stackLayout.mFreeformRect.top);
             transformOut.visible = true;
             transformOut.p = 1f;
 
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
index 7d5daae..f599f52 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
@@ -507,6 +507,15 @@
     }
 
     /**
+     * Returns the task progress that would put the task just off the back of the stack.
+     */
+    public float getStackBackTaskProgress(float stackScroll) {
+        float min = mUnfocusedRange.relativeMin +
+                mFocusState * (mFocusedRange.relativeMin - mUnfocusedRange.relativeMin);
+        return stackScroll + min;
+    }
+
+    /**
      * Returns the task progress that would put the task just off the front of the stack.
      */
     public float getStackFrontTaskProgress(float stackScroll) {
@@ -647,6 +656,7 @@
             return transformOut;
         }
 
+        int x = (mStackRect.width() - mTaskRect.width()) / 2;
         int y;
         float z;
         float relP;
@@ -671,16 +681,13 @@
 
         // Fill out the transform
         transformOut.scale = 1f;
-        transformOut.translationX = (mStackRect.width() - mTaskRect.width()) / 2;
-        transformOut.translationY = y;
+        transformOut.alpha = 1f;
         transformOut.translationZ = z;
         transformOut.rect.set(mTaskRect);
-        transformOut.rect.offset(transformOut.translationX, transformOut.translationY);
+        transformOut.rect.offset(x, y);
         Utilities.scaleRectAboutCenter(transformOut.rect, transformOut.scale);
         transformOut.visible = (transformOut.rect.top < mStackRect.bottom) &&
                 (frontTransform == null || transformOut.rect.top != frontTransform.rect.top);
-        transformOut.clipBottom = 0;
-        transformOut.clipRight = 0;
         transformOut.thumbnailScale = 1f;
         transformOut.p = relP;
         return transformOut;
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 cc5aaae..831cb12 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -20,6 +20,7 @@
 import android.animation.ValueAnimator;
 import android.content.ComponentName;
 import android.content.Context;
+import android.content.res.Resources;
 import android.graphics.Canvas;
 import android.graphics.Rect;
 import android.graphics.RectF;
@@ -126,6 +127,7 @@
     Task mFocusedTask;
     // Optimizations
     int mStackViewsAnimationDuration;
+    int mTaskCornerRadiusPx;
     boolean mStackViewsDirty = true;
     boolean mStackViewsClipDirty = true;
     boolean mAwaitingFirstLayout = true;
@@ -174,6 +176,8 @@
 
     public TaskStackView(Context context, TaskStack stack) {
         super(context);
+        Resources res = context.getResources();
+
         // Set the stack first
         setStack(stack);
         mViewPool = new ViewPool<>(context, this);
@@ -184,6 +188,8 @@
         mTouchHandler = new TaskStackViewTouchHandler(context, this, mStackScroller);
         mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(context,
                 com.android.internal.R.interpolator.fast_out_slow_in);
+        mTaskCornerRadiusPx = res.getDimensionPixelSize(
+                R.dimen.recents_task_view_rounded_corners_radius);
 
         int taskBarDismissDozeDelaySeconds = getResources().getInteger(
                 R.integer.recents_task_bar_dismiss_delay_seconds);
@@ -364,8 +370,7 @@
     private boolean updateStackTransforms(ArrayList<TaskViewTransform> taskTransforms,
                                        ArrayList<Task> tasks,
                                        float stackScroll,
-                                       int[] visibleRangeOut,
-                                       boolean boundTranslationsToRect) {
+                                       int[] visibleRangeOut) {
         int taskTransformCount = taskTransforms.size();
         int taskCount = tasks.size();
         int frontMostVisibleIndex = -1;
@@ -411,11 +416,6 @@
                     break;
                 }
             }
-
-            if (boundTranslationsToRect) {
-                transform.translationY = Math.min(transform.translationY,
-                        mLayoutAlgorithm.mStackRect.bottom);
-            }
             frontTransform = transform;
         }
         if (visibleRangeOut != null) {
@@ -433,7 +433,7 @@
             float stackScroll = mStackScroller.getStackScroll();
             int[] visibleStackRange = mTmpVisibleRange;
             boolean isValidVisibleStackRange = updateStackTransforms(mCurrentTaskTransforms, tasks,
-                    stackScroll, visibleStackRange, false);
+                    stackScroll, visibleStackRange);
             boolean hasStackBackTransform = false;
             boolean hasStackFrontTransform = false;
             if (DEBUG) {
@@ -490,7 +490,7 @@
                 }
 
                 // Animate the task into place
-                tv.updateViewPropertiesToTaskTransform(transform, transform.clipBottom,
+                tv.updateViewPropertiesToTaskTransform(transform, 0,
                         mStackViewsAnimationDuration, mFastOutSlowInInterpolator,
                         mRequestUpdateClippingListener);
 
@@ -513,8 +513,9 @@
                         if (Float.compare(transform.p, 0f) <= 0) {
                             if (!hasStackBackTransform) {
                                 hasStackBackTransform = true;
-                                mLayoutAlgorithm.getStackTransform(0f, 0f, mTmpStackBackTransform,
-                                        null);
+                                mLayoutAlgorithm.getStackTransform(
+                                        mLayoutAlgorithm.getStackBackTaskProgress(0f), 0f,
+                                        mTmpStackBackTransform, null);
                             }
                             tv.updateViewPropertiesToTaskTransform(mTmpStackBackTransform, 0, 0,
                                     mFastOutSlowInInterpolator, mRequestUpdateClippingListener);
@@ -586,17 +587,11 @@
                 // stacked and we can make assumptions about the visibility of the this
                 // task relative to the ones in front of it.
                 if (frontTv != null) {
-                    mTmpTaskRect.set(mLayoutAlgorithm.mTaskRect);
-                    mTmpTaskRect.offset(0, tv.getTranslationY());
-                    Utilities.scaleRectAboutCenter(mTmpTaskRect, tv.getScaleX());
-                    float taskBottom = mTmpTaskRect.bottom;
-                    mTmpTaskRect.set(mLayoutAlgorithm.mTaskRect);
-                    mTmpTaskRect.offset(0, frontTv.getTranslationY());
-                    Utilities.scaleRectAboutCenter(mTmpTaskRect, frontTv.getScaleX());
-                    float frontTaskTop = mTmpTaskRect.top;
+                    float taskBottom = tv.getBottom();
+                    float frontTaskTop = frontTv.getTop();
                     if (frontTaskTop < taskBottom) {
                         // Map the stack view space coordinate (the rects) to view space
-                        clipBottom = (int) ((taskBottom - frontTaskTop) / tv.getScaleX()) - 1;
+                        clipBottom = (int) (taskBottom - frontTaskTop) - mTaskCornerRadiusPx;
                     }
                 }
             }
@@ -980,11 +975,11 @@
             onFirstLayout();
         }
 
+        requestSynchronizeStackViewsWithModel();
         if (changed) {
             if (mStackScroller.isScrollOutOfBounds()) {
                 mStackScroller.boundScroll();
             }
-            requestSynchronizeStackViewsWithModel();
             synchronizeStackViewsWithModel();
             requestUpdateStackViewsClip();
             clipTaskViews(true /* forceUpdate */);
@@ -1147,8 +1142,7 @@
         transformPointToViewLocal(point, tv);
         x = point[0];
         y = point[1];
-        return (0 <= x) && (x < (tv.getMeasuredWidth() - tv.getViewBounds().getClipRight())) &&
-                (0 <= y) && (y < (tv.getMeasuredHeight() - tv.getViewBounds().getClipBottom()));
+        return (0 <= x) && (x < tv.getWidth()) && (0 <= y) && (y < tv.getHeight());
     }
 
     @Override
@@ -1498,6 +1492,18 @@
         event.taskView.animate()
                 .withEndAction(event.postAnimationTrigger.decrementAsRunnable());
 
+        // We translated the view but we need to animate it back from the current layout-space rect
+        // to its final layout-space rect
+        int x = (int) event.taskView.getTranslationX();
+        int y = (int) event.taskView.getTranslationY();
+        Rect taskViewRect = new Rect(event.taskView.getLeft(), event.taskView.getTop(),
+                event.taskView.getRight(), event.taskView.getBottom());
+        taskViewRect.offset(x, y);
+        event.taskView.setTranslationX(0);
+        event.taskView.setTranslationY(0);
+        event.taskView.setLeftTopRightBottom(taskViewRect.left, taskViewRect.top,
+                taskViewRect.right, taskViewRect.bottom);
+
         // Animate the tack view back into position
         requestSynchronizeStackViewsWithModel(250);
     }
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 813a1fc..4997709 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
@@ -232,8 +232,14 @@
             mClipAnimation.playTogether(
                     ObjectAnimator.ofInt(mViewBounds, AnimateableViewBounds.CLIP_BOTTOM,
                             mViewBounds.getClipBottom(), clipBottom),
-                    ObjectAnimator.ofInt(mViewBounds, AnimateableViewBounds.CLIP_RIGHT,
-                            mViewBounds.getClipRight(), toTransform.clipRight),
+                    ObjectAnimator.ofInt(this, TaskViewTransform.LEFT, getLeft(),
+                            (int) toTransform.rect.left),
+                    ObjectAnimator.ofInt(this, TaskViewTransform.TOP, getTop(),
+                            (int) toTransform.rect.top),
+                    ObjectAnimator.ofInt(this, TaskViewTransform.RIGHT, getRight(),
+                            (int) toTransform.rect.right),
+                    ObjectAnimator.ofInt(this, TaskViewTransform.BOTTOM, getBottom(),
+                            (int) toTransform.rect.bottom),
                     ObjectAnimator.ofFloat(mThumbnailView, TaskViewThumbnail.BITMAP_SCALE,
                             mThumbnailView.getBitmapScale(), toTransform.thumbnailScale));
             mClipAnimation.setStartDelay(toTransform.startDelay);
@@ -242,8 +248,9 @@
             mClipAnimation.start();
         } else {
             mViewBounds.setClipBottom(clipBottom, false /* forceUpdate */);
-            mViewBounds.setClipRight(toTransform.clipRight, false /* forceUpdate */);
             mThumbnailView.setBitmapScale(toTransform.thumbnailScale);
+            setLeftTopRightBottom((int) toTransform.rect.left, (int) toTransform.rect.top,
+                    (int) toTransform.rect.right, (int) toTransform.rect.bottom);
         }
         if (!config.useHardwareLayers) {
             mThumbnailView.updateThumbnailVisibility(clipBottom - getPaddingBottom());
@@ -336,10 +343,10 @@
             } else {
                 // Animate the task up if it was occluding the launch target
                 if (ctx.currentTaskOccludesLaunchTarget) {
-                    setTranslationY(transform.translationY + taskViewAffiliateGroupEnterOffset);
+                    setTranslationY(taskViewAffiliateGroupEnterOffset);
                     setAlpha(0f);
                     animate().alpha(1f)
-                            .translationY(transform.translationY)
+                            .translationY(0)
                             .setUpdateListener(null)
                             .setListener(new AnimatorListenerAdapter() {
                                 private boolean hasEnded;
@@ -372,7 +379,7 @@
                 animate().translationZ(transform.translationZ);
             }
             animate()
-                    .translationY(transform.translationY)
+                    .translationY(0)
                     .setStartDelay(delay)
                     .setUpdateListener(ctx.updateListener)
                     .setListener(new AnimatorListenerAdapter() {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
index 78a2c7f..d782a63 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
@@ -103,7 +103,7 @@
         setOutlineProvider(new ViewOutlineProvider() {
             @Override
             public void getOutline(View view, Outline outline) {
-                outline.setRect(0, 0, getMeasuredWidth(), getMeasuredHeight());
+                outline.setRect(0, 0, getWidth(), getHeight());
             }
         });
 
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewTransform.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewTransform.java
index c3e0906..3ee50ac 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewTransform.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewTransform.java
@@ -18,6 +18,9 @@
 
 import android.animation.ValueAnimator;
 import android.graphics.RectF;
+import android.util.IntProperty;
+import android.util.Property;
+import android.view.View;
 import android.view.ViewPropertyAnimator;
 import android.view.animation.Interpolator;
 
@@ -25,26 +28,70 @@
 /* The transform state for a task view */
 public class TaskViewTransform {
 
+    public static final Property<View, Integer> LEFT =
+            new IntProperty<View>("left") {
+                @Override
+                public void setValue(View object, int v) {
+                    object.setLeft(v);
+                }
+
+                @Override
+                public Integer get(View object) {
+                    return object.getLeft();
+                }
+            };
+
+    public static final Property<View, Integer> TOP =
+            new IntProperty<View>("top") {
+                @Override
+                public void setValue(View object, int v) {
+                    object.setTop(v);
+                }
+
+                @Override
+                public Integer get(View object) {
+                    return object.getTop();
+                }
+            };
+
+    public static final Property<View, Integer> RIGHT =
+            new IntProperty<View>("right") {
+                @Override
+                public void setValue(View object, int v) {
+                    object.setRight(v);
+                }
+
+                @Override
+                public Integer get(View object) {
+                    return object.getRight();
+                }
+            };
+
+    public static final Property<View, Integer> BOTTOM =
+            new IntProperty<View>("bottom") {
+                @Override
+                public void setValue(View object, int v) {
+                    object.setBottom(v);
+                }
+
+                @Override
+                public Integer get(View object) {
+                    return object.getBottom();
+                }
+            };
+
     // TODO: Move this out of the transform
     public int startDelay = 0;
 
-    public int translationX = 0;
-    public int translationY = 0;
     public float translationZ = 0;
     public float scale = 1f;
     public float alpha = 1f;
-
-    // Clip and thumbnail scale are untransformed layout-space properties
-    // The bottom clip is only used for freeform workspace tasks
-    public int clipBottom = 0;
-    public int clipRight = 0;
     public float thumbnailScale = 1f;
 
     public boolean visible = false;
     float p = 0f;
 
-    // This is a window-space rect that is purely used for coordinating the animation of an app
-    // window into Recents.
+    // This is a window-space rect used for positioning the task in the stack and freeform workspace
     public RectF rect = new RectF();
 
     public TaskViewTransform() {
@@ -56,13 +103,9 @@
      */
     public void reset() {
         startDelay = 0;
-        translationX = 0;
-        translationY = 0;
         translationZ = 0;
         scale = 1f;
         alpha = 1f;
-        clipBottom = 0;
-        clipRight = 0;
         thumbnailScale = 1f;
         visible = false;
         rect.setEmpty();
@@ -76,12 +119,6 @@
     public boolean hasScaleChangedFrom(float v) {
         return (Float.compare(scale, v) != 0);
     }
-    public boolean hasTranslationXChangedFrom(float v) {
-        return (Float.compare(translationX, v) != 0);
-    }
-    public boolean hasTranslationYChangedFrom(float v) {
-        return (Float.compare(translationY, v) != 0);
-    }
     public boolean hasTranslationZChangedFrom(float v) {
         return (Float.compare(translationZ, v) != 0);
     }
@@ -95,12 +132,6 @@
             boolean requiresLayers = false;
 
             // Animate to the final state
-            if (hasTranslationXChangedFrom(v.getTranslationX())) {
-                anim.translationX(translationX);
-            }
-            if (hasTranslationYChangedFrom(v.getTranslationY())) {
-                anim.translationY(translationY);
-            }
             if (allowShadows && hasTranslationZChangedFrom(v.getTranslationZ())) {
                 anim.translationZ(translationZ);
             }
@@ -129,12 +160,6 @@
                     .start();
         } else {
             // Set the changed properties
-            if (hasTranslationXChangedFrom(v.getTranslationX())) {
-                v.setTranslationX(translationX);
-            }
-            if (hasTranslationYChangedFrom(v.getTranslationY())) {
-                v.setTranslationY(translationY);
-            }
             if (allowShadows && hasTranslationZChangedFrom(v.getTranslationZ())) {
                 v.setTranslationZ(translationZ);
             }
@@ -150,7 +175,8 @@
 
     /** Reset the transform on a view. */
     public static void reset(TaskView v) {
-        // Cancel any running animations
+        // Cancel any running animations and reset the translation in case something else (like a
+        // dismiss animation) changes it
         v.animate().cancel();
         v.setTranslationX(0f);
         v.setTranslationY(0f);
@@ -158,16 +184,15 @@
         v.setScaleX(1f);
         v.setScaleY(1f);
         v.setAlpha(1f);
-        v.getViewBounds().setClipRight(0, false /* forceUpdate */);
         v.getViewBounds().setClipBottom(0, false /* forceUpdate */);
+        v.setLeftTopRightBottom(0, 0, 0, 0);
         v.mThumbnailView.setBitmapScale(1f);
     }
 
     @Override
     public String toString() {
-        return "TaskViewTransform delay: " + startDelay +
-                " x: " + translationX + " y: " + translationY + " z: " + translationZ +
-                " scale: " + scale + " alpha: " + alpha + " visible: " + visible + " rect: " + rect +
-                " p: " + p;
+        return "TaskViewTransform delay: " + startDelay + " z: " + translationZ +
+                " scale: " + scale + " alpha: " + alpha + " visible: " + visible +
+                " rect: " + rect + " p: " + p;
     }
 }