DO NOT MERGE - Merge pi-dev@5234907 into stage-aosp-master

Bug: 120848293
Change-Id: I4ac749387dca39a09e96ea5588b651d06728033b
diff --git a/Android.bp b/Android.bp
index 41075d2..afa0337 100644
--- a/Android.bp
+++ b/Android.bp
@@ -45,6 +45,7 @@
     static_libs: [
         "libminui",
         "libotautil",
+        "libfstab",
     ],
 
     shared_libs: [
@@ -157,6 +158,7 @@
         "libhealthhalutils",
         "libvintf_recovery",
         "libvintf",
+        "libfstab",
     ],
 }
 
@@ -260,6 +262,7 @@
 
     static_libs: [
         "libotautil",
+        "libfstab",
     ],
 
     init_rc: [
@@ -287,6 +290,7 @@
 
     static_libs: [
         "libotautil",
+        "libfstab",
     ],
 
     init_rc: [
diff --git a/Android.mk b/Android.mk
index 429c52d..9806d10 100644
--- a/Android.mk
+++ b/Android.mk
@@ -63,14 +63,6 @@
 endif
 endif
 
-# e2fsck is needed for adb remount -R.
-ifeq ($(BOARD_EXT4_SHARE_DUP_BLOCKS),true)
-ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT)))
-LOCAL_REQUIRED_MODULES += \
-    e2fsck_static
-endif
-endif
-
 # On A/B devices recovery-persist reads the recovery related file from the persist storage and
 # copies them into /data/misc/recovery. Then, for both A/B and non-A/B devices, recovery-persist
 # parses the last_install file and reports the embedded update metrics. Also, the last_install file
diff --git a/bootloader_message/bootloader_message.cpp b/bootloader_message/bootloader_message.cpp
index b933cbf..8c1d63b 100644
--- a/bootloader_message/bootloader_message.cpp
+++ b/bootloader_message/bootloader_message.cpp
@@ -29,6 +29,9 @@
 #include <android-base/unique_fd.h>
 #include <fstab/fstab.h>
 
