Merge "Remove --blkid_path argument"
diff --git a/core/Makefile b/core/Makefile
index e2c5900..6dbbef1 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -5886,14 +5886,25 @@
echo "virtual_ab_cow_version=$(PRODUCT_VIRTUAL_AB_COW_VERSION)" >> $(1))
endef
-# Copy an image file to a directory and generate a block list map file from the image.
+# Copy an image file to a directory and generate a block list map file from the image,
+# only if the map_file_generator supports the file system.
+# Otherwise, skip generating map files as well as copying images. The image will be
+# generated from the $(ADD_IMG_TO_TARGET_FILES) to generate the map file with it.
# $(1): path of the image file
# $(2): target out directory
-# $(3): name of the map file. skip generating map file if empty
+# $(3): image name to generate a map file. skip generating map file if empty
define copy-image-and-generate-map
- mkdir -p $(2)
- cp $(1) $(2)
- $(if $(3),$(HOST_OUT_EXECUTABLES)/map_file_generator $(1) $(2)/$(3))
+ $(eval _supported_fs_for_map_file_generator := erofs ext%)
+ $(eval _img := $(call to-upper,$(3)))
+ $(if $(3),$(eval _map_fs_type := $(BOARD_$(_img)IMAGE_FILE_SYSTEM_TYPE)),\
+ $(eval _no_map_file := "true"))
+ $(if $(filter $(_supported_fs_for_map_file_generator),$(_map_fs_type))$(_no_map_file),\
+ mkdir -p $(2); \
+ cp $(1) $(2); \
+ $(if $(3),$(HOST_OUT_EXECUTABLES)/map_file_generator $(1) $(2)/$(3).map))
+ $(eval _img :=)
+ $(eval _map_fs_type :=)
+ $(eval _no_map_file :=)
endef
# By conditionally including the dependency of the target files package on the
@@ -6405,35 +6416,35 @@
@# Run fs_config on all the system, vendor, boot ramdisk,
@# and recovery ramdisk files in the zip, and save the output
ifdef BUILDING_SYSTEM_IMAGE
- $(hide) $(call copy-image-and-generate-map,$(BUILT_SYSTEMIMAGE),$(zip_root)/IMAGES,system.map)
+ $(hide) $(call copy-image-and-generate-map,$(BUILT_SYSTEMIMAGE),$(zip_root)/IMAGES,system)
$(hide) $(call fs_config,$(zip_root)/SYSTEM,system/) > $(zip_root)/META/filesystem_config.txt
endif
ifdef BUILDING_VENDOR_IMAGE
- $(hide) $(call copy-image-and-generate-map,$(BUILT_VENDORIMAGE_TARGET),$(zip_root)/IMAGES,vendor.map)
+ $(hide) $(call copy-image-and-generate-map,$(BUILT_VENDORIMAGE_TARGET),$(zip_root)/IMAGES,vendor)
$(hide) $(call fs_config,$(zip_root)/VENDOR,vendor/) > $(zip_root)/META/vendor_filesystem_config.txt
endif
ifdef BUILDING_PRODUCT_IMAGE
- $(hide) $(call copy-image-and-generate-map,$(BUILT_PRODUCTIMAGE_TARGET),$(zip_root)/IMAGES,product.map)
+ $(hide) $(call copy-image-and-generate-map,$(BUILT_PRODUCTIMAGE_TARGET),$(zip_root)/IMAGES,product)
$(hide) $(call fs_config,$(zip_root)/PRODUCT,product/) > $(zip_root)/META/product_filesystem_config.txt
endif
ifdef BUILDING_SYSTEM_EXT_IMAGE
- $(hide) $(call copy-image-and-generate-map,$(BUILT_SYSTEM_EXTIMAGE_TARGET),$(zip_root)/IMAGES,system_ext.map)
+ $(hide) $(call copy-image-and-generate-map,$(BUILT_SYSTEM_EXTIMAGE_TARGET),$(zip_root)/IMAGES,system_ext)
$(hide) $(call fs_config,$(zip_root)/SYSTEM_EXT,system_ext/) > $(zip_root)/META/system_ext_filesystem_config.txt
endif
ifdef BUILDING_ODM_IMAGE
- $(hide) $(call copy-image-and-generate-map,$(BUILT_ODMIMAGE_TARGET),$(zip_root)/IMAGES,odm.map)
+ $(hide) $(call copy-image-and-generate-map,$(BUILT_ODMIMAGE_TARGET),$(zip_root)/IMAGES,odm)
$(hide) $(call fs_config,$(zip_root)/ODM,odm/) > $(zip_root)/META/odm_filesystem_config.txt
endif
ifdef BUILDING_VENDOR_DLKM_IMAGE
- $(hide)$(call copy-image-and-generate-map,$(BUILT_VENDOR_DLKMIMAGE_TARGET),$(zip_root)/IMAGES,vendor_dlkm.map)
+ $(hide)$(call copy-image-and-generate-map,$(BUILT_VENDOR_DLKMIMAGE_TARGET),$(zip_root)/IMAGES,vendor_dlkm)
$(hide) $(call fs_config,$(zip_root)/VENDOR_DLKM,vendor_dlkm/) > $(zip_root)/META/vendor_dlkm_filesystem_config.txt
endif
ifdef BUILDING_ODM_DLKM_IMAGE
- $(hide) $(call copy-image-and-generate-map,$(BUILT_ODM_DLKMIMAGE_TARGET),$(zip_root)/IMAGES,odm_dlkm.map)
+ $(hide) $(call copy-image-and-generate-map,$(BUILT_ODM_DLKMIMAGE_TARGET),$(zip_root)/IMAGES,odm_dlkm)
$(hide) $(call fs_config,$(zip_root)/ODM_DLKM,odm_dlkm/) > $(zip_root)/META/odm_dlkm_filesystem_config.txt
endif
ifdef BUILDING_SYSTEM_DLKM_IMAGE
- $(hide) $(call copy-image-and-generate-map,$(BUILT_SYSTEM_DLKMIMAGE_TARGET),$(zip_root)/IMAGES,system_dlkm.map)
+ $(hide) $(call copy-image-and-generate-map,$(BUILT_SYSTEM_DLKMIMAGE_TARGET),$(zip_root)/IMAGES,system_dlkm)
$(hide) $(call fs_config,$(zip_root)/SYSTEM_DLKM,system_dlkm/) > $(zip_root)/META/system_dlkm_filesystem_config.txt
endif
@# ROOT always contains the files for the root under normal boot.
diff --git a/target/product/gsi/current.txt b/target/product/gsi/current.txt
index 2df85e5..c747d89 100644
--- a/target/product/gsi/current.txt
+++ b/target/product/gsi/current.txt
@@ -4,6 +4,7 @@
LLNDK: libGLESv3.so
LLNDK: libRS.so
LLNDK: libandroid_net.so
+LLNDK: libapexsupport.so
LLNDK: libbinder_ndk.so
LLNDK: libc.so
LLNDK: libcgrouprc.so
diff --git a/tools/aconfig/src/codegen_java.rs b/tools/aconfig/src/codegen_java.rs
index cf025cb..54fa0dc 100644
--- a/tools/aconfig/src/codegen_java.rs
+++ b/tools/aconfig/src/codegen_java.rs
@@ -24,43 +24,59 @@
use crate::codegen;
use crate::commands::OutputFile;
-pub fn generate_java_code(cache: &Cache) -> Result<OutputFile> {
+pub fn generate_java_code(cache: &Cache) -> Result<Vec<OutputFile>> {
let package = cache.package();
let class_elements: Vec<ClassElement> =
cache.iter().map(|item| create_class_element(package, item)).collect();
- let readwrite = class_elements.iter().any(|item| item.readwrite);
- let context = Context { package: package.to_string(), readwrite, class_elements };
+ let is_read_write = class_elements.iter().any(|item| item.is_read_write);
+ let context = Context { package_name: package.to_string(), is_read_write, class_elements };
+
+ let java_files = vec!["Flags.java", "FeatureFlagsImpl.java", "FeatureFlags.java"];
+
let mut template = TinyTemplate::new();
- template.add_template("java_code_gen", include_str!("../templates/java.template"))?;
- let contents = template.render("java_code_gen", &context)?;
- let mut path: PathBuf = package.split('.').collect();
- // TODO: Allow customization of the java class name
- path.push("Flags.java");
- Ok(OutputFile { contents: contents.into(), path })
+ template.add_template("Flags.java", include_str!("../templates/Flags.java.template"))?;
+ template.add_template(
+ "FeatureFlagsImpl.java",
+ include_str!("../templates/FeatureFlagsImpl.java.template"),
+ )?;
+ template.add_template(
+ "FeatureFlags.java",
+ include_str!("../templates/FeatureFlags.java.template"),
+ )?;
+
+ let path: PathBuf = package.split('.').collect();
+ java_files
+ .iter()
+ .map(|file| {
+ Ok(OutputFile {
+ contents: template.render(file, &context)?.into(),
+ path: path.join(file),
+ })
+ })
+ .collect::<Result<Vec<OutputFile>>>()
}
#[derive(Serialize)]
struct Context {
- pub package: String,
- pub readwrite: bool,
+ pub package_name: String,
+ pub is_read_write: bool,
pub class_elements: Vec<ClassElement>,
}
#[derive(Serialize)]
struct ClassElement {
- pub method_name: String,
- pub readwrite: bool,
pub default_value: String,
pub device_config_namespace: String,
pub device_config_flag: String,
+ pub flag_name_constant_suffix: String,
+ pub is_read_write: bool,
+ pub method_name: String,
}
fn create_class_element(package: &str, item: &Item) -> ClassElement {
let device_config_flag = codegen::create_device_config_ident(package, &item.name)
.expect("values checked at cache creation time");
ClassElement {
- method_name: item.name.replace('-', "_"),
- readwrite: item.permission == Permission::ReadWrite,
default_value: if item.state == FlagState::Enabled {
"true".to_string()
} else {
@@ -68,78 +84,100 @@
},
device_config_namespace: item.namespace.clone(),
device_config_flag,
+ flag_name_constant_suffix: item.name.to_ascii_uppercase(),
+ is_read_write: item.permission == Permission::ReadWrite,
+ method_name: item.name.clone(),
}
}
#[cfg(test)]
mod tests {
use super::*;
- use crate::aconfig::{FlagDeclaration, FlagValue};
- use crate::cache::CacheBuilder;
- use crate::commands::Source;
+ use std::collections::HashMap;
#[test]
fn test_generate_java_code() {
- let package = "com.example";
- let mut builder = CacheBuilder::new(package.to_string()).unwrap();
- builder
- .add_flag_declaration(
- Source::File("test.txt".to_string()),
- FlagDeclaration {
- name: "test".to_string(),
- namespace: "ns".to_string(),
- description: "buildtime enable".to_string(),
- },
- )
- .unwrap()
- .add_flag_declaration(
- Source::File("test2.txt".to_string()),
- FlagDeclaration {
- name: "test2".to_string(),
- namespace: "ns".to_string(),
- description: "runtime disable".to_string(),
- },
- )
- .unwrap()
- .add_flag_value(
- Source::Memory,
- FlagValue {
- package: package.to_string(),
- name: "test".to_string(),
- state: FlagState::Disabled,
- permission: Permission::ReadOnly,
- },
- )
- .unwrap();
- let cache = builder.build();
- let expect_content = r#"package com.example;
-
- import android.provider.DeviceConfig;
-
+ let cache = crate::test::create_cache();
+ let generated_files = generate_java_code(&cache).unwrap();
+ let expect_flags_content = r#"
+ package com.android.aconfig.test;
public final class Flags {
-
- public static boolean test() {
- return false;
+ public static boolean disabled_ro() {
+ return FEATURE_FLAGS.disabled_ro();
}
-
- public static boolean test2() {
- return DeviceConfig.getBoolean(
- "ns",
- "com.example.test2",
- false
- );
+ public static boolean disabled_rw() {
+ return FEATURE_FLAGS.disabled_rw();
}
+ public static boolean enabled_ro() {
+ return FEATURE_FLAGS.enabled_ro();
+ }
+ public static boolean enabled_rw() {
+ return FEATURE_FLAGS.enabled_rw();
+ }
+ private static FeatureFlags FEATURE_FLAGS = new FeatureFlagsImpl();
}
"#;
- let file = generate_java_code(&cache).unwrap();
- assert_eq!("com/example/Flags.java", file.path.to_str().unwrap());
- assert_eq!(
- None,
- crate::test::first_significant_code_diff(
- expect_content,
- &String::from_utf8(file.contents).unwrap()
- )
- );
+ let expected_featureflagsimpl_content = r#"
+ package com.android.aconfig.test;
+ import android.provider.DeviceConfig;
+ public final class FeatureFlagsImpl implements FeatureFlags {
+ @Override
+ public boolean disabled_ro() {
+ return false;
+ }
+ @Override
+ public boolean disabled_rw() {
+ return DeviceConfig.getBoolean(
+ "aconfig_test",
+ "com.android.aconfig.test.disabled_rw",
+ false
+ );
+ }
+ @Override
+ public boolean enabled_ro() {
+ return true;
+ }
+ @Override
+ public boolean enabled_rw() {
+ return DeviceConfig.getBoolean(
+ "aconfig_test",
+ "com.android.aconfig.test.enabled_rw",
+ true
+ );
+ }
+ }
+ "#;
+ let expected_featureflags_content = r#"
+ package com.android.aconfig.test;
+ public interface FeatureFlags {
+ boolean disabled_ro();
+ boolean disabled_rw();
+ boolean enabled_ro();
+ boolean enabled_rw();
+ }
+ "#;
+ let mut file_set = HashMap::from([
+ ("com/android/aconfig/test/Flags.java", expect_flags_content),
+ ("com/android/aconfig/test/FeatureFlagsImpl.java", expected_featureflagsimpl_content),
+ ("com/android/aconfig/test/FeatureFlags.java", expected_featureflags_content),
+ ]);
+
+ for file in generated_files {
+ let file_path = file.path.to_str().unwrap();
+ assert!(file_set.contains_key(file_path), "Cannot find {}", file_path);
+ assert_eq!(
+ None,
+ crate::test::first_significant_code_diff(
+ file_set.get(file_path).unwrap(),
+ &String::from_utf8(file.contents.clone()).unwrap()
+ ),
+ "File {} content is not correct",
+ file_path
+ );
+ file_set.remove(file_path);
+ }
+
+ assert!(file_set.is_empty());
}
}
diff --git a/tools/aconfig/src/commands.rs b/tools/aconfig/src/commands.rs
index 586ba04..eb860b0 100644
--- a/tools/aconfig/src/commands.rs
+++ b/tools/aconfig/src/commands.rs
@@ -89,7 +89,7 @@
Ok(builder.build())
}
-pub fn create_java_lib(cache: Cache) -> Result<OutputFile> {
+pub fn create_java_lib(cache: Cache) -> Result<Vec<OutputFile>> {
generate_java_code(&cache)
}
diff --git a/tools/aconfig/src/main.rs b/tools/aconfig/src/main.rs
index 5a820d9..3a9a573 100644
--- a/tools/aconfig/src/main.rs
+++ b/tools/aconfig/src/main.rs
@@ -147,8 +147,10 @@
let file = fs::File::open(path)?;
let cache = Cache::read_from_reader(file)?;
let dir = PathBuf::from(get_required_arg::<String>(sub_matches, "out")?);
- let generated_file = commands::create_java_lib(cache)?;
- write_output_file_realtive_to_dir(&dir, &generated_file)?;
+ let generated_files = commands::create_java_lib(cache)?;
+ generated_files
+ .iter()
+ .try_for_each(|file| write_output_file_realtive_to_dir(&dir, file))?;
}
Some(("create-cpp-lib", sub_matches)) => {
let path = get_required_arg::<String>(sub_matches, "cache")?;
diff --git a/tools/aconfig/templates/FeatureFlags.java.template b/tools/aconfig/templates/FeatureFlags.java.template
new file mode 100644
index 0000000..b9e2cc7
--- /dev/null
+++ b/tools/aconfig/templates/FeatureFlags.java.template
@@ -0,0 +1,7 @@
+package {package_name};
+
+public interface FeatureFlags \{
+ {{ for item in class_elements}}
+ boolean {item.method_name}();
+ {{ endfor }}
+}
\ No newline at end of file
diff --git a/tools/aconfig/templates/java.template b/tools/aconfig/templates/FeatureFlagsImpl.java.template
similarity index 63%
rename from tools/aconfig/templates/java.template
rename to tools/aconfig/templates/FeatureFlagsImpl.java.template
index a3d3319..2b031f1 100644
--- a/tools/aconfig/templates/java.template
+++ b/tools/aconfig/templates/FeatureFlagsImpl.java.template
@@ -1,11 +1,12 @@
-package {package};
-{{ if readwrite }}
+package {package_name};
+{{ if is_read_write }}
import android.provider.DeviceConfig;
{{ endif }}
-public final class Flags \{
+public final class FeatureFlagsImpl implements FeatureFlags \{
{{ for item in class_elements}}
- public static boolean {item.method_name}() \{
- {{ if item.readwrite- }}
+ @Override
+ public boolean {item.method_name}() \{
+ {{ if item.is_read_write- }}
return DeviceConfig.getBoolean(
"{item.device_config_namespace}",
"{item.device_config_flag}",
@@ -16,4 +17,4 @@
{{ -endif }}
}
{{ endfor }}
-}
+}
\ No newline at end of file
diff --git a/tools/aconfig/templates/Flags.java.template b/tools/aconfig/templates/Flags.java.template
new file mode 100644
index 0000000..752a469
--- /dev/null
+++ b/tools/aconfig/templates/Flags.java.template
@@ -0,0 +1,11 @@
+package {package_name};
+
+public final class Flags \{
+ {{ for item in class_elements}}
+ public static boolean {item.method_name}() \{
+ return FEATURE_FLAGS.{item.method_name}();
+ }
+ {{ endfor }}
+ private static FeatureFlags FEATURE_FLAGS = new FeatureFlagsImpl();
+
+}
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index f92d67c..d33397b 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -2126,17 +2126,28 @@
"""
with zipfile.ZipFile(filename, allowZip64=True, mode="r") as input_zip:
# Filter out non-matching patterns. unzip will complain otherwise.
+ entries = input_zip.infolist()
+ # b/283033491
+ # Per https://en.wikipedia.org/wiki/ZIP_(file_format)#Central_directory_file_header
+ # In zip64 mode, central directory record's header_offset field might be
+ # set to 0xFFFFFFFF if header offset is > 2^32. In this case, the extra
+ # fields will contain an 8 byte little endian integer at offset 20
+ # to indicate the actual local header offset.
+ # As of python3.11, python does not handle zip64 central directories
+ # correctly, so we will manually do the parsing here.
+ for entry in entries:
+ if entry.header_offset == 0xFFFFFFFF and len(entry.extra) >= 28:
+ entry.header_offset = int.from_bytes(entry.extra[20:28], "little")
if patterns is not None:
- names = input_zip.namelist()
- filtered = [name for name in names if any(
- [fnmatch.fnmatch(name, p) for p in patterns])]
+ filtered = [info for info in entries if any(
+ [fnmatch.fnmatch(info.filename, p) for p in patterns])]
# There isn't any matching files. Don't unzip anything.
if not filtered:
return
input_zip.extractall(dirname, filtered)
else:
- input_zip.extractall(dirname)
+ input_zip.extractall(dirname, entries)
def UnzipTemp(filename, patterns=None):
diff --git a/tools/releasetools/ota_utils.py b/tools/releasetools/ota_utils.py
index 466cafb..68c6887 100644
--- a/tools/releasetools/ota_utils.py
+++ b/tools/releasetools/ota_utils.py
@@ -762,6 +762,9 @@
path = os.path.join(target_files_dir, "RADIO", partition + ".map")
if os.path.exists(path):
return path
+ path = os.path.join(target_files_dir, "IMAGES", partition + ".map")
+ if os.path.exists(path):
+ return path
return ""