Merge "adb: add authorizing, connecting states to transport."

am: c97cea0d20

Change-Id: Ie42bbe9205660c59d144563bb7b71377df9fbed1
This commit is contained in:
Josh Gao 2018-05-09 13:48:59 -07:00 committed by android-build-merger
commit ec0dd9b71f
6 changed files with 68 additions and 30 deletions

View file

@ -365,8 +365,8 @@ void handle_packet(apacket *p, atransport *t)
switch (p->msg.arg0) { switch (p->msg.arg0) {
#if ADB_HOST #if ADB_HOST
case ADB_AUTH_TOKEN: case ADB_AUTH_TOKEN:
if (t->GetConnectionState() == kCsOffline) { if (t->GetConnectionState() != kCsAuthorizing) {
t->SetConnectionState(kCsUnauthorized); t->SetConnectionState(kCsAuthorizing);
} }
send_auth_response(p->payload.data(), p->msg.data_length, t); send_auth_response(p->payload.data(), p->msg.data_length, t);
break; break;
@ -1103,14 +1103,11 @@ int handle_host_request(const char* service, TransportType type, const char* ser
if (!strcmp(service, "reconnect-offline")) { if (!strcmp(service, "reconnect-offline")) {
std::string response; std::string response;
close_usb_devices([&response](const atransport* transport) { close_usb_devices([&response](const atransport* transport) {
switch (transport->GetConnectionState()) { if (!ConnectionStateIsOnline(transport->GetConnectionState())) {
case kCsOffline: response += "reconnecting " + transport->serial_name() + "\n";
case kCsUnauthorized: return true;
response += "reconnecting " + transport->serial_name() + "\n";
return true;
default:
return false;
} }
return false;
}); });
if (!response.empty()) { if (!response.empty()) {
response.resize(response.size() - 1); response.resize(response.size() - 1);

View file

@ -95,16 +95,33 @@ enum TransportType {
enum ConnectionState { enum ConnectionState {
kCsAny = -1, kCsAny = -1,
kCsOffline = 0,
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, kCsBootloader,
kCsDevice, kCsDevice,
kCsHost, kCsHost,
kCsRecovery, kCsRecovery,
kCsNoPerm, // Insufficient permissions to communicate with the device.
kCsSideload, kCsSideload,
kCsUnauthorized,
}; };
inline bool ConnectionStateIsOnline(ConnectionState state) {
switch (state) {
case kCsBootloader:
case kCsDevice:
case kCsHost:
case kCsRecovery:
case kCsSideload:
return true;
default:
return false;
}
}
void print_packet(const char* label, apacket* p); void print_packet(const char* label, apacket* p);
// These use the system (v)fprintf, not the adb prefixed ones defined in sysdeps.h, so they // These use the system (v)fprintf, not the adb prefixed ones defined in sysdeps.h, so they

View file

@ -464,6 +464,7 @@ void send_auth_response(const char* token, size_t token_size, atransport* t) {
std::shared_ptr<RSA> key = t->NextKey(); std::shared_ptr<RSA> key = t->NextKey();
if (key == nullptr) { if (key == nullptr) {
// No more private keys to try, send the public key. // No more private keys to try, send the public key.
t->SetConnectionState(kCsUnauthorized);
send_auth_publickey(t); send_auth_publickey(t);
return; return;
} }

View file

@ -750,7 +750,7 @@ static int smart_socket_enqueue(asocket* s, apacket::payload_type data) {
if (!s->transport) { if (!s->transport) {
SendFail(s->peer->fd, "device offline (no transport)"); SendFail(s->peer->fd, "device offline (no transport)");
goto fail; goto fail;
} else if (s->transport->GetConnectionState() == kCsOffline) { } else if (!ConnectionStateIsOnline(s->transport->GetConnectionState())) {
/* if there's no remote we fail the connection /* if there's no remote we fail the connection
** right here and terminate it ** right here and terminate it
*/ */

View file

@ -708,22 +708,41 @@ atransport* acquire_one_transport(TransportType type, const char* serial, Transp
} }
lock.unlock(); lock.unlock();
// Don't return unauthorized devices; the caller can't do anything with them. if (result && !accept_any_state) {
if (result && result->GetConnectionState() == kCsUnauthorized && !accept_any_state) { // The caller requires an active transport.
*error_out = "device unauthorized.\n"; // Make sure that we're actually connected.
char* ADB_VENDOR_KEYS = getenv("ADB_VENDOR_KEYS"); ConnectionState state = result->GetConnectionState();
*error_out += "This adb server's $ADB_VENDOR_KEYS is "; switch (state) {
*error_out += ADB_VENDOR_KEYS ? ADB_VENDOR_KEYS : "not set"; case kCsConnecting:
*error_out += "\n"; *error_out = "device still connecting";
*error_out += "Try 'adb kill-server' if that seems wrong.\n"; result = nullptr;
*error_out += "Otherwise check for a confirmation dialog on your device."; break;
result = nullptr;
}
// Don't return offline devices; the caller can't do anything with them. case kCsAuthorizing:
if (result && result->GetConnectionState() == kCsOffline && !accept_any_state) { *error_out = "device still authorizing";
*error_out = "device offline"; result = nullptr;
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) { if (result) {
@ -802,6 +821,10 @@ std::string atransport::connection_state_name() const {
return "sideload"; return "sideload";
case kCsUnauthorized: case kCsUnauthorized:
return "unauthorized"; return "unauthorized";
case kCsAuthorizing:
return "authorizing";
case kCsConnecting:
return "connecting";
default: default:
return "unknown"; return "unknown";
} }
@ -1080,7 +1103,7 @@ void kick_all_tcp_devices() {
void register_usb_transport(usb_handle* usb, const char* serial, const char* devpath, void register_usb_transport(usb_handle* usb, const char* serial, const char* devpath,
unsigned writeable) { unsigned writeable) {
atransport* t = new atransport((writeable ? kCsOffline : kCsNoPerm)); atransport* t = new atransport((writeable ? kCsConnecting : kCsNoPerm));
D("transport: %p init'ing for usb_handle %p (sn='%s')", t, usb, serial ? serial : ""); D("transport: %p init'ing for usb_handle %p (sn='%s')", t, usb, serial ? serial : "");
init_usb_transport(t, usb); init_usb_transport(t, usb);

View file

@ -198,7 +198,7 @@ class atransport {
// class in one go is a very large change. Given how bad our testing is, // class in one go is a very large change. Given how bad our testing is,
// it's better to do this piece by piece. // it's better to do this piece by piece.
atransport(ConnectionState state = kCsOffline) atransport(ConnectionState state = kCsConnecting)
: id(NextTransportId()), : id(NextTransportId()),
connection_state_(state), connection_state_(state),
connection_waitable_(std::make_shared<ConnectionWaitable>()), connection_waitable_(std::make_shared<ConnectionWaitable>()),