Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4fac7680 authored by Roozbeh Pournader's avatar Roozbeh Pournader Committed by Android (Google) Code Review
Browse files

Merge "Avoid matching system locales in locale negotiation"

parents 982dcf3e 1c686f2c
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -698,6 +698,18 @@ public final class AssetManager implements AutoCloseable {
     */
    public native final String[] getLocales();

    /**
     * Same as getLocales(), except that locales that are only provided by the system (i.e. those
     * present in framework-res.apk or its overlays) will not be listed.
     *
     * For example, if the "system" assets support English, French, and German, and the additional
     * assets support Cherokee and French, getLocales() would return
     * [Cherokee, English, French, German], while getNonSystemLocales() would return
     * [Cherokee, French].
     * {@hide}
     */
    public native final String[] getNonSystemLocales();

    /** {@hide} */
    public native final Configuration[] getSizeConfigurations();

+15 −1
Original line number Diff line number Diff line
@@ -1976,7 +1976,21 @@ public class Resources {

            if (setLocalesToDefault || mResolvedLocale == null
                    || (configChanges & Configuration.NATIVE_CONFIG_LOCALE) != 0) {
                mResolvedLocale = locales.getFirstMatch(mAssets.getLocales());
                if (locales.size() == 1) {
                    // This is an optimization to avoid the JNI call(s) when the result of
                    // getFirstMatch() does not depend on the supported locales.
                    mResolvedLocale = locales.getPrimary();
                } else {
                    String[] supportedLocales = mAssets.getNonSystemLocales();
                    if (LocaleList.isPseudoLocalesOnly(supportedLocales)) {
                        // We fallback to all locales (including system locales) if there was no
                        // locale specifically supported by the assets. This is to properly support
                        // apps that only rely on the shared system assets and don't need assets of
                        // their own.
                        supportedLocales = mAssets.getLocales();
                    }
                    mResolvedLocale = locales.getFirstMatch(supportedLocales);
                }
            }
            mAssets.setConfiguration(mConfiguration.mcc, mConfiguration.mnc,
                    adjustLanguageTag(mResolvedLocale.toLanguageTag()),
+40 −1
Original line number Diff line number Diff line
@@ -213,6 +213,20 @@ public final class LocaleList implements Parcelable {
        }
    }

    private static final String STRING_EN_XA = "en-XA";
    private static final String STRING_AR_XB = "ar-XB";
    private static final Locale LOCALE_EN_XA = new Locale("en", "XA");
    private static final Locale LOCALE_AR_XB = new Locale("ar", "XB");
    private static final int NUM_PSEUDO_LOCALES = 2;

    private static boolean isPseudoLocale(String locale) {
        return STRING_EN_XA.equals(locale) || STRING_AR_XB.equals(locale);
    }

    private static boolean isPseudoLocale(Locale locale) {
        return LOCALE_EN_XA.equals(locale) || LOCALE_AR_XB.equals(locale);
    }

    private static int matchScore(Locale supported, Locale desired) {
        if (supported.equals(desired)) {
            return 1;  // return early so we don't do unnecessary computation
@@ -220,6 +234,11 @@ public final class LocaleList implements Parcelable {
        if (!supported.getLanguage().equals(desired.getLanguage())) {
            return 0;
        }
        if (isPseudoLocale(supported) || isPseudoLocale(desired)) {
            // The locales are not the same, but the languages are the same, and one of the locales
            // is a pseudo-locale. So this is not a match.
            return 0;
        }
        // There is no match if the two locales use different scripts. This will most imporantly
        // take care of traditional vs simplified Chinese.
        final String supportedScr = getLikelyScript(supported);
@@ -241,7 +260,6 @@ public final class LocaleList implements Parcelable {
        if (mList.length == 0) {  // empty locale list
            return null;
        }
        // TODO: Figure out what to if en-XA or ar-XB are in the locale list
        int bestIndex = Integer.MAX_VALUE;
        for (String tag : supportedLocales) {
            final Locale supportedLocale = Locale.forLanguageTag(tag);
@@ -265,6 +283,27 @@ public final class LocaleList implements Parcelable {
        }
    }

    /**
     * Returns true if the array of locale tags only contains empty locales and pseudolocales.
     * Assumes that there is no repetition in the input.
     * {@hide}
     */
    public static boolean isPseudoLocalesOnly(String[] supportedLocales) {
        if (supportedLocales.length > NUM_PSEUDO_LOCALES + 1) {
            // This is for optimization. Since there's no repetition in the input, if we have more
            // than the number of pseudo-locales plus one for the empty string, it's guaranteed
            // that we have some meaninful locale in the list, so the list is not "practically
            // empty".
            return false;
        }
        for (String locale : supportedLocales) {
            if (!locale.isEmpty() && !isPseudoLocale(locale)) {
                return false;
            }
        }
        return true;
    }

    private final static Object sLock = new Object();

    @GuardedBy("sLock")
+14 −2
Original line number Diff line number Diff line
@@ -578,7 +578,7 @@ static jboolean android_content_AssetManager_isUpToDate(JNIEnv* env, jobject cla
    return am->isUpToDate() ? JNI_TRUE : JNI_FALSE;
}

static jobjectArray android_content_AssetManager_getLocales(JNIEnv* env, jobject clazz)
static jobjectArray getLocales(JNIEnv* env, jobject clazz, bool includeSystemLocales)
{
    Vector<String8> locales;

@@ -587,7 +587,7 @@ static jobjectArray android_content_AssetManager_getLocales(JNIEnv* env, jobject
        return NULL;
    }

    am->getLocales(&locales);
    am->getLocales(&locales, includeSystemLocales);

    const int N = locales.size();

@@ -608,6 +608,16 @@ static jobjectArray android_content_AssetManager_getLocales(JNIEnv* env, jobject
    return result;
}

static jobjectArray android_content_AssetManager_getLocales(JNIEnv* env, jobject clazz)
{
    return getLocales(env, clazz, true /* include system locales */);
}

static jobjectArray android_content_AssetManager_getNonSystemLocales(JNIEnv* env, jobject clazz)
{
    return getLocales(env, clazz, false /* don't include system locales */);
}

static jobject constructConfigurationObject(JNIEnv* env, const ResTable_config& config) {
    jobject result = env->NewObject(gConfigurationOffsets.classObject,
            gConfigurationOffsets.constructor);
@@ -2154,6 +2164,8 @@ static const JNINativeMethod gAssetManagerMethods[] = {
    // Resources.
    { "getLocales",      "()[Ljava/lang/String;",
        (void*) android_content_AssetManager_getLocales },
    { "getNonSystemLocales", "()[Ljava/lang/String;",
        (void*) android_content_AssetManager_getNonSystemLocales },
    { "getSizeConfigurations", "()[Landroid/content/res/Configuration;",
        (void*) android_content_AssetManager_getSizeConfigurations },
    { "setConfiguration", "!(IILjava/lang/String;IIIIIIIIIIIIII)V",
+10 −7
Original line number Diff line number Diff line
@@ -100,7 +100,8 @@ public:
     * then on success, *cookie is set to the value corresponding to the
     * newly-added asset source.
     */
    bool addAssetPath(const String8& path, int32_t* cookie, bool appAsLib=false);
    bool addAssetPath(const String8& path, int32_t* cookie,
        bool appAsLib=false, bool isSystemAsset=false);
    bool addOverlayPath(const String8& path, int32_t* cookie);

    /*
@@ -225,7 +226,7 @@ public:
    /**
     * Get the known locales for this asset manager object.
     */
    void getLocales(Vector<String8>* locales) const;
    void getLocales(Vector<String8>* locales, bool includeSystemLocales=true) const;

    /**
     * Generate idmap data to translate resources IDs between a package and a
@@ -237,11 +238,13 @@ public:
private:
    struct asset_path
    {
        asset_path() : path(""), type(kFileTypeRegular), idmap(""), isSystemOverlay(false) {}
        asset_path() : path(""), type(kFileTypeRegular), idmap(""),
                       isSystemOverlay(false), isSystemAsset(false) {}
        String8 path;
        FileType type;
        String8 idmap;
        bool isSystemOverlay;
        bool isSystemAsset;
    };

    Asset* openInPathLocked(const char* fileName, AccessMode mode,
Loading