diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py index 826ab1bf80..ec53a47a5f 100644 --- a/tools/releasetools/common.py +++ b/tools/releasetools/common.py @@ -449,6 +449,10 @@ class BuildInfo(object): system_prop = self.info_dict.get("system.build.prop") return system_prop and system_prop.GetProp("ro.build.version.release") == "11" + @property + def vabc_compression_param(self): + return self.get("virtual_ab_compression_method", "") + @property def vendor_api_level(self): vendor_prop = self.info_dict.get("vendor.build.prop") diff --git a/tools/releasetools/ota_from_target_files.py b/tools/releasetools/ota_from_target_files.py index 71dbde626f..56ec929a9d 100755 --- a/tools/releasetools/ota_from_target_files.py +++ b/tools/releasetools/ota_from_target_files.py @@ -274,7 +274,7 @@ import zipfile import care_map_pb2 import common import ota_utils -from ota_utils import (UNZIP_PATTERN, FinalizeMetadata, GetPackageMetadata, +from ota_utils import (VABC_COMPRESSION_PARAM_SUPPORT, FinalizeMetadata, GetPackageMetadata, PayloadGenerator, SECURITY_PATCH_LEVEL_PROP_NAME, ExtractTargetFiles, CopyTargetFilesDir) from common import DoesInputFileContain, IsSparseImage import target_files_diff @@ -872,6 +872,10 @@ def GenerateAbOtaPackage(target_file, output_file, source_file=None): if not source_info.is_vabc or not target_info.is_vabc: logger.info("Either source or target does not support VABC, disabling.") OPTIONS.disable_vabc = True + if source_info.vabc_compression_param != target_info.vabc_compression_param: + logger.info("Source build and target build use different compression methods {} vs {}, default to source builds parameter {}".format( + source_info.vabc_compression_param, target_info.vabc_compression_param, source_info.vabc_compression_param)) + OPTIONS.vabc_compression_param = source_info.vabc_compression_param # Virtual AB Compression was introduced in Androd S. # Later, we backported VABC to Android R. But verity support was not @@ -886,6 +890,22 @@ def GenerateAbOtaPackage(target_file, output_file, source_file=None): "META/ab_partitions.txt is required for ab_update." target_info = common.BuildInfo(OPTIONS.info_dict, OPTIONS.oem_dicts) source_info = None + if target_info.vabc_compression_param: + minimum_api_level_required = VABC_COMPRESSION_PARAM_SUPPORT[ + target_info.vabc_compression_param] + if target_info.vendor_api_level < minimum_api_level_required: + logger.warning( + "This full OTA is configured to use VABC compression algorithm" + " {}, which is supported since" + " Android API level {}, but device is " + "launched with {} . If this full OTA is" + " served to a device running old build, OTA might fail due to " + "unsupported compression parameter. For safety, gz is used because " + "it's supported since day 1.".format( + target_info.vabc_compression_param, + minimum_api_level_required, + target_info.vendor_api_level)) + OPTIONS.vabc_compression_param = "gz" if OPTIONS.partial == []: logger.info( diff --git a/tools/releasetools/ota_utils.py b/tools/releasetools/ota_utils.py index 68c6887f87..f288a9c362 100644 --- a/tools/releasetools/ota_utils.py +++ b/tools/releasetools/ota_utils.py @@ -51,6 +51,19 @@ SECURITY_PATCH_LEVEL_PROP_NAME = "ro.build.version.security_patch" TARGET_FILES_IMAGES_SUBDIR = ["IMAGES", "PREBUILT_IMAGES", "RADIO"] +# Key is the compression algorithm, value is minimum API level required to +# use this compression algorithm for VABC OTA on device. +VABC_COMPRESSION_PARAM_SUPPORT = { + "gz": 31, + "brotli": 31, + "none": 31, + # lz4 support is added in Android U + "lz4": 34, + # zstd support is added in Android V + "zstd": 35, +} + + def FinalizeMetadata(metadata, input_file, output_file, needed_property_files=None, package_key=None, pw=None): """Finalizes the metadata and signs an A/B OTA package. @@ -727,6 +740,7 @@ def ExtractTargetFiles(path: str): logger.info("target files %s is already extracted", path) return path extracted_dir = common.MakeTempDir("target_files") + logger.info(f"Extracting target files {path} to {extracted_dir}") common.UnzipToDir(path, extracted_dir, UNZIP_PATTERN + [""]) for subdir in TARGET_FILES_IMAGES_SUBDIR: image_dir = os.path.join(extracted_dir, subdir) @@ -850,7 +864,7 @@ class PayloadGenerator(object): cmd.extend(["--dynamic_partition_info_file", dynamic_partition_info]) apex_info = os.path.join( - target_dir, "META", "apex_info.pb") + target_dir, "META", "apex_info.pb") if os.path.exists(apex_info): cmd.extend(["--apex_info_file", apex_info])