diff --git a/app/src/controller.c b/app/src/controller.c index edd767eb..d50e1921 100644 --- a/app/src/controller.c +++ b/app/src/controller.c @@ -7,12 +7,13 @@ #define SC_CONTROL_MSG_QUEUE_MAX 64 static void -sc_controller_receiver_on_error(struct sc_receiver *receiver, void *userdata) { +sc_controller_receiver_on_ended(struct sc_receiver *receiver, bool error, + void *userdata) { (void) receiver; struct sc_controller *controller = userdata; // Forward the event to the controller listener - controller->cbs->on_error(controller, controller->cbs_userdata); + controller->cbs->on_ended(controller, error, controller->cbs_userdata); } bool @@ -27,7 +28,7 @@ sc_controller_init(struct sc_controller *controller, sc_socket control_socket, } static const struct sc_receiver_callbacks receiver_cbs = { - .on_error = sc_controller_receiver_on_error, + .on_ended = sc_controller_receiver_on_ended, }; ok = sc_receiver_init(&controller->receiver, control_socket, &receiver_cbs, @@ -55,7 +56,7 @@ sc_controller_init(struct sc_controller *controller, sc_socket control_socket, controller->control_socket = control_socket; controller->stopped = false; - assert(cbs && cbs->on_error); + assert(cbs && cbs->on_ended); controller->cbs = cbs; controller->cbs_userdata = cbs_userdata; @@ -110,21 +111,30 @@ sc_controller_push_msg(struct sc_controller *controller, static bool process_msg(struct sc_controller *controller, - const struct sc_control_msg *msg) { + const struct sc_control_msg *msg, bool *eos) { static uint8_t serialized_msg[SC_CONTROL_MSG_MAX_SIZE]; size_t length = sc_control_msg_serialize(msg, serialized_msg); if (!length) { + *eos = false; return false; } + ssize_t w = net_send_all(controller->control_socket, serialized_msg, length); - return (size_t) w == length; + if ((size_t) w != length) { + *eos = true; + return false; + } + + return true; } static int run_controller(void *data) { struct sc_controller *controller = data; + bool error = false; + for (;;) { sc_mutex_lock(&controller->mutex); while (!controller->stopped @@ -134,6 +144,7 @@ run_controller(void *data) { if (controller->stopped) { // stop immediately, do not process further msgs sc_mutex_unlock(&controller->mutex); + LOGD("Controller stopped"); break; } @@ -141,20 +152,21 @@ run_controller(void *data) { struct sc_control_msg msg = sc_vecdeque_pop(&controller->queue); sc_mutex_unlock(&controller->mutex); - bool ok = process_msg(controller, &msg); + bool eos; + bool ok = process_msg(controller, &msg, &eos); sc_control_msg_destroy(&msg); if (!ok) { - LOGD("Could not write msg to socket"); - goto error; + if (eos) { + LOGD("Controller stopped (socket closed)"); + } // else error already logged + error = !eos; + break; } } + controller->cbs->on_ended(controller, error, controller->cbs_userdata); + return 0; - -error: - controller->cbs->on_error(controller, controller->cbs_userdata); - - return 1; // ignored } bool diff --git a/app/src/controller.h b/app/src/controller.h index 353d4d0d..57ad79b3 100644 --- a/app/src/controller.h +++ b/app/src/controller.h @@ -28,7 +28,8 @@ struct sc_controller { }; struct sc_controller_callbacks { - void (*on_error)(struct sc_controller *controller, void *userdata); + void (*on_ended)(struct sc_controller *controller, bool error, + void *userdata); }; bool diff --git a/app/src/receiver.c b/app/src/receiver.c index fb923ac4..3e572067 100644 --- a/app/src/receiver.c +++ b/app/src/receiver.c @@ -21,7 +21,7 @@ sc_receiver_init(struct sc_receiver *receiver, sc_socket control_socket, receiver->acksync = NULL; receiver->uhid_devices = NULL; - assert(cbs && cbs->on_error); + assert(cbs && cbs->on_ended); receiver->cbs = cbs; receiver->cbs_userdata = cbs_userdata; @@ -134,12 +134,15 @@ run_receiver(void *data) { static uint8_t buf[DEVICE_MSG_MAX_SIZE]; size_t head = 0; + bool error = false; + for (;;) { assert(head < DEVICE_MSG_MAX_SIZE); ssize_t r = net_recv(receiver->control_socket, buf + head, DEVICE_MSG_MAX_SIZE - head); if (r <= 0) { LOGD("Receiver stopped"); + // device disconnected: keep error=false break; } @@ -147,6 +150,7 @@ run_receiver(void *data) { ssize_t consumed = process_msgs(receiver, buf, head); if (consumed == -1) { // an error occurred + error = true; break; } @@ -157,7 +161,7 @@ run_receiver(void *data) { } } - receiver->cbs->on_error(receiver, receiver->cbs_userdata); + receiver->cbs->on_ended(receiver, error, receiver->cbs_userdata); return 0; } diff --git a/app/src/receiver.h b/app/src/receiver.h index ef83978f..b1ae4fde 100644 --- a/app/src/receiver.h +++ b/app/src/receiver.h @@ -25,7 +25,7 @@ struct sc_receiver { }; struct sc_receiver_callbacks { - void (*on_error)(struct sc_receiver *receiver, void *userdata); + void (*on_ended)(struct sc_receiver *receiver, bool error, void *userdata); }; bool diff --git a/app/src/scrcpy.c b/app/src/scrcpy.c index 84f7c571..376d5839 100644 --- a/app/src/scrcpy.c +++ b/app/src/scrcpy.c @@ -269,13 +269,18 @@ sc_audio_demuxer_on_ended(struct sc_demuxer *demuxer, } static void -sc_controller_on_error(struct sc_controller *controller, void *userdata) { +sc_controller_on_ended(struct sc_controller *controller, bool error, + void *userdata) { // Note: this function may be called twice, once from the controller thread // and once from the receiver thread (void) controller; (void) userdata; - PUSH_EVENT(SC_EVENT_CONTROLLER_ERROR); + if (error) { + PUSH_EVENT(SC_EVENT_CONTROLLER_ERROR); + } else { + PUSH_EVENT(SC_EVENT_DEVICE_DISCONNECTED); + } } static void @@ -567,7 +572,7 @@ scrcpy(struct scrcpy_options *options) { if (options->control) { static const struct sc_controller_callbacks controller_cbs = { - .on_error = sc_controller_on_error, + .on_ended = sc_controller_on_ended, }; if (!sc_controller_init(&s->controller, s->server.control_socket,