Enabled customization of the arrow color in OnboardingFragment

Previosuly, we could customize the foreground color of the arrow but not
the arrow itself which was a PNG drawable. This CL uses ColorFilter that
is installed on the paint which draws the arrow. This enables setting
the bitmap color.
Also defined theme attribute for setting color. Programmatically setting
this color will supersede the theme attribute.

Bug: 37881573
Test: tested with a subclass of OnboardingFragment both setting the
color through the theme attribute as well as dynamically in onCreate().

Change-Id: I18a8d98f7fffe1c029a9116bbcd031ad67c6b10d
(cherry picked from commit 0cb1f577feba17baceb159ab7592e1050425bbad)
diff --git a/api/26.0.0-SNAPSHOT.txt b/api/26.0.0-SNAPSHOT.txt
index e920fc1..0389d87 100644
--- a/api/26.0.0-SNAPSHOT.txt
+++ b/api/26.0.0-SNAPSHOT.txt
@@ -3046,6 +3046,7 @@
   public abstract class OnboardingFragment extends android.app.Fragment {
     ctor public OnboardingFragment();
     method public final int getArrowBackgroundColor();
+    method public final int getArrowColor();
     method protected final int getCurrentPageIndex();
     method public final int getDescriptionViewTextColor();
     method public final int getDotBackgroundColor();
@@ -3071,6 +3072,7 @@
     method protected void onPageChanged(int, int);
     method public int onProvideTheme();
     method public void setArrowBackgroundColor(int);
+    method public void setArrowColor(int);
     method public void setDescriptionViewTextColor(int);
     method public void setDotBackgroundColor(int);
     method public final void setIconResouceId(int);
@@ -3083,6 +3085,7 @@
   public abstract class OnboardingSupportFragment extends android.support.v4.app.Fragment {
     ctor public OnboardingSupportFragment();
     method public final int getArrowBackgroundColor();
+    method public final int getArrowColor();
     method protected final int getCurrentPageIndex();
     method public final int getDescriptionViewTextColor();
     method public final int getDotBackgroundColor();
@@ -3108,6 +3111,7 @@
     method protected void onPageChanged(int, int);
     method public int onProvideTheme();
     method public void setArrowBackgroundColor(int);
+    method public void setArrowColor(int);
     method public void setDescriptionViewTextColor(int);
     method public void setDotBackgroundColor(int);
     method public final void setIconResouceId(int);
diff --git a/v17/leanback/res/values/attrs.xml b/v17/leanback/res/values/attrs.xml
index 563e2ae..b56011c 100644
--- a/v17/leanback/res/values/attrs.xml
+++ b/v17/leanback/res/values/attrs.xml
@@ -584,6 +584,8 @@
         <attr name="dotToArrowGap" format="reference" />
         <!-- Attribute for background color of the dots in PagingIndicator. -->
         <attr name="dotBgColor" format="reference" />
+        <!-- Attribute for the arrow color in PagingIndicator. -->
+        <attr name="arrowColor" format="reference" />
         <!-- Attribute for background color of the arrow in PagingIndicator. -->
         <attr name="arrowBgColor" format="reference" />
     </declare-styleable>
diff --git a/v17/leanback/src/android/support/v17/leanback/app/OnboardingFragment.java b/v17/leanback/src/android/support/v17/leanback/app/OnboardingFragment.java
index 7879206..ab61c4a 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/OnboardingFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/OnboardingFragment.java
@@ -209,6 +209,10 @@
     private boolean mDotBackgroundColorSet;
 
     @ColorInt
+    private int mArrowColor = Color.TRANSPARENT;
+    private boolean mArrowColorSet;
+
+    @ColorInt
     private int mArrowBackgroundColor = Color.TRANSPARENT;
     private boolean mArrowBackgroundColorSet;
 
@@ -327,6 +331,9 @@
         if (mDotBackgroundColorSet) {
             mPageIndicator.setDotBackgroundColor(mDotBackgroundColor);
         }
+        if (mArrowColorSet) {
+            mPageIndicator.setArrowColor(mArrowColor);
+        }
         if (mArrowBackgroundColorSet) {
             mPageIndicator.setDotBackgroundColor(mArrowBackgroundColor);
         }
@@ -452,6 +459,30 @@
     }
 
     /**
+     * Sets the color of the arrow. This color will supersede the color set in the theme attribute
+     * {@link R.styleable#PagingIndicator_arrowColor} if provided. If none of these two are set, the
+     * arrow will have its original bitmap color.
+     *
+     * @param color the color to use for arrow background
+     */
+    public void setArrowColor(@ColorInt int color) {
+        mArrowColor = color;
+        mArrowColorSet = true;
+        if (mPageIndicator != null) {
+            mPageIndicator.setArrowColor(color);
+        }
+    }
+
+    /**
+     * Returns the color of the arrow if it's set through
+     * {@link #setArrowColor(int)}. If no color was set, transparent is returned.
+     */
+    @ColorInt
+    public final int getArrowColor() {
+        return mArrowColor;
+    }
+
+    /**
      * Sets the background color of the arrow. If not set, the default color from attr
      * {@link R.styleable#PagingIndicator_arrowBgColor} in the theme will be used.
      * @param color the color to use for arrow background
diff --git a/v17/leanback/src/android/support/v17/leanback/app/OnboardingSupportFragment.java b/v17/leanback/src/android/support/v17/leanback/app/OnboardingSupportFragment.java
index 1ceac51..0c7cc4c 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/OnboardingSupportFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/OnboardingSupportFragment.java
@@ -212,6 +212,10 @@
     private boolean mDotBackgroundColorSet;
 
     @ColorInt
+    private int mArrowColor = Color.TRANSPARENT;
+    private boolean mArrowColorSet;
+
+    @ColorInt
     private int mArrowBackgroundColor = Color.TRANSPARENT;
     private boolean mArrowBackgroundColorSet;
 
@@ -330,6 +334,9 @@
         if (mDotBackgroundColorSet) {
             mPageIndicator.setDotBackgroundColor(mDotBackgroundColor);
         }
+        if (mArrowColorSet) {
+            mPageIndicator.setArrowColor(mArrowColor);
+        }
         if (mArrowBackgroundColorSet) {
             mPageIndicator.setDotBackgroundColor(mArrowBackgroundColor);
         }
@@ -455,6 +462,30 @@
     }
 
     /**
+     * Sets the color of the arrow. This color will supersede the color set in the theme attribute
+     * {@link R.styleable#PagingIndicator_arrowColor} if provided. If none of these two are set, the
+     * arrow will have its original bitmap color.
+     *
+     * @param color the color to use for arrow background
+     */
+    public void setArrowColor(@ColorInt int color) {
+        mArrowColor = color;
+        mArrowColorSet = true;
+        if (mPageIndicator != null) {
+            mPageIndicator.setArrowColor(color);
+        }
+    }
+
+    /**
+     * Returns the color of the arrow if it's set through
+     * {@link #setArrowColor(int)}. If no color was set, transparent is returned.
+     */
+    @ColorInt
+    public final int getArrowColor() {
+        return mArrowColor;
+    }
+
+    /**
      * Sets the background color of the arrow. If not set, the default color from attr
      * {@link R.styleable#PagingIndicator_arrowBgColor} in the theme will be used.
      * @param color the color to use for arrow background
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/PagingIndicator.java b/v17/leanback/src/android/support/v17/leanback/widget/PagingIndicator.java
index c7c801f..a16afd3 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/PagingIndicator.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/PagingIndicator.java
@@ -31,6 +31,8 @@
 import android.graphics.Color;
 import android.graphics.Matrix;
 import android.graphics.Paint;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffColorFilter;
 import android.graphics.Rect;
 import android.support.annotation.ColorInt;
 import android.support.annotation.RestrictTo;
@@ -123,6 +125,7 @@
     private final AnimatorSet mHideAnimator;
     private final AnimatorSet mAnimator = new AnimatorSet();
     Bitmap mArrow;
+    Paint mArrowPaint;
     final Rect mArrowRect;
     final float mArrowToBgRatio;
 
@@ -149,14 +152,19 @@
                 R.dimen.lb_page_indicator_dot_gap);
         mArrowGap = getDimensionFromTypedArray(typedArray,
                 R.styleable.PagingIndicator_dotToArrowGap, R.dimen.lb_page_indicator_arrow_gap);
-        int bgColor = getColorFromTypedArray(typedArray, R.styleable.PagingIndicator_dotBgColor,
+
+        int dotBgColor = getColorFromTypedArray(typedArray, R.styleable.PagingIndicator_dotBgColor,
                 R.color.lb_page_indicator_dot);
         mBgPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
-        mBgPaint.setColor(bgColor);
+        mBgPaint.setColor(dotBgColor);
         mDotFgSelectColor = getColorFromTypedArray(typedArray,
                 R.styleable.PagingIndicator_arrowBgColor,
                 R.color.lb_page_indicator_arrow_background);
+        if (mArrowPaint == null && typedArray.hasValue(R.styleable.PagingIndicator_arrowColor)) {
+            setArrowColor(typedArray.getColor(R.styleable.PagingIndicator_arrowColor, 0));
+        }
         typedArray.recycle();
+
         mIsLtr = res.getConfiguration().getLayoutDirection() == View.LAYOUT_DIRECTION_LTR;
         int shadowColor = res.getColor(R.color.lb_page_indicator_arrow_shadow);
         mShadowRadius = res.getDimensionPixelSize(R.dimen.lb_page_indicator_arrow_shadow_radius);
@@ -202,6 +210,20 @@
     }
 
     /**
+     * Sets the color of the arrow. This color will take over the value set through the
+     * theme attribute {@link R.styleable#PagingIndicator_arrowColor} if provided.
+     *
+     * @param color the color of the arrow
+     */
+    public void setArrowColor(@ColorInt int color) {
+        if (mArrowPaint == null) {
+            mArrowPaint = new Paint();
+        }
+        mArrowPaint.setColorFilter(new PorterDuffColorFilter(color,
+                PorterDuff.Mode.SRC_IN));
+    }
+
+    /**
      * Set the background color of the dot. This color will take over the value set through the
      * theme attribute.
      *
@@ -519,7 +541,7 @@
                 canvas.drawBitmap(mArrow, mArrowRect, new Rect((int) (centerX - mArrowImageRadius),
                         (int) (mDotCenterY - mArrowImageRadius),
                         (int) (centerX + mArrowImageRadius),
-                        (int) (mDotCenterY + mArrowImageRadius)), null);
+                        (int) (mDotCenterY + mArrowImageRadius)), mArrowPaint);
             }
         }