Merge "Add animated checkbox"
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 478c541..73e3e05 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -116,6 +116,8 @@
     <integer name="recents_animate_task_bar_enter_duration">200</integer>
     <!-- The animation duration for animating in the info pane. -->
     <integer name="recents_animate_task_view_info_pane_duration">150</integer>
+    <!-- The minimum alpha for the dim applied to cards that go deeper into the stack. -->
+    <integer name="recents_max_task_stack_view_dim">96</integer>
 
     <!-- The maximum count of notifications on Keyguard. The rest will be collapsed in an overflow
      card. -->
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 94d3541..a50b40f 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -239,6 +239,9 @@
     <!-- The size of the activity icon in the recents task view. -->
     <dimen name="recents_task_view_activity_icon_size">60dp</dimen>
 
+    <!-- The radius of the rounded corners on a task view. -->
+    <dimen name="recents_task_view_rounded_corners_radius">2dp</dimen>
+
     <!-- The amount of space a user has to scroll to dismiss any info panes. -->
     <dimen name="recents_task_stack_scroll_dismiss_info_pane_distance">50dp</dimen>
 
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index f61c9f1..71c45f2 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -93,6 +93,12 @@
             getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
         } else {
             mEmptyView.setVisibility(View.GONE);
+
+            // Un-dim the background
+            WindowManager.LayoutParams wlp = getWindow().getAttributes();
+            wlp.dimAmount = 0f;
+            getWindow().setAttributes(wlp);
+            getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
index 9fdb5f9..5e5b841 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
@@ -41,7 +41,9 @@
     public int filteringNewViewsMinAnimDuration;
     public int taskBarEnterAnimDuration;
     public int taskStackScrollDismissInfoPaneDistance;
+    public int taskStackMaxDim;
     public int taskViewInfoPaneAnimDuration;
+    public int taskViewRoundedCornerRadiusPx;
 
     public boolean launchedWithThumbnailAnimation;
 
@@ -85,8 +87,11 @@
                 res.getInteger(R.integer.recents_animate_task_bar_enter_duration);
         taskStackScrollDismissInfoPaneDistance = res.getDimensionPixelSize(
                 R.dimen.recents_task_stack_scroll_dismiss_info_pane_distance);
+        taskStackMaxDim = res.getInteger(R.integer.recents_max_task_stack_view_dim);
         taskViewInfoPaneAnimDuration =
                 res.getInteger(R.integer.recents_animate_task_view_info_pane_duration);
+        taskViewRoundedCornerRadiusPx =
+                res.getDimensionPixelSize(R.dimen.recents_task_view_rounded_corners_radius);
     }
 
     /** Updates the system insets */
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 033bd67..ee92b16 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -564,8 +564,9 @@
         int minHeight = (int) (mStackRect.height() -
                 (Constants.Values.TaskStackView.StackPeekHeightPct * mStackRect.height()));
         int size = Math.min(minHeight, Math.min(mStackRect.width(), mStackRect.height()));
-        mTaskRect.set(mStackRect.left, mStackRectSansPeek.top,
-                mStackRect.right, mStackRectSansPeek.top + size);
+        int left = mStackRect.left + (mStackRect.width() - size) / 2;
+        mTaskRect.set(left, mStackRectSansPeek.top,
+                left + size, mStackRectSansPeek.top + size);
 
         // Update the scroll bounds
         updateMinMaxScroll(false);
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 81805d5..d3b79d6 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
@@ -16,15 +16,22 @@
 
 package com.android.systemui.recents.views;
 
+import android.animation.TimeInterpolator;
+import android.animation.ValueAnimator;
 import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Path;
 import android.graphics.Point;
 import android.graphics.Rect;
+import android.graphics.RectF;
 import android.util.AttributeSet;
 import android.view.MotionEvent;
 import android.view.View;
+import android.view.animation.AccelerateInterpolator;
 import android.widget.FrameLayout;
 import com.android.systemui.R;
 import com.android.systemui.recents.BakedBezierInterpolator;
