aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHongguang Chen <hgchen@google.com>2020-08-31 01:22:12 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2020-08-31 01:22:12 +0000
commita19f55ed67fe37805e86dcaedf66284ad11867a7 (patch)
tree2135c292472a4f7a2083e03d490b598dd0bef0f3
parent141506868ab1ce9ef4e62e0f459598e11b7ebe10 (diff)
parent2ec2b8e9b1c6fad3b9fc1facba2d266ec8222f5e (diff)
downloadtradefederation-a19f55ed67fe37805e86dcaedf66284ad11867a7.tar.gz
Allow IPv6 link-local address to be fastboot serial number. am: 2ec2b8e9b1
Original change: https://googleplex-android-review.googlesource.com/c/platform/tools/tradefederation/+/12335092 Change-Id: If21c146bd4add1a602c459a7065839bbe0ecebcf
-rw-r--r--device_build_interfaces/com/android/tradefed/device/IDeviceStateMonitor.java5
-rw-r--r--device_build_interfaces/com/android/tradefed/device/INativeDevice.java3
-rw-r--r--global_configuration/com/android/tradefed/host/HostOptions.java43
-rw-r--r--global_configuration/com/android/tradefed/host/IHostOptions.java3
-rw-r--r--src/com/android/tradefed/device/DeviceManager.java13
-rw-r--r--src/com/android/tradefed/device/FastbootHelper.java33
-rw-r--r--src/com/android/tradefed/device/IDeviceManager.java9
-rw-r--r--src/com/android/tradefed/device/NativeDevice.java176
-rw-r--r--src/com/android/tradefed/device/NativeDeviceStateMonitor.java23
-rw-r--r--src/com/android/tradefed/device/WaitDeviceRecovery.java9
-rw-r--r--tests/src/com/android/tradefed/device/MockDeviceManager.java5
-rw-r--r--tests/src/com/android/tradefed/device/NativeDeviceTest.java136
-rw-r--r--tests/src/com/android/tradefed/device/TestDeviceTest.java5
-rw-r--r--tests/src/com/android/tradefed/device/WaitDeviceRecoveryTest.java2
14 files changed, 455 insertions, 10 deletions
diff --git a/device_build_interfaces/com/android/tradefed/device/IDeviceStateMonitor.java b/device_build_interfaces/com/android/tradefed/device/IDeviceStateMonitor.java
index 0e6c86ed2..8f432fcb6 100644
--- a/device_build_interfaces/com/android/tradefed/device/IDeviceStateMonitor.java
+++ b/device_build_interfaces/com/android/tradefed/device/IDeviceStateMonitor.java
@@ -196,4 +196,9 @@ public interface IDeviceStateMonitor {
*/
public void setDefaultAvailableTimeout(long timeoutMs);
+ /** Sets the fastboot mode serial number. */
+ public void setFastbootSerialNumber(String serial);
+
+ /** Gets the fastboot mode serial number. */
+ public String getFastbootSerialNumber();
}
diff --git a/device_build_interfaces/com/android/tradefed/device/INativeDevice.java b/device_build_interfaces/com/android/tradefed/device/INativeDevice.java
index 3ceb9448f..b3fdbbb79 100644
--- a/device_build_interfaces/com/android/tradefed/device/INativeDevice.java
+++ b/device_build_interfaces/com/android/tradefed/device/INativeDevice.java
@@ -82,6 +82,9 @@ public interface INativeDevice {
*/
public String getSerialNumber();
+ /** Returns the fastboot mode serial number. */
+ public String getFastbootSerialNumber();
+
/**
* Retrieve the given property value from the device.
*
diff --git a/global_configuration/com/android/tradefed/host/HostOptions.java b/global_configuration/com/android/tradefed/host/HostOptions.java
index 68aa51f08..f280130d4 100644
--- a/global_configuration/com/android/tradefed/host/HostOptions.java
+++ b/global_configuration/com/android/tradefed/host/HostOptions.java
@@ -19,9 +19,14 @@ package com.android.tradefed.host;
import com.android.tradefed.config.ConfigurationException;
import com.android.tradefed.config.Option;
import com.android.tradefed.config.OptionClass;
+import com.android.tradefed.log.LogUtil.CLog;
import java.io.File;
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.SocketException;
import java.util.ArrayList;
+import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -96,6 +101,11 @@ public class HostOptions implements IHostOptions {
description = "Whether to use zip64 format in partial download.")
private boolean mUseZip64InPartialDownload = false;
+ @Option(
+ name = "use-network-interface",
+ description = "The network interface used to connect to test devices.")
+ private String mNetworkInterface = null;
+
/** {@inheritDoc} */
@Override
public Integer getConcurrentFlasherLimit() {
@@ -167,4 +177,37 @@ public class HostOptions implements IHostOptions {
public boolean getUseZip64InPartialDownload() {
return mUseZip64InPartialDownload;
}
+
+ /** {@inheritDoc} */
+ @Override
+ public String getNetworkInterface() {
+ if (mNetworkInterface != null) {
+ return mNetworkInterface;
+ }
+
+ try {
+ for (Enumeration<NetworkInterface> enNetI = NetworkInterface.getNetworkInterfaces();
+ enNetI.hasMoreElements(); ) {
+ NetworkInterface netI = enNetI.nextElement();
+ if (!netI.isUp()) {
+ continue;
+ }
+ for (Enumeration<InetAddress> enumIpAddr = netI.getInetAddresses();
+ enumIpAddr.hasMoreElements(); ) {
+ InetAddress inetAddress = enumIpAddr.nextElement();
+ if (!inetAddress.isAnyLocalAddress()
+ && !inetAddress.isLinkLocalAddress()
+ && !inetAddress.isLoopbackAddress()
+ && !inetAddress.isMulticastAddress()) {
+ mNetworkInterface = netI.getName();
+ return mNetworkInterface;
+ }
+ }
+ }
+ } catch (SocketException e) {
+ CLog.w("Failed to get host's active interface");
+ CLog.w(e);
+ }
+ return null;
+ }
}
diff --git a/global_configuration/com/android/tradefed/host/IHostOptions.java b/global_configuration/com/android/tradefed/host/IHostOptions.java
index 32b8a044d..342658795 100644
--- a/global_configuration/com/android/tradefed/host/IHostOptions.java
+++ b/global_configuration/com/android/tradefed/host/IHostOptions.java
@@ -73,4 +73,7 @@ public interface IHostOptions {
/** Check if it should use the zip64 format in partial download or not. */
boolean getUseZip64InPartialDownload();
+
+ /** Returns the network interface used to connect to remote test devices. */
+ String getNetworkInterface();
}
diff --git a/src/com/android/tradefed/device/DeviceManager.java b/src/com/android/tradefed/device/DeviceManager.java
index 669496072..c43fd75cc 100644
--- a/src/com/android/tradefed/device/DeviceManager.java
+++ b/src/com/android/tradefed/device/DeviceManager.java
@@ -195,6 +195,8 @@ public class DeviceManager implements IDeviceManager {
/** Flag to remember if adb bridge has been disconnected and needs to be reset * */
private boolean mAdbBridgeNeedRestart = false;
+ private Map<String, String> mMonitoringTcpFastbootDevices = new HashMap<>();
+
/**
* The DeviceManager should be retrieved from the {@link GlobalConfiguration}
*/
@@ -1352,6 +1354,11 @@ public class DeviceManager implements IDeviceManager {
final FastbootHelper fastboot = new FastbootHelper(getRunUtil(), getFastbootPath());
while (!mQuit) {
Map<String, Boolean> serialAndMode = fastboot.getBootloaderAndFastbootdDevices();
+
+ serialAndMode.putAll(
+ fastboot.getBootloaderAndFastbootdTcpDevices(
+ mMonitoringTcpFastbootDevices));
+
if (serialAndMode != null) {
// Update known bootloader devices state
Set<String> bootloader = new HashSet<>();
@@ -1591,4 +1598,10 @@ public class DeviceManager implements IDeviceManager {
public String getAdbVersion() {
return mAdbBridge.getAdbVersion(mAdbPath);
}
+
+ /** {@inheritDoc} */
+ @Override
+ public void addMonitoringTcpFastbootDevice(String serial, String fastboot_serial) {
+ mMonitoringTcpFastbootDevices.put(serial, fastboot_serial);
+ }
}
diff --git a/src/com/android/tradefed/device/FastbootHelper.java b/src/com/android/tradefed/device/FastbootHelper.java
index 276207521..fe251fd03 100644
--- a/src/com/android/tradefed/device/FastbootHelper.java
+++ b/src/com/android/tradefed/device/FastbootHelper.java
@@ -25,6 +25,7 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;
+import java.util.Map.Entry;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -125,6 +126,38 @@ public class FastbootHelper {
}
/**
+ * Returns a map of device serials and whether they are in fastbootd mode or not.
+ *
+ * @param serials a map of devices serial number and fastboot mode serial number.
+ * @return a Map of serial in bootloader or fastbootd, the boolean is true if in fastbootd
+ */
+ public Map<String, Boolean> getBootloaderAndFastbootdTcpDevices(Map<String, String> serials) {
+ HashMap<String, Boolean> devices = new LinkedHashMap<>();
+ long TIMEOUT = 1500;
+
+ for (Entry<String, String> entry : serials.entrySet()) {
+ CLog.v("Run 'fastboot -s %s getvar is-userspace' command", entry.getValue());
+ CommandResult fastbootResult =
+ mRunUtil.runTimedCmdSilently(
+ TIMEOUT,
+ mFastbootPath,
+ "-s",
+ entry.getValue(),
+ "getvar",
+ "is-userspace");
+ if (fastbootResult.getStatus().equals(CommandStatus.SUCCESS)) {
+ if (fastbootResult.getStderr().contains("yes")) {
+ devices.put(entry.getKey(), true);
+ } else {
+ devices.put(entry.getKey(), false);
+ }
+ }
+ }
+
+ return devices;
+ }
+
+ /**
* Parses the output of "fastboot devices" command. Exposed for unit testing.
*
* @param fastbootOutput the output of fastboot command.
diff --git a/src/com/android/tradefed/device/IDeviceManager.java b/src/com/android/tradefed/device/IDeviceManager.java
index c1c3ff153..d5bf57369 100644
--- a/src/com/android/tradefed/device/IDeviceManager.java
+++ b/src/com/android/tradefed/device/IDeviceManager.java
@@ -286,4 +286,13 @@ public interface IDeviceManager {
/** Get the adb version currently in use by the device manager. */
public String getAdbVersion();
+
+ /**
+ * Add a device to fastboot monitor. The fastboot monitor will use 'fastboot_serial' to
+ * communicate with the device.
+ *
+ * @param serial the device's serial number.
+ * @param fastboot_serial the device's fastboot mode serial number.
+ */
+ public void addMonitoringTcpFastbootDevice(String serial, String fastboot_serial);
}
diff --git a/src/com/android/tradefed/device/NativeDevice.java b/src/com/android/tradefed/device/NativeDevice.java
index 2f90ad037..8c9616264 100644
--- a/src/com/android/tradefed/device/NativeDevice.java
+++ b/src/com/android/tradefed/device/NativeDevice.java
@@ -76,6 +76,8 @@ import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.OutputStream;
+import java.net.Inet6Address;
+import java.net.UnknownHostException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Clock;
@@ -168,6 +170,9 @@ public class NativeDevice implements IManagedTestDevice {
static final String MAC_ADDRESS_PATTERN = "([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}";
static final String MAC_ADDRESS_COMMAND = "su root cat /sys/class/net/wlan0/address";
+ static final String ETHERNET_MAC_ADDRESS_COMMAND = "cat /sys/class/net/eth0/address";
+
+ static final int ETHER_ADDR_LEN = 6;
/** The network monitoring interval in ms. */
private static final int NETWORK_MONITOR_INTERVAL = 10 * 1000;
@@ -225,6 +230,8 @@ public class NativeDevice implements IManagedTestDevice {
private DeviceDescriptor mCachedDeviceDescriptor = null;
private final Object mCacheLock = new Object();
+ private String mFastbootSerialNumber = null;
+
/**
* Interface for a generic device communication attempt.
*/
@@ -337,6 +344,11 @@ public class NativeDevice implements IManagedTestDevice {
mReason = reason;
}
+ public boolean isFastbootOrBootloader() {
+ return mRebootMode == RebootMode.REBOOT_INTO_BOOTLOADER
+ || mRebootMode == RebootMode.REBOOT_INTO_FASTBOOTD;
+ }
+
@Override
public boolean run() throws TimeoutException, IOException, AdbCommandRejectedException {
getIDevice().reboot(mRebootMode.formatRebootCommand(mReason));
@@ -2050,8 +2062,8 @@ public class NativeDevice implements IManagedTestDevice {
* Builds the OS command for the given fastboot command and args
*/
private String[] buildFastbootCommand(String... commandArgs) {
- return ArrayUtil.buildArray(new String[] {getFastbootPath(), "-s", getSerialNumber()},
- commandArgs);
+ return ArrayUtil.buildArray(
+ new String[] {getFastbootPath(), "-s", getFastbootSerialNumber()}, commandArgs);
}
/**
@@ -2089,6 +2101,15 @@ public class NativeDevice implements IManagedTestDevice {
return false;
}
} catch (AdbCommandRejectedException e) {
+ // Workaround to not recover device if TCP adb is used.
+ if (isAdbTcp()
+ && (action instanceof RebootDeviceAction)
+ && ((RebootDeviceAction) action).isFastbootOrBootloader()) {
+ CLog.d(
+ "Ignore AdbCommandRejectedException when TCP device is rebooted into"
+ + " fastboot.");
+ return true;
+ }
logDeviceActionException(actionDescription, e);
} catch (ShellCommandUnresponsiveException e) {
CLog.w("Device %s stopped responding when attempting %s", getSerialNumber(),
@@ -2968,6 +2989,10 @@ public class NativeDevice implements IManagedTestDevice {
throw new UnsupportedOperationException(
String.format("Fastboot is not available and cannot reboot into %s", mode));
}
+
+ // Update fastboot serial number before entering fastboot mode
+ mStateMonitor.setFastbootSerialNumber(getFastbootSerialNumber());
+
// If we go to bootloader, it's probably for flashing so ensure we re-check the provider
mShouldSkipContentProviderSetup = false;
CLog.i(
@@ -3747,6 +3772,78 @@ public class NativeDevice implements IManagedTestDevice {
return null;
}
+ /** {@inheritDoc} */
+ @Override
+ public String getFastbootSerialNumber() {
+ if (mFastbootSerialNumber != null) {
+ return mFastbootSerialNumber;
+ }
+
+ // Only devices which use TCP adb have different fastboot serial number because IPv6
+ // link-local address will be used in fastboot mode.
+ if (!isAdbTcp()) {
+ mFastbootSerialNumber = getSerialNumber();
+ CLog.i(
+ "Device %s's fastboot serial number is %s",
+ getSerialNumber(), mFastbootSerialNumber);
+ return mFastbootSerialNumber;
+ }
+
+ mFastbootSerialNumber = getSerialNumber();
+ byte[] macEui48Bytes;
+
+ try {
+ boolean adbRoot = isAdbRoot();
+ if (!adbRoot) {
+ enableAdbRoot();
+ }
+ macEui48Bytes = getEUI48MacAddressInBytes(ETHERNET_MAC_ADDRESS_COMMAND);
+ if (!adbRoot) {
+ disableAdbRoot();
+ }
+ } catch (DeviceNotAvailableException e) {
+ CLog.e("Device %s isn't available when get fastboot serial number", getSerialNumber());
+ CLog.e(e);
+ return getSerialNumber();
+ }
+
+ String net_interface = getHostOptions().getNetworkInterface();
+ if (net_interface == null || macEui48Bytes == null) {
+ CLog.i(
+ "Device %s's fastboot serial number is %s",
+ getSerialNumber(), mFastbootSerialNumber);
+ return mFastbootSerialNumber;
+ }
+
+ // Create a link-local Inet6Address from the MAC address. The EUI-48 MAC address
+ // is converted to an EUI-64 MAC address per RFC 4291. The resulting EUI-64 is
+ // used to construct a link-local IPv6 address per RFC 4862.
+ byte[] addr = new byte[16];
+ addr[0] = (byte) 0xfe;
+ addr[1] = (byte) 0x80;
+ addr[8] = (byte) (macEui48Bytes[0] ^ (byte) 0x02); // flip the link-local bit
+ addr[9] = macEui48Bytes[1];
+ addr[10] = macEui48Bytes[2];
+ addr[11] = (byte) 0xff;
+ addr[12] = (byte) 0xfe;
+ addr[13] = macEui48Bytes[3];
+ addr[14] = macEui48Bytes[4];
+ addr[15] = macEui48Bytes[5];
+
+ try {
+ String host_addr = Inet6Address.getByAddress(null, addr, 0).getHostAddress();
+ mFastbootSerialNumber = "tcp:" + host_addr.split("%")[0] + "%" + net_interface;
+ } catch (UnknownHostException e) {
+ CLog.w("Failed to get %s's IPv6 link-local address", getSerialNumber());
+ CLog.w(e);
+ }
+
+ CLog.i(
+ "Device %s's fastboot serial number is %s",
+ getSerialNumber(), mFastbootSerialNumber);
+ return mFastbootSerialNumber;
+ }
+
/**
* {@inheritDoc}
*/
@@ -4785,10 +4882,12 @@ public class NativeDevice implements IManagedTestDevice {
}
/**
- * {@inheritDoc}
+ * Query Mac address from the device
+ *
+ * @param command the query command
+ * @return the MAC address of the device, null if it fails to query from the device
*/
- @Override
- public String getMacAddress() {
+ private String getMacAddress(String command) {
if (getIDevice() instanceof StubDevice) {
// Do not query MAC addresses from stub devices.
return null;
@@ -4799,20 +4898,81 @@ public class NativeDevice implements IManagedTestDevice {
}
CollectingOutputReceiver receiver = new CollectingOutputReceiver();
try {
- mIDevice.executeShellCommand(MAC_ADDRESS_COMMAND, receiver);
+ mIDevice.executeShellCommand(command, receiver);
} catch (IOException | TimeoutException | AdbCommandRejectedException |
ShellCommandUnresponsiveException e) {
- CLog.w("Failed to query MAC address for %s", mIDevice.getSerialNumber());
+ CLog.w(
+ "Failed to query MAC address for %s by '%s'",
+ mIDevice.getSerialNumber(), command);
CLog.w(e);
}
String output = receiver.getOutput().trim();
if (isMacAddress(output)) {
return output;
}
- CLog.d("No valid MAC address queried from device %s", mIDevice.getSerialNumber());
+ CLog.d(
+ "No valid MAC address queried from device %s by '%s'",
+ mIDevice.getSerialNumber(), command);
return null;
}
+ /**
+ * Query EUI-48 MAC address from the device
+ *
+ * @param command the query command
+ * @return the EUI-48 MAC address in long, 0 if it fails to query from the device
+ * @throws IllegalArgumentException
+ */
+ long getEUI48MacAddressInLong(String command) {
+ String addr = getMacAddress(command);
+ if (addr == null) {
+ return 0;
+ }
+
+ String[] parts = addr.split(":");
+ if (parts.length != ETHER_ADDR_LEN) {
+ throw new IllegalArgumentException(addr + " was not a valid MAC address");
+ }
+ long longAddr = 0;
+ for (int i = 0; i < parts.length; i++) {
+ int x = Integer.valueOf(parts[i], 16);
+ if (x < 0 || 0xff < x) {
+ throw new IllegalArgumentException(addr + "was not a valid MAC address");
+ }
+ longAddr = x + (longAddr << 8);
+ }
+
+ return longAddr;
+ }
+
+ /**
+ * Query EUI-48 MAC address from the device
+ *
+ * @param command the query command
+ * @return the EUI-48 MAC address in byte[], null if it fails to query from the device
+ * @throws IllegalArgumentException
+ */
+ byte[] getEUI48MacAddressInBytes(String command) {
+ long addr = getEUI48MacAddressInLong(command);
+ if (addr == 0) {
+ return null;
+ }
+
+ byte[] bytes = new byte[ETHER_ADDR_LEN];
+ int index = ETHER_ADDR_LEN;
+ while (index-- > 0) {
+ bytes[index] = (byte) addr;
+ addr = addr >> 8;
+ }
+ return bytes;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public String getMacAddress() {
+ return getMacAddress(MAC_ADDRESS_COMMAND);
+ }
+
/** {@inheritDoc} */
@Override
public String getSimState() {
diff --git a/src/com/android/tradefed/device/NativeDeviceStateMonitor.java b/src/com/android/tradefed/device/NativeDeviceStateMonitor.java
index ebe4526e0..dcd2da7f2 100644
--- a/src/com/android/tradefed/device/NativeDeviceStateMonitor.java
+++ b/src/com/android/tradefed/device/NativeDeviceStateMonitor.java
@@ -55,6 +55,9 @@ public class NativeDeviceStateMonitor implements IDeviceStateMonitor {
/** The time in ms to wait for a device to available. */
private long mDefaultAvailableTimeout = 6 * 60 * 1000;
+ /** The fastboot mode serial number */
+ private String mFastbootSerialNumber = null;
+
private List<DeviceStateListener> mStateListeners;
private IDeviceManager mMgr;
private final boolean mFastbootEnabled;
@@ -95,6 +98,17 @@ public class NativeDeviceStateMonitor implements IDeviceStateMonitor {
mDefaultAvailableTimeout = timeoutMs;
}
+ /** Set the fastboot mode serial number. */
+ @Override
+ public void setFastbootSerialNumber(String serial) {
+ mFastbootSerialNumber = serial;
+
+ if (mFastbootSerialNumber != null && !mFastbootSerialNumber.equals(getSerialNumber())) {
+ // Add to IDeviceManager to monitor it
+ mMgr.addMonitoringTcpFastbootDevice(getSerialNumber(), mFastbootSerialNumber);
+ }
+ }
+
/**
* {@inheritDoc}
*/
@@ -131,6 +145,15 @@ public class NativeDeviceStateMonitor implements IDeviceStateMonitor {
return getIDevice().getSerialNumber();
}
+ /** {@inheritDoc} */
+ @Override
+ public String getFastbootSerialNumber() {
+ if (mFastbootSerialNumber == null) {
+ mFastbootSerialNumber = getSerialNumber();
+ }
+ return mFastbootSerialNumber;
+ }
+
/**
* {@inheritDoc}
*/
diff --git a/src/com/android/tradefed/device/WaitDeviceRecovery.java b/src/com/android/tradefed/device/WaitDeviceRecovery.java
index 80a8f7d52..d71fb0637 100644
--- a/src/com/android/tradefed/device/WaitDeviceRecovery.java
+++ b/src/com/android/tradefed/device/WaitDeviceRecovery.java
@@ -137,8 +137,13 @@ public class WaitDeviceRecovery implements IDeviceRecovery {
"Found device %s in %s but expected online. Rebooting...",
monitor.getSerialNumber(), state));
// TODO: retry if failed
- getRunUtil().runTimedCmd(mFastbootWaitTime, mFastbootPath, "-s",
- monitor.getSerialNumber(), "reboot");
+ getRunUtil()
+ .runTimedCmd(
+ mFastbootWaitTime,
+ mFastbootPath,
+ "-s",
+ monitor.getFastbootSerialNumber(),
+ "reboot");
}
// wait for device online
diff --git a/tests/src/com/android/tradefed/device/MockDeviceManager.java b/tests/src/com/android/tradefed/device/MockDeviceManager.java
index 86b58f9d1..997b972ab 100644
--- a/tests/src/com/android/tradefed/device/MockDeviceManager.java
+++ b/tests/src/com/android/tradefed/device/MockDeviceManager.java
@@ -454,4 +454,9 @@ public class MockDeviceManager implements IDeviceManager {
public String getAdbVersion() {
return null;
}
+
+ @Override
+ public void addMonitoringTcpFastbootDevice(String serial, String fastboot_serial) {
+ // ignore
+ }
}
diff --git a/tests/src/com/android/tradefed/device/NativeDeviceTest.java b/tests/src/com/android/tradefed/device/NativeDeviceTest.java
index c77f3ab52..2a3974d6e 100644
--- a/tests/src/com/android/tradefed/device/NativeDeviceTest.java
+++ b/tests/src/com/android/tradefed/device/NativeDeviceTest.java
@@ -1686,10 +1686,16 @@ public class NativeDeviceTest {
public TestDeviceState getDeviceState() {
return TestDeviceState.ONLINE;
}
+
+ @Override
+ public String getFastbootSerialNumber() {
+ return MOCK_DEVICE_SERIAL;
+ }
};
String into = "bootloader";
mMockIDevice.reboot(into);
EasyMock.expectLastCall();
+ mMockStateMonitor.setFastbootSerialNumber(MOCK_DEVICE_SERIAL);
EasyMock.expect(mMockStateMonitor.waitForDeviceBootloader(EasyMock.anyLong()))
.andReturn(true);
EasyMock.replay(mMockIDevice, mMockStateMonitor, mMockDvcMonitor);
@@ -1718,7 +1724,13 @@ public class NativeDeviceTest {
}
return new CommandResult();
}
+
+ @Override
+ public String getFastbootSerialNumber() {
+ return MOCK_DEVICE_SERIAL;
+ }
};
+ mMockStateMonitor.setFastbootSerialNumber(MOCK_DEVICE_SERIAL);
EasyMock.expect(mMockStateMonitor.waitForDeviceBootloader(EasyMock.anyLong()))
.andReturn(true);
EasyMock.replay(mMockIDevice, mMockStateMonitor, mMockDvcMonitor);
@@ -1736,10 +1748,16 @@ public class NativeDeviceTest {
public TestDeviceState getDeviceState() {
return TestDeviceState.ONLINE;
}
+
+ @Override
+ public String getFastbootSerialNumber() {
+ return MOCK_DEVICE_SERIAL;
+ }
};
String into = "fastboot";
mMockIDevice.reboot(into);
EasyMock.expectLastCall();
+ mMockStateMonitor.setFastbootSerialNumber(MOCK_DEVICE_SERIAL);
EasyMock.expect(mMockStateMonitor.waitForDeviceBootloader(EasyMock.anyLong()))
.andReturn(true);
EasyMock.replay(mMockIDevice, mMockStateMonitor, mMockDvcMonitor);
@@ -1768,7 +1786,13 @@ public class NativeDeviceTest {
}
return new CommandResult();
}
+
+ @Override
+ public String getFastbootSerialNumber() {
+ return MOCK_DEVICE_SERIAL;
+ }
};
+ mMockStateMonitor.setFastbootSerialNumber(MOCK_DEVICE_SERIAL);
EasyMock.expect(mMockStateMonitor.waitForDeviceBootloader(EasyMock.anyLong()))
.andReturn(true);
EasyMock.replay(mMockIDevice, mMockStateMonitor, mMockDvcMonitor);
@@ -3235,4 +3259,116 @@ public class NativeDeviceTest {
.andReturn(stubResult);
EasyMock.replay(mMockRunUtil);
}
+
+ /** Test {@link NativeDevice#getFastbootSerialNumber()} with USB adb. */
+ @Test
+ public void testGetFastbootSerialNumber_usb_adb() {
+ mTestDevice =
+ new TestableAndroidNativeDevice() {
+ @Override
+ public boolean isAdbTcp() {
+ return false;
+ }
+ };
+ EasyMock.replay(mMockIDevice);
+ assertEquals(MOCK_DEVICE_SERIAL, mTestDevice.getFastbootSerialNumber());
+ EasyMock.verify(mMockIDevice);
+ }
+
+ /** Test {@link NativeDevice#getFastbootSerialNumber()} with non-root TCP adb. */
+ @Test
+ public void testGetFastbootSerialNumber_non_root_tcp_adb() throws Exception {
+ String address = "00:30:1b:ba:81:28";
+ IDevice device =
+ new StubDevice(MOCK_DEVICE_SERIAL) {
+ @Override
+ public void executeShellCommand(String command, IShellOutputReceiver receiver)
+ throws TimeoutException, AdbCommandRejectedException,
+ ShellCommandUnresponsiveException, IOException {
+ receiver.addOutput(address.getBytes(), 0, address.length());
+ }
+ };
+ mTestDevice =
+ new TestableAndroidNativeDevice() {
+ @Override
+ IHostOptions getHostOptions() {
+ return new HostOptions() {
+ @Override
+ public String getNetworkInterface() {
+ return "en0";
+ }
+ };
+ }
+
+ @Override
+ public boolean isAdbTcp() {
+ return true;
+ }
+
+ @Override
+ public boolean isAdbRoot() throws DeviceNotAvailableException {
+ return false;
+ }
+
+ @Override
+ public boolean enableAdbRoot() throws DeviceNotAvailableException {
+ return true;
+ }
+
+ @Override
+ public boolean disableAdbRoot() throws DeviceNotAvailableException {
+ return true;
+ }
+ };
+ mMockIDevice.executeShellCommand(EasyMock.anyObject(), EasyMock.anyObject());
+ EasyMock.expectLastCall().andDelegateTo(device).anyTimes();
+ EasyMock.replay(mMockIDevice);
+ assertEquals(
+ "tcp:fe80:0:0:0:230:1bff:feba:8128%en0", mTestDevice.getFastbootSerialNumber());
+ EasyMock.verify(mMockIDevice);
+ }
+
+ /** Test {@link NativeDevice#getFastbootSerialNumber()} with root TCP adb. */
+ @Test
+ public void testGetFastbootSerialNumber_root_tcp_adb() throws Exception {
+ String address = "00:30:1b:ba:81:28";
+ IDevice device =
+ new StubDevice(MOCK_DEVICE_SERIAL) {
+ @Override
+ public void executeShellCommand(String command, IShellOutputReceiver receiver)
+ throws TimeoutException, AdbCommandRejectedException,
+ ShellCommandUnresponsiveException, IOException {
+ receiver.addOutput(address.getBytes(), 0, address.length());
+ }
+ };
+ mTestDevice =
+ new TestableAndroidNativeDevice() {
+ @Override
+ IHostOptions getHostOptions() {
+ return new HostOptions() {
+ @Override
+ public String getNetworkInterface() {
+ return "en0";
+ }
+ };
+ }
+
+ @Override
+ public boolean isAdbTcp() {
+ return true;
+ }
+
+ @Override
+ public boolean isAdbRoot() throws DeviceNotAvailableException {
+ return true;
+ }
+ };
+
+ mMockIDevice.executeShellCommand(EasyMock.anyObject(), EasyMock.anyObject());
+ EasyMock.expectLastCall().andDelegateTo(device).anyTimes();
+ EasyMock.replay(mMockIDevice);
+ assertEquals(
+ "tcp:fe80:0:0:0:230:1bff:feba:8128%en0", mTestDevice.getFastbootSerialNumber());
+ EasyMock.verify(mMockIDevice);
+ }
}
diff --git a/tests/src/com/android/tradefed/device/TestDeviceTest.java b/tests/src/com/android/tradefed/device/TestDeviceTest.java
index 5de87725b..e6007fd6f 100644
--- a/tests/src/com/android/tradefed/device/TestDeviceTest.java
+++ b/tests/src/com/android/tradefed/device/TestDeviceTest.java
@@ -129,6 +129,11 @@ public class TestDeviceTest extends TestCase {
// Avoid issue with GlobalConfiguration
return new HostOptions();
}
+
+ @Override
+ public boolean isAdbTcp() {
+ return false;
+ }
}
/**
diff --git a/tests/src/com/android/tradefed/device/WaitDeviceRecoveryTest.java b/tests/src/com/android/tradefed/device/WaitDeviceRecoveryTest.java
index 3b5cb688d..855403a2a 100644
--- a/tests/src/com/android/tradefed/device/WaitDeviceRecoveryTest.java
+++ b/tests/src/com/android/tradefed/device/WaitDeviceRecoveryTest.java
@@ -197,6 +197,7 @@ public class WaitDeviceRecoveryTest {
EasyMock.eq("reboot")))
.andReturn(result);
+ EasyMock.expect(mMockMonitor.getFastbootSerialNumber()).andReturn("serial");
EasyMock.expect(mMockMonitor.waitForDeviceOnline(EasyMock.anyLong())).andReturn(null);
replayMocks();
try {
@@ -247,6 +248,7 @@ public class WaitDeviceRecoveryTest {
CommandResult result = new CommandResult();
result.setStatus(CommandStatus.SUCCESS);
// expect reboot
+ EasyMock.expect(mMockMonitor.getFastbootSerialNumber()).andReturn("serial");
EasyMock.expect(mMockRunUtil.runTimedCmd(EasyMock.anyLong(), EasyMock.eq("fastboot"),
EasyMock.eq("-s"), EasyMock.eq("serial"), EasyMock.eq("reboot"))).
andReturn(result);