Loading adb/adb.h +7 −2 Original line number Diff line number Diff line Loading @@ -214,18 +214,23 @@ void local_init(int port); void local_connect(int port); int local_connect_arbitrary_ports(int console_port, int adb_port, std::string* error); /* usb host/client interface */ // USB host/client interface. void usb_init(); int usb_write(usb_handle *h, const void *data, int len); int usb_read(usb_handle *h, void *data, int len); int usb_close(usb_handle *h); void usb_kick(usb_handle *h); /* used for USB device detection */ // USB device detection. #if ADB_HOST int is_adb_interface(int vid, int pid, int usb_class, int usb_subclass, int usb_protocol); #endif // USB permission error help text. The short version will be one line, long may be multi-line. // Returns a string message to print, or an empty string if no problems could be found. std::string UsbNoPermissionsShortHelpText(); std::string UsbNoPermissionsLongHelpText(); int adb_commandline(int argc, const char **argv); ConnectionState connection_state(atransport *t); Loading adb/transport.cpp +20 −12 Original line number Diff line number Diff line Loading @@ -674,7 +674,11 @@ atransport* acquire_one_transport(TransportType type, const char* serial, adb_mutex_lock(&transport_lock); for (const auto& t : transport_list) { if (t->connection_state == kCsNoPerm) { *error_out = UsbNoPermissionsLongHelpText(); // If we couldn't figure out a reasonable help message default to something generic. if (error_out->empty()) { *error_out = "insufficient permissions for device"; } continue; } Loading Loading @@ -748,14 +752,17 @@ atransport* acquire_one_transport(TransportType type, const char* serial, return result; } const char* atransport::connection_state_name() const { const std::string atransport::connection_state_name() const { switch (connection_state) { case kCsOffline: return "offline"; case kCsBootloader: return "bootloader"; case kCsDevice: return "device"; case kCsHost: return "host"; case kCsRecovery: return "recovery"; case kCsNoPerm: return "no permissions"; case kCsNoPerm: { std::string message = UsbNoPermissionsShortHelpText(); return message.empty() ? "no permissions" : message; } case kCsSideload: return "sideload"; case kCsUnauthorized: return "unauthorized"; default: return "unknown"; Loading Loading @@ -866,7 +873,8 @@ static void append_transport(const atransport* t, std::string* result, *result += '\t'; *result += t->connection_state_name(); } else { android::base::StringAppendF(result, "%-22s %s", serial, t->connection_state_name()); android::base::StringAppendF(result, "%-22s %s", serial, t->connection_state_name().c_str()); append_transport_info(result, "", t->devpath, false); append_transport_info(result, "product:", t->product, false); Loading adb/transport.h +1 −1 Original line number Diff line number Diff line Loading @@ -90,7 +90,7 @@ public: fdevent auth_fde; size_t failed_auth_attempts = 0; const char* connection_state_name() const; const std::string connection_state_name() const; void update_version(int version, size_t payload); int get_protocol_version() const; Loading adb/usb_linux.cpp +52 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ #include <dirent.h> #include <errno.h> #include <fcntl.h> #include <grp.h> #include <linux/usb/ch9.h> #include <linux/usbdevice_fs.h> #include <linux/version.h> Loading Loading @@ -595,3 +596,54 @@ void usb_init() { fatal_errno("cannot create device_poll thread"); } } static const char kPermissionsHelpUrl[] = "developer.android.com/tools/device.html"; // Returns a message describing any potential problems we find with udev, or nullptr if we can't // find plugdev information (i.e. udev is not installed). static const char* GetUdevProblem() { errno = 0; group* plugdev_group = getgrnam("plugdev"); if (plugdev_group == nullptr) { if (errno != 0) { D("failed to read plugdev group info: %s", strerror(errno)); } // We can't give any generally useful advice here, just let the caller print the help URL. return nullptr; } // getgroups(2) indicates that the group_member() may not check the egid so we check it // additionally just to be sure. if (group_member(plugdev_group->gr_gid) || getegid() == plugdev_group->gr_gid) { // The user is in plugdev so the problem is likely with the udev rules. return "verify udev rules"; } return "udev requires plugdev group membership"; } // Short help text must be a single line, and will look something like: // no permissions (reason); see <URL> std::string UsbNoPermissionsShortHelpText() { std::string help_text = "no permissions"; const char* problem = GetUdevProblem(); if (problem != nullptr) { help_text += android::base::StringPrintf(" (%s)", problem); } return android::base::StringPrintf("%s; see [%s]", help_text.c_str(), kPermissionsHelpUrl); } // Long help text can span multiple lines and should provide more detailed information. std::string UsbNoPermissionsLongHelpText() { std::string header = "USB permission failure"; const char* problem = GetUdevProblem(); if (problem != nullptr) { header += android::base::StringPrintf(": %s", problem); } return android::base::StringPrintf("%s.\nSee [%s] for more information.", header.c_str(), kPermissionsHelpUrl); } adb/usb_linux_client.cpp +9 −0 Original line number Diff line number Diff line Loading @@ -571,3 +571,12 @@ void usb_kick(usb_handle *h) { h->kick(h); } // kCsNoPerm is a host-side issue, we can just ignore it here. std::string UsbNoPermissionsShortHelpText() { return ""; } std::string UsbNoPermissionsLongHelpText() { return ""; } Loading
adb/adb.h +7 −2 Original line number Diff line number Diff line Loading @@ -214,18 +214,23 @@ void local_init(int port); void local_connect(int port); int local_connect_arbitrary_ports(int console_port, int adb_port, std::string* error); /* usb host/client interface */ // USB host/client interface. void usb_init(); int usb_write(usb_handle *h, const void *data, int len); int usb_read(usb_handle *h, void *data, int len); int usb_close(usb_handle *h); void usb_kick(usb_handle *h); /* used for USB device detection */ // USB device detection. #if ADB_HOST int is_adb_interface(int vid, int pid, int usb_class, int usb_subclass, int usb_protocol); #endif // USB permission error help text. The short version will be one line, long may be multi-line. // Returns a string message to print, or an empty string if no problems could be found. std::string UsbNoPermissionsShortHelpText(); std::string UsbNoPermissionsLongHelpText(); int adb_commandline(int argc, const char **argv); ConnectionState connection_state(atransport *t); Loading
adb/transport.cpp +20 −12 Original line number Diff line number Diff line Loading @@ -674,7 +674,11 @@ atransport* acquire_one_transport(TransportType type, const char* serial, adb_mutex_lock(&transport_lock); for (const auto& t : transport_list) { if (t->connection_state == kCsNoPerm) { *error_out = UsbNoPermissionsLongHelpText(); // If we couldn't figure out a reasonable help message default to something generic. if (error_out->empty()) { *error_out = "insufficient permissions for device"; } continue; } Loading Loading @@ -748,14 +752,17 @@ atransport* acquire_one_transport(TransportType type, const char* serial, return result; } const char* atransport::connection_state_name() const { const std::string atransport::connection_state_name() const { switch (connection_state) { case kCsOffline: return "offline"; case kCsBootloader: return "bootloader"; case kCsDevice: return "device"; case kCsHost: return "host"; case kCsRecovery: return "recovery"; case kCsNoPerm: return "no permissions"; case kCsNoPerm: { std::string message = UsbNoPermissionsShortHelpText(); return message.empty() ? "no permissions" : message; } case kCsSideload: return "sideload"; case kCsUnauthorized: return "unauthorized"; default: return "unknown"; Loading Loading @@ -866,7 +873,8 @@ static void append_transport(const atransport* t, std::string* result, *result += '\t'; *result += t->connection_state_name(); } else { android::base::StringAppendF(result, "%-22s %s", serial, t->connection_state_name()); android::base::StringAppendF(result, "%-22s %s", serial, t->connection_state_name().c_str()); append_transport_info(result, "", t->devpath, false); append_transport_info(result, "product:", t->product, false); Loading
adb/transport.h +1 −1 Original line number Diff line number Diff line Loading @@ -90,7 +90,7 @@ public: fdevent auth_fde; size_t failed_auth_attempts = 0; const char* connection_state_name() const; const std::string connection_state_name() const; void update_version(int version, size_t payload); int get_protocol_version() const; Loading
adb/usb_linux.cpp +52 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ #include <dirent.h> #include <errno.h> #include <fcntl.h> #include <grp.h> #include <linux/usb/ch9.h> #include <linux/usbdevice_fs.h> #include <linux/version.h> Loading Loading @@ -595,3 +596,54 @@ void usb_init() { fatal_errno("cannot create device_poll thread"); } } static const char kPermissionsHelpUrl[] = "developer.android.com/tools/device.html"; // Returns a message describing any potential problems we find with udev, or nullptr if we can't // find plugdev information (i.e. udev is not installed). static const char* GetUdevProblem() { errno = 0; group* plugdev_group = getgrnam("plugdev"); if (plugdev_group == nullptr) { if (errno != 0) { D("failed to read plugdev group info: %s", strerror(errno)); } // We can't give any generally useful advice here, just let the caller print the help URL. return nullptr; } // getgroups(2) indicates that the group_member() may not check the egid so we check it // additionally just to be sure. if (group_member(plugdev_group->gr_gid) || getegid() == plugdev_group->gr_gid) { // The user is in plugdev so the problem is likely with the udev rules. return "verify udev rules"; } return "udev requires plugdev group membership"; } // Short help text must be a single line, and will look something like: // no permissions (reason); see <URL> std::string UsbNoPermissionsShortHelpText() { std::string help_text = "no permissions"; const char* problem = GetUdevProblem(); if (problem != nullptr) { help_text += android::base::StringPrintf(" (%s)", problem); } return android::base::StringPrintf("%s; see [%s]", help_text.c_str(), kPermissionsHelpUrl); } // Long help text can span multiple lines and should provide more detailed information. std::string UsbNoPermissionsLongHelpText() { std::string header = "USB permission failure"; const char* problem = GetUdevProblem(); if (problem != nullptr) { header += android::base::StringPrintf(": %s", problem); } return android::base::StringPrintf("%s.\nSee [%s] for more information.", header.c_str(), kPermissionsHelpUrl); }
adb/usb_linux_client.cpp +9 −0 Original line number Diff line number Diff line Loading @@ -571,3 +571,12 @@ void usb_kick(usb_handle *h) { h->kick(h); } // kCsNoPerm is a host-side issue, we can just ignore it here. std::string UsbNoPermissionsShortHelpText() { return ""; } std::string UsbNoPermissionsLongHelpText() { return ""; }