Correctly parse colours defined as "#..." or "#...."

The Android framework only understands colours defined as a hex string
of 6 or 8 characters, but not as hex strings of 3 or 4 characters. The
latter are however allowed to be used in Android apps, as AAPT does the
conversion at compile time. This makes sure we can handle all accepted
formats of colours.

Bug: 147374450
Test: RenderTests.testTypedValue updated
Change-Id: Ic5be0d7a92f6ae95ccfdea61789878a27db5b006
(cherry picked from commit a384318502d3773f1098aef6b6e14adc2c3e9f52)
diff --git a/bridge/src/android/content/res/Resources_Delegate.java b/bridge/src/android/content/res/Resources_Delegate.java
index cd57d5c..a5216bc 100644
--- a/bridge/src/android/content/res/Resources_Delegate.java
+++ b/bridge/src/android/content/res/Resources_Delegate.java
@@ -51,7 +51,6 @@
 import android.annotation.Nullable;
 import android.content.res.Resources.NotFoundException;
 import android.content.res.Resources.Theme;
-import android.graphics.Color;
 import android.graphics.Typeface;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.DrawableInflater_Delegate;
@@ -368,7 +367,7 @@
                     try {
                         if (element.startsWith("#")) {
                             // This integer represents a color (starts with #).
-                            values[i] = Color.parseColor(element);
+                            values[i] = ResourceHelper.getColor(element);
                         } else {
                             values[i] = getInt(element);
                         }
diff --git a/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
index d1d37fd..67f7c44 100644
--- a/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
+++ b/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
@@ -32,6 +32,7 @@
 import com.android.layoutlib.bridge.BridgeConstants;
 import com.android.layoutlib.bridge.android.view.WindowManagerImpl;
 import com.android.layoutlib.bridge.impl.ParserFactory;
+import com.android.layoutlib.bridge.impl.ResourceHelper;
 import com.android.layoutlib.bridge.impl.Stack;
 import com.android.resources.ResourceType;
 import com.android.util.Pair;
@@ -66,7 +67,6 @@
 import android.database.sqlite.SQLiteDatabase;
 import android.database.sqlite.SQLiteDatabase.CursorFactory;
 import android.graphics.Bitmap;
-import android.graphics.Color;
 import android.graphics.drawable.Drawable;
 import android.hardware.display.DisplayManager;
 import android.net.Uri;
@@ -416,8 +416,20 @@
         String stringValue = value.getValue();
         if (!stringValue.isEmpty()) {
             if (stringValue.charAt(0) == '#') {
-                outValue.type = TypedValue.TYPE_INT_COLOR_ARGB8;
-                outValue.data = Color.parseColor(value.getValue());
+                outValue.data = ResourceHelper.getColor(stringValue);
+                switch (stringValue.length()) {
+                    case 4:
+                        outValue.type = TypedValue.TYPE_INT_COLOR_RGB4;
+                        break;
+                    case 5:
+                        outValue.type = TypedValue.TYPE_INT_COLOR_ARGB4;
+                        break;
+                    case 7:
+                        outValue.type = TypedValue.TYPE_INT_COLOR_RGB8;
+                        break;
+                    default:
+                        outValue.type = TypedValue.TYPE_INT_COLOR_ARGB8;
+                }
             }
             else if (stringValue.charAt(0) == '@') {
                 outValue.type = TypedValue.TYPE_REFERENCE;
diff --git a/bridge/tests/res/testApp/MyApplication/src/main/res/values/styles.xml b/bridge/tests/res/testApp/MyApplication/src/main/res/values/styles.xml
index f598fda..9e84a53 100644
--- a/bridge/tests/res/testApp/MyApplication/src/main/res/values/styles.xml
+++ b/bridge/tests/res/testApp/MyApplication/src/main/res/values/styles.xml
@@ -3,6 +3,8 @@
     <!-- Base application theme. -->
     <style name="AppTheme" parent="android:Theme.Material.Light.DarkActionBar">
         <item name="myattr">@integer/ten</item>
+        <item name="android:colorError">#f00</item>
+        <item name="android:colorActivatedHighlight">#c0f0</item>
     </style>
 
     <style name="ThemableWidgetStyle">
diff --git a/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTests.java b/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTests.java
index 5118426..303c247 100644
--- a/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTests.java
+++ b/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTests.java
@@ -43,6 +43,7 @@
 import org.kxml2.io.KXmlParser;
 import org.xmlpull.v1.XmlPullParser;
 
+import android.R.attr;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.res.AssetManager;
@@ -965,6 +966,16 @@
         assertNotEquals(0, outValue.data);
 
         outValue = new TypedValue();
+        mContext.resolveThemeAttribute(android.R.attr.colorError, outValue, true);
+        assertEquals(TypedValue.TYPE_INT_COLOR_RGB4, outValue.type);
+        assertEquals(-65536, outValue.data);
+
+        outValue = new TypedValue();
+        mContext.resolveThemeAttribute(attr.colorActivatedHighlight, outValue, true);
+        assertEquals(TypedValue.TYPE_INT_COLOR_ARGB4, outValue.type);
+        assertEquals(-872349952, outValue.data);
+
+        outValue = new TypedValue();
         mContext.resolveThemeAttribute(android.R.attr.isLightTheme, outValue, true);
         assertEquals(TypedValue.TYPE_INT_BOOLEAN, outValue.type);
         assertEquals(1, outValue.data);