Support forcefully generating non-AB packages.
Force generate a non-A/B update package when requested.
Bug: 154344887
Test: ota_from_target_files.py --force_non_ab ...
Test: apply it as well
Change-Id: I5e81eb161722e07ef50081b6a16685cbc9963ae2
(cherry picked from commit 7169f754cc4b806c54a049b838355483575c1785)
Merged-In: I5e81eb161722e07ef50081b6a16685cbc9963ae2
diff --git a/tools/releasetools/blockimgdiff.py b/tools/releasetools/blockimgdiff.py
index 72f065d..8b6a690 100644
--- a/tools/releasetools/blockimgdiff.py
+++ b/tools/releasetools/blockimgdiff.py
@@ -1558,6 +1558,7 @@
split_large_apks = []
cache_size = common.OPTIONS.cache_size
split_threshold = 0.125
+ assert cache_size is not None
max_blocks_per_transfer = int(cache_size * split_threshold /
self.tgt.blocksize)
empty = RangeSet()
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index 2b04334..9f48f78 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -848,12 +848,13 @@
def LoadRecoveryFSTab(read_helper, fstab_version, recovery_fstab_path,
system_root_image=False):
class Partition(object):
- def __init__(self, mount_point, fs_type, device, length, context):
+ def __init__(self, mount_point, fs_type, device, length, context, slotselect):
self.mount_point = mount_point
self.fs_type = fs_type
self.device = device
self.length = length
self.context = context
+ self.slotselect = slotselect
try:
data = read_helper(recovery_fstab_path)
@@ -881,10 +882,13 @@
# It's a good line, parse it.
length = 0
+ slotselect = False
options = options.split(",")
for i in options:
if i.startswith("length="):
length = int(i[7:])
+ elif i == "slotselect":
+ slotselect = True
else:
# Ignore all unknown options in the unified fstab.
continue
@@ -898,7 +902,8 @@
mount_point = pieces[1]
d[mount_point] = Partition(mount_point=mount_point, fs_type=pieces[2],
- device=pieces[0], length=length, context=context)
+ device=pieces[0], length=length, context=context,
+ slotselect=slotselect)
# / is used for the system mount point when the root directory is included in
# system. Other areas assume system is always at "/system" so point /system
@@ -913,7 +918,8 @@
"""Finds the path to recovery fstab and loads its contents."""
# recovery fstab is only meaningful when installing an update via recovery
# (i.e. non-A/B OTA). Skip loading fstab if device used A/B OTA.
- if info_dict.get('ab_update') == 'true':
+ if info_dict.get('ab_update') == 'true' and \
+ info_dict.get("allow_non_ab") != "true":
return None
# We changed recovery.fstab path in Q, from ../RAMDISK/etc/recovery.fstab to
diff --git a/tools/releasetools/ota_from_target_files.py b/tools/releasetools/ota_from_target_files.py
index ad001d1..16d7485 100755
--- a/tools/releasetools/ota_from_target_files.py
+++ b/tools/releasetools/ota_from_target_files.py
@@ -78,6 +78,13 @@
Write a copy of the metadata to a separate file. Therefore, users can
read the post build fingerprint without extracting the OTA package.
+ --force_non_ab
+ This flag can only be set on an A/B device that also supports non-A/B
+ updates. Implies --two_step.
+ If set, generate that non-A/B update package.
+ If not set, generates A/B package for A/B device and non-A/B package for
+ non-A/B device.
+
Non-A/B OTA specific options
-b (--binary) <file>
@@ -251,6 +258,7 @@
OPTIONS.output_metadata_path = None
OPTIONS.disable_fec_computation = False
OPTIONS.boot_variable_values = None
+OPTIONS.force_non_ab = False
METADATA_NAME = 'META-INF/com/android/metadata'
@@ -933,7 +941,7 @@
'ro.build.version.security_patch'),
}
- if target_info.is_ab:
+ if target_info.is_ab and not OPTIONS.force_non_ab:
metadata['ota-type'] = 'AB'
metadata['ota-required-cache'] = '0'
else:
@@ -2067,6 +2075,8 @@
OPTIONS.output_metadata_path = a
elif o == "--disable_fec_computation":
OPTIONS.disable_fec_computation = True
+ elif o == "--force_non_ab":
+ OPTIONS.force_non_ab = True
else:
return False
return True
@@ -2103,6 +2113,7 @@
"skip_compatibility_check",
"output_metadata_path=",
"disable_fec_computation",
+ "force_non_ab",
], extra_option_handler=option_handler)
if len(args) != 2:
@@ -2164,11 +2175,17 @@
OPTIONS.skip_postinstall = True
ab_update = OPTIONS.info_dict.get("ab_update") == "true"
+ allow_non_ab = OPTIONS.info_dict.get("allow_non_ab") == "true"
+ if OPTIONS.force_non_ab:
+ assert allow_non_ab, "--force_non_ab only allowed on devices that supports non-A/B"
+ assert ab_update, "--force_non_ab only allowed on A/B devices"
+
+ generate_ab = not OPTIONS.force_non_ab and ab_update
# Use the default key to sign the package if not specified with package_key.
# package_keys are needed on ab_updates, so always define them if an
- # ab_update is getting created.
- if not OPTIONS.no_signing or ab_update:
+ # A/B update is getting created.
+ if not OPTIONS.no_signing or generate_ab:
if OPTIONS.package_key is None:
OPTIONS.package_key = OPTIONS.info_dict.get(
"default_system_dev_certificate",
@@ -2176,7 +2193,7 @@
# Get signing keys
OPTIONS.key_passwords = common.GetKeyPasswords([OPTIONS.package_key])
- if ab_update:
+ if generate_ab:
GenerateAbOtaPackage(
target_file=args[0],
output_file=args[1],