Make res.Configuration support locale lists.

We also deprecate the locale attribute, but works around the cases in
which people would call it.

Also add various methods to LocaleList to support the features
Configuration requires.

Change-Id: Iacc537e5fc1a3d4c1ea7e5517347876ca4e07e0a
diff --git a/core/java/android/util/LocaleList.java b/core/java/android/util/LocaleList.java
index 017735a..afae9ac 100644
--- a/core/java/android/util/LocaleList.java
+++ b/core/java/android/util/LocaleList.java
@@ -23,8 +23,8 @@
 
 // TODO: We don't except too many LocaleLists to exist at the same time, and
 // we need access to the data at native level, so we should pass the data
-// down to the native level, create a mapt of every list seen there, take a
-// pointer back, and just keep that pointed in the Java-level object, so
+// down to the native level, create a map of every list seen there, take a
+// pointer back, and just keep that pointer in the Java-level object, so
 // things could be copied very quickly.
 
 /**
@@ -34,6 +34,7 @@
 public final class LocaleList {
     private final Locale[] mList;
     private static final Locale[] sEmptyList = new Locale[0];
+    private static final LocaleList sEmptyLocaleList = new LocaleList();
 
     public Locale get(int location) {
         return location < mList.length ? mList[location] : null;
@@ -51,6 +52,60 @@
         return mList.length;
     }
 
+    @Override
+    public boolean equals(Object other) {
+        if (other == this)
+            return true;
+        if (!(other instanceof LocaleList))
+            return false;
+        final Locale[] otherList = ((LocaleList) other).mList;
+        if (mList.length != otherList.length)
+            return false;
+        for (int i = 0; i < mList.length; ++i) {
+            if (!mList[i].equals(otherList[i]))
+                return false;
+        }
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = 1;
+        for (int i = 0; i < mList.length; ++i) {
+            result = 31 * result + mList[i].hashCode();
+        }
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("[");
+        for (int i = 0; i < mList.length; ++i) {
+            sb.append(mList[i]);
+            if (i < mList.length - 1) {
+                sb.append(',');
+            }
+        }
+        sb.append("]");
+        return sb.toString();
+    }
+
+    public String toLanguageTags() {
+        StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < mList.length; ++i) {
+            sb.append(mList[i].toLanguageTag());
+            if (i < mList.length - 1) {
+                sb.append(',');
+            }
+        }
+        return sb.toString();
+    }
+
+    /**
+     * It is almost always better to call {@link #getEmptyLocaleList()} instead which returns
+     * a pre-constructed empty locale list.
+     */
     public LocaleList() {
         mList = sEmptyList;
     }
@@ -59,6 +114,19 @@
      * @throws NullPointerException if any of the input locales is <code>null</code>.
      * @throws IllegalArgumentException if any of the input locales repeat.
      */
+    public LocaleList(@Nullable Locale locale) {
+        if (locale == null) {
+            mList = sEmptyList;
+        } else {
+            mList = new Locale[1];
+            mList[0] = (Locale) locale.clone();
+        }
+    }
+
+    /**
+     * @throws NullPointerException if any of the input locales is <code>null</code>.
+     * @throws IllegalArgumentException if any of the input locales repeat.
+     */
     public LocaleList(@Nullable Locale[] list) {
         if (list == null || list.length == 0) {
             mList = sEmptyList;
@@ -79,4 +147,21 @@
             mList = localeList;
         }
     }
+
+    public static LocaleList getEmptyLocaleList() {
+        return sEmptyLocaleList;
+    }
+
+    public static LocaleList forLanguageTags(@Nullable String list) {
+        if (list == null || list.equals("")) {
+            return getEmptyLocaleList();
+        } else {
+            final String[] tags = list.split(",");
+            final Locale[] localeArray = new Locale[tags.length];
+            for (int i = 0; i < localeArray.length; ++i) {
+                localeArray[i] = Locale.forLanguageTag(tags[i]);
+            }
+            return new LocaleList(localeArray);
+        }
+    }
 }