support multiple boot.img files in release tools

Support for generating multiple boot.img files is required in the
release tools to enable GKI distribution/signing.

Bug: 151094943
Change-Id: I536a286d3123f35918106a52c49b1148d746370f
diff --git a/core/Makefile b/core/Makefile
index 5b3c4c9..a158c9d 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -4167,6 +4167,8 @@
 endif
 ifeq ($(INSTALLED_BOOTIMAGE_TARGET),)
 	$(hide) echo "no_boot=true" >> $@
+else
+	echo "boot_images=$(foreach b,$(INSTALLED_BOOTIMAGE_TARGET),$(notdir $(b)))" >> $@
 endif
 ifneq ($(INSTALLED_VENDOR_BOOTIMAGE_TARGET),)
 	echo "vendor_boot=true" >> $@
diff --git a/tools/releasetools/add_img_to_target_files.py b/tools/releasetools/add_img_to_target_files.py
index cc05c64..7db506c 100755
--- a/tools/releasetools/add_img_to_target_files.py
+++ b/tools/releasetools/add_img_to_target_files.py
@@ -731,16 +731,24 @@
   boot_image = None
   if has_boot:
     banner("boot")
-    # common.GetBootableImage() returns the image directly if present.
-    boot_image = common.GetBootableImage(
-        "IMAGES/boot.img", "boot.img", OPTIONS.input_tmp, "BOOT")
-    # boot.img may be unavailable in some targets (e.g. aosp_arm64).
-    if boot_image:
-      partitions['boot'] = os.path.join(OPTIONS.input_tmp, "IMAGES", "boot.img")
-      if not os.path.exists(partitions['boot']):
-        boot_image.WriteToDir(OPTIONS.input_tmp)
-        if output_zip:
-          boot_image.AddToZip(output_zip)
+    boot_images = OPTIONS.info_dict.get("boot_images")
+    if boot_images is None:
+      boot_images = "boot.img"
+    for b in boot_images.split():
+      # common.GetBootableImage() returns the image directly if present.
+      boot_image = common.GetBootableImage(
+          "IMAGES/" + b, b, OPTIONS.input_tmp, "BOOT")
+      # boot.img may be unavailable in some targets (e.g. aosp_arm64).
+      if boot_image:
+        boot_image_path = os.path.join(OPTIONS.input_tmp, "IMAGES", b)
+        # vbmeta does not need to include boot.img with multiple boot.img files,
+        # which is only used for aosp_arm64 for GKI
+        if len(boot_images.split()) == 1:
+          partitions['boot'] = boot_image_path
+        if not os.path.exists(boot_image_path):
+          boot_image.WriteToDir(OPTIONS.input_tmp)
+          if output_zip:
+            boot_image.AddToZip(output_zip)
 
   if has_vendor_boot:
     banner("vendor_boot")
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index ad69fef..38772cc 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -1047,7 +1047,7 @@
   return ramdisk_img
 
 
-def _BuildBootableImage(sourcedir, fs_config_file, info_dict=None,
+def _BuildBootableImage(image_name, sourcedir, fs_config_file, info_dict=None,
                         has_ramdisk=False, two_step_image=False):
   """Build a bootable image from the specified sourcedir.
 
@@ -1060,7 +1060,15 @@
   for building the requested image.
   """
 
-  if not os.access(os.path.join(sourcedir, "kernel"), os.F_OK):
+  # "boot" or "recovery", without extension.
+  partition_name = os.path.basename(sourcedir).lower()
+
+  if partition_name == "recovery":
+    kernel = "kernel"
+  else:
+    kernel = image_name.replace("boot", "kernel")
+    kernel = kernel.replace(".img","")
+  if not os.access(os.path.join(sourcedir, kernel), os.F_OK):
     return None
 
   if has_ramdisk and not os.access(os.path.join(sourcedir, "RAMDISK"), os.F_OK):
@@ -1077,7 +1085,7 @@
   # use MKBOOTIMG from environ, or "mkbootimg" if empty or not set
   mkbootimg = os.getenv('MKBOOTIMG') or "mkbootimg"
 
-  cmd = [mkbootimg, "--kernel", os.path.join(sourcedir, "kernel")]
+  cmd = [mkbootimg, "--kernel", os.path.join(sourcedir, kernel)]
 
   fn = os.path.join(sourcedir, "second")
   if os.access(fn, os.F_OK):
@@ -1104,9 +1112,6 @@
     cmd.append("--pagesize")
     cmd.append(open(fn).read().rstrip("\n"))
 
-  # "boot" or "recovery", without extension.
-  partition_name = os.path.basename(sourcedir).lower()
-
   if partition_name == "recovery":
     args = info_dict.get("recovery_mkbootimg_args")
   else:
@@ -1229,7 +1234,7 @@
                  info_dict.get("recovery_as_boot") == "true")
 
   fs_config = "META/" + tree_subdir.lower() + "_filesystem_config.txt"
-  data = _BuildBootableImage(os.path.join(unpack_dir, tree_subdir),
+  data = _BuildBootableImage(prebuilt_name, os.path.join(unpack_dir, tree_subdir),
                              os.path.join(unpack_dir, fs_config),
                              info_dict, has_ramdisk, two_step_image)
   if data: