Migrate files and load MNTM settings on SD insert

I don't fully like how I made this work, bu I don't see a better way without restructuring a lot of things and losing behavior compatibility
This commit is contained in:
Willy-JL
2024-08-12 01:15:33 +02:00
parent e8ad079992
commit 8a6c499e1b
4 changed files with 91 additions and 18 deletions
+25
View File
@@ -56,6 +56,25 @@ Storage* storage_app_alloc(void) {
return app;
}
#ifndef FURI_RAM_EXEC
#include <furi/flipper.h>
#include <toolbox/run_parallel.h>
static int32_t sd_mount_handler(void* context) {
Storage* app = context;
StorageEvent event = {.type = StorageEventTypeCardMount};
// Needs to happen before other services load their settings
flipper_mount_callback(&event, NULL);
// Everything else
furi_pubsub_publish(app->pubsub, &event);
furi_record_close(RECORD_STORAGE);
return 0;
}
#endif
void storage_tick(Storage* app) {
for(uint8_t i = 0; i < STORAGE_COUNT; i++) {
StorageApi api = app->storage[i].api;
@@ -86,8 +105,14 @@ void storage_tick(Storage* app) {
if(app->storage[ST_EXT].status == StorageStatusOK) {
FURI_LOG_I(TAG, "SD card mount");
#ifndef FURI_RAM_EXEC
// Can't use pubsub for migration and can't lockup storage thread,
// see more explanation in flipper_mount_callback()
run_parallel(sd_mount_handler, app, 3 * 1024);
#else
StorageEvent event = {.type = StorageEventTypeCardMount};
furi_pubsub_publish(app->pubsub, &event);
#endif
} else {
FURI_LOG_I(TAG, "SD card mount error");
StorageEvent event = {.type = StorageEventTypeCardMountError};
+50 -18
View File
@@ -114,6 +114,34 @@ void flipper_migrate_files() {
furi_record_close(RECORD_STORAGE);
}
// Cannot use pubsub to schedule on SD insert like other services because
// we want migration to happen before others load settings and new pubsub
// subscriptions are put first in callback list so migration would be last
// Also we cannot block the pubsub by loading files as it means storage
// service is deadlocked processing pubsub and cannot process file operations
// So instead storage runs this function in background thread and then
// dispatches the pubsub event to everyone else
void flipper_mount_callback(const void* message, void* context) {
UNUSED(context);
const StorageEvent* event = message;
if(event->type == StorageEventTypeCardMount) {
// Migrate locations before other services load on SD insert
flipper_migrate_files();
// TODO: Need to restart services that already applied previous name
namespoof_init();
// TODO: If new SD doesn't contain all current settings IDs, values
// from previous SD are kept for these settings
momentum_settings_load();
// TODO: Could lock kernel on free to avoid GUI using assets while being free'd
asset_packs_free();
asset_packs_init();
}
}
#endif
void flipper_start_service(const FlipperInternalApplication* service) {
@@ -146,25 +174,29 @@ void flipper_init(void) {
#ifndef FURI_RAM_EXEC
if(furi_hal_is_normal_boot()) {
// Wait for storage record
furi_record_open(RECORD_STORAGE);
Storage* storage = furi_record_open(RECORD_STORAGE);
if(storage_sd_status(storage) != FSE_OK) {
FURI_LOG_D(TAG, "SD Card not ready, skipping early init");
// Init on SD insert done by storage using flipper_mount_callback()
} else {
canvas_draw_icon(canvas, 39, 43, &I_dir_10px);
canvas_commit(canvas);
flipper_migrate_files();
canvas_draw_icon(canvas, 59, 42, &I_Apps_10px);
canvas_commit(canvas);
namespoof_init();
canvas_draw_icon(canvas, 79, 44, &I_Rpc_active_7x8);
canvas_commit(canvas);
momentum_settings_load();
furi_hal_light_sequence("rgb RB");
canvas_draw_icon(canvas, 99, 44, &I_Hidden_window_9x8);
canvas_commit(canvas);
asset_packs_init();
}
furi_record_close(RECORD_STORAGE);
canvas_draw_icon(canvas, 39, 43, &I_dir_10px);
canvas_commit(canvas);
flipper_migrate_files();
canvas_draw_icon(canvas, 59, 42, &I_Apps_10px);
canvas_commit(canvas);
namespoof_init();
canvas_draw_icon(canvas, 79, 44, &I_Rpc_active_7x8);
canvas_commit(canvas);
momentum_settings_load();
furi_hal_light_sequence("rgb RB");
canvas_draw_icon(canvas, 99, 44, &I_Hidden_window_9x8);
canvas_commit(canvas);
asset_packs_init();
} else {
FURI_LOG_I(TAG, "Special boot, skipping optional components");
}
+4
View File
@@ -1,3 +1,7 @@
#pragma once
void flipper_init(void);
#ifndef FURI_RAM_EXEC
void flipper_mount_callback(const void* message, void* context);
#endif
+12
View File
@@ -10,6 +10,9 @@ void namespoof_init(void) {
Storage* storage = furi_record_open(RECORD_STORAGE);
FlipperFormat* file = flipper_format_file_alloc(storage);
const char* prev_custom_name = version_get_custom_name(NULL);
bool applied_new_name = false;
do {
uint32_t version;
if(!flipper_format_file_open_existing(file, NAMESPOOF_PATH)) break;
@@ -20,8 +23,17 @@ void namespoof_init(void) {
if(!flipper_format_read_string(file, "Name", str)) break;
version_set_custom_name(NULL, strdup(furi_string_get_cstr(str)));
furi_hal_version_set_name(NULL);
applied_new_name = true;
} while(false);
if(prev_custom_name) {
if(!applied_new_name) {
version_set_custom_name(NULL, NULL);
furi_hal_version_init();
}
free((void*)prev_custom_name);
}
flipper_format_free(file);
furi_record_close(RECORD_STORAGE);
furi_string_free(str);