[automerger skipped] Import translations. DO NOT MERGE ANYWHERE am: 686da02c37 -s ours

am skip reason: subject contains skip directive

Original change: https://googleplex-android-review.googlesource.com/c/platform/bootable/recovery/+/24212910

Change-Id: I9f981bcdccf0702b08e3068964b099f1aa6f2c05
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/Android.bp b/Android.bp
index bd95705..fba358f 100644
--- a/Android.bp
+++ b/Android.bp
@@ -94,6 +94,8 @@
     shared_libs: [
         "android.hardware.boot@1.0",
         "android.hardware.boot@1.1",
+        "android.hardware.boot-V1-ndk",
+        "libboot_control_client",
         "libbase",
         "libbootloader_message",
         "libcrypto",
@@ -113,6 +115,9 @@
         "librecovery_utils",
         "libotautil",
         "libsnapshot_nobinder",
+        "libsnapshot_cow",
+        "liblz4",
+        "libzstd",
         "update_metadata-protos",
     ],
 }
@@ -157,7 +162,8 @@
     ],
 
     shared_libs: [
-        "android.hardware.health-V1-ndk", // from librecovery_utils
+        "android.hardware.health-V2-ndk", // from librecovery_utils
+        "android.hardware.boot-V1-ndk",
         "librecovery_ui",
     ],
 
diff --git a/README.md b/README.md
index 5ab19d1..507b2bd 100644
--- a/README.md
+++ b/README.md
@@ -137,7 +137,7 @@
 Note that this mechanism applies to both of normal boot and recovery modes.
 
  * **Option 2:** Allow `adbd` to connect without authentication.
-   * `adbd` is compiled with `ALLOW_ADBD_NO_AUTH` (only on debuggable builds).
+   * bootloader is unlocked (`ro.boot.verifiedbootstate` is `orange`) or debuggable build.
    * `ro.adb.secure` has a value of `0`.
 
 Both of the two conditions need to be satisfied. Although `ro.adb.secure` is a runtime property, its
diff --git a/bootloader_message/Android.bp b/bootloader_message/Android.bp
index 778fdb9..7622677 100644
--- a/bootloader_message/Android.bp
+++ b/bootloader_message/Android.bp
@@ -45,6 +45,7 @@
         "libbootloader_message_defaults",
     ],
     recovery_available: true,
