Enable "localfilesystem" UNIX domain socket for ADB.

This patch introduce "service.adb.listen_addrs", a new
string type property, while keeping the old properties.
The new property added in this patch is used to listen
on UNIX domain socket "localfilesystem".

"service.adb.listen_addrs" can be used to listen on
multiple addresses, such as tcp:5555 and tcp:5556.
It is separated by ',' (comma) character.

In the process of introducing the new socket type, the
method tcp_connect is removed and combined into
socket_spec_connect.

Without specifying using the new property, adb will
try to listen on both tcp and vsock (following the
previous implementation).

Some examples of the new property value are:
  - "tcp:5555"
  - "vsock:5555"
  - "localfilesystem:/tmp/test"
  - "tcp:5555,vsock:5555"

Bug: 133378083
Test: On master-arc-dev:
        adb root;
        setprop service.adb.listen_addrs localfilesystem:
	    <path_to_socket>;
        adb connect localfilesystem:<path_to_socket>;
        adb -s localfilesystem:<path_to_socket> shell;
	    inside Chrome OS.
Test: On aosp_bluefin:
        setprop service.adb.listen_addr tcp:5555;
        adb connect <IP>:5555; adb shell;
Test: On aosp_bluefin:
        setprop service.adb.tcp.port 5555;
        adb connect <IP>:5555; adb shell;
Test: On aosp_bluefin:
        setprop service.adb.listen_addrs tcp:5555,tcp:6666;
        adb connect <IP>:5555; adb shell;
        adb connect <IP>:6666; adb shell;
Test: On aosp_bluefin:
        ./adb_test;
Test: On cuttlefish:
        launch_cvd;
        adb -s 127.0.0.1:6520 shell;
Test: Ran host tests:
        ./adb_test;
        ./adb_integration_test_adb;
        ./adb_integration_test_device;

Change-Id: I8289bf0ab3305cf23ce5695ffba46845d58ef6bb
diff --git a/adb/socket_spec.cpp b/adb/socket_spec.cpp
index 27e8c46..2d1ea56 100644
--- a/adb/socket_spec.cpp
+++ b/adb/socket_spec.cpp
@@ -119,6 +119,41 @@
     return true;
 }
 
+int get_host_socket_spec_port(std::string_view spec, std::string* error) {
+    int port;
+    if (spec.starts_with("tcp:")) {
+        if (!parse_tcp_socket_spec(spec, nullptr, &port, nullptr, error)) {
+            return -1;
+        }
+    } else if (spec.starts_with("vsock:")) {
+#if ADB_LINUX
+        std::string spec_str(spec);
+        std::vector<std::string> fragments = android::base::Split(spec_str, ":");
+        if (fragments.size() != 2) {
+            *error = "given vsock server socket string was invalid";
+            return -1;
+        }
+        if (!android::base::ParseInt(fragments[1], &port)) {
+            *error = "could not parse vsock port";
+            errno = EINVAL;
+            return -1;
+        }
+        if (port < 0) {
+            *error = "vsock port was negative.";
+            errno = EINVAL;
+            return -1;
+        }
+#else   // ADB_LINUX
+        *error = "vsock is only supported on linux";
+        return -1;
+#endif  // ADB_LINUX
+    } else {
+        *error = "given socket spec string was invalid";
+        return -1;
+    }
+    return port;
+}
+
 static bool tcp_host_is_local(std::string_view hostname) {
     // FIXME
     return hostname.empty() || hostname == "localhost";
@@ -248,6 +283,14 @@
 
             fd->reset(network_local_client(&address[prefix.length()], it.second.socket_namespace,
                                            SOCK_STREAM, error));
+
+            if (fd->get() < 0) {
+                *error =
+                        android::base::StringPrintf("could not connect to %s address '%s'",
+                                                    it.first.c_str(), std::string(address).c_str());
+                return false;
+            }
+
             if (serial) {
                 *serial = address;
             }
@@ -269,7 +312,11 @@
         }
 
         int result;
+#if ADB_HOST
         if (hostname.empty() && gListenAll) {
+#else
+        if (hostname.empty()) {
+#endif
             result = network_inaddr_any_server(port, SOCK_STREAM, error);
         } else if (tcp_host_is_local(hostname)) {
             result = network_loopback_server(port, SOCK_STREAM, error, true);