Merge "Make host targets use non-repackaged targets"
diff --git a/Usage.txt b/Usage.txt
index 004210b..558329b 100644
--- a/Usage.txt
+++ b/Usage.txt
@@ -29,7 +29,7 @@
An alternative to setting $TARGET_PRODUCT and $TARGET_BUILD_VARIANT,
which you may see in build servers, is to execute:
- make PRODUCT-<product>-<variant>
+ m PRODUCT-<product>-<variant>
A target may be a file path. For example, out/host/linux-x86/bin/adb .
@@ -46,6 +46,17 @@
files named Android.bp
these files are defined in Blueprint syntax
+ During a build, a few log files are generated in ${OUT} (or ${DIST_DIR}/logs
+ for dist builds):
+
+ verbose.log.gz
+ every command run, along with its outputs. This is similar to the
+ previous `m showcommands` option.
+ error.log
+ list of actions that failed during the build, and their outputs.
+ soong.log
+ verbose debug information from soong_ui
+
For now, the full (extremely large) compiled list of targets can be found
(after running the build once), split among these two files:
@@ -57,8 +68,6 @@
tool here.
Targets that adjust an existing build:
- showcommands Display the individual commands run to implement
- the build
dist Copy into ${DIST_DIR} the portion of the build
that must be distributed
@@ -71,7 +80,7 @@
Variables can either be set in the surrounding shell environment or can be
passed as command-line arguments. For example:
export I_AM_A_SHELL_VAR=1
- I_AM_ANOTHER_SHELL_VAR=2 make droid I_AM_A_MAKE_VAR=3
+ I_AM_ANOTHER_SHELL_VAR=2 m droid I_AM_A_MAKE_VAR=3
Here are some common variables and their meanings:
TARGET_PRODUCT The <product> to build # as described above
TARGET_BUILD_VARIANT The <variant> to build # as described above
diff --git a/core/Makefile b/core/Makefile
index 33b697c..2820a71 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -39,7 +39,6 @@
$(if $(filter init%rc,$(notdir $(_dest)))$(filter %/etc/init,$(dir $(_dest))),\
$(eval $(call copy-init-script-file-checked,$(_src),$(_fulldest))),\
$(eval $(call copy-one-file,$(_src),$(_fulldest)))))) \
- $(eval ALL_DEFAULT_INSTALLED_MODULES += $(_fulldest)) \
$(eval unique_product_copy_files_destinations += $(_dest))))
# Dump a list of overriden (and ignored PRODUCT_COPY_FILES entries)
@@ -418,10 +417,17 @@
$(hide) echo ro.vendor.build.date=`$(DATE_FROM_FILE)`>>$@
$(hide) echo ro.vendor.build.date.utc=`$(DATE_FROM_FILE) +%s`>>$@
$(hide) echo ro.vendor.build.fingerprint="$(BUILD_FINGERPRINT_FROM_FILE)">>$@
+ $(hide) echo ro.vendor.build.security_patch="$(VENDOR_SECURITY_PATCH)">>$@
$(hide) echo ro.vendor.product.cpu.abilist="$(TARGET_CPU_ABI_LIST)">>$@
$(hide) echo ro.vendor.product.cpu.abilist32="$(TARGET_CPU_ABI_LIST_32_BIT)">>$@
$(hide) echo ro.vendor.product.cpu.abilist64="$(TARGET_CPU_ABI_LIST_64_BIT)">>$@
- $(hide) TARGET_DEVICE="$(TARGET_DEVICE)" \
+ $(hide) TARGET_BUILD_TYPE="$(TARGET_BUILD_VARIANT)" \
+ BUILD_ID="$(BUILD_ID)" \
+ BUILD_NUMBER="$(BUILD_NUMBER_FROM_FILE)" \
+ PLATFORM_VERSION="$(PLATFORM_VERSION)" \
+ PLATFORM_SDK_VERSION="$(PLATFORM_SDK_VERSION)" \
+ BUILD_VERSION_TAGS="$(BUILD_VERSION_TAGS)" \
+ TARGET_DEVICE="$(TARGET_DEVICE)" \
PRODUCT_NAME="$(TARGET_PRODUCT)" \
PRODUCT_BRAND="$(PRODUCT_BRAND)" \
PRODUCT_MODEL="$(PRODUCT_MODEL)" \
@@ -444,7 +450,7 @@
ALL_DEFAULT_INSTALLED_MODULES += $(INSTALLED_PRODUCT_BUILD_PROP_TARGET)
FINAL_PRODUCT_PROPERTIES += \
- $(call collapse-pairs, $(PRODUCT_PRODUCT_PROPERTIES))
+ $(call collapse-pairs, $(PRODUCT_PRODUCT_PROPERTIES) $(ADDITIONAL_PRODUCT_PROPERTIES))
FINAL_PRODUCT_PROPERTIES := $(call uniq-pairs-by-first-component, \
$(FINAL_PRODUCT_PROPERTIES),=)
@@ -467,6 +473,34 @@
# ----------------------------------------------------------------
# -----------------------------------------------------------------
+# product-services build.prop
+INSTALLED_PRODUCT_SERVICES_BUILD_PROP_TARGET := $(TARGET_OUT_PRODUCT_SERVICES)/build.prop
+ALL_DEFAULT_INSTALLED_MODULES += $(INSTALLED_PRODUCT_SERVICES_BUILD_PROP_TARGET)
+
+FINAL_PRODUCT_SERVICES_PROPERTIES += \
+ $(call collapse-pairs, $(PRODUCT_PRODUCT_SERVICES_PROPERTIES))
+FINAL_PRODUCT_SERVICES_PROPERTIES := $(call uniq-pairs-by-first-component, \
+ $(FINAL_PRODUCT_SERVICES_PROPERTIES),=)
+
+$(INSTALLED_PRODUCT_SERVICES_BUILD_PROP_TARGET):
+ @echo Target product-services buildinfo: $@
+ @mkdir -p $(dir $@)
+ $(hide) echo > $@
+ifdef BOARD_USES_PRODUCT_SERVICESIMAGE
+ $(hide) echo ro.product_services.build.date=`$(DATE_FROM_FILE)`>>$@
+ $(hide) echo ro.product_services.build.date.utc=`$(DATE_FROM_FILE) +%s`>>$@
+ $(hide) echo ro.product_services.build.fingerprint="$(BUILD_FINGERPRINT_FROM_FILE)">>$@
+endif # BOARD_USES_PRODUCT_SERVICESIMAGE
+ $(hide) echo "#" >> $@; \
+ echo "# ADDITIONAL PRODUCT_SERVICES PROPERTIES" >> $@; \
+ echo "#" >> $@;
+ $(hide) $(foreach line,$(FINAL_PRODUCT_SERVICES_PROPERTIES), \
+ echo "$(line)" >> $@;)
+ $(hide) build/make/tools/post_process_props.py $@
+
+# ----------------------------------------------------------------
+
+# -----------------------------------------------------------------
# sdk-build.prop
#
# There are certain things in build.prop that we don't want to
@@ -1101,7 +1135,7 @@
ifneq (true,$(TARGET_USERIMAGES_SPARSE_SQUASHFS_DISABLED))
INTERNAL_USERIMAGES_SPARSE_SQUASHFS_FLAG := -s
endif
-ifneq ($(filter $(BOARD_PRODUCTIMAGE_FILE_SYSTEM_TYPE) $(BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE) $(BOARD_SYSTEMIMAGE_FILE_SYSTEM_TYPE),squashfs),)
+ifneq ($(filter $(BOARD_PRODUCTIMAGE_FILE_SYSTEM_TYPE) $(BOARD_PRODUCT_SERVICESIMAGE_FILE_SYSTEM_TYPE) $(BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE) $(BOARD_SYSTEMIMAGE_FILE_SYSTEM_TYPE),squashfs),)
INTERNAL_USERIMAGES_DEPS += $(MAKE_SQUASHFS) $(MKSQUASHFSUSERIMG) $(IMG2SIMG)
endif
@@ -1123,7 +1157,7 @@
INTERNAL_USERIMAGES_DEPS += $(MKE2FS_CONF)
endif
-ifeq (true,$(USE_LOGICAL_PARTITIONS))
+ifeq (true,$(PRODUCT_USE_LOGICAL_PARTITIONS))
ifeq ($(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VERITY),true)
$(error vboot 1.0 doesn't support logical partition)
@@ -1132,10 +1166,10 @@
# TODO(b/80195851): Should not define BOARD_AVB_SYSTEM_KEY_PATH without
# BOARD_AVB_SYSTEM_DETACHED_VBMETA.
-endif # USE_LOGICAL_PARTITIONS
+endif # PRODUCT_USE_LOGICAL_PARTITIONS
# $(1): the path of the output dictionary file
-# $(2): a subset of "system vendor cache userdata product oem"
+# $(2): a subset of "system vendor cache userdata product product_services oem"
# $(3): additional "key=value" pairs to append to the dictionary file.
define generate-image-prop-dictionary
$(if $(filter $(2),system),\
@@ -1184,6 +1218,19 @@
$(if $(BOARD_PRODUCTIMAGE_SQUASHFS_BLOCK_SIZE),$(hide) echo "product_squashfs_block_size=$(BOARD_PRODUCTIMAGE_SQUASHFS_BLOCK_SIZE)" >> $(1))
$(if $(BOARD_PRODUCTIMAGE_SQUASHFS_DISABLE_4K_ALIGN),$(hide) echo "product_squashfs_disable_4k_align=$(BOARD_PRODUCTIMAGE_SQUASHFS_DISABLE_4K_ALIGN)" >> $(1))
$(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PRODUCT_BASE_FS_PATH),$(hide) echo "product_base_fs_file=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PRODUCT_BASE_FS_PATH)" >> $(1))
+ $(if $(BOARD_PRODUCTIMAGE_PARTITION_RESERVED_SIZE),$(hide) echo "product_reserved_size=$(BOARD_PRODUCTIMAGE_PARTITION_RESERVED_SIZE)" >> $(1))
+)
+$(if $(filter $(2),product_services),\
+ $(if $(BOARD_PRODUCT_SERVICESIMAGE_FILE_SYSTEM_TYPE),$(hide) echo "product_services_fs_type=$(BOARD_PRODUCT_SERVICESIMAGE_FILE_SYSTEM_TYPE)" >> $(1))
+ $(if $(BOARD_PRODUCT_SERVICESIMAGE_EXTFS_INODE_COUNT),$(hide) echo "product_services_extfs_inode_count=$(BOARD_PRODUCT_SERVICESIMAGE_EXTFS_INODE_COUNT)" >> $(1))
+ $(if $(BOARD_PRODUCT_SERVICESIMAGE_EXTFS_RSV_PCT),$(hide) echo "product_services_extfs_rsv_pct=$(BOARD_PRODUCT_SERVICESIMAGE_EXTFS_RSV_PCT)" >> $(1))
+ $(if $(BOARD_PRODUCT_SERVICESIMAGE_PARTITION_SIZE),$(hide) echo "product_services_size=$(BOARD_PRODUCT_SERVICESIMAGE_PARTITION_SIZE)" >> $(1))
+ $(if $(BOARD_PRODUCT_SERVICESIMAGE_JOURNAL_SIZE),$(hide) echo "product_services_journal_size=$(BOARD_PRODUCT_SERVICESIMAGE_JOURNAL_SIZE)" >> $(1))
+ $(if $(BOARD_PRODUCT_SERVICESIMAGE_SQUASHFS_COMPRESSOR),$(hide) echo "product_services_squashfs_compressor=$(BOARD_PRODUCT_SERVICESIMAGE_SQUASHFS_COMPRESSOR)" >> $(1))
+ $(if $(BOARD_PRODUCT_SERVICESIMAGE_SQUASHFS_COMPRESSOR_OPT),$(hide) echo "product_services_squashfs_compressor_opt=$(BOARD_PRODUCT_SERVICESIMAGE_SQUASHFS_COMPRESSOR_OPT)" >> $(1))
+ $(if $(BOARD_PRODUCT_SERVICESIMAGE_SQUASHFS_BLOCK_SIZE),$(hide) echo "product_services_squashfs_block_size=$(BOARD_PRODUCT_SERVICESIMAGE_SQUASHFS_BLOCK_SIZE)" >> $(1))
+ $(if $(BOARD_PRODUCT_SERVICESIMAGE_SQUASHFS_DISABLE_4K_ALIGN),$(hide) echo "product_services_squashfs_disable_4k_align=$(BOARD_PRODUCT_SERVICESIMAGE_SQUASHFS_DISABLE_4K_ALIGN)" >> $(1))
+ $(if $(BOARD_PRODUCT_SERVICESIMAGE_PARTITION_RESERVED_SIZE),$(hide) echo "product_services_reserved_size=$(BOARD_PRODUCT_SERVICESIMAGE_PARTITION_RESERVED_SIZE)" >> $(1))
)
$(if $(filter $(2),oem),\
$(if $(BOARD_OEMIMAGE_PARTITION_SIZE),$(hide) echo "oem_size=$(BOARD_OEMIMAGE_PARTITION_SIZE)" >> $(1))
@@ -1208,6 +1255,7 @@
$(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SYSTEM_VERITY_PARTITION),$(hide) echo "system_verity_block_device=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SYSTEM_VERITY_PARTITION)" >> $(1))
$(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VENDOR_VERITY_PARTITION),$(hide) echo "vendor_verity_block_device=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VENDOR_VERITY_PARTITION)" >> $(1))
$(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PRODUCT_VERITY_PARTITION),$(hide) echo "product_verity_block_device=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PRODUCT_VERITY_PARTITION)" >> $(1))
+$(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PRODUCT_SERVICES_VERITY_PARTITION),$(hide) echo "product_services_verity_block_device=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PRODUCT_SERVICES_VERITY_PARTITION)" >> $(1))
$(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VBOOT),$(hide) echo "vboot=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VBOOT)" >> $(1))
$(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VBOOT),$(hide) echo "vboot_key=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VBOOT_SIGNING_KEY)" >> $(1))
$(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VBOOT),$(hide) echo "vboot_subkey=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VBOOT_SIGNING_SUBKEY)" >> $(1))
@@ -1235,19 +1283,27 @@
$(hide) echo "avb_product_key_path=$(BOARD_AVB_PRODUCT_KEY_PATH)" >> $(1)
$(hide) echo "avb_product_algorithm=$(BOARD_AVB_PRODUCT_ALGORITHM)" >> $(1)
$(hide) echo "avb_product_rollback_index_location=$(BOARD_AVB_PRODUCT_ROLLBACK_INDEX_LOCATION)" >> $(1)))
+$(if $(BOARD_AVB_ENABLE),$(hide) echo "avb_product_services_hashtree_enable=$(BOARD_AVB_ENABLE)" >> $(1))
+$(if $(BOARD_AVB_ENABLE),\
+ $(hide) echo "avb_product_services_add_hashtree_footer_args=$(BOARD_AVB_PRODUCT_SERVICES_ADD_HASHTREE_FOOTER_ARGS)" >> $(1))
+$(if $(BOARD_AVB_ENABLE),\
+ $(if $(BOARD_AVB_PRODUCT_SERVICES_KEY_PATH),\
+ $(hide) echo "avb_product_services_key_path=$(BOARD_AVB_PRODUCT_SERVICES_KEY_PATH)" >> $(1)
+ $(hide) echo "avb_product_services_algorithm=$(BOARD_AVB_PRODUCT_SERVICES_ALGORITHM)" >> $(1)
+ $(hide) echo "avb_product_services_rollback_index_location=$(BOARD_AVB_PRODUCT_SERVICES_ROLLBACK_INDEX_LOCATION)" >> $(1)))
$(if $(filter true,$(BOARD_USES_RECOVERY_AS_BOOT)),\
$(hide) echo "recovery_as_boot=true" >> $(1))
$(if $(filter true,$(BOARD_BUILD_SYSTEM_ROOT_IMAGE)),\
$(hide) echo "system_root_image=true" >> $(1)
- $(hide) echo "ramdisk_dir=$(TARGET_ROOT_OUT)" >> $(1))
-$(if $(USE_LOGICAL_PARTITIONS),$(hide) echo "use_logical_partitions=true" >> $(1))
+ $(hide) echo "root_dir=$(TARGET_ROOT_OUT)" >> $(1))
+$(if $(PRODUCT_USE_DYNAMIC_PARTITION_SIZE),$(hide) echo "use_dynamic_partition_size=true" >> $(1))
$(if $(3),$(hide) $(foreach kv,$(3),echo "$(kv)" >> $(1);))
endef
# $(1): the path of the output dictionary file
# $(2): additional "key=value" pairs to append to the dictionary file.
define generate-userimage-prop-dictionary
-$(call generate-image-prop-dictionary,$(1),system vendor cache userdata product oem,$(2))
+$(call generate-image-prop-dictionary,$(1),system vendor cache userdata product product_services oem,$(2))
endef
# $(1): the path of the input dictionary file, where each line has the format key=value
@@ -1302,13 +1358,6 @@
recovery_kernel := $(INSTALLED_KERNEL_TARGET) # same as a non-recovery system
recovery_ramdisk := $(PRODUCT_OUT)/ramdisk-recovery.img
-recovery_build_props := $(intermediate_system_build_prop)
-ifdef property_overrides_split_enabled
-recovery_build_props += $(INSTALLED_VENDOR_BUILD_PROP_TARGET)
-endif
-ifdef BOARD_USES_PRODUCTIMAGE
-recovery_build_props += $(INSTALLED_PRODUCT_BUILD_PROP_TARGET)
-endif
recovery_resources_common := $(call include-path-for, recovery)/res
# Set recovery_density to the density bucket of the device.
@@ -1381,6 +1430,54 @@
RECOVERY_RESOURCE_ZIP :=
endif
+INSTALLED_RECOVERY_BUILD_PROP_TARGET := $(TARGET_RECOVERY_ROOT_OUT)/prop.default
+
+$(INSTALLED_RECOVERY_BUILD_PROP_TARGET): PRIVATE_RECOVERY_UI_PROPERTIES := \
+ TARGET_RECOVERY_DEFAULT_ROTATION:default_rotation \
+ TARGET_RECOVERY_OVERSCAN_PERCENT:overscan_percent \
+ TARGET_RECOVERY_PIXEL_FORMAT:pixel_format \
+ TARGET_RECOVERY_UI_ANIMATION_FPS:animation_fps \
+ TARGET_RECOVERY_UI_MARGIN_HEIGHT:margin_height \
+ TARGET_RECOVERY_UI_MARGIN_WIDTH:margin_width \
+ TARGET_RECOVERY_UI_MENU_UNUSABLE_ROWS:menu_unusable_rows \
+ TARGET_RECOVERY_UI_PROGRESS_BAR_BASELINE:progress_bar_baseline \
+ TARGET_RECOVERY_UI_TOUCH_LOW_THRESHOLD:touch_low_threshold \
+ TARGET_RECOVERY_UI_TOUCH_HIGH_THRESHOLD:touch_high_threshold \
+ TARGET_RECOVERY_UI_VR_STEREO_OFFSET:vr_stereo_offset
+
+# Parses the given list of build variables and writes their values as build properties if defined.
+# For example, if a target defines `TARGET_RECOVERY_UI_MARGIN_HEIGHT := 100`,
+# `ro.recovery.ui.margin_height=100` will be appended to the given output file.
+# $(1): Map from the build variable names to property names
+# $(2): Output file
+define append-recovery-ui-properties
+echo "#" >> $(2)
+echo "# RECOVERY UI BUILD PROPERTIES" >> $(2)
+echo "#" >> $(2)
+$(foreach prop,$(1), \
+ $(eval _varname := $(call word-colon,1,$(prop))) \
+ $(eval _propname := $(call word-colon,2,$(prop))) \
+ $(eval _value := $($(_varname))) \
+ $(if $(_value), \
+ echo ro.recovery.ui.$(_propname)=$(_value) >> $(2) &&)) true
+endef
+
+$(INSTALLED_RECOVERY_BUILD_PROP_TARGET): \
+ $(INSTALLED_DEFAULT_PROP_TARGET) \
+ $(INSTALLED_VENDOR_DEFAULT_PROP_TARGET) \
+ $(INSTALLED_VENDOR_BUILD_PROP_TARGET) \
+ $(INSTALLED_PRODUCT_BUILD_PROP_TARGET) \
+ $(INSTALLED_PRODUCT_SERVICES_BUILD_PROP_TARGET)
+ @echo "Target recovery buildinfo: $@
+ $(hide) mkdir -p $(dir $@)
+ $(hide) rm -f $@
+ $(hide) cat $(INSTALLED_DEFAULT_PROP_TARGET) > $@
+ $(hide) cat $(INSTALLED_VENDOR_DEFAULT_PROP_TARGET) >> $@
+ $(hide) cat $(INSTALLED_VENDOR_BUILD_PROP_TARGET) >> $@
+ $(hide) cat $(INSTALLED_PRODUCT_BUILD_PROP_TARGET) >> $@
+ $(hide) cat $(INSTALLED_PRODUCT_SERVICES_BUILD_PROP_TARGET) >> $@
+ $(call append-recovery-ui-properties,$(PRIVATE_RECOVERY_UI_PROPERTIES),$@)
+
INTERNAL_RECOVERYIMAGE_ARGS := \
$(addprefix --second ,$(INSTALLED_2NDBOOTLOADER_TARGET)) \
--kernel $(recovery_kernel) \
@@ -1446,13 +1543,6 @@
$(if $(strip $(recovery_wipe)), \
$(hide) cp -f $(recovery_wipe) $(TARGET_RECOVERY_ROOT_OUT)/etc/recovery.wipe)
$(hide) cp $(RECOVERY_INSTALL_OTA_KEYS) $(TARGET_RECOVERY_ROOT_OUT)/res/keys
- $(hide) cat $(INSTALLED_DEFAULT_PROP_TARGET) \
- > $(TARGET_RECOVERY_ROOT_OUT)/prop.default
- $(if $(INSTALLED_VENDOR_DEFAULT_PROP_TARGET), \
- $(hide) cat $(INSTALLED_VENDOR_DEFAULT_PROP_TARGET) \
- >> $(TARGET_RECOVERY_ROOT_OUT)/prop.default)
- $(hide) cat $(recovery_build_props) \
- >> $(TARGET_RECOVERY_ROOT_OUT)/prop.default
$(hide) ln -sf prop.default $(TARGET_RECOVERY_ROOT_OUT)/default.prop
$(BOARD_RECOVERY_IMAGE_PREPARE)
$(hide) $(MKBOOTFS) -d $(TARGET_OUT) $(TARGET_RECOVERY_ROOT_OUT) | $(MINIGZIP) > $(recovery_ramdisk)
@@ -1491,10 +1581,10 @@
$(INTERNAL_RECOVERYIMAGE_FILES) \
$(recovery_initrc) $(recovery_sepolicy) $(recovery_kernel) \
$(INSTALLED_2NDBOOTLOADER_TARGET) \
- $(recovery_build_props) $(recovery_resource_deps) \
+ $(INSTALLED_RECOVERY_BUILD_PROP_TARGET) \
+ $(recovery_resource_deps) \
$(recovery_fstab) \
$(RECOVERY_INSTALL_OTA_KEYS) \
- $(INSTALLED_VENDOR_DEFAULT_PROP_TARGET) \
$(BOARD_RECOVERY_KERNEL_MODULES) \
$(DEPMOD)
$(call pretty,"Target boot image from recovery: $@")
@@ -1507,10 +1597,10 @@
$(INTERNAL_RECOVERYIMAGE_FILES) \
$(recovery_initrc) $(recovery_sepolicy) $(recovery_kernel) \
$(INSTALLED_2NDBOOTLOADER_TARGET) \
- $(recovery_build_props) $(recovery_resource_deps) \
+ $(INSTALLED_RECOVERY_BUILD_PROP_TARGET) \
+ $(recovery_resource_deps) \
$(recovery_fstab) \
$(RECOVERY_INSTALL_OTA_KEYS) \
- $(INSTALLED_VENDOR_DEFAULT_PROP_TARGET) \
$(BOARD_RECOVERY_KERNEL_MODULES) \
$(DEPMOD)
$(call build-recoveryimage-target, $@)
@@ -1647,11 +1737,27 @@
endef
endif
+# Create symlink /system/product-services to /product-services if necessary.
+ifdef BOARD_USES_PRODUCT_SERVICESIMAGE
+define create-system-product-services-symlink
+$(hide) if [ -d $(TARGET_OUT)/product-services ] && [ ! -h $(TARGET_OUT)/product-services ]; then \
+ echo 'Non-symlink $(TARGET_OUT)/product-services detected!' 1>&2; \
+ echo 'You cannot install files to $(TARGET_OUT)/product-services while building a separate product-services.img!' 1>&2; \
+ exit 1; \
+fi
+$(hide) ln -sf /product-services $(TARGET_OUT)/product-services
+endef
+else
+define create-system-product-services-symlink
+endef
+endif
+
# $(1): output file
define build-systemimage-target
@echo "Target system fs image: $(1)"
$(call create-system-vendor-symlink)
$(call create-system-product-symlink)
+ $(call create-system-product-services-symlink)
@mkdir -p $(dir $(1)) $(systemimage_intermediates) && rm -rf $(systemimage_intermediates)/system_image_info.txt
$(call generate-image-prop-dictionary, $(systemimage_intermediates)/system_image_info.txt,system, \
skip_fsck=true)
@@ -1731,6 +1837,7 @@
$(call pretty,"Target system fs tarball: $(INSTALLED_SYSTEMTARBALL_TARGET)")
$(call create-system-vendor-symlink)
$(call create-system-product-symlink)
+ $(call create-system-product-services-symlink)
$(MKTARBALL) $(FS_GET_STATS) \
$(PRODUCT_OUT) system $(PRIVATE_SYSTEM_TAR) \
$(INSTALLED_SYSTEMTARBALL_TARGET) $(TARGET_OUT)
@@ -1815,6 +1922,10 @@
$(hide) cd $(dir $@) && zip -qryX $(notdir $@) \
$(TARGET_COPY_OUT_PRODUCT)
endif
+ifdef BOARD_PRODUCT_SERVICESIMAGE_FILE_SYSTEM_TYPE
+ $(hide) cd $(dir $@) && zip -qryX $(notdir $@) \
+ $(TARGET_COPY_OUT_PRODUCT_SERVICES)
+endif
ifneq ($(PDK_PLATFORM_JAVA_ZIP_CONTENTS),)
$(hide) cd $(OUT_DIR) && zip -qryX $(patsubst $(OUT_DIR)/%,%,$@) $(PDK_PLATFORM_JAVA_ZIP_CONTENTS)
endif
@@ -2196,8 +2307,11 @@
$(call generate-image-prop-dictionary, $(productimage_intermediates)/product_image_info.txt,product,skip_fsck=true)
$(hide) PATH=$(foreach p,$(INTERNAL_USERIMAGES_BINARY_PATHS),$(p):)$$PATH \
./build/tools/releasetools/build_image.py \
- $(TARGET_OUT_PRODUCT) $(productimage_intermediates)/product_image_info.txt $(INSTALLED_PRODUCTIMAGE_TARGET) $(TARGET_OUT)
- $(hide) $(call assert-max-image-size,$(INSTALLED_PRODUCTIMAGE_TARGET),$(BOARD_PRODUCTIMAGE_PARTITION_SIZE))
+ $(TARGET_OUT_PRODUCT) $(productimage_intermediates)/product_image_info.txt $(INSTALLED_PRODUCTIMAGE_TARGET) $(TARGET_OUT) \
+ $(productimage_intermediates)/generated_product_image_info.txt
+ $(hide) $(call assert-max-image-size,$(INSTALLED_PRODUCTIMAGE_TARGET),\
+ $(call read-image-prop-dictionary,\
+ $(productimage_intermediates)/generated_product_image_info.txt,product_size))
endef
# We just build this directly to the install location.
@@ -2217,6 +2331,61 @@
endif
# -----------------------------------------------------------------
+# product-services partition image
+ifdef BOARD_PRODUCT_SERVICESIMAGE_FILE_SYSTEM_TYPE
+INTERNAL_PRODUCT_SERVICESIMAGE_FILES := \
+ $(filter $(TARGET_OUT_PRODUCT_SERVICES)/%,\
+ $(ALL_DEFAULT_INSTALLED_MODULES)\
+ $(ALL_PDK_FUSION_FILES)) \
+ $(PDK_FUSION_SYMLINK_STAMP)
+
+# platform.zip depends on $(INTERNAL_PRODUCT_SERVICESIMAGE_FILES).
+$(INSTALLED_PLATFORM_ZIP) : $(INTERNAL_PRODUCT_SERVICESIMAGE_FILES)
+
+INSTALLED_FILES_FILE_PRODUCT_SERVICES := $(PRODUCT_OUT)/installed-files-product-services.txt
+INSTALLED_FILES_JSON_PRODUCT_SERVICES := $(INSTALLED_FILES_FILE_PRODUCT_SERVICES:.txt=.json)
+$(INSTALLED_FILES_FILE_PRODUCT_SERVICES): .KATI_IMPLICIT_OUTPUTS := $(INSTALLED_FILES_JSON_PRODUCT_SERVICES)
+$(INSTALLED_FILES_FILE_PRODUCT_SERVICES) : $(INTERNAL_PRODUCT_SERVICESIMAGE_FILES) $(FILESLIST)
+ @echo Installed file list: $@
+ @mkdir -p $(dir $@)
+ @rm -f $@
+ $(hide) $(FILESLIST) $(TARGET_OUT_PRODUCT_SERVICES) > $(@:.txt=.json)
+ $(hide) build/tools/fileslist_util.py -c $(@:.txt=.json) > $@
+
+product_servicesimage_intermediates := \
+ $(call intermediates-dir-for,PACKAGING,product_services)
+BUILT_PRODUCT_SERVICESIMAGE_TARGET := $(PRODUCT_OUT)/product-services.img
+define build-product-servicesimage-target
+ $(call pretty,"Target product-services fs image: $(INSTALLED_PRODUCT_SERVICESIMAGE_TARGET)")
+ @mkdir -p $(TARGET_OUT_PRODUCT_SERVICES)
+ @mkdir -p $(product_servicesimage_intermediates) && rm -rf $(product_servicesimage_intermediates)/product_services_image_info.txt
+ $(call generate-image-prop-dictionary, $(product_servicesimage_intermediates)/product_services_image_info.txt,product_services, skip_fsck=true)
+ $(hide) PATH=$(foreach p,$(INTERNAL_USERIMAGES_BINARY_PATHS),$(p):)$$PATH \
+ ./build/tools/releasetools/build_image.py \
+ $(TARGET_OUT_PRODUCT_SERVICES) $(product_servicesimage_intermediates)/product_services_image_info.txt $(INSTALLED_PRODUCT_SERVICESIMAGE_TARGET) $(TARGET_OUT) \
+ $(product_servicesimage_intermediates)/generated_product_services_image_info.txt
+ $(hide) $(call assert-max-image-size,$(INSTALLED_PRODUCT_SERVICESIMAGE_TARGET),\
+ $(call read-image-prop-dictionary,\
+ $(product_servicesimage_intermediates)/generated_product_services_image_info.txt,product_services_size))
+endef
+
+# We just build this directly to the install location.
+INSTALLED_PRODUCT_SERVICESIMAGE_TARGET := $(BUILT_PRODUCT_SERVICESIMAGE_TARGET)
+$(INSTALLED_PRODUCT_SERVICESIMAGE_TARGET): $(INTERNAL_USERIMAGES_DEPS) $(INTERNAL_PRODUCT_SERVICESIMAGE_FILES) $(INSTALLED_FILES_FILE_PRODUCT_SERVICES) $(BUILD_IMAGE_SRCS)
+ $(build-product-servicesimage-target)
+
+.PHONY: productservicesimage-nodeps psnod
+productservicesimage-nodeps psnod: | $(INTERNAL_USERIMAGES_DEPS)
+ $(build-product-servicesimage-target)
+
+sync: $(INTERNAL_PRODUCT_SERVICESIMAGE_FILES)
+
+else ifdef BOARD_PREBUILT_PRODUCT_SERVICESIMAGE
+INSTALLED_PRODUCT_SERVICESIMAGE_TARGET := $(PRODUCT_OUT)/product-services.img
+$(eval $(call copy-one-file,$(BOARD_PREBUILT_PRODUCT_SERVICESIMAGE),$(INSTALLED_PRODUCT_SERVICESIMAGE_TARGET)))
+endif
+
+# -----------------------------------------------------------------
# dtbo image
ifdef BOARD_PREBUILT_DTBOIMAGE
INSTALLED_DTBOIMAGE_TARGET := $(PRODUCT_OUT)/dtbo.img
@@ -2260,6 +2429,7 @@
VENDOR_FOOTER_ARGS := BOARD_AVB_VENDOR_ADD_HASHTREE_FOOTER_ARGS
RECOVERY_FOOTER_ARGS := BOARD_AVB_RECOVERY_ADD_HASH_FOOTER_ARGS
PRODUCT_FOOTER_ARGS := BOARD_AVB_PRODUCT_ADD_HASHTREE_FOOTER_ARGS
+PRODUCT_SERVICES_FOOTER_ARGS := BOARD_AVB_PRODUCT_SERVICES_ADD_HASHTREE_FOOTER_ARGS
# Check and set required build variables for a chain partition.
# $(1): the partition to enable AVB chain, e.g., BOOT or SYSTEM.
@@ -2377,6 +2547,9 @@
$(if $(BOARD_AVB_PRODUCT_KEY_PATH),\
$(hide) $(AVBTOOL) extract_public_key --key $(BOARD_AVB_PRODUCT_KEY_PATH) \
--output $(1)/product.avbpubkey)
+ $(if $(BOARD_AVB_PRODUCT_SERVICES_KEY_PATH),\
+ $(hide) $(AVBTOOL) extract_public_key --key $(BOARD_AVB_PRODUCT_SERVICES_KEY_PATH) \
+ --output $(1)/product-services.avbpubkey)
$(if $(BOARD_AVB_DTBO_KEY_PATH),\
$(hide) $(AVBTOOL) extract_public_key --key $(BOARD_AVB_DTBO_KEY_PATH) \
--output $(1)/dtbo.avbpubkey)
@@ -2404,6 +2577,7 @@
$(INSTALLED_SYSTEMIMAGE) \
$(INSTALLED_VENDORIMAGE_TARGET) \
$(INSTALLED_PRODUCTIMAGE_TARGET) \
+ $(INSTALLED_PRODUCT_SERVICESIMAGE_TARGET) \
$(INSTALLED_DTBOIMAGE_TARGET) \
$(INSTALLED_RECOVERYIMAGE_TARGET) \
$(BOARD_AVB_KEY_PATH)
@@ -2424,6 +2598,97 @@
endif # BOARD_AVB_ENABLE
# -----------------------------------------------------------------
+# super partition image
+
+# (1): list of items like "system", "vendor", "product", "product_services"
+# return: map each item to the corresponding image target.
+# system => $(BUILT_SYSTEMIMAGE), vendor => $(INSTALLED_VENDORIMAGE_TARGET), etc.
+define image-for-partitions
+$(foreach item,$(1),$(or $(strip $(foreach mapping,
+ system:$(BUILT_SYSTEMIMAGE)
+ product_services:$(INSTALLED_PRODUCT_SERVICESIMAGE_TARGET),
+ $(if $(filter $(call word-colon,1,$(mapping)),$(item)),
+ $(patsubst $(call word-colon,1,$(mapping)),$(call word-colon,2,$(mapping)),$(item))))),
+ $(INSTALLED_$(call to-upper,$(item)IMAGE_TARGET))))
+endef
+
+# (1): list of items like "system", "vendor", "product", "product_services"
+# return: map each item into a command ( wrapped in $$() ) that reads the size
+define read-size-of-partitions
+$(foreach p,$(1),$(call read-image-prop-dictionary,$($(p)image_intermediates)/generated_$(p)_image_info.txt,$(p)_size))
+endef
+
+ifeq (true,$(PRODUCT_BUILD_SUPER_PARTITION))
+
+# BOARD_SUPER_PARTITION_SIZE must be defined to build super image.
+ifdef BOARD_SUPER_PARTITION_SIZE
+
+INSTALLED_SUPERIMAGE_TARGET := $(PRODUCT_OUT)/super.img
+$(INSTALLED_SUPERIMAGE_TARGET): $(call image-for-partitions,$(BOARD_SUPER_PARTITION_PARTITION_LIST))
+
+# For A/B devices, super partition always contains sub-partitions in the _a slot, because this
+# image should only be used for bootstrapping / initializing the device. When flashing the image,
+# bootloader fastboot should always mark _a slot as bootable.
+ifeq ($(AB_OTA_UPDATER),true)
+$(INSTALLED_SUPERIMAGE_TARGET): PRIVATE_PARTITION_SUFFIX=_a
+$(INSTALLED_SUPERIMAGE_TARGET): PRIVATE_METADATA_SLOTS=2
+else
+$(INSTALLED_SUPERIMAGE_TARGET): PRIVATE_METADATA_SLOTS=1
+endif # AB_OTA_UPDATER
+
+
+$(INSTALLED_SUPERIMAGE_TARGET): $(HOST_OUT_EXECUTABLES)/lpmake
+ $< \
+ --sparse \
+ --metadata-size 65536 \
+ --metadata-slots $(PRIVATE_METADATA_SLOTS) \
+ --device-size $(BOARD_SUPER_PARTITION_SIZE) \
+ --output $@ \
+ $(foreach name,$(BOARD_SUPER_PARTITION_PARTITION_LIST), \
+ --partition $(name)$(PRIVATE_PARTITION_SUFFIX):$$($(UUIDGEN) $(name)$(PRIVATE_PARTITION_SUFFIX)):readonly:$(call read-size-of-partitions,$(name)) \
+ --image $(name)$(PRIVATE_PARTITION_SUFFIX)=$(call image-for-partitions,$(name)))
+
+$(call dist-for-goals,dist_files,$(INSTALLED_SUPERIMAGE_TARGET))
+
+endif # BOARD_SUPER_PARTITION_SIZE
+endif # PRODUCT_BUILD_SUPER_PARTITION
+
+# -----------------------------------------------------------------
+# Check image sizes <= size of super partition
+
+ifeq (,$(TARGET_BUILD_APPS))
+# Do not check for apps-only build
+
+ifeq (true,$(PRODUCT_BUILD_SUPER_PARTITION))
+ifdef BOARD_SUPER_PARTITION_SIZE
+ifdef BOARD_SUPER_PARTITION_PARTITION_LIST
+
+droid_targets: check_android_partition_sizes
+
+.PHONY: check_android_partition_sizes
+
+# Add image dependencies so that generated_*_image_info.txt are written before checking.
+check_android_partition_sizes: $(call image-for-partitions,$(BOARD_SUPER_PARTITION_PARTITION_LIST))
+
+check_android_partition_sizes:
+ partition_size_list="$(call read-size-of-partitions,$(BOARD_SUPER_PARTITION_PARTITION_LIST))"; \
+ sum_sizes_expr=$$(sed -e 's/ /+/g' <<< "$${partition_size_list}"); \
+ if [ $$(( $${sum_sizes_expr} )) -gt $(BOARD_SUPER_PARTITION_SIZE) ]; then \
+ echo 'The sum of sizes of all logical partitions is larger than BOARD_SUPER_PARTITION_SIZE.'; \
+ echo $${sum_sizes_expr} '==' $$(( $${sum_sizes_expr} )) '>' $(BOARD_SUPER_PARTITION_SIZE); \
+ exit 1; \
+ else \
+ echo 'The sum of sizes of all logical partitions is within BOARD_SUPER_PARTITION_SIZE:' \
+ $${sum_sizes_expr} '==' $$(( $${sum_sizes_expr} )) '<=' $(BOARD_SUPER_PARTITION_SIZE); \
+ fi
+
+endif # BOARD_SUPER_PARTITION_PARTITION_LIST
+endif # BOARD_SUPER_PARTITION_SIZE
+endif # PRODUCT_BUILD_SUPER_PARTITION
+
+endif # TARGET_BUILD_APPS
+
+# -----------------------------------------------------------------
# bring in the installer image generation defines if necessary
ifeq ($(TARGET_USE_DISKINSTALLER),true)
include bootable/diskinstaller/config.mk
@@ -2665,6 +2930,7 @@
$(INSTALLED_CACHEIMAGE_TARGET) \
$(INSTALLED_VENDORIMAGE_TARGET) \
$(INSTALLED_PRODUCTIMAGE_TARGET) \
+ $(INSTALLED_PRODUCT_SERVICESIMAGE_TARGET) \
$(INSTALLED_VBMETAIMAGE_TARGET) \
$(INSTALLED_DTBOIMAGE_TARGET) \
$(INTERNAL_SYSTEMOTHERIMAGE_FILES) \
@@ -2674,6 +2940,7 @@
$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SYSTEM_BASE_FS_PATH) \
$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VENDOR_BASE_FS_PATH) \
$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PRODUCT_BASE_FS_PATH) \
+ $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PRODUCT_SERVICES_BASE_FS_PATH) \
$(SELINUX_FC) \
$(APKCERTS_FILE) \
$(SOONG_ZIP) \
@@ -2689,6 +2956,7 @@
@echo "Package target files: $@"
$(call create-system-vendor-symlink)
$(call create-system-product-symlink)
+ $(call create-system-product-services-symlink)
$(hide) rm -rf $@ $@.list $(zip_root)
$(hide) mkdir -p $(dir $@) $(zip_root)
ifneq (,$(INSTALLED_RECOVERYIMAGE_TARGET)$(filter true,$(BOARD_USES_RECOVERY_AS_BOOT)))
@@ -2762,6 +3030,11 @@
$(hide) $(call package_files-copy-root, \
$(TARGET_OUT_PRODUCT),$(zip_root)/PRODUCT)
endif
+ifdef BOARD_PRODUCT_SERVICESIMAGE_FILE_SYSTEM_TYPE
+ @# Contents of the product-services image
+ $(hide) $(call package_files-copy-root, \
+ $(TARGET_OUT_PRODUCT_SERVICES),$(zip_root)/PRODUCT-SERVICES)
+endif
ifdef INSTALLED_SYSTEMOTHERIMAGE_TARGET
@# Contents of the system_other image
$(hide) $(call package_files-copy-root, \
@@ -2833,6 +3106,10 @@
$(hide) cp $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PRODUCT_BASE_FS_PATH) \
$(zip_root)/META/$(notdir $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PRODUCT_BASE_FS_PATH))
endif
+ifneq ($(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PRODUCT_SERVICES_BASE_FS_PATH),)
+ $(hide) cp $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PRODUCT_SERVICES_BASE_FS_PATH) \
+ $(zip_root)/META/$(notdir $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PRODUCT_SERVICES_BASE_FS_PATH))
+endif
ifneq ($(strip $(SANITIZE_TARGET)),)
# We need to create userdata.img with real data because the instrumented libraries are in userdata.img.
$(hide) echo "userdata_img_with_data=true" >> $(zip_root)/META/misc_info.txt
@@ -2909,6 +3186,10 @@
$(hide) mkdir -p $(zip_root)/IMAGES
$(hide) cp $(INSTALLED_PRODUCTIMAGE_TARGET) $(zip_root)/IMAGES/
endif
+ifdef BOARD_PREBUILT_PRODUCT_SERVICESIMAGE
+ $(hide) mkdir -p $(zip_root)/IMAGES
+ $(hide) cp $(INSTALLED_PRODUCT_SERVICESIMAGE_TARGET) $(zip_root)/IMAGES/
+endif
ifdef BOARD_PREBUILT_BOOTIMAGE
$(hide) mkdir -p $(zip_root)/IMAGES
$(hide) cp $(INSTALLED_BOOTIMAGE_TARGET) $(zip_root)/IMAGES/
@@ -2942,6 +3223,9 @@
ifdef BOARD_PRODUCTIMAGE_FILE_SYSTEM_TYPE
$(hide) $(call fs_config,$(zip_root)/PRODUCT,product/) > $(zip_root)/META/product_filesystem_config.txt
endif
+ifdef BOARD_PRODUCT_SERVICESIMAGE_FILE_SYSTEM_TYPE
+ $(hide) $(call fs_config,$(zip_root)/PRODUCT_SERVICES,product-services/) > $(zip_root)/META/product_services_filesystem_config.txt
+endif
ifeq ($(BOARD_BUILD_SYSTEM_ROOT_IMAGE),true)
@# When using BOARD_BUILD_SYSTEM_ROOT_IMAGE, ROOT always contains the files for the root under
@# normal boot. BOOT/RAMDISK exists only if additionally using BOARD_USES_RECOVERY_AS_BOOT.
@@ -3049,6 +3333,27 @@
updatepackage: $(INTERNAL_UPDATE_PACKAGE_TARGET)
# -----------------------------------------------------------------
+# A zip of the appcompat directory containing logs
+APPCOMPAT_ZIP := $(PRODUCT_OUT)/appcompat.zip
+# For apps_only build we'll establish the dependency later in build/make/core/main.mk.
+ifndef TARGET_BUILD_APPS
+$(APPCOMPAT_ZIP): $(INSTALLED_SYSTEMIMAGE) \
+ $(INSTALLED_BOOTIMAGE_TARGET) \
+ $(INSTALLED_USERDATAIMAGE_TARGET) \
+ $(INSTALLED_VENDORIMAGE_TARGET) \
+ $(INSTALLED_PRODUCTIMAGE_TARGET) \
+ $(INSTALLED_PRODUCT_SERVICESIMAGE_TARGET)
+endif
+$(APPCOMPAT_ZIP): PRIVATE_LIST_FILE := $(call intermediates-dir-for,PACKAGING,appcompat)/filelist
+$(APPCOMPAT_ZIP): $(SOONG_ZIP)
+ @echo "appcompat logs: $@"
+ $(hide) rm -rf $@ $(PRIVATE_LIST_FILE)
+ $(hide) mkdir -p $(dir $@) $(PRODUCT_OUT)/appcompat $(dir $(PRIVATE_LIST_FILE))
+ $(hide) find $(PRODUCT_OUT)/appcompat | sort >$(PRIVATE_LIST_FILE)
+ $(hide) $(SOONG_ZIP) -d -o $@ -C $(PRODUCT_OUT)/appcompat -l $(PRIVATE_LIST_FILE)
+
+
+# -----------------------------------------------------------------
# A zip of the symbols directory. Keep the full paths to make it
# more obvious where these files came from.
#
@@ -3066,6 +3371,7 @@
$(INSTALLED_USERDATAIMAGE_TARGET) \
$(INSTALLED_VENDORIMAGE_TARGET) \
$(INSTALLED_PRODUCTIMAGE_TARGET) \
+ $(INSTALLED_PRODUCT_SERVICESIMAGE_TARGET) \
$(updater_dep)
endif
$(SYMBOLS_ZIP): PRIVATE_LIST_FILE := $(call intermediates-dir-for,PACKAGING,symbols)/filelist
@@ -3089,7 +3395,8 @@
$(INSTALLED_BOOTIMAGE_TARGET) \
$(INSTALLED_USERDATAIMAGE_TARGET) \
$(INSTALLED_VENDORIMAGE_TARGET) \
- $(INSTALLED_PRODUCTIMAGE_TARGET)
+ $(INSTALLED_PRODUCTIMAGE_TARGET) \
+ $(INSTALLED_PRODUCT_SERVICESIMAGE_TARGET)
endif
$(COVERAGE_ZIP): PRIVATE_LIST_FILE := $(call intermediates-dir-for,PACKAGING,coverage)/filelist
$(COVERAGE_ZIP): $(SOONG_ZIP)
@@ -3198,6 +3505,15 @@
productimage: $(INSTALLED_QEMU_PRODUCTIMAGE)
droidcore: $(INSTALLED_QEMU_PRODUCTIMAGE)
endif
+ifeq ($(BOARD_USES_PRODUCT_SERVICESIMAGE),true)
+INSTALLED_QEMU_PRODUCT_SERVICESIMAGE := $(PRODUCT_OUT)/product-services-qemu.img
+$(INSTALLED_QEMU_PRODUCT_SERVICESIMAGE): $(INSTALLED_PRODUCT_SERVICESIMAGE_TARGET) $(MK_QEMU_IMAGE_SH) $(SGDISK_HOST)
+ @echo Create product-services-qemu.img
+ (export SGDISK=$(SGDISK_HOST); $(MK_QEMU_IMAGE_SH) ${PRODUCT_OUT}/product-services.img)
+
+productservicesimage: $(INSTALLED_QEMU_PRODUCT_SERVICESIMAGE)
+droidcore: $(INSTALLED_QEMU_PRODUCT_SERVICESIMAGE)
+endif
endif
# -----------------------------------------------------------------
# The emulator package
@@ -3261,6 +3577,7 @@
$(ALL_DEFAULT_INSTALLED_MODULES) \
$(INSTALLED_RAMDISK_TARGET) \
$(ALL_DOCS) \
+ $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/metalava-api-stubs-docs_annotations.zip \
$(ALL_SDK_FILES)
endif
@@ -3293,6 +3610,7 @@
$(OUT_DOCS)/offline-sdk-timestamp \
$(SYMBOLS_ZIP) \
$(COVERAGE_ZIP) \
+ $(APPCOMPAT_ZIP) \
$(INSTALLED_SYSTEMIMAGE) \
$(INSTALLED_QEMU_SYSTEMIMAGE) \
$(INSTALLED_QEMU_VENDORIMAGE) \
@@ -3409,4 +3727,4 @@
# Find lsdump paths
FIND_LSDUMPS_FILE := $(PRODUCT_OUT)/lsdump_paths.txt
$(FIND_LSDUMPS_FILE) : $(LSDUMP_PATHS)
- $(hide) rm -rf $@ && echo "$^" > $@
+ $(hide) rm -rf $@ && echo "$^" | sed -e 's/ /\n/g' > $@
diff --git a/core/android_manifest.mk b/core/android_manifest.mk
index 517379a..13da10c 100644
--- a/core/android_manifest.mk
+++ b/core/android_manifest.mk
@@ -38,28 +38,36 @@
$(full_android_manifest): PRIVATE_MIN_SDK_VERSION := $(DEFAULT_APP_TARGET_SDK)
endif
-# Set up rules to merge library manifest files
-my_exported_sdk_libs_file := $(call local-intermediates-dir,COMMON)/exported-sdk-libs
-$(full_android_manifest): PRIVATE_EXPORTED_SDK_LIBS_FILE := $(my_exported_sdk_libs_file)
-$(full_android_manifest): $(my_exported_sdk_libs_file)
-$(full_android_manifest): $(MANIFEST_FIXER)
-
ifneq (,$(strip $(my_full_libs_manifest_files)))
+ # Set up rules to merge library manifest files
+ fixed_android_manifest := $(intermediates.COMMON)/manifest/AndroidManifest.xml.fixed
-$(full_android_manifest): PRIVATE_LIBS_MANIFESTS := $(my_full_libs_manifest_files)
-$(full_android_manifest): $(ANDROID_MANIFEST_MERGER_DEPS)
-$(full_android_manifest) : $(main_android_manifest) $(my_full_libs_manifest_files)
+ $(full_android_manifest): PRIVATE_LIBS_MANIFESTS := $(my_full_libs_manifest_files)
+ $(full_android_manifest): $(ANDROID_MANIFEST_MERGER_DEPS)
+ $(full_android_manifest) : $(fixed_android_manifest) $(my_full_libs_manifest_files)
@echo "Merge android manifest files: $@ <-- $< $(PRIVATE_LIBS_MANIFESTS)"
@mkdir -p $(dir $@)
- $(call fix-manifest,$<,$@.tmp,$(PRIVATE_MIN_SDK_VERSION),$(PRIVATE_EXPORTED_SDK_LIBS_FILE))
- $(hide) $(ANDROID_MANIFEST_MERGER) --main $@.tmp \
+ $(hide) $(ANDROID_MANIFEST_MERGER) --main $< \
--libs $(call normalize-path-list,$(PRIVATE_LIBS_MANIFESTS)) \
--out $@
- rm $@.tmp
-
else
-$(full_android_manifest): $(main_android_manifest)
- @echo "Fix manifest: $@"
- $(call fix-manifest,$<,$@,$(PRIVATE_MIN_SDK_VERSION),$(PRIVATE_EXPORTED_SDK_LIBS_FILE))
-
+ fixed_android_manifest := $(full_android_manifest)
endif
+
+my_exported_sdk_libs_file := $(call local-intermediates-dir,COMMON)/exported-sdk-libs
+$(fixed_android_manifest): PRIVATE_EXPORTED_SDK_LIBS_FILE := $(my_exported_sdk_libs_file)
+$(fixed_android_manifest): $(my_exported_sdk_libs_file)
+
+$(fixed_android_manifest): PRIVATE_MANIFEST_FIXER_FLAGS :=
+ifneq ($(LOCAL_MODULE_CLASS),APPS)
+$(fixed_android_manifest): PRIVATE_MANIFEST_FIXER_FLAGS := --library
+endif
+$(fixed_android_manifest): $(MANIFEST_FIXER)
+$(fixed_android_manifest): $(main_android_manifest)
+ @echo "Fix manifest: $@"
+ $(MANIFEST_FIXER) \
+ --minSdkVersion $(PRIVATE_MIN_SDK_VERSION) \
+ $(PRIVATE_MANIFEST_FIXER_FLAGS) \
+ $(if (PRIVATE_EXPORTED_SDK_LIBS_FILE),\
+ $$(cat $(PRIVATE_EXPORTED_SDK_LIBS_FILE) | sort -u | sed -e 's/^/\ --uses-library\ /' | tr '\n' ' ')) \
+ $< $@
diff --git a/core/autogen_test_config.mk b/core/autogen_test_config.mk
index 5feec2b..bf87c9d 100644
--- a/core/autogen_test_config.mk
+++ b/core/autogen_test_config.mk
@@ -29,9 +29,10 @@
autogen_test_config_template := $(NATIVE_TEST_CONFIG_TEMPLATE)
endif
# Auto generating test config file for native test
+$(autogen_test_config_file): PRIVATE_MODULE_NAME := $(LOCAL_MODULE)
$(autogen_test_config_file) : $(autogen_test_config_template)
@echo "Auto generating test config $(notdir $@)"
- $(hide) sed 's&{MODULE}&$(PRIVATE_MODULE)&g' $< > $@
+ $(hide) sed 's&{MODULE}&$(PRIVATE_MODULE_NAME)&g' $< > $@
my_auto_generate_config := true
else
# Auto generating test config file for instrumentation test
@@ -52,6 +53,7 @@
LOCAL_INTERMEDIATE_TARGETS += $(autogen_test_config_file)
$(LOCAL_BUILT_MODULE): $(autogen_test_config_file)
ALL_MODULES.$(my_register_name).auto_test_config := true
+ $(my_prefix)$(LOCAL_MODULE_CLASS)_$(LOCAL_MODULE)_autogen := true
else
autogen_test_config_file :=
endif
diff --git a/core/base_rules.mk b/core/base_rules.mk
index f59df3f..770a16c 100644
--- a/core/base_rules.mk
+++ b/core/base_rules.mk
@@ -75,6 +75,8 @@
LOCAL_ODM_MODULE := true
else ifneq ($(filter $(TARGET_OUT_PRODUCT)/%,$(_path)),)
LOCAL_PRODUCT_MODULE := true
+else ifneq ($(filter $(TARGET_OUT_PRODUCT_SERVICES)/%,$(_path)),)
+LOCAL_PRODUCT_SERVICES_MODULE := true
endif
_path :=
@@ -205,6 +207,8 @@
partition_tag := _ODM
else ifeq (true,$(LOCAL_PRODUCT_MODULE))
partition_tag := _PRODUCT
+else ifeq (true,$(LOCAL_PRODUCT_SERVICES_MODULE))
+ partition_tag := _PRODUCT_SERVICES
else ifeq (NATIVE_TESTS,$(LOCAL_MODULE_CLASS))
partition_tag := _DATA
else
@@ -352,6 +356,7 @@
## make clean- targets
###########################################################
cleantarget := clean-$(my_register_name)
+.PHONY: $(cleantarget)
$(cleantarget) : PRIVATE_MODULE := $(my_register_name)
$(cleantarget) : PRIVATE_CLEAN_FILES := \
$(LOCAL_BUILT_MODULE) \
@@ -561,69 +566,74 @@
$(LOCAL_BUILT_MODULE):$(dir)/$(my_installed_module_stem))) \
$(eval my_compat_dist_config_$(suite) := ))
+
# Make sure we only add the files once for multilib modules.
-ifndef $(my_prefix)$(LOCAL_MODULE_CLASS)_$(LOCAL_MODULE)_compat_files
-$(my_prefix)$(LOCAL_MODULE_CLASS)_$(LOCAL_MODULE)_compat_files := true
-
-# LOCAL_COMPATIBILITY_SUPPORT_FILES is a list of <src>[:<dest>].
-$(foreach suite, $(LOCAL_COMPATIBILITY_SUITE), \
- $(eval my_compat_dist_$(suite) += $(foreach f, $(LOCAL_COMPATIBILITY_SUPPORT_FILES), \
- $(eval p := $(subst :,$(space),$(f))) \
- $(eval s := $(word 1,$(p))) \
- $(eval n := $(or $(word 2,$(p)),$(notdir $(word 1, $(p))))) \
- $(foreach dir, $(call compatibility_suite_dirs,$(suite)), \
- $(s):$(dir)/$(n)))))
-
-test_config := $(wildcard $(LOCAL_PATH)/AndroidTest.xml)
-ifeq (,$(test_config))
- ifneq (true,$(is_native))
- is_instrumentation_test := true
- ifeq (true, $(LOCAL_IS_HOST_MODULE))
- is_instrumentation_test := false
- endif
- # If LOCAL_MODULE_CLASS is not APPS, it's certainly not an instrumentation
- # test. However, some packages for test data also have LOCAL_MODULE_CLASS
- # set to APPS. These will require flag LOCAL_DISABLE_AUTO_GENERATE_TEST_CONFIG
- # to disable auto-generating test config file.
- ifneq (APPS, $(LOCAL_MODULE_CLASS))
- is_instrumentation_test := false
- endif
+ifdef $(my_prefix)$(LOCAL_MODULE_CLASS)_$(LOCAL_MODULE)_compat_files
+ # Sync the auto_test_config value for multilib modules.
+ ifdef $(my_prefix)$(LOCAL_MODULE_CLASS)_$(LOCAL_MODULE)_autogen
+ ALL_MODULES.$(my_register_name).auto_test_config := true
endif
- # CTS modules can be used for test data, so test config files must be
- # explicitly created using AndroidTest.xml
- ifeq (,$(filter cts, $(LOCAL_COMPATIBILITY_SUITE)))
- ifneq (true, $(LOCAL_DISABLE_AUTO_GENERATE_TEST_CONFIG))
- ifeq (true, $(filter true,$(is_native) $(is_instrumentation_test)))
- include $(BUILD_SYSTEM)/autogen_test_config.mk
- test_config := $(autogen_test_config_file)
- autogen_test_config_file :=
+else
+ $(my_prefix)$(LOCAL_MODULE_CLASS)_$(LOCAL_MODULE)_compat_files := true
+ # LOCAL_COMPATIBILITY_SUPPORT_FILES is a list of <src>[:<dest>].
+ $(foreach suite, $(LOCAL_COMPATIBILITY_SUITE), \
+ $(eval my_compat_dist_$(suite) += $(foreach f, $(LOCAL_COMPATIBILITY_SUPPORT_FILES), \
+ $(eval p := $(subst :,$(space),$(f))) \
+ $(eval s := $(word 1,$(p))) \
+ $(eval n := $(or $(word 2,$(p)),$(notdir $(word 1, $(p))))) \
+ $(foreach dir, $(call compatibility_suite_dirs,$(suite)), \
+ $(s):$(dir)/$(n)))))
+
+ test_config := $(wildcard $(LOCAL_PATH)/AndroidTest.xml)
+ ifeq (,$(test_config))
+ ifneq (true,$(is_native))
+ is_instrumentation_test := true
+ ifeq (true, $(LOCAL_IS_HOST_MODULE))
+ is_instrumentation_test := false
+ endif
+ # If LOCAL_MODULE_CLASS is not APPS, it's certainly not an instrumentation
+ # test. However, some packages for test data also have LOCAL_MODULE_CLASS
+ # set to APPS. These will require flag LOCAL_DISABLE_AUTO_GENERATE_TEST_CONFIG
+ # to disable auto-generating test config file.
+ ifneq (APPS, $(LOCAL_MODULE_CLASS))
+ is_instrumentation_test := false
+ endif
+ endif
+ # CTS modules can be used for test data, so test config files must be
+ # explicitly created using AndroidTest.xml
+ ifeq (,$(filter cts, $(LOCAL_COMPATIBILITY_SUITE)))
+ ifneq (true, $(LOCAL_DISABLE_AUTO_GENERATE_TEST_CONFIG))
+ ifeq (true, $(filter true,$(is_native) $(is_instrumentation_test)))
+ include $(BUILD_SYSTEM)/autogen_test_config.mk
+ test_config := $(autogen_test_config_file)
+ autogen_test_config_file :=
+ endif
endif
endif
endif
-endif
-is_instrumentation_test :=
+ is_instrumentation_test :=
-ifneq (,$(test_config))
-$(foreach suite, $(LOCAL_COMPATIBILITY_SUITE), \
- $(eval my_compat_dist_config_$(suite) += $(foreach dir, $(call compatibility_suite_dirs,$(suite)), \
- $(test_config):$(dir)/$(LOCAL_MODULE).config)))
-endif
+ ifneq (,$(test_config))
+ $(foreach suite, $(LOCAL_COMPATIBILITY_SUITE), \
+ $(eval my_compat_dist_config_$(suite) += $(foreach dir, $(call compatibility_suite_dirs,$(suite)), \
+ $(test_config):$(dir)/$(LOCAL_MODULE).config)))
+ endif
-test_config :=
+ test_config :=
-ifneq (,$(wildcard $(LOCAL_PATH)/DynamicConfig.xml))
-$(foreach suite, $(LOCAL_COMPATIBILITY_SUITE), \
- $(eval my_compat_dist_config_$(suite) += $(foreach dir, $(call compatibility_suite_dirs,$(suite)), \
- $(LOCAL_PATH)/DynamicConfig.xml:$(dir)/$(LOCAL_MODULE).dynamic)))
-endif
+ ifneq (,$(wildcard $(LOCAL_PATH)/DynamicConfig.xml))
+ $(foreach suite, $(LOCAL_COMPATIBILITY_SUITE), \
+ $(eval my_compat_dist_config_$(suite) += $(foreach dir, $(call compatibility_suite_dirs,$(suite)), \
+ $(LOCAL_PATH)/DynamicConfig.xml:$(dir)/$(LOCAL_MODULE).dynamic)))
+ endif
-ifneq (,$(wildcard $(LOCAL_PATH)/$(LOCAL_MODULE)_*.config))
-$(foreach extra_config, $(wildcard $(LOCAL_PATH)/$(LOCAL_MODULE)_*.config), \
- $(foreach suite, $(LOCAL_COMPATIBILITY_SUITE), \
- $(eval my_compat_dist_config_$(suite) += $(foreach dir, $(call compatibility_suite_dirs,$(suite)), \
- $(extra_config):$(dir)/$(notdir $(extra_config))))))
-endif
+ ifneq (,$(wildcard $(LOCAL_PATH)/$(LOCAL_MODULE)_*.config))
+ $(foreach extra_config, $(wildcard $(LOCAL_PATH)/$(LOCAL_MODULE)_*.config), \
+ $(foreach suite, $(LOCAL_COMPATIBILITY_SUITE), \
+ $(eval my_compat_dist_config_$(suite) += $(foreach dir, $(call compatibility_suite_dirs,$(suite)), \
+ $(extra_config):$(dir)/$(notdir $(extra_config))))))
+ endif
endif # $(my_prefix)$(LOCAL_MODULE_CLASS)_$(LOCAL_MODULE)_compat_files
ifneq ($(my_test_data_file_pairs),)
diff --git a/core/build-system.html b/core/build-system.html
index 3d86e24..3a11a47 100644
--- a/core/build-system.html
+++ b/core/build-system.html
@@ -147,12 +147,6 @@
.c, .cpp, .h, .java, java libraries, etc., should all work without intervention
in the Android.mk file.</p>
-<h3>Hiding command lines</h3>
-<p>The default of the build system will be to hide the command lines being
-executed for make steps. It will be possible to override this by specifying
-the showcommands pseudo-target, and possibly by setting an environment
-variable.</p>
-
<h3>Wildcard source files</h3>
<p>Wildcarding source file will be discouraged. It may be useful in some
scenarios. The default <code>$(wildcard *)</code> will not work due to the
@@ -326,19 +320,6 @@
directory inside the current combo directory. This is especially useful on the
simulator and emulator, where the persistent data remains present between
builds.</li>
-<li><b>showcommands</b> - <code>showcommands</code> is a modifier target
-which causes the build system to show the actual command lines for the build
-steps, instead of the brief descriptions. Most people don't like seeing the
-actual commands, because they're quite long and hard to read, but if you need
-to for debugging purposes, you can add <code>showcommands</code> to the list
-of targets you build. For example <code>make showcommands</code> will build
-the default android configuration, and <code>make runtime showcommands</code>
-will build just the runtime, and targets that it depends on, while displaying
-the full command lines. Please note that there are a couple places where the
-commands aren't shown here. These are considered bugs, and should be fixed,
-but they're often hard to track down. Please let
-<a href="mailto:android-build-team">android-build-team</a> know if you find
-any.</li>
<li><b>LOCAL_MODULE</b> - Anything you specify as a <code>LOCAL_MODULE</code>
in an Android.mk is made into a pseudotarget. For example, <code>make
runtime</code> might be shorthand for <code>make
diff --git a/core/clang/TARGET_x86_64.mk b/core/clang/TARGET_x86_64.mk
index 0d3ee3f..3161f84 100644
--- a/core/clang/TARGET_x86_64.mk
+++ b/core/clang/TARGET_x86_64.mk
@@ -3,3 +3,6 @@
RS_COMPAT_TRIPLE := x86_64-linux-android
TARGET_LIBPROFILE_RT := $(LLVM_RTLIB_PATH)/libclang_rt.profile-x86_64-android.a
+
+# Address sanitizer clang config
+ADDRESS_SANITIZER_LINKER := /system/bin/linker_asan64
diff --git a/core/clear_vars.mk b/core/clear_vars.mk
index 5051ef7..e7116a5 100644
--- a/core/clear_vars.mk
+++ b/core/clear_vars.mk
@@ -207,6 +207,7 @@
LOCAL_PRIVILEGED_MODULE:=
# '',full,custom,disabled,obfuscation,optimization
LOCAL_PRODUCT_MODULE:=
+LOCAL_PRODUCT_SERVICES_MODULE:=
LOCAL_PROGUARD_ENABLED:=
LOCAL_PROGUARD_FLAG_FILES:=
LOCAL_PROGUARD_FLAGS:=
@@ -252,6 +253,7 @@
LOCAL_SOONG_STATIC_LIBRARY_EXTRA_PACKAGES :=
LOCAL_DROIDDOC_STUBS_SRCJAR :=
LOCAL_DROIDDOC_DOC_ZIP :=
+LOCAL_DROIDDOC_ANNOTATIONS_ZIP :=
# '',true
LOCAL_SOURCE_FILES_ALL_GENERATED:=
LOCAL_SRC_FILES:=
diff --git a/core/config.mk b/core/config.mk
index 967ab5e..53718d5 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -701,6 +701,7 @@
DATA_BINDING_COMPILER := $(HOST_OUT_JAVA_LIBRARIES)/databinding-compiler.jar
FAT16COPY := build/make/tools/fat16copy.py
CHECK_LINK_TYPE := build/make/tools/check_link_type.py
+UUIDGEN := build/make/tools/uuidgen.py
PROGUARD := external/proguard/bin/proguard.sh
JAVATAGS := build/make/tools/java-event-log-tags.py
@@ -719,6 +720,7 @@
DEXDUMP := $(HOST_OUT_EXECUTABLES)/dexdump2$(BUILD_EXECUTABLE_SUFFIX)
PROFMAN := $(HOST_OUT_EXECUTABLES)/profman
HIDDENAPI := $(HOST_OUT_EXECUTABLES)/hiddenapi
+CLASS2GREYLIST := $(HOST_OUT_EXECUTABLES)/class2greylist
FINDBUGS_DIR := external/owasp/sanitizer/tools/findbugs/bin
FINDBUGS := $(FINDBUGS_DIR)/findbugs
@@ -901,20 +903,43 @@
# A list of SEPolicy versions, besides PLATFORM_SEPOLICY_VERSION, that the framework supports.
PLATFORM_SEPOLICY_COMPAT_VERSIONS := \
26.0 \
- 27.0
+ 27.0 \
+ 28.0 \
.KATI_READONLY := \
PLATFORM_SEPOLICY_COMPAT_VERSIONS \
PLATFORM_SEPOLICY_VERSION \
TOT_SEPOLICY_VERSION \
-ifndef USE_LOGICAL_PARTITIONS
- USE_LOGICAL_PARTITIONS := $(PRODUCT_USE_LOGICAL_PARTITIONS)
+# If true, kernel configuration requirements are present in OTA package (and will be enforced
+# during OTA). Otherwise, kernel configuration requirements are enforced in VTS.
+# Devices that checks the running kernel (instead of the kernel in OTA package) should not
+# set this variable to prevent OTA failures.
+ifndef PRODUCT_OTA_ENFORCE_VINTF_KERNEL_REQUIREMENTS
+ PRODUCT_OTA_ENFORCE_VINTF_KERNEL_REQUIREMENTS :=
+ ifdef PRODUCT_SHIPPING_API_LEVEL
+ ifeq (true,$(call math_gt_or_eq,$(PRODUCT_SHIPPING_API_LEVEL),29))
+ PRODUCT_OTA_ENFORCE_VINTF_KERNEL_REQUIREMENTS := true
+ endif
+ endif
endif
-.KATI_READONLY := USE_LOGICAL_PARTITIONS
+.KATI_READONLY := PRODUCT_OTA_ENFORCE_VINTF_KERNEL_REQUIREMENTS
-ifeq ($(USE_LOGICAL_PARTITIONS),true)
+ifeq ($(PRODUCT_USE_LOGICAL_PARTITIONS),true)
+ requirements := \
+ PRODUCT_USE_DYNAMIC_PARTITION_SIZE \
+ PRODUCT_BUILD_SUPER_PARTITION \
+ PRODUCT_USE_FASTBOOTD \
+
+ $(foreach req,$(requirements),$(if $(filter false,$($(req))),\
+ $(error PRODUCT_USE_LOGICAL_PARTITIONS requires $(req) to be true)))
+
+ requirements :=
+
BOARD_KERNEL_CMDLINE += androidboot.logical_partitions=1
+endif
+
+ifeq ($(PRODUCT_USE_DYNAMIC_PARTITION_SIZE),true)
ifneq ($(BOARD_SYSTEMIMAGE_PARTITION_SIZE),)
ifneq ($(BOARD_SYSTEMIMAGE_PARTITION_RESERVED_SIZE),)
@@ -930,7 +955,34 @@
endif
endif
-endif # USE_LOGICAL_PARTITIONS
+ifneq ($(BOARD_PRODUCTIMAGE_PARTITION_SIZE),)
+ifneq ($(BOARD_PRODUCTIMAGE_PARTITION_RESERVED_SIZE),)
+$(error Should not define BOARD_PRODUCTIMAGE_PARTITION_SIZE and \
+ BOARD_PRODUCTIMAGE_PARTITION_RESERVED_SIZE together)
+endif
+endif
+
+ifneq ($(BOARD_PRODUCT_SERVICESIMAGE_PARTITION_SIZE),)
+ifneq ($(BOARD_PRODUCT_SERVICESIMAGE_PARTITION_RESERVED_SIZE),)
+$(error Should not define BOARD_PRODUCT_SERVICESIMAGE_PARTITION_SIZE and \
+ BOARD_PRODUCT_SERVICESIMAGE_PARTITION_RESERVED_SIZE together)
+endif
+endif
+
+endif # PRODUCT_USE_DYNAMIC_PARTITION_SIZE
+
+ifeq ($(PRODUCT_BUILD_SUPER_PARTITION),true)
+ifdef BOARD_SUPER_PARTITION_PARTITION_LIST
+# BOARD_SUPER_PARTITION_PARTITION_LIST: a list of the following tokens
+valid_super_partition_list := system vendor product product_services
+ifneq (,$(filter-out $(valid_super_partition_list),$(BOARD_SUPER_PARTITION_PARTITION_LIST)))
+$(error BOARD_SUPER_PARTITION_PARTITION_LIST contains invalid partition name \
+ ($(filter-out $(valid_super_partition_list),$(BOARD_SUPER_PARTITION_PARTITION_LIST))). \
+ Valid names are $(valid_super_partition_list))
+endif
+valid_super_partition_list :=
+endif # BOARD_SUPER_PARTITION_PARTITION_LIST
+endif # PRODUCT_BUILD_SUPER_PARTITION
# ###############################################################
# Set up final options.
@@ -1036,6 +1088,8 @@
TARGET_SDK_VERSIONS_WITHOUT_JAVA_18_SUPPORT := $(call numbers_less_than,24,$(TARGET_AVAILABLE_SDK_VERSIONS))
TARGET_SDK_VERSIONS_WITHOUT_JAVA_19_SUPPORT := $(call numbers_less_than,27,$(TARGET_AVAILABLE_SDK_VERSIONS))
+INTERNAL_PLATFORM_HIDDENAPI_PUBLIC_LIST := $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/hiddenapi-public-list.txt
+INTERNAL_PLATFORM_HIDDENAPI_PRIVATE_LIST := $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/hiddenapi-private-list.txt
INTERNAL_PLATFORM_HIDDENAPI_LIGHT_GREYLIST := $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/hiddenapi-light-greylist.txt
INTERNAL_PLATFORM_HIDDENAPI_DARK_GREYLIST := $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/hiddenapi-dark-greylist.txt
INTERNAL_PLATFORM_HIDDENAPI_BLACKLIST := $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/hiddenapi-blacklist.txt
@@ -1086,6 +1140,7 @@
bptimage-nodeps \
vnod vendorimage-nodeps \
pnod productimage-nodeps \
+ psnod productservicesimage-nodeps \
systemotherimage-nodeps \
ramdisk-nodeps \
bootimage-nodeps \
diff --git a/core/definitions.mk b/core/definitions.mk
index 8d7e3ff..b0c5db0 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -742,18 +742,6 @@
$(foreach lib,$(1),$(call intermediates-dir-for,JAVA_LIBRARIES,$(lib),,COMMON)/exported-sdk-libs)
endef
-# Fix manifest
-# $(1): input manifest path
-# $(2): output manifest path
-# $(3): min sdk version
-# $(4): (optional) exported-sdk-libs file
-define fix-manifest
-$(MANIFEST_FIXER) \
---minSdkVersion $(3) \
-$(if $(4),$$(cat $(4) | sort -u | sed -e 's/^/\ --uses-library\ /' | tr '\n' ' ')) \
-$(1) $(2)
-endef
-
###########################################################
## Returns true if $(1) and $(2) are equal. Returns
## the empty string if they are not equal.
@@ -808,8 +796,8 @@
define collapse-pairs
$(eval _cpSEP := $(strip $(if $(2),$(2),=)))\
-$(subst $(space)$(_cpSEP)$(space),$(_cpSEP),$(strip \
- $(subst $(_cpSEP), $(_cpSEP) ,$(1))))
+$(strip $(subst $(space)$(_cpSEP)$(space),$(_cpSEP),$(strip \
+ $(subst $(_cpSEP), $(_cpSEP) ,$(1)))$(space)))
endef
###########################################################
@@ -2126,7 +2114,9 @@
# $(2): the base dir of the output file path
# Returns: the compiled output file path
define aapt2-compiled-resource-out-file
-$(eval _p_w := $(strip $(subst /,$(space),$(dir $(1)))))$(2)/$(subst $(space),/,$(_p_w))_$(if $(filter values%,$(lastword $(_p_w))),$(patsubst %.xml,%.arsc,$(notdir $(1))),$(notdir $(1))).flat
+$(strip \
+ $(eval _p_w := $(strip $(subst /,$(space),$(dir $(call clean-path,$(1))))))
+ $(2)/$(subst $(space),/,$(_p_w))_$(if $(filter values%,$(lastword $(_p_w))),$(patsubst %.xml,%.arsc,$(notdir $(1))),$(notdir $(1))).flat)
endef
define aapt2-link
@@ -2557,6 +2547,34 @@
mv $@.compressed $@;
endef
+ifeq ($(HOST_OS),linux)
+# Runs appcompat and store logs in $(PRODUCT_OUT)/appcompat
+define extract-package
+$(if $(filter aapt2, $(1)), \
+ $(AAPT2) dump $@ | awk -F ' |=' '/^Package/{print $$3}' >> $(PRODUCT_OUT)/appcompat/$(PRIVATE_MODULE).log &&, \
+ $(AAPT) dump badging $@ | awk -F \' '/^package/{print $$2}' >> $(PRODUCT_OUT)/appcompat/$(PRIVATE_MODULE).log &&)
+endef
+define appcompat-header
+$(hide) \
+ mkdir -p $(PRODUCT_OUT)/appcompat && \
+ rm -f $(PRODUCT_OUT)/appcompat/$(PRIVATE_MODULE).log && \
+ echo -n "Package name: " >> $(PRODUCT_OUT)/appcompat/$(PRIVATE_MODULE).log && \
+ $(call extract-package, $(1)) \
+ echo "Module name in Android tree: $(PRIVATE_MODULE)" >> $(PRODUCT_OUT)/appcompat/$(PRIVATE_MODULE).log && \
+ echo "Local path in Android tree: $(PRIVATE_PATH)" >> $(PRODUCT_OUT)/appcompat/$(PRIVATE_MODULE).log && \
+ echo "Install path on $(TARGET_PRODUCT)-$(TARGET_BUILD_VARIANT): $(PRIVATE_INSTALLED_MODULE)" >> $(PRODUCT_OUT)/appcompat/$(PRIVATE_MODULE).log && \
+ echo >> $(PRODUCT_OUT)/appcompat/$(PRIVATE_MODULE).log
+endef
+define run-appcompat
+$(hide) \
+ echo "appcompat.sh output:" >> $(PRODUCT_OUT)/appcompat/$(PRIVATE_MODULE).log && \
+ art/tools/veridex/appcompat.sh --dex-file=$@ 2>&1 >> $(PRODUCT_OUT)/appcompat/$(PRIVATE_MODULE).log
+endef
+else
+appcompat-header =
+run-appcompat =
+endif # HOST_OS == linux
+
# Remove dynamic timestamps from packages
#
define remove-timestamps-from-package
@@ -2837,6 +2855,7 @@
endef
# Copy dex files, invoking $(HIDDENAPI) on them in the process.
+# Also make the source dex file an input of the hiddenapi singleton rule in dex_preopt.mk.
define hiddenapi-copy-dex-files
$(2): $(1) $(HIDDENAPI) $(INTERNAL_PLATFORM_HIDDENAPI_LIGHT_GREYLIST) \
$(INTERNAL_PLATFORM_HIDDENAPI_DARK_GREYLIST) $(INTERNAL_PLATFORM_HIDDENAPI_BLACKLIST)
@@ -2848,6 +2867,20 @@
--light-greylist=$(INTERNAL_PLATFORM_HIDDENAPI_LIGHT_GREYLIST) \
--dark-greylist=$(INTERNAL_PLATFORM_HIDDENAPI_DARK_GREYLIST) \
--blacklist=$(INTERNAL_PLATFORM_HIDDENAPI_BLACKLIST)
+
+$(INTERNAL_PLATFORM_HIDDENAPI_PRIVATE_LIST): $(1)
+$(INTERNAL_PLATFORM_HIDDENAPI_PRIVATE_LIST): \
+ PRIVATE_DEX_INPUTS := $$(PRIVATE_DEX_INPUTS) $(1)
+endef
+
+# Generate a greylist.txt from a classes.jar
+define hiddenapi-generate-greylist-txt
+$(2): $(1) $(CLASS2GREYLIST)
+ $(CLASS2GREYLIST) $(1) > $(2)
+
+$(INTERNAL_PLATFORM_HIDDENAPI_LIGHT_GREYLIST): $(2)
+$(INTERNAL_PLATFORM_HIDDENAPI_LIGHT_GREYLIST): \
+ PRIVATE_GREYLIST_INPUTS := $$(PRIVATE_GREYLIST_INPUTS) $(2)
endef
# File names for intermediate dex files of `hiddenapi-copy-soong-jar`.
@@ -3547,10 +3580,12 @@
###########################################################
## Verify module name meets character requirements:
## a-z A-Z 0-9
-## _.+-=,@~
+## _.+-,@~
##
## This is a subset of bazel's target name restrictions:
## https://docs.bazel.build/versions/master/build-ref.html#name
+##
+## Kati has problems with '=': https://github.com/google/kati/issues/138
###########################################################
define verify-module-name
$(if $(filter-out $(LOCAL_MODULE),$(subst /,,$(LOCAL_MODULE))), \
@@ -3559,14 +3594,14 @@
$(call pretty-error,Invalid characters in module name: $(call _invalid-name-chars,$(LOCAL_MODULE))))
endef
define _invalid-name-chars
-$(subst _,,$(subst .,,$(subst +,,$(subst -,,$(subst =,,$(subst $(comma),,$(subst @,,$(subst ~,,$(subst 0,,$(subst 1,,$(subst 2,,$(subst 3,,$(subst 4,,$(subst 5,,$(subst 6,,$(subst 7,,$(subst 8,,$(subst 9,,$(subst a,,$(subst b,,$(subst c,,$(subst d,,$(subst e,,$(subst f,,$(subst g,,$(subst h,,$(subst i,,$(subst j,,$(subst k,,$(subst l,,$(subst m,,$(subst n,,$(subst o,,$(subst p,,$(subst q,,$(subst r,,$(subst s,,$(subst t,,$(subst u,,$(subst v,,$(subst w,,$(subst x,,$(subst y,,$(subst z,,$(call to-lower,$(1))))))))))))))))))))))))))))))))))))))))))))))
+$(subst _,,$(subst .,,$(subst +,,$(subst -,,$(subst $(comma),,$(subst @,,$(subst ~,,$(subst 0,,$(subst 1,,$(subst 2,,$(subst 3,,$(subst 4,,$(subst 5,,$(subst 6,,$(subst 7,,$(subst 8,,$(subst 9,,$(subst a,,$(subst b,,$(subst c,,$(subst d,,$(subst e,,$(subst f,,$(subst g,,$(subst h,,$(subst i,,$(subst j,,$(subst k,,$(subst l,,$(subst m,,$(subst n,,$(subst o,,$(subst p,,$(subst q,,$(subst r,,$(subst s,,$(subst t,,$(subst u,,$(subst v,,$(subst w,,$(subst x,,$(subst y,,$(subst z,,$(call to-lower,$(1)))))))))))))))))))))))))))))))))))))))))))))
endef
.KATI_READONLY := verify-module-name _invalid-name-chars
###########################################################
## Verify module stem meets character requirements:
## a-z A-Z 0-9
-## _.+-=,@~
+## _.+-,@~
##
## This is a subset of bazel's target name restrictions:
## https://docs.bazel.build/versions/master/build-ref.html#name
diff --git a/core/dex_preopt.mk b/core/dex_preopt.mk
index de830d4..e668248 100644
--- a/core/dex_preopt.mk
+++ b/core/dex_preopt.mk
@@ -89,3 +89,34 @@
ifdef TARGET_2ND_ARCH
$(TARGET_2ND_ARCH_VAR_PREFIX)DEXPREOPT_ONE_FILE_DEPENDENCY_BUILT_BOOT_PREOPT := $($(TARGET_2ND_ARCH_VAR_PREFIX)DEFAULT_DEX_PREOPT_BUILT_IMAGE_FILENAME)
endif # TARGET_2ND_ARCH
+
+# === hiddenapi rules ===
+
+hiddenapi_stubs_jar = $(call intermediates-dir-for,JAVA_LIBRARIES,$(1),,COMMON)/javalib.jar
+
+# Public API stubs
+HIDDENAPI_STUBS := \
+ $(call hiddenapi_stubs_jar,android_stubs_current) \
+ $(call hiddenapi_stubs_jar,android.test.base.stubs)
+
+# System API stubs
+HIDDENAPI_STUBS += \
+ $(call hiddenapi_stubs_jar,android_system_stubs_current)
+
+# Test API stubs
+HIDDENAPI_STUBS += \
+ $(call hiddenapi_stubs_jar,android_test_stubs_current)
+
+# Singleton rule which applies $(HIDDENAPI) on all boot class path dex files.
+# Inputs are filled with `hiddenapi-copy-dex-files` rules.
+$(INTERNAL_PLATFORM_HIDDENAPI_PRIVATE_LIST): \
+ PRIVATE_HIDDENAPI_STUBS := $(HIDDENAPI_STUBS)
+$(INTERNAL_PLATFORM_HIDDENAPI_PRIVATE_LIST): \
+ .KATI_IMPLICIT_OUTPUTS := $(INTERNAL_PLATFORM_HIDDENAPI_PUBLIC_LIST)
+$(INTERNAL_PLATFORM_HIDDENAPI_PRIVATE_LIST): $(HIDDENAPI) $(HIDDENAPI_STUBS)
+ for INPUT_DEX in $(PRIVATE_DEX_INPUTS); do \
+ find `dirname $${INPUT_DEX}` -maxdepth 1 -name "classes*.dex"; \
+ done | sort | sed 's/^/--boot-dex=/' | xargs $(HIDDENAPI) list \
+ $(addprefix --stub-dex=,$(PRIVATE_HIDDENAPI_STUBS)) \
+ --out-public=$(INTERNAL_PLATFORM_HIDDENAPI_PUBLIC_LIST) \
+ --out-private=$(INTERNAL_PLATFORM_HIDDENAPI_PRIVATE_LIST)
diff --git a/core/dex_preopt_libart_boot.mk b/core/dex_preopt_libart_boot.mk
index 977f852..5a68738 100644
--- a/core/dex_preopt_libart_boot.mk
+++ b/core/dex_preopt_libart_boot.mk
@@ -100,7 +100,9 @@
$(PRIVATE_BOOT_IMAGE_FLAGS) \
$(addprefix --dex-file=,$(LIBART_TARGET_BOOT_DEX_FILES)) \
$(addprefix --dex-location=,$(LIBART_TARGET_BOOT_DEX_LOCATIONS)) \
+ --generate-debug-info --generate-build-id \
--oat-symbols=$($(PRIVATE_2ND_ARCH_VAR_PREFIX)LIBART_TARGET_BOOT_OAT_UNSTRIPPED) \
+ --strip \
--oat-file=$(patsubst %.art,%.oat,$@) \
--oat-location=$(patsubst %.art,%.oat,$($(PRIVATE_2ND_ARCH_VAR_PREFIX)LIBART_BOOT_IMAGE_FILENAME)) \
--image=$@ --base=$(LIBART_IMG_TARGET_BASE_ADDRESS) \
@@ -109,7 +111,6 @@
--instruction-set-features=$($(PRIVATE_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_INSTRUCTION_SET_FEATURES) \
--android-root=$(PRODUCT_OUT)/system \
--runtime-arg -Xnorelocate --compile-pic \
- --no-generate-debug-info --generate-build-id \
--multi-image --no-inline-from=core-oj.jar \
--abort-on-hard-verifier-error \
--abort-on-soft-verifier-error \
diff --git a/core/dex_preopt_odex_install.mk b/core/dex_preopt_odex_install.mk
index 3585026..208647e 100644
--- a/core/dex_preopt_odex_install.mk
+++ b/core/dex_preopt_odex_install.mk
@@ -34,6 +34,14 @@
else # LOCAL_APK_LIBRARIES not empty
LOCAL_DEX_PREOPT := nostripping
endif # LOCAL_APK_LIBRARIES not empty
+ else
+ # Default to nostripping for non system preopt (enables preopt).
+ # Don't strip in case the oat/vdex version in system ROM doesn't match the one in other
+ # partitions. It needs to be able to fall back to the APK for that case.
+ # Also only enable preopt for non tests.
+ ifeq (,$(filter $(LOCAL_MODULE_TAGS),tests))
+ LOCAL_DEX_PREOPT := nostripping
+ endif
endif # Installed to system.img.
endif # LOCAL_DEX_PREOPT undefined
endif # TARGET_BUILD_APPS empty
@@ -204,6 +212,11 @@
endif
endif
+# Only preopt primary arch for translated arch since there is only an image there.
+ifeq ($(TARGET_TRANSLATE_2ND_ARCH),true)
+my_module_multilib := first
+endif
+
# #################################################
# Odex for the 1st arch
my_2nd_arch_prefix :=
@@ -222,9 +235,12 @@
else # must be APPS
# The preferred arch
my_2nd_arch_prefix := $(LOCAL_2ND_ARCH_VAR_PREFIX)
+# Save the module multilib since setup_one_odex modifies it.
+saved_my_module_multilib := $(my_module_multilib)
include $(BUILD_SYSTEM)/setup_one_odex.mk
+my_module_multilib := $(saved_my_module_multilib)
ifdef TARGET_2ND_ARCH
-ifeq ($(LOCAL_MULTILIB),both)
+ifeq ($(my_module_multilib),both)
# The non-preferred arch
my_2nd_arch_prefix := $(if $(LOCAL_2ND_ARCH_VAR_PREFIX),,$(TARGET_2ND_ARCH_VAR_PREFIX))
include $(BUILD_SYSTEM)/setup_one_odex.mk
diff --git a/core/droiddoc.mk b/core/droiddoc.mk
index deaee56..5425e31 100644
--- a/core/droiddoc.mk
+++ b/core/droiddoc.mk
@@ -287,6 +287,7 @@
$(hide) ( F=$$(pwd)/$@ ; cd $(PRIVATE_DOCS_DIR) && zip -rqX $$F * )
$(LOCAL_MODULE)-docs.zip : $(out_zip)
+.PHONY: $(LOCAL_MODULE)-docs.zip
$(call dist-for-goals,docs,$(out_zip))
diff --git a/core/envsetup.mk b/core/envsetup.mk
index 2f37767..c7c3f92 100644
--- a/core/envsetup.mk
+++ b/core/envsetup.mk
@@ -180,6 +180,7 @@
TARGET_COPY_OUT_OEM := oem
TARGET_COPY_OUT_ODM := odm
TARGET_COPY_OUT_PRODUCT := product
+TARGET_COPY_OUT_PRODUCT_SERVICES := product-services
TARGET_COPY_OUT_ROOT := root
TARGET_COPY_OUT_RECOVERY := recovery
@@ -210,6 +211,17 @@
TARGET_COPY_OUT_PRODUCT := $(_product_path_placeholder)
###########################################
+###########################################
+# Define TARGET_COPY_OUT_PRODUCT_SERVICES to a placeholder, for at this point
+# we don't know if the device wants to build a separate product-services.img
+# or just build product stuff into system.img.
+# A device can set up TARGET_COPY_OUT_PRODUCT_SERVICES to "product-services" in its
+# BoardConfig.mk.
+# We'll substitute with the real value after loading BoardConfig.mk.
+_product_services_path_placeholder := ||PRODUCT-SERVICES-PATH-PH||
+TARGET_COPY_OUT_PRODUCT_SERVICES := $(_product_services_path_placeholder)
+###########################################
+
#################################################################
# Set up minimal BOOTCLASSPATH list of jars to build/execute
# java code with dalvikvm/art.
@@ -342,6 +354,28 @@
endif
###########################################
+# Now we can substitute with the real value of TARGET_COPY_OUT_PRODUCT_SERVICES
+ifeq ($(TARGET_COPY_OUT_PRODUCT_SERVICES),$(_product_services_path_placeholder))
+TARGET_COPY_OUT_PRODUCT_SERVICES := system/product-services
+else ifeq ($(filter product-services system/product-services,$(TARGET_COPY_OUT_PRODUCT_SERVICES)),)
+$(error TARGET_COPY_OUT_PRODUCT_SERVICES must be either 'product-services' or 'system/product-services', seeing '$(TARGET_COPY_OUT_PRODUCT_SERVICES)'.)
+endif
+PRODUCT_SERVICES_COPY_FILES := $(subst $(_product_services_path_placeholder),$(TARGET_COPY_OUT_PRODUCT_SERVICES),$(PRODUCT_SERVICES_COPY_FILES))
+
+BOARD_USES_PRODUCT_SERVICESIMAGE :=
+ifdef BOARD_PREBUILT_PRODUCT_SERVICESIMAGE
+BOARD_USES_PRODUCT_SERVICESIMAGE := true
+endif
+ifdef BOARD_PRODUCT_SERVICESIMAGE_FILE_SYSTEM_TYPE
+BOARD_USES_PRODUCT_SERVICESIMAGE := true
+endif
+ifeq ($(TARGET_COPY_OUT_PRODUCT_SERVICES),product-services)
+BOARD_USES_PRODUCT_SERVICESIMAGE := true
+else ifdef BOARD_USES_PRODUCT_SERVICESIMAGE
+$(error TARGET_COPY_OUT_PRODUCT_SERVICES must be set to 'product-services' to use a product-services image)
+endif
+
+###########################################
# Ensure that only TARGET_RECOVERY_UPDATER_LIBS *or* AB_OTA_UPDATER is set.
TARGET_RECOVERY_UPDATER_LIBS ?=
AB_OTA_UPDATER ?=
@@ -880,6 +914,39 @@
$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_PRODUCT_APPS \
$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_PRODUCT_APPS_PRIVILEGED
+TARGET_OUT_PRODUCT_SERVICES := $(PRODUCT_OUT)/$(TARGET_COPY_OUT_PRODUCT_SERVICES)
+ifneq ($(filter address,$(SANITIZE_TARGET)),)
+target_out_product_services_shared_libraries_base := $(PRODUCT_SERVICES_OUT)/$(TARGET_COPY_OUT_ASAN)/product-services
+ifeq ($(SANITIZE_LITE),true)
+# When using SANITIZE_LITE, APKs must not be packaged with sanitized libraries, as they will not
+# work with unsanitized app_process. For simplicity, generate APKs into /data/asan/.
+target_out_product_services_app_base := $(PRODUCT_SERVICES_OUT)/$(TARGET_COPY_OUT_ASAN)/product-services
+else
+target_out_product_services_app_base := $(TARGET_OUT_PRODUCT_SERVICES)
+endif
+else
+target_out_product_services_shared_libraries_base := $(TARGET_OUT_PRODUCT_SERVICES)
+target_out_product_services_app_base := $(TARGET_OUT_PRODUCT_SERVICES)
+endif
+
+ifeq ($(TARGET_IS_64_BIT),true)
+TARGET_OUT_PRODUCT_SERVICES_SHARED_LIBRARIES := $(target_out_product_services_shared_libraries_base)/lib64
+else
+TARGET_OUT_PRODUCT_SERVICES_SHARED_LIBRARIES := $(target_out_product_services_shared_libraries_base)/lib
+endif
+TARGET_OUT_PRODUCT_SERVICES_JAVA_LIBRARIES:= $(TARGET_OUT_PRODUCT_SERVICES)/framework
+TARGET_OUT_PRODUCT_SERVICES_APPS := $(target_out_product_services_app_base)/app
+TARGET_OUT_PRODUCT_SERVICES_APPS_PRIVILEGED := $(target_out_product_services_app_base)/priv-app
+TARGET_OUT_PRODUCT_SERVICES_ETC := $(TARGET_OUT_PRODUCT_SERVICES)/etc
+
+ifeq ($(TARGET_TRANSLATE_2ND_ARCH),true)
+$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_PRODUCT_SERVICES_SHARED_LIBRARIES := $(target_out_product_services_shared_libraries_base)/lib/$(TARGET_2ND_ARCH)
+else
+$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_PRODUCT_SERVICES_SHARED_LIBRARIES := $(target_out_product_services_shared_libraries_base)/lib
+endif
+$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_PRODUCT_SERVICES_APPS := $(TARGET_OUT_PRODUCT_SERVICES_APPS)
+$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_PRODUCT_SERVICES_APPS_PRIVILEGED := $(TARGET_OUT_PRODUCT_SERVICES_APPS_PRIVILEGED)
+
TARGET_OUT_BREAKPAD := $(PRODUCT_OUT)/breakpad
.KATI_READONLY := TARGET_OUT_BREAKPAD
diff --git a/core/host_java_library.mk b/core/host_java_library.mk
index db24542..2aed61e 100644
--- a/core/host_java_library.mk
+++ b/core/host_java_library.mk
@@ -93,6 +93,7 @@
javac-check : $(full_classes_compiled_jar)
javac-check-$(LOCAL_MODULE) : $(full_classes_compiled_jar)
+.PHONY: javac-check-$(LOCAL_MODULE)
$(full_classes_combined_jar): $(full_classes_compiled_jar) \
$(jar_manifest_file) \
diff --git a/core/java.mk b/core/java.mk
index 78b492d..0d898e7 100644
--- a/core/java.mk
+++ b/core/java.mk
@@ -79,6 +79,7 @@
built_dex_hiddenapi := $(intermediates.COMMON)/dex-hiddenapi/classes.dex
full_classes_stubs_jar := $(intermediates.COMMON)/stubs.jar
java_source_list_file := $(intermediates.COMMON)/java-source-list
+greylist_txt := $(intermediates.COMMON)/greylist.txt
ifeq ($(LOCAL_MODULE_CLASS)$(LOCAL_SRC_FILES)$(LOCAL_STATIC_JAVA_LIBRARIES)$(LOCAL_SOURCE_FILES_ALL_GENERATED),APPS)
@@ -308,6 +309,7 @@
javac-check : $(full_classes_compiled_jar)
javac-check-$(LOCAL_MODULE) : $(full_classes_compiled_jar)
+.PHONY: javac-check-$(LOCAL_MODULE)
$(full_classes_combined_jar): PRIVATE_DONT_DELETE_JAR_META_INF := $(LOCAL_DONT_DELETE_JAR_META_INF)
$(full_classes_combined_jar): $(full_classes_compiled_jar) \
@@ -457,14 +459,15 @@
-applymapping $(link_instr_intermediates_dir.COMMON)/proguard_dictionary \
-verbose \
$(legacy_proguard_flags)
+legacy_proguard_lib_deps += \
+ $(link_instr_classes_jar) \
+ $(link_instr_intermediates_dir.COMMON)/proguard_options \
+ $(link_instr_intermediates_dir.COMMON)/proguard_dictionary \
# Sometimes (test + main app) uses different keep rules from the main app -
# apply the main app's dictionary anyway.
legacy_proguard_flags += -ignorewarnings
-# Make sure we run Proguard on the main app first
-$(full_classes_proguard_jar) : $(link_instr_intermediates_dir.COMMON)/proguard.classes.jar
-
endif # no obfuscation
endif # LOCAL_INSTRUMENTATION_FOR
@@ -544,6 +547,13 @@
endif
ifneq ($(filter $(LOCAL_MODULE),$(PRODUCT_BOOT_JARS)),) # is_boot_jar
+ # Derive API greylist from the classes jar.
+ # We use full_classes_proguard_jar here, as that is what is converted to dex
+ # later on. The difference is academic currently, as we don't proguard any
+ # bootclasspath code at the moment. If we were to do that, we should add keep
+ # rules for all members with the @UnsupportedAppUsage annotation.
+ $(eval $(call hiddenapi-generate-greylist-txt,$(full_classes_proguard_jar),$(greylist_txt)))
+ LOCAL_INTERMEDIATE_TARGETS += $(greylist_txt)
$(eval $(call hiddenapi-copy-dex-files,$(built_dex_intermediate),$(built_dex_hiddenapi)))
built_dex_copy_from := $(built_dex_hiddenapi)
else # !is_boot_jar
@@ -576,6 +586,7 @@
findbugs_html := $(PRODUCT_OUT)/findbugs/$(LOCAL_MODULE).html
$(findbugs_html) : PRIVATE_XML_FILE := $(findbugs_xml)
$(LOCAL_MODULE)-findbugs : $(findbugs_html)
+.PHONY: $(LOCAL_MODULE)-findbugs
$(findbugs_html) : $(findbugs_xml)
@mkdir -p $(dir $@)
@echo ConvertXmlToText: $@
diff --git a/core/main.mk b/core/main.mk
index 436971a..ba082ac 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -26,6 +26,8 @@
else # KATI
+$(info [1/1] initializing build system ...)
+
# Absolute path of the present working direcotry.
# This overrides the shell variable $PWD, which does not necessarily points to
# the top of the source tree, for example when "make -C" is used in m/mm/mmm.
@@ -144,6 +146,15 @@
#
# -----------------------------------------------------------------
+# Validate ADDITIONAL_PRODUCT_PROPERTIES.
+ifneq ($(ADDITIONAL_PRODUCT_PROPERTIES),)
+$(error ADDITIONAL_PRODUCT_PROPERTIES must not be set before here: $(ADDITIONAL_PRODUCT_PROPERTIES))
+endif
+
+ADDITIONAL_PRODUCT_PROPERTIES :=
+
+#
+# -----------------------------------------------------------------
# Add the product-defined properties to the build properties.
ifdef PRODUCT_SHIPPING_API_LEVEL
ADDITIONAL_BUILD_PROPERTIES += \
@@ -229,7 +240,7 @@
ADDITIONAL_DEFAULT_PROPERTIES += ro.actionable_compatible_property.enabled=${PRODUCT_COMPATIBLE_PROPERTY}
endif
-ADDITIONAL_BUILD_PROPERTIES += ro.boot.logical_partitions=${USE_LOGICAL_PARTITIONS}
+ADDITIONAL_PRODUCT_PROPERTIES += ro.boot.logical_partitions=$(PRODUCT_USE_LOGICAL_PARTITIONS)
# -----------------------------------------------------------------
###
@@ -400,11 +411,15 @@
.KATI_READONLY := ADDITIONAL_DEFAULT_PROPERTIES
ADDITIONAL_BUILD_PROPERTIES := $(strip $(ADDITIONAL_BUILD_PROPERTIES))
.KATI_READONLY := ADDITIONAL_BUILD_PROPERTIES
+ADDITIONAL_PRODUCT_PROPERTIES := $(strip $(ADDITIONAL_PRODUCT_PROPERTIES))
+.KATI_READONLY := ADDITIONAL_PRODUCT_PROPERTIES
ifneq ($(PRODUCT_ENFORCE_RRO_TARGETS),)
ENFORCE_RRO_SOURCES :=
endif
+subdir_makefiles_inc := .
+
ifneq ($(ONE_SHOT_MAKEFILE),)
# We've probably been invoked by the "mm" shell function
# with a subdirectory's makefile.
@@ -449,7 +464,7 @@
#
subdir_makefiles := $(SOONG_ANDROID_MK) $(file <$(OUT_DIR)/.module_paths/Android.mk.list)
-subdir_makefiles_total := $(words $(subdir_makefiles))
+subdir_makefiles_total := $(words int $(subdir_makefiles) post finish)
.KATI_READONLY := subdir_makefiles_total
$(foreach mk,$(subdir_makefiles),$(info [$(call inc_and_print,subdir_makefiles_inc)/$(subdir_makefiles_total)] including $(mk) ...)$(eval include $(mk)))
@@ -465,6 +480,12 @@
endif # ONE_SHOT_MAKEFILE
+ifndef subdir_makefiles_total
+subdir_makefiles_total := $(words init post finish)
+endif
+
+$(info [$(call inc_and_print,subdir_makefiles_inc)/$(subdir_makefiles_total)] finishing build rules ...)
+
# -------------------------------------------------------------------
# All module makefiles have been included at this point.
# -------------------------------------------------------------------
@@ -891,7 +912,18 @@
$(call expand-required-modules,$(1),$(_erm_new_modules)))
endef
-# Determines the files a particular product installs.
+# Transforms paths relative to PRODUCT_OUT to absolute paths.
+# $(1): list of relative paths
+# $(2): optional suffix to append to paths
+define resolve-product-relative-paths
+ $(subst $(_vendor_path_placeholder),$(TARGET_COPY_OUT_VENDOR),\
+ $(subst $(_product_path_placeholder),$(TARGET_COPY_OUT_PRODUCT),\
+ $(foreach p,$(1),$(call append-path,$(PRODUCT_OUT),$(p)$(2)))))
+endef
+
+# Lists most of the files a particular product installs, including:
+# - PRODUCT_PACKAGES, and their LOCAL_REQUIRED_MODULES
+# - PRODUCT_COPY_FILES
# The base list of modules to build for this product is specified
# by the appropriate product definition file, which was included
# by product_config.mk.
@@ -905,7 +937,8 @@
# 32-bit variant, if it exits. See the select-bitness-of-required-modules definition.
# $(1): product makefile
define product-installed-files
- $(eval _pif_modules := $(PRODUCTS.$(strip $(1)).PRODUCT_PACKAGES)) \
+ $(eval _mk := $(strip $(1))) \
+ $(eval _pif_modules := $(PRODUCTS.$(_mk).PRODUCT_PACKAGES)) \
$(if $(BOARD_VNDK_VERSION),$(eval _pif_modules += vndk_package)) \
$(eval ### Filter out the overridden packages and executables before doing expansion) \
$(eval _pif_overrides := $(foreach p, $(_pif_modules), $(PACKAGES.$(p).OVERRIDES))) \
@@ -922,7 +955,9 @@
$(eval _pif_modules += $(call get-32-bit-modules, $(_pif_modules_rest))) \
$(eval _pif_modules += $(_pif_modules_rest)) \
$(call expand-required-modules,_pif_modules,$(_pif_modules)) \
- $(call module-installed-files, $(_pif_modules))
+ $(call module-installed-files, $(_pif_modules)) \
+ $(call resolve-product-relative-paths,\
+ $(foreach cf,$(PRODUCTS.$(_mk).PRODUCT_COPY_FILES),$(call word-colon,2,$(cf))))
endef
# Fails the build if the given list is non-empty, and prints it entries (stripping PRODUCT_OUT).
@@ -953,6 +988,39 @@
ifdef FULL_BUILD
product_FILES := $(call product-installed-files, $(INTERNAL_PRODUCT))
+
+ # Verify the artifact path requirements made by included products.
+ all_offending_files :=
+ $(foreach makefile,$(ARTIFACT_PATH_REQUIREMENT_PRODUCTS),\
+ $(eval requirements := $(PRODUCTS.$(makefile).ARTIFACT_PATH_REQUIREMENTS)) \
+ $(eval ### Verify that the product only produces files inside its path requirements.) \
+ $(eval whitelist := $(PRODUCTS.$(makefile).ARTIFACT_PATH_WHITELIST)) \
+ $(eval path_patterns := $(call resolve-product-relative-paths,$(requirements),%)) \
+ $(eval whitelist_patterns := $(call resolve-product-relative-paths,$(whitelist))) \
+ $(eval files := $(call product-installed-files, $(makefile))) \
+ $(eval files := $(filter-out $(TARGET_OUT_FAKE)/% $(HOST_OUT)/%,$(files))) \
+ $(eval # RROs become REQUIRED by the source module, but are always placed on the vendor partition.) \
+ $(eval files := $(filter-out %__auto_generated_rro.apk,$(files))) \
+ $(eval offending_files := $(filter-out $(path_patterns) $(whitelist_patterns),$(files))) \
+ $(call maybe-print-list-and-error,$(offending_files),$(makefile) produces files outside its artifact path requirement.) \
+ $(eval unused_whitelist := $(filter-out $(files),$(whitelist_patterns))) \
+ $(call maybe-print-list-and-error,$(unused_whitelist),$(makefile) includes redundant whitelist entries in its artifact path requirement.) \
+ $(eval ### Optionally verify that nothing else produces files inside this artifact path requirement.) \
+ $(eval extra_files := $(filter-out $(files) $(HOST_OUT)/%,$(product_FILES))) \
+ $(eval files_in_requirement := $(filter $(path_patterns),$(extra_files))) \
+ $(eval all_offending_files += $(files_in_requirement)) \
+ $(eval whitelist := $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_ARTIFACT_PATH_REQUIREMENT_WHITELIST)) \
+ $(eval whitelist_patterns := $(call resolve-product-relative-paths,$(whitelist))) \
+ $(eval offending_files := $(filter-out $(whitelist_patterns),$(files_in_requirement))) \
+ $(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS),\
+ $(call maybe-print-list-and-error,$(offending_files),$(INTERNAL_PRODUCT) produces files inside $(makefile)s artifact path requirement.) \
+ $(eval unused_whitelist := $(filter-out $(extra_files),$(whitelist_patterns))) \
+ $(call maybe-print-list-and-error,$(unused_whitelist),$(INTERNAL_PRODUCT) includes redundant artifact path requirement whitelist entries.) \
+ ) \
+ )
+$(PRODUCT_OUT)/offending_artifacts.txt:
+ rm -f $@
+ $(foreach f,$(sort $(all_offending_files)),echo $(f) >> $@;)
else
# We're not doing a full build, and are probably only including
# a subset of the module makefiles. Don't try to build any modules
@@ -961,43 +1029,6 @@
product_FILES :=
endif
-# Transforms paths relative to PRODUCT_OUT to absolute paths.
-# $(1): list of relative paths
-# $(2): optional suffix to append to paths
-define resolve-product-relative-paths
- $(subst $(_vendor_path_placeholder),$(TARGET_COPY_OUT_VENDOR),\
- $(subst $(_product_path_placeholder),$(TARGET_COPY_OUT_PRODUCT),\
- $(foreach p,$(1),$(PRODUCT_OUT)/$(p)$(2))))
-endef
-
-# Verify the artifact path requirements made by included products.
-$(foreach makefile,$(ARTIFACT_PATH_REQUIREMENT_PRODUCTS),\
- $(eval requirements := $(PRODUCTS.$(makefile).ARTIFACT_PATH_REQUIREMENTS)) \
- $(eval ### Verify that the product only produces files inside its path requirements.) \
- $(eval whitelist := $(PRODUCTS.$(makefile).ARTIFACT_PATH_WHITELIST)) \
- $(eval path_patterns := $(call resolve-product-relative-paths,$(requirements),%)) \
- $(eval whitelist_patterns := $(call resolve-product-relative-paths,$(whitelist))) \
- $(eval files := $(call product-installed-files, $(makefile))) \
- $(eval files += $(foreach cf,$(PRODUCTS.$(makefile).PRODUCT_COPY_FILES),\
- $(call append-path,$(PRODUCT_OUT),$(call word-colon,2,$(cf))))) \
- $(eval files := $(filter-out $(TARGET_OUT_FAKE)/% $(HOST_OUT)/%,$(files))) \
- $(eval offending_files := $(filter-out $(path_patterns) $(whitelist_patterns),$(files))) \
- $(call maybe-print-list-and-error,$(offending_files),$(makefile) produces files outside its artifact path requirement.) \
- $(eval unused_whitelist := $(filter-out $(files),$(whitelist_patterns))) \
- $(call maybe-print-list-and-error,$(unused_whitelist),$(makefile) includes redundant whitelist entries in its artifact path requirement.) \
- $(eval ### Optionally verify that nothing else produces files inside this artifact path requirement.) \
- $(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS),\
- $(eval extra_files := $(filter-out $(files) $(HOST_OUT)/%,$(product_FILES))) \
- $(eval whitelist := $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_ARTIFACT_PATH_REQUIREMENT_WHITELIST)) \
- $(eval whitelist_patterns := $(call resolve-product-relative-paths,$(whitelist))) \
- $(eval files_in_requirement := $(filter $(path_patterns),$(extra_files))) \
- $(eval offending_files := $(filter-out $(whitelist_patterns),$(files_in_requirement))) \
- $(call maybe-print-list-and-error,$(offending_files),$(INTERNAL_PRODUCT) produces files inside $(makefile)s artifact path requirement.) \
- $(eval unused_whitelist := $(filter-out $(extra_files),$(whitelist_patterns))) \
- $(call maybe-print-list-and-error,$(unused_whitelist),$(INTERNAL_PRODUCT) includes redundant artifact path requirement whitelist entries.) \
- ) \
-)
-
ifeq (0,1)
$(info product_FILES for $(TARGET_DEVICE) ($(INTERNAL_PRODUCT)):)
$(foreach p,$(product_FILES),$(info : $(p)))
@@ -1164,9 +1195,15 @@
.PHONY: productimage
productimage: $(INSTALLED_PRODUCTIMAGE_TARGET)
+.PHONY: productservicesimage
+productservicesimage: $(INSTALLED_PRODUCT_SERVICESIMAGE_TARGET)
+
.PHONY: systemotherimage
systemotherimage: $(INSTALLED_SYSTEMOTHERIMAGE_TARGET)
+.PHONY: superimage
+superimage: $(INSTALLED_SUPERIMAGE_TARGET)
+
.PHONY: bootimage
bootimage: $(INSTALLED_BOOTIMAGE_TARGET)
@@ -1195,6 +1232,8 @@
$(INSTALLED_FILES_JSON_VENDOR) \
$(INSTALLED_FILES_FILE_PRODUCT) \
$(INSTALLED_FILES_JSON_PRODUCT) \
+ $(INSTALLED_FILES_FILE_PRODUCT_SERVICES) \
+ $(INSTALLED_FILES_JSON_PRODUCT_SERVICES) \
$(INSTALLED_FILES_FILE_SYSTEMOTHER) \
$(INSTALLED_FILES_JSON_SYSTEMOTHER) \
soong_docs
@@ -1259,12 +1298,15 @@
$(BUILT_OTATOOLS_PACKAGE) \
$(SYMBOLS_ZIP) \
$(COVERAGE_ZIP) \
+ $(APPCOMPAT_ZIP) \
$(INSTALLED_FILES_FILE) \
$(INSTALLED_FILES_JSON) \
$(INSTALLED_FILES_FILE_VENDOR) \
$(INSTALLED_FILES_JSON_VENDOR) \
$(INSTALLED_FILES_FILE_PRODUCT) \
$(INSTALLED_FILES_JSON_PRODUCT) \
+ $(INSTALLED_FILES_FILE_PRODUCT_SERVICES) \
+ $(INSTALLED_FILES_JSON_PRODUCT_SERVICES) \
$(INSTALLED_FILES_FILE_SYSTEMOTHER) \
$(INSTALLED_FILES_JSON_SYSTEMOTHER) \
$(INSTALLED_BUILD_PROP_TARGET) \
@@ -1312,26 +1354,6 @@
# Building a full system-- the default is to build droidcore
droid_targets: droidcore dist_files
-ifdef USE_LOGICAL_PARTITIONS
-ifdef BOARD_SUPER_PARTITION_SIZE
-ifdef BOARD_SUPER_PARTITION_PARTITION_LIST
-
-droid_targets: check_android_partition_sizes
-
-.PHONY: check_android_partition_sizes
-check_android_partition_sizes: partition_size_list=$(foreach p,$(BOARD_SUPER_PARTITION_PARTITION_LIST),$(BOARD_$(call to-upper,$(p))IMAGE_PARTITION_SIZE))
-check_android_partition_sizes: sum_sizes_expr=$(subst $(space),+,$(partition_size_list))
-check_android_partition_sizes:
- if [ $$(( $(sum_sizes_expr) )) -gt $(BOARD_SUPER_PARTITION_SIZE) ]; then \
- echo The sum of sizes of all logical partitions is larger than BOARD_SUPER_PARTITION_SIZE.; \
- echo $(sum_sizes_expr) == $$(( $(sum_sizes_expr) )) '>' $(BOARD_SUPER_PARTITION_SIZE); \
- exit 1; \
- fi
-
-endif # BOARD_SUPER_PARTITION_PARTITION_LIST
-endif # BOARD_SUPER_PARTITION_SIZE
-endif # USE_LOGICAL_PARTITIONS
-
endif # TARGET_BUILD_APPS
.PHONY: docs
@@ -1344,13 +1366,15 @@
$(ALL_SDK_TARGETS) \
$(SYMBOLS_ZIP) \
$(COVERAGE_ZIP) \
+ $(APPCOMPAT_ZIP) \
$(INSTALLED_BUILD_PROP_TARGET) \
)
# umbrella targets to assit engineers in verifying builds
.PHONY: java native target host java-host java-target native-host native-target \
java-host-tests java-target-tests native-host-tests native-target-tests \
- java-tests native-tests host-tests target-tests tests java-dex
+ java-tests native-tests host-tests target-tests tests java-dex \
+ native-host-cross
# some synonyms
.PHONY: host-java target-java host-native target-native \
target-java-tests target-native-tests
@@ -1405,4 +1429,6 @@
ndk: $(SOONG_OUT_DIR)/ndk.timestamp
.PHONY: ndk
+$(info [$(call inc_and_print,subdir_makefiles_inc)/$(subdir_makefiles_total)] writing build rules ...)
+
endif # KATI
diff --git a/core/native_test_config_template.xml b/core/native_test_config_template.xml
index a960529..a88d57c 100644
--- a/core/native_test_config_template.xml
+++ b/core/native_test_config_template.xml
@@ -15,6 +15,8 @@
-->
<!-- This test config file is auto-generated. -->
<configuration description="Runs {MODULE}.">
+ <option name="test-suite-tag" value="apct" />
+ <option name="test-suite-tag" value="apct-native" />
<target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
<option name="cleanup" value="true" />
<option name="push" value="{MODULE}->/data/local/tmp/{MODULE}" />
diff --git a/core/package_internal.mk b/core/package_internal.mk
index 637a135..acb128c 100644
--- a/core/package_internal.mk
+++ b/core/package_internal.mk
@@ -118,6 +118,8 @@
enforce_rro_enabled :=
else ifeq (true,$(LOCAL_PRODUCT_MODULE))
enforce_rro_enabled :=
+ else ifeq (true,$(LOCAL_PRODUCT_SERVICES_MODULE))
+ enforce_rro_enabled :=
endif
else ifeq ($(filter $(TARGET_OUT)/%,$(LOCAL_MODULE_PATH)),)
enforce_rro_enabled :=
@@ -590,6 +592,22 @@
endif
endif
+# Run veridex on product, product-services and vendor modules.
+# We skip it for unbundled app builds where we cannot build veridex.
+module_run_appcompat :=
+ifeq (true,$(filter true, \
+ $(LOCAL_PRODUCT_MODULE) $(LOCAL_PRODUCT_SERVICES_MODULE) \
+ $(LOCAL_VENDOR_MODULE) $(LOCAL_PROPRIETARY_MODULE)))
+ifeq (,$(TARGET_BUILD_APPS)$(filter true,$(TARGET_BUILD_PDK))) # ! unbundled app build
+ module_run_appcompat := true
+endif
+endif
+
+ifeq ($(module_run_appcompat),true)
+$(LOCAL_BUILT_MODULE) : $(call intermediates-dir-for,PACKAGING,veridex,HOST)/veridex.zip
+$(LOCAL_BUILT_MODULE): PRIVATE_INSTALLED_MODULE := $(LOCAL_INSTALLED_MODULE)
+endif
+
$(LOCAL_BUILT_MODULE): PRIVATE_DONT_DELETE_JAR_DIRS := $(LOCAL_DONT_DELETE_JAR_DIRS)
$(LOCAL_BUILT_MODULE): PRIVATE_RESOURCE_INTERMEDIATES_DIR := $(intermediates.COMMON)/resources
$(LOCAL_BUILT_MODULE): PRIVATE_FULL_CLASSES_JAR := $(full_classes_jar)
@@ -630,6 +648,15 @@
@# No need to align, sign-package below will do it.
$(uncompress-dexs)
endif
+# Run appcompat before stripping the classes.dex file.
+ifeq ($(module_run_appcompat),true)
+ifeq ($(LOCAL_USE_AAPT2),true)
+ $(call appcompat-header, aapt2)
+else
+ $(appcompat-header)
+endif
+ $(run-appcompat)
+endif # module_run_appcompat
ifdef LOCAL_DEX_PREOPT
ifneq ($(BUILD_PLATFORM_ZIP),)
@# Keep a copy of apk with classes.dex unstripped
diff --git a/core/prebuilt_internal.mk b/core/prebuilt_internal.mk
index c635ca5..a4bf055 100644
--- a/core/prebuilt_internal.mk
+++ b/core/prebuilt_internal.mk
@@ -95,6 +95,17 @@
prebuilt_module_is_dex_javalib :=
endif
+# Run veridex on product, product-services and vendor modules.
+# We skip it for unbundled app builds where we cannot build veridex.
+module_run_appcompat :=
+ifeq (true,$(filter true, \
+ $(LOCAL_PRODUCT_MODULE) $(LOCAL_PRODUCT_SERVICES_MODULE) \
+ $(LOCAL_VENDOR_MODULE) $(LOCAL_PROPRIETARY_MODULE)))
+ifeq (,$(TARGET_BUILD_APPS)$(filter true,$(TARGET_BUILD_PDK))) # ! unbundled app build
+ module_run_appcompat := true
+endif
+endif
+
ifdef LOCAL_COMPRESSED_MODULE
ifneq (true,$(LOCAL_COMPRESSED_MODULE))
$(call pretty-error, Unknown value for LOCAL_COMPRESSED_MODULE $(LOCAL_COMPRESSED_MODULE))
@@ -376,6 +387,11 @@
$(built_module) : $(MINIGZIP)
endif
+ifeq ($(module_run_appcompat),true)
+$(built_module) : $(call intermediates-dir-for,PACKAGING,veridex,HOST)/veridex.zip
+$(LOCAL_BUILT_MODULE): PRIVATE_INSTALLED_MODULE := $(LOCAL_INSTALLED_MODULE)
+endif
+
$(built_module) : $(my_prebuilt_src_file) | $(ZIPALIGN) $(SIGNAPK_JAR)
$(transform-prebuilt-to-target)
$(uncompress-shared-libs)
@@ -390,6 +406,15 @@
endif # LOCAL_DEX_PREOPT
ifneq ($(LOCAL_CERTIFICATE),PRESIGNED)
@# Only strip out files if we can re-sign the package.
+# Run appcompat before stripping the classes.dex file.
+ifeq ($(module_run_appcompat),true)
+ifeq ($(LOCAL_USE_AAPT2),true)
+ $(call appcompat-header, aapt2)
+else
+ $(appcompat-header)
+endif
+ $(run-appcompat)
+endif # module_run_appcompat
ifdef LOCAL_DEX_PREOPT
ifneq (nostripping,$(LOCAL_DEX_PREOPT))
$(call dexpreopt-remove-classes.dex,$@)
@@ -667,7 +692,7 @@
$(my_exported_sdk_libs_file):
@echo "Export SDK libs $@"
$(hide) mkdir -p $(dir $@) && rm -f $@
- $(if $(PRIATE_EXPORTED_SDK_LIBS),\
+ $(if $(PRIVATE_EXPORTED_SDK_LIBS),\
$(hide) echo $(PRIVATE_EXPORTED_SDK_LIBS) | tr ' ' '\n' > $@,\
$(hide) touch $@)
diff --git a/core/product-graph.mk b/core/product-graph.mk
index 4133bd9..696aabf 100644
--- a/core/product-graph.mk
+++ b/core/product-graph.mk
@@ -105,6 +105,7 @@
$(hide) echo 'PRODUCT_DEFAULT_PROPERTY_OVERRIDES=$$(PRODUCTS.$(strip $(1)).PRODUCT_DEFAULT_PROPERTY_OVERRIDES)' >> $$@
$(hide) echo 'PRODUCT_SYSTEM_DEFAULT_PROPERTIES=$$(PRODUCTS.$(strip $(1)).PRODUCT_SYSTEM_DEFAULT_PROPERTIES)' >> $$@
$(hide) echo 'PRODUCT_PRODUCT_PROPERTIES=$$(PRODUCTS.$(strip $(1)).PRODUCT_PRODUCT_PROPERTIES)' >> $$@
+ $(hide) echo 'PRODUCT_PRODUCT_SERVICES_PROPERTIES=$$(PRODUCTS.$(strip $(1)).PRODUCT_PRODUCT_SERVICES_PROPERTIES)' >> $$@
$(hide) echo 'PRODUCT_CHARACTERISTICS=$$(PRODUCTS.$(strip $(1)).PRODUCT_CHARACTERISTICS)' >> $$@
$(hide) echo 'PRODUCT_COPY_FILES=$$(PRODUCTS.$(strip $(1)).PRODUCT_COPY_FILES)' >> $$@
$(hide) echo 'PRODUCT_OTA_PUBLIC_KEYS=$$(PRODUCTS.$(strip $(1)).PRODUCT_OTA_PUBLIC_KEYS)' >> $$@
@@ -144,3 +145,4 @@
dot -Tsvg -Nshape=box -o $@ $<
product-graph: $(products_pdf) $(products_svg)
+.PHONY: product-graph
diff --git a/core/product.mk b/core/product.mk
index 51b376a..ddf774f 100644
--- a/core/product.mk
+++ b/core/product.mk
@@ -128,6 +128,7 @@
PRODUCT_PROPERTY_OVERRIDES \
PRODUCT_DEFAULT_PROPERTY_OVERRIDES \
PRODUCT_PRODUCT_PROPERTIES \
+ PRODUCT_PRODUCT_SERVICES_PROPERTIES \
PRODUCT_CHARACTERISTICS \
PRODUCT_COPY_FILES \
PRODUCT_OTA_PUBLIC_KEYS \
@@ -167,6 +168,7 @@
PRODUCT_SYSTEM_VERITY_PARTITION \
PRODUCT_VENDOR_VERITY_PARTITION \
PRODUCT_PRODUCT_VERITY_PARTITION \
+ PRODUCT_PRODUCT_SERVICES_VERITY_PARTITION \
PRODUCT_SYSTEM_SERVER_DEBUG_INFO \
PRODUCT_OTHER_JAVA_DEBUG_INFO \
PRODUCT_DEX_PREOPT_MODULE_CONFIGS \
@@ -182,6 +184,7 @@
PRODUCT_SYSTEM_BASE_FS_PATH \
PRODUCT_VENDOR_BASE_FS_PATH \
PRODUCT_PRODUCT_BASE_FS_PATH \
+ PRODUCT_PRODUCT_SERVICES_BASE_FS_PATH \
PRODUCT_SHIPPING_API_LEVEL \
VENDOR_PRODUCT_RESTRICT_VENDOR_FILES \
VENDOR_EXCEPTION_MODULES \
@@ -200,6 +203,9 @@
PRODUCT_USE_LOGICAL_PARTITIONS \
PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS \
PRODUCT_ARTIFACT_PATH_REQUIREMENT_WHITELIST \
+ PRODUCT_USE_DYNAMIC_PARTITION_SIZE \
+ PRODUCT_BUILD_SUPER_PARTITION \
+ PRODUCT_USE_FASTBOOTD \
define dump-product
$(info ==== $(1) ====)\
@@ -378,6 +384,8 @@
BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE \
BOARD_PRODUCTIMAGE_PARTITION_SIZE \
BOARD_PRODUCTIMAGE_FILE_SYSTEM_TYPE \
+ BOARD_PRODUCT_SERVICESIMAGE_PARTITION_SIZE \
+ BOARD_PRODUCT_SERVICESIMAGE_FILE_SYSTEM_TYPE \
BOARD_INSTALLER_CMDLINE \
@@ -390,6 +398,8 @@
_product_stash_var_list += \
BOARD_SYSTEMIMAGE_PARTITION_RESERVED_SIZE \
BOARD_VENDORIMAGE_PARTITION_RESERVED_SIZE \
+ BOARD_PRODUCTIMAGE_PARTITION_RESERVED_SIZE \
+ BOARD_PRODUCT_SERVICESIMAGE_PARTITION_RESERVED_SIZE \
BOARD_SUPER_PARTITION_SIZE \
BOARD_SUPER_PARTITION_PARTITION_LIST \
diff --git a/core/product_config.mk b/core/product_config.mk
index 8425b09..b5f2896 100644
--- a/core/product_config.mk
+++ b/core/product_config.mk
@@ -373,6 +373,14 @@
$(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PRODUCT_PROPERTIES))
.KATI_READONLY := PRODUCT_PRODUCT_PROPERTIES
+
+# A list of property assignments, like "key = value", with zero or more
+# whitespace characters on either side of the '='.
+# used for adding properties to build.prop of product partition
+PRODUCT_PRODUCT_SERVICES_PROPERTIES := \
+ $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PRODUCT_SERVICES_PROPERTIES))
+.KATI_READONLY := PRODUCT_PRODUCT_SERVICES_PROPERTIES
+
# Should we use the default resources or add any product specific overlays
PRODUCT_PACKAGE_OVERLAYS := \
$(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PACKAGE_OVERLAYS))
@@ -511,3 +519,18 @@
PRODUCT_USE_LOGICAL_PARTITIONS := \
$(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_USE_LOGICAL_PARTITIONS))
.KATI_READONLY := PRODUCT_USE_LOGICAL_PARTITIONS
+
+# All requirements of PRODUCT_USE_LOGICAL_PARTITIONS falls back to
+# PRODUCT_USE_LOGICAL_PARTITIONS if not defined.
+PRODUCT_USE_DYNAMIC_PARTITION_SIZE := $(or \
+ $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_USE_DYNAMIC_PARTITION_SIZE)),\
+ $(PRODUCT_USE_LOGICAL_PARTITIONS))
+.KATI_READONLY := PRODUCT_USE_DYNAMIC_PARTITION_SIZE
+PRODUCT_BUILD_SUPER_PARTITION := $(or \
+ $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_BUILD_SUPER_PARTITION)),\
+ $(PRODUCT_USE_LOGICAL_PARTITIONS))
+.KATI_READONLY := PRODUCT_BUILD_SUPER_PARTITION
+PRODUCT_USE_FASTBOOTD := $(or \
+ $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_USE_FASTBOOTD)),\
+ $(PRODUCT_USE_LOGICAL_PARTITIONS))
+.KATI_READONLY := PRODUCT_USE_FASTBOOTD
diff --git a/core/soong_config.mk b/core/soong_config.mk
index f75e263..914b7f9 100644
--- a/core/soong_config.mk
+++ b/core/soong_config.mk
@@ -133,6 +133,7 @@
$(call add_json_str, VendorPath, $(TARGET_COPY_OUT_VENDOR))
$(call add_json_str, OdmPath, $(TARGET_COPY_OUT_ODM))
$(call add_json_str, ProductPath, $(TARGET_COPY_OUT_PRODUCT))
+$(call add_json_str, ProductServicesPath, $(TARGET_COPY_OUT_PRODUCT_SERVICES))
$(call add_json_bool, MinimizeJavaDebugInfo, $(filter true,$(PRODUCT_MINIMIZE_JAVA_DEBUG_INFO)))
$(call add_json_bool, UseGoma, $(filter-out false,$(USE_GOMA)))
diff --git a/core/soong_java_prebuilt.mk b/core/soong_java_prebuilt.mk
index ef71107..44b4f5c 100644
--- a/core/soong_java_prebuilt.mk
+++ b/core/soong_java_prebuilt.mk
@@ -19,6 +19,7 @@
full_classes_pre_proguard_jar := $(intermediates.COMMON)/classes-pre-proguard.jar
full_classes_header_jar := $(intermediates.COMMON)/classes-header.jar
common_javalib.jar := $(intermediates.COMMON)/javalib.jar
+greylist_txt := $(intermediates.COMMON)/greylist.txt
$(eval $(call copy-one-file,$(LOCAL_PREBUILT_MODULE_FILE),$(full_classes_jar)))
$(eval $(call copy-one-file,$(LOCAL_PREBUILT_MODULE_FILE),$(full_classes_pre_proguard_jar)))
@@ -33,6 +34,10 @@
$(call dist-for-goals,docs,$(OUT_DOCS)/$(LOCAL_MODULE)-docs.zip)
endif
+ifdef LOCAL_DROIDDOC_ANNOTATIONS_ZIP
+$(eval $(call copy-one-file,$(LOCAL_DROIDDOC_ANNOTATIONS_ZIP),$(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/$(LOCAL_MODULE)_annotations.zip))
+endif
+
ifdef LOCAL_SOONG_JACOCO_REPORT_CLASSES_JAR
$(eval $(call copy-one-file,$(LOCAL_SOONG_JACOCO_REPORT_CLASSES_JAR),\
$(intermediates.COMMON)/jacoco-report-classes.jar))
@@ -82,6 +87,11 @@
ifneq ($(LOCAL_UNINSTALLABLE_MODULE),true)
ifndef LOCAL_IS_HOST_MODULE
ifneq ($(filter $(LOCAL_MODULE),$(PRODUCT_BOOT_JARS)),) # is_boot_jar
+ # Derive greylist from classes.jar.
+ # We use full_classes_jar here, which is the post-proguard jar (on the basis that we also
+ # have a full_classes_pre_proguard_jar). This is consistent with the equivalent code in
+ # java.mk.
+ $(eval $(call hiddenapi-generate-greylist-txt,$(full_classes_jar),$(greylist_txt)))
$(eval $(call hiddenapi-copy-soong-jar,$(LOCAL_SOONG_DEX_JAR),$(common_javalib.jar)))
else # !is_boot_jar
$(eval $(call copy-one-file,$(LOCAL_SOONG_DEX_JAR),$(common_javalib.jar)))
@@ -131,6 +141,7 @@
javac-check : $(full_classes_jar)
javac-check-$(LOCAL_MODULE) : $(full_classes_jar)
+.PHONY: javac-check-$(LOCAL_MODULE)
ifndef LOCAL_IS_HOST_MODULE
ifeq ($(LOCAL_SDK_VERSION),system_current)
diff --git a/core/tasks/tools/compatibility.mk b/core/tasks/tools/compatibility.mk
index 6117414..34ac1d0 100644
--- a/core/tasks/tools/compatibility.mk
+++ b/core/tasks/tools/compatibility.mk
@@ -48,6 +48,7 @@
$(compatibility_zip): $(test_artifacts) $(test_tools) $(test_suite_prebuilt_tools) $(test_suite_dynamic_config) $(SOONG_ZIP) | $(ADB) $(ACP)
# Make dir structure
$(hide) mkdir -p $(PRIVATE_OUT_DIR)/tools $(PRIVATE_OUT_DIR)/testcases
+ $(hide) echo $(BUILD_NUMBER_FROM_FILE) > $(PRIVATE_OUT_DIR)/tools/version.txt
# Copy tools
$(hide) $(ACP) -fp $(PRIVATE_TOOLS) $(PRIVATE_OUT_DIR)/tools
$(if $(PRIVATE_DYNAMIC_CONFIG),$(hide) $(ACP) -fp $(PRIVATE_DYNAMIC_CONFIG) $(PRIVATE_OUT_DIR)/testcases/$(PRIVATE_SUITE_NAME).dynamic)
diff --git a/core/tasks/vndk.mk b/core/tasks/vndk.mk
index ba48df7..9420638 100644
--- a/core/tasks/vndk.mk
+++ b/core/tasks/vndk.mk
@@ -23,19 +23,6 @@
# BOARD_VNDK_RUNTIME_DISABLE must not be set to 'true'.
ifneq ($(BOARD_VNDK_RUNTIME_DISABLE),true)
-# Returns arch-specific libclang_rt.ubsan* library name.
-# Because VNDK_CORE_LIBRARIES includes all arch variants for libclang_rt.ubsan*
-# libs, the arch-specific libs are selected separately.
-#
-# Args:
-# $(1): if not empty, evaluates for TARGET_2ND_ARCH
-define clang-ubsan-vndk-core
-$(strip \
- $(eval prefix := $(if $(1),2ND_,)) \
- $(addsuffix .vendor,$($(addprefix $(prefix),UBSAN_RUNTIME_LIBRARY))) \
-)
-endef
-
# Returns list of src:dest paths of the intermediate objs
#
# Args:
@@ -70,20 +57,7 @@
$(if $(notice),$(notice):$(subst .vendor,,$(lib)).so.txt)))
endef
-# If in the future libclang_rt.ubsan* is removed from the VNDK-core list,
-# need to update the related logic in this file.
-ifeq (,$(filter libclang_rt.ubsan%,$(VNDK_CORE_LIBRARIES)))
- $(warning libclang_rt.ubsan* is no longer a VNDK-core library. Please update this file.)
- vndk_core_libs := $(addsuffix .vendor,$(VNDK_CORE_LIBRARIES))
-else
- vndk_core_libs := $(addsuffix .vendor,$(filter-out libclang_rt.ubsan%,$(VNDK_CORE_LIBRARIES)))
-
- vndk_core_libs += $(call clang-ubsan-vndk-core)
- ifdef TARGET_2ND_ARCH
- vndk_core_libs += $(call clang-ubsan-vndk-core,true)
- endif
-endif
-
+vndk_core_libs := $(addsuffix .vendor,$(VNDK_CORE_LIBRARIES))
vndk_sp_libs := $(addsuffix .vendor,$(VNDK_SAMEPROCESS_LIBRARIES))
vndk_private_libs := $(addsuffix .vendor,$(VNDK_PRIVATE_LIBRARIES))
@@ -145,8 +119,10 @@
# vndk_snapshot_zip
vndk_snapshot_variant := $(vndk_snapshot_out)/$(TARGET_ARCH)
binder :=
-ifneq ($(TARGET_USES_64_BIT_BINDER), true)
- binder := binder32
+ifneq ($(TARGET_IS_64_BIT), true)
+ ifneq ($(TARGET_USES_64_BIT_BINDER), true)
+ binder := binder32
+ endif
endif
vndk_lib_dir := $(subst $(space),/,$(strip $(vndk_snapshot_variant) $(binder) arch-$(TARGET_ARCH)-$(TARGET_ARCH_VARIANT)))
vndk_lib_dir_2nd := $(subst $(space),/,$(strip $(vndk_snapshot_variant) $(binder) arch-$(TARGET_2ND_ARCH)-$(TARGET_2ND_ARCH_VARIANT)))
diff --git a/envsetup.sh b/envsetup.sh
index 12168e1..5894144 100644
--- a/envsetup.sh
+++ b/envsetup.sh
@@ -48,12 +48,12 @@
{
local T=$(gettop)
# Grep out the variable names from the script.
- cached_vars=`cat $T/build/envsetup.sh | tr '()' ' ' | awk '{for(i=1;i<=NF;i++) if($i~/get_build_var/) print $(i+1)}' | sort -u | tr '\n' ' '`
- cached_abs_vars=`cat $T/build/envsetup.sh | tr '()' ' ' | awk '{for(i=1;i<=NF;i++) if($i~/get_abs_build_var/) print $(i+1)}' | sort -u | tr '\n' ' '`
+ cached_vars=(`cat $T/build/envsetup.sh | tr '()' ' ' | awk '{for(i=1;i<=NF;i++) if($i~/get_build_var/) print $(i+1)}' | sort -u | tr '\n' ' '`)
+ cached_abs_vars=(`cat $T/build/envsetup.sh | tr '()' ' ' | awk '{for(i=1;i<=NF;i++) if($i~/get_abs_build_var/) print $(i+1)}' | sort -u | tr '\n' ' '`)
# Call the build system to dump the "<val>=<value>" pairs as a shell script.
build_dicts_script=`\builtin cd $T; build/soong/soong_ui.bash --dumpvars-mode \
- --vars="$cached_vars" \
- --abs-vars="$cached_abs_vars" \
+ --vars="${cached_vars[*]}" \
+ --abs-vars="${cached_abs_vars[*]}" \
--var-prefix=var_cache_ \
--abs-var-prefix=abs_var_cache_`
local ret=$?
@@ -317,11 +317,11 @@
# Takes a command name, and check if it's in ENVSETUP_NO_COMPLETION or not.
function should_add_completion() {
- local cmd="$1"
+ local cmd="$(basename $1| sed 's/_completion//' |sed 's/\.\(.*\)*sh$//')"
case :"$ENVSETUP_NO_COMPLETION": in
- *:"$cmd":*)
- return 1
- ;;
+ *:"$cmd":*)
+ return 1
+ ;;
esac
return 0
}
@@ -330,22 +330,27 @@
{
local T dir f
- # Keep us from trying to run in something that isn't bash.
- if [ -z "${BASH_VERSION}" ]; then
+ # Keep us from trying to run in something that's neither bash nor zsh.
+ if [ -z "$BASH_VERSION" -a -z "$ZSH_VERSION" ]; then
return
fi
# Keep us from trying to run in bash that's too old.
- if [ ${BASH_VERSINFO[0]} -lt 3 ]; then
+ if [ -n "$BASH_VERSION" -a ${BASH_VERSINFO[0]} -lt 3 ]; then
return
fi
+ local completion_files=(
+ system/core/adb/adb.bash
+ system/core/fastboot/fastboot.bash
+ tools/tradefederation/core/atest/atest_completion.sh
+ )
# Completion can be disabled selectively to allow users to use non-standard completion.
# e.g.
# ENVSETUP_NO_COMPLETION=adb # -> disable adb completion
# ENVSETUP_NO_COMPLETION=adb:bit # -> disable adb and bit completion
- for f in system/core/adb/adb.bash system/core/fastboot/fastboot.bash; do
- if [ -f "$f" ] && should_add_completion $(basename "$f" .bash) ; then
+ for f in ${completion_files[*]}; do
+ if [ -f "$f" ] && should_add_completion "$f"; then
. $f
fi
done
@@ -353,6 +358,7 @@
if should_add_completion bit ; then
complete -C "bit --tab" bit
fi
+ complete -F _lunch lunch
}
function choosetype()
@@ -646,7 +652,6 @@
COMPREPLY=( $(compgen -W "${COMMON_LUNCH_CHOICES_CACHE}" -- ${cur}) )
return 0
}
-complete -F _lunch lunch
# Configures the build to build unbundled apps.
# Run tapas with one or more app names (from LOCAL_PACKAGE_NAME)
@@ -1562,24 +1567,37 @@
"$(gettop)"/tools/tradefederation/core/atest/atest.py "$@"
}
-if [ "x$SHELL" != "x/bin/bash" ]; then
- case `ps -o command -p $$` in
+# Zsh needs bashcompinit called to support bash-style completion.
+function add_zsh_completion() {
+ autoload -U compinit && compinit
+ autoload -U bashcompinit && bashcompinit
+}
+
+function validate_current_shell() {
+ local current_sh="$(ps -o command -p $$)"
+ case "$current_sh" in
*bash*)
+ function check_type() { type -t "$1"; }
;;
+ *zsh*)
+ function check_type() { type "$1"; }
+ add_zsh_completion ;;
*)
- echo "WARNING: Only bash is supported, use of other shell would lead to erroneous results"
+ echo -e "WARNING: Only bash and zsh are supported.\nUse of other shell would lead to erroneous results."
;;
esac
-fi
+}
# Execute the contents of any vendorsetup.sh files we can find.
-for f in `test -d device && find -L device -maxdepth 4 -name 'vendorsetup.sh' 2> /dev/null | sort` \
- `test -d vendor && find -L vendor -maxdepth 4 -name 'vendorsetup.sh' 2> /dev/null | sort` \
- `test -d product && find -L product -maxdepth 4 -name 'vendorsetup.sh' 2> /dev/null | sort`
-do
- echo "including $f"
- . $f
-done
-unset f
+function source_vendorsetup() {
+ for dir in device vendor product; do
+ for f in $(test -d $dir && \
+ find -L $dir -maxdepth 4 -name 'vendorsetup.sh' 2>/dev/null | sort); do
+ echo "including $f"; . $f
+ done
+ done
+}
+validate_current_shell
+source_vendorsetup
addcompletions
diff --git a/help.sh b/help.sh
index c143542..ad22253 100755
--- a/help.sh
+++ b/help.sh
@@ -40,6 +40,8 @@
Stands for "Vendor, NO Dependencies"
pnod Quickly rebuild the product image from built packages
Stands for "Product, NO Dependencies"
+ psnod Quickly rebuild the product-services image from built packages
+ Stands for "ProductServices, NO Dependencies"
So, for example, you could run:
diff --git a/target/board/BoardConfigEmuCommon.mk b/target/board/BoardConfigEmuCommon.mk
index 1d58eab..e8a562a 100644
--- a/target/board/BoardConfigEmuCommon.mk
+++ b/target/board/BoardConfigEmuCommon.mk
@@ -11,9 +11,6 @@
BOARD_USES_GENERIC_AUDIO := true
TARGET_BOOTLOADER_BOARD_NAME := goldfish_$(TARGET_ARCH)
-TARGET_USES_64_BIT_BINDER := true
-TARGET_USES_MKE2FS := true
-
# no hardware camera
USE_CAMERA_STUB := true
@@ -29,22 +26,14 @@
USE_OPENGL_RENDERER := true
TARGET_COPY_OUT_VENDOR := vendor
+
# ~100 MB vendor image. Please adjust system image / vendor image sizes
# when finalizing them.
BOARD_VENDORIMAGE_PARTITION_SIZE := 100000000
BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE := ext4
BOARD_FLASH_BLOCK_SIZE := 512
-TARGET_USERIMAGES_SPARSE_EXT_DISABLED := true
DEVICE_MATRIX_FILE := device/generic/goldfish/compatibility_matrix.xml
-# Android generic system image always create metadata partition
-BOARD_USES_METADATA_PARTITION := true
-
-# Set this to create /cache mount point for non-A/B devices that mounts /cache.
-# The partition size doesn't matter, just to make build pass.
-BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE := ext4
-BOARD_CACHEIMAGE_PARTITION_SIZE := 16777216
-
BOARD_SEPOLICY_DIRS += device/generic/goldfish/sepolicy/common
BOARD_PROPERTY_OVERRIDES_SPLIT_ENABLED := true
diff --git a/target/board/BoardConfigGsiCommon.mk b/target/board/BoardConfigGsiCommon.mk
index 237cd28..24614de 100644
--- a/target/board/BoardConfigGsiCommon.mk
+++ b/target/board/BoardConfigGsiCommon.mk
@@ -3,6 +3,13 @@
# Common compile-time definitions for GSI
#
+# system.img is always ext4 with sparse option
+TARGET_USERIMAGES_USE_EXT4 := true
+# TODO(b/63790380): emulator doesn't support sparse yet
+#TARGET_USERIMAGES_SPARSE_EXT_DISABLED := false
+TARGET_USERIMAGES_SPARSE_EXT_DISABLED := true
+TARGET_USES_MKE2FS := true
+
# Android Verified Boot (AVB):
# Builds a special vbmeta.img that disables AVB verification.
# Otherwise, AVB will prevent the device from booting the generic system.img.
@@ -20,9 +27,20 @@
endif
BOARD_VNDK_VERSION := current
-# Pi GSI supports system-as-root
+# system-as-root is mandatory from Android P
TARGET_NO_RECOVERY := true
BOARD_BUILD_SYSTEM_ROOT_IMAGE := true
+# 64 bits binder interface is mandatory from Android P
+TARGET_USES_64_BIT_BINDER := true
+
+# Android generic system image always create metadata partition
+BOARD_USES_METADATA_PARTITION := true
+
+# Set this to create /cache mount point for non-A/B devices that mounts /cache.
+# The partition size doesn't matter, just to make build pass.
+BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE := ext4
+BOARD_CACHEIMAGE_PARTITION_SIZE := 16777216
+
# Audio: must using XML format for Treblized devices
USE_XML_AUDIO_POLICY_CONF := 1
diff --git a/target/board/generic/BoardConfig.mk b/target/board/generic/BoardConfig.mk
index 38d294b..8113ae3 100644
--- a/target/board/generic/BoardConfig.mk
+++ b/target/board/generic/BoardConfig.mk
@@ -48,7 +48,6 @@
include build/make/target/board/BoardConfigEmuCommon.mk
include build/make/target/board/BoardConfigGsiCommon.mk
-TARGET_USERIMAGES_USE_EXT4 := true
# Partition size is default 1.5GB (1536MB) for 64 bits projects
BOARD_SYSTEMIMAGE_PARTITION_SIZE := 1610612736
BOARD_USERDATAIMAGE_PARTITION_SIZE := 576716800
diff --git a/target/board/generic_arm64/BoardConfig.mk b/target/board/generic_arm64/BoardConfig.mk
index 88f89de..ad6d229 100644
--- a/target/board/generic_arm64/BoardConfig.mk
+++ b/target/board/generic_arm64/BoardConfig.mk
@@ -55,7 +55,6 @@
include build/make/target/board/BoardConfigEmuCommon.mk
include build/make/target/board/BoardConfigGsiCommon.mk
-TARGET_USERIMAGES_USE_EXT4 := true
# Partition size is default 1.5GB (1536MB) for 64 bits projects
BOARD_SYSTEMIMAGE_PARTITION_SIZE := 1610612736
BOARD_USERDATAIMAGE_PARTITION_SIZE := 576716800
@@ -63,9 +62,10 @@
# Emulator system image is going to be used as GSI and some vendor still hasn't
# cleaned up all device specific directories under root!
-# TODO(jiyong) These might be SoC specific.
-BOARD_ROOT_EXTRA_FOLDERS += firmware firmware/radio persist
+# TODO(b/111434759, b/111287060) SoC specific hacks
BOARD_ROOT_EXTRA_SYMLINKS := /vendor/lib/dsp:/dsp
+BOARD_ROOT_EXTRA_SYMLINKS += /mnt/vendor/persist:/persist
+BOARD_ROOT_EXTRA_SYMLINKS += /vendor/firmware_mnt:/firmware
# TODO(b/36764215): remove this setting when the generic system image
# no longer has QCOM-specific directories under /.
diff --git a/target/board/generic_x86/BoardConfig.mk b/target/board/generic_x86/BoardConfig.mk
index 9a45188..c8ba2cf 100644
--- a/target/board/generic_x86/BoardConfig.mk
+++ b/target/board/generic_x86/BoardConfig.mk
@@ -23,6 +23,5 @@
include build/make/target/board/BoardConfigEmuCommon.mk
include build/make/target/board/BoardConfigGsiCommon.mk
-TARGET_USERIMAGES_USE_EXT4 := true
BOARD_SYSTEMIMAGE_PARTITION_SIZE := 2684354560
BOARD_USERDATAIMAGE_PARTITION_SIZE := 576716800
diff --git a/target/board/generic_x86_64/BoardConfig.mk b/target/board/generic_x86_64/BoardConfig.mk
index a24263d..1bae7f8 100755
--- a/target/board/generic_x86_64/BoardConfig.mk
+++ b/target/board/generic_x86_64/BoardConfig.mk
@@ -27,6 +27,5 @@
include build/make/target/board/BoardConfigEmuCommon.mk
include build/make/target/board/BoardConfigGsiCommon.mk
-TARGET_USERIMAGES_USE_EXT4 := true
BOARD_SYSTEMIMAGE_PARTITION_SIZE := 2684354560 # 2.5 GB
BOARD_USERDATAIMAGE_PARTITION_SIZE := 576716800
diff --git a/target/product/aosp_arm.mk b/target/product/aosp_arm.mk
index 8c8f407..a052b3a 100644
--- a/target/product/aosp_arm.mk
+++ b/target/product/aosp_arm.mk
@@ -14,6 +14,13 @@
# limitations under the License.
#
+# The system image of aosp_arm-userdebug is a GSI for the devices with:
+# - ARM 32 bits user space
+# - 64 bits binder interface
+# - system-as-root
+# - VNDK enforcement
+# - compatible property override enabled
+
PRODUCT_PROPERTY_OVERRIDES += \
rild.libpath=/vendor/lib/libreference-ril.so
@@ -27,6 +34,13 @@
include $(SRC_TARGET_DIR)/product/full.mk
+# Enable A/B update
+AB_OTA_UPDATER := true
+AB_OTA_PARTITIONS := system
+PRODUCT_PACKAGES += \
+ update_engine \
+ update_verifier
+
# Needed by Pi newly launched device to pass VtsTrebleSysProp on GSI
PRODUCT_COMPATIBLE_PROPERTY_OVERRIDE := true
diff --git a/target/product/aosp_arm64.mk b/target/product/aosp_arm64.mk
index aeff3f0..efbc300 100644
--- a/target/product/aosp_arm64.mk
+++ b/target/product/aosp_arm64.mk
@@ -14,6 +14,13 @@
# limitations under the License.
#
+# The system image of aosp_arm64-userdebug is a GSI for the devices with:
+# - ARM 64 bits user space
+# - 64 bits binder interface
+# - system-as-root
+# - VNDK enforcement
+# - compatible property override enabled
+
PRODUCT_PROPERTY_OVERRIDES += \
rild.libpath=/vendor/lib64/libreference-ril.so
@@ -44,6 +51,13 @@
include $(SRC_TARGET_DIR)/product/emulator.mk
+# Enable A/B update
+AB_OTA_UPDATER := true
+AB_OTA_PARTITIONS := system
+PRODUCT_PACKAGES += \
+ update_engine \
+ update_verifier
+
# Needed by Pi newly launched device to pass VtsTrebleSysProp on GSI
PRODUCT_COMPATIBLE_PROPERTY_OVERRIDE := true
diff --git a/target/product/aosp_arm64_ab.mk b/target/product/aosp_arm64_ab.mk
index c96cb91..d389c74 100644
--- a/target/product/aosp_arm64_ab.mk
+++ b/target/product/aosp_arm64_ab.mk
@@ -19,8 +19,14 @@
# on the generic system image, place them in build/make/target/board/
# treble_system.prop.
+# aosp_arm64_ab-userdebug is a Legacy GSI for the devices with:
+# - ARM 64 bits user space
+# - 64 bits binder interface
+# - system-as-root
+
include build/make/target/product/treble_common_64.mk
+# Enable A/B update
AB_OTA_UPDATER := true
AB_OTA_PARTITIONS := system
PRODUCT_PACKAGES += \
diff --git a/target/product/aosp_arm_ab.mk b/target/product/aosp_arm_ab.mk
index 98b2f99..5845d3b 100644
--- a/target/product/aosp_arm_ab.mk
+++ b/target/product/aosp_arm_ab.mk
@@ -19,8 +19,14 @@
# on the generic system image, place them in build/make/target/board/
# treble_system.prop.
+# aosp_arm_ab-userdebug is a Legacy GSI for the devices with:
+# - ARM 32 bits user space
+# - 32 bits binder interface
+# - system-as-root
+
include build/make/target/product/treble_common_32.mk
+# Enable A/B update
AB_OTA_UPDATER := true
AB_OTA_PARTITIONS := system
PRODUCT_PACKAGES += \
diff --git a/target/product/aosp_x86.mk b/target/product/aosp_x86.mk
index b044149..7929a3e 100644
--- a/target/product/aosp_x86.mk
+++ b/target/product/aosp_x86.mk
@@ -14,6 +14,13 @@
# limitations under the License.
#
+# The system image of aosp_x86-userdebug is a GSI for the devices with:
+# - x86 32 bits user space
+# - 64 bits binder interface
+# - system-as-root
+# - VNDK enforcement
+# - compatible property override enabled
+
PRODUCT_PROPERTY_OVERRIDES += \
rild.libpath=/vendor/lib/libreference-ril.so
@@ -28,6 +35,13 @@
include $(SRC_TARGET_DIR)/product/full_x86.mk
+# Enable A/B update
+AB_OTA_UPDATER := true
+AB_OTA_PARTITIONS := system
+PRODUCT_PACKAGES += \
+ update_engine \
+ update_verifier
+
# Needed by Pi newly launched device to pass VtsTrebleSysProp on GSI
PRODUCT_COMPATIBLE_PROPERTY_OVERRIDE := true
diff --git a/target/product/aosp_x86_64.mk b/target/product/aosp_x86_64.mk
index 4d2589e..5a934a9 100644
--- a/target/product/aosp_x86_64.mk
+++ b/target/product/aosp_x86_64.mk
@@ -14,6 +14,13 @@
# limitations under the License.
#
+# The system image of aosp_x86_64-userdebug is a GSI for the devices with:
+# - x86 64 bits user space
+# - 64 bits binder interface
+# - system-as-root
+# - VNDK enforcement
+# - compatible property override enabled
+
PRODUCT_PROPERTY_OVERRIDES += \
rild.libpath=/vendor/lib64/libreference-ril.so
@@ -41,6 +48,13 @@
include $(SRC_TARGET_DIR)/product/emulator.mk
+# Enable A/B update
+AB_OTA_UPDATER := true
+AB_OTA_PARTITIONS := system
+PRODUCT_PACKAGES += \
+ update_engine \
+ update_verifier
+
# Needed by Pi newly launched device to pass VtsTrebleSysProp on GSI
PRODUCT_COMPATIBLE_PROPERTY_OVERRIDE := true
diff --git a/target/product/aosp_x86_64_ab.mk b/target/product/aosp_x86_64_ab.mk
index 4590dc5..d9163d7 100644
--- a/target/product/aosp_x86_64_ab.mk
+++ b/target/product/aosp_x86_64_ab.mk
@@ -19,8 +19,14 @@
# on the generic system image, place them in build/make/target/board/
# treble_system.prop.
+# aosp_x86_64_ab-userdebug is a Legacy GSI for the devices with:
+# - x86 64 bits user space
+# - 64 bits binder interface
+# - system-as-root
+
include build/make/target/product/treble_common_64.mk
+# Enable A/B update
AB_OTA_UPDATER := true
AB_OTA_PARTITIONS := system
PRODUCT_PACKAGES += \
diff --git a/target/product/aosp_x86_ab.mk b/target/product/aosp_x86_ab.mk
index 404a4da..4fff3d1 100644
--- a/target/product/aosp_x86_ab.mk
+++ b/target/product/aosp_x86_ab.mk
@@ -19,8 +19,14 @@
# on the generic system image, place them in build/make/target/board/
# treble_system.prop.
+# aosp_x86_ab-userdebug is a Legacy GSI for the devices with:
+# - x86 32 bits user space
+# - 32 bits binder interface
+# - system-as-root
+
include build/make/target/product/treble_common_32.mk
+# Enable A/B update
AB_OTA_UPDATER := true
AB_OTA_PARTITIONS := system
PRODUCT_PACKAGES += \
diff --git a/target/product/base_system.mk b/target/product/base_system.mk
index 83c53b6..12cee24 100644
--- a/target/product/base_system.mk
+++ b/target/product/base_system.mk
@@ -241,13 +241,13 @@
voip-common \
vold \
WallpaperBackup \
+ watchdogd \
wificond \
wifi-service \
wm \
-# VINTF data
+# VINTF data for system image
PRODUCT_PACKAGES += \
- device_manifest.xml \
framework_manifest.xml \
framework_compatibility_matrix.xml \
@@ -291,7 +291,10 @@
procrank \
showmap \
sqlite3 \
- strace
+ strace \
+ unwind_info \
+ unwind_reg_info \
+ unwind_symbols \
# The set of packages whose code can be loaded by the system server.
PRODUCT_SYSTEM_SERVER_APPS += \
diff --git a/target/product/base_vendor.mk b/target/product/base_vendor.mk
index 681def2..4926a3f 100644
--- a/target/product/base_vendor.mk
+++ b/target/product/base_vendor.mk
@@ -21,13 +21,13 @@
linker.recovery \
recovery \
shell_and_utilities_recovery \
+ watchdogd.recovery \
# Base modules and settings for the vendor partition.
PRODUCT_PACKAGES += \
android.hardware.cas@1.0-service \
android.hardware.configstore@1.0-service \
android.hardware.media.omx@1.0-service \
- device_compatibility_matrix.xml \
fs_config_files_nonsystem \
fs_config_dirs_nonsystem \
gralloc.default \
@@ -48,3 +48,8 @@
shell_and_utilities_vendor \
vndservice \
vndservicemanager \
+
+# VINTF data for vendor image
+PRODUCT_PACKAGES += \
+ device_manifest.xml \
+ device_compatibility_matrix.xml \
diff --git a/target/product/mainline_arm64.mk b/target/product/mainline_arm64.mk
index 2dcca88..4c18dd3 100644
--- a/target/product/mainline_arm64.mk
+++ b/target/product/mainline_arm64.mk
@@ -24,4 +24,6 @@
PRODUCT_SHIPPING_API_LEVEL := 28
PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS := true
-PRODUCT_ARTIFACT_PATH_REQUIREMENT_WHITELIST := system/etc/seccomp_policy/mediacodec.policy
+PRODUCT_ARTIFACT_PATH_REQUIREMENT_WHITELIST := \
+ root/init.zygote64_32.rc \
+ system/etc/seccomp_policy/mediacodec.policy \
diff --git a/tools/releasetools/add_img_to_target_files.py b/tools/releasetools/add_img_to_target_files.py
index 8ac039f..fb4b882 100755
--- a/tools/releasetools/add_img_to_target_files.py
+++ b/tools/releasetools/add_img_to_target_files.py
@@ -72,10 +72,12 @@
OPTIONS.replace_verity_private_key = False
OPTIONS.is_signing = False
-
# Partitions that should have their care_map added to META/care_map.txt.
-PARTITIONS_WITH_CARE_MAP = ('system', 'vendor', 'product')
-
+PARTITIONS_WITH_CARE_MAP = ('system', 'vendor', 'product', 'product-services')
+# Use a fixed timestamp (01/01/2009 00:00:00 UTC) for files when packaging
+# images. (b/24377993, b/80600931)
+FIXED_FILE_TIMESTAMP = (datetime.datetime(2009, 1, 1, 0, 0, 0, 0, None)
+ - datetime.datetime.utcfromtimestamp(0)).total_seconds()
class OutputFile(object):
def __init__(self, output_zip, input_dir, prefix, name):
@@ -94,7 +96,6 @@
if self._output_zip:
common.ZipWrite(self._output_zip, self.name, self._zip_name)
-
def GetCareMap(which, imgname):
"""Returns the care_map string for the given partition.
@@ -196,6 +197,24 @@
return img.name
+def AddProductServices(output_zip):
+ """Turn the contents of PRODUCT-SERVICES into a product-services image and
+ store it in output_zip."""
+
+ img = OutputFile(output_zip, OPTIONS.input_tmp, "IMAGES",
+ "product-services.img")
+ if os.path.exists(img.input_name):
+ print("product-services.img already exists; no need to rebuild...")
+ return img.input_name
+
+ block_list = OutputFile(
+ output_zip, OPTIONS.input_tmp, "IMAGES", "product-services.map")
+ CreateImage(
+ OPTIONS.input_tmp, OPTIONS.info_dict, "product-services", img,
+ block_list=block_list)
+ return img.name
+
+
def AddDtbo(output_zip):
"""Adds the DTBO image.
@@ -241,11 +260,7 @@
if fstab and mount_point in fstab:
image_props["fs_type"] = fstab[mount_point].fs_type
- # Use a fixed timestamp (01/01/2009) when packaging the image.
- # Bug: 24377993
- epoch = datetime.datetime.fromtimestamp(0)
- timestamp = (datetime.datetime(2009, 1, 1) - epoch).total_seconds()
- image_props["timestamp"] = int(timestamp)
+ image_props["timestamp"] = FIXED_FILE_TIMESTAMP
if what == "system":
fs_config_prefix = ""
@@ -319,11 +334,7 @@
print("creating userdata.img...")
- # Use a fixed timestamp (01/01/2009) when packaging the image.
- # Bug: 24377993
- epoch = datetime.datetime.fromtimestamp(0)
- timestamp = (datetime.datetime(2009, 1, 1) - epoch).total_seconds()
- image_props["timestamp"] = int(timestamp)
+ image_props["timestamp"] = FIXED_FILE_TIMESTAMP
if OPTIONS.info_dict.get("userdata_img_with_data") == "true":
user_dir = os.path.join(OPTIONS.input_tmp, "DATA")
@@ -340,29 +351,26 @@
img.Write()
-def AppendVBMetaArgsForPartition(cmd, partition, img_path, public_key_dir):
- if not img_path:
- return
+def AppendVBMetaArgsForPartition(cmd, partition, image):
+ """Appends the VBMeta arguments for partition.
+ It sets up the VBMeta argument by including the partition descriptor from the
+ given 'image', or by configuring the partition as a chained partition.
+
+ Args:
+ cmd: A list of command args that will be used to generate the vbmeta image.
+ The argument for the partition will be appended to the list.
+ partition: The name of the partition (e.g. "system").
+ image: The path to the partition image.
+ """
# Check if chain partition is used.
key_path = OPTIONS.info_dict.get("avb_" + partition + "_key_path")
if key_path:
- # extract public key in AVB format to be included in vbmeta.img
- avbtool = os.getenv('AVBTOOL') or OPTIONS.info_dict["avb_avbtool"]
- public_key_path = os.path.join(public_key_dir, "%s.avbpubkey" % partition)
- p = common.Run([avbtool, "extract_public_key", "--key", key_path,
- "--output", public_key_path],
- stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- p.communicate()
- assert p.returncode == 0, \
- "avbtool extract_public_key fail for partition: %r" % partition
-
- rollback_index_location = OPTIONS.info_dict[
- "avb_" + partition + "_rollback_index_location"]
- cmd.extend(["--chain_partition", "%s:%s:%s" % (
- partition, rollback_index_location, public_key_path)])
+ chained_partition_arg = common.GetAvbChainedPartitionArg(
+ partition, OPTIONS.info_dict)
+ cmd.extend(["--chain_partition", chained_partition_arg])
else:
- cmd.extend(["--include_descriptors_from_image", img_path])
+ cmd.extend(["--include_descriptors_from_image", image])
def AddVBMeta(output_zip, partitions):
@@ -371,8 +379,8 @@
Args:
output_zip: The output zip file, which needs to be already open.
partitions: A dict that's keyed by partition names with image paths as
- values. Only valid partition names are accepted, which include 'boot',
- 'recovery', 'system', 'vendor', 'dtbo'.
+ values. Only valid partition names are accepted, as listed in
+ common.AVB_PARTITIONS.
"""
img = OutputFile(output_zip, OPTIONS.input_tmp, "IMAGES", "vbmeta.img")
if os.path.exists(img.input_name):
@@ -383,13 +391,12 @@
cmd = [avbtool, "make_vbmeta_image", "--output", img.name]
common.AppendAVBSigningArgs(cmd, "vbmeta")
- public_key_dir = common.MakeTempDir(prefix="avbpubkey-")
for partition, path in partitions.items():
- assert partition in common.AVB_PARTITIONS, 'Unknown partition: %s' % (
- partition,)
- assert os.path.exists(path), 'Failed to find %s for partition %s' % (
- path, partition)
- AppendVBMetaArgsForPartition(cmd, partition, path, public_key_dir)
+ assert partition in common.AVB_PARTITIONS, \
+ 'Unknown partition: {}'.format(partition)
+ assert os.path.exists(path), \
+ 'Failed to find {} for {}'.format(path, partition)
+ AppendVBMetaArgsForPartition(cmd, partition, path)
args = OPTIONS.info_dict.get("avb_vbmeta_args")
if args and args.strip():
@@ -469,11 +476,7 @@
print("creating cache.img...")
- # Use a fixed timestamp (01/01/2009) when packaging the image.
- # Bug: 24377993
- epoch = datetime.datetime.fromtimestamp(0)
- timestamp = (datetime.datetime(2009, 1, 1) - epoch).total_seconds()
- image_props["timestamp"] = int(timestamp)
+ image_props["timestamp"] = FIXED_FILE_TIMESTAMP
user_dir = common.MakeTempDir()
@@ -628,16 +631,22 @@
has_recovery = OPTIONS.info_dict.get("no_recovery") != "true"
- # {vendor,product}.img is unlike system.img or system_other.img. Because it
- # could be built from source, or dropped into target_files.zip as a prebuilt
- # blob. We consider either of them as {vendor,product}.img being available,
- # which could be used when generating vbmeta.img for AVB.
+ # {vendor,product,product-services}.img are unlike system.img or
+ # system_other.img. Because it could be built from source, or dropped into
+ # target_files.zip as a prebuilt blob. We consider either of them as
+ # {vendor,product,product-services}.img being available, which could be
+ # used when generating vbmeta.img for AVB.
has_vendor = (os.path.isdir(os.path.join(OPTIONS.input_tmp, "VENDOR")) or
os.path.exists(os.path.join(OPTIONS.input_tmp, "IMAGES",
"vendor.img")))
has_product = (os.path.isdir(os.path.join(OPTIONS.input_tmp, "PRODUCT")) or
os.path.exists(os.path.join(OPTIONS.input_tmp, "IMAGES",
"product.img")))
+ has_product_services = (os.path.isdir(os.path.join(OPTIONS.input_tmp,
+ "PRODUCT-SERVICES")) or
+ os.path.exists(os.path.join(OPTIONS.input_tmp,
+ "IMAGES",
+ "product-services.img")))
has_system_other = os.path.isdir(os.path.join(OPTIONS.input_tmp,
"SYSTEM_OTHER"))
@@ -714,6 +723,10 @@
banner("product")
partitions['product'] = AddProduct(output_zip)
+ if has_product_services:
+ banner("product-services")
+ partitions['product-services'] = AddProductServices(output_zip)
+
if has_system_other:
banner("system_other")
AddSystemOther(output_zip)
diff --git a/tools/releasetools/blockimgdiff.py b/tools/releasetools/blockimgdiff.py
index e82e66a..c7d93d3 100644
--- a/tools/releasetools/blockimgdiff.py
+++ b/tools/releasetools/blockimgdiff.py
@@ -163,7 +163,7 @@
def RangeSha1(self, ranges):
h = sha1()
- for data in self._GetRangeData(ranges):
+ for data in self._GetRangeData(ranges): # pylint: disable=not-an-iterable
h.update(data)
return h.hexdigest()
@@ -177,7 +177,7 @@
return sha1(self.data).hexdigest()
def WriteRangeDataToFd(self, ranges, fd):
- for data in self._GetRangeData(ranges):
+ for data in self._GetRangeData(ranges): # pylint: disable=not-an-iterable
fd.write(data)
@@ -320,46 +320,45 @@
print(''.join([' {}\n'.format(name) for name in values]))
-# BlockImageDiff works on two image objects. An image object is
-# anything that provides the following attributes:
-#
-# blocksize: the size in bytes of a block, currently must be 4096.
-#
-# total_blocks: the total size of the partition/image, in blocks.
-#
-# care_map: a RangeSet containing which blocks (in the range [0,
-# total_blocks) we actually care about; i.e. which blocks contain
-# data.
-#
-# file_map: a dict that partitions the blocks contained in care_map
-# into smaller domains that are useful for doing diffs on.
-# (Typically a domain is a file, and the key in file_map is the
-# pathname.)
-#
-# clobbered_blocks: a RangeSet containing which blocks contain data
-# but may be altered by the FS. They need to be excluded when
-# verifying the partition integrity.
-#
-# ReadRangeSet(): a function that takes a RangeSet and returns the
-# data contained in the image blocks of that RangeSet. The data
-# is returned as a list or tuple of strings; concatenating the
-# elements together should produce the requested data.
-# Implementations are free to break up the data into list/tuple
-# elements in any way that is convenient.
-#
-# RangeSha1(): a function that returns (as a hex string) the SHA-1
-# hash of all the data in the specified range.
-#
-# TotalSha1(): a function that returns (as a hex string) the SHA-1
-# hash of all the data in the image (ie, all the blocks in the
-# care_map minus clobbered_blocks, or including the clobbered
-# blocks if include_clobbered_blocks is True).
-#
-# When creating a BlockImageDiff, the src image may be None, in which
-# case the list of transfers produced will never read from the
-# original image.
-
class BlockImageDiff(object):
+ """Generates the diff of two block image objects.
+
+ BlockImageDiff works on two image objects. An image object is anything that
+ provides the following attributes:
+
+ blocksize: the size in bytes of a block, currently must be 4096.
+
+ total_blocks: the total size of the partition/image, in blocks.
+
+ care_map: a RangeSet containing which blocks (in the range [0,
+ total_blocks) we actually care about; i.e. which blocks contain data.
+
+ file_map: a dict that partitions the blocks contained in care_map into
+ smaller domains that are useful for doing diffs on. (Typically a domain
+ is a file, and the key in file_map is the pathname.)
+
+ clobbered_blocks: a RangeSet containing which blocks contain data but may
+ be altered by the FS. They need to be excluded when verifying the
+ partition integrity.
+
+ ReadRangeSet(): a function that takes a RangeSet and returns the data
+ contained in the image blocks of that RangeSet. The data is returned as
+ a list or tuple of strings; concatenating the elements together should
+ produce the requested data. Implementations are free to break up the
+ data into list/tuple elements in any way that is convenient.
+
+ RangeSha1(): a function that returns (as a hex string) the SHA-1 hash of
+ all the data in the specified range.
+
+ TotalSha1(): a function that returns (as a hex string) the SHA-1 hash of
+ all the data in the image (ie, all the blocks in the care_map minus
+ clobbered_blocks, or including the clobbered blocks if
+ include_clobbered_blocks is True).
+
+ When creating a BlockImageDiff, the src image may be None, in which case the
+ list of transfers produced will never read from the original image.
+ """
+
def __init__(self, tgt, src=None, threads=None, version=4,
disable_imgdiff=False):
if threads is None:
diff --git a/tools/releasetools/build_image.py b/tools/releasetools/build_image.py
index 8e20859..5b46ab0 100755
--- a/tools/releasetools/build_image.py
+++ b/tools/releasetools/build_image.py
@@ -425,6 +425,52 @@
return base_fs_file if exit_code == 0 else None
+def SetUpInDirAndFsConfig(origin_in, prop_dict):
+ """Returns the in_dir and fs_config that should be used for image building.
+
+ If the target uses system_root_image and it's building system.img, it creates
+ and returns a staged dir that combines the contents of /system (i.e. in the
+ given in_dir) and root.
+
+ Args:
+ origin_in: Path to the input directory.
+ prop_dict: A property dict that contains info like partition size. Values
+ may be updated.
+
+ Returns:
+ A tuple of in_dir and fs_config that should be used to build the image.
+ """
+ fs_config = prop_dict.get("fs_config")
+ if (prop_dict.get("system_root_image") != "true" or
+ prop_dict["mount_point"] != "system"):
+ return origin_in, fs_config
+
+ # Construct a staging directory of the root file system.
+ in_dir = common.MakeTempDir()
+ root_dir = prop_dict.get("root_dir")
+ if root_dir:
+ shutil.rmtree(in_dir)
+ shutil.copytree(root_dir, in_dir, symlinks=True)
+ in_dir_system = os.path.join(in_dir, "system")
+ shutil.rmtree(in_dir_system, ignore_errors=True)
+ shutil.copytree(origin_in, in_dir_system, symlinks=True)
+
+ # Change the mount point to "/".
+ prop_dict["mount_point"] = "/"
+ if fs_config:
+ # We need to merge the fs_config files of system and root.
+ merged_fs_config = common.MakeTempFile(
+ prefix="merged_fs_config", suffix=".txt")
+ with open(merged_fs_config, "w") as fw:
+ if "root_fs_config" in prop_dict:
+ with open(prop_dict["root_fs_config"]) as fr:
+ fw.writelines(fr.readlines())
+ with open(fs_config) as fr:
+ fw.writelines(fr.readlines())
+ fs_config = merged_fs_config
+ return in_dir, fs_config
+
+
def CheckHeadroom(ext4fs_output, prop_dict):
"""Checks if there's enough headroom space available.
@@ -468,40 +514,25 @@
def BuildImage(in_dir, prop_dict, out_file, target_out=None):
- """Build an image to out_file from in_dir with property prop_dict.
- After the function call, values in prop_dict is updated with
- computed values.
+ """Builds an image for the files under in_dir and writes it to out_file.
+
+ When using system_root_image, it will additionally look for the files under
+ root (specified by 'root_dir') and builds an image that contains both sources.
Args:
- in_dir: path of input directory.
- prop_dict: property dictionary.
- out_file: path of the output image file.
- target_out: path of the product out directory to read device specific FS
- config files.
+ in_dir: Path to input directory.
+ prop_dict: A property dict that contains info like partition size. Values
+ will be updated with computed values.
+ out_file: The output image file.
+ target_out: Path to the TARGET_OUT directory as in Makefile. It actually
+ points to the /system directory under PRODUCT_OUT. fs_config (the one
+ under system/core/libcutils) reads device specific FS config files from
+ there.
Returns:
True iff the image is built successfully.
"""
- # system_root_image=true: build a system.img that combines the contents of
- # /system and the ramdisk, and can be mounted at the root of the file system.
- origin_in = in_dir
- fs_config = prop_dict.get("fs_config")
- if (prop_dict.get("system_root_image") == "true" and
- prop_dict["mount_point"] == "system"):
- in_dir = common.MakeTempDir()
- # Change the mount point to "/".
- prop_dict["mount_point"] = "/"
- if fs_config:
- # We need to merge the fs_config files of system and ramdisk.
- merged_fs_config = common.MakeTempFile(prefix="root_fs_config",
- suffix=".txt")
- with open(merged_fs_config, "w") as fw:
- if "ramdisk_fs_config" in prop_dict:
- with open(prop_dict["ramdisk_fs_config"]) as fr:
- fw.writelines(fr.readlines())
- with open(fs_config) as fr:
- fw.writelines(fr.readlines())
- fs_config = merged_fs_config
+ in_dir, fs_config = SetUpInDirAndFsConfig(in_dir, prop_dict)
build_command = []
fs_type = prop_dict.get("fs_type", "")
@@ -515,14 +546,14 @@
verity_supported = prop_dict.get("verity") == "true"
verity_fec_supported = prop_dict.get("verity_fec") == "true"
- if (prop_dict.get("use_logical_partitions") == "true" and
+ if (prop_dict.get("use_dynamic_partition_size") == "true" and
"partition_size" not in prop_dict):
# if partition_size is not defined, use output of `du' + reserved_size
- success, size = GetDiskUsage(origin_in)
+ success, size = GetDiskUsage(in_dir)
if not success:
return False
if OPTIONS.verbose:
- print("The tree size of %s is %d MB." % (origin_in, size // BYTES_IN_MB))
+ print("The tree size of %s is %d MB." % (in_dir, size // BYTES_IN_MB))
size += int(prop_dict.get("partition_reserved_size", 0))
# Round this up to a multiple of 4K so that avbtool works
size = common.RoundUpTo4K(size)
@@ -643,31 +674,31 @@
print("Error: unknown filesystem type '%s'" % (fs_type))
return False
- if in_dir != origin_in:
- # Construct a staging directory of the root file system.
- ramdisk_dir = prop_dict.get("ramdisk_dir")
- if ramdisk_dir:
- shutil.rmtree(in_dir)
- shutil.copytree(ramdisk_dir, in_dir, symlinks=True)
- staging_system = os.path.join(in_dir, "system")
- shutil.rmtree(staging_system, ignore_errors=True)
- shutil.copytree(origin_in, staging_system, symlinks=True)
-
(mkfs_output, exit_code) = RunCommand(build_command)
if exit_code != 0:
print("Error: '%s' failed with exit code %d:\n%s" % (
build_command, exit_code, mkfs_output))
- success, du = GetDiskUsage(origin_in)
+ success, du = GetDiskUsage(in_dir)
du_str = ("%d bytes (%d MB)" % (du, du // BYTES_IN_MB)
) if success else "unknown"
- print("Out of space? The tree size of %s is %s." % (
- origin_in, du_str))
- print("The max is %d bytes (%d MB)." % (
- int(prop_dict["partition_size"]),
- int(prop_dict["partition_size"]) // BYTES_IN_MB))
- print("Reserved space is %d bytes (%d MB)." % (
- int(prop_dict.get("partition_reserved_size", 0)),
- int(prop_dict.get("partition_reserved_size", 0)) // BYTES_IN_MB))
+ print(
+ "Out of space? The tree size of {} is {}, with reserved space of {} "
+ "bytes ({} MB).".format(
+ in_dir, du_str,
+ int(prop_dict.get("partition_reserved_size", 0)),
+ int(prop_dict.get("partition_reserved_size", 0)) // BYTES_IN_MB))
+ if "original_partition_size" in prop_dict:
+ print(
+ "The max size for filsystem files is {} bytes ({} MB), out of a "
+ "total image size of {} bytes ({} MB).".format(
+ int(prop_dict["partition_size"]),
+ int(prop_dict["partition_size"]) // BYTES_IN_MB,
+ int(prop_dict["original_partition_size"]),
+ int(prop_dict["original_partition_size"]) // BYTES_IN_MB))
+ else:
+ print("The max image size is {} bytes ({} MB).".format(
+ int(prop_dict["partition_size"]),
+ int(prop_dict["partition_size"]) // BYTES_IN_MB))
return False
# Check if there's enough headroom space available for ext4 image.
@@ -714,7 +745,9 @@
# Run e2fsck on the inflated image file
e2fsck_command = ["e2fsck", "-f", "-n", unsparse_image]
- (e2fsck_output, exit_code) = RunCommand(e2fsck_command)
+ # TODO(b/112062612): work around e2fsck failure with SANITIZE_HOST=address
+ env4e2fsck = {"ASAN_OPTIONS": "detect_odr_violation=0"}
+ (e2fsck_output, exit_code) = RunCommand(e2fsck_command, env=env4e2fsck)
os.remove(unsparse_image)
@@ -768,7 +801,7 @@
"avb_enable",
"avb_avbtool",
"avb_salt",
- "use_logical_partitions",
+ "use_dynamic_partition_size",
)
for p in common_props:
copy_prop(p, p)
@@ -790,8 +823,8 @@
d["journal_size"] = "0"
copy_prop("system_verity_block_device", "verity_block_device")
copy_prop("system_root_image", "system_root_image")
- copy_prop("ramdisk_dir", "ramdisk_dir")
- copy_prop("ramdisk_fs_config", "ramdisk_fs_config")
+ copy_prop("root_dir", "root_dir")
+ copy_prop("root_fs_config", "root_fs_config")
copy_prop("ext4_share_dup_blocks", "ext4_share_dup_blocks")
copy_prop("system_squashfs_compressor", "squashfs_compressor")
copy_prop("system_squashfs_compressor_opt", "squashfs_compressor_opt")
@@ -875,6 +908,29 @@
copy_prop("product_extfs_inode_count", "extfs_inode_count")
if not copy_prop("product_extfs_rsv_pct", "extfs_rsv_pct"):
d["extfs_rsv_pct"] = "0"
+ copy_prop("product_reserved_size", "partition_reserved_size")
+ elif mount_point == "product-services":
+ copy_prop("avb_product_services_hashtree_enable", "avb_hashtree_enable")
+ copy_prop("avb_product_services_add_hashtree_footer_args",
+ "avb_add_hashtree_footer_args")
+ copy_prop("avb_product_services_key_path", "avb_key_path")
+ copy_prop("avb_product_services_algorithm", "avb_algorithm")
+ copy_prop("product_services_fs_type", "fs_type")
+ copy_prop("product_services_size", "partition_size")
+ if not copy_prop("product_services_journal_size", "journal_size"):
+ d["journal_size"] = "0"
+ copy_prop("product_services_verity_block_device", "verity_block_device")
+ copy_prop("product_services_squashfs_compressor", "squashfs_compressor")
+ copy_prop("product_services_squashfs_compressor_opt",
+ "squashfs_compressor_opt")
+ copy_prop("product_services_squashfs_block_size", "squashfs_block_size")
+ copy_prop("product_services_squashfs_disable_4k_align",
+ "squashfs_disable_4k_align")
+ copy_prop("product_services_base_fs_file", "base_fs_file")
+ copy_prop("product_services_extfs_inode_count", "extfs_inode_count")
+ if not copy_prop("product_services_extfs_rsv_pct", "extfs_rsv_pct"):
+ d["extfs_rsv_pct"] = "0"
+ copy_prop("product_services_reserved_size", "partition_reserved_size")
elif mount_point == "oem":
copy_prop("fs_type", "fs_type")
copy_prop("oem_size", "partition_size")
@@ -908,12 +964,22 @@
d[dest_p] = image_prop[src_p]
return True
return False
+
+ if "original_partition_size" in image_prop:
+ size_property = "original_partition_size"
+ else:
+ size_property = "partition_size"
+
if mount_point == "system":
- copy_prop("partition_size", "system_size")
+ copy_prop(size_property, "system_size")
elif mount_point == "system_other":
- copy_prop("partition_size", "system_size")
+ copy_prop(size_property, "system_size")
elif mount_point == "vendor":
- copy_prop("partition_size", "vendor_size")
+ copy_prop(size_property, "vendor_size")
+ elif mount_point == "product":
+ copy_prop(size_property, "product_size")
+ elif mount_point == "product-services":
+ copy_prop(size_property, "product_services_size")
return d
@@ -955,6 +1021,8 @@
mount_point = "oem"
elif image_filename == "product.img":
mount_point = "product"
+ elif image_filename == "product-services.img":
+ mount_point = "product-services"
else:
print("error: unknown image file name ", image_filename, file=sys.stderr)
sys.exit(1)
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index 364d6ac..89b4037 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -44,7 +44,7 @@
"darwin": "out/host/darwin-x86",
}
- self.search_path = platform_search_path.get(sys.platform, None)
+ self.search_path = platform_search_path.get(sys.platform)
self.signapk_path = "framework/signapk.jar" # Relative to search_path
self.signapk_shared_library_path = "lib64" # Relative to search_path
self.extra_signapk_args = []
@@ -78,7 +78,8 @@
# The partitions allowed to be signed by AVB (Android verified boot 2.0).
-AVB_PARTITIONS = ('boot', 'recovery', 'system', 'vendor', 'product', 'dtbo')
+AVB_PARTITIONS = ('boot', 'recovery', 'system', 'vendor', 'product',
+ 'product-services', 'dtbo')
class ErrorCode(object):
@@ -195,10 +196,10 @@
if fc_config:
d["selinux_fc"] = fc_config
- # Similarly we need to redirect "ramdisk_dir" and "ramdisk_fs_config".
+ # Similarly we need to redirect "root_dir" and "root_fs_config".
if d.get("system_root_image") == "true":
- d["ramdisk_dir"] = os.path.join(input_dir, "ROOT")
- d["ramdisk_fs_config"] = os.path.join(
+ d["root_dir"] = os.path.join(input_dir, "ROOT")
+ d["root_fs_config"] = os.path.join(
input_dir, "META", "root_filesystem_config.txt")
# Redirect {system,vendor}_base_fs_file.
@@ -236,15 +237,15 @@
makeint("boot_size")
makeint("fstab_version")
- system_root_image = d.get("system_root_image", None) == "true"
- if d.get("no_recovery", None) != "true":
+ system_root_image = d.get("system_root_image") == "true"
+ if d.get("no_recovery") != "true":
recovery_fstab_path = "RECOVERY/RAMDISK/etc/recovery.fstab"
- d["fstab"] = LoadRecoveryFSTab(read_helper, d["fstab_version"],
- recovery_fstab_path, system_root_image)
- elif d.get("recovery_as_boot", None) == "true":
+ d["fstab"] = LoadRecoveryFSTab(
+ read_helper, d["fstab_version"], recovery_fstab_path, system_root_image)
+ elif d.get("recovery_as_boot") == "true":
recovery_fstab_path = "BOOT/RAMDISK/etc/recovery.fstab"
- d["fstab"] = LoadRecoveryFSTab(read_helper, d["fstab_version"],
- recovery_fstab_path, system_root_image)
+ d["fstab"] = LoadRecoveryFSTab(
+ read_helper, d["fstab_version"], recovery_fstab_path, system_root_image)
else:
d["fstab"] = None
@@ -370,6 +371,40 @@
cmd.extend(["--salt", avb_salt])
+def GetAvbChainedPartitionArg(partition, info_dict, key=None):
+ """Constructs and returns the arg to build or verify a chained partition.
+
+ Args:
+ partition: The partition name.
+ info_dict: The info dict to look up the key info and rollback index
+ location.
+ key: The key to be used for building or verifying the partition. Defaults to
+ the key listed in info_dict.
+
+ Returns:
+ A string of form "partition:rollback_index_location:key" that can be used to
+ build or verify vbmeta image.
+
+ Raises:
+ AssertionError: When it fails to extract the public key with avbtool.
+ """
+ if key is None:
+ key = info_dict["avb_" + partition + "_key_path"]
+ avbtool = os.getenv('AVBTOOL') or info_dict["avb_avbtool"]
+ pubkey_path = MakeTempFile(prefix="avb-", suffix=".pubkey")
+ proc = Run(
+ [avbtool, "extract_public_key", "--key", key, "--output", pubkey_path],
+ stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+ stdoutdata, _ = proc.communicate()
+ assert proc.returncode == 0, \
+ "Failed to extract pubkey for {}:\n{}".format(
+ partition, stdoutdata)
+
+ rollback_index_location = info_dict[
+ "avb_" + partition + "_rollback_index_location"]
+ return "{}:{}:{}".format(partition, rollback_index_location, pubkey_path)
+
+
def _BuildBootableImage(sourcedir, fs_config_file, info_dict=None,
has_ramdisk=False, two_step_image=False):
"""Build a bootable image from the specified sourcedir.
@@ -440,11 +475,11 @@
cmd.append("--pagesize")
cmd.append(open(fn).read().rstrip("\n"))
- args = info_dict.get("mkbootimg_args", None)
+ args = info_dict.get("mkbootimg_args")
if args and args.strip():
cmd.extend(shlex.split(args))
- args = info_dict.get("mkbootimg_version_args", None)
+ args = info_dict.get("mkbootimg_version_args")
if args and args.strip():
cmd.extend(shlex.split(args))
@@ -452,7 +487,7 @@
cmd.extend(["--ramdisk", ramdisk_img.name])
img_unsigned = None
- if info_dict.get("vboot", None):
+ if info_dict.get("vboot"):
img_unsigned = tempfile.NamedTemporaryFile()
cmd.extend(["--output", img_unsigned.name])
else:
@@ -470,8 +505,8 @@
p.communicate()
assert p.returncode == 0, "mkbootimg of %s image failed" % (partition_name,)
- if (info_dict.get("boot_signer", None) == "true" and
- info_dict.get("verity_key", None)):
+ if (info_dict.get("boot_signer") == "true" and
+ info_dict.get("verity_key")):
# Hard-code the path as "/boot" for two-step special recovery image (which
# will be loaded into /boot during the two-step OTA).
if two_step_image:
@@ -488,7 +523,7 @@
assert p.returncode == 0, "boot_signer of %s image failed" % path
# Sign the image if vboot is non-empty.
- elif info_dict.get("vboot", None):
+ elif info_dict.get("vboot"):
path = "/" + partition_name
img_keyblock = tempfile.NamedTemporaryFile()
# We have switched from the prebuilt futility binary to using the tool
@@ -577,9 +612,9 @@
def Gunzip(in_filename, out_filename):
- """Gunzip the given gzip compressed file to a given output file.
- """
- with gzip.open(in_filename, "rb") as in_file, open(out_filename, "wb") as out_file:
+ """Gunzips the given gzip compressed file to a given output file."""
+ with gzip.open(in_filename, "rb") as in_file, \
+ open(out_filename, "wb") as out_file:
shutil.copyfileobj(in_file, out_file)
@@ -733,7 +768,7 @@
devnull.close()
key_passwords.update(PasswordManager().GetPasswords(need_passwords))
- key_passwords.update(dict.fromkeys(no_passwords, None))
+ key_passwords.update(dict.fromkeys(no_passwords))
return key_passwords
@@ -798,8 +833,7 @@
def SignFile(input_name, output_name, key, password, min_api_level=None,
- codename_to_api_level_map=dict(),
- whole_file=False):
+ codename_to_api_level_map=None, whole_file=False):
"""Sign the input_name zip/jar/apk, producing output_name. Use the
given key and password (the latter may be None if the key does not
have a password.
@@ -815,6 +849,8 @@
codename_to_api_level_map is needed to translate the codename which may be
encountered as the APK's minSdkVersion.
"""
+ if codename_to_api_level_map is None:
+ codename_to_api_level_map = {}
java_library_path = os.path.join(
OPTIONS.search_path, OPTIONS.signapk_shared_library_path)
@@ -876,7 +912,7 @@
device = p.device
if "/" in device:
device = device[device.rfind("/")+1:]
- limit = info_dict.get(device + "_size", None)
+ limit = info_dict.get(device + "_size")
if not fs_type or not limit:
return
@@ -1106,8 +1142,8 @@
class PasswordManager(object):
def __init__(self):
- self.editor = os.getenv("EDITOR", None)
- self.pwfile = os.getenv("ANDROID_PW_FILE", None)
+ self.editor = os.getenv("EDITOR")
+ self.pwfile = os.getenv("ANDROID_PW_FILE")
def GetPasswords(self, items):
"""Get passwords corresponding to each string in 'items',
@@ -1235,8 +1271,12 @@
os.chmod(filename, perms)
# Use a fixed timestamp so the output is repeatable.
- epoch = datetime.datetime.fromtimestamp(0)
- timestamp = (datetime.datetime(2009, 1, 1) - epoch).total_seconds()
+ # Note: Use of fromtimestamp rather than utcfromtimestamp here is
+ # intentional. zip stores datetimes in local time without a time zone
+ # attached, so we need "epoch" but in the local time zone to get 2009/01/01
+ # in the zip archive.
+ local_epoch = datetime.datetime.fromtimestamp(0)
+ timestamp = (datetime.datetime(2009, 1, 1) - local_epoch).total_seconds()
os.utime(filename, (timestamp, timestamp))
zip_file.write(filename, arcname=arcname, compress_type=compress_type)
@@ -1357,7 +1397,7 @@
module does not define the function, return the value of the
'default' kwarg (which itself defaults to None)."""
if self.module is None or not hasattr(self.module, function_name):
- return kwargs.get("default", None)
+ return kwargs.get("default")
return getattr(self.module, function_name)(*((self,) + args), **kwargs)
def FullOTA_Assertions(self):
@@ -1407,8 +1447,9 @@
def VerifyOTA_Assertions(self):
return self._DoCall("VerifyOTA_Assertions")
+
class File(object):
- def __init__(self, name, data, compress_size = None):
+ def __init__(self, name, data, compress_size=None):
self.name = name
self.data = data
self.size = len(data)
@@ -1435,6 +1476,7 @@
def AddToZip(self, z, compression=None):
ZipWriteStr(z, self.name, self.data, compress_type=compression)
+
DIFF_PROGRAM_BY_EXT = {
".gz" : "imgdiff",
".zip" : ["imgdiff", "-z"],
@@ -1443,6 +1485,7 @@
".img" : "imgdiff",
}
+
class Difference(object):
def __init__(self, tf, sf, diff_program=None):
self.tf = tf
@@ -1510,9 +1553,11 @@
def GetPatch(self):
- """Return a tuple (target_file, source_file, patch_data).
+ """Returns a tuple of (target_file, source_file, patch_data).
+
patch_data may be None if ComputePatch hasn't been called, or if
- computing the patch failed."""
+ computing the patch failed.
+ """
return self.tf, self.sf, self.patch
@@ -1544,7 +1589,8 @@
else:
name = "%s (%s)" % (tf.name, sf.name)
if patch is None:
- print("patching failed! %s" % (name,))
+ print(
+ "patching failed! %s" % (name,))
else:
print("%8.2f sec %8d / %8d bytes (%6.2f%%) %s" % (
dur, len(patch), tf.size, 100.0 * len(patch) / tf.size, name))
@@ -1597,7 +1643,8 @@
def required_cache(self):
return self._required_cache
- def WriteScript(self, script, output_zip, progress=None):
+ def WriteScript(self, script, output_zip, progress=None,
+ write_verify_script=False):
if not self.src:
# write the output unconditionally
script.Print("Patching %s image unconditionally..." % (self.partition,))
@@ -1607,7 +1654,8 @@
if progress:
script.ShowProgress(progress, 0)
self._WriteUpdate(script, output_zip)
- if OPTIONS.verify:
+
+ if write_verify_script:
self._WritePostInstallVerifyScript(script)
def WriteStrictVerifyScript(self, script):
@@ -1621,12 +1669,12 @@
script.Print("Verifying %s..." % (partition,))
ranges = self.tgt.care_map
ranges_str = ranges.to_string_raw()
- script.AppendExtra('range_sha1("%s", "%s") == "%s" && '
- 'ui_print(" Verified.") || '
- 'ui_print("\\"%s\\" has unexpected contents.");' % (
- self.device, ranges_str,
- self.tgt.TotalSha1(include_clobbered_blocks=True),
- self.device))
+ script.AppendExtra(
+ 'range_sha1("%s", "%s") == "%s" && ui_print(" Verified.") || '
+ 'ui_print("\\"%s\\" has unexpected contents.");' % (
+ self.device, ranges_str,
+ self.tgt.TotalSha1(include_clobbered_blocks=True),
+ self.device))
script.AppendExtra("")
def WriteVerifyScript(self, script, touched_blocks_only=False):
@@ -1650,12 +1698,12 @@
return
ranges_str = ranges.to_string_raw()
- script.AppendExtra(('if (range_sha1("%s", "%s") == "%s" || '
- 'block_image_verify("%s", '
- 'package_extract_file("%s.transfer.list"), '
- '"%s.new.dat", "%s.patch.dat")) then') % (
- self.device, ranges_str, expected_sha1,
- self.device, partition, partition, partition))
+ script.AppendExtra(
+ 'if (range_sha1("%s", "%s") == "%s" || block_image_verify("%s", '
+ 'package_extract_file("%s.transfer.list"), "%s.new.dat", '
+ '"%s.patch.dat")) then' % (
+ self.device, ranges_str, expected_sha1,
+ self.device, partition, partition, partition))
script.Print('Verified %s image...' % (partition,))
script.AppendExtra('else')
@@ -1705,17 +1753,19 @@
# Unlike pre-install verification, clobbered_blocks should not be ignored.
ranges = self.tgt.care_map
ranges_str = ranges.to_string_raw()
- script.AppendExtra('if range_sha1("%s", "%s") == "%s" then' % (
- self.device, ranges_str,
- self.tgt.TotalSha1(include_clobbered_blocks=True)))
+ script.AppendExtra(
+ 'if range_sha1("%s", "%s") == "%s" then' % (
+ self.device, ranges_str,
+ self.tgt.TotalSha1(include_clobbered_blocks=True)))
# Bug: 20881595
# Verify that extended blocks are really zeroed out.
if self.tgt.extended:
ranges_str = self.tgt.extended.to_string_raw()
- script.AppendExtra('if range_sha1("%s", "%s") == "%s" then' % (
- self.device, ranges_str,
- self._HashZeroBlocks(self.tgt.extended.size())))
+ script.AppendExtra(
+ 'if range_sha1("%s", "%s") == "%s" then' % (
+ self.device, ranges_str,
+ self._HashZeroBlocks(self.tgt.extended.size())))
script.Print('Verified the updated %s image.' % (partition,))
if partition == "system":
code = ErrorCode.SYSTEM_NONZERO_CONTENTS
@@ -1745,9 +1795,9 @@
'{}.transfer.list'.format(self.path),
'{}.transfer.list'.format(self.partition))
- # For full OTA, compress the new.dat with brotli with quality 6 to reduce its size. Quailty 9
- # almost triples the compression time but doesn't further reduce the size too much.
- # For a typical 1.8G system.new.dat
+ # For full OTA, compress the new.dat with brotli with quality 6 to reduce
+ # its size. Quailty 9 almost triples the compression time but doesn't
+ # further reduce the size too much. For a typical 1.8G system.new.dat
# zip | brotli(quality 6) | brotli(quality 9)
# compressed_size: 942M | 869M (~8% reduced) | 854M
# compression_time: 75s | 265s | 719s
@@ -1812,6 +1862,7 @@
DataImage = blockimgdiff.DataImage
+
# map recovery.fstab's fs_types to mount/format "partition types"
PARTITION_TYPES = {
"ext4": "EMMC",
@@ -1820,6 +1871,7 @@
"squashfs": "EMMC"
}
+
def GetTypeAndDevice(mount_point, info):
fstab = info["fstab"]
if fstab:
@@ -1914,7 +1966,7 @@
if os.path.exists(path):
diff_program.append("-b")
diff_program.append(path)
- bonus_args = "-b /system/etc/recovery-resource.dat"
+ bonus_args = "--bonus /system/etc/recovery-resource.dat"
else:
bonus_args = ""
@@ -1932,8 +1984,12 @@
if full_recovery_image:
sh = """#!/system/bin/sh
-if ! applypatch -c %(type)s:%(device)s:%(size)d:%(sha1)s; then
- applypatch /system/etc/recovery.img %(type)s:%(device)s %(sha1)s %(size)d && log -t recovery "Installing new recovery image: succeeded" || log -t recovery "Installing new recovery image: failed"
+if ! applypatch --check %(type)s:%(device)s:%(size)d:%(sha1)s; then
+ applypatch \\
+ --flash /system/etc/recovery.img \\
+ --target %(type)s:%(device)s:%(size)d:%(sha1)s && \\
+ log -t recovery "Installing new recovery image: succeeded" || \\
+ log -t recovery "Installing new recovery image: failed"
else
log -t recovery "Recovery image already installed"
fi
@@ -1943,8 +1999,13 @@
'size': recovery_img.size}
else:
sh = """#!/system/bin/sh
-if ! applypatch -c %(recovery_type)s:%(recovery_device)s:%(recovery_size)d:%(recovery_sha1)s; then
- applypatch %(bonus_args)s %(boot_type)s:%(boot_device)s:%(boot_size)d:%(boot_sha1)s %(recovery_type)s:%(recovery_device)s %(recovery_sha1)s %(recovery_size)d %(boot_sha1)s:/system/recovery-from-boot.p && log -t recovery "Installing new recovery image: succeeded" || log -t recovery "Installing new recovery image: failed"
+if ! applypatch --check %(recovery_type)s:%(recovery_device)s:%(recovery_size)d:%(recovery_sha1)s; then
+ applypatch %(bonus_args)s \\
+ --patch /system/recovery-from-boot.p \\
+ --source %(boot_type)s:%(boot_device)s:%(boot_size)d:%(boot_sha1)s \\
+ --target %(recovery_type)s:%(recovery_device)s:%(recovery_size)d:%(recovery_sha1)s && \\
+ log -t recovery "Installing new recovery image: succeeded" || \\
+ log -t recovery "Installing new recovery image: failed"
else
log -t recovery "Recovery image already installed"
fi
diff --git a/tools/releasetools/edify_generator.py b/tools/releasetools/edify_generator.py
index 5c3533e..3595a9e 100644
--- a/tools/releasetools/edify_generator.py
+++ b/tools/releasetools/edify_generator.py
@@ -132,8 +132,8 @@
self.script.append(
('(!less_than_int(%s, getprop("ro.build.date.utc"))) || '
'abort("E%d: Can\'t install this package (%s) over newer '
- 'build (" + getprop("ro.build.date") + ").");') % (timestamp,
- common.ErrorCode.OLDER_BUILD, timestamp_text))
+ 'build (" + getprop("ro.build.date") + ").");') % (
+ timestamp, common.ErrorCode.OLDER_BUILD, timestamp_text))
def AssertDevice(self, device):
"""Assert that the device identifier is the given string."""
@@ -260,8 +260,8 @@
cmd.append(',\0%s,\0package_extract_file("%s")' % patchpairs[i:i+2])
cmd.append(') ||\n abort("E%d: Failed to apply patch to %s");' % (
common.ErrorCode.APPLY_PATCH_FAILURE, srcfile))
- cmd = "".join(cmd)
- self.script.append(self.WordWrap(cmd))
+ cmd_str = "".join(cmd)
+ self.script.append(self.WordWrap(cmd_str))
def WriteRawImage(self, mount_point, fn, mapfn=None):
"""Write the given package file into the partition for the given
diff --git a/tools/releasetools/img_from_target_files.py b/tools/releasetools/img_from_target_files.py
index e6e8c9f..01ff149 100755
--- a/tools/releasetools/img_from_target_files.py
+++ b/tools/releasetools/img_from_target_files.py
@@ -28,17 +28,17 @@
from __future__ import print_function
+import os
+import shutil
import sys
+import zipfile
+
+import common
if sys.hexversion < 0x02070000:
print("Python 2.7 or newer is required.", file=sys.stderr)
sys.exit(1)
-import os
-import shutil
-import zipfile
-
-import common
OPTIONS = common.OPTIONS
@@ -51,11 +51,12 @@
def main(argv):
- bootable_only = [False]
+ # This allows modifying the value from inner function.
+ bootable_only_array = [False]
def option_handler(o, _):
if o in ("-z", "--bootable_zip"):
- bootable_only[0] = True
+ bootable_only_array[0] = True
else:
return False
return True
@@ -65,7 +66,7 @@
extra_long_opts=["bootable_zip"],
extra_option_handler=option_handler)
- bootable_only = bootable_only[0]
+ bootable_only = bootable_only_array[0]
if len(args) != 2:
common.Usage(__doc__)
diff --git a/tools/releasetools/ota_from_target_files.py b/tools/releasetools/ota_from_target_files.py
index 0e25c7e..8cfe4c3 100755
--- a/tools/releasetools/ota_from_target_files.py
+++ b/tools/releasetools/ota_from_target_files.py
@@ -697,17 +697,11 @@
if not HasTrebleEnabled(target_zip, target_info):
return
- # We don't support OEM thumbprint in Treble world (which calculates
- # fingerprints in a different way as shown in CalculateFingerprint()).
- assert not target_info.oem_props
-
# Full OTA carries the info for system/vendor both.
if source_info is None:
AddCompatibilityArchive(True, True)
return
- assert not source_info.oem_props
-
source_fp = source_info.fingerprint
target_fp = target_info.fingerprint
system_updated = source_fp != target_fp
@@ -833,7 +827,8 @@
allow_shared_blocks)
system_tgt.ResetFileMap()
system_diff = common.BlockDifference("system", system_tgt, src=None)
- system_diff.WriteScript(script, output_zip)
+ system_diff.WriteScript(script, output_zip,
+ write_verify_script=OPTIONS.verify)
boot_img = common.GetBootableImage(
"boot.img", "boot.img", OPTIONS.input_tmp, "BOOT")
@@ -845,7 +840,8 @@
allow_shared_blocks)
vendor_tgt.ResetFileMap()
vendor_diff = common.BlockDifference("vendor", vendor_tgt)
- vendor_diff.WriteScript(script, output_zip)
+ vendor_diff.WriteScript(script, output_zip,
+ write_verify_script=OPTIONS.verify)
AddCompatibilityArchiveIfTrebleEnabled(input_zip, output_zip, target_info)
@@ -1565,10 +1561,12 @@
device_specific.IncrementalOTA_InstallBegin()
system_diff.WriteScript(script, output_zip,
- progress=0.8 if vendor_diff else 0.9)
+ progress=0.8 if vendor_diff else 0.9,
+ write_verify_script=OPTIONS.verify)
if vendor_diff:
- vendor_diff.WriteScript(script, output_zip, progress=0.1)
+ vendor_diff.WriteScript(script, output_zip, progress=0.1,
+ write_verify_script=OPTIONS.verify)
if OPTIONS.two_step:
common.ZipWriteStr(output_zip, "boot.img", target_boot.data)
@@ -1657,9 +1655,15 @@
target_file = common.MakeTempFile(prefix="targetfiles-", suffix=".zip")
target_zip = zipfile.ZipFile(target_file, 'w', allowZip64=True)
- input_tmp = common.UnzipTemp(input_file, UNZIP_PATTERN)
with zipfile.ZipFile(input_file, 'r') as input_zip:
infolist = input_zip.infolist()
+ namelist = input_zip.namelist()
+
+ # Additionally unzip 'RADIO/*' if exists.
+ unzip_pattern = UNZIP_PATTERN[:]
+ if any([entry.startswith('RADIO/') for entry in namelist]):
+ unzip_pattern.append('RADIO/*')
+ input_tmp = common.UnzipTemp(input_file, unzip_pattern)
for info in infolist:
unzipped_file = os.path.join(input_tmp, *info.filename.split('/'))
@@ -1675,7 +1679,7 @@
elif skip_postinstall and info.filename == POSTINSTALL_CONFIG:
pass
- elif info.filename.startswith(('META/', 'IMAGES/')):
+ elif info.filename.startswith(('META/', 'IMAGES/', 'RADIO/')):
common.ZipWrite(target_zip, unzipped_file, arcname=info.filename)
common.ZipClose(target_zip)
diff --git a/tools/releasetools/pylintrc b/tools/releasetools/pylintrc
index 7b3405c..2a30742 100644
--- a/tools/releasetools/pylintrc
+++ b/tools/releasetools/pylintrc
@@ -62,7 +62,7 @@
# --enable=similarities". If you want to run only the classes checker, but have
# no Warning level messages displayed, use"--disable=all --enable=classes
# --disable=W"
-disable=invalid-name,missing-docstring,too-many-branches,too-many-locals,too-many-arguments,too-many-statements,duplicate-code,too-few-public-methods,too-many-instance-attributes,too-many-lines,too-many-public-methods,locally-disabled,fixme
+disable=invalid-name,missing-docstring,too-many-branches,too-many-locals,too-many-arguments,too-many-statements,duplicate-code,too-few-public-methods,too-many-instance-attributes,too-many-lines,too-many-public-methods,locally-disabled,fixme,not-callable
[REPORTS]
diff --git a/tools/releasetools/test_add_img_to_target_files.py b/tools/releasetools/test_add_img_to_target_files.py
index a9c7f7c..3f2e5ea 100644
--- a/tools/releasetools/test_add_img_to_target_files.py
+++ b/tools/releasetools/test_add_img_to_target_files.py
@@ -22,7 +22,8 @@
import common
import test_utils
from add_img_to_target_files import (
- AddCareMapTxtForAbOta, AddPackRadioImages, CheckAbOtaImages, GetCareMap)
+ AddCareMapTxtForAbOta, AddPackRadioImages, AppendVBMetaArgsForPartition,
+ CheckAbOtaImages, GetCareMap)
from rangelib import RangeSet
@@ -264,6 +265,31 @@
# The existing entry should be scheduled to be replaced.
self.assertIn('META/care_map.txt', OPTIONS.replace_updated_files_list)
+ def test_AppendVBMetaArgsForPartition(self):
+ OPTIONS.info_dict = {}
+ cmd = []
+ AppendVBMetaArgsForPartition(cmd, 'system', '/path/to/system.img')
+ self.assertEqual(
+ ['--include_descriptors_from_image', '/path/to/system.img'], cmd)
+
+ def test_AppendVBMetaArgsForPartition_vendorAsChainedPartition(self):
+ testdata_dir = test_utils.get_testdata_dir()
+ pubkey = os.path.join(testdata_dir, 'testkey.pubkey.pem')
+ OPTIONS.info_dict = {
+ 'avb_avbtool': 'avbtool',
+ 'avb_vendor_key_path': pubkey,
+ 'avb_vendor_rollback_index_location': 5,
+ }
+ cmd = []
+ AppendVBMetaArgsForPartition(cmd, 'vendor', '/path/to/vendor.img')
+ self.assertEqual(2, len(cmd))
+ self.assertEqual('--chain_partition', cmd[0])
+ chained_partition_args = cmd[1].split(':')
+ self.assertEqual(3, len(chained_partition_args))
+ self.assertEqual('vendor', chained_partition_args[0])
+ self.assertEqual('5', chained_partition_args[1])
+ self.assertTrue(os.path.exists(chained_partition_args[2]))
+
def test_GetCareMap(self):
sparse_image = test_utils.construct_sparse_image([
(0xCAC1, 6),
diff --git a/tools/releasetools/test_build_image.py b/tools/releasetools/test_build_image.py
index 161faff..19b5e08 100644
--- a/tools/releasetools/test_build_image.py
+++ b/tools/releasetools/test_build_image.py
@@ -14,10 +14,12 @@
# limitations under the License.
#
+import filecmp
+import os.path
import unittest
import common
-from build_image import CheckHeadroom, RunCommand
+from build_image import CheckHeadroom, RunCommand, SetUpInDirAndFsConfig
class BuildImageTest(unittest.TestCase):
@@ -26,6 +28,9 @@
EXT4FS_OUTPUT = (
"Created filesystem with 2777/129024 inodes and 515099/516099 blocks")
+ def tearDown(self):
+ common.Cleanup()
+
def test_CheckHeadroom_SizeUnderLimit(self):
# Required headroom: 1000 blocks.
prop_dict = {
@@ -91,4 +96,95 @@
}
self.assertFalse(CheckHeadroom(ext4fs_output, prop_dict))
- common.Cleanup()
+ def test_SetUpInDirAndFsConfig_SystemRootImageFalse(self):
+ prop_dict = {
+ 'fs_config': 'fs-config',
+ 'mount_point': 'system',
+ }
+ in_dir, fs_config = SetUpInDirAndFsConfig('/path/to/in_dir', prop_dict)
+ self.assertEqual('/path/to/in_dir', in_dir)
+ self.assertEqual('fs-config', fs_config)
+ self.assertEqual('system', prop_dict['mount_point'])
+
+ def test_SetUpInDirAndFsConfig_SystemRootImageTrue_NonSystem(self):
+ prop_dict = {
+ 'fs_config': 'fs-config',
+ 'mount_point': 'vendor',
+ 'system_root_image': 'true',
+ }
+ in_dir, fs_config = SetUpInDirAndFsConfig('/path/to/in_dir', prop_dict)
+ self.assertEqual('/path/to/in_dir', in_dir)
+ self.assertEqual('fs-config', fs_config)
+ self.assertEqual('vendor', prop_dict['mount_point'])
+
+ @staticmethod
+ def _gen_fs_config(partition):
+ fs_config = common.MakeTempFile(suffix='.txt')
+ with open(fs_config, 'w') as fs_config_fp:
+ fs_config_fp.write('fs-config-{}\n'.format(partition))
+ return fs_config
+
+ def test_SetUpInDirAndFsConfig_SystemRootImageTrue(self):
+ root_dir = common.MakeTempDir()
+ with open(os.path.join(root_dir, 'init'), 'w') as init_fp:
+ init_fp.write('init')
+
+ origin_in = common.MakeTempDir()
+ with open(os.path.join(origin_in, 'file'), 'w') as in_fp:
+ in_fp.write('system-file')
+ os.symlink('../etc', os.path.join(origin_in, 'symlink'))
+
+ fs_config_system = self._gen_fs_config('system')
+
+ prop_dict = {
+ 'fs_config': fs_config_system,
+ 'mount_point': 'system',
+ 'root_dir': root_dir,
+ 'system_root_image': 'true',
+ }
+ in_dir, fs_config = SetUpInDirAndFsConfig(origin_in, prop_dict)
+
+ self.assertTrue(filecmp.cmp(
+ os.path.join(in_dir, 'init'), os.path.join(root_dir, 'init')))
+ self.assertTrue(filecmp.cmp(
+ os.path.join(in_dir, 'system', 'file'),
+ os.path.join(origin_in, 'file')))
+ self.assertTrue(os.path.islink(os.path.join(in_dir, 'system', 'symlink')))
+
+ self.assertTrue(filecmp.cmp(fs_config_system, fs_config))
+ self.assertEqual('/', prop_dict['mount_point'])
+
+ def test_SetUpInDirAndFsConfig_SystemRootImageTrue_WithRootFsConfig(self):
+ root_dir = common.MakeTempDir()
+ with open(os.path.join(root_dir, 'init'), 'w') as init_fp:
+ init_fp.write('init')
+
+ origin_in = common.MakeTempDir()
+ with open(os.path.join(origin_in, 'file'), 'w') as in_fp:
+ in_fp.write('system-file')
+ os.symlink('../etc', os.path.join(origin_in, 'symlink'))
+
+ fs_config_system = self._gen_fs_config('system')
+ fs_config_root = self._gen_fs_config('root')
+
+ prop_dict = {
+ 'fs_config': fs_config_system,
+ 'mount_point': 'system',
+ 'root_dir': root_dir,
+ 'root_fs_config': fs_config_root,
+ 'system_root_image': 'true',
+ }
+ in_dir, fs_config = SetUpInDirAndFsConfig(origin_in, prop_dict)
+
+ self.assertTrue(filecmp.cmp(
+ os.path.join(in_dir, 'init'), os.path.join(root_dir, 'init')))
+ self.assertTrue(filecmp.cmp(
+ os.path.join(in_dir, 'system', 'file'),
+ os.path.join(origin_in, 'file')))
+ self.assertTrue(os.path.islink(os.path.join(in_dir, 'system', 'symlink')))
+
+ with open(fs_config) as fs_config_fp:
+ fs_config_data = fs_config_fp.readlines()
+ self.assertIn('fs-config-system\n', fs_config_data)
+ self.assertIn('fs-config-root\n', fs_config_data)
+ self.assertEqual('/', prop_dict['mount_point'])
diff --git a/tools/releasetools/test_common.py b/tools/releasetools/test_common.py
index 1c75d19..2a28db4 100644
--- a/tools/releasetools/test_common.py
+++ b/tools/releasetools/test_common.py
@@ -524,6 +524,9 @@
class CommonUtilsTest(unittest.TestCase):
+ def setUp(self):
+ self.testdata_dir = test_utils.get_testdata_dir()
+
def tearDown(self):
common.Cleanup()
@@ -730,6 +733,56 @@
AssertionError, common.GetSparseImage, 'system', tempdir, input_zip,
False)
+ def test_GetAvbChainedPartitionArg(self):
+ pubkey = os.path.join(self.testdata_dir, 'testkey.pubkey.pem')
+ info_dict = {
+ 'avb_avbtool': 'avbtool',
+ 'avb_system_key_path': pubkey,
+ 'avb_system_rollback_index_location': 2,
+ }
+ args = common.GetAvbChainedPartitionArg('system', info_dict).split(':')
+ self.assertEqual(3, len(args))
+ self.assertEqual('system', args[0])
+ self.assertEqual('2', args[1])
+ self.assertTrue(os.path.exists(args[2]))
+
+ def test_GetAvbChainedPartitionArg_withPrivateKey(self):
+ key = os.path.join(self.testdata_dir, 'testkey.key')
+ info_dict = {
+ 'avb_avbtool': 'avbtool',
+ 'avb_product_key_path': key,
+ 'avb_product_rollback_index_location': 2,
+ }
+ args = common.GetAvbChainedPartitionArg('product', info_dict).split(':')
+ self.assertEqual(3, len(args))
+ self.assertEqual('product', args[0])
+ self.assertEqual('2', args[1])
+ self.assertTrue(os.path.exists(args[2]))
+
+ def test_GetAvbChainedPartitionArg_withSpecifiedKey(self):
+ info_dict = {
+ 'avb_avbtool': 'avbtool',
+ 'avb_system_key_path': 'does-not-exist',
+ 'avb_system_rollback_index_location': 2,
+ }
+ pubkey = os.path.join(self.testdata_dir, 'testkey.pubkey.pem')
+ args = common.GetAvbChainedPartitionArg(
+ 'system', info_dict, pubkey).split(':')
+ self.assertEqual(3, len(args))
+ self.assertEqual('system', args[0])
+ self.assertEqual('2', args[1])
+ self.assertTrue(os.path.exists(args[2]))
+
+ def test_GetAvbChainedPartitionArg_invalidKey(self):
+ pubkey = os.path.join(self.testdata_dir, 'testkey_with_passwd.x509.pem')
+ info_dict = {
+ 'avb_avbtool': 'avbtool',
+ 'avb_system_key_path': pubkey,
+ 'avb_system_rollback_index_location': 2,
+ }
+ self.assertRaises(
+ AssertionError, common.GetAvbChainedPartitionArg, 'system', info_dict)
+
class InstallRecoveryScriptFormatTest(unittest.TestCase):
"""Checks the format of install-recovery.sh.
diff --git a/tools/releasetools/test_ota_from_target_files.py b/tools/releasetools/test_ota_from_target_files.py
index 7c34b7e..c8e6750 100644
--- a/tools/releasetools/test_ota_from_target_files.py
+++ b/tools/releasetools/test_ota_from_target_files.py
@@ -566,6 +566,8 @@
self.assertIn('IMAGES/boot.img', namelist)
self.assertIn('IMAGES/system.img', namelist)
self.assertIn('IMAGES/vendor.img', namelist)
+ self.assertIn('RADIO/bootloader.img', namelist)
+ self.assertIn('RADIO/modem.img', namelist)
self.assertIn(POSTINSTALL_CONFIG, namelist)
self.assertNotIn('IMAGES/system_other.img', namelist)
@@ -583,11 +585,33 @@
self.assertIn('IMAGES/boot.img', namelist)
self.assertIn('IMAGES/system.img', namelist)
self.assertIn('IMAGES/vendor.img', namelist)
+ self.assertIn('RADIO/bootloader.img', namelist)
+ self.assertIn('RADIO/modem.img', namelist)
self.assertNotIn('IMAGES/system_other.img', namelist)
self.assertNotIn('IMAGES/system.map', namelist)
self.assertNotIn(POSTINSTALL_CONFIG, namelist)
+ def test_GetTargetFilesZipForSecondaryImages_withoutRadioImages(self):
+ input_file = construct_target_files(secondary=True)
+ common.ZipDelete(input_file, 'RADIO/bootloader.img')
+ common.ZipDelete(input_file, 'RADIO/modem.img')
+ target_file = GetTargetFilesZipForSecondaryImages(input_file)
+
+ with zipfile.ZipFile(target_file) as verify_zip:
+ namelist = verify_zip.namelist()
+
+ self.assertIn('META/ab_partitions.txt', namelist)
+ self.assertIn('IMAGES/boot.img', namelist)
+ self.assertIn('IMAGES/system.img', namelist)
+ self.assertIn('IMAGES/vendor.img', namelist)
+ self.assertIn(POSTINSTALL_CONFIG, namelist)
+
+ self.assertNotIn('IMAGES/system_other.img', namelist)
+ self.assertNotIn('IMAGES/system.map', namelist)
+ self.assertNotIn('RADIO/bootloader.img', namelist)
+ self.assertNotIn('RADIO/modem.img', namelist)
+
def test_GetTargetFilesZipWithoutPostinstallConfig(self):
input_file = construct_target_files()
target_file = GetTargetFilesZipWithoutPostinstallConfig(input_file)
diff --git a/tools/releasetools/testdata/testkey.key b/tools/releasetools/testdata/testkey.key
new file mode 100644
index 0000000..3a84607
--- /dev/null
+++ b/tools/releasetools/testdata/testkey.key
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC+O/I7YvBaCZA3
+KrvP7ErTh6DS3cAvjLY2GkAA7NWcXIICsVwWMtMZAMO+Rtk/o3XY7r53Amg8ue2e
+b0D5Wc8gUVEeDQdRZJscz5CTwmC/b/YBWQBSPknWv23hf7ZYjR5HMk/XlmOfrylA
+oaZzJyKvLSBu+Zi9cvZlSZObnoOYR8JQJEhjYgYn8JwycV4i1VTQvEqxXkyW3kE7
+RW/8JXgRqI4vDIKehm5SFi2jt0eU7/ju/8f3OGQkLng4DV2QPfwQ+A7kad+EYVI1
+dBGYkNNesWB3o75A7jJQ1fyVg/XQzOKZSki1lrTm3rw0AOrBiXdPudbO+4L2vgip
+kPI9/bVNAgMBAAECggEABGjBSY0Wgw+7rvunlL8mUNbQ7HJFVRTO2FwtZZgXr2MZ
+hFR2DPGqoOa6ortjp6zzO071TS7aGaY5krWDbQQe3+Hinm6w37sUOUu6TyJvOaCv
+tAJLFpzo+zg+pL5gDJdgv0e0QAv1TSszKpNUl1Ct5h+Go+vXFXUHrvtQl4fKBwqA
+efxcd3R4z3p/3Cl2ZYIRz9I7UXUZZYwJE7bDNDz3aFZ1jUoELGmhe1O5w0hJY1q6
+PxuOM9bL60yDn0vu0eiCjaPlHeHyGe9pQ1aQLEuwQz9zpWC01dWPVkLmny7HDygC
+VBsdg8MNlzJQ1WV2en11BH72IqZ59U8pD0xEB7a4BQKBgQDxenfXyYZw4AKcaJlP
+ncJmsx/wcgEvWNxiI4etArXES4VIyP2OlSw+q9JbOOpaSk8TJP5PNfUkgTbC4B2y
+gh/AobJP5b7Wn5LrsHc3GY6CzF1i8T4xXQRxnaKWE86SOmZQlEmyCnpyCmfFVuaR
+E8p8CPW/gQLhpxSlQdGZ0bYLiwKBgQDJrJRDdyaI/Isusog/OwKHVGBU6CmRa5tM
+gx+GIlxheqhuDqnBkr0h1kL20Zi80JeG7vKWr+dwfqkEarfdTe+juwlIuQ3MEuXL
+AbsKNuaU1naOqOLm9rjZgRtR7oNLVH5AbkKMaJz1zM6YiMl54FEDX7ZVY8b6q1Kz
+YXT3sGi9hwKBgBsNa0ujagpPLjuzhCllNRgoTRW0z+kr/VSJQnPhb9eT1lS3H6DP
+mWtT+Hb7w1VmKcGtTUg2dUYnq6jdTrZm2YPNGZrV1DFbIyyAUnq7xDlnB7dD64HA
+N/U6gbJqeaPsIvY4BqGJhvorrEBxYdcy7mZC4rUXkOkSvL9exkqDMe/NAoGARaHU
+v0aQg5PO6pyx9kMFqHw1lptiXtdsk4pihAmxI+cZ6IYfjrp/mwNDs7zCo87RwsEV
++Xlay7iv2tqOCVczerDFj9p1LRUJSoKadfhmvNUfsjoVvfFJ+a9eI3fa1VOjE9P+
+HkSwjR3d50Sza+VLk4Kkje8ZcMtejpkDrdG3GFkCgYBXHqciwlFn5nMPFRe8v426
+6YBiUtzCQCZxDtMeeZYCJslFfjrqPXNUcU/flxWwaikjFsLJEtl7aT3Hpdi5I7T8
+yCYkUWqAAh7twEYTOeG6v/tEa/PmsBjZXPD2zkCp76EQmv3gbvsH4F/nA55gT/GR
+2in6XS/4rHBvjn5gF6MFyg==
+-----END PRIVATE KEY-----
diff --git a/tools/releasetools/validate_target_files.py b/tools/releasetools/validate_target_files.py
index 886de26..09f800f 100755
--- a/tools/releasetools/validate_target_files.py
+++ b/tools/releasetools/validate_target_files.py
@@ -131,14 +131,18 @@
1. full recovery:
...
- if ! applypatch -c type:device:size:SHA-1; then
- applypatch /system/etc/recovery.img type:device sha1 size && ...
+ if ! applypatch --check type:device:size:sha1; then
+ applypatch --flash /system/etc/recovery.img \\
+ type:device:size:sha1 && \\
...
2. recovery from boot:
...
- applypatch [-b bonus_args] boot_info recovery_info recovery_sha1 \
- recovery_size patch_info && ...
+ if ! applypatch --check type:recovery_device:recovery_size:recovery_sha1; then
+ applypatch [--bonus bonus_args] \\
+ --patch /system/recovery-from-boot.p \\
+ --source type:boot_device:boot_size:boot_sha1 \\
+ --target type:recovery_device:recovery_size:recovery_sha1 && \\
...
For full recovery, we want to calculate the SHA-1 of /system/etc/recovery.img
@@ -155,44 +159,63 @@
logging.info('Checking %s', script_path)
with open(os.path.join(input_tmp, script_path), 'r') as script:
lines = script.read().strip().split('\n')
- assert len(lines) >= 6
- check_cmd = re.search(r'if ! applypatch -c \w+:.+:\w+:(\w+);',
+ assert len(lines) >= 10
+ check_cmd = re.search(r'if ! applypatch --check (\w+:.+:\w+:\w+);',
lines[1].strip())
- expected_recovery_check_sha1 = check_cmd.group(1)
- patch_cmd = re.search(r'(applypatch.+)&&', lines[2].strip())
- applypatch_argv = patch_cmd.group(1).strip().split()
+ check_partition = check_cmd.group(1)
+ assert len(check_partition.split(':')) == 4
full_recovery_image = info_dict.get("full_recovery_image") == "true"
if full_recovery_image:
- assert len(applypatch_argv) == 5
- # Check we have the same expected SHA-1 of recovery.img in both check mode
- # and patch mode.
- expected_recovery_sha1 = applypatch_argv[3].strip()
- assert expected_recovery_check_sha1 == expected_recovery_sha1
- ValidateFileAgainstSha1(input_tmp, 'recovery.img',
- 'SYSTEM/etc/recovery.img', expected_recovery_sha1)
- else:
- # We're patching boot.img to get recovery.img where bonus_args is optional
- if applypatch_argv[1] == "-b":
- assert len(applypatch_argv) == 8
- boot_info_index = 3
- else:
- assert len(applypatch_argv) == 6
- boot_info_index = 1
+ assert len(lines) == 10, "Invalid line count: {}".format(lines)
- # boot_info: boot_type:boot_device:boot_size:boot_sha1
- boot_info = applypatch_argv[boot_info_index].strip().split(':')
- assert len(boot_info) == 4
+ # Expect something like "EMMC:/dev/block/recovery:28:5f9c..62e3".
+ target = re.search(r'--target (.+) &&', lines[4].strip())
+ assert target is not None, \
+ "Failed to parse target line \"{}\"".format(lines[4])
+ flash_partition = target.group(1)
+
+ # Check we have the same recovery target in the check and flash commands.
+ assert check_partition == flash_partition, \
+ "Mismatching targets: {} vs {}".format(check_partition, flash_partition)
+
+ # Validate the SHA-1 of the recovery image.
+ recovery_sha1 = flash_partition.split(':')[3]
+ ValidateFileAgainstSha1(
+ input_tmp, 'recovery.img', 'SYSTEM/etc/recovery.img', recovery_sha1)
+ else:
+ assert len(lines) == 11, "Invalid line count: {}".format(lines)
+
+ # --source boot_type:boot_device:boot_size:boot_sha1
+ source = re.search(r'--source (\w+:.+:\w+:\w+) \\', lines[4].strip())
+ assert source is not None, \
+ "Failed to parse source line \"{}\"".format(lines[4])
+
+ source_partition = source.group(1)
+ source_info = source_partition.split(':')
+ assert len(source_info) == 4, \
+ "Invalid source partition: {}".format(source_partition)
ValidateFileAgainstSha1(input_tmp, file_name='boot.img',
file_path='IMAGES/boot.img',
- expected_sha1=boot_info[3])
+ expected_sha1=source_info[3])
- recovery_sha1_index = boot_info_index + 2
- expected_recovery_sha1 = applypatch_argv[recovery_sha1_index]
- assert expected_recovery_check_sha1 == expected_recovery_sha1
+ # --target recovery_type:recovery_device:recovery_size:recovery_sha1
+ target = re.search(r'--target (\w+:.+:\w+:\w+) && \\', lines[5].strip())
+ assert target is not None, \
+ "Failed to parse target line \"{}\"".format(lines[5])
+ target_partition = target.group(1)
+
+ # Check we have the same recovery target in the check and patch commands.
+ assert check_partition == target_partition, \
+ "Mismatching targets: {} vs {}".format(
+ check_partition, target_partition)
+
+ recovery_info = target_partition.split(':')
+ assert len(recovery_info) == 4, \
+ "Invalid target partition: {}".format(target_partition)
ValidateFileAgainstSha1(input_tmp, file_name='recovery.img',
file_path='IMAGES/recovery.img',
- expected_sha1=expected_recovery_sha1)
+ expected_sha1=recovery_info[3])
logging.info('Done checking %s', script_path)
@@ -292,9 +315,19 @@
key = options['verity_key']
if key is None:
key = info_dict['avb_vbmeta_key_path']
+
# avbtool verifies all the images that have descriptors listed in vbmeta.
image = os.path.join(input_tmp, 'IMAGES', 'vbmeta.img')
cmd = ['avbtool', 'verify_image', '--image', image, '--key', key]
+
+ # Append the args for chained partitions if any.
+ for partition in common.AVB_PARTITIONS:
+ key_name = 'avb_' + partition + '_key_path'
+ if info_dict.get(key_name) is not None:
+ chained_partition_arg = common.GetAvbChainedPartitionArg(
+ partition, info_dict, options[key_name])
+ cmd.extend(["--expected_chain_partition", chained_partition_arg])
+
proc = common.Run(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
stdoutdata, _ = proc.communicate()
assert proc.returncode == 0, \
@@ -316,8 +349,13 @@
parser.add_argument(
'--verity_key',
help='the verity public key to verify the bootable images (Verified '
- 'Boot 1.0), or the vbmeta image (Verified Boot 2.0), where '
+ 'Boot 1.0), or the vbmeta image (Verified Boot 2.0, aka AVB), where '
'applicable')
+ for partition in common.AVB_PARTITIONS:
+ parser.add_argument(
+ '--avb_' + partition + '_key_path',
+ help='the public or private key in PEM format to verify AVB chained '
+ 'partition of {}'.format(partition))
parser.add_argument(
'--verity_key_mincrypt',
help='the verity public key in mincrypt format to verify the system '
diff --git a/tools/uuidgen.py b/tools/uuidgen.py
new file mode 100755
index 0000000..d3091a7
--- /dev/null
+++ b/tools/uuidgen.py
@@ -0,0 +1,29 @@
+#!/usr/bin/env python
+#
+# Copyright 2018 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.
+
+from __future__ import print_function
+import sys
+import uuid
+
+def uuidgen(name):
+ return uuid.uuid5(uuid.uuid5(uuid.NAMESPACE_URL, "android.com"), name)
+
+if __name__ == "__main__":
+ if len(sys.argv) < 2:
+ print("Usage: uuidgen.py <name>")
+ sys.exit(1)
+ name = sys.argv[1]
+ print(uuidgen(name))
diff --git a/tools/vendor_buildinfo.sh b/tools/vendor_buildinfo.sh
index c12f7cb..6590049 100755
--- a/tools/vendor_buildinfo.sh
+++ b/tools/vendor_buildinfo.sh
@@ -3,6 +3,13 @@
echo "# begin build properties"
echo "# autogenerated by vendor_buildinfo.sh"
+echo "ro.vendor.build.id=$BUILD_ID"
+echo "ro.vendor.build.version.incremental=$BUILD_NUMBER"
+echo "ro.vendor.build.version.sdk=$PLATFORM_SDK_VERSION"
+echo "ro.vendor.build.version.release=$PLATFORM_VERSION"
+echo "ro.vendor.build.type=$TARGET_BUILD_TYPE"
+echo "ro.vendor.build.tags=$BUILD_VERSION_TAGS"
+
echo "ro.product.board=$TARGET_BOOTLOADER_BOARD_NAME"
echo "ro.board.platform=$TARGET_BOARD_PLATFORM"
diff --git a/tools/warn.py b/tools/warn.py
index 89f4778..4596307 100755
--- a/tools/warn.py
+++ b/tools/warn.py
@@ -75,6 +75,7 @@
# emit_js_data():
import argparse
+import cgi
import csv
import multiprocessing
import os
@@ -3149,6 +3150,14 @@
print '];'
+# Emit a JavaScript const string array for HTML.
+def emit_const_html_string_array(name, array):
+ print 'const ' + name + ' = ['
+ for s in array:
+ print '"' + cgi.escape(strip_escape_string(s)) + '",'
+ print '];'
+
+
# Emit a JavaScript const object array.
def emit_const_object_array(name, array):
print 'const ' + name + ' = ['
@@ -3167,11 +3176,11 @@
emit_const_string_array('ProjectNames', project_names)
emit_const_int_array('WarnPatternsSeverity',
[w['severity'] for w in warn_patterns])
- emit_const_string_array('WarnPatternsDescription',
- [w['description'] for w in warn_patterns])
- emit_const_string_array('WarnPatternsOption',
- [w['option'] for w in warn_patterns])
- emit_const_string_array('WarningMessages', warning_messages)
+ emit_const_html_string_array('WarnPatternsDescription',
+ [w['description'] for w in warn_patterns])
+ emit_const_html_string_array('WarnPatternsOption',
+ [w['option'] for w in warn_patterns])
+ emit_const_html_string_array('WarningMessages', warning_messages)
emit_const_object_array('Warnings', warning_records)
draw_table_javascript = """