+    vendor_available: true,
     host_supported: true,
 
     target: {
diff --git a/bootloader_message/include/bootloader_message/bootloader_message.h b/bootloader_message/include/bootloader_message/bootloader_message.h
index d58158d..8fba101 100644
--- a/bootloader_message/include/bootloader_message/bootloader_message.h
+++ b/bootloader_message/include/bootloader_message/bootloader_message.h
@@ -109,6 +109,7 @@
 #define MISC_MEMTAG_MODE_MEMTAG_ONCE 0x2
 #define MISC_MEMTAG_MODE_MEMTAG_KERNEL 0x4
 #define MISC_MEMTAG_MODE_MEMTAG_KERNEL_ONCE 0x8
+#define MISC_MEMTAG_MODE_MEMTAG_OFF 0x10
 
 #if (__STDC_VERSION__ >= 201112L) || defined(__cplusplus)
 static_assert(sizeof(struct misc_virtual_ab_message) == 64,
diff --git a/etc/init.rc b/etc/init.rc
index e4afecf..c7ff2b2 100644
--- a/etc/init.rc
+++ b/etc/init.rc
@@ -102,7 +102,7 @@
 on fs && property:sys.usb.configfs=1
     mount configfs none /config
     mkdir /config/usb_gadget/g1 0770 shell shell
-    write /config/usb_gadget/g1/idVendor 0x18D1
+    write /config/usb_gadget/g1/idVendor 0x${ro.recovery.usb.vid}
     mkdir /config/usb_gadget/g1/strings/0x409 0770
     write /config/usb_gadget/g1/strings/0x409/serialnumber ${ro.serialno}
     write /config/usb_gadget/g1/strings/0x409/manufacturer ${ro.product.manufacturer}
@@ -110,11 +110,13 @@
     mkdir /config/usb_gadget/g1/functions/ffs.adb
     mkdir /config/usb_gadget/g1/functions/ffs.fastboot
     mkdir /config/usb_gadget/g1/configs/b.1 0777 shell shell
+    # Set current limit to 900mA (b/277022505)
+    write /config/usb_gadget/g1/configs/b.1/MaxPower 0x384
     mkdir /config/usb_gadget/g1/configs/b.1/strings/0x409 0770 shell shell
 
 on fs && property:sys.usb.configfs=0
     write /sys/class/android_usb/android0/f_ffs/aliases adb,fastboot
-    write /sys/class/android_usb/android0/idVendor 18D1
+    write /sys/class/android_usb/android0/idVendor ${ro.recovery.usb.vid}
     write /sys/class/android_usb/android0/iManufacturer ${ro.product.manufacturer}
     write /sys/class/android_usb/android0/iProduct ${ro.product.model}
     write /sys/class/android_usb/android0/iSerial ${ro.serialno}
@@ -139,19 +141,19 @@
     setprop sys.usb.state ${sys.usb.config}
 
 on property:sys.usb.config=adb && property:sys.usb.configfs=0
-    write /sys/class/android_usb/android0/idProduct D001
+    write /sys/class/android_usb/android0/idProduct ${ro.recovery.usb.adb.pid}
     write /sys/class/android_usb/android0/functions adb
     write /sys/class/android_usb/android0/enable 1
     setprop sys.usb.state ${sys.usb.config}
 
 on property:sys.usb.config=sideload && property:sys.usb.configfs=0
-    write /sys/class/android_usb/android0/idProduct D001
+    write /sys/class/android_usb/android0/idProduct ${ro.recovery.usb.adb.pid}
     write /sys/class/android_usb/android0/functions adb
     write /sys/class/android_usb/android0/enable 1
     setprop sys.usb.state ${sys.usb.config}
 
 on property:sys.usb.config=fastboot && property:sys.usb.configfs=0
-    write /sys/class/android_usb/android0/idProduct 4EE0
+    write /sys/class/android_usb/android0/idProduct ${ro.recovery.usb.fastboot.pid}
     write /sys/class/android_usb/android0/functions fastboot
     write /sys/class/android_usb/android0/enable 1
     setprop sys.usb.state ${sys.usb.config}
@@ -166,21 +168,21 @@
     setprop sys.usb.state ${sys.usb.config}
 
 on property:sys.usb.config=sideload && property:sys.usb.ffs.ready=1 && property:sys.usb.configfs=1
-    write /config/usb_gadget/g1/idProduct 0xD001
+    write /config/usb_gadget/g1/idProduct 0x${ro.recovery.usb.adb.pid}
     write /config/usb_gadget/g1/configs/b.1/strings/0x409/configuration "adb"
     symlink /config/usb_gadget/g1/functions/ffs.adb /config/usb_gadget/g1/configs/b.1/f1
     write /config/usb_gadget/g1/UDC ${sys.usb.controller}
     setprop sys.usb.state ${sys.usb.config}
 
 on property:sys.usb.config=adb && property:sys.usb.ffs.ready=1 && property:sys.usb.configfs=1
-    write /config/usb_gadget/g1/idProduct 0xD001
+    write /config/usb_gadget/g1/idProduct 0x${ro.recovery.usb.adb.pid}
     write /config/usb_gadget/g1/configs/b.1/strings/0x409/configuration "adb"
     symlink /config/usb_gadget/g1/functions/ffs.adb /config/usb_gadget/g1/configs/b.1/f1
     write /config/usb_gadget/g1/UDC ${sys.usb.controller}
     setprop sys.usb.state ${sys.usb.config}
 
 on property:sys.usb.config=fastboot && property:sys.usb.ffs.ready=1 && property:sys.usb.configfs=1
-    write /config/usb_gadget/g1/idProduct 0x4EE0
+    write /config/usb_gadget/g1/idProduct 0x${ro.recovery.usb.fastboot.pid}
     write /config/usb_gadget/g1/configs/b.1/strings/0x409/configuration "fastboot"
     symlink /config/usb_gadget/g1/functions/ffs.fastboot /config/usb_gadget/g1/configs/b.1/f1
     write /config/usb_gadget/g1/UDC ${sys.usb.controller}
diff --git a/install/include/install/wipe_device.h b/install/include/install/wipe_device.h
index 903ddfd..19e7c65 100644
--- a/install/include/install/wipe_device.h
+++ b/install/include/install/wipe_device.h
@@ -24,6 +24,7 @@
 
 // Wipes the current A/B device, with a secure wipe of all the partitions in RECOVERY_WIPE.
 bool WipeAbDevice(Device* device, size_t wipe_package_size);
+bool WipeAbDevice(Device* device, Package* wipe_package);
 
 // Reads the "recovery.wipe" entry in the zip archive returns a list of partitions to wipe.
 std::vector<std::string> GetWipePartitionList(Package* wipe_package);
diff --git a/install/install.cpp b/install/install.cpp
index 83f3cad..a9786cf 100644
--- a/install/install.cpp
+++ b/install/install.cpp
@@ -48,6 +48,7 @@
 
 #include "install/spl_check.h"
 #include "install/wipe_data.h"
+#include "install/wipe_device.h"
 #include "otautil/error_code.h"
 #include "otautil/package.h"
 #include "otautil/paths.h"
@@ -70,6 +71,10 @@
 static constexpr float VERIFICATION_PROGRESS_FRACTION = 0.25;
 // The charater used to separate dynamic fingerprints. e.x. sargo|aosp-sargo
 static const char* FINGERPRING_SEPARATOR = "|";
+static constexpr auto&& RELEASE_KEYS_TAG = "release-keys";
+// If brick packages are smaller than |MEMORY_PACKAGE_LIMIT|, read the entire package into memory
+static constexpr size_t MEMORY_PACKAGE_LIMIT = 1024 * 1024;
+
 static std::condition_variable finish_log_temperature;
 static bool isInStringList(const std::string& target_token, const std::string& str_list,
                            const std::string& deliminator);
@@ -213,6 +218,7 @@
   // We allow the package to not have any serialno; and we also allow it to carry multiple serial
   // numbers split by "|"; e.g. serialno=serialno1|serialno2|serialno3 ... We will fail the
   // verification if the device's serialno doesn't match any of these carried numbers.
+
   auto pkg_serial_no = get_value(metadata, "serialno");
   if (!pkg_serial_no.empty()) {
     auto device_serial_no = android::base::GetProperty("ro.serialno", "");
@@ -226,6 +232,21 @@
       LOG(ERROR) << "Package is for serial " << pkg_serial_no;
       return false;
     }
+  } else if (ota_type == OtaType::BRICK) {
+    const auto device_build_tag = android::base::GetProperty("ro.build.tags", "");
+    if (device_build_tag.empty()) {
+      LOG(ERROR) << "Unable to determine device build tags, serial number is missing from package. "
+                    "Rejecting the brick OTA package.";
+      return false;
+    }
+    if (device_build_tag == RELEASE_KEYS_TAG) {
+      LOG(ERROR) << "Device is release key build, serial number is missing from package. "
+                    "Rejecting the brick OTA package.";
+      return false;
+    }
+    LOG(INFO)
+        << "Serial number is missing from brick OTA package, permitting anyway because device is "
+        << device_build_tag;
   }
 
   if (ota_type == OtaType::AB) {
@@ -364,7 +385,20 @@
     return INSTALL_CORRUPT;
   }
 
-  bool package_is_ab = get_value(metadata, "ota-type") == OtaTypeToString(OtaType::AB);
+  const bool package_is_ab = get_value(metadata, "ota-type") == OtaTypeToString(OtaType::AB);
+  const bool package_is_brick = get_value(metadata, "ota-type") == OtaTypeToString(OtaType::BRICK);
+  if (package_is_brick) {
+    LOG(INFO) << "Installing a brick package";
+    if (package->GetType() == PackageType::kFile &&
+        package->GetPackageSize() < MEMORY_PACKAGE_LIMIT) {
+      std::vector<uint8_t> content(package->GetPackageSize());
+      if (package->ReadFullyAtOffset(content.data(), content.size(), 0)) {
+        auto memory_package = Package::CreateMemoryPackage(std::move(content), {});
+        return WipeAbDevice(device, memory_package.get()) ? INSTALL_SUCCESS : INSTALL_ERROR;
+      }
+    }
+    return WipeAbDevice(device, package) ? INSTALL_SUCCESS : INSTALL_ERROR;
+  }
   bool device_supports_ab = android::base::GetBoolProperty("ro.build.ab_update", false);
   bool ab_device_supports_nonab =
       android::base::GetBoolProperty("ro.virtual_ab.allow_non_ab", false);
@@ -551,7 +585,9 @@
   } else {
     LOG(FATAL) << "Invalid status code " << status;
   }
