Update CTS tests for res.Configuration adding locale lists.

This especially focuses on cases where the deprecated 'locale'
attribute is used together with setLocales().

Also:
* Add CTS tests for new LocaleList methods introduced for
  res.Configuration needs.
* Remove the perhaps overreaching requirement that the system's
  default locale should be be LTR.
* Correct the country code for the Persian locale.
* Add a locale for Urdu to layout direction tests.

Change-Id: Ib0df546e9874f877cc986e888cbf745ddf0bdc08
diff --git a/tests/tests/content/src/android/content/res/cts/ConfigurationTest.java b/tests/tests/content/src/android/content/res/cts/ConfigurationTest.java
index 30c78a8..d4b6c63 100644
--- a/tests/tests/content/src/android/content/res/cts/ConfigurationTest.java
+++ b/tests/tests/content/src/android/content/res/cts/ConfigurationTest.java
@@ -22,6 +22,7 @@
 import android.content.res.Configuration;
 import android.os.Parcel;
 import android.test.AndroidTestCase;
+import android.util.LocaleList;
 import android.view.View;
 
 public class ConfigurationTest extends AndroidTestCase {
@@ -40,7 +41,7 @@
         mConfig = new Configuration();
         mConfig.fontScale = 2;
         mConfig.mcc = mConfig.mnc = 1;
-        mConfig.locale = Locale.getDefault();
+        mConfig.setLocale(Locale.getDefault());
         mConfig.touchscreen = Configuration.TOUCHSCREEN_NOTOUCH;
         mConfig.keyboard = Configuration.KEYBOARD_NOKEYS;
         mConfig.keyboardHidden = Configuration.KEYBOARDHIDDEN_NO;
@@ -93,6 +94,27 @@
         cfg2.touchscreen = 2;
         assertEquals(1, cfg1.compareTo(cfg2));
 
+        cfg1.setLocales(LocaleList.forLanguageTags("fr"));
+        cfg2.setLocales(LocaleList.forLanguageTags("fr,en"));
+        assertTrue(cfg1.compareTo(cfg2) < 0);
+        cfg1.setLocales(LocaleList.forLanguageTags("fr,en"));
+        cfg2.setLocales(LocaleList.forLanguageTags("fr"));
+        assertTrue(cfg1.compareTo(cfg2) > 0);
+
+        cfg1.setLocales(LocaleList.forLanguageTags("fr,en"));
+        cfg2.setLocales(LocaleList.forLanguageTags("fr,en-US"));
+        assertTrue(cfg1.compareTo(cfg2) < 0);
+        cfg1.setLocales(LocaleList.forLanguageTags("fr,en-US"));
+        cfg2.setLocales(LocaleList.forLanguageTags("fr,en"));
+        assertTrue(cfg1.compareTo(cfg2) > 0);
+
+        cfg1.locale = Locale.forLanguageTag("en");
+        cfg2.locale = Locale.forLanguageTag("en-Shaw");
+        assertTrue(cfg1.compareTo(cfg2) < 0);
+        cfg1.locale = Locale.forLanguageTag("en-Shaw");
+        cfg2.locale = Locale.forLanguageTag("en");
+        assertTrue(cfg1.compareTo(cfg2) > 0);
+
         cfg1.locale = new Locale("", "", "2");
         cfg2.locale = new Locale("", "", "3");
         assertEquals(-1, cfg1.compareTo(cfg2));
@@ -114,6 +136,13 @@
         cfg2.locale = new Locale("2", "", "");
         assertEquals(1, cfg1.compareTo(cfg2));
 
+        cfg1.locale = new Locale("");
+        cfg2.locale = null;
+        assertTrue(cfg1.compareTo(cfg2) < 0);
+        cfg1.locale = null;
+        cfg2.locale = new Locale("");
+        assertTrue(cfg1.compareTo(cfg2) > 0);
+
         cfg1.mnc = 2;
         cfg2.mnc = 3;
         assertEquals(-1, cfg1.compareTo(cfg2));
@@ -160,6 +189,11 @@
                 | ActivityInfo.CONFIG_MNC
                 | ActivityInfo.CONFIG_LOCALE
                 | ActivityInfo.CONFIG_LAYOUT_DIRECTION, mConfigDefault, config);
