adb: allow selection of a specific transport.

Extend device selection to allow selecting a specific transport via
monotonically increasing identifier (visible in devices -l).

This is useful when using multiple devices (like hikey960...) that
have identical bogus serial numbers like 0123456789ABCDEF.

Bug: http://b/37043226
Test: adb -t {1, 2, 9999999} {get-serialno, shell, features}
Change-Id: I55e5dc5a406a4eeee0012e39b52e8cd232e608a6
diff --git a/adb/transport.h b/adb/transport.h
index 4a89ed9..238e959 100644
--- a/adb/transport.h
+++ b/adb/transport.h
@@ -54,14 +54,17 @@
 // The server supports `push --sync`.
 extern const char* const kFeaturePushSync;
 
+TransportId NextTransportId();
+
 class atransport {
-public:
+  public:
     // TODO(danalbert): We expose waaaaaaay too much stuff because this was
     // historically just a struct, but making the whole thing a more idiomatic
     // class in one go is a very large change. Given how bad our testing is,
     // it's better to do this piece by piece.
 
-    atransport(ConnectionState state = kCsOffline) : ref_count(0), connection_state_(state) {
+    atransport(ConnectionState state = kCsOffline)
+        : id(NextTransportId()), ref_count(0), connection_state_(state) {
         transport_fde = {};
         protocol_version = A_VERSION;
         max_payload = MAX_PAYLOAD;
@@ -72,12 +75,8 @@
     void (*close)(atransport* t) = nullptr;
 
     void SetWriteFunction(int (*write_func)(apacket*, atransport*)) { write_func_ = write_func; }
-    void SetKickFunction(void (*kick_func)(atransport*)) {
-        kick_func_ = kick_func;
-    }
-    bool IsKicked() {
-        return kicked_;
-    }
+    void SetKickFunction(void (*kick_func)(atransport*)) { kick_func_ = kick_func; }
+    bool IsKicked() { return kicked_; }
     int Write(apacket* p);
     void Kick();
 
@@ -85,6 +84,7 @@
     ConnectionState GetConnectionState() const;
     void SetConnectionState(ConnectionState state);
 
+    const TransportId id;
     int fd = -1;
     int transport_socket = -1;
     fdevent transport_fde;
@@ -191,12 +191,14 @@
 /*
  * Obtain a transport from the available transports.
  * If serial is non-null then only the device with that serial will be chosen.
+ * If transport_id is non-zero then only the device with that transport ID will be chosen.
  * If multiple devices/emulators would match, *is_ambiguous (if non-null)
  * is set to true and nullptr returned.
  * If no suitable transport is found, error is set and nullptr returned.
  */
-atransport* acquire_one_transport(TransportType type, const char* serial, bool* is_ambiguous,
-                                  std::string* error_out, bool accept_any_state = false);
+atransport* acquire_one_transport(TransportType type, const char* serial, TransportId transport_id,
+                                  bool* is_ambiguous, std::string* error_out,
+                                  bool accept_any_state = false);
 void kick_transport(atransport* t);
 void update_transports(void);