-  PerformPowerwashIfRequired(zip, device);
+  if (package_is_ab) {
+    PerformPowerwashIfRequired(zip, device);
+  }
 
   return INSTALL_SUCCESS;
 }
diff --git a/install/wipe_data.cpp b/install/wipe_data.cpp
index 024c1e1..c65e6f4 100644
--- a/install/wipe_data.cpp
+++ b/install/wipe_data.cpp
@@ -25,6 +25,7 @@
 #include <android-base/logging.h>
 #include <android-base/stringprintf.h>
 
+#include "bootloader_message/bootloader_message.h"
 #include "install/snapshot_utils.h"
 #include "otautil/dirutil.h"
 #include "recovery_ui/ui.h"
@@ -100,6 +101,12 @@
       success &= EraseVolume(METADATA_ROOT, ui);
     }
   }
+  ui->Print("Resetting memtag message...\n");
+  std::string err;
+  if (!WriteMiscMemtagMessage({}, &err)) {
+    ui->Print("Failed to reset memtag message: %s\n", err.c_str());
+    success = false;
+  }
   if (success) {
     success &= device->PostWipeData();
   }
diff --git a/install/wipe_device.cpp b/install/wipe_device.cpp
index 0a525fa..2656580 100644
--- a/install/wipe_device.cpp
+++ b/install/wipe_device.cpp
@@ -182,13 +182,17 @@
     LOG(ERROR) << "Failed to open wipe package";
     return false;
   }
