support use of prebuilt bootable images

img_from_target_files now, with the -z flag, will produce an output
zip with only the bootable partitions (boot and recovery).

img_ and ota_from_target_files can take, instead of a simple
"target_files.zip", a name of the form
"target_files.zip+bootable_images.zip", where the second zip contains
bootable images that should be used instead of building them from the
target_files.zip.  (This should be the zip produced by the above -z
flag, perhaps with the images messed with in some way, such as by an
unnamed OEM's extra signature wrapper for their "secure boot"
process.)

Bug: 3391371
Change-Id: Iaf96dfc8f30e806ae342dcf3241566e76ae372d4
diff --git a/tools/releasetools/img_from_target_files b/tools/releasetools/img_from_target_files
index 793f7ac..08817ca 100755
--- a/tools/releasetools/img_from_target_files
+++ b/tools/releasetools/img_from_target_files
@@ -23,6 +23,10 @@
   -b  (--board_config)  <file>
       Deprecated.
 
+  -z  (--bootable_zip)
+      Include only the bootable images (eg 'boot' and 'recovery') in
+      the output.
+
 """
 
 import sys
@@ -149,35 +153,44 @@
 
 
 def main(argv):
+  bootable_only = [False]
 
   def option_handler(o, a):
     if o in ("-b", "--board_config"):
       pass       # deprecated
+    if o in ("-z", "--bootable_zip"):
+      bootable_only[0] = True
     else:
       return False
     return True
 
   args = common.ParseOptions(argv, __doc__,
-                             extra_opts="b:",
-                             extra_long_opts=["board_config="],
+                             extra_opts="b:z",
+                             extra_long_opts=["board_config=",
+                                              "bootable_zip"],
                              extra_option_handler=option_handler)
 
+  bootable_only = bootable_only[0]
+
   if len(args) != 2:
     common.Usage(__doc__)
     sys.exit(1)
 
-  OPTIONS.input_tmp = common.UnzipTemp(args[0])
-
-  input_zip = zipfile.ZipFile(args[0], "r")
+  OPTIONS.input_tmp, input_zip = common.UnzipTemp(args[0])
   OPTIONS.info_dict = common.LoadInfoDict(input_zip)
 
   output_zip = zipfile.ZipFile(args[1], "w", compression=zipfile.ZIP_DEFLATED)
 
-  common.AddBoot(output_zip, OPTIONS.info_dict)
-  common.AddRecovery(output_zip, OPTIONS.info_dict)
-  AddSystem(output_zip)
-  AddUserdata(output_zip)
-  CopyInfo(output_zip)
+  common.GetBootableImage(
+      "boot.img", "boot.img", OPTIONS.input_tmp, "BOOT").AddToZip(output_zip)
+  common.GetBootableImage(
+      "recovery.img", "recovery.img", OPTIONS.input_tmp,
+      "RECOVERY").AddToZip(output_zip)
+
+  if not bootable_only:
+    AddSystem(output_zip)
+    AddUserdata(output_zip)
+    CopyInfo(output_zip)
 
   print "cleaning up..."
   output_zip.close()