Fix Button.Borderless.Colored disabled text color

We can now use the new themeable CSL support in
AppCompat to support disabled text colors.

BUG: 25788830

Change-Id: I0a5d2a50fb79d58da203fa5524914abb015139d9
diff --git a/v7/appcompat/res/color/abc_btn_colored_borderless_text_material.xml b/v7/appcompat/res/color/abc_btn_colored_borderless_text_material.xml
new file mode 100644
index 0000000..f4a93b7
--- /dev/null
+++ b/v7/appcompat/res/color/abc_btn_colored_borderless_text_material.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Used for the text of a borderless colored button. -->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_enabled="false"
+          android:alpha="?android:attr/disabledAlpha"
+          android:color="?android:attr/textColorSecondary" />
+    <item android:color="?attr/colorAccent"/>
+</selector>
\ No newline at end of file
diff --git a/v7/appcompat/res/values-v21/styles_base.xml b/v7/appcompat/res/values-v21/styles_base.xml
index b1d3006..d31f6f9 100644
--- a/v7/appcompat/res/values-v21/styles_base.xml
+++ b/v7/appcompat/res/values-v21/styles_base.xml
@@ -186,7 +186,9 @@
 
     <style name="Base.Widget.AppCompat.Button.Borderless" parent="android:Widget.Material.Button.Borderless" />
 
-    <style name="Base.Widget.AppCompat.Button.Borderless.Colored" parent="android:Widget.Material.Button.Borderless.Colored" />
+    <style name="Base.Widget.AppCompat.Button.Borderless.Colored" parent="android:Widget.Material.Button.Borderless.Colored">
+        <item name="android:textColor">@color/abc_btn_colored_borderless_text_material</item>
+    </style>
 
     <style name="Base.Widget.AppCompat.ButtonBar" parent="android:Widget.Material.ButtonBar" />
 
diff --git a/v7/appcompat/res/values-v23/styles_base.xml b/v7/appcompat/res/values-v23/styles_base.xml
index 56563c7..e6be6b9 100644
--- a/v7/appcompat/res/values-v23/styles_base.xml
+++ b/v7/appcompat/res/values-v23/styles_base.xml
@@ -17,6 +17,8 @@
 
 <resources>
 
+    <style name="Base.Widget.AppCompat.Button.Borderless.Colored" parent="android:Widget.Material.Button.Borderless.Colored" />
+
     <style name="Base.Widget.AppCompat.Button.Colored" parent="android:Widget.Material.Button.Colored" />
 
     <style name="Base.Widget.AppCompat.RatingBar.Indicator" parent="android:Widget.Material.RatingBar.Indicator" />
diff --git a/v7/appcompat/res/values/styles_base.xml b/v7/appcompat/res/values/styles_base.xml
index 85f8c22..8b808da 100644
--- a/v7/appcompat/res/values/styles_base.xml
+++ b/v7/appcompat/res/values/styles_base.xml
@@ -455,7 +455,7 @@
 
     <!-- Colored borderless ink button -->
     <style name="Base.Widget.AppCompat.Button.Borderless.Colored">
-        <item name="android:textColor">?attr/colorAccent</item>
+        <item name="android:textColor">@color/abc_btn_colored_borderless_text_material</item>
     </style>
 
     <style name="Base.Widget.AppCompat.Button.ButtonBar.AlertDialog" parent="Widget.AppCompat.Button.Borderless.Colored">
diff --git a/v7/appcompat/src/android/support/v7/widget/AppCompatTextHelper.java b/v7/appcompat/src/android/support/v7/widget/AppCompatTextHelper.java
index 16bb5cf..9d7f663 100644
--- a/v7/appcompat/src/android/support/v7/widget/AppCompatTextHelper.java
+++ b/v7/appcompat/src/android/support/v7/widget/AppCompatTextHelper.java
@@ -25,6 +25,7 @@
 import android.support.v7.text.AllCapsTransformationMethod;
 import android.text.method.PasswordTransformationMethod;
 import android.util.AttributeSet;
+import android.util.TypedValue;
 import android.widget.TextView;
 
 class AppCompatTextHelper {
@@ -36,10 +37,13 @@
         return new AppCompatTextHelper(textView);
     }
 
