Merge "switch to using DIST_DIR env var for dist" into main
diff --git a/core/config.mk b/core/config.mk
index d7516d3..daefa70 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -407,35 +407,22 @@
else ifeq ($(strip $(call is-low-mem-device)),true)
# Low memory device will have 4096 binary alignment.
TARGET_MAX_PAGE_SIZE_SUPPORTED := 4096
-else
- # The default binary alignment for userspace is 4096.
+else ifeq ($(call math_lt,$(VSR_VENDOR_API_LEVEL),34),true)
TARGET_MAX_PAGE_SIZE_SUPPORTED := 4096
- # When VSR vendor API level >= 34, binary alignment will be 65536.
- ifeq ($(call math_gt_or_eq,$(VSR_VENDOR_API_LEVEL),34),true)
- ifeq ($(TARGET_ARCH),arm64)
- TARGET_MAX_PAGE_SIZE_SUPPORTED := 65536
- endif
- endif
+else ifeq (,$(filter arm64 x86_64,$(TARGET_ARCH)))
+ # TARGET_MAX_PAGE_SIZE_SUPPORTED > 4096 is only supported in arm64 and
+ # x86_64 targets.
+ TARGET_MAX_PAGE_SIZE_SUPPORTED := 4096
+else
+ # The default binary alignment for userspace is 16384.
+ TARGET_MAX_PAGE_SIZE_SUPPORTED := 16384
endif
.KATI_READONLY := TARGET_MAX_PAGE_SIZE_SUPPORTED
-# Only arm64 and x86_64 archs supports TARGET_MAX_PAGE_SIZE_SUPPORTED greater than 4096.
-ifneq ($(TARGET_MAX_PAGE_SIZE_SUPPORTED),4096)
- ifeq (,$(filter arm64 x86_64,$(TARGET_ARCH)))
- $(error TARGET_MAX_PAGE_SIZE_SUPPORTED=$(TARGET_MAX_PAGE_SIZE_SUPPORTED) is greater than 4096. Only supported in arm64 and x86_64 archs)
- endif
-endif
-
-# Boolean variable determining if AOSP is page size agnostic. This means
-# that AOSP can use a kernel configured with 4k/16k/64k PAGE SIZES.
+# Boolean variable determining if AOSP relies on bionic's PAGE_SIZE macro.
TARGET_NO_BIONIC_PAGE_SIZE_MACRO := false
ifdef PRODUCT_NO_BIONIC_PAGE_SIZE_MACRO
TARGET_NO_BIONIC_PAGE_SIZE_MACRO := $(PRODUCT_NO_BIONIC_PAGE_SIZE_MACRO)
- ifeq ($(TARGET_NO_BIONIC_PAGE_SIZE_MACRO),true)
- ifneq ($(TARGET_MAX_PAGE_SIZE_SUPPORTED),65536)
- $(error TARGET_MAX_PAGE_SIZE_SUPPORTED has to be 65536 to support page size agnostic)
- endif
- endif
endif
.KATI_READONLY := TARGET_NO_BIONIC_PAGE_SIZE_MACRO
diff --git a/core/envsetup.mk b/core/envsetup.mk
index 30a6c06..7f9cbad 100644
--- a/core/envsetup.mk
+++ b/core/envsetup.mk
@@ -789,6 +789,7 @@
TARGET_OUT_ODM_APPS := $(target_out_odm_app_base)/app
TARGET_OUT_ODM_APPS_PRIVILEGED := $(target_out_odm_app_base)/priv-app
TARGET_OUT_ODM_ETC := $(TARGET_OUT_ODM)/etc
+TARGET_OUT_ODM_FAKE := $(PRODUCT_OUT)/odm_fake_packages
.KATI_READONLY := \
TARGET_OUT_ODM \
TARGET_OUT_ODM_EXECUTABLES \
@@ -798,7 +799,8 @@
TARGET_OUT_ODM_JAVA_LIBRARIES \
TARGET_OUT_ODM_APPS \
TARGET_OUT_ODM_APPS_PRIVILEGED \
- TARGET_OUT_ODM_ETC
+ TARGET_OUT_ODM_ETC \
+ TARGET_OUT_ODM_FAKE
$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_ODM_EXECUTABLES := $(TARGET_OUT_ODM_EXECUTABLES)
$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_ODM_SHARED_LIBRARIES := $(target_out_odm_shared_libraries_base)/lib
@@ -936,13 +938,15 @@
TARGET_OUT_PRODUCT_APPS := $(target_out_product_app_base)/app
TARGET_OUT_PRODUCT_APPS_PRIVILEGED := $(target_out_product_app_base)/priv-app
TARGET_OUT_PRODUCT_ETC := $(TARGET_OUT_PRODUCT)/etc
+TARGET_OUT_PRODUCT_FAKE := $(TARGET_OUT_PRODUCT)/product_fake_packages
.KATI_READONLY := \
TARGET_OUT_PRODUCT_EXECUTABLES \
TARGET_OUT_PRODUCT_SHARED_LIBRARIES \
TARGET_OUT_PRODUCT_JAVA_LIBRARIES \
TARGET_OUT_PRODUCT_APPS \
TARGET_OUT_PRODUCT_APPS_PRIVILEGED \
- TARGET_OUT_PRODUCT_ETC
+ TARGET_OUT_PRODUCT_ETC \
+ TARGET_OUT_PRODUCT_FAKE
$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_PRODUCT_EXECUTABLES := $(TARGET_OUT_PRODUCT_EXECUTABLES)
$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_PRODUCT_SHARED_LIBRARIES := $(target_out_product_shared_libraries_base)/lib
@@ -979,13 +983,15 @@
TARGET_OUT_SYSTEM_EXT_APPS_PRIVILEGED := $(target_out_system_ext_app_base)/priv-app
TARGET_OUT_SYSTEM_EXT_ETC := $(TARGET_OUT_SYSTEM_EXT)/etc
TARGET_OUT_SYSTEM_EXT_EXECUTABLES := $(TARGET_OUT_SYSTEM_EXT)/bin
+TARGET_OUT_SYSTEM_EXT_FAKE := $(PRODUCT_OUT)/system_ext_fake_packages
.KATI_READONLY := \
TARGET_OUT_SYSTEM_EXT_EXECUTABLES \
TARGET_OUT_SYSTEM_EXT_SHARED_LIBRARIES \
TARGET_OUT_SYSTEM_EXT_JAVA_LIBRARIES \
TARGET_OUT_SYSTEM_EXT_APPS \
TARGET_OUT_SYSTEM_EXT_APPS_PRIVILEGED \
- TARGET_OUT_SYSTEM_EXT_ETC
+ TARGET_OUT_SYSTEM_EXT_ETC \
+ TARGET_OUT_SYSTEM_EXT_FAKE
$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_SYSTEM_EXT_EXECUTABLES := $(TARGET_OUT_SYSTEM_EXT_EXECUTABLES)
$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_SYSTEM_EXT_SHARED_LIBRARIES := $(target_out_system_ext_shared_libraries_base)/lib
diff --git a/core/main.mk b/core/main.mk
index c1cafc0..051ebdd 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -1859,12 +1859,12 @@
$(INSTALLED_FILES_JSON_SYSTEMOTHER) \
$(INSTALLED_FILES_FILE_RECOVERY) \
$(INSTALLED_FILES_JSON_RECOVERY) \
- $(INSTALLED_BUILD_PROP_TARGET):build.prop \
- $(INSTALLED_VENDOR_BUILD_PROP_TARGET):build.prop-vendor \
- $(INSTALLED_PRODUCT_BUILD_PROP_TARGET):build.prop-product \
- $(INSTALLED_ODM_BUILD_PROP_TARGET):build.prop-odm \
- $(INSTALLED_SYSTEM_EXT_BUILD_PROP_TARGET):build.prop-system_ext \
- $(INSTALLED_RAMDISK_BUILD_PROP_TARGET):build.prop-ramdisk \
+ $(if $(BUILDING_SYSTEM_IMAGE), $(INSTALLED_BUILD_PROP_TARGET):build.prop) \
+ $(if $(BUILDING_VENDOR_IMAGE), $(INSTALLED_VENDOR_BUILD_PROP_TARGET):build.prop-vendor) \
+ $(if $(BUILDING_PRODUCT_IMAGE), $(INSTALLED_PRODUCT_BUILD_PROP_TARGET):build.prop-product) \
+ $(if $(BUILDING_ODM_IMAGE), $(INSTALLED_ODM_BUILD_PROP_TARGET):build.prop-odm) \
+ $(if $(BUILDING_SYSTEM_EXT_IMAGE), $(INSTALLED_SYSTEM_EXT_BUILD_PROP_TARGET):build.prop-system_ext) \
+ $(if $(BUILDING_RAMDISK_IMAGE), $(INSTALLED_RAMDISK_BUILD_PROP_TARGET):build.prop-ramdisk) \
$(INSTALLED_ANDROID_INFO_TXT_TARGET) \
$(INSTALLED_MISC_INFO_TARGET) \
$(INSTALLED_RAMDISK_TARGET) \
diff --git a/core/packaging/flags.mk b/core/packaging/flags.mk
index 500efdd..e715fd1 100644
--- a/core/packaging/flags.mk
+++ b/core/packaging/flags.mk
@@ -119,13 +119,14 @@
# $(5): installed aconfig flags storage flag map file (out)
# $(6): installed aconfig flags storage flag value file (out)
# $(7): input aconfig files for the partition (in)
+# $(8): partition name
define generate-partition-aconfig-storage-file
$(eval $(strip $(1)): PRIVATE_OUT := $(strip $(1)))
$(eval $(strip $(1)): PRIVATE_IN := $(strip $(7)))
$(strip $(1)): $(ACONFIG) $(strip $(7))
mkdir -p $$(dir $$(PRIVATE_OUT))
$$(if $$(PRIVATE_IN), \
- $$(ACONFIG) create-storage --container "" --file package_map --out $$(PRIVATE_OUT) \
+ $$(ACONFIG) create-storage --container $(8) --file package_map --out $$(PRIVATE_OUT) \
$$(addprefix --cache ,$$(PRIVATE_IN)), \
)
touch $$(PRIVATE_OUT)
@@ -134,7 +135,7 @@
$(strip $(2)): $(ACONFIG) $(strip $(7))
mkdir -p $$(dir $$(PRIVATE_OUT))
$$(if $$(PRIVATE_IN), \
- $$(ACONFIG) create-storage --container "" --file flag_map --out $$(PRIVATE_OUT) \
+ $$(ACONFIG) create-storage --container $(8) --file flag_map --out $$(PRIVATE_OUT) \
$$(addprefix --cache ,$$(PRIVATE_IN)), \
)
touch $$(PRIVATE_OUT)
@@ -143,7 +144,7 @@
$(strip $(3)): $(ACONFIG) $(strip $(7))
mkdir -p $$(dir $$(PRIVATE_OUT))
$$(if $$(PRIVATE_IN), \
- $$(ACONFIG) create-storage --container "" --file flag_val --out $$(PRIVATE_OUT) \
+ $$(ACONFIG) create-storage --container $(8) --file flag_val --out $$(PRIVATE_OUT) \
$$(addprefix --cache ,$$(PRIVATE_IN)), \
)
touch $$(PRIVATE_OUT)
@@ -167,6 +168,7 @@
$(sort $(foreach m,$(call register-names-for-partition, $(partition)), \
$(ALL_MODULES.$(m).ACONFIG_FILES) \
)), \
+ $(partition), \
)) \
)
endif
diff --git a/core/product.mk b/core/product.mk
index d64dde2..01b5ead 100644
--- a/core/product.mk
+++ b/core/product.mk
@@ -33,8 +33,7 @@
# 4096, 16384 and 65536.
_product_single_value_vars += PRODUCT_MAX_PAGE_SIZE_SUPPORTED
-# Indicates that AOSP can use a kernel configured with 4k/16k/64k page sizes.
-# The possible values are true or false.
+# Boolean variable determining if AOSP relies on bionic's PAGE_SIZE macro.
_product_single_value_vars += PRODUCT_NO_BIONIC_PAGE_SIZE_MACRO
# The resource configuration options to use for this product.
diff --git a/core/tasks/tools/vts_package_utils.mk b/core/tasks/tools/vts_package_utils.mk
index 06161f0..1a819f2 100644
--- a/core/tasks/tools/vts_package_utils.mk
+++ b/core/tasks/tools/vts_package_utils.mk
@@ -21,7 +21,7 @@
$(foreach m,$(1),\
$(eval _built_files := $(strip $(ALL_MODULES.$(m).BUILT_INSTALLED)\
$(ALL_MODULES.$(m)$(TARGET_2ND_ARCH_MODULE_SUFFIX).BUILT_INSTALLED)))\
- $(foreach i, $(_built_files),\
+ $(foreach i, $(sort $(_built_files)),\
$(eval bui_ins := $(subst :,$(space),$(i)))\
$(eval ins := $(word 2,$(bui_ins)))\
$(if $(filter $(TARGET_OUT_ROOT)/%,$(ins)),\
diff --git a/envsetup.sh b/envsetup.sh
index 74cfbbd..fbe522d 100644
--- a/envsetup.sh
+++ b/envsetup.sh
@@ -1093,7 +1093,9 @@
# that my Mac has /usr/local/bin/adb installed by default and on the default
# path.
function adb() {
- local ADB=$(which adb)
+ # We need `command which` because zsh has a built-in `which` that's more
+ # like `type`.
+ local ADB=$(command which adb)
if [ -z "$ADB" ]; then
echo "Command adb not found; try lunch (and building) first?"
return 1
diff --git a/target/board/BoardConfigMainlineCommon.mk b/target/board/BoardConfigMainlineCommon.mk
index c3878b8..2b17349 100644
--- a/target/board/BoardConfigMainlineCommon.mk
+++ b/target/board/BoardConfigMainlineCommon.mk
@@ -2,6 +2,9 @@
#
# Common compile-time definitions for mainline images.
+# Ensure all trunk-stable flags are available.
+include build/make/target/product/build_variables.mk
+
# The generic product target doesn't have any hardware-specific pieces.
TARGET_NO_BOOTLOADER := true
TARGET_NO_RECOVERY := true
diff --git a/target/board/mainline_sdk/BoardConfig.mk b/target/board/mainline_sdk/BoardConfig.mk
index 84f8b2d..e4c6a8c 100644
--- a/target/board/mainline_sdk/BoardConfig.mk
+++ b/target/board/mainline_sdk/BoardConfig.mk
@@ -13,6 +13,9 @@
# limitations under the License.
#
+# Ensure all trunk-stable flags are available.
+include build/make/target/product/build_variables.mk
+
TARGET_ARCH_SUITE := mainline_sdk
HOST_CROSS_OS := linux_bionic
diff --git a/target/product/base_system.mk b/target/product/base_system.mk
index cd45e2a..884af4f 100644
--- a/target/product/base_system.mk
+++ b/target/product/base_system.mk
@@ -237,6 +237,7 @@
PackageInstaller \
passwd_system \
perfetto \
+ perfetto-extras \
ping \
ping6 \
pintool \
@@ -490,8 +491,8 @@
$(call inherit-product, $(SRC_TARGET_DIR)/product/runtime_libart.mk)
-# Use the configured release of sqlite
-$(call soong_config_set, libsqlite3, release_package_libsqlite3, $(RELEASE_PACKAGE_LIBSQLITE3))
+# Ensure all trunk-stable flags are available.
+$(call inherit-product, $(SRC_TARGET_DIR)/product/build_variables.mk)
# Use "image" APEXes always.
$(call inherit-product,$(SRC_TARGET_DIR)/product/updatable_apex.mk)
diff --git a/target/product/build_variables.mk b/target/product/build_variables.mk
new file mode 100644
index 0000000..5fe5333
--- /dev/null
+++ b/target/product/build_variables.mk
@@ -0,0 +1,21 @@
+#
+# 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.
+#
+
+# This file contains the trunk-stable flags that should be exported to all
+# Android targets.
+
+# Use the configured release of sqlite
+$(call soong_config_set, libsqlite3, release_package_libsqlite3, $(RELEASE_PACKAGE_LIBSQLITE3))
diff --git a/target/product/module_common.mk b/target/product/module_common.mk
index 53b2ca6..bf146a0 100644
--- a/target/product/module_common.mk
+++ b/target/product/module_common.mk
@@ -14,6 +14,7 @@
# limitations under the License.
#
+$(call inherit-product, $(SRC_TARGET_DIR)/product/build_variables.mk)
$(call inherit-product, $(SRC_TARGET_DIR)/product/default_art_config.mk)
$(call inherit-product, $(SRC_TARGET_DIR)/product/languages_default.mk)
$(call inherit-product, $(SRC_TARGET_DIR)/product/cfi-common.mk)
diff --git a/target/product/sdk.mk b/target/product/sdk.mk
index 009a9d4..04649a2 100644
--- a/target/product/sdk.mk
+++ b/target/product/sdk.mk
@@ -17,6 +17,9 @@
# This is a simple product that uses configures the minimum amount
# needed to build the SDK (without the emulator).
+# Ensure all trunk-stable flags are available.
+$(call inherit-product, $(SRC_TARGET_DIR)/product/build_variables.mk)
+
# In order to build the bootclasspath sources, the bootclasspath needs to
# be setup via default_art_config.mk. The sources only really make sense
# together with a device (e.g. the emulator). So if the SDK sources change
diff --git a/tools/aconfig/aconfig/src/commands.rs b/tools/aconfig/aconfig/src/commands.rs
index 98dde44..7736ce7 100644
--- a/tools/aconfig/aconfig/src/commands.rs
+++ b/tools/aconfig/aconfig/src/commands.rs
@@ -317,9 +317,7 @@
}
fn find_unique_package(parsed_flags: &[ProtoParsedFlag]) -> Option<&str> {
- let Some(package) = parsed_flags.first().map(|pf| pf.package()) else {
- return None;
- };
+ let package = parsed_flags.first().map(|pf| pf.package())?;
if parsed_flags.iter().any(|pf| pf.package() != package) {
return None;
}
@@ -327,9 +325,7 @@
}
fn find_unique_container(parsed_flags: &ProtoParsedFlags) -> Option<&str> {
- let Some(container) = parsed_flags.parsed_flag.first().map(|pf| pf.container()) else {
- return None;
- };
+ let container = parsed_flags.parsed_flag.first().map(|pf| pf.container())?;
if parsed_flags.parsed_flag.iter().any(|pf| pf.container() != container) {
return None;
}
diff --git a/tools/aconfig/aconfig_storage_read_api/aconfig_storage_read_api.cpp b/tools/aconfig/aconfig_storage_read_api/aconfig_storage_read_api.cpp
index b5bcf7d..ea756b3 100644
--- a/tools/aconfig/aconfig_storage_read_api/aconfig_storage_read_api.cpp
+++ b/tools/aconfig/aconfig_storage_read_api/aconfig_storage_read_api.cpp
@@ -74,11 +74,6 @@
if (fstat(fd, &fd_stat) < 0) {
return Error() << "fstat failed";
}
-
- if ((fd_stat.st_mode & (S_IWUSR | S_IWGRP | S_IWOTH)) != 0) {
- return Error() << "cannot map writeable file";
- }
-
size_t file_size = fd_stat.st_size;
void* const map_result = mmap(nullptr, file_size, PROT_READ, MAP_SHARED, fd, 0);
diff --git a/tools/aconfig/aconfig_storage_read_api/src/lib.rs b/tools/aconfig/aconfig_storage_read_api/src/lib.rs
index ea45f5d..8a71480 100644
--- a/tools/aconfig/aconfig_storage_read_api/src/lib.rs
+++ b/tools/aconfig/aconfig_storage_read_api/src/lib.rs
@@ -64,11 +64,17 @@
/// \input container: the flag package container
/// \input file_type: stoarge file type enum
/// \return a result of read only mapped file
-pub fn get_mapped_storage_file(
+///
+/// # Safety
+///
+/// The memory mapped file may have undefined behavior if there are writes to this
+/// file after being mapped. Ensure no writes can happen to this file while this
+/// mapping stays alive.
+pub unsafe fn get_mapped_storage_file(
container: &str,
file_type: StorageFileType,
) -> Result<Mmap, AconfigStorageError> {
- crate::mapped_file::get_mapped_file(STORAGE_LOCATION_FILE, container, file_type)
+ unsafe { crate::mapped_file::get_mapped_file(STORAGE_LOCATION_FILE, container, file_type) }
}
/// Get package start offset for flags.
@@ -311,10 +317,10 @@
use aconfig_storage_file::protos::storage_record_pb::write_proto_to_temp_file;
use tempfile::NamedTempFile;
- fn create_test_storage_files(read_only: bool) -> [NamedTempFile; 4] {
- let package_map = copy_to_temp_file("./tests/package.map", read_only).unwrap();
- let flag_map = copy_to_temp_file("./tests/flag.map", read_only).unwrap();
- let flag_val = copy_to_temp_file("./tests/flag.val", read_only).unwrap();
+ fn create_test_storage_files() -> [NamedTempFile; 4] {
+ let package_map = copy_to_temp_file("./tests/package.map").unwrap();
+ let flag_map = copy_to_temp_file("./tests/flag.map").unwrap();
+ let flag_val = copy_to_temp_file("./tests/flag.val").unwrap();
let text_proto = format!(
r#"
@@ -338,10 +344,11 @@
#[test]
// this test point locks down flag package offset query
fn test_package_offset_query() {
- let [package_map, flag_map, flag_val, pb_file] = create_test_storage_files(true);
+ let [_package_map, _flag_map, _flag_val, pb_file] = create_test_storage_files();
let pb_file_path = pb_file.path().display().to_string();
- let package_mapped_file =
- get_mapped_file(&pb_file_path, "system", StorageFileType::PackageMap).unwrap();
+ let package_mapped_file = unsafe {
+ get_mapped_file(&pb_file_path, "system", StorageFileType::PackageMap).unwrap()
+ };
let package_offset =
get_package_offset(&package_mapped_file, "com.android.aconfig.storage.test_1")
@@ -368,10 +375,10 @@
#[test]
// this test point locks down flag offset query
fn test_flag_offset_query() {
- let [package_map, flag_map, flag_val, pb_file] = create_test_storage_files(true);
+ let [_package_map, _flag_map, _flag_val, pb_file] = create_test_storage_files();
let pb_file_path = pb_file.path().display().to_string();
let flag_mapped_file =
- get_mapped_file(&pb_file_path, "system", StorageFileType::FlagMap).unwrap();
+ unsafe { get_mapped_file(&pb_file_path, "system", StorageFileType::FlagMap).unwrap() };
let baseline = vec![
(0, "enabled_ro", 1u16),
@@ -393,10 +400,10 @@
#[test]
// this test point locks down flag offset query
fn test_flag_value_query() {
- let [package_map, flag_map, flag_val, pb_file] = create_test_storage_files(true);
+ let [_package_map, _flag_map, _flag_val, pb_file] = create_test_storage_files();
let pb_file_path = pb_file.path().display().to_string();
let flag_value_file =
- get_mapped_file(&pb_file_path, "system", StorageFileType::FlagVal).unwrap();
+ unsafe { get_mapped_file(&pb_file_path, "system", StorageFileType::FlagVal).unwrap() };
let baseline: Vec<bool> = vec![false; 8];
for (offset, expected_value) in baseline.into_iter().enumerate() {
let flag_value = get_boolean_flag_value(&flag_value_file, offset as u32).unwrap();
@@ -407,7 +414,6 @@
#[test]
// this test point locks down flag storage file version number query api
fn test_storage_version_query() {
- let _ro_files = create_test_storage_files(true);
assert_eq!(get_storage_file_version("./tests/package.map").unwrap(), 1);
assert_eq!(get_storage_file_version("./tests/flag.map").unwrap(), 1);
assert_eq!(get_storage_file_version("./tests/flag.val").unwrap(), 1);
diff --git a/tools/aconfig/aconfig_storage_read_api/src/mapped_file.rs b/tools/aconfig/aconfig_storage_read_api/src/mapped_file.rs
index 09ecdb6..86c6a1b 100644
--- a/tools/aconfig/aconfig_storage_read_api/src/mapped_file.rs
+++ b/tools/aconfig/aconfig_storage_read_api/src/mapped_file.rs
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-use std::fs::{self, File};
+use std::fs::File;
use std::io::{BufReader, Read};
use anyhow::anyhow;
@@ -56,26 +56,16 @@
Err(StorageFileNotFound(anyhow!("Storage file does not exist for {}", container)))
}
-/// Verify the file is read only and then map it
-fn verify_read_only_and_map(file_path: &str) -> Result<Mmap, AconfigStorageError> {
- // ensure file has read only permission
- let perms = fs::metadata(file_path).unwrap().permissions();
- if !perms.readonly() {
- return Err(MapFileFail(anyhow!("fail to map non read only storage file {}", file_path)));
- }
-
+/// Get the read only memory mapping of a storage file
+///
+/// # Safety
+///
+/// The memory mapped file may have undefined behavior if there are writes to this
+/// file after being mapped. Ensure no writes can happen to this file while this
+/// mapping stays alive.
+unsafe fn map_file(file_path: &str) -> Result<Mmap, AconfigStorageError> {
let file = File::open(file_path)
.map_err(|errmsg| FileReadFail(anyhow!("Failed to open file {}: {}", file_path, errmsg)))?;
-
- // SAFETY:
- //
- // Mmap constructors are unsafe as it would have undefined behaviors if the file
- // is modified after mapped (https://docs.rs/memmap2/latest/memmap2/struct.Mmap.html).
- //
- // We either have to make this api unsafe or ensure that the file will not be modified
- // which means it is read only. Here in the code, we check explicitly that the file
- // being mapped must only have read permission, otherwise, error out, thus making sure
- // it is safe.
unsafe {
let mapped_file = Mmap::map(&file).map_err(|errmsg| {
MapFileFail(anyhow!("fail to map storage file {}: {}", file_path, errmsg))
@@ -85,16 +75,22 @@
}
/// Get a mapped storage file given the container and file type
-pub fn get_mapped_file(
+///
+/// # Safety
+///
+/// The memory mapped file may have undefined behavior if there are writes to this
+/// file after being mapped. Ensure no writes can happen to this file while this
+/// mapping stays alive.
+pub unsafe fn get_mapped_file(
location_pb_file: &str,
container: &str,
file_type: StorageFileType,
) -> Result<Mmap, AconfigStorageError> {
let files_location = find_container_storage_location(location_pb_file, container)?;
match file_type {
- StorageFileType::PackageMap => verify_read_only_and_map(files_location.package_map()),
- StorageFileType::FlagMap => verify_read_only_and_map(files_location.flag_map()),
- StorageFileType::FlagVal => verify_read_only_and_map(files_location.flag_val()),
+ StorageFileType::PackageMap => unsafe { map_file(files_location.package_map()) },
+ StorageFileType::FlagMap => unsafe { map_file(files_location.flag_map()) },
+ StorageFileType::FlagVal => unsafe { map_file(files_location.flag_val()) },
}
}
@@ -155,14 +151,15 @@
let mut content = Vec::new();
opened_file.read_to_end(&mut content).unwrap();
- let mmaped_file = get_mapped_file(location_pb_file, "system", file_type).unwrap();
+ let mmaped_file =
+ unsafe { get_mapped_file(location_pb_file, "system", file_type).unwrap() };
assert_eq!(mmaped_file[..], content[..]);
}
- fn create_test_storage_files(read_only: bool) -> [NamedTempFile; 4] {
- let package_map = copy_to_temp_file("./tests/package.map", read_only).unwrap();
- let flag_map = copy_to_temp_file("./tests/flag.map", read_only).unwrap();
- let flag_val = copy_to_temp_file("./tests/package.map", read_only).unwrap();
+ fn create_test_storage_files() -> [NamedTempFile; 4] {
+ let package_map = copy_to_temp_file("./tests/package.map").unwrap();
+ let flag_map = copy_to_temp_file("./tests/flag.map").unwrap();
+ let flag_val = copy_to_temp_file("./tests/package.map").unwrap();
let text_proto = format!(
r#"
@@ -185,7 +182,7 @@
#[test]
fn test_mapped_file_contents() {
- let [package_map, flag_map, flag_val, pb_file] = create_test_storage_files(true);
+ let [package_map, flag_map, flag_val, pb_file] = create_test_storage_files();
let pb_file_path = pb_file.path().display().to_string();
map_and_verify(
&pb_file_path,
@@ -203,35 +200,4 @@
&flag_val.path().display().to_string(),
);
}
-
- #[test]
- fn test_map_non_read_only_file() {
- let [package_map, flag_map, flag_val, pb_file] = create_test_storage_files(false);
- let pb_file_path = pb_file.path().display().to_string();
- let error =
- get_mapped_file(&pb_file_path, "system", StorageFileType::PackageMap).unwrap_err();
- assert_eq!(
- format!("{:?}", error),
- format!(
- "MapFileFail(fail to map non read only storage file {})",
- package_map.path().display()
- )
- );
- let error = get_mapped_file(&pb_file_path, "system", StorageFileType::FlagMap).unwrap_err();
- assert_eq!(
- format!("{:?}", error),
- format!(
- "MapFileFail(fail to map non read only storage file {})",
- flag_map.path().display()
- )
- );
- let error = get_mapped_file(&pb_file_path, "system", StorageFileType::FlagVal).unwrap_err();
- assert_eq!(
- format!("{:?}", error),
- format!(
- "MapFileFail(fail to map non read only storage file {})",
- flag_val.path().display()
- )
- );
- }
}
diff --git a/tools/aconfig/aconfig_storage_read_api/src/test_utils.rs b/tools/aconfig/aconfig_storage_read_api/src/test_utils.rs
index ff72499..84f31aa 100644
--- a/tools/aconfig/aconfig_storage_read_api/src/test_utils.rs
+++ b/tools/aconfig/aconfig_storage_read_api/src/test_utils.rs
@@ -19,14 +19,8 @@
use tempfile::NamedTempFile;
/// Create temp file copy
-pub(crate) fn copy_to_temp_file(source_file: &str, read_only: bool) -> Result<NamedTempFile> {
+pub(crate) fn copy_to_temp_file(source_file: &str) -> Result<NamedTempFile> {
let file = NamedTempFile::new()?;
fs::copy(source_file, file.path())?;
- if read_only {
- let file_name = file.path().display().to_string();
- let mut perms = fs::metadata(file_name).unwrap().permissions();
- perms.set_readonly(true);
- fs::set_permissions(file.path(), perms.clone()).unwrap();
- }
Ok(file)
}
diff --git a/tools/aconfig/aconfig_storage_read_api/tests/storage_read_api_test.cpp b/tools/aconfig/aconfig_storage_read_api/tests/storage_read_api_test.cpp
index 377395a..1d36aae 100644
--- a/tools/aconfig/aconfig_storage_read_api/tests/storage_read_api_test.cpp
+++ b/tools/aconfig/aconfig_storage_read_api/tests/storage_read_api_test.cpp
@@ -33,7 +33,7 @@
class AconfigStorageTest : public ::testing::Test {
protected:
- Result<std::string> copy_to_ro_temp_file(std::string const& source_file) {
+ Result<std::string> copy_to_temp_file(std::string const& source_file) {
auto temp_file = std::string(std::tmpnam(nullptr));
auto content = std::string();
if (!ReadFileToString(source_file, &content)) {
@@ -42,9 +42,6 @@
if (!WriteStringToFile(content, temp_file)) {
return Error() << "failed to copy file: " << source_file;
}
- if (chmod(temp_file.c_str(), S_IRUSR | S_IRGRP | S_IROTH) == -1) {
- return Error() << "failed to make file read only";
- }
return temp_file;
}
@@ -71,9 +68,9 @@
void SetUp() override {
auto const test_dir = android::base::GetExecutableDirectory();
- package_map = *copy_to_ro_temp_file(test_dir + "/package.map");
- flag_map = *copy_to_ro_temp_file(test_dir + "/flag.map");
- flag_val = *copy_to_ro_temp_file(test_dir + "/flag.val");
+ package_map = *copy_to_temp_file(test_dir + "/package.map");
+ flag_map = *copy_to_temp_file(test_dir + "/flag.map");
+ flag_val = *copy_to_temp_file(test_dir + "/flag.val");
storage_record_pb = *write_storage_location_pb_file(
package_map, flag_map, flag_val);
}
@@ -113,27 +110,6 @@
"Unable to find storage files for container vendor");
}
-/// Negative test to lock down the error when mapping a writeable storage file
-TEST_F(AconfigStorageTest, test_writable_storage_file_mapping) {
- ASSERT_TRUE(chmod(package_map.c_str(), 0666) != -1);
- auto mapped_file = private_api::get_mapped_file_impl(
- storage_record_pb, "system", api::StorageFileType::package_map);
- ASSERT_FALSE(mapped_file.ok());
- ASSERT_EQ(mapped_file.error().message(), "cannot map writeable file");
-
- ASSERT_TRUE(chmod(flag_map.c_str(), 0666) != -1);
- mapped_file = private_api::get_mapped_file_impl(
- storage_record_pb, "system", api::StorageFileType::flag_map);
- ASSERT_FALSE(mapped_file.ok());
- ASSERT_EQ(mapped_file.error().message(), "cannot map writeable file");
-
- ASSERT_TRUE(chmod(flag_val.c_str(), 0666) != -1);
- mapped_file = private_api::get_mapped_file_impl(
- storage_record_pb, "system", api::StorageFileType::flag_val);
- ASSERT_FALSE(mapped_file.ok());
- ASSERT_EQ(mapped_file.error().message(), "cannot map writeable file");
-}
-
/// Test to lock down storage package offset query api
TEST_F(AconfigStorageTest, test_package_offset_query) {
auto mapped_file = private_api::get_mapped_file_impl(
diff --git a/tools/aconfig/aconfig_storage_read_api/tests/storage_read_api_test.rs b/tools/aconfig/aconfig_storage_read_api/tests/storage_read_api_test.rs
index eb4d54d..afcd5a7 100644
--- a/tools/aconfig/aconfig_storage_read_api/tests/storage_read_api_test.rs
+++ b/tools/aconfig/aconfig_storage_read_api/tests/storage_read_api_test.rs
@@ -9,20 +9,16 @@
use std::fs;
use tempfile::NamedTempFile;
- pub fn copy_to_ro_temp_file(source_file: &str) -> NamedTempFile {
+ pub fn copy_to_temp_file(source_file: &str) -> NamedTempFile {
let file = NamedTempFile::new().unwrap();
fs::copy(source_file, file.path()).unwrap();
- let file_name = file.path().display().to_string();
- let mut perms = fs::metadata(file_name).unwrap().permissions();
- perms.set_readonly(true);
- fs::set_permissions(file.path(), perms.clone()).unwrap();
file
}
fn create_test_storage_files() -> [NamedTempFile; 4] {
- let package_map = copy_to_ro_temp_file("./package.map");
- let flag_map = copy_to_ro_temp_file("./flag.map");
- let flag_val = copy_to_ro_temp_file("./flag.val");
+ let package_map = copy_to_temp_file("./package.map");
+ let flag_map = copy_to_temp_file("./flag.map");
+ let flag_val = copy_to_temp_file("./flag.val");
let text_proto = format!(
r#"
@@ -47,8 +43,11 @@
fn test_unavailable_stoarge() {
let [_package_map, _flag_map, _flag_val, pb_file] = create_test_storage_files();
let pb_file_path = pb_file.path().display().to_string();
- let err =
- get_mapped_file(&pb_file_path, "vendor", StorageFileType::PackageMap).unwrap_err();
+ // SAFETY:
+ // The safety here is ensured as the test process will not write to temp storage file
+ let err = unsafe {
+ get_mapped_file(&pb_file_path, "vendor", StorageFileType::PackageMap).unwrap_err()
+ };
assert_eq!(
format!("{:?}", err),
"StorageFileNotFound(Storage file does not exist for vendor)"
@@ -59,8 +58,11 @@
fn test_package_offset_query() {
let [_package_map, _flag_map, _flag_val, pb_file] = create_test_storage_files();
let pb_file_path = pb_file.path().display().to_string();
- let package_mapped_file =
- get_mapped_file(&pb_file_path, "system", StorageFileType::PackageMap).unwrap();
+ // SAFETY:
+ // The safety here is ensured as the test process will not write to temp storage file
+ let package_mapped_file = unsafe {
+ get_mapped_file(&pb_file_path, "system", StorageFileType::PackageMap).unwrap()
+ };
let package_offset =
get_package_offset(&package_mapped_file, "com.android.aconfig.storage.test_1")
@@ -88,8 +90,12 @@
fn test_none_exist_package_offset_query() {
let [_package_map, _flag_map, _flag_val, pb_file] = create_test_storage_files();
let pb_file_path = pb_file.path().display().to_string();
- let package_mapped_file =
- get_mapped_file(&pb_file_path, "system", StorageFileType::PackageMap).unwrap();
+ // SAFETY:
+ // The safety here is ensured as the test process will not write to temp storage file
+ let package_mapped_file = unsafe {
+ get_mapped_file(&pb_file_path, "system", StorageFileType::PackageMap).unwrap()
+ };
+
let package_offset_option =
get_package_offset(&package_mapped_file, "com.android.aconfig.storage.test_3").unwrap();
assert_eq!(package_offset_option, None);
@@ -99,8 +105,10 @@
fn test_flag_offset_query() {
let [_package_map, _flag_map, _flag_val, pb_file] = create_test_storage_files();
let pb_file_path = pb_file.path().display().to_string();
+ // SAFETY:
+ // The safety here is ensured as the test process will not write to temp storage file
let flag_mapped_file =
- get_mapped_file(&pb_file_path, "system", StorageFileType::FlagMap).unwrap();
+ unsafe { get_mapped_file(&pb_file_path, "system", StorageFileType::FlagMap).unwrap() };
let baseline = vec![
(0, "enabled_ro", 1u16),
@@ -123,9 +131,10 @@
fn test_none_exist_flag_offset_query() {
let [_package_map, _flag_map, _flag_val, pb_file] = create_test_storage_files();
let pb_file_path = pb_file.path().display().to_string();
+ // SAFETY:
+ // The safety here is ensured as the test process will not write to temp storage file
let flag_mapped_file =
- get_mapped_file(&pb_file_path, "system", StorageFileType::FlagMap).unwrap();
-
+ unsafe { get_mapped_file(&pb_file_path, "system", StorageFileType::FlagMap).unwrap() };
let flag_offset_option = get_flag_offset(&flag_mapped_file, 0, "none_exist").unwrap();
assert_eq!(flag_offset_option, None);
@@ -137,9 +146,10 @@
fn test_boolean_flag_value_query() {
let [_package_map, _flag_map, _flag_val, pb_file] = create_test_storage_files();
let pb_file_path = pb_file.path().display().to_string();
+ // SAFETY:
+ // The safety here is ensured as the test process will not write to temp storage file
let flag_value_file =
- get_mapped_file(&pb_file_path, "system", StorageFileType::FlagVal).unwrap();
-
+ unsafe { get_mapped_file(&pb_file_path, "system", StorageFileType::FlagVal).unwrap() };
let baseline: Vec<bool> = vec![false; 8];
for (offset, expected_value) in baseline.into_iter().enumerate() {
let flag_value = get_boolean_flag_value(&flag_value_file, offset as u32).unwrap();
@@ -151,9 +161,10 @@
fn test_invalid_boolean_flag_value_query() {
let [_package_map, _flag_map, _flag_val, pb_file] = create_test_storage_files();
let pb_file_path = pb_file.path().display().to_string();
+ // SAFETY:
+ // The safety here is ensured as the test process will not write to temp storage file
let flag_value_file =
- get_mapped_file(&pb_file_path, "system", StorageFileType::FlagVal).unwrap();
-
+ unsafe { get_mapped_file(&pb_file_path, "system", StorageFileType::FlagVal).unwrap() };
let err = get_boolean_flag_value(&flag_value_file, 8u32).unwrap_err();
assert_eq!(
format!("{:?}", err),
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index 8a8a613..8836248 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -1313,7 +1313,11 @@
key = "super_%s_partition_list" % partition_group
merged_dict[key] = uniq_concat(
framework_dict.get(key, ""), vendor_dict.get(key, ""))
-
+ # in the case that vendor is on s build, but is taking a v3 -> v3 vabc ota, we want to fallback to v2
+ if "vabc_cow_version" not in vendor_dict or "vabc_cow_version" not in framework_dict:
+ merged_dict["vabc_cow_version"] = '2'
+ else:
+ merged_dict["vabc_cow_version"] = min(vendor_dict["vabc_cow_version"], framework_dict["vabc_cow_version"])
# Various other flags should be copied from the vendor dict, if defined.
for key in ("virtual_ab", "virtual_ab_retrofit", "lpmake",
"super_metadata_device", "super_partition_error_limit",
@@ -2456,7 +2460,7 @@
m = re.match(r'(?:minSdkVersion|sdkVersion):\'([^\']*)\'', line)
if m:
return m.group(1)
- raise ExternalError("No minSdkVersion returned by aapt2")
+ raise ExternalError("No minSdkVersion returned by aapt2 for apk: {}".format(apk_name))
def GetMinSdkVersionInt(apk_name, codename_to_api_level_map):
diff --git a/tools/releasetools/sign_target_files_apks.py b/tools/releasetools/sign_target_files_apks.py
index 5d92ede..b8f848f 100755
--- a/tools/releasetools/sign_target_files_apks.py
+++ b/tools/releasetools/sign_target_files_apks.py
@@ -271,6 +271,10 @@
def IsEntryOtaPackage(input_zip, filename):
with input_zip.open(filename, "r") as fp:
+ external_attr = input_zip.getinfo(filename).external_attr
+ if stat.S_ISLNK(external_attr >> 16):
+ return IsEntryOtaPackage(input_zip,
+ os.path.join(os.path.dirname(filename), fp.read().decode()))
return IsOtaPackage(fp)
diff --git a/tools/releasetools/test_common.py b/tools/releasetools/test_common.py
index 2989338..89933a0 100644
--- a/tools/releasetools/test_common.py
+++ b/tools/releasetools/test_common.py
@@ -1515,6 +1515,7 @@
'super_group_a_group_size': '1000',
'super_group_b_partition_list': 'product',
'super_group_b_group_size': '2000',
+ 'vabc_cow_version': '2',
}
self.assertEqual(merged_dict, expected_merged_dict)
@@ -1525,6 +1526,7 @@
'dynamic_partition_list': 'system',
'super_group_a_partition_list': 'system',
'super_group_a_group_size': '5000',
+ 'vabc_cow_version': '3',
}
vendor_dict = {
'use_dynamic_partitions': 'true',
@@ -1546,6 +1548,7 @@
'super_group_a_group_size': '1000',
'super_group_b_partition_list': 'product',
'super_group_b_group_size': '2000',
+ 'vabc_cow_version': '2',
}
self.assertEqual(merged_dict, expected_merged_dict)