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

Commit ba7a198c authored by Elliott Hughes's avatar Elliott Hughes Committed by android-build-merger
Browse files

Merge "adb host: add device state in "adb wait-for-*""

am: 82509e79

* commit '82509e79':
  adb host: add device state in "adb wait-for-*"
parents 67a6d861 82509e79
Loading
Loading
Loading
Loading
+37 −4
Original line number Diff line number Diff line
@@ -204,7 +204,10 @@ static void help() {
        "  adb version                  - show version num\n"
        "\n"
        "scripting:\n"
        "  adb wait-for-device          - block until device is online\n"
        "  adb wait-for[-<transport>]-<state>\n"
        "                               - wait for device to be in the given state:\n"
        "                                 device, recovery, sideload, or bootloader\n"
        "                                 Transport is: usb, local or any [default=any]\n"
        "  adb start-server             - ensure that there is a server running\n"
        "  adb kill-server              - kill the server if it is running\n"
        "  adb get-state                - prints: offline | bootloader | device\n"
@@ -1010,19 +1013,49 @@ static int ppp(int argc, const char** argv) {
#endif /* !defined(_WIN32) */
}

static bool check_wait_for_device_syntax(const char* service) {
    // TODO: when we have libc++ for Windows, use a regular expression instead.
    // wait-for-((any|local|usb)-)?(bootloader|device|recovery|sideload)

    char type[20];
    char state[20];
    int length = 0;
    if (sscanf(service, "wait-for-%20[a-z]-%20[a-z]%n", type, state, &length) < 2 ||
        length != static_cast<int>(strlen(service))) {
        fprintf(stderr, "adb: couldn't parse 'wait-for' command: %s\n", service);
        return false;
    }

    if (strcmp(type, "any") != 0 && strcmp(type, "local") != 0 && strcmp(type, "usb") != 0) {
        fprintf(stderr, "adb: unknown type %s; expected 'any', 'local', or 'usb'\n", type);
        return false;
    }
    if (strcmp(state, "bootloader") != 0 && strcmp(state, "device") != 0 &&
        strcmp(state, "recovery") != 0 && strcmp(state, "sideload") != 0) {
        fprintf(stderr, "adb: unknown state %s; "
                        "expected 'bootloader', 'device', 'recovery', or 'sideload'\n", state);
        return false;
    }
    return true;
}

static bool wait_for_device(const char* service, TransportType t, const char* serial) {
    // Was the caller vague about what they'd like us to wait for?
    // If so, check they weren't more specific in their choice of transport type.
    if (strcmp(service, "wait-for-device") == 0) {
        if (t == kTransportUsb) {
            service = "wait-for-usb";
            service = "wait-for-usb-device";
        } else if (t == kTransportLocal) {
            service = "wait-for-local";
            service = "wait-for-local-device";
        } else {
            service = "wait-for-any";
            service = "wait-for-any-device";
        }
    }

    if (!check_wait_for_device_syntax(service)) {
        return false;
    }

    std::string cmd = format_host_command(service, t, serial);
    return adb_command(cmd);
}
+29 −28
Original line number Diff line number Diff line
@@ -356,19 +356,19 @@ int service_to_fd(const char* name, const atransport* transport) {
#if ADB_HOST
struct state_info {
    TransportType transport_type;
    char* serial;
    std::string serial;
    ConnectionState state;
};

static void wait_for_state(int fd, void* cookie) {
    state_info* sinfo = reinterpret_cast<state_info*>(cookie);
static void wait_for_state(int fd, void* data) {
    std::unique_ptr<state_info> sinfo(reinterpret_cast<state_info*>(data));

    D("wait_for_state %d", sinfo->state);

    while (true) {
        bool is_ambiguous = false;
        std::string error = "unknown error";
        atransport* t = acquire_one_transport(sinfo->transport_type, sinfo->serial,
        atransport* t = acquire_one_transport(sinfo->transport_type, sinfo->serial.c_str(),
                                              &is_ambiguous, &error);
        if (t != nullptr && t->connection_state == sinfo->state) {
            SendOkay(fd);
@@ -382,10 +382,6 @@ static void wait_for_state(int fd, void* cookie) {
        }
    }

    if (sinfo->serial) {
        free(sinfo->serial);
    }
    free(sinfo);
    adb_close(fd);
    D("wait_for_state is done");
}
@@ -491,38 +487,43 @@ static void connect_service(int fd, void* data) {
asocket* host_service_to_socket(const char* name, const char* serial) {
    if (!strcmp(name,"track-devices")) {
        return create_device_tracker();
    } else if (!strncmp(name, "wait-for-", strlen("wait-for-"))) {
        auto sinfo = reinterpret_cast<state_info*>(malloc(sizeof(state_info)));
    } else if (android::base::StartsWith(name, "wait-for-")) {
        name += strlen("wait-for-");

        std::unique_ptr<state_info> sinfo(new state_info);
        if (sinfo == nullptr) {
            fprintf(stderr, "couldn't allocate state_info: %s", strerror(errno));
            return NULL;
            return nullptr;
        }

        if (serial)
            sinfo->serial = strdup(serial);
        else
            sinfo->serial = NULL;

        name += strlen("wait-for-");
        if (serial) sinfo->serial = serial;

        if (!strncmp(name, "local", strlen("local"))) {
        if (android::base::StartsWith(name, "local")) {
            name += strlen("local");
            sinfo->transport_type = kTransportLocal;
            sinfo->state = kCsDevice;
        } else if (!strncmp(name, "usb", strlen("usb"))) {
        } else if (android::base::StartsWith(name, "usb")) {
            name += strlen("usb");
            sinfo->transport_type = kTransportUsb;
            sinfo->state = kCsDevice;
        } else if (!strncmp(name, "any", strlen("any"))) {
        } else if (android::base::StartsWith(name, "any")) {
            name += strlen("any");
            sinfo->transport_type = kTransportAny;
            sinfo->state = kCsDevice;
        } else {
            if (sinfo->serial) {
                free(sinfo->serial);
            return nullptr;
        }
            free(sinfo);
            return NULL;

        if (!strcmp(name, "-device")) {
            sinfo->state = kCsDevice;
        } else if (!strcmp(name, "-recovery")) {
            sinfo->state = kCsRecovery;
        } else if (!strcmp(name, "-sideload")) {
            sinfo->state = kCsSideload;
        } else if (!strcmp(name, "-bootloader")) {
            sinfo->state = kCsBootloader;
        } else {
            return nullptr;
        }

        int fd = create_service_thread(wait_for_state, sinfo);
        int fd = create_service_thread(wait_for_state, sinfo.release());
        return create_local_socket(fd);
    } else if (!strncmp(name, "connect:", 8)) {
        char* host = strdup(name + 8);