325 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
			
		
		
	
	
			325 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
#!/bin/bash -ex
 | 
						|
usage () {
 | 
						|
  echo "Create a Mixed Build archive with the given system and device archives."
 | 
						|
  echo
 | 
						|
  echo "Usage: $0 [-v <vendor_version>] [-m <modify_system_image_path>]"
 | 
						|
  echo "    [-t <prebuilt_otatools_path>] [-p <override_vbmeta_image_path>]"
 | 
						|
  echo "    [-b <override_boot_image_path>]"
 | 
						|
  echo "    [-s] [-d] system_build_dir device_build_dir out_dir"
 | 
						|
  echo
 | 
						|
  echo "Options -v, -m, -t, -p, -b, -s, -d must precede positional arguments."
 | 
						|
  echo
 | 
						|
  echo "vendor_version is the version of the vendor image when Keymaster v3"
 | 
						|
  echo "    related modifications to the system image is necessary. Optional."
 | 
						|
  echo "    eg. 8.1.0 for a mixed build of GSI and O-MR1 vendor image."
 | 
						|
  echo "modify_system_image_path is the path to the script that modifies the"
 | 
						|
  echo "    system image, needed for Keymaster v3. Optional."
 | 
						|
  echo "prebuilt_otatools_path is the path to otatools.zip file that has all"
 | 
						|
  echo "    required host binaries to modify system image. It also must include"
 | 
						|
  echo "    VINTF check tool to verify the compatibility of the given images."
 | 
						|
  echo "    Optional."
 | 
						|
  echo "override_vbmeta_image_path is the path to a vbmeta.img to use"
 | 
						|
  echo "    to override the existing vbmeta.img of device. Optional."
 | 
						|
  echo "override_boot_image_path is the path to a boot imgage to use to"
 | 
						|
  echo "    override the existing boot.img of device. Optional."
 | 
						|
  echo "-s is used to fetch and flash both product.img and system.img from"
 | 
						|
  echo "    the system_build_dir for devices with a product partition."
 | 
						|
  echo "    product.img will be removed if system_build_dir does not have"
 | 
						|
  echo "    product.img when -s option is declared."
 | 
						|
  echo "    By default, only system.img is flashed to the target device for"
 | 
						|
  echo "    independent system update. No parameter required. Optional"
 | 
						|
  echo "-d is used to skip vbmeta.img replacement in its entirety and the"
 | 
						|
  echo "    one from the device build (if exists) is left untouched"
 | 
						|
  echo "system_build_dir is the path to the system build"
 | 
						|
  echo "    eg. aosp_arm64-userdebug."
 | 
						|
  echo "device_build_dir is the path to the device build"
 | 
						|
  echo "    eg. sailfish-user."
 | 
						|
  echo "out_dir is the path to where the new build will be placed."
 | 
						|
}
 | 
						|
 | 
						|
# Print error message and exit.
 | 
						|
# Usage: exit_badparam message
 | 
						|
#
 | 
						|
# message is a string to be displayed before exit.
 | 
						|
exit_badparam () {
 | 
						|
  echo "ERROR: $1" >&2
 | 
						|
  usage
 | 
						|
  exit 1
 | 
						|
}
 | 
						|
 | 
						|
cleanup_and_exit () {
 | 
						|
  readonly result="$?"
 | 
						|
  rm -rf "$TEMP_DIR"
 | 
						|
  exit "$result"
 | 
						|
}
 | 
						|
 | 
						|
trap cleanup_and_exit EXIT
 | 
						|
 | 
						|
while getopts :v:m:p:b:t:sd opt; do
 | 
						|
  case "$opt" in
 | 
						|
    v)
 | 
						|
      readonly VENDOR_VERSION="$OPTARG"
 | 
						|
      ;;
 | 
						|
    m)
 | 
						|
      readonly MODIFY_SYSTEM_SCRIPT="$OPTARG"
 | 
						|
      ;;
 | 
						|
    p)
 | 
						|
      readonly OVERRIDE_VBMETA_IMAGE_PATH="$OPTARG"
 | 
						|
      ;;
 | 
						|
    b)
 | 
						|
      readonly OVERRIDE_BOOT_IMAGE_PATH="$OPTARG"
 | 
						|
      ;;
 | 
						|
    t)
 | 
						|
      readonly OTATOOLS_ZIP="$OPTARG"
 | 
						|
      ;;
 | 
						|
    s)
 | 
						|
      readonly INCLUDE_PRODUCT=true
 | 
						|
      ;;
 | 
						|
    d)
 | 
						|
      readonly SKIP_VBMETA_REPLACE=true
 | 
						|
      ;;
 | 
						|
    \?)
 | 
						|
      exit_badparam "Invalid options: -"$OPTARG""
 | 
						|
      ;;
 | 
						|
    :)
 | 
						|
      exit_badparam "Option -"$OPTARG" requires an argument."
 | 
						|
      ;;
 | 
						|
  esac
 | 
						|
done
 | 
						|
 | 
						|
if [[ -z "${VENDOR_VERSION+x}" && ! -z "${MODIFY_SYSTEM_SCRIPT+x}" ]] || \
 | 
						|
  [[ ! -z "${VENDOR_VERSION+x}" && -z "${MODIFY_SYSTEM_SCRIPT+x}" ]]; then
 | 
						|
  exit_badparam "Options -v and -m must be set together."
 | 
						|
fi
 | 
						|
 | 
						|
shift "$((OPTIND-1))"
 | 
						|
 | 
						|
if [[ $# -lt 3 ]]; then
 | 
						|
  exit_badparam "Unexpected number of arguments"
 | 
						|
fi
 | 
						|
 | 
						|
readonly SYSTEM_DIR="$1"
 | 
						|
readonly DEVICE_DIR="$2"
 | 
						|
readonly DIST_DIR="$3"
 | 
						|
readonly TEMP_DIR="$(mktemp -d /tmp/"$(basename $0)"_XXXXXXXX)"
 | 
						|
 | 
						|
readonly SYSTEM_TARGET_FILES_ARCHIVE="$(find "$SYSTEM_DIR" -name "*-target_files-*.zip" -print)"
 | 
						|
if [[ ! -f "$SYSTEM_TARGET_FILES_ARCHIVE" ]]; then
 | 
						|
  exit_badparam "Could not find system target files archive in $SYSTEM_DIR."
 | 
						|
fi
 | 
						|
 | 
						|
readonly DEVICE_ARCHIVE="$(find "$DEVICE_DIR" -name "*-img-*.zip" -print)"
 | 
						|
if [[ ! -f "$DEVICE_ARCHIVE" ]]; then
 | 
						|
  exit_badparam "Could not find device img archive in $DEVICE_DIR."
 | 
						|
fi
 | 
						|
 | 
						|
readonly DEVICE_TARGET_FILES_ARCHIVE="$(find "$DEVICE_DIR" -name "*-target_files-*.zip" -print)"
 | 
						|
if [[ ! -f "$DEVICE_TARGET_FILES_ARCHIVE" ]]; then
 | 
						|
  exit_badparam "Could not find device target_files archive in $DEVICE_DIR."
 | 
						|
fi
 | 
						|
 | 
						|
if [[ ! -z "${MODIFY_SYSTEM_SCRIPT+x}" && ! -f "$MODIFY_SYSTEM_SCRIPT" ]]; then
 | 
						|
  exit_badparam "Script not found: "$MODIFY_SYSTEM_SCRIPT""
 | 
						|
fi
 | 
						|
 | 
						|
if [[ ! -z "${OVERRIDE_VBMETA_IMAGE_PATH+x}" && ! -f "$OVERRIDE_VBMETA_IMAGE_PATH" ]]; then
 | 
						|
  exit_badparam "Specified vbmeta.img not found: "$OVERRIDE_VBMETA_IMAGE_PATH""
 | 
						|
fi
 | 
						|
 | 
						|
if [[ ! -z "${OVERRIDE_BOOT_IMAGE_PATH+x}" && ! -f "$OVERRIDE_BOOT_IMAGE_PATH" ]]; then
 | 
						|
  exit_badparam "Specified boot image not found: "$OVERRIDE_BOOT_IMAGE_PATH""
 | 
						|
fi
 | 
						|
 | 
						|
readonly DEVICE_ARTIFACTS_DIR="$TEMP_DIR"/device_archive_artifacts
 | 
						|
readonly DEVICE_IMAGES_DIR="$DEVICE_ARTIFACTS_DIR"/IMAGES
 | 
						|
readonly SYSTEM_ARTIFACTS_DIR="$TEMP_DIR"/system_artifacts
 | 
						|
readonly SYSTEM_IMAGES_DIR="$SYSTEM_ARTIFACTS_DIR"/IMAGES
 | 
						|
readonly OTATOOLS_DIR="$TEMP_DIR"/otatools
 | 
						|
 | 
						|
readonly SPL_PROPERTY_NAME="ro.build.version.security_patch"
 | 
						|
readonly SYSTEM_BUILD_PROP="SYSTEM/build.prop"
 | 
						|
 | 
						|
declare -a EXTRACT_SYSTEM_FILE_LIST
 | 
						|
EXTRACT_SYSTEM_FILE_LIST=(
 | 
						|
  IMAGES/system.img \
 | 
						|
  IMAGES/vbmeta.img \
 | 
						|
  "$SYSTEM_BUILD_PROP" \
 | 
						|
)
 | 
						|
 | 
						|
declare -a EXTRACT_VINTF_SYSTEM_FILE_LIST
 | 
						|
EXTRACT_VINTF_SYSTEM_FILE_LIST=(
 | 
						|
  "$SYSTEM_BUILD_PROP" \
 | 
						|
)
 | 
						|
 | 
						|
declare -a EXTRACT_DEVICE_FILE_LIST
 | 
						|
EXTRACT_DEVICE_FILE_LIST=(
 | 
						|
  */build.prop \
 | 
						|
  META/* \
 | 
						|
)
 | 
						|
 | 
						|
declare -A SYSTEM_SEARCH_PATH
 | 
						|
SYSTEM_SEARCH_PATH=( \
 | 
						|
  [/system]="SYSTEM" \
 | 
						|
  [/product]="PRODUCT SYSTEM/product" \
 | 
						|
  [/system_ext]="SYSTEM_EXT SYSTEM/system_ext" \
 | 
						|
)
 | 
						|
 | 
						|
declare -A DEVICE_SEARCH_PATH
 | 
						|
# Mixed build will not have /vendor to SYSTEM/vendor case
 | 
						|
DEVICE_SEARCH_PATH=( \
 | 
						|
  [/vendor]="VENDOR" \
 | 
						|
  [/odm]="ODM VENDOR/odm" \
 | 
						|
)
 | 
						|
 | 
						|
###
 | 
						|
# Uncompress otatools.zip and get vintf file list.
 | 
						|
if [[ ! -f "$OTATOOLS_ZIP" ]]; then
 | 
						|
  echo "WARNING: otatools.zip is missing. Add \"-t otatools.zip\" to enable checkvintf"
 | 
						|
else
 | 
						|
  readonly OTATOOLS_AVAILABLE=true
 | 
						|
  # Uncompress otatools
 | 
						|
  mkdir -p "$OTATOOLS_DIR"
 | 
						|
  unzip "$OTATOOLS_ZIP" bin/* lib64/* -d "$OTATOOLS_DIR"
 | 
						|
  # Set paths for using prebuilt host binaries.
 | 
						|
  export PATH="$OTATOOLS_DIR"/bin:"$PATH"
 | 
						|
  export LD_LIBRARY_PATH="$OTATOOLS_DIR"/lib64:"$LD_LIBRARY_PATH"
 | 
						|
 | 
						|
  # Add vintf file to extract file list
 | 
						|
  declare -a VINTF_DUMP_FILE_LIST
 | 
						|
  VINTF_DUMP_FILE_LIST=( "$(checkvintf --dump-file-list)" )
 | 
						|
 | 
						|
  for vintf_file_list in ${VINTF_DUMP_FILE_LIST[*]}; do
 | 
						|
    if [[ "$vintf_file_list" == */ ]]; then
 | 
						|
      vintf_file_list="$vintf_file_list"\*
 | 
						|
      # Create system vintf file list for system target files archive
 | 
						|
      for system_dir in "${!SYSTEM_SEARCH_PATH[@]}"; do
 | 
						|
        if [[ "$vintf_file_list" == "$system_dir"/* ]]; then
 | 
						|
          for search_dir in ${SYSTEM_SEARCH_PATH["$system_dir"]}; do
 | 
						|
            search_file=${vintf_file_list/$system_dir/$search_dir}
 | 
						|
            unzip -l "$SYSTEM_TARGET_FILES_ARCHIVE" "$search_file" > /dev/null && \
 | 
						|
              EXTRACT_VINTF_SYSTEM_FILE_LIST+=( "$search_file" )
 | 
						|
          done
 | 
						|
          break
 | 
						|
        fi
 | 
						|
      done
 | 
						|
      # Create device vintf file list for device target files archive
 | 
						|
      for device_dir in "${!DEVICE_SEARCH_PATH[@]}"; do
 | 
						|
        if [[ "$vintf_file_list" == "$device_dir"/* ]]; then
 | 
						|
          for search_dir in ${DEVICE_SEARCH_PATH["$device_dir"]}; do
 | 
						|
            search_file=${vintf_file_list/$device_dir/$search_dir}
 | 
						|
            unzip -l "$DEVICE_TARGET_FILES_ARCHIVE" "$search_file" > /dev/null && \
 | 
						|
              EXTRACT_DEVICE_FILE_LIST+=( "$search_file" )
 | 
						|
          done
 | 
						|
          break
 | 
						|
        fi
 | 
						|
      done
 | 
						|
     fi
 | 
						|
  done
 | 
						|
fi
 | 
						|
 | 
						|
###
 | 
						|
# Uncompress the system archives.
 | 
						|
if [[ "$INCLUDE_PRODUCT" == true ]]; then
 | 
						|
  unzip -l "$SYSTEM_TARGET_FILES_ARCHIVE" | grep -q IMAGES/product.img &&
 | 
						|
  EXTRACT_SYSTEM_FILE_LIST+=(IMAGES/product.img)
 | 
						|
fi
 | 
						|
 | 
						|
mkdir -p "$SYSTEM_ARTIFACTS_DIR"
 | 
						|
# Get system images.
 | 
						|
unzip "$SYSTEM_TARGET_FILES_ARCHIVE" "${EXTRACT_SYSTEM_FILE_LIST[@]}" \
 | 
						|
  -d "$SYSTEM_ARTIFACTS_DIR"
 | 
						|
 | 
						|
###
 | 
						|
# Uncompress the device archives.
 | 
						|
mkdir -p "$DEVICE_IMAGES_DIR"
 | 
						|
# Get device images.
 | 
						|
unzip "$DEVICE_ARCHIVE" -d "$DEVICE_IMAGES_DIR"
 | 
						|
# Get the device meta data.
 | 
						|
unzip "$DEVICE_TARGET_FILES_ARCHIVE" "${EXTRACT_DEVICE_FILE_LIST[@]}" \
 | 
						|
  -d "$DEVICE_ARTIFACTS_DIR"
 | 
						|
 | 
						|
###
 | 
						|
# Modify system.img if vendor version is provided.
 | 
						|
if [[ ! -z "${VENDOR_VERSION+x}" ]]; then
 | 
						|
  # Create copy of system target files package that can be modified
 | 
						|
  # since the original $SYSTEM_TARGET_FILES_ARCHIVE is a symlink to
 | 
						|
  # prebuilt files in cache
 | 
						|
  cp "$SYSTEM_TARGET_FILES_ARCHIVE" "$TEMP_DIR"
 | 
						|
  readonly COPY_SYSTEM_TARGET_FILES_ARCHIVE="$TEMP_DIR"/"$(basename "$SYSTEM_TARGET_FILES_ARCHIVE")"
 | 
						|
 | 
						|
  # Check compatibility of security patch level
 | 
						|
  readonly SYSTEM_SPL=$(sed -n -r "s/^"$SPL_PROPERTY_NAME"=(.*)$/\1/p" "$SYSTEM_ARTIFACTS_DIR"/"$SYSTEM_BUILD_PROP")
 | 
						|
  readonly VENDOR_SPL=$(sed -n -r "s/^"$SPL_PROPERTY_NAME"=(.*)$/\1/p" "$DEVICE_ARTIFACTS_DIR"/"$SYSTEM_BUILD_PROP")
 | 
						|
  declare -a args
 | 
						|
  args=(-v "$VENDOR_VERSION" "$COPY_SYSTEM_TARGET_FILES_ARCHIVE")
 | 
						|
  if [[ "$SYSTEM_SPL" != "$VENDOR_SPL" ]]; then
 | 
						|
    echo "Security patch level mismatch detected..."
 | 
						|
    echo "  SPL of system: "$SYSTEM_SPL""
 | 
						|
    echo "  SPL of vendor: "$VENDOR_SPL""
 | 
						|
    args+=("$VENDOR_SPL")
 | 
						|
  fi
 | 
						|
  "$MODIFY_SYSTEM_SCRIPT" "${args[@]}"
 | 
						|
  # Replace system.img with newly modified system.img
 | 
						|
  unzip -o "$COPY_SYSTEM_TARGET_FILES_ARCHIVE" IMAGES/system.img -d "$SYSTEM_ARTIFACTS_DIR"
 | 
						|
fi
 | 
						|
 | 
						|
# Check vintf
 | 
						|
if [[ "$OTATOOLS_AVAILABLE" == true ]]; then
 | 
						|
  # Overwrite VINTF system matrix to device artifacts dir
 | 
						|
  unzip -o "$SYSTEM_TARGET_FILES_ARCHIVE" "${EXTRACT_VINTF_SYSTEM_FILE_LIST[@]}" \
 | 
						|
    -d "$DEVICE_ARTIFACTS_DIR"
 | 
						|
  check_target_files_vintf "$DEVICE_ARTIFACTS_DIR"
 | 
						|
fi
 | 
						|
 | 
						|
###
 | 
						|
# Overwrite artifacts in the device archive to create the Mixed Build artifacts.
 | 
						|
cp "$SYSTEM_IMAGES_DIR"/system.img "$DEVICE_IMAGES_DIR"/
 | 
						|
if [[ "$INCLUDE_PRODUCT" == true ]]; then
 | 
						|
  if [[ -f "$SYSTEM_IMAGES_DIR"/product.img ]]; then
 | 
						|
    cp "$SYSTEM_IMAGES_DIR"/product.img "$DEVICE_IMAGES_DIR"/
 | 
						|
  else
 | 
						|
    rm -f "$DEVICE_IMAGES_DIR"/product.img
 | 
						|
    # Removed product partition from required partition list
 | 
						|
    sed -i "/partition-exists=product$/d" "$DEVICE_IMAGES_DIR"/android-info.txt
 | 
						|
  fi
 | 
						|
fi
 | 
						|
 | 
						|
if [[ "$SKIP_VBMETA_REPLACE" == true ]]; then
 | 
						|
    # Totally skip the vbmeta.img replacement
 | 
						|
    echo "Skip vbmeta.img replacement."
 | 
						|
else
 | 
						|
    # Only override vbmeta if it is already present since fastboot update will try
 | 
						|
    # to flash whatever is in the archive.
 | 
						|
    if [[ -f "$DEVICE_IMAGES_DIR"/vbmeta.img ]]; then
 | 
						|
      readonly VBMETA_IMAGE_PATH="${OVERRIDE_VBMETA_IMAGE_PATH:-"$SYSTEM_IMAGES_DIR"/vbmeta.img}"
 | 
						|
      cp "$VBMETA_IMAGE_PATH" "$DEVICE_IMAGES_DIR"/
 | 
						|
    fi
 | 
						|
fi
 | 
						|
 | 
						|
# Override boot.img with the provided boot image file since fastboot update cmd
 | 
						|
# will try to flash boot.img in the archive.
 | 
						|
if [[ ! -z "${OVERRIDE_BOOT_IMAGE_PATH+x}" && -f "$DEVICE_IMAGES_DIR"/boot.img ]]; then
 | 
						|
  cp "$OVERRIDE_BOOT_IMAGE_PATH" "$DEVICE_IMAGES_DIR"/boot.img
 | 
						|
fi
 | 
						|
 | 
						|
###
 | 
						|
# Create the Mixed Build archive.
 | 
						|
(
 | 
						|
  cd "$DEVICE_IMAGES_DIR"
 | 
						|
  zip -r mixed.zip ./*
 | 
						|
)
 | 
						|
 | 
						|
###
 | 
						|
# Archive the artifacts.
 | 
						|
if [ -n "$DIST_DIR" ]; then
 | 
						|
  mkdir -p "$DIST_DIR" || true
 | 
						|
fi
 | 
						|
# Archive all the device artifacts.
 | 
						|
rsync --archive --verbose --copy-links --exclude='logs' \
 | 
						|
  "$DEVICE_DIR"/* "$DIST_DIR"
 | 
						|
# Overwrite the image archive with the Mixed Build archive.
 | 
						|
OUT_ARCHIVE="$DIST_DIR"/"$(basename $DEVICE_ARCHIVE)"
 | 
						|
cp "$DEVICE_IMAGES_DIR"/mixed.zip "$OUT_ARCHIVE"
 | 
						|
# Overwrite android-info.txt with the updated one.
 | 
						|
cp "$DEVICE_IMAGES_DIR"/android-info.txt "$DIST_DIR"/
 |