Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 216d158d authored by Josh Gao's avatar Josh Gao Committed by Gerrit Code Review
Browse files

Merge changes I86c3ec0f,I57d1a30a,Ib50d289b,I791a4f82,I316a8799, ...

* changes:
  adb: switch sockets.cpp to ConsumePrefix.
  adbd: switch abb to ConsumePrefix.
  adb: increment server version.
  adb: wait for device to disconnect upon `adb root`.
  adb: implement wait-for-disconnect.
  adb: tell the client what transport it received.
  adbd: switch daemon/services to ConsumePrefix.
  adb: switch host_service_to_socket to string_view.
  adb: switch handle_host_request to string_view.
  adb: switch adb_io.h to string_view.
  adb: add helper to consume a prefix on a string_view.
  adb: make ParseUint reject garbage at the end by default.
parents 1706eb08 43f38059
Loading
Loading
Loading
Loading
+100 −70
Original line number Diff line number Diff line
@@ -1018,9 +1018,10 @@ static int SendOkay(int fd, const std::string& s) {
    return 0;
}

bool handle_host_request(const char* service, TransportType type, const char* serial,
                        TransportId transport_id, int reply_fd, asocket* s) {
    if (strcmp(service, "kill") == 0) {
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 @@ bool handle_host_request(const char* service, TransportType type, const char* se
        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 (!strncmp(service, "transport", strlen("transport"))) {
    LOG(DEBUG) << "handle_host_request(" << service << ")";

    // Transport selection:
    if (service.starts_with("transport") || service.starts_with("tport:")) {
        TransportType type = kTransportAny;

        if (!strncmp(service, "transport-id:", strlen("transport-id:"))) {
            service += strlen("transport-id:");
            transport_id = strtoll(service, const_cast<char**>(&service), 10);
            if (*service != '\0') {
        std::string serial_storage;
        bool legacy = 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;
            }

            // 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 true;
                    return HostRequestResult::Handled;
                }
        } else if (!strncmp(service, "transport-usb", strlen("transport-usb"))) {
            } else if (service == "transport-usb") {
                type = kTransportUsb;
        } else if (!strncmp(service, "transport-local", strlen("transport-local"))) {
            } else if (service == "transport-local") {
                type = kTransportLocal;
        } else if (!strncmp(service, "transport-any", strlen("transport-any"))) {
            } else if (service == "transport-any") {
                type = kTransportAny;
        } else if (!strncmp(service, "transport:", strlen("transport:"))) {
            service += strlen("transport:");
            serial = service;
            } else if (ConsumePrefix(&service, "transport:")) {
                serial_storage = service;
                serial = serial_storage.c_str();
            }
        }

        std::string error;
@@ -1063,27 +1084,29 @@ bool handle_host_request(const char* service, TransportType type, const char* se
            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;
        }
    }

    // return a list of all connected devices
    if (!strncmp(service, "devices", 7)) {
        bool long_listing = (strcmp(service+7, "-l") == 0);
        if (long_listing || service[7] == 0) {
    if (service == "devices" || service == "devices-l") {
        bool long_listing = service == "devices-l";
        D("Getting device list...");
        std::string device_list = list_transports(long_listing);
        D("Sending device list...");
        SendOkay(reply_fd, device_list);
        }
        return true;
        return HostRequestResult::Handled;
    }

    if (!strcmp(service, "reconnect-offline")) {
    if (service == "reconnect-offline") {
        std::string response;
        close_usb_devices([&response](const atransport* transport) {
            if (!ConnectionStateIsOnline(transport->GetConnectionState())) {
@@ -1096,10 +1119,10 @@ bool handle_host_request(const char* service, TransportType type, const char* se
            response.resize(response.size() - 1);
        }
        SendOkay(reply_fd, response);
        return true;
        return HostRequestResult::Handled;
    }

    if (!strcmp(service, "features")) {
    if (service == "features") {
        std::string error;
        atransport* t = acquire_one_transport(type, serial, transport_id, nullptr, &error);
        if (t != nullptr) {
@@ -1107,10 +1130,10 @@ bool handle_host_request(const char* service, TransportType type, const char* se
        } else {
            SendFail(reply_fd, error);
        }
        return true;
        return HostRequestResult::Handled;
    }

    if (!strcmp(service, "host-features")) {
    if (service == "host-features") {
        FeatureSet features = supported_features();
        // Abuse features to report libusb status.
        if (should_use_libusb()) {
@@ -1118,16 +1141,16 @@ bool handle_host_request(const char* service, TransportType type, const char* se
        }
        features.insert(kFeaturePushSync);
        SendOkay(reply_fd, FeatureSetToString(features));
        return true;
        return HostRequestResult::Handled;
    }

    // remove TCP transport
    if (!strncmp(service, "disconnect:", 11)) {
        const std::string address(service + 11);
    if (service.starts_with("disconnect:")) {
        std::string address(service.substr(11));
        if (address.empty()) {
            kick_all_tcp_devices();
            SendOkay(reply_fd, "disconnected everything");
            return true;
            return HostRequestResult::Handled;
        }

        std::string serial;
@@ -1139,26 +1162,26 @@ bool handle_host_request(const char* service, TransportType type, const char* se
        } 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 (!strcmp(service, "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.
    if (!strcmp(service, "get-serialno")) {
    if (service == "get-serialno") {
        std::string error;
        atransport* t = acquire_one_transport(type, serial, transport_id, nullptr, &error);
        if (t) {
@@ -1166,9 +1189,9 @@ bool handle_host_request(const char* service, TransportType type, const char* se
        } else {
            SendFail(reply_fd, error);
        }
        return true;
        return HostRequestResult::Handled;
    }
    if (!strcmp(service, "get-devpath")) {
    if (service == "get-devpath") {
        std::string error;
        atransport* t = acquire_one_transport(type, serial, transport_id, nullptr, &error);
        if (t) {
@@ -1176,9 +1199,9 @@ bool handle_host_request(const char* service, TransportType type, const char* se
        } else {
            SendFail(reply_fd, error);
        }
        return true;
        return HostRequestResult::Handled;
    }
    if (!strcmp(service, "get-state")) {
    if (service == "get-state") {
        std::string error;
        atransport* t = acquire_one_transport(type, serial, transport_id, nullptr, &error);
        if (t) {
@@ -1186,18 +1209,23 @@ bool handle_host_request(const char* service, TransportType type, const char* se
        } else {
            SendFail(reply_fd, error);
        }
        return true;
        return HostRequestResult::Handled;
    }

    // Indicates a new emulator instance has started.
    if (!strncmp(service, "emulator:", 9)) {
        int  port = atoi(service+9);
    if (ConsumePrefix(&service, "emulator:")) {
        unsigned int port;
        if (!ParseUint(&port, service)) {
          LOG(ERROR) << "received invalid port for emulator: " << service;
        } else {
          local_connect(port);
        }

        /* we don't even need to send a reply */
        return true;
        return HostRequestResult::Handled;
    }

    if (!strcmp(service, "reconnect")) {
    if (service == "reconnect") {
        std::string response;
        atransport* t = acquire_one_transport(type, serial, transport_id, nullptr, &response, true);
        if (t != nullptr) {
@@ -1206,19 +1234,21 @@ bool handle_host_request(const char* service, TransportType type, const char* se
                    "reconnecting " + t->serial_name() + " [" + t->connection_state_name() + "]\n";
        }
        SendOkay(reply_fd, response);
        return true;
        return HostRequestResult::Handled;
    }

    if (handle_forward_request(service,
    // TODO: Switch handle_forward_request to string_view.
    std::string service_str(service);
    if (handle_forward_request(
                service_str.c_str(),
                [=](std::string* error) {
                                   return acquire_one_transport(type, serial, transport_id, nullptr,
                                                                error);
                    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();
+12 −4
Original line number Diff line number Diff line
@@ -59,7 +59,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 40
#define ADB_SERVER_VERSION 41

using TransportId = uint64_t;
class atransport;
@@ -145,7 +145,8 @@ unique_fd daemon_service_to_fd(std::string_view name, atransport* transport);
#endif

#if ADB_HOST
asocket* host_service_to_socket(const char* name, const char* serial, TransportId transport_id);
asocket* host_service_to_socket(std::string_view name, std::string_view serial,
                                TransportId transport_id);
#endif

#if !ADB_HOST
@@ -218,8 +219,15 @@ extern const char* adb_device_banner;
#define USB_FFS_ADB_IN USB_FFS_ADB_EP(ep2)
#endif

bool handle_host_request(const char* service, TransportType type, const char* serial,
                         TransportId transport_id, int reply_fd, asocket* s);
enum class HostRequestResult {
    Handled,
    SwitchedTransport,
    Unhandled,
};

HostRequestResult handle_host_request(std::string_view service, TransportType type,
                                      const char* serial, TransportId transport_id, int reply_fd,
                                      asocket* s);

void handle_online(atransport* t);
void handle_offline(atransport* t);
+2 −2
Original line number Diff line number Diff line
@@ -34,7 +34,7 @@
#include "adb_utils.h"
#include "sysdeps.h"

bool SendProtocolString(int fd, const std::string& s) {
bool SendProtocolString(int fd, std::string_view s) {
    unsigned int length = s.size();
    if (length > MAX_PAYLOAD - 4) {
        errno = EMSGSIZE;
@@ -69,7 +69,7 @@ bool SendOkay(int fd) {
    return WriteFdExactly(fd, "OKAY", 4);
}

bool SendFail(int fd, const std::string& reason) {
bool SendFail(int fd, std::string_view reason) {
    return WriteFdExactly(fd, "FAIL", 4) && SendProtocolString(fd, reason);
}

+3 −2
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@
#include <sys/types.h>

#include <string>
#include <string_view>

#include "adb_unique_fd.h"

@@ -27,10 +28,10 @@
bool SendOkay(int fd);

// Sends the protocol "FAIL" message, with the given failure reason.
bool SendFail(int fd, const std::string& reason);
bool SendFail(int fd, std::string_view reason);

// Writes a protocol-format string; a four hex digit length followed by the string data.
bool SendProtocolString(int fd, const std::string& s);
bool SendProtocolString(int fd, std::string_view s);

// Reads a protocol-format string; a four hex digit length followed by the string data.
bool ReadProtocolString(int fd, std::string* s, std::string* error);
+12 −1
Original line number Diff line number Diff line
@@ -110,7 +110,7 @@ inline std::string_view StripTrailingNulls(std::string_view str) {

// Base-10 stroll on a string_view.
template <typename T>
inline bool ParseUint(T* result, std::string_view str, std::string_view* remaining) {
inline bool ParseUint(T* result, std::string_view str, std::string_view* remaining = nullptr) {
    if (str.empty() || !isdigit(str[0])) {
        return false;
    }
@@ -135,6 +135,17 @@ inline bool ParseUint(T* result, std::string_view str, std::string_view* remaini
    *result = value;
    if (remaining) {
        *remaining = str.substr(it - str.begin());
    } else {
      return it == str.end();
    }

    return true;
}

inline bool ConsumePrefix(std::string_view* str, std::string_view prefix) {
  if (str->starts_with(prefix)) {
    str->remove_prefix(prefix.size());
    return true;
  }
  return false;
}
Loading