'adb pair' by mdns instance name.

Bug: 152886765

Test: Turn on wireless debugging > "Pair with Pairing Code". On client,
> adb pair <mdns_instance>

Change-Id: I8f15c3ea17f3ac02205064f64aca0167bf5d2ad5
diff --git a/adb/adb_wifi.h b/adb/adb_wifi.h
index 5113c15..42f414b 100644
--- a/adb/adb_wifi.h
+++ b/adb/adb_wifi.h
@@ -42,6 +42,7 @@
 };
 
 std::optional<MdnsInfo> mdns_get_connect_service_info(std::string_view name);
+std::optional<MdnsInfo> mdns_get_pairing_service_info(std::string_view name);
 
 #else  // !ADB_HOST
 
diff --git a/adb/client/adb_wifi.cpp b/adb/client/adb_wifi.cpp
index fa71028..61a9a48 100644
--- a/adb/client/adb_wifi.cpp
+++ b/adb/client/adb_wifi.cpp
@@ -179,17 +179,21 @@
 
 void adb_wifi_pair_device(const std::string& host, const std::string& password,
                           std::string& response) {
-    // Check the address for a valid address and port.
-    std::string parsed_host;
-    std::string err;
-    int port = -1;
-    if (!android::base::ParseNetAddress(host, &parsed_host, &port, nullptr, &err)) {
-        response = "Failed to parse address for pairing: " + err;
-        return;
-    }
-    if (port <= 0 || port > 65535) {
-        response = "Invalid port while parsing address [" + host + "]";
-        return;
+    auto mdns_info = mdns_get_pairing_service_info(host);
+
+    if (!mdns_info.has_value()) {
+        // Check the address for a valid address and port.
+        std::string parsed_host;
+        std::string err;
+        int port = -1;
+        if (!android::base::ParseNetAddress(host, &parsed_host, &port, nullptr, &err)) {
+            response = "Failed to parse address for pairing: " + err;
+            return;
+        }
+        if (port <= 0 || port > 65535) {
+            response = "Invalid port while parsing address [" + host + "]";
+            return;
+        }
     }
 
     auto priv_key = adb_auth_get_user_privkey();
@@ -220,7 +224,11 @@
 
     PairingResultWaiter waiter;
     std::unique_lock<std::mutex> lock(waiter.mutex_);
-    if (!client->Start(host, waiter.OnResult, &waiter)) {
+    if (!client->Start(mdns_info.has_value()
+                               ? android::base::StringPrintf("%s:%d", mdns_info->addr.c_str(),
+                                                             mdns_info->port)
+                               : host,
+                       waiter.OnResult, &waiter)) {
         response = "Failed: Unable to start pairing client.";
         return;
     }
diff --git a/adb/client/transport_mdns.cpp b/adb/client/transport_mdns.cpp
index f8c9de3..35e2c6d 100644
--- a/adb/client/transport_mdns.cpp
+++ b/adb/client/transport_mdns.cpp
@@ -720,3 +720,34 @@
 
     return std::nullopt;
 }
+
+std::optional<MdnsInfo> mdns_get_pairing_service_info(std::string_view name) {
+    CHECK(!name.empty());
+
+    auto mdns_instance = mdns::mdns_parse_instance_name(name);
+    if (!mdns_instance.has_value()) {
+        D("Failed to parse mDNS pairing name [%s]", name.data());
+        return std::nullopt;
+    }
+
+    std::optional<MdnsInfo> info;
+    auto cb = [&](const char* service_name, const char* reg_type, const char* ip_addr,
+                  uint16_t port) { info.emplace(service_name, reg_type, ip_addr, port); };
+
+    // Verify it's a pairing service if user explicitly inputs it.
+    if (!mdns_instance->service_name.empty()) {
+        auto reg_type = android::base::StringPrintf("%s.%s", mdns_instance->service_name.data(),
+                                                    mdns_instance->transport_type.data());
+        int index = adb_DNSServiceIndexByName(reg_type);
+        switch (index) {
+            case kADBSecurePairingServiceRefIndex:
+                break;
+            default:
+                D("Not an adb pairing reg_type [%s]", reg_type.data());
+                return std::nullopt;
+        }
+    }
+
+    ResolvedService::forEachService(*ResolvedService::sAdbSecurePairingServices, name, cb);
+    return info;
+}