-    private static final int[] VIEW_ATTRS = {android.R.attr.textAppearance,
-            android.R.attr.drawableLeft, android.R.attr.drawableTop,
-            android.R.attr.drawableRight, android.R.attr.drawableBottom };
-    private static final int[] TEXT_APPEARANCE_ATTRS = {R.attr.textAllCaps};
+    private static final int[] VIEW_ATTRS = {
+            android.R.attr.textAppearance,
+            android.R.attr.drawableLeft,
+            android.R.attr.drawableTop,
+            android.R.attr.drawableRight,
+            android.R.attr.drawableBottom
+    };
 
     final TextView mView;
 
@@ -57,9 +61,9 @@
         final AppCompatDrawableManager drawableManager = AppCompatDrawableManager.get();
 
         // First read the TextAppearance style id
-        TypedArray a = context.obtainStyledAttributes(attrs, VIEW_ATTRS, defStyleAttr, 0);
+        TintTypedArray a = TintTypedArray.obtainStyledAttributes(context, attrs,
+                VIEW_ATTRS, defStyleAttr, 0);
         final int ap = a.getResourceId(0, -1);
-
         // Now read the compound drawable and grab any tints
         if (a.hasValue(1)) {
             mDrawableLeftTint = createTintInfo(context, drawableManager, a.getResourceId(1, 0));
@@ -75,45 +79,75 @@
         }
         a.recycle();
 
