コード例 #1
0
  def test_GetPackageMetadata_downgrade(self):
    target_info_dict = copy.deepcopy(self.TEST_TARGET_INFO_DICT)
    source_info_dict = copy.deepcopy(self.TEST_SOURCE_INFO_DICT)
    self._test_GetPackageMetadata_swapBuildTimestamps(
        target_info_dict, source_info_dict)

    target_info = common.BuildInfo(target_info_dict, None)
    source_info = common.BuildInfo(source_info_dict, None)
    common.OPTIONS.incremental_source = ''
    common.OPTIONS.downgrade = True
    common.OPTIONS.wipe_user_data = True
    metadata = GetPackageMetadata(target_info, source_info)
    self.assertDictEqual(
        {
            'ota-downgrade' : 'yes',
            'ota-type' : 'BLOCK',
            'ota-wipe' : 'yes',
            'post-build' : 'build-fingerprint-target',
            'post-build-incremental' : 'build-version-incremental-target',
            'post-sdk-level' : '27',
            'post-security-patch-level' : '2017-12-01',
            'post-timestamp' : '1400000000',
            'pre-device' : 'product-device',
            'pre-build' : 'build-fingerprint-source',
            'pre-build-incremental' : 'build-version-incremental-source',
        },
        metadata)
コード例 #2
0
    def test_WriteFingerprintAssertion_with_target_oem_props(self):
        target_info = common.BuildInfo(self.TEST_INFO_DICT_USES_OEM_PROPS,
                                       self.TEST_OEM_DICTS)
        source_info = common.BuildInfo(self.TEST_TARGET_INFO_DICT, None)

        script_writer = test_utils.MockScriptWriter()
        WriteFingerprintAssertion(script_writer, target_info, source_info)
        self.assertEqual([('AssertFingerprintOrThumbprint',
                           'build-fingerprint-target', 'build-thumbprint')],
                         script_writer.lines)
コード例 #3
0
  def test_GetPackageMetadata_unintentionalDowngradeDetected(self):
    target_info_dict = copy.deepcopy(self.TEST_TARGET_INFO_DICT)
    source_info_dict = copy.deepcopy(self.TEST_SOURCE_INFO_DICT)
    self._test_GetPackageMetadata_swapBuildTimestamps(
        target_info_dict, source_info_dict)

    target_info = common.BuildInfo(target_info_dict, None)
    source_info = common.BuildInfo(source_info_dict, None)
    common.OPTIONS.incremental_source = ''
    self.assertRaises(RuntimeError, GetPackageMetadata, target_info,
                      source_info)
コード例 #4
0
    def test_WriteFingerprintAssertion_without_oem_props(self):
        target_info = common.BuildInfo(self.TEST_TARGET_INFO_DICT, None)
        source_info_dict = copy.deepcopy(self.TEST_TARGET_INFO_DICT)
        source_info_dict['build.prop'].build_props['ro.build.fingerprint'] = (
            'source-build-fingerprint')
        source_info = common.BuildInfo(source_info_dict, None)

        script_writer = test_utils.MockScriptWriter()
        WriteFingerprintAssertion(script_writer, target_info, source_info)
        self.assertEqual([('AssertSomeFingerprint', 'source-build-fingerprint',
                           'build-fingerprint-target')], script_writer.lines)
コード例 #5
0
    def test_WriteFingerprintAssertion_with_both_oem_props(self):
        target_info = common.BuildInfo(self.TEST_INFO_DICT_USES_OEM_PROPS,
                                       self.TEST_OEM_DICTS)
        source_info_dict = copy.deepcopy(self.TEST_INFO_DICT_USES_OEM_PROPS)
        source_info_dict['build.prop'].build_props['ro.build.thumbprint'] = (
            'source-build-thumbprint')
        source_info = common.BuildInfo(source_info_dict, self.TEST_OEM_DICTS)

        script_writer = test_utils.MockScriptWriter()
        WriteFingerprintAssertion(script_writer, target_info, source_info)
        self.assertEqual([('AssertSomeThumbprint', 'build-thumbprint',
                           'source-build-thumbprint')], script_writer.lines)
コード例 #6
0
def ValidatePartitionFingerprints(input_tmp, info_dict):
    build_info = common.BuildInfo(info_dict)
    if not build_info.avb_enabled:
        logging.info("AVB not enabled, skipping partition fingerprint checks")
        return
    # Expected format:
    #  Prop: com.android.build.vendor.fingerprint -> 'generic/aosp_cf_x86_64_phone/vsoc_x86_64:S/AOSP.MASTER/7335886:userdebug/test-keys'
    #  Prop: com.android.build.vendor_boot.fingerprint -> 'generic/aosp_cf_x86_64_phone/vsoc_x86_64:S/AOSP.MASTER/7335886:userdebug/test-keys'
    p = re.compile(
        r"Prop: com.android.build.(?P<partition>\w+).fingerprint -> '(?P<fingerprint>[\w\/:\.-]+)'"
    )
    for vbmeta_partition in ["vbmeta", "vbmeta_system"]:
        image = os.path.join(input_tmp, "IMAGES", vbmeta_partition + ".img")
        if not os.path.exists(image):
            assert vbmeta_partition != "vbmeta",\
                "{} is a required partition for AVB.".format(
                    vbmeta_partition)
            logging.info("vb partition %s not present, skipping",
                         vbmeta_partition)
            continue

        output = common.RunAndCheckOutput(
            [info_dict["avb_avbtool"], "info_image", "--image", image])
        matches = p.findall(output)
        for (partition, fingerprint) in matches:
            actual_fingerprint = build_info.GetPartitionFingerprint(partition)
            if actual_fingerprint is None:
                logging.warning("Failed to get fingerprint for partition %s",
                                partition)
                continue
            assert fingerprint == actual_fingerprint, "Fingerprint mismatch for partition {}, expected: {} actual: {}".format(
                partition, fingerprint, actual_fingerprint)
