Build repeatable system images with mke2fs.

We have added support in mkuserimg_mke2fs.sh that allows specifying
filesystem UUID and hash seed UUID. This CL generates and passes the
UUIDs based on the image name and build fingerprint. This way we can
rebuild and get identical images.

Note that this only applies to images generated with `m dist` and with
signing tools (sign_target_files_apks.py and
add_img_to_target_files.py). Images under $OUT (built with `make`) are
not affected.

Bug: 64994964
Test: lunch marlin-userdebug; run `m dist` twice (after deleting the
      intermediate files under $OUT/obj/PACKAGING), and compare the
      generated images.
Change-Id: I41cf4e5869582bb930af2f35a8e9c79bff43b2a2
(cherry picked from commit 3aa21e6bb9f46b5c16c4b42757d64e738e506031)
diff --git a/tools/releasetools/add_img_to_target_files.py b/tools/releasetools/add_img_to_target_files.py
index 52d3918..02f2000 100755
--- a/tools/releasetools/add_img_to_target_files.py
+++ b/tools/releasetools/add_img_to_target_files.py
@@ -58,6 +58,7 @@
 import shutil
 import subprocess
 import tempfile
+import uuid
 import zipfile
 
 import build_image
@@ -257,6 +258,19 @@
   if block_list:
     image_props["block_list"] = block_list.name
 
+  # Use repeatable ext4 FS UUID and hash_seed UUID (based on partition name and
+  # build fingerprint).
+  uuid_seed = what + "-"
+  if "build.prop" in info_dict:
+    build_prop = info_dict["build.prop"]
+    if "ro.build.fingerprint" in build_prop:
+      uuid_seed += build_prop["ro.build.fingerprint"]
+    elif "ro.build.thumbprint" in build_prop:
+      uuid_seed += build_prop["ro.build.thumbprint"]
+  image_props["uuid"] = str(uuid.uuid5(uuid.NAMESPACE_URL, uuid_seed))
+  hash_seed = "hash_seed-" + uuid_seed
+  image_props["hash_seed"] = str(uuid.uuid5(uuid.NAMESPACE_URL, hash_seed))
+
   succ = build_image.BuildImage(os.path.join(temp_dir, what),
                                 image_props, output_file.name)
   assert succ, "build " + what + ".img image failed"
diff --git a/tools/releasetools/build_image.py b/tools/releasetools/build_image.py
index 6de9763..1b9bb04 100755
--- a/tools/releasetools/build_image.py
+++ b/tools/releasetools/build_image.py
@@ -467,6 +467,12 @@
       build_command.extend(["-e", prop_dict["flash_erase_block_size"]])
     if "flash_logical_block_size" in prop_dict:
       build_command.extend(["-o", prop_dict["flash_logical_block_size"]])
+    # Specify UUID and hash_seed if using mke2fs.
+    if prop_dict["ext_mkuserimg"] == "mkuserimg_mke2fs.sh":
+      if "uuid" in prop_dict:
+        build_command.extend(["-U", prop_dict["uuid"]])
+      if "hash_seed" in prop_dict:
+        build_command.extend(["-S", prop_dict["hash_seed"]])
     if "selinux_fc" in prop_dict:
       build_command.append(prop_dict["selinux_fc"])
   elif fs_type.startswith("squash"):