Merge "Makefile: Avoid packaging pvmfw.bin in /system" into main
diff --git a/Changes.md b/Changes.md
index fc6701d..6836528 100644
--- a/Changes.md
+++ b/Changes.md
@@ -10,8 +10,9 @@
build team via email android-building@googlegroups.com (external) for any
questions, or see [go/soong](http://go/soong) (internal).
-To omit the validation, `BUILD_BROKEN_PLUGIN_VALIDATION` expects a list of
-plugins to omit from the validation.
+To omit the validation, `BUILD_BROKEN_PLUGIN_VALIDATION` expects a
+space-separated list of plugins to omit from the validation. This must be set
+within a product configuration .mk file, board config .mk file, or buildspec.mk.
## Python 2 to 3 migration
diff --git a/core/Makefile b/core/Makefile
index 4a124c8..82dd770 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -16,53 +16,93 @@
ODM_DLKM_NOTICE_DEPS :=
SYSTEM_DLKM_NOTICE_DEPS :=
-# -----------------------------------------------------------------
-# Release Config Flags
-# Create a summary file of build flags for each partition
-# $(1): build flags json file
-# $(2): flag names
-define generate-partition-build-flag-file
-$(eval $(strip $(1)): PRIVATE_OUT := $(strip $(1)))
-$(eval $(strip $(1)): PRIVATE_FLAG_NAMES := $(strip $(2)))
-$(strip $(1)):
- mkdir -p $$(dir $$(PRIVATE_OUT))
- echo '{' > $$(PRIVATE_OUT)
- echo '"flags": [' >> $$(PRIVATE_OUT)
- $$(foreach flag, $$(PRIVATE_FLAG_NAMES), \
- ( \
- printf ' { "name": "%s", "value": "%s", ' \
- '$$(flag)' \
- '$$(_ALL_RELEASE_FLAGS.$$(flag).VALUE)' \
- ; \
- printf '"set": "%s", "default": "%s", "declared": "%s" }' \
- '$$(_ALL_RELEASE_FLAGS.$$(flag).SET_IN)' \
- '$$(_ALL_RELEASE_FLAGS.$$(flag).DEFAULT)' \
- '$$(_ALL_RELEASE_FLAGS.$$(flag).DECLARED_IN)' \
- ; \
- printf '$$(if $$(filter $$(lastword $$(PRIVATE_FLAG_NAMES)),$$(flag)),,$$(comma))\n' ; \
- ) >> $$(PRIVATE_OUT) \
- )
- echo "]" >> $$(PRIVATE_OUT)
- echo "}" >> $$(PRIVATE_OUT)
+# IMAGES_TO_BUILD is a list of the partition .img files that will be created.
+IMAGES_TO_BUILD:=
+ifneq ($(BUILDING_BOOT_IMAGE),)
+ IMAGES_TO_BUILD += boot
+endif
+ifneq ($(BUILDING_CACHE_IMAGE),)
+ IMAGES_TO_BUILD += cache
+endif
+ifneq ($(BUILDING_DEBUG_BOOT_IMAGE),)
+ IMAGES_TO_BUILD += debug_boot
+endif
+ifneq ($(BUILDING_DEBUG_VENDOR_BOOT_IMAGE),)
+ IMAGES_TO_BUILD += debug_vendor_boot
+endif
+ifneq ($(BUILDING_INIT_BOOT_IMAGE),)
+ IMAGES_TO_BUILD += init_boot
+endif
+ifneq ($(BUILDING_ODM_DLKM_IMAGE),)
+ IMAGES_TO_BUILD += odm_dlkm
+endif
+ifneq ($(BUILDING_ODM_IMAGE),)
+ IMAGES_TO_BUILD += odm
+endif
+ifneq ($(BUILDING_PRODUCT_IMAGE),)
+ IMAGES_TO_BUILD += product
+endif
+ifneq ($(BUILDING_RAMDISK_IMAGE),)
+ IMAGES_TO_BUILD += ramdisk
+endif
+ifneq ($(BUILDING_RECOVERY_IMAGE),)
+ IMAGES_TO_BUILD += recovery
+endif
+ifneq ($(BUILDING_SUPER_EMPTY_IMAGE),)
+ IMAGES_TO_BUILD += super_empty
+endif
+ifneq ($(BUILDING_SYSTEM_DLKM_IMAGE),)
+ IMAGES_TO_BUILD += system_dlkm
+endif
+ifneq ($(BUILDING_SYSTEM_EXT_IMAGE),)
+ IMAGES_TO_BUILD += system_ext
+endif
+ifneq ($(BUILDING_SYSTEM_IMAGE),)
+ IMAGES_TO_BUILD += system
+endif
+ifneq ($(BUILDING_SYSTEM_OTHER_IMAGE),)
+ IMAGES_TO_BUILD += system_other
+endif
+ifneq ($(BUILDING_USERDATA_IMAGE),)
+ IMAGES_TO_BUILD += userdata
+endif
+ifneq ($(BUILDING_VBMETA_IMAGE),)
+ IMAGES_TO_BUILD += vbmeta
+endif
+ifneq ($(BUILDING_VENDOR_BOOT_IMAGE),)
+ IMAGES_TO_BUILD += vendor_boot
+endif
+ifneq ($(BUILDING_VENDOR_DLKM_IMAGE),)
+ IMAGES_TO_BUILD += vendor_dlkm
+endif
+ifneq ($(BUILDING_VENDOR_IMAGE),)
+ IMAGES_TO_BUILD += vendor
+endif
+ifneq ($(BUILDING_VENDOR_KERNEL_BOOT_IMAGE),)
+ IMAGES_TO_BUILD += vendor_kernel_boot
+endif
+
+
+###########################################################
+# Get the module names suitable for ALL_MODULES.* variables that are installed
+# for a given partition
+#
+# $(1): Partition
+###########################################################
+define register-names-for-partition
+$(sort $(foreach m,$(product_MODULES),\
+ $(if $(filter $(PRODUCT_OUT)/$(strip $(1))/%, $(ALL_MODULES.$(m).INSTALLED)), \
+ $(m)
+ ) \
+))
endef
-_FLAG_PARTITIONS := product system system_ext vendor
-$(foreach partition, $(_FLAG_PARTITIONS), \
- $(eval BUILD_FLAG_SUMMARIES.$(partition) \
- := $(TARGET_OUT_FLAGS)/$(partition)/etc/build_flags.json) \
- $(eval $(call generate-partition-build-flag-file, \
- $(BUILD_FLAG_SUMMARIES.$(partition)), \
- $(_ALL_RELEASE_FLAGS.PARTITIONS.$(partition)) \
- ) \
- ) \
-)
+# Release & Aconfig Flags
+# -----------------------------------------------------------------
+include $(BUILD_SYSTEM)/packaging/flags.mk
-# TODO: Remove
-.PHONY: flag-files
-flag-files: $(foreach partition, $(_FLAG_PARTITIONS), \
- $(TARGET_OUT_FLAGS)/$(partition)/etc/build_flags.json)
# -----------------------------------------------------------------
# Define rules to copy PRODUCT_COPY_FILES defined by the product.
@@ -1045,8 +1085,8 @@
COMPRESSION_COMMAND := $(LZ4) -l -12 --favor-decSpeed
RAMDISK_EXT := .lz4
else
-COMPRESSION_COMMAND_DEPS := $(MINIGZIP)
-COMPRESSION_COMMAND := $(MINIGZIP)
+COMPRESSION_COMMAND_DEPS := $(GZIP)
+COMPRESSION_COMMAND := $(GZIP)
RAMDISK_EXT := .gz
endif
@@ -2170,6 +2210,8 @@
$(hide) echo "root_dir=$(TARGET_ROOT_OUT)" >> $(1)
$(if $(filter true,$(PRODUCT_USE_DYNAMIC_PARTITION_SIZE)),\
$(hide) echo "use_dynamic_partition_size=true" >> $(1))
+$(if $(COPY_IMAGES_FOR_TARGET_FILES_ZIP),\
+ $(hide) echo "use_fixed_timestamp=true" >> $(1))
$(if $(3),$(hide) $(foreach kv,$(3),echo "$(kv)" >> $(1);))
endef
@@ -3313,6 +3355,10 @@
$(call intermediates-dir-for,PACKAGING,systemimage)
BUILT_SYSTEMIMAGE := $(systemimage_intermediates)/system.img
+# Used by the bazel sandwich to request the staging dir be built
+$(systemimage_intermediates)/staging_dir.stamp: $(FULL_SYSTEMIMAGE_DEPS)
+ touch $@
+
# $(1): output file
define build-systemimage-target
@echo "Target system fs image: $(1)"
@@ -3465,45 +3511,6 @@
tar cfj $(ASAN_IN_SYSTEM_INSTALLED) $(ASAN_SYSTEM_INSTALL_OPTIONS) -C $(TARGET_OUT_DATA)/.. $(ASAN_OUT_DIRS_FOR_SYSTEM_INSTALL) >/dev/null
# -----------------------------------------------------------------
-# partition table image
-ifdef BOARD_BPT_INPUT_FILES
-
-BUILT_BPTIMAGE_TARGET := $(PRODUCT_OUT)/partition-table.img
-BUILT_BPTJSON_TARGET := $(PRODUCT_OUT)/partition-table.bpt
-
-INTERNAL_BVBTOOL_MAKE_TABLE_ARGS := \
- --output_gpt $(BUILT_BPTIMAGE_TARGET) \
- --output_json $(BUILT_BPTJSON_TARGET) \
- $(foreach file, $(BOARD_BPT_INPUT_FILES), --input $(file))
-
-ifdef BOARD_BPT_DISK_SIZE
-INTERNAL_BVBTOOL_MAKE_TABLE_ARGS += --disk_size $(BOARD_BPT_DISK_SIZE)
-endif
-
-define build-bptimage-target
- $(call pretty,"Target partition table image: $(INSTALLED_BPTIMAGE_TARGET)")
- $(hide) $(BPTTOOL) make_table $(INTERNAL_BVBTOOL_MAKE_TABLE_ARGS) $(BOARD_BPT_MAKE_TABLE_ARGS)
-endef
-
-INSTALLED_BPTIMAGE_TARGET := $(BUILT_BPTIMAGE_TARGET)
-$(BUILT_BPTJSON_TARGET): $(INSTALLED_BPTIMAGE_TARGET)
- $(hide) touch -c $(BUILT_BPTJSON_TARGET)
-
-$(INSTALLED_BPTIMAGE_TARGET): $(BPTTOOL) $(BOARD_BPT_INPUT_FILES)
- $(build-bptimage-target)
-
-$(call declare-1p-container,$(INSTALLED_BPTIMAGE_TARGET),)
-$(call declare-container-license-deps,$(INSTALLED_BPTIMAGE_TARGET),$(BOARD_BPT_INPUT_FILES),$(PRODUCT_OUT)/:/)
-
-UNMOUNTED_NOTICE_VENDOR_DEPS+= $(INSTALLED_BPTIMAGE_TARGET)
-
-.PHONY: bptimage-nodeps
-bptimage-nodeps:
- $(build-bptimage-target)
-
-endif # BOARD_BPT_INPUT_FILES
-
-# -----------------------------------------------------------------
# cache partition image
INSTALLED_FILES_OUTSIDE_IMAGES := $(filter-out $(TARGET_OUT_CACHE)/%, $(INSTALLED_FILES_OUTSIDE_IMAGES))
ifdef BUILDING_CACHE_IMAGE
@@ -4204,6 +4211,13 @@
ifneq ($(strip $(BOARD_CUSTOMIMAGES_PARTITION_LIST)),)
INTERNAL_AVB_CUSTOMIMAGES_SIGNING_ARGS :=
+BOARD_AVB_CUSTOMIMAGES_PARTITION_LIST :=
+# If BOARD_AVB_$(call to-upper,$(partition))_KEY_PATH is set, the image will be included in
+# BOARD_AVB_CUSTOMIMAGES_PARTITION_LIST, otherwise the image won't be AVB signed.
+$(foreach partition,$(BOARD_CUSTOMIMAGES_PARTITION_LIST), \
+ $(if $(BOARD_AVB_$(call to-upper,$(partition))_KEY_PATH), \
+ $(eval BOARD_AVB_CUSTOMIMAGES_PARTITION_LIST += $(partition)) \
+ $(eval BOARD_$(call to-upper,$(partition))_IMAGE_LIST := $(BOARD_AVB_$(call to-upper,$(partition))_IMAGE_LIST))))
# Sign custom image.
# $(1): the prebuilt custom image.
@@ -4228,9 +4242,26 @@
INSTALLED_CUSTOMIMAGES_TARGET += $(3)
endef
-$(foreach partition,$(BOARD_CUSTOMIMAGES_PARTITION_LIST), \
+# Copy unsigned custom image.
+# $(1): the prebuilt custom image.
+# $(2): the signed custom image target.
+define copy_custom_image
+$(2): $(1) $(INTERNAL_USERIMAGES_DEPS)
+ @echo Target custom image: $(2)
+ mkdir -p $(dir $(2))
+ cp $(1) $(2)
+INSTALLED_CUSTOMIMAGES_TARGET += $(2)
+endef
+
+# Add AVB custom image to droid target
+$(foreach partition,$(BOARD_AVB_CUSTOMIMAGES_PARTITION_LIST), \
$(foreach image,$(BOARD_AVB_$(call to-upper,$(partition))_IMAGE_LIST), \
$(eval $(call sign_custom_image,$(image),$(partition),$(PRODUCT_OUT)/$(notdir $(image))))))
+
+# Add unsigned custom image to droid target
+$(foreach partition,$(filter-out $(BOARD_AVB_CUSTOMIMAGES_PARTITION_LIST), $(BOARD_CUSTOMIMAGES_PARTITION_LIST)), \
+ $(foreach image,$(BOARD_$(call to-upper,$(partition))_IMAGE_LIST), \
+ $(eval $(call copy_custom_image,$(image),$(PRODUCT_OUT)/$(notdir $(image))))))
endif
# -----------------------------------------------------------------
@@ -4507,7 +4538,9 @@
$(eval part := $(1))
$(eval PART=$(call to-upper,$(part)))
$(eval _rollback_index_location := BOARD_AVB_$(PART)_ROLLBACK_INDEX_LOCATION)
+$(eval _key_path := BOARD_AVB_$(PART)_KEY_PATH)
$(if $($(_rollback_index_location)),,$(error $(_rollback_index_location) is not defined))
+$(if $($(_key_path)),,$(error $(_key_path) is not defined))
INTERNAL_AVB_MAKE_VBMETA_IMAGE_ARGS += \
--chain_partition $(part):$($(_rollback_index_location)):$(AVB_CHAIN_KEY_DIR)/$(part).avbpubkey
@@ -4587,8 +4620,8 @@
$(foreach partition,$(BOARD_AVB_VBMETA_CUSTOM_PARTITIONS),$(eval BOARD_AVB_MAKE_VBMETA_$(call to-upper,$(partition))_IMAGE_ARGS += --padding_size 4096))
endif
-ifneq ($(strip $(BOARD_CUSTOMIMAGES_PARTITION_LIST)),)
-$(foreach partition,$(BOARD_CUSTOMIMAGES_PARTITION_LIST), \
+ifneq ($(strip $(BOARD_AVB_CUSTOMIMAGES_PARTITION_LIST)),)
+$(foreach partition,$(BOARD_AVB_CUSTOMIMAGES_PARTITION_LIST), \
$(eval $(call check-and-set-custom-avb-chain-args,$(partition))))
endif
@@ -4675,8 +4708,8 @@
$(if $(BOARD_AVB_VBMETA_VENDOR_KEY_PATH),\
$(hide) $(AVBTOOL) extract_public_key --key $(BOARD_AVB_VBMETA_VENDOR_KEY_PATH) \
--output $(1)/vbmeta_vendor.avbpubkey)
- $(if $(BOARD_CUSTOMIMAGES_PARTITION_LIST),\
- $(hide) $(foreach partition,$(BOARD_CUSTOMIMAGES_PARTITION_LIST), \
+ $(if $(BOARD_AVB_CUSTOMIMAGES_PARTITION_LIST),\
+ $(hide) $(foreach partition,$(BOARD_AVB_CUSTOMIMAGES_PARTITION_LIST), \
$(AVBTOOL) extract_public_key --key $(BOARD_AVB_$(call to-upper,$(partition))_KEY_PATH) \
--output $(1)/$(partition).avbpubkey;)) \
$(if $(BOARD_AVB_VBMETA_CUSTOM_PARTITIONS),\
@@ -4999,7 +5032,9 @@
endif # INSTALLED_BOOTIMAGE_TARGET
endif # my_board_extracted_kernel
-ifneq ($(my_board_extracted_kernel),true)
+ifeq ($(my_board_extracted_kernel),true)
+$(call dist-for-goals, droid_targets, $(BUILT_KERNEL_VERSION_FILE))
+else
$(warning Neither INSTALLED_KERNEL_TARGET nor INSTALLED_BOOTIMAGE_TARGET is defined when \
PRODUCT_OTA_ENFORCE_VINTF_KERNEL_REQUIREMENTS is true. Information about the updated kernel \
cannot be built into OTA update package. You can fix this by: \
@@ -5262,7 +5297,6 @@
make_f2fs_casefold \
merge_ota \
merge_target_files \
- minigzip \
mk_combined_img \
mkbootfs \
mkbootimg \
@@ -5419,6 +5453,9 @@
ifeq ($(BOARD_USES_PVMFWIMAGE),true)
$(hide) echo "flash pvmfw" >> $@
endif
+ifneq ($(INSTALLED_VENDOR_BOOTIMAGE_TARGET),)
+ $(hide) echo "flash vendor_boot" >> $@
+endif
ifeq ($(BOARD_AVB_ENABLE),true)
ifeq ($(BUILDING_VBMETA_IMAGE),true)
$(hide) echo "flash --apply-vbmeta vbmeta" >> $@
@@ -5429,9 +5466,6 @@
ifneq (,$(strip $(BOARD_AVB_VBMETA_VENDOR)))
$(hide) echo "flash --apply-vbmeta vbmeta_vendor" >> $@
endif
-ifneq ($(INSTALLED_VENDOR_BOOTIMAGE_TARGET),)
- $(hide) echo "flash vendor_boot" >> $@
-endif
ifneq (,$(strip $(BOARD_AVB_VBMETA_CUSTOM_PARTITIONS)))
$(hide) $(foreach partition,$(BOARD_AVB_VBMETA_CUSTOM_PARTITIONS), \
echo "flash vbmeta_$(partition)" >> $@;)
@@ -5595,15 +5629,20 @@
$(hide) echo "avb_recovery_rollback_index_location=$(BOARD_AVB_RECOVERY_ROLLBACK_INDEX_LOCATION)" >> $@
endif # BOARD_AVB_RECOVERY_KEY_PATH
ifneq (,$(strip $(BOARD_CUSTOMIMAGES_PARTITION_LIST)))
- $(hide) echo "avb_custom_images_partition_list=$(BOARD_CUSTOMIMAGES_PARTITION_LIST)" >> $@
- $(hide) $(foreach partition,$(BOARD_CUSTOMIMAGES_PARTITION_LIST), \
+ $(hide) echo "custom_images_partition_list=$(filter-out $(BOARD_AVB_CUSTOMIMAGES_PARTITION_LIST), $(BOARD_CUSTOMIMAGES_PARTITION_LIST))" >> $@
+ $(hide) $(foreach partition,$(filter-out $(BOARD_AVB_CUSTOMIMAGES_PARTITION_LIST), $(BOARD_CUSTOMIMAGES_PARTITION_LIST)), \
+ echo "$(partition)_image_list=$(foreach image,$(BOARD_$(call to-upper,$(partition))_IMAGE_LIST),$(notdir $(image)))" >> $@;)
+endif # BOARD_CUSTOMIMAGES_PARTITION_LIST
+ifneq (,$(strip $(BOARD_AVB_CUSTOMIMAGES_PARTITION_LIST)))
+ $(hide) echo "avb_custom_images_partition_list=$(BOARD_AVB_CUSTOMIMAGES_PARTITION_LIST)" >> $@
+ $(hide) $(foreach partition,$(BOARD_AVB_CUSTOMIMAGES_PARTITION_LIST), \
echo "avb_$(partition)_key_path=$(BOARD_AVB_$(call to-upper,$(partition))_KEY_PATH)" >> $@; \
echo "avb_$(partition)_algorithm=$(BOARD_AVB_$(call to-upper,$(partition))_ALGORITHM)" >> $@; \
echo "avb_$(partition)_add_hashtree_footer_args=$(BOARD_AVB_$(call to-upper,$(partition))_ADD_HASHTREE_FOOTER_ARGS)" >> $@; \
echo "avb_$(partition)_rollback_index_location=$(BOARD_AVB_$(call to-upper,$(partition))_ROLLBACK_INDEX_LOCATION)" >> $@; \
echo "avb_$(partition)_partition_size=$(BOARD_AVB_$(call to-upper,$(partition))_PARTITION_SIZE)" >> $@; \
echo "avb_$(partition)_image_list=$(foreach image,$(BOARD_AVB_$(call to-upper,$(partition))_IMAGE_LIST),$(notdir $(image)))" >> $@;)
-endif # BOARD_CUSTOMIMAGES_PARTITION_LIST
+endif # BOARD_AVB_CUSTOMIMAGES_PARTITION_LIST
ifneq (,$(strip $(BOARD_AVB_VBMETA_SYSTEM)))
$(hide) echo "avb_vbmeta_system=$(BOARD_AVB_VBMETA_SYSTEM)" >> $@
$(hide) echo "avb_vbmeta_system_args=$(BOARD_AVB_MAKE_VBMETA_SYSTEM_IMAGE_ARGS)" >> $@
@@ -5628,14 +5667,6 @@
echo "avb_vbmeta_$(partition)_rollback_index_location=$(BOARD_AVB_VBMETA_$(call to-upper,$(partition))_ROLLBACK_INDEX_LOCATION)" >> $@ ;)
endif # BOARD_AVB_VBMETA_CUSTOM_PARTITIONS
endif # BOARD_AVB_ENABLE
-ifdef BOARD_BPT_INPUT_FILES
- $(hide) echo "board_bpt_enable=true" >> $@
- $(hide) echo "board_bpt_make_table_args=$(BOARD_BPT_MAKE_TABLE_ARGS)" >> $@
- $(hide) echo "board_bpt_input_files=$(BOARD_BPT_INPUT_FILES)" >> $@
-endif
-ifdef BOARD_BPT_DISK_SIZE
- $(hide) echo "board_bpt_disk_size=$(BOARD_BPT_DISK_SIZE)" >> $@
-endif
$(call generate-userimage-prop-dictionary, $@)
ifeq ($(AB_OTA_UPDATER),true)
@# Include the build type in META/misc_info.txt so the server can easily differentiate production builds.
@@ -5737,11 +5768,11 @@
# $(1): Directory to copy
# $(2): Location to copy it to
-# The "ls -A" is to prevent "acp s/* d" from failing if s is empty.
+# The "ls -A" is to skip if $(1) is empty.
define package_files-copy-root
if [ -d "$(strip $(1))" -a "$$(ls -A $(1))" ]; then \
mkdir -p $(2) && \
- $(ACP) -rd $(strip $(1))/* $(2); \
+ $(ACP) -rd $(strip $(1))/. $(strip $(2))/; \
fi
endef
@@ -5902,17 +5933,19 @@
# $(2): target out directory
# $(3): image name to generate a map file. skip generating map file if empty
define copy-image-and-generate-map
- $(eval _supported_fs_for_map_file_generator := erofs ext%)
- $(eval _img := $(call to-upper,$(3)))
- $(if $(3),$(eval _map_fs_type := $(BOARD_$(_img)IMAGE_FILE_SYSTEM_TYPE)),\
- $(eval _no_map_file := "true"))
- $(if $(filter $(_supported_fs_for_map_file_generator),$(_map_fs_type))$(_no_map_file),\
- mkdir -p $(2); \
- cp $(1) $(2); \
- $(if $(3),$(HOST_OUT_EXECUTABLES)/map_file_generator $(1) $(2)/$(3).map))
- $(eval _img :=)
- $(eval _map_fs_type :=)
- $(eval _no_map_file :=)
+ $(if $(COPY_IMAGES_FOR_TARGET_FILES_ZIP), \
+ $(eval _supported_fs_for_map_file_generator := erofs ext%) \
+ $(eval _img := $(call to-upper,$(3))) \
+ $(if $(3),$(eval _map_fs_type := $(BOARD_$(_img)IMAGE_FILE_SYSTEM_TYPE)),\
+ $(eval _no_map_file := "true")) \
+ $(if $(filter $(_supported_fs_for_map_file_generator),$(_map_fs_type))$(_no_map_file),\
+ mkdir -p $(2); \
+ cp $(1) $(2); \
+ $(if $(3),$(HOST_OUT_EXECUTABLES)/map_file_generator $(1) $(2)/$(3).map)) \
+ $(eval _img :=) \
+ $(eval _map_fs_type :=) \
+ $(eval _no_map_file :=) \
+ )
endef
# By conditionally including the dependency of the target files package on the
@@ -5920,7 +5953,9 @@
# image.
ifdef BUILDING_SYSTEM_IMAGE
$(BUILT_TARGET_FILES_DIR): $(FULL_SYSTEMIMAGE_DEPS)
- $(BUILT_TARGET_FILES_DIR): $(BUILT_SYSTEMIMAGE)
+ ifdef COPY_IMAGES_FOR_TARGET_FILES_ZIP
+ $(BUILT_TARGET_FILES_DIR): $(BUILT_SYSTEMIMAGE)
+ endif
else
# releasetools may need the system build.prop even when building a
# system-image-less product.
@@ -5933,7 +5968,9 @@
ifdef BUILDING_SYSTEM_OTHER_IMAGE
$(BUILT_TARGET_FILES_DIR): $(INTERNAL_SYSTEMOTHERIMAGE_FILES)
- $(BUILT_TARGET_FILES_DIR): $(BUILT_SYSTEMOTHERIMAGE_TARGET)
+ ifdef COPY_IMAGES_FOR_TARGET_FILES_ZIP
+ $(BUILT_TARGET_FILES_DIR): $(BUILT_SYSTEMOTHERIMAGE_TARGET)
+ endif
endif
ifdef BUILDING_VENDOR_BOOT_IMAGE
@@ -5965,21 +6002,27 @@
ifdef BUILDING_VENDOR_IMAGE
$(BUILT_TARGET_FILES_DIR): $(INTERNAL_VENDORIMAGE_FILES)
- $(BUILT_TARGET_FILES_DIR): $(BUILT_VENDORIMAGE_TARGET)
+ ifdef COPY_IMAGES_FOR_TARGET_FILES_ZIP
+ $(BUILT_TARGET_FILES_DIR): $(BUILT_VENDORIMAGE_TARGET)
+ endif
else ifdef BOARD_PREBUILT_VENDORIMAGE
$(BUILT_TARGET_FILES_DIR): $(INSTALLED_VENDORIMAGE_TARGET)
endif
ifdef BUILDING_PRODUCT_IMAGE
$(BUILT_TARGET_FILES_DIR): $(INTERNAL_PRODUCTIMAGE_FILES)
- $(BUILT_TARGET_FILES_DIR): $(BUILT_PRODUCTIMAGE_TARGET)
+ ifdef COPY_IMAGES_FOR_TARGET_FILES_ZIP
+ $(BUILT_TARGET_FILES_DIR): $(BUILT_PRODUCTIMAGE_TARGET)
+ endif
else ifdef BOARD_PREBUILT_PRODUCTIMAGE
$(BUILT_TARGET_FILES_DIR): $(INSTALLED_PRODUCTIMAGE_TARGET)
endif
ifdef BUILDING_SYSTEM_EXT_IMAGE
$(BUILT_TARGET_FILES_DIR): $(INTERNAL_SYSTEM_EXTIMAGE_FILES)
- $(BUILT_TARGET_FILES_DIR): $(BUILT_SYSTEM_EXTIMAGE_TARGET)
+ ifdef COPY_IMAGES_FOR_TARGET_FILES_ZIP
+ $(BUILT_TARGET_FILES_DIR): $(BUILT_SYSTEM_EXTIMAGE_TARGET)
+ endif
else ifdef BOARD_PREBUILT_SYSTEM_EXTIMAGE
$(BUILT_TARGET_FILES_DIR): $(INSTALLED_SYSTEM_EXTIMAGE_TARGET)
endif
@@ -5994,28 +6037,36 @@
ifdef BUILDING_ODM_IMAGE
$(BUILT_TARGET_FILES_DIR): $(INTERNAL_ODMIMAGE_FILES)
- $(BUILT_TARGET_FILES_DIR): $(BUILT_ODMIMAGE_TARGET)
+ ifdef COPY_IMAGES_FOR_TARGET_FILES_ZIP
+ $(BUILT_TARGET_FILES_DIR): $(BUILT_ODMIMAGE_TARGET)
+ endif
else ifdef BOARD_PREBUILT_ODMIMAGE
$(BUILT_TARGET_FILES_DIR): $(INSTALLED_ODMIMAGE_TARGET)
endif
ifdef BUILDING_VENDOR_DLKM_IMAGE
$(BUILT_TARGET_FILES_DIR): $(INTERNAL_VENDOR_DLKMIMAGE_FILES)
- $(BUILT_TARGET_FILES_DIR): $(BUILT_VENDOR_DLKMIMAGE_TARGET)
+ ifdef COPY_IMAGES_FOR_TARGET_FILES_ZIP
+ $(BUILT_TARGET_FILES_DIR): $(BUILT_VENDOR_DLKMIMAGE_TARGET)
+ endif
else ifdef BOARD_PREBUILT_VENDOR_DLKMIMAGE
$(BUILT_TARGET_FILES_DIR): $(INSTALLED_VENDOR_DLKMIMAGE_TARGET)
endif
ifdef BUILDING_ODM_DLKM_IMAGE
$(BUILT_TARGET_FILES_DIR): $(INTERNAL_ODM_DLKMIMAGE_FILES)
- $(BUILT_TARGET_FILES_DIR): $(BUILT_ODM_DLKMIMAGE_TARGET)
+ ifdef COPY_IMAGES_FOR_TARGET_FILES_ZIP
+ $(BUILT_TARGET_FILES_DIR): $(BUILT_ODM_DLKMIMAGE_TARGET)
+ endif
else ifdef BOARD_PREBUILT_ODM_DLKMIMAGE
$(BUILT_TARGET_FILES_DIR): $(INSTALLED_ODM_DLKMIMAGE_TARGET)
endif
ifdef BUILDING_SYSTEM_DLKM_IMAGE
$(BUILT_TARGET_FILES_DIR): $(INTERNAL_SYSTEM_DLKMIMAGE_FILES)
- $(BUILT_TARGET_FILES_DIR): $(BUILT_SYSTEM_DLKMIMAGE_TARGET)
+ ifdef COPY_IMAGES_FOR_TARGET_FILES_ZIP
+ $(BUILT_TARGET_FILES_DIR): $(BUILT_SYSTEM_DLKMIMAGE_TARGET)
+ endif
else ifdef BOARD_PREBUILT_SYSTEM_DLKMIMAGE
$(BUILT_TARGET_FILES_DIR): $(INSTALLED_SYSTEM_DLKMIMAGE_TARGET)
endif
@@ -6414,7 +6465,7 @@
ifneq ($(strip $(BOARD_CUSTOMIMAGES_PARTITION_LIST)),)
$(hide) mkdir -p $(zip_root)/PREBUILT_IMAGES
$(hide) $(foreach partition,$(BOARD_CUSTOMIMAGES_PARTITION_LIST), \
- $(foreach image,$(BOARD_AVB_$(call to-upper,$(partition))_IMAGE_LIST),cp $(image) $(zip_root)/PREBUILT_IMAGES/;))
+ $(foreach image,$(BOARD_$(call to-upper,$(partition))_IMAGE_LIST),cp $(image) $(zip_root)/PREBUILT_IMAGES/;))
endif # BOARD_CUSTOMIMAGES_PARTITION_LIST
@# The radio images in BOARD_PACK_RADIOIMAGES will be additionally copied from RADIO/ into
@# IMAGES/, which then will be added into <product>-img.zip. Such images must be listed in
@@ -6838,6 +6889,14 @@
ifeq (,$(TARGET_BUILD_UNBUNDLED))
$(JACOCO_REPORT_CLASSES_ALL): $(INTERNAL_ALLIMAGES_FILES)
endif
+
+# This is not ideal, but it is difficult to correctly figure out the actual jacoco report
+# jars we need to add here as dependencies, so we add the device-tests as a dependency when
+# the env variable is set and this should guarantee thaat all the jacoco report jars are ready
+# when we package the final report jar here.
+ifeq ($(JACOCO_PACKAGING_INCLUDE_DEVICE_TESTS),true)
+ $(JACOCO_REPORT_CLASSES_ALL): $(COMPATIBILITY.device-tests.FILES)
+endif
endif # EMMA_INSTRUMENT=true
@@ -7067,6 +7126,7 @@
PATH=$(INTERNAL_USERIMAGES_BINARY_PATHS):$(dir $(ZIP2ZIP)):$$PATH \
$(IMG_FROM_TARGET_FILES) \
--additional IMAGES/VerifiedBootParams.textproto:VerifiedBootParams.textproto \
+ --build_super_image $(BUILD_SUPER_IMAGE) \
$(BUILT_TARGET_FILES_PACKAGE) $@
$(call declare-1p-container,$(INTERNAL_UPDATE_PACKAGE_TARGET),)
@@ -7412,6 +7472,9 @@
haiku-rust: $(SOONG_RUST_FUZZ_PACKAGING_ARCH_MODULES) $(ALL_RUST_FUZZ_TARGETS)
$(call dist-for-goals,haiku-rust,$(SOONG_RUST_FUZZ_PACKAGING_ARCH_MODULES))
$(call dist-for-goals,haiku-rust,$(PRODUCT_OUT)/module-info.json)
+.PHONY: haiku-presubmit
+haiku-presubmit: $(SOONG_PRESUBMIT_FUZZ_PACKAGING_ARCH_MODULES) $(ALL_PRESUBMIT_FUZZ_TARGETS)
+$(call dist-for-goals,haiku-presubmit,$(SOONG_PRESUBMIT_FUZZ_PACKAGING_ARCH_MODULES))
# -----------------------------------------------------------------
# Extract platform fonts used in Layoutlib
diff --git a/core/aapt2.mk b/core/aapt2.mk
index 7b17df4..0e23477 100644
--- a/core/aapt2.mk
+++ b/core/aapt2.mk
@@ -68,6 +68,8 @@
# support for it.
my_static_library_resources := $(foreach l, $(call reverse-list,$(LOCAL_STATIC_ANDROID_LIBRARIES) $(LOCAL_STATIC_JAVA_AAR_LIBRARIES)),\
$(call intermediates-dir-for,JAVA_LIBRARIES,$(l),,COMMON)/package-res.apk)
+my_static_library_transitive_resource_packages_lists := $(foreach l, $(call reverse-list,$(LOCAL_STATIC_ANDROID_LIBRARIES) $(LOCAL_STATIC_JAVA_AAR_LIBRARIES)),\
+ $(call intermediates-dir-for,JAVA_LIBRARIES,$(l),,COMMON)/transitive-res-packages)
my_static_library_extra_packages := $(foreach l, $(call reverse-list,$(LOCAL_STATIC_ANDROID_LIBRARIES) $(LOCAL_STATIC_JAVA_AAR_LIBRARIES)),\
$(call intermediates-dir-for,JAVA_LIBRARIES,$(l),,COMMON)/extra_packages)
my_shared_library_resources := $(foreach l, $(LOCAL_SHARED_ANDROID_LIBRARIES),\
@@ -95,6 +97,7 @@
$(my_res_package): PRIVATE_JAVA_GEN_DIR := $(intermediates.COMMON)/aapt2
$(my_res_package): PRIVATE_SRCJAR := $(my_srcjar)
$(my_res_package): PRIVATE_STATIC_LIBRARY_EXTRA_PACKAGES := $(my_static_library_extra_packages)
+$(my_res_package): PRIVATE_STATIC_LIBRARY_TRANSITIVE_RES_PACKAGES_LISTS := $(my_static_library_transitive_resource_packages_lists)
$(my_res_package): PRIVATE_AAPT_EXTRA_PACKAGES := $(aapt_extra_packages)
$(my_res_package): .KATI_IMPLICIT_OUTPUTS := $(my_srcjar) $(aapt_extra_packages)
@@ -117,7 +120,7 @@
$(my_res_package): .KATI_IMPLICIT_OUTPUTS += $(proguard_options_file)
endif
-$(my_res_package): $(full_android_manifest) $(my_static_library_resources) $(my_shared_library_resources)
+$(my_res_package): $(full_android_manifest) $(my_static_library_resources) $(my_static_library_transitive_resource_packages_lists) $(my_shared_library_resources)
$(my_res_package): $(my_full_asset_paths)
$(my_res_package): $(my_res_resources_flat) $(my_overlay_resources_flat) \
$(my_resources_flata) $(my_static_library_resources) $(my_static_library_extra_packages) \
diff --git a/core/app_prebuilt_internal.mk b/core/app_prebuilt_internal.mk
index 9fab44d..b141a98 100644
--- a/core/app_prebuilt_internal.mk
+++ b/core/app_prebuilt_internal.mk
@@ -227,7 +227,7 @@
$(built_module): PRIVATE_EMBEDDED_JNI_LIBS := $(embedded_prebuilt_jni_libs)
ifdef LOCAL_COMPRESSED_MODULE
-$(built_module) : $(MINIGZIP)
+$(built_module) : $(GZIP)
endif
ifeq ($(module_run_appcompat),true)
@@ -305,4 +305,4 @@
###########################################################
## SBOM generation
###########################################################
-include $(BUILD_SBOM_GEN)
\ No newline at end of file
+include $(BUILD_SBOM_GEN)
diff --git a/core/base_rules.mk b/core/base_rules.mk
index 9ad1cc5..e7c28ec 100644
--- a/core/base_rules.mk
+++ b/core/base_rules.mk
@@ -578,7 +578,9 @@
ALL_VINTF_MANIFEST_FRAGMENTS_LIST += $(my_vintf_new_pairs)
- $(my_all_targets) : $(my_vintf_new_installed)
+ $(my_all_targets) : $(my_vintf_installed)
+ # Install fragments together with the target
+ $(LOCAL_INSTALLED_MODULE) : | $(my_vintf_installed)
endif # my_vintf_fragments
# Rule to install the module's companion init.rc.
@@ -615,6 +617,8 @@
ALL_INIT_RC_INSTALLED_PAIRS += $(my_init_rc_new_pairs)
$(my_all_targets) : $(my_init_rc_installed)
+ # Install init_rc together with the target
+ $(LOCAL_INSTALLED_MODULE) : | $(my_init_rc_installed)
endif # my_init_rc
endif # !LOCAL_IS_HOST_MODULE
@@ -975,6 +979,11 @@
$(my_init_rc_pairs) \
$(my_test_data_pairs) \
$(my_vintf_pairs))
+ # Store the list of vintf/init_rc as order-only dependencies
+ ALL_MODULES.$(my_register_name).ORDERONLY_INSTALLED := \
+ $(strip $(ALL_MODULES.$(my_register_name).ORDERONLY_INSTALLED) \
+ $(my_init_rc_installed) \
+ $(my_vintf_installed))
else ifneq (true,$(LOCAL_UNINSTALLABLE_MODULE))
ALL_MODULES.$(my_register_name).INSTALLED := \
$(strip $(ALL_MODULES.$(my_register_name).INSTALLED) \
@@ -984,6 +993,10 @@
$(strip $(ALL_MODULES.$(my_register_name).BUILT_INSTALLED) \
$(LOCAL_BUILT_MODULE):$(LOCAL_INSTALLED_MODULE) \
$(my_init_rc_pairs) $(my_test_data_pairs) $(my_vintf_pairs))
+ ALL_MODULES.$(my_register_name).ORDERONLY_INSTALLED := \
+ $(strip $(ALL_MODULES.$(my_register_name).ORDERONLY_INSTALLED) \
+ $(my_init_rc_installed) \
+ $(my_vintf_installed))
endif
ifdef LOCAL_PICKUP_FILES
# Files or directories ready to pick up by the build system
@@ -1045,6 +1058,10 @@
$(ALL_MODULES.$(my_register_name).SUPPORTED_VARIANTS) \
$(filter-out $(ALL_MODULES.$(my_register_name).SUPPORTED_VARIANTS),$(my_supported_variant))
+ALL_MODULES.$(my_register_name).ACONFIG_FILES := \
+ $(ALL_MODULES.$(my_register_name).ACONFIG_FILES) $(LOCAL_ACONFIG_FILES)
+
+
##########################################################################
## When compiling against API imported module, use API import stub
## libraries.
diff --git a/core/board_config.mk b/core/board_config.mk
index 663ec7c..c3a6864 100644
--- a/core/board_config.mk
+++ b/core/board_config.mk
@@ -144,9 +144,6 @@
_board_strip_list += BOARD_AVB_PVMFW_ALGORITHM
_board_strip_list += BOARD_AVB_PVMFW_ROLLBACK_INDEX_LOCATION
_board_strip_list += BOARD_PARTIAL_OTA_UPDATE_PARTITIONS_LIST
-_board_strip_list += BOARD_BPT_DISK_SIZE
-_board_strip_list += BOARD_BPT_INPUT_FILES
-_board_strip_list += BOARD_BPT_MAKE_TABLE_ARGS
_board_strip_list += BOARD_AVB_VBMETA_VENDOR_ROLLBACK_INDEX_LOCATION
_board_strip_list += BOARD_AVB_VBMETA_VENDOR_ALGORITHM
_board_strip_list += BOARD_AVB_VBMETA_VENDOR_KEY_PATH
@@ -174,7 +171,6 @@
_build_broken_var_list := \
- BUILD_BROKEN_PLUGIN_VALIDATION \
BUILD_BROKEN_CLANG_PROPERTY \
BUILD_BROKEN_CLANG_ASFLAGS \
BUILD_BROKEN_CLANG_CFLAGS \
@@ -189,7 +185,6 @@
BUILD_BROKEN_PREBUILT_ELF_FILES \
BUILD_BROKEN_TREBLE_SYSPROP_NEVERALLOW \
BUILD_BROKEN_USES_NETWORK \
- BUILD_BROKEN_USES_SOONG_PYTHON2_MODULES \
BUILD_BROKEN_VENDOR_PROPERTY_NAMESPACE \
BUILD_BROKEN_VINTF_PRODUCT_COPY_FILES \
diff --git a/core/build_id.mk b/core/build_id.mk
index ba5ca42..4c2c7fa 100644
--- a/core/build_id.mk
+++ b/core/build_id.mk
@@ -18,4 +18,4 @@
# (like "CRB01"). It must be a single word, and is
# capitalized by convention.
-BUILD_ID=AOSP.MASTER
+BUILD_ID=AOSP.MAIN
diff --git a/core/clear_vars.mk b/core/clear_vars.mk
index bb7ba1b..409e559 100644
--- a/core/clear_vars.mk
+++ b/core/clear_vars.mk
@@ -9,6 +9,7 @@
LOCAL_AAPT_FLAGS:=
LOCAL_AAPT_INCLUDE_ALL_RESOURCES:=
LOCAL_AAPT_NAMESPACES:=
+LOCAL_ACONFIG_FILES:=
LOCAL_ADDITIONAL_CERTIFICATES:=
LOCAL_ADDITIONAL_CHECKED_MODULE:=
LOCAL_ADDITIONAL_DEPENDENCIES:=
@@ -297,6 +298,7 @@
LOCAL_SOONG_PROGUARD_DICT :=
LOCAL_SOONG_PROGUARD_USAGE_ZIP :=
LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE :=
+LOCAL_SOONG_TRANSITIVE_RES_PACKAGES :=
LOCAL_SOONG_DEVICE_RRO_DIRS :=
LOCAL_SOONG_PRODUCT_RRO_DIRS :=
LOCAL_SOONG_STATIC_LIBRARY_EXTRA_PACKAGES :=
diff --git a/core/config.mk b/core/config.mk
index c166ef7..e919be3 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -342,6 +342,23 @@
JAVA_TMPDIR_ARG :=
endif
+# These build broken variables are intended to be set in a buildspec file,
+# while other build broken flags are expected to be set in a board config.
+# These are build broken variables that are expected to apply across board
+# configs, generally for cross-cutting features.
+
+# Build broken variables that should be treated as booleans
+_build_broken_bool_vars := \
+ BUILD_BROKEN_USES_SOONG_PYTHON2_MODULES \
+
+# Build broken variables that should be treated as lists
+_build_broken_list_vars := \
+ BUILD_BROKEN_PLUGIN_VALIDATION \
+
+_build_broken_var_names := $(_build_broken_bool_vars)
+_build_broken_var_names += $(_build_broken_list_vars)
+$(foreach v,$(_build_broken_var_names),$(eval $(v) :=))
+
# ###############################################################
# Include sub-configuration files
# ###############################################################
@@ -371,6 +388,13 @@
# are specific to the user's build configuration.
include $(BUILD_SYSTEM)/envsetup.mk
+
+$(foreach var,$(_build_broken_bool_vars), \
+ $(if $(filter-out true false,$($(var))), \
+ $(error Valid values of $(var) are "true", "false", and "". Not "$($(var))")))
+
+.KATI_READONLY := $(_build_broken_var_names)
+
# Returns true if it is a low memory device, otherwise it returns false.
define is-low-mem-device
$(if $(findstring ro.config.low_ram=true,$(PRODUCT_PROPERTY_OVERRIDES)),true,\
@@ -401,6 +425,7 @@
endif
# Set TARGET_MAX_PAGE_SIZE_SUPPORTED.
+# TARGET_MAX_PAGE_SIZE_SUPPORTED indicates the alignment of the ELF segments.
ifdef PRODUCT_MAX_PAGE_SIZE_SUPPORTED
TARGET_MAX_PAGE_SIZE_SUPPORTED := $(PRODUCT_MAX_PAGE_SIZE_SUPPORTED)
else ifeq ($(strip $(call is-low-mem-device)),true)
@@ -411,11 +436,38 @@
TARGET_MAX_PAGE_SIZE_SUPPORTED := 4096
# When VSR vendor API level >= 34, binary alignment will be 65536.
ifeq ($(call math_gt_or_eq,$(vsr_vendor_api_level),34),true)
+ ifeq ($(TARGET_ARCH),arm64)
TARGET_MAX_PAGE_SIZE_SUPPORTED := 65536
+ endif
+ ifeq ($(TARGET_ARCH),arm)
+ TARGET_MAX_PAGE_SIZE_SUPPORTED := 65536
+ endif
endif
endif
.KATI_READONLY := TARGET_MAX_PAGE_SIZE_SUPPORTED
+# Check that TARGET_MAX_PAGE_SIZE_SUPPORTED is greater than 4096 only for ARM arch.
+ifneq ($(TARGET_MAX_PAGE_SIZE_SUPPORTED),4096)
+ ifneq ($(TARGET_ARCH),arm64)
+ ifneq ($(TARGET_ARCH),arm)
+ $(error TARGET_MAX_PAGE_SIZE_SUPPORTED=$(TARGET_MAX_PAGE_SIZE_SUPPORTED) is greater than 4096. Only supported in ARM arch)
+ endif
+ endif
+endif
+
+# Boolean variable determining if AOSP is page size agnostic. This means
+# that AOSP can use a kernel configured with 4k/16k/64k PAGE SIZES.
+TARGET_PAGE_SIZE_AGNOSTIC := false
+ifdef PRODUCT_PAGE_SIZE_AGNOSTIC
+ TARGET_PAGE_SIZE_AGNOSTIC := $(PRODUCT_PAGE_SIZE_AGNOSTIC)
+ ifeq ($(TARGET_PAGE_SIZE_AGNOSTIC),true)
+ ifneq ($(TARGET_MAX_PAGE_SIZE_SUPPORTED),65536)
+ $(error TARGET_MAX_PAGE_SIZE_SUPPORTED has to be 65536 to support page size agnostic)
+ endif
+ endif
+endif
+.KATI_READONLY := TARGET_PAGE_SIZE_AGNOSTIC
+
# Pruned directory options used when using findleaves.py
# See envsetup.mk for a description of SCAN_EXCLUDE_DIRS
FIND_LEAVES_EXCLUDES := $(addprefix --prune=, $(SCAN_EXCLUDE_DIRS) .repo .git)
@@ -625,6 +677,7 @@
FILESLIST_UTIL :=$= build/make/tools/fileslist_util.py
HOST_INIT_VERIFIER := $(HOST_OUT_EXECUTABLES)/host_init_verifier
XMLLINT := $(HOST_OUT_EXECUTABLES)/xmllint
+ACONFIG := $(HOST_OUT_EXECUTABLES)/aconfig
# SOONG_ZIP is exported by Soong, but needs to be defined early for
# $OUT/dexpreopt.global. It will be verified against the Soong version.
@@ -645,10 +698,11 @@
# For non-supported hosts, do not generate breakpad symbols.
BREAKPAD_GENERATE_SYMBOLS := false
endif
+GZIP := prebuilts/build-tools/path/$(BUILD_OS)-$(HOST_PREBUILT_ARCH)/gzip
PROTOC := $(HOST_OUT_EXECUTABLES)/aprotoc$(HOST_EXECUTABLE_SUFFIX)
NANOPB_SRCS := $(HOST_OUT_EXECUTABLES)/protoc-gen-nanopb
MKBOOTFS := $(HOST_OUT_EXECUTABLES)/mkbootfs$(HOST_EXECUTABLE_SUFFIX)
-MINIGZIP := $(HOST_OUT_EXECUTABLES)/minigzip$(HOST_EXECUTABLE_SUFFIX)
+MINIGZIP := $(GZIP)
LZ4 := $(HOST_OUT_EXECUTABLES)/lz4$(HOST_EXECUTABLE_SUFFIX)
GENERATE_GKI_CERTIFICATE := $(HOST_OUT_EXECUTABLES)/generate_gki_certificate$(HOST_EXECUTABLE_SUFFIX)
ifeq (,$(strip $(BOARD_CUSTOM_MKBOOTIMG)))
@@ -722,7 +776,7 @@
# Path to tools.jar
HOST_JDK_TOOLS_JAR := $(ANDROID_JAVA8_HOME)/lib/tools.jar
-APICHECK_COMMAND := $(JAVA) -Xmx4g -jar $(APICHECK) --no-banner
+APICHECK_COMMAND := $(JAVA) -Xmx4g -jar $(APICHECK)
# Boolean variable determining if the allow list for compatible properties is enabled
PRODUCT_COMPATIBLE_PROPERTY := true
@@ -777,6 +831,9 @@
requirements :=
+# Set default value of KEEP_VNDK.
+KEEP_VNDK ?= true
+
# BOARD_PROPERTY_OVERRIDES_SPLIT_ENABLED can be true only if early-mount of
# partitions is supported. But the early-mount must be supported for full
# treble products, and so BOARD_PROPERTY_OVERRIDES_SPLIT_ENABLED should be set
diff --git a/core/config_sanitizers.mk b/core/config_sanitizers.mk
index 7fa190f..82b17be 100644
--- a/core/config_sanitizers.mk
+++ b/core/config_sanitizers.mk
@@ -413,7 +413,6 @@
my_cflags += -fvisibility=default
endif
my_ldflags += $(CFI_EXTRA_LDFLAGS)
- my_arflags += --plugin $(LLVM_PREBUILTS_PATH)/../lib64/LLVMgold.so
ifeq ($(LOCAL_FORCE_STATIC_EXECUTABLE),true)
my_ldflags := $(filter-out -fsanitize-cfi-cross-dso,$(my_ldflags))
diff --git a/core/definitions.mk b/core/definitions.mk
index be40584..62d482b 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -2377,6 +2377,7 @@
mkdir -p $(PRIVATE_JAVA_GEN_DIR)
$(call dump-words-to-file,$(PRIVATE_RES_FLAT),$(dir $@)aapt2-flat-list)
$(call dump-words-to-file,$(PRIVATE_OVERLAY_FLAT),$(dir $@)aapt2-flat-overlay-list)
+cat $(PRIVATE_STATIC_LIBRARY_TRANSITIVE_RES_PACKAGES_LISTS) | sort -u | tr '\n' ' ' > $(dir $@)aapt2-transitive-overlay-list
$(hide) $(AAPT2) link -o $@ \
$(PRIVATE_AAPT_FLAGS) \
$(if $(PRIVATE_STATIC_LIBRARY_EXTRA_PACKAGES),$$(cat $(PRIVATE_STATIC_LIBRARY_EXTRA_PACKAGES))) \
@@ -2396,6 +2397,7 @@
$(addprefix --rename-manifest-package ,$(PRIVATE_MANIFEST_PACKAGE_NAME)) \
$(addprefix --rename-instrumentation-target-package ,$(PRIVATE_MANIFEST_INSTRUMENTATION_FOR)) \
-R \@$(dir $@)aapt2-flat-overlay-list \
+ -R \@$(dir $@)aapt2-transitive-overlay-list \
\@$(dir $@)aapt2-flat-list
$(SOONG_ZIP) -o $(PRIVATE_SRCJAR) -C $(PRIVATE_JAVA_GEN_DIR) -D $(PRIVATE_JAVA_GEN_DIR)
$(EXTRACT_JAR_PACKAGES) -i $(PRIVATE_SRCJAR) -o $(PRIVATE_AAPT_EXTRA_PACKAGES) --prefix '--extra-packages '
@@ -2941,7 +2943,7 @@
define compress-package
$(hide) \
mv $@ $@.uncompressed; \
- $(MINIGZIP) -9 -c $@.uncompressed > $@.compressed; \
+ $(GZIP) -9 -c $@.uncompressed > $@.compressed; \
rm -f $@.uncompressed; \
mv $@.compressed $@;
endef
@@ -3201,8 +3203,9 @@
define copy-vintf-manifest-checked
$(2): $(1) $(HOST_OUT_EXECUTABLES)/assemble_vintf
@echo "Copy xml: $$@"
- $(hide) $(HOST_OUT_EXECUTABLES)/assemble_vintf -i $$< >/dev/null # Don't print the xml file to stdout.
- $$(copy-file-to-target)
+ $(hide) mkdir -p "$$(dir $$@)"
+ $(hide) VINTF_IGNORE_TARGET_FCM_VERSION=true\
+ $(HOST_OUT_EXECUTABLES)/assemble_vintf -i $$< -o $$@
endef
# Copies many vintf manifest files checked.
diff --git a/core/dex_preopt_config.mk b/core/dex_preopt_config.mk
index 7b9c4db..6739459 100644
--- a/core/dex_preopt_config.mk
+++ b/core/dex_preopt_config.mk
@@ -111,6 +111,7 @@
$(call add_json_list, BootJars, $(PRODUCT_BOOT_JARS))
$(call add_json_list, ApexBootJars, $(PRODUCT_APEX_BOOT_JARS))
$(call add_json_list, ArtApexJars, $(filter $(PRODUCT_BOOT_JARS),$(ART_APEX_JARS)))
+ $(call add_json_list, TestOnlyArtBootImageJars, $(PRODUCT_TEST_ONLY_ART_BOOT_IMAGE_JARS))
$(call add_json_list, SystemServerJars, $(PRODUCT_SYSTEM_SERVER_JARS))
$(call add_json_list, SystemServerApps, $(PRODUCT_SYSTEM_SERVER_APPS))
$(call add_json_list, ApexSystemServerJars, $(PRODUCT_APEX_SYSTEM_SERVER_JARS))
diff --git a/core/dupcheck.sh b/core/dupcheck.sh
new file mode 100755
index 0000000..13ab782
--- /dev/null
+++ b/core/dupcheck.sh
@@ -0,0 +1,118 @@
+#!/bin/bash
+
+# Find duplicate shared libraries by md5 checksum and possible duplicates by size.
+# Results will be available in the out directory of the build.
+# Usage:
+# ./dupcheck.sh <out_dir> <image>
+
+OUT_DIR="$1"
+IMG="$2"
+TMP_MD5="${OUT_DIR}/_dup_md5"
+TMP_SIZE="${OUT_DIR}/_dup_size"
+TMP_CHECK="${OUT_DIR}/_dup_tmp_check"
+TMP_SIZE_REAL="${OUT_DIR}/_dup_size_real"
+TMP_FILE1="${OUT_DIR}/_dup_f1"
+TMP_FILE2="${OUT_DIR}/_dup_f2"
+MD5_DUPLICATES="${OUT_DIR}/duplicate-libs-md5-${IMG}.txt"
+SIZE_DUPLICATES="${OUT_DIR}/duplicate-libs-size-${IMG}.txt"
+
+# Check arguments
+if [ "$#" -ne 2 ]; then
+ echo "Usage: ./dupcheck.sh <out_dir> <image>"
+ exit 1
+fi
+
+# Check host and toolchain version
+CHECK_HOST=$(uname)
+if [ "${CHECK_HOST}" == "Linux" ]; then
+ ARCH="linux-x86"
+else
+ ARCH="darwin-x86"
+fi
+BINUTILS_PATH="./prebuilts/clang/host/${ARCH}/llvm-binutils-stable"
+
+# Remove any old files if they exist.
+if [ -f "${MD5_DUPLICATES}" ]; then
+ rm "${MD5_DUPLICATES}"
+fi
+
+if [ -f "${SIZE_DUPLICATES}" ]; then
+ rm "${SIZE_DUPLICATES}"
+fi
+
+# Find all .so files and calculate their md5.
+find ./"${OUT_DIR}"/${IMG}/ -name "lib*.so" -type f -print0 | xargs -0 md5sum | sed -e "s# .*/# #" | sort | uniq -c | sort -g | sed "/^.*1 /d" | sed "s/^. *[0-9] //" > "${TMP_MD5}" 2>&1
+
+if [ -s "${TMP_MD5}" ]; then
+ while read -r list; do
+ checksum=$(echo "${list}" | cut -f1 -d ' ')
+ filename=$(echo "${list}" | cut -f2 -d ' ')
+ # For each md5, list the file paths that match.
+ {
+ echo "MD5: ${checksum}"; \
+ find ./"${OUT_DIR}"/${IMG}/ -name "${filename}" -type f -print0 | xargs -0 md5sum | grep "${checksum}" | sed 's/^.* //'; \
+ echo ""; \
+ } >> "${MD5_DUPLICATES}"
+ done <"${TMP_MD5}"
+else
+ echo "No duplicate files by md5 found." >> "${MD5_DUPLICATES}"
+fi
+
+# Cleanup
+rm "${TMP_MD5}"
+
+# Find possible duplicate .so files by size.
+find ./"${OUT_DIR}"/${IMG}/ -name "*.so" -type f -print0 | xargs -0 stat --format="%s %n" 2>/dev/null | sed -e "s# .*/# #" | sort | uniq -c | sort -g | sed "/^.*1 /d" > "${TMP_SIZE}" 2>&1
+if [ -s "${TMP_SIZE}" ]; then
+ while read -r list; do
+ size=$(echo "${list}" | cut -f2 -d ' ')
+ filename=$(echo "${list}" | cut -f3 -d ' ')
+ # Check if the files are not in the md5sum list and do nothing if that is the case.
+ find ./"${OUT_DIR}"/${IMG}/ -name "${filename}" -type f -print0 | xargs -0 stat --format="%s %n" 2>/dev/null | grep "${size}" | sed "s/^.* //" | sort > "${TMP_CHECK}" 2>&1
+ while read -r filepath; do
+ found=$(grep -F "${filepath}" "${MD5_DUPLICATES}")
+ if [ -z "${found}" ]; then
+ echo "${filepath}" >> "${TMP_SIZE_REAL}"
+ fi
+ done<"${TMP_CHECK}"
+ # For every duplication found, diff the .note and .text sections.
+ if [ -s "${TMP_SIZE_REAL}" ]; then
+ {
+ echo "File: ${filename}, Size: ${size}"; \
+ cat "${TMP_SIZE_REAL}"; \
+ echo ""; \
+ } >> "${SIZE_DUPLICATES}"
+ count=$(wc -l "${TMP_SIZE_REAL}" | cut -f1 -d ' ')
+ # Limitation: this only works for file pairs. If more than two possible duplications are found, the user need to check manually
+ # all the possible combinations using the llvm-readelf and llvm-objdump commands below.
+ if [ "${count}" = 2 ]; then
+ file1=$(head -n 1 "${TMP_SIZE_REAL}")
+ file2=$(tail -n 1 "${TMP_SIZE_REAL}")
+ # Check .note section
+ ${BINUTILS_PATH}/llvm-readelf --wide --notes "${file1}" > "${TMP_FILE1}" 2>&1
+ ${BINUTILS_PATH}/llvm-readelf --wide --notes "${file2}" > "${TMP_FILE2}" 2>&1
+ {
+ diff -u "${TMP_FILE1}" "${TMP_FILE2}" | sed "1d;2d;3d"; \
+ echo "";
+ } >> "${SIZE_DUPLICATES}"
+ # Check .text section
+ ${BINUTILS_PATH}/llvm-objdump --line-numbers --disassemble --demangle --reloc --no-show-raw-insn --section=.text "${file1}" | sed "1d;2d"> "${TMP_FILE1}" 2>&1
+ ${BINUTILS_PATH}/llvm-objdump --line-numbers --disassemble --demangle --reloc --no-show-raw-insn --section=.text "${file2}" | sed "1d;2d"> "${TMP_FILE2}" 2>&1
+ {
+ diff -u "${TMP_FILE1}" "${TMP_FILE2}" | sed "1d;2d;3d"; \
+ echo "";
+ } >> "${SIZE_DUPLICATES}"
+ # Cleanup
+ rm "${TMP_FILE1}" "${TMP_FILE2}"
+ else
+ echo "*Note: more than one duplicate. Manually verify all possible combinations." >> "${SIZE_DUPLICATES}"
+ fi
+ rm "${TMP_SIZE_REAL}"
+ echo "" >> "${SIZE_DUPLICATES}"
+ fi
+ done <"${TMP_SIZE}"
+ # Cleanup
+ rm "${TMP_SIZE}" "${TMP_CHECK}"
+else
+ echo "No duplicate files by size found." >> "${SIZE_DUPLICATES}"
+fi
diff --git a/core/main.mk b/core/main.mk
index 5a591f9..5738cdb 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -218,6 +218,12 @@
else
ADDITIONAL_VENDOR_PROPERTIES := ro.vndk.version=$(BOARD_VNDK_VERSION)
endif
+
+ # TODO(b/290159430): ro.vndk.deprecate is a temporal variable for deprecating VNDK.
+ # This variable will be removed once ro.vndk.version can be removed.
+ ifneq ($(KEEP_VNDK),true)
+ ADDITIONAL_SYSTEM_PROPERTIES += ro.vndk.deprecate=true
+ endif
endif
# Add cpu properties for bionic and ART.
@@ -810,12 +816,14 @@
# Sets up dependencies such that whenever a target module is installed,
# any other target modules listed in $(ALL_MODULES.$(m).REQUIRED_FROM_TARGET) will also be installed
+# This doesn't apply to ORDERONLY_INSTALLED items.
define add-all-target-to-target-required-modules-deps
$(foreach m,$(ALL_MODULES), \
$(eval r := $(ALL_MODULES.$(m).REQUIRED_FROM_TARGET)) \
$(if $(r), \
$(eval r := $(call module-installed-files,$(r))) \
$(eval t_m := $(filter $(TARGET_OUT_ROOT)/%, $(ALL_MODULES.$(m).INSTALLED))) \
+ $(eval t_m := $(filter-out $(ALL_MODULES.$(m).ORDERONLY_INSTALLED), $(ALL_MODULES.$(m).INSTALLED))) \
$(eval t_r := $(filter $(TARGET_OUT_ROOT)/%, $(r))) \
$(eval t_r := $(filter-out $(t_m), $(t_r))) \
$(if $(t_m), $(eval $(call add-required-deps, $(t_m),$(t_r)))) \
@@ -1356,6 +1364,7 @@
product_host_FILES := $(call host-installed-files,$(INTERNAL_PRODUCT))
product_target_FILES := $(call product-installed-files, $(INTERNAL_PRODUCT))
# WARNING: The product_MODULES variable is depended on by external files.
+ # It contains the list of register names that will be installed on the device
product_MODULES := $(_pif_modules)
# Verify the artifact path requirements made by included products.
@@ -1708,7 +1717,7 @@
# If they used the magic goal "all" then build all apps in the source tree.
unbundled_build_modules := $(foreach m,$(sort $(ALL_MODULES)),$(if $(filter APPS,$(ALL_MODULES.$(m).CLASS)),$(m)))
else
- unbundled_build_modules := $(TARGET_BUILD_APPS)
+ unbundled_build_modules := $(sort $(TARGET_BUILD_APPS))
endif
# Dist the installed files if they exist.
@@ -2186,7 +2195,9 @@
$(eval _is_fsverity_build_manifest_apk := $(if $(findstring $f,$(ALL_FSVERITY_BUILD_MANIFEST_APK)),Y)) \
$(eval _is_linker_config := $(if $(findstring $f,$(SYSTEM_LINKER_CONFIG) $(vendor_linker_config_file)),Y)) \
$(eval _is_partition_compat_symlink := $(if $(findstring $f,$(PARTITION_COMPAT_SYMLINKS)),Y)) \
- $(eval _is_platform_generated := $(_is_build_prop)$(_is_notice_file)$(_is_dexpreopt_image_profile)$(_is_product_system_other_avbkey)$(_is_event_log_tags_file)$(_is_system_other_odex_marker)$(_is_kernel_modules_blocklist)$(_is_fsverity_build_manifest_apk)$(_is_linker_config)$(_is_partition_compat_symlink)) \
+ $(eval _is_flags_file := $(if $(findstring $f, $(ALL_FLAGS_FILES)),Y)) \
+ $(eval _is_rootdir_symlink := $(if $(findstring $f, $(ALL_ROOTDIR_SYMLINKS)),Y)) \
+ $(eval _is_platform_generated := $(_is_build_prop)$(_is_notice_file)$(_is_dexpreopt_image_profile)$(_is_product_system_other_avbkey)$(_is_event_log_tags_file)$(_is_system_other_odex_marker)$(_is_kernel_modules_blocklist)$(_is_fsverity_build_manifest_apk)$(_is_linker_config)$(_is_partition_compat_symlink)$(_is_flags_file)$(_is_rootdir_symlink)) \
$(eval _static_libs := $(ALL_INSTALLED_FILES.$f.STATIC_LIBRARIES)) \
$(eval _whole_static_libs := $(ALL_INSTALLED_FILES.$f.WHOLE_STATIC_LIBRARIES)) \
$(foreach l,$(_static_libs),$(eval _all_static_libs += $l:$(strip $(sort $(ALL_MODULES.$l.PATH))):$(strip $(sort $(ALL_MODULES.$l.SOONG_MODULE_TYPE))):$(ALL_STATIC_LIBRARIES.$l.BUILT_FILE))) \
diff --git a/core/package_internal.mk b/core/package_internal.mk
index 7cfab5b..a03a62b 100644
--- a/core/package_internal.mk
+++ b/core/package_internal.mk
@@ -531,7 +531,7 @@
$(LOCAL_BUILT_MODULE): PRIVATE_RES_PACKAGE := $(my_res_package)
$(LOCAL_BUILT_MODULE) : $(my_res_package) $(AAPT2)
ifdef LOCAL_COMPRESSED_MODULE
-$(LOCAL_BUILT_MODULE) : $(MINIGZIP)
+$(LOCAL_BUILT_MODULE) : $(GZIP)
endif
ifeq (true, $(LOCAL_UNCOMPRESS_DEX))
$(LOCAL_BUILT_MODULE) : $(ZIP2ZIP)
diff --git a/core/packaging/flags.mk b/core/packaging/flags.mk
new file mode 100644
index 0000000..cb43741
--- /dev/null
+++ b/core/packaging/flags.mk
@@ -0,0 +1,123 @@
+# Copyright (C) 2023 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#
+# This file is included by build/make/core/Makefile, and contains the logic for
+# the combined flags files.
+#
+
+# TODO: Should we do all of the images in $(IMAGES_TO_BUILD)?
+_FLAG_PARTITIONS := product system system_ext vendor
+
+
+# -----------------------------------------------------------------
+# Release Config Flags
+
+# Create a summary file of build flags for each partition
+# $(1): built build flags json file
+# $(2): installed build flags json file
+# $(3): flag names
+define generate-partition-build-flag-file
+$(eval $(strip $(1)): PRIVATE_OUT := $(strip $(1)))
+$(eval $(strip $(1)): PRIVATE_FLAG_NAMES := $(strip $(3)))
+$(strip $(1)):
+ mkdir -p $$(dir $$(PRIVATE_OUT))
+ echo '{' > $$(PRIVATE_OUT)
+ echo '"flags": [' >> $$(PRIVATE_OUT)
+ $$(foreach flag, $$(PRIVATE_FLAG_NAMES), \
+ ( \
+ printf ' { "name": "%s", "value": "%s", ' \
+ '$$(flag)' \
+ '$$(_ALL_RELEASE_FLAGS.$$(flag).VALUE)' \
+ ; \
+ printf '"set": "%s", "default": "%s", "declared": "%s" }' \
+ '$$(_ALL_RELEASE_FLAGS.$$(flag).SET_IN)' \
+ '$$(_ALL_RELEASE_FLAGS.$$(flag).DEFAULT)' \
+ '$$(_ALL_RELEASE_FLAGS.$$(flag).DECLARED_IN)' \
+ ; \
+ printf '$$(if $$(filter $$(lastword $$(PRIVATE_FLAG_NAMES)),$$(flag)),,$$(comma))\n' ; \
+ ) >> $$(PRIVATE_OUT) ; \
+ )
+ echo "]" >> $$(PRIVATE_OUT)
+ echo "}" >> $$(PRIVATE_OUT)
+$(call copy-one-file, $(1), $(2))
+endef
+
+$(foreach partition, $(_FLAG_PARTITIONS), \
+ $(eval build_flag_summaries.$(partition) := $(PRODUCT_OUT)/$(partition)/etc/build_flags.json) \
+ $(eval $(call generate-partition-build-flag-file, \
+ $(TARGET_OUT_FLAGS)/$(partition)/build_flags.json, \
+ $(build_flag_summaries.$(partition)), \
+ $(_ALL_RELEASE_FLAGS.PARTITIONS.$(partition)) \
+ ) \
+ ) \
+)
+
+
+# -----------------------------------------------------------------
+# Aconfig Flags
+
+# Create a summary file of build flags for each partition
+# $(1): built aconfig flags textprot file (out)
+# $(2): installed aconfig flags textprot file (out)
+# $(3): input aconfig files for the partition (in)
+define generate-partition-aconfig-flag-file
+$(eval $(strip $(1)): PRIVATE_OUT := $(strip $(1)))
+$(eval $(strip $(1)): PRIVATE_IN := $(strip $(3)))
+$(strip $(1)): $(ACONFIG)
+ mkdir -p $$(dir $$(PRIVATE_OUT))
+ $$(if $$(PRIVATE_IN), \
+ $$(ACONFIG) dump --format textproto --out $$(PRIVATE_OUT) \
+ $$(addprefix --cache ,$$(PRIVATE_IN)), \
+ echo "# No aconfig flags" > $$(PRIVATE_OUT) \
+ )
+$(call copy-one-file, $(1), $(2))
+endef
+
+
+$(foreach partition, $(_FLAG_PARTITIONS), \
+ $(eval aconfig_flag_summaries.$(partition) := $(PRODUCT_OUT)/$(partition)/etc/aconfig_flags.textproto) \
+ $(eval $(call generate-partition-aconfig-flag-file, \
+ $(TARGET_OUT_FLAGS)/$(partition)/aconfig_flags.textproto, \
+ $(aconfig_flag_summaries.$(partition)), \
+ $(sort $(foreach m,$(call register-names-for-partition, $(partition)), \
+ $(ALL_MODULES.$(m).ACONFIG_FILES) \
+ )) \
+ )) \
+)
+
+
+# -----------------------------------------------------------------
+# Install the ones we need for the configured product
+required_flags_files := \
+ $(sort $(foreach partition, $(filter $(IMAGES_TO_BUILD), $(_FLAG_PARTITIONS)), \
+ $(build_flag_summaries.$(partition)) \
+ $(aconfig_flag_summaries.$(partition)) \
+ ))
+
+ALL_DEFAULT_INSTALLED_MODULES += $(required_flags_files)
+ALL_FLAGS_FILES := $(required_flags_files)
+
+# TODO: Remove
+.PHONY: flag-files
+flag-files: $(required_flags_files)
+
+
+# Clean up
+required_flags_files:=
+$(foreach partition, $(_FLAG_PARTITIONS), \
+ $(eval build_flag_summaries.$(partition):=) \
+ $(eval aconfig_flag_summaries.$(partition):=) \
+)
+
diff --git a/core/product.mk b/core/product.mk
index 8f4db38..b66f1e2 100644
--- a/core/product.mk
+++ b/core/product.mk
@@ -33,6 +33,10 @@
# 4096, 16384 and 65536.
_product_single_value_vars += PRODUCT_MAX_PAGE_SIZE_SUPPORTED
+# Indicates that AOSP can use a kernel configured with 4k/16k/64k page sizes.
+# The possible values are true or false.
+_product_single_value_vars += PRODUCT_PAGE_SIZE_AGNOSTIC
+
# The resource configuration options to use for this product.
_product_list_vars += PRODUCT_LOCALES
_product_list_vars += PRODUCT_AAPT_CONFIG
@@ -146,6 +150,9 @@
# PRODUCT_BOOT_JARS, so that device-specific jars go after common jars.
_product_list_vars += PRODUCT_BOOT_JARS_EXTRA
+# List of jars to be included in the ART boot image for testing.
+_product_list_vars += PRODUCT_TEST_ONLY_ART_BOOT_IMAGE_JARS
+
_product_single_value_vars += PRODUCT_SUPPORTS_VBOOT
_product_list_vars += PRODUCT_SYSTEM_SERVER_APPS
# List of system_server classpath jars on the platform.
@@ -317,6 +324,10 @@
_product_list_vars += PRODUCT_PACKAGE_NAME_OVERRIDES
_product_list_vars += PRODUCT_CERTIFICATE_OVERRIDES
+# Overrides the (apex, jar) pairs above when determining the on-device location. The format is:
+# <old_apex>:<old_jar>:<new_apex>:<new_jar>
+_product_list_vars += PRODUCT_CONFIGURED_JAR_LOCATION_OVERRIDES
+
# Controls for whether different partitions are built for the current product.
_product_single_value_vars += PRODUCT_BUILD_SYSTEM_IMAGE
_product_single_value_vars += PRODUCT_BUILD_SYSTEM_OTHER_IMAGE
diff --git a/core/rust_device_benchmark_config_template.xml b/core/rust_device_benchmark_config_template.xml
index 2055df2..541630c 100644
--- a/core/rust_device_benchmark_config_template.xml
+++ b/core/rust_device_benchmark_config_template.xml
@@ -16,7 +16,7 @@
<!-- This test config file is auto-generated. -->
<configuration description="Config to run {MODULE} rust benchmark tests.">
<target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
- <option name="cleanup" value="false" />
+ <option name="cleanup" value="true" />
<option name="push" value="{MODULE}->/data/local/tmp/{MODULE}" />
</target_preparer>
diff --git a/core/soong_app_prebuilt.mk b/core/soong_app_prebuilt.mk
index ccc5449..593dfa0 100644
--- a/core/soong_app_prebuilt.mk
+++ b/core/soong_app_prebuilt.mk
@@ -73,12 +73,14 @@
# We skip it for unbundled app builds where we cannot build veridex.
module_run_appcompat :=
ifeq (true,$(non_system_module))
-ifeq (,$(TARGET_BUILD_APPS)) # ! unbundled app build
+ifeq (,$(TARGET_BUILD_APPS)) # not unbundled app build
+ifeq (,$(filter sdk,$(MAKECMDGOALS))) # not sdk build (which is another form of unbundled build)
ifneq ($(UNSAFE_DISABLE_HIDDENAPI_FLAGS),true)
module_run_appcompat := true
endif
endif
endif
+endif
ifeq ($(module_run_appcompat),true)
$(LOCAL_BUILT_MODULE): $(appcompat-files)
diff --git a/core/soong_config.mk b/core/soong_config.mk
index 0d5799c..26998ed 100644
--- a/core/soong_config.mk
+++ b/core/soong_config.mk
@@ -40,6 +40,7 @@
$(call add_json_str, Platform_base_os, $(PLATFORM_BASE_OS))
$(call add_json_str, Platform_version_last_stable, $(PLATFORM_VERSION_LAST_STABLE))
$(call add_json_str, Platform_version_known_codenames, $(PLATFORM_VERSION_KNOWN_CODENAMES))
+$(call add_json_bool, Release_aidl_use_unfrozen, $(RELEASE_AIDL_USE_UNFROZEN))
$(call add_json_str, Platform_min_supported_target_sdk_version, $(PLATFORM_MIN_SUPPORTED_TARGET_SDK_VERSION))
@@ -150,6 +151,7 @@
$(call add_json_bool, Malloc_pattern_fill_contents, $(MALLOC_PATTERN_FILL_CONTENTS))
$(call add_json_str, Override_rs_driver, $(OVERRIDE_RS_DRIVER))
$(call add_json_str, DeviceMaxPageSizeSupported, $(TARGET_MAX_PAGE_SIZE_SUPPORTED))
+$(call add_json_bool, DevicePageSizeAgnostic, $(filter true,$(TARGET_PAGE_SIZE_AGNOSTIC)))
$(call add_json_bool, UncompressPrivAppDex, $(call invert_bool,$(filter true,$(DONT_UNCOMPRESS_PRIV_APPS_DEXS))))
$(call add_json_list, ModulesLoadedByPrivilegedModules, $(PRODUCT_LOADED_BY_PRIVILEGED_MODULES))
@@ -235,6 +237,7 @@
$(call add_json_list, ManifestPackageNameOverrides, $(PRODUCT_MANIFEST_PACKAGE_NAME_OVERRIDES))
$(call add_json_list, PackageNameOverrides, $(PRODUCT_PACKAGE_NAME_OVERRIDES))
$(call add_json_list, CertificateOverrides, $(PRODUCT_CERTIFICATE_OVERRIDES))
+$(call add_json_list, ConfiguredJarLocationOverrides, $(PRODUCT_CONFIGURED_JAR_LOCATION_OVERRIDES))
$(call add_json_str, ApexGlobalMinSdkVersionOverride, $(APEX_GLOBAL_MIN_SDK_VERSION_OVERRIDE))
@@ -317,6 +320,9 @@
$(call add_json_str, ReleaseVersion, $(_RELEASE_VERSION))
$(call add_json_list, ReleaseAconfigValueSets, $(RELEASE_ACONFIG_VALUE_SETS))
+$(call add_json_str, ReleaseAconfigFlagDefaultPermission, $(RELEASE_ACONFIG_FLAG_DEFAULT_PERMISSION))
+
+$(call add_json_bool, KeepVndk, $(filter true,$(KEEP_VNDK)))
$(call json_end)
diff --git a/core/soong_java_prebuilt.mk b/core/soong_java_prebuilt.mk
index a8f475f..c7c6a11 100644
--- a/core/soong_java_prebuilt.mk
+++ b/core/soong_java_prebuilt.mk
@@ -99,6 +99,17 @@
$(call add-dependency,$(LOCAL_BUILT_MODULE),$(my_res_package))
+ my_transitive_res_packages := $(intermediates.COMMON)/transitive-res-packages
+ $(my_transitive_res_packages): PRIVATE_TRANSITIVE_RES_PACKAGES := $(filter-out $(LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE),$(LOCAL_SOONG_TRANSITIVE_RES_PACKAGES))
+ $(my_transitive_res_packages):
+ @echo Write transitive resource package list $@
+ rm -f $@
+ touch $@
+ $(foreach f,$(PRIVATE_TRANSITIVE_RES_PACKAGES),\
+ echo "$f" >> $@; )
+
+ $(call add-dependency,$(my_res_package),$(my_transitive_res_packages))
+
my_proguard_flags := $(intermediates.COMMON)/export_proguard_flags
$(my_proguard_flags): $(LOCAL_SOONG_EXPORT_PROGUARD_FLAGS)
@echo "Export proguard flags: $@"
diff --git a/core/static_java_library.mk b/core/static_java_library.mk
index 4053985..4a72a1f 100644
--- a/core/static_java_library.mk
+++ b/core/static_java_library.mk
@@ -127,6 +127,12 @@
endif
endif
+# transitive-res-packages is only populated for Soong modules for now, but needs
+# to exist so that other Make modules can depend on it. Create an empty file.
+my_transitive_res_packages := $(intermediates.COMMON)/transitive-res-packages
+$(my_transitive_res_packages):
+ touch $@
+
import_proguard_flag_files := $(strip $(foreach l,$(LOCAL_STATIC_ANDROID_LIBRARIES) $(LOCAL_STATIC_JAVA_AAR_LIBRARIES),\
$(call intermediates-dir-for,JAVA_LIBRARIES,$(l),,COMMON)/export_proguard_flags))
$(intermediates.COMMON)/export_proguard_flags: $(import_proguard_flag_files) $(addprefix $(LOCAL_PATH)/,$(LOCAL_EXPORT_PROGUARD_FLAG_FILES))
diff --git a/core/sysprop.mk b/core/sysprop.mk
index a2296a8..451e88a 100644
--- a/core/sysprop.mk
+++ b/core/sysprop.mk
@@ -66,9 +66,12 @@
)\
echo "ro.$(1).build.date=`$(DATE_FROM_FILE)`" >> $(2);\
echo "ro.$(1).build.date.utc=`$(DATE_FROM_FILE) +%s`" >> $(2);\
- echo "ro.$(1).build.fingerprint=$(BUILD_FINGERPRINT_FROM_FILE)" >> $(2);\
- echo "ro.$(1).build.id=$(BUILD_ID)" >> $(2);\
- echo "ro.$(1).build.tags=$(BUILD_VERSION_TAGS)" >> $(2);\
+ # Allow optional assignments for ARC forward-declarations (b/249168657)
+ # TODO: Remove any tag-related inconsistencies once the goals from
+ # go/arc-android-sigprop-changes have been achieved.
+ echo "ro.$(1).build.fingerprint?=$(BUILD_FINGERPRINT_FROM_FILE)" >> $(2);\
+ echo "ro.$(1).build.id?=$(BUILD_ID)" >> $(2);\
+ echo "ro.$(1).build.tags?=$(BUILD_VERSION_TAGS)" >> $(2);\
echo "ro.$(1).build.type=$(TARGET_BUILD_VARIANT)" >> $(2);\
echo "ro.$(1).build.version.incremental=$(BUILD_NUMBER_FROM_FILE)" >> $(2);\
echo "ro.$(1).build.version.release=$(PLATFORM_VERSION_LAST_STABLE)" >> $(2);\
@@ -565,4 +568,4 @@
# $1 installed file path, e.g. out/target/product/vsoc_x86_64/system/build.prop
define is-build-prop
$(if $(findstring $1,$(ALL_INSTALLED_BUILD_PROP_FILES)),Y)
-endef
\ No newline at end of file
+endef
diff --git a/core/tasks/module-info.mk b/core/tasks/module-info.mk
index 66ba8f1..9668b53 100644
--- a/core/tasks/module-info.mk
+++ b/core/tasks/module-info.mk
@@ -2,40 +2,40 @@
# Currently runtime_dependencies only include the runtime libs information for cc binaries.
MODULE_INFO_JSON := $(PRODUCT_OUT)/module-info.json
+COMMA := ,
+_NEWLINE := '\n'
$(MODULE_INFO_JSON):
@echo Generating $@
$(hide) echo -ne '{\n ' > $@
- $(hide) echo -ne $(foreach m, $(sort $(ALL_MODULES)), \
- ' "$(m)": {' \
- '"class": [$(foreach w,$(sort $(ALL_MODULES.$(m).CLASS)),"$(w)", )], ' \
- '"path": [$(foreach w,$(sort $(ALL_MODULES.$(m).PATH)),"$(w)", )], ' \
- '"tags": [$(foreach w,$(sort $(ALL_MODULES.$(m).TAGS)),"$(w)", )], ' \
- '"installed": [$(foreach w,$(sort $(ALL_MODULES.$(m).INSTALLED)),"$(w)", )], ' \
- '"compatibility_suites": [$(foreach w,$(sort $(ALL_MODULES.$(m).COMPATIBILITY_SUITES)),"$(w)", )], ' \
- '"auto_test_config": [$(ALL_MODULES.$(m).auto_test_config)], ' \
- '"module_name": "$(ALL_MODULES.$(m).MODULE_NAME)", ' \
- '"test_config": [$(foreach w,$(strip $(ALL_MODULES.$(m).TEST_CONFIG) $(ALL_MODULES.$(m).EXTRA_TEST_CONFIGS)),"$(w)", )], ' \
- '"dependencies": [$(foreach w,$(sort $(ALL_DEPS.$(m).ALL_DEPS)),"$(w)", )], ' \
- '"shared_libs": [$(foreach w,$(sort $(ALL_MODULES.$(m).SHARED_LIBS)),"$(w)", )], ' \
- '"static_libs": [$(foreach w,$(sort $(ALL_MODULES.$(m).STATIC_LIBS)),"$(w)", )], ' \
- '"system_shared_libs": [$(foreach w,$(sort $(ALL_MODULES.$(m).SYSTEM_SHARED_LIBS)),"$(w)", )], ' \
- '"srcs": [$(foreach w,$(sort $(ALL_MODULES.$(m).SRCS)),"$(w)", )], ' \
- '"srcjars": [$(foreach w,$(sort $(ALL_MODULES.$(m).SRCJARS)),"$(w)", )], ' \
- '"classes_jar": [$(foreach w,$(sort $(ALL_MODULES.$(m).CLASSES_JAR)),"$(w)", )], ' \
- '"test_mainline_modules": [$(foreach w,$(sort $(ALL_MODULES.$(m).TEST_MAINLINE_MODULES)),"$(w)", )], ' \
- '"is_unit_test": "$(ALL_MODULES.$(m).IS_UNIT_TEST)", ' \
- '"test_options_tags": [$(foreach w,$(sort $(ALL_MODULES.$(m).TEST_OPTIONS_TAGS)),"$(w)", )], ' \
- '"data": [$(foreach w,$(sort $(ALL_MODULES.$(m).TEST_DATA)),"$(w)", )], ' \
- '"runtime_dependencies": [$(foreach w,$(sort $(ALL_MODULES.$(m).LOCAL_RUNTIME_LIBRARIES)),"$(w)", )], ' \
- '"static_dependencies": [$(foreach w,$(sort $(ALL_MODULES.$(m).LOCAL_STATIC_LIBRARIES)),"$(w)", )], ' \
- '"data_dependencies": [$(foreach w,$(sort $(ALL_MODULES.$(m).TEST_DATA_BINS)),"$(w)", )], ' \
- '"supported_variants": [$(foreach w,$(sort $(ALL_MODULES.$(m).SUPPORTED_VARIANTS)),"$(w)", )], ' \
- '"host_dependencies": [$(foreach w,$(sort $(ALL_MODULES.$(m).HOST_REQUIRED_FROM_TARGET)),"$(w)", )], ' \
- '"target_dependencies": [$(foreach w,$(sort $(ALL_MODULES.$(m).TARGET_REQUIRED_FROM_HOST)),"$(w)", )], ' \
- '},\n' \
- ) | sed -e 's/, *\]/]/g' -e 's/, *\}/ }/g' -e '$$s/,$$//' >> $@
- $(hide) echo '}' >> $@
+ $(hide) echo -ne $(KATI_foreach_sep m,$(COMMA)$(_NEWLINE), $(sort $(ALL_MODULES)),\
+ '"$(m)": {' \
+ '"class": [$(KATI_foreach_sep w,$(COMMA) ,$(sort $(ALL_MODULES.$(m).CLASS)),"$(w)")],' \
+ '"path": [$(KATI_foreach_sep w,$(COMMA) ,$(sort $(ALL_MODULES.$(m).PATH)),"$(w)")],' \
+ '"tags": [$(KATI_foreach_sep w,$(COMMA) ,$(sort $(ALL_MODULES.$(m).TAGS)),"$(w)")],' \
+ '"installed": [$(KATI_foreach_sep w,$(COMMA) ,$(sort $(ALL_MODULES.$(m).INSTALLED)),"$(w)")],' \
+ '"compatibility_suites": [$(KATI_foreach_sep w,$(COMMA) ,$(sort $(ALL_MODULES.$(m).COMPATIBILITY_SUITES)),"$(w)")],' \
+ '"auto_test_config": [$(ALL_MODULES.$(m).auto_test_config)],' \
+ '"module_name": "$(ALL_MODULES.$(m).MODULE_NAME)"$(COMMA)' \
+ '"test_config": [$(KATI_foreach_sep w,$(COMMA) ,$(strip $(ALL_MODULES.$(m).TEST_CONFIG) $(ALL_MODULES.$(m).EXTRA_TEST_CONFIGS)),"$(w)")],' \
+ '"dependencies": [$(KATI_foreach_sep w,$(COMMA) ,$(sort $(ALL_DEPS.$(m).ALL_DEPS)),"$(w)")],' \
+ '"shared_libs": [$(KATI_foreach_sep w,$(COMMA) ,$(sort $(ALL_MODULES.$(m).SHARED_LIBS)),"$(w)")],' \
+ '"static_libs": [$(KATI_foreach_sep w,$(COMMA) ,$(sort $(ALL_MODULES.$(m).STATIC_LIBS)),"$(w)")],' \
+ '"system_shared_libs": [$(KATI_foreach_sep w,$(COMMA) ,$(sort $(ALL_MODULES.$(m).SYSTEM_SHARED_LIBS)),"$(w)")],' \
+ '"srcs": [$(KATI_foreach_sep w,$(COMMA) ,$(sort $(ALL_MODULES.$(m).SRCS)),"$(w)")],' \
+ '"srcjars": [$(KATI_foreach_sep w,$(COMMA) ,$(sort $(ALL_MODULES.$(m).SRCJARS)),"$(w)")],' \
+ '"classes_jar": [$(KATI_foreach_sep w,$(COMMA) ,$(sort $(ALL_MODULES.$(m).CLASSES_JAR)),"$(w)")],' \
+ '"test_mainline_modules": [$(KATI_foreach_sep w,$(COMMA) ,$(sort $(ALL_MODULES.$(m).TEST_MAINLINE_MODULES)),"$(w)")],' \
+ '"is_unit_test": "$(ALL_MODULES.$(m).IS_UNIT_TEST)"$(COMMA)' \
+ '"test_options_tags": [$(KATI_foreach_sep w,$(COMMA) ,$(sort $(ALL_MODULES.$(m).TEST_OPTIONS_TAGS)),"$(w)")],' \
+ '"data": [$(KATI_foreach_sep w,$(COMMA) ,$(sort $(ALL_MODULES.$(m).TEST_DATA)),"$(w)")],' \
+ '"runtime_dependencies": [$(KATI_foreach_sep w,$(COMMA) ,$(sort $(ALL_MODULES.$(m).LOCAL_RUNTIME_LIBRARIES)),"$(w)")],' \
+ '"static_dependencies": [$(KATI_foreach_sep w,$(COMMA) ,$(sort $(ALL_MODULES.$(m).LOCAL_STATIC_LIBRARIES)),"$(w)")],' \
+ '"data_dependencies": [$(KATI_foreach_sep w,$(COMMA) ,$(sort $(ALL_MODULES.$(m).TEST_DATA_BINS)),"$(w)")],' \
+ '"supported_variants": [$(KATI_foreach_sep w,$(COMMA) ,$(sort $(ALL_MODULES.$(m).SUPPORTED_VARIANTS)),"$(w)")],' \
+ '"host_dependencies": [$(KATI_foreach_sep w,$(COMMA) ,$(sort $(ALL_MODULES.$(m).HOST_REQUIRED_FROM_TARGET)),"$(w)")],' \
+ '"target_dependencies": [$(KATI_foreach_sep w,$(COMMA) ,$(sort $(ALL_MODULES.$(m).TARGET_REQUIRED_FROM_HOST)),"$(w)")]' \
+ '}')'\n}\n' >> $@
droidcore-unbundled: $(MODULE_INFO_JSON)
diff --git a/core/version_defaults.mk b/core/version_defaults.mk
index c107254..e288779 100644
--- a/core/version_defaults.mk
+++ b/core/version_defaults.mk
@@ -103,7 +103,7 @@
# It must be of the form "YYYY-MM-DD" on production devices.
# It must match one of the Android Security Patch Level strings of the Public Security Bulletins.
# If there is no $PLATFORM_SECURITY_PATCH set, keep it empty.
- PLATFORM_SECURITY_PATCH := 2023-06-05
+ PLATFORM_SECURITY_PATCH := 2023-07-05
endif
include $(BUILD_SYSTEM)/version_util.mk
diff --git a/envsetup.sh b/envsetup.sh
index f4755dd..0a90460 100644
--- a/envsetup.sh
+++ b/envsetup.sh
@@ -1075,6 +1075,10 @@
echo "can't find Android.mk"
}
+function adb() {
+ command adb "${@}"
+}
+
# simplified version of ps; output in the form
# <pid> <procname>
function qpid() {
@@ -1358,53 +1362,6 @@
get_abs_build_var ANDROID_PREBUILTS
}
-function tracedmdump()
-{
- local T=$(gettop)
- if [ ! "$T" ]; then
- echo "Couldn't locate the top of the tree. Try setting TOP."
- return
- fi
- local prebuiltdir=$(getprebuilt)
- local arch=$(gettargetarch)
- local KERNEL=$T/prebuilts/qemu-kernel/$arch/vmlinux-qemu
-
- local TRACE=$1
- if [ ! "$TRACE" ] ; then
- echo "usage: tracedmdump tracename"
- return
- fi
-
- if [ ! -r "$KERNEL" ] ; then
- echo "Error: cannot find kernel: '$KERNEL'"
- return
- fi
-
- local BASETRACE=$(basename $TRACE)
- if [ "$BASETRACE" = "$TRACE" ] ; then
- TRACE=$ANDROID_PRODUCT_OUT/traces/$TRACE
- fi
-
- echo "post-processing traces..."
- rm -f $TRACE/qtrace.dexlist
- post_trace $TRACE
- if [ $? -ne 0 ]; then
- echo "***"
- echo "*** Error: malformed trace. Did you remember to exit the emulator?"
- echo "***"
- return
- fi
- echo "generating dexlist output..."
- /bin/ls $ANDROID_PRODUCT_OUT/system/framework/*.jar $ANDROID_PRODUCT_OUT/system/app/*.apk $ANDROID_PRODUCT_OUT/data/app/*.apk 2>/dev/null | xargs dexlist > $TRACE/qtrace.dexlist
- echo "generating dmtrace data..."
- q2dm -r $ANDROID_PRODUCT_OUT/symbols $TRACE $KERNEL $TRACE/dmtrace || return
- echo "generating html file..."
- dmtracedump -h $TRACE/dmtrace >| $TRACE/dmtrace.html || return
- echo "done, see $TRACE/dmtrace.html for details"
- echo "or run:"
- echo " traceview $TRACE/dmtrace"
-}
-
# communicate with a running device or emulator, set up necessary state,
# and run the hat command.
function runhat()
diff --git a/target/board/generic/BoardConfig.mk b/target/board/generic/BoardConfig.mk
index 87c16da..6720ddb 100644
--- a/target/board/generic/BoardConfig.mk
+++ b/target/board/generic/BoardConfig.mk
@@ -30,20 +30,3 @@
TARGET_CPU_ABI2 := armeabi
include build/make/target/board/BoardConfigGsiCommon.mk
-
-ifndef BUILDING_GSI
-include build/make/target/board/BoardConfigEmuCommon.mk
-
-BOARD_USERDATAIMAGE_PARTITION_SIZE := 576716800
-
-# Wifi.
-BOARD_WLAN_DEVICE := emulator
-BOARD_HOSTAPD_DRIVER := NL80211
-BOARD_WPA_SUPPLICANT_DRIVER := NL80211
-BOARD_HOSTAPD_PRIVATE_LIB := lib_driver_cmd_simulated
-BOARD_WPA_SUPPLICANT_PRIVATE_LIB := lib_driver_cmd_simulated
-WPA_SUPPLICANT_VERSION := VER_0_8_X
-WIFI_DRIVER_FW_PATH_PARAM := "/dev/null"
-WIFI_DRIVER_FW_PATH_STA := "/dev/null"
-WIFI_DRIVER_FW_PATH_AP := "/dev/null"
-endif
diff --git a/target/board/generic/device.mk b/target/board/generic/device.mk
index 76242c9..76edf6b 100644
--- a/target/board/generic/device.mk
+++ b/target/board/generic/device.mk
@@ -14,5 +14,3 @@
# limitations under the License.
#
-PRODUCT_SOONG_NAMESPACES += device/generic/goldfish # for libwifi-hal-emu
-PRODUCT_SOONG_NAMESPACES += device/generic/goldfish-opengl # for goldfish deps.
diff --git a/target/board/generic_64bitonly_x86_64/BoardConfig.mk b/target/board/generic_64bitonly_x86_64/BoardConfig.mk
index a240eab..a129ea0 100644
--- a/target/board/generic_64bitonly_x86_64/BoardConfig.mk
+++ b/target/board/generic_64bitonly_x86_64/BoardConfig.mk
@@ -28,23 +28,3 @@
TARGET_PRELINK_MODULE := false
include build/make/target/board/BoardConfigGsiCommon.mk
-
-ifndef BUILDING_GSI
-include build/make/target/board/BoardConfigEmuCommon.mk
-
-BOARD_USERDATAIMAGE_PARTITION_SIZE := 576716800
-
-BOARD_SEPOLICY_DIRS += device/generic/goldfish/sepolicy/x86
-
-# Wifi.
-BOARD_WLAN_DEVICE := emulator
-BOARD_HOSTAPD_DRIVER := NL80211
-BOARD_WPA_SUPPLICANT_DRIVER := NL80211
-BOARD_HOSTAPD_PRIVATE_LIB := lib_driver_cmd_simulated
-BOARD_WPA_SUPPLICANT_PRIVATE_LIB := lib_driver_cmd_simulated
-WPA_SUPPLICANT_VERSION := VER_0_8_X
-WIFI_DRIVER_FW_PATH_PARAM := "/dev/null"
-WIFI_DRIVER_FW_PATH_STA := "/dev/null"
-WIFI_DRIVER_FW_PATH_AP := "/dev/null"
-
-endif # !BUILDING_GSI
diff --git a/target/board/generic_x86/BoardConfig.mk b/target/board/generic_x86/BoardConfig.mk
index 47fd384..26bede8 100644
--- a/target/board/generic_x86/BoardConfig.mk
+++ b/target/board/generic_x86/BoardConfig.mk
@@ -19,23 +19,3 @@
TARGET_ARCH_VARIANT := x86
include build/make/target/board/BoardConfigGsiCommon.mk
-
-ifndef BUILDING_GSI
-include build/make/target/board/BoardConfigEmuCommon.mk
-
-# Resize to 4G to accomodate ASAN and CTS
-BOARD_USERDATAIMAGE_PARTITION_SIZE := 4294967296
-
-BOARD_SEPOLICY_DIRS += device/generic/goldfish/sepolicy/x86
-
-# Wifi.
-BOARD_WLAN_DEVICE := emulator
-BOARD_HOSTAPD_DRIVER := NL80211
-BOARD_WPA_SUPPLICANT_DRIVER := NL80211
-BOARD_HOSTAPD_PRIVATE_LIB := lib_driver_cmd_simulated
-BOARD_WPA_SUPPLICANT_PRIVATE_LIB := lib_driver_cmd_simulated
-WPA_SUPPLICANT_VERSION := VER_0_8_X
-WIFI_DRIVER_FW_PATH_PARAM := "/dev/null"
-WIFI_DRIVER_FW_PATH_STA := "/dev/null"
-WIFI_DRIVER_FW_PATH_AP := "/dev/null"
-endif
diff --git a/target/board/generic_x86/device.mk b/target/board/generic_x86/device.mk
index 5ad008f..60f0cc3 100644
--- a/target/board/generic_x86/device.mk
+++ b/target/board/generic_x86/device.mk
@@ -14,9 +14,6 @@
# limitations under the License.
#
-PRODUCT_SOONG_NAMESPACES += device/generic/goldfish # for libwifi-hal-emu
-PRODUCT_SOONG_NAMESPACES += device/generic/goldfish-opengl # for goldfish deps.
-
ifdef NET_ETH0_STARTONBOOT
PRODUCT_VENDOR_PROPERTIES += net.eth0.startonboot=1
endif
diff --git a/target/board/generic_x86_64/BoardConfig.mk b/target/board/generic_x86_64/BoardConfig.mk
old mode 100755
new mode 100644
index 36136f4..64da578
--- a/target/board/generic_x86_64/BoardConfig.mk
+++ b/target/board/generic_x86_64/BoardConfig.mk
@@ -28,23 +28,3 @@
TARGET_DYNAMIC_64_32_DRMSERVER := true
include build/make/target/board/BoardConfigGsiCommon.mk
-
-ifndef BUILDING_GSI
-include build/make/target/board/BoardConfigEmuCommon.mk
-
-BOARD_USERDATAIMAGE_PARTITION_SIZE := 576716800
-
-BOARD_SEPOLICY_DIRS += device/generic/goldfish/sepolicy/x86
-
-# Wifi.
-BOARD_WLAN_DEVICE := emulator
-BOARD_HOSTAPD_DRIVER := NL80211
-BOARD_WPA_SUPPLICANT_DRIVER := NL80211
-BOARD_HOSTAPD_PRIVATE_LIB := lib_driver_cmd_simulated
-BOARD_WPA_SUPPLICANT_PRIVATE_LIB := lib_driver_cmd_simulated
-WPA_SUPPLICANT_VERSION := VER_0_8_X
-WIFI_DRIVER_FW_PATH_PARAM := "/dev/null"
-WIFI_DRIVER_FW_PATH_STA := "/dev/null"
-WIFI_DRIVER_FW_PATH_AP := "/dev/null"
-
-endif # !BUILDING_GSI
diff --git a/target/board/generic_x86_64_arm64/BoardConfig.mk b/target/board/generic_x86_64_arm64/BoardConfig.mk
old mode 100755
new mode 100644
index f528294..818ec44
--- a/target/board/generic_x86_64_arm64/BoardConfig.mk
+++ b/target/board/generic_x86_64_arm64/BoardConfig.mk
@@ -13,7 +13,6 @@
# limitations under the License.
#
-# x86_64 emulator specific definitions
TARGET_CPU_ABI := x86_64
TARGET_ARCH := x86_64
TARGET_ARCH_VARIANT := x86_64
@@ -37,23 +36,9 @@
TARGET_PRELINK_MODULE := false
include build/make/target/board/BoardConfigMainlineCommon.mk
-include build/make/target/board/BoardConfigEmuCommon.mk
# the settings differ from BoardConfigMainlineCommon.mk
BOARD_USES_SYSTEM_OTHER_ODEX :=
# Resize to 4G to accommodate ASAN and CTS
BOARD_USERDATAIMAGE_PARTITION_SIZE := 4294967296
-
-BOARD_SEPOLICY_DIRS += device/generic/goldfish/sepolicy/x86
-
-# Wifi.
-BOARD_WLAN_DEVICE := emulator
-BOARD_HOSTAPD_DRIVER := NL80211
-BOARD_WPA_SUPPLICANT_DRIVER := NL80211
-BOARD_HOSTAPD_PRIVATE_LIB := lib_driver_cmd_simulated
-BOARD_WPA_SUPPLICANT_PRIVATE_LIB := lib_driver_cmd_simulated
-WPA_SUPPLICANT_VERSION := VER_0_8_X
-WIFI_DRIVER_FW_PATH_PARAM := "/dev/null"
-WIFI_DRIVER_FW_PATH_STA := "/dev/null"
-WIFI_DRIVER_FW_PATH_AP := "/dev/null"
diff --git a/target/board/generic_x86_64_arm64/device.mk b/target/board/generic_x86_64_arm64/device.mk
old mode 100755
new mode 100644
index 76242c9..76edf6b
--- a/target/board/generic_x86_64_arm64/device.mk
+++ b/target/board/generic_x86_64_arm64/device.mk
@@ -14,5 +14,3 @@
# limitations under the License.
#
-PRODUCT_SOONG_NAMESPACES += device/generic/goldfish # for libwifi-hal-emu
-PRODUCT_SOONG_NAMESPACES += device/generic/goldfish-opengl # for goldfish deps.
diff --git a/target/board/generic_x86_arm/BoardConfig.mk b/target/board/generic_x86_arm/BoardConfig.mk
index f6589b0..62bb5eb 100644
--- a/target/board/generic_x86_arm/BoardConfig.mk
+++ b/target/board/generic_x86_arm/BoardConfig.mk
@@ -13,7 +13,6 @@
# limitations under the License.
#
-# x86 emulator specific definitions
TARGET_CPU_ABI := x86
TARGET_ARCH := x86
TARGET_ARCH_VARIANT := x86
@@ -30,23 +29,9 @@
# The settings in latter makefiles overwrite those in the former.
#
include build/make/target/board/BoardConfigMainlineCommon.mk
-include build/make/target/board/BoardConfigEmuCommon.mk
# the settings differ from BoardConfigMainlineCommon.mk
BOARD_USES_SYSTEM_OTHER_ODEX :=
# Resize to 4G to accomodate ASAN and CTS
BOARD_USERDATAIMAGE_PARTITION_SIZE := 4294967296
-
-BOARD_SEPOLICY_DIRS += device/generic/goldfish/sepolicy/x86
-
-# Wifi.
-BOARD_WLAN_DEVICE := emulator
-BOARD_HOSTAPD_DRIVER := NL80211
-BOARD_WPA_SUPPLICANT_DRIVER := NL80211
-BOARD_HOSTAPD_PRIVATE_LIB := lib_driver_cmd_simulated
-BOARD_WPA_SUPPLICANT_PRIVATE_LIB := lib_driver_cmd_simulated
-WPA_SUPPLICANT_VERSION := VER_0_8_X
-WIFI_DRIVER_FW_PATH_PARAM := "/dev/null"
-WIFI_DRIVER_FW_PATH_STA := "/dev/null"
-WIFI_DRIVER_FW_PATH_AP := "/dev/null"
diff --git a/target/board/generic_x86_arm/device.mk b/target/board/generic_x86_arm/device.mk
index 76242c9..76edf6b 100644
--- a/target/board/generic_x86_arm/device.mk
+++ b/target/board/generic_x86_arm/device.mk
@@ -14,5 +14,3 @@
# limitations under the License.
#
-PRODUCT_SOONG_NAMESPACES += device/generic/goldfish # for libwifi-hal-emu
-PRODUCT_SOONG_NAMESPACES += device/generic/goldfish-opengl # for goldfish deps.
diff --git a/target/product/aosp_64bitonly_x86_64.mk b/target/product/aosp_64bitonly_x86_64.mk
index 75fd3c8..cf812a2 100644
--- a/target/product/aosp_64bitonly_x86_64.mk
+++ b/target/product/aosp_64bitonly_x86_64.mk
@@ -51,7 +51,6 @@
#
# All components inherited here go to vendor image
#
-$(call inherit-product, $(SRC_TARGET_DIR)/product/emulator_vendor.mk)
$(call inherit-product, $(SRC_TARGET_DIR)/board/generic_x86_64/device.mk)
#
diff --git a/target/product/aosp_arm.mk b/target/product/aosp_arm.mk
index 61c1316..d9c362e 100644
--- a/target/product/aosp_arm.mk
+++ b/target/product/aosp_arm.mk
@@ -50,7 +50,6 @@
# All components inherited here go to vendor image
#
$(call inherit-product-if-exists, build/make/target/product/ramdisk_stub.mk)
-$(call inherit-product, $(SRC_TARGET_DIR)/product/emulator_vendor.mk)
$(call inherit-product, $(SRC_TARGET_DIR)/board/generic_x86/device.mk)
#
diff --git a/target/product/aosp_arm64.mk b/target/product/aosp_arm64.mk
index 6c907db..d3514a5 100644
--- a/target/product/aosp_arm64.mk
+++ b/target/product/aosp_arm64.mk
@@ -54,7 +54,6 @@
#
# All components inherited here go to vendor or vendor_boot image
#
-$(call inherit-product, $(SRC_TARGET_DIR)/product/emulator_vendor.mk)
$(call inherit-product, $(SRC_TARGET_DIR)/board/generic_arm64/device.mk)
$(call inherit-product, $(SRC_TARGET_DIR)/product/non_ab_device.mk)
diff --git a/target/product/aosp_riscv64.mk b/target/product/aosp_riscv64.mk
index 270a989..fa503ff 100644
--- a/target/product/aosp_riscv64.mk
+++ b/target/product/aosp_riscv64.mk
@@ -46,7 +46,6 @@
#
# All components inherited here go to vendor image
#
-$(call inherit-product, $(SRC_TARGET_DIR)/product/emulator_vendor.mk)
$(call inherit-product, $(SRC_TARGET_DIR)/board/generic_riscv64/device.mk)
#
diff --git a/target/product/aosp_x86.mk b/target/product/aosp_x86.mk
index a2f0390..c26a8bf 100644
--- a/target/product/aosp_x86.mk
+++ b/target/product/aosp_x86.mk
@@ -47,7 +47,6 @@
#
# All components inherited here go to vendor image
#
-$(call inherit-product, $(SRC_TARGET_DIR)/product/emulator_vendor.mk)
$(call inherit-product, $(SRC_TARGET_DIR)/board/generic_x86/device.mk)
diff --git a/target/product/aosp_x86_64.mk b/target/product/aosp_x86_64.mk
index 535ee3f..3040dd3 100644
--- a/target/product/aosp_x86_64.mk
+++ b/target/product/aosp_x86_64.mk
@@ -56,7 +56,6 @@
#
# All components inherited here go to vendor image
#
-$(call inherit-product, $(SRC_TARGET_DIR)/product/emulator_vendor.mk)
$(call inherit-product, $(SRC_TARGET_DIR)/board/generic_x86_64/device.mk)
$(call inherit-product, $(SRC_TARGET_DIR)/product/non_ab_device.mk)
diff --git a/target/product/aosp_x86_arm.mk b/target/product/aosp_x86_arm.mk
index 39ad0d8..a103b1a 100644
--- a/target/product/aosp_x86_arm.mk
+++ b/target/product/aosp_x86_arm.mk
@@ -45,7 +45,6 @@
#
# All components inherited here go to vendor image
#
-$(call inherit-product, $(SRC_TARGET_DIR)/product/emulator_vendor.mk)
$(call inherit-product, $(SRC_TARGET_DIR)/board/generic_x86_arm/device.mk)
diff --git a/target/product/base_system.mk b/target/product/base_system.mk
index 7fc33b0..6dd85f0 100644
--- a/target/product/base_system.mk
+++ b/target/product/base_system.mk
@@ -89,7 +89,6 @@
dump.erofs \
dumpstate \
dumpsys \
- DynamicSystemInstallationService \
e2fsck \
ExtShared \
flags_health_check \
@@ -298,6 +297,13 @@
endif
+# Product does not support Dynamic System Update
+ifneq ($(PRODUCT_NO_DYNAMIC_SYSTEM_UPDATE),true)
+ PRODUCT_PACKAGES += \
+ DynamicSystemInstallationService \
+
+endif
+
# VINTF data for system image
PRODUCT_PACKAGES += \
system_manifest.xml \
@@ -348,7 +354,6 @@
incident_report \
ld.mc \
lpdump \
- minigzip \
mke2fs \
mkfs.erofs \
resize2fs \
diff --git a/target/product/cfi-common.mk b/target/product/cfi-common.mk
index 5cc7ae5..559963c 100644
--- a/target/product/cfi-common.mk
+++ b/target/product/cfi-common.mk
@@ -33,7 +33,7 @@
hardware/qcom/wlan/wcn6740/qcwcn/wpa_supplicant_8_lib \
hardware/interfaces/keymaster \
hardware/interfaces/security \
- packages/modules/Bluetooth \
+ packages/modules/Bluetooth/system \
system/chre \
system/core/libnetutils \
system/libziparchive \
diff --git a/target/product/default_art_config.mk b/target/product/default_art_config.mk
index 1e28c80..f82d177 100644
--- a/target/product/default_art_config.mk
+++ b/target/product/default_art_config.mk
@@ -38,6 +38,14 @@
PRODUCT_BOOT_JARS := \
$(ART_APEX_JARS)
+# List of jars to be included in the ART boot image for testing.
+# DO NOT reorder this list. The order must match the one described above.
+# Note: We use the host variant of "core-icu4j" and "conscrypt" for testing.
+PRODUCT_TEST_ONLY_ART_BOOT_IMAGE_JARS := \
+ $(ART_APEX_JARS) \
+ platform:core-icu4j-host \
+ platform:conscrypt-host \
+
# /system and /system_ext boot jars.
PRODUCT_BOOT_JARS += \
framework-minus-apex \
@@ -103,9 +111,17 @@
com.android.os.statsd:service-statsd \
com.android.scheduling:service-scheduling \
com.android.tethering:service-connectivity \
+ com.android.threadnetwork:service-threadnetwork \
com.android.uwb:service-uwb \
com.android.wifi:service-wifi \
+# Overrides the (apex, jar) pairs above when determining the on-device location. The format is:
+# <old_apex>:<old_jar>:<new_apex>:<new_jar>
+PRODUCT_CONFIGURED_JAR_LOCATION_OVERRIDES := \
+ platform:framework-minus-apex:platform:framework \
+ platform:core-icu4j-host:com.android.i18n:core-icu4j \
+ platform:conscrypt-host:com.android.conscrypt:conscrypt \
+
# Minimal configuration for running dex2oat (default argument values).
# PRODUCT_USES_DEFAULT_ART_CONFIG must be true to enable boot image compilation.
PRODUCT_USES_DEFAULT_ART_CONFIG := true
diff --git a/target/product/full.manifest.xml b/target/product/full.manifest.xml
new file mode 100644
index 0000000..b8b0d37
--- /dev/null
+++ b/target/product/full.manifest.xml
@@ -0,0 +1,2 @@
+<manifest version="1.0" type="device" target-level="7">
+</manifest>
diff --git a/target/product/full.mk b/target/product/full.mk
index 945957f..da04f49 100644
--- a/target/product/full.mk
+++ b/target/product/full.mk
@@ -20,10 +20,11 @@
# entirely appropriate to inherit from for on-device configurations.
$(call inherit-product-if-exists, build/make/target/product/ramdisk_stub.mk)
-$(call inherit-product, $(SRC_TARGET_DIR)/product/emulator_vendor.mk)
$(call inherit-product, $(SRC_TARGET_DIR)/product/aosp_base_telephony.mk)
$(call inherit-product, $(SRC_TARGET_DIR)/board/generic/device.mk)
+DEVICE_MANIFEST_FILE += build/make/target/product/full.manifest.xml
+
# Enable dynamic partition size
PRODUCT_USE_DYNAMIC_PARTITION_SIZE := true
diff --git a/target/product/full_x86.mk b/target/product/full_x86.mk
index 0f3be91..07f6472 100644
--- a/target/product/full_x86.mk
+++ b/target/product/full_x86.mk
@@ -23,10 +23,11 @@
# that isn't a wifi connection. This will instruct init.rc to enable the
# network connection so that you can use it with ADB
-$(call inherit-product, $(SRC_TARGET_DIR)/product/emulator_vendor.mk)
$(call inherit-product, $(SRC_TARGET_DIR)/product/aosp_base_telephony.mk)
$(call inherit-product, $(SRC_TARGET_DIR)/board/generic_x86/device.mk)
+DEVICE_MANIFEST_FILE += build/make/target/product/full.manifest.xml
+
ifdef NET_ETH0_STARTONBOOT
PRODUCT_VENDOR_PROPERTIES += net.eth0.startonboot=1
endif
diff --git a/target/product/generic.mk b/target/product/generic.mk
index fb5b727..fd3b3fb 100644
--- a/target/product/generic.mk
+++ b/target/product/generic.mk
@@ -14,9 +14,6 @@
# limitations under the License.
#
-PRODUCT_SOONG_NAMESPACES += device/generic/goldfish # for libwifi-hal-emu
-PRODUCT_SOONG_NAMESPACES += device/generic/goldfish-opengl # for goldfish deps.
-
# This is a generic phone product that isn't specialized for a specific device.
# It includes the base Android platform.
diff --git a/target/product/sdk.mk b/target/product/sdk.mk
index fa7e1ad..e4cb7ff 100644
--- a/target/product/sdk.mk
+++ b/target/product/sdk.mk
@@ -14,11 +14,8 @@
# limitations under the License.
#
-# This is a simple product that uses configures the minimum amount
-# needed to build the SDK (without the emulator).
+# Don't modify this file - It's just an alias!
-$(call inherit-product, $(SRC_TARGET_DIR)/product/languages_default.mk)
+$(call inherit-product, $(SRC_TARGET_DIR)/product/sdk_x86.mk)
PRODUCT_NAME := sdk
-PRODUCT_BRAND := Android
-PRODUCT_DEVICE := mainline_x86
diff --git a/target/product/sdk_arm64.mk b/target/product/sdk_arm64.mk
index 8bb38f4..497f673 100644
--- a/target/product/sdk_arm64.mk
+++ b/target/product/sdk_arm64.mk
@@ -14,8 +14,11 @@
# limitations under the License.
#
-# Don't modify this file - It's just an alias!
+$(call inherit-product, $(SRC_TARGET_DIR)/product/languages_default.mk)
-$(call inherit-product, $(SRC_TARGET_DIR)/product/sdk_phone_arm64.mk)
+TARGET_SUPPORTS_32_BIT_APPS := true
+TARGET_SUPPORTS_64_BIT_APPS := true
PRODUCT_NAME := sdk_arm64
+PRODUCT_BRAND := Android
+PRODUCT_DEVICE := mainline_arm64
diff --git a/target/product/sdk_x86.mk b/target/product/sdk_x86.mk
index 13ee57d..843321f 100644
--- a/target/product/sdk_x86.mk
+++ b/target/product/sdk_x86.mk
@@ -14,8 +14,11 @@
# limitations under the License.
#
-# Don't modify this file - It's just an alias!
+# This is a simple product that uses configures the minimum amount
+# needed to build the SDK (without the emulator).
-$(call inherit-product, $(SRC_TARGET_DIR)/product/sdk_phone_x86.mk)
+$(call inherit-product, $(SRC_TARGET_DIR)/product/languages_default.mk)
-PRODUCT_NAME := sdk_x86
+PRODUCT_NAME := sdk_x86_64
+PRODUCT_BRAND := Android
+PRODUCT_DEVICE := mainline_x86
diff --git a/target/product/sdk_x86_64.mk b/target/product/sdk_x86_64.mk
index 5f6553e..c1caf7e 100644
--- a/target/product/sdk_x86_64.mk
+++ b/target/product/sdk_x86_64.mk
@@ -14,8 +14,14 @@
# limitations under the License.
#
-# Don't modify this file - It's just an alias!
+# This is a simple product that uses configures the minimum amount
+# needed to build the SDK (without the emulator).
-$(call inherit-product, $(SRC_TARGET_DIR)/product/sdk_phone_x86_64.mk)
+$(call inherit-product, $(SRC_TARGET_DIR)/product/languages_default.mk)
+
+TARGET_SUPPORTS_32_BIT_APPS := true
+TARGET_SUPPORTS_64_BIT_APPS := true
PRODUCT_NAME := sdk_x86_64
+PRODUCT_BRAND := Android
+PRODUCT_DEVICE := mainline_x86_64
diff --git a/tools/aconfig/Android.bp b/tools/aconfig/Android.bp
index c349907..a3f63a9 100644
--- a/tools/aconfig/Android.bp
+++ b/tools/aconfig/Android.bp
@@ -67,7 +67,7 @@
],
}
-// integration tests: java
+// integration tests: general
aconfig_declarations {
name: "aconfig.test.flags",
@@ -91,22 +91,80 @@
],
}
+// integration tests: java
+
java_aconfig_library {
- name: "aconfig_test_java",
+ name: "aconfig_test_java_library",
aconfig_declarations: "aconfig.test.flags",
}
android_test {
name: "aconfig.test.java",
srcs: [
- "tests/**/*.java",
+ "tests/AconfigTest.java",
],
manifest: "tests/AndroidManifest.xml",
certificate: "platform",
static_libs: [
+ "aconfig_test_java_library",
"androidx.test.rules",
"testng",
- "aconfig_test_java",
],
test_suites: ["device-tests"],
}
+
+java_aconfig_library {
+ name: "aconfig_host_test_java_library",
+ aconfig_declarations: "aconfig.test.flags",
+ host_supported: true,
+ test: true,
+}
+
+java_test_host {
+ name: "AconfigJavaHostTest",
+ srcs: [
+ "tests/AconfigHostTest.java",
+ ],
+ static_libs: [
+ "aconfig_host_test_java_library",
+ "junit",
+ ],
+ test_suites: ["general-tests"],
+}
+
+// integration tests: C++
+
+cc_aconfig_library {
+ name: "aconfig_test_cpp_library",
+ aconfig_declarations: "aconfig.test.flags",
+}
+
+cc_test {
+ name: "aconfig.test.cpp",
+ srcs: [
+ "tests/aconfig_test.cpp",
+ ],
+ static_libs: [
+ "aconfig_test_cpp_library",
+ "libgmock",
+ ],
+ shared_libs: [
+ "server_configurable_flags",
+ ],
+}
+
+rust_aconfig_library {
+ name: "libaconfig_test_rust_library",
+ crate_name: "aconfig_test_rust_library",
+ aconfig_declarations: "aconfig.test.flags",
+}
+
+rust_test {
+ name: "aconfig.test.rust",
+ srcs: [
+ "tests/aconfig_test.rs"
+ ],
+ rustlibs: [
+ "libaconfig_test_rust_library",
+ ],
+}
\ No newline at end of file
diff --git a/tools/aconfig/src/codegen_cpp.rs b/tools/aconfig/src/codegen_cpp.rs
index a802725..530af49 100644
--- a/tools/aconfig/src/codegen_cpp.rs
+++ b/tools/aconfig/src/codegen_cpp.rs
@@ -42,7 +42,7 @@
cpp_namespace,
package: package.to_string(),
readwrite,
- for_prod: codegen_mode == CodegenMode::Production,
+ for_test: codegen_mode == CodegenMode::Test,
class_elements,
};
@@ -57,16 +57,6 @@
template: include_str!("../templates/cpp_source_file.template"),
dir: "",
},
- FileSpec {
- name: &format!("{}_flag_provider.h", header),
- template: match codegen_mode {
- CodegenMode::Production => {
- include_str!("../templates/cpp_prod_flag_provider.template")
- }
- CodegenMode::Test => include_str!("../templates/cpp_test_flag_provider.template"),
- },
- dir: "",
- },
];
files.iter().map(|file| generate_file(file, &context)).collect()
}
@@ -92,7 +82,7 @@
pub cpp_namespace: String,
pub package: String,
pub readwrite: bool,
- pub for_prod: bool,
+ pub for_test: bool,
pub class_elements: Vec<ClassElement>,
}
@@ -101,7 +91,6 @@
pub readwrite: bool,
pub default_value: String,
pub flag_name: String,
- pub uppercase_flag_name: String,
pub device_config_namespace: String,
pub device_config_flag: String,
}
@@ -115,7 +104,6 @@
"false".to_string()
},
flag_name: pf.name().to_string(),
- uppercase_flag_name: pf.name().to_string().to_ascii_uppercase(),
device_config_namespace: pf.namespace().to_string(),
device_config_flag: codegen::create_device_config_ident(package, pf.name())
.expect("values checked at flag parse time"),
@@ -128,18 +116,15 @@
use std::collections::HashMap;
const EXPORTED_PROD_HEADER_EXPECTED: &str = r#"
-#ifndef com_android_aconfig_test_HEADER_H
-#define com_android_aconfig_test_HEADER_H
+#pragma once
-#include <string>
+#ifdef __cplusplus
+
#include <memory>
-#include <server_configurable_flags/get_flags.h>
-using namespace server_configurable_flags;
namespace com::android::aconfig::test {
class flag_provider_interface {
public:
-
virtual ~flag_provider_interface() = default;
virtual bool disabled_ro() = 0;
@@ -149,19 +134,10 @@
virtual bool enabled_ro() = 0;
virtual bool enabled_rw() = 0;
-
- virtual void override_flag(std::string const&, bool) {}
-
- virtual void reset_overrides() {}
};
extern std::unique_ptr<flag_provider_interface> provider_;
-extern std::string const DISABLED_RO;
-extern std::string const DISABLED_RW;
-extern std::string const ENABLED_RO;
-extern std::string const ENABLED_RW;
-
inline bool disabled_ro() {
return false;
}
@@ -178,28 +154,33 @@
return provider_->enabled_rw();
}
-inline void override_flag(std::string const& name, bool val) {
- return provider_->override_flag(name, val);
}
-inline void reset_overrides() {
- return provider_->reset_overrides();
-}
+extern "C" {
+#endif // __cplusplus
-}
+bool com_android_aconfig_test_disabled_ro();
+
+bool com_android_aconfig_test_disabled_rw();
+
+bool com_android_aconfig_test_enabled_ro();
+
+bool com_android_aconfig_test_enabled_rw();
+
+#ifdef __cplusplus
+} // extern "C"
#endif
"#;
const EXPORTED_TEST_HEADER_EXPECTED: &str = r#"
-#ifndef com_android_aconfig_test_HEADER_H
-#define com_android_aconfig_test_HEADER_H
+#pragma once
-#include <string>
+#ifdef __cplusplus
+
#include <memory>
-#include <server_configurable_flags/get_flags.h>
-using namespace server_configurable_flags;
namespace com::android::aconfig::test {
+
class flag_provider_interface {
public:
@@ -207,184 +188,270 @@
virtual bool disabled_ro() = 0;
+ virtual void disabled_ro(bool val) = 0;
+
virtual bool disabled_rw() = 0;
+ virtual void disabled_rw(bool val) = 0;
+
virtual bool enabled_ro() = 0;
+ virtual void enabled_ro(bool val) = 0;
+
virtual bool enabled_rw() = 0;
- virtual void override_flag(std::string const&, bool) {}
+ virtual void enabled_rw(bool val) = 0;
- virtual void reset_overrides() {}
+ virtual void reset_flags() {}
};
extern std::unique_ptr<flag_provider_interface> provider_;
-extern std::string const DISABLED_RO;
-extern std::string const DISABLED_RW;
-extern std::string const ENABLED_RO;
-extern std::string const ENABLED_RW;
-
inline bool disabled_ro() {
return provider_->disabled_ro();
}
+inline void disabled_ro(bool val) {
+ provider_->disabled_ro(val);
+}
+
inline bool disabled_rw() {
return provider_->disabled_rw();
}
+inline void disabled_rw(bool val) {
+ provider_->disabled_rw(val);
+}
+
inline bool enabled_ro() {
return provider_->enabled_ro();
}
+inline void enabled_ro(bool val) {
+ provider_->enabled_ro(val);
+}
+
inline bool enabled_rw() {
return provider_->enabled_rw();
}
-inline void override_flag(std::string const& name, bool val) {
- return provider_->override_flag(name, val);
+inline void enabled_rw(bool val) {
+ provider_->enabled_rw(val);
}
-inline void reset_overrides() {
- return provider_->reset_overrides();
+inline void reset_flags() {
+ return provider_->reset_flags();
}
}
+
+extern "C" {
+#endif // __cplusplus
+
+bool com_android_aconfig_test_disabled_ro();
+
+void set_com_android_aconfig_test_disabled_ro(bool val);
+
+bool com_android_aconfig_test_disabled_rw();
+
+void set_com_android_aconfig_test_disabled_rw(bool val);
+
+bool com_android_aconfig_test_enabled_ro();
+
+void set_com_android_aconfig_test_enabled_ro(bool val);
+
+bool com_android_aconfig_test_enabled_rw();
+
+void set_com_android_aconfig_test_enabled_rw(bool val);
+
+void com_android_aconfig_test_reset_flags();
+
+
+#ifdef __cplusplus
+} // extern "C"
#endif
+
+
"#;
- const PROD_FLAG_PROVIDER_HEADER_EXPECTED: &str = r#"
-#ifndef com_android_aconfig_test_flag_provider_HEADER_H
-#define com_android_aconfig_test_flag_provider_HEADER_H
-
+ const PROD_SOURCE_FILE_EXPECTED: &str = r#"
#include "com_android_aconfig_test.h"
-
-namespace com::android::aconfig::test {
-class flag_provider : public flag_provider_interface {
-public:
-
- virtual bool disabled_ro() override {
- return false;
- }
-
- virtual bool disabled_rw() override {
- return GetServerConfigurableFlag(
- "aconfig_test",
- "com.android.aconfig.test.disabled_rw",
- "false") == "true";
- }
-
- virtual bool enabled_ro() override {
- return true;
- }
-
- virtual bool enabled_rw() override {
- return GetServerConfigurableFlag(
- "aconfig_test",
- "com.android.aconfig.test.enabled_rw",
- "true") == "true";
- }
-};
-}
-#endif
-"#;
-
- const TEST_FLAG_PROVIDER_HEADER_EXPECTED: &str = r#"
-#ifndef com_android_aconfig_test_flag_provider_HEADER_H
-#define com_android_aconfig_test_flag_provider_HEADER_H
-
-#include "com_android_aconfig_test.h"
-
-#include <unordered_map>
-#include <unordered_set>
-#include <cassert>
-
-namespace com::android::aconfig::test {
-class flag_provider : public flag_provider_interface {
-private:
- std::unordered_map<std::string, bool> overrides_;
- std::unordered_set<std::string> flag_names_;
-
-public:
-
- flag_provider()
- : overrides_(),
- flag_names_() {
- flag_names_.insert(DISABLED_RO);
- flag_names_.insert(DISABLED_RW);
- flag_names_.insert(ENABLED_RO);
- flag_names_.insert(ENABLED_RW);
- }
-
- virtual bool disabled_ro() override {
- auto it = overrides_.find(DISABLED_RO);
- if (it != overrides_.end()) {
- return it->second;
- } else {
- return false;
- }
- }
-
- virtual bool disabled_rw() override {
- auto it = overrides_.find(DISABLED_RW);
- if (it != overrides_.end()) {
- return it->second;
- } else {
- return GetServerConfigurableFlag(
- "aconfig_test",
- "com.android.aconfig.test.disabled_rw",
- "false") == "true";
- }
- }
-
- virtual bool enabled_ro() override {
- auto it = overrides_.find(ENABLED_RO);
- if (it != overrides_.end()) {
- return it->second;
- } else {
- return true;
- }
- }
-
- virtual bool enabled_rw() override {
- auto it = overrides_.find(ENABLED_RW);
- if (it != overrides_.end()) {
- return it->second;
- } else {
- return GetServerConfigurableFlag(
- "aconfig_test",
- "com.android.aconfig.test.enabled_rw",
- "true") == "true";
- }
- }
-
- virtual void override_flag(std::string const& flag, bool val) override {
- assert(flag_names_.count(flag));
- overrides_[flag] = val;
- }
-
- virtual void reset_overrides() override {
- overrides_.clear();
- }
-};
-}
-#endif
-"#;
-
- const SOURCE_FILE_EXPECTED: &str = r#"
-#include "com_android_aconfig_test.h"
-#include "com_android_aconfig_test_flag_provider.h"
+#include <server_configurable_flags/get_flags.h>
namespace com::android::aconfig::test {
- std::string const DISABLED_RO = "com.android.aconfig.test.disabled_ro";
- std::string const DISABLED_RW = "com.android.aconfig.test.disabled_rw";
- std::string const ENABLED_RO = "com.android.aconfig.test.enabled_ro";
- std::string const ENABLED_RW = "com.android.aconfig.test.enabled_rw";
+ class flag_provider : public flag_provider_interface {
+ public:
+
+ virtual bool disabled_ro() override {
+ return false;
+ }
+
+ virtual bool disabled_rw() override {
+ return server_configurable_flags::GetServerConfigurableFlag(
+ "aconfig_test",
+ "com.android.aconfig.test.disabled_rw",
+ "false") == "true";
+ }
+
+ virtual bool enabled_ro() override {
+ return true;
+ }
+
+ virtual bool enabled_rw() override {
+ return server_configurable_flags::GetServerConfigurableFlag(
+ "aconfig_test",
+ "com.android.aconfig.test.enabled_rw",
+ "true") == "true";
+ }
+
+ };
std::unique_ptr<flag_provider_interface> provider_ =
std::make_unique<flag_provider>();
}
+
+bool com_android_aconfig_test_disabled_ro() {
+ return false;
+}
+
+bool com_android_aconfig_test_disabled_rw() {
+ return com::android::aconfig::test::disabled_rw();
+}
+
+bool com_android_aconfig_test_enabled_ro() {
+ return true;
+}
+
+bool com_android_aconfig_test_enabled_rw() {
+ return com::android::aconfig::test::enabled_rw();
+}
+
+"#;
+
+ const TEST_SOURCE_FILE_EXPECTED: &str = r#"
+#include "com_android_aconfig_test.h"
+#include <server_configurable_flags/get_flags.h>
+
+namespace com::android::aconfig::test {
+
+ class flag_provider : public flag_provider_interface {
+ private:
+ std::unordered_map<std::string, bool> overrides_;
+
+ public:
+ flag_provider()
+ : overrides_()
+ {}
+
+ virtual bool disabled_ro() override {
+ auto it = overrides_.find("disabled_ro");
+ if (it != overrides_.end()) {
+ return it->second;
+ } else {
+ return false;
+ }
+ }
+
+ virtual void disabled_ro(bool val) override {
+ overrides_["disabled_ro"] = val;
+ }
+
+ virtual bool disabled_rw() override {
+ auto it = overrides_.find("disabled_rw");
+ if (it != overrides_.end()) {
+ return it->second;
+ } else {
+ return server_configurable_flags::GetServerConfigurableFlag(
+ "aconfig_test",
+ "com.android.aconfig.test.disabled_rw",
+ "false") == "true";
+ }
+ }
+
+ virtual void disabled_rw(bool val) override {
+ overrides_["disabled_rw"] = val;
+ }
+
+ virtual bool enabled_ro() override {
+ auto it = overrides_.find("enabled_ro");
+ if (it != overrides_.end()) {
+ return it->second;
+ } else {
+ return true;
+ }
+ }
+
+ virtual void enabled_ro(bool val) override {
+ overrides_["enabled_ro"] = val;
+ }
+
+ virtual bool enabled_rw() override {
+ auto it = overrides_.find("enabled_rw");
+ if (it != overrides_.end()) {
+ return it->second;
+ } else {
+ return server_configurable_flags::GetServerConfigurableFlag(
+ "aconfig_test",
+ "com.android.aconfig.test.enabled_rw",
+ "true") == "true";
+ }
+ }
+
+ virtual void enabled_rw(bool val) override {
+ overrides_["enabled_rw"] = val;
+ }
+
+
+ virtual void reset_flags() override {
+ overrides_.clear();
+ }
+ };
+
+ std::unique_ptr<flag_provider_interface> provider_ =
+ std::make_unique<flag_provider>();
+}
+
+bool com_android_aconfig_test_disabled_ro() {
+ return com::android::aconfig::test::disabled_ro();
+}
+
+
+void set_com_android_aconfig_test_disabled_ro(bool val) {
+ com::android::aconfig::test::disabled_ro(val);
+}
+
+bool com_android_aconfig_test_disabled_rw() {
+ return com::android::aconfig::test::disabled_rw();
+}
+
+
+void set_com_android_aconfig_test_disabled_rw(bool val) {
+ com::android::aconfig::test::disabled_rw(val);
+}
+
+bool com_android_aconfig_test_enabled_ro() {
+ return com::android::aconfig::test::enabled_ro();
+}
+
+
+void set_com_android_aconfig_test_enabled_ro(bool val) {
+ com::android::aconfig::test::enabled_ro(val);
+}
+
+bool com_android_aconfig_test_enabled_rw() {
+ return com::android::aconfig::test::enabled_rw();
+}
+
+
+void set_com_android_aconfig_test_enabled_rw(bool val) {
+ com::android::aconfig::test::enabled_rw(val);
+}
+
+void com_android_aconfig_test_reset_flags() {
+ com::android::aconfig::test::reset_flags();
+}
+
"#;
fn test_generate_cpp_code(mode: CodegenMode) {
@@ -413,25 +480,15 @@
)
);
- target_file_path = String::from("com_android_aconfig_test_flag_provider.h");
- assert!(generated_files_map.contains_key(&target_file_path));
- assert_eq!(
- None,
- crate::test::first_significant_code_diff(
- match mode {
- CodegenMode::Production => PROD_FLAG_PROVIDER_HEADER_EXPECTED,
- CodegenMode::Test => TEST_FLAG_PROVIDER_HEADER_EXPECTED,
- },
- generated_files_map.get(&target_file_path).unwrap()
- )
- );
-
target_file_path = String::from("com_android_aconfig_test.cc");
assert!(generated_files_map.contains_key(&target_file_path));
assert_eq!(
None,
crate::test::first_significant_code_diff(
- SOURCE_FILE_EXPECTED,
+ match mode {
+ CodegenMode::Production => PROD_SOURCE_FILE_EXPECTED,
+ CodegenMode::Test => TEST_SOURCE_FILE_EXPECTED,
+ },
generated_files_map.get(&target_file_path).unwrap()
)
);
diff --git a/tools/aconfig/src/codegen_java.rs b/tools/aconfig/src/codegen_java.rs
index 8ab6ffa..2c9dcf5 100644
--- a/tools/aconfig/src/codegen_java.rs
+++ b/tools/aconfig/src/codegen_java.rs
@@ -47,9 +47,13 @@
"FeatureFlags.java",
include_str!("../templates/FeatureFlags.java.template"),
)?;
+ template.add_template(
+ "FakeFeatureFlagsImpl.java",
+ include_str!("../templates/FakeFeatureFlagsImpl.java.template"),
+ )?;
let path: PathBuf = package.split('.').collect();
- ["Flags.java", "FeatureFlagsImpl.java", "FeatureFlags.java"]
+ ["Flags.java", "FeatureFlags.java", "FeatureFlagsImpl.java", "FakeFeatureFlagsImpl.java"]
.iter()
.map(|file| {
Ok(OutputFile {
@@ -112,14 +116,14 @@
use super::*;
use std::collections::HashMap;
- const EXPECTED_FEATUREFLAGS_CONTENT: &str = r#"
+ const EXPECTED_FEATUREFLAGS_COMMON_CONTENT: &str = r#"
package com.android.aconfig.test;
public interface FeatureFlags {
boolean disabledRo();
boolean disabledRw();
boolean enabledRo();
boolean enabledRw();
- }"#;
+ "#;
const EXPECTED_FLAG_COMMON_CONTENT: &str = r#"
package com.android.aconfig.test;
@@ -143,6 +147,29 @@
}
"#;
+ const EXPECTED_METHOD_NOT_IMPL_COMMON_CONTENT: &str = r#"
+ @Override
+ public boolean disabledRo() {
+ throw new UnsupportedOperationException(
+ "Method is not implemented.");
+ }
+ @Override
+ public boolean disabledRw() {
+ throw new UnsupportedOperationException(
+ "Method is not implemented.");
+ }
+ @Override
+ public boolean enabledRo() {
+ throw new UnsupportedOperationException(
+ "Method is not implemented.");
+ }
+ @Override
+ public boolean enabledRw() {
+ throw new UnsupportedOperationException(
+ "Method is not implemented.");
+ }
+ "#;
+
#[test]
fn test_generate_java_code_production() {
let parsed_flags = crate::test::parse_test_flags();
@@ -152,11 +179,22 @@
CodegenMode::Production,
)
.unwrap();
+ let expect_featureflags_content = EXPECTED_FEATUREFLAGS_COMMON_CONTENT.to_string()
+ + r#"
+ }"#;
let expect_flags_content = EXPECTED_FLAG_COMMON_CONTENT.to_string()
+ r#"
private static FeatureFlags FEATURE_FLAGS = new FeatureFlagsImpl();
}"#;
- let expected_featureflagsimpl_content = r#"
+ let expect_fakefeatureflagsimpl_content = r#"
+ package com.android.aconfig.test;
+ public class FakeFeatureFlagsImpl implements FeatureFlags {"#
+ .to_owned()
+ + EXPECTED_METHOD_NOT_IMPL_COMMON_CONTENT
+ + r#"
+ }
+ "#;
+ let expect_featureflagsimpl_content = r#"
package com.android.aconfig.test;
import android.provider.DeviceConfig;
public final class FeatureFlagsImpl implements FeatureFlags {
@@ -188,8 +226,12 @@
"#;
let mut file_set = HashMap::from([
("com/android/aconfig/test/Flags.java", expect_flags_content.as_str()),
- ("com/android/aconfig/test/FeatureFlagsImpl.java", expected_featureflagsimpl_content),
- ("com/android/aconfig/test/FeatureFlags.java", EXPECTED_FEATUREFLAGS_CONTENT),
+ ("com/android/aconfig/test/FeatureFlagsImpl.java", expect_featureflagsimpl_content),
+ ("com/android/aconfig/test/FeatureFlags.java", expect_featureflags_content.as_str()),
+ (
+ "com/android/aconfig/test/FakeFeatureFlagsImpl.java",
+ expect_fakefeatureflagsimpl_content.as_str(),
+ ),
]);
for file in generated_files {
@@ -219,24 +261,47 @@
CodegenMode::Test,
)
.unwrap();
+ let expect_featureflags_content = EXPECTED_FEATUREFLAGS_COMMON_CONTENT.to_string()
+ + r#"
+ public void setFlag(String flagName, boolean value);
+ public void resetAll();
+ }"#;
let expect_flags_content = EXPECTED_FLAG_COMMON_CONTENT.to_string()
+ r#"
- public static void setFeatureFlagsImpl(FeatureFlags featureFlags) {
+ public static void setFeatureFlags(FeatureFlags featureFlags) {
Flags.FEATURE_FLAGS = featureFlags;
}
- public static void unsetFeatureFlagsImpl() {
+ public static void unsetFeatureFlags() {
Flags.FEATURE_FLAGS = null;
}
private static FeatureFlags FEATURE_FLAGS;
}
"#;
- let expected_featureflagsimpl_content = r#"
+ let expect_featureflagsimpl_content = r#"
+ package com.android.aconfig.test;
+ public final class FeatureFlagsImpl implements FeatureFlags {"#
+ .to_owned()
+ + EXPECTED_METHOD_NOT_IMPL_COMMON_CONTENT
+ + r#"
+ @Override
+ public void setFlag(String flagName, boolean value) {
+ throw new UnsupportedOperationException(
+ "Method is not implemented.");
+ }
+ @Override
+ public void resetAll() {
+ throw new UnsupportedOperationException(
+ "Method is not implemented.");
+ }
+ }
+ "#;
+ let expect_fakefeatureflagsimpl_content = r#"
package com.android.aconfig.test;
import static java.util.stream.Collectors.toMap;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Stream;
- public final class FeatureFlagsImpl implements FeatureFlags {
+ public class FakeFeatureFlagsImpl implements FeatureFlags {
@Override
public boolean disabledRo() {
return getFlag(Flags.FLAG_DISABLED_RO);
@@ -253,12 +318,14 @@
public boolean enabledRw() {
return getFlag(Flags.FLAG_ENABLED_RW);
}
+ @Override
public void setFlag(String flagName, boolean value) {
if (!this.mFlagMap.containsKey(flagName)) {
throw new IllegalArgumentException("no such flag" + flagName);
}
this.mFlagMap.put(flagName, value);
}
+ @Override
public void resetAll() {
for (Map.Entry entry : mFlagMap.entrySet()) {
entry.setValue(null);
@@ -284,10 +351,18 @@
);
}
"#;
+
let mut file_set = HashMap::from([
("com/android/aconfig/test/Flags.java", expect_flags_content.as_str()),
- ("com/android/aconfig/test/FeatureFlagsImpl.java", expected_featureflagsimpl_content),
- ("com/android/aconfig/test/FeatureFlags.java", EXPECTED_FEATUREFLAGS_CONTENT),
+ ("com/android/aconfig/test/FeatureFlags.java", expect_featureflags_content.as_str()),
+ (
+ "com/android/aconfig/test/FeatureFlagsImpl.java",
+ expect_featureflagsimpl_content.as_str(),
+ ),
+ (
+ "com/android/aconfig/test/FakeFeatureFlagsImpl.java",
+ expect_fakefeatureflagsimpl_content,
+ ),
]);
for file in generated_files {
diff --git a/tools/aconfig/src/codegen_rust.rs b/tools/aconfig/src/codegen_rust.rs
index f931418..053cebc 100644
--- a/tools/aconfig/src/codegen_rust.rs
+++ b/tools/aconfig/src/codegen_rust.rs
@@ -19,10 +19,14 @@
use tinytemplate::TinyTemplate;
use crate::codegen;
-use crate::commands::OutputFile;
+use crate::commands::{CodegenMode, OutputFile};
use crate::protos::{ProtoFlagPermission, ProtoFlagState, ProtoParsedFlag};
-pub fn generate_rust_code<'a, I>(package: &str, parsed_flags_iter: I) -> Result<OutputFile>
+pub fn generate_rust_code<'a, I>(
+ package: &str,
+ parsed_flags_iter: I,
+ codegen_mode: CodegenMode,
+) -> Result<OutputFile>
where
I: Iterator<Item = &'a ProtoParsedFlag>,
{
@@ -34,7 +38,13 @@
modules: package.split('.').map(|s| s.to_string()).collect::<Vec<_>>(),
};
let mut template = TinyTemplate::new();
- template.add_template("rust_code_gen", include_str!("../templates/rust.template"))?;
+ template.add_template(
+ "rust_code_gen",
+ match codegen_mode {
+ CodegenMode::Production => include_str!("../templates/rust_prod.template"),
+ CodegenMode::Test => include_str!("../templates/rust_test.template"),
+ },
+ )?;
let contents = template.render("rust_code_gen", &context)?;
let path = ["src", "lib.rs"].iter().collect();
Ok(OutputFile { contents: contents.into(), path })
@@ -49,41 +59,27 @@
#[derive(Serialize)]
struct TemplateParsedFlag {
+ pub readwrite: bool,
+ pub default_value: String,
pub name: String,
pub device_config_namespace: String,
pub device_config_flag: String,
-
- // TinyTemplate's conditionals are limited to single <bool> expressions; list all options here
- // Invariant: exactly one of these fields will be true
- pub is_read_only_enabled: bool,
- pub is_read_only_disabled: bool,
- pub is_read_write: bool,
}
impl TemplateParsedFlag {
#[allow(clippy::nonminimal_bool)]
fn new(package: &str, pf: &ProtoParsedFlag) -> Self {
let template = TemplateParsedFlag {
+ readwrite: pf.permission() == ProtoFlagPermission::READ_WRITE,
+ default_value: match pf.state() {
+ ProtoFlagState::ENABLED => "true".to_string(),
+ ProtoFlagState::DISABLED => "false".to_string(),
+ },
name: pf.name().to_string(),
device_config_namespace: pf.namespace().to_string(),
device_config_flag: codegen::create_device_config_ident(package, pf.name())
.expect("values checked at flag parse time"),
- is_read_only_enabled: pf.permission() == ProtoFlagPermission::READ_ONLY
- && pf.state() == ProtoFlagState::ENABLED,
- is_read_only_disabled: pf.permission() == ProtoFlagPermission::READ_ONLY
- && pf.state() == ProtoFlagState::DISABLED,
- is_read_write: pf.permission() == ProtoFlagPermission::READ_WRITE,
};
- #[rustfmt::skip]
- debug_assert!(
- (template.is_read_only_enabled && !template.is_read_only_disabled && !template.is_read_write) ||
- (!template.is_read_only_enabled && template.is_read_only_disabled && !template.is_read_write) ||
- (!template.is_read_only_enabled && !template.is_read_only_disabled && template.is_read_write),
- "TemplateParsedFlag invariant failed: {} {} {}",
- template.is_read_only_enabled,
- template.is_read_only_disabled,
- template.is_read_write,
- );
template
}
}
@@ -92,48 +88,224 @@
mod tests {
use super::*;
- #[test]
- fn test_generate_rust_code() {
- let parsed_flags = crate::test::parse_test_flags();
- let generated =
- generate_rust_code(crate::test::TEST_PACKAGE, parsed_flags.parsed_flag.iter()).unwrap();
- assert_eq!("src/lib.rs", format!("{}", generated.path.display()));
- let expected = r#"
-pub mod com {
-pub mod android {
-pub mod aconfig {
-pub mod test {
+ const PROD_EXPECTED: &str = r#"
+//! codegenerated rust flag lib
+
+/// flag provider
+pub struct FlagProvider;
+
+impl FlagProvider {
+ /// query flag disabled_ro
+ pub fn disabled_ro(&self) -> bool {
+ false
+ }
+
+ /// query flag disabled_rw
+ pub fn disabled_rw(&self) -> bool {
+ flags_rust::GetServerConfigurableFlag(
+ "aconfig_test",
+ "com.android.aconfig.test.disabled_rw",
+ "false") == "true"
+ }
+
+ /// query flag enabled_ro
+ pub fn enabled_ro(&self) -> bool {
+ true
+ }
+
+ /// query flag enabled_rw
+ pub fn enabled_rw(&self) -> bool {
+ flags_rust::GetServerConfigurableFlag(
+ "aconfig_test",
+ "com.android.aconfig.test.enabled_rw",
+ "true") == "true"
+ }
+}
+
+/// flag provider
+pub static PROVIDER: FlagProvider = FlagProvider;
+
+/// query flag disabled_ro
#[inline(always)]
-pub const fn r#disabled_ro() -> bool {
+pub fn disabled_ro() -> bool {
false
}
+/// query flag disabled_rw
#[inline(always)]
-pub fn r#disabled_rw() -> bool {
- flags_rust::GetServerConfigurableFlag("aconfig_test", "com.android.aconfig.test.disabled_rw", "false") == "true"
+pub fn disabled_rw() -> bool {
+ PROVIDER.disabled_rw()
}
+/// query flag enabled_ro
#[inline(always)]
-pub const fn r#enabled_ro() -> bool {
+pub fn enabled_ro() -> bool {
true
}
+/// query flag enabled_rw
#[inline(always)]
-pub fn r#enabled_rw() -> bool {
- flags_rust::GetServerConfigurableFlag("aconfig_test", "com.android.aconfig.test.enabled_rw", "false") == "true"
-}
-
-}
-}
-}
+pub fn enabled_rw() -> bool {
+ PROVIDER.enabled_rw()
}
"#;
+
+ const TEST_EXPECTED: &str = r#"
+//! codegenerated rust flag lib
+
+use std::collections::BTreeMap;
+use std::sync::Mutex;
+
+/// flag provider
+pub struct FlagProvider {
+ overrides: BTreeMap<&'static str, bool>,
+}
+
+impl FlagProvider {
+ /// query flag disabled_ro
+ pub fn disabled_ro(&self) -> bool {
+ self.overrides.get("disabled_ro").copied().unwrap_or(
+ false
+ )
+ }
+
+ /// set flag disabled_ro
+ pub fn set_disabled_ro(&mut self, val: bool) {
+ self.overrides.insert("disabled_ro", val);
+ }
+
+ /// query flag disabled_rw
+ pub fn disabled_rw(&self) -> bool {
+ self.overrides.get("disabled_rw").copied().unwrap_or(
+ flags_rust::GetServerConfigurableFlag(
+ "aconfig_test",
+ "com.android.aconfig.test.disabled_rw",
+ "false") == "true"
+ )
+ }
+
+ /// set flag disabled_rw
+ pub fn set_disabled_rw(&mut self, val: bool) {
+ self.overrides.insert("disabled_rw", val);
+ }
+
+ /// query flag enabled_ro
+ pub fn enabled_ro(&self) -> bool {
+ self.overrides.get("enabled_ro").copied().unwrap_or(
+ true
+ )
+ }
+
+ /// set flag enabled_ro
+ pub fn set_enabled_ro(&mut self, val: bool) {
+ self.overrides.insert("enabled_ro", val);
+ }
+
+ /// query flag enabled_rw
+ pub fn enabled_rw(&self) -> bool {
+ self.overrides.get("enabled_rw").copied().unwrap_or(
+ flags_rust::GetServerConfigurableFlag(
+ "aconfig_test",
+ "com.android.aconfig.test.enabled_rw",
+ "true") == "true"
+ )
+ }
+
+ /// set flag enabled_rw
+ pub fn set_enabled_rw(&mut self, val: bool) {
+ self.overrides.insert("enabled_rw", val);
+ }
+
+ /// clear all flag overrides
+ pub fn reset_flags(&mut self) {
+ self.overrides.clear();
+ }
+}
+
+/// flag provider
+pub static PROVIDER: Mutex<FlagProvider> = Mutex::new(
+ FlagProvider {overrides: BTreeMap::new()}
+);
+
+/// query flag disabled_ro
+#[inline(always)]
+pub fn disabled_ro() -> bool {
+ PROVIDER.lock().unwrap().disabled_ro()
+}
+
+/// set flag disabled_ro
+#[inline(always)]
+pub fn set_disabled_ro(val: bool) {
+ PROVIDER.lock().unwrap().set_disabled_ro(val);
+}
+
+/// query flag disabled_rw
+#[inline(always)]
+pub fn disabled_rw() -> bool {
+ PROVIDER.lock().unwrap().disabled_rw()
+}
+
+/// set flag disabled_rw
+#[inline(always)]
+pub fn set_disabled_rw(val: bool) {
+ PROVIDER.lock().unwrap().set_disabled_rw(val);
+}
+
+/// query flag enabled_ro
+#[inline(always)]
+pub fn enabled_ro() -> bool {
+ PROVIDER.lock().unwrap().enabled_ro()
+}
+
+/// set flag enabled_ro
+#[inline(always)]
+pub fn set_enabled_ro(val: bool) {
+ PROVIDER.lock().unwrap().set_enabled_ro(val);
+}
+
+/// query flag enabled_rw
+#[inline(always)]
+pub fn enabled_rw() -> bool {
+ PROVIDER.lock().unwrap().enabled_rw()
+}
+
+/// set flag enabled_rw
+#[inline(always)]
+pub fn set_enabled_rw(val: bool) {
+ PROVIDER.lock().unwrap().set_enabled_rw(val);
+}
+
+/// clear all flag override
+pub fn reset_flags() {
+ PROVIDER.lock().unwrap().reset_flags()
+}
+"#;
+
+ fn test_generate_rust_code(mode: CodegenMode) {
+ let parsed_flags = crate::test::parse_test_flags();
+ let generated =
+ generate_rust_code(crate::test::TEST_PACKAGE, parsed_flags.parsed_flag.iter(), mode)
+ .unwrap();
+ assert_eq!("src/lib.rs", format!("{}", generated.path.display()));
assert_eq!(
None,
crate::test::first_significant_code_diff(
- expected,
+ match mode {
+ CodegenMode::Production => PROD_EXPECTED,
+ CodegenMode::Test => TEST_EXPECTED,
+ },
&String::from_utf8(generated.contents).unwrap()
)
);
}
+
+ #[test]
+ fn test_generate_rust_code_for_prod() {
+ test_generate_rust_code(CodegenMode::Production);
+ }
+
+ #[test]
+ fn test_generate_rust_code_for_test() {
+ test_generate_rust_code(CodegenMode::Test);
+ }
}
diff --git a/tools/aconfig/src/commands.rs b/tools/aconfig/src/commands.rs
index 687f319..ab5b0f2 100644
--- a/tools/aconfig/src/commands.rs
+++ b/tools/aconfig/src/commands.rs
@@ -35,8 +35,15 @@
impl Input {
fn try_parse_flags(&mut self) -> Result<ProtoParsedFlags> {
let mut buffer = Vec::new();
- self.reader.read_to_end(&mut buffer)?;
+ self.reader
+ .read_to_end(&mut buffer)
+ .with_context(|| format!("failed to read {}", self.source))?;
crate::protos::parsed_flags::try_from_binary_proto(&buffer)
+ .with_context(|| self.error_context())
+ }
+
+ fn error_context(&self) -> String {
+ format!("failed to parse {}", self.source)
}
}
@@ -45,28 +52,36 @@
pub contents: Vec<u8>,
}
-const DEFAULT_FLAG_STATE: ProtoFlagState = ProtoFlagState::DISABLED;
-const DEFAULT_FLAG_PERMISSION: ProtoFlagPermission = ProtoFlagPermission::READ_WRITE;
+pub const DEFAULT_FLAG_STATE: ProtoFlagState = ProtoFlagState::DISABLED;
+pub const DEFAULT_FLAG_PERMISSION: ProtoFlagPermission = ProtoFlagPermission::READ_WRITE;
-pub fn parse_flags(package: &str, declarations: Vec<Input>, values: Vec<Input>) -> Result<Vec<u8>> {
+pub fn parse_flags(
+ package: &str,
+ declarations: Vec<Input>,
+ values: Vec<Input>,
+ default_permission: ProtoFlagPermission,
+) -> Result<Vec<u8>> {
let mut parsed_flags = ProtoParsedFlags::new();
for mut input in declarations {
let mut contents = String::new();
- input.reader.read_to_string(&mut contents)?;
+ input
+ .reader
+ .read_to_string(&mut contents)
+ .with_context(|| format!("failed to read {}", input.source))?;
let flag_declarations = crate::protos::flag_declarations::try_from_text_proto(&contents)
- .with_context(|| format!("Failed to parse {}", input.source))?;
+ .with_context(|| input.error_context())?;
ensure!(
package == flag_declarations.package(),
- "Failed to parse {}: expected package {}, got {}",
+ "failed to parse {}: expected package {}, got {}",
input.source,
package,
flag_declarations.package()
);
for mut flag_declaration in flag_declarations.flag.into_iter() {
crate::protos::flag_declaration::verify_fields(&flag_declaration)
- .with_context(|| format!("Failed to parse {}", input.source))?;
+ .with_context(|| input.error_context())?;
// create ParsedFlag using FlagDeclaration and default values
let mut parsed_flag = ProtoParsedFlag::new();
@@ -76,11 +91,11 @@
parsed_flag.set_description(flag_declaration.take_description());
parsed_flag.bug.append(&mut flag_declaration.bug);
parsed_flag.set_state(DEFAULT_FLAG_STATE);
- parsed_flag.set_permission(DEFAULT_FLAG_PERMISSION);
+ parsed_flag.set_permission(default_permission);
let mut tracepoint = ProtoTracepoint::new();
tracepoint.set_source(input.source.clone());
tracepoint.set_state(DEFAULT_FLAG_STATE);
- tracepoint.set_permission(DEFAULT_FLAG_PERMISSION);
+ tracepoint.set_permission(default_permission);
parsed_flag.trace.push(tracepoint);
// verify ParsedFlag looks reasonable
@@ -101,14 +116,21 @@
for mut input in values {
let mut contents = String::new();
- input.reader.read_to_string(&mut contents)?;
+ input
+ .reader
+ .read_to_string(&mut contents)
+ .with_context(|| format!("failed to read {}", input.source))?;
let flag_values = crate::protos::flag_values::try_from_text_proto(&contents)
- .with_context(|| format!("Failed to parse {}", input.source))?;
+ .with_context(|| input.error_context())?;
for flag_value in flag_values.flag_value.into_iter() {
crate::protos::flag_value::verify_fields(&flag_value)
- .with_context(|| format!("Failed to parse {}", input.source))?;
+ .with_context(|| input.error_context())?;
- let Some(parsed_flag) = parsed_flags.parsed_flag.iter_mut().find(|pf| pf.package() == flag_value.package() && pf.name() == flag_value.name()) else {
+ let Some(parsed_flag) = parsed_flags
+ .parsed_flag
+ .iter_mut()
+ .find(|pf| pf.package() == flag_value.package() && pf.name() == flag_value.name())
+ else {
// (silently) skip unknown flags
continue;
};
@@ -123,6 +145,8 @@
}
}
+ // Create a sorted parsed_flags
+ crate::protos::parsed_flags::sort_parsed_flags(&mut parsed_flags);
crate::protos::parsed_flags::verify_fields(&parsed_flags)?;
let mut output = Vec::new();
parsed_flags.write_to_vec(&mut output)?;
@@ -151,12 +175,12 @@
generate_cpp_code(package, parsed_flags.parsed_flag.iter(), codegen_mode)
}
-pub fn create_rust_lib(mut input: Input) -> Result<OutputFile> {
+pub fn create_rust_lib(mut input: Input, codegen_mode: CodegenMode) -> Result<OutputFile> {
let parsed_flags = input.try_parse_flags()?;
let Some(package) = find_unique_package(&parsed_flags) else {
bail!("no parsed flags, or the parsed flags use different packages");
};
- generate_rust_code(package, parsed_flags.parsed_flag.iter())
+ generate_rust_code(package, parsed_flags.parsed_flag.iter(), codegen_mode)
}
pub fn create_device_config_defaults(mut input: Input) -> Result<Vec<u8>> {
@@ -207,7 +231,7 @@
#[derive(Copy, Clone, Debug, PartialEq, Eq, ValueEnum)]
pub enum DumpFormat {
Text,
- Debug,
+ Verbose,
Protobuf,
Textproto,
}
@@ -223,18 +247,27 @@
DumpFormat::Text => {
for parsed_flag in parsed_flags.parsed_flag.into_iter() {
let line = format!(
- "{}/{}: {:?} {:?}\n",
+ "{}/{}: {:?} + {:?}\n",
parsed_flag.package(),
parsed_flag.name(),
- parsed_flag.state(),
- parsed_flag.permission()
+ parsed_flag.permission(),
+ parsed_flag.state()
);
output.extend_from_slice(line.as_bytes());
}
}
- DumpFormat::Debug => {
+ DumpFormat::Verbose => {
for parsed_flag in parsed_flags.parsed_flag.into_iter() {
- let line = format!("{:#?}\n", parsed_flag);
+ let sources: Vec<_> =
+ parsed_flag.trace.iter().map(|tracepoint| tracepoint.source()).collect();
+ let line = format!(
+ "{}/{}: {:?} + {:?} ({})\n",
+ parsed_flag.package(),
+ parsed_flag.name(),
+ parsed_flag.permission(),
+ parsed_flag.state(),
+ sources.join(", ")
+ );
output.extend_from_slice(line.as_bytes());
}
}
@@ -300,6 +333,36 @@
}
#[test]
+ fn test_parse_flags_setting_default() {
+ let first_flag = r#"
+ package: "com.first"
+ flag {
+ name: "first"
+ namespace: "first_ns"
+ description: "This is the description of the first flag."
+ bug: "123"
+ }
+ "#;
+ let declaration =
+ vec![Input { source: "momery".to_string(), reader: Box::new(first_flag.as_bytes()) }];
+ let value: Vec<Input> = vec![];
+
+ let flags_bytes = crate::commands::parse_flags(
+ "com.first",
+ declaration,
+ value,
+ ProtoFlagPermission::READ_ONLY,
+ )
+ .unwrap();
+ let parsed_flags =
+ crate::protos::parsed_flags::try_from_binary_proto(&flags_bytes).unwrap();
+ assert_eq!(1, parsed_flags.parsed_flag.len());
+ let parsed_flag = parsed_flags.parsed_flag.first().unwrap();
+ assert_eq!(ProtoFlagState::DISABLED, parsed_flag.state());
+ assert_eq!(ProtoFlagPermission::READ_ONLY, parsed_flag.permission());
+ }
+
+ #[test]
fn test_create_device_config_defaults() {
let input = parse_test_flags_as_input();
let bytes = create_device_config_defaults(input).unwrap();
@@ -320,7 +383,7 @@
let input = parse_test_flags_as_input();
let bytes = dump_parsed_flags(vec![input], DumpFormat::Text).unwrap();
let text = std::str::from_utf8(&bytes).unwrap();
- assert!(text.contains("com.android.aconfig.test/disabled_ro: DISABLED READ_ONLY"));
+ assert!(text.contains("com.android.aconfig.test/disabled_ro: READ_ONLY + DISABLED"));
}
#[test]
diff --git a/tools/aconfig/src/main.rs b/tools/aconfig/src/main.rs
index 72feb94..84073f7 100644
--- a/tools/aconfig/src/main.rs
+++ b/tools/aconfig/src/main.rs
@@ -16,7 +16,7 @@
//! `aconfig` is a build time tool to manage build time configurations, such as feature flags.
-use anyhow::{anyhow, bail, ensure, Result};
+use anyhow::{anyhow, bail, Context, Result};
use clap::{builder::ArgAction, builder::EnumValueParser, Arg, ArgMatches, Command};
use core::any::Any;
use std::fs;
@@ -44,6 +44,14 @@
.arg(Arg::new("package").long("package").required(true))
.arg(Arg::new("declarations").long("declarations").action(ArgAction::Append))
.arg(Arg::new("values").long("values").action(ArgAction::Append))
+ .arg(
+ Arg::new("default-permission")
+ .long("default-permission")
+ .value_parser(protos::flag_permission::parse_from_str)
+ .default_value(protos::flag_permission::to_string(
+ &commands::DEFAULT_FLAG_PERMISSION,
+ )),
+ )
.arg(Arg::new("cache").long("cache").required(true)),
)
.subcommand(
@@ -71,7 +79,13 @@
.subcommand(
Command::new("create-rust-lib")
.arg(Arg::new("cache").long("cache").required(true))
- .arg(Arg::new("out").long("out").required(true)),
+ .arg(Arg::new("out").long("out").required(true))
+ .arg(
+ Arg::new("mode")
+ .long("mode")
+ .value_parser(EnumValueParser::<commands::CodegenMode>::new())
+ .default_value("production"),
+ ),
)
.subcommand(
Command::new("create-device-config-defaults")
@@ -123,26 +137,27 @@
}
fn write_output_file_realtive_to_dir(root: &Path, output_file: &OutputFile) -> Result<()> {
- ensure!(
- root.is_dir(),
- "output directory {} does not exist or is not a directory",
- root.display()
- );
let path = root.join(output_file.path.clone());
let parent = path
.parent()
.ok_or(anyhow!("unable to locate parent of output file {}", path.display()))?;
- fs::create_dir_all(parent)?;
- let mut file = fs::File::create(path)?;
- file.write_all(&output_file.contents)?;
+ fs::create_dir_all(parent)
+ .with_context(|| format!("failed to create directory {}", parent.display()))?;
+ let mut file = fs::File::create(path.clone())
+ .with_context(|| format!("failed to open {}", path.display()))?;
+ file.write_all(&output_file.contents)
+ .with_context(|| format!("failed to write to {}", path.display()))?;
Ok(())
}
fn write_output_to_file_or_stdout(path: &str, data: &[u8]) -> Result<()> {
if path == "-" {
- io::stdout().write_all(data)?;
+ io::stdout().write_all(data).context("failed to write to stdout")?;
} else {
- fs::File::create(path)?.write_all(data)?;
+ fs::File::create(path)
+ .with_context(|| format!("failed to open {}", path))?
+ .write_all(data)
+ .with_context(|| format!("failed to write to {}", path))?;
}
Ok(())
}
@@ -154,14 +169,18 @@
let package = get_required_arg::<String>(sub_matches, "package")?;
let declarations = open_zero_or_more_files(sub_matches, "declarations")?;
let values = open_zero_or_more_files(sub_matches, "values")?;
- let output = commands::parse_flags(package, declarations, values)?;
+ let default_permission =
+ get_required_arg::<protos::ProtoFlagPermission>(sub_matches, "default-permission")?;
+ let output = commands::parse_flags(package, declarations, values, *default_permission)
+ .context("failed to create cache")?;
let path = get_required_arg::<String>(sub_matches, "cache")?;
write_output_to_file_or_stdout(path, &output)?;
}
Some(("create-java-lib", sub_matches)) => {
let cache = open_single_file(sub_matches, "cache")?;
let mode = get_required_arg::<CodegenMode>(sub_matches, "mode")?;
- let generated_files = commands::create_java_lib(cache, *mode)?;
+ let generated_files =
+ commands::create_java_lib(cache, *mode).context("failed to create java lib")?;
let dir = PathBuf::from(get_required_arg::<String>(sub_matches, "out")?);
generated_files
.iter()
@@ -170,7 +189,8 @@
Some(("create-cpp-lib", sub_matches)) => {
let cache = open_single_file(sub_matches, "cache")?;
let mode = get_required_arg::<CodegenMode>(sub_matches, "mode")?;
- let generated_files = commands::create_cpp_lib(cache, *mode)?;
+ let generated_files =
+ commands::create_cpp_lib(cache, *mode).context("failed to create cpp lib")?;
let dir = PathBuf::from(get_required_arg::<String>(sub_matches, "out")?);
generated_files
.iter()
@@ -178,25 +198,30 @@
}
Some(("create-rust-lib", sub_matches)) => {
let cache = open_single_file(sub_matches, "cache")?;
- let generated_file = commands::create_rust_lib(cache)?;
+ let mode = get_required_arg::<CodegenMode>(sub_matches, "mode")?;
+ let generated_file =
+ commands::create_rust_lib(cache, *mode).context("failed to create rust lib")?;
let dir = PathBuf::from(get_required_arg::<String>(sub_matches, "out")?);
write_output_file_realtive_to_dir(&dir, &generated_file)?;
}
Some(("create-device-config-defaults", sub_matches)) => {
let cache = open_single_file(sub_matches, "cache")?;
- let output = commands::create_device_config_defaults(cache)?;
+ let output = commands::create_device_config_defaults(cache)
+ .context("failed to create device config defaults")?;
let path = get_required_arg::<String>(sub_matches, "out")?;
write_output_to_file_or_stdout(path, &output)?;
}
Some(("create-device-config-sysprops", sub_matches)) => {
let cache = open_single_file(sub_matches, "cache")?;
- let output = commands::create_device_config_sysprops(cache)?;
+ let output = commands::create_device_config_sysprops(cache)
+ .context("failed to create device config sysprops")?;
let path = get_required_arg::<String>(sub_matches, "out")?;
write_output_to_file_or_stdout(path, &output)?;
}
Some(("dump", sub_matches)) => {
let input = open_zero_or_more_files(sub_matches, "cache")?;
- let format = get_required_arg::<DumpFormat>(sub_matches, "format")?;
+ let format = get_required_arg::<DumpFormat>(sub_matches, "format")
+ .context("failed to dump previously parsed flags")?;
let output = commands::dump_parsed_flags(input, *format)?;
let path = get_required_arg::<String>(sub_matches, "out")?;
write_output_to_file_or_stdout(path, &output)?;
diff --git a/tools/aconfig/src/protos.rs b/tools/aconfig/src/protos.rs
index 17019be..c3911e5 100644
--- a/tools/aconfig/src/protos.rs
+++ b/tools/aconfig/src/protos.rs
@@ -92,8 +92,7 @@
ensure!(codegen::is_valid_name_ident(pdf.name()), "bad flag declaration: bad name");
ensure!(codegen::is_valid_name_ident(pdf.namespace()), "bad flag declaration: bad name");
ensure!(!pdf.description().is_empty(), "bad flag declaration: empty description");
-
- // ProtoFlagDeclaration.bug: Vec<String>: may be empty, no checks needed
+ ensure!(pdf.bug.len() == 1, "bad flag declaration: exactly one bug required");
Ok(())
}
@@ -157,6 +156,26 @@
}
}
+pub mod flag_permission {
+ use super::*;
+ use anyhow::bail;
+
+ pub fn parse_from_str(permission: &str) -> Result<ProtoFlagPermission> {
+ match permission.to_ascii_lowercase().as_str() {
+ "read_write" => Ok(ProtoFlagPermission::READ_WRITE),
+ "read_only" => Ok(ProtoFlagPermission::READ_ONLY),
+ _ => bail!("Permission needs to be read_only or read_write."),
+ }
+ }
+
+ pub fn to_string(permission: &ProtoFlagPermission) -> &str {
+ match permission {
+ ProtoFlagPermission::READ_WRITE => "read_write",
+ ProtoFlagPermission::READ_ONLY => "read_only",
+ }
+ }
+}
+
pub mod tracepoint {
use super::*;
use anyhow::ensure;
@@ -195,11 +214,15 @@
for tp in pf.trace.iter() {
super::tracepoint::verify_fields(tp)?;
}
-
- // ProtoParsedFlag.bug: Vec<String>: may be empty, no checks needed
+ ensure!(pf.bug.len() == 1, "bad flag declaration: exactly one bug required");
Ok(())
}
+
+ pub fn path_to_declaration(pf: &ProtoParsedFlag) -> &str {
+ debug_assert!(!pf.trace.is_empty());
+ pf.trace[0].source()
+ }
}
pub mod parsed_flags {
@@ -214,6 +237,8 @@
}
pub fn verify_fields(pf: &ProtoParsedFlags) -> Result<()> {
+ use crate::protos::parsed_flag::path_to_declaration;
+
let mut previous: Option<&ProtoParsedFlag> = None;
for parsed_flag in pf.parsed_flag.iter() {
if let Some(prev) = previous {
@@ -221,7 +246,12 @@
let b = create_sorting_key(parsed_flag);
match a.cmp(&b) {
Ordering::Less => {}
- Ordering::Equal => bail!("bad parsed flags: duplicate flag {}", a),
+ Ordering::Equal => bail!(
+ "bad parsed flags: duplicate flag {} (defined in {} and {})",
+ a,
+ path_to_declaration(prev),
+ path_to_declaration(parsed_flag)
+ ),
Ordering::Greater => {
bail!("bad parsed flags: not sorted: {} comes before {}", a, b)
}
@@ -243,6 +273,10 @@
Ok(merged)
}
+ pub fn sort_parsed_flags(pf: &mut ProtoParsedFlags) {
+ pf.parsed_flag.sort_by_key(create_sorting_key);
+ }
+
fn create_sorting_key(pf: &ProtoParsedFlag) -> String {
format!("{}.{}", pf.package(), pf.name())
}
@@ -263,12 +297,12 @@
namespace: "first_ns"
description: "This is the description of the first flag."
bug: "123"
- bug: "abc"
}
flag {
name: "second"
namespace: "second_ns"
description: "This is the description of the second flag."
+ bug: "abc"
}
"#,
)
@@ -278,14 +312,12 @@
assert_eq!(first.name(), "first");
assert_eq!(first.namespace(), "first_ns");
assert_eq!(first.description(), "This is the description of the first flag.");
- assert_eq!(first.bug.len(), 2);
- assert_eq!(first.bug[0], "123");
- assert_eq!(first.bug[1], "abc");
+ assert_eq!(first.bug, vec!["123"]);
let second = flag_declarations.flag.iter().find(|pf| pf.name() == "second").unwrap();
assert_eq!(second.name(), "second");
assert_eq!(second.namespace(), "second_ns");
assert_eq!(second.description(), "This is the description of the second flag.");
- assert_eq!(second.bug.len(), 0);
+ assert_eq!(second.bug, vec!["abc"]);
// bad input: missing package in flag declarations
let error = flag_declarations::try_from_text_proto(
@@ -360,6 +392,36 @@
)
.unwrap_err();
assert!(format!("{:?}", error).contains("bad flag declaration: bad name"));
+
+ // bad input: no bug entries in flag declaration
+ let error = flag_declarations::try_from_text_proto(
+ r#"
+package: "com.foo.bar"
+flag {
+ name: "first"
+ namespace: "first_ns"
+ description: "This is the description of the first flag."
+}
+"#,
+ )
+ .unwrap_err();
+ assert!(format!("{:?}", error).contains("bad flag declaration: exactly one bug required"));
+
+ // bad input: multiple bug entries in flag declaration
+ let error = flag_declarations::try_from_text_proto(
+ r#"
+package: "com.foo.bar"
+flag {
+ name: "first"
+ namespace: "first_ns"
+ description: "This is the description of the first flag."
+ bug: "123"
+ bug: "abc"
+}
+"#,
+ )
+ .unwrap_err();
+ assert!(format!("{:?}", error).contains("bad flag declaration: exactly one bug required"));
}
#[test]
@@ -466,6 +528,7 @@
name: "first"
namespace: "first_ns"
description: "This is the description of the first flag."
+ bug: "SOME_BUG"
state: DISABLED
permission: READ_ONLY
trace {
@@ -479,6 +542,7 @@
name: "second"
namespace: "second_ns"
description: "This is the description of the second flag."
+ bug: "SOME_BUG"
state: ENABLED
permission: READ_WRITE
trace {
@@ -500,6 +564,7 @@
assert_eq!(second.name(), "second");
assert_eq!(second.namespace(), "second_ns");
assert_eq!(second.description(), "This is the description of the second flag.");
+ assert_eq!(second.bug, vec!["SOME_BUG"]);
assert_eq!(second.state(), ProtoFlagState::ENABLED);
assert_eq!(second.permission(), ProtoFlagPermission::READ_WRITE);
assert_eq!(2, second.trace.len());
@@ -553,6 +618,7 @@
name: "first"
namespace: "first_ns"
description: "This is the description of the first flag."
+ bug: ""
state: DISABLED
permission: READ_ONLY
trace {
@@ -566,6 +632,7 @@
name: "second"
namespace: "second_ns"
description: "This is the description of the second flag."
+ bug: ""
state: ENABLED
permission: READ_WRITE
trace {
@@ -588,6 +655,7 @@
name: "bbb"
namespace: "first_ns"
description: "This is the description of the first flag."
+ bug: ""
state: DISABLED
permission: READ_ONLY
trace {
@@ -601,6 +669,7 @@
name: "aaa"
namespace: "second_ns"
description: "This is the description of the second flag."
+ bug: ""
state: ENABLED
permission: READ_WRITE
trace {
@@ -623,6 +692,7 @@
name: "bar"
namespace: "first_ns"
description: "This is the description of the first flag."
+ bug: ""
state: DISABLED
permission: READ_ONLY
trace {
@@ -636,6 +706,7 @@
name: "bar"
namespace: "second_ns"
description: "This is the description of the second flag."
+ bug: ""
state: ENABLED
permission: READ_WRITE
trace {
@@ -646,7 +717,38 @@
}
"#;
let error = try_from_binary_proto_from_text_proto(text_proto).unwrap_err();
- assert_eq!(format!("{:?}", error), "bad parsed flags: duplicate flag com.foo.bar");
+ assert_eq!(format!("{:?}", error), "bad parsed flags: duplicate flag com.foo.bar (defined in flags.declarations and flags.declarations)");
+ }
+
+ #[test]
+ fn test_parsed_flag_path_to_declaration() {
+ let text_proto = r#"
+parsed_flag {
+ package: "com.foo"
+ name: "bar"
+ namespace: "first_ns"
+ description: "This is the description of the first flag."
+ bug: "b/12345678"
+ state: DISABLED
+ permission: READ_ONLY
+ trace {
+ source: "flags.declarations"
+ state: DISABLED
+ permission: READ_ONLY
+ }
+ trace {
+ source: "flags.values"
+ state: ENABLED
+ permission: READ_ONLY
+ }
+}
+"#;
+ let parsed_flags = try_from_binary_proto_from_text_proto(text_proto).unwrap();
+ let parsed_flag = &parsed_flags.parsed_flag[0];
+ assert_eq!(
+ crate::protos::parsed_flag::path_to_declaration(parsed_flag),
+ "flags.declarations"
+ );
}
#[test]
@@ -657,6 +759,7 @@
name: "first"
namespace: "first_ns"
description: "This is the description of the first flag."
+ bug: "a"
state: DISABLED
permission: READ_ONLY
trace {
@@ -670,6 +773,7 @@
name: "second"
namespace: "second_ns"
description: "This is the description of the second flag."
+ bug: "b"
state: ENABLED
permission: READ_WRITE
trace {
@@ -687,6 +791,7 @@
name: "first"
namespace: "first_ns"
description: "This is the description of the first flag."
+ bug: "a"
state: DISABLED
permission: READ_ONLY
trace {
@@ -703,6 +808,7 @@
package: "com.second"
name: "second"
namespace: "second_ns"
+ bug: "b"
description: "This is the description of the second flag."
state: ENABLED
permission: READ_WRITE
@@ -717,7 +823,7 @@
// bad cases
let error = parsed_flags::merge(vec![first.clone(), first.clone()]).unwrap_err();
- assert_eq!(format!("{:?}", error), "bad parsed flags: duplicate flag com.first.first");
+ assert_eq!(format!("{:?}", error), "bad parsed flags: duplicate flag com.first.first (defined in flags.declarations and flags.declarations)");
// valid cases
assert!(parsed_flags::merge(vec![]).unwrap().parsed_flag.is_empty());
diff --git a/tools/aconfig/src/test.rs b/tools/aconfig/src/test.rs
index 04bbe28..6c27885 100644
--- a/tools/aconfig/src/test.rs
+++ b/tools/aconfig/src/test.rs
@@ -61,7 +61,6 @@
name: "enabled_ro"
namespace: "aconfig_test"
description: "This flag is ENABLED + READ_ONLY"
- bug: "789"
bug: "abc"
state: ENABLED
permission: READ_ONLY
@@ -86,6 +85,7 @@
name: "enabled_rw"
namespace: "aconfig_test"
description: "This flag is ENABLED + READ_WRITE"
+ bug: ""
state: ENABLED
permission: READ_WRITE
trace {
@@ -118,6 +118,7 @@
reader: Box::new(include_bytes!("../tests/second.values").as_slice()),
},
],
+ crate::commands::DEFAULT_FLAG_PERMISSION,
)
.unwrap();
crate::protos::parsed_flags::try_from_binary_proto(&bytes).unwrap()
diff --git a/tools/aconfig/templates/FakeFeatureFlagsImpl.java.template b/tools/aconfig/templates/FakeFeatureFlagsImpl.java.template
new file mode 100644
index 0000000..dba82ef
--- /dev/null
+++ b/tools/aconfig/templates/FakeFeatureFlagsImpl.java.template
@@ -0,0 +1,61 @@
+package {package_name};
+{{ if is_test_mode }}
+import static java.util.stream.Collectors.toMap;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.stream.Stream;
+
+public class FakeFeatureFlagsImpl implements FeatureFlags \{
+{{ for item in class_elements}}
+ @Override
+ public boolean {item.method_name}() \{
+ return getFlag(Flags.FLAG_{item.flag_name_constant_suffix});
+ }
+{{ endfor}}
+ @Override
+ public void setFlag(String flagName, boolean value) \{
+ if (!this.mFlagMap.containsKey(flagName)) \{
+ throw new IllegalArgumentException("no such flag" + flagName);
+ }
+ this.mFlagMap.put(flagName, value);
+ }
+
+ @Override
+ public void resetAll() \{
+ for (Map.Entry entry : mFlagMap.entrySet()) \{
+ entry.setValue(null);
+ }
+ }
+
+ private boolean getFlag(String flagName) \{
+ Boolean value = this.mFlagMap.get(flagName);
+ if (value == null) \{
+ throw new IllegalArgumentException(flagName + " is not set");
+ }
+ return value;
+ }
+
+ private HashMap<String, Boolean> mFlagMap = Stream.of(
+ {{-for item in class_elements}}
+ Flags.FLAG_{item.flag_name_constant_suffix}{{ if not @last }},{{ endif }}
+ {{ -endfor }}
+ )
+ .collect(
+ HashMap::new,
+ (map, elem) -> map.put(elem, null),
+ HashMap::putAll
+ );
+}
+{{ else }}
+{#- Generate only stub if in prod mode #}
+public class FakeFeatureFlagsImpl implements FeatureFlags \{
+{{ for item in class_elements}}
+ @Override
+ public boolean {item.method_name}() \{
+ throw new UnsupportedOperationException(
+ "Method is not implemented.");
+ }
+{{ endfor}}
+}
+{{ endif }}
diff --git a/tools/aconfig/templates/FeatureFlags.java.template b/tools/aconfig/templates/FeatureFlags.java.template
index e0f201f..c99ccbb 100644
--- a/tools/aconfig/templates/FeatureFlags.java.template
+++ b/tools/aconfig/templates/FeatureFlags.java.template
@@ -4,4 +4,10 @@
{{ for item in class_elements}}
boolean {item.method_name}();
{{ endfor }}
+
+{{ -if is_test_mode }}
+ public void setFlag(String flagName, boolean value);
+
+ public void resetAll();
+{{ -endif }}
}
diff --git a/tools/aconfig/templates/FeatureFlagsImpl.java.template b/tools/aconfig/templates/FeatureFlagsImpl.java.template
index 082d476..7e1eb15 100644
--- a/tools/aconfig/templates/FeatureFlagsImpl.java.template
+++ b/tools/aconfig/templates/FeatureFlagsImpl.java.template
@@ -1,65 +1,44 @@
package {package_name};
-{{ -if is_test_mode }}
-import static java.util.stream.Collectors.toMap;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.stream.Stream;
-{{ else}}
+{{ if not is_test_mode }}
{{ if is_read_write- }}
import android.provider.DeviceConfig;
-{{ -endif- }}
{{ endif }}
public final class FeatureFlagsImpl implements FeatureFlags \{
{{ for item in class_elements}}
@Override
public boolean {item.method_name}() \{
- {{ -if not is_test_mode- }}
- {{ if item.is_read_write }}
+ {{ -if item.is_read_write }}
return DeviceConfig.getBoolean(
"{item.device_config_namespace}",
"{item.device_config_flag}",
{item.default_value}
);
- {{ -else }}
+ {{ else }}
return {item.default_value};
- {{ -endif- }}
- {{ else }}
- return getFlag(Flags.FLAG_{item.flag_name_constant_suffix});
- {{ -endif }}
+ {{ endif- }}
}
{{ endfor- }}
-{{ if is_test_mode }}
- public void setFlag(String flagName, boolean value) \{
- if (!this.mFlagMap.containsKey(flagName)) \{
- throw new IllegalArgumentException("no such flag" + flagName);
- }
- this.mFlagMap.put(flagName, value);
- }
-
- public void resetAll() \{
- for (Map.Entry entry : mFlagMap.entrySet()) \{
- entry.setValue(null);
- }
- }
-
- private boolean getFlag(String flagName) \{
- Boolean value = this.mFlagMap.get(flagName);
- if (value == null) \{
- throw new IllegalArgumentException(flagName + " is not set");
- }
- return value;
- }
-
- private HashMap<String, Boolean> mFlagMap = Stream.of(
- {{-for item in class_elements}}
- Flags.FLAG_{item.flag_name_constant_suffix}{{ if not @last }},{{ endif }}
- {{ -endfor }}
- )
- .collect(
- HashMap::new,
- (map, elem) -> map.put(elem, null),
- HashMap::putAll
- );
-{{ -endif }}
}
+{{ else }}
+{#- Generate only stub if in test mode #}
+public final class FeatureFlagsImpl implements FeatureFlags \{
+{{ for item in class_elements}}
+ @Override
+ public boolean {item.method_name}() \{
+ throw new UnsupportedOperationException(
+ "Method is not implemented.");
+ }
+{{ endfor- }}
+ @Override
+ public void setFlag(String flagName, boolean value) \{
+ throw new UnsupportedOperationException(
+ "Method is not implemented.");
+ }
+
+ @Override
+ public void resetAll() \{
+ throw new UnsupportedOperationException(
+ "Method is not implemented.");
+ }
+}
+{{ endif }}
diff --git a/tools/aconfig/templates/Flags.java.template b/tools/aconfig/templates/Flags.java.template
index c244b15..012eba6 100644
--- a/tools/aconfig/templates/Flags.java.template
+++ b/tools/aconfig/templates/Flags.java.template
@@ -10,11 +10,11 @@
}
{{ endfor }}
{{ -if is_test_mode }}
- public static void setFeatureFlagsImpl(FeatureFlags featureFlags) \{
+ public static void setFeatureFlags(FeatureFlags featureFlags) \{
Flags.FEATURE_FLAGS = featureFlags;
}
- public static void unsetFeatureFlagsImpl() \{
+ public static void unsetFeatureFlags() \{
Flags.FEATURE_FLAGS = null;
}
{{ endif}}
diff --git a/tools/aconfig/templates/cpp_exported_header.template b/tools/aconfig/templates/cpp_exported_header.template
index e244de3..4d56dbc 100644
--- a/tools/aconfig/templates/cpp_exported_header.template
+++ b/tools/aconfig/templates/cpp_exported_header.template
@@ -1,12 +1,9 @@
-#ifndef {header}_HEADER_H
-#define {header}_HEADER_H
+#pragma once
-#include <string>
+#ifdef __cplusplus
+
#include <memory>
-{{ if readwrite }}
-#include <server_configurable_flags/get_flags.h>
-using namespace server_configurable_flags;
-{{ endif }}
+
namespace {cpp_namespace} \{
class flag_provider_interface \{
@@ -14,35 +11,63 @@
virtual ~flag_provider_interface() = default;
{{ for item in class_elements}}
virtual bool {item.flag_name}() = 0;
- {{ endfor }}
- virtual void override_flag(std::string const&, bool) \{}
- virtual void reset_overrides() \{}
+ {{ if for_test }}
+ virtual void {item.flag_name}(bool val) = 0;
+ {{ -endif }}
+ {{ endfor }}
+
+ {{ if for_test }}
+ virtual void reset_flags() \{}
+ {{ -endif }}
};
extern std::unique_ptr<flag_provider_interface> provider_;
-{{ for item in class_elements}}
-extern std::string const {item.uppercase_flag_name};{{ endfor }}
+
{{ for item in class_elements}}
inline bool {item.flag_name}() \{
- {{ if for_prod }}
+ {{ if for_test }}
+ return provider_->{item.flag_name}();
+ {{ -else- }}
{{ if not item.readwrite- }}
return {item.default_value};
{{ -else- }}
return provider_->{item.flag_name}();
{{ -endif }}
- {{ -else- }}
- return provider_->{item.flag_name}();
{{ -endif }}
}
+
+{{ if for_test }}
+inline void {item.flag_name}(bool val) \{
+ provider_->{item.flag_name}(val);
+}
+{{ -endif }}
{{ endfor }}
-inline void override_flag(std::string const& name, bool val) \{
- return provider_->override_flag(name, val);
-}
-inline void reset_overrides() \{
- return provider_->reset_overrides();
+{{ if for_test }}
+inline void reset_flags() \{
+ return provider_->reset_flags();
}
+{{ -endif }}
}
+
+extern "C" \{
+#endif // __cplusplus
+
+{{ for item in class_elements }}
+bool {header}_{item.flag_name}();
+
+{{ if for_test }}
+void set_{header}_{item.flag_name}(bool val);
+{{ -endif }}
+{{ endfor - }}
+
+{{ if for_test }}
+void {header}_reset_flags();
+{{ -endif }}
+
+#ifdef __cplusplus
+} // extern "C"
#endif
+
diff --git a/tools/aconfig/templates/cpp_prod_flag_provider.template b/tools/aconfig/templates/cpp_prod_flag_provider.template
deleted file mode 100644
index c966ed4..0000000
--- a/tools/aconfig/templates/cpp_prod_flag_provider.template
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifndef {header}_flag_provider_HEADER_H
-#define {header}_flag_provider_HEADER_H
-#include "{header}.h"
-
-namespace {cpp_namespace} \{
-class flag_provider : public flag_provider_interface \{
-public:
- {{ for item in class_elements}}
- virtual bool {item.flag_name}() override \{
- {{ if item.readwrite- }}
- return GetServerConfigurableFlag(
- "{item.device_config_namespace}",
- "{item.device_config_flag}",
- "{item.default_value}") == "true";
- {{ -else- }}
- return {item.default_value};
- {{ -endif }}
- }
- {{ endfor }}
-};
-}
-#endif
diff --git a/tools/aconfig/templates/cpp_source_file.template b/tools/aconfig/templates/cpp_source_file.template
index 1b4f336..289e299 100644
--- a/tools/aconfig/templates/cpp_source_file.template
+++ b/tools/aconfig/templates/cpp_source_file.template
@@ -1,10 +1,98 @@
-
#include "{header}.h"
-#include "{header}_flag_provider.h"
+{{ if readwrite }}
+#include <server_configurable_flags/get_flags.h>
+{{ endif }}
namespace {cpp_namespace} \{
-{{ for item in class_elements}}
-std::string const {item.uppercase_flag_name} = "{item.device_config_flag}";{{ endfor }}
+
+{{ if for_test }}
+ class flag_provider : public flag_provider_interface \{
+ private:
+ std::unordered_map<std::string, bool> overrides_;
+
+ public:
+ flag_provider()
+ : overrides_()
+ \{}
+
+ {{ for item in class_elements}}
+ virtual bool {item.flag_name}() override \{
+ auto it = overrides_.find("{item.flag_name}");
+ if (it != overrides_.end()) \{
+ return it->second;
+ } else \{
+ {{ if item.readwrite- }}
+ return server_configurable_flags::GetServerConfigurableFlag(
+ "{item.device_config_namespace}",
+ "{item.device_config_flag}",
+ "{item.default_value}") == "true";
+ {{ -else- }}
+ return {item.default_value};
+ {{ -endif }}
+ }
+ }
+
+ virtual void {item.flag_name}(bool val) override \{
+ overrides_["{item.flag_name}"] = val;
+ }
+ {{ endfor }}
+
+ virtual void reset_flags() override \{
+ overrides_.clear();
+ }
+ };
+
+{{ -else- }}
+
+ class flag_provider : public flag_provider_interface \{
+ public:
+ {{ for item in class_elements}}
+ virtual bool {item.flag_name}() override \{
+ {{ if item.readwrite- }}
+ return server_configurable_flags::GetServerConfigurableFlag(
+ "{item.device_config_namespace}",
+ "{item.device_config_flag}",
+ "{item.default_value}") == "true";
+ {{ -else- }}
+ return {item.default_value};
+ {{ -endif }}
+ }
+ {{ endfor }}
+ };
+
+
+{{ -endif }}
+
+
std::unique_ptr<flag_provider_interface> provider_ =
std::make_unique<flag_provider>();
+
}
+
+
+{{ for item in class_elements}}
+bool {header}_{item.flag_name}() \{
+ {{ if for_test }}
+ return {cpp_namespace}::{item.flag_name}();
+ {{ -else- }}
+ {{ if not item.readwrite- }}
+ return {item.default_value};
+ {{ -else- }}
+ return {cpp_namespace}::{item.flag_name}();
+ {{ -endif }}
+ {{ -endif }}
+}
+
+{{ if for_test }}
+void set_{header}_{item.flag_name}(bool val) \{
+ {cpp_namespace}::{item.flag_name}(val);
+}
+{{ -endif }}
+{{ endfor -}}
+
+{{ if for_test }}
+void {header}_reset_flags() \{
+ {cpp_namespace}::reset_flags();
+}
+{{ -endif }}
+
diff --git a/tools/aconfig/templates/cpp_test_flag_provider.template b/tools/aconfig/templates/cpp_test_flag_provider.template
deleted file mode 100644
index bd597e7..0000000
--- a/tools/aconfig/templates/cpp_test_flag_provider.template
+++ /dev/null
@@ -1,49 +0,0 @@
-#ifndef {header}_flag_provider_HEADER_H
-#define {header}_flag_provider_HEADER_H
-#include "{header}.h"
-
-#include <unordered_map>
-#include <unordered_set>
-#include <cassert>
-
-namespace {cpp_namespace} \{
-class flag_provider : public flag_provider_interface \{
-private:
- std::unordered_map<std::string, bool> overrides_;
- std::unordered_set<std::string> flag_names_;
-
-public:
- flag_provider()
- : overrides_(),
- flag_names_() \{
- {{ for item in class_elements}}
- flag_names_.insert({item.uppercase_flag_name});{{ endfor }}
- }
- {{ for item in class_elements}}
- virtual bool {item.flag_name}() override \{
- auto it = overrides_.find({item.uppercase_flag_name});
- if (it != overrides_.end()) \{
- return it->second;
- } else \{
- {{ if item.readwrite- }}
- return GetServerConfigurableFlag(
- "{item.device_config_namespace}",
- "{item.device_config_flag}",
- "{item.default_value}") == "true";
- {{ -else- }}
- return {item.default_value};
- {{ -endif }}
- }
- }
- {{ endfor }}
- virtual void override_flag(std::string const& flag, bool val) override \{
- assert(flag_names_.count(flag));
- overrides_[flag] = val;
- }
-
- virtual void reset_overrides() override \{
- overrides_.clear();
- }
-};
-}
-#endif
diff --git a/tools/aconfig/templates/rust.template b/tools/aconfig/templates/rust.template
deleted file mode 100644
index 960c494..0000000
--- a/tools/aconfig/templates/rust.template
+++ /dev/null
@@ -1,29 +0,0 @@
-{{- for mod in modules -}}
-pub mod {mod} \{
-{{ endfor -}}
-{{- for flag in template_flags -}}
-{{- if flag.is_read_only_disabled -}}
-#[inline(always)]
-pub const fn r#{flag.name}() -> bool \{
- false
-}
-
-{{ endif -}}
-{{- if flag.is_read_only_enabled -}}
-#[inline(always)]
-pub const fn r#{flag.name}() -> bool \{
- true
-}
-
-{{ endif -}}
-{{- if flag.is_read_write -}}
-#[inline(always)]
-pub fn r#{flag.name}() -> bool \{
- flags_rust::GetServerConfigurableFlag("{flag.device_config_namespace}", "{flag.device_config_flag}", "false") == "true"
-}
-
-{{ endif -}}
-{{- endfor -}}
-{{- for mod in modules -}}
-}
-{{ endfor -}}
diff --git a/tools/aconfig/templates/rust_prod.template b/tools/aconfig/templates/rust_prod.template
new file mode 100644
index 0000000..d518694
--- /dev/null
+++ b/tools/aconfig/templates/rust_prod.template
@@ -0,0 +1,38 @@
+//! codegenerated rust flag lib
+
+/// flag provider
+pub struct FlagProvider;
+
+impl FlagProvider \{
+
+ {{ for flag in template_flags }}
+ /// query flag {flag.name}
+ pub fn {flag.name}(&self) -> bool \{
+ {{ if flag.readwrite -}}
+ flags_rust::GetServerConfigurableFlag(
+ "{flag.device_config_namespace}",
+ "{flag.device_config_flag}",
+ "{flag.default_value}") == "true"
+ {{ -else- }}
+ {flag.default_value}
+ {{ -endif }}
+ }
+ {{ endfor }}
+
+}
+
+/// flag provider
+pub static PROVIDER: FlagProvider = FlagProvider;
+
+{{ for flag in template_flags }}
+/// query flag {flag.name}
+#[inline(always)]
+{{ if flag.readwrite -}}
+pub fn {flag.name}() -> bool \{
+ PROVIDER.{flag.name}()
+{{ -else- }}
+pub fn {flag.name}() -> bool \{
+ {flag.default_value}
+{{ -endif }}
+}
+{{ endfor }}
diff --git a/tools/aconfig/templates/rust_test.template b/tools/aconfig/templates/rust_test.template
new file mode 100644
index 0000000..1e2c28a
--- /dev/null
+++ b/tools/aconfig/templates/rust_test.template
@@ -0,0 +1,61 @@
+//! codegenerated rust flag lib
+
+use std::collections::BTreeMap;
+use std::sync::Mutex;
+
+/// flag provider
+pub struct FlagProvider \{
+ overrides: BTreeMap<&'static str, bool>,
+}
+
+impl FlagProvider \{
+ {{ for flag in template_flags }}
+ /// query flag {flag.name}
+ pub fn {flag.name}(&self) -> bool \{
+ self.overrides.get("{flag.name}").copied().unwrap_or(
+ {{ if flag.readwrite -}}
+ flags_rust::GetServerConfigurableFlag(
+ "{flag.device_config_namespace}",
+ "{flag.device_config_flag}",
+ "{flag.default_value}") == "true"
+ {{ -else- }}
+ {flag.default_value}
+ {{ -endif }}
+ )
+ }
+
+ /// set flag {flag.name}
+ pub fn set_{flag.name}(&mut self, val: bool) \{
+ self.overrides.insert("{flag.name}", val);
+ }
+ {{ endfor }}
+
+ /// clear all flag overrides
+ pub fn reset_flags(&mut self) \{
+ self.overrides.clear();
+ }
+}
+
+/// flag provider
+pub static PROVIDER: Mutex<FlagProvider> = Mutex::new(
+ FlagProvider \{overrides: BTreeMap::new()}
+);
+
+{{ for flag in template_flags }}
+/// query flag {flag.name}
+#[inline(always)]
+pub fn {flag.name}() -> bool \{
+ PROVIDER.lock().unwrap().{flag.name}()
+}
+
+/// set flag {flag.name}
+#[inline(always)]
+pub fn set_{flag.name}(val: bool) \{
+ PROVIDER.lock().unwrap().set_{flag.name}(val);
+}
+{{ endfor }}
+
+/// clear all flag override
+pub fn reset_flags() \{
+ PROVIDER.lock().unwrap().reset_flags()
+}
diff --git a/tools/aconfig/tests/AconfigHostTest.java b/tools/aconfig/tests/AconfigHostTest.java
new file mode 100644
index 0000000..29a01e3
--- /dev/null
+++ b/tools/aconfig/tests/AconfigHostTest.java
@@ -0,0 +1,88 @@
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+
+import com.android.aconfig.test.FakeFeatureFlagsImpl;
+import com.android.aconfig.test.FeatureFlags;
+import com.android.aconfig.test.FeatureFlagsImpl;
+import com.android.aconfig.test.Flags;
+
+@RunWith(JUnit4.class)
+public final class AconfigHostTest {
+ @Test
+ public void testThrowsExceptionIfFlagNotSet() {
+ assertThrows(NullPointerException.class, () -> Flags.disabledRo());
+ FeatureFlags featureFlags = new FakeFeatureFlagsImpl();
+ assertThrows(IllegalArgumentException.class, () -> featureFlags.disabledRo());
+ }
+
+ @Test
+ public void testSetFlagInFakeFeatureFlagsImpl() {
+ FeatureFlags featureFlags = new FakeFeatureFlagsImpl();
+ featureFlags.setFlag(Flags.FLAG_ENABLED_RW, true);
+ assertTrue(featureFlags.enabledRw());
+ featureFlags.setFlag(Flags.FLAG_ENABLED_RW, false);
+ assertFalse(featureFlags.enabledRw());
+
+ //Set Flags
+ assertThrows(NullPointerException.class, () -> Flags.enabledRw());
+ Flags.setFeatureFlags(featureFlags);
+ featureFlags.setFlag(Flags.FLAG_ENABLED_RW, true);
+ assertTrue(Flags.enabledRw());
+ Flags.unsetFeatureFlags();
+ }
+
+ @Test
+ public void testSetFlagWithRandomName() {
+ FeatureFlags featureFlags = new FakeFeatureFlagsImpl();
+ assertThrows(IllegalArgumentException.class,
+ () -> featureFlags.setFlag("Randome_name", true));
+ }
+
+ @Test
+ public void testResetFlagsInFakeFeatureFlagsImpl() {
+ FeatureFlags featureFlags = new FakeFeatureFlagsImpl();
+ featureFlags.setFlag(Flags.FLAG_ENABLED_RO, true);
+ assertTrue(featureFlags.enabledRo());
+ featureFlags.resetAll();
+ assertThrows(IllegalArgumentException.class, () -> featureFlags.enabledRo());
+
+ // Set value after reset
+ featureFlags.setFlag(Flags.FLAG_ENABLED_RO, false);
+ assertFalse(featureFlags.enabledRo());
+ }
+
+ @Test
+ public void testFlagsSetFeatureFlags() {
+ FeatureFlags featureFlags = new FakeFeatureFlagsImpl();
+ featureFlags.setFlag(Flags.FLAG_ENABLED_RW, true);
+ assertThrows(NullPointerException.class, () -> Flags.enabledRw());
+ Flags.setFeatureFlags(featureFlags);
+ assertTrue(Flags.enabledRw());
+ Flags.unsetFeatureFlags();
+ }
+
+ @Test
+ public void testFlagsUnsetFeatureFlags() {
+ FeatureFlags featureFlags = new FakeFeatureFlagsImpl();
+ featureFlags.setFlag(Flags.FLAG_ENABLED_RW, true);
+ assertThrows(NullPointerException.class, () -> Flags.enabledRw());
+ Flags.setFeatureFlags(featureFlags);
+ assertTrue(Flags.enabledRw());
+
+ Flags.unsetFeatureFlags();
+ assertThrows(NullPointerException.class, () -> Flags.enabledRw());
+ }
+
+ @Test
+ public void testFeatureFlagsImplNotImpl() {
+ FeatureFlags featureFlags = new FeatureFlagsImpl();
+ assertThrows(UnsupportedOperationException.class,
+ () -> featureFlags.enabledRw());
+ }
+}
diff --git a/tools/aconfig/tests/AconfigTest.java b/tools/aconfig/tests/AconfigTest.java
index 778a4c6..317289d 100644
--- a/tools/aconfig/tests/AconfigTest.java
+++ b/tools/aconfig/tests/AconfigTest.java
@@ -1,23 +1,34 @@
+import static com.android.aconfig.test.Flags.FLAG_DISABLED_RO;
+import static com.android.aconfig.test.Flags.FLAG_DISABLED_RW;
+import static com.android.aconfig.test.Flags.FLAG_ENABLED_RO;
+import static com.android.aconfig.test.Flags.FLAG_ENABLED_RW;
import static com.android.aconfig.test.Flags.disabledRo;
import static com.android.aconfig.test.Flags.disabledRw;
import static com.android.aconfig.test.Flags.enabledRo;
import static com.android.aconfig.test.Flags.enabledRw;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
+import com.android.aconfig.test.FakeFeatureFlagsImpl;
+import com.android.aconfig.test.FeatureFlags;
+
@RunWith(JUnit4.class)
public final class AconfigTest {
@Test
public void testDisabledReadOnlyFlag() {
+ assertEquals("com.android.aconfig.test.disabled_ro", FLAG_DISABLED_RO);
assertFalse(disabledRo());
}
@Test
public void testEnabledReadOnlyFlag() {
+ assertEquals("com.android.aconfig.test.disabled_rw", FLAG_DISABLED_RW);
// TODO: change to assertTrue(enabledRo()) when the build supports reading tests/*.values
// (currently all flags are assigned the default READ_ONLY + DISABLED)
assertFalse(enabledRo());
@@ -25,13 +36,21 @@
@Test
public void testDisabledReadWriteFlag() {
+ assertEquals("com.android.aconfig.test.enabled_ro", FLAG_ENABLED_RO);
assertFalse(disabledRw());
}
@Test
public void testEnabledReadWriteFlag() {
+ assertEquals("com.android.aconfig.test.enabled_rw", FLAG_ENABLED_RW);
// TODO: change to assertTrue(enabledRw()) when the build supports reading tests/*.values
// (currently all flags are assigned the default READ_ONLY + DISABLED)
assertFalse(enabledRw());
}
+
+ @Test
+ public void testFakeFeatureFlagsImplNotImpl() {
+ FeatureFlags featureFlags = new FakeFeatureFlagsImpl();
+ assertThrows(UnsupportedOperationException.class, () -> featureFlags.enabledRw());
+ }
}
diff --git a/tools/aconfig/tests/aconfig_test.cpp b/tools/aconfig/tests/aconfig_test.cpp
new file mode 100644
index 0000000..10de347
--- /dev/null
+++ b/tools/aconfig/tests/aconfig_test.cpp
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "com_android_aconfig_test.h"
+#include "gtest/gtest.h"
+
+TEST(AconfigTest, TestDisabledReadOnlyFlag) {
+ ASSERT_FALSE(com_android_aconfig_test_disabled_ro());
+}
+
+TEST(AconfigTest, TestEnabledReadOnlyFlag) {
+ // TODO: change to assertTrue(enabledRo()) when the build supports reading tests/*.values
+ // (currently all flags are assigned the default READ_ONLY + DISABLED)
+ ASSERT_FALSE(com_android_aconfig_test_enabled_ro());
+}
+
+TEST(AconfigTest, TestDisabledReadWriteFlag) {
+ ASSERT_FALSE(com_android_aconfig_test_disabled_rw());
+}
+
+TEST(AconfigTest, TestEnabledReadWriteFlag) {
+ // TODO: change to assertTrue(enabledRo()) when the build supports reading tests/*.values
+ // (currently all flags are assigned the default READ_ONLY + DISABLED)
+ ASSERT_FALSE(com_android_aconfig_test_enabled_rw());
+}
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
diff --git a/tools/aconfig/tests/aconfig_test.rs b/tools/aconfig/tests/aconfig_test.rs
new file mode 100644
index 0000000..dbfe141
--- /dev/null
+++ b/tools/aconfig/tests/aconfig_test.rs
@@ -0,0 +1,7 @@
+#[test]
+fn test_flags() {
+ assert!(!aconfig_test_rust_library::disabled_ro());
+ assert!(!aconfig_test_rust_library::disabled_rw());
+ assert!(aconfig_test_rust_library::enabled_ro());
+ assert!(aconfig_test_rust_library::enabled_rw());
+}
diff --git a/tools/aconfig/tests/test.aconfig b/tools/aconfig/tests/test.aconfig
index a8f6652..46cf1e9 100644
--- a/tools/aconfig/tests/test.aconfig
+++ b/tools/aconfig/tests/test.aconfig
@@ -2,6 +2,28 @@
# This flag's final value is calculated from:
# - test.aconfig: DISABLED + READ_WRITE (default)
+# - first.values: DISABLED + READ_WRITE
+# - second.values: ENABLED + READ_ONLY
+flag {
+ name: "enabled_ro"
+ namespace: "aconfig_test"
+ description: "This flag is ENABLED + READ_ONLY"
+ bug: "abc"
+}
+
+# This flag's final value is calculated from:
+# - test.aconfig: DISABLED + READ_WRITE (default)
+# - first.values: ENABLED + READ_WRITE
+flag {
+ name: "enabled_rw"
+ namespace: "aconfig_test"
+ description: "This flag is ENABLED + READ_WRITE"
+ # for bug fields, the empty string is a discouraged but valid value
+ bug: ""
+}
+
+# This flag's final value is calculated from:
+# - test.aconfig: DISABLED + READ_WRITE (default)
# - first.values: DISABLED + READ_ONLY
flag {
name: "disabled_ro"
@@ -18,25 +40,3 @@
description: "This flag is DISABLED + READ_WRITE"
bug: "456"
}
-
-# This flag's final value is calculated from:
-# - test.aconfig: DISABLED + READ_WRITE (default)
-# - first.values: DISABLED + READ_WRITE
-# - second.values: ENABLED + READ_ONLY
-flag {
- name: "enabled_ro"
- namespace: "aconfig_test"
- description: "This flag is ENABLED + READ_ONLY"
- bug: "789"
- bug: "abc"
-}
-
-# This flag's final value is calculated from:
-# - test.aconfig: DISABLED + READ_WRITE (default)
-# - first.values: ENABLED + READ_WRITE
-flag {
- name: "enabled_rw"
- namespace: "aconfig_test"
- description: "This flag is ENABLED + READ_WRITE"
- # no bug field: bug is not mandatory
-}
diff --git a/tools/buildinfo.sh b/tools/buildinfo.sh
index c2e36df..0ed9453 100755
--- a/tools/buildinfo.sh
+++ b/tools/buildinfo.sh
@@ -7,9 +7,9 @@
if [ "$BOARD_USE_VBMETA_DIGTEST_IN_FINGERPRINT" = "true" ] ; then
echo "ro.build.legacy.id=$BUILD_ID"
else
- echo "ro.build.id=$BUILD_ID"
+ echo "ro.build.id?=$BUILD_ID"
fi
-echo "ro.build.display.id=$BUILD_DISPLAY_ID"
+echo "ro.build.display.id?=$BUILD_DISPLAY_ID"
echo "ro.build.version.incremental=$BUILD_NUMBER"
echo "ro.build.version.sdk=$PLATFORM_SDK_VERSION"
echo "ro.build.version.preview_sdk=$PLATFORM_PREVIEW_SDK_VERSION"
@@ -28,7 +28,9 @@
echo "ro.build.type=$TARGET_BUILD_TYPE"
echo "ro.build.user=$BUILD_USERNAME"
echo "ro.build.host=$BUILD_HOSTNAME"
-echo "ro.build.tags=$BUILD_VERSION_TAGS"
+# TODO: Remove any tag-related optional property declarations once the goals
+# from go/arc-android-sigprop-changes have been achieved.
+echo "ro.build.tags?=$BUILD_VERSION_TAGS"
echo "ro.build.flavor=$TARGET_BUILD_FLAVOR"
# These values are deprecated, use "ro.product.cpu.abilist"
@@ -49,7 +51,7 @@
echo "ro.build.product=$TARGET_DEVICE"
echo "# Do not try to parse description or thumbprint"
-echo "ro.build.description=$PRIVATE_BUILD_DESC"
+echo "ro.build.description?=$PRIVATE_BUILD_DESC"
if [ -n "$BUILD_THUMBPRINT" ] ; then
echo "ro.build.thumbprint=$BUILD_THUMBPRINT"
fi
diff --git a/tools/releasetools/Android.bp b/tools/releasetools/Android.bp
index 7a2dcb7..5a7cc76 100644
--- a/tools/releasetools/Android.bp
+++ b/tools/releasetools/Android.bp
@@ -168,7 +168,6 @@
"brillo_update_payload",
"checkvintf",
"generate_gki_certificate",
- "minigzip",
"lz4",
"toybox",
"unpack_bootimg",
@@ -244,7 +243,6 @@
"bsdiff",
"generate_gki_certificate",
"imgdiff",
- "minigzip",
"lz4",
"mkbootfs",
"signapk",
@@ -310,7 +308,6 @@
"deapexer",
"generate_gki_certificate",
"imgdiff",
- "minigzip",
"lz4",
"mkbootfs",
"signapk",
diff --git a/tools/releasetools/add_img_to_target_files.py b/tools/releasetools/add_img_to_target_files.py
index 465d222..31f8736 100644
--- a/tools/releasetools/add_img_to_target_files.py
+++ b/tools/releasetools/add_img_to_target_files.py
@@ -517,12 +517,14 @@
return img.name
-def AddCustomImages(output_zip, partition_name):
- """Adds and signs custom images in IMAGES/.
+def AddCustomImages(output_zip, partition_name, image_list):
+ """Adds and signs avb custom images as needed in IMAGES/.
Args:
output_zip: The output zip file (needs to be already open), or None to
write images to OPTIONS.input_tmp/.
+ partition_name: The custom image partition name.
+ image_list: The image list of the custom image partition.
Uses the image under IMAGES/ if it already exists. Otherwise looks for the
image under PREBUILT_IMAGES/, signs it as needed, and returns the image name.
@@ -531,19 +533,20 @@
AssertionError: If image can't be found.
"""
+ builder = None
key_path = OPTIONS.info_dict.get("avb_{}_key_path".format(partition_name))
- algorithm = OPTIONS.info_dict.get("avb_{}_algorithm".format(partition_name))
- extra_args = OPTIONS.info_dict.get(
- "avb_{}_add_hashtree_footer_args".format(partition_name))
- partition_size = OPTIONS.info_dict.get(
- "avb_{}_partition_size".format(partition_name))
+ if key_path is not None:
+ algorithm = OPTIONS.info_dict.get("avb_{}_algorithm".format(partition_name))
+ extra_args = OPTIONS.info_dict.get(
+ "avb_{}_add_hashtree_footer_args".format(partition_name))
+ partition_size = OPTIONS.info_dict.get(
+ "avb_{}_partition_size".format(partition_name))
- builder = verity_utils.CreateCustomImageBuilder(
- OPTIONS.info_dict, partition_name, partition_size,
- key_path, algorithm, extra_args)
+ builder = verity_utils.CreateCustomImageBuilder(
+ OPTIONS.info_dict, partition_name, partition_size,
+ key_path, algorithm, extra_args)
- for img_name in OPTIONS.info_dict.get(
- "avb_{}_image_list".format(partition_name)).split():
+ for img_name in image_list:
custom_image = OutputFile(
output_zip, OPTIONS.input_tmp, "IMAGES", img_name)
if os.path.exists(custom_image.name):
@@ -684,34 +687,6 @@
return img.name
-def AddPartitionTable(output_zip):
- """Create a partition table image and store it in output_zip."""
-
- img = OutputFile(
- output_zip, OPTIONS.input_tmp, "IMAGES", "partition-table.img")
- bpt = OutputFile(
- output_zip, OPTIONS.input_tmp, "META", "partition-table.bpt")
-
- # use BPTTOOL from environ, or "bpttool" if empty or not set.
- bpttool = os.getenv("BPTTOOL") or "bpttool"
- cmd = [bpttool, "make_table", "--output_json", bpt.name,
- "--output_gpt", img.name]
- input_files_str = OPTIONS.info_dict["board_bpt_input_files"]
- input_files = input_files_str.split()
- for i in input_files:
- cmd.extend(["--input", i])
- disk_size = OPTIONS.info_dict.get("board_bpt_disk_size")
- if disk_size:
- cmd.extend(["--disk_size", disk_size])
- args = OPTIONS.info_dict.get("board_bpt_make_table_args")
- if args:
- cmd.extend(shlex.split(args))
- common.RunAndCheckOutput(cmd)
-
- img.Write()
- bpt.Write()
-
-
def AddCache(output_zip):
"""Create an empty cache image and store it in output_zip."""
@@ -1087,10 +1062,6 @@
banner("cache")
AddCache(output_zip)
- if OPTIONS.info_dict.get("board_bpt_enable") == "true":
- banner("partition-table")
- AddPartitionTable(output_zip)
-
add_partition("dtbo",
OPTIONS.info_dict.get("has_dtbo") == "true", AddDtbo, [])
add_partition("pvmfw",
@@ -1098,18 +1069,29 @@
# Custom images.
custom_partitions = OPTIONS.info_dict.get(
- "avb_custom_images_partition_list", "").strip().split()
+ "custom_images_partition_list", "").strip().split()
for partition_name in custom_partitions:
partition_name = partition_name.strip()
banner("custom images for " + partition_name)
- partitions[partition_name] = AddCustomImages(output_zip, partition_name)
+ image_list = OPTIONS.info_dict.get(
+ "{}_image_list".format(partition_name)).split()
+ partitions[partition_name] = AddCustomImages(output_zip, partition_name, image_list)
+
+ avb_custom_partitions = OPTIONS.info_dict.get(
+ "avb_custom_images_partition_list", "").strip().split()
+ for partition_name in avb_custom_partitions:
+ partition_name = partition_name.strip()
+ banner("avb custom images for " + partition_name)
+ image_list = OPTIONS.info_dict.get(
+ "avb_{}_image_list".format(partition_name)).split()
+ partitions[partition_name] = AddCustomImages(output_zip, partition_name, image_list)
if OPTIONS.info_dict.get("avb_enable") == "true":
# vbmeta_partitions includes the partitions that should be included into
# top-level vbmeta.img, which are the ones that are not included in any
# chained VBMeta image plus the chained VBMeta images themselves.
- # Currently custom_partitions are all chained to VBMeta image.
- vbmeta_partitions = common.AVB_PARTITIONS[:] + tuple(custom_partitions)
+ # Currently avb_custom_partitions are all chained to VBMeta image.
+ vbmeta_partitions = common.AVB_PARTITIONS[:] + tuple(avb_custom_partitions)
vbmeta_system = OPTIONS.info_dict.get("avb_vbmeta_system", "").strip()
if vbmeta_system:
diff --git a/tools/releasetools/build_image.py b/tools/releasetools/build_image.py
index 11bd784..8c6d597 100755
--- a/tools/releasetools/build_image.py
+++ b/tools/releasetools/build_image.py
@@ -683,7 +683,9 @@
d = {}
TryParseFingerprint(glob_dict)
- d["timestamp"] = FIXED_FILE_TIMESTAMP
+ # Set fixed timestamp for building the OTA package.
+ if "use_fixed_timestamp" in glob_dict:
+ d["timestamp"] = FIXED_FILE_TIMESTAMP
if "build.prop" in glob_dict:
timestamp = glob_dict["build.prop"].GetProp("ro.build.date.utc")
if timestamp:
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index 091121f..826ab1b 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -96,7 +96,6 @@
self.cache_size = None
self.stash_threshold = 0.8
self.logfile = None
- self.host_tools = {}
self.sepolicy_name = 'sepolicy.apex'
@@ -225,23 +224,15 @@
logging.config.dictConfig(config)
-def SetHostToolLocation(tool_name, location):
- OPTIONS.host_tools[tool_name] = location
-
-
def FindHostToolPath(tool_name):
"""Finds the path to the host tool.
Args:
tool_name: name of the tool to find
Returns:
- path to the tool if found under either one of the host_tools map or under
- the same directory as this binary is located at. If not found, tool_name
- is returned.
+ path to the tool if found under the same directory as this binary is located at. If not found,
+ tool_name is returned.
"""
- if tool_name in OPTIONS.host_tools:
- return OPTIONS.host_tools[tool_name]
-
my_dir = os.path.dirname(os.path.realpath(sys.argv[0]))
tool_path = os.path.join(my_dir, tool_name)
if os.path.exists(tool_path):
@@ -985,7 +976,7 @@
each of the variables.
ramdisk_format: If name is "boot", the format of ramdisk inside the
boot image. Otherwise, its value is ignored.
- Use lz4 to decompress by default. If its value is gzip, use minigzip.
+ Use lz4 to decompress by default. If its value is gzip, use gzip.
"""
def __init__(self, input_file, name, placeholder_values=None):
@@ -1429,7 +1420,7 @@
if os.path.exists(new_path):
return new_path
raise ExternalError(
- "Failed to find {}".format(new_path))
+ "Failed to find {}".format(path))
if not split_args:
return split_args
@@ -1638,9 +1629,9 @@
p2 = Run(["lz4", "-l", "-12", "--favor-decSpeed"], stdin=p1.stdout,
stdout=ramdisk_img.file.fileno())
elif ramdisk_format == RamdiskFormat.GZ:
- p2 = Run(["minigzip"], stdin=p1.stdout, stdout=ramdisk_img.file.fileno())
+ p2 = Run(["gzip"], stdin=p1.stdout, stdout=ramdisk_img.file.fileno())
else:
- raise ValueError("Only support lz4 or minigzip ramdisk format.")
+ raise ValueError("Only support lz4 or gzip ramdisk format.")
p2.wait()
p1.wait()
@@ -2120,20 +2111,33 @@
# According to https://stackoverflow.com/questions/434641/how-do-i-set-permissions-attributes-on-a-file-in-a-zip-file-using-pythons-zip/6297838#6297838
# higher bits of |external_attr| are unix file permission and types
unix_filetype = info.external_attr >> 16
+ file_perm = unix_filetype & 0o777
def CheckMask(a, mask):
return (a & mask) == mask
def IsSymlink(a):
return CheckMask(a, stat.S_IFLNK)
+
+ def IsDir(a):
+ return CheckMask(a, stat.S_IFDIR)
# python3.11 zipfile implementation doesn't handle symlink correctly
if not IsSymlink(unix_filetype):
- return input_zip.extract(info, dirname)
+ target = input_zip.extract(info, dirname)
+ # We want to ensure that the file is at least read/writable by owner and readable by all users
+ if IsDir(unix_filetype):
+ os.chmod(target, file_perm | 0o755)
+ else:
+ os.chmod(target, file_perm | 0o644)
+ return target
if dirname is None:
dirname = os.getcwd()
target = os.path.join(dirname, info.filename)
os.makedirs(os.path.dirname(target), exist_ok=True)
+ if os.path.exists(target):
+ os.unlink(target)
os.symlink(input_zip.read(info).decode(), target)
+ return target
def UnzipToDir(filename, dirname, patterns=None):
@@ -2425,8 +2429,9 @@
apk_name, proc.returncode, stdoutdata, stderrdata))
for line in stdoutdata.split("\n"):
- # Looking for lines such as sdkVersion:'23' or sdkVersion:'M'.
- m = re.match(r'sdkVersion:\'([^\']*)\'', line)
+ # Due to ag/24161708, looking for lines such as minSdkVersion:'23',minSdkVersion:'M'
+ # or sdkVersion:'23', sdkVersion:'M'.
+ m = re.match(r'(?:minSdkVersion|sdkVersion):\'([^\']*)\'', line)
if m:
return m.group(1)
raise ExternalError("No minSdkVersion returned by aapt2")
@@ -4075,7 +4080,7 @@
Get build.prop from ramdisk within the boot image
Args:
- boot_img: the boot image file. Ramdisk must be compressed with lz4 or minigzip format.
+ boot_img: the boot image file. Ramdisk must be compressed with lz4 or gzip format.
Return:
An extracted file that stores properties in the boot image.
@@ -4094,11 +4099,11 @@
elif ramdisk_format == RamdiskFormat.GZ:
with open(ramdisk, 'rb') as input_stream:
with open(uncompressed_ramdisk, 'wb') as output_stream:
- p2 = Run(['minigzip', '-d'], stdin=input_stream.fileno(),
+ p2 = Run(['gzip', '-d'], stdin=input_stream.fileno(),
stdout=output_stream.fileno())
p2.wait()
else:
- logger.error('Only support lz4 or minigzip ramdisk format.')
+ logger.error('Only support lz4 or gzip ramdisk format.')
return None
abs_uncompressed_ramdisk = os.path.abspath(uncompressed_ramdisk)
diff --git a/tools/releasetools/img_from_target_files.py b/tools/releasetools/img_from_target_files.py
index fa53ad2..5412b2a 100755
--- a/tools/releasetools/img_from_target_files.py
+++ b/tools/releasetools/img_from_target_files.py
@@ -65,6 +65,7 @@
OPTIONS.build_super = None
OPTIONS.sparse_userimages = None
OPTIONS.use_fastboot_info = False
+OPTIONS.build_super_image = None
def LoadOptions(input_file):
"""Loads information from input_file to OPTIONS.
@@ -174,7 +175,13 @@
input_tmp = common.UnzipTemp(input_file)
super_file = common.MakeTempFile('super_', '.img')
- BuildSuperImage(input_tmp, super_file)
+
+ # Allow overriding the BUILD_SUPER_IMAGE binary
+ if OPTIONS.build_super_image:
+ command = [OPTIONS.build_super_image, input_tmp, super_file]
+ common.RunAndCheckOutput(command)
+ else:
+ BuildSuperImage(input_tmp, super_file)
logger.info('Writing super.img to archive...')
with zipfile.ZipFile(
@@ -231,6 +238,8 @@
OPTIONS.bootable_only = True
elif o == '--additional':
OPTIONS.additional_entries.append(a)
+ elif o == '--build_super_image':
+ OPTIONS.build_super_image = a
else:
return False
return True
@@ -240,6 +249,7 @@
extra_long_opts=[
'additional=',
'bootable_zip',
+ 'build_super_image=',
],
extra_option_handler=option_handler)
if len(args) != 2:
diff --git a/tools/releasetools/merge/merge_utils.py b/tools/releasetools/merge/merge_utils.py
index b5683a8..d446fc0 100644
--- a/tools/releasetools/merge/merge_utils.py
+++ b/tools/releasetools/merge/merge_utils.py
@@ -217,7 +217,7 @@
# Partitions that are grabbed from the framework partial build by default.
_FRAMEWORK_PARTITIONS = {
- 'system', 'product', 'system_ext', 'system_other', 'root', 'system_dlkm',
+ 'system', 'product', 'system_ext', 'system_other', 'root',
'vbmeta_system', 'pvmfw'
}
diff --git a/tools/releasetools/ota_from_target_files.py b/tools/releasetools/ota_from_target_files.py
index f3e6f1e..71dbde6 100755
--- a/tools/releasetools/ota_from_target_files.py
+++ b/tools/releasetools/ota_from_target_files.py
@@ -147,7 +147,7 @@
A/B OTA specific options
--disable_fec_computation
- Disable the on device FEC data computation for incremental updates.
+ Disable the on device FEC data computation for incremental updates. OTA will be larger but installation will be faster.
--include_secondary
Additionally include the payload for secondary slot images (default:
@@ -224,7 +224,7 @@
wait time in recovery.
--enable_vabc_xor
- Enable the VABC xor feature. Will reduce space requirements for OTA
+ Enable the VABC xor feature. Will reduce space requirements for OTA, but OTA installation will be slower.
--force_minor_version
Override the update_engine minor version for delta generation.
@@ -233,7 +233,10 @@
A colon ':' separated list of compressors. Allowed values are bz2 and brotli.
--enable_zucchini
- Whether to enable to zucchini feature. Will generate smaller OTA but uses more memory.
+ Whether to enable to zucchini feature. Will generate smaller OTA but uses more memory, OTA generation will take longer.
+
+ --enable_puffdiff
+ Whether to enable to puffdiff feature. Will generate smaller OTA but uses more memory, OTA generation will take longer.
--enable_lz4diff
Whether to enable lz4diff feature. Will generate smaller OTA for EROFS but
@@ -244,7 +247,9 @@
older SPL.
--vabc_compression_param
- Compression algorithm to be used for VABC. Available options: gz, brotli, none
+ Compression algorithm to be used for VABC. Available options: gz, lz4, zstd, brotli, none.
+ Compression level can be specified by appending ",$LEVEL" to option.
+ e.g. --vabc_compression_param=gz,9 specifies level 9 compression with gz algorithm
--security_patch_level
Override the security patch level in target files
@@ -320,6 +325,7 @@
OPTIONS.force_minor_version = None
OPTIONS.compressor_types = None
OPTIONS.enable_zucchini = True
+OPTIONS.enable_puffdiff = None
OPTIONS.enable_lz4diff = False
OPTIONS.vabc_compression_param = None
OPTIONS.security_patch_level = None
@@ -456,48 +462,51 @@
target_file = common.MakeTempFile(prefix="targetfiles-", suffix=".zip")
target_zip = zipfile.ZipFile(target_file, 'w', allowZip64=True)
- with zipfile.ZipFile(input_file, 'r', allowZip64=True) as input_zip:
- infolist = input_zip.infolist()
+ fileslist = []
+ for (root, dirs, files) in os.walk(input_file):
+ root = root.lstrip(input_file).lstrip("/")
+ fileslist.extend([os.path.join(root, d) for d in dirs])
+ fileslist.extend([os.path.join(root, d) for d in files])
- input_tmp = common.UnzipTemp(input_file, UNZIP_PATTERN)
- for info in infolist:
- unzipped_file = os.path.join(input_tmp, *info.filename.split('/'))
- if info.filename == 'IMAGES/system_other.img':
+ input_tmp = input_file
+ for filename in fileslist:
+ unzipped_file = os.path.join(input_tmp, *filename.split('/'))
+ if filename == 'IMAGES/system_other.img':
common.ZipWrite(target_zip, unzipped_file, arcname='IMAGES/system.img')
# Primary images and friends need to be skipped explicitly.
- elif info.filename in ('IMAGES/system.img',
- 'IMAGES/system.map'):
+ elif filename in ('IMAGES/system.img',
+ 'IMAGES/system.map'):
pass
# Copy images that are not in SECONDARY_PAYLOAD_SKIPPED_IMAGES.
- elif info.filename.startswith(('IMAGES/', 'RADIO/')):
- image_name = os.path.basename(info.filename)
+ elif filename.startswith(('IMAGES/', 'RADIO/')):
+ image_name = os.path.basename(filename)
if image_name not in ['{}.img'.format(partition) for partition in
SECONDARY_PAYLOAD_SKIPPED_IMAGES]:
- common.ZipWrite(target_zip, unzipped_file, arcname=info.filename)
+ common.ZipWrite(target_zip, unzipped_file, arcname=filename)
# Skip copying the postinstall config if requested.
- elif skip_postinstall and info.filename == POSTINSTALL_CONFIG:
+ elif skip_postinstall and filename == POSTINSTALL_CONFIG:
pass
- elif info.filename.startswith('META/'):
+ elif filename.startswith('META/'):
# Remove the unnecessary partitions for secondary images from the
# ab_partitions file.
- if info.filename == AB_PARTITIONS:
+ if filename == AB_PARTITIONS:
with open(unzipped_file) as f:
partition_list = f.read().splitlines()
partition_list = [partition for partition in partition_list if partition
and partition not in SECONDARY_PAYLOAD_SKIPPED_IMAGES]
- common.ZipWriteStr(target_zip, info.filename,
+ common.ZipWriteStr(target_zip, filename,
'\n'.join(partition_list))
# Remove the unnecessary partitions from the dynamic partitions list.
- elif (info.filename == 'META/misc_info.txt' or
- info.filename == DYNAMIC_PARTITION_INFO):
+ elif (filename == 'META/misc_info.txt' or
+ filename == DYNAMIC_PARTITION_INFO):
modified_info = GetInfoForSecondaryImages(unzipped_file)
- common.ZipWriteStr(target_zip, info.filename, modified_info)
+ common.ZipWriteStr(target_zip, filename, modified_info)
else:
- common.ZipWrite(target_zip, unzipped_file, arcname=info.filename)
+ common.ZipWrite(target_zip, unzipped_file, arcname=filename)
common.ZipClose(target_zip)
@@ -994,6 +1003,9 @@
additional_args += ["--enable_zucchini=" +
str(OPTIONS.enable_zucchini).lower()]
+ if OPTIONS.enable_puffdiff is not None:
+ additional_args += ["--enable_puffdiff=" +
+ str(OPTIONS.enable_puffdiff).lower()]
if not ota_utils.IsLz4diffCompatible(source_file, target_file):
logger.warning(
@@ -1193,11 +1205,20 @@
elif o == "--enable_zucchini":
assert a.lower() in ["true", "false"]
OPTIONS.enable_zucchini = a.lower() != "false"
+ elif o == "--enable_puffdiff":
+ assert a.lower() in ["true", "false"]
+ OPTIONS.enable_puffdiff = a.lower() != "false"
elif o == "--enable_lz4diff":
assert a.lower() in ["true", "false"]
OPTIONS.enable_lz4diff = a.lower() != "false"
elif o == "--vabc_compression_param":
+ words = a.split(",")
+ assert len(words) >= 1 and len(words) <= 2
OPTIONS.vabc_compression_param = a.lower()
+ if len(words) == 2:
+ if not words[1].isdigit():
+ raise ValueError("Cannot parse value %r for option $COMPRESSION_LEVEL - only "
+ "integers are allowed." % words[1])
elif o == "--security_patch_level":
OPTIONS.security_patch_level = a
elif o in ("--max_threads"):
@@ -1254,6 +1275,7 @@
"force_minor_version=",
"compressor_types=",
"enable_zucchini=",
+ "enable_puffdiff=",
"enable_lz4diff=",
"vabc_compression_param=",
"security_patch_level=",
diff --git a/tools/releasetools/sign_target_files_apks.py b/tools/releasetools/sign_target_files_apks.py
index 8291448..2b45825 100755
--- a/tools/releasetools/sign_target_files_apks.py
+++ b/tools/releasetools/sign_target_files_apks.py
@@ -1234,11 +1234,11 @@
vendor_misc_info["no_recovery"] = "true" # recovery
vendor_misc_info["avb_enable"] = "false" # vbmeta
- vendor_misc_info["board_bpt_enable"] = "false" # partition-table
vendor_misc_info["has_dtbo"] = "false" # dtbo
vendor_misc_info["has_pvmfw"] = "false" # pvmfw
- vendor_misc_info["avb_custom_images_partition_list"] = "" # custom images
+ vendor_misc_info["avb_custom_images_partition_list"] = "" # avb custom images
vendor_misc_info["avb_building_vbmeta_image"] = "false" # skip building vbmeta
+ vendor_misc_info["custom_images_partition_list"] = "" # custom images
vendor_misc_info["use_dynamic_partitions"] = "false" # super_empty
vendor_misc_info["build_super_partition"] = "false" # super split
vendor_misc_info["avb_vbmeta_system"] = "" # skip building vbmeta_system
diff --git a/tools/sbom/Android.bp b/tools/sbom/Android.bp
index 4837dde..519251e 100644
--- a/tools/sbom/Android.bp
+++ b/tools/sbom/Android.bp
@@ -53,5 +53,27 @@
libs: [
"sbom_lib",
],
+ version: {
+ py3: {
+ embedded_launcher: true,
+ },
+ },
+ test_suites: ["general-tests"],
+}
+
+python_test_host {
+ name: "sbom_data_test",
+ main: "sbom_data_test.py",
+ srcs: [
+ "sbom_data_test.py",
+ ],
+ libs: [
+ "sbom_lib",
+ ],
+ version: {
+ py3: {
+ embedded_launcher: true,
+ },
+ },
test_suites: ["general-tests"],
}
diff --git a/tools/sbom/sbom_data.py b/tools/sbom/sbom_data.py
index ea38e36..71f8660 100644
--- a/tools/sbom/sbom_data.py
+++ b/tools/sbom/sbom_data.py
@@ -133,7 +133,7 @@
checksums = []
for file in self.files:
if file.id in package.file_ids:
- checksums.append(file.checksum)
+ checksums.append(file.checksum.split(': ')[1])
checksums.sort()
h = hashlib.sha1()
h.update(''.join(checksums).encode(encoding='utf-8'))
diff --git a/tools/sbom/sbom_data_test.py b/tools/sbom/sbom_data_test.py
new file mode 100644
index 0000000..69bc9d2
--- /dev/null
+++ b/tools/sbom/sbom_data_test.py
@@ -0,0 +1,139 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2023 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.
+
+import hashlib
+import unittest
+import sbom_data
+
+BUILD_FINGER_PRINT = 'build_finger_print'
+SUPPLIER_GOOGLE = 'Organization: Google'
+SUPPLIER_UPSTREAM = 'Organization: upstream'
+
+SPDXID_PREBUILT_PACKAGE1 = 'SPDXRef-PREBUILT-package1'
+SPDXID_SOURCE_PACKAGE1 = 'SPDXRef-SOURCE-package1'
+SPDXID_UPSTREAM_PACKAGE1 = 'SPDXRef-UPSTREAM-package1'
+
+SPDXID_FILE1 = 'SPDXRef-file1'
+SPDXID_FILE2 = 'SPDXRef-file2'
+SPDXID_FILE3 = 'SPDXRef-file3'
+SPDXID_FILE4 = 'SPDXRef-file4'
+
+
+class SBOMDataTest(unittest.TestCase):
+
+ def setUp(self):
+ # SBOM of a product
+ self.sbom_doc = sbom_data.Document(name='test doc',
+ namespace='http://www.google.com/sbom/spdx/android',
+ creators=[SUPPLIER_GOOGLE],
+ created='2023-03-31T22:17:58Z',
+ describes=sbom_data.SPDXID_PRODUCT)
+ self.sbom_doc.add_external_ref(
+ sbom_data.DocumentExternalReference(id='DocumentRef-external_doc_ref',
+ uri='external_doc_uri',
+ checksum='SHA1: 1234567890'))
+ self.sbom_doc.add_package(
+ sbom_data.Package(id=sbom_data.SPDXID_PRODUCT,
+ name=sbom_data.PACKAGE_NAME_PRODUCT,
+ download_location=sbom_data.VALUE_NONE,
+ supplier=SUPPLIER_GOOGLE,
+ version=BUILD_FINGER_PRINT,
+ files_analyzed=True,
+ verification_code='',
+ file_ids=[SPDXID_FILE1, SPDXID_FILE2, SPDXID_FILE3, SPDXID_FILE4]))
+
+ self.sbom_doc.add_package(
+ sbom_data.Package(id=sbom_data.SPDXID_PLATFORM,
+ name=sbom_data.PACKAGE_NAME_PLATFORM,
+ download_location=sbom_data.VALUE_NONE,
+ supplier=SUPPLIER_GOOGLE,
+ version=BUILD_FINGER_PRINT,
+ ))
+
+ self.sbom_doc.add_package(
+ sbom_data.Package(id=SPDXID_PREBUILT_PACKAGE1,
+ name='Prebuilt package1',
+ download_location=sbom_data.VALUE_NONE,
+ supplier=SUPPLIER_GOOGLE,
+ version=BUILD_FINGER_PRINT,
+ ))
+
+ self.sbom_doc.add_package(
+ sbom_data.Package(id=SPDXID_SOURCE_PACKAGE1,
+ name='Source package1',
+ download_location=sbom_data.VALUE_NONE,
+ supplier=SUPPLIER_GOOGLE,
+ version=BUILD_FINGER_PRINT,
+ external_refs=[sbom_data.PackageExternalRef(
+ category=sbom_data.PackageExternalRefCategory.SECURITY,
+ type=sbom_data.PackageExternalRefType.cpe22Type,
+ locator='cpe:/a:jsoncpp_project:jsoncpp:1.9.4')]
+ ))
+
+ self.sbom_doc.add_package(
+ sbom_data.Package(id=SPDXID_UPSTREAM_PACKAGE1,
+ name='Upstream package1',
+ supplier=SUPPLIER_UPSTREAM,
+ version='1.1',
+ ))
+
+ self.sbom_doc.add_relationship(sbom_data.Relationship(id1=SPDXID_SOURCE_PACKAGE1,
+ relationship=sbom_data.RelationshipType.VARIANT_OF,
+ id2=SPDXID_UPSTREAM_PACKAGE1))
+
+ self.sbom_doc.files.append(
+ sbom_data.File(id=SPDXID_FILE1, name='/bin/file1',
+ checksum='SHA1: 356a192b7913b04c54574d18c28d46e6395428ab')) # sha1 hash of 1
+ self.sbom_doc.files.append(
+ sbom_data.File(id=SPDXID_FILE2, name='/bin/file2',
+ checksum='SHA1: da4b9237bacccdf19c0760cab7aec4a8359010b0')) # sha1 hash of 2
+ self.sbom_doc.files.append(
+ sbom_data.File(id=SPDXID_FILE3, name='/bin/file3',
+ checksum='SHA1: 77de68daecd823babbb58edb1c8e14d7106e83bb')) # sha1 hash of 3
+ self.sbom_doc.files.append(
+ sbom_data.File(id=SPDXID_FILE4, name='file4.a',
+ checksum='SHA1: 1b6453892473a467d07372d45eb05abc2031647a')) # sha1 of 4
+
+ self.sbom_doc.add_relationship(sbom_data.Relationship(id1=SPDXID_FILE1,
+ relationship=sbom_data.RelationshipType.GENERATED_FROM,
+ id2=sbom_data.SPDXID_PLATFORM))
+ self.sbom_doc.add_relationship(sbom_data.Relationship(id1=SPDXID_FILE2,
+ relationship=sbom_data.RelationshipType.GENERATED_FROM,
+ id2=SPDXID_PREBUILT_PACKAGE1))
+ self.sbom_doc.add_relationship(sbom_data.Relationship(id1=SPDXID_FILE3,
+ relationship=sbom_data.RelationshipType.GENERATED_FROM,
+ id2=SPDXID_SOURCE_PACKAGE1
+ ))
+ self.sbom_doc.add_relationship(sbom_data.Relationship(id1=SPDXID_FILE1,
+ relationship=sbom_data.RelationshipType.STATIC_LINK,
+ id2=SPDXID_FILE4
+ ))
+
+ def test_package_verification_code(self):
+ checksums = []
+ for file in self.sbom_doc.files:
+ checksums.append(file.checksum.split(': ')[1])
+ checksums.sort()
+ h = hashlib.sha1()
+ h.update(''.join(checksums).encode(encoding='utf-8'))
+ expected_package_verification_code = h.hexdigest()
+
+ self.sbom_doc.generate_packages_verification_code()
+ self.assertEqual(expected_package_verification_code, self.sbom_doc.packages[0].verification_code)
+
+
+if __name__ == '__main__':
+ unittest.main(verbosity=2)