From 15b271bd922ed0e315206492e67cc1469652aa4c Mon Sep 17 00:00:00 2001 From: Anna Antonenko Date: Mon, 16 Sep 2024 16:27:24 +0300 Subject: [PATCH] fix: cli autolock inhibit --- applications/services/cli/cli_vcp.c | 43 +++++++++++-------- applications/services/desktop/desktop.c | 43 ++++++++++++++++++- applications/services/desktop/desktop.h | 14 ++++++ applications/services/desktop/desktop_i.h | 1 + .../services/desktop/views/desktop_events.h | 2 + scripts/serial_cli.py | 2 +- 6 files changed, 83 insertions(+), 22 deletions(-) diff --git a/applications/services/cli/cli_vcp.c b/applications/services/cli/cli_vcp.c index 9eabd4d7d..a74710284 100644 --- a/applications/services/cli/cli_vcp.c +++ b/applications/services/cli/cli_vcp.c @@ -5,6 +5,7 @@ #include #include #include +#include #define TAG "CliVcp" @@ -50,6 +51,9 @@ typedef struct { // CLI icon Gui* gui; ViewPort* view_port; + + // Autolocking inhibition + Desktop* desktop; } CliVcp; static int32_t vcp_worker(void* context); @@ -117,6 +121,15 @@ static int32_t vcp_worker(void* context) { FURI_LOG_D(TAG, "Start"); vcp->running = true; + // GUI icon + vcp->desktop = furi_record_open(RECORD_DESKTOP); + const Icon* icon = &I_Console_active_8x8; + vcp->gui = furi_record_open(RECORD_GUI); + vcp->view_port = view_port_alloc(); + view_port_set_width(vcp->view_port, icon_get_width(icon)); + // casting const away. we know that we cast it right back in the callback + view_port_draw_callback_set(vcp->view_port, cli_vcp_icon_draw_callback, (void*)icon); + while(1) { uint32_t flags = furi_thread_flags_wait(VCP_THREAD_FLAG_ALL, FuriFlagWaitAny, FuriWaitForever); @@ -129,18 +142,8 @@ static int32_t vcp_worker(void* context) { if(vcp->connected == false) { vcp->connected = true; furi_stream_buffer_send(vcp->rx_stream, &ascii_soh, 1, FuriWaitForever); - - // GUI icon - furi_assert(!vcp->gui); - furi_assert(!vcp->view_port); - const Icon* icon = &I_Console_active_8x8; - vcp->gui = furi_record_open(RECORD_GUI); - vcp->view_port = view_port_alloc(); - view_port_set_width(vcp->view_port, icon_get_width(icon)); - // casting const away. we know that we cast it right back in the callback - view_port_draw_callback_set( - vcp->view_port, cli_vcp_icon_draw_callback, (void*)icon); gui_add_view_port(vcp->gui, vcp->view_port, GuiLayerStatusBarLeft); + desktop_api_add_external_inhibitor(vcp->desktop); } } @@ -152,15 +155,8 @@ static int32_t vcp_worker(void* context) { vcp->connected = false; furi_stream_buffer_receive(vcp->tx_stream, vcp->data_buffer, USB_CDC_PKT_LEN, 0); furi_stream_buffer_send(vcp->rx_stream, &ascii_eot, 1, FuriWaitForever); - - // remove GUI icon - furi_assert(vcp->gui); - furi_assert(vcp->view_port); gui_remove_view_port(vcp->gui, vcp->view_port); - view_port_free(vcp->view_port); - furi_record_close(RECORD_GUI); - vcp->gui = NULL; - vcp->view_port = NULL; + desktop_api_remove_external_inhibitor(vcp->desktop); } } @@ -225,6 +221,10 @@ static int32_t vcp_worker(void* context) { } if(flags & VcpEvtStop) { + if(vcp->connected) { + gui_remove_view_port(vcp->gui, vcp->view_port); + desktop_api_remove_external_inhibitor(vcp->desktop); + } vcp->connected = false; vcp->running = false; furi_hal_cdc_set_callbacks(VCP_IF_NUM, NULL, NULL); @@ -238,6 +238,11 @@ static int32_t vcp_worker(void* context) { break; } } + + view_port_free(vcp->view_port); + furi_record_close(RECORD_DESKTOP); + furi_record_close(RECORD_GUI); + FURI_LOG_D(TAG, "End"); return 0; } diff --git a/applications/services/desktop/desktop.c b/applications/services/desktop/desktop.c index e57e1eb00..93d00c78d 100644 --- a/applications/services/desktop/desktop.c +++ b/applications/services/desktop/desktop.c @@ -19,6 +19,8 @@ static void desktop_auto_lock_arm(Desktop*); static void desktop_auto_lock_inhibit(Desktop*); static void desktop_start_auto_lock_timer(Desktop*); static void desktop_apply_settings(Desktop*); +static void desktop_auto_lock_add_inhibitor(Desktop* desktop); +static void desktop_auto_lock_remove_inhibitor(Desktop* desktop); static void desktop_loader_callback(const void* message, void* context) { furi_assert(context); @@ -130,16 +132,22 @@ static bool desktop_custom_event_callback(void* context, uint32_t event) { animation_manager_unload_and_stall_animation(desktop->animation_manager); } - desktop_auto_lock_inhibit(desktop); + desktop_auto_lock_add_inhibitor(desktop); desktop->app_running = true; furi_semaphore_release(desktop->animation_semaphore); } else if(event == DesktopGlobalAfterAppFinished) { animation_manager_load_and_continue_animation(desktop->animation_manager); - desktop_auto_lock_arm(desktop); + desktop_auto_lock_remove_inhibitor(desktop); desktop->app_running = false; + } else if(event == DesktopGlobalAddExternalInhibitor) { + desktop_auto_lock_add_inhibitor(desktop); + + } else if(event == DesktopGlobalRemoveExternalInhibitor) { + desktop_auto_lock_remove_inhibitor(desktop); + } else if(event == DesktopGlobalAutoLock) { if(!desktop->app_running && !desktop->locked) { desktop_lock(desktop); @@ -205,6 +213,24 @@ static void desktop_auto_lock_arm(Desktop* desktop) { } } +static void desktop_auto_lock_add_inhibitor(Desktop* desktop) { + furi_check(furi_semaphore_release(desktop->auto_lock_inhibitors) == FuriStatusOk); + FURI_LOG_D( + TAG, + "%lu autolock inhibitors (+1)", + furi_semaphore_get_count(desktop->auto_lock_inhibitors)); + desktop_auto_lock_inhibit(desktop); +} + +static void desktop_auto_lock_remove_inhibitor(Desktop* desktop) { + furi_check(furi_semaphore_acquire(desktop->auto_lock_inhibitors, 0) == FuriStatusOk); + uint32_t inhibitors = furi_semaphore_get_count(desktop->auto_lock_inhibitors); + FURI_LOG_D(TAG, "%lu autolock inhibitors (-1)", inhibitors); + if(inhibitors == 0) { + desktop_auto_lock_arm(desktop); + } +} + static void desktop_auto_lock_inhibit(Desktop* desktop) { desktop_stop_auto_lock_timer(desktop); if(desktop->input_events_subscription) { @@ -371,6 +397,7 @@ static Desktop* desktop_alloc(void) { desktop->notification = furi_record_open(RECORD_NOTIFICATION); desktop->input_events_pubsub = furi_record_open(RECORD_INPUT_EVENTS); + desktop->auto_lock_inhibitors = furi_semaphore_alloc(UINT32_MAX, 0); desktop->auto_lock_timer = furi_timer_alloc(desktop_auto_lock_timer_callback, FuriTimerTypeOnce, desktop); @@ -503,6 +530,18 @@ void desktop_api_set_settings(Desktop* instance, const DesktopSettings* settings view_dispatcher_send_custom_event(instance->view_dispatcher, DesktopGlobalSaveSettings); } +void desktop_api_add_external_inhibitor(Desktop* instance) { + furi_assert(instance); + view_dispatcher_send_custom_event( + instance->view_dispatcher, DesktopGlobalAddExternalInhibitor); +} + +void desktop_api_remove_external_inhibitor(Desktop* instance) { + furi_assert(instance); + view_dispatcher_send_custom_event( + instance->view_dispatcher, DesktopGlobalRemoveExternalInhibitor); +} + /* * Application thread */ diff --git a/applications/services/desktop/desktop.h b/applications/services/desktop/desktop.h index e83bc3ee4..4f1556f7c 100644 --- a/applications/services/desktop/desktop.h +++ b/applications/services/desktop/desktop.h @@ -21,3 +21,17 @@ FuriPubSub* desktop_api_get_status_pubsub(Desktop* instance); void desktop_api_get_settings(Desktop* instance, DesktopSettings* settings); void desktop_api_set_settings(Desktop* instance, const DesktopSettings* settings); + +/** + * @brief Adds 1 to the count of active external autolock inhibitors + * + * Autolocking will not get triggered while there's at least 1 inhibitor + */ +void desktop_api_add_external_inhibitor(Desktop* instance); + +/** + * @brief Removes 1 from the count of active external autolock inhibitors + * + * Autolocking will not get triggered while there's at least 1 inhibitor + */ +void desktop_api_remove_external_inhibitor(Desktop* instance); diff --git a/applications/services/desktop/desktop_i.h b/applications/services/desktop/desktop_i.h index 1dc7c7d21..b62dac63c 100644 --- a/applications/services/desktop/desktop_i.h +++ b/applications/services/desktop/desktop_i.h @@ -73,6 +73,7 @@ struct Desktop { FuriPubSub* input_events_pubsub; FuriPubSubSubscription* input_events_subscription; + FuriSemaphore* auto_lock_inhibitors; FuriTimer* auto_lock_timer; FuriTimer* update_clock_timer; diff --git a/applications/services/desktop/views/desktop_events.h b/applications/services/desktop/views/desktop_events.h index 07631dfac..94348184d 100644 --- a/applications/services/desktop/views/desktop_events.h +++ b/applications/services/desktop/views/desktop_events.h @@ -57,4 +57,6 @@ typedef enum { DesktopGlobalApiUnlock, DesktopGlobalSaveSettings, DesktopGlobalReloadSettings, + DesktopGlobalAddExternalInhibitor, + DesktopGlobalRemoveExternalInhibitor, } DesktopEvent; diff --git a/scripts/serial_cli.py b/scripts/serial_cli.py index 8e35d57fa..095b5dd35 100644 --- a/scripts/serial_cli.py +++ b/scripts/serial_cli.py @@ -13,7 +13,7 @@ def main(): parser.add_argument("-p", "--port", help="CDC Port", default="auto") args = parser.parse_args() if not (port := resolve_port(logger, args.port)): - logger.error("Is Flipper connected via USB and not in DFU mode?") + logger.error("Is Flipper connected via USB, currently unlocked and not in DFU mode?") return 1 subprocess.call( [