Improve atomiticy of update checkpointing

Current check point works by writing different prefs to different files
under a pending directory, and rename the pending directory to actual pref
directory afterwards to achieve atomicity. It has two pitfalls:

1. Before the rename() call, existing prefs dir must be rm -rf'ed , this
   deletion process isn't atomic. If device rebooted during rm -rf, we
   will end up with a partially deleted old pref.

2. fsync() on the parent directory is needed after rename()

This CL addresses both issues. For #1, we rename() the old pref dir to a
tmp dir first, and then rm -rf the tmp dir. Upon device restart, if the
current prefs dir is empty, we can simply rename() the pending directory
to actual pref directory.

Test: th
Bug: 295252766
Change-Id: Ic671a18245986c579b51d7443c3e8c10e206c448
diff --git a/common/utils.cc b/common/utils.cc
index 15ee05c..f0c045f 100644
--- a/common/utils.cc
+++ b/common/utils.cc
@@ -412,6 +412,17 @@
   return true;
 }
 
+bool DeleteDirectory(const char* dirname) {
+  const std::string tmpdir = std::string(dirname) + "_deleted";
+  std::filesystem::remove_all(tmpdir);
+  if (rename(dirname, tmpdir.c_str()) != 0) {
+    PLOG(ERROR) << "Failed to rename " << dirname << " to " << tmpdir;
+    return false;
+  }
+  std::filesystem::remove_all(tmpdir);
+  return true;
+}
+
 bool FsyncDirectory(const char* dirname) {
   android::base::unique_fd fd(
       TEMP_FAILURE_RETRY(open(dirname, O_RDONLY | O_CLOEXEC)));