Loading tools/aconfig/aconfig_storage_file/srcs/android/aconfig/storage/AconfigStorageException.java +106 −0 Original line number Diff line number Diff line Loading @@ -16,12 +16,118 @@ package android.aconfig.storage; /** * Exception thrown when an error occurs while accessing Aconfig Storage. * * <p>This exception indicates a general problem with Aconfig Storage, such as an inability to read * or write data. */ public class AconfigStorageException extends RuntimeException { /** Generic error code indicating an unspecified Aconfig Storage error. */ public static final int ERROR_GENERIC = 0; /** Error code indicating that the Aconfig Storage system is not found on the device. */ public static final int ERROR_STORAGE_SYSTEM_NOT_FOUND = 1; /** Error code indicating that the requested configuration package is not found. */ public static final int ERROR_PACKAGE_NOT_FOUND = 2; /** Error code indicating that the specified container is not found. */ public static final int ERROR_CONTAINER_NOT_FOUND = 3; /** Error code indicating that there was an error reading the Aconfig Storage file. */ public static final int ERROR_CANNOT_READ_STORAGE_FILE = 4; private final int mErrorCode; /** * Constructs a new {@code AconfigStorageException} with a generic error code and the specified * detail message. * * @param msg The detail message for this exception. */ public AconfigStorageException(String msg) { super(msg); mErrorCode = ERROR_GENERIC; } /** * Constructs a new {@code AconfigStorageException} with a generic error code, the specified * detail message, and cause. * * @param msg The detail message for this exception. * @param cause The cause of this exception. */ public AconfigStorageException(String msg, Throwable cause) { super(msg, cause); mErrorCode = ERROR_GENERIC; } /** * Constructs a new {@code AconfigStorageException} with the specified error code and detail * message. * * @param errorCode The error code for this exception. * @param msg The detail message for this exception. */ public AconfigStorageException(int errorCode, String msg) { super(msg); mErrorCode = errorCode; } /** * Constructs a new {@code AconfigStorageException} with the specified error code, detail * message, and cause. * * @param errorCode The error code for this exception. * @param msg The detail message for this exception. * @param cause The cause of this exception. */ public AconfigStorageException(int errorCode, String msg, Throwable cause) { super(msg, cause); mErrorCode = errorCode; } /** * Returns the error code associated with this exception. * * @return The error code. */ public int getErrorCode() { return mErrorCode; } /** * Returns the error message for this exception, including the error code and the original * message. * * @return The error message. */ @Override public String getMessage() { return errorString() + ": " + super.getMessage(); } /** * Returns a string representation of the error code. * * @return The error code string. */ private String errorString() { switch (mErrorCode) { case ERROR_GENERIC: return "ERROR_GENERIC"; case ERROR_STORAGE_SYSTEM_NOT_FOUND: return "ERROR_STORAGE_SYSTEM_NOT_FOUND"; case ERROR_PACKAGE_NOT_FOUND: return "ERROR_PACKAGE_NOT_FOUND"; case ERROR_CONTAINER_NOT_FOUND: return "ERROR_CONTAINER_NOT_FOUND"; case ERROR_CANNOT_READ_STORAGE_FILE: return "ERROR_CANNOT_READ_STORAGE_FILE"; default: return "<Unknown error code " + mErrorCode + ">"; } } } tools/aconfig/aconfig_storage_read_api/srcs/android/aconfig/storage/AconfigPackageImpl.java +27 −21 Original line number Diff line number Diff line Loading @@ -27,29 +27,26 @@ public class AconfigPackageImpl { private PackageTable.Node mPNode; /** @hide */ public static final int ERROR_NEW_STORAGE_SYSTEM_NOT_FOUND = 1; private AconfigPackageImpl() {} /** @hide */ public static final int ERROR_PACKAGE_NOT_FOUND = 2; /** @hide */ public static final int ERROR_CONTAINER_NOT_FOUND = 3; /** @hide */ public AconfigPackageImpl() {} /** @hide */ public int load(String packageName, StorageFileProvider fileProvider) { return init(null, packageName, fileProvider); public static AconfigPackageImpl load(String packageName, StorageFileProvider fileProvider) { AconfigPackageImpl impl = new AconfigPackageImpl(); impl.init(null, packageName, fileProvider); return impl; } /** @hide */ public int load(String container, String packageName, StorageFileProvider fileProvider) { public static AconfigPackageImpl load( String container, String packageName, StorageFileProvider fileProvider) { if (container == null) { return ERROR_CONTAINER_NOT_FOUND; throw new AconfigStorageException( AconfigStorageException.ERROR_CONTAINER_NOT_FOUND, "container null cannot be found on the device"); } return init(container, packageName, fileProvider); AconfigPackageImpl impl = new AconfigPackageImpl(); impl.init(container, packageName, fileProvider); return impl; } /** @hide */ Loading @@ -76,13 +73,15 @@ public class AconfigPackageImpl { return mPNode.hasPackageFingerprint(); } private int init(String containerName, String packageName, StorageFileProvider fileProvider) { private void init(String containerName, String packageName, StorageFileProvider fileProvider) { StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); String container = containerName; try { // for devices don't have new storage directly return if (!fileProvider.containerFileExists(null)) { return ERROR_NEW_STORAGE_SYSTEM_NOT_FOUND; throw new AconfigStorageException( AconfigStorageException.ERROR_STORAGE_SYSTEM_NOT_FOUND, "aconfig storage cannot be found on the device"); } PackageTable.Node pNode = null; Loading @@ -107,7 +106,9 @@ public class AconfigPackageImpl { } } else { if (!fileProvider.containerFileExists(container)) { return ERROR_CONTAINER_NOT_FOUND; throw new AconfigStorageException( AconfigStorageException.ERROR_CONTAINER_NOT_FOUND, "container " + container + " cannot be found on the device"); } pNode = fileProvider.getPackageTable(container).get(packageName); } Loading @@ -115,7 +116,13 @@ public class AconfigPackageImpl { if (pNode == null) { // for the case package is not found in all container, return instead of throwing // error return ERROR_PACKAGE_NOT_FOUND; throw new AconfigStorageException( AconfigStorageException.ERROR_PACKAGE_NOT_FOUND, "package " + packageName + " in container " + container + " cannot be found on the device"); } mFlagTable = fileProvider.getFlagTable(container); Loading @@ -126,6 +133,5 @@ public class AconfigPackageImpl { } finally { StrictMode.setThreadPolicy(oldPolicy); } return 0; } } tools/aconfig/aconfig_storage_read_api/srcs/android/aconfig/storage/StorageFileProvider.java +3 −1 Original line number Diff line number Diff line Loading @@ -105,7 +105,9 @@ public class StorageFileProvider { return channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size()); } catch (Exception e) { throw new AconfigStorageException( String.format("Fail to mmap storage file %s", file), e); AconfigStorageException.ERROR_CANNOT_READ_STORAGE_FILE, String.format("Fail to mmap storage file %s", file), e); } finally { quietlyDispose(channel); } Loading tools/aconfig/aconfig_storage_read_api/tests/java/AconfigPackageImplTest.java +48 −28 Original line number Diff line number Diff line Loading @@ -43,53 +43,73 @@ public class AconfigPackageImplTest { @Test public void testLoad_onlyPackageName() throws Exception { AconfigPackageImpl p = new AconfigPackageImpl(); p.load("com.android.aconfig.storage.test_1", pr); AconfigPackageImpl p = AconfigPackageImpl.load("com.android.aconfig.storage.test_1", pr); assertNotNull(p); } @Test public void testLoad_groupNameFingerprint() throws Exception { AconfigPackageImpl p = new AconfigPackageImpl(); p.load("mockup", "com.android.aconfig.storage.test_1", pr); AconfigPackageImpl p = AconfigPackageImpl.load("mockup", "com.android.aconfig.storage.test_1", pr); assertNotNull(p); } @Test public void testLoad_error() throws Exception { AconfigPackageImpl p = new AconfigPackageImpl(); AconfigPackageImpl p; AconfigStorageException e = assertThrows( AconfigStorageException.class, () -> AconfigPackageImpl.load( "mockup", "com.android.aconfig.storage.test_10", pr)); // cannot find package assertEquals( AconfigPackageImpl.ERROR_PACKAGE_NOT_FOUND, p.load("mockup", "com.android.aconfig.storage.test_10", pr)); assertEquals(AconfigStorageException.ERROR_PACKAGE_NOT_FOUND, e.getErrorCode()); // cannot find package assertEquals( AconfigPackageImpl.ERROR_PACKAGE_NOT_FOUND, p.load("com.android.aconfig.storage.test_10", pr)); e = assertThrows( AconfigStorageException.class, () -> AconfigPackageImpl.load("com.android.aconfig.storage.test_10", pr)); assertEquals(AconfigStorageException.ERROR_PACKAGE_NOT_FOUND, e.getErrorCode()); // cannot find container assertEquals( AconfigPackageImpl.ERROR_CONTAINER_NOT_FOUND, p.load(null, "com.android.aconfig.storage.test_1", pr)); assertEquals( AconfigPackageImpl.ERROR_CONTAINER_NOT_FOUND, p.load("test", "com.android.aconfig.storage.test_1", pr)); e = assertThrows( AconfigStorageException.class, () -> AconfigPackageImpl.load( null, "com.android.aconfig.storage.test_1", pr)); assertEquals(AconfigStorageException.ERROR_CONTAINER_NOT_FOUND, e.getErrorCode()); e = assertThrows( AconfigStorageException.class, () -> AconfigPackageImpl.load( "test", "com.android.aconfig.storage.test_1", pr)); assertEquals(AconfigStorageException.ERROR_CONTAINER_NOT_FOUND, e.getErrorCode()); // new storage doesn't exist pr = new StorageFileProvider("fake/path/", "fake/path/"); assertEquals( AconfigPackageImpl.ERROR_NEW_STORAGE_SYSTEM_NOT_FOUND, p.load("fake_package", pr)); e = assertThrows( AconfigStorageException.class, () -> AconfigPackageImpl.load("fake_package", pr)); assertEquals(AconfigStorageException.ERROR_STORAGE_SYSTEM_NOT_FOUND, e.getErrorCode()); // file read issue pr = new StorageFileProvider(TestDataUtils.TESTDATA_PATH, "fake/path/"); e = assertThrows( AconfigStorageException.class, () -> p.load("mockup", "com.android.aconfig.storage.test_1", pr)); () -> AconfigPackageImpl.load( "mockup", "com.android.aconfig.storage.test_1", pr)); assertEquals(AconfigStorageException.ERROR_CANNOT_READ_STORAGE_FILE, e.getErrorCode()); } @Test public void testGetBooleanFlagValue_flagName() throws Exception { AconfigPackageImpl p = new AconfigPackageImpl(); p.load("mockup", "com.android.aconfig.storage.test_1", pr); AconfigPackageImpl p = AconfigPackageImpl.load("mockup", "com.android.aconfig.storage.test_1", pr); assertFalse(p.getBooleanFlagValue("disabled_rw", true)); assertTrue(p.getBooleanFlagValue("enabled_ro", false)); assertTrue(p.getBooleanFlagValue("enabled_rw", false)); Loading @@ -98,8 +118,8 @@ public class AconfigPackageImplTest { @Test public void testGetBooleanFlagValue_index() throws Exception { AconfigPackageImpl p = new AconfigPackageImpl(); p.load("mockup", "com.android.aconfig.storage.test_1", pr); AconfigPackageImpl p = AconfigPackageImpl.load("mockup", "com.android.aconfig.storage.test_1", pr); assertFalse(p.getBooleanFlagValue(0)); assertTrue(p.getBooleanFlagValue(1)); assertTrue(p.getBooleanFlagValue(2)); Loading @@ -107,8 +127,8 @@ public class AconfigPackageImplTest { @Test public void testHasPackageFingerprint() throws Exception { AconfigPackageImpl p = new AconfigPackageImpl(); p.load("mockup", "com.android.aconfig.storage.test_1", pr); AconfigPackageImpl p = AconfigPackageImpl.load("mockup", "com.android.aconfig.storage.test_1", pr); assertFalse(p.hasPackageFingerprint()); } } Loading
tools/aconfig/aconfig_storage_file/srcs/android/aconfig/storage/AconfigStorageException.java +106 −0 Original line number Diff line number Diff line Loading @@ -16,12 +16,118 @@ package android.aconfig.storage; /** * Exception thrown when an error occurs while accessing Aconfig Storage. * * <p>This exception indicates a general problem with Aconfig Storage, such as an inability to read * or write data. */ public class AconfigStorageException extends RuntimeException { /** Generic error code indicating an unspecified Aconfig Storage error. */ public static final int ERROR_GENERIC = 0; /** Error code indicating that the Aconfig Storage system is not found on the device. */ public static final int ERROR_STORAGE_SYSTEM_NOT_FOUND = 1; /** Error code indicating that the requested configuration package is not found. */ public static final int ERROR_PACKAGE_NOT_FOUND = 2; /** Error code indicating that the specified container is not found. */ public static final int ERROR_CONTAINER_NOT_FOUND = 3; /** Error code indicating that there was an error reading the Aconfig Storage file. */ public static final int ERROR_CANNOT_READ_STORAGE_FILE = 4; private final int mErrorCode; /** * Constructs a new {@code AconfigStorageException} with a generic error code and the specified * detail message. * * @param msg The detail message for this exception. */ public AconfigStorageException(String msg) { super(msg); mErrorCode = ERROR_GENERIC; } /** * Constructs a new {@code AconfigStorageException} with a generic error code, the specified * detail message, and cause. * * @param msg The detail message for this exception. * @param cause The cause of this exception. */ public AconfigStorageException(String msg, Throwable cause) { super(msg, cause); mErrorCode = ERROR_GENERIC; } /** * Constructs a new {@code AconfigStorageException} with the specified error code and detail * message. * * @param errorCode The error code for this exception. * @param msg The detail message for this exception. */ public AconfigStorageException(int errorCode, String msg) { super(msg); mErrorCode = errorCode; } /** * Constructs a new {@code AconfigStorageException} with the specified error code, detail * message, and cause. * * @param errorCode The error code for this exception. * @param msg The detail message for this exception. * @param cause The cause of this exception. */ public AconfigStorageException(int errorCode, String msg, Throwable cause) { super(msg, cause); mErrorCode = errorCode; } /** * Returns the error code associated with this exception. * * @return The error code. */ public int getErrorCode() { return mErrorCode; } /** * Returns the error message for this exception, including the error code and the original * message. * * @return The error message. */ @Override public String getMessage() { return errorString() + ": " + super.getMessage(); } /** * Returns a string representation of the error code. * * @return The error code string. */ private String errorString() { switch (mErrorCode) { case ERROR_GENERIC: return "ERROR_GENERIC"; case ERROR_STORAGE_SYSTEM_NOT_FOUND: return "ERROR_STORAGE_SYSTEM_NOT_FOUND"; case ERROR_PACKAGE_NOT_FOUND: return "ERROR_PACKAGE_NOT_FOUND"; case ERROR_CONTAINER_NOT_FOUND: return "ERROR_CONTAINER_NOT_FOUND"; case ERROR_CANNOT_READ_STORAGE_FILE: return "ERROR_CANNOT_READ_STORAGE_FILE"; default: return "<Unknown error code " + mErrorCode + ">"; } } }
tools/aconfig/aconfig_storage_read_api/srcs/android/aconfig/storage/AconfigPackageImpl.java +27 −21 Original line number Diff line number Diff line Loading @@ -27,29 +27,26 @@ public class AconfigPackageImpl { private PackageTable.Node mPNode; /** @hide */ public static final int ERROR_NEW_STORAGE_SYSTEM_NOT_FOUND = 1; private AconfigPackageImpl() {} /** @hide */ public static final int ERROR_PACKAGE_NOT_FOUND = 2; /** @hide */ public static final int ERROR_CONTAINER_NOT_FOUND = 3; /** @hide */ public AconfigPackageImpl() {} /** @hide */ public int load(String packageName, StorageFileProvider fileProvider) { return init(null, packageName, fileProvider); public static AconfigPackageImpl load(String packageName, StorageFileProvider fileProvider) { AconfigPackageImpl impl = new AconfigPackageImpl(); impl.init(null, packageName, fileProvider); return impl; } /** @hide */ public int load(String container, String packageName, StorageFileProvider fileProvider) { public static AconfigPackageImpl load( String container, String packageName, StorageFileProvider fileProvider) { if (container == null) { return ERROR_CONTAINER_NOT_FOUND; throw new AconfigStorageException( AconfigStorageException.ERROR_CONTAINER_NOT_FOUND, "container null cannot be found on the device"); } return init(container, packageName, fileProvider); AconfigPackageImpl impl = new AconfigPackageImpl(); impl.init(container, packageName, fileProvider); return impl; } /** @hide */ Loading @@ -76,13 +73,15 @@ public class AconfigPackageImpl { return mPNode.hasPackageFingerprint(); } private int init(String containerName, String packageName, StorageFileProvider fileProvider) { private void init(String containerName, String packageName, StorageFileProvider fileProvider) { StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); String container = containerName; try { // for devices don't have new storage directly return if (!fileProvider.containerFileExists(null)) { return ERROR_NEW_STORAGE_SYSTEM_NOT_FOUND; throw new AconfigStorageException( AconfigStorageException.ERROR_STORAGE_SYSTEM_NOT_FOUND, "aconfig storage cannot be found on the device"); } PackageTable.Node pNode = null; Loading @@ -107,7 +106,9 @@ public class AconfigPackageImpl { } } else { if (!fileProvider.containerFileExists(container)) { return ERROR_CONTAINER_NOT_FOUND; throw new AconfigStorageException( AconfigStorageException.ERROR_CONTAINER_NOT_FOUND, "container " + container + " cannot be found on the device"); } pNode = fileProvider.getPackageTable(container).get(packageName); } Loading @@ -115,7 +116,13 @@ public class AconfigPackageImpl { if (pNode == null) { // for the case package is not found in all container, return instead of throwing // error return ERROR_PACKAGE_NOT_FOUND; throw new AconfigStorageException( AconfigStorageException.ERROR_PACKAGE_NOT_FOUND, "package " + packageName + " in container " + container + " cannot be found on the device"); } mFlagTable = fileProvider.getFlagTable(container); Loading @@ -126,6 +133,5 @@ public class AconfigPackageImpl { } finally { StrictMode.setThreadPolicy(oldPolicy); } return 0; } }
tools/aconfig/aconfig_storage_read_api/srcs/android/aconfig/storage/StorageFileProvider.java +3 −1 Original line number Diff line number Diff line Loading @@ -105,7 +105,9 @@ public class StorageFileProvider { return channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size()); } catch (Exception e) { throw new AconfigStorageException( String.format("Fail to mmap storage file %s", file), e); AconfigStorageException.ERROR_CANNOT_READ_STORAGE_FILE, String.format("Fail to mmap storage file %s", file), e); } finally { quietlyDispose(channel); } Loading
tools/aconfig/aconfig_storage_read_api/tests/java/AconfigPackageImplTest.java +48 −28 Original line number Diff line number Diff line Loading @@ -43,53 +43,73 @@ public class AconfigPackageImplTest { @Test public void testLoad_onlyPackageName() throws Exception { AconfigPackageImpl p = new AconfigPackageImpl(); p.load("com.android.aconfig.storage.test_1", pr); AconfigPackageImpl p = AconfigPackageImpl.load("com.android.aconfig.storage.test_1", pr); assertNotNull(p); } @Test public void testLoad_groupNameFingerprint() throws Exception { AconfigPackageImpl p = new AconfigPackageImpl(); p.load("mockup", "com.android.aconfig.storage.test_1", pr); AconfigPackageImpl p = AconfigPackageImpl.load("mockup", "com.android.aconfig.storage.test_1", pr); assertNotNull(p); } @Test public void testLoad_error() throws Exception { AconfigPackageImpl p = new AconfigPackageImpl(); AconfigPackageImpl p; AconfigStorageException e = assertThrows( AconfigStorageException.class, () -> AconfigPackageImpl.load( "mockup", "com.android.aconfig.storage.test_10", pr)); // cannot find package assertEquals( AconfigPackageImpl.ERROR_PACKAGE_NOT_FOUND, p.load("mockup", "com.android.aconfig.storage.test_10", pr)); assertEquals(AconfigStorageException.ERROR_PACKAGE_NOT_FOUND, e.getErrorCode()); // cannot find package assertEquals( AconfigPackageImpl.ERROR_PACKAGE_NOT_FOUND, p.load("com.android.aconfig.storage.test_10", pr)); e = assertThrows( AconfigStorageException.class, () -> AconfigPackageImpl.load("com.android.aconfig.storage.test_10", pr)); assertEquals(AconfigStorageException.ERROR_PACKAGE_NOT_FOUND, e.getErrorCode()); // cannot find container assertEquals( AconfigPackageImpl.ERROR_CONTAINER_NOT_FOUND, p.load(null, "com.android.aconfig.storage.test_1", pr)); assertEquals( AconfigPackageImpl.ERROR_CONTAINER_NOT_FOUND, p.load("test", "com.android.aconfig.storage.test_1", pr)); e = assertThrows( AconfigStorageException.class, () -> AconfigPackageImpl.load( null, "com.android.aconfig.storage.test_1", pr)); assertEquals(AconfigStorageException.ERROR_CONTAINER_NOT_FOUND, e.getErrorCode()); e = assertThrows( AconfigStorageException.class, () -> AconfigPackageImpl.load( "test", "com.android.aconfig.storage.test_1", pr)); assertEquals(AconfigStorageException.ERROR_CONTAINER_NOT_FOUND, e.getErrorCode()); // new storage doesn't exist pr = new StorageFileProvider("fake/path/", "fake/path/"); assertEquals( AconfigPackageImpl.ERROR_NEW_STORAGE_SYSTEM_NOT_FOUND, p.load("fake_package", pr)); e = assertThrows( AconfigStorageException.class, () -> AconfigPackageImpl.load("fake_package", pr)); assertEquals(AconfigStorageException.ERROR_STORAGE_SYSTEM_NOT_FOUND, e.getErrorCode()); // file read issue pr = new StorageFileProvider(TestDataUtils.TESTDATA_PATH, "fake/path/"); e = assertThrows( AconfigStorageException.class, () -> p.load("mockup", "com.android.aconfig.storage.test_1", pr)); () -> AconfigPackageImpl.load( "mockup", "com.android.aconfig.storage.test_1", pr)); assertEquals(AconfigStorageException.ERROR_CANNOT_READ_STORAGE_FILE, e.getErrorCode()); } @Test public void testGetBooleanFlagValue_flagName() throws Exception { AconfigPackageImpl p = new AconfigPackageImpl(); p.load("mockup", "com.android.aconfig.storage.test_1", pr); AconfigPackageImpl p = AconfigPackageImpl.load("mockup", "com.android.aconfig.storage.test_1", pr); assertFalse(p.getBooleanFlagValue("disabled_rw", true)); assertTrue(p.getBooleanFlagValue("enabled_ro", false)); assertTrue(p.getBooleanFlagValue("enabled_rw", false)); Loading @@ -98,8 +118,8 @@ public class AconfigPackageImplTest { @Test public void testGetBooleanFlagValue_index() throws Exception { AconfigPackageImpl p = new AconfigPackageImpl(); p.load("mockup", "com.android.aconfig.storage.test_1", pr); AconfigPackageImpl p = AconfigPackageImpl.load("mockup", "com.android.aconfig.storage.test_1", pr); assertFalse(p.getBooleanFlagValue(0)); assertTrue(p.getBooleanFlagValue(1)); assertTrue(p.getBooleanFlagValue(2)); Loading @@ -107,8 +127,8 @@ public class AconfigPackageImplTest { @Test public void testHasPackageFingerprint() throws Exception { AconfigPackageImpl p = new AconfigPackageImpl(); p.load("mockup", "com.android.aconfig.storage.test_1", pr); AconfigPackageImpl p = AconfigPackageImpl.load("mockup", "com.android.aconfig.storage.test_1", pr); assertFalse(p.hasPackageFingerprint()); } }