Make sure that FAB's border respects tint updates

BUG: 24699109
Change-Id: I15469769242abfe9edf8b87b2f88f46dac7aa3de
diff --git a/design/base/android/support/design/widget/CircularBorderDrawable.java b/design/base/android/support/design/widget/CircularBorderDrawable.java
index 7e2ebc7..617a501 100644
--- a/design/base/android/support/design/widget/CircularBorderDrawable.java
+++ b/design/base/android/support/design/widget/CircularBorderDrawable.java
@@ -16,6 +16,7 @@
 
 package android.support.design.widget;
 
+import android.content.res.ColorStateList;
 import android.graphics.Canvas;
 import android.graphics.ColorFilter;
 import android.graphics.LinearGradient;
@@ -50,7 +51,8 @@
     private int mBottomOuterStrokeColor;
     private int mBottomInnerStrokeColor;
 
-    private int mTintColor;
+    private ColorStateList mBorderTint;
+    private int mCurrentBorderTintColor;
 
     private boolean mInvalidateShader = true;
 
@@ -120,8 +122,11 @@
         invalidateSelf();
     }
 
-    void setTintColor(int tintColor) {
-        mTintColor = tintColor;
+    void setBorderTint(ColorStateList tint) {
+        if (tint != null) {
+            mCurrentBorderTintColor = tint.getColorForState(getState(), mCurrentBorderTintColor);
+        }
+        mBorderTint = tint;
         mInvalidateShader = true;
         invalidateSelf();
     }
@@ -149,6 +154,26 @@
         mInvalidateShader = true;
     }
 
+    @Override
+    public boolean isStateful() {
+        return (mBorderTint != null && mBorderTint.isStateful()) || super.isStateful();
+    }
+
+    @Override
+    protected boolean onStateChange(int[] state) {
+        if (mBorderTint != null) {
+            final int newColor = mBorderTint.getColorForState(state, mCurrentBorderTintColor);
+            if (newColor != mCurrentBorderTintColor) {
+                mInvalidateShader = true;
+                mCurrentBorderTintColor = newColor;
+            }
+        }
+        if (mInvalidateShader) {
+            invalidateSelf();
+        }
+        return mInvalidateShader;
+    }
+
     /**
      * Creates a vertical {@link LinearGradient}
      * @return
@@ -160,14 +185,14 @@
         final float borderRatio = mBorderWidth / rect.height();
 
         final int[] colors = new int[6];
-        colors[0] = ColorUtils.compositeColors(mTopOuterStrokeColor, mTintColor);
-        colors[1] = ColorUtils.compositeColors(mTopInnerStrokeColor, mTintColor);
+        colors[0] = ColorUtils.compositeColors(mTopOuterStrokeColor, mCurrentBorderTintColor);
+        colors[1] = ColorUtils.compositeColors(mTopInnerStrokeColor, mCurrentBorderTintColor);
         colors[2] = ColorUtils.compositeColors(
-                ColorUtils.setAlphaComponent(mTopInnerStrokeColor, 0), mTintColor);
+                ColorUtils.setAlphaComponent(mTopInnerStrokeColor, 0), mCurrentBorderTintColor);
         colors[3] = ColorUtils.compositeColors(
-                ColorUtils.setAlphaComponent(mBottomInnerStrokeColor, 0), mTintColor);
-        colors[4] = ColorUtils.compositeColors(mBottomInnerStrokeColor, mTintColor);
-        colors[5] = ColorUtils.compositeColors(mBottomOuterStrokeColor, mTintColor);
+                ColorUtils.setAlphaComponent(mBottomInnerStrokeColor, 0), mCurrentBorderTintColor);
+        colors[4] = ColorUtils.compositeColors(mBottomInnerStrokeColor, mCurrentBorderTintColor);
+        colors[5] = ColorUtils.compositeColors(mBottomOuterStrokeColor, mCurrentBorderTintColor);
 
         final float[] positions = new float[6];
         positions[0] = 0f;
diff --git a/design/base/android/support/design/widget/FloatingActionButtonImpl.java b/design/base/android/support/design/widget/FloatingActionButtonImpl.java
index 097aedf..b61bf15 100644
--- a/design/base/android/support/design/widget/FloatingActionButtonImpl.java
+++ b/design/base/android/support/design/widget/FloatingActionButtonImpl.java
@@ -98,7 +98,7 @@
                 resources.getColor(R.color.design_fab_stroke_end_inner_color),
                 resources.getColor(R.color.design_fab_stroke_end_outer_color));
         borderDrawable.setBorderWidth(borderWidth);
-        borderDrawable.setTintColor(backgroundTint.getDefaultColor());
+        borderDrawable.setBorderTint(backgroundTint);
         return borderDrawable;
     }
 
diff --git a/design/eclair-mr1/android/support/design/widget/FloatingActionButtonEclairMr1.java b/design/eclair-mr1/android/support/design/widget/FloatingActionButtonEclairMr1.java
index 8ad581d..42e2e9d 100644
--- a/design/eclair-mr1/android/support/design/widget/FloatingActionButtonEclairMr1.java
+++ b/design/eclair-mr1/android/support/design/widget/FloatingActionButtonEclairMr1.java
@@ -83,7 +83,6 @@
         GradientDrawable touchFeedbackShape = new GradientDrawable();
         touchFeedbackShape.setShape(GradientDrawable.OVAL);
         touchFeedbackShape.setColor(Color.WHITE);
-        touchFeedbackShape.setCornerRadius(mShadowViewDelegate.getRadius());
 
         // We'll now wrap that touch feedback mask drawable with a ColorStateList. We do not need
         // to inset for any border here as LayerDrawable will nest the padding for us
@@ -126,7 +125,7 @@
     void setBackgroundTintList(ColorStateList tint) {
         DrawableCompat.setTintList(mShapeDrawable, tint);
         if (mBorderDrawable != null) {
-            DrawableCompat.setTintList(mBorderDrawable, tint);
+            mBorderDrawable.setBorderTint(tint);
         }
     }
 
diff --git a/design/lollipop/android/support/design/widget/CircularBorderDrawableLollipop.java b/design/lollipop/android/support/design/widget/CircularBorderDrawableLollipop.java
index 554ecb8..8b90361 100644
--- a/design/lollipop/android/support/design/widget/CircularBorderDrawableLollipop.java
+++ b/design/lollipop/android/support/design/widget/CircularBorderDrawableLollipop.java
@@ -16,70 +16,17 @@
 
 package android.support.design.widget;
 
-
-import android.content.res.ColorStateList;
-import android.graphics.Canvas;
-import android.graphics.Color;
 import android.graphics.Outline;
-import android.graphics.PorterDuff;
-import android.graphics.PorterDuffColorFilter;
 
 /**
- * Lollipop version of {@link CircularBorderDrawable} which accepts tint calls.
+ * Lollipop version of {@link CircularBorderDrawable}.
  */
 class CircularBorderDrawableLollipop extends CircularBorderDrawable {
 
-    private ColorStateList mTint;
-    private PorterDuff.Mode mTintMode = PorterDuff.Mode.SRC_IN;
-    private PorterDuffColorFilter mTintFilter;
-
-    @Override
-    public void draw(Canvas canvas) {
-        boolean clearColorFilter;
-        if (mTintFilter != null && mPaint.getColorFilter() == null) {
-            mPaint.setColorFilter(mTintFilter);
-            clearColorFilter = true;
-        } else {
-            clearColorFilter = false;
-        }
-
-        super.draw(canvas);
-
-        if (clearColorFilter) {
-            mPaint.setColorFilter(null);
-        }
-    }
-
-    @Override
-    public void setTintList(ColorStateList tint) {
-        mTint = tint;
-        mTintFilter = updateTintFilter(tint, mTintMode);
-        invalidateSelf();
-    }
-
-    @Override
-    public void setTintMode(PorterDuff.Mode tintMode) {
-        mTintMode = tintMode;
-        mTintFilter = updateTintFilter(mTint, tintMode);
-        invalidateSelf();
-    }
-
     @Override
     public void getOutline(Outline outline) {
         copyBounds(mRect);
         outline.setOval(mRect);
     }
 
-    /**
-     * Ensures the tint filter is consistent with the current tint color and
-     * mode.
-     */
-    private PorterDuffColorFilter updateTintFilter(ColorStateList tint, PorterDuff.Mode tintMode) {
-        if (tint == null || tintMode == null) {
-            return null;
-        }
-
-        final int color = tint.getColorForState(getState(), Color.TRANSPARENT);
-        return new PorterDuffColorFilter(color, tintMode);
-    }
 }
