Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bcba1cfd authored by Yifan Hong's avatar Yifan Hong Committed by Gerrit Code Review
Browse files

Merge changes from topic "vintf_ota_delete"

* changes:
  merge_target_files: Checks VINTF metadata of resulting target files
  Check VINTF compatibility at OTA generation time.
  releasetools: add tests for check_target_files_vintf
  Add a script to check VINTF compat of target files package.
parents e9cb5fa3 ade0d3f4
Loading
Loading
Loading
Loading
+32 −28
Original line number Original line Diff line number Diff line
@@ -2698,12 +2698,19 @@ $(BUILT_ASSEMBLED_VENDOR_MANIFEST): PRIVATE_FLAGS :=
# -- Kernel version and configurations.
# -- Kernel version and configurations.
ifeq ($(PRODUCT_OTA_ENFORCE_VINTF_KERNEL_REQUIREMENTS),true)
ifeq ($(PRODUCT_OTA_ENFORCE_VINTF_KERNEL_REQUIREMENTS),true)


intermediates := $(call intermediates-dir-for,ETC,$(notdir $(BUILT_ASSEMBLED_VENDOR_MANIFEST)))
BUILT_KERNEL_CONFIGS_FILE := $(intermediates)/kernel_configs.txt
BUILT_KERNEL_VERSION_FILE := $(intermediates)/kernel_version.txt

# BOARD_KERNEL_CONFIG_FILE and BOARD_KERNEL_VERSION can be used to override the values extracted
# BOARD_KERNEL_CONFIG_FILE and BOARD_KERNEL_VERSION can be used to override the values extracted
# from INSTALLED_KERNEL_TARGET.
# from INSTALLED_KERNEL_TARGET.
ifdef BOARD_KERNEL_CONFIG_FILE
ifdef BOARD_KERNEL_CONFIG_FILE
ifdef BOARD_KERNEL_VERSION
ifdef BOARD_KERNEL_VERSION
$(BUILT_ASSEMBLED_VENDOR_MANIFEST): $(BOARD_KERNEL_CONFIG_FILE)
$(BUILT_KERNEL_CONFIGS_FILE): $(BOARD_KERNEL_CONFIG_FILE)
$(BUILT_ASSEMBLED_VENDOR_MANIFEST): PRIVATE_FLAGS += --kernel $(BOARD_KERNEL_VERSION):$(BOARD_KERNEL_CONFIG_FILE)
	cp $< $@
$(BUILT_KERNEL_VERSION_FILE):
	echo $(BOARD_KERNEL_VERSION) > $@

my_board_extracted_kernel := true
my_board_extracted_kernel := true
endif # BOARD_KERNEL_VERSION
endif # BOARD_KERNEL_VERSION
endif # BOARD_KERNEL_CONFIG_FILE
endif # BOARD_KERNEL_CONFIG_FILE
@@ -2718,7 +2725,6 @@ $(warning No INSTALLED_KERNEL_TARGET is defined when PRODUCT_OTA_ENFORCE_VINTF_K
    BOARD_KERNEL_VERSION manually; or (3) unsetting PRODUCT_OTA_ENFORCE_VINTF_KERNEL_REQUIREMENTS \
    BOARD_KERNEL_VERSION manually; or (3) unsetting PRODUCT_OTA_ENFORCE_VINTF_KERNEL_REQUIREMENTS \
    manually.)
    manually.)
else
else
intermediates := $(call intermediates-dir-for,ETC,$(notdir $(BUILT_ASSEMBLED_VENDOR_MANIFEST)))


