Add split super images to target_files.

Test: build target files package
Bug: 118506262
Change-Id: Iee6143987c9bfa6f2d287e20c06ea5ef25e82985
diff --git a/tools/releasetools/add_img_to_target_files.py b/tools/releasetools/add_img_to_target_files.py
index ddc50be..b0dd0f8 100755
--- a/tools/releasetools/add_img_to_target_files.py
+++ b/tools/releasetools/add_img_to_target_files.py
@@ -330,6 +330,12 @@
       image_blocks_key = what + "_image_blocks"
       info_dict[image_blocks_key] = int(image_size) / 4096 - 1
 
+  use_dynamic_size = (
+    info_dict.get("use_dynamic_partition_size") == "true" and
+    what in shlex.split(info_dict.get("dynamic_partition_list", "").strip()))
+  if use_dynamic_size:
+    info_dict.update(build_image.GlobalDictFromImageProp(image_props, what))
+
 
 def AddUserdata(output_zip):
   """Create a userdata image and store it in output_zip.
@@ -656,8 +662,8 @@
   """Create a super_empty.img and store it in output_zip."""
 
   img = OutputFile(output_zip, OPTIONS.input_tmp, "IMAGES", "super_empty.img")
-  cmd = [OPTIONS.info_dict.get('lpmake')]
-  cmd += shlex.split(OPTIONS.info_dict.get('lpmake_args').strip())
+  cmd = [OPTIONS.info_dict['lpmake']]
+  cmd += shlex.split(OPTIONS.info_dict['lpmake_args'].strip())
   cmd += ['--output', img.name]
 
   proc = common.Run(cmd)
@@ -668,6 +674,58 @@
   img.Write()
 
 
+def AddSuperSplit(output_zip):
+  """Create split super_*.img and store it in output_zip."""
+
+  def TransformPartitionArg(arg):
+    lst = arg.split(':')
+    # Because --auto-slot-suffixing for A/B, there is no need to remove suffix.
+    name = lst[0]
+    assert name + '_size' in OPTIONS.info_dict, (
+        "{} is a prebuilt. Dynamic partitions with prebuilt images "
+        "are not supported yet.".format(name))
+    size = OPTIONS.info_dict[name + '_size']
+    assert size is not None, \
+        '{0}_size is not found; is {0} built?'.format(name)
+    lst[2] = str(size)
+    return ':'.join(lst)
+
+  def GetLpmakeArgsWithSizes():
+    lpmake_args = shlex.split(OPTIONS.info_dict['lpmake_args'].strip())
+
+    for i, arg in enumerate(lpmake_args):
+      if arg == '--partition':
+        assert i + 1 < len(lpmake_args), \
+          'lpmake_args has --partition without value'
+        lpmake_args[i + 1] = TransformPartitionArg(lpmake_args[i + 1])
+
+    return lpmake_args
+
+  outdir = OutputFile(output_zip, OPTIONS.input_tmp, "OTA", "")
+  cmd = [OPTIONS.info_dict['lpmake']]
+  cmd += GetLpmakeArgsWithSizes()
+
+  source = OPTIONS.info_dict.get('dynamic_partition_list', '').strip()
+  if source:
+    cmd.append('--sparse')
+    for name in shlex.split(source):
+      img = os.path.join(OPTIONS.input_tmp, "IMAGES", '{}.img'.format(name))
+      # Because --auto-slot-suffixing for A/B, there is no need to add suffix.
+      cmd += ['--image', '{}={}'.format(name, img)]
+
+  cmd += ['--output', outdir.name]
+
+  proc = common.Run(cmd)
+  stdoutdata, _ = proc.communicate()
+  assert proc.returncode == 0, \
+      "lpmake tool failed:\n{}".format(stdoutdata)
+
+  for dev in OPTIONS.info_dict['super_block_devices'].strip().split():
+    img = OutputFile(output_zip, OPTIONS.input_tmp, "OTA",
+                     "super_" + dev + ".img")
+    img.Write()
+
+
 def ReplaceUpdatedFiles(zip_filename, files_list):
   """Updates all the ZIP entries listed in files_list.
 
@@ -861,10 +919,15 @@
     banner("vbmeta")
     AddVBMeta(output_zip, partitions, "vbmeta", vbmeta_partitions)
 
-  if OPTIONS.info_dict.get("super_size"):
+  if OPTIONS.info_dict.get("lpmake_args"):
     banner("super_empty")
     AddSuperEmpty(output_zip)
 
+    if OPTIONS.info_dict.get("dynamic_partition_retrofit") == "true":
+      banner("super split images")
+      AddSuperSplit(output_zip)
+    # TODO(b/119322123): Add super.img to target_files for non-retrofit
+
   banner("radio")
   ab_partitions_txt = os.path.join(OPTIONS.input_tmp, "META",
                                    "ab_partitions.txt")