Add support for /odm partition

This CL is largely an adaptation of Change-Id
I5d229f6ac729ea6df9ff1f14cee2e28972cd9b4d

tools/vendor_buildinfo.sh is also renamed to tools/device_buildinfo.sh.
The caller then can invoke device_buildinfo.sh "vendor" | "odm" to
generate properties for vendor.img and odm.img, respectively.

It adds the following variables:

- BOARD_AVB_ODM_KEY_PATH
- BOARD_AVB_ODM_ALGORITHM
- BOARD_AVB_ODM_ROLLBACK_INDEX_LOCATION
- BOARD_ODMIMAGE_FILE_SYSTEM_TYPE
- BOARD_ODMIMAGE_EXTFS_INODE_COUNT
- BOARD_ODMIMAGE_EXTFS_RSV_PCT
- BOARD_ODMIMAGE_PARTITION_SIZE
- BOARD_ODMIMAGE_JOURNAL_SIZE
- BOARD_ODMIMAGE_SQUASHFS_BLOCK_SIZE
- BOARD_ODMIMAGE_SQUASHFS_COMPRESSOR
- BOARD_ODMIMAGE_SQUASHFS_COMPRESSOR_OPT
- BOARD_ODMIMAGE_SQUASHFS_DISABLE_4K_ALIGN
- BOARD_PREBUILT_ODMIMAGE
- BOARD_USES_ODMIMAGE
- LOCAL_ODM_MODULE
- PRODUCT_ODM_BASE_FS_PATH
- PRODUCT_ODM_VERITY_PARTITION
- PRODUCT_ODM_PROPERTIES
- TARGET_COPY_OUT_ODM
- TARGET_OUT_ODM
- TARGET_OUT_ODM_*

Bug: 64195575
Test: boot a Taimen with existing images

Test: `make odmimage` with
      - BOARD_AVB_ENABLE := true
      - BOARD_ODMIMAGE_PARTITION_SIZE := 62914560
      - BOARD_ODMIMAGE_FILE_SYSTEM_TYPE := ext4
      - TARGET_COPY_OUT_ODM := odm
      - PRODUCT_ODM_PROPERTIES += odm.test.build=success

Test: `make odmimage` with
      - BOARD_ODMIMAGE_PARTITION_RESERVED_SIZE := 10485760
      - BOARD_ODMIMAGE_FILE_SYSTEM_TYPE := ext4
      - BOARD_AVB_ENABLE := true
      - TARGET_COPY_OUT_ODM := odm
      - PRODUCT_ODM_PROPERTIES += odm.test.build=success
      - PRODUCT_USE_DYNAMIC_PARTITION_SIZE := true

Change-Id: I4dea7b567ec49a766c7a4683decaf81c7e921d55
diff --git a/tools/device_buildinfo.sh b/tools/device_buildinfo.sh
new file mode 100755
index 0000000..0782565
--- /dev/null
+++ b/tools/device_buildinfo.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+
+partition="$1"
+
+if [ "$#" -ne 1 ]; then
+  echo "Usage: $0 <vendor|odm>" 1>&2
+  exit 1
+fi
+
+if [ "$partition" != "vendor" ] && [ "$partition" != "odm" ]; then
+  echo "Unknown partition name: $partition" 1>&2
+  exit 1
+fi
+
+echo "# begin build properties"
+echo "# autogenerated by device_buildinfo.sh"
+
+echo "ro.${partition}.build.id=$BUILD_ID"
+echo "ro.${partition}.build.version.incremental=$BUILD_NUMBER"
+echo "ro.${partition}.build.version.sdk=$PLATFORM_SDK_VERSION"
+echo "ro.${partition}.build.version.release=$PLATFORM_VERSION"
+echo "ro.${partition}.build.type=$TARGET_BUILD_TYPE"
+echo "ro.${partition}.build.tags=$BUILD_VERSION_TAGS"
+
+echo "ro.product.board=$TARGET_BOOTLOADER_BOARD_NAME"
+echo "ro.board.platform=$TARGET_BOARD_PLATFORM"
+
+echo "ro.product.${partition}.manufacturer=$PRODUCT_MANUFACTURER"
+echo "ro.product.${partition}.model=$PRODUCT_MODEL"
+echo "ro.product.${partition}.brand=$PRODUCT_BRAND"
+echo "ro.product.${partition}.name=$PRODUCT_NAME"
+echo "ro.product.${partition}.device=$TARGET_DEVICE"
+
+echo "# end build properties"
diff --git a/tools/releasetools/add_img_to_target_files.py b/tools/releasetools/add_img_to_target_files.py
index fb4b882..932fab9 100755
--- a/tools/releasetools/add_img_to_target_files.py
+++ b/tools/releasetools/add_img_to_target_files.py
@@ -73,12 +73,14 @@
 OPTIONS.is_signing = False
 
 # Partitions that should have their care_map added to META/care_map.txt.
