adb: tell the client what transport it received.
Prerequisite for making `adb root` wait for the device that it told to
restart to disappear: the client needs to know which transport to wait
on.
Bug: http://b/124244488
Test: manual
Change-Id: I474559838ad7c0e961e9d2a98c902bca3b60d6c8
diff --git a/adb/adb.cpp b/adb/adb.cpp
index 32fbb65..3c07882 100644
--- a/adb/adb.cpp
+++ b/adb/adb.cpp
@@ -1018,8 +1018,9 @@
return 0;
}
-bool handle_host_request(std::string_view service, TransportType type, const char* serial,
- TransportId transport_id, int reply_fd, asocket* s) {
+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);
@@ -1032,29 +1033,49 @@
exit(0);
}
- // "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
- // "transport-any:" is used for switching transport to the only transport
- if (service.starts_with("transport")) {
+ 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;
- if (ConsumePrefix(&service, "transport-id:")) {
- if (!ParseUint(&transport_id, service)) {
- SendFail(reply_fd, "invalid transport id");
- return 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 (ConsumePrefix(&service, "tport:")) {
+ legacy = false;
+ if (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;
}
- } else if (service == "transport-usb") {
- type = kTransportUsb;
- } else if (service == "transport-local") {
- type = kTransportLocal;
- } else if (service == "transport-any") {
- type = kTransportAny;
- } else if (ConsumePrefix(&service, "transport:")) {
- serial_storage = service;
- serial = serial_storage.c_str();
+
+ // Selection by id is unimplemented, since you obviously already know the transport id
+ // you're connecting to.
+ } else {
+ if (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 (ConsumePrefix(&service, "transport:")) {
+ serial_storage = service;
+ serial = serial_storage.c_str();
+ }
}
std::string error;
@@ -1063,11 +1084,15 @@
s->transport = t;
SendOkay(reply_fd);
- // We succesfully handled the device selection, but there's another request coming.
- return false;
+ 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 true;
+ return HostRequestResult::Handled;
}
}
@@ -1078,7 +1103,7 @@
std::string device_list = list_transports(long_listing);
D("Sending device list...");
SendOkay(reply_fd, device_list);
- return true;
+ return HostRequestResult::Handled;
}
if (service == "reconnect-offline") {
@@ -1094,7 +1119,7 @@
response.resize(response.size() - 1);
}
SendOkay(reply_fd, response);
- return true;
+ return HostRequestResult::Handled;
}
if (service == "features") {
@@ -1105,7 +1130,7 @@
} else {
SendFail(reply_fd, error);
}
- return true;
+ return HostRequestResult::Handled;
}
if (service == "host-features") {
@@ -1116,7 +1141,7 @@
}
features.insert(kFeaturePushSync);
SendOkay(reply_fd, FeatureSetToString(features));
- return true;
+ return HostRequestResult::Handled;
}
// remove TCP transport
@@ -1125,7 +1150,7 @@
if (address.empty()) {
kick_all_tcp_devices();
SendOkay(reply_fd, "disconnected everything");
- return true;
+ return HostRequestResult::Handled;
}
std::string serial;
@@ -1137,22 +1162,22 @@
} 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 true;
+ 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 true;
+ return HostRequestResult::Handled;
}
kick_transport(t);
SendOkay(reply_fd, android::base::StringPrintf("disconnected %s", address.c_str()));
- return true;
+ return HostRequestResult::Handled;
}
// Returns our value for ADB_SERVER_VERSION.
if (service == "version") {
SendOkay(reply_fd, android::base::StringPrintf("%04x", ADB_SERVER_VERSION));
- return true;
+ return HostRequestResult::Handled;
}
// These always report "unknown" rather than the actual error, for scripts.
@@ -1164,7 +1189,7 @@
} else {
SendFail(reply_fd, error);
}
- return true;
+ return HostRequestResult::Handled;
}
if (service == "get-devpath") {
std::string error;
@@ -1174,7 +1199,7 @@
} else {
SendFail(reply_fd, error);
}
- return true;
+ return HostRequestResult::Handled;
}
if (service == "get-state") {
std::string error;
@@ -1184,7 +1209,7 @@
} else {
SendFail(reply_fd, error);
}
- return true;
+ return HostRequestResult::Handled;
}
// Indicates a new emulator instance has started.
@@ -1197,7 +1222,7 @@
}
/* we don't even need to send a reply */
- return true;
+ return HostRequestResult::Handled;
}
if (service == "reconnect") {
@@ -1209,7 +1234,7 @@
"reconnecting " + t->serial_name() + " [" + t->connection_state_name() + "]\n";
}
SendOkay(reply_fd, response);
- return true;
+ return HostRequestResult::Handled;
}
// TODO: Switch handle_forward_request to string_view.
@@ -1220,10 +1245,10 @@
return acquire_one_transport(type, serial, transport_id, nullptr, error);
},
reply_fd)) {
- return true;
+ return HostRequestResult::Handled;
}
- return false;
+ return HostRequestResult::Unhandled;
}
static auto& init_mutex = *new std::mutex();