+  return WipeAbDevice(device, wipe_package.get());
+}
 
-  if (!CheckWipePackage(wipe_package.get(), ui)) {
+bool WipeAbDevice(Device* device, Package* wipe_package) {
+  auto ui = device->GetUI();
+  if (!CheckWipePackage(wipe_package, ui)) {
     LOG(ERROR) << "Failed to verify wipe package";
     return false;
   }
 
-  auto partition_list = GetWipePartitionList(wipe_package.get());
+  auto partition_list = GetWipePartitionList(wipe_package);
   if (partition_list.empty()) {
     LOG(ERROR) << "Empty wipe ab partition list";
     return false;
diff --git a/minadbd/Android.bp b/minadbd/Android.bp
index 9d3f733..c664d74 100644
--- a/minadbd/Android.bp
+++ b/minadbd/Android.bp
@@ -97,7 +97,7 @@
     ],
 
     shared_libs: [
-        "android.hardware.health-V1-ndk", // from librecovery_utils
+        "android.hardware.health-V2-ndk", // from librecovery_utils
         "libbase",
         "libcrypto",
     ],
@@ -129,7 +129,7 @@
     ],
 
     static_libs: [
-        "android.hardware.health-V1-ndk", // from librecovery_utils
+        "android.hardware.health-V2-ndk", // from librecovery_utils
         "libminadbd_services",
         "libfusesideload",
         "librecovery_utils",
diff --git a/minadbd/OWNERS b/minadbd/OWNERS
new file mode 100644
index 0000000..8ee79dd
--- /dev/null
+++ b/minadbd/OWNERS
@@ -0,0 +1,2 @@
+enh@google.com
+shaju@google.com
diff --git a/minadbd/minadbd_services.cpp b/minadbd/minadbd_services.cpp
index 0abe867..16bcb5e 100644
--- a/minadbd/minadbd_services.cpp
+++ b/minadbd/minadbd_services.cpp
@@ -305,7 +305,7 @@
   }
 }
 
