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

Commit e5083153 authored by Tianjie Xu's avatar Tianjie Xu Committed by Automerger Merge Worker
Browse files

Merge changes I637dea34,I4a9fa35c,I5c952cd2 into rvc-dev am: 8098b73e

Change-Id: If75ec310a8a8ca4bcaa922861a48add85565323d
parents 8878ac2e 8098b73e
Loading
Loading
Loading
Loading
+43 −19
Original line number Diff line number Diff line
@@ -189,6 +189,13 @@ A/B OTA specific options
  --payload_signer_key_size <key_size>
      Deprecated. Use the '--payload_signer_maximum_signature_size' instead.

  --boot_variable_file <path>
      A file that contains the possible values of ro.boot.* properties. It's
      used to calculate the possible runtime fingerprints when some
      ro.product.* properties are overridden by the 'import' statement.
      The file expects one property per line, and each line has the following
      format: 'prop_name=value1,value2'. e.g. 'ro.boot.product.sku=std,pro'

  --skip_postinstall
      Skip the postinstall hooks when generating an A/B OTA package (default:
      False). Note that this discards ALL the hooks, including non-optional
@@ -258,7 +265,7 @@ OPTIONS.skip_compatibility_check = False
OPTIONS.output_metadata_path = None
OPTIONS.disable_fec_computation = False
OPTIONS.force_non_ab = False
OPTIONS.boot_variable_values = None
OPTIONS.boot_variable_file = None


METADATA_NAME = 'META-INF/com/android/metadata'
@@ -931,8 +938,18 @@ def GetPackageMetadata(target_info, source_info=None):
  assert isinstance(target_info, common.BuildInfo)
  assert source_info is None or isinstance(source_info, common.BuildInfo)

  separator = '|'

  boot_variable_values = {}
  if OPTIONS.boot_variable_file:
    d = common.LoadDictionaryFromFile(OPTIONS.boot_variable_file)
    for key, values in d.items():
      boot_variable_values[key] = [val.strip() for val in values.split(',')]

  post_build_devices, post_build_fingerprints = \
      CalculateRuntimeDevicesAndFingerprints(target_info, boot_variable_values)
  metadata = {
      'post-build' : target_info.fingerprint,
      'post-build': separator.join(sorted(post_build_fingerprints)),
      'post-build-incremental': target_info.GetBuildProp(
          'ro.build.version.incremental'),
      'post-sdk-level': target_info.GetBuildProp(
@@ -955,12 +972,15 @@ def GetPackageMetadata(target_info, source_info=None):

  is_incremental = source_info is not None
  if is_incremental:
    metadata['pre-build'] = source_info.fingerprint
    pre_build_devices, pre_build_fingerprints = \
        CalculateRuntimeDevicesAndFingerprints(source_info,
                                               boot_variable_values)
    metadata['pre-build'] = separator.join(sorted(pre_build_fingerprints))
    metadata['pre-build-incremental'] = source_info.GetBuildProp(
        'ro.build.version.incremental')
    metadata['pre-device'] = source_info.device
    metadata['pre-device'] = separator.join(sorted(pre_build_devices))
  else:
    metadata['pre-device'] = target_info.device
    metadata['pre-device'] = separator.join(sorted(post_build_devices))

  # Use the actual post-timestamp, even for a downgrade case.
  metadata['post-timestamp'] = target_info.GetBuildProp('ro.build.date.utc')
@@ -1972,24 +1992,24 @@ def GenerateNonAbOtaPackage(target_file, output_file, source_file=None):
          output_file)


def CalculateRuntimeFingerprints():
  """Returns a set of runtime fingerprints based on the boot variables."""
def CalculateRuntimeDevicesAndFingerprints(build_info, boot_variable_values):
  """Returns a tuple of sets for runtime devices and fingerprints"""

  build_info = common.BuildInfo(OPTIONS.info_dict, OPTIONS.oem_dicts)
  device_names = {build_info.device}
  fingerprints = {build_info.fingerprint}

  if not OPTIONS.boot_variable_values:
    return fingerprints
  if not boot_variable_values:
    return device_names, fingerprints

  # Calculate all possible combinations of the values for the boot variables.
  keys = OPTIONS.boot_variable_values.keys()
  value_list = OPTIONS.boot_variable_values.values()
  keys = boot_variable_values.keys()
  value_list = boot_variable_values.values()
  combinations = [dict(zip(keys, values))
                  for values in itertools.product(*value_list)]
  for placeholder_values in combinations:
    # Reload the info_dict as some build properties may change their values
    # based on the value of ro.boot* properties.
    info_dict = copy.deepcopy(OPTIONS.info_dict)
    info_dict = copy.deepcopy(build_info.info_dict)
    for partition in common.PARTITIONS_WITH_CARE_MAP:
      partition_prop_key = "{}.build.prop".format(partition)
      old_props = info_dict[partition_prop_key]
@@ -1997,9 +2017,10 @@ def CalculateRuntimeFingerprints():
          old_props.input_file, partition, placeholder_values)
    info_dict["build.prop"] = info_dict["system.build.prop"]

    build_info = common.BuildInfo(info_dict, OPTIONS.oem_dicts)
    fingerprints.add(build_info.fingerprint)
  return fingerprints
    new_build_info = common.BuildInfo(info_dict, build_info.oem_dicts)
    device_names.add(new_build_info.device)
    fingerprints.add(new_build_info.fingerprint)
  return device_names, fingerprints


