Merge "Snap for 6159284 from ea5c4aa4e61053e32d0781ce7397dbb068110727 to android10-tests-release" into android10-tests-release
diff --git a/fastboot/device/usb_client.cpp b/fastboot/device/usb_client.cpp
index 1014291..df75531 100644
--- a/fastboot/device/usb_client.cpp
+++ b/fastboot/device/usb_client.cpp
@@ -297,3 +297,7 @@
     CloseFunctionFs(handle_.get());
     return 0;
 }
+
+int ClientUsbTransport::Reset() {
+    return 0;
+}
diff --git a/fastboot/device/usb_client.h b/fastboot/device/usb_client.h
index 3694f9a..e6a1a8b 100644
--- a/fastboot/device/usb_client.h
+++ b/fastboot/device/usb_client.h
@@ -29,6 +29,7 @@
     ssize_t Read(void* data, size_t len) override;
     ssize_t Write(const void* data, size_t len) override;
     int Close() override;
+    int Reset() override;
 
   private:
     std::unique_ptr<usb_handle> handle_;
diff --git a/fastboot/fuzzy_fastboot/Android.bp b/fastboot/fuzzy_fastboot/Android.bp
index 277cc3a..fe982ac 100644
--- a/fastboot/fuzzy_fastboot/Android.bp
+++ b/fastboot/fuzzy_fastboot/Android.bp
@@ -5,7 +5,7 @@
   srcs: [
     "main.cpp",
     "extensions.cpp",
-    "usb_transport_sniffer.cpp",
+    "transport_sniffer.cpp",
     "fixtures.cpp",
     "test_utils.cpp",
   ],
diff --git a/fastboot/fuzzy_fastboot/fixtures.cpp b/fastboot/fuzzy_fastboot/fixtures.cpp
index bc13a8c..bd76ff4 100644
--- a/fastboot/fuzzy_fastboot/fixtures.cpp
+++ b/fastboot/fuzzy_fastboot/fixtures.cpp
@@ -48,12 +48,13 @@
 #include <gtest/gtest.h>
 
 #include "fastboot_driver.h"
+#include "tcp.h"
 #include "usb.h"
 
 #include "extensions.h"
 #include "fixtures.h"
 #include "test_utils.h"
-#include "usb_transport_sniffer.h"
+#include "transport_sniffer.h"
 
 using namespace std::literals::chrono_literals;
 
@@ -74,7 +75,14 @@
     return 0;
 }
 