+import com.android.systemui.recents.Constants;
 import com.android.systemui.recents.RecentsConfiguration;
 import com.android.systemui.recents.Utilities;
 import com.android.systemui.recents.model.Task;
@@ -43,10 +50,15 @@
         // public void onTaskViewReboundToTask(TaskView tv, Task t);
     }
 
+    int mDim;
+    int mMaxDim;
+    TimeInterpolator mDimInterpolator = new AccelerateInterpolator();
+
     Task mTask;
     boolean mTaskDataLoaded;
     boolean mTaskInfoPaneVisible;
     Point mLastTouchDown = new Point();
+    Path mRoundedRectClipPath = new Path();
 
     TaskThumbnailView mThumbnailView;
     TaskBarView mBarView;
@@ -68,10 +80,14 @@
 
     public TaskView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
         super(context, attrs, defStyleAttr, defStyleRes);
+        setWillNotDraw(false);
     }
 
     @Override
     protected void onFinishInflate() {
+        RecentsConfiguration config = RecentsConfiguration.getInstance();
+        mMaxDim = config.taskStackMaxDim;
+
         // Bind the views
         mThumbnailView = (TaskThumbnailView) findViewById(R.id.task_view_thumbnail);
         mBarView = (TaskBarView) findViewById(R.id.task_view_bar);
@@ -83,6 +99,18 @@
     }
 
     @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+
+        // Update the rounded rect clip path
+        RecentsConfiguration config = RecentsConfiguration.getInstance();
+        float radius = config.taskViewRoundedCornerRadiusPx;
+        mRoundedRectClipPath.reset();
+        mRoundedRectClipPath.addRoundRect(new RectF(0, 0, getMeasuredWidth(), getMeasuredHeight()),
+                radius, radius, Path.Direction.CW);
+    }
+
+    @Override
     public boolean onInterceptTouchEvent(MotionEvent ev) {
         switch (ev.getAction()) {
             case MotionEvent.ACTION_DOWN:
@@ -120,6 +148,12 @@
                     .setDuration(duration)
                     .setInterpolator(BakedBezierInterpolator.INSTANCE)
                     .withLayer()
+                    .setUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+                        @Override
+                        public void onAnimationUpdate(ValueAnimator animation) {
+                            updateDimOverlayFromScale();
+                        }
+                    })
                     .start();
         } else {
             setTranslationY(toTransform.translationY);
@@ -127,6 +161,8 @@
             setScaleY(toTransform.scale);
             setAlpha(toTransform.alpha);
         }
+        updateDimOverlayFromScale();
+        invalidate();
     }
 
     /** Resets this view's properties */
@@ -136,6 +172,7 @@
         setScaleX(1f);
         setScaleY(1f);
         setAlpha(1f);
+        invalidate();
     }
 
     /**
@@ -278,6 +315,29 @@
         mThumbnailView.setLayerType(View.LAYER_TYPE_NONE, null);
     }
 
+    /** Update the dim as a function of the scale of this view. */
+    void updateDimOverlayFromScale() {
+        float minScale = Constants.Values.TaskStackView.StackPeekMinScale;
+        float scaleRange = 1f - minScale;
+        float dim = (1f - getScaleX()) / scaleRange;
+        dim = mDimInterpolator.getInterpolation(Math.min(dim, 1f));
+        mDim = Math.max(0, Math.min(mMaxDim, (int) (dim * 255)));
+        invalidate();
+    }
+
+    @Override
+    public void draw(Canvas canvas) {
+        // Apply the rounded rect clip path on the whole view
+        canvas.clipPath(mRoundedRectClipPath);
+
+        super.draw(canvas);
+
+        // Apply the dim if necessary
+        if (mDim > 0) {
+            canvas.drawColor(mDim << 24);
+        }
+    }
+
     /**** TaskCallbacks Implementation ****/
 
     /** Binds this task view to the task */