Skip to content

Commit

Permalink
Use vector for listing ADB devices
Browse files Browse the repository at this point in the history
This avoids the hardcoded maximum number of ADB devices detected (16).

Refs #3029 <#3029>
PR #3035 <#3035>

Co-authored-by: Daniel Ansorregui <[email protected]>
  • Loading branch information
rom1v and Daniel Ansorregui committed Feb 20, 2022
1 parent 1790e88 commit 4b8cb04
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 85 deletions.
44 changes: 22 additions & 22 deletions app/src/adb/adb.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <stdlib.h>
#include <string.h>

#include "adb_device.h"
#include "adb_parser.h"
#include "util/file.h"
#include "util/log.h"
Expand Down Expand Up @@ -392,16 +393,16 @@ sc_adb_disconnect(struct sc_intr *intr, const char *ip_port, unsigned flags) {
return process_check_success_intr(intr, pid, "adb disconnect", flags);
}

static ssize_t
static bool
sc_adb_list_devices(struct sc_intr *intr, unsigned flags,
struct sc_adb_device *devices, size_t len) {
struct sc_vec_adb_devices *out_vec) {
const char *const argv[] = SC_ADB_COMMAND("devices", "-l");

sc_pipe pout;
sc_pid pid = sc_adb_execute_p(argv, flags, &pout);
if (pid == SC_PROCESS_NONE) {
LOGE("Could not execute \"adb devices -l\"");
return -1;
return false;
}

char buf[4096];
Expand All @@ -410,11 +411,11 @@ sc_adb_list_devices(struct sc_intr *intr, unsigned flags,

bool ok = process_check_success_intr(intr, pid, "adb devices -l", flags);
if (!ok) {
return -1;
return false;
}

if (r == -1) {
return -1;
return false;
}

assert((size_t) r < sizeof(buf));
Expand All @@ -423,14 +424,14 @@ sc_adb_list_devices(struct sc_intr *intr, unsigned flags,
// in the buffer in a single pass
LOGW("Result of \"adb devices -l\" does not fit in 4Kb. "
"Please report an issue.");
return -1;
return false;
}

// It is parsed as a NUL-terminated string
buf[r] = '\0';

// List all devices to the output list directly
return sc_adb_parse_devices(buf, devices, len);
return sc_adb_parse_devices(buf, out_vec);
}

static bool
Expand Down Expand Up @@ -529,22 +530,21 @@ bool
sc_adb_select_device(struct sc_intr *intr,
const struct sc_adb_device_selector *selector,
unsigned flags, struct sc_adb_device *out_device) {
struct sc_adb_device devices[16];
ssize_t count =
sc_adb_list_devices(intr, flags, devices, ARRAY_LEN(devices));
if (count == -1) {
struct sc_vec_adb_devices vec = SC_VECTOR_INITIALIZER;
bool ok = sc_adb_list_devices(intr, flags, &vec);
if (!ok) {
LOGE("Could not list ADB devices");
return false;
}

if (count == 0) {
if (vec.size == 0) {
LOGE("Could not find any ADB device");
return false;
}

size_t sel_idx; // index of the single matching device if sel_count == 1
size_t sel_count =
sc_adb_devices_select(devices, count, selector, &sel_idx);
sc_adb_devices_select(vec.data, vec.size, selector, &sel_idx);

if (sel_count == 0) {
// if count > 0 && sel_count == 0, then necessarily a selection is
Expand All @@ -567,8 +567,8 @@ sc_adb_select_device(struct sc_intr *intr,
break;
}

sc_adb_devices_log(SC_LOG_LEVEL_ERROR, devices, count);
sc_adb_devices_destroy_all(devices, count);
sc_adb_devices_log(SC_LOG_LEVEL_ERROR, vec.data, vec.size);
sc_adb_devices_destroy(&vec);
return false;
}

Expand All @@ -594,28 +594,28 @@ sc_adb_select_device(struct sc_intr *intr,
assert(!"Unexpected selector type");
break;
}
sc_adb_devices_log(SC_LOG_LEVEL_ERROR, devices, count);
sc_adb_devices_log(SC_LOG_LEVEL_ERROR, vec.data, vec.size);
LOGE("Select a device via -s (--serial), -d (--select-usb) or -e "
"(--select-tcpip)");
sc_adb_devices_destroy_all(devices, count);
sc_adb_devices_destroy(&vec);
return false;
}

assert(sel_count == 1); // sel_idx is valid only if sel_count == 1
struct sc_adb_device *device = &devices[sel_idx];
struct sc_adb_device *device = &vec.data[sel_idx];

bool ok = sc_adb_device_check_state(device, devices, count);
ok = sc_adb_device_check_state(device, vec.data, vec.size);
if (!ok) {
sc_adb_devices_destroy_all(devices, count);
sc_adb_devices_destroy(&vec);
return false;
}

LOGD("ADB device found:");
sc_adb_devices_log(SC_LOG_LEVEL_DEBUG, devices, count);
sc_adb_devices_log(SC_LOG_LEVEL_DEBUG, vec.data, vec.size);

// Move devics into out_device (do not destroy device)
sc_adb_device_move(out_device, device);
sc_adb_devices_destroy_all(devices, count);
sc_adb_devices_destroy(&vec);
return true;
}

Expand Down
7 changes: 4 additions & 3 deletions app/src/adb/adb_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@ sc_adb_device_move(struct sc_adb_device *dst, struct sc_adb_device *src) {
}

void
sc_adb_devices_destroy_all(struct sc_adb_device *devices, size_t count) {
for (size_t i = 0; i < count; ++i) {
sc_adb_device_destroy(&devices[i]);
sc_adb_devices_destroy(struct sc_vec_adb_devices *devices) {
for (size_t i = 0; i < devices->size; ++i) {
sc_adb_device_destroy(&devices->data[i]);
}
sc_vector_destroy(devices);
}

6 changes: 5 additions & 1 deletion app/src/adb/adb_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,17 @@
#include <stdbool.h>
#include <stddef.h>

#include "util/vector.h"

struct sc_adb_device {
char *serial;
char *state;
char *model;
bool selected;
};

struct sc_vec_adb_devices SC_VECTOR(struct sc_adb_device);

void
sc_adb_device_destroy(struct sc_adb_device *device);

Expand All @@ -29,6 +33,6 @@ void
sc_adb_device_move(struct sc_adb_device *dst, struct sc_adb_device *src);

void
sc_adb_devices_destroy_all(struct sc_adb_device *devices, size_t count);
sc_adb_devices_destroy(struct sc_vec_adb_devices *devices);

#endif
30 changes: 13 additions & 17 deletions app/src/adb/adb_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,8 @@ sc_adb_parse_device(char *line, struct sc_adb_device *device) {
return true;
}

ssize_t
sc_adb_parse_devices(char *str, struct sc_adb_device *devices,
size_t devices_len) {
size_t dev_count = 0;

bool
sc_adb_parse_devices(char *str, struct sc_vec_adb_devices *out_vec) {
#define HEADER "List of devices attached"
#define HEADER_LEN (sizeof(HEADER) - 1)
bool header_found = false;
Expand Down Expand Up @@ -144,25 +141,24 @@ sc_adb_parse_devices(char *str, struct sc_adb_device *devices,
size_t line_len = sc_str_remove_trailing_cr(line, len);
line[line_len] = '\0';

bool ok = sc_adb_parse_device(line, &devices[dev_count]);
struct sc_adb_device device;
bool ok = sc_adb_parse_device(line, &device);
if (!ok) {
continue;
}

++dev_count;

assert(dev_count <= devices_len);
if (dev_count == devices_len) {
// Max number of devices reached
break;
ok = sc_vector_push(out_vec, device);
if (!ok) {
LOG_OOM();
LOGE("Could not push adb_device to vector");
sc_adb_device_destroy(&device);
// continue anyway
continue;
}
}

if (!header_found) {
return -1;
}

return dev_count;
assert(header_found || out_vec->size == 0);
return header_found;
}

static char *
Expand Down
5 changes: 2 additions & 3 deletions app/src/adb/adb_parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,8 @@
*
* Warning: this function modifies the buffer for optimization purposes.
*/
ssize_t
sc_adb_parse_devices(char *str, struct sc_adb_device *devices,
size_t devices_len);
bool
sc_adb_parse_devices(char *str, struct sc_vec_adb_devices *out_vec);

/**
* Parse the ip from the output of `adb shell ip route`
Expand Down
Loading

0 comments on commit 4b8cb04

Please sign in to comment.