Adds --output-super-empty flag to enable building super_empty.img.

Any mixed build that uses dynamic partitions will require a
super_empty.img image. This image must be created from the merged
misc_info.txt file, so adding this functionality here simplifies
the creation of this image for users (versus having to call
build_super_image.py manually after calling merge_target_files.py).

Bug: 129976345
Test: Ran merge_target_files.py on a dynamic partition enabled build
using the new --output-super-empty flag.

Change-Id: I73901f363d73c9fae1af1579faa2a908369dbbec
diff --git a/tools/releasetools/merge_target_files.py b/tools/releasetools/merge_target_files.py
index e9ae5cd..97b53d9 100755
--- a/tools/releasetools/merge_target_files.py
+++ b/tools/releasetools/merge_target_files.py
@@ -54,6 +54,10 @@
       file patterns to copy into the --output-dir. Required if providing
       the --output-dir flag.
 
+  --output-super-empty output-super-empty-image
+      If provided, creates a super_empty.img file from the merged target
+      files package and saves it at this path.
+
   --rebuild_recovery
       Rebuild the recovery patch used by non-A/B devices and write it to the
       system image.
@@ -71,8 +75,9 @@
 import sys
 import zipfile
 
-import common
 import add_img_to_target_files
+import build_super_image
+import common
 
 logger = logging.getLogger(__name__)
 OPTIONS = common.OPTIONS
@@ -85,6 +90,7 @@
 OPTIONS.output_target_files = None
 OPTIONS.output_dir = None
 OPTIONS.output_item_list = None
+OPTIONS.output_super_empty = None
 OPTIONS.rebuild_recovery = False
 OPTIONS.keep_tmp = False
 
@@ -424,7 +430,7 @@
     # a shared system image.
     for partition_group in merged_info_dict['super_partition_groups'].split(' '):
       if ('super_%s_group_size' % partition_group) not in merged_info_dict:
-        raise common.ExternalError(
+        raise ValueError(
             'Other META/misc_info.txt does not contain required key '
             'super_%s_group_size.' % partition_group)
       key = 'super_%s_partition_list' % partition_group
@@ -584,6 +590,7 @@
     output_target_files,
     output_dir,
     output_item_list,
+    output_super_empty,
     rebuild_recovery):
   """Merge two target files packages together.
 
@@ -618,6 +625,9 @@
     output_target_files: The name of the output zip archive target files
     package created by merging system and other.
 
+    output_super_empty: If provided, creates a super_empty.img file from the
+    merged target files package and saves it at this path.
+
     rebuild_recovery: If true, rebuild the recovery patch used by non-A/B
     devices and write it to the system image.
   """
@@ -684,6 +694,27 @@
       system_misc_info_keys=system_misc_info_keys,
       rebuild_recovery=rebuild_recovery)
 
+  # Create super_empty.img using the merged misc_info.txt.
+
+  if output_super_empty:
+    misc_info_txt = os.path.join(output_target_files_temp_dir,
+                                 'META', 'misc_info.txt')
+    def read_helper():
+      with open(misc_info_txt) as f:
+        return list(f.read().splitlines())
+
+    misc_info_dict = common.LoadDictionaryFromLines(read_helper())
+    if misc_info_dict.get('use_dynamic_partitions') != 'true':
+      raise ValueError(
+          'Building super_empty.img requires use_dynamic_partitions=true.')
+
+    build_super_image_args = [
+      '--verbose',
+      misc_info_txt,
+      output_super_empty,
+    ]
+    build_super_image.main(build_super_image_args)
+
   # Regenerate IMAGES in the temporary directory.
 
   add_img_args = ['--verbose']
@@ -796,6 +827,8 @@
       OPTIONS.output_dir = a
     elif o == '--output-item-list':
       OPTIONS.output_item_list = a
+    elif o == '--output-super-empty':
+      OPTIONS.output_super_empty = a
     elif o == '--rebuild_recovery':
       OPTIONS.rebuild_recovery = True
     elif o == '--keep-tmp':
@@ -815,6 +848,7 @@
           'output-target-files=',
           'output-dir=',
           'output-item-list=',
+          'output-super-empty=',
           'rebuild_recovery',
           'keep-tmp',
       ],
@@ -867,6 +901,7 @@
           output_target_files=OPTIONS.output_target_files,
           output_dir=OPTIONS.output_dir,
           output_item_list=output_item_list,
+          output_super_empty=OPTIONS.output_super_empty,
           rebuild_recovery=OPTIONS.rebuild_recovery),
       OPTIONS.keep_tmp)