mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-05-11 06:09:08 -07:00
Storage: remove LFS (#3577)
* Storage: drop internal storage * Storage: rollback some unnecessary changes * Storage: rollback some unnecessary changes part 2 * Storage: cleanup various defines and int handling. Ble: allow short connection interval if internal flash is not used. * Storage: do not return storage if it is not ready * Save PIN code to RTC, update settings * Simplify the code, clean up includes * Rearrange some code * apps: storage_move_to_sd: conditionally enable with --extra-define=STORAGE_INT_ON_LFS * Load Desktop settings automatically * Redirect /any to /ext * Abolish storage_move_to_sd app * Remove as many mentions of ANY_PATH as possible * Fix desktop settings wrongly not loading * Improve desktop settings handling and strings * Load BLE settings and keys automatically * Improve BLE configuration procedure * Do not load bluetooth keys twice if they were already loaded * Load dolphin state automatically * Fix merge artifact * Load notification settings automatically * Update desktop settings strings * Load expansion settings automatically * Do not use thread signals to reload desktop settings * Load region data automatically, separate to its own hook * Improve ble behaviour with no keys * Fix Dolphin state not resetting correctly * Add a status check * Make Desktop save its own settings * Check result when taking and releasing mutex * Improve default thread signal handling in FuriEventLoop * Make bt service in charge of saving settings, add settings api * Fix a deadlock due to timer thread not receiving time * Lock core2 when reinitialising bt * Update clang-format * Revert "Update clang-format" This reverts commit d61295ac063c6ec879375ceeab54d6ff2c90a9a1. * Format sources with clang-format * Revert old stack size for desktop settings * Allocate big struct dynamically * Simplify PIN comparison * Save pointer to storage in Desktop object * Fix region provisioning for hardware regions * Remove stale TODO + siimplify code * Clean up region.c * Use sizeof instead of macro define * Limit PIN length to 10 for consistency * Emit a warning upon usage of /any * Add delay after finding flipper * Remove unnecessary delay * Remove all mentions of STORAGE_INT_ON_LFS * Remove littlefs and internal storage * Remove all possible LittleFS mentions * Fix browser tab in Archive * Ble: fix connection interval explanation * Bump API Symbols * BLE: Update comments interval connection comments * Storage: clear FuriHalRtcFlagStorageFormatInternal if set --------- Co-authored-by: Georgii Surkov <georgii.surkov@outlook.com> Co-authored-by: hedger <hedger@nanode.su> Co-authored-by: Georgii Surkov <37121527+gsurkov@users.noreply.github.com>
This commit is contained in:
@@ -97,8 +97,11 @@ void animation_manager_set_interact_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);
|
||||
// Prevent change of animations if mode is the same
|
||||
if(animation_manager->dummy_mode != enabled) {
|
||||
animation_manager->dummy_mode = enabled;
|
||||
animation_manager_start_new_idle(animation_manager);
|
||||
}
|
||||
}
|
||||
|
||||
static void animation_manager_check_blocking_callback(const void* message, void* context) {
|
||||
|
||||
@@ -1,31 +1,24 @@
|
||||
#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 "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 "helpers/slideshow_filename.h"
|
||||
#include <gui/gui_i.h>
|
||||
|
||||
#include <locale/locale.h>
|
||||
#include <storage/storage.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);
|
||||
@@ -42,6 +35,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);
|
||||
@@ -122,30 +125,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_SETTINGS_LOAD(&desktop->settings);
|
||||
|
||||
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);
|
||||
}
|
||||
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,84 +217,45 @@ 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);
|
||||
}
|
||||
}
|
||||
|
||||
void desktop_lock(Desktop* desktop) {
|
||||
furi_assert(!desktop->locked);
|
||||
|
||||
furi_hal_rtc_set_flag(FuriHalRtcFlagLock);
|
||||
|
||||
if(desktop->settings.pin_code.length) {
|
||||
Cli* cli = furi_record_open(RECORD_CLI);
|
||||
cli_session_close(cli);
|
||||
furi_record_close(RECORD_CLI);
|
||||
}
|
||||
|
||||
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;
|
||||
view_port_enabled_set(desktop->clock_viewport, clock_enabled);
|
||||
}
|
||||
|
||||
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);
|
||||
furi_hal_rtc_reset_flag(FuriHalRtcFlagLock);
|
||||
furi_hal_rtc_set_pin_fails(0);
|
||||
|
||||
if(desktop->settings.pin_code.length) {
|
||||
Cli* cli = furi_record_open(RECORD_CLI);
|
||||
cli_session_open(cli, &cli_vcp);
|
||||
furi_record_close(RECORD_CLI);
|
||||
}
|
||||
|
||||
DesktopStatus status = {.locked = false};
|
||||
furi_pubsub_publish(desktop->status_pubsub, &status);
|
||||
|
||||
desktop->locked = false;
|
||||
}
|
||||
|
||||
void desktop_set_dummy_mode_state(Desktop* desktop, bool enabled) {
|
||||
static void desktop_apply_settings(Desktop* desktop) {
|
||||
desktop->in_transition = true;
|
||||
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);
|
||||
|
||||
desktop_clock_reconfigure(desktop);
|
||||
|
||||
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);
|
||||
|
||||
if(!desktop->app_running && !desktop->locked) {
|
||||
desktop_auto_lock_arm(desktop);
|
||||
}
|
||||
|
||||
desktop->in_transition = 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);
|
||||
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;
|
||||
}
|
||||
view_port_enabled_set(desktop->stealth_mode_icon_viewport, enabled);
|
||||
desktop->in_transition = false;
|
||||
|
||||
desktop_settings_load(&desktop->settings);
|
||||
desktop_apply_settings(desktop);
|
||||
}
|
||||
|
||||
Desktop* desktop_alloc(void) {
|
||||
static Desktop* desktop_alloc(void) {
|
||||
Desktop* desktop = malloc(sizeof(Desktop));
|
||||
|
||||
desktop->animation_semaphore = furi_semaphore_alloc(1, 0);
|
||||
@@ -391,14 +364,13 @@ 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->auto_lock_timer =
|
||||
furi_timer_alloc(desktop_auto_lock_timer_callback, FuriTimerTypeOnce, desktop);
|
||||
@@ -408,19 +380,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) {
|
||||
furi_assert(!desktop->locked);
|
||||
|
||||
furi_hal_rtc_set_flag(FuriHalRtcFlagLock);
|
||||
|
||||
if(desktop_pin_code_is_set()) {
|
||||
Cli* cli = furi_record_open(RECORD_CLI);
|
||||
cli_session_close(cli);
|
||||
furi_record_close(RECORD_CLI);
|
||||
}
|
||||
|
||||
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);
|
||||
furi_hal_rtc_reset_flag(FuriHalRtcFlagLock);
|
||||
furi_hal_rtc_set_pin_fails(0);
|
||||
|
||||
if(desktop_pin_code_is_set()) {
|
||||
Cli* cli = furi_record_open(RECORD_CLI);
|
||||
cli_session_open(cli, &cli_vcp);
|
||||
furi_record_close(RECORD_CLI);
|
||||
}
|
||||
|
||||
DesktopStatus status = {.locked = false};
|
||||
furi_pubsub_publish(desktop->status_pubsub, &status);
|
||||
|
||||
desktop->locked = false;
|
||||
}
|
||||
|
||||
void desktop_set_dummy_mode_state(Desktop* desktop, bool enabled) {
|
||||
desktop->in_transition = true;
|
||||
|
||||
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->in_transition = false;
|
||||
|
||||
desktop_settings_save(&desktop->settings);
|
||||
}
|
||||
|
||||
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);
|
||||
@@ -436,6 +484,30 @@ 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);
|
||||
}
|
||||
|
||||
/*
|
||||
* Application thread
|
||||
*/
|
||||
|
||||
int32_t desktop_srv(void* p) {
|
||||
UNUSED(p);
|
||||
|
||||
@@ -448,31 +520,15 @@ int32_t desktop_srv(void* p) {
|
||||
|
||||
Desktop* desktop = desktop_alloc();
|
||||
|
||||
bool loaded = DESKTOP_SETTINGS_LOAD(&desktop->settings);
|
||||
if(!loaded) {
|
||||
memset(&desktop->settings, 0, sizeof(desktop->settings));
|
||||
DESKTOP_SETTINGS_SAVE(&desktop->settings);
|
||||
}
|
||||
|
||||
view_port_enabled_set(desktop->dummy_mode_icon_viewport, desktop->settings.dummy_mode);
|
||||
|
||||
desktop_clock_reconfigure(desktop);
|
||||
|
||||
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);
|
||||
desktop_init_settings(desktop);
|
||||
|
||||
scene_manager_next_scene(desktop->scene_manager, DesktopSceneMain);
|
||||
|
||||
if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagLock)) {
|
||||
desktop_lock(desktop);
|
||||
} 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);
|
||||
}
|
||||
|
||||
@@ -496,14 +552,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;
|
||||
}
|
||||
|
||||
@@ -2,16 +2,22 @@
|
||||
|
||||
#include <furi.h>
|
||||
|
||||
typedef struct Desktop Desktop;
|
||||
#include "desktop_settings.h"
|
||||
|
||||
#define RECORD_DESKTOP "desktop"
|
||||
|
||||
bool desktop_api_is_locked(Desktop* instance);
|
||||
|
||||
void desktop_api_unlock(Desktop* instance);
|
||||
typedef struct Desktop Desktop;
|
||||
|
||||
typedef struct {
|
||||
bool locked;
|
||||
} DesktopStatus;
|
||||
|
||||
bool desktop_api_is_locked(Desktop* instance);
|
||||
|
||||
void desktop_api_unlock(Desktop* instance);
|
||||
|
||||
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);
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "desktop.h"
|
||||
#include "desktop_settings.h"
|
||||
|
||||
#include "animations/animation_manager.h"
|
||||
#include "views/desktop_view_pin_timeout.h"
|
||||
#include "views/desktop_view_pin_input.h"
|
||||
@@ -9,9 +11,7 @@
|
||||
#include "views/desktop_view_lock_menu.h"
|
||||
#include "views/desktop_view_debug.h"
|
||||
#include "views/desktop_view_slideshow.h"
|
||||
#include <desktop/desktop_settings.h>
|
||||
|
||||
#include <furi.h>
|
||||
#include <gui/gui.h>
|
||||
#include <gui/view_stack.h>
|
||||
#include <gui/view_dispatcher.h>
|
||||
@@ -42,9 +42,8 @@ typedef struct {
|
||||
} DesktopClock;
|
||||
|
||||
struct Desktop {
|
||||
// Scene
|
||||
FuriThread* scene_thread;
|
||||
// GUI
|
||||
|
||||
Gui* gui;
|
||||
ViewDispatcher* view_dispatcher;
|
||||
SceneManager* scene_manager;
|
||||
@@ -56,42 +55,38 @@ struct Desktop {
|
||||
DesktopMainView* main_view;
|
||||
DesktopViewPinTimeout* pin_timeout_view;
|
||||
DesktopSlideshowView* slideshow_view;
|
||||
DesktopViewPinInput* pin_input_view;
|
||||
|
||||
ViewStack* main_view_stack;
|
||||
ViewStack* locked_view_stack;
|
||||
|
||||
DesktopSettings settings;
|
||||
DesktopViewPinInput* pin_input_view;
|
||||
|
||||
ViewPort* lock_icon_viewport;
|
||||
ViewPort* dummy_mode_icon_viewport;
|
||||
ViewPort* clock_viewport;
|
||||
ViewPort* stealth_mode_icon_viewport;
|
||||
|
||||
AnimationManager* animation_manager;
|
||||
|
||||
Loader* loader;
|
||||
Storage* storage;
|
||||
NotificationApp* notification;
|
||||
|
||||
FuriPubSubSubscription* app_start_stop_subscription;
|
||||
FuriPubSub* status_pubsub;
|
||||
FuriPubSub* input_events_pubsub;
|
||||
FuriPubSubSubscription* input_events_subscription;
|
||||
|
||||
FuriTimer* auto_lock_timer;
|
||||
FuriTimer* update_clock_timer;
|
||||
|
||||
FuriPubSub* status_pubsub;
|
||||
AnimationManager* animation_manager;
|
||||
FuriSemaphore* animation_semaphore;
|
||||
|
||||
DesktopClock clock;
|
||||
DesktopSettings settings;
|
||||
|
||||
bool in_transition : 1;
|
||||
bool locked : 1;
|
||||
|
||||
FuriSemaphore* animation_semaphore;
|
||||
bool in_transition;
|
||||
bool app_running;
|
||||
bool locked;
|
||||
};
|
||||
|
||||
Desktop* desktop_alloc(void);
|
||||
|
||||
void desktop_free(Desktop* desktop);
|
||||
void desktop_lock(Desktop* desktop);
|
||||
void desktop_unlock(Desktop* desktop);
|
||||
void desktop_set_dummy_mode_state(Desktop* desktop, bool enabled);
|
||||
|
||||
79
applications/services/desktop/desktop_settings.c
Normal file
79
applications/services/desktop/desktop_settings.c
Normal file
@@ -0,0 +1,79 @@
|
||||
#include "desktop_settings.h"
|
||||
#include "desktop_settings_filename.h"
|
||||
|
||||
#include <saved_struct.h>
|
||||
#include <storage/storage.h>
|
||||
|
||||
#define TAG "DesktopSettings"
|
||||
|
||||
#define DESKTOP_SETTINGS_VER_10 (10)
|
||||
#define DESKTOP_SETTINGS_VER (11)
|
||||
|
||||
#define DESKTOP_SETTINGS_PATH INT_PATH(DESKTOP_SETTINGS_FILE_NAME)
|
||||
#define DESKTOP_SETTINGS_MAGIC (0x17)
|
||||
|
||||
typedef struct {
|
||||
uint8_t reserved[11];
|
||||
DesktopSettings settings;
|
||||
} DesktopSettingsV10;
|
||||
|
||||
// Actual size of DesktopSettings v10
|
||||
static_assert(sizeof(DesktopSettingsV10) == 1044);
|
||||
|
||||
void desktop_settings_load(DesktopSettings* settings) {
|
||||
furi_assert(settings);
|
||||
|
||||
bool success = false;
|
||||
|
||||
do {
|
||||
uint8_t version;
|
||||
if(!saved_struct_get_metadata(DESKTOP_SETTINGS_PATH, NULL, &version, NULL)) break;
|
||||
|
||||
if(version == DESKTOP_SETTINGS_VER) {
|
||||
success = saved_struct_load(
|
||||
DESKTOP_SETTINGS_PATH,
|
||||
settings,
|
||||
sizeof(DesktopSettings),
|
||||
DESKTOP_SETTINGS_MAGIC,
|
||||
DESKTOP_SETTINGS_VER);
|
||||
|
||||
} else if(version == DESKTOP_SETTINGS_VER_10) {
|
||||
DesktopSettingsV10* settings_v10 = malloc(sizeof(DesktopSettingsV10));
|
||||
|
||||
success = saved_struct_load(
|
||||
DESKTOP_SETTINGS_PATH,
|
||||
settings_v10,
|
||||
sizeof(DesktopSettingsV10),
|
||||
DESKTOP_SETTINGS_MAGIC,
|
||||
DESKTOP_SETTINGS_VER_10);
|
||||
|
||||
if(success) {
|
||||
*settings = settings_v10->settings;
|
||||
}
|
||||
|
||||
free(settings_v10);
|
||||
}
|
||||
|
||||
} while(false);
|
||||
|
||||
if(!success) {
|
||||
FURI_LOG_W(TAG, "Failed to load file, using defaults");
|
||||
memset(settings, 0, sizeof(DesktopSettings));
|
||||
desktop_settings_save(settings);
|
||||
}
|
||||
}
|
||||
|
||||
void desktop_settings_save(const DesktopSettings* settings) {
|
||||
furi_assert(settings);
|
||||
|
||||
const bool success = saved_struct_save(
|
||||
DESKTOP_SETTINGS_PATH,
|
||||
settings,
|
||||
sizeof(DesktopSettings),
|
||||
DESKTOP_SETTINGS_MAGIC,
|
||||
DESKTOP_SETTINGS_VER);
|
||||
|
||||
if(!success) {
|
||||
FURI_LOG_E(TAG, "Failed to save file");
|
||||
}
|
||||
}
|
||||
@@ -1,43 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "desktop_settings_filename.h"
|
||||
|
||||
#include <furi_hal.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <toolbox/saved_struct.h>
|
||||
#include <storage/storage.h>
|
||||
|
||||
#define DESKTOP_SETTINGS_VER (10)
|
||||
|
||||
#define DESKTOP_SETTINGS_PATH INT_PATH(DESKTOP_SETTINGS_FILE_NAME)
|
||||
#define DESKTOP_SETTINGS_MAGIC (0x17)
|
||||
#define PIN_MAX_LENGTH 12
|
||||
|
||||
#define DESKTOP_SETTINGS_RUN_PIN_SETUP_ARG "run_pin_setup"
|
||||
|
||||
#define DESKTOP_SETTINGS_SAVE(x) \
|
||||
saved_struct_save( \
|
||||
DESKTOP_SETTINGS_PATH, \
|
||||
(x), \
|
||||
sizeof(DesktopSettings), \
|
||||
DESKTOP_SETTINGS_MAGIC, \
|
||||
DESKTOP_SETTINGS_VER)
|
||||
|
||||
#define DESKTOP_SETTINGS_LOAD(x) \
|
||||
saved_struct_load( \
|
||||
DESKTOP_SETTINGS_PATH, \
|
||||
(x), \
|
||||
sizeof(DesktopSettings), \
|
||||
DESKTOP_SETTINGS_MAGIC, \
|
||||
DESKTOP_SETTINGS_VER)
|
||||
|
||||
#define MAX_PIN_SIZE 10
|
||||
#define MIN_PIN_SIZE 4
|
||||
#define MAX_APP_LENGTH 128
|
||||
|
||||
typedef enum {
|
||||
FavoriteAppLeftShort = 0,
|
||||
FavoriteAppLeftShort,
|
||||
FavoriteAppLeftLong,
|
||||
FavoriteAppRightShort,
|
||||
FavoriteAppRightLong,
|
||||
@@ -45,7 +11,7 @@ typedef enum {
|
||||
} FavoriteAppShortcut;
|
||||
|
||||
typedef enum {
|
||||
DummyAppLeft = 0,
|
||||
DummyAppLeft,
|
||||
DummyAppRight,
|
||||
DummyAppDown,
|
||||
DummyAppOk,
|
||||
@@ -53,19 +19,16 @@ typedef enum {
|
||||
} DummyAppShortcut;
|
||||
|
||||
typedef struct {
|
||||
InputKey data[MAX_PIN_SIZE];
|
||||
uint8_t length;
|
||||
} PinCode;
|
||||
|
||||
typedef struct {
|
||||
char name_or_path[MAX_APP_LENGTH];
|
||||
char name_or_path[128];
|
||||
} FavoriteApp;
|
||||
|
||||
typedef struct {
|
||||
PinCode pin_code;
|
||||
uint32_t auto_lock_delay_ms;
|
||||
uint8_t dummy_mode;
|
||||
uint8_t display_clock;
|
||||
FavoriteApp favorite_apps[FavoriteAppNumber];
|
||||
FavoriteApp dummy_apps[DummyAppNumber];
|
||||
} DesktopSettings;
|
||||
|
||||
void desktop_settings_load(DesktopSettings* settings);
|
||||
void desktop_settings_save(const DesktopSettings* settings);
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
#include "pin.h"
|
||||
|
||||
#include <notification/notification.h>
|
||||
#include <notification/notification_messages.h>
|
||||
#include <stddef.h>
|
||||
#include <furi.h>
|
||||
#include <furi_hal.h>
|
||||
#include <gui/gui.h>
|
||||
|
||||
static const NotificationSequence sequence_pin_fail = {
|
||||
&message_display_backlight_on,
|
||||
|
||||
&message_red_255,
|
||||
&message_vibro_on,
|
||||
&message_delay_100,
|
||||
&message_vibro_off,
|
||||
&message_red_0,
|
||||
|
||||
&message_delay_250,
|
||||
|
||||
&message_red_255,
|
||||
&message_vibro_on,
|
||||
&message_delay_100,
|
||||
&message_vibro_off,
|
||||
&message_red_0,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static const uint8_t desktop_helpers_fails_timeout[] = {
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
30,
|
||||
60,
|
||||
90,
|
||||
120,
|
||||
150,
|
||||
180,
|
||||
/* +60 for every next fail */
|
||||
};
|
||||
|
||||
void desktop_pin_lock_error_notify(void) {
|
||||
NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION);
|
||||
notification_message(notification, &sequence_pin_fail);
|
||||
furi_record_close(RECORD_NOTIFICATION);
|
||||
}
|
||||
|
||||
uint32_t desktop_pin_lock_get_fail_timeout(void) {
|
||||
uint32_t pin_fails = furi_hal_rtc_get_pin_fails();
|
||||
uint32_t pin_timeout = 0;
|
||||
uint32_t max_index = COUNT_OF(desktop_helpers_fails_timeout) - 1;
|
||||
if(pin_fails <= max_index) {
|
||||
pin_timeout = desktop_helpers_fails_timeout[pin_fails];
|
||||
} else {
|
||||
pin_timeout = desktop_helpers_fails_timeout[max_index] + (pin_fails - max_index) * 60;
|
||||
}
|
||||
|
||||
return pin_timeout;
|
||||
}
|
||||
|
||||
bool desktop_pin_compare(const PinCode* pin_code1, const PinCode* pin_code2) {
|
||||
furi_assert(pin_code1);
|
||||
furi_assert(pin_code2);
|
||||
bool result = false;
|
||||
|
||||
if(pin_code1->length == pin_code2->length) {
|
||||
result = !memcmp(pin_code1->data, pin_code2->data, pin_code1->length);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
#pragma once
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "../desktop.h"
|
||||
#include <desktop/desktop_settings.h>
|
||||
|
||||
void desktop_pin_lock_error_notify(void);
|
||||
|
||||
uint32_t desktop_pin_lock_get_fail_timeout(void);
|
||||
|
||||
bool desktop_pin_compare(const PinCode* pin_code1, const PinCode* pin_code2);
|
||||
103
applications/services/desktop/helpers/pin_code.c
Normal file
103
applications/services/desktop/helpers/pin_code.c
Normal file
@@ -0,0 +1,103 @@
|
||||
#include "pin_code.h"
|
||||
|
||||
#include <furi_hal_rtc.h>
|
||||
|
||||
#include <furi.h>
|
||||
#include <notification/notification_messages.h>
|
||||
|
||||
#define DESKTOP_PIN_CODE_DIGIT_BIT_WIDTH (2)
|
||||
#define DESKTOP_PIN_CODE_LENGTH_OFFSET (28)
|
||||
|
||||
static const NotificationSequence sequence_pin_fail = {
|
||||
&message_display_backlight_on,
|
||||
|
||||
&message_red_255,
|
||||
&message_vibro_on,
|
||||
&message_delay_100,
|
||||
&message_vibro_off,
|
||||
&message_red_0,
|
||||
|
||||
&message_delay_250,
|
||||
|
||||
&message_red_255,
|
||||
&message_vibro_on,
|
||||
&message_delay_100,
|
||||
&message_vibro_off,
|
||||
&message_red_0,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static const uint8_t desktop_helpers_fails_timeout[] = {
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
30,
|
||||
60,
|
||||
90,
|
||||
120,
|
||||
150,
|
||||
180,
|
||||
/* +60 for every next fail */
|
||||
};
|
||||
|
||||
static uint32_t desktop_pin_code_pack(const DesktopPinCode* pin_code) {
|
||||
furi_check(pin_code);
|
||||
furi_check(pin_code->length <= sizeof(pin_code->data));
|
||||
|
||||
uint32_t reg_value = 0;
|
||||
|
||||
for(uint8_t i = 0; i < pin_code->length; ++i) {
|
||||
furi_check(pin_code->data[i] < (1 << DESKTOP_PIN_CODE_DIGIT_BIT_WIDTH));
|
||||
reg_value |= (uint32_t)pin_code->data[i] << (i * DESKTOP_PIN_CODE_DIGIT_BIT_WIDTH);
|
||||
}
|
||||
|
||||
reg_value |= (uint32_t)pin_code->length << DESKTOP_PIN_CODE_LENGTH_OFFSET;
|
||||
|
||||
return reg_value;
|
||||
}
|
||||
|
||||
bool desktop_pin_code_is_set(void) {
|
||||
return furi_hal_rtc_get_pin_value() >> DESKTOP_PIN_CODE_LENGTH_OFFSET;
|
||||
}
|
||||
|
||||
void desktop_pin_code_set(const DesktopPinCode* pin_code) {
|
||||
furi_hal_rtc_set_pin_value(desktop_pin_code_pack(pin_code));
|
||||
}
|
||||
|
||||
void desktop_pin_code_reset(void) {
|
||||
furi_hal_rtc_set_pin_value(0);
|
||||
}
|
||||
|
||||
bool desktop_pin_code_check(const DesktopPinCode* pin_code) {
|
||||
return furi_hal_rtc_get_pin_value() == desktop_pin_code_pack(pin_code);
|
||||
}
|
||||
|
||||
bool desktop_pin_code_is_equal(const DesktopPinCode* pin_code1, const DesktopPinCode* pin_code2) {
|
||||
furi_check(pin_code1);
|
||||
furi_check(pin_code1->length <= sizeof(pin_code1->data));
|
||||
furi_check(pin_code2);
|
||||
furi_check(pin_code2->length <= sizeof(pin_code2->data));
|
||||
|
||||
return pin_code1->length == pin_code2->length &&
|
||||
memcmp(pin_code1->data, pin_code2->data, pin_code1->length) == 0;
|
||||
}
|
||||
|
||||
void desktop_pin_lock_error_notify(void) {
|
||||
NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION);
|
||||
notification_message(notification, &sequence_pin_fail);
|
||||
furi_record_close(RECORD_NOTIFICATION);
|
||||
}
|
||||
|
||||
uint32_t desktop_pin_lock_get_fail_timeout(void) {
|
||||
uint32_t pin_fails = furi_hal_rtc_get_pin_fails();
|
||||
uint32_t pin_timeout = 0;
|
||||
uint32_t max_index = COUNT_OF(desktop_helpers_fails_timeout) - 1;
|
||||
if(pin_fails <= max_index) {
|
||||
pin_timeout = desktop_helpers_fails_timeout[pin_fails];
|
||||
} else {
|
||||
pin_timeout = desktop_helpers_fails_timeout[max_index] + (pin_fails - max_index) * 60;
|
||||
}
|
||||
|
||||
return pin_timeout;
|
||||
}
|
||||
25
applications/services/desktop/helpers/pin_code.h
Normal file
25
applications/services/desktop/helpers/pin_code.h
Normal file
@@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define DESKTOP_PIN_CODE_MAX_LEN (10)
|
||||
|
||||
typedef struct {
|
||||
uint8_t data[DESKTOP_PIN_CODE_MAX_LEN];
|
||||
uint8_t length;
|
||||
} DesktopPinCode;
|
||||
|
||||
bool desktop_pin_code_is_set(void);
|
||||
|
||||
void desktop_pin_code_set(const DesktopPinCode* pin_code);
|
||||
|
||||
void desktop_pin_code_reset(void);
|
||||
|
||||
bool desktop_pin_code_check(const DesktopPinCode* pin_code);
|
||||
|
||||
bool desktop_pin_code_is_equal(const DesktopPinCode* pin_code1, const DesktopPinCode* pin_code2);
|
||||
|
||||
void desktop_pin_lock_error_notify(void);
|
||||
|
||||
uint32_t desktop_pin_lock_get_fail_timeout(void);
|
||||
@@ -1,4 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#define SCENE_LOCKED_FIRST_ENTER 0
|
||||
#define SCENE_LOCKED_REPEAT_ENTER 1
|
||||
@@ -20,7 +20,6 @@ void desktop_scene_lock_menu_callback(DesktopEvent event, void* context) {
|
||||
void desktop_scene_lock_menu_on_enter(void* context) {
|
||||
Desktop* desktop = (Desktop*)context;
|
||||
|
||||
DESKTOP_SETTINGS_LOAD(&desktop->settings);
|
||||
scene_manager_set_scene_state(desktop->scene_manager, DesktopSceneLockMenu, 0);
|
||||
desktop_lock_menu_set_callback(desktop->lock_menu, desktop_scene_lock_menu_callback, desktop);
|
||||
desktop_lock_menu_set_dummy_mode_state(desktop->lock_menu, desktop->settings.dummy_mode);
|
||||
@@ -38,11 +37,8 @@ bool desktop_scene_lock_menu_on_event(void* context, SceneManagerEvent event) {
|
||||
if(event.type == SceneManagerEventTypeTick) {
|
||||
bool check_pin_changed =
|
||||
scene_manager_get_scene_state(desktop->scene_manager, DesktopSceneLockMenu);
|
||||
if(check_pin_changed) {
|
||||
DESKTOP_SETTINGS_LOAD(&desktop->settings);
|
||||
if(desktop->settings.pin_code.length > 0) {
|
||||
scene_manager_set_scene_state(desktop->scene_manager, DesktopSceneLockMenu, 0);
|
||||
}
|
||||
if(check_pin_changed && desktop_pin_code_is_set()) {
|
||||
scene_manager_set_scene_state(desktop->scene_manager, DesktopSceneLockMenu, 0);
|
||||
}
|
||||
} else if(event.type == SceneManagerEventTypeCustom) {
|
||||
switch(event.event) {
|
||||
|
||||
@@ -6,12 +6,12 @@
|
||||
|
||||
#include "../desktop.h"
|
||||
#include "../desktop_i.h"
|
||||
#include "../helpers/pin.h"
|
||||
#include "../helpers/pin_code.h"
|
||||
#include "../animations/animation_manager.h"
|
||||
#include "../views/desktop_events.h"
|
||||
#include "../views/desktop_view_locked.h"
|
||||
#include "desktop_scene.h"
|
||||
#include "desktop_scene_i.h"
|
||||
#include "desktop_scene_locked.h"
|
||||
|
||||
#define WRONG_PIN_HEADER_TIMEOUT 3000
|
||||
#define INPUT_PIN_VIEW_TIMEOUT 15000
|
||||
@@ -42,15 +42,13 @@ void desktop_scene_locked_on_enter(void* context) {
|
||||
|
||||
bool switch_to_timeout_scene = false;
|
||||
uint32_t state = scene_manager_get_scene_state(desktop->scene_manager, DesktopSceneLocked);
|
||||
if(state == SCENE_LOCKED_FIRST_ENTER) {
|
||||
bool pin_locked = desktop->settings.pin_code.length > 0;
|
||||
if(state == DesktopSceneLockedStateFirstEnter) {
|
||||
view_port_enabled_set(desktop->lock_icon_viewport, true);
|
||||
Gui* gui = furi_record_open(RECORD_GUI);
|
||||
gui_set_lockdown(gui, true);
|
||||
furi_record_close(RECORD_GUI);
|
||||
|
||||
if(pin_locked) {
|
||||
DESKTOP_SETTINGS_LOAD(&desktop->settings);
|
||||
if(desktop_pin_code_is_set()) {
|
||||
desktop_view_locked_lock(desktop->locked_view, true);
|
||||
uint32_t pin_timeout = desktop_pin_lock_get_fail_timeout();
|
||||
if(pin_timeout > 0) {
|
||||
@@ -65,7 +63,7 @@ void desktop_scene_locked_on_enter(void* context) {
|
||||
desktop_view_locked_close_doors(desktop->locked_view);
|
||||
}
|
||||
scene_manager_set_scene_state(
|
||||
desktop->scene_manager, DesktopSceneLocked, SCENE_LOCKED_REPEAT_ENTER);
|
||||
desktop->scene_manager, DesktopSceneLocked, DesktopSceneLockedStateRepeatEnter);
|
||||
}
|
||||
|
||||
if(switch_to_timeout_scene) {
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
typedef enum {
|
||||
DesktopSceneLockedStateFirstEnter,
|
||||
DesktopSceneLockedStateRepeatEnter,
|
||||
} DesktopSceneLockedState;
|
||||
@@ -141,25 +141,21 @@ bool desktop_scene_main_on_event(void* context, SceneManagerEvent event) {
|
||||
}
|
||||
|
||||
case DesktopMainEventOpenFavoriteLeftShort:
|
||||
DESKTOP_SETTINGS_LOAD(&desktop->settings);
|
||||
desktop_scene_main_start_favorite(
|
||||
desktop, &desktop->settings.favorite_apps[FavoriteAppLeftShort]);
|
||||
consumed = true;
|
||||
break;
|
||||
case DesktopMainEventOpenFavoriteLeftLong:
|
||||
DESKTOP_SETTINGS_LOAD(&desktop->settings);
|
||||
desktop_scene_main_start_favorite(
|
||||
desktop, &desktop->settings.favorite_apps[FavoriteAppLeftLong]);
|
||||
consumed = true;
|
||||
break;
|
||||
case DesktopMainEventOpenFavoriteRightShort:
|
||||
DESKTOP_SETTINGS_LOAD(&desktop->settings);
|
||||
desktop_scene_main_start_favorite(
|
||||
desktop, &desktop->settings.favorite_apps[FavoriteAppRightShort]);
|
||||
consumed = true;
|
||||
break;
|
||||
case DesktopMainEventOpenFavoriteRightLong:
|
||||
DESKTOP_SETTINGS_LOAD(&desktop->settings);
|
||||
desktop_scene_main_start_favorite(
|
||||
desktop, &desktop->settings.favorite_apps[FavoriteAppRightLong]);
|
||||
consumed = true;
|
||||
@@ -175,7 +171,6 @@ bool desktop_scene_main_on_event(void* context, SceneManagerEvent event) {
|
||||
break;
|
||||
case DesktopAnimationEventInteractAnimation:
|
||||
if(!animation_manager_interact_process(desktop->animation_manager)) {
|
||||
DESKTOP_SETTINGS_LOAD(&desktop->settings);
|
||||
if(!desktop->settings.dummy_mode) {
|
||||
desktop_scene_main_open_app_or_profile(
|
||||
desktop, &desktop->settings.favorite_apps[FavoriteAppRightShort]);
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#include "../desktop_i.h"
|
||||
#include "../views/desktop_events.h"
|
||||
#include "../views/desktop_view_pin_input.h"
|
||||
#include "../helpers/pin.h"
|
||||
#include "../helpers/pin_code.h"
|
||||
#include "desktop_scene.h"
|
||||
|
||||
#define WRONG_PIN_HEADER_TIMEOUT 3000
|
||||
@@ -49,10 +49,12 @@ static void desktop_scene_pin_input_back_callback(void* context) {
|
||||
view_dispatcher_send_custom_event(desktop->view_dispatcher, DesktopPinInputEventBack);
|
||||
}
|
||||
|
||||
static void desktop_scene_pin_input_done_callback(const PinCode* pin_code, void* context) {
|
||||
static void desktop_scene_pin_input_done_callback(const DesktopPinCode* pin_code, void* context) {
|
||||
Desktop* desktop = (Desktop*)context;
|
||||
if(desktop_pin_compare(&desktop->settings.pin_code, pin_code)) {
|
||||
|
||||
if(desktop_pin_code_check(pin_code)) {
|
||||
view_dispatcher_send_custom_event(desktop->view_dispatcher, DesktopPinInputEventUnlocked);
|
||||
|
||||
} else {
|
||||
uint32_t pin_fails = furi_hal_rtc_get_pin_fails();
|
||||
furi_hal_rtc_set_pin_fails(pin_fails + 1);
|
||||
|
||||
@@ -45,9 +45,6 @@ bool desktop_scene_slideshow_on_event(void* context, SceneManagerEvent event) {
|
||||
}
|
||||
|
||||
void desktop_scene_slideshow_on_exit(void* context) {
|
||||
UNUSED(context);
|
||||
|
||||
Storage* storage = furi_record_open(RECORD_STORAGE);
|
||||
storage_common_remove(storage, SLIDESHOW_FS_PATH);
|
||||
furi_record_close(RECORD_STORAGE);
|
||||
Desktop* desktop = context;
|
||||
storage_common_remove(desktop->storage, SLIDESHOW_FS_PATH);
|
||||
}
|
||||
|
||||
@@ -55,4 +55,6 @@ typedef enum {
|
||||
DesktopGlobalAfterAppFinished,
|
||||
DesktopGlobalAutoLock,
|
||||
DesktopGlobalApiUnlock,
|
||||
DesktopGlobalSaveSettings,
|
||||
DesktopGlobalReloadSettings,
|
||||
} DesktopEvent;
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "desktop_view_pin_input.h"
|
||||
#include <desktop/desktop_settings.h>
|
||||
|
||||
#define NO_ACTIVITY_TIMEOUT 15000
|
||||
|
||||
@@ -14,6 +13,9 @@
|
||||
#define DEFAULT_PIN_X 64
|
||||
#define DEFAULT_PIN_Y 32
|
||||
|
||||
#define MIN_PIN_LENGTH 4
|
||||
#define MAX_PIN_LENGTH DESKTOP_PIN_CODE_MAX_LEN
|
||||
|
||||
struct DesktopViewPinInput {
|
||||
View* view;
|
||||
DesktopViewPinInputCallback back_callback;
|
||||
@@ -24,7 +26,7 @@ struct DesktopViewPinInput {
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
PinCode pin;
|
||||
DesktopPinCode pin;
|
||||
bool pin_hidden;
|
||||
bool locked_input;
|
||||
uint8_t pin_x;
|
||||
@@ -50,7 +52,7 @@ static bool desktop_view_pin_input_input(InputEvent* event, void* context) {
|
||||
|
||||
bool call_back_callback = false;
|
||||
bool call_done_callback = false;
|
||||
PinCode pin_code = {0};
|
||||
DesktopPinCode pin_code = {0};
|
||||
|
||||
if(event->type == InputTypeShort) {
|
||||
switch(event->key) {
|
||||
@@ -59,13 +61,13 @@ static bool desktop_view_pin_input_input(InputEvent* event, void* context) {
|
||||
case InputKeyDown:
|
||||
case InputKeyUp:
|
||||
if(!model->locked_input) {
|
||||
if(model->pin.length < MAX_PIN_SIZE) {
|
||||
if(model->pin.length < MAX_PIN_LENGTH) {
|
||||
model->pin.data[model->pin.length++] = event->key;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case InputKeyOk:
|
||||
if(model->pin.length >= MIN_PIN_SIZE) {
|
||||
if(model->pin.length >= MIN_PIN_LENGTH) {
|
||||
call_done_callback = true;
|
||||
pin_code = model->pin;
|
||||
}
|
||||
@@ -102,7 +104,7 @@ static void desktop_view_pin_input_draw_cells(Canvas* canvas, DesktopViewPinInpu
|
||||
furi_assert(model);
|
||||
|
||||
uint8_t draw_pin_size = MAX(4, model->pin.length + 1);
|
||||
if(model->locked_input || (model->pin.length == MAX_PIN_SIZE)) {
|
||||
if(model->locked_input || (model->pin.length == MAX_PIN_LENGTH)) {
|
||||
draw_pin_size = model->pin.length;
|
||||
}
|
||||
|
||||
@@ -155,7 +157,7 @@ static void desktop_view_pin_input_draw(Canvas* canvas, void* context) {
|
||||
canvas_draw_str(canvas, 16, 60, "= clear");
|
||||
}
|
||||
|
||||
if(model->button_label && ((model->pin.length >= MIN_PIN_SIZE) || model->locked_input)) {
|
||||
if(model->button_label && ((model->pin.length >= MIN_PIN_LENGTH) || model->locked_input)) {
|
||||
elements_button_center(canvas, model->button_label);
|
||||
}
|
||||
|
||||
@@ -247,7 +249,7 @@ void desktop_view_pin_input_unlock_input(DesktopViewPinInput* pin_input) {
|
||||
view_commit_model(pin_input->view, true);
|
||||
}
|
||||
|
||||
void desktop_view_pin_input_set_pin(DesktopViewPinInput* pin_input, const PinCode* pin) {
|
||||
void desktop_view_pin_input_set_pin(DesktopViewPinInput* pin_input, const DesktopPinCode* pin) {
|
||||
furi_assert(pin_input);
|
||||
furi_assert(pin);
|
||||
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include <gui/view.h>
|
||||
#include <desktop/desktop_settings.h>
|
||||
|
||||
#include "../helpers/pin_code.h"
|
||||
|
||||
typedef void (*DesktopViewPinInputCallback)(void*);
|
||||
typedef void (*DesktopViewPinInputDoneCallback)(const PinCode* pin_code, void*);
|
||||
typedef void (*DesktopViewPinInputDoneCallback)(const DesktopPinCode* pin_code, void*);
|
||||
typedef struct DesktopViewPinInput DesktopViewPinInput;
|
||||
|
||||
DesktopViewPinInput* desktop_view_pin_input_alloc(void);
|
||||
void desktop_view_pin_input_free(DesktopViewPinInput*);
|
||||
|
||||
void desktop_view_pin_input_set_pin(DesktopViewPinInput* pin_input, const PinCode* pin);
|
||||
void desktop_view_pin_input_set_pin(DesktopViewPinInput* pin_input, const DesktopPinCode* pin_code);
|
||||
void desktop_view_pin_input_reset_pin(DesktopViewPinInput* pin_input);
|
||||
void desktop_view_pin_input_hide_pin(DesktopViewPinInput* pin_input, bool pin_hidden);
|
||||
void desktop_view_pin_input_set_label_button(DesktopViewPinInput* pin_input, const char* label);
|
||||
|
||||
Reference in New Issue
Block a user