Query the fastbootd status only when needed

Only check for it when explicitly needed due to device
calls. Otherwise assume bootloader.

Test: unit tests
Bug: 148109220
Change-Id: Iffce3a071797fb28cf471ea76d941620a3977015
diff --git a/device_build_interfaces/com/android/tradefed/device/IDeviceStateMonitor.java b/device_build_interfaces/com/android/tradefed/device/IDeviceStateMonitor.java
index 76faec6..5ad0364 100644
--- a/device_build_interfaces/com/android/tradefed/device/IDeviceStateMonitor.java
+++ b/device_build_interfaces/com/android/tradefed/device/IDeviceStateMonitor.java
@@ -96,10 +96,11 @@
     /**
      * Waits for the device to be in fastbootd.
      *
+     * @param fastbootPath the path of the fastboot binary to use.
      * @param waitTime the maximum time in ms to wait
      * @return <code>true</code> if device is in fastbootd before time expires
      */
-    public boolean waitForDeviceFastbootd(long waitTime);
+    public boolean waitForDeviceFastbootd(String fastbootPath, long waitTime);
 
     /**
      * Waits for device bootloader state to be refreshed
diff --git a/src/com/android/tradefed/device/DeviceManager.java b/src/com/android/tradefed/device/DeviceManager.java
index ed7b0da..b8ec979 100644
--- a/src/com/android/tradefed/device/DeviceManager.java
+++ b/src/com/android/tradefed/device/DeviceManager.java
@@ -566,21 +566,12 @@
         }
     }
 
+    /** Representation of a device in Fastboot mode. */
     public static class FastbootDevice extends StubDevice {
 
-        private boolean mIsFastbootd = false;
-
         public FastbootDevice(String serial) {
             super(serial, false);
         }
-
-        public void setFastbootd(boolean isFastbootd) {
-            mIsFastbootd = isFastbootd;
-        }
-
-        public boolean isFastbootD() {
-            return mIsFastbootd;
-        }
     }
 
     /**
diff --git a/src/com/android/tradefed/device/FastbootHelper.java b/src/com/android/tradefed/device/FastbootHelper.java
index 4d5bc6a..01bc927 100644
--- a/src/com/android/tradefed/device/FastbootHelper.java
+++ b/src/com/android/tradefed/device/FastbootHelper.java
@@ -21,9 +21,7 @@
 import com.android.tradefed.util.CommandStatus;
 import com.android.tradefed.util.IRunUtil;
 
-import java.util.HashMap;
 import java.util.HashSet;
-import java.util.Map;
 import java.util.Set;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -96,32 +94,6 @@
     }
 
     /**
-     * Returns a map of device serials and whether they are in fastbootd mode or not.
-     *
-     * @return a Map of serial in bootloader or fastbootd, the boolean is true if in fastbootd
-     */
-    public Map<String, Boolean> getBootloaderAndFastbootdDevices() {
-        Map<String, Boolean> devices = new HashMap<>();
-        Set<String> fastbootDevices = getDevices();
-        for (String serial : fastbootDevices) {
-            CommandResult result =
-                    mRunUtil.runTimedCmdSilently(
-                            FASTBOOT_CMD_TIMEOUT,
-                            mFastbootPath,
-                            "-s",
-                            serial,
-                            "getvar",
-                            "is-userspace");
-            if (result.getStderr().contains("is-userspace: yes")) {
-                devices.put(serial, true);
-            } else {
-                devices.put(serial, false);
-            }
-        }
-        return devices;
-    }
-
-    /**
      * Parses the output of "fastboot devices" command.
      * Exposed for unit testing.
      *
@@ -155,4 +127,20 @@
         }
         return fastbootResult.getStdout();
     }
+
+    /** Returns whether or not a device is in Fastbootd instead of Bootloader. */
+    public boolean isFastbootd(String serial) {
+        final CommandResult fastbootResult =
+                mRunUtil.runTimedCmd(
+                        FASTBOOT_CMD_TIMEOUT,
+                        mFastbootPath,
+                        "-s",
+                        serial,
+                        "getvar",
+                        "is-userspace");
+        if (fastbootResult.getStderr().contains("is-userspace: yes")) {
+            return true;
+        }
+        return false;
+    }
 }
diff --git a/src/com/android/tradefed/device/ManagedTestDeviceFactory.java b/src/com/android/tradefed/device/ManagedTestDeviceFactory.java
index 6890639..4771e2b 100644
--- a/src/com/android/tradefed/device/ManagedTestDeviceFactory.java
+++ b/src/com/android/tradefed/device/ManagedTestDeviceFactory.java
@@ -130,11 +130,7 @@
         }
 
         if (idevice instanceof FastbootDevice) {
-            if (((FastbootDevice) idevice).isFastbootD()) {
-                testDevice.setDeviceState(TestDeviceState.FASTBOOTD);
-            } else {
-                testDevice.setDeviceState(TestDeviceState.FASTBOOT);
-            }
+            testDevice.setDeviceState(TestDeviceState.FASTBOOT);
         } else if (idevice instanceof StubDevice) {
             testDevice.setDeviceState(TestDeviceState.NOT_AVAILABLE);
         }
