Merge "Add an option to input the boot variables for OTA package generation"
diff --git a/core/Makefile b/core/Makefile
index 6926b26..35d744a 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -2830,6 +2830,41 @@
endef
# -----------------------------------------------------------------
+# custom images
+INSTALLED_CUSTOMIMAGES_TARGET :=
+
+ifneq ($(strip $(BOARD_CUSTOMIMAGES_PARTITION_LIST)),)
+INTERNAL_AVB_CUSTOMIMAGES_SIGNING_ARGS :=
+
+# Sign custom image.
+# $(1): the prebuilt custom image.
+# $(2): the mount point of the prebuilt custom image.
+# $(3): the signed custom image target.
+define sign_custom_image
+$(3): $(1) $(INTERNAL_USERIMAGES_DEPS)
+ @echo Target custom image: $(3)
+ mkdir -p $(dir $(3))
+ cp $(1) $(3)
+ifeq ($(BOARD_AVB_ENABLE),true)
+ PATH=$(INTERNAL_USERIMAGES_BINARY_PATHS):$$$$PATH \
+ $(AVBTOOL) add_hashtree_footer \
+ --image $(3) \
+ --key $(BOARD_AVB_$(call to-upper,$(2))_KEY_PATH) \
+ --algorithm $(BOARD_AVB_$(call to-upper,$(2))_ALGORITHM) \
+ --partition_size $(BOARD_AVB_$(call to-upper,$(2))_PARTITION_SIZE) \
+ --partition_name $(2) \
+ $(INTERNAL_AVB_CUSTOMIMAGES_SIGNING_ARGS) \
+ $(BOARD_AVB_$(call to-upper,$(2))_ADD_HASHTREE_FOOTER_ARGS)
+endif
+INSTALLED_CUSTOMIMAGES_TARGET += $(3)
+endef
+
+$(foreach partition,$(BOARD_CUSTOMIMAGES_PARTITION_LIST), \
+ $(foreach image,$(BOARD_AVB_$(call to-upper,$(partition))_IMAGE_LIST), \
+ $(eval $(call sign_custom_image,$(image),$(partition),$(PRODUCT_OUT)/$(notdir $(image))))))
+endif
+
+# -----------------------------------------------------------------
# vbmeta image
ifeq ($(BOARD_AVB_ENABLE),true)
@@ -3000,6 +3035,18 @@
--include_descriptors_from_image $(call images-for-partitions,$(1)))))
endef
+# Checks and sets build variables for a custom chained partition to include it into vbmeta.img.
+# $(1): the custom partition to enable AVB chain.
+define check-and-set-custom-avb-chain-args
+$(eval part := $(1))
+$(eval PART=$(call to-upper,$(part)))
+$(eval _rollback_index_location := BOARD_AVB_$(PART)_ROLLBACK_INDEX_LOCATION)
+$(if $($(_rollback_index_location)),,$(error $(_rollback_index_location) is not defined))
+
+INTERNAL_AVB_MAKE_VBMETA_IMAGE_ARGS += \
+ --chain_partition $(part):$($(_rollback_index_location)):$(AVB_CHAIN_KEY_DIR)/$(part).avbpubkey
+endef
+
ifdef INSTALLED_BOOTIMAGE_TARGET
$(eval $(call check-and-set-avb-args,boot))
endif
@@ -3043,6 +3090,11 @@
$(eval $(call check-and-set-avb-args,vbmeta_vendor))
endif
+ifneq ($(strip $(BOARD_CUSTOMIMAGES_PARTITION_LIST)),)
+$(foreach partition,$(BOARD_CUSTOMIMAGES_PARTITION_LIST), \
+ $(eval $(call check-and-set-custom-avb-chain-args,$(partition))))
+endif
+
# Add kernel cmdline descriptor for kernel to mount system.img as root with
# dm-verity. This works when system.img is either chained or not-chained:
# - chained: The --setup_as_rootfs_from_kernel option will add dm-verity kernel
@@ -3113,6 +3165,10 @@
$(if $(BOARD_AVB_VBMETA_VENDOR_KEY_PATH),\
$(hide) $(AVBTOOL) extract_public_key --key $(BOARD_AVB_VBMETA_VENDOR_KEY_PATH) \
--output $(1)/vbmeta_vendor.avbpubkey)
+ $(if $(BOARD_CUSTOMIMAGES_PARTITION_LIST),\
+ $(hide) $(foreach partition,$(BOARD_CUSTOMIMAGES_PARTITION_LIST), \
+ $(AVBTOOL) extract_public_key --key $(BOARD_AVB_$(call to-upper,$(partition))_KEY_PATH) \
+ --output $(1)/$(partition).avbpubkey;))
endef
# Builds a chained VBMeta image. This VBMeta image will contain the descriptors for the partitions
@@ -3180,6 +3236,7 @@
$(INSTALLED_SYSTEM_EXTIMAGE_TARGET) \
$(INSTALLED_ODMIMAGE_TARGET) \
$(INSTALLED_DTBOIMAGE_TARGET) \
+ $(INSTALLED_CUSTOMIMAGES_TARGET) \
$(INSTALLED_RECOVERYIMAGE_TARGET) \
$(INSTALLED_VBMETA_SYSTEMIMAGE_TARGET) \
$(INSTALLED_VBMETA_VENDORIMAGE_TARGET) \
@@ -3739,6 +3796,16 @@
$(hide) echo "avb_recovery_algorithm=$(BOARD_AVB_RECOVERY_ALGORITHM)" >> $@
$(hide) echo "avb_recovery_rollback_index_location=$(BOARD_AVB_RECOVERY_ROLLBACK_INDEX_LOCATION)" >> $@
endif # BOARD_AVB_RECOVERY_KEY_PATH
+ifneq (,$(strip $(BOARD_CUSTOMIMAGES_PARTITION_LIST)))
+ $(hide) echo "avb_custom_images_partition_list=$(BOARD_CUSTOMIMAGES_PARTITION_LIST)" >> $@
+ $(hide) $(foreach partition,$(BOARD_CUSTOMIMAGES_PARTITION_LIST), \
+ echo "avb_$(partition)_key_path=$(BOARD_AVB_$(call to-upper,$(partition))_KEY_PATH)" >> $@; \
+ echo "avb_$(partition)_algorithm=$(BOARD_AVB_$(call to-upper,$(partition))_ALGORITHM)" >> $@; \
+ echo "avb_$(partition)_add_hashtree_footer_args=$(BOARD_AVB_$(call to-upper,$(partition))_ADD_HASHTREE_FOOTER_ARGS)" >> $@; \
+ echo "avb_$(partition)_rollback_index_location=$(BOARD_AVB_$(call to-upper,$(partition))_ROLLBACK_INDEX_LOCATION)" >> $@; \
+ echo "avb_$(partition)_partition_size=$(BOARD_AVB_$(call to-upper,$(partition))_PARTITION_SIZE)" >> $@; \
+ echo "avb_$(partition)_image_list=$(foreach image,$(BOARD_AVB_$(call to-upper,$(partition))_IMAGE_LIST),$(notdir $(image)))" >> $@;)
+endif # BOARD_CUSTOMIMAGES_PARTITION_LIST
ifneq (,$(strip $(BOARD_AVB_VBMETA_SYSTEM)))
$(hide) echo "avb_vbmeta_system=$(BOARD_AVB_VBMETA_SYSTEM)" >> $@
$(hide) echo "avb_vbmeta_system_args=$(BOARD_AVB_MAKE_VBMETA_SYSTEM_IMAGE_ARGS)" >> $@
@@ -3972,6 +4039,7 @@
$(INSTALLED_VBMETAIMAGE_TARGET) \
$(INSTALLED_ODMIMAGE_TARGET) \
$(INSTALLED_DTBOIMAGE_TARGET) \
+ $(INSTALLED_CUSTOMIMAGES_TARGET) \
$(INTERNAL_SYSTEMOTHERIMAGE_FILES) \
$(INSTALLED_ANDROID_INFO_TXT_TARGET) \
$(INSTALLED_KERNEL_TARGET) \
@@ -4216,6 +4284,11 @@
$(hide) mkdir -p $(zip_root)/PREBUILT_IMAGES
$(hide) cp $(INSTALLED_DTBOIMAGE_TARGET) $(zip_root)/PREBUILT_IMAGES/
endif # BOARD_PREBUILT_DTBOIMAGE
+ifneq ($(strip $(BOARD_CUSTOMIMAGES_PARTITION_LIST)),)
+ $(hide) mkdir -p $(zip_root)/PREBUILT_IMAGES
+ $(hide) $(foreach partition,$(BOARD_CUSTOMIMAGES_PARTITION_LIST), \
+ $(foreach image,$(BOARD_AVB_$(call to-upper,$(partition))_IMAGE_LIST),cp $(image) $(zip_root)/PREBUILT_IMAGES/;))
+endif # BOARD_CUSTOMIMAGES_PARTITION_LIST
@# The radio images in BOARD_PACK_RADIOIMAGES will be additionally copied from RADIO/ into
@# IMAGES/, which then will be added into <product>-img.zip. Such images must be listed in
@# INSTALLED_RADIOIMAGE_TARGET.
diff --git a/envsetup.sh b/envsetup.sh
index 8699a19..0ec7e6f 100644
--- a/envsetup.sh
+++ b/envsetup.sh
@@ -51,7 +51,8 @@
}
# Get all the build variables needed by this script in a single call to the build system.
-function build_build_var_cache() {
+function build_build_var_cache()
+{
local T=$(gettop)
# Grep out the variable names from the script.
cached_vars=(`cat $T/build/envsetup.sh | tr '()' ' ' | awk '{for(i=1;i<=NF;i++) if($i~/get_build_var/) print $(i+1)}' | sort -u | tr '\n' ' '`)
@@ -63,7 +64,8 @@
--var-prefix=var_cache_ \
--abs-var-prefix=abs_var_cache_`
local ret=$?
- if [ $ret -ne 0 ]; then
+ if [ $ret -ne 0 ]
+ then
unset build_dicts_script
return $ret
fi
@@ -71,7 +73,8 @@
eval "$build_dicts_script"
ret=$?
unset build_dicts_script
- if [ $ret -ne 0 ]; then
+ if [ $ret -ne 0 ]
+ then
return $ret
fi
BUILD_VAR_CACHE_READY="true"
@@ -79,7 +82,8 @@
# Delete the build var cache, so that we can still call into the build system
# to get build variables not listed in this script.
-function destroy_build_var_cache() {
+function destroy_build_var_cache()
+{
unset BUILD_VAR_CACHE_READY
local v
for v in $cached_vars; do
@@ -93,10 +97,12 @@
}
# Get the value of a build variable as an absolute path.
-function get_abs_build_var() {
- if [ "$BUILD_VAR_CACHE_READY" == "true" ]; then
+function get_abs_build_var()
+{
+ if [ "$BUILD_VAR_CACHE_READY" = "true" ]
+ then
eval "echo \"\${abs_var_cache_$1}\""
- return
+ return
fi
local T=$(gettop)
@@ -108,8 +114,10 @@
}
# Get the exact value of a build variable.
-function get_build_var() {
- if [ "$BUILD_VAR_CACHE_READY" == "true" ]; then
+function get_build_var()
+{
+ if [ "$BUILD_VAR_CACHE_READY" = "true" ]
+ then
eval "echo \"\${var_cache_$1}\""
return 0
fi
@@ -123,7 +131,8 @@
}
# check to see if the supplied product is one we can build
-function check_product() {
+function check_product()
+{
local T=$(gettop)
if [ ! "$T" ]; then
echo "Couldn't locate the top of the tree. Try setting TOP." >&2
@@ -140,18 +149,21 @@
VARIANT_CHOICES=(user userdebug eng)
# check to see if the supplied variant is valid
-function check_variant() {
+function check_variant()
+{
local v
for v in ${VARIANT_CHOICES[@]}
do
- if [ "$v" == "$1" ]; then
+ if [ "$v" = "$1" ]
+ then
return 0
fi
done
return 1
}
-function setpaths() {
+function setpaths()
+{
local T=$(gettop)
if [ ! "$T" ]; then
echo "Couldn't locate the top of the tree. Try setting TOP."
@@ -173,10 +185,10 @@
# due to "C:\Program Files" being in the path.
# out with the old
- if [ -n "$ANDROID_BUILD_PATHS" ]; then
+ if [ -n "$ANDROID_BUILD_PATHS" ] ; then
export PATH=${PATH/$ANDROID_BUILD_PATHS/}
fi
- if [ -n "$ANDROID_PRE_BUILD_PATHS" ]; then
+ if [ -n "$ANDROID_PRE_BUILD_PATHS" ] ; then
export PATH=${PATH/$ANDROID_PRE_BUILD_PATHS/}
# strip leading ':', if any
export PATH=${PATH/:%/}
@@ -197,18 +209,14 @@
local ARCH=$(get_build_var TARGET_ARCH)
local toolchaindir toolchaindir2=
case $ARCH in
- x86)
- toolchaindir=x86/x86_64-linux-android-$targetgccversion/bin
+ x86) toolchaindir=x86/x86_64-linux-android-$targetgccversion/bin
;;
- x86_64)
- toolchaindir=x86/x86_64-linux-android-$targetgccversion/bin
+ x86_64) toolchaindir=x86/x86_64-linux-android-$targetgccversion/bin
;;
- arm)
- toolchaindir=arm/arm-linux-androideabi-$targetgccversion/bin
+ arm) toolchaindir=arm/arm-linux-androideabi-$targetgccversion/bin
;;
- arm64)
- toolchaindir=aarch64/aarch64-linux-android-$targetgccversion/bin
- toolchaindir2=arm/arm-linux-androideabi-$targetgccversion2/bin
+ arm64) toolchaindir=aarch64/aarch64-linux-android-$targetgccversion/bin;
+ toolchaindir2=arm/arm-linux-androideabi-$targetgccversion2/bin
;;
*)
echo "Can't find toolchain for unknown architecture: $ARCH"
@@ -309,7 +317,8 @@
#export HOST_EXTRACFLAGS="-I "$T/system/kernel_headers/host_include
}
-function printconfig() {
+function printconfig()
+{
local T=$(gettop)
if [ ! "$T" ]; then
echo "Couldn't locate the top of the tree. Try setting TOP." >&2
@@ -318,7 +327,8 @@
get_build_var report_config
}
-function set_stuff_for_environment() {
+function set_stuff_for_environment()
+{
setpaths
set_sequence_number
@@ -327,7 +337,8 @@
export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01'
}
-function set_sequence_number() {
+function set_sequence_number()
+{
export BUILD_ENV_SEQUENCE_NUMBER=13
}
@@ -342,7 +353,8 @@
return 0
}
-function addcompletions() {
+function addcompletions()
+{
local T dir f
# Keep us from trying to run in something that's neither bash nor zsh.
@@ -370,7 +382,7 @@
fi
done
- if should_add_completion bit; then
+ if should_add_completion bit ; then
complete -C "bit --tab" bit
fi
if [ -z "$ZSH_VERSION" ]; then
@@ -383,7 +395,8 @@
complete -F _complete_android_module_names m
}
-function choosetype() {
+function choosetype()
+{
echo "Build type choices are:"
echo " 1. release"
echo " 2. debug"
@@ -398,7 +411,7 @@
while [ -z $TARGET_BUILD_TYPE ]
do
echo -n "Which would you like? ["$DEFAULT_NUM"] "
- if [ -z "$1" ]; then
+ if [ -z "$1" ] ; then
read ANSWER
else
echo $1
@@ -426,7 +439,7 @@
echo
;;
esac
- if [ -n "$1" ]; then
+ if [ -n "$1" ] ; then
break
fi
done
@@ -442,9 +455,10 @@
# that kinda works with a generic product, but really, you should
# pick a product by name.
#
-function chooseproduct() {
+function chooseproduct()
+{
local default_value
- if [ "x$TARGET_PRODUCT" != x ]; then
+ if [ "x$TARGET_PRODUCT" != x ] ; then
default_value=$TARGET_PRODUCT
else
default_value=aosp_arm
@@ -456,23 +470,24 @@
while [ -z "$TARGET_PRODUCT" ]
do
echo -n "Which product would you like? [$default_value] "
- if [ -z "$1" ]; then
+ if [ -z "$1" ] ; then
read ANSWER
else
echo $1
ANSWER=$1
fi
- if [ -z "$ANSWER" ]; then
+ if [ -z "$ANSWER" ] ; then
export TARGET_PRODUCT=$default_value
else
- if check_product $ANSWER; then
+ if check_product $ANSWER
+ then
export TARGET_PRODUCT=$ANSWER
else
echo "** Not a valid product: $ANSWER"
fi
fi
- if [ -n "$1" ]; then
+ if [ -n "$1" ] ; then
break
fi
done
@@ -482,7 +497,8 @@
destroy_build_var_cache
}
-function choosevariant() {
+function choosevariant()
+{
echo "Variant choices are:"
local index=1
local v
@@ -501,33 +517,35 @@
while [ -z "$TARGET_BUILD_VARIANT" ]
do
echo -n "Which would you like? [$default_value] "
- if [ -z "$1" ]; then
+ if [ -z "$1" ] ; then
read ANSWER
else
echo $1
ANSWER=$1
fi
- if [ -z "$ANSWER" ]; then
+ if [ -z "$ANSWER" ] ; then
export TARGET_BUILD_VARIANT=$default_value
- elif (echo -n $ANSWER | grep -q -e "^[0-9][0-9]*$"); then
- if [ "$ANSWER" -le "${#VARIANT_CHOICES[@]}" ]; then
+ elif (echo -n $ANSWER | grep -q -e "^[0-9][0-9]*$") ; then
+ if [ "$ANSWER" -le "${#VARIANT_CHOICES[@]}" ] ; then
export TARGET_BUILD_VARIANT=${VARIANT_CHOICES[@]:$(($ANSWER-1)):1}
fi
else
- if check_variant $ANSWER; then
+ if check_variant $ANSWER
+ then
export TARGET_BUILD_VARIANT=$ANSWER
else
echo "** Not a valid variant: $ANSWER"
fi
fi
- if [ -n "$1" ]; then
+ if [ -n "$1" ] ; then
break
fi
done
}
-function choosecombo() {
+function choosecombo()
+{
choosetype $1
echo
@@ -545,7 +563,8 @@
destroy_build_var_cache
}
-function add_lunch_combo() {
+function add_lunch_combo()
+{
if [ -n "$ZSH_VERSION" ]; then
echo -n "${funcfiletrace[1]}: "
else
@@ -554,7 +573,8 @@
echo "add_lunch_combo is obsolete. Use COMMON_LUNCH_CHOICES in your AndroidProducts.mk instead."
}
-function print_lunch_menu() {
+function print_lunch_menu()
+{
local uname=$(uname)
local choices
choices=$(TARGET_BUILD_APPS= get_build_var COMMON_LUNCH_CHOICES 2>/dev/null)
@@ -564,7 +584,8 @@
echo "You're building on" $uname
echo
- if [ $ret -ne 0 ]; then
+ if [ $ret -ne 0 ]
+ then
echo "Warning: Cannot display lunch menu."
echo
echo "Note: You can invoke lunch with an explicit target:"
@@ -587,7 +608,8 @@
echo
}
-function lunch() {
+function lunch()
+{
local answer
if [[ $# -gt 1 ]]; then
@@ -605,13 +627,17 @@
local selection=
- if [ -z "$answer" ]; then
+ if [ -z "$answer" ]
+ then
selection=aosp_arm-eng
- elif (echo -n $answer | grep -q -e "^[0-9][0-9]*$"); then
+ elif (echo -n $answer | grep -q -e "^[0-9][0-9]*$")
+ then
local choices=($(TARGET_BUILD_APPS= get_build_var COMMON_LUNCH_CHOICES))
- if [ $answer -le ${#choices[@]} ]; then
+ if [ $answer -le ${#choices[@]} ]
+ then
# array in zsh starts from 1 instead of 0.
- if [ -n "$ZSH_VERSION" ]; then
+ if [ -n "$ZSH_VERSION" ]
+ then
selection=${choices[$(($answer))]}
else
selection=${choices[$(($answer-1))]}
@@ -634,7 +660,8 @@
fi
fi
- if [ -z "$product" ]; then
+ if [ -z "$product" ]
+ then
echo
echo "Invalid lunch combo: $selection"
return 1
@@ -644,7 +671,8 @@
TARGET_BUILD_VARIANT=$variant \
TARGET_PLATFORM_VERSION=$version \
build_build_var_cache
- if [ $? -ne 0 ]; then
+ if [ $? -ne 0 ]
+ then
return 1
fi
@@ -666,7 +694,8 @@
unset COMMON_LUNCH_CHOICES_CACHE
# Tab completion for lunch.
-function _lunch() {
+function _lunch()
+{
local cur prev opts
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
@@ -682,7 +711,8 @@
# Configures the build to build unbundled apps.
# Run tapas with one or more app names (from LOCAL_PACKAGE_NAME)
-function tapas() {
+function tapas()
+{
local showHelp="$(echo $* | xargs -n 1 echo | \grep -E '^(help)$' | xargs)"
local arch="$(echo $* | xargs -n 1 echo | \grep -E '^(arm|x86|arm64|x86_64)$' | xargs)"
local variant="$(echo $* | xargs -n 1 echo | \grep -E '^(user|userdebug|eng)$' | xargs)"
@@ -709,15 +739,9 @@
local product=aosp_arm
case $arch in
- x86)
- product=aosp_x86
- ;;
- arm64)
- product=aosp_arm64
- ;;
- x86_64)
- product=aosp_x86_64
- ;;
+ x86) product=aosp_x86;;
+ arm64) product=aosp_arm64;;
+ x86_64) product=aosp_x86_64;;
esac
if [ -z "$variant" ]; then
variant=eng
@@ -741,13 +765,14 @@
destroy_build_var_cache
}
-function gettop {
+function gettop
+{
local TOPFILE=build/make/core/envsetup.mk
- if [ -n "$TOP" -a -f "$TOP/$TOPFILE" ]; then
+ if [ -n "$TOP" -a -f "$TOP/$TOPFILE" ] ; then
# The following circumlocution ensures we remove symlinks from TOP.
(cd $TOP; PWD= /bin/pwd)
else
- if [ -f $TOPFILE ]; then
+ if [ -f $TOPFILE ] ; then
# The following circumlocution (repeated below as well) ensures
# that we record the true directory name and not one that is
# faked up with symlink names.
@@ -767,7 +792,8 @@
fi
}
-function croot() {
+function croot()
+{
local T=$(gettop)
if [ "$T" ]; then
if [ "$1" ]; then
@@ -780,7 +806,8 @@
fi
}
-function _croot() {
+function _croot()
+{
local T=$(gettop)
if [ "$T" ]; then
local cur="${COMP_WORDS[COMP_CWORD]}"
@@ -791,7 +818,8 @@
fi
}
-function cproj() {
+function cproj()
+{
local TOPFILE=build/make/core/envsetup.mk
local HERE=$PWD
local T=
@@ -812,17 +840,17 @@
function qpid() {
local prepend=''
local append=''
- if [ "$1" == "--exact" ]; then
+ if [ "$1" = "--exact" ]; then
prepend=' '
append='$'
shift
- elif [ "$1" == "--help" -o "$1" == "-h" ]; then
+ elif [ "$1" = "--help" -o "$1" = "-h" ]; then
echo "usage: qpid [[--exact] <process name|pid>"
return 255
fi
local EXE="$1"
- if [ "$EXE" ]; then
+ if [ "$EXE" ] ; then
qpid | \grep "$prepend$EXE$append"
else
adb shell ps \
@@ -838,87 +866,92 @@
# if its core-file-size limit is not set already.
# NOTE: Core dumps are written to ramdisk; they will not survive a reboot!
-function coredump_setup() {
- echo "Getting root..."
- adb root
- adb wait-for-device
+function coredump_setup()
+{
+ echo "Getting root...";
+ adb root;
+ adb wait-for-device;
- echo "Remounting root partition read-write..."
- adb shell mount -w -o remount -t rootfs rootfs
- sleep 1
- adb wait-for-device
- adb shell mkdir -p /cores
- adb shell mount -t tmpfs tmpfs /cores
- adb shell chmod 0777 /cores
+ echo "Remounting root partition read-write...";
+ adb shell mount -w -o remount -t rootfs rootfs;
+ sleep 1;
+ adb wait-for-device;
+ adb shell mkdir -p /cores;
+ adb shell mount -t tmpfs tmpfs /cores;
+ adb shell chmod 0777 /cores;
- echo "Granting SELinux permission to dump in /cores..."
- adb shell restorecon -R /cores
+ echo "Granting SELinux permission to dump in /cores...";
+ adb shell restorecon -R /cores;
- echo "Set core pattern."
- adb shell 'echo /cores/core.%p > /proc/sys/kernel/core_pattern'
+ echo "Set core pattern.";
+ adb shell 'echo /cores/core.%p > /proc/sys/kernel/core_pattern';
echo "Done."
}
# coredump_enable - enable core dumps for the specified process
-# $1 == PID of process (e.g., $(pid mediaserver))
+# $1 = PID of process (e.g., $(pid mediaserver))
#
# NOTE: coredump_setup must have been called as well for a core
# dump to actually be generated.
-function coredump_enable() {
- local PID=$1
+function coredump_enable()
+{
+ local PID=$1;
if [ -z "$PID" ]; then
- printf "Expecting a PID!\n"
- return
- fi
- echo "Setting core limit for $PID to infinite..."
+ printf "Expecting a PID!\n";
+ return;
+ fi;
+ echo "Setting core limit for $PID to infinite...";
adb shell /system/bin/ulimit -p $PID -c unlimited
}
# core - send SIGV and pull the core for process
-# $1 == PID of process (e.g., $(pid mediaserver))
+# $1 = PID of process (e.g., $(pid mediaserver))
#
# NOTE: coredump_setup must be called once per boot for core dumps to be
# enabled globally.
-function core() {
- local PID=$1
+function core()
+{
+ local PID=$1;
if [ -z "$PID" ]; then
- printf "Expecting a PID!\n"
- return
- fi
+ printf "Expecting a PID!\n";
+ return;
+ fi;
- local CORENAME=core.$PID
- local COREPATH=/cores/$CORENAME
- local SIG=SEGV
+ local CORENAME=core.$PID;
+ local COREPATH=/cores/$CORENAME;
+ local SIG=SEGV;
- coredump_enable $1
+ coredump_enable $1;
- local done=0
+ local done=0;
while [ $(adb shell "[ -d /proc/$PID ] && echo -n yes") ]; do
- printf "\tSending SIG%s to %d...\n" $SIG $PID
- adb shell kill -$SIG $PID
- sleep 1
- done
+ printf "\tSending SIG%s to %d...\n" $SIG $PID;
+ adb shell kill -$SIG $PID;
+ sleep 1;
+ done;
- adb shell "while [ ! -f $COREPATH ]; do echo waiting for $COREPATH to be generated; sleep 1; done"
- echo "Done: core is under $COREPATH on device."
+ adb shell "while [ ! -f $COREPATH ] ; do echo waiting for $COREPATH to be generated; sleep 1; done"
+ echo "Done: core is under $COREPATH on device.";
}
# systemstack - dump the current stack trace of all threads in the system process
# to the usual ANR traces file
-function systemstack() {
+function systemstack()
+{
stacks system_server
}
# Read the ELF header from /proc/$PID/exe to determine if the process is
# 64-bit.
-function is64bit() {
+function is64bit()
+{
local PID="$1"
- if [ "$PID" ]; then
- if [[ "$(adb shell cat /proc/$PID/exe | xxd -l 1 -s 4 -p)" -eq "02" ]]; then
+ if [ "$PID" ] ; then
+ if [[ "$(adb shell cat /proc/$PID/exe | xxd -l 1 -s 4 -p)" -eq "02" ]] ; then
echo "64"
else
echo ""
@@ -930,90 +963,107 @@
case `uname -s` in
Darwin)
- function sgrep() {
+ function sgrep()
+ {
find -E . -name .repo -prune -o -name .git -prune -o -type f -iregex '.*\.(c|h|cc|cpp|hpp|S|java|xml|sh|mk|aidl|vts|proto)' \
-exec grep --color -n "$@" {} +
}
+
;;
*)
- function sgrep() {
+ function sgrep()
+ {
find . -name .repo -prune -o -name .git -prune -o -type f -iregex '.*\.\(c\|h\|cc\|cpp\|hpp\|S\|java\|xml\|sh\|mk\|aidl\|vts\|proto\)' \
-exec grep --color -n "$@" {} +
}
;;
esac
-function gettargetarch {
+function gettargetarch
+{
get_build_var TARGET_ARCH
}
-function ggrep() {
+function ggrep()
+{
find . -name .repo -prune -o -name .git -prune -o -name out -prune -o -type f -name "*\.gradle" \
-exec grep --color -n "$@" {} +
}
-function gogrep() {
+function gogrep()
+{
find . -name .repo -prune -o -name .git -prune -o -name out -prune -o -type f -name "*\.go" \
-exec grep --color -n "$@" {} +
}
-function jgrep() {
+function jgrep()
+{
find . -name .repo -prune -o -name .git -prune -o -name out -prune -o -type f -name "*\.java" \
-exec grep --color -n "$@" {} +
}
-function cgrep() {
+function cgrep()
+{
find . -name .repo -prune -o -name .git -prune -o -name out -prune -o -type f \( -name '*.c' -o -name '*.cc' -o -name '*.cpp' -o -name '*.h' -o -name '*.hpp' \) \
-exec grep --color -n "$@" {} +
}
-function resgrep() {
+function resgrep()
+{
local dir
for dir in `find . -name .repo -prune -o -name .git -prune -o -name out -prune -o -name res -type d`; do
find $dir -type f -name '*\.xml' -exec grep --color -n "$@" {} +
done
}
-function mangrep() {
+function mangrep()
+{
find . -name .repo -prune -o -name .git -prune -o -path ./out -prune -o -type f -name 'AndroidManifest.xml' \
-exec grep --color -n "$@" {} +
}
-function owngrep() {
+function owngrep()
+{
find . -name .repo -prune -o -name .git -prune -o -path ./out -prune -o -type f -name 'OWNERS' \
-exec grep --color -n "$@" {} +
}
-function sepgrep() {
+function sepgrep()
+{
find . -name .repo -prune -o -name .git -prune -o -path ./out -prune -o -name sepolicy -type d \
-exec grep --color -n -r --exclude-dir=\.git "$@" {} +
}
-function rcgrep() {
+function rcgrep()
+{
find . -name .repo -prune -o -name .git -prune -o -name out -prune -o -type f -name "*\.rc*" \
-exec grep --color -n "$@" {} +
}
case `uname -s` in
Darwin)
- function mgrep() {
+ function mgrep()
+ {
find -E . -name .repo -prune -o -name .git -prune -o -path ./out -prune -o \( -iregex '.*/(Makefile|Makefile\..*|.*\.make|.*\.mak|.*\.mk|.*\.bp)' -o -regex '(.*/)?(build|soong)/.*[^/]*\.go' \) -type f \
-exec grep --color -n "$@" {} +
}
- function treegrep() {
+ function treegrep()
+ {
find -E . -name .repo -prune -o -name .git -prune -o -type f -iregex '.*\.(c|h|cpp|hpp|S|java|xml)' \
-exec grep --color -n -i "$@" {} +
}
;;
*)
- function mgrep() {
+ function mgrep()
+ {
find . -name .repo -prune -o -name .git -prune -o -path ./out -prune -o \( -regextype posix-egrep -iregex '(.*\/Makefile|.*\/Makefile\..*|.*\.make|.*\.mak|.*\.mk|.*\.bp)' -o -regextype posix-extended -regex '(.*/)?(build|soong)/.*[^/]*\.go' \) -type f \
-exec grep --color -n "$@" {} +
}
- function treegrep() {
+ function treegrep()
+ {
find . -name .repo -prune -o -name .git -prune -o -regextype posix-egrep -iregex '.*\.(c|h|cpp|hpp|S|java|xml)' -type f \
-exec grep --color -n -i "$@" {} +
}
@@ -1021,11 +1071,13 @@
;;
esac
-function getprebuilt {
+function getprebuilt
+{
get_abs_build_var ANDROID_PREBUILTS
}
-function tracedmdump() {
+function tracedmdump()
+{
local T=$(gettop)
if [ ! "$T" ]; then
echo "Couldn't locate the top of the tree. Try setting TOP."
@@ -1036,18 +1088,18 @@
local KERNEL=$T/prebuilts/qemu-kernel/$arch/vmlinux-qemu
local TRACE=$1
- if [ ! "$TRACE" ]; then
+ if [ ! "$TRACE" ] ; then
echo "usage: tracedmdump tracename"
return
fi
- if [ ! -r "$KERNEL" ]; then
+ if [ ! -r "$KERNEL" ] ; then
echo "Error: cannot find kernel: '$KERNEL'"
return
fi
local BASETRACE=$(basename $TRACE)
- if [ "$BASETRACE" == "$TRACE" ]; then
+ if [ "$BASETRACE" = "$TRACE" ] ; then
TRACE=$ANDROID_PRODUCT_OUT/traces/$TRACE
fi
@@ -1073,23 +1125,24 @@
# communicate with a running device or emulator, set up necessary state,
# and run the hat command.
-function runhat() {
+function runhat()
+{
# process standard adb options
local adbTarget=""
- if [ "$1" == "-d" -o "$1" == "-e" ]; then
+ if [ "$1" = "-d" -o "$1" = "-e" ]; then
adbTarget=$1
shift 1
- elif [ "$1" == "-s" ]; then
+ elif [ "$1" = "-s" ]; then
adbTarget="$1 $2"
shift 2
fi
local adbOptions=${adbTarget}
- #echo adbOptions == ${adbOptions}
+ #echo adbOptions = ${adbOptions}
# runhat options
local targetPid=$1
- if [ "$targetPid" == "" ]; then
+ if [ "$targetPid" = "" ]; then
echo "Usage: runhat [ -d | -e | -s serial ] target-pid"
return
fi
@@ -1122,7 +1175,8 @@
hat -JXmx512m $localFile
}
-function getbugreports() {
+function getbugreports()
+{
local reports=(`adb shell ls /sdcard/bugreports | tr -d '\r'`)
if [ ! "$reports" ]; then
@@ -1139,18 +1193,21 @@
done
}
-function getsdcardpath() {
+function getsdcardpath()
+{
adb ${adbOptions} shell echo -n \$\{EXTERNAL_STORAGE\}
}
-function getscreenshotpath() {
+function getscreenshotpath()
+{
echo "$(getsdcardpath)/Pictures/Screenshots"
}
-function getlastscreenshot() {
+function getlastscreenshot()
+{
local screenshot_path=$(getscreenshotpath)
local screenshot=`adb ${adbOptions} ls ${screenshot_path} | grep Screenshot_[0-9-]*.*\.png | sort -rk 3 | cut -d " " -f 4 | head -n 1`
- if [ "$screenshot" == "" ]; then
+ if [ "$screenshot" = "" ]; then
echo "No screenshots found."
return
fi
@@ -1158,7 +1215,8 @@
adb ${adbOptions} pull ${screenshot_path}/${screenshot}
}
-function startviewserver() {
+function startviewserver()
+{
local port=4939
if [ $# -gt 0 ]; then
port=$1
@@ -1166,27 +1224,33 @@
adb shell service call window 1 i32 $port
}
-function stopviewserver() {
+function stopviewserver()
+{
adb shell service call window 2
}
-function isviewserverstarted() {
+function isviewserverstarted()
+{
adb shell service call window 3
}
-function key_home() {
+function key_home()
+{
adb shell input keyevent 3
}
-function key_back() {
+function key_back()
+{
adb shell input keyevent 4
}
-function key_menu() {
+function key_menu()
+{
adb shell input keyevent 82
}
-function smoketest() {
+function smoketest()
+{
if [ ! "$ANDROID_PRODUCT_OUT" ]; then
echo "Couldn't locate output files. Try running 'lunch' first." >&2
return
@@ -1206,7 +1270,8 @@
}
# simple shortcut to the runtest command
-function runtest() {
+function runtest()
+{
local T=$(gettop)
if [ ! "$T" ]; then
echo "Couldn't locate the top of the tree. Try setting TOP." >&2
@@ -1222,7 +1287,7 @@
fi
local T=$(gettop)
local FILELIST
- if [ ! "$OUT_DIR" == "" ]; then
+ if [ ! "$OUT_DIR" = "" ]; then
mkdir -p $OUT_DIR
FILELIST=$OUT_DIR/filelist
else
@@ -1236,7 +1301,7 @@
fi
local lines
lines=($(\grep "$1" $FILELIST | sed -e 's/\/[^/]*$//' | sort | uniq))
- if [[ ${#lines[@]} == 0 ]]; then
+ if [[ ${#lines[@]} = 0 ]]; then
echo "Not found"
return
fi
@@ -1356,7 +1421,8 @@
function pez {
"$@"
local retval=$?
- if [ $retval -ne 0 ]; then
+ if [ $retval -ne 0 ]
+ then
echo $'\E'"[0;31mFAILURE\e[00m"
else
echo $'\E'"[0;32mSUCCESS\e[00m"
@@ -1364,7 +1430,8 @@
return $retval
}
-function get_make_command() {
+function get_make_command()
+{
# If we're in the top of an Android tree, use soong_ui.bash instead of make
if [ -f build/soong/soong_ui.bash ]; then
# Always use the real make if -C is passed in
@@ -1380,7 +1447,8 @@
fi
}
-function _wrap_build() {
+function _wrap_build()
+{
if [[ "${ANDROID_QUIET_BUILD:-}" == true ]]; then
"$@"
return $?
@@ -1404,16 +1472,16 @@
color_reset=""
fi
echo
- if [ $ret -eq 0 ]; then
+ if [ $ret -eq 0 ] ; then
echo -n "${color_success}#### build completed successfully "
else
echo -n "${color_failed}#### failed to build some targets "
fi
- if [ $hours -gt 0 ]; then
+ if [ $hours -gt 0 ] ; then
printf "(%02g:%02g:%02g (hh:mm:ss))" $hours $mins $secs
- elif [ $mins -gt 0 ]; then
+ elif [ $mins -gt 0 ] ; then
printf "(%02g:%02g (mm:ss))" $mins $secs
- elif [ $secs -gt 0 ]; then
+ elif [ $secs -gt 0 ] ; then
printf "(%s seconds)" $secs
fi
echo " ####${color_reset}"
@@ -1456,11 +1524,13 @@
_trigger_build "modules-in-dirs" "$@"
)
-function make() {
+function make()
+{
_wrap_build $(get_make_command "$@") "$@"
}
-function provision() {
+function provision()
+{
if [ ! "$ANDROID_PRODUCT_OUT" ]; then
echo "Couldn't locate output files. Try running 'lunch' first." >&2
return 1
@@ -1471,7 +1541,7 @@
fi
# Check if user really wants to do this.
- if [ "$1" == "--no-confirmation" ]; then
+ if [ "$1" = "--no-confirmation" ]; then
shift 1
else
echo "This action will reflash your device."
@@ -1480,7 +1550,7 @@
echo ""
echo -n "Are you sure you want to do this (yes/no)? "
read
- if [[ "${REPLY}" != "yes" ]]; then
+ if [[ "${REPLY}" != "yes" ]] ; then
echo "Not taking any action. Exiting." >&2
return 1
fi
@@ -1505,8 +1575,7 @@
;;
*zsh*)
function check_type() { type "$1"; }
- enable_zsh_completion
- ;;
+ enable_zsh_completion ;;
*)
echo -e "WARNING: Only bash and zsh are supported.\nUse of other shell would lead to erroneous results."
;;
diff --git a/tools/releasetools/add_img_to_target_files.py b/tools/releasetools/add_img_to_target_files.py
index 70ea967..490b44a 100755
--- a/tools/releasetools/add_img_to_target_files.py
+++ b/tools/releasetools/add_img_to_target_files.py
@@ -60,6 +60,7 @@
import common
import rangelib
import sparse_img
+import verity_utils
if sys.hexversion < 0x02070000:
print("Python 2.7 or newer is required.", file=sys.stderr)
@@ -312,6 +313,56 @@
img.Write()
return img.name
+def AddCustomImages(output_zip, partition_name):
+ """Adds and signs custom images in IMAGES/.
+
+ Args:
+ output_zip: The output zip file (needs to be already open), or None to
+ write images to OPTIONS.input_tmp/.
+
+ Uses the image under IMAGES/ if it already exists. Otherwise looks for the
+ image under PREBUILT_IMAGES/, signs it as needed, and returns the image name.
+
+ Raises:
+ 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(
+ "avb_{}_add_hashtree_footer_args".format(partition_name))
+ partition_size = OPTIONS.info_dict.get(
+ "avb_{}_partition_size".format(partition_name))
+
+ builder = verity_utils.CreateCustomImageBuilder(
+ OPTIONS.info_dict, partition_name, partition_size,
+ key_path, algorithm, extra_args)
+
+ for img_name in OPTIONS.info_dict.get(
+ "avb_{}_image_list".format(partition_name)).split():
+ custom_image = OutputFile(output_zip, OPTIONS.input_tmp, "IMAGES", img_name)
+ if os.path.exists(custom_image.name):
+ continue
+
+ custom_image_prebuilt_path = os.path.join(
+ OPTIONS.input_tmp, "PREBUILT_IMAGES", img_name)
+ assert os.path.exists(custom_image_prebuilt_path), \
+ "Failed to find %s at %s" % (img_name, custom_image_prebuilt_path)
+
+ shutil.copy(custom_image_prebuilt_path, custom_image.name)
+
+ if builder is not None:
+ builder.Build(custom_image.name)
+
+ custom_image.Write()
+
+ default = os.path.join(OPTIONS.input_tmp, "IMAGES", partition_name + ".img")
+ assert os.path.exists(default), \
+ "There should be one %s.img" % (partition_name)
+ return default
+
def CreateImage(input_dir, info_dict, what, output_file, block_list=None):
logger.info("creating %s.img...", what)
@@ -411,8 +462,9 @@
Args:
output_zip: The output zip file, which needs to be already open.
partitions: A dict that's keyed by partition names with image paths as
- values. Only valid partition names are accepted, as listed in
- common.AVB_PARTITIONS.
+ values. Only valid partition names are accepted, as partitions listed
+ in common.AVB_PARTITIONS and custom partitions listed in
+ OPTIONS.info_dict.get("avb_custom_images_partition_list")
name: Name of the VBMeta partition, e.g. 'vbmeta', 'vbmeta_system'.
needed_partitions: Partitions whose descriptors should be included into the
generated VBMeta image.
@@ -831,11 +883,20 @@
banner("dtbo")
partitions['dtbo'] = AddDtbo(output_zip)
+ # Custom images.
+ custom_partitions = OPTIONS.info_dict.get(
+ "avb_custom_images_partition_list", "").strip().split()
+ for partition_name in custom_partitions:
+ partition_name = partition_name.strip()
+ banner("custom images for " + partition_name)
+ partitions[partition_name] = AddCustomImages(output_zip, partition_name)
+
if OPTIONS.info_dict.get("avb_enable") == "true":
# vbmeta_partitions includes the partitions that should be included into
# top-level vbmeta.img, which are the ones that are not included in any
# chained VBMeta image plus the chained VBMeta images themselves.
- vbmeta_partitions = common.AVB_PARTITIONS[:]
+ # Currently custom_partitions are all chained to VBMeta image.
+ vbmeta_partitions = common.AVB_PARTITIONS[:] + tuple(custom_partitions)
vbmeta_system = OPTIONS.info_dict.get("avb_vbmeta_system", "").strip()
if vbmeta_system:
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index 96f93a8..93e14e5 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -1132,8 +1132,9 @@
Args:
image_path: The output path for the new VBMeta image.
partitions: A dict that's keyed by partition names with image paths as
- values. Only valid partition names are accepted, as listed in
- common.AVB_PARTITIONS.
+ values. Only valid partition names are accepted, as partitions listed
+ in common.AVB_PARTITIONS and custom partitions listed in
+ OPTIONS.info_dict.get("avb_custom_images_partition_list")
name: Name of the VBMeta partition, e.g. 'vbmeta', 'vbmeta_system'.
needed_partitions: Partitions whose descriptors should be included into the
generated VBMeta image.
@@ -1145,11 +1146,15 @@
cmd = [avbtool, "make_vbmeta_image", "--output", image_path]
AppendAVBSigningArgs(cmd, name)
+ custom_partitions = OPTIONS.info_dict.get(
+ "avb_custom_images_partition_list", "").strip().split()
+
for partition, path in partitions.items():
if partition not in needed_partitions:
continue
assert (partition in AVB_PARTITIONS or
- partition in AVB_VBMETA_PARTITIONS), \
+ partition in AVB_VBMETA_PARTITIONS or
+ partition in custom_partitions), \
'Unknown partition: {}'.format(partition)
assert os.path.exists(path), \
'Failed to find {} for {}'.format(path, partition)
diff --git a/tools/releasetools/sign_target_files_apks.py b/tools/releasetools/sign_target_files_apks.py
index 52cd9a8..52b7889 100755
--- a/tools/releasetools/sign_target_files_apks.py
+++ b/tools/releasetools/sign_target_files_apks.py
@@ -112,6 +112,17 @@
(e.g. "--signing_helper /path/to/helper"). The args will be appended to
the existing ones in info dict.
+ --avb_extra_custom_image_key <partition=key>
+ --avb_extra_custom_image_algorithm <partition=algorithm>
+ Use the specified algorithm (e.g. SHA256_RSA4096) and the key to AVB-sign
+ the specified custom images mounted on the partition. Otherwise it uses
+ the existing values in info dict.
+
+ --avb_extra_custom_image_extra_args <partition=extra_args>
+ Specify any additional args that are needed to AVB-sign the custom images
+ mounted on the partition (e.g. "--signing_helper /path/to/helper"). The
+ args will be appended to the existing ones in info dict.
+
--android_jar_path <path>
Path to the android.jar to repack the apex file.
"""
@@ -956,12 +967,20 @@
if extra_args:
print('Setting extra AVB signing args for %s to "%s"' % (
partition, extra_args))
- args_key = AVB_FOOTER_ARGS_BY_PARTITION[partition]
+ if partition in AVB_FOOTER_ARGS_BY_PARTITION:
+ args_key = AVB_FOOTER_ARGS_BY_PARTITION[partition]
+ else:
+ # custom partition
+ args_key = "avb_{}_add_hashtree_footer_args".format(partition)
misc_info[args_key] = (misc_info.get(args_key, '') + ' ' + extra_args)
for partition in AVB_FOOTER_ARGS_BY_PARTITION:
ReplaceAvbPartitionSigningKey(partition)
+ for custom_partition in misc_info.get(
+ "avb_custom_images_partition_list", "").strip().split():
+ ReplaceAvbPartitionSigningKey(custom_partition)
+
def RewriteAvbProps(misc_info):
"""Rewrites the props in AVB signing args."""
@@ -1208,6 +1227,15 @@
OPTIONS.avb_extra_args['vbmeta_vendor'] = a
elif o == "--avb_apex_extra_args":
OPTIONS.avb_extra_args['apex'] = a
+ elif o == "--avb_extra_custom_image_key":
+ partition, key = a.split("=")
+ OPTIONS.avb_keys[partition] = key
+ elif o == "--avb_extra_custom_image_algorithm":
+ partition, algorithm = a.split("=")
+ OPTIONS.avb_algorithms[partition] = algorithm
+ elif o == "--avb_extra_custom_image_extra_args":
+ partition, extra_args = a.split("=")
+ OPTIONS.avb_extra_args[partition] = extra_args
else:
return False
return True
@@ -1252,6 +1280,9 @@
"avb_vbmeta_vendor_algorithm=",
"avb_vbmeta_vendor_key=",
"avb_vbmeta_vendor_extra_args=",
+ "avb_extra_custom_image_key=",
+ "avb_extra_custom_image_algorithm=",
+ "avb_extra_custom_image_extra_args=",
],
extra_option_handler=option_handler)
diff --git a/tools/releasetools/validate_target_files.py b/tools/releasetools/validate_target_files.py
index 1b918cc..69be511 100755
--- a/tools/releasetools/validate_target_files.py
+++ b/tools/releasetools/validate_target_files.py
@@ -352,8 +352,13 @@
cmd = [info_dict['avb_avbtool'], 'verify_image', '--image', image,
'--follow_chain_partitions']
+ # Custom images.
+ custom_partitions = info_dict.get(
+ "avb_custom_images_partition_list", "").strip().split()
+
# Append the args for chained partitions if any.
- for partition in common.AVB_PARTITIONS + common.AVB_VBMETA_PARTITIONS:
+ for partition in (common.AVB_PARTITIONS + common.AVB_VBMETA_PARTITIONS +
+ tuple(custom_partitions)):
key_name = 'avb_' + partition + '_key_path'
if info_dict.get(key_name) is not None:
if info_dict.get('ab_update') != 'true' and partition == 'recovery':
diff --git a/tools/releasetools/verity_utils.py b/tools/releasetools/verity_utils.py
index e7f84f5..fc83689 100644
--- a/tools/releasetools/verity_utils.py
+++ b/tools/releasetools/verity_utils.py
@@ -695,3 +695,22 @@
raise HashtreeInfoGenerationError("Failed to reconstruct the verity tree")
return self.hashtree_info
+
+
+def CreateCustomImageBuilder(info_dict, partition_name, partition_size,
+ key_path, algorithm, signing_args):
+ builder = None
+ if info_dict.get("avb_enable") == "true":
+ builder = VerifiedBootVersion2VerityImageBuilder(
+ partition_name,
+ partition_size,
+ VerifiedBootVersion2VerityImageBuilder.AVB_HASHTREE_FOOTER,
+ info_dict.get("avb_avbtool"),
+ key_path,
+ algorithm,
+ # Salt is None because custom images have no fingerprint property to be
+ # used as the salt.
+ None,
+ signing_args)
+
+ return builder