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 ed2cf25..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
deleted file mode 100644
index a8b4a4f..0000000
--- a/libstats/pull/Android.bp
+++ /dev/null
@@ -1,110 +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.
-//
-
-// ==========================================================
-// Native library to register a pull atom callback with statsd
-// ==========================================================
-cc_defaults {
-    name: "libstatspull_defaults",
-    srcs: [
-        "stats_pull_atom_callback.cpp",
-    ],
-    cflags: [
-        "-Wall",
-        "-Werror",
-    ],
-    export_include_dirs: ["include"],
-    shared_libs: [
-        "libbinder_ndk",
-        "liblog",
-        "libstatssocket",
-    ],
-    static_libs: [
-        "libutils",
-        "statsd-aidl-ndk_platform",
-    ],
-}
-cc_library_shared {
-    name: "libstatspull",
-    defaults: [
-        "libstatspull_defaults"
-    ],
-    // enumerate stable entry points for APEX use
-    stubs: {
-        symbol_file: "libstatspull.map.txt",
-        versions: [
-            "30",
-        ],
-    },
-    apex_available: [
-        "com.android.os.statsd",
-        "test_com.android.os.statsd",
-    ],
-
-    stl: "libc++_static",
-
-    // TODO(b/151102177): Enable it when the build error is fixed.
-    header_abi_checker: {
-        enabled: false,
-    },
-}
-
-// ONLY USE IN TESTS.
-cc_library_static {
-    name: "libstatspull_private",
-    defaults: [
-        "libstatspull_defaults",
-    ],
-    visibility: [
-        "//frameworks/base/apex/statsd/tests/libstatspull",
-    ],
-}
-
-// Note: These unit tests only test PullAtomMetadata.
-// For full E2E tests of libstatspull, use LibStatsPullTests
-cc_test {
-    name: "libstatspull_test",
-    srcs: [
-        "tests/pull_atom_metadata_test.cpp",
-    ],
-    shared_libs: [
-        "libstatspull",
-        "libstatssocket",
-    ],
-    test_suites: ["general-tests", "mts"],
-    test_config: "libstatspull_test.xml",
-
-    //TODO(b/153588990): Remove when the build system properly separates 
-    //32bit and 64bit architectures.
-    compile_multilib: "both",
-    multilib: {
-        lib64: {
-            suffix: "64",
-        },
-        lib32: {
-            suffix: "32",
-        },
-    },
-    cflags: [
-        "-Wall",
-        "-Werror",
-        "-Wno-missing-field-initializers",
-        "-Wno-unused-variable",
-        "-Wno-unused-function",
-        "-Wno-unused-parameter",
-    ],
-    require_root: true,
-}
diff --git a/libstats/pull/OWNERS b/libstats/pull/OWNERS
deleted file mode 100644
index 7855774..0000000
--- a/libstats/pull/OWNERS
+++ /dev/null
@@ -1,7 +0,0 @@
-joeo@google.com
-muhammadq@google.com
-ruchirr@google.com
-singhtejinder@google.com
-tsaichristine@google.com
-yaochen@google.com
-yro@google.com
diff --git a/libstats/pull/TEST_MAPPING b/libstats/pull/TEST_MAPPING
deleted file mode 100644
index 76f4f02..0000000
--- a/libstats/pull/TEST_MAPPING
+++ /dev/null
@@ -1,7 +0,0 @@
-{
-  "presubmit" : [
-    {
-      "name" : "libstatspull_test"
-    }
-  ]
-}
\ No newline at end of file
diff --git a/libstats/pull/include/stats_pull_atom_callback.h b/libstats/pull/include/stats_pull_atom_callback.h
deleted file mode 100644
index 17df584..0000000
--- a/libstats/pull/include/stats_pull_atom_callback.h
+++ /dev/null
@@ -1,170 +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 <stats_event.h>
-
-#include <stdbool.h>
-#include <stdint.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * Opaque struct representing the metadata for registering an AStatsManager_PullAtomCallback.
- */
-struct AStatsManager_PullAtomMetadata;
-typedef struct AStatsManager_PullAtomMetadata AStatsManager_PullAtomMetadata;
-
-/**
- * Allocate and initialize new PullAtomMetadata.
- *
- * Must call AStatsManager_PullAtomMetadata_release to free the memory.
- */
-AStatsManager_PullAtomMetadata* AStatsManager_PullAtomMetadata_obtain();
-
-/**
- * Frees the memory held by this PullAtomMetadata
- *
- * After calling this, the PullAtomMetadata must not be used or modified in any way.
- */
-void AStatsManager_PullAtomMetadata_release(AStatsManager_PullAtomMetadata* metadata);
-
-/**
- * Set the cool down time of the pull in milliseconds. If two successive pulls are issued
- * within the cool down, a cached version of the first will be used for the second. The minimum
- * allowed cool down is one second.
- */
-void AStatsManager_PullAtomMetadata_setCoolDownMillis(AStatsManager_PullAtomMetadata* metadata,
-                                                      int64_t cool_down_millis);
-
-/**
- * Get the cool down time of the pull in milliseconds.
- */
-int64_t AStatsManager_PullAtomMetadata_getCoolDownMillis(AStatsManager_PullAtomMetadata* metadata);
-
-/**
- * Set the maximum time the pull can take in milliseconds.
- * The maximum allowed timeout is 10 seconds.
- */
-void AStatsManager_PullAtomMetadata_setTimeoutMillis(AStatsManager_PullAtomMetadata* metadata,
-                                                     int64_t timeout_millis);
-
-/**
- * Get the maximum time the pull can take in milliseconds.
- */
-int64_t AStatsManager_PullAtomMetadata_getTimeoutMillis(AStatsManager_PullAtomMetadata* metadata);
-
-/**
- * Set the additive fields of this pulled atom.
- *
- * This is only applicable for atoms which have a uid field. When tasks are run in
- * isolated processes, the data will be attributed to the host uid. Additive fields
- * will be combined when the non-additive fields are the same.
- */
-void AStatsManager_PullAtomMetadata_setAdditiveFields(AStatsManager_PullAtomMetadata* metadata,
-                                                      int32_t* additive_fields, int32_t num_fields);
-
-/**
- * Get the number of additive fields for this pulled atom. This is intended to be called before
- * AStatsManager_PullAtomMetadata_getAdditiveFields to determine the size of the array.
- */
-int32_t AStatsManager_PullAtomMetadata_getNumAdditiveFields(
-        AStatsManager_PullAtomMetadata* metadata);
-
-/**
- * Get the additive fields of this pulled atom.
- *
- * \param fields an output parameter containing the additive fields for this PullAtomMetadata.
- *               Fields is an array and it is assumed that it is at least as large as the number of
- *               additive fields, which can be obtained by calling
- *               AStatsManager_PullAtomMetadata_getNumAdditiveFields.
- */
-void AStatsManager_PullAtomMetadata_getAdditiveFields(AStatsManager_PullAtomMetadata* metadata,
-                                                      int32_t* fields);
-
-/**
- * Return codes for the result of a pull.
- */
-typedef int32_t AStatsManager_PullAtomCallbackReturn;
-enum {
-    // Value indicating that this pull was successful and that the result should be used.
-    AStatsManager_PULL_SUCCESS = 0,
-    // Value indicating that this pull was unsuccessful and that the result should not be used.
-    AStatsManager_PULL_SKIP = 1,
-};
-
-/**
- * Opaque struct representing a list of AStatsEvent objects.
- */
-struct AStatsEventList;
-typedef struct AStatsEventList AStatsEventList;
-
-/**
- * Appends and returns an AStatsEvent to the end of the AStatsEventList.
- *
- * If an AStatsEvent is obtained in this manner, the memory is internally managed and
- * AStatsEvent_release does not need to be called. The lifetime of the AStatsEvent is that of the
- * AStatsEventList.
- *
- * The AStatsEvent does still need to be built by calling AStatsEvent_build.
- */
-AStatsEvent* AStatsEventList_addStatsEvent(AStatsEventList* pull_data);
-
-/**
- * Callback interface for pulling atoms requested by the stats service.
- *
- * \param atom_tag the tag of the atom to pull.
- * \param data an output parameter in which the caller should fill the results of the pull. This
- *             param cannot be NULL and it's lifetime is as long as the execution of the callback.
- *             It must not be accessed or modified after returning from the callback.
- * \param cookie the opaque pointer passed in AStatsManager_registerPullAtomCallback.
- * \return AStatsManager_PULL_SUCCESS if the pull was successful, or AStatsManager_PULL_SKIP if not.
- */
-typedef AStatsManager_PullAtomCallbackReturn (*AStatsManager_PullAtomCallback)(
-        int32_t atom_tag, AStatsEventList* data, void* cookie);
-/**
- * Sets a callback for an atom when that atom is to be pulled. The stats service will
- * invoke the callback when the stats service determines that this atom needs to be
- * pulled.
- *
- * Requires the REGISTER_STATS_PULL_ATOM permission.
- *
- * \param atom_tag          The tag of the atom for this pull atom callback.
- * \param metadata          Optional metadata specifying the timeout, cool down time, and
- *                          additive fields for mapping isolated to host uids.
- *                          This param is nullable, in which case defaults will be used.
- * \param callback          The callback to be invoked when the stats service pulls the atom.
- * \param cookie            A pointer that will be passed back to the callback.
- *                          It has no meaning to statsd.
- */
-void AStatsManager_setPullAtomCallback(int32_t atom_tag, AStatsManager_PullAtomMetadata* metadata,
-                                       AStatsManager_PullAtomCallback callback, void* cookie);
-
-/**
- * Clears a callback for an atom when that atom is to be pulled. Note that any ongoing
- * pulls will still occur.
- *
- * Requires the REGISTER_STATS_PULL_ATOM permission.
- *
- * \param atomTag           The tag of the atom of which to unregister
- */
-void AStatsManager_clearPullAtomCallback(int32_t atom_tag);
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/libstats/pull/libstatspull.map.txt b/libstats/pull/libstatspull.map.txt
deleted file mode 100644
index e0e851a..0000000
--- a/libstats/pull/libstatspull.map.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-LIBSTATSPULL {
-    global:
-        AStatsManager_PullAtomMetadata_obtain; # apex # introduced=30
-        AStatsManager_PullAtomMetadata_release; # apex # introduced=30
-        AStatsManager_PullAtomMetadata_setCoolDownMillis; # apex # introduced=30
-        AStatsManager_PullAtomMetadata_getCoolDownMillis; # apex # introduced=30
-        AStatsManager_PullAtomMetadata_setTimeoutMillis; # apex # introduced=30
-        AStatsManager_PullAtomMetadata_getTimeoutMillis; # apex # introduced=30
-        AStatsManager_PullAtomMetadata_setAdditiveFields; # apex # introduced=30
-        AStatsManager_PullAtomMetadata_getNumAdditiveFields; # apex # introduced=30
-        AStatsManager_PullAtomMetadata_getAdditiveFields; # apex # introduced=30
-        AStatsEventList_addStatsEvent; # apex # introduced=30
-        AStatsManager_setPullAtomCallback; # apex # introduced=30
-        AStatsManager_clearPullAtomCallback; # apex # introduced=30
-    local:
-        *;
-};
diff --git a/libstats/pull/libstatspull_test.xml b/libstats/pull/libstatspull_test.xml
deleted file mode 100644
index 233fc1f..0000000
--- a/libstats/pull/libstatspull_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.
--->
-<configuration description="Runs libstatspull_test.">
-    <option name="test-suite-tag" value="apct" />
-    <option name="test-suite-tag" value="apct-native" />
-    <option name="test-suite-tag" value="mts" />
-
-    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
-
-    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
-       <option name="cleanup" value="true" />
-       <option name="push" value="libstatspull_test->/data/local/tmp/libstatspull_test" />
-       <option name="append-bitness" value="true" />
-    </target_preparer>
-
-    <test class="com.android.tradefed.testtype.GTest" >
-        <option name="native-test-device-path" value="/data/local/tmp" />
-        <option name="module-name" value="libstatspull_test" />
-    </test>
-
-    <object type="module_controller" class="com.android.tradefed.testtype.suite.module.MainlineTestModuleController">
-        <option name="mainline-module-package-name" value="com.google.android.os.statsd" />
-    </object>
-</configuration>
diff --git a/libstats/pull/stats_pull_atom_callback.cpp b/libstats/pull/stats_pull_atom_callback.cpp
deleted file mode 100644
index 478cae7..0000000
--- a/libstats/pull/stats_pull_atom_callback.cpp
+++ /dev/null
@@ -1,260 +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 <map>
-#include <thread>
-#include <vector>
-
-#include <stats_event.h>
-#include <stats_pull_atom_callback.h>
-
-#include <aidl/android/os/BnPullAtomCallback.h>
-#include <aidl/android/os/IPullAtomResultReceiver.h>
-#include <aidl/android/os/IStatsd.h>
-#include <aidl/android/util/StatsEventParcel.h>
-#include <android/binder_auto_utils.h>
-#include <android/binder_ibinder.h>
-#include <android/binder_manager.h>
-
-using Status = ::ndk::ScopedAStatus;
-using aidl::android::os::BnPullAtomCallback;
-using aidl::android::os::IPullAtomResultReceiver;
-using aidl::android::os::IStatsd;
-using aidl::android::util::StatsEventParcel;
-using ::ndk::SharedRefBase;
-
-struct AStatsEventList {
-    std::vector<AStatsEvent*> data;
-};
-
-AStatsEvent* AStatsEventList_addStatsEvent(AStatsEventList* pull_data) {
-    AStatsEvent* event = AStatsEvent_obtain();
-    pull_data->data.push_back(event);
-    return event;
-}
-
-static const int64_t DEFAULT_COOL_DOWN_MILLIS = 1000LL;  // 1 second.
-static const int64_t DEFAULT_TIMEOUT_MILLIS = 2000LL;    // 2 seconds.
-
-struct AStatsManager_PullAtomMetadata {
-    int64_t cool_down_millis;
-    int64_t timeout_millis;
-    std::vector<int32_t> additive_fields;
-};
-
-AStatsManager_PullAtomMetadata* AStatsManager_PullAtomMetadata_obtain() {
-    AStatsManager_PullAtomMetadata* metadata = new AStatsManager_PullAtomMetadata();
-    metadata->cool_down_millis = DEFAULT_COOL_DOWN_MILLIS;
-    metadata->timeout_millis = DEFAULT_TIMEOUT_MILLIS;
-    metadata->additive_fields = std::vector<int32_t>();
-    return metadata;
-}
-
-void AStatsManager_PullAtomMetadata_release(AStatsManager_PullAtomMetadata* metadata) {
-    delete metadata;
-}
-
-void AStatsManager_PullAtomMetadata_setCoolDownMillis(AStatsManager_PullAtomMetadata* metadata,
-                                                      int64_t cool_down_millis) {
-    metadata->cool_down_millis = cool_down_millis;
-}
-
-int64_t AStatsManager_PullAtomMetadata_getCoolDownMillis(AStatsManager_PullAtomMetadata* metadata) {
-    return metadata->cool_down_millis;
-}
-
-void AStatsManager_PullAtomMetadata_setTimeoutMillis(AStatsManager_PullAtomMetadata* metadata,
-                                                     int64_t timeout_millis) {
-    metadata->timeout_millis = timeout_millis;
-}
-
-int64_t AStatsManager_PullAtomMetadata_getTimeoutMillis(AStatsManager_PullAtomMetadata* metadata) {
-    return metadata->timeout_millis;
-}
-
-void AStatsManager_PullAtomMetadata_setAdditiveFields(AStatsManager_PullAtomMetadata* metadata,
-                                                      int32_t* additive_fields,
-                                                      int32_t num_fields) {
-    metadata->additive_fields.assign(additive_fields, additive_fields + num_fields);
-}
-
-int32_t AStatsManager_PullAtomMetadata_getNumAdditiveFields(
-        AStatsManager_PullAtomMetadata* metadata) {
-    return metadata->additive_fields.size();
-}
-
-void AStatsManager_PullAtomMetadata_getAdditiveFields(AStatsManager_PullAtomMetadata* metadata,
-                                                      int32_t* fields) {
-    std::copy(metadata->additive_fields.begin(), metadata->additive_fields.end(), fields);
-}
-
-class StatsPullAtomCallbackInternal : public BnPullAtomCallback {
-  public:
-    StatsPullAtomCallbackInternal(const AStatsManager_PullAtomCallback callback, void* cookie,
-                                  const int64_t coolDownMillis, const int64_t timeoutMillis,
-                                  const std::vector<int32_t> additiveFields)
-        : mCallback(callback),
-          mCookie(cookie),
-          mCoolDownMillis(coolDownMillis),
-          mTimeoutMillis(timeoutMillis),
-          mAdditiveFields(additiveFields) {}
-
-    Status onPullAtom(int32_t atomTag,
-                      const std::shared_ptr<IPullAtomResultReceiver>& resultReceiver) override {
-        AStatsEventList statsEventList;
-        int successInt = mCallback(atomTag, &statsEventList, mCookie);
-        bool success = successInt == AStatsManager_PULL_SUCCESS;
-
-        // Convert stats_events into StatsEventParcels.
-        std::vector<StatsEventParcel> parcels;
-        for (int i = 0; i < statsEventList.data.size(); i++) {
-            size_t size;
-            uint8_t* buffer = AStatsEvent_getBuffer(statsEventList.data[i], &size);
-
-            StatsEventParcel p;
-            // vector.assign() creates a copy, but this is inevitable unless
-            // stats_event.h/c uses a vector as opposed to a buffer.
-            p.buffer.assign(buffer, buffer + size);
-            parcels.push_back(std::move(p));
-        }
-
-        Status status = resultReceiver->pullFinished(atomTag, success, parcels);
-        if (!status.isOk()) {
-            std::vector<StatsEventParcel> emptyParcels;
-            resultReceiver->pullFinished(atomTag, /*success=*/false, emptyParcels);
-        }
-        for (int i = 0; i < statsEventList.data.size(); i++) {
-            AStatsEvent_release(statsEventList.data[i]);
-        }
-        return Status::ok();
-    }
-
-    int64_t getCoolDownMillis() const { return mCoolDownMillis; }
-    int64_t getTimeoutMillis() const { return mTimeoutMillis; }
-    const std::vector<int32_t>& getAdditiveFields() const { return mAdditiveFields; }
-
-  private:
-    const AStatsManager_PullAtomCallback mCallback;
-    void* mCookie;
-    const int64_t mCoolDownMillis;
-    const int64_t mTimeoutMillis;
-    const std::vector<int32_t> mAdditiveFields;
-};
-
-static std::mutex pullAtomMutex;
-static std::shared_ptr<IStatsd> sStatsd = nullptr;
-
-static std::map<int32_t, std::shared_ptr<StatsPullAtomCallbackInternal>> mPullers;
-static std::shared_ptr<IStatsd> getStatsService();
-
-static void binderDied(void* /*cookie*/) {
-    {
-        std::lock_guard<std::mutex> lock(pullAtomMutex);
-        sStatsd = nullptr;
-    }
-
-    std::shared_ptr<IStatsd> statsService = getStatsService();
-    if (statsService == nullptr) {
-        return;
-    }
-
-    // Since we do not want to make an IPC with the lock held, we first create a
-    // copy of the data with the lock held before iterating through the map.
-    std::map<int32_t, std::shared_ptr<StatsPullAtomCallbackInternal>> pullersCopy;
-    {
-        std::lock_guard<std::mutex> lock(pullAtomMutex);
-        pullersCopy = mPullers;
-    }
-    for (const auto& it : pullersCopy) {
-        statsService->registerNativePullAtomCallback(it.first, it.second->getCoolDownMillis(),
-                                                     it.second->getTimeoutMillis(),
-                                                     it.second->getAdditiveFields(), it.second);
-    }
-}
-
-static ::ndk::ScopedAIBinder_DeathRecipient sDeathRecipient(
-        AIBinder_DeathRecipient_new(binderDied));
-
-static std::shared_ptr<IStatsd> getStatsService() {
-    std::lock_guard<std::mutex> lock(pullAtomMutex);
-    if (!sStatsd) {
-        // Fetch statsd
-        ::ndk::SpAIBinder binder(AServiceManager_getService("stats"));
-        sStatsd = IStatsd::fromBinder(binder);
-        if (sStatsd) {
-            AIBinder_linkToDeath(binder.get(), sDeathRecipient.get(), /*cookie=*/nullptr);
-        }
-    }
-    return sStatsd;
-}
-
-void registerStatsPullAtomCallbackBlocking(int32_t atomTag,
-                                           std::shared_ptr<StatsPullAtomCallbackInternal> cb) {
-    const std::shared_ptr<IStatsd> statsService = getStatsService();
-    if (statsService == nullptr) {
-        // Statsd not available
-        return;
-    }
-
-    statsService->registerNativePullAtomCallback(
-            atomTag, cb->getCoolDownMillis(), cb->getTimeoutMillis(), cb->getAdditiveFields(), cb);
-}
-
-void unregisterStatsPullAtomCallbackBlocking(int32_t atomTag) {
-    const std::shared_ptr<IStatsd> statsService = getStatsService();
-    if (statsService == nullptr) {
-        // Statsd not available
-        return;
-    }
-
-    statsService->unregisterNativePullAtomCallback(atomTag);
-}
-
-void AStatsManager_setPullAtomCallback(int32_t atom_tag, AStatsManager_PullAtomMetadata* metadata,
-                                       AStatsManager_PullAtomCallback callback, void* cookie) {
-    int64_t coolDownMillis =
-            metadata == nullptr ? DEFAULT_COOL_DOWN_MILLIS : metadata->cool_down_millis;
-    int64_t timeoutMillis = metadata == nullptr ? DEFAULT_TIMEOUT_MILLIS : metadata->timeout_millis;
-
-    std::vector<int32_t> additiveFields;
-    if (metadata != nullptr) {
-        additiveFields = metadata->additive_fields;
-    }
-
-    std::shared_ptr<StatsPullAtomCallbackInternal> callbackBinder =
-            SharedRefBase::make<StatsPullAtomCallbackInternal>(callback, cookie, coolDownMillis,
-                                                               timeoutMillis, additiveFields);
-
-    {
-        std::lock_guard<std::mutex> lg(pullAtomMutex);
-        // Always add to the map. If statsd is dead, we will add them when it comes back.
-        mPullers[atom_tag] = callbackBinder;
-    }
-
-    std::thread registerThread(registerStatsPullAtomCallbackBlocking, atom_tag, callbackBinder);
-    registerThread.detach();
-}
-
-void AStatsManager_clearPullAtomCallback(int32_t atom_tag) {
-    {
-        std::lock_guard<std::mutex> lg(pullAtomMutex);
-        // Always remove the puller from our map.
-        // If statsd is down, we will not register it when it comes back.
-        mPullers.erase(atom_tag);
-    }
-    std::thread unregisterThread(unregisterStatsPullAtomCallbackBlocking, atom_tag);
-    unregisterThread.detach();
-}
diff --git a/libstats/pull/tests/pull_atom_metadata_test.cpp b/libstats/pull/tests/pull_atom_metadata_test.cpp
deleted file mode 100644
index abc8e47..0000000
--- a/libstats/pull/tests/pull_atom_metadata_test.cpp
+++ /dev/null
@@ -1,92 +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 <stats_pull_atom_callback.h>
-
-namespace {
-
-static const int64_t DEFAULT_COOL_DOWN_MILLIS = 1000LL;  // 1 second.
-static const int64_t DEFAULT_TIMEOUT_MILLIS = 2000LL;    // 2 seconds.
-
-}  // anonymous namespace
-
-TEST(AStatsManager_PullAtomMetadataTest, TestEmpty) {
-    AStatsManager_PullAtomMetadata* metadata = AStatsManager_PullAtomMetadata_obtain();
-    EXPECT_EQ(AStatsManager_PullAtomMetadata_getCoolDownMillis(metadata), DEFAULT_COOL_DOWN_MILLIS);
-    EXPECT_EQ(AStatsManager_PullAtomMetadata_getTimeoutMillis(metadata), DEFAULT_TIMEOUT_MILLIS);
-    EXPECT_EQ(AStatsManager_PullAtomMetadata_getNumAdditiveFields(metadata), 0);
-    AStatsManager_PullAtomMetadata_release(metadata);
-}
-
-TEST(AStatsManager_PullAtomMetadataTest, TestSetTimeoutMillis) {
-    int64_t timeoutMillis = 500;
-    AStatsManager_PullAtomMetadata* metadata = AStatsManager_PullAtomMetadata_obtain();
-    AStatsManager_PullAtomMetadata_setTimeoutMillis(metadata, timeoutMillis);
-    EXPECT_EQ(AStatsManager_PullAtomMetadata_getCoolDownMillis(metadata), DEFAULT_COOL_DOWN_MILLIS);
-    EXPECT_EQ(AStatsManager_PullAtomMetadata_getTimeoutMillis(metadata), timeoutMillis);
-    EXPECT_EQ(AStatsManager_PullAtomMetadata_getNumAdditiveFields(metadata), 0);
-    AStatsManager_PullAtomMetadata_release(metadata);
-}
-
-TEST(AStatsManager_PullAtomMetadataTest, TestSetCoolDownMillis) {
-    int64_t coolDownMillis = 10000;
-    AStatsManager_PullAtomMetadata* metadata = AStatsManager_PullAtomMetadata_obtain();
-    AStatsManager_PullAtomMetadata_setCoolDownMillis(metadata, coolDownMillis);
-    EXPECT_EQ(AStatsManager_PullAtomMetadata_getCoolDownMillis(metadata), coolDownMillis);
-    EXPECT_EQ(AStatsManager_PullAtomMetadata_getTimeoutMillis(metadata), DEFAULT_TIMEOUT_MILLIS);
-    EXPECT_EQ(AStatsManager_PullAtomMetadata_getNumAdditiveFields(metadata), 0);
-    AStatsManager_PullAtomMetadata_release(metadata);
-}
-
-TEST(AStatsManager_PullAtomMetadataTest, TestSetAdditiveFields) {
-    const int numFields = 3;
-    int inputFields[numFields] = {2, 4, 6};
-    AStatsManager_PullAtomMetadata* metadata = AStatsManager_PullAtomMetadata_obtain();
-    AStatsManager_PullAtomMetadata_setAdditiveFields(metadata, inputFields, numFields);
-    EXPECT_EQ(AStatsManager_PullAtomMetadata_getCoolDownMillis(metadata), DEFAULT_COOL_DOWN_MILLIS);
-    EXPECT_EQ(AStatsManager_PullAtomMetadata_getTimeoutMillis(metadata), DEFAULT_TIMEOUT_MILLIS);
-    EXPECT_EQ(AStatsManager_PullAtomMetadata_getNumAdditiveFields(metadata), numFields);
-    int outputFields[numFields];
-    AStatsManager_PullAtomMetadata_getAdditiveFields(metadata, outputFields);
-    for (int i = 0; i < numFields; i++) {
-        EXPECT_EQ(inputFields[i], outputFields[i]);
-    }
-    AStatsManager_PullAtomMetadata_release(metadata);
-}
-
-TEST(AStatsManager_PullAtomMetadataTest, TestSetAllElements) {
-    int64_t timeoutMillis = 500;
-    int64_t coolDownMillis = 10000;
-    const int numFields = 3;
-    int inputFields[numFields] = {2, 4, 6};
-
-    AStatsManager_PullAtomMetadata* metadata = AStatsManager_PullAtomMetadata_obtain();
-    AStatsManager_PullAtomMetadata_setTimeoutMillis(metadata, timeoutMillis);
-    AStatsManager_PullAtomMetadata_setCoolDownMillis(metadata, coolDownMillis);
-    AStatsManager_PullAtomMetadata_setAdditiveFields(metadata, inputFields, numFields);
-
-    EXPECT_EQ(AStatsManager_PullAtomMetadata_getCoolDownMillis(metadata), coolDownMillis);
-    EXPECT_EQ(AStatsManager_PullAtomMetadata_getTimeoutMillis(metadata), timeoutMillis);
-    EXPECT_EQ(AStatsManager_PullAtomMetadata_getNumAdditiveFields(metadata), numFields);
-    int outputFields[numFields];
-    AStatsManager_PullAtomMetadata_getAdditiveFields(metadata, outputFields);
-    for (int i = 0; i < numFields; i++) {
-        EXPECT_EQ(inputFields[i], outputFields[i]);
-    }
-    AStatsManager_PullAtomMetadata_release(metadata);
-}
diff --git a/libstats/socket/Android.bp b/libstats/socket/Android.bp
deleted file mode 100644
index bf79ea2..0000000
--- a/libstats/socket/Android.bp
+++ /dev/null
@@ -1,124 +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.
-//
-
-// =========================================================================
-// Native library to write stats log to statsd socket on Android R and later
-// =========================================================================
-cc_defaults {
-    name: "libstatssocket_defaults",
-    srcs: [
-        "stats_buffer_writer.c",
-        "stats_event.c",
-        "stats_socket.c",
-        "statsd_writer.c",
-    ],
-    export_include_dirs: ["include"],
-    static_libs: [
-        "libcutils", // does not expose a stable C API
-    ],
-    cflags: [
-        "-Wall",
-        "-Werror",
-    ],
-}
-
-cc_library {
-    name: "libstatssocket",
-    defaults: [
-        "libstatssocket_defaults",
-    ],
-    host_supported: true,
-    target: {
-        // On android, libstatssocket should only be linked as a shared lib
-        android: {
-            static: {
-                enabled: false,
-            },
-        },
-        host: {
-            shared: {
-                enabled: false,
-            },
-        },
-    },
-    stl: "libc++_static",
-
-    // enumerate stable entry points for APEX use
-    stubs: {
-        symbol_file: "libstatssocket.map.txt",
-        versions: [
-            "30",
-        ],
-    },
-    apex_available: [
-        "com.android.os.statsd",
-        "test_com.android.os.statsd",
-    ],
-}
-
-//TODO (b/149842105): Figure out if there is a better solution for this.
-cc_test_library {
-    name: "libstatssocket_private",
-    defaults: [
-        "libstatssocket_defaults",
-    ],
-    visibility: [
-        "//frameworks/base/apex/statsd/tests/libstatspull",
-        "//frameworks/base/cmds/statsd",
-    ],
-}
-
-cc_library_headers {
-    name: "libstatssocket_headers",
-    export_include_dirs: ["include"],
-    host_supported: true,
-    apex_available: ["com.android.resolv"],
-    min_sdk_version: "29",
-}
-
-cc_test {
-    name: "libstatssocket_test",
-    srcs: [
-        "tests/stats_event_test.cpp",
-        "tests/stats_writer_test.cpp",
-    ],
-    cflags: [
-        "-Wall",
-        "-Werror",
-    ],
-    static_libs: [
-        "libgmock",
-        "libstatssocket_private",
-    ],
-    shared_libs: [
-        "libcutils",
-        "libutils",
-    ],
-    test_suites: ["device-tests", "mts"],
-    test_config: "libstatssocket_test.xml",
-    //TODO(b/153588990): Remove when the build system properly separates.
-    //32bit and 64bit architectures.
-    compile_multilib: "both",
-    multilib: {
-        lib64: {
-            suffix: "64",
-        },
-        lib32: {
-            suffix: "32",
-        },
-    },
-    require_root: true,
-}
diff --git a/libstats/socket/TEST_MAPPING b/libstats/socket/TEST_MAPPING
deleted file mode 100644
index 0224998..0000000
--- a/libstats/socket/TEST_MAPPING
+++ /dev/null
@@ -1,7 +0,0 @@
-{
-  "presubmit" : [
-    {
-      "name" : "libstatssocket_test"
-    }
-  ]
-}
\ No newline at end of file
diff --git a/libstats/socket/include/stats_buffer_writer.h b/libstats/socket/include/stats_buffer_writer.h
deleted file mode 100644
index 5b41f0e..0000000
--- a/libstats/socket/include/stats_buffer_writer.h
+++ /dev/null
@@ -1,30 +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>
-
-#ifdef __cplusplus
-extern "C" {
-#endif  // __CPLUSPLUS
-void stats_log_close();
-int stats_log_is_closed();
-int write_buffer_to_statsd(void* buffer, size_t size, uint32_t atomId);
-#ifdef __cplusplus
-}
-#endif  // __CPLUSPLUS
diff --git a/libstats/socket/include/stats_event.h b/libstats/socket/include/stats_event.h
deleted file mode 100644
index 3d3baf9..0000000
--- a/libstats/socket/include/stats_event.h
+++ /dev/null
@@ -1,164 +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.
- */
-
-#ifndef ANDROID_STATS_LOG_STATS_EVENT_H
-#define ANDROID_STATS_LOG_STATS_EVENT_H
-
-#include <stdbool.h>
-#include <stddef.h>
-#include <stdint.h>
-
-/*
- * Functionality to build and store the buffer sent over the statsd socket.
- * This code defines and encapsulates the socket protocol.
- *
- * Usage:
- *      AStatsEvent* event = AStatsEvent_obtain();
- *
- *      AStatsEvent_setAtomId(event, atomId);
- *      AStatsEvent_addBoolAnnotation(event, 5, false); // atom-level annotation
- *      AStatsEvent_writeInt32(event, 24);
- *      AStatsEvent_addBoolAnnotation(event, 1, true); // annotation for preceding atom field
- *      AStatsEvent_addInt32Annotation(event, 2, 128);
- *      AStatsEvent_writeFloat(event, 2.0);
- *
- *      AStatsEvent_write(event);
- *      AStatsEvent_release(event);
- *
- * Note that calls to add atom fields and annotations should be made in the
- * order that they are defined in the atom.
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif  // __CPLUSPLUS
-
-/**
- * Opaque struct use to represent a StatsEvent. It builds and stores the data that is sent to
- * statsd.
- */
-struct AStatsEvent;
-typedef struct AStatsEvent AStatsEvent;
-
-/**
- * Returns a new AStatsEvent. If you call this function, you must call AStatsEvent_release to free
- * the allocated memory.
- */
-AStatsEvent* AStatsEvent_obtain();
-
-/**
- * Builds and finalizes the AStatsEvent for a pulled event.
- * This should only be called for pulled AStatsEvents.
- *
- * After this function, the StatsEvent must not be modified in any way other than calling release or
- * write.
- *
- * Build can be called multiple times without error.
- * If the event has been built before, this function is a no-op.
- */
-void AStatsEvent_build(AStatsEvent* event);
-
-/**
- * Writes the StatsEvent to the stats log.
- *
- * After calling this, AStatsEvent_release must be called,
- * and is the only function that can be safely called.
- */
-int AStatsEvent_write(AStatsEvent* event);
-
-/**
- * Frees the memory held by this StatsEvent.
- *
- * After calling this, the StatsEvent must not be used or modified in any way.
- */
-void AStatsEvent_release(AStatsEvent* event);
-
-/**
- * Sets the atom id for this StatsEvent.
- *
- * This function should be called immediately after AStatsEvent_obtain. It may
- * be called additional times as well, but subsequent calls will have no effect.
- **/
-void AStatsEvent_setAtomId(AStatsEvent* event, uint32_t atomId);
-
-/**
- * Writes an int32_t field to this StatsEvent.
- **/
-void AStatsEvent_writeInt32(AStatsEvent* event, int32_t value);
-
-/**
- * Writes an int64_t field to this StatsEvent.
- **/
-void AStatsEvent_writeInt64(AStatsEvent* event, int64_t value);
-
-/**
- * Writes a float field to this StatsEvent.
- **/
-void AStatsEvent_writeFloat(AStatsEvent* event, float value);
-
-/**
- * Write a bool field to this StatsEvent.
- **/
-void AStatsEvent_writeBool(AStatsEvent* event, bool value);
-
-/**
- * Write a byte array field to this StatsEvent.
- **/
-void AStatsEvent_writeByteArray(AStatsEvent* event, const uint8_t* buf, size_t numBytes);
-
-/**
- * Write a string field to this StatsEvent.
- *
- * The string must be null-terminated.
- **/
-void AStatsEvent_writeString(AStatsEvent* event, const char* value);
-
-/**
- * Write an attribution chain field to this StatsEvent.
- *
- * The sizes of uids and tags must be equal. The AttributionNode at position i is
- * made up of uids[i] and tags[i].
- *
- * \param uids array of uids in the attribution chain.
- * \param tags array of tags in the attribution chain. Each tag must be null-terminated.
- * \param numNodes the number of AttributionNodes in the attribution chain. This is the length of
- *                 the uids and the tags.
- **/
-void AStatsEvent_writeAttributionChain(AStatsEvent* event, const uint32_t* uids,
-                                       const char* const* tags, uint8_t numNodes);
-
-/**
- * Write a bool annotation for the previous field written.
- **/
-void AStatsEvent_addBoolAnnotation(AStatsEvent* event, uint8_t annotationId, bool value);
-
-/**
- * Write an integer annotation for the previous field written.
- **/
-void AStatsEvent_addInt32Annotation(AStatsEvent* event, uint8_t annotationId, int32_t value);
-
-// Internal/test APIs. Should not be exposed outside of the APEX.
-void AStatsEvent_overwriteTimestamp(AStatsEvent* event, uint64_t timestampNs);
-uint32_t AStatsEvent_getAtomId(AStatsEvent* event);
-// Size is an output parameter.
-uint8_t* AStatsEvent_getBuffer(AStatsEvent* event, size_t* size);
-uint32_t AStatsEvent_getErrors(AStatsEvent* event);
-
-#ifdef __cplusplus
-}
-#endif  // __CPLUSPLUS
-
-#endif  // ANDROID_STATS_LOG_STATS_EVENT_H
diff --git a/libstats/socket/include/stats_socket.h b/libstats/socket/include/stats_socket.h
deleted file mode 100644
index 5a75fc0..0000000
--- a/libstats/socket/include/stats_socket.h
+++ /dev/null
@@ -1,33 +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
-
-/**
- * Helpers to manage the statsd socket.
- **/
-
-#ifdef __cplusplus
-extern "C" {
-#endif  // __CPLUSPLUS
-
-/**
- * Closes the statsd socket file descriptor.
- **/
-void AStatsSocket_close();
-#ifdef __cplusplus
-}
-#endif  // __CPLUSPLUS
diff --git a/libstats/socket/libstatssocket.map.txt b/libstats/socket/libstatssocket.map.txt
deleted file mode 100644
index 5c13904..0000000
--- a/libstats/socket/libstatssocket.map.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-LIBSTATSSOCKET {
-    global:
-        AStatsEvent_obtain; # apex # introduced=30
-        AStatsEvent_build; # apex # introduced=30
-        AStatsEvent_write; # apex # introduced=30
-        AStatsEvent_release; # apex # introduced=30
-        AStatsEvent_setAtomId; # apex # introduced=30
-        AStatsEvent_writeInt32; # apex # introduced=30
-        AStatsEvent_writeInt64; # apex # introduced=30
-        AStatsEvent_writeFloat; # apex # introduced=30
-        AStatsEvent_writeBool; # apex # introduced=30
-        AStatsEvent_writeByteArray; # apex # introduced=30
-        AStatsEvent_writeString; # apex # introduced=30
-        AStatsEvent_writeAttributionChain; # apex # introduced=30
-        AStatsEvent_addBoolAnnotation; # apex # introduced=30
-        AStatsEvent_addInt32Annotation; # apex # introduced=30
-        AStatsSocket_close; # apex # introduced=30
-    local:
-        *;
-};
diff --git a/libstats/socket/libstatssocket_test.xml b/libstats/socket/libstatssocket_test.xml
deleted file mode 100644
index d2694d1..0000000
--- a/libstats/socket/libstatssocket_test.xml
+++ /dev/null
@@ -1,38 +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.
--->
-<configuration description="Runs libstatssocket_test.">
-    <option name="test-suite-tag" value="apct" />
-    <option name="test-suite-tag" value="apct-native" />
-    <option name="test-suite-tag" value="mts" />
-
-    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
-
-    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
-       <option name="cleanup" value="true" />
-       <option name="push" value="libstatssocket_test->/data/local/tmp/libstatssocket_test" />
-       <option name="append-bitness" value="true" />
-    </target_preparer>
-
-    <test class="com.android.tradefed.testtype.GTest" >
-        <option name="native-test-device-path" value="/data/local/tmp" />
-        <option name="module-name" value="libstatssocket_test" />
-    </test>
-
-    <object type="module_controller" class="com.android.tradefed.testtype.suite.module.MainlineTestModuleController">
-        <option name="mainline-module-package-name" value="com.google.android.os.statsd" />
-    </object>
-</configuration>
-
diff --git a/libstats/socket/stats_buffer_writer.c b/libstats/socket/stats_buffer_writer.c
deleted file mode 100644
index 549acdc..0000000
--- a/libstats/socket/stats_buffer_writer.c
+++ /dev/null
@@ -1,126 +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 "include/stats_buffer_writer.h"
-#ifdef __ANDROID__
-#include <cutils/properties.h>
-#endif
-#include <errno.h>
-#include <sys/time.h>
-#include <sys/uio.h>
-#include "statsd_writer.h"
-
-static const uint32_t kStatsEventTag = 1937006964;
-
-extern struct android_log_transport_write statsdLoggerWrite;
-
-static int __write_to_statsd_init(struct iovec* vec, size_t nr);
-static int (*__write_to_statsd)(struct iovec* vec, size_t nr) = __write_to_statsd_init;
-
-void note_log_drop(int error, int atomId) {
-    statsdLoggerWrite.noteDrop(error, atomId);
-}
-
-void stats_log_close() {
-    statsd_writer_init_lock();
-    __write_to_statsd = __write_to_statsd_init;
-    if (statsdLoggerWrite.close) {
-        (*statsdLoggerWrite.close)();
-    }
-    statsd_writer_init_unlock();
-}
-
-int stats_log_is_closed() {
-    return statsdLoggerWrite.isClosed && (*statsdLoggerWrite.isClosed)();
-}
-
-int write_buffer_to_statsd(void* buffer, size_t size, uint32_t atomId) {
-    int ret = 1;
-
-    struct iovec vecs[2];
-    vecs[0].iov_base = (void*)&kStatsEventTag;
-    vecs[0].iov_len = sizeof(kStatsEventTag);
-    vecs[1].iov_base = buffer;
-    vecs[1].iov_len = size;
-
-    ret = __write_to_statsd(vecs, 2);
-
-    if (ret < 0) {
-        note_log_drop(ret, atomId);
-    }
-
-    return ret;
-}
-
-static int __write_to_stats_daemon(struct iovec* vec, size_t nr) {
-    int save_errno;
-    struct timespec ts;
-    size_t len, i;
-
-    for (len = i = 0; i < nr; ++i) {
-        len += vec[i].iov_len;
-    }
-    if (!len) {
-        return -EINVAL;
-    }
-
-    save_errno = errno;
-#if defined(__ANDROID__)
-    clock_gettime(CLOCK_REALTIME, &ts);
-#else
-    struct timeval tv;
-    gettimeofday(&tv, NULL);
-    ts.tv_sec = tv.tv_sec;
-    ts.tv_nsec = tv.tv_usec * 1000;
-#endif
-
-    int ret = (int)(*statsdLoggerWrite.write)(&ts, vec, nr);
-    errno = save_errno;
-    return ret;
-}
-
-static int __write_to_statsd_initialize_locked() {
-    if (!statsdLoggerWrite.open || ((*statsdLoggerWrite.open)() < 0)) {
-        if (statsdLoggerWrite.close) {
-            (*statsdLoggerWrite.close)();
-            return -ENODEV;
-        }
-    }
-    return 1;
-}
-
-static int __write_to_statsd_init(struct iovec* vec, size_t nr) {
-    int ret, save_errno = errno;
-
-    statsd_writer_init_lock();
-
-    if (__write_to_statsd == __write_to_statsd_init) {
-        ret = __write_to_statsd_initialize_locked();
-        if (ret < 0) {
-            statsd_writer_init_unlock();
-            errno = save_errno;
-            return ret;
-        }
-
-        __write_to_statsd = __write_to_stats_daemon;
-    }
-
-    statsd_writer_init_unlock();
-
-    ret = __write_to_statsd(vec, nr);
-    errno = save_errno;
-    return ret;
-}
diff --git a/libstats/socket/stats_event.c b/libstats/socket/stats_event.c
deleted file mode 100644
index f3e8087..0000000
--- a/libstats/socket/stats_event.c
+++ /dev/null
@@ -1,351 +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 "include/stats_event.h"
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include "stats_buffer_writer.h"
-
-#define LOGGER_ENTRY_MAX_PAYLOAD 4068
-// Max payload size is 4 bytes less as 4 bytes are reserved for stats_eventTag.
-// See android_util_Stats_Log.cpp
-#define MAX_PUSH_EVENT_PAYLOAD (LOGGER_ENTRY_MAX_PAYLOAD - 4)
-
-#define MAX_PULL_EVENT_PAYLOAD (50 * 1024)  // 50 KB
-
-/* POSITIONS */
-#define POS_NUM_ELEMENTS 1
-#define POS_TIMESTAMP (POS_NUM_ELEMENTS + sizeof(uint8_t))
-#define POS_ATOM_ID (POS_TIMESTAMP + sizeof(uint8_t) + sizeof(uint64_t))
-
-/* LIMITS */
-#define MAX_ANNOTATION_COUNT 15
-#define MAX_BYTE_VALUE 127  // parsing side requires that lengths fit in 7 bits
-
-/* ERRORS */
-#define ERROR_NO_TIMESTAMP 0x1
-#define ERROR_NO_ATOM_ID 0x2
-#define ERROR_OVERFLOW 0x4
-#define ERROR_ATTRIBUTION_CHAIN_TOO_LONG 0x8
-#define ERROR_TOO_MANY_KEY_VALUE_PAIRS 0x10
-#define ERROR_ANNOTATION_DOES_NOT_FOLLOW_FIELD 0x20
-#define ERROR_INVALID_ANNOTATION_ID 0x40
-#define ERROR_ANNOTATION_ID_TOO_LARGE 0x80
-#define ERROR_TOO_MANY_ANNOTATIONS 0x100
-#define ERROR_TOO_MANY_FIELDS 0x200
-#define ERROR_INVALID_VALUE_TYPE 0x400
-#define ERROR_STRING_NOT_NULL_TERMINATED 0x800
-#define ERROR_ATOM_ID_INVALID_POSITION 0x2000
-
-/* TYPE IDS */
-#define INT32_TYPE 0x00
-#define INT64_TYPE 0x01
-#define STRING_TYPE 0x02
-#define LIST_TYPE 0x03
-#define FLOAT_TYPE 0x04
-#define BOOL_TYPE 0x05
-#define BYTE_ARRAY_TYPE 0x06
-#define OBJECT_TYPE 0x07
-#define KEY_VALUE_PAIRS_TYPE 0x08
-#define ATTRIBUTION_CHAIN_TYPE 0x09
-#define ERROR_TYPE 0x0F
-
-// The AStatsEvent struct holds the serialized encoding of an event
-// within a buf. Also includes other required fields.
-struct AStatsEvent {
-    uint8_t* buf;
-    // Location of last field within the buf. Here, field denotes either a
-    // metadata field (e.g. timestamp) or an atom field.
-    size_t lastFieldPos;
-    // Number of valid bytes within the buffer.
-    size_t numBytesWritten;
-    uint32_t numElements;
-    uint32_t atomId;
-    uint32_t errors;
-    bool built;
-    size_t bufSize;
-};
-
-static int64_t get_elapsed_realtime_ns() {
-    struct timespec t;
-    t.tv_sec = t.tv_nsec = 0;
-    clock_gettime(CLOCK_BOOTTIME, &t);
-    return (int64_t)t.tv_sec * 1000000000LL + t.tv_nsec;
-}
-
-AStatsEvent* AStatsEvent_obtain() {
-    AStatsEvent* event = malloc(sizeof(AStatsEvent));
-    event->lastFieldPos = 0;
-    event->numBytesWritten = 2;  // reserve first 2 bytes for root event type and number of elements
-    event->numElements = 0;
-    event->atomId = 0;
-    event->errors = 0;
-    event->built = false;
-    event->bufSize = MAX_PUSH_EVENT_PAYLOAD;
-    event->buf = (uint8_t*)calloc(event->bufSize, 1);
-
-    event->buf[0] = OBJECT_TYPE;
-    AStatsEvent_writeInt64(event, get_elapsed_realtime_ns());  // write the timestamp
-
-    return event;
-}
-
-void AStatsEvent_release(AStatsEvent* event) {
-    free(event->buf);
-    free(event);
-}
-
-void AStatsEvent_setAtomId(AStatsEvent* event, uint32_t atomId) {
-    if (event->atomId != 0) return;
-    if (event->numElements != 1) {
-        event->errors |= ERROR_ATOM_ID_INVALID_POSITION;
-        return;
-    }
-
-    event->atomId = atomId;
-    AStatsEvent_writeInt32(event, atomId);
-}
-
-// Overwrites the timestamp populated in AStatsEvent_obtain with a custom
-// timestamp. Should only be called from test code.
-void AStatsEvent_overwriteTimestamp(AStatsEvent* event, uint64_t timestampNs) {
-    memcpy(&event->buf[POS_TIMESTAMP + sizeof(uint8_t)], &timestampNs, sizeof(timestampNs));
-    // Do not increment numElements because we already accounted for the timestamp
-    // within AStatsEvent_obtain.
-}
-
-// Side-effect: modifies event->errors if the buffer would overflow
-static bool overflows(AStatsEvent* event, size_t size) {
-    const size_t totalBytesNeeded = event->numBytesWritten + size;
-    if (totalBytesNeeded > MAX_PULL_EVENT_PAYLOAD) {
-        event->errors |= ERROR_OVERFLOW;
-        return true;
-    }
-
-    // Expand buffer if needed.
-    if (event->bufSize < MAX_PULL_EVENT_PAYLOAD && totalBytesNeeded > event->bufSize) {
-        do {
-            event->bufSize *= 2;
-        } while (event->bufSize <= totalBytesNeeded);
-
-        if (event->bufSize > MAX_PULL_EVENT_PAYLOAD) {
-            event->bufSize = MAX_PULL_EVENT_PAYLOAD;
-        }
-
-        event->buf = (uint8_t*)realloc(event->buf, event->bufSize);
-    }
-    return false;
-}
-
-// Side-effect: all append functions increment event->numBytesWritten if there is
-// sufficient space within the buffer to place the value
-static void append_byte(AStatsEvent* event, uint8_t value) {
-    if (!overflows(event, sizeof(value))) {
-        event->buf[event->numBytesWritten] = value;
-        event->numBytesWritten += sizeof(value);
-    }
-}
-
-static void append_bool(AStatsEvent* event, bool value) {
-    append_byte(event, (uint8_t)value);
-}
-
-static void append_int32(AStatsEvent* event, int32_t value) {
-    if (!overflows(event, sizeof(value))) {
-        memcpy(&event->buf[event->numBytesWritten], &value, sizeof(value));
-        event->numBytesWritten += sizeof(value);
-    }
-}
-
-static void append_int64(AStatsEvent* event, int64_t value) {
-    if (!overflows(event, sizeof(value))) {
-        memcpy(&event->buf[event->numBytesWritten], &value, sizeof(value));
-        event->numBytesWritten += sizeof(value);
-    }
-}
-
-static void append_float(AStatsEvent* event, float value) {
-    if (!overflows(event, sizeof(value))) {
-        memcpy(&event->buf[event->numBytesWritten], &value, sizeof(value));
-        event->numBytesWritten += sizeof(float);
-    }
-}
-
-static void append_byte_array(AStatsEvent* event, const uint8_t* buf, size_t size) {
-    if (!overflows(event, size)) {
-        memcpy(&event->buf[event->numBytesWritten], buf, size);
-        event->numBytesWritten += size;
-    }
-}
-
-// Side-effect: modifies event->errors if buf is not properly null-terminated
-static void append_string(AStatsEvent* event, const char* buf) {
-    size_t size = strnlen(buf, MAX_PULL_EVENT_PAYLOAD);
-    if (size == MAX_PULL_EVENT_PAYLOAD) {
-        event->errors |= ERROR_STRING_NOT_NULL_TERMINATED;
-        return;
-    }
-
-    append_int32(event, size);
-    append_byte_array(event, (uint8_t*)buf, size);
-}
-
-static void start_field(AStatsEvent* event, uint8_t typeId) {
-    event->lastFieldPos = event->numBytesWritten;
-    append_byte(event, typeId);
-    event->numElements++;
-}
-
-void AStatsEvent_writeInt32(AStatsEvent* event, int32_t value) {
-    start_field(event, INT32_TYPE);
-    append_int32(event, value);
-}
-
-void AStatsEvent_writeInt64(AStatsEvent* event, int64_t value) {
-    start_field(event, INT64_TYPE);
-    append_int64(event, value);
-}
-
-void AStatsEvent_writeFloat(AStatsEvent* event, float value) {
-    start_field(event, FLOAT_TYPE);
-    append_float(event, value);
-}
-
-void AStatsEvent_writeBool(AStatsEvent* event, bool value) {
-    start_field(event, BOOL_TYPE);
-    append_bool(event, value);
-}
-
-void AStatsEvent_writeByteArray(AStatsEvent* event, const uint8_t* buf, size_t numBytes) {
-    start_field(event, BYTE_ARRAY_TYPE);
-    append_int32(event, numBytes);
-    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);
-}
-
-// Tags are assumed to be encoded using UTF8
-void AStatsEvent_writeAttributionChain(AStatsEvent* event, const uint32_t* uids,
-                                       const char* const* tags, uint8_t numNodes) {
-    if (numNodes > MAX_BYTE_VALUE) {
-        event->errors |= ERROR_ATTRIBUTION_CHAIN_TOO_LONG;
-        return;
-    }
-
-    start_field(event, ATTRIBUTION_CHAIN_TYPE);
-    append_byte(event, numNodes);
-
-    for (uint8_t i = 0; i < numNodes; i++) {
-        append_int32(event, uids[i]);
-        append_string(event, tags[i]);
-    }
-}
-
-// Side-effect: modifies event->errors if field has too many annotations
-static void increment_annotation_count(AStatsEvent* event) {
-    uint8_t fieldType = event->buf[event->lastFieldPos] & 0x0F;
-    uint32_t oldAnnotationCount = (event->buf[event->lastFieldPos] & 0xF0) >> 4;
-    uint32_t newAnnotationCount = oldAnnotationCount + 1;
-
-    if (newAnnotationCount > MAX_ANNOTATION_COUNT) {
-        event->errors |= ERROR_TOO_MANY_ANNOTATIONS;
-        return;
-    }
-
-    event->buf[event->lastFieldPos] = (((uint8_t)newAnnotationCount << 4) & 0xF0) | fieldType;
-}
-
-void AStatsEvent_addBoolAnnotation(AStatsEvent* event, uint8_t annotationId, bool value) {
-    if (event->numElements < 2) {
-        event->errors |= ERROR_ANNOTATION_DOES_NOT_FOLLOW_FIELD;
-        return;
-    } else if (annotationId > MAX_BYTE_VALUE) {
-        event->errors |= ERROR_ANNOTATION_ID_TOO_LARGE;
-        return;
-    }
-
-    append_byte(event, annotationId);
-    append_byte(event, BOOL_TYPE);
-    append_bool(event, value);
-    increment_annotation_count(event);
-}
-
-void AStatsEvent_addInt32Annotation(AStatsEvent* event, uint8_t annotationId, int32_t value) {
-    if (event->numElements < 2) {
-        event->errors |= ERROR_ANNOTATION_DOES_NOT_FOLLOW_FIELD;
-        return;
-    } else if (annotationId > MAX_BYTE_VALUE) {
-        event->errors |= ERROR_ANNOTATION_ID_TOO_LARGE;
-        return;
-    }
-
-    append_byte(event, annotationId);
-    append_byte(event, INT32_TYPE);
-    append_int32(event, value);
-    increment_annotation_count(event);
-}
-
-uint32_t AStatsEvent_getAtomId(AStatsEvent* event) {
-    return event->atomId;
-}
-
-uint8_t* AStatsEvent_getBuffer(AStatsEvent* event, size_t* size) {
-    if (size) *size = event->numBytesWritten;
-    return event->buf;
-}
-
-uint32_t AStatsEvent_getErrors(AStatsEvent* event) {
-    return event->errors;
-}
-
-static void build_internal(AStatsEvent* event, const bool push) {
-    if (event->numElements > MAX_BYTE_VALUE) event->errors |= ERROR_TOO_MANY_FIELDS;
-    if (0 == event->atomId) event->errors |= ERROR_NO_ATOM_ID;
-    if (push && event->numBytesWritten > MAX_PUSH_EVENT_PAYLOAD) event->errors |= ERROR_OVERFLOW;
-
-    // If there are errors, rewrite buffer.
-    if (event->errors) {
-        // Discard everything after the atom id (including atom-level
-        // annotations). This leaves only two elements (timestamp and atom id).
-        event->numElements = 2;
-        // Reset number of atom-level annotations to 0.
-        event->buf[POS_ATOM_ID] = INT32_TYPE;
-        // Now, write errors to the buffer immediately after the atom id.
-        event->numBytesWritten = POS_ATOM_ID + sizeof(uint8_t) + sizeof(uint32_t);
-        start_field(event, ERROR_TYPE);
-        append_int32(event, event->errors);
-    }
-
-    event->buf[POS_NUM_ELEMENTS] = event->numElements;
-}
-
-void AStatsEvent_build(AStatsEvent* event) {
-    if (event->built) return;
-
-    build_internal(event, false /* push */);
-
-    event->built = true;
-}
-
-int AStatsEvent_write(AStatsEvent* event) {
-    build_internal(event, true /* push */);
-    return write_buffer_to_statsd(event->buf, event->numBytesWritten, event->atomId);
-}
diff --git a/libstats/socket/stats_socket.c b/libstats/socket/stats_socket.c
deleted file mode 100644
index 09f8967..0000000
--- a/libstats/socket/stats_socket.c
+++ /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.
- */
-
-#include "include/stats_socket.h"
-#include "stats_buffer_writer.h"
-
-void AStatsSocket_close() {
-    stats_log_close();
-}
diff --git a/libstats/socket/statsd_writer.c b/libstats/socket/statsd_writer.c
deleted file mode 100644
index 73b7a7e..0000000
--- a/libstats/socket/statsd_writer.c
+++ /dev/null
@@ -1,294 +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 "statsd_writer.h"
-
-#include <cutils/fs.h>
-#include <cutils/sockets.h>
-#include <cutils/threads.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <inttypes.h>
-#include <poll.h>
-#include <private/android_filesystem_config.h>
-#include <private/android_logger.h>
-#include <stdarg.h>
-#include <stdatomic.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/uio.h>
-#include <sys/un.h>
-#include <time.h>
-#include <unistd.h>
-
-static pthread_mutex_t log_init_lock = PTHREAD_MUTEX_INITIALIZER;
-static atomic_int dropped = 0;
-static atomic_int log_error = 0;
-static atomic_int atom_tag = 0;
-
-void statsd_writer_init_lock() {
-    /*
-     * If we trigger a signal handler in the middle of locked activity and the
-     * signal handler logs a message, we could get into a deadlock state.
-     */
-    pthread_mutex_lock(&log_init_lock);
-}
-
-int statd_writer_trylock() {
-    return pthread_mutex_trylock(&log_init_lock);
-}
-
-void statsd_writer_init_unlock() {
-    pthread_mutex_unlock(&log_init_lock);
-}
-
-static int statsdAvailable();
-static int statsdOpen();
-static void statsdClose();
-static int statsdWrite(struct timespec* ts, struct iovec* vec, size_t nr);
-static void statsdNoteDrop();
-static int statsdIsClosed();
-
-struct android_log_transport_write statsdLoggerWrite = {
-        .name = "statsd",
-        .sock = -EBADF,
-        .available = statsdAvailable,
-        .open = statsdOpen,
-        .close = statsdClose,
-        .write = statsdWrite,
-        .noteDrop = statsdNoteDrop,
-        .isClosed = statsdIsClosed,
-};
-
-/* log_init_lock assumed */
-static int statsdOpen() {
-    int i, ret = 0;
-
-    i = atomic_load(&statsdLoggerWrite.sock);
-    if (i < 0) {
-        int flags = SOCK_DGRAM;
-#ifdef SOCK_CLOEXEC
-        flags |= SOCK_CLOEXEC;
-#endif
-#ifdef SOCK_NONBLOCK
-        flags |= SOCK_NONBLOCK;
-#endif
-        int sock = TEMP_FAILURE_RETRY(socket(PF_UNIX, flags, 0));
-        if (sock < 0) {
-            ret = -errno;
-        } else {
-            int sndbuf = 1 * 1024 * 1024;  // set max send buffer size 1MB
-            socklen_t bufLen = sizeof(sndbuf);
-            // SO_RCVBUF does not have an effect on unix domain socket, but SO_SNDBUF does.
-            // Proceed to connect even setsockopt fails.
-            setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &sndbuf, bufLen);
-            struct sockaddr_un un;
-            memset(&un, 0, sizeof(struct sockaddr_un));
-            un.sun_family = AF_UNIX;
-            strcpy(un.sun_path, "/dev/socket/statsdw");
-
-            if (TEMP_FAILURE_RETRY(
-                        connect(sock, (struct sockaddr*)&un, sizeof(struct sockaddr_un))) < 0) {
-                ret = -errno;
-                switch (ret) {
-                    case -ENOTCONN:
-                    case -ECONNREFUSED:
-                    case -ENOENT:
-                        i = atomic_exchange(&statsdLoggerWrite.sock, ret);
-                    /* FALLTHRU */
-                    default:
-                        break;
-                }
-                close(sock);
-            } else {
-                ret = atomic_exchange(&statsdLoggerWrite.sock, sock);
-                if ((ret >= 0) && (ret != sock)) {
-                    close(ret);
-                }
-                ret = 0;
-            }
-        }
-    }
-
-    return ret;
-}
-
-static void __statsdClose(int negative_errno) {
-    int sock = atomic_exchange(&statsdLoggerWrite.sock, negative_errno);
-    if (sock >= 0) {
-        close(sock);
-    }
-}
-
-static void statsdClose() {
-    __statsdClose(-EBADF);
-}
-
-static int statsdAvailable() {
-    if (atomic_load(&statsdLoggerWrite.sock) < 0) {
-        if (access("/dev/socket/statsdw", W_OK) == 0) {
-            return 0;
-        }
-        return -EBADF;
-    }
-    return 1;
-}
-
-static void statsdNoteDrop(int error, int tag) {
-    atomic_fetch_add_explicit(&dropped, 1, memory_order_relaxed);
-    atomic_exchange_explicit(&log_error, error, memory_order_relaxed);
-    atomic_exchange_explicit(&atom_tag, tag, memory_order_relaxed);
-}
-
-static int statsdIsClosed() {
-    if (atomic_load(&statsdLoggerWrite.sock) < 0) {
-        return 1;
-    }
-    return 0;
-}
-
-static int statsdWrite(struct timespec* ts, struct iovec* vec, size_t nr) {
-    ssize_t ret;
-    int sock;
-    static const unsigned headerLength = 1;
-    struct iovec newVec[nr + headerLength];
-    android_log_header_t header;
-    size_t i, payloadSize;
-
-    sock = atomic_load(&statsdLoggerWrite.sock);
-    if (sock < 0) switch (sock) {
-            case -ENOTCONN:
-            case -ECONNREFUSED:
-            case -ENOENT:
-                break;
-            default:
-                return -EBADF;
-        }
-    /*
-     *  struct {
-     *      // what we provide to socket
-     *      android_log_header_t header;
-     *      // caller provides
-     *      union {
-     *          struct {
-     *              char     prio;
-     *              char     payload[];
-     *          } string;
-     *          struct {
-     *              uint32_t tag
-     *              char     payload[];
-     *          } binary;
-     *      };
-     *  };
-     */
-
-    header.tid = gettid();
-    header.realtime.tv_sec = ts->tv_sec;
-    header.realtime.tv_nsec = ts->tv_nsec;
-
-    newVec[0].iov_base = (unsigned char*)&header;
-    newVec[0].iov_len = sizeof(header);
-
-    // If we dropped events before, try to tell statsd.
-    if (sock >= 0) {
-        int32_t snapshot = atomic_exchange_explicit(&dropped, 0, memory_order_relaxed);
-        if (snapshot) {
-            android_log_event_long_t buffer;
-            header.id = LOG_ID_STATS;
-            // store the last log error in the tag field. This tag field is not used by statsd.
-            buffer.header.tag = atomic_load(&log_error);
-            buffer.payload.type = EVENT_TYPE_LONG;
-            // format:
-            // |atom_tag|dropped_count|
-            int64_t composed_long = atomic_load(&atom_tag);
-            // Send 2 int32's via an int64.
-            composed_long = ((composed_long << 32) | ((int64_t)snapshot));
-            buffer.payload.data = composed_long;
-
-            newVec[headerLength].iov_base = &buffer;
-            newVec[headerLength].iov_len = sizeof(buffer);
-
-            ret = TEMP_FAILURE_RETRY(writev(sock, newVec, 2));
-            if (ret != (ssize_t)(sizeof(header) + sizeof(buffer))) {
-                atomic_fetch_add_explicit(&dropped, snapshot, memory_order_relaxed);
-            }
-        }
-    }
-
-    header.id = LOG_ID_STATS;
-
-    for (payloadSize = 0, i = headerLength; i < nr + headerLength; i++) {
-        newVec[i].iov_base = vec[i - headerLength].iov_base;
-        payloadSize += newVec[i].iov_len = vec[i - headerLength].iov_len;
-
-        if (payloadSize > LOGGER_ENTRY_MAX_PAYLOAD) {
-            newVec[i].iov_len -= payloadSize - LOGGER_ENTRY_MAX_PAYLOAD;
-            if (newVec[i].iov_len) {
-                ++i;
-            }
-            break;
-        }
-    }
-
-    /*
-     * The write below could be lost, but will never block.
-     *
-     * ENOTCONN occurs if statsd has died.
-     * ENOENT occurs if statsd is not running and socket is missing.
-     * ECONNREFUSED occurs if we can not reconnect to statsd.
-     * EAGAIN occurs if statsd is overloaded.
-     */
-    if (sock < 0) {
-        ret = sock;
-    } else {
-        ret = TEMP_FAILURE_RETRY(writev(sock, newVec, i));
-        if (ret < 0) {
-            ret = -errno;
-        }
-    }
-    switch (ret) {
-        case -ENOTCONN:
-        case -ECONNREFUSED:
-        case -ENOENT:
-            if (statd_writer_trylock()) {
-                return ret; /* in a signal handler? try again when less stressed
-                             */
-            }
-            __statsdClose(ret);
-            ret = statsdOpen();
-            statsd_writer_init_unlock();
-
-            if (ret < 0) {
-                return ret;
-            }
-
-            ret = TEMP_FAILURE_RETRY(writev(atomic_load(&statsdLoggerWrite.sock), newVec, i));
-            if (ret < 0) {
-                ret = -errno;
-            }
-        /* FALLTHRU */
-        default:
-            break;
-    }
-
-    if (ret > (ssize_t)sizeof(header)) {
-        ret -= sizeof(header);
-    }
-
-    return ret;
-}
diff --git a/libstats/socket/statsd_writer.h b/libstats/socket/statsd_writer.h
deleted file mode 100644
index 562bda5..0000000
--- a/libstats/socket/statsd_writer.h
+++ /dev/null
@@ -1,47 +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.
- */
-
-#ifndef ANDROID_STATS_LOG_STATS_WRITER_H
-#define ANDROID_STATS_LOG_STATS_WRITER_H
-
-#include <pthread.h>
-#include <stdatomic.h>
-#include <sys/socket.h>
-
-/**
- * Internal lock should not be exposed. This is bad design.
- * TODO: rewrite it in c++ code and encapsulate the functionality in a
- * StatsdWriter class.
- */
-void statsd_writer_init_lock();
-int statsd_writer_init_trylock();
-void statsd_writer_init_unlock();
-
-struct android_log_transport_write {
-    const char* name; /* human name to describe the transport */
-    atomic_int sock;
-    int (*available)(); /* Does not cause resources to be taken */
-    int (*open)();      /* can be called multiple times, reusing current resources */
-    void (*close)();    /* free up resources */
-    /* write log to transport, returns number of bytes propagated, or -errno */
-    int (*write)(struct timespec* ts, struct iovec* vec, size_t nr);
-    /* note one log drop */
-    void (*noteDrop)(int error, int tag);
-    /* checks if the socket is closed */
-    int (*isClosed)();
-};
-
-#endif  // ANDROID_STATS_LOG_STATS_WRITER_H
diff --git a/libstats/socket/tests/stats_event_test.cpp b/libstats/socket/tests/stats_event_test.cpp
deleted file mode 100644
index 9a1fac8..0000000
--- a/libstats/socket/tests/stats_event_test.cpp
+++ /dev/null
@@ -1,460 +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 "stats_event.h"
-#include <gtest/gtest.h>
-#include <utils/SystemClock.h>
-
-// Keep in sync with stats_event.c. Consider moving to separate header file to avoid duplication.
-/* ERRORS */
-#define ERROR_NO_TIMESTAMP 0x1
-#define ERROR_NO_ATOM_ID 0x2
-#define ERROR_OVERFLOW 0x4
-#define ERROR_ATTRIBUTION_CHAIN_TOO_LONG 0x8
-#define ERROR_TOO_MANY_KEY_VALUE_PAIRS 0x10
-#define ERROR_ANNOTATION_DOES_NOT_FOLLOW_FIELD 0x20
-#define ERROR_INVALID_ANNOTATION_ID 0x40
-#define ERROR_ANNOTATION_ID_TOO_LARGE 0x80
-#define ERROR_TOO_MANY_ANNOTATIONS 0x100
-#define ERROR_TOO_MANY_FIELDS 0x200
-#define ERROR_INVALID_VALUE_TYPE 0x400
-#define ERROR_STRING_NOT_NULL_TERMINATED 0x800
-#define ERROR_ATOM_ID_INVALID_POSITION 0x2000
-
-/* TYPE IDS */
-#define INT32_TYPE 0x00
-#define INT64_TYPE 0x01
-#define STRING_TYPE 0x02
-#define LIST_TYPE 0x03
-#define FLOAT_TYPE 0x04
-#define BOOL_TYPE 0x05
-#define BYTE_ARRAY_TYPE 0x06
-#define OBJECT_TYPE 0x07
-#define KEY_VALUE_PAIRS_TYPE 0x08
-#define ATTRIBUTION_CHAIN_TYPE 0x09
-#define ERROR_TYPE 0x0F
-
-using std::string;
-using std::vector;
-
-// Side-effect: this function moves the start of the buffer past the read value
-template <class T>
-T readNext(uint8_t** buffer) {
-    T value;
-    if ((reinterpret_cast<uintptr_t>(*buffer) % alignof(T)) == 0) {
-        value = *(T*)(*buffer);
-    } else {
-        memcpy(&value, *buffer, sizeof(T));
-    }
-    *buffer += sizeof(T);
-    return value;
-}
-
-void checkTypeHeader(uint8_t** buffer, uint8_t typeId, uint8_t numAnnotations = 0) {
-    uint8_t typeHeader = (numAnnotations << 4) | typeId;
-    EXPECT_EQ(readNext<uint8_t>(buffer), typeHeader);
-}
-
-template <class T>
-void checkScalar(uint8_t** buffer, T expectedValue) {
-    EXPECT_EQ(readNext<T>(buffer), expectedValue);
-}
-
-void checkString(uint8_t** buffer, const string& expectedString) {
-    uint32_t size = readNext<uint32_t>(buffer);
-    string parsedString((char*)(*buffer), size);
-    EXPECT_EQ(parsedString, expectedString);
-    *buffer += size;  // move buffer past string we just read
-}
-
-void checkByteArray(uint8_t** buffer, const vector<uint8_t>& expectedByteArray) {
-    uint32_t size = readNext<uint32_t>(buffer);
-    vector<uint8_t> parsedByteArray(*buffer, *buffer + size);
-    EXPECT_EQ(parsedByteArray, expectedByteArray);
-    *buffer += size;  // move buffer past byte array we just read
-}
-
-template <class T>
-void checkAnnotation(uint8_t** buffer, uint8_t annotationId, uint8_t typeId, T annotationValue) {
-    EXPECT_EQ(readNext<uint8_t>(buffer), annotationId);
-    EXPECT_EQ(readNext<uint8_t>(buffer), typeId);
-    checkScalar<T>(buffer, annotationValue);
-}
-
-void checkMetadata(uint8_t** buffer, uint8_t numElements, int64_t startTime, int64_t endTime,
-                   uint32_t atomId, uint8_t numAtomLevelAnnotations = 0) {
-    // All events start with OBJECT_TYPE id.
-    checkTypeHeader(buffer, OBJECT_TYPE);
-
-    // We increment by 2 because the number of elements listed in the
-    // serialization accounts for the timestamp and atom id as well.
-    checkScalar(buffer, static_cast<uint8_t>(numElements + 2));
-
-    // Check timestamp
-    checkTypeHeader(buffer, INT64_TYPE);
-    int64_t timestamp = readNext<int64_t>(buffer);
-    EXPECT_GE(timestamp, startTime);
-    EXPECT_LE(timestamp, endTime);
-
-    // Check atom id
-    checkTypeHeader(buffer, INT32_TYPE, numAtomLevelAnnotations);
-    checkScalar(buffer, atomId);
-}
-
-TEST(StatsEventTest, TestScalars) {
-    uint32_t atomId = 100;
-    int32_t int32Value = -5;
-    int64_t int64Value = -2 * android::elapsedRealtimeNano();
-    float floatValue = 2.0;
-    bool boolValue = false;
-
-    int64_t startTime = android::elapsedRealtimeNano();
-    AStatsEvent* event = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(event, atomId);
-    AStatsEvent_writeInt32(event, int32Value);
-    AStatsEvent_writeInt64(event, int64Value);
-    AStatsEvent_writeFloat(event, floatValue);
-    AStatsEvent_writeBool(event, boolValue);
-    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=*/4, startTime, endTime, atomId);
-
-    // check int32 element
-    checkTypeHeader(&buffer, INT32_TYPE);
-    checkScalar(&buffer, int32Value);
-
-    // check int64 element
-    checkTypeHeader(&buffer, INT64_TYPE);
-    checkScalar(&buffer, int64Value);
-
-    // check float element
-    checkTypeHeader(&buffer, FLOAT_TYPE);
-    checkScalar(&buffer, floatValue);
-
-    // check bool element
-    checkTypeHeader(&buffer, BOOL_TYPE);
-    checkScalar(&buffer, boolValue);
-
-    EXPECT_EQ(buffer, bufferEnd);  // ensure that we have read the entire buffer
-    EXPECT_EQ(AStatsEvent_getErrors(event), 0);
-    AStatsEvent_release(event);
-}
-
-TEST(StatsEventTest, TestStrings) {
-    uint32_t atomId = 100;
-    string str = "test_string";
-
-    int64_t startTime = android::elapsedRealtimeNano();
-    AStatsEvent* event = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(event, atomId);
-    AStatsEvent_writeString(event, str.c_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, str);
-
-    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'};
-
-    int64_t startTime = android::elapsedRealtimeNano();
-    AStatsEvent* event = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(event, atomId);
-    AStatsEvent_writeByteArray(event, message.data(), message.size());
-    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;
-
-    uint8_t numNodes = 50;
-    uint32_t uids[numNodes];
-    vector<string> tags(numNodes);  // storage that cTag elements point to
-    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();
-    }
-
-    int64_t startTime = android::elapsedRealtimeNano();
-    AStatsEvent* event = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(event, atomId);
-    AStatsEvent_writeAttributionChain(event, uids, cTags, numNodes);
-    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, ATTRIBUTION_CHAIN_TYPE);
-    checkScalar(&buffer, numNodes);
-    for (int i = 0; i < numNodes; i++) {
-        checkScalar(&buffer, uids[i]);
-        checkString(&buffer, tags[i]);
-    }
-
-    EXPECT_EQ(buffer, bufferEnd);  // ensure that we have read the entire buffer
-    EXPECT_EQ(AStatsEvent_getErrors(event), 0);
-    AStatsEvent_release(event);
-}
-
-TEST(StatsEventTest, TestFieldAnnotations) {
-    uint32_t atomId = 100;
-
-    // first element information
-    bool boolValue = false;
-    uint8_t boolAnnotation1Id = 1;
-    uint8_t boolAnnotation2Id = 2;
-    bool boolAnnotation1Value = true;
-    int32_t boolAnnotation2Value = 3;
-
-    // second element information
-    float floatValue = -5.0;
-    uint8_t floatAnnotation1Id = 3;
-    uint8_t floatAnnotation2Id = 4;
-    int32_t floatAnnotation1Value = 8;
-    bool floatAnnotation2Value = false;
-
-    int64_t startTime = android::elapsedRealtimeNano();
-    AStatsEvent* event = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(event, atomId);
-    AStatsEvent_writeBool(event, boolValue);
-    AStatsEvent_addBoolAnnotation(event, boolAnnotation1Id, boolAnnotation1Value);
-    AStatsEvent_addInt32Annotation(event, boolAnnotation2Id, boolAnnotation2Value);
-    AStatsEvent_writeFloat(event, floatValue);
-    AStatsEvent_addInt32Annotation(event, floatAnnotation1Id, floatAnnotation1Value);
-    AStatsEvent_addBoolAnnotation(event, floatAnnotation2Id, floatAnnotation2Value);
-    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=*/2, startTime, endTime, atomId);
-
-    // check first element
-    checkTypeHeader(&buffer, BOOL_TYPE, /*numAnnotations=*/2);
-    checkScalar(&buffer, boolValue);
-    checkAnnotation(&buffer, boolAnnotation1Id, BOOL_TYPE, boolAnnotation1Value);
-    checkAnnotation(&buffer, boolAnnotation2Id, INT32_TYPE, boolAnnotation2Value);
-
-    // check second element
-    checkTypeHeader(&buffer, FLOAT_TYPE, /*numAnnotations=*/2);
-    checkScalar(&buffer, floatValue);
-    checkAnnotation(&buffer, floatAnnotation1Id, INT32_TYPE, floatAnnotation1Value);
-    checkAnnotation(&buffer, floatAnnotation2Id, BOOL_TYPE, floatAnnotation2Value);
-
-    EXPECT_EQ(buffer, bufferEnd);  // ensure that we have read the entire buffer
-    EXPECT_EQ(AStatsEvent_getErrors(event), 0);
-    AStatsEvent_release(event);
-}
-
-TEST(StatsEventTest, TestAtomLevelAnnotations) {
-    uint32_t atomId = 100;
-    // atom-level annotation information
-    uint8_t boolAnnotationId = 1;
-    uint8_t int32AnnotationId = 2;
-    bool boolAnnotationValue = false;
-    int32_t int32AnnotationValue = 5;
-
-    float fieldValue = -3.5;
-
-    int64_t startTime = android::elapsedRealtimeNano();
-    AStatsEvent* event = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(event, atomId);
-    AStatsEvent_addBoolAnnotation(event, boolAnnotationId, boolAnnotationValue);
-    AStatsEvent_addInt32Annotation(event, int32AnnotationId, int32AnnotationValue);
-    AStatsEvent_writeFloat(event, fieldValue);
-    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,
-                  /*numAtomLevelAnnotations=*/2);
-
-    // check atom-level annotations
-    checkAnnotation(&buffer, boolAnnotationId, BOOL_TYPE, boolAnnotationValue);
-    checkAnnotation(&buffer, int32AnnotationId, INT32_TYPE, int32AnnotationValue);
-
-    // check first element
-    checkTypeHeader(&buffer, FLOAT_TYPE);
-    checkScalar(&buffer, fieldValue);
-
-    EXPECT_EQ(buffer, bufferEnd);  // ensure that we have read the entire buffer
-    EXPECT_EQ(AStatsEvent_getErrors(event), 0);
-    AStatsEvent_release(event);
-}
-
-TEST(StatsEventTest, TestNoAtomIdError) {
-    AStatsEvent* event = AStatsEvent_obtain();
-    // Don't set the atom id in order to trigger the error.
-    AStatsEvent_build(event);
-
-    uint32_t errors = AStatsEvent_getErrors(event);
-    EXPECT_EQ(errors & ERROR_NO_ATOM_ID, ERROR_NO_ATOM_ID);
-
-    AStatsEvent_release(event);
-}
-
-TEST(StatsEventTest, TestPushOverflowError) {
-    const char* str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
-    const int writeCount = 120;  // Number of times to write str in the event.
-
-    AStatsEvent* event = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(event, 100);
-
-    // Add str to the event 120 times. Each str takes >35 bytes so this will
-    // overflow the 4068 byte buffer.
-    // We want to keep writeCount less than 127 to avoid hitting
-    // ERROR_TOO_MANY_FIELDS.
-    for (int i = 0; i < writeCount; i++) {
-        AStatsEvent_writeString(event, str);
-    }
-    AStatsEvent_write(event);
-
-    uint32_t errors = AStatsEvent_getErrors(event);
-    EXPECT_EQ(errors & ERROR_OVERFLOW, ERROR_OVERFLOW);
-
-    AStatsEvent_release(event);
-}
-
-TEST(StatsEventTest, TestPullOverflowError) {
-    const uint32_t atomId = 10100;
-    const vector<uint8_t> bytes(430 /* number of elements */, 1 /* value of each element */);
-    const int writeCount = 120;  // Number of times to write bytes in the event.
-
-    AStatsEvent* event = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(event, atomId);
-
-    // Add bytes to the event 120 times. Size of bytes is 430 so this will
-    // overflow the 50 KB pulled event buffer.
-    // We want to keep writeCount less than 127 to avoid hitting
-    // ERROR_TOO_MANY_FIELDS.
-    for (int i = 0; i < writeCount; i++) {
-        AStatsEvent_writeByteArray(event, bytes.data(), bytes.size());
-    }
-    AStatsEvent_build(event);
-
-    uint32_t errors = AStatsEvent_getErrors(event);
-    EXPECT_EQ(errors & ERROR_OVERFLOW, ERROR_OVERFLOW);
-
-    AStatsEvent_release(event);
-}
-
-TEST(StatsEventTest, TestLargePull) {
-    const uint32_t atomId = 100;
-    const string str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
-    const int writeCount = 120;  // Number of times to write str in the event.
-    const int64_t startTime = android::elapsedRealtimeNano();
-
-    AStatsEvent* event = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(event, atomId);
-
-    // Add str to the event 120 times.
-    // We want to keep writeCount less than 127 to avoid hitting
-    // ERROR_TOO_MANY_FIELDS.
-    for (int i = 0; i < writeCount; i++) {
-        AStatsEvent_writeString(event, str.c_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, writeCount, startTime, endTime, atomId);
-
-    // Check all instances of str have been written.
-    for (int i = 0; i < writeCount; i++) {
-        checkTypeHeader(&buffer, STRING_TYPE);
-        checkString(&buffer, str);
-    }
-
-    EXPECT_EQ(buffer, bufferEnd);  // Ensure that we have read the entire buffer.
-    EXPECT_EQ(AStatsEvent_getErrors(event), 0);
-    AStatsEvent_release(event);
-}
-
-TEST(StatsEventTest, TestAtomIdInvalidPositionError) {
-    AStatsEvent* event = AStatsEvent_obtain();
-    AStatsEvent_writeInt32(event, 0);
-    AStatsEvent_setAtomId(event, 100);
-    AStatsEvent_writeBool(event, true);
-    AStatsEvent_build(event);
-
-    uint32_t errors = AStatsEvent_getErrors(event);
-    EXPECT_EQ(errors & ERROR_ATOM_ID_INVALID_POSITION, ERROR_ATOM_ID_INVALID_POSITION);
-
-    AStatsEvent_release(event);
-}
-
-TEST(StatsEventTest, TestOverwriteTimestamp) {
-    uint32_t atomId = 100;
-    int64_t expectedTimestamp = 0x123456789;
-    AStatsEvent* event = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(event, atomId);
-    AStatsEvent_overwriteTimestamp(event, expectedTimestamp);
-    AStatsEvent_build(event);
-
-    uint8_t* buffer = AStatsEvent_getBuffer(event, NULL);
-
-    // Make sure that the timestamp is being overwritten.
-    checkMetadata(&buffer, /*numElements=*/0, /*startTime=*/expectedTimestamp,
-                  /*endTime=*/expectedTimestamp, atomId);
-
-    EXPECT_EQ(AStatsEvent_getErrors(event), 0);
-    AStatsEvent_release(event);
-}
diff --git a/libstats/socket/tests/stats_writer_test.cpp b/libstats/socket/tests/stats_writer_test.cpp
deleted file mode 100644
index 749599f..0000000
--- a/libstats/socket/tests/stats_writer_test.cpp
+++ /dev/null
@@ -1,36 +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 "stats_buffer_writer.h"
-#include "stats_event.h"
-#include "stats_socket.h"
-
-TEST(StatsWriterTest, TestSocketClose) {
-    AStatsEvent* event = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(event, 100);
-    AStatsEvent_writeInt32(event, 5);
-    int successResult = AStatsEvent_write(event);
-    AStatsEvent_release(event);
-
-    // In the case of a successful write, we return the number of bytes written.
-    EXPECT_GT(successResult, 0);
-    EXPECT_FALSE(stats_log_is_closed());
-
-    AStatsSocket_close();
-
-    EXPECT_TRUE(stats_log_is_closed());
-}
diff --git a/libsync/Android.bp b/libsync/Android.bp
index c996e1b..bad6230 100644
--- a/libsync/Android.bp
+++ b/libsync/Android.bp
@@ -25,6 +25,12 @@
     recovery_available: true,
     native_bridge_supported: true,
     defaults: ["libsync_defaults"],
+    stubs: {
+        symbol_file: "libsync.map.txt",
+        versions: [
+            "26",
+        ],
+    },
 }
 
 llndk_library {
diff --git a/libsync/libsync.map.txt b/libsync/libsync.map.txt
index 91c3528..aac6b57 100644
--- a/libsync/libsync.map.txt
+++ b/libsync/libsync.map.txt
@@ -19,7 +19,7 @@
     sync_merge; # introduced=26
     sync_file_info; # introduced=26
     sync_file_info_free; # introduced=26
-    sync_wait; # llndk
+    sync_wait; # llndk apex
     sync_fence_info; # llndk
     sync_pt_info; # llndk
     sync_fence_info_free; # llndk
