Merge "core/Makefile: Add desktop pack image hook." into main
diff --git a/core/main.mk b/core/main.mk
index f3980f1..8d73793 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -688,11 +688,16 @@
$(eval my_testcases := $(HOST_OUT_TESTCASES)),\
$(eval my_testcases := $$(COMPATIBILITY_TESTCASES_OUT_$(suite))))\
$(eval target := $(my_testcases)/$(lastword $(subst /, ,$(dir $(f))))/$(notdir $(f)))\
+ $(eval link_target := ../../../$(lastword $(subst /, ,$(dir $(f))))/$(notdir $(f)))\
+ $(eval symlink := $(my_testcases)/$(m)/shared_libs/$(lastword $(subst /, ,$(dir $(f))))/$(notdir $(f)))\
+ $(eval COMPATIBILITY.$(suite).SYMLINKS := \
+ $$(COMPATIBILITY.$(suite).SYMLINKS) $(f):$(link_target):$(symlink))\
$(if $(strip $(ALL_TARGETS.$(target).META_LIC)),,$(call declare-copy-target-license-metadata,$(target),$(f)))\
$(eval COMPATIBILITY.$(suite).HOST_SHARED_LIBRARY.FILES := \
$$(COMPATIBILITY.$(suite).HOST_SHARED_LIBRARY.FILES) $(f):$(target))\
$(eval COMPATIBILITY.$(suite).HOST_SHARED_LIBRARY.FILES := \
- $(sort $(COMPATIBILITY.$(suite).HOST_SHARED_LIBRARY.FILES)))))))
+ $(sort $(COMPATIBILITY.$(suite).HOST_SHARED_LIBRARY.FILES))))))\
+ $(eval COMPATIBILITY.$(suite).SYMLINKS := $(sort $(COMPATIBILITY.$(suite).SYMLINKS))))
endef
$(call resolve-shared-libs-depes,TARGET_)
diff --git a/core/tasks/host-unit-tests.mk b/core/tasks/host-unit-tests.mk
index 733a2e2..4cb23c0 100644
--- a/core/tasks/host-unit-tests.mk
+++ b/core/tasks/host-unit-tests.mk
@@ -29,15 +29,28 @@
$(eval _cmf_src := $(word 1,$(_cmf_tuple))) \
$(_cmf_src)))
+my_symlinks_for_host_unit_tests := $(foreach f,$(COMPATIBILITY.host-unit-tests.SYMLINKS),\
+ $(strip $(eval _cmf_tuple := $(subst :, ,$(f))) \
+ $(eval _cmf_dep := $(word 1,$(_cmf_tuple))) \
+ $(eval _cmf_src := $(word 2,$(_cmf_tuple))) \
+ $(eval _cmf_dest := $(word 3,$(_cmf_tuple))) \
+ $(call symlink-file,$(_cmf_dep),$(_cmf_src),$(_cmf_dest)) \
+ $(_cmf_dest)))
+
$(host_unit_tests_zip) : PRIVATE_HOST_SHARED_LIBS := $(my_host_shared_lib_for_host_unit_tests)
-$(host_unit_tests_zip) : $(COMPATIBILITY.host-unit-tests.FILES) $(my_host_shared_lib_for_host_unit_tests) $(SOONG_ZIP)
+$(host_unit_tests_zip) : PRIVATE_SYMLINKS := $(my_symlinks_for_host_unit_tests)
+
+$(host_unit_tests_zip) : $(COMPATIBILITY.host-unit-tests.FILES) $(my_host_shared_lib_for_host_unit_tests) $(my_symlinks_for_host_unit_tests) $(SOONG_ZIP)
echo $(sort $(COMPATIBILITY.host-unit-tests.FILES)) | tr " " "\n" > $@.list
grep $(HOST_OUT_TESTCASES) $@.list > $@-host.list || true
echo "" >> $@-host-libs.list
$(hide) for shared_lib in $(PRIVATE_HOST_SHARED_LIBS); do \
echo $$shared_lib >> $@-host-libs.list; \
done
+ $(hide) for symlink in $(PRIVATE_SYMLINKS); do \
+ echo $$symlink >> $@-host.list; \
+ done
grep $(TARGET_OUT_TESTCASES) $@.list > $@-target.list || true
$(hide) $(SOONG_ZIP) -d -o $@ -P host -C $(HOST_OUT) -l $@-host.list \
-P target -C $(PRODUCT_OUT) -l $@-target.list \
diff --git a/target/product/virtual_ab_ota/OWNERS b/target/product/virtual_ab_ota/OWNERS
new file mode 100644
index 0000000..8eb0686
--- /dev/null
+++ b/target/product/virtual_ab_ota/OWNERS
@@ -0,0 +1,4 @@
+zhangkelvin@google.com
+dvander@google.com
+akailash@google.com
+
diff --git a/tools/aconfig/aconfig_storage_read_api/Android.bp b/tools/aconfig/aconfig_storage_read_api/Android.bp
index 5e9eb54..c2f4c18 100644
--- a/tools/aconfig/aconfig_storage_read_api/Android.bp
+++ b/tools/aconfig/aconfig_storage_read_api/Android.bp
@@ -154,7 +154,9 @@
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 @@
"//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 0000000..5f31017
--- /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 d94b2b4..11b3824 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 0000000..3a1bba0
--- /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));
+ }
+}