Merge "Do not enforce debugfs restrictions on GSI builds"
diff --git a/core/Makefile b/core/Makefile
index b70948b..26b19c0 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -5319,6 +5319,19 @@
$(hide) find $(PRODUCT_OUT)/appcompat | sort >$(PRIVATE_LIST_FILE)
$(hide) $(SOONG_ZIP) -d -o $@ -C $(PRODUCT_OUT)/appcompat -l $(PRIVATE_LIST_FILE)
+# The mac build doesn't build dex2oat, so create the zip file only if the build OS is linux.
+ifeq ($(BUILD_OS),linux)
+ifneq ($(DEX2OAT),)
+dexpreopt_tools_deps := $(DEXPREOPT_GEN_DEPS) $(DEXPREOPT_GEN) $(AAPT2)
+DEXPREOPT_TOOLS_ZIP := $(PRODUCT_OUT)/dexpreopt_tools.zip
+$(DEXPREOPT_TOOLS_ZIP): $(dexpreopt_tools_deps)
+$(DEXPREOPT_TOOLS_ZIP): PRIVATE_DEXPREOPT_TOOLS_DEPS := $(dexpreopt_tools_deps)
+$(DEXPREOPT_TOOLS_ZIP): $(SOONG_ZIP)
+ $(hide) mkdir -p $(dir $@)
+ $(hide) $(SOONG_ZIP) -d -o $@ -j $(addprefix -f ,$(PRIVATE_DEXPREOPT_TOOLS_DEPS)) -f $$(realpath $(DEX2OAT))
+endif # DEX2OAT is set
+endif # BUILD_OS == linux
+
DEXPREOPT_CONFIG_ZIP := $(PRODUCT_OUT)/dexpreopt_config.zip
$(DEXPREOPT_CONFIG_ZIP): $(FULL_SYSTEMIMAGE_DEPS) \
$(INTERNAL_RAMDISK_FILES) \
diff --git a/core/android_soong_config_vars.mk b/core/android_soong_config_vars.mk
index c9fcf47..74558f5 100644
--- a/core/android_soong_config_vars.mk
+++ b/core/android_soong_config_vars.mk
@@ -27,6 +27,7 @@
# Add variables to the namespace below:
$(call add_soong_config_var,ANDROID,TARGET_ENABLE_MEDIADRM_64)
+$(call add_soong_config_var,ANDROID,BOARD_USES_ODMIMAGE)
# TODO(b/172480615): Remove when platform uses ART Module prebuilts by default.
ifeq (,$(filter art_module,$(SOONG_CONFIG_NAMESPACES)))
diff --git a/core/dex_preopt.mk b/core/dex_preopt.mk
index dd31999..593ad66 100644
--- a/core/dex_preopt.mk
+++ b/core/dex_preopt.mk
@@ -62,7 +62,9 @@
boot_zip := $(PRODUCT_OUT)/boot.zip
bootclasspath_jars := $(DEXPREOPT_BOOTCLASSPATH_DEX_FILES)
-system_server_jars := $(foreach m,$(PRODUCT_SYSTEM_SERVER_JARS),$(PRODUCT_OUT)/system/framework/$(m).jar)
+system_server_jars := \
+ $(foreach m,$(PRODUCT_SYSTEM_SERVER_JARS),\
+ $(PRODUCT_OUT)/system/framework/$(call word-colon,2,$(m)).jar)
$(boot_zip): PRIVATE_BOOTCLASSPATH_JARS := $(bootclasspath_jars)
$(boot_zip): PRIVATE_SYSTEM_SERVER_JARS := $(system_server_jars)
diff --git a/core/dex_preopt_odex_install.mk b/core/dex_preopt_odex_install.mk
index a23bae2..bcbce8d 100644
--- a/core/dex_preopt_odex_install.mk
+++ b/core/dex_preopt_odex_install.mk
@@ -70,9 +70,10 @@
# /data. If we don't do this they will need to be extracted which is not favorable for RAM usage
# or performance. If my_preopt_for_extracted_apk is true, we ignore the only preopt boot image
# options.
+system_server_jars := $(foreach m,$(PRODUCT_SYSTEM_SERVER_JARS),$(call word-colon,2,$(m)))
ifneq (true,$(my_preopt_for_extracted_apk))
ifeq (true,$(WITH_DEXPREOPT_BOOT_IMG_AND_SYSTEM_SERVER_ONLY))
- ifeq ($(filter $(PRODUCT_SYSTEM_SERVER_JARS) $(DEXPREOPT_BOOT_JARS_MODULES),$(LOCAL_MODULE)),)
+ ifeq ($(filter $(system_server_jars) $(DEXPREOPT_BOOT_JARS_MODULES),$(LOCAL_MODULE)),)
LOCAL_DEX_PREOPT :=
endif
endif
@@ -226,14 +227,9 @@
LOCAL_ENFORCE_USES_LIBRARIES := false
endif
-# Verify LOCAL_USES_LIBRARIES/LOCAL_OPTIONAL_USES_LIBRARIES
-# If LOCAL_ENFORCE_USES_LIBRARIES is not set, default to true if either of LOCAL_USES_LIBRARIES or
-# LOCAL_OPTIONAL_USES_LIBRARIES are specified.
-# Will change the default to true unconditionally in the future.
+# Verify LOCAL_USES_LIBRARIES/LOCAL_OPTIONAL_USES_LIBRARIES against the manifest.
ifndef LOCAL_ENFORCE_USES_LIBRARIES
- ifneq (,$(strip $(LOCAL_USES_LIBRARIES)$(LOCAL_OPTIONAL_USES_LIBRARIES)))
- LOCAL_ENFORCE_USES_LIBRARIES := true
- endif
+ LOCAL_ENFORCE_USES_LIBRARIES := true
endif
my_enforced_uses_libraries :=
@@ -266,7 +262,7 @@
$(PRIVATE_DEXPREOPT_CONFIGS) \
$(PRIVATE_RELAX_CHECK) \
$<
- $(built_module) : $(my_enforced_uses_libraries)
+ $(LOCAL_BUILT_MODULE) : $(my_enforced_uses_libraries)
endif
################################################################################
@@ -388,7 +384,7 @@
$(call end_json_map)
$(call add_json_list, Archs, $(my_dexpreopt_archs))
$(call add_json_list, DexPreoptImages, $(my_dexpreopt_images))
- $(call add_json_list, DexPreoptImageLocations, $(my_dexpreopt_image_locations))
+ $(call add_json_list, DexPreoptImageLocationsOnHost, $(my_dexpreopt_image_locations))
$(call add_json_list, PreoptBootClassPathDexFiles, $(DEXPREOPT_BOOTCLASSPATH_DEX_FILES))
$(call add_json_list, PreoptBootClassPathDexLocations,$(DEXPREOPT_BOOTCLASSPATH_DEX_LOCATIONS))
$(call add_json_bool, PreoptExtractedApk, $(my_preopt_for_extracted_apk))
diff --git a/core/main.mk b/core/main.mk
index c9fa148..c45c1f2 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -1709,6 +1709,7 @@
$(COVERAGE_ZIP) \
$(APPCOMPAT_ZIP) \
$(DEXPREOPT_CONFIG_ZIP) \
+ $(DEXPREOPT_TOOLS_ZIP) \
$(INSTALLED_FILES_FILE) \
$(INSTALLED_FILES_JSON) \
$(INSTALLED_FILES_FILE_VENDOR) \
diff --git a/core/product_config.mk b/core/product_config.mk
index eb6f69f..5c85fb8 100644
--- a/core/product_config.mk
+++ b/core/product_config.mk
@@ -231,12 +231,23 @@
PRODUCT_AAPT_CONFIG_SP := $(PRODUCT_AAPT_CONFIG)
PRODUCT_AAPT_CONFIG := $(subst $(space),$(comma),$(PRODUCT_AAPT_CONFIG))
+###########################################################
+## Add 'platform:' prefix to jars not in <apex>:<module> format.
+##
+## This makes sure that a jar corresponds to ConfigureJarList format of <apex> and <module> pairs
+## where needed.
+##
+## $(1): a list of jars either in <module> or <apex>:<module> format
+###########################################################
+
+define qualify-platform-jars
+ $(foreach jar,$(1),$(if $(findstring :,$(jar)),,platform:)$(jar))
+endef
+
# Extra boot jars must be appended at the end after common boot jars.
PRODUCT_BOOT_JARS += $(PRODUCT_BOOT_JARS_EXTRA)
-# Add 'platform:' prefix to unqualified boot jars
-PRODUCT_BOOT_JARS := $(foreach pair,$(PRODUCT_BOOT_JARS), \
- $(if $(findstring :,$(pair)),,platform:)$(pair))
+PRODUCT_BOOT_JARS := $(call qualify-platform-jars,$(PRODUCT_BOOT_JARS))
# Replaces references to overridden boot jar modules in a boot jars variable.
# $(1): Name of a boot jars variable with <apex>:<jar> pairs.
@@ -254,6 +265,8 @@
# The extra system server jars must be appended at the end after common system server jars.
PRODUCT_SYSTEM_SERVER_JARS += $(PRODUCT_SYSTEM_SERVER_JARS_EXTRA)
+PRODUCT_SYSTEM_SERVER_JARS := $(call qualify-platform-jars,$(PRODUCT_SYSTEM_SERVER_JARS))
+
ifndef PRODUCT_SYSTEM_NAME
PRODUCT_SYSTEM_NAME := $(PRODUCT_NAME)
endif
diff --git a/core/sysprop.mk b/core/sysprop.mk
index daebdd3..0fc96e0 100644
--- a/core/sysprop.mk
+++ b/core/sysprop.mk
@@ -260,6 +260,7 @@
BUILD_HOSTNAME="$(BUILD_HOSTNAME)" \
BUILD_NUMBER="$(BUILD_NUMBER_FROM_FILE)" \
BOARD_BUILD_SYSTEM_ROOT_IMAGE="$(BOARD_BUILD_SYSTEM_ROOT_IMAGE)" \
+ BOARD_USE_VBMETA_DIGTEST_IN_FINGERPRINT="$(BOARD_USE_VBMETA_DIGTEST_IN_FINGERPRINT)" \
PLATFORM_VERSION="$(PLATFORM_VERSION)" \
PLATFORM_VERSION_LAST_STABLE="$(PLATFORM_VERSION_LAST_STABLE)" \
PLATFORM_SECURITY_PATCH="$(PLATFORM_SECURITY_PATCH)" \
diff --git a/core/version_defaults.mk b/core/version_defaults.mk
index 4138277..181ea62 100644
--- a/core/version_defaults.mk
+++ b/core/version_defaults.mk
@@ -240,7 +240,7 @@
# It must be of the form "YYYY-MM-DD" on production devices.
# It must match one of the Android Security Patch Level strings of the Public Security Bulletins.
# If there is no $PLATFORM_SECURITY_PATCH set, keep it empty.
- PLATFORM_SECURITY_PATCH := 2021-04-05
+ PLATFORM_SECURITY_PATCH := 2021-05-05
endif
.KATI_READONLY := PLATFORM_SECURITY_PATCH
diff --git a/target/board/BoardConfigGsiCommon.mk b/target/board/BoardConfigGsiCommon.mk
index a2150ad..95ba1d0 100644
--- a/target/board/BoardConfigGsiCommon.mk
+++ b/target/board/BoardConfigGsiCommon.mk
@@ -30,6 +30,14 @@
# the devices with metadata parition
BOARD_USES_METADATA_PARTITION := true
+# Enable GKI 2.0 signing.
+BOARD_GKI_SIGNING_KEY_PATH := build/make/target/product/gsi/testkey_rsa2048.pem
+BOARD_GKI_SIGNING_ALGORITHM := SHA256_RSA2048
+# The following is needed to allow release signing process appends more extra
+# args, e.g., passing --signing_helper_with_files from mkbootimg to avbtool.
+# See b/178559811 for more details.
+BOARD_GKI_SIGNING_SIGNATURE_ARGS := --prop foo:bar
+
# Android Verified Boot (AVB):
# Set the rollback index to zero, to prevent the device bootloader from
# updating the last seen rollback index in the tamper-evident storage.
@@ -41,6 +49,10 @@
BOARD_AVB_SYSTEM_ALGORITHM := SHA256_RSA2048
BOARD_AVB_SYSTEM_ROLLBACK_INDEX := $(PLATFORM_SECURITY_PATCH_TIMESTAMP)
BOARD_AVB_SYSTEM_ROLLBACK_INDEX_LOCATION := 1
+
+# Using sha256 for dm-verity partitions. b/156162446
+BOARD_AVB_SYSTEM_ADD_HASHTREE_FOOTER_ARGS += --hash_algorithm sha256
+
ifdef BUILDING_GSI
# super.img spec for GSI targets
BOARD_SUPER_PARTITION_SIZE := 3229614080
diff --git a/target/board/generic_arm64/BoardConfig.mk b/target/board/generic_arm64/BoardConfig.mk
index 15c311c..1dbce1e 100644
--- a/target/board/generic_arm64/BoardConfig.mk
+++ b/target/board/generic_arm64/BoardConfig.mk
@@ -77,10 +77,6 @@
BOARD_BOOT_HEADER_VERSION := 4
BOARD_MKBOOTIMG_ARGS += --header_version $(BOARD_BOOT_HEADER_VERSION)
-# Enable GKI 2.0 signing.
-BOARD_GKI_SIGNING_KEY_PATH := build/make/target/product/gsi/testkey_rsa2048.pem
-BOARD_GKI_SIGNING_ALGORITHM := SHA256_RSA2048
-
BOARD_KERNEL_BINARIES := \
kernel-4.19-gz \
kernel-5.4 kernel-5.4-gz kernel-5.4-lz4 \
@@ -99,8 +95,8 @@
TARGET_NO_KERNEL := false
BOARD_USES_GENERIC_KERNEL_IMAGE := true
BOARD_KERNEL_MODULE_INTERFACE_VERSIONS := \
- 5.4-android12-0 \
- 5.10-android12-0 \
+ 5.4-android12-unstable \
+ 5.10-android12-unstable \
# Copy boot image in $OUT to target files. This is defined for targets where
# the installed GKI APEXes are built from source.
diff --git a/target/product/default_art_config.mk b/target/product/default_art_config.mk
index feb2eb7..0e652c1 100644
--- a/target/product/default_art_config.mk
+++ b/target/product/default_art_config.mk
@@ -48,17 +48,17 @@
PRODUCT_BOOT_JARS += \
com.android.i18n:core-icu4j
-# Updatable APEX jars. Keep the list sorted.
+# Updatable APEX jars. Keep the list sorted by module names and then library names.
PRODUCT_UPDATABLE_BOOT_JARS := \
com.android.conscrypt:conscrypt \
+ com.android.ipsec:android.net.ipsec.ike \
com.android.media:updatable-media \
com.android.mediaprovider:framework-mediaprovider \
com.android.os.statsd:framework-statsd \
com.android.permission:framework-permission \
com.android.sdkext:framework-sdkextensions \
- com.android.wifi:framework-wifi \
com.android.tethering:framework-tethering \
- com.android.ipsec:android.net.ipsec.ike
+ com.android.wifi:framework-wifi
# Minimal configuration for running dex2oat (default argument values).
# PRODUCT_USES_DEFAULT_ART_CONFIG must be true to enable boot image compilation.
diff --git a/tools/buildinfo.sh b/tools/buildinfo.sh
index f27ed8c..a349cba 100755
--- a/tools/buildinfo.sh
+++ b/tools/buildinfo.sh
@@ -3,7 +3,12 @@
echo "# begin build properties"
echo "# autogenerated by buildinfo.sh"
-echo "ro.build.id=$BUILD_ID"
+# The ro.build.id will be set dynamically by init, by appending the unique vbmeta digest.
+if [ "$BOARD_USE_VBMETA_DIGTEST_IN_FINGERPRINT" = "true" ] ; then
+ echo "ro.build.legacy.id=$BUILD_ID"
+else
+ echo "ro.build.id=$BUILD_ID"
+fi
echo "ro.build.display.id=$BUILD_DISPLAY_ID"
echo "ro.build.version.incremental=$BUILD_NUMBER"
echo "ro.build.version.sdk=$PLATFORM_SDK_VERSION"
diff --git a/tools/releasetools/Android.bp b/tools/releasetools/Android.bp
index 65c035e..687070d 100644
--- a/tools/releasetools/Android.bp
+++ b/tools/releasetools/Android.bp
@@ -114,6 +114,25 @@
},
}
+java_library_static {
+ name: "ota_metadata_proto_java",
+ host_supported: true,
+ proto: {
+ type: "nano",
+ },
+ srcs: ["ota_metadata.proto"],
+ sdk_version: "9",
+ target: {
+ android: {
+ jarjar_rules: "jarjar-rules.txt",
+ },
+ host: {
+ static_libs: ["libprotobuf-java-nano"],
+ },
+ },
+ visibility: ["//frameworks/base:__subpackages__"]
+}
+
python_defaults {
name: "releasetools_ota_from_target_files_defaults",
srcs: [
diff --git a/tools/releasetools/add_img_to_target_files.py b/tools/releasetools/add_img_to_target_files.py
index 00bbb21..c583d01 100644
--- a/tools/releasetools/add_img_to_target_files.py
+++ b/tools/releasetools/add_img_to_target_files.py
@@ -259,6 +259,7 @@
block_list=block_list)
return img.name
+
def AddOdmDlkm(output_zip):
"""Turn the contents of OdmDlkm into an odm_dlkm image and store it in output_zip."""
@@ -310,6 +311,7 @@
img.Write()
return img.name
+
def AddPvmfw(output_zip):
"""Adds the pvmfw image.
@@ -345,6 +347,7 @@
img.Write()
return img.name
+
def AddCustomImages(output_zip, partition_name):
"""Adds and signs custom images in IMAGES/.
@@ -359,8 +362,6 @@
AssertionError: If image can't be found.
"""
- partition_size = OPTIONS.info_dict.get(
- "avb_{}_partition_size".format(partition_name))
key_path = OPTIONS.info_dict.get("avb_{}_key_path".format(partition_name))
algorithm = OPTIONS.info_dict.get("avb_{}_algorithm".format(partition_name))
extra_args = OPTIONS.info_dict.get(
@@ -419,8 +420,9 @@
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)
+ # build fingerprint). Also use the legacy build id, because the vbmeta digest
+ # isn't available at this point.
+ build_info = common.BuildInfo(info_dict, use_legacy_id=True)
uuid_seed = what + "-" + build_info.GetPartitionFingerprint(what)
image_props["uuid"] = str(uuid.uuid5(uuid.NAMESPACE_URL, uuid_seed))
hash_seed = "hash_seed-" + uuid_seed
@@ -955,6 +957,20 @@
with open(pack_radioimages_txt) as f:
AddPackRadioImages(output_zip, f.readlines())
+ # Calculate the vbmeta digest and put the result in to META/
+ boot_images = OPTIONS.info_dict.get("boot_images")
+ # Disable the digest calculation if the target_file is used as a container
+ # for boot images.
+ boot_container = boot_images and len(boot_images.split()) >= 2
+ if (OPTIONS.info_dict.get("avb_enable") == "true" and not boot_container and
+ OPTIONS.info_dict.get("avb_building_vbmeta_image") == "true"):
+ avbtool = OPTIONS.info_dict["avb_avbtool"]
+ digest = verity_utils.CalculateVbmetaDigest(OPTIONS.input_tmp, avbtool)
+ vbmeta_digest_txt = os.path.join(OPTIONS.input_tmp, "META",
+ "vbmeta_digest.txt")
+ with open(vbmeta_digest_txt, 'w') as f:
+ f.write(digest)
+
if output_zip:
common.ZipClose(output_zip)
if OPTIONS.replace_updated_files_list:
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index b397fd0..5e2a50d 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -372,7 +372,10 @@
"product", "product_services", "odm", "vendor", "system"]
_RO_PRODUCT_PROPS_DEFAULT_SOURCE_ORDER_LEGACY = []
- def __init__(self, info_dict, oem_dicts=None):
+ # The length of vbmeta digest to append to the fingerprint
+ _VBMETA_DIGEST_SIZE_USED = 8
+
+ def __init__(self, info_dict, oem_dicts=None, use_legacy_id=False):
"""Initializes a BuildInfo instance with the given dicts.
Note that it only wraps up the given dicts, without making copies.
@@ -383,6 +386,9 @@
that it always uses the first dict to calculate the fingerprint or the
device name. The rest would be used for asserting OEM properties only
(e.g. one package can be installed on one of these devices).
+ use_legacy_id: Use the legacy build id to construct the fingerprint. This
+ is used when we need a BuildInfo class, while the vbmeta digest is
+ unavailable.
Raises:
ValueError: On invalid inputs.
@@ -391,6 +397,7 @@
self.oem_dicts = oem_dicts
self._is_ab = info_dict.get("ab_update") == "true"
+ self.use_legacy_id = use_legacy_id
# Skip _oem_props if oem_dicts is None to use BuildInfo in
# sign_target_files_apks
@@ -491,6 +498,9 @@
if prop in BuildInfo._RO_PRODUCT_RESOLVE_PROPS:
return self._ResolveRoProductBuildProp(prop)
+ if prop == "ro.build.id":
+ return self._GetBuildId()
+
prop_val = self._GetRawBuildProp(prop, None)
if prop_val is not None:
return prop_val
@@ -557,6 +567,34 @@
return self.GetBuildProp("ro.build.version.release")
+ def _GetBuildId(self):
+ build_id = self._GetRawBuildProp("ro.build.id", None)
+ if build_id:
+ return build_id
+
+ legacy_build_id = self.GetBuildProp("ro.build.legacy.id")
+ if not legacy_build_id:
+ raise ExternalError("Couldn't find build id in property file")
+
+ if self.use_legacy_id:
+ return legacy_build_id
+
+ # Append the top 8 chars of vbmeta digest to the existing build id. The
+ # logic needs to match the one in init, so that OTA can deliver correctly.
+ avb_enable = self.info_dict.get("avb_enable") == "true"
+ if not avb_enable:
+ raise ExternalError("AVB isn't enabled when using legacy build id")
+
+ vbmeta_digest = self.info_dict.get("vbmeta_digest")
+ if not vbmeta_digest:
+ raise ExternalError("Vbmeta digest isn't provided when using legacy build"
+ " id")
+ if len(vbmeta_digest) < self._VBMETA_DIGEST_SIZE_USED:
+ raise ExternalError("Invalid vbmeta digest " + vbmeta_digest)
+
+ digest_prefix = vbmeta_digest[:self._VBMETA_DIGEST_SIZE_USED]
+ return legacy_build_id + '.' + digest_prefix
+
def _GetPartitionPlatformVersion(self, partition):
try:
return self.GetPartitionBuildProp("ro.build.version.release_or_codename",
@@ -790,12 +828,19 @@
# Set up the salt (based on fingerprint) that will be used when adding AVB
# hash / hashtree footers.
if d.get("avb_enable") == "true":
- build_info = BuildInfo(d)
+ build_info = BuildInfo(d, use_legacy_id=True)
for partition in PARTITIONS_WITH_BUILD_PROP:
fingerprint = build_info.GetPartitionFingerprint(partition)
if fingerprint:
d["avb_{}_salt".format(partition)] = sha256(
fingerprint.encode()).hexdigest()
+
+ # Set the vbmeta digest if exists
+ try:
+ d["vbmeta_digest"] = read_helper("META/vbmeta_digest.txt").rstrip()
+ except KeyError:
+ pass
+
try:
d["ab_partitions"] = read_helper("META/ab_partitions.txt").split("\n")
except KeyError:
@@ -1339,7 +1384,7 @@
vbmeta_image = MakeTempFile()
os.rename(output_image, vbmeta_image)
- build_info = BuildInfo(OPTIONS.info_dict)
+ build_info = BuildInfo(OPTIONS.info_dict, use_legacy_id=True)
version_incremental = build_info.GetBuildProp("ro.build.version.incremental")
aftltool = OPTIONS.aftl_tool_path
server_argument_list = [OPTIONS.aftl_server, OPTIONS.aftl_key_path]
diff --git a/tools/releasetools/jarjar-rules.txt b/tools/releasetools/jarjar-rules.txt
new file mode 100644
index 0000000..40043a8
--- /dev/null
+++ b/tools/releasetools/jarjar-rules.txt
@@ -0,0 +1 @@
+rule com.google.protobuf.nano.** com.android.framework.protobuf.nano.@1
diff --git a/tools/releasetools/ota_from_target_files.py b/tools/releasetools/ota_from_target_files.py
index abbcfa0..61c8212 100755
--- a/tools/releasetools/ota_from_target_files.py
+++ b/tools/releasetools/ota_from_target_files.py
@@ -215,6 +215,12 @@
--disable_vabc
Disable Virtual A/B Compression, for builds that have compression enabled
by default.
+
+ --vabc_downgrade
+ Don't disable Virtual A/B Compression for downgrading OTAs.
+ For VABC downgrades, we must finish merging before doing data wipe, and
+ since data wipe is required for downgrading OTA, this might cause long
+ wait time in recovery.
"""
from __future__ import print_function
@@ -278,6 +284,7 @@
OPTIONS.custom_images = {}
OPTIONS.disable_vabc = False
OPTIONS.spl_downgrade = False
+OPTIONS.vabc_downgrade = False
POSTINSTALL_CONFIG = 'META/postinstall_config.txt'
DYNAMIC_PARTITION_INFO = 'META/dynamic_partitions_info.txt'
@@ -1284,6 +1291,8 @@
elif o == "--spl_downgrade":
OPTIONS.spl_downgrade = True
OPTIONS.wipe_user_data = True
+ elif o == "--vabc_downgrade":
+ OPTIONS.vabc_downgrade = True
else:
return False
return True
@@ -1326,7 +1335,8 @@
"partial=",
"custom_image=",
"disable_vabc",
- "spl_downgrade"
+ "spl_downgrade",
+ "vabc_downgrade",
], extra_option_handler=option_handler)
if len(args) != 2:
@@ -1347,7 +1357,14 @@
else:
OPTIONS.info_dict = ParseInfoDict(args[0])
- if OPTIONS.downgrade:
+ if OPTIONS.wipe_user_data:
+ if not OPTIONS.vabc_downgrade:
+ logger.info("Detected downgrade/datawipe OTA."
+ "When wiping userdata, VABC OTA makes the user "
+ "wait in recovery mode for merge to finish. Disable VABC by "
+ "default. If you really want to do VABC downgrade, pass "
+ "--vabc_downgrade")
+ OPTIONS.disable_vabc = True
# We should only allow downgrading incrementals (as opposed to full).
# Otherwise the device may go back from arbitrary build with this full
# OTA package.
diff --git a/tools/releasetools/ota_metadata.proto b/tools/releasetools/ota_metadata.proto
index 7aaca6f..ed9d0c3 100644
--- a/tools/releasetools/ota_metadata.proto
+++ b/tools/releasetools/ota_metadata.proto
@@ -23,6 +23,8 @@
package build.tools.releasetools;
option optimize_for = LITE_RUNTIME;
+option java_package = "android.ota";
+option java_outer_classname = "OtaPackageMetadata";
// The build information of a particular partition on the device.
message PartitionState {
diff --git a/tools/releasetools/sign_target_files_apks.py b/tools/releasetools/sign_target_files_apks.py
index 313d1e6..dd2de36 100755
--- a/tools/releasetools/sign_target_files_apks.py
+++ b/tools/releasetools/sign_target_files_apks.py
@@ -629,6 +629,10 @@
elif OPTIONS.replace_verity_keyid and filename == "BOOT/cmdline":
pass
+ # Skip the vbmeta digest as we will recalculate it.
+ elif filename == "META/vbmeta_digest.txt":
+ pass
+
# Skip the care_map as we will regenerate the system/vendor images.
elif filename in ["META/care_map.pb", "META/care_map.txt"]:
pass
@@ -1029,9 +1033,8 @@
extra_args = OPTIONS.gki_signing_extra_args
if extra_args:
- print('Setting extra GKI signing args: "%s"' % (extra_args))
- misc_info["gki_signing_signature_args"] = (
- misc_info.get("gki_signing_signature_args", '') + ' ' + extra_args)
+ print('Setting GKI signing args: "%s"' % (extra_args))
+ misc_info["gki_signing_signature_args"] = extra_args
def BuildKeyMap(misc_info, key_mapping_options):
diff --git a/tools/releasetools/test_common.py b/tools/releasetools/test_common.py
index a516366..1a00549 100644
--- a/tools/releasetools/test_common.py
+++ b/tools/releasetools/test_common.py
@@ -48,6 +48,22 @@
class BuildInfoTest(test_utils.ReleaseToolsTestCase):
+ TEST_INFO_FINGERPRINT_DICT = {
+ 'build.prop': common.PartitionBuildProps.FromDictionary(
+ 'system', {
+ 'ro.product.brand': 'product-brand',
+ 'ro.product.name': 'product-name',
+ 'ro.product.device': 'product-device',
+ 'ro.build.version.release': 'version-release',
+ 'ro.build.id': 'build-id',
+ 'ro.build.version.incremental': 'version-incremental',
+ 'ro.build.type': 'build-type',
+ 'ro.build.tags': 'build-tags',
+ 'ro.build.version.sdk': 30,
+ }
+ ),
+ }
+
TEST_INFO_DICT = {
'build.prop': common.PartitionBuildProps.FromDictionary(
'system', {
@@ -202,6 +218,33 @@
'ro.build.fingerprint'] = 'bad\x80fingerprint'
self.assertRaises(ValueError, common.BuildInfo, info_dict, None)
+ def test_init_goodFingerprint(self):
+ info_dict = copy.deepcopy(self.TEST_INFO_FINGERPRINT_DICT)
+ build_info = common.BuildInfo(info_dict)
+ self.assertEqual(
+ 'product-brand/product-name/product-device:version-release/build-id/'
+ 'version-incremental:build-type/build-tags', build_info.fingerprint)
+
+ build_props = info_dict['build.prop'].build_props
+ del build_props['ro.build.id']
+ build_props['ro.build.legacy.id'] = 'legacy-build-id'
+ build_info = common.BuildInfo(info_dict, use_legacy_id=True)
+ self.assertEqual(
+ 'product-brand/product-name/product-device:version-release/'
+ 'legacy-build-id/version-incremental:build-type/build-tags',
+ build_info.fingerprint)
+
+ self.assertRaises(common.ExternalError, common.BuildInfo, info_dict, None,
+ False)
+
+ info_dict['avb_enable'] = 'true'
+ info_dict['vbmeta_digest'] = 'abcde12345'
+ build_info = common.BuildInfo(info_dict, use_legacy_id=False)
+ self.assertEqual(
+ 'product-brand/product-name/product-device:version-release/'
+ 'legacy-build-id.abcde123/version-incremental:build-type/build-tags',
+ build_info.fingerprint)
+
def test___getitem__(self):
target_info = common.BuildInfo(self.TEST_INFO_DICT, None)
self.assertEqual('value1', target_info['property1'])
diff --git a/tools/releasetools/test_sign_target_files_apks.py b/tools/releasetools/test_sign_target_files_apks.py
index 64e27a2..ad9e657 100644
--- a/tools/releasetools/test_sign_target_files_apks.py
+++ b/tools/releasetools/test_sign_target_files_apks.py
@@ -602,7 +602,7 @@
expected_dict = {
'gki_signing_key_path': 'release_gki_key',
'gki_signing_algorithm': 'release_gki_algorithm',
- 'gki_signing_signature_args': 'default_gki_signature_args release_gki_signature_extra_args',
+ 'gki_signing_signature_args': 'release_gki_signature_extra_args',
}
ReplaceGkiSigningKey(misc_info)
self.assertDictEqual(expected_dict, misc_info)
diff --git a/tools/releasetools/test_verity_utils.py b/tools/releasetools/test_verity_utils.py
index a850390..e2a022a 100644
--- a/tools/releasetools/test_verity_utils.py
+++ b/tools/releasetools/test_verity_utils.py
@@ -27,7 +27,8 @@
from test_utils import (
get_testdata_dir, ReleaseToolsTestCase, SkipIfExternalToolsUnavailable)
from verity_utils import (
- CreateHashtreeInfoGenerator, CreateVerityImageBuilder, HashtreeInfo,
+ CalculateVbmetaDigest, CreateHashtreeInfoGenerator,
+ CreateVerityImageBuilder, HashtreeInfo,
VerifiedBootVersion1HashtreeInfoGenerator)
BLOCK_SIZE = common.BLOCK_SIZE
@@ -388,3 +389,31 @@
self.assertLess(
_SizeCalculator(min_partition_size - BLOCK_SIZE),
image_size)
+
+ @SkipIfExternalToolsUnavailable()
+ def test_CalculateVbmetaDigest(self):
+ prop_dict = copy.deepcopy(self.DEFAULT_PROP_DICT)
+ verity_image_builder = CreateVerityImageBuilder(prop_dict)
+ self.assertEqual(2, verity_image_builder.version)
+
+ input_dir = common.MakeTempDir()
+ image_dir = common.MakeTempDir()
+ os.mkdir(os.path.join(image_dir, 'IMAGES'))
+ system_image = os.path.join(image_dir, 'IMAGES', 'system.img')
+ system_image_size = verity_image_builder.CalculateMaxImageSize()
+ cmd = ['mkuserimg_mke2fs', input_dir, system_image, 'ext4', '/system',
+ str(system_image_size), '-j', '0', '-s']
+ common.RunAndCheckOutput(cmd)
+ verity_image_builder.Build(system_image)
+
+ # Additionally make vbmeta image
+ vbmeta_image = os.path.join(image_dir, 'IMAGES', 'vbmeta.img')
+ cmd = ['avbtool', 'make_vbmeta_image', '--include_descriptors_from_image',
+ system_image, '--output', vbmeta_image]
+ common.RunAndCheckOutput(cmd)
+
+ # Verify the verity metadata.
+ cmd = ['avbtool', 'verify_image', '--image', vbmeta_image]
+ common.RunAndCheckOutput(cmd)
+ digest = CalculateVbmetaDigest(image_dir, 'avbtool')
+ self.assertIsNotNone(digest)
diff --git a/tools/releasetools/verity_utils.py b/tools/releasetools/verity_utils.py
index 8faa2d1..a08ddbe 100644
--- a/tools/releasetools/verity_utils.py
+++ b/tools/releasetools/verity_utils.py
@@ -26,6 +26,7 @@
import os.path
import shlex
import struct
+import sys
import common
import sparse_img
@@ -739,6 +740,30 @@
return int(output.split()[0]) * 1024
+def CalculateVbmetaDigest(extracted_dir, avbtool):
+ """Calculates the vbmeta digest of the images in the extracted target_file"""
+
+ images_dir = common.MakeTempDir()
+ for name in ("PREBUILT_IMAGES", "RADIO", "IMAGES"):
+ path = os.path.join(extracted_dir, name)
+ if not os.path.exists(path):
+ continue
+
+ # Create symlink for image files under PREBUILT_IMAGES, RADIO and IMAGES,
+ # and put them into one directory.
+ for filename in os.listdir(path):
+ if not filename.endswith(".img"):
+ continue
+ symlink_path = os.path.join(images_dir, filename)
+ # The files in latter directory overwrite the existing links
+ common.RunAndCheckOutput(
+ ['ln', '-sf', os.path.join(path, filename), symlink_path])
+
+ cmd = [avbtool, "calculate_vbmeta_digest", "--image",
+ os.path.join(images_dir, 'vbmeta.img')]
+ return common.RunAndCheckOutput(cmd)
+
+
def main(argv):
if len(argv) != 2:
print(__doc__)