From 621323cfdaff0c18ffefb75458a7223cf30afe4b Mon Sep 17 00:00:00 2001 From: Zhi Dou Date: Thu, 11 Jul 2024 21:46:31 +0000 Subject: [PATCH] add storage java reader Test: atest aconfig_storage_read_api.test.java Bug: 349874828 Change-Id: I4b1d5ccf4d48622a88712b6e8940ffe18e980927 --- .../aconfig_storage_read_api/Android.bp | 15 +++- .../storage/StorageInternalReader.java | 74 +++++++++++++++++++ .../tests/java/Android.bp | 3 +- .../tests/java/StorageInternalReaderTest.java | 45 +++++++++++ 4 files changed, 135 insertions(+), 2 deletions(-) create mode 100644 tools/aconfig/aconfig_storage_read_api/srcs/android/aconfig/storage/StorageInternalReader.java create mode 100644 tools/aconfig/aconfig_storage_read_api/tests/java/StorageInternalReaderTest.java diff --git a/tools/aconfig/aconfig_storage_read_api/Android.bp b/tools/aconfig/aconfig_storage_read_api/Android.bp index 5e9eb54d48..c2f4c1803f 100644 --- a/tools/aconfig/aconfig_storage_read_api/Android.bp +++ b/tools/aconfig/aconfig_storage_read_api/Android.bp @@ -154,7 +154,9 @@ rust_ffi_shared { java_library { name: "libaconfig_storage_read_api_java", srcs: [ - "srcs/**/*.java", + "srcs/android/aconfig/storage/AconfigStorageReadAPI.java", + "srcs/android/aconfig/storage/FlagReadContext.java", + "srcs/android/aconfig/storage/PackageReadContext.java", ], required: ["libaconfig_storage_read_api_rust_jni"], min_sdk_version: "UpsideDownCake", @@ -163,3 +165,14 @@ java_library { "//apex_available:platform", ], } + +java_library { + name: "aconfig_storage_reader_java", + srcs: [ + "srcs/android/aconfig/storage/StorageInternalReader.java", + ], + static_libs: [ + "aconfig_storage_file_java", + ], + sdk_version: "core_current", +} diff --git a/tools/aconfig/aconfig_storage_read_api/srcs/android/aconfig/storage/StorageInternalReader.java b/tools/aconfig/aconfig_storage_read_api/srcs/android/aconfig/storage/StorageInternalReader.java new file mode 100644 index 0000000000..5f31017d21 --- /dev/null +++ b/tools/aconfig/aconfig_storage_read_api/srcs/android/aconfig/storage/StorageInternalReader.java @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2024 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.aconfig.storage; + +import java.io.FileInputStream; +import java.nio.MappedByteBuffer; +import java.nio.channels.FileChannel; + +public class StorageInternalReader { + + private static final String MAP_PATH = "/metadata/aconfig/maps/"; + private static final String BOOT_PATH = "/metadata/aconfig/boot/"; + + private PackageTable mPackageTable; + private FlagValueList mFlagValueList; + + private int mPackageBooleanStartOffset; + + public StorageInternalReader(String container, String packageName) { + this(packageName, MAP_PATH + container + ".package.map", BOOT_PATH + container + ".val"); + } + + public StorageInternalReader(String packageName, String packageMapFile, String flagValueFile) { + mPackageTable = PackageTable.fromBytes(mapStorageFile(packageMapFile)); + mFlagValueList = FlagValueList.fromBytes(mapStorageFile(flagValueFile)); + mPackageBooleanStartOffset = getPackageBooleanStartOffset(packageName); + } + + public boolean getBooleanFlagValue(int index) { + index += mPackageBooleanStartOffset; + if (index >= mFlagValueList.size()) { + throw new AconfigStorageException("Fail to get boolean flag value"); + } + return mFlagValueList.get(index); + } + + private int getPackageBooleanStartOffset(String packageName) { + PackageTable.Node pNode = mPackageTable.get(packageName); + if (pNode == null) { + PackageTable.Header header = mPackageTable.getHeader(); + throw new AconfigStorageException( + String.format( + "Fail to get package %s from container %s", + packageName, header.getContainer())); + } + return pNode.getBooleanStartIndex(); + } + + // Map a storage file given file path + private static MappedByteBuffer mapStorageFile(String file) { + try { + FileInputStream stream = new FileInputStream(file); + FileChannel channel = stream.getChannel(); + 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); + } + } +} diff --git a/tools/aconfig/aconfig_storage_read_api/tests/java/Android.bp b/tools/aconfig/aconfig_storage_read_api/tests/java/Android.bp index d94b2b438c..11b3824e82 100644 --- a/tools/aconfig/aconfig_storage_read_api/tests/java/Android.bp +++ b/tools/aconfig/aconfig_storage_read_api/tests/java/Android.bp @@ -1,7 +1,8 @@ android_test { name: "aconfig_storage_read_api.test.java", - srcs: ["AconfigStorageReadAPITest.java"], + srcs: ["./**/*.java"], static_libs: [ + "aconfig_storage_reader_java", "androidx.test.rules", "libaconfig_storage_read_api_java", "junit", diff --git a/tools/aconfig/aconfig_storage_read_api/tests/java/StorageInternalReaderTest.java b/tools/aconfig/aconfig_storage_read_api/tests/java/StorageInternalReaderTest.java new file mode 100644 index 0000000000..3a1bba0fad --- /dev/null +++ b/tools/aconfig/aconfig_storage_read_api/tests/java/StorageInternalReaderTest.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2024 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.aconfig.storage.test; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import android.aconfig.storage.StorageInternalReader; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +public class StorageInternalReaderTest { + + private String mStorageDir = "/data/local/tmp/aconfig_java_api_test"; + + @Test + public void testStorageInternalReader_getFlag() { + + String packageMapFile = mStorageDir + "/maps/mockup.package.map"; + String flagValueFile = mStorageDir + "/boot/mockup.val"; + + StorageInternalReader reader = + new StorageInternalReader( + "com.android.aconfig.storage.test_1", packageMapFile, flagValueFile); + assertFalse(reader.getBooleanFlagValue(0)); + assertTrue(reader.getBooleanFlagValue(1)); + } +}