コード例 #7
0
 def test_GetPackageMetadata_nonAbOta_incremental(self):
   target_info = common.BuildInfo(self.TEST_TARGET_INFO_DICT, None)
   source_info = common.BuildInfo(self.TEST_SOURCE_INFO_DICT, None)
   common.OPTIONS.incremental_source = ''
   metadata = GetPackageMetadata(target_info, source_info)
   self.assertDictEqual(
       {
           'ota-type' : 'BLOCK',
           'post-build' : 'build-fingerprint-target',
           'post-build-incremental' : 'build-version-incremental-target',
           'post-sdk-level' : '27',
           'post-security-patch-level' : '2017-12-01',
           'post-timestamp' : '1500000000',
           'pre-device' : 'product-device',
           'pre-build' : 'build-fingerprint-source',
           'pre-build-incremental' : 'build-version-incremental-source',
       },
       metadata)
コード例 #8
0
def CreateImage(input_dir, info_dict, what, output_file, block_list=None):
    logger.info("creating %s.img...", what)

    image_props = build_image.ImagePropFromGlobalDict(info_dict, what)
    image_props["timestamp"] = FIXED_FILE_TIMESTAMP

    if what == "system":
        fs_config_prefix = ""
    else:
        fs_config_prefix = what + "_"

    fs_config = os.path.join(
        input_dir, "META/" + fs_config_prefix + "filesystem_config.txt")
    if not os.path.exists(fs_config):
        fs_config = None

    # Override values loaded from info_dict.
    if fs_config:
        image_props["fs_config"] = fs_config
    if block_list:
        image_props["block_list"] = block_list.name

    # Use repeatable ext4 FS UUID and hash_seed UUID (based on partition name and
    # build fingerprint).
    build_info = common.BuildInfo(info_dict)
    uuid_seed = what
    if what != "modules":
        uuid_seed += "-" + build_info.GetPartitionFingerprint(what)
    image_props["uuid"] = str(uuid.uuid5(uuid.NAMESPACE_URL, uuid_seed))
    hash_seed = "hash_seed-" + uuid_seed
    image_props["hash_seed"] = str(uuid.uuid5(uuid.NAMESPACE_URL, hash_seed))

    build_image.BuildImage(os.path.join(input_dir, what.upper()), image_props,
                           output_file.name)

    output_file.Write()
    if block_list:
        block_list.Write()

    # Set the '_image_size' for given image size.
    is_verity_partition = "verity_block_device" in image_props
    verity_supported = (image_props.get("verity") == "true"
                        or image_props.get("avb_enable") == "true")
    is_avb_enable = image_props.get("avb_hashtree_enable") == "true"
    if verity_supported and (is_verity_partition or is_avb_enable):
        image_size = image_props.get("image_size")
        if image_size:
            image_size_key = what + "_image_size"
            info_dict[image_size_key] = int(image_size)

    use_dynamic_size = (info_dict.get("use_dynamic_partition_size") == "true"
                        and what in shlex.split(
                            info_dict.get("dynamic_partition_list",
                                          "").strip()))
    if use_dynamic_size:
        info_dict.update(build_image.GlobalDictFromImageProp(
            image_props, what))
コード例 #9
0
 def test_GetPackageMetadata_abOta_incremental(self):
   target_info_dict = copy.deepcopy(self.TEST_TARGET_INFO_DICT)
   target_info_dict['ab_update'] = 'true'
   target_info = common.BuildInfo(target_info_dict, None)
   source_info = common.BuildInfo(self.TEST_SOURCE_INFO_DICT, None)
   common.OPTIONS.incremental_source = ''
   metadata = GetPackageMetadata(target_info, source_info)
   self.assertDictEqual(
       {
           'ota-type' : 'AB',
           'ota-required-cache' : '0',
           'post-build' : 'build-fingerprint-target',
           'post-build-incremental' : 'build-version-incremental-target',
           'post-sdk-level' : '27',
           'post-security-patch-level' : '2017-12-01',
           'post-timestamp' : '1500000000',
           'pre-device' : 'product-device',
           'pre-build' : 'build-fingerprint-source',
           'pre-build-incremental' : 'build-version-incremental-source',
       },
       metadata)
コード例 #10
0
 def test_GetPackageMetadata_retrofitDynamicPartitions(self):
   target_info = common.BuildInfo(self.TEST_TARGET_INFO_DICT, None)
   common.OPTIONS.retrofit_dynamic_partitions = True
   metadata = GetPackageMetadata(target_info)
   self.assertDictEqual(
       {
           'ota-retrofit-dynamic-partitions' : 'yes',
           'ota-type' : 'BLOCK',
           'post-build' : 'build-fingerprint-target',
           'post-build-incremental' : 'build-version-incremental-target',
           'post-sdk-level' : '27',
           'post-security-patch-level' : '2017-12-01',
           'post-timestamp' : '1500000000',
           'pre-device' : 'product-device',
       },
       metadata)
