Merge "Isolate the force allocate logic"
diff --git a/src/com/android/tradefed/device/DeviceManager.java b/src/com/android/tradefed/device/DeviceManager.java
index a653c1e..485af19 100644
--- a/src/com/android/tradefed/device/DeviceManager.java
+++ b/src/com/android/tradefed/device/DeviceManager.java
@@ -615,7 +615,7 @@
     @Override
     public ITestDevice forceAllocateDevice(String serial) {
         checkInit();
-        IManagedTestDevice d = mManagedDeviceList.findOrCreate(new StubDevice(serial, false));
+        IManagedTestDevice d = mManagedDeviceList.forceAllocate(serial);
         if (d != null) {
             DeviceEventResponse r = d.handleAllocationEvent(DeviceEvent.FORCE_ALLOCATE_REQUEST);
             if (r.stateChanged && r.allocationState == DeviceAllocationState.Allocated) {
@@ -836,10 +836,17 @@
      */
     @Override
     public ITestDevice connectToTcpDevice(String ipAndPort) {
-        ITestDevice tcpDevice = forceAllocateDevice(ipAndPort);
+        IManagedTestDevice tcpDevice = mManagedDeviceList.findOrCreate(new StubDevice(ipAndPort));
         if (tcpDevice == null) {
             return null;
         }
+        DeviceEventResponse r = tcpDevice.handleAllocationEvent(DeviceEvent.FORCE_ALLOCATE_REQUEST);
+        if (r.stateChanged && r.allocationState == DeviceAllocationState.Allocated) {
+            // Wait for the fastboot state to be updated once to update the IDevice.
+            tcpDevice.getMonitor().waitForDeviceBootloaderStateUpdate();
+        } else {
+            return null;
+        }
         if (doAdbConnect(ipAndPort)) {
             try {
                 tcpDevice.setRecovery(new WaitDeviceRecovery());
diff --git a/src/com/android/tradefed/device/ManagedDeviceList.java b/src/com/android/tradefed/device/ManagedDeviceList.java
index d33c769..d296ab7 100644
--- a/src/com/android/tradefed/device/ManagedDeviceList.java
+++ b/src/com/android/tradefed/device/ManagedDeviceList.java
@@ -237,6 +237,23 @@
     }
 
     /**
+     * Force allocate a device based on its serial, if the device isn't tracked yet we won't create
+     * its tracking. This is meant for force-allocate known devices, usually for automated recovery.
+     */
+    public IManagedTestDevice forceAllocate(String serial) {
+        if (!isValidDeviceSerial(serial)) {
+            return null;
+        }
+        mListLock.lock();
+        try {
+            // Unlike findOrCreate we don't attempt to create in this case.
+            return find(serial);
+        } finally {
+            mListLock.unlock();
+        }
+    }
+
+    /**
      * Directly add a device to the list. Should not be used outside of unit testing.
      * @param device
      */
diff --git a/tests/src/com/android/tradefed/device/DeviceManagerTest.java b/tests/src/com/android/tradefed/device/DeviceManagerTest.java
index 3d1d564..d3c4a4e 100644
--- a/tests/src/com/android/tradefed/device/DeviceManagerTest.java
+++ b/tests/src/com/android/tradefed/device/DeviceManagerTest.java
@@ -502,11 +502,9 @@
     /** Test {@link DeviceManager#forceAllocateDevice(String)} when device is unknown */
     @Test
     public void testForceAllocateDevice() {
-        EasyMock.expect(mMockTestDevice.handleAllocationEvent(DeviceEvent.FORCE_ALLOCATE_REQUEST))
-                .andReturn(new DeviceEventResponse(DeviceAllocationState.Allocated, true));
         replayMocks();
         DeviceManager manager = createDeviceManager(null);
-        assertNotNull(manager.forceAllocateDevice("unknownserial"));
+        assertNull(manager.forceAllocateDevice("unknownserial"));
         verifyMocks();
     }
 
@@ -514,8 +512,6 @@
     @Test
     public void testForceAllocateDevice_available() {
         setCheckAvailableDeviceExpectations();
-        EasyMock.expect(mMockTestDevice.getAllocationState())
-                .andReturn(DeviceAllocationState.Available);
         EasyMock.expect(mMockTestDevice.handleAllocationEvent(DeviceEvent.FORCE_ALLOCATE_REQUEST))
                 .andReturn(new DeviceEventResponse(DeviceAllocationState.Allocated, true));
         replayMocks();
@@ -528,8 +524,6 @@
     @Test
     public void testForceAllocateDevice_alreadyAllocated() {
         setCheckAvailableDeviceExpectations();
-        EasyMock.expect(mMockTestDevice.getAllocationState())
-                .andReturn(DeviceAllocationState.Allocated);
         EasyMock.expect(mMockTestDevice.handleAllocationEvent(DeviceEvent.ALLOCATE_REQUEST))
                 .andReturn(new DeviceEventResponse(DeviceAllocationState.Allocated, true));
         EasyMock.expect(mMockTestDevice.handleAllocationEvent(DeviceEvent.FORCE_ALLOCATE_REQUEST))