Add system_other partition, install odex files

For AB devices, support flashing two system partitions for factory use.
The normal system image on one partition, but without dex preopt. And a
system_other image that just contains the odex files. The dex files will
not be stripped out of the system image, in case the second system
partition is wiped.

Setting BOARD_USES_SYSTEM_OTHER_ODEX := true in the BoardConfig.mk
enables this behavior.

One can control which directories are placed in system_other by the
SYSTEM_OTHER_ODEX_FILTER configuration variable. Currently we default
to only copying only app and priv-app odexs.

Bug: 29278988
Change-Id: I7f4e87da919e7dc6a89fd8c668193cd4e98631bc
diff --git a/tools/releasetools/add_img_to_target_files.py b/tools/releasetools/add_img_to_target_files.py
index 7cb9072..ddc0d0b 100755
--- a/tools/releasetools/add_img_to_target_files.py
+++ b/tools/releasetools/add_img_to_target_files.py
@@ -78,6 +78,24 @@
   return CreateImage(input_dir, info_dict, "system", block_list=block_list)
 
 
+def AddSystemOther(output_zip, prefix="IMAGES/"):
+  """Turn the contents of SYSTEM_OTHER into a system_other image
+  and store it in output_zip."""
+
+  prebuilt_path = os.path.join(OPTIONS.input_tmp, prefix, "system_other.img")
+  if os.path.exists(prebuilt_path):
+    print "system_other.img already exists in %s, no need to rebuild..." % (prefix,)
+    return
+
+  imgname = BuildSystemOther(OPTIONS.input_tmp, OPTIONS.info_dict)
+  common.ZipWrite(output_zip, imgname, prefix + "system_other.img")
+
+def BuildSystemOther(input_dir, info_dict):
+  """Build the (sparse) system_other image and return the name of a temp
+  file containing it."""
+  return CreateImage(input_dir, info_dict, "system_other", block_list=None)
+
+
 def AddVendor(output_zip, prefix="IMAGES/"):
   """Turn the contents of VENDOR into a vendor image and store in it
   output_zip."""
@@ -268,6 +286,8 @@
   except KeyError:
     has_vendor = False
 
+  has_system_other = "SYSTEM_OTHER/" in input_zip.namelist()
+
   OPTIONS.info_dict = common.LoadInfoDict(input_zip, OPTIONS.input_tmp)
 
   common.ZipClose(input_zip)
@@ -314,6 +334,9 @@
   if has_vendor:
     banner("vendor")
     AddVendor(output_zip)
+  if has_system_other:
+    banner("system_other")
+    AddSystemOther(output_zip)
   banner("userdata")
   AddUserdata(output_zip)
   banner("cache")