diff --git a/adb/.clang-format b/adb/.clang-format
deleted file mode 120000
index 1af4f51..0000000
--- a/adb/.clang-format
+++ /dev/null
@@ -1 +0,0 @@
-../.clang-format-4
\ No newline at end of file
diff --git a/adb/Android.bp b/adb/Android.bp
deleted file mode 100644
index dee48bf..0000000
--- a/adb/Android.bp
+++ /dev/null
@@ -1,821 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-cc_defaults {
-    name: "adb_defaults",
-
-    cflags: [
-        "-Wall",
-        "-Wextra",
-        "-Werror",
-        "-Wexit-time-destructors",
-        "-Wno-unused-parameter",
-        "-Wno-missing-field-initializers",
-        "-Wthread-safety",
-        "-Wvla",
-        "-DADB_HOST=1",         // overridden by adbd_defaults
-        "-DANDROID_BASE_UNIQUE_FD_DISABLE_IMPLICIT_CONVERSION=1",
-    ],
-    cpp_std: "experimental",
-
-    use_version_lib: true,
-    compile_multilib: "first",
-
-    target: {
-        darwin: {
-            host_ldlibs: [
-                "-lpthread",
-                "-framework CoreFoundation",
-                "-framework IOKit",
-                "-lobjc",
-            ],
-        },
-
-        windows: {
-            cflags: [
-                // Define windows.h and tchar.h Unicode preprocessor symbols so that
-                // CreateFile(), _tfopen(), etc. map to versions that take wchar_t*, breaking the
-                // build if you accidentally pass char*. Fix by calling like:
-                //   std::wstring path_wide;
-                //   if (!android::base::UTF8ToWide(path_utf8, &path_wide)) { /* error handling */ }
-                //   CreateFileW(path_wide.c_str());
-                "-DUNICODE=1",
-                "-D_UNICODE=1",
-
-                // Unlike on Linux, -std=gnu++ doesn't set _GNU_SOURCE on Windows.
-                "-D_GNU_SOURCE",
-
-                // MinGW hides some things behind _POSIX_SOURCE.
-                "-D_POSIX_SOURCE",
-
-                // libusb uses __stdcall on a variadic function, which gets ignored.
-                "-Wno-ignored-attributes",
-
-                // Not supported yet.
-                "-Wno-thread-safety",
-            ],
-
-            host_ldlibs: [
-                "-lws2_32",
-                "-lgdi32",
-                "-luserenv",
-            ],
-        },
-    },
-}
-
-cc_defaults {
-    name: "adbd_defaults",
-    defaults: ["adb_defaults"],
-
-    cflags: ["-UADB_HOST", "-DADB_HOST=0"],
-}
-
-cc_defaults {
-    name: "host_adbd_supported",
-
-    host_supported: true,
-    target: {
-        linux: {
-            enabled: true,
-            host_ldlibs: [
-                "-lresolv", // b64_pton
-                "-lutil", // forkpty
-            ],
-        },
-        darwin: {
-            enabled: false,
-        },
-        windows: {
-            enabled: false,
-        },
-    },
-}
-
-cc_defaults {
-    name: "libadbd_binary_dependencies",
-    static_libs: [
-        "libadb_crypto",
-        "libadb_pairing_connection",
-        "libadb_tls_connection",
-        "libadbd",
-        "libadbd_core",
-        "libadbconnection_server",
-        "libasyncio",
-        "libbrotli",
-        "libcutils_sockets",
-        "libdiagnose_usb",
-        "libmdnssd",
-        "libbase",
-
-        "libadb_protos",
-    ],
-
-    shared_libs: [
-        "libadbd_auth",
-        "libadbd_fs",
-        "libcrypto",
-        "libcrypto_utils",
-        "liblog",
-        "libselinux",
-    ],
-
-    target: {
-        recovery: {
-            exclude_static_libs: [
-                "libadb_pairing_auth",
-                "libadb_pairing_connection",
-            ],
-        },
-    },
-}
-
-// libadb
-// =========================================================
-// These files are compiled for both the host and the device.
-libadb_srcs = [
-    "adb.cpp",
-    "adb_io.cpp",
-    "adb_listeners.cpp",
-    "adb_trace.cpp",
-    "adb_unique_fd.cpp",
-    "adb_utils.cpp",
-    "fdevent/fdevent.cpp",
-    "fdevent/fdevent_poll.cpp",
-    "services.cpp",
-    "sockets.cpp",
-    "socket_spec.cpp",
-    "sysdeps/errno.cpp",
-    "transport.cpp",
-    "transport_fd.cpp",
-    "transport_local.cpp",
-    "types.cpp",
-]
-
-libadb_posix_srcs = [
-    "sysdeps_unix.cpp",
-    "sysdeps/posix/network.cpp",
-]
-
-libadb_linux_srcs = [
-    "fdevent/fdevent_epoll.cpp",
-]
-
-libadb_test_srcs = [
-    "adb_io_test.cpp",
-    "adb_listeners_test.cpp",
-    "adb_utils_test.cpp",
-    "fdevent/fdevent_test.cpp",
-    "socket_spec_test.cpp",
-    "socket_test.cpp",
-    "sysdeps_test.cpp",
-    "sysdeps/stat_test.cpp",
-    "transport_test.cpp",
-    "types_test.cpp",
-]
-
-cc_library_host_static {
-    name: "libadb_host",
-    defaults: ["adb_defaults"],
-
-    srcs: libadb_srcs + [
-        "client/auth.cpp",
-        "client/adb_wifi.cpp",
-        "client/usb_libusb.cpp",
-        "client/usb_dispatch.cpp",
-        "client/transport_mdns.cpp",
-        "client/transport_usb.cpp",
-        "client/pairing/pairing_client.cpp",
-    ],
-
-    generated_headers: ["platform_tools_version"],
-
-    target: {
-        linux: {
-            srcs: ["client/usb_linux.cpp"] + libadb_linux_srcs,
-        },
-        darwin: {
-            srcs: ["client/usb_osx.cpp"],
-        },
-        not_windows: {
-            srcs: libadb_posix_srcs,
-        },
-        windows: {
-            enabled: true,
-            srcs: [
-                "client/usb_windows.cpp",
-                "sysdeps_win32.cpp",
-                "sysdeps/win32/errno.cpp",
-                "sysdeps/win32/stat.cpp",
-            ],
-            shared_libs: ["AdbWinApi"],
-        },
-    },
-
-    static_libs: [
-        "libadb_crypto",
-        "libadb_protos",
-        "libadb_pairing_connection",
-        "libadb_tls_connection",
-        "libbase",
-        "libcrypto_utils",
-        "libcrypto",
-        "libdiagnose_usb",
-        "libmdnssd",
-        "libusb",
-        "libutils",
-        "liblog",
-        "libcutils",
-        "libprotobuf-cpp-lite",
-    ],
-}
-
-cc_test_host {
-    name: "adb_test",
-    defaults: ["adb_defaults"],
-    srcs: libadb_test_srcs,
-    static_libs: [
-        "libadb_crypto_static",
-        "libadb_host",
-        "libadb_pairing_auth_static",
-        "libadb_pairing_connection_static",
-        "libadb_protos_static",
-        "libadb_tls_connection_static",
-        "libbase",
-        "libcutils",
-        "libcrypto_utils",
-        "libcrypto",
-        "liblog",
-        "libmdnssd",
-        "libdiagnose_usb",
-        "libprotobuf-cpp-lite",
-        "libssl",
-        "libusb",
-    ],
-
-    target: {
-        windows: {
-            enabled: true,
-            ldflags: ["-municode"],
-            shared_libs: ["AdbWinApi"],
-        },
-    },
-}
-
-cc_binary_host {
-    name: "adb",
-
-    stl: "libc++_static",
-    defaults: ["adb_defaults"],
-
-    srcs: [
-        "client/adb_client.cpp",
-        "client/bugreport.cpp",
-        "client/commandline.cpp",
-        "client/file_sync_client.cpp",
-        "client/main.cpp",
-        "client/console.cpp",
-        "client/adb_install.cpp",
-        "client/line_printer.cpp",
-        "client/fastdeploy.cpp",
-        "client/fastdeploycallbacks.cpp",
-        "client/incremental.cpp",
-        "client/incremental_server.cpp",
-        "client/incremental_utils.cpp",
-        "shell_service_protocol.cpp",
-    ],
-
-    generated_headers: [
-        "bin2c_fastdeployagent",
-        "bin2c_fastdeployagentscript"
-    ],
-
-    static_libs: [
-        "libadb_crypto",
-        "libadb_host",
-	"libadb_pairing_auth",
-	"libadb_pairing_connection",
-        "libadb_protos",
-        "libadb_tls_connection",
-        "libandroidfw",
-        "libbase",
-        "libbrotli",
-        "libcutils",
-        "libcrypto_utils",
-        "libcrypto",
-        "libfastdeploy_host",
-        "libdiagnose_usb",
-        "liblog",
-        "liblz4",
-        "libmdnssd",
-        "libprotobuf-cpp-lite",
-        "libssl",
-        "libusb",
-        "libutils",
-        "liblog",
-        "libziparchive",
-        "libz",
-    ],
-
-    // Don't add anything here, we don't want additional shared dependencies
-    // on the host adb tool, and shared libraries that link against libc++
-    // will violate ODR
-    shared_libs: [],
-
-    // Archive adb, adb.exe.
-    dist: {
-        targets: [
-            "dist_files",
-            "sdk",
-            "win_sdk",
-        ],
-    },
-
-    target: {
-        darwin: {
-            cflags: [
-                "-Wno-sizeof-pointer-memaccess",
-            ],
-        },
-        windows: {
-            enabled: true,
-            ldflags: ["-municode"],
-            shared_libs: ["AdbWinApi"],
-            required: [
-                "AdbWinUsbApi",
-            ],
-        },
-    },
-}
-
-// libadbd_core contains the common sources to build libadbd and libadbd_services.
-cc_library_static {
-    name: "libadbd_core",
-    defaults: ["adbd_defaults", "host_adbd_supported"],
-    recovery_available: true,
-
-    // libminadbd wants both, as it's used to build native tests.
-    compile_multilib: "both",
-
-    srcs: libadb_srcs + libadb_linux_srcs + libadb_posix_srcs + [
-        "daemon/auth.cpp",
-        "daemon/jdwp_service.cpp",
-        "daemon/logging.cpp",
-        "daemon/adb_wifi.cpp",
-    ],
-
-    generated_headers: ["platform_tools_version"],
-
-    static_libs: [
-        "libadbconnection_server",
-        "libdiagnose_usb",
-    ],
-
-    shared_libs: [
-        "libadb_crypto",
-        "libadb_pairing_connection",
-        "libadb_protos",
-        "libadb_tls_connection",
-        "libadbd_auth",
-        "libasyncio",
-        "libbase",
-        "libcrypto",
-        "libcrypto_utils",
-        "libcutils_sockets",
-        "liblog",
-    ],
-
-    target: {
-        android: {
-            whole_static_libs: [
-                "libqemu_pipe",
-            ],
-            srcs: [
-                "daemon/transport_qemu.cpp",
-                "daemon/usb.cpp",
-                "daemon/usb_ffs.cpp",
-            ]
-        },
-        recovery: {
-            exclude_shared_libs: [
-                "libadb_pairing_auth",
-                "libadb_pairing_connection",
-            ],
-        }
-    },
-
-    apex_available: [
-        "//apex_available:platform",
-        "com.android.adbd",
-    ],
-    visibility: [
-        "//bootable/recovery/minadbd",
-        "//system/core/adb",
-    ],
-}
-
-cc_library {
-    name: "libadbd_services",
-    defaults: ["adbd_defaults", "host_adbd_supported"],
-    recovery_available: true,
-    compile_multilib: "both",
-
-    srcs: [
-        "daemon/file_sync_service.cpp",
-        "daemon/services.cpp",
-        "daemon/shell_service.cpp",
-        "shell_service_protocol.cpp",
-    ],
-
-    cflags: [
-        "-D_GNU_SOURCE",
-        "-Wno-deprecated-declarations",
-    ],
-
-    static_libs: [
-        "libadbconnection_server",
-        "libadbd_core",
-        "libbrotli",
-        "libdiagnose_usb",
-    ],
-
-    shared_libs: [
-        "libadb_crypto",
-        "libadb_pairing_connection",
-        "libadb_protos",
-        "libadb_tls_connection",
-        "libasyncio",
-        "libbase",
-        "libcrypto_utils",
-        "libcutils_sockets",
-
-        // APEX dependencies.
-        "libadbd_auth",
-        "libadbd_fs",
-        "libcrypto",
-        "liblog",
-    ],
-
-    target: {
-        android: {
-            srcs: [
-                "daemon/abb_service.cpp",
-                "daemon/framebuffer_service.cpp",
-                "daemon/mdns.cpp",
-                "daemon/restart_service.cpp",
-            ],
-            shared_libs: [
-                "libmdnssd",
-                "libselinux",
-            ],
-        },
-        recovery: {
-            exclude_srcs: [
-                "daemon/abb_service.cpp",
-            ],
-            exclude_shared_libs: [
-                "libadb_pairing_auth",
-                "libadb_pairing_connection",
-            ],
-        },
-    },
-
-    apex_available: [
-        "//apex_available:platform",
-        "com.android.adbd",
-    ],
-    visibility: [
-        "//system/core/adb",
-    ],
-
-}
-
-cc_library {
-    name: "libadbd",
-    defaults: ["adbd_defaults", "host_adbd_supported"],
-    recovery_available: true,
-    apex_available: ["com.android.adbd"],
-
-    // avoid getting duplicate symbol of android::build::getbuildnumber().
-    use_version_lib: false,
-
-    // libminadbd wants both, as it's used to build native tests.
-    compile_multilib: "both",
-
-    shared_libs: [
-        "libadb_crypto",
-        "libadb_pairing_connection",
-        "libadb_tls_connection",
-        "libasyncio",
-        "libbase",
-        "libcrypto",
-        "libcrypto_utils",
-        "liblog",
-        "libselinux",
-
-        // APEX dependencies on the system image.
-        "libadbd_auth",
-        "libadbd_fs",
-        "libadbd_services",
-    ],
-
-    target: {
-        recovery: {
-            exclude_shared_libs: [
-                "libadb_pairing_auth",
-                "libadb_pairing_connection",
-            ],
-        }
-    },
-
-    static_libs: [
-        "libadbd_core",
-        "libbrotli",
-        "libcutils_sockets",
-        "libdiagnose_usb",
-        "libmdnssd",
-    ],
-
-    visibility: [
-        "//bootable/recovery/minadbd",
-        "//system/core/adb",
-    ],
-}
-
-cc_binary {
-    name: "adbd",
-    defaults: ["adbd_defaults", "host_adbd_supported", "libadbd_binary_dependencies"],
-    recovery_available: true,
-    apex_available: ["com.android.adbd"],
-
-    srcs: [
-        "daemon/main.cpp",
-    ],
-
-    cflags: [
-        "-D_GNU_SOURCE",
-        "-Wno-deprecated-declarations",
-    ],
-
-    strip: {
-        keep_symbols: true,
-    },
-
-    static_libs: [
-        "libadbd",
-        "libadbd_services",
-        "libasyncio",
-        "libcap",
-        "libminijail",
-        "libssl",
-    ],
-
-    shared_libs: [
-        "libadb_protos",
-        "libadbd_auth",
-    ],
-
-    target: {
-        recovery: {
-            exclude_shared_libs: [
-                "libadb_pairing_auth",
-                "libadb_pairing_connection",
-            ],
-        }
-    },
-}
-
-phony {
-    // Interface between adbd in a module and the system.
-    name: "adbd_system_api",
-    required: [
-        "libadbd_auth",
-        "libadbd_fs",
-        "abb",
-        "reboot",
-        "set-verity-state",
-    ]
-}
-
-phony {
-    name: "adbd_system_api_recovery",
-    required: [
-        "libadbd_auth",
-        "libadbd_fs",
-        "reboot.recovery",
-    ],
-}
-
-cc_binary {
-    name: "abb",
-
-    defaults: ["adbd_defaults"],
-    stl: "libc++",
-    recovery_available: false,
-
-    srcs: [
-        "daemon/abb.cpp",
-    ],
-
-    cflags: [
-        "-D_GNU_SOURCE",
-        "-Wno-deprecated-declarations",
-    ],
-
-    strip: {
-        keep_symbols: true,
-    },
-
-    static_libs: [
-        "libadbd_core",
-        "libadbd_services",
-        "libcmd",
-    ],
-
-    shared_libs: [
-        "libbase",
-        "libbinder",
-        "liblog",
-        "libutils",
-        "libselinux",
-    ],
-}
-
-cc_test {
-    name: "adbd_test",
-
-    defaults: ["adbd_defaults", "libadbd_binary_dependencies"],
-
-    recovery_available: false,
-    srcs: libadb_test_srcs + [
-        "daemon/services.cpp",
-        "daemon/shell_service.cpp",
-        "daemon/shell_service_test.cpp",
-        "shell_service_protocol.cpp",
-        "shell_service_protocol_test.cpp",
-        "mdns_test.cpp",
-    ],
-
-    test_config: "adb_test.xml",
-
-    shared_libs: [
-        "liblog",
-    ],
-
-    static_libs: [
-        "libadbd",
-        "libadbd_auth",
-        "libbase",
-        "libcrypto_utils",
-        "libusb",
-    ],
-    test_suites: ["device-tests", "mts"],
-    require_root: true,
-}
-
-python_test_host {
-    name: "adb_integration_test_adb",
-    main: "test_adb.py",
-    srcs: [
-        "test_adb.py",
-    ],
-    test_config: "adb_integration_test_adb.xml",
-    test_suites: ["general-tests"],
-    version: {
-        py2: {
-            enabled: false,
-        },
-        py3: {
-            enabled: true,
-        },
-    },
-}
-
-python_test_host {
-    name: "adb_integration_test_device",
-    main: "test_device.py",
-    srcs: [
-        "test_device.py",
-    ],
-    libs: [
-        "adb_py",
-    ],
-    test_config: "adb_integration_test_device.xml",
-    test_suites: ["general-tests"],
-    version: {
-        py2: {
-            enabled: false,
-        },
-        py3: {
-            enabled: true,
-        },
-    },
-}
-
-// Note: using pipe for xxd to control the variable name generated
-// the default name used by xxd is the path to the input file.
-java_genrule {
-    name: "bin2c_fastdeployagent",
-    out: ["deployagent.inc"],
-    srcs: [":deployagent"],
-    cmd: "(echo 'unsigned char kDeployAgent[] = {' && xxd -i <$(in) && echo '};') > $(out)",
-}
-
-genrule {
-    name: "bin2c_fastdeployagentscript",
-    out: ["deployagentscript.inc"],
-    srcs: ["fastdeploy/deployagent/deployagent.sh"],
-    cmd: "(echo 'unsigned char kDeployAgentScript[] = {' && xxd -i <$(in) && echo '};') > $(out)",
-}
-
-cc_library_host_static {
-    name: "libfastdeploy_host",
-    defaults: ["adb_defaults"],
-    srcs: [
-        "fastdeploy/deploypatchgenerator/apk_archive.cpp",
-        "fastdeploy/deploypatchgenerator/deploy_patch_generator.cpp",
-        "fastdeploy/deploypatchgenerator/patch_utils.cpp",
-        "fastdeploy/proto/ApkEntry.proto",
-    ],
-    static_libs: [
-        "libadb_host",
-        "libandroidfw",
-        "libbase",
-        "libcutils",
-        "libcrypto_utils",
-        "libcrypto",
-        "libdiagnose_usb",
-        "liblog",
-        "libmdnssd",
-        "libusb",
-        "libutils",
-        "libziparchive",
-        "libz",
-    ],
-    proto: {
-        type: "lite",
-        export_proto_headers: true,
-    },
-    target: {
-        windows: {
-            enabled: true,
-            shared_libs: ["AdbWinApi"],
-        },
-    },
-}
-
-cc_test_host {
-    name: "fastdeploy_test",
-    defaults: ["adb_defaults"],
-    srcs: [
-        "fastdeploy/deploypatchgenerator/apk_archive_test.cpp",
-        "fastdeploy/deploypatchgenerator/deploy_patch_generator_test.cpp",
-        "fastdeploy/deploypatchgenerator/patch_utils_test.cpp",
-    ],
-    static_libs: [
-        "libadb_crypto_static",
-        "libadb_host",
-        "libadb_pairing_auth_static",
-        "libadb_pairing_connection_static",
-        "libadb_protos_static",
-        "libadb_tls_connection_static",
-        "libandroidfw",
-        "libbase",
-        "libcutils",
-        "libcrypto_utils",
-        "libcrypto",
-        "libdiagnose_usb",
-        "libfastdeploy_host",
-        "liblog",
-        "libmdnssd",
-        "libprotobuf-cpp-lite",
-        "libssl",
-        "libusb",
-        "libutils",
-        "libziparchive",
-        "libz",
-    ],
-    target: {
-        windows: {
-            enabled: true,
-            shared_libs: ["AdbWinApi"],
-        },
-    },
-    data: [
-        "fastdeploy/testdata/rotating_cube-metadata-release.data",
-        "fastdeploy/testdata/rotating_cube-release.apk",
-        "fastdeploy/testdata/sample.apk",
-        "fastdeploy/testdata/sample.cd",
-    ],
-}
diff --git a/adb/MODULE_LICENSE_APACHE2 b/adb/MODULE_LICENSE_APACHE2
deleted file mode 100644
index e69de29..0000000
--- a/adb/MODULE_LICENSE_APACHE2
+++ /dev/null
diff --git a/adb/NOTICE b/adb/NOTICE
deleted file mode 100644
index 9ffcc08..0000000
--- a/adb/NOTICE
+++ /dev/null
@@ -1,191 +0,0 @@
-
-   Copyright (c) 2006-2009, The Android Open Source Project
-   Copyright 2006, Brian Swetland <swetland@frotz.net>
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
-
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
diff --git a/adb/OVERVIEW.TXT b/adb/OVERVIEW.TXT
deleted file mode 100644
index f0b184c..0000000
--- a/adb/OVERVIEW.TXT
+++ /dev/null
@@ -1,135 +0,0 @@
-Implementation notes regarding ADB.
-
-I. General Overview:
-
-The Android Debug Bridge (ADB) is used to:
-
-- keep track of all Android devices and emulators instances
-  connected to or running on a given host developer machine
-
-- implement various control commands (e.g. "adb shell", "adb pull", etc.)
-  for the benefit of clients (command-line users, or helper programs like
-  DDMS). These commands are called 'services' in ADB.
-
-As a whole, everything works through the following components:
-
-  1. The ADB server
-
-    This is a background process that runs on the host machine. Its purpose
-    is to sense the USB ports to know when devices are attached/removed,
-    as well as when emulator instances start/stop.
-
-    It thus maintains a list of "connected devices" and assigns a 'state'
-    to each one of them: OFFLINE, BOOTLOADER, RECOVERY or ONLINE (more on
-    this below).
-
-    The ADB server is really one giant multiplexing loop whose purpose is
-    to orchestrate the exchange of data (packets, really) between clients,
-    services and devices.
-
-
-  2. The ADB daemon (adbd)
-
-    The 'adbd' program runs as a background process within an Android device
-    or emulated system. Its purpose is to connect to the ADB server
-    (through USB for devices, through TCP for emulators) and provide a
-    few services for clients that run on the host.
-
-    The ADB server considers that a device is ONLINE when it has successfully
-    connected to the adbd program within it. Otherwise, the device is OFFLINE,
-    meaning that the ADB server detected a new device/emulator, but could not
-    connect to the adbd daemon.
-
-    The BOOTLOADER and RECOVERY states correspond to alternate states of
-    devices when they are in the bootloader or recovery mode.
-
-  3. The ADB command-line client
-
-    The 'adb' command-line program is used to run adb commands from a shell
-    or a script. It first tries to locate the ADB server on the host machine,
-    and will start one automatically if none is found.
-
-    Then, the client sends its service requests to the ADB server.
-
-    Currently, a single 'adb' binary is used for both the server and client.
-    this makes distribution and starting the server easier.
-
-
-  4. Services
-
-    There are essentially two kinds of services that a client can talk to.
-
-    Host Services:
-      These services run within the ADB Server and thus do not need to
-      communicate with a device at all. A typical example is "adb devices"
-      which is used to return the list of currently known devices and their
-      states. They are a few other services though.
-
-    Local Services:
-      These services either run within the adbd daemon, or are started by
-      it on the device. The ADB server is used to multiplex streams
-      between the client and the service running in adbd. In this case
-      its role is to initiate the connection, then of being a pass-through
-      for the data.
-
-
-II. Protocol details:
-
-  1. Client <-> Server protocol:
-
-    This details the protocol used between ADB clients and the ADB
-    server itself. The ADB server listens on TCP:localhost:5037.
-
-    A client sends a request using the following format:
-
-        1. A 4-byte hexadecimal string giving the length of the payload
-        2. Followed by the payload itself.
-
-    For example, to query the ADB server for its internal version number,
-    the client will do the following:
-
-        1. Connect to tcp:localhost:5037
-        2. Send the string "000Chost:version" to the corresponding socket
-
-    The 'host:' prefix is used to indicate that the request is addressed
-    to the server itself (we will talk about other kinds of requests later).
-    The content length is encoded in ASCII for easier debugging.
-
-    The server should answer a request with one of the following:
-
-        1. For success, the 4-byte "OKAY" string
-
-        2. For failure, the 4-byte "FAIL" string, followed by a
-           4-byte hex length, followed by a string giving the reason
-           for failure.
-
-    Note that the connection is still alive after an OKAY, which allows the
-    client to make other requests. But in certain cases, an OKAY will even
-    change the state of the connection.
-
-    For example, the case of the 'host:transport:<serialnumber>' request,
-    where '<serialnumber>' is used to identify a given device/emulator; after
-    the "OKAY" answer, all further requests made by the client will go
-    directly to the corresponding adbd daemon.
-
-    The file SERVICES.TXT lists all services currently implemented by ADB.
-
-
-  2. Transports:
-
-    An ADB transport models a connection between the ADB server and one device
-    or emulator. There are currently two kinds of transports:
-
-       - USB transports, for physical devices through USB
-
-       - Local transports, for emulators running on the host, connected to
-         the server through TCP
-
-    In theory, it should be possible to write a local transport that proxies
-    a connection between an ADB server and a device/emulator connected to/
-    running on another machine. This hasn't been done yet though.
-
-    Each transport can carry one or more multiplexed streams between clients
-    and the device/emulator they point to. The ADB server must handle
-    unexpected transport disconnections (e.g. when a device is physically
-    unplugged) properly.
diff --git a/adb/OWNERS b/adb/OWNERS
deleted file mode 100644
index 643b448..0000000
--- a/adb/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-jmgao@google.com
-yabinc@google.com
diff --git a/adb/SERVICES.TXT b/adb/SERVICES.TXT
deleted file mode 100644
index 3e18a54..0000000
--- a/adb/SERVICES.TXT
+++ /dev/null
@@ -1,255 +0,0 @@
-This file tries to document all requests a client can make
-to the ADB server of an adbd daemon. See the OVERVIEW.TXT document
-to understand what's going on here.
-
-HOST SERVICES:
-
-host:version
-    Ask the ADB server for its internal version number.
-
-host:kill
-    Ask the ADB server to quit immediately. This is used when the
-    ADB client detects that an obsolete server is running after an
-    upgrade.
-
-host:devices
-host:devices-l
-    Ask to return the list of available Android devices and their
-    state. devices-l includes the device paths in the state.
-    After the OKAY, this is followed by a 4-byte hex len,
-    and a string that will be dumped as-is by the client, then
-    the connection is closed
-
-host:track-devices
-    This is a variant of host:devices which doesn't close the
-    connection. Instead, a new device list description is sent
-    each time a device is added/removed or the state of a given
-    device changes (hex4 + content). This allows tools like DDMS
-    to track the state of connected devices in real-time without
-    polling the server repeatedly.
-
-host:emulator:<port>
-    This is a special query that is sent to the ADB server when a
-    new emulator starts up. <port> is a decimal number corresponding
-    to the emulator's ADB control port, i.e. the TCP port that the
-    emulator will forward automatically to the adbd daemon running
-    in the emulator system.
-
-    This mechanism allows the ADB server to know when new emulator
-    instances start.
-
-host:transport:<serial-number>
-    Ask to switch the connection to the device/emulator identified by
-    <serial-number>. After the OKAY response, every client request will
-    be sent directly to the adbd daemon running on the device.
-    (Used to implement the -s option)
-
-host:transport-usb
-    Ask to switch the connection to one device connected through USB
-    to the host machine. This will fail if there are more than one such
-    devices. (Used to implement the -d convenience option)
-
-host:transport-local
-    Ask to switch the connection to one emulator connected through TCP.
-    This will fail if there is more than one such emulator instance
-    running. (Used to implement the -e convenience option)
-
-host:transport-any
-    Another host:transport variant. Ask to switch the connection to
-    either the device or emulator connect to/running on the host.
-    Will fail if there is more than one such device/emulator available.
-    (Used when neither -s, -d or -e are provided)
-
-host-serial:<serial-number>:<request>
-    This is a special form of query, where the 'host-serial:<serial-number>:'
-    prefix can be used to indicate that the client is asking the ADB server
-    for information related to a specific device. <request> can be in one
-    of the format described below.
-
-host-usb:<request>
-    A variant of host-serial used to target the single USB device connected
-    to the host. This will fail if there is none or more than one.
-
-host-local:<request>
-    A variant of host-serial used to target the single emulator instance
-    running on the host. This will fail if there is none or more than one.
-
-host:<request>
-    When asking for information related to a device, 'host:' can also be
-    interpreted as 'any single device or emulator connected to/running on
-    the host'.
-
-<host-prefix>:get-product
-    XXX
-
-<host-prefix>:get-serialno
-    Returns the serial number of the corresponding device/emulator.
-    Note that emulator serial numbers are of the form "emulator-5554"
-
-<host-prefix>:get-devpath
-    Returns the device path of the corresponding device/emulator.
-
-<host-prefix>:get-state
-    Returns the state of a given device as a string.
-
-<host-prefix>:forward:<local>;<remote>
-    Asks the ADB server to forward local connections from <local>
-    to the <remote> address on a given device.
-
-    There, <host-prefix> can be one of the
-    host-serial/host-usb/host-local/host prefixes as described previously
-    and indicates which device/emulator to target.
-
-    the format of <local> is one of:
-
-        tcp:<port>      -> TCP connection on localhost:<port>
-        local:<path>    -> Unix local domain socket on <path>
-
-    the format of <remote> is one of:
-
-        tcp:<port>      -> TCP localhost:<port> on device
-        local:<path>    -> Unix local domain socket on device
-        jdwp:<pid>      -> JDWP thread on VM process <pid>
-
-    or even any one of the local services described below.
-
-<host-prefix>:forward:norebind:<local>;<remote>
-    Same as <host-prefix>:forward:<local>;<remote> except that it will
-    fail it there is already a forward connection from <local>.
-
-    Used to implement 'adb forward --no-rebind <local> <remote>'
-
-<host-prefix>:killforward:<local>
-    Remove any existing forward local connection from <local>.
-    This is used to implement 'adb forward --remove <local>'
-
-<host-prefix>:killforward-all
-    Remove all forward network connections.
-    This is used to implement 'adb forward --remove-all'.
-
-<host-prefix>:list-forward
-    List all existing forward connections from this server.
-    This returns something that looks like the following:
-
-       <hex4>: The length of the payload, as 4 hexadecimal chars.
-       <payload>: A series of lines of the following format:
-
-         <serial> " " <local> " " <remote> "\n"
-
-    Where <serial> is a device serial number.
-          <local>  is the host-specific endpoint (e.g. tcp:9000).
-          <remote> is the device-specific endpoint.
-
-    Used to implement 'adb forward --list'.
-
-LOCAL SERVICES:
-
-All the queries below assumed that you already switched the transport
-to a real device, or that you have used a query prefix as described
-above.
-
-shell:command arg1 arg2 ...
-    Run 'command arg1 arg2 ...' in a shell on the device, and return
-    its output and error streams. Note that arguments must be separated
-    by spaces. If an argument contains a space, it must be quoted with
-    double-quotes. Arguments cannot contain double quotes or things
-    will go very wrong.
-
-    Note that this is the non-interactive version of "adb shell"
-
-shell:
-    Start an interactive shell session on the device. Redirect
-    stdin/stdout/stderr as appropriate. Note that the ADB server uses
-    this to implement "adb shell", but will also cook the input before
-    sending it to the device (see interactive_shell() in commandline.c)
-
-remount:
-    Ask adbd to remount the device's filesystem in read-write mode,
-    instead of read-only. This is usually necessary before performing
-    an "adb sync" or "adb push" request.
-
-    This request may not succeed on certain builds which do not allow
-    that.
-
-dev:<path>
-    Opens a device file and connects the client directly to it for
-    read/write purposes. Useful for debugging, but may require special
-    privileges and thus may not run on all devices. <path> is a full
-    path from the root of the filesystem.
-
-tcp:<port>
-    Tries to connect to tcp port <port> on localhost.
-
-tcp:<port>:<server-name>
-    Tries to connect to tcp port <port> on machine <server-name> from
-    the device. This can be useful to debug some networking/proxy
-    issues that can only be revealed on the device itself.
-
-local:<path>
-    Tries to connect to a Unix domain socket <path> on the device
-
-localreserved:<path>
-localabstract:<path>
-localfilesystem:<path>
-    Variants of local:<path> that are used to access other Android
-    socket namespaces.
-
-framebuffer:
-    This service is used to send snapshots of the framebuffer to a client.
-    It requires sufficient privileges but works as follow:
-
-      After the OKAY, the service sends 16-byte binary structure
-      containing the following fields (little-endian format):
-
-            depth:   uint32_t:    framebuffer depth
-            size:    uint32_t:    framebuffer size in bytes
-            width:   uint32_t:    framebuffer width in pixels
-            height:  uint32_t:    framebuffer height in pixels
-
-      With the current implementation, depth is always 16, and
-      size is always width*height*2
-
-      Then, each time the client wants a snapshot, it should send
-      one byte through the channel, which will trigger the service
-      to send it 'size' bytes of framebuffer data.
-
-      If the adbd daemon doesn't have sufficient privileges to open
-      the framebuffer device, the connection is simply closed immediately.
-
-jdwp:<pid>
-    Connects to the JDWP thread running in the VM of process <pid>.
-
-track-jdwp
-    This is used to send the list of JDWP pids periodically to the client.
-    The format of the returned data is the following:
-
-        <hex4>:    the length of all content as a 4-char hexadecimal string
-        <content>: a series of ASCII lines of the following format:
-                        <pid> "\n"
-
-    This service is used by DDMS to know which debuggable processes are running
-    on the device/emulator.
-
-    Note that there is no single-shot service to retrieve the list only once.
-
-sync:
-    This starts the file synchronization service, used to implement "adb push"
-    and "adb pull". Since this service is pretty complex, it will be detailed
-    in a companion document named SYNC.TXT
-
-reverse:<forward-command>
-    This implements the 'adb reverse' feature, i.e. the ability to reverse
-    socket connections from a device to the host. <forward-command> is one
-    of the forwarding commands that are described above, as in:
-
-      list-forward
-      forward:<local>;<remote>
-      forward:norebind:<local>;<remote>
-      killforward-all
-      killforward:<local>
-
-    Note that in this case, <local> corresponds to the socket on the device
-    and <remote> corresponds to the socket on the host.
-
-    The output of reverse:list-forward is the same as host:list-forward
-    except that <serial> will be just 'host'.
diff --git a/adb/SOCKET-ACTIVATION.txt b/adb/SOCKET-ACTIVATION.txt
deleted file mode 100644
index 4ef62ac..0000000
--- a/adb/SOCKET-ACTIVATION.txt
+++ /dev/null
@@ -1,42 +0,0 @@
-adb can be configured to work with systemd-style socket activation,
-allowing the daemon to start automatically when the adb control port
-is forwarded across a network. You need two files, placed in the usual
-systemd service directories (e.g., ~/.config/systemd/user for a user
-service).
-
-adb.service:
-
---- START adb.service CUT HERE ---
-[Unit]
-Description=adb
-After=adb.socket
-Requires=adb.socket
-[Service]
-Type=simple
-# FD 3 is part of the systemd interface
-ExecStart=/path/to/adb server nodaemon -L acceptfd:3
---- END adb.service CUT HERE ---
-
---- START adb.socket CUT HERE ---
-[Unit]
-Description=adb
-PartOf=adb.service
-[Socket]
-ListenStream=127.0.0.1:5037
-Accept=no
-[Install]
-WantedBy=sockets.target
---- END adb.socket CUT HERE ---
-
-After installing the adb service, the adb server will be started
-automatically on any connection to 127.0.0.1:5037 (the default adb
-control port), even after adb kill-server kills the server.
-
-Other "superserver" launcher systems (like macOS launchd) can be
-configured analogously. The important part is that adb be started with
-"server" and "nodaemon" command line arguments and that the listen
-address (passed to -L) name a file descriptor that's ready to
-accept(2) connections and that's already bound to the desired address
-and listening. inetd-style pre-accepted sockets do _not_ work in this
-configuration: the file descriptor passed to acceptfd must be the
-serve socket, not the accepted connection socket.
diff --git a/adb/SYNC.TXT b/adb/SYNC.TXT
deleted file mode 100644
index 4445a76..0000000
--- a/adb/SYNC.TXT
+++ /dev/null
@@ -1,80 +0,0 @@
-This file tries to document file-related requests a client can make
-to the ADB server of an adbd daemon. See the OVERVIEW.TXT document
-to understand what's going on here. See the SERVICES.TXT to learn more
-about the other requests that are possible.
-
-SYNC SERVICES:
-
-
-Requesting the sync service ("sync:") using the protocol as described in
-SERVICES.TXT sets the connection in sync mode. This mode is a binary mode that
-differs from the regular adb protocol. The connection stays in sync mode until
-explicitly terminated (see below).
-
-After the initial "sync:" command is sent the server must respond with either
-"OKAY" or "FAIL" as per usual.
-
-In sync mode both the server and the client will frequently use eight-byte
-packets to communicate. In this document these are called sync requests and sync
-responses. The first four bytes are an id that specifies the sync request. It is
-represented by four utf-8 characters. The last four bytes are a Little-Endian
-integer, with various uses. This number will be called "length" below. In fact
-all binary integers are Little-Endian in the sync mode. Sync mode is
-implicitly exited after each sync request, and normal adb communication
-follows as described in SERVICES.TXT.
-
-The following sync requests are accepted:
-LIST - List the files in a folder
-RECV - Retrieve a file from device
-SEND - Send a file to device
-STAT - Stat a file
-
-All of the sync requests above must be followed by "length": the number of
-bytes containing a utf-8 string with a remote filename.
-
-LIST:
-Lists files in the directory specified by the remote filename. The server will
-respond with zero or more directory entries or "dents".
-
-The directory entries will be returned in the following form
-1. A four-byte sync response id "DENT"
-2. A four-byte integer representing file mode.
-3. A four-byte integer representing file size.
-4. A four-byte integer representing last modified time.
-5. A four-byte integer representing file name length.
-6. length number of bytes containing an utf-8 string representing the file
-   name.
-
-When a sync response "DONE" is received the listing is done.
-
-SEND:
-The remote file name is split into two parts separated by the last
-comma (","). The first part is the actual path, while the second is a decimal
-encoded file mode containing the permissions of the file on device.
-
-Note that some file types will be deleted before the copying starts, and if
-the transfer fails. Some file types will not be deleted, which allows
-  adb push disk_image /some_block_device
-to work.
-
-After this the actual file is sent in chunks. Each chunk has the following
-format.
-A sync request with id "DATA" and length equal to the chunk size. After
-follows chunk size number of bytes. This is repeated until the file is
-transferred. Each chunk must not be larger than 64k.
-
-When the file is transferred a sync request "DONE" is sent, where length is set
-to the last modified time for the file. The server responds to this last
-request (but not to chunk requests) with an "OKAY" sync response (length can
-be ignored).
-
-
-RECV:
-Retrieves a file from device to a local file. The remote path is the path to
-the file that will be returned. Just as for the SEND sync request the file
-received is split up into chunks. The sync response id is "DATA" and length is
-the chunk size. After follows chunk size number of bytes. This is repeated
-until the file is transferred. Each chunk will not be larger than 64k.
-
-When the file is transferred a sync response "DONE" is retrieved where the
-length can be ignored.
diff --git a/adb/adb.bash b/adb/adb.bash
deleted file mode 100644
index b1b3957..0000000
--- a/adb/adb.bash
+++ /dev/null
@@ -1,499 +0,0 @@
-# /* vim: set ai ts=4 ft=sh: */
-#
-# Copyright 2011, The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-_adb() {
-    if ! check_type "$1" >/dev/null; then
-        return
-    fi
-
-    if check_type _init_completion >/dev/null; then
-        _init_completion || return
-    fi
-
-    local where i cur serial
-    COMPREPLY=()
-
-    serial="${ANDROID_SERIAL:-none}"
-    where=OPTIONS
-    for ((i=1; i <= COMP_CWORD; i++)); do
-        cur="${COMP_WORDS[i]}"
-        case "${cur}" in
-            -s)
-                where=OPT_SERIAL
-                ;;
-            -p)
-                where=OPT_PATH
-                ;;
-            -*)
-                where=OPTIONS
-                ;;
-            *)
-                if [[ $where == OPT_SERIAL ]]; then
-                    where=OPT_SERIAL_ARG
-                    serial=${cur}
-                else
-                    where=COMMAND
-                    break
-                fi
-                ;;
-        esac
-    done
-
-    if [[ $where == COMMAND && $i -ge $COMP_CWORD ]]; then
-        where=OPTIONS
-    fi
-
-    OPTIONS="-d -e -s -p"
-    COMMAND="devices connect disconnect push pull sync shell emu logcat lolcat forward jdwp install uninstall bugreport help version start-server kill-server get-state get-serialno status-window remount reboot reboot-bootloader root usb tcpip disable-verity"
-
-    case $where in
-        OPTIONS|OPT_SERIAL|OPT_PATH)
-            COMPREPLY=( $(compgen -W "$OPTIONS $COMMAND" -- "$cur") )
-            ;;
-        OPT_SERIAL_ARG)
-            local devices=$(command adb devices 2> /dev/null | grep -v "List of devices" | awk '{ print $1 }')
-            COMPREPLY=( $(compgen -W "${devices}" -- ${cur}) )
-            ;;
-        COMMAND)
-            if [[ $i -eq $COMP_CWORD ]]; then
-                COMPREPLY=( $(compgen -W "$COMMAND" -- "$cur") )
-            else
-                i=$((i+1))
-                case "${cur}" in
-                    install)
-                        _adb_cmd_install "$serial" $i
-                        ;;
-                    sideload)
-                        _adb_cmd_sideload "$serial" $i
-                        ;;
-                    pull)
-                        _adb_cmd_pull "$serial" $i
-                        ;;
-                    push)
-                        _adb_cmd_push "$serial" $i
-                        ;;
-                    reboot)
-                        if [[ $COMP_CWORD == $i ]]; then
-                            args="bootloader recovery"
-                            COMPREPLY=( $(compgen -W "${args}" -- "${COMP_WORDS[i]}") )
-                        fi
-                        ;;
-                    shell)
-                        _adb_cmd_shell "$serial" $i
-                        ;;
-                    uninstall)
-                        _adb_cmd_uninstall "$serial" $i
-                        ;;
-                esac
-            fi
-            ;;
-    esac
-
-    return 0
-}
-
-_adb_cmd_install() {
-    local serial i cur where
-
-    serial=$1
-    i=$2
-
-    where=OPTIONS
-    for ((; i <= COMP_CWORD; i++)); do
-        cur="${COMP_WORDS[i]}"
-        case "${cur}" in
-            -*)
-                where=OPTIONS
-                ;;
-            *)
-                where=FILE
-                break
-                ;;
-        esac
-    done
-
-    cur="${COMP_WORDS[COMP_CWORD]}"
-    if [[ $where == OPTIONS ]]; then
-        COMPREPLY=( $(compgen -W "-d -l -r -s" -- "${cur}") )
-        return
-    fi
-
-    _adb_util_complete_local_file "${cur}" '!*.apk'
-}
-
-_adb_cmd_sideload() {
-    local serial i cur
-
-    serial=$1
-    i=$2
-
-    cur="${COMP_WORDS[COMP_CWORD]}"
-
-    _adb_util_complete_local_file "${cur}" '!*.zip'
-}
-
-_adb_cmd_push() {
-    local serial IFS=$'\n' i cur
-
-    serial=$1
-    i=$2
-
-    cur="${COMP_WORDS[COMP_CWORD]}"
-
-    if [[ $COMP_CWORD == $i ]]; then
-        _adb_util_complete_local_file "${cur}"
-    elif [[ $COMP_CWORD == $(($i+1)) ]]; then
-        if [ "${cur}" == "" ]; then
-            cur="/"
-        fi
-        _adb_util_list_files $serial "${cur}"
-    fi
-}
-
-_adb_cmd_pull() {
-    local serial IFS=$'\n' i cur
-
-    serial=$1
-    i=$2
-
-    cur="${COMP_WORDS[COMP_CWORD]}"
-
-    if [[ $COMP_CWORD == $i ]]; then
-        if [ "${cur}" == "" ]; then
-            cur="/"
-        fi
-        _adb_util_list_files $serial "${cur}"
-    elif [[ $COMP_CWORD == $(($i+1)) ]]; then
-        _adb_util_complete_local_file "${cur}"
-    fi
-}
-
-_adb_cmd_shell() {
-    local serial IFS=$'\n' i cur
-    local -a args
-
-    serial=$1
-    i=$2
-
-    cur="${COMP_WORDS[i]}"
-    if [ "$serial" != "none" ]; then
-        args=(-s $serial)
-    fi
-
-    if [[ $i -eq $COMP_CWORD && ${cur:0:1} != "/" ]]; then
-        paths=$(command adb ${args[@]} shell echo '$'PATH 2> /dev/null | tr -d '\r' | tr : '\n')
-        COMMAND=$(command adb ${args[@]} shell ls $paths '2>' /dev/null | tr -d '\r' | {
-            while read -r tmp; do
-                command=${tmp##*/}
-                printf '%s\n' "$command"
-            done
-        })
-        COMPREPLY=( $(compgen -W "$COMMAND" -- "$cur") )
-        return 0
-    fi
-
-    i=$((i+1))
-    case "$cur" in
-        ls)
-            _adb_shell_file_command $serial $i "--color -A -C -F -H -L -R -S -Z -a -c -d -f -h -i -k -l -m -n -p -q -r -s -t -u -x -1"
-            ;;
-        cat)
-            _adb_shell_file_command $serial $i "-h -e -t -u -v"
-            ;;
-        dumpsys)
-            _adb_cmd_shell_dumpsys "$serial" $i
-            ;;
-        am)
-            _adb_cmd_shell_am "$serial" $i
-            ;;
-        pm)
-            _adb_cmd_shell_pm "$serial" $i
-            ;;
-        /*)
-            _adb_util_list_files $serial "$cur"
-            ;;
-        *)
-            COMPREPLY=( )
-            ;;
-    esac
-
-    return 0
-}
-
-_adb_cmd_shell_dumpsys() {
-    local serial i cur
-    local -a args
-    local candidates
-
-    unset IFS
-
-    serial=$1
-    i=$2
-
-    if [ "$serial" != "none" ]; then
-        args=(-s $serial)
-    fi
-
-    if (( $i == $COMP_CWORD )) ; then
-        cur="${COMP_WORDS[COMP_CWORD]}"
-        # First line is a header, so need "1d".
-        candidates=$(command adb ${args[@]} shell dumpsys -l 2> /dev/null | sed -e '1d;s/^  *//' | tr -d '\r')
-        candidates="-l $candidates"
-        COMPREPLY=( $(compgen -W "$candidates" -- "$cur") )
-        return 0
-    fi
-
-    COMPREPLY=( )
-    return 0
-}
-
-_adb_cmd_shell_am() {
-    local serial i cur
-    local candidates
-
-    unset IFS
-
-    serial=$1
-    i=$2
-
-    if (( $i == $COMP_CWORD )) ; then
-        cur="${COMP_WORDS[COMP_CWORD]}"
-        candidates="broadcast clear-debug-app clear-watch-heap dumpheap force-stop get-config get-inactive hang idle-maintenance instrument kill kill-all monitor package-importance profile restart screen-compat send-trim-memory set-debug-app set-inactive set-watch-heap stack start startservice start-user stopservice stop-user suppress-resize-config-changes switch-user task to-app-uri to-intent-uri to-uri"
-        COMPREPLY=( $(compgen -W "$candidates" -- "$cur") )
-        return 0
-    fi
-
-    COMPREPLY=( )
-    return 0
-}
-
-
-_adb_cmd_shell_pm() {
-    local serial i cur
-    local candidates
-
-    unset IFS
-
-    serial=$1
-    i=$2
-
-    if (( $i == $COMP_CWORD )) ; then
-        cur="${COMP_WORDS[COMP_CWORD]}"
-        candidates="-l -lf -p clear create-user default-state disable"
-        candidates+=" disable-until-used disable-user dump enable"
-        candidates+=" get-app-link get-install-location get-max-users"
-        candidates+=" get-max-running-users grant hide install"
-        candidates+=" install-abandon install-commit install-create"
-        candidates+=" install-write list move-package"
-        candidates+=" move-primary-storage path remove-user"
-        candidates+=" reset-permissions revoke set-app-link"
-        candidates+=" set-installer set-install-location"
-        candidates+=" set-permission-enforced trim-caches unhide"
-        candidates+=" uninstall"
-        COMPREPLY=( $(compgen -W "$candidates" -- "$cur") )
-        return 0
-    fi
-
-    if (( $i + 1 == $COMP_CWORD )) && [[ "${COMP_WORDS[COMP_CWORD -1]}" == "list" ]]  ; then
-        cur="${COMP_WORDS[COMP_CWORD]}"
-        candidates="packages permission-groups permissions instrumentation features libraries users"
-        COMPREPLY=( $(compgen -W "$candidates" -- "$cur") )
-        return 0
-    fi
-
-    COMPREPLY=( )
-    return 0
-}
-
-_adb_cmd_uninstall() {
-    local serial i where cur packages
-
-    serial=$1
-    i=$2
-    if [ "$serial" != "none" ]; then
-        args=(-s $serial)
-    fi
-
-    where=OPTIONS
-    for ((; i <= COMP_CWORD; i++)); do
-        cur="${COMP_WORDS[i]}"
-        case "${cur}" in
-            -*)
-                where=OPTIONS
-                ;;
-            *)
-                where=FILE
-                break
-                ;;
-        esac
-    done
-
-    cur="${COMP_WORDS[COMP_CWORD]}"
-    if [[ $where == OPTIONS ]]; then
-        COMPREPLY=( $(compgen -W "-k" -- "${cur}") )
-    fi
-
-    packages="$(
-        command adb ${args[@]} shell pm list packages '2>' /dev/null 2> /dev/null | tr -d '\r' | {
-            while read -r tmp; do
-                local package=${tmp#package:}
-                echo -n "${package} "
-            done
-        }
-    )"
-
-    COMPREPLY=( ${COMPREPLY[@]:-} $(compgen -W "${packages}" -- "${cur}") )
-}
-
-_adb_shell_file_command() {
-    local serial i cur file options
-    local -a args
-
-    serial=$1
-    i=$2
-    if [ "$serial" != "none" ]; then
-        args=(-s $serial)
-    fi
-    options=$3
-
-    where=OPTIONS
-    for ((; i <= COMP_CWORD; i++)); do
-        cur="${COMP_WORDS[i]}"
-        case "${cur}" in
-            -*)
-                where=OPTIONS
-                ;;
-            *)
-                where=FILE
-                break
-                ;;
-        esac
-    done
-
-    file="${COMP_WORDS[COMP_CWORD]}"
-    if [[ ${file} == "" ]]; then
-        file="/"
-    fi
-
-    case $where in
-        OPTIONS)
-            unset IFS
-            COMPREPLY=( $(compgen -W "$options" -- "$cur") )
-            ;;
-        FILE)
-            _adb_util_list_files $serial "$file"
-            ;;
-    esac
-
-    return 0
-}
-
-_adb_util_list_files() {
-    local serial dir IFS=$'\n'
-    local -a toks
-    local -a args
-
-    serial="$1"
-    file="$2"
-
-    if [ "$serial" != "none" ]; then
-        args=(-s $serial)
-    fi
-
-    if [[ $( command adb ${args[@]} shell ls -dF / '2>/dev/null' | tr -d '\r' ) == "d /" ]] ; then
-        toks=( ${toks[@]-} $(
-            command adb ${args[@]} shell ls -dF ${file}"*" '2>' /dev/null 2> /dev/null | tr -d '\r' | {
-                while read -r tmp; do
-                    filetype=${tmp%% *}
-                    filename=${tmp:${#filetype}+1}
-                    if [[ ${filetype:${#filetype}-1:1} == d ]]; then
-                        printf '%s/\n' "$filename"
-                    else
-                        printf '%s\n' "$filename"
-                    fi
-                done
-            }
-        ))
-    else
-        toks=( ${toks[@]-} $(
-            command adb ${args[@]} shell ls -dp ${file}"*" '2>/dev/null' 2> /dev/null | tr -d '\r'
-        ))
-    fi
-
-    # Since we're probably doing file completion here, don't add a space after.
-    if [[ $(check_type compopt) == "builtin" ]]; then
-        compopt -o nospace
-    fi
-
-    COMPREPLY=( ${COMPREPLY[@]:-} "${toks[@]}" )
-}
-
-_adb_util_complete_local_file()
-{
-    local file xspec i j IFS=$'\n'
-    local -a dirs files
-
-    file=$1
-    xspec=$2
-
-    # Since we're probably doing file completion here, don't add a space after.
-    if [[ $(check_type compopt) == "builtin" ]]; then
-        compopt -o plusdirs
-        if [[ "${xspec}" == "" ]]; then
-            COMPREPLY=( ${COMPREPLY[@]:-} $(compgen -f -- "${cur}") )
-        else
-            compopt +o filenames
-            COMPREPLY=( ${COMPREPLY[@]:-} $(compgen -f -X "${xspec}" -- "${cur}") )
-        fi
-    else
-        # Work-around for shells with no compopt
-
-        dirs=( $(compgen -d -- "${cur}" ) )
-
-        if [[ "${xspec}" == "" ]]; then
-            files=( ${COMPREPLY[@]:-} $(compgen -f -- "${cur}") )
-        else
-            files=( ${COMPREPLY[@]:-} $(compgen -f -X "${xspec}" -- "${cur}") )
-        fi
-
-        COMPREPLY=( $(
-            for i in "${files[@]}"; do
-                local skip=
-                for j in "${dirs[@]}"; do
-                    if [[ $i == $j ]]; then
-                        skip=1
-                        break
-                    fi
-                done
-                [[ -n $skip ]] || printf "%s\n" "$i"
-            done
-        ))
-
-        COMPREPLY=( ${COMPREPLY[@]:-} $(
-            for i in "${dirs[@]}"; do
-                printf "%s/\n" "$i"
-            done
-        ))
-    fi
-}
-
-
-if [[ $(check_type compopt) == "builtin" ]]; then
-    complete -F _adb adb
-else
-    complete -o nospace -F _adb adb
-fi
diff --git a/adb/adb.cpp b/adb/adb.cpp
deleted file mode 100644
index c3e9731..0000000
--- a/adb/adb.cpp
+++ /dev/null
@@ -1,1359 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define TRACE_TAG ADB
-
-#include "sysdeps.h"
-#include "adb.h"
-
-#include <ctype.h>
-#include <errno.h>
-#include <stdarg.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/time.h>
-#include <time.h>
-
-#include <chrono>
-#include <condition_variable>
-#include <mutex>
-#include <string>
-#include <string_view>
-#include <thread>
-#include <vector>
-
-#include <android-base/errors.h>
-#include <android-base/file.h>
-#include <android-base/logging.h>
-#include <android-base/macros.h>
-#include <android-base/parsenetaddress.h>
-#include <android-base/stringprintf.h>
-#include <android-base/strings.h>
-#include <build/version.h>
-#include <platform_tools_version.h>
-
-#include "adb_auth.h"
-#include "adb_io.h"
-#include "adb_listeners.h"
-#include "adb_unique_fd.h"
-#include "adb_utils.h"
-#include "adb_wifi.h"
-#include "sysdeps/chrono.h"
-#include "transport.h"
-
-#if !ADB_HOST
-#include <sys/capability.h>
-#include <sys/mount.h>
-#include <android-base/properties.h>
-using namespace std::chrono_literals;
-
-#include "daemon/logging.h"
-#endif
-
-#if ADB_HOST
-#include "client/usb.h"
-#endif
-
-std::string adb_version() {
-    // Don't change the format of this --- it's parsed by ddmlib.
-    return android::base::StringPrintf(
-        "Android Debug Bridge version %d.%d.%d\n"
-        "Version %s-%s\n"
-        "Installed as %s\n",
-        ADB_VERSION_MAJOR, ADB_VERSION_MINOR, ADB_SERVER_VERSION,
-        PLATFORM_TOOLS_VERSION, android::build::GetBuildNumber().c_str(),
-        android::base::GetExecutablePath().c_str());
-}
-
-uint32_t calculate_apacket_checksum(const apacket* p) {
-    uint32_t sum = 0;
-    for (size_t i = 0; i < p->msg.data_length; ++i) {
-        sum += static_cast<uint8_t>(p->payload[i]);
-    }
-    return sum;
-}
-
-apacket* get_apacket(void)
-{
-    apacket* p = new apacket();
-    if (p == nullptr) {
-        LOG(FATAL) << "failed to allocate an apacket";
-    }
-
-    memset(&p->msg, 0, sizeof(p->msg));
-    return p;
-}
-
-void put_apacket(apacket *p)
-{
-    delete p;
-}
-
-void handle_online(atransport *t)
-{
-    D("adb: online");
-    t->online = 1;
-    t->SetConnectionEstablished(true);
-}
-
-void handle_offline(atransport *t)
-{
-    if (t->GetConnectionState() == kCsOffline) {
-        LOG(INFO) << t->serial_name() << ": already offline";
-        return;
-    }
-
-    LOG(INFO) << t->serial_name() << ": offline";
-
-    t->SetConnectionState(kCsOffline);
-
-    // Close the associated usb
-    t->online = 0;
-
-    // This is necessary to avoid a race condition that occurred when a transport closes
-    // while a client socket is still active.
-    close_all_sockets(t);
-
-    t->RunDisconnects();
-}
-
-#if DEBUG_PACKETS
-#define DUMPMAX 32
-void print_packet(const char *label, apacket *p)
-{
-    const char* tag;
-    unsigned count;
-
-    switch(p->msg.command){
-    case A_SYNC: tag = "SYNC"; break;
-    case A_CNXN: tag = "CNXN" ; break;
-    case A_OPEN: tag = "OPEN"; break;
-    case A_OKAY: tag = "OKAY"; break;
-    case A_CLSE: tag = "CLSE"; break;
-    case A_WRTE: tag = "WRTE"; break;
-    case A_AUTH: tag = "AUTH"; break;
-    case A_STLS:
-        tag = "STLS";
-        break;
-    default: tag = "????"; break;
-    }
-
-    fprintf(stderr, "%s: %s %08x %08x %04x \"",
-            label, tag, p->msg.arg0, p->msg.arg1, p->msg.data_length);
-    count = p->msg.data_length;
-    const char* x = p->payload.data();
-    if (count > DUMPMAX) {
-        count = DUMPMAX;
-        tag = "\n";
-    } else {
-        tag = "\"\n";
-    }
-    while (count-- > 0) {
-        if ((*x >= ' ') && (*x < 127)) {
-            fputc(*x, stderr);
-        } else {
-            fputc('.', stderr);
-        }
-        x++;
-    }
-    fputs(tag, stderr);
-}
-#endif
-
-static void send_ready(unsigned local, unsigned remote, atransport *t)
-{
-    D("Calling send_ready");
-    apacket *p = get_apacket();
-    p->msg.command = A_OKAY;
-    p->msg.arg0 = local;
-    p->msg.arg1 = remote;
-    send_packet(p, t);
-}
-
-static void send_close(unsigned local, unsigned remote, atransport *t)
-{
-    D("Calling send_close");
-    apacket *p = get_apacket();
-    p->msg.command = A_CLSE;
-    p->msg.arg0 = local;
-    p->msg.arg1 = remote;
-    send_packet(p, t);
-}
-
-std::string get_connection_string() {
-    std::vector<std::string> connection_properties;
-
-#if !ADB_HOST
-    static const char* cnxn_props[] = {
-        "ro.product.name",
-        "ro.product.model",
-        "ro.product.device",
-    };
-
-    for (const auto& prop : cnxn_props) {
-        std::string value = std::string(prop) + "=" + android::base::GetProperty(prop, "");
-        connection_properties.push_back(value);
-    }
-#endif
-
-    connection_properties.push_back(android::base::StringPrintf(
-        "features=%s", FeatureSetToString(supported_features()).c_str()));
-
-    return android::base::StringPrintf(
-        "%s::%s", adb_device_banner,
-        android::base::Join(connection_properties, ';').c_str());
-}
-
-void send_tls_request(atransport* t) {
-    D("Calling send_tls_request");
-    apacket* p = get_apacket();
-    p->msg.command = A_STLS;
-    p->msg.arg0 = A_STLS_VERSION;
-    p->msg.data_length = 0;
-    send_packet(p, t);
-}
-
-void send_connect(atransport* t) {
-    D("Calling send_connect");
-    apacket* cp = get_apacket();
-    cp->msg.command = A_CNXN;
-    // Send the max supported version, but because the transport is
-    // initialized to A_VERSION_MIN, this will be compatible with every
-    // device.
-    cp->msg.arg0 = A_VERSION;
-    cp->msg.arg1 = t->get_max_payload();
-
-    std::string connection_str = get_connection_string();
-    // Connect and auth packets are limited to MAX_PAYLOAD_V1 because we don't
-    // yet know how much data the other size is willing to accept.
-    if (connection_str.length() > MAX_PAYLOAD_V1) {
-        LOG(FATAL) << "Connection banner is too long (length = "
-                   << connection_str.length() << ")";
-    }
-
-    cp->payload.assign(connection_str.begin(), connection_str.end());
-    cp->msg.data_length = cp->payload.size();
-
-    send_packet(cp, t);
-}
-
-void parse_banner(const std::string& banner, atransport* t) {
-    D("parse_banner: %s", banner.c_str());
-
-    // The format is something like:
-    // "device::ro.product.name=x;ro.product.model=y;ro.product.device=z;".
-    std::vector<std::string> pieces = android::base::Split(banner, ":");
-
-    // Reset the features list or else if the server sends no features we may
-    // keep the existing feature set (http://b/24405971).
-    t->SetFeatures("");
-
-    if (pieces.size() > 2) {
-        const std::string& props = pieces[2];
-        for (const auto& prop : android::base::Split(props, ";")) {
-            // The list of properties was traditionally ;-terminated rather than ;-separated.
-            if (prop.empty()) continue;
-
-            std::vector<std::string> key_value = android::base::Split(prop, "=");
-            if (key_value.size() != 2) continue;
-
-            const std::string& key = key_value[0];
-            const std::string& value = key_value[1];
-            if (key == "ro.product.name") {
-                t->product = value;
-            } else if (key == "ro.product.model") {
-                t->model = value;
-            } else if (key == "ro.product.device") {
-                t->device = value;
-            } else if (key == "features") {
-                t->SetFeatures(value);
-            }
-        }
-    }
-
-    const std::string& type = pieces[0];
-    if (type == "bootloader") {
-        D("setting connection_state to kCsBootloader");
-        t->SetConnectionState(kCsBootloader);
-    } else if (type == "device") {
-        D("setting connection_state to kCsDevice");
-        t->SetConnectionState(kCsDevice);
-    } else if (type == "recovery") {
-        D("setting connection_state to kCsRecovery");
-        t->SetConnectionState(kCsRecovery);
-    } else if (type == "sideload") {
-        D("setting connection_state to kCsSideload");
-        t->SetConnectionState(kCsSideload);
-    } else if (type == "rescue") {
-        D("setting connection_state to kCsRescue");
-        t->SetConnectionState(kCsRescue);
-    } else {
-        D("setting connection_state to kCsHost");
-        t->SetConnectionState(kCsHost);
-    }
-}
-
-static void handle_new_connection(atransport* t, apacket* p) {
-    handle_offline(t);
-
-    t->update_version(p->msg.arg0, p->msg.arg1);
-    std::string banner(p->payload.begin(), p->payload.end());
-    parse_banner(banner, t);
-
-#if ADB_HOST
-    handle_online(t);
-#else
-    ADB_LOG(Connection) << "received CNXN: version=" << p->msg.arg0 << ", maxdata = " << p->msg.arg1
-                        << ", banner = '" << banner << "'";
-
-    if (t->use_tls) {
-        // We still handshake in TLS mode. If auth_required is disabled,
-        // we'll just not verify the client's certificate. This should be the
-        // first packet the client receives to indicate the new protocol.
-        send_tls_request(t);
-    } else if (!auth_required) {
-        LOG(INFO) << "authentication not required";
-        handle_online(t);
-        send_connect(t);
-    } else {
-        send_auth_request(t);
-    }
-#endif
-
-    update_transports();
-}
-
-void handle_packet(apacket *p, atransport *t)
-{
-    D("handle_packet() %c%c%c%c", ((char*) (&(p->msg.command)))[0],
-            ((char*) (&(p->msg.command)))[1],
-            ((char*) (&(p->msg.command)))[2],
-            ((char*) (&(p->msg.command)))[3]);
-    print_packet("recv", p);
-    CHECK_EQ(p->payload.size(), p->msg.data_length);
-
-    switch(p->msg.command){
-    case A_CNXN:  // CONNECT(version, maxdata, "system-id-string")
-        handle_new_connection(t, p);
-        break;
-    case A_STLS:  // TLS(version, "")
-        t->use_tls = true;
-#if ADB_HOST
-        send_tls_request(t);
-        adb_auth_tls_handshake(t);
-#else
-        adbd_auth_tls_handshake(t);
-#endif
-        break;
-
-    case A_AUTH:
-        // All AUTH commands are ignored in TLS mode
-        if (t->use_tls) {
-            break;
-        }
-        switch (p->msg.arg0) {
-#if ADB_HOST
-            case ADB_AUTH_TOKEN:
-                if (t->GetConnectionState() != kCsAuthorizing) {
-                    t->SetConnectionState(kCsAuthorizing);
-                }
-                send_auth_response(p->payload.data(), p->msg.data_length, t);
-                break;
-#else
-            case ADB_AUTH_SIGNATURE: {
-                // TODO: Switch to string_view.
-                std::string signature(p->payload.begin(), p->payload.end());
-                std::string auth_key;
-                if (adbd_auth_verify(t->token, sizeof(t->token), signature, &auth_key)) {
-                    adbd_auth_verified(t);
-                    t->failed_auth_attempts = 0;
-                    t->auth_key = auth_key;
-                    adbd_notify_framework_connected_key(t);
-                } else {
-                    if (t->failed_auth_attempts++ > 256) std::this_thread::sleep_for(1s);
-                    send_auth_request(t);
-                }
-                break;
-            }
-
-            case ADB_AUTH_RSAPUBLICKEY:
-                t->auth_key = std::string(p->payload.data());
-                adbd_auth_confirm_key(t);
-                break;
-#endif
-            default:
-                t->SetConnectionState(kCsOffline);
-                handle_offline(t);
-                break;
-        }
-        break;
-
-    case A_OPEN: /* OPEN(local-id, 0, "destination") */
-        if (t->online && p->msg.arg0 != 0 && p->msg.arg1 == 0) {
-            std::string_view address(p->payload.begin(), p->payload.size());
-
-            // Historically, we received service names as a char*, and stopped at the first NUL
-            // byte. The client sent strings with null termination, which post-string_view, start
-            // being interpreted as part of the string, unless we explicitly strip them.
-            address = StripTrailingNulls(address);
-
-            asocket* s = create_local_service_socket(address, t);
-            if (s == nullptr) {
-                send_close(0, p->msg.arg0, t);
-            } else {
-                s->peer = create_remote_socket(p->msg.arg0, t);
-                s->peer->peer = s;
-                send_ready(s->id, s->peer->id, t);
-                s->ready(s);
-            }
-        }
-        break;
-
-    case A_OKAY: /* READY(local-id, remote-id, "") */
-        if (t->online && p->msg.arg0 != 0 && p->msg.arg1 != 0) {
-            asocket* s = find_local_socket(p->msg.arg1, 0);
-            if (s) {
-                if(s->peer == nullptr) {
-                    /* On first READY message, create the connection. */
-                    s->peer = create_remote_socket(p->msg.arg0, t);
-                    s->peer->peer = s;
-                    s->ready(s);
-                } else if (s->peer->id == p->msg.arg0) {
-                    /* Other READY messages must use the same local-id */
-                    s->ready(s);
-                } else {
-                    D("Invalid A_OKAY(%d,%d), expected A_OKAY(%d,%d) on transport %s", p->msg.arg0,
-                      p->msg.arg1, s->peer->id, p->msg.arg1, t->serial.c_str());
-                }
-            } else {
-                // When receiving A_OKAY from device for A_OPEN request, the host server may
-                // have closed the local socket because of client disconnection. Then we need
-                // to send A_CLSE back to device to close the service on device.
-                send_close(p->msg.arg1, p->msg.arg0, t);
-            }
-        }
-        break;
-
-    case A_CLSE: /* CLOSE(local-id, remote-id, "") or CLOSE(0, remote-id, "") */
-        if (t->online && p->msg.arg1 != 0) {
-            asocket* s = find_local_socket(p->msg.arg1, p->msg.arg0);
-            if (s) {
-                /* According to protocol.txt, p->msg.arg0 might be 0 to indicate
-                 * a failed OPEN only. However, due to a bug in previous ADB
-                 * versions, CLOSE(0, remote-id, "") was also used for normal
-                 * CLOSE() operations.
-                 *
-                 * This is bad because it means a compromised adbd could
-                 * send packets to close connections between the host and
-                 * other devices. To avoid this, only allow this if the local
-                 * socket has a peer on the same transport.
-                 */
-                if (p->msg.arg0 == 0 && s->peer && s->peer->transport != t) {
-                    D("Invalid A_CLSE(0, %u) from transport %s, expected transport %s", p->msg.arg1,
-                      t->serial.c_str(), s->peer->transport->serial.c_str());
-                } else {
-                    s->close(s);
-                }
-            }
-        }
-        break;
-
-    case A_WRTE: /* WRITE(local-id, remote-id, <data>) */
-        if (t->online && p->msg.arg0 != 0 && p->msg.arg1 != 0) {
-            asocket* s = find_local_socket(p->msg.arg1, p->msg.arg0);
-            if (s) {
-                unsigned rid = p->msg.arg0;
-                if (s->enqueue(s, std::move(p->payload)) == 0) {
-                    D("Enqueue the socket");
-                    send_ready(s->id, rid, t);
-                }
-            }
-        }
-        break;
-
-    default:
-        printf("handle_packet: what is %08x?!\n", p->msg.command);
-    }
-
-    put_apacket(p);
-}
-
-#if ADB_HOST
-
-#ifdef _WIN32
-
-// Try to make a handle non-inheritable and if there is an error, don't output
-// any error info, but leave GetLastError() for the caller to read. This is
-// convenient if the caller is expecting that this may fail and they'd like to
-// ignore such a failure.
-static bool _try_make_handle_noninheritable(HANDLE h) {
-    if (h != INVALID_HANDLE_VALUE && h != NULL) {
-        return SetHandleInformation(h, HANDLE_FLAG_INHERIT, 0) ? true : false;
-    }
-
-    return true;
-}
-
-// Try to make a handle non-inheritable with the expectation that this should
-// succeed, so if this fails, output error info.
-static bool _make_handle_noninheritable(HANDLE h) {
-    if (!_try_make_handle_noninheritable(h)) {
-        // Show the handle value to give us a clue in case we have problems
-        // with pseudo-handle values.
-        fprintf(stderr, "adb: cannot make handle 0x%p non-inheritable: %s\n", h,
-                android::base::SystemErrorCodeToString(GetLastError()).c_str());
-        return false;
-    }
-
-    return true;
-}
-
-// Create anonymous pipe, preventing inheritance of the read pipe and setting
-// security of the write pipe to sa.
-static bool _create_anonymous_pipe(unique_handle* pipe_read_out,
-                                   unique_handle* pipe_write_out,
-                                   SECURITY_ATTRIBUTES* sa) {
-    HANDLE pipe_read_raw = NULL;
-    HANDLE pipe_write_raw = NULL;
-    if (!CreatePipe(&pipe_read_raw, &pipe_write_raw, sa, 0)) {
-        fprintf(stderr, "adb: CreatePipe failed: %s\n",
-                android::base::SystemErrorCodeToString(GetLastError()).c_str());
-        return false;
-    }
-
-    unique_handle pipe_read(pipe_read_raw);
-    pipe_read_raw = NULL;
-    unique_handle pipe_write(pipe_write_raw);
-    pipe_write_raw = NULL;
-
-    if (!_make_handle_noninheritable(pipe_read.get())) {
-        return false;
-    }
-
-    *pipe_read_out = std::move(pipe_read);
-    *pipe_write_out = std::move(pipe_write);
-
-    return true;
-}
-
-// Read from a pipe (that we take ownership of) and write the result to stdout/stderr. Return on
-// error or when the pipe is closed. Internally makes inheritable handles, so this should not be
-// called if subprocesses may be started concurrently.
-static unsigned _redirect_pipe_thread(HANDLE h, DWORD nStdHandle) {
-    // Take ownership of the HANDLE and close when we're done.
-    unique_handle   read_pipe(h);
-    const char*     output_name = nStdHandle == STD_OUTPUT_HANDLE ? "stdout" : "stderr";
-    const int       original_fd = fileno(nStdHandle == STD_OUTPUT_HANDLE ? stdout : stderr);
-    std::unique_ptr<FILE, decltype(&fclose)> stream(nullptr, fclose);
-
-    if (original_fd == -1) {
-        fprintf(stderr, "adb: failed to get file descriptor for %s: %s\n", output_name,
-                strerror(errno));
-        return EXIT_FAILURE;
-    }
-
-    // If fileno() is -2, stdout/stderr is not associated with an output stream, so we should read,
-    // but don't write. Otherwise, make a FILE* identical to stdout/stderr except that it is in
-    // binary mode with no CR/LR translation since we're reading raw.
-    if (original_fd >= 0) {
-        // This internally makes a duplicate file handle that is inheritable, so callers should not
-        // call this function if subprocesses may be started concurrently.
-        const int fd = dup(original_fd);
-        if (fd == -1) {
-            fprintf(stderr, "adb: failed to duplicate file descriptor for %s: %s\n", output_name,
-                    strerror(errno));
-            return EXIT_FAILURE;
-        }
-
-        // Note that although we call fdopen() below with a binary flag, it may not adhere to that
-        // flag, so we have to set the mode manually.
-        if (_setmode(fd, _O_BINARY) == -1) {
-            fprintf(stderr, "adb: failed to set binary mode for duplicate of %s: %s\n", output_name,
-                    strerror(errno));
-            unix_close(fd);
-            return EXIT_FAILURE;
-        }
-
-        stream.reset(fdopen(fd, "wb"));
-        if (stream.get() == nullptr) {
-            fprintf(stderr, "adb: failed to open duplicate stream for %s: %s\n", output_name,
-                    strerror(errno));
-            unix_close(fd);
-            return EXIT_FAILURE;
-        }
-
-        // Unbuffer the stream because it will be buffered by default and we want subprocess output
-        // to be shown immediately.
-        if (setvbuf(stream.get(), NULL, _IONBF, 0) == -1) {
-            fprintf(stderr, "adb: failed to unbuffer %s: %s\n", output_name, strerror(errno));
-            return EXIT_FAILURE;
-        }
-
-        // fd will be closed when stream is closed.
-    }
-
-    while (true) {
-        char    buf[64 * 1024];
-        DWORD   bytes_read = 0;
-        if (!ReadFile(read_pipe.get(), buf, sizeof(buf), &bytes_read, NULL)) {
-            const DWORD err = GetLastError();
-            // ERROR_BROKEN_PIPE is expected when the subprocess closes
-            // the other end of the pipe.
-            if (err == ERROR_BROKEN_PIPE) {
-                return EXIT_SUCCESS;
-            } else {
-                fprintf(stderr, "adb: failed to read from %s: %s\n", output_name,
-                        android::base::SystemErrorCodeToString(err).c_str());
-                return EXIT_FAILURE;
-            }
-        }
-
-        // Don't try to write if our stdout/stderr was not setup by the parent process.
-        if (stream) {
-            // fwrite() actually calls adb_fwrite() which can write UTF-8 to the console.
-            const size_t bytes_written = fwrite(buf, 1, bytes_read, stream.get());
-            if (bytes_written != bytes_read) {
-                fprintf(stderr, "adb: error: only wrote %zu of %lu bytes to %s\n", bytes_written,
-                        bytes_read, output_name);
-                return EXIT_FAILURE;
-            }
-        }
-    }
-}
-
-static unsigned __stdcall _redirect_stdout_thread(HANDLE h) {
-    adb_thread_setname("stdout redirect");
-    return _redirect_pipe_thread(h, STD_OUTPUT_HANDLE);
-}
-
-static unsigned __stdcall _redirect_stderr_thread(HANDLE h) {
-    adb_thread_setname("stderr redirect");
-    return _redirect_pipe_thread(h, STD_ERROR_HANDLE);
-}
-
-#endif
-
-static void ReportServerStartupFailure(pid_t pid) {
-    fprintf(stderr, "ADB server didn't ACK\n");
-    fprintf(stderr, "Full server startup log: %s\n", GetLogFilePath().c_str());
-    fprintf(stderr, "Server had pid: %d\n", pid);
-
-    android::base::unique_fd fd(unix_open(GetLogFilePath(), O_RDONLY));
-    if (fd == -1) return;
-
-    // Let's not show more than 128KiB of log...
-    unix_lseek(fd, -128 * 1024, SEEK_END);
-    std::string content;
-    if (!android::base::ReadFdToString(fd, &content)) return;
-
-    std::string header = android::base::StringPrintf("--- adb starting (pid %d) ---", pid);
-    std::vector<std::string> lines = android::base::Split(content, "\n");
-    int i = lines.size() - 1;
-    while (i >= 0 && lines[i] != header) --i;
-    while (static_cast<size_t>(i) < lines.size()) fprintf(stderr, "%s\n", lines[i++].c_str());
-}
-
-int launch_server(const std::string& socket_spec) {
-#if defined(_WIN32)
-    /* we need to start the server in the background                    */
-    /* we create a PIPE that will be used to wait for the server's "OK" */
-    /* message since the pipe handles must be inheritable, we use a     */
-    /* security attribute                                               */
-    SECURITY_ATTRIBUTES   sa;
-    sa.nLength = sizeof(sa);
-    sa.lpSecurityDescriptor = NULL;
-    sa.bInheritHandle = TRUE;
-
-    // Redirect stdin to Windows /dev/null. If we instead pass an original
-    // stdin/stdout/stderr handle and it is a console handle, when the adb
-    // server starts up, the C Runtime will see a console handle for a process
-    // that isn't connected to a console and it will configure
-    // stdin/stdout/stderr to be closed. At that point, freopen() could be used
-    // to reopen stderr/out, but it would take more massaging to fixup the file
-    // descriptor number that freopen() uses. It's simplest to avoid all of this
-    // complexity by just redirecting stdin to `nul' and then the C Runtime acts
-    // as expected.
-    unique_handle   nul_read(CreateFileW(L"nul", GENERIC_READ,
-            FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, OPEN_EXISTING,
-            FILE_ATTRIBUTE_NORMAL, NULL));
-    if (nul_read.get() == INVALID_HANDLE_VALUE) {
-        fprintf(stderr, "adb: CreateFileW 'nul' failed: %s\n",
-                android::base::SystemErrorCodeToString(GetLastError()).c_str());
-        return -1;
-    }
-
-    // Create pipes with non-inheritable read handle, inheritable write handle. We need to connect
-    // the subprocess to pipes instead of just letting the subprocess inherit our existing
-    // stdout/stderr handles because a DETACHED_PROCESS cannot write to a console that it is not
-    // attached to.
-    unique_handle   ack_read, ack_write;
-    if (!_create_anonymous_pipe(&ack_read, &ack_write, &sa)) {
-        return -1;
-    }
-    unique_handle   stdout_read, stdout_write;
-    if (!_create_anonymous_pipe(&stdout_read, &stdout_write, &sa)) {
-        return -1;
-    }
-    unique_handle   stderr_read, stderr_write;
-    if (!_create_anonymous_pipe(&stderr_read, &stderr_write, &sa)) {
-        return -1;
-    }
-
-    /* Some programs want to launch an adb command and collect its output by
-     * calling CreateProcess with inheritable stdout/stderr handles, then
-     * using read() to get its output. When this happens, the stdout/stderr
-     * handles passed to the adb client process will also be inheritable.
-     * When starting the adb server here, care must be taken to reset them
-     * to non-inheritable.
-     * Otherwise, something bad happens: even if the adb command completes,
-     * the calling process is stuck while read()-ing from the stdout/stderr
-     * descriptors, because they're connected to corresponding handles in the
-     * adb server process (even if the latter never uses/writes to them).
-     * Note that even if we don't pass these handles in the STARTUPINFO struct,
-     * if they're marked inheritable, they're still inherited, requiring us to
-     * deal with this.
-     *
-     * If we're still having problems with inheriting random handles in the
-     * future, consider using PROC_THREAD_ATTRIBUTE_HANDLE_LIST to explicitly
-     * specify which handles should be inherited: http://blogs.msdn.com/b/oldnewthing/archive/2011/12/16/10248328.aspx
-     *
-     * Older versions of Windows return console pseudo-handles that cannot be
-     * made non-inheritable, so ignore those failures.
-     */
-    _try_make_handle_noninheritable(GetStdHandle(STD_INPUT_HANDLE));
-    _try_make_handle_noninheritable(GetStdHandle(STD_OUTPUT_HANDLE));
-    _try_make_handle_noninheritable(GetStdHandle(STD_ERROR_HANDLE));
-
-    STARTUPINFOW    startup;
-    ZeroMemory( &startup, sizeof(startup) );
-    startup.cb = sizeof(startup);
-    startup.hStdInput  = nul_read.get();
-    startup.hStdOutput = stdout_write.get();
-    startup.hStdError  = stderr_write.get();
-    startup.dwFlags    = STARTF_USESTDHANDLES;
-
-    // Verify that the pipe_write handle value can be passed on the command line
-    // as %d and that the rest of adb code can pass it around in an int.
-    const int ack_write_as_int = cast_handle_to_int(ack_write.get());
-    if (cast_int_to_handle(ack_write_as_int) != ack_write.get()) {
-        // If this fires, either handle values are larger than 32-bits or else
-        // there is a bug in our casting.
-        // https://msdn.microsoft.com/en-us/library/windows/desktop/aa384203%28v=vs.85%29.aspx
-        fprintf(stderr, "adb: cannot fit pipe handle value into 32-bits: 0x%p\n", ack_write.get());
-        return -1;
-    }
-
-    // get path of current program
-    WCHAR       program_path[MAX_PATH];
-    const DWORD module_result = GetModuleFileNameW(NULL, program_path,
-                                                   arraysize(program_path));
-    if ((module_result >= arraysize(program_path)) || (module_result == 0)) {
-        // String truncation or some other error.
-        fprintf(stderr, "adb: cannot get executable path: %s\n",
-                android::base::SystemErrorCodeToString(GetLastError()).c_str());
-        return -1;
-    }
-
-    WCHAR   args[64];
-    snwprintf(args, arraysize(args), L"adb -L %s fork-server server --reply-fd %d",
-              socket_spec.c_str(), ack_write_as_int);
-
-    PROCESS_INFORMATION   pinfo;
-    ZeroMemory(&pinfo, sizeof(pinfo));
-
-    if (!CreateProcessW(
-            program_path,                              /* program path  */
-            args,
-                                    /* the fork-server argument will set the
-                                       debug = 2 in the child           */
-            NULL,                   /* process handle is not inheritable */
-            NULL,                    /* thread handle is not inheritable */
-            TRUE,                          /* yes, inherit some handles */
-            DETACHED_PROCESS, /* the new process doesn't have a console */
-            NULL,                     /* use parent's environment block */
-            NULL,                    /* use parent's starting directory */
-            &startup,                 /* startup info, i.e. std handles */
-            &pinfo )) {
-        fprintf(stderr, "adb: CreateProcessW failed: %s\n",
-                android::base::SystemErrorCodeToString(GetLastError()).c_str());
-        return -1;
-    }
-
-    unique_handle   process_handle(pinfo.hProcess);
-    pinfo.hProcess = NULL;
-
-    // Close handles that we no longer need to complete the rest.
-    CloseHandle(pinfo.hThread);
-    pinfo.hThread = NULL;
-
-    nul_read.reset();
-    ack_write.reset();
-    stdout_write.reset();
-    stderr_write.reset();
-
-    // Start threads to read from subprocess stdout/stderr and write to ours to make subprocess
-    // errors easier to diagnose. Note that the threads internally create inheritable handles, but
-    // that is ok because we've already spawned the subprocess.
-
-    // In the past, reading from a pipe before the child process's C Runtime
-    // started up and called GetFileType() caused a hang: http://blogs.msdn.com/b/oldnewthing/archive/2011/12/02/10243553.aspx#10244216
-    // This is reportedly fixed in Windows Vista: https://support.microsoft.com/en-us/kb/2009703
-    // I was unable to reproduce the problem on Windows XP. It sounds like a
-    // Windows Update may have fixed this: https://www.duckware.com/tech/peeknamedpipe.html
-    unique_handle   stdout_thread(reinterpret_cast<HANDLE>(
-            _beginthreadex(NULL, 0, _redirect_stdout_thread, stdout_read.get(),
-                           0, NULL)));
-    if (stdout_thread.get() == nullptr) {
-        fprintf(stderr, "adb: cannot create thread: %s\n", strerror(errno));
-        return -1;
-    }
-    stdout_read.release();  // Transfer ownership to new thread
-
-    unique_handle   stderr_thread(reinterpret_cast<HANDLE>(
-            _beginthreadex(NULL, 0, _redirect_stderr_thread, stderr_read.get(),
-                           0, NULL)));
-    if (stderr_thread.get() == nullptr) {
-        fprintf(stderr, "adb: cannot create thread: %s\n", strerror(errno));
-        return -1;
-    }
-    stderr_read.release();  // Transfer ownership to new thread
-
-    bool    got_ack = false;
-
-    // Wait for the "OK\n" message, for the pipe to be closed, or other error.
-    {
-        char    temp[3];
-        DWORD   count = 0;
-
-        if (ReadFile(ack_read.get(), temp, sizeof(temp), &count, NULL)) {
-            const CHAR  expected[] = "OK\n";
-            const DWORD expected_length = arraysize(expected) - 1;
-            if (count == expected_length &&
-                memcmp(temp, expected, expected_length) == 0) {
-                got_ack = true;
-            } else {
-                ReportServerStartupFailure(pinfo.dwProcessId);
-                return -1;
-            }
-        } else {
-            const DWORD err = GetLastError();
-            // If the ACK was not written and the process exited, GetLastError()
-            // is probably ERROR_BROKEN_PIPE, in which case that info is not
-            // useful to the user.
-            fprintf(stderr, "could not read ok from ADB Server%s\n",
-                    err == ERROR_BROKEN_PIPE ? "" :
-                    android::base::StringPrintf(": %s",
-                            android::base::SystemErrorCodeToString(err).c_str()).c_str());
-        }
-    }
-
-    // Always try to wait a bit for threads reading stdout/stderr to finish.
-    // If the process started ok, it should close the pipes causing the threads
-    // to finish. If the process had an error, it should exit, also causing
-    // the pipes to be closed. In that case we want to read all of the output
-    // and write it out so that the user can diagnose failures.
-    const DWORD     thread_timeout_ms = 15 * 1000;
-    const HANDLE    threads[] = { stdout_thread.get(), stderr_thread.get() };
-    const DWORD     wait_result = WaitForMultipleObjects(arraysize(threads),
-            threads, TRUE, thread_timeout_ms);
-    if (wait_result == WAIT_TIMEOUT) {
-        // Threads did not finish after waiting a little while. Perhaps the
-        // server didn't close pipes, or it is hung.
-        fprintf(stderr, "adb: timed out waiting for threads to finish reading from ADB server\n");
-        // Process handles are signaled when the process exits, so if we wait
-        // on the handle for 0 seconds and it returns 'timeout', that means that
-        // the process is still running.
-        if (WaitForSingleObject(process_handle.get(), 0) == WAIT_TIMEOUT) {
-            // We could TerminateProcess(), but that seems somewhat presumptive.
-            fprintf(stderr, "adb: server is running with process id %lu\n", pinfo.dwProcessId);
-        }
-        return -1;
-    }
-
-    if (wait_result != WAIT_OBJECT_0) {
-        fprintf(stderr, "adb: unexpected result waiting for threads: %lu: %s\n", wait_result,
-                android::base::SystemErrorCodeToString(GetLastError()).c_str());
-        return -1;
-    }
-
-    // For now ignore the thread exit codes and assume they worked properly.
-
-    if (!got_ack) {
-        return -1;
-    }
-#else /* !defined(_WIN32) */
-    // set up a pipe so the child can tell us when it is ready.
-    unique_fd pipe_read, pipe_write;
-    if (!Pipe(&pipe_read, &pipe_write)) {
-        fprintf(stderr, "pipe failed in launch_server, errno: %d\n", errno);
-        return -1;
-    }
-
-    std::string path = android::base::GetExecutablePath();
-
-    pid_t pid = fork();
-    if (pid < 0) return -1;
-
-    if (pid == 0) {
-        // child side of the fork
-        pipe_read.reset();
-
-        // android::base::Pipe unconditionally opens the pipe with O_CLOEXEC.
-        // Undo this manually.
-        fcntl(pipe_write.get(), F_SETFD, 0);
-
-        char reply_fd[30];
-        snprintf(reply_fd, sizeof(reply_fd), "%d", pipe_write.get());
-        // child process
-        int result = execl(path.c_str(), "adb", "-L", socket_spec.c_str(), "fork-server", "server",
-                           "--reply-fd", reply_fd, NULL);
-        // this should not return
-        fprintf(stderr, "adb: execl returned %d: %s\n", result, strerror(errno));
-    } else {
-        // parent side of the fork
-        char temp[3] = {};
-        // wait for the "OK\n" message
-        pipe_write.reset();
-        int ret = adb_read(pipe_read.get(), temp, 3);
-        int saved_errno = errno;
-        pipe_read.reset();
-        if (ret < 0) {
-            fprintf(stderr, "could not read ok from ADB Server, errno = %d\n", saved_errno);
-            return -1;
-        }
-        if (ret != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') {
-            ReportServerStartupFailure(pid);
-            return -1;
-        }
-    }
-#endif /* !defined(_WIN32) */
-    return 0;
-}
-#endif /* ADB_HOST */
-
-bool handle_forward_request(const char* service, atransport* transport, int reply_fd) {
-    return handle_forward_request(service, [transport](std::string*) { return transport; },
-                                  reply_fd);
-}
-
-// Try to handle a network forwarding request.
-bool handle_forward_request(const char* service,
-                            std::function<atransport*(std::string* error)> transport_acquirer,
-                            int reply_fd) {
-    if (!strcmp(service, "list-forward")) {
-        // Create the list of forward redirections.
-        std::string listeners = format_listeners();
-#if ADB_HOST
-        SendOkay(reply_fd);
-#endif
-        SendProtocolString(reply_fd, listeners);
-        return true;
-    }
-
-    if (!strcmp(service, "killforward-all")) {
-        remove_all_listeners();
-#if ADB_HOST
-        /* On the host: 1st OKAY is connect, 2nd OKAY is status */
-        SendOkay(reply_fd);
-#endif
-        SendOkay(reply_fd);
-        return true;
-    }
-
-    if (!strncmp(service, "forward:", 8) || !strncmp(service, "killforward:", 12)) {
-        // killforward:local
-        // forward:(norebind:)?local;remote
-        std::string error;
-        atransport* transport = transport_acquirer(&error);
-        if (!transport) {
-            SendFail(reply_fd, error);
-            return true;
-        }
-
-        bool kill_forward = false;
-        bool no_rebind = false;
-        if (android::base::StartsWith(service, "killforward:")) {
-            kill_forward = true;
-            service += 12;
-        } else {
-            service += 8;   // skip past "forward:"
-            if (android::base::StartsWith(service, "norebind:")) {
-                no_rebind = true;
-                service += 9;
-            }
-        }
-
-        std::vector<std::string> pieces = android::base::Split(service, ";");
-
-        if (kill_forward) {
-            // Check killforward: parameter format: '<local>'
-            if (pieces.size() != 1 || pieces[0].empty()) {
-                SendFail(reply_fd, android::base::StringPrintf("bad killforward: %s", service));
-                return true;
-            }
-        } else {
-            // Check forward: parameter format: '<local>;<remote>'
-            if (pieces.size() != 2 || pieces[0].empty() || pieces[1].empty() || pieces[1][0] == '*') {
-                SendFail(reply_fd, android::base::StringPrintf("bad forward: %s", service));
-                return true;
-            }
-        }
-
-        InstallStatus r;
-        int resolved_tcp_port = 0;
-        if (kill_forward) {
-            r = remove_listener(pieces[0].c_str(), transport);
-        } else {
-            r = install_listener(pieces[0], pieces[1].c_str(), transport, no_rebind,
-                                 &resolved_tcp_port, &error);
-        }
-        if (r == INSTALL_STATUS_OK) {
-#if ADB_HOST
-            // On the host: 1st OKAY is connect, 2nd OKAY is status.
-            SendOkay(reply_fd);
-#endif
-            SendOkay(reply_fd);
-
-            // If a TCP port was resolved, send the actual port number back.
-            if (resolved_tcp_port != 0) {
-                SendProtocolString(reply_fd, android::base::StringPrintf("%d", resolved_tcp_port));
-            }
-
-            return true;
-        }
-
-        std::string message;
-        switch (r) {
-          case INSTALL_STATUS_OK: message = "success (!)"; break;
-          case INSTALL_STATUS_INTERNAL_ERROR: message = "internal error"; break;
-          case INSTALL_STATUS_CANNOT_BIND:
-            message = android::base::StringPrintf("cannot bind listener: %s",
-                                                  error.c_str());
-            break;
-          case INSTALL_STATUS_CANNOT_REBIND:
-            message = android::base::StringPrintf("cannot rebind existing socket");
-            break;
-          case INSTALL_STATUS_LISTENER_NOT_FOUND:
-            message = android::base::StringPrintf("listener '%s' not found", service);
-            break;
-        }
-        SendFail(reply_fd, message);
-        return true;
-    }
-
-    return false;
-}
-
-#if ADB_HOST
-static int SendOkay(int fd, const std::string& s) {
-    SendOkay(fd);
-    SendProtocolString(fd, s);
-    return 0;
-}
-
-HostRequestResult handle_host_request(std::string_view service, TransportType type,
-                                      const char* serial, TransportId transport_id, int reply_fd,
-                                      asocket* s) {
-    if (service == "kill") {
-        fprintf(stderr, "adb server killed by remote request\n");
-        fflush(stdout);
-
-        // Send a reply even though we don't read it anymore, so that old versions
-        // of adb that do read it don't spew error messages.
-        SendOkay(reply_fd);
-
-        // Rely on process exit to close the socket for us.
-        exit(0);
-    }
-
-    LOG(DEBUG) << "handle_host_request(" << service << ")";
-
-    // Transport selection:
-    if (service.starts_with("transport") || service.starts_with("tport:")) {
-        TransportType type = kTransportAny;
-
-        std::string serial_storage;
-        bool legacy = true;
-
-        // New transport selection protocol:
-        // This is essentially identical to the previous version, except it returns the selected
-        // transport id to the caller as well.
-        if (android::base::ConsumePrefix(&service, "tport:")) {
-            legacy = false;
-            if (android::base::ConsumePrefix(&service, "serial:")) {
-                serial_storage = service;
-                serial = serial_storage.c_str();
-            } else if (service == "usb") {
-                type = kTransportUsb;
-            } else if (service == "local") {
-                type = kTransportLocal;
-            } else if (service == "any") {
-                type = kTransportAny;
-            }
-
-            // Selection by id is unimplemented, since you obviously already know the transport id
-            // you're connecting to.
-        } else {
-            if (android::base::ConsumePrefix(&service, "transport-id:")) {
-                if (!ParseUint(&transport_id, service)) {
-                    SendFail(reply_fd, "invalid transport id");
-                    return HostRequestResult::Handled;
-                }
-            } else if (service == "transport-usb") {
-                type = kTransportUsb;
-            } else if (service == "transport-local") {
-                type = kTransportLocal;
-            } else if (service == "transport-any") {
-                type = kTransportAny;
-            } else if (android::base::ConsumePrefix(&service, "transport:")) {
-                serial_storage = service;
-                serial = serial_storage.c_str();
-            }
-        }
-
-        std::string error;
-        atransport* t = acquire_one_transport(type, serial, transport_id, nullptr, &error);
-        if (t != nullptr) {
-            s->transport = t;
-            SendOkay(reply_fd);
-
-            if (!legacy) {
-                // Nothing we can do if this fails.
-                WriteFdExactly(reply_fd, &t->id, sizeof(t->id));
-            }
-
-            return HostRequestResult::SwitchedTransport;
-        } else {
-            SendFail(reply_fd, error);
-            return HostRequestResult::Handled;
-        }
-    }
-
-    // return a list of all connected devices
-    if (service == "devices" || service == "devices-l") {
-        bool long_listing = service == "devices-l";
-        D("Getting device list...");
-        std::string device_list = list_transports(long_listing);
-        D("Sending device list...");
-        SendOkay(reply_fd, device_list);
-        return HostRequestResult::Handled;
-    }
-
-    if (service == "reconnect-offline") {
-        std::string response;
-        close_usb_devices([&response](const atransport* transport) {
-            if (!ConnectionStateIsOnline(transport->GetConnectionState())) {
-                response += "reconnecting " + transport->serial_name() + "\n";
-                return true;
-            }
-            return false;
-        }, true);
-        if (!response.empty()) {
-            response.resize(response.size() - 1);
-        }
-        SendOkay(reply_fd, response);
-        return HostRequestResult::Handled;
-    }
-
-    if (service == "features") {
-        std::string error;
-        atransport* t =
-                s->transport ? s->transport
-                             : acquire_one_transport(type, serial, transport_id, nullptr, &error);
-        if (t != nullptr) {
-            SendOkay(reply_fd, FeatureSetToString(t->features()));
-        } else {
-            SendFail(reply_fd, error);
-        }
-        return HostRequestResult::Handled;
-    }
-
-    if (service == "host-features") {
-        FeatureSet features = supported_features();
-        // Abuse features to report libusb status.
-        if (should_use_libusb()) {
-            features.insert(kFeatureLibusb);
-        }
-        features.insert(kFeaturePushSync);
-        SendOkay(reply_fd, FeatureSetToString(features));
-        return HostRequestResult::Handled;
-    }
-
-    // remove TCP transport
-    if (service.starts_with("disconnect:")) {
-        std::string address(service.substr(11));
-        if (address.empty()) {
-            kick_all_tcp_devices();
-            SendOkay(reply_fd, "disconnected everything");
-            return HostRequestResult::Handled;
-        }
-
-        std::string serial;
-        std::string host;
-        int port = DEFAULT_ADB_LOCAL_TRANSPORT_PORT;
-        std::string error;
-        if (address.starts_with("vsock:") || address.starts_with("localfilesystem:")) {
-            serial = address;
-        } else if (!android::base::ParseNetAddress(address, &host, &port, &serial, &error)) {
-            SendFail(reply_fd, android::base::StringPrintf("couldn't parse '%s': %s",
-                                                           address.c_str(), error.c_str()));
-            return HostRequestResult::Handled;
-        }
-        atransport* t = find_transport(serial.c_str());
-        if (t == nullptr) {
-            SendFail(reply_fd, android::base::StringPrintf("no such device '%s'", serial.c_str()));
-            return HostRequestResult::Handled;
-        }
-        kick_transport(t);
-        SendOkay(reply_fd, android::base::StringPrintf("disconnected %s", address.c_str()));
-        return HostRequestResult::Handled;
-    }
-
-    // Returns our value for ADB_SERVER_VERSION.
-    if (service == "version") {
-        SendOkay(reply_fd, android::base::StringPrintf("%04x", ADB_SERVER_VERSION));
-        return HostRequestResult::Handled;
-    }
-
-    // These always report "unknown" rather than the actual error, for scripts.
-    if (service == "get-serialno") {
-        std::string error;
-        atransport* t =
-                s->transport ? s->transport
-                             : acquire_one_transport(type, serial, transport_id, nullptr, &error);
-        if (t) {
-            SendOkay(reply_fd, !t->serial.empty() ? t->serial : "unknown");
-        } else {
-            SendFail(reply_fd, error);
-        }
-        return HostRequestResult::Handled;
-    }
-    if (service == "get-devpath") {
-        std::string error;
-        atransport* t =
-                s->transport ? s->transport
-                             : acquire_one_transport(type, serial, transport_id, nullptr, &error);
-        if (t) {
-            SendOkay(reply_fd, !t->devpath.empty() ? t->devpath : "unknown");
-        } else {
-            SendFail(reply_fd, error);
-        }
-        return HostRequestResult::Handled;
-    }
-    if (service == "get-state") {
-        std::string error;
-        atransport* t =
-                s->transport ? s->transport
-                             : acquire_one_transport(type, serial, transport_id, nullptr, &error);
-        if (t) {
-            SendOkay(reply_fd, t->connection_state_name());
-        } else {
-            SendFail(reply_fd, error);
-        }
-        return HostRequestResult::Handled;
-    }
-
-    // Indicates a new emulator instance has started.
-    if (android::base::ConsumePrefix(&service, "emulator:")) {
-        unsigned int port;
-        if (!ParseUint(&port, service)) {
-          LOG(ERROR) << "received invalid port for emulator: " << service;
-        } else {
-          local_connect(port);
-        }
-
-        /* we don't even need to send a reply */
-        return HostRequestResult::Handled;
-    }
-
-    if (service == "reconnect") {
-        std::string response;
-        atransport* t = s->transport ? s->transport
-                                     : acquire_one_transport(type, serial, transport_id, nullptr,
-                                                             &response, true);
-        if (t != nullptr) {
-            kick_transport(t, true);
-            response =
-                    "reconnecting " + t->serial_name() + " [" + t->connection_state_name() + "]\n";
-        }
-        SendOkay(reply_fd, response);
-        return HostRequestResult::Handled;
-    }
-
-    // TODO: Switch handle_forward_request to string_view.
-    std::string service_str(service);
-    auto transport_acquirer = [=](std::string* error) {
-        if (s->transport) {
-            return s->transport;
-        } else {
-            std::string error;
-            return acquire_one_transport(type, serial, transport_id, nullptr, &error);
-        }
-    };
-    if (handle_forward_request(service_str.c_str(), transport_acquirer, reply_fd)) {
-        return HostRequestResult::Handled;
-    }
-
-    return HostRequestResult::Unhandled;
-}
-
-static auto& init_mutex = *new std::mutex();
-static auto& init_cv = *new std::condition_variable();
-static bool device_scan_complete = false;
-static bool transports_ready = false;
-
-void update_transport_status() {
-    bool result = iterate_transports([](const atransport* t) {
-        if (t->type == kTransportUsb && t->online != 1) {
-            return false;
-        }
-        return true;
-    });
-
-    bool ready;
-    {
-        std::lock_guard<std::mutex> lock(init_mutex);
-        transports_ready = result;
-        ready = transports_ready && device_scan_complete;
-    }
-
-    if (ready) {
-        init_cv.notify_all();
-    }
-}
-
-void adb_notify_device_scan_complete() {
-    {
-        std::lock_guard<std::mutex> lock(init_mutex);
-        if (device_scan_complete) {
-            return;
-        }
-
-        device_scan_complete = true;
-    }
-
-    update_transport_status();
-}
-
-void adb_wait_for_device_initialization() {
-    std::unique_lock<std::mutex> lock(init_mutex);
-    init_cv.wait_for(lock, 3s, []() { return device_scan_complete && transports_ready; });
-}
-
-#endif  // ADB_HOST
diff --git a/adb/adb.h b/adb/adb.h
deleted file mode 100644
index ce12a55..0000000
--- a/adb/adb.h
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef __ADB_H
-#define __ADB_H
-
-#include <limits.h>
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <string>
-
-#include <android-base/macros.h>
-
-#include "adb_trace.h"
-#include "fdevent/fdevent.h"
-#include "socket.h"
-#include "types.h"
-
-constexpr size_t MAX_PAYLOAD_V1 = 4 * 1024;
-constexpr size_t MAX_PAYLOAD = 1024 * 1024;
-constexpr size_t MAX_FRAMEWORK_PAYLOAD = 64 * 1024;
-
-constexpr size_t LINUX_MAX_SOCKET_SIZE = 4194304;
-
-#define A_SYNC 0x434e5953
-#define A_CNXN 0x4e584e43
-#define A_OPEN 0x4e45504f
-#define A_OKAY 0x59414b4f
-#define A_CLSE 0x45534c43
-#define A_WRTE 0x45545257
-#define A_AUTH 0x48545541
-#define A_STLS 0x534C5453
-
-// ADB protocol version.
-// Version revision:
-// 0x01000000: original
-// 0x01000001: skip checksum (Dec 2017)
-#define A_VERSION_MIN 0x01000000
-#define A_VERSION_SKIP_CHECKSUM 0x01000001
-#define A_VERSION 0x01000001
-
-// Stream-based TLS protocol version
-#define A_STLS_VERSION_MIN 0x01000000
-#define A_STLS_VERSION 0x01000000
-
-// Used for help/version information.
-#define ADB_VERSION_MAJOR 1
-#define ADB_VERSION_MINOR 0
-
-std::string adb_version();
-
-// Increment this when we want to force users to start a new adb server.
-#define ADB_SERVER_VERSION 41
-
-using TransportId = uint64_t;
-class atransport;
-
-uint32_t calculate_apacket_checksum(const apacket* packet);
-
-/* the adisconnect structure is used to record a callback that
-** will be called whenever a transport is disconnected (e.g. by the user)
-** this should be used to cleanup objects that depend on the
-** transport (e.g. remote sockets, listeners, etc...)
-*/
-struct adisconnect {
-    void (*func)(void* opaque, atransport* t);
-    void* opaque;
-};
-
-// A transport object models the connection to a remote device or emulator there
-// is one transport per connected device/emulator. A "local transport" connects
-// through TCP (for the emulator), while a "usb transport" through USB (for real
-// devices).
-//
-// Note that kTransportHost doesn't really correspond to a real transport
-// object, it's a special value used to indicate that a client wants to connect
-// to a service implemented within the ADB server itself.
-enum TransportType {
-    kTransportUsb,
-    kTransportLocal,
-    kTransportAny,
-    kTransportHost,
-};
-
-#define TOKEN_SIZE 20
-
-enum ConnectionState {
-    kCsAny = -1,
-
-    kCsConnecting = 0,  // Haven't received a response from the device yet.
-    kCsAuthorizing,     // Authorizing with keys from ADB_VENDOR_KEYS.
-    kCsUnauthorized,    // ADB_VENDOR_KEYS exhausted, fell back to user prompt.
-    kCsNoPerm,          // Insufficient permissions to communicate with the device.
-    kCsOffline,
-
-    kCsBootloader,
-    kCsDevice,
-    kCsHost,
-    kCsRecovery,
-    kCsSideload,
-    kCsRescue,
-};
-
-inline bool ConnectionStateIsOnline(ConnectionState state) {
-    switch (state) {
-        case kCsBootloader:
-        case kCsDevice:
-        case kCsHost:
-        case kCsRecovery:
-        case kCsSideload:
-        case kCsRescue:
-            return true;
-        default:
-            return false;
-    }
-}
-
-void print_packet(const char* label, apacket* p);
-
-void handle_packet(apacket* p, atransport* t);
-
-int launch_server(const std::string& socket_spec);
-int adb_server_main(int is_daemon, const std::string& socket_spec, int ack_reply_fd);
-
-/* initialize a transport object's func pointers and state */
-int init_socket_transport(atransport* t, unique_fd s, int port, int local);
-
-std::string getEmulatorSerialString(int console_port);
-#if ADB_HOST
-atransport* find_emulator_transport_by_adb_port(int adb_port);
-atransport* find_emulator_transport_by_console_port(int console_port);
-#endif
-
-unique_fd service_to_fd(std::string_view name, atransport* transport);
-#if !ADB_HOST
-unique_fd daemon_service_to_fd(std::string_view name, atransport* transport);
-#endif
-
-#if ADB_HOST
-asocket* host_service_to_socket(std::string_view name, std::string_view serial,
-                                TransportId transport_id);
-#endif
-
-#if !ADB_HOST
-asocket* daemon_service_to_socket(std::string_view name);
-#endif
-
-#if !ADB_HOST
-unique_fd execute_abb_command(std::string_view command);
-#endif
-
-#if !ADB_HOST
-int init_jdwp(void);
-asocket* create_jdwp_service_socket();
-asocket* create_jdwp_tracker_service_socket();
-unique_fd create_jdwp_connection_fd(int jdwp_pid);
-#endif
-
-bool handle_forward_request(const char* service, atransport* transport, int reply_fd);
-bool handle_forward_request(const char* service,
-                            std::function<atransport*(std::string* error)> transport_acquirer,
-                            int reply_fd);
-
-/* packet allocator */
-apacket* get_apacket(void);
-void put_apacket(apacket* p);
-
-// Define it if you want to dump packets.
-#define DEBUG_PACKETS 0
-
-#if !DEBUG_PACKETS
-#define print_packet(tag, p) \
-    do {                     \
-    } while (0)
-#endif
-
-#define DEFAULT_ADB_PORT 5037
-
-#define DEFAULT_ADB_LOCAL_TRANSPORT_PORT 5555
-
-#define ADB_CLASS 0xff
-#define ADB_SUBCLASS 0x42
-#define ADB_PROTOCOL 0x1
-
-void local_init(const std::string& addr);
-bool local_connect(int port);
-int local_connect_arbitrary_ports(int console_port, int adb_port, std::string* error);
-
-ConnectionState connection_state(atransport* t);
-
-extern const char* adb_device_banner;
-
-#define CHUNK_SIZE (64 * 1024)
-
-// Argument delimeter for adb abb command.
-#define ABB_ARG_DELIMETER ('\0')
-
-#if !ADB_HOST
-#define USB_FFS_ADB_PATH "/dev/usb-ffs/adb/"
-#define USB_FFS_ADB_EP(x) USB_FFS_ADB_PATH #x
-
-#define USB_FFS_ADB_EP0 USB_FFS_ADB_EP(ep0)
-#define USB_FFS_ADB_OUT USB_FFS_ADB_EP(ep1)
-#define USB_FFS_ADB_IN USB_FFS_ADB_EP(ep2)
-#endif
-
-enum class HostRequestResult {
-    Handled,
-    SwitchedTransport,
-    Unhandled,
-};
-
-HostRequestResult handle_host_request(std::string_view service, TransportType type,
-                                      const char* serial, TransportId transport_id, int reply_fd,
-                                      asocket* s);
-
-void handle_online(atransport* t);
-void handle_offline(atransport* t);
-
-void send_connect(atransport* t);
-void send_tls_request(atransport* t);
-
-void parse_banner(const std::string&, atransport* t);
-
-// On startup, the adb server needs to wait until all of the connected devices are ready.
-// To do this, we need to know when the scan has identified all of the potential new transports, and
-// when each transport becomes ready.
-// TODO: Do this for mDNS as well, instead of just USB?
-
-// We've found all of the transports we potentially care about.
-void adb_notify_device_scan_complete();
-
-// One or more transports have changed status, check to see if we're ready.
-void update_transport_status();
-
-// Wait until device scan has completed and every transport is ready, or a timeout elapses.
-void adb_wait_for_device_initialization();
-
-void usb_init();
-#endif
diff --git a/adb/adb_auth.h b/adb/adb_auth.h
deleted file mode 100644
index 7e858dc..0000000
--- a/adb/adb_auth.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef __ADB_AUTH_H
-#define __ADB_AUTH_H
-
-#include "adb.h"
-
-#include <deque>
-#include <memory>
-
-#include <openssl/rsa.h>
-
-/* AUTH packets first argument */
-/* Request */
-#define ADB_AUTH_TOKEN         1
-/* Response */
-#define ADB_AUTH_SIGNATURE     2
-#define ADB_AUTH_RSAPUBLICKEY  3
-
-#if ADB_HOST
-
-void adb_auth_init();
-
-int adb_auth_keygen(const char* filename);
-int adb_auth_pubkey(const char* filename);
-std::string adb_auth_get_userkey();
-bssl::UniquePtr<EVP_PKEY> adb_auth_get_user_privkey();
-std::deque<std::shared_ptr<RSA>> adb_auth_get_private_keys();
-
-void send_auth_response(const char* token, size_t token_size, atransport* t);
-
-int adb_tls_set_certificate(SSL* ssl);
-void adb_auth_tls_handshake(atransport* t);
-
-#else // !ADB_HOST
-
-extern bool auth_required;
-
-void adbd_auth_init(void);
-void adbd_auth_verified(atransport *t);
-
-void adbd_cloexec_auth_socket();
-bool adbd_auth_verify(const char* token, size_t token_size, const std::string& sig,
-                      std::string* auth_key);
-void adbd_auth_confirm_key(atransport* t);
-void adbd_notify_framework_connected_key(atransport* t);
-
-void send_auth_request(atransport *t);
-
-void adbd_auth_tls_handshake(atransport* t);
-int adbd_tls_verify_cert(X509_STORE_CTX* ctx, std::string* auth_key);
-bssl::UniquePtr<STACK_OF(X509_NAME)> adbd_tls_client_ca_list();
-
-#endif // ADB_HOST
-
-#endif // __ADB_AUTH_H
diff --git a/adb/adb_integration_test_adb.xml b/adb/adb_integration_test_adb.xml
deleted file mode 100644
index e722956..0000000
--- a/adb/adb_integration_test_adb.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<configuration description="Config to run adb integration tests">
-    <option name="test-suite-tag" value="adb_tests" />
-    <option name="test-suite-tag" value="adb_integration" />
-    <target_preparer class="com.android.tradefed.targetprep.SemaphoreTokenTargetPreparer">
-        <option name="disable" value="false" />
-    </target_preparer>
-
-    <target_preparer class="com.android.tradefed.targetprep.adb.AdbStopServerPreparer" />
-    <test class="com.android.tradefed.testtype.python.PythonBinaryHostTest" >
-        <option name="par-file-name" value="adb_integration_test_adb" />
-        <option name="inject-android-serial" value="true" />
-        <option name="test-timeout" value="2m" />
-    </test>
-</configuration>
diff --git a/adb/adb_integration_test_device.xml b/adb/adb_integration_test_device.xml
deleted file mode 100644
index b892377..0000000
--- a/adb/adb_integration_test_device.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<configuration description="Config to run adb integration tests for device">
-    <option name="test-suite-tag" value="adb_tests" />
-    <option name="test-suite-tag" value="adb_integration_device" />
-    <target_preparer class="com.android.tradefed.targetprep.SemaphoreTokenTargetPreparer">
-        <option name="disable" value="false" />
-    </target_preparer>
-
-    <target_preparer class="com.android.tradefed.targetprep.adb.AdbStopServerPreparer" />
-    <test class="com.android.tradefed.testtype.python.PythonBinaryHostTest" >
-        <option name="par-file-name" value="adb_integration_test_device" />
-        <option name="inject-android-serial" value="true" />
-        <option name="test-timeout" value="2m" />
-    </test>
-</configuration>
diff --git a/adb/adb_io.cpp b/adb/adb_io.cpp
deleted file mode 100644
index bdb8efa..0000000
--- a/adb/adb_io.cpp
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define TRACE_TAG RWX
-
-#include "adb_io.h"
-
-#include <unistd.h>
-
-#if !ADB_HOST
-#include <sys/socket.h>
-#include <sys/un.h>
-#endif
-
-#include <thread>
-
-#include <android-base/stringprintf.h>
-
-#include "adb.h"
-#include "adb_trace.h"
-#include "adb_utils.h"
-#include "sysdeps.h"
-
-bool SendProtocolString(borrowed_fd fd, std::string_view s) {
-    unsigned int length = s.size();
-    if (length > MAX_PAYLOAD - 4) {
-        errno = EMSGSIZE;
-        return false;
-    }
-
-    // The cost of sending two strings outweighs the cost of formatting.
-    // "adb sync" performance is affected by this.
-    auto str = android::base::StringPrintf("%04x", length).append(s);
-    return WriteFdExactly(fd, str);
-}
-
-bool ReadProtocolString(borrowed_fd fd, std::string* s, std::string* error) {
-    char buf[5];
-    if (!ReadFdExactly(fd, buf, 4)) {
-        *error = perror_str("protocol fault (couldn't read status length)");
-        return false;
-    }
-    buf[4] = 0;
-
-    unsigned long len = strtoul(buf, nullptr, 16);
-    s->resize(len, '\0');
-    if (!ReadFdExactly(fd, &(*s)[0], len)) {
-        *error = perror_str("protocol fault (couldn't read status message)");
-        return false;
-    }
-
-    return true;
-}
-
-bool SendOkay(borrowed_fd fd) {
-    return WriteFdExactly(fd, "OKAY", 4);
-}
-
-bool SendFail(borrowed_fd fd, std::string_view reason) {
-    return WriteFdExactly(fd, "FAIL", 4) && SendProtocolString(fd, reason);
-}
-
-bool ReadFdExactly(borrowed_fd fd, void* buf, size_t len) {
-    char* p = reinterpret_cast<char*>(buf);
-
-    size_t len0 = len;
-
-    D("readx: fd=%d wanted=%zu", fd.get(), len);
-    while (len > 0) {
-        int r = adb_read(fd, p, len);
-        if (r > 0) {
-            len -= r;
-            p += r;
-        } else if (r == -1) {
-            D("readx: fd=%d error %d: %s", fd.get(), errno, strerror(errno));
-            return false;
-        } else {
-            D("readx: fd=%d disconnected", fd.get());
-            errno = 0;
-            return false;
-        }
-    }
-
-    VLOG(RWX) << "readx: fd=" << fd.get() << " wanted=" << len0 << " got=" << (len0 - len) << " "
-              << dump_hex(reinterpret_cast<const unsigned char*>(buf), len0);
-
-    return true;
-}
-
-bool WriteFdExactly(borrowed_fd fd, const void* buf, size_t len) {
-    const char* p = reinterpret_cast<const char*>(buf);
-    int r;
-
-    VLOG(RWX) << "writex: fd=" << fd.get() << " len=" << len << " "
-              << dump_hex(reinterpret_cast<const unsigned char*>(buf), len);
-
-    while (len > 0) {
-        r = adb_write(fd, p, len);
-        if (r == -1) {
-            D("writex: fd=%d error %d: %s", fd.get(), errno, strerror(errno));
-            if (errno == EAGAIN) {
-                std::this_thread::yield();
-                continue;
-            } else if (errno == EPIPE) {
-                D("writex: fd=%d disconnected", fd.get());
-                errno = 0;
-                return false;
-            } else {
-                return false;
-            }
-        } else {
-            len -= r;
-            p += r;
-        }
-    }
-    return true;
-}
-
-bool WriteFdExactly(borrowed_fd fd, const char* str) {
-    return WriteFdExactly(fd, str, strlen(str));
-}
-
-bool WriteFdExactly(borrowed_fd fd, const std::string& str) {
-    return WriteFdExactly(fd, str.c_str(), str.size());
-}
-
-bool WriteFdFmt(borrowed_fd fd, const char* fmt, ...) {
-    std::string str;
-
-    va_list ap;
-    va_start(ap, fmt);
-    android::base::StringAppendV(&str, fmt, ap);
-    va_end(ap);
-
-    return WriteFdExactly(fd, str);
-}
-
-bool ReadOrderlyShutdown(borrowed_fd fd) {
-    char buf[16];
-
-    // Only call this function if you're sure that the peer does
-    // orderly/graceful shutdown of the socket, closing the socket so that
-    // adb_read() will return 0. If the peer keeps the socket open, adb_read()
-    // will never return.
-    int result = adb_read(fd, buf, sizeof(buf));
-    if (result == -1) {
-        // If errno is EAGAIN, that means this function was called on a
-        // nonblocking socket and it would have blocked (which would be bad
-        // because we'd probably block the main thread where nonblocking IO is
-        // done). Don't do that. If you have a nonblocking socket, use the
-        // fdevent APIs to get called on FDE_READ, and then call this function
-        // if you really need to, but it shouldn't be needed for server sockets.
-        CHECK_NE(errno, EAGAIN);
-
-        // Note that on Windows, orderly shutdown sometimes causes
-        // recv() == SOCKET_ERROR && WSAGetLastError() == WSAECONNRESET. That
-        // can be ignored.
-        return false;
-    } else if (result == 0) {
-        // Peer has performed an orderly/graceful shutdown.
-        return true;
-    } else {
-        // Unexpectedly received data. This is essentially a protocol error
-        // because you should not call this function unless you expect no more
-        // data. We don't repeatedly call adb_read() until we get zero because
-        // we don't know how long that would take, but we do know that the
-        // caller wants to close the socket soon.
-        VLOG(RWX) << "ReadOrderlyShutdown(" << fd.get() << ") unexpectedly read "
-                  << dump_hex(buf, result);
-        // Shutdown the socket to prevent the caller from reading or writing to
-        // it which doesn't make sense if we just read and discarded some data.
-        adb_shutdown(fd);
-        errno = EINVAL;
-        return false;
-    }
-}
diff --git a/adb/adb_io.h b/adb/adb_io.h
deleted file mode 100644
index 9628946..0000000
--- a/adb/adb_io.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ADB_IO_H
-#define ADB_IO_H
-
-#include <sys/types.h>
-
-#include <string>
-#include <string_view>
-
-#include "adb_unique_fd.h"
-
-// Sends the protocol "OKAY" message.
-bool SendOkay(borrowed_fd fd);
-
-// Sends the protocol "FAIL" message, with the given failure reason.
-bool SendFail(borrowed_fd fd, std::string_view reason);
-
-// Writes a protocol-format string; a four hex digit length followed by the string data.
-bool SendProtocolString(borrowed_fd fd, std::string_view s);
-
-// Reads a protocol-format string; a four hex digit length followed by the string data.
-bool ReadProtocolString(borrowed_fd fd, std::string* s, std::string* error);
-
-// Reads exactly len bytes from fd into buf.
-//
-// Returns false if there is an error or if EOF was reached before len bytes
-// were read. If EOF was found, errno will be set to 0.
-//
-// If this function fails, the contents of buf are undefined.
-bool ReadFdExactly(borrowed_fd fd, void* buf, size_t len);
-
-// Given a client socket, wait for orderly/graceful shutdown. Call this:
-//
-// * Before closing a client socket.
-// * Only when no more data is expected to come in.
-// * Only when the server is not waiting for data from the client (because then
-//   the client and server will deadlock waiting for each other).
-// * Only when the server is expected to close its socket right now.
-// * Don't call shutdown(SHUT_WR) before calling this because that will shutdown
-//   the client socket early, defeating the purpose of calling this.
-//
-// Waiting for orderly/graceful shutdown of the server socket will cause the
-// server socket to close before the client socket. That prevents the client
-// socket from staying in TIME_WAIT which eventually causes subsequent
-// connect()s from the client to fail with WSAEADDRINUSE on Windows.
-// Returns true if it is sure that orderly/graceful shutdown has occurred with
-// no additional data read from the server.
-bool ReadOrderlyShutdown(borrowed_fd fd);
-
-// Writes exactly len bytes from buf to fd.
-//
-// Returns false if there is an error or if the fd was closed before the write
-// completed. If the other end of the fd (such as in a socket, pipe, or fifo),
-// is closed, errno will be set to 0.
-bool WriteFdExactly(borrowed_fd fd, const void* buf, size_t len);
-
-// Same as above, but for strings.
-bool WriteFdExactly(borrowed_fd fd, const char* s);
-bool WriteFdExactly(borrowed_fd fd, const std::string& s);
-
-// Same as above, but formats the string to send.
-bool WriteFdFmt(borrowed_fd fd, const char* fmt, ...) __attribute__((__format__(__printf__, 2, 3)));
-#endif /* ADB_IO_H */
diff --git a/adb/adb_io_test.cpp b/adb/adb_io_test.cpp
deleted file mode 100644
index 91b73a9..0000000
--- a/adb/adb_io_test.cpp
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "adb_io.h"
-
-#include <gtest/gtest.h>
-
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include <string>
-
-#include <android-base/file.h>
-
-// All of these tests fail on Windows because they use the C Runtime open(),
-// but the adb_io APIs expect file descriptors from adb_open(). This could
-// theoretically be fixed by making adb_read()/adb_write() fallback to using
-// read()/write() if an unrecognized fd is used, and by making adb_open() return
-// fds far from the range that open() returns. But all of that might defeat the
-// purpose of the tests.
-
-#if defined(_WIN32)
-#define POSIX_TEST(x,y) TEST(DISABLED_ ## x,y)
-#else
-#define POSIX_TEST TEST
-#endif
-
-POSIX_TEST(io, ReadFdExactly_whole) {
-  const char expected[] = "Foobar";
-  TemporaryFile tf;
-  ASSERT_NE(-1, tf.fd);
-
-  ASSERT_TRUE(android::base::WriteStringToFd(expected, tf.fd)) << strerror(errno);
-  ASSERT_EQ(0, lseek(tf.fd, 0, SEEK_SET));
-
-  // Test reading the whole file.
-  char buf[sizeof(expected)] = {};
-  ASSERT_TRUE(ReadFdExactly(tf.fd, buf, sizeof(buf) - 1)) << strerror(errno);
-  EXPECT_STREQ(expected, buf);
-}
-
-POSIX_TEST(io, ReadFdExactly_eof) {
-  const char expected[] = "Foobar";
-  TemporaryFile tf;
-  ASSERT_NE(-1, tf.fd);
-
-  ASSERT_TRUE(android::base::WriteStringToFd(expected, tf.fd)) << strerror(errno);
-  ASSERT_EQ(0, lseek(tf.fd, 0, SEEK_SET));
-
-  // Test that not having enough data will fail.
-  char buf[sizeof(expected) + 1] = {};
-  ASSERT_FALSE(ReadFdExactly(tf.fd, buf, sizeof(buf)));
-  EXPECT_EQ(0, errno) << strerror(errno);
-}
-
-POSIX_TEST(io, ReadFdExactly_partial) {
-  const char input[] = "Foobar";
-  TemporaryFile tf;
-  ASSERT_NE(-1, tf.fd);
-
-  ASSERT_TRUE(android::base::WriteStringToFd(input, tf.fd)) << strerror(errno);
-  ASSERT_EQ(0, lseek(tf.fd, 0, SEEK_SET));
-
-  // Test reading a partial file.
-  char buf[sizeof(input) - 1] = {};
-  ASSERT_TRUE(ReadFdExactly(tf.fd, buf, sizeof(buf) - 1));
-
-  std::string expected(input);
-  expected.pop_back();
-  EXPECT_STREQ(expected.c_str(), buf);
-}
-
-POSIX_TEST(io, WriteFdExactly_whole) {
-  const char expected[] = "Foobar";
-  TemporaryFile tf;
-  ASSERT_NE(-1, tf.fd);
-
-  // Test writing the whole string to the file.
-  ASSERT_TRUE(WriteFdExactly(tf.fd, expected, sizeof(expected)))
-    << strerror(errno);
-  ASSERT_EQ(0, lseek(tf.fd, 0, SEEK_SET));
-
-  std::string s;
-  ASSERT_TRUE(android::base::ReadFdToString(tf.fd, &s));
-  EXPECT_STREQ(expected, s.c_str());
-}
-
-POSIX_TEST(io, WriteFdExactly_partial) {
-  const char buf[] = "Foobar";
-  TemporaryFile tf;
-  ASSERT_NE(-1, tf.fd);
-
-  // Test writing a partial string to the file.
-  ASSERT_TRUE(WriteFdExactly(tf.fd, buf, sizeof(buf) - 2)) << strerror(errno);
-  ASSERT_EQ(0, lseek(tf.fd, 0, SEEK_SET));
-
-  std::string expected(buf);
-  expected.pop_back();
-
-  std::string s;
-  ASSERT_TRUE(android::base::ReadFdToString(tf.fd, &s));
-  EXPECT_EQ(expected, s);
-}
-
-POSIX_TEST(io, WriteFdExactly_ENOSPC) {
-    int fd = open("/dev/full", O_WRONLY);
-    ASSERT_NE(-1, fd);
-
-    char buf[] = "foo";
-    ASSERT_FALSE(WriteFdExactly(fd, buf, sizeof(buf)));
-    ASSERT_EQ(ENOSPC, errno);
-}
-
-POSIX_TEST(io, WriteFdExactly_string) {
-  const char str[] = "Foobar";
-  TemporaryFile tf;
-  ASSERT_NE(-1, tf.fd);
-
-  // Test writing a partial string to the file.
-  ASSERT_TRUE(WriteFdExactly(tf.fd, str)) << strerror(errno);
-  ASSERT_EQ(0, lseek(tf.fd, 0, SEEK_SET));
-
-  std::string s;
-  ASSERT_TRUE(android::base::ReadFdToString(tf.fd, &s));
-  EXPECT_STREQ(str, s.c_str());
-}
-
-POSIX_TEST(io, WriteFdFmt) {
-    TemporaryFile tf;
-    ASSERT_NE(-1, tf.fd);
-
-    // Test writing a partial string to the file.
-    ASSERT_TRUE(WriteFdFmt(tf.fd, "Foo%s%d", "bar", 123)) << strerror(errno);
-    ASSERT_EQ(0, lseek(tf.fd, 0, SEEK_SET));
-
-    std::string s;
-    ASSERT_TRUE(android::base::ReadFdToString(tf.fd, &s));
-    EXPECT_STREQ("Foobar123", s.c_str());
-}
diff --git a/adb/adb_listeners.cpp b/adb/adb_listeners.cpp
deleted file mode 100644
index 29909a5..0000000
--- a/adb/adb_listeners.cpp
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "adb_listeners.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <algorithm>
-#include <list>
-#include <memory>
-
-#include <android-base/stringprintf.h>
-#include <android-base/strings.h>
-#include <android-base/thread_annotations.h>
-#include <cutils/sockets.h>
-
-#include "socket_spec.h"
-#include "sysdeps.h"
-#include "transport.h"
-
-// A listener is an entity which binds to a local port and, upon receiving a connection on that
-// port, creates an asocket to connect the new local connection to a specific remote service.
-//
-// TODO: some listeners read from the new connection to determine what exact service to connect to
-// on the far side.
-class alistener {
-  public:
-    alistener(const std::string& _local_name, const std::string& _connect_to);
-    ~alistener();
-
-    fdevent* fde = nullptr;
-    int fd = -1;
-
-    std::string local_name;
-    std::string connect_to;
-    atransport* transport = nullptr;
-    adisconnect disconnect;
-
-  private:
-    DISALLOW_COPY_AND_ASSIGN(alistener);
-};
-
-alistener::alistener(const std::string& _local_name, const std::string& _connect_to)
-    : local_name(_local_name), connect_to(_connect_to) {
-}
-
-alistener::~alistener() {
-    // Closes the corresponding fd.
-    fdevent_destroy(fde);
-
-    if (transport) {
-        transport->RemoveDisconnect(&disconnect);
-    }
-}
-
-// listener_list retains ownership of all created alistener objects. Removing an alistener from
-// this list will cause it to be deleted.
-static auto& listener_list_mutex = *new std::mutex();
-typedef std::list<std::unique_ptr<alistener>> ListenerList;
-static ListenerList& listener_list GUARDED_BY(listener_list_mutex) = *new ListenerList();
-
-static void ss_listener_event_func(int _fd, unsigned ev, void *_l) {
-    if (ev & FDE_READ) {
-        unique_fd fd(adb_socket_accept(_fd, nullptr, nullptr));
-        if (fd < 0) return;
-
-        int rcv_buf_size = CHUNK_SIZE;
-        adb_setsockopt(fd.get(), SOL_SOCKET, SO_RCVBUF, &rcv_buf_size, sizeof(rcv_buf_size));
-
-        asocket* s = create_local_socket(std::move(fd));
-        if (s) {
-            connect_to_smartsocket(s);
-            return;
-        }
-    }
-}
-
-static void listener_event_func(int _fd, unsigned ev, void* _l)
-{
-    alistener* listener = reinterpret_cast<alistener*>(_l);
-
-    if (ev & FDE_READ) {
-        unique_fd fd(adb_socket_accept(_fd, nullptr, nullptr));
-        if (fd < 0) {
-            return;
-        }
-
-        asocket* s = create_local_socket(std::move(fd));
-        if (s) {
-            s->transport = listener->transport;
-            connect_to_remote(s, listener->connect_to);
-            return;
-        }
-    }
-}
-
-// Called as a transport disconnect function. |arg| is the raw alistener*.
-static void listener_disconnect(void* arg, atransport*) EXCLUDES(listener_list_mutex) {
-    std::lock_guard<std::mutex> lock(listener_list_mutex);
-    for (auto iter = listener_list.begin(); iter != listener_list.end(); ++iter) {
-        if (iter->get() == arg) {
-            (*iter)->transport = nullptr;
-            listener_list.erase(iter);
-            return;
-        }
-    }
-}
-
-// Write the list of current listeners (network redirections) into a string.
-std::string format_listeners() EXCLUDES(listener_list_mutex) {
-    std::lock_guard<std::mutex> lock(listener_list_mutex);
-    std::string result;
-    for (auto& l : listener_list) {
-        // Ignore special listeners like those for *smartsocket*
-        if (l->connect_to[0] == '*') {
-            continue;
-        }
-        //  <device-serial> " " <local-name> " " <remote-name> "\n"
-        // Entries from "adb reverse" have no serial.
-        android::base::StringAppendF(
-                &result, "%s %s %s\n",
-                !l->transport->serial.empty() ? l->transport->serial.c_str() : "(reverse)",
-                l->local_name.c_str(), l->connect_to.c_str());
-    }
-    return result;
-}
-
-InstallStatus remove_listener(const char* local_name, atransport* transport)
-    EXCLUDES(listener_list_mutex) {
-    std::lock_guard<std::mutex> lock(listener_list_mutex);
-    for (auto iter = listener_list.begin(); iter != listener_list.end(); ++iter) {
-        if (local_name == (*iter)->local_name) {
-            listener_list.erase(iter);
-            return INSTALL_STATUS_OK;
-        }
-    }
-    return INSTALL_STATUS_LISTENER_NOT_FOUND;
-}
-
-void remove_all_listeners() EXCLUDES(listener_list_mutex) {
-    std::lock_guard<std::mutex> lock(listener_list_mutex);
-    auto iter = listener_list.begin();
-    while (iter != listener_list.end()) {
-        // Never remove smart sockets.
-        if ((*iter)->connect_to[0] == '*') {
-            ++iter;
-        } else {
-            iter = listener_list.erase(iter);
-        }
-    }
-}
-
-void close_smartsockets() EXCLUDES(listener_list_mutex) {
-    std::lock_guard<std::mutex> lock(listener_list_mutex);
-    auto pred = [](const std::unique_ptr<alistener>& listener) {
-        return listener->local_name == "*smartsocket*";
-    };
-    listener_list.remove_if(pred);
-}
-
-InstallStatus install_listener(const std::string& local_name, const char* connect_to,
-                               atransport* transport, int no_rebind, int* resolved_tcp_port,
-                               std::string* error) EXCLUDES(listener_list_mutex) {
-    std::lock_guard<std::mutex> lock(listener_list_mutex);
-    for (auto& l : listener_list) {
-        if (local_name == l->local_name) {
-            // Can't repurpose a smartsocket.
-            if(l->connect_to[0] == '*') {
-                *error = "cannot repurpose smartsocket";
-                return INSTALL_STATUS_INTERNAL_ERROR;
-            }
-
-            // Can't repurpose a listener if 'no_rebind' is true.
-            if (no_rebind) {
-                *error = "cannot rebind";
-                return INSTALL_STATUS_CANNOT_REBIND;
-            }
-
-            l->connect_to = connect_to;
-            if (l->transport != transport) {
-                l->transport->RemoveDisconnect(&l->disconnect);
-                l->transport = transport;
-                l->transport->AddDisconnect(&l->disconnect);
-            }
-            return INSTALL_STATUS_OK;
-        }
-    }
-
-    auto listener = std::make_unique<alistener>(local_name, connect_to);
-
-    int resolved = 0;
-    listener->fd = socket_spec_listen(listener->local_name, error, &resolved);
-    if (listener->fd < 0) {
-        return INSTALL_STATUS_CANNOT_BIND;
-    }
-
-    // If the caller requested port 0, update the listener name with the resolved port.
-    if (resolved != 0) {
-        listener->local_name = android::base::StringPrintf("tcp:%d", resolved);
-        if (resolved_tcp_port) {
-            *resolved_tcp_port = resolved;
-        }
-    }
-
-    close_on_exec(listener->fd);
-    if (listener->connect_to == "*smartsocket*") {
-        listener->fde = fdevent_create(listener->fd, ss_listener_event_func, listener.get());
-    } else {
-        listener->fde = fdevent_create(listener->fd, listener_event_func, listener.get());
-    }
-    fdevent_set(listener->fde, FDE_READ);
-
-    listener->transport = transport;
-
-    if (transport) {
-        listener->disconnect.opaque = listener.get();
-        listener->disconnect.func = listener_disconnect;
-        transport->AddDisconnect(&listener->disconnect);
-    }
-
-    listener_list.push_back(std::move(listener));
-    return INSTALL_STATUS_OK;
-}
diff --git a/adb/adb_listeners.h b/adb/adb_listeners.h
deleted file mode 100644
index 70a2ee1..0000000
--- a/adb/adb_listeners.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef __ADB_LISTENERS_H
-#define __ADB_LISTENERS_H
-
-#include "adb.h"
-
-#include <string>
-
-#include <android-base/macros.h>
-
-// error/status codes for install_listener.
-enum InstallStatus {
-  INSTALL_STATUS_OK = 0,
-  INSTALL_STATUS_INTERNAL_ERROR = -1,
-  INSTALL_STATUS_CANNOT_BIND = -2,
-  INSTALL_STATUS_CANNOT_REBIND = -3,
-  INSTALL_STATUS_LISTENER_NOT_FOUND = -4,
-};
-
-InstallStatus install_listener(const std::string& local_name, const char* connect_to,
-                               atransport* transport, int no_rebind, int* resolved_tcp_port,
-                               std::string* error);
-
-std::string format_listeners();
-
-InstallStatus remove_listener(const char* local_name, atransport* transport);
-void remove_all_listeners(void);
-
-void close_smartsockets();
-
-#endif /* __ADB_LISTENERS_H */
diff --git a/adb/adb_listeners_test.cpp b/adb/adb_listeners_test.cpp
deleted file mode 100644
index a7e2dea..0000000
--- a/adb/adb_listeners_test.cpp
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "adb_listeners.h"
-
-#include <gtest/gtest.h>
-
-#include <android-base/stringprintf.h>
-#include <android-base/strings.h>
-
-#include "fdevent/fdevent.h"
-#include "sysdeps.h"
-#include "transport.h"
-
-// Returns true if the given listener is present in format_listeners(). Empty parameters will
-// be ignored.
-static bool listener_is_installed(const std::string& serial, const std::string& source,
-                                  const std::string& dest) {
-    // format_listeners() gives lines of "<serial> <source> <dest>\n".
-    for (const std::string& line : android::base::Split(format_listeners(), "\n")) {
-        std::vector<std::string> info = android::base::Split(line, " ");
-        if (info.size() == 3 &&
-                (serial.empty() || info[0] == serial) &&
-                (source.empty() || info[1] == source) &&
-                (dest.empty() || info[2] == dest)) {
-            return true;
-        }
-    }
-
-    return false;
-}
-
-class AdbListenersTest : public ::testing::Test {
-  public:
-    void SetUp() override {
-        // We don't need an fdevent loop, but adding/removing listeners must be done from the
-        // fdevent thread if one exists. Since previously run tests may have created an fdevent
-        // thread, we need to reset to prevent the thread check.
-        fdevent_reset();
-    }
-
-    void TearDown() override {
-        // Clean up any listeners that may have been installed.
-        remove_all_listeners();
-
-        // Make sure we didn't leave any dangling events.
-        ASSERT_EQ(0u, fdevent_installed_count());
-    }
-
-  protected:
-    atransport transport_;
-};
-
-TEST_F(AdbListenersTest, test_install_listener) {
-    std::string error;
-
-    ASSERT_EQ(INSTALL_STATUS_OK,
-              install_listener("tcp:9000", "tcp:9000", &transport_, false, nullptr, &error));
-    ASSERT_TRUE(error.empty());
-
-    ASSERT_TRUE(listener_is_installed("", "tcp:9000", "tcp:9000"));
-}
-
-TEST_F(AdbListenersTest, test_install_listener_rebind) {
-    std::string error;
-
-    ASSERT_EQ(INSTALL_STATUS_OK,
-              install_listener("tcp:9000", "tcp:9000", &transport_, false, nullptr, &error));
-    ASSERT_TRUE(error.empty());
-
-    ASSERT_EQ(INSTALL_STATUS_OK,
-              install_listener("tcp:9000", "tcp:9001", &transport_, false, nullptr, &error));
-    ASSERT_TRUE(error.empty());
-
-    ASSERT_TRUE(listener_is_installed("", "tcp:9000", "tcp:9001"));
-}
-
-TEST_F(AdbListenersTest, test_install_listener_no_rebind) {
-    std::string error;
-
-    ASSERT_EQ(INSTALL_STATUS_OK,
-              install_listener("tcp:9000", "tcp:9000", &transport_, true, nullptr, &error));
-    ASSERT_TRUE(error.empty());
-
-    ASSERT_EQ(INSTALL_STATUS_CANNOT_REBIND,
-              install_listener("tcp:9000", "tcp:9001", &transport_, true, nullptr, &error));
-    ASSERT_FALSE(error.empty());
-
-    ASSERT_TRUE(listener_is_installed("", "tcp:9000", "tcp:9000"));
-}
-
-TEST_F(AdbListenersTest, test_install_listener_tcp_port_0) {
-    int port = 0;
-    std::string error;
-
-    ASSERT_EQ(INSTALL_STATUS_OK,
-              install_listener("tcp:0", "tcp:9000", &transport_, true, &port, &error));
-    ASSERT_TRUE(error.empty());
-
-    ASSERT_TRUE(listener_is_installed("", android::base::StringPrintf("tcp:%d", port), "tcp:9000"));
-}
-
-TEST_F(AdbListenersTest, test_remove_listener) {
-    std::string error;
-
-    ASSERT_EQ(INSTALL_STATUS_OK,
-              install_listener("tcp:9000", "tcp:9000", &transport_, false, nullptr, &error));
-    ASSERT_TRUE(error.empty());
-
-    ASSERT_EQ(INSTALL_STATUS_OK, remove_listener("tcp:9000", &transport_));
-    ASSERT_TRUE(format_listeners().empty());
-}
-
-TEST_F(AdbListenersTest, test_remove_nonexistent_listener) {
-    std::string error;
-
-    ASSERT_EQ(INSTALL_STATUS_OK,
-              install_listener("tcp:9000", "tcp:9000", &transport_, false, nullptr, &error));
-    ASSERT_TRUE(error.empty());
-
-    ASSERT_EQ(INSTALL_STATUS_LISTENER_NOT_FOUND, remove_listener("tcp:1", &transport_));
-    ASSERT_TRUE(listener_is_installed("", "tcp:9000", "tcp:9000"));
-}
-
-TEST_F(AdbListenersTest, test_remove_all_listeners) {
-    std::string error;
-
-    ASSERT_EQ(INSTALL_STATUS_OK,
-              install_listener("tcp:9000", "tcp:9000", &transport_, false, nullptr, &error));
-    ASSERT_TRUE(error.empty());
-
-    ASSERT_EQ(INSTALL_STATUS_OK,
-              install_listener("tcp:9001", "tcp:9001", &transport_, false, nullptr, &error));
-    ASSERT_TRUE(error.empty());
-
-    remove_all_listeners();
-    ASSERT_TRUE(format_listeners().empty());
-}
-
-TEST_F(AdbListenersTest, test_transport_disconnect) {
-    std::string error;
-
-    ASSERT_EQ(INSTALL_STATUS_OK,
-              install_listener("tcp:9000", "tcp:9000", &transport_, false, nullptr, &error));
-    ASSERT_TRUE(error.empty());
-
-    ASSERT_EQ(INSTALL_STATUS_OK,
-              install_listener("tcp:9001", "tcp:9001", &transport_, false, nullptr, &error));
-    ASSERT_TRUE(error.empty());
-
-    transport_.RunDisconnects();
-    ASSERT_TRUE(format_listeners().empty());
-}
diff --git a/adb/adb_mdns.h b/adb/adb_mdns.h
deleted file mode 100644
index 3111248..0000000
--- a/adb/adb_mdns.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _ADB_MDNS_H_
-#define _ADB_MDNS_H_
-
-#include <android-base/macros.h>
-
-// The rules for Service Names [RFC6335] state that they may be no more
-// than fifteen characters long (not counting the mandatory underscore),
-// consisting of only letters, digits, and hyphens, must begin and end
-// with a letter or digit, must not contain consecutive hyphens, and
-// must contain at least one letter.
-#define ADB_MDNS_SERVICE_TYPE "adb"
-#define ADB_MDNS_TLS_PAIRING_TYPE "adb-tls-pairing"
-#define ADB_MDNS_TLS_CONNECT_TYPE "adb-tls-connect"
-
-const int kADBTransportServiceRefIndex = 0;
-const int kADBSecurePairingServiceRefIndex = 1;
-const int kADBSecureConnectServiceRefIndex = 2;
-
-// Each ADB Secure service advertises with a TXT record indicating the version
-// using a key/value pair per RFC 6763 (https://tools.ietf.org/html/rfc6763).
-//
-// The first key/value pair is always the version of the protocol.
-// There may be more key/value pairs added after.
-//
-// The version is purposely represented as the single letter "v" due to the
-// need to minimize DNS traffic. The version starts at 1.  With each breaking
-// protocol change, the version is incremented by 1.
-//
-// Newer adb clients/daemons need to recognize and either reject
-// or be backward-compatible with older verseions if there is a mismatch.
-//
-// Relevant sections:
-//
-// """
-// 6.4.  Rules for Keys in DNS-SD Key/Value Pairs
-//
-// The key MUST be at least one character.  DNS-SD TXT record strings
-// beginning with an '=' character (i.e., the key is missing) MUST be
-// silently ignored.
-//
-// ...
-//
-// 6.5.  Rules for Values in DNS-SD Key/Value Pairs
-//
-// If there is an '=' in a DNS-SD TXT record string, then everything
-// after the first '=' to the end of the string is the value.  The value
-// can contain any eight-bit values including '='.
-// """
-
-#define ADB_SECURE_SERVICE_VERSION_TXT_RECORD(ver) ("v=" #ver)
-
-// Client/service versions are initially defined to be matching,
-// but may go out of sync as different clients and services
-// try to talk to each other.
-#define ADB_SECURE_SERVICE_VERSION 1
-#define ADB_SECURE_CLIENT_VERSION ADB_SECURE_SERVICE_VERSION
-
-const char* kADBSecurePairingServiceTxtRecord =
-        ADB_SECURE_SERVICE_VERSION_TXT_RECORD(ADB_SECURE_SERVICE_VERSION);
-const char* kADBSecureConnectServiceTxtRecord =
-        ADB_SECURE_SERVICE_VERSION_TXT_RECORD(ADB_SECURE_SERVICE_VERSION);
-
-#define ADB_FULL_MDNS_SERVICE_TYPE(atype) ("_" atype "._tcp")
-const char* kADBDNSServices[] = {ADB_FULL_MDNS_SERVICE_TYPE(ADB_MDNS_SERVICE_TYPE),
-                                 ADB_FULL_MDNS_SERVICE_TYPE(ADB_MDNS_TLS_PAIRING_TYPE),
-                                 ADB_FULL_MDNS_SERVICE_TYPE(ADB_MDNS_TLS_CONNECT_TYPE)};
-
-const char* kADBDNSServiceTxtRecords[] = {
-        nullptr,
-        kADBSecurePairingServiceTxtRecord,
-        kADBSecureConnectServiceTxtRecord,
-};
-
-const int kNumADBDNSServices = arraysize(kADBDNSServices);
-
-#endif
diff --git a/adb/adb_test.xml b/adb/adb_test.xml
deleted file mode 100644
index cc3302d..0000000
--- a/adb/adb_test.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2020 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<!-- This test config file is auto-generated. -->
-<configuration description="Runs adbd_test.">
-    <option name="test-suite-tag" value="apct" />
-    <option name="test-suite-tag" value="apct-native" />
-
-    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
-    </target_preparer>
-
-    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
-        <option name="cleanup" value="true" />
-        <option name="push" value="adbd_test->/data/local/tmp/adbd_test" />
-    </target_preparer>
-
-    <test class="com.android.tradefed.testtype.GTest" >
-        <option name="native-test-device-path" value="/data/local/tmp" />
-        <option name="module-name" value="adbd_test" />
-    </test>
-
-    <object type="module_controller" class="com.android.tradefed.testtype.suite.module.MainlineTestModuleController">
-      <option name="mainline-module-package-name" value="com.google.android.adbd" />
-    </object>
-</configuration>
diff --git a/adb/adb_trace.cpp b/adb/adb_trace.cpp
deleted file mode 100644
index cea24fe..0000000
--- a/adb/adb_trace.cpp
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "sysdeps.h"
-#include "adb_trace.h"
-
-#include <string>
-#include <unordered_map>
-#include <vector>
-
-#include <android-base/logging.h>
-#include <android-base/strings.h>
-
-#include "adb.h"
-
-#if !ADB_HOST
-#include <android-base/properties.h>
-#endif
-
-#if !ADB_HOST
-const char* adb_device_banner = "device";
-#if defined(__ANDROID__)
-static android::base::LogdLogger gLogdLogger;
-#endif
-#else
-const char* adb_device_banner = "host";
-#endif
-
-void AdbLogger(android::base::LogId id, android::base::LogSeverity severity,
-               const char* tag, const char* file, unsigned int line,
-               const char* message) {
-    android::base::StderrLogger(id, severity, tag, file, line, message);
-#if defined(_WIN32)
-    // stderr can be buffered on Windows (and setvbuf doesn't seem to work), so explicitly flush.
-    fflush(stderr);
-#endif
-
-#if !ADB_HOST && defined(__ANDROID__)
-    // Only print logs of INFO or higher to logcat, so that `adb logcat` with adbd tracing on
-    // doesn't result in exponential logging.
-    if (severity >= android::base::INFO) {
-        gLogdLogger(id, severity, tag, file, line, message);
-    }
-#endif
-}
-
-
-#if !ADB_HOST
-static std::string get_log_file_name() {
-    struct tm now;
-    time_t t;
-    tzset();
-    time(&t);
-    localtime_r(&t, &now);
-
-    char timestamp[PATH_MAX];
-    strftime(timestamp, sizeof(timestamp), "%Y-%m-%d-%H-%M-%S", &now);
-
-    return android::base::StringPrintf("/data/adb/adb-%s-%d", timestamp,
-                                       getpid());
-}
-
-void start_device_log(void) {
-    int fd = unix_open(get_log_file_name(), O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, 0640);
-    if (fd == -1) {
-        return;
-    }
-
-    // Redirect stdout and stderr to the log file.
-    dup2(fd, STDOUT_FILENO);
-    dup2(fd, STDERR_FILENO);
-    fprintf(stderr, "--- adb starting (pid %d) ---\n", getpid());
-    unix_close(fd);
-}
-#endif
-
-int adb_trace_mask;
-
-std::string get_trace_setting_from_env() {
-    const char* setting = getenv("ADB_TRACE");
-    if (setting == nullptr) {
-        setting = "";
-    }
-
-    return std::string(setting);
-}
-
-std::string get_trace_setting() {
-#if ADB_HOST
-    return get_trace_setting_from_env();
-#else
-    return android::base::GetProperty("persist.adb.trace_mask", "");
-#endif
-}
-
-// Split the space separated list of tags from the trace setting and build the
-// trace mask from it. note that '1' and 'all' are special cases to enable all
-// tracing.
-//
-// adb's trace setting comes from the ADB_TRACE environment variable, whereas
-// adbd's comes from the system property persist.adb.trace_mask.
-static void setup_trace_mask() {
-    const std::string trace_setting = get_trace_setting();
-    if (trace_setting.empty()) {
-        return;
-    }
-
-    std::unordered_map<std::string, int> trace_flags = {{"1", -1},
-                                                        {"all", -1},
-                                                        {"adb", ADB},
-                                                        {"sockets", SOCKETS},
-                                                        {"packets", PACKETS},
-                                                        {"rwx", RWX},
-                                                        {"usb", USB},
-                                                        {"sync", SYNC},
-                                                        {"sysdeps", SYSDEPS},
-                                                        {"transport", TRANSPORT},
-                                                        {"jdwp", JDWP},
-                                                        {"services", SERVICES},
-                                                        {"auth", AUTH},
-                                                        {"fdevent", FDEVENT},
-                                                        {"shell", SHELL},
-                                                        {"incremental", INCREMENTAL}};
-
-    std::vector<std::string> elements = android::base::Split(trace_setting, " ");
-    for (const auto& elem : elements) {
-        const auto& flag = trace_flags.find(elem);
-        if (flag == trace_flags.end()) {
-            LOG(ERROR) << "Unknown trace flag: " << elem;
-            continue;
-        }
-
-        if (flag->second == -1) {
-            // -1 is used for the special values "1" and "all" that enable all
-            // tracing.
-            adb_trace_mask = ~0;
-            break;
-        } else {
-            adb_trace_mask |= 1 << flag->second;
-        }
-    }
-
-    if (adb_trace_mask != 0) {
-        android::base::SetMinimumLogSeverity(android::base::VERBOSE);
-    }
-}
-
-void adb_trace_init(char** argv) {
-#if !ADB_HOST
-    // Don't open log file if no tracing, since this will block
-    // the crypto unmount of /data
-    if (!get_trace_setting().empty()) {
-        if (unix_isatty(STDOUT_FILENO) == 0) {
-            start_device_log();
-        }
-    }
-#endif
-
-#if ADB_HOST && !defined(_WIN32)
-    // adb historically ignored $ANDROID_LOG_TAGS but passed it through to logcat.
-    // If set, move it out of the way so that libbase logging doesn't try to parse it.
-    std::string log_tags;
-    char* ANDROID_LOG_TAGS = getenv("ANDROID_LOG_TAGS");
-    if (ANDROID_LOG_TAGS) {
-        log_tags = ANDROID_LOG_TAGS;
-        unsetenv("ANDROID_LOG_TAGS");
-    }
-#endif
-
-    android::base::InitLogging(argv, &AdbLogger);
-
-#if ADB_HOST && !defined(_WIN32)
-    // Put $ANDROID_LOG_TAGS back so we can pass it to logcat.
-    if (!log_tags.empty()) setenv("ANDROID_LOG_TAGS", log_tags.c_str(), 1);
-#endif
-
-    setup_trace_mask();
-
-    VLOG(ADB) << adb_version();
-}
-
-void adb_trace_enable(AdbTrace trace_tag) {
-    adb_trace_mask |= (1 << trace_tag);
-}
diff --git a/adb/adb_trace.h b/adb/adb_trace.h
deleted file mode 100644
index 3421a02..0000000
--- a/adb/adb_trace.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef __ADB_TRACE_H
-#define __ADB_TRACE_H
-
-#include <android-base/logging.h>
-#include <android-base/stringprintf.h>
-
-/* IMPORTANT: if you change the following list, don't
- * forget to update the corresponding 'tags' table in
- * the adb_trace_init() function implemented in adb_trace.cpp.
- */
-enum AdbTrace {
-    ADB = 0, /* 0x001 */
-    SOCKETS,
-    PACKETS,
-    TRANSPORT,
-    RWX, /* 0x010 */
-    USB,
-    SYNC,
-    SYSDEPS,
-    JDWP, /* 0x100 */
-    SERVICES,
-    AUTH,
-    FDEVENT,
-    SHELL,
-    INCREMENTAL,
-};
-
-#define VLOG_IS_ON(TAG) \
-    ((adb_trace_mask & (1 << (TAG))) != 0)
-
-#define VLOG(TAG)                 \
-    if (LIKELY(!VLOG_IS_ON(TAG))) \
-        ;                         \
-    else                          \
-        LOG(DEBUG)
-
-// You must define TRACE_TAG before using this macro.
-#define D(...) \
-    VLOG(TRACE_TAG) << android::base::StringPrintf(__VA_ARGS__)
-
-
-extern int adb_trace_mask;
-void adb_trace_init(char**);
-void adb_trace_enable(AdbTrace trace_tag);
-
-#endif /* __ADB_TRACE_H */
diff --git a/adb/adb_unique_fd.cpp b/adb/adb_unique_fd.cpp
deleted file mode 100644
index dec73bc..0000000
--- a/adb/adb_unique_fd.cpp
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "adb_unique_fd.h"
-
-#include <errno.h>
-#include <unistd.h>
-
-#include "sysdeps.h"
-
-#if defined(_WIN32)
-void AdbCloser::Close(int fd) {
-    adb_close(fd);
-}
-#endif
diff --git a/adb/adb_unique_fd.h b/adb/adb_unique_fd.h
deleted file mode 100644
index b6c910a..0000000
--- a/adb/adb_unique_fd.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <errno.h>
-#include <unistd.h>
-
-#include <android-base/unique_fd.h>
-
-#if defined(_WIN32)
-// Helper to automatically close an FD when it goes out of scope.
-struct AdbCloser {
-    static void Close(int fd);
-};
-
-using unique_fd = android::base::unique_fd_impl<AdbCloser>;
-#else
-using unique_fd = android::base::unique_fd;
-#endif
-
-using android::base::borrowed_fd;
-
-template <typename T>
-int adb_close(const android::base::unique_fd_impl<T>&)
-        __attribute__((__unavailable__("adb_close called on unique_fd")));
diff --git a/adb/adb_utils.cpp b/adb/adb_utils.cpp
deleted file mode 100644
index d1910f1..0000000
--- a/adb/adb_utils.cpp
+++ /dev/null
@@ -1,380 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define TRACE_TAG ADB
-
-#include "adb_utils.h"
-#include "adb_unique_fd.h"
-
-#include <stdlib.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include <algorithm>
-#include <vector>
-
-#include <android-base/file.h>
-#include <android-base/logging.h>
-#include <android-base/parseint.h>
-#include <android-base/stringprintf.h>
-#include <android-base/strings.h>
-
-#include "adb.h"
-#include "adb_trace.h"
-#include "sysdeps.h"
-
-#ifdef _WIN32
-#  ifndef WIN32_LEAN_AND_MEAN
-#    define WIN32_LEAN_AND_MEAN
-#  endif
-#  include "windows.h"
-#  include "shlobj.h"
-#else
-#include <pwd.h>
-#endif
-
-
-#if defined(_WIN32)
-static constexpr char kNullFileName[] = "NUL";
-#else
-static constexpr char kNullFileName[] = "/dev/null";
-#endif
-
-void close_stdin() {
-    int fd = unix_open(kNullFileName, O_RDONLY);
-    if (fd == -1) {
-        PLOG(FATAL) << "failed to open " << kNullFileName;
-    }
-
-    if (TEMP_FAILURE_RETRY(dup2(fd, STDIN_FILENO)) == -1) {
-        PLOG(FATAL) << "failed to redirect stdin to " << kNullFileName;
-    }
-    unix_close(fd);
-}
-
-bool getcwd(std::string* s) {
-  char* cwd = getcwd(nullptr, 0);
-  if (cwd != nullptr) *s = cwd;
-  free(cwd);
-  return (cwd != nullptr);
-}
-
-bool directory_exists(const std::string& path) {
-  struct stat sb;
-  return stat(path.c_str(), &sb) != -1 && S_ISDIR(sb.st_mode);
-}
-
-std::string escape_arg(const std::string& s) {
-  // Escape any ' in the string (before we single-quote the whole thing).
-  // The correct way to do this for the shell is to replace ' with '\'' --- that is,
-  // close the existing single-quoted string, escape a single single-quote, and start
-  // a new single-quoted string. Like the C preprocessor, the shell will concatenate
-  // these pieces into one string.
-
-  std::string result;
-  result.push_back('\'');
-
-  size_t base = 0;
-  while (true) {
-    size_t found = s.find('\'', base);
-    result.append(s, base, found - base);
-    if (found == s.npos) break;
-    result.append("'\\''");
-    base = found + 1;
-  }
-
-  result.push_back('\'');
-  return result;
-}
-
-// Given a relative or absolute filepath, create the directory hierarchy
-// as needed. Returns true if the hierarchy is/was setup.
-bool mkdirs(const std::string& path) {
-  // TODO: all the callers do unlink && mkdirs && adb_creat ---
-  // that's probably the operation we should expose.
-
-  // Implementation Notes:
-  //
-  // Pros:
-  // - Uses dirname, so does not need to deal with OS_PATH_SEPARATOR.
-  // - On Windows, uses mingw dirname which accepts '/' and '\\', drive letters
-  //   (C:\foo), UNC paths (\\server\share\dir\dir\file), and Unicode (when
-  //   combined with our adb_mkdir() which takes UTF-8).
-  // - Is optimistic wrt thinking that a deep directory hierarchy will exist.
-  //   So it does as few stat()s as possible before doing mkdir()s.
-  // Cons:
-  // - Recursive, so it uses stack space relative to number of directory
-  //   components.
-
-  // If path points to a symlink to a directory, that's fine.
-  struct stat sb;
-  if (stat(path.c_str(), &sb) != -1 && S_ISDIR(sb.st_mode)) {
-    return true;
-  }
-
-  const std::string parent(android::base::Dirname(path));
-
-  // If dirname returned the same path as what we passed in, don't go recursive.
-  // This can happen on Windows when walking up the directory hierarchy and not
-  // finding anything that already exists (unlike POSIX that will eventually
-  // find . or /).
-  if (parent == path) {
-    errno = ENOENT;
-    return false;
-  }
-
-  // Recursively make parent directories of 'path'.
-  if (!mkdirs(parent)) {
-    return false;
-  }
-
-  // Now that the parent directory hierarchy of 'path' has been ensured,
-  // create path itself.
-  if (adb_mkdir(path, 0775) == -1) {
-    const int saved_errno = errno;
-    // If someone else created the directory, that is ok.
-    if (directory_exists(path)) {
-      return true;
-    }
-    // There might be a pre-existing file at 'path', or there might have been some other error.
-    errno = saved_errno;
-    return false;
-  }
-
-  return true;
-}
-
-std::string dump_hex(const void* data, size_t byte_count) {
-    size_t truncate_len = 16;
-    bool truncated = false;
-    if (byte_count > truncate_len) {
-        byte_count = truncate_len;
-        truncated = true;
-    }
-
-    const uint8_t* p = reinterpret_cast<const uint8_t*>(data);
-
-    std::string line;
-    for (size_t i = 0; i < byte_count; ++i) {
-        android::base::StringAppendF(&line, "%02x", p[i]);
-    }
-    line.push_back(' ');
-
-    for (size_t i = 0; i < byte_count; ++i) {
-        int ch = p[i];
-        line.push_back(isprint(ch) ? ch : '.');
-    }
-
-    if (truncated) {
-        line += " [truncated]";
-    }
-
-    return line;
-}
-
-std::string dump_header(const amessage* msg) {
-    unsigned command = msg->command;
-    int len = msg->data_length;
-    char cmd[9];
-    char arg0[12], arg1[12];
-    int n;
-
-    for (n = 0; n < 4; n++) {
-        int b = (command >> (n * 8)) & 255;
-        if (b < 32 || b >= 127) break;
-        cmd[n] = (char)b;
-    }
-    if (n == 4) {
-        cmd[4] = 0;
-    } else {
-        // There is some non-ASCII name in the command, so dump the hexadecimal value instead
-        snprintf(cmd, sizeof cmd, "%08x", command);
-    }
-
-    if (msg->arg0 < 256U)
-        snprintf(arg0, sizeof arg0, "%d", msg->arg0);
-    else
-        snprintf(arg0, sizeof arg0, "0x%x", msg->arg0);
-
-    if (msg->arg1 < 256U)
-        snprintf(arg1, sizeof arg1, "%d", msg->arg1);
-    else
-        snprintf(arg1, sizeof arg1, "0x%x", msg->arg1);
-
-    return android::base::StringPrintf("[%s] arg0=%s arg1=%s (len=%d) ", cmd, arg0, arg1, len);
-}
-
-std::string dump_packet(const char* name, const char* func, const apacket* p) {
-    std::string result = name;
-    result += ": ";
-    result += func;
-    result += ": ";
-    result += dump_header(&p->msg);
-    result += dump_hex(p->payload.data(), p->payload.size());
-    return result;
-}
-
-std::string perror_str(const char* msg) {
-    return android::base::StringPrintf("%s: %s", msg, strerror(errno));
-}
-
-#if !defined(_WIN32)
-// Windows version provided in sysdeps_win32.cpp
-bool set_file_block_mode(borrowed_fd fd, bool block) {
-    int flags = fcntl(fd.get(), F_GETFL, 0);
-    if (flags == -1) {
-        PLOG(ERROR) << "failed to fcntl(F_GETFL) for fd " << fd.get();
-        return false;
-    }
-    flags = block ? (flags & ~O_NONBLOCK) : (flags | O_NONBLOCK);
-    if (fcntl(fd.get(), F_SETFL, flags) != 0) {
-        PLOG(ERROR) << "failed to fcntl(F_SETFL) for fd " << fd.get() << ", flags " << flags;
-        return false;
-    }
-    return true;
-}
-#endif
-
-bool forward_targets_are_valid(const std::string& source, const std::string& dest,
-                               std::string* error) {
-    if (android::base::StartsWith(source, "tcp:")) {
-        // The source port may be 0 to allow the system to select an open port.
-        int port;
-        if (!android::base::ParseInt(&source[4], &port) || port < 0) {
-            *error = android::base::StringPrintf("Invalid source port: '%s'", &source[4]);
-            return false;
-        }
-    }
-
-    if (android::base::StartsWith(dest, "tcp:")) {
-        // The destination port must be > 0.
-        int port;
-        if (!android::base::ParseInt(&dest[4], &port) || port <= 0) {
-            *error = android::base::StringPrintf("Invalid destination port: '%s'", &dest[4]);
-            return false;
-        }
-    }
-
-    return true;
-}
-
-std::string adb_get_homedir_path() {
-#ifdef _WIN32
-    WCHAR path[MAX_PATH];
-    const HRESULT hr = SHGetFolderPathW(NULL, CSIDL_PROFILE, NULL, 0, path);
-    if (FAILED(hr)) {
-        D("SHGetFolderPathW failed: %s", android::base::SystemErrorCodeToString(hr).c_str());
-        return {};
-    }
-    std::string home_str;
-    if (!android::base::WideToUTF8(path, &home_str)) {
-        return {};
-    }
-    return home_str;
-#else
-    if (const char* const home = getenv("HOME")) {
-        return home;
-    }
-
-    struct passwd pwent;
-    struct passwd* result;
-    int pwent_max = sysconf(_SC_GETPW_R_SIZE_MAX);
-    if (pwent_max == -1) {
-        pwent_max = 16384;
-    }
-    std::vector<char> buf(pwent_max);
-    int rc = getpwuid_r(getuid(), &pwent, buf.data(), buf.size(), &result);
-    if (rc == 0 && result) {
-        return result->pw_dir;
-    }
-
-    LOG(FATAL) << "failed to get user home directory";
-    return {};
-#endif
-}
-
-std::string adb_get_android_dir_path() {
-    std::string user_dir = adb_get_homedir_path();
-    std::string android_dir = user_dir + OS_PATH_SEPARATOR + ".android";
-    struct stat buf;
-    if (stat(android_dir.c_str(), &buf) == -1) {
-        if (adb_mkdir(android_dir, 0750) == -1) {
-            PLOG(FATAL) << "Cannot mkdir '" << android_dir << "'";
-        }
-    }
-    return android_dir;
-}
-
-std::string GetLogFilePath() {
-    // https://issuetracker.google.com/112588493
-    const char* path = getenv("ANDROID_ADB_LOG_PATH");
-    if (path) return path;
-
-#if defined(_WIN32)
-    const char log_name[] = "adb.log";
-    WCHAR temp_path[MAX_PATH];
-
-    // https://msdn.microsoft.com/en-us/library/windows/desktop/aa364992%28v=vs.85%29.aspx
-    DWORD nchars = GetTempPathW(arraysize(temp_path), temp_path);
-    if (nchars >= arraysize(temp_path) || nchars == 0) {
-        // If string truncation or some other error.
-        LOG(FATAL) << "cannot retrieve temporary file path: "
-                   << android::base::SystemErrorCodeToString(GetLastError());
-    }
-
-    std::string temp_path_utf8;
-    if (!android::base::WideToUTF8(temp_path, &temp_path_utf8)) {
-        PLOG(FATAL) << "cannot convert temporary file path from UTF-16 to UTF-8";
-    }
-
-    return temp_path_utf8 + log_name;
-#else
-    const char* tmp_dir = getenv("TMPDIR");
-    if (tmp_dir == nullptr) tmp_dir = "/tmp";
-    return android::base::StringPrintf("%s/adb.%u.log", tmp_dir, getuid());
-#endif
-}
-
-[[noreturn]] static void error_exit_va(int error, const char* fmt, va_list va) {
-    fflush(stdout);
-    fprintf(stderr, "%s: ", android::base::Basename(android::base::GetExecutablePath()).c_str());
-
-    vfprintf(stderr, fmt, va);
-
-    if (error != 0) {
-        fprintf(stderr, ": %s", strerror(error));
-    }
-
-    putc('\n', stderr);
-    fflush(stderr);
-
-    exit(EXIT_FAILURE);
-}
-
-void error_exit(const char* fmt, ...) {
-    va_list va;
-    va_start(va, fmt);
-    error_exit_va(0, fmt, va);
-    va_end(va);
-}
-
-void perror_exit(const char* fmt, ...) {
-    va_list va;
-    va_start(va, fmt);
-    error_exit_va(errno, fmt, va);
-    va_end(va);
-}
diff --git a/adb/adb_utils.h b/adb/adb_utils.h
deleted file mode 100644
index 66cba12..0000000
--- a/adb/adb_utils.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <charconv>
-#include <condition_variable>
-#include <mutex>
-#include <string>
-#include <string_view>
-#include <type_traits>
-#include <vector>
-
-#include <android-base/macros.h>
-
-#include "adb.h"
-#include "adb_unique_fd.h"
-
-void close_stdin();
-
-bool getcwd(std::string* cwd);
-bool directory_exists(const std::string& path);
-
-// Return the user's home directory.
-std::string adb_get_homedir_path();
-
-// Return the adb user directory.
-std::string adb_get_android_dir_path();
-
-bool mkdirs(const std::string& path);
-
-std::string escape_arg(const std::string& s);
-
-std::string dump_hex(const void* ptr, size_t byte_count);
-std::string dump_header(const amessage* msg);
-std::string dump_packet(const char* name, const char* func, const apacket* p);
-
-std::string perror_str(const char* msg);
-
-[[noreturn]] void error_exit(const char* fmt, ...) __attribute__((__format__(__printf__, 1, 2)));
-[[noreturn]] void perror_exit(const char* fmt, ...) __attribute__((__format__(__printf__, 1, 2)));
-
-bool set_file_block_mode(borrowed_fd fd, bool block);
-
-// Given forward/reverse targets, returns true if they look sane. If an error is found, fills
-// |error| and returns false.
-// Currently this only checks "tcp:" targets. Additional checking could be added for other targets
-// if needed.
-bool forward_targets_are_valid(const std::string& source, const std::string& dest,
-                               std::string* error);
-
-// A thread-safe blocking queue.
-template <typename T>
-class BlockingQueue {
-    std::mutex mutex;
-    std::condition_variable cv;
-    std::vector<T> queue;
-
-  public:
-    void Push(const T& t) {
-        {
-            std::unique_lock<std::mutex> lock(mutex);
-            queue.push_back(t);
-        }
-        cv.notify_one();
-    }
-
-    template <typename Fn>
-    void PopAll(Fn fn) {
-        std::vector<T> popped;
-
-        {
-            std::unique_lock<std::mutex> lock(mutex);
-            cv.wait(lock, [this]() { return !queue.empty(); });
-            popped = std::move(queue);
-            queue.clear();
-        }
-
-        for (const T& t : popped) {
-            fn(t);
-        }
-    }
-};
-
-std::string GetLogFilePath();
-
-inline std::string_view StripTrailingNulls(std::string_view str) {
-    size_t n = 0;
-    for (auto it = str.rbegin(); it != str.rend(); ++it) {
-        if (*it != '\0') {
-            break;
-        }
-        ++n;
-    }
-
-    str.remove_suffix(n);
-    return str;
-}
-
-// Base-10 stroll on a string_view.
-template <typename T>
-inline bool ParseUint(T* result, std::string_view str, std::string_view* remaining = nullptr) {
-    T value;
-    const auto res = std::from_chars(str.begin(), str.end(), value);
-    if (res.ec != std::errc{}) {
-        return false;
-    }
-    if (res.ptr != str.end() && !remaining) {
-        return false;
-    }
-    if (remaining) {
-        *remaining = std::string_view(res.ptr, str.end() - res.ptr);
-    }
-    *result = value;
-    return true;
-}
diff --git a/adb/adb_utils_test.cpp b/adb/adb_utils_test.cpp
deleted file mode 100644
index cdca3aa..0000000
--- a/adb/adb_utils_test.cpp
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "adb_utils.h"
-
-#ifdef _WIN32
-#include <windows.h>
-#include <userenv.h>
-#endif
-
-#include <string>
-
-#include <gtest/gtest.h>
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "sysdeps.h"
-
-#include <android-base/file.h>
-#include <android-base/macros.h>
-
-#ifdef _WIN32
-static std::string subdir(const char* parent, const char* child) {
-  std::string str(parent);
-  str += OS_PATH_SEPARATOR;
-  str += child;
-  return str;
-}
-#endif
-
-TEST(adb_utils, directory_exists) {
-#ifdef _WIN32
-  char profiles_dir[MAX_PATH];
-  DWORD cch = arraysize(profiles_dir);
-
-  // On typical Windows 7, returns C:\Users
-  ASSERT_TRUE(GetProfilesDirectoryA(profiles_dir, &cch));
-
-  ASSERT_TRUE(directory_exists(profiles_dir));
-
-  ASSERT_FALSE(directory_exists(subdir(profiles_dir, "does-not-exist")));
-#else
-  ASSERT_TRUE(directory_exists("/proc"));
-  ASSERT_FALSE(directory_exists("/proc/does-not-exist"));
-#endif
-}
-
-#if defined(_WIN32)
-TEST(adb_utils, directory_exists_win32_symlink_junction) {
-  char profiles_dir[MAX_PATH];
-  DWORD cch = arraysize(profiles_dir);
-
-  // On typical Windows 7, returns C:\Users
-  ASSERT_TRUE(GetProfilesDirectoryA(profiles_dir, &cch));
-
-  // On modern (English?) Windows, this is a directory symbolic link to
-  // C:\ProgramData. Symbolic links are rare on Windows and the user requires
-  // a special permission (by default granted to Administrative users) to
-  // create symbolic links.
-  EXPECT_FALSE(directory_exists(subdir(profiles_dir, "All Users")));
-
-  // On modern (English?) Windows, this is a directory junction to
-  // C:\Users\Default. Junctions are used throughout user profile directories
-  // for backwards compatibility and they don't require any special permissions
-  // to create.
-  EXPECT_FALSE(directory_exists(subdir(profiles_dir, "Default User")));
-}
-#endif
-
-TEST(adb_utils, escape_arg) {
-  EXPECT_EQ(R"('')", escape_arg(""));
-
-  EXPECT_EQ(R"('abc')", escape_arg("abc"));
-
-  auto wrap = [](const std::string& x) { return '\'' + x + '\''; };
-  const std::string q = R"('\'')";
-  EXPECT_EQ(wrap(q), escape_arg("'"));
-  EXPECT_EQ(wrap(q + q), escape_arg("''"));
-  EXPECT_EQ(wrap(q + "abc" + q), escape_arg("'abc'"));
-  EXPECT_EQ(wrap(q + "abc"), escape_arg("'abc"));
-  EXPECT_EQ(wrap("abc" + q), escape_arg("abc'"));
-  EXPECT_EQ(wrap("abc" + q + "def"), escape_arg("abc'def"));
-  EXPECT_EQ(wrap("a" + q + "b" + q + "c"), escape_arg("a'b'c"));
-  EXPECT_EQ(wrap("a" + q + "bcde" + q + "f"), escape_arg("a'bcde'f"));
-
-  EXPECT_EQ(R"(' abc')", escape_arg(" abc"));
-  EXPECT_EQ(R"('"abc')", escape_arg("\"abc"));
-  EXPECT_EQ(R"('\abc')", escape_arg("\\abc"));
-  EXPECT_EQ(R"('(abc')", escape_arg("(abc"));
-  EXPECT_EQ(R"(')abc')", escape_arg(")abc"));
-
-  EXPECT_EQ(R"('abc abc')", escape_arg("abc abc"));
-  EXPECT_EQ(R"('abc"abc')", escape_arg("abc\"abc"));
-  EXPECT_EQ(R"('abc\abc')", escape_arg("abc\\abc"));
-  EXPECT_EQ(R"('abc(abc')", escape_arg("abc(abc"));
-  EXPECT_EQ(R"('abc)abc')", escape_arg("abc)abc"));
-
-  EXPECT_EQ(R"('abc ')", escape_arg("abc "));
-  EXPECT_EQ(R"('abc"')", escape_arg("abc\""));
-  EXPECT_EQ(R"('abc\')", escape_arg("abc\\"));
-  EXPECT_EQ(R"('abc(')", escape_arg("abc("));
-  EXPECT_EQ(R"('abc)')", escape_arg("abc)"));
-}
-
-void test_mkdirs(const std::string& basepath) {
-  // Test creating a directory hierarchy.
-  ASSERT_TRUE(mkdirs(basepath));
-  // Test finding an existing directory hierarchy.
-  ASSERT_TRUE(mkdirs(basepath));
-  // Test mkdirs on an existing hierarchy with a trailing slash.
-  ASSERT_TRUE(mkdirs(basepath + '/'));
-#if defined(_WIN32)
-  ASSERT_TRUE(mkdirs(basepath + '\\'));
-#endif
-
-  const std::string filepath = basepath + "/file";
-  // Verify that the hierarchy was created by trying to create a file in it.
-  ASSERT_NE(-1, adb_creat(filepath.c_str(), 0600));
-  // If a file exists where we want a directory, the operation should fail.
-  ASSERT_FALSE(mkdirs(filepath));
-}
-
-TEST(adb_utils, mkdirs) {
-  TemporaryDir td;
-
-  // Absolute paths.
-  test_mkdirs(std::string(td.path) + "/dir/subdir");
-
-  // Relative paths.
-  ASSERT_EQ(0, chdir(td.path)) << strerror(errno);
-  test_mkdirs(std::string("relative/subrel"));
-}
-
-#if !defined(_WIN32)
-TEST(adb_utils, set_file_block_mode) {
-    unique_fd fd(adb_open("/dev/null", O_RDWR | O_APPEND));
-    ASSERT_GE(fd, 0);
-    int flags = fcntl(fd.get(), F_GETFL, 0);
-    ASSERT_EQ(O_RDWR | O_APPEND, (flags & (O_RDWR | O_APPEND)));
-    ASSERT_TRUE(set_file_block_mode(fd, false));
-    int new_flags = fcntl(fd.get(), F_GETFL, 0);
-    ASSERT_EQ(flags | O_NONBLOCK, new_flags);
-    ASSERT_TRUE(set_file_block_mode(fd, true));
-    new_flags = fcntl(fd.get(), F_GETFL, 0);
-    ASSERT_EQ(flags, new_flags);
-}
-#endif
-
-TEST(adb_utils, test_forward_targets_are_valid) {
-    std::string error;
-
-    // Source port can be >= 0.
-    EXPECT_FALSE(forward_targets_are_valid("tcp:-1", "tcp:9000", &error));
-    EXPECT_TRUE(forward_targets_are_valid("tcp:0", "tcp:9000", &error));
-    EXPECT_TRUE(forward_targets_are_valid("tcp:8000", "tcp:9000", &error));
-
-    // Destination port must be >0.
-    EXPECT_FALSE(forward_targets_are_valid("tcp:8000", "tcp:-1", &error));
-    EXPECT_FALSE(forward_targets_are_valid("tcp:8000", "tcp:0", &error));
-
-    // Port must be a number.
-    EXPECT_FALSE(forward_targets_are_valid("tcp:", "tcp:9000", &error));
-    EXPECT_FALSE(forward_targets_are_valid("tcp:a", "tcp:9000", &error));
-    EXPECT_FALSE(forward_targets_are_valid("tcp:22x", "tcp:9000", &error));
-    EXPECT_FALSE(forward_targets_are_valid("tcp:8000", "tcp:", &error));
-    EXPECT_FALSE(forward_targets_are_valid("tcp:8000", "tcp:a", &error));
-    EXPECT_FALSE(forward_targets_are_valid("tcp:8000", "tcp:22x", &error));
-}
-
-void TestParseUint(std::string_view string, bool expected_success, uint32_t expected_value = 0) {
-    // Standalone.
-    {
-        uint32_t value;
-        std::string_view remaining;
-        bool success = ParseUint(&value, string, &remaining);
-        EXPECT_EQ(success, expected_success);
-        if (expected_success) {
-            EXPECT_EQ(value, expected_value);
-        }
-        EXPECT_TRUE(remaining.empty());
-    }
-
-    // With trailing text.
-    {
-        std::string text = std::string(string) + "foo";
-        uint32_t value;
-        std::string_view remaining;
-        bool success = ParseUint(&value, text, &remaining);
-        EXPECT_EQ(success, expected_success);
-        if (expected_success) {
-            EXPECT_EQ(value, expected_value);
-            EXPECT_EQ(remaining, "foo");
-        }
-    }
-
-    // With trailing text, without remaining.
-    {
-        std::string text = std::string(string) + "foo";
-        uint32_t value;
-        bool success = ParseUint(&value, text, nullptr);
-        EXPECT_EQ(success, false);
-    }
-}
-
-TEST(adb_utils, ParseUint) {
-    TestParseUint("", false);
-    TestParseUint("foo", false);
-    TestParseUint("foo123", false);
-    TestParseUint("-1", false);
-
-    TestParseUint("123", true, 123);
-    TestParseUint("9999999999999999999999999", false);
-    TestParseUint(std::to_string(UINT32_MAX), true, UINT32_MAX);
-    TestParseUint("0" + std::to_string(UINT32_MAX), true, UINT32_MAX);
-    TestParseUint(std::to_string(static_cast<uint64_t>(UINT32_MAX) + 1), false);
-    TestParseUint("0" + std::to_string(static_cast<uint64_t>(UINT32_MAX) + 1), false);
-
-    std::string x = std::to_string(UINT32_MAX) + "123";
-    std::string_view substr = std::string_view(x).substr(0, std::to_string(UINT32_MAX).size());
-    TestParseUint(substr, true, UINT32_MAX);
-}
diff --git a/adb/adb_wifi.h b/adb/adb_wifi.h
deleted file mode 100644
index 585748c..0000000
--- a/adb/adb_wifi.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <string>
-
-#include "adb.h"
-
-#if ADB_HOST
-
-void adb_wifi_init(void);
-void adb_wifi_pair_device(const std::string& host, const std::string& password,
-                          std::string& response);
-bool adb_wifi_is_known_host(const std::string& host);
-
-#else  // !ADB_HOST
-
-struct AdbdAuthContext;
-
-void adbd_wifi_init(AdbdAuthContext* ctx);
-void adbd_wifi_secure_connect(atransport* t);
-
-#endif
diff --git a/adb/apex/Android.bp b/adb/apex/Android.bp
deleted file mode 100644
index ddb17da..0000000
--- a/adb/apex/Android.bp
+++ /dev/null
@@ -1,55 +0,0 @@
-apex_defaults {
-    name: "com.android.adbd-defaults",
-    updatable: true,
-    min_sdk_version: "R",
-
-    binaries: ["adbd"],
-    compile_multilib: "both",
-    multilib: {
-        both: {
-            native_shared_libs: [
-                "libadb_pairing_auth",
-                "libadb_pairing_connection",
-                "libadb_pairing_server",
-                "libadbconnection_client",
-            ],
-        },
-    },
-    prebuilts: ["com.android.adbd.init.rc"],
-
-    key: "com.android.adbd.key",
-    certificate: ":com.android.adbd.certificate",
-}
-
-apex {
-    name: "com.android.adbd",
-    defaults: ["com.android.adbd-defaults"],
-    manifest: "apex_manifest.json",
-}
-
-// adbd apex with INT_MAX version code, to allow for upgrade/rollback testing.
-apex_test {
-    name: "test_com.android.adbd",
-    defaults: ["com.android.adbd-defaults"],
-    manifest: "test_apex_manifest.json",
-    file_contexts: ":com.android.adbd-file_contexts",
-    installable: false,
-}
-
-prebuilt_etc {
-    name: "com.android.adbd.init.rc",
-    src: "adbd.rc",
-    filename: "init.rc",
-    installable: false,
-}
-
-apex_key {
-    name: "com.android.adbd.key",
-    public_key: "com.android.adbd.avbpubkey",
-    private_key: "com.android.adbd.pem",
-}
-
-android_app_certificate {
-    name: "com.android.adbd.certificate",
-    certificate: "com.android.adbd",
-}
diff --git a/adb/apex/adbd.rc b/adb/apex/adbd.rc
deleted file mode 100644
index 9cb072b..0000000
--- a/adb/apex/adbd.rc
+++ /dev/null
@@ -1,6 +0,0 @@
-service adbd /apex/com.android.adbd/bin/adbd --root_seclabel=u:r:su:s0
-    class core
-    socket adbd seqpacket 660 system system
-    disabled
-    override
-    seclabel u:r:adbd:s0
diff --git a/adb/apex/apex_manifest.json b/adb/apex/apex_manifest.json
deleted file mode 100644
index 0444409..0000000
--- a/adb/apex/apex_manifest.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
-  "name": "com.android.adbd",
-  "version": 300000000
-}
diff --git a/adb/apex/com.android.adbd.avbpubkey b/adb/apex/com.android.adbd.avbpubkey
deleted file mode 100644
index 06235bd..0000000
--- a/adb/apex/com.android.adbd.avbpubkey
+++ /dev/null
Binary files differ
diff --git a/adb/apex/com.android.adbd.pem b/adb/apex/com.android.adbd.pem
deleted file mode 100644
index 2c9a860..0000000
--- a/adb/apex/com.android.adbd.pem
+++ /dev/null
@@ -1,51 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIIJKQIBAAKCAgEAwUmO4l/ZdLhmBcBtpwDjih6z6bC7iZDPAVgnFVnYuYDRlVDA
-9OCDwv02Wwc/YCNzON7vt7JBk3o9wyJZpqY9HR1PUjk2DJa/wHtxbskmLcqsvcoh
-wZxmMkgx1mFyni/vQ0tCjjxYmDcnpoVmSntoPG4LBTZRwbgE2roYSuEi7q88Z9+t
-cFiQ5x7MqVTzUFsi1E+rpsxRaTt6Ly9DO71yR1gMTqONsSgmFm8f2HhUCiQzRh7H
-qLwk8eN5ZLPLVc1JBqo8swuH5pR9whR8HaYyQtK1VANRR9oVj3JpRXmyFUk8QjEn
-91I3sFV1lErdP1uh6xi6ewMBp+mQ+ccNFiNJs8PHVprzbEgX2ah45Tnge95ZwnkR
-V/5G/EwGBsggk/BcZjQyj0PExG6LmygR7lq8q4m9ODJj3cmNLZsZu8ukMBxf4Fim
-4/Y7lyaelW0FL+x3CR27wlIxLyIf/JfUNv/cFO/O2MHrDHYdHtCbvg8vpq1MZtDN
-+gJIkYQNUfBEtGS4SkH3WWfNet3bcL5yFx5IVdwCY+n635jPA1fvr1vcIiKnyGUm
-zNE+jMOZkgk6lPPuDwllAX0D8nYTm1eBMCTAWCePO0QlcFHCT9j1/xKbFbjt/xYI
-0pXuOc8/1n61F5ybzH/91cS66gqmYUAekUiP0osTIZ7idVFJMoqpc9m7+rECAwEA
-AQKCAgEAkjg9WU89SCk/NNavnQj1GUXEwOKr3JOppdC0MFi5tQuYgSaH8jfuNZIs
-joxbCzWGMt2j5wl4xkJRes7/lyxnSyEjIoaZNsjL4qb/1tlggn+yUhkZlEfmn98x
-pIYvmS+WBwhmHwfT1cLTwgtkqK/W2PA+cgD3tF6rfXQOcIcEUCBMyB/UKws1A0Kv
-fOIA9ycaoBZtOk+SvtL5ybwtVoIoc4ROOydLR1uiBJKoOrA8kzdzenZKgIFkSYDW
-ErJY/l3AAsTCCoiMlIh84ldw1VUm7JpOBnJECOEYMl5Q+PfpGmU+qqxZGaYe7syX
-mElSOl3tjdY1LF3H4Oi2fd5xLfAgDgQjXcawKRYpImEgbqNfEUHW4BE/uVp0hHn+
-W0tCq9hvWoizhjxVq7oEfpdCXJBH0bTg9h3Ho2nuJMHTrUVbSWPTqNJn1xOi4Oxl
-vWsD5qjOOVw1e0P1dtxQ+6a8+rCL8LDvIthQC9Wpt0yXduEi/vUWiMFx2VbcSpNn
-5PB9HK7vvCpR/k0IocaTKt80D3m2svJCnfrekRx/7n//x8imrvtvaYNpoToTSN0q
-hPOpTNc77R4aARJNXm4sVHzGs6HUXsJfODJdjFtTuaDHjLvRoXZi2wFUVWBvIaFg
-/4+PHXjsfMkY15KULKn3f7Xs7K6rmINAb853zti3Qkllv1EeYoECggEBAP9t1Jxe
-hLKnVrJ5jJ0zCT0/ez6qM5cQG8YvXbVICmoAOQ+/NV6qjPABg5j8FuNhpyr45OuJ
-m1oISLgZPVCbIvYx3oZS4ekWUp9Z7jlDGzsWiBCkEUFLRzDLQRUl4bQMI2SWM+vD
-RL9AAM+NHJQ8LJN7ASNdSQw9ZinNCSByCZ52QjPCfRON0OPY4l1FJKHHymzBNXpe
-R5e9a1o9KEIhd7j+3YX9y8SOVrbUe6U8me5LZ6RY+pLB+cA/UHcSQK23hYAkMcvL
-MQny6B57P6rquzFZDG/OUOZWzWub2FSYTTmiYSHPAuB15FyWShs7h7+wK8y2xrSM
-Lq3FWHxzR1OK2HkCggEBAMG4KsAU/lp9rQhNpdw2NQXqbDLgHy09BFMOOWhyp2/Z
-2lbDo9aP746Q56HAfRRgx5oAAtr3SxeN/R/uEJLYzzDU+SrG4TQO/TZ3DPZOAVYM
-oESWG/HXLN4Hw6j4iWt2NvqpnSVJrvYr6zar/QxRHOMwnUoUV3ugmzUkqFC/Nwmm
-nMGJbTQbEha8OyatfwejmhrCkbQMBiCk0AQmgLybUxs2ckGs5jibau7VqXVxly0f
-WkAsWE/qfybQl4oyBhGCFNObr3Co/PHTaD4ACFQQvaEEF4bTuh6wP+MIgJKxL8IB
-SkrKWO5PFbJWY5lacnNMe7ITrWy60HukLlJe5or5lfkCggEBAP3Rwghw1CRDrR9F
-Mbm0UWYPgwTOVN20ICVcRB40LEURW6KOOxaLG+oTVxXay1PAYkGNes2jvEBHIxvt
-2MQUpTVIcPvBuMPKbufykYtNZ+3bgfInVw4vI9sU3uOI9TPZLAJ0T7vkGpiBnUyh
-yNh0w0b6YDMoK8KB8Ndw67TWHUDd+wM8LNYVgpInnylX4ALzae+QPvgOX84laFwP
-kcXFRBcNDExt2uLDHuAnXYbhJYVqYN8rnDPhlbC4OdlYxfTZ/UtMrD769wwP2SER
-ED9jagirmHQx7Ko3b4GTJ/FINtUiyqqx7wXloLtwjMtq6IZPJfcTWXloI6qCBGAG
-ncYinuECggEAfZeiF8BEm3RpTz3QL3HxdHFkTqOhctnhSNuq+n2C8nBCLwhN21ic
-DkkB84txTFnmboBdWYsEYzQKDL5yflIUGeup00L3VKH3Jm2OuM0f7qLm8TCE04kW
-rKhKAO2JYmNVB7QZjsgzp6QXre1ZdLfNy7mD8Dg584vPtGecvCUMULR1YsBvTV3T
-n2vPyaan+dLmoTzN6/XzrwxLVLWFt0HYYoctEkk/RSn17PwXDm5jfbya7YoSg1Vb
-tFV+Oflul8FHMV35I0hcHYhbR/8LZz0nRBH8EsyIGUdZVB76BKDdfqEJgm2ntHEP
-dvytPAo4s2m9tFkvkZOYgOCTq5GdVDK2OQKCAQAsz+y9rDcqFciCESu4IHzmtckT
-0kwP2W5ds5hzUjbY0Y2AKTx2oHNOFak6WW5vxN0+OIn37SNK3RBStPWJiigut4R4
-rGrZM4pijm53s3cWzd0h8XyLGisl2zORu8gD2IQLkQf79F3lEZHGA+J0mkSHB85N
-IuqReFzL6cfOToNd+8WYjMgJcXmVuKiCV1FRK3jrqNpXO2cLtnhFvQMxRUAYU4j+
-2MIdBFVeMq5ftMMOBS21hM9cNLlOzoSN2HmK+ZkmrlTCK0G9lmF427/lqXTmWLed
-sspOUbOLfBOwxdCCc9JUxz5KggKWcDcTqX25M0mv09rpuCxIEg8lez1Ax0if
------END RSA PRIVATE KEY-----
diff --git a/adb/apex/com.android.adbd.pk8 b/adb/apex/com.android.adbd.pk8
deleted file mode 100644
index cdddc3f..0000000
--- a/adb/apex/com.android.adbd.pk8
+++ /dev/null
Binary files differ
diff --git a/adb/apex/com.android.adbd.x509.pem b/adb/apex/com.android.adbd.x509.pem
deleted file mode 100644
index bb85c1d..0000000
--- a/adb/apex/com.android.adbd.x509.pem
+++ /dev/null
@@ -1,35 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIGHzCCBAegAwIBAgIUW8npFHXBP+wsEAesGMBxaV7TScAwDQYJKoZIhvcNAQEL
-BQAwgZ0xCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQH
-DA1Nb3VudGFpbiBWaWV3MRAwDgYDVQQKDAdBbmRyb2lkMRAwDgYDVQQLDAdBbmRy
-b2lkMRkwFwYDVQQDDBBjb20uYW5kcm9pZC5hZGJkMSIwIAYJKoZIhvcNAQkBFhNh
-bmRyb2lkQGFuZHJvaWQuY29tMCAXDTE5MDgxNTE5MzkxM1oYDzQ3NTcwNzExMTkz
-OTEzWjCBnTELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNV
-BAcMDU1vdW50YWluIFZpZXcxEDAOBgNVBAoMB0FuZHJvaWQxEDAOBgNVBAsMB0Fu
-ZHJvaWQxGTAXBgNVBAMMEGNvbS5hbmRyb2lkLmFkYmQxIjAgBgkqhkiG9w0BCQEW
-E2FuZHJvaWRAYW5kcm9pZC5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK
-AoICAQC6zbUeWi5vNA6vCC4FBrJQ9re4UexP6TabsDYvWpFBoCluvMkT2ZRmpXMF
-W7EzQ5VmuUvZgLYVHuJmnvHIV3uaRc2VE1SV+spjWTRt+6DtsAN7irR5K66POWMp
-+tr5hASdQBVOJdebimsepy0pH6sXREvanrrFzkSM/2Ho0unlwWJ5Y4jcnvdkVHI5
-Ks0vifLmX4y5mYgv1dcXYWzyYx39f8HyePv0cjRhYXiIEYZ49KWU4MjryvQe/mAu
-MQuMp901BLps2W1+oKyPPA4DV69KUXgF66RFfsjjkJJ/CSeQGzTuez+UWzFk3Duc
-6MmbiL1LTki3vyyVtjW1rYFO2s+M6Pa5NZWHgA55uUxiJ987WPyK9lWnMsY6YeKa
-FDBfS1JUzXGPzVncgM7LLvzAEibLdhjII88NsJvzPoHK0SluSn+E7t7iGO1fTjkD
-Js94iUJAp8OQ4GwkcTVgtEAR+NXzownNjHJ6qpiq6tXRqXdBqSat/glf01AgNDtz
-9AGeW7Mz6FqTdOzg3U4lu77+CGd3SZTuQk8C8PUDNhqhQX5H2qhr90bakGaXuYfE
-rWFzIjrVdJIznV1BimOCay5HyyHab4FWlVhAvslEQb2BpHRyi2lhe0laupOpmN44
-LzfjFM18bi2GashIi2OQuYDyAeT5mGtR2g8mC7g44H6dH+wTfQIDAQABo1MwUTAd
-BgNVHQ4EFgQU7lyyxPO5SOOh9a5O0l4+RjckcgcwHwYDVR0jBBgwFoAU7lyyxPO5
-SOOh9a5O0l4+RjckcgcwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOC
-AgEAStsOy8bkbZg/Ygx47bPkLSz0cJIvATxTChUGOabkz+brLis88ABVWVP0IXps
-tlLlZR5cjXBJguE7GJXzKPWzQZuB8+YwcGHG6QDFpfdMeGrxPDhwNfGy236ArVnx
-K0v1IIxoZRZ0P7aubk3xwUAPgsmT5ayZCKu+dqlEy5B6ioKEsr7Y2RRT/8ifERNm
-cjS9AhcyWrp4R3cjy2iA/RpdsPFwE5ac3I+GtUB4D2up5aDMsy85i9t2/1kuTUaA
-9UHwGXCpcqP8f8BqeLzuxDzYkAvkntlNxbXn1cbn+dTRIOCBoDbtSeqtxhWooOUH
-RQROeRsB7iicdYJJRge0+WyR+216AKUSQPE6/rT0Ifr06ZRwi22/YyySpwuO3SNA
-+yWffh+f4h31Dz+p6pu8wjbMDkq4LnCWyjLwfF/yhvWhwwm5+KPAEhvJABeHQc+3
-cslOC9dlXJm9sPoUC7ghmUiFsCmN2hIzQrr2QoK0Obh0AGexOvOAw9cqtOdZQncB
-bqC8c4sVYScVxwDWkg0lNfRMC5boPjBsl7+M2CC1ukgVpXTyDOEjMWILrBXfYCDX
-unBH3kbKQOfL5RT0nE1Lkt1rn5qAWMJg4mvS4QuIurbRtEoj3QYQadF9md4qJXs0
-TvqvY8iEC4xrWU2SQn1K3PutXgaLP9/b6Cy1SBrhBX+AC5s=
------END CERTIFICATE-----
diff --git a/adb/apex/test_apex_manifest.json b/adb/apex/test_apex_manifest.json
deleted file mode 100644
index 7131977..0000000
--- a/adb/apex/test_apex_manifest.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
-  "name": "com.android.adbd",
-  "version": 2147483647
-}
diff --git a/adb/benchmark_device.py b/adb/benchmark_device.py
deleted file mode 100755
index 4d0cf49..0000000
--- a/adb/benchmark_device.py
+++ /dev/null
@@ -1,156 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import os
-import statistics
-import subprocess
-import tempfile
-import time
-
-import adb
-
-def lock_min(device):
-    device.shell_nocheck(["""
-        for x in /sys/devices/system/cpu/cpu?/cpufreq; do
-            echo userspace > $x/scaling_governor
-            cat $x/scaling_min_freq > $x/scaling_setspeed
-        done
-    """])
-
-def lock_max(device):
-    device.shell_nocheck(["""
-        for x in /sys/devices/system/cpu/cpu?/cpufreq; do
-            echo userspace > $x/scaling_governor
-            cat $x/scaling_max_freq > $x/scaling_setspeed
-        done
-    """])
-
-def unlock(device):
-    device.shell_nocheck(["""
-        for x in /sys/devices/system/cpu/cpu?/cpufreq; do
-            echo ondemand > $x/scaling_governor
-            echo sched > $x/scaling_governor
-            echo schedutil > $x/scaling_governor
-        done
-    """])
-
-def harmonic_mean(xs):
-    return 1.0 / statistics.mean([1.0 / x for x in xs])
-
-def analyze(name, speeds):
-    median = statistics.median(speeds)
-    mean = harmonic_mean(speeds)
-    stddev = statistics.stdev(speeds)
-    msg = "%s: %d runs: median %.2f MiB/s, mean %.2f MiB/s, stddev: %.2f MiB/s"
-    print(msg % (name, len(speeds), median, mean, stddev))
-
-def benchmark_sink(device=None, size_mb=100):
-    if device == None:
-        device = adb.get_device()
-
-    speeds = list()
-    cmd = device.adb_cmd + ["raw", "sink:%d" % (size_mb * 1024 * 1024)]
-
-    with tempfile.TemporaryFile() as tmpfile:
-        tmpfile.truncate(size_mb * 1024 * 1024)
-
-        for _ in range(0, 10):
-            tmpfile.seek(0)
-            begin = time.time()
-            subprocess.check_call(cmd, stdin=tmpfile)
-            end = time.time()
-            speeds.append(size_mb / float(end - begin))
-
-    analyze("sink %dMiB" % size_mb, speeds)
-
-def benchmark_source(device=None, size_mb=100):
-    if device == None:
-        device = adb.get_device()
-
-    speeds = list()
-    cmd = device.adb_cmd + ["raw", "source:%d" % (size_mb * 1024 * 1024)]
-
-    with open(os.devnull, 'w') as devnull:
-        for _ in range(0, 10):
-            begin = time.time()
-            subprocess.check_call(cmd, stdout=devnull)
-            end = time.time()
-            speeds.append(size_mb / float(end - begin))
-
-    analyze("source %dMiB" % size_mb, speeds)
-
-def benchmark_push(device=None, file_size_mb=100):
-    if device == None:
-        device = adb.get_device()
-
-    remote_path = "/dev/null"
-    local_path = "/tmp/adb_benchmark_temp"
-
-    with open(local_path, "wb") as f:
-        f.truncate(file_size_mb * 1024 * 1024)
-
-    speeds = list()
-    for _ in range(0, 10):
-        begin = time.time()
-        device.push(local=local_path, remote=remote_path)
-        end = time.time()
-        speeds.append(file_size_mb / float(end - begin))
-
-    analyze("push %dMiB" % file_size_mb, speeds)
-
-def benchmark_pull(device=None, file_size_mb=100):
-    if device == None:
-        device = adb.get_device()
-
-    remote_path = "/data/local/tmp/adb_benchmark_temp"
-    local_path = "/tmp/adb_benchmark_temp"
-
-    device.shell(["dd", "if=/dev/zero", "of=" + remote_path, "bs=1m",
-                  "count=" + str(file_size_mb)])
-    speeds = list()
-    for _ in range(0, 10):
-        begin = time.time()
-        device.pull(remote=remote_path, local=local_path)
-        end = time.time()
-        speeds.append(file_size_mb / float(end - begin))
-
-    analyze("pull %dMiB" % file_size_mb, speeds)
-
-def benchmark_shell(device=None, file_size_mb=100):
-    if device == None:
-        device = adb.get_device()
-
-    speeds = list()
-    for _ in range(0, 10):
-        begin = time.time()
-        device.shell(["dd", "if=/dev/zero", "bs=1m",
-                      "count=" + str(file_size_mb)])
-        end = time.time()
-        speeds.append(file_size_mb / float(end - begin))
-
-    analyze("shell %dMiB" % file_size_mb, speeds)
-
-def main():
-    device = adb.get_device()
-    unlock(device)
-    benchmark_sink(device)
-    benchmark_source(device)
-    benchmark_push(device)
-    benchmark_pull(device)
-
-if __name__ == "__main__":
-    main()
diff --git a/adb/brotli_utils.h b/adb/brotli_utils.h
deleted file mode 100644
index c5be73d..0000000
--- a/adb/brotli_utils.h
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <span>
-
-#include <brotli/decode.h>
-#include <brotli/encode.h>
-
-#include "types.h"
-
-enum class BrotliDecodeResult {
-    Error,
-    Done,
-    NeedInput,
-    MoreOutput,
-};
-
-struct BrotliDecoder {
-    explicit BrotliDecoder(std::span<char> output_buffer)
-        : output_buffer_(output_buffer),
-          decoder_(BrotliDecoderCreateInstance(nullptr, nullptr, nullptr),
-                   BrotliDecoderDestroyInstance) {}
-
-    void Append(Block&& block) { input_buffer_.append(std::move(block)); }
-
-    BrotliDecodeResult Decode(std::span<char>* output) {
-        size_t available_in = input_buffer_.front_size();
-        const uint8_t* next_in = reinterpret_cast<const uint8_t*>(input_buffer_.front_data());
-
-        size_t available_out = output_buffer_.size();
-        uint8_t* next_out = reinterpret_cast<uint8_t*>(output_buffer_.data());
-
-        BrotliDecoderResult r = BrotliDecoderDecompressStream(
-                decoder_.get(), &available_in, &next_in, &available_out, &next_out, nullptr);
-
-        size_t bytes_consumed = input_buffer_.front_size() - available_in;
-        input_buffer_.drop_front(bytes_consumed);
-
-        size_t bytes_emitted = output_buffer_.size() - available_out;
-        *output = std::span<char>(output_buffer_.data(), bytes_emitted);
-
-        switch (r) {
-            case BROTLI_DECODER_RESULT_SUCCESS:
-                return BrotliDecodeResult::Done;
-            case BROTLI_DECODER_RESULT_ERROR:
-                return BrotliDecodeResult::Error;
-            case BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT:
-                // Brotli guarantees as one of its invariants that if it returns NEEDS_MORE_INPUT,
-                // it will consume the entire input buffer passed in, so we don't have to worry
-                // about bytes left over in the front block with more input remaining.
-                return BrotliDecodeResult::NeedInput;
-            case BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT:
-                return BrotliDecodeResult::MoreOutput;
-        }
-    }
-
-  private:
-    IOVector input_buffer_;
-    std::span<char> output_buffer_;
-    std::unique_ptr<BrotliDecoderState, void (*)(BrotliDecoderState*)> decoder_;
-};
-
-enum class BrotliEncodeResult {
-    Error,
-    Done,
-    NeedInput,
-    MoreOutput,
-};
-
-template <size_t OutputBlockSize>
-struct BrotliEncoder {
-    explicit BrotliEncoder()
-        : output_block_(OutputBlockSize),
-          output_bytes_left_(OutputBlockSize),
-          encoder_(BrotliEncoderCreateInstance(nullptr, nullptr, nullptr),
-                   BrotliEncoderDestroyInstance) {
-        BrotliEncoderSetParameter(encoder_.get(), BROTLI_PARAM_QUALITY, 1);
-    }
-
-    void Append(Block input) { input_buffer_.append(std::move(input)); }
-    void Finish() { finished_ = true; }
-
-    BrotliEncodeResult Encode(Block* output) {
-        output->clear();
-        while (true) {
-            size_t available_in = input_buffer_.front_size();
-            const uint8_t* next_in = reinterpret_cast<const uint8_t*>(input_buffer_.front_data());
-
-            size_t available_out = output_bytes_left_;
-            uint8_t* next_out = reinterpret_cast<uint8_t*>(output_block_.data() +
-                                                           (OutputBlockSize - output_bytes_left_));
-
-            BrotliEncoderOperation op = BROTLI_OPERATION_PROCESS;
-            if (finished_) {
-                op = BROTLI_OPERATION_FINISH;
-            }
-
-            if (!BrotliEncoderCompressStream(encoder_.get(), op, &available_in, &next_in,
-                                             &available_out, &next_out, nullptr)) {
-                return BrotliEncodeResult::Error;
-            }
-
-            size_t bytes_consumed = input_buffer_.front_size() - available_in;
-            input_buffer_.drop_front(bytes_consumed);
-
-            output_bytes_left_ = available_out;
-
-            if (BrotliEncoderIsFinished(encoder_.get())) {
-                output_block_.resize(OutputBlockSize - output_bytes_left_);
-                *output = std::move(output_block_);
-                return BrotliEncodeResult::Done;
-            } else if (output_bytes_left_ == 0) {
-                *output = std::move(output_block_);
-                output_block_.resize(OutputBlockSize);
-                output_bytes_left_ = OutputBlockSize;
-                return BrotliEncodeResult::MoreOutput;
-            } else if (input_buffer_.empty()) {
-                return BrotliEncodeResult::NeedInput;
-            }
-        }
-    }
-
-  private:
-    bool finished_ = false;
-    IOVector input_buffer_;
-    Block output_block_;
-    size_t output_bytes_left_;
-    std::unique_ptr<BrotliEncoderState, void (*)(BrotliEncoderState*)> encoder_;
-};
diff --git a/adb/bugreport_test.cpp b/adb/bugreport_test.cpp
deleted file mode 100644
index a6be203..0000000
--- a/adb/bugreport_test.cpp
+++ /dev/null
@@ -1,466 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "bugreport.h"
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-
-#include <android-base/strings.h>
-#include <android-base/test_utils.h>
-
-#include "sysdeps.h"
-#include "adb_utils.h"
-
-using ::testing::_;
-using ::testing::Action;
-using ::testing::ActionInterface;
-using ::testing::DoAll;
-using ::testing::ElementsAre;
-using ::testing::HasSubstr;
-using ::testing::MakeAction;
-using ::testing::Return;
-using ::testing::StrEq;
-using ::testing::WithArg;
-using ::testing::internal::CaptureStderr;
-using ::testing::internal::CaptureStdout;
-using ::testing::internal::GetCapturedStderr;
-using ::testing::internal::GetCapturedStdout;
-
-// Empty function so tests don't need to be linked against file_sync_service.cpp, which requires
-// SELinux and its transitive dependencies...
-bool do_sync_pull(const std::vector<const char*>& srcs, const char* dst, bool copy_attrs,
-                  const char* name) {
-    ADD_FAILURE() << "do_sync_pull() should have been mocked";
-    return false;
-}
-
-// Empty functions so tests don't need to be linked against commandline.cpp
-DefaultStandardStreamsCallback DEFAULT_STANDARD_STREAMS_CALLBACK(nullptr, nullptr);
-
-int send_shell_command(const std::string& command, bool disable_shell_protocol,
-                       StandardStreamsCallbackInterface* callback) {
-    ADD_FAILURE() << "send_shell_command() should have been mocked";
-    return -42;
-}
-
-enum StreamType {
-    kStreamStdout,
-    kStreamStderr,
-};
-
-// gmock black magic to provide a WithArg<2>(WriteOnStdout(output)) matcher
-typedef void OnStandardStreamsCallbackFunction(StandardStreamsCallbackInterface*);
-
-class OnStandardStreamsCallbackAction : public ActionInterface<OnStandardStreamsCallbackFunction> {
-  public:
-    explicit OnStandardStreamsCallbackAction(StreamType type, const std::string& output)
-        : type_(type), output_(output) {
-    }
-    virtual Result Perform(const ArgumentTuple& args) {
-        if (type_ == kStreamStdout) {
-            ::std::tr1::get<0>(args)->OnStdout(output_.c_str(), output_.size());
-        }
-        if (type_ == kStreamStderr) {
-            ::std::tr1::get<0>(args)->OnStderr(output_.c_str(), output_.size());
-        }
-    }
-
-  private:
-    StreamType type_;
-    std::string output_;
-};
-
-// Matcher used to emulated StandardStreamsCallbackInterface.OnStdout(buffer,
-// length)
-Action<OnStandardStreamsCallbackFunction> WriteOnStdout(const std::string& output) {
-    return MakeAction(new OnStandardStreamsCallbackAction(kStreamStdout, output));
-}
-
-// Matcher used to emulated StandardStreamsCallbackInterface.OnStderr(buffer,
-// length)
-Action<OnStandardStreamsCallbackFunction> WriteOnStderr(const std::string& output) {
-    return MakeAction(new OnStandardStreamsCallbackAction(kStreamStderr, output));
-}
-
-typedef int CallbackDoneFunction(StandardStreamsCallbackInterface*);
-
-class CallbackDoneAction : public ActionInterface<CallbackDoneFunction> {
-  public:
-    explicit CallbackDoneAction(int status) : status_(status) {
-    }
-    virtual Result Perform(const ArgumentTuple& args) {
-        int status = ::std::tr1::get<0>(args)->Done(status_);
-        return status;
-    }
-
-  private:
-    int status_;
-};
-
-// Matcher used to emulated StandardStreamsCallbackInterface.Done(status)
-Action<CallbackDoneFunction> ReturnCallbackDone(int status = -1337) {
-    return MakeAction(new CallbackDoneAction(status));
-}
-
-class BugreportMock : public Bugreport {
-  public:
-    MOCK_METHOD3(SendShellCommand, int(const std::string& command, bool disable_shell_protocol,
-                                       StandardStreamsCallbackInterface* callback));
-    MOCK_METHOD4(DoSyncPull, bool(const std::vector<const char*>& srcs, const char* dst,
-                                  bool copy_attrs, const char* name));
-    MOCK_METHOD2(UpdateProgress, void(const std::string&, int));
-};
-
-class BugreportTest : public ::testing::Test {
-  public:
-    void SetUp() {
-        if (!getcwd(&cwd_)) {
-            ADD_FAILURE() << "getcwd failed: " << strerror(errno);
-            return;
-        }
-    }
-
-    void ExpectBugreportzVersion(const std::string& version) {
-        EXPECT_CALL(br_, SendShellCommand("bugreportz -v", false, _))
-            .WillOnce(DoAll(WithArg<2>(WriteOnStderr(version)),
-                            WithArg<2>(ReturnCallbackDone(0))));
-    }
-
-    void ExpectProgress(int progress_percentage, const std::string& file = "file.zip") {
-        EXPECT_CALL(br_, UpdateProgress(StrEq("generating " + file), progress_percentage));
-    }
-
-    BugreportMock br_;
-    std::string cwd_;  // TODO: make it static
-};
-
-// Tests when called with invalid number of arguments
-TEST_F(BugreportTest, InvalidNumberArgs) {
-    const char* args[] = {"bugreport", "to", "principal"};
-    ASSERT_EQ(1, br_.DoIt(3, args));
-}
-
-// Tests the 'adb bugreport' option when the device does not support 'bugreportz' - it falls back
-// to the flat-file format ('bugreport' binary on device)
-TEST_F(BugreportTest, NoArgumentsPreNDevice) {
-    // clang-format off
-    EXPECT_CALL(br_, SendShellCommand("bugreportz -v", false, _))
-        .WillOnce(DoAll(WithArg<2>(WriteOnStderr("")),
-                        // Write some bogus output on stdout to make sure it's ignored
-                        WithArg<2>(WriteOnStdout("Dude, where is my bugreportz?")),
-                        WithArg<2>(ReturnCallbackDone(0))));
-    // clang-format on
-    std::string bugreport = "Reported the bug was.";
-    CaptureStdout();
-    EXPECT_CALL(br_, SendShellCommand("bugreport", false, _))
-        .WillOnce(DoAll(WithArg<2>(WriteOnStdout(bugreport)), Return(0)));
-
-    const char* args[] = {"bugreport"};
-    ASSERT_EQ(0, br_.DoIt(1, args));
-    ASSERT_THAT(GetCapturedStdout(), StrEq(bugreport));
-}
-
-// Tests the 'adb bugreport' option when the device supports 'bugreportz' version 1.0 - it will
-// save the bugreport in the current directory with the name provided by the device.
-TEST_F(BugreportTest, NoArgumentsNDevice) {
-    ExpectBugreportzVersion("1.0");
-
-    std::string dest_file =
-        android::base::StringPrintf("%s%cda_bugreport.zip", cwd_.c_str(), OS_PATH_SEPARATOR);
-    EXPECT_CALL(br_, SendShellCommand("bugreportz", false, _))
-        .WillOnce(DoAll(WithArg<2>(WriteOnStdout("OK:/device/da_bugreport.zip")),
-                        WithArg<2>(ReturnCallbackDone())));
-    EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/da_bugreport.zip")), StrEq(dest_file),
-                                false, StrEq("pulling da_bugreport.zip")))
-        .WillOnce(Return(true));
-
-    const char* args[] = {"bugreport"};
-    ASSERT_EQ(0, br_.DoIt(1, args));
-}
-
-// Tests the 'adb bugreport' option when the device supports 'bugreportz' version 1.1 - it will
-// save the bugreport in the current directory with the name provided by the device.
-TEST_F(BugreportTest, NoArgumentsPostNDevice) {
-    ExpectBugreportzVersion("1.1");
-    std::string dest_file =
-        android::base::StringPrintf("%s%cda_bugreport.zip", cwd_.c_str(), OS_PATH_SEPARATOR);
-    ExpectProgress(50, "da_bugreport.zip");
-    EXPECT_CALL(br_, SendShellCommand("bugreportz -p", false, _))
-        .WillOnce(DoAll(WithArg<2>(WriteOnStdout("BEGIN:/device/da_bugreport.zip\n")),
-                        WithArg<2>(WriteOnStdout("PROGRESS:50/100\n")),
-                        WithArg<2>(WriteOnStdout("OK:/device/da_bugreport.zip\n")),
-                        WithArg<2>(ReturnCallbackDone())));
-    EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/da_bugreport.zip")), StrEq(dest_file),
-                                false, StrEq("pulling da_bugreport.zip")))
-        .WillOnce(Return(true));
-
-    const char* args[] = {"bugreport"};
-    ASSERT_EQ(0, br_.DoIt(1, args));
-}
-
-// Tests 'adb bugreport file.zip' when it succeeds and device does not support progress.
-TEST_F(BugreportTest, OkNDevice) {
-    ExpectBugreportzVersion("1.0");
-    EXPECT_CALL(br_, SendShellCommand("bugreportz", false, _))
-        .WillOnce(DoAll(WithArg<2>(WriteOnStdout("OK:/device/bugreport.zip")),
-                        WithArg<2>(ReturnCallbackDone())));
-    EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
-                                false, StrEq("pulling file.zip")))
-        .WillOnce(Return(true));
-
-    const char* args[] = {"bugreport", "file.zip"};
-    ASSERT_EQ(0, br_.DoIt(2, args));
-}
-
-// Tests 'adb bugreport file.zip' when it succeeds but response was sent in
-// multiple buffer writers and without progress updates.
-TEST_F(BugreportTest, OkNDeviceSplitBuffer) {
-    ExpectBugreportzVersion("1.0");
-    EXPECT_CALL(br_, SendShellCommand("bugreportz", false, _))
-        .WillOnce(DoAll(WithArg<2>(WriteOnStdout("OK:/device")),
-                        WithArg<2>(WriteOnStdout("/bugreport.zip")),
-                        WithArg<2>(ReturnCallbackDone())));
-    EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
-                                false, StrEq("pulling file.zip")))
-        .WillOnce(Return(true));
-
-    const char* args[] = {"bugreport", "file.zip"};
-    ASSERT_EQ(0, br_.DoIt(2, args));
-}
-
-// Tests 'adb bugreport file.zip' when it succeeds and displays progress.
-TEST_F(BugreportTest, OkProgress) {
-    ExpectBugreportzVersion("1.1");
-    ExpectProgress(1);
-    ExpectProgress(10);
-    ExpectProgress(50);
-    ExpectProgress(99);
-    // clang-format off
-    EXPECT_CALL(br_, SendShellCommand("bugreportz -p", false, _))
-        // NOTE: DoAll accepts at most 10 arguments, and we're almost reached that limit...
-        .WillOnce(DoAll(
-            // Name might change on OK, so make sure the right one is picked.
-            WithArg<2>(WriteOnStdout("BEGIN:/device/bugreport___NOT.zip\n")),
-            // Progress line in one write
-            WithArg<2>(WriteOnStdout("PROGRESS:1/100\n")),
-            // Add some bogus lines
-            WithArg<2>(WriteOnStdout("\nDUDE:SWEET\n\nBLA\n\nBLA\nBLA\n\n")),
-            // Multiple progress lines in one write
-            WithArg<2>(WriteOnStdout("PROGRESS:10/100\nPROGRESS:50/100\n")),
-            // Progress line in multiple writes
-            WithArg<2>(WriteOnStdout("PROG")),
-            WithArg<2>(WriteOnStdout("RESS:99")),
-            WithArg<2>(WriteOnStdout("/100\n")),
-            // Split last message as well, just in case
-            WithArg<2>(WriteOnStdout("OK:/device/bugreport")),
-            WithArg<2>(WriteOnStdout(".zip")),
-            WithArg<2>(ReturnCallbackDone())));
-    // clang-format on
-    EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
-                                false, StrEq("pulling file.zip")))
-        .WillOnce(Return(true));
-
-    const char* args[] = {"bugreport", "file.zip"};
-    ASSERT_EQ(0, br_.DoIt(2, args));
-}
-
-// Tests 'adb bugreport file.zip' when it succeeds and displays progress, even if progress recedes.
-TEST_F(BugreportTest, OkProgressAlwaysForward) {
-    ExpectBugreportzVersion("1.1");
-    ExpectProgress(1);
-    ExpectProgress(50);
-    ExpectProgress(75);
-    // clang-format off
-    EXPECT_CALL(br_, SendShellCommand("bugreportz -p", false, _))
-        // NOTE: DoAll accepts at most 10 arguments, and we're almost reached that limit...
-        .WillOnce(DoAll(
-            WithArg<2>(WriteOnStdout("BEGIN:/device/bugreport.zip\n")),
-            WithArg<2>(WriteOnStdout("PROGRESS:1/100\n")), // 1%
-            WithArg<2>(WriteOnStdout("PROGRESS:50/100\n")), // 50%
-            // 25% should be ignored becaused it receded.
-            WithArg<2>(WriteOnStdout("PROGRESS:25/100\n")), // 25%
-            WithArg<2>(WriteOnStdout("PROGRESS:75/100\n")), // 75%
-            // 75% should be ignored becaused it didn't change.
-            WithArg<2>(WriteOnStdout("PROGRESS:75/100\n")), // 75%
-            // Try a receeding percentage with a different max progress
-            WithArg<2>(WriteOnStdout("PROGRESS:700/1000\n")), // 70%
-            WithArg<2>(WriteOnStdout("OK:/device/bugreport.zip")),
-            WithArg<2>(ReturnCallbackDone())));
-    // clang-format on
-    EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
-                                false, StrEq("pulling file.zip")))
-        .WillOnce(Return(true));
-
-    const char* args[] = {"bugreport", "file.zip"};
-    ASSERT_EQ(0, br_.DoIt(2, args));
-}
-
-// Tests 'adb bugreport file.zip' when it succeeds and displays the initial progress of 0%
-TEST_F(BugreportTest, OkProgressZeroPercentIsNotIgnored) {
-    ExpectBugreportzVersion("1.1");
-    ExpectProgress(0);
-    ExpectProgress(1);
-    // clang-format off
-    EXPECT_CALL(br_, SendShellCommand("bugreportz -p", false, _))
-        // NOTE: DoAll accepts at most 10 arguments, and we're almost reached that limit...
-        .WillOnce(DoAll(
-            WithArg<2>(WriteOnStdout("BEGIN:/device/bugreport.zip\n")),
-            WithArg<2>(WriteOnStdout("PROGRESS:1/100000\n")),
-            WithArg<2>(WriteOnStdout("PROGRESS:1/100\n")), // 1%
-            WithArg<2>(WriteOnStdout("OK:/device/bugreport.zip")),
-            WithArg<2>(ReturnCallbackDone())));
-    // clang-format on
-    EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
-                                false, StrEq("pulling file.zip")))
-        .WillOnce(Return(true));
-
-    const char* args[] = {"bugreport", "file.zip"};
-    ASSERT_EQ(0, br_.DoIt(2, args));
-}
-
-// Tests 'adb bugreport dir' when it succeeds and destination is a directory.
-TEST_F(BugreportTest, OkDirectory) {
-    ExpectBugreportzVersion("1.1");
-    TemporaryDir td;
-    std::string dest_file =
-        android::base::StringPrintf("%s%cda_bugreport.zip", td.path, OS_PATH_SEPARATOR);
-
-    EXPECT_CALL(br_, SendShellCommand("bugreportz -p", false, _))
-        .WillOnce(DoAll(WithArg<2>(WriteOnStdout("BEGIN:/device/da_bugreport.zip\n")),
-                        WithArg<2>(WriteOnStdout("OK:/device/da_bugreport.zip")),
-                        WithArg<2>(ReturnCallbackDone())));
-    EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/da_bugreport.zip")), StrEq(dest_file),
-                                false, StrEq("pulling da_bugreport.zip")))
-        .WillOnce(Return(true));
-
-    const char* args[] = {"bugreport", td.path};
-    ASSERT_EQ(0, br_.DoIt(2, args));
-}
-
-// Tests 'adb bugreport file' when it succeeds
-TEST_F(BugreportTest, OkNoExtension) {
-    ExpectBugreportzVersion("1.1");
-    EXPECT_CALL(br_, SendShellCommand("bugreportz -p", false, _))
-        .WillOnce(DoAll(WithArg<2>(WriteOnStdout("OK:/device/bugreport.zip\n")),
-                        WithArg<2>(ReturnCallbackDone())));
-    EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
-                                false, StrEq("pulling file.zip")))
-        .WillOnce(Return(true));
-
-    const char* args[] = {"bugreport", "file"};
-    ASSERT_EQ(0, br_.DoIt(2, args));
-}
-
-// Tests 'adb bugreport dir' when it succeeds and destination is a directory and device runs N.
-TEST_F(BugreportTest, OkNDeviceDirectory) {
-    ExpectBugreportzVersion("1.0");
-    TemporaryDir td;
-    std::string dest_file =
-        android::base::StringPrintf("%s%cda_bugreport.zip", td.path, OS_PATH_SEPARATOR);
-
-    EXPECT_CALL(br_, SendShellCommand("bugreportz", false, _))
-        .WillOnce(DoAll(WithArg<2>(WriteOnStdout("BEGIN:/device/da_bugreport.zip\n")),
-                        WithArg<2>(WriteOnStdout("OK:/device/da_bugreport.zip")),
-                        WithArg<2>(ReturnCallbackDone())));
-    EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/da_bugreport.zip")), StrEq(dest_file),
-                                false, StrEq("pulling da_bugreport.zip")))
-        .WillOnce(Return(true));
-
-    const char* args[] = {"bugreport", td.path};
-    ASSERT_EQ(0, br_.DoIt(2, args));
-}
-
-// Tests 'adb bugreport file.zip' when the bugreport itself failed
-TEST_F(BugreportTest, BugreportzReturnedFail) {
-    ExpectBugreportzVersion("1.1");
-    EXPECT_CALL(br_, SendShellCommand("bugreportz -p", false, _))
-        .WillOnce(
-            DoAll(WithArg<2>(WriteOnStdout("FAIL:D'OH!\n")), WithArg<2>(ReturnCallbackDone())));
-
-    CaptureStderr();
-    const char* args[] = {"bugreport", "file.zip"};
-    ASSERT_EQ(-1, br_.DoIt(2, args));
-    ASSERT_THAT(GetCapturedStderr(), HasSubstr("D'OH!"));
-}
-
-// Tests 'adb bugreport file.zip' when the bugreport itself failed but response
-// was sent in
-// multiple buffer writes
-TEST_F(BugreportTest, BugreportzReturnedFailSplitBuffer) {
-    ExpectBugreportzVersion("1.1");
-    EXPECT_CALL(br_, SendShellCommand("bugreportz -p", false, _))
-        .WillOnce(DoAll(WithArg<2>(WriteOnStdout("FAIL")), WithArg<2>(WriteOnStdout(":D'OH!\n")),
-                        WithArg<2>(ReturnCallbackDone())));
-
-    CaptureStderr();
-    const char* args[] = {"bugreport", "file.zip"};
-    ASSERT_EQ(-1, br_.DoIt(2, args));
-    ASSERT_THAT(GetCapturedStderr(), HasSubstr("D'OH!"));
-}
-
-// Tests 'adb bugreport file.zip' when the bugreportz returned an unsupported
-// response.
-TEST_F(BugreportTest, BugreportzReturnedUnsupported) {
-    ExpectBugreportzVersion("1.1");
-    EXPECT_CALL(br_, SendShellCommand("bugreportz -p", false, _))
-        .WillOnce(DoAll(WithArg<2>(WriteOnStdout("bugreportz? What am I, a zombie?")),
-                        WithArg<2>(ReturnCallbackDone())));
-
-    CaptureStderr();
-    const char* args[] = {"bugreport", "file.zip"};
-    ASSERT_EQ(-1, br_.DoIt(2, args));
-    ASSERT_THAT(GetCapturedStderr(), HasSubstr("bugreportz? What am I, a zombie?"));
-}
-
-// Tests 'adb bugreport file.zip' when the bugreportz -v command failed
-TEST_F(BugreportTest, BugreportzVersionFailed) {
-    EXPECT_CALL(br_, SendShellCommand("bugreportz -v", false, _)).WillOnce(Return(666));
-
-    const char* args[] = {"bugreport", "file.zip"};
-    ASSERT_EQ(666, br_.DoIt(2, args));
-}
-
-// Tests 'adb bugreport file.zip' when the bugreportz -v returns status 0 but with no output.
-TEST_F(BugreportTest, BugreportzVersionEmpty) {
-    ExpectBugreportzVersion("");
-
-    const char* args[] = {"bugreport", "file.zip"};
-    ASSERT_EQ(-1, br_.DoIt(2, args));
-}
-
-// Tests 'adb bugreport file.zip' when the main bugreportz command failed
-TEST_F(BugreportTest, BugreportzFailed) {
-    ExpectBugreportzVersion("1.1");
-    EXPECT_CALL(br_, SendShellCommand("bugreportz -p", false, _)).WillOnce(Return(666));
-
-    const char* args[] = {"bugreport", "file.zip"};
-    ASSERT_EQ(666, br_.DoIt(2, args));
-}
-
-// Tests 'adb bugreport file.zip' when the bugreport could not be pulled
-TEST_F(BugreportTest, PullFails) {
-    ExpectBugreportzVersion("1.1");
-    EXPECT_CALL(br_, SendShellCommand("bugreportz -p", false, _))
-        .WillOnce(DoAll(WithArg<2>(WriteOnStdout("OK:/device/bugreport.zip")),
-                        WithArg<2>(ReturnCallbackDone())));
-    EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
-                                false, HasSubstr("file.zip")))
-        .WillOnce(Return(false));
-
-    const char* args[] = {"bugreport", "file.zip"};
-    ASSERT_EQ(1, br_.DoIt(2, args));
-}
diff --git a/adb/client/adb_client.cpp b/adb/client/adb_client.cpp
deleted file mode 100644
index f724cb5..0000000
--- a/adb/client/adb_client.cpp
+++ /dev/null
@@ -1,416 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define TRACE_TAG ADB
-
-#include "sysdeps.h"
-#include "adb_client.h"
-
-#include <errno.h>
-#include <inttypes.h>
-#include <limits.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#include <condition_variable>
-#include <mutex>
-#include <optional>
-#include <string>
-#include <thread>
-#include <vector>
-
-#include <android-base/file.h>
-#include <android-base/stringprintf.h>
-#include <android-base/strings.h>
-#include <android-base/thread_annotations.h>
-#include <cutils/sockets.h>
-
-#include "adb_io.h"
-#include "adb_utils.h"
-#include "socket_spec.h"
-#include "sysdeps/chrono.h"
-
-static TransportType __adb_transport = kTransportAny;
-static const char* __adb_serial = nullptr;
-static TransportId __adb_transport_id = 0;
-
-static const char* __adb_server_socket_spec;
-
-void adb_set_transport(TransportType type, const char* serial, TransportId transport_id) {
-    __adb_transport = type;
-    __adb_serial = serial;
-    __adb_transport_id = transport_id;
-}
-
-void adb_get_transport(TransportType* type, const char** serial, TransportId* transport_id) {
-    if (type) *type = __adb_transport;
-    if (serial) *serial = __adb_serial;
-    if (transport_id) *transport_id = __adb_transport_id;
-}
-
-void adb_set_socket_spec(const char* socket_spec) {
-    if (__adb_server_socket_spec) {
-        LOG(FATAL) << "attempted to reinitialize adb_server_socket_spec " << socket_spec << " (was " << __adb_server_socket_spec << ")";
-    }
-    __adb_server_socket_spec = socket_spec;
-}
-
-static std::optional<TransportId> switch_socket_transport(int fd, std::string* error) {
-    TransportId result;
-    bool read_transport = true;
-
-    std::string service;
-    if (__adb_transport_id) {
-        read_transport = false;
-        service += "host:transport-id:";
-        service += std::to_string(__adb_transport_id);
-        result = __adb_transport_id;
-    } else if (__adb_serial) {
-        service += "host:tport:serial:";
-        service += __adb_serial;
-    } else {
-        const char* transport_type = "???";
-        switch (__adb_transport) {
-          case kTransportUsb:
-              transport_type = "usb";
-              break;
-          case kTransportLocal:
-              transport_type = "local";
-              break;
-          case kTransportAny:
-              transport_type = "any";
-              break;
-          case kTransportHost:
-            // no switch necessary
-            return 0;
-        }
-        service += "host:tport:";
-        service += transport_type;
-    }
-
-    if (!SendProtocolString(fd, service)) {
-        *error = perror_str("write failure during connection");
-        return std::nullopt;
-    }
-
-    LOG(DEBUG) << "Switch transport in progress: " << service;
-
-    if (!adb_status(fd, error)) {
-        D("Switch transport failed: %s", error->c_str());
-        return std::nullopt;
-    }
-
-    if (read_transport) {
-        if (!ReadFdExactly(fd, &result, sizeof(result))) {
-            *error = "failed to read transport id from server";
-            return std::nullopt;
-        }
-    }
-
-    D("Switch transport success");
-    return result;
-}
-
-bool adb_status(borrowed_fd fd, std::string* error) {
-    char buf[5];
-    if (!ReadFdExactly(fd, buf, 4)) {
-        *error = perror_str("protocol fault (couldn't read status)");
-        return false;
-    }
-
-    if (!memcmp(buf, "OKAY", 4)) {
-        return true;
-    }
-
-    if (memcmp(buf, "FAIL", 4)) {
-        *error = android::base::StringPrintf("protocol fault (status %02x %02x %02x %02x?!)",
-                                             buf[0], buf[1], buf[2], buf[3]);
-        return false;
-    }
-
-    ReadProtocolString(fd, error, error);
-    return false;
-}
-
-static int _adb_connect(std::string_view service, TransportId* transport, std::string* error,
-                        bool force_switch = false) {
-    LOG(DEBUG) << "_adb_connect: " << service;
-    if (service.empty() || service.size() > MAX_PAYLOAD) {
-        *error = android::base::StringPrintf("bad service name length (%zd)", service.size());
-        return -1;
-    }
-
-    std::string reason;
-    unique_fd fd;
-    if (!socket_spec_connect(&fd, __adb_server_socket_spec, nullptr, nullptr, &reason)) {
-        *error = android::base::StringPrintf("cannot connect to daemon at %s: %s",
-                                             __adb_server_socket_spec, reason.c_str());
-        return -2;
-    }
-
-    if (!service.starts_with("host") || force_switch) {
-        std::optional<TransportId> transport_result = switch_socket_transport(fd.get(), error);
-        if (!transport_result) {
-            return -1;
-        }
-
-        if (transport) {
-            *transport = *transport_result;
-        }
-    }
-
-    if (!SendProtocolString(fd.get(), service)) {
-        *error = perror_str("write failure during connection");
-        return -1;
-    }
-
-    if (!adb_status(fd.get(), error)) {
-        return -1;
-    }
-
-    D("_adb_connect: return fd %d", fd.get());
-    return fd.release();
-}
-
-bool adb_kill_server() {
-    D("adb_kill_server");
-    std::string reason;
-    unique_fd fd;
-    if (!socket_spec_connect(&fd, __adb_server_socket_spec, nullptr, nullptr, &reason)) {
-        fprintf(stderr, "cannot connect to daemon at %s: %s\n", __adb_server_socket_spec,
-                reason.c_str());
-        return true;
-    }
-
-    if (!SendProtocolString(fd.get(), "host:kill")) {
-        fprintf(stderr, "error: write failure during connection: %s\n", strerror(errno));
-        return false;
-    }
-
-    // The server might send OKAY, so consume that.
-    char buf[4];
-    ReadFdExactly(fd.get(), buf, 4);
-    // Now that no more data is expected, wait for socket orderly shutdown or error, indicating
-    // server death.
-    ReadOrderlyShutdown(fd.get());
-    return true;
-}
-
-int adb_connect(std::string_view service, std::string* error) {
-    return adb_connect(nullptr, service, error);
-}
-
-#if defined(__linux__)
-std::optional<std::string> adb_get_server_executable_path() {
-    int port;
-    std::string error;
-    if (!parse_tcp_socket_spec(__adb_server_socket_spec, nullptr, &port, nullptr, &error)) {
-        return {};
-    }
-
-    return adb_get_android_dir_path() + OS_PATH_SEPARATOR + "adb." + std::to_string(port);
-}
-#endif
-
-static bool __adb_check_server_version(std::string* error) {
-    unique_fd fd(_adb_connect("host:version", nullptr, error));
-
-    bool local = is_local_socket_spec(__adb_server_socket_spec);
-    if (fd == -2 && !local) {
-        fprintf(stderr, "* cannot start server on remote host\n");
-        // error is the original network connection error
-        return false;
-    } else if (fd == -2) {
-        fprintf(stderr, "* daemon not running; starting now at %s\n", __adb_server_socket_spec);
-    start_server:
-        if (launch_server(__adb_server_socket_spec)) {
-            fprintf(stderr, "* failed to start daemon\n");
-            // launch_server() has already printed detailed error info, so just
-            // return a generic error string about the overall adb_connect()
-            // that the caller requested.
-            *error = "cannot connect to daemon";
-            return false;
-        } else {
-            fprintf(stderr, "* daemon started successfully\n");
-        }
-        // The server will wait until it detects all of its connected devices before acking.
-        // Fall through to _adb_connect.
-    } else {
-        // If a server is already running, check its version matches.
-        int version = 0;
-
-        // If we have a file descriptor, then parse version result.
-        if (fd >= 0) {
-            std::string version_string;
-            if (!ReadProtocolString(fd, &version_string, error)) {
-                return false;
-            }
-
-            ReadOrderlyShutdown(fd);
-
-            if (sscanf(&version_string[0], "%04x", &version) != 1) {
-                *error = android::base::StringPrintf("cannot parse version string: %s",
-                                                     version_string.c_str());
-                return false;
-            }
-        } else {
-            // If fd is -1 check for "unknown host service" which would
-            // indicate a version of adb that does not support the
-            // version command, in which case we should fall-through to kill it.
-            if (*error != "unknown host service") {
-                return false;
-            }
-        }
-
-        if (version != ADB_SERVER_VERSION) {
-#if defined(__linux__)
-            if (version > ADB_SERVER_VERSION && local) {
-                // Try to re-exec the existing adb server's binary.
-                constexpr const char* adb_reexeced = "adb (re-execed)";
-                if (strcmp(adb_reexeced, *__adb_argv) != 0) {
-                    __adb_argv[0] = adb_reexeced;
-                    std::optional<std::string> server_path_path = adb_get_server_executable_path();
-                    std::string server_path;
-                    if (server_path_path &&
-                        android::base::ReadFileToString(*server_path_path, &server_path)) {
-                        if (execve(server_path.c_str(), const_cast<char**>(__adb_argv),
-                                   const_cast<char**>(__adb_envp)) == -1) {
-                            LOG(ERROR) << "failed to exec newer version at " << server_path;
-                        }
-
-                        // Fall-through to restarting the server.
-                    }
-                }
-            }
-#endif
-
-            fprintf(stderr, "adb server version (%d) doesn't match this client (%d); killing...\n",
-                    version, ADB_SERVER_VERSION);
-            adb_kill_server();
-            goto start_server;
-        }
-    }
-
-    return true;
-}
-
-bool adb_check_server_version(std::string* error) {
-    // Only check the version once per process, since this isn't atomic anyway.
-    static std::once_flag once;
-    static bool result;
-    static std::string* err;
-    std::call_once(once, []() {
-        err = new std::string();
-        result = __adb_check_server_version(err);
-    });
-    *error = *err;
-    return result;
-}
-
-int adb_connect(TransportId* transport, std::string_view service, std::string* error,
-                bool force_switch_device) {
-    LOG(DEBUG) << "adb_connect: service: " << service;
-
-    // Query the adb server's version.
-    if (!adb_check_server_version(error)) {
-        return -1;
-    }
-
-    // if the command is start-server, we are done.
-    if (service == "host:start-server") {
-        return 0;
-    }
-
-    unique_fd fd(_adb_connect(service, transport, error, force_switch_device));
-    if (fd == -1) {
-        D("_adb_connect error: %s", error->c_str());
-    } else if(fd == -2) {
-        fprintf(stderr, "* daemon still not running\n");
-    }
-    D("adb_connect: return fd %d", fd.get());
-
-    return fd.release();
-}
-
-bool adb_command(const std::string& service) {
-    std::string error;
-    unique_fd fd(adb_connect(service, &error));
-    if (fd < 0) {
-        fprintf(stderr, "error: %s\n", error.c_str());
-        return false;
-    }
-
-    if (!adb_status(fd.get(), &error)) {
-        fprintf(stderr, "error: %s\n", error.c_str());
-        return false;
-    }
-
-    ReadOrderlyShutdown(fd.get());
-    return true;
-}
-
-bool adb_query(const std::string& service, std::string* result, std::string* error) {
-    D("adb_query: %s", service.c_str());
-    unique_fd fd(adb_connect(service, error));
-    if (fd < 0) {
-        return false;
-    }
-
-    result->clear();
-    if (!ReadProtocolString(fd.get(), result, error)) {
-        return false;
-    }
-
-    ReadOrderlyShutdown(fd.get());
-    return true;
-}
-
-std::string format_host_command(const char* command) {
-    if (__adb_transport_id) {
-        return android::base::StringPrintf("host-transport-id:%" PRIu64 ":%s", __adb_transport_id,
-                                           command);
-    } else if (__adb_serial) {
-        return android::base::StringPrintf("host-serial:%s:%s", __adb_serial, command);
-    }
-
-    const char* prefix = "host";
-    if (__adb_transport == kTransportUsb) {
-        prefix = "host-usb";
-    } else if (__adb_transport == kTransportLocal) {
-        prefix = "host-local";
-    }
-    return android::base::StringPrintf("%s:%s", prefix, command);
-}
-
-bool adb_get_feature_set(FeatureSet* feature_set, std::string* error) {
-    static FeatureSet* features = nullptr;
-    if (!features) {
-        std::string result;
-        if (adb_query(format_host_command("features"), &result, error)) {
-            features = new FeatureSet(StringToFeatureSet(result));
-        }
-    }
-    if (features) {
-        *feature_set = *features;
-        return true;
-    }
-    feature_set->clear();
-    return false;
-}
diff --git a/adb/client/adb_client.h b/adb/client/adb_client.h
deleted file mode 100644
index 1c6cde7..0000000
--- a/adb/client/adb_client.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <functional>
-#include <optional>
-#include <string>
-
-#include "adb.h"
-#include "adb_unique_fd.h"
-#include "sysdeps.h"
-#include "transport.h"
-
-// Explicitly check the adb server version.
-// All of the commands below do this implicitly.
-// Only the first invocation of this function will check the server version.
-bool adb_check_server_version(std::string* _Nonnull error);
-
-// Connect to adb, connect to the named service, and return a valid fd for
-// interacting with that service upon success or a negative number on failure.
-int adb_connect(std::string_view service, std::string* _Nonnull error);
-
-// Same as above, except returning the TransportId for the service that we've connected to.
-// force_switch_device forces the function to attempt to select a device, even if the service
-// string appears to be a host: service (for use with host services that are device specific, like
-// forward).
-int adb_connect(TransportId* _Nullable id, std::string_view service, std::string* _Nonnull error,
-                bool force_switch_device = false);
-
-// Kill the currently running adb server, if it exists.
-bool adb_kill_server();
-
-// Connect to adb, connect to the named service, returns true if the connection
-// succeeded AND the service returned OKAY. Outputs any returned error otherwise.
-bool adb_command(const std::string& service);
-
-// Connects to the named adb service and fills 'result' with the response.
-// Returns true on success; returns false and fills 'error' on failure.
-bool adb_query(const std::string& service, std::string* _Nonnull result,
-               std::string* _Nonnull error);
-
-// Set the preferred transport to connect to.
-void adb_set_transport(TransportType type, const char* _Nullable serial, TransportId transport_id);
-void adb_get_transport(TransportType* _Nullable type, const char* _Nullable* _Nullable serial,
-                       TransportId* _Nullable transport_id);
-
-// Set the socket specification for the adb server.
-// This function can only be called once, and the argument must live to the end of the process.
-void adb_set_socket_spec(const char* _Nonnull socket_spec);
-
-// Send commands to the current emulator instance. Will fail if there is not
-// exactly one emulator connected (or if you use -s <serial> with a <serial>
-// that does not designate an emulator).
-int adb_send_emulator_command(int argc, const char* _Nonnull* _Nonnull argv,
-                              const char* _Nullable serial);
-
-// Reads a standard adb status response (OKAY|FAIL) and returns true in the
-// event of OKAY, false in the event of FAIL or protocol error.
-bool adb_status(borrowed_fd fd, std::string* _Nonnull error);
-
-// Create a host command corresponding to selected transport type/serial.
-std::string format_host_command(const char* _Nonnull command);
-
-// Get the feature set of the current preferred transport.
-bool adb_get_feature_set(FeatureSet* _Nonnull feature_set, std::string* _Nonnull error);
-
-#if defined(__linux__)
-// Get the path of a file containing the path to the server executable, if the socket spec set via
-// adb_set_socket_spec is a local one.
-std::optional<std::string> adb_get_server_executable_path();
-#endif
-
-// Globally acccesible argv/envp, for the purpose of re-execing adb.
-extern const char* _Nullable * _Nullable __adb_argv;
-extern const char* _Nullable * _Nullable __adb_envp;
-
-// ADB Secure DNS service interface. Used to query what ADB Secure DNS services have been
-// resolved, and to run some kind of callback for each one.
-using adb_secure_foreach_service_callback = std::function<void(
-        const char* _Nonnull service_name, const char* _Nonnull ip_address, uint16_t port)>;
-
-// Queries pairing/connect services that have been discovered and resolved.
-// If |host_name| is not null, run |cb| only for services
-// matching |host_name|. Otherwise, run for all services.
-void adb_secure_foreach_pairing_service(const char* _Nullable service_name,
-                                        adb_secure_foreach_service_callback cb);
-void adb_secure_foreach_connect_service(const char* _Nullable service_name,
-                                        adb_secure_foreach_service_callback cb);
-// Tries to connect to a |service_name| if found. Returns true if found and
-// connected, false otherwise.
-bool adb_secure_connect_by_service_name(const char* _Nonnull service_name);
diff --git a/adb/client/adb_install.cpp b/adb/client/adb_install.cpp
deleted file mode 100644
index f2de0d2..0000000
--- a/adb/client/adb_install.cpp
+++ /dev/null
@@ -1,995 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "adb_install.h"
-
-#include <fcntl.h>
-#include <inttypes.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <algorithm>
-#include <string>
-#include <string_view>
-#include <vector>
-
-#include <android-base/file.h>
-#include <android-base/parsebool.h>
-#include <android-base/stringprintf.h>
-#include <android-base/strings.h>
-
-#include "adb.h"
-#include "adb_client.h"
-#include "adb_unique_fd.h"
-#include "adb_utils.h"
-#include "client/file_sync_client.h"
-#include "commandline.h"
-#include "fastdeploy.h"
-#include "incremental.h"
-
-using namespace std::literals;
-
-static constexpr int kFastDeployMinApi = 24;
-
-namespace {
-
-enum InstallMode {
-    INSTALL_DEFAULT,
-    INSTALL_PUSH,
-    INSTALL_STREAM,
-    INSTALL_INCREMENTAL,
-};
-
-enum class CmdlineOption { None, Enable, Disable };
-}
-
-static bool can_use_feature(const char* feature) {
-    FeatureSet features;
-    std::string error;
-    if (!adb_get_feature_set(&features, &error)) {
-        fprintf(stderr, "error: %s\n", error.c_str());
-        return false;
-    }
-    return CanUseFeature(features, feature);
-}
-
-static InstallMode best_install_mode() {
-    if (can_use_feature(kFeatureCmd)) {
-        return INSTALL_STREAM;
-    }
-    return INSTALL_PUSH;
-}
-
-static bool is_apex_supported() {
-    return can_use_feature(kFeatureApex);
-}
-
-static bool is_abb_exec_supported() {
-    return can_use_feature(kFeatureAbbExec);
-}
-
-static int pm_command(int argc, const char** argv) {
-    std::string cmd = "pm";
-
-    while (argc-- > 0) {
-        cmd += " " + escape_arg(*argv++);
-    }
-
-    return send_shell_command(cmd);
-}
-
-static int uninstall_app_streamed(int argc, const char** argv) {
-    // 'adb uninstall' takes the same arguments as 'cmd package uninstall' on device
-    std::string cmd = "cmd package";
-    while (argc-- > 0) {
-        // deny the '-k' option until the remaining data/cache can be removed with adb/UI
-        if (strcmp(*argv, "-k") == 0) {
-            printf("The -k option uninstalls the application while retaining the "
-                   "data/cache.\n"
-                   "At the moment, there is no way to remove the remaining data.\n"
-                   "You will have to reinstall the application with the same "
-                   "signature, and fully "
-                   "uninstall it.\n"
-                   "If you truly wish to continue, execute 'adb shell cmd package "
-                   "uninstall -k'.\n");
-            return EXIT_FAILURE;
-        }
-        cmd += " " + escape_arg(*argv++);
-    }
-
-    return send_shell_command(cmd);
-}
-
-static int uninstall_app_legacy(int argc, const char** argv) {
-    /* if the user choose the -k option, we refuse to do it until devices are
-       out with the option to uninstall the remaining data somehow (adb/ui) */
-    for (int i = 1; i < argc; i++) {
-        if (!strcmp(argv[i], "-k")) {
-            printf("The -k option uninstalls the application while retaining the "
-                   "data/cache.\n"
-                   "At the moment, there is no way to remove the remaining data.\n"
-                   "You will have to reinstall the application with the same "
-                   "signature, and fully "
-                   "uninstall it.\n"
-                   "If you truly wish to continue, execute 'adb shell pm uninstall "
-                   "-k'\n.");
-            return EXIT_FAILURE;
-        }
-    }
-
-    /* 'adb uninstall' takes the same arguments as 'pm uninstall' on device */
-    return pm_command(argc, argv);
-}
-
-int uninstall_app(int argc, const char** argv) {
-    if (best_install_mode() == INSTALL_PUSH) {
-        return uninstall_app_legacy(argc, argv);
-    }
-    return uninstall_app_streamed(argc, argv);
-}
-
-static void read_status_line(int fd, char* buf, size_t count) {
-    count--;
-    while (count > 0) {
-        int len = adb_read(fd, buf, count);
-        if (len <= 0) {
-            break;
-        }
-
-        buf += len;
-        count -= len;
-    }
-    *buf = '\0';
-}
-
-static unique_fd send_command(const std::vector<std::string>& cmd_args, std::string* error) {
-    if (is_abb_exec_supported()) {
-        return send_abb_exec_command(cmd_args, error);
-    } else {
-        return unique_fd(adb_connect(android::base::Join(cmd_args, " "), error));
-    }
-}
-
-static int install_app_streamed(int argc, const char** argv, bool use_fastdeploy) {
-    printf("Performing Streamed Install\n");
-
-    // The last argument must be the APK file
-    const char* file = argv[argc - 1];
-    if (!android::base::EndsWithIgnoreCase(file, ".apk") &&
-        !android::base::EndsWithIgnoreCase(file, ".apex")) {
-        error_exit("filename doesn't end .apk or .apex: %s", file);
-    }
-
-    bool is_apex = false;
-    if (android::base::EndsWithIgnoreCase(file, ".apex")) {
-        is_apex = true;
-    }
-    if (is_apex && !is_apex_supported()) {
-        error_exit(".apex is not supported on the target device");
-    }
-
-    if (is_apex && use_fastdeploy) {
-        error_exit("--fastdeploy doesn't support .apex files");
-    }
-
-    if (use_fastdeploy) {
-        auto metadata = extract_metadata(file);
-        if (metadata.has_value()) {
-            // pass all but 1st (command) and last (apk path) parameters through to pm for
-            // session creation
-            std::vector<const char*> pm_args{argv + 1, argv + argc - 1};
-            auto patchFd = install_patch(pm_args.size(), pm_args.data());
-            return stream_patch(file, std::move(metadata.value()), std::move(patchFd));
-        }
-    }
-
-    struct stat sb;
-    if (stat(file, &sb) == -1) {
-        fprintf(stderr, "adb: failed to stat %s: %s\n", file, strerror(errno));
-        return 1;
-    }
-
-    unique_fd local_fd(adb_open(file, O_RDONLY | O_CLOEXEC));
-    if (local_fd < 0) {
-        fprintf(stderr, "adb: failed to open %s: %s\n", file, strerror(errno));
-        return 1;
-    }
-
-#ifdef __linux__
-    posix_fadvise(local_fd.get(), 0, 0, POSIX_FADV_SEQUENTIAL | POSIX_FADV_NOREUSE);
-#endif
-
-    const bool use_abb_exec = is_abb_exec_supported();
-    std::string error;
-    std::vector<std::string> cmd_args = {use_abb_exec ? "package" : "exec:cmd package"};
-    cmd_args.reserve(argc + 3);
-
-    // don't copy the APK name, but, copy the rest of the arguments as-is
-    while (argc-- > 1) {
-        if (use_abb_exec) {
-            cmd_args.push_back(*argv++);
-        } else {
-            cmd_args.push_back(escape_arg(*argv++));
-        }
-    }
-
-    // add size parameter [required for streaming installs]
-    // do last to override any user specified value
-    cmd_args.push_back("-S");
-    cmd_args.push_back(android::base::StringPrintf("%" PRIu64, static_cast<uint64_t>(sb.st_size)));
-
-    if (is_apex) {
-        cmd_args.push_back("--apex");
-    }
-
-    unique_fd remote_fd = send_command(cmd_args, &error);
-    if (remote_fd < 0) {
-        fprintf(stderr, "adb: connect error for write: %s\n", error.c_str());
-        return 1;
-    }
-
-    if (!copy_to_file(local_fd.get(), remote_fd.get())) {
-        fprintf(stderr, "adb: failed to install: copy_to_file: %s: %s", file, strerror(errno));
-        return 1;
-    }
-
-    char buf[BUFSIZ];
-    read_status_line(remote_fd.get(), buf, sizeof(buf));
-    if (strncmp("Success", buf, 7) != 0) {
-        fprintf(stderr, "adb: failed to install %s: %s", file, buf);
-        return 1;
-    }
-
-    fputs(buf, stdout);
-    return 0;
-}
-
-static int install_app_legacy(int argc, const char** argv, bool use_fastdeploy) {
-    printf("Performing Push Install\n");
-
-    // Find last APK argument.
-    // All other arguments passed through verbatim.
-    int last_apk = -1;
-    for (int i = argc - 1; i >= 0; i--) {
-        if (android::base::EndsWithIgnoreCase(argv[i], ".apex")) {
-            error_exit("APEX packages are only compatible with Streamed Install");
-        }
-        if (android::base::EndsWithIgnoreCase(argv[i], ".apk")) {
-            last_apk = i;
-            break;
-        }
-    }
-
-    if (last_apk == -1) error_exit("need APK file on command line");
-
-    int result = -1;
-    std::vector<const char*> apk_file = {argv[last_apk]};
-    std::string apk_dest = "/data/local/tmp/" + android::base::Basename(argv[last_apk]);
-    argv[last_apk] = apk_dest.c_str(); /* destination name, not source location */
-
-    if (use_fastdeploy) {
-        auto metadata = extract_metadata(apk_file[0]);
-        if (metadata.has_value()) {
-            auto patchFd = apply_patch_on_device(apk_dest.c_str());
-            int status = stream_patch(apk_file[0], std::move(metadata.value()), std::move(patchFd));
-
-            result = pm_command(argc, argv);
-            delete_device_file(apk_dest);
-
-            return status;
-        }
-    }
-
-    if (do_sync_push(apk_file, apk_dest.c_str(), false, true)) {
-        result = pm_command(argc, argv);
-        delete_device_file(apk_dest);
-    }
-
-    return result;
-}
-
-template <class TimePoint>
-static int ms_between(TimePoint start, TimePoint end) {
-    return std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
-}
-
-static int install_app_incremental(int argc, const char** argv, bool wait, bool silent) {
-    using clock = std::chrono::high_resolution_clock;
-    const auto start = clock::now();
-    int first_apk = -1;
-    int last_apk = -1;
-    incremental::Args passthrough_args = {};
-    for (int i = 0; i < argc; ++i) {
-        const auto arg = std::string_view(argv[i]);
-        if (android::base::EndsWithIgnoreCase(arg, ".apk"sv)) {
-            last_apk = i;
-            if (first_apk == -1) {
-                first_apk = i;
-            }
-        } else if (arg.starts_with("install"sv)) {
-            // incremental installation command on the device is the same for all its variations in
-            // the adb, e.g. install-multiple or install-multi-package
-        } else {
-            passthrough_args.push_back(arg);
-        }
-    }
-
-    if (first_apk == -1) {
-        if (!silent) {
-            fprintf(stderr, "error: need at least one APK file on command line\n");
-        }
-        return -1;
-    }
-
-    auto files = incremental::Files{argv + first_apk, argv + last_apk + 1};
-    if (silent) {
-        // For a silent installation we want to do the lightweight check first and bail early and
-        // quietly if it fails.
-        if (!incremental::can_install(files)) {
-            return -1;
-        }
-    }
-
-    printf("Performing Incremental Install\n");
-    auto server_process = incremental::install(files, passthrough_args, silent);
-    if (!server_process) {
-        return -1;
-    }
-
-    const auto end = clock::now();
-    printf("Install command complete in %d ms\n", ms_between(start, end));
-
-    if (wait) {
-        (*server_process).wait();
-    }
-
-    return 0;
-}
-
-static std::pair<InstallMode, std::optional<InstallMode>> calculate_install_mode(
-        InstallMode modeFromArgs, bool fastdeploy, CmdlineOption incremental_request) {
-    if (incremental_request == CmdlineOption::Enable) {
-        if (fastdeploy) {
-            error_exit(
-                    "--incremental and --fast-deploy options are incompatible. "
-                    "Please choose one");
-        }
-    }
-
-    if (modeFromArgs != INSTALL_DEFAULT) {
-        if (incremental_request == CmdlineOption::Enable) {
-            error_exit("--incremental is not compatible with other installation modes");
-        }
-        return {modeFromArgs, std::nullopt};
-    }
-
-    if (incremental_request != CmdlineOption::Disable && !is_abb_exec_supported()) {
-        if (incremental_request == CmdlineOption::None) {
-            incremental_request = CmdlineOption::Disable;
-        } else {
-            error_exit("Device doesn't support incremental installations");
-        }
-    }
-    if (incremental_request == CmdlineOption::None) {
-        // check if the host is ok with incremental by default
-        if (const char* incrementalFromEnv = getenv("ADB_INSTALL_DEFAULT_INCREMENTAL")) {
-            using namespace android::base;
-            auto val = ParseBool(incrementalFromEnv);
-            if (val == ParseBoolResult::kFalse) {
-                incremental_request = CmdlineOption::Disable;
-            }
-        }
-    }
-    if (incremental_request == CmdlineOption::None) {
-        // still ok: let's see if the device allows using incremental by default
-        // it starts feeling like we're looking for an excuse to not to use incremental...
-        std::string error;
-        std::vector<std::string> args = {"settings", "get",
-                                         "enable_adb_incremental_install_default"};
-        auto fd = send_abb_exec_command(args, &error);
-        if (!fd.ok()) {
-            fprintf(stderr, "adb: retrieving the default device installation mode failed: %s",
-                    error.c_str());
-        } else {
-            char buf[BUFSIZ] = {};
-            read_status_line(fd.get(), buf, sizeof(buf));
-            using namespace android::base;
-            auto val = ParseBool(buf);
-            if (val == ParseBoolResult::kFalse) {
-                incremental_request = CmdlineOption::Disable;
-            }
-        }
-    }
-
-    if (incremental_request == CmdlineOption::Enable) {
-        // explicitly requested - no fallback
-        return {INSTALL_INCREMENTAL, std::nullopt};
-    }
-    const auto bestMode = best_install_mode();
-    if (incremental_request == CmdlineOption::None) {
-        // no opinion - use incremental, fallback to regular on a failure.
-        return {INSTALL_INCREMENTAL, bestMode};
-    }
-    // incremental turned off - use the regular best mode without a fallback.
-    return {bestMode, std::nullopt};
-}
-
-static std::vector<const char*> parse_install_mode(std::vector<const char*> argv,
-                                                   InstallMode* install_mode,
-                                                   CmdlineOption* incremental_request,
-                                                   bool* incremental_wait) {
-    *install_mode = INSTALL_DEFAULT;
-    *incremental_request = CmdlineOption::None;
-    *incremental_wait = false;
-
-    std::vector<const char*> passthrough;
-    for (auto&& arg : argv) {
-        if (arg == "--streaming"sv) {
-            *install_mode = INSTALL_STREAM;
-        } else if (arg == "--no-streaming"sv) {
-            *install_mode = INSTALL_PUSH;
-        } else if (strlen(arg) >= "--incr"sv.size() && "--incremental"sv.starts_with(arg)) {
-            *incremental_request = CmdlineOption::Enable;
-        } else if (strlen(arg) >= "--no-incr"sv.size() && "--no-incremental"sv.starts_with(arg)) {
-            *incremental_request = CmdlineOption::Disable;
-        } else if (arg == "--wait"sv) {
-            *incremental_wait = true;
-        } else {
-            passthrough.push_back(arg);
-        }
-    }
-    return passthrough;
-}
-
-static std::vector<const char*> parse_fast_deploy_mode(
-        std::vector<const char*> argv, bool* use_fastdeploy,
-        FastDeploy_AgentUpdateStrategy* agent_update_strategy) {
-    *use_fastdeploy = false;
-    *agent_update_strategy = FastDeploy_AgentUpdateDifferentVersion;
-
-    std::vector<const char*> passthrough;
-    for (auto&& arg : argv) {
-        if (arg == "--fastdeploy"sv) {
-            *use_fastdeploy = true;
-        } else if (arg == "--no-fastdeploy"sv) {
-            *use_fastdeploy = false;
-        } else if (arg == "--force-agent"sv) {
-            *agent_update_strategy = FastDeploy_AgentUpdateAlways;
-        } else if (arg == "--date-check-agent"sv) {
-            *agent_update_strategy = FastDeploy_AgentUpdateNewerTimeStamp;
-        } else if (arg == "--version-check-agent"sv) {
-            *agent_update_strategy = FastDeploy_AgentUpdateDifferentVersion;
-        } else {
-            passthrough.push_back(arg);
-        }
-    }
-    return passthrough;
-}
-
-int install_app(int argc, const char** argv) {
-    InstallMode install_mode = INSTALL_DEFAULT;
-    auto incremental_request = CmdlineOption::None;
-    bool incremental_wait = false;
-
-    bool use_fastdeploy = false;
-    FastDeploy_AgentUpdateStrategy agent_update_strategy = FastDeploy_AgentUpdateDifferentVersion;
-
-    auto unused_argv = parse_install_mode({argv, argv + argc}, &install_mode, &incremental_request,
-                                          &incremental_wait);
-    auto passthrough_argv =
-            parse_fast_deploy_mode(std::move(unused_argv), &use_fastdeploy, &agent_update_strategy);
-
-    auto [primary_mode, fallback_mode] =
-            calculate_install_mode(install_mode, use_fastdeploy, incremental_request);
-    if ((primary_mode == INSTALL_STREAM ||
-         fallback_mode.value_or(INSTALL_PUSH) == INSTALL_STREAM) &&
-        best_install_mode() == INSTALL_PUSH) {
-        error_exit("Attempting to use streaming install on unsupported device");
-    }
-
-    if (use_fastdeploy && get_device_api_level() < kFastDeployMinApi) {
-        fprintf(stderr,
-                "Fast Deploy is only compatible with devices of API version %d or higher, "
-                "ignoring.\n",
-                kFastDeployMinApi);
-        use_fastdeploy = false;
-    }
-    fastdeploy_set_agent_update_strategy(agent_update_strategy);
-
-    if (passthrough_argv.size() < 2) {
-        error_exit("install requires an apk argument");
-    }
-
-    auto run_install_mode = [&](InstallMode install_mode, bool silent) {
-        switch (install_mode) {
-            case INSTALL_PUSH:
-                return install_app_legacy(passthrough_argv.size(), passthrough_argv.data(),
-                                          use_fastdeploy);
-            case INSTALL_STREAM:
-                return install_app_streamed(passthrough_argv.size(), passthrough_argv.data(),
-                                            use_fastdeploy);
-            case INSTALL_INCREMENTAL:
-                return install_app_incremental(passthrough_argv.size(), passthrough_argv.data(),
-                                               incremental_wait, silent);
-            case INSTALL_DEFAULT:
-            default:
-                error_exit("invalid install mode");
-        }
-    };
-    auto res = run_install_mode(primary_mode, fallback_mode.has_value());
-    if (res && fallback_mode.value_or(primary_mode) != primary_mode) {
-        res = run_install_mode(*fallback_mode, false);
-    }
-    return res;
-}
-
-static int install_multiple_app_streamed(int argc, const char** argv) {
-    // Find all APK arguments starting at end.
-    // All other arguments passed through verbatim.
-    int first_apk = -1;
-    uint64_t total_size = 0;
-    for (int i = argc - 1; i >= 0; i--) {
-        const char* file = argv[i];
-        if (android::base::EndsWithIgnoreCase(argv[i], ".apex")) {
-            error_exit("APEX packages are not compatible with install-multiple");
-        }
-
-        if (android::base::EndsWithIgnoreCase(file, ".apk") ||
-            android::base::EndsWithIgnoreCase(file, ".dm") ||
-            android::base::EndsWithIgnoreCase(file, ".fsv_sig")) {
-            struct stat sb;
-            if (stat(file, &sb) == -1) perror_exit("failed to stat \"%s\"", file);
-            total_size += sb.st_size;
-            first_apk = i;
-        } else {
-            break;
-        }
-    }
-
-    if (first_apk == -1) error_exit("need APK file on command line");
-
-    const bool use_abb_exec = is_abb_exec_supported();
-    const std::string install_cmd =
-            use_abb_exec ? "package"
-                         : best_install_mode() == INSTALL_PUSH ? "exec:pm" : "exec:cmd package";
-
-    std::vector<std::string> cmd_args = {install_cmd, "install-create", "-S",
-                                         std::to_string(total_size)};
-    cmd_args.reserve(first_apk + 4);
-    for (int i = 1; i < first_apk; i++) {
-        if (use_abb_exec) {
-            cmd_args.push_back(argv[i]);
-        } else {
-            cmd_args.push_back(escape_arg(argv[i]));
-        }
-    }
-
-    // Create install session
-    std::string error;
-    char buf[BUFSIZ];
-    {
-        unique_fd fd = send_command(cmd_args, &error);
-        if (fd < 0) {
-            fprintf(stderr, "adb: connect error for create: %s\n", error.c_str());
-            return EXIT_FAILURE;
-        }
-        read_status_line(fd.get(), buf, sizeof(buf));
-    }
-
-    int session_id = -1;
-    if (!strncmp("Success", buf, 7)) {
-        char* start = strrchr(buf, '[');
-        char* end = strrchr(buf, ']');
-        if (start && end) {
-            *end = '\0';
-            session_id = strtol(start + 1, nullptr, 10);
-        }
-    }
-    if (session_id < 0) {
-        fprintf(stderr, "adb: failed to create session\n");
-        fputs(buf, stderr);
-        return EXIT_FAILURE;
-    }
-    const auto session_id_str = std::to_string(session_id);
-
-    // Valid session, now stream the APKs
-    bool success = true;
-    for (int i = first_apk; i < argc; i++) {
-        const char* file = argv[i];
-        struct stat sb;
-        if (stat(file, &sb) == -1) {
-            fprintf(stderr, "adb: failed to stat \"%s\": %s\n", file, strerror(errno));
-            success = false;
-            goto finalize_session;
-        }
-
-        std::vector<std::string> cmd_args = {
-                install_cmd,
-                "install-write",
-                "-S",
-                std::to_string(sb.st_size),
-                session_id_str,
-                android::base::Basename(file),
-                "-",
-        };
-
-        unique_fd local_fd(adb_open(file, O_RDONLY | O_CLOEXEC));
-        if (local_fd < 0) {
-            fprintf(stderr, "adb: failed to open \"%s\": %s\n", file, strerror(errno));
-            success = false;
-            goto finalize_session;
-        }
-
-        std::string error;
-        unique_fd remote_fd = send_command(cmd_args, &error);
-        if (remote_fd < 0) {
-            fprintf(stderr, "adb: connect error for write: %s\n", error.c_str());
-            success = false;
-            goto finalize_session;
-        }
-
-        if (!copy_to_file(local_fd.get(), remote_fd.get())) {
-            fprintf(stderr, "adb: failed to write \"%s\": %s\n", file, strerror(errno));
-            success = false;
-            goto finalize_session;
-        }
-
-        read_status_line(remote_fd.get(), buf, sizeof(buf));
-
-        if (strncmp("Success", buf, 7)) {
-            fprintf(stderr, "adb: failed to write \"%s\"\n", file);
-            fputs(buf, stderr);
-            success = false;
-            goto finalize_session;
-        }
-    }
-
-finalize_session:
-    // Commit session if we streamed everything okay; otherwise abandon.
-    std::vector<std::string> service_args = {
-            install_cmd,
-            success ? "install-commit" : "install-abandon",
-            session_id_str,
-    };
-    {
-        unique_fd fd = send_command(service_args, &error);
-        if (fd < 0) {
-            fprintf(stderr, "adb: connect error for finalize: %s\n", error.c_str());
-            return EXIT_FAILURE;
-        }
-        read_status_line(fd.get(), buf, sizeof(buf));
-    }
-    if (!success) return EXIT_FAILURE;
-
-    if (strncmp("Success", buf, 7)) {
-        fprintf(stderr, "adb: failed to finalize session\n");
-        fputs(buf, stderr);
-        return EXIT_FAILURE;
-    }
-
-    fputs(buf, stdout);
-    return EXIT_SUCCESS;
-}
-
-int install_multiple_app(int argc, const char** argv) {
-    InstallMode install_mode = INSTALL_DEFAULT;
-    auto incremental_request = CmdlineOption::None;
-    bool incremental_wait = false;
-    bool use_fastdeploy = false;
-
-    auto passthrough_argv = parse_install_mode({argv + 1, argv + argc}, &install_mode,
-                                               &incremental_request, &incremental_wait);
-
-    auto [primary_mode, fallback_mode] =
-            calculate_install_mode(install_mode, use_fastdeploy, incremental_request);
-    if ((primary_mode == INSTALL_STREAM ||
-         fallback_mode.value_or(INSTALL_PUSH) == INSTALL_STREAM) &&
-        best_install_mode() == INSTALL_PUSH) {
-        error_exit("Attempting to use streaming install on unsupported device");
-    }
-
-    auto run_install_mode = [&](InstallMode install_mode, bool silent) {
-        switch (install_mode) {
-            case INSTALL_PUSH:
-            case INSTALL_STREAM:
-                return install_multiple_app_streamed(passthrough_argv.size(),
-                                                     passthrough_argv.data());
-            case INSTALL_INCREMENTAL:
-                return install_app_incremental(passthrough_argv.size(), passthrough_argv.data(),
-                                               incremental_wait, silent);
-            case INSTALL_DEFAULT:
-            default:
-                error_exit("invalid install mode");
-        }
-    };
-    auto res = run_install_mode(primary_mode, fallback_mode.has_value());
-    if (res && fallback_mode.value_or(primary_mode) != primary_mode) {
-        res = run_install_mode(*fallback_mode, false);
-    }
-    return res;
-}
-
-int install_multi_package(int argc, const char** argv) {
-    // Find all APK arguments starting at end.
-    // All other arguments passed through verbatim.
-    bool apex_found = false;
-    int first_package = -1;
-    for (int i = argc - 1; i >= 0; i--) {
-        const char* file = argv[i];
-        if (android::base::EndsWithIgnoreCase(file, ".apk") ||
-            android::base::EndsWithIgnoreCase(file, ".apex")) {
-            first_package = i;
-            if (android::base::EndsWithIgnoreCase(file, ".apex")) {
-                apex_found = true;
-            }
-        } else {
-            break;
-        }
-    }
-
-    if (first_package == -1) error_exit("need APK or APEX files on command line");
-
-    if (best_install_mode() == INSTALL_PUSH) {
-        fprintf(stderr, "adb: multi-package install is not supported on this device\n");
-        return EXIT_FAILURE;
-    }
-
-    const bool use_abb_exec = is_abb_exec_supported();
-    const std::string install_cmd = use_abb_exec ? "package" : "exec:cmd package";
-
-    std::vector<std::string> multi_package_cmd_args = {install_cmd, "install-create",
-                                                       "--multi-package"};
-
-    multi_package_cmd_args.reserve(first_package + 4);
-    for (int i = 1; i < first_package; i++) {
-        if (use_abb_exec) {
-            multi_package_cmd_args.push_back(argv[i]);
-        } else {
-            multi_package_cmd_args.push_back(escape_arg(argv[i]));
-        }
-    }
-
-    if (apex_found) {
-        multi_package_cmd_args.emplace_back("--staged");
-    }
-
-    // Create multi-package install session
-    std::string error;
-    char buf[BUFSIZ];
-    {
-        unique_fd fd = send_command(multi_package_cmd_args, &error);
-        if (fd < 0) {
-            fprintf(stderr, "adb: connect error for create multi-package: %s\n", error.c_str());
-            return EXIT_FAILURE;
-        }
-        read_status_line(fd.get(), buf, sizeof(buf));
-    }
-
-    int parent_session_id = -1;
-    if (!strncmp("Success", buf, 7)) {
-        char* start = strrchr(buf, '[');
-        char* end = strrchr(buf, ']');
-        if (start && end) {
-            *end = '\0';
-            parent_session_id = strtol(start + 1, nullptr, 10);
-        }
-    }
-    if (parent_session_id < 0) {
-        fprintf(stderr, "adb: failed to create multi-package session\n");
-        fputs(buf, stderr);
-        return EXIT_FAILURE;
-    }
-    const auto parent_session_id_str = std::to_string(parent_session_id);
-
-    fprintf(stdout, "Created parent session ID %d.\n", parent_session_id);
-
-    std::vector<int> session_ids;
-
-    // Valid session, now create the individual sessions and stream the APKs
-    int success = EXIT_FAILURE;
-    std::vector<std::string> individual_cmd_args = {install_cmd, "install-create"};
-    for (int i = 1; i < first_package; i++) {
-        if (use_abb_exec) {
-            individual_cmd_args.push_back(argv[i]);
-        } else {
-            individual_cmd_args.push_back(escape_arg(argv[i]));
-        }
-    }
-    if (apex_found) {
-        individual_cmd_args.emplace_back("--staged");
-    }
-
-    std::vector<std::string> individual_apex_cmd_args;
-    if (apex_found) {
-        individual_apex_cmd_args = individual_cmd_args;
-        individual_apex_cmd_args.emplace_back("--apex");
-    }
-
-    std::vector<std::string> add_session_cmd_args = {
-            install_cmd,
-            "install-add-session",
-            parent_session_id_str,
-    };
-
-    for (int i = first_package; i < argc; i++) {
-        const char* file = argv[i];
-        char buf[BUFSIZ];
-        {
-            unique_fd fd;
-            // Create individual install session
-            if (android::base::EndsWithIgnoreCase(file, ".apex")) {
-                fd = send_command(individual_apex_cmd_args, &error);
-            } else {
-                fd = send_command(individual_cmd_args, &error);
-            }
-            if (fd < 0) {
-                fprintf(stderr, "adb: connect error for create: %s\n", error.c_str());
-                goto finalize_multi_package_session;
-            }
-            read_status_line(fd.get(), buf, sizeof(buf));
-        }
-
-        int session_id = -1;
-        if (!strncmp("Success", buf, 7)) {
-            char* start = strrchr(buf, '[');
-            char* end = strrchr(buf, ']');
-            if (start && end) {
-                *end = '\0';
-                session_id = strtol(start + 1, nullptr, 10);
-            }
-        }
-        if (session_id < 0) {
-            fprintf(stderr, "adb: failed to create multi-package session\n");
-            fputs(buf, stderr);
-            goto finalize_multi_package_session;
-        }
-        const auto session_id_str = std::to_string(session_id);
-
-        fprintf(stdout, "Created child session ID %d.\n", session_id);
-        session_ids.push_back(session_id);
-
-        // Support splitAPKs by allowing the notation split1.apk:split2.apk:split3.apk as argument.
-        std::vector<std::string> splits = android::base::Split(file, ":");
-
-        for (const std::string& split : splits) {
-            struct stat sb;
-            if (stat(split.c_str(), &sb) == -1) {
-                fprintf(stderr, "adb: failed to stat %s: %s\n", split.c_str(), strerror(errno));
-                goto finalize_multi_package_session;
-            }
-
-            std::vector<std::string> cmd_args = {
-                    install_cmd,
-                    "install-write",
-                    "-S",
-                    std::to_string(sb.st_size),
-                    session_id_str,
-                    android::base::StringPrintf("%d_%s", i, android::base::Basename(file).c_str()),
-                    "-",
-            };
-
-            unique_fd local_fd(adb_open(split.c_str(), O_RDONLY | O_CLOEXEC));
-            if (local_fd < 0) {
-                fprintf(stderr, "adb: failed to open %s: %s\n", split.c_str(), strerror(errno));
-                goto finalize_multi_package_session;
-            }
-
-            std::string error;
-            unique_fd remote_fd = send_command(cmd_args, &error);
-            if (remote_fd < 0) {
-                fprintf(stderr, "adb: connect error for write: %s\n", error.c_str());
-                goto finalize_multi_package_session;
-            }
-
-            if (!copy_to_file(local_fd.get(), remote_fd.get())) {
-                fprintf(stderr, "adb: failed to write %s: %s\n", split.c_str(), strerror(errno));
-                goto finalize_multi_package_session;
-            }
-
-            read_status_line(remote_fd.get(), buf, sizeof(buf));
-
-            if (strncmp("Success", buf, 7)) {
-                fprintf(stderr, "adb: failed to write %s\n", split.c_str());
-                fputs(buf, stderr);
-                goto finalize_multi_package_session;
-            }
-        }
-        add_session_cmd_args.push_back(std::to_string(session_id));
-    }
-
-    {
-        unique_fd fd = send_command(add_session_cmd_args, &error);
-        if (fd < 0) {
-            fprintf(stderr, "adb: connect error for install-add-session: %s\n", error.c_str());
-            goto finalize_multi_package_session;
-        }
-        read_status_line(fd.get(), buf, sizeof(buf));
-    }
-
-    if (strncmp("Success", buf, 7)) {
-        fprintf(stderr, "adb: failed to link sessions (%s)\n",
-                android::base::Join(add_session_cmd_args, " ").c_str());
-        fputs(buf, stderr);
-        goto finalize_multi_package_session;
-    }
-
-    // no failures means we can proceed with the assumption of success
-    success = 0;
-
-finalize_multi_package_session:
-    // Commit session if we streamed everything okay; otherwise abandon
-    std::vector<std::string> service_args = {
-            install_cmd,
-            success == 0 ? "install-commit" : "install-abandon",
-            parent_session_id_str,
-    };
-
-    {
-        unique_fd fd = send_command(service_args, &error);
-        if (fd < 0) {
-            fprintf(stderr, "adb: connect error for finalize: %s\n", error.c_str());
-            return EXIT_FAILURE;
-        }
-        read_status_line(fd.get(), buf, sizeof(buf));
-    }
-
-    if (!strncmp("Success", buf, 7)) {
-        fputs(buf, stdout);
-        if (success == 0) {
-            return 0;
-        }
-    } else {
-        fprintf(stderr, "adb: failed to finalize session\n");
-        fputs(buf, stderr);
-    }
-
-    session_ids.push_back(parent_session_id);
-    // try to abandon all remaining sessions
-    for (std::size_t i = 0; i < session_ids.size(); i++) {
-        std::vector<std::string> service_args = {
-                install_cmd,
-                "install-abandon",
-                std::to_string(session_ids[i]),
-        };
-        fprintf(stderr, "Attempting to abandon session ID %d\n", session_ids[i]);
-        unique_fd fd = send_command(service_args, &error);
-        if (fd < 0) {
-            fprintf(stderr, "adb: connect error for finalize: %s\n", error.c_str());
-            continue;
-        }
-        read_status_line(fd.get(), buf, sizeof(buf));
-    }
-    return EXIT_FAILURE;
-}
-
-int delete_device_file(const std::string& filename) {
-    // http://b/17339227 "Sideloading a Readonly File Results in a Prompt to
-    // Delete" caused us to add `-f` here, to avoid the equivalent of the `-i`
-    // prompt that you get from BSD rm (used in Android 5) if you have a
-    // non-writable file and stdin is a tty (which is true for old versions of
-    // adbd).
-    //
-    // Unfortunately, `rm -f` requires Android 4.3, so that workaround broke
-    // earlier Android releases. This was reported as http://b/37704384 "adb
-    // install -r passes invalid argument to rm on Android 4.1" and
-    // http://b/37035817 "ADB Fails: rm failed for -f, No such file or
-    // directory".
-    //
-    // Testing on a variety of devices and emulators shows that redirecting
-    // stdin is sufficient to avoid the pseudo-`-i`, and works on toolbox,
-    // BSD, and toybox versions of rm.
-    return send_shell_command("rm " + escape_arg(filename) + " </dev/null");
-}
diff --git a/adb/client/adb_install.h b/adb/client/adb_install.h
deleted file mode 100644
index 9946604..0000000
--- a/adb/client/adb_install.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <string>
-
-int install_app(int argc, const char** argv);
-int install_multiple_app(int argc, const char** argv);
-int install_multi_package(int argc, const char** argv);
-int uninstall_app(int argc, const char** argv);
-
-int delete_device_file(const std::string& filename);
-int delete_host_file(const std::string& filename);
-
diff --git a/adb/client/adb_wifi.cpp b/adb/client/adb_wifi.cpp
deleted file mode 100644
index fa71028..0000000
--- a/adb/client/adb_wifi.cpp
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "adb_wifi.h"
-
-#include <fstream>
-#include <random>
-#include <thread>
-
-#include <adb/crypto/key.h>
-#include <adb/crypto/x509_generator.h>
-#include <android-base/file.h>
-#include <android-base/parsenetaddress.h>
-#include "client/pairing/pairing_client.h"
-
-#include "adb_auth.h"
-#include "adb_known_hosts.pb.h"
-#include "adb_utils.h"
-#include "client/adb_client.h"
-#include "sysdeps.h"
-
-using adbwifi::pairing::PairingClient;
-using namespace adb::crypto;
-
-struct PairingResultWaiter {
-    std::mutex mutex_;
-    std::condition_variable cv_;
-    std::optional<bool> is_valid_;
-    PeerInfo peer_info_;
-
-    static void OnResult(const PeerInfo* peer_info, void* opaque) {
-        CHECK(opaque);
-        auto* p = reinterpret_cast<PairingResultWaiter*>(opaque);
-        {
-            std::lock_guard<std::mutex> lock(p->mutex_);
-            if (peer_info) {
-                memcpy(&(p->peer_info_), peer_info, sizeof(PeerInfo));
-            }
-            p->is_valid_ = (peer_info != nullptr);
-        }
-        p->cv_.notify_one();
-    }
-};  // PairingResultWaiter
-
-void adb_wifi_init() {}
-
-static std::vector<uint8_t> stringToUint8(const std::string& str) {
-    auto* p8 = reinterpret_cast<const uint8_t*>(str.data());
-    return std::vector<uint8_t>(p8, p8 + str.length());
-}
-
-// Tries to replace the |old_file| with |new_file|.
-// On success, then |old_file| has been removed and replaced with the
-// contents of |new_file|, |new_file| will be removed, and only |old_file| will
-// remain.
-// On failure, both files will be unchanged.
-// |new_file| must exist, but |old_file| does not need to exist.
-bool SafeReplaceFile(std::string_view old_file, std::string_view new_file) {
-    std::string to_be_deleted(old_file);
-    to_be_deleted += ".tbd";
-
-    bool old_renamed = true;
-    if (adb_rename(old_file.data(), to_be_deleted.c_str()) != 0) {
-        // Don't exit here. This is not necessarily an error, because |old_file|
-        // may not exist.
-        PLOG(INFO) << "Failed to rename " << old_file;
-        old_renamed = false;
-    }
-
-    if (adb_rename(new_file.data(), old_file.data()) != 0) {
-        PLOG(ERROR) << "Unable to rename file (" << new_file << " => " << old_file << ")";
-        if (old_renamed) {
-            // Rename the .tbd file back to it's original name
-            adb_rename(to_be_deleted.c_str(), old_file.data());
-        }
-        return false;
-    }
-
-    adb_unlink(to_be_deleted.c_str());
-    return true;
-}
-
-static std::string get_user_known_hosts_path() {
-    return adb_get_android_dir_path() + OS_PATH_SEPARATOR + "adb_known_hosts.pb";
-}
-
-bool load_known_hosts_from_file(const std::string& path, adb::proto::AdbKnownHosts& known_hosts) {
-    // Check for file existence.
-    struct stat buf;
-    if (stat(path.c_str(), &buf) == -1) {
-        LOG(INFO) << "Known hosts file [" << path << "] does not exist...";
-        return false;
-    }
-
-    std::ifstream file(path, std::ios::binary);
-    if (!file) {
-        PLOG(ERROR) << "Unable to open [" << path << "].";
-        return false;
-    }
-
-    if (!known_hosts.ParseFromIstream(&file)) {
-        PLOG(ERROR) << "Failed to parse [" << path << "]. Deleting it as it may be corrupted.";
-        adb_unlink(path.c_str());
-        return false;
-    }
-
-    return true;
-}
-
-static bool write_known_host_to_file(std::string& known_host) {
-    std::string path = get_user_known_hosts_path();
-    if (path.empty()) {
-        PLOG(ERROR) << "Error getting user known hosts filename";
-        return false;
-    }
-
-    adb::proto::AdbKnownHosts known_hosts;
-    load_known_hosts_from_file(path, known_hosts);
-    auto* host_info = known_hosts.add_host_infos();
-    host_info->set_guid(known_host);
-
-    std::unique_ptr<TemporaryFile> temp_file(new TemporaryFile(adb_get_android_dir_path()));
-    if (temp_file->fd == -1) {
-        PLOG(ERROR) << "Failed to open [" << temp_file->path << "] for writing";
-        return false;
-    }
-
-    if (!known_hosts.SerializeToFileDescriptor(temp_file->fd)) {
-        LOG(ERROR) << "Unable to write out adb_knowns_hosts";
-        return false;
-    }
-    temp_file->DoNotRemove();
-    std::string temp_file_name(temp_file->path);
-    temp_file.reset();
-
-    // Replace the existing adb_known_hosts with the new one
-    if (!SafeReplaceFile(path, temp_file_name.c_str())) {
-        LOG(ERROR) << "Failed to replace old adb_known_hosts";
-        adb_unlink(temp_file_name.c_str());
-        return false;
-    }
-    chmod(path.c_str(), S_IRUSR | S_IWUSR | S_IRGRP);
-
-    return true;
-}
-
-bool adb_wifi_is_known_host(const std::string& host) {
-    std::string path = get_user_known_hosts_path();
-    if (path.empty()) {
-        PLOG(ERROR) << "Error getting user known hosts filename";
-        return false;
-    }
-
-    adb::proto::AdbKnownHosts known_hosts;
-    if (!load_known_hosts_from_file(path, known_hosts)) {
-        return false;
-    }
-
-    for (const auto& host_info : known_hosts.host_infos()) {
-        if (host == host_info.guid()) {
-            return true;
-        }
-    }
-    return false;
-}
-
-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 priv_key = adb_auth_get_user_privkey();
-    auto x509_cert = GenerateX509Certificate(priv_key.get());
-    if (!x509_cert) {
-        LOG(ERROR) << "Unable to create X509 certificate for pairing";
-        return;
-    }
-    auto cert_str = X509ToPEMString(x509_cert.get());
-    auto priv_str = Key::ToPEMString(priv_key.get());
-
-    // Send our public key on pairing success
-    PeerInfo system_info = {};
-    system_info.type = ADB_RSA_PUB_KEY;
-    std::string public_key = adb_auth_get_userkey();
-    CHECK_LE(public_key.size(), sizeof(system_info.data) - 1);  // -1 for null byte
-    memcpy(system_info.data, public_key.data(), public_key.size());
-
-    auto pswd8 = stringToUint8(password);
-    auto cert8 = stringToUint8(cert_str);
-    auto priv8 = stringToUint8(priv_str);
-
-    auto client = PairingClient::Create(pswd8, system_info, cert8, priv8);
-    if (client == nullptr) {
-        response = "Failed: unable to create pairing client.";
-        return;
-    }
-
-    PairingResultWaiter waiter;
-    std::unique_lock<std::mutex> lock(waiter.mutex_);
-    if (!client->Start(host, waiter.OnResult, &waiter)) {
-        response = "Failed: Unable to start pairing client.";
-        return;
-    }
-    waiter.cv_.wait(lock, [&]() { return waiter.is_valid_.has_value(); });
-    if (!*(waiter.is_valid_)) {
-        response = "Failed: Wrong password or connection was dropped.";
-        return;
-    }
-
-    if (waiter.peer_info_.type != ADB_DEVICE_GUID) {
-        response = "Failed: Successfully paired but server returned unknown response=";
-        response += waiter.peer_info_.type;
-        return;
-    }
-
-    std::string device_guid = reinterpret_cast<const char*>(waiter.peer_info_.data);
-    response = "Successfully paired to " + host + " [guid=" + device_guid + "]";
-
-    // Write to adb_known_hosts
-    write_known_host_to_file(device_guid);
-    // Try to auto-connect.
-    adb_secure_connect_by_service_name(device_guid.c_str());
-}
diff --git a/adb/client/auth.cpp b/adb/client/auth.cpp
deleted file mode 100644
index 35264c7..0000000
--- a/adb/client/auth.cpp
+++ /dev/null
@@ -1,557 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define TRACE_TAG AUTH
-
-#include <dirent.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#if defined(__linux__)
-#include <sys/inotify.h>
-#endif
-
-#include <map>
-#include <mutex>
-#include <set>
-#include <string>
-
-#include <adb/crypto/rsa_2048_key.h>
-#include <adb/crypto/x509_generator.h>
-#include <adb/tls/adb_ca_list.h>
-#include <adb/tls/tls_connection.h>
-#include <android-base/errors.h>
-#include <android-base/file.h>
-#include <android-base/stringprintf.h>
-#include <android-base/strings.h>
-#include <crypto_utils/android_pubkey.h>
-#include <openssl/base64.h>
-#include <openssl/evp.h>
-#include <openssl/objects.h>
-#include <openssl/pem.h>
-#include <openssl/rsa.h>
-#include <openssl/sha.h>
-
-#include "adb.h"
-#include "adb_auth.h"
-#include "adb_io.h"
-#include "adb_utils.h"
-#include "sysdeps.h"
-#include "transport.h"
-
-static std::mutex& g_keys_mutex = *new std::mutex;
-static std::map<std::string, std::shared_ptr<RSA>>& g_keys =
-    *new std::map<std::string, std::shared_ptr<RSA>>;
-static std::map<int, std::string>& g_monitored_paths = *new std::map<int, std::string>;
-
-using namespace adb::crypto;
-using namespace adb::tls;
-
-static bool generate_key(const std::string& file) {
-    LOG(INFO) << "generate_key(" << file << ")...";
-
-    auto rsa_2048 = CreateRSA2048Key();
-    if (!rsa_2048) {
-        LOG(ERROR) << "Unable to create key";
-        return false;
-    }
-    std::string pubkey;
-
-    RSA* rsa = EVP_PKEY_get0_RSA(rsa_2048->GetEvpPkey());
-    CHECK(rsa);
-
-    if (!CalculatePublicKey(&pubkey, rsa)) {
-        LOG(ERROR) << "failed to calculate public key";
-        return false;
-    }
-
-    mode_t old_mask = umask(077);
-
-    std::unique_ptr<FILE, decltype(&fclose)> f(nullptr, &fclose);
-    f.reset(fopen(file.c_str(), "w"));
-    if (!f) {
-        PLOG(ERROR) << "Failed to open " << file;
-        umask(old_mask);
-        return false;
-    }
-
-    umask(old_mask);
-
-    if (!PEM_write_PrivateKey(f.get(), rsa_2048->GetEvpPkey(), nullptr, nullptr, 0, nullptr,
-                              nullptr)) {
-        LOG(ERROR) << "Failed to write key";
-        return false;
-    }
-
-    if (!android::base::WriteStringToFile(pubkey, file + ".pub")) {
-        PLOG(ERROR) << "failed to write public key";
-        return false;
-    }
-
-    return true;
-}
-
-static std::string hash_key(RSA* key) {
-    unsigned char* pubkey = nullptr;
-    int len = i2d_RSA_PUBKEY(key, &pubkey);
-    if (len < 0) {
-        LOG(ERROR) << "failed to encode RSA public key";
-        return std::string();
-    }
-
-    std::string result;
-    result.resize(SHA256_DIGEST_LENGTH);
-    SHA256(pubkey, len, reinterpret_cast<unsigned char*>(&result[0]));
-    OPENSSL_free(pubkey);
-    return result;
-}
-
-static std::shared_ptr<RSA> read_key_file(const std::string& file) {
-    std::unique_ptr<FILE, decltype(&fclose)> fp(fopen(file.c_str(), "r"), fclose);
-    if (!fp) {
-        PLOG(ERROR) << "Failed to open '" << file << "'";
-        return nullptr;
-    }
-
-    RSA* key = RSA_new();
-    if (!PEM_read_RSAPrivateKey(fp.get(), &key, nullptr, nullptr)) {
-        LOG(ERROR) << "Failed to read key from '" << file << "'";
-        ERR_print_errors_fp(stderr);
-        RSA_free(key);
-        return nullptr;
-    }
-
-    return std::shared_ptr<RSA>(key, RSA_free);
-}
-
-static bool load_key(const std::string& file) {
-    std::shared_ptr<RSA> key = read_key_file(file);
-    if (!key) {
-        return false;
-    }
-
-    std::lock_guard<std::mutex> lock(g_keys_mutex);
-    std::string fingerprint = hash_key(key.get());
-    if (g_keys.find(fingerprint) != g_keys.end()) {
-        LOG(INFO) << "ignoring already-loaded key: " << file;
-    } else {
-        LOG(INFO) << "Loaded fingerprint=[" << SHA256BitsToHexString(fingerprint) << "]";
-        g_keys[fingerprint] = std::move(key);
-    }
-    return true;
-}
-
-static bool load_keys(const std::string& path, bool allow_dir = true) {
-    LOG(INFO) << "load_keys '" << path << "'...";
-
-    struct stat st;
-    if (stat(path.c_str(), &st) != 0) {
-        PLOG(ERROR) << "failed to stat '" << path << "'";
-        return false;
-    }
-
-    if (S_ISREG(st.st_mode)) {
-        return load_key(path);
-    } else if (S_ISDIR(st.st_mode)) {
-        if (!allow_dir) {
-            // inotify isn't recursive. It would break expectations to load keys in nested
-            // directories but not monitor them for new keys.
-            LOG(WARNING) << "refusing to recurse into directory '" << path << "'";
-            return false;
-        }
-
-        std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(path.c_str()), closedir);
-        if (!dir) {
-            PLOG(ERROR) << "failed to open directory '" << path << "'";
-            return false;
-        }
-
-        bool result = false;
-        while (struct dirent* dent = readdir(dir.get())) {
-            std::string name = dent->d_name;
-
-            // We can't use dent->d_type here because it's not available on Windows.
-            if (name == "." || name == "..") {
-                continue;
-            }
-
-            if (!android::base::EndsWith(name, ".adb_key")) {
-                LOG(INFO) << "skipping non-adb_key '" << path << "/" << name << "'";
-                continue;
-            }
-
-            result |= load_key((path + OS_PATH_SEPARATOR + name));
-        }
-        return result;
-    }
-
-    LOG(ERROR) << "unexpected type for '" << path << "': 0x" << std::hex << st.st_mode;
-    return false;
-}
-
-static std::string get_user_key_path() {
-    return adb_get_android_dir_path() + OS_PATH_SEPARATOR + "adbkey";
-}
-
-static bool load_userkey() {
-    std::string path = get_user_key_path();
-    if (path.empty()) {
-        PLOG(ERROR) << "Error getting user key filename";
-        return false;
-    }
-
-    struct stat buf;
-    if (stat(path.c_str(), &buf) == -1) {
-        LOG(INFO) << "User key '" << path << "' does not exist...";
-        if (!generate_key(path)) {
-            LOG(ERROR) << "Failed to generate new key";
-            return false;
-        }
-    }
-
-    return load_key(path);
-}
-
-static std::set<std::string> get_vendor_keys() {
-    const char* adb_keys_path = getenv("ADB_VENDOR_KEYS");
-    if (adb_keys_path == nullptr) {
-        return std::set<std::string>();
-    }
-
-    std::set<std::string> result;
-    for (const auto& path : android::base::Split(adb_keys_path, ENV_PATH_SEPARATOR_STR)) {
-        result.emplace(path);
-    }
-    return result;
-}
-
-std::deque<std::shared_ptr<RSA>> adb_auth_get_private_keys() {
-    std::deque<std::shared_ptr<RSA>> result;
-
-    // Copy all the currently known keys.
-    std::lock_guard<std::mutex> lock(g_keys_mutex);
-    for (const auto& it : g_keys) {
-        result.push_back(it.second);
-    }
-
-    // Add a sentinel to the list. Our caller uses this to mean "out of private keys,
-    // but try using the public key" (the empty deque could otherwise mean this _or_
-    // that this function hasn't been called yet to request the keys).
-    result.push_back(nullptr);
-
-    return result;
-}
-
-static std::string adb_auth_sign(RSA* key, const char* token, size_t token_size) {
-    if (token_size != TOKEN_SIZE) {
-        D("Unexpected token size %zd", token_size);
-        return nullptr;
-    }
-
-    std::string result;
-    result.resize(MAX_PAYLOAD);
-
-    unsigned int len;
-    if (!RSA_sign(NID_sha1, reinterpret_cast<const uint8_t*>(token), token_size,
-                  reinterpret_cast<uint8_t*>(&result[0]), &len, key)) {
-        return std::string();
-    }
-
-    result.resize(len);
-
-    D("adb_auth_sign len=%d", len);
-    return result;
-}
-
-static bool pubkey_from_privkey(std::string* out, const std::string& path) {
-    std::shared_ptr<RSA> privkey = read_key_file(path);
-    if (!privkey) {
-        return false;
-    }
-    return CalculatePublicKey(out, privkey.get());
-}
-
-bssl::UniquePtr<EVP_PKEY> adb_auth_get_user_privkey() {
-    std::string path = get_user_key_path();
-    if (path.empty()) {
-        PLOG(ERROR) << "Error getting user key filename";
-        return nullptr;
-    }
-
-    std::shared_ptr<RSA> rsa_privkey = read_key_file(path);
-    if (!rsa_privkey) {
-        return nullptr;
-    }
-
-    bssl::UniquePtr<EVP_PKEY> pkey(EVP_PKEY_new());
-    if (!pkey) {
-        LOG(ERROR) << "Failed to allocate key";
-        return nullptr;
-    }
-
-    EVP_PKEY_set1_RSA(pkey.get(), rsa_privkey.get());
-    return pkey;
-}
-
-std::string adb_auth_get_userkey() {
-    std::string path = get_user_key_path();
-    if (path.empty()) {
-        PLOG(ERROR) << "Error getting user key filename";
-        return "";
-    }
-
-    std::string result;
-    if (!pubkey_from_privkey(&result, path)) {
-        return "";
-    }
-    return result;
-}
-
-int adb_auth_keygen(const char* filename) {
-    return !generate_key(filename);
-}
-
-int adb_auth_pubkey(const char* filename) {
-    std::string pubkey;
-    if (!pubkey_from_privkey(&pubkey, filename)) {
-        return 1;
-    }
-    pubkey.push_back('\n');
-
-    return WriteFdExactly(STDOUT_FILENO, pubkey.data(), pubkey.size()) ? 0 : 1;
-}
-
-#if defined(__linux__)
-static void adb_auth_inotify_update(int fd, unsigned fd_event, void*) {
-    LOG(INFO) << "adb_auth_inotify_update called";
-    if (!(fd_event & FDE_READ)) {
-        return;
-    }
-
-    char buf[sizeof(struct inotify_event) + NAME_MAX + 1];
-    while (true) {
-        ssize_t rc = TEMP_FAILURE_RETRY(unix_read(fd, buf, sizeof(buf)));
-        if (rc == -1) {
-            if (errno == EAGAIN) {
-                LOG(INFO) << "done reading inotify fd";
-                break;
-            }
-            PLOG(FATAL) << "read of inotify event failed";
-        }
-
-        // The read potentially returned multiple events.
-        char* start = buf;
-        char* end = buf + rc;
-
-        while (start < end) {
-            inotify_event* event = reinterpret_cast<inotify_event*>(start);
-            auto root_it = g_monitored_paths.find(event->wd);
-            if (root_it == g_monitored_paths.end()) {
-                LOG(FATAL) << "observed inotify event for unmonitored path, wd = " << event->wd;
-            }
-
-            std::string path = root_it->second;
-            if (event->len > 0) {
-                path += '/';
-                path += event->name;
-            }
-
-            if (event->mask & (IN_CREATE | IN_MOVED_TO)) {
-                if (event->mask & IN_ISDIR) {
-                    LOG(INFO) << "ignoring new directory at '" << path << "'";
-                } else {
-                    LOG(INFO) << "observed new file at '" << path << "'";
-                    load_keys(path, false);
-                }
-            } else {
-                LOG(WARNING) << "unmonitored event for " << path << ": 0x" << std::hex
-                             << event->mask;
-            }
-
-            start += sizeof(struct inotify_event) + event->len;
-        }
-    }
-}
-
-static void adb_auth_inotify_init(const std::set<std::string>& paths) {
-    LOG(INFO) << "adb_auth_inotify_init...";
-
-    int infd = inotify_init1(IN_CLOEXEC | IN_NONBLOCK);
-    if (infd < 0) {
-        PLOG(ERROR) << "failed to create inotify fd";
-        return;
-    }
-
-    for (const std::string& path : paths) {
-        int wd = inotify_add_watch(infd, path.c_str(), IN_CREATE | IN_MOVED_TO);
-        if (wd < 0) {
-            PLOG(ERROR) << "failed to inotify_add_watch on path '" << path;
-            continue;
-        }
-
-        g_monitored_paths[wd] = path;
-        LOG(INFO) << "watch descriptor " << wd << " registered for " << path;
-    }
-
-    fdevent* event = fdevent_create(infd, adb_auth_inotify_update, nullptr);
-    fdevent_add(event, FDE_READ);
-}
-#endif
-
-void adb_auth_init() {
-    LOG(INFO) << "adb_auth_init...";
-
-    if (!load_userkey()) {
-        LOG(ERROR) << "Failed to load (or generate) user key";
-        return;
-    }
-
-    const auto& key_paths = get_vendor_keys();
-
-#if defined(__linux__)
-    adb_auth_inotify_init(key_paths);
-#endif
-
-    for (const std::string& path : key_paths) {
-        load_keys(path);
-    }
-}
-
-static void send_auth_publickey(atransport* t) {
-    LOG(INFO) << "Calling send_auth_publickey";
-
-    std::string key = adb_auth_get_userkey();
-    if (key.empty()) {
-        D("Failed to get user public key");
-        return;
-    }
-
-    if (key.size() >= MAX_PAYLOAD_V1) {
-        D("User public key too large (%zu B)", key.size());
-        return;
-    }
-
-    apacket* p = get_apacket();
-    p->msg.command = A_AUTH;
-    p->msg.arg0 = ADB_AUTH_RSAPUBLICKEY;
-
-    // adbd expects a null-terminated string.
-    p->payload.assign(key.data(), key.data() + key.size() + 1);
-    p->msg.data_length = p->payload.size();
-    send_packet(p, t);
-}
-
-void send_auth_response(const char* token, size_t token_size, atransport* t) {
-    std::shared_ptr<RSA> key = t->NextKey();
-    if (key == nullptr) {
-        // No more private keys to try, send the public key.
-        t->SetConnectionState(kCsUnauthorized);
-        t->SetConnectionEstablished(true);
-        send_auth_publickey(t);
-        return;
-    }
-
-    LOG(INFO) << "Calling send_auth_response";
-    apacket* p = get_apacket();
-
-    std::string result = adb_auth_sign(key.get(), token, token_size);
-    if (result.empty()) {
-        D("Error signing the token");
-        put_apacket(p);
-        return;
-    }
-
-    p->msg.command = A_AUTH;
-    p->msg.arg0 = ADB_AUTH_SIGNATURE;
-    p->payload.assign(result.begin(), result.end());
-    p->msg.data_length = p->payload.size();
-    send_packet(p, t);
-}
-
-void adb_auth_tls_handshake(atransport* t) {
-    std::thread([t]() {
-        std::shared_ptr<RSA> key = t->Key();
-        if (key == nullptr) {
-            // Can happen if !auth_required
-            LOG(INFO) << "t->auth_key not set before handshake";
-            key = t->NextKey();
-            CHECK(key);
-        }
-
-        LOG(INFO) << "Attempting to TLS handshake";
-        bool success = t->connection()->DoTlsHandshake(key.get());
-        if (success) {
-            LOG(INFO) << "Handshake succeeded. Waiting for CNXN packet...";
-        } else {
-            LOG(INFO) << "Handshake failed. Kicking transport";
-            t->Kick();
-        }
-    }).detach();
-}
-
-// Callback given to SSL_set_cert_cb to select a certificate when server requests
-// for a certificate. This is where the server will give us a CA-issuer list, and
-// figure out if the server knows any of our public keys. We currently always return
-// 1 here to indicate success, since we always try a key here (in the case of no auth).
-// See https://commondatastorage.googleapis.com/chromium-boringssl-docs/ssl.h.html#SSL_set_cert_cb
-// for more details.
-int adb_tls_set_certificate(SSL* ssl) {
-    LOG(INFO) << __func__;
-
-    const STACK_OF(X509_NAME)* ca_list = SSL_get_client_CA_list(ssl);
-    if (ca_list == nullptr) {
-        // Either the device doesn't know any keys, or !auth_required.
-        // So let's just try with the default certificate and see what happens.
-        LOG(INFO) << "No client CA list. Trying with default certificate.";
-        return 1;
-    }
-
-    const size_t num_cas = sk_X509_NAME_num(ca_list);
-    for (size_t i = 0; i < num_cas; ++i) {
-        auto* x509_name = sk_X509_NAME_value(ca_list, i);
-        auto adbFingerprint = ParseEncodedKeyFromCAIssuer(x509_name);
-        if (!adbFingerprint.has_value()) {
-            // This could be a real CA issuer. Unfortunately, we don't support
-            // it ATM.
-            continue;
-        }
-
-        LOG(INFO) << "Checking for fingerprint match [" << *adbFingerprint << "]";
-        auto encoded_key = SHA256HexStringToBits(*adbFingerprint);
-        if (!encoded_key.has_value()) {
-            continue;
-        }
-        // Check against our list of encoded keys for a match
-        std::lock_guard<std::mutex> lock(g_keys_mutex);
-        auto rsa_priv_key = g_keys.find(*encoded_key);
-        if (rsa_priv_key != g_keys.end()) {
-            LOG(INFO) << "Got SHA256 match on a key";
-            bssl::UniquePtr<EVP_PKEY> evp_pkey(EVP_PKEY_new());
-            CHECK(EVP_PKEY_set1_RSA(evp_pkey.get(), rsa_priv_key->second.get()));
-            auto x509 = GenerateX509Certificate(evp_pkey.get());
-            auto x509_str = X509ToPEMString(x509.get());
-            auto evp_str = Key::ToPEMString(evp_pkey.get());
-            TlsConnection::SetCertAndKey(ssl, x509_str, evp_str);
-            return 1;
-        } else {
-            LOG(INFO) << "No match for [" << *adbFingerprint << "]";
-        }
-    }
-
-    // Let's just try with the default certificate anyways, because daemon might
-    // not require auth, even though it has a list of keys.
-    return 1;
-}
diff --git a/adb/client/bugreport.cpp b/adb/client/bugreport.cpp
deleted file mode 100644
index 8ca44e8..0000000
--- a/adb/client/bugreport.cpp
+++ /dev/null
@@ -1,286 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define TRACE_TAG ADB
-
-#include "sysdeps.h"
-
-#include "bugreport.h"
-
-#include <string>
-#include <vector>
-
-#include <android-base/file.h>
-#include <android-base/strings.h>
-
-#include "adb_utils.h"
-#include "client/file_sync_client.h"
-
-static constexpr char BUGZ_BEGIN_PREFIX[] = "BEGIN:";
-static constexpr char BUGZ_PROGRESS_PREFIX[] = "PROGRESS:";
-static constexpr char BUGZ_PROGRESS_SEPARATOR[] = "/";
-static constexpr char BUGZ_OK_PREFIX[] = "OK:";
-static constexpr char BUGZ_FAIL_PREFIX[] = "FAIL:";
-
-// Custom callback used to handle the output of zipped bugreports.
-class BugreportStandardStreamsCallback : public StandardStreamsCallbackInterface {
-  public:
-    BugreportStandardStreamsCallback(const std::string& dest_dir, const std::string& dest_file,
-                                     bool show_progress, Bugreport* br)
-        : br_(br),
-          src_file_(),
-          dest_dir_(dest_dir),
-          dest_file_(dest_file),
-          line_message_(),
-          invalid_lines_(),
-          show_progress_(show_progress),
-          status_(0),
-          line_(),
-          last_progress_percentage_(0) {
-        SetLineMessage("generating");
-    }
-
-    void OnStdout(const char* buffer, int length) {
-        for (int i = 0; i < length; i++) {
-            char c = buffer[i];
-            if (c == '\n') {
-                ProcessLine(line_);
-                line_.clear();
-            } else {
-                line_.append(1, c);
-            }
-        }
-    }
-
-    void OnStderr(const char* buffer, int length) {
-        OnStream(nullptr, stderr, buffer, length);
-    }
-
-    int Done(int unused_) {
-        // Process remaining line, if any.
-        ProcessLine(line_);
-
-        // Warn about invalid lines, if any.
-        if (!invalid_lines_.empty()) {
-            fprintf(stderr,
-                    "WARNING: bugreportz generated %zu line(s) with unknown commands, "
-                    "device might not support zipped bugreports:\n",
-                    invalid_lines_.size());
-            for (const auto& line : invalid_lines_) {
-                fprintf(stderr, "\t%s\n", line.c_str());
-            }
-            fprintf(stderr,
-                    "If the zipped bugreport was not generated, try 'adb bugreport' instead.\n");
-        }
-
-        // Pull the generated bug report.
-        if (status_ == 0) {
-            if (src_file_.empty()) {
-                fprintf(stderr, "bugreportz did not return a '%s' or '%s' line\n", BUGZ_OK_PREFIX,
-                        BUGZ_FAIL_PREFIX);
-                return -1;
-            }
-            std::string destination;
-            if (dest_dir_.empty()) {
-                destination = dest_file_;
-            } else {
-                destination = android::base::StringPrintf("%s%c%s", dest_dir_.c_str(),
-                                                          OS_PATH_SEPARATOR, dest_file_.c_str());
-            }
-            std::vector<const char*> srcs{src_file_.c_str()};
-            SetLineMessage("pulling");
-            status_ =
-                br_->DoSyncPull(srcs, destination.c_str(), false, line_message_.c_str()) ? 0 : 1;
-            if (status_ != 0) {
-                fprintf(stderr,
-                        "Bug report finished but could not be copied to '%s'.\n"
-                        "Try to run 'adb pull %s <directory>'\n"
-                        "to copy it to a directory that can be written.\n",
-                        destination.c_str(), src_file_.c_str());
-            }
-        }
-        return status_;
-    }
-
-  private:
-    void SetLineMessage(const std::string& action) {
-        line_message_ = action + " " + android::base::Basename(dest_file_);
-    }
-
-    void SetSrcFile(const std::string path) {
-        src_file_ = path;
-        if (!dest_dir_.empty()) {
-            // Only uses device-provided name when user passed a directory.
-            dest_file_ = android::base::Basename(path);
-            SetLineMessage("generating");
-        }
-    }
-
-    void ProcessLine(const std::string& line) {
-        if (line.empty()) return;
-
-        if (android::base::StartsWith(line, BUGZ_BEGIN_PREFIX)) {
-            SetSrcFile(&line[strlen(BUGZ_BEGIN_PREFIX)]);
-        } else if (android::base::StartsWith(line, BUGZ_OK_PREFIX)) {
-            SetSrcFile(&line[strlen(BUGZ_OK_PREFIX)]);
-        } else if (android::base::StartsWith(line, BUGZ_FAIL_PREFIX)) {
-            const char* error_message = &line[strlen(BUGZ_FAIL_PREFIX)];
-            fprintf(stderr, "adb: device failed to take a zipped bugreport: %s\n", error_message);
-            status_ = -1;
-        } else if (show_progress_ && android::base::StartsWith(line, BUGZ_PROGRESS_PREFIX)) {
-            // progress_line should have the following format:
-            //
-            // BUGZ_PROGRESS_PREFIX:PROGRESS/TOTAL
-            //
-            size_t idx1 = line.rfind(BUGZ_PROGRESS_PREFIX) + strlen(BUGZ_PROGRESS_PREFIX);
-            size_t idx2 = line.rfind(BUGZ_PROGRESS_SEPARATOR);
-            int progress = std::stoi(line.substr(idx1, (idx2 - idx1)));
-            int total = std::stoi(line.substr(idx2 + 1));
-            int progress_percentage = (progress * 100 / total);
-            if (progress_percentage != 0 && progress_percentage <= last_progress_percentage_) {
-                // Ignore.
-                return;
-            }
-            last_progress_percentage_ = progress_percentage;
-            br_->UpdateProgress(line_message_, progress_percentage);
-        } else {
-            invalid_lines_.push_back(line);
-        }
-    }
-
-    Bugreport* br_;
-
-    // Path of bugreport on device.
-    std::string src_file_;
-
-    // Bugreport destination on host, depending on argument passed on constructor:
-    // - if argument is a directory, dest_dir_ is set with it and dest_file_ will be the name
-    //   of the bugreport reported by the device.
-    // - if argument is empty, dest_dir is set as the current directory and dest_file_ will be the
-    //   name of the bugreport reported by the device.
-    // - otherwise, dest_dir_ is not set and dest_file_ is set with the value passed on constructor.
-    std::string dest_dir_, dest_file_;
-
-    // Message displayed on LinePrinter, it's updated every time the destination above change.
-    std::string line_message_;
-
-    // Lines sent by bugreportz that contain invalid commands; will be displayed at the end.
-    std::vector<std::string> invalid_lines_;
-
-    // Whether PROGRESS_LINES should be interpreted as progress.
-    bool show_progress_;
-
-    // Overall process of the operation, as returned by Done().
-    int status_;
-
-    // Temporary buffer containing the characters read since the last newline (\n).
-    std::string line_;
-
-    // Last displayed progress.
-    // Since dumpstate progress can recede, only forward progress should be displayed
-    int last_progress_percentage_;
-
-    DISALLOW_COPY_AND_ASSIGN(BugreportStandardStreamsCallback);
-};
-
-int Bugreport::DoIt(int argc, const char** argv) {
-    if (argc > 2) error_exit("usage: adb bugreport [PATH]");
-
-    // Gets bugreportz version.
-    std::string bugz_stdout, bugz_stderr;
-    DefaultStandardStreamsCallback version_callback(&bugz_stdout, &bugz_stderr);
-    int status = SendShellCommand("bugreportz -v", false, &version_callback);
-    std::string bugz_version = android::base::Trim(bugz_stderr);
-    std::string bugz_output = android::base::Trim(bugz_stdout);
-
-    if (status != 0 || bugz_version.empty()) {
-        D("'bugreportz' -v results: status=%d, stdout='%s', stderr='%s'", status,
-          bugz_output.c_str(), bugz_version.c_str());
-        if (argc == 1) {
-            // Device does not support bugreportz: if called as 'adb bugreport', just falls out to
-            // the flat-file version.
-            fprintf(stderr,
-                    "Failed to get bugreportz version, which is only available on devices "
-                    "running Android 7.0 or later.\nTrying a plain-text bug report instead.\n");
-            return SendShellCommand("bugreport", false);
-        }
-
-        // But if user explicitly asked for a zipped bug report, fails instead (otherwise calling
-        // 'bugreport' would generate a lot of output the user might not be prepared to handle).
-        fprintf(stderr,
-                "Failed to get bugreportz version: 'bugreportz -v' returned '%s' (code %d).\n"
-                "If the device does not run Android 7.0 or above, try 'adb bugreport' instead.\n",
-                bugz_output.c_str(), status);
-        return status != 0 ? status : -1;
-    }
-
-    std::string dest_file, dest_dir;
-
-    if (argc == 1) {
-        // No args - use current directory
-        if (!getcwd(&dest_dir)) {
-            perror("adb: getcwd failed");
-            return 1;
-        }
-    } else {
-        // Check whether argument is a directory or file
-        if (directory_exists(argv[1])) {
-            dest_dir = argv[1];
-        } else {
-            dest_file = argv[1];
-        }
-    }
-
-    if (dest_file.empty()) {
-        // Uses a default value until device provides the proper name
-        dest_file = "bugreport.zip";
-    } else {
-        if (!android::base::EndsWithIgnoreCase(dest_file, ".zip")) {
-            dest_file += ".zip";
-        }
-    }
-
-    bool show_progress = true;
-    std::string bugz_command = "bugreportz -p";
-    if (bugz_version == "1.0") {
-        // 1.0 does not support progress notifications, so print a disclaimer
-        // message instead.
-        fprintf(stderr,
-                "Bugreport is in progress and it could take minutes to complete.\n"
-                "Please be patient and do not cancel or disconnect your device "
-                "until it completes.\n");
-        show_progress = false;
-        bugz_command = "bugreportz";
-    }
-    BugreportStandardStreamsCallback bugz_callback(dest_dir, dest_file, show_progress, this);
-    return SendShellCommand(bugz_command, false, &bugz_callback);
-}
-
-void Bugreport::UpdateProgress(const std::string& message, int progress_percentage) {
-    line_printer_.Print(
-        android::base::StringPrintf("[%3d%%] %s", progress_percentage, message.c_str()),
-        LinePrinter::INFO);
-}
-
-int Bugreport::SendShellCommand(const std::string& command, bool disable_shell_protocol,
-                                StandardStreamsCallbackInterface* callback) {
-    return send_shell_command(command, disable_shell_protocol, callback);
-}
-
-bool Bugreport::DoSyncPull(const std::vector<const char*>& srcs, const char* dst, bool copy_attrs,
-                           const char* name) {
-    return do_sync_pull(srcs, dst, copy_attrs, name);
-}
diff --git a/adb/client/bugreport.h b/adb/client/bugreport.h
deleted file mode 100644
index 413439b..0000000
--- a/adb/client/bugreport.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef BUGREPORT_H
-#define BUGREPORT_H
-
-#include <vector>
-
-#include "adb.h"
-#include "commandline.h"
-#include "line_printer.h"
-
-class Bugreport {
-    friend class BugreportStandardStreamsCallback;
-
-  public:
-    Bugreport() : line_printer_() {
-    }
-    int DoIt(int argc, const char** argv);
-
-  protected:
-    // Functions below are abstractions of external functions so they can be
-    // mocked on tests.
-    virtual int SendShellCommand(
-        const std::string& command, bool disable_shell_protocol,
-        StandardStreamsCallbackInterface* callback = &DEFAULT_STANDARD_STREAMS_CALLBACK);
-
-    virtual bool DoSyncPull(const std::vector<const char*>& srcs, const char* dst, bool copy_attrs,
-                            const char* name);
-
-  private:
-    virtual void UpdateProgress(const std::string& file_name, int progress_percentage);
-    LinePrinter line_printer_;
-    DISALLOW_COPY_AND_ASSIGN(Bugreport);
-};
-
-#endif  // BUGREPORT_H
diff --git a/adb/client/commandline.cpp b/adb/client/commandline.cpp
deleted file mode 100644
index ad4e21c..0000000
--- a/adb/client/commandline.cpp
+++ /dev/null
@@ -1,2066 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define TRACE_TAG ADB
-
-#include "sysdeps.h"
-
-#include <assert.h>
-#include <ctype.h>
-#include <errno.h>
-#include <inttypes.h>
-#include <limits.h>
-#include <stdarg.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <iostream>
-
-#include <memory>
-#include <string>
-#include <thread>
-#include <vector>
-
-#include <android-base/file.h>
-#include <android-base/logging.h>
-#include <android-base/parseint.h>
-#include <android-base/stringprintf.h>
-#include <android-base/strings.h>
-
-#if !defined(_WIN32)
-#include <signal.h>
-#include <sys/ioctl.h>
-#include <termios.h>
-#include <unistd.h>
-#endif
-
-#include "adb.h"
-#include "adb_auth.h"
-#include "adb_client.h"
-#include "adb_install.h"
-#include "adb_io.h"
-#include "adb_unique_fd.h"
-#include "adb_utils.h"
-#include "bugreport.h"
-#include "client/file_sync_client.h"
-#include "commandline.h"
-#include "fastdeploy.h"
-#include "incremental_server.h"
-#include "services.h"
-#include "shell_protocol.h"
-#include "sysdeps/chrono.h"
-
-extern int gListenAll;
-
-DefaultStandardStreamsCallback DEFAULT_STANDARD_STREAMS_CALLBACK(nullptr, nullptr);
-
-static std::string product_file(const std::string& file) {
-    const char* ANDROID_PRODUCT_OUT = getenv("ANDROID_PRODUCT_OUT");
-    if (ANDROID_PRODUCT_OUT == nullptr) {
-        error_exit("product directory not specified; set $ANDROID_PRODUCT_OUT");
-    }
-    return std::string{ANDROID_PRODUCT_OUT} + OS_PATH_SEPARATOR_STR + file;
-}
-
-static void help() {
-    fprintf(stdout, "%s\n", adb_version().c_str());
-    // clang-format off
-    fprintf(stdout,
-        "global options:\n"
-        " -a         listen on all network interfaces, not just localhost\n"
-        " -d         use USB device (error if multiple devices connected)\n"
-        " -e         use TCP/IP device (error if multiple TCP/IP devices available)\n"
-        " -s SERIAL  use device with given serial (overrides $ANDROID_SERIAL)\n"
-        " -t ID      use device with given transport id\n"
-        " -H         name of adb server host [default=localhost]\n"
-        " -P         port of adb server [default=5037]\n"
-        " -L SOCKET  listen on given socket for adb server [default=tcp:localhost:5037]\n"
-        "\n"
-        "general commands:\n"
-        " devices [-l]             list connected devices (-l for long output)\n"
-        " help                     show this help message\n"
-        " version                  show version num\n"
-        "\n"
-        "networking:\n"
-        " connect HOST[:PORT]      connect to a device via TCP/IP [default port=5555]\n"
-        " disconnect [HOST[:PORT]]\n"
-        "     disconnect from given TCP/IP device [default port=5555], or all\n"
-        " pair HOST[:PORT]         pair with a device for secure TCP/IP communication\n"
-        " forward --list           list all forward socket connections\n"
-        " forward [--no-rebind] LOCAL REMOTE\n"
-        "     forward socket connection using:\n"
-        "       tcp:<port> (<local> may be \"tcp:0\" to pick any open port)\n"
-        "       localabstract:<unix domain socket name>\n"
-        "       localreserved:<unix domain socket name>\n"
-        "       localfilesystem:<unix domain socket name>\n"
-        "       dev:<character device name>\n"
-        "       jdwp:<process pid> (remote only)\n"
-        "       acceptfd:<fd> (listen only)\n"
-        " forward --remove LOCAL   remove specific forward socket connection\n"
-        " forward --remove-all     remove all forward socket connections\n"
-        " ppp TTY [PARAMETER...]   run PPP over USB\n"
-        " reverse --list           list all reverse socket connections from device\n"
-        " reverse [--no-rebind] REMOTE LOCAL\n"
-        "     reverse socket connection using:\n"
-        "       tcp:<port> (<remote> may be \"tcp:0\" to pick any open port)\n"
-        "       localabstract:<unix domain socket name>\n"
-        "       localreserved:<unix domain socket name>\n"
-        "       localfilesystem:<unix domain socket name>\n"
-        " reverse --remove REMOTE  remove specific reverse socket connection\n"
-        " reverse --remove-all     remove all reverse socket connections from device\n"
-        "\n"
-        "file transfer:\n"
-        " push [--sync] [-zZ] LOCAL... REMOTE\n"
-        "     copy local files/directories to device\n"
-        "     --sync: only push files that are newer on the host than the device\n"
-        "     -z: enable compression\n"
-        "     -Z: disable compression\n"
-        " pull [-azZ] REMOTE... LOCAL\n"
-        "     copy files/dirs from device\n"
-        "     -a: preserve file timestamp and mode\n"
-        "     -z: enable compression\n"
-        "     -Z: disable compression\n"
-        " sync [-lzZ] [all|data|odm|oem|product|system|system_ext|vendor]\n"
-        "     sync a local build from $ANDROID_PRODUCT_OUT to the device (default all)\n"
-        "     -l: list files that would be copied, but don't copy them\n"
-        "     -z: enable compression\n"
-        "     -Z: disable compression\n"
-        "\n"
-        "shell:\n"
-        " shell [-e ESCAPE] [-n] [-Tt] [-x] [COMMAND...]\n"
-        "     run remote shell command (interactive shell if no command given)\n"
-        "     -e: choose escape character, or \"none\"; default '~'\n"
-        "     -n: don't read from stdin\n"
-        "     -T: disable pty allocation\n"
-        "     -t: allocate a pty if on a tty (-tt: force pty allocation)\n"
-        "     -x: disable remote exit codes and stdout/stderr separation\n"
-        " emu COMMAND              run emulator console command\n"
-        "\n"
-        "app installation (see also `adb shell cmd package help`):\n"
-        " install [-lrtsdg] [--instant] PACKAGE\n"
-        "     push a single package to the device and install it\n"
-        " install-multiple [-lrtsdpg] [--instant] PACKAGE...\n"
-        "     push multiple APKs to the device for a single package and install them\n"
-        " install-multi-package [-lrtsdpg] [--instant] PACKAGE...\n"
-        "     push one or more packages to the device and install them atomically\n"
-        "     -r: replace existing application\n"
-        "     -t: allow test packages\n"
-        "     -d: allow version code downgrade (debuggable packages only)\n"
-        "     -p: partial application install (install-multiple only)\n"
-        "     -g: grant all runtime permissions\n"
-        "     --abi ABI: override platform's default ABI\n"
-        "     --instant: cause the app to be installed as an ephemeral install app\n"
-        "     --no-streaming: always push APK to device and invoke Package Manager as separate steps\n"
-        "     --streaming: force streaming APK directly into Package Manager\n"
-        "     --fastdeploy: use fast deploy\n"
-        "     --no-fastdeploy: prevent use of fast deploy\n"
-        "     --force-agent: force update of deployment agent when using fast deploy\n"
-        "     --date-check-agent: update deployment agent when local version is newer and using fast deploy\n"
-        "     --version-check-agent: update deployment agent when local version has different version code and using fast deploy\n"
-#ifndef _WIN32
-        "     --local-agent: locate agent files from local source build (instead of SDK location)\n"
-#endif
-        "     (See also `adb shell pm help` for more options.)\n"
-        //TODO--installlog <filename>
-        " uninstall [-k] PACKAGE\n"
-        "     remove this app package from the device\n"
-        "     '-k': keep the data and cache directories\n"
-        "\n"
-        "debugging:\n"
-        " bugreport [PATH]\n"
-        "     write bugreport to given PATH [default=bugreport.zip];\n"
-        "     if PATH is a directory, the bug report is saved in that directory.\n"
-        "     devices that don't support zipped bug reports output to stdout.\n"
-        " jdwp                     list pids of processes hosting a JDWP transport\n"
-        " logcat                   show device log (logcat --help for more)\n"
-        "\n"
-        "security:\n"
-        " disable-verity           disable dm-verity checking on userdebug builds\n"
-        " enable-verity            re-enable dm-verity checking on userdebug builds\n"
-        " keygen FILE\n"
-        "     generate adb public/private key; private key stored in FILE,\n"
-        "\n"
-        "scripting:\n"
-        " wait-for[-TRANSPORT]-STATE\n"
-        "     wait for device to be in the given state\n"
-        "     STATE: device, recovery, rescue, sideload, bootloader, or disconnect\n"
-        "     TRANSPORT: usb, local, or any [default=any]\n"
-        " get-state                print offline | bootloader | device\n"
-        " get-serialno             print <serial-number>\n"
-        " get-devpath              print <device-path>\n"
-        " remount [-R]\n"
-        "      remount partitions read-write. if a reboot is required, -R will\n"
-        "      will automatically reboot the device.\n"
-        " reboot [bootloader|recovery|sideload|sideload-auto-reboot]\n"
-        "     reboot the device; defaults to booting system image but\n"
-        "     supports bootloader and recovery too. sideload reboots\n"
-        "     into recovery and automatically starts sideload mode,\n"
-        "     sideload-auto-reboot is the same but reboots after sideloading.\n"
-        " sideload OTAPACKAGE      sideload the given full OTA package\n"
-        " root                     restart adbd with root permissions\n"
-        " unroot                   restart adbd without root permissions\n"
-        " usb                      restart adbd listening on USB\n"
-        " tcpip PORT               restart adbd listening on TCP on PORT\n"
-        "\n"
-        "internal debugging:\n"
-        " start-server             ensure that there is a server running\n"
-        " kill-server              kill the server if it is running\n"
-        " reconnect                kick connection from host side to force reconnect\n"
-        " reconnect device         kick connection from device side to force reconnect\n"
-        " reconnect offline        reset offline/unauthorized devices to force reconnect\n"
-        "\n"
-        "environment variables:\n"
-        " $ADB_TRACE\n"
-        "     comma-separated list of debug info to log:\n"
-        "     all,adb,sockets,packets,rwx,usb,sync,sysdeps,transport,jdwp\n"
-        " $ADB_VENDOR_KEYS         colon-separated list of keys (files or directories)\n"
-        " $ANDROID_SERIAL          serial number to connect to (see -s)\n"
-        " $ANDROID_LOG_TAGS        tags to be used by logcat (see logcat --help)\n"
-        " $ADB_LOCAL_TRANSPORT_MAX_PORT max emulator scan port (default 5585, 16 emus)\n"
-    );
-    // clang-format on
-}
-
-#if defined(_WIN32)
-
-// Implemented in sysdeps_win32.cpp.
-void stdin_raw_init();
-void stdin_raw_restore();
-
-#else
-static termios g_saved_terminal_state;
-
-static void stdin_raw_init() {
-    if (tcgetattr(STDIN_FILENO, &g_saved_terminal_state)) return;
-
-    termios tio;
-    if (tcgetattr(STDIN_FILENO, &tio)) return;
-
-    cfmakeraw(&tio);
-
-    // No timeout but request at least one character per read.
-    tio.c_cc[VTIME] = 0;
-    tio.c_cc[VMIN] = 1;
-
-    tcsetattr(STDIN_FILENO, TCSAFLUSH, &tio);
-}
-
-static void stdin_raw_restore() {
-    tcsetattr(STDIN_FILENO, TCSAFLUSH, &g_saved_terminal_state);
-}
-#endif
-
-int read_and_dump(borrowed_fd fd, bool use_shell_protocol,
-                  StandardStreamsCallbackInterface* callback) {
-    int exit_code = 0;
-    if (fd < 0) return exit_code;
-
-    std::unique_ptr<ShellProtocol> protocol;
-    int length = 0;
-
-    char raw_buffer[BUFSIZ];
-    char* buffer_ptr = raw_buffer;
-    if (use_shell_protocol) {
-        protocol = std::make_unique<ShellProtocol>(fd);
-        if (!protocol) {
-            LOG(ERROR) << "failed to allocate memory for ShellProtocol object";
-            return 1;
-        }
-        buffer_ptr = protocol->data();
-    }
-
-    while (true) {
-        if (use_shell_protocol) {
-            if (!protocol->Read()) {
-                break;
-            }
-            length = protocol->data_length();
-            switch (protocol->id()) {
-                case ShellProtocol::kIdStdout:
-                    callback->OnStdout(buffer_ptr, length);
-                    break;
-                case ShellProtocol::kIdStderr:
-                    callback->OnStderr(buffer_ptr, length);
-                    break;
-                case ShellProtocol::kIdExit:
-                    // data() returns a char* which doesn't have defined signedness.
-                    // Cast to uint8_t to prevent 255 from being sign extended to INT_MIN,
-                    // which doesn't get truncated on Windows.
-                    exit_code = static_cast<uint8_t>(protocol->data()[0]);
-                    continue;
-                default:
-                    continue;
-            }
-            length = protocol->data_length();
-        } else {
-            D("read_and_dump(): pre adb_read(fd=%d)", fd.get());
-            length = adb_read(fd, raw_buffer, sizeof(raw_buffer));
-            D("read_and_dump(): post adb_read(fd=%d): length=%d", fd.get(), length);
-            if (length <= 0) {
-                break;
-            }
-            callback->OnStdout(buffer_ptr, length);
-        }
-    }
-
-    return callback->Done(exit_code);
-}
-
-static void stdinout_raw_prologue(int inFd, int outFd, int& old_stdin_mode, int& old_stdout_mode) {
-    if (inFd == STDIN_FILENO) {
-        stdin_raw_init();
-#ifdef _WIN32
-        old_stdin_mode = _setmode(STDIN_FILENO, _O_BINARY);
-        if (old_stdin_mode == -1) {
-            PLOG(FATAL) << "could not set stdin to binary";
-        }
-#endif
-    }
-
-#ifdef _WIN32
-    if (outFd == STDOUT_FILENO) {
-        old_stdout_mode = _setmode(STDOUT_FILENO, _O_BINARY);
-        if (old_stdout_mode == -1) {
-            PLOG(FATAL) << "could not set stdout to binary";
-        }
-    }
-#endif
-}
-
-static void stdinout_raw_epilogue(int inFd, int outFd, int old_stdin_mode, int old_stdout_mode) {
-    if (inFd == STDIN_FILENO) {
-        stdin_raw_restore();
-#ifdef _WIN32
-        if (_setmode(STDIN_FILENO, old_stdin_mode) == -1) {
-            PLOG(FATAL) << "could not restore stdin mode";
-        }
-#endif
-    }
-
-#ifdef _WIN32
-    if (outFd == STDOUT_FILENO) {
-        if (_setmode(STDOUT_FILENO, old_stdout_mode) == -1) {
-            PLOG(FATAL) << "could not restore stdout mode";
-        }
-    }
-#endif
-}
-
-bool copy_to_file(int inFd, int outFd) {
-    bool result = true;
-    std::vector<char> buf(64 * 1024);
-    int len;
-    long total = 0;
-    int old_stdin_mode = -1;
-    int old_stdout_mode = -1;
-
-    D("copy_to_file(%d -> %d)", inFd, outFd);
-
-    stdinout_raw_prologue(inFd, outFd, old_stdin_mode, old_stdout_mode);
-
-    while (true) {
-        if (inFd == STDIN_FILENO) {
-            len = unix_read(inFd, buf.data(), buf.size());
-        } else {
-            len = adb_read(inFd, buf.data(), buf.size());
-        }
-        if (len == 0) {
-            D("copy_to_file() : read 0 bytes; exiting");
-            break;
-        }
-        if (len < 0) {
-            D("copy_to_file(): read failed: %s", strerror(errno));
-            result = false;
-            break;
-        }
-        if (outFd == STDOUT_FILENO) {
-            fwrite(buf.data(), 1, len, stdout);
-            fflush(stdout);
-        } else {
-            adb_write(outFd, buf.data(), len);
-        }
-        total += len;
-    }
-
-    stdinout_raw_epilogue(inFd, outFd, old_stdin_mode, old_stdout_mode);
-
-    D("copy_to_file() finished with %s after %lu bytes", result ? "success" : "failure", total);
-    return result;
-}
-
-static void send_window_size_change(int fd, std::unique_ptr<ShellProtocol>& shell) {
-    // Old devices can't handle window size changes.
-    if (shell == nullptr) return;
-
-#if defined(_WIN32)
-    struct winsize {
-        unsigned short ws_row;
-        unsigned short ws_col;
-        unsigned short ws_xpixel;
-        unsigned short ws_ypixel;
-    };
-#endif
-
-    winsize ws;
-
-#if defined(_WIN32)
-    // If stdout is redirected to a non-console, we won't be able to get the
-    // console size, but that makes sense.
-    const intptr_t intptr_handle = _get_osfhandle(STDOUT_FILENO);
-    if (intptr_handle == -1) return;
-
-    const HANDLE handle = reinterpret_cast<const HANDLE>(intptr_handle);
-
-    CONSOLE_SCREEN_BUFFER_INFO info;
-    memset(&info, 0, sizeof(info));
-    if (!GetConsoleScreenBufferInfo(handle, &info)) return;
-
-    memset(&ws, 0, sizeof(ws));
-    // The number of visible rows, excluding offscreen scroll-back rows which are in info.dwSize.Y.
-    ws.ws_row = info.srWindow.Bottom - info.srWindow.Top + 1;
-    // If the user has disabled "Wrap text output on resize", they can make the screen buffer wider
-    // than the window, in which case we should use the width of the buffer.
-    ws.ws_col = info.dwSize.X;
-#else
-    if (ioctl(fd, TIOCGWINSZ, &ws) == -1) return;
-#endif
-
-    // Send the new window size as human-readable ASCII for debugging convenience.
-    size_t l = snprintf(shell->data(), shell->data_capacity(), "%dx%d,%dx%d",
-                        ws.ws_row, ws.ws_col, ws.ws_xpixel, ws.ws_ypixel);
-    shell->Write(ShellProtocol::kIdWindowSizeChange, l + 1);
-}
-
-// Used to pass multiple values to the stdin read thread.
-struct StdinReadArgs {
-    int stdin_fd, write_fd;
-    bool raw_stdin;
-    std::unique_ptr<ShellProtocol> protocol;
-    char escape_char;
-};
-
-// Loops to read from stdin and push the data to the given FD.
-// The argument should be a pointer to a StdinReadArgs object. This function
-// will take ownership of the object and delete it when finished.
-static void stdin_read_thread_loop(void* x) {
-    std::unique_ptr<StdinReadArgs> args(reinterpret_cast<StdinReadArgs*>(x));
-
-#if !defined(_WIN32)
-    // Mask SIGTTIN in case we're in a backgrounded process.
-    sigset_t sigset;
-    sigemptyset(&sigset);
-    sigaddset(&sigset, SIGTTIN);
-    pthread_sigmask(SIG_BLOCK, &sigset, nullptr);
-#endif
-
-#if defined(_WIN32)
-    // _get_interesting_input_record_uncached() causes unix_read_interruptible()
-    // to return -1 with errno == EINTR if the window size changes.
-#else
-    // Unblock SIGWINCH for this thread, so our read(2) below will be
-    // interrupted if the window size changes.
-    sigset_t mask;
-    sigemptyset(&mask);
-    sigaddset(&mask, SIGWINCH);
-    pthread_sigmask(SIG_UNBLOCK, &mask, nullptr);
-#endif
-
-    // Set up the initial window size.
-    send_window_size_change(args->stdin_fd, args->protocol);
-
-    char raw_buffer[BUFSIZ];
-    char* buffer_ptr = raw_buffer;
-    size_t buffer_size = sizeof(raw_buffer);
-    if (args->protocol != nullptr) {
-        buffer_ptr = args->protocol->data();
-        buffer_size = args->protocol->data_capacity();
-    }
-
-    // If we need to parse escape sequences, make life easy.
-    if (args->raw_stdin && args->escape_char != '\0') {
-        buffer_size = 1;
-    }
-
-    enum EscapeState { kMidFlow, kStartOfLine, kInEscape };
-    EscapeState state = kStartOfLine;
-
-    while (true) {
-        // Use unix_read_interruptible() rather than adb_read() for stdin.
-        D("stdin_read_thread_loop(): pre unix_read_interruptible(fdi=%d,...)", args->stdin_fd);
-        int r = unix_read_interruptible(args->stdin_fd, buffer_ptr,
-                                        buffer_size);
-        if (r == -1 && errno == EINTR) {
-            send_window_size_change(args->stdin_fd, args->protocol);
-            continue;
-        }
-        D("stdin_read_thread_loop(): post unix_read_interruptible(fdi=%d,...)", args->stdin_fd);
-        if (r <= 0) {
-            // Only devices using the shell protocol know to close subprocess
-            // stdin. For older devices we want to just leave the connection
-            // open, otherwise an unpredictable amount of return data could
-            // be lost due to the FD closing before all data has been received.
-            if (args->protocol) {
-                args->protocol->Write(ShellProtocol::kIdCloseStdin, 0);
-            }
-            break;
-        }
-        // If we made stdin raw, check input for escape sequences. In
-        // this situation signals like Ctrl+C are sent remotely rather than
-        // interpreted locally so this provides an emergency out if the remote
-        // process starts ignoring the signal. SSH also does this, see the
-        // "escape characters" section on the ssh man page for more info.
-        if (args->raw_stdin && args->escape_char != '\0') {
-            char ch = buffer_ptr[0];
-            if (ch == args->escape_char) {
-                if (state == kStartOfLine) {
-                    state = kInEscape;
-                    // Swallow the escape character.
-                    continue;
-                } else {
-                    state = kMidFlow;
-                }
-            } else {
-                if (state == kInEscape) {
-                    if (ch == '.') {
-                        fprintf(stderr,"\r\n[ disconnected ]\r\n");
-                        stdin_raw_restore();
-                        exit(0);
-                    } else {
-                        // We swallowed an escape character that wasn't part of
-                        // a valid escape sequence; time to cough it up.
-                        buffer_ptr[0] = args->escape_char;
-                        buffer_ptr[1] = ch;
-                        ++r;
-                    }
-                }
-                state = (ch == '\n' || ch == '\r') ? kStartOfLine : kMidFlow;
-            }
-        }
-        if (args->protocol) {
-            if (!args->protocol->Write(ShellProtocol::kIdStdin, r)) {
-                break;
-            }
-        } else {
-            if (!WriteFdExactly(args->write_fd, buffer_ptr, r)) {
-                break;
-            }
-        }
-    }
-}
-
-// Returns a shell service string with the indicated arguments and command.
-static std::string ShellServiceString(bool use_shell_protocol,
-                                      const std::string& type_arg,
-                                      const std::string& command) {
-    std::vector<std::string> args;
-    if (use_shell_protocol) {
-        args.push_back(kShellServiceArgShellProtocol);
-
-        const char* terminal_type = getenv("TERM");
-        if (terminal_type != nullptr) {
-            args.push_back(std::string("TERM=") + terminal_type);
-        }
-    }
-    if (!type_arg.empty()) {
-        args.push_back(type_arg);
-    }
-
-    // Shell service string can look like: shell[,arg1,arg2,...]:[command].
-    return android::base::StringPrintf("shell%s%s:%s",
-                                       args.empty() ? "" : ",",
-                                       android::base::Join(args, ',').c_str(),
-                                       command.c_str());
-}
-
-// Connects to a shell on the device and read/writes data.
-//
-// Note: currently this function doesn't properly clean up resources; the
-// FD connected to the adb server is never closed and the stdin read thread
-// may never exit.
-//
-// On success returns the remote exit code if |use_shell_protocol| is true,
-// 0 otherwise. On failure returns 1.
-static int RemoteShell(bool use_shell_protocol, const std::string& type_arg, char escape_char,
-                       bool empty_command, const std::string& service_string) {
-    // Old devices can't handle a service string that's longer than MAX_PAYLOAD_V1.
-    // Use |use_shell_protocol| to determine whether to allow a command longer than that.
-    if (service_string.size() > MAX_PAYLOAD_V1 && !use_shell_protocol) {
-        fprintf(stderr, "error: shell command too long\n");
-        return 1;
-    }
-
-    // Make local stdin raw if the device allocates a PTY, which happens if:
-    //   1. We are explicitly asking for a PTY shell, or
-    //   2. We don't specify shell type and are starting an interactive session.
-    bool raw_stdin = (type_arg == kShellServiceArgPty || (type_arg.empty() && empty_command));
-
-    std::string error;
-    int fd = adb_connect(service_string, &error);
-    if (fd < 0) {
-        fprintf(stderr,"error: %s\n", error.c_str());
-        return 1;
-    }
-
-    StdinReadArgs* args = new StdinReadArgs;
-    if (!args) {
-        LOG(ERROR) << "couldn't allocate StdinReadArgs object";
-        return 1;
-    }
-    args->stdin_fd = STDIN_FILENO;
-    args->write_fd = fd;
-    args->raw_stdin = raw_stdin;
-    args->escape_char = escape_char;
-    if (use_shell_protocol) {
-        args->protocol = std::make_unique<ShellProtocol>(args->write_fd);
-    }
-
-    if (raw_stdin) stdin_raw_init();
-
-#if !defined(_WIN32)
-    // Ensure our process is notified if the local window size changes.
-    // We use sigaction(2) to ensure that the SA_RESTART flag is not set,
-    // because the whole reason we're sending signals is to unblock the read(2)!
-    // That also means we don't need to do anything in the signal handler:
-    // the side effect of delivering the signal is all we need.
-    struct sigaction sa;
-    memset(&sa, 0, sizeof(sa));
-    sa.sa_handler = [](int) {};
-    sa.sa_flags = 0;
-    sigaction(SIGWINCH, &sa, nullptr);
-
-    // Now block SIGWINCH in this thread (the main thread) and all threads spawned
-    // from it. The stdin read thread will unblock this signal to ensure that it's
-    // the thread that receives the signal.
-    sigset_t mask;
-    sigemptyset(&mask);
-    sigaddset(&mask, SIGWINCH);
-    pthread_sigmask(SIG_BLOCK, &mask, nullptr);
-#endif
-
-    // TODO: combine read_and_dump with stdin_read_thread to make life simpler?
-    std::thread(stdin_read_thread_loop, args).detach();
-    int exit_code = read_and_dump(fd, use_shell_protocol);
-
-    // TODO: properly exit stdin_read_thread_loop and close |fd|.
-
-    // TODO: we should probably install signal handlers for this.
-    // TODO: can we use atexit? even on Windows?
-    if (raw_stdin) stdin_raw_restore();
-
-    return exit_code;
-}
-
-static int adb_shell(int argc, const char** argv) {
-    FeatureSet features;
-    std::string error_message;
-    if (!adb_get_feature_set(&features, &error_message)) {
-        fprintf(stderr, "error: %s\n", error_message.c_str());
-        return 1;
-    }
-
-    enum PtyAllocationMode { kPtyAuto, kPtyNo, kPtyYes, kPtyDefinitely };
-
-    // Defaults.
-    char escape_char = '~'; // -e
-    bool use_shell_protocol = CanUseFeature(features, kFeatureShell2); // -x
-    PtyAllocationMode tty = use_shell_protocol ? kPtyAuto : kPtyDefinitely; // -t/-T
-
-    // Parse shell-specific command-line options.
-    argv[0] = "adb shell"; // So getopt(3) error messages start "adb shell".
-#ifdef _WIN32
-    // fixes "adb shell -l" crash on Windows, b/37284906
-    __argv = const_cast<char**>(argv);
-#endif
-    optind = 1; // argv[0] is always "shell", so set `optind` appropriately.
-    int opt;
-    while ((opt = getopt(argc, const_cast<char**>(argv), "+e:ntTx")) != -1) {
-        switch (opt) {
-            case 'e':
-                if (!(strlen(optarg) == 1 || strcmp(optarg, "none") == 0)) {
-                    error_exit("-e requires a single-character argument or 'none'");
-                }
-                escape_char = (strcmp(optarg, "none") == 0) ? 0 : optarg[0];
-                break;
-            case 'n':
-                close_stdin();
-                break;
-            case 'x':
-                // This option basically asks for historical behavior, so set options that
-                // correspond to the historical defaults. This is slightly weird in that -Tx
-                // is fine (because we'll undo the -T) but -xT isn't, but that does seem to
-                // be our least worst choice...
-                use_shell_protocol = false;
-                tty = kPtyDefinitely;
-                escape_char = '~';
-                break;
-            case 't':
-                // Like ssh, -t arguments are cumulative so that multiple -t's
-                // are needed to force a PTY.
-                tty = (tty >= kPtyYes) ? kPtyDefinitely : kPtyYes;
-                break;
-            case 'T':
-                tty = kPtyNo;
-                break;
-            default:
-                // getopt(3) already printed an error message for us.
-                return 1;
-        }
-    }
-
-    bool is_interactive = (optind == argc);
-
-    std::string shell_type_arg = kShellServiceArgPty;
-    if (tty == kPtyNo) {
-        shell_type_arg = kShellServiceArgRaw;
-    } else if (tty == kPtyAuto) {
-        // If stdin isn't a TTY, default to a raw shell; this lets
-        // things like `adb shell < my_script.sh` work as expected.
-        // Non-interactive shells should also not have a pty.
-        if (!unix_isatty(STDIN_FILENO) || !is_interactive) {
-            shell_type_arg = kShellServiceArgRaw;
-        }
-    } else if (tty == kPtyYes) {
-        // A single -t arg isn't enough to override implicit -T.
-        if (!unix_isatty(STDIN_FILENO)) {
-            fprintf(stderr,
-                    "Remote PTY will not be allocated because stdin is not a terminal.\n"
-                    "Use multiple -t options to force remote PTY allocation.\n");
-            shell_type_arg = kShellServiceArgRaw;
-        }
-    }
-
-    D("shell -e 0x%x t=%d use_shell_protocol=%s shell_type_arg=%s\n",
-      escape_char, tty,
-      use_shell_protocol ? "true" : "false",
-      (shell_type_arg == kShellServiceArgPty) ? "pty" : "raw");
-
-    // Raw mode is only supported when talking to a new device *and* using the shell protocol.
-    if (!use_shell_protocol) {
-        if (shell_type_arg != kShellServiceArgPty) {
-            fprintf(stderr, "error: %s only supports allocating a pty\n",
-                    !CanUseFeature(features, kFeatureShell2) ? "device" : "-x");
-            return 1;
-        } else {
-            // If we're not using the shell protocol, the type argument must be empty.
-            shell_type_arg = "";
-        }
-    }
-
-    std::string command;
-    if (optind < argc) {
-        // We don't escape here, just like ssh(1). http://b/20564385.
-        command = android::base::Join(std::vector<const char*>(argv + optind, argv + argc), ' ');
-    }
-
-    std::string service_string = ShellServiceString(use_shell_protocol, shell_type_arg, command);
-    return RemoteShell(use_shell_protocol, shell_type_arg, escape_char, command.empty(),
-                       service_string);
-}
-
-static int adb_abb(int argc, const char** argv) {
-    FeatureSet features;
-    std::string error_message;
-    if (!adb_get_feature_set(&features, &error_message)) {
-        fprintf(stderr, "error: %s\n", error_message.c_str());
-        return 1;
-    }
-
-    if (!CanUseFeature(features, kFeatureAbb)) {
-        error_exit("abb is not supported by the device");
-    }
-
-    optind = 1;  // argv[0] is always "abb", so set `optind` appropriately.
-
-    // Defaults.
-    constexpr char escape_char = '~';  // -e
-    constexpr bool use_shell_protocol = true;
-    constexpr auto shell_type_arg = kShellServiceArgRaw;
-    constexpr bool empty_command = false;
-
-    std::vector<const char*> args(argv + optind, argv + argc);
-    std::string service_string = "abb:" + android::base::Join(args, ABB_ARG_DELIMETER);
-
-    D("abb -e 0x%x [%*.s]\n", escape_char, static_cast<int>(service_string.size()),
-      service_string.data());
-
-    return RemoteShell(use_shell_protocol, shell_type_arg, escape_char, empty_command,
-                       service_string);
-}
-
-static int adb_shell_noinput(int argc, const char** argv) {
-#if !defined(_WIN32)
-    unique_fd fd(adb_open("/dev/null", O_RDONLY));
-    CHECK_NE(STDIN_FILENO, fd.get());
-    dup2(fd.get(), STDIN_FILENO);
-#endif
-    return adb_shell(argc, argv);
-}
-
-static int adb_sideload_legacy(const char* filename, int in_fd, int size) {
-    std::string error;
-    unique_fd out_fd(adb_connect(android::base::StringPrintf("sideload:%d", size), &error));
-    if (out_fd < 0) {
-        fprintf(stderr, "adb: pre-KitKat sideload connection failed: %s\n", error.c_str());
-        return -1;
-    }
-
-    int opt = CHUNK_SIZE;
-    opt = adb_setsockopt(out_fd, SOL_SOCKET, SO_SNDBUF, &opt, sizeof(opt));
-
-    char buf[CHUNK_SIZE];
-    int total = size;
-    while (size > 0) {
-        unsigned xfer = (size > CHUNK_SIZE) ? CHUNK_SIZE : size;
-        if (!ReadFdExactly(in_fd, buf, xfer)) {
-            fprintf(stderr, "adb: failed to read data from %s: %s\n", filename, strerror(errno));
-            return -1;
-        }
-        if (!WriteFdExactly(out_fd, buf, xfer)) {
-            std::string error;
-            adb_status(out_fd, &error);
-            fprintf(stderr, "adb: failed to write data: %s\n", error.c_str());
-            return -1;
-        }
-        size -= xfer;
-        printf("sending: '%s' %4d%%    \r", filename, (int)(100LL - ((100LL * size) / (total))));
-        fflush(stdout);
-    }
-    printf("\n");
-
-    if (!adb_status(out_fd, &error)) {
-        fprintf(stderr, "adb: error response: %s\n", error.c_str());
-        return -1;
-    }
-
-    return 0;
-}
-
-#define SIDELOAD_HOST_BLOCK_SIZE (CHUNK_SIZE)
-
-// Connects to the sideload / rescue service on the device (served by minadbd) and sends over the
-// data in an OTA package.
-//
-// It uses a simple protocol as follows.
-//
-// - The connect message includes the total number of bytes in the file and a block size chosen by
-//   us.
-//
-// - The other side sends the desired block number as eight decimal digits (e.g. "00000023" for
-//   block 23). Blocks are numbered from zero.
-//
-// - We send back the data of the requested block. The last block is likely to be partial; when the
-//   last block is requested we only send the part of the block that exists, it's not padded up to
-//   the block size.
-//
-// - When the other side sends "DONEDONE" or "FAILFAIL" instead of a block number, we have done all
-//   the data transfer.
-//
-static int adb_sideload_install(const char* filename, bool rescue_mode) {
-    // TODO: use a LinePrinter instead...
-    struct stat sb;
-    if (stat(filename, &sb) == -1) {
-        fprintf(stderr, "adb: failed to stat file %s: %s\n", filename, strerror(errno));
-        return -1;
-    }
-    unique_fd package_fd(adb_open(filename, O_RDONLY));
-    if (package_fd == -1) {
-        fprintf(stderr, "adb: failed to open file %s: %s\n", filename, strerror(errno));
-        return -1;
-    }
-
-    std::string service = android::base::StringPrintf(
-            "%s:%" PRId64 ":%d", rescue_mode ? "rescue-install" : "sideload-host",
-            static_cast<int64_t>(sb.st_size), SIDELOAD_HOST_BLOCK_SIZE);
-    std::string error;
-    unique_fd device_fd(adb_connect(service, &error));
-    if (device_fd < 0) {
-        fprintf(stderr, "adb: sideload connection failed: %s\n", error.c_str());
-
-        if (rescue_mode) {
-            return -1;
-        }
-
-        // If this is a small enough package, maybe this is an older device that doesn't
-        // support sideload-host. Try falling back to the older (<= K) sideload method.
-        if (sb.st_size > INT_MAX) {
-            return -1;
-        }
-        fprintf(stderr, "adb: trying pre-KitKat sideload method...\n");
-        return adb_sideload_legacy(filename, package_fd.get(), static_cast<int>(sb.st_size));
-    }
-
-    int opt = SIDELOAD_HOST_BLOCK_SIZE;
-    adb_setsockopt(device_fd, SOL_SOCKET, SO_SNDBUF, &opt, sizeof(opt));
-
-    char buf[SIDELOAD_HOST_BLOCK_SIZE];
-
-    int64_t xfer = 0;
-    int last_percent = -1;
-    while (true) {
-        if (!ReadFdExactly(device_fd, buf, 8)) {
-            fprintf(stderr, "adb: failed to read command: %s\n", strerror(errno));
-            return -1;
-        }
-        buf[8] = '\0';
-
-        if (strcmp(kMinadbdServicesExitSuccess, buf) == 0 ||
-            strcmp(kMinadbdServicesExitFailure, buf) == 0) {
-            printf("\rTotal xfer: %.2fx%*s\n",
-                   static_cast<double>(xfer) / (sb.st_size ? sb.st_size : 1),
-                   static_cast<int>(strlen(filename) + 10), "");
-            if (strcmp(kMinadbdServicesExitFailure, buf) == 0) {
-                return 1;
-            }
-            return 0;
-        }
-
-        int64_t block = strtoll(buf, nullptr, 10);
-        int64_t offset = block * SIDELOAD_HOST_BLOCK_SIZE;
-        if (offset >= static_cast<int64_t>(sb.st_size)) {
-            fprintf(stderr,
-                    "adb: failed to read block %" PRId64 " at offset %" PRId64 ", past end %" PRId64
-                    "\n",
-                    block, offset, static_cast<int64_t>(sb.st_size));
-            return -1;
-        }
-
-        size_t to_write = SIDELOAD_HOST_BLOCK_SIZE;
-        if ((offset + SIDELOAD_HOST_BLOCK_SIZE) > static_cast<int64_t>(sb.st_size)) {
-            to_write = sb.st_size - offset;
-        }
-
-        if (adb_lseek(package_fd, offset, SEEK_SET) != offset) {
-            fprintf(stderr, "adb: failed to seek to package block: %s\n", strerror(errno));
-            return -1;
-        }
-        if (!ReadFdExactly(package_fd, buf, to_write)) {
-            fprintf(stderr, "adb: failed to read package block: %s\n", strerror(errno));
-            return -1;
-        }
-
-        if (!WriteFdExactly(device_fd, buf, to_write)) {
-            adb_status(device_fd, &error);
-            fprintf(stderr, "adb: failed to write data '%s' *\n", error.c_str());
-            return -1;
-        }
-        xfer += to_write;
-
-        // For normal OTA packages, we expect to transfer every byte
-        // twice, plus a bit of overhead (one read during
-        // verification, one read of each byte for installation, plus
-        // extra access to things like the zip central directory).
-        // This estimate of the completion becomes 100% when we've
-        // transferred ~2.13 (=100/47) times the package size.
-        int percent = static_cast<int>(xfer * 47LL / (sb.st_size ? sb.st_size : 1));
-        if (percent != last_percent) {
-            printf("\rserving: '%s'  (~%d%%)    ", filename, percent);
-            fflush(stdout);
-            last_percent = percent;
-        }
-    }
-}
-
-static int adb_wipe_devices() {
-    auto wipe_devices_message_size = strlen(kMinadbdServicesExitSuccess);
-    std::string error;
-    unique_fd fd(adb_connect(
-            android::base::StringPrintf("rescue-wipe:userdata:%zu", wipe_devices_message_size),
-            &error));
-    if (fd < 0) {
-        fprintf(stderr, "adb: wipe device connection failed: %s\n", error.c_str());
-        return 1;
-    }
-
-    std::string message(wipe_devices_message_size, '\0');
-    if (!ReadFdExactly(fd, message.data(), wipe_devices_message_size)) {
-        fprintf(stderr, "adb: failed to read wipe result: %s\n", strerror(errno));
-        return 1;
-    }
-
-    if (message == kMinadbdServicesExitSuccess) {
-        return 0;
-    }
-
-    if (message != kMinadbdServicesExitFailure) {
-        fprintf(stderr, "adb: got unexpected message from rescue wipe %s\n", message.c_str());
-    }
-    return 1;
-}
-
-/**
- * Run ppp in "notty" mode against a resource listed as the first parameter
- * eg:
- *
- * ppp dev:/dev/omap_csmi_tty0 <ppp options>
- *
- */
-static int ppp(int argc, const char** argv) {
-#if defined(_WIN32)
-    error_exit("adb %s not implemented on Win32", argv[0]);
-    __builtin_unreachable();
-#else
-    if (argc < 2) error_exit("usage: adb %s <adb service name> [ppp opts]", argv[0]);
-
-    const char* adb_service_name = argv[1];
-    std::string error_message;
-    int fd = adb_connect(adb_service_name, &error_message);
-    if (fd < 0) {
-        error_exit("could not open adb service %s: %s", adb_service_name, error_message.c_str());
-    }
-
-    pid_t pid = fork();
-    if (pid == -1) {
-        perror_exit("fork failed");
-    }
-
-    if (pid == 0) {
-        // child side
-        int i;
-
-        // copy args
-        const char** ppp_args = (const char**)alloca(sizeof(char*) * argc + 1);
-        ppp_args[0] = "pppd";
-        for (i = 2 ; i < argc ; i++) {
-            //argv[2] and beyond become ppp_args[1] and beyond
-            ppp_args[i - 1] = argv[i];
-        }
-        ppp_args[i-1] = nullptr;
-
-        dup2(fd, STDIN_FILENO);
-        dup2(fd, STDOUT_FILENO);
-        adb_close(STDERR_FILENO);
-        adb_close(fd);
-
-        execvp("pppd", (char* const*)ppp_args);
-        perror_exit("exec pppd failed");
-    }
-
-    // parent side
-    adb_close(fd);
-    return 0;
-#endif /* !defined(_WIN32) */
-}
-
-static bool wait_for_device(const char* service,
-                            std::optional<std::chrono::milliseconds> timeout = std::nullopt) {
-    std::vector<std::string> components = android::base::Split(service, "-");
-    if (components.size() < 3 || components.size() > 4) {
-        fprintf(stderr, "adb: couldn't parse 'wait-for' command: %s\n", service);
-        return false;
-    }
-
-    TransportType t;
-    adb_get_transport(&t, nullptr, nullptr);
-
-    // Was the caller vague about what they'd like us to wait for?
-    // If so, check they weren't more specific in their choice of transport type.
-    if (components.size() == 3) {
-        auto it = components.begin() + 2;
-        if (t == kTransportUsb) {
-            components.insert(it, "usb");
-        } else if (t == kTransportLocal) {
-            components.insert(it, "local");
-        } else {
-            components.insert(it, "any");
-        }
-    } else if (components[2] != "any" && components[2] != "local" && components[2] != "usb") {
-        fprintf(stderr, "adb: unknown type %s; expected 'any', 'local', or 'usb'\n",
-                components[2].c_str());
-        return false;
-    }
-
-    if (components[3] != "any" && components[3] != "bootloader" && components[3] != "device" &&
-        components[3] != "recovery" && components[3] != "rescue" && components[3] != "sideload" &&
-        components[3] != "disconnect") {
-        fprintf(stderr,
-                "adb: unknown state %s; "
-                "expected 'any', 'bootloader', 'device', 'recovery', 'rescue', 'sideload', or "
-                "'disconnect'\n",
-                components[3].c_str());
-        return false;
-    }
-
-    std::string cmd = format_host_command(android::base::Join(components, "-").c_str());
-    if (timeout) {
-        std::thread([timeout]() {
-            std::this_thread::sleep_for(*timeout);
-            fprintf(stderr, "timeout expired while waiting for device\n");
-            _exit(1);
-        }).detach();
-    }
-    return adb_command(cmd);
-}
-
-static bool adb_root(const char* command) {
-    std::string error;
-
-    TransportId transport_id;
-    unique_fd fd(adb_connect(&transport_id, android::base::StringPrintf("%s:", command), &error));
-    if (fd < 0) {
-        fprintf(stderr, "adb: unable to connect for %s: %s\n", command, error.c_str());
-        return false;
-    }
-
-    // Figure out whether we actually did anything.
-    char buf[256];
-    char* cur = buf;
-    ssize_t bytes_left = sizeof(buf);
-    while (bytes_left > 0) {
-        ssize_t bytes_read = adb_read(fd, cur, bytes_left);
-        if (bytes_read == 0) {
-            break;
-        } else if (bytes_read < 0) {
-            fprintf(stderr, "adb: error while reading for %s: %s\n", command, strerror(errno));
-            return false;
-        }
-        cur += bytes_read;
-        bytes_left -= bytes_read;
-    }
-
-    if (bytes_left == 0) {
-        fprintf(stderr, "adb: unexpected output length for %s\n", command);
-        return false;
-    }
-
-    fwrite(buf, 1, sizeof(buf) - bytes_left, stdout);
-    fflush(stdout);
-    if (cur != buf && strstr(buf, "restarting") == nullptr) {
-        return true;
-    }
-
-    // Wait for the device to go away.
-    TransportType previous_type;
-    const char* previous_serial;
-    TransportId previous_id;
-    adb_get_transport(&previous_type, &previous_serial, &previous_id);
-
-    adb_set_transport(kTransportAny, nullptr, transport_id);
-    wait_for_device("wait-for-disconnect");
-
-    // Wait for the device to come back.
-    // If we were using a specific transport ID, there's nothing we can wait for.
-    if (previous_id == 0) {
-        adb_set_transport(previous_type, previous_serial, 0);
-        wait_for_device("wait-for-device", 6000ms);
-    }
-
-    return true;
-}
-
-int send_shell_command(const std::string& command, bool disable_shell_protocol,
-                       StandardStreamsCallbackInterface* callback) {
-    unique_fd fd;
-    bool use_shell_protocol = false;
-
-    while (true) {
-        bool attempt_connection = true;
-
-        // Use shell protocol if it's supported and the caller doesn't explicitly
-        // disable it.
-        if (!disable_shell_protocol) {
-            FeatureSet features;
-            std::string error;
-            if (adb_get_feature_set(&features, &error)) {
-                use_shell_protocol = CanUseFeature(features, kFeatureShell2);
-            } else {
-                // Device was unreachable.
-                attempt_connection = false;
-            }
-        }
-
-        if (attempt_connection) {
-            std::string error;
-            std::string service_string = ShellServiceString(use_shell_protocol, "", command);
-
-            fd.reset(adb_connect(service_string, &error));
-            if (fd >= 0) {
-                break;
-            }
-        }
-
-        fprintf(stderr, "- waiting for device -\n");
-        if (!wait_for_device("wait-for-device")) {
-            return 1;
-        }
-    }
-
-    return read_and_dump(fd.get(), use_shell_protocol, callback);
-}
-
-static int logcat(int argc, const char** argv) {
-    char* log_tags = getenv("ANDROID_LOG_TAGS");
-    std::string quoted = escape_arg(log_tags == nullptr ? "" : log_tags);
-
-    std::string cmd = "export ANDROID_LOG_TAGS=\"" + quoted + "\"; exec logcat";
-
-    if (!strcmp(argv[0], "longcat")) {
-        cmd += " -v long";
-    }
-
-    --argc;
-    ++argv;
-    while (argc-- > 0) {
-        cmd += " " + escape_arg(*argv++);
-    }
-
-    return send_shell_command(cmd);
-}
-
-static void write_zeros(int bytes, borrowed_fd fd) {
-    int old_stdin_mode = -1;
-    int old_stdout_mode = -1;
-    std::vector<char> buf(bytes);
-
-    D("write_zeros(%d) -> %d", bytes, fd.get());
-
-    stdinout_raw_prologue(-1, fd.get(), old_stdin_mode, old_stdout_mode);
-
-    if (fd == STDOUT_FILENO) {
-        fwrite(buf.data(), 1, bytes, stdout);
-        fflush(stdout);
-    } else {
-        adb_write(fd, buf.data(), bytes);
-    }
-
-    stdinout_raw_prologue(-1, fd.get(), old_stdin_mode, old_stdout_mode);
-
-    D("write_zeros() finished");
-}
-
-static int backup(int argc, const char** argv) {
-    fprintf(stdout, "WARNING: adb backup is deprecated and may be removed in a future release\n");
-
-    const char* filename = "backup.ab";
-
-    /* find, extract, and use any -f argument */
-    for (int i = 1; i < argc; i++) {
-        if (!strcmp("-f", argv[i])) {
-            if (i == argc - 1) error_exit("backup -f passed with no filename");
-            filename = argv[i+1];
-            for (int j = i+2; j <= argc; ) {
-                argv[i++] = argv[j++];
-            }
-            argc -= 2;
-            argv[argc] = nullptr;
-        }
-    }
-
-    // Bare "adb backup" or "adb backup -f filename" are not valid invocations ---
-    // a list of packages is required.
-    if (argc < 2) error_exit("backup either needs a list of packages or -all/-shared");
-
-    adb_unlink(filename);
-    unique_fd outFd(adb_creat(filename, 0640));
-    if (outFd < 0) {
-        fprintf(stderr, "adb: backup unable to create file '%s': %s\n", filename, strerror(errno));
-        return EXIT_FAILURE;
-    }
-
-    std::string cmd = "backup:";
-    --argc;
-    ++argv;
-    while (argc-- > 0) {
-        cmd += " " + escape_arg(*argv++);
-    }
-
-    D("backup. filename=%s cmd=%s", filename, cmd.c_str());
-    std::string error;
-    unique_fd fd(adb_connect(cmd, &error));
-    if (fd < 0) {
-        fprintf(stderr, "adb: unable to connect for backup: %s\n", error.c_str());
-        return EXIT_FAILURE;
-    }
-
-    fprintf(stdout, "Now unlock your device and confirm the backup operation...\n");
-    fflush(stdout);
-
-    copy_to_file(fd.get(), outFd.get());
-    return EXIT_SUCCESS;
-}
-
-static int restore(int argc, const char** argv) {
-    fprintf(stdout, "WARNING: adb restore is deprecated and may be removed in a future release\n");
-
-    if (argc != 2) error_exit("restore requires an argument");
-
-    const char* filename = argv[1];
-    unique_fd tarFd(adb_open(filename, O_RDONLY));
-    if (tarFd < 0) {
-        fprintf(stderr, "adb: unable to open file %s: %s\n", filename, strerror(errno));
-        return -1;
-    }
-
-    std::string error;
-    unique_fd fd(adb_connect("restore:", &error));
-    if (fd < 0) {
-        fprintf(stderr, "adb: unable to connect for restore: %s\n", error.c_str());
-        return -1;
-    }
-
-    fprintf(stdout, "Now unlock your device and confirm the restore operation.\n");
-    fflush(stdout);
-
-    copy_to_file(tarFd.get(), fd.get());
-
-    // Provide an in-band EOD marker in case the archive file is malformed
-    write_zeros(512 * 2, fd);
-
-    // Wait until the other side finishes, or it'll get sent SIGHUP.
-    copy_to_file(fd.get(), STDOUT_FILENO);
-    return 0;
-}
-
-static void parse_push_pull_args(const char** arg, int narg, std::vector<const char*>* srcs,
-                                 const char** dst, bool* copy_attrs, bool* sync, bool* compressed) {
-    *copy_attrs = false;
-    const char* adb_compression = getenv("ADB_COMPRESSION");
-    if (adb_compression && strcmp(adb_compression, "0") == 0) {
-        *compressed = false;
-    }
-
-    srcs->clear();
-    bool ignore_flags = false;
-    while (narg > 0) {
-        if (ignore_flags || *arg[0] != '-') {
-            srcs->push_back(*arg);
-        } else {
-            if (!strcmp(*arg, "-p")) {
-                // Silently ignore for backwards compatibility.
-            } else if (!strcmp(*arg, "-a")) {
-                *copy_attrs = true;
-            } else if (!strcmp(*arg, "-z")) {
-                if (compressed != nullptr) {
-                    *compressed = true;
-                }
-            } else if (!strcmp(*arg, "-Z")) {
-                if (compressed != nullptr) {
-                    *compressed = false;
-                }
-            } else if (!strcmp(*arg, "--sync")) {
-                if (sync != nullptr) {
-                    *sync = true;
-                }
-            } else if (!strcmp(*arg, "--")) {
-                ignore_flags = true;
-            } else {
-                error_exit("unrecognized option '%s'", *arg);
-            }
-        }
-        ++arg;
-        --narg;
-    }
-
-    if (srcs->size() > 1) {
-        *dst = srcs->back();
-        srcs->pop_back();
-    }
-}
-
-static int adb_connect_command(const std::string& command, TransportId* transport = nullptr) {
-    std::string error;
-    unique_fd fd(adb_connect(transport, command, &error));
-    if (fd < 0) {
-        fprintf(stderr, "error: %s\n", error.c_str());
-        return 1;
-    }
-    read_and_dump(fd);
-    return 0;
-}
-
-static int adb_connect_command_bidirectional(const std::string& command) {
-    std::string error;
-    unique_fd fd(adb_connect(command, &error));
-    if (fd < 0) {
-        fprintf(stderr, "error: %s\n", error.c_str());
-        return 1;
-    }
-
-    static constexpr auto forward = [](int src, int sink, bool exit_on_end) {
-        char buf[4096];
-        while (true) {
-            int rc = adb_read(src, buf, sizeof(buf));
-            if (rc == 0) {
-                if (exit_on_end) {
-                    exit(0);
-                } else {
-                    adb_shutdown(sink, SHUT_WR);
-                }
-                return;
-            } else if (rc < 0) {
-                perror_exit("read failed");
-            }
-            if (!WriteFdExactly(sink, buf, rc)) {
-                perror_exit("write failed");
-            }
-        }
-    };
-
-    std::thread read(forward, fd.get(), STDOUT_FILENO, true);
-    std::thread write(forward, STDIN_FILENO, fd.get(), false);
-    read.join();
-    write.join();
-    return 0;
-}
-
-static int adb_query_command(const std::string& command) {
-    std::string result;
-    std::string error;
-    if (!adb_query(command, &result, &error)) {
-        fprintf(stderr, "error: %s\n", error.c_str());
-        return 1;
-    }
-    printf("%s\n", result.c_str());
-    return 0;
-}
-
-// Disallow stdin, stdout, and stderr.
-static bool _is_valid_ack_reply_fd(const int ack_reply_fd) {
-#ifdef _WIN32
-    const HANDLE ack_reply_handle = cast_int_to_handle(ack_reply_fd);
-    return (GetStdHandle(STD_INPUT_HANDLE) != ack_reply_handle) &&
-           (GetStdHandle(STD_OUTPUT_HANDLE) != ack_reply_handle) &&
-           (GetStdHandle(STD_ERROR_HANDLE) != ack_reply_handle);
-#else
-    return ack_reply_fd > 2;
-#endif
-}
-
-static bool _is_valid_os_fd(int fd) {
-    // Disallow invalid FDs and stdin/out/err as well.
-    if (fd < 3) {
-        return false;
-    }
-#ifdef _WIN32
-    auto handle = (HANDLE)fd;
-    DWORD info = 0;
-    if (GetHandleInformation(handle, &info) == 0) {
-        return false;
-    }
-#else
-    int flags = fcntl(fd, F_GETFD);
-    if (flags == -1) {
-        return false;
-    }
-#endif
-    return true;
-}
-
-int adb_commandline(int argc, const char** argv) {
-    bool no_daemon = false;
-    bool is_daemon = false;
-    bool is_server = false;
-    int r;
-    TransportType transport_type = kTransportAny;
-    int ack_reply_fd = -1;
-
-#if !defined(_WIN32)
-    // We'd rather have EPIPE than SIGPIPE.
-    signal(SIGPIPE, SIG_IGN);
-#endif
-
-    const char* server_host_str = nullptr;
-    const char* server_port_str = nullptr;
-    const char* server_socket_str = nullptr;
-
-    // We need to check for -d and -e before we look at $ANDROID_SERIAL.
-    const char* serial = nullptr;
-    TransportId transport_id = 0;
-
-    while (argc > 0) {
-        if (!strcmp(argv[0], "server")) {
-            is_server = true;
-        } else if (!strcmp(argv[0], "nodaemon")) {
-            no_daemon = true;
-        } else if (!strcmp(argv[0], "fork-server")) {
-            /* this is a special flag used only when the ADB client launches the ADB Server */
-            is_daemon = true;
-        } else if (!strcmp(argv[0], "--reply-fd")) {
-            if (argc < 2) error_exit("--reply-fd requires an argument");
-            const char* reply_fd_str = argv[1];
-            argc--;
-            argv++;
-            ack_reply_fd = strtol(reply_fd_str, nullptr, 10);
-            if (!_is_valid_ack_reply_fd(ack_reply_fd)) {
-                fprintf(stderr, "adb: invalid reply fd \"%s\"\n", reply_fd_str);
-                return 1;
-            }
-        } else if (!strncmp(argv[0], "-s", 2)) {
-            if (isdigit(argv[0][2])) {
-                serial = argv[0] + 2;
-            } else {
-                if (argc < 2 || argv[0][2] != '\0') error_exit("-s requires an argument");
-                serial = argv[1];
-                argc--;
-                argv++;
-            }
-        } else if (!strncmp(argv[0], "-t", 2)) {
-            const char* id;
-            if (isdigit(argv[0][2])) {
-                id = argv[0] + 2;
-            } else {
-                id = argv[1];
-                argc--;
-                argv++;
-            }
-            transport_id = strtoll(id, const_cast<char**>(&id), 10);
-            if (*id != '\0') {
-                error_exit("invalid transport id");
-            }
-        } else if (!strcmp(argv[0], "-d")) {
-            transport_type = kTransportUsb;
-        } else if (!strcmp(argv[0], "-e")) {
-            transport_type = kTransportLocal;
-        } else if (!strcmp(argv[0], "-a")) {
-            gListenAll = 1;
-        } else if (!strncmp(argv[0], "-H", 2)) {
-            if (argv[0][2] == '\0') {
-                if (argc < 2) error_exit("-H requires an argument");
-                server_host_str = argv[1];
-                argc--;
-                argv++;
-            } else {
-                server_host_str = argv[0] + 2;
-            }
-        } else if (!strncmp(argv[0], "-P", 2)) {
-            if (argv[0][2] == '\0') {
-                if (argc < 2) error_exit("-P requires an argument");
-                server_port_str = argv[1];
-                argc--;
-                argv++;
-            } else {
-                server_port_str = argv[0] + 2;
-            }
-        } else if (!strcmp(argv[0], "-L")) {
-            if (argc < 2) error_exit("-L requires an argument");
-            server_socket_str = argv[1];
-            argc--;
-            argv++;
-        } else {
-            /* out of recognized modifiers and flags */
-            break;
-        }
-        argc--;
-        argv++;
-    }
-
-    if ((server_host_str || server_port_str) && server_socket_str) {
-        error_exit("-L is incompatible with -H or -P");
-    }
-
-    // If -L, -H, or -P are specified, ignore environment variables.
-    // Otherwise, prefer ADB_SERVER_SOCKET over ANDROID_ADB_SERVER_ADDRESS/PORT.
-    if (!server_host_str && !server_port_str && !server_socket_str) {
-        server_socket_str = getenv("ADB_SERVER_SOCKET");
-    }
-
-    if (!server_socket_str) {
-        // tcp:1234 and tcp:localhost:1234 are different with -a, so don't default to localhost
-        server_host_str = server_host_str ? server_host_str : getenv("ANDROID_ADB_SERVER_ADDRESS");
-
-        int server_port = DEFAULT_ADB_PORT;
-        server_port_str = server_port_str ? server_port_str : getenv("ANDROID_ADB_SERVER_PORT");
-        if (server_port_str && strlen(server_port_str) > 0) {
-            if (!android::base::ParseInt(server_port_str, &server_port, 1, 65535)) {
-                error_exit(
-                        "$ANDROID_ADB_SERVER_PORT must be a positive number less than 65535: "
-                        "got \"%s\"",
-                        server_port_str);
-            }
-        }
-
-        int rc;
-        char* temp;
-        if (server_host_str) {
-            rc = asprintf(&temp, "tcp:%s:%d", server_host_str, server_port);
-        } else {
-            rc = asprintf(&temp, "tcp:%d", server_port);
-        }
-        if (rc < 0) {
-            LOG(FATAL) << "failed to allocate server socket specification";
-        }
-        server_socket_str = temp;
-    }
-
-    adb_set_socket_spec(server_socket_str);
-
-    // If none of -d, -e, or -s were specified, try $ANDROID_SERIAL.
-    if (transport_type == kTransportAny && serial == nullptr) {
-        serial = getenv("ANDROID_SERIAL");
-    }
-
-    adb_set_transport(transport_type, serial, transport_id);
-
-    if (is_server) {
-        if (no_daemon || is_daemon) {
-            if (is_daemon && (ack_reply_fd == -1)) {
-                fprintf(stderr, "reply fd for adb server to client communication not specified.\n");
-                return 1;
-            }
-            r = adb_server_main(is_daemon, server_socket_str, ack_reply_fd);
-        } else {
-            r = launch_server(server_socket_str);
-        }
-        if (r) {
-            fprintf(stderr,"* could not start server *\n");
-        }
-        return r;
-    }
-
-    if (argc == 0) {
-        help();
-        return 1;
-    }
-
-    /* handle wait-for-* prefix */
-    if (!strncmp(argv[0], "wait-for-", strlen("wait-for-"))) {
-        const char* service = argv[0];
-
-        if (!wait_for_device(service)) {
-            return 1;
-        }
-
-        // Allow a command to be run after wait-for-device,
-        // e.g. 'adb wait-for-device shell'.
-        if (argc == 1) {
-            return 0;
-        }
-
-        /* Fall through */
-        argc--;
-        argv++;
-    }
-
-    /* adb_connect() commands */
-    if (!strcmp(argv[0], "devices")) {
-        const char *listopt;
-        if (argc < 2) {
-            listopt = "";
-        } else if (argc == 2 && !strcmp(argv[1], "-l")) {
-            listopt = argv[1];
-        } else {
-            error_exit("adb devices [-l]");
-        }
-
-        std::string query = android::base::StringPrintf("host:%s%s", argv[0], listopt);
-        std::string error;
-        if (!adb_check_server_version(&error)) {
-            error_exit("failed to check server version: %s", error.c_str());
-        }
-        printf("List of devices attached\n");
-        return adb_query_command(query);
-    }
-    else if (!strcmp(argv[0], "connect")) {
-        if (argc != 2) error_exit("usage: adb connect HOST[:PORT]");
-
-        std::string query = android::base::StringPrintf("host:connect:%s", argv[1]);
-        return adb_query_command(query);
-    }
-    else if (!strcmp(argv[0], "disconnect")) {
-        if (argc > 2) error_exit("usage: adb disconnect [HOST[:PORT]]");
-
-        std::string query = android::base::StringPrintf("host:disconnect:%s",
-                                                        (argc == 2) ? argv[1] : "");
-        return adb_query_command(query);
-    } else if (!strcmp(argv[0], "abb")) {
-        return adb_abb(argc, argv);
-    } else if (!strcmp(argv[0], "pair")) {
-        if (argc != 2) error_exit("usage: adb pair <host>[:<port>]");
-
-        std::string password;
-        printf("Enter pairing code: ");
-        fflush(stdout);
-        if (!std::getline(std::cin, password) || password.empty()) {
-            error_exit("No pairing code provided");
-        }
-        std::string query =
-                android::base::StringPrintf("host:pair:%s:%s", password.c_str(), argv[1]);
-
-        return adb_query_command(query);
-    } else if (!strcmp(argv[0], "emu")) {
-        return adb_send_emulator_command(argc, argv, serial);
-    } else if (!strcmp(argv[0], "shell")) {
-        return adb_shell(argc, argv);
-    } else if (!strcmp(argv[0], "exec-in") || !strcmp(argv[0], "exec-out")) {
-        int exec_in = !strcmp(argv[0], "exec-in");
-
-        if (argc < 2) error_exit("usage: adb %s command", argv[0]);
-
-        std::string cmd = "exec:";
-        cmd += argv[1];
-        argc -= 2;
-        argv += 2;
-        while (argc-- > 0) {
-            cmd += " " + escape_arg(*argv++);
-        }
-
-        std::string error;
-        unique_fd fd(adb_connect(cmd, &error));
-        if (fd < 0) {
-            fprintf(stderr, "error: %s\n", error.c_str());
-            return -1;
-        }
-
-        if (exec_in) {
-            copy_to_file(STDIN_FILENO, fd.get());
-        } else {
-            copy_to_file(fd.get(), STDOUT_FILENO);
-        }
-        return 0;
-    } else if (!strcmp(argv[0], "kill-server")) {
-        return adb_kill_server() ? 0 : 1;
-    } else if (!strcmp(argv[0], "sideload")) {
-        if (argc != 2) error_exit("sideload requires an argument");
-        if (adb_sideload_install(argv[1], false /* rescue_mode */)) {
-            return 1;
-        } else {
-            return 0;
-        }
-    } else if (!strcmp(argv[0], "rescue")) {
-        // adb rescue getprop
-        // adb rescue getprop <prop>
-        // adb rescue install <filename>
-        // adb rescue wipe userdata
-        if (argc < 2) error_exit("rescue requires at least one argument");
-        if (!strcmp(argv[1], "getprop")) {
-            if (argc == 2) {
-                return adb_connect_command("rescue-getprop:");
-            }
-            if (argc == 3) {
-                return adb_connect_command(
-                        android::base::StringPrintf("rescue-getprop:%s", argv[2]));
-            }
-            error_exit("invalid rescue getprop arguments");
-        } else if (!strcmp(argv[1], "install")) {
-            if (argc != 3) error_exit("rescue install requires two arguments");
-            if (adb_sideload_install(argv[2], true /* rescue_mode */) != 0) {
-                return 1;
-            }
-        } else if (!strcmp(argv[1], "wipe")) {
-            if (argc != 3 || strcmp(argv[2], "userdata") != 0) {
-                error_exit("invalid rescue wipe arguments");
-            }
-            return adb_wipe_devices();
-        } else {
-            error_exit("invalid rescue argument");
-        }
-        return 0;
-    } else if (!strcmp(argv[0], "tcpip")) {
-        if (argc != 2) error_exit("tcpip requires an argument");
-        int port;
-        if (!android::base::ParseInt(argv[1], &port, 1, 65535)) {
-            error_exit("tcpip: invalid port: %s", argv[1]);
-        }
-        return adb_connect_command(android::base::StringPrintf("tcpip:%d", port));
-    } else if (!strcmp(argv[0], "remount")) {
-        FeatureSet features;
-        std::string error;
-        if (!adb_get_feature_set(&features, &error)) {
-            fprintf(stderr, "error: %s\n", error.c_str());
-            return 1;
-        }
-
-        if (CanUseFeature(features, kFeatureRemountShell)) {
-            std::vector<const char*> args = {"shell"};
-            args.insert(args.cend(), argv, argv + argc);
-            return adb_shell_noinput(args.size(), args.data());
-        } else if (argc > 1) {
-            auto command = android::base::StringPrintf("%s:%s", argv[0], argv[1]);
-            return adb_connect_command(command);
-        } else {
-            return adb_connect_command("remount:");
-        }
-    }
-    // clang-format off
-    else if (!strcmp(argv[0], "reboot") ||
-             !strcmp(argv[0], "reboot-bootloader") ||
-             !strcmp(argv[0], "reboot-fastboot") ||
-             !strcmp(argv[0], "usb") ||
-             !strcmp(argv[0], "disable-verity") ||
-             !strcmp(argv[0], "enable-verity")) {
-        // clang-format on
-        std::string command;
-        if (!strcmp(argv[0], "reboot-bootloader")) {
-            command = "reboot:bootloader";
-        } else if (!strcmp(argv[0], "reboot-fastboot")) {
-            command = "reboot:fastboot";
-        } else if (argc > 1) {
-            command = android::base::StringPrintf("%s:%s", argv[0], argv[1]);
-        } else {
-            command = android::base::StringPrintf("%s:", argv[0]);
-        }
-        return adb_connect_command(command);
-    } else if (!strcmp(argv[0], "root") || !strcmp(argv[0], "unroot")) {
-        return adb_root(argv[0]) ? 0 : 1;
-    } else if (!strcmp(argv[0], "bugreport")) {
-        Bugreport bugreport;
-        return bugreport.DoIt(argc, argv);
-    } else if (!strcmp(argv[0], "forward") || !strcmp(argv[0], "reverse")) {
-        bool reverse = !strcmp(argv[0], "reverse");
-        --argc;
-        if (argc < 1) error_exit("%s requires an argument", argv[0]);
-        ++argv;
-
-        // Determine the <host-prefix> for this command.
-        std::string host_prefix;
-        if (reverse) {
-            host_prefix = "reverse:";
-        } else {
-            host_prefix = "host:";
-        }
-
-        std::string cmd, error_message;
-        if (strcmp(argv[0], "--list") == 0) {
-            if (argc != 1) error_exit("--list doesn't take any arguments");
-            return adb_query_command(host_prefix + "list-forward");
-        } else if (strcmp(argv[0], "--remove-all") == 0) {
-            if (argc != 1) error_exit("--remove-all doesn't take any arguments");
-            cmd = "killforward-all";
-        } else if (strcmp(argv[0], "--remove") == 0) {
-            // forward --remove <local>
-            if (argc != 2) error_exit("--remove requires an argument");
-            cmd = std::string("killforward:") + argv[1];
-        } else if (strcmp(argv[0], "--no-rebind") == 0) {
-            // forward --no-rebind <local> <remote>
-            if (argc != 3) error_exit("--no-rebind takes two arguments");
-            if (forward_targets_are_valid(argv[1], argv[2], &error_message)) {
-                cmd = std::string("forward:norebind:") + argv[1] + ";" + argv[2];
-            }
-        } else {
-            // forward <local> <remote>
-            if (argc != 2) error_exit("forward takes two arguments");
-            if (forward_targets_are_valid(argv[0], argv[1], &error_message)) {
-                cmd = std::string("forward:") + argv[0] + ";" + argv[1];
-            }
-        }
-
-        if (!error_message.empty()) {
-            error_exit("error: %s", error_message.c_str());
-        }
-
-        unique_fd fd(adb_connect(nullptr, host_prefix + cmd, &error_message, true));
-        if (fd < 0 || !adb_status(fd.get(), &error_message)) {
-            error_exit("error: %s", error_message.c_str());
-        }
-
-        // Server or device may optionally return a resolved TCP port number.
-        std::string resolved_port;
-        if (ReadProtocolString(fd, &resolved_port, &error_message) && !resolved_port.empty()) {
-            printf("%s\n", resolved_port.c_str());
-        }
-
-        ReadOrderlyShutdown(fd);
-        return 0;
-    }
-    /* do_sync_*() commands */
-    else if (!strcmp(argv[0], "ls")) {
-        if (argc != 2) error_exit("ls requires an argument");
-        return do_sync_ls(argv[1]) ? 0 : 1;
-    } else if (!strcmp(argv[0], "push")) {
-        bool copy_attrs = false;
-        bool sync = false;
-        bool compressed = true;
-        std::vector<const char*> srcs;
-        const char* dst = nullptr;
-
-        parse_push_pull_args(&argv[1], argc - 1, &srcs, &dst, &copy_attrs, &sync, &compressed);
-        if (srcs.empty() || !dst) error_exit("push requires an argument");
-        return do_sync_push(srcs, dst, sync, compressed) ? 0 : 1;
-    } else if (!strcmp(argv[0], "pull")) {
-        bool copy_attrs = false;
-        bool compressed = true;
-        std::vector<const char*> srcs;
-        const char* dst = ".";
-
-        parse_push_pull_args(&argv[1], argc - 1, &srcs, &dst, &copy_attrs, nullptr, &compressed);
-        if (srcs.empty()) error_exit("pull requires an argument");
-        return do_sync_pull(srcs, dst, copy_attrs, compressed) ? 0 : 1;
-    } else if (!strcmp(argv[0], "install")) {
-        if (argc < 2) error_exit("install requires an argument");
-        return install_app(argc, argv);
-    } else if (!strcmp(argv[0], "install-multiple")) {
-        if (argc < 2) error_exit("install-multiple requires an argument");
-        return install_multiple_app(argc, argv);
-    } else if (!strcmp(argv[0], "install-multi-package")) {
-        if (argc < 2) error_exit("install-multi-package requires an argument");
-        return install_multi_package(argc, argv);
-    } else if (!strcmp(argv[0], "uninstall")) {
-        if (argc < 2) error_exit("uninstall requires an argument");
-        return uninstall_app(argc, argv);
-    } else if (!strcmp(argv[0], "sync")) {
-        std::string src;
-        bool list_only = false;
-        bool compressed = true;
-
-        const char* adb_compression = getenv("ADB_COMPRESSION");
-        if (adb_compression && strcmp(adb_compression, "0") == 0) {
-            compressed = false;
-        }
-
-        int opt;
-        while ((opt = getopt(argc, const_cast<char**>(argv), "lzZ")) != -1) {
-            switch (opt) {
-                case 'l':
-                    list_only = true;
-                    break;
-                case 'z':
-                    compressed = true;
-                    break;
-                case 'Z':
-                    compressed = false;
-                    break;
-                default:
-                    error_exit("usage: adb sync [-lzZ] [PARTITION]");
-            }
-        }
-
-        if (optind == argc) {
-            src = "all";
-        } else if (optind + 1 == argc) {
-            src = argv[optind];
-        } else {
-            error_exit("usage: adb sync [-lzZ] [PARTITION]");
-        }
-
-        std::vector<std::string> partitions{"data",   "odm",        "oem",   "product",
-                                            "system", "system_ext", "vendor"};
-        bool found = false;
-        for (const auto& partition : partitions) {
-            if (src == "all" || src == partition) {
-                std::string src_dir{product_file(partition)};
-                if (!directory_exists(src_dir)) continue;
-                found = true;
-                if (!do_sync_sync(src_dir, "/" + partition, list_only, compressed)) return 1;
-            }
-        }
-        if (!found) error_exit("don't know how to sync %s partition", src.c_str());
-        return 0;
-    }
-    /* passthrough commands */
-    else if (!strcmp(argv[0], "get-state") || !strcmp(argv[0], "get-serialno") ||
-             !strcmp(argv[0], "get-devpath")) {
-        return adb_query_command(format_host_command(argv[0]));
-    }
-    /* other commands */
-    else if (!strcmp(argv[0], "logcat") || !strcmp(argv[0], "lolcat") ||
-             !strcmp(argv[0], "longcat")) {
-        return logcat(argc, argv);
-    } else if (!strcmp(argv[0], "ppp")) {
-        return ppp(argc, argv);
-    } else if (!strcmp(argv[0], "start-server")) {
-        std::string error;
-        const int result = adb_connect("host:start-server", &error);
-        if (result < 0) {
-            fprintf(stderr, "error: %s\n", error.c_str());
-        }
-        return result;
-    } else if (!strcmp(argv[0], "backup")) {
-        return backup(argc, argv);
-    } else if (!strcmp(argv[0], "restore")) {
-        return restore(argc, argv);
-    } else if (!strcmp(argv[0], "keygen")) {
-        if (argc != 2) error_exit("keygen requires an argument");
-        // Always print key generation information for keygen command.
-        adb_trace_enable(AUTH);
-        return adb_auth_keygen(argv[1]);
-    } else if (!strcmp(argv[0], "pubkey")) {
-        if (argc != 2) error_exit("pubkey requires an argument");
-        return adb_auth_pubkey(argv[1]);
-    } else if (!strcmp(argv[0], "jdwp")) {
-        return adb_connect_command("jdwp");
-    } else if (!strcmp(argv[0], "track-jdwp")) {
-        return adb_connect_command("track-jdwp");
-    } else if (!strcmp(argv[0], "track-devices")) {
-        if (argc > 2 || (argc == 2 && strcmp(argv[1], "-l"))) {
-            error_exit("usage: adb track-devices [-l]");
-        }
-        return adb_connect_command(argc == 2 ? "host:track-devices-l" : "host:track-devices");
-    } else if (!strcmp(argv[0], "raw")) {
-        if (argc != 2) {
-            error_exit("usage: adb raw SERVICE");
-        }
-        return adb_connect_command_bidirectional(argv[1]);
-    }
-
-    /* "adb /?" is a common idiom under Windows */
-    else if (!strcmp(argv[0], "--help") || !strcmp(argv[0], "help") || !strcmp(argv[0], "/?")) {
-        help();
-        return 0;
-    } else if (!strcmp(argv[0], "--version") || !strcmp(argv[0], "version")) {
-        fprintf(stdout, "%s", adb_version().c_str());
-        return 0;
-    } else if (!strcmp(argv[0], "features")) {
-        // Only list the features common to both the adb client and the device.
-        FeatureSet features;
-        std::string error;
-        if (!adb_get_feature_set(&features, &error)) {
-            fprintf(stderr, "error: %s\n", error.c_str());
-            return 1;
-        }
-
-        for (const std::string& name : features) {
-            if (CanUseFeature(features, name)) {
-                printf("%s\n", name.c_str());
-            }
-        }
-        return 0;
-    } else if (!strcmp(argv[0], "host-features")) {
-        return adb_query_command("host:host-features");
-    } else if (!strcmp(argv[0], "reconnect")) {
-        if (argc == 1) {
-            return adb_query_command(format_host_command(argv[0]));
-        } else if (argc == 2) {
-            if (!strcmp(argv[1], "device")) {
-                std::string err;
-                adb_connect("reconnect", &err);
-                return 0;
-            } else if (!strcmp(argv[1], "offline")) {
-                std::string err;
-                return adb_query_command("host:reconnect-offline");
-            } else {
-                error_exit("usage: adb reconnect [device|offline]");
-            }
-        }
-    } else if (!strcmp(argv[0], "inc-server")) {
-        if (argc < 4) {
-#ifdef _WIN32
-            error_exit("usage: adb inc-server CONNECTION_HANDLE OUTPUT_HANDLE FILE1 FILE2 ...");
-#else
-            error_exit("usage: adb inc-server CONNECTION_FD OUTPUT_FD FILE1 FILE2 ...");
-#endif
-        }
-        int connection_fd = atoi(argv[1]);
-        if (!_is_valid_os_fd(connection_fd)) {
-            error_exit("Invalid connection_fd number given: %d", connection_fd);
-        }
-
-        connection_fd = adb_register_socket(connection_fd);
-        close_on_exec(connection_fd);
-
-        int output_fd = atoi(argv[2]);
-        if (!_is_valid_os_fd(output_fd)) {
-            error_exit("Invalid output_fd number given: %d", output_fd);
-        }
-        output_fd = adb_register_socket(output_fd);
-        close_on_exec(output_fd);
-        return incremental::serve(connection_fd, output_fd, argc - 3, argv + 3);
-    }
-
-    error_exit("unknown command %s", argv[0]);
-    __builtin_unreachable();
-}
diff --git a/adb/client/commandline.h b/adb/client/commandline.h
deleted file mode 100644
index b9dee56..0000000
--- a/adb/client/commandline.h
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef COMMANDLINE_H
-#define COMMANDLINE_H
-
-#include <android-base/strings.h>
-
-#include "adb.h"
-#include "adb_client.h"
-#include "adb_unique_fd.h"
-
-// Callback used to handle the standard streams (stdout and stderr) sent by the
-// device's upon receiving a command.
-//
-class StandardStreamsCallbackInterface {
-  public:
-    StandardStreamsCallbackInterface() {
-    }
-    // Handles the stdout output from devices supporting the Shell protocol.
-    virtual void OnStdout(const char* buffer, int length) = 0;
-
-    // Handles the stderr output from devices supporting the Shell protocol.
-    virtual void OnStderr(const char* buffer, int length) = 0;
-
-    // Indicates the communication is finished and returns the appropriate error
-    // code.
-    //
-    // |status| has the status code returning by the underlying communication
-    // channels
-    virtual int Done(int status) = 0;
-
-  protected:
-    static void OnStream(std::string* string, FILE* stream, const char* buffer, int length) {
-        if (string != nullptr) {
-            string->append(buffer, length);
-        } else {
-            fwrite(buffer, 1, length, stream);
-            fflush(stream);
-        }
-    }
-
-  private:
-    DISALLOW_COPY_AND_ASSIGN(StandardStreamsCallbackInterface);
-};
-
-// Default implementation that redirects the streams to the equilavent host
-// stream or to a string
-// passed to the constructor.
-class DefaultStandardStreamsCallback : public StandardStreamsCallbackInterface {
-  public:
-    // If |stdout_str| is non-null, OnStdout will append to it.
-    // If |stderr_str| is non-null, OnStderr will append to it.
-    DefaultStandardStreamsCallback(std::string* stdout_str, std::string* stderr_str)
-        : stdout_str_(stdout_str), stderr_str_(stderr_str) {
-    }
-
-    void OnStdout(const char* buffer, int length) {
-        OnStream(stdout_str_, stdout, buffer, length);
-    }
-
-    void OnStderr(const char* buffer, int length) {
-        OnStream(stderr_str_, stderr, buffer, length);
-    }
-
-    int Done(int status) {
-        return status;
-    }
-
-  private:
-    std::string* stdout_str_;
-    std::string* stderr_str_;
-
-    DISALLOW_COPY_AND_ASSIGN(DefaultStandardStreamsCallback);
-};
-
-class SilentStandardStreamsCallbackInterface : public StandardStreamsCallbackInterface {
-  public:
-    SilentStandardStreamsCallbackInterface() = default;
-    void OnStdout(const char*, int) override final {}
-    void OnStderr(const char*, int) override final {}
-    int Done(int status) override final { return status; }
-};
-
-// Singleton.
-extern DefaultStandardStreamsCallback DEFAULT_STANDARD_STREAMS_CALLBACK;
-
-int adb_commandline(int argc, const char** argv);
-
-bool copy_to_file(int inFd, int outFd);
-
-// Connects to the device "shell" service with |command| and prints the
-// resulting output.
-// if |callback| is non-null, stdout/stderr output will be handled by it.
-int send_shell_command(
-        const std::string& command, bool disable_shell_protocol = false,
-        StandardStreamsCallbackInterface* callback = &DEFAULT_STANDARD_STREAMS_CALLBACK);
-
-// Reads from |fd| and prints received data. If |use_shell_protocol| is true
-// this expects that incoming data will use the shell protocol, in which case
-// stdout/stderr are routed independently and the remote exit code will be
-// returned.
-// if |callback| is non-null, stdout/stderr output will be handled by it.
-int read_and_dump(borrowed_fd fd, bool use_shell_protocol = false,
-                  StandardStreamsCallbackInterface* callback = &DEFAULT_STANDARD_STREAMS_CALLBACK);
-
-// Connects to the device "abb" service with |command| and returns the fd.
-template <typename ContainerT>
-unique_fd send_abb_exec_command(const ContainerT& command_args, std::string* error) {
-    std::string service_string = "abb_exec:" + android::base::Join(command_args, ABB_ARG_DELIMETER);
-
-    unique_fd fd(adb_connect(service_string, error));
-    if (fd < 0) {
-        fprintf(stderr, "adb: failed to run abb_exec. Error: %s\n", error->c_str());
-        return unique_fd{};
-    }
-    return fd;
-}
-
-#endif  // COMMANDLINE_H
diff --git a/adb/client/console.cpp b/adb/client/console.cpp
deleted file mode 100644
index d10f4de..0000000
--- a/adb/client/console.cpp
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "sysdeps.h"
-
-#include <stdio.h>
-
-#include <android-base/file.h>
-#include <android-base/logging.h>
-#include <android-base/strings.h>
-#include <cutils/sockets.h>
-
-#include "adb.h"
-#include "adb_client.h"
-#include "adb_io.h"
-#include "adb_utils.h"
-
-// Return the console authentication command for the emulator, if needed
-static std::string adb_construct_auth_command() {
-    static const char auth_token_filename[] = ".emulator_console_auth_token";
-
-    std::string auth_token_path = adb_get_homedir_path();
-    auth_token_path += OS_PATH_SEPARATOR;
-    auth_token_path += auth_token_filename;
-
-    // read the token
-    std::string token;
-    if (!android::base::ReadFileToString(auth_token_path, &token)
-        || token.empty()) {
-        // we either can't read the file, or it doesn't exist, or it's empty -
-        // either way we won't add any authentication command.
-        return {};
-    }
-
-    // now construct and return the actual command: "auth <token>\n"
-    std::string command = "auth ";
-    command += token;
-    command += '\n';
-    return command;
-}
-
-// Return the console port of the currently connected emulator (if any) or -1 if
-// there is no emulator, and -2 if there is more than one.
-static int adb_get_emulator_console_port(const char* serial) {
-    if (serial) {
-        // The user specified a serial number; is it an emulator?
-        int port;
-        return (sscanf(serial, "emulator-%d", &port) == 1) ? port : -1;
-    }
-
-    // No specific device was given, so get the list of connected devices and
-    // search for emulators. If there's one, we'll take it. If there are more
-    // than one, that's an error.
-    std::string devices;
-    std::string error;
-    if (!adb_query("host:devices", &devices, &error)) {
-        fprintf(stderr, "error: no emulator connected: %s\n", error.c_str());
-        return -1;
-    }
-
-    int port = -1;
-    size_t emulator_count = 0;
-    for (const auto& device : android::base::Split(devices, "\n")) {
-        if (sscanf(device.c_str(), "emulator-%d", &port) == 1) {
-            if (++emulator_count > 1) {
-                fprintf(
-                    stderr, "error: more than one emulator detected; use -s\n");
-                return -1;
-            }
-        }
-    }
-
-    if (emulator_count == 0) {
-        fprintf(stderr, "error: no emulator detected\n");
-        return -1;
-    }
-
-    return port;
-}
-
-static int connect_to_console(const char* serial) {
-    int port = adb_get_emulator_console_port(serial);
-    if (port == -1) {
-        return -1;
-    }
-
-    std::string error;
-    int fd = network_loopback_client(port, SOCK_STREAM, &error);
-    if (fd == -1) {
-        fprintf(stderr, "error: could not connect to TCP port %d: %s\n", port,
-                error.c_str());
-        return -1;
-    }
-    return fd;
-}
-
-int adb_send_emulator_command(int argc, const char** argv, const char* serial) {
-    unique_fd fd(connect_to_console(serial));
-    if (fd == -1) {
-        return 1;
-    }
-
-    std::string commands = adb_construct_auth_command();
-
-    for (int i = 1; i < argc; i++) {
-        commands.append(argv[i]);
-        commands.push_back(i == argc - 1 ? '\n' : ' ');
-    }
-
-    commands.append("quit\n");
-
-    if (!WriteFdExactly(fd, commands)) {
-        fprintf(stderr, "error: cannot write to emulator: %s\n",
-                strerror(errno));
-        return 1;
-    }
-
-    // Drain output that the emulator console has sent us to prevent a problem
-    // on Windows where if adb closes the socket without reading all the data,
-    // the emulator's next call to recv() will have an ECONNABORTED error,
-    // preventing the emulator from reading the command that adb has sent.
-    // https://code.google.com/p/android/issues/detail?id=21021
-    int result;
-    std::string emulator_output;
-    do {
-        char buf[BUFSIZ];
-        result = adb_read(fd, buf, sizeof(buf));
-        // Keep reading until zero bytes (orderly/graceful shutdown) or an
-        // error. If 'adb emu kill' is executed, the emulator calls exit() with
-        // the socket open (and shutdown(SD_SEND) was not called), which causes
-        // Windows to send a TCP RST segment which causes adb to get ECONNRESET.
-        // Any other emu command is followed by the quit command that we
-        // appended above, and that causes the emulator to close the socket
-        // which should cause zero bytes (orderly/graceful shutdown) to be
-        // returned.
-        if (result > 0) emulator_output.append(buf, result);
-    } while (result > 0);
-
-    // Note: the following messages are expected to be quite stable from emulator.
-    //
-    // Emulator console will send the following message upon connection:
-    //
-    // Android Console: Authentication required
-    // Android Console: type 'auth <auth_token>' to authenticate
-    // Android Console: you can find your <auth_token> in
-    // '/<path-to-home>/.emulator_console_auth_token'
-    // OK\r\n
-    //
-    // and the following after authentication:
-    // Android Console: type 'help' for a list of commands
-    // OK\r\n
-    //
-    // So try search and skip first two "OK\r\n", print the rest.
-    //
-    const std::string delims = "OK\r\n";
-    size_t found = 0;
-    for (int i = 0; i < 2; ++i) {
-        const size_t result = emulator_output.find(delims, found);
-        if (result == std::string::npos) {
-            break;
-        } else {
-            found = result + delims.size();
-        }
-    }
-
-    printf("%s", emulator_output.c_str() + found);
-    return 0;
-}
diff --git a/adb/client/fastdeploy.cpp b/adb/client/fastdeploy.cpp
deleted file mode 100644
index de82e14..0000000
--- a/adb/client/fastdeploy.cpp
+++ /dev/null
@@ -1,357 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "fastdeploy.h"
-
-#include <string.h>
-#include <algorithm>
-#include <array>
-#include <memory>
-
-#include "android-base/file.h"
-#include "android-base/strings.h"
-#include "androidfw/ResourceTypes.h"
-#include "androidfw/ZipFileRO.h"
-#include "client/file_sync_client.h"
-#include "commandline.h"
-#include "deployagent.inc"        // Generated include via build rule.
-#include "deployagentscript.inc"  // Generated include via build rule.
-#include "fastdeploy/deploypatchgenerator/deploy_patch_generator.h"
-#include "fastdeploy/deploypatchgenerator/patch_utils.h"
-#include "fastdeploy/proto/ApkEntry.pb.h"
-#include "fastdeploycallbacks.h"
-#include "sysdeps.h"
-
-#include "adb_utils.h"
-
-static constexpr long kRequiredAgentVersion = 0x00000003;
-
-static constexpr int kPackageMissing = 3;
-static constexpr int kInvalidAgentVersion = 4;
-
-static constexpr const char* kDeviceAgentFile = "/data/local/tmp/deployagent.jar";
-static constexpr const char* kDeviceAgentScript = "/data/local/tmp/deployagent";
-
-static constexpr bool g_verbose_timings = false;
-static FastDeploy_AgentUpdateStrategy g_agent_update_strategy =
-        FastDeploy_AgentUpdateDifferentVersion;
-
-using APKMetaData = com::android::fastdeploy::APKMetaData;
-
-namespace {
-
-struct TimeReporter {
-    TimeReporter(const char* label) : label_(label) {}
-    ~TimeReporter() {
-        if (g_verbose_timings) {
-            auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(
-                    std::chrono::steady_clock::now() - start_);
-            fprintf(stderr, "%s finished in %lldms\n", label_,
-                    static_cast<long long>(duration.count()));
-        }
-    }
-
-  private:
-    const char* label_;
-    std::chrono::steady_clock::time_point start_ = std::chrono::steady_clock::now();
-};
-#define REPORT_FUNC_TIME() TimeReporter reporter(__func__)
-
-struct FileDeleter {
-    FileDeleter(const char* path) : path_(path) {}
-    ~FileDeleter() { adb_unlink(path_); }
-
-  private:
-    const char* const path_;
-};
-
-}  // namespace
-
-int get_device_api_level() {
-    static const int api_level = [] {
-        REPORT_FUNC_TIME();
-        std::vector<char> sdk_version_output_buffer;
-        std::vector<char> sdk_version_error_buffer;
-        int api_level = -1;
-
-        int status_code =
-                capture_shell_command("getprop ro.build.version.sdk", &sdk_version_output_buffer,
-                                      &sdk_version_error_buffer);
-        if (status_code == 0 && sdk_version_output_buffer.size() > 0) {
-            api_level = strtol((char*)sdk_version_output_buffer.data(), nullptr, 10);
-        }
-
-        return api_level;
-    }();
-    return api_level;
-}
-
-void fastdeploy_set_agent_update_strategy(FastDeploy_AgentUpdateStrategy agent_update_strategy) {
-    g_agent_update_strategy = agent_update_strategy;
-}
-
-static void push_to_device(const void* data, size_t byte_count, const char* dst, bool sync) {
-    std::vector<const char*> srcs;
-    TemporaryFile tf;
-    android::base::WriteFully(tf.fd, data, byte_count);
-    srcs.push_back(tf.path);
-    // On Windows, the file needs to be flushed before pushing to device,
-    // but can't be removed until after the push.
-    unix_close(tf.release());
-
-    if (!do_sync_push(srcs, dst, sync, true)) {
-        error_exit("Failed to push fastdeploy agent to device.");
-    }
-}
-
-static bool deploy_agent(bool check_time_stamps) {
-    REPORT_FUNC_TIME();
-
-    push_to_device(kDeployAgent, sizeof(kDeployAgent), kDeviceAgentFile, check_time_stamps);
-    push_to_device(kDeployAgentScript, sizeof(kDeployAgentScript), kDeviceAgentScript,
-                   check_time_stamps);
-
-    // on windows the shell script might have lost execute permission
-    // so need to set this explicitly
-    const char* kChmodCommandPattern = "chmod 777 %s";
-    std::string chmod_command =
-            android::base::StringPrintf(kChmodCommandPattern, kDeviceAgentScript);
-    int ret = send_shell_command(chmod_command);
-    if (ret != 0) {
-        error_exit("Error executing %s returncode: %d", chmod_command.c_str(), ret);
-    }
-
-    return true;
-}
-
-static std::string get_string_from_utf16(const char16_t* input, int input_len) {
-    ssize_t utf8_length = utf16_to_utf8_length(input, input_len);
-    if (utf8_length <= 0) {
-        return {};
-    }
-    std::string utf8;
-    utf8.resize(utf8_length);
-    utf16_to_utf8(input, input_len, &*utf8.begin(), utf8_length + 1);
-    return utf8;
-}
-
-static std::string get_package_name_from_apk(const char* apk_path) {
-#undef open
-    std::unique_ptr<android::ZipFileRO> zip_file((android::ZipFileRO::open)(apk_path));
-#define open ___xxx_unix_open
-    if (zip_file == nullptr) {
-        perror_exit("Could not open %s", apk_path);
-    }
-    android::ZipEntryRO entry = zip_file->findEntryByName("AndroidManifest.xml");
-    if (entry == nullptr) {
-        error_exit("Could not find AndroidManifest.xml inside %s", apk_path);
-    }
-    uint32_t manifest_len = 0;
-    if (!zip_file->getEntryInfo(entry, NULL, &manifest_len, NULL, NULL, NULL, NULL)) {
-        error_exit("Could not read AndroidManifest.xml inside %s", apk_path);
-    }
-    std::vector<char> manifest_data(manifest_len);
-    if (!zip_file->uncompressEntry(entry, manifest_data.data(), manifest_len)) {
-        error_exit("Could not uncompress AndroidManifest.xml inside %s", apk_path);
-    }
-    android::ResXMLTree tree;
-    android::status_t setto_status = tree.setTo(manifest_data.data(), manifest_len, true);
-    if (setto_status != android::OK) {
-        error_exit("Could not parse AndroidManifest.xml inside %s", apk_path);
-    }
-    android::ResXMLParser::event_code_t code;
-    while ((code = tree.next()) != android::ResXMLParser::BAD_DOCUMENT &&
-           code != android::ResXMLParser::END_DOCUMENT) {
-        switch (code) {
-            case android::ResXMLParser::START_TAG: {
-                size_t element_name_length;
-                const char16_t* element_name = tree.getElementName(&element_name_length);
-                if (element_name == nullptr) {
-                    continue;
-                }
-                std::u16string element_name_string(element_name, element_name_length);
-                if (element_name_string == u"manifest") {
-                    for (size_t i = 0; i < tree.getAttributeCount(); i++) {
-                        size_t attribute_name_length;
-                        const char16_t* attribute_name_text =
-                                tree.getAttributeName(i, &attribute_name_length);
-                        if (attribute_name_text == nullptr) {
-                            continue;
-                        }
-                        std::u16string attribute_name_string(attribute_name_text,
-                                                             attribute_name_length);
-                        if (attribute_name_string == u"package") {
-                            size_t attribute_value_length;
-                            const char16_t* attribute_value_text =
-                                    tree.getAttributeStringValue(i, &attribute_value_length);
-                            if (attribute_value_text == nullptr) {
-                                continue;
-                            }
-                            return get_string_from_utf16(attribute_value_text,
-                                                         attribute_value_length);
-                        }
-                    }
-                }
-                break;
-            }
-            default:
-                break;
-        }
-    }
-    error_exit("Could not find package name tag in AndroidManifest.xml inside %s", apk_path);
-}
-
-static long parse_agent_version(const std::vector<char>& version_buffer) {
-    long version = -1;
-    if (!version_buffer.empty()) {
-        version = strtol((char*)version_buffer.data(), NULL, 16);
-    }
-    return version;
-}
-
-static void update_agent_if_necessary() {
-    switch (g_agent_update_strategy) {
-        case FastDeploy_AgentUpdateAlways:
-            deploy_agent(/*check_time_stamps=*/false);
-            break;
-        case FastDeploy_AgentUpdateNewerTimeStamp:
-            deploy_agent(/*check_time_stamps=*/true);
-            break;
-        default:
-            break;
-    }
-}
-
-std::optional<APKMetaData> extract_metadata(const char* apk_path) {
-    // Update agent if there is a command line argument forcing to do so.
-    update_agent_if_necessary();
-
-    REPORT_FUNC_TIME();
-
-    std::string package_name = get_package_name_from_apk(apk_path);
-
-    // Dump apk command checks the required vs current agent version and if they match then returns
-    // the APK dump for package. Doing this in a single call saves round-trip and agent launch time.
-    constexpr const char* kAgentDumpCommandPattern = "/data/local/tmp/deployagent dump %ld %s";
-    std::string dump_command = android::base::StringPrintf(
-            kAgentDumpCommandPattern, kRequiredAgentVersion, package_name.c_str());
-
-    std::vector<char> dump_out_buffer;
-    std::vector<char> dump_error_buffer;
-    int returnCode =
-            capture_shell_command(dump_command.c_str(), &dump_out_buffer, &dump_error_buffer);
-    if (returnCode >= kInvalidAgentVersion) {
-        // Agent has wrong version or missing.
-        long agent_version = parse_agent_version(dump_out_buffer);
-        if (agent_version < 0) {
-            printf("Could not detect agent on device, deploying\n");
-        } else {
-            printf("Device agent version is (%ld), (%ld) is required, re-deploying\n",
-                   agent_version, kRequiredAgentVersion);
-        }
-        deploy_agent(/*check_time_stamps=*/false);
-
-        // Retry with new agent.
-        dump_out_buffer.clear();
-        dump_error_buffer.clear();
-        returnCode =
-                capture_shell_command(dump_command.c_str(), &dump_out_buffer, &dump_error_buffer);
-    }
-    if (returnCode != 0) {
-        if (returnCode == kInvalidAgentVersion) {
-            long agent_version = parse_agent_version(dump_out_buffer);
-            error_exit(
-                    "After update agent version remains incorrect! Expected %ld but version is %ld",
-                    kRequiredAgentVersion, agent_version);
-        }
-        if (returnCode == kPackageMissing) {
-            fprintf(stderr, "Package %s not found, falling back to install\n",
-                    package_name.c_str());
-            return {};
-        }
-        fprintf(stderr, "Executing %s returned %d\n", dump_command.c_str(), returnCode);
-        fprintf(stderr, "%*s\n", int(dump_error_buffer.size()), dump_error_buffer.data());
-        error_exit("Aborting");
-    }
-
-    com::android::fastdeploy::APKDump dump;
-    if (!dump.ParseFromArray(dump_out_buffer.data(), dump_out_buffer.size())) {
-        fprintf(stderr, "Can't parse output of %s\n", dump_command.c_str());
-        error_exit("Aborting");
-    }
-
-    return PatchUtils::GetDeviceAPKMetaData(dump);
-}
-
-unique_fd install_patch(int argc, const char** argv) {
-    REPORT_FUNC_TIME();
-    constexpr char kAgentApplyServicePattern[] = "shell:/data/local/tmp/deployagent apply - -pm %s";
-
-    std::vector<unsigned char> apply_output_buffer;
-    std::vector<unsigned char> apply_error_buffer;
-    std::string argsString;
-
-    bool rSwitchPresent = false;
-    for (int i = 0; i < argc; i++) {
-        argsString.append(argv[i]);
-        argsString.append(" ");
-        if (!strcmp(argv[i], "-r")) {
-            rSwitchPresent = true;
-        }
-    }
-    if (!rSwitchPresent) {
-        argsString.append("-r");
-    }
-
-    std::string error;
-    std::string apply_patch_service_string =
-            android::base::StringPrintf(kAgentApplyServicePattern, argsString.c_str());
-    unique_fd fd{adb_connect(apply_patch_service_string, &error)};
-    if (fd < 0) {
-        error_exit("Executing %s returned %s", apply_patch_service_string.c_str(), error.c_str());
-    }
-    return fd;
-}
-
-unique_fd apply_patch_on_device(const char* output_path) {
-    REPORT_FUNC_TIME();
-    constexpr char kAgentApplyServicePattern[] = "shell:/data/local/tmp/deployagent apply - -o %s";
-
-    std::string error;
-    std::string apply_patch_service_string =
-            android::base::StringPrintf(kAgentApplyServicePattern, output_path);
-    unique_fd fd{adb_connect(apply_patch_service_string, &error)};
-    if (fd < 0) {
-        error_exit("Executing %s returned %s", apply_patch_service_string.c_str(), error.c_str());
-    }
-    return fd;
-}
-
-static void create_patch(const char* apk_path, APKMetaData metadata, borrowed_fd patch_fd) {
-    REPORT_FUNC_TIME();
-    DeployPatchGenerator generator(/*is_verbose=*/false);
-    bool success = generator.CreatePatch(apk_path, std::move(metadata), patch_fd);
-    if (!success) {
-        error_exit("Failed to create patch for %s", apk_path);
-    }
-}
-
-int stream_patch(const char* apk_path, APKMetaData metadata, unique_fd patch_fd) {
-    create_patch(apk_path, std::move(metadata), patch_fd);
-
-    REPORT_FUNC_TIME();
-    return read_and_dump(patch_fd.get());
-}
diff --git a/adb/client/fastdeploy.h b/adb/client/fastdeploy.h
deleted file mode 100644
index 830aeb2..0000000
--- a/adb/client/fastdeploy.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "adb_unique_fd.h"
-
-#include "fastdeploy/proto/ApkEntry.pb.h"
-
-#include <optional>
-#include <string>
-
-enum FastDeploy_AgentUpdateStrategy {
-    FastDeploy_AgentUpdateAlways,
-    FastDeploy_AgentUpdateNewerTimeStamp,
-    FastDeploy_AgentUpdateDifferentVersion
-};
-
-void fastdeploy_set_agent_update_strategy(FastDeploy_AgentUpdateStrategy agent_update_strategy);
-int get_device_api_level();
-
-std::optional<com::android::fastdeploy::APKMetaData> extract_metadata(const char* apk_path);
-unique_fd install_patch(int argc, const char** argv);
-unique_fd apply_patch_on_device(const char* output_path);
-int stream_patch(const char* apk_path, com::android::fastdeploy::APKMetaData metadata,
-                 unique_fd patch_fd);
diff --git a/adb/client/fastdeploycallbacks.cpp b/adb/client/fastdeploycallbacks.cpp
deleted file mode 100644
index 86ceaa1..0000000
--- a/adb/client/fastdeploycallbacks.cpp
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define TRACE_TAG ADB
-
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/stat.h>
-
-#include "client/file_sync_client.h"
-#include "commandline.h"
-#include "sysdeps.h"
-
-#include "fastdeploycallbacks.h"
-
-static void appendBuffer(std::vector<char>* buffer, const char* input, int length) {
-    if (buffer != NULL) {
-        buffer->insert(buffer->end(), input, input + length);
-    }
-}
-
-class DeployAgentBufferCallback : public StandardStreamsCallbackInterface {
-  public:
-    DeployAgentBufferCallback(std::vector<char>* outBuffer, std::vector<char>* errBuffer);
-
-    virtual void OnStdout(const char* buffer, int length);
-    virtual void OnStderr(const char* buffer, int length);
-    virtual int Done(int status);
-
-  private:
-    std::vector<char>* mpOutBuffer;
-    std::vector<char>* mpErrBuffer;
-};
-
-int capture_shell_command(const char* command, std::vector<char>* outBuffer,
-                          std::vector<char>* errBuffer) {
-    DeployAgentBufferCallback cb(outBuffer, errBuffer);
-    return send_shell_command(command, /*disable_shell_protocol=*/false, &cb);
-}
-
-DeployAgentBufferCallback::DeployAgentBufferCallback(std::vector<char>* outBuffer,
-                                                     std::vector<char>* errBuffer) {
-    mpOutBuffer = outBuffer;
-    mpErrBuffer = errBuffer;
-}
-
-void DeployAgentBufferCallback::OnStdout(const char* buffer, int length) {
-    appendBuffer(mpOutBuffer, buffer, length);
-}
-
-void DeployAgentBufferCallback::OnStderr(const char* buffer, int length) {
-    appendBuffer(mpErrBuffer, buffer, length);
-}
-
-int DeployAgentBufferCallback::Done(int status) {
-    return status;
-}
diff --git a/adb/client/fastdeploycallbacks.h b/adb/client/fastdeploycallbacks.h
deleted file mode 100644
index 4a6fb99..0000000
--- a/adb/client/fastdeploycallbacks.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <vector>
-
-int capture_shell_command(const char* command, std::vector<char>* outBuffer,
-                          std::vector<char>* errBuffer);
diff --git a/adb/client/file_sync_client.cpp b/adb/client/file_sync_client.cpp
deleted file mode 100644
index e686973..0000000
--- a/adb/client/file_sync_client.cpp
+++ /dev/null
@@ -1,1650 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "client/file_sync_client.h"
-
-#include <dirent.h>
-#include <inttypes.h>
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <time.h>
-#include <unistd.h>
-#include <utime.h>
-
-#include <chrono>
-#include <deque>
-#include <functional>
-#include <memory>
-#include <sstream>
-#include <string>
-#include <vector>
-
-#include "sysdeps.h"
-
-#include "adb.h"
-#include "adb_client.h"
-#include "adb_io.h"
-#include "adb_utils.h"
-#include "brotli_utils.h"
-#include "file_sync_protocol.h"
-#include "line_printer.h"
-#include "sysdeps/errno.h"
-#include "sysdeps/stat.h"
-
-#include "client/commandline.h"
-
-#include <android-base/file.h>
-#include <android-base/strings.h>
-#include <android-base/stringprintf.h>
-
-using namespace std::literals;
-
-typedef void(sync_ls_cb)(unsigned mode, uint64_t size, uint64_t time, const char* name);
-
-struct syncsendbuf {
-    unsigned id;
-    unsigned size;
-    char data[SYNC_DATA_MAX];
-};
-
-static void ensure_trailing_separators(std::string& local_path, std::string& remote_path) {
-    if (!adb_is_separator(local_path.back())) {
-        local_path.push_back(OS_PATH_SEPARATOR);
-    }
-    if (remote_path.back() != '/') {
-        remote_path.push_back('/');
-    }
-}
-
-static bool should_pull_file(mode_t mode) {
-    return S_ISREG(mode) || S_ISBLK(mode) || S_ISCHR(mode);
-}
-
-static bool should_push_file(mode_t mode) {
-    return S_ISREG(mode) || S_ISLNK(mode);
-}
-
-struct copyinfo {
-    std::string lpath;
-    std::string rpath;
-    int64_t time = 0;
-    uint32_t mode;
-    uint64_t size = 0;
-    bool skip = false;
-
-    copyinfo(const std::string& local_path,
-             const std::string& remote_path,
-             const std::string& name,
-             unsigned int mode)
-            : lpath(local_path), rpath(remote_path), mode(mode) {
-        ensure_trailing_separators(lpath, rpath);
-        lpath.append(name);
-        rpath.append(name);
-        if (S_ISDIR(mode)) {
-            ensure_trailing_separators(lpath, rpath);
-        }
-    }
-};
-
-enum class TransferDirection {
-    push,
-    pull,
-};
-
-struct TransferLedger {
-    std::chrono::steady_clock::time_point start_time;
-    uint64_t files_transferred;
-    uint64_t files_skipped;
-    uint64_t bytes_transferred;
-    uint64_t bytes_expected;
-    bool expect_multiple_files;
-
-  private:
-    std::string last_progress_str;
-    std::chrono::steady_clock::time_point last_progress_time;
-
-  public:
-    TransferLedger() {
-        Reset();
-    }
-
-    bool operator==(const TransferLedger& other) const {
-        return files_transferred == other.files_transferred &&
-               files_skipped == other.files_skipped && bytes_transferred == other.bytes_transferred;
-    }
-
-    bool operator!=(const TransferLedger& other) const {
-        return !(*this == other);
-    }
-
-    void Reset() {
-        start_time = std::chrono::steady_clock::now();
-        files_transferred = 0;
-        files_skipped = 0;
-        bytes_transferred = 0;
-        bytes_expected = 0;
-        last_progress_str.clear();
-        last_progress_time = {};
-    }
-
-    std::string TransferRate() {
-        if (bytes_transferred == 0) return "";
-
-        std::chrono::duration<double> duration;
-        duration = std::chrono::steady_clock::now() - start_time;
-
-        double s = duration.count();
-        if (s == 0) {
-            return "";
-        }
-        double rate = (static_cast<double>(bytes_transferred) / s) / (1024 * 1024);
-        return android::base::StringPrintf(" %.1f MB/s (%" PRIu64 " bytes in %.3fs)", rate,
-                                           bytes_transferred, s);
-    }
-
-    void ReportProgress(LinePrinter& lp, const std::string& file, uint64_t file_copied_bytes,
-                        uint64_t file_total_bytes) {
-        static constexpr auto kProgressReportInterval = 100ms;
-
-        auto now = std::chrono::steady_clock::now();
-        if (now < last_progress_time + kProgressReportInterval) {
-            return;
-        }
-        char overall_percentage_str[5] = "?";
-        if (bytes_expected != 0 && bytes_transferred <= bytes_expected) {
-            int overall_percentage = static_cast<int>(bytes_transferred * 100 / bytes_expected);
-            // If we're pulling symbolic links, we'll pull the target of the link rather than
-            // just create a local link, and that will cause us to go over 100%.
-            if (overall_percentage <= 100) {
-                snprintf(overall_percentage_str, sizeof(overall_percentage_str), "%d%%",
-                         overall_percentage);
-            }
-        }
-
-        std::string output;
-        if (file_copied_bytes > file_total_bytes || file_total_bytes == 0) {
-            // This case can happen if we're racing against something that wrote to the file
-            // between our stat and our read, or if we're reading a magic file that lies about
-            // its size. Just show how much we've copied.
-            output = android::base::StringPrintf("[%4s] %s: %" PRId64 "/?", overall_percentage_str,
-                                                 file.c_str(), file_copied_bytes);
-        } else {
-            // If we're transferring multiple files, we want to know how far through the current
-            // file we are, as well as the overall percentage.
-            if (expect_multiple_files) {
-                int file_percentage = static_cast<int>(file_copied_bytes * 100 / file_total_bytes);
-                output = android::base::StringPrintf("[%4s] %s: %d%%", overall_percentage_str,
-                                                     file.c_str(), file_percentage);
-            } else {
-                output =
-                    android::base::StringPrintf("[%4s] %s", overall_percentage_str, file.c_str());
-            }
-        }
-        if (output != last_progress_str) {
-            lp.Print(output, LinePrinter::LineType::INFO);
-            last_progress_str = std::move(output);
-            last_progress_time = now;
-        }
-    }
-
-    void ReportTransferRate(LinePrinter& lp, const std::string& name, TransferDirection direction) {
-        const char* direction_str = (direction == TransferDirection::push) ? "pushed" : "pulled";
-        std::stringstream ss;
-        if (!name.empty()) {
-            std::string_view display_name(name);
-            char* out = getenv("ANDROID_PRODUCT_OUT");
-            if (out) android::base::ConsumePrefix(&display_name, out);
-            ss << display_name << ": ";
-        }
-        ss << files_transferred << " file" << ((files_transferred == 1) ? "" : "s") << " "
-           << direction_str << ", " << files_skipped << " skipped.";
-        ss << TransferRate();
-
-        lp.Print(ss.str(), LinePrinter::LineType::INFO);
-        lp.KeepInfoLine();
-    }
-};
-
-class SyncConnection {
-  public:
-    SyncConnection() : acknowledgement_buffer_(sizeof(sync_status) + SYNC_DATA_MAX) {
-        acknowledgement_buffer_.resize(0);
-        max = SYNC_DATA_MAX; // TODO: decide at runtime.
-
-        std::string error;
-        if (!adb_get_feature_set(&features_, &error)) {
-            Error("failed to get feature set: %s", error.c_str());
-        } else {
-            have_stat_v2_ = CanUseFeature(features_, kFeatureStat2);
-            have_ls_v2_ = CanUseFeature(features_, kFeatureLs2);
-            have_sendrecv_v2_ = CanUseFeature(features_, kFeatureSendRecv2);
-            have_sendrecv_v2_brotli_ = CanUseFeature(features_, kFeatureSendRecv2Brotli);
-            fd.reset(adb_connect("sync:", &error));
-            if (fd < 0) {
-                Error("connect failed: %s", error.c_str());
-            }
-        }
-    }
-
-    ~SyncConnection() {
-        if (!IsValid()) return;
-
-        if (SendQuit()) {
-            // We sent a quit command, so the server should be doing orderly
-            // shutdown soon. But if we encountered an error while we were using
-            // the connection, the server might still be sending data (before
-            // doing orderly shutdown), in which case we won't wait for all of
-            // the data nor the coming orderly shutdown. In the common success
-            // case, this will wait for the server to do orderly shutdown.
-            ReadOrderlyShutdown(fd);
-        }
-
-        line_printer_.KeepInfoLine();
-    }
-
-    bool HaveSendRecv2() const { return have_sendrecv_v2_; }
-    bool HaveSendRecv2Brotli() const { return have_sendrecv_v2_brotli_; }
-
-    const FeatureSet& Features() const { return features_; }
-
-    bool IsValid() { return fd >= 0; }
-
-    void NewTransfer() {
-        current_ledger_.Reset();
-    }
-
-    void RecordBytesTransferred(size_t bytes) {
-        current_ledger_.bytes_transferred += bytes;
-        global_ledger_.bytes_transferred += bytes;
-    }
-
-    void RecordFileSent(std::string from, std::string to) {
-        RecordFilesTransferred(1);
-        deferred_acknowledgements_.emplace_back(std::move(from), std::move(to));
-    }
-
-    void RecordFilesTransferred(size_t files) {
-        current_ledger_.files_transferred += files;
-        global_ledger_.files_transferred += files;
-    }
-
-    void RecordFilesSkipped(size_t files) {
-        current_ledger_.files_skipped += files;
-        global_ledger_.files_skipped += files;
-    }
-
-    void ReportProgress(const std::string& file, uint64_t file_copied_bytes,
-                        uint64_t file_total_bytes) {
-        current_ledger_.ReportProgress(line_printer_, file, file_copied_bytes, file_total_bytes);
-    }
-
-    void ReportTransferRate(const std::string& file, TransferDirection direction) {
-        current_ledger_.ReportTransferRate(line_printer_, file, direction);
-    }
-
-    void ReportOverallTransferRate(TransferDirection direction) {
-        if (current_ledger_ != global_ledger_) {
-            global_ledger_.ReportTransferRate(line_printer_, "", direction);
-        }
-    }
-
-    bool SendRequest(int id, const std::string& path) {
-        if (path.length() > 1024) {
-            Error("SendRequest failed: path too long: %zu", path.length());
-            errno = ENAMETOOLONG;
-            return false;
-        }
-
-        // Sending header and payload in a single write makes a noticeable
-        // difference to "adb sync" performance.
-        std::vector<char> buf(sizeof(SyncRequest) + path.length());
-        SyncRequest* req = reinterpret_cast<SyncRequest*>(&buf[0]);
-        req->id = id;
-        req->path_length = path.length();
-        char* data = reinterpret_cast<char*>(req + 1);
-        memcpy(data, path.data(), path.length());
-        return WriteFdExactly(fd, buf.data(), buf.size());
-    }
-
-    bool SendSend2(std::string_view path, mode_t mode, bool compressed) {
-        if (path.length() > 1024) {
-            Error("SendRequest failed: path too long: %zu", path.length());
-            errno = ENAMETOOLONG;
-            return false;
-        }
-
-        Block buf;
-
-        SyncRequest req;
-        req.id = ID_SEND_V2;
-        req.path_length = path.length();
-
-        syncmsg msg;
-        msg.send_v2_setup.id = ID_SEND_V2;
-        msg.send_v2_setup.mode = mode;
-        msg.send_v2_setup.flags = compressed ? kSyncFlagBrotli : kSyncFlagNone;
-
-        buf.resize(sizeof(SyncRequest) + path.length() + sizeof(msg.send_v2_setup));
-
-        void* p = buf.data();
-
-        p = mempcpy(p, &req, sizeof(SyncRequest));
-        p = mempcpy(p, path.data(), path.length());
-        p = mempcpy(p, &msg.send_v2_setup, sizeof(msg.send_v2_setup));
-
-        return WriteFdExactly(fd, buf.data(), buf.size());
-    }
-
-    bool SendRecv2(const std::string& path) {
-        if (path.length() > 1024) {
-            Error("SendRequest failed: path too long: %zu", path.length());
-            errno = ENAMETOOLONG;
-            return false;
-        }
-
-        Block buf;
-
-        SyncRequest req;
-        req.id = ID_RECV_V2;
-        req.path_length = path.length();
-
-        syncmsg msg;
-        msg.recv_v2_setup.id = ID_RECV_V2;
-        msg.recv_v2_setup.flags = kSyncFlagBrotli;
-
-        buf.resize(sizeof(SyncRequest) + path.length() + sizeof(msg.recv_v2_setup));
-
-        void* p = buf.data();
-
-        p = mempcpy(p, &req, sizeof(SyncRequest));
-        p = mempcpy(p, path.data(), path.length());
-        p = mempcpy(p, &msg.recv_v2_setup, sizeof(msg.recv_v2_setup));
-
-        return WriteFdExactly(fd, buf.data(), buf.size());
-    }
-
-    bool SendStat(const std::string& path) {
-        if (!have_stat_v2_) {
-            errno = ENOTSUP;
-            return false;
-        }
-        return SendRequest(ID_STAT_V2, path);
-    }
-
-    bool SendLstat(const std::string& path) {
-        if (have_stat_v2_) {
-            return SendRequest(ID_LSTAT_V2, path);
-        } else {
-            return SendRequest(ID_LSTAT_V1, path);
-        }
-    }
-
-    bool FinishStat(struct stat* st) {
-        syncmsg msg;
-
-        memset(st, 0, sizeof(*st));
-        if (have_stat_v2_) {
-            if (!ReadFdExactly(fd.get(), &msg.stat_v2, sizeof(msg.stat_v2))) {
-                PLOG(FATAL) << "protocol fault: failed to read stat response";
-            }
-
-            if (msg.stat_v2.id != ID_LSTAT_V2 && msg.stat_v2.id != ID_STAT_V2) {
-                PLOG(FATAL) << "protocol fault: stat response has wrong message id: "
-                            << msg.stat_v2.id;
-            }
-
-            if (msg.stat_v2.error != 0) {
-                errno = errno_from_wire(msg.stat_v2.error);
-                return false;
-            }
-
-            st->st_dev = msg.stat_v2.dev;
-            st->st_ino = msg.stat_v2.ino;
-            st->st_mode = msg.stat_v2.mode;
-            st->st_nlink = msg.stat_v2.nlink;
-            st->st_uid = msg.stat_v2.uid;
-            st->st_gid = msg.stat_v2.gid;
-            st->st_size = msg.stat_v2.size;
-            st->st_atime = msg.stat_v2.atime;
-            st->st_mtime = msg.stat_v2.mtime;
-            st->st_ctime = msg.stat_v2.ctime;
-            return true;
-        } else {
-            if (!ReadFdExactly(fd.get(), &msg.stat_v1, sizeof(msg.stat_v1))) {
-                PLOG(FATAL) << "protocol fault: failed to read stat response";
-            }
-
-            if (msg.stat_v1.id != ID_LSTAT_V1) {
-                LOG(FATAL) << "protocol fault: stat response has wrong message id: "
-                           << msg.stat_v1.id;
-            }
-
-            if (msg.stat_v1.mode == 0 && msg.stat_v1.size == 0 && msg.stat_v1.mtime == 0) {
-                // There's no way for us to know what the error was.
-                errno = ENOPROTOOPT;
-                return false;
-            }
-
-            st->st_mode = msg.stat_v1.mode;
-            st->st_size = msg.stat_v1.size;
-            st->st_ctime = msg.stat_v1.mtime;
-            st->st_mtime = msg.stat_v1.mtime;
-        }
-
-        return true;
-    }
-
-    bool SendLs(const std::string& path) {
-        return SendRequest(have_ls_v2_ ? ID_LIST_V2 : ID_LIST_V1, path);
-    }
-
-  private:
-    template <bool v2>
-    static bool FinishLsImpl(borrowed_fd fd, const std::function<sync_ls_cb>& callback) {
-        using dent_type =
-                std::conditional_t<v2, decltype(syncmsg::dent_v2), decltype(syncmsg::dent_v1)>;
-
-        while (true) {
-            dent_type dent;
-            if (!ReadFdExactly(fd, &dent, sizeof(dent))) return false;
-
-            uint32_t expected_id = v2 ? ID_DENT_V2 : ID_DENT_V1;
-            if (dent.id == ID_DONE) return true;
-            if (dent.id != expected_id) return false;
-
-            // Maximum length of a file name excluding null terminator (NAME_MAX) on Linux is 255.
-            char buf[256];
-            size_t len = dent.namelen;
-            if (len > 255) return false;
-
-            if (!ReadFdExactly(fd, buf, len)) return false;
-            buf[len] = 0;
-
-            callback(dent.mode, dent.size, dent.mtime, buf);
-        }
-    }
-
-  public:
-    bool FinishLs(const std::function<sync_ls_cb>& callback) {
-        if (have_ls_v2_) {
-            return FinishLsImpl<true>(this->fd, callback);
-        } else {
-            return FinishLsImpl<false>(this->fd, callback);
-        }
-    }
-
-    // Sending header, payload, and footer in a single write makes a huge
-    // difference to "adb sync" performance.
-    bool SendSmallFile(const std::string& path, mode_t mode, const std::string& lpath,
-                       const std::string& rpath, unsigned mtime, const char* data,
-                       size_t data_length) {
-        std::string path_and_mode = android::base::StringPrintf("%s,%d", path.c_str(), mode);
-        if (path_and_mode.length() > 1024) {
-            Error("SendSmallFile failed: path too long: %zu", path_and_mode.length());
-            errno = ENAMETOOLONG;
-            return false;
-        }
-
-        std::vector<char> buf(sizeof(SyncRequest) + path_and_mode.length() + sizeof(SyncRequest) +
-                              data_length + sizeof(SyncRequest));
-        char* p = &buf[0];
-
-        SyncRequest* req_send = reinterpret_cast<SyncRequest*>(p);
-        req_send->id = ID_SEND_V1;
-        req_send->path_length = path_and_mode.length();
-        p += sizeof(SyncRequest);
-        memcpy(p, path_and_mode.data(), path_and_mode.size());
-        p += path_and_mode.length();
-
-        SyncRequest* req_data = reinterpret_cast<SyncRequest*>(p);
-        req_data->id = ID_DATA;
-        req_data->path_length = data_length;
-        p += sizeof(SyncRequest);
-        memcpy(p, data, data_length);
-        p += data_length;
-
-        SyncRequest* req_done = reinterpret_cast<SyncRequest*>(p);
-        req_done->id = ID_DONE;
-        req_done->path_length = mtime;
-        p += sizeof(SyncRequest);
-
-        WriteOrDie(lpath, rpath, &buf[0], (p - &buf[0]));
-
-        RecordFileSent(lpath, rpath);
-        RecordBytesTransferred(data_length);
-        ReportProgress(rpath, data_length, data_length);
-        return true;
-    }
-
-    bool SendLargeFileCompressed(const std::string& path, mode_t mode, const std::string& lpath,
-                                 const std::string& rpath, unsigned mtime) {
-        if (!SendSend2(path, mode, true)) {
-            Error("failed to send ID_SEND_V2 message '%s': %s", path.c_str(), strerror(errno));
-            return false;
-        }
-
-        struct stat st;
-        if (stat(lpath.c_str(), &st) == -1) {
-            Error("cannot stat '%s': %s", lpath.c_str(), strerror(errno));
-            return false;
-        }
-
-        uint64_t total_size = st.st_size;
-        uint64_t bytes_copied = 0;
-
-        unique_fd lfd(adb_open(lpath.c_str(), O_RDONLY | O_CLOEXEC));
-        if (lfd < 0) {
-            Error("opening '%s' locally failed: %s", lpath.c_str(), strerror(errno));
-            return false;
-        }
-
-        syncsendbuf sbuf;
-        sbuf.id = ID_DATA;
-
-        BrotliEncoder<SYNC_DATA_MAX> encoder;
-        bool sending = true;
-        while (sending) {
-            Block input(SYNC_DATA_MAX);
-            int r = adb_read(lfd.get(), input.data(), input.size());
-            if (r < 0) {
-                Error("reading '%s' locally failed: %s", lpath.c_str(), strerror(errno));
-                return false;
-            }
-
-            if (r == 0) {
-                encoder.Finish();
-            } else {
-                input.resize(r);
-                encoder.Append(std::move(input));
-                RecordBytesTransferred(r);
-                bytes_copied += r;
-                ReportProgress(rpath, bytes_copied, total_size);
-            }
-
-            while (true) {
-                Block output;
-                BrotliEncodeResult result = encoder.Encode(&output);
-                if (result == BrotliEncodeResult::Error) {
-                    Error("compressing '%s' locally failed", lpath.c_str());
-                    return false;
-                }
-
-                if (!output.empty()) {
-                    sbuf.size = output.size();
-                    memcpy(sbuf.data, output.data(), output.size());
-                    WriteOrDie(lpath, rpath, &sbuf, sizeof(SyncRequest) + output.size());
-                }
-
-                if (result == BrotliEncodeResult::Done) {
-                    sending = false;
-                    break;
-                } else if (result == BrotliEncodeResult::NeedInput) {
-                    break;
-                } else if (result == BrotliEncodeResult::MoreOutput) {
-                    continue;
-                }
-            }
-        }
-
-        syncmsg msg;
-        msg.data.id = ID_DONE;
-        msg.data.size = mtime;
-        RecordFileSent(lpath, rpath);
-        return WriteOrDie(lpath, rpath, &msg.data, sizeof(msg.data));
-    }
-
-    bool SendLargeFile(const std::string& path, mode_t mode, const std::string& lpath,
-                       const std::string& rpath, unsigned mtime, bool compressed) {
-        if (compressed && HaveSendRecv2Brotli()) {
-            return SendLargeFileCompressed(path, mode, lpath, rpath, mtime);
-        }
-
-        std::string path_and_mode = android::base::StringPrintf("%s,%d", path.c_str(), mode);
-        if (!SendRequest(ID_SEND_V1, path_and_mode)) {
-            Error("failed to send ID_SEND_V1 message '%s': %s", path_and_mode.c_str(),
-                  strerror(errno));
-            return false;
-        }
-
-        struct stat st;
-        if (stat(lpath.c_str(), &st) == -1) {
-            Error("cannot stat '%s': %s", lpath.c_str(), strerror(errno));
-            return false;
-        }
-
-        uint64_t total_size = st.st_size;
-        uint64_t bytes_copied = 0;
-
-        unique_fd lfd(adb_open(lpath.c_str(), O_RDONLY | O_CLOEXEC));
-        if (lfd < 0) {
-            Error("opening '%s' locally failed: %s", lpath.c_str(), strerror(errno));
-            return false;
-        }
-
-        syncsendbuf sbuf;
-        sbuf.id = ID_DATA;
-
-        while (true) {
-            int bytes_read = adb_read(lfd, sbuf.data, max);
-            if (bytes_read == -1) {
-                Error("reading '%s' locally failed: %s", lpath.c_str(), strerror(errno));
-                return false;
-            } else if (bytes_read == 0) {
-                break;
-            }
-
-            sbuf.size = bytes_read;
-            WriteOrDie(lpath, rpath, &sbuf, sizeof(SyncRequest) + bytes_read);
-
-            RecordBytesTransferred(bytes_read);
-            bytes_copied += bytes_read;
-            ReportProgress(rpath, bytes_copied, total_size);
-        }
-
-        syncmsg msg;
-        msg.data.id = ID_DONE;
-        msg.data.size = mtime;
-        RecordFileSent(lpath, rpath);
-        return WriteOrDie(lpath, rpath, &msg.data, sizeof(msg.data));
-    }
-
-    bool ReportCopyFailure(const std::string& from, const std::string& to, const syncmsg& msg) {
-        std::vector<char> buf(msg.status.msglen + 1);
-        if (!ReadFdExactly(fd, &buf[0], msg.status.msglen)) {
-            Error("failed to copy '%s' to '%s'; failed to read reason (!): %s", from.c_str(),
-                  to.c_str(), strerror(errno));
-            return false;
-        }
-        buf[msg.status.msglen] = 0;
-        Error("failed to copy '%s' to '%s': remote %s", from.c_str(), to.c_str(), &buf[0]);
-        return false;
-    }
-
-    void CopyDone() { deferred_acknowledgements_.pop_front(); }
-
-    void ReportDeferredCopyFailure(const std::string& msg) {
-        auto& [from, to] = deferred_acknowledgements_.front();
-        Error("failed to copy '%s' to '%s': remote %s", from.c_str(), to.c_str(), msg.c_str());
-        deferred_acknowledgements_.pop_front();
-    }
-
-    bool ReadAcknowledgements(bool read_all = false) {
-        // We need to read enough such that adbd's intermediate socket's write buffer can't be
-        // full. The default buffer on Linux is 212992 bytes, but there's 576 bytes of bookkeeping
-        // overhead per write. The worst case scenario is a continuous string of failures, since
-        // each logical packet is divided into two writes. If our packet size if conservatively 512
-        // bytes long, this leaves us with space for 128 responses.
-        constexpr size_t max_deferred_acks = 128;
-        auto& buf = acknowledgement_buffer_;
-        adb_pollfd pfd = {.fd = fd.get(), .events = POLLIN};
-        while (!deferred_acknowledgements_.empty()) {
-            bool should_block = read_all || deferred_acknowledgements_.size() >= max_deferred_acks;
-
-            ssize_t rc = adb_poll(&pfd, 1, should_block ? -1 : 0);
-            if (rc == 0) {
-                CHECK(!should_block);
-                return true;
-            }
-
-            if (acknowledgement_buffer_.size() < sizeof(sync_status)) {
-                const ssize_t header_bytes_left = sizeof(sync_status) - buf.size();
-                ssize_t rc = adb_read(fd, buf.end(), header_bytes_left);
-                if (rc <= 0) {
-                    Error("failed to read copy response");
-                    return false;
-                }
-
-                buf.resize(buf.size() + rc);
-                if (rc != header_bytes_left) {
-                    // Early exit if we run out of data in the socket.
-                    return true;
-                }
-
-                if (!should_block) {
-                    // We don't want to read again yet, because the socket might be empty.
-                    continue;
-                }
-            }
-
-            auto* hdr = reinterpret_cast<sync_status*>(buf.data());
-            if (hdr->id == ID_OKAY) {
-                buf.resize(0);
-                if (hdr->msglen != 0) {
-                    Error("received ID_OKAY with msg_len (%" PRIu32 " != 0", hdr->msglen);
-                    return false;
-                }
-                CopyDone();
-                continue;
-            } else if (hdr->id != ID_FAIL) {
-                Error("unexpected response from daemon: id = %#" PRIx32, hdr->id);
-                return false;
-            } else if (hdr->msglen > SYNC_DATA_MAX) {
-                Error("too-long message length from daemon: msglen = %" PRIu32, hdr->msglen);
-                return false;
-            }
-
-            const ssize_t msg_bytes_left = hdr->msglen + sizeof(sync_status) - buf.size();
-            CHECK_GE(msg_bytes_left, 0);
-            if (msg_bytes_left > 0) {
-                ssize_t rc = adb_read(fd, buf.end(), msg_bytes_left);
-                if (rc <= 0) {
-                    Error("failed to read copy failure message");
-                    return false;
-                }
-
-                buf.resize(buf.size() + rc);
-                if (rc != msg_bytes_left) {
-                    if (should_block) {
-                        continue;
-                    } else {
-                        return true;
-                    }
-                }
-
-                std::string msg(buf.begin() + sizeof(sync_status), buf.end());
-                ReportDeferredCopyFailure(msg);
-                buf.resize(0);
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    void Printf(const char* fmt, ...) __attribute__((__format__(__printf__, 2, 3))) {
-        std::string s;
-
-        va_list ap;
-        va_start(ap, fmt);
-        android::base::StringAppendV(&s, fmt, ap);
-        va_end(ap);
-
-        line_printer_.Print(s, LinePrinter::INFO);
-    }
-
-    void Println(const char* fmt, ...) __attribute__((__format__(__printf__, 2, 3))) {
-        std::string s;
-
-        va_list ap;
-        va_start(ap, fmt);
-        android::base::StringAppendV(&s, fmt, ap);
-        va_end(ap);
-
-        line_printer_.Print(s, LinePrinter::INFO);
-        line_printer_.KeepInfoLine();
-    }
-
-    void Error(const char* fmt, ...) __attribute__((__format__(__printf__, 2, 3))) {
-        std::string s = "adb: error: ";
-
-        va_list ap;
-        va_start(ap, fmt);
-        android::base::StringAppendV(&s, fmt, ap);
-        va_end(ap);
-
-        line_printer_.Print(s, LinePrinter::ERROR);
-    }
-
-    void Warning(const char* fmt, ...) __attribute__((__format__(__printf__, 2, 3))) {
-        std::string s = "adb: warning: ";
-
-        va_list ap;
-        va_start(ap, fmt);
-        android::base::StringAppendV(&s, fmt, ap);
-        va_end(ap);
-
-        line_printer_.Print(s, LinePrinter::WARNING);
-    }
-
-    void ComputeExpectedTotalBytes(const std::vector<copyinfo>& file_list) {
-        current_ledger_.bytes_expected = 0;
-        for (const copyinfo& ci : file_list) {
-            // Unfortunately, this doesn't work for symbolic links, because we'll copy the
-            // target of the link rather than just creating a link. (But ci.size is the link size.)
-            if (!ci.skip) current_ledger_.bytes_expected += ci.size;
-        }
-        current_ledger_.expect_multiple_files = true;
-    }
-
-    void SetExpectedTotalBytes(uint64_t expected_total_bytes) {
-        current_ledger_.bytes_expected = expected_total_bytes;
-        current_ledger_.expect_multiple_files = false;
-    }
-
-    // TODO: add a char[max] buffer here, to replace syncsendbuf...
-    unique_fd fd;
-    size_t max;
-
-  private:
-    std::deque<std::pair<std::string, std::string>> deferred_acknowledgements_;
-    Block acknowledgement_buffer_;
-    FeatureSet features_;
-    bool have_stat_v2_;
-    bool have_ls_v2_;
-    bool have_sendrecv_v2_;
-    bool have_sendrecv_v2_brotli_;
-
-    TransferLedger global_ledger_;
-    TransferLedger current_ledger_;
-    LinePrinter line_printer_;
-
-    bool SendQuit() {
-        return SendRequest(ID_QUIT, ""); // TODO: add a SendResponse?
-    }
-
-    bool WriteOrDie(const std::string& from, const std::string& to, const void* data,
-                    size_t data_length) {
-        if (!WriteFdExactly(fd, data, data_length)) {
-            if (errno == ECONNRESET) {
-                // Assume adbd told us why it was closing the connection, and
-                // try to read failure reason from adbd.
-                syncmsg msg;
-                if (!ReadFdExactly(fd, &msg.status, sizeof(msg.status))) {
-                    Error("failed to copy '%s' to '%s': no response: %s", from.c_str(), to.c_str(),
-                          strerror(errno));
-                } else if (msg.status.id != ID_FAIL) {
-                    Error("failed to copy '%s' to '%s': not ID_FAIL: %d", from.c_str(), to.c_str(),
-                          msg.status.id);
-                } else {
-                    ReportCopyFailure(from, to, msg);
-                }
-            } else {
-                Error("%zu-byte write failed: %s", data_length, strerror(errno));
-            }
-            _exit(1);
-        }
-        return true;
-    }
-};
-
-static bool sync_ls(SyncConnection& sc, const std::string& path,
-                    const std::function<sync_ls_cb>& func) {
-    return sc.SendLs(path) && sc.FinishLs(func);
-}
-
-static bool sync_stat(SyncConnection& sc, const std::string& path, struct stat* st) {
-    return sc.SendStat(path) && sc.FinishStat(st);
-}
-
-static bool sync_lstat(SyncConnection& sc, const std::string& path, struct stat* st) {
-    return sc.SendLstat(path) && sc.FinishStat(st);
-}
-
-static bool sync_stat_fallback(SyncConnection& sc, const std::string& path, struct stat* st) {
-    if (sync_stat(sc, path, st)) {
-        return true;
-    }
-
-    if (errno != ENOTSUP) {
-        return false;
-    }
-
-    // Try to emulate the parts we can when talking to older adbds.
-    bool lstat_result = sync_lstat(sc, path, st);
-    if (!lstat_result) {
-        return false;
-    }
-
-    if (S_ISLNK(st->st_mode)) {
-        // If the target is a symlink, figure out whether it's a file or a directory.
-        // Also, zero out the st_size field, since no one actually cares what the path length is.
-        st->st_size = 0;
-        std::string dir_path = path;
-        dir_path.push_back('/');
-        struct stat tmp_st;
-
-        st->st_mode &= ~S_IFMT;
-        if (sync_lstat(sc, dir_path, &tmp_st)) {
-            st->st_mode |= S_IFDIR;
-        } else {
-            st->st_mode |= S_IFREG;
-        }
-    }
-    return true;
-}
-
-static bool sync_send(SyncConnection& sc, const std::string& lpath, const std::string& rpath,
-                      unsigned mtime, mode_t mode, bool sync, bool compressed) {
-    if (sync) {
-        struct stat st;
-        if (sync_lstat(sc, rpath, &st)) {
-            if (st.st_mtime == static_cast<time_t>(mtime)) {
-                sc.RecordFilesSkipped(1);
-                return true;
-            }
-        }
-    }
-
-    if (S_ISLNK(mode)) {
-#if !defined(_WIN32)
-        char buf[PATH_MAX];
-        ssize_t data_length = readlink(lpath.c_str(), buf, PATH_MAX - 1);
-        if (data_length == -1) {
-            sc.Error("readlink '%s' failed: %s", lpath.c_str(), strerror(errno));
-            return false;
-        }
-        buf[data_length++] = '\0';
-
-        if (!sc.SendSmallFile(rpath, mode, lpath, rpath, mtime, buf, data_length)) {
-            return false;
-        }
-        return sc.ReadAcknowledgements();
-#endif
-    }
-
-    struct stat st;
-    if (stat(lpath.c_str(), &st) == -1) {
-        sc.Error("failed to stat local file '%s': %s", lpath.c_str(), strerror(errno));
-        return false;
-    }
-    if (st.st_size < SYNC_DATA_MAX) {
-        std::string data;
-        if (!android::base::ReadFileToString(lpath, &data, true)) {
-            sc.Error("failed to read all of '%s': %s", lpath.c_str(), strerror(errno));
-            return false;
-        }
-        if (!sc.SendSmallFile(rpath, mode, lpath, rpath, mtime, data.data(), data.size())) {
-            return false;
-        }
-    } else {
-        if (!sc.SendLargeFile(rpath, mode, lpath, rpath, mtime, compressed)) {
-            return false;
-        }
-    }
-    return sc.ReadAcknowledgements();
-}
-
-static bool sync_recv_v1(SyncConnection& sc, const char* rpath, const char* lpath, const char* name,
-                         uint64_t expected_size) {
-    if (!sc.SendRequest(ID_RECV_V1, rpath)) return false;
-
-    adb_unlink(lpath);
-    unique_fd lfd(adb_creat(lpath, 0644));
-    if (lfd < 0) {
-        sc.Error("cannot create '%s': %s", lpath, strerror(errno));
-        return false;
-    }
-
-    uint64_t bytes_copied = 0;
-    while (true) {
-        syncmsg msg;
-        if (!ReadFdExactly(sc.fd, &msg.data, sizeof(msg.data))) {
-            adb_unlink(lpath);
-            return false;
-        }
-
-        if (msg.data.id == ID_DONE) break;
-
-        if (msg.data.id != ID_DATA) {
-            adb_unlink(lpath);
-            sc.ReportCopyFailure(rpath, lpath, msg);
-            return false;
-        }
-
-        if (msg.data.size > sc.max) {
-            sc.Error("msg.data.size too large: %u (max %zu)", msg.data.size, sc.max);
-            adb_unlink(lpath);
-            return false;
-        }
-
-        char buffer[SYNC_DATA_MAX];
-        if (!ReadFdExactly(sc.fd, buffer, msg.data.size)) {
-            adb_unlink(lpath);
-            return false;
-        }
-
-        if (!WriteFdExactly(lfd, buffer, msg.data.size)) {
-            sc.Error("cannot write '%s': %s", lpath, strerror(errno));
-            adb_unlink(lpath);
-            return false;
-        }
-
-        bytes_copied += msg.data.size;
-
-        sc.RecordBytesTransferred(msg.data.size);
-        sc.ReportProgress(name != nullptr ? name : rpath, bytes_copied, expected_size);
-    }
-
-    sc.RecordFilesTransferred(1);
-    return true;
-}
-
-static bool sync_recv_v2(SyncConnection& sc, const char* rpath, const char* lpath, const char* name,
-                         uint64_t expected_size) {
-    if (!sc.SendRecv2(rpath)) return false;
-
-    adb_unlink(lpath);
-    unique_fd lfd(adb_creat(lpath, 0644));
-    if (lfd < 0) {
-        sc.Error("cannot create '%s': %s", lpath, strerror(errno));
-        return false;
-    }
-
-    uint64_t bytes_copied = 0;
-
-    Block buffer(SYNC_DATA_MAX);
-    BrotliDecoder decoder(std::span(buffer.data(), buffer.size()));
-    bool reading = true;
-    while (reading) {
-        syncmsg msg;
-        if (!ReadFdExactly(sc.fd, &msg.data, sizeof(msg.data))) {
-            adb_unlink(lpath);
-            return false;
-        }
-
-        if (msg.data.id == ID_DONE) {
-            adb_unlink(lpath);
-            sc.Error("unexpected ID_DONE");
-            return false;
-        }
-
-        if (msg.data.id != ID_DATA) {
-            adb_unlink(lpath);
-            sc.ReportCopyFailure(rpath, lpath, msg);
-            return false;
-        }
-
-        if (msg.data.size > sc.max) {
-            sc.Error("msg.data.size too large: %u (max %zu)", msg.data.size, sc.max);
-            adb_unlink(lpath);
-            return false;
-        }
-
-        Block block(msg.data.size);
-        if (!ReadFdExactly(sc.fd, block.data(), msg.data.size)) {
-            adb_unlink(lpath);
-            return false;
-        }
-        decoder.Append(std::move(block));
-
-        while (true) {
-            std::span<char> output;
-            BrotliDecodeResult result = decoder.Decode(&output);
-
-            if (result == BrotliDecodeResult::Error) {
-                sc.Error("decompress failed");
-                adb_unlink(lpath);
-                return false;
-            }
-
-            if (!output.empty()) {
-                if (!WriteFdExactly(lfd, output.data(), output.size())) {
-                    sc.Error("cannot write '%s': %s", lpath, strerror(errno));
-                    adb_unlink(lpath);
-                    return false;
-                }
-            }
-
-            bytes_copied += output.size();
-
-            sc.RecordBytesTransferred(msg.data.size);
-            sc.ReportProgress(name != nullptr ? name : rpath, bytes_copied, expected_size);
-
-            if (result == BrotliDecodeResult::NeedInput) {
-                break;
-            } else if (result == BrotliDecodeResult::MoreOutput) {
-                continue;
-            } else if (result == BrotliDecodeResult::Done) {
-                reading = false;
-                break;
-            } else {
-                LOG(FATAL) << "invalid BrotliDecodeResult: " << static_cast<int>(result);
-            }
-        }
-    }
-
-    syncmsg msg;
-    if (!ReadFdExactly(sc.fd, &msg.data, sizeof(msg.data))) {
-        sc.Error("failed to read ID_DONE");
-        return false;
-    }
-
-    if (msg.data.id != ID_DONE) {
-        sc.Error("unexpected message after transfer: id = %d (expected ID_DONE)", msg.data.id);
-        return false;
-    }
-
-    sc.RecordFilesTransferred(1);
-    return true;
-}
-
-static bool sync_recv(SyncConnection& sc, const char* rpath, const char* lpath, const char* name,
-                      uint64_t expected_size, bool compressed) {
-    if (sc.HaveSendRecv2() && compressed) {
-        return sync_recv_v2(sc, rpath, lpath, name, expected_size);
-    } else {
-        return sync_recv_v1(sc, rpath, lpath, name, expected_size);
-    }
-}
-
-bool do_sync_ls(const char* path) {
-    SyncConnection sc;
-    if (!sc.IsValid()) return false;
-
-    return sync_ls(sc, path, [](unsigned mode, uint64_t size, uint64_t time, const char* name) {
-        printf("%08x %08" PRIx64 " %08" PRIx64 " %s\n", mode, size, time, name);
-    });
-}
-
-static bool IsDotOrDotDot(const char* name) {
-    return name[0] == '.' && (name[1] == '\0' || (name[1] == '.' && name[2] == '\0'));
-}
-
-static bool local_build_list(SyncConnection& sc, std::vector<copyinfo>* file_list,
-                             std::vector<std::string>* directory_list, const std::string& lpath,
-                             const std::string& rpath) {
-    std::vector<copyinfo> dirlist;
-    std::unique_ptr<DIR, int (*)(DIR*)> dir(opendir(lpath.c_str()), closedir);
-    if (!dir) {
-        sc.Error("cannot open '%s': %s", lpath.c_str(), strerror(errno));
-        return false;
-    }
-
-    bool empty_dir = true;
-    dirent* de;
-    while ((de = readdir(dir.get()))) {
-        if (IsDotOrDotDot(de->d_name)) {
-            continue;
-        }
-
-        empty_dir = false;
-        std::string stat_path = lpath + de->d_name;
-
-        struct stat st;
-        if (lstat(stat_path.c_str(), &st) == -1) {
-            sc.Error("cannot lstat '%s': %s", stat_path.c_str(),
-                     strerror(errno));
-            continue;
-        }
-
-        copyinfo ci(lpath, rpath, de->d_name, st.st_mode);
-        if (S_ISDIR(st.st_mode)) {
-            dirlist.push_back(ci);
-        } else {
-            if (!should_push_file(st.st_mode)) {
-                sc.Warning("skipping special file '%s' (mode = 0o%o)", lpath.c_str(), st.st_mode);
-                ci.skip = true;
-            }
-            ci.time = st.st_mtime;
-            ci.size = st.st_size;
-            file_list->push_back(ci);
-        }
-    }
-
-    // Close this directory and recurse.
-    dir.reset();
-
-    for (const copyinfo& ci : dirlist) {
-        directory_list->push_back(ci.rpath);
-        local_build_list(sc, file_list, directory_list, ci.lpath, ci.rpath);
-    }
-
-    return true;
-}
-
-// dirname("//foo") returns "//", so we can't do the obvious `path == "/"`.
-static bool is_root_dir(std::string_view path) {
-    for (char c : path) {
-        if (c != '/') {
-            return false;
-        }
-    }
-    return true;
-}
-
-static bool copy_local_dir_remote(SyncConnection& sc, std::string lpath, std::string rpath,
-                                  bool check_timestamps, bool list_only, bool compressed) {
-    sc.NewTransfer();
-
-    // Make sure that both directory paths end in a slash.
-    // Both paths are known to be nonempty, so we don't need to check.
-    ensure_trailing_separators(lpath, rpath);
-
-    // Recursively build the list of files to copy.
-    std::vector<copyinfo> file_list;
-    std::vector<std::string> directory_list;
-
-    for (std::string path = rpath; !is_root_dir(path); path = android::base::Dirname(path)) {
-        directory_list.push_back(path);
-    }
-    std::reverse(directory_list.begin(), directory_list.end());
-
-    int skipped = 0;
-    if (!local_build_list(sc, &file_list, &directory_list, lpath, rpath)) {
-        return false;
-    }
-
-    // b/110953234:
-    // P shipped with a bug that causes directory creation as a side-effect of a push to fail.
-    // Work around this by explicitly doing a mkdir via shell.
-    //
-    // Devices that don't support shell_v2 are unhappy if we try to send a too-long packet to them,
-    // but they're not affected by this bug, so only apply the workaround if we have shell_v2.
-    //
-    // TODO(b/25457350): We don't preserve permissions on directories.
-    // TODO: Find all of the leaves and `mkdir -p` them instead?
-    if (!CanUseFeature(sc.Features(), kFeatureFixedPushMkdir) &&
-        CanUseFeature(sc.Features(), kFeatureShell2)) {
-        SilentStandardStreamsCallbackInterface cb;
-        std::string cmd = "mkdir";
-        for (const auto& dir : directory_list) {
-            std::string escaped_path = escape_arg(dir);
-            if (escaped_path.size() > 16384) {
-                // Somewhat arbitrarily limit that probably won't ever happen.
-                sc.Error("path too long: %s", escaped_path.c_str());
-                return false;
-            }
-
-            // The maximum should be 64kiB, but that's not including other stuff that gets tacked
-            // onto the command line, so let's be a bit conservative.
-            if (cmd.size() + escaped_path.size() > 32768) {
-                // Dispatch the command, ignoring failure (since the directory might already exist).
-                send_shell_command(cmd, false, &cb);
-                cmd = "mkdir";
-            }
-            cmd += " ";
-            cmd += escaped_path;
-        }
-
-        if (cmd != "mkdir") {
-            send_shell_command(cmd, false, &cb);
-        }
-    }
-
-    if (check_timestamps) {
-        for (const copyinfo& ci : file_list) {
-            if (!sc.SendLstat(ci.rpath)) {
-                sc.Error("failed to send lstat");
-                return false;
-            }
-        }
-        for (copyinfo& ci : file_list) {
-            struct stat st;
-            if (sc.FinishStat(&st)) {
-                if (st.st_size == static_cast<off_t>(ci.size) && st.st_mtime == ci.time) {
-                    ci.skip = true;
-                }
-            }
-        }
-    }
-
-    sc.ComputeExpectedTotalBytes(file_list);
-
-    for (const copyinfo& ci : file_list) {
-        if (!ci.skip) {
-            if (list_only) {
-                sc.Println("would push: %s -> %s", ci.lpath.c_str(), ci.rpath.c_str());
-            } else {
-                if (!sync_send(sc, ci.lpath, ci.rpath, ci.time, ci.mode, false, compressed)) {
-                    return false;
-                }
-            }
-        } else {
-            skipped++;
-        }
-    }
-
-    sc.RecordFilesSkipped(skipped);
-    bool success = sc.ReadAcknowledgements(true);
-    sc.ReportTransferRate(lpath, TransferDirection::push);
-    return success;
-}
-
-bool do_sync_push(const std::vector<const char*>& srcs, const char* dst, bool sync,
-                  bool compressed) {
-    SyncConnection sc;
-    if (!sc.IsValid()) return false;
-
-    bool success = true;
-    bool dst_exists;
-    bool dst_isdir;
-
-    struct stat st;
-    if (sync_stat_fallback(sc, dst, &st)) {
-        dst_exists = true;
-        dst_isdir = S_ISDIR(st.st_mode);
-    } else {
-        if (errno == ENOENT || errno == ENOPROTOOPT) {
-            dst_exists = false;
-            dst_isdir = false;
-        } else {
-            sc.Error("stat failed when trying to push to %s: %s", dst, strerror(errno));
-            return false;
-        }
-    }
-
-    if (!dst_isdir) {
-        if (srcs.size() > 1) {
-            sc.Error("target '%s' is not a directory", dst);
-            return false;
-        } else {
-            size_t dst_len = strlen(dst);
-
-            // A path that ends with a slash doesn't have to be a directory if
-            // it doesn't exist yet.
-            if (dst[dst_len - 1] == '/' && dst_exists) {
-                sc.Error("failed to access '%s': Not a directory", dst);
-                return false;
-            }
-        }
-    }
-
-    for (const char* src_path : srcs) {
-        const char* dst_path = dst;
-        struct stat st;
-        if (stat(src_path, &st) == -1) {
-            sc.Error("cannot stat '%s': %s", src_path, strerror(errno));
-            success = false;
-            continue;
-        }
-
-        if (S_ISDIR(st.st_mode)) {
-            std::string dst_dir = dst;
-
-            // If the destination path existed originally, the source directory
-            // should be copied as a child of the destination.
-            if (dst_exists) {
-                if (!dst_isdir) {
-                    sc.Error("target '%s' is not a directory", dst);
-                    return false;
-                }
-                // dst is a POSIX path, so we don't want to use the sysdeps
-                // helpers here.
-                if (dst_dir.back() != '/') {
-                    dst_dir.push_back('/');
-                }
-                dst_dir.append(android::base::Basename(src_path));
-            }
-
-            success &= copy_local_dir_remote(sc, src_path, dst_dir, sync, false, compressed);
-            continue;
-        } else if (!should_push_file(st.st_mode)) {
-            sc.Warning("skipping special file '%s' (mode = 0o%o)", src_path, st.st_mode);
-            continue;
-        }
-
-        std::string path_holder;
-        if (dst_isdir) {
-            // If we're copying a local file to a remote directory,
-            // we really want to copy to remote_dir + "/" + local_filename.
-            path_holder = dst_path;
-            if (path_holder.back() != '/') {
-                path_holder.push_back('/');
-            }
-            path_holder += android::base::Basename(src_path);
-            dst_path = path_holder.c_str();
-        }
-
-        sc.NewTransfer();
-        sc.SetExpectedTotalBytes(st.st_size);
-        success &= sync_send(sc, src_path, dst_path, st.st_mtime, st.st_mode, sync, compressed);
-        sc.ReportTransferRate(src_path, TransferDirection::push);
-    }
-
-    success &= sc.ReadAcknowledgements(true);
-    sc.ReportOverallTransferRate(TransferDirection::push);
-    return success;
-}
-
-static bool remote_build_list(SyncConnection& sc, std::vector<copyinfo>* file_list,
-                              const std::string& rpath, const std::string& lpath) {
-    std::vector<copyinfo> dirlist;
-    std::vector<copyinfo> linklist;
-
-    // Add an entry for the current directory to ensure it gets created before pulling its contents.
-    copyinfo ci(android::base::Dirname(lpath), android::base::Dirname(rpath),
-                android::base::Basename(lpath), S_IFDIR);
-    file_list->push_back(ci);
-
-    // Put the files/dirs in rpath on the lists.
-    auto callback = [&](unsigned mode, uint64_t size, uint64_t time, const char* name) {
-        if (IsDotOrDotDot(name)) {
-            return;
-        }
-
-        copyinfo ci(lpath, rpath, name, mode);
-        if (S_ISDIR(mode)) {
-            dirlist.push_back(ci);
-        } else if (S_ISLNK(mode)) {
-            linklist.push_back(ci);
-        } else {
-            if (!should_pull_file(ci.mode)) {
-                sc.Warning("skipping special file '%s' (mode = 0o%o)", ci.rpath.c_str(), ci.mode);
-                ci.skip = true;
-            }
-            ci.time = time;
-            ci.size = size;
-            file_list->push_back(ci);
-        }
-    };
-
-    if (!sync_ls(sc, rpath.c_str(), callback)) {
-        return false;
-    }
-
-    // Check each symlink we found to see whether it's a file or directory.
-    for (copyinfo& link_ci : linklist) {
-        struct stat st;
-        if (!sync_stat_fallback(sc, link_ci.rpath.c_str(), &st)) {
-            sc.Warning("stat failed for path %s: %s", link_ci.rpath.c_str(), strerror(errno));
-            continue;
-        }
-
-        if (S_ISDIR(st.st_mode)) {
-            dirlist.emplace_back(std::move(link_ci));
-        } else {
-            file_list->emplace_back(std::move(link_ci));
-        }
-    }
-
-    // Recurse into each directory we found.
-    while (!dirlist.empty()) {
-        copyinfo current = dirlist.back();
-        dirlist.pop_back();
-        if (!remote_build_list(sc, file_list, current.rpath, current.lpath)) {
-            return false;
-        }
-    }
-
-    return true;
-}
-
-static int set_time_and_mode(const std::string& lpath, time_t time,
-                             unsigned int mode) {
-    struct utimbuf times = { time, time };
-    int r1 = utime(lpath.c_str(), &times);
-
-    /* use umask for permissions */
-    mode_t mask = umask(0000);
-    umask(mask);
-    int r2 = chmod(lpath.c_str(), mode & ~mask);
-
-    return r1 ? r1 : r2;
-}
-
-static bool copy_remote_dir_local(SyncConnection& sc, std::string rpath, std::string lpath,
-                                  bool copy_attrs, bool compressed) {
-    sc.NewTransfer();
-
-    // Make sure that both directory paths end in a slash.
-    // Both paths are known to be nonempty, so we don't need to check.
-    ensure_trailing_separators(lpath, rpath);
-
-    // Recursively build the list of files to copy.
-    sc.Printf("pull: building file list...");
-    std::vector<copyinfo> file_list;
-    if (!remote_build_list(sc, &file_list, rpath, lpath)) {
-        return false;
-    }
-
-    sc.ComputeExpectedTotalBytes(file_list);
-
-    int skipped = 0;
-    for (const copyinfo &ci : file_list) {
-        if (!ci.skip) {
-            if (S_ISDIR(ci.mode)) {
-                // Entry is for an empty directory, create it and continue.
-                // TODO(b/25457350): We don't preserve permissions on directories.
-                if (!mkdirs(ci.lpath))  {
-                    sc.Error("failed to create directory '%s': %s",
-                             ci.lpath.c_str(), strerror(errno));
-                    return false;
-                }
-                continue;
-            }
-
-            if (!sync_recv(sc, ci.rpath.c_str(), ci.lpath.c_str(), nullptr, ci.size, compressed)) {
-                return false;
-            }
-
-            if (copy_attrs && set_time_and_mode(ci.lpath, ci.time, ci.mode)) {
-                return false;
-            }
-        } else {
-            skipped++;
-        }
-    }
-
-    sc.RecordFilesSkipped(skipped);
-    sc.ReportTransferRate(rpath, TransferDirection::pull);
-    return true;
-}
-
-bool do_sync_pull(const std::vector<const char*>& srcs, const char* dst, bool copy_attrs,
-                  bool compressed, const char* name) {
-    SyncConnection sc;
-    if (!sc.IsValid()) return false;
-
-    bool success = true;
-    struct stat st;
-    bool dst_exists = true;
-
-    if (stat(dst, &st) == -1) {
-        dst_exists = false;
-
-        // If we're only pulling one path, the destination path might point to
-        // a path that doesn't exist yet.
-        if (srcs.size() == 1 && errno == ENOENT) {
-            // However, its parent must exist.
-            struct stat parent_st;
-            if (stat(android::base::Dirname(dst).c_str(), &parent_st) == -1) {
-                sc.Error("cannot create file/directory '%s': %s", dst, strerror(errno));
-                return false;
-            }
-        } else {
-            sc.Error("failed to access '%s': %s", dst, strerror(errno));
-            return false;
-        }
-    }
-
-    bool dst_isdir = dst_exists && S_ISDIR(st.st_mode);
-    if (!dst_isdir) {
-        if (srcs.size() > 1) {
-            sc.Error("target '%s' is not a directory", dst);
-            return false;
-        } else {
-            size_t dst_len = strlen(dst);
-
-            // A path that ends with a slash doesn't have to be a directory if
-            // it doesn't exist yet.
-            if (adb_is_separator(dst[dst_len - 1]) && dst_exists) {
-                sc.Error("failed to access '%s': Not a directory", dst);
-                return false;
-            }
-        }
-    }
-
-    for (const char* src_path : srcs) {
-        const char* dst_path = dst;
-        struct stat src_st;
-        if (!sync_stat_fallback(sc, src_path, &src_st)) {
-            if (errno == ENOPROTOOPT) {
-                sc.Error("remote object '%s' does not exist", src_path);
-            } else {
-                sc.Error("failed to stat remote object '%s': %s", src_path, strerror(errno));
-            }
-
-            success = false;
-            continue;
-        }
-
-        bool src_isdir = S_ISDIR(src_st.st_mode);
-        if (src_isdir) {
-            std::string dst_dir = dst;
-
-            // If the destination path existed originally, the source directory
-            // should be copied as a child of the destination.
-            if (dst_exists) {
-                if (!dst_isdir) {
-                    sc.Error("target '%s' is not a directory", dst);
-                    return false;
-                }
-                if (!adb_is_separator(dst_dir.back())) {
-                    dst_dir.push_back(OS_PATH_SEPARATOR);
-                }
-                dst_dir.append(android::base::Basename(src_path));
-            }
-
-            success &= copy_remote_dir_local(sc, src_path, dst_dir, copy_attrs, compressed);
-            continue;
-        } else if (!should_pull_file(src_st.st_mode)) {
-            sc.Warning("skipping special file '%s' (mode = 0o%o)", src_path, src_st.st_mode);
-            continue;
-        }
-
-        std::string path_holder;
-        if (dst_isdir) {
-            // If we're copying a remote file to a local directory, we
-            // really want to copy to local_dir + OS_PATH_SEPARATOR +
-            // basename(remote).
-            path_holder = android::base::StringPrintf("%s%c%s", dst_path, OS_PATH_SEPARATOR,
-                                                      android::base::Basename(src_path).c_str());
-            dst_path = path_holder.c_str();
-        }
-
-        sc.NewTransfer();
-        sc.SetExpectedTotalBytes(src_st.st_size);
-        if (!sync_recv(sc, src_path, dst_path, name, src_st.st_size, compressed)) {
-            success = false;
-            continue;
-        }
-
-        if (copy_attrs && set_time_and_mode(dst_path, src_st.st_mtime, src_st.st_mode) != 0) {
-            success = false;
-            continue;
-        }
-        sc.ReportTransferRate(src_path, TransferDirection::pull);
-    }
-
-    sc.ReportOverallTransferRate(TransferDirection::pull);
-    return success;
-}
-
-bool do_sync_sync(const std::string& lpath, const std::string& rpath, bool list_only,
-                  bool compressed) {
-    SyncConnection sc;
-    if (!sc.IsValid()) return false;
-
-    bool success = copy_local_dir_remote(sc, lpath, rpath, true, list_only, compressed);
-    if (!list_only) {
-        sc.ReportOverallTransferRate(TransferDirection::push);
-    }
-    return success;
-}
diff --git a/adb/client/file_sync_client.h b/adb/client/file_sync_client.h
deleted file mode 100644
index de3f192..0000000
--- a/adb/client/file_sync_client.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <string>
-#include <vector>
-
-bool do_sync_ls(const char* path);
-bool do_sync_push(const std::vector<const char*>& srcs, const char* dst, bool sync,
-                  bool compressed);
-bool do_sync_pull(const std::vector<const char*>& srcs, const char* dst, bool copy_attrs,
-                  bool compressed, const char* name = nullptr);
-
-bool do_sync_sync(const std::string& lpath, const std::string& rpath, bool list_only,
-                  bool compressed);
diff --git a/adb/client/incremental.cpp b/adb/client/incremental.cpp
deleted file mode 100644
index c8f69c3..0000000
--- a/adb/client/incremental.cpp
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "incremental.h"
-
-#include "incremental_utils.h"
-
-#include <android-base/file.h>
-#include <android-base/stringprintf.h>
-#include <openssl/base64.h>
-
-#include "adb_client.h"
-#include "adb_utils.h"
-#include "commandline.h"
-#include "sysdeps.h"
-
-using namespace std::literals;
-
-namespace incremental {
-
-using android::base::StringPrintf;
-
-// Read, verify and return the signature bytes. Keeping fd at the position of start of verity tree.
-static std::pair<unique_fd, std::vector<char>> read_signature(Size file_size,
-                                                              std::string signature_file,
-                                                              bool silent) {
-    signature_file += IDSIG;
-
-    struct stat st;
-    if (stat(signature_file.c_str(), &st)) {
-        if (!silent) {
-            fprintf(stderr, "Failed to stat signature file %s. Abort.\n", signature_file.c_str());
-        }
-        return {};
-    }
-
-    unique_fd fd(adb_open(signature_file.c_str(), O_RDONLY));
-    if (fd < 0) {
-        if (!silent) {
-            fprintf(stderr, "Failed to open signature file: %s. Abort.\n", signature_file.c_str());
-        }
-        return {};
-    }
-
-    auto [signature, tree_size] = read_id_sig_headers(fd);
-    if (auto expected = verity_tree_size_for_file(file_size); tree_size != expected) {
-        if (!silent) {
-            fprintf(stderr,
-                    "Verity tree size mismatch in signature file: %s [was %lld, expected %lld].\n",
-                    signature_file.c_str(), (long long)tree_size, (long long)expected);
-        }
-        return {};
-    }
-
-    return {std::move(fd), std::move(signature)};
-}
-
-// Base64-encode signature bytes. Keeping fd at the position of start of verity tree.
-static std::pair<unique_fd, std::string> read_and_encode_signature(Size file_size,
-                                                                   std::string signature_file,
-                                                                   bool silent) {
-    auto [fd, signature] = read_signature(file_size, std::move(signature_file), silent);
-    if (!fd.ok()) {
-        return {};
-    }
-
-    size_t base64_len = 0;
-    if (!EVP_EncodedLength(&base64_len, signature.size())) {
-        if (!silent) {
-            fprintf(stderr, "Fail to estimate base64 encoded length. Abort.\n");
-        }
-        return {};
-    }
-    std::string encoded_signature(base64_len, '\0');
-    encoded_signature.resize(EVP_EncodeBlock((uint8_t*)encoded_signature.data(),
-                                             (const uint8_t*)signature.data(), signature.size()));
-
-    return {std::move(fd), std::move(encoded_signature)};
-}
-
-// Send install-incremental to the device along with properly configured file descriptors in
-// streaming format. Once connection established, send all fs-verity tree bytes.
-static unique_fd start_install(const Files& files, const Args& passthrough_args, bool silent) {
-    std::vector<std::string> command_args{"package", "install-incremental"};
-    command_args.insert(command_args.end(), passthrough_args.begin(), passthrough_args.end());
-
-    for (int i = 0, size = files.size(); i < size; ++i) {
-        const auto& file = files[i];
-
-        struct stat st;
-        if (stat(file.c_str(), &st)) {
-            if (!silent) {
-                fprintf(stderr, "Failed to stat input file %s. Abort.\n", file.c_str());
-            }
-            return {};
-        }
-
-        auto [signature_fd, signature] = read_and_encode_signature(st.st_size, file, silent);
-        if (!signature_fd.ok()) {
-            return {};
-        }
-
-        auto file_desc = StringPrintf("%s:%lld:%d:%s:1", android::base::Basename(file).c_str(),
-                                      (long long)st.st_size, i, signature.c_str());
-        command_args.push_back(std::move(file_desc));
-    }
-
-    std::string error;
-    auto connection_fd = unique_fd(send_abb_exec_command(command_args, &error));
-    if (connection_fd < 0) {
-        if (!silent) {
-            fprintf(stderr, "Failed to run: %s, error: %s\n",
-                    android::base::Join(command_args, " ").c_str(), error.c_str());
-        }
-        return {};
-    }
-
-    return connection_fd;
-}
-
-bool can_install(const Files& files) {
-    for (const auto& file : files) {
-        struct stat st;
-        if (stat(file.c_str(), &st)) {
-            return false;
-        }
-
-        auto [fd, _] = read_signature(st.st_size, file, true);
-        if (!fd.ok()) {
-            return false;
-        }
-    }
-    return true;
-}
-
-std::optional<Process> install(const Files& files, const Args& passthrough_args, bool silent) {
-    auto connection_fd = start_install(files, passthrough_args, silent);
-    if (connection_fd < 0) {
-        if (!silent) {
-            fprintf(stderr, "adb: failed to initiate installation on device.\n");
-        }
-        return {};
-    }
-
-    std::string adb_path = android::base::GetExecutablePath();
-
-    auto osh = adb_get_os_handle(connection_fd.get());
-#ifdef _WIN32
-    auto fd_param = std::to_string(reinterpret_cast<intptr_t>(osh));
-#else /* !_WIN32 a.k.a. Unix */
-    auto fd_param = std::to_string(osh);
-#endif
-
-    // pipe for child process to write output
-    int print_fds[2];
-    if (adb_socketpair(print_fds) != 0) {
-        if (!silent) {
-            fprintf(stderr, "Failed to create socket pair for child to print to parent\n");
-        }
-        return {};
-    }
-    auto [pipe_read_fd, pipe_write_fd] = print_fds;
-    auto pipe_write_fd_param = std::to_string(intptr_t(adb_get_os_handle(pipe_write_fd)));
-    close_on_exec(pipe_read_fd);
-
-    std::vector<std::string> args(std::move(files));
-    args.insert(args.begin(), {"inc-server", fd_param, pipe_write_fd_param});
-    auto child =
-            adb_launch_process(adb_path, std::move(args), {connection_fd.get(), pipe_write_fd});
-    if (!child) {
-        if (!silent) {
-            fprintf(stderr, "adb: failed to fork: %s\n", strerror(errno));
-        }
-        return {};
-    }
-
-    adb_close(pipe_write_fd);
-
-    auto killOnExit = [](Process* p) { p->kill(); };
-    std::unique_ptr<Process, decltype(killOnExit)> serverKiller(&child, killOnExit);
-
-    Result result = wait_for_installation(pipe_read_fd);
-    adb_close(pipe_read_fd);
-
-    if (result == Result::Success) {
-        // adb client exits now but inc-server can continue
-        serverKiller.release();
-    }
-    return child;
-}
-
-Result wait_for_installation(int read_fd) {
-    static constexpr int maxMessageSize = 256;
-    std::vector<char> child_stdout(CHUNK_SIZE);
-    int bytes_read;
-    int buf_size = 0;
-    // TODO(b/150865433): optimize child's output parsing
-    while ((bytes_read = adb_read(read_fd, child_stdout.data() + buf_size,
-                                  child_stdout.size() - buf_size)) > 0) {
-        // print to parent's stdout
-        fprintf(stdout, "%.*s", bytes_read, child_stdout.data() + buf_size);
-
-        buf_size += bytes_read;
-        const std::string_view stdout_str(child_stdout.data(), buf_size);
-        // wait till installation either succeeds or fails
-        if (stdout_str.find("Success") != std::string::npos) {
-            return Result::Success;
-        }
-        // on failure, wait for full message
-        static constexpr auto failure_msg_head = "Failure ["sv;
-        if (const auto begin_itr = stdout_str.find(failure_msg_head);
-            begin_itr != std::string::npos) {
-            if (buf_size >= maxMessageSize) {
-                return Result::Failure;
-            }
-            const auto end_itr = stdout_str.rfind("]");
-            if (end_itr != std::string::npos && end_itr >= begin_itr + failure_msg_head.size()) {
-                return Result::Failure;
-            }
-        }
-        child_stdout.resize(buf_size + CHUNK_SIZE);
-    }
-    return Result::None;
-}
-
-}  // namespace incremental
diff --git a/adb/client/incremental.h b/adb/client/incremental.h
deleted file mode 100644
index 40e928a..0000000
--- a/adb/client/incremental.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "adb_unique_fd.h"
-
-#include <optional>
-#include <string>
-
-#include "sysdeps.h"
-
-namespace incremental {
-
-using Files = std::vector<std::string>;
-using Args = std::vector<std::string_view>;
-
-bool can_install(const Files& files);
-std::optional<Process> install(const Files& files, const Args& passthrough_args, bool silent);
-
-enum class Result { Success, Failure, None };
-Result wait_for_installation(int read_fd);
-
-}  // namespace incremental
diff --git a/adb/client/incremental_server.cpp b/adb/client/incremental_server.cpp
deleted file mode 100644
index bfe18c0..0000000
--- a/adb/client/incremental_server.cpp
+++ /dev/null
@@ -1,716 +0,0 @@
-﻿/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define TRACE_TAG INCREMENTAL
-
-#include "incremental_server.h"
-
-#include <android-base/endian.h>
-#include <android-base/strings.h>
-#include <inttypes.h>
-#include <lz4.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <array>
-#include <deque>
-#include <fstream>
-#include <thread>
-#include <type_traits>
-#include <unordered_set>
-
-#include "adb.h"
-#include "adb_io.h"
-#include "adb_trace.h"
-#include "adb_unique_fd.h"
-#include "adb_utils.h"
-#include "incremental_utils.h"
-#include "sysdeps.h"
-
-namespace incremental {
-
-static constexpr int kHashesPerBlock = kBlockSize / kDigestSize;
-static constexpr int kCompressedSizeMax = kBlockSize * 0.95;
-static constexpr int8_t kTypeData = 0;
-static constexpr int8_t kTypeHash = 1;
-static constexpr int8_t kCompressionNone = 0;
-static constexpr int8_t kCompressionLZ4 = 1;
-static constexpr int kCompressBound = std::max(kBlockSize, LZ4_COMPRESSBOUND(kBlockSize));
-static constexpr auto kReadBufferSize = 128 * 1024;
-static constexpr int kPollTimeoutMillis = 300000;  // 5 minutes
-
-using BlockSize = int16_t;
-using FileId = int16_t;
-using BlockIdx = int32_t;
-using NumBlocks = int32_t;
-using BlockType = int8_t;
-using CompressionType = int8_t;
-using RequestType = int16_t;
-using ChunkHeader = int32_t;
-using MagicType = uint32_t;
-
-static constexpr MagicType INCR = 0x494e4352;  // LE INCR
-
-static constexpr RequestType SERVING_COMPLETE = 0;
-static constexpr RequestType BLOCK_MISSING = 1;
-static constexpr RequestType PREFETCH = 2;
-static constexpr RequestType DESTROY = 3;
-
-static constexpr inline int64_t roundDownToBlockOffset(int64_t val) {
-    return val & ~(kBlockSize - 1);
-}
-
-static constexpr inline int64_t roundUpToBlockOffset(int64_t val) {
-    return roundDownToBlockOffset(val + kBlockSize - 1);
-}
-
-static constexpr inline NumBlocks numBytesToNumBlocks(int64_t bytes) {
-    return roundUpToBlockOffset(bytes) / kBlockSize;
-}
-
-static constexpr inline off64_t blockIndexToOffset(BlockIdx blockIdx) {
-    return static_cast<off64_t>(blockIdx) * kBlockSize;
-}
-
-template <typename T>
-static inline constexpr T toBigEndian(T t) {
-    using unsigned_type = std::make_unsigned_t<T>;
-    if constexpr (std::is_same_v<T, int16_t>) {
-        return htobe16(static_cast<unsigned_type>(t));
-    } else if constexpr (std::is_same_v<T, int32_t>) {
-        return htobe32(static_cast<unsigned_type>(t));
-    } else if constexpr (std::is_same_v<T, int64_t>) {
-        return htobe64(static_cast<unsigned_type>(t));
-    } else {
-        return t;
-    }
-}
-
-template <typename T>
-static inline constexpr T readBigEndian(void* data) {
-    using unsigned_type = std::make_unsigned_t<T>;
-    if constexpr (std::is_same_v<T, int16_t>) {
-        return static_cast<T>(be16toh(*reinterpret_cast<unsigned_type*>(data)));
-    } else if constexpr (std::is_same_v<T, int32_t>) {
-        return static_cast<T>(be32toh(*reinterpret_cast<unsigned_type*>(data)));
-    } else if constexpr (std::is_same_v<T, int64_t>) {
-        return static_cast<T>(be64toh(*reinterpret_cast<unsigned_type*>(data)));
-    } else {
-        return T();
-    }
-}
-
-// Received from device
-// !Does not include magic!
-struct RequestCommand {
-    RequestType request_type;  // 2 bytes
-    FileId file_id;            // 2 bytes
-    union {
-        BlockIdx block_idx;
-        NumBlocks num_blocks;
-    };  // 4 bytes
-} __attribute__((packed));
-
-// Placed before actual data bytes of each block
-struct ResponseHeader {
-    FileId file_id;                    // 2 bytes
-    BlockType block_type;              // 1 byte
-    CompressionType compression_type;  // 1 byte
-    BlockIdx block_idx;                // 4 bytes
-    BlockSize block_size;              // 2 bytes
-
-    static constexpr size_t responseSizeFor(size_t dataSize) {
-        return dataSize + sizeof(ResponseHeader);
-    }
-} __attribute__((packed));
-
-template <size_t Size = kBlockSize>
-struct BlockBuffer {
-    ResponseHeader header;
-    char data[Size];
-} __attribute__((packed));
-
-// Holds streaming state for a file
-class File {
-  public:
-    // Plain file
-    File(const char* filepath, FileId id, int64_t size, unique_fd fd, int64_t tree_offset,
-         unique_fd tree_fd)
-        : File(filepath, id, size, tree_offset) {
-        this->fd_ = std::move(fd);
-        this->tree_fd_ = std::move(tree_fd);
-        priority_blocks_ = PriorityBlocksForFile(filepath, fd_.get(), size);
-    }
-    int64_t ReadDataBlock(BlockIdx block_idx, void* buf, bool* is_zip_compressed) const {
-        int64_t bytes_read = -1;
-        const off64_t offsetStart = blockIndexToOffset(block_idx);
-        bytes_read = adb_pread(fd_, buf, kBlockSize, offsetStart);
-        return bytes_read;
-    }
-    int64_t ReadTreeBlock(BlockIdx block_idx, void* buf) const {
-        int64_t bytes_read = -1;
-        const off64_t offsetStart = tree_offset_ + blockIndexToOffset(block_idx);
-        bytes_read = adb_pread(tree_fd_, buf, kBlockSize, offsetStart);
-        return bytes_read;
-    }
-
-    const std::vector<BlockIdx>& PriorityBlocks() const { return priority_blocks_; }
-
-    std::vector<bool> sentBlocks;
-    NumBlocks sentBlocksCount = 0;
-
-    std::vector<bool> sentTreeBlocks;
-
-    const char* const filepath;
-    const FileId id;
-    const int64_t size;
-
-  private:
-    File(const char* filepath, FileId id, int64_t size, int64_t tree_offset)
-        : filepath(filepath), id(id), size(size), tree_offset_(tree_offset) {
-        sentBlocks.resize(numBytesToNumBlocks(size));
-        sentTreeBlocks.resize(verity_tree_blocks_for_file(size));
-    }
-    unique_fd fd_;
-    std::vector<BlockIdx> priority_blocks_;
-
-    unique_fd tree_fd_;
-    const int64_t tree_offset_;
-};
-
-class IncrementalServer {
-  public:
-    IncrementalServer(unique_fd adb_fd, unique_fd output_fd, std::vector<File> files)
-        : adb_fd_(std::move(adb_fd)), output_fd_(std::move(output_fd)), files_(std::move(files)) {
-        buffer_.reserve(kReadBufferSize);
-        pendingBlocksBuffer_.resize(kChunkFlushSize + 2 * kBlockSize);
-        pendingBlocks_ = pendingBlocksBuffer_.data() + sizeof(ChunkHeader);
-    }
-
-    bool Serve();
-
-  private:
-    struct PrefetchState {
-        const File* file;
-        BlockIdx overallIndex = 0;
-        BlockIdx overallEnd = 0;
-        BlockIdx priorityIndex = 0;
-
-        explicit PrefetchState(const File& f, BlockIdx start, int count)
-            : file(&f),
-              overallIndex(start),
-              overallEnd(std::min<BlockIdx>(start + count, f.sentBlocks.size())) {}
-
-        explicit PrefetchState(const File& f)
-            : PrefetchState(f, 0, (BlockIdx)f.sentBlocks.size()) {}
-
-        bool done() const {
-            const bool overallSent = (overallIndex >= overallEnd);
-            if (file->PriorityBlocks().empty()) {
-                return overallSent;
-            }
-            return overallSent && (priorityIndex >= (BlockIdx)file->PriorityBlocks().size());
-        }
-    };
-
-    bool SkipToRequest(void* buffer, size_t* size, bool blocking);
-    std::optional<RequestCommand> ReadRequest(bool blocking);
-
-    void erase_buffer_head(int count) { buffer_.erase(buffer_.begin(), buffer_.begin() + count); }
-
-    enum class SendResult { Sent, Skipped, Error };
-    SendResult SendDataBlock(FileId fileId, BlockIdx blockIdx, bool flush = false);
-
-    bool SendTreeBlock(FileId fileId, int32_t fileBlockIdx, BlockIdx blockIdx);
-    bool SendTreeBlocksForDataBlock(FileId fileId, BlockIdx blockIdx);
-
-    bool SendDone();
-    void RunPrefetching();
-
-    void Send(const void* data, size_t size, bool flush);
-    void Flush();
-    using TimePoint = decltype(std::chrono::high_resolution_clock::now());
-    bool ServingComplete(std::optional<TimePoint> startTime, int missesCount, int missesSent);
-
-    unique_fd const adb_fd_;
-    unique_fd const output_fd_;
-    std::vector<File> files_;
-
-    // Incoming data buffer.
-    std::vector<char> buffer_;
-
-    std::deque<PrefetchState> prefetches_;
-    int compressed_ = 0, uncompressed_ = 0;
-    long long sentSize_ = 0;
-
-    static constexpr auto kChunkFlushSize = 31 * kBlockSize;
-
-    std::vector<char> pendingBlocksBuffer_;
-    char* pendingBlocks_ = nullptr;
-
-    // True when client notifies that all the data has been received
-    bool servingComplete_ = false;
-};
-
-bool IncrementalServer::SkipToRequest(void* buffer, size_t* size, bool blocking) {
-    while (true) {
-        // Looking for INCR magic.
-        bool magic_found = false;
-        int bcur = 0;
-        int bsize = buffer_.size();
-        for (bcur = 0; bcur + 4 < bsize; ++bcur) {
-            uint32_t magic = be32toh(*(uint32_t*)(buffer_.data() + bcur));
-            if (magic == INCR) {
-                magic_found = true;
-                break;
-            }
-        }
-
-        if (bcur > 0) {
-            // output the rest.
-            (void)WriteFdExactly(output_fd_, buffer_.data(), bcur);
-            erase_buffer_head(bcur);
-        }
-
-        if (magic_found && buffer_.size() >= *size + sizeof(INCR)) {
-            // fine, return
-            memcpy(buffer, buffer_.data() + sizeof(INCR), *size);
-            erase_buffer_head(*size + sizeof(INCR));
-            return true;
-        }
-
-        adb_pollfd pfd = {adb_fd_.get(), POLLIN, 0};
-        auto res = adb_poll(&pfd, 1, blocking ? kPollTimeoutMillis : 0);
-
-        if (res != 1) {
-            auto err = errno;
-            (void)WriteFdExactly(output_fd_, buffer_.data(), buffer_.size());
-            if (res < 0) {
-                D("Failed to poll: %s", strerror(err));
-                return false;
-            }
-            if (blocking) {
-                fprintf(stderr, "Timed out waiting for data from device.\n");
-            }
-            if (blocking && servingComplete_) {
-                // timeout waiting from client. Serving is complete, so quit.
-                return false;
-            }
-            *size = 0;
-            return true;
-        }
-
-        bsize = buffer_.size();
-        buffer_.resize(kReadBufferSize);
-        int r = adb_read(adb_fd_, buffer_.data() + bsize, kReadBufferSize - bsize);
-        if (r > 0) {
-            buffer_.resize(bsize + r);
-            continue;
-        }
-
-        D("Failed to read from fd %d: %d. Exit", adb_fd_.get(), errno);
-        break;
-    }
-    // socket is closed. print remaining messages
-    WriteFdExactly(output_fd_, buffer_.data(), buffer_.size());
-    return false;
-}
-
-std::optional<RequestCommand> IncrementalServer::ReadRequest(bool blocking) {
-    uint8_t commandBuf[sizeof(RequestCommand)];
-    auto size = sizeof(commandBuf);
-    if (!SkipToRequest(&commandBuf, &size, blocking)) {
-        return {{DESTROY}};
-    }
-    if (size < sizeof(RequestCommand)) {
-        return {};
-    }
-    RequestCommand request;
-    request.request_type = readBigEndian<RequestType>(&commandBuf[0]);
-    request.file_id = readBigEndian<FileId>(&commandBuf[2]);
-    request.block_idx = readBigEndian<BlockIdx>(&commandBuf[4]);
-    return request;
-}
-
-bool IncrementalServer::SendTreeBlocksForDataBlock(const FileId fileId, const BlockIdx blockIdx) {
-    auto& file = files_[fileId];
-    const int32_t data_block_count = numBytesToNumBlocks(file.size);
-
-    const int32_t total_nodes_count(file.sentTreeBlocks.size());
-    const int32_t leaf_nodes_count = (data_block_count + kHashesPerBlock - 1) / kHashesPerBlock;
-
-    const int32_t leaf_nodes_offset = total_nodes_count - leaf_nodes_count;
-
-    // Leaf level, sending only 1 block.
-    const int32_t leaf_idx = leaf_nodes_offset + blockIdx / kHashesPerBlock;
-    if (file.sentTreeBlocks[leaf_idx]) {
-        return true;
-    }
-    if (!SendTreeBlock(fileId, blockIdx, leaf_idx)) {
-        return false;
-    }
-    file.sentTreeBlocks[leaf_idx] = true;
-
-    // Non-leaf, sending EVERYTHING. This should be done only once.
-    if (leaf_nodes_offset == 0 || file.sentTreeBlocks[0]) {
-        return true;
-    }
-
-    for (int32_t i = 0; i < leaf_nodes_offset; ++i) {
-        if (!SendTreeBlock(fileId, blockIdx, i)) {
-            return false;
-        }
-        file.sentTreeBlocks[i] = true;
-    }
-    return true;
-}
-
-bool IncrementalServer::SendTreeBlock(FileId fileId, int32_t fileBlockIdx, BlockIdx blockIdx) {
-    const auto& file = files_[fileId];
-
-    BlockBuffer buffer;
-    const int64_t bytesRead = file.ReadTreeBlock(blockIdx, buffer.data);
-    if (bytesRead <= 0) {
-        fprintf(stderr, "Failed to get data for %s.idsig at blockIdx=%d.\n", file.filepath,
-                blockIdx);
-        return false;
-    }
-
-    buffer.header.compression_type = kCompressionNone;
-    buffer.header.block_type = kTypeHash;
-    buffer.header.file_id = toBigEndian(fileId);
-    buffer.header.block_size = toBigEndian(int16_t(bytesRead));
-    buffer.header.block_idx = toBigEndian(blockIdx);
-
-    Send(&buffer, ResponseHeader::responseSizeFor(bytesRead), /*flush=*/false);
-
-    return true;
-}
-
-auto IncrementalServer::SendDataBlock(FileId fileId, BlockIdx blockIdx, bool flush) -> SendResult {
-    auto& file = files_[fileId];
-    if (blockIdx >= static_cast<long>(file.sentBlocks.size())) {
-        // may happen as we schedule some extra blocks for reported page misses
-        D("Skipped reading file %s at block %" PRId32 " (past end).", file.filepath, blockIdx);
-        return SendResult::Skipped;
-    }
-    if (file.sentBlocks[blockIdx]) {
-        return SendResult::Skipped;
-    }
-
-    if (!SendTreeBlocksForDataBlock(fileId, blockIdx)) {
-        return SendResult::Error;
-    }
-
-    BlockBuffer raw;
-    bool isZipCompressed = false;
-    const int64_t bytesRead = file.ReadDataBlock(blockIdx, raw.data, &isZipCompressed);
-    if (bytesRead < 0) {
-        fprintf(stderr, "Failed to get data for %s at blockIdx=%d (%d).\n", file.filepath, blockIdx,
-                errno);
-        return SendResult::Error;
-    }
-
-    BlockBuffer<kCompressBound> compressed;
-    int16_t compressedSize = 0;
-    if (!isZipCompressed) {
-        compressedSize = LZ4_compress_default(raw.data, compressed.data, bytesRead, kCompressBound);
-    }
-    int16_t blockSize;
-    ResponseHeader* header;
-    if (compressedSize > 0 && compressedSize < kCompressedSizeMax) {
-        ++compressed_;
-        blockSize = compressedSize;
-        header = &compressed.header;
-        header->compression_type = kCompressionLZ4;
-    } else {
-        ++uncompressed_;
-        blockSize = bytesRead;
-        header = &raw.header;
-        header->compression_type = kCompressionNone;
-    }
-
-    header->block_type = kTypeData;
-    header->file_id = toBigEndian(fileId);
-    header->block_size = toBigEndian(blockSize);
-    header->block_idx = toBigEndian(blockIdx);
-
-    file.sentBlocks[blockIdx] = true;
-    file.sentBlocksCount += 1;
-    Send(header, ResponseHeader::responseSizeFor(blockSize), flush);
-
-    return SendResult::Sent;
-}
-
-bool IncrementalServer::SendDone() {
-    ResponseHeader header;
-    header.file_id = -1;
-    header.block_type = 0;
-    header.compression_type = 0;
-    header.block_idx = 0;
-    header.block_size = 0;
-    Send(&header, sizeof(header), true);
-    return true;
-}
-
-void IncrementalServer::RunPrefetching() {
-    constexpr auto kPrefetchBlocksPerIteration = 128;
-
-    int blocksToSend = kPrefetchBlocksPerIteration;
-    while (!prefetches_.empty() && blocksToSend > 0) {
-        auto& prefetch = prefetches_.front();
-        const auto& file = *prefetch.file;
-        const auto& priority_blocks = file.PriorityBlocks();
-        if (!priority_blocks.empty()) {
-            for (auto& i = prefetch.priorityIndex;
-                 blocksToSend > 0 && i < (BlockIdx)priority_blocks.size(); ++i) {
-                if (auto res = SendDataBlock(file.id, priority_blocks[i]);
-                    res == SendResult::Sent) {
-                    --blocksToSend;
-                } else if (res == SendResult::Error) {
-                    fprintf(stderr, "Failed to send priority block %" PRId32 "\n", i);
-                }
-            }
-        }
-        for (auto& i = prefetch.overallIndex; blocksToSend > 0 && i < prefetch.overallEnd; ++i) {
-            if (auto res = SendDataBlock(file.id, i); res == SendResult::Sent) {
-                --blocksToSend;
-            } else if (res == SendResult::Error) {
-                fprintf(stderr, "Failed to send block %" PRId32 "\n", i);
-            }
-        }
-        if (prefetch.done()) {
-            prefetches_.pop_front();
-        }
-    }
-}
-
-void IncrementalServer::Send(const void* data, size_t size, bool flush) {
-    pendingBlocks_ = std::copy_n(static_cast<const char*>(data), size, pendingBlocks_);
-    if (flush || pendingBlocks_ - pendingBlocksBuffer_.data() > kChunkFlushSize) {
-        Flush();
-    }
-}
-
-void IncrementalServer::Flush() {
-    auto dataBytes = pendingBlocks_ - (pendingBlocksBuffer_.data() + sizeof(ChunkHeader));
-    if (dataBytes == 0) {
-        return;
-    }
-
-    *(ChunkHeader*)pendingBlocksBuffer_.data() = toBigEndian<int32_t>(dataBytes);
-    auto totalBytes = sizeof(ChunkHeader) + dataBytes;
-    if (!WriteFdExactly(adb_fd_, pendingBlocksBuffer_.data(), totalBytes)) {
-        fprintf(stderr, "Failed to write %d bytes\n", int(totalBytes));
-    }
-    sentSize_ += totalBytes;
-    pendingBlocks_ = pendingBlocksBuffer_.data() + sizeof(ChunkHeader);
-}
-
-bool IncrementalServer::ServingComplete(std::optional<TimePoint> startTime, int missesCount,
-                                        int missesSent) {
-    servingComplete_ = true;
-    using namespace std::chrono;
-    auto endTime = high_resolution_clock::now();
-    D("Streaming completed.\n"
-      "Misses: %d, of those unique: %d; sent compressed: %d, uncompressed: "
-      "%d, mb: %.3f\n"
-      "Total time taken: %.3fms",
-      missesCount, missesSent, compressed_, uncompressed_, sentSize_ / 1024.0 / 1024.0,
-      duration_cast<microseconds>(endTime - (startTime ? *startTime : endTime)).count() / 1000.0);
-    return true;
-}
-
-bool IncrementalServer::Serve() {
-    // Initial handshake to verify connection is still alive
-    if (!SendOkay(adb_fd_)) {
-        fprintf(stderr, "Connection is dead. Abort.\n");
-        return false;
-    }
-
-    std::unordered_set<FileId> prefetchedFiles;
-    bool doneSent = false;
-    int missesCount = 0;
-    int missesSent = 0;
-
-    using namespace std::chrono;
-    std::optional<TimePoint> startTime;
-
-    while (true) {
-        if (!doneSent && prefetches_.empty() &&
-            std::all_of(files_.begin(), files_.end(), [](const File& f) {
-                return f.sentBlocksCount == NumBlocks(f.sentBlocks.size());
-            })) {
-            fprintf(stderr, "All files should be loaded. Notifying the device.\n");
-            SendDone();
-            doneSent = true;
-        }
-
-        const bool blocking = prefetches_.empty();
-        if (blocking) {
-            // We've no idea how long the blocking call is, so let's flush whatever is still unsent.
-            Flush();
-        }
-        auto request = ReadRequest(blocking);
-
-        if (!startTime) {
-            startTime = high_resolution_clock::now();
-        }
-
-        if (request) {
-            FileId fileId = request->file_id;
-            BlockIdx blockIdx = request->block_idx;
-
-            switch (request->request_type) {
-                case DESTROY: {
-                    // Stop everything.
-                    return true;
-                }
-                case SERVING_COMPLETE: {
-                    // Not stopping the server here.
-                    ServingComplete(startTime, missesCount, missesSent);
-                    break;
-                }
-                case BLOCK_MISSING: {
-                    ++missesCount;
-                    // Sends one single block ASAP.
-                    if (fileId < 0 || fileId >= (FileId)files_.size() || blockIdx < 0 ||
-                        blockIdx >= (BlockIdx)files_[fileId].sentBlocks.size()) {
-                        fprintf(stderr,
-                                "Received invalid data request for file_id %" PRId16
-                                " block_idx %" PRId32 ".\n",
-                                fileId, blockIdx);
-                        break;
-                    }
-
-                    if (VLOG_IS_ON(INCREMENTAL)) {
-                        auto& file = files_[fileId];
-                        auto posP = std::find(file.PriorityBlocks().begin(),
-                                              file.PriorityBlocks().end(), blockIdx);
-                        D("\tMISSING BLOCK: reading file %d block %04d (in priority: %d of %d)",
-                          (int)fileId, (int)blockIdx,
-                          posP == file.PriorityBlocks().end()
-                                  ? -1
-                                  : int(posP - file.PriorityBlocks().begin()),
-                          int(file.PriorityBlocks().size()));
-                    }
-
-                    if (auto res = SendDataBlock(fileId, blockIdx, true);
-                        res == SendResult::Error) {
-                        fprintf(stderr, "Failed to send block %" PRId32 ".\n", blockIdx);
-                    } else if (res == SendResult::Sent) {
-                        ++missesSent;
-                        // Make sure we send more pages from this place onward, in case if the OS is
-                        // reading a bigger block.
-                        prefetches_.emplace_front(files_[fileId], blockIdx + 1, 7);
-                    }
-                    break;
-                }
-                case PREFETCH: {
-                    // Start prefetching for a file
-                    if (fileId < 0) {
-                        fprintf(stderr,
-                                "Received invalid prefetch request for file_id %" PRId16 "\n",
-                                fileId);
-                        break;
-                    }
-                    if (!prefetchedFiles.insert(fileId).second) {
-                        fprintf(stderr,
-                                "Received duplicate prefetch request for file_id %" PRId16 "\n",
-                                fileId);
-                        break;
-                    }
-                    D("Received prefetch request for file_id %" PRId16 ".", fileId);
-                    prefetches_.emplace_back(files_[fileId]);
-                    break;
-                }
-                default:
-                    fprintf(stderr, "Invalid request %" PRId16 ",%" PRId16 ",%" PRId32 ".\n",
-                            request->request_type, fileId, blockIdx);
-                    break;
-            }
-        }
-
-        RunPrefetching();
-    }
-}
-
-static std::pair<unique_fd, int64_t> open_fd(const char* filepath) {
-    struct stat st;
-    if (stat(filepath, &st)) {
-        error_exit("inc-server: failed to stat input file '%s'.", filepath);
-    }
-
-    unique_fd fd(adb_open(filepath, O_RDONLY));
-    if (fd < 0) {
-        error_exit("inc-server: failed to open file '%s'.", filepath);
-    }
-
-    return {std::move(fd), st.st_size};
-}
-
-static std::pair<unique_fd, int64_t> open_signature(int64_t file_size, const char* filepath) {
-    std::string signature_file(filepath);
-    signature_file += IDSIG;
-
-    unique_fd fd(adb_open(signature_file.c_str(), O_RDONLY));
-    if (fd < 0) {
-        error_exit("inc-server: failed to open file '%s'.", signature_file.c_str());
-    }
-
-    auto [tree_offset, tree_size] = skip_id_sig_headers(fd);
-    if (auto expected = verity_tree_size_for_file(file_size); tree_size != expected) {
-        error_exit("Verity tree size mismatch in signature file: %s [was %lld, expected %lld].\n",
-                   signature_file.c_str(), (long long)tree_size, (long long)expected);
-    }
-
-    int32_t data_block_count = numBytesToNumBlocks(file_size);
-    int32_t leaf_nodes_count = (data_block_count + kHashesPerBlock - 1) / kHashesPerBlock;
-    D("Verity tree loaded: %s, tree size: %d (%d blocks, %d leafs)", signature_file.c_str(),
-      int(tree_size), int(numBytesToNumBlocks(tree_size)), int(leaf_nodes_count));
-
-    return {std::move(fd), tree_offset};
-}
-
-bool serve(int connection_fd, int output_fd, int argc, const char** argv) {
-    auto connection_ufd = unique_fd(connection_fd);
-    auto output_ufd = unique_fd(output_fd);
-    if (argc <= 0) {
-        error_exit("inc-server: must specify at least one file.");
-    }
-
-    std::vector<File> files;
-    files.reserve(argc);
-    for (int i = 0; i < argc; ++i) {
-        auto filepath = argv[i];
-
-        auto [file_fd, file_size] = open_fd(filepath);
-        auto [sign_fd, sign_offset] = open_signature(file_size, filepath);
-
-        files.emplace_back(filepath, i, file_size, std::move(file_fd), sign_offset,
-                           std::move(sign_fd));
-    }
-
-    IncrementalServer server(std::move(connection_ufd), std::move(output_ufd), std::move(files));
-    printf("Serving...\n");
-    fclose(stdin);
-    fclose(stdout);
-    return server.Serve();
-}
-
-}  // namespace incremental
diff --git a/adb/client/incremental_server.h b/adb/client/incremental_server.h
deleted file mode 100644
index 55b8215..0000000
--- a/adb/client/incremental_server.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-namespace incremental {
-
-// Expecting arguments like:
-// {FILE1 FILE2 ...}
-// Where FILE* are files to serve.
-bool serve(int connection_fd, int output_fd, int argc, const char** argv);
-
-}  // namespace incremental
diff --git a/adb/client/incremental_utils.cpp b/adb/client/incremental_utils.cpp
deleted file mode 100644
index 076b766..0000000
--- a/adb/client/incremental_utils.cpp
+++ /dev/null
@@ -1,366 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define TRACE_TAG INCREMENTAL
-
-#include "incremental_utils.h"
-
-#include <android-base/endian.h>
-#include <android-base/mapped_file.h>
-#include <android-base/strings.h>
-#include <ziparchive/zip_archive.h>
-#include <ziparchive/zip_writer.h>
-
-#include <cinttypes>
-#include <numeric>
-#include <unordered_set>
-
-#include "adb_io.h"
-#include "adb_trace.h"
-#include "sysdeps.h"
-
-namespace incremental {
-
-static constexpr inline int32_t offsetToBlockIndex(int64_t offset) {
-    return (offset & ~(kBlockSize - 1)) >> 12;
-}
-
-Size verity_tree_blocks_for_file(Size fileSize) {
-    if (fileSize == 0) {
-        return 0;
-    }
-
-    constexpr int hash_per_block = kBlockSize / kDigestSize;
-
-    Size total_tree_block_count = 0;
-
-    auto block_count = 1 + (fileSize - 1) / kBlockSize;
-    auto hash_block_count = block_count;
-    for (auto i = 0; hash_block_count > 1; i++) {
-        hash_block_count = (hash_block_count + hash_per_block - 1) / hash_per_block;
-        total_tree_block_count += hash_block_count;
-    }
-    return total_tree_block_count;
-}
-
-Size verity_tree_size_for_file(Size fileSize) {
-    return verity_tree_blocks_for_file(fileSize) * kBlockSize;
-}
-
-static inline int32_t read_int32(borrowed_fd fd) {
-    int32_t result;
-    return ReadFdExactly(fd, &result, sizeof(result)) ? result : -1;
-}
-
-static inline int32_t skip_int(borrowed_fd fd) {
-    return adb_lseek(fd, 4, SEEK_CUR);
-}
-
-static inline void append_int(borrowed_fd fd, std::vector<char>* bytes) {
-    int32_t le_val = read_int32(fd);
-    auto old_size = bytes->size();
-    bytes->resize(old_size + sizeof(le_val));
-    memcpy(bytes->data() + old_size, &le_val, sizeof(le_val));
-}
-
-static inline void append_bytes_with_size(borrowed_fd fd, std::vector<char>* bytes) {
-    int32_t le_size = read_int32(fd);
-    if (le_size < 0) {
-        return;
-    }
-    int32_t size = int32_t(le32toh(le_size));
-    auto old_size = bytes->size();
-    bytes->resize(old_size + sizeof(le_size) + size);
-    memcpy(bytes->data() + old_size, &le_size, sizeof(le_size));
-    ReadFdExactly(fd, bytes->data() + old_size + sizeof(le_size), size);
-}
-
-static inline int32_t skip_bytes_with_size(borrowed_fd fd) {
-    int32_t le_size = read_int32(fd);
-    if (le_size < 0) {
-        return -1;
-    }
-    int32_t size = int32_t(le32toh(le_size));
-    return (int32_t)adb_lseek(fd, size, SEEK_CUR);
-}
-
-std::pair<std::vector<char>, int32_t> read_id_sig_headers(borrowed_fd fd) {
-    std::vector<char> result;
-    append_int(fd, &result);              // version
-    append_bytes_with_size(fd, &result);  // hashingInfo
-    append_bytes_with_size(fd, &result);  // signingInfo
-    auto le_tree_size = read_int32(fd);
-    auto tree_size = int32_t(le32toh(le_tree_size));  // size of the verity tree
-    return {std::move(result), tree_size};
-}
-
-std::pair<off64_t, ssize_t> skip_id_sig_headers(borrowed_fd fd) {
-    skip_int(fd);                            // version
-    skip_bytes_with_size(fd);                // hashingInfo
-    auto offset = skip_bytes_with_size(fd);  // signingInfo
-    auto le_tree_size = read_int32(fd);
-    auto tree_size = int32_t(le32toh(le_tree_size));  // size of the verity tree
-    return {offset + sizeof(le_tree_size), tree_size};
-}
-
-template <class T>
-static T valueAt(borrowed_fd fd, off64_t offset) {
-    T t;
-    memset(&t, 0, sizeof(T));
-    if (adb_pread(fd, &t, sizeof(T), offset) != sizeof(T)) {
-        memset(&t, -1, sizeof(T));
-    }
-
-    return t;
-}
-
-static void appendBlocks(int32_t start, int count, std::vector<int32_t>* blocks) {
-    if (count == 1) {
-        blocks->push_back(start);
-    } else {
-        auto oldSize = blocks->size();
-        blocks->resize(oldSize + count);
-        std::iota(blocks->begin() + oldSize, blocks->end(), start);
-    }
-}
-
-template <class T>
-static void unduplicate(std::vector<T>& v) {
-    std::unordered_set<T> uniques(v.size());
-    v.erase(std::remove_if(v.begin(), v.end(),
-                           [&uniques](T t) { return !uniques.insert(t).second; }),
-            v.end());
-}
-
-static off64_t CentralDirOffset(borrowed_fd fd, Size fileSize) {
-    static constexpr int kZipEocdRecMinSize = 22;
-    static constexpr int32_t kZipEocdRecSig = 0x06054b50;
-    static constexpr int kZipEocdCentralDirSizeFieldOffset = 12;
-    static constexpr int kZipEocdCommentLengthFieldOffset = 20;
-
-    int32_t sigBuf = 0;
-    off64_t eocdOffset = -1;
-    off64_t maxEocdOffset = fileSize - kZipEocdRecMinSize;
-    int16_t commentLenBuf = 0;
-
-    // Search from the end of zip, backward to find beginning of EOCD
-    for (int16_t commentLen = 0; commentLen < fileSize; ++commentLen) {
-        sigBuf = valueAt<int32_t>(fd, maxEocdOffset - commentLen);
-        if (sigBuf == kZipEocdRecSig) {
-            commentLenBuf = valueAt<int16_t>(
-                    fd, maxEocdOffset - commentLen + kZipEocdCommentLengthFieldOffset);
-            if (commentLenBuf == commentLen) {
-                eocdOffset = maxEocdOffset - commentLen;
-                break;
-            }
-        }
-    }
-
-    if (eocdOffset < 0) {
-        return -1;
-    }
-
-    off64_t cdLen = static_cast<int64_t>(
-            valueAt<int32_t>(fd, eocdOffset + kZipEocdCentralDirSizeFieldOffset));
-
-    return eocdOffset - cdLen;
-}
-
-// Does not support APKs larger than 4GB
-static off64_t SignerBlockOffset(borrowed_fd fd, Size fileSize) {
-    static constexpr int kApkSigBlockMinSize = 32;
-    static constexpr int kApkSigBlockFooterSize = 24;
-    static constexpr int64_t APK_SIG_BLOCK_MAGIC_HI = 0x3234206b636f6c42l;
-    static constexpr int64_t APK_SIG_BLOCK_MAGIC_LO = 0x20676953204b5041l;
-
-    off64_t cdOffset = CentralDirOffset(fd, fileSize);
-    if (cdOffset < 0) {
-        return -1;
-    }
-    // CD offset is where original signer block ends. Search backwards for magic and footer.
-    if (cdOffset < kApkSigBlockMinSize ||
-        valueAt<int64_t>(fd, cdOffset - 2 * sizeof(int64_t)) != APK_SIG_BLOCK_MAGIC_LO ||
-        valueAt<int64_t>(fd, cdOffset - sizeof(int64_t)) != APK_SIG_BLOCK_MAGIC_HI) {
-        return -1;
-    }
-    int32_t signerSizeInFooter = valueAt<int32_t>(fd, cdOffset - kApkSigBlockFooterSize);
-    off64_t signerBlockOffset = cdOffset - signerSizeInFooter - sizeof(int64_t);
-    if (signerBlockOffset < 0) {
-        return -1;
-    }
-    int32_t signerSizeInHeader = valueAt<int32_t>(fd, signerBlockOffset);
-    if (signerSizeInFooter != signerSizeInHeader) {
-        return -1;
-    }
-
-    return signerBlockOffset;
-}
-
-static std::vector<int32_t> ZipPriorityBlocks(off64_t signerBlockOffset, Size fileSize) {
-    int32_t signerBlockIndex = offsetToBlockIndex(signerBlockOffset);
-    int32_t lastBlockIndex = offsetToBlockIndex(fileSize);
-    const auto numPriorityBlocks = lastBlockIndex - signerBlockIndex + 1;
-
-    std::vector<int32_t> zipPriorityBlocks;
-
-    // Some magic here: most of zip libraries perform a scan for EOCD record starting at the offset
-    // of a maximum comment size from the end of the file. This means the last 65-ish KBs will be
-    // accessed first, followed by the rest of the central directory blocks. Make sure we
-    // send the data in the proper order, as central directory can be quite big by itself.
-    static constexpr auto kMaxZipCommentSize = 64 * 1024;
-    static constexpr auto kNumBlocksInEocdSearch = kMaxZipCommentSize / kBlockSize + 1;
-    if (numPriorityBlocks > kNumBlocksInEocdSearch) {
-        appendBlocks(lastBlockIndex - kNumBlocksInEocdSearch + 1, kNumBlocksInEocdSearch,
-                     &zipPriorityBlocks);
-        appendBlocks(signerBlockIndex, numPriorityBlocks - kNumBlocksInEocdSearch,
-                     &zipPriorityBlocks);
-    } else {
-        appendBlocks(signerBlockIndex, numPriorityBlocks, &zipPriorityBlocks);
-    }
-
-    // Somehow someone keeps accessing the start of the archive, even if there's nothing really
-    // interesting there...
-    appendBlocks(0, 1, &zipPriorityBlocks);
-    return zipPriorityBlocks;
-}
-
-[[maybe_unused]] static ZipArchiveHandle openZipArchiveFd(borrowed_fd fd) {
-    bool transferFdOwnership = false;
-#ifdef _WIN32
-    //
-    // Need to create a special CRT FD here as the current one is not compatible with
-    // normal read()/write() calls that libziparchive uses.
-    // To make this work we have to create a copy of the file handle, as CRT doesn't care
-    // and closes it together with the new descriptor.
-    //
-    // Note: don't move this into a helper function, it's better to be hard to reuse because
-    //       the code is ugly and won't work unless it's a last resort.
-    //
-    auto handle = adb_get_os_handle(fd);
-    HANDLE dupedHandle;
-    if (!::DuplicateHandle(::GetCurrentProcess(), handle, ::GetCurrentProcess(), &dupedHandle, 0,
-                           false, DUPLICATE_SAME_ACCESS)) {
-        D("%s failed at DuplicateHandle: %d", __func__, (int)::GetLastError());
-        return {};
-    }
-    int osfd = _open_osfhandle((intptr_t)dupedHandle, _O_RDONLY | _O_BINARY);
-    if (osfd < 0) {
-        D("%s failed at _open_osfhandle: %d", __func__, errno);
-        ::CloseHandle(handle);
-        return {};
-    }
-    transferFdOwnership = true;
-#else
-    int osfd = fd.get();
-#endif
-    ZipArchiveHandle zip;
-    if (OpenArchiveFd(osfd, "apk_fd", &zip, transferFdOwnership) != 0) {
-        D("%s failed at OpenArchiveFd: %d", __func__, errno);
-#ifdef _WIN32
-        // "_close()" is a secret WinCRT name for the regular close() function.
-        _close(osfd);
-#endif
-        return {};
-    }
-    return zip;
-}
-
-static std::pair<ZipArchiveHandle, std::unique_ptr<android::base::MappedFile>> openZipArchive(
-        borrowed_fd fd, Size fileSize) {
-#ifndef __LP64__
-    if (fileSize >= INT_MAX) {
-        return {openZipArchiveFd(fd), nullptr};
-    }
-#endif
-    auto mapping =
-            android::base::MappedFile::FromOsHandle(adb_get_os_handle(fd), 0, fileSize, PROT_READ);
-    if (!mapping) {
-        D("%s failed at FromOsHandle: %d", __func__, errno);
-        return {};
-    }
-    ZipArchiveHandle zip;
-    if (OpenArchiveFromMemory(mapping->data(), mapping->size(), "apk_mapping", &zip) != 0) {
-        D("%s failed at OpenArchiveFromMemory: %d", __func__, errno);
-        return {};
-    }
-    return {zip, std::move(mapping)};
-}
-
-// TODO(b/151676293): avoid using libziparchive as it reads local file headers
-// which causes additional performance cost. Instead, only read from central directory.
-static std::vector<int32_t> InstallationPriorityBlocks(borrowed_fd fd, Size fileSize) {
-    auto [zip, _] = openZipArchive(fd, fileSize);
-    if (!zip) {
-        return {};
-    }
-
-    void* cookie = nullptr;
-    if (StartIteration(zip, &cookie) != 0) {
-        D("%s failed at StartIteration: %d", __func__, errno);
-        return {};
-    }
-
-    std::vector<int32_t> installationPriorityBlocks;
-    ZipEntry entry;
-    std::string_view entryName;
-    while (Next(cookie, &entry, &entryName) == 0) {
-        if (entryName == "resources.arsc" || entryName == "AndroidManifest.xml" ||
-            entryName.starts_with("lib/")) {
-            // Full entries are needed for installation
-            off64_t entryStartOffset = entry.offset;
-            off64_t entryEndOffset =
-                    entryStartOffset +
-                    (entry.method == kCompressStored ? entry.uncompressed_length
-                                                     : entry.compressed_length) +
-                    (entry.has_data_descriptor ? 16 /* sizeof(DataDescriptor) */ : 0);
-            int32_t startBlockIndex = offsetToBlockIndex(entryStartOffset);
-            int32_t endBlockIndex = offsetToBlockIndex(entryEndOffset);
-            int32_t numNewBlocks = endBlockIndex - startBlockIndex + 1;
-            appendBlocks(startBlockIndex, numNewBlocks, &installationPriorityBlocks);
-            D("\tadding to priority blocks: '%.*s'", (int)entryName.size(), entryName.data());
-        } else if (entryName == "classes.dex") {
-            // Only the head is needed for installation
-            int32_t startBlockIndex = offsetToBlockIndex(entry.offset);
-            appendBlocks(startBlockIndex, 2, &installationPriorityBlocks);
-            D("\tadding to priority blocks: '%.*s'", (int)entryName.size(), entryName.data());
-        }
-    }
-
-    EndIteration(cookie);
-    CloseArchive(zip);
-    return installationPriorityBlocks;
-}
-
-std::vector<int32_t> PriorityBlocksForFile(const std::string& filepath, borrowed_fd fd,
-                                           Size fileSize) {
-    if (!android::base::EndsWithIgnoreCase(filepath, ".apk")) {
-        return {};
-    }
-    off64_t signerOffset = SignerBlockOffset(fd, fileSize);
-    if (signerOffset < 0) {
-        // No signer block? not a valid APK
-        return {};
-    }
-    std::vector<int32_t> priorityBlocks = ZipPriorityBlocks(signerOffset, fileSize);
-    std::vector<int32_t> installationPriorityBlocks = InstallationPriorityBlocks(fd, fileSize);
-
-    priorityBlocks.insert(priorityBlocks.end(), installationPriorityBlocks.begin(),
-                          installationPriorityBlocks.end());
-    unduplicate(priorityBlocks);
-    return priorityBlocks;
-}
-
-}  // namespace incremental
diff --git a/adb/client/incremental_utils.h b/adb/client/incremental_utils.h
deleted file mode 100644
index fe2914d..0000000
--- a/adb/client/incremental_utils.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "adb_unique_fd.h"
-
-#include <string>
-#include <string_view>
-#include <utility>
-#include <vector>
-
-#include <stdint.h>
-
-#include <android-base/off64_t.h>
-
-namespace incremental {
-
-using Size = int64_t;
-constexpr int kBlockSize = 4096;
-constexpr int kSha256DigestSize = 32;
-constexpr int kDigestSize = kSha256DigestSize;
-
-constexpr std::string_view IDSIG = ".idsig";
-
-std::vector<int32_t> PriorityBlocksForFile(const std::string& filepath, borrowed_fd fd,
-                                           Size fileSize);
-
-Size verity_tree_blocks_for_file(Size fileSize);
-Size verity_tree_size_for_file(Size fileSize);
-
-std::pair<std::vector<char>, int32_t> read_id_sig_headers(borrowed_fd fd);
-std::pair<off64_t, ssize_t> skip_id_sig_headers(borrowed_fd fd);
-
-}  // namespace incremental
diff --git a/adb/client/line_printer.cpp b/adb/client/line_printer.cpp
deleted file mode 100644
index 50c03e8..0000000
--- a/adb/client/line_printer.cpp
+++ /dev/null
@@ -1,138 +0,0 @@
-// Copyright 2013 Google Inc. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "line_printer.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#ifdef _WIN32
-#include <windows.h>
-#else
-#include <unistd.h>
-#include <sys/ioctl.h>
-#include <termios.h>
-#include <sys/time.h>
-#endif
-
-// Make sure printf is really adb_printf which works for UTF-8 on Windows.
-#include <sysdeps.h>
-
-// Stuff from ninja's util.h that's needed below.
-#include <vector>
-using namespace std;
-// This does not account for multiple UTF-8 bytes corresponding to a single Unicode code point, or
-// multiple code points corresponding to a single grapheme cluster (user-perceived character).
-string ElideMiddle(const string& str, size_t width) {
-  const int kMargin = 3;  // Space for "...".
-  string result = str;
-  if (result.size() + kMargin > width) {
-    size_t elide_size = (width - kMargin) / 2;
-    result = result.substr(0, elide_size)
-      + "..."
-      + result.substr(result.size() - elide_size, elide_size);
-  }
-  return result;
-}
-
-LinePrinter::LinePrinter() : have_blank_line_(true) {
-#ifndef _WIN32
-  const char* term = getenv("TERM");
-  smart_terminal_ = unix_isatty(1) && term && string(term) != "dumb";
-#else
-  // Disable output buffer.  It'd be nice to use line buffering but
-  // MSDN says: "For some systems, [_IOLBF] provides line
-  // buffering. However, for Win32, the behavior is the same as _IOFBF
-  // - Full Buffering."
-  setvbuf(stdout, nullptr, _IONBF, 0);
-  console_ = GetStdHandle(STD_OUTPUT_HANDLE);
-  CONSOLE_SCREEN_BUFFER_INFO csbi;
-  smart_terminal_ = GetConsoleScreenBufferInfo(console_, &csbi);
-#endif
-}
-
-static void Out(const std::string& s) {
-  // Avoid printf and C strings, since the actual output might contain null
-  // bytes like UTF-16 does (yuck).
-  fwrite(s.data(), 1, s.size(), stdout);
-}
-
-void LinePrinter::Print(string to_print, LineType type) {
-  if (!smart_terminal_) {
-    if (type == LineType::INFO) {
-        info_line_ = to_print + "\n";
-    } else {
-        Out(to_print + "\n");
-    }
-    return;
-  }
-
-  // Print over previous line, if any.
-  // On Windows, calling a C library function writing to stdout also handles
-  // pausing the executable when the "Pause" key or Ctrl-S is pressed.
-  printf("\r");
-
-  if (type == INFO) {
-#ifdef _WIN32
-    CONSOLE_SCREEN_BUFFER_INFO csbi;
-    GetConsoleScreenBufferInfo(console_, &csbi);
-
-    to_print = ElideMiddle(to_print, static_cast<size_t>(csbi.dwSize.X));
-    std::wstring to_print_wide;
-    // ElideMiddle may create invalid UTF-8, so ignore conversion errors.
-    (void)android::base::UTF8ToWide(to_print, &to_print_wide);
-    // We don't want to have the cursor spamming back and forth, so instead of
-    // printf use WriteConsoleOutput which updates the contents of the buffer,
-    // but doesn't move the cursor position.
-    COORD buf_size = { csbi.dwSize.X, 1 };
-    COORD zero_zero = { 0, 0 };
-    SMALL_RECT target = {
-      csbi.dwCursorPosition.X, csbi.dwCursorPosition.Y,
-      static_cast<SHORT>(csbi.dwCursorPosition.X + csbi.dwSize.X - 1),
-      csbi.dwCursorPosition.Y
-    };
-    vector<CHAR_INFO> char_data(csbi.dwSize.X);
-    for (size_t i = 0; i < static_cast<size_t>(csbi.dwSize.X); ++i) {
-        char_data[i].Char.UnicodeChar = i < to_print_wide.size() ? to_print_wide[i] : L' ';
-        char_data[i].Attributes = csbi.wAttributes;
-    }
-    WriteConsoleOutputW(console_, &char_data[0], buf_size, zero_zero, &target);
-#else
-    // Limit output to width of the terminal if provided so we don't cause
-    // line-wrapping.
-    winsize size;
-    if ((ioctl(0, TIOCGWINSZ, &size) == 0) && size.ws_col) {
-      to_print = ElideMiddle(to_print, size.ws_col);
-    }
-    Out(to_print);
-    printf("\x1B[K");  // Clear to end of line.
-    fflush(stdout);
-#endif
-
-    have_blank_line_ = false;
-  } else {
-    Out(to_print);
-    Out("\n");
-    have_blank_line_ = true;
-  }
-}
-
-void LinePrinter::KeepInfoLine() {
-  if (smart_terminal_) {
-      if (!have_blank_line_) Out("\n");
-      have_blank_line_ = true;
-  } else {
-      Out(info_line_);
-      info_line_.clear();
-  }
-}
diff --git a/adb/client/line_printer.h b/adb/client/line_printer.h
deleted file mode 100644
index 4c4c7c6..0000000
--- a/adb/client/line_printer.h
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2013 Google Inc. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef NINJA_LINE_PRINTER_H_
-#define NINJA_LINE_PRINTER_H_
-
-#include <stddef.h>
-#include <string>
-
-/// Prints lines of text, possibly overprinting previously printed lines
-/// if the terminal supports it.
-struct LinePrinter {
-  LinePrinter();
-
-  bool is_smart_terminal() const { return smart_terminal_; }
-  void set_smart_terminal(bool smart) { smart_terminal_ = smart; }
-
-  enum LineType { INFO, WARNING, ERROR };
-
-  /// Outputs the given line. INFO output will be overwritten.
-  /// WARNING and ERROR appear on a line to themselves.
-  void Print(std::string to_print, LineType type);
-
-  /// If there's an INFO line, keep it. If not, do nothing.
-  void KeepInfoLine();
-
- private:
-  /// Whether we can do fancy terminal control codes.
-  bool smart_terminal_;
-
-  /// Whether the caret is at the beginning of a blank line.
-  bool have_blank_line_;
-
-  /// The last printed info line when printing to a dumb terminal.
-  std::string info_line_;
-
-#ifdef _WIN32
-  void* console_;
-#endif
-};
-
-#endif  // NINJA_LINE_PRINTER_H_
diff --git a/adb/client/main.cpp b/adb/client/main.cpp
deleted file mode 100644
index 78f7b8f..0000000
--- a/adb/client/main.cpp
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define TRACE_TAG ADB
-
-#include "sysdeps.h"
-
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include <thread>
-
-#include <android-base/errors.h>
-#include <android-base/file.h>
-#include <android-base/logging.h>
-#include <android-base/stringprintf.h>
-
-#include "adb.h"
-#include "adb_auth.h"
-#include "adb_client.h"
-#include "adb_listeners.h"
-#include "adb_utils.h"
-#include "adb_wifi.h"
-#include "client/usb.h"
-#include "commandline.h"
-#include "sysdeps/chrono.h"
-#include "transport.h"
-
-const char** __adb_argv;
-const char** __adb_envp;
-
-static void setup_daemon_logging() {
-    const std::string log_file_path(GetLogFilePath());
-    int fd = unix_open(log_file_path, O_WRONLY | O_CREAT | O_APPEND, 0640);
-    if (fd == -1) {
-        PLOG(FATAL) << "cannot open " << log_file_path;
-    }
-    if (dup2(fd, STDOUT_FILENO) == -1) {
-        PLOG(FATAL) << "cannot redirect stdout";
-    }
-    if (dup2(fd, STDERR_FILENO) == -1) {
-        PLOG(FATAL) << "cannot redirect stderr";
-    }
-    unix_close(fd);
-
-    fprintf(stderr, "--- adb starting (pid %d) ---\n", getpid());
-    LOG(INFO) << adb_version();
-}
-
-void adb_server_cleanup() {
-    // Upon exit, we want to clean up in the following order:
-    //   1. close_smartsockets, so that we don't get any new clients
-    //   2. kick_all_transports, to avoid writing only part of a packet to a transport.
-    //   3. usb_cleanup, to tear down the USB stack.
-    close_smartsockets();
-    kick_all_transports();
-    usb_cleanup();
-}
-
-static void intentionally_leak() {
-    void* p = ::operator new(1);
-    // The analyzer is upset about this leaking. NOLINTNEXTLINE
-    LOG(INFO) << "leaking pointer " << p;
-}
-
-int adb_server_main(int is_daemon, const std::string& socket_spec, int ack_reply_fd) {
-#if defined(_WIN32)
-    // adb start-server starts us up with stdout and stderr hooked up to
-    // anonymous pipes. When the C Runtime sees this, it makes stderr and
-    // stdout buffered, but to improve the chance that error output is seen,
-    // unbuffer stdout and stderr just like if we were run at the console.
-    // This also keeps stderr unbuffered when it is redirected to adb.log.
-    if (is_daemon) {
-        if (setvbuf(stdout, nullptr, _IONBF, 0) == -1) {
-            PLOG(FATAL) << "cannot make stdout unbuffered";
-        }
-        if (setvbuf(stderr, nullptr, _IONBF, 0) == -1) {
-            PLOG(FATAL) << "cannot make stderr unbuffered";
-        }
-    }
-
-    // TODO: On Ctrl-C, consider trying to kill a starting up adb server (if we're in
-    // launch_server) by calling GenerateConsoleCtrlEvent().
-
-    // On Windows, SIGBREAK is when Ctrl-Break is pressed or the console window is closed. It should
-    // act like Ctrl-C.
-    signal(SIGBREAK, [](int) { raise(SIGINT); });
-#endif
-    signal(SIGINT, [](int) {
-        fdevent_run_on_main_thread([]() { exit(0); });
-    });
-
-    char* leak = getenv("ADB_LEAK");
-    if (leak && strcmp(leak, "1") == 0) {
-        intentionally_leak();
-    }
-
-    if (is_daemon) {
-        close_stdin();
-        setup_daemon_logging();
-    }
-
-    atexit(adb_server_cleanup);
-
-    init_transport_registration();
-    init_reconnect_handler();
-
-    adb_wifi_init();
-    if (!getenv("ADB_MDNS") || strcmp(getenv("ADB_MDNS"), "0") != 0) {
-        init_mdns_transport_discovery();
-    }
-
-    if (!getenv("ADB_USB") || strcmp(getenv("ADB_USB"), "0") != 0) {
-        usb_init();
-    } else {
-        adb_notify_device_scan_complete();
-    }
-
-    if (!getenv("ADB_EMU") || strcmp(getenv("ADB_EMU"), "0") != 0) {
-        local_init(android::base::StringPrintf("tcp:%d", DEFAULT_ADB_LOCAL_TRANSPORT_PORT));
-    }
-
-    std::string error;
-
-    auto start = std::chrono::steady_clock::now();
-
-    // If we told a previous adb server to quit because of version mismatch, we can get to this
-    // point before it's finished exiting. Retry for a while to give it some time.
-    while (install_listener(socket_spec, "*smartsocket*", nullptr, 0, nullptr, &error) !=
-           INSTALL_STATUS_OK) {
-        if (std::chrono::steady_clock::now() - start > 0.5s) {
-            LOG(FATAL) << "could not install *smartsocket* listener: " << error;
-        }
-
-        std::this_thread::sleep_for(100ms);
-    }
-
-    adb_auth_init();
-
-    if (is_daemon) {
-#if !defined(_WIN32)
-        // Start a new session for the daemon. Do this here instead of after the fork so
-        // that a ctrl-c between the "starting server" and "done starting server" messages
-        // gets a chance to terminate the server.
-        // setsid will fail with EPERM if it's already been a lead process of new session.
-        // Ignore such error.
-        if (setsid() == -1 && errno != EPERM) {
-            PLOG(FATAL) << "setsid() failed";
-        }
-#endif
-
-        // Wait for the USB scan to complete before notifying the parent that we're up.
-        // We need to perform this in a thread, because we would otherwise block the event loop.
-        std::thread notify_thread([ack_reply_fd]() {
-            adb_wait_for_device_initialization();
-
-            // Any error output written to stderr now goes to adb.log. We could
-            // keep around a copy of the stderr fd and use that to write any errors
-            // encountered by the following code, but that is probably overkill.
-#if defined(_WIN32)
-            const HANDLE ack_reply_handle = cast_int_to_handle(ack_reply_fd);
-            const CHAR ack[] = "OK\n";
-            const DWORD bytes_to_write = arraysize(ack) - 1;
-            DWORD written = 0;
-            if (!WriteFile(ack_reply_handle, ack, bytes_to_write, &written, NULL)) {
-                LOG(FATAL) << "cannot write ACK to handle " << ack_reply_handle
-                           << android::base::SystemErrorCodeToString(GetLastError());
-            }
-            if (written != bytes_to_write) {
-                LOG(FATAL) << "cannot write " << bytes_to_write << " bytes of ACK: only wrote "
-                           << written << " bytes";
-            }
-            CloseHandle(ack_reply_handle);
-#else
-            // TODO(danalbert): Can't use SendOkay because we're sending "OK\n", not
-            // "OKAY".
-            if (!android::base::WriteStringToFd("OK\n", ack_reply_fd)) {
-                PLOG(FATAL) << "error writing ACK to fd " << ack_reply_fd;
-            }
-            unix_close(ack_reply_fd);
-#endif
-        });
-        notify_thread.detach();
-    }
-
-#if defined(__linux__)
-    // Write our location to .android/adb.$PORT, so that older clients can exec us.
-    std::string path;
-    if (!android::base::Readlink("/proc/self/exe", &path)) {
-        PLOG(ERROR) << "failed to readlink /proc/self/exe";
-    }
-
-    std::optional<std::string> server_executable_path = adb_get_server_executable_path();
-    if (server_executable_path) {
-      if (!android::base::WriteStringToFile(path, *server_executable_path)) {
-          PLOG(ERROR) << "failed to write server path to " << path;
-      }
-    }
-#endif
-
-    D("Event loop starting");
-    fdevent_loop();
-    return 0;
-}
-
-int main(int argc, char* argv[], char* envp[]) {
-    __adb_argv = const_cast<const char**>(argv);
-    __adb_envp = const_cast<const char**>(envp);
-    adb_trace_init(argv);
-    return adb_commandline(argc - 1, const_cast<const char**>(argv + 1));
-}
diff --git a/adb/client/pairing/pairing_client.cpp b/adb/client/pairing/pairing_client.cpp
deleted file mode 100644
index 04bbceb..0000000
--- a/adb/client/pairing/pairing_client.cpp
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "client/pairing/pairing_client.h"
-
-#include <atomic>
-#include <iomanip>
-#include <mutex>
-#include <sstream>
-#include <thread>
-#include <vector>
-
-#include <android-base/logging.h>
-#include <android-base/parsenetaddress.h>
-#include <android-base/stringprintf.h>
-#include <android-base/thread_annotations.h>
-#include <android-base/unique_fd.h>
-#include <cutils/sockets.h>
-#include "sysdeps.h"
-
-namespace adbwifi {
-namespace pairing {
-
-using android::base::unique_fd;
-
-namespace {
-
-struct ConnectionDeleter {
-    void operator()(PairingConnectionCtx* p) { pairing_connection_destroy(p); }
-};  // ConnectionDeleter
-using ConnectionPtr = std::unique_ptr<PairingConnectionCtx, ConnectionDeleter>;
-
-class PairingClientImpl : public PairingClient {
-  public:
-    virtual ~PairingClientImpl();
-
-    explicit PairingClientImpl(const Data& pswd, const PeerInfo& peer_info, const Data& cert,
-                               const Data& priv_key);
-
-    // Starts the pairing client. This call is non-blocking. Upon pairing
-    // completion, |cb| will be called with the PeerInfo on success,
-    // or an empty value on failure.
-    //
-    // Returns true if PairingClient was successfully started. Otherwise,
-    // return false.
-    virtual bool Start(std::string_view ip_addr, pairing_client_result_cb cb,
-                       void* opaque) override;
-
-    static void OnPairingResult(const PeerInfo* peer_info, int fd, void* opaque);
-
-  private:
-    // Setup and start the PairingConnection
-    bool StartConnection();
-
-    enum class State {
-        Ready,
-        Running,
-        Stopped,
-    };
-
-    State state_ = State::Ready;
-    Data pswd_;
-    PeerInfo peer_info_;
-    Data cert_;
-    Data priv_key_;
-    std::string host_;
-    int port_;
-
-    ConnectionPtr connection_;
-    pairing_client_result_cb cb_;
-    void* opaque_ = nullptr;
-};  // PairingClientImpl
-
-PairingClientImpl::PairingClientImpl(const Data& pswd, const PeerInfo& peer_info, const Data& cert,
-                                     const Data& priv_key)
-    : pswd_(pswd), peer_info_(peer_info), cert_(cert), priv_key_(priv_key) {
-    CHECK(!pswd_.empty() && !cert_.empty() && !priv_key_.empty());
-
-    state_ = State::Ready;
-}
-
-PairingClientImpl::~PairingClientImpl() {
-    // Make sure to kill the PairingConnection before terminating the fdevent
-    // looper.
-    if (connection_ != nullptr) {
-        connection_.reset();
-    }
-}
-
-bool PairingClientImpl::Start(std::string_view ip_addr, pairing_client_result_cb cb, void* opaque) {
-    CHECK(!ip_addr.empty());
-    cb_ = cb;
-    opaque_ = opaque;
-
-    if (state_ != State::Ready) {
-        LOG(ERROR) << "PairingClient already running or finished";
-        return false;
-    }
-
-    // Try to parse the host address
-    std::string err;
-    CHECK(android::base::ParseNetAddress(std::string(ip_addr), &host_, &port_, nullptr, &err));
-    CHECK(port_ > 0 && port_ <= 65535);
-
-    if (!StartConnection()) {
-        LOG(ERROR) << "Unable to start PairingClient connection";
-        state_ = State::Stopped;
-        return false;
-    }
-
-    state_ = State::Running;
-    return true;
-}
-
-bool PairingClientImpl::StartConnection() {
-    std::string err;
-    const int timeout = 10;  // seconds
-    unique_fd fd(network_connect(host_, port_, SOCK_STREAM, timeout, &err));
-    if (fd.get() == -1) {
-        LOG(ERROR) << "Failed to start pairing connection client [" << err << "]";
-        return false;
-    }
-    int off = 1;
-    adb_setsockopt(fd.get(), IPPROTO_TCP, TCP_NODELAY, &off, sizeof(off));
-
-    connection_ = ConnectionPtr(
-            pairing_connection_client_new(pswd_.data(), pswd_.size(), &peer_info_, cert_.data(),
-                                          cert_.size(), priv_key_.data(), priv_key_.size()));
-    CHECK(connection_);
-
-#ifdef _WIN32
-    int osh = cast_handle_to_int(adb_get_os_handle(fd.release()));
-#else
-    int osh = adb_get_os_handle(fd.release());
-#endif
-    if (!pairing_connection_start(connection_.get(), osh, OnPairingResult, this)) {
-        LOG(ERROR) << "PairingClient failed to start the PairingConnection";
-        state_ = State::Stopped;
-        return false;
-    }
-
-    return true;
-}
-
-// static
-void PairingClientImpl::OnPairingResult(const PeerInfo* peer_info, int /* fd */, void* opaque) {
-    auto* p = reinterpret_cast<PairingClientImpl*>(opaque);
-    p->cb_(peer_info, p->opaque_);
-}
-
-}  // namespace
-
-// static
-std::unique_ptr<PairingClient> PairingClient::Create(const Data& pswd, const PeerInfo& peer_info,
-                                                     const Data& cert, const Data& priv_key) {
-    CHECK(!pswd.empty());
-    CHECK(!cert.empty());
-    CHECK(!priv_key.empty());
-
-    return std::unique_ptr<PairingClient>(new PairingClientImpl(pswd, peer_info, cert, priv_key));
-}
-
-}  // namespace pairing
-}  // namespace adbwifi
diff --git a/adb/client/pairing/pairing_client.h b/adb/client/pairing/pairing_client.h
deleted file mode 100644
index dbd72a5..0000000
--- a/adb/client/pairing/pairing_client.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <functional>
-#include <memory>
-#include <string_view>
-#include <vector>
-
-#include "adb/pairing/pairing_connection.h"
-
-namespace adbwifi {
-namespace pairing {
-
-typedef void (*pairing_client_result_cb)(const PeerInfo*, void*);
-
-// PairingClient is the client side of the PairingConnection protocol. It will
-// attempt to connect to a PairingServer specified at |host| and |port|, and
-// allocate a new PairingConnection for processing.
-//
-// See pairing_connection_test.cpp for example usage.
-//
-class PairingClient {
-  public:
-    using Data = std::vector<uint8_t>;
-
-    virtual ~PairingClient() = default;
-
-    // Starts the pairing client. This call is non-blocking. Upon completion,
-    // if the pairing was successful, then |cb| will be called with the PeerInfo
-    // containing the info of the trusted peer. Otherwise, |cb| will be
-    // called with an empty value. Start can only be called once in the lifetime
-    // of this object.
-    //
-    // Returns true if PairingClient was successfully started. Otherwise,
-    // returns false.
-    virtual bool Start(std::string_view ip_addr, pairing_client_result_cb cb, void* opaque) = 0;
-
-    // Creates a new PairingClient instance. May return null if unable
-    // to create an instance. |pswd|, |certificate|, |priv_key| and
-    // |ip_addr| cannot be empty. |peer_info| must contain non-empty strings for
-    // the guid and name fields.
-    static std::unique_ptr<PairingClient> Create(const Data& pswd, const PeerInfo& peer_info,
-                                                 const Data& certificate, const Data& priv_key);
-
-  protected:
-    PairingClient() = default;
-};  // class PairingClient
-
-}  // namespace pairing
-}  // namespace adbwifi
diff --git a/adb/client/pairing/tests/pairing_connection_test.cpp b/adb/client/pairing/tests/pairing_connection_test.cpp
deleted file mode 100644
index c69c1c2..0000000
--- a/adb/client/pairing/tests/pairing_connection_test.cpp
+++ /dev/null
@@ -1,473 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "AdbWifiPairingConnectionTest"
-
-#include <condition_variable>
-#include <mutex>
-#include <thread>
-
-#include <adbwifi/pairing/pairing_server.h>
-#include <android-base/logging.h>
-#include <gtest/gtest.h>
-
-#include "adb/client/pairing/tests/pairing_client.h"
-
-namespace adbwifi {
-namespace pairing {
-
-static const std::string kTestServerCert =
-        "-----BEGIN CERTIFICATE-----\n"
-        "MIIBljCCAT2gAwIBAgIBATAKBggqhkjOPQQDAjAzMQswCQYDVQQGEwJVUzEQMA4G\n"
-        "A1UECgwHQW5kcm9pZDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTE5MTEwNzAyMDkx\n"
-        "NVoXDTI5MTEwNDAyMDkxNVowMzELMAkGA1UEBhMCVVMxEDAOBgNVBAoMB0FuZHJv\n"
-        "aWQxEjAQBgNVBAMMCWxvY2FsaG9zdDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IA\n"
-        "BCXRovy3RhtK0Khle48vUmkcuI0OF7K8o9sVPE4oVnp24l+cCYr3BtrgifoHPgj4\n"
-        "vq7n105qzK7ngBHH+LBmYIijQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/\n"
-        "BAQDAgGGMB0GA1UdDgQWBBQi4eskzqVG3SCX2CwJF/aTZqUcuTAKBggqhkjOPQQD\n"
-        "AgNHADBEAiBPYvLOCIvPDtq3vMF7A2z7t7JfcCmbC7g8ftEVJucJBwIgepf+XjTb\n"
-        "L7RCE16p7iVkpHUrWAOl7zDxqD+jaji5MkQ=\n"
-        "-----END CERTIFICATE-----\n";
-
-static const std::string kTestServerPrivKey =
-        "-----BEGIN PRIVATE KEY-----\n"
-        "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgSCaskWPtutIgh8uQ\n"
-        "UBH6ZIea5Kxm7m6kkGNkd8FYPSOhRANCAAQl0aL8t0YbStCoZXuPL1JpHLiNDhey\n"
-        "vKPbFTxOKFZ6duJfnAmK9wba4In6Bz4I+L6u59dOasyu54ARx/iwZmCI\n"
-        "-----END PRIVATE KEY-----\n";
-
-static const std::string kTestClientCert =
-        "-----BEGIN CERTIFICATE-----\n"
-        "MIIBlzCCAT2gAwIBAgIBATAKBggqhkjOPQQDAjAzMQswCQYDVQQGEwJVUzEQMA4G\n"
-        "A1UECgwHQW5kcm9pZDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTE5MTEwOTAxNTAy\n"
-        "OFoXDTI5MTEwNjAxNTAyOFowMzELMAkGA1UEBhMCVVMxEDAOBgNVBAoMB0FuZHJv\n"
-        "aWQxEjAQBgNVBAMMCWxvY2FsaG9zdDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IA\n"
-        "BGW+RuoEIzbt42zAuZzbXaC0bvh8n4OLFDnqkkW6kWA43GYg/mUMVc9vg/nuxyuM\n"
-        "aT0KqbTaLhm+NjCXVRnxBrajQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/\n"
-        "BAQDAgGGMB0GA1UdDgQWBBTjCaC8/NXgdBz9WlMVCNwhx7jn0jAKBggqhkjOPQQD\n"
-        "AgNIADBFAiB/xp2boj7b1KK2saS6BL59deo/TvfgZ+u8HPq4k4VP3gIhAMXswp9W\n"
-        "XdlziccQdj+0KpbUojDKeHOr4fIj/+LxsWPa\n"
-        "-----END CERTIFICATE-----\n";
-
-static const std::string kTestClientPrivKey =
-        "-----BEGIN PRIVATE KEY-----\n"
-        "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgFw/CWY1f6TSB70AF\n"
-        "yVe8n6QdYFu8HW5t/tij2SrXx42hRANCAARlvkbqBCM27eNswLmc212gtG74fJ+D\n"
-        "ixQ56pJFupFgONxmIP5lDFXPb4P57scrjGk9Cqm02i4ZvjYwl1UZ8Qa2\n"
-        "-----END PRIVATE KEY-----\n";
-
-class AdbWifiPairingConnectionTest : public testing::Test {
-  protected:
-    virtual void SetUp() override {}
-
-    virtual void TearDown() override {}
-
-    void initPairing(const std::vector<uint8_t> server_pswd,
-                     const std::vector<uint8_t> client_pswd) {
-        std::vector<uint8_t> cert;
-        std::vector<uint8_t> key;
-        // Include the null-byte as well.
-        cert.assign(reinterpret_cast<const uint8_t*>(kTestServerCert.data()),
-                    reinterpret_cast<const uint8_t*>(kTestServerCert.data()) +
-                            kTestServerCert.size() + 1);
-        key.assign(reinterpret_cast<const uint8_t*>(kTestServerPrivKey.data()),
-                   reinterpret_cast<const uint8_t*>(kTestServerPrivKey.data()) +
-                           kTestServerPrivKey.size() + 1);
-        server_ = PairingServer::create(server_pswd, server_info_, cert, key, kDefaultPairingPort);
-        cert.assign(reinterpret_cast<const uint8_t*>(kTestClientCert.data()),
-                    reinterpret_cast<const uint8_t*>(kTestClientCert.data()) +
-                            kTestClientCert.size() + 1);
-        key.assign(reinterpret_cast<const uint8_t*>(kTestClientPrivKey.data()),
-                   reinterpret_cast<const uint8_t*>(kTestClientPrivKey.data()) +
-                           kTestClientPrivKey.size() + 1);
-        client_ = PairingClient::create(client_pswd, client_info_, cert, key, "127.0.0.1");
-    }
-
-    std::unique_ptr<PairingServer> createServer(const std::vector<uint8_t> pswd) {
-        std::vector<uint8_t> cert;
-        std::vector<uint8_t> key;
-        // Include the null-byte as well.
-        cert.assign(reinterpret_cast<const uint8_t*>(kTestServerCert.data()),
-                    reinterpret_cast<const uint8_t*>(kTestServerCert.data()) +
-                            kTestServerCert.size() + 1);
-        key.assign(reinterpret_cast<const uint8_t*>(kTestServerPrivKey.data()),
-                   reinterpret_cast<const uint8_t*>(kTestServerPrivKey.data()) +
-                           kTestServerPrivKey.size() + 1);
-        return PairingServer::create(pswd, server_info_, cert, key, kDefaultPairingPort);
-    }
-
-    std::unique_ptr<PairingClient> createClient(const std::vector<uint8_t> pswd) {
-        std::vector<uint8_t> cert;
-        std::vector<uint8_t> key;
-        // Include the null-byte as well.
-        cert.assign(reinterpret_cast<const uint8_t*>(kTestClientCert.data()),
-                    reinterpret_cast<const uint8_t*>(kTestClientCert.data()) +
-                            kTestClientCert.size() + 1);
-        key.assign(reinterpret_cast<const uint8_t*>(kTestClientPrivKey.data()),
-                   reinterpret_cast<const uint8_t*>(kTestClientPrivKey.data()) +
-                           kTestClientPrivKey.size() + 1);
-        return PairingClient::create(pswd, client_info_, cert, key, "127.0.0.1");
-    }
-
-    std::unique_ptr<PairingServer> server_;
-    const PeerInfo server_info_ = {
-            .name = "my_server_name",
-            .guid = "my_server_guid",
-    };
-    std::unique_ptr<PairingClient> client_;
-    const PeerInfo client_info_ = {
-            .name = "my_client_name",
-            .guid = "my_client_guid",
-    };
-};
-
-TEST_F(AdbWifiPairingConnectionTest, ServerCreation) {
-    // All parameters bad
-    auto server = PairingServer::create({}, {}, {}, {}, -1);
-    EXPECT_EQ(nullptr, server);
-    // Bad password
-    server = PairingServer::create({}, server_info_, {0x01}, {0x01}, -1);
-    EXPECT_EQ(nullptr, server);
-    // Bad peer_info
-    server = PairingServer::create({0x01}, {}, {0x01}, {0x01}, -1);
-    EXPECT_EQ(nullptr, server);
-    // Bad certificate
-    server = PairingServer::create({0x01}, server_info_, {}, {0x01}, -1);
-    EXPECT_EQ(nullptr, server);
-    // Bad private key
-    server = PairingServer::create({0x01}, server_info_, {0x01}, {}, -1);
-    EXPECT_EQ(nullptr, server);
-    // Bad port
-    server = PairingServer::create({0x01}, server_info_, {0x01}, {0x01}, -1);
-    EXPECT_EQ(nullptr, server);
-    // Valid params
-    server = PairingServer::create({0x01}, server_info_, {0x01}, {0x01}, 7776);
-    EXPECT_NE(nullptr, server);
-}
-
-TEST_F(AdbWifiPairingConnectionTest, ClientCreation) {
-    // All parameters bad
-    auto client = PairingClient::create({}, client_info_, {}, {}, "");
-    EXPECT_EQ(nullptr, client);
-    // Bad password
-    client = PairingClient::create({}, client_info_, {0x01}, {0x01}, "127.0.0.1");
-    EXPECT_EQ(nullptr, client);
-    // Bad peer_info
-    client = PairingClient::create({0x01}, {}, {0x01}, {0x01}, "127.0.0.1");
-    EXPECT_EQ(nullptr, client);
-    // Bad certificate
-    client = PairingClient::create({0x01}, client_info_, {}, {0x01}, "127.0.0.1");
-    EXPECT_EQ(nullptr, client);
-    // Bad private key
-    client = PairingClient::create({0x01}, client_info_, {0x01}, {}, "127.0.0.1");
-    EXPECT_EQ(nullptr, client);
-    // Bad ip address
-    client = PairingClient::create({0x01}, client_info_, {0x01}, {0x01}, "");
-    EXPECT_EQ(nullptr, client);
-    // Valid params
-    client = PairingClient::create({0x01}, client_info_, {0x01}, {0x01}, "127.0.0.1");
-    EXPECT_NE(nullptr, client);
-}
-
-TEST_F(AdbWifiPairingConnectionTest, SmokeValidPairing) {
-    std::vector<uint8_t> pswd{0x01, 0x03, 0x05, 0x07};
-    initPairing(pswd, pswd);
-
-    // Start the server first, to open the port for connections
-    std::mutex server_mutex;
-    std::condition_variable server_cv;
-    std::unique_lock<std::mutex> server_lock(server_mutex);
-
-    auto server_callback = [&](const PeerInfo* peer_info, const std::vector<uint8_t>* cert,
-                               void* opaque) {
-        ASSERT_NE(nullptr, peer_info);
-        ASSERT_NE(nullptr, cert);
-        EXPECT_FALSE(cert->empty());
-        EXPECT_EQ(nullptr, opaque);
-
-        // Verify the peer_info and cert
-        ASSERT_EQ(strlen(peer_info->name), strlen(client_info_.name));
-        EXPECT_EQ(::memcmp(peer_info->name, client_info_.name, strlen(client_info_.name)), 0);
-        ASSERT_EQ(strlen(peer_info->guid), strlen(client_info_.guid));
-        EXPECT_EQ(::memcmp(peer_info->guid, client_info_.guid, strlen(client_info_.guid)), 0);
-        ASSERT_EQ(cert->size(), kTestClientCert.size() + 1);
-        EXPECT_EQ(::memcmp(cert->data(), kTestClientCert.data(), kTestClientCert.size() + 1), 0);
-
-        std::lock_guard<std::mutex> lock(server_mutex);
-        server_cv.notify_one();
-    };
-    ASSERT_TRUE(server_->start(server_callback, nullptr));
-
-    // Start the client
-    bool got_valid_pairing = false;
-    std::mutex client_mutex;
-    std::condition_variable client_cv;
-    std::unique_lock<std::mutex> client_lock(client_mutex);
-    auto client_callback = [&](const PeerInfo* peer_info, const std::vector<uint8_t>* cert,
-                               void* opaque) {
-        ASSERT_NE(nullptr, peer_info);
-        ASSERT_NE(nullptr, cert);
-        EXPECT_FALSE(cert->empty());
-        EXPECT_EQ(nullptr, opaque);
-
-        // Verify the peer_info and cert
-        ASSERT_EQ(strlen(peer_info->name), strlen(server_info_.name));
-        EXPECT_EQ(::memcmp(peer_info->name, server_info_.name, strlen(server_info_.name)), 0);
-        ASSERT_EQ(strlen(peer_info->guid), strlen(server_info_.guid));
-        EXPECT_EQ(::memcmp(peer_info->guid, server_info_.guid, strlen(server_info_.guid)), 0);
-        ASSERT_EQ(cert->size(), kTestServerCert.size() + 1);
-        EXPECT_EQ(::memcmp(cert->data(), kTestServerCert.data(), kTestServerCert.size() + 1), 0);
-
-        got_valid_pairing = (peer_info != nullptr && cert != nullptr && !cert->empty());
-        std::lock_guard<std::mutex> lock(client_mutex);
-        client_cv.notify_one();
-    };
-    ASSERT_TRUE(client_->start(client_callback, nullptr));
-    client_cv.wait(client_lock);
-
-    // Kill server if the pairing failed, since server only shuts down when
-    // it gets a valid pairing.
-    if (!got_valid_pairing) {
-        server_lock.unlock();
-        server_.reset();
-    } else {
-        server_cv.wait(server_lock);
-    }
-}
-
-TEST_F(AdbWifiPairingConnectionTest, CancelPairing) {
-    std::vector<uint8_t> pswd{0x01, 0x03, 0x05, 0x07};
-    std::vector<uint8_t> pswd2{0x01, 0x03, 0x05, 0x06};
-    initPairing(pswd, pswd2);
-
-    // Start the server first, to open the port for connections
-    std::mutex server_mutex;
-    std::condition_variable server_cv;
-    std::unique_lock<std::mutex> server_lock(server_mutex);
-
-    bool server_got_valid_pairing = true;
-    auto server_callback = [&](const PeerInfo* peer_info, const std::vector<uint8_t>* cert,
-                               void* opaque) {
-        // Pairing will be cancelled, which should initiate this callback with
-        // empty values.
-        ASSERT_EQ(nullptr, peer_info);
-        ASSERT_EQ(nullptr, cert);
-        EXPECT_EQ(nullptr, opaque);
-        std::lock_guard<std::mutex> lock(server_mutex);
-        server_cv.notify_one();
-        server_got_valid_pairing = false;
-    };
-    ASSERT_TRUE(server_->start(server_callback, nullptr));
-
-    // Start the client (should fail because of different passwords).
-    bool got_valid_pairing = false;
-    std::mutex client_mutex;
-    std::condition_variable client_cv;
-    std::unique_lock<std::mutex> client_lock(client_mutex);
-    auto client_callback = [&](const PeerInfo* peer_info, const std::vector<uint8_t>* cert,
-                               void* opaque) {
-        ASSERT_EQ(nullptr, peer_info);
-        ASSERT_EQ(nullptr, cert);
-        EXPECT_EQ(nullptr, opaque);
-
-        got_valid_pairing = (peer_info != nullptr && cert != nullptr && !cert->empty());
-        std::lock_guard<std::mutex> lock(client_mutex);
-        client_cv.notify_one();
-    };
-    ASSERT_TRUE(client_->start(client_callback, nullptr));
-    client_cv.wait(client_lock);
-
-    server_lock.unlock();
-    // This should trigger the callback to be on the same thread.
-    server_.reset();
-    EXPECT_FALSE(server_got_valid_pairing);
-}
-
-TEST_F(AdbWifiPairingConnectionTest, MultipleClientsAllFail) {
-    std::vector<uint8_t> pswd{0x01, 0x03, 0x05, 0x07};
-    std::vector<uint8_t> pswd2{0x01, 0x03, 0x05, 0x06};
-
-    auto server = createServer(pswd);
-    ASSERT_NE(nullptr, server);
-    // Start the server first, to open the port for connections
-    std::mutex server_mutex;
-    std::condition_variable server_cv;
-    std::unique_lock<std::mutex> server_lock(server_mutex);
-
-    bool server_got_valid_pairing = true;
-    auto server_callback = [&](const PeerInfo* peer_info, const std::vector<uint8_t>* cert,
-                               void* opaque) {
-        // Pairing will be cancelled, which should initiate this callback with
-        // empty values.
-        ASSERT_EQ(nullptr, peer_info);
-        ASSERT_EQ(nullptr, cert);
-        EXPECT_EQ(nullptr, opaque);
-        std::lock_guard<std::mutex> lock(server_mutex);
-        server_cv.notify_one();
-        server_got_valid_pairing = false;
-    };
-    ASSERT_TRUE(server->start(server_callback, nullptr));
-
-    // Start multiple clients, all with bad passwords
-    std::vector<std::unique_ptr<PairingClient>> clients;
-    int num_clients_done = 0;
-    int test_num_clients = 5;
-    std::mutex client_mutex;
-    std::condition_variable client_cv;
-    std::unique_lock<std::mutex> client_lock(client_mutex);
-    while (clients.size() < test_num_clients) {
-        auto client = createClient(pswd2);
-        ASSERT_NE(nullptr, client);
-        auto callback = [&](const PeerInfo* peer_info, const std::vector<uint8_t>* cert,
-                            void* opaque) {
-            ASSERT_EQ(nullptr, peer_info);
-            ASSERT_EQ(nullptr, cert);
-            EXPECT_EQ(nullptr, opaque);
-
-            {
-                std::lock_guard<std::mutex> lock(client_mutex);
-                num_clients_done++;
-            }
-            client_cv.notify_one();
-        };
-        ASSERT_TRUE(client->start(callback, nullptr));
-        clients.push_back(std::move(client));
-    }
-
-    client_cv.wait(client_lock, [&]() { return (num_clients_done == test_num_clients); });
-    EXPECT_EQ(num_clients_done, test_num_clients);
-
-    server_lock.unlock();
-    // This should trigger the callback to be on the same thread.
-    server.reset();
-    EXPECT_FALSE(server_got_valid_pairing);
-}
-
-TEST_F(AdbWifiPairingConnectionTest, MultipleClientsOnePass) {
-    // Send multiple clients with bad passwords, but send the last one with the
-    // correct password.
-    std::vector<uint8_t> pswd{0x01, 0x03, 0x05, 0x07};
-    std::vector<uint8_t> pswd2{0x01, 0x03, 0x05, 0x06};
-
-    auto server = createServer(pswd);
-    ASSERT_NE(nullptr, server);
-    // Start the server first, to open the port for connections
-    std::mutex server_mutex;
-    std::condition_variable server_cv;
-    std::unique_lock<std::mutex> server_lock(server_mutex);
-
-    bool server_got_valid_pairing = false;
-    auto server_callback = [&](const PeerInfo* peer_info, const std::vector<uint8_t>* cert,
-                               void* opaque) {
-        // Pairing will be cancelled, which should initiate this callback with
-        // empty values.
-
-        ASSERT_NE(nullptr, peer_info);
-        ASSERT_NE(nullptr, cert);
-        EXPECT_FALSE(cert->empty());
-        EXPECT_EQ(nullptr, opaque);
-
-        // Verify the peer_info and cert
-        ASSERT_EQ(strlen(peer_info->name), strlen(client_info_.name));
-        EXPECT_EQ(::memcmp(peer_info->name, client_info_.name, strlen(client_info_.name)), 0);
-        ASSERT_EQ(strlen(peer_info->guid), strlen(client_info_.guid));
-        EXPECT_EQ(::memcmp(peer_info->guid, client_info_.guid, strlen(client_info_.guid)), 0);
-        ASSERT_EQ(cert->size(), kTestClientCert.size() + 1);
-        EXPECT_EQ(::memcmp(cert->data(), kTestClientCert.data(), kTestClientCert.size() + 1), 0);
-
-        std::lock_guard<std::mutex> lock(server_mutex);
-        server_got_valid_pairing = true;
-        server_cv.notify_one();
-    };
-    ASSERT_TRUE(server->start(server_callback, nullptr));
-
-    // Start multiple clients, all with bad passwords (except for the last one)
-    std::vector<std::unique_ptr<PairingClient>> clients;
-    int num_clients_done = 0;
-    int test_num_clients = 5;
-    std::mutex client_mutex;
-    std::condition_variable client_cv;
-    std::unique_lock<std::mutex> client_lock(client_mutex);
-    bool got_valid_pairing = false;
-    while (clients.size() < test_num_clients) {
-        std::unique_ptr<PairingClient> client;
-        if (clients.size() == test_num_clients - 1) {
-            // Make this one have the valid password
-            client = createClient(pswd);
-            ASSERT_NE(nullptr, client);
-            auto callback = [&](const PeerInfo* peer_info, const std::vector<uint8_t>* cert,
-                                void* opaque) {
-                ASSERT_NE(nullptr, peer_info);
-                ASSERT_NE(nullptr, cert);
-                EXPECT_FALSE(cert->empty());
-                EXPECT_EQ(nullptr, opaque);
-
-                // Verify the peer_info and cert
-                ASSERT_EQ(strlen(peer_info->name), strlen(server_info_.name));
-                EXPECT_EQ(::memcmp(peer_info->name, server_info_.name, strlen(server_info_.name)),
-                          0);
-                ASSERT_EQ(strlen(peer_info->guid), strlen(server_info_.guid));
-                EXPECT_EQ(::memcmp(peer_info->guid, server_info_.guid, strlen(server_info_.guid)),
-                          0);
-                ASSERT_EQ(cert->size(), kTestServerCert.size() + 1);
-                EXPECT_EQ(
-                        ::memcmp(cert->data(), kTestServerCert.data(), kTestServerCert.size() + 1),
-                        0);
-                got_valid_pairing = (peer_info != nullptr && cert != nullptr && !cert->empty());
-
-                {
-                    std::lock_guard<std::mutex> lock(client_mutex);
-                    num_clients_done++;
-                }
-                client_cv.notify_one();
-            };
-            ASSERT_TRUE(client->start(callback, nullptr));
-        } else {
-            client = createClient(pswd2);
-            ASSERT_NE(nullptr, client);
-            auto callback = [&](const PeerInfo* peer_info, const std::vector<uint8_t>* cert,
-                                void* opaque) {
-                ASSERT_EQ(nullptr, peer_info);
-                ASSERT_EQ(nullptr, cert);
-                EXPECT_EQ(nullptr, opaque);
-
-                {
-                    std::lock_guard<std::mutex> lock(client_mutex);
-                    num_clients_done++;
-                }
-                client_cv.notify_one();
-            };
-            ASSERT_TRUE(client->start(callback, nullptr));
-        }
-        clients.push_back(std::move(client));
-    }
-
-    client_cv.wait(client_lock, [&]() { return (num_clients_done == test_num_clients); });
-    EXPECT_EQ(num_clients_done, test_num_clients);
-
-    // Kill server if the pairing failed, since server only shuts down when
-    // it gets a valid pairing.
-    if (!got_valid_pairing) {
-        server_lock.unlock();
-        server_.reset();
-    } else {
-        server_cv.wait(server_lock);
-    }
-    EXPECT_TRUE(server_got_valid_pairing);
-}
-
-}  // namespace pairing
-}  // namespace adbwifi
diff --git a/adb/client/pairing/tests/pairing_server.cpp b/adb/client/pairing/tests/pairing_server.cpp
deleted file mode 100644
index 9201e7a..0000000
--- a/adb/client/pairing/tests/pairing_server.cpp
+++ /dev/null
@@ -1,426 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "adbwifi/pairing/pairing_server.h"
-
-#include <sys/epoll.h>
-#include <sys/eventfd.h>
-
-#include <atomic>
-#include <deque>
-#include <iomanip>
-#include <mutex>
-#include <sstream>
-#include <thread>
-#include <tuple>
-#include <unordered_map>
-#include <variant>
-#include <vector>
-
-#include <adbwifi/pairing/pairing_connection.h>
-#include <android-base/logging.h>
-#include <android-base/parsenetaddress.h>
-#include <android-base/thread_annotations.h>
-#include <android-base/unique_fd.h>
-#include <cutils/sockets.h>
-
-namespace adbwifi {
-namespace pairing {
-
-using android::base::ScopedLockAssertion;
-using android::base::unique_fd;
-
-namespace {
-
-// The implimentation has two background threads running: one to handle and
-// accept any new pairing connection requests (socket accept), and the other to
-// handle connection events (connection started, connection finished).
-class PairingServerImpl : public PairingServer {
-  public:
-    virtual ~PairingServerImpl();
-
-    // All parameters must be non-empty.
-    explicit PairingServerImpl(const Data& pswd, const PeerInfo& peer_info, const Data& cert,
-                               const Data& priv_key, int port);
-
-    // Starts the pairing server. This call is non-blocking. Upon completion,
-    // if the pairing was successful, then |cb| will be called with the PublicKeyHeader
-    // containing the info of the trusted peer. Otherwise, |cb| will be
-    // called with an empty value. Start can only be called once in the lifetime
-    // of this object.
-    //
-    // Returns true if PairingServer was successfully started. Otherwise,
-    // returns false.
-    virtual bool start(PairingConnection::ResultCallback cb, void* opaque) override;
-
-  private:
-    // Setup the server socket to accept incoming connections
-    bool setupServer();
-    // Force stop the server thread.
-    void stopServer();
-
-    // handles a new pairing client connection
-    bool handleNewClientConnection(int fd) EXCLUDES(conn_mutex_);
-
-    // ======== connection events thread =============
-    std::mutex conn_mutex_;
-    std::condition_variable conn_cv_;
-
-    using FdVal = int;
-    using ConnectionPtr = std::unique_ptr<PairingConnection>;
-    using NewConnectionEvent = std::tuple<unique_fd, ConnectionPtr>;
-    // <fd, PeerInfo.name, PeerInfo.guid, certificate>
-    using ConnectionFinishedEvent = std::tuple<FdVal, std::optional<std::string>,
-                                               std::optional<std::string>, std::optional<Data>>;
-    using ConnectionEvent = std::variant<NewConnectionEvent, ConnectionFinishedEvent>;
-    // Queue for connections to write into. We have a separate queue to read
-    // from, in order to minimize the time the server thread is blocked.
-    std::deque<ConnectionEvent> conn_write_queue_ GUARDED_BY(conn_mutex_);
-    std::deque<ConnectionEvent> conn_read_queue_;
-    // Map of fds to their PairingConnections currently running.
-    std::unordered_map<FdVal, ConnectionPtr> connections_;
-
-    // Two threads launched when starting the pairing server:
-    // 1) A server thread that waits for incoming client connections, and
-    // 2) A connection events thread that synchonizes events from all of the
-    //    clients, since each PairingConnection is running in it's own thread.
-    void startConnectionEventsThread();
-    void startServerThread();
-
-    std::thread conn_events_thread_;
-    void connectionEventsWorker();
-    std::thread server_thread_;
-    void serverWorker();
-    bool is_terminate_ GUARDED_BY(conn_mutex_) = false;
-
-    enum class State {
-        Ready,
-        Running,
-        Stopped,
-    };
-    State state_ = State::Ready;
-    Data pswd_;
-    PeerInfo peer_info_;
-    Data cert_;
-    Data priv_key_;
-    int port_ = -1;
-
-    PairingConnection::ResultCallback cb_;
-    void* opaque_ = nullptr;
-    bool got_valid_pairing_ = false;
-
-    static const int kEpollConstSocket = 0;
-    // Used to break the server thread from epoll_wait
-    static const int kEpollConstEventFd = 1;
-    unique_fd epoll_fd_;
-    unique_fd server_fd_;
-    unique_fd event_fd_;
-};  // PairingServerImpl
-
-PairingServerImpl::PairingServerImpl(const Data& pswd, const PeerInfo& peer_info, const Data& cert,
-                                     const Data& priv_key, int port)
-    : pswd_(pswd), peer_info_(peer_info), cert_(cert), priv_key_(priv_key), port_(port) {
-    CHECK(!pswd_.empty() && !cert_.empty() && !priv_key_.empty() && port_ > 0);
-    CHECK('\0' == peer_info.name[kPeerNameLength - 1] &&
-          '\0' == peer_info.guid[kPeerGuidLength - 1] && strlen(peer_info.name) > 0 &&
-          strlen(peer_info.guid) > 0);
-}
-
-PairingServerImpl::~PairingServerImpl() {
-    // Since these connections have references to us, let's make sure they
-    // destruct before us.
-    if (server_thread_.joinable()) {
-        stopServer();
-        server_thread_.join();
-    }
-
-    {
-        std::lock_guard<std::mutex> lock(conn_mutex_);
-        is_terminate_ = true;
-    }
-    conn_cv_.notify_one();
-    if (conn_events_thread_.joinable()) {
-        conn_events_thread_.join();
-    }
-
-    // Notify the cb_ if it hasn't already.
-    if (!got_valid_pairing_ && cb_ != nullptr) {
-        cb_(nullptr, nullptr, opaque_);
-    }
-}
-
-bool PairingServerImpl::start(PairingConnection::ResultCallback cb, void* opaque) {
-    cb_ = cb;
-    opaque_ = opaque;
-
-    if (state_ != State::Ready) {
-        LOG(ERROR) << "PairingServer already running or stopped";
-        return false;
-    }
-
-    if (!setupServer()) {
-        LOG(ERROR) << "Unable to start PairingServer";
-        state_ = State::Stopped;
-        return false;
-    }
-
-    state_ = State::Running;
-    return true;
-}
-
-void PairingServerImpl::stopServer() {
-    if (event_fd_.get() == -1) {
-        return;
-    }
-    uint64_t value = 1;
-    ssize_t rc = write(event_fd_.get(), &value, sizeof(value));
-    if (rc == -1) {
-        // This can happen if the server didn't start.
-        PLOG(ERROR) << "write to eventfd failed";
-    } else if (rc != sizeof(value)) {
-        LOG(FATAL) << "write to event returned short (" << rc << ")";
-    }
-}
-
-bool PairingServerImpl::setupServer() {
-    epoll_fd_.reset(epoll_create1(EPOLL_CLOEXEC));
-    if (epoll_fd_ == -1) {
-        PLOG(ERROR) << "failed to create epoll fd";
-        return false;
-    }
-
-    event_fd_.reset(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
-    if (event_fd_ == -1) {
-        PLOG(ERROR) << "failed to create eventfd";
-        return false;
-    }
-
-    server_fd_.reset(socket_inaddr_any_server(port_, SOCK_STREAM));
-    if (server_fd_.get() == -1) {
-        PLOG(ERROR) << "Failed to start pairing connection server";
-        return false;
-    } else if (fcntl(server_fd_.get(), F_SETFD, FD_CLOEXEC) != 0) {
-        PLOG(ERROR) << "Failed to make server socket cloexec";
-        return false;
-    } else if (fcntl(server_fd_.get(), F_SETFD, O_NONBLOCK) != 0) {
-        PLOG(ERROR) << "Failed to make server socket nonblocking";
-        return false;
-    }
-
-    startConnectionEventsThread();
-    startServerThread();
-    return true;
-}
-
-void PairingServerImpl::startServerThread() {
-    server_thread_ = std::thread([this]() { serverWorker(); });
-}
-
-void PairingServerImpl::startConnectionEventsThread() {
-    conn_events_thread_ = std::thread([this]() { connectionEventsWorker(); });
-}
-
-void PairingServerImpl::serverWorker() {
-    {
-        struct epoll_event event;
-        event.events = EPOLLIN;
-        event.data.u64 = kEpollConstSocket;
-        CHECK_EQ(0, epoll_ctl(epoll_fd_.get(), EPOLL_CTL_ADD, server_fd_.get(), &event));
-    }
-
-    {
-        struct epoll_event event;
-        event.events = EPOLLIN;
-        event.data.u64 = kEpollConstEventFd;
-        CHECK_EQ(0, epoll_ctl(epoll_fd_.get(), EPOLL_CTL_ADD, event_fd_.get(), &event));
-    }
-
-    while (true) {
-        struct epoll_event events[2];
-        int rc = TEMP_FAILURE_RETRY(epoll_wait(epoll_fd_.get(), events, 2, -1));
-        if (rc == -1) {
-            PLOG(ERROR) << "epoll_wait failed";
-            return;
-        } else if (rc == 0) {
-            LOG(ERROR) << "epoll_wait returned 0";
-            return;
-        }
-
-        for (int i = 0; i < rc; ++i) {
-            struct epoll_event& event = events[i];
-            switch (event.data.u64) {
-                case kEpollConstSocket:
-                    handleNewClientConnection(server_fd_.get());
-                    break;
-                case kEpollConstEventFd:
-                    uint64_t dummy;
-                    int rc = TEMP_FAILURE_RETRY(read(event_fd_.get(), &dummy, sizeof(dummy)));
-                    if (rc != sizeof(dummy)) {
-                        PLOG(FATAL) << "failed to read from eventfd (rc=" << rc << ")";
-                    }
-                    return;
-            }
-        }
-    }
-}
-
-void PairingServerImpl::connectionEventsWorker() {
-    for (;;) {
-        // Transfer the write queue to the read queue.
-        {
-            std::unique_lock<std::mutex> lock(conn_mutex_);
-            ScopedLockAssertion assume_locked(conn_mutex_);
-
-            if (is_terminate_) {
-                // We check |is_terminate_| twice because condition_variable's
-                // notify() only wakes up a thread if it is in the wait state
-                // prior to notify(). Furthermore, we aren't holding the mutex
-                // when processing the events in |conn_read_queue_|.
-                return;
-            }
-            if (conn_write_queue_.empty()) {
-                // We need to wait for new events, or the termination signal.
-                conn_cv_.wait(lock, [this]() REQUIRES(conn_mutex_) {
-                    return (is_terminate_ || !conn_write_queue_.empty());
-                });
-            }
-            if (is_terminate_) {
-                // We're done.
-                return;
-            }
-            // Move all events into the read queue.
-            conn_read_queue_ = std::move(conn_write_queue_);
-            conn_write_queue_.clear();
-        }
-
-        // Process all events in the read queue.
-        while (conn_read_queue_.size() > 0) {
-            auto& event = conn_read_queue_.front();
-            if (auto* p = std::get_if<NewConnectionEvent>(&event)) {
-                // Ignore if we are already at the max number of connections
-                if (connections_.size() >= internal::kMaxConnections) {
-                    conn_read_queue_.pop_front();
-                    continue;
-                }
-                auto [ufd, connection] = std::move(*p);
-                int fd = ufd.release();
-                bool started = connection->start(
-                        fd,
-                        [fd](const PeerInfo* peer_info, const Data* cert, void* opaque) {
-                            auto* p = reinterpret_cast<PairingServerImpl*>(opaque);
-
-                            ConnectionFinishedEvent event;
-                            if (peer_info != nullptr && cert != nullptr) {
-                                event = std::make_tuple(fd, std::string(peer_info->name),
-                                                        std::string(peer_info->guid), Data(*cert));
-                            } else {
-                                event = std::make_tuple(fd, std::nullopt, std::nullopt,
-                                                        std::nullopt);
-                            }
-                            {
-                                std::lock_guard<std::mutex> lock(p->conn_mutex_);
-                                p->conn_write_queue_.push_back(std::move(event));
-                            }
-                            p->conn_cv_.notify_one();
-                        },
-                        this);
-                if (!started) {
-                    LOG(ERROR) << "PairingServer unable to start a PairingConnection fd=" << fd;
-                    ufd.reset(fd);
-                } else {
-                    connections_[fd] = std::move(connection);
-                }
-            } else if (auto* p = std::get_if<ConnectionFinishedEvent>(&event)) {
-                auto [fd, name, guid, cert] = std::move(*p);
-                if (name.has_value() && guid.has_value() && cert.has_value() && !name->empty() &&
-                    !guid->empty() && !cert->empty()) {
-                    // Valid pairing. Let's shutdown the server and close any
-                    // pairing connections in progress.
-                    stopServer();
-                    connections_.clear();
-
-                    CHECK_LE(name->size(), kPeerNameLength);
-                    CHECK_LE(guid->size(), kPeerGuidLength);
-                    PeerInfo info = {};
-                    strncpy(info.name, name->data(), name->size());
-                    strncpy(info.guid, guid->data(), guid->size());
-
-                    cb_(&info, &*cert, opaque_);
-
-                    got_valid_pairing_ = true;
-                    return;
-                }
-                // Invalid pairing. Close the invalid connection.
-                if (connections_.find(fd) != connections_.end()) {
-                    connections_.erase(fd);
-                }
-            }
-            conn_read_queue_.pop_front();
-        }
-    }
-}
-
-bool PairingServerImpl::handleNewClientConnection(int fd) {
-    unique_fd ufd(TEMP_FAILURE_RETRY(accept4(fd, nullptr, nullptr, SOCK_CLOEXEC)));
-    if (ufd == -1) {
-        PLOG(WARNING) << "adb_socket_accept failed fd=" << fd;
-        return false;
-    }
-    auto connection = PairingConnection::create(PairingConnection::Role::Server, pswd_, peer_info_,
-                                                cert_, priv_key_);
-    if (connection == nullptr) {
-        LOG(ERROR) << "PairingServer unable to create a PairingConnection fd=" << fd;
-        return false;
-    }
-    // send the new connection to the connection thread for further processing
-    NewConnectionEvent event = std::make_tuple(std::move(ufd), std::move(connection));
-    {
-        std::lock_guard<std::mutex> lock(conn_mutex_);
-        conn_write_queue_.push_back(std::move(event));
-    }
-    conn_cv_.notify_one();
-
-    return true;
-}
-
-}  // namespace
-
-// static
-std::unique_ptr<PairingServer> PairingServer::create(const Data& pswd, const PeerInfo& peer_info,
-                                                     const Data& cert, const Data& priv_key,
-                                                     int port) {
-    if (pswd.empty() || cert.empty() || priv_key.empty() || port <= 0) {
-        return nullptr;
-    }
-    // Make sure peer_info has a non-empty, null-terminated string for guid and
-    // name.
-    if ('\0' != peer_info.name[kPeerNameLength - 1] ||
-        '\0' != peer_info.guid[kPeerGuidLength - 1] || strlen(peer_info.name) == 0 ||
-        strlen(peer_info.guid) == 0) {
-        LOG(ERROR) << "The GUID/short name fields are empty or not null-terminated";
-        return nullptr;
-    }
-
-    if (port != kDefaultPairingPort) {
-        LOG(WARNING) << "Starting server with non-default pairing port=" << port;
-    }
-
-    return std::unique_ptr<PairingServer>(
-            new PairingServerImpl(pswd, peer_info, cert, priv_key, port));
-}
-
-}  // namespace pairing
-}  // namespace adbwifi
diff --git a/adb/client/pairing/tests/pairing_server.h b/adb/client/pairing/tests/pairing_server.h
deleted file mode 100644
index 6fb51cc..0000000
--- a/adb/client/pairing/tests/pairing_server.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <functional>
-#include <memory>
-#include <string_view>
-#include <vector>
-
-#include <adbwifi/pairing/pairing_connection.h>
-
-namespace adbwifi {
-namespace pairing {
-
-// PairingServer is the server side of the PairingConnection protocol. It will
-// listen for incoming PairingClient connections, and allocate a new
-// PairingConnection per client for processing. PairingServer can handle multiple
-// connections, but the first one to establish the pairing will be the only one
-// to succeed. All others will be disconnected.
-//
-// See pairing_connection_test.cpp for example usage.
-//
-class PairingServer {
-  public:
-    using Data = std::vector<uint8_t>;
-
-    virtual ~PairingServer() = default;
-
-    // Starts the pairing server. This call is non-blocking. Upon completion,
-    // if the pairing was successful, then |cb| will be called with the PeerInfo
-    // containing the info of the trusted peer. Otherwise, |cb| will be
-    // called with an empty value. Start can only be called once in the lifetime
-    // of this object.
-    //
-    // Returns true if PairingServer was successfully started. Otherwise,
-    // returns false.
-    virtual bool start(PairingConnection::ResultCallback cb, void* opaque) = 0;
-
-    // Creates a new PairingServer instance. May return null if unable
-    // to create an instance. |pswd|, |certificate| and |priv_key| cannot
-    // be empty. |port| is the port PairingServer will listen to PairingClient
-    // connections on. |peer_info| must contain non-empty strings for the guid
-    // and name fields.
-    static std::unique_ptr<PairingServer> create(const Data& pswd, const PeerInfo& peer_info,
-                                                 const Data& certificate, const Data& priv_key,
-                                                 int port);
-
-  protected:
-    PairingServer() = default;
-};  // class PairingServer
-
-}  // namespace pairing
-}  // namespace adbwifi
diff --git a/adb/client/transport_mdns.cpp b/adb/client/transport_mdns.cpp
deleted file mode 100644
index 22b9b18..0000000
--- a/adb/client/transport_mdns.cpp
+++ /dev/null
@@ -1,547 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define TRACE_TAG TRANSPORT
-
-#include "transport.h"
-
-#ifdef _WIN32
-#include <winsock2.h>
-#else
-#include <arpa/inet.h>
-#endif
-
-#include <memory>
-#include <thread>
-#include <vector>
-
-#include <android-base/stringprintf.h>
-#include <android-base/strings.h>
-#include <dns_sd.h>
-
-#include "adb_client.h"
-#include "adb_mdns.h"
-#include "adb_trace.h"
-#include "adb_utils.h"
-#include "adb_wifi.h"
-#include "fdevent/fdevent.h"
-#include "sysdeps.h"
-
-static DNSServiceRef service_refs[kNumADBDNSServices];
-static fdevent* service_ref_fdes[kNumADBDNSServices];
-
-static int adb_DNSServiceIndexByName(const char* regType) {
-    for (int i = 0; i < kNumADBDNSServices; ++i) {
-        if (!strncmp(regType, kADBDNSServices[i], strlen(kADBDNSServices[i]))) {
-            return i;
-        }
-    }
-    return -1;
-}
-
-static bool adb_DNSServiceShouldConnect(const char* regType, const char* serviceName) {
-    int index = adb_DNSServiceIndexByName(regType);
-    if (index == kADBTransportServiceRefIndex) {
-        // Ignore adb-EMULATOR* service names, as it interferes with the
-        // emulator ports that are already connected.
-        if (android::base::StartsWith(serviceName, "adb-EMULATOR")) {
-            LOG(INFO) << "Ignoring emulator transport service [" << serviceName << "]";
-            return false;
-        }
-    }
-    return (index == kADBTransportServiceRefIndex || index == kADBSecureConnectServiceRefIndex);
-}
-
-// Use adb_DNSServiceRefSockFD() instead of calling DNSServiceRefSockFD()
-// directly so that the socket is put through the appropriate compatibility
-// layers to work with the rest of ADB's internal APIs.
-static inline int adb_DNSServiceRefSockFD(DNSServiceRef ref) {
-    return adb_register_socket(DNSServiceRefSockFD(ref));
-}
-#define DNSServiceRefSockFD ___xxx_DNSServiceRefSockFD
-
-static void DNSSD_API register_service_ip(DNSServiceRef sdRef,
-                                          DNSServiceFlags flags,
-                                          uint32_t interfaceIndex,
-                                          DNSServiceErrorType errorCode,
-                                          const char* hostname,
-                                          const sockaddr* address,
-                                          uint32_t ttl,
-                                          void* context);
-
-static void pump_service_ref(int /*fd*/, unsigned ev, void* data) {
-    DNSServiceRef* ref = reinterpret_cast<DNSServiceRef*>(data);
-
-    if (ev & FDE_READ)
-        DNSServiceProcessResult(*ref);
-}
-
-class AsyncServiceRef {
-  public:
-    bool Initialized() {
-        return initialized_;
-    }
-
-    virtual ~AsyncServiceRef() {
-        if (!initialized_) {
-            return;
-        }
-
-        // Order matters here! Must destroy the fdevent first since it has a
-        // reference to |sdRef_|.
-        fdevent_destroy(fde_);
-        DNSServiceRefDeallocate(sdRef_);
-    }
-
-  protected:
-    DNSServiceRef sdRef_;
-
-    void Initialize() {
-        fde_ = fdevent_create(adb_DNSServiceRefSockFD(sdRef_), pump_service_ref, &sdRef_);
-        if (fde_ == nullptr) {
-            D("Unable to create fdevent");
-            return;
-        }
-        fdevent_set(fde_, FDE_READ);
-        initialized_ = true;
-    }
-
-  private:
-    bool initialized_ = false;
-    fdevent* fde_;
-};
-
-class ResolvedService : public AsyncServiceRef {
-  public:
-    virtual ~ResolvedService() = default;
-
-    ResolvedService(std::string serviceName, std::string regType, uint32_t interfaceIndex,
-                    const char* hosttarget, uint16_t port, int version)
-        : serviceName_(serviceName),
-          regType_(regType),
-          hosttarget_(hosttarget),
-          port_(port),
-          sa_family_(0),
-          ip_addr_data_(NULL),
-          serviceVersion_(version) {
-        memset(ip_addr_, 0, sizeof(ip_addr_));
-
-        /* TODO: We should be able to get IPv6 support by adding
-         * kDNSServiceProtocol_IPv6 to the flags below. However, when we do
-         * this, we get served link-local addresses that are usually useless to
-         * connect to. What's more, we seem to /only/ get those and nothing else.
-         * If we want IPv6 in the future we'll have to figure out why.
-         */
-        DNSServiceErrorType ret =
-            DNSServiceGetAddrInfo(
-                &sdRef_, 0, interfaceIndex,
-                kDNSServiceProtocol_IPv4, hosttarget,
-                register_service_ip, reinterpret_cast<void*>(this));
-
-        if (ret != kDNSServiceErr_NoError) {
-            D("Got %d from DNSServiceGetAddrInfo.", ret);
-        } else {
-            Initialize();
-        }
-
-        D("Client version: %d Service version: %d\n", clientVersion_, serviceVersion_);
-    }
-
-    bool ConnectSecureWifiDevice() {
-        if (!adb_wifi_is_known_host(serviceName_)) {
-            LOG(INFO) << "serviceName=" << serviceName_ << " not in keystore";
-            return false;
-        }
-
-        std::string response;
-        connect_device(android::base::StringPrintf(addr_format_.c_str(), ip_addr_, port_),
-                       &response);
-        D("Secure connect to %s regtype %s (%s:%hu) : %s", serviceName_.c_str(), regType_.c_str(),
-          ip_addr_, port_, response.c_str());
-        return true;
-    }
-
-    void Connect(const sockaddr* address) {
-        sa_family_ = address->sa_family;
-
-        if (sa_family_ == AF_INET) {
-            ip_addr_data_ = &reinterpret_cast<const sockaddr_in*>(address)->sin_addr;
-            addr_format_ = "%s:%hu";
-        } else if (sa_family_ == AF_INET6) {
-            ip_addr_data_ = &reinterpret_cast<const sockaddr_in6*>(address)->sin6_addr;
-            addr_format_ = "[%s]:%hu";
-        } else {  // Should be impossible
-            D("mDNS resolved non-IP address.");
-            return;
-        }
-
-        // Winsock version requires the const cast Because Microsoft.
-        if (!inet_ntop(sa_family_, const_cast<void*>(ip_addr_data_), ip_addr_, sizeof(ip_addr_))) {
-            D("Could not convert IP address to string.");
-            return;
-        }
-
-        // adb secure service needs to do something different from just
-        // connecting here.
-        if (adb_DNSServiceShouldConnect(regType_.c_str(), serviceName_.c_str())) {
-            std::string response;
-            D("Attempting to serviceName=[%s], regtype=[%s] ipaddr=(%s:%hu)", serviceName_.c_str(),
-              regType_.c_str(), ip_addr_, port_);
-            int index = adb_DNSServiceIndexByName(regType_.c_str());
-            if (index == kADBSecureConnectServiceRefIndex) {
-                ConnectSecureWifiDevice();
-            } else {
-                connect_device(android::base::StringPrintf(addr_format_.c_str(), ip_addr_, port_),
-                               &response);
-                D("Connect to %s regtype %s (%s:%hu) : %s", serviceName_.c_str(), regType_.c_str(),
-                  ip_addr_, port_, response.c_str());
-            }
-        } else {
-            D("Not immediately connecting to serviceName=[%s], regtype=[%s] ipaddr=(%s:%hu)",
-              serviceName_.c_str(), regType_.c_str(), ip_addr_, port_);
-        }
-
-        int adbSecureServiceType = serviceIndex();
-        switch (adbSecureServiceType) {
-            case kADBSecurePairingServiceRefIndex:
-                sAdbSecurePairingServices->push_back(this);
-                break;
-            case kADBSecureConnectServiceRefIndex:
-                sAdbSecureConnectServices->push_back(this);
-                break;
-            default:
-                break;
-        }
-    }
-
-    int serviceIndex() const { return adb_DNSServiceIndexByName(regType_.c_str()); }
-
-    std::string hostTarget() const { return hosttarget_; }
-
-    std::string serviceName() const { return serviceName_; }
-
-    std::string ipAddress() const { return ip_addr_; }
-
-    uint16_t port() const { return port_; }
-
-    using ServiceRegistry = std::vector<ResolvedService*>;
-
-    static ServiceRegistry* sAdbSecurePairingServices;
-    static ServiceRegistry* sAdbSecureConnectServices;
-
-    static void initAdbSecure();
-
-    static void forEachService(const ServiceRegistry& services, const std::string& hostname,
-                               adb_secure_foreach_service_callback cb);
-
-    static bool connectByServiceName(const ServiceRegistry& services,
-                                     const std::string& service_name);
-
-  private:
-    int clientVersion_ = ADB_SECURE_CLIENT_VERSION;
-    std::string addr_format_;
-    std::string serviceName_;
-    std::string regType_;
-    std::string hosttarget_;
-    const uint16_t port_;
-    int sa_family_;
-    const void* ip_addr_data_;
-    char ip_addr_[INET6_ADDRSTRLEN];
-    int serviceVersion_;
-};
-
-// static
-std::vector<ResolvedService*>* ResolvedService::sAdbSecurePairingServices = NULL;
-
-// static
-std::vector<ResolvedService*>* ResolvedService::sAdbSecureConnectServices = NULL;
-
-// static
-void ResolvedService::initAdbSecure() {
-    if (!sAdbSecurePairingServices) {
-        sAdbSecurePairingServices = new ServiceRegistry;
-    }
-    if (!sAdbSecureConnectServices) {
-        sAdbSecureConnectServices = new ServiceRegistry;
-    }
-}
-
-// static
-void ResolvedService::forEachService(const ServiceRegistry& services,
-                                     const std::string& wanted_service_name,
-                                     adb_secure_foreach_service_callback cb) {
-    initAdbSecure();
-
-    for (auto service : services) {
-        auto service_name = service->serviceName();
-        auto ip = service->ipAddress();
-        auto port = service->port();
-
-        if (wanted_service_name == "") {
-            cb(service_name.c_str(), ip.c_str(), port);
-        } else if (service_name == wanted_service_name) {
-            cb(service_name.c_str(), ip.c_str(), port);
-        }
-    }
-}
-
-// static
-bool ResolvedService::connectByServiceName(const ServiceRegistry& services,
-                                           const std::string& service_name) {
-    initAdbSecure();
-    for (auto service : services) {
-        if (service_name == service->serviceName()) {
-            D("Got service_name match [%s]", service->serviceName().c_str());
-            return service->ConnectSecureWifiDevice();
-        }
-    }
-    D("No registered serviceNames matched [%s]", service_name.c_str());
-    return false;
-}
-
-void adb_secure_foreach_pairing_service(const char* service_name,
-                                        adb_secure_foreach_service_callback cb) {
-    ResolvedService::forEachService(*ResolvedService::sAdbSecurePairingServices,
-                                    service_name ? service_name : "", cb);
-}
-
-void adb_secure_foreach_connect_service(const char* service_name,
-                                        adb_secure_foreach_service_callback cb) {
-    ResolvedService::forEachService(*ResolvedService::sAdbSecureConnectServices,
-                                    service_name ? service_name : "", cb);
-}
-
-bool adb_secure_connect_by_service_name(const char* service_name) {
-    return ResolvedService::connectByServiceName(*ResolvedService::sAdbSecureConnectServices,
-                                                 service_name);
-}
-
-static void DNSSD_API register_service_ip(DNSServiceRef /*sdRef*/,
-                                          DNSServiceFlags /*flags*/,
-                                          uint32_t /*interfaceIndex*/,
-                                          DNSServiceErrorType /*errorCode*/,
-                                          const char* /*hostname*/,
-                                          const sockaddr* address,
-                                          uint32_t /*ttl*/,
-                                          void* context) {
-    D("Got IP for service.");
-    std::unique_ptr<ResolvedService> data(
-        reinterpret_cast<ResolvedService*>(context));
-    data->Connect(address);
-
-    // For ADB Secure services, keep those ResolvedService's around
-    // for later processing with secure connection establishment.
-    if (data->serviceIndex() != kADBTransportServiceRefIndex) {
-        data.release();
-    }
-}
-
-static void DNSSD_API register_resolved_mdns_service(DNSServiceRef sdRef,
-                                                     DNSServiceFlags flags,
-                                                     uint32_t interfaceIndex,
-                                                     DNSServiceErrorType errorCode,
-                                                     const char* fullname,
-                                                     const char* hosttarget,
-                                                     uint16_t port,
-                                                     uint16_t txtLen,
-                                                     const unsigned char* txtRecord,
-                                                     void* context);
-
-class DiscoveredService : public AsyncServiceRef {
-  public:
-    DiscoveredService(uint32_t interfaceIndex, const char* serviceName, const char* regtype,
-                      const char* domain)
-        : serviceName_(serviceName), regType_(regtype) {
-        DNSServiceErrorType ret =
-            DNSServiceResolve(&sdRef_, 0, interfaceIndex, serviceName, regtype,
-                              domain, register_resolved_mdns_service,
-                              reinterpret_cast<void*>(this));
-
-        D("DNSServiceResolve for "
-          "interfaceIndex %u "
-          "serviceName %s "
-          "regtype %s "
-          "domain %s "
-          ": %d",
-          interfaceIndex, serviceName, regtype, domain, ret);
-
-        if (ret == kDNSServiceErr_NoError) {
-            Initialize();
-        }
-    }
-
-    const char* ServiceName() {
-        return serviceName_.c_str();
-    }
-
-    const char* RegType() { return regType_.c_str(); }
-
-  private:
-    std::string serviceName_;
-    std::string regType_;
-};
-
-static void adb_RemoveDNSService(const char* regType, const char* serviceName) {
-    int index = adb_DNSServiceIndexByName(regType);
-    ResolvedService::ServiceRegistry* services;
-    switch (index) {
-        case kADBSecurePairingServiceRefIndex:
-            services = ResolvedService::sAdbSecurePairingServices;
-            break;
-        case kADBSecureConnectServiceRefIndex:
-            services = ResolvedService::sAdbSecureConnectServices;
-            break;
-        default:
-            return;
-    }
-
-    std::string sName(serviceName);
-    services->erase(std::remove_if(
-            services->begin(), services->end(),
-            [&sName](ResolvedService* service) { return (sName == service->serviceName()); }));
-}
-
-// Returns the version the device wanted to advertise,
-// or -1 if parsing fails.
-static int parse_version_from_txt_record(uint16_t txtLen, const unsigned char* txtRecord) {
-    if (!txtLen) return -1;
-    if (!txtRecord) return -1;
-
-    // https://tools.ietf.org/html/rfc6763
-    // """
-    // 6.1.  General Format Rules for DNS TXT Records
-    //
-    // A DNS TXT record can be up to 65535 (0xFFFF) bytes long.  The total
-    // length is indicated by the length given in the resource record header
-    // in the DNS message.  There is no way to tell directly from the data
-    // alone how long it is (e.g., there is no length count at the start, or
-    // terminating NULL byte at the end).
-    // """
-
-    // Let's trust the TXT record's length byte
-    // Worst case, it wastes 255 bytes
-    std::vector<char> recordAsString(txtLen + 1, '\0');
-    char* str = recordAsString.data();
-
-    memcpy(str, txtRecord + 1 /* skip the length byte */, txtLen);
-
-    // Check if it's the version key
-    static const char* versionKey = "v=";
-    size_t versionKeyLen = strlen(versionKey);
-
-    if (strncmp(versionKey, str, versionKeyLen)) return -1;
-
-    auto valueStart = str + versionKeyLen;
-
-    long parsedNumber = strtol(valueStart, 0, 10);
-
-    // No valid conversion. Also, 0
-    // is not a valid version.
-    if (!parsedNumber) return -1;
-
-    // Outside bounds of long.
-    if (parsedNumber == LONG_MIN || parsedNumber == LONG_MAX) return -1;
-
-    // Possibly valid version
-    return static_cast<int>(parsedNumber);
-}
-
-static void DNSSD_API register_resolved_mdns_service(
-        DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex,
-        DNSServiceErrorType errorCode, const char* fullname, const char* hosttarget, uint16_t port,
-        uint16_t txtLen, const unsigned char* txtRecord, void* context) {
-    D("Resolved a service.");
-    std::unique_ptr<DiscoveredService> discovered(
-        reinterpret_cast<DiscoveredService*>(context));
-
-    if (errorCode != kDNSServiceErr_NoError) {
-        D("Got error %d resolving service.", errorCode);
-        return;
-    }
-
-    // TODO: Reject certain combinations of invalid or mismatched client and
-    // service versions here before creating anything.
-    // At the moment, there is nothing to reject, so accept everything
-    // as an optimistic default.
-    auto serviceVersion = parse_version_from_txt_record(txtLen, txtRecord);
-
-    auto resolved = new ResolvedService(discovered->ServiceName(), discovered->RegType(),
-                                        interfaceIndex, hosttarget, ntohs(port), serviceVersion);
-
-    if (! resolved->Initialized()) {
-        D("Unable to init resolved service");
-        delete resolved;
-    }
-
-    if (flags) { /* Only ever equals MoreComing or 0 */
-        D("releasing discovered service");
-        discovered.release();
-    }
-}
-
-static void DNSSD_API on_service_browsed(DNSServiceRef sdRef, DNSServiceFlags flags,
-                                         uint32_t interfaceIndex, DNSServiceErrorType errorCode,
-                                         const char* serviceName, const char* regtype,
-                                         const char* domain, void* /*context*/) {
-    if (errorCode != kDNSServiceErr_NoError) {
-        D("Got error %d during mDNS browse.", errorCode);
-        DNSServiceRefDeallocate(sdRef);
-        int serviceIndex = adb_DNSServiceIndexByName(regtype);
-        if (serviceIndex != -1) {
-            fdevent_destroy(service_ref_fdes[serviceIndex]);
-        }
-        return;
-    }
-
-    if (flags & kDNSServiceFlagsAdd) {
-        D("%s: Discover found new serviceName=[%s] regtype=[%s] domain=[%s]", __func__, serviceName,
-          regtype, domain);
-        auto discovered = new DiscoveredService(interfaceIndex, serviceName, regtype, domain);
-        if (!discovered->Initialized()) {
-            delete discovered;
-        }
-    } else {
-        D("%s: Discover lost serviceName=[%s] regtype=[%s] domain=[%s]", __func__, serviceName,
-          regtype, domain);
-        adb_RemoveDNSService(regtype, serviceName);
-    }
-}
-
-void init_mdns_transport_discovery_thread(void) {
-    int errorCodes[kNumADBDNSServices];
-
-    for (int i = 0; i < kNumADBDNSServices; ++i) {
-        errorCodes[i] = DNSServiceBrowse(&service_refs[i], 0, 0, kADBDNSServices[i], nullptr,
-                                         on_service_browsed, nullptr);
-
-        if (errorCodes[i] != kDNSServiceErr_NoError) {
-            D("Got %d browsing for mDNS service %s.", errorCodes[i], kADBDNSServices[i]);
-        }
-
-        if (errorCodes[i] == kDNSServiceErr_NoError) {
-            fdevent_run_on_main_thread([i]() {
-                service_ref_fdes[i] = fdevent_create(adb_DNSServiceRefSockFD(service_refs[i]),
-                                                     pump_service_ref, &service_refs[i]);
-                fdevent_set(service_ref_fdes[i], FDE_READ);
-            });
-        }
-    }
-}
-
-void init_mdns_transport_discovery(void) {
-    ResolvedService::initAdbSecure();
-    std::thread(init_mdns_transport_discovery_thread).detach();
-}
diff --git a/adb/client/transport_usb.cpp b/adb/client/transport_usb.cpp
deleted file mode 100644
index 777edde..0000000
--- a/adb/client/transport_usb.cpp
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define TRACE_TAG TRANSPORT
-
-#include "sysdeps.h"
-
-#include "client/usb.h"
-
-#include <memory>
-
-#include "sysdeps.h"
-#include "transport.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "adb.h"
-
-#if ADB_HOST
-
-#if defined(__APPLE__)
-#define CHECK_PACKET_OVERFLOW 0
-#else
-#define CHECK_PACKET_OVERFLOW 1
-#endif
-
-// Call usb_read using a buffer having a multiple of usb_get_max_packet_size() bytes
-// to avoid overflow. See http://libusb.sourceforge.net/api-1.0/packetoverflow.html.
-static int UsbReadMessage(usb_handle* h, amessage* msg) {
-    D("UsbReadMessage");
-
-#if CHECK_PACKET_OVERFLOW
-    size_t usb_packet_size = usb_get_max_packet_size(h);
-    CHECK_GE(usb_packet_size, sizeof(*msg));
-    CHECK_LT(usb_packet_size, 4096ULL);
-
-    char buffer[4096];
-    int n = usb_read(h, buffer, usb_packet_size);
-    if (n != sizeof(*msg)) {
-        D("usb_read returned unexpected length %d (expected %zu)", n, sizeof(*msg));
-        return -1;
-    }
-    memcpy(msg, buffer, sizeof(*msg));
-    return n;
-#else
-    return usb_read(h, msg, sizeof(*msg));
-#endif
-}
-
-// Call usb_read using a buffer having a multiple of usb_get_max_packet_size() bytes
-// to avoid overflow. See http://libusb.sourceforge.net/api-1.0/packetoverflow.html.
-static int UsbReadPayload(usb_handle* h, apacket* p) {
-    D("UsbReadPayload(%d)", p->msg.data_length);
-
-    if (p->msg.data_length > MAX_PAYLOAD) {
-        return -1;
-    }
-
-#if CHECK_PACKET_OVERFLOW
-    size_t usb_packet_size = usb_get_max_packet_size(h);
-
-    // Round the data length up to the nearest packet size boundary.
-    // The device won't send a zero packet for packet size aligned payloads,
-    // so don't read any more packets than needed.
-    size_t len = p->msg.data_length;
-    size_t rem_size = len % usb_packet_size;
-    if (rem_size) {
-        len += usb_packet_size - rem_size;
-    }
-
-    p->payload.resize(len);
-    int rc = usb_read(h, &p->payload[0], p->payload.size());
-    if (rc != static_cast<int>(p->msg.data_length)) {
-        return -1;
-    }
-
-    p->payload.resize(rc);
-    return rc;
-#else
-    p->payload.resize(p->msg.data_length);
-    return usb_read(h, &p->payload[0], p->payload.size());
-#endif
-}
-
-static int remote_read(apacket* p, usb_handle* usb) {
-    int n = UsbReadMessage(usb, &p->msg);
-    if (n < 0) {
-        D("remote usb: read terminated (message)");
-        return -1;
-    }
-    if (static_cast<size_t>(n) != sizeof(p->msg)) {
-        D("remote usb: read received unexpected header length %d", n);
-        return -1;
-    }
-    if (p->msg.data_length) {
-        n = UsbReadPayload(usb, p);
-        if (n < 0) {
-            D("remote usb: terminated (data)");
-            return -1;
-        }
-        if (static_cast<uint32_t>(n) != p->msg.data_length) {
-            D("remote usb: read payload failed (need %u bytes, give %d bytes), skip it",
-              p->msg.data_length, n);
-            return -1;
-        }
-    }
-    return 0;
-}
-
-#else
-
-// On Android devices, we rely on the kernel to provide buffered read.
-// So we can recover automatically from EOVERFLOW.
-static int remote_read(apacket* p, usb_handle* usb) {
-    if (usb_read(usb, &p->msg, sizeof(amessage)) != sizeof(amessage)) {
-        PLOG(ERROR) << "remote usb: read terminated (message)";
-        return -1;
-    }
-
-    if (p->msg.data_length) {
-        if (p->msg.data_length > MAX_PAYLOAD) {
-            PLOG(ERROR) << "remote usb: read overflow (data length = " << p->msg.data_length << ")";
-            return -1;
-        }
-
-        p->payload.resize(p->msg.data_length);
-        if (usb_read(usb, &p->payload[0], p->payload.size()) !=
-            static_cast<int>(p->payload.size())) {
-            PLOG(ERROR) << "remote usb: terminated (data)";
-            return -1;
-        }
-    }
-
-    return 0;
-}
-#endif
-
-UsbConnection::~UsbConnection() {
-    usb_close(handle_);
-}
-
-bool UsbConnection::Read(apacket* packet) {
-    int rc = remote_read(packet, handle_);
-    return rc == 0;
-}
-
-bool UsbConnection::Write(apacket* packet) {
-    int size = packet->msg.data_length;
-
-    if (usb_write(handle_, &packet->msg, sizeof(packet->msg)) != sizeof(packet->msg)) {
-        PLOG(ERROR) << "remote usb: 1 - write terminated";
-        return false;
-    }
-
-    if (packet->msg.data_length != 0 && usb_write(handle_, packet->payload.data(), size) != size) {
-        PLOG(ERROR) << "remote usb: 2 - write terminated";
-        return false;
-    }
-
-    return true;
-}
-
-bool UsbConnection::DoTlsHandshake(RSA* key, std::string* auth_key) {
-    // TODO: support TLS for usb connections
-    LOG(FATAL) << "Not supported yet.";
-    return false;
-}
-
-void UsbConnection::Reset() {
-    usb_reset(handle_);
-    usb_kick(handle_);
-}
-
-void UsbConnection::Close() {
-    usb_kick(handle_);
-}
-
-void init_usb_transport(atransport* t, usb_handle* h) {
-    D("transport: usb");
-    auto connection = std::make_unique<UsbConnection>(h);
-    t->SetConnection(std::make_unique<BlockingConnectionAdapter>(std::move(connection)));
-    t->type = kTransportUsb;
-    t->SetUsbHandle(h);
-}
-
-int is_adb_interface(int usb_class, int usb_subclass, int usb_protocol) {
-    return (usb_class == ADB_CLASS && usb_subclass == ADB_SUBCLASS && usb_protocol == ADB_PROTOCOL);
-}
-
-bool should_use_libusb() {
-#if !ADB_HOST
-    return false;
-#else
-    static bool enable = getenv("ADB_LIBUSB") && strcmp(getenv("ADB_LIBUSB"), "1") == 0;
-    return enable;
-#endif
-}
diff --git a/adb/client/usb.h b/adb/client/usb.h
deleted file mode 100644
index b371788..0000000
--- a/adb/client/usb.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <sys/types.h>
-
-#include "adb.h"
-#include "transport.h"
-
-// USB host/client interface.
-
-#define ADB_USB_INTERFACE(handle_ref_type)                       \
-    void usb_init();                                             \
-    void usb_cleanup();                                          \
-    int usb_write(handle_ref_type h, const void* data, int len); \
-    int usb_read(handle_ref_type h, void* data, int len);        \
-    int usb_close(handle_ref_type h);                            \
-    void usb_reset(handle_ref_type h);                           \
-    void usb_kick(handle_ref_type h);                            \
-    size_t usb_get_max_packet_size(handle_ref_type)
-
-// Linux and Darwin clients have native and libusb implementations.
-
-namespace libusb {
-struct usb_handle;
-ADB_USB_INTERFACE(libusb::usb_handle*);
-}  // namespace libusb
-
-namespace native {
-struct usb_handle;
-ADB_USB_INTERFACE(native::usb_handle*);
-}  // namespace native
-
-// Empty base that both implementations' opaque handles inherit from.
-struct usb_handle {};
-
-ADB_USB_INTERFACE(::usb_handle*);
-
-// USB device detection.
-int is_adb_interface(int usb_class, int usb_subclass, int usb_protocol);
-
-bool should_use_libusb();
-
-struct UsbConnection : public BlockingConnection {
-    explicit UsbConnection(usb_handle* handle) : handle_(handle) {}
-    ~UsbConnection();
-
-    bool Read(apacket* packet) override final;
-    bool Write(apacket* packet) override final;
-    bool DoTlsHandshake(RSA* key, std::string* auth_key) override final;
-
-    void Close() override final;
-    virtual void Reset() override final;
-
-    usb_handle* handle_;
-};
diff --git a/adb/client/usb_dispatch.cpp b/adb/client/usb_dispatch.cpp
deleted file mode 100644
index 7b97117..0000000
--- a/adb/client/usb_dispatch.cpp
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <android-base/logging.h>
-
-#include "client/usb.h"
-
-void usb_init() {
-    if (should_use_libusb()) {
-        LOG(DEBUG) << "using libusb backend";
-        libusb::usb_init();
-    } else {
-        LOG(DEBUG) << "using native backend";
-        native::usb_init();
-    }
-}
-
-void usb_cleanup() {
-    if (should_use_libusb()) {
-        libusb::usb_cleanup();
-    } else {
-        native::usb_cleanup();
-    }
-}
-
-int usb_write(usb_handle* h, const void* data, int len) {
-    return should_use_libusb()
-               ? libusb::usb_write(reinterpret_cast<libusb::usb_handle*>(h), data, len)
-               : native::usb_write(reinterpret_cast<native::usb_handle*>(h), data, len);
-}
-
-int usb_read(usb_handle* h, void* data, int len) {
-    return should_use_libusb()
-               ? libusb::usb_read(reinterpret_cast<libusb::usb_handle*>(h), data, len)
-               : native::usb_read(reinterpret_cast<native::usb_handle*>(h), data, len);
-}
-
-int usb_close(usb_handle* h) {
-    return should_use_libusb() ? libusb::usb_close(reinterpret_cast<libusb::usb_handle*>(h))
-                               : native::usb_close(reinterpret_cast<native::usb_handle*>(h));
-}
-
-void usb_reset(usb_handle* h) {
-    should_use_libusb() ? libusb::usb_reset(reinterpret_cast<libusb::usb_handle*>(h))
-                        : native::usb_reset(reinterpret_cast<native::usb_handle*>(h));
-}
-
-void usb_kick(usb_handle* h) {
-    should_use_libusb() ? libusb::usb_kick(reinterpret_cast<libusb::usb_handle*>(h))
-                        : native::usb_kick(reinterpret_cast<native::usb_handle*>(h));
-}
-
-size_t usb_get_max_packet_size(usb_handle* h) {
-    return should_use_libusb()
-               ? libusb::usb_get_max_packet_size(reinterpret_cast<libusb::usb_handle*>(h))
-               : native::usb_get_max_packet_size(reinterpret_cast<native::usb_handle*>(h));
-}
diff --git a/adb/client/usb_libusb.cpp b/adb/client/usb_libusb.cpp
deleted file mode 100644
index 07cbc94..0000000
--- a/adb/client/usb_libusb.cpp
+++ /dev/null
@@ -1,638 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "sysdeps.h"
-
-#include "client/usb.h"
-
-#include <stdint.h>
-#include <stdlib.h>
-
-#include <atomic>
-#include <chrono>
-#include <condition_variable>
-#include <memory>
-#include <mutex>
-#include <string>
-#include <thread>
-#include <unordered_map>
-
-#include <libusb/libusb.h>
-
-#include <android-base/file.h>
-#include <android-base/logging.h>
-#include <android-base/stringprintf.h>
-#include <android-base/strings.h>
-
-#include "adb.h"
-#include "adb_utils.h"
-#include "transport.h"
-
-using android::base::StringPrintf;
-
-// RAII wrappers for libusb.
-struct ConfigDescriptorDeleter {
-    void operator()(libusb_config_descriptor* desc) {
-        libusb_free_config_descriptor(desc);
-    }
-};
-
-using unique_config_descriptor = std::unique_ptr<libusb_config_descriptor, ConfigDescriptorDeleter>;
-
-struct DeviceHandleDeleter {
-    void operator()(libusb_device_handle* h) {
-        libusb_close(h);
-    }
-};
-
-using unique_device_handle = std::unique_ptr<libusb_device_handle, DeviceHandleDeleter>;
-
-struct transfer_info {
-    transfer_info(const char* name, uint16_t zero_mask, bool is_bulk_out)
-        : name(name),
-          transfer(libusb_alloc_transfer(0)),
-          is_bulk_out(is_bulk_out),
-          zero_mask(zero_mask) {}
-
-    ~transfer_info() {
-        libusb_free_transfer(transfer);
-    }
-
-    const char* name;
-    libusb_transfer* transfer;
-    bool is_bulk_out;
-    bool transfer_complete;
-    std::condition_variable cv;
-    std::mutex mutex;
-    uint16_t zero_mask;
-
-    void Notify() {
-        LOG(DEBUG) << "notifying " << name << " transfer complete";
-        transfer_complete = true;
-        cv.notify_one();
-    }
-};
-
-namespace libusb {
-struct usb_handle : public ::usb_handle {
-    usb_handle(const std::string& device_address, const std::string& serial,
-               unique_device_handle&& device_handle, uint8_t interface, uint8_t bulk_in,
-               uint8_t bulk_out, size_t zero_mask, size_t max_packet_size)
-        : device_address(device_address),
-          serial(serial),
-          closing(false),
-          device_handle(device_handle.release()),
-          read("read", zero_mask, false),
-          write("write", zero_mask, true),
-          interface(interface),
-          bulk_in(bulk_in),
-          bulk_out(bulk_out),
-          max_packet_size(max_packet_size) {}
-
-    ~usb_handle() {
-        Close();
-    }
-
-    void Close() {
-        std::unique_lock<std::mutex> lock(device_handle_mutex);
-        // Cancelling transfers will trigger more Closes, so make sure this only happens once.
-        if (closing) {
-            return;
-        }
-        closing = true;
-
-        // Make sure that no new transfers come in.
-        libusb_device_handle* handle = device_handle;
-        if (!handle) {
-            return;
-        }
-
-        device_handle = nullptr;
-
-        // Cancel already dispatched transfers.
-        libusb_cancel_transfer(read.transfer);
-        libusb_cancel_transfer(write.transfer);
-
-        libusb_release_interface(handle, interface);
-        libusb_close(handle);
-    }
-
-    std::string device_address;
-    std::string serial;
-
-    std::atomic<bool> closing;
-    std::mutex device_handle_mutex;
-    libusb_device_handle* device_handle;
-
-    transfer_info read;
-    transfer_info write;
-
-    uint8_t interface;
-    uint8_t bulk_in;
-    uint8_t bulk_out;
-
-    size_t max_packet_size;
-};
-
-static auto& usb_handles = *new std::unordered_map<std::string, std::unique_ptr<usb_handle>>();
-static auto& usb_handles_mutex = *new std::mutex();
-
-static libusb_hotplug_callback_handle hotplug_handle;
-
-static std::string get_device_address(libusb_device* device) {
-    return StringPrintf("usb:%d:%d", libusb_get_bus_number(device),
-                        libusb_get_device_address(device));
-}
-
-#if defined(__linux__)
-static std::string get_device_serial_path(libusb_device* device) {
-    uint8_t ports[7];
-    int port_count = libusb_get_port_numbers(device, ports, 7);
-    if (port_count < 0) return "";
-
-    std::string path =
-        StringPrintf("/sys/bus/usb/devices/%d-%d", libusb_get_bus_number(device), ports[0]);
-    for (int port = 1; port < port_count; ++port) {
-        path += StringPrintf(".%d", ports[port]);
-    }
-    path += "/serial";
-    return path;
-}
-
-static std::string get_device_dev_path(libusb_device* device) {
-    uint8_t ports[7];
-    int port_count = libusb_get_port_numbers(device, ports, 7);
-    if (port_count < 0) return "";
-    return StringPrintf("/dev/bus/usb/%03u/%03u", libusb_get_bus_number(device), ports[0]);
-}
-#endif
-
-static bool endpoint_is_output(uint8_t endpoint) {
-    return (endpoint & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_OUT;
-}
-
-static bool should_perform_zero_transfer(uint8_t endpoint, size_t write_length, uint16_t zero_mask) {
-    return endpoint_is_output(endpoint) && write_length != 0 && zero_mask != 0 &&
-           (write_length & zero_mask) == 0;
-}
-
-static void process_device(libusb_device* device) {
-    std::string device_address = get_device_address(device);
-    std::string device_serial;
-
-    // Figure out if we want to open the device.
-    libusb_device_descriptor device_desc;
-    int rc = libusb_get_device_descriptor(device, &device_desc);
-    if (rc != 0) {
-        LOG(WARNING) << "failed to get device descriptor for device at " << device_address << ": "
-                     << libusb_error_name(rc);
-        return;
-    }
-
-    if (device_desc.bDeviceClass != LIBUSB_CLASS_PER_INTERFACE) {
-        // Assume that all Android devices have the device class set to per interface.
-        // TODO: Is this assumption valid?
-        LOG(VERBOSE) << "skipping device with incorrect class at " << device_address;
-        return;
-    }
-
-    libusb_config_descriptor* config_raw;
-    rc = libusb_get_active_config_descriptor(device, &config_raw);
-    if (rc != 0) {
-        LOG(WARNING) << "failed to get active config descriptor for device at " << device_address
-                     << ": " << libusb_error_name(rc);
-        return;
-    }
-    const unique_config_descriptor config(config_raw);
-
-    // Use size_t for interface_num so <iostream>s don't mangle it.
-    size_t interface_num;
-    uint16_t zero_mask = 0;
-    uint8_t bulk_in = 0, bulk_out = 0;
-    size_t packet_size = 0;
-    bool found_adb = false;
-
-    for (interface_num = 0; interface_num < config->bNumInterfaces; ++interface_num) {
-        const libusb_interface& interface = config->interface[interface_num];
-        if (interface.num_altsetting != 1) {
-            // Assume that interfaces with alternate settings aren't adb interfaces.
-            // TODO: Is this assumption valid?
-            LOG(VERBOSE) << "skipping interface with incorrect num_altsetting at " << device_address
-                         << " (interface " << interface_num << ")";
-            continue;
-        }
-
-        const libusb_interface_descriptor& interface_desc = interface.altsetting[0];
-        if (!is_adb_interface(interface_desc.bInterfaceClass, interface_desc.bInterfaceSubClass,
-                              interface_desc.bInterfaceProtocol)) {
-            LOG(VERBOSE) << "skipping non-adb interface at " << device_address << " (interface "
-                         << interface_num << ")";
-            continue;
-        }
-
-        LOG(VERBOSE) << "found potential adb interface at " << device_address << " (interface "
-                     << interface_num << ")";
-
-        bool found_in = false;
-        bool found_out = false;
-        for (size_t endpoint_num = 0; endpoint_num < interface_desc.bNumEndpoints; ++endpoint_num) {
-            const auto& endpoint_desc = interface_desc.endpoint[endpoint_num];
-            const uint8_t endpoint_addr = endpoint_desc.bEndpointAddress;
-            const uint8_t endpoint_attr = endpoint_desc.bmAttributes;
-
-            const uint8_t transfer_type = endpoint_attr & LIBUSB_TRANSFER_TYPE_MASK;
-
-            if (transfer_type != LIBUSB_TRANSFER_TYPE_BULK) {
-                continue;
-            }
-
-            if (endpoint_is_output(endpoint_addr) && !found_out) {
-                found_out = true;
-                bulk_out = endpoint_addr;
-                zero_mask = endpoint_desc.wMaxPacketSize - 1;
-            } else if (!endpoint_is_output(endpoint_addr) && !found_in) {
-                found_in = true;
-                bulk_in = endpoint_addr;
-            }
-
-            size_t endpoint_packet_size = endpoint_desc.wMaxPacketSize;
-            CHECK(endpoint_packet_size != 0);
-            if (packet_size == 0) {
-                packet_size = endpoint_packet_size;
-            } else {
-                CHECK(packet_size == endpoint_packet_size);
-            }
-        }
-
-        if (found_in && found_out) {
-            found_adb = true;
-            break;
-        } else {
-            LOG(VERBOSE) << "rejecting potential adb interface at " << device_address
-                         << "(interface " << interface_num << "): missing bulk endpoints "
-                         << "(found_in = " << found_in << ", found_out = " << found_out << ")";
-        }
-    }
-
-    if (!found_adb) {
-        LOG(VERBOSE) << "skipping device with no adb interfaces at " << device_address;
-        return;
-    }
-
-    {
-        std::unique_lock<std::mutex> lock(usb_handles_mutex);
-        if (usb_handles.find(device_address) != usb_handles.end()) {
-            LOG(VERBOSE) << "device at " << device_address
-                         << " has already been registered, skipping";
-            return;
-        }
-    }
-
-    bool writable = true;
-    libusb_device_handle* handle_raw = nullptr;
-    rc = libusb_open(device, &handle_raw);
-    unique_device_handle handle(handle_raw);
-    if (rc == 0) {
-        LOG(DEBUG) << "successfully opened adb device at " << device_address << ", "
-                   << StringPrintf("bulk_in = %#x, bulk_out = %#x", bulk_in, bulk_out);
-
-        device_serial.resize(255);
-        rc = libusb_get_string_descriptor_ascii(handle_raw, device_desc.iSerialNumber,
-                                                reinterpret_cast<unsigned char*>(&device_serial[0]),
-                                                device_serial.length());
-        if (rc == 0) {
-            LOG(WARNING) << "received empty serial from device at " << device_address;
-            return;
-        } else if (rc < 0) {
-            LOG(WARNING) << "failed to get serial from device at " << device_address
-                         << libusb_error_name(rc);
-            return;
-        }
-        device_serial.resize(rc);
-
-        // WARNING: this isn't released via RAII.
-        rc = libusb_claim_interface(handle.get(), interface_num);
-        if (rc != 0) {
-            LOG(WARNING) << "failed to claim adb interface for device '" << device_serial << "'"
-                         << libusb_error_name(rc);
-            return;
-        }
-
-        for (uint8_t endpoint : {bulk_in, bulk_out}) {
-            rc = libusb_clear_halt(handle.get(), endpoint);
-            if (rc != 0) {
-                LOG(WARNING) << "failed to clear halt on device '" << device_serial
-                             << "' endpoint 0x" << std::hex << endpoint << ": "
-                             << libusb_error_name(rc);
-                libusb_release_interface(handle.get(), interface_num);
-                return;
-            }
-        }
-    } else {
-        LOG(WARNING) << "failed to open usb device at " << device_address << ": "
-                     << libusb_error_name(rc);
-        writable = false;
-
-#if defined(__linux__)
-        // libusb doesn't think we should be messing around with devices we don't have
-        // write access to, but Linux at least lets us get the serial number anyway.
-        if (!android::base::ReadFileToString(get_device_serial_path(device), &device_serial)) {
-            // We don't actually want to treat an unknown serial as an error because
-            // devices aren't able to communicate a serial number in early bringup.
-            // http://b/20883914
-            device_serial = "unknown";
-        }
-        device_serial = android::base::Trim(device_serial);
-#else
-        // On Mac OS and Windows, we're screwed. But I don't think this situation actually
-        // happens on those OSes.
-        return;
-#endif
-    }
-
-    std::unique_ptr<usb_handle> result(new usb_handle(device_address, device_serial,
-                                                      std::move(handle), interface_num, bulk_in,
-                                                      bulk_out, zero_mask, packet_size));
-    usb_handle* usb_handle_raw = result.get();
-
-    {
-        std::unique_lock<std::mutex> lock(usb_handles_mutex);
-        usb_handles[device_address] = std::move(result);
-
-        register_usb_transport(usb_handle_raw, device_serial.c_str(), device_address.c_str(),
-                               writable);
-    }
-    LOG(INFO) << "registered new usb device '" << device_serial << "'";
-}
-
-static std::atomic<int> connecting_devices(0);
-
-static void device_connected(libusb_device* device) {
-#if defined(__linux__)
-    // Android's host linux libusb uses netlink instead of udev for device hotplug notification,
-    // which means we can get hotplug notifications before udev has updated ownership/perms on the
-    // device. Since we're not going to be able to link against the system's libudev any time soon,
-    // hack around this by inserting a sleep.
-    auto thread = std::thread([device]() {
-        std::string device_path = get_device_dev_path(device);
-        std::this_thread::sleep_for(std::chrono::seconds(1));
-
-        process_device(device);
-        if (--connecting_devices == 0) {
-            adb_notify_device_scan_complete();
-        }
-    });
-    thread.detach();
-#else
-    process_device(device);
-#endif
-}
-
-static void device_disconnected(libusb_device* device) {
-    std::string device_address = get_device_address(device);
-
-    LOG(INFO) << "device disconnected: " << device_address;
-    std::unique_lock<std::mutex> lock(usb_handles_mutex);
-    auto it = usb_handles.find(device_address);
-    if (it != usb_handles.end()) {
-        if (!it->second->device_handle) {
-            // If the handle is null, we were never able to open the device.
-
-            // Temporarily release the usb handles mutex to avoid deadlock.
-            std::unique_ptr<usb_handle> handle = std::move(it->second);
-            usb_handles.erase(it);
-            lock.unlock();
-            unregister_usb_transport(handle.get());
-            lock.lock();
-        } else {
-            // Closure of the transport will erase the usb_handle.
-        }
-    }
-}
-
-static auto& hotplug_queue = *new BlockingQueue<std::pair<libusb_hotplug_event, libusb_device*>>();
-static void hotplug_thread() {
-    adb_thread_setname("libusb hotplug");
-    while (true) {
-        hotplug_queue.PopAll([](std::pair<libusb_hotplug_event, libusb_device*> pair) {
-            libusb_hotplug_event event = pair.first;
-            libusb_device* device = pair.second;
-            if (event == LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED) {
-                device_connected(device);
-            } else if (event == LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT) {
-                device_disconnected(device);
-            }
-        });
-    }
-}
-
-static LIBUSB_CALL int hotplug_callback(libusb_context*, libusb_device* device,
-                                        libusb_hotplug_event event, void*) {
-    // We're called with the libusb lock taken. Call these on a separate thread outside of this
-    // function so that the usb_handle mutex is always taken before the libusb mutex.
-    static std::once_flag once;
-    std::call_once(once, []() { std::thread(hotplug_thread).detach(); });
-
-    if (event == LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED) {
-        ++connecting_devices;
-    }
-    hotplug_queue.Push({event, device});
-    return 0;
-}
-
-void usb_init() {
-    LOG(DEBUG) << "initializing libusb...";
-    int rc = libusb_init(nullptr);
-    if (rc != 0) {
-        LOG(FATAL) << "failed to initialize libusb: " << libusb_error_name(rc);
-    }
-
-    // Register the hotplug callback.
-    rc = libusb_hotplug_register_callback(
-        nullptr, static_cast<libusb_hotplug_event>(LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED |
-                                                   LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT),
-        LIBUSB_HOTPLUG_ENUMERATE, LIBUSB_HOTPLUG_MATCH_ANY, LIBUSB_HOTPLUG_MATCH_ANY,
-        LIBUSB_CLASS_PER_INTERFACE, hotplug_callback, nullptr, &hotplug_handle);
-
-    if (rc != LIBUSB_SUCCESS) {
-        LOG(FATAL) << "failed to register libusb hotplug callback";
-    }
-
-    // Spawn a thread for libusb_handle_events.
-    std::thread([]() {
-        adb_thread_setname("libusb");
-        while (true) {
-            libusb_handle_events(nullptr);
-        }
-    }).detach();
-}
-
-void usb_cleanup() {
-    libusb_hotplug_deregister_callback(nullptr, hotplug_handle);
-}
-
-static LIBUSB_CALL void transfer_callback(libusb_transfer* transfer) {
-    transfer_info* info = static_cast<transfer_info*>(transfer->user_data);
-
-    LOG(DEBUG) << info->name << " transfer callback entered";
-
-    // Make sure that the original submitter has made it to the condition_variable wait.
-    std::unique_lock<std::mutex> lock(info->mutex);
-
-    LOG(DEBUG) << info->name << " callback successfully acquired lock";
-
-    if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
-        LOG(WARNING) << info->name << " transfer failed: " << libusb_error_name(transfer->status);
-        info->Notify();
-        return;
-    }
-
-    // usb_read() can return when receiving some data.
-    if (info->is_bulk_out && transfer->actual_length != transfer->length) {
-        LOG(DEBUG) << info->name << " transfer incomplete, resubmitting";
-        transfer->length -= transfer->actual_length;
-        transfer->buffer += transfer->actual_length;
-        int rc = libusb_submit_transfer(transfer);
-        if (rc != 0) {
-            LOG(WARNING) << "failed to submit " << info->name
-                         << " transfer: " << libusb_error_name(rc);
-            transfer->status = LIBUSB_TRANSFER_ERROR;
-            info->Notify();
-        }
-        return;
-    }
-
-    if (should_perform_zero_transfer(transfer->endpoint, transfer->length, info->zero_mask)) {
-        LOG(DEBUG) << "submitting zero-length write";
-        transfer->length = 0;
-        int rc = libusb_submit_transfer(transfer);
-        if (rc != 0) {
-            LOG(WARNING) << "failed to submit zero-length write: " << libusb_error_name(rc);
-            transfer->status = LIBUSB_TRANSFER_ERROR;
-            info->Notify();
-        }
-        return;
-    }
-
-    LOG(VERBOSE) << info->name << "transfer fully complete";
-    info->Notify();
-}
-
-// Dispatch a libusb transfer, unlock |device_lock|, and then wait for the result.
-static int perform_usb_transfer(usb_handle* h, transfer_info* info,
-                                std::unique_lock<std::mutex> device_lock) {
-    libusb_transfer* transfer = info->transfer;
-
-    transfer->user_data = info;
-    transfer->callback = transfer_callback;
-
-    LOG(DEBUG) << "locking " << info->name << " transfer_info mutex";
-    std::unique_lock<std::mutex> lock(info->mutex);
-    info->transfer_complete = false;
-    LOG(DEBUG) << "submitting " << info->name << " transfer";
-    int rc = libusb_submit_transfer(transfer);
-    if (rc != 0) {
-        LOG(WARNING) << "failed to submit " << info->name << " transfer: " << libusb_error_name(rc);
-        errno = EIO;
-        return -1;
-    }
-
-    LOG(DEBUG) << info->name << " transfer successfully submitted";
-    device_lock.unlock();
-    info->cv.wait(lock, [info]() { return info->transfer_complete; });
-    if (transfer->status != 0) {
-        errno = EIO;
-        return -1;
-    }
-
-    return 0;
-}
-
-int usb_write(usb_handle* h, const void* d, int len) {
-    LOG(DEBUG) << "usb_write of length " << len;
-
-    std::unique_lock<std::mutex> lock(h->device_handle_mutex);
-    if (!h->device_handle) {
-        errno = EIO;
-        return -1;
-    }
-
-    transfer_info* info = &h->write;
-    info->transfer->dev_handle = h->device_handle;
-    info->transfer->flags = 0;
-    info->transfer->endpoint = h->bulk_out;
-    info->transfer->type = LIBUSB_TRANSFER_TYPE_BULK;
-    info->transfer->length = len;
-    info->transfer->buffer = reinterpret_cast<unsigned char*>(const_cast<void*>(d));
-    info->transfer->num_iso_packets = 0;
-
-    int rc = perform_usb_transfer(h, info, std::move(lock));
-    LOG(DEBUG) << "usb_write(" << len << ") = " << rc;
-    return info->transfer->actual_length;
-}
-
-int usb_read(usb_handle* h, void* d, int len) {
-    LOG(DEBUG) << "usb_read of length " << len;
-
-    std::unique_lock<std::mutex> lock(h->device_handle_mutex);
-    if (!h->device_handle) {
-        errno = EIO;
-        return -1;
-    }
-
-    transfer_info* info = &h->read;
-    info->transfer->dev_handle = h->device_handle;
-    info->transfer->flags = 0;
-    info->transfer->endpoint = h->bulk_in;
-    info->transfer->type = LIBUSB_TRANSFER_TYPE_BULK;
-    info->transfer->length = len;
-    info->transfer->buffer = reinterpret_cast<unsigned char*>(d);
-    info->transfer->num_iso_packets = 0;
-
-    int rc = perform_usb_transfer(h, info, std::move(lock));
-    LOG(DEBUG) << "usb_read(" << len << ") = " << rc << ", actual_length "
-               << info->transfer->actual_length;
-    if (rc < 0) {
-        return rc;
-    }
-    return info->transfer->actual_length;
-}
-
-int usb_close(usb_handle* h) {
-    std::unique_lock<std::mutex> lock(usb_handles_mutex);
-    auto it = usb_handles.find(h->device_address);
-    if (it == usb_handles.end()) {
-        LOG(FATAL) << "attempted to close unregistered usb_handle for '" << h->serial << "'";
-    }
-    usb_handles.erase(h->device_address);
-    return 0;
-}
-
-void usb_reset(usb_handle* h) {
-    libusb_reset_device(h->device_handle);
-    usb_kick(h);
-}
-
-void usb_kick(usb_handle* h) {
-    h->Close();
-}
-
-size_t usb_get_max_packet_size(usb_handle* h) {
-    CHECK(h->max_packet_size != 0);
-    return h->max_packet_size;
-}
-
-} // namespace libusb
diff --git a/adb/client/usb_linux.cpp b/adb/client/usb_linux.cpp
deleted file mode 100644
index 95b1817..0000000
--- a/adb/client/usb_linux.cpp
+++ /dev/null
@@ -1,632 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define TRACE_TAG USB
-
-#include "sysdeps.h"
-
-#include "client/usb.h"
-
-#include <ctype.h>
-#include <dirent.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <linux/usb/ch9.h>
-#include <linux/usbdevice_fs.h>
-#include <linux/version.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/ioctl.h>
-#include <sys/time.h>
-#include <sys/sysmacros.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include <chrono>
-#include <condition_variable>
-#include <list>
-#include <mutex>
-#include <string>
-#include <string_view>
-#include <thread>
-
-#include <android-base/file.h>
-#include <android-base/stringprintf.h>
-#include <android-base/strings.h>
-
-#include "adb.h"
-#include "transport.h"
-
-using namespace std::chrono_literals;
-using namespace std::literals;
-
-/* usb scan debugging is waaaay too verbose */
-#define DBGX(x...)
-
-namespace native {
-struct usb_handle : public ::usb_handle {
-    ~usb_handle() {
-      if (fd != -1) unix_close(fd);
-    }
-
-    std::string path;
-    int fd = -1;
-    unsigned char ep_in;
-    unsigned char ep_out;
-
-    size_t max_packet_size;
-    unsigned zero_mask;
-    unsigned writeable = 1;
-
-    usbdevfs_urb urb_in;
-    usbdevfs_urb urb_out;
-
-    bool urb_in_busy = false;
-    bool urb_out_busy = false;
-    bool dead = false;
-
-    std::condition_variable cv;
-    std::mutex mutex;
-
-    // for garbage collecting disconnected devices
-    bool mark;
-
-    // ID of thread currently in REAPURB
-    pthread_t reaper_thread = 0;
-};
-
-static auto& g_usb_handles_mutex = *new std::mutex();
-static auto& g_usb_handles = *new std::list<usb_handle*>();
-
-static int is_known_device(std::string_view dev_name) {
-    std::lock_guard<std::mutex> lock(g_usb_handles_mutex);
-    for (usb_handle* usb : g_usb_handles) {
-        if (usb->path == dev_name) {
-            // set mark flag to indicate this device is still alive
-            usb->mark = true;
-            return 1;
-        }
-    }
-    return 0;
-}
-
-static void kick_disconnected_devices() {
-    std::lock_guard<std::mutex> lock(g_usb_handles_mutex);
-    // kick any devices in the device list that were not found in the device scan
-    for (usb_handle* usb : g_usb_handles) {
-        if (!usb->mark) {
-            usb_kick(usb);
-        } else {
-            usb->mark = false;
-        }
-    }
-}
-
-static inline bool contains_non_digit(const char* name) {
-    while (*name) {
-        if (!isdigit(*name++)) return true;
-    }
-    return false;
-}
-
-static void find_usb_device(const std::string& base,
-                            void (*register_device_callback)(const char*, const char*,
-                                                             unsigned char, unsigned char, int, int,
-                                                             unsigned, size_t)) {
-    std::unique_ptr<DIR, int(*)(DIR*)> bus_dir(opendir(base.c_str()), closedir);
-    if (!bus_dir) return;
-
-    dirent* de;
-    while ((de = readdir(bus_dir.get())) != nullptr) {
-        if (contains_non_digit(de->d_name)) continue;
-
-        std::string bus_name = base + "/" + de->d_name;
-
-        std::unique_ptr<DIR, int(*)(DIR*)> dev_dir(opendir(bus_name.c_str()), closedir);
-        if (!dev_dir) continue;
-
-        while ((de = readdir(dev_dir.get()))) {
-            unsigned char devdesc[4096];
-            unsigned char* bufptr = devdesc;
-            unsigned char* bufend;
-            struct usb_device_descriptor* device;
-            struct usb_config_descriptor* config;
-            struct usb_interface_descriptor* interface;
-            struct usb_endpoint_descriptor *ep1, *ep2;
-            unsigned zero_mask = 0;
-            size_t max_packet_size = 0;
-            unsigned vid, pid;
-
-            if (contains_non_digit(de->d_name)) continue;
-
-            std::string dev_name = bus_name + "/" + de->d_name;
-            if (is_known_device(dev_name)) {
-                continue;
-            }
-
-            int fd = unix_open(dev_name, O_RDONLY | O_CLOEXEC);
-            if (fd == -1) {
-                continue;
-            }
-
-            size_t desclength = unix_read(fd, devdesc, sizeof(devdesc));
-            bufend = bufptr + desclength;
-
-                // should have device and configuration descriptors, and atleast two endpoints
-            if (desclength < USB_DT_DEVICE_SIZE + USB_DT_CONFIG_SIZE) {
-                D("desclength %zu is too small", desclength);
-                unix_close(fd);
-                continue;
-            }
-
-            device = (struct usb_device_descriptor*)bufptr;
-            bufptr += USB_DT_DEVICE_SIZE;
-
-            if((device->bLength != USB_DT_DEVICE_SIZE) || (device->bDescriptorType != USB_DT_DEVICE)) {
-                unix_close(fd);
-                continue;
-            }
-
-            vid = device->idVendor;
-            pid = device->idProduct;
-            DBGX("[ %s is V:%04x P:%04x ]\n", dev_name.c_str(), vid, pid);
-
-                // should have config descriptor next
-            config = (struct usb_config_descriptor *)bufptr;
-            bufptr += USB_DT_CONFIG_SIZE;
-            if (config->bLength != USB_DT_CONFIG_SIZE || config->bDescriptorType != USB_DT_CONFIG) {
-                D("usb_config_descriptor not found");
-                unix_close(fd);
-                continue;
-            }
-
-                // loop through all the descriptors and look for the ADB interface
-            while (bufptr < bufend) {
-                unsigned char length = bufptr[0];
-                unsigned char type = bufptr[1];
-
-                if (type == USB_DT_INTERFACE) {
-                    interface = (struct usb_interface_descriptor *)bufptr;
-                    bufptr += length;
-
-                    if (length != USB_DT_INTERFACE_SIZE) {
-                        D("interface descriptor has wrong size");
-                        break;
-                    }
-
-                    DBGX("bInterfaceClass: %d,  bInterfaceSubClass: %d,"
-                         "bInterfaceProtocol: %d, bNumEndpoints: %d\n",
-                         interface->bInterfaceClass, interface->bInterfaceSubClass,
-                         interface->bInterfaceProtocol, interface->bNumEndpoints);
-
-                    if (interface->bNumEndpoints == 2 &&
-                        is_adb_interface(interface->bInterfaceClass, interface->bInterfaceSubClass,
-                                         interface->bInterfaceProtocol)) {
-                        struct stat st;
-                        char pathbuf[128];
-                        char link[256];
-                        char *devpath = nullptr;
-
-                        DBGX("looking for bulk endpoints\n");
-                            // looks like ADB...
-                        ep1 = (struct usb_endpoint_descriptor *)bufptr;
-                        bufptr += USB_DT_ENDPOINT_SIZE;
-                            // For USB 3.0 SuperSpeed devices, skip potential
-                            // USB 3.0 SuperSpeed Endpoint Companion descriptor
-                        if (bufptr+2 <= devdesc + desclength &&
-                            bufptr[0] == USB_DT_SS_EP_COMP_SIZE &&
-                            bufptr[1] == USB_DT_SS_ENDPOINT_COMP) {
-                            bufptr += USB_DT_SS_EP_COMP_SIZE;
-                        }
-                        ep2 = (struct usb_endpoint_descriptor *)bufptr;
-                        bufptr += USB_DT_ENDPOINT_SIZE;
-                        if (bufptr+2 <= devdesc + desclength &&
-                            bufptr[0] == USB_DT_SS_EP_COMP_SIZE &&
-                            bufptr[1] == USB_DT_SS_ENDPOINT_COMP) {
-                            bufptr += USB_DT_SS_EP_COMP_SIZE;
-                        }
-
-                        if (bufptr > devdesc + desclength ||
-                            ep1->bLength != USB_DT_ENDPOINT_SIZE ||
-                            ep1->bDescriptorType != USB_DT_ENDPOINT ||
-                            ep2->bLength != USB_DT_ENDPOINT_SIZE ||
-                            ep2->bDescriptorType != USB_DT_ENDPOINT) {
-                            D("endpoints not found");
-                            break;
-                        }
-
-                            // both endpoints should be bulk
-                        if (ep1->bmAttributes != USB_ENDPOINT_XFER_BULK ||
-                            ep2->bmAttributes != USB_ENDPOINT_XFER_BULK) {
-                            D("bulk endpoints not found");
-                            continue;
-                        }
-                            /* aproto 01 needs 0 termination */
-                        if (interface->bInterfaceProtocol == ADB_PROTOCOL) {
-                            max_packet_size = ep1->wMaxPacketSize;
-                            zero_mask = ep1->wMaxPacketSize - 1;
-                        }
-
-                            // we have a match.  now we just need to figure out which is in and which is out.
-                        unsigned char local_ep_in, local_ep_out;
-                        if (ep1->bEndpointAddress & USB_ENDPOINT_DIR_MASK) {
-                            local_ep_in = ep1->bEndpointAddress;
-                            local_ep_out = ep2->bEndpointAddress;
-                        } else {
-                            local_ep_in = ep2->bEndpointAddress;
-                            local_ep_out = ep1->bEndpointAddress;
-                        }
-
-                            // Determine the device path
-                        if (!fstat(fd, &st) && S_ISCHR(st.st_mode)) {
-                            snprintf(pathbuf, sizeof(pathbuf), "/sys/dev/char/%d:%d",
-                                     major(st.st_rdev), minor(st.st_rdev));
-                            ssize_t link_len = readlink(pathbuf, link, sizeof(link) - 1);
-                            if (link_len > 0) {
-                                link[link_len] = '\0';
-                                const char* slash = strrchr(link, '/');
-                                if (slash) {
-                                    snprintf(pathbuf, sizeof(pathbuf),
-                                             "usb:%s", slash + 1);
-                                    devpath = pathbuf;
-                                }
-                            }
-                        }
-
-                        register_device_callback(dev_name.c_str(), devpath, local_ep_in,
-                                                 local_ep_out, interface->bInterfaceNumber,
-                                                 device->iSerialNumber, zero_mask, max_packet_size);
-                        break;
-                    }
-                } else {
-                    bufptr += length;
-                }
-            } // end of while
-
-            unix_close(fd);
-        }
-    }
-}
-
-static int usb_bulk_write(usb_handle* h, const void* data, int len) {
-    std::unique_lock<std::mutex> lock(h->mutex);
-    D("++ usb_bulk_write ++");
-
-    usbdevfs_urb* urb = &h->urb_out;
-    memset(urb, 0, sizeof(*urb));
-    urb->type = USBDEVFS_URB_TYPE_BULK;
-    urb->endpoint = h->ep_out;
-    urb->status = -1;
-    urb->buffer = const_cast<void*>(data);
-    urb->buffer_length = len;
-
-    if (h->dead) {
-        errno = EINVAL;
-        return -1;
-    }
-
-    if (TEMP_FAILURE_RETRY(ioctl(h->fd, USBDEVFS_SUBMITURB, urb)) == -1) {
-        return -1;
-    }
-
-    h->urb_out_busy = true;
-    while (true) {
-        auto now = std::chrono::steady_clock::now();
-        if (h->cv.wait_until(lock, now + 5s) == std::cv_status::timeout || h->dead) {
-            // TODO: call USBDEVFS_DISCARDURB?
-            errno = ETIMEDOUT;
-            return -1;
-        }
-        if (!h->urb_out_busy) {
-            if (urb->status != 0) {
-                errno = -urb->status;
-                return -1;
-            }
-            return urb->actual_length;
-        }
-    }
-}
-
-static int usb_bulk_read(usb_handle* h, void* data, int len) {
-    std::unique_lock<std::mutex> lock(h->mutex);
-    D("++ usb_bulk_read ++");
-
-    usbdevfs_urb* urb = &h->urb_in;
-    memset(urb, 0, sizeof(*urb));
-    urb->type = USBDEVFS_URB_TYPE_BULK;
-    urb->endpoint = h->ep_in;
-    urb->status = -1;
-    urb->buffer = data;
-    urb->buffer_length = len;
-
-    if (h->dead) {
-        errno = EINVAL;
-        return -1;
-    }
-
-    if (TEMP_FAILURE_RETRY(ioctl(h->fd, USBDEVFS_SUBMITURB, urb)) == -1) {
-        return -1;
-    }
-
-    h->urb_in_busy = true;
-    while (true) {
-        D("[ reap urb - wait ]");
-        h->reaper_thread = pthread_self();
-        int fd = h->fd;
-        lock.unlock();
-
-        // This ioctl must not have TEMP_FAILURE_RETRY because we send SIGALRM to break out.
-        usbdevfs_urb* out = nullptr;
-        int res = ioctl(fd, USBDEVFS_REAPURB, &out);
-        int saved_errno = errno;
-
-        lock.lock();
-        h->reaper_thread = 0;
-        if (h->dead) {
-            errno = EINVAL;
-            return -1;
-        }
-        if (res < 0) {
-            if (saved_errno == EINTR) {
-                continue;
-            }
-            D("[ reap urb - error ]");
-            errno = saved_errno;
-            return -1;
-        }
-        D("[ urb @%p status = %d, actual = %d ]", out, out->status, out->actual_length);
-
-        if (out == &h->urb_in) {
-            D("[ reap urb - IN complete ]");
-            h->urb_in_busy = false;
-            if (urb->status != 0) {
-                errno = -urb->status;
-                return -1;
-            }
-            return urb->actual_length;
-        }
-        if (out == &h->urb_out) {
-            D("[ reap urb - OUT compelete ]");
-            h->urb_out_busy = false;
-            h->cv.notify_all();
-        }
-    }
-}
-
-static int usb_write_split(usb_handle* h, unsigned char* data, int len) {
-    for (int i = 0; i < len; i += 16384) {
-        int chunk_size = (i + 16384 > len) ? len - i : 16384;
-        int n = usb_bulk_write(h, data + i, chunk_size);
-        if (n != chunk_size) {
-            D("ERROR: n = %d, errno = %d (%s)", n, errno, strerror(errno));
-            return -1;
-        }
-    }
-
-    return len;
-}
-
-int usb_write(usb_handle* h, const void* _data, int len) {
-    D("++ usb_write ++");
-
-    unsigned char* data = (unsigned char*)_data;
-
-    // The kernel will attempt to allocate a contiguous buffer for each write we submit.
-    // This might fail due to heap fragmentation, so attempt a contiguous write once, and if that
-    // fails, retry after having split the data into 16kB chunks to avoid allocation failure.
-    int n = usb_bulk_write(h, data, len);
-    if (n == -1 && errno == ENOMEM) {
-        n = usb_write_split(h, data, len);
-    }
-
-    if (n == -1) {
-        return -1;
-    }
-
-    if (h->zero_mask && !(len & h->zero_mask)) {
-        // If we need 0-markers and our transfer is an even multiple of the packet size,
-        // then send a zero marker.
-        return usb_bulk_write(h, _data, 0) == 0 ? len : -1;
-    }
-
-    D("-- usb_write --");
-    return len;
-}
-
-int usb_read(usb_handle *h, void *_data, int len)
-{
-    unsigned char *data = (unsigned char*) _data;
-    int n;
-
-    D("++ usb_read ++");
-    int orig_len = len;
-    while (len == orig_len) {
-        int xfer = len;
-
-        D("[ usb read %d fd = %d], path=%s", xfer, h->fd, h->path.c_str());
-        n = usb_bulk_read(h, data, xfer);
-        D("[ usb read %d ] = %d, path=%s", xfer, n, h->path.c_str());
-        if (n <= 0) {
-            if((errno == ETIMEDOUT) && (h->fd != -1)) {
-                D("[ timeout ]");
-                continue;
-            }
-            D("ERROR: n = %d, errno = %d (%s)",
-                n, errno, strerror(errno));
-            return -1;
-        }
-
-        len -= n;
-        data += n;
-    }
-
-    D("-- usb_read --");
-    return orig_len - len;
-}
-
-void usb_reset(usb_handle* h) {
-    ioctl(h->fd, USBDEVFS_RESET);
-    usb_kick(h);
-}
-
-void usb_kick(usb_handle* h) {
-    std::lock_guard<std::mutex> lock(h->mutex);
-    D("[ kicking %p (fd = %d) ]", h, h->fd);
-    if (!h->dead) {
-        h->dead = true;
-
-        if (h->writeable) {
-            /* HACK ALERT!
-            ** Sometimes we get stuck in ioctl(USBDEVFS_REAPURB).
-            ** This is a workaround for that problem.
-            */
-            if (h->reaper_thread) {
-                pthread_kill(h->reaper_thread, SIGALRM);
-            }
-
-            /* cancel any pending transactions
-            ** these will quietly fail if the txns are not active,
-            ** but this ensures that a reader blocked on REAPURB
-            ** will get unblocked
-            */
-            ioctl(h->fd, USBDEVFS_DISCARDURB, &h->urb_in);
-            ioctl(h->fd, USBDEVFS_DISCARDURB, &h->urb_out);
-            h->urb_in.status = -ENODEV;
-            h->urb_out.status = -ENODEV;
-            h->urb_in_busy = false;
-            h->urb_out_busy = false;
-            h->cv.notify_all();
-        } else {
-            unregister_usb_transport(h);
-        }
-    }
-}
-
-int usb_close(usb_handle* h) {
-    std::lock_guard<std::mutex> lock(g_usb_handles_mutex);
-    g_usb_handles.remove(h);
-
-    D("-- usb close %p (fd = %d) --", h, h->fd);
-
-    delete h;
-
-    return 0;
-}
-
-size_t usb_get_max_packet_size(usb_handle* h) {
-    return h->max_packet_size;
-}
-
-static void register_device(const char* dev_name, const char* dev_path, unsigned char ep_in,
-                            unsigned char ep_out, int interface, int serial_index,
-                            unsigned zero_mask, size_t max_packet_size) {
-    // Since Linux will not reassign the device ID (and dev_name) as long as the
-    // device is open, we can add to the list here once we open it and remove
-    // from the list when we're finally closed and everything will work out
-    // fine.
-    //
-    // If we have a usb_handle on the list of handles with a matching name, we
-    // have no further work to do.
-    {
-        std::lock_guard<std::mutex> lock(g_usb_handles_mutex);
-        for (usb_handle* usb: g_usb_handles) {
-            if (usb->path == dev_name) {
-                return;
-            }
-        }
-    }
-
-    D("[ usb located new device %s (%d/%d/%d) ]", dev_name, ep_in, ep_out, interface);
-    std::unique_ptr<usb_handle> usb(new usb_handle);
-    usb->path = dev_name;
-    usb->ep_in = ep_in;
-    usb->ep_out = ep_out;
-    usb->zero_mask = zero_mask;
-    usb->max_packet_size = max_packet_size;
-
-    // Initialize mark so we don't get garbage collected after the device scan.
-    usb->mark = true;
-
-    usb->fd = unix_open(usb->path, O_RDWR | O_CLOEXEC);
-    if (usb->fd == -1) {
-        // Opening RW failed, so see if we have RO access.
-        usb->fd = unix_open(usb->path, O_RDONLY | O_CLOEXEC);
-        if (usb->fd == -1) {
-            D("[ usb open %s failed: %s]", usb->path.c_str(), strerror(errno));
-            return;
-        }
-        usb->writeable = 0;
-    }
-
-    D("[ usb opened %s%s, fd=%d]",
-      usb->path.c_str(), (usb->writeable ? "" : " (read-only)"), usb->fd);
-
-    if (usb->writeable) {
-        if (ioctl(usb->fd, USBDEVFS_CLAIMINTERFACE, &interface) != 0) {
-            D("[ usb ioctl(%d, USBDEVFS_CLAIMINTERFACE) failed: %s]", usb->fd, strerror(errno));
-            return;
-        }
-    }
-
-    // Read the device's serial number.
-    std::string serial_path = android::base::StringPrintf(
-        "/sys/bus/usb/devices/%s/serial", dev_path + 4);
-    std::string serial;
-    if (!android::base::ReadFileToString(serial_path, &serial)) {
-        D("[ usb read %s failed: %s ]", serial_path.c_str(), strerror(errno));
-        // We don't actually want to treat an unknown serial as an error because
-        // devices aren't able to communicate a serial number in early bringup.
-        // http://b/20883914
-        serial = "";
-    }
-    serial = android::base::Trim(serial);
-
-    // Add to the end of the active handles.
-    usb_handle* done_usb = usb.release();
-    {
-        std::lock_guard<std::mutex> lock(g_usb_handles_mutex);
-        g_usb_handles.push_back(done_usb);
-    }
-    register_usb_transport(done_usb, serial.c_str(), dev_path, done_usb->writeable);
-}
-
-static void device_poll_thread() {
-    adb_thread_setname("device poll");
-    D("Created device thread");
-    while (true) {
-        // TODO: Use inotify.
-        find_usb_device("/dev/bus/usb", register_device);
-        adb_notify_device_scan_complete();
-        kick_disconnected_devices();
-        std::this_thread::sleep_for(1s);
-    }
-}
-
-void usb_init() {
-    struct sigaction actions;
-    memset(&actions, 0, sizeof(actions));
-    sigemptyset(&actions.sa_mask);
-    actions.sa_flags = 0;
-    actions.sa_handler = [](int) {};
-    sigaction(SIGALRM, &actions, nullptr);
-
-    std::thread(device_poll_thread).detach();
-}
-
-void usb_cleanup() {}
-
-} // namespace native
diff --git a/adb/client/usb_osx.cpp b/adb/client/usb_osx.cpp
deleted file mode 100644
index a93fa3a..0000000
--- a/adb/client/usb_osx.cpp
+++ /dev/null
@@ -1,592 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define TRACE_TAG USB
-
-#include "sysdeps.h"
-
-#include "client/usb.h"
-
-#include <CoreFoundation/CoreFoundation.h>
-
-#include <IOKit/IOKitLib.h>
-#include <IOKit/IOCFPlugIn.h>
-#include <IOKit/usb/IOUSBLib.h>
-#include <IOKit/IOMessage.h>
-#include <mach/mach_port.h>
-
-#include <inttypes.h>
-#include <stdio.h>
-
-#include <atomic>
-#include <chrono>
-#include <memory>
-#include <mutex>
-#include <thread>
-#include <vector>
-
-#include <android-base/logging.h>
-#include <android-base/stringprintf.h>
-#include <android-base/thread_annotations.h>
-
-#include "adb.h"
-#include "transport.h"
-
-using namespace std::chrono_literals;
-
-namespace native {
-struct usb_handle
-{
-    UInt8 bulkIn;
-    UInt8 bulkOut;
-    IOUSBInterfaceInterface550** interface;
-    unsigned int zero_mask;
-    size_t max_packet_size;
-
-    // For garbage collecting disconnected devices.
-    bool mark;
-    std::string devpath;
-    std::atomic<bool> dead;
-
-    usb_handle()
-        : bulkIn(0),
-          bulkOut(0),
-          interface(nullptr),
-          zero_mask(0),
-          max_packet_size(0),
-          mark(false),
-          dead(false) {}
-};
-
-static std::atomic<bool> usb_inited_flag;
-
-static auto& g_usb_handles_mutex = *new std::mutex();
-static auto& g_usb_handles = *new std::vector<std::unique_ptr<usb_handle>>();
-
-static bool IsKnownDevice(const std::string& devpath) {
-    std::lock_guard<std::mutex> lock_guard(g_usb_handles_mutex);
-    for (auto& usb : g_usb_handles) {
-        if (usb->devpath == devpath) {
-            // Set mark flag to indicate this device is still alive.
-            usb->mark = true;
-            return true;
-        }
-    }
-    return false;
-}
-
-static void usb_kick_locked(usb_handle* handle);
-
-static void KickDisconnectedDevices() {
-    std::lock_guard<std::mutex> lock_guard(g_usb_handles_mutex);
-    for (auto& usb : g_usb_handles) {
-        if (!usb->mark) {
-            usb_kick_locked(usb.get());
-        } else {
-            usb->mark = false;
-        }
-    }
-}
-
-static void AddDevice(std::unique_ptr<usb_handle> handle) {
-    handle->mark = true;
-    std::lock_guard<std::mutex> lock(g_usb_handles_mutex);
-    g_usb_handles.push_back(std::move(handle));
-}
-
-static void AndroidInterfaceAdded(io_iterator_t iterator);
-static std::unique_ptr<usb_handle> CheckInterface(IOUSBInterfaceInterface550** iface, UInt16 vendor,
-                                                  UInt16 product);
-
-static bool FindUSBDevices() {
-    // Create the matching dictionary to find the Android device's adb interface.
-    CFMutableDictionaryRef matchingDict = IOServiceMatching(kIOUSBInterfaceClassName);
-    if (!matchingDict) {
-        LOG(ERROR) << "couldn't create USB matching dictionary";
-        return false;
-    }
-    // Create an iterator for all I/O Registry objects that match the dictionary.
-    io_iterator_t iter = 0;
-    kern_return_t kr = IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDict, &iter);
-    if (kr != KERN_SUCCESS) {
-        LOG(ERROR) << "failed to get matching services";
-        return false;
-    }
-    // Iterate over all matching objects.
-    AndroidInterfaceAdded(iter);
-    IOObjectRelease(iter);
-    return true;
-}
-
-static void
-AndroidInterfaceAdded(io_iterator_t iterator)
-{
-    kern_return_t            kr;
-    io_service_t             usbDevice;
-    io_service_t             usbInterface;
-    IOCFPlugInInterface      **plugInInterface = NULL;
-    IOUSBInterfaceInterface500  **iface = NULL;
-    IOUSBDeviceInterface500  **dev = NULL;
-    HRESULT                  result;
-    SInt32                   score;
-    uint32_t                 locationId;
-    UInt8                    if_class, subclass, protocol;
-    UInt16                   vendor;
-    UInt16                   product;
-    UInt8                    serialIndex;
-    char                     serial[256];
-    std::string devpath;
-
-    while ((usbInterface = IOIteratorNext(iterator))) {
-        //* Create an intermediate interface plugin
-        kr = IOCreatePlugInInterfaceForService(usbInterface,
-                                               kIOUSBInterfaceUserClientTypeID,
-                                               kIOCFPlugInInterfaceID,
-                                               &plugInInterface, &score);
-        IOObjectRelease(usbInterface);
-        if ((kIOReturnSuccess != kr) || (!plugInInterface)) {
-            LOG(ERROR) << "Unable to create an interface plug-in (" << std::hex << kr << ")";
-            continue;
-        }
-
-        //* This gets us the interface object
-        result = (*plugInInterface)->QueryInterface(
-            plugInInterface,
-            CFUUIDGetUUIDBytes(kIOUSBInterfaceInterfaceID500), (LPVOID*)&iface);
-        //* We only needed the plugin to get the interface, so discard it
-        (*plugInInterface)->Release(plugInInterface);
-        if (result || !iface) {
-            LOG(ERROR) << "Couldn't query the interface (" << std::hex << result << ")";
-            continue;
-        }
-
-        kr = (*iface)->GetInterfaceClass(iface, &if_class);
-        kr = (*iface)->GetInterfaceSubClass(iface, &subclass);
-        kr = (*iface)->GetInterfaceProtocol(iface, &protocol);
-        if (!is_adb_interface(if_class, subclass, protocol)) {
-            // Ignore non-ADB devices.
-            LOG(DEBUG) << "Ignoring interface with incorrect class/subclass/protocol - " << if_class
-                       << ", " << subclass << ", " << protocol;
-            (*iface)->Release(iface);
-            continue;
-        }
-
-        //* this gets us an ioservice, with which we will find the actual
-        //* device; after getting a plugin, and querying the interface, of
-        //* course.
-        //* Gotta love OS X
-        kr = (*iface)->GetDevice(iface, &usbDevice);
-        if (kIOReturnSuccess != kr || !usbDevice) {
-            LOG(ERROR) << "Couldn't grab device from interface (" << std::hex << kr << ")";
-            (*iface)->Release(iface);
-            continue;
-        }
-
-        plugInInterface = NULL;
-        score = 0;
-        //* create an intermediate device plugin
-        kr = IOCreatePlugInInterfaceForService(usbDevice,
-                                               kIOUSBDeviceUserClientTypeID,
-                                               kIOCFPlugInInterfaceID,
-                                               &plugInInterface, &score);
-        //* only needed this to find the plugin
-        (void)IOObjectRelease(usbDevice);
-        if ((kIOReturnSuccess != kr) || (!plugInInterface)) {
-            LOG(ERROR) << "Unable to create a device plug-in (" << std::hex << kr << ")";
-            (*iface)->Release(iface);
-            continue;
-        }
-
-        result = (*plugInInterface)->QueryInterface(plugInInterface,
-            CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID500), (LPVOID*)&dev);
-        //* only needed this to query the plugin
-        (*plugInInterface)->Release(plugInInterface);
-        if (result || !dev) {
-            LOG(ERROR) << "Couldn't create a device interface (" << std::hex << result << ")";
-            (*iface)->Release(iface);
-            continue;
-        }
-
-        //* Now after all that, we actually have a ref to the device and
-        //* the interface that matched our criteria
-        kr = (*dev)->GetDeviceVendor(dev, &vendor);
-        kr = (*dev)->GetDeviceProduct(dev, &product);
-        kr = (*dev)->GetLocationID(dev, &locationId);
-        if (kr == KERN_SUCCESS) {
-            devpath = android::base::StringPrintf("usb:%" PRIu32 "X", locationId);
-            if (IsKnownDevice(devpath)) {
-                (*dev)->Release(dev);
-                (*iface)->Release(iface);
-                continue;
-            }
-        }
-        kr = (*dev)->USBGetSerialNumberStringIndex(dev, &serialIndex);
-
-        if (serialIndex > 0) {
-            IOUSBDevRequest req;
-            UInt16          buffer[256];
-            UInt16          languages[128];
-
-            memset(languages, 0, sizeof(languages));
-
-            req.bmRequestType =
-                    USBmakebmRequestType(kUSBIn, kUSBStandard, kUSBDevice);
-            req.bRequest = kUSBRqGetDescriptor;
-            req.wValue = (kUSBStringDesc << 8) | 0;
-            req.wIndex = 0;
-            req.pData = languages;
-            req.wLength = sizeof(languages);
-            kr = (*dev)->DeviceRequest(dev, &req);
-
-            if (kr == kIOReturnSuccess && req.wLenDone > 0) {
-
-                int langCount = (req.wLenDone - 2) / 2, lang;
-
-                for (lang = 1; lang <= langCount; lang++) {
-
-                    memset(buffer, 0, sizeof(buffer));
-                    memset(&req, 0, sizeof(req));
-
-                    req.bmRequestType =
-                            USBmakebmRequestType(kUSBIn, kUSBStandard, kUSBDevice);
-                    req.bRequest = kUSBRqGetDescriptor;
-                    req.wValue = (kUSBStringDesc << 8) | serialIndex;
-                    req.wIndex = languages[lang];
-                    req.pData = buffer;
-                    req.wLength = sizeof(buffer);
-                    kr = (*dev)->DeviceRequest(dev, &req);
-
-                    if (kr == kIOReturnSuccess && req.wLenDone > 0) {
-                        int i, count;
-
-                        // skip first word, and copy the rest to the serial string,
-                        // changing shorts to bytes.
-                        count = (req.wLenDone - 1) / 2;
-                        for (i = 0; i < count; i++)
-                                serial[i] = buffer[i + 1];
-                        serial[i] = 0;
-                        break;
-                    }
-                }
-            }
-        }
-
-        (*dev)->Release(dev);
-
-        VLOG(USB) << android::base::StringPrintf("Found vid=%04x pid=%04x serial=%s\n",
-                        vendor, product, serial);
-        if (devpath.empty()) {
-            devpath = serial;
-        }
-        if (IsKnownDevice(devpath)) {
-            (*iface)->USBInterfaceClose(iface);
-            (*iface)->Release(iface);
-            continue;
-        }
-
-        std::unique_ptr<usb_handle> handle =
-            CheckInterface((IOUSBInterfaceInterface550**)iface, vendor, product);
-        if (handle == nullptr) {
-            LOG(ERROR) << "Could not find device interface";
-            (*iface)->Release(iface);
-            continue;
-        }
-        handle->devpath = devpath;
-        usb_handle* handle_p = handle.get();
-        VLOG(USB) << "Add usb device " << serial;
-        LOG(INFO) << "reported max packet size for " << serial << " is " << handle->max_packet_size;
-        AddDevice(std::move(handle));
-        register_usb_transport(reinterpret_cast<::usb_handle*>(handle_p), serial, devpath.c_str(),
-                               1);
-    }
-}
-
-// Used to clear both the endpoints before starting.
-// When adb quits, we might clear the host endpoint but not the device.
-// So we make sure both sides are clear before starting up.
-static bool ClearPipeStallBothEnds(IOUSBInterfaceInterface550** interface, UInt8 bulkEp) {
-    IOReturn rc = (*interface)->ClearPipeStallBothEnds(interface, bulkEp);
-    if (rc != kIOReturnSuccess) {
-        LOG(ERROR) << "Could not clear pipe stall both ends: " << std::hex << rc;
-        return false;
-    }
-    return true;
-}
-
-//* TODO: simplify this further since we only register to get ADB interface
-//* subclass+protocol events
-static std::unique_ptr<usb_handle> CheckInterface(IOUSBInterfaceInterface550** interface,
-                                                  UInt16 vendor, UInt16 product) {
-    std::unique_ptr<usb_handle> handle;
-    IOReturn kr;
-    UInt8 interfaceNumEndpoints, interfaceClass, interfaceSubClass, interfaceProtocol;
-    UInt8 endpoint;
-
-    //* Now open the interface.  This will cause the pipes associated with
-    //* the endpoints in the interface descriptor to be instantiated
-    kr = (*interface)->USBInterfaceOpen(interface);
-    if (kr != kIOReturnSuccess) {
-        LOG(ERROR) << "Could not open interface: " << std::hex << kr;
-        return NULL;
-    }
-
-    //* Get the number of endpoints associated with this interface
-    kr = (*interface)->GetNumEndpoints(interface, &interfaceNumEndpoints);
-    if (kr != kIOReturnSuccess) {
-        LOG(ERROR) << "Unable to get number of endpoints: " << std::hex << kr;
-        goto err_get_num_ep;
-    }
-
-    //* Get interface class, subclass and protocol
-    if ((*interface)->GetInterfaceClass(interface, &interfaceClass) != kIOReturnSuccess ||
-            (*interface)->GetInterfaceSubClass(interface, &interfaceSubClass) != kIOReturnSuccess ||
-            (*interface)->GetInterfaceProtocol(interface, &interfaceProtocol) != kIOReturnSuccess) {
-            LOG(ERROR) << "Unable to get interface class, subclass and protocol";
-            goto err_get_interface_class;
-    }
-
-    //* check to make sure interface class, subclass and protocol match ADB
-    //* avoid opening mass storage endpoints
-    if (!is_adb_interface(interfaceClass, interfaceSubClass, interfaceProtocol)) {
-        goto err_bad_adb_interface;
-    }
-
-    handle.reset(new usb_handle);
-    if (handle == nullptr) {
-        goto err_bad_adb_interface;
-    }
-
-    //* Iterate over the endpoints for this interface and find the first
-    //* bulk in/out pipes available.  These will be our read/write pipes.
-    for (endpoint = 1; endpoint <= interfaceNumEndpoints; endpoint++) {
-        UInt8   transferType;
-        UInt16  maxPacketSize;
-        UInt8   interval;
-        UInt8   number;
-        UInt8   direction;
-        UInt8 maxBurst;
-        UInt8 mult;
-        UInt16 bytesPerInterval;
-
-        kr = (*interface)
-                 ->GetPipePropertiesV2(interface, endpoint, &direction, &number, &transferType,
-                                       &maxPacketSize, &interval, &maxBurst, &mult,
-                                       &bytesPerInterval);
-        if (kr != kIOReturnSuccess) {
-            LOG(ERROR) << "FindDeviceInterface - could not get pipe properties: "
-                       << std::hex << kr;
-            goto err_get_pipe_props;
-        }
-
-        if (kUSBBulk != transferType) continue;
-
-        if (kUSBIn == direction) {
-            handle->bulkIn = endpoint;
-            if (!ClearPipeStallBothEnds(interface, handle->bulkIn)) goto err_get_pipe_props;
-        }
-
-        if (kUSBOut == direction) {
-            handle->bulkOut = endpoint;
-            if (!ClearPipeStallBothEnds(interface, handle->bulkOut)) goto err_get_pipe_props;
-        }
-
-        if (maxBurst != 0)
-            // bMaxBurst is the number of additional packets in the burst.
-            maxPacketSize /= (maxBurst + 1);
-
-        // mult is only relevant for isochronous endpoints.
-        CHECK_EQ(0, mult);
-
-        handle->zero_mask = maxPacketSize - 1;
-        handle->max_packet_size = maxPacketSize;
-    }
-
-    handle->interface = interface;
-    return handle;
-
-err_get_pipe_props:
-err_bad_adb_interface:
-err_get_interface_class:
-err_get_num_ep:
-    (*interface)->USBInterfaceClose(interface);
-    return nullptr;
-}
-
-std::mutex& operate_device_lock = *new std::mutex();
-
-static void RunLoopThread() {
-    adb_thread_setname("RunLoop");
-
-    VLOG(USB) << "RunLoopThread started";
-    while (true) {
-        {
-            std::lock_guard<std::mutex> lock_guard(operate_device_lock);
-            FindUSBDevices();
-            KickDisconnectedDevices();
-        }
-        // Signal the parent that we are running
-        usb_inited_flag = true;
-        std::this_thread::sleep_for(1s);
-    }
-    VLOG(USB) << "RunLoopThread done";
-}
-
-void usb_cleanup() NO_THREAD_SAFETY_ANALYSIS {
-    VLOG(USB) << "usb_cleanup";
-    // Wait until usb operations in RunLoopThread finish, and prevent further operations.
-    operate_device_lock.lock();
-    close_usb_devices();
-}
-
-void usb_init() {
-    static bool initialized = false;
-    if (!initialized) {
-        usb_inited_flag = false;
-
-        std::thread(RunLoopThread).detach();
-
-        // Wait for initialization to finish
-        while (!usb_inited_flag) {
-            std::this_thread::sleep_for(100ms);
-        }
-
-        adb_notify_device_scan_complete();
-        initialized = true;
-    }
-}
-
-int usb_write(usb_handle *handle, const void *buf, int len)
-{
-    IOReturn    result;
-
-    if (!len)
-        return 0;
-
-    if (!handle || handle->dead)
-        return -1;
-
-    if (NULL == handle->interface) {
-        LOG(ERROR) << "usb_write interface was null";
-        return -1;
-    }
-
-    if (0 == handle->bulkOut) {
-        LOG(ERROR) << "bulkOut endpoint not assigned";
-        return -1;
-    }
-
-    result =
-        (*handle->interface)->WritePipe(handle->interface, handle->bulkOut, (void *)buf, len);
-
-    if ((result == 0) && (handle->zero_mask)) {
-        /* we need 0-markers and our transfer */
-        if(!(len & handle->zero_mask)) {
-            result =
-                (*handle->interface)->WritePipe(
-                        handle->interface, handle->bulkOut, (void *)buf, 0);
-        }
-    }
-
-    if (!result)
-        return len;
-
-    LOG(ERROR) << "usb_write failed with status: " << std::hex << result;
-    return -1;
-}
-
-int usb_read(usb_handle *handle, void *buf, int len)
-{
-    IOReturn result;
-    UInt32  numBytes = len;
-
-    if (!len) {
-        return 0;
-    }
-
-    if (!handle || handle->dead) {
-        return -1;
-    }
-
-    if (NULL == handle->interface) {
-        LOG(ERROR) << "usb_read interface was null";
-        return -1;
-    }
-
-    if (0 == handle->bulkIn) {
-        LOG(ERROR) << "bulkIn endpoint not assigned";
-        return -1;
-    }
-
-    result = (*handle->interface)->ReadPipe(handle->interface, handle->bulkIn, buf, &numBytes);
-
-    if (kIOUSBPipeStalled == result) {
-        LOG(ERROR) << "Pipe stalled, clearing stall.\n";
-        (*handle->interface)->ClearPipeStall(handle->interface, handle->bulkIn);
-        result = (*handle->interface)->ReadPipe(handle->interface, handle->bulkIn, buf, &numBytes);
-    }
-
-    if (kIOReturnSuccess == result)
-        return numBytes;
-    else {
-        LOG(ERROR) << "usb_read failed with status: " << std::hex << result;
-    }
-
-    return -1;
-}
-
-int usb_close(usb_handle *handle)
-{
-    std::lock_guard<std::mutex> lock(g_usb_handles_mutex);
-    for (auto it = g_usb_handles.begin(); it != g_usb_handles.end(); ++it) {
-        if ((*it).get() == handle) {
-            g_usb_handles.erase(it);
-            break;
-        }
-    }
-    return 0;
-}
-
-void usb_reset(usb_handle* handle) {
-    // Unimplemented on OS X.
-    usb_kick(handle);
-}
-
-static void usb_kick_locked(usb_handle *handle)
-{
-    LOG(INFO) << "Kicking handle";
-    /* release the interface */
-    if (!handle)
-        return;
-
-    if (!handle->dead)
-    {
-        handle->dead = true;
-        (*handle->interface)->USBInterfaceClose(handle->interface);
-        (*handle->interface)->Release(handle->interface);
-    }
-}
-
-void usb_kick(usb_handle *handle) {
-    // Use the lock to avoid multiple thread kicking the device at the same time.
-    std::lock_guard<std::mutex> lock_guard(g_usb_handles_mutex);
-    usb_kick_locked(handle);
-}
-
-size_t usb_get_max_packet_size(usb_handle* handle) {
-    return handle->max_packet_size;
-}
-
-} // namespace native
diff --git a/adb/client/usb_windows.cpp b/adb/client/usb_windows.cpp
deleted file mode 100644
index e209230..0000000
--- a/adb/client/usb_windows.cpp
+++ /dev/null
@@ -1,621 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define TRACE_TAG USB
-
-#include "sysdeps.h"
-
-#include "client/usb.h"
-
-// clang-format off
-#include <winsock2.h>  // winsock.h *must* be included before windows.h.
-#include <windows.h>
-// clang-format on
-#include <usb100.h>
-#include <winerror.h>
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <algorithm>
-#include <mutex>
-#include <thread>
-
-#include <adb_api.h>
-
-#include <android-base/errors.h>
-
-#include "adb.h"
-#include "sysdeps/chrono.h"
-#include "transport.h"
-
-namespace native {
-
-/** Structure usb_handle describes our connection to the usb device via
-  AdbWinApi.dll. This structure is returned from usb_open() routine and
-  is expected in each subsequent call that is accessing the device.
-
-  Most members are protected by usb_lock, except for adb_{read,write}_pipe which
-  rely on AdbWinApi.dll's handle validation and AdbCloseHandle(endpoint)'s
-  ability to break a thread out of pipe IO.
-*/
-struct usb_handle : public ::usb_handle {
-    /// Handle to USB interface
-    ADBAPIHANDLE adb_interface;
-
-    /// Handle to USB read pipe (endpoint)
-    ADBAPIHANDLE adb_read_pipe;
-
-    /// Handle to USB write pipe (endpoint)
-    ADBAPIHANDLE adb_write_pipe;
-
-    /// Interface name
-    wchar_t* interface_name;
-
-    /// Maximum packet size.
-    unsigned max_packet_size;
-
-    /// Mask for determining when to use zero length packets
-    unsigned zero_mask;
-};
-
-/// Class ID assigned to the device by androidusb.sys
-static const GUID usb_class_id = ANDROID_USB_CLASS_ID;
-
-/// List of opened usb handles
-static std::vector<usb_handle*>& handle_list = *new std::vector<usb_handle*>();
-
-/// Locker for the list of opened usb handles
-static std::mutex& usb_lock = *new std::mutex();
-
-/// Checks if there is opened usb handle in handle_list for this device.
-int known_device(const wchar_t* dev_name);
-
-/// Checks if there is opened usb handle in handle_list for this device.
-/// usb_lock mutex must be held before calling this routine.
-int known_device_locked(const wchar_t* dev_name);
-
-/// Registers opened usb handle (adds it to handle_list).
-int register_new_device(usb_handle* handle);
-
-/// Checks if interface (device) matches certain criteria
-int recognized_device(usb_handle* handle);
-
-/// Enumerates present and available interfaces (devices), opens new ones and
-/// registers usb transport for them.
-void find_devices();
-
-/// Kicks all USB devices
-static void kick_devices();
-
-/// Entry point for thread that polls (every second) for new usb interfaces.
-/// This routine calls find_devices in infinite loop.
-static void device_poll_thread();
-
-/// Initializes this module
-void usb_init();
-
-/// Opens usb interface (device) by interface (device) name.
-usb_handle* do_usb_open(const wchar_t* interface_name);
-
-/// Writes data to the opened usb handle
-int usb_write(usb_handle* handle, const void* data, int len);
-
-/// Reads data using the opened usb handle
-int usb_read(usb_handle* handle, void* data, int len);
-
-/// Cleans up opened usb handle
-void usb_cleanup_handle(usb_handle* handle);
-
-/// Cleans up (but don't close) opened usb handle
-void usb_kick(usb_handle* handle);
-
-/// Closes opened usb handle
-int usb_close(usb_handle* handle);
-
-int known_device_locked(const wchar_t* dev_name) {
-    if (nullptr != dev_name) {
-        // Iterate through the list looking for the name match.
-        for (usb_handle* usb : handle_list) {
-            // In Windows names are not case sensetive!
-            if ((nullptr != usb->interface_name) && (0 == wcsicmp(usb->interface_name, dev_name))) {
-                return 1;
-            }
-        }
-    }
-
-    return 0;
-}
-
-int known_device(const wchar_t* dev_name) {
-    int ret = 0;
-
-    if (nullptr != dev_name) {
-        std::lock_guard<std::mutex> lock(usb_lock);
-        ret = known_device_locked(dev_name);
-    }
-
-    return ret;
-}
-
-int register_new_device(usb_handle* handle) {
-    if (nullptr == handle) return 0;
-
-    std::lock_guard<std::mutex> lock(usb_lock);
-
-    // Check if device is already in the list
-    if (known_device_locked(handle->interface_name)) {
-        return 0;
-    }
-
-    // Not in the list. Add this handle to the list.
-    handle_list.push_back(handle);
-
-    return 1;
-}
-
-void device_poll_thread() {
-    adb_thread_setname("Device Poll");
-    D("Created device thread");
-
-    while (true) {
-        find_devices();
-        adb_notify_device_scan_complete();
-        std::this_thread::sleep_for(1s);
-    }
-}
-
-static LRESULT CALLBACK _power_window_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
-    switch (uMsg) {
-        case WM_POWERBROADCAST:
-            switch (wParam) {
-                case PBT_APMRESUMEAUTOMATIC:
-                    // Resuming from sleep or hibernation, so kick all existing USB devices
-                    // and then allow the device_poll_thread to redetect USB devices from
-                    // scratch. If we don't do this, existing USB devices will never respond
-                    // to us because they'll be waiting for the connect/auth handshake.
-                    D("Received (WM_POWERBROADCAST, PBT_APMRESUMEAUTOMATIC) notification, "
-                      "so kicking all USB devices\n");
-                    kick_devices();
-                    return TRUE;
-            }
-    }
-    return DefWindowProcW(hwnd, uMsg, wParam, lParam);
-}
-
-static void _power_notification_thread() {
-    // This uses a thread with its own window message pump to get power
-    // notifications. If adb runs from a non-interactive service account, this
-    // might not work (not sure). If that happens to not work, we could use
-    // heavyweight WMI APIs to get power notifications. But for the common case
-    // of a developer's interactive session, a window message pump is more
-    // appropriate.
-    D("Created power notification thread");
-    adb_thread_setname("Power Notifier");
-
-    // Window class names are process specific.
-    static const WCHAR kPowerNotificationWindowClassName[] = L"PowerNotificationWindow";
-
-    // Get the HINSTANCE corresponding to the module that _power_window_proc
-    // is in (the main module).
-    const HINSTANCE instance = GetModuleHandleW(nullptr);
-    if (!instance) {
-        // This is such a common API call that this should never fail.
-        LOG(FATAL) << "GetModuleHandleW failed: "
-                   << android::base::SystemErrorCodeToString(GetLastError());
-    }
-
-    WNDCLASSEXW wndclass;
-    memset(&wndclass, 0, sizeof(wndclass));
-    wndclass.cbSize = sizeof(wndclass);
-    wndclass.lpfnWndProc = _power_window_proc;
-    wndclass.hInstance = instance;
-    wndclass.lpszClassName = kPowerNotificationWindowClassName;
-    if (!RegisterClassExW(&wndclass)) {
-        LOG(FATAL) << "RegisterClassExW failed: "
-                   << android::base::SystemErrorCodeToString(GetLastError());
-    }
-
-    if (!CreateWindowExW(WS_EX_NOACTIVATE, kPowerNotificationWindowClassName,
-                         L"ADB Power Notification Window", WS_POPUP, 0, 0, 0, 0, nullptr, nullptr,
-                         instance, nullptr)) {
-        LOG(FATAL) << "CreateWindowExW failed: "
-                   << android::base::SystemErrorCodeToString(GetLastError());
-    }
-
-    MSG msg;
-    while (GetMessageW(&msg, nullptr, 0, 0)) {
-        TranslateMessage(&msg);
-        DispatchMessageW(&msg);
-    }
-
-    // GetMessageW() will return false if a quit message is posted. We don't
-    // do that, but it might be possible for that to occur when logging off or
-    // shutting down. Not a big deal since the whole process will be going away
-    // soon anyway.
-    D("Power notification thread exiting");
-}
-
-void usb_init() {
-    std::thread(device_poll_thread).detach();
-    std::thread(_power_notification_thread).detach();
-}
-
-void usb_cleanup() {}
-
-usb_handle* do_usb_open(const wchar_t* interface_name) {
-    unsigned long name_len = 0;
-
-    // Allocate our handle
-    usb_handle* ret = (usb_handle*)calloc(1, sizeof(usb_handle));
-    if (nullptr == ret) {
-        D("Could not allocate %u bytes for usb_handle: %s", sizeof(usb_handle), strerror(errno));
-        goto fail;
-    }
-
-    // Create interface.
-    ret->adb_interface = AdbCreateInterfaceByName(interface_name);
-    if (nullptr == ret->adb_interface) {
-        D("AdbCreateInterfaceByName failed: %s",
-          android::base::SystemErrorCodeToString(GetLastError()).c_str());
-        goto fail;
-    }
-
-    // Open read pipe (endpoint)
-    ret->adb_read_pipe = AdbOpenDefaultBulkReadEndpoint(
-        ret->adb_interface, AdbOpenAccessTypeReadWrite, AdbOpenSharingModeReadWrite);
-    if (nullptr == ret->adb_read_pipe) {
-        D("AdbOpenDefaultBulkReadEndpoint failed: %s",
-          android::base::SystemErrorCodeToString(GetLastError()).c_str());
-        goto fail;
-    }
-
-    // Open write pipe (endpoint)
-    ret->adb_write_pipe = AdbOpenDefaultBulkWriteEndpoint(
-        ret->adb_interface, AdbOpenAccessTypeReadWrite, AdbOpenSharingModeReadWrite);
-    if (nullptr == ret->adb_write_pipe) {
-        D("AdbOpenDefaultBulkWriteEndpoint failed: %s",
-          android::base::SystemErrorCodeToString(GetLastError()).c_str());
-        goto fail;
-    }
-
-    // Save interface name
-    // First get expected name length
-    AdbGetInterfaceName(ret->adb_interface, nullptr, &name_len, false);
-    if (0 == name_len) {
-        D("AdbGetInterfaceName returned name length of zero: %s",
-          android::base::SystemErrorCodeToString(GetLastError()).c_str());
-        goto fail;
-    }
-
-    ret->interface_name = (wchar_t*)malloc(name_len * sizeof(ret->interface_name[0]));
-    if (nullptr == ret->interface_name) {
-        D("Could not allocate %lu characters for interface_name: %s", name_len, strerror(errno));
-        goto fail;
-    }
-
-    // Now save the name
-    if (!AdbGetInterfaceName(ret->adb_interface, ret->interface_name, &name_len, false)) {
-        D("AdbGetInterfaceName failed: %s",
-          android::base::SystemErrorCodeToString(GetLastError()).c_str());
-        goto fail;
-    }
-
-    // We're done at this point
-    return ret;
-
-fail:
-    if (nullptr != ret) {
-        usb_cleanup_handle(ret);
-        free(ret);
-    }
-
-    return nullptr;
-}
-
-int usb_write(usb_handle* handle, const void* data, int len) {
-    unsigned long time_out = 5000;
-    unsigned long written = 0;
-    int err = 0;
-
-    D("usb_write %d", len);
-    if (nullptr == handle) {
-        D("usb_write was passed NULL handle");
-        err = EINVAL;
-        goto fail;
-    }
-
-    // Perform write
-    if (!AdbWriteEndpointSync(handle->adb_write_pipe, (void*)data, (unsigned long)len, &written,
-                              time_out)) {
-        D("AdbWriteEndpointSync failed: %s",
-          android::base::SystemErrorCodeToString(GetLastError()).c_str());
-        err = EIO;
-        goto fail;
-    }
-
-    // Make sure that we've written what we were asked to write
-    D("usb_write got: %ld, expected: %d", written, len);
-    if (written != (unsigned long)len) {
-        // If this occurs, this code should be changed to repeatedly call
-        // AdbWriteEndpointSync() until all bytes are written.
-        D("AdbWriteEndpointSync was supposed to write %d, but only wrote %ld", len, written);
-        err = EIO;
-        goto fail;
-    }
-
-    if (handle->zero_mask && (len & handle->zero_mask) == 0) {
-        // Send a zero length packet
-        unsigned long dummy;
-        if (!AdbWriteEndpointSync(handle->adb_write_pipe, (void*)data, 0, &dummy, time_out)) {
-            D("AdbWriteEndpointSync of zero length packet failed: %s",
-              android::base::SystemErrorCodeToString(GetLastError()).c_str());
-            err = EIO;
-            goto fail;
-        }
-    }
-
-    return written;
-
-fail:
-    // Any failure should cause us to kick the device instead of leaving it a
-    // zombie state with potential to hang.
-    if (nullptr != handle) {
-        D("Kicking device due to error in usb_write");
-        usb_kick(handle);
-    }
-
-    D("usb_write failed");
-    errno = err;
-    return -1;
-}
-
-int usb_read(usb_handle* handle, void* data, int len) {
-    unsigned long time_out = 0;
-    unsigned long read = 0;
-    int err = 0;
-    int orig_len = len;
-
-    D("usb_read %d", len);
-    if (nullptr == handle) {
-        D("usb_read was passed NULL handle");
-        err = EINVAL;
-        goto fail;
-    }
-
-    while (len == orig_len) {
-        if (!AdbReadEndpointSync(handle->adb_read_pipe, data, len, &read, time_out)) {
-            D("AdbReadEndpointSync failed: %s",
-              android::base::SystemErrorCodeToString(GetLastError()).c_str());
-            err = EIO;
-            goto fail;
-        }
-        D("usb_read got: %ld, expected: %d", read, len);
-
-        data = (char*)data + read;
-        len -= read;
-    }
-
-    return orig_len - len;
-
-fail:
-    // Any failure should cause us to kick the device instead of leaving it a
-    // zombie state with potential to hang.
-    if (nullptr != handle) {
-        D("Kicking device due to error in usb_read");
-        usb_kick(handle);
-    }
-
-    D("usb_read failed");
-    errno = err;
-    return -1;
-}
-
-// Wrapper around AdbCloseHandle() that logs diagnostics.
-static void _adb_close_handle(ADBAPIHANDLE adb_handle) {
-    if (!AdbCloseHandle(adb_handle)) {
-        D("AdbCloseHandle(%p) failed: %s", adb_handle,
-          android::base::SystemErrorCodeToString(GetLastError()).c_str());
-    }
-}
-
-void usb_cleanup_handle(usb_handle* handle) {
-    D("usb_cleanup_handle");
-    if (nullptr != handle) {
-        if (nullptr != handle->interface_name) free(handle->interface_name);
-        // AdbCloseHandle(pipe) will break any threads out of pending IO calls and
-        // wait until the pipe no longer uses the interface. Then we can
-        // AdbCloseHandle() the interface.
-        if (nullptr != handle->adb_write_pipe) _adb_close_handle(handle->adb_write_pipe);
-        if (nullptr != handle->adb_read_pipe) _adb_close_handle(handle->adb_read_pipe);
-        if (nullptr != handle->adb_interface) _adb_close_handle(handle->adb_interface);
-
-        handle->interface_name = nullptr;
-        handle->adb_write_pipe = nullptr;
-        handle->adb_read_pipe = nullptr;
-        handle->adb_interface = nullptr;
-    }
-}
-
-void usb_reset(usb_handle* handle) {
-    // Unimplemented on Windows.
-    usb_kick(handle);
-}
-
-static void usb_kick_locked(usb_handle* handle) {
-    // The reason the lock must be acquired before calling this function is in
-    // case multiple threads are trying to kick the same device at the same time.
-    usb_cleanup_handle(handle);
-}
-
-void usb_kick(usb_handle* handle) {
-    D("usb_kick");
-    if (nullptr != handle) {
-        std::lock_guard<std::mutex> lock(usb_lock);
-        usb_kick_locked(handle);
-    } else {
-        errno = EINVAL;
-    }
-}
-
-int usb_close(usb_handle* handle) {
-    D("usb_close");
-
-    if (nullptr != handle) {
-        // Remove handle from the list
-        {
-            std::lock_guard<std::mutex> lock(usb_lock);
-            handle_list.erase(std::remove(handle_list.begin(), handle_list.end(), handle),
-                              handle_list.end());
-        }
-
-        // Cleanup handle
-        usb_cleanup_handle(handle);
-        free(handle);
-    }
-
-    return 0;
-}
-
-size_t usb_get_max_packet_size(usb_handle* handle) {
-    return handle->max_packet_size;
-}
-
-int recognized_device(usb_handle* handle) {
-    if (nullptr == handle) return 0;
-
-    // Check vendor and product id first
-    USB_DEVICE_DESCRIPTOR device_desc;
-
-    if (!AdbGetUsbDeviceDescriptor(handle->adb_interface, &device_desc)) {
-        D("AdbGetUsbDeviceDescriptor failed: %s",
-          android::base::SystemErrorCodeToString(GetLastError()).c_str());
-        return 0;
-    }
-
-    // Then check interface properties
-    USB_INTERFACE_DESCRIPTOR interf_desc;
-
-    if (!AdbGetUsbInterfaceDescriptor(handle->adb_interface, &interf_desc)) {
-        D("AdbGetUsbInterfaceDescriptor failed: %s",
-          android::base::SystemErrorCodeToString(GetLastError()).c_str());
-        return 0;
-    }
-
-    // Must have two endpoints
-    if (2 != interf_desc.bNumEndpoints) {
-        return 0;
-    }
-
-    if (!is_adb_interface(interf_desc.bInterfaceClass, interf_desc.bInterfaceSubClass,
-                          interf_desc.bInterfaceProtocol)) {
-        return 0;
-    }
-
-    AdbEndpointInformation endpoint_info;
-    // assuming zero is a valid bulk endpoint ID
-    if (AdbGetEndpointInformation(handle->adb_interface, 0, &endpoint_info)) {
-        handle->max_packet_size = endpoint_info.max_packet_size;
-        handle->zero_mask = endpoint_info.max_packet_size - 1;
-        D("device zero_mask: 0x%x", handle->zero_mask);
-    } else {
-        D("AdbGetEndpointInformation failed: %s",
-          android::base::SystemErrorCodeToString(GetLastError()).c_str());
-    }
-
-    return 1;
-}
-
-void find_devices() {
-    usb_handle* handle = nullptr;
-    char entry_buffer[2048];
-    AdbInterfaceInfo* next_interface = (AdbInterfaceInfo*)(&entry_buffer[0]);
-    unsigned long entry_buffer_size = sizeof(entry_buffer);
-
-    // Enumerate all present and active interfaces.
-    ADBAPIHANDLE enum_handle = AdbEnumInterfaces(usb_class_id, true, true, true);
-
-    if (nullptr == enum_handle) {
-        D("AdbEnumInterfaces failed: %s",
-          android::base::SystemErrorCodeToString(GetLastError()).c_str());
-        return;
-    }
-
-    while (AdbNextInterface(enum_handle, next_interface, &entry_buffer_size)) {
-        // Lets see if we already have this device in the list
-        if (!known_device(next_interface->device_name)) {
-            // This seems to be a new device. Open it!
-            handle = do_usb_open(next_interface->device_name);
-            if (nullptr != handle) {
-                // Lets see if this interface (device) belongs to us
-                if (recognized_device(handle)) {
-                    D("adding a new device %ls", next_interface->device_name);
-
-                    // We don't request a wchar_t string from AdbGetSerialNumber() because of a bug
-                    // in adb_winusb_interface.cpp:CopyMemory(buffer, ser_num->bString,
-                    // bytes_written) where the last parameter should be (str_len *
-                    // sizeof(wchar_t)). The bug reads 2 bytes past the end of a stack buffer in the
-                    // best case, and in the unlikely case of a long serial number, it will read 2
-                    // bytes past the end of a heap allocation. This doesn't affect the resulting
-                    // string, but we should avoid the bad reads in the first place.
-                    char serial_number[512];
-                    unsigned long serial_number_len = sizeof(serial_number);
-                    if (AdbGetSerialNumber(handle->adb_interface, serial_number, &serial_number_len,
-                                           true)) {
-                        // Lets make sure that we don't duplicate this device
-                        if (register_new_device(handle)) {
-                            register_usb_transport(handle, serial_number, nullptr, 1);
-                        } else {
-                            D("register_new_device failed for %ls", next_interface->device_name);
-                            usb_cleanup_handle(handle);
-                            free(handle);
-                        }
-                    } else {
-                        D("cannot get serial number: %s",
-                          android::base::SystemErrorCodeToString(GetLastError()).c_str());
-                        usb_cleanup_handle(handle);
-                        free(handle);
-                    }
-                } else {
-                    usb_cleanup_handle(handle);
-                    free(handle);
-                }
-            }
-        }
-
-        entry_buffer_size = sizeof(entry_buffer);
-    }
-
-    if (GetLastError() != ERROR_NO_MORE_ITEMS) {
-        // Only ERROR_NO_MORE_ITEMS is expected at the end of enumeration.
-        D("AdbNextInterface failed: %s",
-          android::base::SystemErrorCodeToString(GetLastError()).c_str());
-    }
-
-    _adb_close_handle(enum_handle);
-}
-
-static void kick_devices() {
-    // Need to acquire lock to safely walk the list which might be modified
-    // by another thread.
-    std::lock_guard<std::mutex> lock(usb_lock);
-    for (usb_handle* usb : handle_list) {
-        usb_kick_locked(usb);
-    }
-}
-
-}  // namespace native
diff --git a/adb/crypto/Android.bp b/adb/crypto/Android.bp
deleted file mode 100644
index 9d14b03..0000000
--- a/adb/crypto/Android.bp
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-cc_defaults {
-    name: "libadb_crypto_defaults",
-    cflags: [
-        "-Wall",
-        "-Wextra",
-        "-Wthread-safety",
-        "-Werror",
-    ],
-
-    compile_multilib: "both",
-
-    srcs: [
-        "key.cpp",
-        "rsa_2048_key.cpp",
-        "x509_generator.cpp",
-    ],
-
-    target: {
-        windows: {
-            compile_multilib: "first",
-            enabled: true,
-        },
-    },
-
-    export_include_dirs: ["include"],
-
-    visibility: [
-        "//system/core/adb:__subpackages__",
-        "//bootable/recovery/minadbd:__subpackages__",
-    ],
-
-    host_supported: true,
-    recovery_available: true,
-
-    shared_libs: [
-        "libadb_protos",
-        "libbase",
-        "liblog",
-        "libcrypto",
-        "libcrypto_utils",
-    ],
-}
-
-cc_library {
-    name: "libadb_crypto",
-    defaults: ["libadb_crypto_defaults"],
-
-    apex_available: [
-        "com.android.adbd",
-        "test_com.android.adbd",
-    ],
-}
-
-// For running atest (b/147158681)
-cc_library_static {
-    name: "libadb_crypto_static",
-    defaults: ["libadb_crypto_defaults"],
-
-    apex_available: [
-        "//apex_available:platform",
-    ],
-
-    static_libs: [
-        "libadb_protos_static",
-    ],
-}
diff --git a/adb/crypto/include/adb/crypto/key.h b/adb/crypto/include/adb/crypto/key.h
deleted file mode 100644
index d9ce69e..0000000
--- a/adb/crypto/include/adb/crypto/key.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <string>
-
-#include <openssl/evp.h>
-
-#include "key_type.pb.h"
-
-namespace adb {
-namespace crypto {
-
-// Class that represents a public/private key pair.
-class Key {
-  public:
-    explicit Key(bssl::UniquePtr<EVP_PKEY>&& pkey, adb::proto::KeyType type)
-        : pkey_(std::move(pkey)), key_type_(type) {}
-    Key(Key&&) = default;
-    Key& operator=(Key&&) = default;
-
-    EVP_PKEY* GetEvpPkey() const { return pkey_.get(); }
-    adb::proto::KeyType GetKeyType() const { return key_type_; }
-    static std::string ToPEMString(EVP_PKEY* pkey);
-
-  private:
-    bssl::UniquePtr<EVP_PKEY> pkey_;
-    adb::proto::KeyType key_type_;
-};  // Key
-
-}  // namespace crypto
-}  // namespace adb
diff --git a/adb/crypto/include/adb/crypto/rsa_2048_key.h b/adb/crypto/include/adb/crypto/rsa_2048_key.h
deleted file mode 100644
index 2983a84..0000000
--- a/adb/crypto/include/adb/crypto/rsa_2048_key.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <memory>
-#include <optional>
-
-#include "adb/crypto/key.h"
-
-namespace adb {
-namespace crypto {
-
-// Create a new RSA2048 key pair.
-std::optional<Key> CreateRSA2048Key();
-
-// Generates the public key from the RSA private key.
-bool CalculatePublicKey(std::string* out, RSA* private_key);
-
-}  // namespace crypto
-}  // namespace adb
diff --git a/adb/crypto/include/adb/crypto/x509_generator.h b/adb/crypto/include/adb/crypto/x509_generator.h
deleted file mode 100644
index a269243..0000000
--- a/adb/crypto/include/adb/crypto/x509_generator.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <openssl/x509v3.h>
-
-namespace adb {
-namespace crypto {
-
-// Generate a X.509 certificate based on the key |pkey|.
-bssl::UniquePtr<X509> GenerateX509Certificate(EVP_PKEY* pkey);
-
-// Convert X509* to PEM string format
-std::string X509ToPEMString(X509* x509);
-
-}  // namespace crypto
-}  // namespace adb
diff --git a/adb/crypto/key.cpp b/adb/crypto/key.cpp
deleted file mode 100644
index 4d87006..0000000
--- a/adb/crypto/key.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "adb/crypto/key.h"
-
-#include <android-base/logging.h>
-#include <openssl/bn.h>
-#include <openssl/pem.h>
-#include <openssl/rsa.h>
-
-namespace adb {
-namespace crypto {
-
-// static
-std::string Key::ToPEMString(EVP_PKEY* pkey) {
-    bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_mem()));
-    int rc = PEM_write_bio_PKCS8PrivateKey(bio.get(), pkey, nullptr, nullptr, 0, nullptr, nullptr);
-    if (rc != 1) {
-        LOG(ERROR) << "PEM_write_bio_PKCS8PrivateKey failed";
-        return "";
-    }
-
-    BUF_MEM* mem = nullptr;
-    BIO_get_mem_ptr(bio.get(), &mem);
-    if (!mem || !mem->data || !mem->length) {
-        LOG(ERROR) << "BIO_get_mem_ptr failed";
-        return "";
-    }
-
-    return std::string(mem->data, mem->length);
-}
-
-}  // namespace crypto
-}  // namespace adb
diff --git a/adb/crypto/rsa_2048_key.cpp b/adb/crypto/rsa_2048_key.cpp
deleted file mode 100644
index 7911af9..0000000
--- a/adb/crypto/rsa_2048_key.cpp
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "adb/crypto/rsa_2048_key.h"
-
-#include <android-base/logging.h>
-#include <crypto_utils/android_pubkey.h>
-#include <openssl/bn.h>
-#include <openssl/rsa.h>
-
-namespace adb {
-namespace crypto {
-
-namespace {
-std::string get_user_info() {
-    std::string hostname;
-    if (getenv("HOSTNAME")) hostname = getenv("HOSTNAME");
-#if !defined(_WIN32)
-    char buf[64];
-    if (hostname.empty() && gethostname(buf, sizeof(buf)) != -1) hostname = buf;
-#endif
-    if (hostname.empty()) hostname = "unknown";
-
-    std::string username;
-    if (getenv("LOGNAME")) username = getenv("LOGNAME");
-#if !defined(_WIN32)
-    if (username.empty() && getlogin()) username = getlogin();
-#endif
-    if (username.empty()) hostname = "unknown";
-
-    return " " + username + "@" + hostname;
-}
-
-}  // namespace
-
-bool CalculatePublicKey(std::string* out, RSA* private_key) {
-    uint8_t binary_key_data[ANDROID_PUBKEY_ENCODED_SIZE];
-    if (!android_pubkey_encode(private_key, binary_key_data, sizeof(binary_key_data))) {
-        LOG(ERROR) << "Failed to convert to public key";
-        return false;
-    }
-
-    size_t expected_length;
-    if (!EVP_EncodedLength(&expected_length, sizeof(binary_key_data))) {
-        LOG(ERROR) << "Public key too large to base64 encode";
-        return false;
-    }
-
-    out->resize(expected_length);
-    size_t actual_length = EVP_EncodeBlock(reinterpret_cast<uint8_t*>(out->data()), binary_key_data,
-                                           sizeof(binary_key_data));
-    out->resize(actual_length);
-    out->append(get_user_info());
-    return true;
-}
-
-std::optional<Key> CreateRSA2048Key() {
-    bssl::UniquePtr<EVP_PKEY> pkey(EVP_PKEY_new());
-    bssl::UniquePtr<BIGNUM> exponent(BN_new());
-    bssl::UniquePtr<RSA> rsa(RSA_new());
-    if (!pkey || !exponent || !rsa) {
-        LOG(ERROR) << "Failed to allocate key";
-        return std::nullopt;
-    }
-
-    BN_set_word(exponent.get(), RSA_F4);
-    RSA_generate_key_ex(rsa.get(), 2048, exponent.get(), nullptr);
-    EVP_PKEY_set1_RSA(pkey.get(), rsa.get());
-
-    return std::optional<Key>{Key(std::move(pkey), adb::proto::KeyType::RSA_2048)};
-}
-
-}  // namespace crypto
-}  // namespace adb
diff --git a/adb/crypto/tests/Android.bp b/adb/crypto/tests/Android.bp
deleted file mode 100644
index b32dcf7..0000000
--- a/adb/crypto/tests/Android.bp
+++ /dev/null
@@ -1,41 +0,0 @@
-//
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-cc_test {
-    name: "adb_crypto_test",
-    srcs: [
-        "rsa_2048_key_test.cpp",
-        "x509_generator_test.cpp",
-    ],
-
-    compile_multilib: "first",
-
-    shared_libs: [
-        "libbase",
-        "libcrypto",
-        "libcrypto_utils",
-        "libprotobuf-cpp-lite",
-    ],
-
-    // Let's statically link them so we don't have to install it onto the
-    // system image for testing.
-    static_libs: [
-        "libadb_crypto_static",
-        "libadb_protos_static",
-    ],
-
-    test_suites: ["device-tests"],
-}
diff --git a/adb/crypto/tests/key_test.cpp b/adb/crypto/tests/key_test.cpp
deleted file mode 100644
index 1feb6e8..0000000
--- a/adb/crypto/tests/key_test.cpp
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <gtest/gtest.h>
-
-#include <resolv.h>
-
-#include <adb/crypto/rsa_2048_key.h>
-#include <android-base/logging.h>
-#include <android-base/strings.h>
-#include <crypto_utils/android_pubkey.h>
-#include <openssl/err.h>
-#include <openssl/rsa.h>
-#include <openssl/sha.h>
-
-namespace adb {
-namespace crypto {
-
-TEST(RSA2048Key, Smoke) {
-    auto rsa_2048 = CreateRSA2048Key();
-    EXPECT_NE(rsa_2048, std::nullopt);
-    EXPECT_EQ(rsa_2048->GetKeyType(), adb::proto::KeyType::RSA_2048);
-    ASSERT_NE(rsa_2048->GetEvpPkey(), nullptr);
-
-    // The public key string format is expected to be: "<pub_key> <host_name>"
-    std::string pub_key_plus_name;
-    auto* rsa = EVP_PKEY_get0_RSA(rsa_2048->GetEvpPkey());
-    ASSERT_TRUE(CalculatePublicKey(&pub_key_plus_name, rsa));
-    std::vector<std::string> split = android::base::Split(std::string(pub_key_plus_name), " \t");
-    EXPECT_EQ(split.size(), 2);
-
-    LOG(INFO) << "pub_key=[" << pub_key_plus_name << "]";
-
-    // Try to sign something and decode it.
-    const char token[SHA_DIGEST_LENGTH] = "abcdefghij123456789";
-    std::vector<uint8_t> sig(RSA_size(rsa));
-    unsigned sig_len;
-    EXPECT_EQ(RSA_sign(NID_sha1, reinterpret_cast<const uint8_t*>(token), sizeof(token), sig.data(),
-                       &sig_len, rsa),
-              1);
-    sig.resize(sig_len);
-
-    {
-        uint8_t keybuf[ANDROID_PUBKEY_ENCODED_SIZE + 1];
-        const std::string& pubkey = split[0];
-        ASSERT_EQ(b64_pton(pubkey.c_str(), keybuf, sizeof(keybuf)), ANDROID_PUBKEY_ENCODED_SIZE);
-        RSA* key = nullptr;
-        ASSERT_TRUE(android_pubkey_decode(keybuf, ANDROID_PUBKEY_ENCODED_SIZE, &key));
-        EXPECT_EQ(RSA_verify(NID_sha1, reinterpret_cast<const uint8_t*>(token), sizeof(token),
-                             sig.data(), sig.size(), key),
-                  1);
-        RSA_free(key);
-    }
-}
-
-}  // namespace crypto
-}  // namespace adb
diff --git a/adb/crypto/tests/rsa_2048_key_test.cpp b/adb/crypto/tests/rsa_2048_key_test.cpp
deleted file mode 100644
index 1d8880e..0000000
--- a/adb/crypto/tests/rsa_2048_key_test.cpp
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <gtest/gtest.h>
-
-#include <resolv.h>
-
-#include <adb/crypto/rsa_2048_key.h>
-#include <android-base/logging.h>
-#include <android-base/strings.h>
-#include <crypto_utils/android_pubkey.h>
-#include <openssl/err.h>
-#include <openssl/rsa.h>
-#include <openssl/sha.h>
-
-namespace adb {
-namespace crypto {
-
-TEST(RSA2048Key, Smoke) {
-    auto rsa_2048 = CreateRSA2048Key();
-    EXPECT_NE(rsa_2048, std::nullopt);
-    EXPECT_EQ(rsa_2048->GetKeyType(), adb::proto::KeyType::RSA_2048);
-    ASSERT_NE(rsa_2048->GetEvpPkey(), nullptr);
-
-    // The public key string format is expected to be: "<pub_key> <host_name>"
-    std::string pub_key_plus_name;
-    auto* rsa = EVP_PKEY_get0_RSA(rsa_2048->GetEvpPkey());
-    ASSERT_TRUE(CalculatePublicKey(&pub_key_plus_name, rsa));
-    std::vector<std::string> split = android::base::Split(std::string(pub_key_plus_name), " \t");
-    EXPECT_EQ(split.size(), 2);
-
-    LOG(INFO) << "pub_key=[" << pub_key_plus_name << "]";
-
-    std::string pemString = Key::ToPEMString(rsa_2048->GetEvpPkey());
-    ASSERT_FALSE(pemString.empty());
-
-    // Try to sign something and decode it.
-    const char token[SHA_DIGEST_LENGTH] = "abcdefghij123456789";
-    std::vector<uint8_t> sig(RSA_size(rsa));
-    unsigned sig_len;
-    EXPECT_EQ(RSA_sign(NID_sha1, reinterpret_cast<const uint8_t*>(token), sizeof(token), sig.data(),
-                       &sig_len, rsa),
-              1);
-    sig.resize(sig_len);
-
-    {
-        uint8_t keybuf[ANDROID_PUBKEY_ENCODED_SIZE + 1];
-        const std::string& pubkey = split[0];
-        ASSERT_EQ(b64_pton(pubkey.c_str(), keybuf, sizeof(keybuf)), ANDROID_PUBKEY_ENCODED_SIZE);
-        RSA* key = nullptr;
-        ASSERT_TRUE(android_pubkey_decode(keybuf, ANDROID_PUBKEY_ENCODED_SIZE, &key));
-        EXPECT_EQ(RSA_verify(NID_sha1, reinterpret_cast<const uint8_t*>(token), sizeof(token),
-                             sig.data(), sig.size(), key),
-                  1);
-        RSA_free(key);
-    }
-}
-
-}  // namespace crypto
-}  // namespace adb
diff --git a/adb/crypto/tests/x509_generator_test.cpp b/adb/crypto/tests/x509_generator_test.cpp
deleted file mode 100644
index 281776b..0000000
--- a/adb/crypto/tests/x509_generator_test.cpp
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <gtest/gtest.h>
-
-#include <adb/crypto/rsa_2048_key.h>
-#include <adb/crypto/x509_generator.h>
-#include <android-base/logging.h>
-#include <android-base/strings.h>
-
-namespace adb {
-namespace crypto {
-
-TEST(X509Generator, Smoke) {
-    auto rsa_2048 = CreateRSA2048Key();
-
-    std::string pub_key_plus_name;
-    auto* rsa = EVP_PKEY_get0_RSA(rsa_2048->GetEvpPkey());
-    ASSERT_TRUE(CalculatePublicKey(&pub_key_plus_name, rsa));
-    std::vector<std::string> split = android::base::Split(std::string(pub_key_plus_name), " \t");
-    EXPECT_EQ(split.size(), 2);
-
-    LOG(INFO) << "pub_key=[" << pub_key_plus_name << "]";
-    auto x509_cert = GenerateX509Certificate(rsa_2048->GetEvpPkey());
-    ASSERT_NE(x509_cert.get(), nullptr);
-
-    std::string x509_str = X509ToPEMString(x509_cert.get());
-    ASSERT_FALSE(x509_str.empty());
-}
-
-}  // namespace crypto
-}  // namespace adb
diff --git a/adb/crypto/x509_generator.cpp b/adb/crypto/x509_generator.cpp
deleted file mode 100644
index 43b8153..0000000
--- a/adb/crypto/x509_generator.cpp
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "adb/crypto/x509_generator.h"
-
-#include <vector>
-
-#include <android-base/logging.h>
-#include <crypto_utils/android_pubkey.h>
-#include <openssl/bn.h>
-#include <openssl/pem.h>
-#include <openssl/rsa.h>
-
-namespace adb {
-namespace crypto {
-
-namespace {
-
-const char kBasicConstraints[] = "critical,CA:TRUE";
-const char kKeyUsage[] = "critical,keyCertSign,cRLSign,digitalSignature";
-const char kSubjectKeyIdentifier[] = "hash";
-constexpr int kCertLifetimeSeconds = 10 * 365 * 24 * 60 * 60;
-
-bool add_ext(X509* cert, int nid, const char* value) {
-    size_t len = strlen(value) + 1;
-    std::vector<char> mutableValue(value, value + len);
-    X509V3_CTX context;
-
-    X509V3_set_ctx_nodb(&context);
-
-    X509V3_set_ctx(&context, cert, cert, nullptr, nullptr, 0);
-    X509_EXTENSION* ex = X509V3_EXT_nconf_nid(nullptr, &context, nid, mutableValue.data());
-    if (!ex) {
-        return false;
-    }
-
-    X509_add_ext(cert, ex, -1);
-    X509_EXTENSION_free(ex);
-    return true;
-}
-
-}  // namespace
-
-bssl::UniquePtr<X509> GenerateX509Certificate(EVP_PKEY* pkey) {
-    CHECK(pkey);
-    bssl::UniquePtr<X509> x509(X509_new());
-    if (!x509) {
-        LOG(ERROR) << "Unable to allocate x509 container";
-        return nullptr;
-    }
-    X509_set_version(x509.get(), 2);
-
-    ASN1_INTEGER_set(X509_get_serialNumber(x509.get()), 1);
-    X509_gmtime_adj(X509_get_notBefore(x509.get()), 0);
-    X509_gmtime_adj(X509_get_notAfter(x509.get()), kCertLifetimeSeconds);
-
-    if (!X509_set_pubkey(x509.get(), pkey)) {
-        LOG(ERROR) << "Unable to set x509 public key";
-        return nullptr;
-    }
-
-    X509_NAME* name = X509_get_subject_name(x509.get());
-    if (!name) {
-        LOG(ERROR) << "Unable to get x509 subject name";
-        return nullptr;
-    }
-    X509_NAME_add_entry_by_txt(name, "C", MBSTRING_ASC,
-                               reinterpret_cast<const unsigned char*>("US"), -1, -1, 0);
-    X509_NAME_add_entry_by_txt(name, "O", MBSTRING_ASC,
-                               reinterpret_cast<const unsigned char*>("Android"), -1, -1, 0);
-    X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC,
-                               reinterpret_cast<const unsigned char*>("Adb"), -1, -1, 0);
-    if (!X509_set_issuer_name(x509.get(), name)) {
-        LOG(ERROR) << "Unable to set x509 issuer name";
-        return nullptr;
-    }
-
-    add_ext(x509.get(), NID_basic_constraints, kBasicConstraints);
-    add_ext(x509.get(), NID_key_usage, kKeyUsage);
-    add_ext(x509.get(), NID_subject_key_identifier, kSubjectKeyIdentifier);
-
-    int bytes = X509_sign(x509.get(), pkey, EVP_sha256());
-    if (bytes <= 0) {
-        LOG(ERROR) << "Unable to sign x509 certificate";
-        return nullptr;
-    }
-
-    return x509;
-}
-
-std::string X509ToPEMString(X509* x509) {
-    bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_mem()));
-    int rc = PEM_write_bio_X509(bio.get(), x509);
-    if (rc != 1) {
-        LOG(ERROR) << "PEM_write_bio_X509 failed";
-        return "";
-    }
-
-    BUF_MEM* mem = nullptr;
-    BIO_get_mem_ptr(bio.get(), &mem);
-    if (!mem || !mem->data || !mem->length) {
-        LOG(ERROR) << "BIO_get_mem_ptr failed";
-        return "";
-    }
-
-    return std::string(mem->data, mem->length);
-}
-
-}  // namespace crypto
-}  // namespace adb
diff --git a/adb/daemon/abb.cpp b/adb/daemon/abb.cpp
deleted file mode 100644
index 17c25e8..0000000
--- a/adb/daemon/abb.cpp
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <sys/wait.h>
-
-#include <android-base/cmsg.h>
-#include <android-base/strings.h>
-#include <cmd.h>
-
-#include "adb.h"
-#include "adb_io.h"
-#include "adb_utils.h"
-#include "shell_service.h"
-#include "sysdeps.h"
-
-namespace {
-
-class AdbFdTextOutput : public android::TextOutput {
-  public:
-    explicit AdbFdTextOutput(borrowed_fd fd) : fd_(fd) {}
-
-  private:
-    android::status_t print(const char* txt, size_t len) override {
-        return WriteFdExactly(fd_, txt, len) ? android::OK : -errno;
-    }
-    void moveIndent(int delta) override { /*not implemented*/
-    }
-
-    void pushBundle() override { /*not implemented*/
-    }
-    void popBundle() override { /*not implemented*/
-    }
-
-  private:
-    borrowed_fd fd_;
-};
-
-std::vector<std::string_view> parseCmdArgs(std::string_view args) {
-    std::vector<std::string_view> argv;
-
-    char delim = ABB_ARG_DELIMETER;
-    size_t size = args.size();
-    size_t base = 0;
-    while (base < size) {
-        size_t found;
-        for (found = base; found < size && args[found] && args[found] != delim; ++found)
-            ;
-        if (found > base) {
-            argv.emplace_back(args.substr(base, found - base));
-        }
-        base = found + 1;
-    }
-
-    return argv;
-}
-
-}  // namespace
-
-static int execCmd(std::string_view args, borrowed_fd in, borrowed_fd out, borrowed_fd err) {
-    int max_buf = LINUX_MAX_SOCKET_SIZE;
-    adb_setsockopt(in, SOL_SOCKET, SO_SNDBUF, &max_buf, sizeof(max_buf));
-    adb_setsockopt(out, SOL_SOCKET, SO_SNDBUF, &max_buf, sizeof(max_buf));
-    adb_setsockopt(err, SOL_SOCKET, SO_SNDBUF, &max_buf, sizeof(max_buf));
-
-    AdbFdTextOutput oin(out);
-    AdbFdTextOutput oerr(err);
-    return cmdMain(parseCmdArgs(args), oin, oerr, in.get(), out.get(), err.get(),
-                   RunMode::kLibrary);
-}
-
-int main(int argc, char* const argv[]) {
-    signal(SIGPIPE, SIG_IGN);
-
-    int fd = STDIN_FILENO;
-    std::string data;
-    while (true) {
-        std::string error;
-        if (!ReadProtocolString(fd, &data, &error)) {
-            PLOG(ERROR) << "Failed to read message: " << error;
-            break;
-        }
-
-        std::string_view name = data;
-        auto protocol = SubprocessProtocol::kShell;
-        if (android::base::ConsumePrefix(&name, "abb:")) {
-            protocol = SubprocessProtocol::kShell;
-        } else if (android::base::ConsumePrefix(&name, "abb_exec:")) {
-            protocol = SubprocessProtocol::kNone;
-        } else {
-            LOG(FATAL) << "Unknown command prefix for abb: " << data;
-        }
-
-        unique_fd result = StartCommandInProcess(std::string(name), &execCmd, protocol);
-        int max_buf = LINUX_MAX_SOCKET_SIZE;
-        adb_setsockopt(result, SOL_SOCKET, SO_SNDBUF, &max_buf, sizeof(max_buf));
-        if (android::base::SendFileDescriptors(fd, "", 1, result.get()) != 1) {
-            PLOG(ERROR) << "Failed to send an inprocess fd for command: " << data;
-            break;
-        }
-    }
-}
diff --git a/adb/daemon/abb_service.cpp b/adb/daemon/abb_service.cpp
deleted file mode 100644
index e1df4a5..0000000
--- a/adb/daemon/abb_service.cpp
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "adb.h"
-#include "adb_io.h"
-#include "adb_unique_fd.h"
-#include "adb_utils.h"
-#include "shell_service.h"
-
-#include <android-base/cmsg.h>
-
-namespace {
-
-struct AbbProcess;
-static auto& abbp = *new std::unique_ptr<AbbProcess>(std::make_unique<AbbProcess>());
-
-struct AbbProcess {
-    unique_fd sendCommand(std::string_view command);
-
-  private:
-    static unique_fd startAbbProcess(unique_fd* error_fd);
-
-    static constexpr auto kRetries = 2;
-    static constexpr auto kErrorProtocol = SubprocessProtocol::kShell;
-
-    std::mutex locker_;
-    unique_fd socket_fd_;
-};
-
-unique_fd AbbProcess::sendCommand(std::string_view command) {
-    std::unique_lock lock{locker_};
-
-    for (int i = 0; i < kRetries; ++i) {
-        unique_fd error_fd;
-        if (socket_fd_ == -1) {
-            socket_fd_ = startAbbProcess(&error_fd);
-        }
-        if (socket_fd_ == -1) {
-            LOG(ERROR) << "failed to start abb process";
-            return error_fd;
-        }
-
-        if (!SendProtocolString(socket_fd_, command)) {
-            PLOG(ERROR) << "failed to send command to abb";
-            socket_fd_.reset();
-            continue;
-        }
-
-        unique_fd fd;
-        char buf;
-        if (android::base::ReceiveFileDescriptors(socket_fd_, &buf, 1, &fd) != 1) {
-            PLOG(ERROR) << "failed to receive FD from abb";
-            socket_fd_.reset();
-            continue;
-        }
-
-        return fd;
-    }
-
-    LOG(ERROR) << "abb is unavailable";
-    socket_fd_.reset();
-    return ReportError(kErrorProtocol, "abb is unavailable");
-}
-
-unique_fd AbbProcess::startAbbProcess(unique_fd* error_fd) {
-    constexpr auto abb_process_type = SubprocessType::kRaw;
-    constexpr auto abb_protocol = SubprocessProtocol::kNone;
-    constexpr auto make_pty_raw = false;
-    return StartSubprocess("abb", "dumb", abb_process_type, abb_protocol, make_pty_raw,
-                           kErrorProtocol, error_fd);
-}
-
-}  // namespace
-
-unique_fd execute_abb_command(std::string_view command) {
-    return abbp->sendCommand(command);
-}
diff --git a/adb/daemon/adb_wifi.cpp b/adb/daemon/adb_wifi.cpp
deleted file mode 100644
index 2f9e9b4..0000000
--- a/adb/daemon/adb_wifi.cpp
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#if !ADB_HOST
-
-#define TRACE_TAG ADB_WIRELESS
-
-#include "adb_wifi.h"
-
-#include <unistd.h>
-#include <optional>
-
-#include <adbd_auth.h>
-#include <android-base/properties.h>
-
-#include "adb.h"
-#include "daemon/mdns.h"
-#include "sysdeps.h"
-#include "transport.h"
-
-using namespace android::base;
-
-namespace {
-
-static AdbdAuthContext* auth_ctx;
-
-static void adb_disconnected(void* unused, atransport* t);
-static struct adisconnect adb_disconnect = {adb_disconnected, nullptr};
-
-static void adb_disconnected(void* unused, atransport* t) {
-    LOG(INFO) << "ADB wifi device disconnected";
-    CHECK(t->auth_id.has_value());
-    adbd_auth_tls_device_disconnected(auth_ctx, kAdbTransportTypeWifi, t->auth_id.value());
-}
-
-// TODO(b/31559095): need bionic host so that we can use 'prop_info' returned
-// from WaitForProperty
-#if defined(__ANDROID__)
-
-class TlsServer {
-  public:
-    explicit TlsServer(int port);
-    virtual ~TlsServer();
-    bool Start();
-    uint16_t port() { return port_; };
-
-  private:
-    void OnFdEvent(int fd, unsigned ev);
-    static void StaticOnFdEvent(int fd, unsigned ev, void* opaque);
-
-    fdevent* fd_event_ = nullptr;
-    uint16_t port_;
-};  // TlsServer
-
-TlsServer::TlsServer(int port) : port_(port) {}
-
-TlsServer::~TlsServer() {
-    fdevent* fde = fd_event_;
-    fdevent_run_on_main_thread([fde]() {
-        if (fde != nullptr) {
-            fdevent_destroy(fde);
-        }
-    });
-}
-
-bool TlsServer::Start() {
-    std::condition_variable cv;
-    std::mutex mutex;
-    std::optional<bool> success;
-    auto callback = [&](bool result) {
-        {
-            std::lock_guard<std::mutex> lock(mutex);
-            success = result;
-        }
-        cv.notify_one();
-    };
-
-    std::string err;
-    unique_fd fd(network_inaddr_any_server(port_, SOCK_STREAM, &err));
-    if (fd.get() == -1) {
-        LOG(ERROR) << "Failed to start TLS server [" << err << "]";
-        return false;
-    }
-    close_on_exec(fd.get());
-    int port = socket_get_local_port(fd.get());
-    if (port <= 0 || port > 65535) {
-        LOG(ERROR) << "Invalid port for tls server";
-        return false;
-    }
-    port_ = static_cast<uint16_t>(port);
-    LOG(INFO) << "adbwifi started on port " << port_;
-
-    std::unique_lock<std::mutex> lock(mutex);
-    fdevent_run_on_main_thread([&]() {
-        fd_event_ = fdevent_create(fd.release(), &TlsServer::StaticOnFdEvent, this);
-        if (fd_event_ == nullptr) {
-            LOG(ERROR) << "Failed to create fd event for TlsServer.";
-            callback(false);
-            return;
-        }
-        callback(true);
-    });
-
-    cv.wait(lock, [&]() { return success.has_value(); });
-    if (!*success) {
-        LOG(INFO) << "TlsServer fdevent_create failed";
-        return false;
-    }
-    fdevent_set(fd_event_, FDE_READ);
-    LOG(INFO) << "TlsServer running on port " << port_;
-
-    return *success;
-}
-
-// static
-void TlsServer::StaticOnFdEvent(int fd, unsigned ev, void* opaque) {
-    auto server = reinterpret_cast<TlsServer*>(opaque);
-    server->OnFdEvent(fd, ev);
-}
-
-void TlsServer::OnFdEvent(int fd, unsigned ev) {
-    if ((ev & FDE_READ) == 0 || fd != fd_event_->fd.get()) {
-        LOG(INFO) << __func__ << ": No read [ev=" << ev << " fd=" << fd << "]";
-        return;
-    }
-
-    unique_fd new_fd(adb_socket_accept(fd, nullptr, nullptr));
-    if (new_fd >= 0) {
-        LOG(INFO) << "New TLS connection [fd=" << new_fd.get() << "]";
-        close_on_exec(new_fd.get());
-        disable_tcp_nagle(new_fd.get());
-        std::string serial = android::base::StringPrintf("host-%d", new_fd.get());
-        register_socket_transport(
-                std::move(new_fd), std::move(serial), port_, 1,
-                [](atransport*) { return ReconnectResult::Abort; }, true);
-    }
-}
-
-TlsServer* sTlsServer = nullptr;
-const char kWifiPortProp[] = "service.adb.tls.port";
-
-const char kWifiEnabledProp[] = "persist.adb.tls_server.enable";
-
-static void enable_wifi_debugging() {
-    start_mdnsd();
-
-    if (sTlsServer != nullptr) {
-        delete sTlsServer;
-    }
-    sTlsServer = new TlsServer(0);
-    if (!sTlsServer->Start()) {
-        LOG(ERROR) << "Failed to start TlsServer";
-        delete sTlsServer;
-        sTlsServer = nullptr;
-        return;
-    }
-
-    // Start mdns connect service for discovery
-    register_adb_secure_connect_service(sTlsServer->port());
-    LOG(INFO) << "adb wifi started on port " << sTlsServer->port();
-    SetProperty(kWifiPortProp, std::to_string(sTlsServer->port()));
-}
-
-static void disable_wifi_debugging() {
-    if (sTlsServer != nullptr) {
-        delete sTlsServer;
-        sTlsServer = nullptr;
-    }
-    if (is_adb_secure_connect_service_registered()) {
-        unregister_adb_secure_connect_service();
-    }
-    kick_all_tcp_tls_transports();
-    LOG(INFO) << "adb wifi stopped";
-    SetProperty(kWifiPortProp, "");
-}
-
-// Watches for the #kWifiEnabledProp property to toggle the TlsServer
-static void start_wifi_enabled_observer() {
-    std::thread([]() {
-        bool wifi_enabled = false;
-        while (true) {
-            std::string toggled_val = wifi_enabled ? "0" : "1";
-            LOG(INFO) << "Waiting for " << kWifiEnabledProp << "=" << toggled_val;
-            if (WaitForProperty(kWifiEnabledProp, toggled_val)) {
-                wifi_enabled = !wifi_enabled;
-                LOG(INFO) << kWifiEnabledProp << " changed to " << toggled_val;
-                if (wifi_enabled) {
-                    enable_wifi_debugging();
-                } else {
-                    disable_wifi_debugging();
-                }
-            }
-        }
-    }).detach();
-}
-#endif  //__ANDROID__
-
-}  // namespace
-
-void adbd_wifi_init(AdbdAuthContext* ctx) {
-    auth_ctx = ctx;
-#if defined(__ANDROID__)
-    start_wifi_enabled_observer();
-#endif  //__ANDROID__
-}
-
-void adbd_wifi_secure_connect(atransport* t) {
-    t->AddDisconnect(&adb_disconnect);
-    handle_online(t);
-    send_connect(t);
-    LOG(INFO) << __func__ << ": connected " << t->serial;
-    t->auth_id = adbd_auth_tls_device_connected(auth_ctx, kAdbTransportTypeWifi, t->auth_key.data(),
-                                                t->auth_key.size());
-}
-
-#endif /* !HOST */
diff --git a/adb/daemon/auth.cpp b/adb/daemon/auth.cpp
deleted file mode 100644
index 1a1e4ad..0000000
--- a/adb/daemon/auth.cpp
+++ /dev/null
@@ -1,382 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define TRACE_TAG AUTH
-
-#include "sysdeps.h"
-
-#include <resolv.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <algorithm>
-#include <chrono>
-#include <iomanip>
-#include <map>
-#include <memory>
-#include <thread>
-
-#include <adb/crypto/rsa_2048_key.h>
-#include <adb/tls/adb_ca_list.h>
-#include <adbd_auth.h>
-#include <android-base/file.h>
-#include <android-base/no_destructor.h>
-#include <android-base/strings.h>
-#include <crypto_utils/android_pubkey.h>
-#include <openssl/obj_mac.h>
-#include <openssl/rsa.h>
-#include <openssl/sha.h>
-#include <openssl/ssl.h>
-
-#include "adb.h"
-#include "adb_auth.h"
-#include "adb_io.h"
-#include "adb_wifi.h"
-#include "fdevent/fdevent.h"
-#include "transport.h"
-#include "types.h"
-
-using namespace adb::crypto;
-using namespace adb::tls;
-using namespace std::chrono_literals;
-
-static AdbdAuthContext* auth_ctx;
-
-static RSA* rsa_pkey = nullptr;
-
-static void adb_disconnected(void* unused, atransport* t);
-static struct adisconnect adb_disconnect = {adb_disconnected, nullptr};
-
-static android::base::NoDestructor<std::map<uint32_t, weak_ptr<atransport>>> transports;
-static uint32_t transport_auth_id = 0;
-
-bool auth_required = true;
-
-static void* transport_to_callback_arg(atransport* transport) {
-    uint32_t id = transport_auth_id++;
-    (*transports)[id] = transport->weak();
-    return reinterpret_cast<void*>(id);
-}
-
-static atransport* transport_from_callback_arg(void* id) {
-    uint64_t id_u64 = reinterpret_cast<uint64_t>(id);
-    if (id_u64 > std::numeric_limits<uint32_t>::max()) {
-        LOG(FATAL) << "transport_from_callback_arg called on out of range value: " << id_u64;
-    }
-
-    uint32_t id_u32 = static_cast<uint32_t>(id_u64);
-    auto it = transports->find(id_u32);
-    if (it == transports->end()) {
-        LOG(ERROR) << "transport_from_callback_arg failed to find transport for id " << id_u32;
-        return nullptr;
-    }
-
-    atransport* t = it->second.get();
-    if (!t) {
-        LOG(WARNING) << "transport_from_callback_arg found already destructed transport";
-        return nullptr;
-    }
-
-    transports->erase(it);
-    return t;
-}
-
-static void IteratePublicKeys(std::function<bool(std::string_view public_key)> f) {
-    adbd_auth_get_public_keys(
-            auth_ctx,
-            [](void* opaque, const char* public_key, size_t len) {
-                return (*static_cast<decltype(f)*>(opaque))(std::string_view(public_key, len));
-            },
-            &f);
-}
-
-bssl::UniquePtr<STACK_OF(X509_NAME)> adbd_tls_client_ca_list() {
-    if (!auth_required) {
-        return nullptr;
-    }
-
-    bssl::UniquePtr<STACK_OF(X509_NAME)> ca_list(sk_X509_NAME_new_null());
-
-    IteratePublicKeys([&](std::string_view public_key) {
-        // TODO: do we really have to support both ' ' and '\t'?
-        std::vector<std::string> split = android::base::Split(std::string(public_key), " \t");
-        uint8_t keybuf[ANDROID_PUBKEY_ENCODED_SIZE + 1];
-        const std::string& pubkey = split[0];
-        if (b64_pton(pubkey.c_str(), keybuf, sizeof(keybuf)) != ANDROID_PUBKEY_ENCODED_SIZE) {
-            LOG(ERROR) << "Invalid base64 key " << pubkey;
-            return true;
-        }
-
-        RSA* key = nullptr;
-        if (!android_pubkey_decode(keybuf, ANDROID_PUBKEY_ENCODED_SIZE, &key)) {
-            LOG(ERROR) << "Failed to parse key " << pubkey;
-            return true;
-        }
-        bssl::UniquePtr<RSA> rsa_key(key);
-
-        unsigned char* dkey = nullptr;
-        int len = i2d_RSA_PUBKEY(rsa_key.get(), &dkey);
-        if (len <= 0 || dkey == nullptr) {
-            LOG(ERROR) << "Failed to encode RSA public key";
-            return true;
-        }
-
-        uint8_t digest[SHA256_DIGEST_LENGTH];
-        // Put the encoded key in the commonName attribute of the issuer name.
-        // Note that the commonName has a max length of 64 bytes, which is less
-        // than the SHA256_DIGEST_LENGTH.
-        SHA256(dkey, len, digest);
-        OPENSSL_free(dkey);
-
-        auto digest_str = SHA256BitsToHexString(
-                std::string_view(reinterpret_cast<const char*>(&digest[0]), sizeof(digest)));
-        LOG(INFO) << "fingerprint=[" << digest_str << "]";
-        auto issuer = CreateCAIssuerFromEncodedKey(digest_str);
-        CHECK(bssl::PushToStack(ca_list.get(), std::move(issuer)));
-        return true;
-    });
-
-    return ca_list;
-}
-
-bool adbd_auth_verify(const char* token, size_t token_size, const std::string& sig,
-                      std::string* auth_key) {
-    bool authorized = false;
-    auth_key->clear();
-
-    IteratePublicKeys([&](std::string_view public_key) {
-        // TODO: do we really have to support both ' ' and '\t'?
-        std::vector<std::string> split = android::base::Split(std::string(public_key), " \t");
-        uint8_t keybuf[ANDROID_PUBKEY_ENCODED_SIZE + 1];
-        const std::string& pubkey = split[0];
-        if (b64_pton(pubkey.c_str(), keybuf, sizeof(keybuf)) != ANDROID_PUBKEY_ENCODED_SIZE) {
-            LOG(ERROR) << "Invalid base64 key " << pubkey;
-            return true;
-        }
-
-        RSA* key = nullptr;
-        if (!android_pubkey_decode(keybuf, ANDROID_PUBKEY_ENCODED_SIZE, &key)) {
-            LOG(ERROR) << "Failed to parse key " << pubkey;
-            return true;
-        }
-
-        bool verified =
-                (RSA_verify(NID_sha1, reinterpret_cast<const uint8_t*>(token), token_size,
-                            reinterpret_cast<const uint8_t*>(sig.c_str()), sig.size(), key) == 1);
-        RSA_free(key);
-        if (verified) {
-            *auth_key = public_key;
-            authorized = true;
-            return false;
-        }
-
-        return true;
-    });
-
-    return authorized;
-}
-
-static bool adbd_auth_generate_token(void* token, size_t token_size) {
-    FILE* fp = fopen("/dev/urandom", "re");
-    if (!fp) return false;
-    bool okay = (fread(token, token_size, 1, fp) == 1);
-    fclose(fp);
-    return okay;
-}
-
-void adbd_cloexec_auth_socket() {
-    int fd = android_get_control_socket("adbd");
-    if (fd == -1) {
-        PLOG(ERROR) << "Failed to get adbd socket";
-        return;
-    }
-    fcntl(fd, F_SETFD, FD_CLOEXEC);
-}
-
-static void adbd_auth_key_authorized(void* arg, uint64_t id) {
-    LOG(INFO) << "adb client " << id << " authorized";
-    fdevent_run_on_main_thread([=]() {
-        auto* transport = transport_from_callback_arg(arg);
-        if (!transport) {
-            LOG(ERROR) << "authorization received for deleted transport (" << id << "), ignoring";
-            return;
-        }
-
-        if (transport->auth_id.has_value()) {
-            if (transport->auth_id.value() != id) {
-                LOG(ERROR)
-                        << "authorization received, but auth id doesn't match, ignoring (expected "
-                        << transport->auth_id.value() << ", got " << id << ")";
-                return;
-            }
-        } else {
-            // Older versions (i.e. dogfood/beta builds) of libadbd_auth didn't pass the initial
-            // auth id to us, so we'll just have to trust it until R ships and we can retcon this.
-            transport->auth_id = id;
-        }
-
-        adbd_auth_verified(transport);
-    });
-}
-
-static void adbd_key_removed(const char* public_key, size_t len) {
-    // The framework removed the key from its keystore. We need to disconnect all
-    // devices using that key. Search by t->auth_key
-    std::string_view auth_key(public_key, len);
-    kick_all_transports_by_auth_key(auth_key);
-}
-
-void adbd_auth_init(void) {
-    AdbdAuthCallbacksV1 cb;
-    cb.version = 1;
-    cb.key_authorized = adbd_auth_key_authorized;
-    cb.key_removed = adbd_key_removed;
-    auth_ctx = adbd_auth_new(&cb);
-    adbd_wifi_init(auth_ctx);
-    std::thread([]() {
-        adb_thread_setname("adbd auth");
-        adbd_auth_run(auth_ctx);
-        LOG(FATAL) << "auth thread terminated";
-    }).detach();
-}
-
-void send_auth_request(atransport* t) {
-    LOG(INFO) << "Calling send_auth_request...";
-
-    if (!adbd_auth_generate_token(t->token, sizeof(t->token))) {
-        PLOG(ERROR) << "Error generating token";
-        return;
-    }
-
-    apacket* p = get_apacket();
-    p->msg.command = A_AUTH;
-    p->msg.arg0 = ADB_AUTH_TOKEN;
-    p->msg.data_length = sizeof(t->token);
-    p->payload.assign(t->token, t->token + sizeof(t->token));
-    send_packet(p, t);
-}
-
-void adbd_auth_verified(atransport* t) {
-    LOG(INFO) << "adb client authorized";
-    handle_online(t);
-    send_connect(t);
-}
-
-static void adb_disconnected(void* unused, atransport* t) {
-    LOG(INFO) << "ADB disconnect";
-    CHECK(t->auth_id.has_value());
-    adbd_auth_notify_disconnect(auth_ctx, t->auth_id.value());
-}
-
-void adbd_auth_confirm_key(atransport* t) {
-    LOG(INFO) << "prompting user to authorize key";
-    t->AddDisconnect(&adb_disconnect);
-    if (adbd_auth_prompt_user_with_id) {
-        t->auth_id = adbd_auth_prompt_user_with_id(auth_ctx, t->auth_key.data(), t->auth_key.size(),
-                                                   transport_to_callback_arg(t));
-    } else {
-        adbd_auth_prompt_user(auth_ctx, t->auth_key.data(), t->auth_key.size(),
-                              transport_to_callback_arg(t));
-    }
-}
-
-void adbd_notify_framework_connected_key(atransport* t) {
-    t->auth_id = adbd_auth_notify_auth(auth_ctx, t->auth_key.data(), t->auth_key.size());
-}
-
-int adbd_tls_verify_cert(X509_STORE_CTX* ctx, std::string* auth_key) {
-    if (!auth_required) {
-        // Any key will do.
-        LOG(INFO) << __func__ << ": auth not required";
-        return 1;
-    }
-
-    bool authorized = false;
-    X509* cert = X509_STORE_CTX_get0_cert(ctx);
-    if (cert == nullptr) {
-        LOG(INFO) << "got null x509 certificate";
-        return 0;
-    }
-    bssl::UniquePtr<EVP_PKEY> evp_pkey(X509_get_pubkey(cert));
-    if (evp_pkey == nullptr) {
-        LOG(INFO) << "got null evp_pkey from x509 certificate";
-        return 0;
-    }
-
-    IteratePublicKeys([&](std::string_view public_key) {
-        // TODO: do we really have to support both ' ' and '\t'?
-        std::vector<std::string> split = android::base::Split(std::string(public_key), " \t");
-        uint8_t keybuf[ANDROID_PUBKEY_ENCODED_SIZE + 1];
-        const std::string& pubkey = split[0];
-        if (b64_pton(pubkey.c_str(), keybuf, sizeof(keybuf)) != ANDROID_PUBKEY_ENCODED_SIZE) {
-            LOG(ERROR) << "Invalid base64 key " << pubkey;
-            return true;
-        }
-
-        RSA* key = nullptr;
-        if (!android_pubkey_decode(keybuf, ANDROID_PUBKEY_ENCODED_SIZE, &key)) {
-            LOG(ERROR) << "Failed to parse key " << pubkey;
-            return true;
-        }
-
-        bool verified = false;
-        bssl::UniquePtr<EVP_PKEY> known_evp(EVP_PKEY_new());
-        EVP_PKEY_set1_RSA(known_evp.get(), key);
-        if (EVP_PKEY_cmp(known_evp.get(), evp_pkey.get())) {
-            LOG(INFO) << "Matched auth_key=" << public_key;
-            verified = true;
-        } else {
-            LOG(INFO) << "auth_key doesn't match [" << public_key << "]";
-        }
-        RSA_free(key);
-        if (verified) {
-            *auth_key = public_key;
-            authorized = true;
-            return false;
-        }
-
-        return true;
-    });
-
-    return authorized ? 1 : 0;
-}
-
-void adbd_auth_tls_handshake(atransport* t) {
-    if (rsa_pkey == nullptr) {
-        // Generate a random RSA key to feed into the X509 certificate
-        auto rsa_2048 = CreateRSA2048Key();
-        CHECK(rsa_2048.has_value());
-        rsa_pkey = EVP_PKEY_get1_RSA(rsa_2048->GetEvpPkey());
-        CHECK(rsa_pkey);
-    }
-
-    std::thread([t]() {
-        std::string auth_key;
-        if (t->connection()->DoTlsHandshake(rsa_pkey, &auth_key)) {
-            LOG(INFO) << "auth_key=" << auth_key;
-            if (t->IsTcpDevice()) {
-                t->auth_key = auth_key;
-                adbd_wifi_secure_connect(t);
-            } else {
-                adbd_auth_verified(t);
-                adbd_notify_framework_connected_key(t);
-            }
-        } else {
-            // Only allow one attempt at the handshake.
-            t->Kick();
-        }
-    }).detach();
-}
diff --git a/adb/daemon/file_sync_service.cpp b/adb/daemon/file_sync_service.cpp
deleted file mode 100644
index 07f6e65..0000000
--- a/adb/daemon/file_sync_service.cpp
+++ /dev/null
@@ -1,816 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define TRACE_TAG SYNC
-
-#include "daemon/file_sync_service.h"
-
-#include "sysdeps.h"
-
-#include <dirent.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <utime.h>
-
-#include <memory>
-#include <optional>
-#include <span>
-#include <string>
-#include <vector>
-
-#include <android-base/file.h>
-#include <android-base/macros.h>
-#include <android-base/stringprintf.h>
-#include <android-base/strings.h>
-
-#include <adbd_fs.h>
-
-// Needed for __android_log_security_bswrite.
-#include <private/android_logger.h>
-
-#if defined(__ANDROID__)
-#include <linux/capability.h>
-#include <selinux/android.h>
-#include <sys/xattr.h>
-#endif
-
-#include "adb.h"
-#include "adb_io.h"
-#include "adb_trace.h"
-#include "adb_utils.h"
-#include "brotli_utils.h"
-#include "file_sync_protocol.h"
-#include "security_log_tags.h"
-#include "sysdeps/errno.h"
-
-using android::base::borrowed_fd;
-using android::base::Dirname;
-using android::base::StringPrintf;
-
-static bool should_use_fs_config(const std::string& path) {
-#if defined(__ANDROID__)
-    // TODO: use fs_config to configure permissions on /data too.
-    return !android::base::StartsWith(path, "/data/");
-#else
-    UNUSED(path);
-    return false;
-#endif
-}
-
-static bool update_capabilities(const char* path, uint64_t capabilities) {
-#if defined(__ANDROID__)
-    if (capabilities == 0) {
-        // Ensure we clean up in case the capabilities weren't 0 in the past.
-        removexattr(path, XATTR_NAME_CAPS);
-        return true;
-    }
-
-    vfs_cap_data cap_data = {};
-    cap_data.magic_etc = VFS_CAP_REVISION_2 | VFS_CAP_FLAGS_EFFECTIVE;
-    cap_data.data[0].permitted = (capabilities & 0xffffffff);
-    cap_data.data[0].inheritable = 0;
-    cap_data.data[1].permitted = (capabilities >> 32);
-    cap_data.data[1].inheritable = 0;
-    return setxattr(path, XATTR_NAME_CAPS, &cap_data, sizeof(cap_data), 0) != -1;
-#else
-    UNUSED(path, capabilities);
-    return true;
-#endif
-}
-
-static bool secure_mkdirs(const std::string& path) {
-    if (path[0] != '/') return false;
-
-    std::vector<std::string> path_components = android::base::Split(path, "/");
-    std::string partial_path;
-    for (const auto& path_component : path_components) {
-        uid_t uid = -1;
-        gid_t gid = -1;
-        mode_t mode = 0775;
-        uint64_t capabilities = 0;
-
-        if (path_component.empty()) {
-            continue;
-        }
-
-        if (partial_path.empty() || partial_path.back() != OS_PATH_SEPARATOR) {
-            partial_path += OS_PATH_SEPARATOR;
-        }
-        partial_path += path_component;
-
-        if (should_use_fs_config(partial_path)) {
-            adbd_fs_config(partial_path.c_str(), 1, nullptr, &uid, &gid, &mode, &capabilities);
-        }
-        if (adb_mkdir(partial_path.c_str(), mode) == -1) {
-            if (errno != EEXIST) {
-                return false;
-            }
-        } else {
-            if (chown(partial_path.c_str(), uid, gid) == -1) return false;
-
-#if defined(__ANDROID__)
-            // Not all filesystems support setting SELinux labels. http://b/23530370.
-            selinux_android_restorecon(partial_path.c_str(), 0);
-#endif
-
-            if (!update_capabilities(partial_path.c_str(), capabilities)) return false;
-        }
-    }
-    return true;
-}
-
-static bool do_lstat_v1(int s, const char* path) {
-    syncmsg msg = {};
-    msg.stat_v1.id = ID_LSTAT_V1;
-
-    struct stat st = {};
-    lstat(path, &st);
-    msg.stat_v1.mode = st.st_mode;
-    msg.stat_v1.size = st.st_size;
-    msg.stat_v1.mtime = st.st_mtime;
-    return WriteFdExactly(s, &msg.stat_v1, sizeof(msg.stat_v1));
-}
-
-static bool do_stat_v2(int s, uint32_t id, const char* path) {
-    syncmsg msg = {};
-    msg.stat_v2.id = id;
-
-    decltype(&stat) stat_fn;
-    if (id == ID_STAT_V2) {
-        stat_fn = stat;
-    } else {
-        stat_fn = lstat;
-    }
-
-    struct stat st = {};
-    int rc = stat_fn(path, &st);
-    if (rc == -1) {
-        msg.stat_v2.error = errno_to_wire(errno);
-    } else {
-        msg.stat_v2.dev = st.st_dev;
-        msg.stat_v2.ino = st.st_ino;
-        msg.stat_v2.mode = st.st_mode;
-        msg.stat_v2.nlink = st.st_nlink;
-        msg.stat_v2.uid = st.st_uid;
-        msg.stat_v2.gid = st.st_gid;
-        msg.stat_v2.size = st.st_size;
-        msg.stat_v2.atime = st.st_atime;
-        msg.stat_v2.mtime = st.st_mtime;
-        msg.stat_v2.ctime = st.st_ctime;
-    }
-
-    return WriteFdExactly(s, &msg.stat_v2, sizeof(msg.stat_v2));
-}
-
-template <bool v2>
-static bool do_list(int s, const char* path) {
-    dirent* de;
-
-    using MessageType =
-            std::conditional_t<v2, decltype(syncmsg::dent_v2), decltype(syncmsg::dent_v1)>;
-    MessageType msg;
-    uint32_t msg_id;
-    if constexpr (v2) {
-        msg_id = ID_DENT_V2;
-    } else {
-        msg_id = ID_DENT_V1;
-    }
-
-    std::unique_ptr<DIR, int(*)(DIR*)> d(opendir(path), closedir);
-    if (!d) goto done;
-
-    while ((de = readdir(d.get()))) {
-        memset(&msg, 0, sizeof(msg));
-        msg.id = msg_id;
-
-        std::string filename(StringPrintf("%s/%s", path, de->d_name));
-
-        struct stat st;
-        if (lstat(filename.c_str(), &st) == 0) {
-            msg.mode = st.st_mode;
-            msg.size = st.st_size;
-            msg.mtime = st.st_mtime;
-
-            if constexpr (v2) {
-                msg.dev = st.st_dev;
-                msg.ino = st.st_ino;
-                msg.nlink = st.st_nlink;
-                msg.uid = st.st_uid;
-                msg.gid = st.st_gid;
-                msg.atime = st.st_atime;
-                msg.ctime = st.st_ctime;
-            }
-        } else {
-            if constexpr (v2) {
-                msg.error = errno;
-            } else {
-                continue;
-            }
-        }
-
-        size_t d_name_length = strlen(de->d_name);
-        msg.namelen = d_name_length;
-
-        if (!WriteFdExactly(s, &msg, sizeof(msg)) ||
-            !WriteFdExactly(s, de->d_name, d_name_length)) {
-            return false;
-        }
-    }
-
-done:
-    memset(&msg, 0, sizeof(msg));
-    msg.id = ID_DONE;
-    return WriteFdExactly(s, &msg, sizeof(msg));
-}
-
-static bool do_list_v1(int s, const char* path) {
-    return do_list<false>(s, path);
-}
-
-static bool do_list_v2(int s, const char* path) {
-    return do_list<true>(s, path);
-}
-
-// Make sure that SendFail from adb_io.cpp isn't accidentally used in this file.
-#pragma GCC poison SendFail
-
-static bool SendSyncFail(borrowed_fd fd, const std::string& reason) {
-    D("sync: failure: %s", reason.c_str());
-
-    syncmsg msg;
-    msg.data.id = ID_FAIL;
-    msg.data.size = reason.size();
-    return WriteFdExactly(fd, &msg.data, sizeof(msg.data)) && WriteFdExactly(fd, reason);
-}
-
-static bool SendSyncFailErrno(borrowed_fd fd, const std::string& reason) {
-    return SendSyncFail(fd, StringPrintf("%s: %s", reason.c_str(), strerror(errno)));
-}
-
-static bool handle_send_file_compressed(borrowed_fd s, unique_fd fd, uint32_t* timestamp) {
-    syncmsg msg;
-    Block decode_buffer(SYNC_DATA_MAX);
-    BrotliDecoder decoder(std::span(decode_buffer.data(), decode_buffer.size()));
-    while (true) {
-        if (!ReadFdExactly(s, &msg.data, sizeof(msg.data))) return false;
-
-        if (msg.data.id != ID_DATA) {
-            if (msg.data.id == ID_DONE) {
-                *timestamp = msg.data.size;
-                return true;
-            }
-            SendSyncFail(s, "invalid data message");
-            return false;
-        }
-
-        Block block(msg.data.size);
-        if (!ReadFdExactly(s, block.data(), msg.data.size)) return false;
-        decoder.Append(std::move(block));
-
-        while (true) {
-            std::span<char> output;
-            BrotliDecodeResult result = decoder.Decode(&output);
-            if (result == BrotliDecodeResult::Error) {
-                SendSyncFailErrno(s, "decompress failed");
-                return false;
-            }
-
-            if (!WriteFdExactly(fd, output.data(), output.size())) {
-                SendSyncFailErrno(s, "write failed");
-                return false;
-            }
-
-            if (result == BrotliDecodeResult::NeedInput) {
-                break;
-            } else if (result == BrotliDecodeResult::MoreOutput) {
-                continue;
-            } else if (result == BrotliDecodeResult::Done) {
-                break;
-            } else {
-                LOG(FATAL) << "invalid BrotliDecodeResult: " << static_cast<int>(result);
-            }
-        }
-    }
-
-    __builtin_unreachable();
-}
-
-static bool handle_send_file_uncompressed(borrowed_fd s, unique_fd fd, uint32_t* timestamp,
-                                          std::vector<char>& buffer) {
-    syncmsg msg;
-
-    while (true) {
-        if (!ReadFdExactly(s, &msg.data, sizeof(msg.data))) return false;
-
-        if (msg.data.id != ID_DATA) {
-            if (msg.data.id == ID_DONE) {
-                *timestamp = msg.data.size;
-                return true;
-            }
-            SendSyncFail(s, "invalid data message");
-            return false;
-        }
-
-        if (msg.data.size > buffer.size()) {  // TODO: resize buffer?
-            SendSyncFail(s, "oversize data message");
-            return false;
-        }
-        if (!ReadFdExactly(s, &buffer[0], msg.data.size)) return false;
-        if (!WriteFdExactly(fd, &buffer[0], msg.data.size)) {
-            SendSyncFailErrno(s, "write failed");
-            return false;
-        }
-    }
-}
-
-static bool handle_send_file(borrowed_fd s, const char* path, uint32_t* timestamp, uid_t uid,
-                             gid_t gid, uint64_t capabilities, mode_t mode, bool compressed,
-                             std::vector<char>& buffer, bool do_unlink) {
-    int rc;
-    syncmsg msg;
-
-    __android_log_security_bswrite(SEC_TAG_ADB_SEND_FILE, path);
-
-    unique_fd fd(adb_open_mode(path, O_WRONLY | O_CREAT | O_EXCL | O_CLOEXEC, mode));
-
-    if (fd < 0 && errno == ENOENT) {
-        if (!secure_mkdirs(Dirname(path))) {
-            SendSyncFailErrno(s, "secure_mkdirs failed");
-            goto fail;
-        }
-        fd.reset(adb_open_mode(path, O_WRONLY | O_CREAT | O_EXCL | O_CLOEXEC, mode));
-    }
-    if (fd < 0 && errno == EEXIST) {
-        fd.reset(adb_open_mode(path, O_WRONLY | O_CLOEXEC, mode));
-    }
-    if (fd < 0) {
-        SendSyncFailErrno(s, "couldn't create file");
-        goto fail;
-    } else {
-        if (fchown(fd.get(), uid, gid) == -1) {
-            SendSyncFailErrno(s, "fchown failed");
-            goto fail;
-        }
-
-#if defined(__ANDROID__)
-        // Not all filesystems support setting SELinux labels. http://b/23530370.
-        selinux_android_restorecon(path, 0);
-#endif
-
-        // fchown clears the setuid bit - restore it if present.
-        // Ignore the result of calling fchmod. It's not supported
-        // by all filesystems, so we don't check for success. b/12441485
-        fchmod(fd.get(), mode);
-    }
-
-    {
-        rc = posix_fadvise(fd.get(), 0, 0,
-                           POSIX_FADV_SEQUENTIAL | POSIX_FADV_NOREUSE | POSIX_FADV_WILLNEED);
-        if (rc != 0) {
-            D("[ Failed to fadvise: %s ]", strerror(rc));
-        }
-
-        bool result;
-        if (compressed) {
-            result = handle_send_file_compressed(s, std::move(fd), timestamp);
-        } else {
-            result = handle_send_file_uncompressed(s, std::move(fd), timestamp, buffer);
-        }
-
-        if (!result) {
-            goto fail;
-        }
-
-        if (!update_capabilities(path, capabilities)) {
-            SendSyncFailErrno(s, "update_capabilities failed");
-            goto fail;
-        }
-
-        msg.status.id = ID_OKAY;
-        msg.status.msglen = 0;
-        return WriteFdExactly(s, &msg.status, sizeof(msg.status));
-    }
-
-fail:
-    // If there's a problem on the device, we'll send an ID_FAIL message and
-    // close the socket. Unfortunately the kernel will sometimes throw that
-    // data away if the other end keeps writing without reading (which is
-    // the case with old versions of adb). To maintain compatibility, keep
-    // reading and throwing away ID_DATA packets until the other side notices
-    // that we've reported an error.
-    while (true) {
-        if (!ReadFdExactly(s, &msg.data, sizeof(msg.data))) break;
-
-        if (msg.data.id == ID_DONE) {
-            break;
-        } else if (msg.data.id != ID_DATA) {
-            char id[5];
-            memcpy(id, &msg.data.id, sizeof(msg.data.id));
-            id[4] = '\0';
-            D("handle_send_fail received unexpected id '%s' during failure", id);
-            break;
-        }
-
-        if (msg.data.size > buffer.size()) {
-            D("handle_send_fail received oversized packet of length '%u' during failure",
-              msg.data.size);
-            break;
-        }
-
-        if (!ReadFdExactly(s, &buffer[0], msg.data.size)) break;
-    }
-
-    if (do_unlink) adb_unlink(path);
-    return false;
-}
-
-#if defined(_WIN32)
-extern bool handle_send_link(int s, const std::string& path,
-                             uint32_t* timestamp, std::vector<char>& buffer)
-        __attribute__((error("no symlinks on Windows")));
-#else
-static bool handle_send_link(int s, const std::string& path, uint32_t* timestamp,
-                             std::vector<char>& buffer) {
-    syncmsg msg;
-
-    if (!ReadFdExactly(s, &msg.data, sizeof(msg.data))) return false;
-
-    if (msg.data.id != ID_DATA) {
-        SendSyncFail(s, "invalid data message: expected ID_DATA");
-        return false;
-    }
-
-    unsigned int len = msg.data.size;
-    if (len > buffer.size()) { // TODO: resize buffer?
-        SendSyncFail(s, "oversize data message");
-        return false;
-    }
-    if (!ReadFdExactly(s, &buffer[0], len)) return false;
-
-    std::string buf_link;
-    if (!android::base::Readlink(path, &buf_link) || (buf_link != &buffer[0])) {
-        adb_unlink(path.c_str());
-        auto ret = symlink(&buffer[0], path.c_str());
-        if (ret && errno == ENOENT) {
-            if (!secure_mkdirs(Dirname(path))) {
-                SendSyncFailErrno(s, "secure_mkdirs failed");
-                return false;
-            }
-            ret = symlink(&buffer[0], path.c_str());
-        }
-        if (ret) {
-            SendSyncFailErrno(s, "symlink failed");
-            return false;
-        }
-    }
-
-    if (!ReadFdExactly(s, &msg.data, sizeof(msg.data))) return false;
-
-    if (msg.data.id == ID_DONE) {
-        *timestamp = msg.data.size;
-        msg.status.id = ID_OKAY;
-        msg.status.msglen = 0;
-        if (!WriteFdExactly(s, &msg.status, sizeof(msg.status))) return false;
-    } else {
-        SendSyncFail(s, "invalid data message: expected ID_DONE");
-        return false;
-    }
-
-    return true;
-}
-#endif
-
-static bool send_impl(int s, const std::string& path, mode_t mode, bool compressed,
-                      std::vector<char>& buffer) {
-    // Don't delete files before copying if they are not "regular" or symlinks.
-    struct stat st;
-    bool do_unlink = (lstat(path.c_str(), &st) == -1) || S_ISREG(st.st_mode) ||
-                     (S_ISLNK(st.st_mode) && !S_ISLNK(mode));
-    if (do_unlink) {
-        adb_unlink(path.c_str());
-    }
-
-    bool result;
-    uint32_t timestamp;
-    if (S_ISLNK(mode)) {
-        result = handle_send_link(s, path, &timestamp, buffer);
-    } else {
-        // Copy user permission bits to "group" and "other" permissions.
-        mode &= 0777;
-        mode |= ((mode >> 3) & 0070);
-        mode |= ((mode >> 3) & 0007);
-
-        uid_t uid = -1;
-        gid_t gid = -1;
-        uint64_t capabilities = 0;
-        if (should_use_fs_config(path)) {
-            adbd_fs_config(path.c_str(), 0, nullptr, &uid, &gid, &mode, &capabilities);
-        }
-
-        result = handle_send_file(s, path.c_str(), &timestamp, uid, gid, capabilities, mode,
-                                  compressed, buffer, do_unlink);
-    }
-
-    if (!result) {
-      return false;
-    }
-
-    struct timeval tv[2];
-    tv[0].tv_sec = timestamp;
-    tv[0].tv_usec = 0;
-    tv[1].tv_sec = timestamp;
-    tv[1].tv_usec = 0;
-    lutimes(path.c_str(), tv);
-    return true;
-}
-
-static bool do_send_v1(int s, const std::string& spec, std::vector<char>& buffer) {
-    // 'spec' is of the form "/some/path,0755". Break it up.
-    size_t comma = spec.find_last_of(',');
-    if (comma == std::string::npos) {
-        SendSyncFail(s, "missing , in ID_SEND_V1");
-        return false;
-    }
-
-    std::string path = spec.substr(0, comma);
-
-    errno = 0;
-    mode_t mode = strtoul(spec.substr(comma + 1).c_str(), nullptr, 0);
-    if (errno != 0) {
-        SendSyncFail(s, "bad mode");
-        return false;
-    }
-
-    return send_impl(s, path, mode, false, buffer);
-}
-
-static bool do_send_v2(int s, const std::string& path, std::vector<char>& buffer) {
-    // Read the setup packet.
-    syncmsg msg;
-    int rc = ReadFdExactly(s, &msg.send_v2_setup, sizeof(msg.send_v2_setup));
-    if (rc == 0) {
-        LOG(ERROR) << "failed to read send_v2 setup packet: EOF";
-        return false;
-    } else if (rc < 0) {
-        PLOG(ERROR) << "failed to read send_v2 setup packet";
-    }
-
-    bool compressed = false;
-    if (msg.send_v2_setup.flags & kSyncFlagBrotli) {
-        msg.send_v2_setup.flags &= ~kSyncFlagBrotli;
-        compressed = true;
-    }
-    if (msg.send_v2_setup.flags) {
-        SendSyncFail(s, android::base::StringPrintf("unknown flags: %d", msg.send_v2_setup.flags));
-        return false;
-    }
-
-    errno = 0;
-    return send_impl(s, path, msg.send_v2_setup.mode, compressed, buffer);
-}
-
-static bool recv_uncompressed(borrowed_fd s, unique_fd fd, std::vector<char>& buffer) {
-    syncmsg msg;
-    msg.data.id = ID_DATA;
-    std::optional<BrotliEncoder<SYNC_DATA_MAX>> encoder;
-    while (true) {
-        int r = adb_read(fd.get(), &buffer[0], buffer.size() - sizeof(msg.data));
-        if (r <= 0) {
-            if (r == 0) break;
-            SendSyncFailErrno(s, "read failed");
-            return false;
-        }
-        msg.data.size = r;
-
-        if (!WriteFdExactly(s, &msg.data, sizeof(msg.data)) || !WriteFdExactly(s, &buffer[0], r)) {
-            return false;
-        }
-    }
-
-    return true;
-}
-
-static bool recv_compressed(borrowed_fd s, unique_fd fd) {
-    syncmsg msg;
-    msg.data.id = ID_DATA;
-
-    BrotliEncoder<SYNC_DATA_MAX> encoder;
-
-    bool sending = true;
-    while (sending) {
-        Block input(SYNC_DATA_MAX);
-        int r = adb_read(fd.get(), input.data(), input.size());
-        if (r < 0) {
-            SendSyncFailErrno(s, "read failed");
-            return false;
-        }
-
-        if (r == 0) {
-            encoder.Finish();
-        } else {
-            input.resize(r);
-            encoder.Append(std::move(input));
-        }
-
-        while (true) {
-            Block output;
-            BrotliEncodeResult result = encoder.Encode(&output);
-            if (result == BrotliEncodeResult::Error) {
-                SendSyncFailErrno(s, "compress failed");
-                return false;
-            }
-
-            if (!output.empty()) {
-                msg.data.size = output.size();
-                if (!WriteFdExactly(s, &msg.data, sizeof(msg.data)) ||
-                    !WriteFdExactly(s, output.data(), output.size())) {
-                    return false;
-                }
-            }
-
-            if (result == BrotliEncodeResult::Done) {
-                sending = false;
-                break;
-            } else if (result == BrotliEncodeResult::NeedInput) {
-                break;
-            } else if (result == BrotliEncodeResult::MoreOutput) {
-                continue;
-            }
-        }
-    }
-
-    return true;
-}
-
-static bool recv_impl(borrowed_fd s, const char* path, bool compressed, std::vector<char>& buffer) {
-    __android_log_security_bswrite(SEC_TAG_ADB_RECV_FILE, path);
-
-    unique_fd fd(adb_open(path, O_RDONLY | O_CLOEXEC));
-    if (fd < 0) {
-        SendSyncFailErrno(s, "open failed");
-        return false;
-    }
-
-    int rc = posix_fadvise(fd.get(), 0, 0, POSIX_FADV_SEQUENTIAL | POSIX_FADV_NOREUSE);
-    if (rc != 0) {
-        D("[ Failed to fadvise: %s ]", strerror(rc));
-    }
-
-    bool result;
-    if (compressed) {
-        result = recv_compressed(s, std::move(fd));
-    } else {
-        result = recv_uncompressed(s, std::move(fd), buffer);
-    }
-
-    if (!result) {
-        return false;
-    }
-
-    syncmsg msg;
-    msg.data.id = ID_DONE;
-    msg.data.size = 0;
-    return WriteFdExactly(s, &msg.data, sizeof(msg.data));
-}
-
-static bool do_recv_v1(borrowed_fd s, const char* path, std::vector<char>& buffer) {
-    return recv_impl(s, path, false, buffer);
-}
-
-static bool do_recv_v2(borrowed_fd s, const char* path, std::vector<char>& buffer) {
-    syncmsg msg;
-    // Read the setup packet.
-    int rc = ReadFdExactly(s, &msg.recv_v2_setup, sizeof(msg.recv_v2_setup));
-    if (rc == 0) {
-        LOG(ERROR) << "failed to read recv_v2 setup packet: EOF";
-        return false;
-    } else if (rc < 0) {
-        PLOG(ERROR) << "failed to read recv_v2 setup packet";
-    }
-
-    bool compressed = false;
-    if (msg.recv_v2_setup.flags & kSyncFlagBrotli) {
-        msg.recv_v2_setup.flags &= ~kSyncFlagBrotli;
-        compressed = true;
-    }
-    if (msg.recv_v2_setup.flags) {
-        SendSyncFail(s, android::base::StringPrintf("unknown flags: %d", msg.recv_v2_setup.flags));
-        return false;
-    }
-
-    return recv_impl(s, path, compressed, buffer);
-}
-
-static const char* sync_id_to_name(uint32_t id) {
-  switch (id) {
-    case ID_LSTAT_V1:
-      return "lstat_v1";
-    case ID_LSTAT_V2:
-      return "lstat_v2";
-    case ID_STAT_V2:
-      return "stat_v2";
-    case ID_LIST_V1:
-      return "list_v1";
-    case ID_LIST_V2:
-      return "list_v2";
-    case ID_SEND_V1:
-        return "send_v1";
-    case ID_SEND_V2:
-        return "send_v2";
-    case ID_RECV_V1:
-        return "recv_v1";
-    case ID_RECV_V2:
-        return "recv_v2";
-    case ID_QUIT:
-        return "quit";
-    default:
-        return "???";
-  }
-}
-
-static bool handle_sync_command(int fd, std::vector<char>& buffer) {
-    D("sync: waiting for request");
-
-    SyncRequest request;
-    if (!ReadFdExactly(fd, &request, sizeof(request))) {
-        SendSyncFail(fd, "command read failure");
-        return false;
-    }
-    size_t path_length = request.path_length;
-    if (path_length > 1024) {
-        SendSyncFail(fd, "path too long");
-        return false;
-    }
-    char name[1025];
-    if (!ReadFdExactly(fd, name, path_length)) {
-        SendSyncFail(fd, "filename read failure");
-        return false;
-    }
-    name[path_length] = 0;
-
-    std::string id_name = sync_id_to_name(request.id);
-
-    D("sync: %s('%s')", id_name.c_str(), name);
-    switch (request.id) {
-        case ID_LSTAT_V1:
-            if (!do_lstat_v1(fd, name)) return false;
-            break;
-        case ID_LSTAT_V2:
-        case ID_STAT_V2:
-            if (!do_stat_v2(fd, request.id, name)) return false;
-            break;
-        case ID_LIST_V1:
-            if (!do_list_v1(fd, name)) return false;
-            break;
-        case ID_LIST_V2:
-            if (!do_list_v2(fd, name)) return false;
-            break;
-        case ID_SEND_V1:
-            if (!do_send_v1(fd, name, buffer)) return false;
-            break;
-        case ID_SEND_V2:
-            if (!do_send_v2(fd, name, buffer)) return false;
-            break;
-        case ID_RECV_V1:
-            if (!do_recv_v1(fd, name, buffer)) return false;
-            break;
-        case ID_RECV_V2:
-            if (!do_recv_v2(fd, name, buffer)) return false;
-            break;
-        case ID_QUIT:
-            return false;
-        default:
-            SendSyncFail(fd, StringPrintf("unknown command %08x", request.id));
-            return false;
-    }
-
-    return true;
-}
-
-void file_sync_service(unique_fd fd) {
-    std::vector<char> buffer(SYNC_DATA_MAX);
-
-    while (handle_sync_command(fd.get(), buffer)) {
-    }
-
-    D("sync: done");
-}
diff --git a/adb/daemon/file_sync_service.h b/adb/daemon/file_sync_service.h
deleted file mode 100644
index f300e7b..0000000
--- a/adb/daemon/file_sync_service.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "adb_unique_fd.h"
-
-void file_sync_service(unique_fd fd);
diff --git a/adb/daemon/framebuffer_service.cpp b/adb/daemon/framebuffer_service.cpp
deleted file mode 100644
index 676f8e9..0000000
--- a/adb/daemon/framebuffer_service.cpp
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "framebuffer_service.h"
-
-#include <errno.h>
-#include <fcntl.h>
-#include <linux/fb.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/ioctl.h>
-#include <sys/mman.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
-
-#include "sysdeps.h"
-
-#include "adb.h"
-#include "adb_io.h"
-#include "adb_utils.h"
-
-/* TODO:
-** - sync with vsync to avoid tearing
-*/
-/* This version number defines the format of the fbinfo struct.
-   It must match versioning in ddms where this data is consumed. */
-#define DDMS_RAWIMAGE_VERSION 2
-struct fbinfo {
-    unsigned int version;
-    unsigned int bpp;
-    unsigned int colorSpace;
-    unsigned int size;
-    unsigned int width;
-    unsigned int height;
-    unsigned int red_offset;
-    unsigned int red_length;
-    unsigned int blue_offset;
-    unsigned int blue_length;
-    unsigned int green_offset;
-    unsigned int green_length;
-    unsigned int alpha_offset;
-    unsigned int alpha_length;
-} __attribute__((packed));
-
-void framebuffer_service(unique_fd fd) {
-    struct fbinfo fbinfo;
-    unsigned int i, bsize;
-    char buf[640];
-    int fd_screencap;
-    int w, h, f, c;
-    int fds[2];
-    pid_t pid;
-
-    if (pipe2(fds, O_CLOEXEC) < 0) return;
-
-    pid = fork();
-    if (pid < 0) goto done;
-
-    if (pid == 0) {
-        dup2(fds[1], STDOUT_FILENO);
-        adb_close(fds[0]);
-        adb_close(fds[1]);
-        const char* command = "screencap";
-        const char *args[2] = {command, nullptr};
-        execvp(command, (char**)args);
-        perror_exit("exec screencap failed");
-    }
-
-    adb_close(fds[1]);
-    fd_screencap = fds[0];
-
-    /* read w, h, format & color space */
-    if(!ReadFdExactly(fd_screencap, &w, 4)) goto done;
-    if(!ReadFdExactly(fd_screencap, &h, 4)) goto done;
-    if(!ReadFdExactly(fd_screencap, &f, 4)) goto done;
-    if(!ReadFdExactly(fd_screencap, &c, 4)) goto done;
-
-    fbinfo.version = DDMS_RAWIMAGE_VERSION;
-    fbinfo.colorSpace = c;
-    /* see hardware/hardware.h */
-    switch (f) {
-        case 1: /* RGBA_8888 */
-            fbinfo.bpp = 32;
-            fbinfo.size = w * h * 4;
-            fbinfo.width = w;
-            fbinfo.height = h;
-            fbinfo.red_offset = 0;
-            fbinfo.red_length = 8;
-            fbinfo.green_offset = 8;
-            fbinfo.green_length = 8;
-            fbinfo.blue_offset = 16;
-            fbinfo.blue_length = 8;
-            fbinfo.alpha_offset = 24;
-            fbinfo.alpha_length = 8;
-            break;
-        case 2: /* RGBX_8888 */
-            fbinfo.bpp = 32;
-            fbinfo.size = w * h * 4;
-            fbinfo.width = w;
-            fbinfo.height = h;
-            fbinfo.red_offset = 0;
-            fbinfo.red_length = 8;
-            fbinfo.green_offset = 8;
-            fbinfo.green_length = 8;
-            fbinfo.blue_offset = 16;
-            fbinfo.blue_length = 8;
-            fbinfo.alpha_offset = 24;
-            fbinfo.alpha_length = 0;
-            break;
-        case 3: /* RGB_888 */
-            fbinfo.bpp = 24;
-            fbinfo.size = w * h * 3;
-            fbinfo.width = w;
-            fbinfo.height = h;
-            fbinfo.red_offset = 0;
-            fbinfo.red_length = 8;
-            fbinfo.green_offset = 8;
-            fbinfo.green_length = 8;
-            fbinfo.blue_offset = 16;
-            fbinfo.blue_length = 8;
-            fbinfo.alpha_offset = 24;
-            fbinfo.alpha_length = 0;
-            break;
-        case 4: /* RGB_565 */
-            fbinfo.bpp = 16;
-            fbinfo.size = w * h * 2;
-            fbinfo.width = w;
-            fbinfo.height = h;
-            fbinfo.red_offset = 11;
-            fbinfo.red_length = 5;
-            fbinfo.green_offset = 5;
-            fbinfo.green_length = 6;
-            fbinfo.blue_offset = 0;
-            fbinfo.blue_length = 5;
-            fbinfo.alpha_offset = 0;
-            fbinfo.alpha_length = 0;
-            break;
-        case 5: /* BGRA_8888 */
-            fbinfo.bpp = 32;
-            fbinfo.size = w * h * 4;
-            fbinfo.width = w;
-            fbinfo.height = h;
-            fbinfo.red_offset = 16;
-            fbinfo.red_length = 8;
-            fbinfo.green_offset = 8;
-            fbinfo.green_length = 8;
-            fbinfo.blue_offset = 0;
-            fbinfo.blue_length = 8;
-            fbinfo.alpha_offset = 24;
-            fbinfo.alpha_length = 8;
-           break;
-        default:
-            goto done;
-    }
-
-    /* write header */
-    if (!WriteFdExactly(fd.get(), &fbinfo, sizeof(fbinfo))) goto done;
-
-    /* write data */
-    for(i = 0; i < fbinfo.size; i += bsize) {
-      bsize = sizeof(buf);
-      if (i + bsize > fbinfo.size)
-        bsize = fbinfo.size - i;
-      if(!ReadFdExactly(fd_screencap, buf, bsize)) goto done;
-      if (!WriteFdExactly(fd.get(), buf, bsize)) goto done;
-    }
-
-done:
-    adb_close(fds[0]);
-
-    TEMP_FAILURE_RETRY(waitpid(pid, nullptr, 0));
-}
diff --git a/adb/daemon/framebuffer_service.h b/adb/daemon/framebuffer_service.h
deleted file mode 100644
index bab44be..0000000
--- a/adb/daemon/framebuffer_service.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "adb_unique_fd.h"
-
-#if defined(__ANDROID__)
-void framebuffer_service(unique_fd fd);
-#endif
diff --git a/adb/daemon/jdwp_service.cpp b/adb/daemon/jdwp_service.cpp
deleted file mode 100644
index b92a7de..0000000
--- a/adb/daemon/jdwp_service.cpp
+++ /dev/null
@@ -1,438 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#if !ADB_HOST
-
-#define TRACE_TAG JDWP
-
-#include "sysdeps.h"
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <unistd.h>
-
-#include <list>
-#include <memory>
-#include <thread>
-#include <vector>
-
-#include <adbconnection/server.h>
-#include <android-base/cmsg.h>
-#include <android-base/unique_fd.h>
-
-#include "adb.h"
-#include "adb_io.h"
-#include "adb_unique_fd.h"
-#include "adb_utils.h"
-
-using android::base::borrowed_fd;
-using android::base::unique_fd;
-
-/* here's how these things work.
-
-   when adbd starts, it creates a unix server socket
-   named @jdwp-control (@ is a shortcut for "first byte is zero"
-   to use the private namespace instead of the file system)
-
-   when a new JDWP daemon thread starts in a new VM process, it creates
-   a connection to @jdwp-control to announce its availability.
-
-
-     JDWP thread                             @jdwp-control
-         |                                         |
-         |------------------------------->         |
-         | hello I'm in process <pid>              |
-         |                                         |
-         |                                         |
-
-    the connection is kept alive. it will be closed automatically if
-    the JDWP process terminates (this allows adbd to detect dead
-    processes).
-
-    adbd thus maintains a list of "active" JDWP processes. it can send
-    its content to clients through the "device:debug-ports" service,
-    or even updates through the "device:track-debug-ports" service.
-
-    when a debugger wants to connect, it simply runs the command
-    equivalent to  "adb forward tcp:<hostport> jdwp:<pid>"
-
-    "jdwp:<pid>" is a new forward destination format used to target
-    a given JDWP process on the device. when sutch a request arrives,
-    adbd does the following:
-
-      - first, it calls socketpair() to create a pair of equivalent
-        sockets.
-
-      - it attaches the first socket in the pair to a local socket
-        which is itself attached to the transport's remote socket:
-
-
-      - it sends the file descriptor of the second socket directly
-        to the JDWP process with the help of sendmsg()
-
-
-     JDWP thread                             @jdwp-control
-         |                                         |
-         |                  <----------------------|
-         |           OK, try this file descriptor  |
-         |                                         |
-         |                                         |
-
-   then, the JDWP thread uses this new socket descriptor as its
-   pass-through connection to the debugger (and receives the
-   JDWP-Handshake message, answers to it, etc...)
-
-   this gives the following graphics:
-                    ____________________________________
-                   |                                    |
-                   |          ADB Server (host)         |
-                   |                                    |
-        Debugger <---> LocalSocket <----> RemoteSocket  |
-                   |                           ^^       |
-                   |___________________________||_______|
-                                               ||
-                                     Transport ||
-           (TCP for emulator - USB for device) ||
-                                               ||
-                    ___________________________||_______
-                   |                           ||       |
-                   |          ADBD  (device)   ||       |
-                   |                           VV       |
-         JDWP <======> LocalSocket <----> RemoteSocket  |
-                   |                                    |
-                   |____________________________________|
-
-    due to the way adb works, this doesn't need a special socket
-    type or fancy handling of socket termination if either the debugger
-    or the JDWP process closes the connection.
-
-    THIS IS THE SIMPLEST IMPLEMENTATION I COULD FIND, IF YOU HAPPEN
-    TO HAVE A BETTER IDEA, LET ME KNOW - Digit
-
-**********************************************************************/
-
-/** JDWP PID List Support Code
- ** for each JDWP process, we record its pid and its connected socket
- **/
-
-static void jdwp_process_event(int socket, unsigned events, void* _proc);
-static void jdwp_process_list_updated(void);
-
-struct JdwpProcess;
-static auto& _jdwp_list = *new std::list<std::unique_ptr<JdwpProcess>>();
-
-struct JdwpProcess {
-    JdwpProcess(unique_fd socket, pid_t pid) {
-        CHECK(pid != 0);
-
-        this->socket = socket;
-        this->pid = pid;
-        this->fde = fdevent_create(socket.release(), jdwp_process_event, this);
-
-        if (!this->fde) {
-            LOG(FATAL) << "could not create fdevent for new JDWP process";
-        }
-    }
-
-    ~JdwpProcess() {
-        if (this->socket >= 0) {
-            adb_shutdown(this->socket);
-            this->socket = -1;
-        }
-
-        if (this->fde) {
-            fdevent_destroy(this->fde);
-            this->fde = nullptr;
-        }
-
-        out_fds.clear();
-    }
-
-    void RemoveFromList() {
-        auto pred = [this](const auto& proc) { return proc.get() == this; };
-        _jdwp_list.remove_if(pred);
-    }
-
-    borrowed_fd socket = -1;
-    int32_t pid = -1;
-    fdevent* fde = nullptr;
-
-    std::vector<unique_fd> out_fds;
-};
-
-static size_t jdwp_process_list(char* buffer, size_t bufferlen) {
-    std::string temp;
-
-    for (auto& proc : _jdwp_list) {
-        std::string next = std::to_string(proc->pid) + "\n";
-        if (temp.length() + next.length() > bufferlen) {
-            D("truncating JDWP process list (max len = %zu)", bufferlen);
-            break;
-        }
-        temp.append(next);
-    }
-
-    memcpy(buffer, temp.data(), temp.length());
-    return temp.length();
-}
-
-static size_t jdwp_process_list_msg(char* buffer, size_t bufferlen) {
-    // Message is length-prefixed with 4 hex digits in ASCII.
-    static constexpr size_t header_len = 4;
-    if (bufferlen < header_len) {
-        LOG(FATAL) << "invalid JDWP process list buffer size: " << bufferlen;
-    }
-
-    char head[header_len + 1];
-    size_t len = jdwp_process_list(buffer + header_len, bufferlen - header_len);
-    snprintf(head, sizeof head, "%04zx", len);
-    memcpy(buffer, head, header_len);
-    return len + header_len;
-}
-
-static void jdwp_process_event(int socket, unsigned events, void* _proc) {
-    JdwpProcess* proc = reinterpret_cast<JdwpProcess*>(_proc);
-    CHECK_EQ(socket, proc->socket.get());
-
-    if (events & FDE_READ) {
-        // We already have the PID, if we can read from the socket, we've probably hit EOF.
-        D("terminating JDWP connection %d", proc->pid);
-        goto CloseProcess;
-    }
-
-    if (events & FDE_WRITE) {
-        D("trying to send fd to JDWP process (count = %zu)", proc->out_fds.size());
-        CHECK(!proc->out_fds.empty());
-
-        int fd = proc->out_fds.back().get();
-        if (android::base::SendFileDescriptors(socket, "", 1, fd) != 1) {
-            D("sending new file descriptor to JDWP %d failed: %s", proc->pid, strerror(errno));
-            goto CloseProcess;
-        }
-
-        D("sent file descriptor %d to JDWP process %d", fd, proc->pid);
-
-        proc->out_fds.pop_back();
-        if (proc->out_fds.empty()) {
-            fdevent_del(proc->fde, FDE_WRITE);
-        }
-    }
-
-    return;
-
-CloseProcess:
-    proc->RemoveFromList();
-    jdwp_process_list_updated();
-}
-
-unique_fd create_jdwp_connection_fd(int pid) {
-    D("looking for pid %d in JDWP process list", pid);
-
-    for (auto& proc : _jdwp_list) {
-        if (proc->pid == pid) {
-            int fds[2];
-
-            if (adb_socketpair(fds) < 0) {
-                D("%s: socket pair creation failed: %s", __FUNCTION__, strerror(errno));
-                return unique_fd{};
-            }
-            D("socketpair: (%d,%d)", fds[0], fds[1]);
-
-            proc->out_fds.emplace_back(fds[1]);
-            if (proc->out_fds.size() == 1) {
-                fdevent_add(proc->fde, FDE_WRITE);
-            }
-
-            return unique_fd{fds[0]};
-        }
-    }
-    D("search failed !!");
-    return unique_fd{};
-}
-
-/** "jdwp" local service implementation
- ** this simply returns the list of known JDWP process pids
- **/
-
-struct JdwpSocket : public asocket {
-    bool pass = false;
-};
-
-static void jdwp_socket_close(asocket* s) {
-    D("LS(%d): closing jdwp socket", s->id);
-
-    if (s->peer) {
-        D("LS(%d) peer->close()ing peer->id=%d peer->fd=%d", s->id, s->peer->id, s->peer->fd);
-        s->peer->peer = nullptr;
-        s->peer->close(s->peer);
-        s->peer = nullptr;
-    }
-
-    remove_socket(s);
-    delete s;
-}
-
-static int jdwp_socket_enqueue(asocket* s, apacket::payload_type) {
-    /* you can't write to this asocket */
-    D("LS(%d): JDWP socket received data?", s->id);
-    s->peer->close(s->peer);
-    return -1;
-}
-
-static void jdwp_socket_ready(asocket* s) {
-    JdwpSocket* jdwp = (JdwpSocket*)s;
-    asocket* peer = jdwp->peer;
-
-    /* on the first call, send the list of pids,
-     * on the second one, close the connection
-     */
-    if (!jdwp->pass) {
-        apacket::payload_type data;
-        data.resize(s->get_max_payload());
-        size_t len = jdwp_process_list(&data[0], data.size());
-        data.resize(len);
-        peer->enqueue(peer, std::move(data));
-        jdwp->pass = true;
-    } else {
-        peer->close(peer);
-    }
-}
-
-asocket* create_jdwp_service_socket(void) {
-    JdwpSocket* s = new JdwpSocket();
-
-    if (!s) {
-        LOG(FATAL) << "failed to allocate JdwpSocket";
-    }
-
-    install_local_socket(s);
-
-    s->ready = jdwp_socket_ready;
-    s->enqueue = jdwp_socket_enqueue;
-    s->close = jdwp_socket_close;
-    s->pass = false;
-
-    return s;
-}
-
-/** "track-jdwp" local service implementation
- ** this periodically sends the list of known JDWP process pids
- ** to the client...
- **/
-
-struct JdwpTracker : public asocket {
-    bool need_initial;
-};
-
-static auto& _jdwp_trackers = *new std::vector<std::unique_ptr<JdwpTracker>>();
-
-static void jdwp_process_list_updated(void) {
-    std::string data;
-    data.resize(1024);
-    data.resize(jdwp_process_list_msg(&data[0], data.size()));
-
-    for (auto& t : _jdwp_trackers) {
-        if (t->peer) {
-            // The tracker might not have been connected yet.
-            apacket::payload_type payload(data.begin(), data.end());
-            t->peer->enqueue(t->peer, std::move(payload));
-        }
-    }
-}
-
-static void jdwp_tracker_close(asocket* s) {
-    D("LS(%d): destroying jdwp tracker service", s->id);
-
-    if (s->peer) {
-        D("LS(%d) peer->close()ing peer->id=%d peer->fd=%d", s->id, s->peer->id, s->peer->fd);
-        s->peer->peer = nullptr;
-        s->peer->close(s->peer);
-        s->peer = nullptr;
-    }
-
-    remove_socket(s);
-
-    auto pred = [s](const auto& tracker) { return tracker.get() == s; };
-    _jdwp_trackers.erase(std::remove_if(_jdwp_trackers.begin(), _jdwp_trackers.end(), pred),
-                         _jdwp_trackers.end());
-}
-
-static void jdwp_tracker_ready(asocket* s) {
-    JdwpTracker* t = (JdwpTracker*)s;
-
-    if (t->need_initial) {
-        apacket::payload_type data;
-        data.resize(s->get_max_payload());
-        data.resize(jdwp_process_list_msg(&data[0], data.size()));
-        t->need_initial = false;
-        s->peer->enqueue(s->peer, std::move(data));
-    }
-}
-
-static int jdwp_tracker_enqueue(asocket* s, apacket::payload_type) {
-    /* you can't write to this socket */
-    D("LS(%d): JDWP tracker received data?", s->id);
-    s->peer->close(s->peer);
-    return -1;
-}
-
-asocket* create_jdwp_tracker_service_socket(void) {
-    auto t = std::make_unique<JdwpTracker>();
-    if (!t) {
-        LOG(FATAL) << "failed to allocate JdwpTracker";
-    }
-
-    memset(t.get(), 0, sizeof(asocket));
-
-    install_local_socket(t.get());
-    D("LS(%d): created new jdwp tracker service", t->id);
-
-    t->ready = jdwp_tracker_ready;
-    t->enqueue = jdwp_tracker_enqueue;
-    t->close = jdwp_tracker_close;
-    t->need_initial = true;
-
-    asocket* result = t.get();
-
-    _jdwp_trackers.emplace_back(std::move(t));
-
-    return result;
-}
-
-int init_jdwp(void) {
-    std::thread([]() {
-        adb_thread_setname("jdwp control");
-        adbconnection_listen([](int fd, pid_t pid) {
-            LOG(INFO) << "jdwp connection from " << pid;
-            fdevent_run_on_main_thread([fd, pid] {
-                unique_fd ufd(fd);
-                auto proc = std::make_unique<JdwpProcess>(std::move(ufd), pid);
-                if (!proc) {
-                    LOG(FATAL) << "failed to allocate JdwpProcess";
-                }
-                _jdwp_list.emplace_back(std::move(proc));
-                jdwp_process_list_updated();
-            });
-        });
-    }).detach();
-    return 0;
-}
-
-#endif /* !ADB_HOST */
diff --git a/adb/daemon/logging.cpp b/adb/daemon/logging.cpp
deleted file mode 100644
index 203c6c7..0000000
--- a/adb/daemon/logging.cpp
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "daemon/logging.h"
-
-#include <mutex>
-#include <optional>
-#include <string_view>
-
-#include <android-base/no_destructor.h>
-#include <android-base/properties.h>
-#include <android-base/strings.h>
-#include <android-base/thread_annotations.h>
-
-#if defined(__ANDROID__)
-struct LogStatus {
-    bool enabled[static_cast<size_t>(adb::LogType::COUNT)];
-
-    bool& operator[](adb::LogType type) { return enabled[static_cast<size_t>(type)]; }
-};
-
-using android::base::CachedProperty;
-using android::base::NoDestructor;
-
-static NoDestructor<std::mutex> log_mutex;
-static NoDestructor<CachedProperty> log_property GUARDED_BY(log_mutex)("debug.adbd.logging");
-static std::optional<LogStatus> cached_log_status GUARDED_BY(log_mutex);
-
-static NoDestructor<CachedProperty> persist_log_property
-        GUARDED_BY(log_mutex)("persist.debug.adbd.logging");
-static std::optional<LogStatus> cached_persist_log_status GUARDED_BY(log_mutex);
-
-static LogStatus ParseLogStatus(std::string_view str) {
-    LogStatus result = {};
-    for (const auto& part : android::base::Split(std::string(str), ",")) {
-        if (part == "cnxn") {
-            result[adb::LogType::Connection] = true;
-        } else if (part == "service") {
-            result[adb::LogType::Service] = true;
-        } else if (part == "shell") {
-            result[adb::LogType::Shell] = true;
-        } else if (part == "all") {
-            result[adb::LogType::Connection] = true;
-            result[adb::LogType::Service] = true;
-            result[adb::LogType::Shell] = true;
-        }
-    }
-    return result;
-}
-
-static LogStatus GetLogStatus(android::base::CachedProperty* property,
-                              std::optional<LogStatus>* cached_status) REQUIRES(log_mutex) {
-    bool changed;
-    const char* value = property->Get(&changed);
-    if (changed || !*cached_status) {
-        **cached_status = ParseLogStatus(value);
-    }
-    return **cached_status;
-}
-
-namespace adb {
-bool is_logging_enabled(LogType type) {
-    std::lock_guard<std::mutex> lock(*log_mutex);
-    return GetLogStatus(log_property.get(), &cached_log_status)[type] ||
-           GetLogStatus(persist_log_property.get(), &cached_persist_log_status)[type];
-}
-}  // namespace adb
-
-#else
-
-namespace adb {
-bool is_logging_enabled(LogType type) {
-    return false;
-}
-}  // namespace adb
-#endif
diff --git a/adb/daemon/logging.h b/adb/daemon/logging.h
deleted file mode 100644
index 3e28bef..0000000
--- a/adb/daemon/logging.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <android-base/logging.h>
-
-namespace adb {
-enum class LogType {
-    Connection,
-    Service,
-    Shell,
-    COUNT,
-};
-
-bool is_logging_enabled(LogType type);
-
-#define ADB_LOG(type) ::adb::is_logging_enabled(::adb::LogType::type) && LOG(INFO)
-
-}  // namespace adb
diff --git a/adb/daemon/main.cpp b/adb/daemon/main.cpp
deleted file mode 100644
index 658e244..0000000
--- a/adb/daemon/main.cpp
+++ /dev/null
@@ -1,341 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define TRACE_TAG ADB
-
-#include "sysdeps.h"
-
-#if defined(__BIONIC__)
-#include <android/fdsan.h>
-#endif
-
-#include <errno.h>
-#include <getopt.h>
-#include <malloc.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/capability.h>
-#include <sys/prctl.h>
-
-#include <memory>
-#include <vector>
-
-#include <android-base/logging.h>
-#include <android-base/macros.h>
-#include <android-base/properties.h>
-#include <android-base/stringprintf.h>
-#include <android-base/strings.h>
-
-#if defined(__ANDROID__)
-#include <libminijail.h>
-#include <log/log_properties.h>
-#include <scoped_minijail.h>
-
-#include <private/android_filesystem_config.h>
-#include "selinux/android.h"
-#endif
-
-#include "adb.h"
-#include "adb_auth.h"
-#include "adb_listeners.h"
-#include "adb_utils.h"
-#include "adb_wifi.h"
-#include "socket_spec.h"
-#include "transport.h"
-
-#include "mdns.h"
-
-#if defined(__ANDROID__)
-static const char* root_seclabel = nullptr;
-
-static bool should_drop_privileges() {
-    // The properties that affect `adb root` and `adb unroot` are ro.secure and
-    // ro.debuggable. In this context the names don't make the expected behavior
-    // particularly obvious.
-    //
-    // ro.debuggable:
-    //   Allowed to become root, but not necessarily the default. Set to 1 on
-    //   eng and userdebug builds.
-    //
-    // ro.secure:
-    //   Drop privileges by default. Set to 1 on userdebug and user builds.
-    bool ro_secure = android::base::GetBoolProperty("ro.secure", true);
-    bool ro_debuggable = __android_log_is_debuggable();
-
-    // Drop privileges if ro.secure is set...
-    bool drop = ro_secure;
-
-    // ... except "adb root" lets you keep privileges in a debuggable build.
-    std::string prop = android::base::GetProperty("service.adb.root", "");
-    bool adb_root = (prop == "1");
-    bool adb_unroot = (prop == "0");
-    if (ro_debuggable && adb_root) {
-        drop = false;
-    }
-    // ... and "adb unroot" lets you explicitly drop privileges.
-    if (adb_unroot) {
-        drop = true;
-    }
-
-    return drop;
-}
-
-static void drop_privileges(int server_port) {
-    ScopedMinijail jail(minijail_new());
-
-    // Add extra groups:
-    // AID_ADB to access the USB driver
-    // AID_LOG to read system logs (adb logcat)
-    // AID_INPUT to diagnose input issues (getevent)
-    // AID_INET to diagnose network issues (ping)
-    // AID_NET_BT and AID_NET_BT_ADMIN to diagnose bluetooth (hcidump)
-    // AID_SDCARD_R to allow reading from the SD card
-    // AID_SDCARD_RW to allow writing to the SD card
-    // AID_NET_BW_STATS to read out qtaguid statistics
-    // AID_READPROC for reading /proc entries across UID boundaries
-    // AID_UHID for using 'hid' command to read/write to /dev/uhid
-    gid_t groups[] = {AID_ADB,          AID_LOG,          AID_INPUT,    AID_INET,
-                      AID_NET_BT,       AID_NET_BT_ADMIN, AID_SDCARD_R, AID_SDCARD_RW,
-                      AID_NET_BW_STATS, AID_READPROC,     AID_UHID};
-    minijail_set_supplementary_gids(jail.get(), arraysize(groups), groups);
-
-    // Don't listen on a port (default 5037) if running in secure mode.
-    // Don't run as root if running in secure mode.
-    if (should_drop_privileges()) {
-        const bool should_drop_caps = !__android_log_is_debuggable();
-
-        if (should_drop_caps) {
-            minijail_use_caps(jail.get(), CAP_TO_MASK(CAP_SETUID) | CAP_TO_MASK(CAP_SETGID));
-        }
-
-        minijail_change_gid(jail.get(), AID_SHELL);
-        minijail_change_uid(jail.get(), AID_SHELL);
-        // minijail_enter() will abort if any priv-dropping step fails.
-        minijail_enter(jail.get());
-
-        // Whenever ambient capabilities are being used, minijail cannot
-        // simultaneously drop the bounding capability set to just
-        // CAP_SETUID|CAP_SETGID while clearing the inheritable, effective,
-        // and permitted sets. So we need to do that in two steps.
-        using ScopedCaps =
-            std::unique_ptr<std::remove_pointer<cap_t>::type, std::function<void(cap_t)>>;
-        ScopedCaps caps(cap_get_proc(), &cap_free);
-        if (cap_clear_flag(caps.get(), CAP_INHERITABLE) == -1) {
-            PLOG(FATAL) << "cap_clear_flag(INHERITABLE) failed";
-        }
-        if (cap_clear_flag(caps.get(), CAP_EFFECTIVE) == -1) {
-            PLOG(FATAL) << "cap_clear_flag(PEMITTED) failed";
-        }
-        if (cap_clear_flag(caps.get(), CAP_PERMITTED) == -1) {
-            PLOG(FATAL) << "cap_clear_flag(PEMITTED) failed";
-        }
-        if (cap_set_proc(caps.get()) != 0) {
-            PLOG(FATAL) << "cap_set_proc() failed";
-        }
-
-        D("Local port disabled");
-    } else {
-        // minijail_enter() will abort if any priv-dropping step fails.
-        minijail_enter(jail.get());
-
-        if (root_seclabel != nullptr) {
-            if (selinux_android_setcon(root_seclabel) < 0) {
-                LOG(FATAL) << "Could not set SELinux context";
-            }
-        }
-        std::string error;
-        std::string local_name =
-            android::base::StringPrintf("tcp:%d", server_port);
-        if (install_listener(local_name, "*smartsocket*", nullptr, 0, nullptr, &error)) {
-            LOG(FATAL) << "Could not install *smartsocket* listener: " << error;
-        }
-    }
-}
-#endif
-
-static void setup_adb(const std::vector<std::string>& addrs) {
-#if defined(__ANDROID__)
-    // Get the first valid port from addrs and setup mDNS.
-    int port = -1;
-    std::string error;
-    for (const auto& addr : addrs) {
-        port = get_host_socket_spec_port(addr, &error);
-        if (port != -1) {
-            break;
-        }
-    }
-    if (port == -1) {
-        port = DEFAULT_ADB_LOCAL_TRANSPORT_PORT;
-    }
-    LOG(INFO) << "Setup mdns on port= " << port;
-    setup_mdns(port);
-#endif
-    for (const auto& addr : addrs) {
-        LOG(INFO) << "adbd listening on " << addr;
-        local_init(addr);
-    }
-}
-
-int adbd_main(int server_port) {
-    umask(0);
-
-    signal(SIGPIPE, SIG_IGN);
-
-#if defined(__BIONIC__)
-    auto fdsan_level = android_fdsan_get_error_level();
-    if (fdsan_level == ANDROID_FDSAN_ERROR_LEVEL_DISABLED) {
-        android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_WARN_ONCE);
-    }
-#endif
-
-    init_transport_registration();
-
-    // We need to call this even if auth isn't enabled because the file
-    // descriptor will always be open.
-    adbd_cloexec_auth_socket();
-
-#if defined(__ANDROID__)
-    // If we're on userdebug/eng or the device is unlocked, permit no-authentication.
-    bool device_unlocked = "orange" == android::base::GetProperty("ro.boot.verifiedbootstate", "");
-    if (__android_log_is_debuggable() || device_unlocked) {
-        auth_required = android::base::GetBoolProperty("ro.adb.secure", false);
-    }
-#endif
-
-    // Our external storage path may be different than apps, since
-    // we aren't able to bind mount after dropping root.
-    const char* adb_external_storage = getenv("ADB_EXTERNAL_STORAGE");
-    if (adb_external_storage != nullptr) {
-        setenv("EXTERNAL_STORAGE", adb_external_storage, 1);
-    } else {
-        D("Warning: ADB_EXTERNAL_STORAGE is not set.  Leaving EXTERNAL_STORAGE"
-          " unchanged.\n");
-    }
-
-#if defined(__ANDROID__)
-    drop_privileges(server_port);
-#endif
-
-    // adbd_auth_init will spawn a thread, so we need to defer it until after selinux transitions.
-    adbd_auth_init();
-
-    bool is_usb = false;
-
-#if defined(__ANDROID__)
-    if (access(USB_FFS_ADB_EP0, F_OK) == 0) {
-        // Listen on USB.
-        usb_init();
-        is_usb = true;
-    }
-#endif
-
-    // If one of these properties is set, also listen on that port.
-    // If one of the properties isn't set and we couldn't listen on usb, listen
-    // on the default port.
-    std::vector<std::string> addrs;
-    std::string prop_addr = android::base::GetProperty("service.adb.listen_addrs", "");
-    if (prop_addr.empty()) {
-        std::string prop_port = android::base::GetProperty("service.adb.tcp.port", "");
-        if (prop_port.empty()) {
-            prop_port = android::base::GetProperty("persist.adb.tcp.port", "");
-        }
-
-#if !defined(__ANDROID__)
-        if (prop_port.empty() && getenv("ADBD_PORT")) {
-            prop_port = getenv("ADBD_PORT");
-        }
-#endif
-
-        int port;
-        if (sscanf(prop_port.c_str(), "%d", &port) == 1 && port > 0) {
-            D("using tcp port=%d", port);
-            // Listen on TCP and VSOCK port specified by service.adb.tcp.port property.
-            addrs.push_back(android::base::StringPrintf("tcp:%d", port));
-            addrs.push_back(android::base::StringPrintf("vsock:%d", port));
-            setup_adb(addrs);
-        } else if (!is_usb) {
-            // Listen on default port.
-            addrs.push_back(
-                    android::base::StringPrintf("tcp:%d", DEFAULT_ADB_LOCAL_TRANSPORT_PORT));
-            addrs.push_back(
-                    android::base::StringPrintf("vsock:%d", DEFAULT_ADB_LOCAL_TRANSPORT_PORT));
-            setup_adb(addrs);
-        }
-    } else {
-        addrs = android::base::Split(prop_addr, ",");
-        setup_adb(addrs);
-    }
-
-    D("adbd_main(): pre init_jdwp()");
-    init_jdwp();
-    D("adbd_main(): post init_jdwp()");
-
-    D("Event loop starting");
-    fdevent_loop();
-
-    return 0;
-}
-
-int main(int argc, char** argv) {
-#if defined(__BIONIC__)
-    // Set M_DECAY_TIME so that our allocations aren't immediately purged on free.
-    mallopt(M_DECAY_TIME, 1);
-#endif
-
-    while (true) {
-        static struct option opts[] = {
-                {"root_seclabel", required_argument, nullptr, 's'},
-                {"device_banner", required_argument, nullptr, 'b'},
-                {"version", no_argument, nullptr, 'v'},
-                {"logpostfsdata", no_argument, nullptr, 'l'},
-        };
-
-        int option_index = 0;
-        int c = getopt_long(argc, argv, "", opts, &option_index);
-        if (c == -1) {
-            break;
-        }
-
-        switch (c) {
-#if defined(__ANDROID__)
-            case 's':
-                root_seclabel = optarg;
-                break;
-#endif
-            case 'b':
-                adb_device_banner = optarg;
-                break;
-            case 'v':
-                printf("Android Debug Bridge Daemon version %d.%d.%d\n", ADB_VERSION_MAJOR,
-                       ADB_VERSION_MINOR, ADB_SERVER_VERSION);
-                return 0;
-            case 'l':
-                LOG(ERROR) << "post-fs-data triggered";
-                return 0;
-            default:
-                // getopt already prints "adbd: invalid option -- %c" for us.
-                return 1;
-        }
-    }
-
-    close_stdin();
-
-    adb_trace_init(argv);
-
-    D("Handling main()");
-    return adbd_main(DEFAULT_ADB_PORT);
-}
diff --git a/adb/daemon/mdns.cpp b/adb/daemon/mdns.cpp
deleted file mode 100644
index fa692c0..0000000
--- a/adb/daemon/mdns.cpp
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "mdns.h"
-#include "adb_mdns.h"
-#include "sysdeps.h"
-
-#include <dns_sd.h>
-#include <endian.h>
-#include <unistd.h>
-
-#include <chrono>
-#include <mutex>
-#include <random>
-#include <thread>
-
-#include <android-base/logging.h>
-#include <android-base/properties.h>
-
-using namespace std::chrono_literals;
-
-static std::mutex& mdns_lock = *new std::mutex();
-static int port;
-static DNSServiceRef mdns_refs[kNumADBDNSServices];
-static bool mdns_registered[kNumADBDNSServices];
-
-void start_mdnsd() {
-    if (android::base::GetProperty("init.svc.mdnsd", "") == "running") {
-        return;
-    }
-
-    android::base::SetProperty("ctl.start", "mdnsd");
-
-    if (! android::base::WaitForProperty("init.svc.mdnsd", "running", 5s)) {
-        LOG(ERROR) << "Could not start mdnsd.";
-    }
-}
-
-static void mdns_callback(DNSServiceRef /*ref*/,
-                          DNSServiceFlags /*flags*/,
-                          DNSServiceErrorType errorCode,
-                          const char* /*name*/,
-                          const char* /*regtype*/,
-                          const char* /*domain*/,
-                          void* /*context*/) {
-    if (errorCode != kDNSServiceErr_NoError) {
-        LOG(ERROR) << "Encountered mDNS registration error ("
-            << errorCode << ").";
-    }
-}
-
-static void register_mdns_service(int index, int port, const std::string service_name) {
-    std::lock_guard<std::mutex> lock(mdns_lock);
-
-
-    // https://tools.ietf.org/html/rfc6763
-    // """
-    // The format of the data within a DNS TXT record is one or more
-    // strings, packed together in memory without any intervening gaps or
-    // padding bytes for word alignment.
-    //
-    // The format of each constituent string within the DNS TXT record is a
-    // single length byte, followed by 0-255 bytes of text data.
-    // """
-    //
-    // Therefore:
-    // 1. Begin with the string length
-    // 2. No null termination
-
-    std::vector<char> txtRecord;
-
-    if (kADBDNSServiceTxtRecords[index]) {
-        size_t txtRecordStringLength = strlen(kADBDNSServiceTxtRecords[index]);
-
-        txtRecord.resize(1 +                    // length byte
-                         txtRecordStringLength  // string bytes
-        );
-
-        txtRecord[0] = (char)txtRecordStringLength;
-        memcpy(txtRecord.data() + 1, kADBDNSServiceTxtRecords[index], txtRecordStringLength);
-    }
-
-    auto error = DNSServiceRegister(
-            &mdns_refs[index], 0, 0, service_name.c_str(), kADBDNSServices[index], nullptr, nullptr,
-            htobe16((uint16_t)port), (uint16_t)txtRecord.size(),
-            txtRecord.empty() ? nullptr : txtRecord.data(), mdns_callback, nullptr);
-
-    if (error != kDNSServiceErr_NoError) {
-        LOG(ERROR) << "Could not register mDNS service " << kADBDNSServices[index] << ", error ("
-                   << error << ").";
-        mdns_registered[index] = false;
-    }
-
-    mdns_registered[index] = true;
-
-    LOG(INFO) << "adbd mDNS service " << kADBDNSServices[index]
-              << " registered: " << mdns_registered[index];
-}
-
-static void unregister_mdns_service(int index) {
-    std::lock_guard<std::mutex> lock(mdns_lock);
-
-    if (mdns_registered[index]) {
-        DNSServiceRefDeallocate(mdns_refs[index]);
-    }
-}
-
-static void register_base_mdns_transport() {
-    std::string hostname = "adb-";
-    hostname += android::base::GetProperty("ro.serialno", "unidentified");
-    register_mdns_service(kADBTransportServiceRefIndex, port, hostname);
-}
-
-static void setup_mdns_thread() {
-    start_mdnsd();
-
-    // We will now only set up the normal transport mDNS service
-    // instead of registering all the adb secure mDNS services
-    // in the beginning. This is to provide more privacy/security.
-    register_base_mdns_transport();
-}
-
-// This also tears down any adb secure mDNS services, if they exist.
-static void teardown_mdns() {
-    for (int i = 0; i < kNumADBDNSServices; ++i) {
-        unregister_mdns_service(i);
-    }
-}
-
-static std::string RandomAlphaNumString(size_t len) {
-    std::string ret;
-    std::random_device rd;
-    std::mt19937 mt(rd());
-    // Generate values starting with zero and then up to enough to cover numeric
-    // digits, small letters and capital letters (26 each).
-    std::uniform_int_distribution<uint8_t> dist(0, 61);
-    for (size_t i = 0; i < len; ++i) {
-        uint8_t val = dist(mt);
-        if (val < 10) {
-            ret += '0' + val;
-        } else if (val < 36) {
-            ret += 'A' + (val - 10);
-        } else {
-            ret += 'a' + (val - 36);
-        }
-    }
-    return ret;
-}
-
-static std::string GenerateDeviceGuid() {
-    // The format is adb-<serial_no>-<six-random-alphanum>
-    std::string guid = "adb-";
-
-    std::string serial = android::base::GetProperty("ro.serialno", "");
-    if (serial.empty()) {
-        // Generate 16-bytes of random alphanum string
-        serial = RandomAlphaNumString(16);
-    }
-    guid += serial + '-';
-    // Random six-char suffix
-    guid += RandomAlphaNumString(6);
-    return guid;
-}
-
-static std::string ReadDeviceGuid() {
-    std::string guid = android::base::GetProperty("persist.adb.wifi.guid", "");
-    if (guid.empty()) {
-        guid = GenerateDeviceGuid();
-        CHECK(!guid.empty());
-        android::base::SetProperty("persist.adb.wifi.guid", guid);
-    }
-    return guid;
-}
-
-// Public interface/////////////////////////////////////////////////////////////
-
-void setup_mdns(int port_in) {
-    // Make sure the adb wifi guid is generated.
-    std::string guid = ReadDeviceGuid();
-    CHECK(!guid.empty());
-    port = port_in;
-    std::thread(setup_mdns_thread).detach();
-
-    // TODO: Make this more robust against a hard kill.
-    atexit(teardown_mdns);
-}
-
-void register_adb_secure_connect_service(int port) {
-    std::thread([port]() {
-        auto service_name = ReadDeviceGuid();
-        if (service_name.empty()) {
-            return;
-        }
-        LOG(INFO) << "Registering secure_connect service (" << service_name << ")";
-        register_mdns_service(kADBSecureConnectServiceRefIndex, port, service_name);
-    }).detach();
-}
-
-void unregister_adb_secure_connect_service() {
-    std::thread([]() { unregister_mdns_service(kADBSecureConnectServiceRefIndex); }).detach();
-}
-
-bool is_adb_secure_connect_service_registered() {
-    std::lock_guard<std::mutex> lock(mdns_lock);
-    return mdns_registered[kADBSecureConnectServiceRefIndex];
-}
diff --git a/adb/daemon/mdns.h b/adb/daemon/mdns.h
deleted file mode 100644
index e7e7a62..0000000
--- a/adb/daemon/mdns.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _DAEMON_MDNS_H_
-#define _DAEMON_MDNS_H_
-
-void setup_mdns(int port);
-
-void register_adb_secure_connect_service(int port);
-void unregister_adb_secure_connect_service();
-bool is_adb_secure_connect_service_registered();
-
-void start_mdnsd();
-#endif  // _DAEMON_MDNS_H_
diff --git a/adb/daemon/restart_service.cpp b/adb/daemon/restart_service.cpp
deleted file mode 100644
index 16d2627..0000000
--- a/adb/daemon/restart_service.cpp
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define TRACE_TAG SERVICES
-
-#include "sysdeps.h"
-
-#include <unistd.h>
-
-#include <android-base/logging.h>
-#include <android-base/properties.h>
-#include <android-base/stringprintf.h>
-#include <log/log_properties.h>
-
-#include "adb_io.h"
-#include "adb_unique_fd.h"
-
-void restart_root_service(unique_fd fd) {
-    if (getuid() == 0) {
-        WriteFdExactly(fd.get(), "adbd is already running as root\n");
-        return;
-    }
-    if (!__android_log_is_debuggable()) {
-        WriteFdExactly(fd.get(), "adbd cannot run as root in production builds\n");
-        return;
-    }
-
-    LOG(INFO) << "adbd restarting as root";
-    android::base::SetProperty("service.adb.root", "1");
-    WriteFdExactly(fd.get(), "restarting adbd as root\n");
-}
-
-void restart_unroot_service(unique_fd fd) {
-    if (getuid() != 0) {
-        WriteFdExactly(fd.get(), "adbd not running as root\n");
-        return;
-    }
-
-    LOG(INFO) << "adbd restarting as nonroot";
-    android::base::SetProperty("service.adb.root", "0");
-    WriteFdExactly(fd.get(), "restarting adbd as non root\n");
-}
-
-void restart_tcp_service(unique_fd fd, int port) {
-    if (port <= 0) {
-        WriteFdFmt(fd.get(), "invalid port %d\n", port);
-        return;
-    }
-
-    LOG(INFO) << "adbd restarting in TCP mode (port = " << port << ")";
-    android::base::SetProperty("service.adb.tcp.port", android::base::StringPrintf("%d", port));
-    WriteFdFmt(fd.get(), "restarting in TCP mode port: %d\n", port);
-}
-
-void restart_usb_service(unique_fd fd) {
-    LOG(INFO) << "adbd restarting in USB mode";
-    android::base::SetProperty("service.adb.tcp.port", "0");
-    WriteFdExactly(fd.get(), "restarting in USB mode\n");
-}
diff --git a/adb/daemon/restart_service.h b/adb/daemon/restart_service.h
deleted file mode 100644
index 19840bd..0000000
--- a/adb/daemon/restart_service.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "adb_unique_fd.h"
-
-#if defined(__ANDROID__)
-void restart_root_service(unique_fd fd);
-void restart_unroot_service(unique_fd fd);
-void restart_tcp_service(unique_fd fd, int port);
-void restart_usb_service(unique_fd fd);
-#endif
diff --git a/adb/daemon/services.cpp b/adb/daemon/services.cpp
deleted file mode 100644
index 6bbf66e..0000000
--- a/adb/daemon/services.cpp
+++ /dev/null
@@ -1,335 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define TRACE_TAG SERVICES
-
-#include "sysdeps.h"
-
-#include <errno.h>
-#include <netdb.h>
-#include <netinet/in.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <unistd.h>
-
-#include <thread>
-
-#include <android-base/file.h>
-#include <android-base/parseint.h>
-#include <android-base/parsenetaddress.h>
-#include <android-base/properties.h>
-#include <android-base/stringprintf.h>
-#include <android-base/strings.h>
-#include <android-base/unique_fd.h>
-#include <cutils/android_reboot.h>
-#include <cutils/sockets.h>
-#include <log/log_properties.h>
-
-#include "adb.h"
-#include "adb_io.h"
-#include "adb_unique_fd.h"
-#include "adb_utils.h"
-#include "services.h"
-#include "socket_spec.h"
-#include "sysdeps.h"
-#include "transport.h"
-
-#include "daemon/file_sync_service.h"
-#include "daemon/framebuffer_service.h"
-#include "daemon/logging.h"
-#include "daemon/restart_service.h"
-#include "daemon/shell_service.h"
-
-void reconnect_service(unique_fd fd, atransport* t) {
-    WriteFdExactly(fd.get(), "done");
-    kick_transport(t);
-}
-
-unique_fd reverse_service(std::string_view command, atransport* transport) {
-    // TODO: Switch handle_forward_request to std::string_view.
-    std::string str(command);
-
-    int s[2];
-    if (adb_socketpair(s)) {
-        PLOG(ERROR) << "cannot create service socket pair.";
-        return unique_fd{};
-    }
-    VLOG(SERVICES) << "service socketpair: " << s[0] << ", " << s[1];
-    if (!handle_forward_request(str.c_str(), transport, s[1])) {
-        SendFail(s[1], "not a reverse forwarding command");
-    }
-    adb_close(s[1]);
-    return unique_fd{s[0]};
-}
-
-// Shell service string can look like:
-//   shell[,arg1,arg2,...]:[command]
-unique_fd ShellService(std::string_view args, const atransport* transport) {
-    size_t delimiter_index = args.find(':');
-    if (delimiter_index == std::string::npos) {
-        LOG(ERROR) << "No ':' found in shell service arguments: " << args;
-        return unique_fd{};
-    }
-
-    // TODO: android::base::Split(const std::string_view&, ...)
-    std::string service_args(args.substr(0, delimiter_index));
-    std::string command(args.substr(delimiter_index + 1));
-
-    // Defaults:
-    //   PTY for interactive, raw for non-interactive.
-    //   No protocol.
-    //   $TERM set to "dumb".
-    SubprocessType type(command.empty() ? SubprocessType::kPty : SubprocessType::kRaw);
-    SubprocessProtocol protocol = SubprocessProtocol::kNone;
-    std::string terminal_type = "dumb";
-
-    for (const std::string& arg : android::base::Split(service_args, ",")) {
-        if (arg == kShellServiceArgRaw) {
-            type = SubprocessType::kRaw;
-        } else if (arg == kShellServiceArgPty) {
-            type = SubprocessType::kPty;
-        } else if (arg == kShellServiceArgShellProtocol) {
-            protocol = SubprocessProtocol::kShell;
-        } else if (arg.starts_with("TERM=")) {
-            terminal_type = arg.substr(strlen("TERM="));
-        } else if (!arg.empty()) {
-            // This is not an error to allow for future expansion.
-            LOG(WARNING) << "Ignoring unknown shell service argument: " << arg;
-        }
-    }
-
-    return StartSubprocess(command, terminal_type.c_str(), type, protocol);
-}
-
-static void spin_service(unique_fd fd) {
-    if (!__android_log_is_debuggable()) {
-        WriteFdExactly(fd.get(), "refusing to spin on non-debuggable build\n");
-        return;
-    }
-
-    // A service that creates an fdevent that's always pending, and then ignores it.
-    unique_fd pipe_read, pipe_write;
-    if (!Pipe(&pipe_read, &pipe_write)) {
-        WriteFdExactly(fd.get(), "failed to create pipe\n");
-        return;
-    }
-
-    fdevent_run_on_main_thread([fd = pipe_read.release()]() {
-        fdevent* fde = fdevent_create(
-                fd, [](int, unsigned, void*) {}, nullptr);
-        fdevent_add(fde, FDE_READ);
-    });
-
-    WriteFdExactly(fd.get(), "spinning\n");
-}
-
-[[maybe_unused]] static unique_fd reboot_device(const std::string& name) {
-#if defined(__ANDROID_RECOVERY__)
-    if (!__android_log_is_debuggable()) {
-        auto reboot_service = [name](unique_fd fd) {
-            std::string reboot_string = android::base::StringPrintf("reboot,%s", name.c_str());
-            if (!android::base::SetProperty(ANDROID_RB_PROPERTY, reboot_string)) {
-                WriteFdFmt(fd.get(), "reboot (%s) failed\n", reboot_string.c_str());
-                return;
-            }
-            while (true) pause();
-        };
-        return create_service_thread("reboot", reboot_service);
-    }
-#endif
-    // Fall through
-    std::string cmd = "/system/bin/reboot ";
-    cmd += name;
-    return StartSubprocess(cmd, nullptr, SubprocessType::kRaw, SubprocessProtocol::kNone);
-}
-
-struct ServiceSocket : public asocket {
-    ServiceSocket() {
-        install_local_socket(this);
-        this->enqueue = [](asocket* self, apacket::payload_type data) {
-            return static_cast<ServiceSocket*>(self)->Enqueue(std::move(data));
-        };
-        this->ready = [](asocket* self) { return static_cast<ServiceSocket*>(self)->Ready(); };
-        this->close = [](asocket* self) { return static_cast<ServiceSocket*>(self)->Close(); };
-    }
-    virtual ~ServiceSocket() = default;
-
-    virtual int Enqueue(apacket::payload_type data) { return -1; }
-    virtual void Ready() {}
-    virtual void Close() {
-        if (peer) {
-            peer->peer = nullptr;
-            if (peer->shutdown) {
-                peer->shutdown(peer);
-            }
-            peer->close(peer);
-        }
-
-        remove_socket(this);
-        delete this;
-    }
-};
-
-struct SinkSocket : public ServiceSocket {
-    explicit SinkSocket(size_t byte_count) {
-        LOG(INFO) << "Creating new SinkSocket with capacity " << byte_count;
-        bytes_left_ = byte_count;
-    }
-
-    virtual ~SinkSocket() { LOG(INFO) << "SinkSocket destroyed"; }
-
-    virtual int Enqueue(apacket::payload_type data) override final {
-        if (bytes_left_ <= data.size()) {
-            // Done reading.
-            Close();
-            return -1;
-        }
-
-        bytes_left_ -= data.size();
-        return 0;
-    }
-
-    size_t bytes_left_;
-};
-
-struct SourceSocket : public ServiceSocket {
-    explicit SourceSocket(size_t byte_count) {
-        LOG(INFO) << "Creating new SourceSocket with capacity " << byte_count;
-        bytes_left_ = byte_count;
-    }
-
-    virtual ~SourceSocket() { LOG(INFO) << "SourceSocket destroyed"; }
-
-    void Ready() {
-        size_t len = std::min(bytes_left_, get_max_payload());
-        if (len == 0) {
-            Close();
-            return;
-        }
-
-        Block block(len);
-        memset(block.data(), 0, block.size());
-        peer->enqueue(peer, std::move(block));
-        bytes_left_ -= len;
-    }
-
-    int Enqueue(apacket::payload_type data) { return -1; }
-
-    size_t bytes_left_;
-};
-
-asocket* daemon_service_to_socket(std::string_view name) {
-    if (name == "jdwp") {
-        return create_jdwp_service_socket();
-    } else if (name == "track-jdwp") {
-        return create_jdwp_tracker_service_socket();
-    } else if (android::base::ConsumePrefix(&name, "sink:")) {
-        uint64_t byte_count = 0;
-        if (!ParseUint(&byte_count, name)) {
-            return nullptr;
-        }
-        return new SinkSocket(byte_count);
-    } else if (android::base::ConsumePrefix(&name, "source:")) {
-        uint64_t byte_count = 0;
-        if (!ParseUint(&byte_count, name)) {
-            return nullptr;
-        }
-        return new SourceSocket(byte_count);
-    }
-
-    return nullptr;
-}
-
-unique_fd daemon_service_to_fd(std::string_view name, atransport* transport) {
-    ADB_LOG(Service) << "transport " << transport->serial_name() << " opening service " << name;
-
-#if defined(__ANDROID__) && !defined(__ANDROID_RECOVERY__)
-    if (name.starts_with("abb:") || name.starts_with("abb_exec:")) {
-        return execute_abb_command(name);
-    }
-#endif
-
-#if defined(__ANDROID__)
-    if (name.starts_with("framebuffer:")) {
-        return create_service_thread("fb", framebuffer_service);
-    } else if (android::base::ConsumePrefix(&name, "remount:")) {
-        std::string cmd = "/system/bin/remount ";
-        cmd += name;
-        return StartSubprocess(cmd, nullptr, SubprocessType::kRaw, SubprocessProtocol::kNone);
-    } else if (android::base::ConsumePrefix(&name, "reboot:")) {
-        return reboot_device(std::string(name));
-    } else if (name.starts_with("root:")) {
-        return create_service_thread("root", restart_root_service);
-    } else if (name.starts_with("unroot:")) {
-        return create_service_thread("unroot", restart_unroot_service);
-    } else if (android::base::ConsumePrefix(&name, "backup:")) {
-        std::string cmd = "/system/bin/bu backup ";
-        cmd += name;
-        return StartSubprocess(cmd, nullptr, SubprocessType::kRaw, SubprocessProtocol::kNone);
-    } else if (name.starts_with("restore:")) {
-        return StartSubprocess("/system/bin/bu restore", nullptr, SubprocessType::kRaw,
-                               SubprocessProtocol::kNone);
-    } else if (name.starts_with("disable-verity:")) {
-        return StartSubprocess("/system/bin/disable-verity", nullptr, SubprocessType::kRaw,
-                               SubprocessProtocol::kNone);
-    } else if (name.starts_with("enable-verity:")) {
-        return StartSubprocess("/system/bin/enable-verity", nullptr, SubprocessType::kRaw,
-                               SubprocessProtocol::kNone);
-    } else if (android::base::ConsumePrefix(&name, "tcpip:")) {
-        std::string str(name);
-
-        int port;
-        if (sscanf(str.c_str(), "%d", &port) != 1) {
-            return unique_fd{};
-        }
-        return create_service_thread("tcp",
-                                     std::bind(restart_tcp_service, std::placeholders::_1, port));
-    } else if (name.starts_with("usb:")) {
-        return create_service_thread("usb", restart_usb_service);
-    }
-#endif
-
-    if (android::base::ConsumePrefix(&name, "dev:")) {
-        return unique_fd{unix_open(name, O_RDWR | O_CLOEXEC)};
-    } else if (android::base::ConsumePrefix(&name, "jdwp:")) {
-        pid_t pid;
-        if (!ParseUint(&pid, name)) {
-            return unique_fd{};
-        }
-        return create_jdwp_connection_fd(pid);
-    } else if (android::base::ConsumePrefix(&name, "shell")) {
-        return ShellService(name, transport);
-    } else if (android::base::ConsumePrefix(&name, "exec:")) {
-        return StartSubprocess(std::string(name), nullptr, SubprocessType::kRaw,
-                               SubprocessProtocol::kNone);
-    } else if (name.starts_with("sync:")) {
-        return create_service_thread("sync", file_sync_service);
-    } else if (android::base::ConsumePrefix(&name, "reverse:")) {
-        return reverse_service(name, transport);
-    } else if (name == "reconnect") {
-        return create_service_thread(
-                "reconnect", std::bind(reconnect_service, std::placeholders::_1, transport));
-    } else if (name == "spin") {
-        return create_service_thread("spin", spin_service);
-    }
-
-    return unique_fd{};
-}
diff --git a/adb/daemon/shell_service.cpp b/adb/daemon/shell_service.cpp
deleted file mode 100644
index fbfae1e..0000000
--- a/adb/daemon/shell_service.cpp
+++ /dev/null
@@ -1,911 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-// Functionality for launching and managing shell subprocesses.
-//
-// There are two types of subprocesses, PTY or raw. PTY is typically used for
-// an interactive session, raw for non-interactive. There are also two methods
-// of communication with the subprocess, passing raw data or using a simple
-// protocol to wrap packets. The protocol allows separating stdout/stderr and
-// passing the exit code back, but is not backwards compatible.
-//   ----------------+--------------------------------------
-//   Type  Protocol  |   Exit code?  Separate stdout/stderr?
-//   ----------------+--------------------------------------
-//   PTY   No        |   No          No
-//   Raw   No        |   No          No
-//   PTY   Yes       |   Yes         No
-//   Raw   Yes       |   Yes         Yes
-//   ----------------+--------------------------------------
-//
-// Non-protocol subprocesses work by passing subprocess stdin/out/err through
-// a single pipe which is registered with a local socket in adbd. The local
-// socket uses the fdevent loop to pass raw data between this pipe and the
-// transport, which then passes data back to the adb client. Cleanup is done by
-// waiting in a separate thread for the subprocesses to exit and then signaling
-// a separate fdevent to close out the local socket from the main loop.
-//
-// ------------------+-------------------------+------------------------------
-//   Subprocess      |  adbd subprocess thread |   adbd main fdevent loop
-// ------------------+-------------------------+------------------------------
-//                   |                         |
-//   stdin/out/err <----------------------------->       LocalSocket
-//      |            |                         |
-//      |            |      Block on exit      |
-//      |            |           *             |
-//      v            |           *             |
-//     Exit         --->      Unblock          |
-//                   |           |             |
-//                   |           v             |
-//                   |   Notify shell exit FD --->    Close LocalSocket
-// ------------------+-------------------------+------------------------------
-//
-// The protocol requires the thread to intercept stdin/out/err in order to
-// wrap/unwrap data with shell protocol packets.
-//
-// ------------------+-------------------------+------------------------------
-//   Subprocess      |  adbd subprocess thread |   adbd main fdevent loop
-// ------------------+-------------------------+------------------------------
-//                   |                         |
-//     stdin/out   <--->      Protocol       <--->       LocalSocket
-//     stderr       --->      Protocol        --->       LocalSocket
-//       |           |                         |
-//       v           |                         |
-//      Exit        --->  Exit code protocol  --->       LocalSocket
-//                   |           |             |
-//                   |           v             |
-//                   |   Notify shell exit FD --->    Close LocalSocket
-// ------------------+-------------------------+------------------------------
-//
-// An alternate approach is to put the protocol wrapping/unwrapping in the main
-// fdevent loop, which has the advantage of being able to re-use the existing
-// select() code for handling data streams. However, implementation turned out
-// to be more complex due to partial reads and non-blocking I/O so this model
-// was chosen instead.
-
-#define TRACE_TAG SHELL
-
-#include "sysdeps.h"
-
-#include "shell_service.h"
-
-#include <errno.h>
-#include <paths.h>
-#include <pty.h>
-#include <pwd.h>
-#include <termios.h>
-
-#include <memory>
-#include <string>
-#include <thread>
-#include <unordered_map>
-#include <vector>
-
-#include <android-base/logging.h>
-#include <android-base/properties.h>
-#include <android-base/stringprintf.h>
-#include <private/android_logger.h>
-
-#if defined(__ANDROID__)
-#include <selinux/android.h>
-#endif
-
-#include "adb.h"
-#include "adb_io.h"
-#include "adb_trace.h"
-#include "adb_unique_fd.h"
-#include "adb_utils.h"
-#include "daemon/logging.h"
-#include "security_log_tags.h"
-#include "shell_protocol.h"
-
-namespace {
-
-// Reads from |fd| until close or failure.
-std::string ReadAll(borrowed_fd fd) {
-    char buffer[512];
-    std::string received;
-
-    while (1) {
-        int bytes = adb_read(fd, buffer, sizeof(buffer));
-        if (bytes <= 0) {
-            break;
-        }
-        received.append(buffer, bytes);
-    }
-
-    return received;
-}
-
-// Creates a socketpair and saves the endpoints to |fd1| and |fd2|.
-bool CreateSocketpair(unique_fd* fd1, unique_fd* fd2) {
-    int sockets[2];
-    if (adb_socketpair(sockets) < 0) {
-        PLOG(ERROR) << "cannot create socket pair";
-        return false;
-    }
-    fd1->reset(sockets[0]);
-    fd2->reset(sockets[1]);
-    return true;
-}
-
-struct SubprocessPollfds {
-    adb_pollfd pfds[3];
-
-    adb_pollfd* data() { return pfds; }
-    size_t size() { return 3; }
-
-    adb_pollfd* begin() { return pfds; }
-    adb_pollfd* end() { return pfds + size(); }
-
-    adb_pollfd& stdinout_pfd() { return pfds[0]; }
-    adb_pollfd& stderr_pfd() { return pfds[1]; }
-    adb_pollfd& protocol_pfd() { return pfds[2]; }
-};
-
-class Subprocess {
-  public:
-    Subprocess(std::string command, const char* terminal_type, SubprocessType type,
-               SubprocessProtocol protocol, bool make_pty_raw);
-    ~Subprocess();
-
-    const std::string& command() const { return command_; }
-
-    int ReleaseLocalSocket() { return local_socket_sfd_.release(); }
-
-    pid_t pid() const { return pid_; }
-
-    // Sets up FDs, forks a subprocess, starts the subprocess manager thread,
-    // and exec's the child. Returns false and sets error on failure.
-    bool ForkAndExec(std::string* _Nonnull error);
-
-    // Sets up FDs, starts a thread executing command and the manager thread,
-    // Returns false and sets error on failure.
-    bool ExecInProcess(Command command, std::string* _Nonnull error);
-
-    // Start the subprocess manager thread. Consumes the subprocess, regardless of success.
-    // Returns false and sets error on failure.
-    static bool StartThread(std::unique_ptr<Subprocess> subprocess,
-                            std::string* _Nonnull error);
-
-  private:
-    // Opens the file at |pts_name|.
-    int OpenPtyChildFd(const char* pts_name, unique_fd* error_sfd);
-
-    bool ConnectProtocolEndpoints(std::string* _Nonnull error);
-
-    static void ThreadHandler(void* userdata);
-    void PassDataStreams();
-    void WaitForExit();
-
-    unique_fd* PollLoop(SubprocessPollfds* pfds);
-
-    // Input/output stream handlers. Success returns nullptr, failure returns
-    // a pointer to the failed FD.
-    unique_fd* PassInput();
-    unique_fd* PassOutput(unique_fd* sfd, ShellProtocol::Id id);
-
-    const std::string command_;
-    const std::string terminal_type_;
-    SubprocessType type_;
-    SubprocessProtocol protocol_;
-    bool make_pty_raw_;
-    pid_t pid_ = -1;
-    unique_fd local_socket_sfd_;
-
-    // Shell protocol variables.
-    unique_fd stdinout_sfd_, stderr_sfd_, protocol_sfd_;
-    std::unique_ptr<ShellProtocol> input_, output_;
-    size_t input_bytes_left_ = 0;
-
-    DISALLOW_COPY_AND_ASSIGN(Subprocess);
-};
-
-Subprocess::Subprocess(std::string command, const char* terminal_type, SubprocessType type,
-                       SubprocessProtocol protocol, bool make_pty_raw)
-    : command_(std::move(command)),
-      terminal_type_(terminal_type ? terminal_type : ""),
-      type_(type),
-      protocol_(protocol),
-      make_pty_raw_(make_pty_raw) {}
-
-Subprocess::~Subprocess() {
-    WaitForExit();
-}
-
-static std::string GetHostName() {
-    char buf[HOST_NAME_MAX];
-    if (gethostname(buf, sizeof(buf)) != -1 && strcmp(buf, "localhost") != 0) return buf;
-
-    return android::base::GetProperty("ro.product.device", "android");
-}
-
-bool Subprocess::ForkAndExec(std::string* error) {
-    unique_fd child_stdinout_sfd, child_stderr_sfd;
-    unique_fd parent_error_sfd, child_error_sfd;
-    const char* pts_name = nullptr;
-
-    if (command_.empty()) {
-        __android_log_security_bswrite(SEC_TAG_ADB_SHELL_INTERACTIVE, "");
-    } else {
-        __android_log_security_bswrite(SEC_TAG_ADB_SHELL_CMD, command_.c_str());
-    }
-
-    // Create a socketpair for the fork() child to report any errors back to the parent. Since we
-    // use threads, logging directly from the child might deadlock due to locks held in another
-    // thread during the fork.
-    if (!CreateSocketpair(&parent_error_sfd, &child_error_sfd)) {
-        *error = android::base::StringPrintf(
-            "failed to create pipe for subprocess error reporting: %s", strerror(errno));
-        return false;
-    }
-
-    // Construct the environment for the child before we fork.
-    passwd* pw = getpwuid(getuid());
-    std::unordered_map<std::string, std::string> env;
-    if (environ) {
-        char** current = environ;
-        while (char* env_cstr = *current++) {
-            std::string env_string = env_cstr;
-            char* delimiter = strchr(&env_string[0], '=');
-
-            // Drop any values that don't contain '='.
-            if (delimiter) {
-                *delimiter++ = '\0';
-                env[env_string.c_str()] = delimiter;
-            }
-        }
-    }
-
-    if (pw != nullptr) {
-        env["HOME"] = pw->pw_dir;
-        env["HOSTNAME"] = GetHostName();
-        env["LOGNAME"] = pw->pw_name;
-        env["SHELL"] = pw->pw_shell;
-        env["TMPDIR"] = "/data/local/tmp";
-        env["USER"] = pw->pw_name;
-    }
-
-    if (!terminal_type_.empty()) {
-        env["TERM"] = terminal_type_;
-    }
-
-    std::vector<std::string> joined_env;
-    for (const auto& it : env) {
-        const char* key = it.first.c_str();
-        const char* value = it.second.c_str();
-        joined_env.push_back(android::base::StringPrintf("%s=%s", key, value));
-    }
-
-    std::vector<const char*> cenv;
-    for (const std::string& str : joined_env) {
-        cenv.push_back(str.c_str());
-    }
-    cenv.push_back(nullptr);
-
-    if (type_ == SubprocessType::kPty) {
-        unique_fd pty_master(posix_openpt(O_RDWR | O_NOCTTY | O_CLOEXEC));
-        if (pty_master == -1) {
-            *error =
-                    android::base::StringPrintf("failed to create pty master: %s", strerror(errno));
-            return false;
-        }
-        if (unlockpt(pty_master.get()) != 0) {
-            *error = android::base::StringPrintf("failed to unlockpt pty master: %s",
-                                                 strerror(errno));
-            return false;
-        }
-
-        pid_ = fork();
-        pts_name = ptsname(pty_master.get());
-        if (pid_ > 0) {
-            stdinout_sfd_ = std::move(pty_master);
-        }
-    } else {
-        if (!CreateSocketpair(&stdinout_sfd_, &child_stdinout_sfd)) {
-            *error = android::base::StringPrintf("failed to create socketpair for stdin/out: %s",
-                                                 strerror(errno));
-            return false;
-        }
-        // Raw subprocess + shell protocol allows for splitting stderr.
-        if (protocol_ == SubprocessProtocol::kShell &&
-                !CreateSocketpair(&stderr_sfd_, &child_stderr_sfd)) {
-            *error = android::base::StringPrintf("failed to create socketpair for stderr: %s",
-                                                 strerror(errno));
-            return false;
-        }
-        pid_ = fork();
-    }
-
-    if (pid_ == -1) {
-        *error = android::base::StringPrintf("fork failed: %s", strerror(errno));
-        return false;
-    }
-
-    if (pid_ == 0) {
-        // Subprocess child.
-        setsid();
-
-        if (type_ == SubprocessType::kPty) {
-            child_stdinout_sfd.reset(OpenPtyChildFd(pts_name, &child_error_sfd));
-        }
-
-        dup2(child_stdinout_sfd.get(), STDIN_FILENO);
-        dup2(child_stdinout_sfd.get(), STDOUT_FILENO);
-        dup2(child_stderr_sfd != -1 ? child_stderr_sfd.get() : child_stdinout_sfd.get(),
-             STDERR_FILENO);
-
-        // exec doesn't trigger destructors, close the FDs manually.
-        stdinout_sfd_.reset(-1);
-        stderr_sfd_.reset(-1);
-        child_stdinout_sfd.reset(-1);
-        child_stderr_sfd.reset(-1);
-        parent_error_sfd.reset(-1);
-        close_on_exec(child_error_sfd);
-
-        // adbd sets SIGPIPE to SIG_IGN to get EPIPE instead, and Linux propagates that to child
-        // processes, so we need to manually reset back to SIG_DFL here (http://b/35209888).
-        signal(SIGPIPE, SIG_DFL);
-
-        // Increase oom_score_adj from -1000, so that the child is visible to the OOM-killer.
-        // Don't treat failure as an error, because old Android kernels explicitly disabled this.
-        int oom_score_adj_fd = adb_open("/proc/self/oom_score_adj", O_WRONLY | O_CLOEXEC);
-        if (oom_score_adj_fd != -1) {
-            const char* oom_score_adj_value = "-950";
-            TEMP_FAILURE_RETRY(
-                adb_write(oom_score_adj_fd, oom_score_adj_value, strlen(oom_score_adj_value)));
-        }
-
-#ifdef __ANDROID_RECOVERY__
-        // Special routine for recovery. Switch to shell domain when adbd is
-        // is running with dropped privileged (i.e. not running as root) and
-        // is built for the recovery mode. This is required because recovery
-        // rootfs is not labeled and everything is labeled just as rootfs.
-        char* con = nullptr;
-        if (getcon(&con) == 0) {
-            if (!strcmp(con, "u:r:adbd:s0")) {
-                if (selinux_android_setcon("u:r:shell:s0") < 0) {
-                    LOG(FATAL) << "Could not set SELinux context for subprocess";
-                }
-            }
-            freecon(con);
-        } else {
-            LOG(FATAL) << "Failed to get SELinux context";
-        }
-#endif
-
-        if (command_.empty()) {
-            // Spawn a login shell if we don't have a command.
-            execle(_PATH_BSHELL, "-" _PATH_BSHELL, nullptr, cenv.data());
-        } else {
-            execle(_PATH_BSHELL, _PATH_BSHELL, "-c", command_.c_str(), nullptr, cenv.data());
-        }
-        WriteFdExactly(child_error_sfd, "exec '" _PATH_BSHELL "' failed: ");
-        WriteFdExactly(child_error_sfd, strerror(errno));
-        child_error_sfd.reset(-1);
-        _Exit(1);
-    }
-
-    // Subprocess parent.
-    D("subprocess parent: stdin/stdout FD = %d, stderr FD = %d",
-      stdinout_sfd_.get(), stderr_sfd_.get());
-
-    // Wait to make sure the subprocess exec'd without error.
-    child_error_sfd.reset(-1);
-    std::string error_message = ReadAll(parent_error_sfd);
-    if (!error_message.empty()) {
-        *error = error_message;
-        return false;
-    }
-
-    D("subprocess parent: exec completed");
-    if (!ConnectProtocolEndpoints(error)) {
-        kill(pid_, SIGKILL);
-        return false;
-    }
-
-    D("subprocess parent: completed");
-    return true;
-}
-
-bool Subprocess::ExecInProcess(Command command, std::string* _Nonnull error) {
-    unique_fd child_stdinout_sfd, child_stderr_sfd;
-
-    CHECK(type_ == SubprocessType::kRaw);
-
-    __android_log_security_bswrite(SEC_TAG_ADB_SHELL_CMD, command_.c_str());
-
-    if (!CreateSocketpair(&stdinout_sfd_, &child_stdinout_sfd)) {
-        *error = android::base::StringPrintf("failed to create socketpair for stdin/out: %s",
-                                             strerror(errno));
-        return false;
-    }
-    if (protocol_ == SubprocessProtocol::kShell) {
-        // Shell protocol allows for splitting stderr.
-        if (!CreateSocketpair(&stderr_sfd_, &child_stderr_sfd)) {
-            *error = android::base::StringPrintf("failed to create socketpair for stderr: %s",
-                                                 strerror(errno));
-            return false;
-        }
-    } else {
-        // Raw protocol doesn't support multiple output streams, so combine stdout and stderr.
-        child_stderr_sfd.reset(dup(child_stdinout_sfd.get()));
-    }
-
-    D("execinprocess: stdin/stdout FD = %d, stderr FD = %d", stdinout_sfd_.get(),
-      stderr_sfd_.get());
-
-    if (!ConnectProtocolEndpoints(error)) {
-        return false;
-    }
-
-    std::thread([inout_sfd = std::move(child_stdinout_sfd), err_sfd = std::move(child_stderr_sfd),
-                 command = std::move(command),
-                 args = command_]() { command(args, inout_sfd, inout_sfd, err_sfd); })
-            .detach();
-
-    D("execinprocess: completed");
-    return true;
-}
-
-bool Subprocess::ConnectProtocolEndpoints(std::string* _Nonnull error) {
-    if (protocol_ == SubprocessProtocol::kNone) {
-        // No protocol: all streams pass through the stdinout FD and hook
-        // directly into the local socket for raw data transfer.
-        local_socket_sfd_.reset(stdinout_sfd_.release());
-    } else {
-        // Required for shell protocol: create another socketpair to intercept data.
-        if (!CreateSocketpair(&protocol_sfd_, &local_socket_sfd_)) {
-            *error = android::base::StringPrintf(
-                    "failed to create socketpair to intercept data: %s", strerror(errno));
-            return false;
-        }
-        D("protocol FD = %d", protocol_sfd_.get());
-
-        input_ = std::make_unique<ShellProtocol>(protocol_sfd_);
-        output_ = std::make_unique<ShellProtocol>(protocol_sfd_);
-        if (!input_ || !output_) {
-            *error = "failed to allocate shell protocol objects";
-            return false;
-        }
-
-        // Don't let reads/writes to the subprocess block our thread. This isn't
-        // likely but could happen under unusual circumstances, such as if we
-        // write a ton of data to stdin but the subprocess never reads it and
-        // the pipe fills up.
-        for (int fd : {stdinout_sfd_.get(), stderr_sfd_.get()}) {
-            if (fd >= 0) {
-                if (!set_file_block_mode(fd, false)) {
-                    *error = android::base::StringPrintf(
-                            "failed to set non-blocking mode for fd %d", fd);
-                    return false;
-                }
-            }
-        }
-    }
-
-    return true;
-}
-
-bool Subprocess::StartThread(std::unique_ptr<Subprocess> subprocess, std::string* error) {
-    Subprocess* raw = subprocess.release();
-    std::thread(ThreadHandler, raw).detach();
-
-    return true;
-}
-
-int Subprocess::OpenPtyChildFd(const char* pts_name, unique_fd* error_sfd) {
-    int child_fd = adb_open(pts_name, O_RDWR | O_CLOEXEC);
-    if (child_fd == -1) {
-        // Don't use WriteFdFmt; since we're in the fork() child we don't want
-        // to allocate any heap memory to avoid race conditions.
-        const char* messages[] = {"child failed to open pseudo-term slave ",
-                                  pts_name, ": ", strerror(errno)};
-        for (const char* message : messages) {
-            WriteFdExactly(*error_sfd, message);
-        }
-        abort();
-    }
-
-    if (make_pty_raw_) {
-        termios tattr;
-        if (tcgetattr(child_fd, &tattr) == -1) {
-            int saved_errno = errno;
-            WriteFdExactly(*error_sfd, "tcgetattr failed: ");
-            WriteFdExactly(*error_sfd, strerror(saved_errno));
-            abort();
-        }
-
-        cfmakeraw(&tattr);
-        if (tcsetattr(child_fd, TCSADRAIN, &tattr) == -1) {
-            int saved_errno = errno;
-            WriteFdExactly(*error_sfd, "tcsetattr failed: ");
-            WriteFdExactly(*error_sfd, strerror(saved_errno));
-            abort();
-        }
-    }
-
-    return child_fd;
-}
-
-void Subprocess::ThreadHandler(void* userdata) {
-    Subprocess* subprocess = reinterpret_cast<Subprocess*>(userdata);
-
-    adb_thread_setname(android::base::StringPrintf("shell svc %d", subprocess->pid()));
-
-    D("passing data streams for PID %d", subprocess->pid());
-    subprocess->PassDataStreams();
-
-    D("deleting Subprocess for PID %d", subprocess->pid());
-    delete subprocess;
-}
-
-void Subprocess::PassDataStreams() {
-    if (protocol_sfd_ == -1) {
-        return;
-    }
-
-    // Start by trying to read from the protocol FD, stdout, and stderr.
-    SubprocessPollfds pfds;
-    pfds.stdinout_pfd() = {.fd = stdinout_sfd_.get(), .events = POLLIN};
-    pfds.stderr_pfd() = {.fd = stderr_sfd_.get(), .events = POLLIN};
-    pfds.protocol_pfd() = {.fd = protocol_sfd_.get(), .events = POLLIN};
-
-    // Pass data until the protocol FD or both the subprocess pipes die, at
-    // which point we can't pass any more data.
-    while (protocol_sfd_ != -1 && (stdinout_sfd_ != -1 || stderr_sfd_ != -1)) {
-        unique_fd* dead_sfd = PollLoop(&pfds);
-        if (dead_sfd) {
-            D("closing FD %d", dead_sfd->get());
-            auto it = std::find_if(pfds.begin(), pfds.end(), [=](const adb_pollfd& pfd) {
-                return pfd.fd == dead_sfd->get();
-            });
-            CHECK(it != pfds.end());
-            it->fd = -1;
-            it->events = 0;
-            if (dead_sfd == &protocol_sfd_) {
-                // Using SIGHUP is a decent general way to indicate that the
-                // controlling process is going away. If specific signals are
-                // needed (e.g. SIGINT), pass those through the shell protocol
-                // and only fall back on this for unexpected closures.
-                D("protocol FD died, sending SIGHUP to pid %d", pid_);
-                if (pid_ != -1) {
-                    kill(pid_, SIGHUP);
-                }
-
-                // We also need to close the pipes connected to the child process
-                // so that if it ignores SIGHUP and continues to write data it
-                // won't fill up the pipe and block.
-                stdinout_sfd_.reset();
-                stderr_sfd_.reset();
-            }
-            dead_sfd->reset();
-        }
-    }
-}
-
-unique_fd* Subprocess::PollLoop(SubprocessPollfds* pfds) {
-    unique_fd* dead_sfd = nullptr;
-    adb_pollfd& stdinout_pfd = pfds->stdinout_pfd();
-    adb_pollfd& stderr_pfd = pfds->stderr_pfd();
-    adb_pollfd& protocol_pfd = pfds->protocol_pfd();
-
-    // Keep calling poll() and passing data until an FD closes/errors.
-    while (!dead_sfd) {
-        if (adb_poll(pfds->data(), pfds->size(), -1) < 0) {
-            if (errno == EINTR) {
-                continue;
-            } else {
-                PLOG(ERROR) << "poll failed, closing subprocess pipes";
-                stdinout_sfd_.reset(-1);
-                stderr_sfd_.reset(-1);
-                return nullptr;
-            }
-        }
-
-        // Read stdout, write to protocol FD.
-        if (stdinout_pfd.fd != -1 && (stdinout_pfd.revents & POLLIN)) {
-            dead_sfd = PassOutput(&stdinout_sfd_, ShellProtocol::kIdStdout);
-        }
-
-        // Read stderr, write to protocol FD.
-        if (!dead_sfd && stderr_pfd.fd != 1 && (stderr_pfd.revents & POLLIN)) {
-            dead_sfd = PassOutput(&stderr_sfd_, ShellProtocol::kIdStderr);
-        }
-
-        // Read protocol FD, write to stdin.
-        if (!dead_sfd && protocol_pfd.fd != -1 && (protocol_pfd.revents & POLLIN)) {
-            dead_sfd = PassInput();
-            // If we didn't finish writing, block on stdin write.
-            if (input_bytes_left_) {
-                protocol_pfd.events &= ~POLLIN;
-                stdinout_pfd.events |= POLLOUT;
-            }
-        }
-
-        // Continue writing to stdin; only happens if a previous write blocked.
-        if (!dead_sfd && stdinout_pfd.fd != -1 && (stdinout_pfd.revents & POLLOUT)) {
-            dead_sfd = PassInput();
-            // If we finished writing, go back to blocking on protocol read.
-            if (!input_bytes_left_) {
-                protocol_pfd.events |= POLLIN;
-                stdinout_pfd.events &= ~POLLOUT;
-            }
-        }
-
-        // After handling all of the events we've received, check to see if any fds have died.
-        if (stdinout_pfd.revents & (POLLHUP | POLLRDHUP | POLLERR | POLLNVAL)) {
-            return &stdinout_sfd_;
-        }
-
-        if (stderr_pfd.revents & (POLLHUP | POLLRDHUP | POLLERR | POLLNVAL)) {
-            return &stderr_sfd_;
-        }
-
-        if (protocol_pfd.revents & (POLLHUP | POLLRDHUP | POLLERR | POLLNVAL)) {
-            return &protocol_sfd_;
-        }
-    }  // while (!dead_sfd)
-
-    return dead_sfd;
-}
-
-unique_fd* Subprocess::PassInput() {
-    // Only read a new packet if we've finished writing the last one.
-    if (!input_bytes_left_) {
-        if (!input_->Read()) {
-            // Read() uses ReadFdExactly() which sets errno to 0 on EOF.
-            if (errno != 0) {
-                PLOG(ERROR) << "error reading protocol FD " << protocol_sfd_.get();
-            }
-            return &protocol_sfd_;
-        }
-
-        if (stdinout_sfd_ != -1) {
-            switch (input_->id()) {
-                case ShellProtocol::kIdWindowSizeChange:
-                    int rows, cols, x_pixels, y_pixels;
-                    if (sscanf(input_->data(), "%dx%d,%dx%d",
-                               &rows, &cols, &x_pixels, &y_pixels) == 4) {
-                        winsize ws;
-                        ws.ws_row = rows;
-                        ws.ws_col = cols;
-                        ws.ws_xpixel = x_pixels;
-                        ws.ws_ypixel = y_pixels;
-                        ioctl(stdinout_sfd_.get(), TIOCSWINSZ, &ws);
-                    }
-                    break;
-                case ShellProtocol::kIdStdin:
-                    input_bytes_left_ = input_->data_length();
-                    break;
-                case ShellProtocol::kIdCloseStdin:
-                    if (type_ == SubprocessType::kRaw) {
-                        if (adb_shutdown(stdinout_sfd_, SHUT_WR) == 0) {
-                            return nullptr;
-                        }
-                        PLOG(ERROR) << "failed to shutdown writes to FD " << stdinout_sfd_.get();
-                        return &stdinout_sfd_;
-                    } else {
-                        // PTYs can't close just input, so rather than close the
-                        // FD and risk losing subprocess output, leave it open.
-                        // This only happens if the client starts a PTY shell
-                        // non-interactively which is rare and unsupported.
-                        // If necessary, the client can manually close the shell
-                        // with `exit` or by killing the adb client process.
-                        D("can't close input for PTY FD %d", stdinout_sfd_.get());
-                    }
-                    break;
-            }
-        }
-    }
-
-    if (input_bytes_left_ > 0) {
-        int index = input_->data_length() - input_bytes_left_;
-        int bytes = adb_write(stdinout_sfd_, input_->data() + index, input_bytes_left_);
-        if (bytes == 0 || (bytes < 0 && errno != EAGAIN)) {
-            if (bytes < 0) {
-                PLOG(ERROR) << "error reading stdin FD " << stdinout_sfd_.get();
-            }
-            // stdin is done, mark this packet as finished and we'll just start
-            // dumping any further data received from the protocol FD.
-            input_bytes_left_ = 0;
-            return &stdinout_sfd_;
-        } else if (bytes > 0) {
-            input_bytes_left_ -= bytes;
-        }
-    }
-
-    return nullptr;
-}
-
-unique_fd* Subprocess::PassOutput(unique_fd* sfd, ShellProtocol::Id id) {
-    int bytes = adb_read(*sfd, output_->data(), output_->data_capacity());
-    if (bytes == 0 || (bytes < 0 && errno != EAGAIN)) {
-        // read() returns EIO if a PTY closes; don't report this as an error,
-        // it just means the subprocess completed.
-        if (bytes < 0 && !(type_ == SubprocessType::kPty && errno == EIO)) {
-            PLOG(ERROR) << "error reading output FD " << sfd->get();
-        }
-        return sfd;
-    }
-
-    if (bytes > 0 && !output_->Write(id, bytes)) {
-        if (errno != 0) {
-            PLOG(ERROR) << "error reading protocol FD " << protocol_sfd_.get();
-        }
-        return &protocol_sfd_;
-    }
-
-    return nullptr;
-}
-
-void Subprocess::WaitForExit() {
-    int exit_code = 1;
-
-    D("waiting for pid %d", pid_);
-    while (pid_ != -1) {
-        int status;
-        if (pid_ == waitpid(pid_, &status, 0)) {
-            D("post waitpid (pid=%d) status=%04x", pid_, status);
-            if (WIFSIGNALED(status)) {
-                exit_code = 0x80 | WTERMSIG(status);
-                ADB_LOG(Shell) << "subprocess " << pid_ << " killed by signal " << WTERMSIG(status);
-                break;
-            } else if (!WIFEXITED(status)) {
-                D("subprocess didn't exit");
-                break;
-            } else if (WEXITSTATUS(status) >= 0) {
-                exit_code = WEXITSTATUS(status);
-                ADB_LOG(Shell) << "subprocess " << pid_ << " exited with status " << exit_code;
-                break;
-            }
-        }
-    }
-
-    // If we have an open protocol FD send an exit packet.
-    if (protocol_sfd_ != -1) {
-        output_->data()[0] = exit_code;
-        if (output_->Write(ShellProtocol::kIdExit, 1)) {
-            D("wrote the exit code packet: %d", exit_code);
-        } else {
-            PLOG(ERROR) << "failed to write the exit code packet";
-        }
-        protocol_sfd_.reset(-1);
-    }
-}
-
-}  // namespace
-
-// Create a pipe containing the error.
-unique_fd ReportError(SubprocessProtocol protocol, const std::string& message) {
-    unique_fd read, write;
-    if (!Pipe(&read, &write)) {
-        PLOG(ERROR) << "failed to create pipe to report error";
-        return unique_fd{};
-    }
-
-    std::string buf = android::base::StringPrintf("error: %s\n", message.c_str());
-    if (protocol == SubprocessProtocol::kShell) {
-        ShellProtocol::Id id = ShellProtocol::kIdStderr;
-        uint32_t length = buf.length();
-        WriteFdExactly(write.get(), &id, sizeof(id));
-        WriteFdExactly(write.get(), &length, sizeof(length));
-    }
-
-    WriteFdExactly(write.get(), buf.data(), buf.length());
-
-    if (protocol == SubprocessProtocol::kShell) {
-        ShellProtocol::Id id = ShellProtocol::kIdExit;
-        uint32_t length = 1;
-        char exit_code = 126;
-        WriteFdExactly(write.get(), &id, sizeof(id));
-        WriteFdExactly(write.get(), &length, sizeof(length));
-        WriteFdExactly(write.get(), &exit_code, sizeof(exit_code));
-    }
-
-    return read;
-}
-
-unique_fd StartSubprocess(std::string name, const char* terminal_type, SubprocessType type,
-                          SubprocessProtocol protocol) {
-    // If we aren't using the shell protocol we must allocate a PTY to properly close the
-    // subprocess. PTYs automatically send SIGHUP to the slave-side process when the master side
-    // of the PTY closes, which we rely on. If we use a raw pipe, processes that don't read/write,
-    // e.g. screenrecord, will never notice the broken pipe and terminate.
-    // The shell protocol doesn't require a PTY because it's always monitoring the local socket FD
-    // with select() and will send SIGHUP manually to the child process.
-    bool make_pty_raw = false;
-    if (protocol == SubprocessProtocol::kNone && type == SubprocessType::kRaw) {
-        // Disable PTY input/output processing since the client is expecting raw data.
-        D("Can't create raw subprocess without shell protocol, using PTY in raw mode instead");
-        type = SubprocessType::kPty;
-        make_pty_raw = true;
-    }
-
-    unique_fd error_fd;
-    unique_fd fd = StartSubprocess(std::move(name), terminal_type, type, protocol, make_pty_raw,
-                                   protocol, &error_fd);
-    if (fd == -1) {
-        return error_fd;
-    }
-    return fd;
-}
-
-unique_fd StartSubprocess(std::string name, const char* terminal_type, SubprocessType type,
-                          SubprocessProtocol protocol, bool make_pty_raw,
-                          SubprocessProtocol error_protocol, unique_fd* error_fd) {
-    D("starting %s subprocess (protocol=%s, TERM=%s): '%s'",
-      type == SubprocessType::kRaw ? "raw" : "PTY",
-      protocol == SubprocessProtocol::kNone ? "none" : "shell", terminal_type, name.c_str());
-
-    auto subprocess = std::make_unique<Subprocess>(std::move(name), terminal_type, type, protocol,
-                                                   make_pty_raw);
-    if (!subprocess) {
-        LOG(ERROR) << "failed to allocate new subprocess";
-        *error_fd = ReportError(error_protocol, "failed to allocate new subprocess");
-        return {};
-    }
-
-    std::string error;
-    if (!subprocess->ForkAndExec(&error)) {
-        LOG(ERROR) << "failed to start subprocess: " << error;
-        *error_fd = ReportError(error_protocol, error);
-        return {};
-    }
-
-    unique_fd local_socket(subprocess->ReleaseLocalSocket());
-    D("subprocess creation successful: local_socket_fd=%d, pid=%d", local_socket.get(),
-      subprocess->pid());
-
-    if (!Subprocess::StartThread(std::move(subprocess), &error)) {
-        LOG(ERROR) << "failed to start subprocess management thread: " << error;
-        *error_fd = ReportError(error_protocol, error);
-        return {};
-    }
-
-    return local_socket;
-}
-
-unique_fd StartCommandInProcess(std::string name, Command command, SubprocessProtocol protocol) {
-    LOG(INFO) << "StartCommandInProcess(" << dump_hex(name.data(), name.size()) << ")";
-
-    constexpr auto terminal_type = "";
-    constexpr auto type = SubprocessType::kRaw;
-    constexpr auto make_pty_raw = false;
-
-    auto subprocess = std::make_unique<Subprocess>(std::move(name), terminal_type, type, protocol,
-                                                   make_pty_raw);
-    if (!subprocess) {
-        LOG(ERROR) << "failed to allocate new subprocess";
-        return ReportError(protocol, "failed to allocate new subprocess");
-    }
-
-    std::string error;
-    if (!subprocess->ExecInProcess(std::move(command), &error)) {
-        LOG(ERROR) << "failed to start subprocess: " << error;
-        return ReportError(protocol, error);
-    }
-
-    unique_fd local_socket(subprocess->ReleaseLocalSocket());
-    D("inprocess creation successful: local_socket_fd=%d, pid=%d", local_socket.get(),
-      subprocess->pid());
-
-    if (!Subprocess::StartThread(std::move(subprocess), &error)) {
-        LOG(ERROR) << "failed to start inprocess management thread: " << error;
-        return ReportError(protocol, error);
-    }
-
-    return local_socket;
-}
diff --git a/adb/daemon/shell_service.h b/adb/daemon/shell_service.h
deleted file mode 100644
index 030228c..0000000
--- a/adb/daemon/shell_service.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <string>
-
-#include "adb_unique_fd.h"
-
-#include <string_view>
-
-enum class SubprocessType {
-    kPty,
-    kRaw,
-};
-
-enum class SubprocessProtocol {
-    kNone,
-    kShell,
-};
-
-// Forks and starts a new shell subprocess. If |name| is empty an interactive
-// shell is started, otherwise |name| is executed non-interactively.
-//
-// Returns an open FD connected to the subprocess or -1 on failure.
-unique_fd StartSubprocess(std::string name, const char* terminal_type, SubprocessType type,
-                          SubprocessProtocol protocol);
-
-// The same as above but with more fined grained control and custom error handling.
-unique_fd StartSubprocess(std::string name, const char* terminal_type, SubprocessType type,
-                          SubprocessProtocol protocol, bool make_pty_raw,
-                          SubprocessProtocol error_protocol, unique_fd* error_fd);
-
-// Executes |command| in a separate thread.
-// Sets up in/out and error streams to emulate shell-like behavior.
-//
-// Returns an open FD connected to the thread or -1 on failure.
-using Command = int(std::string_view args, borrowed_fd in, borrowed_fd out, borrowed_fd err);
-unique_fd StartCommandInProcess(std::string name, Command command, SubprocessProtocol protocol);
-
-// Create a pipe containing the error.
-unique_fd ReportError(SubprocessProtocol protocol, const std::string& message);
diff --git a/adb/daemon/shell_service_test.cpp b/adb/daemon/shell_service_test.cpp
deleted file mode 100644
index cdd8dbe..0000000
--- a/adb/daemon/shell_service_test.cpp
+++ /dev/null
@@ -1,320 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "shell_service.h"
-
-#include <gtest/gtest.h>
-
-#include <signal.h>
-
-#include <string>
-#include <vector>
-
-#include <android-base/strings.h>
-
-#include "adb.h"
-#include "adb_io.h"
-#include "shell_protocol.h"
-#include "sysdeps.h"
-
-class ShellServiceTest : public ::testing::Test {
-  public:
-    static void SetUpTestCase() {
-        // This is normally done in main.cpp.
-        saved_sigpipe_handler_ = signal(SIGPIPE, SIG_IGN);
-    }
-
-    static void TearDownTestCase() {
-        signal(SIGPIPE, saved_sigpipe_handler_);
-    }
-
-    // Helpers to start and cleanup a subprocess. Cleanup normally does not
-    // need to be called manually unless multiple subprocesses are run from
-    // a single test.
-    void StartTestSubprocess(const char* command, SubprocessType type,
-                             SubprocessProtocol protocol);
-    void CleanupTestSubprocess();
-
-    void StartTestCommandInProcess(std::string name, Command command, SubprocessProtocol protocol);
-
-    virtual void TearDown() override { CleanupTestSubprocess(); }
-
-    static sighandler_t saved_sigpipe_handler_;
-
-    unique_fd command_fd_;
-};
-
-sighandler_t ShellServiceTest::saved_sigpipe_handler_ = nullptr;
-
-void ShellServiceTest::StartTestSubprocess(
-        const char* command, SubprocessType type, SubprocessProtocol protocol) {
-    command_fd_ = StartSubprocess(command, nullptr, type, protocol);
-    ASSERT_TRUE(command_fd_ >= 0);
-}
-
-void ShellServiceTest::CleanupTestSubprocess() {
-}
-
-void ShellServiceTest::StartTestCommandInProcess(std::string name, Command command,
-                                                 SubprocessProtocol protocol) {
-    command_fd_ = StartCommandInProcess(std::move(name), std::move(command), protocol);
-    ASSERT_TRUE(command_fd_ >= 0);
-}
-
-namespace {
-
-// Reads raw data from |fd| until it closes or errors.
-std::string ReadRaw(borrowed_fd fd) {
-    char buffer[1024];
-    char *cur_ptr = buffer, *end_ptr = buffer + sizeof(buffer);
-
-    while (1) {
-        int bytes = adb_read(fd, cur_ptr, end_ptr - cur_ptr);
-        if (bytes <= 0) {
-            return std::string(buffer, cur_ptr);
-        }
-        cur_ptr += bytes;
-    }
-}
-
-// Reads shell protocol data from |fd| until it closes or errors. Fills
-// |stdout| and |stderr| with their respective data, and returns the exit code
-// read from the protocol or -1 if an exit code packet was not received.
-int ReadShellProtocol(borrowed_fd fd, std::string* stdout, std::string* stderr) {
-    int exit_code = -1;
-    stdout->clear();
-    stderr->clear();
-
-    auto protocol = std::make_unique<ShellProtocol>(fd.get());
-    while (protocol->Read()) {
-        switch (protocol->id()) {
-            case ShellProtocol::kIdStdout:
-                stdout->append(protocol->data(), protocol->data_length());
-                break;
-            case ShellProtocol::kIdStderr:
-                stderr->append(protocol->data(), protocol->data_length());
-                break;
-            case ShellProtocol::kIdExit:
-                EXPECT_EQ(-1, exit_code) << "Multiple exit packets received";
-                EXPECT_EQ(1u, protocol->data_length());
-                exit_code = protocol->data()[0];
-                break;
-            default:
-                ADD_FAILURE() << "Unidentified packet ID: " << protocol->id();
-        }
-    }
-
-    return exit_code;
-}
-
-// Checks if each line in |lines| exists in the same order in |output|. Blank
-// lines in |output| are ignored for simplicity.
-bool ExpectLinesEqual(const std::string& output,
-                      const std::vector<std::string>& lines) {
-    auto output_lines = android::base::Split(output, "\r\n");
-    size_t i = 0;
-
-    for (const std::string& line : lines) {
-        // Skip empty lines in output.
-        while (i < output_lines.size() && output_lines[i].empty()) {
-            ++i;
-        }
-        if (i >= output_lines.size()) {
-            ADD_FAILURE() << "Ran out of output lines";
-            return false;
-        }
-        EXPECT_EQ(line, output_lines[i]);
-        ++i;
-    }
-
-    while (i < output_lines.size() && output_lines[i].empty()) {
-        ++i;
-    }
-    EXPECT_EQ(i, output_lines.size()) << "Found unmatched output lines";
-    return true;
-}
-
-}  // namespace
-
-// Tests a raw subprocess with no protocol.
-TEST_F(ShellServiceTest, RawNoProtocolSubprocess) {
-    // [ -t 0 ] checks if stdin is connected to a terminal.
-    ASSERT_NO_FATAL_FAILURE(StartTestSubprocess(
-            "echo foo; echo bar >&2; [ -t 0 ]; echo $?",
-            SubprocessType::kRaw, SubprocessProtocol::kNone));
-
-    // [ -t 0 ] == 0 means we have a terminal (PTY). Even when requesting a raw subprocess, without
-    // the shell protocol we should always force a PTY to ensure proper cleanup.
-    ExpectLinesEqual(ReadRaw(command_fd_), {"foo", "bar", "0"});
-}
-
-// Tests a PTY subprocess with no protocol.
-TEST_F(ShellServiceTest, PtyNoProtocolSubprocess) {
-    // [ -t 0 ] checks if stdin is connected to a terminal.
-    ASSERT_NO_FATAL_FAILURE(StartTestSubprocess(
-            "echo foo; echo bar >&2; [ -t 0 ]; echo $?",
-            SubprocessType::kPty, SubprocessProtocol::kNone));
-
-    // [ -t 0 ] == 0 means we have a terminal (PTY).
-    ExpectLinesEqual(ReadRaw(command_fd_), {"foo", "bar", "0"});
-}
-
-// Tests a raw subprocess with the shell protocol.
-TEST_F(ShellServiceTest, RawShellProtocolSubprocess) {
-    ASSERT_NO_FATAL_FAILURE(StartTestSubprocess(
-            "echo foo; echo bar >&2; echo baz; exit 24",
-            SubprocessType::kRaw, SubprocessProtocol::kShell));
-
-    std::string stdout, stderr;
-    EXPECT_EQ(24, ReadShellProtocol(command_fd_, &stdout, &stderr));
-    ExpectLinesEqual(stdout, {"foo", "baz"});
-    ExpectLinesEqual(stderr, {"bar"});
-}
-
-// Tests a PTY subprocess with the shell protocol.
-TEST_F(ShellServiceTest, PtyShellProtocolSubprocess) {
-    ASSERT_NO_FATAL_FAILURE(StartTestSubprocess(
-            "echo foo; echo bar >&2; echo baz; exit 50",
-            SubprocessType::kPty, SubprocessProtocol::kShell));
-
-    // PTY always combines stdout and stderr but the shell protocol should
-    // still give us an exit code.
-    std::string stdout, stderr;
-    EXPECT_EQ(50, ReadShellProtocol(command_fd_, &stdout, &stderr));
-    ExpectLinesEqual(stdout, {"foo", "bar", "baz"});
-    ExpectLinesEqual(stderr, {});
-}
-
-// Tests an interactive PTY session.
-TEST_F(ShellServiceTest, InteractivePtySubprocess) {
-    ASSERT_NO_FATAL_FAILURE(StartTestSubprocess(
-            "", SubprocessType::kPty, SubprocessProtocol::kShell));
-
-    // Use variable substitution so echoed input is different from output.
-    const char* commands[] = {"TEST_STR=abc123",
-                              "echo --${TEST_STR}--",
-                              "exit"};
-
-    ShellProtocol* protocol = new ShellProtocol(command_fd_);
-    for (std::string command : commands) {
-        // Interactive shell requires a newline to complete each command.
-        command.push_back('\n');
-        memcpy(protocol->data(), command.data(), command.length());
-        ASSERT_TRUE(protocol->Write(ShellProtocol::kIdStdin, command.length()));
-    }
-    delete protocol;
-
-    std::string stdout, stderr;
-    EXPECT_EQ(0, ReadShellProtocol(command_fd_, &stdout, &stderr));
-    // An unpredictable command prompt makes parsing exact output difficult but
-    // it should at least contain echoed input and the expected output.
-    for (const char* command : commands) {
-        EXPECT_FALSE(stdout.find(command) == std::string::npos);
-    }
-    EXPECT_FALSE(stdout.find("--abc123--") == std::string::npos);
-}
-
-// Tests closing raw subprocess stdin.
-TEST_F(ShellServiceTest, CloseClientStdin) {
-    ASSERT_NO_FATAL_FAILURE(StartTestSubprocess(
-            "cat; echo TEST_DONE",
-            SubprocessType::kRaw, SubprocessProtocol::kShell));
-
-    std::string input = "foo\nbar";
-    ShellProtocol* protocol = new ShellProtocol(command_fd_);
-    memcpy(protocol->data(), input.data(), input.length());
-    ASSERT_TRUE(protocol->Write(ShellProtocol::kIdStdin, input.length()));
-    ASSERT_TRUE(protocol->Write(ShellProtocol::kIdCloseStdin, 0));
-    delete protocol;
-
-    std::string stdout, stderr;
-    EXPECT_EQ(0, ReadShellProtocol(command_fd_, &stdout, &stderr));
-    ExpectLinesEqual(stdout, {"foo", "barTEST_DONE"});
-    ExpectLinesEqual(stderr, {});
-}
-
-// Tests that nothing breaks when the stdin/stdout pipe closes.
-TEST_F(ShellServiceTest, CloseStdinStdoutSubprocess) {
-    ASSERT_NO_FATAL_FAILURE(StartTestSubprocess(
-            "exec 0<&-; exec 1>&-; echo bar >&2",
-            SubprocessType::kRaw, SubprocessProtocol::kShell));
-
-    std::string stdout, stderr;
-    EXPECT_EQ(0, ReadShellProtocol(command_fd_, &stdout, &stderr));
-    ExpectLinesEqual(stdout, {});
-    ExpectLinesEqual(stderr, {"bar"});
-}
-
-// Tests that nothing breaks when the stderr pipe closes.
-TEST_F(ShellServiceTest, CloseStderrSubprocess) {
-    ASSERT_NO_FATAL_FAILURE(StartTestSubprocess(
-            "exec 2>&-; echo foo",
-            SubprocessType::kRaw, SubprocessProtocol::kShell));
-
-    std::string stdout, stderr;
-    EXPECT_EQ(0, ReadShellProtocol(command_fd_, &stdout, &stderr));
-    ExpectLinesEqual(stdout, {"foo"});
-    ExpectLinesEqual(stderr, {});
-}
-
-// Tests an inprocess command with no protocol.
-TEST_F(ShellServiceTest, RawNoProtocolInprocess) {
-    ASSERT_NO_FATAL_FAILURE(
-            StartTestCommandInProcess("123",
-                                      [](auto args, auto in, auto out, auto err) -> int {
-                                          EXPECT_EQ("123", args);
-                                          char input[10];
-                                          EXPECT_TRUE(ReadFdExactly(in, input, 2));
-                                          input[2] = 0;
-                                          EXPECT_STREQ("in", input);
-                                          WriteFdExactly(out, "out\n");
-                                          WriteFdExactly(err, "err\n");
-                                          return 0;
-                                      },
-                                      SubprocessProtocol::kNone));
-
-    WriteFdExactly(command_fd_, "in");
-    ExpectLinesEqual(ReadRaw(command_fd_), {"out", "err"});
-}
-
-// Tests an inprocess command with the shell protocol.
-TEST_F(ShellServiceTest, RawShellProtocolInprocess) {
-    ASSERT_NO_FATAL_FAILURE(
-            StartTestCommandInProcess("321",
-                                      [](auto args, auto in, auto out, auto err) -> int {
-                                          EXPECT_EQ("321", args);
-                                          char input[10];
-                                          EXPECT_TRUE(ReadFdExactly(in, input, 2));
-                                          input[2] = 0;
-                                          EXPECT_STREQ("in", input);
-                                          WriteFdExactly(out, "out\n");
-                                          WriteFdExactly(err, "err\n");
-                                          return 0;
-                                      },
-                                      SubprocessProtocol::kShell));
-
-    {
-        auto write_protocol = std::make_unique<ShellProtocol>(command_fd_);
-        memcpy(write_protocol->data(), "in", 2);
-        write_protocol->Write(ShellProtocol::kIdStdin, 2);
-    }
-
-    std::string stdout, stderr;
-    // For in-process commands the exit code is always the default (1).
-    EXPECT_EQ(1, ReadShellProtocol(command_fd_, &stdout, &stderr));
-    ExpectLinesEqual(stdout, {"out"});
-    ExpectLinesEqual(stderr, {"err"});
-}
diff --git a/adb/daemon/transport_qemu.cpp b/adb/daemon/transport_qemu.cpp
deleted file mode 100644
index e458cea..0000000
--- a/adb/daemon/transport_qemu.cpp
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-// Include qemu_pipe.h before sysdeps, since it has inlined references to open, read, write.
-#include <qemu_pipe.h>
-
-#define TRACE_TAG TRANSPORT
-#include "socket_spec.h"
-#include "sysdeps.h"
-#include "transport.h"
-
-#include <android-base/properties.h>
-
-#include "adb_io.h"
-#include "adb_trace.h"
-#include "adb_unique_fd.h"
-
-/* A worker thread that monitors host connections, and registers a transport for
- * every new host connection. This thread replaces server_socket_thread on
- * condition that adbd daemon runs inside the emulator, and emulator uses QEMUD
- * pipe to communicate with adbd daemon inside the guest. This is done in order
- * to provide more robust communication channel between ADB host and guest. The
- * main issue with server_socket_thread approach is that it runs on top of TCP,
- * and thus is sensitive to network disruptions. For instance, the
- * ConnectionManager may decide to reset all network connections, in which case
- * the connection between ADB host and guest will be lost. To make ADB traffic
- * independent from the network, we use here 'adb' QEMUD service to transfer data
- * between the host, and the guest. See external/qemu/android/adb-*.* that
- * implements the emulator's side of the protocol. Another advantage of using
- * QEMUD approach is that ADB will be up much sooner, since it doesn't depend
- * anymore on network being set up.
- * The guest side of the protocol contains the following phases:
- * - Connect with adb QEMUD service. In this phase a handle to 'adb' QEMUD service
- *   is opened, and it becomes clear whether or not emulator supports that
- *   protocol.
- * - Wait for the ADB host to create connection with the guest. This is done by
- *   sending an 'accept' request to the adb QEMUD service, and waiting on
- *   response.
- * - When new ADB host connection is accepted, the connection with adb QEMUD
- *   service is registered as the transport, and a 'start' request is sent to the
- *   adb QEMUD service, indicating that the guest is ready to receive messages.
- *   Note that the guest will ignore messages sent down from the emulator before
- *   the transport registration is completed. That's why we need to send the
- *   'start' request after the transport is registered.
- */
-void qemu_socket_thread(std::string_view addr) {
-    /* 'accept' request to the adb QEMUD service. */
-    static const char _accept_req[] = "accept";
-    /* 'start' request to the adb QEMUD service. */
-    static const char _start_req[] = "start";
-    /* 'ok' reply from the adb QEMUD service. */
-    static const char _ok_resp[] = "ok";
-
-    char tmp[256];
-    char con_name[32];
-
-    adb_thread_setname("qemu socket");
-    D("transport: qemu_socket_thread() starting");
-
-    std::string error;
-    int port = get_host_socket_spec_port(addr, &error);
-    if (port == -1) {
-        port = DEFAULT_ADB_LOCAL_TRANSPORT_PORT;
-    }
-
-    /* adb QEMUD service connection request. */
-    snprintf(con_name, sizeof(con_name), "pipe:qemud:adb:%d", port);
-
-    /* Connect to the adb QEMUD service. */
-    unique_fd fd(qemu_pipe_open(con_name));
-    if (fd < 0) {
-        /* This could be an older version of the emulator, that doesn't
-         * implement adb QEMUD service. Fall back to the old TCP way. */
-        D("adb service is not available. Falling back to TCP socket.");
-        std::thread(server_socket_thread, adb_listen, addr).detach();
-        return;
-    }
-
-    while (true) {
-        /*
-         * Wait till the host creates a new connection.
-         */
-
-        /* Send the 'accept' request. */
-        if (WriteFdExactly(fd.get(), _accept_req, strlen(_accept_req))) {
-            /* Wait for the response. In the response we expect 'ok' on success,
-             * or 'ko' on failure. */
-            if (!ReadFdExactly(fd.get(), tmp, 2) || memcmp(tmp, _ok_resp, 2)) {
-                D("Accepting ADB host connection has failed.");
-            } else {
-                /* Host is connected. Register the transport, and start the
-                 * exchange. */
-                std::string serial = android::base::StringPrintf("host-%d", fd.get());
-                WriteFdExactly(fd.get(), _start_req, strlen(_start_req));
-                register_socket_transport(
-                        std::move(fd), std::move(serial), port, 1,
-                        [](atransport*) { return ReconnectResult::Abort; }, false);
-            }
-
-            /* Prepare for accepting of the next ADB host connection. */
-            fd.reset(qemu_pipe_open(con_name));
-            if (fd < 0) {
-                D("adb service become unavailable.");
-                return;
-            }
-        } else {
-            D("Unable to send the '%s' request to ADB service.", _accept_req);
-            return;
-        }
-    }
-    D("transport: qemu_socket_thread() exiting");
-    return;
-}
-
-// If adbd is running inside the emulator, it will normally use QEMUD pipe (aka
-// goldfish) as the transport. This can either be explicitly set by the
-// service.adb.transport property, or be inferred from ro.kernel.qemu that is
-// set to "1" for ranchu/goldfish.
-bool use_qemu_goldfish() {
-    // Legacy way to detect if adbd should use the goldfish pipe is to check for
-    // ro.kernel.qemu, keep that behaviour for backward compatibility.
-    if (android::base::GetBoolProperty("ro.kernel.qemu", false)) {
-        return true;
-    }
-    // If service.adb.transport is present and is set to "goldfish", use the
-    // QEMUD pipe.
-    if (android::base::GetProperty("service.adb.transport", "") == "goldfish") {
-        return true;
-    }
-    return false;
-}
diff --git a/adb/daemon/usb.cpp b/adb/daemon/usb.cpp
deleted file mode 100644
index a663871..0000000
--- a/adb/daemon/usb.cpp
+++ /dev/null
@@ -1,767 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define TRACE_TAG USB
-
-#include "sysdeps.h"
-
-#include <errno.h>
-#include <inttypes.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/ioctl.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include <linux/usb/functionfs.h>
-#include <sys/eventfd.h>
-
-#include <algorithm>
-#include <array>
-#include <future>
-#include <memory>
-#include <mutex>
-#include <optional>
-#include <vector>
-
-#include <asyncio/AsyncIO.h>
-
-#include <android-base/logging.h>
-#include <android-base/macros.h>
-#include <android-base/properties.h>
-#include <android-base/thread_annotations.h>
-
-#include "adb_unique_fd.h"
-#include "adb_utils.h"
-#include "daemon/usb_ffs.h"
-#include "sysdeps/chrono.h"
-#include "transport.h"
-#include "types.h"
-
-using android::base::StringPrintf;
-
-// Not all USB controllers support operations larger than 16k, so don't go above that.
-// Also, each submitted operation does an allocation in the kernel of that size, so we want to
-// minimize our queue depth while still maintaining a deep enough queue to keep the USB stack fed.
-static constexpr size_t kUsbReadQueueDepth = 8;
-static constexpr size_t kUsbReadSize = 4 * PAGE_SIZE;
-
-static constexpr size_t kUsbWriteQueueDepth = 8;
-static constexpr size_t kUsbWriteSize = 4 * PAGE_SIZE;
-
-static const char* to_string(enum usb_functionfs_event_type type) {
-    switch (type) {
-        case FUNCTIONFS_BIND:
-            return "FUNCTIONFS_BIND";
-        case FUNCTIONFS_UNBIND:
-            return "FUNCTIONFS_UNBIND";
-        case FUNCTIONFS_ENABLE:
-            return "FUNCTIONFS_ENABLE";
-        case FUNCTIONFS_DISABLE:
-            return "FUNCTIONFS_DISABLE";
-        case FUNCTIONFS_SETUP:
-            return "FUNCTIONFS_SETUP";
-        case FUNCTIONFS_SUSPEND:
-            return "FUNCTIONFS_SUSPEND";
-        case FUNCTIONFS_RESUME:
-            return "FUNCTIONFS_RESUME";
-    }
-}
-
-enum class TransferDirection : uint64_t {
-    READ = 0,
-    WRITE = 1,
-};
-
-struct TransferId {
-    TransferDirection direction : 1;
-    uint64_t id : 63;
-
-    TransferId() : TransferId(TransferDirection::READ, 0) {}
-
-  private:
-    TransferId(TransferDirection direction, uint64_t id) : direction(direction), id(id) {}
-
-  public:
-    explicit operator uint64_t() const {
-        uint64_t result;
-        static_assert(sizeof(*this) == sizeof(result));
-        memcpy(&result, this, sizeof(*this));
-        return result;
-    }
-
-    static TransferId read(uint64_t id) { return TransferId(TransferDirection::READ, id); }
-    static TransferId write(uint64_t id) { return TransferId(TransferDirection::WRITE, id); }
-
-    static TransferId from_value(uint64_t value) {
-        TransferId result;
-        memcpy(&result, &value, sizeof(value));
-        return result;
-    }
-};
-
-template <class Payload>
-struct IoBlock {
-    bool pending = false;
-    struct iocb control = {};
-    Payload payload;
-
-    TransferId id() const { return TransferId::from_value(control.aio_data); }
-};
-
-using IoReadBlock = IoBlock<Block>;
-using IoWriteBlock = IoBlock<std::shared_ptr<Block>>;
-
-struct ScopedAioContext {
-    ScopedAioContext() = default;
-    ~ScopedAioContext() { reset(); }
-
-    ScopedAioContext(ScopedAioContext&& move) { reset(move.release()); }
-    ScopedAioContext(const ScopedAioContext& copy) = delete;
-
-    ScopedAioContext& operator=(ScopedAioContext&& move) {
-        reset(move.release());
-        return *this;
-    }
-    ScopedAioContext& operator=(const ScopedAioContext& copy) = delete;
-
-    static ScopedAioContext Create(size_t max_events) {
-        aio_context_t ctx = 0;
-        if (io_setup(max_events, &ctx) != 0) {
-            PLOG(FATAL) << "failed to create aio_context_t";
-        }
-        ScopedAioContext result;
-        result.reset(ctx);
-        return result;
-    }
-
-    aio_context_t release() {
-        aio_context_t result = context_;
-        context_ = 0;
-        return result;
-    }
-
-    void reset(aio_context_t new_context = 0) {
-        if (context_ != 0) {
-            io_destroy(context_);
-        }
-
-        context_ = new_context;
-    }
-
-    aio_context_t get() { return context_; }
-
-  private:
-    aio_context_t context_ = 0;
-};
-
-struct UsbFfsConnection : public Connection {
-    UsbFfsConnection(unique_fd control, unique_fd read, unique_fd write,
-                     std::promise<void> destruction_notifier)
-        : worker_started_(false),
-          stopped_(false),
-          destruction_notifier_(std::move(destruction_notifier)),
-          control_fd_(std::move(control)),
-          read_fd_(std::move(read)),
-          write_fd_(std::move(write)) {
-        LOG(INFO) << "UsbFfsConnection constructed";
-        worker_event_fd_.reset(eventfd(0, EFD_CLOEXEC));
-        if (worker_event_fd_ == -1) {
-            PLOG(FATAL) << "failed to create eventfd";
-        }
-
-        monitor_event_fd_.reset(eventfd(0, EFD_CLOEXEC));
-        if (monitor_event_fd_ == -1) {
-            PLOG(FATAL) << "failed to create eventfd";
-        }
-
-        aio_context_ = ScopedAioContext::Create(kUsbReadQueueDepth + kUsbWriteQueueDepth);
-    }
-
-    ~UsbFfsConnection() {
-        LOG(INFO) << "UsbFfsConnection being destroyed";
-        Stop();
-        monitor_thread_.join();
-
-        // We need to explicitly close our file descriptors before we notify our destruction,
-        // because the thread listening on the future will immediately try to reopen the endpoint.
-        aio_context_.reset();
-        control_fd_.reset();
-        read_fd_.reset();
-        write_fd_.reset();
-
-        destruction_notifier_.set_value();
-    }
-
-    virtual bool Write(std::unique_ptr<apacket> packet) override final {
-        LOG(DEBUG) << "USB write: " << dump_header(&packet->msg);
-        auto header = std::make_shared<Block>(sizeof(packet->msg));
-        memcpy(header->data(), &packet->msg, sizeof(packet->msg));
-
-        std::lock_guard<std::mutex> lock(write_mutex_);
-        write_requests_.push_back(
-                CreateWriteBlock(std::move(header), 0, sizeof(packet->msg), next_write_id_++));
-        if (!packet->payload.empty()) {
-            // The kernel attempts to allocate a contiguous block of memory for each write,
-            // which can fail if the write is large and the kernel heap is fragmented.
-            // Split large writes into smaller chunks to avoid this.
-            auto payload = std::make_shared<Block>(std::move(packet->payload));
-            size_t offset = 0;
-            size_t len = payload->size();
-
-            while (len > 0) {
-                size_t write_size = std::min(kUsbWriteSize, len);
-                write_requests_.push_back(
-                        CreateWriteBlock(payload, offset, write_size, next_write_id_++));
-                len -= write_size;
-                offset += write_size;
-            }
-        }
-
-        // Wake up the worker thread to submit writes.
-        uint64_t notify = 1;
-        ssize_t rc = adb_write(worker_event_fd_.get(), &notify, sizeof(notify));
-        if (rc < 0) {
-            PLOG(FATAL) << "failed to notify worker eventfd to submit writes";
-        }
-
-        return true;
-    }
-
-    virtual void Start() override final { StartMonitor(); }
-
-    virtual void Stop() override final {
-        if (stopped_.exchange(true)) {
-            return;
-        }
-        stopped_ = true;
-        uint64_t notify = 1;
-        ssize_t rc = adb_write(worker_event_fd_.get(), &notify, sizeof(notify));
-        if (rc < 0) {
-            PLOG(FATAL) << "failed to notify worker eventfd to stop UsbFfsConnection";
-        }
-        CHECK_EQ(static_cast<size_t>(rc), sizeof(notify));
-
-        rc = adb_write(monitor_event_fd_.get(), &notify, sizeof(notify));
-        if (rc < 0) {
-            PLOG(FATAL) << "failed to notify monitor eventfd to stop UsbFfsConnection";
-        }
-
-        CHECK_EQ(static_cast<size_t>(rc), sizeof(notify));
-    }
-
-    virtual bool DoTlsHandshake(RSA* key, std::string* auth_key) override final {
-        // TODO: support TLS for usb connections.
-        LOG(FATAL) << "Not supported yet.";
-        return false;
-    }
-
-  private:
-    void StartMonitor() {
-        // This is a bit of a mess.
-        // It's possible for io_submit to end up blocking, if we call it as the endpoint
-        // becomes disabled. Work around this by having a monitor thread to listen for functionfs
-        // lifecycle events. If we notice an error condition (either we've become disabled, or we
-        // were never enabled in the first place), we send interruption signals to the worker thread
-        // until it dies, and then report failure to the transport via HandleError, which will
-        // eventually result in the transport being destroyed, which will result in UsbFfsConnection
-        // being destroyed, which unblocks the open thread and restarts this entire process.
-        static std::once_flag handler_once;
-        std::call_once(handler_once, []() { signal(kInterruptionSignal, [](int) {}); });
-
-        monitor_thread_ = std::thread([this]() {
-            adb_thread_setname("UsbFfs-monitor");
-            LOG(INFO) << "UsbFfs-monitor thread spawned";
-
-            bool bound = false;
-            bool enabled = false;
-            bool running = true;
-            while (running) {
-                adb_pollfd pfd[2] = {
-                  { .fd = control_fd_.get(), .events = POLLIN, .revents = 0 },
-                  { .fd = monitor_event_fd_.get(), .events = POLLIN, .revents = 0 },
-                };
-
-                // If we don't see our first bind within a second, try again.
-                int timeout_ms = bound ? -1 : 1000;
-
-                int rc = TEMP_FAILURE_RETRY(adb_poll(pfd, 2, timeout_ms));
-                if (rc == -1) {
-                    PLOG(FATAL) << "poll on USB control fd failed";
-                } else if (rc == 0) {
-                    LOG(WARNING) << "timed out while waiting for FUNCTIONFS_BIND, trying again";
-                    break;
-                }
-
-                if (pfd[1].revents) {
-                    // We were told to die.
-                    break;
-                }
-
-                struct usb_functionfs_event event;
-                rc = TEMP_FAILURE_RETRY(adb_read(control_fd_.get(), &event, sizeof(event)));
-                if (rc == -1) {
-                    PLOG(FATAL) << "failed to read functionfs event";
-                } else if (rc == 0) {
-                    LOG(WARNING) << "hit EOF on functionfs control fd";
-                    break;
-                } else if (rc != sizeof(event)) {
-                    LOG(FATAL) << "read functionfs event of unexpected size, expected "
-                               << sizeof(event) << ", got " << rc;
-                }
-
-                LOG(INFO) << "USB event: "
-                          << to_string(static_cast<usb_functionfs_event_type>(event.type));
-
-                switch (event.type) {
-                    case FUNCTIONFS_BIND:
-                        if (bound) {
-                            LOG(WARNING) << "received FUNCTIONFS_BIND while already bound?";
-                            running = false;
-                            break;
-                        }
-
-                        if (enabled) {
-                            LOG(WARNING) << "received FUNCTIONFS_BIND while already enabled?";
-                            running = false;
-                            break;
-                        }
-
-                        bound = true;
-                        break;
-
-                    case FUNCTIONFS_ENABLE:
-                        if (!bound) {
-                            LOG(WARNING) << "received FUNCTIONFS_ENABLE while not bound?";
-                            running = false;
-                            break;
-                        }
-
-                        if (enabled) {
-                            LOG(WARNING) << "received FUNCTIONFS_ENABLE while already enabled?";
-                            running = false;
-                            break;
-                        }
-
-                        enabled = true;
-                        StartWorker();
-                        break;
-
-                    case FUNCTIONFS_DISABLE:
-                        if (!bound) {
-                            LOG(WARNING) << "received FUNCTIONFS_DISABLE while not bound?";
-                        }
-
-                        if (!enabled) {
-                            LOG(WARNING) << "received FUNCTIONFS_DISABLE while not enabled?";
-                        }
-
-                        enabled = false;
-                        running = false;
-                        break;
-
-                    case FUNCTIONFS_UNBIND:
-                        if (enabled) {
-                            LOG(WARNING) << "received FUNCTIONFS_UNBIND while still enabled?";
-                        }
-
-                        if (!bound) {
-                            LOG(WARNING) << "received FUNCTIONFS_UNBIND when not bound?";
-                        }
-
-                        bound = false;
-                        running = false;
-                        break;
-
-                    case FUNCTIONFS_SETUP: {
-                        LOG(INFO) << "received FUNCTIONFS_SETUP control transfer: bRequestType = "
-                                  << static_cast<int>(event.u.setup.bRequestType)
-                                  << ", bRequest = " << static_cast<int>(event.u.setup.bRequest)
-                                  << ", wValue = " << static_cast<int>(event.u.setup.wValue)
-                                  << ", wIndex = " << static_cast<int>(event.u.setup.wIndex)
-                                  << ", wLength = " << static_cast<int>(event.u.setup.wLength);
-
-                        if ((event.u.setup.bRequestType & USB_DIR_IN)) {
-                            LOG(INFO) << "acking device-to-host control transfer";
-                            ssize_t rc = adb_write(control_fd_.get(), "", 0);
-                            if (rc != 0) {
-                                PLOG(ERROR) << "failed to write empty packet to host";
-                                break;
-                            }
-                        } else {
-                            std::string buf;
-                            buf.resize(event.u.setup.wLength + 1);
-
-                            ssize_t rc = adb_read(control_fd_.get(), buf.data(), buf.size());
-                            if (rc != event.u.setup.wLength) {
-                                LOG(ERROR)
-                                        << "read " << rc
-                                        << " bytes when trying to read control request, expected "
-                                        << event.u.setup.wLength;
-                            }
-
-                            LOG(INFO) << "control request contents: " << buf;
-                            break;
-                        }
-                    }
-                }
-            }
-
-            StopWorker();
-            HandleError("monitor thread finished");
-        });
-    }
-
-    void StartWorker() {
-        CHECK(!worker_started_);
-        worker_started_ = true;
-        worker_thread_ = std::thread([this]() {
-            adb_thread_setname("UsbFfs-worker");
-            LOG(INFO) << "UsbFfs-worker thread spawned";
-
-            for (size_t i = 0; i < kUsbReadQueueDepth; ++i) {
-                read_requests_[i] = CreateReadBlock(next_read_id_++);
-                if (!SubmitRead(&read_requests_[i])) {
-                    return;
-                }
-            }
-
-            while (!stopped_) {
-                uint64_t dummy;
-                ssize_t rc = adb_read(worker_event_fd_.get(), &dummy, sizeof(dummy));
-                if (rc == -1) {
-                    PLOG(FATAL) << "failed to read from eventfd";
-                } else if (rc == 0) {
-                    LOG(FATAL) << "hit EOF on eventfd";
-                }
-
-                ReadEvents();
-
-                std::lock_guard<std::mutex> lock(write_mutex_);
-                SubmitWrites();
-            }
-        });
-    }
-
-    void StopWorker() {
-        if (!worker_started_) {
-            return;
-        }
-
-        pthread_t worker_thread_handle = worker_thread_.native_handle();
-        while (true) {
-            int rc = pthread_kill(worker_thread_handle, kInterruptionSignal);
-            if (rc != 0) {
-                LOG(ERROR) << "failed to send interruption signal to worker: " << strerror(rc);
-                break;
-            }
-
-            std::this_thread::sleep_for(100ms);
-
-            rc = pthread_kill(worker_thread_handle, 0);
-            if (rc == 0) {
-                continue;
-            } else if (rc == ESRCH) {
-                break;
-            } else {
-                LOG(ERROR) << "failed to send interruption signal to worker: " << strerror(rc);
-            }
-        }
-
-        worker_thread_.join();
-    }
-
-    void PrepareReadBlock(IoReadBlock* block, uint64_t id) {
-        block->pending = false;
-        if (block->payload.capacity() >= kUsbReadSize) {
-            block->payload.resize(kUsbReadSize);
-        } else {
-            block->payload = Block(kUsbReadSize);
-        }
-        block->control.aio_data = static_cast<uint64_t>(TransferId::read(id));
-        block->control.aio_buf = reinterpret_cast<uintptr_t>(block->payload.data());
-        block->control.aio_nbytes = block->payload.size();
-    }
-
-    IoReadBlock CreateReadBlock(uint64_t id) {
-        IoReadBlock block;
-        PrepareReadBlock(&block, id);
-        block.control.aio_rw_flags = 0;
-        block.control.aio_lio_opcode = IOCB_CMD_PREAD;
-        block.control.aio_reqprio = 0;
-        block.control.aio_fildes = read_fd_.get();
-        block.control.aio_offset = 0;
-        block.control.aio_flags = IOCB_FLAG_RESFD;
-        block.control.aio_resfd = worker_event_fd_.get();
-        return block;
-    }
-
-    void ReadEvents() {
-        static constexpr size_t kMaxEvents = kUsbReadQueueDepth + kUsbWriteQueueDepth;
-        struct io_event events[kMaxEvents];
-        struct timespec timeout = {.tv_sec = 0, .tv_nsec = 0};
-        int rc = io_getevents(aio_context_.get(), 0, kMaxEvents, events, &timeout);
-        if (rc == -1) {
-            HandleError(StringPrintf("io_getevents failed while reading: %s", strerror(errno)));
-            return;
-        }
-
-        for (int event_idx = 0; event_idx < rc; ++event_idx) {
-            auto& event = events[event_idx];
-            TransferId id = TransferId::from_value(event.data);
-
-            if (event.res < 0) {
-                std::string error =
-                        StringPrintf("%s %" PRIu64 " failed with error %s",
-                                     id.direction == TransferDirection::READ ? "read" : "write",
-                                     id.id, strerror(-event.res));
-                HandleError(error);
-                return;
-            }
-
-            if (id.direction == TransferDirection::READ) {
-                if (!HandleRead(id, event.res)) {
-                    return;
-                }
-            } else {
-                HandleWrite(id);
-            }
-        }
-    }
-
-    bool HandleRead(TransferId id, int64_t size) {
-        uint64_t read_idx = id.id % kUsbReadQueueDepth;
-        IoReadBlock* block = &read_requests_[read_idx];
-        block->pending = false;
-        block->payload.resize(size);
-
-        // Notification for completed reads can be received out of order.
-        if (block->id().id != needed_read_id_) {
-            LOG(VERBOSE) << "read " << block->id().id << " completed while waiting for "
-                         << needed_read_id_;
-            return true;
-        }
-
-        for (uint64_t id = needed_read_id_;; ++id) {
-            size_t read_idx = id % kUsbReadQueueDepth;
-            IoReadBlock* current_block = &read_requests_[read_idx];
-            if (current_block->pending) {
-                break;
-            }
-            if (!ProcessRead(current_block)) {
-                return false;
-            }
-            ++needed_read_id_;
-        }
-
-        return true;
-    }
-
-    bool ProcessRead(IoReadBlock* block) {
-        if (!block->payload.empty()) {
-            if (!incoming_header_.has_value()) {
-                if (block->payload.size() != sizeof(amessage)) {
-                    HandleError("received packet of unexpected length while reading header");
-                    return false;
-                }
-                amessage& msg = incoming_header_.emplace();
-                memcpy(&msg, block->payload.data(), sizeof(msg));
-                LOG(DEBUG) << "USB read:" << dump_header(&msg);
-                incoming_header_ = msg;
-            } else {
-                size_t bytes_left = incoming_header_->data_length - incoming_payload_.size();
-                Block payload = std::move(block->payload);
-                if (block->payload.size() > bytes_left) {
-                    HandleError("received too many bytes while waiting for payload");
-                    return false;
-                }
-                incoming_payload_.append(std::move(payload));
-            }
-
-            if (incoming_header_->data_length == incoming_payload_.size()) {
-                auto packet = std::make_unique<apacket>();
-                packet->msg = *incoming_header_;
-
-                // TODO: Make apacket contain an IOVector so we don't have to coalesce.
-                packet->payload = std::move(incoming_payload_).coalesce();
-                read_callback_(this, std::move(packet));
-
-                incoming_header_.reset();
-                // reuse the capacity of the incoming payload while we can.
-                auto free_block = incoming_payload_.clear();
-                if (block->payload.capacity() == 0) {
-                    block->payload = std::move(free_block);
-                }
-            }
-        }
-
-        PrepareReadBlock(block, block->id().id + kUsbReadQueueDepth);
-        SubmitRead(block);
-        return true;
-    }
-
-    bool SubmitRead(IoReadBlock* block) {
-        block->pending = true;
-        struct iocb* iocb = &block->control;
-        if (io_submit(aio_context_.get(), 1, &iocb) != 1) {
-            HandleError(StringPrintf("failed to submit read: %s", strerror(errno)));
-            return false;
-        }
-
-        return true;
-    }
-
-    void HandleWrite(TransferId id) {
-        std::lock_guard<std::mutex> lock(write_mutex_);
-        auto it =
-                std::find_if(write_requests_.begin(), write_requests_.end(), [id](const auto& req) {
-                    return static_cast<uint64_t>(req.id()) == static_cast<uint64_t>(id);
-                });
-        CHECK(it != write_requests_.end());
-
-        write_requests_.erase(it);
-        size_t outstanding_writes = --writes_submitted_;
-        LOG(DEBUG) << "USB write: reaped, down to " << outstanding_writes;
-    }
-
-    IoWriteBlock CreateWriteBlock(std::shared_ptr<Block> payload, size_t offset, size_t len,
-                                  uint64_t id) {
-        auto block = IoWriteBlock();
-        block.payload = std::move(payload);
-        block.control.aio_data = static_cast<uint64_t>(TransferId::write(id));
-        block.control.aio_rw_flags = 0;
-        block.control.aio_lio_opcode = IOCB_CMD_PWRITE;
-        block.control.aio_reqprio = 0;
-        block.control.aio_fildes = write_fd_.get();
-        block.control.aio_buf = reinterpret_cast<uintptr_t>(block.payload->data() + offset);
-        block.control.aio_nbytes = len;
-        block.control.aio_offset = 0;
-        block.control.aio_flags = IOCB_FLAG_RESFD;
-        block.control.aio_resfd = worker_event_fd_.get();
-        return block;
-    }
-
-    IoWriteBlock CreateWriteBlock(Block&& payload, uint64_t id) {
-        size_t len = payload.size();
-        return CreateWriteBlock(std::make_shared<Block>(std::move(payload)), 0, len, id);
-    }
-
-    void SubmitWrites() REQUIRES(write_mutex_) {
-        if (writes_submitted_ == kUsbWriteQueueDepth) {
-            return;
-        }
-
-        ssize_t writes_to_submit = std::min(kUsbWriteQueueDepth - writes_submitted_,
-                                            write_requests_.size() - writes_submitted_);
-        CHECK_GE(writes_to_submit, 0);
-        if (writes_to_submit == 0) {
-            return;
-        }
-
-        struct iocb* iocbs[kUsbWriteQueueDepth];
-        for (int i = 0; i < writes_to_submit; ++i) {
-            CHECK(!write_requests_[writes_submitted_ + i].pending);
-            write_requests_[writes_submitted_ + i].pending = true;
-            iocbs[i] = &write_requests_[writes_submitted_ + i].control;
-            LOG(VERBOSE) << "submitting write_request " << static_cast<void*>(iocbs[i]);
-        }
-
-        writes_submitted_ += writes_to_submit;
-
-        int rc = io_submit(aio_context_.get(), writes_to_submit, iocbs);
-        if (rc == -1) {
-            HandleError(StringPrintf("failed to submit write requests: %s", strerror(errno)));
-            return;
-        } else if (rc != writes_to_submit) {
-            LOG(FATAL) << "failed to submit all writes: wanted to submit " << writes_to_submit
-                       << ", actually submitted " << rc;
-        }
-    }
-
-    void HandleError(const std::string& error) {
-        std::call_once(error_flag_, [&]() {
-            error_callback_(this, error);
-            if (!stopped_) {
-                Stop();
-            }
-        });
-    }
-
-    std::thread monitor_thread_;
-
-    bool worker_started_;
-    std::thread worker_thread_;
-
-    std::atomic<bool> stopped_;
-    std::promise<void> destruction_notifier_;
-    std::once_flag error_flag_;
-
-    unique_fd worker_event_fd_;
-    unique_fd monitor_event_fd_;
-
-    ScopedAioContext aio_context_;
-    unique_fd control_fd_;
-    unique_fd read_fd_;
-    unique_fd write_fd_;
-
-    std::optional<amessage> incoming_header_;
-    IOVector incoming_payload_;
-
-    std::array<IoReadBlock, kUsbReadQueueDepth> read_requests_;
-    IOVector read_data_;
-
-    // ID of the next request that we're going to send out.
-    size_t next_read_id_ = 0;
-
-    // ID of the next packet we're waiting for.
-    size_t needed_read_id_ = 0;
-
-    std::mutex write_mutex_;
-    std::deque<IoWriteBlock> write_requests_ GUARDED_BY(write_mutex_);
-    size_t next_write_id_ GUARDED_BY(write_mutex_) = 0;
-    size_t writes_submitted_ GUARDED_BY(write_mutex_) = 0;
-
-    static constexpr int kInterruptionSignal = SIGUSR1;
-};
-
-static void usb_ffs_open_thread() {
-    adb_thread_setname("usb ffs open");
-
-    while (true) {
-        unique_fd control;
-        unique_fd bulk_out;
-        unique_fd bulk_in;
-        if (!open_functionfs(&control, &bulk_out, &bulk_in)) {
-            std::this_thread::sleep_for(1s);
-            continue;
-        }
-
-        atransport* transport = new atransport();
-        transport->serial = "UsbFfs";
-        std::promise<void> destruction_notifier;
-        std::future<void> future = destruction_notifier.get_future();
-        transport->SetConnection(std::make_unique<UsbFfsConnection>(
-                std::move(control), std::move(bulk_out), std::move(bulk_in),
-                std::move(destruction_notifier)));
-        register_transport(transport);
-        future.wait();
-    }
-}
-
-void usb_init() {
-    std::thread(usb_ffs_open_thread).detach();
-}
diff --git a/adb/daemon/usb_ffs.cpp b/adb/daemon/usb_ffs.cpp
deleted file mode 100644
index e538ca8..0000000
--- a/adb/daemon/usb_ffs.cpp
+++ /dev/null
@@ -1,321 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define TRACE_TAG USB
-
-#include "sysdeps.h"
-
-#include "daemon/usb_ffs.h"
-
-#include <linux/usb/ch9.h>
-#include <linux/usb/functionfs.h>
-
-#include <android-base/logging.h>
-#include <android-base/properties.h>
-#include <android-base/unique_fd.h>
-
-#include "adb.h"
-
-#define MAX_PACKET_SIZE_FS 64
-#define MAX_PACKET_SIZE_HS 512
-#define MAX_PACKET_SIZE_SS 1024
-
-#define USB_FFS_BULK_SIZE 16384
-
-// Number of buffers needed to fit MAX_PAYLOAD, with an extra for ZLPs.
-#define USB_FFS_NUM_BUFS ((4 * MAX_PAYLOAD / USB_FFS_BULK_SIZE) + 1)
-
-#define USB_EXT_PROP_UNICODE 1
-
-#define cpu_to_le16(x) htole16(x)
-#define cpu_to_le32(x) htole32(x)
-
-// clang-format off
-struct func_desc {
-    struct usb_interface_descriptor intf;
-    struct usb_endpoint_descriptor_no_audio source;
-    struct usb_endpoint_descriptor_no_audio sink;
-} __attribute__((packed));
-
-struct ss_func_desc {
-    struct usb_interface_descriptor intf;
-    struct usb_endpoint_descriptor_no_audio source;
-    struct usb_ss_ep_comp_descriptor source_comp;
-    struct usb_endpoint_descriptor_no_audio sink;
-    struct usb_ss_ep_comp_descriptor sink_comp;
-} __attribute__((packed));
-
-struct desc_v1 {
-    struct usb_functionfs_descs_head_v1 {
-        __le32 magic;
-        __le32 length;
-        __le32 fs_count;
-        __le32 hs_count;
-    } __attribute__((packed)) header;
-    struct func_desc fs_descs, hs_descs;
-} __attribute__((packed));
-
-template <size_t PropertyNameLength, size_t PropertyDataLength>
-struct usb_os_desc_ext_prop {
-    uint32_t dwSize = sizeof(*this);
-    uint32_t dwPropertyDataType = cpu_to_le32(USB_EXT_PROP_UNICODE);
-
-    // Property name and value are transmitted as UTF-16, but the kernel only
-    // accepts ASCII values and performs the conversion for us.
-    uint16_t wPropertyNameLength = cpu_to_le16(PropertyNameLength);
-    char bPropertyName[PropertyNameLength];
-
-    uint32_t dwPropertyDataLength = cpu_to_le32(PropertyDataLength);
-    char bProperty[PropertyDataLength];
-} __attribute__((packed));
-
-using usb_os_desc_guid_t = usb_os_desc_ext_prop<20, 39>;
-usb_os_desc_guid_t os_desc_guid = {
-    .bPropertyName = "DeviceInterfaceGUID",
-    .bProperty = "{F72FE0D4-CBCB-407D-8814-9ED673D0DD6B}",
-};
-
-struct usb_ext_prop_values {
-    usb_os_desc_guid_t guid;
-} __attribute__((packed));
-
-usb_ext_prop_values os_prop_values = {
-    .guid = os_desc_guid,
-};
-
-struct desc_v2 {
-    struct usb_functionfs_descs_head_v2 header;
-    // The rest of the structure depends on the flags in the header.
-    __le32 fs_count;
-    __le32 hs_count;
-    __le32 ss_count;
-    __le32 os_count;
-    struct func_desc fs_descs, hs_descs;
-    struct ss_func_desc ss_descs;
-    struct usb_os_desc_header os_header;
-    struct usb_ext_compat_desc os_desc;
-    struct usb_os_desc_header os_prop_header;
-    struct usb_ext_prop_values os_prop_values;
-} __attribute__((packed));
-
-static struct func_desc fs_descriptors = {
-    .intf = {
-        .bLength = sizeof(fs_descriptors.intf),
-        .bDescriptorType = USB_DT_INTERFACE,
-        .bInterfaceNumber = 0,
-        .bNumEndpoints = 2,
-        .bInterfaceClass = ADB_CLASS,
-        .bInterfaceSubClass = ADB_SUBCLASS,
-        .bInterfaceProtocol = ADB_PROTOCOL,
-        .iInterface = 1, /* first string from the provided table */
-    },
-    .source = {
-        .bLength = sizeof(fs_descriptors.source),
-        .bDescriptorType = USB_DT_ENDPOINT,
-        .bEndpointAddress = 1 | USB_DIR_OUT,
-        .bmAttributes = USB_ENDPOINT_XFER_BULK,
-        .wMaxPacketSize = MAX_PACKET_SIZE_FS,
-    },
-    .sink = {
-        .bLength = sizeof(fs_descriptors.sink),
-        .bDescriptorType = USB_DT_ENDPOINT,
-        .bEndpointAddress = 2 | USB_DIR_IN,
-        .bmAttributes = USB_ENDPOINT_XFER_BULK,
-        .wMaxPacketSize = MAX_PACKET_SIZE_FS,
-    },
-};
-
-static struct func_desc hs_descriptors = {
-    .intf = {
-        .bLength = sizeof(hs_descriptors.intf),
-        .bDescriptorType = USB_DT_INTERFACE,
-        .bInterfaceNumber = 0,
-        .bNumEndpoints = 2,
-        .bInterfaceClass = ADB_CLASS,
-        .bInterfaceSubClass = ADB_SUBCLASS,
-        .bInterfaceProtocol = ADB_PROTOCOL,
-        .iInterface = 1, /* first string from the provided table */
-    },
-    .source = {
-        .bLength = sizeof(hs_descriptors.source),
-        .bDescriptorType = USB_DT_ENDPOINT,
-        .bEndpointAddress = 1 | USB_DIR_OUT,
-        .bmAttributes = USB_ENDPOINT_XFER_BULK,
-        .wMaxPacketSize = MAX_PACKET_SIZE_HS,
-    },
-    .sink = {
-        .bLength = sizeof(hs_descriptors.sink),
-        .bDescriptorType = USB_DT_ENDPOINT,
-        .bEndpointAddress = 2 | USB_DIR_IN,
-        .bmAttributes = USB_ENDPOINT_XFER_BULK,
-        .wMaxPacketSize = MAX_PACKET_SIZE_HS,
-    },
-};
-
-static struct ss_func_desc ss_descriptors = {
-    .intf = {
-        .bLength = sizeof(ss_descriptors.intf),
-        .bDescriptorType = USB_DT_INTERFACE,
-        .bInterfaceNumber = 0,
-        .bNumEndpoints = 2,
-        .bInterfaceClass = ADB_CLASS,
-        .bInterfaceSubClass = ADB_SUBCLASS,
-        .bInterfaceProtocol = ADB_PROTOCOL,
-        .iInterface = 1, /* first string from the provided table */
-    },
-    .source = {
-        .bLength = sizeof(ss_descriptors.source),
-        .bDescriptorType = USB_DT_ENDPOINT,
-        .bEndpointAddress = 1 | USB_DIR_OUT,
-        .bmAttributes = USB_ENDPOINT_XFER_BULK,
-        .wMaxPacketSize = MAX_PACKET_SIZE_SS,
-    },
-    .source_comp = {
-        .bLength = sizeof(ss_descriptors.source_comp),
-        .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
-        .bMaxBurst = 4,
-    },
-    .sink = {
-        .bLength = sizeof(ss_descriptors.sink),
-        .bDescriptorType = USB_DT_ENDPOINT,
-        .bEndpointAddress = 2 | USB_DIR_IN,
-        .bmAttributes = USB_ENDPOINT_XFER_BULK,
-        .wMaxPacketSize = MAX_PACKET_SIZE_SS,
-    },
-    .sink_comp = {
-        .bLength = sizeof(ss_descriptors.sink_comp),
-        .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
-        .bMaxBurst = 4,
-    },
-};
-
-struct usb_ext_compat_desc os_desc_compat = {
-    .bFirstInterfaceNumber = 0,
-    .Reserved1 = cpu_to_le32(1),
-    .CompatibleID = { 'W', 'I', 'N', 'U', 'S', 'B', '\0', '\0'},
-    .SubCompatibleID = {0},
-    .Reserved2 = {0},
-};
-
-static struct usb_os_desc_header os_desc_header = {
-    .interface = cpu_to_le32(0),
-    .dwLength = cpu_to_le32(sizeof(os_desc_header) + sizeof(os_desc_compat)),
-    .bcdVersion = cpu_to_le32(1),
-    .wIndex = cpu_to_le32(4),
-    .bCount = cpu_to_le32(1),
-    .Reserved = cpu_to_le32(0),
-};
-
-static struct usb_os_desc_header os_prop_header = {
-    .interface = cpu_to_le32(0),
-    .dwLength = cpu_to_le32(sizeof(os_desc_header) + sizeof(os_prop_values)),
-    .bcdVersion = cpu_to_le32(1),
-    .wIndex = cpu_to_le32(5),
-    .wCount = cpu_to_le16(1),
-};
-
-#define STR_INTERFACE_ "ADB Interface"
-
-static const struct {
-    struct usb_functionfs_strings_head header;
-    struct {
-        __le16 code;
-        const char str1[sizeof(STR_INTERFACE_)];
-    } __attribute__((packed)) lang0;
-} __attribute__((packed)) strings = {
-    .header = {
-        .magic = cpu_to_le32(FUNCTIONFS_STRINGS_MAGIC),
-        .length = cpu_to_le32(sizeof(strings)),
-        .str_count = cpu_to_le32(1),
-        .lang_count = cpu_to_le32(1),
-    },
-    .lang0 = {
-        cpu_to_le16(0x0409), /* en-us */
-        STR_INTERFACE_,
-    },
-};
-// clang-format on
-
-bool open_functionfs(android::base::unique_fd* out_control, android::base::unique_fd* out_bulk_out,
-                     android::base::unique_fd* out_bulk_in) {
-    unique_fd control, bulk_out, bulk_in;
-    struct desc_v1 v1_descriptor = {};
-    struct desc_v2 v2_descriptor = {};
-
-    v2_descriptor.header.magic = cpu_to_le32(FUNCTIONFS_DESCRIPTORS_MAGIC_V2);
-    v2_descriptor.header.length = cpu_to_le32(sizeof(v2_descriptor));
-    v2_descriptor.header.flags = FUNCTIONFS_HAS_FS_DESC | FUNCTIONFS_HAS_HS_DESC |
-                                 FUNCTIONFS_HAS_SS_DESC | FUNCTIONFS_HAS_MS_OS_DESC;
-    v2_descriptor.fs_count = 3;
-    v2_descriptor.hs_count = 3;
-    v2_descriptor.ss_count = 5;
-    v2_descriptor.os_count = 2;
-    v2_descriptor.fs_descs = fs_descriptors;
-    v2_descriptor.hs_descs = hs_descriptors;
-    v2_descriptor.ss_descs = ss_descriptors;
-    v2_descriptor.os_header = os_desc_header;
-    v2_descriptor.os_desc = os_desc_compat;
-    v2_descriptor.os_prop_header = os_prop_header;
-    v2_descriptor.os_prop_values = os_prop_values;
-
-    if (out_control->get() < 0) {  // might have already done this before
-        LOG(INFO) << "opening control endpoint " << USB_FFS_ADB_EP0;
-        control.reset(adb_open(USB_FFS_ADB_EP0, O_RDWR));
-        if (control < 0) {
-            PLOG(ERROR) << "cannot open control endpoint " << USB_FFS_ADB_EP0;
-            return false;
-        }
-
-        if (adb_write(control.get(), &v2_descriptor, sizeof(v2_descriptor)) < 0) {
-            D("[ %s: Switching to V1_descriptor format errno=%s ]", USB_FFS_ADB_EP0,
-              strerror(errno));
-            v1_descriptor.header.magic = cpu_to_le32(FUNCTIONFS_DESCRIPTORS_MAGIC);
-            v1_descriptor.header.length = cpu_to_le32(sizeof(v1_descriptor));
-            v1_descriptor.header.fs_count = 3;
-            v1_descriptor.header.hs_count = 3;
-            v1_descriptor.fs_descs = fs_descriptors;
-            v1_descriptor.hs_descs = hs_descriptors;
-            if (adb_write(control.get(), &v1_descriptor, sizeof(v1_descriptor)) < 0) {
-                PLOG(ERROR) << "failed to write USB descriptors";
-                return false;
-            }
-        }
-
-        if (adb_write(control.get(), &strings, sizeof(strings)) < 0) {
-            PLOG(ERROR) << "failed to write USB strings";
-            return false;
-        }
-        // Signal only when writing the descriptors to ffs
-        android::base::SetProperty("sys.usb.ffs.ready", "1");
-    }
-
-    bulk_out.reset(adb_open(USB_FFS_ADB_OUT, O_RDONLY));
-    if (bulk_out < 0) {
-        PLOG(ERROR) << "cannot open bulk-out endpoint " << USB_FFS_ADB_OUT;
-        return false;
-    }
-
-    bulk_in.reset(adb_open(USB_FFS_ADB_IN, O_WRONLY));
-    if (bulk_in < 0) {
-        PLOG(ERROR) << "cannot open bulk-in endpoint " << USB_FFS_ADB_IN;
-        return false;
-    }
-
-    *out_control = std::move(control);
-    *out_bulk_in = std::move(bulk_in);
-    *out_bulk_out = std::move(bulk_out);
-    return true;
-}
diff --git a/adb/daemon/usb_ffs.h b/adb/daemon/usb_ffs.h
deleted file mode 100644
index a19d7cc..0000000
--- a/adb/daemon/usb_ffs.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <android-base/unique_fd.h>
-
-bool open_functionfs(android::base::unique_fd* control, android::base::unique_fd* bulk_out,
-                     android::base::unique_fd* bulk_in);
diff --git a/adb/fastdeploy/Android.bp b/adb/fastdeploy/Android.bp
deleted file mode 100644
index f5893aa..0000000
--- a/adb/fastdeploy/Android.bp
+++ /dev/null
@@ -1,89 +0,0 @@
-//
-// Copyright (C) 2018 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-java_library {
-    name: "deployagent_lib",
-    sdk_version: "24",
-    srcs: [
-        "deployagent/src/**/*.java",
-        "proto/**/*.proto",
-    ],
-    proto: {
-        type: "lite",
-    },
-}
-
-java_binary {
-    name: "deployagent",
-    sdk_version: "24",
-    static_libs: [
-        "deployagent_lib",
-    ],
-    dex_preopt: {
-        enabled: false,
-    }
-}
-
-android_test {
-    name: "FastDeployTests",
-
-    manifest: "AndroidManifest.xml",
-
-    srcs: [
-        "deployagent/test/com/android/fastdeploy/ApkArchiveTest.java",
-    ],
-
-    static_libs: [
-        "androidx.test.core",
-        "androidx.test.runner",
-        "androidx.test.rules",
-        "deployagent_lib",
-        "mockito-target-inline-minus-junit4",
-    ],
-
-    libs: [
-        "android.test.runner",
-        "android.test.base",
-        "android.test.mock",
-    ],
-
-    data: [
-        "testdata/sample.apk",
-        "testdata/sample.cd",
-    ],
-
-    optimize: {
-        enabled: false,
-    },
-}
-
-java_test_host {
-    name: "FastDeployHostTests",
-    srcs: [
-        "deployagent/test/com/android/fastdeploy/FastDeployTest.java",
-    ],
-    data: [
-        "testdata/helloworld5.apk",
-        "testdata/helloworld7.apk",
-    ],
-    libs: [
-        "compatibility-host-util",
-        "cts-tradefed",
-        "tradefed",
-    ],
-    test_suites: [
-        "general-tests",
-    ],
-}
diff --git a/adb/fastdeploy/AndroidManifest.xml b/adb/fastdeploy/AndroidManifest.xml
deleted file mode 100644
index 89dc745..0000000
--- a/adb/fastdeploy/AndroidManifest.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2019 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.fastdeploytests">
-
-    <application android:testOnly="true"
-                 android:debuggable="true">
-        <uses-library android:name="android.test.runner" />
-    </application>
-
-    <instrumentation
-        android:name="androidx.test.runner.AndroidJUnitRunner"
-        android:targetPackage="com.android.fastdeploytests"
-        android:label="FastDeploy Tests" />
-</manifest>
\ No newline at end of file
diff --git a/adb/fastdeploy/AndroidTest.xml b/adb/fastdeploy/AndroidTest.xml
deleted file mode 100644
index 24a72bc..0000000
--- a/adb/fastdeploy/AndroidTest.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2019 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-<configuration description="Runs Device Tests for FastDeploy.">
-    <option name="test-suite-tag" value="FastDeployTests"/>
-
-    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
-        <option name="cleanup-apks" value="true"/>
-        <option name="install-arg" value="-t"/>
-        <option name="test-file-name" value="FastDeployTests.apk"/>
-    </target_preparer>
-
-    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
-        <option name="cleanup" value="false" />
-        <option name="push-file" key="sample.apk" value="/data/local/tmp/FastDeployTests/sample.apk" />
-        <option name="push-file" key="sample.cd" value="/data/local/tmp/FastDeployTests/sample.cd" />
-    </target_preparer>
-
-    <test class="com.android.tradefed.testtype.AndroidJUnitTest">
-        <option name="package" value="com.android.fastdeploytests"/>
-        <option name="runner" value="androidx.test.runner.AndroidJUnitRunner"/>
-    </test>
-
-    <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
-        <option name="jar" value="FastDeployHostTests.jar" />
-    </test>
-</configuration>
diff --git a/adb/fastdeploy/OWNERS b/adb/fastdeploy/OWNERS
deleted file mode 100644
index d145834..0000000
--- a/adb/fastdeploy/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-idries@google.com
diff --git a/adb/fastdeploy/deployagent/deployagent.sh b/adb/fastdeploy/deployagent/deployagent.sh
deleted file mode 100755
index 91576ca..0000000
--- a/adb/fastdeploy/deployagent/deployagent.sh
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/system/bin/sh
-base=/data/local/tmp
-export CLASSPATH=$base/deployagent.jar
-exec app_process $base com.android.fastdeploy.DeployAgent "$@"
diff --git a/adb/fastdeploy/deployagent/src/com/android/fastdeploy/ApkArchive.java b/adb/fastdeploy/deployagent/src/com/android/fastdeploy/ApkArchive.java
deleted file mode 100644
index 31e0502..0000000
--- a/adb/fastdeploy/deployagent/src/com/android/fastdeploy/ApkArchive.java
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.fastdeploy;
-
-import android.util.Log;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.RandomAccessFile;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.channels.FileChannel;
-
-/**
- * Extremely light-weight APK parser class.
- * Aware of Central Directory, Local File Headers and Signature.
- * No Zip64 support yet.
- */
-public final class ApkArchive {
-    private static final String TAG = "ApkArchive";
-
-    // Central Directory constants.
-    private static final int EOCD_SIGNATURE = 0x06054b50;
-    private static final int EOCD_MIN_SIZE = 22;
-    private static final long EOCD_MAX_SIZE = 65_535L + EOCD_MIN_SIZE;
-
-    private static final int CD_ENTRY_HEADER_SIZE_BYTES = 22;
-    private static final int CD_LOCAL_FILE_HEADER_SIZE_OFFSET = 12;
-
-    // Signature constants.
-    private static final int EOSIGNATURE_SIZE = 24;
-
-    public final static class Dump {
-        final byte[] cd;
-        final byte[] signature;
-
-        Dump(byte[] cd, byte[] signature) {
-            this.cd = cd;
-            this.signature = signature;
-        }
-    }
-
-    final static class Location {
-        final long offset;
-        final long size;
-
-        public Location(long offset, long size) {
-            this.offset = offset;
-            this.size = size;
-        }
-    }
-
-    private final RandomAccessFile mFile;
-    private final FileChannel mChannel;
-
-    public ApkArchive(File apk) throws IOException {
-        mFile = new RandomAccessFile(apk, "r");
-        mChannel = mFile.getChannel();
-    }
-
-    /**
-     * Extract the APK metadata: content of Central Directory and Signature.
-     *
-     * @return raw content from APK representing CD and Signature data.
-     */
-    public Dump extractMetadata() throws IOException {
-        Location cdLoc = getCDLocation();
-        byte[] cd = readMetadata(cdLoc);
-
-        byte[] signature = null;
-        Location sigLoc = getSignatureLocation(cdLoc.offset);
-        if (sigLoc != null) {
-            signature = readMetadata(sigLoc);
-            long size = ByteBuffer.wrap(signature).order(ByteOrder.LITTLE_ENDIAN).getLong();
-            if (sigLoc.size != size) {
-                Log.e(TAG, "Mismatching signature sizes: " + sigLoc.size + " != " + size);
-                signature = null;
-            }
-        }
-
-        return new Dump(cd, signature);
-    }
-
-    private long findEndOfCDRecord() throws IOException {
-        final long fileSize = mChannel.size();
-        int sizeToRead = Math.toIntExact(Math.min(fileSize, EOCD_MAX_SIZE));
-        final long readOffset = fileSize - sizeToRead;
-        ByteBuffer buffer = mChannel.map(FileChannel.MapMode.READ_ONLY, readOffset,
-                sizeToRead).order(ByteOrder.LITTLE_ENDIAN);
-
-        buffer.position(sizeToRead - EOCD_MIN_SIZE);
-        while (true) {
-            int signature = buffer.getInt(); // Read 4 bytes.
-            if (signature == EOCD_SIGNATURE) {
-                return readOffset + buffer.position() - 4;
-            }
-            if (buffer.position() == 4) {
-                break;
-            }
-            buffer.position(buffer.position() - Integer.BYTES - 1); // Backtrack 5 bytes.
-        }
-
-        return -1L;
-    }
-
-    private Location findCDRecord(ByteBuffer buf) {
-        if (buf.order() != ByteOrder.LITTLE_ENDIAN) {
-            throw new IllegalArgumentException("ByteBuffer byte order must be little endian");
-        }
-        if (buf.remaining() < CD_ENTRY_HEADER_SIZE_BYTES) {
-            throw new IllegalArgumentException(
-                    "Input too short. Need at least " + CD_ENTRY_HEADER_SIZE_BYTES
-                            + " bytes, available: " + buf.remaining() + "bytes.");
-        }
-
-        int originalPosition = buf.position();
-        int recordSignature = buf.getInt();
-        if (recordSignature != EOCD_SIGNATURE) {
-            throw new IllegalArgumentException(
-                    "Not a Central Directory record. Signature: 0x"
-                            + Long.toHexString(recordSignature & 0xffffffffL));
-        }
-
-        buf.position(originalPosition + CD_LOCAL_FILE_HEADER_SIZE_OFFSET);
-        long size = buf.getInt() & 0xffffffffL;
-        long offset = buf.getInt() & 0xffffffffL;
-        return new Location(offset, size);
-    }
-
-    // Retrieve the location of the Central Directory Record.
-    Location getCDLocation() throws IOException {
-        long eocdRecord = findEndOfCDRecord();
-        if (eocdRecord < 0) {
-            throw new IllegalArgumentException("Unable to find End of Central Directory record.");
-        }
-
-        Location location = findCDRecord(mChannel.map(FileChannel.MapMode.READ_ONLY, eocdRecord,
-                CD_ENTRY_HEADER_SIZE_BYTES).order(ByteOrder.LITTLE_ENDIAN));
-        if (location == null) {
-            throw new IllegalArgumentException("Unable to find Central Directory File Header.");
-        }
-
-        return location;
-    }
-
-    // Retrieve the location of the signature block starting from Central
-    // Directory Record or null if signature is not found.
-    Location getSignatureLocation(long cdRecordOffset) throws IOException {
-        long signatureOffset = cdRecordOffset - EOSIGNATURE_SIZE;
-        if (signatureOffset < 0) {
-            Log.e(TAG, "Unable to find Signature.");
-            return null;
-        }
-
-        ByteBuffer signature = mChannel.map(FileChannel.MapMode.READ_ONLY, signatureOffset,
-                EOSIGNATURE_SIZE).order(ByteOrder.LITTLE_ENDIAN);
-
-        long size = signature.getLong();
-
-        byte[] sign = new byte[16];
-        signature.get(sign);
-        String signAsString = new String(sign);
-        if (!"APK Sig Block 42".equals(signAsString)) {
-            Log.e(TAG, "Signature magic does not match: " + signAsString);
-            return null;
-        }
-
-        long offset = cdRecordOffset - size - 8;
-
-        return new Location(offset, size);
-    }
-
-    private byte[] readMetadata(Location loc) throws IOException {
-        byte[] payload = new byte[(int) loc.size];
-        ByteBuffer buffer = mChannel.map(FileChannel.MapMode.READ_ONLY, loc.offset, loc.size);
-        buffer.get(payload);
-        return payload;
-    }
-}
diff --git a/adb/fastdeploy/deployagent/src/com/android/fastdeploy/DeployAgent.java b/adb/fastdeploy/deployagent/src/com/android/fastdeploy/DeployAgent.java
deleted file mode 100644
index 3812307..0000000
--- a/adb/fastdeploy/deployagent/src/com/android/fastdeploy/DeployAgent.java
+++ /dev/null
@@ -1,337 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.fastdeploy;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.io.RandomAccessFile;
-import java.nio.channels.Channels;
-import java.nio.channels.FileChannel;
-import java.nio.channels.WritableByteChannel;
-
-import com.android.fastdeploy.PatchFormatException;
-import com.android.fastdeploy.ApkArchive;
-import com.android.fastdeploy.APKDump;
-import com.android.fastdeploy.APKMetaData;
-import com.android.fastdeploy.PatchUtils;
-
-import com.google.protobuf.ByteString;
-
-public final class DeployAgent {
-    private static final int BUFFER_SIZE = 128 * 1024;
-    private static final int AGENT_VERSION = 0x00000003;
-
-    public static void main(String[] args) {
-        int exitCode = 0;
-        try {
-            if (args.length < 1) {
-                showUsage(0);
-            }
-
-            String commandString = args[0];
-            switch (commandString) {
-                case "dump": {
-                    if (args.length != 3) {
-                        showUsage(1);
-                    }
-
-                    String requiredVersion = args[1];
-                    if (AGENT_VERSION == Integer.parseInt(requiredVersion)) {
-                        String packageName = args[2];
-                        String packagePath = getFilenameFromPackageName(packageName);
-                        if (packagePath != null) {
-                            dumpApk(packageName, packagePath);
-                        } else {
-                            exitCode = 3;
-                        }
-                    } else {
-                        System.out.printf("0x%08X\n", AGENT_VERSION);
-                        exitCode = 4;
-                    }
-                    break;
-                }
-                case "apply": {
-                    if (args.length < 3) {
-                        showUsage(1);
-                    }
-
-                    String patchPath = args[1];
-                    String outputParam = args[2];
-
-                    InputStream deltaInputStream = null;
-                    if (patchPath.compareTo("-") == 0) {
-                        deltaInputStream = System.in;
-                    } else {
-                        deltaInputStream = new FileInputStream(patchPath);
-                    }
-
-                    if (outputParam.equals("-o")) {
-                        OutputStream outputStream = null;
-                        if (args.length > 3) {
-                            String outputPath = args[3];
-                            if (!outputPath.equals("-")) {
-                                outputStream = new FileOutputStream(outputPath);
-                            }
-                        }
-                        if (outputStream == null) {
-                            outputStream = System.out;
-                        }
-                        writePatchToStream(deltaInputStream, outputStream);
-                    } else if (outputParam.equals("-pm")) {
-                        String[] sessionArgs = null;
-                        if (args.length > 3) {
-                            int numSessionArgs = args.length - 3;
-                            sessionArgs = new String[numSessionArgs];
-                            for (int i = 0; i < numSessionArgs; i++) {
-                                sessionArgs[i] = args[i + 3];
-                            }
-                        }
-                        exitCode = applyPatch(deltaInputStream, sessionArgs);
-                    }
-                    break;
-                }
-                default:
-                    showUsage(1);
-                    break;
-            }
-        } catch (Exception e) {
-            System.err.println("Error: " + e);
-            e.printStackTrace();
-            System.exit(2);
-        }
-        System.exit(exitCode);
-    }
-
-    private static void showUsage(int exitCode) {
-        System.err.println(
-                "usage: deployagent <command> [<args>]\n\n" +
-                        "commands:\n" +
-                        "dump VERSION PKGNAME  dump info for an installed package given that " +
-                        "VERSION equals current agent's version\n" +
-                        "apply PATCHFILE [-o|-pm]    apply a patch from PATCHFILE " +
-                        "(- for stdin) to an installed package\n" +
-                        " -o <FILE> directs output to FILE, default or - for stdout\n" +
-                        " -pm <ARGS> directs output to package manager, passes <ARGS> to " +
-                        "'pm install-create'\n"
-        );
-        System.exit(exitCode);
-    }
-
-    private static Process executeCommand(String command) throws IOException {
-        try {
-            Process p;
-            p = Runtime.getRuntime().exec(command);
-            p.waitFor();
-            return p;
-        } catch (InterruptedException e) {
-            e.printStackTrace();
-        }
-
-        return null;
-    }
-
-    private static String getFilenameFromPackageName(String packageName) throws IOException {
-        StringBuilder commandBuilder = new StringBuilder();
-        commandBuilder.append("pm list packages -f " + packageName);
-
-        Process p = executeCommand(commandBuilder.toString());
-        BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
-
-        String packagePrefix = "package:";
-        String packageSuffix = "=" + packageName;
-        String line = "";
-        while ((line = reader.readLine()) != null) {
-            if (line.endsWith(packageSuffix)) {
-                int packageIndex = line.indexOf(packagePrefix);
-                if (packageIndex == -1) {
-                    throw new IOException("error reading package list");
-                }
-                int equalsIndex = line.lastIndexOf(packageSuffix);
-                String fileName =
-                        line.substring(packageIndex + packagePrefix.length(), equalsIndex);
-                return fileName;
-            }
-        }
-        return null;
-    }
-
-    private static void dumpApk(String packageName, String packagePath) throws IOException {
-        File apk = new File(packagePath);
-        ApkArchive.Dump dump = new ApkArchive(apk).extractMetadata();
-
-        APKDump.Builder apkDumpBuilder = APKDump.newBuilder();
-        apkDumpBuilder.setName(packageName);
-        if (dump.cd != null) {
-            apkDumpBuilder.setCd(ByteString.copyFrom(dump.cd));
-        }
-        if (dump.signature != null) {
-            apkDumpBuilder.setSignature(ByteString.copyFrom(dump.signature));
-        }
-        apkDumpBuilder.setAbsolutePath(apk.getAbsolutePath());
-
-        apkDumpBuilder.build().writeTo(System.out);
-    }
-
-    private static int createInstallSession(String[] args) throws IOException {
-        StringBuilder commandBuilder = new StringBuilder();
-        commandBuilder.append("pm install-create ");
-        for (int i = 0; args != null && i < args.length; i++) {
-            commandBuilder.append(args[i] + " ");
-        }
-
-        Process p = executeCommand(commandBuilder.toString());
-
-        BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
-        String line = "";
-        String successLineStart = "Success: created install session [";
-        String successLineEnd = "]";
-        while ((line = reader.readLine()) != null) {
-            if (line.startsWith(successLineStart) && line.endsWith(successLineEnd)) {
-                return Integer.parseInt(line.substring(successLineStart.length(),
-                        line.lastIndexOf(successLineEnd)));
-            }
-        }
-
-        return -1;
-    }
-
-    private static int commitInstallSession(int sessionId) throws IOException {
-        StringBuilder commandBuilder = new StringBuilder();
-        commandBuilder.append(String.format("pm install-commit %d -- - ", sessionId));
-        Process p = executeCommand(commandBuilder.toString());
-        return p.exitValue();
-    }
-
-    private static int applyPatch(InputStream deltaStream, String[] sessionArgs)
-            throws IOException, PatchFormatException {
-        int sessionId = createInstallSession(sessionArgs);
-        if (sessionId < 0) {
-            System.err.println("PM Create Session Failed");
-            return -1;
-        }
-
-        int writeExitCode = writePatchedDataToSession(deltaStream, sessionId);
-        if (writeExitCode == 0) {
-            return commitInstallSession(sessionId);
-        } else {
-            return -1;
-        }
-    }
-
-    private static long writePatchToStream(InputStream patchData,
-            OutputStream outputStream) throws IOException, PatchFormatException {
-        long newSize = readPatchHeader(patchData);
-        long bytesWritten = writePatchedDataToStream(newSize, patchData, outputStream);
-        outputStream.flush();
-        if (bytesWritten != newSize) {
-            throw new PatchFormatException(String.format(
-                    "output size mismatch (expected %ld but wrote %ld)", newSize, bytesWritten));
-        }
-        return bytesWritten;
-    }
-
-    private static long readPatchHeader(InputStream patchData)
-            throws IOException, PatchFormatException {
-        byte[] signatureBuffer = new byte[PatchUtils.SIGNATURE.length()];
-        try {
-            PatchUtils.readFully(patchData, signatureBuffer);
-        } catch (IOException e) {
-            throw new PatchFormatException("truncated signature");
-        }
-
-        String signature = new String(signatureBuffer);
-        if (!PatchUtils.SIGNATURE.equals(signature)) {
-            throw new PatchFormatException("bad signature");
-        }
-
-        long newSize = PatchUtils.readLELong(patchData);
-        if (newSize < 0) {
-            throw new PatchFormatException("bad newSize: " + newSize);
-        }
-
-        return newSize;
-    }
-
-    // Note that this function assumes patchData has been seek'ed to the start of the delta stream
-    // (i.e. the signature has already been read by readPatchHeader). For a stream that points to
-    // the start of a patch file call writePatchToStream
-    private static long writePatchedDataToStream(long newSize, InputStream patchData,
-            OutputStream outputStream) throws IOException {
-        String deviceFile = PatchUtils.readString(patchData);
-        RandomAccessFile oldDataFile = new RandomAccessFile(deviceFile, "r");
-        FileChannel oldData = oldDataFile.getChannel();
-
-        WritableByteChannel newData = Channels.newChannel(outputStream);
-
-        long newDataBytesWritten = 0;
-        byte[] buffer = new byte[BUFFER_SIZE];
-
-        while (newDataBytesWritten < newSize) {
-            long newDataLen = PatchUtils.readLELong(patchData);
-            if (newDataLen > 0) {
-                PatchUtils.pipe(patchData, outputStream, buffer, newDataLen);
-            }
-
-            long oldDataOffset = PatchUtils.readLELong(patchData);
-            long oldDataLen = PatchUtils.readLELong(patchData);
-            if (oldDataLen >= 0) {
-                long offset = oldDataOffset;
-                long len = oldDataLen;
-                while (len > 0) {
-                    long chunkLen = Math.min(len, 1024*1024*1024);
-                    oldData.transferTo(offset, chunkLen, newData);
-                    offset += chunkLen;
-                    len -= chunkLen;
-                }
-            }
-            newDataBytesWritten += newDataLen + oldDataLen;
-        }
-
-        return newDataBytesWritten;
-    }
-
-    private static int writePatchedDataToSession(InputStream patchData, int sessionId)
-            throws IOException, PatchFormatException {
-        try {
-            Process p;
-            long newSize = readPatchHeader(patchData);
-            String command = String.format("pm install-write -S %d %d -- -", newSize, sessionId);
-            p = Runtime.getRuntime().exec(command);
-
-            OutputStream sessionOutputStream = p.getOutputStream();
-            long bytesWritten = writePatchedDataToStream(newSize, patchData, sessionOutputStream);
-            sessionOutputStream.flush();
-            p.waitFor();
-            if (bytesWritten != newSize) {
-                throw new PatchFormatException(
-                        String.format("output size mismatch (expected %d but wrote %)", newSize,
-                                bytesWritten));
-            }
-            return p.exitValue();
-        } catch (InterruptedException e) {
-            e.printStackTrace();
-        }
-
-        return -1;
-    }
-}
diff --git a/adb/fastdeploy/deployagent/src/com/android/fastdeploy/PatchFormatException.java b/adb/fastdeploy/deployagent/src/com/android/fastdeploy/PatchFormatException.java
deleted file mode 100644
index f0655f3..0000000
--- a/adb/fastdeploy/deployagent/src/com/android/fastdeploy/PatchFormatException.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.fastdeploy;
-
-class PatchFormatException extends Exception {
-    /**
-     * Constructs a new exception with the specified message.
-     * @param message the message
-     */
-    public PatchFormatException(String message) { super(message); }
-
-    /**
-     * Constructs a new exception with the specified message and cause.
-     * @param message the message
-     * @param cause the cause of the error
-     */
-    public PatchFormatException(String message, Throwable cause) {
-        super(message);
-        initCause(cause);
-    }
-}
diff --git a/adb/fastdeploy/deployagent/src/com/android/fastdeploy/PatchUtils.java b/adb/fastdeploy/deployagent/src/com/android/fastdeploy/PatchUtils.java
deleted file mode 100644
index 54be26f..0000000
--- a/adb/fastdeploy/deployagent/src/com/android/fastdeploy/PatchUtils.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.fastdeploy;
-
-import java.io.DataInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-
-class PatchUtils {
-    public static final String SIGNATURE = "FASTDEPLOY";
-
-    /**
-     * Reads a 64-bit signed integer in Little Endian format from the specified {@link
-     * DataInputStream}.
-     *
-     * @param in the stream to read from.
-     */
-    static long readLELong(InputStream in) throws IOException {
-        byte[] buffer = new byte[Long.BYTES];
-        readFully(in, buffer);
-        ByteBuffer buf = ByteBuffer.wrap(buffer).order(ByteOrder.LITTLE_ENDIAN);
-        return buf.getLong();
-    }
-
-    static String readString(InputStream in) throws IOException {
-        int size = (int) readLELong(in);
-        byte[] buffer = new byte[size];
-        readFully(in, buffer);
-        return new String(buffer);
-    }
-
-    static void readFully(final InputStream in, final byte[] destination, final int startAt,
-            final int numBytes) throws IOException {
-        int numRead = 0;
-        while (numRead < numBytes) {
-            int readNow = in.read(destination, startAt + numRead, numBytes - numRead);
-            if (readNow == -1) {
-                throw new IOException("truncated input stream");
-            }
-            numRead += readNow;
-        }
-    }
-
-    static void readFully(final InputStream in, final byte[] destination) throws IOException {
-        readFully(in, destination, 0, destination.length);
-    }
-
-    static void pipe(final InputStream in, final OutputStream out, final byte[] buffer,
-            long copyLength) throws IOException {
-        while (copyLength > 0) {
-            int maxCopy = (int) Math.min(buffer.length, copyLength);
-            readFully(in, buffer, 0, maxCopy);
-            out.write(buffer, 0, maxCopy);
-            copyLength -= maxCopy;
-        }
-    }
-}
diff --git a/adb/fastdeploy/deployagent/test/com/android/fastdeploy/ApkArchiveTest.java b/adb/fastdeploy/deployagent/test/com/android/fastdeploy/ApkArchiveTest.java
deleted file mode 100644
index 7c2468f..0000000
--- a/adb/fastdeploy/deployagent/test/com/android/fastdeploy/ApkArchiveTest.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.fastdeploy;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotEquals;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Assert;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import com.android.fastdeploy.ApkArchive;
-
-import java.io.File;
-import java.io.IOException;
-
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class ApkArchiveTest {
-    private static final File SAMPLE_APK = new File("/data/local/tmp/FastDeployTests/sample.apk");
-    private static final File WRONG_APK = new File("/data/local/tmp/FastDeployTests/sample.cd");
-
-    @Test
-    public void testApkArchiveSizes() throws IOException {
-        ApkArchive archive = new ApkArchive(SAMPLE_APK);
-
-        ApkArchive.Location cdLoc = archive.getCDLocation();
-        assertNotEquals(cdLoc, null);
-        assertEquals(cdLoc.offset, 2044145);
-        assertEquals(cdLoc.size, 49390);
-
-        // Check that block can be retrieved
-        ApkArchive.Location sigLoc = archive.getSignatureLocation(cdLoc.offset);
-        assertNotEquals(sigLoc, null);
-        assertEquals(sigLoc.offset, 2040049);
-        assertEquals(sigLoc.size, 4088);
-    }
-
-    @Test
-    public void testApkArchiveDump() throws IOException {
-        ApkArchive archive = new ApkArchive(SAMPLE_APK);
-
-        ApkArchive.Dump dump = archive.extractMetadata();
-        assertNotEquals(dump, null);
-        assertNotEquals(dump.cd, null);
-        assertNotEquals(dump.signature, null);
-        assertEquals(dump.cd.length, 49390);
-        assertEquals(dump.signature.length, 4088);
-    }
-
-    @Test(expected = IllegalArgumentException.class)
-    public void testApkArchiveDumpWrongApk() throws IOException {
-        ApkArchive archive = new ApkArchive(WRONG_APK);
-
-        archive.extractMetadata();
-    }
-}
diff --git a/adb/fastdeploy/deployagent/test/com/android/fastdeploy/FastDeployTest.java b/adb/fastdeploy/deployagent/test/com/android/fastdeploy/FastDeployTest.java
deleted file mode 100644
index 4aa2f79..0000000
--- a/adb/fastdeploy/deployagent/test/com/android/fastdeploy/FastDeployTest.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.fastdeploy;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
-import com.android.ddmlib.Log.LogLevel;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.io.IOException;
-import java.util.Arrays;
-
-@RunWith(DeviceJUnit4ClassRunner.class)
-public class FastDeployTest extends BaseHostJUnit4Test {
-
-    private static final String TEST_APP_PACKAGE = "com.example.helloworld";
-    private static final String TEST_APK5_NAME = "helloworld5.apk";
-    private static final String TEST_APK7_NAME = "helloworld7.apk";
-
-    private String mTestApk5Path;
-    private String mTestApk7Path;
-
-    @Before
-    public void setUp() throws Exception {
-        CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(getBuild());
-        getDevice().uninstallPackage(TEST_APP_PACKAGE);
-        mTestApk5Path = buildHelper.getTestFile(TEST_APK5_NAME).getAbsolutePath();
-        mTestApk7Path = buildHelper.getTestFile(TEST_APK7_NAME).getAbsolutePath();
-    }
-
-    @Test
-    public void testAppInstalls() throws Exception {
-        fastInstallPackage(mTestApk5Path);
-        assertTrue(isAppInstalled(TEST_APP_PACKAGE));
-        getDevice().uninstallPackage(TEST_APP_PACKAGE);
-        assertFalse(isAppInstalled(TEST_APP_PACKAGE));
-    }
-
-    @Test
-    public void testAppPatch() throws Exception {
-        fastInstallPackage(mTestApk5Path);
-        assertTrue(isAppInstalled(TEST_APP_PACKAGE));
-        fastInstallPackage(mTestApk7Path);
-        assertTrue(isAppInstalled(TEST_APP_PACKAGE));
-        getDevice().uninstallPackage(TEST_APP_PACKAGE);
-        assertFalse(isAppInstalled(TEST_APP_PACKAGE));
-    }
-
-    private boolean isAppInstalled(String packageName) throws DeviceNotAvailableException {
-        final String result = getDevice().executeShellCommand("pm list packages");
-        CLog.logAndDisplay(LogLevel.INFO, result);
-        final int prefixLength = "package:".length();
-        return Arrays.stream(result.split("\\r?\\n"))
-                .anyMatch(line -> line.substring(prefixLength).equals(packageName));
-    }
-
-    // Mostly copied from PkgInstallSignatureVerificationTest.java.
-    private void fastInstallPackage(String apkPath)
-            throws IOException, DeviceNotAvailableException {
-        String result = getDevice().executeAdbCommand("install", "-t", "--fastdeploy", "--force-agent",
-                apkPath);
-        CLog.logAndDisplay(LogLevel.INFO, result);
-    }
-}
-
-
diff --git a/adb/fastdeploy/deploypatchgenerator/apk_archive.cpp b/adb/fastdeploy/deploypatchgenerator/apk_archive.cpp
deleted file mode 100644
index 9da256e..0000000
--- a/adb/fastdeploy/deploypatchgenerator/apk_archive.cpp
+++ /dev/null
@@ -1,417 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define TRACE_TAG ADB
-
-#include "apk_archive.h"
-
-#include <inttypes.h>
-
-#include "adb_trace.h"
-#include "sysdeps.h"
-
-#include <android-base/endian.h>
-#include <android-base/mapped_file.h>
-
-#include <openssl/md5.h>
-
-constexpr uint16_t kCompressStored = 0;
-
-// mask value that signifies that the entry has a DD
-static const uint32_t kGPBDDFlagMask = 0x0008;
-
-namespace {
-struct FileRegion {
-    FileRegion(borrowed_fd fd, off64_t offset, size_t length)
-        : mapped_(android::base::MappedFile::FromOsHandle(adb_get_os_handle(fd), offset, length,
-                                                          PROT_READ)) {
-        if (mapped_ != nullptr) {
-            return;
-        }
-
-        // Mapped file failed, falling back to pread.
-        buffer_.resize(length);
-        if (auto err = adb_pread(fd.get(), buffer_.data(), length, offset); size_t(err) != length) {
-            fprintf(stderr, "Unable to read %lld bytes at offset %" PRId64 " \n",
-                    static_cast<long long>(length), offset);
-            buffer_.clear();
-            return;
-        }
-    }
-
-    const char* data() const { return mapped_ ? mapped_->data() : buffer_.data(); }
-    size_t size() const { return mapped_ ? mapped_->size() : buffer_.size(); }
-
-  private:
-    FileRegion() = default;
-    DISALLOW_COPY_AND_ASSIGN(FileRegion);
-
-    std::unique_ptr<android::base::MappedFile> mapped_;
-    std::string buffer_;
-};
-}  // namespace
-
-using com::android::fastdeploy::APKDump;
-
-ApkArchive::ApkArchive(const std::string& path) : path_(path), size_(0) {
-    fd_.reset(adb_open(path_.c_str(), O_RDONLY));
-    if (fd_ == -1) {
-        fprintf(stderr, "Unable to open file '%s'\n", path_.c_str());
-        return;
-    }
-
-    struct stat st;
-    if (stat(path_.c_str(), &st) == -1) {
-        fprintf(stderr, "Unable to stat file '%s'\n", path_.c_str());
-        return;
-    }
-    size_ = st.st_size;
-}
-
-ApkArchive::~ApkArchive() {}
-
-APKDump ApkArchive::ExtractMetadata() {
-    D("ExtractMetadata");
-    if (!ready()) {
-        return {};
-    }
-
-    Location cdLoc = GetCDLocation();
-    if (!cdLoc.valid) {
-        return {};
-    }
-
-    APKDump dump;
-    dump.set_absolute_path(path_);
-    dump.set_cd(ReadMetadata(cdLoc));
-
-    Location sigLoc = GetSignatureLocation(cdLoc.offset);
-    if (sigLoc.valid) {
-        dump.set_signature(ReadMetadata(sigLoc));
-    }
-    return dump;
-}
-
-off_t ApkArchive::FindEndOfCDRecord() const {
-    constexpr int endOfCDSignature = 0x06054b50;
-    constexpr off_t endOfCDMinSize = 22;
-    constexpr off_t endOfCDMaxSize = 65535 + endOfCDMinSize;
-
-    auto sizeToRead = std::min(size_, endOfCDMaxSize);
-    auto readOffset = size_ - sizeToRead;
-    FileRegion mapped(fd_, readOffset, sizeToRead);
-
-    // Start scanning from the end
-    auto* start = mapped.data();
-    auto* cursor = start + mapped.size() - sizeof(endOfCDSignature);
-
-    // Search for End of Central Directory record signature.
-    while (cursor >= start) {
-        if (*(int32_t*)cursor == endOfCDSignature) {
-            return readOffset + (cursor - start);
-        }
-        cursor--;
-    }
-    return -1;
-}
-
-ApkArchive::Location ApkArchive::FindCDRecord(const char* cursor) {
-    struct ecdr_t {
-        int32_t signature;
-        uint16_t diskNumber;
-        uint16_t numDisk;
-        uint16_t diskEntries;
-        uint16_t numEntries;
-        uint32_t crSize;
-        uint32_t offsetToCdHeader;
-        uint16_t commentSize;
-        uint8_t comment[0];
-    } __attribute__((packed));
-    ecdr_t* header = (ecdr_t*)cursor;
-
-    Location location;
-    location.offset = header->offsetToCdHeader;
-    location.size = header->crSize;
-    location.valid = true;
-    return location;
-}
-
-ApkArchive::Location ApkArchive::GetCDLocation() {
-    constexpr off_t cdEntryHeaderSizeBytes = 22;
-    Location location;
-
-    // Find End of Central Directory Record
-    off_t eocdRecord = FindEndOfCDRecord();
-    if (eocdRecord < 0) {
-        fprintf(stderr, "Unable to find End of Central Directory record in file '%s'\n",
-                path_.c_str());
-        return location;
-    }
-
-    // Find Central Directory Record
-    FileRegion mapped(fd_, eocdRecord, cdEntryHeaderSizeBytes);
-    location = FindCDRecord(mapped.data());
-    if (!location.valid) {
-        fprintf(stderr, "Unable to find Central Directory File Header in file '%s'\n",
-                path_.c_str());
-        return location;
-    }
-
-    return location;
-}
-
-ApkArchive::Location ApkArchive::GetSignatureLocation(off_t cdRecordOffset) {
-    Location location;
-
-    // Signature constants.
-    constexpr off_t endOfSignatureSize = 24;
-    off_t signatureOffset = cdRecordOffset - endOfSignatureSize;
-    if (signatureOffset < 0) {
-        fprintf(stderr, "Unable to find signature in file '%s'\n", path_.c_str());
-        return location;
-    }
-
-    FileRegion mapped(fd_, signatureOffset, endOfSignatureSize);
-
-    uint64_t signatureSize = *(uint64_t*)mapped.data();
-    auto* signature = mapped.data() + sizeof(signatureSize);
-    // Check if there is a v2/v3 Signature block here.
-    if (memcmp(signature, "APK Sig Block 42", 16)) {
-        return location;
-    }
-
-    // This is likely a signature block.
-    location.size = signatureSize;
-    location.offset = cdRecordOffset - location.size - 8;
-    location.valid = true;
-
-    return location;
-}
-
-std::string ApkArchive::ReadMetadata(Location loc) const {
-    FileRegion mapped(fd_, loc.offset, loc.size);
-    return {mapped.data(), mapped.size()};
-}
-
-size_t ApkArchive::ParseCentralDirectoryRecord(const char* input, size_t size, std::string* md5Hash,
-                                               int64_t* localFileHeaderOffset, int64_t* dataSize) {
-    // A structure representing the fixed length fields for a single
-    // record in the central directory of the archive. In addition to
-    // the fixed length fields listed here, each central directory
-    // record contains a variable length "file_name" and "extra_field"
-    // whose lengths are given by |file_name_length| and |extra_field_length|
-    // respectively.
-    static constexpr int kCDFileHeaderMagic = 0x02014b50;
-    struct CentralDirectoryRecord {
-        // The start of record signature. Must be |kSignature|.
-        uint32_t record_signature;
-        // Source tool version. Top byte gives source OS.
-        uint16_t version_made_by;
-        // Tool version. Ignored by this implementation.
-        uint16_t version_needed;
-        // The "general purpose bit flags" for this entry. The only
-        // flag value that we currently check for is the "data descriptor"
-        // flag.
-        uint16_t gpb_flags;
-        // The compression method for this entry, one of |kCompressStored|
-        // and |kCompressDeflated|.
-        uint16_t compression_method;
-        // The file modification time and date for this entry.
-        uint16_t last_mod_time;
-        uint16_t last_mod_date;
-        // The CRC-32 checksum for this entry.
-        uint32_t crc32;
-        // The compressed size (in bytes) of this entry.
-        uint32_t compressed_size;
-        // The uncompressed size (in bytes) of this entry.
-        uint32_t uncompressed_size;
-        // The length of the entry file name in bytes. The file name
-        // will appear immediately after this record.
-        uint16_t file_name_length;
-        // The length of the extra field info (in bytes). This data
-        // will appear immediately after the entry file name.
-        uint16_t extra_field_length;
-        // The length of the entry comment (in bytes). This data will
-        // appear immediately after the extra field.
-        uint16_t comment_length;
-        // The start disk for this entry. Ignored by this implementation).
-        uint16_t file_start_disk;
-        // File attributes. Ignored by this implementation.
-        uint16_t internal_file_attributes;
-        // File attributes. For archives created on Unix, the top bits are the
-        // mode.
-        uint32_t external_file_attributes;
-        // The offset to the local file header for this entry, from the
-        // beginning of this archive.
-        uint32_t local_file_header_offset;
-
-      private:
-        CentralDirectoryRecord() = default;
-        DISALLOW_COPY_AND_ASSIGN(CentralDirectoryRecord);
-    } __attribute__((packed));
-
-    const CentralDirectoryRecord* cdr;
-    if (size < sizeof(*cdr)) {
-        return 0;
-    }
-
-    auto begin = input;
-    cdr = reinterpret_cast<const CentralDirectoryRecord*>(begin);
-    if (cdr->record_signature != kCDFileHeaderMagic) {
-        fprintf(stderr, "Invalid Central Directory Record signature\n");
-        return 0;
-    }
-    auto end = begin + sizeof(*cdr) + cdr->file_name_length + cdr->extra_field_length +
-               cdr->comment_length;
-
-    uint8_t md5Digest[MD5_DIGEST_LENGTH];
-    MD5((const unsigned char*)begin, end - begin, md5Digest);
-    md5Hash->assign((const char*)md5Digest, sizeof(md5Digest));
-
-    *localFileHeaderOffset = cdr->local_file_header_offset;
-    *dataSize = (cdr->compression_method == kCompressStored) ? cdr->uncompressed_size
-                                                             : cdr->compressed_size;
-
-    return end - begin;
-}
-
-size_t ApkArchive::CalculateLocalFileEntrySize(int64_t localFileHeaderOffset,
-                                               int64_t dataSize) const {
-    // The local file header for a given entry. This duplicates information
-    // present in the central directory of the archive. It is an error for
-    // the information here to be different from the central directory
-    // information for a given entry.
-    static constexpr int kLocalFileHeaderMagic = 0x04034b50;
-    struct LocalFileHeader {
-        // The local file header signature, must be |kSignature|.
-        uint32_t lfh_signature;
-        // Tool version. Ignored by this implementation.
-        uint16_t version_needed;
-        // The "general purpose bit flags" for this entry. The only
-        // flag value that we currently check for is the "data descriptor"
-        // flag.
-        uint16_t gpb_flags;
-        // The compression method for this entry, one of |kCompressStored|
-        // and |kCompressDeflated|.
-        uint16_t compression_method;
-        // The file modification time and date for this entry.
-        uint16_t last_mod_time;
-        uint16_t last_mod_date;
-        // The CRC-32 checksum for this entry.
-        uint32_t crc32;
-        // The compressed size (in bytes) of this entry.
-        uint32_t compressed_size;
-        // The uncompressed size (in bytes) of this entry.
-        uint32_t uncompressed_size;
-        // The length of the entry file name in bytes. The file name
-        // will appear immediately after this record.
-        uint16_t file_name_length;
-        // The length of the extra field info (in bytes). This data
-        // will appear immediately after the entry file name.
-        uint16_t extra_field_length;
-
-      private:
-        LocalFileHeader() = default;
-        DISALLOW_COPY_AND_ASSIGN(LocalFileHeader);
-    } __attribute__((packed));
-    static constexpr int kLocalFileHeaderSize = sizeof(LocalFileHeader);
-    CHECK(ready()) << path_;
-
-    const LocalFileHeader* lfh;
-    if (localFileHeaderOffset + kLocalFileHeaderSize > size_) {
-        fprintf(stderr,
-                "Invalid Local File Header offset in file '%s' at offset %lld, file size %lld\n",
-                path_.c_str(), static_cast<long long>(localFileHeaderOffset),
-                static_cast<long long>(size_));
-        return 0;
-    }
-
-    FileRegion lfhMapped(fd_, localFileHeaderOffset, sizeof(LocalFileHeader));
-    lfh = reinterpret_cast<const LocalFileHeader*>(lfhMapped.data());
-    if (lfh->lfh_signature != kLocalFileHeaderMagic) {
-        fprintf(stderr, "Invalid Local File Header signature in file '%s' at offset %lld\n",
-                path_.c_str(), static_cast<long long>(localFileHeaderOffset));
-        return 0;
-    }
-
-    // The *optional* data descriptor start signature.
-    static constexpr int kOptionalDataDescriptorMagic = 0x08074b50;
-    struct DataDescriptor {
-        // CRC-32 checksum of the entry.
-        uint32_t crc32;
-        // Compressed size of the entry.
-        uint32_t compressed_size;
-        // Uncompressed size of the entry.
-        uint32_t uncompressed_size;
-
-      private:
-        DataDescriptor() = default;
-        DISALLOW_COPY_AND_ASSIGN(DataDescriptor);
-    } __attribute__((packed));
-    static constexpr int kDataDescriptorSize = sizeof(DataDescriptor);
-
-    off_t ddOffset = localFileHeaderOffset + kLocalFileHeaderSize + lfh->file_name_length +
-                     lfh->extra_field_length + dataSize;
-    int64_t ddSize = 0;
-
-    int64_t localDataSize;
-    if (lfh->gpb_flags & kGPBDDFlagMask) {
-        // There is trailing data descriptor.
-        const DataDescriptor* dd;
-
-        if (ddOffset + int(sizeof(uint32_t)) > size_) {
-            fprintf(stderr,
-                    "Error reading trailing data descriptor signature in file '%s' at offset %lld, "
-                    "file size %lld\n",
-                    path_.c_str(), static_cast<long long>(ddOffset), static_cast<long long>(size_));
-            return 0;
-        }
-
-        FileRegion ddMapped(fd_, ddOffset, sizeof(uint32_t) + sizeof(DataDescriptor));
-
-        off_t localDDOffset = 0;
-        if (kOptionalDataDescriptorMagic == *(uint32_t*)ddMapped.data()) {
-            ddOffset += sizeof(uint32_t);
-            localDDOffset += sizeof(uint32_t);
-            ddSize += sizeof(uint32_t);
-        }
-        if (ddOffset + kDataDescriptorSize > size_) {
-            fprintf(stderr,
-                    "Error reading trailing data descriptor in file '%s' at offset %lld, file size "
-                    "%lld\n",
-                    path_.c_str(), static_cast<long long>(ddOffset), static_cast<long long>(size_));
-            return 0;
-        }
-
-        dd = reinterpret_cast<const DataDescriptor*>(ddMapped.data() + localDDOffset);
-        localDataSize = (lfh->compression_method == kCompressStored) ? dd->uncompressed_size
-                                                                     : dd->compressed_size;
-        ddSize += sizeof(*dd);
-    } else {
-        localDataSize = (lfh->compression_method == kCompressStored) ? lfh->uncompressed_size
-                                                                     : lfh->compressed_size;
-    }
-    if (localDataSize != dataSize) {
-        fprintf(stderr,
-                "Data sizes mismatch in file '%s' at offset %lld, CDr: %lld vs LHR/DD: %lld\n",
-                path_.c_str(), static_cast<long long>(localFileHeaderOffset),
-                static_cast<long long>(dataSize), static_cast<long long>(localDataSize));
-        return 0;
-    }
-
-    return kLocalFileHeaderSize + lfh->file_name_length + lfh->extra_field_length + dataSize +
-           ddSize;
-}
diff --git a/adb/fastdeploy/deploypatchgenerator/apk_archive.h b/adb/fastdeploy/deploypatchgenerator/apk_archive.h
deleted file mode 100644
index 7127800..0000000
--- a/adb/fastdeploy/deploypatchgenerator/apk_archive.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include <adb_unique_fd.h>
-
-#include "fastdeploy/proto/ApkEntry.pb.h"
-
-class ApkArchiveTester;
-
-// Manipulates an APK archive. Process it by mmaping it in order to minimize
-// I/Os.
-class ApkArchive {
-  public:
-    friend ApkArchiveTester;
-
-    // A convenience struct to store the result of search operation when
-    // locating the EoCDr, CDr, and Signature Block.
-    struct Location {
-        off_t offset = 0;
-        off_t size = 0;
-        bool valid = false;
-    };
-
-    ApkArchive(const std::string& path);
-    ~ApkArchive();
-
-    com::android::fastdeploy::APKDump ExtractMetadata();
-
-    // Parses the CDr starting from |input| and returns number of bytes consumed.
-    // Extracts local file header offset, data size and calculates MD5 hash of the record.
-    // 0 indicates invalid CDr.
-    static size_t ParseCentralDirectoryRecord(const char* input, size_t size, std::string* md5Hash,
-                                              int64_t* localFileHeaderOffset, int64_t* dataSize);
-    // Calculates Local File Entry size including header using offset and data size from CDr.
-    // 0 indicates invalid Local File Entry.
-    size_t CalculateLocalFileEntrySize(int64_t localFileHeaderOffset, int64_t dataSize) const;
-
-  private:
-    std::string ReadMetadata(Location loc) const;
-
-    // Retrieve the location of the Central Directory Record.
-    Location GetCDLocation();
-
-    // Retrieve the location of the signature block starting from Central
-    // Directory Record
-    Location GetSignatureLocation(off_t cdRecordOffset);
-
-    // Find the End of Central Directory Record, starting from the end of the
-    // file.
-    off_t FindEndOfCDRecord() const;
-
-    // Find Central Directory Record, starting from the end of the file.
-    Location FindCDRecord(const char* cursor);
-
-    // Checks if the archive can be used.
-    bool ready() const { return fd_ >= 0; }
-
-    std::string path_;
-    off_t size_;
-    unique_fd fd_;
-};
diff --git a/adb/fastdeploy/deploypatchgenerator/apk_archive_test.cpp b/adb/fastdeploy/deploypatchgenerator/apk_archive_test.cpp
deleted file mode 100644
index 554cb57..0000000
--- a/adb/fastdeploy/deploypatchgenerator/apk_archive_test.cpp
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <iostream>
-
-#include <gtest/gtest.h>
-
-#include "apk_archive.h"
-
-// Friend test to get around private scope of ApkArchive private functions.
-class ApkArchiveTester {
-  public:
-    ApkArchiveTester(const std::string& path) : archive_(path) {}
-
-    bool ready() { return archive_.ready(); }
-
-    auto ExtractMetadata() { return archive_.ExtractMetadata(); }
-
-    ApkArchive::Location GetCDLocation() { return archive_.GetCDLocation(); }
-    ApkArchive::Location GetSignatureLocation(size_t start) {
-        return archive_.GetSignatureLocation(start);
-    }
-
-  private:
-    ApkArchive archive_;
-};
-
-TEST(ApkArchiveTest, TestApkArchiveSizes) {
-    ApkArchiveTester archiveTester("fastdeploy/testdata/sample.apk");
-    EXPECT_TRUE(archiveTester.ready());
-
-    ApkArchive::Location cdLoc = archiveTester.GetCDLocation();
-    EXPECT_TRUE(cdLoc.valid);
-    ASSERT_EQ(cdLoc.offset, 2044145u);
-    ASSERT_EQ(cdLoc.size, 49390u);
-
-    // Check that block can be retrieved
-    ApkArchive::Location sigLoc = archiveTester.GetSignatureLocation(cdLoc.offset);
-    EXPECT_TRUE(sigLoc.valid);
-    ASSERT_EQ(sigLoc.offset, 2040049u);
-    ASSERT_EQ(sigLoc.size, 4088u);
-}
-
-TEST(ApkArchiveTest, TestApkArchiveDump) {
-    ApkArchiveTester archiveTester("fastdeploy/testdata/sample.apk");
-    EXPECT_TRUE(archiveTester.ready());
-
-    auto dump = archiveTester.ExtractMetadata();
-    ASSERT_EQ(dump.cd().size(), 49390u);
-    ASSERT_EQ(dump.signature().size(), 4088u);
-}
-
-TEST(ApkArchiveTest, WrongApk) {
-    ApkArchiveTester archiveTester("fastdeploy/testdata/sample.cd");
-    EXPECT_TRUE(archiveTester.ready());
-
-    auto dump = archiveTester.ExtractMetadata();
-    ASSERT_EQ(dump.cd().size(), 0u);
-    ASSERT_EQ(dump.signature().size(), 0u);
-}
diff --git a/adb/fastdeploy/deploypatchgenerator/deploy_patch_generator.cpp b/adb/fastdeploy/deploypatchgenerator/deploy_patch_generator.cpp
deleted file mode 100644
index 8aa7da7..0000000
--- a/adb/fastdeploy/deploypatchgenerator/deploy_patch_generator.cpp
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "deploy_patch_generator.h"
-
-#include <inttypes.h>
-#include <stdio.h>
-
-#include <algorithm>
-#include <fstream>
-#include <functional>
-#include <iostream>
-#include <sstream>
-#include <string>
-#include <unordered_map>
-
-#include <openssl/md5.h>
-
-#include "adb_unique_fd.h"
-#include "adb_utils.h"
-#include "android-base/file.h"
-#include "patch_utils.h"
-#include "sysdeps.h"
-
-using namespace com::android::fastdeploy;
-
-void DeployPatchGenerator::Log(const char* fmt, ...) {
-    va_list ap;
-    va_start(ap, fmt);
-    vprintf(fmt, ap);
-    printf("\n");
-    va_end(ap);
-}
-
-static std::string HexEncode(const void* in_buffer, unsigned int size) {
-    static const char kHexChars[] = "0123456789ABCDEF";
-
-    // Each input byte creates two output hex characters.
-    std::string out_buffer(size * 2, '\0');
-
-    for (unsigned int i = 0; i < size; ++i) {
-        char byte = ((const uint8_t*)in_buffer)[i];
-        out_buffer[(i << 1)] = kHexChars[(byte >> 4) & 0xf];
-        out_buffer[(i << 1) + 1] = kHexChars[byte & 0xf];
-    }
-    return out_buffer;
-}
-
-void DeployPatchGenerator::APKEntryToLog(const APKEntry& entry) {
-    if (!is_verbose_) {
-        return;
-    }
-    Log("MD5: %s", HexEncode(entry.md5().data(), entry.md5().size()).c_str());
-    Log("Data Offset: %" PRId64, entry.dataoffset());
-    Log("Data Size: %" PRId64, entry.datasize());
-}
-
-void DeployPatchGenerator::APKMetaDataToLog(const APKMetaData& metadata) {
-    if (!is_verbose_) {
-        return;
-    }
-    Log("APK Metadata: %s", metadata.absolute_path().c_str());
-    for (int i = 0; i < metadata.entries_size(); i++) {
-        const APKEntry& entry = metadata.entries(i);
-        APKEntryToLog(entry);
-    }
-}
-
-void DeployPatchGenerator::ReportSavings(const std::vector<SimpleEntry>& identicalEntries,
-                                         uint64_t totalSize) {
-    uint64_t totalEqualBytes = 0;
-    uint64_t totalEqualFiles = 0;
-    for (size_t i = 0; i < identicalEntries.size(); i++) {
-        if (identicalEntries[i].deviceEntry != nullptr) {
-            totalEqualBytes += identicalEntries[i].localEntry->datasize();
-            totalEqualFiles++;
-        }
-    }
-    double savingPercent = (totalEqualBytes * 100.0f) / totalSize;
-    fprintf(stderr, "Detected %" PRIu64 " equal APK entries\n", totalEqualFiles);
-    fprintf(stderr, "%" PRIu64 " bytes are equal out of %" PRIu64 " (%.2f%%)\n", totalEqualBytes,
-            totalSize, savingPercent);
-}
-
-struct PatchEntry {
-    int64_t deltaFromDeviceDataStart = 0;
-    int64_t deviceDataOffset = 0;
-    int64_t deviceDataLength = 0;
-};
-static void WritePatchEntry(const PatchEntry& patchEntry, borrowed_fd input, borrowed_fd output,
-                            size_t* realSizeOut) {
-    if (!(patchEntry.deltaFromDeviceDataStart | patchEntry.deviceDataOffset |
-          patchEntry.deviceDataLength)) {
-        return;
-    }
-
-    PatchUtils::WriteLong(patchEntry.deltaFromDeviceDataStart, output);
-    if (patchEntry.deltaFromDeviceDataStart > 0) {
-        PatchUtils::Pipe(input, output, patchEntry.deltaFromDeviceDataStart);
-    }
-    auto hostDataLength = patchEntry.deviceDataLength;
-    adb_lseek(input, hostDataLength, SEEK_CUR);
-
-    PatchUtils::WriteLong(patchEntry.deviceDataOffset, output);
-    PatchUtils::WriteLong(patchEntry.deviceDataLength, output);
-
-    *realSizeOut += patchEntry.deltaFromDeviceDataStart + hostDataLength;
-}
-
-void DeployPatchGenerator::GeneratePatch(const std::vector<SimpleEntry>& entriesToUseOnDevice,
-                                         const std::string& localApkPath,
-                                         const std::string& deviceApkPath, borrowed_fd output) {
-    unique_fd input(adb_open(localApkPath.c_str(), O_RDONLY | O_CLOEXEC));
-    size_t newApkSize = adb_lseek(input, 0L, SEEK_END);
-    adb_lseek(input, 0L, SEEK_SET);
-
-    // Header.
-    PatchUtils::WriteSignature(output);
-    PatchUtils::WriteLong(newApkSize, output);
-    PatchUtils::WriteString(deviceApkPath, output);
-
-    size_t currentSizeOut = 0;
-    size_t realSizeOut = 0;
-    // Write data from the host upto the first entry we have that matches a device entry. Then write
-    // the metadata about the device entry and repeat for all entries that match on device. Finally
-    // write out any data left. If the device and host APKs are exactly the same this ends up
-    // writing out zip metadata from the local APK followed by offsets to the data to use from the
-    // device APK.
-    PatchEntry patchEntry;
-    for (size_t i = 0, size = entriesToUseOnDevice.size(); i < size; ++i) {
-        auto&& entry = entriesToUseOnDevice[i];
-        int64_t hostDataOffset = entry.localEntry->dataoffset();
-        int64_t hostDataLength = entry.localEntry->datasize();
-        int64_t deviceDataOffset = entry.deviceEntry->dataoffset();
-        // Both entries are the same, using host data length.
-        int64_t deviceDataLength = hostDataLength;
-
-        int64_t deltaFromDeviceDataStart = hostDataOffset - currentSizeOut;
-        if (deltaFromDeviceDataStart > 0) {
-            WritePatchEntry(patchEntry, input, output, &realSizeOut);
-            patchEntry.deltaFromDeviceDataStart = deltaFromDeviceDataStart;
-            patchEntry.deviceDataOffset = deviceDataOffset;
-            patchEntry.deviceDataLength = deviceDataLength;
-        } else {
-            patchEntry.deviceDataLength += deviceDataLength;
-        }
-
-        currentSizeOut += deltaFromDeviceDataStart + hostDataLength;
-    }
-    WritePatchEntry(patchEntry, input, output, &realSizeOut);
-    if (realSizeOut != currentSizeOut) {
-        fprintf(stderr, "Size mismatch current %lld vs real %lld\n",
-                static_cast<long long>(currentSizeOut), static_cast<long long>(realSizeOut));
-        error_exit("Aborting");
-    }
-
-    if (newApkSize > currentSizeOut) {
-        PatchUtils::WriteLong(newApkSize - currentSizeOut, output);
-        PatchUtils::Pipe(input, output, newApkSize - currentSizeOut);
-        PatchUtils::WriteLong(0, output);
-        PatchUtils::WriteLong(0, output);
-    }
-}
-
-bool DeployPatchGenerator::CreatePatch(const char* localApkPath, APKMetaData deviceApkMetadata,
-                                       android::base::borrowed_fd output) {
-    return CreatePatch(PatchUtils::GetHostAPKMetaData(localApkPath), std::move(deviceApkMetadata),
-                       output);
-}
-
-bool DeployPatchGenerator::CreatePatch(APKMetaData localApkMetadata, APKMetaData deviceApkMetadata,
-                                       borrowed_fd output) {
-    // Log metadata info.
-    APKMetaDataToLog(deviceApkMetadata);
-    APKMetaDataToLog(localApkMetadata);
-
-    const std::string localApkPath = localApkMetadata.absolute_path();
-    const std::string deviceApkPath = deviceApkMetadata.absolute_path();
-
-    std::vector<SimpleEntry> identicalEntries;
-    uint64_t totalSize =
-            BuildIdenticalEntries(identicalEntries, localApkMetadata, deviceApkMetadata);
-    ReportSavings(identicalEntries, totalSize);
-    GeneratePatch(identicalEntries, localApkPath, deviceApkPath, output);
-
-    return true;
-}
-
-uint64_t DeployPatchGenerator::BuildIdenticalEntries(std::vector<SimpleEntry>& outIdenticalEntries,
-                                                     const APKMetaData& localApkMetadata,
-                                                     const APKMetaData& deviceApkMetadata) {
-    outIdenticalEntries.reserve(
-            std::min(localApkMetadata.entries_size(), deviceApkMetadata.entries_size()));
-
-    using md5Digest = std::pair<uint64_t, uint64_t>;
-    struct md5Hash {
-        size_t operator()(const md5Digest& digest) const {
-            std::hash<uint64_t> hasher;
-            size_t seed = 0;
-            seed ^= hasher(digest.first) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
-            seed ^= hasher(digest.second) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
-            return seed;
-        }
-    };
-    static_assert(sizeof(md5Digest) == MD5_DIGEST_LENGTH);
-    std::unordered_map<md5Digest, std::vector<const APKEntry*>, md5Hash> deviceEntries;
-    for (const auto& deviceEntry : deviceApkMetadata.entries()) {
-        md5Digest md5;
-        memcpy(&md5, deviceEntry.md5().data(), deviceEntry.md5().size());
-
-        deviceEntries[md5].push_back(&deviceEntry);
-    }
-
-    uint64_t totalSize = 0;
-    for (const auto& localEntry : localApkMetadata.entries()) {
-        totalSize += localEntry.datasize();
-
-        md5Digest md5;
-        memcpy(&md5, localEntry.md5().data(), localEntry.md5().size());
-
-        auto deviceEntriesIt = deviceEntries.find(md5);
-        if (deviceEntriesIt == deviceEntries.end()) {
-            continue;
-        }
-
-        for (const auto* deviceEntry : deviceEntriesIt->second) {
-            if (deviceEntry->md5() == localEntry.md5()) {
-                SimpleEntry simpleEntry;
-                simpleEntry.localEntry = &localEntry;
-                simpleEntry.deviceEntry = deviceEntry;
-                APKEntryToLog(localEntry);
-                outIdenticalEntries.push_back(simpleEntry);
-                break;
-            }
-        }
-    }
-    std::sort(outIdenticalEntries.begin(), outIdenticalEntries.end(),
-              [](const SimpleEntry& lhs, const SimpleEntry& rhs) {
-                  return lhs.localEntry->dataoffset() < rhs.localEntry->dataoffset();
-              });
-    return totalSize;
-}
diff --git a/adb/fastdeploy/deploypatchgenerator/deploy_patch_generator.h b/adb/fastdeploy/deploypatchgenerator/deploy_patch_generator.h
deleted file mode 100644
index fd7eaee..0000000
--- a/adb/fastdeploy/deploypatchgenerator/deploy_patch_generator.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <vector>
-
-#include "adb_unique_fd.h"
-#include "fastdeploy/proto/ApkEntry.pb.h"
-
-/**
- * This class is responsible for creating a patch that can be accepted by the deployagent. The
- * patch format is documented in GeneratePatch.
- */
-class DeployPatchGenerator {
-  public:
-    using APKEntry = com::android::fastdeploy::APKEntry;
-    using APKMetaData = com::android::fastdeploy::APKMetaData;
-
-    /**
-     * Simple struct to hold mapping between local metadata and device metadata.
-     */
-    struct SimpleEntry {
-        const APKEntry* localEntry;
-        const APKEntry* deviceEntry;
-    };
-
-    /**
-     * If |is_verbose| is true ApkEntries that are similar between device and host are written to
-     * the console.
-     */
-    explicit DeployPatchGenerator(bool is_verbose) : is_verbose_(is_verbose) {}
-    /**
-     * Given a |localApkPath|, and the |deviceApkMetadata| from an installed APK this function
-     * writes a patch to the given |output|.
-     */
-    bool CreatePatch(const char* localApkPath, APKMetaData deviceApkMetadata,
-                     android::base::borrowed_fd output);
-
-  private:
-    bool is_verbose_;
-
-    /**
-     * Log function only logs data to stdout when |is_verbose_| is true.
-     */
-    void Log(const char* fmt, ...) __attribute__((__format__(__printf__, 2, 3)));
-
-    /**
-     * Helper function to log the APKMetaData structure. If |is_verbose_| is false this function
-     * early outs. This function is used for debugging / information.
-     */
-    void APKMetaDataToLog(const APKMetaData& metadata);
-    /**
-     * Helper function to log APKEntry.
-     */
-    void APKEntryToLog(const APKEntry& entry);
-
-    /**
-     * Given the |localApkMetadata| metadata, and the |deviceApkMetadata| from an installed APK this
-     * function writes a patch to the given |output|.
-     */
-    bool CreatePatch(APKMetaData localApkMetadata, APKMetaData deviceApkMetadata,
-                     android::base::borrowed_fd output);
-
-    /**
-     * Helper function to report savings by fastdeploy. This function prints out savings even with
-     * |is_verbose_| set to false. |totalSize| is used to show a percentage of savings. Note:
-     * |totalSize| is the size of the ZipEntries. Not the size of the entire file. The metadata of
-     * the zip data needs to be sent across with every iteration.
-     * [Patch format]
-     * |Fixed String| Signature
-     * |long|         New Size of Apk
-     * |Packets[]|    Array of Packets
-     *
-     * [Packet Format]
-     * |long|     Size of data to use from patch
-     * |byte[]|   Patch data
-     * |long|     Offset of data to use already on device
-     * |long|     Length of data to read from device APK
-     * TODO(b/138306784): Move the patch format to a proto.
-     */
-    void ReportSavings(const std::vector<SimpleEntry>& identicalEntries, uint64_t totalSize);
-
-    /**
-     * This enumerates each entry in |entriesToUseOnDevice| and builds a patch file copying data
-     * from |localApkPath| where we are unable to use entries already on the device. The new patch
-     * is written to |output|. The entries are expected to be sorted by data offset from lowest to
-     * highest.
-     */
-    void GeneratePatch(const std::vector<SimpleEntry>& entriesToUseOnDevice,
-                       const std::string& localApkPath, const std::string& deviceApkPath,
-                       android::base::borrowed_fd output);
-
-  protected:
-    uint64_t BuildIdenticalEntries(std::vector<SimpleEntry>& outIdenticalEntries,
-                                   const APKMetaData& localApkMetadata,
-                                   const APKMetaData& deviceApkMetadata);
-};
diff --git a/adb/fastdeploy/deploypatchgenerator/deploy_patch_generator_test.cpp b/adb/fastdeploy/deploypatchgenerator/deploy_patch_generator_test.cpp
deleted file mode 100644
index e4c96ea..0000000
--- a/adb/fastdeploy/deploypatchgenerator/deploy_patch_generator_test.cpp
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "deploy_patch_generator.h"
-#include "apk_archive.h"
-#include "patch_utils.h"
-
-#include <android-base/file.h>
-#include <gtest/gtest.h>
-#include <stdlib.h>
-#include <string.h>
-#include <string>
-
-#include "sysdeps.h"
-
-using namespace com::android::fastdeploy;
-
-static std::string GetTestFile(const std::string& name) {
-    return "fastdeploy/testdata/" + name;
-}
-
-struct TestPatchGenerator : DeployPatchGenerator {
-    using DeployPatchGenerator::BuildIdenticalEntries;
-    using DeployPatchGenerator::DeployPatchGenerator;
-};
-
-TEST(DeployPatchGeneratorTest, IdenticalFileEntries) {
-    std::string apkPath = GetTestFile("rotating_cube-release.apk");
-    APKMetaData metadataA = PatchUtils::GetHostAPKMetaData(apkPath.c_str());
-    TestPatchGenerator generator(false);
-    std::vector<DeployPatchGenerator::SimpleEntry> entries;
-    generator.BuildIdenticalEntries(entries, metadataA, metadataA);
-    // Expect the entry count to match the number of entries in the metadata.
-    const uint32_t identicalCount = entries.size();
-    const uint32_t entriesCount = metadataA.entries_size();
-    EXPECT_EQ(identicalCount, entriesCount);
-}
-
-TEST(DeployPatchGeneratorTest, NoDeviceMetadata) {
-    std::string apkPath = GetTestFile("rotating_cube-release.apk");
-    // Get size of our test apk.
-    long apkSize = 0;
-    {
-        unique_fd apkFile(adb_open(apkPath.c_str(), O_RDWR));
-        apkSize = adb_lseek(apkFile, 0L, SEEK_END);
-    }
-
-    // Create a patch that is 100% different.
-    TemporaryFile output;
-    DeployPatchGenerator generator(true);
-    generator.CreatePatch(apkPath.c_str(), {}, output.fd);
-
-    // Expect a patch file that has a size at least the size of our initial APK.
-    long patchSize = adb_lseek(output.fd, 0L, SEEK_END);
-    EXPECT_GT(patchSize, apkSize);
-}
-
-TEST(DeployPatchGeneratorTest, ZeroSizePatch) {
-    std::string apkPath = GetTestFile("rotating_cube-release.apk");
-    ApkArchive archive(apkPath);
-    auto dump = archive.ExtractMetadata();
-    EXPECT_NE(dump.cd().size(), 0u);
-
-    APKMetaData metadata = PatchUtils::GetDeviceAPKMetaData(dump);
-
-    // Create a patch that is 100% the same.
-    TemporaryFile output;
-    output.DoNotRemove();
-    DeployPatchGenerator generator(true);
-    generator.CreatePatch(apkPath.c_str(), metadata, output.fd);
-
-    // Expect a patch file that is smaller than 0.5K.
-    int64_t patchSize = adb_lseek(output.fd, 0L, SEEK_END);
-    EXPECT_LE(patchSize, 512);
-}
diff --git a/adb/fastdeploy/deploypatchgenerator/patch_utils.cpp b/adb/fastdeploy/deploypatchgenerator/patch_utils.cpp
deleted file mode 100644
index 2b00c80..0000000
--- a/adb/fastdeploy/deploypatchgenerator/patch_utils.cpp
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "patch_utils.h"
-
-#include <stdio.h>
-
-#include "adb_io.h"
-#include "adb_utils.h"
-#include "android-base/endian.h"
-#include "sysdeps.h"
-
-#include "apk_archive.h"
-
-using namespace com::android;
-using namespace com::android::fastdeploy;
-using namespace android::base;
-
-static constexpr char kSignature[] = "FASTDEPLOY";
-
-APKMetaData PatchUtils::GetDeviceAPKMetaData(const APKDump& apk_dump) {
-    APKMetaData apkMetaData;
-    apkMetaData.set_absolute_path(apk_dump.absolute_path());
-
-    std::string md5Hash;
-    int64_t localFileHeaderOffset;
-    int64_t dataSize;
-
-    const auto& cd = apk_dump.cd();
-    auto cur = cd.data();
-    int64_t size = cd.size();
-    while (auto consumed = ApkArchive::ParseCentralDirectoryRecord(
-                   cur, size, &md5Hash, &localFileHeaderOffset, &dataSize)) {
-        cur += consumed;
-        size -= consumed;
-
-        auto apkEntry = apkMetaData.add_entries();
-        apkEntry->set_md5(md5Hash);
-        apkEntry->set_dataoffset(localFileHeaderOffset);
-        apkEntry->set_datasize(dataSize);
-    }
-    return apkMetaData;
-}
-
-APKMetaData PatchUtils::GetHostAPKMetaData(const char* apkPath) {
-    ApkArchive archive(apkPath);
-    auto dump = archive.ExtractMetadata();
-    if (dump.cd().empty()) {
-        fprintf(stderr, "adb: Could not extract Central Directory from %s\n", apkPath);
-        error_exit("Aborting");
-    }
-
-    auto apkMetaData = GetDeviceAPKMetaData(dump);
-
-    // Now let's set data sizes.
-    for (auto& apkEntry : *apkMetaData.mutable_entries()) {
-        auto dataSize =
-                archive.CalculateLocalFileEntrySize(apkEntry.dataoffset(), apkEntry.datasize());
-        if (dataSize == 0) {
-            error_exit("Aborting");
-        }
-        apkEntry.set_datasize(dataSize);
-    }
-
-    return apkMetaData;
-}
-
-void PatchUtils::WriteSignature(borrowed_fd output) {
-    WriteFdExactly(output, kSignature, sizeof(kSignature) - 1);
-}
-
-void PatchUtils::WriteLong(int64_t value, borrowed_fd output) {
-    int64_t littleEndian = htole64(value);
-    WriteFdExactly(output, &littleEndian, sizeof(littleEndian));
-}
-
-void PatchUtils::WriteString(const std::string& value, android::base::borrowed_fd output) {
-    WriteLong(value.size(), output);
-    WriteFdExactly(output, value);
-}
-
-void PatchUtils::Pipe(borrowed_fd input, borrowed_fd output, size_t amount) {
-    constexpr static size_t BUFFER_SIZE = 128 * 1024;
-    char buffer[BUFFER_SIZE];
-    size_t transferAmount = 0;
-    while (transferAmount != amount) {
-        auto chunkAmount = std::min(amount - transferAmount, BUFFER_SIZE);
-        auto readAmount = adb_read(input, buffer, chunkAmount);
-        if (readAmount < 0) {
-            fprintf(stderr, "adb: failed to read from input: %s\n", strerror(errno));
-            error_exit("Aborting");
-        }
-        WriteFdExactly(output, buffer, readAmount);
-        transferAmount += readAmount;
-    }
-}
diff --git a/adb/fastdeploy/deploypatchgenerator/patch_utils.h b/adb/fastdeploy/deploypatchgenerator/patch_utils.h
deleted file mode 100644
index 8dc9b9c..0000000
--- a/adb/fastdeploy/deploypatchgenerator/patch_utils.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "adb_unique_fd.h"
-#include "fastdeploy/proto/ApkEntry.pb.h"
-
-/**
- * Helper class that mirrors the PatchUtils from deploy agent.
- */
-class PatchUtils {
-  public:
-    /**
-     * This function takes the dump of Central Directly and builds the APKMetaData required by the
-     * patching algorithm. The if this function has an error a string is printed to the terminal and
-     * exit(1) is called.
-     */
-    static com::android::fastdeploy::APKMetaData GetDeviceAPKMetaData(
-            const com::android::fastdeploy::APKDump& apk_dump);
-    /**
-     * This function takes a local APK file and builds the APKMetaData required by the patching
-     * algorithm. The if this function has an error a string is printed to the terminal and exit(1)
-     * is called.
-     */
-    static com::android::fastdeploy::APKMetaData GetHostAPKMetaData(const char* file);
-    /**
-     * Writes a fixed signature string to the header of the patch.
-     */
-    static void WriteSignature(android::base::borrowed_fd output);
-    /**
-     * Writes an int64 to the |output| reversing the bytes.
-     */
-    static void WriteLong(int64_t value, android::base::borrowed_fd output);
-    /**
-     * Writes string to the |output|.
-     */
-    static void WriteString(const std::string& value, android::base::borrowed_fd output);
-    /**
-     * Copy |amount| of data from |input| to |output|.
-     */
-    static void Pipe(android::base::borrowed_fd input, android::base::borrowed_fd output,
-                     size_t amount);
-};
diff --git a/adb/fastdeploy/deploypatchgenerator/patch_utils_test.cpp b/adb/fastdeploy/deploypatchgenerator/patch_utils_test.cpp
deleted file mode 100644
index 3ec5ab3..0000000
--- a/adb/fastdeploy/deploypatchgenerator/patch_utils_test.cpp
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "patch_utils.h"
-
-#include <android-base/file.h>
-#include <gtest/gtest.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sstream>
-#include <string>
-
-#include <google/protobuf/util/message_differencer.h>
-
-#include "adb_io.h"
-#include "sysdeps.h"
-
-using namespace com::android::fastdeploy;
-using google::protobuf::util::MessageDifferencer;
-
-static std::string GetTestFile(const std::string& name) {
-    return "fastdeploy/testdata/" + name;
-}
-
-bool FileMatchesContent(android::base::borrowed_fd input, const char* contents,
-                        ssize_t contentsSize) {
-    adb_lseek(input, 0, SEEK_SET);
-    // Use a temp buffer larger than any test contents.
-    constexpr int BUFFER_SIZE = 2048;
-    char buffer[BUFFER_SIZE];
-    bool result = true;
-    // Validate size of files is equal.
-    ssize_t readAmount = adb_read(input, buffer, BUFFER_SIZE);
-    EXPECT_EQ(readAmount, contentsSize);
-    result = memcmp(buffer, contents, readAmount) == 0;
-    for (int i = 0; i < readAmount; i++) {
-        printf("%x", buffer[i]);
-    }
-    printf(" == ");
-    for (int i = 0; i < contentsSize; i++) {
-        printf("%x", contents[i]);
-    }
-    printf("\n");
-
-    return result;
-}
-
-TEST(PatchUtilsTest, SwapLongWrites) {
-    TemporaryFile output;
-    PatchUtils::WriteLong(0x0011223344556677, output.fd);
-    adb_lseek(output.fd, 0, SEEK_SET);
-    const char expected[] = {0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x00};
-    EXPECT_TRUE(FileMatchesContent(output.fd, expected, 8));
-}
-
-TEST(PatchUtilsTest, PipeWritesAmountToOutput) {
-    std::string expected("Some Data");
-    TemporaryFile input;
-    TemporaryFile output;
-    // Populate input file.
-    WriteFdExactly(input.fd, expected);
-    adb_lseek(input.fd, 0, SEEK_SET);
-    // Open input file for read, and output file for write.
-    PatchUtils::Pipe(input.fd, output.fd, expected.size());
-    // Validate pipe worked
-    EXPECT_TRUE(FileMatchesContent(output.fd, expected.c_str(), expected.size()));
-}
-
-TEST(PatchUtilsTest, SignatureConstMatches) {
-    std::string apkFile = GetTestFile("rotating_cube-release.apk");
-    TemporaryFile output;
-    PatchUtils::WriteSignature(output.fd);
-    std::string contents("FASTDEPLOY");
-    EXPECT_TRUE(FileMatchesContent(output.fd, contents.c_str(), contents.size()));
-}
-
-TEST(PatchUtilsTest, GatherMetadata) {
-    std::string apkFile = GetTestFile("rotating_cube-release.apk");
-    APKMetaData actual = PatchUtils::GetHostAPKMetaData(apkFile.c_str());
-
-    std::string expectedMetadata;
-    android::base::ReadFileToString(GetTestFile("rotating_cube-metadata-release.data"),
-                                    &expectedMetadata);
-    APKMetaData expected;
-    EXPECT_TRUE(expected.ParseFromString(expectedMetadata));
-
-    // Test paths might vary.
-    expected.set_absolute_path(actual.absolute_path());
-
-    std::string actualMetadata;
-    actual.SerializeToString(&actualMetadata);
-
-    expected.SerializeToString(&expectedMetadata);
-
-    EXPECT_EQ(expectedMetadata, actualMetadata);
-}
-
-static inline void sanitize(APKMetaData& metadata) {
-    metadata.clear_absolute_path();
-    for (auto&& entry : *metadata.mutable_entries()) {
-        entry.clear_datasize();
-    }
-}
-
-TEST(PatchUtilsTest, GatherDumpMetadata) {
-    APKMetaData hostMetadata;
-    APKMetaData deviceMetadata;
-
-    hostMetadata = PatchUtils::GetHostAPKMetaData(GetTestFile("sample.apk").c_str());
-
-    {
-        std::string cd;
-        android::base::ReadFileToString(GetTestFile("sample.cd"), &cd);
-
-        APKDump dump;
-        dump.set_cd(std::move(cd));
-
-        deviceMetadata = PatchUtils::GetDeviceAPKMetaData(dump);
-    }
-
-    sanitize(hostMetadata);
-    sanitize(deviceMetadata);
-
-    std::string expectedMetadata;
-    hostMetadata.SerializeToString(&expectedMetadata);
-
-    std::string actualMetadata;
-    deviceMetadata.SerializeToString(&actualMetadata);
-
-    EXPECT_EQ(expectedMetadata, actualMetadata);
-}
diff --git a/adb/fastdeploy/proto/ApkEntry.proto b/adb/fastdeploy/proto/ApkEntry.proto
deleted file mode 100644
index d84c5a5..0000000
--- a/adb/fastdeploy/proto/ApkEntry.proto
+++ /dev/null
@@ -1,26 +0,0 @@
-syntax = "proto3";
-
-package com.android.fastdeploy;
-
-option java_package = "com.android.fastdeploy";
-option java_outer_classname = "ApkEntryProto";
-option java_multiple_files = true;
-option optimize_for = LITE_RUNTIME;
-
-message APKDump {
-    string name = 1;
-    bytes cd = 2;
-    bytes signature = 3;
-    string absolute_path = 4;
-}
-
-message APKEntry {
-    bytes md5 = 1;
-    int64 dataOffset = 2;
-    int64 dataSize = 3;
-}
-
-message APKMetaData {
-    string absolute_path = 1;
-    repeated APKEntry entries = 2;
-}
diff --git a/adb/fastdeploy/testdata/helloworld5.apk b/adb/fastdeploy/testdata/helloworld5.apk
deleted file mode 100644
index 4a1539e..0000000
--- a/adb/fastdeploy/testdata/helloworld5.apk
+++ /dev/null
Binary files differ
diff --git a/adb/fastdeploy/testdata/helloworld7.apk b/adb/fastdeploy/testdata/helloworld7.apk
deleted file mode 100644
index 82c46df..0000000
--- a/adb/fastdeploy/testdata/helloworld7.apk
+++ /dev/null
Binary files differ
diff --git a/adb/fastdeploy/testdata/rotating_cube-metadata-release.data b/adb/fastdeploy/testdata/rotating_cube-metadata-release.data
deleted file mode 100644
index 52352ff..0000000
--- a/adb/fastdeploy/testdata/rotating_cube-metadata-release.data
+++ /dev/null
Binary files differ
diff --git a/adb/fastdeploy/testdata/rotating_cube-release.apk b/adb/fastdeploy/testdata/rotating_cube-release.apk
deleted file mode 100644
index d47e0ea..0000000
--- a/adb/fastdeploy/testdata/rotating_cube-release.apk
+++ /dev/null
Binary files differ
diff --git a/adb/fastdeploy/testdata/sample.apk b/adb/fastdeploy/testdata/sample.apk
deleted file mode 100644
index c316205..0000000
--- a/adb/fastdeploy/testdata/sample.apk
+++ /dev/null
Binary files differ
diff --git a/adb/fastdeploy/testdata/sample.cd b/adb/fastdeploy/testdata/sample.cd
deleted file mode 100644
index 5e5b4d4..0000000
--- a/adb/fastdeploy/testdata/sample.cd
+++ /dev/null
Binary files differ
diff --git a/adb/fdevent/fdevent.cpp b/adb/fdevent/fdevent.cpp
deleted file mode 100644
index fd55020..0000000
--- a/adb/fdevent/fdevent.cpp
+++ /dev/null
@@ -1,262 +0,0 @@
-/*
- * Copyright 2006, Brian Swetland <swetland@frotz.net>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define TRACE_TAG FDEVENT
-
-#include "sysdeps.h"
-
-#include <inttypes.h>
-
-#include <android-base/logging.h>
-#include <android-base/stringprintf.h>
-#include <android-base/threads.h>
-
-#include "adb_utils.h"
-#include "fdevent.h"
-#include "fdevent_epoll.h"
-#include "fdevent_poll.h"
-
-using namespace std::chrono_literals;
-using std::chrono::duration_cast;
-
-void invoke_fde(struct fdevent* fde, unsigned events) {
-    if (auto f = std::get_if<fd_func>(&fde->func)) {
-        (*f)(fde->fd.get(), events, fde->arg);
-    } else if (auto f = std::get_if<fd_func2>(&fde->func)) {
-        (*f)(fde, events, fde->arg);
-    } else {
-        __builtin_unreachable();
-    }
-}
-
-std::string dump_fde(const fdevent* fde) {
-    std::string state;
-    if (fde->state & FDE_READ) {
-        state += "R";
-    }
-    if (fde->state & FDE_WRITE) {
-        state += "W";
-    }
-    if (fde->state & FDE_ERROR) {
-        state += "E";
-    }
-    return android::base::StringPrintf("(fdevent %" PRIu64 ": fd %d %s)", fde->id, fde->fd.get(),
-                                       state.c_str());
-}
-
-fdevent* fdevent_context::Create(unique_fd fd, std::variant<fd_func, fd_func2> func, void* arg) {
-    CheckMainThread();
-    CHECK_GE(fd.get(), 0);
-
-    int fd_num = fd.get();
-
-    auto [it, inserted] = this->installed_fdevents_.emplace(fd_num, fdevent{});
-    CHECK(inserted);
-
-    fdevent* fde = &it->second;
-    fde->id = fdevent_id_++;
-    fde->state = 0;
-    fde->fd = std::move(fd);
-    fde->func = func;
-    fde->arg = arg;
-    if (!set_file_block_mode(fde->fd, false)) {
-        // Here is not proper to handle the error. If it fails here, some error is
-        // likely to be detected by poll(), then we can let the callback function
-        // to handle it.
-        LOG(ERROR) << "failed to set non-blocking mode for fd " << fde->fd.get();
-    }
-
-    this->Register(fde);
-    return fde;
-}
-
-unique_fd fdevent_context::Destroy(fdevent* fde) {
-    CheckMainThread();
-    if (!fde) {
-        return {};
-    }
-
-    this->Unregister(fde);
-
-    unique_fd fd = std::move(fde->fd);
-
-    auto erased = this->installed_fdevents_.erase(fd.get());
-    CHECK_EQ(1UL, erased);
-
-    return fd;
-}
-
-void fdevent_context::Add(fdevent* fde, unsigned events) {
-    CHECK(!(events & FDE_TIMEOUT));
-    Set(fde, fde->state | events);
-}
-
-void fdevent_context::Del(fdevent* fde, unsigned events) {
-    CHECK(!(events & FDE_TIMEOUT));
-    Set(fde, fde->state & ~events);
-}
-
-void fdevent_context::SetTimeout(fdevent* fde, std::optional<std::chrono::milliseconds> timeout) {
-    CheckMainThread();
-    fde->timeout = timeout;
-    fde->last_active = std::chrono::steady_clock::now();
-}
-
-std::optional<std::chrono::milliseconds> fdevent_context::CalculatePollDuration() {
-    std::optional<std::chrono::milliseconds> result = std::nullopt;
-    auto now = std::chrono::steady_clock::now();
-    CheckMainThread();
-
-    for (const auto& [fd, fde] : this->installed_fdevents_) {
-        UNUSED(fd);
-        auto timeout_opt = fde.timeout;
-        if (timeout_opt) {
-            auto deadline = fde.last_active + *timeout_opt;
-            auto time_left = duration_cast<std::chrono::milliseconds>(deadline - now);
-            if (time_left < 0ms) {
-                time_left = 0ms;
-            }
-
-            if (!result) {
-                result = time_left;
-            } else {
-                result = std::min(*result, time_left);
-            }
-        }
-    }
-
-    return result;
-}
-
-void fdevent_context::HandleEvents(const std::vector<fdevent_event>& events) {
-    for (const auto& event : events) {
-        invoke_fde(event.fde, event.events);
-    }
-    FlushRunQueue();
-}
-
-void fdevent_context::FlushRunQueue() {
-    // We need to be careful around reentrancy here, since a function we call can queue up another
-    // function.
-    while (true) {
-        std::function<void()> fn;
-        {
-            std::lock_guard<std::mutex> lock(this->run_queue_mutex_);
-            if (this->run_queue_.empty()) {
-                break;
-            }
-            fn = std::move(this->run_queue_.front());
-            this->run_queue_.pop_front();
-        }
-        fn();
-    }
-}
-
-void fdevent_context::CheckMainThread() {
-    if (main_thread_id_) {
-        CHECK_EQ(*main_thread_id_, android::base::GetThreadId());
-    }
-}
-
-void fdevent_context::Run(std::function<void()> fn) {
-    {
-        std::lock_guard<std::mutex> lock(run_queue_mutex_);
-        run_queue_.push_back(std::move(fn));
-    }
-
-    Interrupt();
-}
-
-void fdevent_context::TerminateLoop() {
-    terminate_loop_ = true;
-    Interrupt();
-}
-
-static std::unique_ptr<fdevent_context> fdevent_create_context() {
-#if defined(__linux__)
-    return std::make_unique<fdevent_context_epoll>();
-#else
-    return std::make_unique<fdevent_context_poll>();
-#endif
-}
-
-static auto& g_ambient_fdevent_context() {
-    static auto context = fdevent_create_context().release();
-    return context;
-}
-
-static fdevent_context* fdevent_get_ambient() {
-    return g_ambient_fdevent_context();
-}
-
-fdevent* fdevent_create(int fd, fd_func func, void* arg) {
-    unique_fd ufd(fd);
-    return fdevent_get_ambient()->Create(std::move(ufd), func, arg);
-}
-
-fdevent* fdevent_create(int fd, fd_func2 func, void* arg) {
-    unique_fd ufd(fd);
-    return fdevent_get_ambient()->Create(std::move(ufd), func, arg);
-}
-
-unique_fd fdevent_release(fdevent* fde) {
-    return fdevent_get_ambient()->Destroy(fde);
-}
-
-void fdevent_destroy(fdevent* fde) {
-    fdevent_get_ambient()->Destroy(fde);
-}
-
-void fdevent_set(fdevent* fde, unsigned events) {
-    fdevent_get_ambient()->Set(fde, events);
-}
-
-void fdevent_add(fdevent* fde, unsigned events) {
-    fdevent_get_ambient()->Add(fde, events);
-}
-
-void fdevent_del(fdevent* fde, unsigned events) {
-    fdevent_get_ambient()->Del(fde, events);
-}
-
-void fdevent_set_timeout(fdevent* fde, std::optional<std::chrono::milliseconds> timeout) {
-    fdevent_get_ambient()->SetTimeout(fde, timeout);
-}
-
-void fdevent_run_on_main_thread(std::function<void()> fn) {
-    fdevent_get_ambient()->Run(std::move(fn));
-}
-
-void fdevent_loop() {
-    fdevent_get_ambient()->Loop();
-}
-
-void check_main_thread() {
-    fdevent_get_ambient()->CheckMainThread();
-}
-
-void fdevent_terminate_loop() {
-    fdevent_get_ambient()->TerminateLoop();
-}
-
-size_t fdevent_installed_count() {
-    return fdevent_get_ambient()->InstalledCount();
-}
-
-void fdevent_reset() {
-    auto old = std::exchange(g_ambient_fdevent_context(), fdevent_create_context().release());
-    delete old;
-}
diff --git a/adb/fdevent/fdevent.h b/adb/fdevent/fdevent.h
deleted file mode 100644
index 9fc3b2c..0000000
--- a/adb/fdevent/fdevent.h
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef __FDEVENT_H
-#define __FDEVENT_H
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <atomic>
-#include <chrono>
-#include <deque>
-#include <functional>
-#include <mutex>
-#include <optional>
-#include <unordered_map>
-#include <variant>
-
-#include <android-base/thread_annotations.h>
-
-#include "adb_unique_fd.h"
-
-// Events that may be observed
-#define FDE_READ 0x0001
-#define FDE_WRITE 0x0002
-#define FDE_ERROR 0x0004
-#define FDE_TIMEOUT 0x0008
-
-struct fdevent;
-
-typedef void (*fd_func)(int fd, unsigned events, void *userdata);
-typedef void (*fd_func2)(struct fdevent* fde, unsigned events, void* userdata);
-
-void invoke_fde(struct fdevent* fde, unsigned events);
-std::string dump_fde(const fdevent* fde);
-
-struct fdevent_event {
-    fdevent* fde;
-    unsigned events;
-};
-
-struct fdevent final {
-    uint64_t id;
-
-    unique_fd fd;
-    int force_eof = 0;
-
-    uint16_t state = 0;
-    std::optional<std::chrono::milliseconds> timeout;
-    std::chrono::steady_clock::time_point last_active;
-
-    std::variant<fd_func, fd_func2> func;
-    void* arg = nullptr;
-};
-
-struct fdevent_context {
-  public:
-    virtual ~fdevent_context() = default;
-
-    // Allocate and initialize a new fdevent object.
-    fdevent* Create(unique_fd fd, std::variant<fd_func, fd_func2> func, void* arg);
-
-    // Deallocate an fdevent object, returning the file descriptor that was owned by it.
-    // Note that this calls Set, which is a virtual method, so destructors that call this must be
-    // final.
-    unique_fd Destroy(fdevent* fde);
-
-  protected:
-    virtual void Register(fdevent*) {}
-    virtual void Unregister(fdevent*) {}
-
-  public:
-    // Change which events should cause notifications.
-    virtual void Set(fdevent* fde, unsigned events) = 0;
-    void Add(fdevent* fde, unsigned events);
-    void Del(fdevent* fde, unsigned events);
-
-    // Set a timeout on an fdevent.
-    // If no events are triggered by the timeout, an FDE_TIMEOUT will be generated.
-    // Note timeouts are not defused automatically; if a timeout is set on an fdevent, it will
-    // trigger repeatedly every |timeout| ms.
-    void SetTimeout(fdevent* fde, std::optional<std::chrono::milliseconds> timeout);
-
-  protected:
-    std::optional<std::chrono::milliseconds> CalculatePollDuration();
-    void HandleEvents(const std::vector<fdevent_event>& events);
-
-  private:
-    // Run all pending functions enqueued via Run().
-    void FlushRunQueue() EXCLUDES(run_queue_mutex_);
-
-  public:
-    // Loop until TerminateLoop is called, handling events.
-    // Implementations should call FlushRunQueue on every iteration, and check the value of
-    // terminate_loop_ to determine whether to stop.
-    virtual void Loop() = 0;
-
-    // Assert that the caller is either running on the context's main thread, or that there is no
-    // active main thread.
-    void CheckMainThread();
-
-    // Queue an operation to be run on the main thread.
-    void Run(std::function<void()> fn);
-
-    // Test-only functionality:
-    void TerminateLoop();
-    virtual size_t InstalledCount() = 0;
-
-  protected:
-    // Interrupt the run loop.
-    virtual void Interrupt() = 0;
-
-    std::optional<uint64_t> main_thread_id_ = std::nullopt;
-    std::atomic<bool> terminate_loop_ = false;
-
-  protected:
-    std::unordered_map<int, fdevent> installed_fdevents_;
-
-  private:
-    uint64_t fdevent_id_ = 0;
-    std::mutex run_queue_mutex_;
-    std::deque<std::function<void()>> run_queue_ GUARDED_BY(run_queue_mutex_);
-};
-
-// Backwards compatibility shims that forward to the global fdevent_context.
-fdevent* fdevent_create(int fd, fd_func func, void* arg);
-fdevent* fdevent_create(int fd, fd_func2 func, void* arg);
-
-unique_fd fdevent_release(fdevent* fde);
-void fdevent_destroy(fdevent* fde);
-
-void fdevent_set(fdevent *fde, unsigned events);
-void fdevent_add(fdevent *fde, unsigned events);
-void fdevent_del(fdevent *fde, unsigned events);
-void fdevent_set_timeout(fdevent* fde, std::optional<std::chrono::milliseconds> timeout);
-void fdevent_loop();
-void check_main_thread();
-
-// Queue an operation to run on the main thread.
-void fdevent_run_on_main_thread(std::function<void()> fn);
-
-// The following functions are used only for tests.
-void fdevent_terminate_loop();
-size_t fdevent_installed_count();
-void fdevent_reset();
-
-#endif
diff --git a/adb/fdevent/fdevent_epoll.cpp b/adb/fdevent/fdevent_epoll.cpp
deleted file mode 100644
index 4ef41d1..0000000
--- a/adb/fdevent/fdevent_epoll.cpp
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "fdevent_epoll.h"
-
-#if defined(__linux__)
-
-#include <sys/epoll.h>
-#include <sys/eventfd.h>
-
-#include <android-base/logging.h>
-#include <android-base/threads.h>
-
-#include "adb_unique_fd.h"
-#include "fdevent.h"
-
-static void fdevent_interrupt(int fd, unsigned, void*) {
-    uint64_t buf;
-    ssize_t rc = TEMP_FAILURE_RETRY(adb_read(fd, &buf, sizeof(buf)));
-    if (rc == -1) {
-        PLOG(FATAL) << "failed to read from fdevent interrupt fd";
-    }
-}
-
-fdevent_context_epoll::fdevent_context_epoll() {
-    epoll_fd_.reset(epoll_create1(EPOLL_CLOEXEC));
-
-    unique_fd interrupt_fd(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
-    if (interrupt_fd == -1) {
-        PLOG(FATAL) << "failed to create fdevent interrupt eventfd";
-    }
-
-    unique_fd interrupt_fd_dup(fcntl(interrupt_fd.get(), F_DUPFD_CLOEXEC, 3));
-    if (interrupt_fd_dup == -1) {
-        PLOG(FATAL) << "failed to dup fdevent interrupt eventfd";
-    }
-
-    this->interrupt_fd_ = std::move(interrupt_fd_dup);
-    fdevent* fde = this->Create(std::move(interrupt_fd), fdevent_interrupt, nullptr);
-    CHECK(fde != nullptr);
-    this->Add(fde, FDE_READ);
-}
-
-fdevent_context_epoll::~fdevent_context_epoll() {
-    // Destroy calls virtual methods, but this class is final, so that's okay.
-    this->Destroy(this->interrupt_fde_);
-}
-
-static epoll_event calculate_epoll_event(fdevent* fde) {
-    epoll_event result;
-    result.events = 0;
-    if (fde->state & FDE_READ) {
-        result.events |= EPOLLIN;
-    }
-    if (fde->state & FDE_WRITE) {
-        result.events |= EPOLLOUT;
-    }
-    if (fde->state & FDE_ERROR) {
-        result.events |= EPOLLERR;
-    }
-    result.events |= EPOLLRDHUP;
-    result.data.ptr = fde;
-    return result;
-}
-
-void fdevent_context_epoll::Register(fdevent* fde) {
-    epoll_event ev = calculate_epoll_event(fde);
-    if (epoll_ctl(epoll_fd_.get(), EPOLL_CTL_ADD, fde->fd.get(), &ev) != 0) {
-        PLOG(FATAL) << "failed to register fd " << fde->fd.get() << " with epoll";
-    }
-}
-
-void fdevent_context_epoll::Unregister(fdevent* fde) {
-    if (epoll_ctl(epoll_fd_.get(), EPOLL_CTL_DEL, fde->fd.get(), nullptr) != 0) {
-        PLOG(FATAL) << "failed to unregister fd " << fde->fd.get() << " with epoll";
-    }
-}
-
-void fdevent_context_epoll::Set(fdevent* fde, unsigned events) {
-    unsigned previous_state = fde->state;
-    fde->state = events;
-
-    // If the state is the same, or only differed by FDE_TIMEOUT, we don't need to modify epoll.
-    if ((previous_state & ~FDE_TIMEOUT) == (events & ~FDE_TIMEOUT)) {
-        return;
-    }
-
-    epoll_event ev = calculate_epoll_event(fde);
-    if (epoll_ctl(epoll_fd_.get(), EPOLL_CTL_MOD, fde->fd.get(), &ev) != 0) {
-        PLOG(FATAL) << "failed to modify fd " << fde->fd.get() << " with epoll";
-    }
-}
-
-void fdevent_context_epoll::Loop() {
-    main_thread_id_ = android::base::GetThreadId();
-
-    std::vector<fdevent_event> fde_events;
-    std::vector<epoll_event> epoll_events;
-    epoll_events.resize(this->installed_fdevents_.size());
-
-    while (true) {
-        if (terminate_loop_) {
-            break;
-        }
-
-        int rc = -1;
-        while (rc == -1) {
-            std::optional<std::chrono::milliseconds> timeout = CalculatePollDuration();
-            int timeout_ms;
-            if (!timeout) {
-                timeout_ms = -1;
-            } else {
-                timeout_ms = timeout->count();
-            }
-
-            rc = epoll_wait(epoll_fd_.get(), epoll_events.data(), epoll_events.size(), timeout_ms);
-            if (rc == -1 && errno != EINTR) {
-                PLOG(FATAL) << "epoll_wait failed";
-            }
-        }
-
-        auto post_poll = std::chrono::steady_clock::now();
-        std::unordered_map<fdevent*, unsigned> event_map;
-        for (int i = 0; i < rc; ++i) {
-            fdevent* fde = static_cast<fdevent*>(epoll_events[i].data.ptr);
-
-            unsigned events = 0;
-            if (epoll_events[i].events & EPOLLIN) {
-                CHECK(fde->state & FDE_READ);
-                events |= FDE_READ;
-            }
-            if (epoll_events[i].events & EPOLLOUT) {
-                CHECK(fde->state & FDE_WRITE);
-                events |= FDE_WRITE;
-            }
-            if (epoll_events[i].events & (EPOLLERR | EPOLLHUP | EPOLLRDHUP)) {
-                // We fake a read, as the rest of the code assumes that errors will
-                // be detected at that point.
-                events |= FDE_READ | FDE_ERROR;
-            }
-
-            event_map[fde] = events;
-        }
-
-        for (auto& [fd, fde] : installed_fdevents_) {
-            unsigned events = 0;
-            if (auto it = event_map.find(&fde); it != event_map.end()) {
-                events = it->second;
-            }
-
-            if (events == 0) {
-                if (fde.timeout) {
-                    auto deadline = fde.last_active + *fde.timeout;
-                    if (deadline < post_poll) {
-                        events |= FDE_TIMEOUT;
-                    }
-                }
-            }
-
-            if (events != 0) {
-                LOG(DEBUG) << dump_fde(&fde) << " got events " << std::hex << std::showbase
-                           << events;
-                fde_events.push_back({&fde, events});
-                fde.last_active = post_poll;
-            }
-        }
-        this->HandleEvents(fde_events);
-        fde_events.clear();
-    }
-
-    main_thread_id_.reset();
-}
-
-size_t fdevent_context_epoll::InstalledCount() {
-    // We always have an installed fde for interrupt.
-    return this->installed_fdevents_.size() - 1;
-}
-
-void fdevent_context_epoll::Interrupt() {
-    uint64_t i = 1;
-    ssize_t rc = TEMP_FAILURE_RETRY(adb_write(this->interrupt_fd_, &i, sizeof(i)));
-    if (rc != sizeof(i)) {
-        PLOG(FATAL) << "failed to write to fdevent interrupt eventfd";
-    }
-}
-
-#endif  // defined(__linux__)
diff --git a/adb/fdevent/fdevent_epoll.h b/adb/fdevent/fdevent_epoll.h
deleted file mode 100644
index 6214d2e..0000000
--- a/adb/fdevent/fdevent_epoll.h
+++ /dev/null
@@ -1,56 +0,0 @@
-#pragma once
-
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#if defined(__linux__)
-
-#include "sysdeps.h"
-
-#include <sys/epoll.h>
-
-#include <deque>
-#include <list>
-#include <mutex>
-#include <unordered_map>
-
-#include <android-base/thread_annotations.h>
-
-#include "adb_unique_fd.h"
-#include "fdevent.h"
-
-struct fdevent_context_epoll final : public fdevent_context {
-    fdevent_context_epoll();
-    virtual ~fdevent_context_epoll();
-
-    virtual void Register(fdevent* fde) final;
-    virtual void Unregister(fdevent* fde) final;
-
-    virtual void Set(fdevent* fde, unsigned events) final;
-
-    virtual void Loop() final;
-    size_t InstalledCount() final;
-
-  protected:
-    virtual void Interrupt() final;
-
-  private:
-    unique_fd epoll_fd_;
-    unique_fd interrupt_fd_;
-    fdevent* interrupt_fde_ = nullptr;
-};
-
-#endif  // defined(__linux__)
diff --git a/adb/fdevent/fdevent_poll.cpp b/adb/fdevent/fdevent_poll.cpp
deleted file mode 100644
index ac86c08..0000000
--- a/adb/fdevent/fdevent_poll.cpp
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define TRACE_TAG FDEVENT
-
-#include "sysdeps.h"
-#include "fdevent_poll.h"
-
-#include <fcntl.h>
-#include <inttypes.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <atomic>
-#include <deque>
-#include <functional>
-#include <list>
-#include <mutex>
-#include <optional>
-#include <unordered_map>
-#include <utility>
-#include <variant>
-#include <vector>
-
-#include <android-base/chrono_utils.h>
-#include <android-base/file.h>
-#include <android-base/logging.h>
-#include <android-base/stringprintf.h>
-#include <android-base/threads.h>
-
-#include "adb_io.h"
-#include "adb_trace.h"
-#include "adb_unique_fd.h"
-#include "adb_utils.h"
-#include "fdevent.h"
-#include "sysdeps/chrono.h"
-
-static void fdevent_interrupt(int fd, unsigned, void*) {
-    char buf[BUFSIZ];
-    ssize_t rc = TEMP_FAILURE_RETRY(adb_read(fd, buf, sizeof(buf)));
-    if (rc == -1) {
-        PLOG(FATAL) << "failed to read from fdevent interrupt fd";
-    }
-}
-
-fdevent_context_poll::fdevent_context_poll() {
-    int s[2];
-    if (adb_socketpair(s) != 0) {
-        PLOG(FATAL) << "failed to create fdevent interrupt socketpair";
-    }
-
-    if (!set_file_block_mode(s[0], false) || !set_file_block_mode(s[1], false)) {
-        PLOG(FATAL) << "failed to make fdevent interrupt socket nonblocking";
-    }
-
-    this->interrupt_fd_.reset(s[0]);
-    fdevent* fde = this->Create(unique_fd(s[1]), fdevent_interrupt, nullptr);
-    CHECK(fde != nullptr);
-    this->Add(fde, FDE_READ);
-}
-
-fdevent_context_poll::~fdevent_context_poll() {
-    // Destroy calls virtual methods, but this class is final, so that's okay.
-    this->Destroy(this->interrupt_fde_);
-}
-
-void fdevent_context_poll::Set(fdevent* fde, unsigned events) {
-    CheckMainThread();
-    fde->state = events;
-    D("fdevent_set: %s, events = %u", dump_fde(fde).c_str(), events);
-}
-
-static std::string dump_pollfds(const std::vector<adb_pollfd>& pollfds) {
-    std::string result;
-    for (const auto& pollfd : pollfds) {
-        std::string op;
-        if (pollfd.events & POLLIN) {
-            op += "R";
-        }
-        if (pollfd.events & POLLOUT) {
-            op += "W";
-        }
-        android::base::StringAppendF(&result, " %d(%s)", pollfd.fd, op.c_str());
-    }
-    return result;
-}
-
-void fdevent_context_poll::Loop() {
-    main_thread_id_ = android::base::GetThreadId();
-
-    std::vector<adb_pollfd> pollfds;
-    std::vector<fdevent_event> poll_events;
-
-    while (true) {
-        if (terminate_loop_) {
-            break;
-        }
-
-        D("--- --- waiting for events");
-        pollfds.clear();
-        for (const auto& [fd, fde] : this->installed_fdevents_) {
-            adb_pollfd pfd;
-            pfd.fd = fd;
-            pfd.events = 0;
-            if (fde.state & FDE_READ) {
-                pfd.events |= POLLIN;
-            }
-            if (fde.state & FDE_WRITE) {
-                pfd.events |= POLLOUT;
-            }
-            if (fde.state & FDE_ERROR) {
-                pfd.events |= POLLERR;
-            }
-#if defined(__linux__)
-            pfd.events |= POLLRDHUP;
-#endif
-            pfd.revents = 0;
-            pollfds.push_back(pfd);
-        }
-        CHECK_GT(pollfds.size(), 0u);
-        D("poll(), pollfds = %s", dump_pollfds(pollfds).c_str());
-
-        std::optional<std::chrono::milliseconds> timeout = CalculatePollDuration();
-        int timeout_ms;
-        if (!timeout) {
-            timeout_ms = -1;
-        } else {
-            timeout_ms = timeout->count();
-        }
-
-        int ret = adb_poll(pollfds.data(), pollfds.size(), timeout_ms);
-        if (ret == -1) {
-            PLOG(ERROR) << "poll(), ret = " << ret;
-            return;
-        }
-
-        auto post_poll = std::chrono::steady_clock::now();
-
-        for (const auto& pollfd : pollfds) {
-            unsigned events = 0;
-            if (pollfd.revents & POLLIN) {
-                events |= FDE_READ;
-            }
-            if (pollfd.revents & POLLOUT) {
-                events |= FDE_WRITE;
-            }
-            if (pollfd.revents & (POLLERR | POLLHUP | POLLNVAL)) {
-                // We fake a read, as the rest of the code assumes that errors will
-                // be detected at that point.
-                events |= FDE_READ | FDE_ERROR;
-            }
-#if defined(__linux__)
-            if (pollfd.revents & POLLRDHUP) {
-                events |= FDE_READ | FDE_ERROR;
-            }
-#endif
-
-            auto it = this->installed_fdevents_.find(pollfd.fd);
-            CHECK(it != this->installed_fdevents_.end());
-            fdevent* fde = &it->second;
-
-            if (events == 0) {
-                if (fde->timeout) {
-                    auto deadline = fde->last_active + *fde->timeout;
-                    if (deadline < post_poll) {
-                        events |= FDE_TIMEOUT;
-                    }
-                }
-            }
-
-            if (events != 0) {
-                D("%s got events %x", dump_fde(fde).c_str(), events);
-                poll_events.push_back({fde, events});
-                fde->last_active = post_poll;
-            }
-        }
-        this->HandleEvents(poll_events);
-        poll_events.clear();
-    }
-
-    main_thread_id_.reset();
-}
-
-size_t fdevent_context_poll::InstalledCount() {
-    // We always have an installed fde for interrupt.
-    return this->installed_fdevents_.size() - 1;
-}
-
-void fdevent_context_poll::Interrupt() {
-    int rc = adb_write(this->interrupt_fd_, "", 1);
-
-    // It's possible that we get EAGAIN here, if lots of notifications came in while handling.
-    if (rc == 0) {
-        PLOG(FATAL) << "fdevent interrupt fd was closed?";
-    } else if (rc == -1 && errno != EAGAIN) {
-        PLOG(FATAL) << "failed to write to fdevent interrupt fd";
-    }
-}
diff --git a/adb/fdevent/fdevent_poll.h b/adb/fdevent/fdevent_poll.h
deleted file mode 100644
index 98abab2..0000000
--- a/adb/fdevent/fdevent_poll.h
+++ /dev/null
@@ -1,63 +0,0 @@
-#pragma once
-
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "sysdeps.h"
-
-#include <deque>
-#include <list>
-#include <mutex>
-#include <unordered_map>
-
-#include <android-base/thread_annotations.h>
-
-#include "adb_unique_fd.h"
-#include "fdevent.h"
-
-struct PollNode {
-  fdevent* fde;
-  adb_pollfd pollfd;
-
-  explicit PollNode(fdevent* fde) : fde(fde) {
-      memset(&pollfd, 0, sizeof(pollfd));
-      pollfd.fd = fde->fd.get();
-
-#if defined(__linux__)
-      // Always enable POLLRDHUP, so the host server can take action when some clients disconnect.
-      // Then we can avoid leaving many sockets in CLOSE_WAIT state. See http://b/23314034.
-      pollfd.events = POLLRDHUP;
-#endif
-  }
-};
-
-struct fdevent_context_poll final : public fdevent_context {
-    fdevent_context_poll();
-    virtual ~fdevent_context_poll();
-
-    virtual void Set(fdevent* fde, unsigned events) final;
-
-    virtual void Loop() final;
-
-    virtual size_t InstalledCount() final;
-
-  protected:
-    virtual void Interrupt() final;
-
-  public:
-    unique_fd interrupt_fd_;
-    fdevent* interrupt_fde_ = nullptr;
-};
diff --git a/adb/fdevent/fdevent_test.cpp b/adb/fdevent/fdevent_test.cpp
deleted file mode 100644
index e06b3b3..0000000
--- a/adb/fdevent/fdevent_test.cpp
+++ /dev/null
@@ -1,321 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "fdevent.h"
-
-#include <gtest/gtest.h>
-
-#include <chrono>
-#include <limits>
-#include <memory>
-#include <queue>
-#include <string>
-#include <thread>
-#include <vector>
-
-#include "adb_io.h"
-#include "fdevent_test.h"
-
-using namespace std::chrono_literals;
-
-class FdHandler {
-  public:
-    FdHandler(int read_fd, int write_fd, bool use_new_callback)
-        : read_fd_(read_fd), write_fd_(write_fd) {
-        if (use_new_callback) {
-            read_fde_ = fdevent_create(read_fd_, FdEventNewCallback, this);
-            write_fde_ = fdevent_create(write_fd_, FdEventNewCallback, this);
-        } else {
-            read_fde_ = fdevent_create(read_fd_, FdEventCallback, this);
-            write_fde_ = fdevent_create(write_fd_, FdEventCallback, this);
-        }
-        fdevent_add(read_fde_, FDE_READ);
-    }
-
-    ~FdHandler() {
-        fdevent_destroy(read_fde_);
-        fdevent_destroy(write_fde_);
-    }
-
-  private:
-    static void FdEventCallback(int fd, unsigned events, void* userdata) {
-        FdHandler* handler = reinterpret_cast<FdHandler*>(userdata);
-        ASSERT_EQ(0u, (events & ~(FDE_READ | FDE_WRITE))) << "unexpected events: " << events;
-        if (events & FDE_READ) {
-            ASSERT_EQ(fd, handler->read_fd_);
-            char c;
-            ASSERT_EQ(1, adb_read(fd, &c, 1));
-            handler->queue_.push(c);
-            fdevent_add(handler->write_fde_, FDE_WRITE);
-        }
-        if (events & FDE_WRITE) {
-            ASSERT_EQ(fd, handler->write_fd_);
-            ASSERT_FALSE(handler->queue_.empty());
-            char c = handler->queue_.front();
-            handler->queue_.pop();
-            ASSERT_EQ(1, adb_write(fd, &c, 1));
-            if (handler->queue_.empty()) {
-                fdevent_del(handler->write_fde_, FDE_WRITE);
-            }
-        }
-    }
-
-    static void FdEventNewCallback(fdevent* fde, unsigned events, void* userdata) {
-        int fd = fde->fd.get();
-        FdHandler* handler = reinterpret_cast<FdHandler*>(userdata);
-        ASSERT_EQ(0u, (events & ~(FDE_READ | FDE_WRITE))) << "unexpected events: " << events;
-        if (events & FDE_READ) {
-            ASSERT_EQ(fd, handler->read_fd_);
-            char c;
-            ASSERT_EQ(1, adb_read(fd, &c, 1));
-            handler->queue_.push(c);
-            fdevent_add(handler->write_fde_, FDE_WRITE);
-        }
-        if (events & FDE_WRITE) {
-            ASSERT_EQ(fd, handler->write_fd_);
-            ASSERT_FALSE(handler->queue_.empty());
-            char c = handler->queue_.front();
-            handler->queue_.pop();
-            ASSERT_EQ(1, adb_write(fd, &c, 1));
-            if (handler->queue_.empty()) {
-                fdevent_del(handler->write_fde_, FDE_WRITE);
-            }
-        }
-    }
-
-  private:
-    const int read_fd_;
-    const int write_fd_;
-    fdevent* read_fde_;
-    fdevent* write_fde_;
-    std::queue<char> queue_;
-};
-
-struct ThreadArg {
-    int first_read_fd;
-    int last_write_fd;
-    size_t middle_pipe_count;
-};
-
-TEST_F(FdeventTest, fdevent_terminate) {
-    PrepareThread();
-    TerminateThread();
-}
-
-TEST_F(FdeventTest, smoke) {
-    for (bool use_new_callback : {true, false}) {
-        fdevent_reset();
-        const size_t PIPE_COUNT = 512;
-        const size_t MESSAGE_LOOP_COUNT = 10;
-        const std::string MESSAGE = "fdevent_test";
-        int fd_pair1[2];
-        int fd_pair2[2];
-        ASSERT_EQ(0, adb_socketpair(fd_pair1));
-        ASSERT_EQ(0, adb_socketpair(fd_pair2));
-        ThreadArg thread_arg;
-        thread_arg.first_read_fd = fd_pair1[0];
-        thread_arg.last_write_fd = fd_pair2[1];
-        thread_arg.middle_pipe_count = PIPE_COUNT;
-        int writer = fd_pair1[1];
-        int reader = fd_pair2[0];
-
-        PrepareThread();
-
-        std::vector<std::unique_ptr<FdHandler>> fd_handlers;
-        fdevent_run_on_main_thread([&thread_arg, &fd_handlers, use_new_callback]() {
-            std::vector<int> read_fds;
-            std::vector<int> write_fds;
-
-            read_fds.push_back(thread_arg.first_read_fd);
-            for (size_t i = 0; i < thread_arg.middle_pipe_count; ++i) {
-                int fds[2];
-                ASSERT_EQ(0, adb_socketpair(fds));
-                read_fds.push_back(fds[0]);
-                write_fds.push_back(fds[1]);
-            }
-            write_fds.push_back(thread_arg.last_write_fd);
-
-            for (size_t i = 0; i < read_fds.size(); ++i) {
-                fd_handlers.push_back(
-                        std::make_unique<FdHandler>(read_fds[i], write_fds[i], use_new_callback));
-            }
-        });
-        WaitForFdeventLoop();
-
-        for (size_t i = 0; i < MESSAGE_LOOP_COUNT; ++i) {
-            std::string read_buffer = MESSAGE;
-            std::string write_buffer(MESSAGE.size(), 'a');
-            ASSERT_TRUE(WriteFdExactly(writer, read_buffer.c_str(), read_buffer.size()));
-            ASSERT_TRUE(ReadFdExactly(reader, &write_buffer[0], write_buffer.size()));
-            ASSERT_EQ(read_buffer, write_buffer);
-        }
-
-        fdevent_run_on_main_thread([&fd_handlers]() { fd_handlers.clear(); });
-        WaitForFdeventLoop();
-
-        TerminateThread();
-        ASSERT_EQ(0, adb_close(writer));
-        ASSERT_EQ(0, adb_close(reader));
-    }
-}
-
-TEST_F(FdeventTest, run_on_main_thread) {
-    std::vector<int> vec;
-
-    PrepareThread();
-
-    // Block the main thread for a long time while we queue our callbacks.
-    fdevent_run_on_main_thread([]() {
-        check_main_thread();
-        std::this_thread::sleep_for(std::chrono::seconds(1));
-    });
-
-    for (int i = 0; i < 1000000; ++i) {
-        fdevent_run_on_main_thread([i, &vec]() {
-            check_main_thread();
-            vec.push_back(i);
-        });
-    }
-
-    TerminateThread();
-
-    ASSERT_EQ(1000000u, vec.size());
-    for (int i = 0; i < 1000000; ++i) {
-        ASSERT_EQ(i, vec[i]);
-    }
-}
-
-static std::function<void()> make_appender(std::vector<int>* vec, int value) {
-    return [vec, value]() {
-        check_main_thread();
-        if (value == 100) {
-            return;
-        }
-
-        vec->push_back(value);
-        fdevent_run_on_main_thread(make_appender(vec, value + 1));
-    };
-}
-
-TEST_F(FdeventTest, run_on_main_thread_reentrant) {
-    std::vector<int> vec;
-
-    PrepareThread();
-    fdevent_run_on_main_thread(make_appender(&vec, 0));
-    TerminateThread();
-
-    ASSERT_EQ(100u, vec.size());
-    for (int i = 0; i < 100; ++i) {
-        ASSERT_EQ(i, vec[i]);
-    }
-}
-
-TEST_F(FdeventTest, timeout) {
-    fdevent_reset();
-    PrepareThread();
-
-    enum class TimeoutEvent {
-        read,
-        timeout,
-        done,
-    };
-
-    struct TimeoutTest {
-        std::vector<std::pair<TimeoutEvent, std::chrono::steady_clock::time_point>> events;
-        fdevent* fde;
-    };
-    TimeoutTest test;
-
-    int fds[2];
-    ASSERT_EQ(0, adb_socketpair(fds));
-    static constexpr auto delta = 100ms;
-    fdevent_run_on_main_thread([&]() {
-        test.fde = fdevent_create(fds[0], [](fdevent* fde, unsigned events, void* arg) {
-            auto test = static_cast<TimeoutTest*>(arg);
-            auto now = std::chrono::steady_clock::now();
-            CHECK((events & FDE_READ) ^ (events & FDE_TIMEOUT));
-            TimeoutEvent event;
-            if ((events & FDE_READ)) {
-                char buf[2];
-                ssize_t rc = adb_read(fde->fd.get(), buf, sizeof(buf));
-                if (rc == 0) {
-                    event = TimeoutEvent::done;
-                } else if (rc == 1) {
-                    event = TimeoutEvent::read;
-                } else {
-                    abort();
-                }
-            } else if ((events & FDE_TIMEOUT)) {
-                event = TimeoutEvent::timeout;
-            } else {
-                abort();
-            }
-
-            CHECK_EQ(fde, test->fde);
-            test->events.emplace_back(event, now);
-
-            if (event == TimeoutEvent::done) {
-                fdevent_destroy(fde);
-            }
-        }, &test);
-        fdevent_add(test.fde, FDE_READ);
-        fdevent_set_timeout(test.fde, delta);
-    });
-
-    ASSERT_EQ(1, adb_write(fds[1], "", 1));
-
-    // Timeout should happen here
-    std::this_thread::sleep_for(delta);
-
-    // and another.
-    std::this_thread::sleep_for(delta);
-
-    // No timeout should happen here.
-    std::this_thread::sleep_for(delta / 2);
-    adb_close(fds[1]);
-
-    TerminateThread();
-
-    ASSERT_EQ(4ULL, test.events.size());
-    ASSERT_EQ(TimeoutEvent::read, test.events[0].first);
-    ASSERT_EQ(TimeoutEvent::timeout, test.events[1].first);
-    ASSERT_EQ(TimeoutEvent::timeout, test.events[2].first);
-    ASSERT_EQ(TimeoutEvent::done, test.events[3].first);
-
-    std::vector<int> time_deltas;
-    for (size_t i = 0; i < test.events.size() - 1; ++i) {
-        auto before = test.events[i].second;
-        auto after = test.events[i + 1].second;
-        auto diff = std::chrono::duration_cast<std::chrono::milliseconds>(after - before);
-        time_deltas.push_back(diff.count());
-    }
-
-    std::vector<int> expected = {
-        delta.count(),
-        delta.count(),
-        delta.count() / 2,
-    };
-
-    std::vector<int> diff;
-    ASSERT_EQ(time_deltas.size(), expected.size());
-    for (size_t i = 0; i < time_deltas.size(); ++i) {
-        diff.push_back(std::abs(time_deltas[i] - expected[i]));
-    }
-
-    ASSERT_LT(diff[0], delta.count() * 0.5);
-    ASSERT_LT(diff[1], delta.count() * 0.5);
-    ASSERT_LT(diff[2], delta.count() * 0.5);
-}
diff --git a/adb/fdevent/fdevent_test.h b/adb/fdevent/fdevent_test.h
deleted file mode 100644
index ecda4da..0000000
--- a/adb/fdevent/fdevent_test.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <gtest/gtest.h>
-
-#include <condition_variable>
-#include <mutex>
-#include <thread>
-
-#include "adb_io.h"
-#include "adb_unique_fd.h"
-#include "socket.h"
-#include "sysdeps.h"
-#include "sysdeps/chrono.h"
-
-static void WaitForFdeventLoop() {
-    // Sleep for a bit to make sure that network events have propagated.
-    std::this_thread::sleep_for(100ms);
-
-    // fdevent_run_on_main_thread has a guaranteed ordering, and is guaranteed to happen after
-    // socket events, so as soon as our function is called, we know that we've processed all
-    // previous events.
-    std::mutex mutex;
-    std::condition_variable cv;
-    std::unique_lock<std::mutex> lock(mutex);
-    fdevent_run_on_main_thread([&]() {
-        mutex.lock();
-        mutex.unlock();
-        cv.notify_one();
-    });
-    cv.wait(lock);
-}
-
-class FdeventTest : public ::testing::Test {
-  protected:
-    unique_fd dummy;
-
-    ~FdeventTest() {
-        if (thread_.joinable()) {
-            TerminateThread();
-        }
-    }
-
-    static void SetUpTestCase() {
-#if !defined(_WIN32)
-        ASSERT_NE(SIG_ERR, signal(SIGPIPE, SIG_IGN));
-#endif
-    }
-
-    void SetUp() override {
-        fdevent_reset();
-        ASSERT_EQ(0u, fdevent_installed_count());
-    }
-
-    // Register a dummy socket used to wake up the fdevent loop to tell it to die.
-    void PrepareThread() {
-        int dummy_fds[2];
-        if (adb_socketpair(dummy_fds) != 0) {
-            FAIL() << "failed to create socketpair: " << strerror(errno);
-        }
-
-        asocket* dummy_socket = create_local_socket(unique_fd(dummy_fds[1]));
-        if (!dummy_socket) {
-            FAIL() << "failed to create local socket: " << strerror(errno);
-        }
-        dummy_socket->ready(dummy_socket);
-        dummy.reset(dummy_fds[0]);
-
-        thread_ = std::thread([]() { fdevent_loop(); });
-        WaitForFdeventLoop();
-    }
-
-    size_t GetAdditionalLocalSocketCount() {
-        // dummy socket installed in PrepareThread()
-        return 1;
-    }
-
-    void TerminateThread() {
-        fdevent_terminate_loop();
-        ASSERT_TRUE(WriteFdExactly(dummy, "", 1));
-        thread_.join();
-        dummy.reset();
-    }
-
-    std::thread thread_;
-};
diff --git a/adb/file_sync_protocol.h b/adb/file_sync_protocol.h
deleted file mode 100644
index fd9a516..0000000
--- a/adb/file_sync_protocol.h
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#define MKID(a, b, c, d) ((a) | ((b) << 8) | ((c) << 16) | ((d) << 24))
-
-#define ID_LSTAT_V1 MKID('S', 'T', 'A', 'T')
-#define ID_STAT_V2 MKID('S', 'T', 'A', '2')
-#define ID_LSTAT_V2 MKID('L', 'S', 'T', '2')
-
-#define ID_LIST_V1 MKID('L', 'I', 'S', 'T')
-#define ID_LIST_V2 MKID('L', 'I', 'S', '2')
-#define ID_DENT_V1 MKID('D', 'E', 'N', 'T')
-#define ID_DENT_V2 MKID('D', 'N', 'T', '2')
-
-#define ID_SEND_V1 MKID('S', 'E', 'N', 'D')
-#define ID_SEND_V2 MKID('S', 'N', 'D', '2')
-#define ID_RECV_V1 MKID('R', 'E', 'C', 'V')
-#define ID_RECV_V2 MKID('R', 'C', 'V', '2')
-#define ID_DONE MKID('D', 'O', 'N', 'E')
-#define ID_DATA MKID('D', 'A', 'T', 'A')
-#define ID_OKAY MKID('O', 'K', 'A', 'Y')
-#define ID_FAIL MKID('F', 'A', 'I', 'L')
-#define ID_QUIT MKID('Q', 'U', 'I', 'T')
-
-struct SyncRequest {
-    uint32_t id;           // ID_STAT, et cetera.
-    uint32_t path_length;  // <= 1024
-    // Followed by 'path_length' bytes of path (not NUL-terminated).
-} __attribute__((packed));
-
-struct __attribute__((packed)) sync_stat_v1 {
-    uint32_t id;
-    uint32_t mode;
-    uint32_t size;
-    uint32_t mtime;
-};
-
-struct __attribute__((packed)) sync_stat_v2 {
-    uint32_t id;
-    uint32_t error;
-    uint64_t dev;
-    uint64_t ino;
-    uint32_t mode;
-    uint32_t nlink;
-    uint32_t uid;
-    uint32_t gid;
-    uint64_t size;
-    int64_t atime;
-    int64_t mtime;
-    int64_t ctime;
-};
-
-struct __attribute__((packed)) sync_dent_v1 {
-    uint32_t id;
-    uint32_t mode;
-    uint32_t size;
-    uint32_t mtime;
-    uint32_t namelen;
-};  // followed by `namelen` bytes of the name.
-
-struct __attribute__((packed)) sync_dent_v2 {
-    uint32_t id;
-    uint32_t error;
-    uint64_t dev;
-    uint64_t ino;
-    uint32_t mode;
-    uint32_t nlink;
-    uint32_t uid;
-    uint32_t gid;
-    uint64_t size;
-    int64_t atime;
-    int64_t mtime;
-    int64_t ctime;
-    uint32_t namelen;
-};  // followed by `namelen` bytes of the name.
-
-enum SyncFlag : uint32_t {
-    kSyncFlagNone = 0,
-    kSyncFlagBrotli = 1,
-};
-
-// send_v1 sent the path in a buffer, followed by a comma and the mode as a string.
-// send_v2 sends just the path in the first request, and then sends another syncmsg (with the
-// same ID!) with details.
-struct __attribute__((packed)) sync_send_v2 {
-    uint32_t id;
-    uint32_t mode;
-    uint32_t flags;
-};
-
-// Likewise, recv_v1 just sent the path without any accompanying data.
-struct __attribute__((packed)) sync_recv_v2 {
-    uint32_t id;
-    uint32_t flags;
-};
-
-struct __attribute__((packed)) sync_data {
-    uint32_t id;
-    uint32_t size;
-};  // followed by `size` bytes of data.
-
-struct __attribute__((packed)) sync_status {
-    uint32_t id;
-    uint32_t msglen;
-};  // followed by `msglen` bytes of error message, if id == ID_FAIL.
-
-union syncmsg {
-    sync_stat_v1 stat_v1;
-    sync_stat_v2 stat_v2;
-    sync_dent_v1 dent_v1;
-    sync_dent_v2 dent_v2;
-    sync_data data;
-    sync_status status;
-    sync_send_v2 send_v2_setup;
-    sync_recv_v2 recv_v2_setup;
-};
-
-#define SYNC_DATA_MAX (64 * 1024)
diff --git a/adb/libs/.clang-format b/adb/libs/.clang-format
deleted file mode 120000
index e545823..0000000
--- a/adb/libs/.clang-format
+++ /dev/null
@@ -1 +0,0 @@
-../../.clang-format-2
\ No newline at end of file
diff --git a/adb/libs/adbconnection/.clang-format b/adb/libs/adbconnection/.clang-format
deleted file mode 120000
index e545823..0000000
--- a/adb/libs/adbconnection/.clang-format
+++ /dev/null
@@ -1 +0,0 @@
-../../.clang-format-2
\ No newline at end of file
diff --git a/adb/libs/adbconnection/Android.bp b/adb/libs/adbconnection/Android.bp
deleted file mode 100644
index ce2ab51..0000000
--- a/adb/libs/adbconnection/Android.bp
+++ /dev/null
@@ -1,64 +0,0 @@
-// libadbconnection
-// =========================================================
-// libadbconnection_client/server implement the socket handling for jdwp
-// forwarding and the track-jdwp service.
-cc_library {
-    name: "libadbconnection_server",
-    srcs: ["adbconnection_server.cpp"],
-
-    export_include_dirs: ["include"],
-
-    stl: "libc++_static",
-    shared_libs: ["liblog"],
-    static_libs: ["libbase"],
-
-    defaults: ["adbd_defaults", "host_adbd_supported"],
-
-    // Avoid getting duplicate symbol of android::build::GetBuildNumber().
-    use_version_lib: false,
-
-    recovery_available: true,
-    apex_available: [
-        "com.android.adbd",
-        // TODO(b/151398197) remove the below
-        "//apex_available:platform",
-    ],
-    compile_multilib: "both",
-}
-
-cc_library {
-    name: "libadbconnection_client",
-    srcs: ["adbconnection_client.cpp"],
-
-    export_include_dirs: ["include"],
-
-    stl: "libc++_static",
-    shared_libs: ["liblog"],
-    static_libs: ["libbase"],
-
-    defaults: ["adbd_defaults"],
-    visibility: [
-        "//art:__subpackages__",
-        "//system/core/adb/apex:__subpackages__",
-    ],
-    apex_available: [
-        "com.android.adbd",
-        "test_com.android.adbd",
-    ],
-
-    // libadbconnection_client doesn't need an embedded build number.
-    use_version_lib: false,
-
-    target: {
-        linux: {
-            version_script: "libadbconnection_client.map.txt",
-        },
-    },
-    stubs: {
-        symbol_file: "libadbconnection_client.map.txt",
-        versions: ["1"],
-    },
-
-    host_supported: true,
-    compile_multilib: "both",
-}
diff --git a/adb/libs/adbconnection/adbconnection_client.cpp b/adb/libs/adbconnection/adbconnection_client.cpp
deleted file mode 100644
index ee48abb..0000000
--- a/adb/libs/adbconnection/adbconnection_client.cpp
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "adbconnection/client.h"
-
-#include <pwd.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-
-#include <memory>
-#include <optional>
-
-#include <android-base/cmsg.h>
-#include <android-base/logging.h>
-#include <android-base/unique_fd.h>
-
-using android::base::unique_fd;
-
-static constexpr char kJdwpControlName[] = "\0jdwp-control";
-
-struct AdbConnectionClientContext {
-  unique_fd control_socket_;
-};
-
-bool SocketPeerIsTrusted(int fd) {
-  ucred cr;
-  socklen_t cr_length = sizeof(cr);
-  if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_length) != 0) {
-    PLOG(ERROR) << "couldn't get socket credentials";
-    return false;
-  }
-
-  passwd* shell = getpwnam("shell");
-  if (cr.uid != 0 && cr.uid != shell->pw_uid) {
-    LOG(ERROR) << "untrusted uid " << cr.uid << " on other end of socket";
-    return false;
-  }
-
-  return true;
-}
-
-AdbConnectionClientContext* adbconnection_client_new(
-    const AdbConnectionClientInfo* const* info_elems, size_t info_count) {
-  auto ctx = std::make_unique<AdbConnectionClientContext>();
-
-  std::optional<uint64_t> pid;
-  std::optional<bool> debuggable;
-
-  for (size_t i = 0; i < info_count; ++i) {
-    auto info = info_elems[i];
-    switch (info->type) {
-      case AdbConnectionClientInfoType::pid:
-        if (pid) {
-          LOG(ERROR) << "multiple pid entries in AdbConnectionClientInfo, ignoring";
-          continue;
-        }
-        pid = info->data.pid;
-        break;
-
-      case AdbConnectionClientInfoType::debuggable:
-        if (debuggable) {
-          LOG(ERROR) << "multiple debuggable entries in AdbConnectionClientInfo, ignoring";
-          continue;
-        }
-        debuggable = info->data.pid;
-        break;
-    }
-  }
-
-  if (!pid) {
-    LOG(ERROR) << "AdbConnectionClientInfo missing required field pid";
-    return nullptr;
-  }
-
-  if (!debuggable) {
-    LOG(ERROR) << "AdbConnectionClientInfo missing required field debuggable";
-    return nullptr;
-  }
-
-  ctx->control_socket_.reset(socket(AF_UNIX, SOCK_SEQPACKET | SOCK_CLOEXEC, 0));
-  if (ctx->control_socket_ < 0) {
-    PLOG(ERROR) << "failed to create Unix domain socket";
-    return nullptr;
-  }
-
-  struct timeval timeout;
-  timeout.tv_sec = 1;
-  timeout.tv_usec = 0;
-  setsockopt(ctx->control_socket_.get(), SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout));
-
-  sockaddr_un addr = {};
-  addr.sun_family = AF_UNIX;
-  memcpy(addr.sun_path, kJdwpControlName, sizeof(kJdwpControlName));
-  size_t addr_len = offsetof(sockaddr_un, sun_path) + sizeof(kJdwpControlName) - 1;
-
-  int rc = connect(ctx->control_socket_.get(), reinterpret_cast<sockaddr*>(&addr), addr_len);
-  if (rc != 0) {
-    PLOG(ERROR) << "failed to connect to jdwp control socket";
-    return nullptr;
-  }
-
-  bool trusted = SocketPeerIsTrusted(ctx->control_socket_.get());
-  if (!trusted) {
-    LOG(ERROR) << "adb socket is not trusted, aborting connection";
-    return nullptr;
-  }
-
-  uint32_t pid_u32 = static_cast<uint32_t>(*pid);
-  rc = TEMP_FAILURE_RETRY(write(ctx->control_socket_.get(), &pid_u32, sizeof(pid_u32)));
-  if (rc != sizeof(pid_u32)) {
-    PLOG(ERROR) << "failed to send JDWP process pid to adbd";
-  }
-
-  return ctx.release();
-}
-
-void adbconnection_client_destroy(AdbConnectionClientContext* ctx) {
-  delete ctx;
-}
-
-int adbconnection_client_pollfd(AdbConnectionClientContext* ctx) {
-  return ctx->control_socket_.get();
-}
-
-int adbconnection_client_receive_jdwp_fd(AdbConnectionClientContext* ctx) {
-  char dummy;
-  unique_fd jdwp_fd;
-  ssize_t rc = android::base::ReceiveFileDescriptors(ctx->control_socket_, &dummy, 1, &jdwp_fd);
-  if (rc != 1) {
-    return rc;
-  }
-  return jdwp_fd.release();
-}
diff --git a/adb/libs/adbconnection/adbconnection_server.cpp b/adb/libs/adbconnection/adbconnection_server.cpp
deleted file mode 100644
index 939da2f..0000000
--- a/adb/libs/adbconnection/adbconnection_server.cpp
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "adbconnection/server.h"
-
-#include <sys/epoll.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <unistd.h>
-
-#include <algorithm>
-#include <array>
-#include <vector>
-
-#include <android-base/logging.h>
-#include <android-base/unique_fd.h>
-
-using android::base::unique_fd;
-
-#define JDWP_CONTROL_NAME "\0jdwp-control"
-#define JDWP_CONTROL_NAME_LEN (sizeof(JDWP_CONTROL_NAME) - 1)
-
-static_assert(JDWP_CONTROL_NAME_LEN <= sizeof(reinterpret_cast<sockaddr_un*>(0)->sun_path));
-
-// Listen for incoming jdwp clients forever.
-void adbconnection_listen(void (*callback)(int fd, pid_t pid)) {
-  sockaddr_un addr = {};
-  socklen_t addrlen = JDWP_CONTROL_NAME_LEN + sizeof(addr.sun_family);
-
-  addr.sun_family = AF_UNIX;
-  memcpy(addr.sun_path, JDWP_CONTROL_NAME, JDWP_CONTROL_NAME_LEN);
-
-  unique_fd s(socket(AF_UNIX, SOCK_SEQPACKET | SOCK_NONBLOCK | SOCK_CLOEXEC, 0));
-  if (s < 0) {
-    PLOG(ERROR) << "failed to create JDWP control socket";
-    return;
-  }
-
-  if (bind(s.get(), reinterpret_cast<sockaddr*>(&addr), addrlen) < 0) {
-    PLOG(ERROR) << "failed to bind JDWP control socket";
-    return;
-  }
-
-  if (listen(s.get(), 4) < 0) {
-    PLOG(ERROR) << "failed to listen on JDWP control socket";
-    return;
-  }
-
-  std::vector<unique_fd> pending_connections;
-
-  unique_fd epfd(epoll_create1(EPOLL_CLOEXEC));
-  std::array<epoll_event, 16> events;
-
-  events[0].events = EPOLLIN;
-  events[0].data.fd = -1;
-  if (epoll_ctl(epfd.get(), EPOLL_CTL_ADD, s.get(), &events[0]) != 0) {
-    LOG(FATAL) << "failed to register event with epoll fd";
-  }
-
-  while (true) {
-    int epoll_rc = TEMP_FAILURE_RETRY(epoll_wait(epfd.get(), events.data(), events.size(), -1));
-    if (epoll_rc == -1) {
-      PLOG(FATAL) << "epoll_wait failed";
-    }
-
-    for (int i = 0; i < epoll_rc; ++i) {
-      const epoll_event& event = events[i];
-      if (event.data.fd == -1) {
-        unique_fd client(
-            TEMP_FAILURE_RETRY(accept4(s.get(), nullptr, nullptr, SOCK_NONBLOCK | SOCK_CLOEXEC)));
-
-        if (client == -1) {
-          PLOG(WARNING) << "failed to accept client on JDWP control socket";
-          continue;
-        }
-
-        epoll_event register_event;
-        register_event.events = EPOLLIN;
-        register_event.data.fd = client.get();
-
-        if (epoll_ctl(epfd.get(), EPOLL_CTL_ADD, client.get(), &register_event) != 0) {
-          PLOG(FATAL) << "failed to register JDWP client with epoll";
-        }
-
-        pending_connections.emplace_back(std::move(client));
-      } else {
-        // n^2, but the backlog should be short.
-        auto it = std::find_if(pending_connections.begin(), pending_connections.end(),
-                               [&](const unique_fd& fd) { return fd.get() == event.data.fd; });
-
-        if (it == pending_connections.end()) {
-          LOG(FATAL) << "failed to find JDWP client (" << event.data.fd
-                     << ") in pending connections";
-        }
-
-        // Massively oversized buffer: we're expecting an int32_t from the other end.
-        char buf[32];
-        int rc = TEMP_FAILURE_RETRY(recv(it->get(), buf, sizeof(buf), MSG_DONTWAIT));
-        if (rc != 4) {
-          LOG(ERROR) << "received data of incorrect size from JDWP client: read " << rc
-                     << ", expected 4";
-        } else {
-          int32_t pid;
-          memcpy(&pid, buf, sizeof(pid));
-          callback(it->release(), static_cast<pid_t>(pid));
-        }
-
-        if (epoll_ctl(epfd.get(), EPOLL_CTL_DEL, event.data.fd, nullptr) != 0) {
-          LOG(FATAL) << "failed to delete fd from JDWP epoll fd";
-        }
-
-        pending_connections.erase(it);
-      }
-    }
-  }
-}
diff --git a/adb/libs/adbconnection/include/adbconnection/client.h b/adb/libs/adbconnection/include/adbconnection/client.h
deleted file mode 100644
index 692fea0..0000000
--- a/adb/libs/adbconnection/include/adbconnection/client.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <android-base/unique_fd.h>
-
-extern "C" {
-
-struct AdbConnectionClientContext;
-
-enum AdbConnectionClientInfoType {
-  pid,
-  debuggable,
-};
-
-struct AdbConnectionClientInfo {
-  AdbConnectionClientInfoType type;
-  union {
-    uint64_t pid;
-    bool debuggable;
-  } data;
-};
-
-// Construct a context and connect to adbd.
-// Returns null if we fail to connect to adbd.
-AdbConnectionClientContext* adbconnection_client_new(
-    const AdbConnectionClientInfo* const* info_elems, size_t info_count);
-
-void adbconnection_client_destroy(AdbConnectionClientContext* ctx);
-
-// Get an fd which can be polled upon to detect when a jdwp socket is available.
-// You do not own this fd. Do not close it.
-int adbconnection_client_pollfd(AdbConnectionClientContext* ctx);
-
-// Receive a jdwp client fd.
-// Ownership is transferred to the caller of this function.
-int adbconnection_client_receive_jdwp_fd(AdbConnectionClientContext* ctx);
-}
diff --git a/adb/libs/adbconnection/include/adbconnection/server.h b/adb/libs/adbconnection/include/adbconnection/server.h
deleted file mode 100644
index 57ca6cd..0000000
--- a/adb/libs/adbconnection/include/adbconnection/server.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <sys/types.h>
-
-#include <android-base/unique_fd.h>
-
-extern "C" {
-
-void adbconnection_listen(void (*callback)(int fd, pid_t pid));
-}
diff --git a/adb/libs/adbconnection/libadbconnection_client.map.txt b/adb/libs/adbconnection/libadbconnection_client.map.txt
deleted file mode 100644
index 153a0e4..0000000
--- a/adb/libs/adbconnection/libadbconnection_client.map.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-#
-# Copyright (C) 2019 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-#  Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-LIBADBCONNECTION_CLIENT_1 {
-  global:
-    adbconnection_client_new;
-    adbconnection_client_destroy;
-    adbconnection_client_pollfd;
-    adbconnection_client_receive_jdwp_fd;
-  local:
-    *;
-};
diff --git a/adb/libs/libadbd_fs/Android.bp b/adb/libs/libadbd_fs/Android.bp
deleted file mode 100644
index d178148..0000000
--- a/adb/libs/libadbd_fs/Android.bp
+++ /dev/null
@@ -1,30 +0,0 @@
-// libadbd_fs
-// =========================================================
-cc_library {
-    name: "libadbd_fs",
-    defaults: ["adbd_defaults"],
-
-    srcs: ["adbd_fs.cpp"],
-    static_libs: [
-        "libbase",
-        "libcutils",
-        "liblog",
-    ],
-    export_include_dirs: ["include"],
-
-    version_script: "libadbd_fs.map.txt",
-    stubs: {
-        versions: ["1"],
-        symbol_file: "libadbd_fs.map.txt",
-    },
-
-    host_supported: true,
-    recovery_available: true,
-    compile_multilib: "both",
-
-    target: {
-        darwin: {
-            enabled: false,
-        }
-    },
-}
diff --git a/adb/libs/libadbd_fs/adbd_fs.cpp b/adb/libs/libadbd_fs/adbd_fs.cpp
deleted file mode 100644
index 8e62d40..0000000
--- a/adb/libs/libadbd_fs/adbd_fs.cpp
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <adbd_fs.h>
-
-#include <private/fs_config.h>
-
-void adbd_fs_config(const char* path, int dir, const char* target_out_path, uid_t* uid, gid_t* gid,
-                    mode_t* mode, uint64_t* capabilities) {
-  unsigned uid_hack;
-  unsigned gid_hack;
-  unsigned mode_hack;
-  fs_config(path, dir, target_out_path, &uid_hack, &gid_hack, &mode_hack, capabilities);
-  *uid = uid_hack;
-  *gid = gid_hack;
-  *mode = mode_hack;
-}
diff --git a/adb/libs/libadbd_fs/include/adbd_fs.h b/adb/libs/libadbd_fs/include/adbd_fs.h
deleted file mode 100644
index 6158d72..0000000
--- a/adb/libs/libadbd_fs/include/adbd_fs.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <stdint.h>
-#include <sys/types.h>
-
-extern "C" {
-// Thin wrapper around libcutils fs_config.
-void adbd_fs_config(const char* path, int dir, const char* target_out_path, uid_t* uid, gid_t* gid,
-                    mode_t* mode, uint64_t* capabilities);
-}
diff --git a/adb/libs/libadbd_fs/libadbd_fs.map.txt b/adb/libs/libadbd_fs/libadbd_fs.map.txt
deleted file mode 100644
index 1454e96..0000000
--- a/adb/libs/libadbd_fs/libadbd_fs.map.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-LIBADBD_FS {
-  global:
-    adbd_fs_config; # apex
-  local:
-    *;
-};
diff --git a/adb/mdns_test.cpp b/adb/mdns_test.cpp
deleted file mode 100644
index 1f662c1..0000000
--- a/adb/mdns_test.cpp
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <gtest/gtest.h>
-
-#include "adb_mdns.h"
-
-static bool isValidMdnsServiceName(std::string_view name) {
-    // The rules for Service Names [RFC6335] state that they may be no more
-    // than fifteen characters long (not counting the mandatory underscore),
-    // consisting of only letters, digits, and hyphens, must begin and end
-    // with a letter or digit, must not contain consecutive hyphens, and
-    // must contain at least one letter.
-
-    // No more than 15 characters long
-    if (name.empty() || name.size() > 15) {
-        return false;
-    }
-
-    bool hasAtLeastOneLetter = false;
-    bool sawHyphen = false;
-    for (size_t i = 0; i < name.size(); ++i) {
-        // Must contain at least one letter
-        // Only contains letters, digits and hyphens
-        if (name[i] == '-') {
-            // Cannot be at beginning or end
-            if (i == 0 || i == name.size() - 1) {
-                return false;
-            }
-            if (sawHyphen) {
-                // Consecutive hyphen found
-                return false;
-            }
-            sawHyphen = true;
-            continue;
-        }
-
-        sawHyphen = false;
-        if ((name[i] >= 'a' && name[i] <= 'z') || (name[i] >= 'A' && name[i] <= 'Z')) {
-            hasAtLeastOneLetter = true;
-            continue;
-        }
-
-        if (name[i] >= '0' && name[i] <= '9') {
-            continue;
-        }
-
-        // Invalid character
-        return false;
-    }
-
-    return hasAtLeastOneLetter;
-}
-
-TEST(mdns, test_isValidMdnsServiceName) {
-    // Longer than 15 characters
-    EXPECT_FALSE(isValidMdnsServiceName("abcd1234abcd1234"));
-
-    // Contains invalid characters
-    EXPECT_FALSE(isValidMdnsServiceName("a*a"));
-    EXPECT_FALSE(isValidMdnsServiceName("a_a"));
-    EXPECT_FALSE(isValidMdnsServiceName("_a"));
-
-    // Does not begin or end with letter or digit
-    EXPECT_FALSE(isValidMdnsServiceName(""));
-    EXPECT_FALSE(isValidMdnsServiceName("-"));
-    EXPECT_FALSE(isValidMdnsServiceName("-a"));
-    EXPECT_FALSE(isValidMdnsServiceName("-1"));
-    EXPECT_FALSE(isValidMdnsServiceName("a-"));
-    EXPECT_FALSE(isValidMdnsServiceName("1-"));
-
-    // Contains consecutive hyphens
-    EXPECT_FALSE(isValidMdnsServiceName("a--a"));
-
-    // Does not contain at least one letter
-    EXPECT_FALSE(isValidMdnsServiceName("1"));
-    EXPECT_FALSE(isValidMdnsServiceName("12"));
-    EXPECT_FALSE(isValidMdnsServiceName("1-2"));
-
-    // Some valid names
-    EXPECT_TRUE(isValidMdnsServiceName("a"));
-    EXPECT_TRUE(isValidMdnsServiceName("a1"));
-    EXPECT_TRUE(isValidMdnsServiceName("1A"));
-    EXPECT_TRUE(isValidMdnsServiceName("aZ"));
-    EXPECT_TRUE(isValidMdnsServiceName("a-Z"));
-    EXPECT_TRUE(isValidMdnsServiceName("a-b-Z"));
-    EXPECT_TRUE(isValidMdnsServiceName("abc-def-123-456"));
-}
-
-TEST(mdns, ServiceName_RFC6335) {
-    EXPECT_TRUE(isValidMdnsServiceName(ADB_MDNS_SERVICE_TYPE));
-    EXPECT_TRUE(isValidMdnsServiceName(ADB_MDNS_TLS_PAIRING_TYPE));
-    EXPECT_TRUE(isValidMdnsServiceName(ADB_MDNS_TLS_CONNECT_TYPE));
-}
diff --git a/adb/pairing_auth/Android.bp b/adb/pairing_auth/Android.bp
deleted file mode 100644
index a43f4d0..0000000
--- a/adb/pairing_auth/Android.bp
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright (C) 2020 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-cc_defaults {
-    name: "libadb_pairing_auth_defaults",
-    cflags: [
-        "-Wall",
-        "-Wextra",
-        "-Wthread-safety",
-        "-Werror",
-    ],
-
-    compile_multilib: "both",
-
-    srcs: [
-        "aes_128_gcm.cpp",
-        "pairing_auth.cpp",
-    ],
-    target: {
-        android: {
-            version_script: "libadb_pairing_auth.map.txt",
-        },
-        windows: {
-            compile_multilib: "first",
-            enabled: true,
-        },
-    },
-    export_include_dirs: ["include"],
-
-    visibility: [
-        "//art:__subpackages__",
-        "//system/core/adb:__subpackages__",
-    ],
-
-    // libadb_pairing_auth doesn't need an embedded build number.
-    use_version_lib: false,
-
-    host_supported: true,
-    recovery_available: false,
-
-    stl: "libc++_static",
-
-    static_libs: ["libbase"],
-    shared_libs: [
-        "libcrypto",
-        "liblog",
-    ],
-}
-
-cc_library {
-    name: "libadb_pairing_auth",
-    defaults: ["libadb_pairing_auth_defaults"],
-
-    apex_available: [
-        "com.android.adbd",
-    ],
-
-    stubs: {
-        symbol_file: "libadb_pairing_auth.map.txt",
-        versions: ["30"],
-    },
-}
-
-// For running atest (b/147158681)
-cc_library_static {
-    name: "libadb_pairing_auth_static",
-    defaults: ["libadb_pairing_auth_defaults"],
-
-    apex_available: [
-        "//apex_available:platform",
-    ],
-}
diff --git a/adb/pairing_auth/aes_128_gcm.cpp b/adb/pairing_auth/aes_128_gcm.cpp
deleted file mode 100644
index 51520d8..0000000
--- a/adb/pairing_auth/aes_128_gcm.cpp
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "adb/pairing/aes_128_gcm.h"
-
-#include <android-base/endian.h>
-#include <android-base/logging.h>
-
-#include <openssl/evp.h>
-#include <openssl/hkdf.h>
-#include <openssl/rand.h>
-
-namespace adb {
-namespace pairing {
-
-namespace {
-// Size of AES-128-GCM key, in bytes
-static constexpr size_t kHkdfKeyLength = 16;
-
-}  // namespace
-
-Aes128Gcm::Aes128Gcm(const uint8_t* key_material, size_t key_material_len) {
-    CHECK(key_material);
-    CHECK_NE(key_material_len, 0ul);
-
-    uint8_t key[kHkdfKeyLength];
-    uint8_t info[] = "adb pairing_auth aes-128-gcm key";
-    CHECK_EQ(HKDF(key, sizeof(key), EVP_sha256(), key_material, key_material_len, nullptr, 0, info,
-                  sizeof(info) - 1),
-             1);
-    CHECK(EVP_AEAD_CTX_init(context_.get(), EVP_aead_aes_128_gcm(), key, sizeof(key),
-                            EVP_AEAD_DEFAULT_TAG_LENGTH, nullptr));
-}
-
-std::optional<size_t> Aes128Gcm::Encrypt(const uint8_t* in, size_t in_len, uint8_t* out,
-                                         size_t out_len) {
-    std::vector<uint8_t> nonce(EVP_AEAD_nonce_length(EVP_AEAD_CTX_aead(context_.get())), 0);
-    memcpy(nonce.data(), &enc_sequence_, sizeof(enc_sequence_));
-    size_t written_sz;
-    if (!EVP_AEAD_CTX_seal(context_.get(), out, &written_sz, out_len, nonce.data(), nonce.size(),
-                           in, in_len, nullptr, 0)) {
-        LOG(ERROR) << "Failed to encrypt (in_len=" << in_len << ", out_len=" << out_len
-                   << ", out_len_needed=" << EncryptedSize(in_len) << ")";
-        return std::nullopt;
-    }
-
-    ++enc_sequence_;
-    return written_sz;
-}
-
-std::optional<size_t> Aes128Gcm::Decrypt(const uint8_t* in, size_t in_len, uint8_t* out,
-                                         size_t out_len) {
-    std::vector<uint8_t> nonce(EVP_AEAD_nonce_length(EVP_AEAD_CTX_aead(context_.get())), 0);
-    memcpy(nonce.data(), &dec_sequence_, sizeof(dec_sequence_));
-    size_t written_sz;
-    if (!EVP_AEAD_CTX_open(context_.get(), out, &written_sz, out_len, nonce.data(), nonce.size(),
-                           in, in_len, nullptr, 0)) {
-        LOG(ERROR) << "Failed to decrypt (in_len=" << in_len << ", out_len=" << out_len
-                   << ", out_len_needed=" << DecryptedSize(in_len) << ")";
-        return std::nullopt;
-    }
-
-    ++dec_sequence_;
-    return written_sz;
-}
-
-size_t Aes128Gcm::EncryptedSize(size_t size) {
-    // https://commondatastorage.googleapis.com/chromium-boringssl-docs/aead.h.html#EVP_AEAD_CTX_seal
-    return size + EVP_AEAD_max_overhead(EVP_AEAD_CTX_aead(context_.get()));
-}
-
-size_t Aes128Gcm::DecryptedSize(size_t size) {
-    // https://commondatastorage.googleapis.com/chromium-boringssl-docs/aead.h.html#EVP_AEAD_CTX_open
-    return size;
-}
-
-}  // namespace pairing
-}  // namespace adb
diff --git a/adb/pairing_auth/include/adb/pairing/aes_128_gcm.h b/adb/pairing_auth/include/adb/pairing/aes_128_gcm.h
deleted file mode 100644
index 6be5856..0000000
--- a/adb/pairing_auth/include/adb/pairing/aes_128_gcm.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <stdint.h>
-
-#include <optional>
-#include <vector>
-
-#include <openssl/aead.h>
-
-namespace adb {
-namespace pairing {
-
-class Aes128Gcm {
-  public:
-    explicit Aes128Gcm(const uint8_t* key_material, size_t key_material_len);
-
-    // Encrypt a block of data in |in| of length |in_len|, this consumes all data
-    // in |in| and places the encrypted data in |out| if |out_len| indicates that
-    // there is enough space. The data contains information needed for
-    // decryption that is specific to this implementation and is therefore only
-    // suitable for decryption with this class.
-    // The method returns the number of bytes placed in |out| on success and a
-    // negative value if an error occurs.
-    std::optional<size_t> Encrypt(const uint8_t* in, size_t in_len, uint8_t* out, size_t out_len);
-    // Decrypt a block of data in |in| of length |in_len|, this consumes all data
-    // in |in_len| bytes of data. The decrypted output is placed in the |out|
-    // buffer of length |out_len|. On successful decryption the number of bytes in
-    // |out| will be placed in |out_len|.
-    // The method returns the number of bytes consumed from the |in| buffer. If
-    // there is not enough data available in |in| the method returns zero. If
-    // an error occurs the method returns a negative value.
-    std::optional<size_t> Decrypt(const uint8_t* in, size_t in_len, uint8_t* out, size_t out_len);
-
-    // Return a safe amount of buffer storage needed to encrypt |size| bytes.
-    size_t EncryptedSize(size_t size);
-    // Return a safe amount of buffer storage needed to decrypt |size| bytes.
-    size_t DecryptedSize(size_t size);
-
-  private:
-    bssl::ScopedEVP_AEAD_CTX context_;
-    // Sequence numbers to use as nonces in the encryption scheme
-    uint64_t dec_sequence_ = 0;
-    uint64_t enc_sequence_ = 0;
-};
-
-}  // namespace pairing
-}  // namespace adb
diff --git a/adb/pairing_auth/include/adb/pairing/pairing_auth.h b/adb/pairing_auth/include/adb/pairing/pairing_auth.h
deleted file mode 100644
index 9ef97e2..0000000
--- a/adb/pairing_auth/include/adb/pairing/pairing_auth.h
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <stddef.h>
-#include <stdint.h>
-#include <sys/cdefs.h>
-
-#if !defined(__INTRODUCED_IN)
-#define __INTRODUCED_IN(__api_level) /* nothing */
-#endif
-
-__BEGIN_DECLS
-#if !defined(__ANDROID__) || __ANDROID_API__ >= 30
-
-/**
- * PairingAuthCtx is a wrapper around the SPAKE2 protocol + cipher initialization
- * for encryption. On construction, the |password| will be used to generate a
- * SPAKE2 message. Each peer will exchange the messages in |pairing_auth_get_msg|
- * to initialize their ciphers in |pairing_auth_init_cipher|. If both peers used the
- * same |password|, then both sides will be able to decrypt each other's messages.
- *
- * On creation of a PairingAuthCtx, |pairing_auth_init_cipher| prior to using
- * the encrypt and decrypt APIs. Furthermore, you can only initialize the cipher
- * once.
- *
- * See pairing_auth_test.cpp for example usage.
- *
- */
-struct PairingAuthCtx;
-typedef struct PairingAuthCtx PairingAuthCtx;
-
-/**
- * Creates a new PairingAuthCtx instance as the server.
- *
- * @param pswd the shared secret the server and client use to authenticate each
- *             other. Will abort if null.
- * @param len the length of the pswd in bytes. Will abort if 0.
- * @return a new PairingAuthCtx server instance. Caller is responsible for
- *         destroying the context via #pairing_auth_destroy.
- */
-PairingAuthCtx* pairing_auth_server_new(const uint8_t* pswd, size_t len) __INTRODUCED_IN(30);
-
-/**
- * Creates a new PairingAuthCtx instance as the client.
- *
- * @param pswd the shared secret the server and client use to authenticate each
- *             other. Will abort if null.
- * @param len the length of the pswd in bytes. Will abort if 0.
- * @return a new PairingAuthCtx client instance. Caller is responsible for
- *         destroying the context via #pairing_auth_destroy.
- */
-PairingAuthCtx* pairing_auth_client_new(const uint8_t* pswd, size_t len) __INTRODUCED_IN(30);
-
-/**
- * Destroys the PairingAuthCtx.
- *
- * @param ctx the PairingAuthCtx instance to destroy. Will abort if null.
- */
-void pairing_auth_destroy(PairingAuthCtx* ctx) __INTRODUCED_IN(30);
-
-/**
- * Returns the exact size of the SPAKE2 msg.
- *
- * Use this size as the buffer size when retrieving the message via
- * #pairing_auth_get_msg.
- *
- * @param ctx the PairingAuthCtx instance. Will abort if null.
- * @return the size of the SPAKE2 message in bytes. This is guaranteed to be > 0.
- */
-size_t pairing_auth_msg_size(PairingAuthCtx* ctx) __INTRODUCED_IN(30);
-
-/**
- * Writes the SPAKE2 message to exchange with the other party to |out_buf|.
- *
- * This is guaranteed to write a valid message to |out_buf|. Use #pairing_auth_msg_size
- * to get the size the |out_buf| should be. The SPAKE2 messages will be used to
- * initialize the cipher for encryption/decryption (see #pairing_auth_init_cipher).
- *
- * @param ctx the PairingAuthCtx instance. Will abort if null.
- * @param out_buf the buffer the message is written to. The buffer is assumed to
- *                be have at least #pairing_auth_msg_size size. Will abort if
- *                out_buf is null.
- */
-void pairing_auth_get_spake2_msg(PairingAuthCtx* ctx, uint8_t* out_buf) __INTRODUCED_IN(30);
-
-/**
- * Processes the peer's |their_msg| and attempts to initialize the cipher for
- * encryption.
- *
- * You can only call this method ONCE with a non-empty |msg|, regardless of success
- * or failure. On success, you can use the #pairing_auth_decrypt and #pairing_auth_encrypt
- * methods to exchange any further information securely. On failure, this
- * PairingAuthCtx instance has no more purpose and should be destroyed.
- *
- * @param ctx the PairingAuthCtx instance. Will abort if null.
- * @param their_msg the peer's SPAKE2 msg. See #pairing_auth_get_msg. Will abort
- *        if null.
- * @param msg_len the length of their_msg in bytes. Will abort if 0.
- * @return true iff the client and server used the same password when creating
- *         the PairingAuthCtx. See
- *         https: *commondatastorage.googleapis.com/chromium-boringssl-docs/curve25519.h.html#SPAKE2
- *         for more details on the SPAKE2 protocol.
- */
-bool pairing_auth_init_cipher(PairingAuthCtx* ctx, const uint8_t* their_msg, size_t msg_len)
-        __INTRODUCED_IN(30);
-
-/**
- * Returns a safe buffer size for encrypting data of a certain size.
- *
- * IMPORTANT: This will abort if either #pairing_auth_init_cipher was not called
- * or #pairing_auth_init_cipher failed.
- *
- * @param ctx the PairingAuthCtx instance. Will abort if null.
- * @param len the size of the message wanting to encrypt in bytes.
- * @return the minimum buffer size, in bytes, to hold an encrypted message of size len. See
- * #pairing_auth_encrypt for usage.
- */
-size_t pairing_auth_safe_encrypted_size(PairingAuthCtx* ctx, size_t len) __INTRODUCED_IN(30);
-
-/**
- * Encrypts input data and writes the encrypted data into a user-provided buffer.
- *
- * IMPORTANT: This will abort if either #pairing_auth_init_cipher was not called
- * or #pairing_auth_init_cipher failed.
- *
- * @param ctx the PairingAuthCtx instance. Will abort if null.
- * @param inbuf the buffer containing the data to encrypt. Will abort if null.
- * @param inlen the size of inbuf in bytes. Will abort if 0.
- * @param outbuf the buffer to write the encrypted data to. Will abort if null
- * @param outlen the size of outbuf in bytes. See #pairing_auth_safe_encrypted_size.
- * @return true if all the data was encrypted and written to outbuf, false
- *         otherwise.
- */
-bool pairing_auth_encrypt(PairingAuthCtx* ctx, const uint8_t* inbuf, size_t inlen, uint8_t* outbuf,
-                          size_t* outlen) __INTRODUCED_IN(30);
-
-/**
- * Returns a safe buffer size for decrypting data of a certain size.
- *
- * IMPORTANT: This will abort if either #pairing_auth_init_cipher was not called
- * or #pairing_auth_init_cipher failed.
- *
- * @param ctx the PairingAuthCtx instance. Will abort if null.
- * @param buf the buffer containing the encrypted data. Will abort if null.
- * @param len the size of the buf in bytes. Will abort if 0.
- * @return the minimum buffer size, in bytes, to hold a decrypted message of size len. See
- *         #pairing_auth_decrypt for usage.
- */
-size_t pairing_auth_safe_decrypted_size(PairingAuthCtx* ctx, const uint8_t* buf, size_t len)
-        __INTRODUCED_IN(30);
-
-/**
- * Decrypts input data and writes the decrypted data into a user-provided buffer.
- *
- * IMPORTANT: This will abort if either #pairing_auth_init_cipher was not called
- * or #pairing_auth_init_cipher failed.
- *
- * @param ctx the PairingAuthCtx instance. Will abort if null.
- * @param inbuf the buffer containing the data to decrypt. Will abort if null.
- * @param inlen the size of inbuf in bytes. WIll abort if 0.
- * @param outbuf the buffer to write the decrypted data to. Will abort if null.
- * @param outlen the size of outbuf in bytes. See #pairing_auth_safe_decrypted_size.
- *        Will abort if 0.
- * @return true if all the data was decrypted and written to outbuf, false
- *         otherwise.
- */
-bool pairing_auth_decrypt(PairingAuthCtx* ctx, const uint8_t* inbuf, size_t inlen, uint8_t* outbuf,
-                          size_t* outlen) __INTRODUCED_IN(30);
-
-#endif  //!__ANDROID__ || __ANDROID_API__ >= 30
-__END_DECLS
diff --git a/adb/pairing_auth/libadb_pairing_auth.map.txt b/adb/pairing_auth/libadb_pairing_auth.map.txt
deleted file mode 100644
index fdc1557..0000000
--- a/adb/pairing_auth/libadb_pairing_auth.map.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-LIBADB_PAIRING_AUTH {
-  global:
-    pairing_auth_msg_size; # apex introduced=30
-    pairing_auth_get_spake2_msg; # apex introduced=30
-    pairing_auth_init_cipher; # apex introduced=30
-    pairing_auth_safe_encrypted_size; # apex introduced=30
-    pairing_auth_encrypt; # apex introduced=30
-    pairing_auth_safe_decrypted_size; # apex introduced=30
-    pairing_auth_decrypt; # apex introduced=30
-    pairing_auth_server_new; # apex introduced=30
-    pairing_auth_client_new; # apex introduced=30
-    pairing_auth_destroy; # apex introduced=30
-  local:
-    *;
-};
diff --git a/adb/pairing_auth/pairing_auth.cpp b/adb/pairing_auth/pairing_auth.cpp
deleted file mode 100644
index 0ac04e6..0000000
--- a/adb/pairing_auth/pairing_auth.cpp
+++ /dev/null
@@ -1,300 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "adb/pairing/pairing_auth.h"
-
-#include <android-base/logging.h>
-
-#include <openssl/curve25519.h>
-#include <openssl/mem.h>
-
-#include <iomanip>
-#include <sstream>
-#include <vector>
-
-#include "adb/pairing/aes_128_gcm.h"
-
-using namespace adb::pairing;
-
-static constexpr spake2_role_t kClientRole = spake2_role_alice;
-static constexpr spake2_role_t kServerRole = spake2_role_bob;
-
-static const uint8_t kClientName[] = "adb pair client";
-static const uint8_t kServerName[] = "adb pair server";
-
-// This class is basically a wrapper around the SPAKE2 protocol + initializing a
-// cipher with the generated key material for encryption.
-struct PairingAuthCtx {
-  public:
-    using Data = std::vector<uint8_t>;
-    enum class Role {
-        Client,
-        Server,
-    };
-
-    explicit PairingAuthCtx(Role role, const Data& pswd);
-
-    // Returns the message to exchange with the other party. This is guaranteed
-    // to have a non-empty message if creating this object with
-    // |PairingAuthCtx::Create|, so you won't need to check.
-    const Data& msg() const;
-
-    // Processes the peer's |msg| and attempts to initialize the cipher for
-    // encryption. You can only call this method ONCE with a non-empty |msg|,
-    // regardless of success or failure. Subsequent calls will always return
-    // false. On success, you can use the |decrypt|
-    // and |encrypt| methods to exchange any further information securely.
-    //
-    // Note: Once you call this with a non-empty key, the state is locked, which
-    // means that you cannot try and register another key, regardless of the
-    // return value. In order to register another key, you have to create a new
-    // instance of PairingAuthCtx.
-    bool InitCipher(const Data& their_msg);
-
-    // Encrypts |data| and returns the result. If encryption fails, the return
-    // will be an empty vector.
-    Data Encrypt(const Data& data);
-
-    // Decrypts |data| and returns the result. If decryption fails, the return
-    // will be an empty vector.
-    Data Decrypt(const Data& data);
-
-    // Returns a safe buffer size for encrypting a buffer of size |len|.
-    size_t SafeEncryptedSize(size_t len);
-
-    // Returns a safe buffer size for decrypting a buffer of size |len|.
-    size_t SafeDecryptedSize(size_t len);
-
-  private:
-    Data our_msg_;
-    Role role_;
-    bssl::UniquePtr<SPAKE2_CTX> spake2_ctx_;
-    std::unique_ptr<Aes128Gcm> cipher_;
-};  // PairingAuthCtx
-
-PairingAuthCtx::PairingAuthCtx(Role role, const Data& pswd) : role_(role) {
-    CHECK(!pswd.empty());
-    // Try to create the spake2 context and generate the public key.
-    spake2_role_t spake_role;
-    const uint8_t* my_name = nullptr;
-    const uint8_t* their_name = nullptr;
-    size_t my_len = 0;
-    size_t their_len = 0;
-
-    // Create the SPAKE2 context
-    switch (role_) {
-        case Role::Client:
-            spake_role = kClientRole;
-            my_name = kClientName;
-            my_len = sizeof(kClientName);
-            their_name = kServerName;
-            their_len = sizeof(kServerName);
-            break;
-        case Role::Server:
-            spake_role = kServerRole;
-            my_name = kServerName;
-            my_len = sizeof(kServerName);
-            their_name = kClientName;
-            their_len = sizeof(kClientName);
-            break;
-    }
-    spake2_ctx_.reset(SPAKE2_CTX_new(spake_role, my_name, my_len, their_name, their_len));
-    if (spake2_ctx_ == nullptr) {
-        LOG(ERROR) << "Unable to create a SPAKE2 context.";
-        return;
-    }
-
-    // Generate the SPAKE2 public key
-    size_t key_size = 0;
-    uint8_t key[SPAKE2_MAX_MSG_SIZE];
-    int status = SPAKE2_generate_msg(spake2_ctx_.get(), key, &key_size, SPAKE2_MAX_MSG_SIZE,
-                                     pswd.data(), pswd.size());
-    if (status != 1 || key_size == 0) {
-        LOG(ERROR) << "Unable to generate the SPAKE2 public key.";
-        return;
-    }
-    our_msg_.assign(key, key + key_size);
-}
-
-const PairingAuthCtx::Data& PairingAuthCtx::msg() const {
-    return our_msg_;
-}
-
-bool PairingAuthCtx::InitCipher(const PairingAuthCtx::Data& their_msg) {
-    // You can only register a key once.
-    CHECK(!their_msg.empty());
-    CHECK(!cipher_);
-
-    // Don't even try to process a message over the SPAKE2_MAX_MSG_SIZE
-    if (their_msg.size() > SPAKE2_MAX_MSG_SIZE) {
-        LOG(ERROR) << "their_msg size [" << their_msg.size() << "] greater then max size ["
-                   << SPAKE2_MAX_MSG_SIZE << "].";
-        return false;
-    }
-
-    size_t key_material_len = 0;
-    uint8_t key_material[SPAKE2_MAX_KEY_SIZE];
-    int status = SPAKE2_process_msg(spake2_ctx_.get(), key_material, &key_material_len,
-                                    sizeof(key_material), their_msg.data(), their_msg.size());
-    if (status != 1) {
-        LOG(ERROR) << "Unable to process their public key";
-        return false;
-    }
-
-    // Once SPAKE2_process_msg returns successfully, you can't do anything else
-    // with the context, besides destroy it.
-    cipher_.reset(new Aes128Gcm(key_material, key_material_len));
-
-    return true;
-}
-
-PairingAuthCtx::Data PairingAuthCtx::Encrypt(const PairingAuthCtx::Data& data) {
-    CHECK(cipher_);
-    CHECK(!data.empty());
-
-    // Determine the size for the encrypted data based on the raw data.
-    Data encrypted(cipher_->EncryptedSize(data.size()));
-    auto out_size = cipher_->Encrypt(data.data(), data.size(), encrypted.data(), encrypted.size());
-    if (!out_size.has_value() || *out_size == 0) {
-        LOG(ERROR) << "Unable to encrypt data";
-        return Data();
-    }
-    encrypted.resize(*out_size);
-
-    return encrypted;
-}
-
-PairingAuthCtx::Data PairingAuthCtx::Decrypt(const PairingAuthCtx::Data& data) {
-    CHECK(cipher_);
-    CHECK(!data.empty());
-
-    // Determine the size for the decrypted data based on the raw data.
-    Data decrypted(cipher_->DecryptedSize(data.size()));
-    size_t decrypted_size = decrypted.size();
-    auto out_size = cipher_->Decrypt(data.data(), data.size(), decrypted.data(), decrypted_size);
-    if (!out_size.has_value() || *out_size == 0) {
-        LOG(ERROR) << "Unable to decrypt data";
-        return Data();
-    }
-    decrypted.resize(*out_size);
-
-    return decrypted;
-}
-
-size_t PairingAuthCtx::SafeEncryptedSize(size_t len) {
-    CHECK(cipher_);
-    return cipher_->EncryptedSize(len);
-}
-
-size_t PairingAuthCtx::SafeDecryptedSize(size_t len) {
-    CHECK(cipher_);
-    return cipher_->DecryptedSize(len);
-}
-
-PairingAuthCtx* pairing_auth_server_new(const uint8_t* pswd, size_t len) {
-    CHECK(pswd);
-    CHECK_GT(len, 0U);
-    std::vector<uint8_t> p(pswd, pswd + len);
-    auto* ret = new PairingAuthCtx(PairingAuthCtx::Role::Server, std::move(p));
-    CHECK(!ret->msg().empty());
-    return ret;
-}
-
-PairingAuthCtx* pairing_auth_client_new(const uint8_t* pswd, size_t len) {
-    CHECK(pswd);
-    CHECK_GT(len, 0U);
-    std::vector<uint8_t> p(pswd, pswd + len);
-    auto* ret = new PairingAuthCtx(PairingAuthCtx::Role::Client, std::move(p));
-    CHECK(!ret->msg().empty());
-    return ret;
-}
-
-size_t pairing_auth_msg_size(PairingAuthCtx* ctx) {
-    CHECK(ctx);
-    return ctx->msg().size();
-}
-
-void pairing_auth_get_spake2_msg(PairingAuthCtx* ctx, uint8_t* out_buf) {
-    CHECK(ctx);
-    CHECK(out_buf);
-    auto& msg = ctx->msg();
-    memcpy(out_buf, msg.data(), msg.size());
-}
-
-bool pairing_auth_init_cipher(PairingAuthCtx* ctx, const uint8_t* their_msg, size_t msg_len) {
-    CHECK(ctx);
-    CHECK(their_msg);
-    CHECK_GT(msg_len, 0U);
-
-    std::vector<uint8_t> p(their_msg, their_msg + msg_len);
-    return ctx->InitCipher(p);
-}
-
-size_t pairing_auth_safe_encrypted_size(PairingAuthCtx* ctx, size_t len) {
-    CHECK(ctx);
-    return ctx->SafeEncryptedSize(len);
-}
-
-bool pairing_auth_encrypt(PairingAuthCtx* ctx, const uint8_t* inbuf, size_t inlen, uint8_t* outbuf,
-                          size_t* outlen) {
-    CHECK(ctx);
-    CHECK(inbuf);
-    CHECK(outbuf);
-    CHECK(outlen);
-    CHECK_GT(inlen, 0U);
-
-    std::vector<uint8_t> in(inbuf, inbuf + inlen);
-    auto out = ctx->Encrypt(in);
-    if (out.empty()) {
-        return false;
-    }
-
-    memcpy(outbuf, out.data(), out.size());
-    *outlen = out.size();
-    return true;
-}
-
-size_t pairing_auth_safe_decrypted_size(PairingAuthCtx* ctx, const uint8_t* buf, size_t len) {
-    CHECK(ctx);
-    CHECK(buf);
-    CHECK_GT(len, 0U);
-    // We no longer need buf for EVP_AEAD
-    return ctx->SafeDecryptedSize(len);
-}
-
-bool pairing_auth_decrypt(PairingAuthCtx* ctx, const uint8_t* inbuf, size_t inlen, uint8_t* outbuf,
-                          size_t* outlen) {
-    CHECK(ctx);
-    CHECK(inbuf);
-    CHECK(outbuf);
-    CHECK(outlen);
-    CHECK_GT(inlen, 0U);
-
-    std::vector<uint8_t> in(inbuf, inbuf + inlen);
-    auto out = ctx->Decrypt(in);
-    if (out.empty()) {
-        return false;
-    }
-
-    memcpy(outbuf, out.data(), out.size());
-    *outlen = out.size();
-    return true;
-}
-
-void pairing_auth_destroy(PairingAuthCtx* ctx) {
-    CHECK(ctx);
-    delete ctx;
-}
diff --git a/adb/pairing_auth/tests/Android.bp b/adb/pairing_auth/tests/Android.bp
deleted file mode 100644
index 213123d..0000000
--- a/adb/pairing_auth/tests/Android.bp
+++ /dev/null
@@ -1,38 +0,0 @@
-//
-// Copyright (C) 2020 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-cc_test {
-    name: "adb_pairing_auth_test",
-    srcs: [
-        "aes_128_gcm_test.cpp",
-        "pairing_auth_test.cpp",
-    ],
-
-    compile_multilib: "first",
-
-    shared_libs: [
-        "libbase",
-        "libcrypto",
-    ],
-
-    // Let's statically link them so we don't have to install it onto the
-    // system image for testing.
-    static_libs: [
-        "libadb_pairing_auth_static",
-    ],
-
-    test_suites: ["device-tests"],
-}
diff --git a/adb/pairing_auth/tests/aes_128_gcm_test.cpp b/adb/pairing_auth/tests/aes_128_gcm_test.cpp
deleted file mode 100644
index 55689d6..0000000
--- a/adb/pairing_auth/tests/aes_128_gcm_test.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <gtest/gtest.h>
-
-#include <memory>
-
-#include <adb/pairing/aes_128_gcm.h>
-#include <openssl/rand.h>
-
-namespace adb {
-namespace pairing {
-
-TEST(Aes128GcmTest, init_null_material) {
-    std::unique_ptr<Aes128Gcm> cipher;
-    ASSERT_DEATH({ cipher.reset(new Aes128Gcm(nullptr, 42)); }, "");
-}
-
-TEST(Aes128GcmTest, init_empty_material) {
-    uint8_t material[64];
-    std::unique_ptr<Aes128Gcm> cipher;
-    ASSERT_DEATH({ cipher.reset(new Aes128Gcm(material, 0)); }, "");
-}
-
-TEST(Aes128GcmTest, encrypt_decrypt) {
-    const uint8_t msg[] = "alice and bob, sitting in a binary tree";
-    uint8_t material[256];
-    uint8_t encrypted[1024];
-    uint8_t out_buf[1024] = {};
-
-    RAND_bytes(material, sizeof(material));
-    Aes128Gcm alice(material, sizeof(material));
-    Aes128Gcm bob(material, sizeof(material));
-    ;
-
-    ASSERT_GE(alice.EncryptedSize(sizeof(msg)), sizeof(msg));
-    auto encrypted_size = alice.Encrypt(msg, sizeof(msg), encrypted, sizeof(encrypted));
-    ASSERT_TRUE(encrypted_size.has_value());
-    ASSERT_GT(*encrypted_size, 0);
-    size_t out_size = sizeof(out_buf);
-    ASSERT_GE(bob.DecryptedSize(*encrypted_size), sizeof(msg));
-    auto decrypted_size = bob.Decrypt(encrypted, *encrypted_size, out_buf, out_size);
-    ASSERT_TRUE(decrypted_size.has_value());
-    ASSERT_EQ(sizeof(msg), *decrypted_size);
-    ASSERT_STREQ(reinterpret_cast<const char*>(msg), reinterpret_cast<const char*>(out_buf));
-}
-
-}  // namespace pairing
-}  // namespace adb
diff --git a/adb/pairing_auth/tests/pairing_auth_test.cpp b/adb/pairing_auth/tests/pairing_auth_test.cpp
deleted file mode 100644
index fdc07f1..0000000
--- a/adb/pairing_auth/tests/pairing_auth_test.cpp
+++ /dev/null
@@ -1,330 +0,0 @@
-/*
- * Copyright 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "AdbPairingAuthTest"
-
-#include <gtest/gtest.h>
-
-#include <adb/pairing/pairing_auth.h>
-#include <android-base/endian.h>
-
-namespace adb {
-namespace pairing {
-
-static void PairingAuthDeleter(PairingAuthCtx* p) {
-    pairing_auth_destroy(p);
-}
-
-class AdbPairingAuthTest : public testing::Test {
-  protected:
-    virtual void SetUp() override {}
-
-    virtual void TearDown() override {}
-
-    using PairingAuthUniquePtr = std::unique_ptr<PairingAuthCtx, decltype(&PairingAuthDeleter)>;
-
-    PairingAuthUniquePtr makeClient(std::vector<uint8_t> pswd) {
-        return PairingAuthUniquePtr(pairing_auth_client_new(pswd.data(), pswd.size()),
-                                    PairingAuthDeleter);
-    }
-
-    PairingAuthUniquePtr makeServer(std::vector<uint8_t> pswd) {
-        return PairingAuthUniquePtr(pairing_auth_server_new(pswd.data(), pswd.size()),
-                                    PairingAuthDeleter);
-    }
-};
-
-TEST_F(AdbPairingAuthTest, EmptyPassword) {
-    // Context creation should fail if password is empty
-    PairingAuthUniquePtr client(nullptr, PairingAuthDeleter);
-    ASSERT_DEATH(
-            {
-                client = PairingAuthUniquePtr(pairing_auth_client_new(nullptr, 0),
-                                              PairingAuthDeleter);
-            },
-            "");
-    ASSERT_DEATH(
-            {
-                client = PairingAuthUniquePtr(pairing_auth_client_new(nullptr, 2),
-                                              PairingAuthDeleter);
-            },
-            "");
-    ASSERT_DEATH(
-            {
-                uint8_t p;
-                client = PairingAuthUniquePtr(pairing_auth_client_new(&p, 0), PairingAuthDeleter);
-            },
-            "");
-}
-
-TEST_F(AdbPairingAuthTest, ValidPassword) {
-    const char* kPswd = "password";
-    std::vector<uint8_t> pswd(kPswd, kPswd + sizeof(kPswd));
-    auto client = makeClient(pswd);
-    auto server = makeServer(pswd);
-
-    ASSERT_NE(nullptr, client);
-    ASSERT_NE(nullptr, server);
-
-    // msg should not be empty.
-    {
-        size_t msg_size = pairing_auth_msg_size(client.get());
-        std::vector<uint8_t> buf(msg_size);
-        ASSERT_GT(msg_size, 0);
-        pairing_auth_get_spake2_msg(client.get(), buf.data());
-    }
-    {
-        size_t msg_size = pairing_auth_msg_size(server.get());
-        std::vector<uint8_t> buf(msg_size);
-        ASSERT_GT(msg_size, 0);
-        pairing_auth_get_spake2_msg(server.get(), buf.data());
-    }
-}
-
-TEST_F(AdbPairingAuthTest, NoInitCipher) {
-    // Register a non-empty password, but not the peer's msg.
-    // You should not be able to encrypt/decrypt messages.
-    const char* kPswd = "password";
-    std::vector<uint8_t> pswd(kPswd, kPswd + sizeof(kPswd));
-    std::vector<uint8_t> data{0x01, 0x02, 0x03};
-    uint8_t outbuf[256];
-    size_t outsize;
-
-    // All other functions should crash if cipher hasn't been initialized.
-    ASSERT_DEATH(
-            {
-                auto server = makeServer(pswd);
-                pairing_auth_init_cipher(server.get(), nullptr, 0);
-            },
-            "");
-    ASSERT_DEATH(
-            {
-                auto server = makeServer(pswd);
-                pairing_auth_encrypt(server.get(), data.data(), data.size(), outbuf, &outsize);
-            },
-            "");
-    ASSERT_DEATH(
-            {
-                auto server = makeServer(pswd);
-                pairing_auth_decrypt(server.get(), data.data(), data.size(), outbuf, &outsize);
-            },
-            "");
-    ASSERT_DEATH(
-            {
-                auto server = makeServer(pswd);
-                pairing_auth_safe_decrypted_size(server.get(), data.data(), data.size());
-            },
-            "");
-    ASSERT_DEATH(
-            {
-                auto server = makeServer(pswd);
-                pairing_auth_safe_encrypted_size(server.get(), data.size());
-            },
-            "");
-}
-
-TEST_F(AdbPairingAuthTest, DifferentPasswords) {
-    // Register different passwords and then exchange the msgs. The
-    // encryption should succeed, but the decryption should fail, since the
-    // ciphers have been initialized with different keys.
-    auto client = makeClient({0x01, 0x02, 0x03});
-    std::vector<uint8_t> client_msg(pairing_auth_msg_size(client.get()));
-    ASSERT_FALSE(client_msg.empty());
-    pairing_auth_get_spake2_msg(client.get(), client_msg.data());
-
-    auto server = makeServer({0x01, 0x02, 0x04});
-    std::vector<uint8_t> server_msg(pairing_auth_msg_size(server.get()));
-    ASSERT_FALSE(server_msg.empty());
-    pairing_auth_get_spake2_msg(server.get(), server_msg.data());
-
-    EXPECT_TRUE(pairing_auth_init_cipher(client.get(), server_msg.data(), server_msg.size()));
-    EXPECT_TRUE(pairing_auth_init_cipher(server.get(), client_msg.data(), client_msg.size()));
-
-    // We shouldn't be able to decrypt.
-    std::vector<uint8_t> msg{0x2a, 0x2b, 0x2c};
-    // Client encrypts, server can't decrypt
-    size_t out_size;
-    client_msg.resize(pairing_auth_safe_encrypted_size(client.get(), msg.size()));
-    ASSERT_GT(client_msg.size(), 0);
-    ASSERT_TRUE(pairing_auth_encrypt(client.get(), msg.data(), msg.size(), client_msg.data(),
-                                     &out_size));
-    ASSERT_GT(out_size, 0);
-    client_msg.resize(out_size);
-
-    server_msg.resize(
-            pairing_auth_safe_decrypted_size(server.get(), client_msg.data(), client_msg.size()));
-    ASSERT_GT(server_msg.size(), 0);
-    ASSERT_FALSE(pairing_auth_decrypt(server.get(), client_msg.data(), client_msg.size(),
-                                      server_msg.data(), &out_size));
-
-    // Server encrypts, client can't decrypt
-    server_msg.resize(pairing_auth_safe_encrypted_size(server.get(), msg.size()));
-    ASSERT_GT(server_msg.size(), 0);
-    ASSERT_TRUE(pairing_auth_encrypt(server.get(), msg.data(), msg.size(), server_msg.data(),
-                                     &out_size));
-    ASSERT_GT(out_size, 0);
-    server_msg.resize(out_size);
-
-    client_msg.resize(
-            pairing_auth_safe_decrypted_size(client.get(), server_msg.data(), server_msg.size()));
-    ASSERT_GT(client_msg.size(), 0);
-    ASSERT_FALSE(pairing_auth_decrypt(client.get(), server_msg.data(), server_msg.size(),
-                                      client_msg.data(), &out_size));
-}
-
-TEST_F(AdbPairingAuthTest, SamePasswords) {
-    // Register same password and then exchange the msgs. The
-    // encryption and decryption should succeed and have the same, unencrypted
-    // values.
-    std::vector<uint8_t> pswd{0x4f, 0x5a, 0x01, 0x46};
-    auto client = makeClient(pswd);
-    std::vector<uint8_t> client_msg(pairing_auth_msg_size(client.get()));
-    ASSERT_FALSE(client_msg.empty());
-    pairing_auth_get_spake2_msg(client.get(), client_msg.data());
-
-    auto server = makeServer(pswd);
-    std::vector<uint8_t> server_msg(pairing_auth_msg_size(server.get()));
-    ASSERT_FALSE(server_msg.empty());
-    pairing_auth_get_spake2_msg(server.get(), server_msg.data());
-
-    EXPECT_TRUE(pairing_auth_init_cipher(client.get(), server_msg.data(), server_msg.size()));
-    EXPECT_TRUE(pairing_auth_init_cipher(server.get(), client_msg.data(), client_msg.size()));
-
-    // We should be able to decrypt.
-    std::vector<uint8_t> msg{0x2a, 0x2b, 0x2c, 0xff, 0x45, 0x12, 0x33};
-    // Client encrypts, server decrypts
-    size_t out_size;
-    client_msg.resize(pairing_auth_safe_encrypted_size(client.get(), msg.size()));
-    ASSERT_GT(client_msg.size(), 0);
-    ASSERT_TRUE(pairing_auth_encrypt(client.get(), msg.data(), msg.size(), client_msg.data(),
-                                     &out_size));
-    ASSERT_GT(out_size, 0);
-    client_msg.resize(out_size);
-
-    server_msg.resize(
-            pairing_auth_safe_decrypted_size(server.get(), client_msg.data(), client_msg.size()));
-    ASSERT_GT(server_msg.size(), 0);
-    ASSERT_TRUE(pairing_auth_decrypt(server.get(), client_msg.data(), client_msg.size(),
-                                     server_msg.data(), &out_size));
-    ASSERT_EQ(out_size, msg.size());
-    EXPECT_EQ(memcmp(msg.data(), server_msg.data(), out_size), 0);
-
-    // Server encrypts, client decrypt
-    server_msg.resize(pairing_auth_safe_encrypted_size(server.get(), msg.size()));
-    ASSERT_GT(server_msg.size(), 0);
-    ASSERT_TRUE(pairing_auth_encrypt(server.get(), msg.data(), msg.size(), server_msg.data(),
-                                     &out_size));
-    ASSERT_GT(out_size, 0);
-    server_msg.resize(out_size);
-
-    client_msg.resize(
-            pairing_auth_safe_decrypted_size(client.get(), server_msg.data(), server_msg.size()));
-    ASSERT_GT(client_msg.size(), 0);
-    ASSERT_TRUE(pairing_auth_decrypt(client.get(), server_msg.data(), server_msg.size(),
-                                     client_msg.data(), &out_size));
-    ASSERT_EQ(out_size, msg.size());
-    EXPECT_EQ(memcmp(msg.data(), client_msg.data(), out_size), 0);
-}
-
-TEST_F(AdbPairingAuthTest, CorruptedPayload) {
-    // Do a matching password for both server/client, but let's fudge with the
-    // header payload field. The decryption should fail.
-    std::vector<uint8_t> pswd{0x4f, 0x5a, 0x01, 0x46};
-    auto client = makeClient(pswd);
-    std::vector<uint8_t> client_msg(pairing_auth_msg_size(client.get()));
-    ASSERT_FALSE(client_msg.empty());
-    pairing_auth_get_spake2_msg(client.get(), client_msg.data());
-
-    auto server = makeServer(pswd);
-    std::vector<uint8_t> server_msg(pairing_auth_msg_size(server.get()));
-    ASSERT_FALSE(server_msg.empty());
-    pairing_auth_get_spake2_msg(server.get(), server_msg.data());
-
-    EXPECT_TRUE(pairing_auth_init_cipher(client.get(), server_msg.data(), server_msg.size()));
-    EXPECT_TRUE(pairing_auth_init_cipher(server.get(), client_msg.data(), client_msg.size()));
-
-    std::vector<uint8_t> msg{0x2a, 0x2b, 0x2c, 0xff, 0x45, 0x12,
-                             0x33, 0x45, 0x12, 0xea, 0xf2, 0xdb};
-    {
-        // Client encrypts whole msg, server decrypts msg. Should be fine.
-        size_t out_size;
-        client_msg.resize(pairing_auth_safe_encrypted_size(client.get(), msg.size()));
-        ASSERT_GT(client_msg.size(), 0);
-        ASSERT_TRUE(pairing_auth_encrypt(client.get(), msg.data(), msg.size(), client_msg.data(),
-                                         &out_size));
-        ASSERT_GT(out_size, 0);
-        client_msg.resize(out_size);
-
-        server_msg.resize(pairing_auth_safe_decrypted_size(server.get(), client_msg.data(),
-                                                           client_msg.size()));
-        ASSERT_GT(server_msg.size(), 0);
-        ASSERT_TRUE(pairing_auth_decrypt(server.get(), client_msg.data(), client_msg.size(),
-                                         server_msg.data(), &out_size));
-        ASSERT_EQ(out_size, msg.size());
-        EXPECT_EQ(memcmp(msg.data(), server_msg.data(), out_size), 0);
-    }
-    {
-        // 1) Client encrypts msg
-        // 2) append some data to the encrypted msg
-        // 3) change the payload field
-        // 4) server tries to decrypt. It should fail.
-        size_t out_size;
-        client_msg.resize(pairing_auth_safe_encrypted_size(client.get(), msg.size()));
-        ASSERT_GT(client_msg.size(), 0);
-        ASSERT_TRUE(pairing_auth_encrypt(client.get(), msg.data(), msg.size(), client_msg.data(),
-                                         &out_size));
-        ASSERT_GT(out_size, 0);
-        client_msg.resize(out_size);
-        client_msg.push_back(0xaa);
-        // This requires knowledge of the layout of the data. payload is the
-        // first four bytes of the client_msg.
-        uint32_t* payload = reinterpret_cast<uint32_t*>(client_msg.data());
-        *payload = ntohl(*payload);
-        *payload = htonl(*payload + 1);
-
-        server_msg.resize(pairing_auth_safe_decrypted_size(server.get(), client_msg.data(),
-                                                           client_msg.size()));
-        ASSERT_GT(server_msg.size(), 0);
-        ASSERT_FALSE(pairing_auth_decrypt(server.get(), client_msg.data(), client_msg.size(),
-                                          server_msg.data(), &out_size));
-    }
-    {
-        // 1) Client encrypts msg
-        // 3) decrement the payload field
-        // 4) server tries to decrypt. It should fail.
-        size_t out_size;
-        client_msg.resize(pairing_auth_safe_encrypted_size(client.get(), msg.size()));
-        ASSERT_GT(client_msg.size(), 0);
-        ASSERT_TRUE(pairing_auth_encrypt(client.get(), msg.data(), msg.size(), client_msg.data(),
-                                         &out_size));
-        ASSERT_GT(out_size, 0);
-        client_msg.resize(out_size);
-        // This requires knowledge of the layout of the data. payload is the
-        // first four bytes of the client_msg.
-        uint32_t* payload = reinterpret_cast<uint32_t*>(client_msg.data());
-        *payload = ntohl(*payload);
-        *payload = htonl(*payload - 1);
-
-        server_msg.resize(pairing_auth_safe_decrypted_size(server.get(), client_msg.data(),
-                                                           client_msg.size()));
-        ASSERT_GT(server_msg.size(), 0);
-        ASSERT_FALSE(pairing_auth_decrypt(server.get(), client_msg.data(), client_msg.size(),
-                                          server_msg.data(), &out_size));
-    }
-}
-
-}  // namespace pairing
-}  // namespace adb
diff --git a/adb/pairing_connection/Android.bp b/adb/pairing_connection/Android.bp
deleted file mode 100644
index 707161b..0000000
--- a/adb/pairing_connection/Android.bp
+++ /dev/null
@@ -1,188 +0,0 @@
-// Copyright (C) 2020 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-cc_defaults {
-    name: "libadb_pairing_connection_defaults",
-    cflags: [
-        "-Wall",
-        "-Wextra",
-        "-Wthread-safety",
-        "-Werror",
-    ],
-
-    compile_multilib: "both",
-
-    srcs: [
-        "pairing_connection.cpp",
-    ],
-    target: {
-        android: {
-            version_script: "libadb_pairing_connection.map.txt",
-        },
-        windows: {
-            compile_multilib: "first",
-            enabled: true,
-        },
-    },
-    export_include_dirs: ["include"],
-
-    visibility: [
-        "//art:__subpackages__",
-        "//system/core/adb:__subpackages__",
-        "//frameworks/base/services:__subpackages__",
-
-        // This needs to be visible to minadbd, even though it's removed via exclude_shared_libs.
-        "//bootable/recovery/minadbd:__subpackages__",
-    ],
-    apex_available: [
-        "com.android.adbd",
-    ],
-
-    // libadb_pairing_connection doesn't need an embedded build number.
-    use_version_lib: false,
-
-    stl: "libc++_static",
-
-    host_supported: true,
-    recovery_available: false,
-
-    static_libs: [
-        "libbase",
-        "libssl",
-    ],
-    shared_libs: [
-        "libcrypto",
-        "liblog",
-        "libadb_pairing_auth",
-    ],
-}
-
-cc_library {
-    name: "libadb_pairing_connection",
-    defaults: ["libadb_pairing_connection_defaults"],
-
-    apex_available: [
-        "com.android.adbd",
-    ],
-
-    stubs: {
-        symbol_file: "libadb_pairing_connection.map.txt",
-        versions: ["30"],
-    },
-
-    static_libs: [
-        "libadb_protos",
-        // Statically link libadb_tls_connection because it is not
-	// ABI-stable.
-        "libadb_tls_connection",
-        "libprotobuf-cpp-lite",
-    ],
-}
-
-// For running atest (b/147158681)
-cc_library_static {
-    name: "libadb_pairing_connection_static",
-    defaults: ["libadb_pairing_connection_defaults"],
-
-    apex_available: [
-        "//apex_available:platform",
-    ],
-
-    static_libs: [
-        "libadb_protos_static",
-        "libprotobuf-cpp-lite",
-        "libadb_tls_connection_static",
-    ],
-}
-
-cc_defaults {
-    name: "libadb_pairing_server_defaults",
-    cflags: [
-        "-Wall",
-        "-Wextra",
-        "-Wthread-safety",
-        "-Werror",
-    ],
-
-    compile_multilib: "both",
-
-    srcs: [
-        "pairing_server.cpp",
-    ],
-    target: {
-        android: {
-            version_script: "libadb_pairing_server.map.txt",
-        },
-    },
-    export_include_dirs: ["include"],
-
-    visibility: [
-        "//art:__subpackages__",
-        "//system/core/adb:__subpackages__",
-        "//frameworks/base/services:__subpackages__",
-    ],
-
-    host_supported: true,
-    recovery_available: false,
-
-    stl: "libc++_static",
-
-    static_libs: [
-        "libbase",
-    ],
-    shared_libs: [
-        "libcrypto",
-        "libcrypto_utils",
-        "libcutils",
-        "liblog",
-        "libadb_pairing_auth",
-        "libadb_pairing_connection",
-    ],
-}
-
-cc_library {
-    name: "libadb_pairing_server",
-    defaults: ["libadb_pairing_server_defaults"],
-
-    apex_available: [
-        "com.android.adbd",
-    ],
-
-    stubs: {
-        symbol_file: "libadb_pairing_server.map.txt",
-        versions: ["30"],
-    },
-
-    static_libs: [
-        // Statically link libadb_crypto because it is not
-	// ABI-stable.
-        "libadb_crypto",
-        "libadb_protos",
-    ],
-}
-
-// For running atest (b/147158681)
-cc_library_static {
-    name: "libadb_pairing_server_static",
-    defaults: ["libadb_pairing_server_defaults"],
-
-    apex_available: [
-        "//apex_available:platform",
-    ],
-
-    static_libs: [
-        "libadb_crypto_static",
-        "libadb_protos_static",
-    ],
-}
diff --git a/adb/pairing_connection/include/adb/pairing/pairing_connection.h b/adb/pairing_connection/include/adb/pairing/pairing_connection.h
deleted file mode 100644
index 3543b87..0000000
--- a/adb/pairing_connection/include/adb/pairing/pairing_connection.h
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <stddef.h>
-#include <stdint.h>
-#include <sys/cdefs.h>
-
-#if !defined(__INTRODUCED_IN)
-#define __INTRODUCED_IN(__api_level) /* nothing */
-#endif
-
-// These APIs are for the Adb pairing protocol. This protocol requires both
-// sides to possess a shared secret to authenticate each other. The connection
-// is over TLS, and requires that both the client and server have a valid
-// certificate.
-//
-// This protocol is one-to-one, i.e., one PairingConnectionCtx server instance
-// interacts with only one PairingConnectionCtx client instance. In other words,
-// every new client instance must be bound to a new server instance.
-//
-// If both sides have authenticated, they will exchange their peer information
-// (see #PeerInfo).
-__BEGIN_DECLS
-#if !defined(__ANDROID__) || __ANDROID_API__ >= 30
-
-const uint32_t kMaxPeerInfoSize = 8192;
-struct PeerInfo {
-    uint8_t type;
-    uint8_t data[kMaxPeerInfoSize - 1];
-} __attribute__((packed));
-typedef struct PeerInfo PeerInfo;
-static_assert(sizeof(PeerInfo) == kMaxPeerInfoSize, "PeerInfo has weird size");
-
-enum PeerInfoType : uint8_t {
-    ADB_RSA_PUB_KEY = 0,
-    ADB_DEVICE_GUID = 1,
-};
-
-struct PairingConnectionCtx;
-typedef struct PairingConnectionCtx PairingConnectionCtx;
-typedef void (*pairing_result_cb)(const PeerInfo*, int, void*);
-
-// Starts the pairing connection on a separate thread.
-//
-// Upon completion, if the pairing was successful,
-// |cb| will be called with the peer information and certificate.
-// Otherwise, |cb| will be called with empty data. |fd| should already
-// be opened. PairingConnectionCtx will take ownership of the |fd|.
-//
-// Pairing is successful if both server/client uses the same non-empty
-// |pswd|, and they are able to exchange the information. |pswd| and
-// |certificate| must be non-empty. start() can only be called once in the
-// lifetime of this object.
-//
-// @param ctx the PairingConnectionCtx instance. Will abort if null.
-// @param fd the fd connecting the peers. This will take ownership of fd.
-// @param cb the user-provided callback that is called with the result of the
-//        pairing. The callback will be called on a different thread from the
-//        caller.
-// @param opaque opaque userdata.
-// @return true if the thread was successfully started, false otherwise. To stop
-//         the connection process, destroy the instance (see
-//         #pairing_connection_destroy). If false is returned, cb will not be
-//         invoked. Otherwise, cb is guaranteed to be invoked, even if you
-//         destroy the ctx while in the pairing process.
-bool pairing_connection_start(PairingConnectionCtx* ctx, int fd, pairing_result_cb cb, void* opaque)
-        __INTRODUCED_IN(30);
-
-// Creates a new PairingConnectionCtx instance as the client.
-//
-// @param pswd the password to authenticate both peers. Will abort if null.
-// @param pswd_len the length of pswd. Will abort if 0.
-// @param peer_info the PeerInfo struct that is exchanged between peers if the
-//                  pairing was successful. Will abort if null.
-// @param x509_cert_pem the X.509 certificate in PEM format. Will abort if null.
-// @param x509_size the size of x509_cert_pem. Will abort if 0.
-// @param priv_key_pem the private key corresponding to the given X.509
-//                     certificate, in PEM format. Will abort if null.
-// @param priv_size the size of priv_key_pem. Will abort if 0.
-// @return a new PairingConnectionCtx client instance. The caller is responsible
-//         for destroying the context via #pairing_connection_destroy.
-PairingConnectionCtx* pairing_connection_client_new(const uint8_t* pswd, size_t pswd_len,
-                                                    const PeerInfo* peer_info,
-                                                    const uint8_t* x509_cert_pem, size_t x509_size,
-                                                    const uint8_t* priv_key_pem, size_t priv_size)
-        __INTRODUCED_IN(30);
-
-// Creates a new PairingConnectionCtx instance as the server.
-//
-// @param pswd the password to authenticate both peers. Will abort if null.
-// @param pswd_len the length of pswd. Will abort if 0.
-// @param peer_info the PeerInfo struct that is exchanged between peers if the
-//                  pairing was successful. Will abort if null.
-// @param x509_cert_pem the X.509 certificate in PEM format. Will abort if null.
-// @param x509_size the size of x509_cert_pem. Will abort if 0.
-// @param priv_key_pem the private key corresponding to the given X.509
-//                     certificate, in PEM format. Will abort if null.
-// @param priv_size the size of priv_key_pem. Will abort if 0.
-// @return a new PairingConnectionCtx server instance. The caller is responsible
-//         for destroying the context via #pairing_connection_destroy.
-PairingConnectionCtx* pairing_connection_server_new(const uint8_t* pswd, size_t pswd_len,
-                                                    const PeerInfo* peer_info,
-                                                    const uint8_t* x509_cert_pem, size_t x509_size,
-                                                    const uint8_t* priv_key_pem, size_t priv_size)
-        __INTRODUCED_IN(30);
-
-// Destroys the PairingConnectionCtx instance.
-//
-// It is safe to destroy the instance at any point in the pairing process.
-//
-// @param ctx the PairingConnectionCtx instance to destroy. Will abort if null.
-void pairing_connection_destroy(PairingConnectionCtx* ctx) __INTRODUCED_IN(30);
-
-#endif  //!__ANDROID__ || __ANDROID_API__ >= 30
-__END_DECLS
diff --git a/adb/pairing_connection/include/adb/pairing/pairing_server.h b/adb/pairing_connection/include/adb/pairing/pairing_server.h
deleted file mode 100644
index 178a174..0000000
--- a/adb/pairing_connection/include/adb/pairing/pairing_server.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <stddef.h>
-#include <stdint.h>
-#include <sys/cdefs.h>
-
-#include <functional>
-#include <memory>
-#include <string_view>
-#include <vector>
-
-#include "adb/pairing/pairing_connection.h"
-
-#if !defined(__INTRODUCED_IN)
-#define __INTRODUCED_IN(__api_level) /* nothing */
-#endif
-
-__BEGIN_DECLS
-#if !defined(__ANDROID__) || __ANDROID_API__ >= 30
-
-// PairingServerCtx is a wrapper around the #PairingConnectionCtx APIs,
-// which handles multiple client connections.
-//
-// See pairing_connection_test.cpp for example usage.
-//
-struct PairingServerCtx;
-typedef struct PairingServerCtx PairingServerCtx;
-
-// Callback containing the result of the pairing. If #PeerInfo is null,
-// then the pairing failed. Otherwise, pairing succeeded and #PeerInfo
-// contains information about the peer.
-typedef void (*pairing_server_result_cb)(const PeerInfo*, void*) __INTRODUCED_IN(30);
-
-// Starts the pairing server.
-//
-// This call is non-blocking. Upon completion, if the pairing was successful,
-// then |cb| will be called with the PeerInfo
-// containing the info of the trusted peer. Otherwise, |cb| will be
-// called with an empty value. Start can only be called once in the lifetime
-// of this object.
-//
-// @param ctx the PairingServerCtx instance.
-// @param cb the user-provided callback to notify the result of the pairing. See
-//           #pairing_server_result_cb.
-// @param opaque the opaque userdata.
-// @return the port number the server is listening on. Returns 0 on failure.
-uint16_t pairing_server_start(PairingServerCtx* ctx, pairing_server_result_cb cb, void* opaque)
-        __INTRODUCED_IN(30);
-
-// Creates a new PairingServerCtx instance.
-//
-// @param pswd the password used to authenticate the client and server.
-// @param pswd_len the length of pswd.
-// @param peer_info the #PeerInfo struct passed to the client on successful
-//                  pairing.
-// @param x509_cert_pem the X.509 certificate in PEM format. Cannot be empty.
-// @param x509_size the size of x509_cert_pem.
-// @param priv_key_pem the private key corresponding to the given X.509
-//                     certificate, in PEM format. Cannot be empty.
-// @param priv_size the size of priv_key_pem.
-// @param port the port number the server should listen on. Must be within the
-//             valid port range [0, 65535]. If port is 0, then the server will
-//             find an open port to listen on. See #pairing_server_start to
-//             obtain the port used.
-// @return a new PairingServerCtx instance The caller is responsible
-//         for destroying the context via #pairing_server_destroy.
-PairingServerCtx* pairing_server_new(const uint8_t* pswd, size_t pswd_len,
-                                     const PeerInfo* peer_info, const uint8_t* x509_cert_pem,
-                                     size_t x509_size, const uint8_t* priv_key_pem,
-                                     size_t priv_size, uint16_t port) __INTRODUCED_IN(30);
-
-// Same as #pairing_server_new, except that the x509 certificate and private key
-// is generated internally.
-//
-// @param pswd the password used to authenticate the client and server.
-// @param pswd_len the length of pswd.
-// @param peer_info the #PeerInfo struct passed to the client on successful
-//                  pairing.
-// @param port the port number the server should listen on. Must be within the
-//             valid port range [0, 65535]. If port is 0, then the server will
-//             find an open port to listen on. See #pairing_server_start to
-//             obtain the port used.
-// @return a new PairingServerCtx instance The caller is responsible
-//         for destroying the context via #pairing_server_destroy.
-PairingServerCtx* pairing_server_new_no_cert(const uint8_t* pswd, size_t pswd_len,
-                                             const PeerInfo* peer_info, uint16_t port)
-        __INTRODUCED_IN(30);
-
-// Destroys the PairingServerCtx instance.
-//
-// @param ctx the PairingServerCtx instance to destroy.
-void pairing_server_destroy(PairingServerCtx* ctx) __INTRODUCED_IN(30);
-
-#endif  //!__ANDROID__ || __ANDROID_API__ >= 30
-__END_DECLS
diff --git a/adb/pairing_connection/internal/constants.h b/adb/pairing_connection/internal/constants.h
deleted file mode 100644
index 9a04f17..0000000
--- a/adb/pairing_connection/internal/constants.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-// This file contains constants that can be used both in the pairing_connection
-// code and tested in the pairing_connection_test code.
-namespace adb {
-namespace pairing {
-namespace internal {
-
-// The maximum number of connections the PairingServer can handle at once.
-constexpr int kMaxConnections = 10;
-// The maximum number of attempts the PairingServer will take before quitting.
-// This is to prevent someone malicious from quickly brute-forcing every
-// combination.
-constexpr int kMaxPairingAttempts = 20;
-
-}  // namespace internal
-}  // namespace pairing
-}  // namespace adb
diff --git a/adb/pairing_connection/libadb_pairing_connection.map.txt b/adb/pairing_connection/libadb_pairing_connection.map.txt
deleted file mode 100644
index abd5f16..0000000
--- a/adb/pairing_connection/libadb_pairing_connection.map.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-LIBADB_PAIRING_CONNECTION {
-  global:
-    pairing_connection_client_new; # apex introduced=30
-    pairing_connection_server_new; # apex introduced=30
-    pairing_connection_start; # apex introduced=30
-    pairing_connection_destroy; # apex introduced=30
-
-  local:
-    *;
-};
diff --git a/adb/pairing_connection/libadb_pairing_server.map.txt b/adb/pairing_connection/libadb_pairing_server.map.txt
deleted file mode 100644
index dc0dc89..0000000
--- a/adb/pairing_connection/libadb_pairing_server.map.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-LIBADB_PAIRING_SERVER {
-  global:
-    pairing_server_start; # apex introduced=30
-    pairing_server_new; # apex introduced=30
-    pairing_server_new_no_cert; # apex introduced=30
-    pairing_server_destroy; # apex introduced=30
-
-  local:
-    *;
-};
diff --git a/adb/pairing_connection/pairing_connection.cpp b/adb/pairing_connection/pairing_connection.cpp
deleted file mode 100644
index ffe49a9..0000000
--- a/adb/pairing_connection/pairing_connection.cpp
+++ /dev/null
@@ -1,491 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "adb/pairing/pairing_connection.h"
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <functional>
-#include <memory>
-#include <string_view>
-#include <thread>
-#include <vector>
-
-#include <adb/pairing/pairing_auth.h>
-#include <adb/tls/tls_connection.h>
-#include <android-base/endian.h>
-#include <android-base/logging.h>
-#include <android-base/macros.h>
-#include <android-base/unique_fd.h>
-
-#include "pairing.pb.h"
-
-using namespace adb;
-using android::base::unique_fd;
-using TlsError = tls::TlsConnection::TlsError;
-
-const uint8_t kCurrentKeyHeaderVersion = 1;
-const uint8_t kMinSupportedKeyHeaderVersion = 1;
-const uint8_t kMaxSupportedKeyHeaderVersion = 1;
-const uint32_t kMaxPayloadSize = kMaxPeerInfoSize * 2;
-
-struct PairingPacketHeader {
-    uint8_t version;   // PairingPacket version
-    uint8_t type;      // the type of packet (PairingPacket.Type)
-    uint32_t payload;  // Size of the payload in bytes
-} __attribute__((packed));
-
-struct PairingAuthDeleter {
-    void operator()(PairingAuthCtx* p) { pairing_auth_destroy(p); }
-};  // PairingAuthDeleter
-using PairingAuthPtr = std::unique_ptr<PairingAuthCtx, PairingAuthDeleter>;
-
-// PairingConnectionCtx encapsulates the protocol to authenticate two peers with
-// each other. This class will open the tcp sockets and handle the pairing
-// process. On completion, both sides will have each other's public key
-// (certificate) if successful, otherwise, the pairing failed. The tcp port
-// number is hardcoded (see pairing_connection.cpp).
-//
-// Each PairingConnectionCtx instance represents a different device trying to
-// pair. So for the device, we can have multiple PairingConnectionCtxs while the
-// host may have only one (unless host has a PairingServer).
-//
-// See pairing_connection_test.cpp for example usage.
-//
-struct PairingConnectionCtx {
-  public:
-    using Data = std::vector<uint8_t>;
-    using ResultCallback = pairing_result_cb;
-    enum class Role {
-        Client,
-        Server,
-    };
-
-    explicit PairingConnectionCtx(Role role, const Data& pswd, const PeerInfo& peer_info,
-                                  const Data& certificate, const Data& priv_key);
-    virtual ~PairingConnectionCtx();
-
-    // Starts the pairing connection on a separate thread.
-    // Upon completion, if the pairing was successful,
-    // |cb| will be called with the peer information and certificate.
-    // Otherwise, |cb| will be called with empty data. |fd| should already
-    // be opened. PairingConnectionCtx will take ownership of the |fd|.
-    //
-    // Pairing is successful if both server/client uses the same non-empty
-    // |pswd|, and they are able to exchange the information. |pswd| and
-    // |certificate| must be non-empty. Start() can only be called once in the
-    // lifetime of this object.
-    //
-    // Returns true if the thread was successfully started, false otherwise.
-    bool Start(int fd, ResultCallback cb, void* opaque);
-
-  private:
-    // Setup the tls connection.
-    bool SetupTlsConnection();
-
-    /************ PairingPacketHeader methods ****************/
-    // Tries to write out the header and payload.
-    bool WriteHeader(const PairingPacketHeader* header, std::string_view payload);
-    // Tries to parse incoming data into the |header|. Returns true if header
-    // is valid and header version is supported. |header| is filled on success.
-    // |header| may contain garbage if unsuccessful.
-    bool ReadHeader(PairingPacketHeader* header);
-    // Creates a PairingPacketHeader.
-    void CreateHeader(PairingPacketHeader* header, adb::proto::PairingPacket::Type type,
-                      uint32_t payload_size);
-    // Checks if actual matches expected.
-    bool CheckHeaderType(adb::proto::PairingPacket::Type expected, uint8_t actual);
-
-    /*********** State related methods **************/
-    // Handles the State::ExchangingMsgs state.
-    bool DoExchangeMsgs();
-    // Handles the State::ExchangingPeerInfo state.
-    bool DoExchangePeerInfo();
-
-    // The background task to do the pairing.
-    void StartWorker();
-
-    // Calls |cb_| and sets the state to Stopped.
-    void NotifyResult(const PeerInfo* p);
-
-    static PairingAuthPtr CreatePairingAuthPtr(Role role, const Data& pswd);
-
-    enum class State {
-        Ready,
-        ExchangingMsgs,
-        ExchangingPeerInfo,
-        Stopped,
-    };
-
-    std::atomic<State> state_{State::Ready};
-    Role role_;
-    Data pswd_;
-    PeerInfo peer_info_;
-    Data cert_;
-    Data priv_key_;
-
-    // Peer's info
-    PeerInfo their_info_;
-
-    ResultCallback cb_;
-    void* opaque_ = nullptr;
-    std::unique_ptr<tls::TlsConnection> tls_;
-    PairingAuthPtr auth_;
-    unique_fd fd_;
-    std::thread thread_;
-    static constexpr size_t kExportedKeySize = 64;
-};  // PairingConnectionCtx
-
-PairingConnectionCtx::PairingConnectionCtx(Role role, const Data& pswd, const PeerInfo& peer_info,
-                                           const Data& cert, const Data& priv_key)
-    : role_(role), pswd_(pswd), peer_info_(peer_info), cert_(cert), priv_key_(priv_key) {
-    CHECK(!pswd_.empty() && !cert_.empty() && !priv_key_.empty());
-}
-
-PairingConnectionCtx::~PairingConnectionCtx() {
-    // Force close the fd and wait for the worker thread to finish.
-    fd_.reset();
-    if (thread_.joinable()) {
-        thread_.join();
-    }
-}
-
-bool PairingConnectionCtx::SetupTlsConnection() {
-    tls_ = tls::TlsConnection::Create(
-            role_ == Role::Server ? tls::TlsConnection::Role::Server
-                                  : tls::TlsConnection::Role::Client,
-            std::string_view(reinterpret_cast<const char*>(cert_.data()), cert_.size()),
-            std::string_view(reinterpret_cast<const char*>(priv_key_.data()), priv_key_.size()),
-            fd_);
-
-    if (tls_ == nullptr) {
-        LOG(ERROR) << "Unable to start TlsConnection. Unable to pair fd=" << fd_.get();
-        return false;
-    }
-
-    // Allow any peer certificate
-    tls_->SetCertVerifyCallback([](X509_STORE_CTX*) { return 1; });
-
-    // SSL doesn't seem to behave correctly with fdevents so just do a blocking
-    // read for the pairing data.
-    if (tls_->DoHandshake() != TlsError::Success) {
-        LOG(ERROR) << "Failed to handshake with the peer fd=" << fd_.get();
-        return false;
-    }
-
-    // To ensure the connection is not stolen while we do the PAKE, append the
-    // exported key material from the tls connection to the password.
-    std::vector<uint8_t> exportedKeyMaterial = tls_->ExportKeyingMaterial(kExportedKeySize);
-    if (exportedKeyMaterial.empty()) {
-        LOG(ERROR) << "Failed to export key material";
-        return false;
-    }
-    pswd_.insert(pswd_.end(), std::make_move_iterator(exportedKeyMaterial.begin()),
-                 std::make_move_iterator(exportedKeyMaterial.end()));
-    auth_ = CreatePairingAuthPtr(role_, pswd_);
-
-    return true;
-}
-
-bool PairingConnectionCtx::WriteHeader(const PairingPacketHeader* header,
-                                       std::string_view payload) {
-    PairingPacketHeader network_header = *header;
-    network_header.payload = htonl(network_header.payload);
-    if (!tls_->WriteFully(std::string_view(reinterpret_cast<const char*>(&network_header),
-                                           sizeof(PairingPacketHeader))) ||
-        !tls_->WriteFully(payload)) {
-        LOG(ERROR) << "Failed to write out PairingPacketHeader";
-        state_ = State::Stopped;
-        return false;
-    }
-    return true;
-}
-
-bool PairingConnectionCtx::ReadHeader(PairingPacketHeader* header) {
-    auto data = tls_->ReadFully(sizeof(PairingPacketHeader));
-    if (data.empty()) {
-        return false;
-    }
-
-    uint8_t* p = data.data();
-    // First byte is always PairingPacketHeader version
-    header->version = *p;
-    ++p;
-    if (header->version < kMinSupportedKeyHeaderVersion ||
-        header->version > kMaxSupportedKeyHeaderVersion) {
-        LOG(ERROR) << "PairingPacketHeader version mismatch (us=" << kCurrentKeyHeaderVersion
-                   << " them=" << header->version << ")";
-        return false;
-    }
-    // Next byte is the PairingPacket::Type
-    if (!adb::proto::PairingPacket::Type_IsValid(*p)) {
-        LOG(ERROR) << "Unknown PairingPacket type=" << static_cast<uint32_t>(*p);
-        return false;
-    }
-    header->type = *p;
-    ++p;
-    // Last, the payload size
-    header->payload = ntohl(*(reinterpret_cast<uint32_t*>(p)));
-    if (header->payload == 0 || header->payload > kMaxPayloadSize) {
-        LOG(ERROR) << "header payload not within a safe payload size (size=" << header->payload
-                   << ")";
-        return false;
-    }
-
-    return true;
-}
-
-void PairingConnectionCtx::CreateHeader(PairingPacketHeader* header,
-                                        adb::proto::PairingPacket::Type type,
-                                        uint32_t payload_size) {
-    header->version = kCurrentKeyHeaderVersion;
-    uint8_t type8 = static_cast<uint8_t>(static_cast<int>(type));
-    header->type = type8;
-    header->payload = payload_size;
-}
-
-bool PairingConnectionCtx::CheckHeaderType(adb::proto::PairingPacket::Type expected_type,
-                                           uint8_t actual) {
-    uint8_t expected = *reinterpret_cast<uint8_t*>(&expected_type);
-    if (actual != expected) {
-        LOG(ERROR) << "Unexpected header type (expected=" << static_cast<uint32_t>(expected)
-                   << " actual=" << static_cast<uint32_t>(actual) << ")";
-        return false;
-    }
-    return true;
-}
-
-void PairingConnectionCtx::NotifyResult(const PeerInfo* p) {
-    cb_(p, fd_.get(), opaque_);
-    state_ = State::Stopped;
-}
-
-bool PairingConnectionCtx::Start(int fd, ResultCallback cb, void* opaque) {
-    if (fd < 0) {
-        return false;
-    }
-    fd_.reset(fd);
-
-    State expected = State::Ready;
-    if (!state_.compare_exchange_strong(expected, State::ExchangingMsgs)) {
-        return false;
-    }
-
-    cb_ = cb;
-    opaque_ = opaque;
-
-    thread_ = std::thread([this] { StartWorker(); });
-    return true;
-}
-
-bool PairingConnectionCtx::DoExchangeMsgs() {
-    uint32_t payload = pairing_auth_msg_size(auth_.get());
-    std::vector<uint8_t> msg(payload);
-    pairing_auth_get_spake2_msg(auth_.get(), msg.data());
-
-    PairingPacketHeader header;
-    CreateHeader(&header, adb::proto::PairingPacket::SPAKE2_MSG, payload);
-
-    // Write our SPAKE2 msg
-    if (!WriteHeader(&header,
-                     std::string_view(reinterpret_cast<const char*>(msg.data()), msg.size()))) {
-        LOG(ERROR) << "Failed to write SPAKE2 msg.";
-        return false;
-    }
-
-    // Read the peer's SPAKE2 msg header
-    if (!ReadHeader(&header)) {
-        LOG(ERROR) << "Invalid PairingPacketHeader.";
-        return false;
-    }
-    if (!CheckHeaderType(adb::proto::PairingPacket::SPAKE2_MSG, header.type)) {
-        return false;
-    }
-
-    // Read the SPAKE2 msg payload and initialize the cipher for
-    // encrypting the PeerInfo and certificate.
-    auto their_msg = tls_->ReadFully(header.payload);
-    if (their_msg.empty() ||
-        !pairing_auth_init_cipher(auth_.get(), their_msg.data(), their_msg.size())) {
-        LOG(ERROR) << "Unable to initialize pairing cipher [their_msg.size=" << their_msg.size()
-                   << "]";
-        return false;
-    }
-
-    return true;
-}
-
-bool PairingConnectionCtx::DoExchangePeerInfo() {
-    // Encrypt PeerInfo
-    std::vector<uint8_t> buf;
-    uint8_t* p = reinterpret_cast<uint8_t*>(&peer_info_);
-    buf.assign(p, p + sizeof(peer_info_));
-    std::vector<uint8_t> outbuf(pairing_auth_safe_encrypted_size(auth_.get(), buf.size()));
-    CHECK(!outbuf.empty());
-    size_t outsize;
-    if (!pairing_auth_encrypt(auth_.get(), buf.data(), buf.size(), outbuf.data(), &outsize)) {
-        LOG(ERROR) << "Failed to encrypt peer info";
-        return false;
-    }
-    outbuf.resize(outsize);
-
-    // Write out the packet header
-    PairingPacketHeader out_header;
-    out_header.version = kCurrentKeyHeaderVersion;
-    out_header.type = static_cast<uint8_t>(static_cast<int>(adb::proto::PairingPacket::PEER_INFO));
-    out_header.payload = htonl(outbuf.size());
-    if (!tls_->WriteFully(
-                std::string_view(reinterpret_cast<const char*>(&out_header), sizeof(out_header)))) {
-        LOG(ERROR) << "Unable to write PairingPacketHeader";
-        return false;
-    }
-
-    // Write out the encrypted payload
-    if (!tls_->WriteFully(
-                std::string_view(reinterpret_cast<const char*>(outbuf.data()), outbuf.size()))) {
-        LOG(ERROR) << "Unable to write encrypted peer info";
-        return false;
-    }
-
-    // Read in the peer's packet header
-    PairingPacketHeader header;
-    if (!ReadHeader(&header)) {
-        LOG(ERROR) << "Invalid PairingPacketHeader.";
-        return false;
-    }
-
-    if (!CheckHeaderType(adb::proto::PairingPacket::PEER_INFO, header.type)) {
-        return false;
-    }
-
-    // Read in the encrypted peer certificate
-    buf = tls_->ReadFully(header.payload);
-    if (buf.empty()) {
-        return false;
-    }
-
-    // Try to decrypt the certificate
-    outbuf.resize(pairing_auth_safe_decrypted_size(auth_.get(), buf.data(), buf.size()));
-    if (outbuf.empty()) {
-        LOG(ERROR) << "Unsupported payload while decrypting peer info.";
-        return false;
-    }
-
-    if (!pairing_auth_decrypt(auth_.get(), buf.data(), buf.size(), outbuf.data(), &outsize)) {
-        LOG(ERROR) << "Failed to decrypt";
-        return false;
-    }
-    outbuf.resize(outsize);
-
-    // The decrypted message should contain the PeerInfo.
-    if (outbuf.size() != sizeof(PeerInfo)) {
-        LOG(ERROR) << "Got size=" << outbuf.size() << "PeerInfo.size=" << sizeof(PeerInfo);
-        return false;
-    }
-
-    p = outbuf.data();
-    ::memcpy(&their_info_, p, sizeof(PeerInfo));
-    p += sizeof(PeerInfo);
-
-    return true;
-}
-
-void PairingConnectionCtx::StartWorker() {
-    // Setup the secure transport
-    if (!SetupTlsConnection()) {
-        NotifyResult(nullptr);
-        return;
-    }
-
-    for (;;) {
-        switch (state_) {
-            case State::ExchangingMsgs:
-                if (!DoExchangeMsgs()) {
-                    NotifyResult(nullptr);
-                    return;
-                }
-                state_ = State::ExchangingPeerInfo;
-                break;
-            case State::ExchangingPeerInfo:
-                if (!DoExchangePeerInfo()) {
-                    NotifyResult(nullptr);
-                    return;
-                }
-                NotifyResult(&their_info_);
-                return;
-            case State::Ready:
-            case State::Stopped:
-                LOG(FATAL) << __func__ << ": Got invalid state";
-                return;
-        }
-    }
-}
-
-// static
-PairingAuthPtr PairingConnectionCtx::CreatePairingAuthPtr(Role role, const Data& pswd) {
-    switch (role) {
-        case Role::Client:
-            return PairingAuthPtr(pairing_auth_client_new(pswd.data(), pswd.size()));
-            break;
-        case Role::Server:
-            return PairingAuthPtr(pairing_auth_server_new(pswd.data(), pswd.size()));
-            break;
-    }
-}
-
-static PairingConnectionCtx* CreateConnection(PairingConnectionCtx::Role role, const uint8_t* pswd,
-                                              size_t pswd_len, const PeerInfo* peer_info,
-                                              const uint8_t* x509_cert_pem, size_t x509_size,
-                                              const uint8_t* priv_key_pem, size_t priv_size) {
-    CHECK(pswd);
-    CHECK_GT(pswd_len, 0U);
-    CHECK(x509_cert_pem);
-    CHECK_GT(x509_size, 0U);
-    CHECK(priv_key_pem);
-    CHECK_GT(priv_size, 0U);
-    CHECK(peer_info);
-    std::vector<uint8_t> vec_pswd(pswd, pswd + pswd_len);
-    std::vector<uint8_t> vec_x509_cert(x509_cert_pem, x509_cert_pem + x509_size);
-    std::vector<uint8_t> vec_priv_key(priv_key_pem, priv_key_pem + priv_size);
-    return new PairingConnectionCtx(role, vec_pswd, *peer_info, vec_x509_cert, vec_priv_key);
-}
-
-PairingConnectionCtx* pairing_connection_client_new(const uint8_t* pswd, size_t pswd_len,
-                                                    const PeerInfo* peer_info,
-                                                    const uint8_t* x509_cert_pem, size_t x509_size,
-                                                    const uint8_t* priv_key_pem, size_t priv_size) {
-    return CreateConnection(PairingConnectionCtx::Role::Client, pswd, pswd_len, peer_info,
-                            x509_cert_pem, x509_size, priv_key_pem, priv_size);
-}
-
-PairingConnectionCtx* pairing_connection_server_new(const uint8_t* pswd, size_t pswd_len,
-                                                    const PeerInfo* peer_info,
-                                                    const uint8_t* x509_cert_pem, size_t x509_size,
-                                                    const uint8_t* priv_key_pem, size_t priv_size) {
-    return CreateConnection(PairingConnectionCtx::Role::Server, pswd, pswd_len, peer_info,
-                            x509_cert_pem, x509_size, priv_key_pem, priv_size);
-}
-
-void pairing_connection_destroy(PairingConnectionCtx* ctx) {
-    CHECK(ctx);
-    delete ctx;
-}
-
-bool pairing_connection_start(PairingConnectionCtx* ctx, int fd, pairing_result_cb cb,
-                              void* opaque) {
-    return ctx->Start(fd, cb, opaque);
-}
diff --git a/adb/pairing_connection/pairing_server.cpp b/adb/pairing_connection/pairing_server.cpp
deleted file mode 100644
index 7218eac..0000000
--- a/adb/pairing_connection/pairing_server.cpp
+++ /dev/null
@@ -1,466 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "adb/pairing/pairing_server.h"
-
-#include <sys/epoll.h>
-#include <sys/eventfd.h>
-
-#include <atomic>
-#include <deque>
-#include <iomanip>
-#include <mutex>
-#include <sstream>
-#include <thread>
-#include <tuple>
-#include <unordered_map>
-#include <variant>
-#include <vector>
-
-#include <adb/crypto/rsa_2048_key.h>
-#include <adb/crypto/x509_generator.h>
-#include <adb/pairing/pairing_connection.h>
-#include <android-base/logging.h>
-#include <android-base/parsenetaddress.h>
-#include <android-base/thread_annotations.h>
-#include <android-base/unique_fd.h>
-#include <cutils/sockets.h>
-
-#include "internal/constants.h"
-
-using android::base::ScopedLockAssertion;
-using android::base::unique_fd;
-using namespace adb::crypto;
-using namespace adb::pairing;
-
-// The implementation has two background threads running: one to handle and
-// accept any new pairing connection requests (socket accept), and the other to
-// handle connection events (connection started, connection finished).
-struct PairingServerCtx {
-  public:
-    using Data = std::vector<uint8_t>;
-
-    virtual ~PairingServerCtx();
-
-    // All parameters must be non-empty.
-    explicit PairingServerCtx(const Data& pswd, const PeerInfo& peer_info, const Data& cert,
-                              const Data& priv_key, uint16_t port);
-
-    // Starts the pairing server. This call is non-blocking. Upon completion,
-    // if the pairing was successful, then |cb| will be called with the PublicKeyHeader
-    // containing the info of the trusted peer. Otherwise, |cb| will be
-    // called with an empty value. Start can only be called once in the lifetime
-    // of this object.
-    //
-    // Returns the port number if PairingServerCtx was successfully started. Otherwise,
-    // returns 0.
-    uint16_t Start(pairing_server_result_cb cb, void* opaque);
-
-  private:
-    // Setup the server socket to accept incoming connections. Returns the
-    // server port number (> 0 on success).
-    uint16_t SetupServer();
-    // Force stop the server thread.
-    void StopServer();
-
-    // handles a new pairing client connection
-    bool HandleNewClientConnection(int fd) EXCLUDES(conn_mutex_);
-
-    // ======== connection events thread =============
-    std::mutex conn_mutex_;
-    std::condition_variable conn_cv_;
-
-    using FdVal = int;
-    struct ConnectionDeleter {
-        void operator()(PairingConnectionCtx* p) { pairing_connection_destroy(p); }
-    };
-    using ConnectionPtr = std::unique_ptr<PairingConnectionCtx, ConnectionDeleter>;
-    static ConnectionPtr CreatePairingConnection(const Data& pswd, const PeerInfo& peer_info,
-                                                 const Data& cert, const Data& priv_key);
-    using NewConnectionEvent = std::tuple<unique_fd, ConnectionPtr>;
-    // <fd, PeerInfo.type, PeerInfo.data>
-    using ConnectionFinishedEvent = std::tuple<FdVal, uint8_t, std::optional<std::string>>;
-    using ConnectionEvent = std::variant<NewConnectionEvent, ConnectionFinishedEvent>;
-    // Queue for connections to write into. We have a separate queue to read
-    // from, in order to minimize the time the server thread is blocked.
-    std::deque<ConnectionEvent> conn_write_queue_ GUARDED_BY(conn_mutex_);
-    std::deque<ConnectionEvent> conn_read_queue_;
-    // Map of fds to their PairingConnections currently running.
-    std::unordered_map<FdVal, ConnectionPtr> connections_;
-
-    // Two threads launched when starting the pairing server:
-    // 1) A server thread that waits for incoming client connections, and
-    // 2) A connection events thread that synchonizes events from all of the
-    //    clients, since each PairingConnection is running in it's own thread.
-    void StartConnectionEventsThread();
-    void StartServerThread();
-
-    static void PairingConnectionCallback(const PeerInfo* peer_info, int fd, void* opaque);
-
-    std::thread conn_events_thread_;
-    void ConnectionEventsWorker();
-    std::thread server_thread_;
-    void ServerWorker();
-    bool is_terminate_ GUARDED_BY(conn_mutex_) = false;
-
-    enum class State {
-        Ready,
-        Running,
-        Stopped,
-    };
-    State state_ = State::Ready;
-    Data pswd_;
-    PeerInfo peer_info_;
-    Data cert_;
-    Data priv_key_;
-    uint16_t port_;
-
-    pairing_server_result_cb cb_;
-    void* opaque_ = nullptr;
-    bool got_valid_pairing_ = false;
-
-    static const int kEpollConstSocket = 0;
-    // Used to break the server thread from epoll_wait
-    static const int kEpollConstEventFd = 1;
-    unique_fd epoll_fd_;
-    unique_fd server_fd_;
-    unique_fd event_fd_;
-};  // PairingServerCtx
-
-// static
-PairingServerCtx::ConnectionPtr PairingServerCtx::CreatePairingConnection(const Data& pswd,
-                                                                          const PeerInfo& peer_info,
-                                                                          const Data& cert,
-                                                                          const Data& priv_key) {
-    return ConnectionPtr(pairing_connection_server_new(pswd.data(), pswd.size(), &peer_info,
-                                                       cert.data(), cert.size(), priv_key.data(),
-                                                       priv_key.size()));
-}
-
-PairingServerCtx::PairingServerCtx(const Data& pswd, const PeerInfo& peer_info, const Data& cert,
-                                   const Data& priv_key, uint16_t port)
-    : pswd_(pswd), peer_info_(peer_info), cert_(cert), priv_key_(priv_key), port_(port) {
-    CHECK(!pswd_.empty() && !cert_.empty() && !priv_key_.empty());
-}
-
-PairingServerCtx::~PairingServerCtx() {
-    // Since these connections have references to us, let's make sure they
-    // destruct before us.
-    if (server_thread_.joinable()) {
-        StopServer();
-        server_thread_.join();
-    }
-
-    {
-        std::lock_guard<std::mutex> lock(conn_mutex_);
-        is_terminate_ = true;
-    }
-    conn_cv_.notify_one();
-    if (conn_events_thread_.joinable()) {
-        conn_events_thread_.join();
-    }
-
-    // Notify the cb_ if it hasn't already.
-    if (!got_valid_pairing_ && cb_ != nullptr) {
-        cb_(nullptr, opaque_);
-    }
-}
-
-uint16_t PairingServerCtx::Start(pairing_server_result_cb cb, void* opaque) {
-    cb_ = cb;
-    opaque_ = opaque;
-
-    if (state_ != State::Ready) {
-        LOG(ERROR) << "PairingServerCtx already running or stopped";
-        return 0;
-    }
-
-    port_ = SetupServer();
-    if (port_ == 0) {
-        LOG(ERROR) << "Unable to start PairingServer";
-        state_ = State::Stopped;
-        return 0;
-    }
-    LOG(INFO) << "Pairing server started on port " << port_;
-
-    state_ = State::Running;
-    return port_;
-}
-
-void PairingServerCtx::StopServer() {
-    if (event_fd_.get() == -1) {
-        return;
-    }
-    uint64_t value = 1;
-    ssize_t rc = write(event_fd_.get(), &value, sizeof(value));
-    if (rc == -1) {
-        // This can happen if the server didn't start.
-        PLOG(ERROR) << "write to eventfd failed";
-    } else if (rc != sizeof(value)) {
-        LOG(FATAL) << "write to event returned short (" << rc << ")";
-    }
-}
-
-uint16_t PairingServerCtx::SetupServer() {
-    epoll_fd_.reset(epoll_create1(EPOLL_CLOEXEC));
-    if (epoll_fd_ == -1) {
-        PLOG(ERROR) << "failed to create epoll fd";
-        return 0;
-    }
-
-    event_fd_.reset(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
-    if (event_fd_ == -1) {
-        PLOG(ERROR) << "failed to create eventfd";
-        return 0;
-    }
-
-    server_fd_.reset(socket_inaddr_any_server(port_, SOCK_STREAM));
-    if (server_fd_.get() == -1) {
-        PLOG(ERROR) << "Failed to start pairing connection server";
-        return 0;
-    } else if (fcntl(server_fd_.get(), F_SETFD, FD_CLOEXEC) != 0) {
-        PLOG(ERROR) << "Failed to make server socket cloexec";
-        return 0;
-    } else if (fcntl(server_fd_.get(), F_SETFD, O_NONBLOCK) != 0) {
-        PLOG(ERROR) << "Failed to make server socket nonblocking";
-        return 0;
-    }
-
-    StartConnectionEventsThread();
-    StartServerThread();
-    int port = socket_get_local_port(server_fd_.get());
-    return (port <= 0 ? 0 : port);
-}
-
-void PairingServerCtx::StartServerThread() {
-    server_thread_ = std::thread([this]() { ServerWorker(); });
-}
-
-void PairingServerCtx::StartConnectionEventsThread() {
-    conn_events_thread_ = std::thread([this]() { ConnectionEventsWorker(); });
-}
-
-void PairingServerCtx::ServerWorker() {
-    {
-        struct epoll_event event;
-        event.events = EPOLLIN;
-        event.data.u64 = kEpollConstSocket;
-        CHECK_EQ(0, epoll_ctl(epoll_fd_.get(), EPOLL_CTL_ADD, server_fd_.get(), &event));
-    }
-
-    {
-        struct epoll_event event;
-        event.events = EPOLLIN;
-        event.data.u64 = kEpollConstEventFd;
-        CHECK_EQ(0, epoll_ctl(epoll_fd_.get(), EPOLL_CTL_ADD, event_fd_.get(), &event));
-    }
-
-    while (true) {
-        struct epoll_event events[2];
-        int rc = TEMP_FAILURE_RETRY(epoll_wait(epoll_fd_.get(), events, 2, -1));
-        if (rc == -1) {
-            PLOG(ERROR) << "epoll_wait failed";
-            return;
-        } else if (rc == 0) {
-            LOG(ERROR) << "epoll_wait returned 0";
-            return;
-        }
-
-        for (int i = 0; i < rc; ++i) {
-            struct epoll_event& event = events[i];
-            switch (event.data.u64) {
-                case kEpollConstSocket:
-                    HandleNewClientConnection(server_fd_.get());
-                    break;
-                case kEpollConstEventFd:
-                    uint64_t dummy;
-                    int rc = TEMP_FAILURE_RETRY(read(event_fd_.get(), &dummy, sizeof(dummy)));
-                    if (rc != sizeof(dummy)) {
-                        PLOG(FATAL) << "failed to read from eventfd (rc=" << rc << ")";
-                    }
-                    return;
-            }
-        }
-    }
-}
-
-// static
-void PairingServerCtx::PairingConnectionCallback(const PeerInfo* peer_info, int fd, void* opaque) {
-    auto* p = reinterpret_cast<PairingServerCtx*>(opaque);
-
-    ConnectionFinishedEvent event;
-    if (peer_info != nullptr) {
-        if (peer_info->type == ADB_RSA_PUB_KEY) {
-            event = std::make_tuple(fd, peer_info->type,
-                                    std::string(reinterpret_cast<const char*>(peer_info->data)));
-        } else {
-            LOG(WARNING) << "Ignoring successful pairing because of unknown "
-                         << "PeerInfo type=" << peer_info->type;
-        }
-    } else {
-        event = std::make_tuple(fd, 0, std::nullopt);
-    }
-    {
-        std::lock_guard<std::mutex> lock(p->conn_mutex_);
-        p->conn_write_queue_.push_back(std::move(event));
-    }
-    p->conn_cv_.notify_one();
-}
-
-void PairingServerCtx::ConnectionEventsWorker() {
-    uint8_t num_tries = 0;
-    for (;;) {
-        // Transfer the write queue to the read queue.
-        {
-            std::unique_lock<std::mutex> lock(conn_mutex_);
-            ScopedLockAssertion assume_locked(conn_mutex_);
-
-            if (is_terminate_) {
-                // We check |is_terminate_| twice because condition_variable's
-                // notify() only wakes up a thread if it is in the wait state
-                // prior to notify(). Furthermore, we aren't holding the mutex
-                // when processing the events in |conn_read_queue_|.
-                return;
-            }
-            if (conn_write_queue_.empty()) {
-                // We need to wait for new events, or the termination signal.
-                conn_cv_.wait(lock, [this]() REQUIRES(conn_mutex_) {
-                    return (is_terminate_ || !conn_write_queue_.empty());
-                });
-            }
-            if (is_terminate_) {
-                // We're done.
-                return;
-            }
-            // Move all events into the read queue.
-            conn_read_queue_ = std::move(conn_write_queue_);
-            conn_write_queue_.clear();
-        }
-
-        // Process all events in the read queue.
-        while (conn_read_queue_.size() > 0) {
-            auto& event = conn_read_queue_.front();
-            if (auto* p = std::get_if<NewConnectionEvent>(&event)) {
-                // Ignore if we are already at the max number of connections
-                if (connections_.size() >= internal::kMaxConnections) {
-                    conn_read_queue_.pop_front();
-                    continue;
-                }
-                auto [ufd, connection] = std::move(*p);
-                int fd = ufd.release();
-                bool started = pairing_connection_start(connection.get(), fd,
-                                                        PairingConnectionCallback, this);
-                if (!started) {
-                    LOG(ERROR) << "PairingServer unable to start a PairingConnection fd=" << fd;
-                    ufd.reset(fd);
-                } else {
-                    connections_[fd] = std::move(connection);
-                }
-            } else if (auto* p = std::get_if<ConnectionFinishedEvent>(&event)) {
-                auto [fd, info_type, public_key] = std::move(*p);
-                if (public_key.has_value() && !public_key->empty()) {
-                    // Valid pairing. Let's shutdown the server and close any
-                    // pairing connections in progress.
-                    StopServer();
-                    connections_.clear();
-
-                    PeerInfo info = {};
-                    info.type = info_type;
-                    strncpy(reinterpret_cast<char*>(info.data), public_key->data(),
-                            public_key->size());
-
-                    cb_(&info, opaque_);
-
-                    got_valid_pairing_ = true;
-                    return;
-                }
-                // Invalid pairing. Close the invalid connection.
-                if (connections_.find(fd) != connections_.end()) {
-                    connections_.erase(fd);
-                }
-
-                if (++num_tries >= internal::kMaxPairingAttempts) {
-                    cb_(nullptr, opaque_);
-                    // To prevent the destructor from calling it again.
-                    cb_ = nullptr;
-                    return;
-                }
-            }
-            conn_read_queue_.pop_front();
-        }
-    }
-}
-
-bool PairingServerCtx::HandleNewClientConnection(int fd) {
-    unique_fd ufd(TEMP_FAILURE_RETRY(accept4(fd, nullptr, nullptr, SOCK_CLOEXEC)));
-    if (ufd == -1) {
-        PLOG(WARNING) << "adb_socket_accept failed fd=" << fd;
-        return false;
-    }
-    auto connection = CreatePairingConnection(pswd_, peer_info_, cert_, priv_key_);
-    if (connection == nullptr) {
-        LOG(ERROR) << "PairingServer unable to create a PairingConnection fd=" << fd;
-        return false;
-    }
-    // send the new connection to the connection thread for further processing
-    NewConnectionEvent event = std::make_tuple(std::move(ufd), std::move(connection));
-    {
-        std::lock_guard<std::mutex> lock(conn_mutex_);
-        conn_write_queue_.push_back(std::move(event));
-    }
-    conn_cv_.notify_one();
-
-    return true;
-}
-
-uint16_t pairing_server_start(PairingServerCtx* ctx, pairing_server_result_cb cb, void* opaque) {
-    return ctx->Start(cb, opaque);
-}
-
-PairingServerCtx* pairing_server_new(const uint8_t* pswd, size_t pswd_len,
-                                     const PeerInfo* peer_info, const uint8_t* x509_cert_pem,
-                                     size_t x509_size, const uint8_t* priv_key_pem,
-                                     size_t priv_size, uint16_t port) {
-    CHECK(pswd);
-    CHECK_GT(pswd_len, 0U);
-    CHECK(x509_cert_pem);
-    CHECK_GT(x509_size, 0U);
-    CHECK(priv_key_pem);
-    CHECK_GT(priv_size, 0U);
-    CHECK(peer_info);
-    std::vector<uint8_t> vec_pswd(pswd, pswd + pswd_len);
-    std::vector<uint8_t> vec_x509_cert(x509_cert_pem, x509_cert_pem + x509_size);
-    std::vector<uint8_t> vec_priv_key(priv_key_pem, priv_key_pem + priv_size);
-    return new PairingServerCtx(vec_pswd, *peer_info, vec_x509_cert, vec_priv_key, port);
-}
-
-PairingServerCtx* pairing_server_new_no_cert(const uint8_t* pswd, size_t pswd_len,
-                                             const PeerInfo* peer_info, uint16_t port) {
-    auto rsa_2048 = CreateRSA2048Key();
-    auto x509_cert = GenerateX509Certificate(rsa_2048->GetEvpPkey());
-    std::string pkey_pem = Key::ToPEMString(rsa_2048->GetEvpPkey());
-    std::string cert_pem = X509ToPEMString(x509_cert.get());
-
-    return pairing_server_new(pswd, pswd_len, peer_info,
-                              reinterpret_cast<const uint8_t*>(cert_pem.data()), cert_pem.size(),
-                              reinterpret_cast<const uint8_t*>(pkey_pem.data()), pkey_pem.size(),
-                              port);
-}
-
-void pairing_server_destroy(PairingServerCtx* ctx) {
-    CHECK(ctx);
-    delete ctx;
-}
diff --git a/adb/pairing_connection/tests/Android.bp b/adb/pairing_connection/tests/Android.bp
deleted file mode 100644
index bf075bc..0000000
--- a/adb/pairing_connection/tests/Android.bp
+++ /dev/null
@@ -1,47 +0,0 @@
-//
-// Copyright (C) 2020 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-cc_test {
-    name: "adb_pairing_connection_test",
-    srcs: [
-        "pairing_client.cpp",
-        "pairing_connection_test.cpp",
-    ],
-
-    compile_multilib: "first",
-
-    shared_libs: [
-        "libbase",
-        "libcutils",
-        "libcrypto",
-        "libcrypto_utils",
-        "libprotobuf-cpp-lite",
-        "libssl",
-    ],
-
-    // Let's statically link them so we don't have to install it onto the
-    // system image for testing.
-    static_libs: [
-        "libadb_pairing_auth_static",
-        "libadb_pairing_connection_static",
-        "libadb_pairing_server_static",
-        "libadb_crypto_static",
-        "libadb_protos_static",
-        "libadb_tls_connection_static",
-    ],
-
-    test_suites: ["device-tests"],
-}
diff --git a/adb/pairing_connection/tests/pairing_client.cpp b/adb/pairing_connection/tests/pairing_client.cpp
deleted file mode 100644
index 1f3ef5a..0000000
--- a/adb/pairing_connection/tests/pairing_client.cpp
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "pairing_client.h"
-
-#include <netdb.h>
-#include <netinet/tcp.h>
-
-#include <atomic>
-#include <iomanip>
-#include <mutex>
-#include <sstream>
-#include <thread>
-#include <vector>
-
-#include <android-base/logging.h>
-#include <android-base/parsenetaddress.h>
-#include <android-base/stringprintf.h>
-#include <android-base/thread_annotations.h>
-#include <android-base/unique_fd.h>
-#include <cutils/sockets.h>
-
-namespace adb {
-namespace pairing {
-
-using android::base::unique_fd;
-
-static void ConnectionDeleter(PairingConnectionCtx* p) {
-    pairing_connection_destroy(p);
-}
-using ConnectionPtr = std::unique_ptr<PairingConnectionCtx, decltype(&ConnectionDeleter)>;
-
-namespace {
-
-class PairingClientImpl : public PairingClient {
-  public:
-    explicit PairingClientImpl(const Data& pswd, const PeerInfo& peer_info, const Data& cert,
-                               const Data& priv_key);
-
-    // Starts the pairing client. This call is non-blocking. Upon pairing
-    // completion, |cb| will be called with the PeerInfo on success,
-    // or an empty value on failure.
-    //
-    // Returns true if PairingClient was successfully started. Otherwise,
-    // return false.
-    virtual bool Start(std::string_view ip_addr, pairing_client_result_cb cb,
-                       void* opaque) override;
-
-  private:
-    static ConnectionPtr CreatePairingConnection(const Data& pswd, const PeerInfo& peer_info,
-                                                 const Data& cert, const Data& priv_key);
-
-    static void PairingResultCallback(const PeerInfo* peer_info, int fd, void* opaque);
-    // Setup and start the PairingConnection
-    bool StartConnection();
-
-    enum class State {
-        Ready,
-        Running,
-        Stopped,
-    };
-
-    State state_ = State::Ready;
-    Data pswd_;
-    PeerInfo peer_info_;
-    Data cert_;
-    Data priv_key_;
-    std::string host_;
-    int port_;
-
-    ConnectionPtr connection_;
-    pairing_client_result_cb cb_;
-    void* opaque_ = nullptr;
-};  // PairingClientImpl
-
-// static
-ConnectionPtr PairingClientImpl::CreatePairingConnection(const Data& pswd,
-                                                         const PeerInfo& peer_info,
-                                                         const Data& cert, const Data& priv_key) {
-    return ConnectionPtr(
-            pairing_connection_client_new(pswd.data(), pswd.size(), &peer_info, cert.data(),
-                                          cert.size(), priv_key.data(), priv_key.size()),
-            ConnectionDeleter);
-}
-
-PairingClientImpl::PairingClientImpl(const Data& pswd, const PeerInfo& peer_info, const Data& cert,
-                                     const Data& priv_key)
-    : pswd_(pswd),
-      peer_info_(peer_info),
-      cert_(cert),
-      priv_key_(priv_key),
-      connection_(nullptr, ConnectionDeleter) {
-    CHECK(!pswd_.empty() && !cert_.empty() && !priv_key_.empty());
-
-    state_ = State::Ready;
-}
-
-bool PairingClientImpl::Start(std::string_view ip_addr, pairing_client_result_cb cb, void* opaque) {
-    CHECK(!ip_addr.empty());
-    cb_ = cb;
-    opaque_ = opaque;
-
-    if (state_ != State::Ready) {
-        LOG(ERROR) << "PairingClient already running or finished";
-        return false;
-    }
-
-    // Try to parse the host address
-    std::string err;
-    CHECK(android::base::ParseNetAddress(std::string(ip_addr), &host_, &port_, nullptr, &err));
-    CHECK(port_ > 0 && port_ <= 65535);
-
-    if (!StartConnection()) {
-        LOG(ERROR) << "Unable to start PairingClient connection";
-        state_ = State::Stopped;
-        return false;
-    }
-
-    state_ = State::Running;
-    return true;
-}
-
-static int network_connect(const std::string& host, int port, int type, int timeout,
-                           std::string* error) {
-    int getaddrinfo_error = 0;
-    int fd = socket_network_client_timeout(host.c_str(), port, type, timeout, &getaddrinfo_error);
-    if (fd != -1) {
-        return fd;
-    }
-    if (getaddrinfo_error != 0) {
-        *error = android::base::StringPrintf("failed to resolve host: '%s': %s", host.c_str(),
-                                             gai_strerror(getaddrinfo_error));
-        LOG(WARNING) << *error;
-    } else {
-        *error = android::base::StringPrintf("failed to connect to '%s:%d': %s", host.c_str(), port,
-                                             strerror(errno));
-        LOG(WARNING) << *error;
-    }
-    return -1;
-}
-
-// static
-void PairingClientImpl::PairingResultCallback(const PeerInfo* peer_info, int /* fd */,
-                                              void* opaque) {
-    auto* p = reinterpret_cast<PairingClientImpl*>(opaque);
-    p->cb_(peer_info, p->opaque_);
-}
-
-bool PairingClientImpl::StartConnection() {
-    std::string err;
-    const int timeout = 10;  // seconds
-    unique_fd fd(network_connect(host_, port_, SOCK_STREAM, timeout, &err));
-    if (fd.get() == -1) {
-        LOG(ERROR) << "Failed to start pairing connection client [" << err << "]";
-        return false;
-    }
-    int off = 1;
-    setsockopt(fd.get(), IPPROTO_TCP, TCP_NODELAY, &off, sizeof(off));
-
-    connection_ = CreatePairingConnection(pswd_, peer_info_, cert_, priv_key_);
-    if (connection_ == nullptr) {
-        LOG(ERROR) << "PairingClient unable to create a PairingConnection";
-        return false;
-    }
-
-    if (!pairing_connection_start(connection_.get(), fd.release(), PairingResultCallback, this)) {
-        LOG(ERROR) << "PairingClient failed to start the PairingConnection";
-        state_ = State::Stopped;
-        return false;
-    }
-
-    return true;
-}
-
-}  // namespace
-
-// static
-std::unique_ptr<PairingClient> PairingClient::Create(const Data& pswd, const PeerInfo& peer_info,
-                                                     const Data& cert, const Data& priv_key) {
-    CHECK(!pswd.empty());
-    CHECK(!cert.empty());
-    CHECK(!priv_key.empty());
-
-    return std::unique_ptr<PairingClient>(new PairingClientImpl(pswd, peer_info, cert, priv_key));
-}
-
-}  // namespace pairing
-}  // namespace adb
diff --git a/adb/pairing_connection/tests/pairing_client.h b/adb/pairing_connection/tests/pairing_client.h
deleted file mode 100644
index be0db5c..0000000
--- a/adb/pairing_connection/tests/pairing_client.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <functional>
-#include <memory>
-#include <string_view>
-#include <vector>
-
-#include "adb/pairing/pairing_connection.h"
-
-typedef void (*pairing_client_result_cb)(const PeerInfo*, void*);
-
-namespace adb {
-namespace pairing {
-
-// PairingClient is the client side of the PairingConnection protocol. It will
-// attempt to connect to a PairingServer specified at |host| and |port|, and
-// allocate a new PairingConnection for processing.
-//
-// See pairing_connection_test.cpp for example usage.
-//
-class PairingClient {
-  public:
-    using Data = std::vector<uint8_t>;
-
-    virtual ~PairingClient() = default;
-
-    // Starts the pairing client. This call is non-blocking. Upon completion,
-    // if the pairing was successful, then |cb| will be called with the PeerInfo
-    // containing the info of the trusted peer. Otherwise, |cb| will be
-    // called with an empty value. Start can only be called once in the lifetime
-    // of this object. |ip_addr| requires a port to be specified.
-    //
-    // Returns true if PairingClient was successfully started. Otherwise,
-    // returns false.
-    virtual bool Start(std::string_view ip_addr, pairing_client_result_cb cb, void* opaque) = 0;
-
-    // Creates a new PairingClient instance. May return null if unable
-    // to create an instance. |pswd|, |certificate|, |priv_key| and
-    // |ip_addr| cannot be empty. |peer_info| must contain non-empty strings for
-    // the guid and name fields.
-    static std::unique_ptr<PairingClient> Create(const Data& pswd, const PeerInfo& peer_info,
-                                                 const Data& certificate, const Data& priv_key);
-
-  protected:
-    PairingClient() = default;
-};  // class PairingClient
-
-}  // namespace pairing
-}  // namespace adb
diff --git a/adb/pairing_connection/tests/pairing_connection_test.cpp b/adb/pairing_connection/tests/pairing_connection_test.cpp
deleted file mode 100644
index b6e09f1..0000000
--- a/adb/pairing_connection/tests/pairing_connection_test.cpp
+++ /dev/null
@@ -1,500 +0,0 @@
-/*
- * Copyright 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "AdbPairingConnectionTest"
-
-#include <chrono>
-#include <condition_variable>
-#include <mutex>
-#include <thread>
-
-#include <adb/pairing/pairing_server.h>
-#include <android-base/logging.h>
-#include <android-base/strings.h>
-#include <gtest/gtest.h>
-
-#include "../internal/constants.h"
-#include "pairing_client.h"
-
-using namespace std::chrono_literals;
-
-namespace adb {
-namespace pairing {
-
-// Test X.509 certificates (RSA 2048)
-static const std::string kTestRsa2048ServerCert =
-        "-----BEGIN CERTIFICATE-----\n"
-        "MIIDFzCCAf+gAwIBAgIBATANBgkqhkiG9w0BAQsFADAtMQswCQYDVQQGEwJVUzEQ\n"
-        "MA4GA1UECgwHQW5kcm9pZDEMMAoGA1UEAwwDQWRiMB4XDTIwMDEyMTIyMjU1NVoX\n"
-        "DTMwMDExODIyMjU1NVowLTELMAkGA1UEBhMCVVMxEDAOBgNVBAoMB0FuZHJvaWQx\n"
-        "DDAKBgNVBAMMA0FkYjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK8E\n"
-        "2Ck9TfuKlz7wqWdMfknjZ1luFDp2IHxAUZzh/F6jeI2dOFGAjpeloSnGOE86FIaT\n"
-        "d1EvpyTh7nBwbrLZAA6XFZTo7Bl6BdNOQdqb2d2+cLEN0inFxqUIycevRtohUE1Y\n"
-        "FHM9fg442X1jOTWXjDZWeiqFWo95paAPhzm6pWqfJK1+YKfT1LsWZpYqJGGQE5pi\n"
-        "C3qOBYYgFpoXMxTYJNoZo3uOYEdM6upc8/vh15nMgIxX/ymJxEY5BHPpZPPWjXLg\n"
-        "BfzVaV9fUfv0JT4HQ4t2WvxC3cD/UsjWp2a6p454uUp2ENrANa+jRdRJepepg9D2\n"
-        "DKsx9L8zjc5Obqexrt0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8B\n"
-        "Af8EBAMCAYYwHQYDVR0OBBYEFDFW+8GTErwoZN5Uu9KyY4QdGYKpMA0GCSqGSIb3\n"
-        "DQEBCwUAA4IBAQBCDEn6SHXGlq5TU7J8cg1kRPd9bsJW+0hDuKSq0REXDkl0PcBf\n"
-        "fy282Agg9enKPPKmnpeQjM1dmnxdM8tT8LIUbMl779i3fn6v9HJVB+yG4gmRFThW\n"
-        "c+AGlBnrIT820cX/gU3h3R3FTahfsq+1rrSJkEgHyuC0HYeRyveSckBdaEOLvx0S\n"
-        "toun+32JJl5hWydpUUZhE9Mbb3KHBRM2YYZZU9JeJ08Apjl+3lRUeMAUwI5fkAAu\n"
-        "z/1SqnuGL96bd8P5ixdkA1+rF8FPhodGcq9mQOuUGP9g5HOXjaNoJYvwVRUdLeGh\n"
-        "cP/ReOTwQIzM1K5a83p8cX8AGGYmM7dQp7ec\n"
-        "-----END CERTIFICATE-----\n";
-
-static const std::string kTestRsa2048ServerPrivKey =
-        "-----BEGIN PRIVATE KEY-----\n"
-        "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCvBNgpPU37ipc+\n"
-        "8KlnTH5J42dZbhQ6diB8QFGc4fxeo3iNnThRgI6XpaEpxjhPOhSGk3dRL6ck4e5w\n"
-        "cG6y2QAOlxWU6OwZegXTTkHam9ndvnCxDdIpxcalCMnHr0baIVBNWBRzPX4OONl9\n"
-        "Yzk1l4w2VnoqhVqPeaWgD4c5uqVqnyStfmCn09S7FmaWKiRhkBOaYgt6jgWGIBaa\n"
-        "FzMU2CTaGaN7jmBHTOrqXPP74deZzICMV/8picRGOQRz6WTz1o1y4AX81WlfX1H7\n"
-        "9CU+B0OLdlr8Qt3A/1LI1qdmuqeOeLlKdhDawDWvo0XUSXqXqYPQ9gyrMfS/M43O\n"
-        "Tm6nsa7dAgMBAAECggEAFCS2bPdUKIgjbzLgtHW+hT+J2hD20rcHdyAp+dNH/2vI\n"
-        "yLfDJHJA4chGMRondKA704oDw2bSJxxlG9t83326lB35yxPhye7cM8fqgWrK8PVl\n"
-        "tU22FhO1ZgeJvb9OeXWNxKZyDW9oOOJ8eazNXVMuEo+dFj7B6l3MXQyHJPL2mJDm\n"
-        "u9ofFLdypX+gJncVO0oW0FNJnEUn2MMwHDNlo7gc4WdQuidPkuZItKRGcB8TTGF3\n"
-        "Ka1/2taYdTQ4Aq//Z84LlFvE0zD3T4c8LwYYzOzD4gGGTXvft7vSHzIun1S8YLRS\n"
-        "dEKXdVjtaFhgH3uUe4j+1b/vMvSHeoGBNX/G88GD+wKBgQDWUYVlMVqc9HD2IeYi\n"
-        "EfBcNwAJFJkh51yAl5QbUBgFYgFJVkkS/EDxEGFPvEmI3/pAeQFHFY13BI466EPs\n"
-        "o8Z8UUwWDp+Z1MFHHKQKnFakbsZbZlbqjJ9VJsqpezbpWhMHTOmcG0dmE7rf0lyM\n"
-        "eQv9slBB8qp2NEUs5Of7f2C2bwKBgQDRDq4nUuMQF1hbjM05tGKSIwkobmGsLspv\n"
-        "TMhkM7fq4RpbFHmbNgsFqMhcqYZ8gY6/scv5KCuAZ4yHUkbqwf5h+QCwrJ4uJeUJ\n"
-        "ZgJfHus2mmcNSo8FwSkNoojIQtzcbJav7bs2K9VTuertk/i7IJLApU4FOZZ5pghN\n"
-        "EXu0CZF1cwKBgDWFGhjRIF29tU/h20R60llU6s9Zs3wB+NmsALJpZ/ZAKS4VPB5f\n"
-        "nCAXBRYSYRKrTCU5kpYbzb4BBzuysPOxWmnFK4j+keCqfrGxd02nCQP7HdHJVr8v\n"
-        "6sIq88UrHeVcNxBFprjzHvtgxfQK5k22FMZ/9wbhAKyQFQ5HA5+MiaxFAoGAIcZZ\n"
-        "ZIkDninnYIMS9OursShv5lRO+15j3i9tgKLKZ+wOMgDQ1L6acUOfezj4PU1BHr8+\n"
-        "0PYocQpJreMhCfRlgLaV4fVBaPs+UZJld7CrF5tCYudUy/01ALrtlk0XGZWBktK5\n"
-        "mDrksC4tQkzRtonAq9cJD9cJ9IVaefkFH0UcdvkCgYBpZj50VLeGhnHHBnkJRlV1\n"
-        "fV+/P6PAq6RtqjA6O9Qdaoj5V3w2d63aQcQXQLJjH2BBmtCIy47r04rFvZpbCxP7\n"
-        "NH/OnK9NHpk2ucRTe8TAnVbvF/TZzPJoIxAO/D3OWaW6df4R8en8u6GYzWFglAyT\n"
-        "sydGT8yfWD1FYUWgfrVRbg==\n"
-        "-----END PRIVATE KEY-----\n";
-
-static const std::string kTestRsa2048ClientCert =
-        "-----BEGIN CERTIFICATE-----\n"
-        "MIIDFzCCAf+gAwIBAgIBATANBgkqhkiG9w0BAQsFADAtMQswCQYDVQQGEwJVUzEQ\n"
-        "MA4GA1UECgwHQW5kcm9pZDEMMAoGA1UEAwwDQWRiMB4XDTIwMDEyMTIyMjU1NloX\n"
-        "DTMwMDExODIyMjU1NlowLTELMAkGA1UEBhMCVVMxEDAOBgNVBAoMB0FuZHJvaWQx\n"
-        "DDAKBgNVBAMMA0FkYjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAI3a\n"
-        "EXh1S5FTbet7JVONswffRPaekdIK53cb8SnAbSO9X5OLA4zGwdkrBvDTsd96SKrp\n"
-        "JxmoNOE1DhbZh05KPlWAPkGKacjGWaz+S7biDOL0I6aaLbTlU/il1Ub9olPSBVUx\n"
-        "0nhdtEFgIOzddnP6/1KmyIIeRxS5lTKeg4avqUkZNXkz/wL1dHBFL7FNFf0SCcbo\n"
-        "tsub/deFbjZ27LTDN+SIBgFttTNqC5NTvoBAoMdyCOAgNYwaHO+fKiK3edfJieaw\n"
-        "7HD8qqmQxcpCtRlA8CUPj7GfR+WHiCJmlevhnkFXCo56R1BS0F4wuD4KPdSWt8gc\n"
-        "27ejH/9/z2cKo/6SLJMCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8B\n"
-        "Af8EBAMCAYYwHQYDVR0OBBYEFO/Mr5ygqqpyU/EHM9v7RDvcqaOkMA0GCSqGSIb3\n"
-        "DQEBCwUAA4IBAQAH33KMouzF2DYbjg90KDrDQr4rq3WfNb6P743knxdUFuvb+40U\n"
-        "QjC2OJZHkSexH7wfG/y6ic7vfCfF4clNs3QvU1lEjOZC57St8Fk7mdNdsWLwxEMD\n"
-        "uePFz0dvclSxNUHyCVMqNxddzQYzxiDWQRmXWrUBliMduQqEQelcxW2yDtg8bj+s\n"
-        "aMpR1ra9scaD4jzIZIIxLoOS9zBMuNRbgP217sZrniyGMhzoI1pZ/izN4oXpyH7O\n"
-        "THuaCzzRT3ph2f8EgmHSodz3ttgSf2DHzi/Ez1xUkk7NOlgNtmsxEdrM47+cC5ae\n"
-        "fIf2V+1o1JW8J7D11RmRbNPh3vfisueB4f88\n"
-        "-----END CERTIFICATE-----\n";
-
-static const std::string kTestRsa2048ClientPrivKey =
-        "-----BEGIN PRIVATE KEY-----\n"
-        "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCN2hF4dUuRU23r\n"
-        "eyVTjbMH30T2npHSCud3G/EpwG0jvV+TiwOMxsHZKwbw07Hfekiq6ScZqDThNQ4W\n"
-        "2YdOSj5VgD5BimnIxlms/ku24gzi9COmmi205VP4pdVG/aJT0gVVMdJ4XbRBYCDs\n"
-        "3XZz+v9SpsiCHkcUuZUynoOGr6lJGTV5M/8C9XRwRS+xTRX9EgnG6LbLm/3XhW42\n"
-        "duy0wzfkiAYBbbUzaguTU76AQKDHcgjgIDWMGhzvnyoit3nXyYnmsOxw/KqpkMXK\n"
-        "QrUZQPAlD4+xn0flh4giZpXr4Z5BVwqOekdQUtBeMLg+Cj3UlrfIHNu3ox//f89n\n"
-        "CqP+kiyTAgMBAAECggEAAa64eP6ggCob1P3c73oayYPIbvRqiQdAFOrr7Vwu7zbr\n"
-        "z0rde+n6RU0mrpc+4NuzyPMtrOGQiatLbidJB5Cx3z8U00ovqbCl7PtcgorOhFKe\n"
-        "VEzihebCcYyQqbWQcKtpDMhOgBxRwFoXieJb6VGXfa96FAZalCWvXgOrTl7/BF2X\n"
-        "qMqIm9nJi+yS5tIO8VdOsOmrMWRH/b/ENUcef4WpLoxTXr0EEgyKWraeZ/hhXo1e\n"
-        "z29dZKqdr9wMsq11NPsRddwS94jnDkXTo+EQyWVTfB7gb6yyp07s8jysaDb21tVv\n"
-        "UXB9MRhDV1mOv0ncXfXZ4/+4A2UahmZaLDAVLaat4QKBgQDAVRredhGRGl2Nkic3\n"
-        "KvZCAfyxug788CgasBdEiouz19iCCwcgMIDwnq0s3/WM7h/laCamT2x38riYDnpq\n"
-        "rkYMfuVtU9CjEL9pTrdfwbIRhTwYNqADaPz2mXwQUhRXutE5TIdgxxC/a+ZTh0qN\n"
-        "S+vhTj/4hf0IZhMh5Nqj7IPExQKBgQC8zxEzhmSGjys0GuE6Wl6Doo2TpiR6vwvi\n"
-        "xPLU9lmIz5eca/Rd/eERioFQqeoIWDLzx52DXuz6rUoQhbJWz9hP3yqCwXD+pbNP\n"
-        "oDJqDDbCC4IMYEb0IK/PEPH+gIpnTjoFcW+ecKDFG7W5Lt05J8WsJsfOaJvMrOU+\n"
-        "dLXq3IgxdwKBgQC5RAFq0v6e8G+3hFaEHL0z3igkpt3zJf7rnj37hx2FMmDa+3Z0\n"
-        "umQp5B9af61PgL12xLmeMBmC/Wp1BlVDV/Yf6Uhk5Hyv5t0KuomHEtTNbbLyfAPs\n"
-        "5P/vJu/L5NS1oT4S3LX3MineyjgGs+bLbpub3z1dzutrYLADUSiPCK/xJQKBgBQt\n"
-        "nQ0Ao+Wtj1R2OvPdjJRM3wyUiPmFSWPm4HzaBx+T8AQLlYYmB9O0FbXlMtnJc0iS\n"
-        "YMcVcgYoVu4FG9YjSF7g3s4yljzgwJUV7c1fmMqMKE3iTDLy+1cJ3JLycdgwiArk\n"
-        "4KTyLHxkRbuQwpvFIF8RlfD9RQlOwQE3v+llwDhpAoGBAL6XG6Rp6mBoD2Ds5c9R\n"
-        "943yYgSUes3ji1SI9zFqeJtj8Ml/enuK1xu+8E/BxB0//+vgZsH6i3i8GFwygKey\n"
-        "CGJF8CbiHc3EJc3NQIIRXcni/CGacf0HwC6m+PGFDBIpA4H2iDpVvCSofxttQiq0\n"
-        "/Z7HXmXUvZHVyYi/QzX2Gahj\n"
-        "-----END PRIVATE KEY-----\n";
-
-struct ServerDeleter {
-    void operator()(PairingServerCtx* p) { pairing_server_destroy(p); }
-};
-using ServerPtr = std::unique_ptr<PairingServerCtx, ServerDeleter>;
-
-struct ResultWaiter {
-    std::mutex mutex_;
-    std::condition_variable cv_;
-    std::optional<bool> is_valid_;
-    PeerInfo peer_info_;
-
-    static void ResultCallback(const PeerInfo* peer_info, void* opaque) {
-        auto* p = reinterpret_cast<ResultWaiter*>(opaque);
-        {
-            std::unique_lock<std::mutex> lock(p->mutex_);
-            if (peer_info) {
-                memcpy(&(p->peer_info_), peer_info, sizeof(PeerInfo));
-            }
-            p->is_valid_ = (peer_info != nullptr);
-        }
-        p->cv_.notify_one();
-    }
-};
-
-class AdbPairingConnectionTest : public testing::Test {
-  protected:
-    virtual void SetUp() override {}
-
-    virtual void TearDown() override {}
-
-    void InitPairing(const std::vector<uint8_t>& server_pswd,
-                     const std::vector<uint8_t>& client_pswd) {
-        server_ = CreateServer(server_pswd);
-        client_ = CreateClient(client_pswd);
-    }
-
-    ServerPtr CreateServer(const std::vector<uint8_t>& pswd) {
-        return CreateServer(pswd, &server_info_, kTestRsa2048ServerCert, kTestRsa2048ServerPrivKey,
-                            0);
-    }
-
-    std::unique_ptr<PairingClient> CreateClient(const std::vector<uint8_t> pswd) {
-        std::vector<uint8_t> cert;
-        std::vector<uint8_t> key;
-        // Include the null-byte as well.
-        cert.assign(reinterpret_cast<const uint8_t*>(kTestRsa2048ClientCert.data()),
-                    reinterpret_cast<const uint8_t*>(kTestRsa2048ClientCert.data()) +
-                            kTestRsa2048ClientCert.size() + 1);
-        key.assign(reinterpret_cast<const uint8_t*>(kTestRsa2048ClientPrivKey.data()),
-                   reinterpret_cast<const uint8_t*>(kTestRsa2048ClientPrivKey.data()) +
-                           kTestRsa2048ClientPrivKey.size() + 1);
-        return PairingClient::Create(pswd, client_info_, cert, key);
-    }
-
-    static ServerPtr CreateServer(const std::vector<uint8_t>& pswd, const PeerInfo* peer_info,
-                                  const std::string_view cert, const std::string_view priv_key,
-                                  int port) {
-        return ServerPtr(pairing_server_new(
-                pswd.data(), pswd.size(), peer_info, reinterpret_cast<const uint8_t*>(cert.data()),
-                cert.size(), reinterpret_cast<const uint8_t*>(priv_key.data()), priv_key.size(),
-                port));
-    }
-
-    ServerPtr server_;
-    const PeerInfo server_info_ = {
-            .type = ADB_DEVICE_GUID,
-            .data = "my_server_info",
-    };
-    std::unique_ptr<PairingClient> client_;
-    const PeerInfo client_info_ = {
-            .type = ADB_RSA_PUB_KEY,
-            .data = "my_client_info",
-    };
-    std::string ip_addr_ = "127.0.0.1:";
-};
-
-TEST_F(AdbPairingConnectionTest, ServerCreation) {
-    // All parameters bad
-    ASSERT_DEATH({ auto server = CreateServer({}, nullptr, "", "", 0); }, "");
-    // Bad password
-    ASSERT_DEATH(
-            {
-                auto server = CreateServer({}, &server_info_, kTestRsa2048ServerCert,
-                                           kTestRsa2048ServerPrivKey, 0);
-            },
-            "");
-    // Bad peer_info
-    ASSERT_DEATH(
-            {
-                auto server = CreateServer({0x01}, nullptr, kTestRsa2048ServerCert,
-                                           kTestRsa2048ServerPrivKey, 0);
-            },
-            "");
-    // Bad certificate
-    ASSERT_DEATH(
-            {
-                auto server = CreateServer({0x01}, &server_info_, "", kTestRsa2048ServerPrivKey, 0);
-            },
-            "");
-    // Bad private key
-    ASSERT_DEATH(
-            { auto server = CreateServer({0x01}, &server_info_, kTestRsa2048ServerCert, "", 0); },
-            "");
-    // Valid params
-    auto server = CreateServer({0x01}, &server_info_, kTestRsa2048ServerCert,
-                               kTestRsa2048ServerPrivKey, 0);
-    EXPECT_NE(nullptr, server);
-}
-
-TEST_F(AdbPairingConnectionTest, ClientCreation) {
-    std::vector<uint8_t> pswd{0x01, 0x03, 0x05, 0x07};
-    // Bad password
-    ASSERT_DEATH(
-            {
-                pairing_connection_client_new(
-                        nullptr, pswd.size(), &client_info_,
-                        reinterpret_cast<const uint8_t*>(kTestRsa2048ClientCert.data()),
-                        kTestRsa2048ClientCert.size(),
-                        reinterpret_cast<const uint8_t*>(kTestRsa2048ClientPrivKey.data()),
-                        kTestRsa2048ClientPrivKey.size());
-            },
-            "");
-    ASSERT_DEATH(
-            {
-                pairing_connection_client_new(
-                        pswd.data(), 0, &client_info_,
-                        reinterpret_cast<const uint8_t*>(kTestRsa2048ClientCert.data()),
-                        kTestRsa2048ClientCert.size(),
-                        reinterpret_cast<const uint8_t*>(kTestRsa2048ClientPrivKey.data()),
-                        kTestRsa2048ClientPrivKey.size());
-            },
-            "");
-
-    // Bad peer_info
-    ASSERT_DEATH(
-            {
-                pairing_connection_client_new(
-                        pswd.data(), pswd.size(), nullptr,
-                        reinterpret_cast<const uint8_t*>(kTestRsa2048ClientCert.data()),
-                        kTestRsa2048ClientCert.size(),
-                        reinterpret_cast<const uint8_t*>(kTestRsa2048ClientPrivKey.data()),
-                        kTestRsa2048ClientPrivKey.size());
-            },
-            "");
-
-    // Bad certificate
-    ASSERT_DEATH(
-            {
-                pairing_connection_client_new(
-                        pswd.data(), pswd.size(), &client_info_, nullptr,
-                        kTestRsa2048ClientCert.size(),
-                        reinterpret_cast<const uint8_t*>(kTestRsa2048ClientPrivKey.data()),
-                        kTestRsa2048ClientPrivKey.size());
-            },
-            "");
-    ASSERT_DEATH(
-            {
-                pairing_connection_client_new(
-                        pswd.data(), pswd.size(), &client_info_,
-                        reinterpret_cast<const uint8_t*>(kTestRsa2048ClientCert.data()), 0,
-                        reinterpret_cast<const uint8_t*>(kTestRsa2048ClientPrivKey.data()),
-                        kTestRsa2048ClientPrivKey.size());
-            },
-            "");
-
-    // Bad private key
-    ASSERT_DEATH(
-            {
-                pairing_connection_client_new(
-                        pswd.data(), pswd.size(), &client_info_,
-                        reinterpret_cast<const uint8_t*>(kTestRsa2048ClientCert.data()),
-                        kTestRsa2048ClientCert.size(), nullptr, kTestRsa2048ClientPrivKey.size());
-            },
-            "");
-    ASSERT_DEATH(
-            {
-                pairing_connection_client_new(
-                        pswd.data(), pswd.size(), &client_info_,
-                        reinterpret_cast<const uint8_t*>(kTestRsa2048ClientCert.data()),
-                        kTestRsa2048ClientCert.size(),
-                        reinterpret_cast<const uint8_t*>(kTestRsa2048ClientPrivKey.data()), 0);
-            },
-            "");
-
-    // Valid params
-    auto client = pairing_connection_client_new(
-            pswd.data(), pswd.size(), &client_info_,
-            reinterpret_cast<const uint8_t*>(kTestRsa2048ClientCert.data()),
-            kTestRsa2048ClientCert.size(),
-            reinterpret_cast<const uint8_t*>(kTestRsa2048ClientPrivKey.data()),
-            kTestRsa2048ClientPrivKey.size());
-    EXPECT_NE(nullptr, client);
-}
-
-TEST_F(AdbPairingConnectionTest, SmokeValidPairing) {
-    std::vector<uint8_t> pswd{0x01, 0x03, 0x05, 0x07};
-    InitPairing(pswd, pswd);
-
-    // Start the server
-    ResultWaiter server_waiter;
-    std::unique_lock<std::mutex> server_lock(server_waiter.mutex_);
-    auto port = pairing_server_start(server_.get(), server_waiter.ResultCallback, &server_waiter);
-    ASSERT_GT(port, 0);
-    ip_addr_ += std::to_string(port);
-
-    // Start the client
-    ResultWaiter client_waiter;
-    std::unique_lock<std::mutex> client_lock(client_waiter.mutex_);
-    ASSERT_TRUE(client_->Start(ip_addr_, client_waiter.ResultCallback, &client_waiter));
-    client_waiter.cv_.wait(client_lock, [&]() { return client_waiter.is_valid_.has_value(); });
-    ASSERT_TRUE(*(client_waiter.is_valid_));
-    ASSERT_EQ(strlen(reinterpret_cast<const char*>(client_waiter.peer_info_.data)),
-              strlen(reinterpret_cast<const char*>(server_info_.data)));
-    EXPECT_EQ(memcmp(client_waiter.peer_info_.data, server_info_.data, sizeof(server_info_.data)),
-              0);
-
-    // Kill server if the pairing failed, since server only shuts down when
-    // it gets a valid pairing.
-    if (!client_waiter.is_valid_) {
-        server_lock.unlock();
-        server_.reset();
-    } else {
-        server_waiter.cv_.wait(server_lock, [&]() { return server_waiter.is_valid_.has_value(); });
-        ASSERT_TRUE(*(server_waiter.is_valid_));
-        ASSERT_EQ(strlen(reinterpret_cast<const char*>(server_waiter.peer_info_.data)),
-                  strlen(reinterpret_cast<const char*>(client_info_.data)));
-        EXPECT_EQ(
-                memcmp(server_waiter.peer_info_.data, client_info_.data, sizeof(client_info_.data)),
-                0);
-    }
-}
-
-TEST_F(AdbPairingConnectionTest, CancelPairing) {
-    std::vector<uint8_t> pswd{0x01, 0x03, 0x05, 0x07};
-    std::vector<uint8_t> pswd2{0x01, 0x03, 0x05, 0x06};
-    InitPairing(pswd, pswd2);
-
-    // Start the server
-    ResultWaiter server_waiter;
-    std::unique_lock<std::mutex> server_lock(server_waiter.mutex_);
-    auto port = pairing_server_start(server_.get(), server_waiter.ResultCallback, &server_waiter);
-    ASSERT_GT(port, 0);
-    ip_addr_ += std::to_string(port);
-
-    // Start the client. Client should fail to pair
-    ResultWaiter client_waiter;
-    std::unique_lock<std::mutex> client_lock(client_waiter.mutex_);
-    ASSERT_TRUE(client_->Start(ip_addr_, client_waiter.ResultCallback, &client_waiter));
-    client_waiter.cv_.wait(client_lock, [&]() { return client_waiter.is_valid_.has_value(); });
-    ASSERT_FALSE(*(client_waiter.is_valid_));
-
-    // Kill the server. We should still receive the callback with no valid
-    // pairing.
-    server_lock.unlock();
-    server_.reset();
-    server_lock.lock();
-    ASSERT_TRUE(server_waiter.is_valid_.has_value());
-    EXPECT_FALSE(*(server_waiter.is_valid_));
-}
-
-TEST_F(AdbPairingConnectionTest, MultipleClientsAllFail) {
-    std::vector<uint8_t> pswd{0x01, 0x03, 0x05, 0x07};
-    std::vector<uint8_t> pswd2{0x01, 0x03, 0x05, 0x06};
-
-    // Start the server
-    auto server = CreateServer(pswd);
-    ResultWaiter server_waiter;
-    std::unique_lock<std::mutex> server_lock(server_waiter.mutex_);
-    auto port = pairing_server_start(server.get(), server_waiter.ResultCallback, &server_waiter);
-    ASSERT_GT(port, 0);
-    ip_addr_ += std::to_string(port);
-
-    // Start multiple clients, all with bad passwords
-    int test_num_clients = 5;
-    int num_clients_done = 0;
-    std::mutex global_clients_mutex;
-    std::unique_lock<std::mutex> global_clients_lock(global_clients_mutex);
-    std::condition_variable global_cv_;
-    for (int i = 0; i < test_num_clients; ++i) {
-        std::thread([&]() {
-            auto client = CreateClient(pswd2);
-            ResultWaiter client_waiter;
-            std::unique_lock<std::mutex> client_lock(client_waiter.mutex_);
-            ASSERT_TRUE(client->Start(ip_addr_, client_waiter.ResultCallback, &client_waiter));
-            client_waiter.cv_.wait(client_lock,
-                                   [&]() { return client_waiter.is_valid_.has_value(); });
-            ASSERT_FALSE(*(client_waiter.is_valid_));
-            {
-                std::lock_guard<std::mutex> global_lock(global_clients_mutex);
-                ++num_clients_done;
-            }
-            global_cv_.notify_one();
-        }).detach();
-    }
-
-    global_cv_.wait(global_clients_lock, [&]() { return num_clients_done == test_num_clients; });
-    server_lock.unlock();
-    server.reset();
-    server_lock.lock();
-    ASSERT_TRUE(server_waiter.is_valid_.has_value());
-    EXPECT_FALSE(*(server_waiter.is_valid_));
-}
-
-TEST_F(AdbPairingConnectionTest, MultipleClientsOnePass) {
-    // Send multiple clients with bad passwords, but send the last one with the
-    // correct password.
-    std::vector<uint8_t> pswd{0x01, 0x03, 0x05, 0x07};
-    std::vector<uint8_t> pswd2{0x01, 0x03, 0x05, 0x06};
-
-    // Start the server
-    auto server = CreateServer(pswd);
-    ResultWaiter server_waiter;
-    std::unique_lock<std::mutex> server_lock(server_waiter.mutex_);
-    auto port = pairing_server_start(server.get(), server_waiter.ResultCallback, &server_waiter);
-    ASSERT_GT(port, 0);
-    ip_addr_ += std::to_string(port);
-
-    // Start multiple clients, all with bad passwords
-    int test_num_clients = 5;
-    int num_clients_done = 0;
-    std::mutex global_clients_mutex;
-    std::unique_lock<std::mutex> global_clients_lock(global_clients_mutex);
-    std::condition_variable global_cv_;
-    for (int i = 0; i < test_num_clients; ++i) {
-        std::thread([&, i]() {
-            bool good_client = (i == (test_num_clients - 1));
-            auto client = CreateClient((good_client ? pswd : pswd2));
-            ResultWaiter client_waiter;
-            std::unique_lock<std::mutex> client_lock(client_waiter.mutex_);
-            ASSERT_TRUE(client->Start(ip_addr_, client_waiter.ResultCallback, &client_waiter));
-            client_waiter.cv_.wait(client_lock,
-                                   [&]() { return client_waiter.is_valid_.has_value(); });
-            if (good_client) {
-                ASSERT_TRUE(*(client_waiter.is_valid_));
-                ASSERT_EQ(strlen(reinterpret_cast<const char*>(client_waiter.peer_info_.data)),
-                          strlen(reinterpret_cast<const char*>(server_info_.data)));
-                EXPECT_EQ(memcmp(client_waiter.peer_info_.data, server_info_.data,
-                                 sizeof(server_info_.data)),
-                          0);
-            } else {
-                ASSERT_FALSE(*(client_waiter.is_valid_));
-            }
-            {
-                std::lock_guard<std::mutex> global_lock(global_clients_mutex);
-                ++num_clients_done;
-            }
-            global_cv_.notify_one();
-        }).detach();
-    }
-
-    global_cv_.wait(global_clients_lock, [&]() { return num_clients_done == test_num_clients; });
-    server_waiter.cv_.wait(server_lock, [&]() { return server_waiter.is_valid_.has_value(); });
-    ASSERT_TRUE(*(server_waiter.is_valid_));
-    ASSERT_EQ(strlen(reinterpret_cast<const char*>(server_waiter.peer_info_.data)),
-              strlen(reinterpret_cast<const char*>(client_info_.data)));
-    EXPECT_EQ(memcmp(server_waiter.peer_info_.data, client_info_.data, sizeof(client_info_.data)),
-              0);
-}
-
-}  // namespace pairing
-}  // namespace adb
diff --git a/adb/proto/Android.bp b/adb/proto/Android.bp
deleted file mode 100644
index f7cba95..0000000
--- a/adb/proto/Android.bp
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright (C) 2020 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-cc_defaults {
-    name: "libadb_protos_defaults",
-    cflags: [
-        "-Wall",
-        "-Wextra",
-        "-Wthread-safety",
-        "-Werror",
-    ],
-
-    compile_multilib: "both",
-
-    proto: {
-        export_proto_headers: true,
-        type: "lite",
-    },
-    srcs: [
-        "adb_known_hosts.proto",
-        "key_type.proto",
-        "pairing.proto",
-    ],
-    target: {
-        windows: {
-            compile_multilib: "first",
-            enabled: true,
-        },
-    },
-
-    visibility: [
-        "//system/core/adb:__subpackages__",
-
-        // This needs to be visible to minadbd, even though it's removed via exclude_shared_libs.
-        "//bootable/recovery/minadbd:__subpackages__",
-    ],
-
-    stl: "libc++_static",
-
-    host_supported: true,
-    recovery_available: true,
-}
-
-cc_library {
-    name: "libadb_protos",
-    defaults: ["libadb_protos_defaults"],
-
-    apex_available: [
-        "com.android.adbd",
-        "test_com.android.adbd",
-    ],
-}
-
-// For running atest (b/147158681)
-cc_library_static {
-    name: "libadb_protos_static",
-    defaults: ["libadb_protos_defaults"],
-
-    apex_available: [
-        "//apex_available:platform",
-    ],
-}
diff --git a/adb/proto/adb_known_hosts.proto b/adb/proto/adb_known_hosts.proto
deleted file mode 100644
index 85d1489..0000000
--- a/adb/proto/adb_known_hosts.proto
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto3";
-
-option java_package = "com.android.server.adb.protos";
-option java_outer_classname = "AdbKnownHostsProto";
-
-package adb.proto;
-
-// Each known host
-message HostInfo {
-    string guid = 1;
-}
-
-// Protobuf definition for the adb_known_hosts.
-message AdbKnownHosts {
-    repeated HostInfo host_infos = 1;
-}
diff --git a/adb/proto/jarjar-rules.txt b/adb/proto/jarjar-rules.txt
deleted file mode 100644
index 4e40637..0000000
--- a/adb/proto/jarjar-rules.txt
+++ /dev/null
@@ -1 +0,0 @@
-rule com.google.protobuf.** com.android.framework.protobuf.@1
diff --git a/adb/proto/key_type.proto b/adb/proto/key_type.proto
deleted file mode 100644
index ed451c5..0000000
--- a/adb/proto/key_type.proto
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto3";
-
-option java_package = "com.android.server.adb.protos";
-option java_outer_classname = "KeyTypeProto";
-
-package adb.proto;
-
-enum KeyType {
-    RSA_2048 = 0;
-}
diff --git a/adb/proto/pairing.proto b/adb/proto/pairing.proto
deleted file mode 100644
index b0be20e..0000000
--- a/adb/proto/pairing.proto
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto3";
-
-option java_package = "com.android.server.adb.protos";
-option java_outer_classname = "PairingProto";
-
-package adb.proto;
-
-// The type of packets used in the pairing protocol
-message PairingPacket {
-    enum Type {
-        SPAKE2_MSG = 0;
-        PEER_INFO = 1;
-    }
-}
diff --git a/adb/protocol.txt b/adb/protocol.txt
deleted file mode 100644
index 75700a4..0000000
--- a/adb/protocol.txt
+++ /dev/null
@@ -1,298 +0,0 @@
-
---- a replacement for aproto -------------------------------------------
-
-When it comes down to it, aproto's primary purpose is to forward
-various streams between the host computer and client device (in either
-direction).
-
-This replacement further simplifies the concept, reducing the protocol
-to an extremely straightforward model optimized to accomplish the
-forwarding of these streams and removing additional state or
-complexity.
-
-The host side becomes a simple comms bridge with no "UI", which will 
-be used by either commandline or interactive tools to communicate with 
-a device or emulator that is connected to the bridge.
-
-The protocol is designed to be straightforward and well-defined enough 
-that if it needs to be reimplemented in another environment (Java 
-perhaps), there should not problems ensuring perfect interoperability.
-
-The protocol discards the layering aproto has and should allow the 
-implementation to be much more robust.
-
-
---- protocol overview and basics ---------------------------------------
-
-The transport layer deals in "messages", which consist of a 24 byte
-header followed (optionally) by a payload.  The header consists of 6
-32 bit words which are sent across the wire in little endian format.
-
-struct message {
-    unsigned command;       /* command identifier constant (A_CNXN, ...) */
-    unsigned arg0;          /* first argument                            */
-    unsigned arg1;          /* second argument                           */
-    unsigned data_length;   /* length of payload (0 is allowed)          */
-    unsigned data_crc32;    /* crc32 of data payload                     */
-    unsigned magic;         /* command ^ 0xffffffff                      */
-};
-
-Receipt of an invalid message header, corrupt message payload, or an
-unrecognized command MUST result in the closing of the remote
-connection.  The protocol depends on shared state and any break in the
-message stream will result in state getting out of sync.
-
-The following sections describe the six defined message types in
-detail.  Their format is COMMAND(arg0, arg1, payload) where the payload
-is represented by a quoted string or an empty string if none should be
-sent.
-
-The identifiers "local-id" and "remote-id" are always relative to the
-*sender* of the message, so for a receiver, the meanings are effectively
-reversed.
-
-
-
---- CONNECT(version, maxdata, "system-identity-string") ----------------
-
-Command constant: A_CNXN
-
-The CONNECT message establishes the presence of a remote system.
-The version is used to ensure protocol compatibility and maxdata
-declares the maximum message body size that the remote system
-is willing to accept.
-
-Currently, version=0x01000000 and maxdata=256*1024. Older versions of adb
-hard-coded maxdata=4096, so CONNECT and AUTH packets sent to a device must not
-be larger than that because they're sent before the CONNECT from the device
-that tells the adb server what maxdata the device can support.
-
-Both sides send a CONNECT message when the connection between them is
-established.  Until a CONNECT message is received no other messages may
-be sent. Any messages received before a CONNECT message MUST be ignored.
-
-If a CONNECT message is received with an unknown version or insufficiently
-large maxdata value, the connection with the other side must be closed.
-
-The system identity string should be "<systemtype>:<serialno>:<banner>"
-where systemtype is "bootloader", "device", or "host", serialno is some
-kind of unique ID (or empty), and banner is a human-readable version
-or identifier string.  The banner is used to transmit useful properties.
-
---- STLS(type, version, "") --------------------------------------------
-
-Command constant: A_STLS
-
-The TLS message informs the recipient that the connection will be encrypted
-and will need to perform a TLS handshake. version is the current version of
-the protocol.
-
-
---- AUTH(type, 0, "data") ----------------------------------------------
-
-Command constant: A_AUTH
-
-The AUTH message informs the recipient that authentication is required to
-connect to the sender. If type is TOKEN(1), data is a random token that
-the recipient can sign with a private key. The recipient replies with an
-AUTH packet where type is SIGNATURE(2) and data is the signature. If the
-signature verification succeeds, the sender replies with a CONNECT packet.
-
-If the signature verification fails, the sender replies with a new AUTH
-packet and a new random token, so that the recipient can retry signing
-with a different private key.
-
-Once the recipient has tried all its private keys, it can reply with an
-AUTH packet where type is RSAPUBLICKEY(3) and data is the public key. If
-possible, an on-screen confirmation may be displayed for the user to
-confirm they want to install the public key on the device.
-
-
---- OPEN(local-id, 0, "destination") -----------------------------------
-
-Command constant: A_OPEN
-
-The OPEN message informs the recipient that the sender has a stream
-identified by local-id that it wishes to connect to the named
-destination in the message payload.  The local-id may not be zero.
-
-The OPEN message MUST result in either a READY message indicating that
-the connection has been established (and identifying the other end) or
-a CLOSE message, indicating failure.  An OPEN message also implies
-a READY message sent at the same time.
-
-Common destination naming conventions include:
-
-* "tcp:<host>:<port>" - host may be omitted to indicate localhost
-* "udp:<host>:<port>" - host may be omitted to indicate localhost
-* "local-dgram:<identifier>"
-* "local-stream:<identifier>"
-* "shell" - local shell service
-* "upload" - service for pushing files across (like aproto's /sync)
-* "fs-bridge" - FUSE protocol filesystem bridge
-
-
---- READY(local-id, remote-id, "") -------------------------------------
-
-Command constant: A_OKAY
-
-The READY message informs the recipient that the sender's stream
-identified by local-id is ready for write messages and that it is
-connected to the recipient's stream identified by remote-id.
-
-Neither the local-id nor the remote-id may be zero.
-
-A READY message containing a remote-id which does not map to an open
-stream on the recipient's side is ignored.  The stream may have been
-closed while this message was in-flight.
-
-The local-id is ignored on all but the first READY message (where it
-is used to establish the connection).  Nonetheless, the local-id MUST
-not change on later READY messages sent to the same stream.
-
-
---- WRITE(local-id, remote-id, "data") ---------------------------------
-
-Command constant: A_WRTE
-
-The WRITE message sends data to the recipient's stream identified by
-remote-id.  The payload MUST be <= maxdata in length.
-
-A WRITE message containing a remote-id which does not map to an open
-stream on the recipient's side is ignored.  The stream may have been
-closed while this message was in-flight.
-
-A WRITE message may not be sent until a READY message is received.
-Once a WRITE message is sent, an additional WRITE message may not be
-sent until another READY message has been received.  Recipients of
-a WRITE message that is in violation of this requirement will CLOSE
-the connection.
-
-
---- CLOSE(local-id, remote-id, "") -------------------------------------
-
-Command constant: A_CLSE
-
-The CLOSE message informs recipient that the connection between the
-sender's stream (local-id) and the recipient's stream (remote-id) is
-broken.  The remote-id MUST not be zero, but the local-id MAY be zero
-if this CLOSE indicates a failed OPEN.
-
-A CLOSE message containing a remote-id which does not map to an open
-stream on the recipient's side is ignored.  The stream may have
-already been closed by the recipient while this message was in-flight.
-
-The recipient should not respond to a CLOSE message in any way.  The
-recipient should cancel pending WRITEs or CLOSEs, but this is not a
-requirement, since they will be ignored.
-
-
---- SYNC(online, sequence, "") -----------------------------------------
-
-Command constant: A_SYNC
-
-*** obsolete, no longer used ***
-
-The SYNC message was used by the io pump to make sure that stale
-outbound messages are discarded when the connection to the remote side
-is broken.  It was only used internally to the bridge and never valid
-to send across the wire.
-
-* when the connection to the remote side goes offline, the io pump
-  sends a SYNC(0, 0) and starts discarding all messages
-* when the connection to the remote side is established, the io pump
-  sends a SYNC(1, token) and continues to discard messages
-* when the io pump receives a matching SYNC(1, token), it once again
-  starts accepting messages to forward to the remote side
-
-
---- message command constants ------------------------------------------
-
-#define A_SYNC 0x434e5953
-#define A_CNXN 0x4e584e43
-#define A_AUTH 0x48545541
-#define A_OPEN 0x4e45504f
-#define A_OKAY 0x59414b4f
-#define A_CLSE 0x45534c43
-#define A_WRTE 0x45545257
-#define A_STLS 0x534C5453
-
-
-
---- implementation details ---------------------------------------------
-
-The core of the bridge program will use three threads.  One thread
-will be a select/epoll loop to handle io between various inbound and
-outbound connections and the connection to the remote side.
-
-The remote side connection will be implemented as two threads (one for
-reading, one for writing) and a datagram socketpair to provide the
-channel between the main select/epoll thread and the remote connection
-threadpair.  The reason for this is that for usb connections, the
-kernel interface on linux and osx does not allow you to do meaningful
-nonblocking IO.
-
-The endian swapping for the message headers will happen (as needed) in
-the remote connection threadpair and that the rest of the program will
-always treat message header values as native-endian.
-
-The bridge program will be able to have a number of mini-servers
-compiled in.  They will be published under known names (examples
-"shell", "fs-bridge", etc) and upon receiving an OPEN() to such a
-service, the bridge program will create a stream socketpair and spawn
-a thread or subprocess to handle the io.
-
-
---- simplified / embedded implementation -------------------------------
-
-For limited environments, like the bootloader, it is allowable to
-support a smaller, fixed number of channels using pre-assigned channel
-ID numbers such that only one stream may be connected to a bootloader
-endpoint at any given time.  The protocol remains unchanged, but the
-"embedded" version of it is less dynamic.
-
-The bootloader will support two streams.  A "bootloader:debug" stream,
-which may be opened to get debug messages from the bootloader and a 
-"bootloader:control", stream which will support the set of basic 
-bootloader commands.
-
-Example command stream dialogues:  
-  "flash_kernel,2515049,........\n" "okay\n" 
-  "flash_ramdisk,5038,........\n" "fail,flash write error\n" 
-  "bogus_command......" <CLOSE>
-
-
---- future expansion ---------------------------------------------------
-
-I plan on providing either a message or a special control stream so that
-the client device could ask the host computer to setup inbound socket
-translations on the fly on behalf of the client device.
-
-
-The initial design does handshaking to provide flow control, with a
-message flow that looks like:
-
-  >OPEN <READY >WRITE <READY >WRITE <READY >WRITE <CLOSE
-
-The far side may choose to issue the READY message as soon as it receives
-a WRITE or it may defer the READY until the write to the local stream
-succeeds.  A future version may want to do some level of windowing where
-multiple WRITEs may be sent without requiring individual READY acks.
-
-------------------------------------------------------------------------
-
---- smartsockets -------------------------------------------------------
-
-Port 5037 is used for smart sockets which allow a client on the host
-side to request access to a service in the host adb daemon or in the
-remote (device) daemon.  The service is requested by ascii name,
-preceeded by a 4 digit hex length.  Upon successful connection an
-"OKAY" response is sent, otherwise a "FAIL" message is returned.  Once
-connected the client is talking to that (remote or local) service.
-
-client: <hex4> <service-name>
-server: "OKAY"
-
-client: <hex4> <service-name>
-server: "FAIL" <hex4> <reason>
-
diff --git a/adb/security_log_tags.h b/adb/security_log_tags.h
deleted file mode 100644
index 1d02744..0000000
--- a/adb/security_log_tags.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#ifndef __SECURITY_LOG_TAGS_H
-#define __SECURITY_LOG_TAGS_H
-
-/* TODO: Automatically generate this file from the logtags file when build
- * infrastructure is in place.
- * Defined in frameworks/base/core/java/android/auditing/SecurityLog.logtags
- */
-#define SEC_TAG_ADB_SHELL_INTERACTIVE 210001
-#define SEC_TAG_ADB_SHELL_CMD         210002
-#define SEC_TAG_ADB_RECV_FILE         210003
-#define SEC_TAG_ADB_SEND_FILE         210004
-
-#endif
diff --git a/adb/services.cpp b/adb/services.cpp
deleted file mode 100644
index 853d658..0000000
--- a/adb/services.cpp
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define TRACE_TAG SERVICES
-
-#include "sysdeps.h"
-
-#include <errno.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <cstring>
-#include <thread>
-
-#include <android-base/stringprintf.h>
-#include <android-base/strings.h>
-#include <cutils/sockets.h>
-
-#include "adb.h"
-#include "adb_io.h"
-#include "adb_unique_fd.h"
-#include "adb_utils.h"
-#include "adb_wifi.h"
-#include "services.h"
-#include "socket_spec.h"
-#include "sysdeps.h"
-#include "transport.h"
-
-namespace {
-
-void service_bootstrap_func(std::string service_name, std::function<void(unique_fd)> func,
-                            unique_fd fd) {
-    adb_thread_setname(android::base::StringPrintf("%s svc %d", service_name.c_str(), fd.get()));
-    func(std::move(fd));
-}
-
-}  // namespace
-
-unique_fd create_service_thread(const char* service_name, std::function<void(unique_fd)> func) {
-    int s[2];
-    if (adb_socketpair(s)) {
-        printf("cannot create service socket pair\n");
-        return unique_fd();
-    }
-    D("socketpair: (%d,%d)", s[0], s[1]);
-
-#if !ADB_HOST
-    if (strcmp(service_name, "sync") == 0) {
-        // Set file sync service socket to maximum size
-        int max_buf = LINUX_MAX_SOCKET_SIZE;
-        adb_setsockopt(s[0], SOL_SOCKET, SO_SNDBUF, &max_buf, sizeof(max_buf));
-        adb_setsockopt(s[1], SOL_SOCKET, SO_SNDBUF, &max_buf, sizeof(max_buf));
-    }
-#endif  // !ADB_HOST
-
-    std::thread(service_bootstrap_func, service_name, func, unique_fd(s[1])).detach();
-
-    D("service thread started, %d:%d", s[0], s[1]);
-    return unique_fd(s[0]);
-}
-
-unique_fd service_to_fd(std::string_view name, atransport* transport) {
-    unique_fd ret;
-
-    if (is_socket_spec(name)) {
-        std::string error;
-        if (!socket_spec_connect(&ret, name, nullptr, nullptr, &error)) {
-            LOG(ERROR) << "failed to connect to socket '" << name << "': " << error;
-        }
-    } else {
-#if !ADB_HOST
-        ret = daemon_service_to_fd(name, transport);
-#endif
-    }
-
-    if (ret >= 0) {
-        close_on_exec(ret.get());
-    }
-    return ret;
-}
-
-#if ADB_HOST
-struct state_info {
-    TransportType transport_type;
-    std::string serial;
-    TransportId transport_id;
-    ConnectionState state;
-};
-
-static void wait_for_state(unique_fd fd, state_info* sinfo) {
-    D("wait_for_state %d", sinfo->state);
-
-    while (true) {
-        bool is_ambiguous = false;
-        std::string error = "unknown error";
-        const char* serial = sinfo->serial.length() ? sinfo->serial.c_str() : nullptr;
-        atransport* t = acquire_one_transport(sinfo->transport_type, serial, sinfo->transport_id,
-                                              &is_ambiguous, &error);
-        if (sinfo->state == kCsOffline) {
-            // wait-for-disconnect uses kCsOffline, we don't actually want to wait for 'offline'.
-            if (t == nullptr) {
-                SendOkay(fd);
-                break;
-            }
-        } else if (t != nullptr &&
-                   (sinfo->state == kCsAny || sinfo->state == t->GetConnectionState())) {
-            SendOkay(fd);
-            break;
-        }
-
-        if (!is_ambiguous) {
-            adb_pollfd pfd = {.fd = fd.get(), .events = POLLIN};
-            int rc = adb_poll(&pfd, 1, 100);
-            if (rc < 0) {
-                SendFail(fd, error);
-                break;
-            } else if (rc > 0 && (pfd.revents & POLLHUP) != 0) {
-                // The other end of the socket is closed, probably because the other side was
-                // terminated, bail out.
-                break;
-            }
-
-            // Try again...
-        } else {
-            SendFail(fd, error);
-            break;
-        }
-    }
-
-    D("wait_for_state is done");
-}
-
-void connect_emulator(const std::string& port_spec, std::string* response) {
-    std::vector<std::string> pieces = android::base::Split(port_spec, ",");
-    if (pieces.size() != 2) {
-        *response = android::base::StringPrintf("unable to parse '%s' as <console port>,<adb port>",
-                                                port_spec.c_str());
-        return;
-    }
-
-    int console_port = strtol(pieces[0].c_str(), nullptr, 0);
-    int adb_port = strtol(pieces[1].c_str(), nullptr, 0);
-    if (console_port <= 0 || adb_port <= 0) {
-        *response = android::base::StringPrintf("Invalid port numbers: %s", port_spec.c_str());
-        return;
-    }
-
-    // Check if the emulator is already known.
-    // Note: There's a small but harmless race condition here: An emulator not
-    // present just yet could be registered by another invocation right
-    // after doing this check here. However, local_connect protects
-    // against double-registration too. From here, a better error message
-    // can be produced. In the case of the race condition, the very specific
-    // error message won't be shown, but the data doesn't get corrupted.
-    atransport* known_emulator = find_emulator_transport_by_adb_port(adb_port);
-    if (known_emulator != nullptr) {
-        *response = android::base::StringPrintf("Emulator already registered on port %d", adb_port);
-        return;
-    }
-
-    // Preconditions met, try to connect to the emulator.
-    std::string error;
-    if (!local_connect_arbitrary_ports(console_port, adb_port, &error)) {
-        *response = android::base::StringPrintf("Connected to emulator on ports %d,%d",
-                                                console_port, adb_port);
-    } else {
-        *response = android::base::StringPrintf("Could not connect to emulator on ports %d,%d: %s",
-                                                console_port, adb_port, error.c_str());
-    }
-}
-
-static void connect_service(unique_fd fd, std::string host) {
-    std::string response;
-    if (!strncmp(host.c_str(), "emu:", 4)) {
-        connect_emulator(host.c_str() + 4, &response);
-    } else {
-        connect_device(host, &response);
-    }
-
-    // Send response for emulator and device
-    SendProtocolString(fd.get(), response);
-}
-
-static void pair_service(unique_fd fd, std::string host, std::string password) {
-    std::string response;
-    adb_wifi_pair_device(host, password, response);
-    SendProtocolString(fd.get(), response);
-}
-#endif
-
-#if ADB_HOST
-asocket* host_service_to_socket(std::string_view name, std::string_view serial,
-                                TransportId transport_id) {
-    if (name == "track-devices") {
-        return create_device_tracker(false);
-    } else if (name == "track-devices-l") {
-        return create_device_tracker(true);
-    } else if (android::base::ConsumePrefix(&name, "wait-for-")) {
-        std::shared_ptr<state_info> sinfo = std::make_shared<state_info>();
-        if (sinfo == nullptr) {
-            fprintf(stderr, "couldn't allocate state_info: %s", strerror(errno));
-            return nullptr;
-        }
-
-        sinfo->serial = serial;
-        sinfo->transport_id = transport_id;
-
-        if (android::base::ConsumePrefix(&name, "local")) {
-            sinfo->transport_type = kTransportLocal;
-        } else if (android::base::ConsumePrefix(&name, "usb")) {
-            sinfo->transport_type = kTransportUsb;
-        } else if (android::base::ConsumePrefix(&name, "any")) {
-            sinfo->transport_type = kTransportAny;
-        } else {
-            return nullptr;
-        }
-
-        if (name == "-device") {
-            sinfo->state = kCsDevice;
-        } else if (name == "-recovery") {
-            sinfo->state = kCsRecovery;
-        } else if (name == "-rescue") {
-            sinfo->state = kCsRescue;
-        } else if (name == "-sideload") {
-            sinfo->state = kCsSideload;
-        } else if (name == "-bootloader") {
-            sinfo->state = kCsBootloader;
-        } else if (name == "-any") {
-            sinfo->state = kCsAny;
-        } else if (name == "-disconnect") {
-            sinfo->state = kCsOffline;
-        } else {
-            return nullptr;
-        }
-
-        unique_fd fd = create_service_thread(
-                "wait", [sinfo](unique_fd fd) { wait_for_state(std::move(fd), sinfo.get()); });
-        return create_local_socket(std::move(fd));
-    } else if (android::base::ConsumePrefix(&name, "connect:")) {
-        std::string host(name);
-        unique_fd fd = create_service_thread(
-                "connect", std::bind(connect_service, std::placeholders::_1, host));
-        return create_local_socket(std::move(fd));
-    } else if (android::base::ConsumePrefix(&name, "pair:")) {
-        const char* divider = strchr(name.data(), ':');
-        if (!divider) {
-            return nullptr;
-        }
-        std::string password(name.data(), divider);
-        std::string host(divider + 1);
-        unique_fd fd = create_service_thread(
-                "pair", std::bind(pair_service, std::placeholders::_1, host, password));
-        return create_local_socket(std::move(fd));
-    }
-    return nullptr;
-}
-#endif /* ADB_HOST */
diff --git a/adb/services.h b/adb/services.h
deleted file mode 100644
index 6fc89d7..0000000
--- a/adb/services.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef SERVICES_H_
-#define SERVICES_H_
-
-#include "adb_unique_fd.h"
-
-constexpr char kShellServiceArgRaw[] = "raw";
-constexpr char kShellServiceArgPty[] = "pty";
-constexpr char kShellServiceArgShellProtocol[] = "v2";
-
-// Special flags sent by minadbd. They indicate the end of sideload transfer and the result of
-// installation or wipe.
-constexpr char kMinadbdServicesExitSuccess[] = "DONEDONE";
-constexpr char kMinadbdServicesExitFailure[] = "FAILFAIL";
-
-unique_fd create_service_thread(const char* service_name, std::function<void(unique_fd)> func);
-#endif  // SERVICES_H_
diff --git a/adb/shell_protocol.h b/adb/shell_protocol.h
deleted file mode 100644
index 4aab813..0000000
--- a/adb/shell_protocol.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <stdint.h>
-
-#include <android-base/macros.h>
-
-#include "adb.h"
-#include "adb_unique_fd.h"
-
-// Class to send and receive shell protocol packets.
-//
-// To keep things simple and predictable, reads and writes block until an entire
-// packet is complete.
-//
-// Example: read raw data from |fd| and send it in a packet.
-//   ShellProtocol* p = new ShellProtocol(protocol_fd);
-//   int len = adb_read(stdout_fd, p->data(), p->data_capacity());
-//   packet->WritePacket(ShellProtocol::kIdStdout, len);
-//
-// Example: read a packet and print it to |stdout|.
-//   ShellProtocol* p = new ShellProtocol(protocol_fd);
-//   if (p->ReadPacket() && p->id() == kIdStdout) {
-//       fwrite(p->data(), 1, p->data_length(), stdout);
-//   }
-class ShellProtocol {
-  public:
-    // This is an unscoped enum to make it easier to compare against raw bytes.
-    enum Id : uint8_t {
-        kIdStdin = 0,
-        kIdStdout = 1,
-        kIdStderr = 2,
-        kIdExit = 3,
-
-        // Close subprocess stdin if possible.
-        kIdCloseStdin = 4,
-
-        // Window size change (an ASCII version of struct winsize).
-        kIdWindowSizeChange = 5,
-
-        // Indicates an invalid or unknown packet.
-        kIdInvalid = 255,
-    };
-
-    // ShellPackets will probably be too large to allocate on the stack so they
-    // should be dynamically allocated on the heap instead.
-    //
-    // |fd| is an open file descriptor to be used to send or receive packets.
-    explicit ShellProtocol(borrowed_fd fd);
-    virtual ~ShellProtocol();
-
-    // Returns a pointer to the data buffer.
-    const char* data() const { return buffer_ + kHeaderSize; }
-    char* data() { return buffer_ + kHeaderSize; }
-
-    // Returns the total capacity of the data buffer.
-    size_t data_capacity() const { return buffer_end_ - data(); }
-
-    // Reads a packet from the FD.
-    //
-    // If a packet is too big to fit in the buffer then Read() will split the
-    // packet across multiple calls. For example, reading a 50-byte packet into
-    // a 20-byte buffer would read 20 bytes, 20 bytes, then 10 bytes.
-    //
-    // Returns false if the FD closed or errored.
-    bool Read();
-
-    // Returns the ID of the packet in the buffer.
-    int id() const { return buffer_[0]; }
-
-    // Returns the number of bytes that have been read into the data buffer.
-    size_t data_length() const { return data_length_; }
-
-    // Writes the packet currently in the buffer to the FD.
-    //
-    // Returns false if the FD closed or errored.
-    bool Write(Id id, size_t length);
-
-  private:
-    // Packets support 4-byte lengths.
-    typedef uint32_t length_t;
-
-    enum {
-        // It's OK if MAX_PAYLOAD doesn't match on the sending and receiving
-        // end, reading will split larger packets into multiple smaller ones.
-        kBufferSize = MAX_PAYLOAD,
-
-        // Header is 1 byte ID + 4 bytes length.
-        kHeaderSize = sizeof(Id) + sizeof(length_t)
-    };
-
-    borrowed_fd fd_;
-    char buffer_[kBufferSize];
-    size_t data_length_ = 0, bytes_left_ = 0;
-
-    // We need to be able to modify this value for testing purposes, but it
-    // will stay constant during actual program use.
-    char* buffer_end_ = buffer_ + sizeof(buffer_);
-
-    friend class ShellProtocolTest;
-
-    DISALLOW_COPY_AND_ASSIGN(ShellProtocol);
-};
diff --git a/adb/shell_service_protocol.cpp b/adb/shell_service_protocol.cpp
deleted file mode 100644
index 95afaff..0000000
--- a/adb/shell_service_protocol.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "shell_protocol.h"
-
-#include <string.h>
-
-#include <algorithm>
-
-#include "adb_io.h"
-
-ShellProtocol::ShellProtocol(borrowed_fd fd) : fd_(fd) {
-    buffer_[0] = kIdInvalid;
-}
-
-ShellProtocol::~ShellProtocol() {
-}
-
-bool ShellProtocol::Read() {
-    // Only read a new header if we've finished the last packet.
-    if (!bytes_left_) {
-        if (!ReadFdExactly(fd_, buffer_, kHeaderSize)) {
-            return false;
-        }
-
-        length_t packet_length;
-        memcpy(&packet_length, &buffer_[1], sizeof(packet_length));
-        bytes_left_ = packet_length;
-        data_length_ = 0;
-    }
-
-    size_t read_length = std::min(bytes_left_, data_capacity());
-    if (read_length && !ReadFdExactly(fd_, data(), read_length)) {
-        return false;
-    }
-
-    bytes_left_ -= read_length;
-    data_length_ = read_length;
-
-    return true;
-}
-
-bool ShellProtocol::Write(Id id, size_t length) {
-    buffer_[0] = id;
-    length_t typed_length = length;
-    memcpy(&buffer_[1], &typed_length, sizeof(typed_length));
-
-    return WriteFdExactly(fd_, buffer_, kHeaderSize + length);
-}
diff --git a/adb/shell_service_protocol_test.cpp b/adb/shell_service_protocol_test.cpp
deleted file mode 100644
index a10b5c0..0000000
--- a/adb/shell_service_protocol_test.cpp
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "shell_protocol.h"
-
-#include <gtest/gtest.h>
-
-#include <signal.h>
-#include <string.h>
-
-#include "sysdeps.h"
-
-class ShellProtocolTest : public ::testing::Test {
-  public:
-    static void SetUpTestCase() {
-#if !defined(_WIN32)
-        // This is normally done in main.cpp.
-        saved_sigpipe_handler_ = signal(SIGPIPE, SIG_IGN);
-#endif
-    }
-
-    static void TearDownTestCase() {
-#if !defined(_WIN32)
-        signal(SIGPIPE, saved_sigpipe_handler_);
-#endif
-    }
-
-    // Initializes the socketpair and ShellProtocols needed for testing.
-    void SetUp() {
-        int fds[2];
-        ASSERT_EQ(0, adb_socketpair(fds));
-        read_fd_ = fds[0];
-        write_fd_ = fds[1];
-
-        write_protocol_ = new ShellProtocol(write_fd_);
-        ASSERT_TRUE(write_protocol_ != nullptr);
-
-        read_protocol_ = new ShellProtocol(read_fd_);
-        ASSERT_TRUE(read_protocol_ != nullptr);
-    }
-
-    // Cleans up FDs and ShellProtocols. If an FD is closed manually during a
-    // test, set it to -1 to prevent TearDown() trying to close it again.
-    void TearDown() {
-        for (int fd : {read_fd_, write_fd_}) {
-            if (fd >= 0) {
-                adb_close(fd);
-            }
-        }
-        for (ShellProtocol* protocol : {read_protocol_, write_protocol_}) {
-            if (protocol) {
-                delete protocol;
-            }
-        }
-    }
-
-    // Fakes the buffer size so we can test filling buffers.
-    void SetReadDataCapacity(size_t size) {
-        read_protocol_->buffer_end_ = read_protocol_->data() + size;
-    }
-
-#if !defined(_WIN32)
-    static sig_t saved_sigpipe_handler_;
-#endif
-
-    int read_fd_ = -1, write_fd_ = -1;
-    ShellProtocol *read_protocol_ = nullptr, *write_protocol_ = nullptr;
-};
-
-#if !defined(_WIN32)
-sig_t ShellProtocolTest::saved_sigpipe_handler_ = nullptr;
-#endif
-
-namespace {
-
-// Returns true if the packet contains the given values. `data` can't be null.
-bool PacketEquals(const ShellProtocol* protocol, ShellProtocol::Id id,
-                    const void* data, size_t data_length) {
-    // Note that passing memcmp null is bad, even if data_length is 0.
-    return (protocol->id() == id &&
-            protocol->data_length() == data_length &&
-            !memcmp(data, protocol->data(), data_length));
-}
-
-}  // namespace
-
-// Tests data that can fit in a single packet.
-TEST_F(ShellProtocolTest, FullPacket) {
-    ShellProtocol::Id id = ShellProtocol::kIdStdout;
-    char data[] = "abc 123 \0\r\n";
-
-    memcpy(write_protocol_->data(), data, sizeof(data));
-    ASSERT_TRUE(write_protocol_->Write(id, sizeof(data)));
-
-    ASSERT_TRUE(read_protocol_->Read());
-    ASSERT_TRUE(PacketEquals(read_protocol_, id, data, sizeof(data)));
-}
-
-// Tests data that has to be read multiple times due to smaller read buffer.
-TEST_F(ShellProtocolTest, ReadBufferOverflow) {
-    ShellProtocol::Id id = ShellProtocol::kIdStdin;
-
-    memcpy(write_protocol_->data(), "1234567890", 10);
-    ASSERT_TRUE(write_protocol_->Write(id, 10));
-
-    SetReadDataCapacity(4);
-    ASSERT_TRUE(read_protocol_->Read());
-    ASSERT_TRUE(PacketEquals(read_protocol_, id, "1234", 4));
-    ASSERT_TRUE(read_protocol_->Read());
-    ASSERT_TRUE(PacketEquals(read_protocol_, id, "5678", 4));
-    ASSERT_TRUE(read_protocol_->Read());
-    ASSERT_TRUE(PacketEquals(read_protocol_, id, "90", 2));
-}
-
-// Tests a zero length packet.
-TEST_F(ShellProtocolTest, ZeroLengthPacket) {
-    ShellProtocol::Id id = ShellProtocol::kIdStderr;
-
-    ASSERT_TRUE(write_protocol_->Write(id, 0));
-    ASSERT_TRUE(read_protocol_->Read());
-    char buf[1];
-    ASSERT_TRUE(PacketEquals(read_protocol_, id, buf, 0));
-}
-
-// Tests exit code packets.
-TEST_F(ShellProtocolTest, ExitCodePacket) {
-    write_protocol_->data()[0] = 20;
-    ASSERT_TRUE(write_protocol_->Write(ShellProtocol::kIdExit, 1));
-
-    ASSERT_TRUE(read_protocol_->Read());
-    ASSERT_EQ(ShellProtocol::kIdExit, read_protocol_->id());
-    ASSERT_EQ(20, read_protocol_->data()[0]);
-}
-
-// Tests writing to a closed pipe.
-TEST_F(ShellProtocolTest, WriteToClosedPipeFail) {
-    adb_close(read_fd_);
-    read_fd_ = -1;
-
-    ASSERT_FALSE(write_protocol_->Write(ShellProtocol::kIdStdout, 0));
-}
-
-// Tests writing to a closed FD.
-TEST_F(ShellProtocolTest, WriteToClosedFdFail) {
-    adb_close(write_fd_);
-    write_fd_ = -1;
-
-    ASSERT_FALSE(write_protocol_->Write(ShellProtocol::kIdStdout, 0));
-}
-
-// Tests reading from a closed pipe.
-TEST_F(ShellProtocolTest, ReadFromClosedPipeFail) {
-    adb_close(write_fd_);
-    write_fd_ = -1;
-
-    ASSERT_FALSE(read_protocol_->Read());
-}
-
-// Tests reading from a closed FD.
-TEST_F(ShellProtocolTest, ReadFromClosedFdFail) {
-    adb_close(read_fd_);
-    read_fd_ = -1;
-
-    ASSERT_FALSE(read_protocol_->Read());
-}
-
-// Tests reading from a closed pipe that has a packet waiting. This checks that
-// even if the pipe closes before we can fully read its contents we will still
-// be able to access the last packets.
-TEST_F(ShellProtocolTest, ReadPacketFromClosedPipe) {
-    ShellProtocol::Id id = ShellProtocol::kIdStdout;
-    char data[] = "foo bar";
-
-    memcpy(write_protocol_->data(), data, sizeof(data));
-    ASSERT_TRUE(write_protocol_->Write(id, sizeof(data)));
-    adb_close(write_fd_);
-    write_fd_ = -1;
-
-    // First read should grab the packet.
-    ASSERT_TRUE(read_protocol_->Read());
-    ASSERT_TRUE(PacketEquals(read_protocol_, id, data, sizeof(data)));
-
-    // Second read should fail.
-    ASSERT_FALSE(read_protocol_->Read());
-}
diff --git a/adb/socket.h b/adb/socket.h
deleted file mode 100644
index 4276851..0000000
--- a/adb/socket.h
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef __ADB_SOCKET_H
-#define __ADB_SOCKET_H
-
-#include <stddef.h>
-
-#include <deque>
-#include <memory>
-#include <string>
-
-#include "adb_unique_fd.h"
-#include "fdevent/fdevent.h"
-#include "types.h"
-
-class atransport;
-
-/* An asocket represents one half of a connection between a local and
- * remote entity.  A local asocket is bound to a file descriptor.  A
- * remote asocket is bound to the protocol engine.
- */
-struct asocket {
-    /* the unique identifier for this asocket
-     */
-    unsigned id = 0;
-
-    /* flag: set when the socket's peer has closed
-     * but packets are still queued for delivery
-     */
-    int closing = 0;
-
-    // flag: set when the socket failed to write, so the socket will not wait to
-    // write packets and close directly.
-    bool has_write_error = 0;
-
-    /* flag: quit adbd when both ends close the
-     * local service socket
-     */
-    int exit_on_close = 0;
-
-    // the asocket we are connected to
-    asocket* peer = nullptr;
-
-    /* For local asockets, the fde is used to bind
-     * us to our fd event system.  For remote asockets
-     * these fields are not used.
-     */
-    fdevent* fde = nullptr;
-    int fd = -1;
-
-    // queue of data waiting to be written
-    IOVector packet_queue;
-
-    std::string smart_socket_data;
-
-    /* enqueue is called by our peer when it has data
-     * for us.  It should return 0 if we can accept more
-     * data or 1 if not.  If we return 1, we must call
-     * peer->ready() when we once again are ready to
-     * receive data.
-     */
-    int (*enqueue)(asocket* s, apacket::payload_type data) = nullptr;
-
-    /* ready is called by the peer when it is ready for
-     * us to send data via enqueue again
-     */
-    void (*ready)(asocket* s) = nullptr;
-
-    /* shutdown is called by the peer before it goes away.
-     * the socket should not do any further calls on its peer.
-     * Always followed by a call to close. Optional, i.e. can be NULL.
-     */
-    void (*shutdown)(asocket* s) = nullptr;
-
-    /* close is called by the peer when it has gone away.
-     * we are not allowed to make any further calls on the
-     * peer once our close method is called.
-     */
-    void (*close)(asocket* s) = nullptr;
-
-    /* A socket is bound to atransport */
-    atransport* transport = nullptr;
-
-    size_t get_max_payload() const;
-};
-
-asocket *find_local_socket(unsigned local_id, unsigned remote_id);
-void install_local_socket(asocket *s);
-void remove_socket(asocket *s);
-void close_all_sockets(atransport *t);
-
-asocket* create_local_socket(unique_fd fd);
-asocket* create_local_service_socket(std::string_view destination, atransport* transport);
-
-asocket *create_remote_socket(unsigned id, atransport *t);
-void connect_to_remote(asocket* s, std::string_view destination);
-void connect_to_smartsocket(asocket *s);
-
-// Internal functions that are only made available here for testing purposes.
-namespace internal {
-
-#if ADB_HOST
-bool parse_host_service(std::string_view* out_serial, std::string_view* out_command,
-                        std::string_view service);
-#endif
-
-}  // namespace internal
-
-#endif  // __ADB_SOCKET_H
diff --git a/adb/socket_spec.cpp b/adb/socket_spec.cpp
deleted file mode 100644
index d17036c..0000000
--- a/adb/socket_spec.cpp
+++ /dev/null
@@ -1,449 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "socket_spec.h"
-
-#include <limits>
-#include <string>
-#include <string_view>
-#include <unordered_map>
-#include <vector>
-
-#include <android-base/parseint.h>
-#include <android-base/parsenetaddress.h>
-#include <android-base/stringprintf.h>
-#include <android-base/strings.h>
-#include <cutils/sockets.h>
-
-#include "adb.h"
-#include "adb_utils.h"
-#include "sysdeps.h"
-
-using namespace std::string_literals;
-
-using android::base::ConsumePrefix;
-using android::base::StringPrintf;
-
-#if defined(__linux__)
-#define ADB_LINUX 1
-#else
-#define ADB_LINUX 0
-#endif
-
-#if defined(_WIN32)
-#define ADB_WINDOWS 1
-#else
-#define ADB_WINDOWS 0
-#endif
-
-#if ADB_LINUX
-#include <sys/socket.h>
-#include "sysdeps/vm_sockets.h"
-#endif
-
-// Not static because it is used in commandline.c.
-int gListenAll = 0;
-
-struct LocalSocketType {
-    int socket_namespace;
-    bool available;
-};
-
-static auto& kLocalSocketTypes = *new std::unordered_map<std::string, LocalSocketType>({
-#if ADB_HOST
-    { "local", { ANDROID_SOCKET_NAMESPACE_FILESYSTEM, !ADB_WINDOWS } },
-#else
-    { "local", { ANDROID_SOCKET_NAMESPACE_RESERVED, !ADB_WINDOWS } },
-#endif
-
-    { "localreserved", { ANDROID_SOCKET_NAMESPACE_RESERVED, !ADB_HOST } },
-    { "localabstract", { ANDROID_SOCKET_NAMESPACE_ABSTRACT, ADB_LINUX } },
-    { "localfilesystem", { ANDROID_SOCKET_NAMESPACE_FILESYSTEM, !ADB_WINDOWS } },
-});
-
-bool parse_tcp_socket_spec(std::string_view spec, std::string* hostname, int* port,
-                           std::string* serial, std::string* error) {
-    if (!spec.starts_with("tcp:")) {
-        *error = "specification is not tcp: ";
-        *error += spec;
-        return false;
-    }
-
-    std::string hostname_value;
-    int port_value;
-
-    // If the spec is tcp:<port>, parse it ourselves.
-    // Otherwise, delegate to android::base::ParseNetAddress.
-    if (android::base::ParseInt(&spec[4], &port_value)) {
-        // Do the range checking ourselves, because ParseInt rejects 'tcp:65536' and 'tcp:foo:1234'
-        // identically.
-        if (port_value < 0 || port_value > 65535) {
-            *error = StringPrintf("bad port number '%d'", port_value);
-            return false;
-        }
-    } else {
-        std::string addr(spec.substr(4));
-        port_value = DEFAULT_ADB_LOCAL_TRANSPORT_PORT;
-
-        // FIXME: ParseNetAddress rejects port 0. This currently doesn't hurt, because listening
-        //        on an address that isn't 'localhost' is unsupported.
-        if (!android::base::ParseNetAddress(addr, &hostname_value, &port_value, serial, error)) {
-            return false;
-        }
-
-        if (port_value == -1) {
-            *error = "missing port in specification: ";
-            *error += spec;
-            return false;
-        }
-    }
-
-    if (hostname) {
-        *hostname = std::move(hostname_value);
-    }
-
-    if (port) {
-        *port = port_value;
-    }
-
-    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";
-}
-
-bool is_socket_spec(std::string_view spec) {
-    for (const auto& it : kLocalSocketTypes) {
-        std::string prefix = it.first + ":";
-        if (spec.starts_with(prefix)) {
-            return true;
-        }
-    }
-    return spec.starts_with("tcp:") || spec.starts_with("acceptfd:");
-}
-
-bool is_local_socket_spec(std::string_view spec) {
-    for (const auto& it : kLocalSocketTypes) {
-        std::string prefix = it.first + ":";
-        if (spec.starts_with(prefix)) {
-            return true;
-        }
-    }
-
-    std::string error;
-    std::string hostname;
-    if (!parse_tcp_socket_spec(spec, &hostname, nullptr, nullptr, &error)) {
-        return false;
-    }
-    return tcp_host_is_local(hostname);
-}
-
-bool socket_spec_connect(unique_fd* fd, std::string_view address, int* port, std::string* serial,
-                         std::string* error) {
-    if (address.starts_with("tcp:")) {
-        std::string hostname;
-        int port_value = port ? *port : 0;
-        if (!parse_tcp_socket_spec(address, &hostname, &port_value, serial, error)) {
-            return false;
-        }
-
-        if (tcp_host_is_local(hostname)) {
-            fd->reset(network_loopback_client(port_value, SOCK_STREAM, error));
-        } else {
-#if ADB_HOST
-            fd->reset(network_connect(hostname, port_value, SOCK_STREAM, 0, error));
-#else
-            // Disallow arbitrary connections in adbd.
-            *error = "adbd does not support arbitrary tcp connections";
-            return false;
-#endif
-        }
-
-        if (fd->get() > 0) {
-            disable_tcp_nagle(fd->get());
-            if (port) {
-                *port = port_value;
-            }
-            return true;
-        }
-        return false;
-    } else if (address.starts_with("vsock:")) {
-#if ADB_LINUX
-        std::string spec_str(address);
-        std::vector<std::string> fragments = android::base::Split(spec_str, ":");
-        unsigned int port_value = port ? *port : 0;
-        if (fragments.size() != 2 && fragments.size() != 3) {
-            *error = android::base::StringPrintf("expected vsock:cid or vsock:port:cid in '%s'",
-                                                 spec_str.c_str());
-            errno = EINVAL;
-            return false;
-        }
-        unsigned int cid = 0;
-        if (!android::base::ParseUint(fragments[1], &cid)) {
-            *error = android::base::StringPrintf("could not parse vsock cid in '%s'",
-                                                 spec_str.c_str());
-            errno = EINVAL;
-            return false;
-        }
-        if (fragments.size() == 3 && !android::base::ParseUint(fragments[2], &port_value)) {
-            *error = android::base::StringPrintf("could not parse vsock port in '%s'",
-                                                 spec_str.c_str());
-            errno = EINVAL;
-            return false;
-        }
-        if (port_value == 0) {
-            *error = android::base::StringPrintf("vsock port was not provided.");
-            errno = EINVAL;
-            return false;
-        }
-        fd->reset(socket(AF_VSOCK, SOCK_STREAM, 0));
-        if (fd->get() == -1) {
-            *error = "could not open vsock socket";
-            return false;
-        }
-        sockaddr_vm addr{};
-        addr.svm_family = AF_VSOCK;
-        addr.svm_port = port_value;
-        addr.svm_cid = cid;
-        if (serial) {
-            *serial = android::base::StringPrintf("vsock:%u:%d", cid, port_value);
-        }
-        if (connect(fd->get(), reinterpret_cast<sockaddr*>(&addr), sizeof(addr))) {
-            int error_num = errno;
-            *error = android::base::StringPrintf("could not connect to vsock address '%s'",
-                                                 spec_str.c_str());
-            errno = error_num;
-            return false;
-        }
-        if (port) {
-            *port = port_value;
-        }
-        return true;
-#else   // ADB_LINUX
-        *error = "vsock is only supported on linux";
-        return false;
-#endif  // ADB_LINUX
-    } else if (address.starts_with("acceptfd:")) {
-        *error = "cannot connect to acceptfd";
-        return false;
-    }
-
-    for (const auto& it : kLocalSocketTypes) {
-        std::string prefix = it.first + ":";
-        if (address.starts_with(prefix)) {
-            if (!it.second.available) {
-                *error = StringPrintf("socket type %s is unavailable on this platform",
-                                      it.first.c_str());
-                return false;
-            }
-
-            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;
-            }
-            return true;
-        }
-    }
-
-    *error = "unknown socket specification: ";
-    *error += address;
-    return false;
-}
-
-int socket_spec_listen(std::string_view spec, std::string* error, int* resolved_port) {
-    if (spec.starts_with("tcp:")) {
-        std::string hostname;
-        int port;
-        if (!parse_tcp_socket_spec(spec, &hostname, &port, nullptr, error)) {
-            return -1;
-        }
-
-        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);
-        } else if (hostname == "::1") {
-            result = network_loopback_server(port, SOCK_STREAM, error, false);
-        } else {
-            // TODO: Implement me.
-            *error = "listening on specified hostname currently unsupported";
-            return -1;
-        }
-
-        if (result >= 0 && resolved_port) {
-            *resolved_port = adb_socket_get_local_port(result);
-        }
-        return result;
-    } 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;
-        }
-        int port;
-        if (!android::base::ParseInt(fragments[1], &port)) {
-            *error = "could not parse vsock port";
-            errno = EINVAL;
-            return -1;
-        } else if (port < 0) {
-            *error = "vsock port was negative.";
-            errno = EINVAL;
-            return -1;
-        }
-        unique_fd serverfd(socket(AF_VSOCK, SOCK_STREAM, 0));
-        if (serverfd == -1) {
-            int error_num = errno;
-            *error = android::base::StringPrintf("could not create vsock server: '%s'",
-                                                 strerror(error_num));
-            errno = error_num;
-            return -1;
-        }
-        sockaddr_vm addr{};
-        addr.svm_family = AF_VSOCK;
-        addr.svm_port = port == 0 ? VMADDR_PORT_ANY : port;
-        addr.svm_cid = VMADDR_CID_ANY;
-        socklen_t addr_len = sizeof(addr);
-        if (bind(serverfd.get(), reinterpret_cast<struct sockaddr*>(&addr), addr_len)) {
-            return -1;
-        }
-        if (listen(serverfd.get(), 4)) {
-            return -1;
-        }
-        if (serverfd >= 0 && resolved_port) {
-            if (getsockname(serverfd.get(), reinterpret_cast<sockaddr*>(&addr), &addr_len) == 0) {
-                *resolved_port = addr.svm_port;
-            } else {
-                return -1;
-            }
-        }
-        return serverfd.release();
-#else   // ADB_LINUX
-        *error = "vsock is only supported on linux";
-        return -1;
-#endif  // ADB_LINUX
-    } else if (ConsumePrefix(&spec, "acceptfd:")) {
-#if ADB_WINDOWS
-        *error = "socket activation not supported under Windows";
-        return -1;
-#else
-        // We inherited the socket from some kind of launcher. It's already bound and
-        // listening. Return a copy of the FD instead of the FD itself so we implement the
-        // normal "listen" contract and can succeed more than once.
-        unsigned int fd_u;
-        if (!ParseUint(&fd_u, spec) || fd_u > std::numeric_limits<int>::max()) {
-            *error = "invalid fd";
-            return -1;
-        }
-        int fd = static_cast<int>(fd_u);
-        int flags = get_fd_flags(fd);
-        if (flags < 0) {
-            *error = android::base::StringPrintf("could not get flags of inherited fd %d: '%s'", fd,
-                                                 strerror(errno));
-            return -1;
-        }
-        if (flags & FD_CLOEXEC) {
-            *error = android::base::StringPrintf("fd %d was not inherited from parent", fd);
-            return -1;
-        }
-
-        int dummy_sock_type;
-        socklen_t dummy_sock_type_size = sizeof(dummy_sock_type);
-        if (getsockopt(fd, SOL_SOCKET, SO_TYPE, &dummy_sock_type, &dummy_sock_type_size)) {
-            *error = android::base::StringPrintf("fd %d does not refer to a socket", fd);
-            return -1;
-        }
-
-        int new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 0);
-        if (new_fd < 0) {
-            *error = android::base::StringPrintf("could not dup inherited fd %d: '%s'", fd,
-                                                 strerror(errno));
-            return -1;
-        }
-        return new_fd;
-#endif
-    }
-
-    for (const auto& it : kLocalSocketTypes) {
-        std::string prefix = it.first + ":";
-        if (spec.starts_with(prefix)) {
-            if (!it.second.available) {
-                *error = "attempted to listen on unavailable socket type: ";
-                *error += spec;
-                return -1;
-            }
-
-            return network_local_server(&spec[prefix.length()], it.second.socket_namespace,
-                                        SOCK_STREAM, error);
-        }
-    }
-
-    *error = "unknown socket specification:";
-    *error += spec;
-    return -1;
-}
diff --git a/adb/socket_spec.h b/adb/socket_spec.h
deleted file mode 100644
index 94719c8..0000000
--- a/adb/socket_spec.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <string>
-#include <tuple>
-
-#include "adb_unique_fd.h"
-
-// Returns true if the argument starts with a plausible socket prefix.
-bool is_socket_spec(std::string_view spec);
-bool is_local_socket_spec(std::string_view spec);
-
-bool socket_spec_connect(unique_fd* fd, std::string_view address, int* port, std::string* serial,
-                         std::string* error);
-int socket_spec_listen(std::string_view spec, std::string* error, int* resolved_tcp_port = nullptr);
-
-bool parse_tcp_socket_spec(std::string_view spec, std::string* hostname, int* port,
-                           std::string* serial, std::string* error);
-
-int get_host_socket_spec_port(std::string_view spec, std::string* error);
diff --git a/adb/socket_spec_test.cpp b/adb/socket_spec_test.cpp
deleted file mode 100644
index e9d5270..0000000
--- a/adb/socket_spec_test.cpp
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "socket_spec.h"
-
-#include <string>
-
-#include <unistd.h>
-
-#include <android-base/file.h>
-#include <android-base/stringprintf.h>
-#include <gtest/gtest.h>
-
-TEST(socket_spec, parse_tcp_socket_spec_just_port) {
-    std::string hostname, error, serial;
-    int port;
-    EXPECT_TRUE(parse_tcp_socket_spec("tcp:5037", &hostname, &port, &serial, &error));
-    EXPECT_EQ("", hostname);
-    EXPECT_EQ(5037, port);
-    EXPECT_EQ("", serial);
-}
-
-TEST(socket_spec, parse_tcp_socket_spec_bad_ports) {
-    std::string hostname, error, serial;
-    int port;
-    EXPECT_FALSE(parse_tcp_socket_spec("tcp:", &hostname, &port, &serial, &error));
-    EXPECT_FALSE(parse_tcp_socket_spec("tcp:-1", &hostname, &port, &serial, &error));
-    EXPECT_FALSE(parse_tcp_socket_spec("tcp:65536", &hostname, &port, &serial, &error));
-}
-
-TEST(socket_spec, parse_tcp_socket_spec_host_and_port) {
-    std::string hostname, error, serial;
-    int port;
-    EXPECT_TRUE(parse_tcp_socket_spec("tcp:localhost:1234", &hostname, &port, &serial, &error));
-    EXPECT_EQ("localhost", hostname);
-    EXPECT_EQ(1234, port);
-    EXPECT_EQ("localhost:1234", serial);
-}
-
-TEST(socket_spec, parse_tcp_socket_spec_host_no_port) {
-    std::string hostname, error, serial;
-    int port;
-    EXPECT_TRUE(parse_tcp_socket_spec("tcp:localhost", &hostname, &port, &serial, &error));
-    EXPECT_EQ("localhost", hostname);
-    EXPECT_EQ(5555, port);
-    EXPECT_EQ("localhost:5555", serial);
-}
-
-TEST(socket_spec, parse_tcp_socket_spec_host_bad_ports) {
-    std::string hostname, error, serial;
-    int port;
-    EXPECT_FALSE(parse_tcp_socket_spec("tcp:localhost:", &hostname, &port, &serial, &error));
-    EXPECT_FALSE(parse_tcp_socket_spec("tcp:localhost:-1", &hostname, &port, &serial, &error));
-    EXPECT_FALSE(parse_tcp_socket_spec("tcp:localhost:65536", &hostname, &port, &serial, &error));
-}
-
-TEST(socket_spec, parse_tcp_socket_spec_ipv6_and_port) {
-    std::string hostname, error, serial;
-    int port;
-    EXPECT_TRUE(parse_tcp_socket_spec("tcp:[::1]:1234", &hostname, &port, &serial, &error));
-    EXPECT_EQ("::1", hostname);
-    EXPECT_EQ(1234, port);
-    EXPECT_EQ("[::1]:1234", serial);
-}
-
-TEST(socket_spec, parse_tcp_socket_spec_ipv6_no_port) {
-    std::string hostname, error, serial;
-    int port;
-    EXPECT_TRUE(parse_tcp_socket_spec("tcp:::1", &hostname, &port, &serial, &error));
-    EXPECT_EQ("::1", hostname);
-    EXPECT_EQ(5555, port);
-    EXPECT_EQ("[::1]:5555", serial);
-}
-
-TEST(socket_spec, parse_tcp_socket_spec_ipv6_bad_ports) {
-    std::string hostname, error, serial;
-    int port;
-    EXPECT_FALSE(parse_tcp_socket_spec("tcp:[::1]", &hostname, &port, &serial, &error));
-    EXPECT_FALSE(parse_tcp_socket_spec("tcp:[::1]:", &hostname, &port, &serial, &error));
-    EXPECT_FALSE(parse_tcp_socket_spec("tcp:[::1]:-1", &hostname, &port, &serial, &error));
-}
-
-TEST(socket_spec, get_host_socket_spec_port) {
-    std::string error;
-    EXPECT_EQ(5555, get_host_socket_spec_port("tcp:5555", &error));
-    EXPECT_EQ(5555, get_host_socket_spec_port("tcp:localhost:5555", &error));
-    EXPECT_EQ(5555, get_host_socket_spec_port("tcp:[::1]:5555", &error));
-    EXPECT_EQ(5555, get_host_socket_spec_port("vsock:5555", &error));
-}
-
-TEST(socket_spec, get_host_socket_spec_port_no_port) {
-    std::string error;
-    EXPECT_EQ(5555, get_host_socket_spec_port("tcp:localhost", &error));
-    EXPECT_EQ(-1, get_host_socket_spec_port("vsock:localhost", &error));
-}
-
-TEST(socket_spec, get_host_socket_spec_port_bad_ports) {
-    std::string error;
-    EXPECT_EQ(-1, get_host_socket_spec_port("tcp:65536", &error));
-    EXPECT_EQ(-1, get_host_socket_spec_port("tcp:-5", &error));
-    EXPECT_EQ(-1, get_host_socket_spec_port("vsock:-5", &error));
-    EXPECT_EQ(-1, get_host_socket_spec_port("vsock:5:5555", &error));
-}
-
-TEST(socket_spec, get_host_socket_spec_port_bad_string) {
-    std::string error;
-    EXPECT_EQ(-1, get_host_socket_spec_port("tcpz:5555", &error));
-    EXPECT_EQ(-1, get_host_socket_spec_port("vsockz:5555", &error));
-    EXPECT_EQ(-1, get_host_socket_spec_port("abcd:5555", &error));
-    EXPECT_EQ(-1, get_host_socket_spec_port("abcd", &error));
-}
-
-TEST(socket_spec, socket_spec_listen_connect_tcp) {
-    std::string error, serial;
-    int port;
-    unique_fd server_fd, client_fd;
-    EXPECT_FALSE(socket_spec_connect(&client_fd, "tcp:localhost:7777", &port, &serial, &error));
-    server_fd.reset(socket_spec_listen("tcp:7777", &error, &port));
-    EXPECT_NE(server_fd.get(), -1);
-    EXPECT_TRUE(socket_spec_connect(&client_fd, "tcp:localhost:7777", &port, &serial, &error));
-    EXPECT_NE(client_fd.get(), -1);
-}
-
-TEST(socket_spec, socket_spec_listen_connect_localfilesystem) {
-    std::string error, serial;
-    int port;
-    unique_fd server_fd, client_fd;
-    TemporaryDir sock_dir;
-
-    // Only run this test if the created directory is writable.
-    int result = access(sock_dir.path, W_OK);
-    if (result == 0) {
-        std::string sock_addr =
-                android::base::StringPrintf("localfilesystem:%s/af_unix_socket", sock_dir.path);
-        EXPECT_FALSE(socket_spec_connect(&client_fd, sock_addr, &port, &serial, &error));
-        server_fd.reset(socket_spec_listen(sock_addr, &error, &port));
-        EXPECT_NE(server_fd.get(), -1);
-        EXPECT_TRUE(socket_spec_connect(&client_fd, sock_addr, &port, &serial, &error));
-        EXPECT_NE(client_fd.get(), -1);
-    }
-}
diff --git a/adb/socket_test.cpp b/adb/socket_test.cpp
deleted file mode 100644
index 1601ff0..0000000
--- a/adb/socket_test.cpp
+++ /dev/null
@@ -1,386 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "fdevent/fdevent.h"
-
-#include <gtest/gtest.h>
-
-#include <array>
-#include <limits>
-#include <queue>
-#include <string>
-#include <thread>
-#include <vector>
-
-#include <unistd.h>
-
-#include "adb.h"
-#include "adb_io.h"
-#include "fdevent/fdevent_test.h"
-#include "socket.h"
-#include "sysdeps.h"
-#include "sysdeps/chrono.h"
-
-using namespace std::string_literals;
-using namespace std::string_view_literals;
-
-struct ThreadArg {
-    int first_read_fd;
-    int last_write_fd;
-    size_t middle_pipe_count;
-};
-
-class LocalSocketTest : public FdeventTest {};
-
-TEST_F(LocalSocketTest, smoke) {
-    // Join two socketpairs with a chain of intermediate socketpairs.
-    int first[2];
-    std::vector<std::array<int, 2>> intermediates;
-    int last[2];
-
-    constexpr size_t INTERMEDIATE_COUNT = 50;
-    constexpr size_t MESSAGE_LOOP_COUNT = 100;
-    const std::string MESSAGE = "socket_test";
-
-    intermediates.resize(INTERMEDIATE_COUNT);
-    ASSERT_EQ(0, adb_socketpair(first)) << strerror(errno);
-    ASSERT_EQ(0, adb_socketpair(last)) << strerror(errno);
-    asocket* prev_tail = create_local_socket(unique_fd(first[1]));
-    ASSERT_NE(nullptr, prev_tail);
-
-    auto connect = [](asocket* tail, asocket* head) {
-        tail->peer = head;
-        head->peer = tail;
-        tail->ready(tail);
-    };
-
-    for (auto& intermediate : intermediates) {
-        ASSERT_EQ(0, adb_socketpair(intermediate.data())) << strerror(errno);
-
-        asocket* head = create_local_socket(unique_fd(intermediate[0]));
-        ASSERT_NE(nullptr, head);
-
-        asocket* tail = create_local_socket(unique_fd(intermediate[1]));
-        ASSERT_NE(nullptr, tail);
-
-        connect(prev_tail, head);
-        prev_tail = tail;
-    }
-
-    asocket* end = create_local_socket(unique_fd(last[0]));
-    ASSERT_NE(nullptr, end);
-    connect(prev_tail, end);
-
-    PrepareThread();
-
-    for (size_t i = 0; i < MESSAGE_LOOP_COUNT; ++i) {
-        std::string read_buffer = MESSAGE;
-        std::string write_buffer(MESSAGE.size(), 'a');
-        ASSERT_TRUE(WriteFdExactly(first[0], &read_buffer[0], read_buffer.size()));
-        ASSERT_TRUE(ReadFdExactly(last[1], &write_buffer[0], write_buffer.size()));
-        ASSERT_EQ(read_buffer, write_buffer);
-    }
-
-    ASSERT_EQ(0, adb_close(first[0]));
-    ASSERT_EQ(0, adb_close(last[1]));
-
-    // Wait until the local sockets are closed.
-    WaitForFdeventLoop();
-    ASSERT_EQ(GetAdditionalLocalSocketCount(), fdevent_installed_count());
-    TerminateThread();
-}
-
-struct CloseWithPacketArg {
-    unique_fd socket_fd;
-    size_t bytes_written;
-    unique_fd cause_close_fd;
-};
-
-static void CreateCloser(CloseWithPacketArg* arg) {
-    fdevent_run_on_main_thread([arg]() {
-        asocket* s = create_local_socket(std::move(arg->socket_fd));
-        ASSERT_TRUE(s != nullptr);
-        arg->bytes_written = 0;
-
-        // On platforms that implement sockets via underlying sockets (e.g. Wine),
-        // a socket can appear to be full, and then become available for writes
-        // again without read being called on the other end. Loop and sleep after
-        // each write to give the underlying implementation time to flush.
-        bool socket_filled = false;
-        for (int i = 0; i < 128; ++i) {
-            apacket::payload_type data;
-            data.resize(MAX_PAYLOAD);
-            arg->bytes_written += data.size();
-            int ret = s->enqueue(s, std::move(data));
-            if (ret == 1) {
-                socket_filled = true;
-                break;
-            }
-            ASSERT_NE(-1, ret);
-
-            std::this_thread::sleep_for(250ms);
-        }
-        ASSERT_TRUE(socket_filled);
-
-        asocket* cause_close_s = create_local_socket(std::move(arg->cause_close_fd));
-        ASSERT_TRUE(cause_close_s != nullptr);
-        cause_close_s->peer = s;
-        s->peer = cause_close_s;
-        cause_close_s->ready(cause_close_s);
-    });
-    WaitForFdeventLoop();
-}
-
-// This test checks if we can close local socket in the following situation:
-// The socket is closing but having some packets, so it is not closed. Then
-// some write error happens in the socket's file handler, e.g., the file
-// handler is closed.
-TEST_F(LocalSocketTest, close_socket_with_packet) {
-    int socket_fd[2];
-    ASSERT_EQ(0, adb_socketpair(socket_fd));
-    int cause_close_fd[2];
-    ASSERT_EQ(0, adb_socketpair(cause_close_fd));
-    CloseWithPacketArg arg;
-    arg.socket_fd.reset(socket_fd[1]);
-    arg.cause_close_fd.reset(cause_close_fd[1]);
-
-    PrepareThread();
-    CreateCloser(&arg);
-
-    ASSERT_EQ(0, adb_close(cause_close_fd[0]));
-
-    WaitForFdeventLoop();
-    EXPECT_EQ(1u + GetAdditionalLocalSocketCount(), fdevent_installed_count());
-    ASSERT_EQ(0, adb_close(socket_fd[0]));
-
-    WaitForFdeventLoop();
-    ASSERT_EQ(GetAdditionalLocalSocketCount(), fdevent_installed_count());
-    TerminateThread();
-}
-
-// This test checks if we can read packets from a closing local socket.
-TEST_F(LocalSocketTest, read_from_closing_socket) {
-    int socket_fd[2];
-    ASSERT_EQ(0, adb_socketpair(socket_fd));
-    int cause_close_fd[2];
-    ASSERT_EQ(0, adb_socketpair(cause_close_fd));
-    CloseWithPacketArg arg;
-    arg.socket_fd.reset(socket_fd[1]);
-    arg.cause_close_fd.reset(cause_close_fd[1]);
-
-    PrepareThread();
-    CreateCloser(&arg);
-
-    WaitForFdeventLoop();
-    ASSERT_EQ(0, adb_close(cause_close_fd[0]));
-
-    WaitForFdeventLoop();
-    EXPECT_EQ(1u + GetAdditionalLocalSocketCount(), fdevent_installed_count());
-
-    // Verify if we can read successfully.
-    std::vector<char> buf(arg.bytes_written);
-    ASSERT_NE(0u, arg.bytes_written);
-    ASSERT_EQ(true, ReadFdExactly(socket_fd[0], buf.data(), buf.size()));
-    ASSERT_EQ(0, adb_close(socket_fd[0]));
-
-    WaitForFdeventLoop();
-    ASSERT_EQ(GetAdditionalLocalSocketCount(), fdevent_installed_count());
-    TerminateThread();
-}
-
-// This test checks if we can close local socket in the following situation:
-// The socket is not closed and has some packets. When it fails to write to
-// the socket's file handler because the other end is closed, we check if the
-// socket is closed.
-TEST_F(LocalSocketTest, write_error_when_having_packets) {
-    int socket_fd[2];
-    ASSERT_EQ(0, adb_socketpair(socket_fd));
-    int cause_close_fd[2];
-    ASSERT_EQ(0, adb_socketpair(cause_close_fd));
-    CloseWithPacketArg arg;
-    arg.socket_fd.reset(socket_fd[1]);
-    arg.cause_close_fd.reset(cause_close_fd[1]);
-
-    PrepareThread();
-    CreateCloser(&arg);
-
-    WaitForFdeventLoop();
-    EXPECT_EQ(2u + GetAdditionalLocalSocketCount(), fdevent_installed_count());
-    ASSERT_EQ(0, adb_close(socket_fd[0]));
-
-    std::this_thread::sleep_for(2s);
-
-    WaitForFdeventLoop();
-    ASSERT_EQ(GetAdditionalLocalSocketCount(), fdevent_installed_count());
-    TerminateThread();
-}
-
-// Ensure that if we fail to write output to an fd, we will still flush data coming from it.
-TEST_F(LocalSocketTest, flush_after_shutdown) {
-    int head_fd[2];
-    int tail_fd[2];
-    ASSERT_EQ(0, adb_socketpair(head_fd));
-    ASSERT_EQ(0, adb_socketpair(tail_fd));
-
-    asocket* head = create_local_socket(unique_fd(head_fd[1]));
-    asocket* tail = create_local_socket(unique_fd(tail_fd[1]));
-
-    head->peer = tail;
-    head->ready(head);
-
-    tail->peer = head;
-    tail->ready(tail);
-
-    PrepareThread();
-
-    EXPECT_TRUE(WriteFdExactly(head_fd[0], "foo", 3));
-
-    EXPECT_EQ(0, adb_shutdown(head_fd[0], SHUT_RD));
-    const char* str = "write succeeds, but local_socket will fail to write";
-    EXPECT_TRUE(WriteFdExactly(tail_fd[0], str, strlen(str)));
-    EXPECT_TRUE(WriteFdExactly(head_fd[0], "bar", 3));
-
-    char buf[6];
-    EXPECT_TRUE(ReadFdExactly(tail_fd[0], buf, 6));
-    EXPECT_EQ(0, memcmp(buf, "foobar", 6));
-
-    adb_close(head_fd[0]);
-    adb_close(tail_fd[0]);
-
-    WaitForFdeventLoop();
-    ASSERT_EQ(GetAdditionalLocalSocketCount(), fdevent_installed_count());
-    TerminateThread();
-}
-
-#if defined(__linux__)
-
-static void ClientThreadFunc() {
-    std::string error;
-    int fd = network_loopback_client(5038, SOCK_STREAM, &error);
-    ASSERT_GE(fd, 0) << error;
-    std::this_thread::sleep_for(1s);
-    ASSERT_EQ(0, adb_close(fd));
-}
-
-// This test checks if we can close sockets in CLOSE_WAIT state.
-TEST_F(LocalSocketTest, close_socket_in_CLOSE_WAIT_state) {
-    std::string error;
-    int listen_fd = network_inaddr_any_server(5038, SOCK_STREAM, &error);
-    ASSERT_GE(listen_fd, 0);
-
-    std::thread client_thread(ClientThreadFunc);
-
-    int accept_fd = adb_socket_accept(listen_fd, nullptr, nullptr);
-    ASSERT_GE(accept_fd, 0);
-
-    PrepareThread();
-
-    fdevent_run_on_main_thread([accept_fd]() {
-        asocket* s = create_local_socket(unique_fd(accept_fd));
-        ASSERT_TRUE(s != nullptr);
-    });
-
-    WaitForFdeventLoop();
-    EXPECT_EQ(1u + GetAdditionalLocalSocketCount(), fdevent_installed_count());
-
-    // Wait until the client closes its socket.
-    client_thread.join();
-
-    WaitForFdeventLoop();
-    ASSERT_EQ(GetAdditionalLocalSocketCount(), fdevent_installed_count());
-    TerminateThread();
-}
-
-#endif  // defined(__linux__)
-
-#if ADB_HOST
-
-#define VerifyParseHostServiceFailed(s)                                         \
-    do {                                                                        \
-        std::string service(s);                                                 \
-        std::string_view serial, command;                                       \
-        bool result = internal::parse_host_service(&serial, &command, service); \
-        EXPECT_FALSE(result);                                                   \
-    } while (0)
-
-#define VerifyParseHostService(s, expected_serial, expected_command)            \
-    do {                                                                        \
-        std::string service(s);                                                 \
-        std::string_view serial, command;                                       \
-        bool result = internal::parse_host_service(&serial, &command, service); \
-        EXPECT_TRUE(result);                                                    \
-        EXPECT_EQ(std::string(expected_serial), std::string(serial));           \
-        EXPECT_EQ(std::string(expected_command), std::string(command));         \
-    } while (0);
-
-// Check [tcp:|udp:]<serial>[:<port>]:<command> format.
-TEST(socket_test, test_parse_host_service) {
-    for (const std::string& protocol : {"", "tcp:", "udp:"}) {
-        VerifyParseHostServiceFailed(protocol);
-        VerifyParseHostServiceFailed(protocol + "foo");
-
-        {
-            std::string serial = protocol + "foo";
-            VerifyParseHostService(serial + ":bar", serial, "bar");
-            VerifyParseHostService(serial + " :bar:baz", serial, "bar:baz");
-        }
-
-        {
-            // With port.
-            std::string serial = protocol + "foo:123";
-            VerifyParseHostService(serial + ":bar", serial, "bar");
-            VerifyParseHostService(serial + ":456", serial, "456");
-            VerifyParseHostService(serial + ":bar:baz", serial, "bar:baz");
-        }
-
-        // Don't register a port unless it's all numbers and ends with ':'.
-        VerifyParseHostService(protocol + "foo:123", protocol + "foo", "123");
-        VerifyParseHostService(protocol + "foo:123bar:baz", protocol + "foo", "123bar:baz");
-
-        std::string addresses[] = {"100.100.100.100", "[0123:4567:89ab:CDEF:0:9:a:f]", "[::1]"};
-        for (const std::string& address : addresses) {
-            std::string serial = protocol + address;
-            std::string serial_with_port = protocol + address + ":5555";
-            VerifyParseHostService(serial + ":foo", serial, "foo");
-            VerifyParseHostService(serial_with_port + ":foo", serial_with_port, "foo");
-        }
-
-        // If we can't find both [] then treat it as a normal serial with [ in it.
-        VerifyParseHostService(protocol + "[0123:foo", protocol + "[0123", "foo");
-
-        // Don't be fooled by random IPv6 addresses in the command string.
-        VerifyParseHostService(protocol + "foo:ping [0123:4567:89ab:CDEF:0:9:a:f]:5555",
-                               protocol + "foo", "ping [0123:4567:89ab:CDEF:0:9:a:f]:5555");
-
-        // Handle embedded NULs properly.
-        VerifyParseHostService(protocol + "foo:echo foo\0bar"s, protocol + "foo",
-                               "echo foo\0bar"sv);
-    }
-}
-
-// Check <prefix>:<serial>:<command> format.
-TEST(socket_test, test_parse_host_service_prefix) {
-    for (const std::string& prefix : {"usb:", "product:", "model:", "device:"}) {
-        VerifyParseHostServiceFailed(prefix);
-        VerifyParseHostServiceFailed(prefix + "foo");
-
-        VerifyParseHostService(prefix + "foo:bar", prefix + "foo", "bar");
-        VerifyParseHostService(prefix + "foo:bar:baz", prefix + "foo", "bar:baz");
-        VerifyParseHostService(prefix + "foo:123:bar", prefix + "foo", "123:bar");
-    }
-}
-
-#endif  // ADB_HOST
diff --git a/adb/sockets.cpp b/adb/sockets.cpp
deleted file mode 100644
index 423af67..0000000
--- a/adb/sockets.cpp
+++ /dev/null
@@ -1,935 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define TRACE_TAG SOCKETS
-
-#include "sysdeps.h"
-
-#include <ctype.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <algorithm>
-#include <chrono>
-#include <mutex>
-#include <string>
-#include <vector>
-
-#include <android-base/strings.h>
-
-#if !ADB_HOST
-#include <android-base/properties.h>
-#include <log/log_properties.h>
-#endif
-
-#include "adb.h"
-#include "adb_io.h"
-#include "adb_utils.h"
-#include "transport.h"
-#include "types.h"
-
-using namespace std::chrono_literals;
-
-static std::recursive_mutex& local_socket_list_lock = *new std::recursive_mutex();
-static unsigned local_socket_next_id = 1;
-
-static auto& local_socket_list = *new std::vector<asocket*>();
-
-/* the the list of currently closing local sockets.
-** these have no peer anymore, but still packets to
-** write to their fd.
-*/
-static auto& local_socket_closing_list = *new std::vector<asocket*>();
-
-// Parse the global list of sockets to find one with id |local_id|.
-// If |peer_id| is not 0, also check that it is connected to a peer
-// with id |peer_id|. Returns an asocket handle on success, NULL on failure.
-asocket* find_local_socket(unsigned local_id, unsigned peer_id) {
-    asocket* result = nullptr;
-
-    std::lock_guard<std::recursive_mutex> lock(local_socket_list_lock);
-    for (asocket* s : local_socket_list) {
-        if (s->id != local_id) {
-            continue;
-        }
-        if (peer_id == 0 || (s->peer && s->peer->id == peer_id)) {
-            result = s;
-        }
-        break;
-    }
-
-    return result;
-}
-
-void install_local_socket(asocket* s) {
-    std::lock_guard<std::recursive_mutex> lock(local_socket_list_lock);
-
-    s->id = local_socket_next_id++;
-
-    // Socket ids should never be 0.
-    if (local_socket_next_id == 0) {
-        LOG(FATAL) << "local socket id overflow";
-    }
-
-    local_socket_list.push_back(s);
-}
-
-void remove_socket(asocket* s) {
-    std::lock_guard<std::recursive_mutex> lock(local_socket_list_lock);
-    for (auto list : { &local_socket_list, &local_socket_closing_list }) {
-        list->erase(std::remove_if(list->begin(), list->end(), [s](asocket* x) { return x == s; }),
-                    list->end());
-    }
-}
-
-void close_all_sockets(atransport* t) {
-    /* this is a little gross, but since s->close() *will* modify
-    ** the list out from under you, your options are limited.
-    */
-    std::lock_guard<std::recursive_mutex> lock(local_socket_list_lock);
-restart:
-    for (asocket* s : local_socket_list) {
-        if (s->transport == t || (s->peer && s->peer->transport == t)) {
-            s->close(s);
-            goto restart;
-        }
-    }
-}
-
-enum class SocketFlushResult {
-    Destroyed,
-    TryAgain,
-    Completed,
-};
-
-static SocketFlushResult local_socket_flush_incoming(asocket* s) {
-    if (!s->packet_queue.empty()) {
-        std::vector<adb_iovec> iov = s->packet_queue.iovecs();
-        ssize_t rc = adb_writev(s->fd, iov.data(), iov.size());
-        if (rc > 0 && static_cast<size_t>(rc) == s->packet_queue.size()) {
-            s->packet_queue.clear();
-        } else if (rc > 0) {
-            s->packet_queue.drop_front(rc);
-            fdevent_add(s->fde, FDE_WRITE);
-            return SocketFlushResult::TryAgain;
-        } else if (rc == -1 && errno == EAGAIN) {
-            fdevent_add(s->fde, FDE_WRITE);
-            return SocketFlushResult::TryAgain;
-        } else {
-            // We failed to write, but it's possible that we can still read from the socket.
-            // Give that a try before giving up.
-            s->has_write_error = true;
-        }
-    }
-
-    // If we sent the last packet of a closing socket, we can now destroy it.
-    if (s->closing) {
-        s->close(s);
-        return SocketFlushResult::Destroyed;
-    }
-
-    fdevent_del(s->fde, FDE_WRITE);
-    return SocketFlushResult::Completed;
-}
-
-// Returns false if the socket has been closed and destroyed as a side-effect of this function.
-static bool local_socket_flush_outgoing(asocket* s) {
-    const size_t max_payload = s->get_max_payload();
-    apacket::payload_type data;
-    data.resize(max_payload);
-    char* x = &data[0];
-    size_t avail = max_payload;
-    int r = 0;
-    int is_eof = 0;
-
-    while (avail > 0) {
-        r = adb_read(s->fd, x, avail);
-        D("LS(%d): post adb_read(fd=%d,...) r=%d (errno=%d) avail=%zu", s->id, s->fd, r,
-          r < 0 ? errno : 0, avail);
-        if (r == -1) {
-            if (errno == EAGAIN) {
-                break;
-            }
-        } else if (r > 0) {
-            avail -= r;
-            x += r;
-            continue;
-        }
-
-        /* r = 0 or unhandled error */
-        is_eof = 1;
-        break;
-    }
-    D("LS(%d): fd=%d post avail loop. r=%d is_eof=%d forced_eof=%d", s->id, s->fd, r, is_eof,
-      s->fde->force_eof);
-
-    if (avail != max_payload && s->peer) {
-        data.resize(max_payload - avail);
-
-        // s->peer->enqueue() may call s->close() and free s,
-        // so save variables for debug printing below.
-        unsigned saved_id = s->id;
-        int saved_fd = s->fd;
-        r = s->peer->enqueue(s->peer, std::move(data));
-        D("LS(%u): fd=%d post peer->enqueue(). r=%d", saved_id, saved_fd, r);
-
-        if (r < 0) {
-            // Error return means they closed us as a side-effect and we must
-            // return immediately.
-            //
-            // Note that if we still have buffered packets, the socket will be
-            // placed on the closing socket list. This handler function will be
-            // called again to process FDE_WRITE events.
-            return false;
-        }
-
-        if (r > 0) {
-            /* if the remote cannot accept further events,
-            ** we disable notification of READs.  They'll
-            ** be enabled again when we get a call to ready()
-            */
-            fdevent_del(s->fde, FDE_READ);
-        }
-    }
-
-    // Don't allow a forced eof if data is still there.
-    if ((s->fde->force_eof && !r) || is_eof) {
-        D(" closing because is_eof=%d r=%d s->fde.force_eof=%d", is_eof, r, s->fde->force_eof);
-        s->close(s);
-        return false;
-    }
-
-    return true;
-}
-
-static int local_socket_enqueue(asocket* s, apacket::payload_type data) {
-    D("LS(%d): enqueue %zu", s->id, data.size());
-
-    s->packet_queue.append(std::move(data));
-    switch (local_socket_flush_incoming(s)) {
-        case SocketFlushResult::Destroyed:
-            return -1;
-
-        case SocketFlushResult::TryAgain:
-            return 1;
-
-        case SocketFlushResult::Completed:
-            return 0;
-    }
-
-    return !s->packet_queue.empty();
-}
-
-static void local_socket_ready(asocket* s) {
-    /* far side is ready for data, pay attention to
-       readable events */
-    fdevent_add(s->fde, FDE_READ);
-}
-
-struct ClosingSocket {
-    std::chrono::steady_clock::time_point begin;
-};
-
-// The standard (RFC 1122 - 4.2.2.13) says that if we call close on a
-// socket while we have pending data, a TCP RST should be sent to the
-// other end to notify it that we didn't read all of its data. However,
-// this can result in data that we've successfully written out to be dropped
-// on the other end. To avoid this, instead of immediately closing a
-// socket, call shutdown on it instead, and then read from the file
-// descriptor until we hit EOF or an error before closing.
-static void deferred_close(unique_fd fd) {
-    // Shutdown the socket in the outgoing direction only, so that
-    // we don't have the same problem on the opposite end.
-    adb_shutdown(fd.get(), SHUT_WR);
-    auto callback = [](fdevent* fde, unsigned event, void* arg) {
-        auto socket_info = static_cast<ClosingSocket*>(arg);
-        if (event & FDE_READ) {
-            ssize_t rc;
-            char buf[BUFSIZ];
-            while ((rc = adb_read(fde->fd.get(), buf, sizeof(buf))) > 0) {
-                continue;
-            }
-
-            if (rc == -1 && errno == EAGAIN) {
-                // There's potentially more data to read.
-                auto duration = std::chrono::steady_clock::now() - socket_info->begin;
-                if (duration > 1s) {
-                    LOG(WARNING) << "timeout expired while flushing socket, closing";
-                } else {
-                    return;
-                }
-            }
-        } else if (event & FDE_TIMEOUT) {
-            LOG(WARNING) << "timeout expired while flushing socket, closing";
-        }
-
-        // Either there was an error, we hit the end of the socket, or our timeout expired.
-        fdevent_destroy(fde);
-        delete socket_info;
-    };
-
-    ClosingSocket* socket_info = new ClosingSocket{
-            .begin = std::chrono::steady_clock::now(),
-    };
-
-    fdevent* fde = fdevent_create(fd.release(), callback, socket_info);
-    fdevent_add(fde, FDE_READ);
-    fdevent_set_timeout(fde, 1s);
-}
-
-// be sure to hold the socket list lock when calling this
-static void local_socket_destroy(asocket* s) {
-    int exit_on_close = s->exit_on_close;
-
-    D("LS(%d): destroying fde.fd=%d", s->id, s->fd);
-
-    deferred_close(fdevent_release(s->fde));
-
-    remove_socket(s);
-    delete s;
-
-    if (exit_on_close) {
-        D("local_socket_destroy: exiting");
-        exit(1);
-    }
-}
-
-static void local_socket_close(asocket* s) {
-    D("entered local_socket_close. LS(%d) fd=%d", s->id, s->fd);
-    std::lock_guard<std::recursive_mutex> lock(local_socket_list_lock);
-    if (s->peer) {
-        D("LS(%d): closing peer. peer->id=%d peer->fd=%d", s->id, s->peer->id, s->peer->fd);
-        /* Note: it's important to call shutdown before disconnecting from
-         * the peer, this ensures that remote sockets can still get the id
-         * of the local socket they're connected to, to send a CLOSE()
-         * protocol event. */
-        if (s->peer->shutdown) {
-            s->peer->shutdown(s->peer);
-        }
-        s->peer->peer = nullptr;
-        s->peer->close(s->peer);
-        s->peer = nullptr;
-    }
-
-    /* If we are already closing, or if there are no
-    ** pending packets, destroy immediately
-    */
-    if (s->closing || s->has_write_error || s->packet_queue.empty()) {
-        int id = s->id;
-        local_socket_destroy(s);
-        D("LS(%d): closed", id);
-        return;
-    }
-
-    /* otherwise, put on the closing list
-    */
-    D("LS(%d): closing", s->id);
-    s->closing = 1;
-    fdevent_del(s->fde, FDE_READ);
-    remove_socket(s);
-    D("LS(%d): put on socket_closing_list fd=%d", s->id, s->fd);
-    local_socket_closing_list.push_back(s);
-    CHECK_EQ(FDE_WRITE, s->fde->state & FDE_WRITE);
-}
-
-static void local_socket_event_func(int fd, unsigned ev, void* _s) {
-    asocket* s = reinterpret_cast<asocket*>(_s);
-    D("LS(%d): event_func(fd=%d(==%d), ev=%04x)", s->id, s->fd, fd, ev);
-
-    /* put the FDE_WRITE processing before the FDE_READ
-    ** in order to simplify the code.
-    */
-    if (ev & FDE_WRITE) {
-        switch (local_socket_flush_incoming(s)) {
-            case SocketFlushResult::Destroyed:
-                return;
-
-            case SocketFlushResult::TryAgain:
-                break;
-
-            case SocketFlushResult::Completed:
-                s->peer->ready(s->peer);
-                break;
-        }
-    }
-
-    if (ev & FDE_READ) {
-        if (!local_socket_flush_outgoing(s)) {
-            return;
-        }
-    }
-
-    if (ev & FDE_ERROR) {
-        /* this should be caught be the next read or write
-        ** catching it here means we may skip the last few
-        ** bytes of readable data.
-        */
-        D("LS(%d): FDE_ERROR (fd=%d)", s->id, s->fd);
-        return;
-    }
-}
-
-asocket* create_local_socket(unique_fd ufd) {
-    int fd = ufd.release();
-    asocket* s = new asocket();
-    s->fd = fd;
-    s->enqueue = local_socket_enqueue;
-    s->ready = local_socket_ready;
-    s->shutdown = nullptr;
-    s->close = local_socket_close;
-    install_local_socket(s);
-
-    s->fde = fdevent_create(fd, local_socket_event_func, s);
-    D("LS(%d): created (fd=%d)", s->id, s->fd);
-    return s;
-}
-
-asocket* create_local_service_socket(std::string_view name, atransport* transport) {
-#if !ADB_HOST
-    if (asocket* s = daemon_service_to_socket(name); s) {
-        return s;
-    }
-#endif
-    unique_fd fd = service_to_fd(name, transport);
-    if (fd < 0) {
-        return nullptr;
-    }
-
-    int fd_value = fd.get();
-    asocket* s = create_local_socket(std::move(fd));
-    LOG(VERBOSE) << "LS(" << s->id << "): bound to '" << name << "' via " << fd_value;
-
-#if !ADB_HOST
-    if ((name.starts_with("root:") && getuid() != 0 && __android_log_is_debuggable()) ||
-        (name.starts_with("unroot:") && getuid() == 0) || name.starts_with("usb:") ||
-        name.starts_with("tcpip:")) {
-        D("LS(%d): enabling exit_on_close", s->id);
-        s->exit_on_close = 1;
-    }
-#endif
-
-    return s;
-}
-
-static int remote_socket_enqueue(asocket* s, apacket::payload_type data) {
-    D("entered remote_socket_enqueue RS(%d) WRITE fd=%d peer.fd=%d", s->id, s->fd, s->peer->fd);
-    apacket* p = get_apacket();
-
-    p->msg.command = A_WRTE;
-    p->msg.arg0 = s->peer->id;
-    p->msg.arg1 = s->id;
-
-    if (data.size() > MAX_PAYLOAD) {
-        put_apacket(p);
-        return -1;
-    }
-
-    p->payload = std::move(data);
-    p->msg.data_length = p->payload.size();
-
-    send_packet(p, s->transport);
-    return 1;
-}
-
-static void remote_socket_ready(asocket* s) {
-    D("entered remote_socket_ready RS(%d) OKAY fd=%d peer.fd=%d", s->id, s->fd, s->peer->fd);
-    apacket* p = get_apacket();
-    p->msg.command = A_OKAY;
-    p->msg.arg0 = s->peer->id;
-    p->msg.arg1 = s->id;
-    send_packet(p, s->transport);
-}
-
-static void remote_socket_shutdown(asocket* s) {
-    D("entered remote_socket_shutdown RS(%d) CLOSE fd=%d peer->fd=%d", s->id, s->fd,
-      s->peer ? s->peer->fd : -1);
-    apacket* p = get_apacket();
-    p->msg.command = A_CLSE;
-    if (s->peer) {
-        p->msg.arg0 = s->peer->id;
-    }
-    p->msg.arg1 = s->id;
-    send_packet(p, s->transport);
-}
-
-static void remote_socket_close(asocket* s) {
-    if (s->peer) {
-        s->peer->peer = nullptr;
-        D("RS(%d) peer->close()ing peer->id=%d peer->fd=%d", s->id, s->peer->id, s->peer->fd);
-        s->peer->close(s->peer);
-    }
-    D("entered remote_socket_close RS(%d) CLOSE fd=%d peer->fd=%d", s->id, s->fd,
-      s->peer ? s->peer->fd : -1);
-    D("RS(%d): closed", s->id);
-    delete s;
-}
-
-// Create a remote socket to exchange packets with a remote service through transport
-// |t|. Where |id| is the socket id of the corresponding service on the other
-//  side of the transport (it is allocated by the remote side and _cannot_ be 0).
-// Returns a new non-NULL asocket handle.
-asocket* create_remote_socket(unsigned id, atransport* t) {
-    if (id == 0) {
-        LOG(FATAL) << "invalid remote socket id (0)";
-    }
-    asocket* s = new asocket();
-    s->id = id;
-    s->enqueue = remote_socket_enqueue;
-    s->ready = remote_socket_ready;
-    s->shutdown = remote_socket_shutdown;
-    s->close = remote_socket_close;
-    s->transport = t;
-
-    D("RS(%d): created", s->id);
-    return s;
-}
-
-void connect_to_remote(asocket* s, std::string_view destination) {
-    D("Connect_to_remote call RS(%d) fd=%d", s->id, s->fd);
-    apacket* p = get_apacket();
-
-    LOG(VERBOSE) << "LS(" << s->id << ": connect(" << destination << ")";
-    p->msg.command = A_OPEN;
-    p->msg.arg0 = s->id;
-
-    // adbd used to expect a null-terminated string.
-    // Keep doing so to maintain backward compatibility.
-    p->payload.resize(destination.size() + 1);
-    memcpy(p->payload.data(), destination.data(), destination.size());
-    p->payload[destination.size()] = '\0';
-    p->msg.data_length = p->payload.size();
-
-    CHECK_LE(p->msg.data_length, s->get_max_payload());
-
-    send_packet(p, s->transport);
-}
-
-/* this is used by magic sockets to rig local sockets to
-   send the go-ahead message when they connect */
-static void local_socket_ready_notify(asocket* s) {
-    s->ready = local_socket_ready;
-    s->shutdown = nullptr;
-    s->close = local_socket_close;
-    SendOkay(s->fd);
-    s->ready(s);
-}
-
-/* this is used by magic sockets to rig local sockets to
-   send the failure message if they are closed before
-   connected (to avoid closing them without a status message) */
-static void local_socket_close_notify(asocket* s) {
-    s->ready = local_socket_ready;
-    s->shutdown = nullptr;
-    s->close = local_socket_close;
-    SendFail(s->fd, "closed");
-    s->close(s);
-}
-
-static unsigned unhex(const char* s, int len) {
-    unsigned n = 0, c;
-
-    while (len-- > 0) {
-        switch ((c = *s++)) {
-            case '0':
-            case '1':
-            case '2':
-            case '3':
-            case '4':
-            case '5':
-            case '6':
-            case '7':
-            case '8':
-            case '9':
-                c -= '0';
-                break;
-            case 'a':
-            case 'b':
-            case 'c':
-            case 'd':
-            case 'e':
-            case 'f':
-                c = c - 'a' + 10;
-                break;
-            case 'A':
-            case 'B':
-            case 'C':
-            case 'D':
-            case 'E':
-            case 'F':
-                c = c - 'A' + 10;
-                break;
-            default:
-                return 0xffffffff;
-        }
-
-        n = (n << 4) | c;
-    }
-
-    return n;
-}
-
-#if ADB_HOST
-
-namespace internal {
-
-// Parses a host service string of the following format:
-//   * [tcp:|udp:]<serial>[:<port>]:<command>
-//   * <prefix>:<serial>:<command>
-// Where <port> must be a base-10 number and <prefix> may be any of {usb,product,model,device}.
-bool parse_host_service(std::string_view* out_serial, std::string_view* out_command,
-                        std::string_view full_service) {
-    if (full_service.empty()) {
-        return false;
-    }
-
-    std::string_view serial;
-    std::string_view command = full_service;
-    // Remove |count| bytes from the beginning of command and add them to |serial|.
-    auto consume = [&full_service, &serial, &command](size_t count) {
-        CHECK_LE(count, command.size());
-        if (!serial.empty()) {
-            CHECK_EQ(serial.data() + serial.size(), command.data());
-        }
-
-        serial = full_service.substr(0, serial.size() + count);
-        command.remove_prefix(count);
-    };
-
-    // Remove the trailing : from serial, and assign the values to the output parameters.
-    auto finish = [out_serial, out_command, &serial, &command] {
-        if (serial.empty() || command.empty()) {
-            return false;
-        }
-
-        CHECK_EQ(':', serial.back());
-        serial.remove_suffix(1);
-
-        *out_serial = serial;
-        *out_command = command;
-        return true;
-    };
-
-    static constexpr std::string_view prefixes[] = {
-            "usb:", "product:", "model:", "device:", "localfilesystem:"};
-    for (std::string_view prefix : prefixes) {
-        if (command.starts_with(prefix)) {
-            consume(prefix.size());
-
-            size_t offset = command.find_first_of(':');
-            if (offset == std::string::npos) {
-                return false;
-            }
-            consume(offset + 1);
-            return finish();
-        }
-    }
-
-    // For fastboot compatibility, ignore protocol prefixes.
-    if (command.starts_with("tcp:") || command.starts_with("udp:")) {
-        consume(4);
-        if (command.empty()) {
-            return false;
-        }
-    }
-    if (command.starts_with("vsock:")) {
-        // vsock serials are vsock:cid:port, which have an extra colon compared to tcp.
-        size_t next_colon = command.find(':');
-        if (next_colon == std::string::npos) {
-            return false;
-        }
-        consume(next_colon + 1);
-    }
-
-    bool found_address = false;
-    if (command[0] == '[') {
-        // Read an IPv6 address. `adb connect` creates the serial number from the canonical
-        // network address so it will always have the [] delimiters.
-        size_t ipv6_end = command.find_first_of(']');
-        if (ipv6_end != std::string::npos) {
-            consume(ipv6_end + 1);
-            if (command.empty()) {
-                // Nothing after the IPv6 address.
-                return false;
-            } else if (command[0] != ':') {
-                // Garbage after the IPv6 address.
-                return false;
-            }
-            consume(1);
-            found_address = true;
-        }
-    }
-
-    if (!found_address) {
-        // Scan ahead to the next colon.
-        size_t offset = command.find_first_of(':');
-        if (offset == std::string::npos) {
-            return false;
-        }
-        consume(offset + 1);
-    }
-
-    // We're either at the beginning of a port, or the command itself.
-    // Look for a port in between colons.
-    size_t next_colon = command.find_first_of(':');
-    if (next_colon == std::string::npos) {
-        // No colon, we must be at the command.
-        return finish();
-    }
-
-    bool port_valid = true;
-    if (command.size() <= next_colon) {
-        return false;
-    }
-
-    std::string_view port = command.substr(0, next_colon);
-    for (auto digit : port) {
-        if (!isdigit(digit)) {
-            // Port isn't a number.
-            port_valid = false;
-            break;
-        }
-    }
-
-    if (port_valid) {
-        consume(next_colon + 1);
-    }
-    return finish();
-}
-
-}  // namespace internal
-
-#endif  // ADB_HOST
-
-static int smart_socket_enqueue(asocket* s, apacket::payload_type data) {
-#if ADB_HOST
-    std::string_view service;
-    std::string_view serial;
-    TransportId transport_id = 0;
-    TransportType type = kTransportAny;
-#endif
-
-    D("SS(%d): enqueue %zu", s->id, data.size());
-
-    if (s->smart_socket_data.empty()) {
-        // TODO: Make this an IOVector?
-        s->smart_socket_data.assign(data.begin(), data.end());
-    } else {
-        std::copy(data.begin(), data.end(), std::back_inserter(s->smart_socket_data));
-    }
-
-    /* don't bother if we can't decode the length */
-    if (s->smart_socket_data.size() < 4) {
-        return 0;
-    }
-
-    uint32_t len = unhex(s->smart_socket_data.data(), 4);
-    if (len == 0 || len > MAX_PAYLOAD) {
-        D("SS(%d): bad size (%u)", s->id, len);
-        goto fail;
-    }
-
-    D("SS(%d): len is %u", s->id, len);
-    /* can't do anything until we have the full header */
-    if ((len + 4) > s->smart_socket_data.size()) {
-        D("SS(%d): waiting for %zu more bytes", s->id, len + 4 - s->smart_socket_data.size());
-        return 0;
-    }
-
-    s->smart_socket_data[len + 4] = 0;
-
-    D("SS(%d): '%s'", s->id, (char*)(s->smart_socket_data.data() + 4));
-
-#if ADB_HOST
-    service = std::string_view(s->smart_socket_data).substr(4);
-
-    // TODO: These should be handled in handle_host_request.
-    if (android::base::ConsumePrefix(&service, "host-serial:")) {
-        // serial number should follow "host:" and could be a host:port string.
-        if (!internal::parse_host_service(&serial, &service, service)) {
-            LOG(ERROR) << "SS(" << s->id << "): failed to parse host service: " << service;
-            goto fail;
-        }
-    } else if (android::base::ConsumePrefix(&service, "host-transport-id:")) {
-        if (!ParseUint(&transport_id, service, &service)) {
-            LOG(ERROR) << "SS(" << s->id << "): failed to parse host transport id: " << service;
-            return -1;
-        }
-        if (!android::base::ConsumePrefix(&service, ":")) {
-            LOG(ERROR) << "SS(" << s->id << "): host-transport-id without command";
-            return -1;
-        }
-    } else if (android::base::ConsumePrefix(&service, "host-usb:")) {
-        type = kTransportUsb;
-    } else if (android::base::ConsumePrefix(&service, "host-local:")) {
-        type = kTransportLocal;
-    } else if (android::base::ConsumePrefix(&service, "host:")) {
-        type = kTransportAny;
-    } else {
-        service = std::string_view{};
-    }
-
-    if (!service.empty()) {
-        asocket* s2;
-
-        // Some requests are handled immediately -- in that case the handle_host_request() routine
-        // has sent the OKAY or FAIL message and all we have to do is clean up.
-        auto host_request_result = handle_host_request(
-                service, type, serial.empty() ? nullptr : std::string(serial).c_str(), transport_id,
-                s->peer->fd, s);
-
-        switch (host_request_result) {
-            case HostRequestResult::Handled:
-                LOG(VERBOSE) << "SS(" << s->id << "): handled host service '" << service << "'";
-                goto fail;
-
-            case HostRequestResult::SwitchedTransport:
-                D("SS(%d): okay transport", s->id);
-                s->smart_socket_data.clear();
-                return 0;
-
-            case HostRequestResult::Unhandled:
-                break;
-        }
-
-        /* try to find a local service with this name.
-        ** if no such service exists, we'll fail out
-        ** and tear down here.
-        */
-        // TODO: Convert to string_view.
-        s2 = host_service_to_socket(service, serial, transport_id);
-        if (s2 == nullptr) {
-            LOG(VERBOSE) << "SS(" << s->id << "): couldn't create host service '" << service << "'";
-            SendFail(s->peer->fd, "unknown host service");
-            goto fail;
-        }
-
-        /* we've connected to a local host service,
-        ** so we make our peer back into a regular
-        ** local socket and bind it to the new local
-        ** service socket, acknowledge the successful
-        ** connection, and close this smart socket now
-        ** that its work is done.
-        */
-        SendOkay(s->peer->fd);
-
-        s->peer->ready = local_socket_ready;
-        s->peer->shutdown = nullptr;
-        s->peer->close = local_socket_close;
-        s->peer->peer = s2;
-        s2->peer = s->peer;
-        s->peer = nullptr;
-        D("SS(%d): okay", s->id);
-        s->close(s);
-
-        /* initial state is "ready" */
-        s2->ready(s2);
-        return 0;
-    }
-#else /* !ADB_HOST */
-    if (s->transport == nullptr) {
-        std::string error_msg = "unknown failure";
-        s->transport = acquire_one_transport(kTransportAny, nullptr, 0, nullptr, &error_msg);
-        if (s->transport == nullptr) {
-            SendFail(s->peer->fd, error_msg);
-            goto fail;
-        }
-    }
-#endif
-
-    if (!s->transport) {
-        SendFail(s->peer->fd, "device offline (no transport)");
-        goto fail;
-    } else if (!ConnectionStateIsOnline(s->transport->GetConnectionState())) {
-        /* if there's no remote we fail the connection
-         ** right here and terminate it
-         */
-        SendFail(s->peer->fd, "device offline (transport offline)");
-        goto fail;
-    }
-
-    /* instrument our peer to pass the success or fail
-    ** message back once it connects or closes, then
-    ** detach from it, request the connection, and
-    ** tear down
-    */
-    s->peer->ready = local_socket_ready_notify;
-    s->peer->shutdown = nullptr;
-    s->peer->close = local_socket_close_notify;
-    s->peer->peer = nullptr;
-    /* give him our transport and upref it */
-    s->peer->transport = s->transport;
-
-    connect_to_remote(s->peer, std::string_view(s->smart_socket_data).substr(4));
-    s->peer = nullptr;
-    s->close(s);
-    return 1;
-
-fail:
-    /* we're going to close our peer as a side-effect, so
-    ** return -1 to signal that state to the local socket
-    ** who is enqueueing against us
-    */
-    s->close(s);
-    return -1;
-}
-
-static void smart_socket_ready(asocket* s) {
-    D("SS(%d): ready", s->id);
-}
-
-static void smart_socket_close(asocket* s) {
-    D("SS(%d): closed", s->id);
-    if (s->peer) {
-        s->peer->peer = nullptr;
-        s->peer->close(s->peer);
-        s->peer = nullptr;
-    }
-    delete s;
-}
-
-static asocket* create_smart_socket(void) {
-    D("Creating smart socket");
-    asocket* s = new asocket();
-    s->enqueue = smart_socket_enqueue;
-    s->ready = smart_socket_ready;
-    s->shutdown = nullptr;
-    s->close = smart_socket_close;
-
-    D("SS(%d)", s->id);
-    return s;
-}
-
-void connect_to_smartsocket(asocket* s) {
-    D("Connecting to smart socket");
-    asocket* ss = create_smart_socket();
-    s->peer = ss;
-    ss->peer = s;
-    s->ready(s);
-}
-
-size_t asocket::get_max_payload() const {
-    size_t max_payload = MAX_PAYLOAD;
-    if (transport) {
-        max_payload = std::min(max_payload, transport->get_max_payload());
-    }
-    if (peer && peer->transport) {
-        max_payload = std::min(max_payload, peer->transport->get_max_payload());
-    }
-    return max_payload;
-}
diff --git a/adb/sockets.dia b/adb/sockets.dia
deleted file mode 100644
index c626f20..0000000
--- a/adb/sockets.dia
+++ /dev/null
Binary files differ
diff --git a/adb/sysdeps.h b/adb/sysdeps.h
deleted file mode 100644
index 1eed0d2..0000000
--- a/adb/sysdeps.h
+++ /dev/null
@@ -1,719 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-/* this file contains system-dependent definitions used by ADB
- * they're related to threads, sockets and file descriptors
- */
-
-#ifdef __CYGWIN__
-#  undef _WIN32
-#endif
-
-#include <errno.h>
-
-#include <string>
-#include <string_view>
-#include <vector>
-
-// Include this before open/close/unlink are defined as macros below.
-#include <android-base/errors.h>
-#include <android-base/macros.h>
-#include <android-base/off64_t.h>
-#include <android-base/unique_fd.h>
-#include <android-base/utf8.h>
-
-#include "adb_unique_fd.h"
-#include "sysdeps/errno.h"
-#include "sysdeps/network.h"
-#include "sysdeps/stat.h"
-
-#if defined(__APPLE__)
-static inline void* mempcpy(void* dst, const void* src, size_t n) {
-    return static_cast<char*>(memcpy(dst, src, n)) + n;
-}
-#endif
-
-#ifdef _WIN32
-
-// Clang-only nullability specifiers
-#define _Nonnull
-#define _Nullable
-
-#include <ctype.h>
-#include <direct.h>
-#include <dirent.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <io.h>
-#include <process.h>
-#include <stdint.h>
-#include <sys/stat.h>
-#include <utime.h>
-#include <windows.h>
-#include <winsock2.h>
-#include <ws2tcpip.h>
-
-#include <memory>   // unique_ptr
-#include <string>
-
-#define OS_PATH_SEPARATORS "\\/"
-#define OS_PATH_SEPARATOR '\\'
-#define OS_PATH_SEPARATOR_STR "\\"
-#define ENV_PATH_SEPARATOR_STR ";"
-
-static inline bool adb_is_separator(char c) {
-    return c == '\\' || c == '/';
-}
-
-extern int adb_thread_setname(const std::string& name);
-
-static inline void close_on_exec(borrowed_fd fd) {
-    /* nothing really */
-}
-
-extern int adb_unlink(const char* path);
-#undef unlink
-#define unlink ___xxx_unlink
-
-extern int adb_mkdir(const std::string& path, int mode);
-#undef mkdir
-#define mkdir ___xxx_mkdir
-
-extern int adb_rename(const char* oldpath, const char* newpath);
-
-// See the comments for the !defined(_WIN32) versions of adb_*().
-extern int adb_open(const char* path, int options);
-extern int adb_creat(const char* path, int mode);
-extern int adb_read(borrowed_fd fd, void* buf, int len);
-extern int adb_pread(borrowed_fd fd, void* buf, int len, off64_t offset);
-extern int adb_write(borrowed_fd fd, const void* buf, int len);
-extern int adb_pwrite(borrowed_fd fd, const void* buf, int len, off64_t offset);
-extern int64_t adb_lseek(borrowed_fd fd, int64_t pos, int where);
-extern int adb_shutdown(borrowed_fd fd, int direction = SHUT_RDWR);
-extern int adb_close(int fd);
-extern int adb_register_socket(SOCKET s);
-extern HANDLE adb_get_os_handle(borrowed_fd fd);
-
-extern int adb_gethostname(char* name, size_t len);
-extern int adb_getlogin_r(char* buf, size_t bufsize);
-
-// See the comments for the !defined(_WIN32) version of unix_close().
-static inline int unix_close(int fd) {
-    return close(fd);
-}
-#undef close
-#define close ____xxx_close
-
-// Like unix_read(), but may return EINTR.
-extern int unix_read_interruptible(borrowed_fd fd, void* buf, size_t len);
-
-// See the comments for the !defined(_WIN32) version of unix_read().
-static inline int unix_read(borrowed_fd fd, void* buf, size_t len) {
-    return TEMP_FAILURE_RETRY(unix_read_interruptible(fd, buf, len));
-}
-
-#undef   read
-#define  read  ___xxx_read
-
-#undef pread
-#define pread ___xxx_pread
-
-// See the comments for the !defined(_WIN32) version of unix_write().
-static inline int unix_write(borrowed_fd fd, const void* buf, size_t len) {
-    return write(fd.get(), buf, len);
-}
-#undef   write
-#define  write  ___xxx_write
-
-#undef pwrite
-#define pwrite ___xxx_pwrite
-
-// See the comments for the !defined(_WIN32) version of unix_lseek().
-static inline int unix_lseek(borrowed_fd fd, int pos, int where) {
-    return lseek(fd.get(), pos, where);
-}
-#undef lseek
-#define lseek ___xxx_lseek
-
-// See the comments for the !defined(_WIN32) version of adb_open_mode().
-static inline int adb_open_mode(const char* path, int options, int mode) {
-    return adb_open(path, options);
-}
-
-// See the comments for the !defined(_WIN32) version of unix_open().
-extern int unix_open(std::string_view path, int options, ...);
-#define  open    ___xxx_unix_open
-
-// Checks if |fd| corresponds to a console.
-// Standard Windows isatty() returns 1 for both console FDs and character
-// devices like NUL. unix_isatty() performs some extra checking to only match
-// console FDs.
-// |fd| must be a real file descriptor, meaning STDxx_FILENO or unix_open() FDs
-// will work but adb_open() FDs will not. Additionally the OS handle associated
-// with |fd| must have GENERIC_READ access (which console FDs have by default).
-// Returns 1 if |fd| is a console FD, 0 otherwise. The value of errno after
-// calling this function is unreliable and should not be used.
-int unix_isatty(borrowed_fd fd);
-#define  isatty  ___xxx_isatty
-
-int network_inaddr_any_server(int port, int type, std::string* error);
-
-inline int network_local_client(const char* name, int namespace_id, int type, std::string* error) {
-    abort();
-}
-
-inline int network_local_server(const char* name, int namespace_id, int type, std::string* error) {
-    abort();
-}
-
-int network_connect(const std::string& host, int port, int type, int timeout,
-                    std::string* error);
-
-extern int adb_socket_accept(borrowed_fd serverfd, struct sockaddr* addr, socklen_t* addrlen);
-
-#undef   accept
-#define  accept  ___xxx_accept
-
-// Returns the local port number of a bound socket, or -1 on failure.
-int adb_socket_get_local_port(borrowed_fd fd);
-
-extern int adb_setsockopt(borrowed_fd fd, int level, int optname, const void* optval,
-                          socklen_t optlen);
-
-#undef   setsockopt
-#define  setsockopt  ___xxx_setsockopt
-
-extern int adb_socketpair(int sv[2]);
-
-struct adb_pollfd {
-    int fd;
-    short events;
-    short revents;
-};
-extern int adb_poll(adb_pollfd* fds, size_t nfds, int timeout);
-#define poll ___xxx_poll
-
-static inline int adb_is_absolute_host_path(const char* path) {
-    return isalpha(path[0]) && path[1] == ':' && path[2] == '\\';
-}
-
-// UTF-8 versions of POSIX APIs.
-extern DIR* adb_opendir(const char* dirname);
-extern struct dirent* adb_readdir(DIR* dir);
-extern int adb_closedir(DIR* dir);
-
-extern int adb_utime(const char *, struct utimbuf *);
-extern int adb_chmod(const char *, int);
-
-extern int adb_vfprintf(FILE* stream, const char* format, va_list ap)
-        __attribute__((__format__(__printf__, 2, 0)));
-extern int adb_vprintf(const char* format, va_list ap) __attribute__((__format__(__printf__, 1, 0)));
-extern int adb_fprintf(FILE* stream, const char* format, ...)
-        __attribute__((__format__(__printf__, 2, 3)));
-extern int adb_printf(const char* format, ...) __attribute__((__format__(__printf__, 1, 2)));
-
-extern int adb_fputs(const char* buf, FILE* stream);
-extern int adb_fputc(int ch, FILE* stream);
-extern int adb_putchar(int ch);
-extern int adb_puts(const char* buf);
-extern size_t adb_fwrite(const void* ptr, size_t size, size_t nmemb, FILE* stream);
-
-extern FILE* adb_fopen(const char* f, const char* m);
-
-extern char* adb_getenv(const char* name);
-
-extern char* adb_getcwd(char* buf, int size);
-
-// Remap calls to POSIX APIs to our UTF-8 versions.
-#define opendir adb_opendir
-#define readdir adb_readdir
-#define closedir adb_closedir
-#define rewinddir rewinddir_utf8_not_yet_implemented
-#define telldir telldir_utf8_not_yet_implemented
-// Some compiler's C++ headers have members named seekdir, so we can't do the
-// macro technique and instead cause a link error if seekdir is called.
-inline void seekdir(DIR*, long) {
-    extern int seekdir_utf8_not_yet_implemented;
-    seekdir_utf8_not_yet_implemented = 1;
-}
-
-#define utime adb_utime
-#define chmod adb_chmod
-
-#define vfprintf adb_vfprintf
-#define vprintf adb_vprintf
-#define fprintf adb_fprintf
-#define printf adb_printf
-#define fputs adb_fputs
-#define fputc adb_fputc
-// putc may be a macro, so if so, undefine it, so that we can redefine it.
-#undef putc
-#define putc(c, s) adb_fputc(c, s)
-#define putchar adb_putchar
-#define puts adb_puts
-#define fwrite adb_fwrite
-
-#define fopen adb_fopen
-#define freopen freopen_utf8_not_yet_implemented
-
-#define getenv adb_getenv
-#define putenv putenv_utf8_not_yet_implemented
-#define setenv setenv_utf8_not_yet_implemented
-#define unsetenv unsetenv_utf8_not_yet_implemented
-
-#define getcwd adb_getcwd
-
-// A very simple wrapper over a launched child process
-class Process {
-  public:
-    constexpr explicit Process(HANDLE h = nullptr) : h_(h) {}
-    constexpr Process(Process&& other) : h_(std::exchange(other.h_, nullptr)) {}
-    ~Process() { close(); }
-    constexpr explicit operator bool() const { return h_ != nullptr; }
-
-    void wait() {
-        if (*this) {
-            ::WaitForSingleObject(h_, INFINITE);
-            close();
-        }
-    }
-    void kill() {
-        if (*this) {
-            ::TerminateProcess(h_, -1);
-        }
-    }
-
-  private:
-    DISALLOW_COPY_AND_ASSIGN(Process);
-
-    void close() {
-        if (*this) {
-            ::CloseHandle(h_);
-            h_ = nullptr;
-        }
-    }
-
-    HANDLE h_;
-};
-
-Process adb_launch_process(std::string_view executable, std::vector<std::string> args,
-                           std::initializer_list<int> fds_to_inherit = {});
-
-// Helper class to convert UTF-16 argv from wmain() to UTF-8 args that can be
-// passed to main().
-class NarrowArgs {
-public:
-    NarrowArgs(int argc, wchar_t** argv);
-    ~NarrowArgs();
-
-    inline char** data() {
-        return narrow_args;
-    }
-
-private:
-    char** narrow_args;
-};
-
-// Windows HANDLE values only use 32-bits of the type, even on 64-bit machines,
-// so they can fit in an int. To convert back, we just need to sign-extend.
-// https://msdn.microsoft.com/en-us/library/windows/desktop/aa384203%28v=vs.85%29.aspx
-// Note that this does not make a HANDLE value work with APIs like open(), nor
-// does this make a value from open() passable to APIs taking a HANDLE. This
-// just lets you take a HANDLE, pass it around as an int, and then use it again
-// as a HANDLE.
-inline int cast_handle_to_int(const HANDLE h) {
-    // truncate
-    return static_cast<int>(reinterpret_cast<INT_PTR>(h));
-}
-
-inline HANDLE cast_int_to_handle(const int fd) {
-    // sign-extend
-    return reinterpret_cast<HANDLE>(static_cast<INT_PTR>(fd));
-}
-
-// Deleter for unique_handle. Adapted from many sources, including:
-// http://stackoverflow.com/questions/14841396/stdunique-ptr-deleters-and-the-win32-api
-// https://visualstudiomagazine.com/articles/2013/09/01/get-a-handle-on-the-windows-api.aspx
-class handle_deleter {
-public:
-    typedef HANDLE pointer;
-
-    void operator()(HANDLE h);
-};
-
-// Like std::unique_ptr, but for Windows HANDLE objects that should be
-// CloseHandle()'d. Operator bool() only checks if the handle != nullptr,
-// but does not check if the handle != INVALID_HANDLE_VALUE.
-typedef std::unique_ptr<HANDLE, handle_deleter> unique_handle;
-
-namespace internal {
-
-size_t ParseCompleteUTF8(const char* first, const char* last, std::vector<char>* remaining_bytes);
-
-}
-
-#else /* !_WIN32 a.k.a. Unix */
-
-#include <fcntl.h>
-#include <netdb.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <poll.h>
-#include <pthread.h>
-#include <signal.h>
-#include <stdarg.h>
-#include <stdint.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/wait.h>
-#include <unistd.h>
-
-#include <string>
-
-#include <cutils/sockets.h>
-
-#define OS_PATH_SEPARATORS "/"
-#define OS_PATH_SEPARATOR '/'
-#define OS_PATH_SEPARATOR_STR "/"
-#define ENV_PATH_SEPARATOR_STR ":"
-
-static inline bool adb_is_separator(char c) {
-    return c == '/';
-}
-
-static inline int get_fd_flags(borrowed_fd fd) {
-    return fcntl(fd.get(), F_GETFD);
-}
-
-static inline void close_on_exec(borrowed_fd fd) {
-    int flags = get_fd_flags(fd);
-    if (flags >= 0 && (flags & FD_CLOEXEC) == 0) {
-        fcntl(fd.get(), F_SETFD, flags | FD_CLOEXEC);
-    }
-}
-
-// Open a file and return a file descriptor that may be used with unix_read(),
-// unix_write(), unix_close(), but not adb_read(), adb_write(), adb_close().
-//
-// On Unix, this is based on open(), so the file descriptor is a real OS file
-// descriptor, but the Windows implementation (in sysdeps_win32.cpp) returns a
-// file descriptor that can only be used with C Runtime APIs (which are wrapped
-// by unix_read(), unix_write(), unix_close()). Also, the C Runtime has
-// configurable CR/LF translation which defaults to text mode, but is settable
-// with _setmode().
-static inline int unix_open(std::string_view path, int options, ...) {
-    std::string zero_terminated(path.begin(), path.end());
-    if ((options & O_CREAT) == 0) {
-        return TEMP_FAILURE_RETRY(open(zero_terminated.c_str(), options));
-    } else {
-        int mode;
-        va_list args;
-        va_start(args, options);
-        mode = va_arg(args, int);
-        va_end(args);
-        return TEMP_FAILURE_RETRY(open(zero_terminated.c_str(), options, mode));
-    }
-}
-
-// Similar to the two-argument adb_open(), but takes a mode parameter for file
-// creation. See adb_open() for more info.
-static inline int adb_open_mode(const char* pathname, int options, int mode) {
-    return TEMP_FAILURE_RETRY(open(pathname, options, mode));
-}
-
-// Open a file and return a file descriptor that may be used with adb_read(),
-// adb_write(), adb_close(), but not unix_read(), unix_write(), unix_close().
-//
-// On Unix, this is based on open(), but the Windows implementation (in
-// sysdeps_win32.cpp) uses Windows native file I/O and bypasses the C Runtime
-// and its CR/LF translation. The returned file descriptor should be used with
-// adb_read(), adb_write(), adb_close(), etc.
-static inline int adb_open(const char* pathname, int options) {
-    int fd = TEMP_FAILURE_RETRY(open(pathname, options));
-    if (fd < 0) return -1;
-    close_on_exec(fd);
-    return fd;
-}
-#undef open
-#define open ___xxx_open
-
-static inline int adb_shutdown(borrowed_fd fd, int direction = SHUT_RDWR) {
-    return shutdown(fd.get(), direction);
-}
-
-#undef shutdown
-#define shutdown ____xxx_shutdown
-
-// Closes a file descriptor that came from adb_open() or adb_open_mode(), but
-// not designed to take a file descriptor from unix_open(). See the comments
-// for adb_open() for more info.
-inline int adb_close(int fd) {
-    return close(fd);
-}
-#undef close
-#define close ____xxx_close
-
-// On Windows, ADB has an indirection layer for file descriptors. If we get a
-// Win32 SOCKET object from an external library, we have to map it in to that
-// indirection layer, which this does.
-inline int adb_register_socket(int s) {
-    return s;
-}
-
-static inline int adb_gethostname(char* name, size_t len) {
-    return gethostname(name, len);
-}
-
-static inline int adb_getlogin_r(char* buf, size_t bufsize) {
-    return getlogin_r(buf, bufsize);
-}
-
-static inline int adb_read(borrowed_fd fd, void* buf, size_t len) {
-    return TEMP_FAILURE_RETRY(read(fd.get(), buf, len));
-}
-
-static inline int adb_pread(borrowed_fd fd, void* buf, size_t len, off64_t offset) {
-#if defined(__APPLE__)
-    return TEMP_FAILURE_RETRY(pread(fd.get(), buf, len, offset));
-#else
-    return TEMP_FAILURE_RETRY(pread64(fd.get(), buf, len, offset));
-#endif
-}
-
-// Like unix_read(), but does not handle EINTR.
-static inline int unix_read_interruptible(borrowed_fd fd, void* buf, size_t len) {
-    return read(fd.get(), buf, len);
-}
-
-#undef read
-#define read ___xxx_read
-#undef pread
-#define pread ___xxx_pread
-
-static inline int adb_write(borrowed_fd fd, const void* buf, size_t len) {
-    return TEMP_FAILURE_RETRY(write(fd.get(), buf, len));
-}
-
-static inline int adb_pwrite(int fd, const void* buf, size_t len, off64_t offset) {
-#if defined(__APPLE__)
-    return TEMP_FAILURE_RETRY(pwrite(fd, buf, len, offset));
-#else
-    return TEMP_FAILURE_RETRY(pwrite64(fd, buf, len, offset));
-#endif
-}
-
-#undef   write
-#define  write  ___xxx_write
-#undef pwrite
-#define pwrite ___xxx_pwrite
-
-static inline int64_t adb_lseek(borrowed_fd fd, int64_t pos, int where) {
-#if defined(__APPLE__)
-    return lseek(fd.get(), pos, where);
-#else
-    return lseek64(fd.get(), pos, where);
-#endif
-}
-#undef lseek
-#define lseek ___xxx_lseek
-
-static inline int adb_unlink(const char* path) {
-    return unlink(path);
-}
-#undef unlink
-#define unlink ___xxx_unlink
-
-static inline int adb_creat(const char* path, int mode) {
-    int fd = TEMP_FAILURE_RETRY(creat(path, mode));
-
-    if (fd < 0) return -1;
-
-    close_on_exec(fd);
-    return fd;
-}
-#undef creat
-#define creat ___xxx_creat
-
-static inline int unix_isatty(borrowed_fd fd) {
-    return isatty(fd.get());
-}
-#define isatty ___xxx_isatty
-
-// Helper for network_* functions.
-inline int _fd_set_error_str(int fd, std::string* error) {
-    if (fd == -1) {
-        *error = strerror(errno);
-    }
-    return fd;
-}
-
-inline int network_inaddr_any_server(int port, int type, std::string* error) {
-    return _fd_set_error_str(socket_inaddr_any_server(port, type), error);
-}
-
-inline int network_local_client(const char* name, int namespace_id, int type, std::string* error) {
-    return _fd_set_error_str(socket_local_client(name, namespace_id, type), error);
-}
-
-inline int network_local_server(const char* name, int namespace_id, int type, std::string* error) {
-    return _fd_set_error_str(socket_local_server(name, namespace_id, type), error);
-}
-
-int network_connect(const std::string& host, int port, int type, int timeout, std::string* error);
-
-static inline int adb_socket_accept(borrowed_fd serverfd, struct sockaddr* addr,
-                                    socklen_t* addrlen) {
-    int fd;
-
-    fd = TEMP_FAILURE_RETRY(accept(serverfd.get(), addr, addrlen));
-    if (fd >= 0) close_on_exec(fd);
-
-    return fd;
-}
-
-#undef accept
-#define accept ___xxx_accept
-
-inline int adb_socket_get_local_port(borrowed_fd fd) {
-    return socket_get_local_port(fd.get());
-}
-
-// Operate on a file descriptor returned from unix_open() or a well-known file
-// descriptor such as STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO.
-//
-// On Unix, unix_read(), unix_write(), unix_close() map to adb_read(),
-// adb_write(), adb_close() (which all map to Unix system calls), but the
-// Windows implementations (in the ifdef above and in sysdeps_win32.cpp) call
-// into the C Runtime and its configurable CR/LF translation (which is settable
-// via _setmode()).
-#define unix_read adb_read
-#define unix_write adb_write
-#define unix_lseek adb_lseek
-#define unix_close adb_close
-
-static inline int adb_thread_setname(const std::string& name) {
-#ifdef __APPLE__
-    return pthread_setname_np(name.c_str());
-#else
-    // Both bionic and glibc's pthread_setname_np fails rather than truncating long strings.
-    // glibc doesn't have strlcpy, so we have to fake it.
-    char buf[16];  // MAX_TASK_COMM_LEN, but that's not exported by the kernel headers.
-    strncpy(buf, name.c_str(), sizeof(buf) - 1);
-    buf[sizeof(buf) - 1] = '\0';
-    return pthread_setname_np(pthread_self(), buf);
-#endif
-}
-
-static inline int adb_setsockopt(borrowed_fd fd, int level, int optname, const void* optval,
-                                 socklen_t optlen) {
-    return setsockopt(fd.get(), level, optname, optval, optlen);
-}
-
-#undef setsockopt
-#define setsockopt ___xxx_setsockopt
-
-static inline int unix_socketpair(int d, int type, int protocol, int sv[2]) {
-    return socketpair(d, type, protocol, sv);
-}
-
-static inline int adb_socketpair(int sv[2]) {
-    int rc;
-
-    rc = unix_socketpair(AF_UNIX, SOCK_STREAM, 0, sv);
-    if (rc < 0) return -1;
-
-    close_on_exec(sv[0]);
-    close_on_exec(sv[1]);
-    return 0;
-}
-
-#undef socketpair
-#define socketpair ___xxx_socketpair
-
-typedef struct pollfd adb_pollfd;
-static inline int adb_poll(adb_pollfd* fds, size_t nfds, int timeout) {
-    return TEMP_FAILURE_RETRY(poll(fds, nfds, timeout));
-}
-
-#define poll ___xxx_poll
-
-static inline int adb_mkdir(const std::string& path, int mode) {
-    return mkdir(path.c_str(), mode);
-}
-
-#undef mkdir
-#define mkdir ___xxx_mkdir
-
-static inline int adb_rename(const char* oldpath, const char* newpath) {
-    return rename(oldpath, newpath);
-}
-
-static inline int adb_is_absolute_host_path(const char* path) {
-    return path[0] == '/';
-}
-
-static inline int adb_get_os_handle(borrowed_fd fd) {
-    return fd.get();
-}
-
-// A very simple wrapper over a launched child process
-class Process {
-  public:
-    constexpr explicit Process(pid_t pid) : pid_(pid) {}
-    constexpr Process(Process&& other) : pid_(std::exchange(other.pid_, -1)) {}
-
-    constexpr explicit operator bool() const { return pid_ >= 0; }
-
-    void wait() {
-        if (*this) {
-            int status;
-            ::waitpid(pid_, &status, 0);
-            pid_ = -1;
-        }
-    }
-    void kill() {
-        if (*this) {
-            ::kill(pid_, SIGTERM);
-        }
-    }
-
-  private:
-    DISALLOW_COPY_AND_ASSIGN(Process);
-
-    pid_t pid_;
-};
-
-Process adb_launch_process(std::string_view executable, std::vector<std::string> args,
-                           std::initializer_list<int> fds_to_inherit = {});
-
-#endif /* !_WIN32 */
-
-static inline void disable_tcp_nagle(borrowed_fd fd) {
-    int off = 1;
-    adb_setsockopt(fd.get(), IPPROTO_TCP, TCP_NODELAY, &off, sizeof(off));
-}
-
-// Sets TCP socket |fd| to send a keepalive TCP message every |interval_sec| seconds. Set
-// |interval_sec| to 0 to disable keepalives. If keepalives are enabled, the connection will be
-// configured to drop after 10 missed keepalives. Returns true on success.
-bool set_tcp_keepalive(borrowed_fd fd, int interval_sec);
-
-#if defined(_WIN32)
-// Win32 defines ERROR, which we don't need, but which conflicts with google3 logging.
-#undef ERROR
-#endif
diff --git a/adb/sysdeps/chrono.h b/adb/sysdeps/chrono.h
deleted file mode 100644
index 5c5af7c..0000000
--- a/adb/sysdeps/chrono.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <chrono>
-
-using namespace std::chrono_literals;
diff --git a/adb/sysdeps/errno.cpp b/adb/sysdeps/errno.cpp
deleted file mode 100644
index 9a37ea2..0000000
--- a/adb/sysdeps/errno.cpp
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "sysdeps/errno.h"
-
-#include <errno.h>
-
-#include <thread>
-#include <unordered_map>
-#include <utility>
-
-#include "adb.h"
-
-// Use the linux asm-generic values for errno (which are used on all android archs but mips).
-#define ERRNO_VALUES()             \
-    ERRNO_VALUE(EACCES, 13);       \
-    ERRNO_VALUE(EEXIST, 17);       \
-    ERRNO_VALUE(EFAULT, 14);       \
-    ERRNO_VALUE(EFBIG, 27);        \
-    ERRNO_VALUE(EINTR, 4);         \
-    ERRNO_VALUE(EINVAL, 22);       \
-    ERRNO_VALUE(EIO, 5);           \
-    ERRNO_VALUE(EISDIR, 21);       \
-    ERRNO_VALUE(ELOOP, 40);        \
-    ERRNO_VALUE(EMFILE, 24);       \
-    ERRNO_VALUE(ENAMETOOLONG, 36); \
-    ERRNO_VALUE(ENFILE, 23);       \
-    ERRNO_VALUE(ENOENT, 2);        \
-    ERRNO_VALUE(ENOMEM, 12);       \
-    ERRNO_VALUE(ENOSPC, 28);       \
-    ERRNO_VALUE(ENOTDIR, 20);      \
-    ERRNO_VALUE(EOVERFLOW, 75);    \
-    ERRNO_VALUE(EPERM, 1);         \
-    ERRNO_VALUE(EROFS, 30);        \
-    ERRNO_VALUE(ETXTBSY, 26)
-
-// Make sure these values are actually correct.
-#if defined(__linux__) && !defined(__mips__)
-#define ERRNO_VALUE(error_name, wire_value) static_assert((error_name) == (wire_value), "")
-ERRNO_VALUES();
-#undef ERRNO_VALUE
-#endif
-
-static std::unordered_map<int, int>* generate_host_to_wire() {
-    auto result = new std::unordered_map<int, int>();
-#define ERRNO_VALUE(error_name, wire_value) \
-    result->insert(std::make_pair((error_name), (wire_value)))
-    ERRNO_VALUES();
-#undef ERRNO_VALUE
-    return result;
-}
-
-static std::unordered_map<int, int>* generate_wire_to_host() {
-    auto result = new std::unordered_map<int, int>();
-#define ERRNO_VALUE(error_name, wire_value) \
-    result->insert(std::make_pair((wire_value), (error_name)))
-    ERRNO_VALUES();
-#undef ERRNO_VALUE
-    return result;
-}
-
-static std::unordered_map<int, int>& host_to_wire = *generate_host_to_wire();
-static std::unordered_map<int, int>& wire_to_host = *generate_wire_to_host();
-
-int errno_to_wire(int error) {
-    auto it = host_to_wire.find(error);
-    if (it == host_to_wire.end()) {
-        LOG(ERROR) << "failed to convert errno " << error << " (" << strerror(error) << ") to wire";
-
-        // Return EIO;
-        return 5;
-    }
-    return it->second;
-}
-
-int errno_from_wire(int error) {
-    auto it = host_to_wire.find(error);
-    if (it == host_to_wire.end()) {
-        LOG(ERROR) << "failed to convert errno " << error << " from wire";
-        return EIO;
-    }
-    return it->second;
-}
diff --git a/adb/sysdeps/errno.h b/adb/sysdeps/errno.h
deleted file mode 100644
index 72816b1..0000000
--- a/adb/sysdeps/errno.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <errno.h>
-#include <string.h>
-
-#if defined(_WIN32)
-char* adb_strerror(int err);
-#define strerror adb_strerror
-#endif
-
-// errno values differ between operating systems and between Linux architectures.
-// Arbitrarily select the Linux asm-generic values to use in the wire protocol.
-int errno_to_wire(int error);
-int errno_from_wire(int error);
diff --git a/adb/sysdeps/network.h b/adb/sysdeps/network.h
deleted file mode 100644
index fadd155..0000000
--- a/adb/sysdeps/network.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#pragma once
-
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <string>
-
-int network_loopback_client(int port, int type, std::string* error);
-int network_loopback_server(int port, int type, std::string* error, bool prefer_ipv4);
diff --git a/adb/sysdeps/posix/network.cpp b/adb/sysdeps/posix/network.cpp
deleted file mode 100644
index a4d9013..0000000
--- a/adb/sysdeps/posix/network.cpp
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "sysdeps/network.h"
-
-#include <errno.h>
-#include <netdb.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-
-#include <string>
-
-#include <android-base/logging.h>
-#include <android-base/stringprintf.h>
-#include <cutils/sockets.h>
-
-#include "adb_unique_fd.h"
-
-static void set_error(std::string* error) {
-    if (error) {
-        *error = strerror(errno);
-    }
-}
-
-static sockaddr* loopback_addr4(sockaddr_storage* addr, socklen_t* addrlen, int port) {
-    struct sockaddr_in* addr4 = reinterpret_cast<sockaddr_in*>(addr);
-    *addrlen = sizeof(*addr4);
-
-    addr4->sin_family = AF_INET;
-    addr4->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
-    addr4->sin_port = htons(port);
-    return reinterpret_cast<sockaddr*>(addr);
-}
-
-static sockaddr* loopback_addr6(sockaddr_storage* addr, socklen_t* addrlen, int port) {
-    struct sockaddr_in6* addr6 = reinterpret_cast<sockaddr_in6*>(addr);
-    *addrlen = sizeof(*addr6);
-
-    addr6->sin6_family = AF_INET6;
-    addr6->sin6_addr = in6addr_loopback;
-    addr6->sin6_port = htons(port);
-    return reinterpret_cast<sockaddr*>(addr);
-}
-
-static int _network_loopback_client(bool ipv6, int port, int type, std::string* error) {
-    unique_fd s(socket(ipv6 ? AF_INET6 : AF_INET, type, 0));
-    if (s == -1) {
-        set_error(error);
-        return -1;
-    }
-
-    struct sockaddr_storage addr_storage = {};
-    socklen_t addrlen = sizeof(addr_storage);
-    sockaddr* addr = (ipv6 ? loopback_addr6 : loopback_addr4)(&addr_storage, &addrlen, 0);
-
-    if (bind(s.get(), addr, addrlen) != 0) {
-        set_error(error);
-        return -1;
-    }
-
-    addr = (ipv6 ? loopback_addr6 : loopback_addr4)(&addr_storage, &addrlen, port);
-
-    if (connect(s.get(), addr, addrlen) != 0) {
-        set_error(error);
-        return -1;
-    }
-
-    return s.release();
-}
-
-int network_loopback_client(int port, int type, std::string* error) {
-    // Try IPv4 first, use IPv6 as a fallback.
-    int rc = _network_loopback_client(false, port, type, error);
-    if (rc == -1) {
-        return _network_loopback_client(true, port, type, error);
-    }
-    return rc;
-}
-
-static int _network_loopback_server(bool ipv6, int port, int type, std::string* error) {
-    unique_fd s(socket(ipv6 ? AF_INET6 : AF_INET, type, 0));
-    if (s == -1) {
-        set_error(error);
-        return -1;
-    }
-
-    int n = 1;
-    setsockopt(s.get(), SOL_SOCKET, SO_REUSEADDR, &n, sizeof(n));
-
-    struct sockaddr_storage addr_storage = {};
-    socklen_t addrlen = sizeof(addr_storage);
-    sockaddr* addr = (ipv6 ? loopback_addr6 : loopback_addr4)(&addr_storage, &addrlen, port);
-
-    if (bind(s.get(), addr, addrlen) != 0) {
-        set_error(error);
-        return -1;
-    }
-
-    if (type == SOCK_STREAM || type == SOCK_SEQPACKET) {
-        if (listen(s.get(), SOMAXCONN) != 0) {
-            set_error(error);
-            return -1;
-        }
-    }
-
-    return s.release();
-}
-
-int network_loopback_server(int port, int type, std::string* error, bool prefer_ipv4) {
-    int rc = -1;
-    if (prefer_ipv4) {
-        rc = _network_loopback_server(false, port, type, error);
-    }
-
-    // Only attempt to listen on IPv6 if IPv4 is unavailable or prefer_ipv4 is false
-    // We don't want to start an IPv6 server if there's already an IPv4 one running.
-    if (rc == -1 && (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT || !prefer_ipv4)) {
-        return _network_loopback_server(true, port, type, error);
-    }
-    return rc;
-}
-
-int network_connect(const std::string& host, int port, int type, int timeout, std::string* error) {
-    int getaddrinfo_error = 0;
-    int fd = socket_network_client_timeout(host.c_str(), port, type, timeout, &getaddrinfo_error);
-    if (fd != -1) {
-        return fd;
-    }
-    if (getaddrinfo_error != 0) {
-        *error = android::base::StringPrintf("failed to resolve host: '%s': %s", host.c_str(),
-                                             gai_strerror(getaddrinfo_error));
-        LOG(WARNING) << *error;
-    } else {
-        *error = android::base::StringPrintf("failed to connect to '%s:%d': %s", host.c_str(), port,
-                                             strerror(errno));
-        LOG(WARNING) << *error;
-    }
-    return -1;
-}
diff --git a/adb/sysdeps/stat.h b/adb/sysdeps/stat.h
deleted file mode 100644
index ed2cf25fb..0000000
--- a/adb/sysdeps/stat.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#if defined(_WIN32)
-// stat is broken on Win32: stat on a path with a trailing slash or backslash will always fail with
-// ENOENT.
-int adb_stat(const char* path, struct adb_stat* buf);
-
-// We later define a macro mapping 'stat' to 'adb_stat'. This causes:
-//   struct stat s;
-//   stat(filename, &s);
-// To turn into the following:
-//   struct adb_stat s;
-//   adb_stat(filename, &s);
-// To get this to work, we need to make 'struct adb_stat' the same as
-// 'struct stat'. Note that this definition of 'struct adb_stat' uses the
-// *current* macro definition of stat, so it may actually be inheriting from
-// struct _stat32i64 (or some other remapping).
-struct adb_stat : public stat {};
-
-#undef stat
-#define stat adb_stat
-
-// Windows doesn't have lstat.
-#define lstat adb_stat
-
-// mingw doesn't define S_IFLNK or S_ISLNK.
-#define S_IFLNK 0120000
-#define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK)
-
-// mingw defines S_IFBLK to a different value from bionic.
-#undef S_IFBLK
-#define S_IFBLK 0060000
-#undef S_ISBLK
-#define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK)
-#endif
-
-// Make sure that host file mode values match the ones on the device.
-static_assert(S_IFMT == 00170000, "");
-static_assert(S_IFLNK == 0120000, "");
-static_assert(S_IFREG == 0100000, "");
-static_assert(S_IFBLK == 0060000, "");
-static_assert(S_IFDIR == 0040000, "");
-static_assert(S_IFCHR == 0020000, "");
diff --git a/adb/sysdeps/stat_test.cpp b/adb/sysdeps/stat_test.cpp
deleted file mode 100644
index 67155d9..0000000
--- a/adb/sysdeps/stat_test.cpp
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <string>
-
-#include <android-base/file.h>
-#include <gtest/gtest.h>
-
-#include "adb_utils.h"
-#include "sysdeps.h"
-
-TEST(sysdeps, stat) {
-    TemporaryDir td;
-    TemporaryFile tf;
-
-    struct stat st;
-    ASSERT_EQ(0, stat(td.path, &st));
-    ASSERT_FALSE(S_ISREG(st.st_mode));
-    ASSERT_TRUE(S_ISDIR(st.st_mode));
-
-    ASSERT_EQ(0, stat((std::string(td.path) + '/').c_str(), &st));
-    ASSERT_TRUE(S_ISDIR(st.st_mode));
-
-#if defined(_WIN32)
-    ASSERT_EQ(0, stat((std::string(td.path) + '\\').c_str(), &st));
-    ASSERT_TRUE(S_ISDIR(st.st_mode));
-#endif
-
-    std::string nonexistent_path = std::string(td.path) + "/nonexistent";
-    ASSERT_EQ(-1, stat(nonexistent_path.c_str(), &st));
-    ASSERT_EQ(ENOENT, errno);
-
-    ASSERT_EQ(-1, stat((nonexistent_path + "/").c_str(), &st));
-    ASSERT_EQ(ENOENT, errno);
-
-#if defined(_WIN32)
-    ASSERT_EQ(-1, stat((nonexistent_path + "\\").c_str(), &st));
-    ASSERT_EQ(ENOENT, errno);
-#endif
-
-    ASSERT_EQ(0, stat(tf.path, &st));
-    ASSERT_TRUE(S_ISREG(st.st_mode));
-    ASSERT_FALSE(S_ISDIR(st.st_mode));
-
-    ASSERT_EQ(-1, stat((std::string(tf.path) + '/').c_str(), &st));
-    ASSERT_EQ(ENOTDIR, errno);
-
-#if defined(_WIN32)
-    ASSERT_EQ(-1, stat((std::string(tf.path) + '\\').c_str(), &st));
-    ASSERT_EQ(ENOTDIR, errno);
-#endif
-}
diff --git a/adb/sysdeps/uio.h b/adb/sysdeps/uio.h
deleted file mode 100644
index ced884b..0000000
--- a/adb/sysdeps/uio.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <sys/types.h>
-
-#include "adb_unique_fd.h"
-
-#if defined(_WIN32)
-
-// Layout of this struct must match struct WSABUF (verified via static assert in sysdeps_win32.cpp)
-struct adb_iovec {
-    size_t iov_len;
-    void* iov_base;
-};
-
-ssize_t adb_writev(borrowed_fd fd, const adb_iovec* iov, int iovcnt);
-
-#else
-
-#include <sys/uio.h>
-using adb_iovec = struct iovec;
-inline ssize_t adb_writev(borrowed_fd fd, const adb_iovec* iov, int iovcnt) {
-    return writev(fd.get(), iov, iovcnt);
-}
-
-#endif
-
-#pragma GCC poison writev
diff --git a/adb/sysdeps/vm_sockets.h b/adb/sysdeps/vm_sockets.h
deleted file mode 100644
index 75c5f44..0000000
--- a/adb/sysdeps/vm_sockets.h
+++ /dev/null
@@ -1,49 +0,0 @@
-#if __BIONIC__
-#include <linux/vm_sockets.h>
-#else
-/****************************************************************************
- ****************************************************************************
- ***
- ***   This header was automatically generated from a Linux kernel header
- ***   of the same name, to make information necessary for userspace to
- ***   call into the kernel available to libc.  It contains only constants,
- ***   structures, and macros generated from the original header, and thus,
- ***   contains no copyrightable information.
- ***
- ***   Copied and modified from bionic/libc/kernel/uapi/linux/vm_sockets.h
- ***
- ****************************************************************************
- ****************************************************************************/
-#ifndef _UAPI_VM_SOCKETS_H
-#define _UAPI_VM_SOCKETS_H
-#include <linux/socket.h>
-#define SO_VM_SOCKETS_BUFFER_SIZE 0
-#define SO_VM_SOCKETS_BUFFER_MIN_SIZE 1
-#define SO_VM_SOCKETS_BUFFER_MAX_SIZE 2
-#define SO_VM_SOCKETS_PEER_HOST_VM_ID 3
-#define SO_VM_SOCKETS_TRUSTED 5
-#define SO_VM_SOCKETS_CONNECT_TIMEOUT 6
-#define SO_VM_SOCKETS_NONBLOCK_TXRX 7
-#define VMADDR_CID_ANY -1U
-#define VMADDR_PORT_ANY -1U
-#define VMADDR_CID_HYPERVISOR 0
-#define VMADDR_CID_RESERVED 1
-#define VMADDR_CID_HOST 2
-#define VM_SOCKETS_INVALID_VERSION -1U
-#define VM_SOCKETS_VERSION_EPOCH(_v) (((_v)&0xFF000000) >> 24)
-#define VM_SOCKETS_VERSION_MAJOR(_v) (((_v)&0x00FF0000) >> 16)
-#define VM_SOCKETS_VERSION_MINOR(_v) (((_v)&0x0000FFFF))
-struct sockaddr_vm {
-    __kernel_sa_family_t svm_family;
-    unsigned short svm_reserved1;
-    unsigned int svm_port;
-    unsigned int svm_cid;
-    unsigned char svm_zero[sizeof(struct sockaddr) - sizeof(sa_family_t) - sizeof(unsigned short) -
-                           sizeof(unsigned int) - sizeof(unsigned int)];
-};
-#define IOCTL_VM_SOCKETS_GET_LOCAL_CID _IO(7, 0xb9)
-#ifndef AF_VSOCK
-#define AF_VSOCK 40
-#endif
-#endif
-#endif
diff --git a/adb/sysdeps/win32/errno.cpp b/adb/sysdeps/win32/errno.cpp
deleted file mode 100644
index a3b9d9b..0000000
--- a/adb/sysdeps/win32/errno.cpp
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "sysdeps/errno.h"
-
-#include <windows.h>
-
-#include <string>
-
-// Overrides strerror() to handle error codes not supported by the Windows C
-// Runtime (MSVCRT.DLL).
-char* adb_strerror(int err) {
-// sysdeps.h defines strerror to adb_strerror, but in this function, we
-// want to call the real C Runtime strerror().
-#pragma push_macro("strerror")
-#undef strerror
-    const int saved_err = errno;  // Save because we overwrite it later.
-
-    // Lookup the string for an unknown error.
-    char* errmsg = strerror(-1);
-    const std::string unknown_error = (errmsg == nullptr) ? "" : errmsg;
-
-    // Lookup the string for this error to see if the C Runtime has it.
-    errmsg = strerror(err);
-    if (errmsg != nullptr && unknown_error != errmsg) {
-        // The CRT returned an error message and it is different than the error
-        // message for an unknown error, so it is probably valid, so use it.
-    } else {
-        // Check if we have a string for this error code.
-        const char* custom_msg = nullptr;
-        switch (err) {
-#pragma push_macro("ERR")
-#undef ERR
-#define ERR(errnum, desc) case errnum: custom_msg = desc; break
-            // These error strings are from AOSP bionic/libc/include/sys/_errdefs.h.
-            // Note that these cannot be longer than 94 characters because we
-            // pass this to _strerror() which has that requirement.
-            ERR(ECONNRESET,    "Connection reset by peer");
-            ERR(EHOSTUNREACH,  "No route to host");
-            ERR(ENETDOWN,      "Network is down");
-            ERR(ENETRESET,     "Network dropped connection because of reset");
-            ERR(ENOBUFS,       "No buffer space available");
-            ERR(ENOPROTOOPT,   "Protocol not available");
-            ERR(ENOTCONN,      "Transport endpoint is not connected");
-            ERR(ENOTSOCK,      "Socket operation on non-socket");
-            ERR(EOPNOTSUPP,    "Operation not supported on transport endpoint");
-#pragma pop_macro("ERR")
-        }
-
-        if (custom_msg != nullptr) {
-            // Use _strerror() to write our string into the writable per-thread
-            // buffer used by strerror()/_strerror(). _strerror() appends the
-            // msg for the current value of errno, so set errno to a consistent
-            // value for every call so that our code-path is always the same.
-            errno = 0;
-            errmsg = _strerror(custom_msg);
-            const size_t custom_msg_len = strlen(custom_msg);
-            // Just in case _strerror() returned a read-only string, check if
-            // the returned string starts with our custom message because that
-            // implies that the string is not read-only.
-            if ((errmsg != nullptr) && !strncmp(custom_msg, errmsg, custom_msg_len)) {
-                // _strerror() puts other text after our custom message, so
-                // remove that by terminating after our message.
-                errmsg[custom_msg_len] = '\0';
-            } else {
-                // For some reason nullptr was returned or a pointer to a
-                // read-only string was returned, so fallback to whatever
-                // strerror() can muster (probably "Unknown error" or some
-                // generic CRT error string).
-                errmsg = strerror(err);
-            }
-        } else {
-            // We don't have a custom message, so use whatever strerror(err)
-            // returned earlier.
-        }
-    }
-
-    errno = saved_err;  // restore
-
-    return errmsg;
-#pragma pop_macro("strerror")
-}
diff --git a/adb/sysdeps/win32/errno_test.cpp b/adb/sysdeps/win32/errno_test.cpp
deleted file mode 100644
index 09ec52c..0000000
--- a/adb/sysdeps/win32/errno_test.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "sysdeps/errno.h"
-
-#include <string>
-
-#include <gtest/gtest.h>
-
-void TestAdbStrError(int err, const char* expected) {
-    errno = 12345;
-    const char* result = adb_strerror(err);
-    // Check that errno is not overwritten.
-    EXPECT_EQ(12345, errno);
-    EXPECT_STREQ(expected, result);
-}
-
-TEST(sysdeps_win32, adb_strerror) {
-    // Test an error code that should not have a mapped string. Use an error
-    // code that is not used by the internal implementation of adb_strerror().
-    TestAdbStrError(-2, "Unknown error");
-    // adb_strerror() uses -1 internally, so test that it can still be passed
-    // as a parameter.
-    TestAdbStrError(-1, "Unknown error");
-    // Test very big, positive unknown error.
-    TestAdbStrError(1000000, "Unknown error");
-
-    // Test success case.
-    // Wine returns "Success" for strerror(0), Windows returns "No error", so accept both.
-    std::string success = adb_strerror(0);
-    EXPECT_TRUE(success == "Success" || success == "No error") << "strerror(0) = " << success;
-
-    // Test error that regular strerror() should have a string for.
-    TestAdbStrError(EPERM, "Operation not permitted");
-    // Test error that regular strerror() doesn't have a string for, but that
-    // adb_strerror() returns.
-    TestAdbStrError(ECONNRESET, "Connection reset by peer");
-}
diff --git a/adb/sysdeps/win32/stat.cpp b/adb/sysdeps/win32/stat.cpp
deleted file mode 100644
index 844c1ce..0000000
--- a/adb/sysdeps/win32/stat.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "sysdeps/stat.h"
-
-#include <errno.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include <string>
-
-#include <android-base/utf8.h>
-
-// Version of stat() that takes a UTF-8 path.
-int adb_stat(const char* path, struct adb_stat* s) {
-// This definition of wstat seems to be missing from <sys/stat.h>.
-#if defined(_FILE_OFFSET_BITS) && (_FILE_OFFSET_BITS == 64)
-#ifdef _USE_32BIT_TIME_T
-#define wstat _wstat32i64
-#else
-#define wstat _wstat64
-#endif
-#else
-// <sys/stat.h> has a function prototype for wstat() that should be available.
-#endif
-
-    std::wstring path_wide;
-    if (!android::base::UTF8ToWide(path, &path_wide)) {
-        errno = ENOENT;
-        return -1;
-    }
-
-    // If the path has a trailing slash, stat will fail with ENOENT regardless of whether the path
-    // is a directory or not.
-    bool expected_directory = false;
-    while (*path_wide.rbegin() == u'/' || *path_wide.rbegin() == u'\\') {
-        path_wide.pop_back();
-        expected_directory = true;
-    }
-
-    struct adb_stat st;
-    int result = wstat(path_wide.c_str(), &st);
-    if (result == 0 && expected_directory) {
-        if (!S_ISDIR(st.st_mode)) {
-            errno = ENOTDIR;
-            return -1;
-        }
-    }
-
-    memcpy(s, &st, sizeof(st));
-    return result;
-}
diff --git a/adb/sysdeps_test.cpp b/adb/sysdeps_test.cpp
deleted file mode 100644
index 0f4b39c..0000000
--- a/adb/sysdeps_test.cpp
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <gtest/gtest.h>
-#include <unistd.h>
-
-#include <atomic>
-#include <condition_variable>
-#include <thread>
-
-#include "adb_io.h"
-#include "sysdeps.h"
-#include "sysdeps/chrono.h"
-
-#if defined(_WIN32)
-#include <windows.h>
-static bool IsWine() {
-    HMODULE ntdll = GetModuleHandleW(L"ntdll.dll");
-    if (!ntdll) {
-        return false;
-    }
-    return GetProcAddress(ntdll, "wine_get_version") != nullptr;
-}
-#else
-static bool IsWine() {
-    return false;
-}
-#endif
-
-TEST(sysdeps_socketpair, smoke) {
-    int fds[2];
-    ASSERT_EQ(0, adb_socketpair(fds)) << strerror(errno);
-    ASSERT_TRUE(WriteFdExactly(fds[0], "foo", 4));
-    ASSERT_TRUE(WriteFdExactly(fds[1], "bar", 4));
-
-    char buf[4];
-    ASSERT_TRUE(ReadFdExactly(fds[1], buf, 4));
-    ASSERT_STREQ(buf, "foo");
-    ASSERT_TRUE(ReadFdExactly(fds[0], buf, 4));
-    ASSERT_STREQ(buf, "bar");
-    ASSERT_EQ(0, adb_close(fds[0]));
-    ASSERT_EQ(0, adb_close(fds[1]));
-}
-
-TEST(sysdeps_fd, exhaustion) {
-    std::vector<int> fds;
-    int socketpair[2];
-
-    while (adb_socketpair(socketpair) == 0) {
-        fds.push_back(socketpair[0]);
-        fds.push_back(socketpair[1]);
-    }
-
-    ASSERT_EQ(EMFILE, errno) << strerror(errno);
-    for (int fd : fds) {
-        ASSERT_EQ(0, adb_close(fd));
-    }
-    ASSERT_EQ(0, adb_socketpair(socketpair));
-    ASSERT_EQ(socketpair[0], fds[0]);
-    ASSERT_EQ(socketpair[1], fds[1]);
-    ASSERT_EQ(0, adb_close(socketpair[0]));
-    ASSERT_EQ(0, adb_close(socketpair[1]));
-}
-
-class sysdeps_poll : public ::testing::Test {
-  protected:
-    int fds[2];
-    void SetUp() override {
-        ASSERT_EQ(0, adb_socketpair(fds)) << strerror(errno);
-    }
-
-    void TearDown() override {
-        if (fds[0] >= 0) {
-            ASSERT_EQ(0, adb_close(fds[0]));
-        }
-        if (fds[1] >= 0) {
-            ASSERT_EQ(0, adb_close(fds[1]));
-        }
-    }
-};
-
-TEST_F(sysdeps_poll, smoke) {
-    adb_pollfd pfd[2] = {};
-    pfd[0].fd = fds[0];
-    pfd[0].events = POLLRDNORM;
-    pfd[1].fd = fds[1];
-    pfd[1].events = POLLWRNORM;
-
-    pfd[0].revents = -1;
-    pfd[1].revents = -1;
-    EXPECT_EQ(1, adb_poll(pfd, 2, 0));
-    EXPECT_EQ(0, pfd[0].revents);
-    EXPECT_EQ(POLLWRNORM, pfd[1].revents);
-
-    ASSERT_TRUE(WriteFdExactly(fds[1], "foo", 4));
-
-    // Wait for the socketpair to be flushed.
-    pfd[0].revents = -1;
-    EXPECT_EQ(1, adb_poll(pfd, 1, 100));
-    EXPECT_EQ(POLLRDNORM, pfd[0].revents);
-    pfd[0].revents = -1;
-    pfd[1].revents = -1;
-    EXPECT_EQ(2, adb_poll(pfd, 2, 0));
-    EXPECT_EQ(POLLRDNORM, pfd[0].revents);
-    EXPECT_EQ(POLLWRNORM, pfd[1].revents);
-}
-
-TEST_F(sysdeps_poll, timeout) {
-    adb_pollfd pfd = {};
-    pfd.fd = fds[0];
-    pfd.events = POLLRDNORM;
-
-    EXPECT_EQ(0, adb_poll(&pfd, 1, 100));
-    EXPECT_EQ(0, pfd.revents);
-
-    ASSERT_TRUE(WriteFdExactly(fds[1], "foo", 4));
-
-    EXPECT_EQ(1, adb_poll(&pfd, 1, 100));
-    EXPECT_EQ(POLLRDNORM, pfd.revents);
-}
-
-TEST_F(sysdeps_poll, invalid_fd) {
-    adb_pollfd pfd[3] = {};
-    pfd[0].fd = fds[0];
-    pfd[0].events = POLLRDNORM;
-    pfd[0].revents = ~0;
-    pfd[1].fd = INT_MAX;
-    pfd[1].events = POLLRDNORM;
-    pfd[1].revents = ~0;
-    pfd[2].fd = fds[1];
-    pfd[2].events = POLLWRNORM;
-    pfd[2].revents = ~0;
-
-    ASSERT_TRUE(WriteFdExactly(fds[1], "foo", 4));
-
-    // Wait for the socketpair to be flushed.
-    EXPECT_EQ(1, adb_poll(pfd, 1, 100));
-    EXPECT_EQ(POLLRDNORM, pfd[0].revents);
-
-    EXPECT_EQ(3, adb_poll(pfd, 3, 0));
-    EXPECT_EQ(POLLRDNORM, pfd[0].revents);
-    EXPECT_EQ(POLLNVAL, pfd[1].revents);
-    EXPECT_EQ(POLLWRNORM, pfd[2].revents);
-
-    // Make sure that we return immediately if an invalid FD is given.
-    pfd[0].fd = fds[0];
-    pfd[0].events = POLLRDNORM;
-    pfd[0].revents = ~0;
-    pfd[1].fd = INT_MAX;
-    pfd[1].events = POLLRDNORM;
-    pfd[1].revents = ~0;
-    EXPECT_EQ(2, adb_poll(pfd, 2, -1));
-    EXPECT_EQ(POLLRDNORM, pfd[0].revents);
-    EXPECT_EQ(POLLNVAL, pfd[1].revents);
-}
-
-TEST_F(sysdeps_poll, duplicate_fd) {
-    adb_pollfd pfd[2] = {};
-    pfd[0].fd = fds[0];
-    pfd[0].events = POLLRDNORM;
-    pfd[1] = pfd[0];
-
-    EXPECT_EQ(0, adb_poll(pfd, 2, 0));
-    EXPECT_EQ(0, pfd[0].revents);
-    EXPECT_EQ(0, pfd[1].revents);
-
-    ASSERT_TRUE(WriteFdExactly(fds[1], "foo", 4));
-
-    EXPECT_EQ(2, adb_poll(pfd, 2, 100));
-    EXPECT_EQ(POLLRDNORM, pfd[0].revents);
-    EXPECT_EQ(POLLRDNORM, pfd[1].revents);
-}
-
-TEST_F(sysdeps_poll, disconnect) {
-    adb_pollfd pfd = {};
-    pfd.fd = fds[0];
-    pfd.events = POLLIN;
-
-    EXPECT_EQ(0, adb_poll(&pfd, 1, 0));
-    EXPECT_EQ(0, pfd.revents);
-
-    EXPECT_EQ(0, adb_close(fds[1]));
-    fds[1] = -1;
-
-    EXPECT_EQ(1, adb_poll(&pfd, 1, 100));
-
-    if (!IsWine()) {
-        // Linux returns POLLIN | POLLHUP, Windows returns just POLLHUP.
-        EXPECT_EQ(POLLHUP, pfd.revents & POLLHUP);
-    }
-}
-
-TEST_F(sysdeps_poll, fd_count) {
-    // https://code.google.com/p/android/issues/detail?id=12141
-    static constexpr int num_sockets = 256;
-    std::vector<int> sockets;
-    std::vector<adb_pollfd> pfds;
-    sockets.resize(num_sockets * 2);
-    for (int32_t i = 0; i < num_sockets; ++i) {
-        ASSERT_EQ(0, adb_socketpair(&sockets[i * 2])) << strerror(errno);
-        ASSERT_TRUE(WriteFdExactly(sockets[i * 2], &i, sizeof(i)));
-        adb_pollfd pfd;
-        pfd.events = POLLIN;
-        pfd.fd = sockets[i * 2 + 1];
-        pfds.push_back(pfd);
-    }
-
-    ASSERT_EQ(num_sockets, adb_poll(pfds.data(), pfds.size(), 0));
-    for (int i = 0; i < num_sockets; ++i) {
-        ASSERT_NE(0, pfds[i].revents & POLLIN);
-
-        int32_t buf[2] = { -1, -1 };
-        ASSERT_EQ(adb_read(pfds[i].fd, buf, sizeof(buf)), static_cast<ssize_t>(sizeof(int32_t)));
-        ASSERT_EQ(i, buf[0]);
-    }
-
-    for (int fd : sockets) {
-        adb_close(fd);
-    }
-}
-
-TEST(sysdeps_condition_variable, smoke) {
-    static std::mutex &m = *new std::mutex;
-    static std::condition_variable &cond = *new std::condition_variable;
-    static volatile bool flag = false;
-
-    std::unique_lock<std::mutex> lock(m);
-    std::thread thread([]() {
-        m.lock();
-        flag = true;
-        cond.notify_one();
-        m.unlock();
-    });
-
-    while (!flag) {
-        cond.wait(lock);
-    }
-
-    thread.join();
-}
diff --git a/adb/sysdeps_unix.cpp b/adb/sysdeps_unix.cpp
deleted file mode 100644
index e565706..0000000
--- a/adb/sysdeps_unix.cpp
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "sysdeps.h"
-
-bool set_tcp_keepalive(borrowed_fd fd, int interval_sec) {
-    int enable = (interval_sec > 0);
-    if (adb_setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &enable, sizeof(enable))) {
-        return false;
-    }
-
-    if (!enable) {
-        return true;
-    }
-
-    // Idle time before sending the first keepalive is TCP_KEEPIDLE on Linux, TCP_KEEPALIVE on Mac.
-#if defined(TCP_KEEPIDLE)
-    if (adb_setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &interval_sec, sizeof(interval_sec))) {
-        return false;
-    }
-#elif defined(TCP_KEEPALIVE)
-    if (adb_setsockopt(fd, IPPROTO_TCP, TCP_KEEPALIVE, &interval_sec, sizeof(interval_sec))) {
-        return false;
-    }
-#endif
-
-    // TCP_KEEPINTVL and TCP_KEEPCNT are available on Linux 2.4+ and OS X 10.8+ (Mountain Lion).
-#if defined(TCP_KEEPINTVL)
-    if (adb_setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &interval_sec, sizeof(interval_sec))) {
-        return false;
-    }
-#endif
-
-#if defined(TCP_KEEPCNT)
-    // On Windows this value is hardcoded to 10. This is a reasonable value, so we do the same here
-    // to match behavior. See SO_KEEPALIVE documentation at
-    // https://msdn.microsoft.com/en-us/library/windows/desktop/ee470551(v=vs.85).aspx.
-    const int keepcnt = 10;
-    if (adb_setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &keepcnt, sizeof(keepcnt))) {
-        return false;
-    }
-#endif
-
-    return true;
-}
-
-static __inline__ void disable_close_on_exec(borrowed_fd fd) {
-    const auto oldFlags = fcntl(fd.get(), F_GETFD);
-    const auto newFlags = (oldFlags & ~FD_CLOEXEC);
-    if (newFlags != oldFlags) {
-        fcntl(fd.get(), F_SETFD, newFlags);
-    }
-}
-
-Process adb_launch_process(std::string_view executable, std::vector<std::string> args,
-                           std::initializer_list<int> fds_to_inherit) {
-    const auto pid = fork();
-    if (pid != 0) {
-        // parent, includes the case when failed to fork()
-        return Process(pid);
-    }
-    // child
-    std::vector<std::string> copies;
-    copies.reserve(args.size() + 1);
-    copies.emplace_back(executable);
-    copies.insert(copies.end(), std::make_move_iterator(args.begin()),
-                  std::make_move_iterator(args.end()));
-
-    std::vector<char*> rawArgs;
-    rawArgs.reserve(copies.size() + 1);
-    for (auto&& str : copies) {
-        rawArgs.push_back(str.data());
-    }
-    rawArgs.push_back(nullptr);
-    for (auto fd : fds_to_inherit) {
-        disable_close_on_exec(fd);
-    }
-    exit(execv(copies.front().data(), rawArgs.data()));
-}
diff --git a/adb/sysdeps_win32.cpp b/adb/sysdeps_win32.cpp
deleted file mode 100644
index be82bc0..0000000
--- a/adb/sysdeps_win32.cpp
+++ /dev/null
@@ -1,2981 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define TRACE_TAG SYSDEPS
-
-#include "sysdeps.h"
-
-#include <lmcons.h>
-#include <windows.h>
-#include <winsock2.h> /* winsock.h *must* be included before windows.h. */
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <algorithm>
-#include <memory>
-#include <mutex>
-#include <string>
-#include <string_view>
-#include <unordered_map>
-#include <vector>
-
-#include <cutils/sockets.h>
-
-#include <android-base/errors.h>
-#include <android-base/file.h>
-#include <android-base/logging.h>
-#include <android-base/macros.h>
-#include <android-base/stringprintf.h>
-#include <android-base/strings.h>
-#include <android-base/utf8.h>
-
-#include "adb.h"
-#include "adb_utils.h"
-
-#include "sysdeps/uio.h"
-
-/* forward declarations */
-
-typedef const struct FHClassRec_* FHClass;
-typedef struct FHRec_* FH;
-
-typedef struct FHClassRec_ {
-    void (*_fh_init)(FH);
-    int (*_fh_close)(FH);
-    int64_t (*_fh_lseek)(FH, int64_t, int);
-    int (*_fh_read)(FH, void*, int);
-    int (*_fh_write)(FH, const void*, int);
-    int (*_fh_writev)(FH, const adb_iovec*, int);
-    intptr_t (*_fh_get_os_handle)(FH);
-} FHClassRec;
-
-static void _fh_file_init(FH);
-static int _fh_file_close(FH);
-static int64_t _fh_file_lseek(FH, int64_t, int);
-static int _fh_file_read(FH, void*, int);
-static int _fh_file_write(FH, const void*, int);
-static int _fh_file_writev(FH, const adb_iovec*, int);
-static intptr_t _fh_file_get_os_handle(FH f);
-
-static const FHClassRec _fh_file_class = {
-        _fh_file_init,  _fh_file_close,  _fh_file_lseek,         _fh_file_read,
-        _fh_file_write, _fh_file_writev, _fh_file_get_os_handle,
-};
-
-static void _fh_socket_init(FH);
-static int _fh_socket_close(FH);
-static int64_t _fh_socket_lseek(FH, int64_t, int);
-static int _fh_socket_read(FH, void*, int);
-static int _fh_socket_write(FH, const void*, int);
-static int _fh_socket_writev(FH, const adb_iovec*, int);
-static intptr_t _fh_socket_get_os_handle(FH f);
-
-static const FHClassRec _fh_socket_class = {
-        _fh_socket_init,  _fh_socket_close,  _fh_socket_lseek,         _fh_socket_read,
-        _fh_socket_write, _fh_socket_writev, _fh_socket_get_os_handle,
-};
-
-#if defined(assert)
-#undef assert
-#endif
-
-void handle_deleter::operator()(HANDLE h) {
-    // CreateFile() is documented to return INVALID_HANDLE_FILE on error,
-    // implying that NULL is a valid handle, but this is probably impossible.
-    // Other APIs like CreateEvent() are documented to return NULL on error,
-    // implying that INVALID_HANDLE_VALUE is a valid handle, but this is also
-    // probably impossible. Thus, consider both NULL and INVALID_HANDLE_VALUE
-    // as invalid handles. std::unique_ptr won't call a deleter with NULL, so we
-    // only need to check for INVALID_HANDLE_VALUE.
-    if (h != INVALID_HANDLE_VALUE) {
-        if (!CloseHandle(h)) {
-            D("CloseHandle(%p) failed: %s", h,
-              android::base::SystemErrorCodeToString(GetLastError()).c_str());
-        }
-    }
-}
-
-/**************************************************************************/
-/**************************************************************************/
-/*****                                                                *****/
-/*****    common file descriptor handling                             *****/
-/*****                                                                *****/
-/**************************************************************************/
-/**************************************************************************/
-
-typedef struct FHRec_
-{
-    FHClass    clazz;
-    int        used;
-    int        eof;
-    union {
-        HANDLE      handle;
-        SOCKET      socket;
-    } u;
-
-    char  name[32];
-} FHRec;
-
-#define  fh_handle  u.handle
-#define  fh_socket  u.socket
-
-#define  WIN32_FH_BASE    2048
-#define  WIN32_MAX_FHS    2048
-
-static  std::mutex&  _win32_lock = *new std::mutex();
-static  FHRec        _win32_fhs[ WIN32_MAX_FHS ];
-static  int          _win32_fh_next;  // where to start search for free FHRec
-
-static FH _fh_from_int(borrowed_fd bfd, const char* func) {
-    FH f;
-
-    int fd = bfd.get();
-    fd -= WIN32_FH_BASE;
-
-    if (fd < 0 || fd >= WIN32_MAX_FHS) {
-        D("_fh_from_int: invalid fd %d passed to %s", fd + WIN32_FH_BASE, func);
-        errno = EBADF;
-        return nullptr;
-    }
-
-    f = &_win32_fhs[fd];
-
-    if (f->used == 0) {
-        D("_fh_from_int: invalid fd %d passed to %s", fd + WIN32_FH_BASE, func);
-        errno = EBADF;
-        return nullptr;
-    }
-
-    return f;
-}
-
-static int _fh_to_int(FH f) {
-    if (f && f->used && f >= _win32_fhs && f < _win32_fhs + WIN32_MAX_FHS)
-        return (int)(f - _win32_fhs) + WIN32_FH_BASE;
-
-    return -1;
-}
-
-static FH _fh_alloc(FHClass clazz) {
-    FH f = nullptr;
-
-    std::lock_guard<std::mutex> lock(_win32_lock);
-
-    for (int i = _win32_fh_next; i < WIN32_MAX_FHS; ++i) {
-        if (_win32_fhs[i].clazz == nullptr) {
-            f = &_win32_fhs[i];
-            _win32_fh_next = i + 1;
-            f->clazz = clazz;
-            f->used = 1;
-            f->eof = 0;
-            f->name[0] = '\0';
-            clazz->_fh_init(f);
-            return f;
-        }
-    }
-
-    D("_fh_alloc: no more free file descriptors");
-    errno = EMFILE;  // Too many open files
-    return nullptr;
-}
-
-static int _fh_close(FH f) {
-    // Use lock so that closing only happens once and so that _fh_alloc can't
-    // allocate a FH that we're in the middle of closing.
-    std::lock_guard<std::mutex> lock(_win32_lock);
-
-    int offset = f - _win32_fhs;
-    if (_win32_fh_next > offset) {
-        _win32_fh_next = offset;
-    }
-
-    if (f->used) {
-        f->clazz->_fh_close( f );
-        f->name[0] = '\0';
-        f->eof     = 0;
-        f->used    = 0;
-        f->clazz   = nullptr;
-    }
-    return 0;
-}
-
-// Deleter for unique_fh.
-class fh_deleter {
- public:
-  void operator()(struct FHRec_* fh) {
-    // We're called from a destructor and destructors should not overwrite
-    // errno because callers may do:
-    //   errno = EBLAH;
-    //   return -1; // calls destructor, which should not overwrite errno
-    const int saved_errno = errno;
-    _fh_close(fh);
-    errno = saved_errno;
-  }
-};
-
-// Like std::unique_ptr, but calls _fh_close() instead of operator delete().
-typedef std::unique_ptr<struct FHRec_, fh_deleter> unique_fh;
-
-/**************************************************************************/
-/**************************************************************************/
-/*****                                                                *****/
-/*****    file-based descriptor handling                              *****/
-/*****                                                                *****/
-/**************************************************************************/
-/**************************************************************************/
-
-static void _fh_file_init(FH f) {
-    f->fh_handle = INVALID_HANDLE_VALUE;
-}
-
-static int _fh_file_close(FH f) {
-    CloseHandle(f->fh_handle);
-    f->fh_handle = INVALID_HANDLE_VALUE;
-    return 0;
-}
-
-static int _fh_file_read(FH f, void* buf, int len) {
-    DWORD read_bytes;
-
-    if (!ReadFile(f->fh_handle, buf, (DWORD)len, &read_bytes, nullptr)) {
-        D("adb_read: could not read %d bytes from %s", len, f->name);
-        errno = EIO;
-        return -1;
-    } else if (read_bytes < (DWORD)len) {
-        f->eof = 1;
-    }
-    return read_bytes;
-}
-
-static int _fh_file_write(FH f, const void* buf, int len) {
-    DWORD wrote_bytes;
-
-    if (!WriteFile(f->fh_handle, buf, (DWORD)len, &wrote_bytes, nullptr)) {
-        D("adb_file_write: could not write %d bytes from %s", len, f->name);
-        errno = EIO;
-        return -1;
-    } else if (wrote_bytes < (DWORD)len) {
-        f->eof = 1;
-    }
-    return wrote_bytes;
-}
-
-static int _fh_file_writev(FH f, const adb_iovec* iov, int iovcnt) {
-    if (iovcnt <= 0) {
-        errno = EINVAL;
-        return -1;
-    }
-
-    DWORD wrote_bytes = 0;
-
-    for (int i = 0; i < iovcnt; ++i) {
-        ssize_t rc = _fh_file_write(f, iov[i].iov_base, iov[i].iov_len);
-        if (rc == -1) {
-            return wrote_bytes > 0 ? wrote_bytes : -1;
-        } else if (rc == 0) {
-            return wrote_bytes;
-        }
-
-        wrote_bytes += rc;
-
-        if (static_cast<size_t>(rc) < iov[i].iov_len) {
-            return wrote_bytes;
-        }
-    }
-
-    return wrote_bytes;
-}
-
-static int64_t _fh_file_lseek(FH f, int64_t pos, int origin) {
-    DWORD method;
-    switch (origin) {
-        case SEEK_SET:
-            method = FILE_BEGIN;
-            break;
-        case SEEK_CUR:
-            method = FILE_CURRENT;
-            break;
-        case SEEK_END:
-            method = FILE_END;
-            break;
-        default:
-            errno = EINVAL;
-            return -1;
-    }
-
-    LARGE_INTEGER li = {.QuadPart = pos};
-    if (!SetFilePointerEx(f->fh_handle, li, &li, method)) {
-        errno = EIO;
-        return -1;
-    }
-    f->eof = 0;
-    return li.QuadPart;
-}
-
-static intptr_t _fh_file_get_os_handle(FH f) {
-    return reinterpret_cast<intptr_t>(f->u.handle);
-}
-
-/**************************************************************************/
-/**************************************************************************/
-/*****                                                                *****/
-/*****    file-based descriptor handling                              *****/
-/*****                                                                *****/
-/**************************************************************************/
-/**************************************************************************/
-
-int adb_open(const char* path, int options) {
-    FH f;
-
-    DWORD desiredAccess = 0;
-    DWORD shareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
-
-    // CreateFileW is inherently O_CLOEXEC by default.
-    options &= ~O_CLOEXEC;
-
-    switch (options) {
-        case O_RDONLY:
-            desiredAccess = GENERIC_READ;
-            break;
-        case O_WRONLY:
-            desiredAccess = GENERIC_WRITE;
-            break;
-        case O_RDWR:
-            desiredAccess = GENERIC_READ | GENERIC_WRITE;
-            break;
-        default:
-            D("adb_open: invalid options (0x%0x)", options);
-            errno = EINVAL;
-            return -1;
-    }
-
-    f = _fh_alloc(&_fh_file_class);
-    if (!f) {
-        return -1;
-    }
-
-    std::wstring path_wide;
-    if (!android::base::UTF8ToWide(path, &path_wide)) {
-        return -1;
-    }
-    f->fh_handle =
-        CreateFileW(path_wide.c_str(), desiredAccess, shareMode, nullptr, OPEN_EXISTING, 0, nullptr);
-
-    if (f->fh_handle == INVALID_HANDLE_VALUE) {
-        const DWORD err = GetLastError();
-        _fh_close(f);
-        D("adb_open: could not open '%s': ", path);
-        switch (err) {
-            case ERROR_FILE_NOT_FOUND:
-                D("file not found");
-                errno = ENOENT;
-                return -1;
-
-            case ERROR_PATH_NOT_FOUND:
-                D("path not found");
-                errno = ENOTDIR;
-                return -1;
-
-            default:
-                D("unknown error: %s", android::base::SystemErrorCodeToString(err).c_str());
-                errno = ENOENT;
-                return -1;
-        }
-    }
-
-    snprintf(f->name, sizeof(f->name), "%d(%s)", _fh_to_int(f), path);
-    D("adb_open: '%s' => fd %d", path, _fh_to_int(f));
-    return _fh_to_int(f);
-}
-
-/* ignore mode on Win32 */
-int adb_creat(const char* path, int mode) {
-    FH f;
-
-    f = _fh_alloc(&_fh_file_class);
-    if (!f) {
-        return -1;
-    }
-
-    std::wstring path_wide;
-    if (!android::base::UTF8ToWide(path, &path_wide)) {
-        return -1;
-    }
-    f->fh_handle = CreateFileW(path_wide.c_str(), GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
-                               nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
-
-    if (f->fh_handle == INVALID_HANDLE_VALUE) {
-        const DWORD err = GetLastError();
-        _fh_close(f);
-        D("adb_creat: could not open '%s': ", path);
-        switch (err) {
-            case ERROR_FILE_NOT_FOUND:
-                D("file not found");
-                errno = ENOENT;
-                return -1;
-
-            case ERROR_PATH_NOT_FOUND:
-                D("path not found");
-                errno = ENOTDIR;
-                return -1;
-
-            default:
-                D("unknown error: %s", android::base::SystemErrorCodeToString(err).c_str());
-                errno = ENOENT;
-                return -1;
-        }
-    }
-    snprintf(f->name, sizeof(f->name), "%d(%s)", _fh_to_int(f), path);
-    D("adb_creat: '%s' => fd %d", path, _fh_to_int(f));
-    return _fh_to_int(f);
-}
-
-int adb_read(borrowed_fd fd, void* buf, int len) {
-    FH f = _fh_from_int(fd, __func__);
-
-    if (f == nullptr) {
-        errno = EBADF;
-        return -1;
-    }
-
-    return f->clazz->_fh_read(f, buf, len);
-}
-
-int adb_pread(borrowed_fd fd, void* buf, int len, off64_t offset) {
-    OVERLAPPED overlapped = {};
-    overlapped.Offset = static_cast<DWORD>(offset);
-    overlapped.OffsetHigh = static_cast<DWORD>(offset >> 32);
-    DWORD bytes_read;
-    if (!::ReadFile(adb_get_os_handle(fd), buf, static_cast<DWORD>(len), &bytes_read,
-                    &overlapped)) {
-        D("adb_pread: could not read %d bytes from FD %d", len, fd.get());
-        switch (::GetLastError()) {
-            case ERROR_IO_PENDING:
-                errno = EAGAIN;
-                return -1;
-            default:
-                errno = EINVAL;
-                return -1;
-        }
-    }
-    return static_cast<int>(bytes_read);
-}
-
-int adb_write(borrowed_fd fd, const void* buf, int len) {
-    FH f = _fh_from_int(fd, __func__);
-
-    if (f == nullptr) {
-        errno = EBADF;
-        return -1;
-    }
-
-    return f->clazz->_fh_write(f, buf, len);
-}
-
-ssize_t adb_writev(borrowed_fd fd, const adb_iovec* iov, int iovcnt) {
-    FH f = _fh_from_int(fd, __func__);
-
-    if (f == nullptr) {
-        errno = EBADF;
-        return -1;
-    }
-
-    return f->clazz->_fh_writev(f, iov, iovcnt);
-}
-
-int adb_pwrite(borrowed_fd fd, const void* buf, int len, off64_t offset) {
-    OVERLAPPED params = {};
-    params.Offset = static_cast<DWORD>(offset);
-    params.OffsetHigh = static_cast<DWORD>(offset >> 32);
-    DWORD bytes_written = 0;
-    if (!::WriteFile(adb_get_os_handle(fd), buf, len, &bytes_written, &params)) {
-        D("adb_pwrite: could not write %d bytes to FD %d", len, fd.get());
-        switch (::GetLastError()) {
-            case ERROR_IO_PENDING:
-                errno = EAGAIN;
-                return -1;
-            default:
-                errno = EINVAL;
-                return -1;
-        }
-    }
-    return static_cast<int>(bytes_written);
-}
-
-int64_t adb_lseek(borrowed_fd fd, int64_t pos, int where) {
-    FH f = _fh_from_int(fd, __func__);
-    if (!f) {
-        errno = EBADF;
-        return -1;
-    }
-    return f->clazz->_fh_lseek(f, pos, where);
-}
-
-int adb_close(int fd) {
-    FH f = _fh_from_int(fd, __func__);
-
-    if (!f) {
-        errno = EBADF;
-        return -1;
-    }
-
-    D("adb_close: %s", f->name);
-    _fh_close(f);
-    return 0;
-}
-
-HANDLE adb_get_os_handle(borrowed_fd fd) {
-    FH f = _fh_from_int(fd, __func__);
-
-    if (!f) {
-        errno = EBADF;
-        return nullptr;
-    }
-
-    D("adb_get_os_handle: %s", f->name);
-    const intptr_t intptr_handle = f->clazz->_fh_get_os_handle(f);
-    const HANDLE handle = reinterpret_cast<const HANDLE>(intptr_handle);
-    return handle;
-}
-
-/**************************************************************************/
-/**************************************************************************/
-/*****                                                                *****/
-/*****    socket-based file descriptors                               *****/
-/*****                                                                *****/
-/**************************************************************************/
-/**************************************************************************/
-
-#undef setsockopt
-
-static void _socket_set_errno( const DWORD err ) {
-    // Because the Windows C Runtime (MSVCRT.DLL) strerror() does not support a
-    // lot of POSIX and socket error codes, some of the resulting error codes
-    // are mapped to strings by adb_strerror().
-    switch ( err ) {
-    case 0:              errno = 0; break;
-    // Don't map WSAEINTR since that is only for Winsock 1.1 which we don't use.
-    // case WSAEINTR:    errno = EINTR; break;
-    case WSAEFAULT:      errno = EFAULT; break;
-    case WSAEINVAL:      errno = EINVAL; break;
-    case WSAEMFILE:      errno = EMFILE; break;
-    // Mapping WSAEWOULDBLOCK to EAGAIN is absolutely critical because
-    // non-blocking sockets can cause an error code of WSAEWOULDBLOCK and
-    // callers check specifically for EAGAIN.
-    case WSAEWOULDBLOCK: errno = EAGAIN; break;
-    case WSAENOTSOCK:    errno = ENOTSOCK; break;
-    case WSAENOPROTOOPT: errno = ENOPROTOOPT; break;
-    case WSAEOPNOTSUPP:  errno = EOPNOTSUPP; break;
-    case WSAENETDOWN:    errno = ENETDOWN; break;
-    case WSAENETRESET:   errno = ENETRESET; break;
-    // Map WSAECONNABORTED to EPIPE instead of ECONNABORTED because POSIX seems
-    // to use EPIPE for these situations and there are some callers that look
-    // for EPIPE.
-    case WSAECONNABORTED: errno = EPIPE; break;
-    case WSAECONNRESET:  errno = ECONNRESET; break;
-    case WSAENOBUFS:     errno = ENOBUFS; break;
-    case WSAENOTCONN:    errno = ENOTCONN; break;
-    // Don't map WSAETIMEDOUT because we don't currently use SO_RCVTIMEO or
-    // SO_SNDTIMEO which would cause WSAETIMEDOUT to be returned. Future
-    // considerations: Reportedly send() can return zero on timeout, and POSIX
-    // code may expect EAGAIN instead of ETIMEDOUT on timeout.
-    // case WSAETIMEDOUT: errno = ETIMEDOUT; break;
-    case WSAEHOSTUNREACH: errno = EHOSTUNREACH; break;
-    default:
-        errno = EINVAL;
-        D( "_socket_set_errno: mapping Windows error code %lu to errno %d",
-           err, errno );
-    }
-}
-
-extern int adb_poll(adb_pollfd* fds, size_t nfds, int timeout) {
-    // WSAPoll doesn't handle invalid/non-socket handles, so we need to handle them ourselves.
-    int skipped = 0;
-    std::vector<WSAPOLLFD> sockets;
-    std::vector<adb_pollfd*> original;
-
-    for (size_t i = 0; i < nfds; ++i) {
-        FH fh = _fh_from_int(fds[i].fd, __func__);
-        if (!fh || !fh->used || fh->clazz != &_fh_socket_class) {
-            D("adb_poll received bad FD %d", fds[i].fd);
-            fds[i].revents = POLLNVAL;
-            ++skipped;
-        } else {
-            WSAPOLLFD wsapollfd = {
-                .fd = fh->u.socket,
-                .events = static_cast<short>(fds[i].events)
-            };
-            sockets.push_back(wsapollfd);
-            original.push_back(&fds[i]);
-        }
-    }
-
-    if (sockets.empty()) {
-        return skipped;
-    }
-
-    // If we have any invalid FDs in our FD set, make sure to return immediately.
-    if (skipped > 0) {
-        timeout = 0;
-    }
-
-    int result = WSAPoll(sockets.data(), sockets.size(), timeout);
-    if (result == SOCKET_ERROR) {
-        _socket_set_errno(WSAGetLastError());
-        return -1;
-    }
-
-    // Map the results back onto the original set.
-    for (size_t i = 0; i < sockets.size(); ++i) {
-        original[i]->revents = sockets[i].revents;
-    }
-
-    // WSAPoll appears to return the number of unique FDs with available events, instead of how many
-    // of the pollfd elements have a non-zero revents field, which is what it and poll are specified
-    // to do. Ignore its result and calculate the proper return value.
-    result = 0;
-    for (size_t i = 0; i < nfds; ++i) {
-        if (fds[i].revents != 0) {
-            ++result;
-        }
-    }
-    return result;
-}
-
-static void _fh_socket_init(FH f) {
-    f->fh_socket = INVALID_SOCKET;
-}
-
-static int _fh_socket_close(FH f) {
-    if (f->fh_socket != INVALID_SOCKET) {
-        if (closesocket(f->fh_socket) == SOCKET_ERROR) {
-            // Don't set errno here, since adb_close will ignore it.
-            const DWORD err = WSAGetLastError();
-            D("closesocket failed: %s", android::base::SystemErrorCodeToString(err).c_str());
-        }
-        f->fh_socket = INVALID_SOCKET;
-    }
-    return 0;
-}
-
-static int64_t _fh_socket_lseek(FH f, int64_t pos, int origin) {
-    errno = EPIPE;
-    return -1;
-}
-
-static int _fh_socket_read(FH f, void* buf, int len) {
-    int result = recv(f->fh_socket, reinterpret_cast<char*>(buf), len, 0);
-    if (result == SOCKET_ERROR) {
-        const DWORD err = WSAGetLastError();
-        // WSAEWOULDBLOCK is normal with a non-blocking socket, so don't trace
-        // that to reduce spam and confusion.
-        if (err != WSAEWOULDBLOCK) {
-            D("recv fd %d failed: %s", _fh_to_int(f),
-              android::base::SystemErrorCodeToString(err).c_str());
-        }
-        _socket_set_errno(err);
-        result = -1;
-    }
-    return result;
-}
-
-static int _fh_socket_write(FH f, const void* buf, int len) {
-    int result = send(f->fh_socket, reinterpret_cast<const char*>(buf), len, 0);
-    if (result == SOCKET_ERROR) {
-        const DWORD err = WSAGetLastError();
-        // WSAEWOULDBLOCK is normal with a non-blocking socket, so don't trace
-        // that to reduce spam and confusion.
-        if (err != WSAEWOULDBLOCK) {
-            D("send fd %d failed: %s", _fh_to_int(f),
-              android::base::SystemErrorCodeToString(err).c_str());
-        }
-        _socket_set_errno(err);
-        result = -1;
-    } else {
-        // According to https://code.google.com/p/chromium/issues/detail?id=27870
-        // Winsock Layered Service Providers may cause this.
-        CHECK_LE(result, len) << "Tried to write " << len << " bytes to " << f->name << ", but "
-                              << result << " bytes reportedly written";
-    }
-    return result;
-}
-
-// Make sure that adb_iovec is compatible with WSABUF.
-static_assert(sizeof(adb_iovec) == sizeof(WSABUF), "");
-static_assert(SIZEOF_MEMBER(adb_iovec, iov_len) == SIZEOF_MEMBER(WSABUF, len), "");
-static_assert(offsetof(adb_iovec, iov_len) == offsetof(WSABUF, len), "");
-
-static_assert(SIZEOF_MEMBER(adb_iovec, iov_base) == SIZEOF_MEMBER(WSABUF, buf), "");
-static_assert(offsetof(adb_iovec, iov_base) == offsetof(WSABUF, buf), "");
-
-static int _fh_socket_writev(FH f, const adb_iovec* iov, int iovcnt) {
-    if (iovcnt <= 0) {
-        errno = EINVAL;
-        return -1;
-    }
-
-    WSABUF* wsabuf = reinterpret_cast<WSABUF*>(const_cast<adb_iovec*>(iov));
-    DWORD bytes_written = 0;
-    int result = WSASend(f->fh_socket, wsabuf, iovcnt, &bytes_written, 0, nullptr, nullptr);
-    if (result == SOCKET_ERROR) {
-        const DWORD err = WSAGetLastError();
-        // WSAEWOULDBLOCK is normal with a non-blocking socket, so don't trace
-        // that to reduce spam and confusion.
-        if (err != WSAEWOULDBLOCK) {
-            D("send fd %d failed: %s", _fh_to_int(f),
-              android::base::SystemErrorCodeToString(err).c_str());
-        }
-        _socket_set_errno(err);
-        return -1;
-    }
-    CHECK_GE(static_cast<DWORD>(std::numeric_limits<int>::max()), bytes_written);
-    return static_cast<int>(bytes_written);
-}
-
-static intptr_t _fh_socket_get_os_handle(FH f) {
-    return f->u.socket;
-}
-
-/**************************************************************************/
-/**************************************************************************/
-/*****                                                                *****/
-/*****    replacement for libs/cutils/socket_xxxx.c                   *****/
-/*****                                                                *****/
-/**************************************************************************/
-/**************************************************************************/
-
-static void _init_winsock() {
-    static std::once_flag once;
-    std::call_once(once, []() {
-        WSADATA wsaData;
-        int rc = WSAStartup(MAKEWORD(2, 2), &wsaData);
-        if (rc != 0) {
-            LOG(FATAL) << "could not initialize Winsock: "
-                       << android::base::SystemErrorCodeToString(rc);
-        }
-
-        // Note that we do not call atexit() to register WSACleanup to be called
-        // at normal process termination because:
-        // 1) When exit() is called, there are still threads actively using
-        //    Winsock because we don't cleanly shutdown all threads, so it
-        //    doesn't make sense to call WSACleanup() and may cause problems
-        //    with those threads.
-        // 2) A deadlock can occur when exit() holds a C Runtime lock, then it
-        //    calls WSACleanup() which tries to unload a DLL, which tries to
-        //    grab the LoaderLock. This conflicts with the device_poll_thread
-        //    which holds the LoaderLock because AdbWinApi.dll calls
-        //    setupapi.dll which tries to load wintrust.dll which tries to load
-        //    crypt32.dll which calls atexit() which tries to acquire the C
-        //    Runtime lock that the other thread holds.
-    });
-}
-
-// Map a socket type to an explicit socket protocol instead of using the socket
-// protocol of 0. Explicit socket protocols are used by most apps and we should
-// do the same to reduce the chance of exercising uncommon code-paths that might
-// have problems or that might load different Winsock service providers that
-// have problems.
-static int GetSocketProtocolFromSocketType(int type) {
-    switch (type) {
-        case SOCK_STREAM:
-            return IPPROTO_TCP;
-        case SOCK_DGRAM:
-            return IPPROTO_UDP;
-        default:
-            LOG(FATAL) << "Unknown socket type: " << type;
-            return 0;
-    }
-}
-
-int network_loopback_client(int port, int type, std::string* error) {
-    struct sockaddr_in addr;
-    SOCKET s;
-
-    unique_fh f(_fh_alloc(&_fh_socket_class));
-    if (!f) {
-        *error = strerror(errno);
-        return -1;
-    }
-
-    memset(&addr, 0, sizeof(addr));
-    addr.sin_family = AF_INET;
-    addr.sin_port = htons(port);
-    addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
-
-    s = socket(AF_INET, type, GetSocketProtocolFromSocketType(type));
-    if (s == INVALID_SOCKET) {
-        const DWORD err = WSAGetLastError();
-        *error = android::base::StringPrintf("cannot create socket: %s",
-                                             android::base::SystemErrorCodeToString(err).c_str());
-        D("%s", error->c_str());
-        _socket_set_errno(err);
-        return -1;
-    }
-    f->fh_socket = s;
-
-    if (connect(s, (struct sockaddr*)&addr, sizeof(addr)) == SOCKET_ERROR) {
-        // Save err just in case inet_ntoa() or ntohs() changes the last error.
-        const DWORD err = WSAGetLastError();
-        *error = android::base::StringPrintf("cannot connect to %s:%u: %s",
-                                             inet_ntoa(addr.sin_addr), ntohs(addr.sin_port),
-                                             android::base::SystemErrorCodeToString(err).c_str());
-        D("could not connect to %s:%d: %s", type != SOCK_STREAM ? "udp" : "tcp", port,
-          error->c_str());
-        _socket_set_errno(err);
-        return -1;
-    }
-
-    const int fd = _fh_to_int(f.get());
-    snprintf(f->name, sizeof(f->name), "%d(lo-client:%s%d)", fd, type != SOCK_STREAM ? "udp:" : "",
-             port);
-    D("port %d type %s => fd %d", port, type != SOCK_STREAM ? "udp" : "tcp", fd);
-    f.release();
-    return fd;
-}
-
-// interface_address is INADDR_LOOPBACK or INADDR_ANY.
-static int _network_server(int port, int type, u_long interface_address, std::string* error) {
-    struct sockaddr_in addr;
-    SOCKET s;
-    int n;
-
-    unique_fh f(_fh_alloc(&_fh_socket_class));
-    if (!f) {
-        *error = strerror(errno);
-        return -1;
-    }
-
-    memset(&addr, 0, sizeof(addr));
-    addr.sin_family = AF_INET;
-    addr.sin_port = htons(port);
-    addr.sin_addr.s_addr = htonl(interface_address);
-
-    // TODO: Consider using dual-stack socket that can simultaneously listen on
-    // IPv4 and IPv6.
-    s = socket(AF_INET, type, GetSocketProtocolFromSocketType(type));
-    if (s == INVALID_SOCKET) {
-        const DWORD err = WSAGetLastError();
-        *error = android::base::StringPrintf("cannot create socket: %s",
-                                             android::base::SystemErrorCodeToString(err).c_str());
-        D("%s", error->c_str());
-        _socket_set_errno(err);
-        return -1;
-    }
-
-    f->fh_socket = s;
-
-    // Note: SO_REUSEADDR on Windows allows multiple processes to bind to the
-    // same port, so instead use SO_EXCLUSIVEADDRUSE.
-    n = 1;
-    if (setsockopt(s, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (const char*)&n, sizeof(n)) == SOCKET_ERROR) {
-        const DWORD err = WSAGetLastError();
-        *error = android::base::StringPrintf("cannot set socket option SO_EXCLUSIVEADDRUSE: %s",
-                                             android::base::SystemErrorCodeToString(err).c_str());
-        D("%s", error->c_str());
-        _socket_set_errno(err);
-        return -1;
-    }
-
-    if (bind(s, (struct sockaddr*)&addr, sizeof(addr)) == SOCKET_ERROR) {
-        // Save err just in case inet_ntoa() or ntohs() changes the last error.
-        const DWORD err = WSAGetLastError();
-        *error = android::base::StringPrintf("cannot bind to %s:%u: %s", inet_ntoa(addr.sin_addr),
-                                             ntohs(addr.sin_port),
-                                             android::base::SystemErrorCodeToString(err).c_str());
-        D("could not bind to %s:%d: %s", type != SOCK_STREAM ? "udp" : "tcp", port, error->c_str());
-        _socket_set_errno(err);
-        return -1;
-    }
-    if (type == SOCK_STREAM) {
-        if (listen(s, SOMAXCONN) == SOCKET_ERROR) {
-            const DWORD err = WSAGetLastError();
-            *error = android::base::StringPrintf(
-                "cannot listen on socket: %s", android::base::SystemErrorCodeToString(err).c_str());
-            D("could not listen on %s:%d: %s", type != SOCK_STREAM ? "udp" : "tcp", port,
-              error->c_str());
-            _socket_set_errno(err);
-            return -1;
-        }
-    }
-    const int fd = _fh_to_int(f.get());
-    snprintf(f->name, sizeof(f->name), "%d(%s-server:%s%d)", fd,
-             interface_address == INADDR_LOOPBACK ? "lo" : "any", type != SOCK_STREAM ? "udp:" : "",
-             port);
-    D("port %d type %s => fd %d", port, type != SOCK_STREAM ? "udp" : "tcp", fd);
-    f.release();
-    return fd;
-}
-
-int network_loopback_server(int port, int type, std::string* error, bool prefer_ipv4) {
-    // TODO implement IPv6 support on windows
-    return _network_server(port, type, INADDR_LOOPBACK, error);
-}
-
-int network_inaddr_any_server(int port, int type, std::string* error) {
-    return _network_server(port, type, INADDR_ANY, error);
-}
-
-int network_connect(const std::string& host, int port, int type, int timeout, std::string* error) {
-    unique_fh f(_fh_alloc(&_fh_socket_class));
-    if (!f) {
-        *error = strerror(errno);
-        return -1;
-    }
-
-    struct addrinfo hints;
-    memset(&hints, 0, sizeof(hints));
-    hints.ai_family = AF_UNSPEC;
-    hints.ai_socktype = type;
-    hints.ai_protocol = GetSocketProtocolFromSocketType(type);
-
-    char port_str[16];
-    snprintf(port_str, sizeof(port_str), "%d", port);
-
-    struct addrinfo* addrinfo_ptr = nullptr;
-
-#if (NTDDI_VERSION >= NTDDI_WINXPSP2) || (_WIN32_WINNT >= _WIN32_WINNT_WS03)
-// TODO: When the Android SDK tools increases the Windows system
-// requirements >= WinXP SP2, switch to android::base::UTF8ToWide() + GetAddrInfoW().
-#else
-// Otherwise, keep using getaddrinfo(), or do runtime API detection
-// with GetProcAddress("GetAddrInfoW").
-#endif
-    if (getaddrinfo(host.c_str(), port_str, &hints, &addrinfo_ptr) != 0) {
-        const DWORD err = WSAGetLastError();
-        *error = android::base::StringPrintf("cannot resolve host '%s' and port %s: %s",
-                                             host.c_str(), port_str,
-                                             android::base::SystemErrorCodeToString(err).c_str());
-
-        D("%s", error->c_str());
-        _socket_set_errno(err);
-        return -1;
-    }
-    std::unique_ptr<struct addrinfo, decltype(&freeaddrinfo)> addrinfo(addrinfo_ptr, freeaddrinfo);
-    addrinfo_ptr = nullptr;
-
-    // TODO: Try all the addresses if there's more than one? This just uses
-    // the first. Or, could call WSAConnectByName() (Windows Vista and newer)
-    // which tries all addresses, takes a timeout and more.
-    SOCKET s = socket(addrinfo->ai_family, addrinfo->ai_socktype, addrinfo->ai_protocol);
-    if (s == INVALID_SOCKET) {
-        const DWORD err = WSAGetLastError();
-        *error = android::base::StringPrintf("cannot create socket: %s",
-                                             android::base::SystemErrorCodeToString(err).c_str());
-        D("%s", error->c_str());
-        _socket_set_errno(err);
-        return -1;
-    }
-    f->fh_socket = s;
-
-    // TODO: Implement timeouts for Windows. Seems like the default in theory
-    // (according to http://serverfault.com/a/671453) and in practice is 21 sec.
-    if (connect(s, addrinfo->ai_addr, addrinfo->ai_addrlen) == SOCKET_ERROR) {
-        // TODO: Use WSAAddressToString or inet_ntop on address.
-        const DWORD err = WSAGetLastError();
-        *error = android::base::StringPrintf("cannot connect to %s:%s: %s", host.c_str(), port_str,
-                                             android::base::SystemErrorCodeToString(err).c_str());
-        D("could not connect to %s:%s:%s: %s", type != SOCK_STREAM ? "udp" : "tcp", host.c_str(),
-          port_str, error->c_str());
-        _socket_set_errno(err);
-        return -1;
-    }
-
-    const int fd = _fh_to_int(f.get());
-    snprintf(f->name, sizeof(f->name), "%d(net-client:%s%d)", fd, type != SOCK_STREAM ? "udp:" : "",
-             port);
-    D("host '%s' port %d type %s => fd %d", host.c_str(), port, type != SOCK_STREAM ? "udp" : "tcp",
-      fd);
-    f.release();
-    return fd;
-}
-
-int adb_register_socket(SOCKET s) {
-    FH f = _fh_alloc(&_fh_socket_class);
-    f->fh_socket = s;
-    return _fh_to_int(f);
-}
-
-static bool isBlankStr(const char* str) {
-    for (; *str != '\0'; ++str) {
-        if (!isblank(*str)) {
-            return false;
-        }
-    }
-    return true;
-}
-
-int adb_gethostname(char* name, size_t len) {
-    const char* computerName = adb_getenv("COMPUTERNAME");
-    if (computerName && !isBlankStr(computerName)) {
-        strncpy(name, computerName, len);
-        name[len - 1] = '\0';
-        return 0;
-    }
-
-    wchar_t buffer[MAX_COMPUTERNAME_LENGTH + 1];
-    DWORD size = sizeof(buffer);
-    if (!GetComputerNameW(buffer, &size)) {
-        return -1;
-    }
-    std::string name_utf8;
-    if (!android::base::WideToUTF8(buffer, &name_utf8)) {
-        return -1;
-    }
-
-    strncpy(name, name_utf8.c_str(), len);
-    name[len - 1] = '\0';
-    return 0;
-}
-
-int adb_getlogin_r(char* buf, size_t bufsize) {
-    wchar_t buffer[UNLEN + 1];
-    DWORD len = sizeof(buffer);
-    if (!GetUserNameW(buffer, &len)) {
-        return -1;
-    }
-
-    std::string login;
-    if (!android::base::WideToUTF8(buffer, &login)) {
-        return -1;
-    }
-
-    strncpy(buf, login.c_str(), bufsize);
-    buf[bufsize - 1] = '\0';
-    return 0;
-}
-
-#undef accept
-int adb_socket_accept(borrowed_fd serverfd, struct sockaddr* addr, socklen_t* addrlen) {
-    FH serverfh = _fh_from_int(serverfd, __func__);
-
-    if (!serverfh || serverfh->clazz != &_fh_socket_class) {
-        D("adb_socket_accept: invalid fd %d", serverfd.get());
-        errno = EBADF;
-        return -1;
-    }
-
-    unique_fh fh(_fh_alloc(&_fh_socket_class));
-    if (!fh) {
-        PLOG(ERROR) << "adb_socket_accept: failed to allocate accepted socket "
-                       "descriptor";
-        return -1;
-    }
-
-    fh->fh_socket = accept(serverfh->fh_socket, addr, addrlen);
-    if (fh->fh_socket == INVALID_SOCKET) {
-        const DWORD err = WSAGetLastError();
-        LOG(ERROR) << "adb_socket_accept: accept on fd " << serverfd.get()
-                   << " failed: " + android::base::SystemErrorCodeToString(err);
-        _socket_set_errno(err);
-        return -1;
-    }
-
-    const int fd = _fh_to_int(fh.get());
-    snprintf(fh->name, sizeof(fh->name), "%d(accept:%s)", fd, serverfh->name);
-    D("adb_socket_accept on fd %d returns fd %d", serverfd.get(), fd);
-    fh.release();
-    return fd;
-}
-
-int adb_setsockopt(borrowed_fd fd, int level, int optname, const void* optval, socklen_t optlen) {
-    FH fh = _fh_from_int(fd, __func__);
-
-    if (!fh || fh->clazz != &_fh_socket_class) {
-        D("adb_setsockopt: invalid fd %d", fd.get());
-        errno = EBADF;
-        return -1;
-    }
-
-    // TODO: Once we can assume Windows Vista or later, if the caller is trying
-    // to set SOL_SOCKET, SO_SNDBUF/SO_RCVBUF, ignore it since the OS has
-    // auto-tuning.
-
-    int result =
-        setsockopt(fh->fh_socket, level, optname, reinterpret_cast<const char*>(optval), optlen);
-    if (result == SOCKET_ERROR) {
-        const DWORD err = WSAGetLastError();
-        D("adb_setsockopt: setsockopt on fd %d level %d optname %d failed: %s\n", fd.get(), level,
-          optname, android::base::SystemErrorCodeToString(err).c_str());
-        _socket_set_errno(err);
-        result = -1;
-    }
-    return result;
-}
-
-static int adb_getsockname(borrowed_fd fd, struct sockaddr* sockaddr, socklen_t* optlen) {
-    FH fh = _fh_from_int(fd, __func__);
-
-    if (!fh || fh->clazz != &_fh_socket_class) {
-        D("adb_getsockname: invalid fd %d", fd.get());
-        errno = EBADF;
-        return -1;
-    }
-
-    int result = getsockname(fh->fh_socket, sockaddr, optlen);
-    if (result == SOCKET_ERROR) {
-        const DWORD err = WSAGetLastError();
-        D("adb_getsockname: setsockopt on fd %d failed: %s\n", fd.get(),
-          android::base::SystemErrorCodeToString(err).c_str());
-        _socket_set_errno(err);
-        result = -1;
-    }
-    return result;
-}
-
-int adb_socket_get_local_port(borrowed_fd fd) {
-    sockaddr_storage addr_storage;
-    socklen_t addr_len = sizeof(addr_storage);
-
-    if (adb_getsockname(fd, reinterpret_cast<sockaddr*>(&addr_storage), &addr_len) < 0) {
-        D("adb_socket_get_local_port: adb_getsockname failed: %s", strerror(errno));
-        return -1;
-    }
-
-    if (!(addr_storage.ss_family == AF_INET || addr_storage.ss_family == AF_INET6)) {
-        D("adb_socket_get_local_port: unknown address family received: %d", addr_storage.ss_family);
-        errno = ECONNABORTED;
-        return -1;
-    }
-
-    return ntohs(reinterpret_cast<sockaddr_in*>(&addr_storage)->sin_port);
-}
-
-int adb_shutdown(borrowed_fd fd, int direction) {
-    FH f = _fh_from_int(fd, __func__);
-
-    if (!f || f->clazz != &_fh_socket_class) {
-        D("adb_shutdown: invalid fd %d", fd.get());
-        errno = EBADF;
-        return -1;
-    }
-
-    D("adb_shutdown: %s", f->name);
-    if (shutdown(f->fh_socket, direction) == SOCKET_ERROR) {
-        const DWORD err = WSAGetLastError();
-        D("socket shutdown fd %d failed: %s", fd.get(),
-          android::base::SystemErrorCodeToString(err).c_str());
-        _socket_set_errno(err);
-        return -1;
-    }
-    return 0;
-}
-
-// Emulate socketpair(2) by binding and connecting to a socket.
-int adb_socketpair(int sv[2]) {
-    int server = -1;
-    int client = -1;
-    int accepted = -1;
-    int local_port = -1;
-    std::string error;
-
-    server = network_loopback_server(0, SOCK_STREAM, &error, true);
-    if (server < 0) {
-        D("adb_socketpair: failed to create server: %s", error.c_str());
-        goto fail;
-    }
-
-    local_port = adb_socket_get_local_port(server);
-    if (local_port < 0) {
-        D("adb_socketpair: failed to get server port number: %s", error.c_str());
-        goto fail;
-    }
-    D("adb_socketpair: bound on port %d", local_port);
-
-    client = network_loopback_client(local_port, SOCK_STREAM, &error);
-    if (client < 0) {
-        D("adb_socketpair: failed to connect client: %s", error.c_str());
-        goto fail;
-    }
-
-    accepted = adb_socket_accept(server, nullptr, nullptr);
-    if (accepted < 0) {
-        D("adb_socketpair: failed to accept: %s", strerror(errno));
-        goto fail;
-    }
-    adb_close(server);
-    sv[0] = client;
-    sv[1] = accepted;
-    return 0;
-
-fail:
-    if (server >= 0) {
-        adb_close(server);
-    }
-    if (client >= 0) {
-        adb_close(client);
-    }
-    if (accepted >= 0) {
-        adb_close(accepted);
-    }
-    return -1;
-}
-
-bool set_file_block_mode(borrowed_fd fd, bool block) {
-    FH fh = _fh_from_int(fd, __func__);
-
-    if (!fh || !fh->used) {
-        errno = EBADF;
-        D("Setting nonblocking on bad file descriptor %d", fd.get());
-        return false;
-    }
-
-    if (fh->clazz == &_fh_socket_class) {
-        u_long x = !block;
-        if (ioctlsocket(fh->u.socket, FIONBIO, &x) != 0) {
-            int error = WSAGetLastError();
-            _socket_set_errno(error);
-            D("Setting %d nonblocking failed (%d)", fd.get(), error);
-            return false;
-        }
-        return true;
-    } else {
-        errno = ENOTSOCK;
-        D("Setting nonblocking on non-socket %d", fd.get());
-        return false;
-    }
-}
-
-bool set_tcp_keepalive(borrowed_fd fd, int interval_sec) {
-    FH fh = _fh_from_int(fd, __func__);
-
-    if (!fh || fh->clazz != &_fh_socket_class) {
-        D("set_tcp_keepalive(%d) failed: invalid fd", fd.get());
-        errno = EBADF;
-        return false;
-    }
-
-    tcp_keepalive keepalive;
-    keepalive.onoff = (interval_sec > 0);
-    keepalive.keepalivetime = interval_sec * 1000;
-    keepalive.keepaliveinterval = interval_sec * 1000;
-
-    DWORD bytes_returned = 0;
-    if (WSAIoctl(fh->fh_socket, SIO_KEEPALIVE_VALS, &keepalive, sizeof(keepalive), nullptr, 0,
-                 &bytes_returned, nullptr, nullptr) != 0) {
-        const DWORD err = WSAGetLastError();
-        D("set_tcp_keepalive(%d) failed: %s", fd.get(),
-          android::base::SystemErrorCodeToString(err).c_str());
-        _socket_set_errno(err);
-        return false;
-    }
-
-    return true;
-}
-
-/**************************************************************************/
-/**************************************************************************/
-/*****                                                                *****/
-/*****      Console Window Terminal Emulation                         *****/
-/*****                                                                *****/
-/**************************************************************************/
-/**************************************************************************/
-
-// This reads input from a Win32 console window and translates it into Unix
-// terminal-style sequences. This emulates mostly Gnome Terminal (in Normal
-// mode, not Application mode), which itself emulates xterm. Gnome Terminal
-// is emulated instead of xterm because it is probably more popular than xterm:
-// Ubuntu's default Ctrl-Alt-T shortcut opens Gnome Terminal, Gnome Terminal
-// supports modern fonts, etc. It seems best to emulate the terminal that most
-// Android developers use because they'll fix apps (the shell, etc.) to keep
-// working with that terminal's emulation.
-//
-// The point of this emulation is not to be perfect or to solve all issues with
-// console windows on Windows, but to be better than the original code which
-// just called read() (which called ReadFile(), which called ReadConsoleA())
-// which did not support Ctrl-C, tab completion, shell input line editing
-// keys, server echo, and more.
-//
-// This implementation reconfigures the console with SetConsoleMode(), then
-// calls ReadConsoleInput() to get raw input which it remaps to Unix
-// terminal-style sequences which is returned via unix_read() which is used
-// by the 'adb shell' command.
-//
-// Code organization:
-//
-// * _get_console_handle() and unix_isatty() provide console information.
-// * stdin_raw_init() and stdin_raw_restore() reconfigure the console.
-// * unix_read() detects console windows (as opposed to pipes, files, etc.).
-// * _console_read() is the main code of the emulation.
-
-// Returns a console HANDLE if |fd| is a console, otherwise returns nullptr.
-// If a valid HANDLE is returned and |mode| is not null, |mode| is also filled
-// with the console mode. Requires GENERIC_READ access to the underlying HANDLE.
-static HANDLE _get_console_handle(borrowed_fd fd, DWORD* mode = nullptr) {
-    // First check isatty(); this is very fast and eliminates most non-console
-    // FDs, but returns 1 for both consoles and character devices like NUL.
-#pragma push_macro("isatty")
-#undef isatty
-    if (!isatty(fd.get())) {
-        return nullptr;
-    }
-#pragma pop_macro("isatty")
-
-    // To differentiate between character devices and consoles we need to get
-    // the underlying HANDLE and use GetConsoleMode(), which is what requires
-    // GENERIC_READ permissions.
-    const intptr_t intptr_handle = _get_osfhandle(fd.get());
-    if (intptr_handle == -1) {
-        return nullptr;
-    }
-    const HANDLE handle = reinterpret_cast<const HANDLE>(intptr_handle);
-    DWORD temp_mode = 0;
-    if (!GetConsoleMode(handle, mode ? mode : &temp_mode)) {
-        return nullptr;
-    }
-
-    return handle;
-}
-
-// Returns a console handle if |stream| is a console, otherwise returns nullptr.
-static HANDLE _get_console_handle(FILE* const stream) {
-    // Save and restore errno to make it easier for callers to prevent from overwriting errno.
-    android::base::ErrnoRestorer er;
-    const int fd = fileno(stream);
-    if (fd < 0) {
-        return nullptr;
-    }
-    return _get_console_handle(fd);
-}
-
-int unix_isatty(borrowed_fd fd) {
-    return _get_console_handle(fd) ? 1 : 0;
-}
-
-// Get the next KEY_EVENT_RECORD that should be processed.
-static bool _get_key_event_record(const HANDLE console, INPUT_RECORD* const input_record) {
-    for (;;) {
-        DWORD read_count = 0;
-        memset(input_record, 0, sizeof(*input_record));
-        if (!ReadConsoleInputA(console, input_record, 1, &read_count)) {
-            D("_get_key_event_record: ReadConsoleInputA() failed: %s\n",
-              android::base::SystemErrorCodeToString(GetLastError()).c_str());
-            errno = EIO;
-            return false;
-        }
-
-        if (read_count == 0) {   // should be impossible
-            LOG(FATAL) << "ReadConsoleInputA returned 0";
-        }
-
-        if (read_count != 1) {   // should be impossible
-            LOG(FATAL) << "ReadConsoleInputA did not return one input record";
-        }
-
-        // If the console window is resized, emulate SIGWINCH by breaking out
-        // of read() with errno == EINTR. Note that there is no event on
-        // vertical resize because we don't give the console our own custom
-        // screen buffer (with CreateConsoleScreenBuffer() +
-        // SetConsoleActiveScreenBuffer()). Instead, we use the default which
-        // supports scrollback, but doesn't seem to raise an event for vertical
-        // window resize.
-        if (input_record->EventType == WINDOW_BUFFER_SIZE_EVENT) {
-            errno = EINTR;
-            return false;
-        }
-
-        if ((input_record->EventType == KEY_EVENT) &&
-            (input_record->Event.KeyEvent.bKeyDown)) {
-            if (input_record->Event.KeyEvent.wRepeatCount == 0) {
-                LOG(FATAL) << "ReadConsoleInputA returned a key event with zero repeat count";
-            }
-
-            // Got an interesting INPUT_RECORD, so return
-            return true;
-        }
-    }
-}
-
-static __inline__ bool _is_shift_pressed(const DWORD control_key_state) {
-    return (control_key_state & SHIFT_PRESSED) != 0;
-}
-
-static __inline__ bool _is_ctrl_pressed(const DWORD control_key_state) {
-    return (control_key_state & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) != 0;
-}
-
-static __inline__ bool _is_alt_pressed(const DWORD control_key_state) {
-    return (control_key_state & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)) != 0;
-}
-
-static __inline__ bool _is_numlock_on(const DWORD control_key_state) {
-    return (control_key_state & NUMLOCK_ON) != 0;
-}
-
-static __inline__ bool _is_capslock_on(const DWORD control_key_state) {
-    return (control_key_state & CAPSLOCK_ON) != 0;
-}
-
-static __inline__ bool _is_enhanced_key(const DWORD control_key_state) {
-    return (control_key_state & ENHANCED_KEY) != 0;
-}
-
-// Constants from MSDN for ToAscii().
-static const BYTE TOASCII_KEY_OFF = 0x00;
-static const BYTE TOASCII_KEY_DOWN = 0x80;
-static const BYTE TOASCII_KEY_TOGGLED_ON = 0x01;   // for CapsLock
-
-// Given a key event, ignore a modifier key and return the character that was
-// entered without the modifier. Writes to *ch and returns the number of bytes
-// written.
-static size_t _get_char_ignoring_modifier(char* const ch,
-    const KEY_EVENT_RECORD* const key_event, const DWORD control_key_state,
-    const WORD modifier) {
-    // If there is no character from Windows, try ignoring the specified
-    // modifier and look for a character. Note that if AltGr is being used,
-    // there will be a character from Windows.
-    if (key_event->uChar.AsciiChar == '\0') {
-        // Note that we read the control key state from the passed in argument
-        // instead of from key_event since the argument has been normalized.
-        if (((modifier == VK_SHIFT)   &&
-            _is_shift_pressed(control_key_state)) ||
-            ((modifier == VK_CONTROL) &&
-            _is_ctrl_pressed(control_key_state)) ||
-            ((modifier == VK_MENU)    && _is_alt_pressed(control_key_state))) {
-
-            BYTE key_state[256]   = {0};
-            key_state[VK_SHIFT]   = _is_shift_pressed(control_key_state) ?
-                TOASCII_KEY_DOWN : TOASCII_KEY_OFF;
-            key_state[VK_CONTROL] = _is_ctrl_pressed(control_key_state)  ?
-                TOASCII_KEY_DOWN : TOASCII_KEY_OFF;
-            key_state[VK_MENU]    = _is_alt_pressed(control_key_state)   ?
-                TOASCII_KEY_DOWN : TOASCII_KEY_OFF;
-            key_state[VK_CAPITAL] = _is_capslock_on(control_key_state)   ?
-                TOASCII_KEY_TOGGLED_ON : TOASCII_KEY_OFF;
-
-            // cause this modifier to be ignored
-            key_state[modifier]   = TOASCII_KEY_OFF;
-
-            WORD translated = 0;
-            if (ToAscii(key_event->wVirtualKeyCode,
-                key_event->wVirtualScanCode, key_state, &translated, 0) == 1) {
-                // Ignoring the modifier, we found a character.
-                *ch = (CHAR)translated;
-                return 1;
-            }
-        }
-    }
-
-    // Just use whatever Windows told us originally.
-    *ch = key_event->uChar.AsciiChar;
-
-    // If the character from Windows is NULL, return a size of zero.
-    return (*ch == '\0') ? 0 : 1;
-}
-
-// If a Ctrl key is pressed, lookup the character, ignoring the Ctrl key,
-// but taking into account the shift key. This is because for a sequence like
-// Ctrl-Alt-0, we want to find the character '0' and for Ctrl-Alt-Shift-0,
-// we want to find the character ')'.
-//
-// Note that Windows doesn't seem to pass bKeyDown for Ctrl-Shift-NoAlt-0
-// because it is the default key-sequence to switch the input language.
-// This is configurable in the Region and Language control panel.
-static __inline__ size_t _get_non_control_char(char* const ch,
-    const KEY_EVENT_RECORD* const key_event, const DWORD control_key_state) {
-    return _get_char_ignoring_modifier(ch, key_event, control_key_state,
-        VK_CONTROL);
-}
-
-// Get without Alt.
-static __inline__ size_t _get_non_alt_char(char* const ch,
-    const KEY_EVENT_RECORD* const key_event, const DWORD control_key_state) {
-    return _get_char_ignoring_modifier(ch, key_event, control_key_state,
-        VK_MENU);
-}
-
-// Ignore the control key, find the character from Windows, and apply any
-// Control key mappings (for example, Ctrl-2 is a NULL character). Writes to
-// *pch and returns number of bytes written.
-static size_t _get_control_character(char* const pch,
-    const KEY_EVENT_RECORD* const key_event, const DWORD control_key_state) {
-    const size_t len = _get_non_control_char(pch, key_event,
-        control_key_state);
-
-    if ((len == 1) && _is_ctrl_pressed(control_key_state)) {
-        char ch = *pch;
-        switch (ch) {
-        case '2':
-        case '@':
-        case '`':
-            ch = '\0';
-            break;
-        case '3':
-        case '[':
-        case '{':
-            ch = '\x1b';
-            break;
-        case '4':
-        case '\\':
-        case '|':
-            ch = '\x1c';
-            break;
-        case '5':
-        case ']':
-        case '}':
-            ch = '\x1d';
-            break;
-        case '6':
-        case '^':
-        case '~':
-            ch = '\x1e';
-            break;
-        case '7':
-        case '-':
-        case '_':
-            ch = '\x1f';
-            break;
-        case '8':
-            ch = '\x7f';
-            break;
-        case '/':
-            if (!_is_alt_pressed(control_key_state)) {
-                ch = '\x1f';
-            }
-            break;
-        case '?':
-            if (!_is_alt_pressed(control_key_state)) {
-                ch = '\x7f';
-            }
-            break;
-        }
-        *pch = ch;
-    }
-
-    return len;
-}
-
-static DWORD _normalize_altgr_control_key_state(
-    const KEY_EVENT_RECORD* const key_event) {
-    DWORD control_key_state = key_event->dwControlKeyState;
-
-    // If we're in an AltGr situation where the AltGr key is down (depending on
-    // the keyboard layout, that might be the physical right alt key which
-    // produces a control_key_state where Right-Alt and Left-Ctrl are down) or
-    // AltGr-equivalent keys are down (any Ctrl key + any Alt key), and we have
-    // a character (which indicates that there was an AltGr mapping), then act
-    // as if alt and control are not really down for the purposes of modifiers.
-    // This makes it so that if the user with, say, a German keyboard layout
-    // presses AltGr-] (which we see as Right-Alt + Left-Ctrl + key), we just
-    // output the key and we don't see the Alt and Ctrl keys.
-    if (_is_ctrl_pressed(control_key_state) &&
-        _is_alt_pressed(control_key_state)
-        && (key_event->uChar.AsciiChar != '\0')) {
-        // Try to remove as few bits as possible to improve our chances of
-        // detecting combinations like Left-Alt + AltGr, Right-Ctrl + AltGr, or
-        // Left-Alt + Right-Ctrl + AltGr.
-        if ((control_key_state & RIGHT_ALT_PRESSED) != 0) {
-            // Remove Right-Alt.
-            control_key_state &= ~RIGHT_ALT_PRESSED;
-            // If uChar is set, a Ctrl key is pressed, and Right-Alt is
-            // pressed, Left-Ctrl is almost always set, except if the user
-            // presses Right-Ctrl, then AltGr (in that specific order) for
-            // whatever reason. At any rate, make sure the bit is not set.
-            control_key_state &= ~LEFT_CTRL_PRESSED;
-        } else if ((control_key_state & LEFT_ALT_PRESSED) != 0) {
-            // Remove Left-Alt.
-            control_key_state &= ~LEFT_ALT_PRESSED;
-            // Whichever Ctrl key is down, remove it from the state. We only
-            // remove one key, to improve our chances of detecting the
-            // corner-case of Left-Ctrl + Left-Alt + Right-Ctrl.
-            if ((control_key_state & LEFT_CTRL_PRESSED) != 0) {
-                // Remove Left-Ctrl.
-                control_key_state &= ~LEFT_CTRL_PRESSED;
-            } else if ((control_key_state & RIGHT_CTRL_PRESSED) != 0) {
-                // Remove Right-Ctrl.
-                control_key_state &= ~RIGHT_CTRL_PRESSED;
-            }
-        }
-
-        // Note that this logic isn't 100% perfect because Windows doesn't
-        // allow us to detect all combinations because a physical AltGr key
-        // press shows up as two bits, plus some combinations are ambiguous
-        // about what is actually physically pressed.
-    }
-
-    return control_key_state;
-}
-
-// If NumLock is on and Shift is pressed, SHIFT_PRESSED is not set in
-// dwControlKeyState for the following keypad keys: period, 0-9. If we detect
-// this scenario, set the SHIFT_PRESSED bit so we can add modifiers
-// appropriately.
-static DWORD _normalize_keypad_control_key_state(const WORD vk,
-    const DWORD control_key_state) {
-    if (!_is_numlock_on(control_key_state)) {
-        return control_key_state;
-    }
-    if (!_is_enhanced_key(control_key_state)) {
-        switch (vk) {
-            case VK_INSERT: // 0
-            case VK_DELETE: // .
-            case VK_END:    // 1
-            case VK_DOWN:   // 2
-            case VK_NEXT:   // 3
-            case VK_LEFT:   // 4
-            case VK_CLEAR:  // 5
-            case VK_RIGHT:  // 6
-            case VK_HOME:   // 7
-            case VK_UP:     // 8
-            case VK_PRIOR:  // 9
-                return control_key_state | SHIFT_PRESSED;
-        }
-    }
-
-    return control_key_state;
-}
-
-static const char* _get_keypad_sequence(const DWORD control_key_state,
-    const char* const normal, const char* const shifted) {
-    if (_is_shift_pressed(control_key_state)) {
-        // Shift is pressed and NumLock is off
-        return shifted;
-    } else {
-        // Shift is not pressed and NumLock is off, or,
-        // Shift is pressed and NumLock is on, in which case we want the
-        // NumLock and Shift to neutralize each other, thus, we want the normal
-        // sequence.
-        return normal;
-    }
-    // If Shift is not pressed and NumLock is on, a different virtual key code
-    // is returned by Windows, which can be taken care of by a different case
-    // statement in _console_read().
-}
-
-// Write sequence to buf and return the number of bytes written.
-static size_t _get_modifier_sequence(char* const buf, const WORD vk,
-    DWORD control_key_state, const char* const normal) {
-    // Copy the base sequence into buf.
-    const size_t len = strlen(normal);
-    memcpy(buf, normal, len);
-
-    int code = 0;
-
-    control_key_state = _normalize_keypad_control_key_state(vk,
-        control_key_state);
-
-    if (_is_shift_pressed(control_key_state)) {
-        code |= 0x1;
-    }
-    if (_is_alt_pressed(control_key_state)) {   // any alt key pressed
-        code |= 0x2;
-    }
-    if (_is_ctrl_pressed(control_key_state)) {  // any control key pressed
-        code |= 0x4;
-    }
-    // If some modifier was held down, then we need to insert the modifier code
-    if (code != 0) {
-        if (len == 0) {
-            // Should be impossible because caller should pass a string of
-            // non-zero length.
-            return 0;
-        }
-        size_t index = len - 1;
-        const char lastChar = buf[index];
-        if (lastChar != '~') {
-            buf[index++] = '1';
-        }
-        buf[index++] = ';';         // modifier separator
-        // 2 = shift, 3 = alt, 4 = shift & alt, 5 = control,
-        // 6 = shift & control, 7 = alt & control, 8 = shift & alt & control
-        buf[index++] = '1' + code;
-        buf[index++] = lastChar;    // move ~ (or other last char) to the end
-        return index;
-    }
-    return len;
-}
-
-// Write sequence to buf and return the number of bytes written.
-static size_t _get_modifier_keypad_sequence(char* const buf, const WORD vk,
-    const DWORD control_key_state, const char* const normal,
-    const char shifted) {
-    if (_is_shift_pressed(control_key_state)) {
-        // Shift is pressed and NumLock is off
-        if (shifted != '\0') {
-            buf[0] = shifted;
-            return sizeof(buf[0]);
-        } else {
-            return 0;
-        }
-    } else {
-        // Shift is not pressed and NumLock is off, or,
-        // Shift is pressed and NumLock is on, in which case we want the
-        // NumLock and Shift to neutralize each other, thus, we want the normal
-        // sequence.
-        return _get_modifier_sequence(buf, vk, control_key_state, normal);
-    }
-    // If Shift is not pressed and NumLock is on, a different virtual key code
-    // is returned by Windows, which can be taken care of by a different case
-    // statement in _console_read().
-}
-
-// The decimal key on the keypad produces a '.' for U.S. English and a ',' for
-// Standard German. Figure this out at runtime so we know what to output for
-// Shift-VK_DELETE.
-static char _get_decimal_char() {
-    return (char)MapVirtualKeyA(VK_DECIMAL, MAPVK_VK_TO_CHAR);
-}
-
-// Prefix the len bytes in buf with the escape character, and then return the
-// new buffer length.
-static size_t _escape_prefix(char* const buf, const size_t len) {
-    // If nothing to prefix, don't do anything. We might be called with
-    // len == 0, if alt was held down with a dead key which produced nothing.
-    if (len == 0) {
-        return 0;
-    }
-
-    memmove(&buf[1], buf, len);
-    buf[0] = '\x1b';
-    return len + 1;
-}
-
-// Internal buffer to satisfy future _console_read() calls.
-static auto& g_console_input_buffer = *new std::vector<char>();
-
-// Writes to buffer buf (of length len), returning number of bytes written or -1 on error. Never
-// returns zero on console closure because Win32 consoles are never 'closed' (as far as I can tell).
-static int _console_read(const HANDLE console, void* buf, size_t len) {
-    for (;;) {
-        // Read of zero bytes should not block waiting for something from the console.
-        if (len == 0) {
-            return 0;
-        }
-
-        // Flush as much as possible from input buffer.
-        if (!g_console_input_buffer.empty()) {
-            const int bytes_read = std::min(len, g_console_input_buffer.size());
-            memcpy(buf, g_console_input_buffer.data(), bytes_read);
-            const auto begin = g_console_input_buffer.begin();
-            g_console_input_buffer.erase(begin, begin + bytes_read);
-            return bytes_read;
-        }
-
-        // Read from the actual console. This may block until input.
-        INPUT_RECORD input_record;
-        if (!_get_key_event_record(console, &input_record)) {
-            return -1;
-        }
-
-        KEY_EVENT_RECORD* const key_event = &input_record.Event.KeyEvent;
-        const WORD vk = key_event->wVirtualKeyCode;
-        const CHAR ch = key_event->uChar.AsciiChar;
-        const DWORD control_key_state = _normalize_altgr_control_key_state(
-            key_event);
-
-        // The following emulation code should write the output sequence to
-        // either seqstr or to seqbuf and seqbuflen.
-        const char* seqstr = nullptr;  // NULL terminated C-string
-        // Enough space for max sequence string below, plus modifiers and/or
-        // escape prefix.
-        char seqbuf[16];
-        size_t seqbuflen = 0;       // Space used in seqbuf.
-
-#define MATCH(vk, normal) \
-            case (vk): \
-            { \
-                seqstr = (normal); \
-            } \
-            break;
-
-        // Modifier keys should affect the output sequence.
-#define MATCH_MODIFIER(vk, normal) \
-            case (vk): \
-            { \
-                seqbuflen = _get_modifier_sequence(seqbuf, (vk), \
-                    control_key_state, (normal)); \
-            } \
-            break;
-
-        // The shift key should affect the output sequence.
-#define MATCH_KEYPAD(vk, normal, shifted) \
-            case (vk): \
-            { \
-                seqstr = _get_keypad_sequence(control_key_state, (normal), \
-                    (shifted)); \
-            } \
-            break;
-
-        // The shift key and other modifier keys should affect the output
-        // sequence.
-#define MATCH_MODIFIER_KEYPAD(vk, normal, shifted) \
-            case (vk): \
-            { \
-                seqbuflen = _get_modifier_keypad_sequence(seqbuf, (vk), \
-                    control_key_state, (normal), (shifted)); \
-            } \
-            break;
-
-#define ESC "\x1b"
-#define CSI ESC "["
-#define SS3 ESC "O"
-
-        // Only support normal mode, not application mode.
-
-        // Enhanced keys:
-        // * 6-pack: insert, delete, home, end, page up, page down
-        // * cursor keys: up, down, right, left
-        // * keypad: divide, enter
-        // * Undocumented: VK_PAUSE (Ctrl-NumLock), VK_SNAPSHOT,
-        //   VK_CANCEL (Ctrl-Pause/Break), VK_NUMLOCK
-        if (_is_enhanced_key(control_key_state)) {
-            switch (vk) {
-                case VK_RETURN: // Enter key on keypad
-                    if (_is_ctrl_pressed(control_key_state)) {
-                        seqstr = "\n";
-                    } else {
-                        seqstr = "\r";
-                    }
-                    break;
-
-                MATCH_MODIFIER(VK_PRIOR, CSI "5~"); // Page Up
-                MATCH_MODIFIER(VK_NEXT,  CSI "6~"); // Page Down
-
-                // gnome-terminal currently sends SS3 "F" and SS3 "H", but that
-                // will be fixed soon to match xterm which sends CSI "F" and
-                // CSI "H". https://bugzilla.redhat.com/show_bug.cgi?id=1119764
-                MATCH(VK_END,  CSI "F");
-                MATCH(VK_HOME, CSI "H");
-
-                MATCH_MODIFIER(VK_LEFT,  CSI "D");
-                MATCH_MODIFIER(VK_UP,    CSI "A");
-                MATCH_MODIFIER(VK_RIGHT, CSI "C");
-                MATCH_MODIFIER(VK_DOWN,  CSI "B");
-
-                MATCH_MODIFIER(VK_INSERT, CSI "2~");
-                MATCH_MODIFIER(VK_DELETE, CSI "3~");
-
-                MATCH(VK_DIVIDE, "/");
-            }
-        } else {    // Non-enhanced keys:
-            switch (vk) {
-                case VK_BACK:   // backspace
-                    if (_is_alt_pressed(control_key_state)) {
-                        seqstr = ESC "\x7f";
-                    } else {
-                        seqstr = "\x7f";
-                    }
-                    break;
-
-                case VK_TAB:
-                    if (_is_shift_pressed(control_key_state)) {
-                        seqstr = CSI "Z";
-                    } else {
-                        seqstr = "\t";
-                    }
-                    break;
-
-                // Number 5 key in keypad when NumLock is off, or if NumLock is
-                // on and Shift is down.
-                MATCH_KEYPAD(VK_CLEAR, CSI "E", "5");
-
-                case VK_RETURN:     // Enter key on main keyboard
-                    if (_is_alt_pressed(control_key_state)) {
-                        seqstr = ESC "\n";
-                    } else if (_is_ctrl_pressed(control_key_state)) {
-                        seqstr = "\n";
-                    } else {
-                        seqstr = "\r";
-                    }
-                    break;
-
-                // VK_ESCAPE: Don't do any special handling. The OS uses many
-                // of the sequences with Escape and many of the remaining
-                // sequences don't produce bKeyDown messages, only !bKeyDown
-                // for whatever reason.
-
-                case VK_SPACE:
-                    if (_is_alt_pressed(control_key_state)) {
-                        seqstr = ESC " ";
-                    } else if (_is_ctrl_pressed(control_key_state)) {
-                        seqbuf[0] = '\0';   // NULL char
-                        seqbuflen = 1;
-                    } else {
-                        seqstr = " ";
-                    }
-                    break;
-
-                MATCH_MODIFIER_KEYPAD(VK_PRIOR, CSI "5~", '9'); // Page Up
-                MATCH_MODIFIER_KEYPAD(VK_NEXT,  CSI "6~", '3'); // Page Down
-
-                MATCH_KEYPAD(VK_END,  CSI "4~", "1");
-                MATCH_KEYPAD(VK_HOME, CSI "1~", "7");
-
-                MATCH_MODIFIER_KEYPAD(VK_LEFT,  CSI "D", '4');
-                MATCH_MODIFIER_KEYPAD(VK_UP,    CSI "A", '8');
-                MATCH_MODIFIER_KEYPAD(VK_RIGHT, CSI "C", '6');
-                MATCH_MODIFIER_KEYPAD(VK_DOWN,  CSI "B", '2');
-
-                MATCH_MODIFIER_KEYPAD(VK_INSERT, CSI "2~", '0');
-                MATCH_MODIFIER_KEYPAD(VK_DELETE, CSI "3~",
-                    _get_decimal_char());
-
-                case 0x30:          // 0
-                case 0x31:          // 1
-                case 0x39:          // 9
-                case VK_OEM_1:      // ;:
-                case VK_OEM_PLUS:   // =+
-                case VK_OEM_COMMA:  // ,<
-                case VK_OEM_PERIOD: // .>
-                case VK_OEM_7:      // '"
-                case VK_OEM_102:    // depends on keyboard, could be <> or \|
-                case VK_OEM_2:      // /?
-                case VK_OEM_3:      // `~
-                case VK_OEM_4:      // [{
-                case VK_OEM_5:      // \|
-                case VK_OEM_6:      // ]}
-                {
-                    seqbuflen = _get_control_character(seqbuf, key_event,
-                        control_key_state);
-
-                    if (_is_alt_pressed(control_key_state)) {
-                        seqbuflen = _escape_prefix(seqbuf, seqbuflen);
-                    }
-                }
-                break;
-
-                case 0x32:          // 2
-                case 0x33:          // 3
-                case 0x34:          // 4
-                case 0x35:          // 5
-                case 0x36:          // 6
-                case 0x37:          // 7
-                case 0x38:          // 8
-                case VK_OEM_MINUS:  // -_
-                {
-                    seqbuflen = _get_control_character(seqbuf, key_event,
-                        control_key_state);
-
-                    // If Alt is pressed and it isn't Ctrl-Alt-ShiftUp, then
-                    // prefix with escape.
-                    if (_is_alt_pressed(control_key_state) &&
-                        !(_is_ctrl_pressed(control_key_state) &&
-                        !_is_shift_pressed(control_key_state))) {
-                        seqbuflen = _escape_prefix(seqbuf, seqbuflen);
-                    }
-                }
-                break;
-
-                case 0x41:  // a
-                case 0x42:  // b
-                case 0x43:  // c
-                case 0x44:  // d
-                case 0x45:  // e
-                case 0x46:  // f
-                case 0x47:  // g
-                case 0x48:  // h
-                case 0x49:  // i
-                case 0x4a:  // j
-                case 0x4b:  // k
-                case 0x4c:  // l
-                case 0x4d:  // m
-                case 0x4e:  // n
-                case 0x4f:  // o
-                case 0x50:  // p
-                case 0x51:  // q
-                case 0x52:  // r
-                case 0x53:  // s
-                case 0x54:  // t
-                case 0x55:  // u
-                case 0x56:  // v
-                case 0x57:  // w
-                case 0x58:  // x
-                case 0x59:  // y
-                case 0x5a:  // z
-                {
-                    seqbuflen = _get_non_alt_char(seqbuf, key_event,
-                        control_key_state);
-
-                    // If Alt is pressed, then prefix with escape.
-                    if (_is_alt_pressed(control_key_state)) {
-                        seqbuflen = _escape_prefix(seqbuf, seqbuflen);
-                    }
-                }
-                break;
-
-                // These virtual key codes are generated by the keys on the
-                // keypad *when NumLock is on* and *Shift is up*.
-                MATCH(VK_NUMPAD0, "0");
-                MATCH(VK_NUMPAD1, "1");
-                MATCH(VK_NUMPAD2, "2");
-                MATCH(VK_NUMPAD3, "3");
-                MATCH(VK_NUMPAD4, "4");
-                MATCH(VK_NUMPAD5, "5");
-                MATCH(VK_NUMPAD6, "6");
-                MATCH(VK_NUMPAD7, "7");
-                MATCH(VK_NUMPAD8, "8");
-                MATCH(VK_NUMPAD9, "9");
-
-                MATCH(VK_MULTIPLY, "*");
-                MATCH(VK_ADD,      "+");
-                MATCH(VK_SUBTRACT, "-");
-                // VK_DECIMAL is generated by the . key on the keypad *when
-                // NumLock is on* and *Shift is up* and the sequence is not
-                // Ctrl-Alt-NoShift-. (which causes Ctrl-Alt-Del and the
-                // Windows Security screen to come up).
-                case VK_DECIMAL:
-                    // U.S. English uses '.', Germany German uses ','.
-                    seqbuflen = _get_non_control_char(seqbuf, key_event,
-                        control_key_state);
-                    break;
-
-                MATCH_MODIFIER(VK_F1,  SS3 "P");
-                MATCH_MODIFIER(VK_F2,  SS3 "Q");
-                MATCH_MODIFIER(VK_F3,  SS3 "R");
-                MATCH_MODIFIER(VK_F4,  SS3 "S");
-                MATCH_MODIFIER(VK_F5,  CSI "15~");
-                MATCH_MODIFIER(VK_F6,  CSI "17~");
-                MATCH_MODIFIER(VK_F7,  CSI "18~");
-                MATCH_MODIFIER(VK_F8,  CSI "19~");
-                MATCH_MODIFIER(VK_F9,  CSI "20~");
-                MATCH_MODIFIER(VK_F10, CSI "21~");
-                MATCH_MODIFIER(VK_F11, CSI "23~");
-                MATCH_MODIFIER(VK_F12, CSI "24~");
-
-                MATCH_MODIFIER(VK_F13, CSI "25~");
-                MATCH_MODIFIER(VK_F14, CSI "26~");
-                MATCH_MODIFIER(VK_F15, CSI "28~");
-                MATCH_MODIFIER(VK_F16, CSI "29~");
-                MATCH_MODIFIER(VK_F17, CSI "31~");
-                MATCH_MODIFIER(VK_F18, CSI "32~");
-                MATCH_MODIFIER(VK_F19, CSI "33~");
-                MATCH_MODIFIER(VK_F20, CSI "34~");
-
-                // MATCH_MODIFIER(VK_F21, ???);
-                // MATCH_MODIFIER(VK_F22, ???);
-                // MATCH_MODIFIER(VK_F23, ???);
-                // MATCH_MODIFIER(VK_F24, ???);
-            }
-        }
-
-#undef MATCH
-#undef MATCH_MODIFIER
-#undef MATCH_KEYPAD
-#undef MATCH_MODIFIER_KEYPAD
-#undef ESC
-#undef CSI
-#undef SS3
-
-        const char* out;
-        size_t outlen;
-
-        // Check for output in any of:
-        // * seqstr is set (and strlen can be used to determine the length).
-        // * seqbuf and seqbuflen are set
-        // Fallback to ch from Windows.
-        if (seqstr != nullptr) {
-            out = seqstr;
-            outlen = strlen(seqstr);
-        } else if (seqbuflen > 0) {
-            out = seqbuf;
-            outlen = seqbuflen;
-        } else if (ch != '\0') {
-            // Use whatever Windows told us it is.
-            seqbuf[0] = ch;
-            seqbuflen = 1;
-            out = seqbuf;
-            outlen = seqbuflen;
-        } else {
-            // No special handling for the virtual key code and Windows isn't
-            // telling us a character code, then we don't know how to translate
-            // the key press.
-            //
-            // Consume the input and 'continue' to cause us to get a new key
-            // event.
-            D("_console_read: unknown virtual key code: %d, enhanced: %s",
-                vk, _is_enhanced_key(control_key_state) ? "true" : "false");
-            continue;
-        }
-
-        // put output wRepeatCount times into g_console_input_buffer
-        while (key_event->wRepeatCount-- > 0) {
-            g_console_input_buffer.insert(g_console_input_buffer.end(), out, out + outlen);
-        }
-
-        // Loop around and try to flush g_console_input_buffer
-    }
-}
-
-static DWORD _old_console_mode; // previous GetConsoleMode() result
-static HANDLE _console_handle;  // when set, console mode should be restored
-
-void stdin_raw_init() {
-    const HANDLE in = _get_console_handle(STDIN_FILENO, &_old_console_mode);
-    if (in == nullptr) {
-        return;
-    }
-
-    // Disable ENABLE_PROCESSED_INPUT so that Ctrl-C is read instead of
-    // calling the process Ctrl-C routine (configured by
-    // SetConsoleCtrlHandler()).
-    // Disable ENABLE_LINE_INPUT so that input is immediately sent.
-    // Disable ENABLE_ECHO_INPUT to disable local echo. Disabling this
-    // flag also seems necessary to have proper line-ending processing.
-    DWORD new_console_mode = _old_console_mode & ~(ENABLE_PROCESSED_INPUT |
-                                                   ENABLE_LINE_INPUT |
-                                                   ENABLE_ECHO_INPUT);
-    // Enable ENABLE_WINDOW_INPUT to get window resizes.
-    new_console_mode |= ENABLE_WINDOW_INPUT;
-
-    if (!SetConsoleMode(in, new_console_mode)) {
-        // This really should not fail.
-        D("stdin_raw_init: SetConsoleMode() failed: %s",
-          android::base::SystemErrorCodeToString(GetLastError()).c_str());
-    }
-
-    // Once this is set, it means that stdin has been configured for
-    // reading from and that the old console mode should be restored later.
-    _console_handle = in;
-
-    // Note that we don't need to configure C Runtime line-ending
-    // translation because _console_read() does not call the C Runtime to
-    // read from the console.
-}
-
-void stdin_raw_restore() {
-    if (_console_handle != nullptr) {
-        const HANDLE in = _console_handle;
-        _console_handle = nullptr;  // clear state
-
-        if (!SetConsoleMode(in, _old_console_mode)) {
-            // This really should not fail.
-            D("stdin_raw_restore: SetConsoleMode() failed: %s",
-              android::base::SystemErrorCodeToString(GetLastError()).c_str());
-        }
-    }
-}
-
-// Called by 'adb shell' and 'adb exec-in' (via unix_read()) to read from stdin.
-int unix_read_interruptible(borrowed_fd fd, void* buf, size_t len) {
-    if ((fd == STDIN_FILENO) && (_console_handle != nullptr)) {
-        // If it is a request to read from stdin, and stdin_raw_init() has been
-        // called, and it successfully configured the console, then read from
-        // the console using Win32 console APIs and partially emulate a unix
-        // terminal.
-        return _console_read(_console_handle, buf, len);
-    } else {
-        // On older versions of Windows (definitely 7, definitely not 10),
-        // ReadConsole() with a size >= 31367 fails, so if |fd| is a console
-        // we need to limit the read size.
-        if (len > 4096 && unix_isatty(fd)) {
-            len = 4096;
-        }
-        // Just call into C Runtime which can read from pipes/files and which
-        // can do LF/CR translation (which is overridable with _setmode()).
-        // Undefine the macro that is set in sysdeps.h which bans calls to
-        // plain read() in favor of unix_read() or adb_read().
-#pragma push_macro("read")
-#undef read
-        return read(fd.get(), buf, len);
-#pragma pop_macro("read")
-    }
-}
-
-/**************************************************************************/
-/**************************************************************************/
-/*****                                                                *****/
-/*****      Unicode support                                           *****/
-/*****                                                                *****/
-/**************************************************************************/
-/**************************************************************************/
-
-// This implements support for using files with Unicode filenames and for
-// outputting Unicode text to a Win32 console window. This is inspired from
-// http://utf8everywhere.org/.
-//
-// Background
-// ----------
-//
-// On POSIX systems, to deal with files with Unicode filenames, just pass UTF-8
-// filenames to APIs such as open(). This works because filenames are largely
-// opaque 'cookies' (perhaps excluding path separators).
-//
-// On Windows, the native file APIs such as CreateFileW() take 2-byte wchar_t
-// UTF-16 strings. There is an API, CreateFileA() that takes 1-byte char
-// strings, but the strings are in the ANSI codepage and not UTF-8. (The
-// CreateFile() API is really just a macro that adds the W/A based on whether
-// the UNICODE preprocessor symbol is defined).
-//
-// Options
-// -------
-//
-// Thus, to write a portable program, there are a few options:
-//
-// 1. Write the program with wchar_t filenames (wchar_t path[256];).
-//    For Windows, just call CreateFileW(). For POSIX, write a wrapper openW()
-//    that takes a wchar_t string, converts it to UTF-8 and then calls the real
-//    open() API.
-//
-// 2. Write the program with a TCHAR typedef that is 2 bytes on Windows and
-//    1 byte on POSIX. Make T-* wrappers for various OS APIs and call those,
-//    potentially touching a lot of code.
-//
-// 3. Write the program with a 1-byte char filenames (char path[256];) that are
-//    UTF-8. For POSIX, just call open(). For Windows, write a wrapper that
-//    takes a UTF-8 string, converts it to UTF-16 and then calls the real OS
-//    or C Runtime API.
-//
-// The Choice
-// ----------
-//
-// The code below chooses option 3, the UTF-8 everywhere strategy. It uses
-// android::base::WideToUTF8() which converts UTF-16 to UTF-8. This is used by the
-// NarrowArgs helper class that is used to convert wmain() args into UTF-8
-// args that are passed to main() at the beginning of program startup. We also use
-// android::base::UTF8ToWide() which converts from UTF-8 to UTF-16. This is used to
-// implement wrappers below that call UTF-16 OS and C Runtime APIs.
-//
-// Unicode console output
-// ----------------------
-//
-// The way to output Unicode to a Win32 console window is to call
-// WriteConsoleW() with UTF-16 text. (The user must also choose a proper font
-// such as Lucida Console or Consolas, and in the case of East Asian languages
-// (such as Chinese, Japanese, Korean), the user must go to the Control Panel
-// and change the "system locale" to Chinese, etc., which allows a Chinese, etc.
-// font to be used in console windows.)
-//
-// The problem is getting the C Runtime to make fprintf and related APIs call
-// WriteConsoleW() under the covers. The C Runtime API, _setmode() sounds
-// promising, but the various modes have issues:
-//
-// 1. _setmode(_O_TEXT) (the default) does not use WriteConsoleW() so UTF-8 and
-//    UTF-16 do not display properly.
-// 2. _setmode(_O_BINARY) does not use WriteConsoleW() and the text comes out
-//    totally wrong.
-// 3. _setmode(_O_U8TEXT) seems to cause the C Runtime _invalid_parameter
-//    handler to be called (upon a later I/O call), aborting the process.
-// 4. _setmode(_O_U16TEXT) and _setmode(_O_WTEXT) cause non-wide printf/fprintf
-//    to output nothing.
-//
-// So the only solution is to write our own adb_fprintf() that converts UTF-8
-// to UTF-16 and then calls WriteConsoleW().
-
-
-// Constructor for helper class to convert wmain() UTF-16 args to UTF-8 to
-// be passed to main().
-NarrowArgs::NarrowArgs(const int argc, wchar_t** const argv) {
-    narrow_args = new char*[argc + 1];
-
-    for (int i = 0; i < argc; ++i) {
-        std::string arg_narrow;
-        if (!android::base::WideToUTF8(argv[i], &arg_narrow)) {
-            PLOG(FATAL) << "cannot convert argument from UTF-16 to UTF-8";
-        }
-        narrow_args[i] = strdup(arg_narrow.c_str());
-    }
-    narrow_args[argc] = nullptr;   // terminate
-}
-
-NarrowArgs::~NarrowArgs() {
-    if (narrow_args != nullptr) {
-        for (char** argp = narrow_args; *argp != nullptr; ++argp) {
-            free(*argp);
-        }
-        delete[] narrow_args;
-        narrow_args = nullptr;
-    }
-}
-
-int unix_open(std::string_view path, int options, ...) {
-    std::wstring path_wide;
-    if (!android::base::UTF8ToWide(path.data(), path.size(), &path_wide)) {
-        return -1;
-    }
-    if ((options & O_CREAT) == 0) {
-        return _wopen(path_wide.c_str(), options);
-    } else {
-        int mode;
-        va_list  args;
-        va_start(args, options);
-        mode = va_arg(args, int);
-        va_end(args);
-        return _wopen(path_wide.c_str(), options, mode);
-    }
-}
-
-// Version of opendir() that takes a UTF-8 path.
-DIR* adb_opendir(const char* path) {
-    std::wstring path_wide;
-    if (!android::base::UTF8ToWide(path, &path_wide)) {
-        return nullptr;
-    }
-
-    // Just cast _WDIR* to DIR*. This doesn't work if the caller reads any of
-    // the fields, but right now all the callers treat the structure as
-    // opaque.
-    return reinterpret_cast<DIR*>(_wopendir(path_wide.c_str()));
-}
-
-// Version of readdir() that returns UTF-8 paths.
-struct dirent* adb_readdir(DIR* dir) {
-    _WDIR* const wdir = reinterpret_cast<_WDIR*>(dir);
-    struct _wdirent* const went = _wreaddir(wdir);
-    if (went == nullptr) {
-        return nullptr;
-    }
-
-    // Convert from UTF-16 to UTF-8.
-    std::string name_utf8;
-    if (!android::base::WideToUTF8(went->d_name, &name_utf8)) {
-        return nullptr;
-    }
-
-    // Cast the _wdirent* to dirent* and overwrite the d_name field (which has
-    // space for UTF-16 wchar_t's) with UTF-8 char's.
-    struct dirent* ent = reinterpret_cast<struct dirent*>(went);
-
-    if (name_utf8.length() + 1 > sizeof(went->d_name)) {
-        // Name too big to fit in existing buffer.
-        errno = ENOMEM;
-        return nullptr;
-    }
-
-    // Note that sizeof(_wdirent::d_name) is bigger than sizeof(dirent::d_name)
-    // because _wdirent contains wchar_t instead of char. So even if name_utf8
-    // can fit in _wdirent::d_name, the resulting dirent::d_name field may be
-    // bigger than the caller expects because they expect a dirent structure
-    // which has a smaller d_name field. Ignore this since the caller should be
-    // resilient.
-
-    // Rewrite the UTF-16 d_name field to UTF-8.
-    strcpy(ent->d_name, name_utf8.c_str());
-
-    return ent;
-}
-
-// Version of closedir() to go with our version of adb_opendir().
-int adb_closedir(DIR* dir) {
-    return _wclosedir(reinterpret_cast<_WDIR*>(dir));
-}
-
-// Version of unlink() that takes a UTF-8 path.
-int adb_unlink(const char* path) {
-    std::wstring wpath;
-    if (!android::base::UTF8ToWide(path, &wpath)) {
-        return -1;
-    }
-
-    int  rc = _wunlink(wpath.c_str());
-
-    if (rc == -1 && errno == EACCES) {
-        /* unlink returns EACCES when the file is read-only, so we first */
-        /* try to make it writable, then unlink again...                 */
-        rc = _wchmod(wpath.c_str(), _S_IREAD | _S_IWRITE);
-        if (rc == 0)
-            rc = _wunlink(wpath.c_str());
-    }
-    return rc;
-}
-
-// Version of mkdir() that takes a UTF-8 path.
-int adb_mkdir(const std::string& path, int mode) {
-    std::wstring path_wide;
-    if (!android::base::UTF8ToWide(path, &path_wide)) {
-        return -1;
-    }
-
-    return _wmkdir(path_wide.c_str());
-}
-
-int adb_rename(const char* oldpath, const char* newpath) {
-    std::wstring oldpath_wide, newpath_wide;
-    if (!android::base::UTF8ToWide(oldpath, &oldpath_wide)) {
-        return -1;
-    }
-    if (!android::base::UTF8ToWide(newpath, &newpath_wide)) {
-        return -1;
-    }
-
-    // MSDN just says the return value is non-zero on failure, make sure it
-    // returns -1 on failure so that it behaves the same as other systems.
-    return _wrename(oldpath_wide.c_str(), newpath_wide.c_str()) ? -1 : 0;
-}
-
-// Version of utime() that takes a UTF-8 path.
-int adb_utime(const char* path, struct utimbuf* u) {
-    std::wstring path_wide;
-    if (!android::base::UTF8ToWide(path, &path_wide)) {
-        return -1;
-    }
-
-    static_assert(sizeof(struct utimbuf) == sizeof(struct _utimbuf),
-        "utimbuf and _utimbuf should be the same size because they both "
-        "contain the same types, namely time_t");
-    return _wutime(path_wide.c_str(), reinterpret_cast<struct _utimbuf*>(u));
-}
-
-// Version of chmod() that takes a UTF-8 path.
-int adb_chmod(const char* path, int mode) {
-    std::wstring path_wide;
-    if (!android::base::UTF8ToWide(path, &path_wide)) {
-        return -1;
-    }
-
-    return _wchmod(path_wide.c_str(), mode);
-}
-
-// From libutils/Unicode.cpp, get the length of a UTF-8 sequence given the lead byte.
-static inline size_t utf8_codepoint_len(uint8_t ch) {
-    return ((0xe5000000 >> ((ch >> 3) & 0x1e)) & 3) + 1;
-}
-
-namespace internal {
-
-// Given a sequence of UTF-8 bytes (denoted by the range [first, last)), return the number of bytes
-// (from the beginning) that are complete UTF-8 sequences and append the remaining bytes to
-// remaining_bytes.
-size_t ParseCompleteUTF8(const char* const first, const char* const last,
-                         std::vector<char>* const remaining_bytes) {
-    // Walk backwards from the end of the sequence looking for the beginning of a UTF-8 sequence.
-    // Current_after points one byte past the current byte to be examined.
-    for (const char* current_after = last; current_after != first; --current_after) {
-        const char* const current = current_after - 1;
-        const char ch = *current;
-        const char kHighBit = 0x80u;
-        const char kTwoHighestBits = 0xC0u;
-        if ((ch & kHighBit) == 0) { // high bit not set
-            // The buffer ends with a one-byte UTF-8 sequence, possibly followed by invalid trailing
-            // bytes with no leading byte, so return the entire buffer.
-            break;
-        } else if ((ch & kTwoHighestBits) == kTwoHighestBits) { // top two highest bits set
-            // Lead byte in UTF-8 sequence, so check if we have all the bytes in the sequence.
-            const size_t bytes_available = last - current;
-            if (bytes_available < utf8_codepoint_len(ch)) {
-                // We don't have all the bytes in the UTF-8 sequence, so return all the bytes
-                // preceding the current incomplete UTF-8 sequence and append the remaining bytes
-                // to remaining_bytes.
-                remaining_bytes->insert(remaining_bytes->end(), current, last);
-                return current - first;
-            } else {
-                // The buffer ends with a complete UTF-8 sequence, possibly followed by invalid
-                // trailing bytes with no lead byte, so return the entire buffer.
-                break;
-            }
-        } else {
-            // Trailing byte, so keep going backwards looking for the lead byte.
-        }
-    }
-
-    // Return the size of the entire buffer. It is possible that we walked backward past invalid
-    // trailing bytes with no lead byte, in which case we want to return all those invalid bytes
-    // so that they can be processed.
-    return last - first;
-}
-
-}
-
-// Bytes that have not yet been output to the console because they are incomplete UTF-8 sequences.
-// Note that we use only one buffer even though stderr and stdout are logically separate streams.
-// This matches the behavior of Linux.
-
-// Internal helper function to write UTF-8 bytes to a console. Returns -1 on error.
-static int _console_write_utf8(const char* const buf, const size_t buf_size, FILE* stream,
-                               HANDLE console) {
-    static std::mutex& console_output_buffer_lock = *new std::mutex();
-    static auto& console_output_buffer = *new std::vector<char>();
-
-    const int saved_errno = errno;
-    std::vector<char> combined_buffer;
-
-    // Complete UTF-8 sequences that should be immediately written to the console.
-    const char* utf8;
-    size_t utf8_size;
-
-    {
-        std::lock_guard<std::mutex> lock(console_output_buffer_lock);
-        if (console_output_buffer.empty()) {
-            // If console_output_buffer doesn't have a buffered up incomplete UTF-8 sequence (the
-            // common case with plain ASCII), parse buf directly.
-            utf8 = buf;
-            utf8_size = internal::ParseCompleteUTF8(buf, buf + buf_size, &console_output_buffer);
-        } else {
-            // If console_output_buffer has a buffered up incomplete UTF-8 sequence, move it to
-            // combined_buffer (and effectively clear console_output_buffer) and append buf to
-            // combined_buffer, then parse it all together.
-            combined_buffer.swap(console_output_buffer);
-            combined_buffer.insert(combined_buffer.end(), buf, buf + buf_size);
-
-            utf8 = combined_buffer.data();
-            utf8_size = internal::ParseCompleteUTF8(utf8, utf8 + combined_buffer.size(),
-                                                    &console_output_buffer);
-        }
-    }
-
-    std::wstring utf16;
-
-    // Try to convert from data that might be UTF-8 to UTF-16, ignoring errors (just like Linux
-    // which does not return an error on bad UTF-8). Data might not be UTF-8 if the user cat's
-    // random data, runs dmesg (which might have non-UTF-8), etc.
-    // This could throw std::bad_alloc.
-    (void)android::base::UTF8ToWide(utf8, utf8_size, &utf16);
-
-    // Note that this does not do \n => \r\n translation because that
-    // doesn't seem necessary for the Windows console. For the Windows
-    // console \r moves to the beginning of the line and \n moves to a new
-    // line.
-
-    // Flush any stream buffering so that our output is afterwards which
-    // makes sense because our call is afterwards.
-    (void)fflush(stream);
-
-    // Write UTF-16 to the console.
-    DWORD written = 0;
-    if (!WriteConsoleW(console, utf16.c_str(), utf16.length(), &written, nullptr)) {
-        errno = EIO;
-        return -1;
-    }
-
-    // Return the size of the original buffer passed in, signifying that we consumed it all, even
-    // if nothing was displayed, in the case of being passed an incomplete UTF-8 sequence. This
-    // matches the Linux behavior.
-    errno = saved_errno;
-    return buf_size;
-}
-
-// Function prototype because attributes cannot be placed on func definitions.
-static int _console_vfprintf(const HANDLE console, FILE* stream, const char* format, va_list ap)
-        __attribute__((__format__(__printf__, 3, 0)));
-
-// Internal function to format a UTF-8 string and write it to a Win32 console.
-// Returns -1 on error.
-static int _console_vfprintf(const HANDLE console, FILE* stream,
-                             const char *format, va_list ap) {
-    const int saved_errno = errno;
-    std::string output_utf8;
-
-    // Format the string.
-    // This could throw std::bad_alloc.
-    android::base::StringAppendV(&output_utf8, format, ap);
-
-    const int result = _console_write_utf8(output_utf8.c_str(), output_utf8.length(), stream,
-                                           console);
-    if (result != -1) {
-        errno = saved_errno;
-    } else {
-        // If -1 was returned, errno has been set.
-    }
-    return result;
-}
-
-// Version of vfprintf() that takes UTF-8 and can write Unicode to a
-// Windows console.
-int adb_vfprintf(FILE *stream, const char *format, va_list ap) {
-    const HANDLE console = _get_console_handle(stream);
-
-    // If there is an associated Win32 console, write to it specially,
-    // otherwise defer to the regular C Runtime, passing it UTF-8.
-    if (console != nullptr) {
-        return _console_vfprintf(console, stream, format, ap);
-    } else {
-        // If vfprintf is a macro, undefine it, so we can call the real
-        // C Runtime API.
-#pragma push_macro("vfprintf")
-#undef vfprintf
-        return vfprintf(stream, format, ap);
-#pragma pop_macro("vfprintf")
-    }
-}
-
-// Version of vprintf() that takes UTF-8 and can write Unicode to a Windows console.
-int adb_vprintf(const char *format, va_list ap) {
-    return adb_vfprintf(stdout, format, ap);
-}
-
-// Version of fprintf() that takes UTF-8 and can write Unicode to a
-// Windows console.
-int adb_fprintf(FILE *stream, const char *format, ...) {
-    va_list ap;
-    va_start(ap, format);
-    const int result = adb_vfprintf(stream, format, ap);
-    va_end(ap);
-
-    return result;
-}
-
-// Version of printf() that takes UTF-8 and can write Unicode to a
-// Windows console.
-int adb_printf(const char *format, ...) {
-    va_list ap;
-    va_start(ap, format);
-    const int result = adb_vfprintf(stdout, format, ap);
-    va_end(ap);
-
-    return result;
-}
-
-// Version of fputs() that takes UTF-8 and can write Unicode to a
-// Windows console.
-int adb_fputs(const char* buf, FILE* stream) {
-    // adb_fprintf returns -1 on error, which is conveniently the same as EOF
-    // which fputs (and hence adb_fputs) should return on error.
-    static_assert(EOF == -1, "EOF is not -1, so this code needs to be fixed");
-    return adb_fprintf(stream, "%s", buf);
-}
-
-// Version of fputc() that takes UTF-8 and can write Unicode to a
-// Windows console.
-int adb_fputc(int ch, FILE* stream) {
-    const int result = adb_fprintf(stream, "%c", ch);
-    if (result == -1) {
-        return EOF;
-    }
-    // For success, fputc returns the char, cast to unsigned char, then to int.
-    return static_cast<unsigned char>(ch);
-}
-
-// Version of putchar() that takes UTF-8 and can write Unicode to a Windows console.
-int adb_putchar(int ch) {
-    return adb_fputc(ch, stdout);
-}
-
-// Version of puts() that takes UTF-8 and can write Unicode to a Windows console.
-int adb_puts(const char* buf) {
-    // adb_printf returns -1 on error, which is conveniently the same as EOF
-    // which puts (and hence adb_puts) should return on error.
-    static_assert(EOF == -1, "EOF is not -1, so this code needs to be fixed");
-    return adb_printf("%s\n", buf);
-}
-
-// Internal function to write UTF-8 to a Win32 console. Returns the number of
-// items (of length size) written. On error, returns a short item count or 0.
-static size_t _console_fwrite(const void* ptr, size_t size, size_t nmemb,
-                              FILE* stream, HANDLE console) {
-    const int result = _console_write_utf8(reinterpret_cast<const char*>(ptr), size * nmemb, stream,
-                                           console);
-    if (result == -1) {
-        return 0;
-    }
-    return result / size;
-}
-
-// Version of fwrite() that takes UTF-8 and can write Unicode to a
-// Windows console.
-size_t adb_fwrite(const void* ptr, size_t size, size_t nmemb, FILE* stream) {
-    const HANDLE console = _get_console_handle(stream);
-
-    // If there is an associated Win32 console, write to it specially,
-    // otherwise defer to the regular C Runtime, passing it UTF-8.
-    if (console != nullptr) {
-        return _console_fwrite(ptr, size, nmemb, stream, console);
-    } else {
-        // If fwrite is a macro, undefine it, so we can call the real
-        // C Runtime API.
-#pragma push_macro("fwrite")
-#undef fwrite
-        return fwrite(ptr, size, nmemb, stream);
-#pragma pop_macro("fwrite")
-    }
-}
-
-// Version of fopen() that takes a UTF-8 filename and can access a file with
-// a Unicode filename.
-FILE* adb_fopen(const char* path, const char* mode) {
-    std::wstring path_wide;
-    if (!android::base::UTF8ToWide(path, &path_wide)) {
-        return nullptr;
-    }
-
-    std::wstring mode_wide;
-    if (!android::base::UTF8ToWide(mode, &mode_wide)) {
-        return nullptr;
-    }
-
-    return _wfopen(path_wide.c_str(), mode_wide.c_str());
-}
-
-// Return a lowercase version of the argument. Uses C Runtime tolower() on
-// each byte which is not UTF-8 aware, and theoretically uses the current C
-// Runtime locale (which in practice is not changed, so this becomes a ASCII
-// conversion).
-static std::string ToLower(const std::string& anycase) {
-    // copy string
-    std::string str(anycase);
-    // transform the copy
-    std::transform(str.begin(), str.end(), str.begin(), tolower);
-    return str;
-}
-
-extern "C" int main(int argc, char** argv);
-
-// Link with -municode to cause this wmain() to be used as the program
-// entrypoint. It will convert the args from UTF-16 to UTF-8 and call the
-// regular main() with UTF-8 args.
-extern "C" int wmain(int argc, wchar_t **argv) {
-    // Convert args from UTF-16 to UTF-8 and pass that to main().
-    NarrowArgs narrow_args(argc, argv);
-
-    // Avoid destructing NarrowArgs: argv might have been mutated to point to string literals.
-    _exit(main(argc, narrow_args.data()));
-}
-
-// Shadow UTF-8 environment variable name/value pairs that are created from
-// _wenviron by _init_env(). Note that this is not currently updated if putenv, setenv, unsetenv are
-// called. Note that no thread synchronization is done, but we're called early enough in
-// single-threaded startup that things work ok.
-static auto& g_environ_utf8 = *new std::unordered_map<std::string, char*>();
-
-// Setup shadow UTF-8 environment variables.
-static void _init_env() {
-    // If some name/value pairs exist, then we've already done the setup below.
-    if (g_environ_utf8.size() != 0) {
-        return;
-    }
-
-    if (_wenviron == nullptr) {
-        // If _wenviron is null, then -municode probably wasn't used. That
-        // linker flag will cause the entry point to setup _wenviron. It will
-        // also require an implementation of wmain() (which we provide above).
-        LOG(FATAL) << "_wenviron is not set, did you link with -municode?";
-    }
-
-    // Read name/value pairs from UTF-16 _wenviron and write new name/value
-    // pairs to UTF-8 g_environ_utf8. Note that it probably does not make sense
-    // to use the D() macro here because that tracing only works if the
-    // ADB_TRACE environment variable is setup, but that env var can't be read
-    // until this code completes.
-    for (wchar_t** env = _wenviron; *env != nullptr; ++env) {
-        wchar_t* const equal = wcschr(*env, L'=');
-        if (equal == nullptr) {
-            // Malformed environment variable with no equal sign. Shouldn't
-            // really happen, but we should be resilient to this.
-            continue;
-        }
-
-        // If we encounter an error converting UTF-16, don't error-out on account of a single env
-        // var because the program might never even read this particular variable.
-        std::string name_utf8;
-        if (!android::base::WideToUTF8(*env, equal - *env, &name_utf8)) {
-            continue;
-        }
-
-        // Store lowercase name so that we can do case-insensitive searches.
-        name_utf8 = ToLower(name_utf8);
-
-        std::string value_utf8;
-        if (!android::base::WideToUTF8(equal + 1, &value_utf8)) {
-            continue;
-        }
-
-        char* const value_dup = strdup(value_utf8.c_str());
-
-        // Don't overwrite a previus env var with the same name. In reality,
-        // the system probably won't let two env vars with the same name exist
-        // in _wenviron.
-        g_environ_utf8.insert({name_utf8, value_dup});
-    }
-}
-
-// Version of getenv() that takes a UTF-8 environment variable name and
-// retrieves a UTF-8 value. Case-insensitive to match getenv() on Windows.
-char* adb_getenv(const char* name) {
-    // Case-insensitive search by searching for lowercase name in a map of
-    // lowercase names.
-    const auto it = g_environ_utf8.find(ToLower(std::string(name)));
-    if (it == g_environ_utf8.end()) {
-        return nullptr;
-    }
-
-    return it->second;
-}
-
-// Version of getcwd() that returns the current working directory in UTF-8.
-char* adb_getcwd(char* buf, int size) {
-    wchar_t* wbuf = _wgetcwd(nullptr, 0);
-    if (wbuf == nullptr) {
-        return nullptr;
-    }
-
-    std::string buf_utf8;
-    const bool narrow_result = android::base::WideToUTF8(wbuf, &buf_utf8);
-    free(wbuf);
-    wbuf = nullptr;
-
-    if (!narrow_result) {
-        return nullptr;
-    }
-
-    // If size was specified, make sure all the chars will fit.
-    if (size != 0) {
-        if (size < static_cast<int>(buf_utf8.length() + 1)) {
-            errno = ERANGE;
-            return nullptr;
-        }
-    }
-
-    // If buf was not specified, allocate storage.
-    if (buf == nullptr) {
-        if (size == 0) {
-            size = buf_utf8.length() + 1;
-        }
-        buf = reinterpret_cast<char*>(malloc(size));
-        if (buf == nullptr) {
-            return nullptr;
-        }
-    }
-
-    // Destination buffer was allocated with enough space, or we've already
-    // checked an existing buffer size for enough space.
-    strcpy(buf, buf_utf8.c_str());
-
-    return buf;
-}
-
-void enable_inherit(borrowed_fd fd) {
-    auto osh = adb_get_os_handle(fd);
-    const auto h = reinterpret_cast<HANDLE>(osh);
-    ::SetHandleInformation(h, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT);
-}
-
-void disable_inherit(borrowed_fd fd) {
-    auto osh = adb_get_os_handle(fd);
-    const auto h = reinterpret_cast<HANDLE>(osh);
-    ::SetHandleInformation(h, HANDLE_FLAG_INHERIT, 0);
-}
-
-Process adb_launch_process(std::string_view executable, std::vector<std::string> args,
-                           std::initializer_list<int> fds_to_inherit) {
-    std::wstring wexe;
-    if (!android::base::UTF8ToWide(executable.data(), executable.size(), &wexe)) {
-        return Process();
-    }
-
-    std::wstring wargs = L"\"" + wexe + L"\"";
-    std::wstring warg;
-    for (auto arg : args) {
-        warg.clear();
-        if (!android::base::UTF8ToWide(arg.data(), arg.size(), &warg)) {
-            return Process();
-        }
-        wargs += L" \"";
-        wargs += warg;
-        wargs += L'\"';
-    }
-
-    STARTUPINFOW sinfo = {sizeof(sinfo)};
-    PROCESS_INFORMATION pinfo = {};
-
-    // TODO: use the Vista+ API to pass the list of inherited handles explicitly;
-    // see http://blogs.msdn.com/b/oldnewthing/archive/2011/12/16/10248328.aspx
-    for (auto fd : fds_to_inherit) {
-        enable_inherit(fd);
-    }
-    const auto created = CreateProcessW(wexe.c_str(), wargs.data(),
-                                        nullptr,                    // process attributes
-                                        nullptr,                    // thread attributes
-                                        fds_to_inherit.size() > 0,  // inherit any handles?
-                                        0,                          // flags
-                                        nullptr,                    // environment
-                                        nullptr,                    // current directory
-                                        &sinfo,                     // startup info
-                                        &pinfo);
-    for (auto fd : fds_to_inherit) {
-        disable_inherit(fd);
-    }
-
-    if (!created) {
-        return Process();
-    }
-
-    ::CloseHandle(pinfo.hThread);
-    return Process(pinfo.hProcess);
-}
-
-// The SetThreadDescription API was brought in version 1607 of Windows 10.
-typedef HRESULT(WINAPI* SetThreadDescription)(HANDLE hThread, PCWSTR lpThreadDescription);
-
-// Based on PlatformThread::SetName() from
-// https://cs.chromium.org/chromium/src/base/threading/platform_thread_win.cc
-int adb_thread_setname(const std::string& name) {
-    // The SetThreadDescription API works even if no debugger is attached.
-    auto set_thread_description_func = reinterpret_cast<SetThreadDescription>(
-            ::GetProcAddress(::GetModuleHandleW(L"Kernel32.dll"), "SetThreadDescription"));
-    if (set_thread_description_func) {
-        std::wstring name_wide;
-        if (!android::base::UTF8ToWide(name.c_str(), &name_wide)) {
-            return errno;
-        }
-        set_thread_description_func(::GetCurrentThread(), name_wide.c_str());
-    }
-
-    // Don't use the thread naming SEH exception because we're compiled with -fno-exceptions.
-    // https://docs.microsoft.com/en-us/visualstudio/debugger/how-to-set-a-thread-name-in-native-code?view=vs-2017
-
-    return 0;
-}
-
-#if !defined(ENABLE_VIRTUAL_TERMINAL_PROCESSING)
-#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
-#endif
-
-#if !defined(DISABLE_NEWLINE_AUTO_RETURN)
-#define DISABLE_NEWLINE_AUTO_RETURN 0x0008
-#endif
-
-static void _init_console() {
-    DWORD old_out_console_mode;
-
-    const HANDLE out = _get_console_handle(STDOUT_FILENO, &old_out_console_mode);
-    if (out == nullptr) {
-        return;
-    }
-
-    // Try to use ENABLE_VIRTUAL_TERMINAL_PROCESSING on the output console to process virtual
-    // terminal sequences on newer versions of Windows 10 and later.
-    // https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences
-    // On older OSes that don't support the flag, SetConsoleMode() will return an error.
-    // ENABLE_VIRTUAL_TERMINAL_PROCESSING also solves a problem where the last column of the
-    // console cannot be overwritten.
-    //
-    // Note that we don't use DISABLE_NEWLINE_AUTO_RETURN because it doesn't seem to be necessary.
-    // If we use DISABLE_NEWLINE_AUTO_RETURN, _console_write_utf8() would need to be modified to
-    // translate \n to \r\n.
-    if (!SetConsoleMode(out, old_out_console_mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING)) {
-        return;
-    }
-
-    // If SetConsoleMode() succeeded, the console supports virtual terminal processing, so we
-    // should set the TERM env var to match so that it will be propagated to adbd on devices.
-    //
-    // Below's direct manipulation of env vars and not g_environ_utf8 assumes that _init_env() has
-    // not yet been called. If this fails, _init_env() should be called after _init_console().
-    if (g_environ_utf8.size() > 0) {
-        LOG(FATAL) << "environment variables have already been converted to UTF-8";
-    }
-
-#pragma push_macro("getenv")
-#undef getenv
-#pragma push_macro("putenv")
-#undef putenv
-    if (getenv("TERM") == nullptr) {
-        // This is the same TERM value used by Gnome Terminal and the version of ssh included with
-        // Windows.
-        putenv("TERM=xterm-256color");
-    }
-#pragma pop_macro("putenv")
-#pragma pop_macro("getenv")
-}
-
-static bool _init_sysdeps() {
-    // _init_console() depends on _init_env() not being called yet.
-    _init_console();
-    _init_env();
-    _init_winsock();
-    return true;
-}
-
-static bool _sysdeps_init = _init_sysdeps();
diff --git a/adb/sysdeps_win32_test.cpp b/adb/sysdeps_win32_test.cpp
deleted file mode 100644
index 183cd5b..0000000
--- a/adb/sysdeps_win32_test.cpp
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <gtest/gtest.h>
-
-#include "sysdeps.h"
-
-#include <android-base/file.h>
-
-TEST(sysdeps_win32, adb_getenv) {
-    // Insert all test env vars before first call to adb_getenv() which will
-    // read the env var block only once.
-    ASSERT_EQ(0, _putenv("SYSDEPS_WIN32_TEST_UPPERCASE=1"));
-    ASSERT_EQ(0, _putenv("sysdeps_win32_test_lowercase=2"));
-    ASSERT_EQ(0, _putenv("Sysdeps_Win32_Test_MixedCase=3"));
-
-    // UTF-16 value
-    ASSERT_EQ(0, _wputenv(L"SYSDEPS_WIN32_TEST_UNICODE=\u00a1\u0048\u006f\u006c"
-                          L"\u0061\u0021\u03b1\u03b2\u03b3\u0061\u006d\u0062"
-                          L"\u0075\u006c\u014d\u043f\u0440\u0438\u0432\u0435"
-                          L"\u0442"));
-
-    // Search for non-existant env vars.
-    EXPECT_STREQ(nullptr, adb_getenv("SYSDEPS_WIN32_TEST_NONEXISTANT"));
-
-    // Search for existing env vars.
-
-    // There is no test for an env var with a value of a zero-length string
-    // because _putenv() does not support inserting such an env var.
-
-    // Search for env var that is uppercase.
-    EXPECT_STREQ("1", adb_getenv("SYSDEPS_WIN32_TEST_UPPERCASE"));
-    EXPECT_STREQ("1", adb_getenv("sysdeps_win32_test_uppercase"));
-    EXPECT_STREQ("1", adb_getenv("Sysdeps_Win32_Test_Uppercase"));
-
-    // Search for env var that is lowercase.
-    EXPECT_STREQ("2", adb_getenv("SYSDEPS_WIN32_TEST_LOWERCASE"));
-    EXPECT_STREQ("2", adb_getenv("sysdeps_win32_test_lowercase"));
-    EXPECT_STREQ("2", adb_getenv("Sysdeps_Win32_Test_Lowercase"));
-
-    // Search for env var that is mixed-case.
-    EXPECT_STREQ("3", adb_getenv("SYSDEPS_WIN32_TEST_MIXEDCASE"));
-    EXPECT_STREQ("3", adb_getenv("sysdeps_win32_test_mixedcase"));
-    EXPECT_STREQ("3", adb_getenv("Sysdeps_Win32_Test_MixedCase"));
-
-    // Check that UTF-16 was converted to UTF-8.
-    EXPECT_STREQ("\xc2\xa1\x48\x6f\x6c\x61\x21\xce\xb1\xce\xb2\xce\xb3\x61\x6d"
-                 "\x62\x75\x6c\xc5\x8d\xd0\xbf\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5"
-                 "\xd1\x82",
-                 adb_getenv("SYSDEPS_WIN32_TEST_UNICODE"));
-
-    // Check an env var that should always be set.
-    const char* path_val = adb_getenv("PATH");
-    EXPECT_NE(nullptr, path_val);
-    if (path_val != nullptr) {
-        EXPECT_GT(strlen(path_val), 0U);
-    }
-}
-
-TEST(sysdeps_win32, unix_isatty) {
-    // stdin and stdout should be consoles. Use CONIN$ and CONOUT$ special files
-    // so that we can test this even if stdin/stdout have been redirected. Read
-    // permissions are required for unix_isatty().
-    int conin_fd = unix_open("CONIN$", O_RDONLY);
-    int conout_fd = unix_open("CONOUT$", O_RDWR);
-    for (const int fd : {conin_fd, conout_fd}) {
-        EXPECT_TRUE(fd >= 0);
-        EXPECT_EQ(1, unix_isatty(fd));
-        EXPECT_EQ(0, unix_close(fd));
-    }
-
-    // nul returns 1 from isatty(), make sure unix_isatty() corrects that.
-    for (auto flags : {O_RDONLY, O_RDWR}) {
-        int nul_fd = unix_open("nul", flags);
-        EXPECT_TRUE(nul_fd >= 0);
-        EXPECT_EQ(0, unix_isatty(nul_fd));
-        EXPECT_EQ(0, unix_close(nul_fd));
-    }
-
-    // Check a real file, both read-write and read-only.
-    TemporaryFile temp_file;
-    EXPECT_TRUE(temp_file.fd >= 0);
-    EXPECT_EQ(0, unix_isatty(temp_file.fd));
-
-    int temp_file_ro_fd = unix_open(temp_file.path, O_RDONLY);
-    EXPECT_TRUE(temp_file_ro_fd >= 0);
-    EXPECT_EQ(0, unix_isatty(temp_file_ro_fd));
-    EXPECT_EQ(0, unix_close(temp_file_ro_fd));
-
-    // Check a real OS pipe.
-    int pipe_fds[2];
-    EXPECT_EQ(0, _pipe(pipe_fds, 64, _O_BINARY));
-    EXPECT_EQ(0, unix_isatty(pipe_fds[0]));
-    EXPECT_EQ(0, unix_isatty(pipe_fds[1]));
-    EXPECT_EQ(0, _close(pipe_fds[0]));
-    EXPECT_EQ(0, _close(pipe_fds[1]));
-
-    // Make sure an invalid FD is handled correctly.
-    EXPECT_EQ(0, unix_isatty(-1));
-}
-
-void TestParseCompleteUTF8(const char* buf, const size_t buf_size,
-                           const size_t expected_complete_bytes,
-                           const std::vector<char>& expected_remaining_bytes) {
-    std::vector<char> remaining_bytes;
-    const size_t complete_bytes = internal::ParseCompleteUTF8(buf, buf + buf_size,
-                                                              &remaining_bytes);
-    EXPECT_EQ(expected_complete_bytes, complete_bytes);
-    EXPECT_EQ(expected_remaining_bytes, remaining_bytes);
-}
-
-TEST(sysdeps_win32, ParseCompleteUTF8) {
-    const std::vector<std::vector<char>> multi_byte_sequences = {
-        { '\xc2', '\xa9' },                 // 2 byte UTF-8 sequence
-        { '\xe1', '\xb4', '\xa8' },         // 3 byte UTF-8 sequence
-        { '\xf0', '\x9f', '\x98', '\x80' }, // 4 byte UTF-8 sequence
-    };
-    std::vector<std::vector<char>> all_sequences = {
-        {},                                 // 0 bytes
-        { '\0' },                           // NULL byte
-        { 'a' },                            // 1 byte UTF-8 sequence
-    };
-    all_sequences.insert(all_sequences.end(), multi_byte_sequences.begin(),
-                         multi_byte_sequences.end());
-
-    // Vary a prefix of bytes in front of the sequence that we're actually interested in parsing.
-    for (const auto& prefix : all_sequences) {
-        // Parse (prefix + one byte of the sequence at a time)
-        for (const auto& seq : multi_byte_sequences) {
-            std::vector<char> buffer(prefix);
-
-            // For every byte of the sequence except the last
-            for (size_t i = 0; i < seq.size() - 1; ++i) {
-                buffer.push_back(seq[i]);
-
-                // When parsing an incomplete UTF-8 sequence, the amount of the buffer preceding
-                // the start of the incomplete UTF-8 sequence is valid. The remaining bytes are the
-                // bytes of the incomplete UTF-8 sequence.
-                TestParseCompleteUTF8(buffer.data(), buffer.size(), prefix.size(),
-                                      std::vector<char>(seq.begin(), seq.begin() + i + 1));
-            }
-
-            // For the last byte of the sequence
-            buffer.push_back(seq.back());
-            TestParseCompleteUTF8(buffer.data(), buffer.size(), buffer.size(), std::vector<char>());
-        }
-
-        // Parse (prefix (aka sequence) + invalid trailing bytes) to verify that the invalid
-        // trailing bytes are immediately "returned" to prevent them from being stuck in some
-        // buffer.
-        std::vector<char> buffer(prefix);
-        for (size_t i = 0; i < 8; ++i) {
-            buffer.push_back(0x80); // trailing byte
-            TestParseCompleteUTF8(buffer.data(), buffer.size(), buffer.size(), std::vector<char>());
-        }
-    }
-}
diff --git a/adb/test_adb.py b/adb/test_adb.py
deleted file mode 100755
index c872fb0..0000000
--- a/adb/test_adb.py
+++ /dev/null
@@ -1,587 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright (C) 2015 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-"""Tests for the adb program itself.
-
-This differs from things in test_device.py in that there is no API for these
-things. Most of these tests involve specific error messages or the help text.
-"""
-
-import contextlib
-import os
-import random
-import select
-import socket
-import struct
-import subprocess
-import sys
-import threading
-import time
-import unittest
-import warnings
-
-def find_open_port():
-    # Find an open port.
-    with socket.socket() as s:
-        s.bind(("localhost", 0))
-        return s.getsockname()[1]
-
-@contextlib.contextmanager
-def fake_adbd(protocol=socket.AF_INET, port=0):
-    """Creates a fake ADB daemon that just replies with a CNXN packet."""
-
-    serversock = socket.socket(protocol, socket.SOCK_STREAM)
-    serversock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
-    if protocol == socket.AF_INET:
-        serversock.bind(("127.0.0.1", port))
-    else:
-        serversock.bind(("::1", port))
-    serversock.listen(1)
-
-    # A pipe that is used to signal the thread that it should terminate.
-    readsock, writesock = socket.socketpair()
-
-    def _adb_packet(command: bytes, arg0: int, arg1: int, data: bytes) -> bytes:
-        bin_command = struct.unpack("I", command)[0]
-        buf = struct.pack("IIIIII", bin_command, arg0, arg1, len(data), 0,
-                          bin_command ^ 0xffffffff)
-        buf += data
-        return buf
-
-    def _handle(sock):
-        with contextlib.closing(sock) as serversock:
-            rlist = [readsock, serversock]
-            cnxn_sent = {}
-            while True:
-                read_ready, _, _ = select.select(rlist, [], [])
-                for ready in read_ready:
-                    if ready == readsock:
-                        # Closure pipe
-                        for f in rlist:
-                            f.close()
-                        return
-                    elif ready == serversock:
-                        # Server socket
-                        conn, _ = ready.accept()
-                        rlist.append(conn)
-                    else:
-                        # Client socket
-                        data = ready.recv(1024)
-                        if not data or data.startswith(b"OPEN"):
-                            if ready in cnxn_sent:
-                                del cnxn_sent[ready]
-                            ready.shutdown(socket.SHUT_RDWR)
-                            ready.close()
-                            rlist.remove(ready)
-                            continue
-                        if ready in cnxn_sent:
-                            continue
-                        cnxn_sent[ready] = True
-                        ready.sendall(_adb_packet(b"CNXN", 0x01000001, 1024 * 1024,
-                                                  b"device::ro.product.name=fakeadb"))
-
-    port = serversock.getsockname()[1]
-    server_thread = threading.Thread(target=_handle, args=(serversock,))
-    server_thread.start()
-
-    try:
-        yield port, writesock
-    finally:
-        writesock.close()
-        server_thread.join()
-
-
-@contextlib.contextmanager
-def adb_connect(unittest, serial):
-    """Context manager for an ADB connection.
-
-    This automatically disconnects when done with the connection.
-    """
-
-    output = subprocess.check_output(["adb", "connect", serial])
-    unittest.assertEqual(output.strip(),
-                        "connected to {}".format(serial).encode("utf8"))
-
-    try:
-        yield
-    finally:
-        # Perform best-effort disconnection. Discard the output.
-        subprocess.Popen(["adb", "disconnect", serial],
-                         stdout=subprocess.PIPE,
-                         stderr=subprocess.PIPE).communicate()
-
-
-@contextlib.contextmanager
-def adb_server():
-    """Context manager for an ADB server.
-
-    This creates an ADB server and returns the port it's listening on.
-    """
-
-    port = find_open_port()
-    read_pipe, write_pipe = os.pipe()
-
-    if sys.platform == "win32":
-        import msvcrt
-        write_handle = msvcrt.get_osfhandle(write_pipe)
-        os.set_handle_inheritable(write_handle, True)
-        reply_fd = str(write_handle)
-    else:
-        os.set_inheritable(write_pipe, True)
-        reply_fd = str(write_pipe)
-
-    proc = subprocess.Popen(["adb", "-L", "tcp:localhost:{}".format(port),
-                             "fork-server", "server",
-                             "--reply-fd", reply_fd], close_fds=False)
-    try:
-        os.close(write_pipe)
-        greeting = os.read(read_pipe, 1024)
-        assert greeting == b"OK\n", repr(greeting)
-        yield port
-    finally:
-        proc.terminate()
-        proc.wait()
-
-
-class CommandlineTest(unittest.TestCase):
-    """Tests for the ADB commandline."""
-
-    def test_help(self):
-        """Make sure we get _something_ out of help."""
-        out = subprocess.check_output(
-            ["adb", "help"], stderr=subprocess.STDOUT)
-        self.assertGreater(len(out), 0)
-
-    def test_version(self):
-        """Get a version number out of the output of adb."""
-        lines = subprocess.check_output(["adb", "version"]).splitlines()
-        version_line = lines[0]
-        self.assertRegex(
-            version_line, rb"^Android Debug Bridge version \d+\.\d+\.\d+$")
-        if len(lines) == 2:
-            # Newer versions of ADB have a second line of output for the
-            # version that includes a specific revision (git SHA).
-            revision_line = lines[1]
-            self.assertRegex(
-                revision_line, rb"^Revision [0-9a-f]{12}-android$")
-
-    def test_tcpip_error_messages(self):
-        """Make sure 'adb tcpip' parsing is sane."""
-        proc = subprocess.Popen(["adb", "tcpip"],
-                                stdout=subprocess.PIPE,
-                                stderr=subprocess.STDOUT)
-        out, _ = proc.communicate()
-        self.assertEqual(1, proc.returncode)
-        self.assertIn(b"requires an argument", out)
-
-        proc = subprocess.Popen(["adb", "tcpip", "foo"],
-                                stdout=subprocess.PIPE,
-                                stderr=subprocess.STDOUT)
-        out, _ = proc.communicate()
-        self.assertEqual(1, proc.returncode)
-        self.assertIn(b"invalid port", out)
-
-
-class ServerTest(unittest.TestCase):
-    """Tests for the ADB server."""
-
-    @staticmethod
-    def _read_pipe_and_set_event(pipe, event):
-        """Reads a pipe until it is closed, then sets the event."""
-        pipe.read()
-        event.set()
-
-    def test_handle_inheritance(self):
-        """Test that launch_server() does not inherit handles.
-
-        launch_server() should not let the adb server inherit
-        stdin/stdout/stderr handles, which can cause callers of adb.exe to hang.
-        This test also runs fine on unix even though the impetus is an issue
-        unique to Windows.
-        """
-        # This test takes 5 seconds to run on Windows: if there is no adb server
-        # running on the the port used below, adb kill-server tries to make a
-        # TCP connection to a closed port and that takes 1 second on Windows;
-        # adb start-server does the same TCP connection which takes another
-        # second, and it waits 3 seconds after starting the server.
-
-        # Start adb client with redirected stdin/stdout/stderr to check if it
-        # passes those redirections to the adb server that it starts. To do
-        # this, run an instance of the adb server on a non-default port so we
-        # don't conflict with a pre-existing adb server that may already be
-        # setup with adb TCP/emulator connections. If there is a pre-existing
-        # adb server, this also tests whether multiple instances of the adb
-        # server conflict on adb.log.
-
-        port = find_open_port()
-
-        try:
-            # We get warnings for unclosed files for the subprocess's pipes,
-            # and it's somewhat cumbersome to close them, so just ignore this.
-            warnings.simplefilter("ignore", ResourceWarning)
-
-            # Run the adb client and have it start the adb server.
-            proc = subprocess.Popen(["adb", "-P", str(port), "start-server"],
-                                    stdin=subprocess.PIPE,
-                                    stdout=subprocess.PIPE,
-                                    stderr=subprocess.PIPE)
-
-            # Start threads that set events when stdout/stderr are closed.
-            stdout_event = threading.Event()
-            stdout_thread = threading.Thread(
-                target=ServerTest._read_pipe_and_set_event,
-                args=(proc.stdout, stdout_event))
-            stdout_thread.start()
-
-            stderr_event = threading.Event()
-            stderr_thread = threading.Thread(
-                target=ServerTest._read_pipe_and_set_event,
-                args=(proc.stderr, stderr_event))
-            stderr_thread.start()
-
-            # Wait for the adb client to finish. Once that has occurred, if
-            # stdin/stderr/stdout are still open, it must be open in the adb
-            # server.
-            proc.wait()
-
-            # Try to write to stdin which we expect is closed. If it isn't
-            # closed, we should get an IOError. If we don't get an IOError,
-            # stdin must still be open in the adb server. The adb client is
-            # probably letting the adb server inherit stdin which would be
-            # wrong.
-            with self.assertRaises(IOError):
-                proc.stdin.write(b"x")
-                proc.stdin.flush()
-
-            # Wait a few seconds for stdout/stderr to be closed (in the success
-            # case, this won't wait at all). If there is a timeout, that means
-            # stdout/stderr were not closed and and they must be open in the adb
-            # server, suggesting that the adb client is letting the adb server
-            # inherit stdout/stderr which would be wrong.
-            self.assertTrue(stdout_event.wait(5), "adb stdout not closed")
-            self.assertTrue(stderr_event.wait(5), "adb stderr not closed")
-            stdout_thread.join()
-            stderr_thread.join()
-        finally:
-            # If we started a server, kill it.
-            subprocess.check_output(["adb", "-P", str(port), "kill-server"],
-                                    stderr=subprocess.STDOUT)
-
-    @unittest.skipUnless(
-        os.name == "posix",
-        "adb doesn't yet support IPv6 on Windows",
-    )
-    def test_starts_on_ipv6_localhost(self):
-        """
-        Tests that the server can start up on ::1 and that it's accessible
-        """
-
-        server_port = find_open_port()
-        try:
-            subprocess.check_output(
-                ["adb", "-L", "tcp:[::1]:{}".format(server_port), "server"],
-                stderr=subprocess.STDOUT,
-            )
-            with fake_adbd() as (port, _):
-                with adb_connect(self, serial="localhost:{}".format(port)):
-                    pass
-        finally:
-            # If we started a server, kill it.
-            subprocess.check_output(
-                ["adb", "-P", str(server_port), "kill-server"],
-                stderr=subprocess.STDOUT,
-            )
-
-
-
-
-class EmulatorTest(unittest.TestCase):
-    """Tests for the emulator connection."""
-
-    def _reset_socket_on_close(self, sock):
-        """Use SO_LINGER to cause TCP RST segment to be sent on socket close."""
-        # The linger structure is two shorts on Windows, but two ints on Unix.
-        linger_format = "hh" if os.name == "nt" else "ii"
-        l_onoff = 1
-        l_linger = 0
-
-        sock.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER,
-                        struct.pack(linger_format, l_onoff, l_linger))
-        # Verify that we set the linger structure properly by retrieving it.
-        linger = sock.getsockopt(socket.SOL_SOCKET, socket.SO_LINGER, 16)
-        self.assertEqual((l_onoff, l_linger),
-                         struct.unpack_from(linger_format, linger))
-
-    def test_emu_kill(self):
-        """Ensure that adb emu kill works.
-
-        Bug: https://code.google.com/p/android/issues/detail?id=21021
-        """
-        with contextlib.closing(
-            socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as listener:
-            # Use SO_REUSEADDR so subsequent runs of the test can grab the port
-            # even if it is in TIME_WAIT.
-            listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
-            listener.bind(("127.0.0.1", 0))
-            listener.listen(4)
-            port = listener.getsockname()[1]
-
-            # Now that listening has started, start adb emu kill, telling it to
-            # connect to our mock emulator.
-            proc = subprocess.Popen(
-                ["adb", "-s", "emulator-" + str(port), "emu", "kill"],
-                stderr=subprocess.STDOUT)
-
-            accepted_connection, addr = listener.accept()
-            with contextlib.closing(accepted_connection) as conn:
-                # If WSAECONNABORTED (10053) is raised by any socket calls,
-                # then adb probably isn't reading the data that we sent it.
-                conn.sendall(("Android Console: type 'help' for a list "
-                             "of commands\r\n").encode("utf8"))
-                conn.sendall(b"OK\r\n")
-
-                with contextlib.closing(conn.makefile()) as connf:
-                    line = connf.readline()
-                    if line.startswith("auth"):
-                        # Ignore the first auth line.
-                        line = connf.readline()
-                    self.assertEqual("kill\n", line)
-                    self.assertEqual("quit\n", connf.readline())
-
-                conn.sendall(b"OK: killing emulator, bye bye\r\n")
-
-                # Use SO_LINGER to send TCP RST segment to test whether adb
-                # ignores WSAECONNRESET on Windows. This happens with the
-                # real emulator because it just calls exit() without closing
-                # the socket or calling shutdown(SD_SEND). At process
-                # termination, Windows sends a TCP RST segment for every
-                # open socket that shutdown(SD_SEND) wasn't used on.
-                self._reset_socket_on_close(conn)
-
-            # Wait for adb to finish, so we can check return code.
-            proc.communicate()
-
-            # If this fails, adb probably isn't ignoring WSAECONNRESET when
-            # reading the response from the adb emu kill command (on Windows).
-            self.assertEqual(0, proc.returncode)
-
-    def test_emulator_connect(self):
-        """Ensure that the emulator can connect.
-
-        Bug: http://b/78991667
-        """
-        with adb_server() as server_port:
-            with fake_adbd() as (port, _):
-                serial = "emulator-{}".format(port - 1)
-                # Ensure that the emulator is not there.
-                try:
-                    subprocess.check_output(["adb", "-P", str(server_port),
-                                             "-s", serial, "get-state"],
-                                            stderr=subprocess.STDOUT)
-                    self.fail("Device should not be available")
-                except subprocess.CalledProcessError as err:
-                    self.assertEqual(
-                        err.output.strip(),
-                        "error: device '{}' not found".format(serial).encode("utf8"))
-
-                # Let the ADB server know that the emulator has started.
-                with contextlib.closing(
-                        socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as sock:
-                    sock.connect(("localhost", server_port))
-                    command = "host:emulator:{}".format(port).encode("utf8")
-                    sock.sendall(b"%04x%s" % (len(command), command))
-
-                # Ensure the emulator is there.
-                subprocess.check_call(["adb", "-P", str(server_port),
-                                       "-s", serial, "wait-for-device"])
-                output = subprocess.check_output(["adb", "-P", str(server_port),
-                                                  "-s", serial, "get-state"])
-                self.assertEqual(output.strip(), b"device")
-
-
-class ConnectionTest(unittest.TestCase):
-    """Tests for adb connect."""
-
-    def test_connect_ipv4_ipv6(self):
-        """Ensure that `adb connect localhost:1234` will try both IPv4 and IPv6.
-
-        Bug: http://b/30313466
-        """
-        for protocol in (socket.AF_INET, socket.AF_INET6):
-            try:
-                with fake_adbd(protocol=protocol) as (port, _):
-                    serial = "localhost:{}".format(port)
-                    with adb_connect(self, serial):
-                        pass
-            except socket.error:
-                print("IPv6 not available, skipping")
-                continue
-
-    def test_already_connected(self):
-        """Ensure that an already-connected device stays connected."""
-
-        with fake_adbd() as (port, _):
-            serial = "localhost:{}".format(port)
-            with adb_connect(self, serial):
-                # b/31250450: this always returns 0 but probably shouldn't.
-                output = subprocess.check_output(["adb", "connect", serial])
-                self.assertEqual(
-                    output.strip(),
-                    "already connected to {}".format(serial).encode("utf8"))
-
-    @unittest.skip("Currently failing b/123247844")
-    def test_reconnect(self):
-        """Ensure that a disconnected device reconnects."""
-
-        with fake_adbd() as (port, _):
-            serial = "localhost:{}".format(port)
-            with adb_connect(self, serial):
-                # Wait a bit to give adb some time to connect.
-                time.sleep(0.25)
-
-                output = subprocess.check_output(["adb", "-s", serial,
-                                                  "get-state"])
-                self.assertEqual(output.strip(), b"device")
-
-                # This will fail.
-                proc = subprocess.Popen(["adb", "-s", serial, "shell", "true"],
-                                        stdout=subprocess.PIPE,
-                                        stderr=subprocess.STDOUT)
-                output, _ = proc.communicate()
-                self.assertEqual(output.strip(), b"error: closed")
-
-                subprocess.check_call(["adb", "-s", serial, "wait-for-device"])
-
-                output = subprocess.check_output(["adb", "-s", serial,
-                                                  "get-state"])
-                self.assertEqual(output.strip(), b"device")
-
-                # Once we explicitly kick a device, it won't attempt to
-                # reconnect.
-                output = subprocess.check_output(["adb", "disconnect", serial])
-                self.assertEqual(
-                    output.strip(),
-                    "disconnected {}".format(serial).encode("utf8"))
-                try:
-                    subprocess.check_output(["adb", "-s", serial, "get-state"],
-                                            stderr=subprocess.STDOUT)
-                    self.fail("Device should not be available")
-                except subprocess.CalledProcessError as err:
-                    self.assertEqual(
-                        err.output.strip(),
-                        "error: device '{}' not found".format(serial).encode("utf8"))
-
-
-class DisconnectionTest(unittest.TestCase):
-    """Tests for adb disconnect."""
-
-    def test_disconnect(self):
-        """Ensure that `adb disconnect` takes effect immediately."""
-
-        def _devices(port):
-            output = subprocess.check_output(["adb", "-P", str(port), "devices"])
-            return [x.split("\t") for x in output.decode("utf8").strip().splitlines()[1:]]
-
-        with adb_server() as server_port:
-            with fake_adbd() as (port, sock):
-                device_name = "localhost:{}".format(port)
-                output = subprocess.check_output(["adb", "-P", str(server_port),
-                                                  "connect", device_name])
-                self.assertEqual(output.strip(),
-                                  "connected to {}".format(device_name).encode("utf8"))
-
-
-                self.assertEqual(_devices(server_port), [[device_name, "device"]])
-
-                # Send a deliberately malformed packet to make the device go offline.
-                packet = struct.pack("IIIIII", 0, 0, 0, 0, 0, 0)
-                sock.sendall(packet)
-
-                # Wait a bit.
-                time.sleep(0.1)
-
-                self.assertEqual(_devices(server_port), [[device_name, "offline"]])
-
-                # Disconnect the device.
-                output = subprocess.check_output(["adb", "-P", str(server_port),
-                                                  "disconnect", device_name])
-
-                # Wait a bit.
-                time.sleep(0.1)
-
-                self.assertEqual(_devices(server_port), [])
-
-
-@unittest.skipUnless(sys.platform == "win32", "requires Windows")
-class PowerTest(unittest.TestCase):
-    def test_resume_usb_kick(self):
-        """Resuming from sleep/hibernate should kick USB devices."""
-        try:
-            usb_serial = subprocess.check_output(["adb", "-d", "get-serialno"]).strip()
-        except subprocess.CalledProcessError:
-            # If there are multiple USB devices, we don't have a way to check whether the selected
-            # device is USB.
-            raise unittest.SkipTest('requires single USB device')
-
-        try:
-            serial = subprocess.check_output(["adb", "get-serialno"]).strip()
-        except subprocess.CalledProcessError:
-            # Did you forget to select a device with $ANDROID_SERIAL?
-            raise unittest.SkipTest('requires $ANDROID_SERIAL set to a USB device')
-
-        # Test only works with USB devices because adb _power_notification_thread does not kick
-        # non-USB devices on resume event.
-        if serial != usb_serial:
-            raise unittest.SkipTest('requires USB device')
-
-        # Run an adb shell command in the background that takes a while to complete.
-        proc = subprocess.Popen(['adb', 'shell', 'sleep', '5'])
-
-        # Wait for startup of adb server's _power_notification_thread.
-        time.sleep(0.1)
-
-        # Simulate resuming from sleep/hibernation by sending Windows message.
-        import ctypes
-        from ctypes import wintypes
-        HWND_BROADCAST = 0xffff
-        WM_POWERBROADCAST = 0x218
-        PBT_APMRESUMEAUTOMATIC = 0x12
-
-        PostMessageW = ctypes.windll.user32.PostMessageW
-        PostMessageW.restype = wintypes.BOOL
-        PostMessageW.argtypes = (wintypes.HWND, wintypes.UINT, wintypes.WPARAM, wintypes.LPARAM)
-        result = PostMessageW(HWND_BROADCAST, WM_POWERBROADCAST, PBT_APMRESUMEAUTOMATIC, 0)
-        if not result:
-            raise ctypes.WinError()
-
-        # Wait for connection to adb shell to be broken by _power_notification_thread detecting the
-        # Windows message.
-        start = time.time()
-        proc.wait()
-        end = time.time()
-
-        # If the power event was detected, the adb shell command should be broken very quickly.
-        self.assertLess(end - start, 2)
-
-
-def main():
-    """Main entrypoint."""
-    random.seed(0)
-    unittest.main(verbosity=3)
-
-
-if __name__ == "__main__":
-    main()
diff --git a/adb/test_device.py b/adb/test_device.py
deleted file mode 100755
index 6a9ff89..0000000
--- a/adb/test_device.py
+++ /dev/null
@@ -1,1678 +0,0 @@
-#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
-#
-# Copyright (C) 2015 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-from __future__ import print_function
-
-import contextlib
-import hashlib
-import os
-import posixpath
-import random
-import re
-import shlex
-import shutil
-import signal
-import socket
-import string
-import subprocess
-import sys
-import tempfile
-import threading
-import time
-import unittest
-
-from datetime import datetime
-
-import adb
-
-def requires_root(func):
-    def wrapper(self, *args):
-        if self.device.get_prop('ro.debuggable') != '1':
-            raise unittest.SkipTest('requires rootable build')
-
-        was_root = self.device.shell(['id', '-un'])[0].strip() == 'root'
-        if not was_root:
-            self.device.root()
-            self.device.wait()
-
-        try:
-            func(self, *args)
-        finally:
-            if not was_root:
-                self.device.unroot()
-                self.device.wait()
-
-    return wrapper
-
-
-def requires_non_root(func):
-    def wrapper(self, *args):
-        was_root = self.device.shell(['id', '-un'])[0].strip() == 'root'
-        if was_root:
-            self.device.unroot()
-            self.device.wait()
-
-        try:
-            func(self, *args)
-        finally:
-            if was_root:
-                self.device.root()
-                self.device.wait()
-
-    return wrapper
-
-
-class DeviceTest(unittest.TestCase):
-    def setUp(self):
-        self.device = adb.get_device()
-
-
-class AbbTest(DeviceTest):
-    def test_smoke(self):
-        result = subprocess.run(['adb', 'abb'], capture_output=True)
-        self.assertEqual(1, result.returncode)
-        expected_output = b"cmd: No service specified; use -l to list all services\n"
-        self.assertEqual(expected_output, result.stderr)
-
-class ForwardReverseTest(DeviceTest):
-    def _test_no_rebind(self, description, direction_list, direction,
-                       direction_no_rebind, direction_remove_all):
-        msg = direction_list()
-        self.assertEqual('', msg.strip(),
-                         description + ' list must be empty to run this test.')
-
-        # Use --no-rebind with no existing binding
-        direction_no_rebind('tcp:5566', 'tcp:6655')
-        msg = direction_list()
-        self.assertTrue(re.search(r'tcp:5566.+tcp:6655', msg))
-
-        # Use --no-rebind with existing binding
-        with self.assertRaises(subprocess.CalledProcessError):
-            direction_no_rebind('tcp:5566', 'tcp:6677')
-        msg = direction_list()
-        self.assertFalse(re.search(r'tcp:5566.+tcp:6677', msg))
-        self.assertTrue(re.search(r'tcp:5566.+tcp:6655', msg))
-
-        # Use the absence of --no-rebind with existing binding
-        direction('tcp:5566', 'tcp:6677')
-        msg = direction_list()
-        self.assertFalse(re.search(r'tcp:5566.+tcp:6655', msg))
-        self.assertTrue(re.search(r'tcp:5566.+tcp:6677', msg))
-
-        direction_remove_all()
-        msg = direction_list()
-        self.assertEqual('', msg.strip())
-
-    def test_forward_no_rebind(self):
-        self._test_no_rebind('forward', self.device.forward_list,
-                            self.device.forward, self.device.forward_no_rebind,
-                            self.device.forward_remove_all)
-
-    def test_reverse_no_rebind(self):
-        self._test_no_rebind('reverse', self.device.reverse_list,
-                            self.device.reverse, self.device.reverse_no_rebind,
-                            self.device.reverse_remove_all)
-
-    def test_forward(self):
-        msg = self.device.forward_list()
-        self.assertEqual('', msg.strip(),
-                         'Forwarding list must be empty to run this test.')
-        self.device.forward('tcp:5566', 'tcp:6655')
-        msg = self.device.forward_list()
-        self.assertTrue(re.search(r'tcp:5566.+tcp:6655', msg))
-        self.device.forward('tcp:7788', 'tcp:8877')
-        msg = self.device.forward_list()
-        self.assertTrue(re.search(r'tcp:5566.+tcp:6655', msg))
-        self.assertTrue(re.search(r'tcp:7788.+tcp:8877', msg))
-        self.device.forward_remove('tcp:5566')
-        msg = self.device.forward_list()
-        self.assertFalse(re.search(r'tcp:5566.+tcp:6655', msg))
-        self.assertTrue(re.search(r'tcp:7788.+tcp:8877', msg))
-        self.device.forward_remove_all()
-        msg = self.device.forward_list()
-        self.assertEqual('', msg.strip())
-
-    def test_forward_old_protocol(self):
-        serialno = subprocess.check_output(self.device.adb_cmd + ['get-serialno']).strip()
-
-        msg = self.device.forward_list()
-        self.assertEqual('', msg.strip(),
-                         'Forwarding list must be empty to run this test.')
-
-        s = socket.create_connection(("localhost", 5037))
-        service = b"host-serial:%s:forward:tcp:5566;tcp:6655" % serialno
-        cmd = b"%04x%s" % (len(service), service)
-        s.sendall(cmd)
-
-        msg = self.device.forward_list()
-        self.assertTrue(re.search(r'tcp:5566.+tcp:6655', msg))
-
-        self.device.forward_remove_all()
-        msg = self.device.forward_list()
-        self.assertEqual('', msg.strip())
-
-    def test_forward_tcp_port_0(self):
-        self.assertEqual('', self.device.forward_list().strip(),
-                         'Forwarding list must be empty to run this test.')
-
-        try:
-            # If resolving TCP port 0 is supported, `adb forward` will print
-            # the actual port number.
-            port = self.device.forward('tcp:0', 'tcp:8888').strip()
-            if not port:
-                raise unittest.SkipTest('Forwarding tcp:0 is not available.')
-
-            self.assertTrue(re.search(r'tcp:{}.+tcp:8888'.format(port),
-                                      self.device.forward_list()))
-        finally:
-            self.device.forward_remove_all()
-
-    def test_reverse(self):
-        msg = self.device.reverse_list()
-        self.assertEqual('', msg.strip(),
-                         'Reverse forwarding list must be empty to run this test.')
-        self.device.reverse('tcp:5566', 'tcp:6655')
-        msg = self.device.reverse_list()
-        self.assertTrue(re.search(r'tcp:5566.+tcp:6655', msg))
-        self.device.reverse('tcp:7788', 'tcp:8877')
-        msg = self.device.reverse_list()
-        self.assertTrue(re.search(r'tcp:5566.+tcp:6655', msg))
-        self.assertTrue(re.search(r'tcp:7788.+tcp:8877', msg))
-        self.device.reverse_remove('tcp:5566')
-        msg = self.device.reverse_list()
-        self.assertFalse(re.search(r'tcp:5566.+tcp:6655', msg))
-        self.assertTrue(re.search(r'tcp:7788.+tcp:8877', msg))
-        self.device.reverse_remove_all()
-        msg = self.device.reverse_list()
-        self.assertEqual('', msg.strip())
-
-    def test_reverse_tcp_port_0(self):
-        self.assertEqual('', self.device.reverse_list().strip(),
-                         'Reverse list must be empty to run this test.')
-
-        try:
-            # If resolving TCP port 0 is supported, `adb reverse` will print
-            # the actual port number.
-            port = self.device.reverse('tcp:0', 'tcp:8888').strip()
-            if not port:
-                raise unittest.SkipTest('Reversing tcp:0 is not available.')
-
-            self.assertTrue(re.search(r'tcp:{}.+tcp:8888'.format(port),
-                                      self.device.reverse_list()))
-        finally:
-            self.device.reverse_remove_all()
-
-    def test_forward_reverse_echo(self):
-        """Send data through adb forward and read it back via adb reverse"""
-        forward_port = 12345
-        reverse_port = forward_port + 1
-        forward_spec = 'tcp:' + str(forward_port)
-        reverse_spec = 'tcp:' + str(reverse_port)
-        forward_setup = False
-        reverse_setup = False
-
-        try:
-            # listen on localhost:forward_port, connect to remote:forward_port
-            self.device.forward(forward_spec, forward_spec)
-            forward_setup = True
-            # listen on remote:forward_port, connect to localhost:reverse_port
-            self.device.reverse(forward_spec, reverse_spec)
-            reverse_setup = True
-
-            listener = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-            with contextlib.closing(listener):
-                # Use SO_REUSEADDR so that subsequent runs of the test can grab
-                # the port even if it is in TIME_WAIT.
-                listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
-
-                # Listen on localhost:reverse_port before connecting to
-                # localhost:forward_port because that will cause adb to connect
-                # back to localhost:reverse_port.
-                listener.bind(('127.0.0.1', reverse_port))
-                listener.listen(4)
-
-                client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-                with contextlib.closing(client):
-                    # Connect to the listener.
-                    client.connect(('127.0.0.1', forward_port))
-
-                    # Accept the client connection.
-                    accepted_connection, addr = listener.accept()
-                    with contextlib.closing(accepted_connection) as server:
-                        data = b'hello'
-
-                        # Send data into the port setup by adb forward.
-                        client.sendall(data)
-                        # Explicitly close() so that server gets EOF.
-                        client.close()
-
-                        # Verify that the data came back via adb reverse.
-                        self.assertEqual(data, server.makefile().read().encode("utf8"))
-        finally:
-            if reverse_setup:
-                self.device.reverse_remove(forward_spec)
-            if forward_setup:
-                self.device.forward_remove(forward_spec)
-
-
-class ShellTest(DeviceTest):
-    def _interactive_shell(self, shell_args, input):
-        """Runs an interactive adb shell.
-
-        Args:
-          shell_args: List of string arguments to `adb shell`.
-          input: bytes input to send to the interactive shell.
-
-        Returns:
-          The remote exit code.
-
-        Raises:
-          unittest.SkipTest: The device doesn't support exit codes.
-        """
-        if not self.device.has_shell_protocol():
-            raise unittest.SkipTest('exit codes are unavailable on this device')
-
-        proc = subprocess.Popen(
-                self.device.adb_cmd + ['shell'] + shell_args,
-                stdin=subprocess.PIPE, stdout=subprocess.PIPE,
-                stderr=subprocess.PIPE)
-        # Closing host-side stdin doesn't trigger a PTY shell to exit so we need
-        # to explicitly add an exit command to close the session from the device
-        # side, plus the necessary newline to complete the interactive command.
-        proc.communicate(input + b'; exit\n')
-        return proc.returncode
-
-    def test_cat(self):
-        """Check that we can at least cat a file."""
-        out = self.device.shell(['cat', '/proc/uptime'])[0].strip()
-        elements = out.split()
-        self.assertEqual(len(elements), 2)
-
-        uptime, idle = elements
-        self.assertGreater(float(uptime), 0.0)
-        self.assertGreater(float(idle), 0.0)
-
-    def test_throws_on_failure(self):
-        self.assertRaises(adb.ShellError, self.device.shell, ['false'])
-
-    def test_output_not_stripped(self):
-        out = self.device.shell(['echo', 'foo'])[0]
-        self.assertEqual(out, 'foo' + self.device.linesep)
-
-    def test_shell_command_length(self):
-        # Devices that have shell_v2 should be able to handle long commands.
-        if self.device.has_shell_protocol():
-            rc, out, err = self.device.shell_nocheck(['echo', 'x' * 16384])
-            self.assertEqual(rc, 0)
-            self.assertTrue(out == ('x' * 16384 + '\n'))
-
-    def test_shell_nocheck_failure(self):
-        rc, out, _ = self.device.shell_nocheck(['false'])
-        self.assertNotEqual(rc, 0)
-        self.assertEqual(out, '')
-
-    def test_shell_nocheck_output_not_stripped(self):
-        rc, out, _ = self.device.shell_nocheck(['echo', 'foo'])
-        self.assertEqual(rc, 0)
-        self.assertEqual(out, 'foo' + self.device.linesep)
-
-    def test_can_distinguish_tricky_results(self):
-        # If result checking on ADB shell is naively implemented as
-        # `adb shell <cmd>; echo $?`, we would be unable to distinguish the
-        # output from the result for a cmd of `echo -n 1`.
-        rc, out, _ = self.device.shell_nocheck(['echo', '-n', '1'])
-        self.assertEqual(rc, 0)
-        self.assertEqual(out, '1')
-
-    def test_line_endings(self):
-        """Ensure that line ending translation is not happening in the pty.
-
-        Bug: http://b/19735063
-        """
-        output = self.device.shell(['uname'])[0]
-        self.assertEqual(output, 'Linux' + self.device.linesep)
-
-    def test_pty_logic(self):
-        """Tests that a PTY is allocated when it should be.
-
-        PTY allocation behavior should match ssh.
-        """
-        def check_pty(args):
-            """Checks adb shell PTY allocation.
-
-            Tests |args| for terminal and non-terminal stdin.
-
-            Args:
-                args: -Tt args in a list (e.g. ['-t', '-t']).
-
-            Returns:
-                A tuple (<terminal>, <non-terminal>). True indicates
-                the corresponding shell allocated a remote PTY.
-            """
-            test_cmd = self.device.adb_cmd + ['shell'] + args + ['[ -t 0 ]']
-
-            terminal = subprocess.Popen(
-                    test_cmd, stdin=None,
-                    stdout=subprocess.PIPE, stderr=subprocess.PIPE)
-            terminal.communicate()
-
-            non_terminal = subprocess.Popen(
-                    test_cmd, stdin=subprocess.PIPE,
-                    stdout=subprocess.PIPE, stderr=subprocess.PIPE)
-            non_terminal.communicate()
-
-            return (terminal.returncode == 0, non_terminal.returncode == 0)
-
-        # -T: never allocate PTY.
-        self.assertEqual((False, False), check_pty(['-T']))
-
-        # These tests require a new device.
-        if self.device.has_shell_protocol() and os.isatty(sys.stdin.fileno()):
-            # No args: PTY only if stdin is a terminal and shell is interactive,
-            # which is difficult to reliably test from a script.
-            self.assertEqual((False, False), check_pty([]))
-
-            # -t: PTY if stdin is a terminal.
-            self.assertEqual((True, False), check_pty(['-t']))
-
-        # -t -t: always allocate PTY.
-        self.assertEqual((True, True), check_pty(['-t', '-t']))
-
-        # -tt: always allocate PTY, POSIX style (http://b/32216152).
-        self.assertEqual((True, True), check_pty(['-tt']))
-
-        # -ttt: ssh has weird even/odd behavior with multiple -t flags, but
-        # we follow the man page instead.
-        self.assertEqual((True, True), check_pty(['-ttt']))
-
-        # -ttx: -x and -tt aren't incompatible (though -Tx would be an error).
-        self.assertEqual((True, True), check_pty(['-ttx']))
-
-        # -Ttt: -tt cancels out -T.
-        self.assertEqual((True, True), check_pty(['-Ttt']))
-
-        # -ttT: -T cancels out -tt.
-        self.assertEqual((False, False), check_pty(['-ttT']))
-
-    def test_shell_protocol(self):
-        """Tests the shell protocol on the device.
-
-        If the device supports shell protocol, this gives us the ability
-        to separate stdout/stderr and return the exit code directly.
-
-        Bug: http://b/19734861
-        """
-        if not self.device.has_shell_protocol():
-            raise unittest.SkipTest('shell protocol unsupported on this device')
-
-        # Shell protocol should be used by default.
-        result = self.device.shell_nocheck(
-                shlex.split('echo foo; echo bar >&2; exit 17'))
-        self.assertEqual(17, result[0])
-        self.assertEqual('foo' + self.device.linesep, result[1])
-        self.assertEqual('bar' + self.device.linesep, result[2])
-
-        self.assertEqual(17, self._interactive_shell([], b'exit 17'))
-
-        # -x flag should disable shell protocol.
-        result = self.device.shell_nocheck(
-                shlex.split('-x echo foo; echo bar >&2; exit 17'))
-        self.assertEqual(0, result[0])
-        self.assertEqual('foo{0}bar{0}'.format(self.device.linesep), result[1])
-        self.assertEqual('', result[2])
-
-        self.assertEqual(0, self._interactive_shell(['-x'], b'exit 17'))
-
-    def test_non_interactive_sigint(self):
-        """Tests that SIGINT in a non-interactive shell kills the process.
-
-        This requires the shell protocol in order to detect the broken
-        pipe; raw data transfer mode will only see the break once the
-        subprocess tries to read or write.
-
-        Bug: http://b/23825725
-        """
-        if not self.device.has_shell_protocol():
-            raise unittest.SkipTest('shell protocol unsupported on this device')
-
-        # Start a long-running process.
-        sleep_proc = subprocess.Popen(
-                self.device.adb_cmd + shlex.split('shell echo $$; sleep 60'),
-                stdin=subprocess.PIPE, stdout=subprocess.PIPE,
-                stderr=subprocess.STDOUT)
-        remote_pid = sleep_proc.stdout.readline().strip().decode("utf8")
-        self.assertIsNone(sleep_proc.returncode, 'subprocess terminated early')
-        proc_query = shlex.split('ps {0} | grep {0}'.format(remote_pid))
-
-        # Verify that the process is running, send signal, verify it stopped.
-        self.device.shell(proc_query)
-        os.kill(sleep_proc.pid, signal.SIGINT)
-        sleep_proc.communicate()
-
-        # It can take some time for the process to receive the signal and die.
-        end_time = time.time() + 3
-        while self.device.shell_nocheck(proc_query)[0] != 1:
-            self.assertFalse(time.time() > end_time,
-                             'subprocess failed to terminate in time')
-
-    def test_non_interactive_stdin(self):
-        """Tests that non-interactive shells send stdin."""
-        if not self.device.has_shell_protocol():
-            raise unittest.SkipTest('non-interactive stdin unsupported '
-                                    'on this device')
-
-        # Test both small and large inputs.
-        small_input = b'foo'
-        characters = [c.encode("utf8") for c in string.ascii_letters + string.digits]
-        large_input = b'\n'.join(characters)
-
-
-        for input in (small_input, large_input):
-            proc = subprocess.Popen(self.device.adb_cmd + ['shell', 'cat'],
-                                    stdin=subprocess.PIPE,
-                                    stdout=subprocess.PIPE,
-                                    stderr=subprocess.PIPE)
-            stdout, stderr = proc.communicate(input)
-            self.assertEqual(input.splitlines(), stdout.splitlines())
-            self.assertEqual(b'', stderr)
-
-    def test_sighup(self):
-        """Ensure that SIGHUP gets sent upon non-interactive ctrl-c"""
-        log_path = "/data/local/tmp/adb_signal_test.log"
-
-        # Clear the output file.
-        self.device.shell_nocheck(["echo", ">", log_path])
-
-        script = """
-            trap "echo SIGINT > {path}; exit 0" SIGINT
-            trap "echo SIGHUP > {path}; exit 0" SIGHUP
-            echo Waiting
-            read
-        """.format(path=log_path)
-
-        script = ";".join([x.strip() for x in script.strip().splitlines()])
-
-        process = self.device.shell_popen([script], kill_atexit=False,
-                                          stdin=subprocess.PIPE,
-                                          stdout=subprocess.PIPE)
-
-        self.assertEqual(b"Waiting\n", process.stdout.readline())
-        process.send_signal(signal.SIGINT)
-        process.wait()
-
-        # Waiting for the local adb to finish is insufficient, since it hangs
-        # up immediately.
-        time.sleep(1)
-
-        stdout, _ = self.device.shell(["cat", log_path])
-        self.assertEqual(stdout.strip(), "SIGHUP")
-
-    def test_exit_stress(self):
-        """Hammer `adb shell exit 42` with multiple threads."""
-        thread_count = 48
-        result = dict()
-        def hammer(thread_idx, thread_count, result):
-            success = True
-            for i in range(thread_idx, 240, thread_count):
-                ret = subprocess.call(['adb', 'shell', 'exit {}'.format(i)])
-                if ret != i % 256:
-                    success = False
-                    break
-            result[thread_idx] = success
-
-        threads = []
-        for i in range(thread_count):
-            thread = threading.Thread(target=hammer, args=(i, thread_count, result))
-            thread.start()
-            threads.append(thread)
-        for thread in threads:
-            thread.join()
-        for i, success in result.items():
-            self.assertTrue(success)
-
-    def disabled_test_parallel(self):
-        """Spawn a bunch of `adb shell` instances in parallel.
-
-        This was broken historically due to the use of select, which only works
-        for fds that are numerically less than 1024.
-
-        Bug: http://b/141955761"""
-
-        n_procs = 2048
-        procs = dict()
-        for i in range(0, n_procs):
-            procs[i] = subprocess.Popen(
-                ['adb', 'shell', 'read foo; echo $foo; read rc; exit $rc'],
-                stdin=subprocess.PIPE,
-                stdout=subprocess.PIPE
-            )
-
-        for i in range(0, n_procs):
-            procs[i].stdin.write("%d\n" % i)
-
-        for i in range(0, n_procs):
-            response = procs[i].stdout.readline()
-            assert(response == "%d\n" % i)
-
-        for i in range(0, n_procs):
-            procs[i].stdin.write("%d\n" % (i % 256))
-
-        for i in range(0, n_procs):
-            assert(procs[i].wait() == i % 256)
-
-
-class ArgumentEscapingTest(DeviceTest):
-    def test_shell_escaping(self):
-        """Make sure that argument escaping is somewhat sane."""
-
-        # http://b/19734868
-        # Note that this actually matches ssh(1)'s behavior --- it's
-        # converted to `sh -c echo hello; echo world` which sh interprets
-        # as `sh -c echo` (with an argument to that shell of "hello"),
-        # and then `echo world` back in the first shell.
-        result = self.device.shell(
-            shlex.split("sh -c 'echo hello; echo world'"))[0]
-        result = result.splitlines()
-        self.assertEqual(['', 'world'], result)
-        # If you really wanted "hello" and "world", here's what you'd do:
-        result = self.device.shell(
-            shlex.split(r'echo hello\;echo world'))[0].splitlines()
-        self.assertEqual(['hello', 'world'], result)
-
-        # http://b/15479704
-        result = self.device.shell(shlex.split("'true && echo t'"))[0].strip()
-        self.assertEqual('t', result)
-        result = self.device.shell(
-            shlex.split("sh -c 'true && echo t'"))[0].strip()
-        self.assertEqual('t', result)
-
-        # http://b/20564385
-        result = self.device.shell(shlex.split('FOO=a BAR=b echo t'))[0].strip()
-        self.assertEqual('t', result)
-        result = self.device.shell(
-            shlex.split(r'echo -n 123\;uname'))[0].strip()
-        self.assertEqual('123Linux', result)
-
-    def test_install_argument_escaping(self):
-        """Make sure that install argument escaping works."""
-        # http://b/20323053, http://b/3090932.
-        for file_suffix in (b'-text;ls;1.apk', b"-Live Hold'em.apk"):
-            tf = tempfile.NamedTemporaryFile('wb', suffix=file_suffix,
-                                             delete=False)
-            tf.close()
-
-            # Installing bogus .apks fails if the device supports exit codes.
-            try:
-                output = self.device.install(tf.name.decode("utf8"))
-            except subprocess.CalledProcessError as e:
-                output = e.output
-
-            self.assertIn(file_suffix, output)
-            os.remove(tf.name)
-
-
-class RootUnrootTest(DeviceTest):
-    def _test_root(self):
-        message = self.device.root()
-        if 'adbd cannot run as root in production builds' in message:
-            return
-        self.device.wait()
-        self.assertEqual('root', self.device.shell(['id', '-un'])[0].strip())
-
-    def _test_unroot(self):
-        self.device.unroot()
-        self.device.wait()
-        self.assertEqual('shell', self.device.shell(['id', '-un'])[0].strip())
-
-    def test_root_unroot(self):
-        """Make sure that adb root and adb unroot work, using id(1)."""
-        if self.device.get_prop('ro.debuggable') != '1':
-            raise unittest.SkipTest('requires rootable build')
-
-        original_user = self.device.shell(['id', '-un'])[0].strip()
-        try:
-            if original_user == 'root':
-                self._test_unroot()
-                self._test_root()
-            elif original_user == 'shell':
-                self._test_root()
-                self._test_unroot()
-        finally:
-            if original_user == 'root':
-                self.device.root()
-            else:
-                self.device.unroot()
-            self.device.wait()
-
-
-class TcpIpTest(DeviceTest):
-    def test_tcpip_failure_raises(self):
-        """adb tcpip requires a port.
-
-        Bug: http://b/22636927
-        """
-        self.assertRaises(
-            subprocess.CalledProcessError, self.device.tcpip, '')
-        self.assertRaises(
-            subprocess.CalledProcessError, self.device.tcpip, 'foo')
-
-
-class SystemPropertiesTest(DeviceTest):
-    def test_get_prop(self):
-        self.assertEqual(self.device.get_prop('init.svc.adbd'), 'running')
-
-    @requires_root
-    def test_set_prop(self):
-        prop_name = 'foo.bar'
-        self.device.shell(['setprop', prop_name, '""'])
-
-        self.device.set_prop(prop_name, 'qux')
-        self.assertEqual(
-            self.device.shell(['getprop', prop_name])[0].strip(), 'qux')
-
-
-def compute_md5(string):
-    hsh = hashlib.md5()
-    hsh.update(string)
-    return hsh.hexdigest()
-
-
-def get_md5_prog(device):
-    """Older platforms (pre-L) had the name md5 rather than md5sum."""
-    try:
-        device.shell(['md5sum', '/proc/uptime'])
-        return 'md5sum'
-    except adb.ShellError:
-        return 'md5'
-
-
-class HostFile(object):
-    def __init__(self, handle, checksum):
-        self.handle = handle
-        self.checksum = checksum
-        self.full_path = handle.name
-        self.base_name = os.path.basename(self.full_path)
-
-
-class DeviceFile(object):
-    def __init__(self, checksum, full_path):
-        self.checksum = checksum
-        self.full_path = full_path
-        self.base_name = posixpath.basename(self.full_path)
-
-
-def make_random_host_files(in_dir, num_files):
-    min_size = 1 * (1 << 10)
-    max_size = 16 * (1 << 10)
-
-    files = []
-    for _ in range(num_files):
-        file_handle = tempfile.NamedTemporaryFile(dir=in_dir, delete=False)
-
-        size = random.randrange(min_size, max_size, 1024)
-        rand_str = os.urandom(size)
-        file_handle.write(rand_str)
-        file_handle.flush()
-        file_handle.close()
-
-        md5 = compute_md5(rand_str)
-        files.append(HostFile(file_handle, md5))
-    return files
-
-
-def make_random_device_files(device, in_dir, num_files, prefix='device_tmpfile'):
-    min_size = 1 * (1 << 10)
-    max_size = 16 * (1 << 10)
-
-    files = []
-    for file_num in range(num_files):
-        size = random.randrange(min_size, max_size, 1024)
-
-        base_name = prefix + str(file_num)
-        full_path = posixpath.join(in_dir, base_name)
-
-        device.shell(['dd', 'if=/dev/urandom', 'of={}'.format(full_path),
-                      'bs={}'.format(size), 'count=1'])
-        dev_md5, _ = device.shell([get_md5_prog(device), full_path])[0].split()
-
-        files.append(DeviceFile(dev_md5, full_path))
-    return files
-
-
-class FileOperationsTest(DeviceTest):
-    SCRATCH_DIR = '/data/local/tmp'
-    DEVICE_TEMP_FILE = SCRATCH_DIR + '/adb_test_file'
-    DEVICE_TEMP_DIR = SCRATCH_DIR + '/adb_test_dir'
-
-    def _verify_remote(self, checksum, remote_path):
-        dev_md5, _ = self.device.shell([get_md5_prog(self.device),
-                                        remote_path])[0].split()
-        self.assertEqual(checksum, dev_md5)
-
-    def _verify_local(self, checksum, local_path):
-        with open(local_path, 'rb') as host_file:
-            host_md5 = compute_md5(host_file.read())
-            self.assertEqual(host_md5, checksum)
-
-    def test_push(self):
-        """Push a randomly generated file to specified device."""
-        kbytes = 512
-        tmp = tempfile.NamedTemporaryFile(mode='wb', delete=False)
-        rand_str = os.urandom(1024 * kbytes)
-        tmp.write(rand_str)
-        tmp.close()
-
-        self.device.shell(['rm', '-rf', self.DEVICE_TEMP_FILE])
-        self.device.push(local=tmp.name, remote=self.DEVICE_TEMP_FILE)
-
-        self._verify_remote(compute_md5(rand_str), self.DEVICE_TEMP_FILE)
-        self.device.shell(['rm', '-f', self.DEVICE_TEMP_FILE])
-
-        os.remove(tmp.name)
-
-    def test_push_dir(self):
-        """Push a randomly generated directory of files to the device."""
-        self.device.shell(['rm', '-rf', self.DEVICE_TEMP_DIR])
-        self.device.shell(['mkdir', self.DEVICE_TEMP_DIR])
-
-        try:
-            host_dir = tempfile.mkdtemp()
-
-            # Make sure the temp directory isn't setuid, or else adb will complain.
-            os.chmod(host_dir, 0o700)
-
-            # Create 32 random files.
-            temp_files = make_random_host_files(in_dir=host_dir, num_files=32)
-            self.device.push(host_dir, self.DEVICE_TEMP_DIR)
-
-            for temp_file in temp_files:
-                remote_path = posixpath.join(self.DEVICE_TEMP_DIR,
-                                             os.path.basename(host_dir),
-                                             temp_file.base_name)
-                self._verify_remote(temp_file.checksum, remote_path)
-            self.device.shell(['rm', '-rf', self.DEVICE_TEMP_DIR])
-        finally:
-            if host_dir is not None:
-                shutil.rmtree(host_dir)
-
-    def disabled_test_push_empty(self):
-        """Push an empty directory to the device."""
-        self.device.shell(['rm', '-rf', self.DEVICE_TEMP_DIR])
-        self.device.shell(['mkdir', self.DEVICE_TEMP_DIR])
-
-        try:
-            host_dir = tempfile.mkdtemp()
-
-            # Make sure the temp directory isn't setuid, or else adb will complain.
-            os.chmod(host_dir, 0o700)
-
-            # Create an empty directory.
-            empty_dir_path = os.path.join(host_dir, 'empty')
-            os.mkdir(empty_dir_path);
-
-            self.device.push(empty_dir_path, self.DEVICE_TEMP_DIR)
-
-            remote_path = os.path.join(self.DEVICE_TEMP_DIR, "empty")
-            test_empty_cmd = ["[", "-d", remote_path, "]"]
-            rc, _, _ = self.device.shell_nocheck(test_empty_cmd)
-
-            self.assertEqual(rc, 0)
-            self.device.shell(['rm', '-rf', self.DEVICE_TEMP_DIR])
-        finally:
-            if host_dir is not None:
-                shutil.rmtree(host_dir)
-
-    @unittest.skipIf(sys.platform == "win32", "symlinks require elevated privileges on windows")
-    def test_push_symlink(self):
-        """Push a symlink.
-
-        Bug: http://b/31491920
-        """
-        try:
-            host_dir = tempfile.mkdtemp()
-
-            # Make sure the temp directory isn't setuid, or else adb will
-            # complain.
-            os.chmod(host_dir, 0o700)
-
-            with open(os.path.join(host_dir, 'foo'), 'w') as f:
-                f.write('foo')
-
-            symlink_path = os.path.join(host_dir, 'symlink')
-            os.symlink('foo', symlink_path)
-
-            self.device.shell(['rm', '-rf', self.DEVICE_TEMP_DIR])
-            self.device.shell(['mkdir', self.DEVICE_TEMP_DIR])
-            self.device.push(symlink_path, self.DEVICE_TEMP_DIR)
-            rc, out, _ = self.device.shell_nocheck(
-                ['cat', posixpath.join(self.DEVICE_TEMP_DIR, 'symlink')])
-            self.assertEqual(0, rc)
-            self.assertEqual(out.strip(), 'foo')
-        finally:
-            if host_dir is not None:
-                shutil.rmtree(host_dir)
-
-    def test_multiple_push(self):
-        """Push multiple files to the device in one adb push command.
-
-        Bug: http://b/25324823
-        """
-
-        self.device.shell(['rm', '-rf', self.DEVICE_TEMP_DIR])
-        self.device.shell(['mkdir', self.DEVICE_TEMP_DIR])
-
-        try:
-            host_dir = tempfile.mkdtemp()
-
-            # Create some random files and a subdirectory containing more files.
-            temp_files = make_random_host_files(in_dir=host_dir, num_files=4)
-
-            subdir = os.path.join(host_dir, 'subdir')
-            os.mkdir(subdir)
-            subdir_temp_files = make_random_host_files(in_dir=subdir,
-                                                       num_files=4)
-
-            paths = [x.full_path for x in temp_files]
-            paths.append(subdir)
-            self.device._simple_call(['push'] + paths + [self.DEVICE_TEMP_DIR])
-
-            for temp_file in temp_files:
-                remote_path = posixpath.join(self.DEVICE_TEMP_DIR,
-                                             temp_file.base_name)
-                self._verify_remote(temp_file.checksum, remote_path)
-
-            for subdir_temp_file in subdir_temp_files:
-                remote_path = posixpath.join(self.DEVICE_TEMP_DIR,
-                                             # BROKEN: http://b/25394682
-                                             # 'subdir';
-                                             temp_file.base_name)
-                self._verify_remote(temp_file.checksum, remote_path)
-
-
-            self.device.shell(['rm', '-rf', self.DEVICE_TEMP_DIR])
-        finally:
-            if host_dir is not None:
-                shutil.rmtree(host_dir)
-
-    @requires_non_root
-    def test_push_error_reporting(self):
-        """Make sure that errors that occur while pushing a file get reported
-
-        Bug: http://b/26816782
-        """
-        with tempfile.NamedTemporaryFile() as tmp_file:
-            tmp_file.write(b'\0' * 1024 * 1024)
-            tmp_file.flush()
-            try:
-                self.device.push(local=tmp_file.name, remote='/system/')
-                self.fail('push should not have succeeded')
-            except subprocess.CalledProcessError as e:
-                output = e.output
-
-            self.assertTrue(b'Permission denied' in output or
-                            b'Read-only file system' in output)
-
-    @requires_non_root
-    def test_push_directory_creation(self):
-        """Regression test for directory creation.
-
-        Bug: http://b/110953234
-        """
-        with tempfile.NamedTemporaryFile() as tmp_file:
-            tmp_file.write(b'\0' * 1024 * 1024)
-            tmp_file.flush()
-            remote_path = self.DEVICE_TEMP_DIR + '/test_push_directory_creation'
-            self.device.shell(['rm', '-rf', remote_path])
-
-            remote_path += '/filename'
-            self.device.push(local=tmp_file.name, remote=remote_path)
-
-    def disabled_test_push_multiple_slash_root(self):
-        """Regression test for pushing to //data/local/tmp.
-
-        Bug: http://b/141311284
-
-        Disabled because this broken on the adbd side as well: b/141943968
-        """
-        with tempfile.NamedTemporaryFile() as tmp_file:
-            tmp_file.write('\0' * 1024 * 1024)
-            tmp_file.flush()
-            remote_path = '/' + self.DEVICE_TEMP_DIR + '/test_push_multiple_slash_root'
-            self.device.shell(['rm', '-rf', remote_path])
-            self.device.push(local=tmp_file.name, remote=remote_path)
-
-    def _test_pull(self, remote_file, checksum):
-        tmp_write = tempfile.NamedTemporaryFile(mode='wb', delete=False)
-        tmp_write.close()
-        self.device.pull(remote=remote_file, local=tmp_write.name)
-        with open(tmp_write.name, 'rb') as tmp_read:
-            host_contents = tmp_read.read()
-            host_md5 = compute_md5(host_contents)
-        self.assertEqual(checksum, host_md5)
-        os.remove(tmp_write.name)
-
-    @requires_non_root
-    def test_pull_error_reporting(self):
-        self.device.shell(['touch', self.DEVICE_TEMP_FILE])
-        self.device.shell(['chmod', 'a-rwx', self.DEVICE_TEMP_FILE])
-
-        try:
-            output = self.device.pull(remote=self.DEVICE_TEMP_FILE, local='x')
-        except subprocess.CalledProcessError as e:
-            output = e.output
-
-        self.assertIn(b'Permission denied', output)
-
-        self.device.shell(['rm', '-f', self.DEVICE_TEMP_FILE])
-
-    def test_pull(self):
-        """Pull a randomly generated file from specified device."""
-        kbytes = 512
-        self.device.shell(['rm', '-rf', self.DEVICE_TEMP_FILE])
-        cmd = ['dd', 'if=/dev/urandom',
-               'of={}'.format(self.DEVICE_TEMP_FILE), 'bs=1024',
-               'count={}'.format(kbytes)]
-        self.device.shell(cmd)
-        dev_md5, _ = self.device.shell(
-            [get_md5_prog(self.device), self.DEVICE_TEMP_FILE])[0].split()
-        self._test_pull(self.DEVICE_TEMP_FILE, dev_md5)
-        self.device.shell_nocheck(['rm', self.DEVICE_TEMP_FILE])
-
-    def test_pull_dir(self):
-        """Pull a randomly generated directory of files from the device."""
-        try:
-            host_dir = tempfile.mkdtemp()
-
-            self.device.shell(['rm', '-rf', self.DEVICE_TEMP_DIR])
-            self.device.shell(['mkdir', '-p', self.DEVICE_TEMP_DIR])
-
-            # Populate device directory with random files.
-            temp_files = make_random_device_files(
-                self.device, in_dir=self.DEVICE_TEMP_DIR, num_files=32)
-
-            self.device.pull(remote=self.DEVICE_TEMP_DIR, local=host_dir)
-
-            for temp_file in temp_files:
-                host_path = os.path.join(
-                    host_dir, posixpath.basename(self.DEVICE_TEMP_DIR),
-                    temp_file.base_name)
-                self._verify_local(temp_file.checksum, host_path)
-
-            self.device.shell(['rm', '-rf', self.DEVICE_TEMP_DIR])
-        finally:
-            if host_dir is not None:
-                shutil.rmtree(host_dir)
-
-    def test_pull_dir_symlink(self):
-        """Pull a directory into a symlink to a directory.
-
-        Bug: http://b/27362811
-        """
-        if os.name != 'posix':
-            raise unittest.SkipTest('requires POSIX')
-
-        try:
-            host_dir = tempfile.mkdtemp()
-            real_dir = os.path.join(host_dir, 'dir')
-            symlink = os.path.join(host_dir, 'symlink')
-            os.mkdir(real_dir)
-            os.symlink(real_dir, symlink)
-
-            self.device.shell(['rm', '-rf', self.DEVICE_TEMP_DIR])
-            self.device.shell(['mkdir', '-p', self.DEVICE_TEMP_DIR])
-
-            # Populate device directory with random files.
-            temp_files = make_random_device_files(
-                self.device, in_dir=self.DEVICE_TEMP_DIR, num_files=32)
-
-            self.device.pull(remote=self.DEVICE_TEMP_DIR, local=symlink)
-
-            for temp_file in temp_files:
-                host_path = os.path.join(
-                    real_dir, posixpath.basename(self.DEVICE_TEMP_DIR),
-                    temp_file.base_name)
-                self._verify_local(temp_file.checksum, host_path)
-
-            self.device.shell(['rm', '-rf', self.DEVICE_TEMP_DIR])
-        finally:
-            if host_dir is not None:
-                shutil.rmtree(host_dir)
-
-    def test_pull_dir_symlink_collision(self):
-        """Pull a directory into a colliding symlink to directory."""
-        if os.name != 'posix':
-            raise unittest.SkipTest('requires POSIX')
-
-        try:
-            host_dir = tempfile.mkdtemp()
-            real_dir = os.path.join(host_dir, 'real')
-            tmp_dirname = os.path.basename(self.DEVICE_TEMP_DIR)
-            symlink = os.path.join(host_dir, tmp_dirname)
-            os.mkdir(real_dir)
-            os.symlink(real_dir, symlink)
-
-            self.device.shell(['rm', '-rf', self.DEVICE_TEMP_DIR])
-            self.device.shell(['mkdir', '-p', self.DEVICE_TEMP_DIR])
-
-            # Populate device directory with random files.
-            temp_files = make_random_device_files(
-                self.device, in_dir=self.DEVICE_TEMP_DIR, num_files=32)
-
-            self.device.pull(remote=self.DEVICE_TEMP_DIR, local=host_dir)
-
-            for temp_file in temp_files:
-                host_path = os.path.join(real_dir, temp_file.base_name)
-                self._verify_local(temp_file.checksum, host_path)
-
-            self.device.shell(['rm', '-rf', self.DEVICE_TEMP_DIR])
-        finally:
-            if host_dir is not None:
-                shutil.rmtree(host_dir)
-
-    def test_pull_dir_nonexistent(self):
-        """Pull a directory of files from the device to a nonexistent path."""
-        try:
-            host_dir = tempfile.mkdtemp()
-            dest_dir = os.path.join(host_dir, 'dest')
-
-            self.device.shell(['rm', '-rf', self.DEVICE_TEMP_DIR])
-            self.device.shell(['mkdir', '-p', self.DEVICE_TEMP_DIR])
-
-            # Populate device directory with random files.
-            temp_files = make_random_device_files(
-                self.device, in_dir=self.DEVICE_TEMP_DIR, num_files=32)
-
-            self.device.pull(remote=self.DEVICE_TEMP_DIR, local=dest_dir)
-
-            for temp_file in temp_files:
-                host_path = os.path.join(dest_dir, temp_file.base_name)
-                self._verify_local(temp_file.checksum, host_path)
-
-            self.device.shell(['rm', '-rf', self.DEVICE_TEMP_DIR])
-        finally:
-            if host_dir is not None:
-                shutil.rmtree(host_dir)
-
-    # selinux prevents adbd from accessing symlinks on /data/local/tmp.
-    def disabled_test_pull_symlink_dir(self):
-        """Pull a symlink to a directory of symlinks to files."""
-        try:
-            host_dir = tempfile.mkdtemp()
-
-            remote_dir = posixpath.join(self.DEVICE_TEMP_DIR, 'contents')
-            remote_links = posixpath.join(self.DEVICE_TEMP_DIR, 'links')
-            remote_symlink = posixpath.join(self.DEVICE_TEMP_DIR, 'symlink')
-
-            self.device.shell(['rm', '-rf', self.DEVICE_TEMP_DIR])
-            self.device.shell(['mkdir', '-p', remote_dir, remote_links])
-            self.device.shell(['ln', '-s', remote_links, remote_symlink])
-
-            # Populate device directory with random files.
-            temp_files = make_random_device_files(
-                self.device, in_dir=remote_dir, num_files=32)
-
-            for temp_file in temp_files:
-                self.device.shell(
-                    ['ln', '-s', '../contents/{}'.format(temp_file.base_name),
-                     posixpath.join(remote_links, temp_file.base_name)])
-
-            self.device.pull(remote=remote_symlink, local=host_dir)
-
-            for temp_file in temp_files:
-                host_path = os.path.join(
-                    host_dir, 'symlink', temp_file.base_name)
-                self._verify_local(temp_file.checksum, host_path)
-
-            self.device.shell(['rm', '-rf', self.DEVICE_TEMP_DIR])
-        finally:
-            if host_dir is not None:
-                shutil.rmtree(host_dir)
-
-    def test_pull_empty(self):
-        """Pull a directory containing an empty directory from the device."""
-        try:
-            host_dir = tempfile.mkdtemp()
-
-            remote_empty_path = posixpath.join(self.DEVICE_TEMP_DIR, 'empty')
-            self.device.shell(['rm', '-rf', self.DEVICE_TEMP_DIR])
-            self.device.shell(['mkdir', '-p', remote_empty_path])
-
-            self.device.pull(remote=remote_empty_path, local=host_dir)
-            self.assertTrue(os.path.isdir(os.path.join(host_dir, 'empty')))
-        finally:
-            if host_dir is not None:
-                shutil.rmtree(host_dir)
-
-    def test_multiple_pull(self):
-        """Pull a randomly generated directory of files from the device."""
-
-        try:
-            host_dir = tempfile.mkdtemp()
-
-            subdir = posixpath.join(self.DEVICE_TEMP_DIR, 'subdir')
-            self.device.shell(['rm', '-rf', self.DEVICE_TEMP_DIR])
-            self.device.shell(['mkdir', '-p', subdir])
-
-            # Create some random files and a subdirectory containing more files.
-            temp_files = make_random_device_files(
-                self.device, in_dir=self.DEVICE_TEMP_DIR, num_files=4)
-
-            subdir_temp_files = make_random_device_files(
-                self.device, in_dir=subdir, num_files=4, prefix='subdir_')
-
-            paths = [x.full_path for x in temp_files]
-            paths.append(subdir)
-            self.device._simple_call(['pull'] + paths + [host_dir])
-
-            for temp_file in temp_files:
-                local_path = os.path.join(host_dir, temp_file.base_name)
-                self._verify_local(temp_file.checksum, local_path)
-
-            for subdir_temp_file in subdir_temp_files:
-                local_path = os.path.join(host_dir,
-                                          'subdir',
-                                          subdir_temp_file.base_name)
-                self._verify_local(subdir_temp_file.checksum, local_path)
-
-            self.device.shell(['rm', '-rf', self.DEVICE_TEMP_DIR])
-        finally:
-            if host_dir is not None:
-                shutil.rmtree(host_dir)
-
-    def verify_sync(self, device, temp_files, device_dir):
-        """Verifies that a list of temp files was synced to the device."""
-        # Confirm that every file on the device mirrors that on the host.
-        for temp_file in temp_files:
-            device_full_path = posixpath.join(
-                device_dir, temp_file.base_name)
-            dev_md5, _ = device.shell(
-                [get_md5_prog(self.device), device_full_path])[0].split()
-            self.assertEqual(temp_file.checksum, dev_md5)
-
-    def test_sync(self):
-        """Sync a host directory to the data partition."""
-
-        try:
-            base_dir = tempfile.mkdtemp()
-
-            # Create mirror device directory hierarchy within base_dir.
-            full_dir_path = base_dir + self.DEVICE_TEMP_DIR
-            os.makedirs(full_dir_path)
-
-            # Create 32 random files within the host mirror.
-            temp_files = make_random_host_files(
-                in_dir=full_dir_path, num_files=32)
-
-            # Clean up any stale files on the device.
-            device = adb.get_device()  # pylint: disable=no-member
-            device.shell(['rm', '-rf', self.DEVICE_TEMP_DIR])
-
-            old_product_out = os.environ.get('ANDROID_PRODUCT_OUT')
-            os.environ['ANDROID_PRODUCT_OUT'] = base_dir
-            device.sync('data')
-            if old_product_out is None:
-                del os.environ['ANDROID_PRODUCT_OUT']
-            else:
-                os.environ['ANDROID_PRODUCT_OUT'] = old_product_out
-
-            self.verify_sync(device, temp_files, self.DEVICE_TEMP_DIR)
-
-            #self.device.shell(['rm', '-rf', self.DEVICE_TEMP_DIR])
-        finally:
-            if base_dir is not None:
-                shutil.rmtree(base_dir)
-
-    def test_push_sync(self):
-        """Sync a host directory to a specific path."""
-
-        try:
-            temp_dir = tempfile.mkdtemp()
-            temp_files = make_random_host_files(in_dir=temp_dir, num_files=32)
-
-            device_dir = posixpath.join(self.DEVICE_TEMP_DIR, 'sync_src_dst')
-
-            # Clean up any stale files on the device.
-            device = adb.get_device()  # pylint: disable=no-member
-            device.shell(['rm', '-rf', device_dir])
-
-            device.push(temp_dir, device_dir, sync=True)
-
-            self.verify_sync(device, temp_files, device_dir)
-
-            self.device.shell(['rm', '-rf', self.DEVICE_TEMP_DIR])
-        finally:
-            if temp_dir is not None:
-                shutil.rmtree(temp_dir)
-
-    def test_unicode_paths(self):
-        """Ensure that we can support non-ASCII paths, even on Windows."""
-        name = u'로보카 폴리'
-
-        self.device.shell(['rm', '-f', '/data/local/tmp/adb-test-*'])
-        remote_path = u'/data/local/tmp/adb-test-{}'.format(name)
-
-        ## push.
-        tf = tempfile.NamedTemporaryFile('wb', suffix=name, delete=False)
-        tf.close()
-        self.device.push(tf.name, remote_path)
-        os.remove(tf.name)
-        self.assertFalse(os.path.exists(tf.name))
-
-        # Verify that the device ended up with the expected UTF-8 path
-        output = self.device.shell(
-                ['ls', '/data/local/tmp/adb-test-*'])[0].strip()
-        self.assertEqual(remote_path, output)
-
-        # pull.
-        self.device.pull(remote_path, tf.name)
-        self.assertTrue(os.path.exists(tf.name))
-        os.remove(tf.name)
-        self.device.shell(['rm', '-f', '/data/local/tmp/adb-test-*'])
-
-
-class DeviceOfflineTest(DeviceTest):
-    def _get_device_state(self, serialno):
-        output = subprocess.check_output(self.device.adb_cmd + ['devices'])
-        for line in output.split('\n'):
-            m = re.match('(\S+)\s+(\S+)', line)
-            if m and m.group(1) == serialno:
-                return m.group(2)
-        return None
-
-    def disabled_test_killed_when_pushing_a_large_file(self):
-        """
-           While running adb push with a large file, kill adb server.
-           Occasionally the device becomes offline. Because the device is still
-           reading data without realizing that the adb server has been restarted.
-           Test if we can bring the device online automatically now.
-           http://b/32952319
-        """
-        serialno = subprocess.check_output(self.device.adb_cmd + ['get-serialno']).strip()
-        # 1. Push a large file
-        file_path = 'tmp_large_file'
-        try:
-            fh = open(file_path, 'w')
-            fh.write('\0' * (100 * 1024 * 1024))
-            fh.close()
-            subproc = subprocess.Popen(self.device.adb_cmd + ['push', file_path, '/data/local/tmp'])
-            time.sleep(0.1)
-            # 2. Kill the adb server
-            subprocess.check_call(self.device.adb_cmd + ['kill-server'])
-            subproc.terminate()
-        finally:
-            try:
-                os.unlink(file_path)
-            except:
-                pass
-        # 3. See if the device still exist.
-        # Sleep to wait for the adb server exit.
-        time.sleep(0.5)
-        # 4. The device should be online
-        self.assertEqual(self._get_device_state(serialno), 'device')
-
-    def disabled_test_killed_when_pulling_a_large_file(self):
-        """
-           While running adb pull with a large file, kill adb server.
-           Occasionally the device can't be connected. Because the device is trying to
-           send a message larger than what is expected by the adb server.
-           Test if we can bring the device online automatically now.
-        """
-        serialno = subprocess.check_output(self.device.adb_cmd + ['get-serialno']).strip()
-        file_path = 'tmp_large_file'
-        try:
-            # 1. Create a large file on device.
-            self.device.shell(['dd', 'if=/dev/zero', 'of=/data/local/tmp/tmp_large_file',
-                               'bs=1000000', 'count=100'])
-            # 2. Pull the large file on host.
-            subproc = subprocess.Popen(self.device.adb_cmd +
-                                       ['pull','/data/local/tmp/tmp_large_file', file_path])
-            time.sleep(0.1)
-            # 3. Kill the adb server
-            subprocess.check_call(self.device.adb_cmd + ['kill-server'])
-            subproc.terminate()
-        finally:
-            try:
-                os.unlink(file_path)
-            except:
-                pass
-        # 4. See if the device still exist.
-        # Sleep to wait for the adb server exit.
-        time.sleep(0.5)
-        self.assertEqual(self._get_device_state(serialno), 'device')
-
-
-    def test_packet_size_regression(self):
-        """Test for http://b/37783561
-
-        Receiving packets of a length divisible by 512 but not 1024 resulted in
-        the adb client waiting indefinitely for more input.
-        """
-        # The values that trigger things are 507 (512 - 5 bytes from shell protocol) + 1024*n
-        # Probe some surrounding values as well, for the hell of it.
-        for base in [512] + list(range(1024, 1024 * 16, 1024)):
-            for offset in [-6, -5, -4]:
-                length = base + offset
-                cmd = ['dd', 'if=/dev/zero', 'bs={}'.format(length), 'count=1', '2>/dev/null;'
-                       'echo', 'foo']
-                rc, stdout, _ = self.device.shell_nocheck(cmd)
-
-                self.assertEqual(0, rc)
-
-                # Output should be '\0' * length, followed by "foo\n"
-                self.assertEqual(length, len(stdout) - 4)
-                self.assertEqual(stdout, "\0" * length + "foo\n")
-
-    def test_zero_packet(self):
-        """Test for http://b/113070258
-
-        Make sure that we don't blow up when sending USB transfers that line up
-        exactly with the USB packet size.
-        """
-
-        local_port = int(self.device.forward("tcp:0", "tcp:12345"))
-        try:
-            for size in [512, 1024]:
-                def listener():
-                    cmd = ["echo foo | nc -l -p 12345; echo done"]
-                    rc, stdout, stderr = self.device.shell_nocheck(cmd)
-
-                thread = threading.Thread(target=listener)
-                thread.start()
-
-                # Wait a bit to let the shell command start.
-                time.sleep(0.25)
-
-                sock = socket.create_connection(("localhost", local_port))
-                with contextlib.closing(sock):
-                    bytesWritten = sock.send(b"a" * size)
-                    self.assertEqual(size, bytesWritten)
-                    readBytes = sock.recv(4096)
-                    self.assertEqual(b"foo\n", readBytes)
-
-                thread.join()
-        finally:
-            self.device.forward_remove("tcp:{}".format(local_port))
-
-
-class SocketTest(DeviceTest):
-    def test_socket_flush(self):
-        """Test that we handle socket closure properly.
-
-        If we're done writing to a socket, closing before the other end has
-        closed will send a TCP_RST if we have incoming data queued up, which
-        may result in data that we've written being discarded.
-
-        Bug: http://b/74616284
-        """
-        s = socket.create_connection(("localhost", 5037))
-
-        def adb_length_prefixed(string):
-            encoded = string.encode("utf8")
-            result = b"%04x%s" % (len(encoded), encoded)
-            return result
-
-        if "ANDROID_SERIAL" in os.environ:
-            transport_string = "host:transport:" + os.environ["ANDROID_SERIAL"]
-        else:
-            transport_string = "host:transport-any"
-
-        s.sendall(adb_length_prefixed(transport_string))
-        response = s.recv(4)
-        self.assertEqual(b"OKAY", response)
-
-        shell_string = "shell:sleep 0.5; dd if=/dev/zero bs=1m count=1 status=none; echo foo"
-        s.sendall(adb_length_prefixed(shell_string))
-
-        response = s.recv(4)
-        self.assertEqual(b"OKAY", response)
-
-        # Spawn a thread that dumps garbage into the socket until failure.
-        def spam():
-            buf = b"\0" * 16384
-            try:
-                while True:
-                    s.sendall(buf)
-            except Exception as ex:
-                print(ex)
-
-        thread = threading.Thread(target=spam)
-        thread.start()
-
-        time.sleep(1)
-
-        received = b""
-        while True:
-            read = s.recv(512)
-            if len(read) == 0:
-                break
-            received += read
-
-        self.assertEqual(1024 * 1024 + len("foo\n"), len(received))
-        thread.join()
-
-
-if sys.platform == "win32":
-    # From https://stackoverflow.com/a/38749458
-    import os
-    import contextlib
-    import msvcrt
-    import ctypes
-    from ctypes import wintypes
-
-    kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)
-
-    GENERIC_READ  = 0x80000000
-    GENERIC_WRITE = 0x40000000
-    FILE_SHARE_READ  = 1
-    FILE_SHARE_WRITE = 2
-    CONSOLE_TEXTMODE_BUFFER = 1
-    INVALID_HANDLE_VALUE = wintypes.HANDLE(-1).value
-    STD_OUTPUT_HANDLE = wintypes.DWORD(-11)
-    STD_ERROR_HANDLE = wintypes.DWORD(-12)
-
-    def _check_zero(result, func, args):
-        if not result:
-            raise ctypes.WinError(ctypes.get_last_error())
-        return args
-
-    def _check_invalid(result, func, args):
-        if result == INVALID_HANDLE_VALUE:
-            raise ctypes.WinError(ctypes.get_last_error())
-        return args
-
-    if not hasattr(wintypes, 'LPDWORD'): # Python 2
-        wintypes.LPDWORD = ctypes.POINTER(wintypes.DWORD)
-        wintypes.PSMALL_RECT = ctypes.POINTER(wintypes.SMALL_RECT)
-
-    class COORD(ctypes.Structure):
-        _fields_ = (('X', wintypes.SHORT),
-                    ('Y', wintypes.SHORT))
-
-    class CONSOLE_SCREEN_BUFFER_INFOEX(ctypes.Structure):
-        _fields_ = (('cbSize',               wintypes.ULONG),
-                    ('dwSize',               COORD),
-                    ('dwCursorPosition',     COORD),
-                    ('wAttributes',          wintypes.WORD),
-                    ('srWindow',             wintypes.SMALL_RECT),
-                    ('dwMaximumWindowSize',  COORD),
-                    ('wPopupAttributes',     wintypes.WORD),
-                    ('bFullscreenSupported', wintypes.BOOL),
-                    ('ColorTable',           wintypes.DWORD * 16))
-        def __init__(self, *args, **kwds):
-            super(CONSOLE_SCREEN_BUFFER_INFOEX, self).__init__(
-                    *args, **kwds)
-            self.cbSize = ctypes.sizeof(self)
-
-    PCONSOLE_SCREEN_BUFFER_INFOEX = ctypes.POINTER(
-                                        CONSOLE_SCREEN_BUFFER_INFOEX)
-    LPSECURITY_ATTRIBUTES = wintypes.LPVOID
-
-    kernel32.GetStdHandle.errcheck = _check_invalid
-    kernel32.GetStdHandle.restype = wintypes.HANDLE
-    kernel32.GetStdHandle.argtypes = (
-        wintypes.DWORD,) # _In_ nStdHandle
-
-    kernel32.CreateConsoleScreenBuffer.errcheck = _check_invalid
-    kernel32.CreateConsoleScreenBuffer.restype = wintypes.HANDLE
-    kernel32.CreateConsoleScreenBuffer.argtypes = (
-        wintypes.DWORD,        # _In_       dwDesiredAccess
-        wintypes.DWORD,        # _In_       dwShareMode
-        LPSECURITY_ATTRIBUTES, # _In_opt_   lpSecurityAttributes
-        wintypes.DWORD,        # _In_       dwFlags
-        wintypes.LPVOID)       # _Reserved_ lpScreenBufferData
-
-    kernel32.GetConsoleScreenBufferInfoEx.errcheck = _check_zero
-    kernel32.GetConsoleScreenBufferInfoEx.argtypes = (
-        wintypes.HANDLE,               # _In_  hConsoleOutput
-        PCONSOLE_SCREEN_BUFFER_INFOEX) # _Out_ lpConsoleScreenBufferInfo
-
-    kernel32.SetConsoleScreenBufferInfoEx.errcheck = _check_zero
-    kernel32.SetConsoleScreenBufferInfoEx.argtypes = (
-        wintypes.HANDLE,               # _In_  hConsoleOutput
-        PCONSOLE_SCREEN_BUFFER_INFOEX) # _In_  lpConsoleScreenBufferInfo
-
-    kernel32.SetConsoleWindowInfo.errcheck = _check_zero
-    kernel32.SetConsoleWindowInfo.argtypes = (
-        wintypes.HANDLE,      # _In_ hConsoleOutput
-        wintypes.BOOL,        # _In_ bAbsolute
-        wintypes.PSMALL_RECT) # _In_ lpConsoleWindow
-
-    kernel32.FillConsoleOutputCharacterW.errcheck = _check_zero
-    kernel32.FillConsoleOutputCharacterW.argtypes = (
-        wintypes.HANDLE,  # _In_  hConsoleOutput
-        wintypes.WCHAR,   # _In_  cCharacter
-        wintypes.DWORD,   # _In_  nLength
-        COORD,            # _In_  dwWriteCoord
-        wintypes.LPDWORD) # _Out_ lpNumberOfCharsWritten
-
-    kernel32.ReadConsoleOutputCharacterW.errcheck = _check_zero
-    kernel32.ReadConsoleOutputCharacterW.argtypes = (
-        wintypes.HANDLE,  # _In_  hConsoleOutput
-        wintypes.LPWSTR,  # _Out_ lpCharacter
-        wintypes.DWORD,   # _In_  nLength
-        COORD,            # _In_  dwReadCoord
-        wintypes.LPDWORD) # _Out_ lpNumberOfCharsRead
-
-    @contextlib.contextmanager
-    def allocate_console():
-        allocated = kernel32.AllocConsole()
-        try:
-            yield allocated
-        finally:
-            if allocated:
-                kernel32.FreeConsole()
-
-    @contextlib.contextmanager
-    def console_screen(ncols=None, nrows=None):
-        info = CONSOLE_SCREEN_BUFFER_INFOEX()
-        new_info = CONSOLE_SCREEN_BUFFER_INFOEX()
-        nwritten = (wintypes.DWORD * 1)()
-        hStdOut = kernel32.GetStdHandle(STD_OUTPUT_HANDLE)
-        kernel32.GetConsoleScreenBufferInfoEx(
-               hStdOut, ctypes.byref(info))
-        if ncols is None:
-            ncols = info.dwSize.X
-        if nrows is None:
-            nrows = info.dwSize.Y
-        elif nrows > 9999:
-            raise ValueError('nrows must be 9999 or less')
-        fd_screen = None
-        hScreen = kernel32.CreateConsoleScreenBuffer(
-                    GENERIC_READ | GENERIC_WRITE,
-                    FILE_SHARE_READ | FILE_SHARE_WRITE,
-                    None, CONSOLE_TEXTMODE_BUFFER, None)
-        try:
-            fd_screen = msvcrt.open_osfhandle(
-                            hScreen, os.O_RDWR | os.O_BINARY)
-            kernel32.GetConsoleScreenBufferInfoEx(
-                   hScreen, ctypes.byref(new_info))
-            new_info.dwSize = COORD(ncols, nrows)
-            new_info.srWindow = wintypes.SMALL_RECT(
-                    Left=0, Top=0, Right=(ncols - 1),
-                    Bottom=(info.srWindow.Bottom - info.srWindow.Top))
-            kernel32.SetConsoleScreenBufferInfoEx(
-                    hScreen, ctypes.byref(new_info))
-            kernel32.SetConsoleWindowInfo(hScreen, True,
-                    ctypes.byref(new_info.srWindow))
-            kernel32.FillConsoleOutputCharacterW(
-                    hScreen, u'\0', ncols * nrows, COORD(0,0), nwritten)
-            kernel32.SetConsoleActiveScreenBuffer(hScreen)
-            try:
-                yield fd_screen
-            finally:
-                kernel32.SetConsoleScreenBufferInfoEx(
-                    hStdOut, ctypes.byref(info))
-                kernel32.SetConsoleWindowInfo(hStdOut, True,
-                        ctypes.byref(info.srWindow))
-                kernel32.SetConsoleActiveScreenBuffer(hStdOut)
-        finally:
-            if fd_screen is not None:
-                os.close(fd_screen)
-            else:
-                kernel32.CloseHandle(hScreen)
-
-    def read_screen(fd):
-        hScreen = msvcrt.get_osfhandle(fd)
-        csbi = CONSOLE_SCREEN_BUFFER_INFOEX()
-        kernel32.GetConsoleScreenBufferInfoEx(
-            hScreen, ctypes.byref(csbi))
-        ncols = csbi.dwSize.X
-        pos = csbi.dwCursorPosition
-        length = ncols * pos.Y + pos.X + 1
-        buf = (ctypes.c_wchar * length)()
-        n = (wintypes.DWORD * 1)()
-        kernel32.ReadConsoleOutputCharacterW(
-            hScreen, buf, length, COORD(0,0), n)
-        lines = [buf[i:i+ncols].rstrip(u'\0')
-                    for i in range(0, n[0], ncols)]
-        return u'\n'.join(lines)
-
-@unittest.skipUnless(sys.platform == "win32", "requires Windows")
-class WindowsConsoleTest(DeviceTest):
-    def test_unicode_output(self):
-        """Test Unicode command line parameters and Unicode console window output.
-
-        Bug: https://issuetracker.google.com/issues/111972753
-        """
-        # If we don't have a console window, allocate one. This isn't necessary if we're already
-        # being run from a console window, which is typical.
-        with allocate_console() as allocated_console:
-            # Create a temporary console buffer and switch to it. We could also pass a parameter of
-            # ncols=len(unicode_string), but it causes the window to flash as it is resized and
-            # likely unnecessary given the typical console window size.
-            with console_screen(nrows=1000) as screen:
-                unicode_string = u'로보카 폴리'
-                # Run adb and allow it to detect that stdout is a console, not a pipe, by using
-                # device.shell_popen() which does not use a pipe, unlike device.shell().
-                process = self.device.shell_popen(['echo', '"' + unicode_string + '"'])
-                process.wait()
-                # Read what was written by adb to the temporary console buffer.
-                console_output = read_screen(screen)
-                self.assertEqual(unicode_string, console_output)
-
-
-def main():
-    random.seed(0)
-    if len(adb.get_devices()) > 0:
-        suite = unittest.TestLoader().loadTestsFromName(__name__)
-        unittest.TextTestRunner(verbosity=3).run(suite)
-    else:
-        print('Test suite must be run with attached devices')
-
-
-if __name__ == '__main__':
-    main()
diff --git a/adb/tls/Android.bp b/adb/tls/Android.bp
deleted file mode 100644
index e5204f3..0000000
--- a/adb/tls/Android.bp
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright (C) 2020 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-cc_defaults {
-    name: "libadb_tls_connection_defaults",
-    cflags: [
-        "-Wall",
-        "-Wextra",
-        "-Wthread-safety",
-        "-Werror",
-    ],
-
-    compile_multilib: "both",
-
-    srcs: [
-        "adb_ca_list.cpp",
-        "tls_connection.cpp",
-    ],
-    target: {
-        windows: {
-            compile_multilib: "first",
-            enabled: true,
-        },
-    },
-    export_include_dirs: ["include"],
-
-    host_supported: true,
-    recovery_available: true,
-
-    visibility: [
-        "//bootable/recovery/minadbd:__subpackages__",
-        "//system/core/adb:__subpackages__",
-    ],
-
-    shared_libs: [
-        "libbase",
-        "libcrypto",
-        "liblog",
-        "libssl",
-    ],
-}
-
-cc_library {
-    name: "libadb_tls_connection",
-    defaults: ["libadb_tls_connection_defaults"],
-
-    apex_available: [
-        "com.android.adbd",
-        "test_com.android.adbd",
-    ],
-}
-
-// For running atest (b/147158681)
-cc_library_static {
-    name: "libadb_tls_connection_static",
-    defaults: ["libadb_tls_connection_defaults"],
-
-    apex_available: [
-        "//apex_available:platform",
-    ],
-}
diff --git a/adb/tls/adb_ca_list.cpp b/adb/tls/adb_ca_list.cpp
deleted file mode 100644
index 36afe42..0000000
--- a/adb/tls/adb_ca_list.cpp
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "adb/tls/adb_ca_list.h"
-
-#include <iomanip>
-#include <sstream>
-#include <vector>
-
-#include <android-base/logging.h>
-#include <android-base/strings.h>
-#include <openssl/ssl.h>
-
-namespace adb {
-namespace tls {
-
-namespace {
-
-// CA issuer identifier to distinguished embedded keys. Also has version
-// information appended to the end of the string (e.g. "AdbKey-0").
-static constexpr int kAdbKeyIdentifierNid = NID_organizationName;
-static constexpr char kAdbKeyIdentifierV0[] = "AdbKey-0";
-
-// Where we store the actual data
-static constexpr int kAdbKeyValueNid = NID_commonName;
-
-// TODO: Remove this once X509_NAME_add_entry_by_NID is fixed to use const unsigned char*
-// https://boringssl-review.googlesource.com/c/boringssl/+/39764
-int X509_NAME_add_entry_by_NID_const(X509_NAME* name, int nid, int type, const unsigned char* bytes,
-                                     int len, int loc, int set) {
-    return X509_NAME_add_entry_by_NID(name, nid, type, const_cast<unsigned char*>(bytes), len, loc,
-                                      set);
-}
-
-bool IsHexDigit(char c) {
-    return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f');
-}
-
-// Wrapper around X509_NAME_get_text_by_NID that first calculates the size
-// of the string. Returns empty string on failure.
-std::optional<std::string> GetX509NameTextByNid(X509_NAME* name, int nid) {
-    // |len| is the len of the text excluding the final null
-    int len = X509_NAME_get_text_by_NID(name, nid, nullptr, -1);
-    if (len <= 0) {
-        return std::nullopt;
-    }
-
-    // Include the space for the final null byte
-    std::vector<char> buf(len + 1, '\0');
-    CHECK(X509_NAME_get_text_by_NID(name, nid, buf.data(), buf.size()));
-    return std::make_optional(std::string(buf.data()));
-}
-
-}  // namespace
-
-// Takes an encoded public key and generates a X509_NAME that can be used in
-// TlsConnection::SetClientCAList(), to allow the client to figure out which of
-// its keys it should try to use in the TLS handshake.
-bssl::UniquePtr<X509_NAME> CreateCAIssuerFromEncodedKey(std::string_view key) {
-    // "O=AdbKey-0;CN=<key>;"
-    CHECK(!key.empty());
-
-    std::string identifier = kAdbKeyIdentifierV0;
-    bssl::UniquePtr<X509_NAME> name(X509_NAME_new());
-    CHECK(X509_NAME_add_entry_by_NID_const(name.get(), kAdbKeyIdentifierNid, MBSTRING_ASC,
-                                           reinterpret_cast<const uint8_t*>(identifier.data()),
-                                           identifier.size(), -1, 0));
-
-    CHECK(X509_NAME_add_entry_by_NID_const(name.get(), kAdbKeyValueNid, MBSTRING_ASC,
-                                           reinterpret_cast<const uint8_t*>(key.data()), key.size(),
-                                           -1, 0));
-    return name;
-}
-
-// Parses a CA issuer and returns the encoded key, if any.
-std::optional<std::string> ParseEncodedKeyFromCAIssuer(X509_NAME* issuer) {
-    CHECK(issuer);
-
-    auto buf = GetX509NameTextByNid(issuer, kAdbKeyIdentifierNid);
-    if (!buf) {
-        return std::nullopt;
-    }
-
-    // Check for supported versions
-    if (*buf == kAdbKeyIdentifierV0) {
-        return GetX509NameTextByNid(issuer, kAdbKeyValueNid);
-    }
-    return std::nullopt;
-}
-
-std::string SHA256BitsToHexString(std::string_view sha256) {
-    CHECK_EQ(sha256.size(), static_cast<size_t>(SHA256_DIGEST_LENGTH));
-    std::stringstream ss;
-    auto* u8 = reinterpret_cast<const uint8_t*>(sha256.data());
-    ss << std::uppercase << std::setfill('0') << std::hex;
-    // Convert to hex-string representation
-    for (size_t i = 0; i < SHA256_DIGEST_LENGTH; ++i) {
-        // Need to cast to something bigger than one byte, or
-        // stringstream will interpret it as a char value.
-        ss << std::setw(2) << static_cast<uint16_t>(u8[i]);
-    }
-    return ss.str();
-}
-
-std::optional<std::string> SHA256HexStringToBits(std::string_view sha256_str) {
-    if (sha256_str.size() != SHA256_DIGEST_LENGTH * 2) {
-        return std::nullopt;
-    }
-
-    std::string result;
-    for (size_t i = 0; i < SHA256_DIGEST_LENGTH; ++i) {
-        auto bytestr = std::string(sha256_str.substr(i * 2, 2));
-        if (!IsHexDigit(bytestr[0]) || !IsHexDigit(bytestr[1])) {
-            LOG(ERROR) << "SHA256 string has invalid non-hex chars";
-            return std::nullopt;
-        }
-        result += static_cast<char>(std::stol(bytestr, nullptr, 16));
-    }
-    return result;
-}
-
-}  // namespace tls
-}  // namespace adb
diff --git a/adb/tls/include/adb/tls/adb_ca_list.h b/adb/tls/include/adb/tls/adb_ca_list.h
deleted file mode 100644
index a1ab9a7..0000000
--- a/adb/tls/include/adb/tls/adb_ca_list.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <openssl/base.h>
-#include <optional>
-#include <string>
-
-// These APIs is used to embed adbd's known public keys into client-allowed CA
-// issuer list that can indicate to the client which key to use.
-namespace adb {
-namespace tls {
-
-// Takes an encoded public key and generates a X509_NAME that can be used in
-// TlsConnection::SetClientCAList(), to allow the client to figure out which of
-// its keys it should try to use in the TLS handshake. This is guaranteed to
-// return a valid X509_NAME, given a non-empty key.
-bssl::UniquePtr<X509_NAME> CreateCAIssuerFromEncodedKey(std::string_view key);
-
-// Parses a CA issuer and returns the encoded key, if any. On failure, returns
-// nullopt.
-std::optional<std::string> ParseEncodedKeyFromCAIssuer(X509_NAME* issuer);
-
-// Converts SHA256 bits to a hex string representation. |sha256| must be exactly
-// |SHA256_DIGEST_LENGTH| in size.
-std::string SHA256BitsToHexString(std::string_view sha256);
-
-// Converts a valid SHA256 hex string to the actual bits. Returns nullopt on
-// failure.
-std::optional<std::string> SHA256HexStringToBits(std::string_view sha256_str);
-
-}  // namespace tls
-}  // namespace adb
diff --git a/adb/tls/include/adb/tls/tls_connection.h b/adb/tls/include/adb/tls/tls_connection.h
deleted file mode 100644
index bc5b98a..0000000
--- a/adb/tls/include/adb/tls/tls_connection.h
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <string_view>
-#include <vector>
-
-#include <android-base/unique_fd.h>
-#include <openssl/ssl.h>
-#include <openssl/x509.h>
-
-namespace adb {
-namespace tls {
-
-class TlsConnection {
-  public:
-    // This class will require both client and server to exchange valid
-    // certificates.
-    enum class Role {
-        Server,
-        Client,
-    };
-
-    enum class TlsError : uint8_t {
-        Success = 0,
-        // An error indicating that we rejected the peer's certificate.
-        CertificateRejected,
-        // An error indicating that the peer rejected our certificate.
-        PeerRejectedCertificate,
-        // Add more if needed
-        UnknownFailure,
-    };
-
-    using CertVerifyCb = std::function<int(X509_STORE_CTX*)>;
-    using SetCertCb = std::function<int(SSL*)>;
-
-    virtual ~TlsConnection() = default;
-
-    // Adds a trusted certificate to the list for the SSL connection.
-    // During the handshake phase, it will check the list of trusted certificates.
-    // The connection will fail if the peer's certificate is not in the list. If
-    // you would like to accept any certificate, use #SetCertVerifyCallback and
-    // set your callback to always return 1.
-    //
-    // Returns true if |cert| was successfully added, false otherwise.
-    virtual bool AddTrustedCertificate(std::string_view cert) = 0;
-
-    // Sets a custom certificate verify callback. |cb| must return 1 if the
-    // certificate is trusted. Otherwise, return 0 if not.
-    virtual void SetCertVerifyCallback(CertVerifyCb cb) = 0;
-
-    // Configures a client |ca_list| that the server sends to the client in the
-    // CertificateRequest message.
-    virtual void SetClientCAList(STACK_OF(X509_NAME) * ca_list) = 0;
-
-    // Sets a callback that will be called to select a certificate. See
-    // https://commondatastorage.googleapis.com/chromium-boringssl-docs/ssl.h.html#SSL_CTX_set_cert_cb
-    // for more details.
-    virtual void SetCertificateCallback(SetCertCb cb) = 0;
-
-    // Exports a value derived from the master secret used in the TLS
-    // connection. This value should be used alongside any PAKE to ensure the
-    // peer is the intended peer. |length| is the requested length for the
-    // keying material. This is only valid after |DoHandshake| succeeds.
-    virtual std::vector<uint8_t> ExportKeyingMaterial(size_t length) = 0;
-
-    // Enable client-side check on whether server accepted the handshake. In TLS
-    // 1.3, client will not know the server rejected the handshake until after
-    // performing a read operation. Basically, this will perform an
-    // SSL_peek right after the handshake and see whether that succeeds.
-    //
-    // IMPORTANT: this will only work if the protocol is a server-speaks-first
-    // type. Enabling this for the server is a no-op. This is disabled by
-    // default.
-    virtual void EnableClientPostHandshakeCheck(bool enable) = 0;
-
-    // Starts the handshake process. Returns TlsError::Success if handshake
-    // succeeded.
-    virtual TlsError DoHandshake() = 0;
-
-    // Reads |size| bytes and returns the data. The returned data has either
-    // size |size| or zero, in which case the read failed.
-    virtual std::vector<uint8_t> ReadFully(size_t size) = 0;
-
-    // Overloaded ReadFully method, which accepts a buffer for writing in.
-    // Returns true iff exactly |size| amount of data was written into |buf|,
-    // false otherwise.
-    virtual bool ReadFully(void* buf, size_t size) = 0;
-
-    // Writes |size| bytes. Returns true if all |size| bytes were read.
-    // Returns false otherwise.
-    virtual bool WriteFully(std::string_view data) = 0;
-
-    // Create a new TlsConnection instance. |cert| and |priv_key| cannot be
-    // empty.
-    static std::unique_ptr<TlsConnection> Create(Role role, std::string_view cert,
-                                                 std::string_view priv_key,
-                                                 android::base::borrowed_fd fd);
-
-    // Helper to set the certificate and key strings to a SSL client/server.
-    // Useful when in the set-certificate callback.
-    static bool SetCertAndKey(SSL* ssl, std::string_view cert_chain, std::string_view priv_key);
-
-  protected:
-    TlsConnection() = default;
-};  // TlsConnection
-
-}  // namespace tls
-}  // namespace adb
diff --git a/adb/tls/tests/Android.bp b/adb/tls/tests/Android.bp
deleted file mode 100644
index 198de58..0000000
--- a/adb/tls/tests/Android.bp
+++ /dev/null
@@ -1,42 +0,0 @@
-//
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-cc_test {
-    name: "adb_tls_connection_test",
-    srcs: [
-        "adb_ca_list_test.cpp",
-        "tls_connection_test.cpp",
-    ],
-
-    compile_multilib: "first",
-
-    shared_libs: [
-        "libbase",
-        "libcrypto",
-        "libcrypto_utils",
-        "libssl",
-    ],
-
-    // Let's statically link them so we don't have to install it onto the
-    // system image for testing.
-    static_libs: [
-        "libadb_crypto_static",
-        "libadb_protos_static",
-        "libadb_tls_connection_static",
-    ],
-
-    test_suites: ["device-tests"],
-}
diff --git a/adb/tls/tests/adb_ca_list_test.cpp b/adb/tls/tests/adb_ca_list_test.cpp
deleted file mode 100644
index c727e5f..0000000
--- a/adb/tls/tests/adb_ca_list_test.cpp
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "AdbCAListTest"
-
-#include <gtest/gtest.h>
-
-#include <adb/tls/adb_ca_list.h>
-#include <android-base/logging.h>
-#include <android-base/strings.h>
-#include <openssl/ssl.h>
-
-namespace adb {
-namespace tls {
-
-class AdbCAListTest : public testing::Test {
-  protected:
-    virtual void SetUp() override {}
-
-    virtual void TearDown() override {}
-};
-
-TEST_F(AdbCAListTest, SHA256BitsToHexString_BadParam) {
-    // Should crash if not exactly SHA256_DIGEST_LENGTH size
-    ASSERT_DEATH(
-            {
-                // empty
-                std::string sha;
-                SHA256BitsToHexString(sha);
-            },
-            "");
-    ASSERT_DEATH(
-            {
-                std::string sha(1, 0x80);
-                SHA256BitsToHexString(sha);
-            },
-            "");
-    ASSERT_DEATH(
-            {
-                std::string sha(SHA256_DIGEST_LENGTH - 1, 0x80);
-                SHA256BitsToHexString(sha);
-            },
-            "");
-    ASSERT_DEATH(
-            {
-                std::string sha(SHA256_DIGEST_LENGTH + 1, 0x80);
-                SHA256BitsToHexString(sha);
-            },
-            "");
-}
-
-TEST_F(AdbCAListTest, SHA256HexStringToBits_BadParam) {
-    {
-        // empty
-        std::string sha_str;
-        auto res = SHA256HexStringToBits(sha_str);
-        EXPECT_FALSE(res.has_value());
-    }
-    {
-        std::string sha_str(1, 'a');
-        auto res = SHA256HexStringToBits(sha_str);
-        EXPECT_FALSE(res.has_value());
-    }
-    {
-        std::string sha_str(SHA256_DIGEST_LENGTH * 2 - 1, 'a');
-        auto res = SHA256HexStringToBits(sha_str);
-        EXPECT_FALSE(res.has_value());
-    }
-    {
-        std::string sha_str(SHA256_DIGEST_LENGTH * 2 + 1, 'a');
-        auto res = SHA256HexStringToBits(sha_str);
-        EXPECT_FALSE(res.has_value());
-    }
-    {
-        // Non-hex chars
-        std::string sha_str(SHA256_DIGEST_LENGTH * 2, 'a');
-        sha_str[32] = 'x';
-        auto res = SHA256HexStringToBits(sha_str);
-        EXPECT_FALSE(res.has_value());
-    }
-}
-
-TEST_F(AdbCAListTest, SHA256BitsToHexString_ValidParam) {
-    uint8_t ct = 0;
-    // Test every possible byte
-    std::vector<std::string> expectedStr = {
-            "000102030405060708090A0B0C0D0E0F"
-            "101112131415161718191A1B1C1D1E1F",
-
-            "202122232425262728292A2B2C2D2E2F"
-            "303132333435363738393A3B3C3D3E3F",
-
-            "404142434445464748494A4B4C4D4E4F"
-            "505152535455565758595A5B5C5D5E5F",
-
-            "606162636465666768696A6B6C6D6E6F"
-            "707172737475767778797A7B7C7D7E7F",
-
-            "808182838485868788898A8B8C8D8E8F"
-            "909192939495969798999A9B9C9D9E9F",
-
-            "A0A1A2A3A4A5A6A7A8A9AAABACADAEAF"
-            "B0B1B2B3B4B5B6B7B8B9BABBBCBDBEBF",
-
-            "C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF"
-            "D0D1D2D3D4D5D6D7D8D9DADBDCDDDEDF",
-
-            "E0E1E2E3E4E5E6E7E8E9EAEBECEDEEEF"
-            "F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF",
-    };
-
-    for (auto& expected : expectedStr) {
-        std::string sha;
-        while (sha.size() < SHA256_DIGEST_LENGTH) {
-            sha += ct++;
-        }
-
-        auto sha_str = SHA256BitsToHexString(sha);
-        EXPECT_EQ(expected, sha_str);
-
-        // try to convert back to bits
-        auto out_sha = SHA256HexStringToBits(sha_str);
-        ASSERT_TRUE(out_sha.has_value());
-        EXPECT_EQ(*out_sha, sha);
-    }
-}
-
-TEST_F(AdbCAListTest, CreateCAIssuerFromEncodedKey_EmptyKey) {
-    ASSERT_DEATH({ auto issuer = CreateCAIssuerFromEncodedKey(""); }, "");
-}
-
-TEST_F(AdbCAListTest, Smoke) {
-    {
-        std::string key =
-                "A45BC1FF6C89BF0E"
-                "65F9BA153FBC9876"
-                "4969B4113F1CF878"
-                "EEF9BF1C3F9C9227";
-        auto issuer = CreateCAIssuerFromEncodedKey(key);
-        ASSERT_NE(issuer, nullptr);
-
-        // Try to parse the encoded key out of the X509_NAME
-        auto out_key = ParseEncodedKeyFromCAIssuer(issuer.get());
-        ASSERT_TRUE(out_key.has_value());
-        EXPECT_EQ(key, *out_key);
-    }
-}
-
-}  // namespace tls
-}  // namespace adb
diff --git a/adb/tls/tests/tls_connection_test.cpp b/adb/tls/tests/tls_connection_test.cpp
deleted file mode 100644
index 27bc1c9..0000000
--- a/adb/tls/tests/tls_connection_test.cpp
+++ /dev/null
@@ -1,608 +0,0 @@
-/*
- * Copyright 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "AdbWifiTlsConnectionTest"
-
-#include <thread>
-
-#include <gtest/gtest.h>
-
-#include <adb/crypto/rsa_2048_key.h>
-#include <adb/crypto/x509_generator.h>
-#include <adb/tls/adb_ca_list.h>
-#include <adb/tls/tls_connection.h>
-#include <android-base/logging.h>
-#include <android-base/strings.h>
-#include <android-base/unique_fd.h>
-#include <openssl/ssl.h>
-
-using namespace adb::crypto;
-
-namespace adb {
-namespace tls {
-
-using android::base::unique_fd;
-using TlsError = TlsConnection::TlsError;
-
-// Test X.509 certificates (RSA 2048)
-static const std::string kTestRsa2048ServerCert =
-        "-----BEGIN CERTIFICATE-----\n"
-        "MIIDFzCCAf+gAwIBAgIBATANBgkqhkiG9w0BAQsFADAtMQswCQYDVQQGEwJVUzEQ\n"
-        "MA4GA1UECgwHQW5kcm9pZDEMMAoGA1UEAwwDQWRiMB4XDTIwMDEyMTIyMjU1NVoX\n"
-        "DTMwMDExODIyMjU1NVowLTELMAkGA1UEBhMCVVMxEDAOBgNVBAoMB0FuZHJvaWQx\n"
-        "DDAKBgNVBAMMA0FkYjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK8E\n"
-        "2Ck9TfuKlz7wqWdMfknjZ1luFDp2IHxAUZzh/F6jeI2dOFGAjpeloSnGOE86FIaT\n"
-        "d1EvpyTh7nBwbrLZAA6XFZTo7Bl6BdNOQdqb2d2+cLEN0inFxqUIycevRtohUE1Y\n"
-        "FHM9fg442X1jOTWXjDZWeiqFWo95paAPhzm6pWqfJK1+YKfT1LsWZpYqJGGQE5pi\n"
-        "C3qOBYYgFpoXMxTYJNoZo3uOYEdM6upc8/vh15nMgIxX/ymJxEY5BHPpZPPWjXLg\n"
-        "BfzVaV9fUfv0JT4HQ4t2WvxC3cD/UsjWp2a6p454uUp2ENrANa+jRdRJepepg9D2\n"
-        "DKsx9L8zjc5Obqexrt0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8B\n"
-        "Af8EBAMCAYYwHQYDVR0OBBYEFDFW+8GTErwoZN5Uu9KyY4QdGYKpMA0GCSqGSIb3\n"
-        "DQEBCwUAA4IBAQBCDEn6SHXGlq5TU7J8cg1kRPd9bsJW+0hDuKSq0REXDkl0PcBf\n"
-        "fy282Agg9enKPPKmnpeQjM1dmnxdM8tT8LIUbMl779i3fn6v9HJVB+yG4gmRFThW\n"
-        "c+AGlBnrIT820cX/gU3h3R3FTahfsq+1rrSJkEgHyuC0HYeRyveSckBdaEOLvx0S\n"
-        "toun+32JJl5hWydpUUZhE9Mbb3KHBRM2YYZZU9JeJ08Apjl+3lRUeMAUwI5fkAAu\n"
-        "z/1SqnuGL96bd8P5ixdkA1+rF8FPhodGcq9mQOuUGP9g5HOXjaNoJYvwVRUdLeGh\n"
-        "cP/ReOTwQIzM1K5a83p8cX8AGGYmM7dQp7ec\n"
-        "-----END CERTIFICATE-----\n";
-
-static const std::string kTestRsa2048ServerPrivKey =
-        "-----BEGIN PRIVATE KEY-----\n"
-        "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCvBNgpPU37ipc+\n"
-        "8KlnTH5J42dZbhQ6diB8QFGc4fxeo3iNnThRgI6XpaEpxjhPOhSGk3dRL6ck4e5w\n"
-        "cG6y2QAOlxWU6OwZegXTTkHam9ndvnCxDdIpxcalCMnHr0baIVBNWBRzPX4OONl9\n"
-        "Yzk1l4w2VnoqhVqPeaWgD4c5uqVqnyStfmCn09S7FmaWKiRhkBOaYgt6jgWGIBaa\n"
-        "FzMU2CTaGaN7jmBHTOrqXPP74deZzICMV/8picRGOQRz6WTz1o1y4AX81WlfX1H7\n"
-        "9CU+B0OLdlr8Qt3A/1LI1qdmuqeOeLlKdhDawDWvo0XUSXqXqYPQ9gyrMfS/M43O\n"
-        "Tm6nsa7dAgMBAAECggEAFCS2bPdUKIgjbzLgtHW+hT+J2hD20rcHdyAp+dNH/2vI\n"
-        "yLfDJHJA4chGMRondKA704oDw2bSJxxlG9t83326lB35yxPhye7cM8fqgWrK8PVl\n"
-        "tU22FhO1ZgeJvb9OeXWNxKZyDW9oOOJ8eazNXVMuEo+dFj7B6l3MXQyHJPL2mJDm\n"
-        "u9ofFLdypX+gJncVO0oW0FNJnEUn2MMwHDNlo7gc4WdQuidPkuZItKRGcB8TTGF3\n"
-        "Ka1/2taYdTQ4Aq//Z84LlFvE0zD3T4c8LwYYzOzD4gGGTXvft7vSHzIun1S8YLRS\n"
-        "dEKXdVjtaFhgH3uUe4j+1b/vMvSHeoGBNX/G88GD+wKBgQDWUYVlMVqc9HD2IeYi\n"
-        "EfBcNwAJFJkh51yAl5QbUBgFYgFJVkkS/EDxEGFPvEmI3/pAeQFHFY13BI466EPs\n"
-        "o8Z8UUwWDp+Z1MFHHKQKnFakbsZbZlbqjJ9VJsqpezbpWhMHTOmcG0dmE7rf0lyM\n"
-        "eQv9slBB8qp2NEUs5Of7f2C2bwKBgQDRDq4nUuMQF1hbjM05tGKSIwkobmGsLspv\n"
-        "TMhkM7fq4RpbFHmbNgsFqMhcqYZ8gY6/scv5KCuAZ4yHUkbqwf5h+QCwrJ4uJeUJ\n"
-        "ZgJfHus2mmcNSo8FwSkNoojIQtzcbJav7bs2K9VTuertk/i7IJLApU4FOZZ5pghN\n"
-        "EXu0CZF1cwKBgDWFGhjRIF29tU/h20R60llU6s9Zs3wB+NmsALJpZ/ZAKS4VPB5f\n"
-        "nCAXBRYSYRKrTCU5kpYbzb4BBzuysPOxWmnFK4j+keCqfrGxd02nCQP7HdHJVr8v\n"
-        "6sIq88UrHeVcNxBFprjzHvtgxfQK5k22FMZ/9wbhAKyQFQ5HA5+MiaxFAoGAIcZZ\n"
-        "ZIkDninnYIMS9OursShv5lRO+15j3i9tgKLKZ+wOMgDQ1L6acUOfezj4PU1BHr8+\n"
-        "0PYocQpJreMhCfRlgLaV4fVBaPs+UZJld7CrF5tCYudUy/01ALrtlk0XGZWBktK5\n"
-        "mDrksC4tQkzRtonAq9cJD9cJ9IVaefkFH0UcdvkCgYBpZj50VLeGhnHHBnkJRlV1\n"
-        "fV+/P6PAq6RtqjA6O9Qdaoj5V3w2d63aQcQXQLJjH2BBmtCIy47r04rFvZpbCxP7\n"
-        "NH/OnK9NHpk2ucRTe8TAnVbvF/TZzPJoIxAO/D3OWaW6df4R8en8u6GYzWFglAyT\n"
-        "sydGT8yfWD1FYUWgfrVRbg==\n"
-        "-----END PRIVATE KEY-----\n";
-
-static const std::string kTestRsa2048ClientCert =
-        "-----BEGIN CERTIFICATE-----\n"
-        "MIIDFzCCAf+gAwIBAgIBATANBgkqhkiG9w0BAQsFADAtMQswCQYDVQQGEwJVUzEQ\n"
-        "MA4GA1UECgwHQW5kcm9pZDEMMAoGA1UEAwwDQWRiMB4XDTIwMDEyMTIyMjU1NloX\n"
-        "DTMwMDExODIyMjU1NlowLTELMAkGA1UEBhMCVVMxEDAOBgNVBAoMB0FuZHJvaWQx\n"
-        "DDAKBgNVBAMMA0FkYjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAI3a\n"
-        "EXh1S5FTbet7JVONswffRPaekdIK53cb8SnAbSO9X5OLA4zGwdkrBvDTsd96SKrp\n"
-        "JxmoNOE1DhbZh05KPlWAPkGKacjGWaz+S7biDOL0I6aaLbTlU/il1Ub9olPSBVUx\n"
-        "0nhdtEFgIOzddnP6/1KmyIIeRxS5lTKeg4avqUkZNXkz/wL1dHBFL7FNFf0SCcbo\n"
-        "tsub/deFbjZ27LTDN+SIBgFttTNqC5NTvoBAoMdyCOAgNYwaHO+fKiK3edfJieaw\n"
-        "7HD8qqmQxcpCtRlA8CUPj7GfR+WHiCJmlevhnkFXCo56R1BS0F4wuD4KPdSWt8gc\n"
-        "27ejH/9/z2cKo/6SLJMCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8B\n"
-        "Af8EBAMCAYYwHQYDVR0OBBYEFO/Mr5ygqqpyU/EHM9v7RDvcqaOkMA0GCSqGSIb3\n"
-        "DQEBCwUAA4IBAQAH33KMouzF2DYbjg90KDrDQr4rq3WfNb6P743knxdUFuvb+40U\n"
-        "QjC2OJZHkSexH7wfG/y6ic7vfCfF4clNs3QvU1lEjOZC57St8Fk7mdNdsWLwxEMD\n"
-        "uePFz0dvclSxNUHyCVMqNxddzQYzxiDWQRmXWrUBliMduQqEQelcxW2yDtg8bj+s\n"
-        "aMpR1ra9scaD4jzIZIIxLoOS9zBMuNRbgP217sZrniyGMhzoI1pZ/izN4oXpyH7O\n"
-        "THuaCzzRT3ph2f8EgmHSodz3ttgSf2DHzi/Ez1xUkk7NOlgNtmsxEdrM47+cC5ae\n"
-        "fIf2V+1o1JW8J7D11RmRbNPh3vfisueB4f88\n"
-        "-----END CERTIFICATE-----\n";
-
-static const std::string kTestRsa2048ClientPrivKey =
-        "-----BEGIN PRIVATE KEY-----\n"
-        "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCN2hF4dUuRU23r\n"
-        "eyVTjbMH30T2npHSCud3G/EpwG0jvV+TiwOMxsHZKwbw07Hfekiq6ScZqDThNQ4W\n"
-        "2YdOSj5VgD5BimnIxlms/ku24gzi9COmmi205VP4pdVG/aJT0gVVMdJ4XbRBYCDs\n"
-        "3XZz+v9SpsiCHkcUuZUynoOGr6lJGTV5M/8C9XRwRS+xTRX9EgnG6LbLm/3XhW42\n"
-        "duy0wzfkiAYBbbUzaguTU76AQKDHcgjgIDWMGhzvnyoit3nXyYnmsOxw/KqpkMXK\n"
-        "QrUZQPAlD4+xn0flh4giZpXr4Z5BVwqOekdQUtBeMLg+Cj3UlrfIHNu3ox//f89n\n"
-        "CqP+kiyTAgMBAAECggEAAa64eP6ggCob1P3c73oayYPIbvRqiQdAFOrr7Vwu7zbr\n"
-        "z0rde+n6RU0mrpc+4NuzyPMtrOGQiatLbidJB5Cx3z8U00ovqbCl7PtcgorOhFKe\n"
-        "VEzihebCcYyQqbWQcKtpDMhOgBxRwFoXieJb6VGXfa96FAZalCWvXgOrTl7/BF2X\n"
-        "qMqIm9nJi+yS5tIO8VdOsOmrMWRH/b/ENUcef4WpLoxTXr0EEgyKWraeZ/hhXo1e\n"
-        "z29dZKqdr9wMsq11NPsRddwS94jnDkXTo+EQyWVTfB7gb6yyp07s8jysaDb21tVv\n"
-        "UXB9MRhDV1mOv0ncXfXZ4/+4A2UahmZaLDAVLaat4QKBgQDAVRredhGRGl2Nkic3\n"
-        "KvZCAfyxug788CgasBdEiouz19iCCwcgMIDwnq0s3/WM7h/laCamT2x38riYDnpq\n"
-        "rkYMfuVtU9CjEL9pTrdfwbIRhTwYNqADaPz2mXwQUhRXutE5TIdgxxC/a+ZTh0qN\n"
-        "S+vhTj/4hf0IZhMh5Nqj7IPExQKBgQC8zxEzhmSGjys0GuE6Wl6Doo2TpiR6vwvi\n"
-        "xPLU9lmIz5eca/Rd/eERioFQqeoIWDLzx52DXuz6rUoQhbJWz9hP3yqCwXD+pbNP\n"
-        "oDJqDDbCC4IMYEb0IK/PEPH+gIpnTjoFcW+ecKDFG7W5Lt05J8WsJsfOaJvMrOU+\n"
-        "dLXq3IgxdwKBgQC5RAFq0v6e8G+3hFaEHL0z3igkpt3zJf7rnj37hx2FMmDa+3Z0\n"
-        "umQp5B9af61PgL12xLmeMBmC/Wp1BlVDV/Yf6Uhk5Hyv5t0KuomHEtTNbbLyfAPs\n"
-        "5P/vJu/L5NS1oT4S3LX3MineyjgGs+bLbpub3z1dzutrYLADUSiPCK/xJQKBgBQt\n"
-        "nQ0Ao+Wtj1R2OvPdjJRM3wyUiPmFSWPm4HzaBx+T8AQLlYYmB9O0FbXlMtnJc0iS\n"
-        "YMcVcgYoVu4FG9YjSF7g3s4yljzgwJUV7c1fmMqMKE3iTDLy+1cJ3JLycdgwiArk\n"
-        "4KTyLHxkRbuQwpvFIF8RlfD9RQlOwQE3v+llwDhpAoGBAL6XG6Rp6mBoD2Ds5c9R\n"
-        "943yYgSUes3ji1SI9zFqeJtj8Ml/enuK1xu+8E/BxB0//+vgZsH6i3i8GFwygKey\n"
-        "CGJF8CbiHc3EJc3NQIIRXcni/CGacf0HwC6m+PGFDBIpA4H2iDpVvCSofxttQiq0\n"
-        "/Z7HXmXUvZHVyYi/QzX2Gahj\n"
-        "-----END PRIVATE KEY-----\n";
-
-static const std::string kTestRsa2048UnknownPrivKey =
-        "-----BEGIN PRIVATE KEY-----\n"
-        "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCrIhr+CS+6UI0w\n"
-        "CTaVzQAicKBe6X531LeQAGYx7j5RLHR1QIoJ0WCc5msmXKe2VzcWuLbVdTGAIP1H\n"
-        "mwbPqlbO4ioxeJhiDv+WPuLG8+j4Iw1Yqxt8cfohxjfvNmIQM8aF5hGyyaaTetDF\n"
-        "EYWONoYCBC4WnFWgYCPb8mzWXlhHE3F66GnHpc32zydPTg3ZurGvSsFf7fNY9yRw\n"
-        "8WtwPiI6mpRxt+n2bQUp+LZ+g/3rXLFPg8uWDGYG7IvLluWc9gR9lxjL64t6ryLU\n"
-        "2cm7eTfDgLw/B1F/wEgCJDnby1JgQ4rq6klJO3BR2ooUr/7T343y5njG5hQJreV7\n"
-        "5ZnSmRLZAgMBAAECggEABPrfeHZFuWkj7KqN+DbAmt/2aMCodZ3+7/20+528WkIe\n"
-        "CvXzdmTth+9UHagLWNzpnVuHdYd9JuZ+3F00aelh8JAIDIu++naHhUSj9ohtRoBF\n"
-        "oIeNK5ZJAj/Zi5hkauaIz8dxyyc/VdIYfm2bundXd7pNqYqH2tyFWp6PwH67GKlZ\n"
-        "1lC7o8gKAK8sz9g0Ctdoe+hDqAsvYFCW4EWDM2qboucSgn8g3E/Gux/KrpXVv7d0\n"
-        "PMQ60m+dyTOCMGqXIoDR3TAvQR7ex5sQ/QZSREdxKy878s/2FY4ktxtCUWlhrmcI\n"
-        "VKtrDOGEKwNoiMluf2635rsVq2e01XhQlmdxbRFU0QKBgQDjOhhD1m9duFTQ2b+J\n"
-        "Xfn6m8Rs7sZqO4Az7gLOWmD/vYWlK4n2nZsh6u5/cB1N+PA+ncvvV4yKJAlLHxbT\n"
-        "pVvfzJ/jbUsj/NJg/w7+KYC9gXgRmBonuG2gRZF/5Otdlza4vMcoSkqGjlGxJyzL\n"
-        "+9umEziN3tEYMRwipYvt7BgbUQKBgQDAzaXryJ3YD3jpecy/+fSnQvFjpyeDRqU1\n"
-        "KDA9nxN5tJN6bnKhUlMhy64SsgvVX9jUuN7cK+qYV0uzdBn6kIAJNLWTdbtH93+e\n"
-        "vNVgluR3jmixW4QfY9vfZKdXZbVGNc0DFMi1vJqgxTgQ5Mq5PxxxRL4FsAF840V1\n"
-        "Wu9uhU0NCQKBgBfjga2QG8E0oeYbHmHouWE5gxsYt09v1fifqzfalJwOZsCIpUaC\n"
-        "J08Xjd9kABC0fT14BXqyL5pOU5PMPvAdUF1k++JDGUU9TTjZV9AsuNYziFYBMa6/\n"
-        "WvcgmT1i6cO7JAuj/SQlO1SOHdSME8+WOO9q0eVIaZ8repPB58YprhchAoGBAJyR\n"
-        "Y8AJdkTSq7nNszvi245IioYGY8vzPo3gSOyBlesrfOfbcTMYC3JSWNXNyFZKM2br\n"
-        "ie75qtRzb4IXMlGLrq3LI/jPjnpuvjBF4HFDl9yOxO3iB3UGPrM2pb4PVhnh7s4l\n"
-        "vqf2tQsBnPn7EbVFTu+ch0NPHqYwWWNnqS/zCBMhAoGBAIkYjOE0iD9W2FXee6VL\n"
-        "iN8wDqlqsGEEtLvykIDmTmM+ZX5ftQuPo18khpE9wQKmJ5OpoVTYIP1UsJFBakgo\n"
-        "+dGaf6xVuPvmydNFqixlW3z227n4Px6GX7CXlCaAleTeItezli+dWf/9astwTA3x\n"
-        "IazYzsxUUpZFC4dJ1GhBn3y1\n"
-        "-----END PRIVATE KEY-----\n";
-
-static const std::string kTestRsa2048UnknownCert =
-        "-----BEGIN CERTIFICATE-----\n"
-        "MIIDFzCCAf+gAwIBAgIBATANBgkqhkiG9w0BAQsFADAtMQswCQYDVQQGEwJVUzEQ\n"
-        "MA4GA1UECgwHQW5kcm9pZDEMMAoGA1UEAwwDQWRiMB4XDTIwMDEyNDE4MzMwNVoX\n"
-        "DTMwMDEyMTE4MzMwNVowLTELMAkGA1UEBhMCVVMxEDAOBgNVBAoMB0FuZHJvaWQx\n"
-        "DDAKBgNVBAMMA0FkYjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKsi\n"
-        "Gv4JL7pQjTAJNpXNACJwoF7pfnfUt5AAZjHuPlEsdHVAignRYJzmayZcp7ZXNxa4\n"
-        "ttV1MYAg/UebBs+qVs7iKjF4mGIO/5Y+4sbz6PgjDVirG3xx+iHGN+82YhAzxoXm\n"
-        "EbLJppN60MURhY42hgIELhacVaBgI9vybNZeWEcTcXroacelzfbPJ09ODdm6sa9K\n"
-        "wV/t81j3JHDxa3A+IjqalHG36fZtBSn4tn6D/etcsU+Dy5YMZgbsi8uW5Zz2BH2X\n"
-        "GMvri3qvItTZybt5N8OAvD8HUX/ASAIkOdvLUmBDiurqSUk7cFHaihSv/tPfjfLm\n"
-        "eMbmFAmt5XvlmdKZEtkCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8B\n"
-        "Af8EBAMCAYYwHQYDVR0OBBYEFDtRSOm1ilhnq6bKN4qJ1ekK/PAkMA0GCSqGSIb3\n"
-        "DQEBCwUAA4IBAQAP6Q8/OxnBA3BO8oxKer0tjI4rZMefUhbAKUWXYjTTNEBm5//b\n"
-        "lVGP2RptO7bxj8w1L3rxsjmVcv2TqBOhrbJqvGVPE2ntoYlFhBBkRvmxuu1y5W9V\n"
-        "uJU7SF9lNmDXShTURULu3P8GdeT1HGeXzWQ4x7VhY9a3VIbmN5VxjB+3C6hYZxSs\n"
-        "DCpmidu/sR+n5Azlh6oqrhOxmv17PuF/ioTUsHd4y2Z41IvvO47oghxNDtboUUsg\n"
-        "LfsM1MOxVC9PqOfQphFU4i8owNIYzBMadDLw+1TSQj0ALqZVyc9Dq+WDFdz+JAE+\n"
-        "k7TkVU06UPGVSnLVzJeYwGCXQp3apBszY9vO\n"
-        "-----END CERTIFICATE-----\n";
-
-struct CAIssuerField {
-    int nid;
-    std::vector<uint8_t> val;
-};
-using CAIssuer = std::vector<CAIssuerField>;
-static std::vector<CAIssuer> kCAIssuers = {
-        {
-                {NID_commonName, {'a', 'b', 'c', 'd', 'e'}},
-                {NID_organizationName, {'d', 'e', 'f', 'g'}},
-        },
-        {
-                {NID_commonName, {'h', 'i', 'j', 'k', 'l', 'm'}},
-                {NID_countryName, {'n', 'o'}},
-        },
-};
-
-class AdbWifiTlsConnectionTest : public testing::Test {
-  protected:
-    virtual void SetUp() override {
-        android::base::Socketpair(SOCK_STREAM, &server_fd_, &client_fd_);
-        server_ = TlsConnection::Create(TlsConnection::Role::Server, kTestRsa2048ServerCert,
-                                        kTestRsa2048ServerPrivKey, server_fd_);
-        client_ = TlsConnection::Create(TlsConnection::Role::Client, kTestRsa2048ClientCert,
-                                        kTestRsa2048ClientPrivKey, client_fd_);
-        ASSERT_NE(nullptr, server_);
-        ASSERT_NE(nullptr, client_);
-    }
-
-    virtual void TearDown() override {
-        WaitForClientConnection();
-        // Shutdown the SSL connection first.
-        server_.reset();
-        client_.reset();
-    }
-
-    bssl::UniquePtr<STACK_OF(X509_NAME)> GetCAIssuerList() {
-        bssl::UniquePtr<STACK_OF(X509_NAME)> ret(sk_X509_NAME_new_null());
-        for (auto& issuer : kCAIssuers) {
-            bssl::UniquePtr<X509_NAME> name(X509_NAME_new());
-            for (auto& attr : issuer) {
-                CHECK(X509_NAME_add_entry_by_NID(name.get(), attr.nid, MBSTRING_ASC,
-                                                 attr.val.data(), attr.val.size(), -1, 0));
-            }
-
-            CHECK(bssl::PushToStack(ret.get(), std::move(name)));
-        }
-
-        return ret;
-    }
-
-    void StartClientHandshakeAsync(TlsError expected) {
-        client_thread_ = std::thread([=]() { EXPECT_EQ(client_->DoHandshake(), expected); });
-    }
-
-    void WaitForClientConnection() {
-        if (client_thread_.joinable()) {
-            client_thread_.join();
-        }
-    }
-
-    unique_fd server_fd_;
-    unique_fd client_fd_;
-    const std::vector<uint8_t> msg_{0xff, 0xab, 0x32, 0xf6, 0x12, 0x56};
-    std::unique_ptr<TlsConnection> server_;
-    std::unique_ptr<TlsConnection> client_;
-    std::thread client_thread_;
-};
-
-TEST_F(AdbWifiTlsConnectionTest, InvalidCreationParams) {
-    // Verify that passing empty certificate/private key results in a crash.
-    ASSERT_DEATH(
-            {
-                server_ = TlsConnection::Create(TlsConnection::Role::Server, "",
-                                                kTestRsa2048ServerPrivKey, server_fd_);
-            },
-            "");
-    ASSERT_DEATH(
-            {
-                server_ = TlsConnection::Create(TlsConnection::Role::Server, kTestRsa2048ServerCert,
-                                                "", server_fd_);
-            },
-            "");
-    ASSERT_DEATH(
-            {
-                client_ = TlsConnection::Create(TlsConnection::Role::Client, "",
-                                                kTestRsa2048ClientPrivKey, client_fd_);
-            },
-            "");
-    ASSERT_DEATH(
-            {
-                client_ = TlsConnection::Create(TlsConnection::Role::Client, kTestRsa2048ClientCert,
-                                                "", client_fd_);
-            },
-            "");
-}
-
-TEST_F(AdbWifiTlsConnectionTest, NoCertificateVerification) {
-    // Allow any certificate
-    server_->SetCertVerifyCallback([](X509_STORE_CTX*) { return 1; });
-    client_->SetCertVerifyCallback([](X509_STORE_CTX*) { return 1; });
-    StartClientHandshakeAsync(TlsError::Success);
-
-    // Handshake should succeed
-    ASSERT_EQ(server_->DoHandshake(), TlsError::Success);
-    WaitForClientConnection();
-
-    // Test client/server read and writes
-    client_thread_ = std::thread([&]() {
-        EXPECT_TRUE(client_->WriteFully(
-                std::string_view(reinterpret_cast<const char*>(msg_.data()), msg_.size())));
-        // Try with overloaded ReadFully
-        std::vector<uint8_t> buf(msg_.size());
-        ASSERT_TRUE(client_->ReadFully(buf.data(), msg_.size()));
-        EXPECT_EQ(buf, msg_);
-    });
-
-    auto data = server_->ReadFully(msg_.size());
-    EXPECT_EQ(data, msg_);
-    EXPECT_TRUE(server_->WriteFully(
-            std::string_view(reinterpret_cast<const char*>(msg_.data()), msg_.size())));
-
-    WaitForClientConnection();
-}
-
-TEST_F(AdbWifiTlsConnectionTest, NoTrustedCertificates) {
-    StartClientHandshakeAsync(TlsError::CertificateRejected);
-
-    // Handshake should not succeed
-    ASSERT_EQ(server_->DoHandshake(), TlsError::PeerRejectedCertificate);
-    WaitForClientConnection();
-
-    // All writes and reads should fail
-    client_thread_ = std::thread([&]() {
-        // Client write, server read should fail
-        EXPECT_FALSE(client_->WriteFully(
-                std::string_view(reinterpret_cast<const char*>(msg_.data()), msg_.size())));
-        auto data = client_->ReadFully(msg_.size());
-        EXPECT_EQ(data.size(), 0);
-    });
-
-    auto data = server_->ReadFully(msg_.size());
-    EXPECT_EQ(data.size(), 0);
-    EXPECT_FALSE(server_->WriteFully(
-            std::string_view(reinterpret_cast<const char*>(msg_.data()), msg_.size())));
-
-    WaitForClientConnection();
-}
-
-TEST_F(AdbWifiTlsConnectionTest, AddTrustedCertificates) {
-    // Add peer certificates
-    EXPECT_TRUE(client_->AddTrustedCertificate(kTestRsa2048ServerCert));
-    EXPECT_TRUE(server_->AddTrustedCertificate(kTestRsa2048ClientCert));
-
-    StartClientHandshakeAsync(TlsError::Success);
-
-    // Handshake should succeed
-    ASSERT_EQ(server_->DoHandshake(), TlsError::Success);
-    WaitForClientConnection();
-
-    // All read writes should succeed
-    client_thread_ = std::thread([&]() {
-        EXPECT_TRUE(client_->WriteFully(
-                std::string_view(reinterpret_cast<const char*>(msg_.data()), msg_.size())));
-        auto data = client_->ReadFully(msg_.size());
-        EXPECT_EQ(data, msg_);
-    });
-
-    auto data = server_->ReadFully(msg_.size());
-    EXPECT_EQ(data, msg_);
-    EXPECT_TRUE(server_->WriteFully(
-            std::string_view(reinterpret_cast<const char*>(msg_.data()), msg_.size())));
-
-    WaitForClientConnection();
-}
-
-TEST_F(AdbWifiTlsConnectionTest, AddTrustedCertificates_ClientWrongCert) {
-    // Server trusts a certificate, client has the wrong certificate
-    EXPECT_TRUE(server_->AddTrustedCertificate(kTestRsa2048UnknownCert));
-    // Client accepts any certificate
-    client_->SetCertVerifyCallback([](X509_STORE_CTX*) { return 1; });
-
-    // Without enabling EnableClientPostHandshakeCheck(), DoHandshake() will
-    // succeed, because in TLS 1.3, the client doesn't get notified if the
-    // server rejected the certificate until a read operation is called.
-    StartClientHandshakeAsync(TlsError::Success);
-
-    // Handshake should fail for server, succeed for client
-    ASSERT_EQ(server_->DoHandshake(), TlsError::CertificateRejected);
-    WaitForClientConnection();
-
-    // Client writes will succeed, everything else will fail.
-    client_thread_ = std::thread([&]() {
-        EXPECT_TRUE(client_->WriteFully(
-                std::string_view(reinterpret_cast<const char*>(msg_.data()), msg_.size())));
-        auto data = client_->ReadFully(msg_.size());
-        EXPECT_EQ(data.size(), 0);
-    });
-
-    auto data = server_->ReadFully(msg_.size());
-    EXPECT_EQ(data.size(), 0);
-    EXPECT_FALSE(server_->WriteFully(
-            std::string_view(reinterpret_cast<const char*>(msg_.data()), msg_.size())));
-
-    WaitForClientConnection();
-}
-
-TEST_F(AdbWifiTlsConnectionTest, ExportKeyingMaterial) {
-    // Allow any certificate
-    server_->SetCertVerifyCallback([](X509_STORE_CTX*) { return 1; });
-    client_->SetCertVerifyCallback([](X509_STORE_CTX*) { return 1; });
-
-    // Add peer certificates
-    EXPECT_TRUE(client_->AddTrustedCertificate(kTestRsa2048ServerCert));
-    EXPECT_TRUE(server_->AddTrustedCertificate(kTestRsa2048ClientCert));
-
-    StartClientHandshakeAsync(TlsError::Success);
-
-    // Handshake should succeed
-    ASSERT_EQ(server_->DoHandshake(), TlsError::Success);
-    WaitForClientConnection();
-
-    // Verify the client and server's exported key material match.
-    const size_t key_size = 64;
-    auto client_key_material = client_->ExportKeyingMaterial(key_size);
-    ASSERT_FALSE(client_key_material.empty());
-    auto server_key_material = server_->ExportKeyingMaterial(key_size);
-    ASSERT_TRUE(!server_key_material.empty());
-    ASSERT_EQ(client_key_material.size(), key_size);
-    ASSERT_EQ(client_key_material, server_key_material);
-}
-
-TEST_F(AdbWifiTlsConnectionTest, SetCertVerifyCallback_ClientAcceptsServerRejects) {
-    // Client accepts all
-    client_->SetCertVerifyCallback([](X509_STORE_CTX*) { return 1; });
-    // Server rejects all
-    server_->SetCertVerifyCallback([](X509_STORE_CTX*) { return 0; });
-    // Client handshake should succeed, because in TLS 1.3, client does not
-    // realize that the peer rejected the certificate until after a read
-    // operation.
-    StartClientHandshakeAsync(TlsError::Success);
-
-    // Server handshake should fail
-    ASSERT_EQ(server_->DoHandshake(), TlsError::CertificateRejected);
-    WaitForClientConnection();
-}
-
-TEST_F(AdbWifiTlsConnectionTest, SetCertVerifyCallback_ClientAcceptsServerRejects_PostHSCheck) {
-    // Client accepts all
-    client_->SetCertVerifyCallback([](X509_STORE_CTX*) { return 1; });
-    // Client should now get a failure in the handshake
-    client_->EnableClientPostHandshakeCheck(true);
-    // Server rejects all
-    server_->SetCertVerifyCallback([](X509_STORE_CTX*) { return 0; });
-
-    // Client handshake should fail because server rejects everything
-    StartClientHandshakeAsync(TlsError::PeerRejectedCertificate);
-
-    // Server handshake should fail
-    ASSERT_EQ(server_->DoHandshake(), TlsError::CertificateRejected);
-    WaitForClientConnection();
-}
-
-TEST_F(AdbWifiTlsConnectionTest, SetCertVerifyCallback_ClientRejectsServerAccepts) {
-    // Client rejects all
-    client_->SetCertVerifyCallback([](X509_STORE_CTX*) { return 0; });
-    // Server accepts all
-    server_->SetCertVerifyCallback([](X509_STORE_CTX*) { return 1; });
-    // Client handshake should fail
-    StartClientHandshakeAsync(TlsError::CertificateRejected);
-
-    // Server handshake should fail
-    ASSERT_EQ(server_->DoHandshake(), TlsError::PeerRejectedCertificate);
-    WaitForClientConnection();
-}
-
-TEST_F(AdbWifiTlsConnectionTest, SetCertVerifyCallback_ClientRejectsServerAccepts_PostHSCheck) {
-    // Client rejects all
-    client_->SetCertVerifyCallback([](X509_STORE_CTX*) { return 0; });
-    // This shouldn't affect the error types returned in the
-    // #SetCertVerifyCallback_ClientRejectsServerAccepts test, since
-    // the failure is still within the TLS 1.3 handshake.
-    client_->EnableClientPostHandshakeCheck(true);
-    // Server accepts all
-    server_->SetCertVerifyCallback([](X509_STORE_CTX*) { return 1; });
-
-    // Client handshake should fail
-    StartClientHandshakeAsync(TlsError::CertificateRejected);
-
-    // Server handshake should fail
-    ASSERT_EQ(server_->DoHandshake(), TlsError::PeerRejectedCertificate);
-    WaitForClientConnection();
-}
-
-TEST_F(AdbWifiTlsConnectionTest, EnableClientPostHandshakeCheck_ClientWrongCert) {
-    client_->AddTrustedCertificate(kTestRsa2048ServerCert);
-    // client's DoHandshake() will fail if the server rejected the certificate
-    client_->EnableClientPostHandshakeCheck(true);
-
-    // Add peer certificates
-    EXPECT_TRUE(server_->AddTrustedCertificate(kTestRsa2048UnknownCert));
-
-    // Handshake should fail for client
-    StartClientHandshakeAsync(TlsError::PeerRejectedCertificate);
-
-    // Handshake should fail for server
-    ASSERT_EQ(server_->DoHandshake(), TlsError::CertificateRejected);
-    WaitForClientConnection();
-
-    // All read writes should fail
-    client_thread_ = std::thread([&]() {
-        EXPECT_FALSE(client_->WriteFully(
-                std::string_view(reinterpret_cast<const char*>(msg_.data()), msg_.size())));
-        auto data = client_->ReadFully(msg_.size());
-        EXPECT_EQ(data.size(), 0);
-    });
-
-    auto data = server_->ReadFully(msg_.size());
-    EXPECT_EQ(data.size(), 0);
-    EXPECT_FALSE(server_->WriteFully(
-            std::string_view(reinterpret_cast<const char*>(msg_.data()), msg_.size())));
-
-    WaitForClientConnection();
-}
-
-TEST_F(AdbWifiTlsConnectionTest, SetClientCAList_Empty) {
-    // Setting an empty CA list should not crash
-    server_->SetClientCAList(nullptr);
-    ASSERT_DEATH(
-            {
-                // Client cannot use this API
-                client_->SetClientCAList(nullptr);
-            },
-            "");
-}
-
-TEST_F(AdbWifiTlsConnectionTest, SetClientCAList_Smoke) {
-    auto bsslIssuerList = GetCAIssuerList();
-    server_->SetClientCAList(bsslIssuerList.get());
-    client_->SetCertVerifyCallback([](X509_STORE_CTX*) { return 1; });
-
-    client_thread_ = std::thread([&]() {
-        client_->SetCertificateCallback([&](SSL* ssl) -> int {
-            const STACK_OF(X509_NAME)* received = SSL_get_client_CA_list(ssl);
-            EXPECT_NE(received, nullptr);
-            const size_t num_names = sk_X509_NAME_num(received);
-            EXPECT_EQ(kCAIssuers.size(), num_names);
-
-            // Client initially registered with the wrong key. Let's change it
-            // here to verify this callback actually changes the client
-            // certificate to the right one.
-            EXPECT_TRUE(TlsConnection::SetCertAndKey(ssl, kTestRsa2048UnknownCert,
-                                                     kTestRsa2048UnknownPrivKey));
-
-            const size_t buf_size = 256;
-            uint8_t buf[buf_size];
-            size_t idx = 0;
-            for (auto& issuer : kCAIssuers) {
-                auto* name = sk_X509_NAME_value(received, idx++);
-                for (auto& attr : issuer) {
-                    EXPECT_EQ(X509_NAME_get_text_by_NID(name, attr.nid,
-                                                        reinterpret_cast<char*>(buf), buf_size),
-                              attr.val.size());
-                    std::vector<uint8_t> out(buf, buf + attr.val.size());
-                    EXPECT_EQ(out, attr.val);
-                }
-            }
-
-            return 1;
-        });
-        // Client handshake should succeed
-        ASSERT_EQ(client_->DoHandshake(), TlsError::Success);
-    });
-
-    EXPECT_TRUE(server_->AddTrustedCertificate(kTestRsa2048UnknownCert));
-    // Server handshake should succeed
-    ASSERT_EQ(server_->DoHandshake(), TlsError::Success);
-    client_thread_.join();
-}
-
-TEST_F(AdbWifiTlsConnectionTest, SetClientCAList_AdbCAList) {
-    bssl::UniquePtr<STACK_OF(X509_NAME)> ca_list(sk_X509_NAME_new_null());
-    std::string keyhash = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
-    auto issuer = CreateCAIssuerFromEncodedKey(keyhash);
-    ASSERT_TRUE(bssl::PushToStack(ca_list.get(), std::move(issuer)));
-    server_->SetClientCAList(ca_list.get());
-    client_->SetCertVerifyCallback([](X509_STORE_CTX*) { return 1; });
-
-    client_thread_ = std::thread([&]() {
-        client_->SetCertificateCallback([&](SSL* ssl) -> int {
-            // Client initially registered with a certificate that is not trusted by
-            // the server. Let's test that we can change the certificate to the
-            // trusted one here.
-            const STACK_OF(X509_NAME)* received = SSL_get_client_CA_list(ssl);
-            EXPECT_NE(received, nullptr);
-            const size_t num_names = sk_X509_NAME_num(received);
-            EXPECT_EQ(1, num_names);
-
-            auto* name = sk_X509_NAME_value(received, 0);
-            EXPECT_NE(name, nullptr);
-            auto enc_key = ParseEncodedKeyFromCAIssuer(name);
-            EXPECT_EQ(keyhash, enc_key);
-
-            return 1;
-        });
-        // Client handshake should succeed
-        ASSERT_EQ(client_->DoHandshake(), TlsError::Success);
-    });
-
-    server_->SetCertVerifyCallback([](X509_STORE_CTX*) { return 1; });
-    // Server handshake should succeed
-    ASSERT_EQ(server_->DoHandshake(), TlsError::Success);
-    client_thread_.join();
-}
-}  // namespace tls
-}  // namespace adb
diff --git a/adb/tls/tls_connection.cpp b/adb/tls/tls_connection.cpp
deleted file mode 100644
index 853cdac..0000000
--- a/adb/tls/tls_connection.cpp
+++ /dev/null
@@ -1,394 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "adb/tls/tls_connection.h"
-
-#include <algorithm>
-#include <vector>
-
-#include <android-base/logging.h>
-#include <android-base/strings.h>
-#include <openssl/err.h>
-#include <openssl/ssl.h>
-
-using android::base::borrowed_fd;
-
-namespace adb {
-namespace tls {
-
-namespace {
-
-static constexpr char kExportedKeyLabel[] = "adb-label";
-
-class TlsConnectionImpl : public TlsConnection {
-  public:
-    explicit TlsConnectionImpl(Role role, std::string_view cert, std::string_view priv_key,
-                               borrowed_fd fd);
-    ~TlsConnectionImpl() override;
-
-    bool AddTrustedCertificate(std::string_view cert) override;
-    void SetCertVerifyCallback(CertVerifyCb cb) override;
-    void SetCertificateCallback(SetCertCb cb) override;
-    void SetClientCAList(STACK_OF(X509_NAME) * ca_list) override;
-    std::vector<uint8_t> ExportKeyingMaterial(size_t length) override;
-    void EnableClientPostHandshakeCheck(bool enable) override;
-    TlsError DoHandshake() override;
-    std::vector<uint8_t> ReadFully(size_t size) override;
-    bool ReadFully(void* buf, size_t size) override;
-    bool WriteFully(std::string_view data) override;
-
-    static bssl::UniquePtr<EVP_PKEY> EvpPkeyFromPEM(std::string_view pem);
-    static bssl::UniquePtr<CRYPTO_BUFFER> BufferFromPEM(std::string_view pem);
-
-  private:
-    static int SSLSetCertVerifyCb(X509_STORE_CTX* ctx, void* opaque);
-    static int SSLSetCertCb(SSL* ssl, void* opaque);
-
-    static bssl::UniquePtr<X509> X509FromBuffer(bssl::UniquePtr<CRYPTO_BUFFER> buffer);
-    static const char* SSLErrorString();
-    void Invalidate();
-    TlsError GetFailureReason(int err);
-    const char* RoleToString() { return role_ == Role::Server ? kServerRoleStr : kClientRoleStr; }
-
-    Role role_;
-    bssl::UniquePtr<EVP_PKEY> priv_key_;
-    bssl::UniquePtr<CRYPTO_BUFFER> cert_;
-
-    bssl::UniquePtr<STACK_OF(X509_NAME)> ca_list_;
-    bssl::UniquePtr<SSL_CTX> ssl_ctx_;
-    bssl::UniquePtr<SSL> ssl_;
-    std::vector<bssl::UniquePtr<X509>> known_certificates_;
-    bool client_verify_post_handshake_ = false;
-
-    CertVerifyCb cert_verify_cb_;
-    SetCertCb set_cert_cb_;
-    borrowed_fd fd_;
-    static constexpr char kClientRoleStr[] = "[client]: ";
-    static constexpr char kServerRoleStr[] = "[server]: ";
-};  // TlsConnectionImpl
-
-TlsConnectionImpl::TlsConnectionImpl(Role role, std::string_view cert, std::string_view priv_key,
-                                     borrowed_fd fd)
-    : role_(role), fd_(fd) {
-    CHECK(!cert.empty() && !priv_key.empty());
-    LOG(INFO) << RoleToString() << "Initializing adbwifi TlsConnection";
-    cert_ = BufferFromPEM(cert);
-    CHECK(cert_);
-    priv_key_ = EvpPkeyFromPEM(priv_key);
-    CHECK(priv_key_);
-}
-
-TlsConnectionImpl::~TlsConnectionImpl() {
-    // shutdown the SSL connection
-    if (ssl_ != nullptr) {
-        SSL_shutdown(ssl_.get());
-    }
-}
-
-// static
-const char* TlsConnectionImpl::SSLErrorString() {
-    auto sslerr = ERR_peek_last_error();
-    return ERR_reason_error_string(sslerr);
-}
-
-// static
-bssl::UniquePtr<EVP_PKEY> TlsConnectionImpl::EvpPkeyFromPEM(std::string_view pem) {
-    bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(pem.data(), pem.size()));
-    return bssl::UniquePtr<EVP_PKEY>(PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
-}
-
-// static
-bssl::UniquePtr<CRYPTO_BUFFER> TlsConnectionImpl::BufferFromPEM(std::string_view pem) {
-    bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(pem.data(), pem.size()));
-    char* name = nullptr;
-    char* header = nullptr;
-    uint8_t* data = nullptr;
-    long data_len = 0;
-
-    if (!PEM_read_bio(bio.get(), &name, &header, &data, &data_len)) {
-        LOG(ERROR) << "Failed to read certificate";
-        return nullptr;
-    }
-    OPENSSL_free(name);
-    OPENSSL_free(header);
-
-    auto ret = bssl::UniquePtr<CRYPTO_BUFFER>(CRYPTO_BUFFER_new(data, data_len, nullptr));
-    OPENSSL_free(data);
-    return ret;
-}
-
-// static
-bssl::UniquePtr<X509> TlsConnectionImpl::X509FromBuffer(bssl::UniquePtr<CRYPTO_BUFFER> buffer) {
-    if (!buffer) {
-        return nullptr;
-    }
-    return bssl::UniquePtr<X509>(X509_parse_from_buffer(buffer.get()));
-}
-
-// static
-int TlsConnectionImpl::SSLSetCertVerifyCb(X509_STORE_CTX* ctx, void* opaque) {
-    auto* p = reinterpret_cast<TlsConnectionImpl*>(opaque);
-    return p->cert_verify_cb_(ctx);
-}
-
-// static
-int TlsConnectionImpl::SSLSetCertCb(SSL* ssl, void* opaque) {
-    auto* p = reinterpret_cast<TlsConnectionImpl*>(opaque);
-    return p->set_cert_cb_(ssl);
-}
-
-bool TlsConnectionImpl::AddTrustedCertificate(std::string_view cert) {
-    // Create X509 buffer from the certificate string
-    auto buf = X509FromBuffer(BufferFromPEM(cert));
-    if (buf == nullptr) {
-        LOG(ERROR) << RoleToString() << "Failed to create a X509 buffer for the certificate.";
-        return false;
-    }
-    known_certificates_.push_back(std::move(buf));
-    return true;
-}
-
-void TlsConnectionImpl::SetCertVerifyCallback(CertVerifyCb cb) {
-    cert_verify_cb_ = cb;
-}
-
-void TlsConnectionImpl::SetCertificateCallback(SetCertCb cb) {
-    set_cert_cb_ = cb;
-}
-
-void TlsConnectionImpl::SetClientCAList(STACK_OF(X509_NAME) * ca_list) {
-    CHECK(role_ == Role::Server);
-    ca_list_.reset(ca_list != nullptr ? SSL_dup_CA_list(ca_list) : nullptr);
-}
-
-std::vector<uint8_t> TlsConnectionImpl::ExportKeyingMaterial(size_t length) {
-    if (ssl_.get() == nullptr) {
-        return {};
-    }
-
-    std::vector<uint8_t> out(length);
-    if (SSL_export_keying_material(ssl_.get(), out.data(), out.size(), kExportedKeyLabel,
-                                   sizeof(kExportedKeyLabel), nullptr, 0, false) == 0) {
-        return {};
-    }
-    return out;
-}
-
-void TlsConnectionImpl::EnableClientPostHandshakeCheck(bool enable) {
-    client_verify_post_handshake_ = enable;
-}
-
-TlsConnection::TlsError TlsConnectionImpl::GetFailureReason(int err) {
-    switch (ERR_GET_REASON(err)) {
-        case SSL_R_SSLV3_ALERT_BAD_CERTIFICATE:
-        case SSL_R_SSLV3_ALERT_UNSUPPORTED_CERTIFICATE:
-        case SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED:
-        case SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED:
-        case SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN:
-        case SSL_R_TLSV1_ALERT_ACCESS_DENIED:
-        case SSL_R_TLSV1_ALERT_UNKNOWN_CA:
-        case SSL_R_TLSV1_CERTIFICATE_REQUIRED:
-            return TlsError::PeerRejectedCertificate;
-        case SSL_R_CERTIFICATE_VERIFY_FAILED:
-            return TlsError::CertificateRejected;
-        default:
-            return TlsError::UnknownFailure;
-    }
-}
-
-TlsConnection::TlsError TlsConnectionImpl::DoHandshake() {
-    LOG(INFO) << RoleToString() << "Starting adbwifi tls handshake";
-    ssl_ctx_.reset(SSL_CTX_new(TLS_method()));
-    // TODO: Remove set_max_proto_version() once external/boringssl is updated
-    // past
-    // https://boringssl.googlesource.com/boringssl/+/58d56f4c59969a23e5f52014e2651c76fea2f877
-    if (ssl_ctx_.get() == nullptr ||
-        !SSL_CTX_set_min_proto_version(ssl_ctx_.get(), TLS1_3_VERSION) ||
-        !SSL_CTX_set_max_proto_version(ssl_ctx_.get(), TLS1_3_VERSION)) {
-        LOG(ERROR) << RoleToString() << "Failed to create SSL context";
-        return TlsError::UnknownFailure;
-    }
-
-    // Register user-supplied known certificates
-    for (auto const& cert : known_certificates_) {
-        if (X509_STORE_add_cert(SSL_CTX_get_cert_store(ssl_ctx_.get()), cert.get()) == 0) {
-            LOG(ERROR) << RoleToString() << "Unable to add certificates into the X509_STORE";
-            return TlsError::UnknownFailure;
-        }
-    }
-
-    // Custom certificate verification
-    if (cert_verify_cb_) {
-        SSL_CTX_set_cert_verify_callback(ssl_ctx_.get(), SSLSetCertVerifyCb, this);
-    }
-
-    // set select certificate callback, if any.
-    if (set_cert_cb_) {
-        SSL_CTX_set_cert_cb(ssl_ctx_.get(), SSLSetCertCb, this);
-    }
-
-    // Server-allowed client CA list
-    if (ca_list_ != nullptr) {
-        bssl::UniquePtr<STACK_OF(X509_NAME)> names(SSL_dup_CA_list(ca_list_.get()));
-        SSL_CTX_set_client_CA_list(ssl_ctx_.get(), names.release());
-    }
-
-    // Register our certificate and private key.
-    std::vector<CRYPTO_BUFFER*> cert_chain = {
-            cert_.get(),
-    };
-    if (!SSL_CTX_set_chain_and_key(ssl_ctx_.get(), cert_chain.data(), cert_chain.size(),
-                                   priv_key_.get(), nullptr)) {
-        LOG(ERROR) << RoleToString()
-                   << "Unable to register the certificate chain file and private key ["
-                   << SSLErrorString() << "]";
-        Invalidate();
-        return TlsError::UnknownFailure;
-    }
-
-    SSL_CTX_set_verify(ssl_ctx_.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
-
-    // Okay! Let's try to do the handshake!
-    ssl_.reset(SSL_new(ssl_ctx_.get()));
-    if (!SSL_set_fd(ssl_.get(), fd_.get())) {
-        LOG(ERROR) << RoleToString() << "SSL_set_fd failed. [" << SSLErrorString() << "]";
-        return TlsError::UnknownFailure;
-    }
-
-    switch (role_) {
-        case Role::Server:
-            SSL_set_accept_state(ssl_.get());
-            break;
-        case Role::Client:
-            SSL_set_connect_state(ssl_.get());
-            break;
-    }
-    if (SSL_do_handshake(ssl_.get()) != 1) {
-        LOG(ERROR) << RoleToString() << "Handshake failed in SSL_accept/SSL_connect ["
-                   << SSLErrorString() << "]";
-        auto sslerr = ERR_get_error();
-        Invalidate();
-        return GetFailureReason(sslerr);
-    }
-
-    if (client_verify_post_handshake_ && role_ == Role::Client) {
-        uint8_t check;
-        // Try to peek one byte for any failures. This assumes on success that
-        // the server actually sends something.
-        if (SSL_peek(ssl_.get(), &check, 1) <= 0) {
-            LOG(ERROR) << RoleToString() << "Post-handshake SSL_peek failed [" << SSLErrorString()
-                       << "]";
-            auto sslerr = ERR_get_error();
-            Invalidate();
-            return GetFailureReason(sslerr);
-        }
-    }
-
-    LOG(INFO) << RoleToString() << "Handshake succeeded.";
-    return TlsError::Success;
-}
-
-void TlsConnectionImpl::Invalidate() {
-    ssl_.reset();
-    ssl_ctx_.reset();
-}
-
-std::vector<uint8_t> TlsConnectionImpl::ReadFully(size_t size) {
-    std::vector<uint8_t> buf(size);
-    if (!ReadFully(buf.data(), buf.size())) {
-        return {};
-    }
-
-    return buf;
-}
-
-bool TlsConnectionImpl::ReadFully(void* buf, size_t size) {
-    CHECK_GT(size, 0U);
-    if (!ssl_) {
-        LOG(ERROR) << RoleToString() << "Tried to read on a null SSL connection";
-        return false;
-    }
-
-    size_t offset = 0;
-    uint8_t* p8 = reinterpret_cast<uint8_t*>(buf);
-    while (size > 0) {
-        int bytes_read =
-                SSL_read(ssl_.get(), p8 + offset, std::min(static_cast<size_t>(INT_MAX), size));
-        if (bytes_read <= 0) {
-            LOG(ERROR) << RoleToString() << "SSL_read failed [" << SSLErrorString() << "]";
-            return false;
-        }
-        size -= bytes_read;
-        offset += bytes_read;
-    }
-    return true;
-}
-
-bool TlsConnectionImpl::WriteFully(std::string_view data) {
-    CHECK(!data.empty());
-    if (!ssl_) {
-        LOG(ERROR) << RoleToString() << "Tried to read on a null SSL connection";
-        return false;
-    }
-
-    while (!data.empty()) {
-        int bytes_out = SSL_write(ssl_.get(), data.data(),
-                                  std::min(static_cast<size_t>(INT_MAX), data.size()));
-        if (bytes_out <= 0) {
-            LOG(ERROR) << RoleToString() << "SSL_write failed [" << SSLErrorString() << "]";
-            return false;
-        }
-        data = data.substr(bytes_out);
-    }
-    return true;
-}
-}  // namespace
-
-// static
-std::unique_ptr<TlsConnection> TlsConnection::Create(TlsConnection::Role role,
-                                                     std::string_view cert,
-                                                     std::string_view priv_key, borrowed_fd fd) {
-    CHECK(!cert.empty());
-    CHECK(!priv_key.empty());
-
-    return std::make_unique<TlsConnectionImpl>(role, cert, priv_key, fd);
-}
-
-// static
-bool TlsConnection::SetCertAndKey(SSL* ssl, std::string_view cert, std::string_view priv_key) {
-    CHECK(ssl);
-    // Note: declaring these in local scope is okay because
-    // SSL_set_chain_and_key will increase the refcount (bssl::UpRef).
-    auto x509_cert = TlsConnectionImpl::BufferFromPEM(cert);
-    auto evp_pkey = TlsConnectionImpl::EvpPkeyFromPEM(priv_key);
-    if (x509_cert == nullptr || evp_pkey == nullptr) {
-        return false;
-    }
-
-    std::vector<CRYPTO_BUFFER*> cert_chain = {
-            x509_cert.get(),
-    };
-    if (!SSL_set_chain_and_key(ssl, cert_chain.data(), cert_chain.size(), evp_pkey.get(),
-                               nullptr)) {
-        LOG(ERROR) << "SSL_set_chain_and_key failed";
-        return false;
-    }
-
-    return true;
-}
-
-}  // namespace tls
-}  // namespace adb
diff --git a/adb/tools/Android.bp b/adb/tools/Android.bp
deleted file mode 100644
index 71e32b7..0000000
--- a/adb/tools/Android.bp
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-cc_binary_host {
-    name: "check_ms_os_desc",
-
-    defaults: ["adb_defaults"],
-
-    srcs: [
-        "check_ms_os_desc.cpp",
-    ],
-
-    static_libs: [
-        "libbase",
-        "libusb",
-    ],
-
-    stl: "libc++_static",
-
-    dist: {
-        targets: [
-            "sdk",
-        ],
-    },
-}
diff --git a/adb/tools/check_ms_os_desc.cpp b/adb/tools/check_ms_os_desc.cpp
deleted file mode 100644
index 8e85809..0000000
--- a/adb/tools/check_ms_os_desc.cpp
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <err.h>
-#include <stdio.h>
-#include <unistd.h>
-
-#include <optional>
-#include <string>
-#include <vector>
-
-#include <libusb/libusb.h>
-
-static bool is_adb_device(libusb_device* device) {
-    libusb_device_descriptor device_desc;
-    libusb_get_device_descriptor(device, &device_desc);
-    if (device_desc.bDeviceClass != 0) {
-        return false;
-    }
-
-    libusb_config_descriptor* config_desc;
-    int rc = libusb_get_active_config_descriptor(device, &config_desc);
-    if (rc != 0) {
-        fprintf(stderr, "failed to get config descriptor for device %u:%u: %s\n",
-                libusb_get_bus_number(device), libusb_get_port_number(device),
-                libusb_error_name(rc));
-        return false;
-    }
-
-    for (size_t i = 0; i < config_desc->bNumInterfaces; ++i) {
-        const libusb_interface* interface = &config_desc->interface[i];
-        for (int j = 0; j < interface->num_altsetting; ++j) {
-            const libusb_interface_descriptor* interface_descriptor = &interface->altsetting[j];
-            if (interface_descriptor->bInterfaceClass == 0xff &&
-                interface_descriptor->bInterfaceSubClass == 0x42 &&
-                interface_descriptor->bInterfaceProtocol == 1) {
-                return true;
-            }
-        }
-    }
-
-    return false;
-}
-
-static std::optional<std::vector<uint8_t>> get_descriptor(libusb_device_handle* handle,
-                                                          uint8_t type, uint8_t index,
-                                                          uint16_t length) {
-    std::vector<uint8_t> result;
-    result.resize(length);
-    int rc = libusb_get_descriptor(handle, type, index, result.data(), result.size());
-    if (rc < 0) {
-        fprintf(stderr, "libusb_get_descriptor failed: %s\n", libusb_error_name(rc));
-        return std::nullopt;
-    }
-    result.resize(rc);
-    return result;
-}
-
-static std::optional<std::string> get_string_descriptor(libusb_device_handle* handle,
-                                                        uint8_t index) {
-    std::string result;
-    result.resize(4096);
-    int rc = libusb_get_string_descriptor_ascii(
-            handle, index, reinterpret_cast<uint8_t*>(result.data()), result.size());
-    if (rc < 0) {
-        fprintf(stderr, "libusb_get_string_descriptor_ascii failed: %s\n", libusb_error_name(rc));
-        return std::nullopt;
-    }
-    result.resize(rc);
-    return result;
-}
-
-static void check_ms_os_desc_v1(libusb_device_handle* device_handle, const std::string& serial) {
-    auto os_desc = get_descriptor(device_handle, 0x03, 0xEE, 0x12);
-    if (!os_desc) {
-        errx(1, "failed to retrieve MS OS descriptor");
-    }
-
-    if (os_desc->size() != 0x12) {
-        errx(1, "os descriptor size mismatch");
-    }
-
-    if (memcmp(os_desc->data() + 2, u"MSFT100\0", 14) != 0) {
-        errx(1, "os descriptor signature mismatch");
-    }
-
-    uint8_t vendor_code = (*os_desc)[16];
-    uint8_t pad = (*os_desc)[17];
-
-    if (pad != 0) {
-        errx(1, "os descriptor padding non-zero");
-    }
-
-    std::vector<uint8_t> data;
-    data.resize(0x10);
-    int rc = libusb_control_transfer(device_handle, 0xC0, vendor_code, 0x00, 0x04, data.data(),
-                                     data.size(), 0);
-    if (rc != 0x10) {
-        errx(1, "failed to retrieve MS OS v1 compat descriptor header: %s", libusb_error_name(rc));
-    }
-
-    struct __attribute__((packed)) ms_os_desc_v1_header {
-        uint32_t dwLength;
-        uint16_t bcdVersion;
-        uint16_t wIndex;
-        uint8_t bCount;
-        uint8_t reserved[7];
-    };
-    static_assert(sizeof(ms_os_desc_v1_header) == 0x10);
-
-    ms_os_desc_v1_header hdr;
-    memcpy(&hdr, data.data(), data.size());
-
-    data.resize(hdr.dwLength);
-    rc = libusb_control_transfer(device_handle, 0xC0, vendor_code, 0x00, 0x04, data.data(),
-                                 data.size(), 0);
-    if (static_cast<size_t>(rc) != data.size()) {
-        errx(1, "failed to retrieve MS OS v1 compat descriptor: %s", libusb_error_name(rc));
-    }
-
-    struct __attribute__((packed)) ms_os_desc_v1_function {
-        uint8_t bFirstInterfaceNumber;
-        uint8_t reserved1;
-        uint8_t compatibleID[8];
-        uint8_t subCompatibleID[8];
-        uint8_t reserved2[6];
-    };
-
-    if (sizeof(ms_os_desc_v1_header) + hdr.bCount * sizeof(ms_os_desc_v1_function) != data.size()) {
-        errx(1, "MS OS v1 compat descriptor size mismatch");
-    }
-
-    for (int i = 0; i < hdr.bCount; ++i) {
-        ms_os_desc_v1_function function;
-        memcpy(&function,
-               data.data() + sizeof(ms_os_desc_v1_header) + i * sizeof(ms_os_desc_v1_function),
-               sizeof(function));
-        if (memcmp("WINUSB\0\0", function.compatibleID, 8) == 0) {
-            return;
-        }
-    }
-
-    errx(1, "failed to find v1 MS OS descriptor specifying WinUSB for device %s", serial.c_str());
-}
-
-static void check_ms_os_desc_v2(libusb_device_handle* device_handle, const std::string& serial) {
-    libusb_bos_descriptor* bos;
-    int rc = libusb_get_bos_descriptor(device_handle, &bos);
-
-    if (rc != 0) {
-        fprintf(stderr, "failed to get bos descriptor for device %s\n", serial.c_str());
-        return;
-    }
-
-    for (size_t i = 0; i < bos->bNumDeviceCaps; ++i) {
-        libusb_bos_dev_capability_descriptor* desc = bos->dev_capability[i];
-        if (desc->bDescriptorType != LIBUSB_DT_DEVICE_CAPABILITY) {
-            errx(1, "invalid BOS descriptor type: %d", desc->bDescriptorType);
-        }
-
-        if (desc->bDevCapabilityType != 0x05 /* PLATFORM */) {
-            fprintf(stderr, "skipping non-platform dev capability: %#02x\n",
-                    desc->bDevCapabilityType);
-            continue;
-        }
-
-        if (desc->bLength < sizeof(*desc) + 16) {
-            errx(1, "received device capability descriptor not long enough to contain a UUID?");
-        }
-
-        char uuid[16];
-        memcpy(uuid, desc->dev_capability_data, 16);
-
-        constexpr uint8_t ms_os_uuid[16] = {0xD8, 0xDD, 0x60, 0xDF, 0x45, 0x89, 0x4C, 0xC7,
-                                            0x9C, 0xD2, 0x65, 0x9D, 0x9E, 0x64, 0x8A, 0x9F};
-        if (memcmp(uuid, ms_os_uuid, 16) != 0) {
-            fprintf(stderr, "skipping unknown UUID\n");
-            continue;
-        }
-
-        size_t data_length = desc->bLength - sizeof(*desc) - 16;
-        fprintf(stderr, "found MS OS 2.0 descriptor, length = %zu\n", data_length);
-
-        // Linux does not appear to support MS OS 2.0 Descriptors.
-        // TODO: If and when it does, verify that we're emitting them properly.
-    }
-}
-
-int main(int argc, char** argv) {
-    libusb_context* ctx;
-    if (libusb_init(&ctx) != 0) {
-        errx(1, "failed to initialize libusb context");
-    }
-
-    libusb_device** device_list = nullptr;
-    ssize_t device_count = libusb_get_device_list(ctx, &device_list);
-    if (device_count < 0) {
-        errx(1, "libusb_get_device_list failed");
-    }
-
-    const char* expected_serial = getenv("ANDROID_SERIAL");
-    bool found = false;
-
-    for (ssize_t i = 0; i < device_count; ++i) {
-        libusb_device* device = device_list[i];
-        if (!is_adb_device(device)) {
-            continue;
-        }
-
-        libusb_device_handle* device_handle = nullptr;
-        int rc = libusb_open(device, &device_handle);
-        if (rc != 0) {
-            fprintf(stderr, "failed to open device %u:%u: %s\n", libusb_get_bus_number(device),
-                    libusb_get_port_number(device), libusb_error_name(rc));
-            continue;
-        }
-
-        libusb_device_descriptor device_desc;
-        libusb_get_device_descriptor(device, &device_desc);
-
-        std::optional<std::string> serial =
-                get_string_descriptor(device_handle, device_desc.iSerialNumber);
-        if (!serial) {
-            errx(1, "failed to get serial for device %u:%u", libusb_get_bus_number(device),
-                 libusb_get_port_number(device));
-        }
-
-        if (expected_serial && *serial != expected_serial) {
-            fprintf(stderr, "skipping %s (wanted %s)\n", serial->c_str(), expected_serial);
-            continue;
-        }
-
-        // Check for MS OS Descriptor v1.
-        // https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpeusb/c2f351f9-84d2-4a1b-9fe3-a6ca195f84d0
-        fprintf(stderr, "fetching v1 OS descriptor from device %s\n", serial->c_str());
-        check_ms_os_desc_v1(device_handle, *serial);
-        fprintf(stderr, "found v1 OS descriptor for device %s\n", serial->c_str());
-
-        // Read BOS for MS OS Descriptor 2.0 descriptors:
-        // http://download.microsoft.com/download/3/5/6/3563ED4A-F318-4B66-A181-AB1D8F6FD42D/MS_OS_2_0_desc.docx
-        fprintf(stderr, "fetching v2 OS descriptor from device %s\n", serial->c_str());
-        check_ms_os_desc_v2(device_handle, *serial);
-
-        found = true;
-    }
-
-    if (expected_serial && !found) {
-        errx(1, "failed to find device with serial %s", expected_serial);
-    }
-    return 0;
-}
diff --git a/adb/trace.sh b/adb/trace.sh
deleted file mode 100755
index 49e5026..0000000
--- a/adb/trace.sh
+++ /dev/null
@@ -1,17 +0,0 @@
-set -e
-
-if ! [ -e $ANDROID_BUILD_TOP/external/chromium-trace/systrace.py ]; then
-    echo "error: can't find systrace.py at \$ANDROID_BUILD_TOP/external/chromium-trace/systrace.py"
-    exit 1
-fi
-
-adb shell "sleep 1; atrace -b 65536 --async_start adb sched power freq idle disk mmc load"
-adb shell killall adbd
-adb wait-for-device
-echo "press enter to finish..."
-read
-TRACE_TEMP=`mktemp /tmp/trace.XXXXXX`
-echo Saving trace to ${TRACE_TEMP}, html file to ${TRACE_TEMP}.html
-adb shell atrace --async_stop -z > ${TRACE_TEMP}
-$ANDROID_BUILD_TOP/external/chromium-trace/systrace.py --from-file=${TRACE_TEMP} -o ${TRACE_TEMP}.html
-chrome ${TRACE_TEMP}.html
diff --git a/adb/transport.cpp b/adb/transport.cpp
deleted file mode 100644
index fe286de..0000000
--- a/adb/transport.cpp
+++ /dev/null
@@ -1,1534 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define TRACE_TAG TRANSPORT
-
-#include "sysdeps.h"
-
-#include "transport.h"
-
-#include <ctype.h>
-#include <errno.h>
-#include <inttypes.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <algorithm>
-#include <deque>
-#include <list>
-#include <memory>
-#include <mutex>
-#include <set>
-#include <thread>
-
-#include <adb/crypto/rsa_2048_key.h>
-#include <adb/crypto/x509_generator.h>
-#include <adb/tls/tls_connection.h>
-#include <android-base/logging.h>
-#include <android-base/parsenetaddress.h>
-#include <android-base/stringprintf.h>
-#include <android-base/strings.h>
-#include <android-base/thread_annotations.h>
-
-#include <diagnose_usb.h>
-
-#include "adb.h"
-#include "adb_auth.h"
-#include "adb_io.h"
-#include "adb_trace.h"
-#include "adb_utils.h"
-#include "fdevent/fdevent.h"
-#include "sysdeps/chrono.h"
-
-using namespace adb::crypto;
-using namespace adb::tls;
-using android::base::ScopedLockAssertion;
-using TlsError = TlsConnection::TlsError;
-
-static void remove_transport(atransport* transport);
-static void transport_destroy(atransport* transport);
-
-// TODO: unordered_map<TransportId, atransport*>
-static auto& transport_list = *new std::list<atransport*>();
-static auto& pending_list = *new std::list<atransport*>();
-
-static auto& transport_lock = *new std::recursive_mutex();
-
-const char* const kFeatureShell2 = "shell_v2";
-const char* const kFeatureCmd = "cmd";
-const char* const kFeatureStat2 = "stat_v2";
-const char* const kFeatureLs2 = "ls_v2";
-const char* const kFeatureLibusb = "libusb";
-const char* const kFeaturePushSync = "push_sync";
-const char* const kFeatureApex = "apex";
-const char* const kFeatureFixedPushMkdir = "fixed_push_mkdir";
-const char* const kFeatureAbb = "abb";
-const char* const kFeatureFixedPushSymlinkTimestamp = "fixed_push_symlink_timestamp";
-const char* const kFeatureAbbExec = "abb_exec";
-const char* const kFeatureRemountShell = "remount_shell";
-const char* const kFeatureSendRecv2 = "sendrecv_v2";
-const char* const kFeatureSendRecv2Brotli = "sendrecv_v2_brotli";
-
-namespace {
-
-#if ADB_HOST
-// Tracks and handles atransport*s that are attempting reconnection.
-class ReconnectHandler {
-  public:
-    ReconnectHandler() = default;
-    ~ReconnectHandler() = default;
-
-    // Starts the ReconnectHandler thread.
-    void Start();
-
-    // Requests the ReconnectHandler thread to stop.
-    void Stop();
-
-    // Adds the atransport* to the queue of reconnect attempts.
-    void TrackTransport(atransport* transport);
-
-    // Wake up the ReconnectHandler thread to have it check for kicked transports.
-    void CheckForKicked();
-
-  private:
-    // The main thread loop.
-    void Run();
-
-    // Tracks a reconnection attempt.
-    struct ReconnectAttempt {
-        atransport* transport;
-        std::chrono::steady_clock::time_point reconnect_time;
-        size_t attempts_left;
-
-        bool operator<(const ReconnectAttempt& rhs) const {
-            if (reconnect_time == rhs.reconnect_time) {
-                return reinterpret_cast<uintptr_t>(transport) <
-                       reinterpret_cast<uintptr_t>(rhs.transport);
-            }
-            return reconnect_time < rhs.reconnect_time;
-        }
-    };
-
-    // Only retry for up to one minute.
-    static constexpr const std::chrono::seconds kDefaultTimeout = 10s;
-    static constexpr const size_t kMaxAttempts = 6;
-
-    // Protects all members.
-    std::mutex reconnect_mutex_;
-    bool running_ GUARDED_BY(reconnect_mutex_) = true;
-    std::thread handler_thread_;
-    std::condition_variable reconnect_cv_;
-    std::set<ReconnectAttempt> reconnect_queue_ GUARDED_BY(reconnect_mutex_);
-
-    DISALLOW_COPY_AND_ASSIGN(ReconnectHandler);
-};
-
-void ReconnectHandler::Start() {
-    check_main_thread();
-    handler_thread_ = std::thread(&ReconnectHandler::Run, this);
-}
-
-void ReconnectHandler::Stop() {
-    check_main_thread();
-    {
-        std::lock_guard<std::mutex> lock(reconnect_mutex_);
-        running_ = false;
-    }
-    reconnect_cv_.notify_one();
-    handler_thread_.join();
-
-    // Drain the queue to free all resources.
-    std::lock_guard<std::mutex> lock(reconnect_mutex_);
-    while (!reconnect_queue_.empty()) {
-        ReconnectAttempt attempt = *reconnect_queue_.begin();
-        reconnect_queue_.erase(reconnect_queue_.begin());
-        remove_transport(attempt.transport);
-    }
-}
-
-void ReconnectHandler::TrackTransport(atransport* transport) {
-    check_main_thread();
-    {
-        std::lock_guard<std::mutex> lock(reconnect_mutex_);
-        if (!running_) return;
-        // Arbitrary sleep to give adbd time to get ready, if we disconnected because it exited.
-        auto reconnect_time = std::chrono::steady_clock::now() + 250ms;
-        reconnect_queue_.emplace(
-                ReconnectAttempt{transport, reconnect_time, ReconnectHandler::kMaxAttempts});
-    }
-    reconnect_cv_.notify_one();
-}
-
-void ReconnectHandler::CheckForKicked() {
-    reconnect_cv_.notify_one();
-}
-
-void ReconnectHandler::Run() {
-    while (true) {
-        ReconnectAttempt attempt;
-        {
-            std::unique_lock<std::mutex> lock(reconnect_mutex_);
-            ScopedLockAssertion assume_lock(reconnect_mutex_);
-
-            if (!reconnect_queue_.empty()) {
-                // FIXME: libstdc++ (used on Windows) implements condition_variable with
-                //        system_clock as its clock, so we're probably hosed if the clock changes,
-                //        even if we use steady_clock throughout. This problem goes away once we
-                //        switch to libc++.
-                reconnect_cv_.wait_until(lock, reconnect_queue_.begin()->reconnect_time);
-            } else {
-                reconnect_cv_.wait(lock);
-            }
-
-            if (!running_) return;
-
-            // Scan the whole list for kicked transports, so that we immediately handle an explicit
-            // disconnect request.
-            bool kicked = false;
-            for (auto it = reconnect_queue_.begin(); it != reconnect_queue_.end();) {
-                if (it->transport->kicked()) {
-                    D("transport %s was kicked. giving up on it.", it->transport->serial.c_str());
-                    remove_transport(it->transport);
-                    it = reconnect_queue_.erase(it);
-                } else {
-                    ++it;
-                }
-                kicked = true;
-            }
-
-            if (reconnect_queue_.empty()) continue;
-
-            // Go back to sleep if we either woke up spuriously, or we were woken up to remove
-            // a kicked transport, and the first transport isn't ready for reconnection yet.
-            auto now = std::chrono::steady_clock::now();
-            if (reconnect_queue_.begin()->reconnect_time > now) {
-                continue;
-            }
-
-            attempt = *reconnect_queue_.begin();
-            reconnect_queue_.erase(reconnect_queue_.begin());
-        }
-        D("attempting to reconnect %s", attempt.transport->serial.c_str());
-
-        switch (attempt.transport->Reconnect()) {
-            case ReconnectResult::Retry: {
-                D("attempting to reconnect %s failed.", attempt.transport->serial.c_str());
-                if (attempt.attempts_left == 0) {
-                    D("transport %s exceeded the number of retry attempts. giving up on it.",
-                      attempt.transport->serial.c_str());
-                    remove_transport(attempt.transport);
-                    continue;
-                }
-
-                std::lock_guard<std::mutex> lock(reconnect_mutex_);
-                reconnect_queue_.emplace(ReconnectAttempt{
-                        attempt.transport,
-                        std::chrono::steady_clock::now() + ReconnectHandler::kDefaultTimeout,
-                        attempt.attempts_left - 1});
-                continue;
-            }
-
-            case ReconnectResult::Success:
-                D("reconnection to %s succeeded.", attempt.transport->serial.c_str());
-                register_transport(attempt.transport);
-                continue;
-
-            case ReconnectResult::Abort:
-                D("cancelling reconnection attempt to %s.", attempt.transport->serial.c_str());
-                remove_transport(attempt.transport);
-                continue;
-        }
-    }
-}
-
-static auto& reconnect_handler = *new ReconnectHandler();
-
-#endif
-
-}  // namespace
-
-TransportId NextTransportId() {
-    static std::atomic<TransportId> next(1);
-    return next++;
-}
-
-void Connection::Reset() {
-    LOG(INFO) << "Connection::Reset(): stopping";
-    Stop();
-}
-
-BlockingConnectionAdapter::BlockingConnectionAdapter(std::unique_ptr<BlockingConnection> connection)
-    : underlying_(std::move(connection)) {}
-
-BlockingConnectionAdapter::~BlockingConnectionAdapter() {
-    LOG(INFO) << "BlockingConnectionAdapter(" << this->transport_name_ << "): destructing";
-    Stop();
-}
-
-void BlockingConnectionAdapter::Start() {
-    std::lock_guard<std::mutex> lock(mutex_);
-    if (started_) {
-        LOG(FATAL) << "BlockingConnectionAdapter(" << this->transport_name_
-                   << "): started multiple times";
-    }
-
-    StartReadThread();
-
-    write_thread_ = std::thread([this]() {
-        LOG(INFO) << this->transport_name_ << ": write thread spawning";
-        while (true) {
-            std::unique_lock<std::mutex> lock(mutex_);
-            ScopedLockAssertion assume_locked(mutex_);
-            cv_.wait(lock, [this]() REQUIRES(mutex_) {
-                return this->stopped_ || !this->write_queue_.empty();
-            });
-
-            if (this->stopped_) {
-                return;
-            }
-
-            std::unique_ptr<apacket> packet = std::move(this->write_queue_.front());
-            this->write_queue_.pop_front();
-            lock.unlock();
-
-            if (!this->underlying_->Write(packet.get())) {
-                break;
-            }
-        }
-        std::call_once(this->error_flag_, [this]() { this->error_callback_(this, "write failed"); });
-    });
-
-    started_ = true;
-}
-
-void BlockingConnectionAdapter::StartReadThread() {
-    read_thread_ = std::thread([this]() {
-        LOG(INFO) << this->transport_name_ << ": read thread spawning";
-        while (true) {
-            auto packet = std::make_unique<apacket>();
-            if (!underlying_->Read(packet.get())) {
-                PLOG(INFO) << this->transport_name_ << ": read failed";
-                break;
-            }
-
-            bool got_stls_cmd = false;
-            if (packet->msg.command == A_STLS) {
-                got_stls_cmd = true;
-            }
-
-            read_callback_(this, std::move(packet));
-
-            // If we received the STLS packet, we are about to perform the TLS
-            // handshake. So this read thread must stop and resume after the
-            // handshake completes otherwise this will interfere in the process.
-            if (got_stls_cmd) {
-                LOG(INFO) << this->transport_name_
-                          << ": Received STLS packet. Stopping read thread.";
-                return;
-            }
-        }
-        std::call_once(this->error_flag_, [this]() { this->error_callback_(this, "read failed"); });
-    });
-}
-
-bool BlockingConnectionAdapter::DoTlsHandshake(RSA* key, std::string* auth_key) {
-    std::lock_guard<std::mutex> lock(mutex_);
-    if (read_thread_.joinable()) {
-        read_thread_.join();
-    }
-    bool success = this->underlying_->DoTlsHandshake(key, auth_key);
-    StartReadThread();
-    return success;
-}
-
-void BlockingConnectionAdapter::Reset() {
-    {
-        std::lock_guard<std::mutex> lock(mutex_);
-        if (!started_) {
-            LOG(INFO) << "BlockingConnectionAdapter(" << this->transport_name_ << "): not started";
-            return;
-        }
-
-        if (stopped_) {
-            LOG(INFO) << "BlockingConnectionAdapter(" << this->transport_name_
-                      << "): already stopped";
-            return;
-        }
-    }
-
-    LOG(INFO) << "BlockingConnectionAdapter(" << this->transport_name_ << "): resetting";
-    this->underlying_->Reset();
-    Stop();
-}
-
-void BlockingConnectionAdapter::Stop() {
-    {
-        std::lock_guard<std::mutex> lock(mutex_);
-        if (!started_) {
-            LOG(INFO) << "BlockingConnectionAdapter(" << this->transport_name_ << "): not started";
-            return;
-        }
-
-        if (stopped_) {
-            LOG(INFO) << "BlockingConnectionAdapter(" << this->transport_name_
-                      << "): already stopped";
-            return;
-        }
-
-        stopped_ = true;
-    }
-
-    LOG(INFO) << "BlockingConnectionAdapter(" << this->transport_name_ << "): stopping";
-
-    this->underlying_->Close();
-    this->cv_.notify_one();
-
-    // Move the threads out into locals with the lock taken, and then unlock to let them exit.
-    std::thread read_thread;
-    std::thread write_thread;
-
-    {
-        std::lock_guard<std::mutex> lock(mutex_);
-        read_thread = std::move(read_thread_);
-        write_thread = std::move(write_thread_);
-    }
-
-    read_thread.join();
-    write_thread.join();
-
-    LOG(INFO) << "BlockingConnectionAdapter(" << this->transport_name_ << "): stopped";
-    std::call_once(this->error_flag_, [this]() { this->error_callback_(this, "requested stop"); });
-}
-
-bool BlockingConnectionAdapter::Write(std::unique_ptr<apacket> packet) {
-    {
-        std::lock_guard<std::mutex> lock(this->mutex_);
-        write_queue_.emplace_back(std::move(packet));
-    }
-
-    cv_.notify_one();
-    return true;
-}
-
-FdConnection::FdConnection(unique_fd fd) : fd_(std::move(fd)) {}
-
-FdConnection::~FdConnection() {}
-
-bool FdConnection::DispatchRead(void* buf, size_t len) {
-    if (tls_ != nullptr) {
-        // The TlsConnection doesn't allow 0 byte reads
-        if (len == 0) {
-            return true;
-        }
-        return tls_->ReadFully(buf, len);
-    }
-
-    return ReadFdExactly(fd_.get(), buf, len);
-}
-
-bool FdConnection::DispatchWrite(void* buf, size_t len) {
-    if (tls_ != nullptr) {
-        // The TlsConnection doesn't allow 0 byte writes
-        if (len == 0) {
-            return true;
-        }
-        return tls_->WriteFully(std::string_view(reinterpret_cast<const char*>(buf), len));
-    }
-
-    return WriteFdExactly(fd_.get(), buf, len);
-}
-
-bool FdConnection::Read(apacket* packet) {
-    if (!DispatchRead(&packet->msg, sizeof(amessage))) {
-        D("remote local: read terminated (message)");
-        return false;
-    }
-
-    if (packet->msg.data_length > MAX_PAYLOAD) {
-        D("remote local: read overflow (data length = %" PRIu32 ")", packet->msg.data_length);
-        return false;
-    }
-
-    packet->payload.resize(packet->msg.data_length);
-
-    if (!DispatchRead(&packet->payload[0], packet->payload.size())) {
-        D("remote local: terminated (data)");
-        return false;
-    }
-
-    return true;
-}
-
-bool FdConnection::Write(apacket* packet) {
-    if (!DispatchWrite(&packet->msg, sizeof(packet->msg))) {
-        D("remote local: write terminated");
-        return false;
-    }
-
-    if (packet->msg.data_length) {
-        if (!DispatchWrite(&packet->payload[0], packet->msg.data_length)) {
-            D("remote local: write terminated");
-            return false;
-        }
-    }
-
-    return true;
-}
-
-bool FdConnection::DoTlsHandshake(RSA* key, std::string* auth_key) {
-    bssl::UniquePtr<EVP_PKEY> evp_pkey(EVP_PKEY_new());
-    if (!EVP_PKEY_set1_RSA(evp_pkey.get(), key)) {
-        LOG(ERROR) << "EVP_PKEY_set1_RSA failed";
-        return false;
-    }
-    auto x509 = GenerateX509Certificate(evp_pkey.get());
-    auto x509_str = X509ToPEMString(x509.get());
-    auto evp_str = Key::ToPEMString(evp_pkey.get());
-#ifdef _WIN32
-    int osh = cast_handle_to_int(adb_get_os_handle(fd_));
-#else
-    int osh = adb_get_os_handle(fd_);
-#endif
-
-#if ADB_HOST
-    tls_ = TlsConnection::Create(TlsConnection::Role::Client, x509_str, evp_str, osh);
-#else
-    tls_ = TlsConnection::Create(TlsConnection::Role::Server, x509_str, evp_str, osh);
-#endif
-    CHECK(tls_);
-#if ADB_HOST
-    // TLS 1.3 gives the client no message if the server rejected the
-    // certificate. This will enable a check in the tls connection to check
-    // whether the client certificate got rejected. Note that this assumes
-    // that, on handshake success, the server speaks first.
-    tls_->EnableClientPostHandshakeCheck(true);
-    // Add callback to set the certificate when server issues the
-    // CertificateRequest.
-    tls_->SetCertificateCallback(adb_tls_set_certificate);
-    // Allow any server certificate
-    tls_->SetCertVerifyCallback([](X509_STORE_CTX*) { return 1; });
-#else
-    // Add callback to check certificate against a list of known public keys
-    tls_->SetCertVerifyCallback(
-            [auth_key](X509_STORE_CTX* ctx) { return adbd_tls_verify_cert(ctx, auth_key); });
-    // Add the list of allowed client CA issuers
-    auto ca_list = adbd_tls_client_ca_list();
-    tls_->SetClientCAList(ca_list.get());
-#endif
-
-    auto err = tls_->DoHandshake();
-    if (err == TlsError::Success) {
-        return true;
-    }
-
-    tls_.reset();
-    return false;
-}
-
-void FdConnection::Close() {
-    adb_shutdown(fd_.get());
-    fd_.reset();
-}
-
-void send_packet(apacket* p, atransport* t) {
-    p->msg.magic = p->msg.command ^ 0xffffffff;
-    // compute a checksum for connection/auth packets for compatibility reasons
-    if (t->get_protocol_version() >= A_VERSION_SKIP_CHECKSUM) {
-        p->msg.data_check = 0;
-    } else {
-        p->msg.data_check = calculate_apacket_checksum(p);
-    }
-
-    VLOG(TRANSPORT) << dump_packet(t->serial.c_str(), "to remote", p);
-
-    if (t == nullptr) {
-        LOG(FATAL) << "Transport is null";
-    }
-
-    if (t->Write(p) != 0) {
-        D("%s: failed to enqueue packet, closing transport", t->serial.c_str());
-        t->Kick();
-    }
-}
-
-void kick_transport(atransport* t, bool reset) {
-    std::lock_guard<std::recursive_mutex> lock(transport_lock);
-    // As kick_transport() can be called from threads without guarantee that t is valid,
-    // check if the transport is in transport_list first.
-    //
-    // TODO(jmgao): WTF? Is this actually true?
-    if (std::find(transport_list.begin(), transport_list.end(), t) != transport_list.end()) {
-        if (reset) {
-            t->Reset();
-        } else {
-            t->Kick();
-        }
-    }
-
-#if ADB_HOST
-    reconnect_handler.CheckForKicked();
-#endif
-}
-
-static int transport_registration_send = -1;
-static int transport_registration_recv = -1;
-static fdevent* transport_registration_fde;
-
-#if ADB_HOST
-
-/* this adds support required by the 'track-devices' service.
- * this is used to send the content of "list_transport" to any
- * number of client connections that want it through a single
- * live TCP connection
- */
-struct device_tracker {
-    asocket socket;
-    bool update_needed = false;
-    bool long_output = false;
-    device_tracker* next = nullptr;
-};
-
-/* linked list of all device trackers */
-static device_tracker* device_tracker_list;
-
-static void device_tracker_remove(device_tracker* tracker) {
-    device_tracker** pnode = &device_tracker_list;
-    device_tracker* node = *pnode;
-
-    std::lock_guard<std::recursive_mutex> lock(transport_lock);
-    while (node) {
-        if (node == tracker) {
-            *pnode = node->next;
-            break;
-        }
-        pnode = &node->next;
-        node = *pnode;
-    }
-}
-
-static void device_tracker_close(asocket* socket) {
-    device_tracker* tracker = (device_tracker*)socket;
-    asocket* peer = socket->peer;
-
-    D("device tracker %p removed", tracker);
-    if (peer) {
-        peer->peer = nullptr;
-        peer->close(peer);
-    }
-    device_tracker_remove(tracker);
-    delete tracker;
-}
-
-static int device_tracker_enqueue(asocket* socket, apacket::payload_type) {
-    /* you can't read from a device tracker, close immediately */
-    device_tracker_close(socket);
-    return -1;
-}
-
-static int device_tracker_send(device_tracker* tracker, const std::string& string) {
-    asocket* peer = tracker->socket.peer;
-
-    apacket::payload_type data;
-    data.resize(4 + string.size());
-    char buf[5];
-    snprintf(buf, sizeof(buf), "%04x", static_cast<int>(string.size()));
-    memcpy(&data[0], buf, 4);
-    memcpy(&data[4], string.data(), string.size());
-    return peer->enqueue(peer, std::move(data));
-}
-
-static void device_tracker_ready(asocket* socket) {
-    device_tracker* tracker = reinterpret_cast<device_tracker*>(socket);
-
-    // We want to send the device list when the tracker connects
-    // for the first time, even if no update occurred.
-    if (tracker->update_needed) {
-        tracker->update_needed = false;
-        device_tracker_send(tracker, list_transports(tracker->long_output));
-    }
-}
-
-asocket* create_device_tracker(bool long_output) {
-    device_tracker* tracker = new device_tracker();
-    if (tracker == nullptr) LOG(FATAL) << "cannot allocate device tracker";
-
-    D("device tracker %p created", tracker);
-
-    tracker->socket.enqueue = device_tracker_enqueue;
-    tracker->socket.ready = device_tracker_ready;
-    tracker->socket.close = device_tracker_close;
-    tracker->update_needed = true;
-    tracker->long_output = long_output;
-
-    tracker->next = device_tracker_list;
-    device_tracker_list = tracker;
-
-    return &tracker->socket;
-}
-
-// Check if all of the USB transports are connected.
-bool iterate_transports(std::function<bool(const atransport*)> fn) {
-    std::lock_guard<std::recursive_mutex> lock(transport_lock);
-    for (const auto& t : transport_list) {
-        if (!fn(t)) {
-            return false;
-        }
-    }
-    for (const auto& t : pending_list) {
-        if (!fn(t)) {
-            return false;
-        }
-    }
-    return true;
-}
-
-// Call this function each time the transport list has changed.
-void update_transports() {
-    update_transport_status();
-
-    // Notify `adb track-devices` clients.
-    device_tracker* tracker = device_tracker_list;
-    while (tracker != nullptr) {
-        device_tracker* next = tracker->next;
-        // This may destroy the tracker if the connection is closed.
-        device_tracker_send(tracker, list_transports(tracker->long_output));
-        tracker = next;
-    }
-}
-
-#else
-
-void update_transports() {
-    // Nothing to do on the device side.
-}
-
-#endif  // ADB_HOST
-
-struct tmsg {
-    atransport* transport;
-    int action;
-};
-
-static int transport_read_action(int fd, struct tmsg* m) {
-    char* p = (char*)m;
-    int len = sizeof(*m);
-    int r;
-
-    while (len > 0) {
-        r = adb_read(fd, p, len);
-        if (r > 0) {
-            len -= r;
-            p += r;
-        } else {
-            D("transport_read_action: on fd %d: %s", fd, strerror(errno));
-            return -1;
-        }
-    }
-    return 0;
-}
-
-static int transport_write_action(int fd, struct tmsg* m) {
-    char* p = (char*)m;
-    int len = sizeof(*m);
-    int r;
-
-    while (len > 0) {
-        r = adb_write(fd, p, len);
-        if (r > 0) {
-            len -= r;
-            p += r;
-        } else {
-            D("transport_write_action: on fd %d: %s", fd, strerror(errno));
-            return -1;
-        }
-    }
-    return 0;
-}
-
-static void transport_registration_func(int _fd, unsigned ev, void*) {
-    tmsg m;
-    atransport* t;
-
-    if (!(ev & FDE_READ)) {
-        return;
-    }
-
-    if (transport_read_action(_fd, &m)) {
-        PLOG(FATAL) << "cannot read transport registration socket";
-    }
-
-    t = m.transport;
-
-    if (m.action == 0) {
-        D("transport: %s deleting", t->serial.c_str());
-
-        {
-            std::lock_guard<std::recursive_mutex> lock(transport_lock);
-            transport_list.remove(t);
-        }
-
-        delete t;
-
-        update_transports();
-        return;
-    }
-
-    /* don't create transport threads for inaccessible devices */
-    if (t->GetConnectionState() != kCsNoPerm) {
-        // The connection gets a reference to the atransport. It will release it
-        // upon a read/write error.
-        t->connection()->SetTransportName(t->serial_name());
-        t->connection()->SetReadCallback([t](Connection*, std::unique_ptr<apacket> p) {
-            if (!check_header(p.get(), t)) {
-                D("%s: remote read: bad header", t->serial.c_str());
-                return false;
-            }
-
-            VLOG(TRANSPORT) << dump_packet(t->serial.c_str(), "from remote", p.get());
-            apacket* packet = p.release();
-
-            // TODO: Does this need to run on the main thread?
-            fdevent_run_on_main_thread([packet, t]() { handle_packet(packet, t); });
-            return true;
-        });
-        t->connection()->SetErrorCallback([t](Connection*, const std::string& error) {
-            LOG(INFO) << t->serial_name() << ": connection terminated: " << error;
-            fdevent_run_on_main_thread([t]() {
-                handle_offline(t);
-                transport_destroy(t);
-            });
-        });
-
-        t->connection()->Start();
-#if ADB_HOST
-        send_connect(t);
-#endif
-    }
-
-    {
-        std::lock_guard<std::recursive_mutex> lock(transport_lock);
-        auto it = std::find(pending_list.begin(), pending_list.end(), t);
-        if (it != pending_list.end()) {
-            pending_list.remove(t);
-            transport_list.push_front(t);
-        }
-    }
-
-    update_transports();
-}
-
-#if ADB_HOST
-void init_reconnect_handler(void) {
-    reconnect_handler.Start();
-}
-#endif
-
-void init_transport_registration(void) {
-    int s[2];
-
-    if (adb_socketpair(s)) {
-        PLOG(FATAL) << "cannot open transport registration socketpair";
-    }
-    D("socketpair: (%d,%d)", s[0], s[1]);
-
-    transport_registration_send = s[0];
-    transport_registration_recv = s[1];
-
-    transport_registration_fde =
-        fdevent_create(transport_registration_recv, transport_registration_func, nullptr);
-    fdevent_set(transport_registration_fde, FDE_READ);
-}
-
-void kick_all_transports() {
-#if ADB_HOST
-    reconnect_handler.Stop();
-#endif
-    // To avoid only writing part of a packet to a transport after exit, kick all transports.
-    std::lock_guard<std::recursive_mutex> lock(transport_lock);
-    for (auto t : transport_list) {
-        t->Kick();
-    }
-}
-
-void kick_all_tcp_tls_transports() {
-    std::lock_guard<std::recursive_mutex> lock(transport_lock);
-    for (auto t : transport_list) {
-        if (t->IsTcpDevice() && t->use_tls) {
-            t->Kick();
-        }
-    }
-}
-
-#if !ADB_HOST
-void kick_all_transports_by_auth_key(std::string_view auth_key) {
-    std::lock_guard<std::recursive_mutex> lock(transport_lock);
-    for (auto t : transport_list) {
-        if (auth_key == t->auth_key) {
-            t->Kick();
-        }
-    }
-}
-#endif
-
-/* the fdevent select pump is single threaded */
-void register_transport(atransport* transport) {
-    tmsg m;
-    m.transport = transport;
-    m.action = 1;
-    D("transport: %s registered", transport->serial.c_str());
-    if (transport_write_action(transport_registration_send, &m)) {
-        PLOG(FATAL) << "cannot write transport registration socket";
-    }
-}
-
-static void remove_transport(atransport* transport) {
-    tmsg m;
-    m.transport = transport;
-    m.action = 0;
-    D("transport: %s removed", transport->serial.c_str());
-    if (transport_write_action(transport_registration_send, &m)) {
-        PLOG(FATAL) << "cannot write transport registration socket";
-    }
-}
-
-static void transport_destroy(atransport* t) {
-    check_main_thread();
-    CHECK(t != nullptr);
-
-    std::lock_guard<std::recursive_mutex> lock(transport_lock);
-    LOG(INFO) << "destroying transport " << t->serial_name();
-    t->connection()->Stop();
-#if ADB_HOST
-    if (t->IsTcpDevice() && !t->kicked()) {
-        D("transport: %s destroy (attempting reconnection)", t->serial.c_str());
-
-        // We need to clear the transport's keys, so that on the next connection, it tries
-        // again from the beginning.
-        t->ResetKeys();
-        reconnect_handler.TrackTransport(t);
-        return;
-    }
-#endif
-
-    D("transport: %s destroy (kicking and closing)", t->serial.c_str());
-    remove_transport(t);
-}
-
-static int qual_match(const std::string& to_test, const char* prefix, const std::string& qual,
-                      bool sanitize_qual) {
-    if (to_test.empty()) /* Return true if both the qual and to_test are empty strings. */
-        return qual.empty();
-
-    if (qual.empty()) return 0;
-
-    const char* ptr = to_test.c_str();
-    if (prefix) {
-        while (*prefix) {
-            if (*prefix++ != *ptr++) return 0;
-        }
-    }
-
-    for (char ch : qual) {
-        if (sanitize_qual && !isalnum(ch)) ch = '_';
-        if (ch != *ptr++) return 0;
-    }
-
-    /* Everything matched so far.  Return true if *ptr is a NUL. */
-    return !*ptr;
-}
-
-atransport* acquire_one_transport(TransportType type, const char* serial, TransportId transport_id,
-                                  bool* is_ambiguous, std::string* error_out,
-                                  bool accept_any_state) {
-    atransport* result = nullptr;
-
-    if (transport_id != 0) {
-        *error_out =
-            android::base::StringPrintf("no device with transport id '%" PRIu64 "'", transport_id);
-    } else if (serial) {
-        *error_out = android::base::StringPrintf("device '%s' not found", serial);
-    } else if (type == kTransportLocal) {
-        *error_out = "no emulators found";
-    } else if (type == kTransportAny) {
-        *error_out = "no devices/emulators found";
-    } else {
-        *error_out = "no devices found";
-    }
-
-    std::unique_lock<std::recursive_mutex> lock(transport_lock);
-    for (const auto& t : transport_list) {
-        if (t->GetConnectionState() == kCsNoPerm) {
-            *error_out = UsbNoPermissionsLongHelpText();
-            continue;
-        }
-
-        if (transport_id) {
-            if (t->id == transport_id) {
-                result = t;
-                break;
-            }
-        } else if (serial) {
-            if (t->MatchesTarget(serial)) {
-                if (result) {
-                    *error_out = "more than one device";
-                    if (is_ambiguous) *is_ambiguous = true;
-                    result = nullptr;
-                    break;
-                }
-                result = t;
-            }
-        } else {
-            if (type == kTransportUsb && t->type == kTransportUsb) {
-                if (result) {
-                    *error_out = "more than one device";
-                    if (is_ambiguous) *is_ambiguous = true;
-                    result = nullptr;
-                    break;
-                }
-                result = t;
-            } else if (type == kTransportLocal && t->type == kTransportLocal) {
-                if (result) {
-                    *error_out = "more than one emulator";
-                    if (is_ambiguous) *is_ambiguous = true;
-                    result = nullptr;
-                    break;
-                }
-                result = t;
-            } else if (type == kTransportAny) {
-                if (result) {
-                    *error_out = "more than one device/emulator";
-                    if (is_ambiguous) *is_ambiguous = true;
-                    result = nullptr;
-                    break;
-                }
-                result = t;
-            }
-        }
-    }
-    lock.unlock();
-
-    if (result && !accept_any_state) {
-        // The caller requires an active transport.
-        // Make sure that we're actually connected.
-        ConnectionState state = result->GetConnectionState();
-        switch (state) {
-            case kCsConnecting:
-                *error_out = "device still connecting";
-                result = nullptr;
-                break;
-
-            case kCsAuthorizing:
-                *error_out = "device still authorizing";
-                result = nullptr;
-                break;
-
-            case kCsUnauthorized: {
-                *error_out = "device unauthorized.\n";
-                char* ADB_VENDOR_KEYS = getenv("ADB_VENDOR_KEYS");
-                *error_out += "This adb server's $ADB_VENDOR_KEYS is ";
-                *error_out += ADB_VENDOR_KEYS ? ADB_VENDOR_KEYS : "not set";
-                *error_out += "\n";
-                *error_out += "Try 'adb kill-server' if that seems wrong.\n";
-                *error_out += "Otherwise check for a confirmation dialog on your device.";
-                result = nullptr;
-                break;
-            }
-
-            case kCsOffline:
-                *error_out = "device offline";
-                result = nullptr;
-                break;
-
-            default:
-                break;
-        }
-    }
-
-    if (result) {
-        *error_out = "success";
-    }
-
-    return result;
-}
-
-bool ConnectionWaitable::WaitForConnection(std::chrono::milliseconds timeout) {
-    std::unique_lock<std::mutex> lock(mutex_);
-    ScopedLockAssertion assume_locked(mutex_);
-    return cv_.wait_for(lock, timeout, [&]() REQUIRES(mutex_) {
-        return connection_established_ready_;
-    }) && connection_established_;
-}
-
-void ConnectionWaitable::SetConnectionEstablished(bool success) {
-    {
-        std::lock_guard<std::mutex> lock(mutex_);
-        if (connection_established_ready_) return;
-        connection_established_ready_ = true;
-        connection_established_ = success;
-        D("connection established with %d", success);
-    }
-    cv_.notify_one();
-}
-
-atransport::~atransport() {
-    // If the connection callback had not been run before, run it now.
-    SetConnectionEstablished(false);
-}
-
-int atransport::Write(apacket* p) {
-    return this->connection()->Write(std::unique_ptr<apacket>(p)) ? 0 : -1;
-}
-
-void atransport::Reset() {
-    if (!kicked_.exchange(true)) {
-        LOG(INFO) << "resetting transport " << this << " " << this->serial;
-        this->connection()->Reset();
-    }
-}
-
-void atransport::Kick() {
-    if (!kicked_.exchange(true)) {
-        LOG(INFO) << "kicking transport " << this << " " << this->serial;
-        this->connection()->Stop();
-    }
-}
-
-ConnectionState atransport::GetConnectionState() const {
-    return connection_state_;
-}
-
-void atransport::SetConnectionState(ConnectionState state) {
-    check_main_thread();
-    connection_state_ = state;
-}
-
-void atransport::SetConnection(std::unique_ptr<Connection> connection) {
-    std::lock_guard<std::mutex> lock(mutex_);
-    connection_ = std::shared_ptr<Connection>(std::move(connection));
-}
-
-std::string atransport::connection_state_name() const {
-    ConnectionState state = GetConnectionState();
-    switch (state) {
-        case kCsOffline:
-            return "offline";
-        case kCsBootloader:
-            return "bootloader";
-        case kCsDevice:
-            return "device";
-        case kCsHost:
-            return "host";
-        case kCsRecovery:
-            return "recovery";
-        case kCsRescue:
-            return "rescue";
-        case kCsNoPerm:
-            return UsbNoPermissionsShortHelpText();
-        case kCsSideload:
-            return "sideload";
-        case kCsUnauthorized:
-            return "unauthorized";
-        case kCsAuthorizing:
-            return "authorizing";
-        case kCsConnecting:
-            return "connecting";
-        default:
-            return "unknown";
-    }
-}
-
-void atransport::update_version(int version, size_t payload) {
-    protocol_version = std::min(version, A_VERSION);
-    max_payload = std::min(payload, MAX_PAYLOAD);
-}
-
-int atransport::get_protocol_version() const {
-    return protocol_version;
-}
-
-int atransport::get_tls_version() const {
-    return tls_version;
-}
-
-size_t atransport::get_max_payload() const {
-    return max_payload;
-}
-
-const FeatureSet& supported_features() {
-    // Local static allocation to avoid global non-POD variables.
-    static const FeatureSet* features = new FeatureSet{
-            kFeatureShell2,
-            kFeatureCmd,
-            kFeatureStat2,
-            kFeatureLs2,
-            kFeatureFixedPushMkdir,
-            kFeatureApex,
-            kFeatureAbb,
-            kFeatureFixedPushSymlinkTimestamp,
-            kFeatureAbbExec,
-            kFeatureRemountShell,
-            kFeatureSendRecv2,
-            kFeatureSendRecv2Brotli,
-            // Increment ADB_SERVER_VERSION when adding a feature that adbd needs
-            // to know about. Otherwise, the client can be stuck running an old
-            // version of the server even after upgrading their copy of adb.
-            // (http://b/24370690)
-    };
-
-    return *features;
-}
-
-std::string FeatureSetToString(const FeatureSet& features) {
-    return android::base::Join(features, ',');
-}
-
-FeatureSet StringToFeatureSet(const std::string& features_string) {
-    if (features_string.empty()) {
-        return FeatureSet();
-    }
-
-    auto names = android::base::Split(features_string, ",");
-    return FeatureSet(names.begin(), names.end());
-}
-
-bool CanUseFeature(const FeatureSet& feature_set, const std::string& feature) {
-    return feature_set.count(feature) > 0 && supported_features().count(feature) > 0;
-}
-
-bool atransport::has_feature(const std::string& feature) const {
-    return features_.count(feature) > 0;
-}
-
-void atransport::SetFeatures(const std::string& features_string) {
-    features_ = StringToFeatureSet(features_string);
-}
-
-void atransport::AddDisconnect(adisconnect* disconnect) {
-    disconnects_.push_back(disconnect);
-}
-
-void atransport::RemoveDisconnect(adisconnect* disconnect) {
-    disconnects_.remove(disconnect);
-}
-
-void atransport::RunDisconnects() {
-    for (const auto& disconnect : disconnects_) {
-        disconnect->func(disconnect->opaque, this);
-    }
-    disconnects_.clear();
-}
-
-bool atransport::MatchesTarget(const std::string& target) const {
-    if (!serial.empty()) {
-        if (target == serial) {
-            return true;
-        } else if (type == kTransportLocal) {
-            // Local transports can match [tcp:|udp:]<hostname>[:port].
-            const char* local_target_ptr = target.c_str();
-
-            // For fastboot compatibility, ignore protocol prefixes.
-            if (android::base::StartsWith(target, "tcp:") ||
-                android::base::StartsWith(target, "udp:")) {
-                local_target_ptr += 4;
-            }
-
-            // Parse our |serial| and the given |target| to check if the hostnames and ports match.
-            std::string serial_host, error;
-            int serial_port = -1;
-            if (android::base::ParseNetAddress(serial, &serial_host, &serial_port, nullptr, &error)) {
-                // |target| may omit the port to default to ours.
-                std::string target_host;
-                int target_port = serial_port;
-                if (android::base::ParseNetAddress(local_target_ptr, &target_host, &target_port,
-                                                   nullptr, &error) &&
-                    serial_host == target_host && serial_port == target_port) {
-                    return true;
-                }
-            }
-        }
-    }
-
-    return (target == devpath) || qual_match(target, "product:", product, false) ||
-           qual_match(target, "model:", model, true) ||
-           qual_match(target, "device:", device, false);
-}
-
-void atransport::SetConnectionEstablished(bool success) {
-    connection_waitable_->SetConnectionEstablished(success);
-}
-
-ReconnectResult atransport::Reconnect() {
-    return reconnect_(this);
-}
-
-#if ADB_HOST
-
-// We use newline as our delimiter, make sure to never output it.
-static std::string sanitize(std::string str, bool alphanumeric) {
-    auto pred = alphanumeric ? [](const char c) { return !isalnum(c); }
-                             : [](const char c) { return c == '\n'; };
-    std::replace_if(str.begin(), str.end(), pred, '_');
-    return str;
-}
-
-static void append_transport_info(std::string* result, const char* key, const std::string& value,
-                                  bool alphanumeric) {
-    if (value.empty()) {
-        return;
-    }
-
-    *result += ' ';
-    *result += key;
-    *result += sanitize(value, alphanumeric);
-}
-
-static void append_transport(const atransport* t, std::string* result, bool long_listing) {
-    std::string serial = t->serial;
-    if (serial.empty()) {
-        serial = "(no serial number)";
-    }
-
-    if (!long_listing) {
-        *result += serial;
-        *result += '\t';
-        *result += t->connection_state_name();
-    } else {
-        android::base::StringAppendF(result, "%-22s %s", serial.c_str(),
-                                     t->connection_state_name().c_str());
-
-        append_transport_info(result, "", t->devpath, false);
-        append_transport_info(result, "product:", t->product, false);
-        append_transport_info(result, "model:", t->model, true);
-        append_transport_info(result, "device:", t->device, false);
-
-        // Put id at the end, so that anyone parsing the output here can always find it by scanning
-        // backwards from newlines, even with hypothetical devices named 'transport_id:1'.
-        *result += " transport_id:";
-        *result += std::to_string(t->id);
-    }
-    *result += '\n';
-}
-
-std::string list_transports(bool long_listing) {
-    std::lock_guard<std::recursive_mutex> lock(transport_lock);
-
-    auto sorted_transport_list = transport_list;
-    sorted_transport_list.sort([](atransport*& x, atransport*& y) {
-        if (x->type != y->type) {
-            return x->type < y->type;
-        }
-        return x->serial < y->serial;
-    });
-
-    std::string result;
-    for (const auto& t : sorted_transport_list) {
-        append_transport(t, &result, long_listing);
-    }
-    return result;
-}
-
-void close_usb_devices(std::function<bool(const atransport*)> predicate, bool reset) {
-    std::lock_guard<std::recursive_mutex> lock(transport_lock);
-    for (auto& t : transport_list) {
-        if (predicate(t)) {
-            if (reset) {
-                t->Reset();
-            } else {
-                t->Kick();
-            }
-        }
-    }
-}
-
-/* hack for osx */
-void close_usb_devices(bool reset) {
-    close_usb_devices([](const atransport*) { return true; }, reset);
-}
-#endif  // ADB_HOST
-
-bool register_socket_transport(unique_fd s, std::string serial, int port, int local,
-                               atransport::ReconnectCallback reconnect, bool use_tls, int* error) {
-    atransport* t = new atransport(std::move(reconnect), kCsOffline);
-    t->use_tls = use_tls;
-
-    D("transport: %s init'ing for socket %d, on port %d", serial.c_str(), s.get(), port);
-    if (init_socket_transport(t, std::move(s), port, local) < 0) {
-        delete t;
-        if (error) *error = errno;
-        return false;
-    }
-
-    std::unique_lock<std::recursive_mutex> lock(transport_lock);
-    for (const auto& transport : pending_list) {
-        if (serial == transport->serial) {
-            VLOG(TRANSPORT) << "socket transport " << transport->serial
-                            << " is already in pending_list and fails to register";
-            delete t;
-            if (error) *error = EALREADY;
-            return false;
-        }
-    }
-
-    for (const auto& transport : transport_list) {
-        if (serial == transport->serial) {
-            VLOG(TRANSPORT) << "socket transport " << transport->serial
-                            << " is already in transport_list and fails to register";
-            delete t;
-            if (error) *error = EALREADY;
-            return false;
-        }
-    }
-
-    t->serial = std::move(serial);
-    pending_list.push_front(t);
-
-    lock.unlock();
-
-    auto waitable = t->connection_waitable();
-    register_transport(t);
-
-    if (local == 1) {
-        // Do not wait for emulator transports.
-        return true;
-    }
-
-    if (!waitable->WaitForConnection(std::chrono::seconds(10))) {
-        if (error) *error = ETIMEDOUT;
-        return false;
-    }
-
-    if (t->GetConnectionState() == kCsUnauthorized) {
-        if (error) *error = EPERM;
-        return false;
-    }
-
-    return true;
-}
-
-#if ADB_HOST
-atransport* find_transport(const char* serial) {
-    atransport* result = nullptr;
-
-    std::lock_guard<std::recursive_mutex> lock(transport_lock);
-    for (auto& t : transport_list) {
-        if (strcmp(serial, t->serial.c_str()) == 0) {
-            result = t;
-            break;
-        }
-    }
-
-    return result;
-}
-
-void kick_all_tcp_devices() {
-    std::lock_guard<std::recursive_mutex> lock(transport_lock);
-    for (auto& t : transport_list) {
-        if (t->IsTcpDevice()) {
-            // Kicking breaks the read_transport thread of this transport out of any read, then
-            // the read_transport thread will notify the main thread to make this transport
-            // offline. Then the main thread will notify the write_transport thread to exit.
-            // Finally, this transport will be closed and freed in the main thread.
-            t->Kick();
-        }
-    }
-#if ADB_HOST
-    reconnect_handler.CheckForKicked();
-#endif
-}
-
-#endif
-
-#if ADB_HOST
-void register_usb_transport(usb_handle* usb, const char* serial, const char* devpath,
-                            unsigned writeable) {
-    atransport* t = new atransport(writeable ? kCsOffline : kCsNoPerm);
-
-    D("transport: %p init'ing for usb_handle %p (sn='%s')", t, usb, serial ? serial : "");
-    init_usb_transport(t, usb);
-    if (serial) {
-        t->serial = serial;
-    }
-
-    if (devpath) {
-        t->devpath = devpath;
-    }
-
-    {
-        std::lock_guard<std::recursive_mutex> lock(transport_lock);
-        pending_list.push_front(t);
-    }
-
-    register_transport(t);
-}
-#endif
-
-#if ADB_HOST
-// This should only be used for transports with connection_state == kCsNoPerm.
-void unregister_usb_transport(usb_handle* usb) {
-    std::lock_guard<std::recursive_mutex> lock(transport_lock);
-    transport_list.remove_if([usb](atransport* t) {
-        return t->GetUsbHandle() == usb && t->GetConnectionState() == kCsNoPerm;
-    });
-}
-#endif
-
-bool check_header(apacket* p, atransport* t) {
-    if (p->msg.magic != (p->msg.command ^ 0xffffffff)) {
-        VLOG(RWX) << "check_header(): invalid magic command = " << std::hex << p->msg.command
-                  << ", magic = " << p->msg.magic;
-        return false;
-    }
-
-    if (p->msg.data_length > t->get_max_payload()) {
-        VLOG(RWX) << "check_header(): " << p->msg.data_length
-                  << " atransport::max_payload = " << t->get_max_payload();
-        return false;
-    }
-
-    return true;
-}
-
-#if ADB_HOST
-std::shared_ptr<RSA> atransport::Key() {
-    if (keys_.empty()) {
-        return nullptr;
-    }
-
-    std::shared_ptr<RSA> result = keys_[0];
-    return result;
-}
-
-std::shared_ptr<RSA> atransport::NextKey() {
-    if (keys_.empty()) {
-        LOG(INFO) << "fetching keys for transport " << this->serial_name();
-        keys_ = adb_auth_get_private_keys();
-
-        // We should have gotten at least one key: the one that's automatically generated.
-        CHECK(!keys_.empty());
-    } else {
-        keys_.pop_front();
-    }
-
-    std::shared_ptr<RSA> result = keys_[0];
-    return result;
-}
-
-void atransport::ResetKeys() {
-    keys_.clear();
-}
-#endif
diff --git a/adb/transport.h b/adb/transport.h
deleted file mode 100644
index 26d804b..0000000
--- a/adb/transport.h
+++ /dev/null
@@ -1,477 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef __TRANSPORT_H
-#define __TRANSPORT_H
-
-#include <sys/types.h>
-
-#include <atomic>
-#include <chrono>
-#include <condition_variable>
-#include <deque>
-#include <functional>
-#include <list>
-#include <memory>
-#include <mutex>
-#include <optional>
-#include <string>
-#include <string_view>
-#include <thread>
-#include <unordered_set>
-
-#include <android-base/macros.h>
-#include <android-base/thread_annotations.h>
-#include <openssl/rsa.h>
-
-#include "adb.h"
-#include "adb_unique_fd.h"
-#include "types.h"
-
-typedef std::unordered_set<std::string> FeatureSet;
-
-namespace adb {
-namespace tls {
-
-class TlsConnection;
-
-}  // namespace tls
-}  // namespace adb
-
-const FeatureSet& supported_features();
-
-// Encodes and decodes FeatureSet objects into human-readable strings.
-std::string FeatureSetToString(const FeatureSet& features);
-FeatureSet StringToFeatureSet(const std::string& features_string);
-
-// Returns true if both local features and |feature_set| support |feature|.
-bool CanUseFeature(const FeatureSet& feature_set, const std::string& feature);
-
-// Do not use any of [:;=,] in feature strings, they have special meaning
-// in the connection banner.
-extern const char* const kFeatureShell2;
-// The 'cmd' command is available
-extern const char* const kFeatureCmd;
-extern const char* const kFeatureStat2;
-extern const char* const kFeatureLs2;
-// The server is running with libusb enabled.
-extern const char* const kFeatureLibusb;
-// adbd supports `push --sync`.
-extern const char* const kFeaturePushSync;
-// adbd supports installing .apex packages.
-extern const char* const kFeatureApex;
-// adbd has b/110953234 fixed.
-extern const char* const kFeatureFixedPushMkdir;
-// adbd supports android binder bridge (abb) in interactive mode using shell protocol.
-extern const char* const kFeatureAbb;
-// adbd supports abb using raw pipe.
-extern const char* const kFeatureAbbExec;
-// adbd properly updates symlink timestamps on push.
-extern const char* const kFeatureFixedPushSymlinkTimestamp;
-// Implement `adb remount` via shelling out to /system/bin/remount.
-extern const char* const kFeatureRemountShell;
-// adbd supports version 2 of send/recv.
-extern const char* const kFeatureSendRecv2;
-// adbd supports brotli for send/recv v2.
-extern const char* const kFeatureSendRecv2Brotli;
-
-TransportId NextTransportId();
-
-// Abstraction for a non-blocking packet transport.
-struct Connection {
-    Connection() = default;
-    virtual ~Connection() = default;
-
-    void SetTransportName(std::string transport_name) {
-        transport_name_ = std::move(transport_name);
-    }
-
-    using ReadCallback = std::function<bool(Connection*, std::unique_ptr<apacket>)>;
-    void SetReadCallback(ReadCallback callback) {
-        CHECK(!read_callback_);
-        read_callback_ = callback;
-    }
-
-    // Called after the Connection has terminated, either by an error or because Stop was called.
-    using ErrorCallback = std::function<void(Connection*, const std::string&)>;
-    void SetErrorCallback(ErrorCallback callback) {
-        CHECK(!error_callback_);
-        error_callback_ = callback;
-    }
-
-    virtual bool Write(std::unique_ptr<apacket> packet) = 0;
-
-    virtual void Start() = 0;
-    virtual void Stop() = 0;
-
-    virtual bool DoTlsHandshake(RSA* key, std::string* auth_key = nullptr) = 0;
-
-    // Stop, and reset the device if it's a USB connection.
-    virtual void Reset();
-
-    std::string transport_name_;
-    ReadCallback read_callback_;
-    ErrorCallback error_callback_;
-
-    static std::unique_ptr<Connection> FromFd(unique_fd fd);
-};
-
-// Abstraction for a blocking packet transport.
-struct BlockingConnection {
-    BlockingConnection() = default;
-    BlockingConnection(const BlockingConnection& copy) = delete;
-    BlockingConnection(BlockingConnection&& move) = delete;
-
-    // Destroy a BlockingConnection. Formerly known as 'Close' in atransport.
-    virtual ~BlockingConnection() = default;
-
-    // Read/Write a packet. These functions are concurrently called from a transport's reader/writer
-    // threads.
-    virtual bool Read(apacket* packet) = 0;
-    virtual bool Write(apacket* packet) = 0;
-
-    virtual bool DoTlsHandshake(RSA* key, std::string* auth_key = nullptr) = 0;
-
-    // Terminate a connection.
-    // This method must be thread-safe, and must cause concurrent Reads/Writes to terminate.
-    // Formerly known as 'Kick' in atransport.
-    virtual void Close() = 0;
-
-    // Terminate a connection, and reset it.
-    virtual void Reset() = 0;
-};
-
-struct BlockingConnectionAdapter : public Connection {
-    explicit BlockingConnectionAdapter(std::unique_ptr<BlockingConnection> connection);
-
-    virtual ~BlockingConnectionAdapter();
-
-    virtual bool Write(std::unique_ptr<apacket> packet) override final;
-
-    virtual void Start() override final;
-    virtual void Stop() override final;
-    virtual bool DoTlsHandshake(RSA* key, std::string* auth_key) override final;
-
-    virtual void Reset() override final;
-
-  private:
-    void StartReadThread() REQUIRES(mutex_);
-    bool started_ GUARDED_BY(mutex_) = false;
-    bool stopped_ GUARDED_BY(mutex_) = false;
-
-    std::unique_ptr<BlockingConnection> underlying_;
-    std::thread read_thread_ GUARDED_BY(mutex_);
-    std::thread write_thread_ GUARDED_BY(mutex_);
-
-    std::deque<std::unique_ptr<apacket>> write_queue_ GUARDED_BY(mutex_);
-    std::mutex mutex_;
-    std::condition_variable cv_;
-
-    std::once_flag error_flag_;
-};
-
-struct FdConnection : public BlockingConnection {
-    explicit FdConnection(unique_fd fd);
-    ~FdConnection();
-
-    bool Read(apacket* packet) override final;
-    bool Write(apacket* packet) override final;
-    bool DoTlsHandshake(RSA* key, std::string* auth_key) override final;
-
-    void Close() override;
-    virtual void Reset() override final { Close(); }
-
-  private:
-    bool DispatchRead(void* buf, size_t len);
-    bool DispatchWrite(void* buf, size_t len);
-
-    unique_fd fd_;
-    std::unique_ptr<adb::tls::TlsConnection> tls_;
-};
-
-// Waits for a transport's connection to be not pending. This is a separate
-// object so that the transport can be destroyed and another thread can be
-// notified of it in a race-free way.
-class ConnectionWaitable {
-  public:
-    ConnectionWaitable() = default;
-    ~ConnectionWaitable() = default;
-
-    // Waits until the first CNXN packet has been received by the owning
-    // atransport, or the specified timeout has elapsed. Can be called from any
-    // thread.
-    //
-    // Returns true if the CNXN packet was received in a timely fashion, false
-    // otherwise.
-    bool WaitForConnection(std::chrono::milliseconds timeout);
-
-    // Can be called from any thread when the connection stops being pending.
-    // Only the first invocation will be acknowledged, the rest will be no-ops.
-    void SetConnectionEstablished(bool success);
-
-  private:
-    bool connection_established_ GUARDED_BY(mutex_) = false;
-    bool connection_established_ready_ GUARDED_BY(mutex_) = false;
-    std::mutex mutex_;
-    std::condition_variable cv_;
-
-    DISALLOW_COPY_AND_ASSIGN(ConnectionWaitable);
-};
-
-enum class ReconnectResult {
-    Retry,
-    Success,
-    Abort,
-};
-
-#if ADB_HOST
-struct usb_handle;
-#endif
-
-class atransport : public enable_weak_from_this<atransport> {
-  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.
-
-    using ReconnectCallback = std::function<ReconnectResult(atransport*)>;
-
-    atransport(ReconnectCallback reconnect, ConnectionState state)
-        : id(NextTransportId()),
-          kicked_(false),
-          connection_state_(state),
-          connection_waitable_(std::make_shared<ConnectionWaitable>()),
-          connection_(nullptr),
-          reconnect_(std::move(reconnect)) {
-        // Initialize protocol to min version for compatibility with older versions.
-        // Version will be updated post-connect.
-        protocol_version = A_VERSION_MIN;
-        max_payload = MAX_PAYLOAD;
-    }
-    atransport(ConnectionState state = kCsOffline)
-        : atransport([](atransport*) { return ReconnectResult::Abort; }, state) {}
-    ~atransport();
-
-    int Write(apacket* p);
-    void Reset();
-    void Kick();
-    bool kicked() const { return kicked_; }
-
-    // ConnectionState can be read by all threads, but can only be written in the main thread.
-    ConnectionState GetConnectionState() const;
-    void SetConnectionState(ConnectionState state);
-
-    void SetConnection(std::unique_ptr<Connection> connection);
-    std::shared_ptr<Connection> connection() {
-        std::lock_guard<std::mutex> lock(mutex_);
-        return connection_;
-    }
-
-#if ADB_HOST
-    void SetUsbHandle(usb_handle* h) { usb_handle_ = h; }
-    usb_handle* GetUsbHandle() { return usb_handle_; }
-#endif
-
-    const TransportId id;
-
-    bool online = false;
-    TransportType type = kTransportAny;
-
-    // Used to identify transports for clients.
-    std::string serial;
-    std::string product;
-    std::string model;
-    std::string device;
-    std::string devpath;
-
-    // If this is set, the transport will initiate the connection with a
-    // START_TLS command, instead of AUTH.
-    bool use_tls = false;
-    int tls_version = A_STLS_VERSION;
-    int get_tls_version() const;
-
-#if !ADB_HOST
-    // Used to provide the key to the framework.
-    std::string auth_key;
-    std::optional<uint64_t> auth_id;
-#endif
-
-    bool IsTcpDevice() const { return type == kTransportLocal; }
-
-#if ADB_HOST
-    // The current key being authorized.
-    std::shared_ptr<RSA> Key();
-    std::shared_ptr<RSA> NextKey();
-    void ResetKeys();
-#endif
-
-    char token[TOKEN_SIZE] = {};
-    size_t failed_auth_attempts = 0;
-
-    std::string serial_name() const { return !serial.empty() ? serial : "<unknown>"; }
-    std::string connection_state_name() const;
-
-    void update_version(int version, size_t payload);
-    int get_protocol_version() const;
-    size_t get_max_payload() const;
-
-    const FeatureSet& features() const {
-        return features_;
-    }
-
-    bool has_feature(const std::string& feature) const;
-
-    // Loads the transport's feature set from the given string.
-    void SetFeatures(const std::string& features_string);
-
-    void AddDisconnect(adisconnect* disconnect);
-    void RemoveDisconnect(adisconnect* disconnect);
-    void RunDisconnects();
-
-    // Returns true if |target| matches this transport. A matching |target| can be any of:
-    //   * <serial>
-    //   * <devpath>
-    //   * product:<product>
-    //   * model:<model>
-    //   * device:<device>
-    //
-    // If this is a local transport, serial will also match [tcp:|udp:]<hostname>[:port] targets.
-    // For example, serial "100.100.100.100:5555" would match any of:
-    //   * 100.100.100.100
-    //   * tcp:100.100.100.100
-    //   * udp:100.100.100.100:5555
-    // This is to make it easier to use the same network target for both fastboot and adb.
-    bool MatchesTarget(const std::string& target) const;
-
-    // Notifies that the atransport is no longer waiting for the connection
-    // being established.
-    void SetConnectionEstablished(bool success);
-
-    // Gets a shared reference to the ConnectionWaitable.
-    std::shared_ptr<ConnectionWaitable> connection_waitable() { return connection_waitable_; }
-
-    // Attempts to reconnect with the underlying Connection.
-    ReconnectResult Reconnect();
-
-  private:
-    std::atomic<bool> kicked_;
-
-    // A set of features transmitted in the banner with the initial connection.
-    // This is stored in the banner as 'features=feature0,feature1,etc'.
-    FeatureSet features_;
-    int protocol_version;
-    size_t max_payload;
-
-    // A list of adisconnect callbacks called when the transport is kicked.
-    std::list<adisconnect*> disconnects_;
-
-    std::atomic<ConnectionState> connection_state_;
-#if ADB_HOST
-    std::deque<std::shared_ptr<RSA>> keys_;
-#endif
-
-    // A sharable object that can be used to wait for the atransport's
-    // connection to be established.
-    std::shared_ptr<ConnectionWaitable> connection_waitable_;
-
-    // The underlying connection object.
-    std::shared_ptr<Connection> connection_ GUARDED_BY(mutex_);
-
-#if ADB_HOST
-    // USB handle for the connection, if available.
-    usb_handle* usb_handle_ = nullptr;
-#endif
-
-    // A callback that will be invoked when the atransport needs to reconnect.
-    ReconnectCallback reconnect_;
-
-    std::mutex mutex_;
-
-    DISALLOW_COPY_AND_ASSIGN(atransport);
-};
-
-/*
- * 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, TransportId transport_id,
-                                  bool* is_ambiguous, std::string* error_out,
-                                  bool accept_any_state = false);
-void kick_transport(atransport* t, bool reset = false);
-void update_transports(void);
-
-// Iterates across all of the current and pending transports.
-// Stops iteration and returns false if fn returns false, otherwise returns true.
-bool iterate_transports(std::function<bool(const atransport*)> fn);
-
-void init_reconnect_handler(void);
-void init_transport_registration(void);
-void init_mdns_transport_discovery(void);
-std::string list_transports(bool long_listing);
-atransport* find_transport(const char* serial);
-void kick_all_tcp_devices();
-void kick_all_transports();
-void kick_all_tcp_tls_transports();
-#if !ADB_HOST
-void kick_all_transports_by_auth_key(std::string_view auth_key);
-#endif
-
-void register_transport(atransport* transport);
-
-#if ADB_HOST
-void init_usb_transport(atransport* t, usb_handle* usb);
-void register_usb_transport(usb_handle* h, const char* serial, const char* devpath,
-                            unsigned writeable);
-
-// This should only be used for transports with connection_state == kCsNoPerm.
-void unregister_usb_transport(usb_handle* usb);
-#endif
-
-/* Connect to a network address and register it as a device */
-void connect_device(const std::string& address, std::string* response);
-
-/* cause new transports to be init'd and added to the list */
-bool register_socket_transport(unique_fd s, std::string serial, int port, int local,
-                               atransport::ReconnectCallback reconnect, bool use_tls,
-                               int* error = nullptr);
-
-bool check_header(apacket* p, atransport* t);
-
-void close_usb_devices(bool reset = false);
-void close_usb_devices(std::function<bool(const atransport*)> predicate, bool reset = false);
-
-void send_packet(apacket* p, atransport* t);
-
-asocket* create_device_tracker(bool long_output);
-
-#if !ADB_HOST
-unique_fd adb_listen(std::string_view addr, std::string* error);
-void server_socket_thread(std::function<unique_fd(std::string_view, std::string*)> listen_func,
-                          std::string_view addr);
-
-#if defined(__ANDROID__)
-void qemu_socket_thread(std::string_view addr);
-bool use_qemu_goldfish();
-#endif
-
-#endif
-
-#endif   /* __TRANSPORT_H */
diff --git a/adb/transport_benchmark.cpp b/adb/transport_benchmark.cpp
deleted file mode 100644
index 022808f..0000000
--- a/adb/transport_benchmark.cpp
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <malloc.h>
-#include <stdio.h>
-
-#include <android-base/logging.h>
-#include <benchmark/benchmark.h>
-
-#include "adb_trace.h"
-#include "sysdeps.h"
-#include "transport.h"
-
-#define ADB_CONNECTION_BENCHMARK(benchmark_name, ...)                          \
-    BENCHMARK_TEMPLATE(benchmark_name, FdConnection, ##__VA_ARGS__)            \
-        ->Arg(1)                                                               \
-        ->Arg(16384)                                                           \
-        ->Arg(MAX_PAYLOAD)                                                     \
-        ->UseRealTime();                                                       \
-    BENCHMARK_TEMPLATE(benchmark_name, NonblockingFdConnection, ##__VA_ARGS__) \
-        ->Arg(1)                                                               \
-        ->Arg(16384)                                                           \
-        ->Arg(MAX_PAYLOAD)                                                     \
-        ->UseRealTime()
-
-struct NonblockingFdConnection;
-template <typename ConnectionType>
-std::unique_ptr<Connection> MakeConnection(unique_fd fd);
-
-template <>
-std::unique_ptr<Connection> MakeConnection<FdConnection>(unique_fd fd) {
-    auto fd_connection = std::make_unique<FdConnection>(std::move(fd));
-    return std::make_unique<BlockingConnectionAdapter>(std::move(fd_connection));
-}
-
-template <>
-std::unique_ptr<Connection> MakeConnection<NonblockingFdConnection>(unique_fd fd) {
-    return Connection::FromFd(std::move(fd));
-}
-
-template <typename ConnectionType>
-void BM_Connection_Unidirectional(benchmark::State& state) {
-    int fds[2];
-    if (adb_socketpair(fds) != 0) {
-        LOG(FATAL) << "failed to create socketpair";
-    }
-
-    auto client = MakeConnection<ConnectionType>(unique_fd(fds[0]));
-    auto server = MakeConnection<ConnectionType>(unique_fd(fds[1]));
-
-    std::atomic<size_t> received_bytes;
-
-    client->SetReadCallback([](Connection*, std::unique_ptr<apacket>) -> bool { return true; });
-    server->SetReadCallback([&received_bytes](Connection*, std::unique_ptr<apacket> packet) -> bool {
-        received_bytes += packet->payload.size();
-        return true;
-    });
-
-    client->SetErrorCallback(
-        [](Connection*, const std::string& error) { LOG(INFO) << "client closed: " << error; });
-    server->SetErrorCallback(
-        [](Connection*, const std::string& error) { LOG(INFO) << "server closed: " << error; });
-
-    client->Start();
-    server->Start();
-
-    for (auto _ : state) {
-        size_t data_size = state.range(0);
-        std::unique_ptr<apacket> packet = std::make_unique<apacket>();
-        memset(&packet->msg, 0, sizeof(packet->msg));
-        packet->msg.command = A_WRTE;
-        packet->msg.data_length = data_size;
-        packet->payload.resize(data_size);
-
-        memset(&packet->payload[0], 0xff, data_size);
-
-        received_bytes = 0;
-        client->Write(std::move(packet));
-        while (received_bytes < data_size) {
-            continue;
-        }
-    }
-    state.SetBytesProcessed(static_cast<int64_t>(state.iterations()) * state.range(0));
-
-    client->Stop();
-    server->Stop();
-}
-
-ADB_CONNECTION_BENCHMARK(BM_Connection_Unidirectional);
-
-enum class ThreadPolicy {
-    MainThread,
-    SameThread,
-};
-
-template <typename ConnectionType, enum ThreadPolicy Policy>
-void BM_Connection_Echo(benchmark::State& state) {
-    int fds[2];
-    if (adb_socketpair(fds) != 0) {
-        LOG(FATAL) << "failed to create socketpair";
-    }
-
-    auto client = MakeConnection<ConnectionType>(unique_fd(fds[0]));
-    auto server = MakeConnection<ConnectionType>(unique_fd(fds[1]));
-
-    std::atomic<size_t> received_bytes;
-
-    fdevent_reset();
-    std::thread fdevent_thread([]() { fdevent_loop(); });
-
-    client->SetReadCallback([&received_bytes](Connection*, std::unique_ptr<apacket> packet) -> bool {
-        received_bytes += packet->payload.size();
-        return true;
-    });
-
-    static const auto handle_packet = [](Connection* connection, std::unique_ptr<apacket> packet) {
-        connection->Write(std::move(packet));
-    };
-
-    server->SetReadCallback([](Connection* connection, std::unique_ptr<apacket> packet) -> bool {
-        if (Policy == ThreadPolicy::MainThread) {
-            auto raw_packet = packet.release();
-            fdevent_run_on_main_thread([connection, raw_packet]() {
-                std::unique_ptr<apacket> packet(raw_packet);
-                handle_packet(connection, std::move(packet));
-            });
-        } else {
-            handle_packet(connection, std::move(packet));
-        }
-        return true;
-    });
-
-    client->SetErrorCallback(
-        [](Connection*, const std::string& error) { LOG(INFO) << "client closed: " << error; });
-    server->SetErrorCallback(
-        [](Connection*, const std::string& error) { LOG(INFO) << "server closed: " << error; });
-
-    client->Start();
-    server->Start();
-
-    for (auto _ : state) {
-        size_t data_size = state.range(0);
-        std::unique_ptr<apacket> packet = std::make_unique<apacket>();
-        memset(&packet->msg, 0, sizeof(packet->msg));
-        packet->msg.command = A_WRTE;
-        packet->msg.data_length = data_size;
-        packet->payload.resize(data_size);
-
-        memset(&packet->payload[0], 0xff, data_size);
-
-        received_bytes = 0;
-        client->Write(std::move(packet));
-        while (received_bytes < data_size) {
-            continue;
-        }
-    }
-    state.SetBytesProcessed(static_cast<int64_t>(state.iterations()) * state.range(0));
-
-    client->Stop();
-    server->Stop();
-
-    // TODO: Make it so that you don't need to poke the fdevent loop to make it terminate?
-    fdevent_terminate_loop();
-    fdevent_run_on_main_thread([]() {});
-
-    fdevent_thread.join();
-}
-
-ADB_CONNECTION_BENCHMARK(BM_Connection_Echo, ThreadPolicy::SameThread);
-ADB_CONNECTION_BENCHMARK(BM_Connection_Echo, ThreadPolicy::MainThread);
-
-int main(int argc, char** argv) {
-    // Set M_DECAY_TIME so that our allocations aren't immediately purged on free.
-    mallopt(M_DECAY_TIME, 1);
-
-    android::base::SetMinimumLogSeverity(android::base::WARNING);
-    adb_trace_init(argv);
-    ::benchmark::Initialize(&argc, argv);
-    if (::benchmark::ReportUnrecognizedArguments(argc, argv)) return 1;
-    ::benchmark::RunSpecifiedBenchmarks();
-}
diff --git a/adb/transport_fd.cpp b/adb/transport_fd.cpp
deleted file mode 100644
index b9b4f42..0000000
--- a/adb/transport_fd.cpp
+++ /dev/null
@@ -1,241 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdint.h>
-
-#include <deque>
-#include <memory>
-#include <mutex>
-#include <string>
-#include <thread>
-
-#include <android-base/logging.h>
-#include <android-base/stringprintf.h>
-#include <android-base/thread_annotations.h>
-
-#include "adb_unique_fd.h"
-#include "adb_utils.h"
-#include "sysdeps.h"
-#include "transport.h"
-#include "types.h"
-
-static void CreateWakeFds(unique_fd* read, unique_fd* write) {
-    // TODO: eventfd on linux?
-    int wake_fds[2];
-    int rc = adb_socketpair(wake_fds);
-    set_file_block_mode(wake_fds[0], false);
-    set_file_block_mode(wake_fds[1], false);
-    CHECK_EQ(0, rc);
-    *read = unique_fd(wake_fds[0]);
-    *write = unique_fd(wake_fds[1]);
-}
-
-struct NonblockingFdConnection : public Connection {
-    NonblockingFdConnection(unique_fd fd) : started_(false), fd_(std::move(fd)) {
-        set_file_block_mode(fd_.get(), false);
-        CreateWakeFds(&wake_fd_read_, &wake_fd_write_);
-    }
-
-    void SetRunning(bool value) {
-        std::lock_guard<std::mutex> lock(run_mutex_);
-        running_ = value;
-    }
-
-    bool IsRunning() {
-        std::lock_guard<std::mutex> lock(run_mutex_);
-        return running_;
-    }
-
-    void Run(std::string* error) {
-        SetRunning(true);
-        while (IsRunning()) {
-            adb_pollfd pfds[2] = {
-                {.fd = fd_.get(), .events = POLLIN},
-                {.fd = wake_fd_read_.get(), .events = POLLIN},
-            };
-
-            {
-                std::lock_guard<std::mutex> lock(this->write_mutex_);
-                if (!writable_) {
-                    pfds[0].events |= POLLOUT;
-                }
-            }
-
-            int rc = adb_poll(pfds, 2, -1);
-            if (rc == -1) {
-                *error = android::base::StringPrintf("poll failed: %s", strerror(errno));
-                return;
-            } else if (rc == 0) {
-                LOG(FATAL) << "poll timed out with an infinite timeout?";
-            }
-
-            if (pfds[0].revents) {
-                if ((pfds[0].revents & POLLOUT)) {
-                    std::lock_guard<std::mutex> lock(this->write_mutex_);
-                    if (DispatchWrites() == WriteResult::Error) {
-                        *error = "write failed";
-                        return;
-                    }
-                }
-
-                if (pfds[0].revents & POLLIN) {
-                    // TODO: Should we be getting blocks from a free list?
-                    auto block = IOVector::block_type(MAX_PAYLOAD);
-                    rc = adb_read(fd_.get(), &block[0], block.size());
-                    if (rc == -1) {
-                        *error = std::string("read failed: ") + strerror(errno);
-                        return;
-                    } else if (rc == 0) {
-                        *error = "read failed: EOF";
-                        return;
-                    }
-                    block.resize(rc);
-                    read_buffer_.append(std::move(block));
-
-                    if (!read_header_ && read_buffer_.size() >= sizeof(amessage)) {
-                        auto header_buf = read_buffer_.take_front(sizeof(amessage)).coalesce();
-                        CHECK_EQ(sizeof(amessage), header_buf.size());
-                        read_header_ = std::make_unique<amessage>();
-                        memcpy(read_header_.get(), header_buf.data(), sizeof(amessage));
-                    }
-
-                    if (read_header_ && read_buffer_.size() >= read_header_->data_length) {
-                        auto data_chain = read_buffer_.take_front(read_header_->data_length);
-
-                        // TODO: Make apacket carry around a IOVector instead of coalescing.
-                        auto payload = std::move(data_chain).coalesce();
-                        auto packet = std::make_unique<apacket>();
-                        packet->msg = *read_header_;
-                        packet->payload = std::move(payload);
-                        read_header_ = nullptr;
-                        read_callback_(this, std::move(packet));
-                    }
-                }
-            }
-
-            if (pfds[1].revents) {
-                uint64_t buf;
-                rc = adb_read(wake_fd_read_.get(), &buf, sizeof(buf));
-                CHECK_EQ(static_cast<int>(sizeof(buf)), rc);
-
-                // We were woken up either to add POLLOUT to our events, or to exit.
-                // Do nothing.
-            }
-        }
-    }
-
-    void Start() override final {
-        if (started_.exchange(true)) {
-            LOG(FATAL) << "Connection started multiple times?";
-        }
-
-        thread_ = std::thread([this]() {
-            std::string error = "connection closed";
-            Run(&error);
-            this->error_callback_(this, error);
-        });
-    }
-
-    void Stop() override final {
-        SetRunning(false);
-        WakeThread();
-        thread_.join();
-    }
-
-    bool DoTlsHandshake(RSA* key, std::string* auth_key) override final {
-        LOG(FATAL) << "Not supported yet";
-        return false;
-    }
-
-    void WakeThread() {
-        uint64_t buf = 0;
-        if (TEMP_FAILURE_RETRY(adb_write(wake_fd_write_.get(), &buf, sizeof(buf))) != sizeof(buf)) {
-            LOG(FATAL) << "failed to wake up thread";
-        }
-    }
-
-    enum class WriteResult {
-        Error,
-        Completed,
-        TryAgain,
-    };
-
-    WriteResult DispatchWrites() REQUIRES(write_mutex_) {
-        CHECK(!write_buffer_.empty());
-        auto iovs = write_buffer_.iovecs();
-        ssize_t rc = adb_writev(fd_.get(), iovs.data(), iovs.size());
-        if (rc == -1) {
-            if (errno == EAGAIN || errno == EWOULDBLOCK) {
-                writable_ = false;
-                return WriteResult::TryAgain;
-            }
-
-            return WriteResult::Error;
-        } else if (rc == 0) {
-            errno = 0;
-            return WriteResult::Error;
-        }
-
-        write_buffer_.drop_front(rc);
-        writable_ = write_buffer_.empty();
-        if (write_buffer_.empty()) {
-            return WriteResult::Completed;
-        }
-
-        // There's data left in the range, which means our write returned early.
-        return WriteResult::TryAgain;
-    }
-
-    bool Write(std::unique_ptr<apacket> packet) final {
-        std::lock_guard<std::mutex> lock(write_mutex_);
-        const char* header_begin = reinterpret_cast<const char*>(&packet->msg);
-        const char* header_end = header_begin + sizeof(packet->msg);
-        auto header_block = IOVector::block_type(header_begin, header_end);
-        write_buffer_.append(std::move(header_block));
-        if (!packet->payload.empty()) {
-            write_buffer_.append(std::move(packet->payload));
-        }
-
-        WriteResult result = DispatchWrites();
-        if (result == WriteResult::TryAgain) {
-            WakeThread();
-        }
-        return result != WriteResult::Error;
-    }
-
-    std::thread thread_;
-
-    std::atomic<bool> started_;
-    std::mutex run_mutex_;
-    bool running_ GUARDED_BY(run_mutex_);
-
-    std::unique_ptr<amessage> read_header_;
-    IOVector read_buffer_;
-
-    unique_fd fd_;
-    unique_fd wake_fd_read_;
-    unique_fd wake_fd_write_;
-
-    std::mutex write_mutex_;
-    bool writable_ GUARDED_BY(write_mutex_) = true;
-    IOVector write_buffer_ GUARDED_BY(write_mutex_);
-
-    IOVector incoming_queue_;
-};
-
-std::unique_ptr<Connection> Connection::FromFd(unique_fd fd) {
-    return std::make_unique<NonblockingFdConnection>(std::move(fd));
-}
diff --git a/adb/transport_local.cpp b/adb/transport_local.cpp
deleted file mode 100644
index 5ec8e16..0000000
--- a/adb/transport_local.cpp
+++ /dev/null
@@ -1,389 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define TRACE_TAG TRANSPORT
-
-#include "sysdeps.h"
-#include "transport.h"
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-
-#include <condition_variable>
-#include <functional>
-#include <memory>
-#include <mutex>
-#include <thread>
-#include <unordered_map>
-#include <vector>
-
-#include <android-base/parsenetaddress.h>
-#include <android-base/stringprintf.h>
-#include <android-base/thread_annotations.h>
-#include <cutils/sockets.h>
-
-#if !ADB_HOST
-#include <android-base/properties.h>
-#endif
-
-#include "adb.h"
-#include "adb_io.h"
-#include "adb_unique_fd.h"
-#include "adb_utils.h"
-#include "socket_spec.h"
-#include "sysdeps/chrono.h"
-
-#if ADB_HOST
-
-// Android Wear has been using port 5601 in all of its documentation/tooling,
-// but we search for emulators on ports [5554, 5555 + ADB_LOCAL_TRANSPORT_MAX].
-// Avoid stomping on their port by restricting the active scanning range.
-// Once emulators self-(re-)register, they'll have to avoid 5601 in their own way.
-static int adb_local_transport_max_port = DEFAULT_ADB_LOCAL_TRANSPORT_PORT + 16 * 2 - 1;
-
-static std::mutex& local_transports_lock = *new std::mutex();
-
-static void adb_local_transport_max_port_env_override() {
-    const char* env_max_s = getenv("ADB_LOCAL_TRANSPORT_MAX_PORT");
-    if (env_max_s != nullptr) {
-        size_t env_max;
-        if (ParseUint(&env_max, env_max_s, nullptr) && env_max < 65536) {
-            // < DEFAULT_ADB_LOCAL_TRANSPORT_PORT harmlessly mimics ADB_EMU=0
-            adb_local_transport_max_port = env_max;
-            D("transport: ADB_LOCAL_TRANSPORT_MAX_PORT read as %d", adb_local_transport_max_port);
-        } else {
-            D("transport: ADB_LOCAL_TRANSPORT_MAX_PORT '%s' invalid or >= 65536, so ignored",
-              env_max_s);
-        }
-    }
-}
-
-// We keep a map from emulator port to transport.
-// TODO: weak_ptr?
-static auto& local_transports GUARDED_BY(local_transports_lock) =
-    *new std::unordered_map<int, atransport*>();
-#endif /* ADB_HOST */
-
-bool local_connect(int port) {
-    std::string dummy;
-    return local_connect_arbitrary_ports(port - 1, port, &dummy) == 0;
-}
-
-void connect_device(const std::string& address, std::string* response) {
-    if (address.empty()) {
-        *response = "empty address";
-        return;
-    }
-
-    D("connection requested to '%s'", address.c_str());
-    unique_fd fd;
-    int port;
-    std::string serial, prefix_addr;
-
-    // If address does not match any socket type, it should default to TCP.
-    if (address.starts_with("vsock:") || address.starts_with("localfilesystem:")) {
-        prefix_addr = address;
-    } else {
-        prefix_addr = "tcp:" + address;
-    }
-
-    socket_spec_connect(&fd, prefix_addr, &port, &serial, response);
-    if (fd.get() == -1) {
-        return;
-    }
-    auto reconnect = [prefix_addr](atransport* t) {
-        std::string response;
-        unique_fd fd;
-        int port;
-        std::string serial;
-        socket_spec_connect(&fd, prefix_addr, &port, &serial, &response);
-        if (fd == -1) {
-            D("reconnect failed: %s", response.c_str());
-            return ReconnectResult::Retry;
-        }
-        // This invokes the part of register_socket_transport() that needs to be
-        // invoked if the atransport* has already been setup. This eventually
-        // calls atransport->SetConnection() with a newly created Connection*
-        // that will in turn send the CNXN packet.
-        return init_socket_transport(t, std::move(fd), port, 0) >= 0 ? ReconnectResult::Success
-                                                                     : ReconnectResult::Retry;
-    };
-
-    int error;
-    if (!register_socket_transport(std::move(fd), serial, port, 0, std::move(reconnect), false,
-                                   &error)) {
-        if (error == EALREADY) {
-            *response = android::base::StringPrintf("already connected to %s", serial.c_str());
-        } else if (error == EPERM) {
-            *response = android::base::StringPrintf("failed to authenticate to %s", serial.c_str());
-        } else {
-            *response = android::base::StringPrintf("failed to connect to %s", serial.c_str());
-        }
-    } else {
-        *response = android::base::StringPrintf("connected to %s", serial.c_str());
-    }
-}
-
-
-int local_connect_arbitrary_ports(int console_port, int adb_port, std::string* error) {
-    unique_fd fd;
-
-#if ADB_HOST
-    if (find_emulator_transport_by_adb_port(adb_port) != nullptr ||
-        find_emulator_transport_by_console_port(console_port) != nullptr) {
-        return -1;
-    }
-
-    const char *host = getenv("ADBHOST");
-    if (host) {
-        fd.reset(network_connect(host, adb_port, SOCK_STREAM, 0, error));
-    }
-#endif
-    if (fd < 0) {
-        fd.reset(network_loopback_client(adb_port, SOCK_STREAM, error));
-    }
-
-    if (fd >= 0) {
-        D("client: connected on remote on fd %d", fd.get());
-        close_on_exec(fd.get());
-        disable_tcp_nagle(fd.get());
-        std::string serial = getEmulatorSerialString(console_port);
-        if (register_socket_transport(
-                    std::move(fd), std::move(serial), adb_port, 1,
-                    [](atransport*) { return ReconnectResult::Abort; }, false)) {
-            return 0;
-        }
-    }
-    return -1;
-}
-
-#if ADB_HOST
-
-static void PollAllLocalPortsForEmulator() {
-    // Try to connect to any number of running emulator instances.
-    for (int port = DEFAULT_ADB_LOCAL_TRANSPORT_PORT; port <= adb_local_transport_max_port;
-         port += 2) {
-        local_connect(port);  // Note, uses port and port-1, so '=max_port' is OK.
-    }
-}
-
-// Retry the disconnected local port for 60 times, and sleep 1 second between two retries.
-static constexpr uint32_t LOCAL_PORT_RETRY_COUNT = 60;
-static constexpr auto LOCAL_PORT_RETRY_INTERVAL = 1s;
-
-struct RetryPort {
-    int port;
-    uint32_t retry_count;
-};
-
-// Retry emulators just kicked.
-static std::vector<RetryPort>& retry_ports = *new std::vector<RetryPort>;
-std::mutex &retry_ports_lock = *new std::mutex;
-std::condition_variable &retry_ports_cond = *new std::condition_variable;
-
-static void client_socket_thread(std::string_view) {
-    adb_thread_setname("client_socket_thread");
-    D("transport: client_socket_thread() starting");
-    PollAllLocalPortsForEmulator();
-    while (true) {
-        std::vector<RetryPort> ports;
-        // Collect retry ports.
-        {
-            std::unique_lock<std::mutex> lock(retry_ports_lock);
-            while (retry_ports.empty()) {
-                retry_ports_cond.wait(lock);
-            }
-            retry_ports.swap(ports);
-        }
-        // Sleep here instead of the end of loop, because if we immediately try to reconnect
-        // the emulator just kicked, the adbd on the emulator may not have time to remove the
-        // just kicked transport.
-        std::this_thread::sleep_for(LOCAL_PORT_RETRY_INTERVAL);
-
-        // Try connecting retry ports.
-        std::vector<RetryPort> next_ports;
-        for (auto& port : ports) {
-            VLOG(TRANSPORT) << "retry port " << port.port << ", last retry_count "
-                << port.retry_count;
-            if (local_connect(port.port)) {
-                VLOG(TRANSPORT) << "retry port " << port.port << " successfully";
-                continue;
-            }
-            if (--port.retry_count > 0) {
-                next_ports.push_back(port);
-            } else {
-                VLOG(TRANSPORT) << "stop retrying port " << port.port;
-            }
-        }
-
-        // Copy back left retry ports.
-        {
-            std::unique_lock<std::mutex> lock(retry_ports_lock);
-            retry_ports.insert(retry_ports.end(), next_ports.begin(), next_ports.end());
-        }
-    }
-}
-
-#else  // !ADB_HOST
-
-void server_socket_thread(std::function<unique_fd(std::string_view, std::string*)> listen_func,
-                          std::string_view addr) {
-    adb_thread_setname("server socket");
-
-    unique_fd serverfd;
-    std::string error;
-
-    while (serverfd == -1) {
-        errno = 0;
-        serverfd = listen_func(addr, &error);
-        if (errno == EAFNOSUPPORT || errno == EINVAL || errno == EPROTONOSUPPORT) {
-            D("unrecoverable error: '%s'", error.c_str());
-            return;
-        } else if (serverfd < 0) {
-            D("server: cannot bind socket yet: %s", error.c_str());
-            std::this_thread::sleep_for(1s);
-            continue;
-        }
-        close_on_exec(serverfd.get());
-    }
-
-    while (true) {
-        D("server: trying to get new connection from fd %d", serverfd.get());
-        unique_fd fd(adb_socket_accept(serverfd, nullptr, nullptr));
-        if (fd >= 0) {
-            D("server: new connection on fd %d", fd.get());
-            close_on_exec(fd.get());
-            disable_tcp_nagle(fd.get());
-            std::string serial = android::base::StringPrintf("host-%d", fd.get());
-            // We don't care about port value in "register_socket_transport" as it is used
-            // only from ADB_HOST. "server_socket_thread" is never called from ADB_HOST.
-            register_socket_transport(
-                    std::move(fd), std::move(serial), 0, 1,
-                    [](atransport*) { return ReconnectResult::Abort; }, false);
-        }
-    }
-    D("transport: server_socket_thread() exiting");
-}
-
-#endif
-
-#if !ADB_HOST
-unique_fd adb_listen(std::string_view addr, std::string* error) {
-    return unique_fd{socket_spec_listen(addr, error, nullptr)};
-}
-#endif
-
-void local_init(const std::string& addr) {
-#if ADB_HOST
-    D("transport: local client init");
-    std::thread(client_socket_thread, addr).detach();
-    adb_local_transport_max_port_env_override();
-#elif !defined(__ANDROID__)
-    // Host adbd.
-    D("transport: local server init");
-    std::thread(server_socket_thread, adb_listen, addr).detach();
-#else
-    D("transport: local server init");
-    // For the adbd daemon in the system image we need to distinguish
-    // between the device, and the emulator.
-    if (addr.starts_with("tcp:") && use_qemu_goldfish()) {
-        std::thread(qemu_socket_thread, addr).detach();
-    } else {
-        std::thread(server_socket_thread, adb_listen, addr).detach();
-    }
-#endif // !ADB_HOST
-}
-
-#if ADB_HOST
-struct EmulatorConnection : public FdConnection {
-    EmulatorConnection(unique_fd fd, int local_port)
-        : FdConnection(std::move(fd)), local_port_(local_port) {}
-
-    ~EmulatorConnection() {
-        VLOG(TRANSPORT) << "remote_close, local_port = " << local_port_;
-        std::unique_lock<std::mutex> lock(retry_ports_lock);
-        RetryPort port;
-        port.port = local_port_;
-        port.retry_count = LOCAL_PORT_RETRY_COUNT;
-        retry_ports.push_back(port);
-        retry_ports_cond.notify_one();
-    }
-
-    void Close() override {
-        std::lock_guard<std::mutex> lock(local_transports_lock);
-        local_transports.erase(local_port_);
-        FdConnection::Close();
-    }
-
-    int local_port_;
-};
-
-/* Only call this function if you already hold local_transports_lock. */
-static atransport* find_emulator_transport_by_adb_port_locked(int adb_port)
-    REQUIRES(local_transports_lock) {
-    auto it = local_transports.find(adb_port);
-    if (it == local_transports.end()) {
-        return nullptr;
-    }
-    return it->second;
-}
-
-atransport* find_emulator_transport_by_adb_port(int adb_port) {
-    std::lock_guard<std::mutex> lock(local_transports_lock);
-    return find_emulator_transport_by_adb_port_locked(adb_port);
-}
-
-atransport* find_emulator_transport_by_console_port(int console_port) {
-    return find_transport(getEmulatorSerialString(console_port).c_str());
-}
-#endif
-
-std::string getEmulatorSerialString(int console_port) {
-    return android::base::StringPrintf("emulator-%d", console_port);
-}
-
-int init_socket_transport(atransport* t, unique_fd fd, int adb_port, int local) {
-    int fail = 0;
-
-    t->type = kTransportLocal;
-
-#if ADB_HOST
-    // Emulator connection.
-    if (local) {
-        auto emulator_connection = std::make_unique<EmulatorConnection>(std::move(fd), adb_port);
-        t->SetConnection(
-                std::make_unique<BlockingConnectionAdapter>(std::move(emulator_connection)));
-        std::lock_guard<std::mutex> lock(local_transports_lock);
-        atransport* existing_transport = find_emulator_transport_by_adb_port_locked(adb_port);
-        if (existing_transport != nullptr) {
-            D("local transport for port %d already registered (%p)?", adb_port, existing_transport);
-            fail = -1;
-        } else {
-            local_transports[adb_port] = t;
-        }
-
-        return fail;
-    }
-#endif
-
-    // Regular tcp connection.
-    auto fd_connection = std::make_unique<FdConnection>(std::move(fd));
-    t->SetConnection(std::make_unique<BlockingConnectionAdapter>(std::move(fd_connection)));
-    return fail;
-}
diff --git a/adb/transport_test.cpp b/adb/transport_test.cpp
deleted file mode 100644
index 00beb3a..0000000
--- a/adb/transport_test.cpp
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "transport.h"
-
-#include <gtest/gtest.h>
-
-#include "adb.h"
-#include "fdevent/fdevent_test.h"
-
-struct TransportTest : public FdeventTest {};
-
-static void DisconnectFunc(void* arg, atransport*) {
-    int* count = reinterpret_cast<int*>(arg);
-    ++*count;
-}
-
-TEST_F(TransportTest, RunDisconnects) {
-    atransport t;
-    // RunDisconnects() can be called with an empty atransport.
-    t.RunDisconnects();
-
-    int count = 0;
-    adisconnect disconnect;
-    disconnect.func = DisconnectFunc;
-    disconnect.opaque = &count;
-    t.AddDisconnect(&disconnect);
-    t.RunDisconnects();
-    ASSERT_EQ(1, count);
-
-    // disconnect should have been removed automatically.
-    t.RunDisconnects();
-    ASSERT_EQ(1, count);
-
-    count = 0;
-    t.AddDisconnect(&disconnect);
-    t.RemoveDisconnect(&disconnect);
-    t.RunDisconnects();
-    ASSERT_EQ(0, count);
-}
-
-TEST_F(TransportTest, SetFeatures) {
-    atransport t;
-    ASSERT_EQ(0U, t.features().size());
-
-    t.SetFeatures(FeatureSetToString(FeatureSet{"foo"}));
-    ASSERT_EQ(1U, t.features().size());
-    ASSERT_TRUE(t.has_feature("foo"));
-
-    t.SetFeatures(FeatureSetToString(FeatureSet{"foo", "bar"}));
-    ASSERT_EQ(2U, t.features().size());
-    ASSERT_TRUE(t.has_feature("foo"));
-    ASSERT_TRUE(t.has_feature("bar"));
-
-    t.SetFeatures(FeatureSetToString(FeatureSet{"foo", "bar", "foo"}));
-    ASSERT_EQ(2U, t.features().size());
-    ASSERT_TRUE(t.has_feature("foo"));
-    ASSERT_TRUE(t.has_feature("bar"));
-
-    t.SetFeatures(FeatureSetToString(FeatureSet{"bar", "baz"}));
-    ASSERT_EQ(2U, t.features().size());
-    ASSERT_FALSE(t.has_feature("foo"));
-    ASSERT_TRUE(t.has_feature("bar"));
-    ASSERT_TRUE(t.has_feature("baz"));
-
-    t.SetFeatures("");
-    ASSERT_EQ(0U, t.features().size());
-}
-
-TEST_F(TransportTest, parse_banner_no_features) {
-    atransport t;
-
-    parse_banner("host::", &t);
-
-    ASSERT_EQ(0U, t.features().size());
-    ASSERT_EQ(kCsHost, t.GetConnectionState());
-
-    ASSERT_EQ(std::string(), t.product);
-    ASSERT_EQ(std::string(), t.model);
-    ASSERT_EQ(std::string(), t.device);
-}
-
-TEST_F(TransportTest, parse_banner_product_features) {
-    atransport t;
-
-    const char banner[] =
-        "host::ro.product.name=foo;ro.product.model=bar;ro.product.device=baz;";
-    parse_banner(banner, &t);
-
-    ASSERT_EQ(kCsHost, t.GetConnectionState());
-
-    ASSERT_EQ(0U, t.features().size());
-
-    ASSERT_EQ(std::string("foo"), t.product);
-    ASSERT_EQ(std::string("bar"), t.model);
-    ASSERT_EQ(std::string("baz"), t.device);
-}
-
-TEST_F(TransportTest, parse_banner_features) {
-    atransport t;
-    const char banner[] =
-        "host::ro.product.name=foo;ro.product.model=bar;ro.product.device=baz;"
-        "features=woodly,doodly";
-    parse_banner(banner, &t);
-
-    ASSERT_EQ(kCsHost, t.GetConnectionState());
-
-    ASSERT_EQ(2U, t.features().size());
-    ASSERT_TRUE(t.has_feature("woodly"));
-    ASSERT_TRUE(t.has_feature("doodly"));
-
-    ASSERT_EQ(std::string("foo"), t.product);
-    ASSERT_EQ(std::string("bar"), t.model);
-    ASSERT_EQ(std::string("baz"), t.device);
-}
-
-TEST_F(TransportTest, test_matches_target) {
-    std::string serial = "foo";
-    std::string devpath = "/path/to/bar";
-    std::string product = "test_product";
-    std::string model = "test_model";
-    std::string device = "test_device";
-
-    atransport t;
-    t.serial = &serial[0];
-    t.devpath = &devpath[0];
-    t.product = &product[0];
-    t.model = &model[0];
-    t.device = &device[0];
-
-    // These tests should not be affected by the transport type.
-    for (TransportType type : {kTransportAny, kTransportLocal}) {
-        t.type = type;
-
-        EXPECT_TRUE(t.MatchesTarget(serial));
-        EXPECT_TRUE(t.MatchesTarget(devpath));
-        EXPECT_TRUE(t.MatchesTarget("product:" + product));
-        EXPECT_TRUE(t.MatchesTarget("model:" + model));
-        EXPECT_TRUE(t.MatchesTarget("device:" + device));
-
-        // Product, model, and device don't match without the prefix.
-        EXPECT_FALSE(t.MatchesTarget(product));
-        EXPECT_FALSE(t.MatchesTarget(model));
-        EXPECT_FALSE(t.MatchesTarget(device));
-    }
-}
-
-TEST_F(TransportTest, test_matches_target_local) {
-    std::string serial = "100.100.100.100:5555";
-
-    atransport t;
-    t.serial = &serial[0];
-
-    // Network address matching should only be used for local transports.
-    for (TransportType type : {kTransportAny, kTransportLocal}) {
-        t.type = type;
-        bool should_match = (type == kTransportLocal);
-
-        EXPECT_EQ(should_match, t.MatchesTarget("100.100.100.100"));
-        EXPECT_EQ(should_match, t.MatchesTarget("tcp:100.100.100.100"));
-        EXPECT_EQ(should_match, t.MatchesTarget("tcp:100.100.100.100:5555"));
-        EXPECT_EQ(should_match, t.MatchesTarget("udp:100.100.100.100"));
-        EXPECT_EQ(should_match, t.MatchesTarget("udp:100.100.100.100:5555"));
-
-        // Wrong protocol, hostname, or port should never match.
-        EXPECT_FALSE(t.MatchesTarget("100.100.100"));
-        EXPECT_FALSE(t.MatchesTarget("100.100.100.100:"));
-        EXPECT_FALSE(t.MatchesTarget("100.100.100.100:-1"));
-        EXPECT_FALSE(t.MatchesTarget("100.100.100.100:5554"));
-        EXPECT_FALSE(t.MatchesTarget("abc:100.100.100.100"));
-    }
-}
diff --git a/adb/types.cpp b/adb/types.cpp
deleted file mode 100644
index 26b77ab..0000000
--- a/adb/types.cpp
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "types.h"
-
-IOVector& IOVector::operator=(IOVector&& move) noexcept {
-    chain_ = std::move(move.chain_);
-    chain_length_ = move.chain_length_;
-    begin_offset_ = move.begin_offset_;
-    start_index_ = move.start_index_;
-
-    move.clear();
-    return *this;
-}
-
-IOVector::block_type IOVector::clear() {
-    chain_length_ = 0;
-    begin_offset_ = 0;
-    start_index_ = 0;
-    block_type res;
-    if (!chain_.empty()) {
-        res = std::move(chain_.back());
-    }
-    chain_.clear();
-    return res;
-}
-
-void IOVector::drop_front(IOVector::size_type len) {
-    if (len == 0) {
-        return;
-    }
-    if (len == size()) {
-        clear();
-        return;
-    }
-    CHECK_LT(len, size());
-
-    auto dropped = 0u;
-    while (dropped < len) {
-        const auto next = chain_[start_index_].size() - begin_offset_;
-        if (dropped + next < len) {
-            pop_front_block();
-            dropped += next;
-        } else {
-            const auto taken = len - dropped;
-            begin_offset_ += taken;
-            break;
-        }
-    }
-}
-
-IOVector IOVector::take_front(IOVector::size_type len) {
-    if (len == 0) {
-        return {};
-    }
-    if (len == size()) {
-        return std::move(*this);
-    }
-
-    CHECK_GE(size(), len);
-    IOVector res;
-    // first iterate over the blocks that completely go into the other vector
-    while (chain_[start_index_].size() - begin_offset_ <= len) {
-        chain_length_ -= chain_[start_index_].size();
-        len -= chain_[start_index_].size() - begin_offset_;
-        if (chain_[start_index_].size() > begin_offset_) {
-            res.append(std::move(chain_[start_index_]));
-            if (begin_offset_) {
-                res.begin_offset_ = std::exchange(begin_offset_, 0);
-            }
-        } else {
-            begin_offset_ = 0;
-        }
-        ++start_index_;
-    }
-
-    if (len > 0) {
-        // what's left is a single buffer that needs to be split between the |res| and |this|
-        // we know that it has to be split - there was a check for the case when it has to
-        // go away as a whole.
-        if (begin_offset_ != 0 || len < chain_[start_index_].size() / 2) {
-            // let's memcpy the data out
-            block_type block(chain_[start_index_].begin() + begin_offset_,
-                             chain_[start_index_].begin() + begin_offset_ + len);
-            res.append(std::move(block));
-            begin_offset_ += len;
-        } else {
-            CHECK_EQ(begin_offset_, 0u);
-            // move out the internal buffer out and copy only the tail of it back in
-            block_type block(chain_[start_index_].begin() + len, chain_[start_index_].end());
-            chain_length_ -= chain_[start_index_].size();
-            chain_[start_index_].resize(len);
-            res.append(std::move(chain_[start_index_]));
-            chain_length_ += block.size();
-            chain_[start_index_] = std::move(block);
-        }
-    }
-    return res;
-}
-
-void IOVector::trim_front() {
-    if ((begin_offset_ == 0 && start_index_ == 0) || chain_.empty()) {
-        return;
-    }
-    block_type& first_block = chain_[start_index_];
-    if (begin_offset_ == first_block.size()) {
-        ++start_index_;
-    } else {
-        memmove(first_block.data(), first_block.data() + begin_offset_,
-                first_block.size() - begin_offset_);
-        first_block.resize(first_block.size() - begin_offset_);
-    }
-    chain_length_ -= begin_offset_;
-    begin_offset_ = 0;
-    trim_chain_front();
-}
-
-void IOVector::trim_chain_front() {
-    if (start_index_) {
-        chain_.erase(chain_.begin(), chain_.begin() + start_index_);
-        start_index_ = 0;
-    }
-}
-
-void IOVector::pop_front_block() {
-    chain_length_ -= chain_[start_index_].size();
-    begin_offset_ = 0;
-    chain_[start_index_].clear();
-    ++start_index_;
-    if (start_index_ > std::max<size_t>(4, chain_.size() / 2)) {
-        trim_chain_front();
-    }
-}
-
-IOVector::block_type IOVector::coalesce() && {
-    // Destructive coalesce() may optimize for several cases when it doesn't need to allocate
-    // new buffer, or even return one of the existing blocks as is. The only guarantee is that
-    // after this call the IOVector is in some valid state. Nothing is guaranteed about the
-    // specifics.
-    if (size() == 0) {
-        return {};
-    }
-    if (begin_offset_ == chain_[start_index_].size() && chain_.size() == start_index_ + 2) {
-        chain_length_ -= chain_.back().size();
-        auto res = std::move(chain_.back());
-        chain_.pop_back();
-        return res;
-    }
-    if (chain_.size() == start_index_ + 1) {
-        chain_length_ -= chain_.back().size();
-        auto res = std::move(chain_.back());
-        chain_.pop_back();
-        if (begin_offset_ != 0) {
-            memmove(res.data(), res.data() + begin_offset_, res.size() - begin_offset_);
-            res.resize(res.size() - begin_offset_);
-            begin_offset_ = 0;
-        }
-        return res;
-    }
-    if (auto& firstBuffer = chain_[start_index_]; firstBuffer.capacity() >= size()) {
-        auto res = std::move(chain_[start_index_]);
-        auto size = res.size();
-        chain_length_ -= size;
-        if (begin_offset_ != 0) {
-            memmove(res.data(), res.data() + begin_offset_, res.size() - begin_offset_);
-            size -= begin_offset_;
-            begin_offset_ = 0;
-        }
-        for (auto i = start_index_ + 1; i < chain_.size(); ++i) {
-            memcpy(res.data() + size, chain_[i].data(), chain_[i].size());
-            size += chain_[i].size();
-        }
-        res.resize(size);
-        ++start_index_;
-        return res;
-    }
-    return const_cast<const IOVector*>(this)->coalesce<>();
-}
-
-std::vector<adb_iovec> IOVector::iovecs() const {
-    std::vector<adb_iovec> result;
-    result.reserve(chain_.size() - start_index_);
-    iterate_blocks([&result](const char* data, size_t len) {
-        adb_iovec iov;
-        iov.iov_base = const_cast<char*>(data);
-        iov.iov_len = len;
-        result.emplace_back(iov);
-    });
-
-    return result;
-}
diff --git a/adb/types.h b/adb/types.h
deleted file mode 100644
index deca7ea..0000000
--- a/adb/types.h
+++ /dev/null
@@ -1,358 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <string.h>
-
-#include <algorithm>
-#include <memory>
-#include <utility>
-#include <vector>
-
-#include <android-base/logging.h>
-
-#include "fdevent/fdevent.h"
-#include "sysdeps/uio.h"
-
-// Essentially std::vector<char>, except without zero initialization or reallocation.
-struct Block {
-    using iterator = char*;
-
-    Block() = default;
-
-    explicit Block(size_t size) { allocate(size); }
-
-    template <typename Iterator>
-    Block(Iterator begin, Iterator end) : Block(end - begin) {
-        std::copy(begin, end, data_.get());
-    }
-
-    Block(const Block& copy) = delete;
-    Block(Block&& move) noexcept
-        : data_(std::exchange(move.data_, nullptr)),
-          capacity_(std::exchange(move.capacity_, 0)),
-          size_(std::exchange(move.size_, 0)) {}
-
-    Block& operator=(const Block& copy) = delete;
-    Block& operator=(Block&& move) noexcept {
-        clear();
-        data_ = std::exchange(move.data_, nullptr);
-        capacity_ = std::exchange(move.capacity_, 0);
-        size_ = std::exchange(move.size_, 0);
-        return *this;
-    }
-
-    ~Block() = default;
-
-    void resize(size_t new_size) {
-        if (!data_) {
-            allocate(new_size);
-        } else {
-            CHECK_GE(capacity_, new_size);
-            size_ = new_size;
-        }
-    }
-
-    template <typename InputIt>
-    void assign(InputIt begin, InputIt end) {
-        clear();
-        allocate(end - begin);
-        std::copy(begin, end, data_.get());
-    }
-
-    void clear() {
-        data_.reset();
-        capacity_ = 0;
-        size_ = 0;
-    }
-
-    size_t capacity() const { return capacity_; }
-    size_t size() const { return size_; }
-    bool empty() const { return size() == 0; }
-
-    char* data() { return data_.get(); }
-    const char* data() const { return data_.get(); }
-
-    char* begin() { return data_.get(); }
-    const char* begin() const { return data_.get(); }
-
-    char* end() { return data() + size_; }
-    const char* end() const { return data() + size_; }
-
-    char& operator[](size_t idx) { return data()[idx]; }
-    const char& operator[](size_t idx) const { return data()[idx]; }
-
-    bool operator==(const Block& rhs) const {
-        return size() == rhs.size() && memcmp(data(), rhs.data(), size()) == 0;
-    }
-
-  private:
-    void allocate(size_t size) {
-        CHECK(data_ == nullptr);
-        CHECK_EQ(0ULL, capacity_);
-        CHECK_EQ(0ULL, size_);
-        if (size != 0) {
-            // This isn't std::make_unique because that's equivalent to `new char[size]()`, which
-            // value-initializes the array instead of leaving it uninitialized. As an optimization,
-            // call new without parentheses to avoid this costly initialization.
-            data_.reset(new char[size]);
-            capacity_ = size;
-            size_ = size;
-        }
-    }
-
-    std::unique_ptr<char[]> data_;
-    size_t capacity_ = 0;
-    size_t size_ = 0;
-};
-
-struct amessage {
-    uint32_t command;     /* command identifier constant      */
-    uint32_t arg0;        /* first argument                   */
-    uint32_t arg1;        /* second argument                  */
-    uint32_t data_length; /* length of payload (0 is allowed) */
-    uint32_t data_check;  /* checksum of data payload         */
-    uint32_t magic;       /* command ^ 0xffffffff             */
-};
-
-struct apacket {
-    using payload_type = Block;
-    amessage msg;
-    payload_type payload;
-};
-
-struct IOVector {
-    using value_type = char;
-    using block_type = Block;
-    using size_type = size_t;
-
-    IOVector() = default;
-
-    explicit IOVector(block_type&& block) { append(std::move(block)); }
-
-    IOVector(const IOVector& copy) = delete;
-    IOVector(IOVector&& move) noexcept : IOVector() { *this = std::move(move); }
-
-    IOVector& operator=(const IOVector& copy) = delete;
-    IOVector& operator=(IOVector&& move) noexcept;
-
-    const value_type* front_data() const {
-        if (chain_.empty()) {
-            return nullptr;
-        }
-
-        return chain_.front().data() + begin_offset_;
-    }
-
-    size_type front_size() const {
-        if (chain_.empty()) {
-            return 0;
-        }
-
-        return chain_.front().size() - begin_offset_;
-    }
-
-    size_type size() const { return chain_length_ - begin_offset_; }
-    bool empty() const { return size() == 0; }
-
-    // Return the last block so the caller can still reuse its allocated capacity
-    // or it can be simply ignored.
-    block_type clear();
-
-    void drop_front(size_type len);
-
-    // Split the first |len| bytes out of this chain into its own.
-    IOVector take_front(size_type len);
-
-    // Add a nonempty block to the chain.
-    void append(block_type&& block) {
-        if (block.size() == 0) {
-            return;
-        }
-        CHECK_NE(0ULL, block.size());
-        chain_length_ += block.size();
-        chain_.emplace_back(std::move(block));
-    }
-
-    void trim_front();
-
-  private:
-    void trim_chain_front();
-
-    // Drop the front block from the chain, and update chain_length_ appropriately.
-    void pop_front_block();
-
-    // Iterate over the blocks with a callback with an operator()(const char*, size_t).
-    template <typename Fn>
-    void iterate_blocks(Fn&& callback) const {
-        if (size() == 0) {
-            return;
-        }
-
-        for (size_t i = start_index_; i < chain_.size(); ++i) {
-            const auto& block = chain_[i];
-            const char* begin = block.data();
-            size_t length = block.size();
-
-            if (i == start_index_) {
-                CHECK_GE(block.size(), begin_offset_);
-                begin += begin_offset_;
-                length -= begin_offset_;
-            }
-            callback(begin, length);
-        }
-    }
-
-  public:
-    // Copy all of the blocks into a single block.
-    template <typename CollectionType = block_type>
-    CollectionType coalesce() const& {
-        CollectionType result;
-        if (size() == 0) {
-            return result;
-        }
-
-        result.resize(size());
-
-        size_t offset = 0;
-        iterate_blocks([&offset, &result](const char* data, size_t len) {
-            memcpy(&result[offset], data, len);
-            offset += len;
-        });
-
-        return result;
-    }
-
-    block_type coalesce() &&;
-
-    template <typename FunctionType>
-    auto coalesced(FunctionType&& f) const {
-        if (chain_.size() == start_index_ + 1) {
-            // If we only have one block, we can use it directly.
-            return f(chain_[start_index_].data() + begin_offset_, size());
-        } else {
-            // Otherwise, copy to a single block.
-            auto data = coalesce();
-            return f(data.data(), data.size());
-        }
-    }
-
-    // Get a list of iovecs that can be used to write out all of the blocks.
-    std::vector<adb_iovec> iovecs() const;
-
-  private:
-    // Total length of all of the blocks in the chain.
-    size_t chain_length_ = 0;
-
-    size_t begin_offset_ = 0;
-    size_t start_index_ = 0;
-    std::vector<block_type> chain_;
-};
-
-// An implementation of weak pointers tied to the fdevent run loop.
-//
-// This allows for code to submit a request for an object, and upon receiving
-// a response, know whether the object is still alive, or has been destroyed
-// because of other reasons. We keep a list of living weak_ptrs in each object,
-// and clear the weak_ptrs when the object is destroyed. This is safe, because
-// we require that both the destructor of the referent and the get method on
-// the weak_ptr are executed on the main thread.
-template <typename T>
-struct enable_weak_from_this;
-
-template <typename T>
-struct weak_ptr {
-    weak_ptr() = default;
-    explicit weak_ptr(T* ptr) { reset(ptr); }
-    weak_ptr(const weak_ptr& copy) { reset(copy.get()); }
-
-    weak_ptr(weak_ptr&& move) {
-        reset(move.get());
-        move.reset();
-    }
-
-    ~weak_ptr() { reset(); }
-
-    weak_ptr& operator=(const weak_ptr& copy) {
-        if (&copy == this) {
-            return *this;
-        }
-
-        reset(copy.get());
-        return *this;
-    }
-
-    weak_ptr& operator=(weak_ptr&& move) {
-        if (&move == this) {
-            return *this;
-        }
-
-        reset(move.get());
-        move.reset();
-        return *this;
-    }
-
-    T* get() {
-        check_main_thread();
-        return ptr_;
-    }
-
-    void reset(T* ptr = nullptr) {
-        check_main_thread();
-
-        if (ptr == ptr_) {
-            return;
-        }
-
-        if (ptr_) {
-            ptr_->weak_ptrs_.erase(
-                    std::remove(ptr_->weak_ptrs_.begin(), ptr_->weak_ptrs_.end(), this));
-        }
-
-        ptr_ = ptr;
-        if (ptr_) {
-            ptr_->weak_ptrs_.push_back(this);
-        }
-    }
-
-  private:
-    friend struct enable_weak_from_this<T>;
-    T* ptr_ = nullptr;
-};
-
-template <typename T>
-struct enable_weak_from_this {
-    ~enable_weak_from_this() {
-        if (!weak_ptrs_.empty()) {
-            check_main_thread();
-            for (auto& weak : weak_ptrs_) {
-                weak->ptr_ = nullptr;
-            }
-            weak_ptrs_.clear();
-        }
-    }
-
-    weak_ptr<T> weak() { return weak_ptr<T>(static_cast<T*>(this)); }
-
-    void schedule_deletion() {
-        fdevent_run_on_main_thread([this]() { delete this; });
-    }
-
-  private:
-    friend struct weak_ptr<T>;
-    std::vector<weak_ptr<T>*> weak_ptrs_;
-};
diff --git a/adb/types_test.cpp b/adb/types_test.cpp
deleted file mode 100644
index 2c99f95..0000000
--- a/adb/types_test.cpp
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <gtest/gtest.h>
-
-#include <memory>
-#include "types.h"
-
-static IOVector::block_type create_block(const std::string& string) {
-    return IOVector::block_type(string.begin(), string.end());
-}
-
-static IOVector::block_type create_block(char value, size_t len) {
-    auto block = IOVector::block_type();
-    block.resize(len);
-    memset(&(block)[0], value, len);
-    return block;
-}
-
-template <typename T>
-static IOVector::block_type copy_block(const T& block) {
-    auto copy = IOVector::block_type();
-    copy.assign(block.begin(), block.end());
-    return copy;
-}
-
-TEST(IOVector, empty) {
-    // Empty IOVector.
-    IOVector bc;
-    CHECK_EQ(0ULL, bc.coalesce().size());
-}
-
-TEST(IOVector, single_block) {
-    // A single block.
-    auto block = create_block('x', 100);
-    IOVector bc;
-    bc.append(copy_block(block));
-    ASSERT_EQ(100ULL, bc.size());
-    auto coalesced = bc.coalesce();
-    ASSERT_EQ(block, coalesced);
-}
-
-TEST(IOVector, single_block_split) {
-    // One block split.
-    IOVector bc;
-    bc.append(create_block("foobar"));
-    IOVector foo = bc.take_front(3);
-    ASSERT_EQ(3ULL, foo.size());
-    ASSERT_EQ(3ULL, bc.size());
-    ASSERT_EQ(create_block("foo"), foo.coalesce());
-    ASSERT_EQ(create_block("bar"), bc.coalesce());
-}
-
-TEST(IOVector, aligned_split) {
-    IOVector bc;
-    bc.append(create_block("foo"));
-    bc.append(create_block("bar"));
-    bc.append(create_block("baz"));
-    ASSERT_EQ(9ULL, bc.size());
-
-    IOVector foo = bc.take_front(3);
-    ASSERT_EQ(3ULL, foo.size());
-    ASSERT_EQ(create_block("foo"), foo.coalesce());
-
-    IOVector bar = bc.take_front(3);
-    ASSERT_EQ(3ULL, bar.size());
-    ASSERT_EQ(create_block("bar"), bar.coalesce());
-
-    IOVector baz = bc.take_front(3);
-    ASSERT_EQ(3ULL, baz.size());
-    ASSERT_EQ(create_block("baz"), baz.coalesce());
-
-    ASSERT_EQ(0ULL, bc.size());
-}
-
-TEST(IOVector, misaligned_split) {
-    IOVector bc;
-    bc.append(create_block("foo"));
-    bc.append(create_block("bar"));
-    bc.append(create_block("baz"));
-    bc.append(create_block("qux"));
-    bc.append(create_block("quux"));
-
-    // Aligned left, misaligned right, across multiple blocks.
-    IOVector foob = bc.take_front(4);
-    ASSERT_EQ(4ULL, foob.size());
-    ASSERT_EQ(create_block("foob"), foob.coalesce());
-
-    // Misaligned left, misaligned right, in one block.
-    IOVector a = bc.take_front(1);
-    ASSERT_EQ(1ULL, a.size());
-    ASSERT_EQ(create_block("a"), a.coalesce());
-
-    // Misaligned left, misaligned right, across two blocks.
-    IOVector rba = bc.take_front(3);
-    ASSERT_EQ(3ULL, rba.size());
-    ASSERT_EQ(create_block("rba"), rba.coalesce());
-
-    // Misaligned left, misaligned right, across three blocks.
-    IOVector zquxquu = bc.take_front(7);
-    ASSERT_EQ(7ULL, zquxquu.size());
-    ASSERT_EQ(create_block("zquxquu"), zquxquu.coalesce());
-
-    ASSERT_EQ(1ULL, bc.size());
-    ASSERT_EQ(create_block("x"), bc.coalesce());
-}
diff --git a/base/Android.bp b/base/Android.bp
index 4556f9b..3d96e42 100644
--- a/base/Android.bp
+++ b/base/Android.bp
@@ -108,6 +108,7 @@
             enabled: true,
         },
     },
+    min_sdk_version: "29",
 }
 
 cc_library {
@@ -133,7 +134,6 @@
         "//apex_available:anyapex",
         "//apex_available:platform",
     ],
-    min_sdk_version: "29",
 }
 
 cc_library_static {
diff --git a/libnetutils/Android.bp b/libnetutils/Android.bp
index 268496f..65371fa 100644
--- a/libnetutils/Android.bp
+++ b/libnetutils/Android.bp
@@ -23,6 +23,21 @@
     export_include_dirs: ["include"],
 }
 
+cc_library_static {
+    name: "libipchecksum",
+
+    srcs: [
+        "checksum.c",
+    ],
+
+    cflags: [
+        "-Wall",
+        "-Werror",
+    ],
+
+    export_include_dirs: ["include"],
+}
+
 cc_binary {
     name: "dhcpdbg",
 
diff --git a/libstats/pull/Android.bp b/libstats/pull/Android.bp
index a8b4a4f..6d6b466 100644
--- a/libstats/pull/Android.bp
+++ b/libstats/pull/Android.bp
@@ -70,6 +70,7 @@
     ],
     visibility: [
         "//frameworks/base/apex/statsd/tests/libstatspull",
+        "//packages/modules/StatsD/apex/tests/libstatspull",
     ],
 }
 
diff --git a/libstats/socket/Android.bp b/libstats/socket/Android.bp
index bf79ea2..c39d475 100644
--- a/libstats/socket/Android.bp
+++ b/libstats/socket/Android.bp
@@ -78,6 +78,8 @@
     visibility: [
         "//frameworks/base/apex/statsd/tests/libstatspull",
         "//frameworks/base/cmds/statsd",
+        "//packages/modules/StatsD/apex/tests/libstatspull",
+        "//packages/modules/StatsD/bin",
     ],
 }
 
diff --git a/libstats/socket/stats_event.c b/libstats/socket/stats_event.c
index f3e8087..dcd34aa 100644
--- a/libstats/socket/stats_event.c
+++ b/libstats/socket/stats_event.c
@@ -232,14 +232,19 @@
 
 void AStatsEvent_writeByteArray(AStatsEvent* event, const uint8_t* buf, size_t numBytes) {
     start_field(event, BYTE_ARRAY_TYPE);
+    if (buf == NULL) {
+        numBytes = 0;
+    }
     append_int32(event, numBytes);
-    append_byte_array(event, buf, numBytes);
+    if (numBytes > 0) {
+        append_byte_array(event, buf, numBytes);
+    }
 }
 
 // Value is assumed to be encoded using UTF8
 void AStatsEvent_writeString(AStatsEvent* event, const char* value) {
     start_field(event, STRING_TYPE);
-    append_string(event, value);
+    append_string(event, value == NULL ? "" : value);
 }
 
 // Tags are assumed to be encoded using UTF8
@@ -255,7 +260,7 @@
 
     for (uint8_t i = 0; i < numNodes; i++) {
         append_int32(event, uids[i]);
-        append_string(event, tags[i]);
+        append_string(event, tags[i] == NULL ? "" : tags[i]);
     }
 }
 
diff --git a/libstats/socket/tests/stats_event_test.cpp b/libstats/socket/tests/stats_event_test.cpp
index 9a1fac8..2f9ccdc 100644
--- a/libstats/socket/tests/stats_event_test.cpp
+++ b/libstats/socket/tests/stats_event_test.cpp
@@ -183,6 +183,31 @@
     AStatsEvent_release(event);
 }
 
+TEST(StatsEventTest, TestNullString) {
+    uint32_t atomId = 100;
+    char* str = nullptr;
+
+    int64_t startTime = android::elapsedRealtimeNano();
+    AStatsEvent* event = AStatsEvent_obtain();
+    AStatsEvent_setAtomId(event, atomId);
+    AStatsEvent_writeString(event, str);
+    AStatsEvent_build(event);
+    int64_t endTime = android::elapsedRealtimeNano();
+
+    size_t bufferSize;
+    uint8_t* buffer = AStatsEvent_getBuffer(event, &bufferSize);
+    uint8_t* bufferEnd = buffer + bufferSize;
+
+    checkMetadata(&buffer, /*numElements=*/1, startTime, endTime, atomId);
+
+    checkTypeHeader(&buffer, STRING_TYPE);
+    checkString(&buffer, "");
+
+    EXPECT_EQ(buffer, bufferEnd);  // ensure that we have read the entire buffer
+    EXPECT_EQ(AStatsEvent_getErrors(event), 0);
+    AStatsEvent_release(event);
+}
+
 TEST(StatsEventTest, TestByteArrays) {
     uint32_t atomId = 100;
     vector<uint8_t> message = {'b', 'y', 't', '\0', 'e', 's'};
@@ -208,6 +233,32 @@
     AStatsEvent_release(event);
 }
 
+TEST(StatsEventTest, TestNullByteArrays) {
+    uint32_t atomId = 100;
+    uint8_t* buf = nullptr;
+    vector<uint8_t> message;
+
+    int64_t startTime = android::elapsedRealtimeNano();
+    AStatsEvent* event = AStatsEvent_obtain();
+    AStatsEvent_setAtomId(event, atomId);
+    AStatsEvent_writeByteArray(event, buf, 2);
+    AStatsEvent_build(event);
+    int64_t endTime = android::elapsedRealtimeNano();
+
+    size_t bufferSize;
+    uint8_t* buffer = AStatsEvent_getBuffer(event, &bufferSize);
+    uint8_t* bufferEnd = buffer + bufferSize;
+
+    checkMetadata(&buffer, /*numElements=*/1, startTime, endTime, atomId);
+
+    checkTypeHeader(&buffer, BYTE_ARRAY_TYPE);
+    checkByteArray(&buffer, message);
+
+    EXPECT_EQ(buffer, bufferEnd);  // ensure that we have read the entire buffer
+    EXPECT_EQ(AStatsEvent_getErrors(event), 0);
+    AStatsEvent_release(event);
+}
+
 TEST(StatsEventTest, TestAttributionChains) {
     uint32_t atomId = 100;
 
@@ -217,8 +268,13 @@
     const char* cTags[numNodes];
     for (int i = 0; i < (int)numNodes; i++) {
         uids[i] = i;
-        tags.push_back("test" + std::to_string(i));
-        cTags[i] = tags[i].c_str();
+        if (0 == i) {
+            tags.push_back("");
+            cTags[i] = nullptr;
+        } else {
+            tags.push_back("test" + std::to_string(i));
+            cTags[i] = tags[i].c_str();
+        }
     }
 
     int64_t startTime = android::elapsedRealtimeNano();