# Tools for decompression that is not in PATH.
# Tools for decompression that is not in PATH.
# Check $(EXTRACT_KERNEL) for decompression algorithms supported by the script.
# Check $(EXTRACT_KERNEL) for decompression algorithms supported by the script.
@@ -2726,29 +2732,25 @@ intermediates := $(call intermediates-dir-for,ETC,$(notdir $(BUILT_ASSEMBLED_VEN
my_decompress_tools := \
my_decompress_tools := \
    lz4:$(HOST_OUT_EXECUTABLES)/lz4 \
    lz4:$(HOST_OUT_EXECUTABLES)/lz4 \


my_kernel_configs := $(intermediates)/kernel_configs.txt
$(BUILT_KERNEL_CONFIGS_FILE): .KATI_IMPLICIT_OUTPUTS := $(BUILT_KERNEL_VERSION_FILE)
my_kernel_version := $(intermediates)/kernel_version.txt
$(BUILT_KERNEL_CONFIGS_FILE): PRIVATE_DECOMPRESS_TOOLS := $(my_decompress_tools)
$(my_kernel_configs): .KATI_IMPLICIT_OUTPUTS := $(my_kernel_version)
$(BUILT_KERNEL_CONFIGS_FILE): $(foreach pair,$(my_decompress_tools),$(call word-colon,2,$(pair)))
$(my_kernel_configs): PRIVATE_KERNEL_VERSION_FILE := $(my_kernel_version)
$(BUILT_KERNEL_CONFIGS_FILE): $(EXTRACT_KERNEL) $(INSTALLED_KERNEL_TARGET)
$(my_kernel_configs): PRIVATE_DECOMPRESS_TOOLS := $(my_decompress_tools)
$(my_kernel_configs): $(foreach pair,$(my_decompress_tools),$(call word-colon,2,$(pair)))
$(my_kernel_configs): $(EXTRACT_KERNEL) $(INSTALLED_KERNEL_TARGET)
	$< --tools $(PRIVATE_DECOMPRESS_TOOLS) --input $(INSTALLED_KERNEL_TARGET) \
	$< --tools $(PRIVATE_DECOMPRESS_TOOLS) --input $(INSTALLED_KERNEL_TARGET) \
	  --output-configs $@ \
	  --output-configs $@ \
	  --output-version $(PRIVATE_KERNEL_VERSION_FILE)
	  --output-version $(BUILT_KERNEL_VERSION_FILE)

$(BUILT_ASSEMBLED_VENDOR_MANIFEST): $(my_kernel_configs) $(my_kernel_version)
$(BUILT_ASSEMBLED_VENDOR_MANIFEST): PRIVATE_FLAGS += --kernel $$(cat $(my_kernel_version)):$(my_kernel_configs)


intermediates :=
intermediates :=
my_kernel_configs :=
my_kernel_version :=
my_decompress_tools :=
my_decompress_tools :=


endif # my_board_extracted_kernel
endif # my_board_extracted_kernel
my_board_extracted_kernel :=
my_board_extracted_kernel :=


endif # INSTALLED_KERNEL_TARGET
endif # INSTALLED_KERNEL_TARGET

$(BUILT_ASSEMBLED_VENDOR_MANIFEST): $(BUILT_KERNEL_CONFIGS_FILE) $(BUILT_KERNEL_VERSION_FILE)
$(BUILT_ASSEMBLED_VENDOR_MANIFEST): PRIVATE_FLAGS += --kernel $$(cat $(BUILT_KERNEL_VERSION_FILE)):$(BUILT_KERNEL_CONFIGS_FILE)

endif # PRODUCT_OTA_ENFORCE_VINTF_KERNEL_REQUIREMENTS
endif # PRODUCT_OTA_ENFORCE_VINTF_KERNEL_REQUIREMENTS


$(BUILT_ASSEMBLED_VENDOR_MANIFEST):
$(BUILT_ASSEMBLED_VENDOR_MANIFEST):
@@ -3614,6 +3616,7 @@ INTERNAL_OTATOOLS_MODULES := \
  care_map_generator \
  care_map_generator \
  check_ota_package_signature \
  check_ota_package_signature \
  check_target_files_signatures \
  check_target_files_signatures \
  check_target_files_vintf \
  checkvintf \
  checkvintf \
  delta_generator \
  delta_generator \
  e2fsck \
  e2fsck \
@@ -3846,6 +3849,13 @@ endif # BOARD_AVB_DTBO_KEY_PATH
endif # BOARD_AVB_ENABLE
endif # BOARD_AVB_ENABLE
endif # BOARD_PREBUILT_DTBOIMAGE
endif # BOARD_PREBUILT_DTBOIMAGE
	$(call dump-dynamic-partitions-info,$@)
	$(call dump-dynamic-partitions-info,$@)
	@# VINTF checks
ifeq ($(PRODUCT_ENFORCE_VINTF_MANIFEST),true)
	$(hide) echo "vintf_enforce=true" >> $@
endif
ifdef ODM_MANIFEST_SKUS
	$(hide) echo "vintf_odm_manifest_skus=$(ODM_MANIFEST_SKUS)" >> $@
endif


.PHONY: misc_info
.PHONY: misc_info
misc_info: $(INSTALLED_MISC_INFO_TARGET)
misc_info: $(INSTALLED_MISC_INFO_TARGET)
@@ -4001,10 +4011,8 @@ $(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_KERNEL_CONFIGS_FILE) \
	    $(BUILT_ASSEMBLED_VENDOR_MANIFEST) \
	    $(BUILT_KERNEL_VERSION_FILE) \
	    $(BUILT_SYSTEM_MATRIX) \
	    $(BUILT_VENDOR_MATRIX) \
	    | $(ACP)
	    | $(ACP)
	@echo "Package target files: $@"
	@echo "Package target files: $@"
	$(call create-system-vendor-symlink)
	$(call create-system-vendor-symlink)
@@ -4243,15 +4251,11 @@ 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_KERNEL_CONFIGS_FILE
ifdef BUILT_ASSEMBLED_FRAMEWORK_MANIFEST
	$(hide) cp $(BUILT_KERNEL_CONFIGS_FILE) $(zip_root)/META/kernel_configs.txt
	$(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
endif
ifdef BUILT_VENDOR_MATRIX
ifdef BUILT_KERNEL_VERSION_FILE
	$(hide) cp $(BUILT_VENDOR_MATRIX) $(zip_root)/META/vendor_matrix.xml
	$(hide) cp $(BUILT_KERNEL_VERSION_FILE) $(zip_root)/META/kernel_version.txt
endif
endif
ifneq ($(BOARD_SUPER_PARTITION_GROUPS),)
ifneq ($(BOARD_SUPER_PARTITION_GROUPS),)
	$(hide) echo "super_partition_groups=$(BOARD_SUPER_PARTITION_GROUPS)" > $(zip_root)/META/dynamic_partitions_info.txt
	$(hide) echo "super_partition_groups=$(BOARD_SUPER_PARTITION_GROUPS)" > $(zip_root)/META/dynamic_partitions_info.txt
+33 −1
Original line number Original line Diff line number Diff line
@@ -75,6 +75,19 @@ python_defaults {
    ],
    ],
}
}


python_defaults {
    name: "releasetools_check_target_files_vintf_defaults",
    srcs: [
        "check_target_files_vintf.py",
    ],
    libs: [
        "releasetools_common",
    ],
    required: [
        "checkvintf",
    ],
}

python_defaults {
python_defaults {
    name: "releasetools_ota_from_target_files_defaults",
    name: "releasetools_ota_from_target_files_defaults",
    srcs: [
    srcs: [
@@ -83,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",
    ],
    ],
@@ -142,6 +156,14 @@ python_library_host {
    ],
    ],
}
}