コード例 #11
0
def WriteBlockIncrementalOTAPackage(target_zip, source_zip, output_file):
  target_info = common.BuildInfo(OPTIONS.target_info_dict, OPTIONS.oem_dicts)
  source_info = common.BuildInfo(OPTIONS.source_info_dict, OPTIONS.oem_dicts)

  target_api_version = target_info["recovery_api_version"]
  source_api_version = source_info["recovery_api_version"]
  if source_api_version == 0:
    logger.warning(
        "Generating edify script for a source that can't install it.")

  script = edify_generator.EdifyGenerator(
      source_api_version, target_info, fstab=source_info["fstab"])

  if target_info.oem_props or source_info.oem_props:
    if not OPTIONS.oem_no_mount:
      source_info.WriteMountOemScript(script)

  metadata = GetPackageMetadata(target_info, source_info)

  if not OPTIONS.no_signing:
    staging_file = common.MakeTempFile(suffix='.zip')
  else:
    staging_file = output_file

  output_zip = zipfile.ZipFile(
      staging_file, "w", compression=zipfile.ZIP_DEFLATED)

  device_specific = common.DeviceSpecificParams(
      source_zip=source_zip,
      source_version=source_api_version,
      source_tmp=OPTIONS.source_tmp,
      target_zip=target_zip,
      target_version=target_api_version,
      target_tmp=OPTIONS.target_tmp,
      output_zip=output_zip,
      script=script,
      metadata=metadata,
      info_dict=source_info)

  source_boot = common.GetBootableImage(
      "/tmp/boot.img", "boot.img", OPTIONS.source_tmp, "BOOT", source_info)
  target_boot = common.GetBootableImage(
      "/tmp/boot.img", "boot.img", OPTIONS.target_tmp, "BOOT", target_info)
  updating_boot = (not OPTIONS.two_step and
                   (source_boot.data != target_boot.data))

  target_recovery = common.GetBootableImage(
      "/tmp/recovery.img", "recovery.img", OPTIONS.target_tmp, "RECOVERY")

  block_diff_dict = GetBlockDifferences(target_zip=target_zip,
                                        source_zip=source_zip,
                                        target_info=target_info,
                                        source_info=source_info,
                                        device_specific=device_specific)

  CheckVintfIfTrebleEnabled(OPTIONS.target_tmp, target_info)

  # Assertions (e.g. device properties check).
  target_info.WriteDeviceAssertions(script, OPTIONS.oem_no_mount)
  device_specific.IncrementalOTA_Assertions()

  # Two-step incremental package strategy (in chronological order,
  # which is *not* the order in which the generated script has
  # things):
  #
  # if stage is not "2/3" or "3/3":
  #    do verification on current system
  #    write recovery image to boot partition
  #    set stage to "2/3"
  #    reboot to boot partition and restart recovery
  # else if stage is "2/3":
  #    write recovery image to recovery partition
  #    set stage to "3/3"
  #    reboot to recovery partition and restart recovery
  # else:
  #    (stage must be "3/3")
  #    perform update:
  #       patch system files, etc.
  #       force full install of new boot image
  #       set up system to update recovery partition on first boot
  #    complete script normally
  #    (allow recovery to mark itself finished and reboot)

  if OPTIONS.two_step:
    if not source_info.get("multistage_support"):
      assert False, "two-step packages not supported by this build"
    fs = source_info["fstab"]["/misc"]
    assert fs.fs_type.upper() == "EMMC", \
        "two-step packages only supported on devices with EMMC /misc partitions"
    bcb_dev = {"bcb_dev": fs.device}
    common.ZipWriteStr(output_zip, "recovery.img", target_recovery.data)
    script.AppendExtra("""
if get_stage("%(bcb_dev)s") == "2/3" then
""" % bcb_dev)

    # Stage 2/3: Write recovery image to /recovery (currently running /boot).
    script.Comment("Stage 2/3")
    script.AppendExtra("sleep(20);\n")
    script.WriteRawImage("/recovery", "recovery.img")
    script.AppendExtra("""
set_stage("%(bcb_dev)s", "3/3");
reboot_now("%(bcb_dev)s", "recovery");
else if get_stage("%(bcb_dev)s") != "3/3" then
""" % bcb_dev)

    # Stage 1/3: (a) Verify the current system.
    script.Comment("Stage 1/3")

  # Dump fingerprints
  script.Print("Source: {}".format(source_info.fingerprint))
  script.Print("Target: {}".format(target_info.fingerprint))

  script.Print("Verifying current system...")

  device_specific.IncrementalOTA_VerifyBegin()

  WriteFingerprintAssertion(script, target_info, source_info)

  # Check the required cache size (i.e. stashed blocks).
  required_cache_sizes = [diff.required_cache for diff in
                          block_diff_dict.values()]
  if updating_boot:
    boot_type, boot_device_expr = common.GetTypeAndDeviceExpr("/boot",
                                                              source_info)
    d = common.Difference(target_boot, source_boot)
    _, _, d = d.ComputePatch()
    if d is None:
      include_full_boot = True
      common.ZipWriteStr(output_zip, "boot.img", target_boot.data)
    else:
      include_full_boot = False

      logger.info(
          "boot      target: %d  source: %d  diff: %d", target_boot.size,
          source_boot.size, len(d))

      common.ZipWriteStr(output_zip, "boot.img.p", d)

      target_expr = 'concat("{}:",{},":{}:{}")'.format(
          boot_type, boot_device_expr, target_boot.size, target_boot.sha1)
      source_expr = 'concat("{}:",{},":{}:{}")'.format(
          boot_type, boot_device_expr, source_boot.size, source_boot.sha1)
      script.PatchPartitionExprCheck(target_expr, source_expr)

      required_cache_sizes.append(target_boot.size)

  if required_cache_sizes:
    script.CacheFreeSpaceCheck(max(required_cache_sizes))

  # Verify the existing partitions.
  for diff in block_diff_dict.values():
    diff.WriteVerifyScript(script, touched_blocks_only=True)

  device_specific.IncrementalOTA_VerifyEnd()

  if OPTIONS.two_step:
    # Stage 1/3: (b) Write recovery image to /boot.
    _WriteRecoveryImageToBoot(script, output_zip)

    script.AppendExtra("""
set_stage("%(bcb_dev)s", "2/3");
reboot_now("%(bcb_dev)s", "");
else
""" % bcb_dev)

    # Stage 3/3: Make changes.
    script.Comment("Stage 3/3")

  script.Comment("---- start making changes here ----")

  device_specific.IncrementalOTA_InstallBegin()

  progress_dict = {partition: 0.1 for partition in block_diff_dict}
  progress_dict["system"] = 1 - len(block_diff_dict) * 0.1

  if OPTIONS.source_info_dict.get("use_dynamic_partitions") == "true":
    if OPTIONS.target_info_dict.get("use_dynamic_partitions") != "true":
      raise RuntimeError(
          "can't generate incremental that disables dynamic partitions")
    dynamic_partitions_diff = common.DynamicPartitionsDifference(
        info_dict=OPTIONS.target_info_dict,
        source_info_dict=OPTIONS.source_info_dict,
        block_diffs=block_diff_dict.values(),
        progress_dict=progress_dict)
    dynamic_partitions_diff.WriteScript(
        script, output_zip, write_verify_script=OPTIONS.verify)
  else:
    for block_diff in block_diff_dict.values():
      block_diff.WriteScript(script, output_zip,
                             progress=progress_dict.get(block_diff.partition),
                             write_verify_script=OPTIONS.verify)

  if OPTIONS.two_step:
    common.ZipWriteStr(output_zip, "boot.img", target_boot.data)
    script.WriteRawImage("/boot", "boot.img")
    logger.info("writing full boot image (forced by two-step mode)")

  if not OPTIONS.two_step:
    if updating_boot:
      if include_full_boot:
        logger.info("boot image changed; including full.")
        script.Print("Installing boot image...")
        script.WriteRawImage("/boot", "boot.img")
      else:
        # Produce the boot image by applying a patch to the current
        # contents of the boot partition, and write it back to the
        # partition.
        logger.info("boot image changed; including patch.")
        script.Print("Patching boot image...")
        script.ShowProgress(0.1, 10)
        target_expr = 'concat("{}:",{},":{}:{}")'.format(
            boot_type, boot_device_expr, target_boot.size, target_boot.sha1)
        source_expr = 'concat("{}:",{},":{}:{}")'.format(
            boot_type, boot_device_expr, source_boot.size, source_boot.sha1)
        script.PatchPartitionExpr(target_expr, source_expr, '"boot.img.p"')
    else:
      logger.info("boot image unchanged; skipping.")

  # Do device-specific installation (eg, write radio image).
  device_specific.IncrementalOTA_InstallEnd()

  if OPTIONS.extra_script is not None:
    script.AppendExtra(OPTIONS.extra_script)

  if OPTIONS.wipe_user_data:
    script.Print("Erasing user data...")
    script.FormatPartition("/data")

  if OPTIONS.two_step:
    script.AppendExtra("""
set_stage("%(bcb_dev)s", "");
endif;
endif;
""" % bcb_dev)

  script.SetProgress(1)
  # For downgrade OTAs, we prefer to use the update-binary in the source
  # build that is actually newer than the one in the target build.
  if OPTIONS.downgrade:
    script.AddToZip(source_zip, output_zip, input_path=OPTIONS.updater_binary)
  else:
    script.AddToZip(target_zip, output_zip, input_path=OPTIONS.updater_binary)
  metadata.required_cache = script.required_cache

  # We haven't written the metadata entry yet, which will be handled in
  # FinalizeMetadata().
  common.ZipClose(output_zip)

  # Sign the generated zip package unless no_signing is specified.
  needed_property_files = (
      NonAbOtaPropertyFiles(),
  )
  FinalizeMetadata(metadata, staging_file, output_file, needed_property_files)
