fastboot: Automatically reboot to userspace fastboot.

In order to flash logical partitions, "flashall" must be run against
userspace fastboot. When the bootloader supports the "reboot-fastboot"
command, we now attempt to automatically reboot into userspace fastboot.

We do this by closing the transport, sleeping for one second, and then
polling for a new connection until one is available. FastBootDriver is
then assigned the new transport.

Bug: 78793464
Test: fastboot flashall on device with logical partitions, while booted
      into bootloader fastboot

Change-Id: I6949871b93ab5e352784cabe0963c6ecfc0af36d
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index 4a8ee33..6cf544f 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -246,13 +246,8 @@
 // The returned Transport is a singleton, so multiple calls to this function will return the same
 // object, and the caller should not attempt to delete the returned Transport.
 static Transport* open_device() {
-    static Transport* transport = nullptr;
     bool announce = true;
 
-    if (transport != nullptr) {
-        return transport;
-    }
-
     Socket::Protocol protocol = Socket::Protocol::kTcp;
     std::string host;
     int port = 0;
@@ -277,6 +272,7 @@
         }
     }
 
+    Transport* transport = nullptr;
     while (true) {
         if (!host.empty()) {
             std::string error;
@@ -1179,6 +1175,17 @@
     return fb_getvar("is-logical:" + partition, &value) && value == "yes";
 }
 
+static void reboot_to_userspace_fastboot() {
+    if (!fb_reboot_to_userspace()) {
+        die("Must reboot to userspace fastboot to flash logical partitions");
+    }
+
+    // Give the current connection time to close.
+    std::this_thread::sleep_for(std::chrono::milliseconds(1000));
+
+    fb_reinit(open_device());
+}
+
 static void update_super_partition(bool force_wipe) {
     if (!if_partition_exists("super", "")) {
         return;
@@ -1189,7 +1196,7 @@
     }
 
     if (!is_userspace_fastboot()) {
-        die("Must have userspace fastboot to flash logical partitions");
+        reboot_to_userspace_fastboot();
     }
 
     int fd = open(image.c_str(), O_RDONLY);