Merge desktop service changes, refactor some old code

This commit is contained in:
Willy-JL
2024-08-08 00:40:32 +02:00
parent b14944b029
commit 7905b829cf
6 changed files with 243 additions and 179 deletions

View File

@@ -1,32 +1,26 @@
#include <storage/storage.h>
#include <assets_icons.h>
#include <gui/gui.h>
#include <gui/gui_i.h>
#include <gui/view_stack.h>
#include <notification/notification.h>
#include <notification/notification_messages.h>
#include <furi.h>
#include <furi_hal.h>
#include "desktop_i.h"
#include <cli/cli.h>
#include <cli/cli_vcp.h>
#include <locale/locale.h>
#include <applications/main/archive/helpers/archive_helpers_ext.h>
#include <momentum/momentum.h>
#include "animations/animation_manager.h"
#include "desktop/scenes/desktop_scene.h"
#include "desktop/scenes/desktop_scene_i.h"
#include "desktop/views/desktop_view_locked.h"
#include "desktop/views/desktop_view_pin_input.h"
#include "desktop/views/desktop_view_pin_timeout.h"
#include "desktop_i.h"
#include "helpers/pin.h"
#include <gui/gui_i.h>
#include <locale/locale.h>
#include <storage/storage.h>
#include <momentum/settings.h>
#include <applications/main/archive/helpers/archive_helpers_ext.h>
#include <assets_icons.h>
#include "scenes/desktop_scene.h"
#include "scenes/desktop_scene_locked.h"
#define TAG "Desktop"
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_loader_callback(const void* message, void* context) {
furi_assert(context);
@@ -43,6 +37,16 @@ static void desktop_loader_callback(const void* message, void* context) {
}
}
static void desktop_storage_callback(const void* message, void* context) {
furi_assert(context);
Desktop* desktop = context;
const StorageEvent* event = message;
if(event->type == StorageEventTypeCardMount) {
view_dispatcher_send_custom_event(desktop->view_dispatcher, DesktopGlobalReloadSettings);
}
}
static void desktop_lock_icon_draw_callback(Canvas* canvas, void* context) {
UNUSED(context);
furi_assert(canvas);
@@ -117,27 +121,39 @@ static bool desktop_custom_event_callback(void* context, uint32_t event) {
furi_assert(context);
Desktop* desktop = (Desktop*)context;
switch(event) {
case DesktopGlobalBeforeAppStarted:
if(event == DesktopGlobalBeforeAppStarted) {
if(animation_manager_is_animation_loaded(desktop->animation_manager)) {
animation_manager_unload_and_stall_animation(desktop->animation_manager);
}
desktop_auto_lock_inhibit(desktop);
desktop->app_running = true;
furi_semaphore_release(desktop->animation_semaphore);
return true;
case DesktopGlobalAfterAppFinished:
} else if(event == DesktopGlobalAfterAppFinished) {
animation_manager_load_and_continue_animation(desktop->animation_manager);
desktop_clock_reconfigure(desktop);
desktop_auto_lock_arm(desktop);
return true;
case DesktopGlobalAutoLock:
if(!loader_is_locked(desktop->loader) && !desktop->locked) {
desktop->app_running = false;
} else if(event == DesktopGlobalAutoLock) {
if(!desktop->app_running && !desktop->locked) {
desktop_lock(desktop, desktop->settings.auto_lock_with_pin);
}
return true;
} else if(event == DesktopGlobalSaveSettings) {
desktop_settings_save(&desktop->settings);
desktop_apply_settings(desktop);
} else if(event == DesktopGlobalReloadSettings) {
desktop_settings_load(&desktop->settings);
desktop_apply_settings(desktop);
} else {
return scene_manager_handle_custom_event(desktop->scene_manager, event);
}
return scene_manager_handle_custom_event(desktop->scene_manager, event);
return true;
}
static bool desktop_back_event_callback(void* context) {
@@ -205,87 +221,42 @@ static void desktop_clock_timer_callback(void* context) {
furi_assert(context);
Desktop* desktop = context;
if(gui_active_view_port_count(desktop->gui, GuiLayerStatusBarLeft) < 6) {
const bool clock_enabled = gui_active_view_port_count(desktop->gui, GuiLayerStatusBarLeft) < 6;
if(clock_enabled) {
desktop_clock_update(desktop);
view_port_enabled_set(desktop->clock_viewport, true);
} else {
view_port_enabled_set(desktop->clock_viewport, false);
}
view_port_enabled_set(desktop->clock_viewport, clock_enabled);
}
void desktop_lock(Desktop* desktop, bool pin_lock) {
furi_assert(!desktop->locked);
pin_lock = pin_lock && desktop_pin_is_valid(&desktop->settings.pin_code);
if(!furi_hal_rtc_is_flag_set(FuriHalRtcFlagLock)) {
furi_hal_rtc_set_pin_fails(0);
}
if(pin_lock) {
furi_hal_rtc_set_flag(FuriHalRtcFlagLock);
Cli* cli = furi_record_open(RECORD_CLI);
cli_session_close(cli);
furi_record_close(RECORD_CLI);
if(!momentum_settings.allow_locked_rpc_commands) {
Bt* bt = furi_record_open(RECORD_BT);
bt_close_rpc_connection(bt);
furi_record_close(RECORD_BT);
}
}
desktop_auto_lock_inhibit(desktop);
scene_manager_set_scene_state(
desktop->scene_manager, DesktopSceneLocked, SCENE_LOCKED_FIRST_ENTER);
scene_manager_next_scene(desktop->scene_manager, DesktopSceneLocked);
DesktopStatus status = {.locked = true};
furi_pubsub_publish(desktop->status_pubsub, &status);
desktop->locked = true;
}
void desktop_unlock(Desktop* desktop) {
furi_assert(desktop->locked);
view_port_enabled_set(desktop->lock_icon_viewport, false);
Gui* gui = furi_record_open(RECORD_GUI);
gui_set_lockdown(gui, false);
furi_record_close(RECORD_GUI);
desktop_view_locked_unlock(desktop->locked_view);
scene_manager_search_and_switch_to_previous_scene(desktop->scene_manager, DesktopSceneMain);
desktop_auto_lock_arm(desktop);
if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagLock)) {
furi_hal_rtc_reset_flag(FuriHalRtcFlagLock);
furi_hal_rtc_set_pin_fails(0);
Cli* cli = furi_record_open(RECORD_CLI);
cli_session_open(cli, &cli_vcp);
furi_record_close(RECORD_CLI);
}
Bt* bt = furi_record_open(RECORD_BT);
bt_open_rpc_connection(bt);
furi_record_close(RECORD_BT);
DesktopStatus status = {.locked = false};
furi_pubsub_publish(desktop->status_pubsub, &status);
desktop->locked = false;
}
void desktop_set_stealth_mode_state(Desktop* desktop, bool enabled) {
static void desktop_apply_settings(Desktop* desktop) {
desktop->in_transition = true;
if(enabled) {
furi_hal_rtc_set_flag(FuriHalRtcFlagStealthMode);
} else {
furi_hal_rtc_reset_flag(FuriHalRtcFlagStealthMode);
desktop_clock_reconfigure(desktop);
view_port_enabled_set(desktop->dummy_mode_icon_viewport, desktop->settings.dummy_mode);
if(!desktop->app_running && !desktop->locked) {
desktop_auto_lock_arm(desktop);
}
desktop_lock_menu_set_stealth_mode_state(desktop->lock_menu, enabled);
view_port_enabled_set(desktop->stealth_mode_icon_viewport, enabled);
desktop->in_transition = false;
}
Desktop* desktop_alloc(void) {
static void desktop_init_settings(Desktop* desktop) {
furi_pubsub_subscribe(storage_get_pubsub(desktop->storage), desktop_storage_callback, desktop);
if(storage_sd_status(desktop->storage) != FSE_OK) {
FURI_LOG_D(TAG, "SD Card not ready, skipping settings");
return;
}
desktop_settings_load(&desktop->settings);
desktop_apply_settings(desktop);
}
static Desktop* desktop_alloc(void) {
Desktop* desktop = malloc(sizeof(Desktop));
desktop->animation_semaphore = furi_semaphore_alloc(1, 0);
@@ -383,16 +354,14 @@ Desktop* desktop_alloc(void) {
}
gui_add_view_port(desktop->gui, desktop->stealth_mode_icon_viewport, GuiLayerStatusBarLeft);
// Unload animations before starting an application
desktop->loader = furi_record_open(RECORD_LOADER);
furi_pubsub_subscribe(loader_get_pubsub(desktop->loader), desktop_loader_callback, desktop);
desktop->storage = furi_record_open(RECORD_STORAGE);
desktop->notification = furi_record_open(RECORD_NOTIFICATION);
desktop->app_start_stop_subscription = furi_pubsub_subscribe(
loader_get_pubsub(desktop->loader), desktop_loader_callback, desktop);
desktop->input_events_pubsub = furi_record_open(RECORD_INPUT_EVENTS);
desktop->input_events_subscription = NULL;
desktop->ascii_events_pubsub = furi_record_open(RECORD_ASCII_EVENTS);
desktop->ascii_events_subscription = NULL;
desktop->auto_lock_timer =
furi_timer_alloc(desktop_auto_lock_timer_callback, FuriTimerTypeOnce, desktop);
@@ -402,19 +371,95 @@ Desktop* desktop_alloc(void) {
desktop->update_clock_timer =
furi_timer_alloc(desktop_clock_timer_callback, FuriTimerTypePeriodic, desktop);
desktop->app_running = loader_is_locked(desktop->loader);
furi_record_create(RECORD_DESKTOP, desktop);
return desktop;
}
static bool desktop_check_file_flag(const char* flag_path) {
Storage* storage = furi_record_open(RECORD_STORAGE);
bool exists = storage_common_stat(storage, flag_path, NULL) == FSE_OK;
furi_record_close(RECORD_STORAGE);
/*
* Private API
*/
return exists;
void desktop_lock(Desktop* desktop, bool with_pin) {
furi_assert(!desktop->locked);
with_pin = with_pin && desktop_pin_code_is_set();
if(!furi_hal_rtc_is_flag_set(FuriHalRtcFlagLock)) {
furi_hal_rtc_set_pin_fails(0);
}
if(with_pin) {
furi_hal_rtc_set_flag(FuriHalRtcFlagLock);
if(!momentum_settings.allow_locked_rpc_commands) {
Cli* cli = furi_record_open(RECORD_CLI);
cli_session_close(cli);
furi_record_close(RECORD_CLI);
Bt* bt = furi_record_open(RECORD_BT);
bt_close_rpc_connection(bt);
furi_record_close(RECORD_BT);
}
}
desktop_auto_lock_inhibit(desktop);
scene_manager_set_scene_state(
desktop->scene_manager, DesktopSceneLocked, DesktopSceneLockedStateFirstEnter);
scene_manager_next_scene(desktop->scene_manager, DesktopSceneLocked);
DesktopStatus status = {.locked = true};
furi_pubsub_publish(desktop->status_pubsub, &status);
desktop->locked = true;
}
void desktop_unlock(Desktop* desktop) {
furi_assert(desktop->locked);
view_port_enabled_set(desktop->lock_icon_viewport, false);
Gui* gui = furi_record_open(RECORD_GUI);
gui_set_lockdown(gui, false);
furi_record_close(RECORD_GUI);
desktop_view_locked_unlock(desktop->locked_view);
scene_manager_search_and_switch_to_previous_scene(desktop->scene_manager, DesktopSceneMain);
desktop_auto_lock_arm(desktop);
bool with_pin = furi_hal_rtc_is_flag_set(FuriHalRtcFlagLock);
furi_hal_rtc_reset_flag(FuriHalRtcFlagLock);
furi_hal_rtc_set_pin_fails(0);
if(with_pin) {
Cli* cli = furi_record_open(RECORD_CLI);
cli_session_open(cli, &cli_vcp);
furi_record_close(RECORD_CLI);
Bt* bt = furi_record_open(RECORD_BT);
bt_open_rpc_connection(bt);
furi_record_close(RECORD_BT);
}
DesktopStatus status = {.locked = false};
furi_pubsub_publish(desktop->status_pubsub, &status);
desktop->locked = false;
}
void desktop_set_stealth_mode_state(Desktop* desktop, bool enabled) {
desktop->in_transition = true;
if(enabled) {
furi_hal_rtc_set_flag(FuriHalRtcFlagStealthMode);
} else {
furi_hal_rtc_reset_flag(FuriHalRtcFlagStealthMode);
}
view_port_enabled_set(desktop->stealth_mode_icon_viewport, enabled);
desktop->in_transition = false;
}
/*
* Public API
*/
bool desktop_api_is_locked(Desktop* instance) {
furi_assert(instance);
return furi_hal_rtc_is_flag_set(FuriHalRtcFlagLock);
@@ -430,6 +475,26 @@ FuriPubSub* desktop_api_get_status_pubsub(Desktop* instance) {
return instance->status_pubsub;
}
void desktop_api_reload_settings(Desktop* instance) {
furi_assert(instance);
view_dispatcher_send_custom_event(instance->view_dispatcher, DesktopGlobalReloadSettings);
}
void desktop_api_get_settings(Desktop* instance, DesktopSettings* settings) {
furi_assert(instance);
furi_assert(settings);
*settings = instance->settings;
}
void desktop_api_set_settings(Desktop* instance, const DesktopSettings* settings) {
furi_assert(instance);
furi_assert(settings);
instance->settings = *settings;
view_dispatcher_send_custom_event(instance->view_dispatcher, DesktopGlobalSaveSettings);
}
static const KeybindType keybind_types[] = {
[InputTypeShort] = KeybindTypePress,
[InputTypeLong] = KeybindTypeHold,
@@ -479,6 +544,10 @@ void desktop_run_keybind(Desktop* instance, InputType _type, InputKey _key) {
}
}
/*
* Application thread
*/
int32_t desktop_srv(void* p) {
UNUSED(p);
@@ -491,31 +560,15 @@ int32_t desktop_srv(void* p) {
Desktop* desktop = desktop_alloc();
bool ok = DESKTOP_SETTINGS_LOAD(&desktop->settings);
if(ok && desktop->settings.pin_code.length) {
ok = desktop_pin_is_valid(&desktop->settings.pin_code);
}
if(!ok) {
memset(&desktop->settings, 0, sizeof(desktop->settings));
furi_hal_rtc_reset_flag(FuriHalRtcFlagLock);
furi_hal_rtc_set_pin_fails(0);
}
DESKTOP_KEYBINDS_LOAD(&desktop->keybinds, sizeof(desktop->keybinds));
desktop_clock_reconfigure(desktop);
desktop_init_settings(desktop);
scene_manager_next_scene(desktop->scene_manager, DesktopSceneMain);
if(momentum_settings.lock_on_boot || furi_hal_rtc_is_flag_set(FuriHalRtcFlagLock)) {
desktop_lock(desktop, true);
} else {
if(!loader_is_locked(desktop->loader)) {
desktop_auto_lock_arm(desktop);
}
}
if(desktop_check_file_flag(SLIDESHOW_FS_PATH)) {
if(storage_file_exists(desktop->storage, SLIDESHOW_FS_PATH)) {
scene_manager_next_scene(desktop->scene_manager, DesktopSceneSlideshow);
}
@@ -539,14 +592,12 @@ int32_t desktop_srv(void* p) {
}
// Special case: autostart application is already running
if(loader_is_locked(desktop->loader) &&
animation_manager_is_animation_loaded(desktop->animation_manager)) {
if(desktop->app_running && animation_manager_is_animation_loaded(desktop->animation_manager)) {
animation_manager_unload_and_stall_animation(desktop->animation_manager);
}
view_dispatcher_run(desktop->view_dispatcher);
furi_crash("That was unexpected");
// Should never get here (a service thread will crash automatically if it returns)
return 0;
}