am 7b12fd9b: am 0bf08254: Merge "Fix Button touch feedback on Gingerbread" into lmp-mr1-ub-dev

* commit '7b12fd9b8e92d94a8b1625c0be2c92c3e1843891':
  Fix Button touch feedback on Gingerbread
diff --git a/v4/java/android/support/v4/graphics/ColorUtils.java b/v4/java/android/support/v4/graphics/ColorUtils.java
index 91c61af..f2d56da 100644
--- a/v4/java/android/support/v4/graphics/ColorUtils.java
+++ b/v4/java/android/support/v4/graphics/ColorUtils.java
@@ -32,18 +32,27 @@
      * Composite two potentially translucent colors over each other and returns the result.
      */
     public static int compositeColors(int foreground, int background) {
-        final float alpha1 = Color.alpha(foreground) / 255f;
-        final float alpha2 = Color.alpha(background) / 255f;
+        int bgAlpha = Color.alpha(background);
+        int fgAlpha = Color.alpha(foreground);
+        int a = compositeAlpha(fgAlpha, bgAlpha);
 
-        float a = (alpha1 + alpha2) * (1f - alpha1);
-        float r = (Color.red(foreground) * alpha1)
-                + (Color.red(background) * alpha2 * (1f - alpha1));
-        float g = (Color.green(foreground) * alpha1)
-                + (Color.green(background) * alpha2 * (1f - alpha1));
-        float b = (Color.blue(foreground) * alpha1)
-                + (Color.blue(background) * alpha2 * (1f - alpha1));
+        int r = compositeComponent(Color.red(foreground), fgAlpha,
+                Color.red(background), bgAlpha, a);
+        int g = compositeComponent(Color.green(foreground), fgAlpha,
+                Color.green(background), bgAlpha, a);
+        int b = compositeComponent(Color.blue(foreground), fgAlpha,
+                Color.blue(background), bgAlpha, a);
 
-        return Color.argb((int) a, (int) r, (int) g, (int) b);
+        return Color.argb(a, r, g, b);
+    }
+
+    private static int compositeAlpha(int foregroundAlpha, int backgroundAlpha) {
+        return 0xFF - (((0xFF - backgroundAlpha) * (0xFF - foregroundAlpha)) / 0xFF);
+    }
+
+    private static int compositeComponent(int fgC, int fgA, int bgC, int bgA, int a) {
+        if (a == 0) return 0;
+        return ((0xFF * fgC * fgA) + (bgC * bgA * (0xFF - fgA))) / (a * 0xFF);
     }
 
     /**
diff --git a/v7/appcompat/src/android/support/v7/internal/widget/TintManager.java b/v7/appcompat/src/android/support/v7/internal/widget/TintManager.java
index e041005..777f5a0 100644
--- a/v7/appcompat/src/android/support/v7/internal/widget/TintManager.java
+++ b/v7/appcompat/src/android/support/v7/internal/widget/TintManager.java
@@ -24,6 +24,7 @@
 import android.graphics.drawable.LayerDrawable;
 import android.os.Build;
 import android.support.v4.content.ContextCompat;
+import android.support.v4.graphics.ColorUtils;
 import android.support.v4.graphics.drawable.DrawableCompat;
 import android.support.v4.util.LruCache;
 import android.support.v7.appcompat.R;
@@ -440,22 +441,25 @@
         final int[] colors = new int[4];
         int i = 0;
 
+        final int colorButtonNormal = getThemeAttrColor(context, R.attr.colorButtonNormal);
+        final int colorControlHighlight = getThemeAttrColor(context, R.attr.colorControlHighlight);
+
         // Disabled state
         states[i] = ThemeUtils.DISABLED_STATE_SET;
         colors[i] = getDisabledThemeAttrColor(context, R.attr.colorButtonNormal);
         i++;
 
         states[i] = ThemeUtils.PRESSED_STATE_SET;
-        colors[i] = getThemeAttrColor(context, R.attr.colorControlHighlight);
+        colors[i] = ColorUtils.compositeColors(colorControlHighlight, colorButtonNormal);
         i++;
 
         states[i] = ThemeUtils.FOCUSED_STATE_SET;
-        colors[i] = getThemeAttrColor(context, R.attr.colorControlHighlight);
+        colors[i] = ColorUtils.compositeColors(colorControlHighlight, colorButtonNormal);
         i++;
 
         // Default enabled state
         states[i] = ThemeUtils.EMPTY_STATE_SET;
-        colors[i] = getThemeAttrColor(context, R.attr.colorButtonNormal);
+        colors[i] = colorButtonNormal;
         i++;
 
         return new ColorStateList(states, colors);
@@ -515,6 +519,12 @@
         } else {
             background.clearColorFilter();
         }
+
+        if (Build.VERSION.SDK_INT <= 10) {
+            // On Gingerbread, GradientDrawable does not invalidate itself when it's ColorFilter
+            // has changed, so we need to force an invalidation
+            view.invalidate();
+        }
     }
 
     private static void setPorterDuffColorFilter(Drawable d, int color, PorterDuff.Mode mode) {