+using android::fs_mgr::Fstab;
+using android::fs_mgr::ReadDefaultFstab;
+
 static std::string get_misc_blk_device(std::string* err) {
   Fstab fstab;
   if (!ReadDefaultFstab(&fstab)) {
diff --git a/recovery-persist.cpp b/recovery-persist.cpp
index ebb42d2..e2a6699 100644
--- a/recovery-persist.cpp
+++ b/recovery-persist.cpp
@@ -158,7 +158,7 @@
       // Collects and reports the non-a/b update metrics from last_install; and removes the file
       // to avoid duplicate report.
       report_metrics_from_last_install(LAST_INSTALL_FILE_IN_CACHE);
-      if (unlink(LAST_INSTALL_FILE_IN_CACHE) == -1) {
+      if (access(LAST_INSTALL_FILE_IN_CACHE, F_OK) && unlink(LAST_INSTALL_FILE_IN_CACHE) == -1) {
         PLOG(ERROR) << "Failed to unlink " << LAST_INSTALL_FILE_IN_CACHE;
       }
 
@@ -182,7 +182,7 @@
     // /data/misc/recovery from pmsg. Looks for the sideload history only.
     if (!has_cache) {
       report_metrics_from_last_install(LAST_INSTALL_FILE);
-      if (unlink(LAST_INSTALL_FILE) == -1) {
+      if (access(LAST_INSTALL_FILE, F_OK) && unlink(LAST_INSTALL_FILE) == -1) {
         PLOG(ERROR) << "Failed to unlink " << LAST_INSTALL_FILE;
       }
     }
diff --git a/roots.cpp b/roots.cpp
index 290be47..7a922b8 100644
--- a/roots.cpp
+++ b/roots.cpp
@@ -45,6 +45,10 @@
 #include "otautil/mounts.h"
 #include "otautil/sysutil.h"
 
+using android::fs_mgr::Fstab;
+using android::fs_mgr::FstabEntry;
+using android::fs_mgr::ReadDefaultFstab;
+
 static Fstab fstab;
 
 extern struct selabel_handle* sehandle;
@@ -69,10 +73,7 @@
 }
 
 Volume* volume_for_mount_point(const std::string& mount_point) {
-  auto it = std::find_if(fstab.begin(), fstab.end(), [&mount_point](const auto& entry) {
-    return entry.mount_point == mount_point;
-  });
-  return it == fstab.end() ? nullptr : &*it;
+  return android::fs_mgr::GetEntryForMountPoint(&fstab, mount_point);
 }
 
 // Mount the volume specified by path at the given mount_point.
diff --git a/roots.h b/roots.h
index 341f905..7b031a1 100644
--- a/roots.h
+++ b/roots.h
@@ -19,7 +19,9 @@
 
 #include <string>
 
-typedef struct FstabEntry Volume;
+#include <fstab/fstab.h>
+
+using Volume = android::fs_mgr::FstabEntry;
 
 // Load and parse volume data from /etc/recovery.fstab.
 void load_volume_table();
diff --git a/screen_ui.cpp b/screen_ui.cpp
index 7fa41c4..6c00a22 100644
--- a/screen_ui.cpp
+++ b/screen_ui.cpp
@@ -278,12 +278,12 @@
 bool GraphicMenu::ValidateGraphicSurface(size_t max_width, size_t max_height, int y,
                                          const GRSurface* surface) {
   if (!surface) {
-    fprintf(stderr, "Graphic surface can not be null");
+    fprintf(stderr, "Graphic surface can not be null\n");
     return false;
   }
 
   if (surface->pixel_bytes != 1 || surface->width != surface->row_bytes) {
-    fprintf(stderr, "Invalid graphic surface, pixel bytes: %zu, width: %zu row_bytes: %zu",
+    fprintf(stderr, "Invalid graphic surface, pixel bytes: %zu, width: %zu row_bytes: %zu\n",
             surface->pixel_bytes, surface->width, surface->row_bytes);
     return false;
   }
diff --git a/tests/Android.bp b/tests/Android.bp
index 1d6a056..898ed7d 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -29,6 +29,7 @@
         "libcutils",
         "liblog",
         "libpng",
+        "libprocessgroup",
         "libselinux",
         "libz",
         "libziparchive",
diff --git a/tests/component/install_test.cpp b/tests/component/install_test.cpp
index 27a01cb..47a5471 100644
--- a/tests/component/install_test.cpp
+++ b/tests/component/install_test.cpp
@@ -439,8 +439,8 @@
 
   std::vector<std::string> serial_numbers;
   // Creates a dummy serial number string.
-  for (size_t c = 'a'; c <= 'z'; c++) {
-    serial_numbers.emplace_back(c, serialno.size());
+  for (char c = 'a'; c <= 'z'; c++) {
+    serial_numbers.emplace_back(serialno.size(), c);
   }
 
   // No matched serialno found.
diff --git a/uncrypt/uncrypt.cpp b/uncrypt/uncrypt.cpp
index 75595ac..f1f4f69 100644
--- a/uncrypt/uncrypt.cpp
+++ b/uncrypt/uncrypt.cpp
@@ -119,6 +119,9 @@
 
 #include "otautil/error_code.h"
 
+using android::fs_mgr::Fstab;
+using android::fs_mgr::ReadDefaultFstab;
+
 static constexpr int WINDOW_SIZE = 5;
 static constexpr int FIBMAP_RETRY_LIMIT = 3;
 
diff --git a/update_verifier/Android.bp b/update_verifier/Android.bp
index 1b84619..f656713 100644
--- a/update_verifier/Android.bp
+++ b/update_verifier/Android.bp
@@ -42,12 +42,15 @@
 
     static_libs: [
         "libotautil",
+        "libvold_binder",
     ],
 
     shared_libs: [
         "android.hardware.boot@1.0",
         "libbase",
         "libcutils",
+        "libbinder",
+        "libutils",
     ],
 
     proto: {
@@ -70,6 +73,7 @@
     static_libs: [
         "libupdate_verifier",
         "libotautil",
+        "libvold_binder",
     ],
 
     shared_libs: [
@@ -80,6 +84,7 @@
         "libhidlbase",
         "liblog",
         "libprotobuf-cpp-lite",
+        "libbinder",
         "libutils",
     ],
 
diff --git a/update_verifier/update_verifier.cpp b/update_verifier/update_verifier.cpp
index d7cd061..5e5eac7 100644
--- a/update_verifier/update_verifier.cpp
+++ b/update_verifier/update_verifier.cpp
@@ -38,6 +38,7 @@
  */
 
 #include "update_verifier/update_verifier.h"
+#include <android/os/IVold.h>
 
 #include <dirent.h>
 #include <errno.h>
@@ -56,6 +57,8 @@
 #include <android-base/strings.h>
 #include <android-base/unique_fd.h>
 #include <android/hardware/boot/1.0/IBootControl.h>
+#include <binder/BinderService.h>
+#include <binder/Status.h>
 #include <cutils/android_reboot.h>
 
 #include "care_map.pb.h"
@@ -376,13 +379,30 @@
       }
     }
 
-    CommandResult cr;
-    module->markBootSuccessful([&cr](CommandResult result) { cr = result; });
-    if (!cr.success) {
-      LOG(ERROR) << "Error marking booted successfully: " << cr.errMsg;
-      return reboot_device();
+    bool supports_checkpoint = false;
+    auto sm = android::defaultServiceManager();
+    android::sp<android::IBinder> binder = sm->getService(android::String16("vold"));
+    if (binder) {
+      auto vold = android::interface_cast<android::os::IVold>(binder);
+      android::binder::Status status = vold->supportsCheckpoint(&supports_checkpoint);
+      if (!status.isOk()) {
+        LOG(ERROR) << "Failed to check if checkpoints supported. Continuing";
+      }
+    } else {
+      LOG(ERROR) << "Failed to obtain vold Binder. Continuing";
     }
-    LOG(INFO) << "Marked slot " << current_slot << " as booted successfully.";
+
+    if (!supports_checkpoint) {
+      CommandResult cr;
+      module->markBootSuccessful([&cr](CommandResult result) { cr = result; });
+      if (!cr.success) {
+        LOG(ERROR) << "Error marking booted successfully: " << cr.errMsg;
+        return reboot_device();
+      }
+      LOG(INFO) << "Marked slot " << current_slot << " as booted successfully.";
+    } else {
+      LOG(INFO) << "Deferred marking slot " << current_slot << " as booted successfully.";
+    }
   }
 
   LOG(INFO) << "Leaving update_verifier.";
diff --git a/updater/blockimg.cpp b/updater/blockimg.cpp
index 6e5d5bb..07c3c7b 100644
--- a/updater/blockimg.cpp
+++ b/updater/blockimg.cpp
@@ -1525,7 +1525,7 @@
 
   // Starts the hash_tree computation.
   HashTreeBuilder builder(BLOCKSIZE, hash_function);
-  if (!builder.Initialize(source_ranges.blocks() * BLOCKSIZE, salt)) {
+  if (!builder.Initialize(static_cast<int64_t>(source_ranges.blocks()) * BLOCKSIZE, salt)) {
     LOG(ERROR) << "Failed to initialize hash tree computation, source " << source_ranges.ToString()
                << ", salt " << salt_hex;
     return -1;
@@ -1915,8 +1915,10 @@
 
       const char* partition = strrchr(blockdev_filename->data.c_str(), '/');
       if (partition != nullptr && *(partition + 1) != 0) {
-        fprintf(cmd_pipe, "log bytes_written_%s: %zu\n", partition + 1, params.written * BLOCKSIZE);
-        fprintf(cmd_pipe, "log bytes_stashed_%s: %zu\n", partition + 1, params.stashed * BLOCKSIZE);
+        fprintf(cmd_pipe, "log bytes_written_%s: %" PRIu64 "\n", partition + 1,
+                static_cast<uint64_t>(params.written) * BLOCKSIZE);
+        fprintf(cmd_pipe, "log bytes_stashed_%s: %" PRIu64 "\n", partition + 1,
+                static_cast<uint64_t>(params.stashed) * BLOCKSIZE);
         fflush(cmd_pipe);
       }
       // Delete stash only after successfully completing the update, as it may contain blocks needed