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

Commit c5344a35 authored by Jeremy Meyer's avatar Jeremy Meyer Committed by Android (Google) Code Review
Browse files

Merge "Make resource multilocale depend on default attribute" into main

parents 19427bde 2ae6ed59
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -668,6 +668,7 @@ package android {
    field public static final int debuggable = 16842767; // 0x101000f
    field public static final int defaultFocusHighlightEnabled = 16844130; // 0x1010562
    field public static final int defaultHeight = 16844021; // 0x10104f5
    field @FlaggedApi("android.content.res.default_locale") public static final int defaultLocale;
    field public static final int defaultToDeviceProtectedStorage = 16844036; // 0x1010504
    field public static final int defaultValue = 16843245; // 0x10101ed
    field public static final int defaultWidth = 16844020; // 0x10104f4
@@ -6188,6 +6189,7 @@ package android.app {
    ctor public LocaleConfig(@NonNull android.os.LocaleList);
    method public int describeContents();
    method @NonNull public static android.app.LocaleConfig fromContextIgnoringOverride(@NonNull android.content.Context);
    method @FlaggedApi("android.content.res.default_locale") @Nullable public java.util.Locale getDefaultLocale();
    method public int getStatus();
    method @Nullable public android.os.LocaleList getSupportedLocales();
    method public void writeToParcel(@NonNull android.os.Parcel, int);
+4 −6
Original line number Diff line number Diff line
@@ -3483,12 +3483,10 @@ class ContextImpl extends Context {

        // only do this if the user already has more than one preferred locale
        if (r.getConfiguration().getLocales().size() > 1) {
            LocaleConfig lc = LocaleConfig.fromContextIgnoringOverride(this);
            mResourcesManager.setLocaleList(lc != null
                    && lc.getSupportedLocales() != null
                    && !lc.getSupportedLocales().isEmpty()
                    ? lc.getSupportedLocales()
                    : null);
            LocaleConfig lc = getUserId() < 0
                    ? LocaleConfig.fromContextIgnoringOverride(this)
                    : new LocaleConfig(this);
            mResourcesManager.setLocaleConfig(lc);
        }
    }

+37 −3
Original line number Diff line number Diff line
@@ -16,9 +16,11 @@

package android.app;

import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
@@ -30,6 +32,7 @@ import android.util.AttributeSet;
import android.util.Slog;
import android.util.Xml;

import com.android.internal.R;
import com.android.internal.util.XmlUtils;

import org.xmlpull.v1.XmlPullParserException;
@@ -39,7 +42,7 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;
@@ -66,6 +69,8 @@ public class LocaleConfig implements Parcelable {
    public static final String TAG_LOCALE_CONFIG = "locale-config";
    public static final String TAG_LOCALE = "locale";
    private LocaleList mLocales;

    private Locale mDefaultLocale;
    private int mStatus = STATUS_NOT_SPECIFIED;

    /**
@@ -193,8 +198,17 @@ public class LocaleConfig implements Parcelable {
        XmlUtils.beginDocument(parser, TAG_LOCALE_CONFIG);
        int outerDepth = parser.getDepth();
        AttributeSet attrs = Xml.asAttributeSet(parser);
        // LinkedHashSet to preserve insertion order
        Set<String> localeNames = new LinkedHashSet<>();

        String defaultLocale = null;
        if (android.content.res.Flags.defaultLocale()) {
            TypedArray att = res.obtainAttributes(
                    attrs, com.android.internal.R.styleable.LocaleConfig);
            defaultLocale = att.getString(
                    R.styleable.LocaleConfig_defaultLocale);
            att.recycle();
        }

        Set<String> localeNames = new HashSet<>();
        while (XmlUtils.nextElementWithin(parser, outerDepth)) {
            if (TAG_LOCALE.equals(parser.getName())) {
                final TypedArray attributes = res.obtainAttributes(
@@ -209,6 +223,15 @@ public class LocaleConfig implements Parcelable {
        }
        mStatus = STATUS_SUCCESS;
        mLocales = LocaleList.forLanguageTags(String.join(",", localeNames));
        if (defaultLocale != null) {
            if (localeNames.contains(defaultLocale)) {
                mDefaultLocale = Locale.forLanguageTag(defaultLocale);
            } else {
                Slog.w(TAG, "Default locale specified that is not contained in the list: "
                        + defaultLocale);
                mStatus = STATUS_PARSING_FAILED;
            }
        }
    }

    /**
@@ -223,6 +246,17 @@ public class LocaleConfig implements Parcelable {
        return mLocales;
    }

    /**
     * Returns the default locale if specified, otherwise null
     *
     * @return The default Locale or null
     */
    @SuppressLint("UseIcu")
    @FlaggedApi(android.content.res.Flags.FLAG_DEFAULT_LOCALE)
    public @Nullable Locale getDefaultLocale() {
        return mDefaultLocale;
    }

    /**
     * Get the status of reading the resource file where the LocaleConfig was stored.
     *
+10 −9
Original line number Diff line number Diff line
@@ -120,9 +120,9 @@ public class ResourcesManager {
    private final ReferenceQueue<Resources> mResourcesReferencesQueue = new ReferenceQueue<>();

    /**
     * The list of locales the app declares it supports.
     * The localeConfig of the app.
     */
    private LocaleList mLocaleList = LocaleList.getEmptyLocaleList();
    private LocaleConfig mLocaleConfig = new LocaleConfig(LocaleList.getEmptyLocaleList());

    private static class ApkKey {
        public final String path;
@@ -1612,18 +1612,19 @@ public class ResourcesManager {
    }

    /**
     * Returns the LocaleList current set
     * Returns the LocaleConfig current set
     */
    public LocaleList getLocaleList() {
        return mLocaleList;
    public LocaleConfig getLocaleConfig() {
        return mLocaleConfig;
    }

    /**
     * Sets the LocaleList of app's supported locales
     * Sets the LocaleConfig of the app
     */
    public void setLocaleList(LocaleList localeList) {
        if ((localeList != null) && !localeList.isEmpty()) {
            mLocaleList = localeList;
    public void setLocaleConfig(LocaleConfig localeConfig) {
        if ((localeConfig != null) && (localeConfig.getSupportedLocales() != null)
                && !localeConfig.getSupportedLocales().isEmpty()) {
            mLocaleConfig = localeConfig;
        }
    }

+44 −21
Original line number Diff line number Diff line
@@ -27,6 +27,8 @@ import android.annotation.PluralsRes;
import android.annotation.RawRes;
import android.annotation.StyleRes;
import android.annotation.StyleableRes;
import android.app.LocaleConfig;
import android.app.ResourcesManager;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.pm.ActivityInfo;
import android.content.pm.ActivityInfo.Config;
@@ -426,8 +428,21 @@ public class ResourcesImpl {

                String[] selectedLocales = null;
                String defaultLocale = null;
                LocaleConfig lc = ResourcesManager.getInstance().getLocaleConfig();
                if ((configChanges & ActivityInfo.CONFIG_LOCALE) != 0) {
                    if (locales.size() > 1) {
                        if (Flags.defaultLocale() && (lc.getDefaultLocale() != null)) {
                            Locale[] intersection =
                                    locales.getIntersection(lc.getSupportedLocales());
                            mConfiguration.setLocales(new LocaleList(intersection));
                            selectedLocales = new String[intersection.length];
                            for (int i = 0; i < intersection.length; i++) {
                                selectedLocales[i] =
                                        adjustLanguageTag(intersection[i].toLanguageTag());
                            }
                            defaultLocale =
                                    adjustLanguageTag(lc.getDefaultLocale().toLanguageTag());
                        } else {
                            String[] availableLocales;
                            // The LocaleList has changed. We must query the AssetManager's
                            // available Locales and figure out the best matching Locale in the new
@@ -455,10 +470,18 @@ public class ResourcesImpl {
                            }
                        }
                    }
                }
                if (selectedLocales == null) {
                    if (Flags.defaultLocale() && (lc.getDefaultLocale() != null)) {
                        selectedLocales = new String[locales.size()];
                        for (int i = 0; i < locales.size(); i++) {
                            selectedLocales[i] = adjustLanguageTag(locales.get(i).toLanguageTag());
                        }
                    } else {
                        selectedLocales = new String[]{
                                adjustLanguageTag(locales.get(0).toLanguageTag())};
                    }
                }

                if (mConfiguration.densityDpi != Configuration.DENSITY_DPI_UNDEFINED) {
                    mMetrics.densityDpi = mConfiguration.densityDpi;
Loading