A new device connection triggers a series of asynchronous events that are not obvious yet worth understanding.
Physically connected
Tradefed uses the ddmlib library (a Java adb library) to provide the basic
interaction with adb and devices. Part of this solution is the
IDeviceChangeListener interface
that allows reception of new device events, such as:
deviceConnected: When a new device is seen byadbdeviceDisconnected: When a device is not reporting toadbanymoredeviceChanged: When a major device state occurs (such as device offline or device online)
These events are enough at the adb level to decide whether or not a device is
connected, online, or offline. But for the test harness, we need a stronger
state than this to ensure a device is truly ready to start running tests; it
should not be impacted by potential state flakiness that can come with a newly
connected device.
This is the sequence of events in Tradefed:
- Device is recognized as
deviceConnectedand open to regular events fromadb An internal Tradefed event is created that will:
- Check if the device is known already; Tradefed keeps internal reference to some devices (especially the one current allocated and running tests) to avoid TF losing track of them randomly.
- Check if the device is
ONLINEorOFFLINE.
If device is:
OFFLINE: Device will be switched to TradefedCONNECTED_OFFLINEstate, which doesn't allow the device to run tests yet. If the device is online later, it will go through theONLINEcycle. If we receive adeviceDisconnectevent, the device will simply be removed from the list.ONLINE(as seen by adb): Device will be put in the stateCONNECTED_ONLINEand will have its availability checked for test allocation:checking_availability.
If
availabilitycheck is successful, the device will be marked as available for test allocation; it will be able to run tests. If not, the device will be marked asunavailablefor allocation and cannot receive any tests.
All of these states are reflected in the Tradefed console when listing the
devices via: tf> list devices
It's important to note that when the device is currently allocated for a test,
most of the above will not occur and Tradefed will determine the device state
internally. So it's possible for a device to disappear from adb devices while
still being listed by Tradefed. That can happen when a test is rebooting the
device for example.
Virtual device connected with adb connect
When a remote virtual device is created, Tradefed connects to it using adb
connect. This will usually trigger the device showing in adb devices as
<some ip>:<port number> and will follow the same sequence as physically
connected devices.
Device tracking when a deviceConnected event occurs
When deviceConnected occurs, ddmlib creates a new reference
IDevice
to track the newly connected device.
Tradefed uses that reference and wraps it in its own implementation of device
interface
ITestDevice
to provide more advanced service. But the underlying IDevice is always the one
coming from ddmlib.
This means if a new device is connected, a new ITestDevice is created and associated with the IDevice. When this happens during an invocation and the ITestDevice is being used, the underlying IDevice is still replaced so testing can proceed on the proper reference. This is done seamlessly each time a device is disconnected/reconnected (for example, during a reboot).