Browse Source

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 <alleteam@gmail.com>
Kassim 3 years ago
parent
commit
d541f142c8

+ 25 - 4
applications/plugins/hid_app/hid.c

@@ -9,10 +9,10 @@ enum HidDebugSubmenuIndex {
     HidSubmenuIndexKeynote,
     HidSubmenuIndexKeynote,
     HidSubmenuIndexKeyboard,
     HidSubmenuIndexKeyboard,
     HidSubmenuIndexMedia,
     HidSubmenuIndexMedia,
-    BtHidSubmenuIndexTikTok,
+    HidSubmenuIndexTikTok,
     HidSubmenuIndexMouse,
     HidSubmenuIndexMouse,
+    HidSubmenuIndexMouseJiggler,
 };
 };
-typedef enum { ConnTypeSubmenuIndexBluetooth, ConnTypeSubmenuIndexUsb } ConnTypeDebugSubmenuIndex;
 
 
 static void hid_submenu_callback(void* context, uint32_t index) {
 static void hid_submenu_callback(void* context, uint32_t index) {
     furi_assert(context);
     furi_assert(context);
@@ -29,9 +29,12 @@ static void hid_submenu_callback(void* context, uint32_t index) {
     } else if(index == HidSubmenuIndexMouse) {
     } else if(index == HidSubmenuIndexMouse) {
         app->view_id = HidViewMouse;
         app->view_id = HidViewMouse;
         view_dispatcher_switch_to_view(app->view_dispatcher, HidViewMouse);
         view_dispatcher_switch_to_view(app->view_dispatcher, HidViewMouse);
-    } else if(index == BtHidSubmenuIndexTikTok) {
+    } else if(index == HidSubmenuIndexTikTok) {
         app->view_id = BtHidViewTikTok;
         app->view_id = BtHidViewTikTok;
         view_dispatcher_switch_to_view(app->view_dispatcher, 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_keyboard_set_connected_status(hid->hid_keyboard, connected);
     hid_media_set_connected_status(hid->hid_media, connected);
     hid_media_set_connected_status(hid->hid_media, connected);
     hid_mouse_set_connected_status(hid->hid_mouse, 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);
     hid_tiktok_set_connected_status(hid->hid_tiktok, connected);
 }
 }
 
 
@@ -104,10 +108,16 @@ Hid* hid_alloc(HidTransport transport) {
         submenu_add_item(
         submenu_add_item(
             app->device_type_submenu,
             app->device_type_submenu,
             "TikTok Controller",
             "TikTok Controller",
-            BtHidSubmenuIndexTikTok,
+            HidSubmenuIndexTikTok,
             hid_submenu_callback,
             hid_submenu_callback,
             app);
             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_set_previous_callback(submenu_get_view(app->device_type_submenu), hid_exit);
     view_dispatcher_add_view(
     view_dispatcher_add_view(
         app->view_dispatcher, HidViewSubmenu, submenu_get_view(app->device_type_submenu));
         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(
     view_dispatcher_add_view(
         app->view_dispatcher, HidViewMouse, hid_mouse_get_view(app->hid_mouse));
         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;
     return app;
 }
 }
 
 
@@ -182,6 +201,8 @@ void hid_free(Hid* app) {
     hid_media_free(app->hid_media);
     hid_media_free(app->hid_media);
     view_dispatcher_remove_view(app->view_dispatcher, HidViewMouse);
     view_dispatcher_remove_view(app->view_dispatcher, HidViewMouse);
     hid_mouse_free(app->hid_mouse);
     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);
     view_dispatcher_remove_view(app->view_dispatcher, BtHidViewTikTok);
     hid_tiktok_free(app->hid_tiktok);
     hid_tiktok_free(app->hid_tiktok);
     view_dispatcher_free(app->view_dispatcher);
     view_dispatcher_free(app->view_dispatcher);

+ 2 - 0
applications/plugins/hid_app/hid.h

@@ -19,6 +19,7 @@
 #include "views/hid_keyboard.h"
 #include "views/hid_keyboard.h"
 #include "views/hid_media.h"
 #include "views/hid_media.h"
 #include "views/hid_mouse.h"
 #include "views/hid_mouse.h"
+#include "views/hid_mouse_jiggler.h"
 #include "views/hid_tiktok.h"
 #include "views/hid_tiktok.h"
 
 
 typedef enum {
 typedef enum {
@@ -39,6 +40,7 @@ struct Hid {
     HidKeyboard* hid_keyboard;
     HidKeyboard* hid_keyboard;
     HidMedia* hid_media;
     HidMedia* hid_media;
     HidMouse* hid_mouse;
     HidMouse* hid_mouse;
+    HidMouseJiggler* hid_mouse_jiggler;
     HidTikTok* hid_tiktok;
     HidTikTok* hid_tiktok;
 
 
     HidTransport transport;
     HidTransport transport;

+ 1 - 0
applications/plugins/hid_app/views.h

@@ -4,6 +4,7 @@ typedef enum {
     HidViewKeyboard,
     HidViewKeyboard,
     HidViewMedia,
     HidViewMedia,
     HidViewMouse,
     HidViewMouse,
+    HidViewMouseJiggler,
     BtHidViewTikTok,
     BtHidViewTikTok,
     HidViewExitConfirm,
     HidViewExitConfirm,
 } HidView;
 } HidView;

+ 149 - 0
applications/plugins/hid_app/views/hid_mouse_jiggler.c

@@ -0,0 +1,149 @@
+#include "hid_mouse_jiggler.h"
+#include <gui/elements.h>
+#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);
+}

+ 17 - 0
applications/plugins/hid_app/views/hid_mouse_jiggler.h

@@ -0,0 +1,17 @@
+#pragma once
+
+#include <gui/view.h>
+
+#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);