From 28980bbc90ab93cf61bdc4b36d2448b8cebbb7df Mon Sep 17 00:00:00 2001 From: Romain Vimont Date: Fri, 31 May 2019 14:55:11 +0200 Subject: [PATCH] Rename "event" to "message" After the recent refactorings, a "control event" is not necessarily an "event" (it may be a "command"). Similarly, the unique "device event" used to send the device clipboard content is more a "reponse" to the request from the client than an "event". Rename both to "message", and rename the message types to better describe their intent. --- app/meson.build | 12 +- app/src/control_event.c | 81 ------- app/src/control_event.h | 64 ----- app/src/control_msg.c | 83 +++++++ app/src/control_msg.h | 64 +++++ app/src/controller.c | 44 ++-- app/src/controller.h | 16 +- app/src/convert.c | 49 ++-- app/src/convert.h | 10 +- app/src/device_event.h | 33 --- app/src/{device_event.c => device_msg.c} | 22 +- app/src/device_msg.h | 32 +++ app/src/input_manager.c | 123 +++++----- app/src/receiver.c | 30 ++- app/tests/test_control_event_serialize.c | 228 ------------------ app/tests/test_control_msg_serialize.c | 228 ++++++++++++++++++ app/tests/test_device_event_deserialize.c | 28 --- app/tests/test_device_msg_deserialize.c | 28 +++ ...{ControlEvent.java => ControlMessage.java} | 44 ++-- ...tReader.java => ControlMessageReader.java} | 78 +++--- .../{EventController.java => Controller.java} | 42 ++-- .../genymobile/scrcpy/DesktopConnection.java | 18 +- .../com/genymobile/scrcpy/DeviceEvent.java | 27 --- .../com/genymobile/scrcpy/DeviceMessage.java | 27 +++ ...ntSender.java => DeviceMessageSender.java} | 8 +- ...ntWriter.java => DeviceMessageWriter.java} | 14 +- .../java/com/genymobile/scrcpy/Server.java | 14 +- ...est.java => ControlMessageReaderTest.java} | 108 ++++----- 28 files changed, 777 insertions(+), 778 deletions(-) delete mode 100644 app/src/control_event.c delete mode 100644 app/src/control_event.h create mode 100644 app/src/control_msg.c create mode 100644 app/src/control_msg.h delete mode 100644 app/src/device_event.h rename app/src/{device_event.c => device_msg.c} (61%) create mode 100644 app/src/device_msg.h delete mode 100644 app/tests/test_control_event_serialize.c create mode 100644 app/tests/test_control_msg_serialize.c delete mode 100644 app/tests/test_device_event_deserialize.c create mode 100644 app/tests/test_device_msg_deserialize.c rename server/src/main/java/com/genymobile/scrcpy/{ControlEvent.java => ControlMessage.java} (61%) rename server/src/main/java/com/genymobile/scrcpy/{ControlEventReader.java => ControlMessageReader.java} (61%) rename server/src/main/java/com/genymobile/scrcpy/{EventController.java => Controller.java} (81%) delete mode 100644 server/src/main/java/com/genymobile/scrcpy/DeviceEvent.java create mode 100644 server/src/main/java/com/genymobile/scrcpy/DeviceMessage.java rename server/src/main/java/com/genymobile/scrcpy/{EventSender.java => DeviceMessageSender.java} (74%) rename server/src/main/java/com/genymobile/scrcpy/{DeviceEventWriter.java => DeviceMessageWriter.java} (72%) rename server/src/test/java/com/genymobile/scrcpy/{ControlEventReaderTest.java => ControlMessageReaderTest.java} (69%) diff --git a/app/meson.build b/app/meson.build index 5e832537..d47eda79 100644 --- a/app/meson.build +++ b/app/meson.build @@ -1,12 +1,12 @@ src = [ 'src/main.c', 'src/command.c', - 'src/control_event.c', + 'src/control_msg.c', 'src/controller.c', 'src/convert.c', 'src/decoder.c', 'src/device.c', - 'src/device_event.c', + 'src/device_msg.c', 'src/file_handler.c', 'src/fps_counter.c', 'src/input_manager.c', @@ -160,13 +160,13 @@ tests = [ 'tests/test_cbuf.c', ]], ['test_control_event_serialize', [ - 'tests/test_control_event_serialize.c', - 'src/control_event.c', + 'tests/test_control_msg_serialize.c', + 'src/control_msg.c', 'src/str_util.c' ]], ['test_device_event_deserialize', [ - 'tests/test_device_event_deserialize.c', - 'src/device_event.c' + 'tests/test_device_msg_deserialize.c', + 'src/device_msg.c' ]], ['test_strutil', [ 'tests/test_strutil.c', diff --git a/app/src/control_event.c b/app/src/control_event.c deleted file mode 100644 index cc4e5b1d..00000000 --- a/app/src/control_event.c +++ /dev/null @@ -1,81 +0,0 @@ -#include "control_event.h" - -#include - -#include "buffer_util.h" -#include "log.h" -#include "str_util.h" - -static void -write_position(uint8_t *buf, const struct position *position) { - buffer_write32be(&buf[0], position->point.x); - buffer_write32be(&buf[4], position->point.y); - buffer_write16be(&buf[8], position->screen_size.width); - buffer_write16be(&buf[10], position->screen_size.height); -} - -// write length (2 bytes) + string (non nul-terminated) -static size_t -write_string(const char *utf8, size_t max_len, unsigned char *buf) { - size_t len = utf8_truncation_index(utf8, max_len); - buffer_write16be(buf, (uint16_t) len); - memcpy(&buf[2], utf8, len); - return 2 + len; -} - -size_t -control_event_serialize(const struct control_event *event, unsigned char *buf) { - buf[0] = event->type; - switch (event->type) { - case CONTROL_EVENT_TYPE_KEYCODE: - buf[1] = event->keycode_event.action; - buffer_write32be(&buf[2], event->keycode_event.keycode); - buffer_write32be(&buf[6], event->keycode_event.metastate); - return 10; - case CONTROL_EVENT_TYPE_TEXT: { - size_t len = write_string(event->text_event.text, - CONTROL_EVENT_TEXT_MAX_LENGTH, &buf[1]); - return 1 + len; - } - case CONTROL_EVENT_TYPE_MOUSE: - buf[1] = event->mouse_event.action; - buffer_write32be(&buf[2], event->mouse_event.buttons); - write_position(&buf[6], &event->mouse_event.position); - return 18; - case CONTROL_EVENT_TYPE_SCROLL: - write_position(&buf[1], &event->scroll_event.position); - buffer_write32be(&buf[13], (uint32_t) event->scroll_event.hscroll); - buffer_write32be(&buf[17], (uint32_t) event->scroll_event.vscroll); - return 21; - case CONTROL_EVENT_TYPE_SET_CLIPBOARD: { - size_t len = write_string(event->text_event.text, - CONTROL_EVENT_CLIPBOARD_TEXT_MAX_LENGTH, - &buf[1]); - return 1 + len; - } - case CONTROL_EVENT_TYPE_BACK_OR_SCREEN_ON: - case CONTROL_EVENT_TYPE_EXPAND_NOTIFICATION_PANEL: - case CONTROL_EVENT_TYPE_COLLAPSE_NOTIFICATION_PANEL: - case CONTROL_EVENT_TYPE_GET_CLIPBOARD: - // no additional data - return 1; - default: - LOGW("Unknown event type: %u", (unsigned) event->type); - return 0; - } -} - -void -control_event_destroy(struct control_event *event) { - switch (event->type) { - case CONTROL_EVENT_TYPE_TEXT: - SDL_free(event->text_event.text); - break; - case CONTROL_EVENT_TYPE_SET_CLIPBOARD: - SDL_free(event->set_clipboard_event.text); - break; - default: - // do nothing - break; - } -} diff --git a/app/src/control_event.h b/app/src/control_event.h deleted file mode 100644 index c381af26..00000000 --- a/app/src/control_event.h +++ /dev/null @@ -1,64 +0,0 @@ -#ifndef CONTROLEVENT_H -#define CONTROLEVENT_H - -#include -#include -#include - -#include "android/input.h" -#include "android/keycodes.h" -#include "common.h" - -#define CONTROL_EVENT_TEXT_MAX_LENGTH 300 -#define CONTROL_EVENT_CLIPBOARD_TEXT_MAX_LENGTH 4093 -#define CONTROL_EVENT_SERIALIZED_MAX_SIZE \ - (3 + CONTROL_EVENT_CLIPBOARD_TEXT_MAX_LENGTH) - -enum control_event_type { - CONTROL_EVENT_TYPE_KEYCODE, - CONTROL_EVENT_TYPE_TEXT, - CONTROL_EVENT_TYPE_MOUSE, - CONTROL_EVENT_TYPE_SCROLL, - CONTROL_EVENT_TYPE_BACK_OR_SCREEN_ON, - CONTROL_EVENT_TYPE_EXPAND_NOTIFICATION_PANEL, - CONTROL_EVENT_TYPE_COLLAPSE_NOTIFICATION_PANEL, - CONTROL_EVENT_TYPE_GET_CLIPBOARD, - CONTROL_EVENT_TYPE_SET_CLIPBOARD, -}; - -struct control_event { - enum control_event_type type; - union { - struct { - enum android_keyevent_action action; - enum android_keycode keycode; - enum android_metastate metastate; - } keycode_event; - struct { - char *text; // owned, to be freed by SDL_free() - } text_event; - struct { - enum android_motionevent_action action; - enum android_motionevent_buttons buttons; - struct position position; - } mouse_event; - struct { - struct position position; - int32_t hscroll; - int32_t vscroll; - } scroll_event; - struct { - char *text; // owned, to be freed by SDL_free() - } set_clipboard_event; - }; -}; - -// buf size must be at least CONTROL_EVENT_SERIALIZED_MAX_SIZE -// return the number of bytes written -size_t -control_event_serialize(const struct control_event *event, unsigned char *buf); - -void -control_event_destroy(struct control_event *event); - -#endif diff --git a/app/src/control_msg.c b/app/src/control_msg.c new file mode 100644 index 00000000..ca1028b3 --- /dev/null +++ b/app/src/control_msg.c @@ -0,0 +1,83 @@ +#include "control_msg.h" + +#include + +#include "buffer_util.h" +#include "log.h" +#include "str_util.h" + +static void +write_position(uint8_t *buf, const struct position *position) { + buffer_write32be(&buf[0], position->point.x); + buffer_write32be(&buf[4], position->point.y); + buffer_write16be(&buf[8], position->screen_size.width); + buffer_write16be(&buf[10], position->screen_size.height); +} + +// write length (2 bytes) + string (non nul-terminated) +static size_t +write_string(const char *utf8, size_t max_len, unsigned char *buf) { + size_t len = utf8_truncation_index(utf8, max_len); + buffer_write16be(buf, (uint16_t) len); + memcpy(&buf[2], utf8, len); + return 2 + len; +} + +size_t +control_msg_serialize(const struct control_msg *msg, unsigned char *buf) { + buf[0] = msg->type; + switch (msg->type) { + case CONTROL_MSG_TYPE_INJECT_KEYCODE: + buf[1] = msg->inject_keycode.action; + buffer_write32be(&buf[2], msg->inject_keycode.keycode); + buffer_write32be(&buf[6], msg->inject_keycode.metastate); + return 10; + case CONTROL_MSG_TYPE_INJECT_TEXT: { + size_t len = write_string(msg->inject_text.text, + CONTROL_MSG_TEXT_MAX_LENGTH, &buf[1]); + return 1 + len; + } + case CONTROL_MSG_TYPE_INJECT_MOUSE_EVENT: + buf[1] = msg->inject_mouse_event.action; + buffer_write32be(&buf[2], msg->inject_mouse_event.buttons); + write_position(&buf[6], &msg->inject_mouse_event.position); + return 18; + case CONTROL_MSG_TYPE_INJECT_SCROLL_EVENT: + write_position(&buf[1], &msg->inject_scroll_event.position); + buffer_write32be(&buf[13], + (uint32_t) msg->inject_scroll_event.hscroll); + buffer_write32be(&buf[17], + (uint32_t) msg->inject_scroll_event.vscroll); + return 21; + case CONTROL_MSG_TYPE_SET_CLIPBOARD: { + size_t len = write_string(msg->inject_text.text, + CONTROL_MSG_CLIPBOARD_TEXT_MAX_LENGTH, + &buf[1]); + return 1 + len; + } + case CONTROL_MSG_TYPE_BACK_OR_SCREEN_ON: + case CONTROL_MSG_TYPE_EXPAND_NOTIFICATION_PANEL: + case CONTROL_MSG_TYPE_COLLAPSE_NOTIFICATION_PANEL: + case CONTROL_MSG_TYPE_GET_CLIPBOARD: + // no additional data + return 1; + default: + LOGW("Unknown message type: %u", (unsigned) msg->type); + return 0; + } +} + +void +control_msg_destroy(struct control_msg *msg) { + switch (msg->type) { + case CONTROL_MSG_TYPE_INJECT_TEXT: + SDL_free(msg->inject_text.text); + break; + case CONTROL_MSG_TYPE_SET_CLIPBOARD: + SDL_free(msg->set_clipboard.text); + break; + default: + // do nothing + break; + } +} diff --git a/app/src/control_msg.h b/app/src/control_msg.h new file mode 100644 index 00000000..abc11f32 --- /dev/null +++ b/app/src/control_msg.h @@ -0,0 +1,64 @@ +#ifndef CONTROLMSG_H +#define CONTROLMSG_H + +#include +#include +#include + +#include "android/input.h" +#include "android/keycodes.h" +#include "common.h" + +#define CONTROL_MSG_TEXT_MAX_LENGTH 300 +#define CONTROL_MSG_CLIPBOARD_TEXT_MAX_LENGTH 4093 +#define CONTROL_MSG_SERIALIZED_MAX_SIZE \ + (3 + CONTROL_MSG_CLIPBOARD_TEXT_MAX_LENGTH) + +enum control_msg_type { + CONTROL_MSG_TYPE_INJECT_KEYCODE, + CONTROL_MSG_TYPE_INJECT_TEXT, + CONTROL_MSG_TYPE_INJECT_MOUSE_EVENT, + CONTROL_MSG_TYPE_INJECT_SCROLL_EVENT, + CONTROL_MSG_TYPE_BACK_OR_SCREEN_ON, + CONTROL_MSG_TYPE_EXPAND_NOTIFICATION_PANEL, + CONTROL_MSG_TYPE_COLLAPSE_NOTIFICATION_PANEL, + CONTROL_MSG_TYPE_GET_CLIPBOARD, + CONTROL_MSG_TYPE_SET_CLIPBOARD, +}; + +struct control_msg { + enum control_msg_type type; + union { + struct { + enum android_keyevent_action action; + enum android_keycode keycode; + enum android_metastate metastate; + } inject_keycode; + struct { + char *text; // owned, to be freed by SDL_free() + } inject_text; + struct { + enum android_motionevent_action action; + enum android_motionevent_buttons buttons; + struct position position; + } inject_mouse_event; + struct { + struct position position; + int32_t hscroll; + int32_t vscroll; + } inject_scroll_event; + struct { + char *text; // owned, to be freed by SDL_free() + } set_clipboard; + }; +}; + +// buf size must be at least CONTROL_MSG_SERIALIZED_MAX_SIZE +// return the number of bytes written +size_t +control_msg_serialize(const struct control_msg *msg, unsigned char *buf); + +void +control_msg_destroy(struct control_msg *msg); + +#endif diff --git a/app/src/controller.c b/app/src/controller.c index 53ea2e26..4b1f4c8b 100644 --- a/app/src/controller.c +++ b/app/src/controller.c @@ -19,7 +19,7 @@ controller_init(struct controller *controller, socket_t control_socket) { return false; } - if (!(controller->event_cond = SDL_CreateCond())) { + if (!(controller->msg_cond = SDL_CreateCond())) { receiver_destroy(&controller->receiver); SDL_DestroyMutex(controller->mutex); return false; @@ -33,39 +33,39 @@ controller_init(struct controller *controller, socket_t control_socket) { void controller_destroy(struct controller *controller) { - SDL_DestroyCond(controller->event_cond); + SDL_DestroyCond(controller->msg_cond); SDL_DestroyMutex(controller->mutex); - struct control_event event; - while (cbuf_take(&controller->queue, &event)) { - control_event_destroy(&event); + struct control_msg msg; + while (cbuf_take(&controller->queue, &msg)) { + control_msg_destroy(&msg); } receiver_destroy(&controller->receiver); } bool -controller_push_event(struct controller *controller, - const struct control_event *event) { +controller_push_msg(struct controller *controller, + const struct control_msg *msg) { mutex_lock(controller->mutex); bool was_empty = cbuf_is_empty(&controller->queue); - bool res = cbuf_push(&controller->queue, *event); + bool res = cbuf_push(&controller->queue, *msg); if (was_empty) { - cond_signal(controller->event_cond); + cond_signal(controller->msg_cond); } mutex_unlock(controller->mutex); return res; } static bool -process_event(struct controller *controller, - const struct control_event *event) { - unsigned char serialized_event[CONTROL_EVENT_SERIALIZED_MAX_SIZE]; - int length = control_event_serialize(event, serialized_event); +process_msg(struct controller *controller, + const struct control_msg *msg) { + unsigned char serialized_msg[CONTROL_MSG_SERIALIZED_MAX_SIZE]; + int length = control_msg_serialize(msg, serialized_msg); if (!length) { return false; } - int w = net_send_all(controller->control_socket, serialized_event, length); + int w = net_send_all(controller->control_socket, serialized_msg, length); return w == length; } @@ -76,22 +76,22 @@ run_controller(void *data) { for (;;) { mutex_lock(controller->mutex); while (!controller->stopped && cbuf_is_empty(&controller->queue)) { - cond_wait(controller->event_cond, controller->mutex); + cond_wait(controller->msg_cond, controller->mutex); } if (controller->stopped) { - // stop immediately, do not process further events + // stop immediately, do not process further msgs mutex_unlock(controller->mutex); break; } - struct control_event event; - bool non_empty = cbuf_take(&controller->queue, &event); + struct control_msg msg; + bool non_empty = cbuf_take(&controller->queue, &msg); SDL_assert(non_empty); mutex_unlock(controller->mutex); - bool ok = process_event(controller, &event); - control_event_destroy(&event); + bool ok = process_msg(controller, &msg); + control_msg_destroy(&msg); if (!ok) { - LOGD("Cannot write event to socket"); + LOGD("Cannot write msg to socket"); break; } } @@ -122,7 +122,7 @@ void controller_stop(struct controller *controller) { mutex_lock(controller->mutex); controller->stopped = true; - cond_signal(controller->event_cond); + cond_signal(controller->msg_cond); mutex_unlock(controller->mutex); } diff --git a/app/src/controller.h b/app/src/controller.h index a54859a7..ae13e39f 100644 --- a/app/src/controller.h +++ b/app/src/controller.h @@ -1,24 +1,24 @@ -#ifndef CONTROL_H -#define CONTROL_H +#ifndef CONTROLLER_H +#define CONTROLLER_H #include #include #include #include "cbuf.h" -#include "control_event.h" +#include "control_msg.h" #include "net.h" #include "receiver.h" -struct control_event_queue CBUF(struct control_event, 64); +struct control_msg_queue CBUF(struct control_msg, 64); struct controller { socket_t control_socket; SDL_Thread *thread; SDL_mutex *mutex; - SDL_cond *event_cond; + SDL_cond *msg_cond; bool stopped; - struct control_event_queue queue; + struct control_msg_queue queue; struct receiver receiver; }; @@ -38,7 +38,7 @@ void controller_join(struct controller *controller); bool -controller_push_event(struct controller *controller, - const struct control_event *event); +controller_push_msg(struct controller *controller, + const struct control_msg *msg); #endif diff --git a/app/src/convert.c b/app/src/convert.c index 504befe0..adf6d400 100644 --- a/app/src/convert.c +++ b/app/src/convert.c @@ -159,19 +159,19 @@ convert_mouse_buttons(uint32_t state) { bool input_key_from_sdl_to_android(const SDL_KeyboardEvent *from, - struct control_event *to) { - to->type = CONTROL_EVENT_TYPE_KEYCODE; + struct control_msg *to) { + to->type = CONTROL_MSG_TYPE_INJECT_KEYCODE; - if (!convert_keycode_action(from->type, &to->keycode_event.action)) { + if (!convert_keycode_action(from->type, &to->inject_keycode.action)) { return false; } uint16_t mod = from->keysym.mod; - if (!convert_keycode(from->keysym.sym, &to->keycode_event.keycode, mod)) { + if (!convert_keycode(from->keysym.sym, &to->inject_keycode.keycode, mod)) { return false; } - to->keycode_event.metastate = convert_meta_state(mod); + to->inject_keycode.metastate = convert_meta_state(mod); return true; } @@ -179,17 +179,18 @@ input_key_from_sdl_to_android(const SDL_KeyboardEvent *from, bool mouse_button_from_sdl_to_android(const SDL_MouseButtonEvent *from, struct size screen_size, - struct control_event *to) { - to->type = CONTROL_EVENT_TYPE_MOUSE; + struct control_msg *to) { + to->type = CONTROL_MSG_TYPE_INJECT_MOUSE_EVENT; - if (!convert_mouse_action(from->type, &to->mouse_event.action)) { + if (!convert_mouse_action(from->type, &to->inject_mouse_event.action)) { return false; } - to->mouse_event.buttons = convert_mouse_buttons(SDL_BUTTON(from->button)); - to->mouse_event.position.screen_size = screen_size; - to->mouse_event.position.point.x = from->x; - to->mouse_event.position.point.y = from->y; + to->inject_mouse_event.buttons = + convert_mouse_buttons(SDL_BUTTON(from->button)); + to->inject_mouse_event.position.screen_size = screen_size; + to->inject_mouse_event.position.point.x = from->x; + to->inject_mouse_event.position.point.y = from->y; return true; } @@ -197,13 +198,13 @@ mouse_button_from_sdl_to_android(const SDL_MouseButtonEvent *from, bool mouse_motion_from_sdl_to_android(const SDL_MouseMotionEvent *from, struct size screen_size, - struct control_event *to) { - to->type = CONTROL_EVENT_TYPE_MOUSE; - to->mouse_event.action = AMOTION_EVENT_ACTION_MOVE; - to->mouse_event.buttons = convert_mouse_buttons(from->state); - to->mouse_event.position.screen_size = screen_size; - to->mouse_event.position.point.x = from->x; - to->mouse_event.position.point.y = from->y; + struct control_msg *to) { + to->type = CONTROL_MSG_TYPE_INJECT_MOUSE_EVENT; + to->inject_mouse_event.action = AMOTION_EVENT_ACTION_MOVE; + to->inject_mouse_event.buttons = convert_mouse_buttons(from->state); + to->inject_mouse_event.position.screen_size = screen_size; + to->inject_mouse_event.position.point.x = from->x; + to->inject_mouse_event.position.point.y = from->y; return true; } @@ -211,17 +212,17 @@ mouse_motion_from_sdl_to_android(const SDL_MouseMotionEvent *from, bool mouse_wheel_from_sdl_to_android(const SDL_MouseWheelEvent *from, struct position position, - struct control_event *to) { - to->type = CONTROL_EVENT_TYPE_SCROLL; + struct control_msg *to) { + to->type = CONTROL_MSG_TYPE_INJECT_SCROLL_EVENT; - to->scroll_event.position = position; + to->inject_scroll_event.position = position; int mul = from->direction == SDL_MOUSEWHEEL_NORMAL ? 1 : -1; // SDL behavior seems inconsistent between horizontal and vertical scrolling // so reverse the horizontal // - to->scroll_event.hscroll = -mul * from->x; - to->scroll_event.vscroll = mul * from->y; + to->inject_scroll_event.hscroll = -mul * from->x; + to->inject_scroll_event.vscroll = mul * from->y; return true; } diff --git a/app/src/convert.h b/app/src/convert.h index 22cf1023..5989e163 100644 --- a/app/src/convert.h +++ b/app/src/convert.h @@ -4,7 +4,7 @@ #include #include -#include "control_event.h" +#include "control_msg.h" struct complete_mouse_motion_event { SDL_MouseMotionEvent *mouse_motion_event; @@ -18,24 +18,24 @@ struct complete_mouse_wheel_event { bool input_key_from_sdl_to_android(const SDL_KeyboardEvent *from, - struct control_event *to); + struct control_msg *to); bool mouse_button_from_sdl_to_android(const SDL_MouseButtonEvent *from, struct size screen_size, - struct control_event *to); + struct control_msg *to); // the video size may be different from the real device size, so we need the // size to which the absolute position apply, to scale it accordingly bool mouse_motion_from_sdl_to_android(const SDL_MouseMotionEvent *from, struct size screen_size, - struct control_event *to); + struct control_msg *to); // on Android, a scroll event requires the current mouse position bool mouse_wheel_from_sdl_to_android(const SDL_MouseWheelEvent *from, struct position position, - struct control_event *to); + struct control_msg *to); #endif diff --git a/app/src/device_event.h b/app/src/device_event.h deleted file mode 100644 index 8e0e8e7f..00000000 --- a/app/src/device_event.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef DEVICEEVENT_H -#define DEVICEEVENT_H - -#include -#include -#include - -#define DEVICE_EVENT_QUEUE_SIZE 64 -#define DEVICE_EVENT_TEXT_MAX_LENGTH 4093 -#define DEVICE_EVENT_SERIALIZED_MAX_SIZE (3 + DEVICE_EVENT_TEXT_MAX_LENGTH) - -enum device_event_type { - DEVICE_EVENT_TYPE_GET_CLIPBOARD, -}; - -struct device_event { - enum device_event_type type; - union { - struct { - char *text; // owned, to be freed by SDL_free() - } clipboard_event; - }; -}; - -// return the number of bytes consumed (0 for no event available, -1 on error) -ssize_t -device_event_deserialize(const unsigned char *buf, size_t len, - struct device_event *event); - -void -device_event_destroy(struct device_event *event); - -#endif diff --git a/app/src/device_event.c b/app/src/device_msg.c similarity index 61% rename from app/src/device_event.c rename to app/src/device_msg.c index 5bc70d99..a90d78dd 100644 --- a/app/src/device_event.c +++ b/app/src/device_msg.c @@ -1,4 +1,4 @@ -#include "device_event.h" +#include "device_msg.h" #include #include @@ -7,16 +7,16 @@ #include "log.h" ssize_t -device_event_deserialize(const unsigned char *buf, size_t len, - struct device_event *event) { +device_msg_deserialize(const unsigned char *buf, size_t len, + struct device_msg *msg) { if (len < 3) { // at least type + empty string length return 0; // not available } - event->type = buf[0]; - switch (event->type) { - case DEVICE_EVENT_TYPE_GET_CLIPBOARD: { + msg->type = buf[0]; + switch (msg->type) { + case DEVICE_MSG_TYPE_CLIPBOARD: { uint16_t clipboard_len = buffer_read16be(&buf[1]); if (clipboard_len > len - 3) { return 0; // not available @@ -31,18 +31,18 @@ device_event_deserialize(const unsigned char *buf, size_t len, } text[clipboard_len] = '\0'; - event->clipboard_event.text = text; + msg->clipboard.text = text; return 3 + clipboard_len; } default: - LOGW("Unsupported device event type: %d", (int) event->type); + LOGW("Unknown device message type: %d", (int) msg->type); return -1; // error, we cannot recover } } void -device_event_destroy(struct device_event *event) { - if (event->type == DEVICE_EVENT_TYPE_GET_CLIPBOARD) { - SDL_free(event->clipboard_event.text); +device_msg_destroy(struct device_msg *msg) { + if (msg->type == DEVICE_MSG_TYPE_CLIPBOARD) { + SDL_free(msg->clipboard.text); } } diff --git a/app/src/device_msg.h b/app/src/device_msg.h new file mode 100644 index 00000000..fd4a7eb1 --- /dev/null +++ b/app/src/device_msg.h @@ -0,0 +1,32 @@ +#ifndef DEVICEMSG_H +#define DEVICEMSG_H + +#include +#include +#include + +#define DEVICE_MSG_TEXT_MAX_LENGTH 4093 +#define DEVICE_MSG_SERIALIZED_MAX_SIZE (3 + DEVICE_MSG_TEXT_MAX_LENGTH) + +enum device_msg_type { + DEVICE_MSG_TYPE_CLIPBOARD, +}; + +struct device_msg { + enum device_msg_type type; + union { + struct { + char *text; // owned, to be freed by SDL_free() + } clipboard; + }; +}; + +// return the number of bytes consumed (0 for no msg available, -1 on error) +ssize_t +device_msg_deserialize(const unsigned char *buf, size_t len, + struct device_msg *msg); + +void +device_msg_destroy(struct device_msg *msg); + +#endif diff --git a/app/src/input_manager.c b/app/src/input_manager.c index 23073cbc..a040913b 100644 --- a/app/src/input_manager.c +++ b/app/src/input_manager.c @@ -39,23 +39,23 @@ static void send_keycode(struct controller *controller, enum android_keycode keycode, int actions, const char *name) { // send DOWN event - struct control_event control_event; - control_event.type = CONTROL_EVENT_TYPE_KEYCODE; - control_event.keycode_event.keycode = keycode; - control_event.keycode_event.metastate = 0; + struct control_msg msg; + msg.type = CONTROL_MSG_TYPE_INJECT_KEYCODE; + msg.inject_keycode.keycode = keycode; + msg.inject_keycode.metastate = 0; if (actions & ACTION_DOWN) { - control_event.keycode_event.action = AKEY_EVENT_ACTION_DOWN; - if (!controller_push_event(controller, &control_event)) { - LOGW("Cannot send %s (DOWN)", name); + msg.inject_keycode.action = AKEY_EVENT_ACTION_DOWN; + if (!controller_push_msg(controller, &msg)) { + LOGW("Cannot request 'inject %s (DOWN)'", name); return; } } if (actions & ACTION_UP) { - control_event.keycode_event.action = AKEY_EVENT_ACTION_UP; - if (!controller_push_event(controller, &control_event)) { - LOGW("Cannot send %s (UP)", name); + msg.inject_keycode.action = AKEY_EVENT_ACTION_UP; + if (!controller_push_msg(controller, &msg)) { + LOGW("Cannot request 'inject %s (UP)'", name); } } } @@ -98,41 +98,41 @@ action_menu(struct controller *controller, int actions) { // turn the screen on if it was off, press BACK otherwise static void press_back_or_turn_screen_on(struct controller *controller) { - struct control_event control_event; - control_event.type = CONTROL_EVENT_TYPE_BACK_OR_SCREEN_ON; + struct control_msg msg; + msg.type = CONTROL_MSG_TYPE_BACK_OR_SCREEN_ON; - if (!controller_push_event(controller, &control_event)) { - LOGW("Cannot turn screen on"); + if (!controller_push_msg(controller, &msg)) { + LOGW("Cannot request 'turn screen on'"); } } static void expand_notification_panel(struct controller *controller) { - struct control_event control_event; - control_event.type = CONTROL_EVENT_TYPE_EXPAND_NOTIFICATION_PANEL; + struct control_msg msg; + msg.type = CONTROL_MSG_TYPE_EXPAND_NOTIFICATION_PANEL; - if (!controller_push_event(controller, &control_event)) { - LOGW("Cannot expand notification panel"); + if (!controller_push_msg(controller, &msg)) { + LOGW("Cannot request 'expand notification panel'"); } } static void collapse_notification_panel(struct controller *controller) { - struct control_event control_event; - control_event.type = CONTROL_EVENT_TYPE_COLLAPSE_NOTIFICATION_PANEL; + struct control_msg msg; + msg.type = CONTROL_MSG_TYPE_COLLAPSE_NOTIFICATION_PANEL; - if (!controller_push_event(controller, &control_event)) { - LOGW("Cannot collapse notification panel"); + if (!controller_push_msg(controller, &msg)) { + LOGW("Cannot request 'collapse notification panel'"); } } static void request_device_clipboard(struct controller *controller) { - struct control_event control_event; - control_event.type = CONTROL_EVENT_TYPE_GET_CLIPBOARD; + struct control_msg msg; + msg.type = CONTROL_MSG_TYPE_GET_CLIPBOARD; - if (!controller_push_event(controller, &control_event)) { - LOGW("Cannot get device clipboard"); + if (!controller_push_msg(controller, &msg)) { + LOGW("Cannot request device clipboard"); } } @@ -149,13 +149,13 @@ set_device_clipboard(struct controller *controller) { return; } - struct control_event control_event; - control_event.type = CONTROL_EVENT_TYPE_SET_CLIPBOARD; - control_event.set_clipboard_event.text = text; + struct control_msg msg; + msg.type = CONTROL_MSG_TYPE_SET_CLIPBOARD; + msg.set_clipboard.text = text; - if (!controller_push_event(controller, &control_event)) { + if (!controller_push_msg(controller, &msg)) { SDL_free(text); - LOGW("Cannot send clipboard paste event"); + LOGW("Cannot request 'set device clipboard'"); } } @@ -185,12 +185,12 @@ clipboard_paste(struct controller *controller) { return; } - struct control_event control_event; - control_event.type = CONTROL_EVENT_TYPE_TEXT; - control_event.text_event.text = text; - if (!controller_push_event(controller, &control_event)) { + struct control_msg msg; + msg.type = CONTROL_MSG_TYPE_INJECT_TEXT; + msg.inject_text.text = text; + if (!controller_push_msg(controller, &msg)) { SDL_free(text); - LOGW("Cannot send clipboard paste event"); + LOGW("Cannot request 'paste clipboard'"); } } @@ -203,16 +203,16 @@ input_manager_process_text_input(struct input_manager *input_manager, // letters and space are handled as raw key event return; } - struct control_event control_event; - control_event.type = CONTROL_EVENT_TYPE_TEXT; - control_event.text_event.text = SDL_strdup(event->text); - if (!control_event.text_event.text) { + struct control_msg msg; + msg.type = CONTROL_MSG_TYPE_INJECT_TEXT; + msg.inject_text.text = SDL_strdup(event->text); + if (!msg.inject_text.text) { LOGW("Cannot strdup input text"); return; } - if (!controller_push_event(input_manager->controller, &control_event)) { - SDL_free(control_event.text_event.text); - LOGW("Cannot send text event"); + if (!controller_push_msg(input_manager->controller, &msg)) { + SDL_free(msg.inject_text.text); + LOGW("Cannot request 'inject text'"); } } @@ -344,10 +344,10 @@ input_manager_process_key(struct input_manager *input_manager, return; } - struct control_event control_event; - if (input_key_from_sdl_to_android(event, &control_event)) { - if (!controller_push_event(input_manager->controller, &control_event)) { - LOGW("Cannot send control event"); + struct control_msg msg; + if (input_key_from_sdl_to_android(event, &msg)) { + if (!controller_push_msg(input_manager->controller, &msg)) { + LOGW("Cannot request 'inject keycode'"); } } } @@ -359,12 +359,12 @@ input_manager_process_mouse_motion(struct input_manager *input_manager, // do not send motion events when no button is pressed return; } - struct control_event control_event; + struct control_msg msg; if (mouse_motion_from_sdl_to_android(event, input_manager->screen->frame_size, - &control_event)) { - if (!controller_push_event(input_manager->controller, &control_event)) { - LOGW("Cannot send mouse motion event"); + &msg)) { + if (!controller_push_msg(input_manager->controller, &msg)) { + LOGW("Cannot request 'inject mouse motion event'"); } } } @@ -391,9 +391,8 @@ input_manager_process_mouse_button(struct input_manager *input_manager, } // double-click on black borders resize to fit the device screen if (event->button == SDL_BUTTON_LEFT && event->clicks == 2) { - bool outside = is_outside_device_screen(input_manager, - event->x, - event->y); + bool outside = + is_outside_device_screen(input_manager, event->x, event->y); if (outside) { screen_resize_to_fit(input_manager->screen); return; @@ -406,12 +405,12 @@ input_manager_process_mouse_button(struct input_manager *input_manager, return; } - struct control_event control_event; + struct control_msg msg; if (mouse_button_from_sdl_to_android(event, input_manager->screen->frame_size, - &control_event)) { - if (!controller_push_event(input_manager->controller, &control_event)) { - LOGW("Cannot send mouse button event"); + &msg)) { + if (!controller_push_msg(input_manager->controller, &msg)) { + LOGW("Cannot request 'inject mouse button event'"); } } } @@ -423,10 +422,10 @@ input_manager_process_mouse_wheel(struct input_manager *input_manager, .screen_size = input_manager->screen->frame_size, .point = get_mouse_point(input_manager->screen), }; - struct control_event control_event; - if (mouse_wheel_from_sdl_to_android(event, position, &control_event)) { - if (!controller_push_event(input_manager->controller, &control_event)) { - LOGW("Cannot send mouse wheel event"); + struct control_msg msg; + if (mouse_wheel_from_sdl_to_android(event, position, &msg)) { + if (!controller_push_msg(input_manager->controller, &msg)) { + LOGW("Cannot request 'inject mouse wheel event'"); } } } diff --git a/app/src/receiver.c b/app/src/receiver.c index 683b61fa..0f989489 100644 --- a/app/src/receiver.c +++ b/app/src/receiver.c @@ -4,8 +4,7 @@ #include #include "config.h" -#include "device_event.h" -#include "events.h" +#include "device_msg.h" #include "lock_util.h" #include "log.h" @@ -24,21 +23,20 @@ receiver_destroy(struct receiver *receiver) { } static void -process_event(struct receiver *receiver, struct device_event *event) { - switch (event->type) { - case DEVICE_EVENT_TYPE_GET_CLIPBOARD: - SDL_SetClipboardText(event->clipboard_event.text); +process_msg(struct receiver *receiver, struct device_msg *msg) { + switch (msg->type) { + case DEVICE_MSG_TYPE_CLIPBOARD: + SDL_SetClipboardText(msg->clipboard.text); break; } } static ssize_t -process_events(struct receiver *receiver, const unsigned char *buf, - size_t len) { +process_msgs(struct receiver *receiver, const unsigned char *buf, size_t len) { size_t head = 0; for (;;) { - struct device_event event; - ssize_t r = device_event_deserialize(&buf[head], len - head, &event); + struct device_msg msg; + ssize_t r = device_msg_deserialize(&buf[head], len - head, &msg); if (r == -1) { return -1; } @@ -46,8 +44,8 @@ process_events(struct receiver *receiver, const unsigned char *buf, return head; } - process_event(receiver, &event); - device_event_destroy(&event); + process_msg(receiver, &msg); + device_msg_destroy(&msg); head += r; SDL_assert(head <= len); @@ -61,19 +59,19 @@ static int run_receiver(void *data) { struct receiver *receiver = data; - unsigned char buf[DEVICE_EVENT_SERIALIZED_MAX_SIZE]; + unsigned char buf[DEVICE_MSG_SERIALIZED_MAX_SIZE]; size_t head = 0; for (;;) { - SDL_assert(head < DEVICE_EVENT_SERIALIZED_MAX_SIZE); + SDL_assert(head < DEVICE_MSG_SERIALIZED_MAX_SIZE); ssize_t r = net_recv(receiver->control_socket, buf, - DEVICE_EVENT_SERIALIZED_MAX_SIZE - head); + DEVICE_MSG_SERIALIZED_MAX_SIZE - head); if (r <= 0) { LOGD("Receiver stopped"); break; } - ssize_t consumed = process_events(receiver, buf, r); + ssize_t consumed = process_msgs(receiver, buf, r); if (consumed == -1) { // an error occurred break; diff --git a/app/tests/test_control_event_serialize.c b/app/tests/test_control_event_serialize.c deleted file mode 100644 index d9cd0b76..00000000 --- a/app/tests/test_control_event_serialize.c +++ /dev/null @@ -1,228 +0,0 @@ -#include -#include - -#include "control_event.h" - -static void test_serialize_keycode_event(void) { - struct control_event event = { - .type = CONTROL_EVENT_TYPE_KEYCODE, - .keycode_event = { - .action = AKEY_EVENT_ACTION_UP, - .keycode = AKEYCODE_ENTER, - .metastate = AMETA_SHIFT_ON | AMETA_SHIFT_LEFT_ON, - }, - }; - - unsigned char buf[CONTROL_EVENT_SERIALIZED_MAX_SIZE]; - int size = control_event_serialize(&event, buf); - assert(size == 10); - - const unsigned char expected[] = { - 0x00, // CONTROL_EVENT_TYPE_KEYCODE - 0x01, // AKEY_EVENT_ACTION_UP - 0x00, 0x00, 0x00, 0x42, // AKEYCODE_ENTER - 0x00, 0x00, 0x00, 0x41, // AMETA_SHIFT_ON | AMETA_SHIFT_LEFT_ON - }; - assert(!memcmp(buf, expected, sizeof(expected))); -} - -static void test_serialize_text_event(void) { - struct control_event event = { - .type = CONTROL_EVENT_TYPE_TEXT, - .text_event = { - .text = "hello, world!", - }, - }; - - unsigned char buf[CONTROL_EVENT_SERIALIZED_MAX_SIZE]; - int size = control_event_serialize(&event, buf); - assert(size == 16); - - const unsigned char expected[] = { - 0x01, // CONTROL_EVENT_TYPE_TEXT - 0x00, 0x0d, // text length - 'h', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd', '!', // text - }; - assert(!memcmp(buf, expected, sizeof(expected))); -} - -static void test_serialize_long_text_event(void) { - struct control_event event; - event.type = CONTROL_EVENT_TYPE_TEXT; - char text[CONTROL_EVENT_TEXT_MAX_LENGTH + 1]; - memset(text, 'a', sizeof(text)); - text[CONTROL_EVENT_TEXT_MAX_LENGTH] = '\0'; - event.text_event.text = text; - - unsigned char buf[CONTROL_EVENT_SERIALIZED_MAX_SIZE]; - int size = control_event_serialize(&event, buf); - assert(size == 3 + CONTROL_EVENT_TEXT_MAX_LENGTH); - - unsigned char expected[3 + CONTROL_EVENT_TEXT_MAX_LENGTH]; - expected[0] = 0x01; // CONTROL_EVENT_TYPE_KEYCODE - expected[1] = 0x01; - expected[2] = 0x2c; // text length (16 bits) - memset(&expected[3], 'a', CONTROL_EVENT_TEXT_MAX_LENGTH); - - assert(!memcmp(buf, expected, sizeof(expected))); -} - -static void test_serialize_mouse_event(void) { - struct control_event event = { - .type = CONTROL_EVENT_TYPE_MOUSE, - .mouse_event = { - .action = AMOTION_EVENT_ACTION_DOWN, - .buttons = AMOTION_EVENT_BUTTON_PRIMARY, - .position = { - .point = { - .x = 260, - .y = 1026, - }, - .screen_size = { - .width = 1080, - .height = 1920, - }, - }, - }, - }; - - unsigned char buf[CONTROL_EVENT_SERIALIZED_MAX_SIZE]; - int size = control_event_serialize(&event, buf); - assert(size == 18); - - const unsigned char expected[] = { - 0x02, // CONTROL_EVENT_TYPE_MOUSE - 0x00, // AKEY_EVENT_ACTION_DOWN - 0x00, 0x00, 0x00, 0x01, // AMOTION_EVENT_BUTTON_PRIMARY - 0x00, 0x00, 0x01, 0x04, 0x00, 0x00, 0x04, 0x02, // 260 1026 - 0x04, 0x38, 0x07, 0x80, // 1080 1920 - }; - assert(!memcmp(buf, expected, sizeof(expected))); -} - -static void test_serialize_scroll_event(void) { - struct control_event event = { - .type = CONTROL_EVENT_TYPE_SCROLL, - .scroll_event = { - .position = { - .point = { - .x = 260, - .y = 1026, - }, - .screen_size = { - .width = 1080, - .height = 1920, - }, - }, - .hscroll = 1, - .vscroll = -1, - }, - }; - - unsigned char buf[CONTROL_EVENT_SERIALIZED_MAX_SIZE]; - int size = control_event_serialize(&event, buf); - assert(size == 21); - - const unsigned char expected[] = { - 0x03, // CONTROL_EVENT_TYPE_SCROLL - 0x00, 0x00, 0x01, 0x04, 0x00, 0x00, 0x04, 0x02, // 260 1026 - 0x04, 0x38, 0x07, 0x80, // 1080 1920 - 0x00, 0x00, 0x00, 0x01, // 1 - 0xFF, 0xFF, 0xFF, 0xFF, // -1 - }; - assert(!memcmp(buf, expected, sizeof(expected))); -} - -static void test_serialize_back_or_screen_on_event(void) { - struct control_event event = { - .type = CONTROL_EVENT_TYPE_BACK_OR_SCREEN_ON, - }; - - unsigned char buf[CONTROL_EVENT_SERIALIZED_MAX_SIZE]; - int size = control_event_serialize(&event, buf); - assert(size == 1); - - const unsigned char expected[] = { - 0x04, // CONTROL_EVENT_TYPE_BACK_OR_SCREEN_ON - }; - assert(!memcmp(buf, expected, sizeof(expected))); -} - -static void test_serialize_expand_notification_panel_event(void) { - struct control_event event = { - .type = CONTROL_EVENT_TYPE_EXPAND_NOTIFICATION_PANEL, - }; - - unsigned char buf[CONTROL_EVENT_SERIALIZED_MAX_SIZE]; - int size = control_event_serialize(&event, buf); - assert(size == 1); - - const unsigned char expected[] = { - 0x05, // CONTROL_EVENT_TYPE_EXPAND_NOTIFICATION_PANEL - }; - assert(!memcmp(buf, expected, sizeof(expected))); -} - -static void test_serialize_collapse_notification_panel_event(void) { - struct control_event event = { - .type = CONTROL_EVENT_TYPE_COLLAPSE_NOTIFICATION_PANEL, - }; - - unsigned char buf[CONTROL_EVENT_SERIALIZED_MAX_SIZE]; - int size = control_event_serialize(&event, buf); - assert(size == 1); - - const unsigned char expected[] = { - 0x06, // CONTROL_EVENT_TYPE_COLLAPSE_NOTIFICATION_PANEL - }; - assert(!memcmp(buf, expected, sizeof(expected))); -} - -static void test_serialize_get_clipboard_event(void) { - struct control_event event = { - .type = CONTROL_EVENT_TYPE_GET_CLIPBOARD, - }; - - unsigned char buf[CONTROL_EVENT_SERIALIZED_MAX_SIZE]; - int size = control_event_serialize(&event, buf); - assert(size == 1); - - const unsigned char expected[] = { - 0x07, // CONTROL_EVENT_TYPE_GET_CLIPBOARD - }; - assert(!memcmp(buf, expected, sizeof(expected))); -} - -static void test_serialize_set_clipboard_event(void) { - struct control_event event = { - .type = CONTROL_EVENT_TYPE_SET_CLIPBOARD, - .text_event = { - .text = "hello, world!", - }, - }; - - unsigned char buf[CONTROL_EVENT_SERIALIZED_MAX_SIZE]; - int size = control_event_serialize(&event, buf); - assert(size == 16); - - const unsigned char expected[] = { - 0x08, // CONTROL_EVENT_TYPE_SET_CLIPBOARD - 0x00, 0x0d, // text length - 'h', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd', '!', // text - }; - assert(!memcmp(buf, expected, sizeof(expected))); -} - -int main(void) { - test_serialize_keycode_event(); - test_serialize_text_event(); - test_serialize_long_text_event(); - test_serialize_mouse_event(); - test_serialize_scroll_event(); - test_serialize_back_or_screen_on_event(); - test_serialize_expand_notification_panel_event(); - test_serialize_collapse_notification_panel_event(); - test_serialize_get_clipboard_event(); - test_serialize_set_clipboard_event(); - return 0; -} diff --git a/app/tests/test_control_msg_serialize.c b/app/tests/test_control_msg_serialize.c new file mode 100644 index 00000000..20f72505 --- /dev/null +++ b/app/tests/test_control_msg_serialize.c @@ -0,0 +1,228 @@ +#include +#include + +#include "control_msg.h" + +static void test_serialize_inject_keycode(void) { + struct control_msg msg = { + .type = CONTROL_MSG_TYPE_INJECT_KEYCODE, + .inject_keycode = { + .action = AKEY_EVENT_ACTION_UP, + .keycode = AKEYCODE_ENTER, + .metastate = AMETA_SHIFT_ON | AMETA_SHIFT_LEFT_ON, + }, + }; + + unsigned char buf[CONTROL_MSG_SERIALIZED_MAX_SIZE]; + int size = control_msg_serialize(&msg, buf); + assert(size == 10); + + const unsigned char expected[] = { + CONTROL_MSG_TYPE_INJECT_KEYCODE, + 0x01, // AKEY_EVENT_ACTION_UP + 0x00, 0x00, 0x00, 0x42, // AKEYCODE_ENTER + 0x00, 0x00, 0x00, 0x41, // AMETA_SHIFT_ON | AMETA_SHIFT_LEFT_ON + }; + assert(!memcmp(buf, expected, sizeof(expected))); +} + +static void test_serialize_inject_text(void) { + struct control_msg msg = { + .type = CONTROL_MSG_TYPE_INJECT_TEXT, + .inject_text = { + .text = "hello, world!", + }, + }; + + unsigned char buf[CONTROL_MSG_SERIALIZED_MAX_SIZE]; + int size = control_msg_serialize(&msg, buf); + assert(size == 16); + + const unsigned char expected[] = { + CONTROL_MSG_TYPE_INJECT_TEXT, + 0x00, 0x0d, // text length + 'h', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd', '!', // text + }; + assert(!memcmp(buf, expected, sizeof(expected))); +} + +static void test_serialize_inject_text_long(void) { + struct control_msg msg; + msg.type = CONTROL_MSG_TYPE_INJECT_TEXT; + char text[CONTROL_MSG_TEXT_MAX_LENGTH + 1]; + memset(text, 'a', sizeof(text)); + text[CONTROL_MSG_TEXT_MAX_LENGTH] = '\0'; + msg.inject_text.text = text; + + unsigned char buf[CONTROL_MSG_SERIALIZED_MAX_SIZE]; + int size = control_msg_serialize(&msg, buf); + assert(size == 3 + CONTROL_MSG_TEXT_MAX_LENGTH); + + unsigned char expected[3 + CONTROL_MSG_TEXT_MAX_LENGTH]; + expected[0] = CONTROL_MSG_TYPE_INJECT_TEXT; + expected[1] = 0x01; + expected[2] = 0x2c; // text length (16 bits) + memset(&expected[3], 'a', CONTROL_MSG_TEXT_MAX_LENGTH); + + assert(!memcmp(buf, expected, sizeof(expected))); +} + +static void test_serialize_inject_mouse_event(void) { + struct control_msg msg = { + .type = CONTROL_MSG_TYPE_INJECT_MOUSE_EVENT, + .inject_mouse_event = { + .action = AMOTION_EVENT_ACTION_DOWN, + .buttons = AMOTION_EVENT_BUTTON_PRIMARY, + .position = { + .point = { + .x = 260, + .y = 1026, + }, + .screen_size = { + .width = 1080, + .height = 1920, + }, + }, + }, + }; + + unsigned char buf[CONTROL_MSG_SERIALIZED_MAX_SIZE]; + int size = control_msg_serialize(&msg, buf); + assert(size == 18); + + const unsigned char expected[] = { + CONTROL_MSG_TYPE_INJECT_MOUSE_EVENT, + 0x00, // AKEY_EVENT_ACTION_DOWN + 0x00, 0x00, 0x00, 0x01, // AMOTION_EVENT_BUTTON_PRIMARY + 0x00, 0x00, 0x01, 0x04, 0x00, 0x00, 0x04, 0x02, // 260 1026 + 0x04, 0x38, 0x07, 0x80, // 1080 1920 + }; + assert(!memcmp(buf, expected, sizeof(expected))); +} + +static void test_serialize_inject_scroll_event(void) { + struct control_msg msg = { + .type = CONTROL_MSG_TYPE_INJECT_SCROLL_EVENT, + .inject_scroll_event = { + .position = { + .point = { + .x = 260, + .y = 1026, + }, + .screen_size = { + .width = 1080, + .height = 1920, + }, + }, + .hscroll = 1, + .vscroll = -1, + }, + }; + + unsigned char buf[CONTROL_MSG_SERIALIZED_MAX_SIZE]; + int size = control_msg_serialize(&msg, buf); + assert(size == 21); + + const unsigned char expected[] = { + CONTROL_MSG_TYPE_INJECT_SCROLL_EVENT, + 0x00, 0x00, 0x01, 0x04, 0x00, 0x00, 0x04, 0x02, // 260 1026 + 0x04, 0x38, 0x07, 0x80, // 1080 1920 + 0x00, 0x00, 0x00, 0x01, // 1 + 0xFF, 0xFF, 0xFF, 0xFF, // -1 + }; + assert(!memcmp(buf, expected, sizeof(expected))); +} + +static void test_serialize_back_or_screen_on(void) { + struct control_msg msg = { + .type = CONTROL_MSG_TYPE_BACK_OR_SCREEN_ON, + }; + + unsigned char buf[CONTROL_MSG_SERIALIZED_MAX_SIZE]; + int size = control_msg_serialize(&msg, buf); + assert(size == 1); + + const unsigned char expected[] = { + CONTROL_MSG_TYPE_BACK_OR_SCREEN_ON, + }; + assert(!memcmp(buf, expected, sizeof(expected))); +} + +static void test_serialize_expand_notification_panel(void) { + struct control_msg msg = { + .type = CONTROL_MSG_TYPE_EXPAND_NOTIFICATION_PANEL, + }; + + unsigned char buf[CONTROL_MSG_SERIALIZED_MAX_SIZE]; + int size = control_msg_serialize(&msg, buf); + assert(size == 1); + + const unsigned char expected[] = { + CONTROL_MSG_TYPE_EXPAND_NOTIFICATION_PANEL, + }; + assert(!memcmp(buf, expected, sizeof(expected))); +} + +static void test_serialize_collapse_notification_panel(void) { + struct control_msg msg = { + .type = CONTROL_MSG_TYPE_COLLAPSE_NOTIFICATION_PANEL, + }; + + unsigned char buf[CONTROL_MSG_SERIALIZED_MAX_SIZE]; + int size = control_msg_serialize(&msg, buf); + assert(size == 1); + + const unsigned char expected[] = { + CONTROL_MSG_TYPE_COLLAPSE_NOTIFICATION_PANEL, + }; + assert(!memcmp(buf, expected, sizeof(expected))); +} + +static void test_serialize_get_clipboard(void) { + struct control_msg msg = { + .type = CONTROL_MSG_TYPE_GET_CLIPBOARD, + }; + + unsigned char buf[CONTROL_MSG_SERIALIZED_MAX_SIZE]; + int size = control_msg_serialize(&msg, buf); + assert(size == 1); + + const unsigned char expected[] = { + CONTROL_MSG_TYPE_GET_CLIPBOARD, + }; + assert(!memcmp(buf, expected, sizeof(expected))); +} + +static void test_serialize_set_clipboard(void) { + struct control_msg msg = { + .type = CONTROL_MSG_TYPE_SET_CLIPBOARD, + .inject_text = { + .text = "hello, world!", + }, + }; + + unsigned char buf[CONTROL_MSG_SERIALIZED_MAX_SIZE]; + int size = control_msg_serialize(&msg, buf); + assert(size == 16); + + const unsigned char expected[] = { + CONTROL_MSG_TYPE_SET_CLIPBOARD, + 0x00, 0x0d, // text length + 'h', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd', '!', // text + }; + assert(!memcmp(buf, expected, sizeof(expected))); +} + +int main(void) { + test_serialize_inject_keycode(); + test_serialize_inject_text(); + test_serialize_inject_text_long(); + test_serialize_inject_mouse_event(); + test_serialize_inject_scroll_event(); + test_serialize_back_or_screen_on(); + test_serialize_expand_notification_panel(); + test_serialize_collapse_notification_panel(); + test_serialize_get_clipboard(); + test_serialize_set_clipboard(); + return 0; +} diff --git a/app/tests/test_device_event_deserialize.c b/app/tests/test_device_event_deserialize.c deleted file mode 100644 index 83e5e02e..00000000 --- a/app/tests/test_device_event_deserialize.c +++ /dev/null @@ -1,28 +0,0 @@ -#include -#include - -#include "device_event.h" - -#include -static void test_deserialize_clipboard_event(void) { - const unsigned char input[] = { - 0x00, // DEVICE_EVENT_TYPE_CLIPBOARD - 0x00, 0x03, // text length - 0x41, 0x42, 0x43, // "ABC" - }; - - struct device_event event; - ssize_t r = device_event_deserialize(input, sizeof(input), &event); - assert(r == 6); - - assert(event.type == DEVICE_EVENT_TYPE_GET_CLIPBOARD); - assert(event.clipboard_event.text); - assert(!strcmp("ABC", event.clipboard_event.text)); - - device_event_destroy(&event); -} - -int main(void) { - test_deserialize_clipboard_event(); - return 0; -} diff --git a/app/tests/test_device_msg_deserialize.c b/app/tests/test_device_msg_deserialize.c new file mode 100644 index 00000000..e163ad72 --- /dev/null +++ b/app/tests/test_device_msg_deserialize.c @@ -0,0 +1,28 @@ +#include +#include + +#include "device_msg.h" + +#include +static void test_deserialize_clipboard(void) { + const unsigned char input[] = { + DEVICE_MSG_TYPE_CLIPBOARD, + 0x00, 0x03, // text length + 0x41, 0x42, 0x43, // "ABC" + }; + + struct device_msg msg; + ssize_t r = device_msg_deserialize(input, sizeof(input), &msg); + assert(r == 6); + + assert(msg.type == DEVICE_MSG_TYPE_CLIPBOARD); + assert(msg.clipboard.text); + assert(!strcmp("ABC", msg.clipboard.text)); + + device_msg_destroy(&msg); +} + +int main(void) { + test_deserialize_clipboard(); + return 0; +} diff --git a/server/src/main/java/com/genymobile/scrcpy/ControlEvent.java b/server/src/main/java/com/genymobile/scrcpy/ControlMessage.java similarity index 61% rename from server/src/main/java/com/genymobile/scrcpy/ControlEvent.java rename to server/src/main/java/com/genymobile/scrcpy/ControlMessage.java index 51360560..093e293f 100644 --- a/server/src/main/java/com/genymobile/scrcpy/ControlEvent.java +++ b/server/src/main/java/com/genymobile/scrcpy/ControlMessage.java @@ -3,12 +3,12 @@ package com.genymobile.scrcpy; /** * Union of all supported event types, identified by their {@code type}. */ -public final class ControlEvent { +public final class ControlMessage { - public static final int TYPE_KEYCODE = 0; - public static final int TYPE_TEXT = 1; - public static final int TYPE_MOUSE = 2; - public static final int TYPE_SCROLL = 3; + public static final int TYPE_INJECT_KEYCODE = 0; + public static final int TYPE_INJECT_TEXT = 1; + public static final int TYPE_INJECT_MOUSE_EVENT = 2; + public static final int TYPE_INJECT_SCROLL_EVENT = 3; public static final int TYPE_BACK_OR_SCREEN_ON = 4; public static final int TYPE_EXPAND_NOTIFICATION_PANEL = 5; public static final int TYPE_COLLAPSE_NOTIFICATION_PANEL = 6; @@ -25,52 +25,52 @@ public final class ControlEvent { private int hScroll; private int vScroll; - private ControlEvent() { + private ControlMessage() { } - public static ControlEvent createKeycodeControlEvent(int action, int keycode, int metaState) { - ControlEvent event = new ControlEvent(); - event.type = TYPE_KEYCODE; + public static ControlMessage createInjectKeycode(int action, int keycode, int metaState) { + ControlMessage event = new ControlMessage(); + event.type = TYPE_INJECT_KEYCODE; event.action = action; event.keycode = keycode; event.metaState = metaState; return event; } - public static ControlEvent createTextControlEvent(String text) { - ControlEvent event = new ControlEvent(); - event.type = TYPE_TEXT; + public static ControlMessage createInjectText(String text) { + ControlMessage event = new ControlMessage(); + event.type = TYPE_INJECT_TEXT; event.text = text; return event; } - public static ControlEvent createMotionControlEvent(int action, int buttons, Position position) { - ControlEvent event = new ControlEvent(); - event.type = TYPE_MOUSE; + public static ControlMessage createInjectMouseEvent(int action, int buttons, Position position) { + ControlMessage event = new ControlMessage(); + event.type = TYPE_INJECT_MOUSE_EVENT; event.action = action; event.buttons = buttons; event.position = position; return event; } - public static ControlEvent createScrollControlEvent(Position position, int hScroll, int vScroll) { - ControlEvent event = new ControlEvent(); - event.type = TYPE_SCROLL; + public static ControlMessage createInjectScrollEvent(Position position, int hScroll, int vScroll) { + ControlMessage event = new ControlMessage(); + event.type = TYPE_INJECT_SCROLL_EVENT; event.position = position; event.hScroll = hScroll; event.vScroll = vScroll; return event; } - public static ControlEvent createSetClipboardControlEvent(String text) { - ControlEvent event = new ControlEvent(); + public static ControlMessage createSetClipboard(String text) { + ControlMessage event = new ControlMessage(); event.type = TYPE_SET_CLIPBOARD; event.text = text; return event; } - public static ControlEvent createSimpleControlEvent(int type) { - ControlEvent event = new ControlEvent(); + public static ControlMessage createEmpty(int type) { + ControlMessage event = new ControlMessage(); event.type = type; return event; } diff --git a/server/src/main/java/com/genymobile/scrcpy/ControlEventReader.java b/server/src/main/java/com/genymobile/scrcpy/ControlMessageReader.java similarity index 61% rename from server/src/main/java/com/genymobile/scrcpy/ControlEventReader.java rename to server/src/main/java/com/genymobile/scrcpy/ControlMessageReader.java index ec807232..965cd29a 100644 --- a/server/src/main/java/com/genymobile/scrcpy/ControlEventReader.java +++ b/server/src/main/java/com/genymobile/scrcpy/ControlMessageReader.java @@ -6,11 +6,11 @@ import java.io.InputStream; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; -public class ControlEventReader { +public class ControlMessageReader { - private static final int KEYCODE_PAYLOAD_LENGTH = 9; - private static final int MOUSE_PAYLOAD_LENGTH = 17; - private static final int SCROLL_PAYLOAD_LENGTH = 20; + private static final int INJECT_KEYCODE_PAYLOAD_LENGTH = 9; + private static final int INJECT_MOUSE_EVENT_PAYLOAD_LENGTH = 17; + private static final int INJECT_SCROLL_EVENT_PAYLOAD_LENGTH = 20; public static final int TEXT_MAX_LENGTH = 300; public static final int CLIPBOARD_TEXT_MAX_LENGTH = 4093; @@ -20,7 +20,7 @@ public class ControlEventReader { private final ByteBuffer buffer = ByteBuffer.wrap(rawBuffer); private final byte[] textBuffer = new byte[CLIPBOARD_TEXT_MAX_LENGTH]; - public ControlEventReader() { + public ControlMessageReader() { // invariant: the buffer is always in "get" mode buffer.limit(0); } @@ -37,63 +37,63 @@ public class ControlEventReader { int head = buffer.position(); int r = input.read(rawBuffer, head, rawBuffer.length - head); if (r == -1) { - throw new EOFException("Event controller socket closed"); + throw new EOFException("Controller socket closed"); } buffer.position(head + r); buffer.flip(); } - public ControlEvent next() { + public ControlMessage next() { if (!buffer.hasRemaining()) { return null; } int savedPosition = buffer.position(); int type = buffer.get(); - ControlEvent controlEvent; + ControlMessage msg; switch (type) { - case ControlEvent.TYPE_KEYCODE: - controlEvent = parseKeycodeControlEvent(); + case ControlMessage.TYPE_INJECT_KEYCODE: + msg = parseInjectKeycode(); break; - case ControlEvent.TYPE_TEXT: - controlEvent = parseTextControlEvent(); + case ControlMessage.TYPE_INJECT_TEXT: + msg = parseInjectText(); break; - case ControlEvent.TYPE_MOUSE: - controlEvent = parseMouseControlEvent(); + case ControlMessage.TYPE_INJECT_MOUSE_EVENT: + msg = parseInjectMouseEvent(); break; - case ControlEvent.TYPE_SCROLL: - controlEvent = parseScrollControlEvent(); + case ControlMessage.TYPE_INJECT_SCROLL_EVENT: + msg = parseInjectScrollEvent(); break; - case ControlEvent.TYPE_SET_CLIPBOARD: - controlEvent = parseSetClipboardEvent(); + case ControlMessage.TYPE_SET_CLIPBOARD: + msg = parseSetClipboard(); break; - case ControlEvent.TYPE_BACK_OR_SCREEN_ON: - case ControlEvent.TYPE_EXPAND_NOTIFICATION_PANEL: - case ControlEvent.TYPE_COLLAPSE_NOTIFICATION_PANEL: - case ControlEvent.TYPE_GET_CLIPBOARD: - controlEvent = ControlEvent.createSimpleControlEvent(type); + case ControlMessage.TYPE_BACK_OR_SCREEN_ON: + case ControlMessage.TYPE_EXPAND_NOTIFICATION_PANEL: + case ControlMessage.TYPE_COLLAPSE_NOTIFICATION_PANEL: + case ControlMessage.TYPE_GET_CLIPBOARD: + msg = ControlMessage.createEmpty(type); break; default: Ln.w("Unknown event type: " + type); - controlEvent = null; + msg = null; break; } - if (controlEvent == null) { + if (msg == null) { // failure, reset savedPosition buffer.position(savedPosition); } - return controlEvent; + return msg; } - private ControlEvent parseKeycodeControlEvent() { - if (buffer.remaining() < KEYCODE_PAYLOAD_LENGTH) { + private ControlMessage parseInjectKeycode() { + if (buffer.remaining() < INJECT_KEYCODE_PAYLOAD_LENGTH) { return null; } int action = toUnsigned(buffer.get()); int keycode = buffer.getInt(); int metaState = buffer.getInt(); - return ControlEvent.createKeycodeControlEvent(action, keycode, metaState); + return ControlMessage.createInjectKeycode(action, keycode, metaState); } private String parseString() { @@ -108,40 +108,40 @@ public class ControlEventReader { return new String(textBuffer, 0, len, StandardCharsets.UTF_8); } - private ControlEvent parseTextControlEvent() { + private ControlMessage parseInjectText() { String text = parseString(); if (text == null) { return null; } - return ControlEvent.createTextControlEvent(text); + return ControlMessage.createInjectText(text); } - private ControlEvent parseMouseControlEvent() { - if (buffer.remaining() < MOUSE_PAYLOAD_LENGTH) { + private ControlMessage parseInjectMouseEvent() { + if (buffer.remaining() < INJECT_MOUSE_EVENT_PAYLOAD_LENGTH) { return null; } int action = toUnsigned(buffer.get()); int buttons = buffer.getInt(); Position position = readPosition(buffer); - return ControlEvent.createMotionControlEvent(action, buttons, position); + return ControlMessage.createInjectMouseEvent(action, buttons, position); } - private ControlEvent parseScrollControlEvent() { - if (buffer.remaining() < SCROLL_PAYLOAD_LENGTH) { + private ControlMessage parseInjectScrollEvent() { + if (buffer.remaining() < INJECT_SCROLL_EVENT_PAYLOAD_LENGTH) { return null; } Position position = readPosition(buffer); int hScroll = buffer.getInt(); int vScroll = buffer.getInt(); - return ControlEvent.createScrollControlEvent(position, hScroll, vScroll); + return ControlMessage.createInjectScrollEvent(position, hScroll, vScroll); } - private ControlEvent parseSetClipboardEvent() { + private ControlMessage parseSetClipboard() { String text = parseString(); if (text == null) { return null; } - return ControlEvent.createSetClipboardControlEvent(text); + return ControlMessage.createSetClipboard(text); } private static Position readPosition(ByteBuffer buffer) { diff --git a/server/src/main/java/com/genymobile/scrcpy/EventController.java b/server/src/main/java/com/genymobile/scrcpy/Controller.java similarity index 81% rename from server/src/main/java/com/genymobile/scrcpy/EventController.java rename to server/src/main/java/com/genymobile/scrcpy/Controller.java index e8cd2d68..c9215f50 100644 --- a/server/src/main/java/com/genymobile/scrcpy/EventController.java +++ b/server/src/main/java/com/genymobile/scrcpy/Controller.java @@ -11,11 +11,11 @@ import android.view.MotionEvent; import java.io.IOException; -public class EventController { +public class Controller { private final Device device; private final DesktopConnection connection; - private final EventSender sender; + private final DeviceMessageSender sender; private final KeyCharacterMap charMap = KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD); @@ -23,11 +23,11 @@ public class EventController { private final MotionEvent.PointerProperties[] pointerProperties = {new MotionEvent.PointerProperties()}; private final MotionEvent.PointerCoords[] pointerCoords = {new MotionEvent.PointerCoords()}; - public EventController(Device device, DesktopConnection connection) { + public Controller(Device device, DesktopConnection connection) { this.device = device; this.connection = connection; initPointer(); - sender = new EventSender(connection); + sender = new DeviceMessageSender(connection); } private void initPointer() { @@ -62,40 +62,40 @@ public class EventController { } } - public EventSender getSender() { + public DeviceMessageSender getSender() { return sender; } private void handleEvent() throws IOException { - ControlEvent controlEvent = connection.receiveControlEvent(); - switch (controlEvent.getType()) { - case ControlEvent.TYPE_KEYCODE: - injectKeycode(controlEvent.getAction(), controlEvent.getKeycode(), controlEvent.getMetaState()); + ControlMessage msg = connection.receiveControlMessage(); + switch (msg.getType()) { + case ControlMessage.TYPE_INJECT_KEYCODE: + injectKeycode(msg.getAction(), msg.getKeycode(), msg.getMetaState()); break; - case ControlEvent.TYPE_TEXT: - injectText(controlEvent.getText()); + case ControlMessage.TYPE_INJECT_TEXT: + injectText(msg.getText()); break; - case ControlEvent.TYPE_MOUSE: - injectMouse(controlEvent.getAction(), controlEvent.getButtons(), controlEvent.getPosition()); + case ControlMessage.TYPE_INJECT_MOUSE_EVENT: + injectMouse(msg.getAction(), msg.getButtons(), msg.getPosition()); break; - case ControlEvent.TYPE_SCROLL: - injectScroll(controlEvent.getPosition(), controlEvent.getHScroll(), controlEvent.getVScroll()); + case ControlMessage.TYPE_INJECT_SCROLL_EVENT: + injectScroll(msg.getPosition(), msg.getHScroll(), msg.getVScroll()); break; - case ControlEvent.TYPE_BACK_OR_SCREEN_ON: + case ControlMessage.TYPE_BACK_OR_SCREEN_ON: pressBackOrTurnScreenOn(); break; - case ControlEvent.TYPE_EXPAND_NOTIFICATION_PANEL: + case ControlMessage.TYPE_EXPAND_NOTIFICATION_PANEL: device.expandNotificationPanel(); break; - case ControlEvent.TYPE_COLLAPSE_NOTIFICATION_PANEL: + case ControlMessage.TYPE_COLLAPSE_NOTIFICATION_PANEL: device.collapsePanels(); break; - case ControlEvent.TYPE_GET_CLIPBOARD: + case ControlMessage.TYPE_GET_CLIPBOARD: String clipboardText = device.getClipboardText(); sender.pushClipboardText(clipboardText); break; - case ControlEvent.TYPE_SET_CLIPBOARD: - device.setClipboardText(controlEvent.getText()); + case ControlMessage.TYPE_SET_CLIPBOARD: + device.setClipboardText(msg.getText()); break; default: // do nothing diff --git a/server/src/main/java/com/genymobile/scrcpy/DesktopConnection.java b/server/src/main/java/com/genymobile/scrcpy/DesktopConnection.java index dcc9863b..a26c74cd 100644 --- a/server/src/main/java/com/genymobile/scrcpy/DesktopConnection.java +++ b/server/src/main/java/com/genymobile/scrcpy/DesktopConnection.java @@ -24,8 +24,8 @@ public final class DesktopConnection implements Closeable { private final InputStream controlInputStream; private final OutputStream controlOutputStream; - private final ControlEventReader reader = new ControlEventReader(); - private final DeviceEventWriter writer = new DeviceEventWriter(); + private final ControlMessageReader reader = new ControlMessageReader(); + private final DeviceMessageWriter writer = new DeviceMessageWriter(); private DesktopConnection(LocalSocket videoSocket, LocalSocket controlSocket) throws IOException { this.videoSocket = videoSocket; @@ -104,16 +104,16 @@ public final class DesktopConnection implements Closeable { return videoFd; } - public ControlEvent receiveControlEvent() throws IOException { - ControlEvent event = reader.next(); - while (event == null) { + public ControlMessage receiveControlMessage() throws IOException { + ControlMessage msg = reader.next(); + while (msg == null) { reader.readFrom(controlInputStream); - event = reader.next(); + msg = reader.next(); } - return event; + return msg; } - public void sendDeviceEvent(DeviceEvent event) throws IOException { - writer.writeTo(event, controlOutputStream); + public void sendDeviceMessage(DeviceMessage msg) throws IOException { + writer.writeTo(msg, controlOutputStream); } } diff --git a/server/src/main/java/com/genymobile/scrcpy/DeviceEvent.java b/server/src/main/java/com/genymobile/scrcpy/DeviceEvent.java deleted file mode 100644 index 97bcbfc6..00000000 --- a/server/src/main/java/com/genymobile/scrcpy/DeviceEvent.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.genymobile.scrcpy; - -public final class DeviceEvent { - - public static final int TYPE_GET_CLIPBOARD = 0; - - private int type; - private String text; - - private DeviceEvent() { - } - - public static DeviceEvent createGetClipboardEvent(String text) { - DeviceEvent event = new DeviceEvent(); - event.type = TYPE_GET_CLIPBOARD; - event.text = text; - return event; - } - - public int getType() { - return type; - } - - public String getText() { - return text; - } -} diff --git a/server/src/main/java/com/genymobile/scrcpy/DeviceMessage.java b/server/src/main/java/com/genymobile/scrcpy/DeviceMessage.java new file mode 100644 index 00000000..c6eebd38 --- /dev/null +++ b/server/src/main/java/com/genymobile/scrcpy/DeviceMessage.java @@ -0,0 +1,27 @@ +package com.genymobile.scrcpy; + +public final class DeviceMessage { + + public static final int TYPE_CLIPBOARD = 0; + + private int type; + private String text; + + private DeviceMessage() { + } + + public static DeviceMessage createClipboard(String text) { + DeviceMessage event = new DeviceMessage(); + event.type = TYPE_CLIPBOARD; + event.text = text; + return event; + } + + public int getType() { + return type; + } + + public String getText() { + return text; + } +} diff --git a/server/src/main/java/com/genymobile/scrcpy/EventSender.java b/server/src/main/java/com/genymobile/scrcpy/DeviceMessageSender.java similarity index 74% rename from server/src/main/java/com/genymobile/scrcpy/EventSender.java rename to server/src/main/java/com/genymobile/scrcpy/DeviceMessageSender.java index 9f50b16a..bbf4dd2e 100644 --- a/server/src/main/java/com/genymobile/scrcpy/EventSender.java +++ b/server/src/main/java/com/genymobile/scrcpy/DeviceMessageSender.java @@ -2,13 +2,13 @@ package com.genymobile.scrcpy; import java.io.IOException; -public final class EventSender { +public final class DeviceMessageSender { private final DesktopConnection connection; private String clipboardText; - public EventSender(DesktopConnection connection) { + public DeviceMessageSender(DesktopConnection connection) { this.connection = connection; } @@ -27,8 +27,8 @@ public final class EventSender { text = clipboardText; clipboardText = null; } - DeviceEvent event = DeviceEvent.createGetClipboardEvent(text); - connection.sendDeviceEvent(event); + DeviceMessage event = DeviceMessage.createClipboard(text); + connection.sendDeviceMessage(event); } } } diff --git a/server/src/main/java/com/genymobile/scrcpy/DeviceEventWriter.java b/server/src/main/java/com/genymobile/scrcpy/DeviceMessageWriter.java similarity index 72% rename from server/src/main/java/com/genymobile/scrcpy/DeviceEventWriter.java rename to server/src/main/java/com/genymobile/scrcpy/DeviceMessageWriter.java index e183a221..e2a3a1a2 100644 --- a/server/src/main/java/com/genymobile/scrcpy/DeviceEventWriter.java +++ b/server/src/main/java/com/genymobile/scrcpy/DeviceMessageWriter.java @@ -5,7 +5,7 @@ import java.io.OutputStream; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; -public class DeviceEventWriter { +public class DeviceMessageWriter { public static final int CLIPBOARD_TEXT_MAX_LENGTH = 4093; private static final int MAX_EVENT_SIZE = CLIPBOARD_TEXT_MAX_LENGTH + 3; @@ -14,12 +14,12 @@ public class DeviceEventWriter { private final ByteBuffer buffer = ByteBuffer.wrap(rawBuffer); @SuppressWarnings("checkstyle:MagicNumber") - public void writeTo(DeviceEvent event, OutputStream output) throws IOException { + public void writeTo(DeviceMessage msg, OutputStream output) throws IOException { buffer.clear(); - buffer.put((byte) DeviceEvent.TYPE_GET_CLIPBOARD); - switch (event.getType()) { - case DeviceEvent.TYPE_GET_CLIPBOARD: - String text = event.getText(); + buffer.put((byte) DeviceMessage.TYPE_CLIPBOARD); + switch (msg.getType()) { + case DeviceMessage.TYPE_CLIPBOARD: + String text = msg.getText(); byte[] raw = text.getBytes(StandardCharsets.UTF_8); int len = StringUtils.getUtf8TruncationIndex(raw, CLIPBOARD_TEXT_MAX_LENGTH); buffer.putShort((short) len); @@ -27,7 +27,7 @@ public class DeviceEventWriter { output.write(rawBuffer, 0, buffer.position()); break; default: - Ln.w("Unknown device event: " + event.getType()); + Ln.w("Unknown device message: " + msg.getType()); break; } } diff --git a/server/src/main/java/com/genymobile/scrcpy/Server.java b/server/src/main/java/com/genymobile/scrcpy/Server.java index 25cb15e6..76028fbe 100644 --- a/server/src/main/java/com/genymobile/scrcpy/Server.java +++ b/server/src/main/java/com/genymobile/scrcpy/Server.java @@ -19,11 +19,11 @@ public final class Server { try (DesktopConnection connection = DesktopConnection.open(device, tunnelForward)) { ScreenEncoder screenEncoder = new ScreenEncoder(options.getSendFrameMeta(), options.getBitRate()); - EventController controller = new EventController(device, connection); + Controller controller = new Controller(device, connection); // asynchronous - startEventController(controller); - startEventSender(controller.getSender()); + startController(controller); + startDeviceMessageSender(controller.getSender()); try { // synchronous @@ -35,7 +35,7 @@ public final class Server { } } - private static void startEventController(final EventController controller) { + private static void startController(final Controller controller) { new Thread(new Runnable() { @Override public void run() { @@ -43,13 +43,13 @@ public final class Server { controller.control(); } catch (IOException e) { // this is expected on close - Ln.d("Event controller stopped"); + Ln.d("Controller stopped"); } } }).start(); } - private static void startEventSender(final EventSender sender) { + private static void startDeviceMessageSender(final DeviceMessageSender sender) { new Thread(new Runnable() { @Override public void run() { @@ -57,7 +57,7 @@ public final class Server { sender.loop(); } catch (IOException | InterruptedException e) { // this is expected on close - Ln.d("Event sender stopped"); + Ln.d("Device message sender stopped"); } } }).start(); diff --git a/server/src/test/java/com/genymobile/scrcpy/ControlEventReaderTest.java b/server/src/test/java/com/genymobile/scrcpy/ControlMessageReaderTest.java similarity index 69% rename from server/src/test/java/com/genymobile/scrcpy/ControlEventReaderTest.java rename to server/src/test/java/com/genymobile/scrcpy/ControlMessageReaderTest.java index 692b5d23..788ee12e 100644 --- a/server/src/test/java/com/genymobile/scrcpy/ControlEventReaderTest.java +++ b/server/src/test/java/com/genymobile/scrcpy/ControlMessageReaderTest.java @@ -14,24 +14,24 @@ import java.nio.charset.StandardCharsets; import java.util.Arrays; -public class ControlEventReaderTest { +public class ControlMessageReaderTest { @Test public void testParseKeycodeEvent() throws IOException { - ControlEventReader reader = new ControlEventReader(); + ControlMessageReader reader = new ControlMessageReader(); ByteArrayOutputStream bos = new ByteArrayOutputStream(); DataOutputStream dos = new DataOutputStream(bos); - dos.writeByte(ControlEvent.TYPE_KEYCODE); + dos.writeByte(ControlMessage.TYPE_INJECT_KEYCODE); dos.writeByte(KeyEvent.ACTION_UP); dos.writeInt(KeyEvent.KEYCODE_ENTER); dos.writeInt(KeyEvent.META_CTRL_ON); byte[] packet = bos.toByteArray(); reader.readFrom(new ByteArrayInputStream(packet)); - ControlEvent event = reader.next(); + ControlMessage event = reader.next(); - Assert.assertEquals(ControlEvent.TYPE_KEYCODE, event.getType()); + Assert.assertEquals(ControlMessage.TYPE_INJECT_KEYCODE, event.getType()); Assert.assertEquals(KeyEvent.ACTION_UP, event.getAction()); Assert.assertEquals(KeyEvent.KEYCODE_ENTER, event.getKeycode()); Assert.assertEquals(KeyEvent.META_CTRL_ON, event.getMetaState()); @@ -39,59 +39,59 @@ public class ControlEventReaderTest { @Test public void testParseTextEvent() throws IOException { - ControlEventReader reader = new ControlEventReader(); + ControlMessageReader reader = new ControlMessageReader(); ByteArrayOutputStream bos = new ByteArrayOutputStream(); DataOutputStream dos = new DataOutputStream(bos); - dos.writeByte(ControlEvent.TYPE_TEXT); + dos.writeByte(ControlMessage.TYPE_INJECT_TEXT); byte[] text = "testé".getBytes(StandardCharsets.UTF_8); dos.writeShort(text.length); dos.write(text); byte[] packet = bos.toByteArray(); reader.readFrom(new ByteArrayInputStream(packet)); - ControlEvent event = reader.next(); + ControlMessage event = reader.next(); - Assert.assertEquals(ControlEvent.TYPE_TEXT, event.getType()); + Assert.assertEquals(ControlMessage.TYPE_INJECT_TEXT, event.getType()); Assert.assertEquals("testé", event.getText()); } @Test public void testParseLongTextEvent() throws IOException { - ControlEventReader reader = new ControlEventReader(); + ControlMessageReader reader = new ControlMessageReader(); ByteArrayOutputStream bos = new ByteArrayOutputStream(); DataOutputStream dos = new DataOutputStream(bos); - dos.writeByte(ControlEvent.TYPE_TEXT); - byte[] text = new byte[ControlEventReader.TEXT_MAX_LENGTH]; + dos.writeByte(ControlMessage.TYPE_INJECT_TEXT); + byte[] text = new byte[ControlMessageReader.TEXT_MAX_LENGTH]; Arrays.fill(text, (byte) 'a'); dos.writeShort(text.length); dos.write(text); byte[] packet = bos.toByteArray(); reader.readFrom(new ByteArrayInputStream(packet)); - ControlEvent event = reader.next(); + ControlMessage event = reader.next(); - Assert.assertEquals(ControlEvent.TYPE_TEXT, event.getType()); + Assert.assertEquals(ControlMessage.TYPE_INJECT_TEXT, event.getType()); Assert.assertEquals(new String(text, StandardCharsets.US_ASCII), event.getText()); } @Test public void testParseMouseEvent() throws IOException { - ControlEventReader reader = new ControlEventReader(); + ControlMessageReader reader = new ControlMessageReader(); ByteArrayOutputStream bos = new ByteArrayOutputStream(); DataOutputStream dos = new DataOutputStream(bos); - dos.writeByte(ControlEvent.TYPE_KEYCODE); + dos.writeByte(ControlMessage.TYPE_INJECT_KEYCODE); dos.writeByte(MotionEvent.ACTION_DOWN); dos.writeInt(MotionEvent.BUTTON_PRIMARY); dos.writeInt(KeyEvent.META_CTRL_ON); byte[] packet = bos.toByteArray(); reader.readFrom(new ByteArrayInputStream(packet)); - ControlEvent event = reader.next(); + ControlMessage event = reader.next(); - Assert.assertEquals(ControlEvent.TYPE_KEYCODE, event.getType()); + Assert.assertEquals(ControlMessage.TYPE_INJECT_KEYCODE, event.getType()); Assert.assertEquals(MotionEvent.ACTION_DOWN, event.getAction()); Assert.assertEquals(MotionEvent.BUTTON_PRIMARY, event.getKeycode()); Assert.assertEquals(KeyEvent.META_CTRL_ON, event.getMetaState()); @@ -100,11 +100,11 @@ public class ControlEventReaderTest { @Test @SuppressWarnings("checkstyle:MagicNumber") public void testParseScrollEvent() throws IOException { - ControlEventReader reader = new ControlEventReader(); + ControlMessageReader reader = new ControlMessageReader(); ByteArrayOutputStream bos = new ByteArrayOutputStream(); DataOutputStream dos = new DataOutputStream(bos); - dos.writeByte(ControlEvent.TYPE_SCROLL); + dos.writeByte(ControlMessage.TYPE_INJECT_SCROLL_EVENT); dos.writeInt(260); dos.writeInt(1026); dos.writeShort(1080); @@ -115,9 +115,9 @@ public class ControlEventReaderTest { byte[] packet = bos.toByteArray(); reader.readFrom(new ByteArrayInputStream(packet)); - ControlEvent event = reader.next(); + ControlMessage event = reader.next(); - Assert.assertEquals(ControlEvent.TYPE_SCROLL, event.getType()); + Assert.assertEquals(ControlMessage.TYPE_INJECT_SCROLL_EVENT, event.getType()); Assert.assertEquals(260, event.getPosition().getPoint().getX()); Assert.assertEquals(1026, event.getPosition().getPoint().getY()); Assert.assertEquals(1080, event.getPosition().getScreenSize().getWidth()); @@ -128,75 +128,75 @@ public class ControlEventReaderTest { @Test public void testParseBackOrScreenOnEvent() throws IOException { - ControlEventReader reader = new ControlEventReader(); + ControlMessageReader reader = new ControlMessageReader(); ByteArrayOutputStream bos = new ByteArrayOutputStream(); DataOutputStream dos = new DataOutputStream(bos); - dos.writeByte(ControlEvent.TYPE_BACK_OR_SCREEN_ON); + dos.writeByte(ControlMessage.TYPE_BACK_OR_SCREEN_ON); byte[] packet = bos.toByteArray(); reader.readFrom(new ByteArrayInputStream(packet)); - ControlEvent event = reader.next(); + ControlMessage event = reader.next(); - Assert.assertEquals(ControlEvent.TYPE_BACK_OR_SCREEN_ON, event.getType()); + Assert.assertEquals(ControlMessage.TYPE_BACK_OR_SCREEN_ON, event.getType()); } @Test public void testParseExpandNotificationPanelEvent() throws IOException { - ControlEventReader reader = new ControlEventReader(); + ControlMessageReader reader = new ControlMessageReader(); ByteArrayOutputStream bos = new ByteArrayOutputStream(); DataOutputStream dos = new DataOutputStream(bos); - dos.writeByte(ControlEvent.TYPE_EXPAND_NOTIFICATION_PANEL); + dos.writeByte(ControlMessage.TYPE_EXPAND_NOTIFICATION_PANEL); byte[] packet = bos.toByteArray(); reader.readFrom(new ByteArrayInputStream(packet)); - ControlEvent event = reader.next(); + ControlMessage event = reader.next(); - Assert.assertEquals(ControlEvent.TYPE_EXPAND_NOTIFICATION_PANEL, event.getType()); + Assert.assertEquals(ControlMessage.TYPE_EXPAND_NOTIFICATION_PANEL, event.getType()); } @Test public void testParseCollapseNotificationPanelEvent() throws IOException { - ControlEventReader reader = new ControlEventReader(); + ControlMessageReader reader = new ControlMessageReader(); ByteArrayOutputStream bos = new ByteArrayOutputStream(); DataOutputStream dos = new DataOutputStream(bos); - dos.writeByte(ControlEvent.TYPE_COLLAPSE_NOTIFICATION_PANEL); + dos.writeByte(ControlMessage.TYPE_COLLAPSE_NOTIFICATION_PANEL); byte[] packet = bos.toByteArray(); reader.readFrom(new ByteArrayInputStream(packet)); - ControlEvent event = reader.next(); + ControlMessage event = reader.next(); - Assert.assertEquals(ControlEvent.TYPE_COLLAPSE_NOTIFICATION_PANEL, event.getType()); + Assert.assertEquals(ControlMessage.TYPE_COLLAPSE_NOTIFICATION_PANEL, event.getType()); } @Test public void testParseGetClipboardEvent() throws IOException { - ControlEventReader reader = new ControlEventReader(); + ControlMessageReader reader = new ControlMessageReader(); ByteArrayOutputStream bos = new ByteArrayOutputStream(); DataOutputStream dos = new DataOutputStream(bos); - dos.writeByte(ControlEvent.TYPE_GET_CLIPBOARD); + dos.writeByte(ControlMessage.TYPE_GET_CLIPBOARD); byte[] packet = bos.toByteArray(); reader.readFrom(new ByteArrayInputStream(packet)); - ControlEvent event = reader.next(); + ControlMessage event = reader.next(); - Assert.assertEquals(ControlEvent.TYPE_GET_CLIPBOARD, event.getType()); + Assert.assertEquals(ControlMessage.TYPE_GET_CLIPBOARD, event.getType()); } @Test public void testParseSetClipboardEvent() throws IOException { - ControlEventReader reader = new ControlEventReader(); + ControlMessageReader reader = new ControlMessageReader(); ByteArrayOutputStream bos = new ByteArrayOutputStream(); DataOutputStream dos = new DataOutputStream(bos); - dos.writeByte(ControlEvent.TYPE_SET_CLIPBOARD); + dos.writeByte(ControlMessage.TYPE_SET_CLIPBOARD); byte[] text = "testé".getBytes(StandardCharsets.UTF_8); dos.writeShort(text.length); dos.write(text); @@ -204,25 +204,25 @@ public class ControlEventReaderTest { byte[] packet = bos.toByteArray(); reader.readFrom(new ByteArrayInputStream(packet)); - ControlEvent event = reader.next(); + ControlMessage event = reader.next(); - Assert.assertEquals(ControlEvent.TYPE_SET_CLIPBOARD, event.getType()); + Assert.assertEquals(ControlMessage.TYPE_SET_CLIPBOARD, event.getType()); Assert.assertEquals("testé", event.getText()); } @Test public void testMultiEvents() throws IOException { - ControlEventReader reader = new ControlEventReader(); + ControlMessageReader reader = new ControlMessageReader(); ByteArrayOutputStream bos = new ByteArrayOutputStream(); DataOutputStream dos = new DataOutputStream(bos); - dos.writeByte(ControlEvent.TYPE_KEYCODE); + dos.writeByte(ControlMessage.TYPE_INJECT_KEYCODE); dos.writeByte(KeyEvent.ACTION_UP); dos.writeInt(KeyEvent.KEYCODE_ENTER); dos.writeInt(KeyEvent.META_CTRL_ON); - dos.writeByte(ControlEvent.TYPE_KEYCODE); + dos.writeByte(ControlMessage.TYPE_INJECT_KEYCODE); dos.writeByte(MotionEvent.ACTION_DOWN); dos.writeInt(MotionEvent.BUTTON_PRIMARY); dos.writeInt(KeyEvent.META_CTRL_ON); @@ -230,14 +230,14 @@ public class ControlEventReaderTest { byte[] packet = bos.toByteArray(); reader.readFrom(new ByteArrayInputStream(packet)); - ControlEvent event = reader.next(); - Assert.assertEquals(ControlEvent.TYPE_KEYCODE, event.getType()); + ControlMessage event = reader.next(); + Assert.assertEquals(ControlMessage.TYPE_INJECT_KEYCODE, event.getType()); Assert.assertEquals(KeyEvent.ACTION_UP, event.getAction()); Assert.assertEquals(KeyEvent.KEYCODE_ENTER, event.getKeycode()); Assert.assertEquals(KeyEvent.META_CTRL_ON, event.getMetaState()); event = reader.next(); - Assert.assertEquals(ControlEvent.TYPE_KEYCODE, event.getType()); + Assert.assertEquals(ControlMessage.TYPE_INJECT_KEYCODE, event.getType()); Assert.assertEquals(MotionEvent.ACTION_DOWN, event.getAction()); Assert.assertEquals(MotionEvent.BUTTON_PRIMARY, event.getKeycode()); Assert.assertEquals(KeyEvent.META_CTRL_ON, event.getMetaState()); @@ -245,24 +245,24 @@ public class ControlEventReaderTest { @Test public void testPartialEvents() throws IOException { - ControlEventReader reader = new ControlEventReader(); + ControlMessageReader reader = new ControlMessageReader(); ByteArrayOutputStream bos = new ByteArrayOutputStream(); DataOutputStream dos = new DataOutputStream(bos); - dos.writeByte(ControlEvent.TYPE_KEYCODE); + dos.writeByte(ControlMessage.TYPE_INJECT_KEYCODE); dos.writeByte(KeyEvent.ACTION_UP); dos.writeInt(KeyEvent.KEYCODE_ENTER); dos.writeInt(KeyEvent.META_CTRL_ON); - dos.writeByte(ControlEvent.TYPE_KEYCODE); + dos.writeByte(ControlMessage.TYPE_INJECT_KEYCODE); dos.writeByte(MotionEvent.ACTION_DOWN); byte[] packet = bos.toByteArray(); reader.readFrom(new ByteArrayInputStream(packet)); - ControlEvent event = reader.next(); - Assert.assertEquals(ControlEvent.TYPE_KEYCODE, event.getType()); + ControlMessage event = reader.next(); + Assert.assertEquals(ControlMessage.TYPE_INJECT_KEYCODE, event.getType()); Assert.assertEquals(KeyEvent.ACTION_UP, event.getAction()); Assert.assertEquals(KeyEvent.KEYCODE_ENTER, event.getKeycode()); Assert.assertEquals(KeyEvent.META_CTRL_ON, event.getMetaState()); @@ -278,7 +278,7 @@ public class ControlEventReaderTest { // the event is now complete event = reader.next(); - Assert.assertEquals(ControlEvent.TYPE_KEYCODE, event.getType()); + Assert.assertEquals(ControlMessage.TYPE_INJECT_KEYCODE, event.getType()); Assert.assertEquals(MotionEvent.ACTION_DOWN, event.getAction()); Assert.assertEquals(MotionEvent.BUTTON_PRIMARY, event.getKeycode()); Assert.assertEquals(KeyEvent.META_CTRL_ON, event.getMetaState());