Storage: Fallback SD format when app unavailable (#208) --nobuild

This commit is contained in:
Willy-JL
2024-09-06 23:02:51 +02:00
parent 5901fa4844
commit 263de09a5f
4 changed files with 133 additions and 1 deletions

View File

@@ -20,7 +20,8 @@
- RFID:
- OFW: Fix detection of GProx II cards and false detection of other cards (by @Astrrra)
- OFW: Fix Guard GProxII False Positive and 36-bit Parsing (by @zinongli)
- Desktop: Poweroff fallback when app unavailable (by @Willy-JL)
- Desktop: Fallback Poweroff prompt when power settings is unavailable (by @Willy-JL)
- Storage: Fallback SD format prompt when storage settings is unavailable (by @Willy-JL)
- Loader: Warn about missing SD card for main apps (by @Willy-JL)
- OFW: NFC: Fix crash on Ultralight unlock (by @Astrrra)
- OFW: RPC: Broken file interaction fixes (by @RebornedBrain)

View File

@@ -4,9 +4,11 @@
#include <gui/modules/submenu.h>
#include <assets_icons.h>
#include <applications.h>
#include <toolbox/run_parallel.h>
#include "loader.h"
#include "loader_menu.h"
#include "loader_menu_storage_i.h"
#include <flipper_application/flipper_application.h>
#include <toolbox/stream/file_stream.h>
@@ -171,6 +173,21 @@ static void loader_menu_applications_callback(void* context, uint32_t index) {
static void loader_menu_settings_menu_callback(void* context, uint32_t index) {
UNUSED(context);
const char* name = FLIPPER_SETTINGS_APPS[index].name;
// Workaround for SD format when app can't be opened
if(!strcmp(name, "Storage")) {
Storage* storage = furi_record_open(RECORD_STORAGE);
FS_Error status = storage_sd_status(storage);
furi_record_close(RECORD_STORAGE);
// If SD card not ready, cannot be formatted, so we want loader to give
// normal error message, with function below
if(status != FSE_NOT_READY) {
// Attempt to launch the app, and if failed offer to format SD card
run_parallel(loader_menu_storage_settings, storage, 512);
return;
}
}
loader_menu_start(name);
}

View File

@@ -0,0 +1,109 @@
#include "loader_menu_storage_i.h"
#include <core/thread.h>
#include <storage/storage.h>
#include <gui/modules/dialog_ex.h>
#include <gui/view_holder.h>
#include <assets_icons.h>
#include "loader.h"
typedef enum {
FormatFlagContinue = (1 << 0),
FormatFlagCancel = (1 << 1),
FormatFlagAll = (FormatFlagContinue | FormatFlagCancel),
} FormatFlag;
static void loader_menu_storage_settings_callback(DialogExResult result, void* context) {
FuriThread* thread = context;
furi_thread_flags_set(
furi_thread_get_id(thread),
result == DialogExResultRight ? FormatFlagContinue : FormatFlagCancel);
}
static void loader_menu_storage_settings_back(void* context) {
FuriThread* thread = context;
furi_thread_flags_set(furi_thread_get_id(thread), FormatFlagCancel);
}
int32_t loader_menu_storage_settings(void* context) {
Storage* storage = context;
Loader* loader = furi_record_open(RECORD_LOADER);
LoaderStatus result = loader_start(loader, "Storage", NULL, NULL);
furi_record_close(RECORD_LOADER);
if(result != LoaderStatusOk) {
DialogEx* dialog_ex = dialog_ex_alloc();
Gui* gui = furi_record_open(RECORD_GUI);
ViewHolder* view_holder = view_holder_alloc();
view_holder_attach_to_gui(view_holder, gui);
view_holder_set_view(view_holder, dialog_ex_get_view(dialog_ex));
dialog_ex_set_context(dialog_ex, furi_thread_get_current());
dialog_ex_set_result_callback(dialog_ex, loader_menu_storage_settings_callback);
view_holder_set_back_callback(
view_holder, loader_menu_storage_settings_back, furi_thread_get_current());
dialog_ex_set_header(dialog_ex, "Update needed", 64, 0, AlignCenter, AlignTop);
dialog_ex_set_text(
dialog_ex,
"Update firmware\n"
"to run this app\n"
"Can format SD\n"
"here if needed",
3,
17,
AlignLeft,
AlignTop);
dialog_ex_set_icon(dialog_ex, 83, 11, &I_WarningDolphinFlip_45x42);
dialog_ex_set_right_button_text(dialog_ex, "Format SD");
FormatFlag flag = furi_thread_flags_wait(FormatFlagAll, FuriFlagWaitAny, FuriWaitForever);
if(flag == FormatFlagContinue) {
char text[39];
dialog_ex_set_header(dialog_ex, "Format SD Card?", 64, 0, AlignCenter, AlignTop);
dialog_ex_set_icon(dialog_ex, 0, 0, NULL);
dialog_ex_set_left_button_text(dialog_ex, "Cancel");
dialog_ex_set_right_button_text(dialog_ex, "Format");
for(uint8_t counter = 5; counter > 0; counter--) {
snprintf(text, sizeof(text), "All data will be lost!\n%d presses left", counter);
dialog_ex_set_text(dialog_ex, text, 64, 12, AlignCenter, AlignTop);
flag = furi_thread_flags_wait(FormatFlagAll, FuriFlagWaitAny, FuriWaitForever);
if(flag != FormatFlagContinue) break;
if(counter == 1) {
dialog_ex_set_header(
dialog_ex, "Formatting...", 70, 32, AlignCenter, AlignCenter);
dialog_ex_set_text(dialog_ex, NULL, 0, 0, AlignCenter, AlignCenter);
dialog_ex_set_icon(dialog_ex, 15, 20, &I_LoadingHourglass_24x24);
dialog_ex_set_left_button_text(dialog_ex, NULL);
dialog_ex_set_right_button_text(dialog_ex, NULL);
FS_Error error = storage_sd_format(storage);
if(error != FSE_OK) {
dialog_ex_set_header(
dialog_ex, "Cannot Format SD Card", 64, 10, AlignCenter, AlignCenter);
dialog_ex_set_icon(dialog_ex, 0, 0, NULL);
dialog_ex_set_text(
dialog_ex,
storage_error_get_desc(error),
64,
32,
AlignCenter,
AlignCenter);
} else {
dialog_ex_set_icon(dialog_ex, 48, 6, &I_DolphinDone_80x58);
dialog_ex_set_header(dialog_ex, "Formatted", 5, 10, AlignLeft, AlignTop);
}
dialog_ex_set_left_button_text(dialog_ex, "Finish");
furi_thread_flags_wait(FormatFlagAll, FuriFlagWaitAny, FuriWaitForever);
}
}
}
view_holder_set_view(view_holder, NULL);
view_holder_free(view_holder);
furi_record_close(RECORD_GUI);
dialog_ex_free(dialog_ex);
}
return 0;
}

View File

@@ -0,0 +1,5 @@
#pragma once
#include <stdint.h>
int32_t loader_menu_storage_settings(void* context);