+        config.setLocales(LocaleList.forLanguageTags("fr,en"));
+        doConfigCompare(ActivityInfo.CONFIG_MCC
+                | ActivityInfo.CONFIG_MNC
+                | ActivityInfo.CONFIG_LOCALE
+                | ActivityInfo.CONFIG_LAYOUT_DIRECTION, mConfigDefault, config);
         config.screenLayout = 1;
         doConfigCompare(ActivityInfo.CONFIG_MCC
                 | ActivityInfo.CONFIG_MNC
@@ -282,6 +316,7 @@
         assertFalse(temp.equals(mConfigDefault));
         temp.setToDefaults();
         assertTrue(temp.equals(mConfigDefault));
+        assertTrue(temp.getLocales().isEmpty());
     }
 
     public void testToString() {
@@ -289,47 +324,62 @@
     }
 
     public void testWriteToParcel() {
-        assertWriteToParcel(createConfig(null), Parcel.obtain());
+        assertWriteToParcel(createConfig((Locale) null), Parcel.obtain());
+        assertWriteToParcel(createConfig(new Locale("")), Parcel.obtain());
         assertWriteToParcel(createConfig(Locale.JAPAN), Parcel.obtain());
+        assertWriteToParcel(createConfig(Locale.forLanguageTag("en-Shaw")), Parcel.obtain());
+        assertWriteToParcel(createConfig(LocaleList.forLanguageTags("fr,en-US")), Parcel.obtain());
     }
 
     public void testSetLocale() {
         Configuration config = new Configuration();
 
+        config.setLocale(null);
+        assertNull(config.locale);
+        assertTrue(config.getLocales().isEmpty());
+
         config.setLocale(Locale.getDefault());
         assertEquals(Locale.getDefault(), config.locale);
-        assertEquals(View.LAYOUT_DIRECTION_LTR, config.getLayoutDirection());
+        assertEquals(new LocaleList(Locale.getDefault()), config.getLocales());
 
         config.setLocale(Locale.ENGLISH);
         assertEquals(Locale.ENGLISH, config.locale);
+        assertEquals(new LocaleList(Locale.ENGLISH), config.getLocales());
         assertEquals(View.LAYOUT_DIRECTION_LTR, config.getLayoutDirection());
 
         config.setLocale(Locale.US);
         assertEquals(Locale.US, config.locale);
+        assertEquals(new LocaleList(Locale.US), config.getLocales());
         assertEquals(View.LAYOUT_DIRECTION_LTR, config.getLayoutDirection());
 
         final Locale arEGLocale = new Locale("ar", "EG");
         config.setLocale(arEGLocale);
         assertEquals(arEGLocale, config.locale);
+        assertEquals(new LocaleList(arEGLocale), config.getLocales());
         assertEquals(View.LAYOUT_DIRECTION_RTL, config.getLayoutDirection());
 
-        final Locale faFALocale = new Locale("fa", "FA");
-        config.setLocale(faFALocale);
-        assertEquals(faFALocale, config.locale);
+        final Locale faIRLocale = new Locale("fa", "IR");
+        config.setLocale(faIRLocale);
+        assertEquals(faIRLocale, config.locale);
+        assertEquals(new LocaleList(faIRLocale), config.getLocales());
         assertEquals(View.LAYOUT_DIRECTION_RTL, config.getLayoutDirection());
 
         final Locale iwILLocale = new Locale("iw", "IL");
         config.setLocale(iwILLocale);
         assertEquals(iwILLocale, config.locale);
+        assertEquals(new LocaleList(iwILLocale), config.getLocales());
+        assertEquals(View.LAYOUT_DIRECTION_RTL, config.getLayoutDirection());
+
+        final Locale urPKLocale = new Locale("ur", "PK");
+        config.setLocale(urPKLocale);
+        assertEquals(urPKLocale, config.locale);
+        assertEquals(new LocaleList(urPKLocale), config.getLocales());
         assertEquals(View.LAYOUT_DIRECTION_RTL, config.getLayoutDirection());
     }
 
     public void testSetGetLayoutDirection() {
         Configuration config = new Configuration();
 
-        config.setLayoutDirection(Locale.getDefault());
-        assertEquals(View.LAYOUT_DIRECTION_LTR, config.getLayoutDirection());
-
         config.setLayoutDirection(Locale.ENGLISH);
         assertEquals(View.LAYOUT_DIRECTION_LTR, config.getLayoutDirection());
 
@@ -340,21 +390,230 @@
         config.setLayoutDirection(arEGLocale);
         assertEquals(View.LAYOUT_DIRECTION_RTL, config.getLayoutDirection());
 
-        final Locale faFALocale = new Locale("fa", "FA");
-        config.setLayoutDirection(faFALocale);
+        final Locale faIRLocale = new Locale("fa", "IR");
+        config.setLayoutDirection(faIRLocale);
         assertEquals(View.LAYOUT_DIRECTION_RTL, config.getLayoutDirection());
 
         final Locale iwILLocale = new Locale("iw", "IL");
         config.setLayoutDirection(iwILLocale);
         assertEquals(View.LAYOUT_DIRECTION_RTL, config.getLayoutDirection());
+
+        final Locale urPKLocale = new Locale("ur", "PK");
+        config.setLayoutDirection(urPKLocale);
+        assertEquals(View.LAYOUT_DIRECTION_RTL, config.getLayoutDirection());
+    }
+
+    public void testFixUpLocaleList() {
+        Configuration config = new Configuration();
+
+        config.setLocales(LocaleList.forLanguageTags("fr"));
+        config.locale = null;
+        assertEquals(LocaleList.getEmptyLocaleList(), config.getLocales());
+
+        config.setLocales(LocaleList.forLanguageTags("fr,en"));
+        config.locale = Locale.forLanguageTag("en");
+        assertEquals(LocaleList.forLanguageTags("en"), config.getLocales());
+
+        config.setLocales(LocaleList.forLanguageTags("fr,en"));
+        config.locale = Locale.forLanguageTag("fr");
+        assertEquals(LocaleList.forLanguageTags("fr,en"), config.getLocales());
+    }
+
+    public void testSetTo_localeFixUp() {
+        Configuration config1 = new Configuration();
+        Configuration config2 = new Configuration();
+        config2.locale = Locale.FRENCH;
+
+        config1.setTo(config2);
+        assertEquals(Locale.FRENCH, config1.locale);
+        assertEquals(new LocaleList(Locale.FRENCH), config1.getLocales());
+        assertEquals(new LocaleList(Locale.FRENCH), config2.getLocales());
+    }
+
+    public void testToString_localeFixUp() {
+        Configuration config1 = new Configuration();
+        Configuration config2 = new Configuration();
+        config1.setLocales(LocaleList.forLanguageTags("fr,en"));
+        config1.locale = Locale.forLanguageTag("en");
+        config2.setLocales(LocaleList.forLanguageTags("en"));
+
+        assertEquals(config1.toString(), config2.toString());
+    }
+
+    public void testUpdateFrom_localeFixUp() {
+        Configuration config1, config2;
+        int changed;
+
+        config1 = new Configuration();
+        config2 = new Configuration();
+        config1.locale = Locale.FRENCH;
+        changed = config1.updateFrom(config2);
+        assertEquals(0, changed);
+        assertEquals(Locale.FRENCH, config1.locale);
+        assertEquals(new LocaleList(Locale.FRENCH), config1.getLocales());
+
+        config1 = new Configuration();
+        config2 = new Configuration();
+        config2.locale = Locale.FRENCH;
+        changed = config1.updateFrom(config2);
+        assertEquals(ActivityInfo.CONFIG_LOCALE | ActivityInfo.CONFIG_LAYOUT_DIRECTION, changed);
+        assertEquals(Locale.FRENCH, config1.locale);
+        assertEquals(new LocaleList(Locale.FRENCH), config1.getLocales());
+        assertEquals(new LocaleList(Locale.FRENCH), config2.getLocales());
+
+        config1 = new Configuration();
+        config2 = new Configuration();
+        config1.setLocales(LocaleList.forLanguageTags("en,fr"));
+        config1.locale = Locale.forLanguageTag("fr");
+        config2.setLocales(LocaleList.forLanguageTags("en,de"));
+        config2.locale = Locale.forLanguageTag("fr");
+        changed = config1.updateFrom(config2);
+        assertEquals(0, changed);
+        assertEquals(Locale.forLanguageTag("fr"), config1.locale);
+        assertEquals(LocaleList.forLanguageTags("fr"), config1.getLocales());
+        assertEquals(LocaleList.forLanguageTags("fr"), config2.getLocales());
+    }
+
+    public void testUpdateFrom_layoutDirection() {
+        Configuration config1, config2;
+        int changed;
+
+        config1 = new Configuration();
+        config2 = new Configuration();
+        config1.setLocales(LocaleList.forLanguageTags("fr,en"));
+        config2.setLocales(LocaleList.forLanguageTags("de,en"));
+        changed = config1.updateFrom(config2);
+        assertTrue((changed & ActivityInfo.CONFIG_LAYOUT_DIRECTION) != 0);
+
+        config1 = new Configuration();
+        config2 = new Configuration();
+        config1.setLocales(LocaleList.forLanguageTags("fr,en"));
+        config2.setLocales(LocaleList.forLanguageTags("fr,de"));
+        changed = config1.updateFrom(config2);
+        assertEquals(0, changed & ActivityInfo.CONFIG_LAYOUT_DIRECTION);
+    }
+
+    public void testDiff_localeFixUp() {
+        Configuration config1 = new Configuration();
+        Configuration config2 = new Configuration();
+        config1.setLocales(LocaleList.forLanguageTags("en,fr"));
+        config1.locale = Locale.forLanguageTag("fr");
+        config2.setLocales(LocaleList.forLanguageTags("en,de"));
+        config2.locale = Locale.forLanguageTag("fr");
+
+        int diff = config1.diff(config2);
+        assertEquals(0, diff);
+    }
+
+    public void testCompareTo_localeFixUp() {
+        Configuration config1 = new Configuration();
+        Configuration config2 = new Configuration();
+        config1.setLocales(LocaleList.forLanguageTags("en,fr"));
+        config2.setLocales(LocaleList.forLanguageTags("en,fr"));
+        assertEquals(0, config1.compareTo(config2));
+        config1.locale = new Locale("2");
+        config2.locale = new Locale("3");
+        assertEquals(-1, config1.compareTo(config2));
+    }
+
+    public void testSetLocales_null() {
+        Configuration config = new Configuration();
+        config.setLocales(null);
+        assertNull(config.locale);
+        assertNotNull(config.getLocales());
+        assertTrue(config.getLocales().isEmpty());
+        assertEquals(View.LAYOUT_DIRECTION_LTR, config.getLayoutDirection());
+    }
+
+    public void testSetLocales_emptyList() {
+        Configuration config = new Configuration();
+        config.setLocales(LocaleList.getEmptyLocaleList());
+        assertNull(config.locale);
+        assertNotNull(config.getLocales());
+        assertTrue(config.getLocales().isEmpty());
+        assertEquals(View.LAYOUT_DIRECTION_LTR, config.getLayoutDirection());
+    }
+
+    public void testSetLocales_oneLtr() {
+        Configuration config = new Configuration();
+        Locale loc = Locale.forLanguageTag("en");
+        LocaleList ll = new LocaleList(loc);
+        config.setLocales(ll);
+        assertEquals(loc, config.locale);
+        assertEquals(ll, config.getLocales());
+        assertEquals(View.LAYOUT_DIRECTION_LTR, config.getLayoutDirection());
+    }
+
+    public void testSetLocales_oneRtl() {
+        Configuration config = new Configuration();
+        Locale loc = Locale.forLanguageTag("az-Arab");
+        LocaleList ll = new LocaleList(loc);
+        config.setLocales(ll);
+        assertEquals(loc, config.locale);
+        assertEquals(ll, config.getLocales());
+        assertEquals(View.LAYOUT_DIRECTION_RTL, config.getLayoutDirection());
+    }
+
+    public void testSetLocales_twoLocales() {
+        Configuration config = new Configuration();
+        Locale rtlLoc = Locale.forLanguageTag("az-Arab");
+        Locale ltrLoc = Locale.forLanguageTag("en");
+        LocaleList ll = LocaleList.forLanguageTags("az-Arab,en");
+        config.setLocales(ll);
+        assertEquals(rtlLoc, config.locale);
+        assertEquals(ll, config.getLocales());
+        assertEquals(View.LAYOUT_DIRECTION_RTL, config.getLayoutDirection());
+    }
+
+    public void testSetLocales_overridesLocale() {
+        Configuration config = new Configuration();
+        config.locale = Locale.forLanguageTag("en");
+        LocaleList ll = LocaleList.forLanguageTags("az-Arab,en");
+        config.setLocales(ll);
+
+        assertEquals(Locale.forLanguageTag("az-Arab"), config.locale);
+        assertEquals(ll, config.getLocales());
+        assertEquals(View.LAYOUT_DIRECTION_RTL, config.getLayoutDirection());
+    }
+
+    public void testSetLocales_overridesSetLocale() {
+        Configuration config = new Configuration();
+        config.setLocale(Locale.forLanguageTag("en"));
+        LocaleList ll = LocaleList.forLanguageTags("az-Arab,en");
+        config.setLocales(ll);
+
+        assertEquals(Locale.forLanguageTag("az-Arab"), config.locale);
+        assertEquals(ll, config.getLocales());
+        assertEquals(View.LAYOUT_DIRECTION_RTL, config.getLayoutDirection());
+    }
+
+    public void testSetLocale_overridesSetLocales() {
+        Configuration config = new Configuration();
+        config.setLocales(LocaleList.forLanguageTags("az-Arab,en"));
+        config.setLocale(Locale.ENGLISH);
+
+        assertEquals(Locale.ENGLISH, config.locale);
+        assertEquals(new LocaleList(Locale.ENGLISH), config.getLocales());
+        assertEquals(View.LAYOUT_DIRECTION_LTR, config.getLayoutDirection());
+    }
+
+    private Configuration createConfig(LocaleList list) {
+        Configuration config = createConfig();
+        config.setLocales(list);
+        return config;
     }
 
     private Configuration createConfig(Locale locale) {
+        Configuration config = createConfig();
+        config.locale = locale;
+        return config;
+    }
+
+    private Configuration createConfig() {
         Configuration config = new Configuration();
         config.fontScale = 13.37f;
         config.mcc = 0;
         config.mnc = 1;
-        config.locale = locale;
         config.touchscreen = Configuration.TOUCHSCREEN_STYLUS;
         config.keyboard = Configuration.KEYBOARD_UNDEFINED;
         config.keyboardHidden = Configuration.KEYBOARDHIDDEN_YES;
diff --git a/tests/tests/util/src/android/util/cts/LocaleListTest.java b/tests/tests/util/src/android/util/cts/LocaleListTest.java
index f7abfdf9..9b5d5e9 100644
--- a/tests/tests/util/src/android/util/cts/LocaleListTest.java
+++ b/tests/tests/util/src/android/util/cts/LocaleListTest.java
@@ -31,7 +31,15 @@
         assertNull(ll.get(1));
         assertNull(ll.get(10));
 
-        ll = new LocaleList(null);
+        ll = new LocaleList((Locale) null);
+        assertNotNull(ll);
+        assertTrue(ll.isEmpty());
+        assertEquals(0, ll.size());
+        assertNull(ll.getPrimary());
+        assertNull(ll.get(1));
+        assertNull(ll.get(10));
+
+        ll = new LocaleList((Locale[]) null);
         assertNotNull(ll);
         assertTrue(ll.isEmpty());
         assertEquals(0, ll.size());
@@ -49,8 +57,7 @@
     }
 
     public void testOneMemberLocaleList() {
-        final Locale[] la = {Locale.US};
-        final LocaleList ll = new LocaleList(la);
+        final LocaleList ll = new LocaleList(Locale.US);
         assertNotNull(ll);
         assertFalse(ll.isEmpty());
         assertEquals(1, ll.size());
@@ -93,4 +100,88 @@
             assertEquals(IllegalArgumentException.class, e.getClass());
         }
     }
