Compare commits

..

5 Commits

Author SHA1 Message Date
c37d455fa2 wip 2021-05-02 18:27:13 +02:00
6e8df74c41 serial in server_params 2021-05-02 17:22:03 +02:00
52f5c6d4c1 server_params_copy 2021-05-02 17:22:03 +02:00
efb531943d reorder server server_params 2021-05-02 17:22:03 +02:00
4dcda82582 ARRAY_LEN 2021-05-02 17:22:03 +02:00
3 changed files with 132 additions and 51 deletions

View File

@ -243,10 +243,6 @@ av_log_callback(void *avcl, int level, const char *fmt, va_list vl) {
bool bool
scrcpy(const struct scrcpy_options *options) { scrcpy(const struct scrcpy_options *options) {
if (!server_init(&server)) {
return false;
}
bool ret = false; bool ret = false;
bool server_started = false; bool server_started = false;
@ -263,6 +259,7 @@ scrcpy(const struct scrcpy_options *options) {
bool record = !!options->record_filename; bool record = !!options->record_filename;
struct server_params params = { struct server_params params = {
.serial = options->serial,
.log_level = options->log_level, .log_level = options->log_level,
.crop = options->crop, .crop = options->crop,
.port_range = options->port_range, .port_range = options->port_range,
@ -279,7 +276,12 @@ scrcpy(const struct scrcpy_options *options) {
.force_adb_forward = options->force_adb_forward, .force_adb_forward = options->force_adb_forward,
.power_off_on_close = options->power_off_on_close, .power_off_on_close = options->power_off_on_close,
}; };
if (!server_start(&server, options->serial, &params)) {
if (!server_init(&server, &params)) {
return false;
}
if (!server_start(&server)) {
goto end; goto end;
} }
@ -311,7 +313,7 @@ scrcpy(const struct scrcpy_options *options) {
fps_counter_initialized = true; fps_counter_initialized = true;
if (options->control) { if (options->control) {
if (!file_handler_init(&file_handler, server.serial, if (!file_handler_init(&file_handler, options->serial,
options->push_target)) { options->push_target)) {
goto end; goto end;
} }

View File

@ -128,9 +128,10 @@ disable_tunnel_forward(const char *serial, uint16_t local_port) {
static bool static bool
disable_tunnel(struct server *server) { disable_tunnel(struct server *server) {
if (server->tunnel_forward) { if (server->tunnel_forward) {
return disable_tunnel_forward(server->serial, server->local_port); return disable_tunnel_forward(server->params.serial,
server->local_port);
} }
return disable_tunnel_reverse(server->serial); return disable_tunnel_reverse(server->params.serial);
} }
static socket_t static socket_t
@ -144,7 +145,7 @@ enable_tunnel_reverse_any_port(struct server *server,
struct sc_port_range port_range) { struct sc_port_range port_range) {
uint16_t port = port_range.first; uint16_t port = port_range.first;
for (;;) { for (;;) {
if (!enable_tunnel_reverse(server->serial, port)) { if (!enable_tunnel_reverse(server->params.serial, port)) {
// the command itself failed, it will fail on any port // the command itself failed, it will fail on any port
return false; return false;
} }
@ -163,7 +164,7 @@ enable_tunnel_reverse_any_port(struct server *server,
} }
// failure, disable tunnel and try another port // failure, disable tunnel and try another port
if (!disable_tunnel_reverse(server->serial)) { if (!disable_tunnel_reverse(server->params.serial)) {
LOGW("Could not remove reverse tunnel on port %" PRIu16, port); LOGW("Could not remove reverse tunnel on port %" PRIu16, port);
} }
@ -191,7 +192,7 @@ enable_tunnel_forward_any_port(struct server *server,
server->tunnel_forward = true; server->tunnel_forward = true;
uint16_t port = port_range.first; uint16_t port = port_range.first;
for (;;) { for (;;) {
if (enable_tunnel_forward(server->serial, port)) { if (enable_tunnel_forward(server->params.serial, port)) {
// success // success
server->local_port = port; server->local_port = port;
return true; return true;
@ -306,7 +307,7 @@ execute_server(struct server *server, const struct server_params *params) {
// Port: 5005 // Port: 5005
// Then click on "Debug" // Then click on "Debug"
#endif #endif
return adb_execute(server->serial, cmd, sizeof(cmd) / sizeof(cmd[0])); return adb_execute(server->params.serial, cmd, ARRAY_LEN(cmd));
} }
static socket_t static socket_t
@ -352,21 +353,75 @@ close_socket(socket_t socket) {
} }
} }
static void
server_params_destroy(struct server_params *params) {
// The server stores a copy of the params provided by the user
free((char *) params->crop);
free((char *) params->codec_options);
free((char *) params->encoder_name);
}
static bool
server_params_copy(struct server_params *dst, const struct server_params *src) {
// params reference user-allocated memory, so we must copy them to handle
// them from a separate thread
*dst = *src;
dst->crop = NULL;
dst->codec_options = NULL;
dst->encoder_name = NULL;
if (src->crop) {
dst->crop = strdup(src->crop);
if (!dst->crop) {
goto error;
}
}
if (src->codec_options) {
dst->codec_options = strdup(src->codec_options);
if (!dst->codec_options) {
goto error;
}
}
if (src->encoder_name) {
dst->encoder_name = strdup(src->encoder_name);
if (!dst->encoder_name) {
goto error;
}
}
return true;
error:
server_params_destroy(dst);
return false;
};
bool bool
server_init(struct server *server) { server_init(struct server *server, const struct server_params *params) {
server->serial = NULL; if (!server_params_copy(&server->params, params)) {
LOGE("Could not copy server params");
return false;
}
server->process = PROCESS_NONE; server->process = PROCESS_NONE;
atomic_flag_clear_explicit(&server->server_socket_closed, atomic_flag_clear_explicit(&server->server_socket_closed,
memory_order_relaxed); memory_order_relaxed);
bool ok = sc_mutex_init(&server->mutex); bool ok = sc_mutex_init(&server->mutex);
if (!ok) { if (!ok) {
server_params_destroy(&server->params);
return false; return false;
} }
ok = sc_cond_init(&server->process_terminated_cond); ok = sc_cond_init(&server->process_terminated_cond);
if (!ok) { if (!ok) {
sc_mutex_destroy(&server->mutex); sc_mutex_destroy(&server->mutex);
server_params_destroy(&server->params);
return false; return false;
} }
@ -406,31 +461,41 @@ run_wait_server(void *data) {
return 0; return 0;
} }
bool static int
server_start(struct server *server, const char *serial, run_server(void *data) {
const struct server_params *params) { struct server *server = data;
if (serial) {
server->serial = strdup(serial);
if (!server->serial) {
return false;
}
}
if (!push_server(serial)) { const struct server_params *params = &server->params;
goto error1; const struct server_callbacks *cbs = &server->cbs;
void *userdata = server->userdata;
if (!push_server(params->serial)) {
cbs->on_connection_failed(server);
goto end;
} }
if (!enable_tunnel_any_port(server, params->port_range, if (!enable_tunnel_any_port(server, params->port_range,
params->force_adb_forward)) { params->force_adb_forward)) {
goto error1; cbs->on_connection_failed(server);
goto end;
} }
// server will connect to our server socket // server will connect to our server socket
server->process = execute_server(server, params); server->process = execute_server(server, params);
if (server->process == PROCESS_NONE) { if (server->process == PROCESS_NONE) {
goto error2; cbs->on_connection_failed(server);
goto end;
} }
process_wait(server->process, false); // ignore exit code
end:
return 0;
}
bool
server_start(struct server *server) {
// If the server process dies before connecting to the server socket, then // If the server process dies before connecting to the server socket, then
// the client will be stuck forever on accept(). To avoid the problem, we // the client will be stuck forever on accept(). To avoid the problem, we
// must be able to wake up the accept() call when the server dies. To keep // must be able to wake up the accept() call when the server dies. To keep
@ -442,14 +507,14 @@ server_start(struct server *server, const char *serial,
if (!ok) { if (!ok) {
process_terminate(server->process); process_terminate(server->process);
process_wait(server->process, true); // ignore exit code process_wait(server->process, true); // ignore exit code
goto error2; goto error;
} }
server->tunnel_enabled = true; server->tunnel_enabled = true;
return true; return true;
error2: error:
if (!server->tunnel_forward) { if (!server->tunnel_forward) {
bool was_closed = bool was_closed =
atomic_flag_test_and_set(&server->server_socket_closed); atomic_flag_test_and_set(&server->server_socket_closed);
@ -459,8 +524,7 @@ error2:
close_socket(server->server_socket); close_socket(server->server_socket);
} }
disable_tunnel(server); disable_tunnel(server);
error1:
free(server->serial);
return false; return false;
} }
@ -558,4 +622,5 @@ server_destroy(struct server *server) {
free(server->serial); free(server->serial);
sc_cond_destroy(&server->process_terminated_cond); sc_cond_destroy(&server->process_terminated_cond);
sc_mutex_destroy(&server->mutex); sc_mutex_destroy(&server->mutex);
server_params_destroy(&server->params);
} }

View File

@ -13,6 +13,25 @@
#include "util/net.h" #include "util/net.h"
#include "util/thread.h" #include "util/thread.h"
struct server_params {
enum sc_log_level log_level;
const char *serial;
const char *crop;
const char *codec_options;
const char *encoder_name;
struct sc_port_range port_range;
uint16_t max_size;
uint32_t bit_rate;
uint16_t max_fps;
int8_t lock_video_orientation;
bool control;
uint32_t display_id;
bool show_touches;
bool stay_awake;
bool force_adb_forward;
bool power_off_on_close;
};
struct server { struct server {
char *serial; char *serial;
process_t process; process_t process;
@ -29,34 +48,29 @@ struct server {
uint16_t local_port; // selected from port_range uint16_t local_port; // selected from port_range
bool tunnel_enabled; bool tunnel_enabled;
bool tunnel_forward; // use "adb forward" instead of "adb reverse" bool tunnel_forward; // use "adb forward" instead of "adb reverse"
// The internal allocated strings are copies owned by the server
struct server_params params;
const struct server_callbacks *cbs;
void *userdata;
}; };
struct server_params { struct server_callbacks {
enum sc_log_level log_level; void (*on_connection_failed)(struct server *server);
const char *crop; void (*on_connected)(struct server *server, const char *name,
const char *codec_options; struct size size, void *userdata);
const char *encoder_name; void (*on_disconnected)(struct server *server, void *userdata);
struct sc_port_range port_range;
uint16_t max_size;
uint32_t bit_rate;
uint16_t max_fps;
int8_t lock_video_orientation;
bool control;
uint32_t display_id;
bool show_touches;
bool stay_awake;
bool force_adb_forward;
bool power_off_on_close;
}; };
// init default values // init server fields
bool bool
server_init(struct server *server); server_init(struct server *server, const struct server_params *params);
// push, enable tunnel et start the server // push, enable tunnel et start the server
bool bool
server_start(struct server *server, const char *serial, server_start(struct server *server, const struct server_callbacks *cbs,
const struct server_params *params); void *userdata);
// block until the communication with the server is established // block until the communication with the server is established
bool bool