コード例 #12
0
def WriteFullOTAPackage(input_zip, output_file):
  target_info = common.BuildInfo(OPTIONS.info_dict, OPTIONS.oem_dicts)

  # We don't know what version it will be installed on top of. We expect the API
  # just won't change very often. Similarly for fstab, it might have changed in
  # the target build.
  target_api_version = target_info["recovery_api_version"]
  script = edify_generator.EdifyGenerator(target_api_version, target_info)

  if target_info.oem_props and not OPTIONS.oem_no_mount:
    target_info.WriteMountOemScript(script)

  metadata = GetPackageMetadata(target_info)

  if not OPTIONS.no_signing:
    staging_file = common.MakeTempFile(suffix='.zip')
  else:
    staging_file = output_file

  output_zip = zipfile.ZipFile(
      staging_file, "w", compression=zipfile.ZIP_DEFLATED)

  device_specific = common.DeviceSpecificParams(
      input_zip=input_zip,
      input_version=target_api_version,
      output_zip=output_zip,
      script=script,
      input_tmp=OPTIONS.input_tmp,
      metadata=metadata,
      info_dict=OPTIONS.info_dict)

  assert HasRecoveryPatch(input_zip, info_dict=OPTIONS.info_dict)

  # Assertions (e.g. downgrade check, device properties check).
  #ts = target_info.GetBuildProp("ro.build.date.utc")
  #ts_text = target_info.GetBuildProp("ro.build.date")
  #script.AssertOlderBuild(ts, ts_text)

  target_info.WriteDeviceAssertions(script, OPTIONS.oem_no_mount)
  device_specific.FullOTA_Assertions()

  block_diff_dict = GetBlockDifferences(target_zip=input_zip, source_zip=None,
                                        target_info=target_info,
                                        source_info=None,
                                        device_specific=device_specific)

  # Two-step package strategy (in chronological order, which is *not*
  # the order in which the generated script has things):
  #
  # if stage is not "2/3" or "3/3":
  #    write recovery image to boot partition
  #    set stage to "2/3"
  #    reboot to boot partition and restart recovery
  # else if stage is "2/3":
  #    write recovery image to recovery partition
  #    set stage to "3/3"
  #    reboot to recovery partition and restart recovery
  # else:
  #    (stage must be "3/3")
  #    set stage to ""
  #    do normal full package installation:
  #       wipe and install system, boot image, etc.
  #       set up system to update recovery partition on first boot
  #    complete script normally
  #    (allow recovery to mark itself finished and reboot)

  #recovery_img = common.GetBootableImage("recovery.img", "recovery.img",
  #                                       OPTIONS.input_tmp, "RECOVERY")
  if OPTIONS.two_step:
    if not target_info.get("multistage_support"):
      assert False, "two-step packages not supported by this build"
    fs = target_info["fstab"]["/misc"]
    assert fs.fs_type.upper() == "EMMC", \
        "two-step packages only supported on devices with EMMC /misc partitions"
    bcb_dev = {"bcb_dev": fs.device}
    common.ZipWriteStr(output_zip, "recovery.img", recovery_img.data)
    script.AppendExtra("""
if get_stage("%(bcb_dev)s") == "2/3" then
""" % bcb_dev)

    # Stage 2/3: Write recovery image to /recovery (currently running /boot).
    script.Comment("Stage 2/3")
    #script.WriteRawImage("/recovery", "recovery.img")
    script.AppendExtra("""
set_stage("%(bcb_dev)s", "3/3");
reboot_now("%(bcb_dev)s", "recovery");
else if get_stage("%(bcb_dev)s") == "3/3" then
""" % bcb_dev)

    # Stage 3/3: Make changes.
    script.Comment("Stage 3/3")

  # Dump fingerprints
  script.Print("Target: {}".format(target_info.fingerprint))

  androidver = target_info.GetBuildProp("ro.build.version.release")
  buildid = target_info.GetBuildProp("ro.build.id")
  builddate = target_info.GetBuildProp("ro.build.date")
  securep = target_info.GetBuildProp("ro.build.version.security_patch")
  name = target_info.GetBuildProp("ro.product.name")
  model = target_info.GetBuildProp("ro.product.model")
  manufacturer = target_info.GetBuildProp("ro.product.manufacturer")
  builduser = target_info.GetBuildProp("ro.build.user")
  buildsdk = target_info.GetBuildProp("ro.build.version.sdk")

  # Start output
  script.Print("----------------------------------------------")
  script.Print("           _____ _   _             _   _ ___ ")
  script.Print("  _____  _|_   _| | | |_ __ ___   | | | |_ _|")
  script.Print(" / _ \ \/ / | | | |_| | '_ ` _ \  | | | || |")
  script.Print("|  __/>  <  | | |  _  | | | | | | | |_| || |")
  script.Print(" \___/_/\_\ |_| |_| |_|_| |_| |_|  \___/|___|")
  script.Print("")
  script.Print("         extended TouHou modified UI")
  script.Print("            Based on AOSP")
  script.Print("----------------------------------------------")
  script.Print("ROM Information    :")
  script.Print("Build Date         : %s"%(builddate))
  script.Print("Android Version    : %s"%(androidver))
  script.Print("exTHmUI Version    : %s"%(buildid))
  script.Print("SDK Version        : %s"%(buildsdk))
  script.Print("Security Patch Date: %s"%(securep))
  script.Print("----------------------------------------------")
  script.Print("Device Information :")
  script.Print("Manufacturer       : %s"%(manufacturer))
  script.Print("Name               : %s"%(name))
  script.Print("Model              : %s"%(model))
  script.Print("----------------------------------------------")
  script.Print("Installing exTHmUI to your device...")
  script.Print("")
  device_specific.FullOTA_InstallBegin()

  CopyInstallTools(output_zip)
  script.UnpackPackageDir("install", "/tmp/install")
  script.SetPermissionsRecursive("/tmp/install", 0, 0, 0o755, 0o644, None, None)
  script.SetPermissionsRecursive("/tmp/install/bin", 0, 0, 0o755, 0o755, None, None)

  if target_info.get("system_root_image") == "true":
    sysmount = "/"
  else:
    sysmount = "/system"

  if OPTIONS.backuptool:
    script.RunBackup("backup", sysmount, target_info.get('use_dynamic_partitions') == "true")

  # All other partitions as well as the data wipe use 10% of the progress, and
  # the update of the system partition takes the remaining progress.
  system_progress = 0.9 - (len(block_diff_dict) - 1) * 0.1
  if OPTIONS.wipe_user_data:
    system_progress -= 0.1
  progress_dict = {partition: 0.1 for partition in block_diff_dict}
  progress_dict["system"] = system_progress

  if target_info.get('use_dynamic_partitions') == "true":
    # Use empty source_info_dict to indicate that all partitions / groups must
    # be re-added.
    dynamic_partitions_diff = common.DynamicPartitionsDifference(
        info_dict=OPTIONS.info_dict,
        block_diffs=block_diff_dict.values(),
        progress_dict=progress_dict,
        build_without_vendor=(not HasPartition(input_zip, "vendor")))
    dynamic_partitions_diff.WriteScript(script, output_zip,
                                        write_verify_script=OPTIONS.verify)
  else:
    for block_diff in block_diff_dict.values():
      block_diff.WriteScript(script, output_zip,
                             progress=progress_dict.get(block_diff.partition),
                             write_verify_script=OPTIONS.verify)

  CheckVintfIfTrebleEnabled(OPTIONS.input_tmp, target_info)

  boot_img = common.GetBootableImage(
      "boot.img", "boot.img", OPTIONS.input_tmp, "BOOT")
  common.CheckSize(boot_img.data, "boot.img", target_info)
  common.ZipWriteStr(output_zip, "boot.img", boot_img.data)

  device_specific.FullOTA_PostValidate()

  if OPTIONS.backuptool:
    script.ShowProgress(0.02, 10)
    script.RunBackup("restore", sysmount, target_info.get('use_dynamic_partitions') == "true")

  script.WriteRawImage("/boot", "boot.img")

  script.ShowProgress(0.1, 10)
  device_specific.FullOTA_InstallEnd()

  if OPTIONS.extra_script is not None:
    script.AppendExtra(OPTIONS.extra_script)

  script.UnmountAll()

  if OPTIONS.wipe_user_data:
    script.ShowProgress(0.1, 10)
    script.FormatPartition("/data")

  if OPTIONS.two_step:
    script.AppendExtra("""
set_stage("%(bcb_dev)s", "");
""" % bcb_dev)
    script.AppendExtra("else\n")

    # Stage 1/3: Nothing to verify for full OTA. Write recovery image to /boot.
    script.Comment("Stage 1/3")
    _WriteRecoveryImageToBoot(script, output_zip)

    script.AppendExtra("""
set_stage("%(bcb_dev)s", "2/3");
reboot_now("%(bcb_dev)s", "");
endif;
endif;
""" % bcb_dev)

  script.SetProgress(1)
  script.AddToZip(input_zip, output_zip, input_path=OPTIONS.updater_binary)
  metadata.required_cache = script.required_cache

  # We haven't written the metadata entry, which will be done in
  # FinalizeMetadata.
  common.ZipClose(output_zip)

  needed_property_files = (
      NonAbOtaPropertyFiles(),
  )
  FinalizeMetadata(metadata, staging_file, output_file, needed_property_files)
