gsid: Make enableGsi() idempotent am: d646d79c4f am: 448be92d3c am: db6cd05741 am: 1f83bd3f4e am: a485064567

Original change: https://android-review.googlesource.com/c/platform/system/gsid/+/2054425

Change-Id: I184b099bfb68b5af551fda3ce4a2f44849ef8c45
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/aidl/android/gsi/IGsiService.aidl b/aidl/android/gsi/IGsiService.aidl
index c889987..3b5d6c0 100644
--- a/aidl/android/gsi/IGsiService.aidl
+++ b/aidl/android/gsi/IGsiService.aidl
@@ -74,8 +74,10 @@
     boolean commitGsiChunkFromAshmem(long bytes);
 
     /**
-     * Complete a GSI installation and mark it as bootable. The caller is
-     * responsible for rebooting the device as soon as possible.
+     * Mark a completed DSU installation as bootable. The caller is responsible
+     * for rebooting the device as soon as possible.
+     *
+     * Could leave the installation in "disabled" state if failure.
      *
      * @param oneShot       If true, the GSI will boot once and then disable itself.
      *                      It can still be re-enabled again later with setGsiBootable.
diff --git a/gsi_service.cpp b/gsi_service.cpp
index 122bbf6..3392a1d 100644
--- a/gsi_service.cpp
+++ b/gsi_service.cpp
@@ -314,12 +314,10 @@
 
 binder::Status GsiService::enableGsiAsync(bool one_shot, const std::string& dsuSlot,
                                           const sp<IGsiServiceCallback>& resultCallback) {
-    int result;
-    auto status = enableGsi(one_shot, dsuSlot, &result);
-    if (!status.isOk()) {
-        LOG(ERROR) << "Could not enableGsi: " << status.exceptionMessage().string();
-        result = IGsiService::INSTALL_ERROR_GENERIC;
-    }
+    ENFORCE_SYSTEM_OR_SHELL;
+    std::lock_guard<std::mutex> guard(lock_);
+
+    const auto result = EnableGsi(one_shot, dsuSlot);
     resultCallback->onResult(result);
     return binder::Status::ok();
 }
@@ -328,20 +326,7 @@
     ENFORCE_SYSTEM_OR_SHELL;
     std::lock_guard<std::mutex> guard(lock_);
 
-    if (!WriteStringToFile(dsuSlot, kDsuActiveFile)) {
-        PLOG(ERROR) << "write failed: " << GetDsuSlot(install_dir_);
-        *_aidl_return = INSTALL_ERROR_GENERIC;
-        return binder::Status::ok();
-    }
-    RestoreconMetadataFiles();
-
-    if (installer_) {
-        LOG(ERROR) << "cannot enable an ongoing installation, was closeInstall() called?";
-        *_aidl_return = IGsiService::INSTALL_ERROR_GENERIC;
-        return binder::Status::ok();
-    }
-
-    *_aidl_return = ReenableGsi(one_shot);
+    *_aidl_return = EnableGsi(one_shot, dsuSlot);
     return binder::Status::ok();
 }
 
@@ -946,26 +931,6 @@
     return kDefaultDsuImageFolder;
 }
 
-int GsiService::ReenableGsi(bool one_shot) {
-    if (!android::gsi::IsGsiInstalled()) {
-        LOG(ERROR) << "no gsi installed - cannot re-enable";
-        return INSTALL_ERROR_GENERIC;
-    }
-    std::string boot_key;
-    if (!GetInstallStatus(&boot_key)) {
-        PLOG(ERROR) << "read " << kDsuInstallStatusFile;
-        return INSTALL_ERROR_GENERIC;
-    }
-    if (boot_key != kInstallStatusDisabled) {
-        LOG(ERROR) << "GSI is not currently disabled";
-        return INSTALL_ERROR_GENERIC;
-    }
-    if (!SetBootMode(one_shot) || !ResetBootAttemptCounter()) {
-        return IGsiService::INSTALL_ERROR_GENERIC;
-    }
-    return IGsiService::INSTALL_OK;
-}
-
 static android::sp<android::os::IVold> GetVoldService() {
     return android::waitForService<android::os::IVold>(android::String16("vold"));
 }
@@ -1021,6 +986,35 @@
     return ok;
 }
 
+int GsiService::EnableGsi(bool one_shot, const std::string& dsu_slot) {
+    if (!android::gsi::IsGsiInstalled()) {
+        LOG(ERROR) << "no gsi installed - cannot enable";
+        return IGsiService::INSTALL_ERROR_GENERIC;
+    }
+    if (installer_) {
+        LOG(ERROR) << "cannot enable an ongoing installation, was closeInstall() called?";
+        return IGsiService::INSTALL_ERROR_GENERIC;
+    }
+
+    if (!DisableGsi()) {
+        PLOG(ERROR) << "cannot write DSU status file";
+        return IGsiService::INSTALL_ERROR_GENERIC;
+    }
+    if (!SetBootMode(one_shot)) {
+        return IGsiService::INSTALL_ERROR_GENERIC;
+    }
+    if (!ResetBootAttemptCounter()) {
+        return IGsiService::INSTALL_ERROR_GENERIC;
+    }
+
+    if (!WriteStringToFile(dsu_slot, kDsuActiveFile)) {
+        PLOG(ERROR) << "cannot write active DSU slot (" << dsu_slot << "): " << kDsuActiveFile;
+        return IGsiService::INSTALL_ERROR_GENERIC;
+    }
+    RestoreconMetadataFiles();
+    return IGsiService::INSTALL_OK;
+}
+
 bool GsiService::DisableGsiInstall() {
     if (!android::gsi::IsGsiInstalled()) {
         LOG(ERROR) << "cannot disable gsi install - no install detected";
diff --git a/gsi_service.h b/gsi_service.h
index 0ec7620..c50c101 100644
--- a/gsi_service.h
+++ b/gsi_service.h
@@ -92,8 +92,8 @@
 
     GsiService();
     static int ValidateInstallParams(std::string& install_dir);
+    int EnableGsi(bool one_shot, const std::string& dsu_slot);
     bool DisableGsiInstall();
-    int ReenableGsi(bool one_shot);
     static void CleanCorruptedInstallation();
     static int SaveInstallation(const std::string&);
     static bool IsInstallationComplete(const std::string&);