Loading core/api/current.txt +2 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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); core/java/android/app/ContextImpl.java +4 −6 Original line number Diff line number Diff line Loading @@ -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); } } Loading core/java/android/app/LocaleConfig.java +37 −3 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading @@ -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; /** Loading Loading @@ -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( Loading @@ -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; } } } /** Loading @@ -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. * Loading core/java/android/app/ResourcesManager.java +10 −9 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; } } Loading core/java/android/content/res/ResourcesImpl.java +44 −21 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 Loading Loading @@ -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 Loading
core/api/current.txt +2 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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);
core/java/android/app/ContextImpl.java +4 −6 Original line number Diff line number Diff line Loading @@ -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); } } Loading
core/java/android/app/LocaleConfig.java +37 −3 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading @@ -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; /** Loading Loading @@ -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( Loading @@ -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; } } } /** Loading @@ -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. * Loading
core/java/android/app/ResourcesManager.java +10 −9 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; } } Loading
core/java/android/content/res/ResourcesImpl.java +44 −21 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 Loading Loading @@ -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