コード例 #13
0
def WriteFullOTAPackage(input_zip, output_file):
    target_info = common.BuildInfo(OPTIONS.info_dict, OPTIONS.oem_dicts)

    # We don't know what version it will be installed on top of. We expect the API
    # just won't change very often. Similarly for fstab, it might have changed in
    # the target build.
    target_api_version = target_info["recovery_api_version"]
    script = edify_generator.EdifyGenerator(target_api_version, target_info)

    if target_info.oem_props and not OPTIONS.oem_no_mount:
        target_info.WriteMountOemScript(script)

    metadata = GetPackageMetadata(target_info)

    if not OPTIONS.no_signing:
        staging_file = common.MakeTempFile(suffix='.zip')
    else:
        staging_file = output_file

    output_zip = zipfile.ZipFile(staging_file,
                                 "w",
                                 compression=zipfile.ZIP_DEFLATED)

    device_specific = common.DeviceSpecificParams(
        input_zip=input_zip,
        input_version=target_api_version,
        output_zip=output_zip,
        script=script,
        input_tmp=OPTIONS.input_tmp,
        metadata=metadata,
        info_dict=OPTIONS.info_dict)

    assert HasRecoveryPatch(input_zip, info_dict=OPTIONS.info_dict)

    # Assertions (e.g. downgrade check, device properties check).
    ts = target_info.GetBuildProp("ro.build.date.utc")
    ts_text = target_info.GetBuildProp("ro.build.date")
    script.AssertOlderBuild(ts, ts_text)

    target_info.WriteDeviceAssertions(script, OPTIONS.oem_no_mount)
    device_specific.FullOTA_Assertions()

    block_diff_dict = GetBlockDifferences(target_zip=input_zip,
                                          source_zip=None,
                                          target_info=target_info,
                                          source_info=None,
                                          device_specific=device_specific)

    # Two-step package strategy (in chronological order, which is *not*
    # the order in which the generated script has things):
    #
    # if stage is not "2/3" or "3/3":
    #    write recovery image to boot partition
    #    set stage to "2/3"
    #    reboot to boot partition and restart recovery
    # else if stage is "2/3":
    #    write recovery image to recovery partition
    #    set stage to "3/3"
    #    reboot to recovery partition and restart recovery
    # else:
    #    (stage must be "3/3")
    #    set stage to ""
    #    do normal full package installation:
    #       wipe and install system, boot image, etc.
    #       set up system to update recovery partition on first boot
    #    complete script normally
    #    (allow recovery to mark itself finished and reboot)

    #recovery_img = common.GetBootableImage("recovery.img", "recovery.img",
    #                                       OPTIONS.input_tmp, "RECOVERY")
    if OPTIONS.two_step:
        if not target_info.get("multistage_support"):
            assert False, "two-step packages not supported by this build"
        fs = target_info["fstab"]["/misc"]
        assert fs.fs_type.upper() == "EMMC", \
            "two-step packages only supported on devices with EMMC /misc partitions"
        bcb_dev = {"bcb_dev": fs.device}
        common.ZipWriteStr(output_zip, "recovery.img", recovery_img.data)
        script.AppendExtra("""
if get_stage("%(bcb_dev)s") == "2/3" then
""" % bcb_dev)

        # Stage 2/3: Write recovery image to /recovery (currently running /boot).
        script.Comment("Stage 2/3")
        #script.WriteRawImage("/recovery", "recovery.img")
        script.AppendExtra("""
set_stage("%(bcb_dev)s", "3/3");
reboot_now("%(bcb_dev)s", "recovery");
else if get_stage("%(bcb_dev)s") == "3/3" then
""" % bcb_dev)

        # Stage 3/3: Make changes.
        script.Comment("Stage 3/3")

    # Dump fingerprints
    script.Print("Target: {}".format(target_info.fingerprint))

    script.AppendExtra(
        "ifelse(is_mounted(\"/system\"), unmount(\"/system\"));")
    device_specific.FullOTA_InstallBegin()

    # All other partitions as well as the data wipe use 10% of the progress, and
    # the update of the system partition takes the remaining progress.
    system_progress = 0.9 - (len(block_diff_dict) - 1) * 0.1
    if OPTIONS.wipe_user_data:
        system_progress -= 0.1
    progress_dict = {partition: 0.1 for partition in block_diff_dict}
    progress_dict["system"] = system_progress

    if target_info.get('use_dynamic_partitions') == "true":
        # Use empty source_info_dict to indicate that all partitions / groups must
        # be re-added.
        dynamic_partitions_diff = common.DynamicPartitionsDifference(
            info_dict=OPTIONS.info_dict,
            block_diffs=block_diff_dict.values(),
            progress_dict=progress_dict)
        dynamic_partitions_diff.WriteScript(script,
                                            output_zip,
                                            write_verify_script=OPTIONS.verify)
    else:
        for block_diff in block_diff_dict.values():
            block_diff.WriteScript(script,
                                   output_zip,
                                   progress=progress_dict.get(
                                       block_diff.partition),
                                   write_verify_script=OPTIONS.verify)

    CheckVintfIfTrebleEnabled(OPTIONS.input_tmp, target_info)

    boot_img = common.GetBootableImage("boot.img", "boot.img",
                                       OPTIONS.input_tmp, "BOOT")
    common.CheckSize(boot_img.data, "boot.img", target_info)
    common.ZipWriteStr(output_zip, "boot.img", boot_img.data)

    script.WriteRawImage("/boot", "boot.img")

    script.ShowProgress(0.1, 10)
    device_specific.FullOTA_InstallEnd()

    if OPTIONS.extra_script is not None:
        script.AppendExtra(OPTIONS.extra_script)

    script.UnmountAll()

    if OPTIONS.wipe_user_data:
        script.ShowProgress(0.1, 10)
        script.FormatPartition("/data")

    if OPTIONS.two_step:
        script.AppendExtra("""
set_stage("%(bcb_dev)s", "");
""" % bcb_dev)
        script.AppendExtra("else\n")

        # Stage 1/3: Nothing to verify for full OTA. Write recovery image to /boot.
        script.Comment("Stage 1/3")
        _WriteRecoveryImageToBoot(script, output_zip)

        script.AppendExtra("""
set_stage("%(bcb_dev)s", "2/3");
reboot_now("%(bcb_dev)s", "");
endif;
endif;
""" % bcb_dev)

    script.SetProgress(1)
    script.AddToZip(input_zip, output_zip, input_path=OPTIONS.updater_binary)
    metadata.required_cache = script.required_cache

    # We haven't written the metadata entry, which will be done in
    # FinalizeMetadata.
    common.ZipClose(output_zip)

    needed_property_files = (NonAbOtaPropertyFiles(), )
    FinalizeMetadata(metadata, staging_file, output_file,
                     needed_property_files)
