Loading tools/releasetools/ota_from_target_files.py +38 −32 Original line number Original line Diff line number Diff line Loading @@ -297,8 +297,6 @@ SECONDARY_PAYLOAD_SKIPPED_IMAGES = [ 'vendor_boot'] 'vendor_boot'] class PayloadSigner(object): class PayloadSigner(object): """A class that wraps the payload signing works. """A class that wraps the payload signing works. Loading Loading @@ -765,10 +763,12 @@ def GetTargetFilesZipWithoutPostinstallConfig(input_file): common.ZipDelete(target_file, POSTINSTALL_CONFIG) common.ZipDelete(target_file, POSTINSTALL_CONFIG) return target_file return target_file def ParseInfoDict(target_file_path): def ParseInfoDict(target_file_path): with zipfile.ZipFile(target_file_path, 'r', allowZip64=True) as zfp: with zipfile.ZipFile(target_file_path, 'r', allowZip64=True) as zfp: return common.LoadInfoDict(zfp) return common.LoadInfoDict(zfp) def GetTargetFilesZipForPartialUpdates(input_file, ab_partitions): def GetTargetFilesZipForPartialUpdates(input_file, ab_partitions): """Returns a target-files.zip for partial ota update package generation. """Returns a target-files.zip for partial ota update package generation. Loading Loading @@ -963,12 +963,14 @@ def GetTargetFilesZipForCustomImagesUpdates(input_file, custom_images): return target_file return target_file def GeneratePartitionTimestampFlags(partition_state): def GeneratePartitionTimestampFlags(partition_state): partition_timestamps = [ partition_timestamps = [ part.partition_name + ":" + part.version part.partition_name + ":" + part.version for part in partition_state] for part in partition_state] return ["--partition_timestamps", ",".join(partition_timestamps)] return ["--partition_timestamps", ",".join(partition_timestamps)] def GeneratePartitionTimestampFlagsDowngrade( def GeneratePartitionTimestampFlagsDowngrade( pre_partition_state, post_partition_state): pre_partition_state, post_partition_state): assert pre_partition_state is not None assert pre_partition_state is not None Loading @@ -980,15 +982,18 @@ def GeneratePartitionTimestampFlagsDowngrade( max(part.version, partition_timestamps[part.partition_name]) max(part.version, partition_timestamps[part.partition_name]) return [ return [ "--partition_timestamps", "--partition_timestamps", ",".join([key + ":" + val for (key, val) in partition_timestamps.items()]) ",".join([key + ":" + val for (key, val) in partition_timestamps.items()]) ] ] def IsSparseImage(filepath): def IsSparseImage(filepath): with open(filepath, 'rb') as fp: with open(filepath, 'rb') as fp: # Magic for android sparse image format # Magic for android sparse image format # https://source.android.com/devices/bootloader/images # https://source.android.com/devices/bootloader/images return fp.read(4) == b'\x3A\xFF\x26\xED' return fp.read(4) == b'\x3A\xFF\x26\xED' def SupportsMainlineGkiUpdates(target_file): def SupportsMainlineGkiUpdates(target_file): """Return True if the build supports MainlineGKIUpdates. """Return True if the build supports MainlineGKIUpdates. Loading Loading @@ -1027,6 +1032,7 @@ def SupportsMainlineGkiUpdates(target_file): pattern = re.compile(r"com\.android\.gki\..*\.apex") pattern = re.compile(r"com\.android\.gki\..*\.apex") return pattern.search(output) is not None return pattern.search(output) is not None def GenerateAbOtaPackage(target_file, output_file, source_file=None): def GenerateAbOtaPackage(target_file, output_file, source_file=None): """Generates an Android OTA package that has A/B update payload.""" """Generates an Android OTA package that has A/B update payload.""" # Stage the output zip package for package signing. # Stage the output zip package for package signing. Loading Loading @@ -1103,7 +1109,8 @@ def GenerateAbOtaPackage(target_file, output_file, source_file=None): additional_args += ["--max_timestamp", max_timestamp] additional_args += ["--max_timestamp", max_timestamp] if SupportsMainlineGkiUpdates(source_file): if SupportsMainlineGkiUpdates(source_file): logger.warning("Detected build with mainline GKI, include full boot image.") logger.warning( "Detected build with mainline GKI, include full boot image.") additional_args.extend(["--full_boot", "true"]) additional_args.extend(["--full_boot", "true"]) payload.Generate( payload.Generate( Loading Loading @@ -1271,6 +1278,7 @@ def main(argv): OPTIONS.disable_vabc = True OPTIONS.disable_vabc = True elif o == "--spl_downgrade": elif o == "--spl_downgrade": OPTIONS.spl_downgrade = True OPTIONS.spl_downgrade = True OPTIONS.wipe_user_data = True else: else: return False return False return True return True Loading Loading @@ -1341,7 +1349,6 @@ def main(argv): if OPTIONS.incremental_source is None: if OPTIONS.incremental_source is None: raise ValueError("Cannot generate downgradable full OTAs") raise ValueError("Cannot generate downgradable full OTAs") # TODO(xunchang) for retrofit and partial updates, maybe we should rebuild the # 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 # target-file and reload the info_dict. So the info will be consistent with # the modified target-file. # the modified target-file. Loading @@ -1349,7 +1356,6 @@ def main(argv): logger.info("--- target info ---") logger.info("--- target info ---") common.DumpInfoDict(OPTIONS.info_dict) common.DumpInfoDict(OPTIONS.info_dict) # Load the source build dict if applicable. # Load the source build dict if applicable. if OPTIONS.incremental_source is not None: if OPTIONS.incremental_source is not None: OPTIONS.target_info_dict = OPTIONS.info_dict OPTIONS.target_info_dict = OPTIONS.info_dict Loading Loading @@ -1423,7 +1429,7 @@ def main(argv): source_spl = source_build_prop.GetProp(SECURITY_PATCH_LEVEL_PROP_NAME) source_spl = source_build_prop.GetProp(SECURITY_PATCH_LEVEL_PROP_NAME) target_spl = target_build_prop.GetProp(SECURITY_PATCH_LEVEL_PROP_NAME) target_spl = target_build_prop.GetProp(SECURITY_PATCH_LEVEL_PROP_NAME) is_spl_downgrade = target_spl < source_spl is_spl_downgrade = target_spl < source_spl if is_spl_downgrade and not OPTIONS.spl_downgrade: if is_spl_downgrade and not OPTIONS.spl_downgrade and not OPTIONS.downgrade: raise common.ExternalError( raise common.ExternalError( "Target security patch level {} is older than source SPL {} applying " "Target security patch level {} is older than source SPL {} applying " "such OTA will likely cause device fail to boot. Pass --spl_downgrade " "such OTA will likely cause device fail to boot. Pass --spl_downgrade " Loading Loading
tools/releasetools/ota_from_target_files.py +38 −32 Original line number Original line Diff line number Diff line Loading @@ -297,8 +297,6 @@ SECONDARY_PAYLOAD_SKIPPED_IMAGES = [ 'vendor_boot'] 'vendor_boot'] class PayloadSigner(object): class PayloadSigner(object): """A class that wraps the payload signing works. """A class that wraps the payload signing works. Loading Loading @@ -765,10 +763,12 @@ def GetTargetFilesZipWithoutPostinstallConfig(input_file): common.ZipDelete(target_file, POSTINSTALL_CONFIG) common.ZipDelete(target_file, POSTINSTALL_CONFIG) return target_file return target_file def ParseInfoDict(target_file_path): def ParseInfoDict(target_file_path): with zipfile.ZipFile(target_file_path, 'r', allowZip64=True) as zfp: with zipfile.ZipFile(target_file_path, 'r', allowZip64=True) as zfp: return common.LoadInfoDict(zfp) return common.LoadInfoDict(zfp) def GetTargetFilesZipForPartialUpdates(input_file, ab_partitions): def GetTargetFilesZipForPartialUpdates(input_file, ab_partitions): """Returns a target-files.zip for partial ota update package generation. """Returns a target-files.zip for partial ota update package generation. Loading Loading @@ -963,12 +963,14 @@ def GetTargetFilesZipForCustomImagesUpdates(input_file, custom_images): return target_file return target_file def GeneratePartitionTimestampFlags(partition_state): def GeneratePartitionTimestampFlags(partition_state): partition_timestamps = [ partition_timestamps = [ part.partition_name + ":" + part.version part.partition_name + ":" + part.version for part in partition_state] for part in partition_state] return ["--partition_timestamps", ",".join(partition_timestamps)] return ["--partition_timestamps", ",".join(partition_timestamps)] def GeneratePartitionTimestampFlagsDowngrade( def GeneratePartitionTimestampFlagsDowngrade( pre_partition_state, post_partition_state): pre_partition_state, post_partition_state): assert pre_partition_state is not None assert pre_partition_state is not None Loading @@ -980,15 +982,18 @@ def GeneratePartitionTimestampFlagsDowngrade( max(part.version, partition_timestamps[part.partition_name]) max(part.version, partition_timestamps[part.partition_name]) return [ return [ "--partition_timestamps", "--partition_timestamps", ",".join([key + ":" + val for (key, val) in partition_timestamps.items()]) ",".join([key + ":" + val for (key, val) in partition_timestamps.items()]) ] ] def IsSparseImage(filepath): def IsSparseImage(filepath): with open(filepath, 'rb') as fp: with open(filepath, 'rb') as fp: # Magic for android sparse image format # Magic for android sparse image format # https://source.android.com/devices/bootloader/images # https://source.android.com/devices/bootloader/images return fp.read(4) == b'\x3A\xFF\x26\xED' return fp.read(4) == b'\x3A\xFF\x26\xED' def SupportsMainlineGkiUpdates(target_file): def SupportsMainlineGkiUpdates(target_file): """Return True if the build supports MainlineGKIUpdates. """Return True if the build supports MainlineGKIUpdates. Loading Loading @@ -1027,6 +1032,7 @@ def SupportsMainlineGkiUpdates(target_file): pattern = re.compile(r"com\.android\.gki\..*\.apex") pattern = re.compile(r"com\.android\.gki\..*\.apex") return pattern.search(output) is not None return pattern.search(output) is not None def GenerateAbOtaPackage(target_file, output_file, source_file=None): def GenerateAbOtaPackage(target_file, output_file, source_file=None): """Generates an Android OTA package that has A/B update payload.""" """Generates an Android OTA package that has A/B update payload.""" # Stage the output zip package for package signing. # Stage the output zip package for package signing. Loading Loading @@ -1103,7 +1109,8 @@ def GenerateAbOtaPackage(target_file, output_file, source_file=None): additional_args += ["--max_timestamp", max_timestamp] additional_args += ["--max_timestamp", max_timestamp] if SupportsMainlineGkiUpdates(source_file): if SupportsMainlineGkiUpdates(source_file): logger.warning("Detected build with mainline GKI, include full boot image.") logger.warning( "Detected build with mainline GKI, include full boot image.") additional_args.extend(["--full_boot", "true"]) additional_args.extend(["--full_boot", "true"]) payload.Generate( payload.Generate( Loading Loading @@ -1271,6 +1278,7 @@ def main(argv): OPTIONS.disable_vabc = True OPTIONS.disable_vabc = True elif o == "--spl_downgrade": elif o == "--spl_downgrade": OPTIONS.spl_downgrade = True OPTIONS.spl_downgrade = True OPTIONS.wipe_user_data = True else: else: return False return False return True return True Loading Loading @@ -1341,7 +1349,6 @@ def main(argv): if OPTIONS.incremental_source is None: if OPTIONS.incremental_source is None: raise ValueError("Cannot generate downgradable full OTAs") raise ValueError("Cannot generate downgradable full OTAs") # TODO(xunchang) for retrofit and partial updates, maybe we should rebuild the # 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 # target-file and reload the info_dict. So the info will be consistent with # the modified target-file. # the modified target-file. Loading @@ -1349,7 +1356,6 @@ def main(argv): logger.info("--- target info ---") logger.info("--- target info ---") common.DumpInfoDict(OPTIONS.info_dict) common.DumpInfoDict(OPTIONS.info_dict) # Load the source build dict if applicable. # Load the source build dict if applicable. if OPTIONS.incremental_source is not None: if OPTIONS.incremental_source is not None: OPTIONS.target_info_dict = OPTIONS.info_dict OPTIONS.target_info_dict = OPTIONS.info_dict Loading Loading @@ -1423,7 +1429,7 @@ def main(argv): source_spl = source_build_prop.GetProp(SECURITY_PATCH_LEVEL_PROP_NAME) source_spl = source_build_prop.GetProp(SECURITY_PATCH_LEVEL_PROP_NAME) target_spl = target_build_prop.GetProp(SECURITY_PATCH_LEVEL_PROP_NAME) target_spl = target_build_prop.GetProp(SECURITY_PATCH_LEVEL_PROP_NAME) is_spl_downgrade = target_spl < source_spl is_spl_downgrade = target_spl < source_spl if is_spl_downgrade and not OPTIONS.spl_downgrade: if is_spl_downgrade and not OPTIONS.spl_downgrade and not OPTIONS.downgrade: raise common.ExternalError( raise common.ExternalError( "Target security patch level {} is older than source SPL {} applying " "Target security patch level {} is older than source SPL {} applying " "such OTA will likely cause device fail to boot. Pass --spl_downgrade " "such OTA will likely cause device fail to boot. Pass --spl_downgrade " Loading