Cleaning up some old animation code, only setting view properties that have changed.

- Also drawing a background on the thumbnails if a transparent thumbnail is detected.

Change-Id: I3f5450d207ae0796150c8b04aabc2f910f80e0a7
diff --git a/packages/SystemUI/src/com/android/systemui/recents/SystemServicesProxy.java b/packages/SystemUI/src/com/android/systemui/recents/SystemServicesProxy.java
index f532aa0..c47f7d7 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/SystemServicesProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/SystemServicesProxy.java
@@ -30,18 +30,21 @@
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
 import android.graphics.Bitmap;
-import android.graphics.Matrix;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffXfermode;
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
 import android.os.Bundle;
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.os.UserManager;
-import android.util.DisplayMetrics;
+import android.util.Log;
 import android.util.Pair;
 import android.view.Display;
 import android.view.DisplayInfo;
-import android.view.Surface;
 import android.view.SurfaceControl;
 import android.view.WindowManager;
 
@@ -55,6 +58,8 @@
  * a point of injection when testing UI.
  */
 public class SystemServicesProxy {
+    final static String TAG = "SystemServicesProxy";
+
     ActivityManager mAm;
     AppWidgetManager mAwm;
     PackageManager mPm;
@@ -67,6 +72,8 @@
     ComponentName mAssistComponent;
 
     Bitmap mDummyIcon;
+    Paint mBgProtectionPaint;
+    Canvas mBgProtectionCanvas;
 
     /** Private constructor */
     public SystemServicesProxy(Context context) {
@@ -80,6 +87,12 @@
         mDisplay = mWm.getDefaultDisplay();
         mRecentsPackage = context.getPackageName();
 
+        // Create the protection paints
+        mBgProtectionPaint = new Paint();
+        mBgProtectionPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_ATOP));
+        mBgProtectionPaint.setColor(0xFFffffff);
+        mBgProtectionCanvas = new Canvas();
+
         // Resolve the assist intent
         Intent assist = mSm.getAssistIntent(context, false);
         if (assist != null) {
@@ -195,7 +208,20 @@
             return thumbnail;
         }
 
-        return mAm.getTaskTopThumbnail(taskId);
+        Bitmap thumbnail = mAm.getTaskTopThumbnail(taskId);
+        if (thumbnail != null) {
+            // We use a dumb heuristic for now, if the thumbnail is purely transparent in the top
+            // left pixel, then assume the whole thumbnail is transparent. Generally, proper
+            // screenshots are always composed onto a bitmap that has no alpha.
+            if (Color.alpha(thumbnail.getPixel(0, 0)) == 0) {
+                mBgProtectionCanvas.setBitmap(thumbnail);
+                mBgProtectionCanvas.drawRect(0, 0, thumbnail.getWidth(), thumbnail.getHeight(),
+                        mBgProtectionPaint);
+                mBgProtectionCanvas.setBitmap(null);
+                Log.e(TAG, "Invalid screenshot detected from getTaskThumbnail()");
+            }
+        }
+        return thumbnail;
     }
 
     /** Moves a task to the front with the specified activity options */
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskBarView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskBarView.java
index 7f7a435..d4f381b 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskBarView.java
@@ -22,10 +22,10 @@
 import android.graphics.Paint;
 import android.graphics.PorterDuff;
 import android.graphics.PorterDuffXfermode;
-import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
 import android.view.View;
+import android.view.ViewPropertyAnimator;
 import android.widget.FrameLayout;
 import android.widget.ImageView;
 import android.widget.TextView;
@@ -103,21 +103,24 @@
     }
 
     /** Synchronizes this bar view's properties with the task's transform */
-    void updateViewPropertiesToTaskTransform(TaskViewTransform animateFromTransform,
-                                             TaskViewTransform toTransform, int duration) {
+    void updateViewPropertiesToTaskTransform(TaskViewTransform toTransform, int duration) {
         if (duration > 0 && (mDismissButton.getVisibility() == View.VISIBLE)) {
-            if (animateFromTransform != null) {
-                mDismissButton.setAlpha(animateFromTransform.dismissAlpha);
-            }
-            mDismissButton.animate()
-                    .alpha(toTransform.dismissAlpha)
+            ViewPropertyAnimator anim = mDismissButton.animate();
+
+            // Animate to the final state
+            if (toTransform.hasDismissAlphaChangedFrom(mDismissButton.getAlpha())) {
+                anim.alpha(toTransform.dismissAlpha)
                     .setStartDelay(0)
                     .setDuration(duration)
                     .setInterpolator(mConfig.fastOutSlowInInterpolator)
                     .withLayer()
                     .start();
+            }
         } else {
-            mDismissButton.setAlpha(toTransform.dismissAlpha);
+            // Set the changed properties
+            if (toTransform.hasDismissAlphaChangedFrom(mDismissButton.getAlpha())) {
+                mDismissButton.setAlpha(toTransform.dismissAlpha);
+            }
         }
     }
 
@@ -169,7 +172,6 @@
                 .setStartDelay(delay)
                 .setInterpolator(mConfig.fastOutSlowInInterpolator)
                 .setDuration(mConfig.taskBarEnterAnimDuration)
-                .withLayer()
                 .withEndAction(postAnimRunnable)
                 .start();
     }
