Merge "Count only physical devices for device lost"
diff --git a/src/com/android/tradefed/command/CommandScheduler.java b/src/com/android/tradefed/command/CommandScheduler.java
index 35afc13..64636a1 100644
--- a/src/com/android/tradefed/command/CommandScheduler.java
+++ b/src/com/android/tradefed/command/CommandScheduler.java
@@ -808,13 +808,13 @@
         if (e instanceof DeviceUnresponsiveException) {
             ITestDevice badDevice =
                     context.getDeviceBySerial(((DeviceUnresponsiveException) e).getSerial());
-            if (badDevice != null) {
+            if (badDevice != null && !(badDevice.getIDevice() instanceof StubDevice)) {
                 deviceStates.put(badDevice, FreeDeviceState.UNRESPONSIVE);
             }
         } else if (e instanceof DeviceNotAvailableException) {
             ITestDevice badDevice =
                     context.getDeviceBySerial(((DeviceNotAvailableException) e).getSerial());
-            if (badDevice != null) {
+            if (badDevice != null && !(badDevice.getIDevice() instanceof StubDevice)) {
                 deviceStates.put(badDevice, FreeDeviceState.UNAVAILABLE);
             }
         }
diff --git a/src/com/android/tradefed/invoker/TestInvocation.java b/src/com/android/tradefed/invoker/TestInvocation.java
index 2bf69ee..fdd0a4b 100644
--- a/src/com/android/tradefed/invoker/TestInvocation.java
+++ b/src/com/android/tradefed/invoker/TestInvocation.java
@@ -343,23 +343,8 @@
             // Track the timestamp when we are done with devices
             addInvocationMetric(
                     InvocationMetricKey.DEVICE_DONE_TIMESTAMP, System.currentTimeMillis());
-            // Capture the FreeDeviceState of the primary device
             Map<ITestDevice, FreeDeviceState> devicesStates =
-                    CommandScheduler.createReleaseMap(context, exception);
-            if (devicesStates.size() >= 1) {
-                addInvocationMetric(
-                        InvocationMetricKey.DEVICE_RELEASE_STATE,
-                        devicesStates.values().iterator().next().toString());
-            }
-            int countLost = 0;
-            for (FreeDeviceState fds : devicesStates.values()) {
-                if (FreeDeviceState.UNAVAILABLE.equals(fds)) {
-                    countLost++;
-                }
-            }
-            if (countLost > 0) {
-                addInvocationMetric(InvocationMetricKey.DEVICE_LOST_DETECTED, countLost);
-            }
+                    handleAndLogReleaseState(context, exception);
             if (config.getCommandOptions().earlyDeviceRelease()) {
                 for (IScheduledInvocationListener scheduleListener : mSchedulerListeners) {
                     scheduleListener.releaseDevices(context, devicesStates);
@@ -1052,6 +1037,32 @@
         testInfo.executionFiles().clearFiles();
     }
 
+    private Map<ITestDevice, FreeDeviceState> handleAndLogReleaseState(
+            IInvocationContext context, Throwable exception) {
+        // Capture the FreeDeviceState of the primary device
+        Map<ITestDevice, FreeDeviceState> devicesStates =
+                CommandScheduler.createReleaseMap(context, exception);
+        if (devicesStates.size() >= 1) {
+            addInvocationMetric(
+                    InvocationMetricKey.DEVICE_RELEASE_STATE,
+                    devicesStates.values().iterator().next().toString());
+        }
+        // TODO: Add Handling of virtual devices
+        int countPhysicalLost = 0;
+        for (Entry<ITestDevice, FreeDeviceState> fds : devicesStates.entrySet()) {
+            if (fds.getKey().getIDevice() instanceof StubDevice) {
+                continue;
+            }
+            if (FreeDeviceState.UNAVAILABLE.equals(fds.getValue())) {
+                countPhysicalLost++;
+            }
+        }
+        if (countPhysicalLost > 0) {
+            addInvocationMetric(InvocationMetricKey.DEVICE_LOST_DETECTED, countPhysicalLost);
+        }
+        return devicesStates;
+    }
+
     /** Helper Thread that ensures host_log is reported in case of killed JVM */
     private class ReportHostLog extends Thread {