diff --git a/design/lollipop/android/support/design/widget/FloatingActionButtonLollipop.java b/design/lollipop/android/support/design/widget/FloatingActionButtonLollipop.java
index 25e9dd9..7dc2df0 100644
--- a/design/lollipop/android/support/design/widget/FloatingActionButtonLollipop.java
+++ b/design/lollipop/android/support/design/widget/FloatingActionButtonLollipop.java
@@ -35,10 +35,6 @@
 @TargetApi(Build.VERSION_CODES.LOLLIPOP)
 class FloatingActionButtonLollipop extends FloatingActionButtonHoneycombMr1 {
 
-    private Drawable mShapeDrawable;
-    private RippleDrawable mRippleDrawable;
-    private Drawable mBorderDrawable;
-
     private Interpolator mInterpolator;
 
     FloatingActionButtonLollipop(View view, ShadowViewDelegate shadowViewDelegate) {
@@ -77,21 +73,12 @@
     }
 
     @Override
-    void setBackgroundTintList(ColorStateList tint) {
-        DrawableCompat.setTintList(mShapeDrawable, tint);
-        if (mBorderDrawable != null) {
-            DrawableCompat.setTintList(mBorderDrawable, tint);
-        }
-    }
-
-    @Override
-    void setBackgroundTintMode(PorterDuff.Mode tintMode) {
-        DrawableCompat.setTintMode(mShapeDrawable, tintMode);
-    }
-
-    @Override
     void setRippleColor(int rippleColor) {
-        mRippleDrawable.setColor(ColorStateList.valueOf(rippleColor));
+        if (mRippleDrawable instanceof RippleDrawable) {
+            ((RippleDrawable) mRippleDrawable).setColor(ColorStateList.valueOf(rippleColor));
+        } else {
+            super.setRippleColor(rippleColor);
+        }
     }
 
     @Override