コード例 #14
0
def GenerateAbOtaPackage(target_file, output_file, source_file=None):
    """Generates an Android OTA package that has A/B update payload."""
    # Stage the output zip package for package signing.
    if not OPTIONS.no_signing:
        staging_file = common.MakeTempFile(suffix='.zip')
    else:
        staging_file = output_file
    output_zip = zipfile.ZipFile(staging_file,
                                 "w",
                                 compression=zipfile.ZIP_DEFLATED)

    if source_file is not None:
        assert "ab_partitions" in OPTIONS.source_info_dict, \
            "META/ab_partitions.txt is required for ab_update."
        assert "ab_partitions" in OPTIONS.target_info_dict, \
            "META/ab_partitions.txt is required for ab_update."
        target_info = common.BuildInfo(OPTIONS.target_info_dict,
                                       OPTIONS.oem_dicts)
        source_info = common.BuildInfo(OPTIONS.source_info_dict,
                                       OPTIONS.oem_dicts)
    else:
        assert "ab_partitions" in OPTIONS.info_dict, \
            "META/ab_partitions.txt is required for ab_update."
        target_info = common.BuildInfo(OPTIONS.info_dict, OPTIONS.oem_dicts)
        source_info = None

    if OPTIONS.retrofit_dynamic_partitions:
        target_file = GetTargetFilesZipForRetrofitDynamicPartitions(
            target_file,
            target_info.get("super_block_devices").strip().split(),
            target_info.get("dynamic_partition_list").strip().split())
    elif OPTIONS.skip_postinstall:
        target_file = GetTargetFilesZipWithoutPostinstallConfig(target_file)
    # Target_file may have been modified, reparse ab_partitions
    with zipfile.ZipFile(target_file, allowZip64=True) as zfp:
        target_info.info_dict['ab_partitions'] = zfp.read(
            AB_PARTITIONS).strip().split("\n")

    # Metadata to comply with Android OTA package format.
    metadata = GetPackageMetadata(target_info, source_info)
    # Generate payload.
    payload = Payload()

    partition_timestamps = []
    # Enforce a max timestamp this payload can be applied on top of.
    if OPTIONS.downgrade:
        max_timestamp = source_info.GetBuildProp("ro.build.date.utc")
    else:
        max_timestamp = str(metadata.postcondition.timestamp)
        partition_timestamps = [
            part.partition_name + ":" + part.version
            for part in metadata.postcondition.partition_state
        ]
    additional_args = ["--max_timestamp", max_timestamp]
    if partition_timestamps:
        additional_args.extend(
            ["--partition_timestamps", ",".join(partition_timestamps)])

    payload.Generate(target_file, source_file, additional_args)

    # Sign the payload.
    payload_signer = PayloadSigner()
    payload.Sign(payload_signer)

    # Write the payload into output zip.
    payload.WriteToZip(output_zip)

    # Generate and include the secondary payload that installs secondary images
    # (e.g. system_other.img).
    if OPTIONS.include_secondary:
        # We always include a full payload for the secondary slot, even when
        # building an incremental OTA. See the comments for "--include_secondary".
        secondary_target_file = GetTargetFilesZipForSecondaryImages(
            target_file, OPTIONS.skip_postinstall)
        secondary_payload = Payload(secondary=True)
        secondary_payload.Generate(secondary_target_file,
                                   additional_args=additional_args)
        secondary_payload.Sign(payload_signer)
        secondary_payload.WriteToZip(output_zip)

    # If dm-verity is supported for the device, copy contents of care_map
    # into A/B OTA package.
    target_zip = zipfile.ZipFile(target_file, "r")
    if (target_info.get("verity") == "true"
            or target_info.get("avb_enable") == "true"):
        care_map_list = [
            x for x in ["care_map.pb", "care_map.txt"]
            if "META/" + x in target_zip.namelist()
        ]

        # Adds care_map if either the protobuf format or the plain text one exists.
        if care_map_list:
            care_map_name = care_map_list[0]
            care_map_data = target_zip.read("META/" + care_map_name)
            # In order to support streaming, care_map needs to be packed as
            # ZIP_STORED.
            common.ZipWriteStr(output_zip,
                               care_map_name,
                               care_map_data,
                               compress_type=zipfile.ZIP_STORED)
        else:
            logger.warning("Cannot find care map file in target_file package")

    common.ZipClose(target_zip)

    CheckVintfIfTrebleEnabled(target_file, target_info)

    # We haven't written the metadata entry yet, which will be handled in
    # FinalizeMetadata().
    common.ZipClose(output_zip)

    # AbOtaPropertyFiles intends to replace StreamingPropertyFiles, as it covers
    # all the info of the latter. However, system updaters and OTA servers need to
    # take time to switch to the new flag. We keep both of the flags for
    # P-timeframe, and will remove StreamingPropertyFiles in later release.
    needed_property_files = (
        AbOtaPropertyFiles(),
        StreamingPropertyFiles(),
    )
    FinalizeMetadata(metadata, staging_file, output_file,
                     needed_property_files)