Skip to content

Commit

Permalink
Merge "adb: fix two device offline problems."
Browse files Browse the repository at this point in the history
  • Loading branch information
Treehugger Robot authored and Gerrit Code Review committed Apr 20, 2017
2 parents d998280 + b5e1141 commit 2e82107
Show file tree
Hide file tree
Showing 20 changed files with 356 additions and 108 deletions.
63 changes: 36 additions & 27 deletions adb/adb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,19 @@ void send_connect(atransport* t) {
send_packet(cp, t);
}

#if ADB_HOST

void SendConnectOnHost(atransport* t) {
// Send an empty message before A_CNXN message. This is because the data toggle of the ep_out on
// host and ep_in on device may not be the same.
apacket* p = get_apacket();
CHECK(p);
send_packet(p, t);
send_connect(t);
}

#endif

// qual_overwrite is used to overwrite a qualifier string. dst is a
// pointer to a char pointer. It is assumed that if *dst is non-NULL, it
// was malloc'ed and needs to freed. *dst will be set to a dup of src.
Expand Down Expand Up @@ -299,29 +312,29 @@ void parse_banner(const std::string& banner, atransport* t) {
const std::string& type = pieces[0];
if (type == "bootloader") {
D("setting connection_state to kCsBootloader");
t->connection_state = kCsBootloader;
t->SetConnectionState(kCsBootloader);
update_transports();
} else if (type == "device") {
D("setting connection_state to kCsDevice");
t->connection_state = kCsDevice;
t->SetConnectionState(kCsDevice);
update_transports();
} else if (type == "recovery") {
D("setting connection_state to kCsRecovery");
t->connection_state = kCsRecovery;
t->SetConnectionState(kCsRecovery);
update_transports();
} else if (type == "sideload") {
D("setting connection_state to kCsSideload");
t->connection_state = kCsSideload;
t->SetConnectionState(kCsSideload);
update_transports();
} else {
D("setting connection_state to kCsHost");
t->connection_state = kCsHost;
t->SetConnectionState(kCsHost);
}
}

