diff --git a/Android.bp b/Android.bp
new file mode 100644
index 0000000..680c703
--- /dev/null
+++ b/Android.bp
@@ -0,0 +1,24 @@
+// Copyright (C) 2018 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.
+
+android_library {
+    name: "localepicker",
+    manifest: "AndroidManifest.xml",
+    resource_dirs: [
+        "res",
+    ],
+    srcs: [
+        "src/**/*.java",
+    ],
+}
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
new file mode 100644
index 0000000..472f3e5
--- /dev/null
+++ b/AndroidManifest.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    Copyright (C) 2015 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.localepicker">
+
+  <uses-sdk android:minSdkVersion="28" android:targetSdkVersion="28" />
+
+</manifest>
diff --git a/res/layout/language_picker_item.xml b/res/layout/language_picker_item.xml
new file mode 100644
index 0000000..d63ed5d
--- /dev/null
+++ b/res/layout/language_picker_item.xml
@@ -0,0 +1,28 @@
+<?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.
+-->
+
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+     android:layout_width="match_parent"
+     android:layout_height="wrap_content"
+     android:id="@+id/locale"
+     android:gravity="center_vertical"
+     android:minHeight="?android:attr/listPreferredItemHeight"
+     android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+     android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+     android:textAppearance="?android:attr/textAppearanceListItem"
+     android:layoutDirection="locale"
+     android:textDirection="locale"
+     android:paddingVertical="8dp" />
diff --git a/res/layout/language_picker_section_header.xml b/res/layout/language_picker_section_header.xml
new file mode 100644
index 0000000..87174ce
--- /dev/null
+++ b/res/layout/language_picker_section_header.xml
@@ -0,0 +1,27 @@
+<?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.
+-->
+
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+     xmlns:tools="http://schemas.android.com/tools"
+     style="?android:attr/preferenceCategoryStyle"
+     android:layout_width="match_parent"
+     android:layout_height="36dp"
+     android:gravity="center_vertical"
+     android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+     android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+     android:textColor="?android:attr/colorAccent"
+     android:textStyle="bold"
+     tools:text="@string/language_picker_section_all"/>
diff --git a/res/values/strings.xml b/res/values/strings.xml
new file mode 100644
index 0000000..0eec907
--- /dev/null
+++ b/res/values/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 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.
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- List section subheader for the language picker, containing a list of suggested languages determined by the default region [CHAR LIMIT=30] -->
+    <string name="language_picker_section_suggested">Suggested</string>
+    <!-- List section subheader for the language picker, containing a list of all languages available [CHAR LIMIT=30] -->
+    <string name="language_picker_section_all">All languages</string>
+    <!-- List section subheader for the region picker, containing a list of all regions supported for the selected language.
+    Warning: this is a more 'neutral' term for 'country', not for the sub-divisions of a country. [CHAR LIMIT=30] -->
+    <string name="region_picker_section_all">All regions</string>
+
+</resources>
\ No newline at end of file
diff --git a/src/com/android/localepicker/LocaleHelper.java b/src/com/android/localepicker/LocaleHelper.java
new file mode 100644
index 0000000..7fd598f
--- /dev/null
+++ b/src/com/android/localepicker/LocaleHelper.java
@@ -0,0 +1,271 @@
+/*
+ * 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.
+ */
+
+package com.android.localepicker;
+
+import android.annotation.IntRange;
+import android.icu.text.ListFormatter;
+import android.icu.util.ULocale;
+import android.os.LocaleList;
+import android.text.TextUtils;
+
+import java.text.Collator;
+import java.util.Comparator;
+import java.util.Locale;
+
+/**
+ * This class implements some handy methods to process with locales.
+ */
+public class LocaleHelper {
+
+    /**
+     * Sentence-case (first character uppercased).
+     *
+     * <p>There is no good API available for this, not even in ICU.
+     * We can revisit this if we get some ICU support later.</p>
+     *
+     * <p>There are currently several tickets requesting this feature:</p>
+     * <ul>
+     * <li>ICU needs to provide an easy way to titlecase only one first letter
+     *   http://bugs.icu-project.org/trac/ticket/11729</li>
+     * <li>Add "initial case"
+     *    http://bugs.icu-project.org/trac/ticket/8394</li>
+     * <li>Add code for initialCase, toTitlecase don't modify after Lt,
+     *   avoid 49Ers, low-level language-specific casing
+     *   http://bugs.icu-project.org/trac/ticket/10410</li>
+     * <li>BreakIterator.getFirstInstance: Often you need to titlecase just the first
+     *   word, and leave the rest of the string alone.  (closed as duplicate)
+     *   http://bugs.icu-project.org/trac/ticket/8946</li>
+     * </ul>
+     *
+     * <p>A (clunky) option with the current ICU API is:</p>
+     * {{
+     *   BreakIterator breakIterator = BreakIterator.getSentenceInstance(locale);
+     *   String result = UCharacter.toTitleCase(locale,
+     *       source, breakIterator, UCharacter.TITLECASE_NO_LOWERCASE);
+     * }}
+     *
+     * <p>That also means creating a BreakIterator for each locale. Expensive...</p>
+     *
+     * @param str the string to sentence-case.
+     * @param locale the locale used for the case conversion.
+     * @return the string converted to sentence-case.
+     */
+    static String toSentenceCase(String str, Locale locale) {
+        if (str.isEmpty()) {
+            return str;
+        }
+        final int firstCodePointLen = str.offsetByCodePoints(0, 1);
+        return str.substring(0, firstCodePointLen).toUpperCase(locale)
+                + str.substring(firstCodePointLen);
+    }
+
+    /**
+     * Normalizes a string for locale name search. Does case conversion for now,
+     * but might do more in the future.
+     *
+     * <p>Warning: it is only intended to be used in searches by the locale picker.
+     * Don't use it for other things, it is very limited.</p>
+     *
+     * @param str the string to normalize
+     * @param locale the locale that might be used for certain operations (i.e. case conversion)
+     * @return the string normalized for search
+     */
+    static String normalizeForSearch(String str, Locale locale) {
+        // TODO: tbd if it needs to be smarter (real normalization, remove accents, etc.)
+        // If needed we might use case folding and ICU/CLDR's collation-based loose searching.
+        // TODO: decide what should the locale be, the default locale, or the locale of the string.
+        // Uppercase is better than lowercase because of things like sharp S, Greek sigma, ...
+        return str != null ? str.toUpperCase() : null;
+    }
+
+    // For some locales we want to use a "dialect" form, for instance
+    // "Dari" instead of "Persian (Afghanistan)", or "Moldavian" instead of "Romanian (Moldova)"
+    private static boolean shouldUseDialectName(Locale locale) {
+        final String lang = locale.getLanguage();
+        return "fa".equals(lang) // Persian
+                || "ro".equals(lang) // Romanian
+                || "zh".equals(lang); // Chinese
+    }
+
+    /**
+     * Returns the locale localized for display in the provided locale.
+     *
+     * @param locale the locale whose name is to be displayed.
+     * @param displayLocale the locale in which to display the name.
+     * @param sentenceCase true if the result should be sentence-cased
+     * @return the localized name of the locale.
+     */
+    public static String getDisplayName(Locale locale, Locale displayLocale, boolean sentenceCase) {
+        final ULocale displayULocale = ULocale.forLocale(displayLocale);
+        String result = shouldUseDialectName(locale)
+                ? ULocale.getDisplayNameWithDialect(locale.toLanguageTag(), displayULocale)
+                : ULocale.getDisplayName(locale.toLanguageTag(), displayULocale);
+        return sentenceCase ? toSentenceCase(result, displayLocale) : result;
+    }
+
+    /**
+     * Returns the locale localized for display in the default locale.
+     *
+     * @param locale the locale whose name is to be displayed.
+     * @param sentenceCase true if the result should be sentence-cased
+     * @return the localized name of the locale.
+     */
+    public static String getDisplayName(Locale locale, boolean sentenceCase) {
+        return getDisplayName(locale, Locale.getDefault(), sentenceCase);
+    }
+
+    /**
+     * Returns a locale's country localized for display in the provided locale.
+     *
+     * @param locale the locale whose country will be displayed.
+     * @param displayLocale the locale in which to display the name.
+     * @return the localized country name.
+     */
+    public static String getDisplayCountry(Locale locale, Locale displayLocale) {
+        final String languageTag = locale.toLanguageTag();
+        final ULocale uDisplayLocale = ULocale.forLocale(displayLocale);
+        final String country = ULocale.getDisplayCountry(languageTag, uDisplayLocale);
+        final String numberingSystem = locale.getUnicodeLocaleType("nu");
+        if (numberingSystem != null) {
+            return String.format("%s (%s)", country,
+                    ULocale.getDisplayKeywordValue(languageTag, "numbers", uDisplayLocale));
+        } else {
+            return country;
+        }
+    }
+
+    /**
+     * Returns a locale's country localized for display in the default locale.
+     *
+     * @param locale the locale whose country will be displayed.
+     * @return the localized country name.
+     */
+    public static String getDisplayCountry(Locale locale) {
+        return ULocale.getDisplayCountry(locale.toLanguageTag(), ULocale.getDefault());
+    }
+
+    /**
+     * Returns the locale list localized for display in the provided locale.
+     *
+     * @param locales the list of locales whose names is to be displayed.
+     * @param displayLocale the locale in which to display the names.
+     *                      If this is null, it will use the default locale.
+     * @param maxLocales maximum number of locales to display. Generates ellipsis after that.
+     * @return the locale aware list of locale names
+     */
+    public static String getDisplayLocaleList(
+            LocaleList locales, Locale displayLocale, @IntRange(from=1) int maxLocales) {
+
+        final Locale dispLocale = displayLocale == null ? Locale.getDefault() : displayLocale;
+
+        final boolean ellipsisNeeded = locales.size() > maxLocales;
+        final int localeCount, listCount;
+        if (ellipsisNeeded) {
+            localeCount = maxLocales;
+            listCount = maxLocales + 1;  // One extra slot for the ellipsis
+        } else {
+            listCount = localeCount = locales.size();
+        }
+        final String[] localeNames = new String[listCount];
+        for (int i = 0; i < localeCount; i++) {
+            localeNames[i] = LocaleHelper.getDisplayName(locales.get(i), dispLocale, false);
+        }
+        if (ellipsisNeeded) {
+            // Theoretically, we want to extract this from ICU's Resource Bundle for
+            // "Ellipsis/final", which seeAms to have different strings than the normal ellipsis for
+            // Hong Kong Traditional Chinese (zh_Hant_HK) and Dzongkha (dz). But that has two
+            // problems: it's expensive to extract it, and in case the output string becomes
+            // automatically ellipsized, it can result in weird output.
+            localeNames[maxLocales] = TextUtils.getEllipsisString(TextUtils.TruncateAt.END);
+        }
+
+        ListFormatter lfn = ListFormatter.getInstance(dispLocale);
+        return lfn.format((Object[]) localeNames);
+    }
+
+    /**
+     * Adds the likely subtags for a provided locale ID.
+     *
+     * @param locale the locale to maximize.
+     * @return the maximized Locale instance.
+     */
+    public static Locale addLikelySubtags(Locale locale) {
+        return libcore.icu.ICU.addLikelySubtags(locale);
+    }
+
+    /**
+     * Locale-sensitive comparison for LocaleInfo.
+     *
+     * <p>It uses the label, leaving the decision on what to put there to the LocaleInfo.
+     * For instance fr-CA can be shown as "français" as a generic label in the language selection,
+     * or "français (Canada)" if it is a suggestion, or "Canada" in the country selection.</p>
+     *
+     * <p>Gives priority to suggested locales (to sort them at the top).</p>
+     */
+    public static final class LocaleInfoComparator implements Comparator<LocaleStore.LocaleInfo> {
+        private final Collator mCollator;
+        private final boolean mCountryMode;
+        private static final String PREFIX_ARABIC = "\u0627\u0644"; // ALEF-LAM, ال
+
+        /**
+         * Constructor.
+         *
+         * @param sortLocale the locale to be used for sorting.
+         */
+        public LocaleInfoComparator(Locale sortLocale, boolean countryMode) {
+            mCollator = Collator.getInstance(sortLocale);
+            mCountryMode = countryMode;
+        }
+
+        /*
+         * The Arabic collation should ignore Alef-Lam at the beginning (b/26277596)
+         *
+         * We look at the label's locale, not the current system locale.
+         * This is because the name of the Arabic language itself is in Arabic,
+         * and starts with Alef-Lam, no matter what the system locale is.
+         */
+        private String removePrefixForCompare(Locale locale, String str) {
+            if ("ar".equals(locale.getLanguage()) && str.startsWith(PREFIX_ARABIC)) {
+                return str.substring(PREFIX_ARABIC.length());
+            }
+            return str;
+        }
+
+        /**
+         * Compares its two arguments for order.
+         *
+         * @param lhs   the first object to be compared
+         * @param rhs   the second object to be compared
+         * @return  a negative integer, zero, or a positive integer as the first
+         *          argument is less than, equal to, or greater than the second.
+         */
+        @Override
+        public int compare(LocaleStore.LocaleInfo lhs, LocaleStore.LocaleInfo rhs) {
+            // We don't care about the various suggestion types, just "suggested" (!= 0)
+            // and "all others" (== 0)
+            if (lhs.isSuggested() == rhs.isSuggested()) {
+                // They are in the same "bucket" (suggested / others), so we compare the text
+                return mCollator.compare(
+                        removePrefixForCompare(lhs.getLocale(), lhs.getLabel(mCountryMode)),
+                        removePrefixForCompare(rhs.getLocale(), rhs.getLabel(mCountryMode)));
+            } else {
+                // One locale is suggested and one is not, so we put them in different "buckets"
+                return lhs.isSuggested() ? -1 : 1;
+            }
+        }
+    }
+}
diff --git a/src/com/android/localepicker/LocaleStore.java b/src/com/android/localepicker/LocaleStore.java
new file mode 100644
index 0000000..5d07ff2
--- /dev/null
+++ b/src/com/android/localepicker/LocaleStore.java
@@ -0,0 +1,382 @@
+/*
+ * 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.
+ */
+
+package com.android.localepicker;
+
+import android.content.Context;
+import android.os.LocaleList;
+import android.provider.Settings;
+import android.telephony.TelephonyManager;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.app.LocalePicker;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.IllformedLocaleException;
+import java.util.Locale;
+import java.util.Set;
+
+public class LocaleStore {
+    private static final HashMap<String, LocaleInfo> sLocaleCache = new HashMap<>();
+    private static boolean sFullyInitialized = false;
+
+    public static class LocaleInfo implements Serializable {
+        @VisibleForTesting static final int SUGGESTION_TYPE_NONE = 0;
+        @VisibleForTesting static final int SUGGESTION_TYPE_SIM = 1 << 0;
+        @VisibleForTesting static final int SUGGESTION_TYPE_CFG = 1 << 1;
+
+        private final Locale mLocale;
+        private final Locale mParent;
+        private final String mId;
+        private boolean mIsTranslated;
+        private boolean mIsPseudo;
+        private boolean mIsChecked; // Used by the LocaleListEditor to mark entries for deletion
+        // Combination of flags for various reasons to show a locale as a suggestion.
+        // Can be SIM, location, etc.
+        @VisibleForTesting int mSuggestionFlags;
+
+        private String mFullNameNative;
+        private String mFullCountryNameNative;
+        private String mLangScriptKey;
+
+        private LocaleInfo(Locale locale) {
+            this.mLocale = locale;
+            this.mId = locale.toLanguageTag();
+            this.mParent = getParent(locale);
+            this.mIsChecked = false;
+            this.mSuggestionFlags = SUGGESTION_TYPE_NONE;
+            this.mIsTranslated = false;
+            this.mIsPseudo = false;
+        }
+
+        private LocaleInfo(String localeId) {
+            this(Locale.forLanguageTag(localeId));
+        }
+
+        private static Locale getParent(Locale locale) {
+            if (locale.getCountry().isEmpty()) {
+                return null;
+            }
+            return new Locale.Builder()
+                    .setLocale(locale)
+                    .setRegion("")
+                    .setExtension(Locale.UNICODE_LOCALE_EXTENSION, "")
+                    .build();
+        }
+
+        @Override
+        public String toString() {
+            return mId;
+        }
+
+        public Locale getLocale() {
+            return mLocale;
+        }
+
+        public Locale getParent() {
+            return mParent;
+        }
+
+        public String getId() {
+            return mId;
+        }
+
+        public boolean isTranslated() {
+            return mIsTranslated;
+        }
+
+        public void setTranslated(boolean isTranslated) {
+            mIsTranslated = isTranslated;
+        }
+
+        /* package */ boolean isSuggested() {
+            if (!mIsTranslated) { // Never suggest an untranslated locale
+                return false;
+            }
+            return mSuggestionFlags != SUGGESTION_TYPE_NONE;
+        }
+
+        private boolean isSuggestionOfType(int suggestionMask) {
+            if (!mIsTranslated) { // Never suggest an untranslated locale
+                return false;
+            }
+            return (mSuggestionFlags & suggestionMask) == suggestionMask;
+        }
+
+        public String getFullNameNative() {
+            if (mFullNameNative == null) {
+                mFullNameNative =
+                        LocaleHelper.getDisplayName(mLocale, mLocale, true /* sentence case */);
+            }
+            return mFullNameNative;
+        }
+
+        String getFullCountryNameNative() {
+            if (mFullCountryNameNative == null) {
+                mFullCountryNameNative = LocaleHelper.getDisplayCountry(mLocale, mLocale);
+            }
+            return mFullCountryNameNative;
+        }
+
+        String getFullCountryNameInUiLanguage() {
+            // We don't cache the UI name because the default locale keeps changing
+            return LocaleHelper.getDisplayCountry(mLocale);
+        }
+
+        /** Returns the name of the locale in the language of the UI.
+         * It is used for search, but never shown.
+         * For instance German will show as "Deutsch" in the list, but we will also search for
+         * "allemand" if the system UI is in French.
+         */
+        public String getFullNameInUiLanguage() {
+            // We don't cache the UI name because the default locale keeps changing
+            return LocaleHelper.getDisplayName(mLocale, true /* sentence case */);
+        }
+
+        private String getLangScriptKey() {
+            if (mLangScriptKey == null) {
+                Locale baseLocale = new Locale.Builder()
+                    .setLocale(mLocale)
+                    .setExtension(Locale.UNICODE_LOCALE_EXTENSION, "")
+                    .build();
+                Locale parentWithScript = getParent(LocaleHelper.addLikelySubtags(baseLocale));
+                mLangScriptKey =
+                        (parentWithScript == null)
+                        ? mLocale.toLanguageTag()
+                        : parentWithScript.toLanguageTag();
+            }
+            return mLangScriptKey;
+        }
+
+        String getLabel(boolean countryMode) {
+            if (countryMode) {
+                return getFullCountryNameNative();
+            } else {
+                return getFullNameNative();
+            }
+        }
+
+        String getContentDescription(boolean countryMode) {
+            if (countryMode) {
+                return getFullCountryNameInUiLanguage();
+            } else {
+                return getFullNameInUiLanguage();
+            }
+        }
+
+        public boolean getChecked() {
+            return mIsChecked;
+        }
+
+        public void setChecked(boolean checked) {
+            mIsChecked = checked;
+        }
+    }
+
+    private static Set<String> getSimCountries(Context context) {
+        Set<String> result = new HashSet<>();
+
+        TelephonyManager tm = TelephonyManager.from(context);
+
+        if (tm != null) {
+            String iso = tm.getSimCountryIso().toUpperCase(Locale.US);
+            if (!iso.isEmpty()) {
+                result.add(iso);
+            }
+
+            iso = tm.getNetworkCountryIso().toUpperCase(Locale.US);
+            if (!iso.isEmpty()) {
+                result.add(iso);
+            }
+        }
+
+        return result;
+    }
+
+    /*
+     * This method is added for SetupWizard, to force an update of the suggested locales
+     * when the SIM is initialized.
+     *
+     * <p>When the device is freshly started, it sometimes gets to the language selection
+     * before the SIM is properly initialized.
+     * So at the time the cache is filled, the info from the SIM might not be available.
+     * The SetupWizard has a SimLocaleMonitor class to detect onSubscriptionsChanged events.
+     * SetupWizard will call this function when that happens.</p>
+     *
+     * <p>TODO: decide if it is worth moving such kind of monitoring in this shared code.
+     * The user might change the SIM or might cross border and connect to a network
+     * in a different country, without restarting the Settings application or the phone.</p>
+     */
+    public static void updateSimCountries(Context context) {
+        Set<String> simCountries = getSimCountries(context);
+
+        for (LocaleInfo li : sLocaleCache.values()) {
+            // This method sets the suggestion flags for the (new) SIM locales, but it does not
+            // try to clean up the old flags. After all, if the user replaces a German SIM
+            // with a French one, it is still possible that they are speaking German.
+            // So both French and German are reasonable suggestions.
+            if (simCountries.contains(li.getLocale().getCountry())) {
+                li.mSuggestionFlags |= LocaleInfo.SUGGESTION_TYPE_SIM;
+            }
+        }
+    }
+
+    /*
+     * Show all the languages supported for a country in the suggested list.
+     * This is also handy for devices without SIM (tablets).
+     */
+    private static void addSuggestedLocalesForRegion(Locale locale) {
+        if (locale == null) {
+            return;
+        }
+        final String country = locale.getCountry();
+        if (country.isEmpty()) {
+            return;
+        }
+
+        for (LocaleInfo li : sLocaleCache.values()) {
+            if (country.equals(li.getLocale().getCountry())) {
+                // We don't need to differentiate between manual and SIM suggestions
+                li.mSuggestionFlags |= LocaleInfo.SUGGESTION_TYPE_SIM;
+            }
+        }
+    }
+
+    public static void fillCache(Context context) {
+        if (sFullyInitialized) {
+            return;
+        }
+
+        Set<String> simCountries = getSimCountries(context);
+
+        final boolean isInDeveloperMode = Settings.Global.getInt(context.getContentResolver(),
+                Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) != 0;
+        for (String localeId : LocalePicker.getSupportedLocales(context)) {
+            if (localeId.isEmpty()) {
+                throw new IllformedLocaleException("Bad locale entry in locale_config.xml");
+            }
+            LocaleInfo li = new LocaleInfo(localeId);
+
+            if (LocaleList.isPseudoLocale(li.getLocale())) {
+                if (isInDeveloperMode) {
+                    li.setTranslated(true);
+                    li.mIsPseudo = true;
+                    li.mSuggestionFlags |= LocaleInfo.SUGGESTION_TYPE_SIM;
+                } else {
+                    // Do not display pseudolocales unless in development mode.
+                    continue;
+                }
+            }
+
+            if (simCountries.contains(li.getLocale().getCountry())) {
+                li.mSuggestionFlags |= LocaleInfo.SUGGESTION_TYPE_SIM;
+            }
+            sLocaleCache.put(li.getId(), li);
+            final Locale parent = li.getParent();
+            if (parent != null) {
+                String parentId = parent.toLanguageTag();
+                if (!sLocaleCache.containsKey(parentId)) {
+                    sLocaleCache.put(parentId, new LocaleInfo(parent));
+                }
+            }
+        }
+
+        // TODO: See if we can reuse what LocaleList.matchScore does
+        final HashSet<String> localizedLocales = new HashSet<>();
+        for (String localeId : LocalePicker.getSystemAssetLocales()) {
+            LocaleInfo li = new LocaleInfo(localeId);
+            final String country = li.getLocale().getCountry();
+            // All this is to figure out if we should suggest a country
+            if (!country.isEmpty()) {
+                LocaleInfo cachedLocale = null;
+                if (sLocaleCache.containsKey(li.getId())) { // the simple case, e.g. fr-CH
+                    cachedLocale = sLocaleCache.get(li.getId());
+                } else { // e.g. zh-TW localized, zh-Hant-TW in cache
+                    final String langScriptCtry = li.getLangScriptKey() + "-" + country;
+                    if (sLocaleCache.containsKey(langScriptCtry)) {
+                        cachedLocale = sLocaleCache.get(langScriptCtry);
+                    }
+                }
+                if (cachedLocale != null) {
+                    cachedLocale.mSuggestionFlags |= LocaleInfo.SUGGESTION_TYPE_CFG;
+                }
+            }
+            localizedLocales.add(li.getLangScriptKey());
+        }
+
+        for (LocaleInfo li : sLocaleCache.values()) {
+            li.setTranslated(localizedLocales.contains(li.getLangScriptKey()));
+        }
+
+        addSuggestedLocalesForRegion(Locale.getDefault());
+
+        sFullyInitialized = true;
+    }
+
+    private static int getLevel(Set<String> ignorables, LocaleInfo li, boolean translatedOnly) {
+        if (ignorables.contains(li.getId())) return 0;
+        if (li.mIsPseudo) return 2;
+        if (translatedOnly && !li.isTranslated()) return 0;
+        if (li.getParent() != null) return 2;
+        return 0;
+    }
+
+    /**
+     * Returns a list of locales for language or region selection.
+     * If the parent is null, then it is the language list.
+     * If it is not null, then the list will contain all the locales that belong to that parent.
+     * Example: if the parent is "ar", then the region list will contain all Arabic locales.
+     * (this is not language based, but language-script, so that it works for zh-Hant and so on.
+     */
+    public static Set<LocaleInfo> getLevelLocales(Context context, Set<String> ignorables,
+            LocaleInfo parent, boolean translatedOnly) {
+        fillCache(context);
+        String parentId = parent == null ? null : parent.getId();
+
+        HashSet<LocaleInfo> result = new HashSet<>();
+        for (LocaleStore.LocaleInfo li : sLocaleCache.values()) {
+            int level = getLevel(ignorables, li, translatedOnly);
+            if (level == 2) {
+                if (parent != null) { // region selection
+                    if (parentId.equals(li.getParent().toLanguageTag())) {
+                        result.add(li);
+                    }
+                } else { // language selection
+                    if (li.isSuggestionOfType(LocaleInfo.SUGGESTION_TYPE_SIM)) {
+                        result.add(li);
+                    } else {
+                        result.add(getLocaleInfo(li.getParent()));
+                    }
+                }
+            }
+        }
+        return result;
+    }
+
+    public static LocaleInfo getLocaleInfo(Locale locale) {
+        String id = locale.toLanguageTag();
+        LocaleInfo result;
+        if (!sLocaleCache.containsKey(id)) {
+            result = new LocaleInfo(locale);
+            sLocaleCache.put(id, result);
+        } else {
+            result = sLocaleCache.get(id);
+        }
+        return result;
+    }
+}
diff --git a/src/com/android/localepicker/SuggestedLocaleAdapter.java b/src/com/android/localepicker/SuggestedLocaleAdapter.java
new file mode 100644
index 0000000..97e2971
--- /dev/null
+++ b/src/com/android/localepicker/SuggestedLocaleAdapter.java
@@ -0,0 +1,327 @@
+/*
+ * 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.
+ */
+
+package com.android.localepicker;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.content.res.Configuration;
+import android.text.TextUtils;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.Filter;
+import android.widget.Filterable;
+import android.widget.TextView;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.localepicker.R;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Locale;
+import java.util.Set;
+
+
+/**
+ * This adapter wraps around a regular ListAdapter for LocaleInfo, and creates 2 sections.
+ *
+ * <p>The first section contains "suggested" languages (usually including a region),
+ * the second section contains all the languages within the original adapter.
+ * The "others" might still include languages that appear in the "suggested" section.</p>
+ *
+ * <p>Example: if we show "German Switzerland" as "suggested" (based on SIM, let's say),
+ * then "German" will still show in the "others" section, clicking on it will only show the
+ * countries for all the other German locales, but not Switzerland
+ * (Austria, Belgium, Germany, Liechtenstein, Luxembourg)</p>
+ *
+ * <p>This class implements {@link Filterable}; apps using this class can use
+ * {@code getFilter().filter(...)} to filter on the available list of locales.</p>
+ */
+public class SuggestedLocaleAdapter extends BaseAdapter implements Filterable {
+    @VisibleForTesting static final int TYPE_HEADER_SUGGESTED = 0;
+    @VisibleForTesting static final int TYPE_HEADER_ALL_OTHERS = 1;
+    @VisibleForTesting static final int TYPE_LOCALE = 2;
+    @VisibleForTesting static final int MIN_REGIONS_FOR_SUGGESTIONS = 6;
+
+    private ArrayList<LocaleStore.LocaleInfo> mLocaleOptions;
+    private ArrayList<LocaleStore.LocaleInfo> mOriginalLocaleOptions;
+    private int mSuggestionCount;
+    private final boolean mCountryMode;
+    private LayoutInflater mInflater;
+
+    private Locale mDisplayLocale = null;
+    // used to potentially cache a modified Context that uses mDisplayLocale
+    private Context mContextOverride = null;
+
+    public SuggestedLocaleAdapter(Set<LocaleStore.LocaleInfo> localeOptions, boolean countryMode) {
+        mCountryMode = countryMode;
+        mLocaleOptions = new ArrayList<>(localeOptions.size());
+        for (LocaleStore.LocaleInfo li : localeOptions) {
+            if (li.isSuggested()) {
+                mSuggestionCount++;
+            }
+            mLocaleOptions.add(li);
+        }
+    }
+
+    @Override
+    public boolean areAllItemsEnabled() {
+        return false;
+    }
+
+    @Override
+    public boolean isEnabled(int position) {
+        return getItemViewType(position) == TYPE_LOCALE;
+    }
+
+    @Override
+    public int getItemViewType(int position) {
+        if (!showHeaders()) {
+            return TYPE_LOCALE;
+        } else {
+            if (position == 0) {
+                return TYPE_HEADER_SUGGESTED;
+            }
+            if (position == mSuggestionCount + 1) {
+                return TYPE_HEADER_ALL_OTHERS;
+            }
+            return TYPE_LOCALE;
+        }
+    }
+
+    @Override
+    public int getViewTypeCount() {
+        if (showHeaders()) {
+            return 3; // Two headers in addition to the locales
+        } else {
+            return 1; // Locales items only
+        }
+    }
+
+    @Override
+    public int getCount() {
+        if (showHeaders()) {
+            return mLocaleOptions.size() + 2; // 2 extra for the headers
+        } else {
+            return mLocaleOptions.size();
+        }
+    }
+
+    @Override
+    public LocaleStore.LocaleInfo getItem(int position) {
+        if (getItemViewType(position) != TYPE_LOCALE) {
+            return null;
+        }
+
+        int offset = 0;
+        if (showHeaders()) {
+            offset = position > mSuggestionCount ? -2 : -1;
+        }
+
+        return mLocaleOptions.get(position + offset);
+    }
+
+    @Override
+    public long getItemId(int position) {
+        return position;
+    }
+
+    /**
+     * Overrides the locale used to display localized labels. Setting the locale to null will reset
+     * the Adapter to use the default locale for the labels.
+     */
+    public void setDisplayLocale(@NonNull Context context, @Nullable Locale locale) {
+        if (locale == null) {
+            mDisplayLocale = null;
+            mContextOverride = null;
+        } else if (!locale.equals(mDisplayLocale)) {
+            mDisplayLocale = locale;
+            final Configuration configOverride = new Configuration();
+            configOverride.setLocale(locale);
+            mContextOverride = context.createConfigurationContext(configOverride);
+        }
+    }
+
+    private void setTextTo(@NonNull TextView textView, int resId) {
+        if (mContextOverride == null) {
+            textView.setText(resId);
+        } else {
+            textView.setText(mContextOverride.getText(resId));
+            // If mContextOverride is not null, mDisplayLocale can't be null either.
+        }
+    }
+
+    @Override
+    public View getView(int position, View convertView, ViewGroup parent) {
+        if (convertView == null && mInflater == null) {
+            mInflater = LayoutInflater.from(parent.getContext());
+        }
+
+        int itemType = getItemViewType(position);
+        switch (itemType) {
+            case TYPE_HEADER_SUGGESTED: // intentional fallthrough
+            case TYPE_HEADER_ALL_OTHERS:
+                // Covers both null, and "reusing" a wrong kind of view
+                if (!(convertView instanceof TextView)) {
+                    convertView = mInflater.inflate(R.layout.language_picker_section_header,
+                            parent, false);
+                }
+                TextView textView = (TextView) convertView;
+                if (itemType == TYPE_HEADER_SUGGESTED) {
+                    setTextTo(textView, R.string.language_picker_section_suggested);
+                } else {
+                    if (mCountryMode) {
+                        setTextTo(textView, R.string.region_picker_section_all);
+                    } else {
+                        setTextTo(textView, R.string.language_picker_section_all);
+                    }
+                }
+                textView.setTextLocale(
+                        mDisplayLocale != null ? mDisplayLocale : Locale.getDefault());
+                break;
+            default:
+                // Covers both null, and "reusing" a wrong kind of view
+                if (!(convertView instanceof ViewGroup)) {
+                    convertView = mInflater.inflate(R.layout.language_picker_item, parent, false);
+                }
+
+                TextView text = (TextView) convertView.findViewById(R.id.locale);
+                LocaleStore.LocaleInfo item = (LocaleStore.LocaleInfo) getItem(position);
+                text.setText(item.getLabel(mCountryMode));
+                text.setTextLocale(item.getLocale());
+                text.setContentDescription(item.getContentDescription(mCountryMode));
+                if (mCountryMode) {
+                    int layoutDir = TextUtils.getLayoutDirectionFromLocale(item.getParent());
+                    //noinspection ResourceType
+                    convertView.setLayoutDirection(layoutDir);
+                    text.setTextDirection(layoutDir == View.LAYOUT_DIRECTION_RTL
+                            ? View.TEXT_DIRECTION_RTL
+                            : View.TEXT_DIRECTION_LTR);
+                }
+        }
+        return convertView;
+    }
+
+    private boolean showHeaders() {
+        // We don't want to show suggestions for locales with very few regions
+        // (e.g. Romanian, with 2 regions)
+        // So we put a (somewhat) arbitrary limit.
+        //
+        // The initial idea was to make that limit dependent on the screen height.
+        // But that would mean rotating the screen could make the suggestions disappear,
+        // as the number of countries that fits on the screen would be different in portrait
+        // and landscape mode.
+        if (mCountryMode && mLocaleOptions.size() < MIN_REGIONS_FOR_SUGGESTIONS) {
+            return false;
+        }
+        return mSuggestionCount != 0 && mSuggestionCount != mLocaleOptions.size();
+    }
+
+    /**
+     * Sorts the items in the adapter using a locale-aware comparator.
+     * @param comp The locale-aware comparator to use.
+     */
+    public void sort(LocaleHelper.LocaleInfoComparator comp) {
+        Collections.sort(mLocaleOptions, comp);
+    }
+
+    class FilterByNativeAndUiNames extends Filter {
+
+        @Override
+        protected FilterResults performFiltering(CharSequence prefix) {
+            FilterResults results = new FilterResults();
+
+            if (mOriginalLocaleOptions == null) {
+                mOriginalLocaleOptions = new ArrayList<>(mLocaleOptions);
+            }
+
+            ArrayList<LocaleStore.LocaleInfo> values;
+            values = new ArrayList<>(mOriginalLocaleOptions);
+            if (prefix == null || prefix.length() == 0) {
+                results.values = values;
+                results.count = values.size();
+            } else {
+                // TODO: decide if we should use the string's locale
+                Locale locale = Locale.getDefault();
+                String prefixString = LocaleHelper.normalizeForSearch(prefix.toString(), locale);
+
+                final int count = values.size();
+                final ArrayList<LocaleStore.LocaleInfo> newValues = new ArrayList<>();
+
+                for (int i = 0; i < count; i++) {
+                    final LocaleStore.LocaleInfo value = values.get(i);
+                    final String nameToCheck = LocaleHelper.normalizeForSearch(
+                            value.getFullNameInUiLanguage(), locale);
+                    final String nativeNameToCheck = LocaleHelper.normalizeForSearch(
+                            value.getFullNameNative(), locale);
+                    if (wordMatches(nativeNameToCheck, prefixString)
+                            || wordMatches(nameToCheck, prefixString)) {
+                        newValues.add(value);
+                    }
+                }
+
+                results.values = newValues;
+                results.count = newValues.size();
+            }
+
+            return results;
+        }
+
+        // TODO: decide if this is enough, or we want to use a BreakIterator...
+        boolean wordMatches(String valueText, String prefixString) {
+            // First match against the whole, non-split value
+            if (valueText.startsWith(prefixString)) {
+                return true;
+            }
+
+            final String[] words = valueText.split(" ");
+            // Start at index 0, in case valueText starts with space(s)
+            for (String word : words) {
+                if (word.startsWith(prefixString)) {
+                    return true;
+                }
+            }
+
+            return false;
+        }
+
+        @Override
+        protected void publishResults(CharSequence constraint, FilterResults results) {
+            mLocaleOptions = (ArrayList<LocaleStore.LocaleInfo>) results.values;
+
+            mSuggestionCount = 0;
+            for (LocaleStore.LocaleInfo li : mLocaleOptions) {
+                if (li.isSuggested()) {
+                    mSuggestionCount++;
+                }
+            }
+
+            if (results.count > 0) {
+                notifyDataSetChanged();
+            } else {
+                notifyDataSetInvalidated();
+            }
+        }
+    }
+
+    @Override
+    public Filter getFilter() {
+        return new FilterByNativeAndUiNames();
+    }
+}
diff --git a/tests/Android.mk b/tests/Android.mk
new file mode 100644
index 0000000..194ab27
--- /dev/null
+++ b/tests/Android.mk
@@ -0,0 +1,66 @@
+#############################################################
+# Build test package for locale picker lib.                 #
+#############################################################
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_PACKAGE_NAME := LocalePickerTest
+
+LOCAL_PRIVATE_PLATFORM_APIS := true
+LOCAL_PROGUARD_ENABLED := disabled
+
+LOCAL_STATIC_ANDROID_LIBRARIES += localepicker
+
+LOCAL_USE_AAPT2 := true
+
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_PACKAGE)
+
+#############################################################
+# LocalePicker Robolectric test target.                     #
+#############################################################
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := LocalePickerRoboTests
+LOCAL_MODULE_CLASS := JAVA_LIBRARIES
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+LOCAL_JAVA_RESOURCE_DIRS := config
+
+LOCAL_JAVA_LIBRARIES := \
+    robolectric_android-all-stub \
+    Robolectric_all-target \
+    mockito-robolectric-prebuilt \
+    truth-prebuilt
+
+LOCAL_INSTRUMENTATION_FOR := LocalePickerTest
+
+LOCAL_MODULE_TAGS := optional
+
+# Generate test_config.properties
+include external/robolectric-shadows/gen_test_config.mk
+
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
+#############################################################
+# LocalePicker runner target to run the previous target.    #
+#############################################################
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := RunLocalePickerRoboTests
+
+LOCAL_JAVA_LIBRARIES := \
+    LocalePickerRoboTests \
+    robolectric_android-all-stub \
+    Robolectric_all-target \
+    mockito-robolectric-prebuilt \
+    truth-prebuilt
+
+LOCAL_TEST_PACKAGE := LocalePickerTest
+
+LOCAL_INSTRUMENT_SOURCE_DIRS := $(LOCAL_PATH)/../src
+
+include external/robolectric-shadows/run_robotests.mk
diff --git a/tests/AndroidManifest.xml b/tests/AndroidManifest.xml
new file mode 100644
index 0000000..bc6f0b6
--- /dev/null
+++ b/tests/AndroidManifest.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    Copyright (C) 2018 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="com.android.localepicker.test">
+
+</manifest>
\ No newline at end of file
diff --git a/tests/config/robolectric.properties b/tests/config/robolectric.properties
new file mode 100644
index 0000000..4c863dc
--- /dev/null
+++ b/tests/config/robolectric.properties
@@ -0,0 +1,16 @@
+#
+# Copyright (C) 2018 Google Inc.
+#
+# 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.
+#
+sdk=NEWEST_SDK
diff --git a/tests/src/com/android/localepicker/LocaleHelperTest.java b/tests/src/com/android/localepicker/LocaleHelperTest.java
new file mode 100644
index 0000000..e4ddb42
--- /dev/null
+++ b/tests/src/com/android/localepicker/LocaleHelperTest.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2018 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
+ */
+
+package com.android.localepicker;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.android.localepicker.LocaleHelper.LocaleInfoComparator;
+import com.android.localepicker.LocaleStore.LocaleInfo;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Locale;
+
+@RunWith(RobolectricTestRunner.class)
+public class LocaleHelperTest {
+
+    @Test
+    public void toSentenceCase_shouldUpperCaseFirstLetter() {
+        String sentenceCase = LocaleHelper.toSentenceCase("hello Google", Locale.US);
+        assertThat(sentenceCase).isEqualTo("Hello Google");
+    }
+
+    @Test
+    public void normalizeForSearch_sameStrings_shouldBeEqualAfterNormalized() {
+        String lowerCase = LocaleHelper.normalizeForSearch("english", Locale.US);
+        String upperCase = LocaleHelper.normalizeForSearch("ENGLISH", Locale.US);
+        assertThat(lowerCase).isEqualTo(upperCase);
+    }
+
+    @Test
+    public void getDisplayName_shouldReturnLocaleDisplayName() {
+        String displayName =
+                LocaleHelper.getDisplayName(Locale.US, Locale.US, /* sentenceCase */ true);
+        assertThat(displayName).isEqualTo("English (United States)");
+    }
+
+    @Test
+    public void getDisplayName_withDifferentLocale_shouldReturnLocalizedDisplayName() {
+        String displayName =
+                LocaleHelper.getDisplayName(
+                        Locale.CANADA_FRENCH,
+                        Locale.US,
+                        /* sentenceCase */ true);
+        assertThat(displayName).isEqualTo("French (Canada)");
+    }
+
+    @Test
+    public void getDisplayCountry_shouldReturnLocalizedCountryName() {
+        String displayCountry = LocaleHelper.getDisplayCountry(Locale.GERMANY, Locale.GERMANY);
+        assertThat(displayCountry).isEqualTo("Deutschland");
+    }
+
+    @Test
+    public void localeInfoComparator_shouldSortLocales() {
+        LocaleInfo germany = LocaleStore.getLocaleInfo(Locale.GERMANY);
+        LocaleInfo unitedStates = LocaleStore.getLocaleInfo(Locale.US);
+        LocaleInfo japan = LocaleStore.getLocaleInfo(Locale.JAPAN);
+
+        ArrayList<LocaleInfo> list =
+                new ArrayList<>(Arrays.asList(germany, unitedStates, japan));
+        list.sort(new LocaleInfoComparator(Locale.US, /* countryMode */ false));
+        assertThat(list).containsExactly(germany, unitedStates, japan).inOrder();
+    }
+}
diff --git a/tests/src/com/android/localepicker/LocaleStoreTest.java b/tests/src/com/android/localepicker/LocaleStoreTest.java
new file mode 100644
index 0000000..ae406e7
--- /dev/null
+++ b/tests/src/com/android/localepicker/LocaleStoreTest.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2018 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
+ */
+
+package com.android.localepicker;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.robolectric.RuntimeEnvironment.application;
+import static org.robolectric.Shadows.shadowOf;
+
+import android.icu.util.ULocale;
+import android.telephony.TelephonyManager;
+
+import com.android.internal.app.LocalePicker;
+import com.android.localepicker.LocaleStore.LocaleInfo;
+import com.android.localepicker.LocaleStoreTest.ShadowICU;
+import com.android.localepicker.LocaleStoreTest.ShadowLocalePicker;
+
+import libcore.icu.ICU;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.annotation.Config;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+
+import java.util.Locale;
+
+@RunWith(RobolectricTestRunner.class)
+@Config(
+        shadows = {
+                ShadowLocalePicker.class,
+                ShadowICU.class,
+        })
+public class LocaleStoreTest {
+
+    @Before
+    public void setupTelephonyManager() {
+        TelephonyManager telephonyManager = application.getSystemService(TelephonyManager.class);
+        shadowOf(telephonyManager).setNetworkCountryIso("us");
+        shadowOf(telephonyManager).setSimCountryIso("us");
+    }
+
+    @Before
+    public void fillCache() {
+        LocaleStore.fillCache(application);
+    }
+
+    @Test
+    public void getLevel() {
+        LocaleInfo localeInfo = LocaleStore.getLocaleInfo(Locale.forLanguageTag("zh-Hant-HK"));
+        assertThat(localeInfo.getParent().toLanguageTag()).isEqualTo("zh-Hant");
+        assertThat(localeInfo.isTranslated()).named("is translated").isTrue();
+    }
+
+    @Implements(LocalePicker.class)
+    public static class ShadowLocalePicker {
+
+        @Implementation
+        public static String[] getSystemAssetLocales() {
+            return new String[] { "en-US", "zh-HK", "ja-JP", "zh-TW" };
+        }
+    }
+
+    @Implements(ICU.class)
+    public static class ShadowICU {
+
+        @Implementation
+        public static Locale addLikelySubtags(Locale locale) {
+            ULocale uLocale = ULocale.addLikelySubtags(ULocale.forLocale(locale));
+            return uLocale.toLocale();
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/src/com/android/localepicker/SuggestedLocaleAdapterTest.java b/tests/src/com/android/localepicker/SuggestedLocaleAdapterTest.java
new file mode 100644
index 0000000..2c735dd
--- /dev/null
+++ b/tests/src/com/android/localepicker/SuggestedLocaleAdapterTest.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright 2018 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
+ */
+
+package com.android.localepicker;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.android.localepicker.LocaleHelper.LocaleInfoComparator;
+import com.android.localepicker.LocaleStore.LocaleInfo;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+
+@RunWith(RobolectricTestRunner.class)
+public class SuggestedLocaleAdapterTest {
+
+    private HashSet<LocaleInfo> mLocaleOptions;
+    private HashSet<LocaleInfo> mEnglishCountryOptions;
+
+    @Before
+    public void setUp() {
+        mLocaleOptions = new HashSet<>();
+        mLocaleOptions.add(LocaleStore.getLocaleInfo(Locale.US));
+        mLocaleOptions.add(LocaleStore.getLocaleInfo(Locale.GERMANY));
+        mLocaleOptions.add(LocaleStore.getLocaleInfo(Locale.JAPAN));
+        LocaleInfo korea = LocaleStore.getLocaleInfo(Locale.KOREA);
+        korea.setTranslated(true);
+        korea.mSuggestionFlags = LocaleInfo.SUGGESTION_TYPE_SIM;
+        mLocaleOptions.add(korea);
+
+        mEnglishCountryOptions = new HashSet<>();
+        mEnglishCountryOptions.add(LocaleStore.getLocaleInfo(Locale.US));
+        mEnglishCountryOptions.add(LocaleStore.getLocaleInfo(Locale.UK));
+        mEnglishCountryOptions.add(LocaleStore.getLocaleInfo(Locale.CANADA));
+        mEnglishCountryOptions.add(LocaleStore.getLocaleInfo(Locale.forLanguageTag("en-IN")));
+        mEnglishCountryOptions.add(LocaleStore.getLocaleInfo(Locale.forLanguageTag("en-HK")));
+        mEnglishCountryOptions.add(LocaleStore.getLocaleInfo(Locale.forLanguageTag("en-SG")));
+        LocaleInfo australianEnglish = LocaleStore.getLocaleInfo(Locale.forLanguageTag("en-AU"));
+        australianEnglish.setTranslated(true);
+        australianEnglish.mSuggestionFlags = LocaleInfo.SUGGESTION_TYPE_SIM;
+        mEnglishCountryOptions.add(australianEnglish);
+    }
+
+    @Test
+    public void suggestedLocaleAdapter_notCountryMode_shouldDisplayLocalesSorted() {
+        SuggestedLocaleAdapter suggestedLocaleAdapter =
+                new SuggestedLocaleAdapter(mLocaleOptions, /* countryMode */ false);
+        suggestedLocaleAdapter.sort(new LocaleInfoComparator(Locale.US, /* countryMode */ false));
+
+        assertThat(getItemTypeList(suggestedLocaleAdapter))
+                .containsExactly(
+                        SuggestedLocaleAdapter.TYPE_HEADER_SUGGESTED,
+                        SuggestedLocaleAdapter.TYPE_LOCALE,
+                        SuggestedLocaleAdapter.TYPE_HEADER_ALL_OTHERS,
+                        SuggestedLocaleAdapter.TYPE_LOCALE,
+                        SuggestedLocaleAdapter.TYPE_LOCALE,
+                        SuggestedLocaleAdapter.TYPE_LOCALE)
+                .inOrder();
+        assertThat(getLocaleTagList(suggestedLocaleAdapter))
+                .containsExactly(
+                        null,
+                        "ko-KR",
+                        null,
+                        "de-DE",
+                        "en-US",
+                        "ja-JP")
+                .inOrder();
+    }
+
+    @Test
+    public void suggestedLocaleAdapter_countryMode_shouldDisplayCountriesSorted() {
+        SuggestedLocaleAdapter suggestedLocaleAdapter =
+                new SuggestedLocaleAdapter(mEnglishCountryOptions, /* countryMode */ true);
+        suggestedLocaleAdapter.sort(new LocaleInfoComparator(Locale.US, /* countryMode */ true));
+
+        assertThat(getItemTypeList(suggestedLocaleAdapter))
+                .containsExactly(
+                        SuggestedLocaleAdapter.TYPE_HEADER_SUGGESTED,
+                        SuggestedLocaleAdapter.TYPE_LOCALE,
+                        SuggestedLocaleAdapter.TYPE_HEADER_ALL_OTHERS,
+                        SuggestedLocaleAdapter.TYPE_LOCALE,
+                        SuggestedLocaleAdapter.TYPE_LOCALE,
+                        SuggestedLocaleAdapter.TYPE_LOCALE,
+                        SuggestedLocaleAdapter.TYPE_LOCALE,
+                        SuggestedLocaleAdapter.TYPE_LOCALE,
+                        SuggestedLocaleAdapter.TYPE_LOCALE)
+                .inOrder();
+        assertThat(getLocaleTagList(suggestedLocaleAdapter))
+                .containsExactly(
+                        null,
+                        "en-AU",
+                        null,
+                        "en-CA",
+                        "en-HK",
+                        "en-IN",
+                        "en-SG",
+                        "en-GB",
+                        "en-US")
+                .inOrder();
+    }
+
+    private static List<Integer> getItemTypeList(final SuggestedLocaleAdapter adapter) {
+        return IntStream.range(0, adapter.getCount())
+                .mapToObj(adapter::getItemViewType)
+                .collect(Collectors.toList());
+    }
+
+    private static List<String> getLocaleTagList(final SuggestedLocaleAdapter adapter) {
+        return IntStream.range(0, adapter.getCount())
+                .mapToObj(position -> {
+                    LocaleInfo localeInfo = adapter.getItem(position);
+                    if (localeInfo == null) {
+                        return null;
+                    }
+                    return localeInfo.getLocale().toLanguageTag();
+                })
+                .collect(Collectors.toList());
+    }
+}
