Merge "Make com.android.sepolicy mandatory"
diff --git a/core/Makefile b/core/Makefile
index a580ac8..bc34305 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -527,16 +527,6 @@
$(eval ALL_DEFAULT_INSTALLED_MODULES += $(call build-image-kernel-modules-dir,GENERIC_RAMDISK,$(TARGET_RAMDISK_OUT),,modules.load,,$(kmd)))))
# -----------------------------------------------------------------
-# FSVerity metadata generation
-ifeq ($(PRODUCT_SYSTEM_FSVERITY_GENERATE_METADATA),true)
-
-FSVERITY_APK_KEY_PATH := $(DEFAULT_SYSTEM_DEV_CERTIFICATE)
-FSVERITY_APK_OUT := system/etc/security/fsverity/BuildManifest.apk
-FSVERITY_APK_MANIFEST_PATH := system/security/fsverity/AndroidManifest.xml
-
-endif # PRODUCT_SYSTEM_FSVERITY_GENERATE_METADATA
-
-# -----------------------------------------------------------------
# Cert-to-package mapping. Used by the post-build signing tools.
# Use a macro to add newline to each echo command
# $1 stem name of the package
@@ -784,6 +774,7 @@
$(INSTALLED_FILES_FILE_ROOT): .KATI_IMPLICIT_OUTPUTS := $(INSTALLED_FILES_JSON_ROOT)
$(INSTALLED_FILES_FILE_ROOT) : $(INTERNAL_ROOT_FILES) $(FILESLIST) $(FILESLIST_UTIL)
@echo Installed file list: $@
+ mkdir -p $(TARGET_ROOT_OUT)
mkdir -p $(dir $@)
rm -f $@
$(FILESLIST) $(TARGET_ROOT_OUT) > $(@:.txt=.json)
@@ -908,8 +899,14 @@
INTERNAL_BOOTIMAGE_ARGS := \
$(addprefix --second ,$(INSTALLED_2NDBOOTLOADER_TARGET))
+INTERNAL_INIT_BOOT_IMAGE_ARGS :=
+
ifneq ($(BOARD_BUILD_SYSTEM_ROOT_IMAGE),true)
-INTERNAL_BOOTIMAGE_ARGS += --ramdisk $(INSTALLED_RAMDISK_TARGET)
+ ifneq ($(BUILDING_INIT_BOOT_IMAGE),true)
+ INTERNAL_BOOTIMAGE_ARGS += --ramdisk $(INSTALLED_RAMDISK_TARGET)
+ else
+ INTERNAL_INIT_BOOT_IMAGE_ARGS += --ramdisk $(INSTALLED_RAMDISK_TARGET)
+ endif
endif
ifndef BUILDING_VENDOR_BOOT_IMAGE
@@ -1089,6 +1086,58 @@
my_installed_prebuilt_gki_apex :=
# -----------------------------------------------------------------
+# init boot image
+ifeq ($(BUILDING_INIT_BOOT_IMAGE),true)
+
+INSTALLED_INIT_BOOT_IMAGE_TARGET := $(PRODUCT_OUT)/init_boot.img
+$(INSTALLED_INIT_BOOT_IMAGE_TARGET): $(MKBOOTIMG) $(INSTALLED_RAMDISK_TARGET)
+
+ifdef BOARD_KERNEL_PAGESIZE
+ INTERNAL_INIT_BOOT_IMAGE_ARGS += --pagesize $(BOARD_KERNEL_PAGESIZE)
+endif
+
+ifeq ($(BOARD_AVB_ENABLE),true)
+$(INSTALLED_INIT_BOOT_IMAGE_TARGET): $(AVBTOOL) $(BOARD_AVB_INIT_BOOT_KEY_PATH)
+ $(call pretty,"Target init_boot image: $@")
+ $(MKBOOTIMG) $(INTERNAL_INIT_BOOT_IMAGE_ARGS) $(INTERNAL_MKBOOTIMG_VERSION_ARGS) $(BOARD_MKBOOTIMG_INIT_ARGS) --output $@
+ $(call assert-max-image-size,$@,$(BOARD_INIT_BOOT_IMAGE_PARTITION_SIZE))
+ $(AVBTOOL) add_hash_footer \
+ --image $@ \
+ --partition_size $(BOARD_INIT_BOOT_IMAGE_PARTITION_SIZE) \
+ --partition_name init_boot $(INTERNAL_AVB_INIT_BOOT_SIGNING_ARGS) \
+ $(BOARD_AVB_INIT_BOOT_ADD_HASH_FOOTER_ARGS)
+else
+$(INSTALLED_INIT_BOOT_IMAGE_TARGET):
+ $(call pretty,"Target init_boot image: $@")
+ $(MKBOOTIMG) $(INTERNAL_INIT_BOOT_IMAGE_ARGS) $(INTERNAL_MKBOOTIMG_VERSION_ARGS) $(BOARD_MKBOOTIMG_INIT_ARGS) --output $@
+ $(call assert-max-image-size,$@,$(BOARD_INIT_BOOT_IMAGE_PARTITION_SIZE))
+endif
+
+else # BUILDING_INIT_BOOT_IMAGE is not true
+
+ifdef BOARD_PREBUILT_INIT_BOOT_IMAGE
+INTERNAL_PREBUILT_INIT_BOOT_IMAGE := $(BOARD_PREBUILT_INIT_BOOT_IMAGE)
+INSTALLED_INIT_BOOT_IMAGE_TARGET := $(PRODUCT_OUT)/init_boot.img
+
+ifeq ($(BOARD_AVB_ENABLE),true)
+$(INSTALLED_INIT_BOOT_IMAGE_TARGET): $(INTERNAL_PREBUILT_INIT_BOOT_IMAGE) $(AVBTOOL) $(BOARD_AVB_INIT_BOOT_KEY_PATH)
+ cp $(INTERNAL_PREBUILT_INIT_BOOT_IMAGE) $@
+ $(AVBTOOL) add_hash_footer \
+ --image $@ \
+ --partition_size $(BOARD_INIT_BOOT_IMAGE_PARTITION_SIZE) \
+ --partition_name boot $(INTERNAL_AVB_INIT_BOOT_SIGNING_ARGS) \
+ $(BOARD_AVB_INIT_BOOT_ADD_HASH_FOOTER_ARGS)
+else
+$(INSTALLED_INIT_BOOT_IMAGE_TARGET): $(INTERNAL_PREBUILT_INIT_BOOT_IMAGE)
+ cp $(INTERNAL_PREBUILT_INIT_BOOT_IMAGE) $@
+endif # BOARD_AVB_ENABLE
+
+else # BOARD_PREBUILT_INIT_BOOT_IMAGE not defined
+INSTALLED_INIT_BOOT_IMAGE_TARGET :=
+endif # BOARD_PREBUILT_INIT_BOOT_IMAGE
+
+endif # BUILDING_INIT_BOOT_IMAGE is not true
+# -----------------------------------------------------------------
# vendor boot image
ifeq ($(BUILDING_VENDOR_BOOT_IMAGE),true)
@@ -1685,11 +1734,6 @@
$(if $(filter $(2),system),\
$(if $(INTERNAL_SYSTEM_OTHER_PARTITION_SIZE),$(hide) echo "system_other_size=$(INTERNAL_SYSTEM_OTHER_PARTITION_SIZE)" >> $(1))
$(if $(PRODUCT_SYSTEM_HEADROOM),$(hide) echo "system_headroom=$(PRODUCT_SYSTEM_HEADROOM)" >> $(1))
- $(if $(filter true,$(PRODUCT_SYSTEM_FSVERITY_GENERATE_METADATA)),$(hide) echo "fsverity=$(HOST_OUT_EXECUTABLES)/fsverity" >> $(1))
- $(if $(filter true,$(PRODUCT_SYSTEM_FSVERITY_GENERATE_METADATA)),$(hide) echo "fsverity_generate_metadata=true" >> $(1))
- $(if $(filter true,$(PRODUCT_SYSTEM_FSVERITY_GENERATE_METADATA)),$(hide) echo "fsverity_apk_key=$(FSVERITY_APK_KEY_PATH)" >> $(1))
- $(if $(filter true,$(PRODUCT_SYSTEM_FSVERITY_GENERATE_METADATA)),$(hide) echo "fsverity_apk_manifest=$(FSVERITY_APK_MANIFEST_PATH)" >> $(1))
- $(if $(filter true,$(PRODUCT_SYSTEM_FSVERITY_GENERATE_METADATA)),$(hide) echo "fsverity_apk_out=$(FSVERITY_APK_OUT)" >> $(1))
$(call add-common-ro-flags-to-image-props,system,$(1))
)
$(if $(filter $(2),system_other),\
@@ -2251,7 +2295,7 @@
$(INTERNAL_MKBOOTIMG_VERSION_ARGS) $(BOARD_RECOVERY_MKBOOTIMG_ARGS) \
--output $(1).unsigned, \
$(MKBOOTIMG) $(if $(strip $(2)),--kernel $(strip $(2))) $(INTERNAL_RECOVERYIMAGE_ARGS) \
- $(INTERNAL_MKBOOTIMG_VERSION_ARGS) $(INTERNAL_MKBOOTIMG_GKI_SINGING_ARGS) \
+ $(INTERNAL_MKBOOTIMG_VERSION_ARGS) \
$(BOARD_RECOVERY_MKBOOTIMG_ARGS) --output $(1))
$(if $(filter true,$(PRODUCT_SUPPORTS_BOOT_SIGNER)),\
$(if $(filter true,$(BOARD_USES_RECOVERY_AS_BOOT)),\
@@ -2280,9 +2324,6 @@
ifeq (true,$(BOARD_AVB_ENABLE))
recoveryimage-deps += $(AVBTOOL) $(BOARD_AVB_BOOT_KEY_PATH)
endif
-ifdef BOARD_GKI_SIGNING_KEY_PATH
- recoveryimage-deps += $(BOARD_GKI_SIGNING_KEY_PATH) $(AVBTOOL)
-endif
ifdef BOARD_INCLUDE_RECOVERY_DTBO
ifdef BOARD_PREBUILT_RECOVERY_DTBOIMAGE
recoveryimage-deps += $(BOARD_PREBUILT_RECOVERY_DTBOIMAGE)
@@ -2446,17 +2487,17 @@
define build-debug-bootimage-target
$(MKBOOTIMG) --kernel $(PRODUCT_OUT)/$(subst .img,,$(subst boot-debug,kernel,$(notdir $(1)))) \
$(INTERNAL_DEBUG_BOOTIMAGE_ARGS) $(INTERNAL_MKBOOTIMG_VERSION_ARGS) \
- $(INTERNAL_MKBOOTIMG_GKI_SINGING_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $1
+ $(BOARD_MKBOOTIMG_ARGS) --output $1
$(if $(BOARD_AVB_BOOT_KEY_PATH),$(call test-key-sign-bootimage,$1,boot-debug))
endef
# Depends on original boot.img and ramdisk-debug.img, to build the new boot-debug.img
-$(INSTALLED_DEBUG_BOOTIMAGE_TARGET): $(MKBOOTIMG) $(INSTALLED_BOOTIMAGE_TARGET) $(BOARD_GKI_SIGNING_KEY_PATH) $(AVBTOOL)
+$(INSTALLED_DEBUG_BOOTIMAGE_TARGET): $(MKBOOTIMG) $(INSTALLED_BOOTIMAGE_TARGET) $(AVBTOOL)
$(call pretty,"Target boot debug image: $@")
$(call build-debug-bootimage-target, $@)
.PHONY: bootimage_debug-nodeps
-bootimage_debug-nodeps: $(MKBOOTIMG) $(BOARD_GKI_SIGNING_KEY_PATH) $(AVBTOOL)
+bootimage_debug-nodeps: $(MKBOOTIMG) $(AVBTOOL)
echo "make $@: ignoring dependencies"
$(foreach b,$(INSTALLED_DEBUG_BOOTIMAGE_TARGET),$(call build-debug-bootimage-target,$b))
@@ -2623,17 +2664,17 @@
define build-boot-test-harness-target
$(MKBOOTIMG) --kernel $(PRODUCT_OUT)/$(subst .img,,$(subst boot-test-harness,kernel,$(notdir $(1)))) \
$(INTERNAL_TEST_HARNESS_BOOTIMAGE_ARGS) $(INTERNAL_MKBOOTIMG_VERSION_ARGS) \
- $(INTERNAL_MKBOOTIMG_GKI_SINGING_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $@
+ $(BOARD_MKBOOTIMG_ARGS) --output $@
$(if $(BOARD_AVB_BOOT_KEY_PATH),$(call test-key-sign-bootimage,$@,boot-test-harness))
endef
# Build the new boot-test-harness.img, based on boot-debug.img and ramdisk-test-harness.img.
-$(INSTALLED_TEST_HARNESS_BOOTIMAGE_TARGET): $(MKBOOTIMG) $(INSTALLED_DEBUG_BOOTIMAGE_TARGET) $(BOARD_GKI_SIGNING_KEY_PATH) $(AVBTOOL)
+$(INSTALLED_TEST_HARNESS_BOOTIMAGE_TARGET): $(MKBOOTIMG) $(INSTALLED_DEBUG_BOOTIMAGE_TARGET) $(AVBTOOL)
$(call pretty,"Target boot test harness image: $@")
$(call build-boot-test-harness-target,$@)
.PHONY: bootimage_test_harness-nodeps
-bootimage_test_harness-nodeps: $(MKBOOTIMG) $(BOARD_GKI_SIGNING_KEY_PATH) $(AVBTOOL)
+bootimage_test_harness-nodeps: $(MKBOOTIMG) $(AVBTOOL)
echo "make $@: ignoring dependencies"
$(foreach b,$(INSTALLED_TEST_HARNESS_BOOTIMAGE_TARGET),$(call build-boot-test-harness-target,$b))
@@ -2709,6 +2750,61 @@
# -----------------------------------------------------------------
# system image
+# FSVerity metadata generation
+# Generate fsverity metadata files (.fsv_meta) and build manifest
+# (system/etc/security/fsverity/BuildManifest.apk) BEFORE filtering systemimage files below
+ifeq ($(PRODUCT_SYSTEM_FSVERITY_GENERATE_METADATA),true)
+
+# Generate fsv_meta
+fsverity-metadata-targets := $(sort $(filter \
+ $(TARGET_OUT)/framework/%.jar \
+ $(foreach arch,$(TARGET_ARCH) $(TARGET_2ND_ARCH),$(foreach ext,oat vdex art, \
+ $(TARGET_OUT)/framework/oat/$(arch)/%.$(ext))) \
+ $(TARGET_OUT)/etc/boot-image.prof \
+ $(TARGET_OUT)/etc/dirty-image-objects \
+ $(TARGET_OUT)/etc/updatable-bcp-packages.txt, \
+ $(ALL_GENERATED_SOURCES) $(ALL_DEFAULT_INSTALLED_MODULES)))
+
+define fsverity-generate-metadata
+$(1).fsv_meta: PRIVATE_SRC := $(1)
+$(1).fsv_meta: PRIVATE_FSVERITY := $(HOST_OUT_EXECUTABLES)/fsverity
+$(1).fsv_meta: $(HOST_OUT_EXECUTABLES)/fsverity_metadata_generator $(HOST_OUT_EXECUTABLES)/fsverity $(1)
+ $$< --fsverity-path $$(PRIVATE_FSVERITY) --signature none \
+ --hash-alg sha256 --output $$@ $$(PRIVATE_SRC)
+endef
+
+$(foreach f,$(fsverity-metadata-targets),$(eval $(call fsverity-generate-metadata,$(f))))
+ALL_DEFAULT_INSTALLED_MODULES += $(addsuffix .fsv_meta,$(fsverity-metadata-targets))
+
+# Generate BuildManifest.apk
+FSVERITY_APK_KEY_PATH := $(DEFAULT_SYSTEM_DEV_CERTIFICATE)
+FSVERITY_APK_OUT := $(TARGET_OUT)/etc/security/fsverity/BuildManifest.apk
+FSVERITY_APK_MANIFEST_PATH := system/security/fsverity/AndroidManifest.xml
+$(FSVERITY_APK_OUT): PRIVATE_FSVERITY := $(HOST_OUT_EXECUTABLES)/fsverity
+$(FSVERITY_APK_OUT): PRIVATE_AAPT2 := $(HOST_OUT_EXECUTABLES)/aapt2
+$(FSVERITY_APK_OUT): PRIVATE_MIN_SDK_VERSION := $(DEFAULT_APP_TARGET_SDK)
+$(FSVERITY_APK_OUT): PRIVATE_APKSIGNER := $(HOST_OUT_EXECUTABLES)/apksigner
+$(FSVERITY_APK_OUT): PRIVATE_MANIFEST := $(FSVERITY_APK_MANIFEST_PATH)
+$(FSVERITY_APK_OUT): PRIVATE_FRAMEWORK_RES := $(call intermediates-dir-for,APPS,framework-res,,COMMON)/package-export.apk
+$(FSVERITY_APK_OUT): PRIVATE_KEY := $(FSVERITY_APK_KEY_PATH)
+$(FSVERITY_APK_OUT): PRIVATE_INPUTS := $(fsverity-metadata-targets)
+$(FSVERITY_APK_OUT): $(HOST_OUT_EXECUTABLES)/fsverity_manifest_generator \
+ $(HOST_OUT_EXECUTABLES)/fsverity $(HOST_OUT_EXECUTABLES)/aapt2 \
+ $(HOST_OUT_EXECUTABLES)/apksigner $(FSVERITY_APK_MANIFEST_PATH) \
+ $(FSVERITY_APK_KEY_PATH).x509.pem $(FSVERITY_APK_KEY_PATH).pk8 \
+ $(call intermediates-dir-for,APPS,framework-res,,COMMON)/package-export.apk \
+ $(fsverity-metadata-targets)
+ $< --fsverity-path $(PRIVATE_FSVERITY) --aapt2-path $(PRIVATE_AAPT2) \
+ --min-sdk-version $(PRIVATE_MIN_SDK_VERSION) \
+ --apksigner-path $(PRIVATE_APKSIGNER) --apk-key-path $(PRIVATE_KEY) \
+ --apk-manifest-path $(PRIVATE_MANIFEST) --framework-res $(PRIVATE_FRAMEWORK_RES) \
+ --output $@ \
+ --base-dir $(PRODUCT_OUT) $(PRIVATE_INPUTS)
+
+ALL_DEFAULT_INSTALLED_MODULES += $(FSVERITY_APK_OUT)
+
+endif # PRODUCT_SYSTEM_FSVERITY_GENERATE_METADATA
+
INTERNAL_SYSTEMIMAGE_FILES := $(sort $(filter $(TARGET_OUT)/%, \
$(ALL_GENERATED_SOURCES) \
$(ALL_DEFAULT_INSTALLED_MODULES)))
@@ -2728,6 +2824,19 @@
INTERNAL_SYSTEMIMAGE_FILES += $(call create-partition-compat-symlink,$(TARGET_OUT)/system_ext,/system_ext,system_ext.img)
endif
+# -----------------------------------------------------------------
+# system_dlkm partition image
+
+# Create symlinks for system_dlkm on devices with a system_dlkm partition:
+# /system/lib/modules -> /system_dlkm/lib/modules
+#
+# On devices with a system_dlkm partition,
+# - /system/lib/modules is a symlink to a directory that stores system DLKMs.
+# - The system_dlkm partition is mounted at /system_dlkm at runtime.
+ifdef BOARD_USES_SYSTEM_DLKM_PARTITION
+ INTERNAL_SYSTEMIMAGE_FILES += $(call create-partition-compat-symlink,$(TARGET_OUT)/lib/modules,/system_dlkm/lib/modules,system_dlkm.img)
+endif
+
FULL_SYSTEMIMAGE_DEPS := $(INTERNAL_SYSTEMIMAGE_FILES) $(INTERNAL_USERIMAGES_DEPS)
# ASAN libraries in the system image - add dependency.
@@ -2795,10 +2904,6 @@
ifeq ($(BOARD_AVB_ENABLE),true)
$(BUILT_SYSTEMIMAGE): $(BOARD_AVB_SYSTEM_KEY_PATH)
endif
-ifeq ($(PRODUCT_SYSTEM_FSVERITY_GENERATE_METADATA),true)
-$(BUILT_SYSTEMIMAGE): $(HOST_OUT_EXECUTABLES)/fsverity $(HOST_OUT_EXECUTABLES)/aapt2 $(HOST_OUT_EXECUTABLES)/apksigner \
- $(FSVERITY_APK_MANIFEST_PATH) $(FSVERITY_APK_KEY_PATH).x509.pem $(FSVERITY_APK_KEY_PATH).pk8
-endif
$(BUILT_SYSTEMIMAGE): $(FULL_SYSTEMIMAGE_DEPS) $(INSTALLED_FILES_FILE)
$(call build-systemimage-target,$@)
@@ -3475,7 +3580,10 @@
# $(INSTALLED_VENDORIMAGE_TARGET)" for "system vendor".
# (1): list of partitions like "system", "vendor" or "system product system_ext".
define images-for-partitions
-$(strip $(foreach item,$(1),$(if $(filter $(item),system_other),$(INSTALLED_SYSTEMOTHERIMAGE_TARGET),$(INSTALLED_$(call to-upper,$(item))IMAGE_TARGET))))
+$(strip $(foreach item,$(1),\
+ $(if $(filter $(item),system_other),$(INSTALLED_SYSTEMOTHERIMAGE_TARGET),\
+ $(if $(filter $(item),init_boot),$(INSTALLED_INIT_BOOT_IMAGE_TARGET),\
+ $(INSTALLED_$(call to-upper,$(item))IMAGE_TARGET)))))
endef
# -----------------------------------------------------------------
@@ -3592,6 +3700,10 @@
--prop com.android.build.boot.fingerprint:$(BUILD_FINGERPRINT_FROM_FILE) \
--prop com.android.build.boot.os_version:$(PLATFORM_VERSION_LAST_STABLE)
+BOARD_AVB_INIT_BOOT_ADD_HASH_FOOTER_ARGS += \
+ --prop com.android.build.init_boot.fingerprint:$(BUILD_FINGERPRINT_FROM_FILE) \
+ --prop com.android.build.init_boot.os_version:$(PLATFORM_VERSION_LAST_STABLE)
+
BOARD_AVB_VENDOR_BOOT_ADD_HASH_FOOTER_ARGS += \
--prop com.android.build.vendor_boot.fingerprint:$(BUILD_FINGERPRINT_FROM_FILE) \
@@ -3621,11 +3733,21 @@
--prop com.android.build.pvmfw.fingerprint:$(BUILD_FINGERPRINT_FROM_FILE)
# The following vendor- and odm-specific images needs explicit SPL set per board.
+# TODO(b/210875415) Is this security_patch property used? Should it be removed from
+# boot.img when there is no platform ramdisk included in it?
ifdef BOOT_SECURITY_PATCH
BOARD_AVB_BOOT_ADD_HASH_FOOTER_ARGS += \
--prop com.android.build.boot.security_patch:$(BOOT_SECURITY_PATCH)
endif
+ifdef INIT_BOOT_SECURITY_PATCH
+BOARD_AVB_INIT_BOOT_ADD_HASH_FOOTER_ARGS += \
+ --prop com.android.build.init_boot.security_patch:$(INIT_BOOT_SECURITY_PATCH)
+else ifdef BOOT_SECURITY_PATCH
+BOARD_AVB_INIT_BOOT_ADD_HASH_FOOTER_ARGS += \
+ --prop com.android.build.init_boot.security_patch:$(BOOT_SECURITY_PATCH)
+endif
+
ifdef VENDOR_SECURITY_PATCH
BOARD_AVB_VENDOR_ADD_HASHTREE_FOOTER_ARGS += \
--prop com.android.build.vendor.security_patch:$(VENDOR_SECURITY_PATCH)
@@ -3652,6 +3774,7 @@
endif
BOOT_FOOTER_ARGS := BOARD_AVB_BOOT_ADD_HASH_FOOTER_ARGS
+INIT_BOOT_FOOTER_ARGS := BOARD_AVB_INIT_BOOT_ADD_HASH_FOOTER_ARGS
VENDOR_BOOT_FOOTER_ARGS := BOARD_AVB_VENDOR_BOOT_ADD_HASH_FOOTER_ARGS
DTBO_FOOTER_ARGS := BOARD_AVB_DTBO_ADD_HASH_FOOTER_ARGS
PVMFW_FOOTER_ARGS := BOARD_AVB_PVMFW_ADD_HASH_FOOTER_ARGS
@@ -3735,11 +3858,17 @@
$(eval $(call check-and-set-avb-args,boot))
endif
+ifdef INSTALLED_INIT_BOOT_IMAGE_TARGET
+$(eval $(call check-and-set-avb-args,init_boot))
+endif
+
ifdef INSTALLED_VENDOR_BOOTIMAGE_TARGET
$(eval $(call check-and-set-avb-args,vendor_boot))
endif
+ifdef INSTALLED_SYSTEMIMAGE_TARGET
$(eval $(call check-and-set-avb-args,system))
+endif
ifdef INSTALLED_VENDORIMAGE_TARGET
$(eval $(call check-and-set-avb-args,vendor))
@@ -3831,6 +3960,9 @@
$(if $(BOARD_AVB_BOOT_KEY_PATH),\
$(hide) $(AVBTOOL) extract_public_key --key $(BOARD_AVB_BOOT_KEY_PATH) \
--output $(1)/boot.avbpubkey)
+ $(if $(BOARD_AVB_INIT_BOOT_KEY_PATH),\
+ $(hide) $(AVBTOOL) extract_public_key --key $(BOARD_AVB_INIT_BOOT_KEY_PATH) \
+ --output $(1)/init_boot.avbpubkey)
$(if $(BOARD_AVB_VENDOR_BOOT_KEY_PATH),\
$(AVBTOOL) extract_public_key --key $(BOARD_AVB_VENDOR_BOOT_KEY_PATH) \
--output $(1)/vendor_boot.avbpubkey)
@@ -3934,6 +4066,7 @@
$(INSTALLED_VBMETAIMAGE_TARGET): \
$(AVBTOOL) \
$(INSTALLED_BOOTIMAGE_TARGET) \
+ $(INSTALLED_INIT_BOOT_IMAGE_TARGET) \
$(INSTALLED_VENDOR_BOOTIMAGE_TARGET) \
$(INSTALLED_SYSTEMIMAGE_TARGET) \
$(INSTALLED_VENDORIMAGE_TARGET) \
@@ -4505,6 +4638,10 @@
else
echo "boot_images=$(foreach b,$(INSTALLED_BOOTIMAGE_TARGET),$(notdir $(b)))" >> $@
endif
+ifneq ($(INSTALLED_INIT_BOOT_IMAGE_TARGET),)
+ $(hide) echo "init_boot=true" >> $@
+ $(hide) echo "init_boot_size=$(BOARD_INIT_BOOT_IMAGE_PARTITION_SIZE)" >> $@
+endif
ifeq ($(BOARD_RAMDISK_USE_LZ4),true)
echo "lz4_ramdisks=true" >> $@
endif
@@ -4532,17 +4669,19 @@
endif
$(hide) echo "tool_extensions=$(tool_extensions)" >> $@
$(hide) echo "default_system_dev_certificate=$(DEFAULT_SYSTEM_DEV_CERTIFICATE)" >> $@
+ifdef PRODUCT_EXTRA_OTA_KEYS
+ $(hide) echo "extra_ota_keys=$(PRODUCT_EXTRA_OTA_KEYS)" >> $@
+endif
ifdef PRODUCT_EXTRA_RECOVERY_KEYS
$(hide) echo "extra_recovery_keys=$(PRODUCT_EXTRA_RECOVERY_KEYS)" >> $@
endif
$(hide) echo 'mkbootimg_args=$(BOARD_MKBOOTIMG_ARGS)' >> $@
$(hide) echo 'recovery_mkbootimg_args=$(BOARD_RECOVERY_MKBOOTIMG_ARGS)' >> $@
$(hide) echo 'mkbootimg_version_args=$(INTERNAL_MKBOOTIMG_VERSION_ARGS)' >> $@
+ $(hide) echo 'mkbootimg_init_args=$(BOARD_MKBOOTIMG_INIT_ARGS)' >> $@
ifdef BOARD_GKI_SIGNING_KEY_PATH
$(hide) echo 'gki_signing_key_path=$(BOARD_GKI_SIGNING_KEY_PATH)' >> $@
$(hide) echo 'gki_signing_algorithm=$(BOARD_GKI_SIGNING_ALGORITHM)' >> $@
-endif
-ifdef BOARD_GKI_SIGNING_SIGNATURE_ARGS
$(hide) echo 'gki_signing_signature_args=$(BOARD_GKI_SIGNING_SIGNATURE_ARGS)' >> $@
endif
$(hide) echo "multistage_support=1" >> $@
@@ -4578,6 +4717,12 @@
$(hide) echo "avb_boot_algorithm=$(BOARD_AVB_BOOT_ALGORITHM)" >> $@
$(hide) echo "avb_boot_rollback_index_location=$(BOARD_AVB_BOOT_ROLLBACK_INDEX_LOCATION)" >> $@
endif # BOARD_AVB_BOOT_KEY_PATH
+ $(hide) echo "avb_init_boot_add_hash_footer_args=$(BOARD_AVB_INIT_BOOT_ADD_HASH_FOOTER_ARGS)" >> $@
+ifdef BOARD_AVB_INIT_BOOT_KEY_PATH
+ $(hide) echo "avb_init_boot_key_path=$(BOARD_AVB_INIT_BOOT_KEY_PATH)" >> $@
+ $(hide) echo "avb_init_boot_algorithm=$(BOARD_AVB_INIT_BOOT_ALGORITHM)" >> $@
+ $(hide) echo "avb_init_boot_rollback_index_location=$(BOARD_AVB_INIT_BOOT_ROLLBACK_INDEX_LOCATION)" >> $@
+endif # BOARD_AVB_INIT_BOOT_KEY_PATH
echo "avb_vendor_boot_add_hash_footer_args=$(BOARD_AVB_VENDOR_BOOT_ADD_HASH_FOOTER_ARGS)" >> $@
ifdef BOARD_AVB_VENDOR_BOOT_KEY_PATH
echo "avb_vendor_boot_key_path=$(BOARD_AVB_VENDOR_BOOT_KEY_PATH)" >> $@
@@ -4734,14 +4879,16 @@
tool_extension := $(wildcard $(tool_extensions)/releasetools.py)
$(BUILT_TARGET_FILES_PACKAGE): PRIVATE_TOOL_EXTENSION := $(tool_extension)
+updaer_dep :=
ifeq ($(AB_OTA_UPDATER),true)
-updater_dep := system/update_engine/update_engine.conf
-updater_dep := external/zucchini/version_info.h
+updater_dep += system/update_engine/update_engine.conf
+updater_dep += external/zucchini/version_info.h
+updater_dep += $(HOST_OUT_SHARED_LIBRARIES)/liblz4.so
endif
# Build OTA tools if non-A/B is allowed
ifeq ($(TARGET_OTA_ALLOW_NON_AB),true)
-updater_dep := $(built_ota_tools)
+updater_dep += $(built_ota_tools)
endif
$(BUILT_TARGET_FILES_PACKAGE): $(updater_dep)
@@ -4860,6 +5007,10 @@
# image.
ifdef BUILDING_SYSTEM_IMAGE
$(BUILT_TARGET_FILES_PACKAGE): $(FULL_SYSTEMIMAGE_DEPS)
+else
+ # releasetools may need the system build.prop even when building a
+ # system-image-less product.
+ $(BUILT_TARGET_FILES_PACKAGE): $(INSTALLED_BUILD_PROP_TARGET)
endif
ifdef BUILDING_USERDATA_IMAGE
@@ -4915,9 +5066,10 @@
$(BUILT_TARGET_FILES_PACKAGE): $(INSTALLED_SYSTEM_EXTIMAGE_TARGET)
endif
-ifdef BUILDING_BOOT_IMAGE
+ifneq (,$(BUILDING_BOOT_IMAGE)$(BUILDING_INIT_BOOT_IMAGE))
$(BUILT_TARGET_FILES_PACKAGE): $(INTERNAL_RAMDISK_FILES)
-endif
+endif # BUILDING_BOOT_IMAGE != "" || BUILDING_INIT_BOOT_IMAGE != ""
+
ifneq (,$(INTERNAL_PREBUILT_BOOTIMAGE) $(filter true,$(BOARD_COPY_BOOT_IMAGE_TO_TARGET_FILES)))
$(BUILT_TARGET_FILES_PACKAGE): $(INSTALLED_BOOTIMAGE_TARGET)
endif
@@ -5105,6 +5257,12 @@
@# Contents of the system image
$(hide) $(call package_files-copy-root, \
$(SYSTEMIMAGE_SOURCE_DIR),$(zip_root)/SYSTEM)
+else ifdef INSTALLED_BUILD_PROP_TARGET
+ @# Copy the system build.prop even if not building a system image
+ @# because add_img_to_target_files may need it to build other partition
+ @# images.
+ $(hide) mkdir -p "$(zip_root)/SYSTEM"
+ $(hide) cp "$(INSTALLED_BUILD_PROP_TARGET)" "$(patsubst $(TARGET_OUT)/%,$(zip_root)/SYSTEM/%,$(INSTALLED_BUILD_PROP_TARGET))"
endif
ifdef BUILDING_USERDATA_IMAGE
@# Contents of the data image
@@ -5211,6 +5369,7 @@
@# When using the A/B updater, include the updater config files in the zip.
$(hide) cp $(TOPDIR)system/update_engine/update_engine.conf $(zip_root)/META/update_engine_config.txt
$(hide) cp $(TOPDIR)external/zucchini/version_info.h $(zip_root)/META/zucchini_config.txt
+ $(hide) cp $(HOST_OUT_SHARED_LIBRARIES)/liblz4.so $(zip_root)/META/liblz4.so
$(hide) for part in $(strip $(AB_OTA_PARTITIONS)); do \
echo "$${part}" >> $(zip_root)/META/ab_partitions.txt; \
done
@@ -5239,8 +5398,12 @@
$(hide) mkdir -p $(zip_root)/IMAGES
$(hide) cp $(INSTALLED_SYSTEM_EXTIMAGE_TARGET) $(zip_root)/IMAGES/
endif
+ifdef BOARD_PREBUILT_INIT_BOOT_IMAGE
+ $(hide) mkdir -p $(zip_root)/PREBUILT_IMAGES
+ $(hide) cp $(INSTALLED_INIT_BOOT_IMAGE_TARGET) $(zip_root)/PREBUILT_IMAGES/
+endif
ifndef BOARD_PREBUILT_BOOTIMAGE
-ifneq (,$(INTERNAL_PREBUILT_BOOTIMAGE) $(filter true,$(BOARD_COPY_BOOT_IMAGE_TO_TARGET_FILES)))
+ifneq (,$(strip $(INTERNAL_PREBUILT_BOOTIMAGE) $(filter true,$(BOARD_COPY_BOOT_IMAGE_TO_TARGET_FILES))))
ifdef INSTALLED_BOOTIMAGE_TARGET
$(hide) mkdir -p $(zip_root)/IMAGES
$(hide) cp $(INSTALLED_BOOTIMAGE_TARGET) $(zip_root)/IMAGES/
@@ -5316,6 +5479,13 @@
@# BOOT/RAMDISK exists and contains the ramdisk for recovery if using BOARD_USES_RECOVERY_AS_BOOT.
$(hide) $(call fs_config,$(zip_root)/BOOT/RAMDISK,) > $(zip_root)/META/boot_filesystem_config.txt
endif
+ifdef BUILDING_INIT_BOOT_IMAGE
+ $(hide) $(call package_files-copy-root, $(TARGET_RAMDISK_OUT),$(zip_root)/INIT_BOOT/RAMDISK)
+ $(hide) $(call fs_config,$(zip_root)/INIT_BOOT/RAMDISK,) > $(zip_root)/META/init_boot_filesystem_config.txt
+ifdef BOARD_KERNEL_PAGESIZE
+ $(hide) echo "$(BOARD_KERNEL_PAGESIZE)" > $(zip_root)/INIT_BOOT/pagesize
+endif # BOARD_KERNEL_PAGESIZE
+endif # BUILDING_INIT_BOOT_IMAGE
ifneq ($(INSTALLED_VENDOR_BOOTIMAGE_TARGET),)
$(call fs_config,$(zip_root)/VENDOR_BOOT/RAMDISK,) > $(zip_root)/META/vendor_boot_filesystem_config.txt
endif
@@ -5629,6 +5799,7 @@
$(INSTALLED_SYSTEMIMAGE_TARGET) \
$(INSTALLED_RAMDISK_TARGET) \
$(INSTALLED_BOOTIMAGE_TARGET) \
+ $(INSTALLED_INIT_BOOT_IMAGE_TARGET) \
$(INSTALLED_USERDATAIMAGE_TARGET) \
$(INSTALLED_VENDORIMAGE_TARGET) \
$(INSTALLED_PRODUCTIMAGE_TARGET) \
diff --git a/core/android_soong_config_vars.mk b/core/android_soong_config_vars.mk
index d24449b..0befbfa 100644
--- a/core/android_soong_config_vars.mk
+++ b/core/android_soong_config_vars.mk
@@ -27,6 +27,10 @@
# Add variables to the namespace below:
$(call add_soong_config_var,ANDROID,TARGET_ENABLE_MEDIADRM_64)
+$(call add_soong_config_var,ANDROID,IS_TARGET_MIXED_SEPOLICY)
+ifeq ($(IS_TARGET_MIXED_SEPOLICY),true)
+$(call add_soong_config_var_value,ANDROID,MIXED_SEPOLICY_VERSION,$(BOARD_SEPOLICY_VERS))
+endif
$(call add_soong_config_var,ANDROID,BOARD_USES_ODMIMAGE)
$(call add_soong_config_var,ANDROID,BOARD_USES_RECOVERY_AS_BOOT)
$(call add_soong_config_var,ANDROID,BOARD_BUILD_SYSTEM_ROOT_IMAGE)
@@ -100,6 +104,9 @@
$(call add_soong_config_var_value,ANDROID,module_build_from_source,true)
endif
+# TODO(b/203088572): Remove when Java optimizations enabled by default for
+# SystemUI.
+$(call add_soong_config_var,ANDROID,SYSTEMUI_OPTIMIZE_JAVA)
# TODO(b/196084106): Remove when Java optimizations enabled by default for
# system packages.
$(call add_soong_config_var,ANDROID,SYSTEM_OPTIMIZE_JAVA)
diff --git a/core/base_rules.mk b/core/base_rules.mk
index 134cb8f..cec7792 100644
--- a/core/base_rules.mk
+++ b/core/base_rules.mk
@@ -981,6 +981,18 @@
ALL_MODULES.$(my_register_name).SYSTEM_SHARED_LIBS := \
$(ALL_MODULES.$(my_register_name).SYSTEM_SHARED_LIBS) $(LOCAL_SYSTEM_SHARED_LIBRARIES)
+ifdef LOCAL_TEST_DATA
+ # Export the list of targets that are handled as data inputs and required
+ # by tests at runtime. The LOCAL_TEST_DATA format is generated from below
+ # https://cs.android.com/android/platform/superproject/+/master:build/soong/android/androidmk.go;l=925-944;drc=master
+ # which format is like $(path):$(relative_file) but for module-info, only
+ # the string after ":" is needed.
+ ALL_MODULES.$(my_register_name).TEST_DATA := \
+ $(strip $(ALL_MODULES.$(my_register_name).TEST_DATA) \
+ $(foreach f, $(LOCAL_TEST_DATA),\
+ $(call word-colon,2,$(f))))
+endif
+
##########################################################################
## When compiling against the VNDK, add the .vendor or .product suffix to
## required modules.
@@ -1055,7 +1067,9 @@
endif
ALL_MODULES.$(my_register_name).FOR_HOST_CROSS := $(my_host_cross)
ALL_MODULES.$(my_register_name).MODULE_NAME := $(LOCAL_MODULE)
-ALL_MODULES.$(my_register_name).COMPATIBILITY_SUITES := $(LOCAL_COMPATIBILITY_SUITE)
+ALL_MODULES.$(my_register_name).COMPATIBILITY_SUITES := \
+ $(ALL_MODULES.$(my_register_name).COMPATIBILITY_SUITES) \
+ $(filter-out $(ALL_MODULES.$(my_register_name).COMPATIBILITY_SUITES),$(LOCAL_COMPATIBILITY_SUITE))
ALL_MODULES.$(my_register_name).TEST_CONFIG := $(test_config)
ALL_MODULES.$(my_register_name).EXTRA_TEST_CONFIGS := $(LOCAL_EXTRA_FULL_TEST_CONFIGS)
ALL_MODULES.$(my_register_name).TEST_MAINLINE_MODULES := $(LOCAL_TEST_MAINLINE_MODULES)
diff --git a/core/board_config.mk b/core/board_config.mk
index 6bbb3a0..95cbe3d 100644
--- a/core/board_config.mk
+++ b/core/board_config.mk
@@ -65,6 +65,7 @@
# File system variables
_board_strip_readonly_list += BOARD_FLASH_BLOCK_SIZE
_board_strip_readonly_list += BOARD_BOOTIMAGE_PARTITION_SIZE
+_board_strip_readonly_list += BOARD_INIT_BOOT_IMAGE_PARTITION_SIZE
_board_strip_readonly_list += BOARD_RECOVERYIMAGE_PARTITION_SIZE
_board_strip_readonly_list += BOARD_SYSTEMIMAGE_PARTITION_SIZE
_board_strip_readonly_list += BOARD_SYSTEMIMAGE_FILE_SYSTEM_TYPE
@@ -122,6 +123,9 @@
_board_strip_readonly_list += BOARD_MOVE_GSI_AVB_KEYS_TO_VENDOR_BOOT
_board_strip_readonly_list += BOARD_COPY_BOOT_IMAGE_TO_TARGET_FILES
+# Prebuilt image variables
+_board_strip_readonly_list += BOARD_PREBUILT_INIT_BOOT_IMAGE
+
# Defines the list of logical vendor ramdisk names to build or include in vendor_boot.
_board_strip_readonly_list += BOARD_VENDOR_RAMDISK_FRAGMENTS
@@ -461,6 +465,25 @@
endif
.KATI_READONLY := BUILDING_BOOT_IMAGE
+# Are we building an init boot image
+BUILDING_INIT_BOOT_IMAGE :=
+ifeq ($(PRODUCT_BUILD_INIT_BOOT_IMAGE),)
+ ifeq ($(BOARD_USES_RECOVERY_AS_BOOT),true)
+ BUILDING_INIT_BOOT_IMAGE :=
+ else ifdef BOARD_PREBUILT_INIT_BOOT_IMAGE
+ BUILDING_INIT_BOOT_IMAGE :=
+ else ifdef BOARD_INIT_BOOT_IMAGE_PARTITION_SIZE
+ BUILDING_INIT_BOOT_IMAGE := true
+ endif
+else ifeq ($(PRODUCT_BUILD_INIT_BOOT_IMAGE),true)
+ ifeq ($(BOARD_USES_RECOVERY_AS_BOOT),true)
+ $(error PRODUCT_BUILD_INIT_BOOT_IMAGE is true, but so is BOARD_USES_RECOVERY_AS_BOOT. Use only one option.)
+ else
+ BUILDING_INIT_BOOT_IMAGE := true
+ endif
+endif
+.KATI_READONLY := BUILDING_INIT_BOOT_IMAGE
+
# Are we building a recovery image
BUILDING_RECOVERY_IMAGE :=
ifeq ($(PRODUCT_BUILD_RECOVERY_IMAGE),)
@@ -569,6 +592,11 @@
$(warning PRODUCT_BUILD_DEBUG_BOOT_IMAGE is true, but we're not building a boot image. \
Skip building the debug boot image.)
endif
+else ifdef BUILDING_INIT_BOOT_IMAGE
+ ifeq ($(PRODUCT_BUILD_DEBUG_BOOT_IMAGE),true)
+ $(warning PRODUCT_BUILD_DEBUG_BOOT_IMAGE is true, but we don't have a ramdisk in the boot image. \
+ Skip building the debug boot image.)
+ endif
else
ifeq ($(PRODUCT_BUILD_DEBUG_BOOT_IMAGE),)
BUILDING_DEBUG_BOOT_IMAGE := true
diff --git a/core/config.mk b/core/config.mk
index bfff84e..3c7c5ce 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -331,6 +331,22 @@
JAVA_TMPDIR_ARG :=
endif
+# http://b/210012154 Set BIONIC_COVERAGE if coverage is enabled for bionic. This
+# disable continuous coverage and removes '%c' from init.environ.rc:LLVM_PROFILE_FILE
+ifeq ($(NATIVE_COVERAGE_PATHS),*)
+ ifeq ($(filter bionic%,$(NATIVE_COVERAGE_EXCLUDE_PATHS)),)
+ BIONIC_COVERAGE := true
+ else
+ BIONIC_COVERAGE := false
+ endif
+else
+ ifeq ($(filter bionic%,$(NATIVE_COVERAGE_PATHS)),)
+ BIONIC_COVERAGE := false
+ else
+ BIONIC_COVERAGE := true
+ endif
+endif
+
# ###############################################################
# Include sub-configuration files
# ###############################################################
@@ -840,6 +856,14 @@
BOARD_SEPOLICY_VERS := $(PLATFORM_SEPOLICY_VERSION)
endif
+ifeq ($(BOARD_SEPOLICY_VERS),$(PLATFORM_SEPOLICY_VERSION))
+IS_TARGET_MIXED_SEPOLICY :=
+else
+IS_TARGET_MIXED_SEPOLICY := true
+endif
+
+.KATI_READONLY := IS_TARGET_MIXED_SEPOLICY
+
# A list of SEPolicy versions, besides PLATFORM_SEPOLICY_VERSION, that the framework supports.
PLATFORM_SEPOLICY_COMPAT_VERSIONS := \
28.0 \
diff --git a/core/force_aapt2.mk b/core/force_aapt2.mk
index 25b45e4..5f3182a 100644
--- a/core/force_aapt2.mk
+++ b/core/force_aapt2.mk
@@ -44,10 +44,3 @@
LOCAL_SDK_RES_VERSION := current
endif
-ifeq (,$(strip $(LOCAL_MANIFEST_FILE)$(LOCAL_FULL_MANIFEST_FILE)))
- ifeq (,$(wildcard $(LOCAL_PATH)/AndroidManifest.xml))
- # work around missing manifests by creating a default one
- LOCAL_FULL_MANIFEST_FILE := $(call local-intermediates-dir,COMMON)/DefaultManifest.xml
- $(call create-default-manifest-file,$(LOCAL_FULL_MANIFEST_FILE),$(call module-min-sdk-version))
- endif
-endif
diff --git a/core/main.mk b/core/main.mk
index f7cf8de..d17f0cb 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -1603,6 +1603,9 @@
.PHONY: bootimage
bootimage: $(INSTALLED_BOOTIMAGE_TARGET)
+.PHONY: initbootimage
+bootimage: $(INSTALLED_INIT_BOOT_IMAGE_TARGET)
+
ifeq (true,$(PRODUCT_EXPORT_BOOT_IMAGE_TO_DIST))
$(call dist-for-goals, bootimage, $(INSTALLED_BOOTIMAGE_TARGET))
endif
@@ -1629,6 +1632,7 @@
$(INSTALLED_SYSTEMIMAGE_TARGET) \
$(INSTALLED_RAMDISK_TARGET) \
$(INSTALLED_BOOTIMAGE_TARGET) \
+ $(INSTALLED_INIT_BOOT_IMAGE_TARGET) \
$(INSTALLED_RADIOIMAGE_TARGET) \
$(INSTALLED_DEBUG_RAMDISK_TARGET) \
$(INSTALLED_DEBUG_BOOTIMAGE_TARGET) \
diff --git a/core/package_internal.mk b/core/package_internal.mk
index 800dbbc..8199ad2 100644
--- a/core/package_internal.mk
+++ b/core/package_internal.mk
@@ -97,6 +97,14 @@
endif
include $(BUILD_SYSTEM)/force_aapt2.mk
+# validate that app contains a manifest file for aapt2
+ifeq (,$(strip $(LOCAL_MANIFEST_FILE)$(LOCAL_FULL_MANIFEST_FILE)))
+ ifeq (,$(wildcard $(LOCAL_PATH)/AndroidManifest.xml))
+ $(call pretty-error,App missing manifest file which is required by aapt2. \
+Provide a manifest file by either setting LOCAL_MANIFEST_FILE in Android.mk \
+or via a AndroidManifest.xml in this directory)
+ endif
+endif
# Process Support Library dependencies.
include $(BUILD_SYSTEM)/support_libraries.mk
diff --git a/core/product-graph.mk b/core/product-graph.mk
index f28ea3d..d425b22 100644
--- a/core/product-graph.mk
+++ b/core/product-graph.mk
@@ -126,6 +126,7 @@
$(hide) echo 'PRODUCT_CHARACTERISTICS=$(call get-product-var,$(1),PRODUCT_CHARACTERISTICS)' >> $$@
$(hide) echo 'PRODUCT_COPY_FILES=$(call get-product-var,$(1),PRODUCT_COPY_FILES)' >> $$@
$(hide) echo 'PRODUCT_OTA_PUBLIC_KEYS=$(call get-product-var,$(1),PRODUCT_OTA_PUBLIC_KEYS)' >> $$@
+ $(hide) echo 'PRODUCT_EXTRA_OTA_KEYS=$(call get-product-var,$(1),PRODUCT_EXTRA_OTA_KEYS)' >> $$@
$(hide) echo 'PRODUCT_EXTRA_RECOVERY_KEYS=$(call get-product-var,$(1),PRODUCT_EXTRA_RECOVERY_KEYS)' >> $$@
$(hide) echo 'PRODUCT_PACKAGE_OVERLAYS=$(call get-product-var,$(1),PRODUCT_PACKAGE_OVERLAYS)' >> $$@
$(hide) echo 'DEVICE_PACKAGE_OVERLAYS=$(call get-product-var,$(1),DEVICE_PACKAGE_OVERLAYS)' >> $$@
diff --git a/core/product.mk b/core/product.mk
index 31b1beb..7192226 100644
--- a/core/product.mk
+++ b/core/product.mk
@@ -183,6 +183,7 @@
# signing tools can substitute them for the test key embedded by
# default.
_product_list_vars += PRODUCT_OTA_PUBLIC_KEYS
+_product_list_vars += PRODUCT_EXTRA_OTA_KEYS
_product_list_vars += PRODUCT_EXTRA_RECOVERY_KEYS
# Should we use the default resources or add any product specific overlays
@@ -395,6 +396,7 @@
_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_single_value_vars += PRODUCT_BUILD_INIT_BOOT_IMAGE
_product_single_value_vars += PRODUCT_BUILD_DEBUG_BOOT_IMAGE
_product_single_value_vars += PRODUCT_BUILD_VENDOR_BOOT_IMAGE
_product_single_value_vars += PRODUCT_BUILD_DEBUG_VENDOR_BOOT_IMAGE
@@ -443,7 +445,7 @@
# Install a copy of the debug policy to the system_ext partition, and allow
# init-second-stage to load debug policy from system_ext.
-# This option is only meant to be set by GSI products.
+# This option is only meant to be set by compliance GSI targets.
_product_single_value_vars += PRODUCT_INSTALL_DEBUG_POLICY_TO_SYSTEM_EXT
# If set, metadata files for the following artifacts will be generated.
diff --git a/core/product_config.mk b/core/product_config.mk
index 0e969fe..6fae73e 100644
--- a/core/product_config.mk
+++ b/core/product_config.mk
@@ -381,6 +381,7 @@
ENFORCE_SYSTEM_CERTIFICATE_ALLOW_LIST := $(PRODUCT_ARTIFACT_SYSTEM_CERTIFICATE_REQUIREMENT_ALLOW_LIST)
PRODUCT_OTA_PUBLIC_KEYS := $(sort $(PRODUCT_OTA_PUBLIC_KEYS))
+PRODUCT_EXTRA_OTA_KEYS := $(sort $(PRODUCT_EXTRA_OTA_KEYS))
PRODUCT_EXTRA_RECOVERY_KEYS := $(sort $(PRODUCT_EXTRA_RECOVERY_KEYS))
# Resolve and setup per-module dex-preopt configs.
@@ -412,16 +413,22 @@
_psmc_modules :=
# Reset ADB keys for non-debuggable builds
-ifeq (,$(filter eng userdebug,$(TARGET_BUILD_VARIANT)),)
+ifeq (,$(filter eng userdebug,$(TARGET_BUILD_VARIANT)))
PRODUCT_ADB_KEYS :=
endif
ifneq ($(filter-out 0 1,$(words $(PRODUCT_ADB_KEYS))),)
$(error Only one file may be in PRODUCT_ADB_KEYS: $(PRODUCT_ADB_KEYS))
endif
+# Show a warning wall of text if non-compliance-GSI products set this option.
ifdef PRODUCT_INSTALL_DEBUG_POLICY_TO_SYSTEM_EXT
- ifeq (,$(filter gsi_arm gsi_arm64 gsi_x86 gsi_x86_64,$(PRODUCT_NAME)))
- $(error Only GSI products are allowed to set PRODUCT_INSTALL_DEBUG_POLICY_TO_SYSTEM_EXT)
+ ifeq (,$(filter gsi_arm gsi_arm64 gsi_x86 gsi_x86_64 gsi_car_arm64 gsi_car_x86_64,$(PRODUCT_NAME)))
+ $(warning PRODUCT_INSTALL_DEBUG_POLICY_TO_SYSTEM_EXT is set but \
+ PRODUCT_NAME ($(PRODUCT_NAME)) doesn't look like a GSI for compliance \
+ testing. This is a special configuration for compliance GSI, so do make \
+ sure you understand the security implications before setting this \
+ option. If you don't know what this option does, then you probably \
+ shouldn't set this.)
endif
endif
diff --git a/core/product_config.rbc b/core/product_config.rbc
index f26b428..1ccffcc 100644
--- a/core/product_config.rbc
+++ b/core/product_config.rbc
@@ -476,6 +476,12 @@
return sorted(["%s/%s:%s/%s" % (
from_dir, f, to_dir, f) for f in rblf_find_files(from_dir, pattern, only_files=1)])
+def _findstring(needle, haystack):
+ """Equivalent to GNU make's $(findstring)."""
+ if haystack.find(needle) < 0:
+ return ""
+ return needle
+
def _filter_out(pattern, text):
"""Return all the words from `text' that do not match any word in `pattern'.
@@ -727,6 +733,7 @@
filter = _filter,
filter_out = _filter_out,
find_and_copy = _find_and_copy,
+ findstring = _findstring,
inherit = _inherit,
indirect = _indirect,
mk2rbc_error = _mk2rbc_error,
@@ -748,4 +755,5 @@
setdefault = _setdefault,
shell = rblf_shell,
warning = _mkwarning,
+ words = __words,
)
diff --git a/core/soong_config.mk b/core/soong_config.mk
index 617abdf..a8071a3 100644
--- a/core/soong_config.mk
+++ b/core/soong_config.mk
@@ -191,6 +191,10 @@
$(call add_json_list, BoardPlatVendorPolicy, $(BOARD_PLAT_VENDOR_POLICY))
$(call add_json_list, BoardReqdMaskPolicy, $(BOARD_REQD_MASK_POLICY))
+$(call add_json_list, BoardSystemExtPublicPrebuiltDirs, $(BOARD_SYSTEM_EXT_PUBLIC_PREBUILT_DIRS))
+$(call add_json_list, BoardSystemExtPrivatePrebuiltDirs, $(BOARD_SYSTEM_EXT_PRIVATE_PREBUILT_DIRS))
+$(call add_json_list, BoardProductPublicPrebuiltDirs, $(BOARD_PRODUCT_PUBLIC_PREBUILT_DIRS))
+$(call add_json_list, BoardProductPrivatePrebuiltDirs, $(BOARD_PRODUCT_PRIVATE_PREBUILT_DIRS))
$(call add_json_list, BoardVendorSepolicyDirs, $(BOARD_VENDOR_SEPOLICY_DIRS) $(BOARD_SEPOLICY_DIRS))
$(call add_json_list, BoardOdmSepolicyDirs, $(BOARD_ODM_SEPOLICY_DIRS))
$(call add_json_list, BoardVendorDlkmSepolicyDirs, $(BOARD_VENDOR_DLKM_SEPOLICY_DIRS))
@@ -203,6 +207,7 @@
$(call add_json_str, PlatformSepolicyVersion, $(PLATFORM_SEPOLICY_VERSION))
$(call add_json_str, TotSepolicyVersion, $(TOT_SEPOLICY_VERSION))
+$(call add_json_list, PlatformSepolicyCompatVersions, $(PLATFORM_SEPOLICY_COMPAT_VERSIONS))
$(call add_json_bool, Flatten_apex, $(filter true,$(TARGET_FLATTEN_APEX)))
$(call add_json_bool, ForceApexSymlinkOptimization, $(filter true,$(TARGET_FORCE_APEX_SYMLINK_OPTIMIZATION)))
diff --git a/core/static_java_library.mk b/core/static_java_library.mk
index 7a87322..4053985 100644
--- a/core/static_java_library.mk
+++ b/core/static_java_library.mk
@@ -101,6 +101,13 @@
include $(BUILD_SYSTEM)/java_renderscript.mk
ifeq (true,$(need_compile_res))
+# work around missing manifests by creating a default one
+ifeq (,$(strip $(LOCAL_MANIFEST_FILE)$(LOCAL_FULL_MANIFEST_FILE)))
+ ifeq (,$(wildcard $(LOCAL_PATH)/AndroidManifest.xml))
+ LOCAL_FULL_MANIFEST_FILE := $(call local-intermediates-dir,COMMON)/DefaultManifest.xml
+ $(call create-default-manifest-file,$(LOCAL_FULL_MANIFEST_FILE),$(call module-min-sdk-version))
+ endif
+endif
include $(BUILD_SYSTEM)/android_manifest.mk
LOCAL_SDK_RES_VERSION:=$(strip $(LOCAL_SDK_RES_VERSION))
diff --git a/core/tasks/module-info.mk b/core/tasks/module-info.mk
index 5d5bfa8..aeeb403 100644
--- a/core/tasks/module-info.mk
+++ b/core/tasks/module-info.mk
@@ -23,6 +23,7 @@
'"classes_jar": [$(foreach w,$(sort $(ALL_MODULES.$(m).CLASSES_JAR)),"$(w)", )], ' \
'"test_mainline_modules": [$(foreach w,$(sort $(ALL_MODULES.$(m).TEST_MAINLINE_MODULES)),"$(w)", )], ' \
'"is_unit_test": "$(ALL_MODULES.$(m).IS_UNIT_TEST)", ' \
+ '"data": [$(foreach w,$(sort $(ALL_MODULES.$(m).TEST_DATA)),"$(w)", )], ' \
'},\n' \
) | sed -e 's/, *\]/]/g' -e 's/, *\}/ }/g' -e '$$s/,$$//' >> $@
$(hide) echo '}' >> $@
diff --git a/core/version_defaults.mk b/core/version_defaults.mk
index 8432513..051de62 100644
--- a/core/version_defaults.mk
+++ b/core/version_defaults.mk
@@ -85,7 +85,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 := 2021-11-05
+ PLATFORM_SECURITY_PATCH := 2022-01-05
endif
.KATI_READONLY := PLATFORM_SECURITY_PATCH
diff --git a/target/board/BoardConfigGkiCommon.mk b/target/board/BoardConfigGkiCommon.mk
index c0f5db9..63ef2b4 100644
--- a/target/board/BoardConfigGkiCommon.mk
+++ b/target/board/BoardConfigGkiCommon.mk
@@ -16,11 +16,7 @@
# Enable GKI 2.0 signing.
BOARD_GKI_SIGNING_KEY_PATH := build/make/target/product/gsi/testkey_rsa2048.pem
BOARD_GKI_SIGNING_ALGORITHM := SHA256_RSA2048
-
-# The following is needed to allow release signing process appends more extra
-# args, e.g., passing --signing_helper_with_files from mkbootimg to avbtool.
-# See b/178559811 for more details.
-BOARD_GKI_SIGNING_SIGNATURE_ARGS := --prop foo:bar
+BOARD_GKI_SIGNING_SIGNATURE_ARGS :=
# Sets boot SPL.
BOOT_SECURITY_PATCH = $(PLATFORM_SECURITY_PATCH)
diff --git a/target/product/default_art_config.mk b/target/product/default_art_config.mk
index f98f7e2..1a0fc76 100644
--- a/target/product/default_art_config.mk
+++ b/target/product/default_art_config.mk
@@ -49,6 +49,7 @@
# APEX boot jars. Keep the list sorted by module names and then library names.
# Note: core-icu4j is moved back to PRODUCT_BOOT_JARS in product_config.mk at a later stage.
+# Note: For modules available in Q, DO NOT add new entries here.
PRODUCT_APEX_BOOT_JARS := \
com.android.appsearch:framework-appsearch \
com.android.conscrypt:conscrypt \
@@ -67,6 +68,7 @@
# List of system_server classpath jars delivered via apex.
# Keep the list sorted by module names and then library names.
+# Note: For modules available in Q, DO NOT add new entries here.
PRODUCT_APEX_SYSTEM_SERVER_JARS := \
com.android.appsearch:service-appsearch \
com.android.art:service-art \
@@ -81,6 +83,7 @@
# List of jars delivered via apex that system_server loads dynamically using separate classloaders.
# Keep the list sorted by module names and then library names.
+# Note: For modules available in Q, DO NOT add new entries here.
PRODUCT_APEX_STANDALONE_SYSTEM_SERVER_JARS := \
com.android.os.statsd:service-statsd \
com.android.scheduling:service-scheduling \
diff --git a/target/product/gsi/Android.mk b/target/product/gsi/Android.mk
index 0d788fa..167ffcf 100644
--- a/target/product/gsi/Android.mk
+++ b/target/product/gsi/Android.mk
@@ -60,11 +60,11 @@
endif
$(check-vndk-list-timestamp): $(INTERNAL_VNDK_LIB_LIST) $(LATEST_VNDK_LIB_LIST) $(HOST_OUT_EXECUTABLES)/update-vndk-list.sh
- $(hide) ($(_READ_INTERNAL_VNDK_LIB_LIST) | \
+ $(hide) ($(_READ_INTERNAL_VNDK_LIB_LIST) | sort | \
diff --old-line-format="Removed %L" \
--new-line-format="Added %L" \
--unchanged-line-format="" \
- $(LATEST_VNDK_LIB_LIST) - \
+ <(cat $(LATEST_VNDK_LIB_LIST) | sort) - \
|| ( echo -e $(_vndk_check_failure_message); exit 1 ))
$(hide) mkdir -p $(dir $@)
$(hide) touch $@
diff --git a/target/product/gsi/current.txt b/target/product/gsi/current.txt
index 52754d4..3cad6f1 100644
--- a/target/product/gsi/current.txt
+++ b/target/product/gsi/current.txt
@@ -29,10 +29,10 @@
VNDK-SP: android.hardware.graphics.mapper@3.0.so
VNDK-SP: android.hardware.graphics.mapper@4.0.so
VNDK-SP: android.hardware.renderscript@1.0.so
+VNDK-SP: android.hidl.safe_union@1.0.so
VNDK-SP: android.hidl.memory.token@1.0.so
VNDK-SP: android.hidl.memory@1.0-impl.so
VNDK-SP: android.hidl.memory@1.0.so
-VNDK-SP: android.hidl.safe_union@1.0.so
VNDK-SP: libRSCpuRef.so
VNDK-SP: libRSDriver.so
VNDK-SP: libRS_internal.so
@@ -56,9 +56,11 @@
VNDK-SP: libutils.so
VNDK-SP: libutilscallstack.so
VNDK-SP: libz.so
+VNDK-core: android.hardware.audio.common-V1-ndk.so
VNDK-core: android.hardware.audio.common@2.0.so
VNDK-core: android.hardware.authsecret-V1-ndk.so
VNDK-core: android.hardware.automotive.occupant_awareness-V1-ndk.so
+VNDK-core: android.hardware.bluetooth.audio-V1-ndk.so
VNDK-core: android.hardware.configstore-utils.so
VNDK-core: android.hardware.configstore@1.0.so
VNDK-core: android.hardware.configstore@1.1.so
@@ -92,6 +94,7 @@
VNDK-core: android.hardware.radio.sim-V1-ndk.so
VNDK-core: android.hardware.radio.voice-V1-ndk.so
VNDK-core: android.hardware.rebootescrow-V1-ndk.so
+VNDK-core: android.hardware.security.dice-V1-ndk.so
VNDK-core: android.hardware.security.keymint-V1-ndk.so
VNDK-core: android.hardware.security.secureclock-V1-ndk.so
VNDK-core: android.hardware.security.sharedsecret-V1-ndk.so
@@ -100,8 +103,10 @@
VNDK-core: android.hardware.vibrator-V2-ndk.so
VNDK-core: android.hardware.weaver-V1-ndk.so
VNDK-core: android.hardware.wifi.hostapd-V1-ndk.so
+VNDK-core: android.hardware.wifi.supplicant-V1-ndk.so
VNDK-core: android.hidl.token@1.0-utils.so
VNDK-core: android.hidl.token@1.0.so
+VNDK-core: android.media.audio.common.types-V1-ndk.so
VNDK-core: android.system.keystore2-V1-ndk.so
VNDK-core: android.system.suspend-V1-ndk.so
VNDK-core: android.system.suspend@1.0.so
diff --git a/target/product/gsi_keys.mk b/target/product/gsi_keys.mk
deleted file mode 100644
index 5a814db..0000000
--- a/target/product/gsi_keys.mk
+++ /dev/null
@@ -1,22 +0,0 @@
-#
-# 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.
-#
-
-# Include GSI keys into first-stage ramdisk, so we can enable verified
-# boot when booting a GSI.
-PRODUCT_PACKAGES += \
- q-gsi.avbpubkey \
- r-gsi.avbpubkey \
- s-gsi.avbpubkey \
diff --git a/target/product/security/Android.mk b/target/product/security/Android.mk
index cedad5b..9daa3bf 100644
--- a/target/product/security/Android.mk
+++ b/target/product/security/Android.mk
@@ -63,9 +63,17 @@
LOCAL_MODULE_STEM := otacerts.zip
LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/security
include $(BUILD_SYSTEM)/base_rules.mk
+
+extra_ota_keys := $(addsuffix .x509.pem,$(PRODUCT_EXTRA_OTA_KEYS))
+
$(LOCAL_BUILT_MODULE): PRIVATE_CERT := $(DEFAULT_SYSTEM_DEV_CERTIFICATE).x509.pem
-$(LOCAL_BUILT_MODULE): $(SOONG_ZIP) $(DEFAULT_SYSTEM_DEV_CERTIFICATE).x509.pem
- $(SOONG_ZIP) -o $@ -j -symlinks=false -f $(PRIVATE_CERT)
+$(LOCAL_BUILT_MODULE): PRIVATE_EXTRA_OTA_KEYS := $(extra_ota_keys)
+$(LOCAL_BUILT_MODULE): \
+ $(SOONG_ZIP) \
+ $(DEFAULT_SYSTEM_DEV_CERTIFICATE).x509.pem \
+ $(extra_ota_keys)
+ $(SOONG_ZIP) -o $@ -j -symlinks=false \
+ $(addprefix -f ,$(PRIVATE_CERT) $(PRIVATE_EXTRA_OTA_KEYS))
#######################################
@@ -80,7 +88,7 @@
LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/system/etc/security
include $(BUILD_SYSTEM)/base_rules.mk
-extra_recovery_keys := $(patsubst %,%.x509.pem,$(PRODUCT_EXTRA_RECOVERY_KEYS))
+extra_recovery_keys := $(addsuffix .x509.pem,$(PRODUCT_EXTRA_RECOVERY_KEYS))
$(LOCAL_BUILT_MODULE): PRIVATE_CERT := $(DEFAULT_SYSTEM_DEV_CERTIFICATE).x509.pem
$(LOCAL_BUILT_MODULE): PRIVATE_EXTRA_RECOVERY_KEYS := $(extra_recovery_keys)
@@ -89,4 +97,4 @@
$(DEFAULT_SYSTEM_DEV_CERTIFICATE).x509.pem \
$(extra_recovery_keys)
$(SOONG_ZIP) -o $@ -j -symlinks=false \
- $(foreach key_file, $(PRIVATE_CERT) $(PRIVATE_EXTRA_RECOVERY_KEYS), -f $(key_file))
+ $(addprefix -f ,$(PRIVATE_CERT) $(PRIVATE_EXTRA_RECOVERY_KEYS))
diff --git a/tools/Android.bp b/tools/Android.bp
index 269e610..2f3b393 100644
--- a/tools/Android.bp
+++ b/tools/Android.bp
@@ -28,27 +28,11 @@
python_binary_host {
name: "generate-self-extracting-archive",
srcs: ["generate-self-extracting-archive.py"],
- version: {
- py2: {
- enabled: true,
- },
- py3: {
- enabled: false,
- },
- },
}
python_binary_host {
name: "post_process_props",
srcs: ["post_process_props.py"],
- version: {
- py2: {
- enabled: false,
- },
- py3: {
- enabled: true,
- },
- },
}
python_test_host {
@@ -58,14 +42,6 @@
"post_process_props.py",
"test_post_process_props.py",
],
- version: {
- py2: {
- enabled: false,
- },
- py3: {
- enabled: true,
- },
- },
test_config: "post_process_props_unittest.xml",
test_suites: ["general-tests"],
}
@@ -73,14 +49,6 @@
python_binary_host {
name: "extract_kernel",
srcs: ["extract_kernel.py"],
- version: {
- py2: {
- enabled: false,
- },
- py3: {
- enabled: true,
- },
- },
}
genrule_defaults {
diff --git a/tools/compliance/readgraph.go b/tools/compliance/readgraph.go
index 0b5ebfe..45fa134 100644
--- a/tools/compliance/readgraph.go
+++ b/tools/compliance/readgraph.go
@@ -80,7 +80,7 @@
lg := newLicenseGraph()
for _, f := range files {
- if strings.HasSuffix(f, ".meta_lic") {
+ if strings.HasSuffix(f, "meta_lic") {
lg.rootFiles = append(lg.rootFiles, f)
} else {
lg.rootFiles = append(lg.rootFiles, f+".meta_lic")
diff --git a/tools/generate-self-extracting-archive.py b/tools/generate-self-extracting-archive.py
index 5b0628d..c9f56cb 100755
--- a/tools/generate-self-extracting-archive.py
+++ b/tools/generate-self-extracting-archive.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
#
# Copyright (C) 2019 The Android Open Source Project
#
@@ -120,7 +120,7 @@
def main(argv):
if len(argv) != 5:
- print 'generate-self-extracting-archive.py expects exactly 4 arguments'
+ print('generate-self-extracting-archive.py expects exactly 4 arguments')
sys.exit(1)
output_filename = argv[1]
@@ -134,11 +134,11 @@
license = license_file.read()
if not license:
- print 'License file was empty'
+ print('License file was empty')
sys.exit(1)
if 'SOFTWARE LICENSE AGREEMENT' not in license:
- print 'License does not look like a license'
+ print('License does not look like a license')
sys.exit(1)
comment_line = '# %s\n' % comment
diff --git a/tools/releasetools/Android.bp b/tools/releasetools/Android.bp
index bf7f9a0..f3123b2 100644
--- a/tools/releasetools/Android.bp
+++ b/tools/releasetools/Android.bp
@@ -554,12 +554,25 @@
}
python_binary_host {
- name: "fsverity_metadata_generator",
+ name: "fsverity_manifest_generator",
srcs: [
- "fsverity_metadata_generator.py",
+ "fsverity_manifest_generator.py",
],
libs: [
"fsverity_digests_proto_python",
+ "releasetools_common",
+ ],
+ required: [
+ "aapt2",
+ "apksigner",
+ "fsverity",
+ ],
+}
+
+python_binary_host {
+ name: "fsverity_metadata_generator",
+ srcs: [
+ "fsverity_metadata_generator.py",
],
required: [
"fsverity",
diff --git a/tools/releasetools/add_img_to_target_files.py b/tools/releasetools/add_img_to_target_files.py
index 2a4b56b..0c39827 100644
--- a/tools/releasetools/add_img_to_target_files.py
+++ b/tools/releasetools/add_img_to_target_files.py
@@ -759,6 +759,7 @@
has_recovery = OPTIONS.info_dict.get("no_recovery") != "true"
has_boot = OPTIONS.info_dict.get("no_boot") != "true"
+ has_init_boot = OPTIONS.info_dict.get("init_boot") == "true"
has_vendor_boot = OPTIONS.info_dict.get("vendor_boot") == "true"
# {vendor,odm,product,system_ext,vendor_dlkm,odm_dlkm, system, system_other}.img
@@ -819,6 +820,17 @@
if output_zip:
boot_image.AddToZip(output_zip)
+ if has_init_boot:
+ banner("init_boot")
+ init_boot_image = common.GetBootableImage(
+ "IMAGES/init_boot.img", "init_boot.img", OPTIONS.input_tmp, "INIT_BOOT")
+ if init_boot_image:
+ partitions['init_boot'] = os.path.join(OPTIONS.input_tmp, "IMAGES", "init_boot.img")
+ if not os.path.exists(partitions['init_boot']):
+ init_boot_image.WriteToDir(OPTIONS.input_tmp)
+ if output_zip:
+ init_boot_image.AddToZip(output_zip)
+
if has_vendor_boot:
banner("vendor_boot")
vendor_boot_image = common.GetVendorBootImage(
diff --git a/tools/releasetools/build_image.py b/tools/releasetools/build_image.py
index 34aa1a6..a4377c7 100755
--- a/tools/releasetools/build_image.py
+++ b/tools/releasetools/build_image.py
@@ -35,9 +35,6 @@
import common
import verity_utils
-from fsverity_digests_pb2 import FSVerityDigests
-from fsverity_metadata_generator import FSVerityMetadataGenerator
-
logger = logging.getLogger(__name__)
OPTIONS = common.OPTIONS
@@ -451,69 +448,6 @@
return mkfs_output
-def GenerateFSVerityMetadata(in_dir, fsverity_path, apk_key_path, apk_manifest_path, apk_out_path):
- """Generates fsverity metadata files.
-
- By setting PRODUCT_SYSTEM_FSVERITY_GENERATE_METADATA := true, fsverity
- metadata files will be generated. For the input files, see `patterns` below.
-
- One metadata file per one input file will be generated with the suffix
- .fsv_meta. e.g. system/framework/foo.jar -> system/framework/foo.jar.fsv_meta
- Also a mapping file containing fsverity digests will be generated to
- system/etc/security/fsverity/BuildManifest.apk.
-
- Args:
- in_dir: temporary working directory (same as BuildImage)
- fsverity_path: path to host tool fsverity
- apk_key_path: path to key (e.g. build/make/target/product/security/platform)
- apk_manifest_path: path to AndroidManifest.xml for APK
- apk_out_path: path to the output APK
-
- Returns:
- None. The files are generated directly under in_dir.
- """
-
- patterns = [
- "system/framework/*.jar",
- "system/framework/oat/*/*.oat",
- "system/framework/oat/*/*.vdex",
- "system/framework/oat/*/*.art",
- "system/etc/boot-image.prof",
- "system/etc/dirty-image-objects",
- ]
- files = []
- for pattern in patterns:
- files += glob.glob(os.path.join(in_dir, pattern))
- files = sorted(set(files))
-
- generator = FSVerityMetadataGenerator(fsverity_path)
- generator.set_hash_alg("sha256")
-
- digests = FSVerityDigests()
- for f in files:
- generator.generate(f)
- # f is a full path for now; make it relative so it starts with {mount_point}/
- digest = digests.digests[os.path.relpath(f, in_dir)]
- digest.digest = generator.digest(f)
- digest.hash_alg = "sha256"
-
- temp_dir = common.MakeTempDir()
-
- os.mkdir(os.path.join(temp_dir, "assets"))
- metadata_path = os.path.join(temp_dir, "assets", "build_manifest")
- with open(metadata_path, "wb") as f:
- f.write(digests.SerializeToString())
-
- apk_path = os.path.join(in_dir, apk_out_path)
-
- common.RunAndCheckOutput(["aapt2", "link",
- "-A", os.path.join(temp_dir, "assets"),
- "-o", apk_path,
- "--manifest", apk_manifest_path])
- common.RunAndCheckOutput(["apksigner", "sign", "--in", apk_path,
- "--cert", apk_key_path + ".x509.pem",
- "--key", apk_key_path + ".pk8"])
-
def BuildImage(in_dir, prop_dict, out_file, target_out=None):
"""Builds an image for the files under in_dir and writes it to out_file.
@@ -541,13 +475,6 @@
elif fs_type.startswith("f2fs") and prop_dict.get("f2fs_compress") == "true":
fs_spans_partition = False
- if "fsverity_generate_metadata" in prop_dict:
- GenerateFSVerityMetadata(in_dir,
- fsverity_path=prop_dict["fsverity"],
- apk_key_path=prop_dict["fsverity_apk_key"],
- apk_manifest_path=prop_dict["fsverity_apk_manifest"],
- apk_out_path=prop_dict["fsverity_apk_out"])
-
# Get a builder for creating an image that's to be verified by Verified Boot,
# or None if not applicable.
verity_image_builder = verity_utils.CreateVerityImageBuilder(prop_dict)
@@ -801,11 +728,6 @@
copy_prop("system_root_image", "system_root_image")
copy_prop("root_dir", "root_dir")
copy_prop("root_fs_config", "root_fs_config")
- copy_prop("fsverity", "fsverity")
- copy_prop("fsverity_generate_metadata", "fsverity_generate_metadata")
- copy_prop("fsverity_apk_key","fsverity_apk_key")
- copy_prop("fsverity_apk_manifest","fsverity_apk_manifest")
- copy_prop("fsverity_apk_out","fsverity_apk_out")
elif mount_point == "data":
# Copy the generic fs type first, override with specific one if available.
copy_prop("flash_logical_block_size", "flash_logical_block_size")
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index 64ac95a..30dcf5b 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -73,6 +73,7 @@
self.search_path = os.environ["ANDROID_HOST_OUT"]
self.signapk_shared_library_path = "lib64" # Relative to search_path
self.extra_signapk_args = []
+ self.aapt2_path = "aapt2"
self.java_path = "java" # Use the one on the path by default.
self.java_args = ["-Xmx2048m"] # The default JVM args.
self.android_jar_path = None
@@ -111,7 +112,7 @@
# descriptor into vbmeta.img. When adding a new entry here, the
# AVB_FOOTER_ARGS_BY_PARTITION in sign_target_files_apks need to be updated
# accordingly.
-AVB_PARTITIONS = ('boot', 'dtbo', 'odm', 'product', 'pvmfw', 'recovery',
+AVB_PARTITIONS = ('boot', 'init_boot', 'dtbo', 'odm', 'product', 'pvmfw', 'recovery',
'system', 'system_ext', 'vendor', 'vendor_boot',
'vendor_dlkm', 'odm_dlkm')
@@ -130,7 +131,7 @@
]
# Partitions with a build.prop file
-PARTITIONS_WITH_BUILD_PROP = PARTITIONS_WITH_CARE_MAP + ['boot']
+PARTITIONS_WITH_BUILD_PROP = PARTITIONS_WITH_CARE_MAP + ['boot', 'init_boot']
# See sysprop.mk. If file is moved, add new search paths here; don't remove
# existing search paths.
@@ -935,9 +936,9 @@
def FromInputFile(input_file, name, placeholder_values=None, ramdisk_format=RamdiskFormat.LZ4):
"""Loads the build.prop file and builds the attributes."""
- if name == "boot":
+ if name in ("boot", "init_boot"):
data = PartitionBuildProps._ReadBootPropFile(
- input_file, ramdisk_format=ramdisk_format)
+ input_file, name, ramdisk_format=ramdisk_format)
else:
data = PartitionBuildProps._ReadPartitionPropFile(input_file, name)
@@ -946,15 +947,16 @@
return props
@staticmethod
- def _ReadBootPropFile(input_file, ramdisk_format):
+ def _ReadBootPropFile(input_file, partition_name, ramdisk_format):
"""
Read build.prop for boot image from input_file.
Return empty string if not found.
"""
+ image_path = 'IMAGES/' + partition_name + '.img'
try:
- boot_img = ExtractFromInputFile(input_file, 'IMAGES/boot.img')
+ boot_img = ExtractFromInputFile(input_file, image_path)
except KeyError:
- logger.warning('Failed to read IMAGES/boot.img')
+ logger.warning('Failed to read %s', image_path)
return ''
prop_file = GetBootImageBuildProp(boot_img, ramdisk_format=ramdisk_format)
if prop_file is None:
@@ -1539,6 +1541,8 @@
logger.info("Excluded kernel binary from recovery image.")
else:
kernel = "kernel"
+ elif partition_name == "init_boot":
+ pass
else:
kernel = image_name.replace("boot", "kernel")
kernel = kernel.replace(".img", "")
@@ -1593,6 +1597,8 @@
# Fall back to "mkbootimg_args" for recovery image
# in case "recovery_mkbootimg_args" is not set.
args = info_dict.get("mkbootimg_args")
+ elif partition_name == "init_boot":
+ args = info_dict.get("mkbootimg_init_args")
else:
args = info_dict.get("mkbootimg_args")
if args and args.strip():
@@ -1694,8 +1700,8 @@
Args:
image_path: The full path of the image, e.g., /path/to/boot.img.
prebuilt_name: The prebuilt image name, e.g., boot.img, boot-5.4-gz.img,
- boot-5.10.img, recovery.img.
- partition_name: The partition name, e.g., 'boot' or 'recovery'.
+ boot-5.10.img, recovery.img or init_boot.img.
+ partition_name: The partition name, e.g., 'boot', 'init_boot' or 'recovery'.
info_dict: The information dict read from misc_info.txt.
"""
if info_dict is None:
@@ -1719,6 +1725,35 @@
RunAndCheckOutput(cmd)
+def HasRamdisk(partition_name, info_dict=None):
+ """Returns true/false to see if a bootable image should have a ramdisk.
+
+ Args:
+ partition_name: The partition name, e.g., 'boot', 'init_boot' or 'recovery'.
+ info_dict: The information dict read from misc_info.txt.
+ """
+ if info_dict is None:
+ info_dict = OPTIONS.info_dict
+
+ if partition_name != "boot":
+ return True # init_boot.img or recovery.img has a ramdisk.
+
+ if info_dict.get("recovery_as_boot") == "true":
+ return True # the recovery-as-boot boot.img has a RECOVERY ramdisk.
+
+ if info_dict.get("system_root_image") == "true":
+ # The ramdisk content is merged into the system.img, so there is NO
+ # ramdisk in the boot.img or boot-<kernel version>.img.
+ return False
+
+ if info_dict.get("init_boot") == "true":
+ # The ramdisk is moved to the init_boot.img, so there is NO
+ # ramdisk in the boot.img or boot-<kernel version>.img.
+ return False
+
+ return True
+
+
def GetBootableImage(name, prebuilt_name, unpack_dir, tree_subdir,
info_dict=None, two_step_image=False):
"""Return a File object with the desired bootable image.
@@ -1740,23 +1775,18 @@
logger.info("using prebuilt %s from IMAGES...", prebuilt_name)
return File.FromLocalFile(name, prebuilt_path)
+ partition_name = tree_subdir.lower()
prebuilt_path = os.path.join(unpack_dir, "PREBUILT_IMAGES", prebuilt_name)
if os.path.exists(prebuilt_path):
logger.info("Re-signing prebuilt %s from PREBUILT_IMAGES...", prebuilt_name)
signed_img = MakeTempFile()
shutil.copy(prebuilt_path, signed_img)
- partition_name = tree_subdir.lower()
_SignBootableImage(signed_img, prebuilt_name, partition_name, info_dict)
return File.FromLocalFile(name, signed_img)
logger.info("building image from target_files %s...", tree_subdir)
- # With system_root_image == "true", we don't pack ramdisk into the boot image.
- # Unless "recovery_as_boot" is specified, in which case we carry the ramdisk
- # for recovery.
- has_ramdisk = (info_dict.get("system_root_image") != "true" or
- prebuilt_name != "boot.img" or
- info_dict.get("recovery_as_boot") == "true")
+ has_ramdisk = HasRamdisk(partition_name, info_dict)
fs_config = "META/" + tree_subdir.lower() + "_filesystem_config.txt"
data = _BuildBootableImage(prebuilt_name, os.path.join(unpack_dir, tree_subdir),
@@ -2155,8 +2185,8 @@
def GetMinSdkVersion(apk_name):
"""Gets the minSdkVersion declared in the APK.
- It calls 'aapt2' to query the embedded minSdkVersion from the given APK file.
- This can be both a decimal number (API Level) or a codename.
+ It calls OPTIONS.aapt2_path to query the embedded minSdkVersion from the given
+ APK file. This can be both a decimal number (API Level) or a codename.
Args:
apk_name: The APK filename.
@@ -2168,7 +2198,7 @@
ExternalError: On failing to obtain the min SDK version.
"""
proc = Run(
- ["aapt2", "dump", "badging", apk_name], stdout=subprocess.PIPE,
+ [OPTIONS.aapt2_path, "dump", "badging", apk_name], stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
stdoutdata, stderrdata = proc.communicate()
if proc.returncode != 0:
@@ -2444,7 +2474,7 @@
opts, args = getopt.getopt(
argv, "hvp:s:x:" + extra_opts,
["help", "verbose", "path=", "signapk_path=",
- "signapk_shared_library_path=", "extra_signapk_args=",
+ "signapk_shared_library_path=", "extra_signapk_args=", "aapt2_path=",
"java_path=", "java_args=", "android_jar_path=", "public_key_suffix=",
"private_key_suffix=", "boot_signer_path=", "boot_signer_args=",
"verity_signer_path=", "verity_signer_args=", "device_specific=",
@@ -2468,6 +2498,8 @@
OPTIONS.signapk_shared_library_path = a
elif o in ("--extra_signapk_args",):
OPTIONS.extra_signapk_args = shlex.split(a)
+ elif o in ("--aapt2_path",):
+ OPTIONS.aapt2_path = a
elif o in ("--java_path",):
OPTIONS.java_path = a
elif o in ("--java_args",):
@@ -3863,7 +3895,10 @@
disable_sparse = OPTIONS.info_dict.get(which + "_disable_sparse")
image_blocks = int(image_size) // 4096 - 1
- assert image_blocks > 0, "blocks for {} must be positive".format(which)
+ # It's OK for image_blocks to be 0, because care map ranges are inclusive.
+ # So 0-0 means "just block 0", which is valid.
+ assert image_blocks >= 0, "blocks for {} must be non-negative, image size: {}".format(
+ which, image_size)
# For sparse images, we will only check the blocks that are listed in the care
# map, i.e. the ones with meaningful data.
diff --git a/tools/releasetools/fsverity_manifest_generator.py b/tools/releasetools/fsverity_manifest_generator.py
new file mode 100644
index 0000000..527cddb
--- /dev/null
+++ b/tools/releasetools/fsverity_manifest_generator.py
@@ -0,0 +1,105 @@
+#!/usr/bin/env python3
+#
+# Copyright 2022 Google Inc. All rights reserved.
+#
+# 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.
+
+"""
+`fsverity_manifest_generator` generates build manifest APK file containing
+digests of target files. The APK file is signed so the manifest inside the APK
+can be trusted.
+"""
+
+import argparse
+import common
+import os
+import subprocess
+import sys
+from fsverity_digests_pb2 import FSVerityDigests
+
+HASH_ALGORITHM = 'sha256'
+
+def _digest(fsverity_path, input_file):
+ cmd = [fsverity_path, 'digest', input_file]
+ cmd.extend(['--compact'])
+ cmd.extend(['--hash-alg', HASH_ALGORITHM])
+ out = subprocess.check_output(cmd, universal_newlines=True).strip()
+ return bytes(bytearray.fromhex(out))
+
+if __name__ == '__main__':
+ p = argparse.ArgumentParser()
+ p.add_argument(
+ '--output',
+ help='Path to the output manifest APK',
+ required=True)
+ p.add_argument(
+ '--fsverity-path',
+ help='path to the fsverity program',
+ required=True)
+ p.add_argument(
+ '--aapt2-path',
+ help='path to the aapt2 program',
+ required=True)
+ p.add_argument(
+ '--min-sdk-version',
+ help='minimum supported sdk version of the generated manifest apk',
+ required=True)
+ p.add_argument(
+ '--framework-res',
+ help='path to framework-res.apk',
+ required=True)
+ p.add_argument(
+ '--apksigner-path',
+ help='path to the apksigner program',
+ required=True)
+ p.add_argument(
+ '--apk-key-path',
+ help='path to the apk key',
+ required=True)
+ p.add_argument(
+ '--apk-manifest-path',
+ help='path to AndroidManifest.xml',
+ required=True)
+ p.add_argument(
+ '--base-dir',
+ help='directory to use as a relative root for the inputs',
+ required=True)
+ p.add_argument(
+ 'inputs',
+ nargs='+',
+ help='input file for the build manifest')
+ args = p.parse_args(sys.argv[1:])
+
+ digests = FSVerityDigests()
+ for f in sorted(args.inputs):
+ # f is a full path for now; make it relative so it starts with {mount_point}/
+ digest = digests.digests[os.path.relpath(f, args.base_dir)]
+ digest.digest = _digest(args.fsverity_path, f)
+ digest.hash_alg = HASH_ALGORITHM
+
+ temp_dir = common.MakeTempDir()
+
+ os.mkdir(os.path.join(temp_dir, "assets"))
+ metadata_path = os.path.join(temp_dir, "assets", "build_manifest.pb")
+ with open(metadata_path, "wb") as f:
+ f.write(digests.SerializeToString())
+
+ common.RunAndCheckOutput([args.aapt2_path, "link",
+ "-A", os.path.join(temp_dir, "assets"),
+ "-o", args.output,
+ "--min-sdk-version", args.min_sdk_version,
+ "-I", args.framework_res,
+ "--manifest", args.apk_manifest_path])
+ common.RunAndCheckOutput([args.apksigner_path, "sign", "--in", args.output,
+ "--cert", args.apk_key_path + ".x509.pem",
+ "--key", args.apk_key_path + ".pk8"])
diff --git a/tools/releasetools/fsverity_metadata_generator.py b/tools/releasetools/fsverity_metadata_generator.py
index a300d2e..fa7cd39 100644
--- a/tools/releasetools/fsverity_metadata_generator.py
+++ b/tools/releasetools/fsverity_metadata_generator.py
@@ -178,6 +178,7 @@
out.write(sig)
else:
out.write(pack('<I', SIG_TYPE_NONE))
+ out.write(pack('<I', 0))
# 4. merkle tree
with open(merkletree_file, 'rb') as f:
diff --git a/tools/releasetools/img_from_target_files.py b/tools/releasetools/img_from_target_files.py
index cbb51e1..0b2b187 100755
--- a/tools/releasetools/img_from_target_files.py
+++ b/tools/releasetools/img_from_target_files.py
@@ -124,7 +124,7 @@
for image_path in [name for name in namelist if name.startswith('IMAGES/')]:
image = os.path.basename(image_path)
- if OPTIONS.bootable_only and image not in('boot.img', 'recovery.img', 'bootloader'):
+ if OPTIONS.bootable_only and image not in('boot.img', 'recovery.img', 'bootloader', 'init_boot.img'):
continue
if not image.endswith('.img') and image != 'bootloader':
continue
diff --git a/tools/releasetools/ota_from_target_files.py b/tools/releasetools/ota_from_target_files.py
index c21de14..58f0e85 100755
--- a/tools/releasetools/ota_from_target_files.py
+++ b/tools/releasetools/ota_from_target_files.py
@@ -230,6 +230,9 @@
--compressor_types
A colon ':' separated list of compressors. Allowed values are bz2 and brotli.
+
+ --enable_zucchini
+ Whether to enable to zucchini feature. Will generate smaller OTA but uses more memory.
"""
from __future__ import print_function
@@ -299,6 +302,7 @@
OPTIONS.enable_vabc_xor = True
OPTIONS.force_minor_version = None
OPTIONS.compressor_types = None
+OPTIONS.enable_zucchini = None
POSTINSTALL_CONFIG = 'META/postinstall_config.txt'
DYNAMIC_PARTITION_INFO = 'META/dynamic_partitions_info.txt'
@@ -1141,6 +1145,14 @@
partition_timestamps_flags = GeneratePartitionTimestampFlags(
metadata.postcondition.partition_state)
+ # Auto-check for compatibility only if --enable_zucchini omitted. Otherwise
+ # let user override zucchini settings. This is useful for testing.
+ if OPTIONS.enable_zucchini is None:
+ if not ota_utils.IsZucchiniCompatible(source_file, target_file):
+ additional_args += ["--enable_zucchini", "false"]
+ else:
+ additional_args += ["--enable_zucchini", str(OPTIONS.enable_zucchini).lower()]
+
if OPTIONS.disable_vabc:
additional_args += ["--disable_vabc", "true"]
if OPTIONS.enable_vabc_xor:
@@ -1326,6 +1338,8 @@
OPTIONS.force_minor_version = a
elif o == "--compressor_types":
OPTIONS.compressor_types = a
+ elif o == "--enable_zucchini":
+ OPTIONS.enable_zucchini = a.lower() != "false"
else:
return False
return True
@@ -1373,6 +1387,7 @@
"enable_vabc_xor=",
"force_minor_version=",
"compressor_types=",
+ "enable_zucchin=",
], extra_option_handler=option_handler)
if len(args) != 2:
diff --git a/tools/releasetools/ota_utils.py b/tools/releasetools/ota_utils.py
index 6c5fc05..a4ec9e2 100644
--- a/tools/releasetools/ota_utils.py
+++ b/tools/releasetools/ota_utils.py
@@ -638,3 +638,38 @@
target_apex.source_version = source_apex_versions[name]
return target_apex_proto.SerializeToString()
+
+
+def IsZucchiniCompatible(source_file: str, target_file: str):
+ """Check whether zucchini versions in two builds are compatible
+
+ Args:
+ source_file: Path to source build's target_file.zip
+ target_file: Path to target build's target_file.zip
+
+ Returns:
+ bool true if and only if zucchini versions are compatible
+ """
+ if source_file is None or target_file is None:
+ return False
+ assert os.path.exists(source_file)
+ assert os.path.exists(target_file)
+
+ assert zipfile.is_zipfile(source_file) or os.path.isdir(source_file)
+ assert zipfile.is_zipfile(target_file) or os.path.isdir(target_file)
+ _ZUCCHINI_CONFIG_ENTRY_NAME = "META/zucchini_config.txt"
+
+ def ReadEntry(path, entry):
+ # Read an entry inside a .zip file or extracted dir of .zip file
+ if zipfile.is_zipfile(path):
+ with zipfile.ZipFile(path, "r", allowZip64=True) as zfp:
+ if entry in zfp.namelist():
+ return zfp.read(entry).decode()
+ else:
+ entry_path = os.path.join(entry, path)
+ if os.path.exists(entry_path):
+ with open(entry_path, "r") as fp:
+ return fp.read()
+ else:
+ return ""
+ return ReadEntry(source_file, _ZUCCHINI_CONFIG_ENTRY_NAME) == ReadEntry(target_file, _ZUCCHINI_CONFIG_ENTRY_NAME)
diff --git a/tools/releasetools/sign_apex.py b/tools/releasetools/sign_apex.py
index 679f57a..66f5e05 100755
--- a/tools/releasetools/sign_apex.py
+++ b/tools/releasetools/sign_apex.py
@@ -141,7 +141,7 @@
signing_args=options.get('payload_extra_args'),
codename_to_api_level_map=options.get(
'codename_to_api_level_map', {}),
- sign_tool=options['sign_tool'])
+ sign_tool=options.get('sign_tool', None))
shutil.copyfile(signed_apex, args[1])
logger.info("done.")
diff --git a/tools/releasetools/sign_target_files_apks.py b/tools/releasetools/sign_target_files_apks.py
index 5626980..c615b84 100755
--- a/tools/releasetools/sign_target_files_apks.py
+++ b/tools/releasetools/sign_target_files_apks.py
@@ -201,6 +201,7 @@
AVB_FOOTER_ARGS_BY_PARTITION = {
'boot': 'avb_boot_add_hash_footer_args',
+ 'init_boot': 'avb_init_boot_add_hash_footer_args',
'dtbo': 'avb_dtbo_add_hash_footer_args',
'product': 'avb_product_add_hashtree_footer_args',
'recovery': 'avb_recovery_add_hash_footer_args',
@@ -519,9 +520,14 @@
compressed_extension):
# maxsize measures the maximum filename length, including the ones to be
# skipped.
- maxsize = max(
- [len(os.path.basename(i.filename)) for i in input_tf_zip.infolist()
- if GetApkFileInfo(i.filename, compressed_extension, [])[0]])
+ try:
+ maxsize = max(
+ [len(os.path.basename(i.filename)) for i in input_tf_zip.infolist()
+ if GetApkFileInfo(i.filename, compressed_extension, [])[0]])
+ except ValueError:
+ # Sets this to zero for targets without APK files, e.g., gki_arm64.
+ maxsize = 0
+
system_root_image = misc_info.get("system_root_image") == "true"
for info in input_tf_zip.infolist():
@@ -608,7 +614,7 @@
common.ZipWriteStr(output_tf_zip, out_info, new_data)
# Replace the certs in *mac_permissions.xml (there could be multiple, such
- # as {system,vendor}/etc/selinux/{plat,nonplat}_mac_permissions.xml).
+ # as {system,vendor}/etc/selinux/{plat,vendor}_mac_permissions.xml).
elif filename.endswith("mac_permissions.xml"):
print("Rewriting %s with new keys." % (filename,))
new_data = ReplaceCerts(data.decode())
@@ -882,14 +888,27 @@
except KeyError:
raise common.ExternalError("can't read META/otakeys.txt from input")
- extra_recovery_keys = misc_info.get("extra_recovery_keys")
- if extra_recovery_keys:
+ extra_ota_keys_info = misc_info.get("extra_ota_keys")
+ if extra_ota_keys_info:
+ extra_ota_keys = [OPTIONS.key_map.get(k, k) + ".x509.pem"
+ for k in extra_ota_keys_info.split()]
+ print("extra ota key(s): " + ", ".join(extra_ota_keys))
+ else:
+ extra_ota_keys = []
+ for k in extra_ota_keys:
+ if not os.path.isfile(k):
+ raise common.ExternalError(k + " does not exist or is not a file")
+
+ extra_recovery_keys_info = misc_info.get("extra_recovery_keys")
+ if extra_recovery_keys_info:
extra_recovery_keys = [OPTIONS.key_map.get(k, k) + ".x509.pem"
- for k in extra_recovery_keys.split()]
- if extra_recovery_keys:
- print("extra recovery-only key(s): " + ", ".join(extra_recovery_keys))
+ for k in extra_recovery_keys_info.split()]
+ print("extra recovery-only key(s): " + ", ".join(extra_recovery_keys))
else:
extra_recovery_keys = []
+ for k in extra_recovery_keys:
+ if not os.path.isfile(k):
+ raise common.ExternalError(k + " does not exist or is not a file")
mapped_keys = []
for k in keylist:
@@ -912,13 +931,20 @@
mapped_keys.append(mapped_devkey + ".x509.pem")
print("META/otakeys.txt has no keys; using %s for OTA package"
" verification." % (mapped_keys[0],))
+ for k in mapped_keys:
+ if not os.path.isfile(k):
+ raise common.ExternalError(k + " does not exist or is not a file")
otacerts = [info
for info in input_tf_zip.infolist()
if info.filename.endswith("/otacerts.zip")]
for info in otacerts:
- print("Rewriting OTA key:", info.filename, mapped_keys)
- WriteOtacerts(output_tf_zip, info.filename, mapped_keys)
+ if info.filename.startswith(("BOOT/", "RECOVERY/", "VENDOR_BOOT/")):
+ extra_keys = extra_recovery_keys
+ else:
+ extra_keys = extra_ota_keys
+ print("Rewriting OTA key:", info.filename, mapped_keys + extra_keys)
+ WriteOtacerts(output_tf_zip, info.filename, mapped_keys + extra_keys)
def ReplaceVerityPublicKey(output_zip, filename, key_path):
diff --git a/tools/releasetools/test_apex_utils.py b/tools/releasetools/test_apex_utils.py
index ed920f2..2aa6f6c 100644
--- a/tools/releasetools/test_apex_utils.py
+++ b/tools/releasetools/test_apex_utils.py
@@ -198,8 +198,9 @@
# pass `false` as a sign_tool to see the invocation error
with self.assertRaises(common.ExternalError) as cm:
- signer = apex_utils.ApexApkSigner(apex_path, None, None, sign_tool='false')
- signer.ProcessApexFile(apk_keys, self.payload_key)
+ signer = apex_utils.ApexApkSigner(
+ apex_path, None, None, sign_tool='false')
+ signer.ProcessApexFile(apk_keys, self.payload_key)
the_exception = cm.exception
- self.assertIn('Failed to run command \'[\'false\'', the_exception.message)
+ self.assertIn('Failed to run command \'[\'false\'', str(the_exception))
diff --git a/tools/releasetools/test_sign_target_files_apks.py b/tools/releasetools/test_sign_target_files_apks.py
index 92dca9a..0f13add 100644
--- a/tools/releasetools/test_sign_target_files_apks.py
+++ b/tools/releasetools/test_sign_target_files_apks.py
@@ -62,6 +62,9 @@
'avb_boot_add_hash_footer_args':
('--prop com.android.build.boot.os_version:R '
'--prop com.android.build.boot.security_patch:2019-09-05'),
+ 'avb_init_boot_add_hash_footer_args':
+ ('--prop com.android.build.boot.os_version:R '
+ '--prop com.android.build.boot.security_patch:2019-09-05'),
'avb_system_add_hashtree_footer_args':
('--prop com.android.build.system.os_version:R '
'--prop com.android.build.system.security_patch:2019-09-05 '
@@ -77,6 +80,9 @@
'avb_boot_add_hash_footer_args':
('--prop com.android.build.boot.os_version:R '
'--prop com.android.build.boot.security_patch:2019-09-05'),
+ 'avb_init_boot_add_hash_footer_args':
+ ('--prop com.android.build.boot.os_version:R '
+ '--prop com.android.build.boot.security_patch:2019-09-05'),
'avb_system_add_hashtree_footer_args':
('--prop com.android.build.system.os_version:R '
'--prop com.android.build.system.security_patch:2019-09-05 '
diff --git a/tools/signapk/src/com/android/signapk/SignApk.java b/tools/signapk/src/com/android/signapk/SignApk.java
index 232e119..c127dbe 100644
--- a/tools/signapk/src/com/android/signapk/SignApk.java
+++ b/tools/signapk/src/com/android/signapk/SignApk.java
@@ -204,26 +204,23 @@
* If a console doesn't exist, reads the password from stdin
* If a console exists, reads the password from console and returns it as a string.
*
- * @param keyFile The file containing the private key. Used to prompt the user.
+ * @param keyFileName Name of the file containing the private key. Used to prompt the user.
*/
- private static String readPassword(File keyFile) {
+ private static char[] readPassword(String keyFileName) {
Console console;
- char[] pwd;
if ((console = System.console()) == null) {
- System.out.print("Enter password for " + keyFile + " (password will not be hidden): ");
+ System.out.print(
+ "Enter password for " + keyFileName + " (password will not be hidden): ");
System.out.flush();
BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
try {
- return stdin.readLine();
+ String result = stdin.readLine();
+ return result == null ? null : result.toCharArray();
} catch (IOException ex) {
return null;
}
} else {
- if ((pwd = console.readPassword("[%s]", "Enter password for " + keyFile)) != null) {
- return String.valueOf(pwd);
- } else {
- return null;
- }
+ return console.readPassword("[%s]", "Enter password for " + keyFileName);
}
}
@@ -246,11 +243,8 @@
return null;
}
- char[] password = readPassword(keyFile).toCharArray();
-
SecretKeyFactory skFactory = SecretKeyFactory.getInstance(epkInfo.getAlgName());
- Key key = skFactory.generateSecret(new PBEKeySpec(password));
-
+ Key key = skFactory.generateSecret(new PBEKeySpec(readPassword(keyFile.getPath())));
Cipher cipher = Cipher.getInstance(epkInfo.getAlgName());
cipher.init(Cipher.DECRYPT_MODE, key, epkInfo.getAlgParameters());
@@ -305,10 +299,10 @@
/** Get a PKCS#11 private key from keyStore */
private static PrivateKey loadPrivateKeyFromKeyStore(
- final KeyStore keyStore, final String keyName, final String password)
+ final KeyStore keyStore, final String keyName)
throws CertificateException, KeyStoreException, NoSuchAlgorithmException,
UnrecoverableKeyException, UnrecoverableEntryException {
- final Key key = keyStore.getKey(keyName, password == null ? null : password.toCharArray());
+ final Key key = keyStore.getKey(keyName, readPassword(keyName));
final PrivateKeyEntry privateKeyEntry = (PrivateKeyEntry) keyStore.getEntry(keyName, null);
if (privateKeyEntry == null) {
throw new Error(
@@ -1201,10 +1195,8 @@
if (keyStore == null) {
privateKey[i] = readPrivateKey(new File(args[argNum]));
} else {
- String[] splits = args[argNum].split(":", 2);
- final String keyAlias = splits[0];
- final String password = splits.length > 1 ? splits[1] : null;
- privateKey[i] = loadPrivateKeyFromKeyStore(keyStore, keyAlias, password);
+ final String keyAlias = args[argNum];
+ privateKey[i] = loadPrivateKeyFromKeyStore(keyStore, keyAlias);
}
}
inputJar = new JarFile(new File(inputFilename), false); // Don't verify.
diff --git a/tools/warn/html_writer.py b/tools/warn/html_writer.py
index ef173bc..3fa822a 100644
--- a/tools/warn/html_writer.py
+++ b/tools/warn/html_writer.py
@@ -63,6 +63,11 @@
from .severity import Severity
+# Report files with this number of warnings or more.
+LIMIT_WARNINGS_PER_FILE = 100
+# Report files/directories with this percentage of total warnings or more.
+LIMIT_PERCENT_WARNINGS = 1
+
HTML_HEAD_SCRIPTS = """\
<script type="text/javascript">
function expand(id) {
@@ -89,12 +94,13 @@
</script>
<style type="text/css">
th,td{border-collapse:collapse; border:1px solid black;}
- .button{color:blue;font-size:110%;font-weight:bolder;}
+ .button{color:blue;font-size:100%;font-weight:bolder;}
.bt{color:black;background-color:transparent;border:none;outline:none;
font-size:140%;font-weight:bolder;}
.c0{background-color:#e0e0e0;}
.c1{background-color:#d0d0d0;}
.t1{border-collapse:collapse; width:100%; border:1px solid black;}
+ .box{margin:5pt; padding:5pt; border:1px solid;}
</style>
<script src="https://www.gstatic.com/charts/loader.js"></script>
"""
@@ -287,14 +293,14 @@
# sort by project, severity, warn_id, warning_message
def emit_buttons(writer):
"""Write the button elements in HTML."""
- writer('<button class="button" onclick="expandCollapse(1);">'
+ writer('<p><button class="button" onclick="expandCollapse(1);">'
'Expand all warnings</button>\n'
'<button class="button" onclick="expandCollapse(0);">'
'Collapse all warnings</button>\n'
- '<button class="button" onclick="groupBySeverity();">'
+ '<p><button class="button" onclick="groupBySeverity();">'
'Group warnings by severity</button>\n'
'<button class="button" onclick="groupByProject();">'
- 'Group warnings by project</button><br>')
+ 'Group warnings by project</button>')
def all_patterns(category):
@@ -559,6 +565,11 @@
"""
+# Emit a JavaScript const number
+def emit_const_number(name, value, writer):
+ writer('const ' + name + ' = ' + str(value) + ';')
+
+
# Emit a JavaScript const string
def emit_const_string(name, value, writer):
writer('const ' + name + ' = "' + escape_string(value) + '";')
@@ -602,6 +613,8 @@
emit_const_string('FlagPlatform', flags.platform, writer)
emit_const_string('FlagURL', flags.url, writer)
emit_const_string('FlagSeparator', flags.separator, writer)
+ emit_const_number('LimitWarningsPerFile', LIMIT_WARNINGS_PER_FILE, writer)
+ emit_const_number('LimitPercentWarnings', LIMIT_PERCENT_WARNINGS, writer)
emit_const_string_array('SeverityColors', [s.color for s in Severity.levels],
writer)
emit_const_string_array('SeverityHeaders',
@@ -624,8 +637,8 @@
DRAW_TABLE_JAVASCRIPT = """
google.charts.load('current', {'packages':['table']});
-google.charts.setOnLoadCallback(drawTable);
-function drawTable() {
+google.charts.setOnLoadCallback(genTables);
+function genSelectedProjectsTable() {
var data = new google.visualization.DataTable();
data.addColumn('string', StatsHeader[0]);
for (var i=1; i<StatsHeader.length; i++) {
@@ -638,12 +651,167 @@
}
}
var table = new google.visualization.Table(
- document.getElementById('stats_table'));
+ document.getElementById('selected_projects_section'));
table.draw(data, {allowHtml: true, alternatingRowStyle: true});
}
+// Global TopDirs and TopFiles are computed later by genTables.
+window.TopDirs = [];
+window.TopFiles = [];
+function computeTopDirsFiles() {
+ var numWarnings = WarningMessages.length;
+ var warningsOfFiles = {};
+ var warningsOfDirs = {};
+ var subDirs = {};
+ function addOneWarning(map, key) {
+ map[key] = 1 + ((key in map) ? map[key] : 0);
+ }
+ for (var i = 0; i < numWarnings; i++) {
+ var file = WarningMessages[i].replace(/:.*/, "");
+ addOneWarning(warningsOfFiles, file);
+ var dirs = file.split("/");
+ var dir = dirs[0];
+ addOneWarning(warningsOfDirs, dir);
+ for (var d = 1; d < dirs.length - 1; d++) {
+ var subDir = dir + "/" + dirs[d];
+ if (!(dir in subDirs)) {
+ subDirs[dir] = {};
+ }
+ subDirs[dir][subDir] = 1;
+ dir = subDir;
+ addOneWarning(warningsOfDirs, dir);
+ }
+ }
+ var minDirWarnings = numWarnings*(LimitPercentWarnings/100);
+ var minFileWarnings = Math.min(LimitWarningsPerFile, minDirWarnings);
+ // Each row in TopDirs and TopFiles has
+ // [index, {v:<num_of_warnings>, f:<percent>}, file_or_dir_name]
+ function countWarnings(minWarnings, warningsOf, isDir) {
+ var rows = [];
+ for (var name in warningsOf) {
+ if (isDir && name in subDirs && Object.keys(subDirs[name]).length < 2) {
+ continue; // skip a directory if it has only one subdir
+ }
+ var count = warningsOf[name];
+ if (count >= minWarnings) {
+ name = isDir ? (name + "/...") : name;
+ var percent = (100*count/numWarnings).toFixed(1);
+ var countFormat = count + ' (' + percent + '%)';
+ rows.push([0, {v:count, f:countFormat}, name]);
+ }
+ }
+ rows.sort((a,b) => b[1].v - a[1].v);
+ for (var i=0; i<rows.length; i++) {
+ rows[i][0] = i;
+ }
+ return rows;
+ }
+ TopDirs = countWarnings(minDirWarnings, warningsOfDirs, true);
+ TopFiles = countWarnings(minFileWarnings, warningsOfFiles, false);
+}
+function genTopDirsFilesTables() {
+ computeTopDirsFiles();
+ function addTable(name, divName, rows, clickFunction) {
+ var data = new google.visualization.DataTable();
+ data.addColumn("number", "index"); // not shown in view
+ data.addColumn("number", "# of warnings");
+ data.addColumn("string", name);
+ data.addRows(rows);
+ var formatter = new google.visualization.PatternFormat(
+ '<p onclick="' + clickFunction + '({0})">{2}</p>');
+ formatter.format(data, [0, 1, 2], 2);
+ var view = new google.visualization.DataView(data);
+ view.setColumns([1,2]); // hide the index column
+ var table = new google.visualization.Table(
+ document.getElementById(divName));
+ table.draw(view, {allowHtml: true, alternatingRowStyle: true});
+ }
+ addTable("Directory", "top_dirs_table", TopDirs, "selectDir");
+ addTable("File", "top_files_table", TopFiles, "selectFile");
+}
+function selectDirFile(idx, rows, dirFile) {
+ if (rows.length <= idx) {
+ return;
+ }
+ var name = rows[idx][2];
+ var spanName = "selected_" + dirFile + "_name";
+ document.getElementById(spanName).innerHTML = name;
+ var divName = "selected_" + dirFile + "_warnings";
+ var numWarnings = rows[idx][1].v;
+ var prefix = name.replace(/\\.\\.\\.$/, "");
+ var data = new google.visualization.DataTable();
+ data.addColumn('string', numWarnings + ' warnings in ' + name);
+ var getWarningMessage = (FlagPlatform == "chrome")
+ ? ((x) => addURLToLine(WarningMessages[Warnings[x][2]],
+ WarningLinks[Warnings[x][3]]))
+ : ((x) => addURL(WarningMessages[Warnings[x][2]]));
+ for (var i = 0; i < Warnings.length; i++) {
+ if (WarningMessages[Warnings[i][2]].startsWith(prefix)) {
+ data.addRow([getWarningMessage(i)]);
+ }
+ }
+ var table = new google.visualization.Table(
+ document.getElementById(divName));
+ table.draw(data, {allowHtml: true, alternatingRowStyle: true});
+}
+function selectDir(idx) {
+ selectDirFile(idx, TopDirs, "directory")
+}
+function selectFile(idx) {
+ selectDirFile(idx, TopFiles, "file");
+}
+function genTables() {
+ genSelectedProjectsTable();
+ if (WarningMessages.length > 1) {
+ genTopDirsFilesTables();
+ }
+}
"""
+def dump_boxed_section(writer, func):
+ writer('<div class="box">')
+ func()
+ writer('</div>')
+
+
+def dump_section_header(writer, table_name, section_title):
+ writer('<h3><b><button id="' + table_name + '_mark" class="bt"\n' +
+ ' onclick="expand(\'' + table_name + '\');">⊕</button></b>\n' +
+ section_title + '</h3>')
+
+
+def dump_table_section(writer, table_name, section_title):
+ dump_section_header(writer, table_name, section_title)
+ writer('<div id="' + table_name + '" style="display:none;"></div>')
+
+
+def dump_dir_file_section(writer, dir_file, table_name, section_title):
+ section_name = 'top_' + dir_file + '_section'
+ dump_section_header(writer, section_name, section_title)
+ writer('<div id="' + section_name + '" style="display:none;">')
+ writer('<div id="' + table_name + '"></div>')
+ def subsection():
+ subsection_name = 'selected_' + dir_file + '_warnings'
+ subsection_title = ('Warnings in <span id="selected_' + dir_file +
+ '_name">(click a ' + dir_file +
+ ' in the above table)</span>')
+ dump_section_header(writer, subsection_name, subsection_title)
+ writer('<div id="' + subsection_name + '" style="display:none;"></div>')
+ dump_boxed_section(writer, subsection)
+ writer('</div>')
+
+
+# HTML output has the following major div elements:
+# selected_projects_section
+# top_directory_section
+# top_dirs_table
+# selected_directory_warnings
+# top_file_section
+# top_files_table
+# selected_file_warnings
+# all_warnings_section
+# warning_groups
+# fixed_warnings
def dump_html(flags, output_stream, warning_messages, warning_links,
warning_records, header_str, warn_patterns, project_names):
"""Dump the flags output to output_stream."""
@@ -651,20 +819,44 @@
dump_html_prologue('Warnings for ' + header_str, writer, warn_patterns,
project_names)
dump_stats(writer, warn_patterns)
- writer('<br><div id="stats_table"></div><br>')
- writer('\n<script>')
- emit_js_data(writer, flags, warning_messages, warning_links, warning_records,
- warn_patterns, project_names)
- writer(SCRIPTS_FOR_WARNING_GROUPS)
- writer('</script>')
- emit_buttons(writer)
- # Warning messages are grouped by severities or project names.
- writer('<br><div id="warning_groups"></div>')
- if flags.byproject:
- writer('<script>groupByProject();</script>')
- else:
- writer('<script>groupBySeverity();</script>')
- dump_fixed(writer, warn_patterns)
+ writer('<br><br>Press ⊕ to show section content,'
+ ' and ⊖ to hide the content.')
+ def section1():
+ dump_table_section(writer, 'selected_projects_section',
+ 'Number of warnings in preselected project directories')
+ def section2():
+ dump_dir_file_section(
+ writer, 'directory', 'top_dirs_table',
+ 'Directories with at least ' +
+ str(LIMIT_PERCENT_WARNINGS) + '% warnings')
+ def section3():
+ dump_dir_file_section(
+ writer, 'file', 'top_files_table',
+ 'Files with at least ' +
+ str(LIMIT_PERCENT_WARNINGS) + '% or ' +
+ str(LIMIT_WARNINGS_PER_FILE) + ' warnings')
+ def section4():
+ writer('<script>')
+ emit_js_data(writer, flags, warning_messages, warning_links,
+ warning_records, warn_patterns, project_names)
+ writer(SCRIPTS_FOR_WARNING_GROUPS)
+ writer('</script>')
+ dump_section_header(writer, 'all_warnings_section',
+ 'All warnings grouped by severities or projects')
+ writer('<div id="all_warnings_section" style="display:none;">')
+ emit_buttons(writer)
+ # Warning messages are grouped by severities or project names.
+ writer('<br><div id="warning_groups"></div>')
+ if flags.byproject:
+ writer('<script>groupByProject();</script>')
+ else:
+ writer('<script>groupBySeverity();</script>')
+ dump_fixed(writer, warn_patterns)
+ writer('</div>')
+ dump_boxed_section(writer, section1)
+ dump_boxed_section(writer, section2)
+ dump_boxed_section(writer, section3)
+ dump_boxed_section(writer, section4)
dump_html_epilogue(writer)
diff --git a/tools/zipalign/tests/src/align_test.cpp b/tools/zipalign/tests/src/align_test.cpp
index 96d4f73..ff45187 100644
--- a/tools/zipalign/tests/src/align_test.cpp
+++ b/tools/zipalign/tests/src/align_test.cpp
@@ -3,6 +3,7 @@
#include "ZipAlign.h"
+#include <filesystem>
#include <stdio.h>
#include <string>
@@ -16,9 +17,15 @@
return test_data_dir + filename;
}
+static std::string GetTempPath(const std::string& filename) {
+ std::filesystem::path temp_path = std::filesystem::path(testing::TempDir());
+ temp_path += filename;
+ return temp_path.string();
+}
+
TEST(Align, Unaligned) {
const std::string src = GetTestPath("unaligned.zip");
- const std::string dst = GetTestPath("unaligned_out.zip");
+ const std::string dst = GetTempPath("unaligned_out.zip");
int processed = process(src.c_str(), dst.c_str(), 4, true, false, 4096);
ASSERT_EQ(0, processed);
@@ -29,8 +36,8 @@
TEST(Align, DoubleAligment) {
const std::string src = GetTestPath("unaligned.zip");
- const std::string tmp = GetTestPath("da_aligned.zip");
- const std::string dst = GetTestPath("da_d_aligner.zip");
+ const std::string tmp = GetTempPath("da_aligned.zip");
+ const std::string dst = GetTempPath("da_d_aligner.zip");
int processed = process(src.c_str(), tmp.c_str(), 4, true, false, 4096);
ASSERT_EQ(0, processed);
@@ -60,7 +67,7 @@
// Directory.
TEST(Align, Holes) {
const std::string src = GetTestPath("holes.zip");
- const std::string dst = GetTestPath("holes_out.zip");
+ const std::string dst = GetTempPath("holes_out.zip");
int processed = process(src.c_str(), dst.c_str(), 4, true, false, 4096);
ASSERT_EQ(0, processed);
@@ -72,7 +79,7 @@
// Align a zip where LFH order and CD entries differ.
TEST(Align, DifferenteOrders) {
const std::string src = GetTestPath("diffOrders.zip");
- const std::string dst = GetTestPath("diffOrders_out.zip");
+ const std::string dst = GetTempPath("diffOrders_out.zip");
int processed = process(src.c_str(), dst.c_str(), 4, true, false, 4096);
ASSERT_EQ(0, processed);