Merge "add new storage sub libray" into main
diff --git a/ci/build_device_and_tests b/ci/build_device_and_tests
new file mode 100755
index 0000000..9d11268
--- /dev/null
+++ b/ci/build_device_and_tests
@@ -0,0 +1,18 @@
+#!/usr/bin/env bash
+#
+# Copyright 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.
+
+build/soong/soong_ui.bash --make-mode build_test_suites || exit $?
+$(build/soong/soong_ui.bash --dumpvar-mode HOST_OUT)/bin/build_test_suites $@ || exit $?
diff --git a/core/definitions.mk b/core/definitions.mk
index cd1b36e..7a32464 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -2605,7 +2605,17 @@
@$(call emit-line,$(wordlist 108501,109000,$(1)),$(2))
@$(call emit-line,$(wordlist 109001,109500,$(1)),$(2))
@$(call emit-line,$(wordlist 109501,110000,$(1)),$(2))
- @$(if $(wordlist 110001,110002,$(1)),$(error dump-words-to-file: Too many words ($(words $(1)))))
+ @$(call emit-line,$(wordlist 110001,110500,$(1)),$(2))
+ @$(call emit-line,$(wordlist 110501,111000,$(1)),$(2))
+ @$(call emit-line,$(wordlist 111001,111500,$(1)),$(2))
+ @$(call emit-line,$(wordlist 111501,112000,$(1)),$(2))
+ @$(call emit-line,$(wordlist 112001,112500,$(1)),$(2))
+ @$(call emit-line,$(wordlist 112501,113000,$(1)),$(2))
+ @$(call emit-line,$(wordlist 113001,113500,$(1)),$(2))
+ @$(call emit-line,$(wordlist 113501,114000,$(1)),$(2))
+ @$(call emit-line,$(wordlist 114001,114500,$(1)),$(2))
+ @$(call emit-line,$(wordlist 114501,115000,$(1)),$(2))
+ @$(if $(wordlist 115001,115002,$(1)),$(error dump-words-to-file: Too many words ($(words $(1)))))
endef
# Return jar arguments to compress files in a given directory
# $(1): directory
diff --git a/core/java_common.mk b/core/java_common.mk
index a21f062..f574b76 100644
--- a/core/java_common.mk
+++ b/core/java_common.mk
@@ -32,7 +32,7 @@
else ifneq (,$(LOCAL_SDK_VERSION)$(TARGET_BUILD_USE_PREBUILT_SDKS))
# TODO(ccross): allow 1.9 for current and unbundled once we have SDK system modules
LOCAL_JAVA_LANGUAGE_VERSION := 1.8
- else ifeq ($(EXPERIMENTAL_TARGET_JAVA_VERSION_21),true)
+ else ifeq ($(RELEASE_TARGET_JAVA_21),true)
LOCAL_JAVA_LANGUAGE_VERSION := 21
else
LOCAL_JAVA_LANGUAGE_VERSION := 17
diff --git a/core/soong_config.mk b/core/soong_config.mk
index 2f69d06..32ca660 100644
--- a/core/soong_config.mk
+++ b/core/soong_config.mk
@@ -437,7 +437,7 @@
$(call add_json_str, BoardPrebuiltBootimage, $(BOARD_PREBUILT_BOOT_IMAGE))
$(call add_json_str, BoardPrebuiltInitBootimage, $(BOARD_PREBUILT_INIT_BOOT_IMAGE))
$(call add_json_str, BoardBootimagePartitionSize, $(BOARD_BOOTIMAGE_PARTITION_SIZE))
- $(call add_json_str, BoardInitBootimagePartitionSize, $(BOARD_INIT_BOOTIMAGE_PARTITION_SIZE))
+ $(call add_json_str, BoardInitBootimagePartitionSize, $(BOARD_INIT_BOOT_IMAGE_PARTITION_SIZE))
$(call add_json_str, BoardBootHeaderVersion, $(BOARD_BOOT_HEADER_VERSION))
$(call add_json_str, TargetKernelPath, $(TARGET_KERNEL_PATH))
$(call add_json_bool, BoardUsesGenericKernelImage, $(BOARD_USES_GENERIC_KERNEL_IMAGE))
diff --git a/target/product/generic/Android.bp b/target/product/generic/Android.bp
index b1c3def..5451042 100644
--- a/target/product/generic/Android.bp
+++ b/target/product/generic/Android.bp
@@ -56,10 +56,6 @@
name: "bugreports",
},
{
- target: "/data/cache",
- name: "cache",
- },
- {
target: "/sys/kernel/debug",
name: "d",
},
@@ -125,6 +121,10 @@
target: "/system_ext",
name: "system/system_ext",
},
+ {
+ target: "/data/cache",
+ name: "cache",
+ },
]
filegroup {
@@ -346,11 +346,6 @@
],
}
-filegroup {
- name: "system_image_erofs_compress_hints.txt",
- srcs: ["erofs_compress_hints.txt"],
-}
-
android_filesystem_defaults {
name: "system_image_defaults",
partition_name: "system",
@@ -374,11 +369,6 @@
],
libs: [":framework-res{.export-package.apk}"],
},
- type: "erofs",
- erofs: {
- compressor: "lz4hc,9",
- compress_hints: ":system_image_erofs_compress_hints.txt",
- },
build_logtags: true,
gen_aconfig_flags_pb: true,
@@ -889,4 +879,9 @@
defaults: ["system_image_defaults"],
dirs: android_rootdirs,
symlinks: android_symlinks,
+ type: "erofs",
+ erofs: {
+ compressor: "lz4hc,9",
+ compress_hints: "erofs_compress_hints.txt",
+ },
}
diff --git a/target/product/gsi/Android.bp b/target/product/gsi/Android.bp
index 1b8f2d7..9e8946d 100644
--- a/target/product/gsi/Android.bp
+++ b/target/product/gsi/Android.bp
@@ -71,12 +71,21 @@
target: "/system/product",
name: "product",
},
+ {
+ target: "/odm/odm_dlkm/etc",
+ name: "odm_dlkm/etc",
+ },
+ {
+ target: "/vendor/vendor_dlkm/etc",
+ name: "vendor_dlkm/etc",
+ },
]
android_system_image {
name: "android_gsi",
defaults: ["system_image_defaults"],
symlinks: gsi_symlinks,
+ dirs: ["cache"],
deps: [
///////////////////////////////////////////
// gsi_system_ext
@@ -196,4 +205,5 @@
"true": true,
default: false,
}),
+ type: "ext4",
}
diff --git a/tools/aconfig/aconfig/src/codegen/java.rs b/tools/aconfig/aconfig/src/codegen/java.rs
index e2bb1ad..bfdf1a7 100644
--- a/tools/aconfig/aconfig/src/codegen/java.rs
+++ b/tools/aconfig/aconfig/src/codegen/java.rs
@@ -513,11 +513,19 @@
package com.android.aconfig.test;
// TODO(b/303773055): Remove the annotation after access issue is resolved.
import android.compat.annotation.UnsupportedAppUsage;
+ import android.os.Binder;
+ import android.provider.DeviceConfig;
+ import android.provider.DeviceConfig.Properties;
import android.aconfig.storage.StorageInternalReader;
+ import java.nio.file.Files;
+ import java.nio.file.Paths;
/** @hide */
public final class FeatureFlagsImpl implements FeatureFlags {
+ private static final boolean isReadFromNew = Files.exists(Paths.get("/metadata/aconfig/boot/enable_only_new_storage"));
private static volatile boolean isCached = false;
+ private static volatile boolean aconfig_test_is_cached = false;
+ private static volatile boolean other_namespace_is_cached = false;
private static boolean disabledRw = false;
private static boolean disabledRwExported = false;
private static boolean disabledRwInOtherNamespace = false;
@@ -536,6 +544,55 @@
disabledRwInOtherNamespace = foundPackage ? reader.getBooleanFlagValue(3) : false;
isCached = true;
}
+ private void load_overrides_aconfig_test() {
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ Properties properties = DeviceConfig.getProperties("aconfig_test");
+ disabledRw =
+ properties.getBoolean(Flags.FLAG_DISABLED_RW, false);
+ disabledRwExported =
+ properties.getBoolean(Flags.FLAG_DISABLED_RW_EXPORTED, false);
+ enabledRw =
+ properties.getBoolean(Flags.FLAG_ENABLED_RW, true);
+ } catch (NullPointerException e) {
+ throw new RuntimeException(
+ "Cannot read value from namespace aconfig_test "
+ + "from DeviceConfig. It could be that the code using flag "
+ + "executed before SettingsProvider initialization. Please use "
+ + "fixed read-only flag by adding is_fixed_read_only: true in "
+ + "flag declaration.",
+ e
+ );
+ } catch (SecurityException e) {
+ // for isolated process case, skip loading flag value from the storage, use the default
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ aconfig_test_is_cached = true;
+ }
+
+ private void load_overrides_other_namespace() {
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ Properties properties = DeviceConfig.getProperties("other_namespace");
+ disabledRwInOtherNamespace =
+ properties.getBoolean(Flags.FLAG_DISABLED_RW_IN_OTHER_NAMESPACE, false);
+ } catch (NullPointerException e) {
+ throw new RuntimeException(
+ "Cannot read value from namespace other_namespace "
+ + "from DeviceConfig. It could be that the code using flag "
+ + "executed before SettingsProvider initialization. Please use "
+ + "fixed read-only flag by adding is_fixed_read_only: true in "
+ + "flag declaration.",
+ e
+ );
+ } catch (SecurityException e) {
+ // for isolated process case, skip loading flag value from the storage, use the default
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ other_namespace_is_cached = true;
+ }
@Override
@com.android.aconfig.annotations.AconfigFlagAccessor
@@ -547,8 +604,14 @@
@com.android.aconfig.annotations.AconfigFlagAccessor
@UnsupportedAppUsage
public boolean disabledRw() {
- if (!isCached) {
- init();
+ if (isReadFromNew) {
+ if (!isCached) {
+ init();
+ }
+ } else {
+ if (!aconfig_test_is_cached) {
+ load_overrides_aconfig_test();
+ }
}
return disabledRw;
}
@@ -556,8 +619,14 @@
@com.android.aconfig.annotations.AconfigFlagAccessor
@UnsupportedAppUsage
public boolean disabledRwExported() {
- if (!isCached) {
- init();
+ if (isReadFromNew) {
+ if (!isCached) {
+ init();
+ }
+ } else {
+ if (!aconfig_test_is_cached) {
+ load_overrides_aconfig_test();
+ }
}
return disabledRwExported;
}
@@ -565,8 +634,14 @@
@com.android.aconfig.annotations.AconfigFlagAccessor
@UnsupportedAppUsage
public boolean disabledRwInOtherNamespace() {
- if (!isCached) {
- init();
+ if (isReadFromNew) {
+ if (!isCached) {
+ init();
+ }
+ } else {
+ if (!other_namespace_is_cached) {
+ load_overrides_other_namespace();
+ }
}
return disabledRwInOtherNamespace;
}
@@ -598,8 +673,14 @@
@com.android.aconfig.annotations.AconfigFlagAccessor
@UnsupportedAppUsage
public boolean enabledRw() {
- if (!isCached) {
- init();
+ if (isReadFromNew) {
+ if (!isCached) {
+ init();
+ }
+ } else {
+ if (!aconfig_test_is_cached) {
+ load_overrides_aconfig_test();
+ }
}
return enabledRw;
}
diff --git a/tools/aconfig/aconfig/src/storage/mod.rs b/tools/aconfig/aconfig/src/storage/mod.rs
index ef1b4f6..4bc72f7 100644
--- a/tools/aconfig/aconfig/src/storage/mod.rs
+++ b/tools/aconfig/aconfig/src/storage/mod.rs
@@ -83,7 +83,7 @@
p.boolean_start_index = boolean_start_index;
boolean_start_index += p.boolean_flags.len() as u32;
- if version > 2 {
+ if version >= 2 {
let mut flag_names_vec =
p.flag_names.clone().into_iter().map(String::from).collect::<Vec<_>>();
let fingerprint = compute_flags_fingerprint(&mut flag_names_vec);
@@ -202,6 +202,7 @@
assert!(packages[0].flag_names.contains("disabled_rw"));
assert!(packages[0].flag_names.contains("enabled_ro"));
assert_eq!(packages[0].boolean_start_index, 0);
+ assert_eq!(packages[0].fingerprint, 0);
assert_eq!(packages[1].package_name, "com.android.aconfig.storage.test_2");
assert_eq!(packages[1].package_id, 1);
@@ -210,6 +211,7 @@
assert!(packages[1].flag_names.contains("disabled_rw"));
assert!(packages[1].flag_names.contains("enabled_fixed_ro"));
assert_eq!(packages[1].boolean_start_index, 3);
+ assert_eq!(packages[0].fingerprint, 0);
assert_eq!(packages[2].package_name, "com.android.aconfig.storage.test_4");
assert_eq!(packages[2].package_id, 2);
@@ -217,5 +219,49 @@
assert!(packages[2].flag_names.contains("enabled_rw"));
assert!(packages[2].flag_names.contains("enabled_fixed_ro"));
assert_eq!(packages[2].boolean_start_index, 6);
+ assert_eq!(packages[2].fingerprint, 0);
+ }
+
+ #[test]
+ fn test_flag_package_with_fingerprint() {
+ let caches = parse_all_test_flags();
+ let packages = group_flags_by_package(caches.iter(), 2);
+
+ for pkg in packages.iter() {
+ let pkg_name = pkg.package_name;
+ assert_eq!(pkg.flag_names.len(), pkg.boolean_flags.len());
+ for pf in pkg.boolean_flags.iter() {
+ assert!(pkg.flag_names.contains(pf.name()));
+ assert_eq!(pf.package(), pkg_name);
+ }
+ }
+
+ assert_eq!(packages.len(), 3);
+
+ assert_eq!(packages[0].package_name, "com.android.aconfig.storage.test_1");
+ assert_eq!(packages[0].package_id, 0);
+ assert_eq!(packages[0].flag_names.len(), 3);
+ assert!(packages[0].flag_names.contains("enabled_rw"));
+ assert!(packages[0].flag_names.contains("disabled_rw"));
+ assert!(packages[0].flag_names.contains("enabled_ro"));
+ assert_eq!(packages[0].boolean_start_index, 0);
+ assert_eq!(packages[0].fingerprint, 15248948510590158086u64);
+
+ assert_eq!(packages[1].package_name, "com.android.aconfig.storage.test_2");
+ assert_eq!(packages[1].package_id, 1);
+ assert_eq!(packages[1].flag_names.len(), 3);
+ assert!(packages[1].flag_names.contains("enabled_ro"));
+ assert!(packages[1].flag_names.contains("disabled_rw"));
+ assert!(packages[1].flag_names.contains("enabled_fixed_ro"));
+ assert_eq!(packages[1].boolean_start_index, 3);
+ assert_eq!(packages[1].fingerprint, 4431940502274857964u64);
+
+ assert_eq!(packages[2].package_name, "com.android.aconfig.storage.test_4");
+ assert_eq!(packages[2].package_id, 2);
+ assert_eq!(packages[2].flag_names.len(), 2);
+ assert!(packages[2].flag_names.contains("enabled_rw"));
+ assert!(packages[2].flag_names.contains("enabled_fixed_ro"));
+ assert_eq!(packages[2].boolean_start_index, 6);
+ assert_eq!(packages[2].fingerprint, 16233229917711622375u64);
}
}
diff --git a/tools/aconfig/aconfig/templates/FeatureFlagsImpl.java.template b/tools/aconfig/aconfig/templates/FeatureFlagsImpl.java.template
index d782f81..cb52150 100644
--- a/tools/aconfig/aconfig/templates/FeatureFlagsImpl.java.template
+++ b/tools/aconfig/aconfig/templates/FeatureFlagsImpl.java.template
@@ -1,22 +1,41 @@
package {package_name};
{{ -if not is_test_mode }}
{{ -if allow_instrumentation }}
-{{ if not library_exported- }}{#- only new storage for prod mode #}
+{{ if not library_exported- }}
// TODO(b/303773055): Remove the annotation after access issue is resolved.
import android.compat.annotation.UnsupportedAppUsage;
+{{ -endif }}
+
{{ -if runtime_lookup_required }}
+import android.os.Binder;
+import android.provider.DeviceConfig;
+import android.provider.DeviceConfig.Properties;
+
+{{ -if not library_exported }}
import android.aconfig.storage.StorageInternalReader;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+{{ -endif }}
+
{{ -endif }}
/** @hide */
public final class FeatureFlagsImpl implements FeatureFlags \{
{{ -if runtime_lookup_required }}
+{{ -if not library_exported }}
+ private static final boolean isReadFromNew = Files.exists(Paths.get("/metadata/aconfig/boot/enable_only_new_storage"));
private static volatile boolean isCached = false;
+{{ -endif }}
+{{ -for namespace_with_flags in namespace_flags }}
+ private static volatile boolean {namespace_with_flags.namespace}_is_cached = false;
+{{ -endfor- }}
+
{{ for flag in flag_elements }}
{{ -if flag.is_read_write }}
private static boolean {flag.method_name} = {flag.default_value};
{{ -endif }}
{{ -endfor }}
+{{ if not library_exported }}
private void init() \{
StorageInternalReader reader = null;
boolean foundPackage = true;
@@ -34,37 +53,9 @@
{{ -endfor }}
isCached = true;
}
-{{ -endif }}{#- end of runtime_lookup_required #}
-{{ -for flag in flag_elements }}
- @Override
- @com.android.aconfig.annotations.AconfigFlagAccessor
- @UnsupportedAppUsage
- public boolean {flag.method_name}() \{
-{{ -if flag.is_read_write }}
- if (!isCached) \{
- init();
- }
- return {flag.method_name};
-{{ -else }}
- return {flag.default_value};
-{{ -endif }}
- }
-{{ endfor }}
-}
-{{ -else- }}{#- device config for exproted mode #}
-import android.os.Binder;
-import android.provider.DeviceConfig;
-import android.provider.DeviceConfig.Properties;
-/** @hide */
-public final class FeatureFlagsImpl implements FeatureFlags \{
-{{ -for namespace_with_flags in namespace_flags }}
- private static volatile boolean {namespace_with_flags.namespace}_is_cached = false;
-{{ -endfor- }}
-{{ for flag in flag_elements }}
-{{ -if flag.is_read_write }}
- private static boolean {flag.method_name} = {flag.default_value};
-{{ -endif }}
-{{ -endfor }}
+{{ endif }}
+
+
{{ for namespace_with_flags in namespace_flags }}
private void load_overrides_{namespace_with_flags.namespace}() \{
final long ident = Binder.clearCallingIdentity();
@@ -93,17 +84,40 @@
{namespace_with_flags.namespace}_is_cached = true;
}
{{ endfor- }}
+
+{{ -endif }}{#- end of runtime_lookup_required #}
{{ -for flag in flag_elements }}
@Override
+{{ -if not library_exported }}
+ @com.android.aconfig.annotations.AconfigFlagAccessor
+ @UnsupportedAppUsage
+{{ -endif }}
public boolean {flag.method_name}() \{
+{{ -if not library_exported }}
+{{ -if flag.is_read_write }}
+ if (isReadFromNew) \{
+ if (!isCached) \{
+ init();
+ }
+ } else \{
+ if (!{flag.device_config_namespace}_is_cached) \{
+ load_overrides_{flag.device_config_namespace}();
+ }
+ }
+ return {flag.method_name};
+{{ -else }}
+ return {flag.default_value};
+{{ -endif }}
+{{ else }}
if (!{flag.device_config_namespace}_is_cached) \{
load_overrides_{flag.device_config_namespace}();
}
return {flag.method_name};
+{{ -endif }}
}
{{ endfor }}
}
-{{ -endif- }} {#- end exported mode #}
+
{{ else }} {#- else for allow_instrumentation is not enabled #}
{{ if not library_exported- }}
// TODO(b/303773055): Remove the annotation after access issue is resolved.