@@ -182,7 +184,6 @@
                 .setStartDelay(0)
                 .setInterpolator(mConfig.fastOutLinearInInterpolator)
                 .setDuration(mConfig.taskBarExitAnimDuration)
-                .withLayer()
                 .withStartAction(preAnimRunnable)
                 .withEndAction(new Runnable() {
                     @Override
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 deac114..79bfa5e 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -322,7 +322,7 @@
                         if (mStackViewsAnimationDuration > 0 && i != 0) {
                             int fromIndex = (transform.t < 0) ? (visibleRange[0] - 1) :
                                     (visibleRange[1] + 1);
-                            tv.updateViewPropertiesToTaskTransform(null,
+                            tv.updateViewPropertiesToTaskTransform(
                                     getStackTransform(fromIndex, stackScroll), 0);
                         }
                     }
@@ -343,7 +343,7 @@
                 if (taskIndex < 0 || !mTaskTransforms.get(taskIndex).visible) {
                     mViewPool.returnViewToPool(tv);
                 } else {
-                    tv.updateViewPropertiesToTaskTransform(null, mTaskTransforms.get(taskIndex),
+                    tv.updateViewPropertiesToTaskTransform(mTaskTransforms.get(taskIndex),
                             mStackViewsAnimationDuration);
                 }
             }
@@ -996,7 +996,7 @@
                     // Compose a new transform to fade and slide the new task in
                     TaskViewTransform fromTransform = new TaskViewTransform(toTransform);
                     tv.prepareTaskTransformForFilterTaskHidden(fromTransform);
-                    tv.updateViewPropertiesToTaskTransform(null, fromTransform, 0);
+                    tv.updateViewPropertiesToTaskTransform(fromTransform, 0);
 
                     int startDelay = offset *
                             Constants.Values.TaskStackView.FilterStartDelay;
@@ -1059,13 +1059,13 @@
                                     for (final TaskView tv : childViewTransforms.keySet()) {
                                         Pair<Integer, TaskViewTransform> t = childViewTransforms.get(tv);
                                         tv.animate().setStartDelay(t.first);
-                                        tv.updateViewPropertiesToTaskTransform(null, t.second, duration);
+                                        tv.updateViewPropertiesToTaskTransform(t.second, duration);
                                     }
                                 }
                             }
                         }
                     });
-            tv.updateViewPropertiesToTaskTransform(null, t.second, duration);
+            tv.updateViewPropertiesToTaskTransform(t.second, duration);
         }
     }
 
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 f84d564..b7e834b 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
@@ -29,6 +29,7 @@
 import android.util.AttributeSet;
 import android.view.MotionEvent;
 import android.view.View;
+import android.view.ViewPropertyAnimator;
 import android.view.animation.AccelerateInterpolator;
 import android.widget.FrameLayout;
 import com.android.systemui.R;
@@ -163,50 +164,64 @@
     }
 
     /** Synchronizes this view's properties with the task's transform */
