mirror of
https://github.com/flipperdevices/flipperzero-firmware.git
synced 2025-12-12 04:41:26 +04: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 d61295ac06.
* 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:
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user