-asocket* daemon_service_to_socket(std::string_view) {
+asocket* daemon_service_to_socket(std::string_view, atransport*) {
   return nullptr;
 }
 
diff --git a/minui/graphics_fbdev.cpp b/minui/graphics_fbdev.cpp
index 4a7d325..2711af7 100644
--- a/minui/graphics_fbdev.cpp
+++ b/minui/graphics_fbdev.cpp
@@ -44,7 +44,11 @@
 }
 
 void MinuiBackendFbdev::Blank(bool blank, DrmConnector index) {
-  fprintf(stderr, "Unsupported multiple connectors, blank = %d, index = %d\n", blank, index);
+  if (index == DRM_MAIN) {
+    MinuiBackendFbdev::Blank(blank);
+  } else {
+    fprintf(stderr, "Unsupported multiple connectors, blank = %d, index = %d\n", blank, index);
+  }
 }
 
 bool MinuiBackendFbdev::HasMultipleConnectors() {
diff --git a/otautil/verifier.cpp b/otautil/verifier.cpp
index 8a65566..83ad708 100644
--- a/otautil/verifier.cpp
+++ b/otautil/verifier.cpp
@@ -309,13 +309,15 @@
 }
 
 static std::vector<Certificate> IterateZipEntriesAndSearchForKeys(const ZipArchiveHandle& handle) {
-  void* cookie;
+  void* cookie{};
+
   int32_t iter_status = StartIteration(handle, &cookie, "", "x509.pem");
   if (iter_status != 0) {
     LOG(ERROR) << "Failed to iterate over entries in the certificate zipfile: "
                << ErrorCodeString(iter_status);
     return {};
   }
+  std::unique_ptr<void, decltype(&EndIteration)> cookie_guard(cookie, &EndIteration);
 
   std::vector<Certificate> result;
 
diff --git a/recovery-persist.cpp b/recovery-persist.cpp
index ad101ed..55699b2 100644
--- a/recovery-persist.cpp
+++ b/recovery-persist.cpp
@@ -77,6 +77,10 @@
   }
 }
 