-        if (!(mView.getTransformationMethod() instanceof PasswordTransformationMethod)) {
-            // PasswordTransformationMethod wipes out all other TransformationMethod instances
-            // in TextView's constructor, so we should only set a new transformation method
-            // if we don't have a PasswordTransformationMethod currently...
+        // PasswordTransformationMethod wipes out all other TransformationMethod instances
+        // in TextView's constructor, so we should only set a new transformation method
+        // if we don't have a PasswordTransformationMethod currently...
+        final boolean hasPwdTm =
+                mView.getTransformationMethod() instanceof PasswordTransformationMethod;
+        boolean allCaps = false;
 
-            boolean allCaps = false;
-
-            // First check TextAppearance's textAllCaps value
-            if (ap != -1) {
-                TypedArray appearance = context
-                        .obtainStyledAttributes(ap, R.styleable.TextAppearance);
-                if (appearance.hasValue(R.styleable.TextAppearance_textAllCaps)) {
-                    allCaps = appearance.getBoolean(R.styleable.TextAppearance_textAllCaps, false);
-                }
-                appearance.recycle();
+        // First check TextAppearance's textAllCaps value
+        if (ap != -1) {
+            a = TintTypedArray.obtainStyledAttributes(context, ap, R.styleable.TextAppearance);
+            if (!hasPwdTm && a.hasValue(R.styleable.TextAppearance_textAllCaps)) {
+                allCaps = a.getBoolean(R.styleable.TextAppearance_textAllCaps, false);
             }
-
-            // Now read the style's value
-            a = context.obtainStyledAttributes(attrs, TEXT_APPEARANCE_ATTRS, defStyleAttr, 0);
-            if (a.hasValue(0)) {
-                allCaps = a.getBoolean(0, false);
+            if (Build.VERSION.SDK_INT < 23 && TypedValue.TYPE_STRING
+                    == a.getType(R.styleable.TextAppearance_android_textColor)) {
+                // If we're running on < API 23, have a color set and it's a String reference,
+                // it may contain theme references so let's re-set using our own inflater
+                final ColorStateList textColor
+                        = a.getColorStateList(R.styleable.TextAppearance_android_textColor);
+                if (textColor != null) {
+                    mView.setTextColor(textColor);
+                }
             }
             a.recycle();
+        }
 
-            if (allCaps) {
-                setAllCaps(true);
+        // Now read the style's values
+        a = TintTypedArray.obtainStyledAttributes(context, attrs, R.styleable.TextAppearance,
+                defStyleAttr, 0);
+        if (!hasPwdTm && a.hasValue(R.styleable.TextAppearance_textAllCaps)) {
+            allCaps = a.getBoolean(R.styleable.TextAppearance_textAllCaps, false);
+        }
+        if (Build.VERSION.SDK_INT < 23 && TypedValue.TYPE_STRING ==
+                a.getType(R.styleable.TextAppearance_android_textColor)) {
+            // If we're running on < API 23, have a color set and it's a String reference, it may
+            // contain theme references so let's re-set using our own inflater
+            final ColorStateList textColor =
+                    a.getColorStateList(R.styleable.TextAppearance_android_textColor);
+            if (textColor != null) {
+                mView.setTextColor(textColor);
             }
         }
+        a.recycle();
+
+        if (!hasPwdTm && allCaps) {
+            setAllCaps(true);
+        }
     }
 
     void onSetTextAppearance(Context context, int resId) {
-        TypedArray appearance = context.obtainStyledAttributes(resId, TEXT_APPEARANCE_ATTRS);
-        if (appearance.getBoolean(0, false)) {
+        final TintTypedArray a = TintTypedArray.obtainStyledAttributes(context,
+                resId, R.styleable.TextAppearance);
+        if (a.getBoolean(R.styleable.TextAppearance_textAllCaps, false)) {
             // This follows the logic in TextView.setTextAppearance that serves as an "overlay"
             // on the current state of the TextView. Here we only allow turning all-caps on when
             // the passed style has textAllCaps attribute set to true.
             setAllCaps(true);
         }
-        appearance.recycle();
+        if (Build.VERSION.SDK_INT < 23 && TypedValue.TYPE_STRING
+                == a.getType(R.styleable.TextAppearance_android_textColor)) {
+            // If we're running on < API 23, have a color set and it's a String reference,
+            // it may contain theme references so let's re-set using our own inflater
+            final ColorStateList textColor
+                    = a.getColorStateList(R.styleable.TextAppearance_android_textColor);
+            if (textColor != null) {
+                mView.setTextColor(textColor);
+            }
+        }
+        a.recycle();
     }
 
     void setAllCaps(boolean allCaps) {
diff --git a/v7/appcompat/src/android/support/v7/widget/TintTypedArray.java b/v7/appcompat/src/android/support/v7/widget/TintTypedArray.java
index 32749f3..78b3d94d 100644
--- a/v7/appcompat/src/android/support/v7/widget/TintTypedArray.java
+++ b/v7/appcompat/src/android/support/v7/widget/TintTypedArray.java
@@ -21,6 +21,7 @@
 import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.graphics.drawable.Drawable;
+import android.os.Build;
 import android.util.AttributeSet;
 import android.util.TypedValue;
 
@@ -36,16 +37,21 @@
     private final Context mContext;
     private final TypedArray mWrapped;
 
+    private TypedValue mTypedValue;
+
     public static TintTypedArray obtainStyledAttributes(Context context, AttributeSet set,
             int[] attrs) {
-        TypedArray array = context.obtainStyledAttributes(set, attrs);
-        return new TintTypedArray(context, array);
+        return new TintTypedArray(context, context.obtainStyledAttributes(set, attrs));
     }
 
     public static TintTypedArray obtainStyledAttributes(Context context, AttributeSet set,
             int[] attrs, int defStyleAttr, int defStyleRes) {
-        TypedArray array = context.obtainStyledAttributes(set, attrs, defStyleAttr, defStyleRes);
-        return new TintTypedArray(context, array);
+        return new TintTypedArray(context,
+                context.obtainStyledAttributes(set, attrs, defStyleAttr, defStyleRes));
+    }
+
+    public static TintTypedArray obtainStyledAttributes(Context context, int resid, int[] attrs) {
+        return new TintTypedArray(context, context.obtainStyledAttributes(resid, attrs));
     }
 
     private TintTypedArray(Context context, TypedArray array) {
@@ -172,7 +178,15 @@
     }
 
     public int getType(int index) {
-        return mWrapped.getType(index);
+        if (Build.VERSION.SDK_INT >= 21) {
+            return mWrapped.getType(index);
+        } else {
+            if (mTypedValue == null) {
+                mTypedValue = new TypedValue();
+            }
+            mWrapped.getValue(index, mTypedValue);
+            return mTypedValue.type;
+        }
     }
 
     public boolean hasValue(int index) {