Enhance the fault tolerance of GSID installation

The gsid may function abnormally when an installation get interrupted.

case 1.
$ gsi_tool install

 ... use ctrl+C to stop ...

$ gsi_tool wipe
Could not remove GSI install.

case 2
When it's interrupted. The installer destructor does not have the
the chance to run therefore it can be a resource leak because the
backing files, e.g. system_gsi and userdata_gsi are not released.
Neither can they be enabled because the IsGsiInstalled() == false.

This CL fixes cases above by making a integrity model based on
IsGsiInstalled() as an atomic switch, e.g.

if (IsGsiInstalled()) {
    The installation must be complete and the enableGsi() must work.
} else {
    All resources that have been allocated must be cleaned up.
    a. Clean up methods and command must work.
    b. runStartup method must do the clean up.
}

All corresponding changes are based on this model.

Bug: 140014207
Test: \
 1. gsi_tool install & reboot
 2. gsi_tool install & ctrl+C & gsi_tool status & gsi_tool wipe & gsi_tool status
 3. gsi_tool install & ctrl+C & gsi_tool status & reboot & gsi_tool status

Change-Id: I0dcf043d65b50f0dd82eac1f428a295e94c81812
diff --git a/gsi_service.cpp b/gsi_service.cpp
index 0f43f8b..5c9f90b 100644
--- a/gsi_service.cpp
+++ b/gsi_service.cpp
@@ -225,14 +225,7 @@
     ENFORCE_SYSTEM_OR_SHELL;
     std::lock_guard<std::mutex> guard(parent_->lock());
 
-    // Just in case an install was left hanging.
-    std::string install_dir;
-    if (installer_) {
-        install_dir = installer_->install_dir();
-    } else {
-        install_dir = GetInstalledImageDir();
-    }
-
+    std::string install_dir = GetActiveInstalledImageDir();
     if (IsGsiRunning()) {
         // Can't remove gsi files while running.
         *_aidl_return = UninstallGsi();
@@ -290,9 +283,7 @@
     ENFORCE_SYSTEM;
     std::lock_guard<std::mutex> guard(parent_->lock());
 
-    if (IsGsiInstalled()) {
-        *_aidl_return = GetInstalledImageDir();
-    }
+    *_aidl_return = GetActiveInstalledImageDir();
     return binder::Status::ok();
 }
 
@@ -305,8 +296,8 @@
         return binder::Status::ok();
     }
 
-    auto installer = std::make_unique<GsiInstaller>(this, GetInstalledImageDir());
-    *_aidl_return = installer->WipeUserdata();
+    std::string install_dir = GetActiveInstalledImageDir();
+    *_aidl_return = GsiInstaller::WipeWritable(install_dir, "userdata");
 
     return binder::Status::ok();
 }
@@ -550,6 +541,15 @@
     return INSTALL_OK;
 }
 
+std::string GsiService::GetActiveInstalledImageDir() {
+    // Just in case an install was left hanging.
+    if (installer_) {
+        return installer_->install_dir();
+    } else {
+        return GetInstalledImageDir();
+    }
+}
+
 std::string GsiService::GetInstalledImageDir() {
     // If there's no install left, just return /data/gsi since that's where
     // installs go by default.
@@ -576,8 +576,7 @@
         return INSTALL_ERROR_GENERIC;
     }
 
-    installer_ = std::make_unique<GsiInstaller>(this, GetInstalledImageDir());
-    return installer_->ReenableGsi(one_shot);
+    return GsiInstaller::ReenableGsi(one_shot);
 }
 
 bool GsiService::RemoveGsiFiles(const std::string& install_dir, bool wipeUserdata) {
@@ -587,9 +586,11 @@
         for (auto&& image : images) {
             if (!android::base::EndsWith(image, "_gsi")) {
                 continue;
-            } else if (!android::base::StartsWith(image, "userdata")) {
-                ok &= manager->DeleteBackingImage(image);
-            } else if (wipeUserdata) {
+            }
+            if (manager->IsImageMapped(image)) {
+                ok &= manager->UnmapImageDevice(image);
+            }
+            if (!android::base::StartsWith(image, "userdata") || wipeUserdata) {
                 ok &= manager->DeleteBackingImage(image);
             }
         }
@@ -626,8 +627,16 @@
     return true;
 }
 
+void GsiService::CleanCorruptedInstallation() {
+    auto install_dir = GetInstalledImageDir();
+    if (!RemoveGsiFiles(install_dir, true)) {
+        LOG(ERROR) << "Failed to CleanCorruptedInstallation on " << install_dir;
+    }
+}
+
 void GsiService::RunStartupTasks() {
     if (!IsGsiInstalled()) {
+        CleanCorruptedInstallation();
         return;
     }