From d541f142c8af39313b525aa28fc7aa7923c0c3f6 Mon Sep 17 00:00:00 2001 From: Kassim Date: Mon, 12 Dec 2022 09:47:22 +0000 Subject: [PATCH 1/2] Add Mouse Jiggler to HID Remote (#2113) * feat: add Mouse Jiggler to HID Remote * move processing to use furi_timer instead of draw loop * HidApp: refine mouse jiggler, move timer work into enter/exit callbacks Co-authored-by: Aleksandr Kutuzov --- applications/plugins/hid_app/hid.c | 29 +++- applications/plugins/hid_app/hid.h | 2 + applications/plugins/hid_app/views.h | 1 + .../plugins/hid_app/views/hid_mouse_jiggler.c | 149 ++++++++++++++++++ .../plugins/hid_app/views/hid_mouse_jiggler.h | 17 ++ 5 files changed, 194 insertions(+), 4 deletions(-) create mode 100644 applications/plugins/hid_app/views/hid_mouse_jiggler.c create mode 100644 applications/plugins/hid_app/views/hid_mouse_jiggler.h diff --git a/applications/plugins/hid_app/hid.c b/applications/plugins/hid_app/hid.c index 2a617fdea..d205d96eb 100644 --- a/applications/plugins/hid_app/hid.c +++ b/applications/plugins/hid_app/hid.c @@ -9,10 +9,10 @@ enum HidDebugSubmenuIndex { HidSubmenuIndexKeynote, HidSubmenuIndexKeyboard, HidSubmenuIndexMedia, - BtHidSubmenuIndexTikTok, + HidSubmenuIndexTikTok, HidSubmenuIndexMouse, + HidSubmenuIndexMouseJiggler, }; -typedef enum { ConnTypeSubmenuIndexBluetooth, ConnTypeSubmenuIndexUsb } ConnTypeDebugSubmenuIndex; static void hid_submenu_callback(void* context, uint32_t index) { furi_assert(context); @@ -29,9 +29,12 @@ static void hid_submenu_callback(void* context, uint32_t index) { } else if(index == HidSubmenuIndexMouse) { app->view_id = HidViewMouse; view_dispatcher_switch_to_view(app->view_dispatcher, HidViewMouse); - } else if(index == BtHidSubmenuIndexTikTok) { + } else if(index == HidSubmenuIndexTikTok) { app->view_id = BtHidViewTikTok; view_dispatcher_switch_to_view(app->view_dispatcher, BtHidViewTikTok); + } else if(index == HidSubmenuIndexMouseJiggler) { + app->view_id = HidViewMouseJiggler; + view_dispatcher_switch_to_view(app->view_dispatcher, HidViewMouseJiggler); } } @@ -48,6 +51,7 @@ static void bt_hid_connection_status_changed_callback(BtStatus status, void* con hid_keyboard_set_connected_status(hid->hid_keyboard, connected); hid_media_set_connected_status(hid->hid_media, connected); hid_mouse_set_connected_status(hid->hid_mouse, connected); + hid_mouse_jiggler_set_connected_status(hid->hid_mouse_jiggler, connected); hid_tiktok_set_connected_status(hid->hid_tiktok, connected); } @@ -104,10 +108,16 @@ Hid* hid_alloc(HidTransport transport) { submenu_add_item( app->device_type_submenu, "TikTok Controller", - BtHidSubmenuIndexTikTok, + HidSubmenuIndexTikTok, hid_submenu_callback, app); } + submenu_add_item( + app->device_type_submenu, + "Mouse Jiggler", + HidSubmenuIndexMouseJiggler, + hid_submenu_callback, + app); view_set_previous_callback(submenu_get_view(app->device_type_submenu), hid_exit); view_dispatcher_add_view( app->view_dispatcher, HidViewSubmenu, submenu_get_view(app->device_type_submenu)); @@ -160,6 +170,15 @@ Hid* hid_app_alloc_view(void* context) { view_dispatcher_add_view( app->view_dispatcher, HidViewMouse, hid_mouse_get_view(app->hid_mouse)); + // Mouse jiggler view + app->hid_mouse_jiggler = hid_mouse_jiggler_alloc(app); + view_set_previous_callback( + hid_mouse_jiggler_get_view(app->hid_mouse_jiggler), hid_exit_confirm_view); + view_dispatcher_add_view( + app->view_dispatcher, + HidViewMouseJiggler, + hid_mouse_jiggler_get_view(app->hid_mouse_jiggler)); + return app; } @@ -182,6 +201,8 @@ void hid_free(Hid* app) { hid_media_free(app->hid_media); view_dispatcher_remove_view(app->view_dispatcher, HidViewMouse); hid_mouse_free(app->hid_mouse); + view_dispatcher_remove_view(app->view_dispatcher, HidViewMouseJiggler); + hid_mouse_jiggler_free(app->hid_mouse_jiggler); view_dispatcher_remove_view(app->view_dispatcher, BtHidViewTikTok); hid_tiktok_free(app->hid_tiktok); view_dispatcher_free(app->view_dispatcher); diff --git a/applications/plugins/hid_app/hid.h b/applications/plugins/hid_app/hid.h index 81ebcf566..375a89706 100644 --- a/applications/plugins/hid_app/hid.h +++ b/applications/plugins/hid_app/hid.h @@ -19,6 +19,7 @@ #include "views/hid_keyboard.h" #include "views/hid_media.h" #include "views/hid_mouse.h" +#include "views/hid_mouse_jiggler.h" #include "views/hid_tiktok.h" typedef enum { @@ -39,6 +40,7 @@ struct Hid { HidKeyboard* hid_keyboard; HidMedia* hid_media; HidMouse* hid_mouse; + HidMouseJiggler* hid_mouse_jiggler; HidTikTok* hid_tiktok; HidTransport transport; diff --git a/applications/plugins/hid_app/views.h b/applications/plugins/hid_app/views.h index 68a827ad6..2a44832e1 100644 --- a/applications/plugins/hid_app/views.h +++ b/applications/plugins/hid_app/views.h @@ -4,6 +4,7 @@ typedef enum { HidViewKeyboard, HidViewMedia, HidViewMouse, + HidViewMouseJiggler, BtHidViewTikTok, HidViewExitConfirm, } HidView; \ No newline at end of file diff --git a/applications/plugins/hid_app/views/hid_mouse_jiggler.c b/applications/plugins/hid_app/views/hid_mouse_jiggler.c new file mode 100644 index 000000000..a2b07c7a1 --- /dev/null +++ b/applications/plugins/hid_app/views/hid_mouse_jiggler.c @@ -0,0 +1,149 @@ +#include "hid_mouse_jiggler.h" +#include +#include "../hid.h" + +#include "hid_icons.h" + +#define TAG "HidMouseJiggler" + +struct HidMouseJiggler { + View* view; + Hid* hid; + FuriTimer* timer; +}; + +typedef struct { + bool connected; + bool running; + uint8_t counter; +} HidMouseJigglerModel; + +static void hid_mouse_jiggler_draw_callback(Canvas* canvas, void* context) { + furi_assert(context); + HidMouseJigglerModel* model = context; + + // Header + if(model->connected) { + canvas_draw_icon(canvas, 0, 0, &I_Ble_connected_15x15); + } else { + canvas_draw_icon(canvas, 0, 0, &I_Ble_disconnected_15x15); + } + canvas_set_font(canvas, FontPrimary); + elements_multiline_text_aligned(canvas, 17, 3, AlignLeft, AlignTop, "Mouse Jiggler"); + + canvas_set_font(canvas, FontPrimary); + elements_multiline_text(canvas, AlignLeft, 35, "Press Start\nto jiggle"); + canvas_set_font(canvas, FontSecondary); + + // Ok + canvas_draw_icon(canvas, 63, 25, &I_Space_65x18); + if(model->running) { + elements_slightly_rounded_box(canvas, 66, 27, 60, 13); + canvas_set_color(canvas, ColorWhite); + } + canvas_draw_icon(canvas, 74, 29, &I_Ok_btn_9x9); + if(model->running) { + elements_multiline_text_aligned(canvas, 91, 36, AlignLeft, AlignBottom, "Stop"); + } else { + elements_multiline_text_aligned(canvas, 91, 36, AlignLeft, AlignBottom, "Start"); + } + canvas_set_color(canvas, ColorBlack); + + // Back + canvas_draw_icon(canvas, 74, 49, &I_Pin_back_arrow_10x8); + elements_multiline_text_aligned(canvas, 91, 57, AlignLeft, AlignBottom, "Quit"); +} + +static void hid_mouse_jiggler_timer_callback(void* context) { + furi_assert(context); + HidMouseJiggler* hid_mouse_jiggler = context; + with_view_model( + hid_mouse_jiggler->view, + HidMouseJigglerModel * model, + { + if(model->running) { + model->counter++; + hid_hal_mouse_move( + hid_mouse_jiggler->hid, + (model->counter % 2 == 0) ? MOUSE_MOVE_SHORT : -MOUSE_MOVE_SHORT, + 0); + } + }, + false); +} + +static void hid_mouse_jiggler_enter_callback(void* context) { + furi_assert(context); + HidMouseJiggler* hid_mouse_jiggler = context; + + furi_timer_start(hid_mouse_jiggler->timer, 500); +} + +static void hid_mouse_jiggler_exit_callback(void* context) { + furi_assert(context); + HidMouseJiggler* hid_mouse_jiggler = context; + furi_timer_stop(hid_mouse_jiggler->timer); +} + +static bool hid_mouse_jiggler_input_callback(InputEvent* event, void* context) { + furi_assert(context); + HidMouseJiggler* hid_mouse_jiggler = context; + + bool consumed = false; + + if(event->key == InputKeyOk) { + with_view_model( + hid_mouse_jiggler->view, + HidMouseJigglerModel * model, + { model->running = !model->running; }, + true); + consumed = true; + } + + return consumed; +} + +HidMouseJiggler* hid_mouse_jiggler_alloc(Hid* hid) { + HidMouseJiggler* hid_mouse_jiggler = malloc(sizeof(HidMouseJiggler)); + + hid_mouse_jiggler->view = view_alloc(); + view_set_context(hid_mouse_jiggler->view, hid_mouse_jiggler); + view_allocate_model( + hid_mouse_jiggler->view, ViewModelTypeLocking, sizeof(HidMouseJigglerModel)); + view_set_draw_callback(hid_mouse_jiggler->view, hid_mouse_jiggler_draw_callback); + view_set_input_callback(hid_mouse_jiggler->view, hid_mouse_jiggler_input_callback); + view_set_enter_callback(hid_mouse_jiggler->view, hid_mouse_jiggler_enter_callback); + view_set_exit_callback(hid_mouse_jiggler->view, hid_mouse_jiggler_exit_callback); + + hid_mouse_jiggler->hid = hid; + + hid_mouse_jiggler->timer = furi_timer_alloc( + hid_mouse_jiggler_timer_callback, FuriTimerTypePeriodic, hid_mouse_jiggler); + + return hid_mouse_jiggler; +} + +void hid_mouse_jiggler_free(HidMouseJiggler* hid_mouse_jiggler) { + furi_assert(hid_mouse_jiggler); + + furi_timer_stop(hid_mouse_jiggler->timer); + furi_timer_free(hid_mouse_jiggler->timer); + + view_free(hid_mouse_jiggler->view); + + free(hid_mouse_jiggler); +} + +View* hid_mouse_jiggler_get_view(HidMouseJiggler* hid_mouse_jiggler) { + furi_assert(hid_mouse_jiggler); + return hid_mouse_jiggler->view; +} + +void hid_mouse_jiggler_set_connected_status(HidMouseJiggler* hid_mouse_jiggler, bool connected) { + furi_assert(hid_mouse_jiggler); + with_view_model( + hid_mouse_jiggler->view, + HidMouseJigglerModel * model, + { model->connected = connected; }, + true); +} diff --git a/applications/plugins/hid_app/views/hid_mouse_jiggler.h b/applications/plugins/hid_app/views/hid_mouse_jiggler.h new file mode 100644 index 000000000..0813b4351 --- /dev/null +++ b/applications/plugins/hid_app/views/hid_mouse_jiggler.h @@ -0,0 +1,17 @@ +#pragma once + +#include + +#define MOUSE_MOVE_SHORT 5 +#define MOUSE_MOVE_LONG 20 + +typedef struct Hid Hid; +typedef struct HidMouseJiggler HidMouseJiggler; + +HidMouseJiggler* hid_mouse_jiggler_alloc(Hid* bt_hid); + +void hid_mouse_jiggler_free(HidMouseJiggler* hid_mouse_jiggler); + +View* hid_mouse_jiggler_get_view(HidMouseJiggler* hid_mouse_jiggler); + +void hid_mouse_jiggler_set_connected_status(HidMouseJiggler* hid_mouse_jiggler, bool connected); From 1c12613863d31bfd778764318742ea28039948c9 Mon Sep 17 00:00:00 2001 From: usiegl00 <50933431+usiegl00@users.noreply.github.com> Date: Mon, 12 Dec 2022 21:46:41 +0900 Subject: [PATCH 2/2] Prevent hacking related backgrounds from being displayed in dummy mode. (#2107) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Prevent hacking related backgrounds from being displayed in dummy mode. * Add function call to animation manager to set dummy mode. * Reboot retains dummy mode background. Co-authored-by: あく --- .../services/desktop/animations/animation_manager.c | 11 ++++++++++- .../services/desktop/animations/animation_manager.h | 8 ++++++++ applications/services/desktop/desktop.c | 3 +++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/applications/services/desktop/animations/animation_manager.c b/applications/services/desktop/animations/animation_manager.c index 36c5b3975..9c22d1314 100644 --- a/applications/services/desktop/animations/animation_manager.c +++ b/applications/services/desktop/animations/animation_manager.c @@ -52,6 +52,7 @@ struct AnimationManager { FuriString* freezed_animation_name; int32_t freezed_animation_time_left; ViewStack* view_stack; + bool dummy_mode; }; static StorageAnimation* @@ -93,6 +94,12 @@ void animation_manager_set_interact_callback( animation_manager->interact_callback = callback; } +void animation_manager_set_dummy_mode_state(AnimationManager* animation_manager, bool enabled) { + furi_assert(animation_manager); + animation_manager->dummy_mode = enabled; + animation_manager_start_new_idle(animation_manager); +} + static void animation_manager_check_blocking_callback(const void* message, void* context) { const StorageEvent* storage_event = message; @@ -363,7 +370,9 @@ static bool animation_manager_is_valid_idle_animation( static StorageAnimation* animation_manager_select_idle_animation(AnimationManager* animation_manager) { - UNUSED(animation_manager); + if(animation_manager->dummy_mode) { + return animation_storage_find_animation(HARDCODED_ANIMATION_NAME); + } StorageAnimationList_t animation_list; StorageAnimationList_init(animation_list); animation_storage_fill_animation_list(&animation_list); diff --git a/applications/services/desktop/animations/animation_manager.h b/applications/services/desktop/animations/animation_manager.h index 234d20de0..a3dcc8827 100644 --- a/applications/services/desktop/animations/animation_manager.h +++ b/applications/services/desktop/animations/animation_manager.h @@ -157,3 +157,11 @@ void animation_manager_unload_and_stall_animation(AnimationManager* animation_ma * @animation_manager instance */ void animation_manager_load_and_continue_animation(AnimationManager* animation_manager); + +/** + * Enable or disable dummy mode backgrounds of animation manager. + * + * @animation_manager instance + * @enabled bool + */ +void animation_manager_set_dummy_mode_state(AnimationManager* animation_manager, bool enabled); diff --git a/applications/services/desktop/desktop.c b/applications/services/desktop/desktop.c index b45a9d621..848f5cb63 100644 --- a/applications/services/desktop/desktop.c +++ b/applications/services/desktop/desktop.c @@ -144,6 +144,7 @@ void desktop_unlock(Desktop* desktop) { void desktop_set_dummy_mode_state(Desktop* desktop, bool enabled) { view_port_enabled_set(desktop->dummy_mode_icon_viewport, enabled); desktop_main_set_dummy_mode_state(desktop->main_view, enabled); + animation_manager_set_dummy_mode_state(desktop->animation_manager, enabled); desktop->settings.dummy_mode = enabled; DESKTOP_SETTINGS_SAVE(&desktop->settings); } @@ -330,6 +331,8 @@ int32_t desktop_srv(void* p) { view_port_enabled_set(desktop->dummy_mode_icon_viewport, desktop->settings.dummy_mode); desktop_main_set_dummy_mode_state(desktop->main_view, desktop->settings.dummy_mode); + animation_manager_set_dummy_mode_state( + desktop->animation_manager, desktop->settings.dummy_mode); scene_manager_next_scene(desktop->scene_manager, DesktopSceneMain);