Loading core/api/current.txt +12 −0 Original line number Diff line number Diff line Loading @@ -972,6 +972,7 @@ package android { field public static final int listSeparatorTextViewStyle = 16843272; // 0x1010208 field public static final int listViewStyle = 16842868; // 0x1010074 field public static final int listViewWhiteStyle = 16842869; // 0x1010075 field public static final int localeConfig; field public static final int lockTaskMode = 16844013; // 0x10104ed field public static final int logo = 16843454; // 0x10102be field public static final int logoDescription = 16844009; // 0x10104e9 Loading Loading @@ -5697,6 +5698,17 @@ package android.app { method @Deprecated public android.view.Window startActivity(String, android.content.Intent); } public class LocaleConfig { ctor public LocaleConfig(@NonNull android.content.Context); method public int getStatus(); method @Nullable public android.os.LocaleList getSupportedLocales(); field public static final int STATUS_NOT_SPECIFIED = 1; // 0x1 field public static final int STATUS_PARSING_FAILED = 2; // 0x2 field public static final int STATUS_SUCCESS = 0; // 0x0 field public static final String TAG_LOCALE = "locale"; field public static final String TAG_LOCALE_CONFIG = "locale-config"; } public class LocaleManager { method @NonNull public android.os.LocaleList getApplicationLocales(); method public void setApplicationLocales(@NonNull android.os.LocaleList); core/java/android/app/LocaleConfig.java 0 → 100644 +166 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 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 android.app; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.res.Resources; import android.content.res.TypedArray; import android.content.res.XmlResourceParser; import android.os.LocaleList; import android.util.AttributeSet; import android.util.Slog; import android.util.Xml; import com.android.internal.util.XmlUtils; import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.HashSet; import java.util.Set; /** * The LocaleConfig of an application. * Defined in an XML resource file with an {@code <locale-config>} element and * referenced in the manifest via {@code android:localeConfig} on * {@code <application>}. * * For more information, see TODO(b/214154050): add link to guide * * @attr ref android.R.styleable#LocaleConfig_Locale_name * @attr ref android.R.styleable#AndroidManifestApplication_localeConfig */ public class LocaleConfig { private static final String TAG = "LocaleConfig"; public static final String TAG_LOCALE_CONFIG = "locale-config"; public static final String TAG_LOCALE = "locale"; private LocaleList mLocales; private int mStatus; /** * succeeded reading the LocaleConfig structure stored in an XML file. */ public static final int STATUS_SUCCESS = 0; /** * No android:localeConfig tag on <application>. */ public static final int STATUS_NOT_SPECIFIED = 1; /** * Malformed input in the XML file where the LocaleConfig was stored. */ public static final int STATUS_PARSING_FAILED = 2; /** @hide */ @IntDef(prefix = { "STATUS_" }, value = { STATUS_SUCCESS, STATUS_NOT_SPECIFIED, STATUS_PARSING_FAILED }) @Retention(RetentionPolicy.SOURCE) public @interface Status{} /** * Returns the LocaleConfig for the provided application context * * @param context the context of the application * * @see Context#createPackageContext(String, int). */ public LocaleConfig(@NonNull Context context) { int resId = 0; Resources res = context.getResources(); try { //Get the resource id resId = new ApplicationInfo(context.getApplicationInfo()).getLocaleConfigRes(); //Get the parser to read XML data XmlResourceParser parser = res.getXml(resId); parseLocaleConfig(parser, res); } catch (Resources.NotFoundException e) { Slog.w(TAG, "The resource file pointed to by the given resource ID isn't found.", e); mStatus = STATUS_NOT_SPECIFIED; } catch (XmlPullParserException | IOException e) { Slog.w(TAG, "Failed to parse XML configuration from " + res.getResourceEntryName(resId), e); mStatus = STATUS_PARSING_FAILED; } } /** * Parse the XML content and get the locales supported by the application */ private void parseLocaleConfig(XmlResourceParser parser, Resources res) throws IOException, XmlPullParserException { XmlUtils.beginDocument(parser, TAG_LOCALE_CONFIG); int outerDepth = parser.getDepth(); AttributeSet attrs = Xml.asAttributeSet(parser); Set<String> localeNames = new HashSet<String>(); while (XmlUtils.nextElementWithin(parser, outerDepth)) { if (TAG_LOCALE.equals(parser.getName())) { final TypedArray attributes = res.obtainAttributes( attrs, com.android.internal.R.styleable.LocaleConfig_Locale); String nameAttr = attributes.getString( com.android.internal.R.styleable.LocaleConfig_Locale_name); localeNames.add(nameAttr); attributes.recycle(); } else { XmlUtils.skipCurrentTag(parser); } } mStatus = STATUS_SUCCESS; mLocales = LocaleList.forLanguageTags(String.join(",", localeNames)); } /** * Returns the locales supported by the specified application. * * <p><b>Note:</b> The locale format should follow the * <a href="https://www.rfc-editor.org/rfc/bcp/bcp47.txt">IETF BCP47 regular expression</a> * * @return the {@link LocaleList} */ public @Nullable LocaleList getSupportedLocales() { return mLocales; } /** * Get the status of reading the resource file where the LocaleConfig was stored. * * <p>Distinguish "the application didn't provide the resource file" from "the application * provided malformed input" if {@link #getSupportedLocales()} returns {@code null}. * * @return {@code STATUS_SUCCESS} if the LocaleConfig structure existed in an XML file was * successfully read, or {@code STATUS_NOT_SPECIFIED} if no android:localeConfig tag on * <application> pointing to an XML file that stores the LocaleConfig, or * {@code STATUS_PARSING_FAILED} if the application provided malformed input for the * LocaleConfig structure. * * @see #STATUS_SUCCESS * @see #STATUS_NOT_SPECIFIED * @see #STATUS_PARSING_FAILED * */ public @Status int getStatus() { return mStatus; } } core/java/android/content/pm/ApplicationInfo.java +24 −0 Original line number Diff line number Diff line Loading @@ -1543,6 +1543,11 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { @Nullable private ArrayMap<String, String> mAppClassNamesByProcess; /** * Resource file providing the application's locales configuration. */ private int localeConfigRes; public void dump(Printer pw, String prefix) { dump(pw, prefix, DUMP_FLAG_ALL); } Loading Loading @@ -1660,6 +1665,10 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { pw.println(prefix + "requestRawExternalStorageAccess=" + requestRawExternalStorageAccess); } if (localeConfigRes != 0) { pw.println(prefix + "localeConfigRes=0x" + Integer.toHexString(localeConfigRes)); } } pw.println(prefix + "createTimestamp=" + createTimestamp); super.dumpBack(pw, prefix); Loading Loading @@ -1891,6 +1900,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { memtagMode = orig.memtagMode; nativeHeapZeroInitialized = orig.nativeHeapZeroInitialized; requestRawExternalStorageAccess = orig.requestRawExternalStorageAccess; localeConfigRes = orig.localeConfigRes; createTimestamp = System.currentTimeMillis(); } Loading Loading @@ -1993,6 +2003,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { dest.writeString(mAppClassNamesByProcess.valueAt(i)); } } dest.writeInt(localeConfigRes); } public static final @android.annotation.NonNull Parcelable.Creator<ApplicationInfo> CREATOR Loading Loading @@ -2088,6 +2099,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { mAppClassNamesByProcess.put(source.readString(), source.readString()); } } localeConfigRes = source.readInt(); } /** Loading Loading @@ -2631,4 +2643,16 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { } return className; } /** @hide */ public void setLocaleConfigRes(int value) { localeConfigRes = value; } /** * Return the resource id pointing to the resource file that provides the application's locales * configuration. * * @hide */ public int getLocaleConfigRes() { return localeConfigRes; } } core/java/android/content/pm/parsing/ParsingPackage.java +2 −0 Original line number Diff line number Diff line Loading @@ -375,6 +375,8 @@ public interface ParsingPackage extends ParsingPackageRead { ParsingPackage setResetEnabledSettingsOnAppDataCleared( boolean resetEnabledSettingsOnAppDataCleared); ParsingPackage setLocaleConfigRes(int localeConfigRes); // TODO(b/135203078): This class no longer has access to ParsedPackage, find a replacement // for moving to the next step @CallSuper Loading core/java/android/content/pm/parsing/ParsingPackageImpl.java +16 −0 Original line number Diff line number Diff line Loading @@ -559,6 +559,8 @@ public class ParsingPackageImpl implements ParsingPackage, ParsingPackageHidden, private UUID mStorageUuid; private long mLongVersionCode; private int mLocaleConfigRes; @VisibleForTesting public ParsingPackageImpl(@NonNull String packageName, @NonNull String baseApkPath, @NonNull String path, @Nullable TypedArray manifestArray) { Loading Loading @@ -1136,6 +1138,7 @@ public class ParsingPackageImpl implements ParsingPackage, ParsingPackageHidden, appInfo.setSplitResourcePaths(splitCodePaths); appInfo.setVersionCode(mLongVersionCode); appInfo.setAppClassNamesByProcess(buildAppClassNamesByProcess()); appInfo.setLocaleConfigRes(mLocaleConfigRes); return appInfo; } Loading Loading @@ -1314,6 +1317,7 @@ public class ParsingPackageImpl implements ParsingPackage, ParsingPackageHidden, dest.writeInt(this.memtagMode); dest.writeInt(this.nativeHeapZeroInitialized); sForBoolean.parcel(this.requestRawExternalStorageAccess, dest, flags); dest.writeInt(this.mLocaleConfigRes); } public ParsingPackageImpl(Parcel in) { Loading Loading @@ -1461,6 +1465,7 @@ public class ParsingPackageImpl implements ParsingPackage, ParsingPackageHidden, this.memtagMode = in.readInt(); this.nativeHeapZeroInitialized = in.readInt(); this.requestRawExternalStorageAccess = sForBoolean.unparcel(in); this.mLocaleConfigRes = in.readInt(); assignDerivedFields(); } Loading Loading @@ -2279,6 +2284,11 @@ public class ParsingPackageImpl implements ParsingPackage, ParsingPackageHidden, return nativeHeapZeroInitialized; } @Override public int getLocaleConfigRes() { return mLocaleConfigRes; } @Nullable @Override public Boolean hasRequestRawExternalStorageAccess() { Loading Loading @@ -2936,4 +2946,10 @@ public class ParsingPackageImpl implements ParsingPackage, ParsingPackageHidden, resetEnabledSettingsOnAppDataCleared); return this; } @Override public ParsingPackageImpl setLocaleConfigRes(int value) { mLocaleConfigRes = value; return this; } } Loading
core/api/current.txt +12 −0 Original line number Diff line number Diff line Loading @@ -972,6 +972,7 @@ package android { field public static final int listSeparatorTextViewStyle = 16843272; // 0x1010208 field public static final int listViewStyle = 16842868; // 0x1010074 field public static final int listViewWhiteStyle = 16842869; // 0x1010075 field public static final int localeConfig; field public static final int lockTaskMode = 16844013; // 0x10104ed field public static final int logo = 16843454; // 0x10102be field public static final int logoDescription = 16844009; // 0x10104e9 Loading Loading @@ -5697,6 +5698,17 @@ package android.app { method @Deprecated public android.view.Window startActivity(String, android.content.Intent); } public class LocaleConfig { ctor public LocaleConfig(@NonNull android.content.Context); method public int getStatus(); method @Nullable public android.os.LocaleList getSupportedLocales(); field public static final int STATUS_NOT_SPECIFIED = 1; // 0x1 field public static final int STATUS_PARSING_FAILED = 2; // 0x2 field public static final int STATUS_SUCCESS = 0; // 0x0 field public static final String TAG_LOCALE = "locale"; field public static final String TAG_LOCALE_CONFIG = "locale-config"; } public class LocaleManager { method @NonNull public android.os.LocaleList getApplicationLocales(); method public void setApplicationLocales(@NonNull android.os.LocaleList);
core/java/android/app/LocaleConfig.java 0 → 100644 +166 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 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 android.app; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.res.Resources; import android.content.res.TypedArray; import android.content.res.XmlResourceParser; import android.os.LocaleList; import android.util.AttributeSet; import android.util.Slog; import android.util.Xml; import com.android.internal.util.XmlUtils; import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.HashSet; import java.util.Set; /** * The LocaleConfig of an application. * Defined in an XML resource file with an {@code <locale-config>} element and * referenced in the manifest via {@code android:localeConfig} on * {@code <application>}. * * For more information, see TODO(b/214154050): add link to guide * * @attr ref android.R.styleable#LocaleConfig_Locale_name * @attr ref android.R.styleable#AndroidManifestApplication_localeConfig */ public class LocaleConfig { private static final String TAG = "LocaleConfig"; public static final String TAG_LOCALE_CONFIG = "locale-config"; public static final String TAG_LOCALE = "locale"; private LocaleList mLocales; private int mStatus; /** * succeeded reading the LocaleConfig structure stored in an XML file. */ public static final int STATUS_SUCCESS = 0; /** * No android:localeConfig tag on <application>. */ public static final int STATUS_NOT_SPECIFIED = 1; /** * Malformed input in the XML file where the LocaleConfig was stored. */ public static final int STATUS_PARSING_FAILED = 2; /** @hide */ @IntDef(prefix = { "STATUS_" }, value = { STATUS_SUCCESS, STATUS_NOT_SPECIFIED, STATUS_PARSING_FAILED }) @Retention(RetentionPolicy.SOURCE) public @interface Status{} /** * Returns the LocaleConfig for the provided application context * * @param context the context of the application * * @see Context#createPackageContext(String, int). */ public LocaleConfig(@NonNull Context context) { int resId = 0; Resources res = context.getResources(); try { //Get the resource id resId = new ApplicationInfo(context.getApplicationInfo()).getLocaleConfigRes(); //Get the parser to read XML data XmlResourceParser parser = res.getXml(resId); parseLocaleConfig(parser, res); } catch (Resources.NotFoundException e) { Slog.w(TAG, "The resource file pointed to by the given resource ID isn't found.", e); mStatus = STATUS_NOT_SPECIFIED; } catch (XmlPullParserException | IOException e) { Slog.w(TAG, "Failed to parse XML configuration from " + res.getResourceEntryName(resId), e); mStatus = STATUS_PARSING_FAILED; } } /** * Parse the XML content and get the locales supported by the application */ private void parseLocaleConfig(XmlResourceParser parser, Resources res) throws IOException, XmlPullParserException { XmlUtils.beginDocument(parser, TAG_LOCALE_CONFIG); int outerDepth = parser.getDepth(); AttributeSet attrs = Xml.asAttributeSet(parser); Set<String> localeNames = new HashSet<String>(); while (XmlUtils.nextElementWithin(parser, outerDepth)) { if (TAG_LOCALE.equals(parser.getName())) { final TypedArray attributes = res.obtainAttributes( attrs, com.android.internal.R.styleable.LocaleConfig_Locale); String nameAttr = attributes.getString( com.android.internal.R.styleable.LocaleConfig_Locale_name); localeNames.add(nameAttr); attributes.recycle(); } else { XmlUtils.skipCurrentTag(parser); } } mStatus = STATUS_SUCCESS; mLocales = LocaleList.forLanguageTags(String.join(",", localeNames)); } /** * Returns the locales supported by the specified application. * * <p><b>Note:</b> The locale format should follow the * <a href="https://www.rfc-editor.org/rfc/bcp/bcp47.txt">IETF BCP47 regular expression</a> * * @return the {@link LocaleList} */ public @Nullable LocaleList getSupportedLocales() { return mLocales; } /** * Get the status of reading the resource file where the LocaleConfig was stored. * * <p>Distinguish "the application didn't provide the resource file" from "the application * provided malformed input" if {@link #getSupportedLocales()} returns {@code null}. * * @return {@code STATUS_SUCCESS} if the LocaleConfig structure existed in an XML file was * successfully read, or {@code STATUS_NOT_SPECIFIED} if no android:localeConfig tag on * <application> pointing to an XML file that stores the LocaleConfig, or * {@code STATUS_PARSING_FAILED} if the application provided malformed input for the * LocaleConfig structure. * * @see #STATUS_SUCCESS * @see #STATUS_NOT_SPECIFIED * @see #STATUS_PARSING_FAILED * */ public @Status int getStatus() { return mStatus; } }
core/java/android/content/pm/ApplicationInfo.java +24 −0 Original line number Diff line number Diff line Loading @@ -1543,6 +1543,11 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { @Nullable private ArrayMap<String, String> mAppClassNamesByProcess; /** * Resource file providing the application's locales configuration. */ private int localeConfigRes; public void dump(Printer pw, String prefix) { dump(pw, prefix, DUMP_FLAG_ALL); } Loading Loading @@ -1660,6 +1665,10 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { pw.println(prefix + "requestRawExternalStorageAccess=" + requestRawExternalStorageAccess); } if (localeConfigRes != 0) { pw.println(prefix + "localeConfigRes=0x" + Integer.toHexString(localeConfigRes)); } } pw.println(prefix + "createTimestamp=" + createTimestamp); super.dumpBack(pw, prefix); Loading Loading @@ -1891,6 +1900,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { memtagMode = orig.memtagMode; nativeHeapZeroInitialized = orig.nativeHeapZeroInitialized; requestRawExternalStorageAccess = orig.requestRawExternalStorageAccess; localeConfigRes = orig.localeConfigRes; createTimestamp = System.currentTimeMillis(); } Loading Loading @@ -1993,6 +2003,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { dest.writeString(mAppClassNamesByProcess.valueAt(i)); } } dest.writeInt(localeConfigRes); } public static final @android.annotation.NonNull Parcelable.Creator<ApplicationInfo> CREATOR Loading Loading @@ -2088,6 +2099,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { mAppClassNamesByProcess.put(source.readString(), source.readString()); } } localeConfigRes = source.readInt(); } /** Loading Loading @@ -2631,4 +2643,16 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { } return className; } /** @hide */ public void setLocaleConfigRes(int value) { localeConfigRes = value; } /** * Return the resource id pointing to the resource file that provides the application's locales * configuration. * * @hide */ public int getLocaleConfigRes() { return localeConfigRes; } }
core/java/android/content/pm/parsing/ParsingPackage.java +2 −0 Original line number Diff line number Diff line Loading @@ -375,6 +375,8 @@ public interface ParsingPackage extends ParsingPackageRead { ParsingPackage setResetEnabledSettingsOnAppDataCleared( boolean resetEnabledSettingsOnAppDataCleared); ParsingPackage setLocaleConfigRes(int localeConfigRes); // TODO(b/135203078): This class no longer has access to ParsedPackage, find a replacement // for moving to the next step @CallSuper Loading
core/java/android/content/pm/parsing/ParsingPackageImpl.java +16 −0 Original line number Diff line number Diff line Loading @@ -559,6 +559,8 @@ public class ParsingPackageImpl implements ParsingPackage, ParsingPackageHidden, private UUID mStorageUuid; private long mLongVersionCode; private int mLocaleConfigRes; @VisibleForTesting public ParsingPackageImpl(@NonNull String packageName, @NonNull String baseApkPath, @NonNull String path, @Nullable TypedArray manifestArray) { Loading Loading @@ -1136,6 +1138,7 @@ public class ParsingPackageImpl implements ParsingPackage, ParsingPackageHidden, appInfo.setSplitResourcePaths(splitCodePaths); appInfo.setVersionCode(mLongVersionCode); appInfo.setAppClassNamesByProcess(buildAppClassNamesByProcess()); appInfo.setLocaleConfigRes(mLocaleConfigRes); return appInfo; } Loading Loading @@ -1314,6 +1317,7 @@ public class ParsingPackageImpl implements ParsingPackage, ParsingPackageHidden, dest.writeInt(this.memtagMode); dest.writeInt(this.nativeHeapZeroInitialized); sForBoolean.parcel(this.requestRawExternalStorageAccess, dest, flags); dest.writeInt(this.mLocaleConfigRes); } public ParsingPackageImpl(Parcel in) { Loading Loading @@ -1461,6 +1465,7 @@ public class ParsingPackageImpl implements ParsingPackage, ParsingPackageHidden, this.memtagMode = in.readInt(); this.nativeHeapZeroInitialized = in.readInt(); this.requestRawExternalStorageAccess = sForBoolean.unparcel(in); this.mLocaleConfigRes = in.readInt(); assignDerivedFields(); } Loading Loading @@ -2279,6 +2284,11 @@ public class ParsingPackageImpl implements ParsingPackage, ParsingPackageHidden, return nativeHeapZeroInitialized; } @Override public int getLocaleConfigRes() { return mLocaleConfigRes; } @Nullable @Override public Boolean hasRequestRawExternalStorageAccess() { Loading Loading @@ -2936,4 +2946,10 @@ public class ParsingPackageImpl implements ParsingPackage, ParsingPackageHidden, resetEnabledSettingsOnAppDataCleared); return this; } @Override public ParsingPackageImpl setLocaleConfigRes(int value) { mLocaleConfigRes = value; return this; } }