Check VINTF compatibility at OTA generation time.
Instead of relying on META/{system,vendor}_{manifest,matrix}.xml and blindly copy compatibility.zip from target files package to OTA package, do a static check on the input target files package before generating the OTA package. META/{system,vendor}_{manifest,matrix} does not contain ODM manifest fragments, which is incorrect. Also, the on-device check of compatibility.zip uses a old libvintf binary on the device, which may not understand the incoming VINTF metadata. This change removes the on-device check. Hence, it removes the requirement of forwards compatibility of libvintf. This behavior can be skipped with --skip-compatibility-check. Test: build OTA package Bug: 139300422 Bug: 131425279 Change-Id: I7fb93be9eb73f578fc05a182c6c9d1f073db2800
This commit is contained in:
@@ -4011,10 +4011,6 @@ $(BUILT_TARGET_FILES_PACKAGE): \
|
|||||||
$(HOST_OUT_EXECUTABLES)/fs_config \
|
$(HOST_OUT_EXECUTABLES)/fs_config \
|
||||||
$(ADD_IMG_TO_TARGET_FILES) \
|
$(ADD_IMG_TO_TARGET_FILES) \
|
||||||
$(MAKE_RECOVERY_PATCH) \
|
$(MAKE_RECOVERY_PATCH) \
|
||||||
$(BUILT_ASSEMBLED_FRAMEWORK_MANIFEST) \
|
|
||||||
$(BUILT_ASSEMBLED_VENDOR_MANIFEST) \
|
|
||||||
$(BUILT_SYSTEM_MATRIX) \
|
|
||||||
$(BUILT_VENDOR_MATRIX) \
|
|
||||||
$(BUILT_KERNEL_CONFIGS_FILE) \
|
$(BUILT_KERNEL_CONFIGS_FILE) \
|
||||||
$(BUILT_KERNEL_VERSION_FILE) \
|
$(BUILT_KERNEL_VERSION_FILE) \
|
||||||
| $(ACP)
|
| $(ACP)
|
||||||
@@ -4255,16 +4251,6 @@ ifdef BUILDING_SYSTEM_OTHER_IMAGE
|
|||||||
$(hide) $(call fs_config,$(zip_root)/SYSTEM_OTHER,system/) > $(zip_root)/META/system_other_filesystem_config.txt
|
$(hide) $(call fs_config,$(zip_root)/SYSTEM_OTHER,system/) > $(zip_root)/META/system_other_filesystem_config.txt
|
||||||
endif
|
endif
|
||||||
@# Metadata for compatibility verification.
|
@# Metadata for compatibility verification.
|
||||||
$(hide) cp $(BUILT_SYSTEM_MATRIX) $(zip_root)/META/system_matrix.xml
|
|
||||||
ifdef BUILT_ASSEMBLED_FRAMEWORK_MANIFEST
|
|
||||||
$(hide) cp $(BUILT_ASSEMBLED_FRAMEWORK_MANIFEST) $(zip_root)/META/system_manifest.xml
|
|
||||||
endif
|
|
||||||
ifdef BUILT_ASSEMBLED_VENDOR_MANIFEST
|
|
||||||
$(hide) cp $(BUILT_ASSEMBLED_VENDOR_MANIFEST) $(zip_root)/META/vendor_manifest.xml
|
|
||||||
endif
|
|
||||||
ifdef BUILT_VENDOR_MATRIX
|
|
||||||
$(hide) cp $(BUILT_VENDOR_MATRIX) $(zip_root)/META/vendor_matrix.xml
|
|
||||||
endif
|
|
||||||
ifdef BUILT_KERNEL_CONFIGS_FILE
|
ifdef BUILT_KERNEL_CONFIGS_FILE
|
||||||
$(hide) cp $(BUILT_KERNEL_CONFIGS_FILE) $(zip_root)/META/kernel_configs.txt
|
$(hide) cp $(BUILT_KERNEL_CONFIGS_FILE) $(zip_root)/META/kernel_configs.txt
|
||||||
endif
|
endif
|
||||||
|
@@ -96,6 +96,7 @@ python_defaults {
|
|||||||
"target_files_diff.py",
|
"target_files_diff.py",
|
||||||
],
|
],
|
||||||
libs: [
|
libs: [
|
||||||
|
"releasetools_check_target_files_vintf",
|
||||||
"releasetools_common",
|
"releasetools_common",
|
||||||
"releasetools_verity_utils",
|
"releasetools_verity_utils",
|
||||||
],
|
],
|
||||||
|
@@ -117,8 +117,6 @@ DEFAULT_FRAMEWORK_ITEM_LIST = (
|
|||||||
'META/apkcerts.txt',
|
'META/apkcerts.txt',
|
||||||
'META/filesystem_config.txt',
|
'META/filesystem_config.txt',
|
||||||
'META/root_filesystem_config.txt',
|
'META/root_filesystem_config.txt',
|
||||||
'META/system_manifest.xml',
|
|
||||||
'META/system_matrix.xml',
|
|
||||||
'META/update_engine_config.txt',
|
'META/update_engine_config.txt',
|
||||||
'PRODUCT/*',
|
'PRODUCT/*',
|
||||||
'ROOT/*',
|
'ROOT/*',
|
||||||
@@ -163,8 +161,6 @@ DEFAULT_VENDOR_ITEM_LIST = (
|
|||||||
'META/otakeys.txt',
|
'META/otakeys.txt',
|
||||||
'META/releasetools.py',
|
'META/releasetools.py',
|
||||||
'META/vendor_filesystem_config.txt',
|
'META/vendor_filesystem_config.txt',
|
||||||
'META/vendor_manifest.xml',
|
|
||||||
'META/vendor_matrix.xml',
|
|
||||||
'BOOT/*',
|
'BOOT/*',
|
||||||
'DATA/*',
|
'DATA/*',
|
||||||
'ODM/*',
|
'ODM/*',
|
||||||
|
@@ -72,7 +72,7 @@ Common options that apply to both of non-A/B and A/B OTAs
|
|||||||
--skip_postinstall is implied.
|
--skip_postinstall is implied.
|
||||||
|
|
||||||
--skip_compatibility_check
|
--skip_compatibility_check
|
||||||
Skip adding the compatibility package to the generated OTA package.
|
Skip checking compatibility of the input target files package.
|
||||||
|
|
||||||
--output_metadata_path
|
--output_metadata_path
|
||||||
Write a copy of the metadata to a separate file. Therefore, users can
|
Write a copy of the metadata to a separate file. Therefore, users can
|
||||||
@@ -189,9 +189,9 @@ import shlex
|
|||||||
import shutil
|
import shutil
|
||||||
import struct
|
import struct
|
||||||
import sys
|
import sys
|
||||||
import tempfile
|
|
||||||
import zipfile
|
import zipfile
|
||||||
|
|
||||||
|
import check_target_files_vintf
|
||||||
import common
|
import common
|
||||||
import edify_generator
|
import edify_generator
|
||||||
import verity_utils
|
import verity_utils
|
||||||
@@ -723,20 +723,15 @@ def HasPartition(target_files_zip, partition):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def HasVendorPartition(target_files_zip):
|
def HasTrebleEnabled(target_files, target_info):
|
||||||
return HasPartition(target_files_zip, "vendor")
|
def HasVendorPartition(target_files):
|
||||||
|
if os.path.isdir(target_files):
|
||||||
|
return os.path.isdir(os.path.join(target_files, "VENDOR"))
|
||||||
|
if zipfile.is_zipfile(target_files):
|
||||||
|
return HasPartition(zipfile.ZipFile(target_files), "vendor")
|
||||||
|
raise ValueError("Unknown target_files argument")
|
||||||
|
|
||||||
|
return (HasVendorPartition(target_files) and
|
||||||
def HasProductPartition(target_files_zip):
|
|
||||||
return HasPartition(target_files_zip, "product")
|
|
||||||
|
|
||||||
|
|
||||||
def HasOdmPartition(target_files_zip):
|
|
||||||
return HasPartition(target_files_zip, "odm")
|
|
||||||
|
|
||||||
|
|
||||||
def HasTrebleEnabled(target_files_zip, target_info):
|
|
||||||
return (HasVendorPartition(target_files_zip) and
|
|
||||||
target_info.GetBuildProp("ro.treble.enabled") == "true")
|
target_info.GetBuildProp("ro.treble.enabled") == "true")
|
||||||
|
|
||||||
|
|
||||||
@@ -761,74 +756,23 @@ def WriteFingerprintAssertion(script, target_info, source_info):
|
|||||||
source_info.GetBuildProp("ro.build.thumbprint"))
|
source_info.GetBuildProp("ro.build.thumbprint"))
|
||||||
|
|
||||||
|
|
||||||
def AddCompatibilityArchiveIfTrebleEnabled(target_zip, output_zip, target_info,
|
def CheckVintfIfTrebleEnabled(target_files, target_info):
|
||||||
source_info=None):
|
"""Checks compatibility info of the input target files.
|
||||||
"""Adds compatibility info into the output zip if it's Treble-enabled target.
|
|
||||||
|
|
||||||
Metadata used for on-device compatibility verification is retrieved from
|
Metadata used for compatibility verification is retrieved from target_zip.
|
||||||
target_zip then added to compatibility.zip which is added to the output_zip
|
|
||||||
archive.
|
|
||||||
|
|
||||||
Compatibility archive should only be included for devices that have enabled
|
Compatibility should only be checked for devices that have enabled
|
||||||
Treble support.
|
Treble support.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
target_zip: Zip file containing the source files to be included for OTA.
|
target_files: Path to zip file containing the source files to be included
|
||||||
output_zip: Zip file that will be sent for OTA.
|
for OTA. Can also be the path to extracted directory.
|
||||||
target_info: The BuildInfo instance that holds the target build info.
|
target_info: The BuildInfo instance that holds the target build info.
|
||||||
source_info: The BuildInfo instance that holds the source build info, if
|
|
||||||
generating an incremental OTA; None otherwise.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def AddCompatibilityArchive(framework_updated, device_updated):
|
|
||||||
"""Adds compatibility info based on update status of both sides of Treble
|
|
||||||
boundary.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
framework_updated: If True, the system / product image will be updated
|
|
||||||
and therefore their metadata should be included.
|
|
||||||
device_updated: If True, the vendor / odm image will be updated and
|
|
||||||
therefore their metadata should be included.
|
|
||||||
"""
|
|
||||||
# Determine what metadata we need. Files are names relative to META/.
|
|
||||||
compatibility_files = []
|
|
||||||
device_metadata = ("vendor_manifest.xml", "vendor_matrix.xml")
|
|
||||||
framework_metadata = ("system_manifest.xml", "system_matrix.xml")
|
|
||||||
if device_updated:
|
|
||||||
compatibility_files += device_metadata
|
|
||||||
if framework_updated:
|
|
||||||
compatibility_files += framework_metadata
|
|
||||||
|
|
||||||
# Create new archive.
|
|
||||||
compatibility_archive = tempfile.NamedTemporaryFile()
|
|
||||||
compatibility_archive_zip = zipfile.ZipFile(
|
|
||||||
compatibility_archive, "w", compression=zipfile.ZIP_DEFLATED)
|
|
||||||
|
|
||||||
# Add metadata.
|
|
||||||
for file_name in compatibility_files:
|
|
||||||
target_file_name = "META/" + file_name
|
|
||||||
|
|
||||||
if target_file_name in target_zip.namelist():
|
|
||||||
data = target_zip.read(target_file_name)
|
|
||||||
common.ZipWriteStr(compatibility_archive_zip, file_name, data)
|
|
||||||
|
|
||||||
# Ensure files are written before we copy into output_zip.
|
|
||||||
compatibility_archive_zip.close()
|
|
||||||
|
|
||||||
# Only add the archive if we have any compatibility info.
|
|
||||||
if compatibility_archive_zip.namelist():
|
|
||||||
common.ZipWrite(output_zip, compatibility_archive.name,
|
|
||||||
arcname="compatibility.zip",
|
|
||||||
compress_type=zipfile.ZIP_STORED)
|
|
||||||
|
|
||||||
def FingerprintChanged(source_fp, target_fp):
|
|
||||||
if source_fp is None or target_fp is None:
|
|
||||||
return True
|
|
||||||
return source_fp != target_fp
|
|
||||||
|
|
||||||
# Will only proceed if the target has enabled the Treble support (as well as
|
# Will only proceed if the target has enabled the Treble support (as well as
|
||||||
# having a /vendor partition).
|
# having a /vendor partition).
|
||||||
if not HasTrebleEnabled(target_zip, target_info):
|
if not HasTrebleEnabled(target_files, target_info):
|
||||||
return
|
return
|
||||||
|
|
||||||
# Skip adding the compatibility package as a workaround for b/114240221. The
|
# Skip adding the compatibility package as a workaround for b/114240221. The
|
||||||
@@ -836,28 +780,8 @@ def AddCompatibilityArchiveIfTrebleEnabled(target_zip, output_zip, target_info,
|
|||||||
if OPTIONS.skip_compatibility_check:
|
if OPTIONS.skip_compatibility_check:
|
||||||
return
|
return
|
||||||
|
|
||||||
# Full OTA carries the info for system/vendor/product/odm
|
if not check_target_files_vintf.CheckVintf(target_files, target_info):
|
||||||
if source_info is None:
|
raise RuntimeError("VINTF compatibility check failed")
|
||||||
AddCompatibilityArchive(True, True)
|
|
||||||
return
|
|
||||||
|
|
||||||
source_fp = source_info.fingerprint
|
|
||||||
target_fp = target_info.fingerprint
|
|
||||||
system_updated = source_fp != target_fp
|
|
||||||
|
|
||||||
# other build fingerprints could be possibly blacklisted at build time. For
|
|
||||||
# such a case, we consider those images being changed.
|
|
||||||
vendor_updated = FingerprintChanged(source_info.vendor_fingerprint,
|
|
||||||
target_info.vendor_fingerprint)
|
|
||||||
product_updated = HasProductPartition(target_zip) and \
|
|
||||||
FingerprintChanged(source_info.product_fingerprint,
|
|
||||||
target_info.product_fingerprint)
|
|
||||||
odm_updated = HasOdmPartition(target_zip) and \
|
|
||||||
FingerprintChanged(source_info.odm_fingerprint,
|
|
||||||
target_info.odm_fingerprint)
|
|
||||||
|
|
||||||
AddCompatibilityArchive(system_updated or product_updated,
|
|
||||||
vendor_updated or odm_updated)
|
|
||||||
|
|
||||||
|
|
||||||
def GetBlockDifferences(target_zip, source_zip, target_info, source_info,
|
def GetBlockDifferences(target_zip, source_zip, target_info, source_info,
|
||||||
@@ -1068,7 +992,7 @@ else if get_stage("%(bcb_dev)s") == "3/3" then
|
|||||||
progress=progress_dict.get(block_diff.partition),
|
progress=progress_dict.get(block_diff.partition),
|
||||||
write_verify_script=OPTIONS.verify)
|
write_verify_script=OPTIONS.verify)
|
||||||
|
|
||||||
AddCompatibilityArchiveIfTrebleEnabled(input_zip, output_zip, target_info)
|
CheckVintfIfTrebleEnabled(OPTIONS.input_tmp, target_info)
|
||||||
|
|
||||||
boot_img = common.GetBootableImage(
|
boot_img = common.GetBootableImage(
|
||||||
"boot.img", "boot.img", OPTIONS.input_tmp, "BOOT")
|
"boot.img", "boot.img", OPTIONS.input_tmp, "BOOT")
|
||||||
@@ -1643,8 +1567,7 @@ def WriteBlockIncrementalOTAPackage(target_zip, source_zip, output_file):
|
|||||||
source_info=source_info,
|
source_info=source_info,
|
||||||
device_specific=device_specific)
|
device_specific=device_specific)
|
||||||
|
|
||||||
AddCompatibilityArchiveIfTrebleEnabled(
|
CheckVintfIfTrebleEnabled(OPTIONS.target_tmp, target_info)
|
||||||
target_zip, output_zip, target_info, source_info)
|
|
||||||
|
|
||||||
# Assertions (e.g. device properties check).
|
# Assertions (e.g. device properties check).
|
||||||
target_info.WriteDeviceAssertions(script, OPTIONS.oem_no_mount)
|
target_info.WriteDeviceAssertions(script, OPTIONS.oem_no_mount)
|
||||||
@@ -2079,11 +2002,10 @@ def GenerateAbOtaPackage(target_file, output_file, source_file=None):
|
|||||||
else:
|
else:
|
||||||
logger.warning("Cannot find care map file in target_file package")
|
logger.warning("Cannot find care map file in target_file package")
|
||||||
|
|
||||||
AddCompatibilityArchiveIfTrebleEnabled(
|
|
||||||
target_zip, output_zip, target_info, source_info)
|
|
||||||
|
|
||||||
common.ZipClose(target_zip)
|
common.ZipClose(target_zip)
|
||||||
|
|
||||||
|
CheckVintfIfTrebleEnabled(target_file, target_info)
|
||||||
|
|
||||||
# We haven't written the metadata entry yet, which will be handled in
|
# We haven't written the metadata entry yet, which will be handled in
|
||||||
# FinalizeMetadata().
|
# FinalizeMetadata().
|
||||||
common.ZipClose(output_zip)
|
common.ZipClose(output_zip)
|
||||||
|
Reference in New Issue
Block a user