Consolidate the codes that handle reboot/shutdown.

Test: Choose `Reboot system now`, `Power off`, `Reboot to bootloader`
      from recovery UI respectively.
Test: `adb reboot recovery` while under sideload mode.
Change-Id: I0f3d55b80b472178ea4f6970b29cd9df0778b639
diff --git a/otautil/include/otautil/sysutil.h b/otautil/include/otautil/sysutil.h
index 692a99e..48e9011 100644
--- a/otautil/include/otautil/sysutil.h
+++ b/otautil/include/otautil/sysutil.h
@@ -14,12 +14,12 @@
  * limitations under the License.
  */
 
-#ifndef _OTAUTIL_SYSUTIL
-#define _OTAUTIL_SYSUTIL
+#pragma once
 
 #include <sys/types.h>
 
 #include <string>
+#include <string_view>
 #include <vector>
 
 #include "rangeset.h"
@@ -101,13 +101,14 @@
   std::vector<MappedRange> ranges_;
 };
 
-// Wrapper function to trigger a reboot, by additionally handling quiescent reboot mode. The
-// command should start with "reboot," (e.g. "reboot,bootloader" or "reboot,").
-bool reboot(const std::string& command);
+// Reboots the device into the specified target, by additionally handling quiescent reboot mode.
+// 'target' can be an empty string, which indicates booting into Android.
+bool Reboot(std::string_view target);
+
+// Triggers a shutdown.
+bool Shutdown();
 
 // Returns a null-terminated char* array, where the elements point to the C-strings in the given
 // vector, plus an additional nullptr at the end. This is a helper function that facilitates
 // calling C functions (such as getopt(3)) that expect an array of C-strings.
 std::vector<char*> StringVectorToNullTerminatedArray(const std::vector<std::string>& args);
-
-#endif  // _OTAUTIL_SYSUTIL
diff --git a/otautil/sysutil.cpp b/otautil/sysutil.cpp
index 8366fa0..2b48618 100644
--- a/otautil/sysutil.cpp
+++ b/otautil/sysutil.cpp
@@ -214,14 +214,21 @@
   ranges_.clear();
 }
 
-bool reboot(const std::string& command) {
-  std::string cmd = command;
-  if (android::base::GetBoolProperty("ro.boot.quiescent", false)) {
+bool Reboot(std::string_view target) {
+  std::string cmd = "reboot," + std::string(target);
+  // Honor the quiescent mode if applicable.
+  if (target != "bootloader" && target != "fastboot" &&
+      android::base::GetBoolProperty("ro.boot.quiescent", false)) {
     cmd += ",quiescent";
   }
   return android::base::SetProperty(ANDROID_RB_PROPERTY, cmd);
 }
 
+bool Shutdown() {
+  // "shutdown" doesn't need a "reason" arg nor a comma.
+  return android::base::SetProperty(ANDROID_RB_PROPERTY, "shutdown");
+}
+
 std::vector<char*> StringVectorToNullTerminatedArray(const std::vector<std::string>& args) {
   std::vector<char*> result(args.size());
   std::transform(args.cbegin(), args.cend(), result.begin(),
diff --git a/recovery.cpp b/recovery.cpp
index 5fc673e..42dad41 100644
--- a/recovery.cpp
+++ b/recovery.cpp
@@ -895,8 +895,8 @@
           // Print retry count on screen.
           ui->Print("Retry attempt %d\n", retry_count);
 
-          // Reboot and retry the update
-          if (!reboot("reboot,recovery")) {
+          // Reboot back into recovery to retry the update.
+          if (!Reboot("recovery")) {
             ui->Print("Reboot failed\n");
           } else {
             while (true) {
diff --git a/recovery_main.cpp b/recovery_main.cpp
index 6e69b70..b999505 100644
--- a/recovery_main.cpp
+++ b/recovery_main.cpp
@@ -41,7 +41,6 @@
 #include <android-base/strings.h>
 #include <android-base/unique_fd.h>
 #include <bootloader_message/bootloader_message.h>
-#include <cutils/android_reboot.h>
 #include <cutils/sockets.h>
 #include <private/android_logger.h> /* private pmsg functions */
 #include <selinux/android.h>
@@ -471,27 +470,26 @@
     switch (ret) {
       case Device::SHUTDOWN:
         ui->Print("Shutting down...\n");
-        // TODO: Move all the reboots to reboot(), which should conditionally set quiescent flag.
-        android::base::SetProperty(ANDROID_RB_PROPERTY, "shutdown,");
+        Shutdown();
         break;
 
       case Device::REBOOT_BOOTLOADER:
         ui->Print("Rebooting to bootloader...\n");
-        android::base::SetProperty(ANDROID_RB_PROPERTY, "reboot,bootloader");
+        Reboot("bootloader");
         break;
 
       case Device::REBOOT_FASTBOOT:
         ui->Print("Rebooting to recovery/fastboot...\n");
-        android::base::SetProperty(ANDROID_RB_PROPERTY, "reboot,fastboot");
+        Reboot("fastboot");
         break;
 
       case Device::REBOOT_RECOVERY:
         ui->Print("Rebooting to recovery...\n");
-        reboot("reboot,recovery");
+        Reboot("recovery");
         break;
 
       case Device::REBOOT_RESCUE: {
-        // Not using `reboot("reboot,rescue")`, as it requires matching support in kernel and/or
+        // Not using `Reboot("rescue")`, as it requires matching support in kernel and/or
         // bootloader.
         bootloader_message boot = {};
         strlcpy(boot.command, "boot-rescue", sizeof(boot.command));
@@ -502,14 +500,14 @@
           continue;
         }
         ui->Print("Rebooting to recovery/rescue...\n");
-        reboot("reboot,recovery");
+        Reboot("recovery");
         break;
       }
 
       case Device::ENTER_FASTBOOT:
         if (logical_partitions_mapped()) {
           ui->Print("Partitions may be mounted - rebooting to enter fastboot.");
-          android::base::SetProperty(ANDROID_RB_PROPERTY, "reboot,fastboot");
+          Reboot("fastboot");
         } else {
           LOG(INFO) << "Entering fastboot";
           fastboot = true;
@@ -523,7 +521,7 @@
 
       default:
         ui->Print("Rebooting...\n");
-        reboot("reboot,");
+        Reboot("");
         break;
     }
   }
diff --git a/recovery_ui/ui.cpp b/recovery_ui/ui.cpp
index b7107ff..7ea9307 100644
--- a/recovery_ui/ui.cpp
+++ b/recovery_ui/ui.cpp
@@ -375,7 +375,7 @@
 
       case RecoveryUI::REBOOT:
         if (reboot_enabled) {
-          reboot("reboot,");
+          Reboot("");
           while (true) {
             pause();
           }
diff --git a/updater/install.cpp b/updater/install.cpp
index 20a204a..8eba64f 100644
--- a/updater/install.cpp
+++ b/updater/install.cpp
@@ -778,7 +778,7 @@
     return StringValue("");
   }
 
-  reboot("reboot," + property);
+  Reboot(property);
 
   sleep(5);
   return ErrorAbort(state, kRebootFailure, "%s() failed to reboot", name);