def main(argv):
@@ -2077,6 +2098,8 @@ def main(argv):
      OPTIONS.disable_fec_computation = True
    elif o == "--force_non_ab":
      OPTIONS.force_non_ab = True
    elif o == "--boot_variable_file":
      OPTIONS.boot_variable_file = a
    else:
      return False
    return True
@@ -2114,6 +2137,7 @@ def main(argv):
                                 "output_metadata_path=",
                                 "disable_fec_computation",
                                 "force_non_ab",
                                 "boot_variable_file=",
                             ], extra_option_handler=option_handler)

  if len(args) != 2:
+136 −22
Original line number Diff line number Diff line
@@ -27,7 +27,7 @@ from ota_from_target_files import (
    GetTargetFilesZipWithoutPostinstallConfig, NonAbOtaPropertyFiles,
    Payload, PayloadSigner, POSTINSTALL_CONFIG, PropertyFiles,
    StreamingPropertyFiles, WriteFingerprintAssertion,
    CalculateRuntimeFingerprints)
    CalculateRuntimeDevicesAndFingerprints)


def construct_target_files(secondary=False):
@@ -1334,6 +1334,9 @@ class RuntimeFingerprintTest(test_utils.ReleaseToolsTestCase):
      'ro.build.version.incremental=version-incremental',
      'ro.build.type=build-type',
      'ro.build.tags=build-tags',
      'ro.build.version.sdk=30',
      'ro.build.version.security_patch=2020',
      'ro.build.date.utc=12345678'
  ]

  VENDOR_BUILD_PROP = [
@@ -1345,11 +1348,12 @@ class RuntimeFingerprintTest(test_utils.ReleaseToolsTestCase):
  def setUp(self):
    common.OPTIONS.oem_dicts = None
    self.test_dir = common.MakeTempDir()
    self.writeFiles({'META/misc_info.txt': '\n'.join(self.MISC_INFO)})
    self.writeFiles({'META/misc_info.txt': '\n'.join(self.MISC_INFO)},
                    self.test_dir)

  def writeFiles(self, contents_dict):
  def writeFiles(self, contents_dict, out_dir):
    for path, content in contents_dict.items():
      abs_path = os.path.join(self.test_dir, path)
      abs_path = os.path.join(out_dir, path)
      dir_name = os.path.dirname(abs_path)
      if not os.path.exists(dir_name):
        os.makedirs(dir_name)
@@ -1371,12 +1375,14 @@ class RuntimeFingerprintTest(test_utils.ReleaseToolsTestCase):
    self.writeFiles({
        'SYSTEM/build.prop': '\n'.join(build_prop),
        'VENDOR/build.prop': '\n'.join(self.VENDOR_BUILD_PROP),
    })
    common.OPTIONS.info_dict = common.LoadInfoDict(self.test_dir)
    }, self.test_dir)

    self.assertEqual({
        self.constructFingerprint('product-brand/product-name/product-device')
    }, CalculateRuntimeFingerprints())
    build_info = common.BuildInfo(common.LoadInfoDict(self.test_dir))
    expected = ({'product-device'},
                {self.constructFingerprint(
                    'product-brand/product-name/product-device')})
    self.assertEqual(expected,
                     CalculateRuntimeDevicesAndFingerprints(build_info, {}))

  def test_CalculatePossibleFingerprints_single_override(self):
    vendor_build_prop = copy.deepcopy(self.VENDOR_BUILD_PROP)
