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

Commit c3760a01 authored by Daniel Zheng's avatar Daniel Zheng
Browse files

remove care_map_generator dependency

care_map is no longer used within android OTA and hasn't been used in a
while. Removing the logic to generate care_maps inside of rthe build
system

Test: th
Change-Id: I6e78a2dfb5ce65b815eb10c2cf0e3397416b5f99
parent 40765fff
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -5793,7 +5793,6 @@ INTERNAL_OTATOOLS_MODULES := \
  build_super_image \
  build_verity_metadata \
  build_verity_tree \
  care_map_generator \
  check_ota_package_signature \
  check_target_files_signatures \
  check_target_files_vintf \
+0 −1
Original line number Diff line number Diff line
@@ -130,7 +130,6 @@ cc_genrule {
        ":build_super_image",
        ":build_verity_metadata",
        ":build_verity_tree",
        ":care_map_generator",
        ":check_ota_package_signature",
        ":check_target_files_signatures",
        ":check_target_files_vintf",
+0 −1
Original line number Diff line number Diff line
@@ -40,7 +40,6 @@ python_defaults {
        "libavbtool",
    ],
    required: [
        "care_map_generator",
        "mkbootimg",
    ],
}
+0 −94
Original line number Diff line number Diff line
@@ -159,87 +159,6 @@ def GetCareMap(which, imgname):
  return [which, care_map_ranges.to_string_raw()]


def AddCareMapForAbOta(output_file, ab_partitions, image_paths):
  """Generates and adds care_map.pb for a/b partition that has care_map.

  Args:
    output_file: The output zip file (needs to be already open),
        or file path to write care_map.pb.
    ab_partitions: The list of A/B partitions.
    image_paths: A map from the partition name to the image path.
  """
  if not output_file:
    raise ExternalError('Expected output_file for AddCareMapForAbOta')

  care_map_list = []
  for partition in ab_partitions:
    partition = partition.strip()
    if partition not in PARTITIONS_WITH_CARE_MAP:
      continue

    verity_block_device = "{}_verity_block_device".format(partition)
    avb_hashtree_enable = "avb_{}_hashtree_enable".format(partition)
    if (verity_block_device in OPTIONS.info_dict or
            OPTIONS.info_dict.get(avb_hashtree_enable) == "true"):
      if partition not in image_paths:
        logger.warning('Potential partition with care_map missing from images: %s',
                       partition)
        continue
      image_path = image_paths[partition]
      if not os.path.exists(image_path):
        raise ExternalError('Expected image at path {}'.format(image_path))

      care_map = GetCareMap(partition, image_path)
      if not care_map:
        continue
      care_map_list += care_map

      # adds fingerprint field to the care_map
      # TODO(xunchang) revisit the fingerprint calculation for care_map.
      partition_props = OPTIONS.info_dict.get(partition + ".build.prop")
      prop_name_list = ["ro.{}.build.fingerprint".format(partition),
                        "ro.{}.build.thumbprint".format(partition)]

      present_props = [x for x in prop_name_list if
                       partition_props and partition_props.GetProp(x)]
      if not present_props:
        logger.warning(
            "fingerprint is not present for partition %s", partition)
        property_id, fingerprint = "unknown", "unknown"
      else:
        property_id = present_props[0]
        fingerprint = partition_props.GetProp(property_id)
      care_map_list += [property_id, fingerprint]

  if not care_map_list:
    return

  # Converts the list into proto buf message by calling care_map_generator; and
  # writes the result to a temp file.
  temp_care_map_text = MakeTempFile(prefix="caremap_text-",
                                           suffix=".txt")
  with open(temp_care_map_text, 'w') as text_file:
    text_file.write('\n'.join(care_map_list))

  temp_care_map = MakeTempFile(prefix="caremap-", suffix=".pb")
  care_map_gen_cmd = ["care_map_generator", temp_care_map_text, temp_care_map]
  RunAndCheckOutput(care_map_gen_cmd)

  if not isinstance(output_file, zipfile.ZipFile):
    shutil.copy(temp_care_map, output_file)
    return
  # output_file is a zip file
  care_map_path = "META/care_map.pb"
  if care_map_path in output_file.namelist():
    # Copy the temp file into the OPTIONS.input_tmp dir and update the
    # replace_updated_files_list used by add_img_to_target_files
    if not OPTIONS.replace_updated_files_list:
      OPTIONS.replace_updated_files_list = []
    shutil.copy(temp_care_map, os.path.join(OPTIONS.input_tmp, care_map_path))
    OPTIONS.replace_updated_files_list.append(care_map_path)
  else:
    ZipWrite(output_file, temp_care_map, arcname=care_map_path)