diff --git a/src/com/android/tradefed/device/NativeDevice.java b/src/com/android/tradefed/device/NativeDevice.java
index d381555..478d0d5 100644
--- a/src/com/android/tradefed/device/NativeDevice.java
+++ b/src/com/android/tradefed/device/NativeDevice.java
@@ -2197,6 +2197,12 @@
         CLog.i("Bootloader recovery successful for %s", getSerialNumber());
     }
 
+    private void recoverDeviceFromFastbootd() throws DeviceNotAvailableException {
+        CLog.i("Attempting recovery on %s in fastbootd", getSerialNumber());
+        mRecovery.recoverDeviceFastbootd(mStateMonitor);
+        CLog.i("Fastbootd recovery successful for %s", getSerialNumber());
+    }
+
     private void recoverDeviceInRecovery() throws DeviceNotAvailableException {
         CLog.i("Attempting recovery on %s in recovery", getSerialNumber());
         mRecovery.recoverDeviceRecovery(mStateMonitor);
@@ -2966,8 +2972,9 @@
         }
 
         if (RebootMode.REBOOT_INTO_FASTBOOTD.equals(mode) && getHostOptions().isFastbootdEnable()) {
-            if (!mStateMonitor.waitForDeviceFastbootd(mOptions.getFastbootTimeout())) {
-                recoverDeviceFromBootloader();
+            if (!mStateMonitor.waitForDeviceFastbootd(
+                    getFastbootPath(), mOptions.getFastbootTimeout())) {
+                recoverDeviceFromFastbootd();
             }
         } else {
             if (!mStateMonitor.waitForDeviceBootloader(mOptions.getFastbootTimeout())) {
diff --git a/src/com/android/tradefed/device/NativeDeviceStateMonitor.java b/src/com/android/tradefed/device/NativeDeviceStateMonitor.java
index c83d702..bdf2dd6 100644
--- a/src/com/android/tradefed/device/NativeDeviceStateMonitor.java
+++ b/src/com/android/tradefed/device/NativeDeviceStateMonitor.java
@@ -399,24 +399,12 @@
 
     /** {@inheritDoc} */
     @Override
-    public boolean waitForDeviceFastbootd(long time) {
-        if (!mFastbootEnabled) {
+    public boolean waitForDeviceFastbootd(String fastbootPath, long time) {
+        boolean bootloader = waitForDeviceBootloader(time);
+        if (!bootloader) {
             return false;
         }
-        long startTime = System.currentTimeMillis();
-        // ensure fastboot state is updated at least once
-        waitForDeviceBootloaderStateUpdate();
-        long elapsedTime = System.currentTimeMillis() - startTime;
-        IFastbootListener listener = new StubFastbootListener();
-        mMgr.addFastbootListener(listener);
-        long waitTime = time - elapsedTime;
-        if (waitTime < 0) {
-            // wait at least 200ms
-            waitTime = 200;
-        }
-        boolean result = waitForDeviceState(TestDeviceState.FASTBOOTD, waitTime);
-        mMgr.removeFastbootListener(listener);
-        return result;
+        return new FastbootHelper(getRunUtil(), fastbootPath).isFastbootd(getSerialNumber());
     }
 
     @Override
diff --git a/src/com/android/tradefed/device/WaitDeviceRecovery.java b/src/com/android/tradefed/device/WaitDeviceRecovery.java
index 94e9591..6c8f942 100644
--- a/src/com/android/tradefed/device/WaitDeviceRecovery.java
+++ b/src/com/android/tradefed/device/WaitDeviceRecovery.java
@@ -287,7 +287,7 @@
         // poll and wait for device to return to valid state
         long pollTime = mBootloaderWaitTime / BOOTLOADER_POLL_ATTEMPTS;
         for (int i = 0; i < BOOTLOADER_POLL_ATTEMPTS; i++) {
-            if (monitor.waitForDeviceFastbootd(pollTime)) {
+            if (monitor.waitForDeviceFastbootd(mFastbootPath, pollTime)) {
                 handleDeviceFastbootdUnresponsive(monitor);
                 // passed above check, abort
                 return;
@@ -342,7 +342,7 @@
             return;
         }
         rebootDevice(device, "fastboot");
-        if (!monitor.waitForDeviceFastbootd(mBootloaderWaitTime)) {
+        if (!monitor.waitForDeviceFastbootd(mFastbootPath, mBootloaderWaitTime)) {
             throw new DeviceNotAvailableException(
                     String.format(
                             "Device %s not in fastbootd after reboot", monitor.getSerialNumber()),
@@ -366,7 +366,7 @@
                         "fastboot");
         // wait for device to reboot
         monitor.waitForDeviceNotAvailable(WAIT_FOR_DEVICE_OFFLINE);
-        if (!monitor.waitForDeviceFastbootd(mBootloaderWaitTime)) {
+        if (!monitor.waitForDeviceFastbootd(mFastbootPath, mBootloaderWaitTime)) {
             throw new DeviceNotAvailableException(
                     String.format(
                             "Device %s not in fastbootd after reboot", monitor.getSerialNumber()),