diff --git a/adb/adb.cpp b/adb/adb.cpp index ece143c63..577e9b996 100644 --- a/adb/adb.cpp +++ b/adb/adb.cpp @@ -1129,6 +1129,18 @@ int handle_host_request(const char* service, TransportType type, return 0; } +#if ADB_HOST + if (!strcmp(service, "host-features")) { + FeatureSet features = supported_features(); + // Abuse features to report libusb status. + if (should_use_libusb()) { + features.insert(kFeatureLibusb); + } + SendOkay(reply_fd, FeatureSetToString(features)); + return 0; + } +#endif + // remove TCP transport if (!strncmp(service, "disconnect:", 11)) { const std::string address(service + 11); diff --git a/adb/adb.h b/adb/adb.h index a30e29789..aea5fb86b 100644 --- a/adb/adb.h +++ b/adb/adb.h @@ -54,7 +54,7 @@ constexpr size_t LINUX_MAX_SOCKET_SIZE = 4194304; std::string adb_version(); // Increment this when we want to force users to start a new adb server. -#define ADB_SERVER_VERSION 38 +#define ADB_SERVER_VERSION 39 class atransport; diff --git a/adb/client/usb_dispatch.cpp b/adb/client/usb_dispatch.cpp index f02dccf54..bfc8e164b 100644 --- a/adb/client/usb_dispatch.cpp +++ b/adb/client/usb_dispatch.cpp @@ -17,11 +17,6 @@ #include #include "usb.h" -static bool should_use_libusb() { - static bool enable = getenv("ADB_LIBUSB") && strcmp(getenv("ADB_LIBUSB"), "1") == 0; - return enable; -} - void usb_init() { if (should_use_libusb()) { LOG(DEBUG) << "using libusb backend"; diff --git a/adb/commandline.cpp b/adb/commandline.cpp index 3b2df2edf..5a2206f6d 100644 --- a/adb/commandline.cpp +++ b/adb/commandline.cpp @@ -1929,8 +1929,7 @@ int adb_commandline(int argc, const char** argv) { 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")) { + } else if (!strcmp(argv[0], "features")) { // Only list the features common to both the adb client and the device. FeatureSet features; std::string error; @@ -1945,6 +1944,8 @@ int adb_commandline(int argc, const char** argv) { } } 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("host:reconnect"); diff --git a/adb/transport.cpp b/adb/transport.cpp index 60f3b5cd1..c951f5b29 100644 --- a/adb/transport.cpp +++ b/adb/transport.cpp @@ -51,6 +51,7 @@ static std::mutex& transport_lock = *new std::mutex(); const char* const kFeatureShell2 = "shell_v2"; const char* const kFeatureCmd = "cmd"; const char* const kFeatureStat2 = "stat_v2"; +const char* const kFeatureLibusb = "libusb"; static std::string dump_packet(const char* name, const char* func, apacket* p) { unsigned command = p->msg.command; diff --git a/adb/transport.h b/adb/transport.h index 330638829..490e51329 100644 --- a/adb/transport.h +++ b/adb/transport.h @@ -47,6 +47,8 @@ extern const char* const kFeatureShell2; // The 'cmd' command is available extern const char* const kFeatureCmd; extern const char* const kFeatureStat2; +// The server is running with libusb enabled. +extern const char* const kFeatureLibusb; class atransport { public: diff --git a/adb/transport_usb.cpp b/adb/transport_usb.cpp index 3d6cc9974..e16cf12e3 100644 --- a/adb/transport_usb.cpp +++ b/adb/transport_usb.cpp @@ -97,3 +97,12 @@ 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 defined(_WIN32) || !ADB_HOST + return false; +#else + static bool enable = getenv("ADB_LIBUSB") && strcmp(getenv("ADB_LIBUSB"), "1") == 0; + return enable; +#endif +} diff --git a/adb/usb.h b/adb/usb.h index 879bacc88..ba70de43e 100644 --- a/adb/usb.h +++ b/adb/usb.h @@ -55,3 +55,5 @@ 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();