python_library_host {
    name: "releasetools_check_target_files_vintf",
    defaults: [
        "releasetools_library_defaults",
        "releasetools_check_target_files_vintf_defaults",
    ],
}

python_library_host {
python_library_host {
    name: "releasetools_common",
    name: "releasetools_common",
    defaults: ["releasetools_library_defaults"],
    defaults: ["releasetools_library_defaults"],
@@ -265,6 +287,14 @@ python_binary_host {
    ],
    ],
}
}


python_binary_host {
    name: "check_target_files_vintf",
    defaults: [
        "releasetools_binary_defaults",
        "releasetools_check_target_files_vintf_defaults"
    ],
}

python_binary_host {
python_binary_host {
    name: "img_from_target_files",
    name: "img_from_target_files",
    defaults: [
    defaults: [
@@ -305,6 +335,7 @@ python_binary_host {
    libs: [
    libs: [
        "releasetools_add_img_to_target_files",
        "releasetools_add_img_to_target_files",
        "releasetools_build_super_image",
        "releasetools_build_super_image",
        "releasetools_check_target_files_vintf",
        "releasetools_common",
        "releasetools_common",
        "releasetools_img_from_target_files",
        "releasetools_img_from_target_files",
        "releasetools_ota_from_target_files",
        "releasetools_ota_from_target_files",
@@ -396,13 +427,14 @@ python_defaults {
        "releasetools_apex_utils",
        "releasetools_apex_utils",
        "releasetools_build_image",
        "releasetools_build_image",
        "releasetools_build_super_image",
        "releasetools_build_super_image",
        "releasetools_check_target_files_vintf",
        "releasetools_common",
        "releasetools_common",
        "releasetools_img_from_target_files",
        "releasetools_img_from_target_files",
        "releasetools_ota_from_target_files",
        "releasetools_ota_from_target_files",
        "releasetools_verity_utils",
        "releasetools_verity_utils",
    ],
    ],
    data: [
    data: [
        "testdata/*",
        "testdata/**/*",
    ],
    ],
    required: [
    required: [
        "otatools",
        "otatools",
+232 −0
Original line number Original line Diff line number Diff line
#!/usr/bin/env python
#
# Copyright (C) 2019 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""
Check VINTF compatibility from a target files package.

Usage: check_target_files_vintf target_files

target_files can be a ZIP file or an extracted target files directory.
"""

import logging
import subprocess
import sys
import os
import zipfile

import common

logger = logging.getLogger(__name__)

OPTIONS = common.OPTIONS

# Keys are paths that VINTF searches. Must keep in sync with libvintf's search
# paths (VintfObject.cpp).
# These paths are stored in different directories in target files package, so
# we have to search for the correct path and tell checkvintf to remap them.
DIR_SEARCH_PATHS = {
    '/system': ('SYSTEM',),
    '/vendor': ('VENDOR', 'SYSTEM/vendor'),
    '/product': ('PRODUCT', 'SYSTEM/product'),
    '/odm': ('ODM', 'VENDOR/odm'),
}

UNZIP_PATTERN = ['META/*', '*/build.prop']


def GetDirmap(input_tmp):
  dirmap = {}
  for device_path, target_files_rel_paths in DIR_SEARCH_PATHS.items():
    for target_files_rel_path in target_files_rel_paths:
      target_files_path = os.path.join(input_tmp, target_files_rel_path)
      if os.path.isdir(target_files_path):
        dirmap[device_path] = target_files_path
        break
    if device_path not in dirmap:
      raise ValueError("Can't determine path for device path " + device_path +
                       ". Searched the following:" +
                       ("\n".join(target_files_rel_paths)))
  return dirmap


def GetArgsForSkus(info_dict):
  skus = info_dict.get('vintf_odm_manifest_skus', '').strip().split()
  if not skus:
    logger.info("ODM_MANIFEST_SKUS is not defined. Check once without SKUs.")
    skus = ['']
  return [['--property', 'ro.boot.product.hardware.sku=' + sku]
          for sku in skus]


def GetArgsForShippingApiLevel(info_dict):
  shipping_api_level = info_dict['vendor.build.prop'].get(
      'ro.product.first_api_level')
  if not shipping_api_level:
    logger.warning('Cannot determine ro.product.first_api_level')
    return []
  return ['--property', 'ro.product.first_api_level=' + shipping_api_level]


def GetArgsForKernel(input_tmp):
  version_path = os.path.join(input_tmp, 'META/kernel_version.txt')
  config_path = os.path.join(input_tmp, 'META/kernel_configs.txt')

  if not os.path.isfile(version_path) or not os.path.isfile(config_path):
    logger.info('Skipping kernel config checks because ' +
                'PRODUCT_OTA_ENFORCE_VINTF_KERNEL_REQUIREMENTS is not set')
    return []

  with open(version_path) as f:
    version = f.read().strip()

  return ['--kernel', '{}:{}'.format(version, config_path)]


def CheckVintfFromExtractedTargetFiles(input_tmp, info_dict=None):
  """
  Checks VINTF metadata of an extracted target files directory.

  Args:
    inp: path to the directory that contains the extracted target files archive.
    info_dict: The build-time info dict. If None, it will be loaded from inp.

  Returns:
    True if VINTF check is skipped or compatible, False if incompatible. Raise
    a RuntimeError if any error occurs.
  """

  if info_dict is None:
    info_dict = common.LoadInfoDict(input_tmp)

  if info_dict.get('vintf_enforce') != 'true':
    logger.warning('PRODUCT_ENFORCE_VINTF_MANIFEST is not set, skipping checks')
    return True

  dirmap = GetDirmap(input_tmp)
  args_for_skus = GetArgsForSkus(info_dict)
  shipping_api_level_args = GetArgsForShippingApiLevel(info_dict)
  kernel_args = GetArgsForKernel(input_tmp)

  common_command = [
      'checkvintf',
      '--check-compat',
  ]
  for device_path, real_path in dirmap.items():
    common_command += ['--dirmap', '{}:{}'.format(device_path, real_path)]
  common_command += kernel_args
  common_command += shipping_api_level_args

  success = True
  for sku_args in args_for_skus:
    command = common_command + sku_args
    proc = common.Run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    out, err = proc.communicate()
    if proc.returncode == 0:
      logger.info("Command `%s` returns 'compatible'", ' '.join(command))
    elif out.strip() == "INCOMPATIBLE":
      logger.info("Command `%s` returns 'incompatible'", ' '.join(command))
      success = False
    else:
      raise common.ExternalError(
          "Failed to run command '{}' (exit code {}):\nstdout:{}\nstderr:{}"
          .format(' '.join(command), proc.returncode, out, err))
    logger.info("stdout: %s", out)
    logger.info("stderr: %s", err)

  return success


def GetVintfFileList():
  """
  Returns a list of VINTF metadata files that should be read from a target files
  package before executing checkvintf.
  """
  def PathToPatterns(path):
    if path[-1] == '/':
      path += '*'
    for device_path, target_files_rel_paths in DIR_SEARCH_PATHS.items():
      if path.startswith(device_path):
        suffix = path[len(device_path):]
        return [rel_path + suffix for rel_path in target_files_rel_paths]
    raise RuntimeError('Unrecognized path from checkvintf --dump-file-list: ' +
                       path)

  out = common.RunAndCheckOutput(['checkvintf', '--dump-file-list'])
  paths = out.strip().split('\n')
  paths = sum((PathToPatterns(path) for path in paths if path), [])
  return paths


def CheckVintfFromTargetFiles(inp, info_dict=None):
  """
  Checks VINTF metadata of a target files zip.

  Args:
    inp: path to the target files archive.
    info_dict: The build-time info dict. If None, it will be loaded from inp.

  Returns:
    True if VINTF check is skipped or compatible, False if incompatible. Raise
    a RuntimeError if any error occurs.
  """
  input_tmp = common.UnzipTemp(inp, GetVintfFileList() + UNZIP_PATTERN)
  return CheckVintfFromExtractedTargetFiles(input_tmp, info_dict)


def CheckVintf(inp, info_dict=None):
  """
  Checks VINTF metadata of a target files zip or extracted target files
  directory.

  Args:
    inp: path to the (possibly extracted) target files archive.
    info_dict: The build-time info dict. If None, it will be loaded from inp.

  Returns:
    True if VINTF check is skipped or compatible, False if incompatible. Raise
    a RuntimeError if any error occurs.
  """
  if os.path.isdir(inp):
    logger.info('Checking VINTF compatibility extracted target files...')
    return CheckVintfFromExtractedTargetFiles(inp, info_dict)

  if zipfile.is_zipfile(inp):
    logger.info('Checking VINTF compatibility target files...')
    return CheckVintfFromTargetFiles(inp, info_dict)

  raise ValueError('{} is not a valid directory or zip file'.format(inp))


def main(argv):
  args = common.ParseOptions(argv, __doc__)
  if len(args) != 1:
    common.Usage(__doc__)
    sys.exit(1)
  common.InitLogging()
  if not CheckVintf(args[0]):
    sys.exit(1)


if __name__ == '__main__':
  try:
    common.CloseInheritedPipes()
    main(sys.argv[1:])
  except common.ExternalError:
    logger.exception('\n   ERROR:\n')
    sys.exit(1)
  finally:
    common.Cleanup()
+4 −4
Original line number Original line Diff line number Diff line
@@ -87,6 +87,7 @@ import zipfile


import add_img_to_target_files
import add_img_to_target_files
import build_super_image
import build_super_image
import check_target_files_vintf
import common
import common
import img_from_target_files
import img_from_target_files
import ota_from_target_files
import ota_from_target_files
@@ -117,8 +118,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 +162,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/*',
@@ -910,6 +907,9 @@ def merge_target_files(temp_dir, framework_target_files, framework_item_list,
      vendor_target_files, vendor_item_list, framework_misc_info_keys,
      vendor_target_files, vendor_item_list, framework_misc_info_keys,
      rebuild_recovery)
      rebuild_recovery)


  if not check_target_files_vintf.CheckVintf(output_target_files_temp_dir):
    raise RuntimeError("Incompatible VINTF metadata")

  generate_images(output_target_files_temp_dir, rebuild_recovery)
  generate_images(output_target_files_temp_dir, rebuild_recovery)


  generate_super_empty_image(output_target_files_temp_dir, output_super_empty)
  generate_super_empty_image(output_target_files_temp_dir, output_super_empty)
+23 −101
Original line number Original line Diff line number Diff line
@@ -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)
Loading