static void handle_new_connection(atransport* t, apacket* p) {
if (t->connection_state != kCsOffline) {
t->connection_state = kCsOffline;
if (t->GetConnectionState() != kCsOffline) {
t->SetConnectionState(kCsOffline);
handle_offline(t);
}

Expand Down Expand Up @@ -355,10 +368,10 @@ void handle_packet(apacket *p, atransport *t)
if (p->msg.arg0){
send_packet(p, t);
#if ADB_HOST
send_connect(t);
SendConnectOnHost(t);
#endif
} else {
t->connection_state = kCsOffline;
t->SetConnectionState(kCsOffline);
handle_offline(t);
send_packet(p, t);
}
Expand All @@ -372,7 +385,9 @@ void handle_packet(apacket *p, atransport *t)
switch (p->msg.arg0) {
#if ADB_HOST
case ADB_AUTH_TOKEN:
t->connection_state = kCsUnauthorized;
if (t->GetConnectionState() == kCsOffline) {
t->SetConnectionState(kCsUnauthorized);
}
send_auth_response(p->data, p->msg.data_length, t);
break;
#else
Expand All @@ -391,7 +406,7 @@ void handle_packet(apacket *p, atransport *t)
break;
#endif
default:
t->connection_state = kCsOffline;
t->SetConnectionState(kCsOffline);
handle_offline(t);
break;
}
Expand Down Expand Up @@ -1032,7 +1047,6 @@ static int SendOkay(int fd, const std::string& s) {
SendProtocolString(fd, s);
return 0;
}
#endif

int handle_host_request(const char* service, TransportType type,
const char* serial, int reply_fd, asocket* s) {
Expand All @@ -1051,7 +1065,6 @@ int handle_host_request(const char* service, TransportType type,
android::base::quick_exit(0);
}

#if ADB_HOST
// "transport:" is used for switching transport with a specified serial number
// "transport-usb:" is used for switching transport to the only USB transport
// "transport-local:" is used for switching transport to the only local transport
Expand Down Expand Up @@ -1096,16 +1109,10 @@ int handle_host_request(const char* service, TransportType type,
if (!strcmp(service, "reconnect-offline")) {
std::string response;
close_usb_devices([&response](const atransport* transport) {
switch (transport->connection_state) {
switch (transport->GetConnectionState()) {
case kCsOffline:
case kCsUnauthorized:
response += "reconnecting ";
if (transport->serial) {
response += transport->serial;
} else {
response += "<unknown>";
}
response += "\n";
response += "reconnecting " + transport->serial_name() + "\n";
return true;
default:
return false;
Expand All @@ -1129,7 +1136,6 @@ 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.
Expand All @@ -1139,7 +1145,6 @@ int handle_host_request(const char* service, TransportType type,
SendOkay(reply_fd, FeatureSetToString(features));
return 0;
}
#endif

// remove TCP transport
if (!strncmp(service, "disconnect:", 11)) {
Expand Down Expand Up @@ -1209,15 +1214,19 @@ int handle_host_request(const char* service, TransportType type,
}

if (!strcmp(service, "reconnect")) {
if (s->transport != nullptr) {
kick_transport(s->transport);
std::string response;
atransport* t = acquire_one_transport(type, serial, nullptr, &response, true);
if (t != nullptr) {
kick_transport(t);
response =
"reconnecting " + t->serial_name() + " [" + t->connection_state_name() + "]\n";
}
return SendOkay(reply_fd, "done");
return SendOkay(reply_fd, response);
}
#endif // ADB_HOST

int ret = handle_forward_request(service, type, serial, reply_fd);
if (ret >= 0)
return ret - 1;
return -1;
}
#endif // ADB_HOST
5 changes: 4 additions & 1 deletion adb/adb.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ int adb_server_main(int is_daemon, const std::string& socket_spec, int ack_reply
int get_available_local_transport_index();
#endif
int init_socket_transport(atransport *t, int s, int port, int local);
void init_usb_transport(atransport *t, usb_handle *usb, ConnectionState state);
void init_usb_transport(atransport* t, usb_handle* usb);

std::string getEmulatorSerialString(int console_port);
#if ADB_HOST
Expand Down Expand Up @@ -222,6 +222,9 @@ void handle_online(atransport *t);
void handle_offline(atransport *t);

void send_connect(atransport *t);
#if ADB_HOST
void SendConnectOnHost(atransport* t);
#endif

void parse_banner(const std::string&, atransport* t);

Expand Down
11 changes: 4 additions & 7 deletions adb/adb_client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,7 @@ int _adb_connect(const std::string& service, std::string* error) {
return -2;
}

if ((memcmp(&service[0],"host",4) != 0 || service == "host:reconnect") &&
switch_socket_transport(fd, error)) {
if (memcmp(&service[0], "host", 4) != 0 && switch_socket_transport(fd, error)) {
return -1;
}

Expand All @@ -147,11 +146,9 @@ int _adb_connect(const std::string& service, std::string* error) {
return -1;
}

if (service != "reconnect") {
if (!adb_status(fd, error)) {
adb_close(fd);
return -1;
}
if (!adb_status(fd, error)) {
adb_close(fd);
return -1;
}

D("_adb_connect: return fd %d", fd);
Expand Down
4 changes: 2 additions & 2 deletions adb/adb_trace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ void adb_trace_init(char** argv) {
}
#endif

#if !defined(_WIN32)
#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;
Expand All @@ -168,7 +168,7 @@ void adb_trace_init(char** argv) {

android::base::InitLogging(argv, &AdbLogger);

#if !defined(_WIN32)
#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
Expand Down
3 changes: 3 additions & 0 deletions adb/adb_trace.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ extern int adb_trace_mask;
void adb_trace_init(char**);
void adb_trace_enable(AdbTrace trace_tag);

// Include <atomic> before stdatomic.h (introduced in cutils/trace.h) to avoid compile error.
#include <atomic>

#define ATRACE_TAG ATRACE_TAG_ADB
#include <cutils/trace.h>
#include <utils/Trace.h>
Expand Down
35 changes: 17 additions & 18 deletions adb/client/usb_libusb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,19 +62,19 @@ struct DeviceHandleDeleter {
using unique_device_handle = std::unique_ptr<libusb_device_handle, DeviceHandleDeleter>;

struct transfer_info {
transfer_info(const char* name, uint16_t zero_mask) :
name(name),
transfer(libusb_alloc_transfer(0)),
zero_mask(zero_mask)
{
}
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;
Expand All @@ -96,12 +96,11 @@ struct usb_handle : public ::usb_handle {
serial(serial),
closing(false),
device_handle(device_handle.release()),
read("read", zero_mask),
write("write", zero_mask),
read("read", zero_mask, false),
write("write", zero_mask, true),
interface(interface),
bulk_in(bulk_in),
bulk_out(bulk_out) {
}
bulk_out(bulk_out) {}

~usb_handle() {
Close();
Expand Down Expand Up @@ -365,11 +364,6 @@ void usb_init() {
device_poll_thread = new std::thread(poll_for_devices);
android::base::at_quick_exit([]() {
terminate_device_poll_thread = true;
std::unique_lock<std::mutex> lock(usb_handles_mutex);
for (auto& it : usb_handles) {
it.second->Close();
}
lock.unlock();
device_poll_thread->join();
});
}
Expand Down Expand Up @@ -397,7 +391,8 @@ static int perform_usb_transfer(usb_handle* h, transfer_info* info,
return;
}

if (transfer->actual_length != transfer->length) {
// 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;
Expand Down Expand Up @@ -491,8 +486,12 @@ int usb_read(usb_handle* h, void* d, int len) {
info->transfer->num_iso_packets = 0;

int rc = perform_usb_transfer(h, info, std::move(lock));
LOG(DEBUG) << "usb_read(" << len << ") = " << rc;
return rc;
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) {
Expand Down
16 changes: 6 additions & 10 deletions adb/client/usb_linux.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,6 @@ static int usb_bulk_read(usb_handle* h, void* data, int len) {
}
}


int usb_write(usb_handle *h, const void *_data, int len)
{
D("++ usb_write ++");
Expand Down Expand Up @@ -429,32 +428,29 @@ int usb_read(usb_handle *h, void *_data, int len)
int n;

D("++ usb_read ++");
while(len > 0) {
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 != xfer) {
if (n <= 0) {
if((errno == ETIMEDOUT) && (h->fd != -1)) {
D("[ timeout ]");
if(n > 0){
data += n;
len -= n;
}
continue;
}
D("ERROR: n = %d, errno = %d (%s)",
n, errno, strerror(errno));
return -1;
}

len -= xfer;
data += xfer;
len -= n;
data += n;
}

D("-- usb_read --");
return 0;
return orig_len - len;
}

void usb_kick(usb_handle* h) {
Expand Down
2 changes: 1 addition & 1 deletion adb/client/usb_osx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -518,7 +518,7 @@ int usb_read(usb_handle *handle, void *buf, int len)
}

if (kIOReturnSuccess == result)
return 0;
return numBytes;
else {
LOG(ERROR) << "usb_read failed with status: " << std::hex << result;
}
Expand Down
Loading

0 comments on commit 2e82107

Please sign in to comment.