Merge "Fix fuzzer builds."
diff --git a/CleanSpec.mk b/CleanSpec.mk
index a93e79e..1d0685d 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -632,6 +632,8 @@
$(call add-clean-step, rm -rf $(HOST_OUT_JAVA_LIBRARIES)/BootSignature.jar)
$(call add-clean-step, rm -rf $(HOST_OUT_JAVA_LIBRARIES)/VeritySigner.jar)
$(call add-clean-step, rm -rf $(HOST_OUT_EXECUTABLES)/build_verity_metadata.py)
+
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib*/libc_malloc*)
# ************************************************
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
# ************************************************
diff --git a/Deprecation.md b/Deprecation.md
index 01825b2..0d925cb 100644
--- a/Deprecation.md
+++ b/Deprecation.md
@@ -12,11 +12,20 @@
[build/make/core/deprecation.mk] is the source of truth, but for easy browsing:
-| Module type | State |
-| -------------------------- | --------- |
-| `BUILD_HOST_TEST_CONFIG` | Error |
-| `BUILD_TARGET_TEST_CONFIG` | Error |
-| `BUILD_*` | Available |
+| Module type | State |
+| -------------------------------- | --------- |
+| `BUILD_AUX_EXECUTABLE` | Warning |
+| `BUILD_AUX_STATIC_LIBRARY` | Warning |
+| `BUILD_HOST_FUZZ_TEST` | Warning |
+| `BUILD_HOST_NATIVE_TEST` | Warning |
+| `BUILD_HOST_SHARED_TEST_LIBRARY` | Error |
+| `BUILD_HOST_STATIC_TEST_LIBRARY` | Warning |
+| `BUILD_HOST_TEST_CONFIG` | Error |
+| `BUILD_NATIVE_BENCHMARK` | Warning |
+| `BUILD_SHARED_TEST_LIBRARY` | Error |
+| `BUILD_STATIC_TEST_LIBRARY` | Warning |
+| `BUILD_TARGET_TEST_CONFIG` | Error |
+| `BUILD_*` | Available |
## Module Type Deprecation Process
diff --git a/core/Makefile b/core/Makefile
index 70421c4..d6bd804 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -459,10 +459,11 @@
build_desc :=
-ifeq (,$(filter true, $(TARGET_NO_KERNEL) $(TARGET_NO_RECOVERY)))
-INSTALLED_RECOVERYIMAGE_TARGET := $(PRODUCT_OUT)/recovery.img
-else
INSTALLED_RECOVERYIMAGE_TARGET :=
+ifdef BUILDING_RECOVERY_IMAGE
+ifneq ($(BOARD_USES_RECOVERY_AS_BOOT),true)
+INSTALLED_RECOVERYIMAGE_TARGET := $(PRODUCT_OUT)/recovery.img
+endif
endif
$(INSTALLED_BUILD_PROP_TARGET): $(intermediate_system_build_prop) $(INSTALLED_RECOVERYIMAGE_TARGET)
@@ -487,6 +488,12 @@
@echo Target vendor buildinfo: $@
@mkdir -p $(dir $@)
$(hide) echo > $@
+ifeq ($(PRODUCT_USE_DYNAMIC_PARTITIONS),true)
+ $(hide) echo ro.boot.dynamic_partitions=true >> $@
+endif
+ifeq ($(PRODUCT_RETROFIT_DYNAMIC_PARTITIONS),true)
+ $(hide) echo ro.boot.dynamic_partitions_retrofit=true >> $@
+endif
$(hide) grep 'ro.product.first_api_level' $(intermediate_system_build_prop) >> $@ || true
$(hide) echo ro.vendor.build.security_patch="$(VENDOR_SECURITY_PATCH)">>$@
$(hide) echo ro.vendor.product.cpu.abilist="$(TARGET_CPU_ABI_LIST)">>$@
@@ -688,7 +695,7 @@
@echo APK certs list: $@
@mkdir -p $(dir $@)
@rm -f $@
- $(foreach p,$(PACKAGES),\
+ $(foreach p,$(sort $(PACKAGES)),\
$(if $(PACKAGES.$(p).EXTERNAL_KEY),\
$(call _apkcerts_write_line,$(p),"EXTERNAL","",$(PACKAGES.$(p).COMPRESSED),$@),\
$(call _apkcerts_write_line,$(p),$(PACKAGES.$(p).CERTIFICATE),$(PACKAGES.$(p).PRIVATE_KEY),$(PACKAGES.$(p).COMPRESSED),$@)))
@@ -900,13 +907,14 @@
endif # BUILDING_RAMDISK_IMAGE
-
-INSTALLED_BOOTIMAGE_TARGET := $(PRODUCT_OUT)/boot.img
-
-ifneq ($(strip $(TARGET_NO_KERNEL)),true)
-
# -----------------------------------------------------------------
# the boot image, which is a collection of other images.
+
+# This is defined here since we may be building recovery as boot
+# below and only want to define this once
+BUILT_BOOTIMAGE_TARGET := $(PRODUCT_OUT)/boot.img
+
+ifneq ($(strip $(TARGET_NO_KERNEL)),true)
INTERNAL_BOOTIMAGE_ARGS := \
$(addprefix --second ,$(INSTALLED_2NDBOOTLOADER_TARGET)) \
--kernel $(INSTALLED_KERNEL_TARGET)
@@ -945,8 +953,10 @@
--os_version $(PLATFORM_VERSION) \
--os_patch_level $(PLATFORM_SECURITY_PATCH)
-# We build recovery as boot image if BOARD_USES_RECOVERY_AS_BOOT is true.
-ifneq ($(BOARD_USES_RECOVERY_AS_BOOT),true)
+# Define these only if we are building boot
+ifdef BUILDING_BOOT_IMAGE
+INSTALLED_BOOTIMAGE_TARGET := $(BUILT_BOOTIMAGE_TARGET)
+
ifeq ($(TARGET_BOOTIMAGE_USE_EXT2),true)
$(error TARGET_BOOTIMAGE_USE_EXT2 is not supported anymore)
@@ -1017,7 +1027,7 @@
$(hide) $(call assert-max-image-size,$(INSTALLED_BOOTIMAGE_TARGET),$(BOARD_BOOTIMAGE_PARTITION_SIZE))
endif # TARGET_BOOTIMAGE_USE_EXT2
-endif # BOARD_USES_RECOVERY_AS_BOOT
+endif # BUILDING_BOOT_IMAGE
else # TARGET_NO_KERNEL == "true"
ifdef BOARD_PREBUILT_BOOTIMAGE
@@ -1493,7 +1503,7 @@
# Recovery image
# Recovery image exists if we are building recovery, or building recovery as boot.
-ifneq (,$(INSTALLED_RECOVERYIMAGE_TARGET)$(filter true,$(BOARD_USES_RECOVERY_AS_BOOT)))
+ifdef BUILDING_RECOVERY_IMAGE
INTERNAL_RECOVERYIMAGE_FILES := $(filter $(TARGET_RECOVERY_OUT)/%, \
$(ALL_DEFAULT_INSTALLED_MODULES))
@@ -1506,6 +1516,7 @@
# build-recoveryimage-target, which would touch the files under TARGET_RECOVERY_OUT and race with
# the call to FILELIST.
ifeq ($(BOARD_USES_RECOVERY_AS_BOOT),true)
+INSTALLED_BOOTIMAGE_TARGET := $(BUILT_BOOTIMAGE_TARGET)
$(INSTALLED_FILES_FILE_RECOVERY): $(INSTALLED_BOOTIMAGE_TARGET)
else
$(INSTALLED_FILES_FILE_RECOVERY): $(INSTALLED_RECOVERYIMAGE_TARGET)
@@ -1924,9 +1935,9 @@
@echo "make $@: ignoring dependencies"
$(call build-recoveryimage-target, $(INSTALLED_RECOVERYIMAGE_TARGET))
-else # INSTALLED_RECOVERYIMAGE_TARGET not defined
+else # BUILDING_RECOVERY_IMAGE
RECOVERY_RESOURCE_ZIP :=
-endif
+endif # BUILDING_RECOVERY_IMAGE
.PHONY: recoveryimage
recoveryimage: $(INSTALLED_RECOVERYIMAGE_TARGET) $(RECOVERY_RESOURCE_ZIP)
@@ -3056,18 +3067,30 @@
$(error BOARD_AVB_VBMETA_SYSTEM and BOARD_AVB_VBMETA_VENDOR cannot have duplicates)
endif
-# Appends security patch level as a AVB property descriptor
+# Appends os version and security patch level as a AVB property descriptor
BOARD_AVB_SYSTEM_ADD_HASHTREE_FOOTER_ARGS += \
+ --prop com.android.build.system.os_version:$(PLATFORM_VERSION) \
--prop com.android.build.system.security_patch:$(PLATFORM_SECURITY_PATCH)
BOARD_AVB_PRODUCT_ADD_HASHTREE_FOOTER_ARGS += \
+ --prop com.android.build.product.os_version:$(PLATFORM_VERSION) \
--prop com.android.build.product.security_patch:$(PLATFORM_SECURITY_PATCH)
BOARD_AVB_PRODUCT_SERVICES_ADD_HASHTREE_FOOTER_ARGS += \
+ --prop com.android.build.product_services.os_version:$(PLATFORM_VERSION) \
--prop com.android.build.product_services.security_patch:$(PLATFORM_SECURITY_PATCH)
-# The following vendor- and odm-specific images needs explicitly set per board.
+BOARD_AVB_BOOT_ADD_HASH_FOOTER_ARGS += \
+ --prop com.android.build.boot.os_version:$(PLATFORM_VERSION)
+
+BOARD_AVB_VENDOR_ADD_HASHTREE_FOOTER_ARGS += \
+ --prop com.android.build.vendor.os_version:$(PLATFORM_VERSION)
+
+BOARD_AVB_ODM_ADD_HASHTREE_FOOTER_ARGS += \
+ --prop com.android.build.odm.os_version:$(PLATFORM_VERSION)
+
+# The following vendor- and odm-specific images needs explicit SPL set per board.
ifdef BOOT_SECURITY_PATCH
BOARD_AVB_BOOT_ADD_HASH_FOOTER_ARGS += \
--prop com.android.build.boot.security_patch:$(BOOT_SECURITY_PATCH)
@@ -3358,8 +3381,12 @@
.PHONY: check-all-partition-sizes check-all-partition-sizes-nodeps
+check_all_partition_sizes_file := $(call intermediates-dir-for,PACKAGING,check-all-partition-sizes)/timestamp
+
+check-all-partition-sizes: $(check_all_partition_sizes_file)
+
# Add image dependencies so that generated_*_image_info.txt are written before checking.
-check-all-partition-sizes: \
+$(check_all_partition_sizes_file): \
build/make/tools/releasetools/sparse_img.py \
$(call images-for-partitions,$(BOARD_SUPER_PARTITION_PARTITION_LIST))
@@ -3427,7 +3454,12 @@
fi
endef
-check-all-partition-sizes check-all-partition-sizes-nodeps:
+$(check_all_partition_sizes_file):
+ $(call check-all-partition-sizes-target)
+ $(call check-super-partition-size)
+ touch $@
+
+check-all-partition-sizes-nodeps:
$(call check-all-partition-sizes-target)
$(call check-super-partition-size)
@@ -3482,131 +3514,112 @@
endif
ifeq ($(build_otatools_package),true)
-OTATOOLS := $(HOST_OUT_EXECUTABLES)/minigzip \
- $(HOST_OUT_EXECUTABLES)/aapt \
- $(HOST_OUT_EXECUTABLES)/checkvintf \
- $(HOST_OUT_EXECUTABLES)/mkbootfs \
- $(HOST_OUT_EXECUTABLES)/mkbootimg \
- $(HOST_OUT_EXECUTABLES)/fs_config \
- $(HOST_OUT_EXECUTABLES)/zipalign \
- $(HOST_OUT_EXECUTABLES)/bsdiff \
- $(HOST_OUT_EXECUTABLES)/imgdiff \
- $(HOST_OUT_JAVA_LIBRARIES)/signapk.jar \
- $(HOST_OUT_JAVA_LIBRARIES)/boot_signer.jar \
- $(HOST_OUT_JAVA_LIBRARIES)/verity_signer.jar \
- $(HOST_OUT_EXECUTABLES)/mke2fs \
- $(HOST_OUT_EXECUTABLES)/mkuserimg_mke2fs \
- $(HOST_OUT_EXECUTABLES)/e2fsdroid \
- $(HOST_OUT_EXECUTABLES)/tune2fs \
- $(HOST_OUT_EXECUTABLES)/mksquashfsimage.sh \
- $(HOST_OUT_EXECUTABLES)/mksquashfs \
- $(HOST_OUT_EXECUTABLES)/mkf2fsuserimg.sh \
- $(HOST_OUT_EXECUTABLES)/make_f2fs \
- $(HOST_OUT_EXECUTABLES)/sload_f2fs \
- $(HOST_OUT_EXECUTABLES)/simg2img \
- $(HOST_OUT_EXECUTABLES)/e2fsck \
- $(HOST_OUT_EXECUTABLES)/generate_verity_key \
- $(HOST_OUT_EXECUTABLES)/verity_signer \
- $(HOST_OUT_EXECUTABLES)/verity_verifier \
- $(HOST_OUT_EXECUTABLES)/append2simg \
- $(HOST_OUT_EXECUTABLES)/img2simg \
- $(HOST_OUT_EXECUTABLES)/boot_signer \
- $(HOST_OUT_EXECUTABLES)/fec \
- $(HOST_OUT_EXECUTABLES)/brillo_update_payload \
- $(HOST_OUT_EXECUTABLES)/lib/shflags/shflags \
- $(HOST_OUT_EXECUTABLES)/delta_generator \
- $(HOST_OUT_EXECUTABLES)/care_map_generator \
- $(HOST_OUT_EXECUTABLES)/fc_sort \
- $(HOST_OUT_EXECUTABLES)/sefcontext_compile \
- $(LPMAKE) \
- $(AVBTOOL) \
- $(BLK_ALLOC_TO_BASE_FS) \
- $(BROTLI) \
- $(BUILD_VERITY_METADATA) \
- $(BUILD_VERITY_TREE)
+
+INTERNAL_OTATOOLS_MODULES := \
+ aapt \
+ append2simg \
+ avbtool \
+ blk_alloc_to_base_fs \
+ boot_signer \
+ brillo_update_payload \
+ brotli \
+ bsdiff \
+ build_verity_metadata \
+ build_verity_tree \
+ care_map_generator \
+ checkvintf \
+ delta_generator \
+ e2fsck \
+ e2fsdroid \
+ fc_sort \
+ fec \
+ fs_config \
+ generate_verity_key \
+ img2simg \
+ imgdiff \
+ libconscrypt_openjdk_jni \
+ lpmake \
+ make_f2fs \
+ minigzip \
+ mkbootfs \
+ mkbootimg \
+ mke2fs \
+ mke2fs.conf \
+ mkf2fsuserimg.sh \
+ mksquashfs \
+ mksquashfsimage.sh \
+ mkuserimg_mke2fs \
+ sefcontext_compile \
+ shflags \
+ signapk \
+ simg2img \
+ sload_f2fs \
+ tune2fs \
+ verity_signer \
+ verity_verifier \
+ zipalign \
ifeq (true,$(PRODUCT_SUPPORTS_VBOOT))
-OTATOOLS += \
- $(FUTILITY) \
- $(VBOOT_SIGNER)
+INTERNAL_OTATOOLS_MODULES += \
+ futility \
+ vboot_signer
endif
-# Shared libraries.
-OTATOOLS += \
- $(HOST_LIBRARY_PATH)/libc++$(HOST_SHLIB_SUFFIX) \
- $(HOST_LIBRARY_PATH)/liblog$(HOST_SHLIB_SUFFIX) \
- $(HOST_LIBRARY_PATH)/libcutils$(HOST_SHLIB_SUFFIX) \
- $(HOST_LIBRARY_PATH)/libselinux$(HOST_SHLIB_SUFFIX) \
- $(HOST_LIBRARY_PATH)/libcrypto_utils$(HOST_SHLIB_SUFFIX) \
- $(HOST_LIBRARY_PATH)/libcrypto-host$(HOST_SHLIB_SUFFIX) \
- $(HOST_LIBRARY_PATH)/libext2fs-host$(HOST_SHLIB_SUFFIX) \
- $(HOST_LIBRARY_PATH)/libext2_blkid-host$(HOST_SHLIB_SUFFIX) \
- $(HOST_LIBRARY_PATH)/libext2_com_err-host$(HOST_SHLIB_SUFFIX) \
- $(HOST_LIBRARY_PATH)/libext2_e2p-host$(HOST_SHLIB_SUFFIX) \
- $(HOST_LIBRARY_PATH)/libext2_quota-host$(HOST_SHLIB_SUFFIX) \
- $(HOST_LIBRARY_PATH)/libext2_uuid-host$(HOST_SHLIB_SUFFIX) \
- $(HOST_LIBRARY_PATH)/libconscrypt_openjdk_jni$(HOST_SHLIB_SUFFIX) \
- $(HOST_LIBRARY_PATH)/libbrillo$(HOST_SHLIB_SUFFIX) \
- $(HOST_LIBRARY_PATH)/libbrillo-stream$(HOST_SHLIB_SUFFIX) \
- $(HOST_LIBRARY_PATH)/libchrome$(HOST_SHLIB_SUFFIX) \
- $(HOST_LIBRARY_PATH)/libevent-host$(HOST_SHLIB_SUFFIX) \
- $(HOST_LIBRARY_PATH)/libprotobuf-cpp-lite$(HOST_SHLIB_SUFFIX) \
- $(HOST_LIBRARY_PATH)/libssl-host$(HOST_SHLIB_SUFFIX) \
- $(HOST_LIBRARY_PATH)/libz-host$(HOST_SHLIB_SUFFIX) \
- $(HOST_LIBRARY_PATH)/libsparse-host$(HOST_SHLIB_SUFFIX) \
- $(HOST_LIBRARY_PATH)/libbase$(HOST_SHLIB_SUFFIX) \
- $(HOST_LIBRARY_PATH)/libpcre2$(HOST_SHLIB_SUFFIX) \
- $(HOST_LIBRARY_PATH)/libbrotli$(HOST_SHLIB_SUFFIX) \
- $(HOST_LIBRARY_PATH)/liblp$(HOST_SHLIB_SUFFIX) \
- $(HOST_LIBRARY_PATH)/libext4_utils$(HOST_SHLIB_SUFFIX) \
- $(HOST_LIBRARY_PATH)/libfec$(HOST_SHLIB_SUFFIX) \
- $(HOST_LIBRARY_PATH)/libsquashfs_utils$(HOST_SHLIB_SUFFIX)
-
+INTERNAL_OTATOOLS_FILES := \
+ $(filter $(HOST_OUT)/%,$(call module-installed-files,$(INTERNAL_OTATOOLS_MODULES)))
.PHONY: otatools
-otatools: $(OTATOOLS)
+otatools: $(INTERNAL_OTATOOLS_FILES)
-BUILT_OTATOOLS_PACKAGE := $(PRODUCT_OUT)/otatools.zip
-$(BUILT_OTATOOLS_PACKAGE): zip_root := $(call intermediates-dir-for,PACKAGING,otatools)/otatools
+# For each module, recursively resolve its host shared library dependencies. Then we have a full
+# list of modules whose installed files need to be packed.
+INTERNAL_OTATOOLS_MODULES_WITH_DEPS := \
+ $(sort $(INTERNAL_OTATOOLS_MODULES) \
+ $(foreach m,$(INTERNAL_OTATOOLS_MODULES),$(call get-all-shared-libs-deps,$(m))))
-OTATOOLS_DEPS := \
- system/extras/ext4_utils/mke2fs.conf \
- $(sort $(shell find build/make/target/product/security -type f -name "*.x509.pem" -o -name "*.pk8" -o \
- -name verity_key))
+INTERNAL_OTATOOLS_PACKAGE_FILES := \
+ $(filter $(HOST_OUT)/%,$(call module-installed-files,$(INTERNAL_OTATOOLS_MODULES_WITH_DEPS)))
+
+INTERNAL_OTATOOLS_PACKAGE_FILES += \
+ $(sort $(shell find build/make/target/product/security -type f -name "*.x509.pem" -o \
+ -name "*.pk8" -o -name verity_key))
ifneq (,$(wildcard device))
-OTATOOLS_DEPS += \
+INTERNAL_OTATOOLS_PACKAGE_FILES += \
$(sort $(shell find device $(wildcard vendor) -type f -name "*.pk8" -o -name "verifiedboot*" -o \
-name "*.x509.pem" -o -name "oem*.prop"))
endif
ifneq (,$(wildcard external/avb))
-OTATOOLS_DEPS += \
+INTERNAL_OTATOOLS_PACKAGE_FILES += \
$(sort $(shell find external/avb/test/data -type f -name "testkey_*.pem" -o \
-name "atx_metadata.bin"))
endif
ifneq (,$(wildcard system/update_engine))
-OTATOOLS_DEPS += \
+INTERNAL_OTATOOLS_PACKAGE_FILES += \
$(sort $(shell find system/update_engine/scripts -name "*.pyc" -prune -o -type f -print))
endif
-
-OTATOOLS_RELEASETOOLS := \
- $(sort $(shell find build/make/tools/releasetools -name "*.pyc" -prune -o -type f))
-
ifeq (true,$(PRODUCT_SUPPORTS_VBOOT))
-OTATOOLS_DEPS += \
+INTERNAL_OTATOOLS_PACKAGE_FILES += \
$(sort $(shell find external/vboot_reference/tests/devkeys -type f))
endif
-$(BUILT_OTATOOLS_PACKAGE): $(OTATOOLS) $(OTATOOLS_DEPS) $(OTATOOLS_RELEASETOOLS) $(SOONG_ZIP)
+INTERNAL_OTATOOLS_RELEASETOOLS := \
+ $(sort $(shell find build/make/tools/releasetools -name "*.pyc" -prune -o \
+ \( -type f -o -type l \) -print))
+
+BUILT_OTATOOLS_PACKAGE := $(PRODUCT_OUT)/otatools.zip
+$(BUILT_OTATOOLS_PACKAGE): PRIVATE_ZIP_ROOT := $(call intermediates-dir-for,PACKAGING,otatools)/otatools
+$(BUILT_OTATOOLS_PACKAGE): PRIVATE_OTATOOLS_PACKAGE_FILES := $(INTERNAL_OTATOOLS_PACKAGE_FILES)
+$(BUILT_OTATOOLS_PACKAGE): PRIVATE_OTATOOLS_RELEASETOOLS := $(INTERNAL_OTATOOLS_RELEASETOOLS)
+$(BUILT_OTATOOLS_PACKAGE): $(INTERNAL_OTATOOLS_PACKAGE_FILES) $(INTERNAL_OTATOOLS_RELEASETOOLS)
+$(BUILT_OTATOOLS_PACKAGE): $(SOONG_ZIP)
@echo "Package OTA tools: $@"
- $(hide) rm -rf $@ $(zip_root)
- $(hide) mkdir -p $(dir $@) $(zip_root)/bin $(zip_root)/framework $(zip_root)/releasetools
- $(call copy-files-with-structure,$(OTATOOLS),$(HOST_OUT)/,$(zip_root))
- $(hide) cp $(SOONG_ZIP) $(zip_root)/bin/
- $(hide) cp -r -d -p build/make/tools/releasetools/* $(zip_root)/releasetools
- $(hide) rm -rf $@ $(zip_root)/releasetools/*.pyc
- $(hide) $(SOONG_ZIP) -o $@ -C $(zip_root) -D $(zip_root) \
- -C . $(addprefix -f ,$(OTATOOLS_DEPS))
+ rm -rf $@ $(PRIVATE_ZIP_ROOT)
+ mkdir -p $(dir $@)
+ $(call copy-files-with-structure,$(PRIVATE_OTATOOLS_PACKAGE_FILES),$(HOST_OUT)/,$(PRIVATE_ZIP_ROOT))
+ $(call copy-files-with-structure,$(PRIVATE_OTATOOLS_RELEASETOOLS),build/make/tools/,$(PRIVATE_ZIP_ROOT))
+ cp $(SOONG_ZIP) $(PRIVATE_ZIP_ROOT)/bin/
+ $(SOONG_ZIP) -o $@ -C $(PRIVATE_ZIP_ROOT) -D $(PRIVATE_ZIP_ROOT)
.PHONY: otatools-package
otatools-package: $(BUILT_OTATOOLS_PACKAGE)
@@ -3908,6 +3921,9 @@
ifdef BOARD_BOOTIMAGE_PARTITION_SIZE
$(hide) echo "boot_size=$(BOARD_BOOTIMAGE_PARTITION_SIZE)" >> $(zip_root)/META/misc_info.txt
endif
+ifeq ($(INSTALLED_BOOTIMAGE_TARGET),)
+ $(hide) echo "no_boot=true" >> $(zip_root)/META/misc_info.txt
+endif
ifeq ($(INSTALLED_RECOVERYIMAGE_TARGET),)
$(hide) echo "no_recovery=true" >> $(zip_root)/META/misc_info.txt
endif
diff --git a/core/binary.mk b/core/binary.mk
index f3a50f1..a420c02 100644
--- a/core/binary.mk
+++ b/core/binary.mk
@@ -1402,9 +1402,6 @@
$(notice_target): | $(installed_static_library_notice_file_targets)
$(LOCAL_INSTALLED_MODULE): | $(notice_target)
-$(notice_target): | $(installed_static_library_notice_file_targets)
-$(LOCAL_INSTALLED_MODULE): | $(notice_target)
-
# Default is -fno-rtti.
ifeq ($(strip $(LOCAL_RTTI_FLAG)),)
LOCAL_RTTI_FLAG := -fno-rtti
diff --git a/core/board_config.mk b/core/board_config.mk
index 2580a33..d83fa32 100644
--- a/core/board_config.mk
+++ b/core/board_config.mk
@@ -181,7 +181,7 @@
# Sanity check to warn about likely cryptic errors later in the build.
ifeq ($(TARGET_IS_64_BIT),true)
ifeq (,$(filter true false,$(TARGET_SUPPORTS_64_BIT_APPS)))
- $(warning Building a 32-bit-app-only product on a 64-bit device. \
+ $(error Building a 32-bit-app-only product on a 64-bit device. \
If this is intentional, set TARGET_SUPPORTS_64_BIT_APPS := false)
endif
endif
@@ -290,8 +290,33 @@
endif
.KATI_READONLY := BUILDING_CACHE_IMAGE
-# TODO: Add BUILDING_BOOT_IMAGE / BUILDING_RECOVERY_IMAGE
-# This gets complicated with BOARD_USES_RECOVERY_AS_BOOT, so skipping for now.
+# Are we building a boot image
+BUILDING_BOOT_IMAGE :=
+ifeq ($(BOARD_USES_RECOVERY_AS_BOOT),true)
+ BUILDING_BOOT_IMAGE :=
+else ifeq ($(PRODUCT_BUILD_BOOT_IMAGE),)
+ ifdef BOARD_BOOTIMAGE_PARTITION_SIZE
+ BUILDING_BOOT_IMAGE := true
+ endif
+else ifeq ($(PRODUCT_BUILD_BOOT_IMAGE),true)
+ BUILDING_BOOT_IMAGE := true
+endif
+.KATI_READONLY := BUILDING_BOOT_IMAGE
+
+# Are we building a recovery image
+BUILDING_RECOVERY_IMAGE :=
+ifeq ($(BOARD_USES_RECOVERY_AS_BOOT),true)
+ BUILDING_RECOVERY_IMAGE := true
+else ifeq ($(PRODUCT_BUILD_RECOVERY_IMAGE),)
+ ifdef BOARD_RECOVERYIMAGE_PARTITION_SIZE
+ ifeq (,$(filter true, $(TARGET_NO_KERNEL) $(TARGET_NO_RECOVERY)))
+ BUILDING_RECOVERY_IMAGE := true
+ endif
+ endif
+else ifeq ($(PRODUCT_BUILD_RECOVERY_IMAGE),true)
+ BUILDING_RECOVERY_IMAGE := true
+endif
+.KATI_READONLY := BUILDING_RECOVERY_IMAGE
# Are we building a ramdisk image
BUILDING_RAMDISK_IMAGE := true
@@ -509,6 +534,14 @@
TARGET_VENDOR_TEST_SUFFIX :=
endif
+###########################################
+# APEXes are by default flattened, i.e. non-updatable.
+# It can be unflattened (and updatable) by inheriting from
+# updatable_apex.mk
+ifeq (,$(TARGET_FLATTEN_APEX))
+TARGET_FLATTEN_APEX := true
+endif
+
ifeq (,$(TARGET_BUILD_APPS))
ifdef PRODUCT_EXTRA_VNDK_VERSIONS
$(foreach v,$(PRODUCT_EXTRA_VNDK_VERSIONS),$(call check_vndk_version,$(v)))
diff --git a/core/config.mk b/core/config.mk
index bf59fb1..57c1d7a 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -608,7 +608,7 @@
BUILD_VERITY_TREE := $(HOST_OUT_EXECUTABLES)/build_verity_tree
BOOT_SIGNER := $(HOST_OUT_EXECUTABLES)/boot_signer
FUTILITY := $(HOST_OUT_EXECUTABLES)/futility-host
-VBOOT_SIGNER := prebuilts/misc/scripts/vboot_signer/vboot_signer.sh
+VBOOT_SIGNER := $(HOST_OUT_EXECUTABLES)/vboot_signer
FEC := $(HOST_OUT_EXECUTABLES)/fec
BRILLO_UPDATE_PAYLOAD := $(HOST_OUT_EXECUTABLES)/brillo_update_payload
@@ -624,11 +624,9 @@
USE_OPENJDK9 := true
-ifeq ($(EXPERIMENTAL_USE_OPENJDK9),)
+ifeq ($(EXPERIMENTAL_JAVA_LANGUAGE_LEVEL_9),)
TARGET_OPENJDK9 :=
-else ifeq ($(EXPERIMENTAL_USE_OPENJDK9),1.8)
-TARGET_OPENJDK9 :=
-else ifeq ($(EXPERIMENTAL_USE_OPENJDK9),true)
+else ifeq ($(EXPERIMENTAL_JAVA_LANGUAGE_LEVEL_9),true)
TARGET_OPENJDK9 := true
endif
@@ -815,15 +813,6 @@
PLATFORM_SEPOLICY_VERSION \
TOT_SEPOLICY_VERSION \
-ifeq ($(PRODUCT_OTA_ENFORCE_VINTF_KERNEL_REQUIREMENTS),)
- ifdef PRODUCT_SHIPPING_API_LEVEL
- ifeq (true,$(call math_gt_or_eq,$(PRODUCT_SHIPPING_API_LEVEL),29))
- PRODUCT_OTA_ENFORCE_VINTF_KERNEL_REQUIREMENTS := true
- endif
- endif
-endif
-.KATI_READONLY := PRODUCT_OTA_ENFORCE_VINTF_KERNEL_REQUIREMENTS
-
ifeq ($(PRODUCT_RETROFIT_DYNAMIC_PARTITIONS),true)
ifneq ($(PRODUCT_USE_DYNAMIC_PARTITIONS),true)
$(error PRODUCT_USE_DYNAMIC_PARTITIONS must be true when PRODUCT_RETROFIT_DYNAMIC_PARTITIONS \
@@ -1113,7 +1102,7 @@
TARGET_AVAIALBLE_SDK_VERSIONS := $(call numerically_sort,$(TARGET_AVAILABLE_SDK_VERSIONS))
TARGET_SDK_VERSIONS_WITHOUT_JAVA_18_SUPPORT := $(call numbers_less_than,24,$(TARGET_AVAILABLE_SDK_VERSIONS))
-TARGET_SDK_VERSIONS_WITHOUT_JAVA_19_SUPPORT := $(call numbers_less_than,27,$(TARGET_AVAILABLE_SDK_VERSIONS))
+TARGET_SDK_VERSIONS_WITHOUT_JAVA_19_SUPPORT := $(call numbers_less_than,30,$(TARGET_AVAILABLE_SDK_VERSIONS))
ifndef INTERNAL_PLATFORM_PRIVATE_API_FILE
INTERNAL_PLATFORM_PRIVATE_API_FILE := $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/private.txt
diff --git a/core/deprecation.mk b/core/deprecation.mk
index 9d57527..11fe290 100644
--- a/core/deprecation.mk
+++ b/core/deprecation.mk
@@ -1,7 +1,5 @@
# These module types can still be used without warnings or errors.
AVAILABLE_BUILD_MODULE_TYPES :=$= \
- BUILD_AUX_EXECUTABLE \
- BUILD_AUX_STATIC_LIBRARY \
BUILD_COPY_HEADERS \
BUILD_EXECUTABLE \
BUILD_FUZZ_TEST \
@@ -9,17 +7,12 @@
BUILD_HOST_DALVIK_JAVA_LIBRARY \
BUILD_HOST_DALVIK_STATIC_JAVA_LIBRARY \
BUILD_HOST_EXECUTABLE \
- BUILD_HOST_FUZZ_TEST \
BUILD_HOST_JAVA_LIBRARY \
- BUILD_HOST_NATIVE_TEST \
BUILD_HOST_PREBUILT \
BUILD_HOST_SHARED_LIBRARY \
- BUILD_HOST_SHARED_TEST_LIBRARY \
BUILD_HOST_STATIC_LIBRARY \
- BUILD_HOST_STATIC_TEST_LIBRARY \
BUILD_JAVA_LIBRARY \
BUILD_MULTI_PREBUILT \
- BUILD_NATIVE_BENCHMARK \
BUILD_NATIVE_TEST \
BUILD_NOTICE_FILE \
BUILD_PACKAGE \
@@ -27,16 +20,21 @@
BUILD_PREBUILT \
BUILD_RRO_PACKAGE \
BUILD_SHARED_LIBRARY \
- BUILD_SHARED_TEST_LIBRARY \
BUILD_STATIC_JAVA_LIBRARY \
BUILD_STATIC_LIBRARY \
- BUILD_STATIC_TEST_LIBRARY \
# These are BUILD_* variables that will throw a warning when used. This is
# generally a temporary state until all the devices are marked with the
# relevant BUILD_BROKEN_USES_BUILD_* variables, then these would move to
# DEFAULT_ERROR_BUILD_MODULE_TYPES.
DEFAULT_WARNING_BUILD_MODULE_TYPES :=$= \
+ BUILD_AUX_EXECUTABLE \
+ BUILD_AUX_STATIC_LIBRARY \
+ BUILD_HOST_FUZZ_TEST \
+ BUILD_HOST_NATIVE_TEST \
+ BUILD_HOST_STATIC_TEST_LIBRARY \
+ BUILD_NATIVE_BENCHMARK \
+ BUILD_STATIC_TEST_LIBRARY \
# These are BUILD_* variables that are errors to reference, but you can set
# BUILD_BROKEN_USES_BUILD_* in your BoardConfig.mk in order to turn them back
@@ -48,6 +46,8 @@
# These are BUILD_* variables that are always errors to reference.
# Setting the BUILD_BROKEN_USES_BUILD_* variables is also an error.
OBSOLETE_BUILD_MODULE_TYPES :=$= \
+ BUILD_HOST_SHARED_TEST_LIBRARY \
+ BUILD_SHARED_TEST_LIBRARY \
$(foreach m,$(OBSOLETE_BUILD_MODULE_TYPES),\
$(KATI_obsolete_var $(m),Please convert to Soong) \
diff --git a/core/dex_preopt_config.mk b/core/dex_preopt_config.mk
index b5834b0..c44e4bd 100644
--- a/core/dex_preopt_config.mk
+++ b/core/dex_preopt_config.mk
@@ -1,4 +1,4 @@
-DEX_PREOPT_CONFIG := $(PRODUCT_OUT)/dexpreopt.config
+DEX_PREOPT_CONFIG := $(SOONG_OUT_DIR)/dexpreopt.config
# The default value for LOCAL_DEX_PREOPT
DEX_PREOPT_DEFAULT ?= true
@@ -169,12 +169,6 @@
fi)
endif
-# Dummy rule to create dexpreopt.config, it will already have been created
-# by the $(file) call above, but a rule needs to exist to keep the dangling
-# rule check happy.
-$(DEX_PREOPT_CONFIG):
- @#empty
-
DEXPREOPT_GEN_DEPS := \
$(SOONG_HOST_OUT_EXECUTABLES)/profman \
$(DEX2OAT) \
diff --git a/core/dex_preopt_odex_install.mk b/core/dex_preopt_odex_install.mk
index 85ddbfa..266ebd2 100644
--- a/core/dex_preopt_odex_install.mk
+++ b/core/dex_preopt_odex_install.mk
@@ -242,12 +242,12 @@
.KATI_RESTAT: $(my_dexpreopt_script) $(my_strip_script)
$(my_dexpreopt_script): PRIVATE_MODULE := $(LOCAL_MODULE)
- $(my_dexpreopt_script): PRIVATE_GLOBAL_CONFIG := $(PRODUCT_OUT)/dexpreopt.config
+ $(my_dexpreopt_script): PRIVATE_GLOBAL_CONFIG := $(DEX_PREOPT_CONFIG_FOR_MAKE)
$(my_dexpreopt_script): PRIVATE_MODULE_CONFIG := $(my_dexpreopt_config)
$(my_dexpreopt_script): PRIVATE_STRIP_SCRIPT := $(my_strip_script)
$(my_dexpreopt_script): .KATI_IMPLICIT_OUTPUTS := $(my_strip_script)
$(my_dexpreopt_script): $(DEXPREOPT_GEN)
- $(my_dexpreopt_script): $(my_dexpreopt_config) $(PRODUCT_OUT)/dexpreopt.config
+ $(my_dexpreopt_script): $(my_dexpreopt_config) $(DEX_PREOPT_CONFIG_FOR_MAKE)
@echo "$(PRIVATE_MODULE) dexpreopt gen"
$(DEXPREOPT_GEN) -global $(PRIVATE_GLOBAL_CONFIG) -module $(PRIVATE_MODULE_CONFIG) \
-dexpreopt_script $@ -strip_script $(PRIVATE_STRIP_SCRIPT) \
diff --git a/core/host_static_test_lib.mk b/core/host_static_test_lib.mk
index a24cd62..a9e39b1 100644
--- a/core/host_static_test_lib.mk
+++ b/core/host_static_test_lib.mk
@@ -6,4 +6,4 @@
include $(BUILD_SYSTEM)/host_test_internal.mk
-include $(BUILD_HOST_STATIC_LIBRARY)
+include $(BUILD_SYSTEM)/host_static_library.mk
diff --git a/core/java.mk b/core/java.mk
index b951f14..41a1686 100644
--- a/core/java.mk
+++ b/core/java.mk
@@ -240,6 +240,8 @@
$(java_source_list_file): $(java_sources_deps)
$(write-java-source-list)
+ALL_MODULES.$(my_register_name).SRCJARS := $(LOCAL_SRCJARS)
+
ifneq ($(TURBINE_ENABLED),false)
$(full_classes_turbine_jar): PRIVATE_JAVACFLAGS := $(LOCAL_JAVACFLAGS) $(annotation_processor_flags)
diff --git a/core/main.mk b/core/main.mk
index 6f92ff1..0225c89 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -243,14 +243,6 @@
ADDITIONAL_DEFAULT_PROPERTIES += ro.actionable_compatible_property.enabled=${PRODUCT_COMPATIBLE_PROPERTY}
endif
-ifeq ($(PRODUCT_USE_DYNAMIC_PARTITIONS),true)
-ADDITIONAL_PRODUCT_PROPERTIES += ro.boot.dynamic_partitions=true
-endif
-
-ifeq ($(PRODUCT_RETROFIT_DYNAMIC_PARTITIONS),true)
-ADDITIONAL_PRODUCT_PROPERTIES += ro.boot.dynamic_partitions_retrofit=true
-endif
-
# Add the system server compiler filter if they are specified for the product.
ifneq (,$(PRODUCT_SYSTEM_SERVER_COMPILER_FILTER))
ADDITIONAL_PRODUCT_PROPERTIES += dalvik.vm.systemservercompilerfilter=$(PRODUCT_SYSTEM_SERVER_COMPILER_FILTER)
@@ -722,7 +714,7 @@
$(eval req_files := )\
$(foreach req_mod,$(req_mods), \
$(eval req_file := $(filter $(TARGET_OUT_ROOT)/%, $(call module-installed-files,$(req_mod)))) \
- $(if $(strip $(req_file)),\
+ $(if $(strip $(req_file))$(ONE_SHOT_MAKEFILE),\
,\
$(error $(m).LOCAL_TARGET_REQUIRED_MODULES : illegal value $(req_mod) : not a device module. If you want to specify host modules to be required to be installed along with your host module, add those module names to LOCAL_REQUIRED_MODULES instead)\
)\
@@ -748,7 +740,7 @@
$(eval req_files := )\
$(foreach req_mod,$(req_mods), \
$(eval req_file := $(filter $(HOST_OUT)/%, $(call module-installed-files,$(req_mod)))) \
- $(if $(strip $(req_file)),\
+ $(if $(strip $(req_file))$(ONE_SHOT_MAKEFILE),\
,\
$(error $(m).LOCAL_HOST_REQUIRED_MODULES : illegal value $(req_mod) : not a host module. If you want to specify target modules to be required to be installed along with your target module, add those module names to LOCAL_REQUIRED_MODULES instead)\
)\
@@ -1208,31 +1200,46 @@
# Runtime APEX libraries
APEX_MODULE_LIBS := \
libadbconnection.so \
+ libadbconnectiond.so \
libandroidicu.so \
libandroidio.so \
libart-compiler.so \
libart-dexlayout.so \
+ libart-disassembler.so \
libart.so \
libartbase.so \
+ libartbased.so \
+ libartd-compiler.so \
+ libartd-dexlayout.so \
+ libartd.so \
libartpalette.so \
+ libc.so \
+ libc_malloc_debug.so \
+ libc_malloc_hooks.so \
libdexfile.so \
libdexfile_external.so \
+ libdexfiled.so \
libdexfiled_external.so \
+ libdl.so \
libdt_fd_forward.so \
libdt_socket.so \
libicui18n.so \
libicuuc.so \
libjavacore.so \
libjdwp.so \
+ libm.so \
libnativebridge.so \
libnativehelper.so \
libnativeloader.so \
libnpt.so \
libopenjdk.so \
libopenjdkjvm.so \
+ libopenjdkjvmd.so \
libopenjdkjvmti.so \
+ libopenjdkjvmtid.so \
libpac.so \
libprofile.so \
+ libprofiled.so \
libsigchain.so \
# Conscrypt APEX libraries
@@ -1243,6 +1250,9 @@
# still may create these libraries in /system (b/129006418).
DISABLE_APEX_LIBS_ABSENCE_CHECK ?=
+# Bionic should not be in /system, except for the bootstrap instance.
+APEX_LIBS_ABSENCE_CHECK_EXCLUDE := lib/bootstrap lib64/bootstrap
+
# Exclude lib/arm and lib/arm64 which contain the native bridge proxy libs. They
# are compiled for the guest architecture and used with an entirely different
# linker config. The native libs are then linked to as usual via exported
@@ -1250,7 +1260,7 @@
# native architecture.
# TODO(b/130630776): Introduce a make variable for the appropriate directory
# when native bridge is active.
-APEX_LIBS_ABSENCE_CHECK_EXCLUDE := lib/arm lib/arm64
+APEX_LIBS_ABSENCE_CHECK_EXCLUDE += lib/arm lib/arm64
# Exclude vndk-* subdirectories which contain prebuilts from older releases.
APEX_LIBS_ABSENCE_CHECK_EXCLUDE += lib/vndk-% lib64/vndk-%
diff --git a/core/product.mk b/core/product.mk
index e5df5cd..838673c 100644
--- a/core/product.mk
+++ b/core/product.mk
@@ -162,7 +162,9 @@
# used for adding properties to build.prop of product partition
_product_list_vars += PRODUCT_PRODUCT_SERVICES_PROPERTIES
_product_list_vars += PRODUCT_ODM_PROPERTIES
-_product_list_vars += PRODUCT_CHARACTERISTICS
+
+# The characteristics of the product, which among other things is passed to aapt
+_product_single_value_vars += PRODUCT_CHARACTERISTICS
# A list of words like <source path>:<destination path>[:<owner>].
# The file at the source path should be copied to the destination path
@@ -302,6 +304,9 @@
# A flag to override PRODUCT_COMPATIBLE_PROPERTY
_product_single_value_vars += PRODUCT_COMPATIBLE_PROPERTY_OVERRIDE
+# List of extra VNDK versions to be included
+_product_list_vars += PRODUCT_EXTRA_VNDK_VERSIONS
+
# Whether the whitelist of actionable compatible properties should be disabled or not
_product_single_value_vars += PRODUCT_ACTIONABLE_COMPATIBLE_PROPERTY_DISABLE
@@ -355,9 +360,12 @@
_product_single_value_vars += PRODUCT_BUILD_CACHE_IMAGE
_product_single_value_vars += PRODUCT_BUILD_RAMDISK_IMAGE
_product_single_value_vars += PRODUCT_BUILD_USERDATA_IMAGE
+_product_single_value_vars += PRODUCT_BUILD_RECOVERY_IMAGE
+_product_single_value_vars += PRODUCT_BUILD_BOOT_IMAGE
_product_list_vars += PRODUCT_UPDATABLE_BOOT_MODULES
_product_list_vars += PRODUCT_UPDATABLE_BOOT_LOCATIONS
+
# Whether the product would like to check prebuilt ELF files.
_product_single_value_vars += PRODUCT_CHECK_ELF_FILES
diff --git a/core/product_config.mk b/core/product_config.mk
index 12c2722..cb58cf4 100644
--- a/core/product_config.mk
+++ b/core/product_config.mk
@@ -376,6 +376,23 @@
PRODUCT_BUILD_SUPER_PARTITION := $(PRODUCT_USE_DYNAMIC_PARTITIONS)
endif
+ifeq ($(PRODUCT_OTA_ENFORCE_VINTF_KERNEL_REQUIREMENTS),)
+ ifdef PRODUCT_SHIPPING_API_LEVEL
+ ifeq (true,$(call math_gt_or_eq,$(PRODUCT_SHIPPING_API_LEVEL),29))
+ PRODUCT_OTA_ENFORCE_VINTF_KERNEL_REQUIREMENTS := true
+ endif
+ endif
+endif
+
+# If build command defines OVERRIDE_PRODUCT_EXTRA_VNDK_VERSIONS,
+# override PRODUCT_EXTRA_VNDK_VERSIONS with it.
+ifdef OVERRIDE_PRODUCT_EXTRA_VNDK_VERSIONS
+ PRODUCT_EXTRA_VNDK_VERSIONS := $(OVERRIDE_PRODUCT_EXTRA_VNDK_VERSIONS)
+endif
+
+$(KATI_obsolete_var OVERRIDE_PRODUCT_EXTRA_VNDK_VERSIONS \
+ ,Use PRODUCT_EXTRA_VNDK_VERSIONS instead)
+
define product-overrides-config
$$(foreach rule,$$(PRODUCT_$(1)_OVERRIDES),\
$$(if $$(filter 2,$$(words $$(subst :,$$(space),$$(rule)))),,\
@@ -405,7 +422,9 @@
ODM \
CACHE \
RAMDISK \
- USERDATA, \
+ USERDATA \
+ BOOT \
+ RECOVERY, \
$(eval $(call product-build-image-config,$(image))))
product-build-image-config :=
diff --git a/core/soong_cc_prebuilt.mk b/core/soong_cc_prebuilt.mk
index 31b0e63..7a8f46e 100644
--- a/core/soong_cc_prebuilt.mk
+++ b/core/soong_cc_prebuilt.mk
@@ -223,7 +223,9 @@
#
# Filter out some NDK libraries that are not being exported.
my_static_libraries := \
- $(filter-out ndk_libc++_static ndk_libc++abi ndk_libandroid_support ndk_libunwind, \
+ $(filter-out ndk_libc++_static ndk_libc++abi ndk_libandroid_support ndk_libunwind \
+ ndk_libc++_static.native_bridge ndk_libc++abi.native_bridge \
+ ndk_libandroid_support.native_bridge ndk_libunwind.native_bridge, \
$(LOCAL_STATIC_LIBRARIES))
installed_static_library_notice_file_targets := \
$(foreach lib,$(my_static_libraries) $(LOCAL_WHOLE_STATIC_LIBRARIES), \
diff --git a/core/soong_config.mk b/core/soong_config.mk
index 48db6b1..220e2c8 100644
--- a/core/soong_config.mk
+++ b/core/soong_config.mk
@@ -121,6 +121,7 @@
$(call add_json_str, DeviceVndkVersion, $(BOARD_VNDK_VERSION))
$(call add_json_str, Platform_vndk_version, $(PLATFORM_VNDK_VERSION))
$(call add_json_list, ExtraVndkVersions, $(PRODUCT_EXTRA_VNDK_VERSIONS))
+$(call add_json_bool, BoardVndkRuntimeDisable, $(BOARD_VNDK_RUNTIME_DISABLE))
$(call add_json_list, DeviceSystemSdkVersions, $(BOARD_SYSTEMSDK_VERSIONS))
$(call add_json_list, Platform_systemsdk_versions, $(PLATFORM_SYSTEMSDK_VERSIONS))
$(call add_json_bool, Malloc_not_svelte, $(call invert_bool,$(filter true,$(MALLOC_SVELTE))))
diff --git a/core/tasks/check_boot_jars/package_whitelist.txt b/core/tasks/check_boot_jars/package_whitelist.txt
index b0becba..3b63843 100644
--- a/core/tasks/check_boot_jars/package_whitelist.txt
+++ b/core/tasks/check_boot_jars/package_whitelist.txt
@@ -46,6 +46,8 @@
java\.util\.spi
java\.util\.stream
java\.util\.zip
+# TODO: Remove javax.annotation.processing if possible, see http://b/132338110:
+javax\.annotation\.processing
javax\.crypto
javax\.crypto\.interfaces
javax\.crypto\.spec
diff --git a/core/tasks/module-info.mk b/core/tasks/module-info.mk
index 2c56162..2d93128 100644
--- a/core/tasks/module-info.mk
+++ b/core/tasks/module-info.mk
@@ -17,6 +17,7 @@
'"test_config": [$(if $(ALL_MODULES.$(m).TEST_CONFIG),"$(ALL_MODULES.$(m).TEST_CONFIG)")], ' \
'"dependencies": [$(foreach w,$(sort $(ALL_DEPS.$(m).ALL_DEPS)),"$(w)", )], ' \
'"srcs": [$(foreach w,$(sort $(ALL_MODULES.$(m).SRCS)),"$(w)", )], ' \
+ '"srcjars": [$(foreach w,$(sort $(ALL_MODULES.$(m).SRCJARS)),"$(w)", )], ' \
'},\n' \
) | sed -e 's/, *\]/]/g' -e 's/, *\}/ }/g' -e '$$s/,$$//' >> $@
$(hide) echo '}' >> $@
diff --git a/core/tasks/vndk.mk b/core/tasks/vndk.mk
index 9420638..90ebd92 100644
--- a/core/tasks/vndk.mk
+++ b/core/tasks/vndk.mk
@@ -27,11 +27,10 @@
#
# Args:
# $(1): list of module and filename pairs (e.g., ld.config.txt:ld.config.27.txt ...)
-# $(2): if not empty, evaluates for TARGET_2ND_ARCH
define paths-of-intermediates
$(strip \
$(foreach pair,$(1), \
- $(eval module := $(call word-colon,1,$(pair))$(if $(2),$(TARGET_2ND_ARCH_MODULE_SUFFIX))) \
+ $(eval module := $(call word-colon,1,$(pair))) \
$(eval built := $(ALL_MODULES.$(module).BUILT_INSTALLED)) \
$(eval filename := $(call word-colon,2,$(pair))) \
$(if $(wordlist 2,100,$(built)), \
@@ -41,30 +40,6 @@
)
endef
-# Returns src:dest list of notice files
-#
-# Args:
-# $(1): list of lib names (e.g., libfoo.vendor)
-define paths-of-notice-files
-$(strip \
- $(foreach lib,$(1), \
- $(eval notice := $(sort \
- $(ALL_MODULES.$(lib).NOTICES) \
- $(if $(TARGET_2ND_ARCH),
- $(ALL_MODULES.$(lib)$(TARGET_2ND_ARCH_MODULE_SUFFIX).NOTICES)))) \
- $(if $(wordlist 2,100,$(notice)), \
- $(error Unable to handle multiple notice files ($(lib)): $(notice))) \
- $(if $(notice),$(notice):$(subst .vendor,,$(lib)).so.txt)))
-endef
-
-vndk_core_libs := $(addsuffix .vendor,$(VNDK_CORE_LIBRARIES))
-vndk_sp_libs := $(addsuffix .vendor,$(VNDK_SAMEPROCESS_LIBRARIES))
-vndk_private_libs := $(addsuffix .vendor,$(VNDK_PRIVATE_LIBRARIES))
-
-vndk_snapshot_libs := \
- $(vndk_core_libs) \
- $(vndk_sp_libs)
-
vndk_prebuilt_txts := \
ld.config.txt \
vndksp.libraries.txt \
@@ -75,47 +50,6 @@
vndk_snapshot_configs_out := $(vndk_snapshot_top)/configs
#######################################
-# vndkcore.libraries.txt
-vndkcore.libraries.txt := $(vndk_snapshot_configs_out)/vndkcore.libraries.txt
-$(vndkcore.libraries.txt): PRIVATE_LIBS := $(vndk_core_libs)
-$(vndkcore.libraries.txt):
- @echo 'Generating: $@'
- @rm -f $@
- @mkdir -p $(dir $@)
- $(hide) echo -n > $@
- $(hide) $(foreach lib,$(PRIVATE_LIBS),echo $(patsubst %.vendor,%,$(lib)).so >> $@;)
-
-
-#######################################
-# vndkprivate.libraries.txt
-vndkprivate.libraries.txt := $(vndk_snapshot_configs_out)/vndkprivate.libraries.txt
-$(vndkprivate.libraries.txt): PRIVATE_LIBS := $(vndk_private_libs)
-$(vndkprivate.libraries.txt):
- @echo 'Generating: $@'
- @rm -f $@
- @mkdir -p $(dir $@)
- $(hide) echo -n > $@
- $(hide) $(foreach lib,$(PRIVATE_LIBS),echo $(patsubst %.vendor,%,$(lib)).so >> $@;)
-
-
-#######################################
-# module_paths.txt
-module_paths.txt := $(vndk_snapshot_configs_out)/module_paths.txt
-$(module_paths.txt): PRIVATE_LIBS := $(vndk_snapshot_libs)
-$(module_paths.txt):
- @echo 'Generating: $@'
- @rm -f $@
- @mkdir -p $(dir $@)
- $(hide) echo -n > $@
- $(hide) $(foreach lib,$(PRIVATE_LIBS),echo $(patsubst %.vendor,%,$(lib)).so $(ALL_MODULES.$(lib).PATH) >> $@;)
-
-
-vndk_snapshot_configs := \
- $(vndkcore.libraries.txt) \
- $(vndkprivate.libraries.txt) \
- $(module_paths.txt)
-
-#######################################
# vndk_snapshot_zip
vndk_snapshot_variant := $(vndk_snapshot_out)/$(TARGET_ARCH)
binder :=
@@ -130,44 +64,46 @@
$(vndk_snapshot_zip): PRIVATE_VNDK_SNAPSHOT_OUT := $(vndk_snapshot_out)
-deps := $(call paths-of-intermediates,$(foreach lib,$(vndk_core_libs),$(lib):$(subst .vendor,,$(lib)).so))
+prebuilts := $(SOONG_VNDK_SNAPSHOT_CORE_LIBS)
$(vndk_snapshot_zip): PRIVATE_VNDK_CORE_OUT := $(vndk_lib_dir)/shared/vndk-core
-$(vndk_snapshot_zip): PRIVATE_VNDK_CORE_INTERMEDIATES := $(deps)
-$(vndk_snapshot_zip): $(foreach d,$(deps),$(call word-colon,1,$(d)))
-deps :=
+$(vndk_snapshot_zip): PRIVATE_VNDK_CORE_SOONG_PREBUILTS := $(prebuilts)
+$(vndk_snapshot_zip): $(prebuilts)
+prebuilts :=
-deps := $(call paths-of-intermediates,$(foreach lib,$(vndk_sp_libs),$(lib):$(subst .vendor,,$(lib)).so))
+prebuilts := $(SOONG_VNDK_SNAPSHOT_SP_LIBS)
$(vndk_snapshot_zip): PRIVATE_VNDK_SP_OUT := $(vndk_lib_dir)/shared/vndk-sp
-$(vndk_snapshot_zip): PRIVATE_VNDK_SP_INTERMEDIATES := $(deps)
-$(vndk_snapshot_zip): $(foreach d,$(deps),$(call word-colon,1,$(d)))
-deps :=
+$(vndk_snapshot_zip): PRIVATE_VNDK_SP_SOONG_PREBUILTS := $(prebuilts)
+$(vndk_snapshot_zip): $(prebuilts)
+prebuilts :=
deps := $(call paths-of-intermediates,$(foreach txt,$(vndk_prebuilt_txts), \
- $(txt):$(patsubst %.txt,%.$(PLATFORM_VNDK_VERSION).txt,$(txt)))) \
- $(foreach config,$(vndk_snapshot_configs),$(config):$(notdir $(config)))
+ $(txt):$(patsubst %.txt,%.$(PLATFORM_VNDK_VERSION).txt,$(txt))))
+prebuilts := $(SOONG_VNDK_SNAPSHOT_CONFIGS)
$(vndk_snapshot_zip): PRIVATE_CONFIGS_OUT := $(vndk_snapshot_variant)/configs
$(vndk_snapshot_zip): PRIVATE_CONFIGS_INTERMEDIATES := $(deps)
-$(vndk_snapshot_zip): $(foreach d,$(deps),$(call word-colon,1,$(d)))
+$(vndk_snapshot_zip): PRIVATE_CONFIGS_SOONG_PREBUILTS := $(prebuilts)
+$(vndk_snapshot_zip): $(foreach d,$(deps),$(call word-colon,1,$(d))) $(prebuilts)
deps :=
+prebuilts :=
-notices := $(call paths-of-notice-files,$(vndk_core_libs) $(vndk_sp_libs))
+prebuilts := $(SOONG_VNDK_SNAPSHOT_NOTICES)
$(vndk_snapshot_zip): PRIVATE_NOTICE_FILES_OUT := $(vndk_snapshot_variant)/NOTICE_FILES
-$(vndk_snapshot_zip): PRIVATE_NOTICE_FILES_INTERMEDIATES := $(notices)
-$(vndk_snapshot_zip): $(foreach n,$(notices),$(call word-colon,1,$(n)))
-notices :=
+$(vndk_snapshot_zip): PRIVATE_NOTICE_FILES_SOONG_PREBUILTS := $(prebuilts)
+$(vndk_snapshot_zip): $(prebuilts)
+prebuilts :=
ifdef TARGET_2ND_ARCH
-deps := $(call paths-of-intermediates,$(foreach lib,$(vndk_core_libs),$(lib):$(subst .vendor,,$(lib)).so),true)
+prebuilts := $(SOONG_VNDK_SNAPSHOT_CORE_LIBS_2ND)
$(vndk_snapshot_zip): PRIVATE_VNDK_CORE_OUT_2ND := $(vndk_lib_dir_2nd)/shared/vndk-core
-$(vndk_snapshot_zip): PRIVATE_VNDK_CORE_INTERMEDIATES_2ND := $(deps)
-$(vndk_snapshot_zip): $(foreach d,$(deps),$(call word-colon,1,$(d)))
-deps :=
+$(vndk_snapshot_zip): PRIVATE_VNDK_CORE_SOONG_PREBUILTS_2ND := $(prebuilts)
+$(vndk_snapshot_zip): $(prebuilts)
+prebuilts :=
-deps := $(call paths-of-intermediates,$(foreach lib,$(vndk_sp_libs),$(lib):$(subst .vendor,,$(lib)).so),true)
+prebuilts := $(SOONG_VNDK_SNAPSHOT_SP_LIBS_2ND)
$(vndk_snapshot_zip): PRIVATE_VNDK_SP_OUT_2ND := $(vndk_lib_dir_2nd)/shared/vndk-sp
-$(vndk_snapshot_zip): PRIVATE_VNDK_SP_INTERMEDIATES_2ND := $(deps)
-$(vndk_snapshot_zip): $(foreach d,$(deps),$(call word-colon,1,$(d)))
-deps :=
+$(vndk_snapshot_zip): PRIVATE_VNDK_SP_SOONG_PREBUILTS_2ND := $(prebuilts)
+$(vndk_snapshot_zip): $(prebuilts)
+prebuilts :=
endif
# Args
@@ -182,6 +118,15 @@
true \
))
+# Args
+# $(1): destination directory
+# $(2): list of prebuilts to copy
+$(vndk_snapshot_zip): private-copy-prebuilts = \
+ $(if $(2),$(strip \
+ @mkdir -p $(1) && \
+ $(foreach file, $(2), cp $(file) $(1) && ) \
+ true \
+ ))
$(vndk_snapshot_zip): $(SOONG_ZIP)
@echo 'Generating VNDK snapshot: $@'
@@ -189,18 +134,20 @@
@rm -rf $(PRIVATE_VNDK_SNAPSHOT_OUT)
@mkdir -p $(PRIVATE_VNDK_SNAPSHOT_OUT)
$(call private-copy-intermediates, \
- $(PRIVATE_VNDK_CORE_OUT),$(PRIVATE_VNDK_CORE_INTERMEDIATES))
- $(call private-copy-intermediates, \
- $(PRIVATE_VNDK_SP_OUT),$(PRIVATE_VNDK_SP_INTERMEDIATES))
- $(call private-copy-intermediates, \
$(PRIVATE_CONFIGS_OUT),$(PRIVATE_CONFIGS_INTERMEDIATES))
- $(call private-copy-intermediates, \
- $(PRIVATE_NOTICE_FILES_OUT),$(PRIVATE_NOTICE_FILES_INTERMEDIATES))
+ $(call private-copy-prebuilts, \
+ $(PRIVATE_VNDK_CORE_OUT),$(PRIVATE_VNDK_CORE_SOONG_PREBUILTS))
+ $(call private-copy-prebuilts, \
+ $(PRIVATE_VNDK_SP_OUT),$(PRIVATE_VNDK_SP_SOONG_PREBUILTS))
+ $(call private-copy-prebuilts, \
+ $(PRIVATE_CONFIGS_OUT),$(PRIVATE_CONFIGS_SOONG_PREBUILTS))
+ $(call private-copy-prebuilts, \
+ $(PRIVATE_NOTICE_FILES_OUT),$(PRIVATE_NOTICE_FILES_SOONG_PREBUILTS))
ifdef TARGET_2ND_ARCH
- $(call private-copy-intermediates, \
- $(PRIVATE_VNDK_CORE_OUT_2ND),$(PRIVATE_VNDK_CORE_INTERMEDIATES_2ND))
- $(call private-copy-intermediates, \
- $(PRIVATE_VNDK_SP_OUT_2ND),$(PRIVATE_VNDK_SP_INTERMEDIATES_2ND))
+ $(call private-copy-prebuilts, \
+ $(PRIVATE_VNDK_CORE_OUT_2ND),$(PRIVATE_VNDK_CORE_SOONG_PREBUILTS_2ND))
+ $(call private-copy-prebuilts, \
+ $(PRIVATE_VNDK_SP_OUT_2ND),$(PRIVATE_VNDK_SP_SOONG_PREBUILTS_2ND))
endif
$(hide) $(SOONG_ZIP) -o $@ -C $(PRIVATE_VNDK_SNAPSHOT_OUT) -D $(PRIVATE_VNDK_SNAPSHOT_OUT)
@@ -212,12 +159,7 @@
# clear global vars
clang-ubsan-vndk-core :=
paths-of-intermediates :=
-paths-of-notice-files :=
-vndk_core_libs :=
-vndk_sp_libs :=
-vndk_snapshot_libs :=
vndk_prebuilt_txts :=
-vndk_snapshot_configs :=
vndk_snapshot_top :=
vndk_snapshot_out :=
vndk_snapshot_configs_out :=
diff --git a/core/version_defaults.mk b/core/version_defaults.mk
index b248fd3..2714f83 100644
--- a/core/version_defaults.mk
+++ b/core/version_defaults.mk
@@ -261,7 +261,7 @@
# It must be of the form "YYYY-MM-DD" on production devices.
# It must match one of the Android Security Patch Level strings of the Public Security Bulletins.
# If there is no $PLATFORM_SECURITY_PATCH set, keep it empty.
- PLATFORM_SECURITY_PATCH := 2019-04-05
+ PLATFORM_SECURITY_PATCH := 2019-05-05
endif
.KATI_READONLY := PLATFORM_SECURITY_PATCH
diff --git a/target/board/BoardConfigMainlineCommon.mk b/target/board/BoardConfigMainlineCommon.mk
index 6c56671..be7c804 100644
--- a/target/board/BoardConfigMainlineCommon.mk
+++ b/target/board/BoardConfigMainlineCommon.mk
@@ -36,9 +36,6 @@
BOARD_CHARGER_ENABLE_SUSPEND := true
-# Enable A/B update
-AB_OTA_UPDATER := true
-
# Enable system property split for Treble
BOARD_PROPERTY_OVERRIDES_SPLIT_ENABLED := true
diff --git a/target/board/mainline_arm64/BoardConfig.mk b/target/board/mainline_arm64/BoardConfig.mk
index 8bb6212..70505f4 100644
--- a/target/board/mainline_arm64/BoardConfig.mk
+++ b/target/board/mainline_arm64/BoardConfig.mk
@@ -28,6 +28,8 @@
TARGET_NO_KERNEL := true
+# Build generic A/B format system-only OTA.
+AB_OTA_UPDATER := true
AB_OTA_PARTITIONS := system
BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE := ext4
diff --git a/target/product/base_system.mk b/target/product/base_system.mk
index 23289f5..606a605 100644
--- a/target/product/base_system.mk
+++ b/target/product/base_system.mk
@@ -122,8 +122,6 @@
libcamera2ndk \
libcamera_client \
libcameraservice \
- libc_malloc_debug \
- libc_malloc_hooks \
libcutils \
libdl.bootstrap \
libdrmframework \
diff --git a/target/product/updatable_apex.mk b/target/product/updatable_apex.mk
index 4b31578..038f66e 100644
--- a/target/product/updatable_apex.mk
+++ b/target/product/updatable_apex.mk
@@ -18,3 +18,4 @@
PRODUCT_PROPERTY_OVERRIDES := ro.apex.updatable=true
PRODUCT_PACKAGES := com.android.apex.cts.shim.v1_prebuilt
+TARGET_FLATTEN_APEX := false
diff --git a/tools/droiddoc/Android.bp b/tools/droiddoc/Android.bp
new file mode 100644
index 0000000..0428068
--- /dev/null
+++ b/tools/droiddoc/Android.bp
@@ -0,0 +1,18 @@
+// Copyright (C) 2013 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.
+
+droiddoc_exported_dir {
+ name: "droiddoc-templates-pdk",
+ path: "templates-pdk",
+}
diff --git a/tools/releasetools/add_img_to_target_files.py b/tools/releasetools/add_img_to_target_files.py
index 99ffa31..4156c8b 100755
--- a/tools/releasetools/add_img_to_target_files.py
+++ b/tools/releasetools/add_img_to_target_files.py
@@ -730,6 +730,7 @@
OPTIONS.info_dict = common.LoadInfoDict(OPTIONS.input_tmp, repacking=True)
has_recovery = OPTIONS.info_dict.get("no_recovery") != "true"
+ has_boot = OPTIONS.info_dict.get("no_boot") != "true"
# {vendor,odm,product,product_services}.img are unlike system.img or
# system_other.img. Because it could be built from source, or dropped into
@@ -777,17 +778,19 @@
def banner(s):
logger.info("\n\n++++ " + s + " ++++\n\n")
- banner("boot")
- # common.GetBootableImage() returns the image directly if present.
- boot_image = common.GetBootableImage(
- "IMAGES/boot.img", "boot.img", OPTIONS.input_tmp, "BOOT")
- # boot.img may be unavailable in some targets (e.g. aosp_arm64).
- if boot_image:
- partitions['boot'] = os.path.join(OPTIONS.input_tmp, "IMAGES", "boot.img")
- if not os.path.exists(partitions['boot']):
- boot_image.WriteToDir(OPTIONS.input_tmp)
- if output_zip:
- boot_image.AddToZip(output_zip)
+ boot_image = None
+ if has_boot:
+ banner("boot")
+ # common.GetBootableImage() returns the image directly if present.
+ boot_image = common.GetBootableImage(
+ "IMAGES/boot.img", "boot.img", OPTIONS.input_tmp, "BOOT")
+ # boot.img may be unavailable in some targets (e.g. aosp_arm64).
+ if boot_image:
+ partitions['boot'] = os.path.join(OPTIONS.input_tmp, "IMAGES", "boot.img")
+ if not os.path.exists(partitions['boot']):
+ boot_image.WriteToDir(OPTIONS.input_tmp)
+ if output_zip:
+ boot_image.AddToZip(output_zip)
recovery_image = None
if has_recovery:
diff --git a/tools/releasetools/apex_utils.py b/tools/releasetools/apex_utils.py
index d14c94f..fb4ca76 100644
--- a/tools/releasetools/apex_utils.py
+++ b/tools/releasetools/apex_utils.py
@@ -19,11 +19,14 @@
import re
import shlex
import sys
+import zipfile
import common
logger = logging.getLogger(__name__)
+OPTIONS = common.OPTIONS
+
class ApexInfoError(Exception):
"""An Exception raised during Apex Information command."""
@@ -145,3 +148,72 @@
'Failed to find {} prop in {}'.format(key, payload_path))
return payload_info
+
+
+def SignApex(apex_data, payload_key, container_key, container_pw,
+ codename_to_api_level_map, signing_args=None):
+ """Signs the current APEX with the given payload/container keys.
+
+ Args:
+ apex_data: Raw APEX data.
+ payload_key: The path to payload signing key (w/ extension).
+ container_key: The path to container signing key (w/o extension).
+ container_pw: The matching password of the container_key, or None.
+ codename_to_api_level_map: A dict that maps from codename to API level.
+ signing_args: Additional args to be passed to the payload signer.
+
+ Returns:
+ The path to the signed APEX file.
+ """
+ apex_file = common.MakeTempFile(prefix='apex-', suffix='.apex')
+ with open(apex_file, 'wb') as apex_fp:
+ apex_fp.write(apex_data)
+
+ APEX_PAYLOAD_IMAGE = 'apex_payload.img'
+ APEX_PUBKEY = 'apex_pubkey'
+
+ # 1a. Extract and sign the APEX_PAYLOAD_IMAGE entry with the given
+ # payload_key.
+ payload_dir = common.MakeTempDir(prefix='apex-payload-')
+ with zipfile.ZipFile(apex_file) as apex_fd:
+ payload_file = apex_fd.extract(APEX_PAYLOAD_IMAGE, payload_dir)
+
+ payload_info = ParseApexPayloadInfo(payload_file)
+ SignApexPayload(
+ payload_file,
+ payload_key,
+ payload_info['apex.key'],
+ payload_info['Algorithm'],
+ payload_info['Salt'],
+ signing_args)
+
+ # 1b. Update the embedded payload public key.
+ payload_public_key = common.ExtractAvbPublicKey(payload_key)
+
+ common.ZipDelete(apex_file, APEX_PAYLOAD_IMAGE)
+ common.ZipDelete(apex_file, APEX_PUBKEY)
+ apex_zip = zipfile.ZipFile(apex_file, 'a')
+ common.ZipWrite(apex_zip, payload_file, arcname=APEX_PAYLOAD_IMAGE)
+ common.ZipWrite(apex_zip, payload_public_key, arcname=APEX_PUBKEY)
+ common.ZipClose(apex_zip)
+
+ # 2. Align the files at page boundary (same as in apexer).
+ aligned_apex = common.MakeTempFile(prefix='apex-container-', suffix='.apex')
+ common.RunAndCheckOutput(['zipalign', '-f', '4096', apex_file, aligned_apex])
+
+ # 3. Sign the APEX container with container_key.
+ signed_apex = common.MakeTempFile(prefix='apex-container-', suffix='.apex')
+
+ # Specify the 4K alignment when calling SignApk.
+ extra_signapk_args = OPTIONS.extra_signapk_args[:]
+ extra_signapk_args.extend(['-a', '4096'])
+
+ common.SignFile(
+ aligned_apex,
+ signed_apex,
+ container_key,
+ container_pw,
+ codename_to_api_level_map=codename_to_api_level_map,
+ extra_signapk_args=extra_signapk_args)
+
+ return signed_apex
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index 495fec3..e642297 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -332,10 +332,8 @@
raise ValueError("Failed to find 'fstab_version'")
if repacking:
- # We carry a copy of file_contexts.bin under META/. If not available, search
- # BOOT/RAMDISK/. Note that sometimes we may need a different file to build
- # images than the one running on device, in that case, we must have the one
- # for image generation copied to META/.
+ # "selinux_fc" should point to the file_contexts file (file_contexts.bin)
+ # under META/.
fc_basename = os.path.basename(d.get("selinux_fc", "file_contexts"))
fc_config = os.path.join(input_file, "META", fc_basename)
assert os.path.exists(fc_config)
diff --git a/tools/releasetools/img_from_target_files.py b/tools/releasetools/img_from_target_files.py
index 6165d96..8fb9871 100755
--- a/tools/releasetools/img_from_target_files.py
+++ b/tools/releasetools/img_from_target_files.py
@@ -180,8 +180,10 @@
OPTIONS.input_tmp = target_files
elif zipfile.is_zipfile(target_files):
logger.info("Building image zip from target files zip.")
- OPTIONS.input_tmp = common.UnzipTemp(target_files,
- ["IMAGES/*", "OTA/*", "META/*"])
+ # We need files under IMAGES/, OTA/, META/ for img_from_target_files.py.
+ # However, common.LoadInfoDict() may read additional files under BOOT/,
+ # RECOVERY/ and ROOT/. So unzip everything from the target_files.zip.
+ OPTIONS.input_tmp = common.UnzipTemp(target_files)
else:
raise ValueError("%s is not a valid path." % target_files)
diff --git a/tools/releasetools/merge_target_files.py b/tools/releasetools/merge_target_files.py
index f0d55d7..2a722c5 100755
--- a/tools/releasetools/merge_target_files.py
+++ b/tools/releasetools/merge_target_files.py
@@ -185,6 +185,26 @@
]
+def write_sorted_data(data, path):
+ """Write the sorted contents of either a list or dict to file.
+
+ This function sorts the contents of the list or dict and then
+ writes the resulting sorted contents to a file specified by path.
+
+ Args:
+ data: The list or dict to sort and write.
+ path: Path to the file to write the sorted values to. The file at path will
+ be overridden if it exists.
+ """
+ with open(path, 'w') as output:
+ sorted_data = sorted(data.keys()) if isinstance(data,
+ dict) else sorted(data)
+ for entry in sorted_data:
+ out_str = '{}={}\n'.format(entry, data[entry]) if isinstance(
+ data, dict) else '{}\n'.format(entry)
+ output.write(out_str)
+
+
def extract_items(target_files, target_files_temp_dir, extract_item_list):
"""Extract items from target files to temporary directory.
@@ -341,9 +361,7 @@
output_ab_partitions_txt = os.path.join(output_target_files_temp_dir, 'META',
'ab_partitions.txt')
- with open(output_ab_partitions_txt, 'w') as output:
- for partition in sorted(output_ab_partitions):
- output.write('%s\n' % partition)
+ write_sorted_data(data=output_ab_partitions, path=output_ab_partitions_txt)
def append_recovery_to_filesystem_config(output_target_files_temp_dir):
@@ -372,6 +390,63 @@
'selabel=u:object_r:install_recovery_exec:s0 capabilities=0x0\n')
+def merge_dynamic_partition_info_dicts(system_dict,
+ other_dict,
+ include_dynamic_partition_list=True,
+ size_prefix='',
+ size_suffix='',
+ list_prefix='',
+ list_suffix=''):
+ """Merges dynamic partition info variables.
+
+ Args:
+ system_dict: The dictionary of dynamic partition info variables from the
+ partial system target files.
+ other_dict: The dictionary of dynamic partition info variables from the
+ partial other target files.
+ include_dynamic_partition_list: If true, merges the dynamic_partition_list
+ variable. Not all use cases need this variable merged.
+ size_prefix: The prefix in partition group size variables that precedes the
+ name of the partition group. For example, partition group 'group_a' with
+ corresponding size variable 'super_group_a_group_size' would have the
+ size_prefix 'super_'.
+ size_suffix: Similar to size_prefix but for the variable's suffix. For
+ example, 'super_group_a_group_size' would have size_suffix '_group_size'.
+ list_prefix: Similar to size_prefix but for the partition group's
+ partition_list variable.
+ list_suffix: Similar to size_suffix but for the partition group's
+ partition_list variable.
+
+ Returns:
+ The merged dynamic partition info dictionary.
+ """
+ merged_dict = {}
+ # Partition groups and group sizes are defined by the other (non-system)
+ # dict because these values may vary for each board that uses a shared system
+ # image.
+ merged_dict['super_partition_groups'] = other_dict['super_partition_groups']
+ if include_dynamic_partition_list:
+ system_dynamic_partition_list = system_dict.get('dynamic_partition_list',
+ '')
+ other_dynamic_partition_list = other_dict.get('dynamic_partition_list', '')
+ merged_dict['dynamic_partition_list'] = (
+ '%s %s' %
+ (system_dynamic_partition_list, other_dynamic_partition_list)).strip()
+ for partition_group in merged_dict['super_partition_groups'].split(' '):
+ # Set the partition group's size using the value from the other dict.
+ key = '%s%s%s' % (size_prefix, partition_group, size_suffix)
+ if key not in other_dict:
+ raise ValueError('Other dict does not contain required key %s.' % key)
+ merged_dict[key] = other_dict[key]
+
+ # Set the partition group's partition list using a concatenation of the
+ # system and other partition lists.
+ key = '%s%s%s' % (list_prefix, partition_group, list_suffix)
+ merged_dict[key] = (
+ '%s %s' % (system_dict.get(key, ''), other_dict.get(key, ''))).strip()
+ return merged_dict
+
+
def process_misc_info_txt(system_target_files_temp_dir,
other_target_files_temp_dir,
output_target_files_temp_dir, system_misc_info_keys):
@@ -417,30 +492,117 @@
# Merge misc info keys used for Dynamic Partitions.
if (merged_info_dict.get('use_dynamic_partitions') == 'true') and (
system_info_dict.get('use_dynamic_partitions') == 'true'):
- merged_info_dict['dynamic_partition_list'] = '%s %s' % (
- system_info_dict.get('dynamic_partition_list', ''),
- merged_info_dict.get('dynamic_partition_list', ''))
- # Partition groups and group sizes are defined by the other (non-system)
- # misc info file because these values may vary for each board that uses
- # a shared system image.
- for partition_group in merged_info_dict['super_partition_groups'].split(
- ' '):
- if ('super_%s_group_size' % partition_group) not in merged_info_dict:
- raise ValueError(
- 'Other META/misc_info.txt does not contain required key '
- 'super_%s_group_size.' % partition_group)
- key = 'super_%s_partition_list' % partition_group
- merged_info_dict[key] = '%s %s' % (system_info_dict.get(
- key, ''), merged_info_dict.get(key, ''))
+ merged_dynamic_partitions_dict = merge_dynamic_partition_info_dicts(
+ system_dict=system_info_dict,
+ other_dict=merged_info_dict,
+ size_prefix='super_',
+ size_suffix='_group_size',
+ list_prefix='super_',
+ list_suffix='_partition_list')
+ merged_info_dict.update(merged_dynamic_partitions_dict)
output_misc_info_txt = os.path.join(output_target_files_temp_dir, 'META',
'misc_info.txt')
+ write_sorted_data(data=merged_info_dict, path=output_misc_info_txt)
- sorted_keys = sorted(merged_info_dict.keys())
- with open(output_misc_info_txt, 'w') as output:
- for key in sorted_keys:
- output.write('{}={}\n'.format(key, merged_info_dict[key]))
+def process_dynamic_partitions_info_txt(system_target_files_dir,
+ other_target_files_dir,
+ output_target_files_dir):
+ """Perform special processing for META/dynamic_partitions_info.txt.
+
+ This function merges the contents of the META/dynamic_partitions_info.txt
+ files from the system directory and the other directory, placing the merged
+ result in the output directory.
+
+ This function does nothing if META/dynamic_partitions_info.txt from the other
+ directory does not exist.
+
+ Args:
+ system_target_files_dir: The name of a directory containing the special
+ items extracted from the system target files package.
+ other_target_files_dir: The name of a directory containing the special items
+ extracted from the other target files package.
+ output_target_files_dir: The name of a directory that will be used to create
+ the output target files package after all the special cases are processed.
+ """
+
+ if not os.path.exists(
+ os.path.join(other_target_files_dir, 'META',
+ 'dynamic_partitions_info.txt')):
+ return
+
+ def read_helper(d):
+ dynamic_partitions_info_txt = os.path.join(d, 'META',
+ 'dynamic_partitions_info.txt')
+ with open(dynamic_partitions_info_txt) as f:
+ return list(f.read().splitlines())
+
+ system_dynamic_partitions_dict = common.LoadDictionaryFromLines(
+ read_helper(system_target_files_dir))
+ other_dynamic_partitions_dict = common.LoadDictionaryFromLines(
+ read_helper(other_target_files_dir))
+
+ merged_dynamic_partitions_dict = merge_dynamic_partition_info_dicts(
+ system_dict=system_dynamic_partitions_dict,
+ other_dict=other_dynamic_partitions_dict,
+ # META/dynamic_partitions_info.txt does not use dynamic_partition_list.
+ include_dynamic_partition_list=False,
+ size_suffix='_size',
+ list_suffix='_partition_list')
+
+ output_dynamic_partitions_info_txt = os.path.join(
+ output_target_files_dir, 'META', 'dynamic_partitions_info.txt')
+ write_sorted_data(
+ data=merged_dynamic_partitions_dict,
+ path=output_dynamic_partitions_info_txt)
+
+
+def process_apex_keys_apk_certs_common(system_target_files_dir,
+ other_target_files_dir,
+ output_target_files_dir, file_name):
+ """Perform special processing for META/apexkeys.txt or META/apkcerts.txt.
+
+ This function merges the contents of the META/apexkeys.txt or
+ META/apkcerts.txt
+ files from the system directory and the other directory, placing the merged
+ result in the output directory. The precondition in that the files are already
+ extracted.
+ The post condition is that the output META/apexkeys.txt or META/apkcerts.txt
+ contains the merged content.
+
+ Args:
+ system_target_files_dir: The name of a directory containing the special
+ items extracted from the system target files package.
+ other_target_files_dir: The name of a directory containing the special items
+ extracted from the other target files package.
+ output_target_files_dir: The name of a directory that will be used to create
+ the output target files package after all the special cases are processed.
+ file_name: The name of the file to merge. One of apkcerts.txt or
+ apexkeys.txt.
+ """
+
+ def read_helper(d):
+ temp = {}
+ file_path = os.path.join(d, 'META', file_name)
+ with open(file_path) as f:
+ for line in f:
+ if line.strip():
+ temp[line.split()[0]] = line.strip()
+ return temp
+
+ system_dict = read_helper(system_target_files_dir)
+ other_dict = read_helper(other_target_files_dir)
+
+ for key in system_dict:
+ if key in other_dict and other_dict[key] != system_dict[key]:
+ raise ValueError('Conflicting entries found in %s:\n %s and\n %s' %
+ (file_name, system_dict[key], other_dict[key]))
+ other_dict[key] = system_dict[key]
+
+ output_file = os.path.join(output_target_files_dir, 'META', file_name)
+
+ write_sorted_data(data=other_dict.values(), path=output_file)
def process_special_cases(system_target_files_temp_dir,
@@ -482,6 +644,23 @@
output_target_files_temp_dir=output_target_files_temp_dir,
system_misc_info_keys=system_misc_info_keys)
+ process_dynamic_partitions_info_txt(
+ system_target_files_dir=system_target_files_temp_dir,
+ other_target_files_dir=other_target_files_temp_dir,
+ output_target_files_dir=output_target_files_temp_dir)
+
+ process_apex_keys_apk_certs_common(
+ system_target_files_dir=system_target_files_temp_dir,
+ other_target_files_dir=other_target_files_temp_dir,
+ output_target_files_dir=output_target_files_temp_dir,
+ file_name='apkcerts.txt')
+
+ process_apex_keys_apk_certs_common(
+ system_target_files_dir=system_target_files_temp_dir,
+ other_target_files_dir=other_target_files_temp_dir,
+ output_target_files_dir=output_target_files_temp_dir,
+ file_name='apexkeys.txt')
+
def merge_target_files(temp_dir, system_target_files, system_item_list,
system_misc_info_keys, other_target_files,
@@ -648,7 +827,8 @@
output_target_files_meta_dir,
]
find_process = common.Run(find_command, stdout=subprocess.PIPE, verbose=False)
- meta_content = common.RunAndCheckOutput(['sort'], stdin=find_process.stdout,
+ meta_content = common.RunAndCheckOutput(['sort'],
+ stdin=find_process.stdout,
verbose=False)
find_command = [
@@ -656,7 +836,8 @@
output_target_files_meta_dir, '-prune', '-o', '-print'
]
find_process = common.Run(find_command, stdout=subprocess.PIPE, verbose=False)
- other_content = common.RunAndCheckOutput(['sort'], stdin=find_process.stdout,
+ other_content = common.RunAndCheckOutput(['sort'],
+ stdin=find_process.stdout,
verbose=False)
with open(output_target_files_list, 'wb') as f:
@@ -686,7 +867,6 @@
ota_from_target_files.main(ota_from_target_files_args)
-
def call_func_with_temp_dir(func, keep_tmp):
"""Manage the creation and cleanup of the temporary directory.
diff --git a/tools/releasetools/sign_apex.py b/tools/releasetools/sign_apex.py
new file mode 100755
index 0000000..1778615
--- /dev/null
+++ b/tools/releasetools/sign_apex.py
@@ -0,0 +1,103 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2019 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.
+
+"""
+Signs a standalone APEX file.
+
+Usage: sign_apex [flags] input_apex_file output_apex_file
+
+ --container_key <key>
+ Mandatory flag that specifies the container signing key.
+
+ --payload_key <key>
+ Mandatory flag that specifies the payload signing key.
+
+ --payload_extra_args <args>
+ Optional flag that specifies any extra args to be passed to payload signer
+ (e.g. --payload_extra_args="--signing_helper_with_files /path/to/helper").
+"""
+
+import logging
+import shutil
+import sys
+
+import apex_utils
+import common
+
+logger = logging.getLogger(__name__)
+
+
+def main(argv):
+
+ options = {}
+
+ def option_handler(o, a):
+ if o == '--container_key':
+ # Strip the suffix if any, as common.SignFile expects no suffix.
+ DEFAULT_CONTAINER_KEY_SUFFIX = '.x509.pem'
+ if a.endswith(DEFAULT_CONTAINER_KEY_SUFFIX):
+ a = a[:-len(DEFAULT_CONTAINER_KEY_SUFFIX)]
+ options['container_key'] = a
+ elif o == '--payload_key':
+ options['payload_key'] = a
+ elif o == '--payload_extra_args':
+ options['payload_extra_args'] = a
+ else:
+ return False
+ return True
+
+ args = common.ParseOptions(
+ argv, __doc__,
+ extra_opts='',
+ extra_long_opts=[
+ 'container_key=',
+ 'payload_extra_args=',
+ 'payload_key=',
+ ],
+ extra_option_handler=option_handler)
+
+ if (len(args) != 2 or 'container_key' not in options or
+ 'payload_key' not in options):
+ common.Usage(__doc__)
+ sys.exit(1)
+
+ common.InitLogging()
+
+ input_zip = args[0]
+ output_zip = args[1]
+ with open(input_zip) as input_fp:
+ apex_data = input_fp.read()
+
+ signed_apex = apex_utils.SignApex(
+ apex_data,
+ payload_key=options['payload_key'],
+ container_key=options['container_key'],
+ container_pw=None,
+ codename_to_api_level_map=None,
+ signing_args=options.get('payload_extra_args'))
+
+ shutil.copyfile(signed_apex, output_zip)
+ logger.info("done.")
+
+
+if __name__ == '__main__':
+ try:
+ main(sys.argv[1:])
+ except common.ExternalError:
+ logger.exception("\n ERROR:\n")
+ sys.exit(1)
+ finally:
+ common.Cleanup()
diff --git a/tools/releasetools/sign_target_files_apks.py b/tools/releasetools/sign_target_files_apks.py
index 24ee91b..7de0978 100755
--- a/tools/releasetools/sign_target_files_apks.py
+++ b/tools/releasetools/sign_target_files_apks.py
@@ -403,77 +403,6 @@
return data
-def SignApex(apex_data, payload_key, container_key, container_pw,
- codename_to_api_level_map, signing_args=None):
- """Signs the current APEX with the given payload/container keys.
-
- Args:
- apex_data: Raw APEX data.
- payload_key: The path to payload signing key (w/ extension).
- container_key: The path to container signing key (w/o extension).
- container_pw: The matching password of the container_key, or None.
- codename_to_api_level_map: A dict that maps from codename to API level.
- signing_args: Additional args to be passed to the payload signer.
-
- Returns:
- The path to the signed APEX file.
- """
- apex_file = common.MakeTempFile(prefix='apex-', suffix='.apex')
- with open(apex_file, 'wb') as apex_fp:
- apex_fp.write(apex_data)
-
- APEX_PAYLOAD_IMAGE = 'apex_payload.img'
- APEX_PUBKEY = 'apex_pubkey'
-
- # 1a. Extract and sign the APEX_PAYLOAD_IMAGE entry with the given
- # payload_key.
- payload_dir = common.MakeTempDir(prefix='apex-payload-')
- with zipfile.ZipFile(apex_file) as apex_fd:
- payload_file = apex_fd.extract(APEX_PAYLOAD_IMAGE, payload_dir)
-
- payload_info = apex_utils.ParseApexPayloadInfo(payload_file)
- apex_utils.SignApexPayload(
- payload_file,
- payload_key,
- payload_info['apex.key'],
- payload_info['Algorithm'],
- payload_info['Salt'],
- signing_args)
-
- # 1b. Update the embedded payload public key.
- payload_public_key = common.ExtractAvbPublicKey(payload_key)
-
- common.ZipDelete(apex_file, APEX_PAYLOAD_IMAGE)
- common.ZipDelete(apex_file, APEX_PUBKEY)
- apex_zip = zipfile.ZipFile(apex_file, 'a')
- common.ZipWrite(apex_zip, payload_file, arcname=APEX_PAYLOAD_IMAGE)
- common.ZipWrite(apex_zip, payload_public_key, arcname=APEX_PUBKEY)
- common.ZipClose(apex_zip)
-
- # 2. Align the files at page boundary (same as in apexer).
- aligned_apex = common.MakeTempFile(
- prefix='apex-container-', suffix='.apex')
- common.RunAndCheckOutput(
- ['zipalign', '-f', '4096', apex_file, aligned_apex])
-
- # 3. Sign the APEX container with container_key.
- signed_apex = common.MakeTempFile(prefix='apex-container-', suffix='.apex')
-
- # Specify the 4K alignment when calling SignApk.
- extra_signapk_args = OPTIONS.extra_signapk_args[:]
- extra_signapk_args.extend(['-a', '4096'])
-
- common.SignFile(
- aligned_apex,
- signed_apex,
- container_key,
- container_pw,
- codename_to_api_level_map=codename_to_api_level_map,
- extra_signapk_args=extra_signapk_args)
-
- return signed_apex
-
-
def ProcessTargetFiles(input_tf_zip, output_tf_zip, misc_info,
apk_keys, apex_keys, key_passwords,
platform_api_level, codename_to_api_level_map,
@@ -538,7 +467,7 @@
print(" : %-*s payload (%s)" % (
maxsize, name, payload_key))
- signed_apex = SignApex(
+ signed_apex = apex_utils.SignApex(
data,
payload_key,
container_key,
diff --git a/tools/releasetools/test_merge_target_files.py b/tools/releasetools/test_merge_target_files.py
index 7e18a34..1e29fde 100644
--- a/tools/releasetools/test_merge_target_files.py
+++ b/tools/releasetools/test_merge_target_files.py
@@ -21,7 +21,9 @@
from merge_target_files import (read_config_list, validate_config_lists,
default_system_item_list,
default_other_item_list,
- default_system_misc_info_keys, copy_items)
+ default_system_misc_info_keys, copy_items,
+ merge_dynamic_partition_info_dicts,
+ process_apex_keys_apk_certs_common)
class MergeTargetFilesTest(test_utils.ReleaseToolsTestCase):
@@ -128,3 +130,86 @@
self.assertFalse(
validate_config_lists(default_system_item_list, system_misc_info_keys,
default_other_item_list))
+
+ def test_merge_dynamic_partition_info_dicts_ReturnsMergedDict(self):
+ system_dict = {
+ 'super_partition_groups': 'group_a',
+ 'dynamic_partition_list': 'system',
+ 'super_group_a_list': 'system',
+ }
+ other_dict = {
+ 'super_partition_groups': 'group_a group_b',
+ 'dynamic_partition_list': 'vendor product',
+ 'super_group_a_list': 'vendor',
+ 'super_group_a_size': '1000',
+ 'super_group_b_list': 'product',
+ 'super_group_b_size': '2000',
+ }
+ merged_dict = merge_dynamic_partition_info_dicts(
+ system_dict=system_dict,
+ other_dict=other_dict,
+ size_prefix='super_',
+ size_suffix='_size',
+ list_prefix='super_',
+ list_suffix='_list')
+ expected_merged_dict = {
+ 'super_partition_groups': 'group_a group_b',
+ 'dynamic_partition_list': 'system vendor product',
+ 'super_group_a_list': 'system vendor',
+ 'super_group_a_size': '1000',
+ 'super_group_b_list': 'product',
+ 'super_group_b_size': '2000',
+ }
+ self.assertEqual(merged_dict, expected_merged_dict)
+
+ def test_process_apex_keys_apk_certs_ReturnsTrueIfNoConflicts(self):
+ output_dir = common.MakeTempDir()
+ os.makedirs(os.path.join(output_dir, 'META'))
+
+ system_dir = common.MakeTempDir()
+ os.makedirs(os.path.join(system_dir, 'META'))
+ os.symlink(
+ os.path.join(self.testdata_dir, 'apexkeys_system.txt'),
+ os.path.join(system_dir, 'META', 'apexkeys.txt'))
+
+ other_dir = common.MakeTempDir()
+ os.makedirs(os.path.join(other_dir, 'META'))
+ os.symlink(
+ os.path.join(self.testdata_dir, 'apexkeys_other.txt'),
+ os.path.join(other_dir, 'META', 'apexkeys.txt'))
+
+ process_apex_keys_apk_certs_common(system_dir, other_dir, output_dir,
+ 'apexkeys.txt')
+
+ merged_entries = []
+ merged_path = os.path.join(self.testdata_dir, 'apexkeys_merge.txt')
+
+ with open(merged_path) as f:
+ merged_entries = f.read().split('\n')
+
+ output_entries = []
+ output_path = os.path.join(output_dir, 'META', 'apexkeys.txt')
+
+ with open(output_path) as f:
+ output_entries = f.read().split('\n')
+
+ return self.assertEqual(merged_entries, output_entries)
+
+ def test_process_apex_keys_apk_certs_ReturnsFalseIfConflictsPresent(self):
+ output_dir = common.MakeTempDir()
+ os.makedirs(os.path.join(output_dir, 'META'))
+
+ system_dir = common.MakeTempDir()
+ os.makedirs(os.path.join(system_dir, 'META'))
+ os.symlink(
+ os.path.join(self.testdata_dir, 'apexkeys_system.txt'),
+ os.path.join(system_dir, 'META', 'apexkeys.txt'))
+
+ conflict_dir = common.MakeTempDir()
+ os.makedirs(os.path.join(conflict_dir, 'META'))
+ os.symlink(
+ os.path.join(self.testdata_dir, 'apexkeys_system_conflict.txt'),
+ os.path.join(conflict_dir, 'META', 'apexkeys.txt'))
+
+ self.assertRaises(ValueError, process_apex_keys_apk_certs_common,
+ system_dir, conflict_dir, output_dir, 'apexkeys.txt')
diff --git a/tools/releasetools/testdata/apexkeys_merge.txt b/tools/releasetools/testdata/apexkeys_merge.txt
new file mode 100644
index 0000000..48e789f
--- /dev/null
+++ b/tools/releasetools/testdata/apexkeys_merge.txt
@@ -0,0 +1,4 @@
+name="com.android.conscrypt.apex" public_key="external/conscrypt/apex/com.android.conscrypt.avbpubkey" private_key="external/conscrypt/apex/com.android.conscrypt.pem" container_certificate="external/conscrypt/apex/com.android.conscrypt.x509.pem" container_private_key="external/conscrypt/apex/com.android.conscrypt.pk8"
+name="com.android.runtime.debug.apex" public_key="art/build/apex/com.android.runtime.avbpubkey" private_key="art/build/apex/com.android.runtime.pem" container_certificate="art/build/apex/com.android.runtime.debug.x509.pem" container_private_key="art/build/apex/com.android.runtime.debug.pk8"
+name="com.android.runtime.release.apex" public_key="art/build/apex/com.android.runtime.avbpubkey" private_key="art/build/apex/com.android.runtime.pem" container_certificate="art/build/apex/com.android.runtime.release.x509.pem" container_private_key="art/build/apex/com.android.runtime.release.pk8"
+name="com.android.support.apexer.apex" public_key="system/apex/apexer/etc/com.android.support.apexer.avbpubkey" private_key="system/apex/apexer/etc/com.android.support.apexer.pem" container_certificate="build/target/product/security/testkey.x509.pem" container_private_key="build/target/product/security/testkey.pk8"
diff --git a/tools/releasetools/testdata/apexkeys_other.txt b/tools/releasetools/testdata/apexkeys_other.txt
new file mode 100644
index 0000000..b751227
--- /dev/null
+++ b/tools/releasetools/testdata/apexkeys_other.txt
@@ -0,0 +1,3 @@
+name="com.android.runtime.release.apex" public_key="art/build/apex/com.android.runtime.avbpubkey" private_key="art/build/apex/com.android.runtime.pem" container_certificate="art/build/apex/com.android.runtime.release.x509.pem" container_private_key="art/build/apex/com.android.runtime.release.pk8"
+name="com.android.support.apexer.apex" public_key="system/apex/apexer/etc/com.android.support.apexer.avbpubkey" private_key="system/apex/apexer/etc/com.android.support.apexer.pem" container_certificate="build/target/product/security/testkey.x509.pem" container_private_key="build/target/product/security/testkey.pk8"
+name="com.android.runtime.debug.apex" public_key="art/build/apex/com.android.runtime.avbpubkey" private_key="art/build/apex/com.android.runtime.pem" container_certificate="art/build/apex/com.android.runtime.debug.x509.pem" container_private_key="art/build/apex/com.android.runtime.debug.pk8"
diff --git a/tools/releasetools/testdata/apexkeys_system.txt b/tools/releasetools/testdata/apexkeys_system.txt
new file mode 100644
index 0000000..2346668
--- /dev/null
+++ b/tools/releasetools/testdata/apexkeys_system.txt
@@ -0,0 +1,2 @@
+name="com.android.runtime.debug.apex" public_key="art/build/apex/com.android.runtime.avbpubkey" private_key="art/build/apex/com.android.runtime.pem" container_certificate="art/build/apex/com.android.runtime.debug.x509.pem" container_private_key="art/build/apex/com.android.runtime.debug.pk8"
+name="com.android.conscrypt.apex" public_key="external/conscrypt/apex/com.android.conscrypt.avbpubkey" private_key="external/conscrypt/apex/com.android.conscrypt.pem" container_certificate="external/conscrypt/apex/com.android.conscrypt.x509.pem" container_private_key="external/conscrypt/apex/com.android.conscrypt.pk8"
diff --git a/tools/releasetools/testdata/apexkeys_system_conflict.txt b/tools/releasetools/testdata/apexkeys_system_conflict.txt
new file mode 100644
index 0000000..caa21c2
--- /dev/null
+++ b/tools/releasetools/testdata/apexkeys_system_conflict.txt
@@ -0,0 +1 @@
+name="com.android.runtime.debug.apex" public_key="art/build/apex/com.android.runtime.avbpubkey" private_key="art/build/apex/com.android.runtime.pem" container_certificate="art/build/apex/com.android.runtime.release.x509.pem" container_private_key="art/build/apex/com.android.runtime.debug.pk8"