Merge "Delete deps-license target."
diff --git a/core/Makefile b/core/Makefile
index 6926b26..35d744a 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -2830,6 +2830,41 @@
endef
# -----------------------------------------------------------------
+# custom images
+INSTALLED_CUSTOMIMAGES_TARGET :=
+
+ifneq ($(strip $(BOARD_CUSTOMIMAGES_PARTITION_LIST)),)
+INTERNAL_AVB_CUSTOMIMAGES_SIGNING_ARGS :=
+
+# Sign custom image.
+# $(1): the prebuilt custom image.
+# $(2): the mount point of the prebuilt custom image.
+# $(3): the signed custom image target.
+define sign_custom_image
+$(3): $(1) $(INTERNAL_USERIMAGES_DEPS)
+ @echo Target custom image: $(3)
+ mkdir -p $(dir $(3))
+ cp $(1) $(3)
+ifeq ($(BOARD_AVB_ENABLE),true)
+ PATH=$(INTERNAL_USERIMAGES_BINARY_PATHS):$$$$PATH \
+ $(AVBTOOL) add_hashtree_footer \
+ --image $(3) \
+ --key $(BOARD_AVB_$(call to-upper,$(2))_KEY_PATH) \
+ --algorithm $(BOARD_AVB_$(call to-upper,$(2))_ALGORITHM) \
+ --partition_size $(BOARD_AVB_$(call to-upper,$(2))_PARTITION_SIZE) \
+ --partition_name $(2) \
+ $(INTERNAL_AVB_CUSTOMIMAGES_SIGNING_ARGS) \
+ $(BOARD_AVB_$(call to-upper,$(2))_ADD_HASHTREE_FOOTER_ARGS)
+endif
+INSTALLED_CUSTOMIMAGES_TARGET += $(3)
+endef
+
+$(foreach partition,$(BOARD_CUSTOMIMAGES_PARTITION_LIST), \
+ $(foreach image,$(BOARD_AVB_$(call to-upper,$(partition))_IMAGE_LIST), \
+ $(eval $(call sign_custom_image,$(image),$(partition),$(PRODUCT_OUT)/$(notdir $(image))))))
+endif
+
+# -----------------------------------------------------------------
# vbmeta image
ifeq ($(BOARD_AVB_ENABLE),true)
@@ -3000,6 +3035,18 @@
--include_descriptors_from_image $(call images-for-partitions,$(1)))))
endef
+# Checks and sets build variables for a custom chained partition to include it into vbmeta.img.
+# $(1): the custom partition to enable AVB chain.
+define check-and-set-custom-avb-chain-args
+$(eval part := $(1))
+$(eval PART=$(call to-upper,$(part)))
+$(eval _rollback_index_location := BOARD_AVB_$(PART)_ROLLBACK_INDEX_LOCATION)
+$(if $($(_rollback_index_location)),,$(error $(_rollback_index_location) is not defined))
+
+INTERNAL_AVB_MAKE_VBMETA_IMAGE_ARGS += \
+ --chain_partition $(part):$($(_rollback_index_location)):$(AVB_CHAIN_KEY_DIR)/$(part).avbpubkey
+endef
+
ifdef INSTALLED_BOOTIMAGE_TARGET
$(eval $(call check-and-set-avb-args,boot))
endif
@@ -3043,6 +3090,11 @@
$(eval $(call check-and-set-avb-args,vbmeta_vendor))
endif
+ifneq ($(strip $(BOARD_CUSTOMIMAGES_PARTITION_LIST)),)
+$(foreach partition,$(BOARD_CUSTOMIMAGES_PARTITION_LIST), \
+ $(eval $(call check-and-set-custom-avb-chain-args,$(partition))))
+endif
+
# Add kernel cmdline descriptor for kernel to mount system.img as root with
# dm-verity. This works when system.img is either chained or not-chained:
# - chained: The --setup_as_rootfs_from_kernel option will add dm-verity kernel
@@ -3113,6 +3165,10 @@
$(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), \
+ $(AVBTOOL) extract_public_key --key $(BOARD_AVB_$(call to-upper,$(partition))_KEY_PATH) \
+ --output $(1)/$(partition).avbpubkey;))
endef
# Builds a chained VBMeta image. This VBMeta image will contain the descriptors for the partitions
@@ -3180,6 +3236,7 @@
$(INSTALLED_SYSTEM_EXTIMAGE_TARGET) \
$(INSTALLED_ODMIMAGE_TARGET) \
$(INSTALLED_DTBOIMAGE_TARGET) \
+ $(INSTALLED_CUSTOMIMAGES_TARGET) \
$(INSTALLED_RECOVERYIMAGE_TARGET) \
$(INSTALLED_VBMETA_SYSTEMIMAGE_TARGET) \
$(INSTALLED_VBMETA_VENDORIMAGE_TARGET) \
@@ -3739,6 +3796,16 @@
$(hide) echo "avb_recovery_algorithm=$(BOARD_AVB_RECOVERY_ALGORITHM)" >> $@
$(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), \
+ 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
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)" >> $@
@@ -3972,6 +4039,7 @@
$(INSTALLED_VBMETAIMAGE_TARGET) \
$(INSTALLED_ODMIMAGE_TARGET) \
$(INSTALLED_DTBOIMAGE_TARGET) \
+ $(INSTALLED_CUSTOMIMAGES_TARGET) \
$(INTERNAL_SYSTEMOTHERIMAGE_FILES) \
$(INSTALLED_ANDROID_INFO_TXT_TARGET) \
$(INSTALLED_KERNEL_TARGET) \
@@ -4216,6 +4284,11 @@
$(hide) mkdir -p $(zip_root)/PREBUILT_IMAGES
$(hide) cp $(INSTALLED_DTBOIMAGE_TARGET) $(zip_root)/PREBUILT_IMAGES/
endif # BOARD_PREBUILT_DTBOIMAGE
+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/;))
+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
@# INSTALLED_RADIOIMAGE_TARGET.
diff --git a/tools/releasetools/add_img_to_target_files.py b/tools/releasetools/add_img_to_target_files.py
index 70ea967..490b44a 100755
--- a/tools/releasetools/add_img_to_target_files.py
+++ b/tools/releasetools/add_img_to_target_files.py
@@ -60,6 +60,7 @@
import common
import rangelib
import sparse_img
+import verity_utils
if sys.hexversion < 0x02070000:
print("Python 2.7 or newer is required.", file=sys.stderr)
@@ -312,6 +313,56 @@
img.Write()
return img.name
+def AddCustomImages(output_zip, partition_name):
+ """Adds and signs custom images in IMAGES/.
+
+ Args:
+ output_zip: The output zip file (needs to be already open), or None to
+ write images to OPTIONS.input_tmp/.
+
+ 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.
+
+ Raises:
+ AssertionError: If image can't be found.
+ """
+
+ partition_size = OPTIONS.info_dict.get(
+ "avb_{}_partition_size".format(partition_name))
+ 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))
+
+ 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():
+ custom_image = OutputFile(output_zip, OPTIONS.input_tmp, "IMAGES", img_name)
+ if os.path.exists(custom_image.name):
+ continue
+
+ custom_image_prebuilt_path = os.path.join(
+ OPTIONS.input_tmp, "PREBUILT_IMAGES", img_name)
+ assert os.path.exists(custom_image_prebuilt_path), \
+ "Failed to find %s at %s" % (img_name, custom_image_prebuilt_path)
+
+ shutil.copy(custom_image_prebuilt_path, custom_image.name)
+
+ if builder is not None:
+ builder.Build(custom_image.name)
+
+ custom_image.Write()
+
+ default = os.path.join(OPTIONS.input_tmp, "IMAGES", partition_name + ".img")
+ assert os.path.exists(default), \
+ "There should be one %s.img" % (partition_name)
+ return default
+
def CreateImage(input_dir, info_dict, what, output_file, block_list=None):
logger.info("creating %s.img...", what)
@@ -411,8 +462,9 @@
Args:
output_zip: The output zip file, which needs to be already open.
partitions: A dict that's keyed by partition names with image paths as
- values. Only valid partition names are accepted, as listed in
- common.AVB_PARTITIONS.
+ values. Only valid partition names are accepted, as partitions listed
+ in common.AVB_PARTITIONS and custom partitions listed in
+ OPTIONS.info_dict.get("avb_custom_images_partition_list")
name: Name of the VBMeta partition, e.g. 'vbmeta', 'vbmeta_system'.
needed_partitions: Partitions whose descriptors should be included into the
generated VBMeta image.
@@ -831,11 +883,20 @@
banner("dtbo")
partitions['dtbo'] = AddDtbo(output_zip)
+ # Custom images.
+ custom_partitions = OPTIONS.info_dict.get(
+ "avb_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)
+
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.
- vbmeta_partitions = common.AVB_PARTITIONS[:]
+ # Currently custom_partitions are all chained to VBMeta image.
+ vbmeta_partitions = common.AVB_PARTITIONS[:] + tuple(custom_partitions)
vbmeta_system = OPTIONS.info_dict.get("avb_vbmeta_system", "").strip()
if vbmeta_system:
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index 96f93a8..93e14e5 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -1132,8 +1132,9 @@
Args:
image_path: The output path for the new VBMeta image.
partitions: A dict that's keyed by partition names with image paths as
- values. Only valid partition names are accepted, as listed in
- common.AVB_PARTITIONS.
+ values. Only valid partition names are accepted, as partitions listed
+ in common.AVB_PARTITIONS and custom partitions listed in
+ OPTIONS.info_dict.get("avb_custom_images_partition_list")
name: Name of the VBMeta partition, e.g. 'vbmeta', 'vbmeta_system'.
needed_partitions: Partitions whose descriptors should be included into the
generated VBMeta image.
@@ -1145,11 +1146,15 @@
cmd = [avbtool, "make_vbmeta_image", "--output", image_path]
AppendAVBSigningArgs(cmd, name)
+ custom_partitions = OPTIONS.info_dict.get(
+ "avb_custom_images_partition_list", "").strip().split()
+
for partition, path in partitions.items():
if partition not in needed_partitions:
continue
assert (partition in AVB_PARTITIONS or
- partition in AVB_VBMETA_PARTITIONS), \
+ partition in AVB_VBMETA_PARTITIONS or
+ partition in custom_partitions), \
'Unknown partition: {}'.format(partition)
assert os.path.exists(path), \
'Failed to find {} for {}'.format(path, partition)
diff --git a/tools/releasetools/ota_from_target_files.py b/tools/releasetools/ota_from_target_files.py
index 16b278a..b753414 100755
--- a/tools/releasetools/ota_from_target_files.py
+++ b/tools/releasetools/ota_from_target_files.py
@@ -189,6 +189,13 @@
--payload_signer_key_size <key_size>
Deprecated. Use the '--payload_signer_maximum_signature_size' instead.
+ --boot_variable_file <path>
+ A file that contains the possible values of ro.boot.* properties. It's
+ used to calculate the possible runtime fingerprints when some
+ ro.product.* properties are overridden by the 'import' statement.
+ The file expects one property per line, and each line has the following
+ format: 'prop_name=value1,value2'. e.g. 'ro.boot.product.sku=std,pro'
+
--skip_postinstall
Skip the postinstall hooks when generating an A/B OTA package (default:
False). Note that this discards ALL the hooks, including non-optional
@@ -257,8 +264,8 @@
OPTIONS.skip_compatibility_check = False
OPTIONS.output_metadata_path = None
OPTIONS.disable_fec_computation = False
-OPTIONS.boot_variable_values = None
OPTIONS.force_non_ab = False
+OPTIONS.boot_variable_file = None
METADATA_NAME = 'META-INF/com/android/metadata'
@@ -931,13 +938,23 @@
assert isinstance(target_info, common.BuildInfo)
assert source_info is None or isinstance(source_info, common.BuildInfo)
+ separator = '|'
+
+ boot_variable_values = {}
+ if OPTIONS.boot_variable_file:
+ d = common.LoadDictionaryFromFile(OPTIONS.boot_variable_file)
+ for key, values in d.items():
+ boot_variable_values[key] = [val.strip() for val in values.split(',')]
+
+ post_build_devices, post_build_fingerprints = \
+ CalculateRuntimeDevicesAndFingerprints(target_info, boot_variable_values)
metadata = {
- 'post-build' : target_info.fingerprint,
- 'post-build-incremental' : target_info.GetBuildProp(
+ 'post-build': separator.join(sorted(post_build_fingerprints)),
+ 'post-build-incremental': target_info.GetBuildProp(
'ro.build.version.incremental'),
- 'post-sdk-level' : target_info.GetBuildProp(
+ 'post-sdk-level': target_info.GetBuildProp(
'ro.build.version.sdk'),
- 'post-security-patch-level' : target_info.GetBuildProp(
+ 'post-security-patch-level': target_info.GetBuildProp(
'ro.build.version.security_patch'),
}
@@ -955,12 +972,15 @@
is_incremental = source_info is not None
if is_incremental:
- metadata['pre-build'] = source_info.fingerprint
+ pre_build_devices, pre_build_fingerprints = \
+ CalculateRuntimeDevicesAndFingerprints(source_info,
+ boot_variable_values)
+ metadata['pre-build'] = separator.join(sorted(pre_build_fingerprints))
metadata['pre-build-incremental'] = source_info.GetBuildProp(
'ro.build.version.incremental')
- metadata['pre-device'] = source_info.device
+ metadata['pre-device'] = separator.join(sorted(pre_build_devices))
else:
- metadata['pre-device'] = target_info.device
+ metadata['pre-device'] = separator.join(sorted(post_build_devices))
# Use the actual post-timestamp, even for a downgrade case.
metadata['post-timestamp'] = target_info.GetBuildProp('ro.build.date.utc')
@@ -1972,24 +1992,24 @@
output_file)
-def CalculateRuntimeFingerprints():
- """Returns a set of runtime fingerprints based on the boot variables."""
+def CalculateRuntimeDevicesAndFingerprints(build_info, boot_variable_values):
+ """Returns a tuple of sets for runtime devices and fingerprints"""
- build_info = common.BuildInfo(OPTIONS.info_dict, OPTIONS.oem_dicts)
+ device_names = {build_info.device}
fingerprints = {build_info.fingerprint}
- if not OPTIONS.boot_variable_values:
- return fingerprints
+ if not boot_variable_values:
+ return device_names, fingerprints
# Calculate all possible combinations of the values for the boot variables.
- keys = OPTIONS.boot_variable_values.keys()
- value_list = OPTIONS.boot_variable_values.values()
+ keys = boot_variable_values.keys()
+ value_list = boot_variable_values.values()
combinations = [dict(zip(keys, values))
for values in itertools.product(*value_list)]
for placeholder_values in combinations:
# Reload the info_dict as some build properties may change their values
# based on the value of ro.boot* properties.
- info_dict = copy.deepcopy(OPTIONS.info_dict)
+ info_dict = copy.deepcopy(build_info.info_dict)
for partition in common.PARTITIONS_WITH_CARE_MAP:
partition_prop_key = "{}.build.prop".format(partition)
old_props = info_dict[partition_prop_key]
@@ -1997,9 +2017,10 @@
old_props.input_file, partition, placeholder_values)
info_dict["build.prop"] = info_dict["system.build.prop"]
- build_info = common.BuildInfo(info_dict, OPTIONS.oem_dicts)
- fingerprints.add(build_info.fingerprint)
- return fingerprints
+ new_build_info = common.BuildInfo(info_dict, build_info.oem_dicts)
+ device_names.add(new_build_info.device)
+ fingerprints.add(new_build_info.fingerprint)
+ return device_names, fingerprints
def main(argv):
@@ -2077,6 +2098,8 @@
OPTIONS.disable_fec_computation = True
elif o == "--force_non_ab":
OPTIONS.force_non_ab = True
+ elif o == "--boot_variable_file":
+ OPTIONS.boot_variable_file = a
else:
return False
return True
@@ -2114,6 +2137,7 @@
"output_metadata_path=",
"disable_fec_computation",
"force_non_ab",
+ "boot_variable_file=",
], extra_option_handler=option_handler)
if len(args) != 2:
diff --git a/tools/releasetools/sign_target_files_apks.py b/tools/releasetools/sign_target_files_apks.py
index 52cd9a8..52b7889 100755
--- a/tools/releasetools/sign_target_files_apks.py
+++ b/tools/releasetools/sign_target_files_apks.py
@@ -112,6 +112,17 @@
(e.g. "--signing_helper /path/to/helper"). The args will be appended to
the existing ones in info dict.
+ --avb_extra_custom_image_key <partition=key>
+ --avb_extra_custom_image_algorithm <partition=algorithm>
+ Use the specified algorithm (e.g. SHA256_RSA4096) and the key to AVB-sign
+ the specified custom images mounted on the partition. Otherwise it uses
+ the existing values in info dict.
+
+ --avb_extra_custom_image_extra_args <partition=extra_args>
+ Specify any additional args that are needed to AVB-sign the custom images
+ mounted on the partition (e.g. "--signing_helper /path/to/helper"). The
+ args will be appended to the existing ones in info dict.
+
--android_jar_path <path>
Path to the android.jar to repack the apex file.
"""
@@ -956,12 +967,20 @@
if extra_args:
print('Setting extra AVB signing args for %s to "%s"' % (
partition, extra_args))
- args_key = AVB_FOOTER_ARGS_BY_PARTITION[partition]
+ if partition in AVB_FOOTER_ARGS_BY_PARTITION:
+ args_key = AVB_FOOTER_ARGS_BY_PARTITION[partition]
+ else:
+ # custom partition
+ args_key = "avb_{}_add_hashtree_footer_args".format(partition)
misc_info[args_key] = (misc_info.get(args_key, '') + ' ' + extra_args)
for partition in AVB_FOOTER_ARGS_BY_PARTITION:
ReplaceAvbPartitionSigningKey(partition)
+ for custom_partition in misc_info.get(
+ "avb_custom_images_partition_list", "").strip().split():
+ ReplaceAvbPartitionSigningKey(custom_partition)
+
def RewriteAvbProps(misc_info):
"""Rewrites the props in AVB signing args."""
@@ -1208,6 +1227,15 @@
OPTIONS.avb_extra_args['vbmeta_vendor'] = a
elif o == "--avb_apex_extra_args":
OPTIONS.avb_extra_args['apex'] = a
+ elif o == "--avb_extra_custom_image_key":
+ partition, key = a.split("=")
+ OPTIONS.avb_keys[partition] = key
+ elif o == "--avb_extra_custom_image_algorithm":
+ partition, algorithm = a.split("=")
+ OPTIONS.avb_algorithms[partition] = algorithm
+ elif o == "--avb_extra_custom_image_extra_args":
+ partition, extra_args = a.split("=")
+ OPTIONS.avb_extra_args[partition] = extra_args
else:
return False
return True
@@ -1252,6 +1280,9 @@
"avb_vbmeta_vendor_algorithm=",
"avb_vbmeta_vendor_key=",
"avb_vbmeta_vendor_extra_args=",
+ "avb_extra_custom_image_key=",
+ "avb_extra_custom_image_algorithm=",
+ "avb_extra_custom_image_extra_args=",
],
extra_option_handler=option_handler)
diff --git a/tools/releasetools/test_ota_from_target_files.py b/tools/releasetools/test_ota_from_target_files.py
index 4077d06..7783f96 100644
--- a/tools/releasetools/test_ota_from_target_files.py
+++ b/tools/releasetools/test_ota_from_target_files.py
@@ -27,7 +27,7 @@
GetTargetFilesZipWithoutPostinstallConfig, NonAbOtaPropertyFiles,
Payload, PayloadSigner, POSTINSTALL_CONFIG, PropertyFiles,
StreamingPropertyFiles, WriteFingerprintAssertion,
- CalculateRuntimeFingerprints)
+ CalculateRuntimeDevicesAndFingerprints)
def construct_target_files(secondary=False):
@@ -1334,6 +1334,9 @@
'ro.build.version.incremental=version-incremental',
'ro.build.type=build-type',
'ro.build.tags=build-tags',
+ 'ro.build.version.sdk=30',
+ 'ro.build.version.security_patch=2020',
+ 'ro.build.date.utc=12345678'
]
VENDOR_BUILD_PROP = [
@@ -1345,11 +1348,12 @@
def setUp(self):
common.OPTIONS.oem_dicts = None
self.test_dir = common.MakeTempDir()
- self.writeFiles({'META/misc_info.txt': '\n'.join(self.MISC_INFO)})
+ self.writeFiles({'META/misc_info.txt': '\n'.join(self.MISC_INFO)},
+ self.test_dir)
- def writeFiles(self, contents_dict):
+ def writeFiles(self, contents_dict, out_dir):
for path, content in contents_dict.items():
- abs_path = os.path.join(self.test_dir, path)
+ abs_path = os.path.join(out_dir, path)
dir_name = os.path.dirname(abs_path)
if not os.path.exists(dir_name):
os.makedirs(dir_name)
@@ -1371,12 +1375,14 @@
self.writeFiles({
'SYSTEM/build.prop': '\n'.join(build_prop),
'VENDOR/build.prop': '\n'.join(self.VENDOR_BUILD_PROP),
- })
- common.OPTIONS.info_dict = common.LoadInfoDict(self.test_dir)
+ }, self.test_dir)
- self.assertEqual({
- self.constructFingerprint('product-brand/product-name/product-device')
- }, CalculateRuntimeFingerprints())
+ build_info = common.BuildInfo(common.LoadInfoDict(self.test_dir))
+ expected = ({'product-device'},
+ {self.constructFingerprint(
+ 'product-brand/product-name/product-device')})
+ self.assertEqual(expected,
+ CalculateRuntimeDevicesAndFingerprints(build_info, {}))
def test_CalculatePossibleFingerprints_single_override(self):
vendor_build_prop = copy.deepcopy(self.VENDOR_BUILD_PROP)
@@ -1390,20 +1396,22 @@
'ro.product.vendor.name=vendor-product-std',
'VENDOR/etc/build_pro.prop':
'ro.product.vendor.name=vendor-product-pro',
- })
- common.OPTIONS.info_dict = common.LoadInfoDict(self.test_dir)
- common.OPTIONS.boot_variable_values = {
- 'ro.boot.sku_name': ['std', 'pro']
- }
+ }, self.test_dir)
- self.assertEqual({
+ build_info = common.BuildInfo(common.LoadInfoDict(self.test_dir))
+ boot_variable_values = {'ro.boot.sku_name': ['std', 'pro']}
+
+ expected = ({'vendor-product-device'}, {
self.constructFingerprint(
'vendor-product-brand/vendor-product-name/vendor-product-device'),
self.constructFingerprint(
'vendor-product-brand/vendor-product-std/vendor-product-device'),
self.constructFingerprint(
'vendor-product-brand/vendor-product-pro/vendor-product-device'),
- }, CalculateRuntimeFingerprints())
+ })
+ self.assertEqual(
+ expected, CalculateRuntimeDevicesAndFingerprints(
+ build_info, boot_variable_values))
def test_CalculatePossibleFingerprints_multiple_overrides(self):
vendor_build_prop = copy.deepcopy(self.VENDOR_BUILD_PROP)
@@ -1422,14 +1430,17 @@
'ro.product.vendor.name=vendor-product-pro',
'VENDOR/etc/build_product2.prop':
'ro.product.vendor.device=vendor-device-product2',
- })
- common.OPTIONS.info_dict = common.LoadInfoDict(self.test_dir)
- common.OPTIONS.boot_variable_values = {
+ }, self.test_dir)
+
+ build_info = common.BuildInfo(common.LoadInfoDict(self.test_dir))
+ boot_variable_values = {
'ro.boot.sku_name': ['std', 'pro'],
'ro.boot.device_name': ['product1', 'product2'],
}
- self.assertEqual({
+ expected_devices = {'vendor-product-device', 'vendor-device-product1',
+ 'vendor-device-product2'}
+ expected_fingerprints = {
self.constructFingerprint(
'vendor-product-brand/vendor-product-name/vendor-product-device'),
self.constructFingerprint(
@@ -1439,5 +1450,108 @@
self.constructFingerprint(
'vendor-product-brand/vendor-product-std/vendor-device-product2'),
self.constructFingerprint(
- 'vendor-product-brand/vendor-product-pro/vendor-device-product2'),
- }, CalculateRuntimeFingerprints())
+ 'vendor-product-brand/vendor-product-pro/vendor-device-product2')
+ }
+ self.assertEqual((expected_devices, expected_fingerprints),
+ CalculateRuntimeDevicesAndFingerprints(
+ build_info, boot_variable_values))
+
+ def test_GetPackageMetadata_full_package(self):
+ vendor_build_prop = copy.deepcopy(self.VENDOR_BUILD_PROP)
+ vendor_build_prop.extend([
+ 'import /vendor/etc/build_${ro.boot.sku_name}.prop',
+ ])
+ self.writeFiles({
+ 'SYSTEM/build.prop': '\n'.join(self.BUILD_PROP),
+ 'VENDOR/build.prop': '\n'.join(vendor_build_prop),
+ 'VENDOR/etc/build_std.prop':
+ 'ro.product.vendor.name=vendor-product-std',
+ 'VENDOR/etc/build_pro.prop':
+ 'ro.product.vendor.name=vendor-product-pro',
+ }, self.test_dir)
+
+ common.OPTIONS.boot_variable_file = common.MakeTempFile()
+ with open(common.OPTIONS.boot_variable_file, 'w') as f:
+ f.write('ro.boot.sku_name=std,pro')
+
+ build_info = common.BuildInfo(common.LoadInfoDict(self.test_dir))
+ metadata = GetPackageMetadata(build_info)
+ self.assertEqual('vendor-product-device', metadata['pre-device'])
+ fingerprints = [
+ self.constructFingerprint(
+ 'vendor-product-brand/vendor-product-name/vendor-product-device'),
+ self.constructFingerprint(
+ 'vendor-product-brand/vendor-product-pro/vendor-product-device'),
+ self.constructFingerprint(
+ 'vendor-product-brand/vendor-product-std/vendor-product-device'),
+ ]
+ self.assertEqual('|'.join(fingerprints), metadata['post-build'])
+
+ def test_GetPackageMetadata_incremental_package(self):
+ vendor_build_prop = copy.deepcopy(self.VENDOR_BUILD_PROP)
+ vendor_build_prop.extend([
+ 'import /vendor/etc/build_${ro.boot.sku_name}.prop',
+ ])
+ self.writeFiles({
+ 'SYSTEM/build.prop': '\n'.join(self.BUILD_PROP),
+ 'VENDOR/build.prop': '\n'.join(vendor_build_prop),
+ 'VENDOR/etc/build_std.prop':
+ 'ro.product.vendor.device=vendor-device-std',
+ 'VENDOR/etc/build_pro.prop':
+ 'ro.product.vendor.device=vendor-device-pro',
+ }, self.test_dir)
+
+ common.OPTIONS.boot_variable_file = common.MakeTempFile()
+ with open(common.OPTIONS.boot_variable_file, 'w') as f:
+ f.write('ro.boot.sku_name=std,pro')
+
+ source_dir = common.MakeTempDir()
+ source_build_prop = [
+ 'ro.build.version.release=source-version-release',
+ 'ro.build.id=source-build-id',
+ 'ro.build.version.incremental=source-version-incremental',
+ 'ro.build.type=build-type',
+ 'ro.build.tags=build-tags',
+ 'ro.build.version.sdk=29',
+ 'ro.build.version.security_patch=2020',
+ 'ro.build.date.utc=12340000'
+ ]
+ self.writeFiles({
+ 'META/misc_info.txt': '\n'.join(self.MISC_INFO),
+ 'SYSTEM/build.prop': '\n'.join(source_build_prop),
+ 'VENDOR/build.prop': '\n'.join(vendor_build_prop),
+ 'VENDOR/etc/build_std.prop':
+ 'ro.product.vendor.device=vendor-device-std',
+ 'VENDOR/etc/build_pro.prop':
+ 'ro.product.vendor.device=vendor-device-pro',
+ }, source_dir)
+ common.OPTIONS.incremental_source = source_dir
+
+ target_info = common.BuildInfo(common.LoadInfoDict(self.test_dir))
+ source_info = common.BuildInfo(common.LoadInfoDict(source_dir))
+
+ metadata = GetPackageMetadata(target_info, source_info)
+ self.assertEqual(
+ 'vendor-device-pro|vendor-device-std|vendor-product-device',
+ metadata['pre-device'])
+ suffix = ':source-version-release/source-build-id/' \
+ 'source-version-incremental:build-type/build-tags'
+ pre_fingerprints = [
+ 'vendor-product-brand/vendor-product-name/vendor-device-pro'
+ '{}'.format(suffix),
+ 'vendor-product-brand/vendor-product-name/vendor-device-std'
+ '{}'.format(suffix),
+ 'vendor-product-brand/vendor-product-name/vendor-product-device'
+ '{}'.format(suffix),
+ ]
+ self.assertEqual('|'.join(pre_fingerprints), metadata['pre-build'])
+
+ post_fingerprints = [
+ self.constructFingerprint(
+ 'vendor-product-brand/vendor-product-name/vendor-device-pro'),
+ self.constructFingerprint(
+ 'vendor-product-brand/vendor-product-name/vendor-device-std'),
+ self.constructFingerprint(
+ 'vendor-product-brand/vendor-product-name/vendor-product-device'),
+ ]
+ self.assertEqual('|'.join(post_fingerprints), metadata['post-build'])
diff --git a/tools/releasetools/validate_target_files.py b/tools/releasetools/validate_target_files.py
index 1b918cc..69be511 100755
--- a/tools/releasetools/validate_target_files.py
+++ b/tools/releasetools/validate_target_files.py
@@ -352,8 +352,13 @@
cmd = [info_dict['avb_avbtool'], 'verify_image', '--image', image,
'--follow_chain_partitions']
+ # Custom images.
+ custom_partitions = info_dict.get(
+ "avb_custom_images_partition_list", "").strip().split()
+
# Append the args for chained partitions if any.
- for partition in common.AVB_PARTITIONS + common.AVB_VBMETA_PARTITIONS:
+ for partition in (common.AVB_PARTITIONS + common.AVB_VBMETA_PARTITIONS +
+ tuple(custom_partitions)):
key_name = 'avb_' + partition + '_key_path'
if info_dict.get(key_name) is not None:
if info_dict.get('ab_update') != 'true' and partition == 'recovery':
diff --git a/tools/releasetools/verity_utils.py b/tools/releasetools/verity_utils.py
index e7f84f5..fc83689 100644
--- a/tools/releasetools/verity_utils.py
+++ b/tools/releasetools/verity_utils.py
@@ -695,3 +695,22 @@
raise HashtreeInfoGenerationError("Failed to reconstruct the verity tree")
return self.hashtree_info
+
+
+def CreateCustomImageBuilder(info_dict, partition_name, partition_size,
+ key_path, algorithm, signing_args):
+ builder = None
+ if info_dict.get("avb_enable") == "true":
+ builder = VerifiedBootVersion2VerityImageBuilder(
+ partition_name,
+ partition_size,
+ VerifiedBootVersion2VerityImageBuilder.AVB_HASHTREE_FOOTER,
+ info_dict.get("avb_avbtool"),
+ key_path,
+ algorithm,
+ # Salt is None because custom images have no fingerprint property to be
+ # used as the salt.
+ None,
+ signing_args)
+
+ return builder