+static bool file_exists(const char* filename) {
+  return access(filename, R_OK) == 0;
+}
+
 static bool rotated = false;
 
 ssize_t logsave(
@@ -141,7 +145,7 @@
     if (has_cache) {
       // Collects and reports the non-a/b update metrics from last_install; and removes the file
       // to avoid duplicate report.
-      if (access(LAST_INSTALL_FILE_IN_CACHE, F_OK) && unlink(LAST_INSTALL_FILE_IN_CACHE) == -1) {
+      if (file_exists(LAST_INSTALL_FILE_IN_CACHE) && unlink(LAST_INSTALL_FILE_IN_CACHE) == -1) {
         PLOG(ERROR) << "Failed to unlink " << LAST_INSTALL_FILE_IN_CACHE;
       }
 
@@ -152,9 +156,9 @@
       }
     }
 
-    /* Is there something in pmsg? */
-    if (access(LAST_PMSG_FILE, R_OK)) {
-        return 0;
+    /* Is there something in pmsg? If not, no need to proceed. */
+    if (!file_exists(LAST_PMSG_FILE)) {
+      return 0;
     }
 
     // Take last pmsg file contents and send it off to the logsave
@@ -164,18 +168,18 @@
     // For those device without /cache, the last_install file has been copied to
     // /data/misc/recovery from pmsg. Looks for the sideload history only.
     if (!has_cache) {
-      if (access(LAST_INSTALL_FILE, F_OK) && unlink(LAST_INSTALL_FILE) == -1) {
+      if (file_exists(LAST_INSTALL_FILE) && unlink(LAST_INSTALL_FILE) == -1) {
         PLOG(ERROR) << "Failed to unlink " << LAST_INSTALL_FILE;
       }
     }
 
     /* Is there a last console log too? */
     if (rotated) {
-        if (!access(LAST_CONSOLE_FILE, R_OK)) {
-            copy_file(LAST_CONSOLE_FILE, LAST_KMSG_FILE);
-        } else if (!access(ALT_LAST_CONSOLE_FILE, R_OK)) {
-            copy_file(ALT_LAST_CONSOLE_FILE, LAST_KMSG_FILE);
-        }
+      if (file_exists(LAST_CONSOLE_FILE)) {
+        copy_file(LAST_CONSOLE_FILE, LAST_KMSG_FILE);
+      } else if (file_exists(ALT_LAST_CONSOLE_FILE)) {
+        copy_file(ALT_LAST_CONSOLE_FILE, LAST_KMSG_FILE);
+      }
     }
 
     return 0;
diff --git a/recovery_utils/Android.bp b/recovery_utils/Android.bp
index 9bd66c5..74392c5 100644
--- a/recovery_utils/Android.bp
+++ b/recovery_utils/Android.bp
@@ -75,11 +75,11 @@
 
     shared_libs: [
         // The following cannot be placed in librecovery_utils_defaults,
-        // because at the time of writing, android.hardware.health-V1-ndk.so
+        // because at the time of writing, android.hardware.health-V2-ndk.so
         // is not installed to the system image yet. (It is installed
         // to the recovery ramdisk.) Hence, minadbd_test must link to it
         // statically.
-        "android.hardware.health-V1-ndk",
+        "android.hardware.health-V2-ndk",
     ],
 
     export_include_dirs: [
diff --git a/tests/Android.bp b/tests/Android.bp
index 0708e85..b888d47 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -148,7 +148,7 @@
 
     static_libs: libapplypatch_static_libs + librecovery_static_libs + [
         "android.hardware.health-translate-ndk",
-        "android.hardware.health-V1-ndk",
+        "android.hardware.health-V2-ndk",
         "libhealthshim",
         "librecovery_ui",
         "libfusesideload",
diff --git a/tools/image_generator/ImageGenerator.java b/tools/image_generator/ImageGenerator.java
index 6c5ea4b..00264b1 100644
--- a/tools/image_generator/ImageGenerator.java
+++ b/tools/image_generator/ImageGenerator.java
@@ -16,6 +16,8 @@
 
 package com.android.recovery.tools;
 
+import static java.util.Map.entry;
+
 import com.ibm.icu.text.BreakIterator;
 
 import org.apache.commons.cli.CommandLine;
@@ -111,49 +113,43 @@
     // https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry
     private static final String DEFAULT_FONT_NAME = "Roboto-Regular";
     private static final Map<String, String> LANGUAGE_TO_FONT_MAP =
-            new TreeMap<String, String>() {
-                {
-                    put("am", "NotoSansEthiopic-VF");
-                    put("ar", "NotoNaskhArabicUI-Regular");
-                    put("as", "NotoSansBengaliUI-VF");
-                    put("bn", "NotoSansBengaliUI-VF");
-                    put("fa", "NotoNaskhArabicUI-Regular");
-                    put("gu", "NotoSansGujaratiUI-Regular");
-                    put("hi", "NotoSansDevanagariUI-VF");
-                    put("hy", "NotoSansArmenian-VF");
-                    put("iw", "NotoSansHebrew-Regular");
-                    put("ja", "NotoSansCJK-Regular");
-                    put("ka", "NotoSansGeorgian-VF");
-                    put("ko", "NotoSansCJK-Regular");
-                    put("km", "NotoSansKhmerUI-Regular");
-                    put("kn", "NotoSansKannadaUI-VF");
-                    put("lo", "NotoSansLaoUI-Regular");
-                    put("ml", "NotoSansMalayalamUI-VF");
-                    put("mr", "NotoSansDevanagariUI-VF");
-                    put("my", "NotoSansMyanmarUI-Regular");
-                    put("ne", "NotoSansDevanagariUI-VF");
-                    put("or", "NotoSansOriya-Regular");
-                    put("pa", "NotoSansGurmukhiUI-VF");
-                    put("si", "NotoSansSinhalaUI-VF");
-                    put("ta", "NotoSansTamilUI-VF");
-                    put("te", "NotoSansTeluguUI-VF");
-                    put("th", "NotoSansThaiUI-Regular");
-                    put("ur", "NotoNaskhArabicUI-Regular");
-                    put("zh", "NotoSansCJK-Regular");
-                }
-            };
+            Map.ofEntries(
+                entry("am", "NotoSansEthiopic-VF"),
+                entry("ar", "NotoNaskhArabicUI-Regular"),
+                entry("as", "NotoSansBengaliUI-VF"),
+                entry("bn", "NotoSansBengaliUI-VF"),
+                entry("fa", "NotoNaskhArabicUI-Regular"),
+                entry("gu", "NotoSansGujaratiUI-Regular"),
+                entry("hi", "NotoSansDevanagariUI-VF"),
+                entry("hy", "NotoSansArmenian-VF"),
+                entry("iw", "NotoSansHebrew-Regular"),
+                entry("ja", "NotoSansCJK-Regular"),
+                entry("ka", "NotoSansGeorgian-VF"),
+                entry("ko", "NotoSansCJK-Regular"),
+                entry("km", "NotoSansKhmerUI-Regular"),
+                entry("kn", "NotoSansKannadaUI-VF"),
+                entry("lo", "NotoSansLaoUI-Regular"),
+                entry("ml", "NotoSansMalayalamUI-VF"),
+                entry("mr", "NotoSansDevanagariUI-VF"),
+                entry("my", "NotoSansMyanmarUI-Regular"),
+                entry("ne", "NotoSansDevanagariUI-VF"),
+                entry("or", "NotoSansOriya-Regular"),
+                entry("pa", "NotoSansGurmukhiUI-VF"),
+                entry("si", "NotoSansSinhalaUI-VF"),
+                entry("ta", "NotoSansTamilUI-VF"),
+                entry("te", "NotoSansTeluguUI-VF"),
+                entry("th", "NotoSansThaiUI-Regular"),
+                entry("ur", "NotoNaskhArabicUI-Regular"),
+                entry("zh", "NotoSansCJK-Regular"));
 
     // Languages that write from right to left.
     private static final Set<String> RTL_LANGUAGE =
-            new HashSet<String>() {
-                {
-                    add("ar"); // Arabic
-                    add("fa"); // Persian
-                    add("he"); // Hebrew
-                    add("iw"); // Hebrew
-                    add("ur"); // Urdu
-                }
-            };
+            Set.of(
+                "ar",  // Arabic
+                "fa",  // Persian
+                "he",  // Hebrew
+                "iw",  // Hebrew
+                "ur"); // Urdu
 
     /** Exception to indicate the failure to find the translated text strings. */
     public static class LocalizedStringNotFoundException extends Exception {
diff --git a/update_verifier/Android.bp b/update_verifier/Android.bp
index cb97bd1..26ff530 100644
--- a/update_verifier/Android.bp
+++ b/update_verifier/Android.bp
@@ -39,14 +39,6 @@
         "care_map.proto",
     ],
     proto: {type: "lite", canonical_path_from_root: false},
-    version: {
-        py2: {
-            enabled: true,
-        },
-        py3: {
-            enabled: true,
-        },
-    },
     visibility: [
         "//build/make/tools/releasetools:__subpackages__",
     ],
@@ -74,11 +66,12 @@
     ],
 
     whole_static_libs: [
-	"libsnapshot_snapuserd",
+        "libsnapshot_snapuserd",
     ],
 
     shared_libs: [
         "android.hardware.boot@1.0",
+        "libboot_control_client",
         "libbase",
         "libcutils",
         "libbinder",
@@ -118,6 +111,7 @@
         "libprotobuf-cpp-lite",
         "libbinder",
         "libutils",
+        "libboot_control_client",
     ],
 
     init_rc: [
@@ -143,12 +137,7 @@
     },
 
     version: {
-        py2: {
-            enabled: false,
-            embedded_launcher: false,
-        },
         py3: {
-            enabled: true,
             embedded_launcher: true,
         },
     },
diff --git a/update_verifier/update_verifier.cpp b/update_verifier/update_verifier.cpp
index 88fcfa5..a0160e2 100644
--- a/update_verifier/update_verifier.cpp
+++ b/update_verifier/update_verifier.cpp
@@ -52,6 +52,7 @@
 #include <future>
 #include <thread>
 
+#include <BootControlClient.h>
 #include <android-base/chrono_utils.h>
 #include <android-base/file.h>
 #include <android-base/logging.h>
@@ -59,7 +60,6 @@
 #include <android-base/properties.h>
 #include <android-base/strings.h>
 #include <android-base/unique_fd.h>
-#include <android/hardware/boot/1.0/IBootControl.h>
 #include <android/os/IVold.h>
 #include <binder/BinderService.h>
 #include <binder/Status.h>
@@ -67,11 +67,6 @@
 
 #include "care_map.pb.h"
 
-using android::sp;
-using android::hardware::boot::V1_0::IBootControl;
-using android::hardware::boot::V1_0::BoolResult;
-using android::hardware::boot::V1_0::CommandResult;
-
 // TODO(xunchang) remove the prefix and use a default path instead.
 constexpr const char* kDefaultCareMapPrefix = "/data/ota_package/care_map";
 
@@ -92,7 +87,7 @@
 // partition's integrity.
 std::map<std::string, std::string> UpdateVerifier::FindDmPartitions() {
   static constexpr auto DM_PATH_PREFIX = "/sys/block/";
-  dirent** namelist;
+  dirent** namelist = nullptr;
   int n = scandir(DM_PATH_PREFIX, &namelist, dm_name_filter, alphasort);
   if (n == -1) {
     PLOG(ERROR) << "Failed to scan dir " << DM_PATH_PREFIX;
@@ -155,7 +150,6 @@
       static constexpr size_t kBlockSize = 4096;
       std::vector<uint8_t> buf(1024 * kBlockSize);
 
-      size_t block_count = 0;
       for (const auto& [range_start, range_end] : group) {
         if (lseek64(fd.get(), static_cast<off64_t>(range_start) * kBlockSize, SEEK_SET) == -1) {
           PLOG(ERROR) << "lseek to " << range_start << " failed";
@@ -171,9 +165,7 @@
           }
           remain -= to_read;
         }
-        block_count += (range_end - range_start);
       }
-      LOG(INFO) << "Finished reading " << block_count << " blocks on " << dm_block_device;
       return true;
     };
 
@@ -184,8 +176,8 @@
   for (auto& t : threads) {
     ret = t.get() && ret;
   }
-  LOG(INFO) << "Finished reading blocks on " << dm_block_device << " with " << thread_num
-            << " threads.";
+  LOG(INFO) << "Finished reading blocks on partition " << partition_name << " @ " << dm_block_device
+            << " with " << thread_num << " threads.";
   return ret;
 }
 
@@ -329,18 +321,21 @@
     LOG(INFO) << "Started with arg " << i << ": " << argv[i];
   }
 
-  sp<IBootControl> module = IBootControl::getService();
+  const auto module = android::hal::BootControlClient::WaitForService();
   if (module == nullptr) {
     LOG(ERROR) << "Error getting bootctrl module.";
     return reboot_device();
   }
 
-  uint32_t current_slot = module->getCurrentSlot();
-  BoolResult is_successful = module->isSlotMarkedSuccessful(current_slot);
-  LOG(INFO) << "Booting slot " << current_slot << ": isSlotMarkedSuccessful="
-            << static_cast<int32_t>(is_successful);
-
-  if (is_successful == BoolResult::FALSE) {
+  uint32_t current_slot = module->GetCurrentSlot();
+  const auto is_successful = module->IsSlotMarkedSuccessful(current_slot);
+  if (!is_successful.has_value()) {
+    LOG(INFO) << "Booting slot " << current_slot << " failed";
+  } else {
+    LOG(INFO) << "Booting slot " << current_slot
+              << ": isSlotMarkedSuccessful=" << is_successful.value();
+  }
+  if (is_successful.has_value() && !is_successful.value()) {
     // The current slot has not booted successfully.
 
     bool skip_verification = false;
@@ -386,8 +381,7 @@
     }
 
     if (!supports_checkpoint) {
-      CommandResult cr;
-      module->markBootSuccessful([&cr](CommandResult result) { cr = result; });
+      const auto cr = module->MarkBootSuccessful();
       if (!cr.success) {
         LOG(ERROR) << "Error marking booted successfully: " << cr.errMsg;
         return reboot_device();