@@ -1390,20 +1396,22 @@ class RuntimeFingerprintTest(test_utils.ReleaseToolsTestCase):
        'ro.product.vendor.name=vendor-product-std',
        'VENDOR/etc/build_pro.prop':
        'ro.product.vendor.name=vendor-product-pro',
    })
    common.OPTIONS.info_dict = common.LoadInfoDict(self.test_dir)
    common.OPTIONS.boot_variable_values = {
        'ro.boot.sku_name': ['std', 'pro']
    }
    }, self.test_dir)

    build_info = common.BuildInfo(common.LoadInfoDict(self.test_dir))
    boot_variable_values = {'ro.boot.sku_name': ['std', 'pro']}

    self.assertEqual({
    expected = ({'vendor-product-device'}, {
        self.constructFingerprint(
            'vendor-product-brand/vendor-product-name/vendor-product-device'),
        self.constructFingerprint(
            'vendor-product-brand/vendor-product-std/vendor-product-device'),
        self.constructFingerprint(
            'vendor-product-brand/vendor-product-pro/vendor-product-device'),
    }, CalculateRuntimeFingerprints())
    })
    self.assertEqual(
        expected, CalculateRuntimeDevicesAndFingerprints(
            build_info, boot_variable_values))

  def test_CalculatePossibleFingerprints_multiple_overrides(self):
    vendor_build_prop = copy.deepcopy(self.VENDOR_BUILD_PROP)
