From 80195724e7c2e456e72250aeaf473ec30a5bfdb6 Mon Sep 17 00:00:00 2001 From: Kelvin Zhang Date: Wed, 4 Nov 2020 14:38:34 -0500 Subject: [PATCH] Allow downgradable partial OTA Cuttlefish doesn't support updatin vendor partition. So in testing we need to exclude vendor and generate a downgrade partial package. Test: generate a partial downgrade OTA Bug: 171999375 Change-Id: I97e450d4063320cf55003a7a5c5ef913c321e067 --- tools/releasetools/ota_from_target_files.py | 40 ++++++++++++++++----- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/tools/releasetools/ota_from_target_files.py b/tools/releasetools/ota_from_target_files.py index 9a57c8ae2..869b71379 100755 --- a/tools/releasetools/ota_from_target_files.py +++ b/tools/releasetools/ota_from_target_files.py @@ -955,6 +955,19 @@ def GeneratePartitionTimestampFlags(partition_state): for part in partition_state] return ["--partition_timestamps", ",".join(partition_timestamps)] +def GeneratePartitionTimestampFlagsDowngrade(pre_partition_state, post_partition_state): + assert pre_partition_state is not None + partition_timestamps = {} + for part in pre_partition_state: + partition_timestamps[part.partition_name] = part.version + for part in post_partition_state: + partition_timestamps[part.partition_name] = \ + max(part.version, partition_timestamps[part.partition_name]) + return [ + "--partition_timestamps", + ",".join([key + ":" + val for (key, val) in partition_timestamps.items()]) + ] + def GenerateAbOtaPackage(target_file, output_file, source_file=None): """Generates an Android OTA package that has A/B update payload.""" # Stage the output zip package for package signing. @@ -1015,6 +1028,10 @@ def GenerateAbOtaPackage(target_file, output_file, source_file=None): # Enforce a max timestamp this payload can be applied on top of. if OPTIONS.downgrade: max_timestamp = source_info.GetBuildProp("ro.build.date.utc") + partition_timestamps_flags = GeneratePartitionTimestampFlagsDowngrade( + metadata.precondition.partition_state, + metadata.postcondition.partition_state + ) else: max_timestamp = str(metadata.postcondition.timestamp) partition_timestamps_flags = GeneratePartitionTimestampFlags( @@ -1226,15 +1243,6 @@ def main(argv): common.InitLogging() - if OPTIONS.downgrade: - # We should only allow downgrading incrementals (as opposed to full). - # Otherwise the device may go back from arbitrary build with this full - # OTA package. - if OPTIONS.incremental_source is None: - raise ValueError("Cannot generate downgradable full OTAs") - if OPTIONS.partial: - raise ValueError("Cannot generate downgradable partial OTAs") - # Load the build info dicts from the zip directly or the extracted input # directory. We don't need to unzip the entire target-files zips, because they # won't be needed for A/B OTAs (brillo_update_payload does that on its own). @@ -1246,6 +1254,19 @@ def main(argv): OPTIONS.info_dict = common.LoadInfoDict(OPTIONS.extracted_input) else: OPTIONS.info_dict = ParseInfoDict(args[0]) + if OPTIONS.partial: + OPTIONS.info_dict['ab_partitions'] = \ + list( + set(OPTIONS.info_dict['ab_partitions']) & set(OPTIONS.partial) + ) + + if OPTIONS.downgrade: + # We should only allow downgrading incrementals (as opposed to full). + # Otherwise the device may go back from arbitrary build with this full + # OTA package. + if OPTIONS.incremental_source is None: + raise ValueError("Cannot generate downgradable full OTAs") + # TODO(xunchang) for retrofit and partial updates, maybe we should rebuild the # target-file and reload the info_dict. So the info will be consistent with @@ -1254,6 +1275,7 @@ def main(argv): logger.info("--- target info ---") common.DumpInfoDict(OPTIONS.info_dict) + # Load the source build dict if applicable. if OPTIONS.incremental_source is not None: OPTIONS.target_info_dict = OPTIONS.info_dict