Loading tools/aconfig/TEST_MAPPING +1 −3 Original line number Diff line number Diff line Loading @@ -102,9 +102,7 @@ { // aconfig_storage file java integration tests "name": "aconfig_storage_file.test.java" } ], "postsubmit": [ }, { // aconfig_storage read functional test "name": "aconfig_storage_read_functional" Loading tools/aconfig/aconfig/src/codegen/java.rs +6 −29 Original line number Diff line number Diff line Loading @@ -543,7 +543,6 @@ mod tests { import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.os.flagging.PlatformAconfigPackageInternal; import android.os.flagging.AconfigStorageReadException; import android.util.Log; /** @hide */ public final class FeatureFlagsImpl implements FeatureFlags { Loading @@ -556,38 +555,16 @@ mod tests { private void init() { try { PlatformAconfigPackageInternal reader = PlatformAconfigPackageInternal.load("system", "com.android.aconfig.test", 0x5081CE7221C77064L); AconfigStorageReadException error = reader.getException(); if (error == null) { disabledRw = reader.getBooleanFlagValue(0); disabledRwExported = reader.getBooleanFlagValue(1); enabledRw = reader.getBooleanFlagValue(7); disabledRwInOtherNamespace = reader.getBooleanFlagValue(2); } else if (Build.VERSION.SDK_INT > 35 && error.getErrorCode() == 5 /* fingerprint doesn't match*/) { disabledRw = reader.getBooleanFlagValue("disabled_rw", false); disabledRwExported = reader.getBooleanFlagValue("disabled_rw_exported", false); enabledRw = reader.getBooleanFlagValue("enabled_rw", true); disabledRwInOtherNamespace = reader.getBooleanFlagValue("disabled_rw_in_other_namespace", false); } else { if (error.getMessage() != null) { Log.e(TAG, error.getMessage()); } else { Log.e(TAG, "Encountered a null AconfigStorageReadException"); } } } catch (Exception e) { if (e.getMessage() != null) { Log.e(TAG, e.getMessage()); } else { Log.e(TAG, "Encountered a null Exception"); } Log.e(TAG, e.toString()); } catch (NoClassDefFoundError e) { // for mainline module running on older devices. // This should be replaces to version check, after the version bump. if (e.getMessage() != null) { Log.e(TAG, e.getMessage()); } else { Log.e(TAG, "Encountered a null NoClassDefFoundError"); } Log.e(TAG, e.toString()); } isCached = true; } Loading tools/aconfig/aconfig/templates/FeatureFlagsImpl.java.template +9 −35 Original line number Diff line number Diff line Loading @@ -11,7 +11,6 @@ import android.os.flagging.PlatformAconfigPackageInternal; {{ -else }} import android.os.flagging.AconfigPackageInternal; {{ -endif }} import android.os.flagging.AconfigStorageReadException; import android.util.Log; {{ -endif }} /** @hide */ Loading @@ -32,44 +31,19 @@ public final class FeatureFlagsImpl implements FeatureFlags \{ {{ -else }} AconfigPackageInternal reader = AconfigPackageInternal.load("{container}", "{package_name}", {package_fingerprint}); {{ -endif }} AconfigStorageReadException error = reader.getException(); if (error == null) \{ {{ for namespace_with_flags in namespace_flags }} {{ -for namespace_with_flags in namespace_flags }} {{ -for flag in namespace_with_flags.flags }} {{ -if flag.is_read_write }} {flag.method_name} = reader.getBooleanFlagValue({flag.flag_offset}); {{ endif }} {{ -endfor }} {{ -endfor }} } else if (Build.VERSION.SDK_INT > 35 && error.getErrorCode() == 5 /* fingerprint doesn't match*/) \{ {{ for namespace_with_flags in namespace_flags }} {{ -for flag in namespace_with_flags.flags }} {{ -if flag.is_read_write }} {flag.method_name} = reader.getBooleanFlagValue("{flag.flag_name}", {flag.default_value}); {{ -endif }} {{ -endfor }} {{ -endfor }} } else \{ if (error.getMessage() != null) \{ Log.e(TAG, error.getMessage()); } else \{ Log.e(TAG, "Encountered a null AconfigStorageReadException"); } } } catch (Exception e) \{ if (e.getMessage() != null) \{ Log.e(TAG, e.getMessage()); } else \{ Log.e(TAG, "Encountered a null Exception"); } Log.e(TAG, e.toString()); } catch (NoClassDefFoundError e) \{ // for mainline module running on older devices. // This should be replaces to version check, after the version bump. if (e.getMessage() != null) \{ Log.e(TAG, e.getMessage()); } else \{ Log.e(TAG, "Encountered a null NoClassDefFoundError"); } Log.e(TAG, e.toString()); } isCached = true; } Loading tools/aconfig/aconfig_storage_file/tests/srcs/StorageFileProviderTest.java +0 −4 Original line number Diff line number Diff line Loading @@ -58,10 +58,6 @@ public class StorageFileProviderTest { new StorageFileProvider(TestDataUtils.TESTDATA_PATH, TestDataUtils.TESTDATA_PATH); PackageTable pt = p.getPackageTable("mock.v1"); assertNotNull(pt); pt = StorageFileProvider.getPackageTable( Paths.get(TestDataUtils.TESTDATA_PATH, "mock.v1.package.map")); assertNotNull(pt); FlagTable f = p.getFlagTable("mock.v1"); assertNotNull(f); FlagValueList v = p.getFlagValueList("mock.v1"); Loading tools/aconfig/aconfig_storage_read_api/srcs/android/os/flagging/PlatformAconfigPackageInternal.java +30 −159 Original line number Diff line number Diff line Loading @@ -17,7 +17,6 @@ package android.os.flagging; import android.aconfig.storage.AconfigStorageException; import android.aconfig.storage.FlagTable; import android.aconfig.storage.FlagValueList; import android.aconfig.storage.PackageTable; import android.aconfig.storage.StorageFileProvider; Loading @@ -41,75 +40,13 @@ import android.os.StrictMode; */ public class PlatformAconfigPackageInternal { private final FlagTable mFlagTable; private final FlagValueList mFlagValueList; private final int mPackageId; private final int mPackageBooleanStartOffset; private final AconfigStorageReadException mException; private PlatformAconfigPackageInternal( FlagValueList flagValueList, FlagTable flagTable, int packageBooleanStartOffset, int packageId, AconfigStorageReadException exception) { FlagValueList flagValueList, int packageBooleanStartOffset) { this.mFlagValueList = flagValueList; this.mFlagTable = flagTable; this.mPackageBooleanStartOffset = packageBooleanStartOffset; this.mPackageId = packageId; this.mException = exception; } /** * Loads an Aconfig Package from platform Aconfig Storage. * * <p>This method is intended for internal use only and may be changed or removed without * notice. * * <p>This method loads the specified Aconfig Package from the given container. * * <p>AconfigStorageException will be stored if there is an error reading from Aconfig Storage. * The specific error code can be got using {@link #getException()}. * * @param container The name of the container. * @param packageName The name of the Aconfig package to load. * @return An instance of {@link PlatformAconfigPackageInternal} * @hide */ @UnsupportedAppUsage public static PlatformAconfigPackageInternal load(String container, String packageName) { return load(container, packageName, StorageFileProvider.getDefaultProvider()); } /** @hide */ public static PlatformAconfigPackageInternal load( String container, String packageName, StorageFileProvider fileProvider) { StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); try { PackageTable.Node pNode = fileProvider.getPackageTable(container).get(packageName); if (pNode == null) { return createExceptionInstance( AconfigStorageException.ERROR_PACKAGE_NOT_FOUND, "package " + packageName + " in container " + container + " cannot be found on the device"); } return new PlatformAconfigPackageInternal( fileProvider.getFlagValueList(container), fileProvider.getFlagTable(container), pNode.getBooleanStartIndex(), pNode.getPackageId(), null); } catch (AconfigStorageException e) { return createExceptionInstance(e.getErrorCode(), e.getMessage()); } finally { StrictMode.setThreadPolicy(oldPolicy); } } /** Loading @@ -118,9 +55,6 @@ public class PlatformAconfigPackageInternal { * <p>This method is intended for internal use only and may be changed or removed without * notice. * * <p>AconfigStorageException will be stored if there is an error reading from Aconfig Storage. * The specific error code can be got using {@link #getException()}. * * @param container The name of the container. * @param packageName The name of the Aconfig package. * @param packageFingerprint The expected fingerprint of the package. Loading @@ -145,48 +79,40 @@ public class PlatformAconfigPackageInternal { long packageFingerprint, StorageFileProvider fileProvider) { StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); PackageTable.Node pNode = null; FlagValueList vList = null; try { PackageTable.Node pNode = fileProvider.getPackageTable(container).get(packageName); pNode = fileProvider.getPackageTable(container).get(packageName); vList = fileProvider.getFlagValueList(container); } catch (AconfigStorageException e) { throw new AconfigStorageReadException(e.getErrorCode(), e.toString()); } finally { StrictMode.setThreadPolicy(oldPolicy); } if (pNode == null) { return createExceptionInstance( if (pNode == null || vList == null) { throw new AconfigStorageReadException( AconfigStorageReadException.ERROR_PACKAGE_NOT_FOUND, String.format( "package " + packageName + " in container " + container + " cannot be found on the device"); + " cannot be found on the device")); } if (pNode.hasPackageFingerprint() && packageFingerprint != pNode.getPackageFingerprint()) { return new PlatformAconfigPackageInternal( fileProvider.getFlagValueList(container), fileProvider.getFlagTable(container), pNode.getBooleanStartIndex(), pNode.getPackageId(), new AconfigStorageReadException( AconfigStorageException.ERROR_FILE_FINGERPRINT_MISMATCH, "The fingerprint provided for the Aconfig package " if (pNode.hasPackageFingerprint() && packageFingerprint != pNode.getPackageFingerprint()) { throw new AconfigStorageReadException( 5, // AconfigStorageReadException.ERROR_FILE_FINGERPRINT_MISMATCH, String.format( "package " + packageName + " in container " + container + " does not match" + " the fingerprint of the package found on the device.")); + " cannot be found on the device")); } return new PlatformAconfigPackageInternal( fileProvider.getFlagValueList(container), null, pNode.getBooleanStartIndex(), 0, null); } catch (AconfigStorageException e) { return createExceptionInstance(e.getErrorCode(), e.getMessage()); } finally { StrictMode.setThreadPolicy(oldPolicy); } return new PlatformAconfigPackageInternal(vList, pNode.getBooleanStartIndex()); } /** Loading @@ -198,10 +124,6 @@ public class PlatformAconfigPackageInternal { * <p>This method retrieves the value of a flag within the loaded Aconfig package using its * index. The index is generated at build time and may vary between builds. * * <p>To ensure you are using the correct index, verify that the package's fingerprint matches * the expected fingerprint before calling this method. If the fingerprints do not match, use * {@link #getBooleanFlagValue(String, boolean)} instead. * * @param index The index of the flag within the package. * @return The boolean value of the flag. * @hide Loading @@ -210,55 +132,4 @@ public class PlatformAconfigPackageInternal { public boolean getBooleanFlagValue(int index) { return mFlagValueList.getBoolean(index + mPackageBooleanStartOffset); } /** * Retrieves the value of a boolean flag using its name. * * <p>This method is intended for internal use only and may be changed or removed without * notice. * * <p>This method retrieves the value of a flag within the loaded Aconfig package using its * name. * * @param flagName The name of the flag. * @param defaultValue The default value to return if the flag is not found. * @return The boolean value of the flag. * @hide */ @UnsupportedAppUsage public boolean getBooleanFlagValue(String flagName, boolean defaultValue) { FlagTable.Node fNode = mFlagTable.get(mPackageId, flagName); if (fNode == null) { return defaultValue; } return mFlagValueList.getBoolean(fNode.getFlagIndex() + mPackageBooleanStartOffset); } /** * Returns any exception that occurred during the loading of the Aconfig package. * * <p>This method is intended for internal use only and may be changed or removed without * notice. * * @return The exception that occurred, or {@code null} if no exception occurred. * @hide */ @UnsupportedAppUsage public AconfigStorageReadException getException() { return mException; } /** * Creates a new {@link PlatformAconfigPackageInternal} instance with an {@link * AconfigStorageException}. * * @param errorCode The error code for the exception. * @param message The error message for the exception. * @return A new {@link PlatformAconfigPackageInternal} instance with the specified exception. */ private static PlatformAconfigPackageInternal createExceptionInstance( int errorCode, String message) { return new PlatformAconfigPackageInternal( null, null, 0, 0, new AconfigStorageReadException(errorCode, message)); } } Loading
tools/aconfig/TEST_MAPPING +1 −3 Original line number Diff line number Diff line Loading @@ -102,9 +102,7 @@ { // aconfig_storage file java integration tests "name": "aconfig_storage_file.test.java" } ], "postsubmit": [ }, { // aconfig_storage read functional test "name": "aconfig_storage_read_functional" Loading
tools/aconfig/aconfig/src/codegen/java.rs +6 −29 Original line number Diff line number Diff line Loading @@ -543,7 +543,6 @@ mod tests { import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.os.flagging.PlatformAconfigPackageInternal; import android.os.flagging.AconfigStorageReadException; import android.util.Log; /** @hide */ public final class FeatureFlagsImpl implements FeatureFlags { Loading @@ -556,38 +555,16 @@ mod tests { private void init() { try { PlatformAconfigPackageInternal reader = PlatformAconfigPackageInternal.load("system", "com.android.aconfig.test", 0x5081CE7221C77064L); AconfigStorageReadException error = reader.getException(); if (error == null) { disabledRw = reader.getBooleanFlagValue(0); disabledRwExported = reader.getBooleanFlagValue(1); enabledRw = reader.getBooleanFlagValue(7); disabledRwInOtherNamespace = reader.getBooleanFlagValue(2); } else if (Build.VERSION.SDK_INT > 35 && error.getErrorCode() == 5 /* fingerprint doesn't match*/) { disabledRw = reader.getBooleanFlagValue("disabled_rw", false); disabledRwExported = reader.getBooleanFlagValue("disabled_rw_exported", false); enabledRw = reader.getBooleanFlagValue("enabled_rw", true); disabledRwInOtherNamespace = reader.getBooleanFlagValue("disabled_rw_in_other_namespace", false); } else { if (error.getMessage() != null) { Log.e(TAG, error.getMessage()); } else { Log.e(TAG, "Encountered a null AconfigStorageReadException"); } } } catch (Exception e) { if (e.getMessage() != null) { Log.e(TAG, e.getMessage()); } else { Log.e(TAG, "Encountered a null Exception"); } Log.e(TAG, e.toString()); } catch (NoClassDefFoundError e) { // for mainline module running on older devices. // This should be replaces to version check, after the version bump. if (e.getMessage() != null) { Log.e(TAG, e.getMessage()); } else { Log.e(TAG, "Encountered a null NoClassDefFoundError"); } Log.e(TAG, e.toString()); } isCached = true; } Loading
tools/aconfig/aconfig/templates/FeatureFlagsImpl.java.template +9 −35 Original line number Diff line number Diff line Loading @@ -11,7 +11,6 @@ import android.os.flagging.PlatformAconfigPackageInternal; {{ -else }} import android.os.flagging.AconfigPackageInternal; {{ -endif }} import android.os.flagging.AconfigStorageReadException; import android.util.Log; {{ -endif }} /** @hide */ Loading @@ -32,44 +31,19 @@ public final class FeatureFlagsImpl implements FeatureFlags \{ {{ -else }} AconfigPackageInternal reader = AconfigPackageInternal.load("{container}", "{package_name}", {package_fingerprint}); {{ -endif }} AconfigStorageReadException error = reader.getException(); if (error == null) \{ {{ for namespace_with_flags in namespace_flags }} {{ -for namespace_with_flags in namespace_flags }} {{ -for flag in namespace_with_flags.flags }} {{ -if flag.is_read_write }} {flag.method_name} = reader.getBooleanFlagValue({flag.flag_offset}); {{ endif }} {{ -endfor }} {{ -endfor }} } else if (Build.VERSION.SDK_INT > 35 && error.getErrorCode() == 5 /* fingerprint doesn't match*/) \{ {{ for namespace_with_flags in namespace_flags }} {{ -for flag in namespace_with_flags.flags }} {{ -if flag.is_read_write }} {flag.method_name} = reader.getBooleanFlagValue("{flag.flag_name}", {flag.default_value}); {{ -endif }} {{ -endfor }} {{ -endfor }} } else \{ if (error.getMessage() != null) \{ Log.e(TAG, error.getMessage()); } else \{ Log.e(TAG, "Encountered a null AconfigStorageReadException"); } } } catch (Exception e) \{ if (e.getMessage() != null) \{ Log.e(TAG, e.getMessage()); } else \{ Log.e(TAG, "Encountered a null Exception"); } Log.e(TAG, e.toString()); } catch (NoClassDefFoundError e) \{ // for mainline module running on older devices. // This should be replaces to version check, after the version bump. if (e.getMessage() != null) \{ Log.e(TAG, e.getMessage()); } else \{ Log.e(TAG, "Encountered a null NoClassDefFoundError"); } Log.e(TAG, e.toString()); } isCached = true; } Loading
tools/aconfig/aconfig_storage_file/tests/srcs/StorageFileProviderTest.java +0 −4 Original line number Diff line number Diff line Loading @@ -58,10 +58,6 @@ public class StorageFileProviderTest { new StorageFileProvider(TestDataUtils.TESTDATA_PATH, TestDataUtils.TESTDATA_PATH); PackageTable pt = p.getPackageTable("mock.v1"); assertNotNull(pt); pt = StorageFileProvider.getPackageTable( Paths.get(TestDataUtils.TESTDATA_PATH, "mock.v1.package.map")); assertNotNull(pt); FlagTable f = p.getFlagTable("mock.v1"); assertNotNull(f); FlagValueList v = p.getFlagValueList("mock.v1"); Loading
tools/aconfig/aconfig_storage_read_api/srcs/android/os/flagging/PlatformAconfigPackageInternal.java +30 −159 Original line number Diff line number Diff line Loading @@ -17,7 +17,6 @@ package android.os.flagging; import android.aconfig.storage.AconfigStorageException; import android.aconfig.storage.FlagTable; import android.aconfig.storage.FlagValueList; import android.aconfig.storage.PackageTable; import android.aconfig.storage.StorageFileProvider; Loading @@ -41,75 +40,13 @@ import android.os.StrictMode; */ public class PlatformAconfigPackageInternal { private final FlagTable mFlagTable; private final FlagValueList mFlagValueList; private final int mPackageId; private final int mPackageBooleanStartOffset; private final AconfigStorageReadException mException; private PlatformAconfigPackageInternal( FlagValueList flagValueList, FlagTable flagTable, int packageBooleanStartOffset, int packageId, AconfigStorageReadException exception) { FlagValueList flagValueList, int packageBooleanStartOffset) { this.mFlagValueList = flagValueList; this.mFlagTable = flagTable; this.mPackageBooleanStartOffset = packageBooleanStartOffset; this.mPackageId = packageId; this.mException = exception; } /** * Loads an Aconfig Package from platform Aconfig Storage. * * <p>This method is intended for internal use only and may be changed or removed without * notice. * * <p>This method loads the specified Aconfig Package from the given container. * * <p>AconfigStorageException will be stored if there is an error reading from Aconfig Storage. * The specific error code can be got using {@link #getException()}. * * @param container The name of the container. * @param packageName The name of the Aconfig package to load. * @return An instance of {@link PlatformAconfigPackageInternal} * @hide */ @UnsupportedAppUsage public static PlatformAconfigPackageInternal load(String container, String packageName) { return load(container, packageName, StorageFileProvider.getDefaultProvider()); } /** @hide */ public static PlatformAconfigPackageInternal load( String container, String packageName, StorageFileProvider fileProvider) { StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); try { PackageTable.Node pNode = fileProvider.getPackageTable(container).get(packageName); if (pNode == null) { return createExceptionInstance( AconfigStorageException.ERROR_PACKAGE_NOT_FOUND, "package " + packageName + " in container " + container + " cannot be found on the device"); } return new PlatformAconfigPackageInternal( fileProvider.getFlagValueList(container), fileProvider.getFlagTable(container), pNode.getBooleanStartIndex(), pNode.getPackageId(), null); } catch (AconfigStorageException e) { return createExceptionInstance(e.getErrorCode(), e.getMessage()); } finally { StrictMode.setThreadPolicy(oldPolicy); } } /** Loading @@ -118,9 +55,6 @@ public class PlatformAconfigPackageInternal { * <p>This method is intended for internal use only and may be changed or removed without * notice. * * <p>AconfigStorageException will be stored if there is an error reading from Aconfig Storage. * The specific error code can be got using {@link #getException()}. * * @param container The name of the container. * @param packageName The name of the Aconfig package. * @param packageFingerprint The expected fingerprint of the package. Loading @@ -145,48 +79,40 @@ public class PlatformAconfigPackageInternal { long packageFingerprint, StorageFileProvider fileProvider) { StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); PackageTable.Node pNode = null; FlagValueList vList = null; try { PackageTable.Node pNode = fileProvider.getPackageTable(container).get(packageName); pNode = fileProvider.getPackageTable(container).get(packageName); vList = fileProvider.getFlagValueList(container); } catch (AconfigStorageException e) { throw new AconfigStorageReadException(e.getErrorCode(), e.toString()); } finally { StrictMode.setThreadPolicy(oldPolicy); } if (pNode == null) { return createExceptionInstance( if (pNode == null || vList == null) { throw new AconfigStorageReadException( AconfigStorageReadException.ERROR_PACKAGE_NOT_FOUND, String.format( "package " + packageName + " in container " + container + " cannot be found on the device"); + " cannot be found on the device")); } if (pNode.hasPackageFingerprint() && packageFingerprint != pNode.getPackageFingerprint()) { return new PlatformAconfigPackageInternal( fileProvider.getFlagValueList(container), fileProvider.getFlagTable(container), pNode.getBooleanStartIndex(), pNode.getPackageId(), new AconfigStorageReadException( AconfigStorageException.ERROR_FILE_FINGERPRINT_MISMATCH, "The fingerprint provided for the Aconfig package " if (pNode.hasPackageFingerprint() && packageFingerprint != pNode.getPackageFingerprint()) { throw new AconfigStorageReadException( 5, // AconfigStorageReadException.ERROR_FILE_FINGERPRINT_MISMATCH, String.format( "package " + packageName + " in container " + container + " does not match" + " the fingerprint of the package found on the device.")); + " cannot be found on the device")); } return new PlatformAconfigPackageInternal( fileProvider.getFlagValueList(container), null, pNode.getBooleanStartIndex(), 0, null); } catch (AconfigStorageException e) { return createExceptionInstance(e.getErrorCode(), e.getMessage()); } finally { StrictMode.setThreadPolicy(oldPolicy); } return new PlatformAconfigPackageInternal(vList, pNode.getBooleanStartIndex()); } /** Loading @@ -198,10 +124,6 @@ public class PlatformAconfigPackageInternal { * <p>This method retrieves the value of a flag within the loaded Aconfig package using its * index. The index is generated at build time and may vary between builds. * * <p>To ensure you are using the correct index, verify that the package's fingerprint matches * the expected fingerprint before calling this method. If the fingerprints do not match, use * {@link #getBooleanFlagValue(String, boolean)} instead. * * @param index The index of the flag within the package. * @return The boolean value of the flag. * @hide Loading @@ -210,55 +132,4 @@ public class PlatformAconfigPackageInternal { public boolean getBooleanFlagValue(int index) { return mFlagValueList.getBoolean(index + mPackageBooleanStartOffset); } /** * Retrieves the value of a boolean flag using its name. * * <p>This method is intended for internal use only and may be changed or removed without * notice. * * <p>This method retrieves the value of a flag within the loaded Aconfig package using its * name. * * @param flagName The name of the flag. * @param defaultValue The default value to return if the flag is not found. * @return The boolean value of the flag. * @hide */ @UnsupportedAppUsage public boolean getBooleanFlagValue(String flagName, boolean defaultValue) { FlagTable.Node fNode = mFlagTable.get(mPackageId, flagName); if (fNode == null) { return defaultValue; } return mFlagValueList.getBoolean(fNode.getFlagIndex() + mPackageBooleanStartOffset); } /** * Returns any exception that occurred during the loading of the Aconfig package. * * <p>This method is intended for internal use only and may be changed or removed without * notice. * * @return The exception that occurred, or {@code null} if no exception occurred. * @hide */ @UnsupportedAppUsage public AconfigStorageReadException getException() { return mException; } /** * Creates a new {@link PlatformAconfigPackageInternal} instance with an {@link * AconfigStorageException}. * * @param errorCode The error code for the exception. * @param message The error message for the exception. * @return A new {@link PlatformAconfigPackageInternal} instance with the specified exception. */ private static PlatformAconfigPackageInternal createExceptionInstance( int errorCode, String message) { return new PlatformAconfigPackageInternal( null, null, 0, 0, new AconfigStorageReadException(errorCode, message)); } }