-    void updateViewPropertiesToTaskTransform(TaskViewTransform animateFromTransform,
-                                             TaskViewTransform toTransform, int duration) {
+    void updateViewPropertiesToTaskTransform(TaskViewTransform toTransform, int duration) {
         if (Console.Enabled) {
             Console.log(Constants.Log.UI.Draw, "[TaskView|updateViewPropertiesToTaskTransform]",
                     "duration: " + duration, Console.AnsiPurple);
         }
 
         // Update the bar view
-        mBarView.updateViewPropertiesToTaskTransform(animateFromTransform, toTransform, duration);
+        mBarView.updateViewPropertiesToTaskTransform(toTransform, duration);
 
-        // Update this task view
+        // Check to see if any properties have changed, and update the task view
         if (duration > 0) {
-            if (animateFromTransform != null) {
-                setTranslationY(animateFromTransform.translationY);
-                if (Constants.DebugFlags.App.EnableShadows) {
-                    setTranslationZ(animateFromTransform.translationZ);
-                }
-                setScaleX(animateFromTransform.scale);
-                setScaleY(animateFromTransform.scale);
-                setAlpha(animateFromTransform.alpha);
+            ViewPropertyAnimator anim = animate();
+            boolean useLayers = false;
+
+            // Animate to the final state
+            if (toTransform.hasTranslationYChangedFrom(getTranslationY())) {
+                anim.translationY(toTransform.translationY);
             }
-            if (Constants.DebugFlags.App.EnableShadows) {
-                animate().translationZ(toTransform.translationZ);
+            if (Constants.DebugFlags.App.EnableShadows &&
+                    toTransform.hasTranslationZChangedFrom(getTranslationZ())) {
+                anim.translationZ(toTransform.translationZ);
             }
-            animate().translationY(toTransform.translationY)
-                    .scaleX(toTransform.scale)
+            if (toTransform.hasScaleChangedFrom(getScaleX())) {
+                anim.scaleX(toTransform.scale)
                     .scaleY(toTransform.scale)
-                    .alpha(toTransform.alpha)
-                    .setStartDelay(0)
-                    .setDuration(duration)
-                    .setInterpolator(mConfig.fastOutSlowInInterpolator)
-                    .setUpdateListener(mUpdateDimListener)
-                    .start();
+                    .setUpdateListener(mUpdateDimListener);
+                useLayers = true;
+            }
+            if (toTransform.hasAlphaChangedFrom(getAlpha())) {
+                // Use layers if we animate alpha
+                anim.alpha(toTransform.alpha);
+                useLayers = true;
+            }
+            if (useLayers) {
+                anim.withLayer();
+            }
+            anim.setStartDelay(0)
+                .setDuration(duration)
+                .setInterpolator(mConfig.fastOutSlowInInterpolator)
+                .start();
         } else {
-            setTranslationY(toTransform.translationY);
-            if (Constants.DebugFlags.App.EnableShadows) {
+            // Set the changed properties
+            if (toTransform.hasTranslationYChangedFrom(getTranslationY())) {
+                setTranslationY(toTransform.translationY);
+            }
+            if (Constants.DebugFlags.App.EnableShadows &&
+                    toTransform.hasTranslationZChangedFrom(getTranslationZ())) {
                 setTranslationZ(toTransform.translationZ);
             }
-            setScaleX(toTransform.scale);
-            setScaleY(toTransform.scale);
-            setAlpha(toTransform.alpha);
+            if (toTransform.hasScaleChangedFrom(getScaleX())) {
+                setScaleX(toTransform.scale);
+                setScaleY(toTransform.scale);
+                updateDimOverlayFromScale();
+            }
+            if (toTransform.hasAlphaChangedFrom(getAlpha())) {
+                setAlpha(toTransform.alpha);
+            }
         }
-        updateDimOverlayFromScale();
-        invalidate();
     }
 
     /** Resets this view's properties */
@@ -298,6 +313,7 @@
                         .scaleY(transform.scale)
                         .translationY(transform.translationY)
                         .setStartDelay(0)
+                        .setUpdateListener(null)
                         .setInterpolator(mConfig.linearOutSlowInInterpolator)
                         .setDuration(475)
                         .withLayer()
@@ -330,6 +346,7 @@
                     .scaleY(transform.scale)
                     .translationY(transform.translationY)
                     .setStartDelay(delay)
+                    .setUpdateListener(null)
                     .setInterpolator(mConfig.quintOutInterpolator)
                     .setDuration(mConfig.taskViewEnterFromHomeDuration)
                     .withLayer()
@@ -343,6 +360,7 @@
         animate()
                 .translationY(ctx.offscreenTranslationY)
                 .setStartDelay(0)
+                .setUpdateListener(null)
                 .setInterpolator(mConfig.fastOutLinearInInterpolator)
                 .setDuration(mConfig.taskViewExitToHomeDuration)
                 .withLayer()
@@ -383,6 +401,7 @@
         animate().translationX(mConfig.taskViewRemoveAnimTranslationXPx)
             .alpha(0f)
             .setStartDelay(0)
+            .setUpdateListener(null)
             .setInterpolator(mConfig.fastOutSlowInInterpolator)
             .setDuration(mConfig.taskViewRemoveAnimDuration)
             .withLayer()
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 4a76872..6c420e1 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewTransform.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewTransform.java
@@ -45,6 +45,23 @@
         t = o.t;
     }
 
+    /** Convenience functions to compare against current property values */
+    public boolean hasAlphaChangedFrom(float v) {
+        return (Float.compare(alpha, v) != 0);
+    }
+    public boolean hasDismissAlphaChangedFrom(float v) {
+        return (Float.compare(dismissAlpha, v) != 0);
+    }
+    public boolean hasScaleChangedFrom(float v) {
+        return (Float.compare(scale, v) != 0);
+    }
+    public boolean hasTranslationYChangedFrom(float v) {
+        return (Float.compare(translationY, v) != 0);
+    }
+    public boolean hasTranslationZChangedFrom(float v) {
+        return (Float.compare(translationZ, v) != 0);
+    }
+
     @Override
     public String toString() {
         return "TaskViewTransform y: " + translationY + " z: " + translationZ + " scale: " + scale +