class OutputFile(object):
  """A helper class to write a generated file to the given dir or zip.
@@ -1149,19 +1068,6 @@ def AddImagesToTargetFiles(filename):
  banner("radio")
  ab_partitions_txt = os.path.join(OPTIONS.input_tmp, "META",
                                   "ab_partitions.txt")
  if os.path.exists(ab_partitions_txt):
    with open(ab_partitions_txt) as f:
      ab_partitions = f.read().splitlines()

    # For devices using A/B update, make sure we have all the needed images
    # ready under IMAGES/ or RADIO/.
    CheckAbOtaImages(output_zip, ab_partitions)

    # Generate care_map.pb for ab_partitions, then write this file to
    # target_files package.
    output_care_map = os.path.join(OPTIONS.input_tmp, "META", "care_map.pb")
    AddCareMapForAbOta(output_zip if output_zip else output_care_map,
                       ab_partitions, partitions)

  # Radio images that need to be packed into IMAGES/, and product-img.zip.
  pack_radioimages_txt = os.path.join(
+1 −256
Original line number Diff line number Diff line
@@ -23,7 +23,7 @@ import common
import test_utils
from add_img_to_target_files import (
    AddPackRadioImages,
    AddCareMapForAbOta, GetCareMap,
    GetCareMap,
    CheckAbOtaImages)
from rangelib import RangeSet

@@ -121,261 +121,6 @@ class AddImagesToTargetFilesTest(test_utils.ReleaseToolsTestCase):
    self.assertRaises(AssertionError, AddPackRadioImages, None,
                      images + ['baz'])

  @staticmethod
  def _test_AddCareMapForAbOta():
    """Helper function to set up the test for test_AddCareMapForAbOta()."""
    OPTIONS.info_dict = {
        'system_verity_block_device': '/dev/block/system',
        'vendor_verity_block_device': '/dev/block/vendor',
        'system.build.prop': common.PartitionBuildProps.FromDictionary(
            'system', {
                'ro.system.build.fingerprint':
                'google/sailfish/12345:user/dev-keys'}
        ),
        'vendor.build.prop': common.PartitionBuildProps.FromDictionary(
            'vendor', {
                'ro.vendor.build.fingerprint':
                'google/sailfish/678:user/dev-keys'}
        ),
    }

    # Prepare the META/ folder.
    meta_path = os.path.join(OPTIONS.input_tmp, 'META')
    if not os.path.exists(meta_path):
      os.mkdir(meta_path)

    system_image = test_utils.construct_sparse_image([
        (0xCAC1, 6),
        (0xCAC3, 4),
        (0xCAC1, 6)], "system")
    vendor_image = test_utils.construct_sparse_image([
        (0xCAC2, 10)], "vendor")

    image_paths = {
        'system': system_image,
        'vendor': vendor_image,
    }
    return image_paths

  def _verifyCareMap(self, expected, file_name):
    """Parses the care_map.pb; and checks the content in plain text."""
    text_file = common.MakeTempFile(prefix="caremap-", suffix=".txt")

    # Calls an external binary to convert the proto message.
    cmd = ["care_map_generator", "--parse_proto", file_name, text_file]
    common.RunAndCheckOutput(cmd)

    with open(text_file) as verify_fp:
      plain_text = verify_fp.read()
    self.assertEqual('\n'.join(expected), plain_text)

  @test_utils.SkipIfExternalToolsUnavailable()
  def test_AddCareMapForAbOta(self):
    image_paths = self._test_AddCareMapForAbOta()

    care_map_file = os.path.join(OPTIONS.input_tmp, 'META', 'care_map.pb')
    AddCareMapForAbOta(care_map_file, ['system', 'vendor'], image_paths)

    expected = ['system', RangeSet("0-5 10-15").to_string_raw(),
                "ro.system.build.fingerprint",
                "google/sailfish/12345:user/dev-keys",
                'vendor', RangeSet("0-9").to_string_raw(),
                "ro.vendor.build.fingerprint",
                "google/sailfish/678:user/dev-keys"]

    self._verifyCareMap(expected, care_map_file)

  @test_utils.SkipIfExternalToolsUnavailable()
  def test_AddCareMapForAbOta_withNonCareMapPartitions(self):
    """Partitions without care_map should be ignored."""
    image_paths = self._test_AddCareMapForAbOta()

    care_map_file = os.path.join(OPTIONS.input_tmp, 'META', 'care_map.pb')
    AddCareMapForAbOta(
        care_map_file, ['boot', 'system', 'vendor', 'vbmeta'], image_paths)

    expected = ['system', RangeSet("0-5 10-15").to_string_raw(),
                "ro.system.build.fingerprint",
                "google/sailfish/12345:user/dev-keys",
                'vendor', RangeSet("0-9").to_string_raw(),
                "ro.vendor.build.fingerprint",
                "google/sailfish/678:user/dev-keys"]

    self._verifyCareMap(expected, care_map_file)

  @test_utils.SkipIfExternalToolsUnavailable()
  def test_AddCareMapForAbOta_withAvb(self):
    """Tests the case for device using AVB."""
    image_paths = self._test_AddCareMapForAbOta()
    OPTIONS.info_dict = {
        'avb_system_hashtree_enable': 'true',
        'avb_vendor_hashtree_enable': 'true',
        'system.build.prop': common.PartitionBuildProps.FromDictionary(
            'system', {
                'ro.system.build.fingerprint':
                'google/sailfish/12345:user/dev-keys'}
        ),
        'vendor.build.prop': common.PartitionBuildProps.FromDictionary(
            'vendor', {
                'ro.vendor.build.fingerprint':
                'google/sailfish/678:user/dev-keys'}
        ),
    }

    care_map_file = os.path.join(OPTIONS.input_tmp, 'META', 'care_map.pb')
    AddCareMapForAbOta(care_map_file, ['system', 'vendor'], image_paths)

    expected = ['system', RangeSet("0-5 10-15").to_string_raw(),
                "ro.system.build.fingerprint",
                "google/sailfish/12345:user/dev-keys",
                'vendor', RangeSet("0-9").to_string_raw(),
                "ro.vendor.build.fingerprint",
                "google/sailfish/678:user/dev-keys"]

    self._verifyCareMap(expected, care_map_file)

  @test_utils.SkipIfExternalToolsUnavailable()
  def test_AddCareMapForAbOta_noFingerprint(self):
    """Tests the case for partitions without fingerprint."""
    image_paths = self._test_AddCareMapForAbOta()
    OPTIONS.info_dict = {
        'system_verity_block_device': '/dev/block/system',
        'vendor_verity_block_device': '/dev/block/vendor',
    }

    care_map_file = os.path.join(OPTIONS.input_tmp, 'META', 'care_map.pb')
    AddCareMapForAbOta(care_map_file, ['system', 'vendor'], image_paths)

    expected = ['system', RangeSet("0-5 10-15").to_string_raw(), "unknown",
                "unknown", 'vendor', RangeSet(
        "0-9").to_string_raw(), "unknown",
        "unknown"]

    self._verifyCareMap(expected, care_map_file)

  @test_utils.SkipIfExternalToolsUnavailable()
  def test_AddCareMapForAbOta_withThumbprint(self):
    """Tests the case for partitions with thumbprint."""
    image_paths = self._test_AddCareMapForAbOta()
    OPTIONS.info_dict = {
        'system_verity_block_device': '/dev/block/system',
        'vendor_verity_block_device': '/dev/block/vendor',
        'system.build.prop': common.PartitionBuildProps.FromDictionary(
            'system', {
                'ro.system.build.thumbprint':
                'google/sailfish/123:user/dev-keys'}
        ),
        'vendor.build.prop': common.PartitionBuildProps.FromDictionary(
            'vendor', {
                'ro.vendor.build.thumbprint':
                'google/sailfish/456:user/dev-keys'}
        ),
    }

    care_map_file = os.path.join(OPTIONS.input_tmp, 'META', 'care_map.pb')
    AddCareMapForAbOta(care_map_file, ['system', 'vendor'], image_paths)

    expected = ['system', RangeSet("0-5 10-15").to_string_raw(),
                "ro.system.build.thumbprint",
                "google/sailfish/123:user/dev-keys",
                'vendor', RangeSet("0-9").to_string_raw(),
                "ro.vendor.build.thumbprint",
                "google/sailfish/456:user/dev-keys"]

    self._verifyCareMap(expected, care_map_file)

  @test_utils.SkipIfExternalToolsUnavailable()
  def test_AddCareMapForAbOta_skipPartition(self):
    image_paths = self._test_AddCareMapForAbOta()
    test_utils.erase_avb_footer(image_paths["vendor"])

    care_map_file = os.path.join(OPTIONS.input_tmp, 'META', 'care_map.pb')
    AddCareMapForAbOta(care_map_file, ['system', 'vendor'], image_paths)

    expected = ['system', RangeSet("0-5 10-15").to_string_raw(),
                "ro.system.build.fingerprint",
                "google/sailfish/12345:user/dev-keys"]

    self._verifyCareMap(expected, care_map_file)

  @test_utils.SkipIfExternalToolsUnavailable()
  def test_AddCareMapForAbOta_skipAllPartitions(self):
    image_paths = self._test_AddCareMapForAbOta()
    test_utils.erase_avb_footer(image_paths["system"])
    test_utils.erase_avb_footer(image_paths["vendor"])

    care_map_file = os.path.join(OPTIONS.input_tmp, 'META', 'care_map.pb')
    AddCareMapForAbOta(care_map_file, ['system', 'vendor'], image_paths)

    self.assertFalse(os.path.exists(care_map_file))

  def test_AddCareMapForAbOta_verityNotEnabled(self):
    """No care_map.pb should be generated if verity not enabled."""
    image_paths = self._test_AddCareMapForAbOta()
    OPTIONS.info_dict = {}
    care_map_file = os.path.join(OPTIONS.input_tmp, 'META', 'care_map.pb')
    AddCareMapForAbOta(care_map_file, ['system', 'vendor'], image_paths)

    self.assertFalse(os.path.exists(care_map_file))

  def test_AddCareMapForAbOta_missingImageFile(self):
    """Missing image file should be considered fatal."""
    image_paths = self._test_AddCareMapForAbOta()
    image_paths['vendor'] = ''
    care_map_file = os.path.join(OPTIONS.input_tmp, 'META', 'care_map.pb')
    self.assertRaises(common.ExternalError, AddCareMapForAbOta, care_map_file,
                      ['system', 'vendor'], image_paths)

  @test_utils.SkipIfExternalToolsUnavailable()
  def test_AddCareMapForAbOta_zipOutput(self):
    """Tests the case with ZIP output."""
    image_paths = self._test_AddCareMapForAbOta()

    output_file = common.MakeTempFile(suffix='.zip')
    with zipfile.ZipFile(output_file, 'w', allowZip64=True) as output_zip:
      AddCareMapForAbOta(output_zip, ['system', 'vendor'], image_paths)

    care_map_name = "META/care_map.pb"
    temp_dir = common.MakeTempDir()
    with zipfile.ZipFile(output_file, 'r', allowZip64=True) as verify_zip:
      self.assertTrue(care_map_name in verify_zip.namelist())
      verify_zip.extract(care_map_name, path=temp_dir)

    expected = ['system', RangeSet("0-5 10-15").to_string_raw(),
                "ro.system.build.fingerprint",
                "google/sailfish/12345:user/dev-keys",
                'vendor', RangeSet("0-9").to_string_raw(),
                "ro.vendor.build.fingerprint",
                "google/sailfish/678:user/dev-keys"]
    self._verifyCareMap(expected, os.path.join(temp_dir, care_map_name))

  @test_utils.SkipIfExternalToolsUnavailable()
  def test_AddCareMapForAbOta_zipOutput_careMapEntryExists(self):
    """Tests the case with ZIP output which already has care_map entry."""
    image_paths = self._test_AddCareMapForAbOta()

    output_file = common.MakeTempFile(suffix='.zip')
    with zipfile.ZipFile(output_file, 'w', allowZip64=True) as output_zip:
      # Create an existing META/care_map.pb entry.
      common.ZipWriteStr(output_zip, 'META/care_map.pb',
                         'fake care_map.pb')

      # Request to add META/care_map.pb again.
      AddCareMapForAbOta(output_zip, ['system', 'vendor'], image_paths)

    # The one under OPTIONS.input_tmp must have been replaced.
    care_map_file = os.path.join(OPTIONS.input_tmp, 'META', 'care_map.pb')
    expected = ['system', RangeSet("0-5 10-15").to_string_raw(),
                "ro.system.build.fingerprint",
                "google/sailfish/12345:user/dev-keys",
                'vendor', RangeSet("0-9").to_string_raw(),
                "ro.vendor.build.fingerprint",
                "google/sailfish/678:user/dev-keys"]

    self._verifyCareMap(expected, care_map_file)

    # The existing entry should be scheduled to be replaced.
    self.assertIn('META/care_map.pb', OPTIONS.replace_updated_files_list)

  def test_GetCareMap(self):
    sparse_image = test_utils.construct_sparse_image([