resolve merge conflicts of 333df6c to nyc-mr1-dev-plus-aosp

Change-Id: Ibe66a7c78073a9c3e9f139bd6b00a0afab075190
diff --git a/tools/releasetools/add_img_to_target_files.py b/tools/releasetools/add_img_to_target_files.py
index 03bb0b1..aeb73d4 100755
--- a/tools/releasetools/add_img_to_target_files.py
+++ b/tools/releasetools/add_img_to_target_files.py
@@ -39,6 +39,7 @@
 
 import build_image
 import common
+import sparse_img
 
 OPTIONS = common.OPTIONS
 
@@ -48,6 +49,19 @@
 OPTIONS.replace_verity_private_key = False
 OPTIONS.verity_signer_path = None
 
+def GetCareMap(which, imgname):
+  """Generate care_map of system (or vendor) partition"""
+
+  assert which in ("system", "vendor")
+  _, blk_device = common.GetTypeAndDevice("/" + which, OPTIONS.info_dict)
+
+  simg = sparse_img.SparseImage(imgname)
+  care_map_list = []
+  care_map_list.append(blk_device)
+  care_map_list.append(simg.care_map.to_string_raw())
+  return care_map_list
+
+
 def AddSystem(output_zip, prefix="IMAGES/", recovery_img=None, boot_img=None):
   """Turn the contents of SYSTEM into a system image and store it in
   output_zip. Returns the name of the system image file."""
@@ -120,13 +134,14 @@
   prebuilt_path = os.path.join(OPTIONS.input_tmp, prefix, "vendor.img")
   if os.path.exists(prebuilt_path):
     print "vendor.img already exists in %s, no need to rebuild..." % (prefix,)
-    return
+    return prebuilt_path
 
   block_list = common.MakeTempFile(prefix="vendor-blocklist-", suffix=".map")
   imgname = BuildVendor(OPTIONS.input_tmp, OPTIONS.info_dict,
                         block_list=block_list)
   common.ZipWrite(output_zip, imgname, prefix + "vendor.img")
   common.ZipWrite(output_zip, block_list, prefix + "vendor.map")
+  return imgname
 
 
 def BuildVendor(input_dir, info_dict, block_list=None):
@@ -156,8 +171,9 @@
 
   image_props = build_image.ImagePropFromGlobalDict(info_dict, what)
   fstab = info_dict["fstab"]
-  if fstab:
-    image_props["fs_type"] = fstab["/" + what].fs_type
+  mount_point = "/" + what
+  if fstab and mount_point in fstab:
+    image_props["fs_type"] = fstab[mount_point].fs_type
 
   # Use a fixed timestamp (01/01/2009) when packaging the image.
   # Bug: 24377993
@@ -402,9 +418,10 @@
       system_img_path=system_img_path)
     if boot_image:
       boot_image.AddToZip(output_zip)
+  vendor_img_path = None
   if has_vendor:
     banner("vendor")
-    AddVendor(output_zip)
+    vendor_img_path = AddVendor(output_zip)
   if has_system_other:
     banner("system_other")
     AddSystemOther(output_zip)
@@ -424,7 +441,19 @@
   if os.path.exists(ab_partitions):
     with open(ab_partitions, 'r') as f:
       lines = f.readlines()
+    # For devices using A/B update, generate care_map for system and vendor
+    # partitions (if present), then write this file to target_files package.
+    care_map_list = []
     for line in lines:
+      if line.strip() == "system" and OPTIONS.info_dict.get(
+          "system_verity_block_device", None) is not None:
+        assert os.path.exists(system_img_path)
+        care_map_list += GetCareMap("system", system_img_path)
+      if line.strip() == "vendor" and OPTIONS.info_dict.get(
+          "vendor_verity_block_device", None) is not None:
+        assert os.path.exists(vendor_img_path)
+        care_map_list += GetCareMap("vendor", vendor_img_path)
+
       img_name = line.strip() + ".img"
       prebuilt_path = os.path.join(OPTIONS.input_tmp, "IMAGES", img_name)
       if os.path.exists(prebuilt_path):
@@ -448,6 +477,10 @@
       img_path = 'IMAGES/' + img_name
       assert img_path in output_zip.namelist(), "cannot find " + img_name
 
+    if care_map_list:
+      file_path = "META/care_map.txt"
+      common.ZipWriteStr(output_zip, file_path, '\n'.join(care_map_list))
+
   common.ZipClose(output_zip)
 
 def main(argv):
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index 3f3b011..e035302 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -251,11 +251,18 @@
   makeint("boot_size")
   makeint("fstab_version")
 
-  if d.get("no_recovery", False) == "true":
-    d["fstab"] = None
-  else:
+  system_root_image = d.get("system_root_image", None) == "true"
+  if d.get("no_recovery", None) != "true":
+    recovery_fstab_path = "RECOVERY/RAMDISK/etc/recovery.fstab"
     d["fstab"] = LoadRecoveryFSTab(read_helper, d["fstab_version"],
-                                   d.get("system_root_image", False))
+        recovery_fstab_path, system_root_image)
+  elif d.get("recovery_as_boot", None) == "true":
+    recovery_fstab_path = "BOOT/RAMDISK/etc/recovery.fstab"
+    d["fstab"] = LoadRecoveryFSTab(read_helper, d["fstab_version"],
+        recovery_fstab_path, system_root_image)
+  else:
+    d["fstab"] = None
+
   d["build.prop"] = LoadBuildProp(read_helper)
   return d
 
@@ -278,7 +285,8 @@
       d[name] = value
   return d
 
-def LoadRecoveryFSTab(read_helper, fstab_version, system_root_image=False):
+def LoadRecoveryFSTab(read_helper, fstab_version, recovery_fstab_path,
+                      system_root_image=False):
   class Partition(object):
     def __init__(self, mount_point, fs_type, device, length, device2, context):
       self.mount_point = mount_point
@@ -289,9 +297,9 @@
       self.context = context
 
   try:
-    data = read_helper("RECOVERY/RAMDISK/etc/recovery.fstab")
+    data = read_helper(recovery_fstab_path)
   except KeyError:
-    print "Warning: could not find RECOVERY/RAMDISK/etc/recovery.fstab"
+    print "Warning: could not find {}".format(recovery_fstab_path)
     data = ""
 
   if fstab_version == 1:
diff --git a/tools/releasetools/ota_from_target_files.py b/tools/releasetools/ota_from_target_files.py
index f32d9d8..dc93a9d 100755
--- a/tools/releasetools/ota_from_target_files.py
+++ b/tools/releasetools/ota_from_target_files.py
@@ -1317,6 +1317,19 @@
                   compress_type=zipfile.ZIP_STORED)
   WriteMetadata(metadata, output_zip)
 
+  # If dm-verity is supported for the device, copy contents of care_map
+  # into A/B OTA package.
+  if OPTIONS.info_dict.get("verity") == "true":
+    target_zip = zipfile.ZipFile(target_file, "r")
+    care_map_path = "META/care_map.txt"
+    namelist = target_zip.namelist()
+    if care_map_path in namelist:
+      care_map_data = target_zip.read(care_map_path)
+      common.ZipWriteStr(output_zip, "care_map.txt", care_map_data)
+    else:
+      print "Warning: cannot find care map file in target_file package"
+    common.ZipClose(target_zip)
+
   # Sign the whole package to comply with the Android OTA package format.
   common.ZipClose(output_zip)
   SignOutput(temp_zip_file.name, output_file)