-PARTITIONS_WITH_CARE_MAP = ('system', 'vendor', 'product', 'product-services')
+PARTITIONS_WITH_CARE_MAP = ('system', 'vendor', 'product', 'product-services',
+                            'odm')
 # Use a fixed timestamp (01/01/2009 00:00:00 UTC) for files when packaging
 # images. (b/24377993, b/80600931)
 FIXED_FILE_TIMESTAMP = (datetime.datetime(2009, 1, 1, 0, 0, 0, 0, None)
                         - datetime.datetime.utcfromtimestamp(0)).total_seconds()
 
+
 class OutputFile(object):
   def __init__(self, output_zip, input_dir, prefix, name):
     self._output_zip = output_zip
@@ -215,6 +217,22 @@
   return img.name
 
 
+def AddOdm(output_zip):
+  """Turn the contents of ODM into an odm image and store it in output_zip."""
+
+  img = OutputFile(output_zip, OPTIONS.input_tmp, "IMAGES", "odm.img")
+  if os.path.exists(img.input_name):
+    print("odm.img already exists; no need to rebuild...")
+    return img.input_name
+
+  block_list = OutputFile(
+      output_zip, OPTIONS.input_tmp, "IMAGES", "odm.map")
+  CreateImage(
+      OPTIONS.input_tmp, OPTIONS.info_dict, "odm", img,
+      block_list=block_list)
+  return img.name
+
+
 def AddDtbo(output_zip):
   """Adds the DTBO image.
 
@@ -631,7 +649,7 @@
 
   has_recovery = OPTIONS.info_dict.get("no_recovery") != "true"
 
-  # {vendor,product,product-services}.img are unlike system.img or
+  # {vendor,odm,product,product-services}.img are unlike system.img or
   # system_other.img. Because it could be built from source, or dropped into
   # target_files.zip as a prebuilt blob. We consider either of them as
   # {vendor,product,product-services}.img being available, which could be
@@ -639,6 +657,9 @@
   has_vendor = (os.path.isdir(os.path.join(OPTIONS.input_tmp, "VENDOR")) or
                 os.path.exists(os.path.join(OPTIONS.input_tmp, "IMAGES",
                                             "vendor.img")))
+  has_odm = (os.path.isdir(os.path.join(OPTIONS.input_tmp, "ODM")) or
+                 os.path.exists(os.path.join(OPTIONS.input_tmp, "IMAGES",
+                                             "odm.img")))
   has_product = (os.path.isdir(os.path.join(OPTIONS.input_tmp, "PRODUCT")) or
                  os.path.exists(os.path.join(OPTIONS.input_tmp, "IMAGES",
                                              "product.img")))
@@ -727,6 +748,10 @@
     banner("product-services")
     partitions['product-services'] = AddProductServices(output_zip)
 
+  if has_odm:
+    banner("odm")
+    partitions['odm'] = AddOdm(output_zip)
+
   if has_system_other:
     banner("system_other")
     AddSystemOther(output_zip)
diff --git a/tools/releasetools/build_image.py b/tools/releasetools/build_image.py
index 5b46ab0..86ba1a6 100755
--- a/tools/releasetools/build_image.py
+++ b/tools/releasetools/build_image.py
@@ -931,6 +931,26 @@
     if not copy_prop("product_services_extfs_rsv_pct", "extfs_rsv_pct"):
       d["extfs_rsv_pct"] = "0"
     copy_prop("product_services_reserved_size", "partition_reserved_size")
+  elif mount_point == "odm":
+    copy_prop("avb_odm_hashtree_enable", "avb_hashtree_enable")
+    copy_prop("avb_odm_add_hashtree_footer_args",
+              "avb_add_hashtree_footer_args")
+    copy_prop("avb_odm_key_path", "avb_key_path")
+    copy_prop("avb_odm_algorithm", "avb_algorithm")
+    copy_prop("odm_fs_type", "fs_type")
+    copy_prop("odm_size", "partition_size")
+    if not copy_prop("odm_journal_size", "journal_size"):
+      d["journal_size"] = "0"
+    copy_prop("odm_verity_block_device", "verity_block_device")
+    copy_prop("odm_squashfs_compressor", "squashfs_compressor")
+    copy_prop("odm_squashfs_compressor_opt", "squashfs_compressor_opt")
+    copy_prop("odm_squashfs_block_size", "squashfs_block_size")
+    copy_prop("odm_squashfs_disable_4k_align", "squashfs_disable_4k_align")
+    copy_prop("odm_base_fs_file", "base_fs_file")
+    copy_prop("odm_extfs_inode_count", "extfs_inode_count")
+    if not copy_prop("odm_extfs_rsv_pct", "extfs_rsv_pct"):
+      d["extfs_rsv_pct"] = "0"
+    copy_prop("odm_reserved_size", "partition_reserved_size")
   elif mount_point == "oem":
     copy_prop("fs_type", "fs_type")
     copy_prop("oem_size", "partition_size")
@@ -976,6 +996,8 @@
     copy_prop(size_property, "system_size")
   elif mount_point == "vendor":
     copy_prop(size_property, "vendor_size")
+  elif mount_point == "odm":
+    copy_prop(size_property, "odm_size")
   elif mount_point == "product":
     copy_prop(size_property, "product_size")
   elif mount_point == "product-services":
@@ -1017,6 +1039,8 @@
       mount_point = "cache"
     elif image_filename == "vendor.img":
       mount_point = "vendor"
+    elif image_filename == "odm.img":
+      mount_point = "odm"
     elif image_filename == "oem.img":
       mount_point = "oem"
     elif image_filename == "product.img":
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index 89b4037..bf380bc 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -79,7 +79,7 @@
 
 # The partitions allowed to be signed by AVB (Android verified boot 2.0).
 AVB_PARTITIONS = ('boot', 'recovery', 'system', 'vendor', 'product',
-                  'product-services', 'dtbo')
+                  'product-services', 'dtbo', 'odm')
 
 
 class ErrorCode(object):
diff --git a/tools/vendor_buildinfo.sh b/tools/vendor_buildinfo.sh
deleted file mode 100755
index 6590049..0000000
--- a/tools/vendor_buildinfo.sh
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/bin/bash
-
-echo "# begin build properties"
-echo "# autogenerated by vendor_buildinfo.sh"
-
-echo "ro.vendor.build.id=$BUILD_ID"
-echo "ro.vendor.build.version.incremental=$BUILD_NUMBER"
-echo "ro.vendor.build.version.sdk=$PLATFORM_SDK_VERSION"
-echo "ro.vendor.build.version.release=$PLATFORM_VERSION"
-echo "ro.vendor.build.type=$TARGET_BUILD_TYPE"
-echo "ro.vendor.build.tags=$BUILD_VERSION_TAGS"
-
-echo "ro.product.board=$TARGET_BOOTLOADER_BOARD_NAME"
-echo "ro.board.platform=$TARGET_BOARD_PLATFORM"
-
-echo "ro.product.vendor.manufacturer=$PRODUCT_MANUFACTURER"
-echo "ro.product.vendor.model=$PRODUCT_MODEL"
-echo "ro.product.vendor.brand=$PRODUCT_BRAND"
-echo "ro.product.vendor.name=$PRODUCT_NAME"
-echo "ro.product.vendor.device=$TARGET_DEVICE"
-
-echo "# end build properties"