+
+    public void testEquals() {
+        final LocaleList empty = new LocaleList();
+        final LocaleList anotherEmpty = new LocaleList();
+        LocaleList oneMember = new LocaleList(Locale.US);
+        LocaleList sameOneMember = new LocaleList(new Locale("en", "US"));
+        LocaleList differentOneMember = new LocaleList(Locale.FRENCH);
+        Locale[] la = {Locale.US, Locale.FRENCH};
+        LocaleList twoMember = new LocaleList(la);
+
+        assertFalse(empty.equals(null));
+        assertFalse(oneMember.equals(null));
+
+        assertFalse(empty.equals(new Object()));
+
+        assertTrue(empty.equals(empty));
+        assertTrue(oneMember.equals(oneMember));
+
+        assertFalse(empty.equals(oneMember));
+        assertFalse(oneMember.equals(twoMember));
+
+        assertFalse(oneMember.equals(differentOneMember));
+
+        assertTrue(empty.equals(anotherEmpty));
+        assertTrue(oneMember.equals(sameOneMember));
+    }
+
+    public void testHashCode() {
+        final LocaleList empty = new LocaleList();
+        final LocaleList anotherEmpty = new LocaleList();
+        Locale[] la1 = {Locale.US};
+        LocaleList oneMember = new LocaleList(la1);
+        LocaleList sameOneMember = new LocaleList(la1);
+
+        assertEquals(empty.hashCode(), anotherEmpty.hashCode());
+        assertEquals(oneMember.hashCode(), sameOneMember.hashCode());
+    }
+
+    public void testToString() {
+        LocaleList ll = new LocaleList();
+        assertEquals("[]", ll.toString());
+
+        final Locale[] la1 = {Locale.US};
+        ll = new LocaleList(la1);
+        assertEquals("["+Locale.US.toString()+"]", ll.toString());
+
+        final Locale[] la2 = {Locale.US, Locale.FRENCH};
+        ll = new LocaleList(la2);
+        assertEquals("["+Locale.US.toString()+","+Locale.FRENCH.toString()+"]", ll.toString());
+    }
+
+    public void testToLanguageTags() {
+        LocaleList ll = new LocaleList();
+        assertEquals("", ll.toLanguageTags());
+
+        final Locale[] la1 = {Locale.US};
+        ll = new LocaleList(la1);
+        assertEquals(Locale.US.toLanguageTag(), ll.toLanguageTags());
+
+        final Locale[] la2 = {Locale.US, Locale.FRENCH};
+        ll = new LocaleList(la2);
+        assertEquals(Locale.US.toLanguageTag()+","+Locale.FRENCH.toLanguageTag(),
+                ll.toLanguageTags());
+    }
+
+    public void testGetEmptyLocaleList() {
+        LocaleList empty = LocaleList.getEmptyLocaleList();
+        LocaleList anotherEmpty = LocaleList.getEmptyLocaleList();
+        LocaleList constructedEmpty = new LocaleList();
+
+        assertEquals(constructedEmpty, empty);
+        assertSame(empty, anotherEmpty);
+    }
+
+    public void testForLanguageTags() {
+        assertEquals(LocaleList.getEmptyLocaleList(), LocaleList.forLanguageTags(null));
+        assertEquals(LocaleList.getEmptyLocaleList(), LocaleList.forLanguageTags(""));
+
+        assertEquals(new LocaleList(Locale.forLanguageTag("en-US")),
+                LocaleList.forLanguageTags("en-US"));
+
+        final Locale[] la = {Locale.forLanguageTag("en-PH"), Locale.forLanguageTag("en-US")};
+        assertEquals(new LocaleList(la), LocaleList.forLanguageTags("en-PH,en-US"));
+    }
 }