@@ -1422,14 +1430,17 @@ class RuntimeFingerprintTest(test_utils.ReleaseToolsTestCase):
        'ro.product.vendor.name=vendor-product-pro',
        'VENDOR/etc/build_product2.prop':
        'ro.product.vendor.device=vendor-device-product2',
    })
    common.OPTIONS.info_dict = common.LoadInfoDict(self.test_dir)
    common.OPTIONS.boot_variable_values = {
    }, self.test_dir)

    build_info = common.BuildInfo(common.LoadInfoDict(self.test_dir))
    boot_variable_values = {
        'ro.boot.sku_name': ['std', 'pro'],
        'ro.boot.device_name': ['product1', 'product2'],
    }

    self.assertEqual({
    expected_devices = {'vendor-product-device', 'vendor-device-product1',
                        'vendor-device-product2'}
    expected_fingerprints = {
        self.constructFingerprint(
            'vendor-product-brand/vendor-product-name/vendor-product-device'),
        self.constructFingerprint(
@@ -1439,5 +1450,108 @@ class RuntimeFingerprintTest(test_utils.ReleaseToolsTestCase):
        self.constructFingerprint(
            'vendor-product-brand/vendor-product-std/vendor-device-product2'),
        self.constructFingerprint(
            'vendor-product-brand/vendor-product-pro/vendor-device-product2'),
    }, CalculateRuntimeFingerprints())
            'vendor-product-brand/vendor-product-pro/vendor-device-product2')
    }
    self.assertEqual((expected_devices, expected_fingerprints),
                     CalculateRuntimeDevicesAndFingerprints(
                         build_info, boot_variable_values))

  def test_GetPackageMetadata_full_package(self):
    vendor_build_prop = copy.deepcopy(self.VENDOR_BUILD_PROP)
    vendor_build_prop.extend([
        'import /vendor/etc/build_${ro.boot.sku_name}.prop',
    ])
    self.writeFiles({
        'SYSTEM/build.prop': '\n'.join(self.BUILD_PROP),
        'VENDOR/build.prop': '\n'.join(vendor_build_prop),
        'VENDOR/etc/build_std.prop':
        'ro.product.vendor.name=vendor-product-std',
        'VENDOR/etc/build_pro.prop':
        'ro.product.vendor.name=vendor-product-pro',
    }, self.test_dir)

    common.OPTIONS.boot_variable_file = common.MakeTempFile()
    with open(common.OPTIONS.boot_variable_file, 'w') as f:
      f.write('ro.boot.sku_name=std,pro')

    build_info = common.BuildInfo(common.LoadInfoDict(self.test_dir))
    metadata = GetPackageMetadata(build_info)
    self.assertEqual('vendor-product-device', metadata['pre-device'])
    fingerprints = [
        self.constructFingerprint(
            'vendor-product-brand/vendor-product-name/vendor-product-device'),
        self.constructFingerprint(
            'vendor-product-brand/vendor-product-pro/vendor-product-device'),
        self.constructFingerprint(
            'vendor-product-brand/vendor-product-std/vendor-product-device'),
    ]
    self.assertEqual('|'.join(fingerprints), metadata['post-build'])

  def test_GetPackageMetadata_incremental_package(self):
    vendor_build_prop = copy.deepcopy(self.VENDOR_BUILD_PROP)
    vendor_build_prop.extend([
        'import /vendor/etc/build_${ro.boot.sku_name}.prop',
    ])
    self.writeFiles({
        'SYSTEM/build.prop': '\n'.join(self.BUILD_PROP),
        'VENDOR/build.prop': '\n'.join(vendor_build_prop),
        'VENDOR/etc/build_std.prop':
        'ro.product.vendor.device=vendor-device-std',
        'VENDOR/etc/build_pro.prop':
        'ro.product.vendor.device=vendor-device-pro',
    }, self.test_dir)

    common.OPTIONS.boot_variable_file = common.MakeTempFile()
    with open(common.OPTIONS.boot_variable_file, 'w') as f:
      f.write('ro.boot.sku_name=std,pro')

    source_dir = common.MakeTempDir()
    source_build_prop = [
        'ro.build.version.release=source-version-release',
        'ro.build.id=source-build-id',
        'ro.build.version.incremental=source-version-incremental',
        'ro.build.type=build-type',
        'ro.build.tags=build-tags',
        'ro.build.version.sdk=29',
        'ro.build.version.security_patch=2020',
        'ro.build.date.utc=12340000'
    ]
    self.writeFiles({
        'META/misc_info.txt': '\n'.join(self.MISC_INFO),
        'SYSTEM/build.prop': '\n'.join(source_build_prop),
        'VENDOR/build.prop': '\n'.join(vendor_build_prop),
        'VENDOR/etc/build_std.prop':
        'ro.product.vendor.device=vendor-device-std',
        'VENDOR/etc/build_pro.prop':
        'ro.product.vendor.device=vendor-device-pro',
    }, source_dir)
    common.OPTIONS.incremental_source = source_dir

    target_info = common.BuildInfo(common.LoadInfoDict(self.test_dir))
    source_info = common.BuildInfo(common.LoadInfoDict(source_dir))

    metadata = GetPackageMetadata(target_info, source_info)
    self.assertEqual(
        'vendor-device-pro|vendor-device-std|vendor-product-device',
        metadata['pre-device'])
    suffix = ':source-version-release/source-build-id/' \
             'source-version-incremental:build-type/build-tags'
    pre_fingerprints = [
        'vendor-product-brand/vendor-product-name/vendor-device-pro'
        '{}'.format(suffix),
        'vendor-product-brand/vendor-product-name/vendor-device-std'
        '{}'.format(suffix),
        'vendor-product-brand/vendor-product-name/vendor-product-device'
        '{}'.format(suffix),
    ]
    self.assertEqual('|'.join(pre_fingerprints), metadata['pre-build'])

    post_fingerprints = [
        self.constructFingerprint(
            'vendor-product-brand/vendor-product-name/vendor-device-pro'),
        self.constructFingerprint(
            'vendor-product-brand/vendor-product-name/vendor-device-std'),
        self.constructFingerprint(
            'vendor-product-brand/vendor-product-name/vendor-product-device'),
    ]
    self.assertEqual('|'.join(post_fingerprints), metadata['post-build'])