+bool FastBootTest::IsFastbootOverTcp() {
+    // serial contains ":" is treated as host ip and port number
+    return (device_serial.find(":") != std::string::npos);
+}
+
 bool FastBootTest::UsbStillAvailible() {
+    if (IsFastbootOverTcp()) return true;
+
     // For some reason someone decided to prefix the path with "usb:"
     std::string prefix("usb:");
     if (std::equal(prefix.begin(), prefix.end(), device_path.begin())) {
@@ -113,15 +121,19 @@
         ASSERT_TRUE(UsbStillAvailible());  // The device disconnected
     }
 
-    const auto matcher = [](usb_ifc_info* info) -> int {
-        return MatchFastboot(info, device_serial);
-    };
-    for (int i = 0; i < MAX_USB_TRIES && !transport; i++) {
-        std::unique_ptr<UsbTransport> usb(usb_open(matcher, USB_TIMEOUT));
-        if (usb)
-            transport = std::unique_ptr<UsbTransportSniffer>(
-                    new UsbTransportSniffer(std::move(usb), serial_port));
-        std::this_thread::sleep_for(std::chrono::milliseconds(10));
+    if (IsFastbootOverTcp()) {
+        ConnectTcpFastbootDevice();
+    } else {
+        const auto matcher = [](usb_ifc_info* info) -> int {
+            return MatchFastboot(info, device_serial);
+        };
+        for (int i = 0; i < MAX_USB_TRIES && !transport; i++) {
+            std::unique_ptr<UsbTransport> usb(usb_open(matcher, USB_TIMEOUT));
+            if (usb)
+                transport = std::unique_ptr<TransportSniffer>(
+                        new TransportSniffer(std::move(usb), serial_port));
+            std::this_thread::sleep_for(std::chrono::milliseconds(10));
+        }
     }
 
     ASSERT_TRUE(transport);  // no nullptr
@@ -154,6 +166,8 @@
 
 // TODO, this should eventually be piped to a file instead of stdout
 void FastBootTest::TearDownSerial() {
+    if (IsFastbootOverTcp()) return;
+
     if (!transport) return;
     // One last read from serial
     transport->ProcessSerial();
@@ -167,9 +181,34 @@
     }
 }
 
+void FastBootTest::ConnectTcpFastbootDevice() {
+    std::size_t found = device_serial.find(":");
+    if (found != std::string::npos) {
+        for (int i = 0; i < MAX_TCP_TRIES && !transport; i++) {
+            std::string error;
+            std::unique_ptr<Transport> tcp(
+                    tcp::Connect(device_serial.substr(0, found), tcp::kDefaultPort, &error)
+                            .release());
+            if (tcp)
+                transport =
+                        std::unique_ptr<TransportSniffer>(new TransportSniffer(std::move(tcp), 0));
+            if (transport != nullptr) break;
+            std::this_thread::sleep_for(std::chrono::milliseconds(10));
+        }
+    }
+}
+
 void FastBootTest::ReconnectFastbootDevice() {
     fb.reset();
     transport.reset();
+
+    if (IsFastbootOverTcp()) {
+        ConnectTcpFastbootDevice();
+        device_path = cb_scratch;
+        fb = std::unique_ptr<FastBootDriver>(new FastBootDriver(transport.get(), {}, true));
+        return;
+    }
+
     while (UsbStillAvailible())
         ;
     printf("WAITING FOR DEVICE\n");
@@ -180,8 +219,8 @@
     while (!transport) {
         std::unique_ptr<UsbTransport> usb(usb_open(matcher, USB_TIMEOUT));
         if (usb) {
-            transport = std::unique_ptr<UsbTransportSniffer>(
-                    new UsbTransportSniffer(std::move(usb), serial_port));
+            transport = std::unique_ptr<TransportSniffer>(
+                    new TransportSniffer(std::move(usb), serial_port));
         }
         std::this_thread::sleep_for(1s);
     }
diff --git a/fastboot/fuzzy_fastboot/fixtures.h b/fastboot/fuzzy_fastboot/fixtures.h
index c71c897..2468868 100644
--- a/fastboot/fuzzy_fastboot/fixtures.h
+++ b/fastboot/fuzzy_fastboot/fixtures.h
@@ -31,7 +31,7 @@
 #include "fastboot_driver.h"
 
 #include "extensions.h"
-#include "usb_transport_sniffer.h"
+#include "transport_sniffer.h"
 
 namespace fastboot {
 
@@ -45,11 +45,14 @@
     static int serial_port;
     static std::string device_serial;
     static constexpr int MAX_USB_TRIES = 10;
+    static constexpr int MAX_TCP_TRIES = 6000;
 
     static int MatchFastboot(usb_ifc_info* info, const std::string& local_serial = "");
+    static bool IsFastbootOverTcp();
     bool UsbStillAvailible();
     bool UserSpaceFastboot();
     void ReconnectFastbootDevice();
+    void ConnectTcpFastbootDevice();
 
   protected:
     RetCode DownloadCommand(uint32_t size, std::string* response = nullptr,
@@ -64,7 +67,7 @@
     void TearDownSerial();
     void SetLockState(bool unlock, bool assert_change = true);
 
-    std::unique_ptr<UsbTransportSniffer> transport;
+    std::unique_ptr<TransportSniffer> transport;
     std::unique_ptr<FastBootDriver> fb;
 
   private:
diff --git a/fastboot/fuzzy_fastboot/main.cpp b/fastboot/fuzzy_fastboot/main.cpp
index a1d69d2..b9784fe 100644
--- a/fastboot/fuzzy_fastboot/main.cpp
+++ b/fastboot/fuzzy_fastboot/main.cpp
@@ -54,7 +54,7 @@
 #include "extensions.h"
 #include "fixtures.h"
 #include "test_utils.h"
-#include "usb_transport_sniffer.h"
+#include "transport_sniffer.h"
 
 namespace fastboot {
 
@@ -1756,16 +1756,19 @@
     }
 
     setbuf(stdout, NULL);  // no buffering
-    printf("<Waiting for Device>\n");
-    const auto matcher = [](usb_ifc_info* info) -> int {
-        return fastboot::FastBootTest::MatchFastboot(info, fastboot::FastBootTest::device_serial);
-    };
-    Transport* transport = nullptr;
-    while (!transport) {
-        transport = usb_open(matcher);
-        std::this_thread::sleep_for(std::chrono::milliseconds(10));
+
+    if (!fastboot::FastBootTest::IsFastbootOverTcp()) {
+        printf("<Waiting for Device>\n");
+        const auto matcher = [](usb_ifc_info* info) -> int {
+            return fastboot::FastBootTest::MatchFastboot(info, fastboot::FastBootTest::device_serial);
+        };
+        Transport* transport = nullptr;
+        while (!transport) {
+            transport = usb_open(matcher);
+            std::this_thread::sleep_for(std::chrono::milliseconds(10));
+        }
+        transport->Close();
     }
-    transport->Close();
 
     if (args.find("serial_port") != args.end()) {
         fastboot::FastBootTest::serial_port = fastboot::ConfigureSerial(args.at("serial_port"));
diff --git a/fastboot/fuzzy_fastboot/usb_transport_sniffer.cpp b/fastboot/fuzzy_fastboot/transport_sniffer.cpp
similarity index 91%
rename from fastboot/fuzzy_fastboot/usb_transport_sniffer.cpp
rename to fastboot/fuzzy_fastboot/transport_sniffer.cpp
index 7c595f4..b55ffd3 100644
--- a/fastboot/fuzzy_fastboot/usb_transport_sniffer.cpp
+++ b/fastboot/fuzzy_fastboot/transport_sniffer.cpp
@@ -1,4 +1,4 @@
-#include "usb_transport_sniffer.h"
+#include "transport_sniffer.h"
 #include <android-base/stringprintf.h>
 #include <sys/select.h>
 #include <sys/time.h>
@@ -8,15 +8,15 @@
 
 namespace fastboot {
 
-UsbTransportSniffer::UsbTransportSniffer(std::unique_ptr<UsbTransport> transport,
+TransportSniffer::TransportSniffer(std::unique_ptr<Transport> transport,
                                          const int serial_fd)
     : transport_(std::move(transport)), serial_fd_(serial_fd) {}
 
-UsbTransportSniffer::~UsbTransportSniffer() {
+TransportSniffer::~TransportSniffer() {
     Close();
 }
 
-ssize_t UsbTransportSniffer::Read(void* data, size_t len) {
+ssize_t TransportSniffer::Read(void* data, size_t len) {
     ProcessSerial();
 
     ssize_t ret = transport_->Read(data, len);
@@ -37,7 +37,7 @@
     return ret;
 }
 
-ssize_t UsbTransportSniffer::Write(const void* data, size_t len) {
+ssize_t TransportSniffer::Write(const void* data, size_t len) {
     ProcessSerial();
 
     size_t ret = transport_->Write(data, len);
@@ -58,11 +58,11 @@
     return ret;
 }
 
-int UsbTransportSniffer::Close() {
+int TransportSniffer::Close() {
     return transport_->Close();
 }
 
-int UsbTransportSniffer::Reset() {
+int TransportSniffer::Reset() {
     ProcessSerial();
     int ret = transport_->Reset();
     std::vector<char> buf;
@@ -72,7 +72,7 @@
     return ret;
 }
 
-const std::vector<UsbTransportSniffer::Event> UsbTransportSniffer::Transfers() {
+const std::vector<TransportSniffer::Event> TransportSniffer::Transfers() {
     return transfers_;
 }
 
@@ -81,7 +81,7 @@
  * the failure. This method will look through its log of captured events, and
  * create a clean printable string of everything that happened.
  */
-std::string UsbTransportSniffer::CreateTrace() {
+std::string TransportSniffer::CreateTrace() {
     std::string ret;
 
     const auto no_print = [](char c) -> bool { return !isprint(c); };
@@ -158,7 +158,7 @@
 
 // This is a quick call to flush any UART logs the device might have sent
 // to our internal event log. It will wait up to 10ms for data to appear
-void UsbTransportSniffer::ProcessSerial() {
+void TransportSniffer::ProcessSerial() {
     if (serial_fd_ <= 0) return;
 
     fd_set set;
diff --git a/fastboot/fuzzy_fastboot/usb_transport_sniffer.h b/fastboot/fuzzy_fastboot/transport_sniffer.h
similarity index 90%
rename from fastboot/fuzzy_fastboot/usb_transport_sniffer.h
rename to fastboot/fuzzy_fastboot/transport_sniffer.h
index 8119aea..2cbb9fe 100644
--- a/fastboot/fuzzy_fastboot/usb_transport_sniffer.h
+++ b/fastboot/fuzzy_fastboot/transport_sniffer.h
@@ -42,12 +42,12 @@
 /* A special class for sniffing reads and writes
  *
  * A useful debugging tool is to see the raw fastboot transactions going between
- * the host and device. This class wraps the UsbTransport class, and snoops and saves
+ * the host and device. This class is a special subclass of Transport that snoops and saves
  * all the transactions going on. Additionally, if there is a console serial port
  * from the device, this class can monitor it as well and capture the interleaving of
  * transport transactions and UART log messages.
  */
-class UsbTransportSniffer : public UsbTransport {
+class TransportSniffer : public Transport {
   public:
     enum EventType {
         READ,
@@ -67,8 +67,8 @@
         const std::vector<char> buf;
     };
 
-    UsbTransportSniffer(std::unique_ptr<UsbTransport> transport, const int serial_fd = 0);
-    ~UsbTransportSniffer() override;
+    TransportSniffer(std::unique_ptr<Transport> transport, const int serial_fd = 0);
+    ~TransportSniffer() override;
 
     virtual ssize_t Read(void* data, size_t len) override;
     virtual ssize_t Write(const void* data, size_t len) override;
@@ -81,7 +81,7 @@
 
   private:
     std::vector<Event> transfers_;
-    std::unique_ptr<UsbTransport> transport_;
+    std::unique_ptr<Transport> transport_;
     const int serial_fd_;
 };
 
diff --git a/fastboot/tcp.cpp b/fastboot/tcp.cpp
index dd6fbf8..dca306f 100644
--- a/fastboot/tcp.cpp
+++ b/fastboot/tcp.cpp
@@ -64,6 +64,7 @@
     ssize_t Read(void* data, size_t length) override;
     ssize_t Write(const void* data, size_t length) override;
     int Close() override;
+    int Reset() override;
 
   private:
     explicit TcpTransport(std::unique_ptr<Socket> sock) : socket_(std::move(sock)) {}
@@ -178,6 +179,10 @@
     return result;
 }
 
+int TcpTransport::Reset() {
+    return 0;
+}
+
 std::unique_ptr<Transport> Connect(const std::string& hostname, int port, std::string* error) {
     return internal::Connect(Socket::NewClient(Socket::Protocol::kTcp, hostname, port, error),
                              error);
diff --git a/fastboot/transport.h b/fastboot/transport.h
index 96b90d2..de0cc92 100644
--- a/fastboot/transport.h
+++ b/fastboot/transport.h
@@ -36,6 +36,8 @@
     // Closes the underlying transport. Returns 0 on success.
     virtual int Close() = 0;
 
+    virtual int Reset() = 0;
+
     // Blocks until the transport disconnects. Transports that don't support
     // this will return immediately. Returns 0 on success.
     virtual int WaitForDisconnect() { return 0; }
diff --git a/fastboot/udp.cpp b/fastboot/udp.cpp
index 53fb347..308c96c 100644
--- a/fastboot/udp.cpp
+++ b/fastboot/udp.cpp
@@ -109,6 +109,7 @@
     ssize_t Read(void* data, size_t length) override;
     ssize_t Write(const void* data, size_t length) override;
     int Close() override;
+    int Reset() override;
 
   private:
     explicit UdpTransport(std::unique_ptr<Socket> socket) : socket_(std::move(socket)) {}
@@ -370,6 +371,10 @@
     return result;
 }
 
+int UdpTransport::Reset() {
+    return 0;
+}
+
 std::unique_ptr<Transport> Connect(const std::string& hostname, int port, std::string* error) {
     return internal::Connect(Socket::NewClient(Socket::Protocol::kUdp, hostname, port, error),
                              error);