Storage: move factory reset to the place it belongs, add gui version. (#822)

This commit is contained in:
あく
2021-11-16 03:04:33 +03:00
committed by GitHub
parent 7f814b5197
commit 516a437305
17 changed files with 173 additions and 66 deletions

View File

@@ -0,0 +1,30 @@
#include "storage_settings_scene.h"
// Generate scene on_enter handlers array
#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter,
void (*const storage_settings_on_enter_handlers[])(void*) = {
#include "storage_settings_scene_config.h"
};
#undef ADD_SCENE
// Generate scene on_event handlers array
#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_event,
bool (*const storage_settings_on_event_handlers[])(void* context, SceneManagerEvent event) = {
#include "storage_settings_scene_config.h"
};
#undef ADD_SCENE
// Generate scene on_exit handlers array
#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_exit,
void (*const storage_settings_on_exit_handlers[])(void* context) = {
#include "storage_settings_scene_config.h"
};
#undef ADD_SCENE
// Initialize scene handlers configuration structure
const SceneManagerHandlers storage_settings_scene_handlers = {
.on_enter_handlers = storage_settings_on_enter_handlers,
.on_event_handlers = storage_settings_on_event_handlers,
.on_exit_handlers = storage_settings_on_exit_handlers,
.scene_num = StorageSettingsSceneNum,
};

View File

@@ -0,0 +1,29 @@
#pragma once
#include <gui/scene_manager.h>
// Generate scene id and total number
#define ADD_SCENE(prefix, name, id) StorageSettings##id,
typedef enum {
#include "storage_settings_scene_config.h"
StorageSettingsSceneNum,
} StorageSettingsScene;
#undef ADD_SCENE
extern const SceneManagerHandlers storage_settings_scene_handlers;
// Generate scene on_enter handlers declaration
#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void*);
#include "storage_settings_scene_config.h"
#undef ADD_SCENE
// Generate scene on_event handlers declaration
#define ADD_SCENE(prefix, name, id) \
bool prefix##_scene_##name##_on_event(void* context, SceneManagerEvent event);
#include "storage_settings_scene_config.h"
#undef ADD_SCENE
// Generate scene on_exit handlers declaration
#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_exit(void* context);
#include "storage_settings_scene_config.h"
#undef ADD_SCENE

View File

@@ -0,0 +1,163 @@
#include "../storage_settings.h"
#define BENCH_DATA_SIZE 4096
#define BENCH_COUNT 6
#define BENCH_REPEATS 4
#define BENCH_FILE "/ext/rwfiletest.bin"
static void
storage_settings_scene_benchmark_dialog_callback(DialogExResult result, void* context) {
StorageSettings* app = context;
view_dispatcher_send_custom_event(app->view_dispatcher, result);
}
static bool storage_settings_scene_bench_write(
Storage* api,
uint16_t size,
const uint8_t* data,
uint32_t* speed) {
File* file = storage_file_alloc(api);
bool result = true;
if(storage_file_open(file, BENCH_FILE, FSAM_WRITE, FSOM_CREATE_ALWAYS)) {
uint32_t ticks;
ticks = osKernelGetTickCount();
for(size_t repeat = 0; repeat < BENCH_REPEATS; repeat++) {
for(size_t i = 0; i < BENCH_DATA_SIZE / size; i++) {
if(storage_file_write(file, (data + i * size), size) != size) {
result = false;
break;
}
}
}
ticks = osKernelGetTickCount() - ticks;
*speed = BENCH_DATA_SIZE * osKernelGetTickFreq() * BENCH_REPEATS;
*speed /= ticks;
*speed /= 1024;
}
storage_file_close(file);
storage_file_free(file);
return result;
}
static bool
storage_settings_scene_bench_read(Storage* api, uint16_t size, uint8_t* data, uint32_t* speed) {
File* file = storage_file_alloc(api);
bool result = true;
*speed = -1;
if(storage_file_open(file, BENCH_FILE, FSAM_READ, FSOM_OPEN_EXISTING)) {
uint32_t ticks;
ticks = osKernelGetTickCount();
for(size_t repeat = 0; repeat < BENCH_REPEATS; repeat++) {
for(size_t i = 0; i < BENCH_DATA_SIZE / size; i++) {
if(storage_file_read(file, (data + i * size), size) != size) {
result = false;
break;
}
}
}
ticks = osKernelGetTickCount() - ticks;
*speed = BENCH_DATA_SIZE * osKernelGetTickFreq() * BENCH_REPEATS;
*speed /= ticks;
*speed /= 1024;
}
storage_file_close(file);
storage_file_free(file);
return result;
}
static void storage_settings_scene_benchmark(StorageSettings* app) {
DialogEx* dialog_ex = app->dialog_ex;
uint8_t* bench_data;
dialog_ex_set_header(dialog_ex, "Preparing data...", 64, 32, AlignCenter, AlignCenter);
bench_data = malloc(BENCH_DATA_SIZE);
for(size_t i = 0; i < BENCH_DATA_SIZE; i++) {
bench_data[i] = (uint8_t)i;
}
uint16_t bench_size[BENCH_COUNT] = {1, 8, 32, 256, 512, 1024};
uint32_t bench_w_speed[BENCH_COUNT] = {0, 0, 0, 0, 0, 0};
uint32_t bench_r_speed[BENCH_COUNT] = {0, 0, 0, 0, 0, 0};
dialog_ex_set_header(dialog_ex, "Benchmarking...", 64, 32, AlignCenter, AlignCenter);
for(size_t i = 0; i < BENCH_COUNT; i++) {
if(!storage_settings_scene_bench_write(
app->fs_api, bench_size[i], bench_data, &bench_w_speed[i]))
break;
if(i > 0) string_cat_printf(app->text_string, "\n");
string_cat_printf(app->text_string, "%ub : W %luK ", bench_size[i], bench_w_speed[i]);
dialog_ex_set_header(dialog_ex, NULL, 0, 0, AlignCenter, AlignCenter);
dialog_ex_set_text(
dialog_ex, string_get_cstr(app->text_string), 0, 32, AlignLeft, AlignCenter);
if(!storage_settings_scene_bench_read(
app->fs_api, bench_size[i], bench_data, &bench_r_speed[i]))
break;
string_cat_printf(app->text_string, "R %luK", bench_r_speed[i]);
dialog_ex_set_text(
dialog_ex, string_get_cstr(app->text_string), 0, 32, AlignLeft, AlignCenter);
}
free(bench_data);
}
void storage_settings_scene_benchmark_on_enter(void* context) {
StorageSettings* app = context;
DialogEx* dialog_ex = app->dialog_ex;
dialog_ex_set_context(dialog_ex, app);
dialog_ex_set_result_callback(dialog_ex, storage_settings_scene_benchmark_dialog_callback);
view_dispatcher_switch_to_view(app->view_dispatcher, StorageSettingsViewDialogEx);
if(storage_sd_status(app->fs_api) != FSE_OK) {
dialog_ex_set_header(dialog_ex, "SD card not mounted", 64, 10, AlignCenter, AlignCenter);
dialog_ex_set_text(
dialog_ex,
"If an SD card is inserted,\r\npull it out and reinsert it",
64,
32,
AlignCenter,
AlignCenter);
dialog_ex_set_left_button_text(dialog_ex, "Back");
} else {
storage_settings_scene_benchmark(app);
notification_message(app->notification, &sequence_blink_green_100);
}
}
bool storage_settings_scene_benchmark_on_event(void* context, SceneManagerEvent event) {
StorageSettings* app = context;
bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) {
switch(event.event) {
case DialogExResultLeft:
consumed = scene_manager_previous_scene(app->scene_manager);
break;
}
}
return consumed;
}
void storage_settings_scene_benchmark_on_exit(void* context) {
StorageSettings* app = context;
DialogEx* dialog_ex = app->dialog_ex;
dialog_ex_set_header(dialog_ex, NULL, 0, 0, AlignCenter, AlignCenter);
dialog_ex_set_text(dialog_ex, NULL, 0, 0, AlignCenter, AlignTop);
dialog_ex_set_icon(dialog_ex, 0, 0, NULL);
dialog_ex_set_left_button_text(dialog_ex, NULL);
dialog_ex_set_right_button_text(dialog_ex, NULL);
dialog_ex_set_result_callback(dialog_ex, NULL);
dialog_ex_set_context(dialog_ex, NULL);
string_reset(app->text_string);
}

View File

@@ -0,0 +1,9 @@
ADD_SCENE(storage_settings, start, Start)
ADD_SCENE(storage_settings, unmount_confirm, UnmountConfirm)
ADD_SCENE(storage_settings, unmounted, Unmounted)
ADD_SCENE(storage_settings, format_confirm, FormatConfirm)
ADD_SCENE(storage_settings, formatting, Formatting)
ADD_SCENE(storage_settings, sd_info, SDInfo)
ADD_SCENE(storage_settings, internal_info, InternalInfo)
ADD_SCENE(storage_settings, benchmark, Benchmark)
ADD_SCENE(storage_settings, factory_reset, FactoryReset)

View File

@@ -0,0 +1,68 @@
#include "../storage_settings.h"
static void
storage_settings_scene_unmount_confirm_dialog_callback(DialogExResult result, void* context) {
StorageSettings* app = context;
view_dispatcher_send_custom_event(app->view_dispatcher, result);
}
void storage_settings_scene_unmount_confirm_on_enter(void* context) {
StorageSettings* app = context;
FS_Error sd_status = storage_sd_status(app->fs_api);
DialogEx* dialog_ex = app->dialog_ex;
dialog_ex_set_left_button_text(dialog_ex, "Back");
if(sd_status == FSE_NOT_READY) {
dialog_ex_set_header(dialog_ex, "SD card not mounted", 64, 10, AlignCenter, AlignCenter);
dialog_ex_set_text(
dialog_ex,
"If an SD card is inserted,\r\npull it out and reinsert it",
64,
32,
AlignCenter,
AlignCenter);
} else {
dialog_ex_set_right_button_text(dialog_ex, "Unmount");
dialog_ex_set_header(dialog_ex, "Unmount SD card?", 64, 10, AlignCenter, AlignCenter);
dialog_ex_set_text(
dialog_ex, "SD card will be\nunavailable", 64, 32, AlignCenter, AlignCenter);
}
dialog_ex_set_context(dialog_ex, app);
dialog_ex_set_result_callback(
dialog_ex, storage_settings_scene_unmount_confirm_dialog_callback);
view_dispatcher_switch_to_view(app->view_dispatcher, StorageSettingsViewDialogEx);
}
bool storage_settings_scene_unmount_confirm_on_event(void* context, SceneManagerEvent event) {
StorageSettings* app = context;
bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) {
switch(event.event) {
case DialogExResultLeft:
consumed = scene_manager_previous_scene(app->scene_manager);
break;
case DialogExResultRight:
scene_manager_next_scene(app->scene_manager, StorageSettingsUnmounted);
consumed = true;
break;
}
}
return consumed;
}
void storage_settings_scene_unmount_confirm_on_exit(void* context) {
StorageSettings* app = context;
DialogEx* dialog_ex = app->dialog_ex;
dialog_ex_set_header(dialog_ex, NULL, 0, 0, AlignCenter, AlignCenter);
dialog_ex_set_text(dialog_ex, NULL, 0, 0, AlignCenter, AlignTop);
dialog_ex_set_icon(dialog_ex, 0, 0, NULL);
dialog_ex_set_left_button_text(dialog_ex, NULL);
dialog_ex_set_right_button_text(dialog_ex, NULL);
dialog_ex_set_result_callback(dialog_ex, NULL);
dialog_ex_set_context(dialog_ex, NULL);
}

View File

@@ -0,0 +1,66 @@
#include "../storage_settings.h"
static void
storage_settings_scene_unmounted_dialog_callback(DialogExResult result, void* context) {
StorageSettings* app = context;
view_dispatcher_send_custom_event(app->view_dispatcher, result);
}
void storage_settings_scene_unmounted_on_enter(void* context) {
StorageSettings* app = context;
FS_Error error = storage_sd_unmount(app->fs_api);
DialogEx* dialog_ex = app->dialog_ex;
dialog_ex_set_left_button_text(dialog_ex, "Back");
if(error == FSE_OK) {
dialog_ex_set_header(dialog_ex, "SD card unmounted", 64, 10, AlignCenter, AlignCenter);
dialog_ex_set_text(
dialog_ex, "Now the SD card\ncan be removed.", 64, 32, AlignCenter, AlignCenter);
notification_message(app->notification, &sequence_blink_green_100);
} else {
dialog_ex_set_header(
dialog_ex, "Cannot unmount SD Card", 64, 10, AlignCenter, AlignCenter);
dialog_ex_set_text(
dialog_ex, storage_error_get_desc(error), 64, 32, AlignCenter, AlignCenter);
notification_message(app->notification, &sequence_blink_red_100);
}
dialog_ex_set_context(dialog_ex, app);
dialog_ex_set_result_callback(dialog_ex, storage_settings_scene_unmounted_dialog_callback);
view_dispatcher_switch_to_view(app->view_dispatcher, StorageSettingsViewDialogEx);
}
bool storage_settings_scene_unmounted_on_event(void* context, SceneManagerEvent event) {
StorageSettings* app = context;
bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) {
switch(event.event) {
case DialogExResultLeft:
consumed = scene_manager_search_and_switch_to_previous_scene(
app->scene_manager, StorageSettingsStart);
break;
}
} else if(event.type == SceneManagerEventTypeBack) {
consumed = scene_manager_search_and_switch_to_previous_scene(
app->scene_manager, StorageSettingsStart);
}
return consumed;
}
void storage_settings_scene_unmounted_on_exit(void* context) {
StorageSettings* app = context;
DialogEx* dialog_ex = app->dialog_ex;
dialog_ex_set_header(dialog_ex, NULL, 0, 0, AlignCenter, AlignCenter);
dialog_ex_set_text(dialog_ex, NULL, 0, 0, AlignCenter, AlignTop);
dialog_ex_set_icon(dialog_ex, 0, 0, NULL);
dialog_ex_set_left_button_text(dialog_ex, NULL);
dialog_ex_set_right_button_text(dialog_ex, NULL);
dialog_ex_set_result_callback(dialog_ex, NULL);
dialog_ex_set_context(dialog_ex, NULL);
}

View File

@@ -0,0 +1,90 @@
#include "../storage_settings.h"
#include <power/power_service/power.h>
#include <furi-hal.h>
#define STORAGE_SETTINGS_SCENE_FACTORY_RESET_CONFIRM_COUNT 5
static void
storage_settings_scene_factory_reset_dialog_callback(DialogExResult result, void* context) {
StorageSettings* app = context;
view_dispatcher_send_custom_event(app->view_dispatcher, result);
}
void storage_settings_scene_factory_reset_on_enter(void* context) {
StorageSettings* app = context;
DialogEx* dialog_ex = app->dialog_ex;
dialog_ex_set_context(dialog_ex, app);
dialog_ex_set_result_callback(dialog_ex, storage_settings_scene_factory_reset_dialog_callback);
dialog_ex_set_left_button_text(dialog_ex, "Back");
dialog_ex_set_right_button_text(dialog_ex, "Erase");
dialog_ex_set_header(dialog_ex, "Confirm Factory Reset", 64, 10, AlignCenter, AlignCenter);
dialog_ex_set_text(
dialog_ex,
"Internal storage will be erased\r\nData and setting will be lost",
64,
32,
AlignCenter,
AlignCenter);
view_dispatcher_switch_to_view(app->view_dispatcher, StorageSettingsViewDialogEx);
}
bool storage_settings_scene_factory_reset_on_event(void* context, SceneManagerEvent event) {
StorageSettings* app = context;
bool consumed = false;
uint32_t counter =
scene_manager_get_scene_state(app->scene_manager, StorageSettingsFactoryReset);
if(event.type == SceneManagerEventTypeCustom) {
switch(event.event) {
case DialogExResultLeft:
scene_manager_set_scene_state(app->scene_manager, StorageSettingsFactoryReset, 0);
consumed = scene_manager_previous_scene(app->scene_manager);
break;
case DialogExResultRight:
counter++;
if(counter < STORAGE_SETTINGS_SCENE_FACTORY_RESET_CONFIRM_COUNT) {
string_printf(
app->text_string,
"%ld presses left",
STORAGE_SETTINGS_SCENE_FACTORY_RESET_CONFIRM_COUNT - counter);
dialog_ex_set_text(
app->dialog_ex,
string_get_cstr(app->text_string),
64,
32,
AlignCenter,
AlignCenter);
scene_manager_set_scene_state(
app->scene_manager, StorageSettingsFactoryReset, counter);
} else {
furi_hal_bootloader_set_flags(FuriHalBootloaderFlagFactoryReset);
power_reboot(PowerBootModeNormal);
}
consumed = true;
break;
}
}
return consumed;
}
void storage_settings_scene_factory_reset_on_exit(void* context) {
StorageSettings* app = context;
DialogEx* dialog_ex = app->dialog_ex;
dialog_ex_set_header(dialog_ex, NULL, 0, 0, AlignCenter, AlignCenter);
dialog_ex_set_text(dialog_ex, NULL, 0, 0, AlignCenter, AlignTop);
dialog_ex_set_icon(dialog_ex, 0, 0, NULL);
dialog_ex_set_left_button_text(dialog_ex, NULL);
dialog_ex_set_right_button_text(dialog_ex, NULL);
dialog_ex_set_result_callback(dialog_ex, NULL);
dialog_ex_set_context(dialog_ex, NULL);
string_reset(app->text_string);
}

View File

@@ -0,0 +1,67 @@
#include "../storage_settings.h"
static void
storage_settings_scene_format_confirm_dialog_callback(DialogExResult result, void* context) {
StorageSettings* app = context;
view_dispatcher_send_custom_event(app->view_dispatcher, result);
}
void storage_settings_scene_format_confirm_on_enter(void* context) {
StorageSettings* app = context;
FS_Error sd_status = storage_sd_status(app->fs_api);
DialogEx* dialog_ex = app->dialog_ex;
dialog_ex_set_left_button_text(dialog_ex, "Back");
if(sd_status == FSE_NOT_READY) {
dialog_ex_set_header(dialog_ex, "SD card not mounted", 64, 10, AlignCenter, AlignCenter);
dialog_ex_set_text(
dialog_ex,
"If an SD card is inserted,\r\npull it out and reinsert it",
64,
32,
AlignCenter,
AlignCenter);
} else {
dialog_ex_set_right_button_text(dialog_ex, "Format");
dialog_ex_set_header(dialog_ex, "Format SD card?", 64, 10, AlignCenter, AlignCenter);
dialog_ex_set_text(dialog_ex, "All data will be lost", 64, 32, AlignCenter, AlignCenter);
}
dialog_ex_set_context(dialog_ex, app);
dialog_ex_set_result_callback(
dialog_ex, storage_settings_scene_format_confirm_dialog_callback);
view_dispatcher_switch_to_view(app->view_dispatcher, StorageSettingsViewDialogEx);
}
bool storage_settings_scene_format_confirm_on_event(void* context, SceneManagerEvent event) {
StorageSettings* app = context;
bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) {
switch(event.event) {
case DialogExResultLeft:
consumed = scene_manager_previous_scene(app->scene_manager);
break;
case DialogExResultRight:
scene_manager_next_scene(app->scene_manager, StorageSettingsFormatting);
consumed = true;
break;
}
}
return consumed;
}
void storage_settings_scene_format_confirm_on_exit(void* context) {
StorageSettings* app = context;
DialogEx* dialog_ex = app->dialog_ex;
dialog_ex_set_header(dialog_ex, NULL, 0, 0, AlignCenter, AlignCenter);
dialog_ex_set_text(dialog_ex, NULL, 0, 0, AlignCenter, AlignTop);
dialog_ex_set_icon(dialog_ex, 0, 0, NULL);
dialog_ex_set_left_button_text(dialog_ex, NULL);
dialog_ex_set_right_button_text(dialog_ex, NULL);
dialog_ex_set_result_callback(dialog_ex, NULL);
dialog_ex_set_context(dialog_ex, NULL);
}

View File

@@ -0,0 +1,86 @@
#include "../storage_settings.h"
static const NotificationMessage message_green_165 = {
.type = NotificationMessageTypeLedGreen,
.data.led.value = 165,
};
static const NotificationSequence sequence_set_formatting_leds = {
&message_red_255,
&message_green_165,
&message_blue_0,
&message_do_not_reset,
NULL,
};
static const NotificationSequence sequence_reset_formatting_leds = {
&message_red_0,
&message_green_0,
NULL,
};
static void
storage_settings_scene_formatting_dialog_callback(DialogExResult result, void* context) {
StorageSettings* app = context;
view_dispatcher_send_custom_event(app->view_dispatcher, result);
}
void storage_settings_scene_formatting_on_enter(void* context) {
StorageSettings* app = context;
FS_Error error;
DialogEx* dialog_ex = app->dialog_ex;
dialog_ex_set_header(dialog_ex, "Formatting...", 64, 32, AlignCenter, AlignCenter);
view_dispatcher_switch_to_view(app->view_dispatcher, StorageSettingsViewDialogEx);
notification_message_block(app->notification, &sequence_set_formatting_leds);
error = storage_sd_format(app->fs_api);
notification_message(app->notification, &sequence_reset_formatting_leds);
notification_message(app->notification, &sequence_blink_green_100);
if(error != FSE_OK) {
dialog_ex_set_header(dialog_ex, "Cannot format SD Card", 64, 10, AlignCenter, AlignCenter);
dialog_ex_set_text(
dialog_ex, storage_error_get_desc(error), 64, 32, AlignCenter, AlignCenter);
} else {
dialog_ex_set_header(dialog_ex, "SD card formatted", 64, 10, AlignCenter, AlignCenter);
dialog_ex_set_text(dialog_ex, "Press back to return", 64, 32, AlignCenter, AlignCenter);
}
dialog_ex_set_context(dialog_ex, app);
dialog_ex_set_result_callback(dialog_ex, storage_settings_scene_formatting_dialog_callback);
dialog_ex_set_left_button_text(dialog_ex, "Back");
}
bool storage_settings_scene_formatting_on_event(void* context, SceneManagerEvent event) {
StorageSettings* app = context;
bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) {
switch(event.event) {
case DialogExResultLeft:
consumed = scene_manager_search_and_switch_to_previous_scene(
app->scene_manager, StorageSettingsStart);
break;
}
} else if(event.type == SceneManagerEventTypeBack) {
consumed = scene_manager_search_and_switch_to_previous_scene(
app->scene_manager, StorageSettingsStart);
}
return consumed;
}
void storage_settings_scene_formatting_on_exit(void* context) {
StorageSettings* app = context;
DialogEx* dialog_ex = app->dialog_ex;
dialog_ex_set_header(dialog_ex, NULL, 0, 0, AlignCenter, AlignCenter);
dialog_ex_set_text(dialog_ex, NULL, 0, 0, AlignCenter, AlignTop);
dialog_ex_set_icon(dialog_ex, 0, 0, NULL);
dialog_ex_set_left_button_text(dialog_ex, NULL);
dialog_ex_set_right_button_text(dialog_ex, NULL);
dialog_ex_set_result_callback(dialog_ex, NULL);
dialog_ex_set_context(dialog_ex, NULL);
}

View File

@@ -0,0 +1,68 @@
#include "../storage_settings.h"
#include <furi-hal-version.h>
static void
storage_settings_scene_internal_info_dialog_callback(DialogExResult result, void* context) {
StorageSettings* app = context;
view_dispatcher_send_custom_event(app->view_dispatcher, result);
}
void storage_settings_scene_internal_info_on_enter(void* context) {
StorageSettings* app = context;
uint64_t total_space;
uint64_t free_space;
FS_Error error = storage_common_fs_info(app->fs_api, "/int", &total_space, &free_space);
DialogEx* dialog_ex = app->dialog_ex;
dialog_ex_set_context(dialog_ex, app);
dialog_ex_set_result_callback(dialog_ex, storage_settings_scene_internal_info_dialog_callback);
dialog_ex_set_left_button_text(dialog_ex, "Back");
if(error != FSE_OK) {
dialog_ex_set_header(
dialog_ex, "Internal storage error", 64, 10, AlignCenter, AlignCenter);
dialog_ex_set_text(
dialog_ex, storage_error_get_desc(error), 64, 32, AlignCenter, AlignCenter);
} else {
string_printf(
app->text_string,
"Label: %s\nType: LittleFS\n%lu KB total\n%lu KB free",
furi_hal_version_get_name_ptr() ? furi_hal_version_get_name_ptr() : "Unknown",
(uint32_t)(total_space / 1024),
(uint32_t)(free_space / 1024));
dialog_ex_set_text(
dialog_ex, string_get_cstr(app->text_string), 4, 4, AlignLeft, AlignTop);
}
view_dispatcher_switch_to_view(app->view_dispatcher, StorageSettingsViewDialogEx);
}
bool storage_settings_scene_internal_info_on_event(void* context, SceneManagerEvent event) {
StorageSettings* app = context;
bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) {
switch(event.event) {
case DialogExResultLeft:
consumed = scene_manager_previous_scene(app->scene_manager);
break;
}
}
return consumed;
}
void storage_settings_scene_internal_info_on_exit(void* context) {
StorageSettings* app = context;
DialogEx* dialog_ex = app->dialog_ex;
dialog_ex_set_header(dialog_ex, NULL, 0, 0, AlignCenter, AlignCenter);
dialog_ex_set_text(dialog_ex, NULL, 0, 0, AlignCenter, AlignTop);
dialog_ex_set_icon(dialog_ex, 0, 0, NULL);
dialog_ex_set_left_button_text(dialog_ex, NULL);
dialog_ex_set_right_button_text(dialog_ex, NULL);
dialog_ex_set_result_callback(dialog_ex, NULL);
dialog_ex_set_context(dialog_ex, NULL);
string_reset(app->text_string);
}

View File

@@ -0,0 +1,74 @@
#include "../storage_settings.h"
static void storage_settings_scene_sd_info_dialog_callback(DialogExResult result, void* context) {
StorageSettings* app = context;
view_dispatcher_send_custom_event(app->view_dispatcher, result);
}
void storage_settings_scene_sd_info_on_enter(void* context) {
StorageSettings* app = context;
SDInfo sd_info;
FS_Error sd_status = storage_sd_info(app->fs_api, &sd_info);
DialogEx* dialog_ex = app->dialog_ex;
dialog_ex_set_context(dialog_ex, app);
dialog_ex_set_result_callback(dialog_ex, storage_settings_scene_sd_info_dialog_callback);
dialog_ex_set_left_button_text(dialog_ex, "Back");
if(sd_status != FSE_OK) {
dialog_ex_set_header(dialog_ex, "SD card not mounted", 64, 10, AlignCenter, AlignCenter);
dialog_ex_set_text(
dialog_ex,
"If an SD card is inserted,\r\npull it out and reinsert it",
64,
32,
AlignCenter,
AlignCenter);
} else {
string_printf(
app->text_string,
"Label: %s\nType: %s\n%lu KB total\n%lu KB free",
sd_info.label,
sd_api_get_fs_type_text(sd_info.fs_type),
sd_info.kb_total,
sd_info.kb_free);
dialog_ex_set_text(
dialog_ex, string_get_cstr(app->text_string), 4, 4, AlignLeft, AlignTop);
}
view_dispatcher_switch_to_view(app->view_dispatcher, StorageSettingsViewDialogEx);
}
bool storage_settings_scene_sd_info_on_event(void* context, SceneManagerEvent event) {
StorageSettings* app = context;
bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) {
switch(event.event) {
case DialogExResultLeft:
consumed = scene_manager_previous_scene(app->scene_manager);
break;
case DialogExResultRight:
scene_manager_next_scene(app->scene_manager, StorageSettingsUnmounted);
consumed = true;
break;
}
}
return consumed;
}
void storage_settings_scene_sd_info_on_exit(void* context) {
StorageSettings* app = context;
DialogEx* dialog_ex = app->dialog_ex;
dialog_ex_set_header(dialog_ex, NULL, 0, 0, AlignCenter, AlignCenter);
dialog_ex_set_text(dialog_ex, NULL, 0, 0, AlignCenter, AlignTop);
dialog_ex_set_icon(dialog_ex, 0, 0, NULL);
dialog_ex_set_left_button_text(dialog_ex, NULL);
dialog_ex_set_right_button_text(dialog_ex, NULL);
dialog_ex_set_result_callback(dialog_ex, NULL);
dialog_ex_set_context(dialog_ex, NULL);
string_reset(app->text_string);
}

View File

@@ -0,0 +1,119 @@
#include "../storage_settings.h"
enum StorageSettingsStartSubmenuIndex {
StorageSettingsStartSubmenuIndexInternalInfo,
StorageSettingsStartSubmenuIndexSDInfo,
StorageSettingsStartSubmenuIndexUnmount,
StorageSettingsStartSubmenuIndexFormat,
StorageSettingsStartSubmenuIndexBenchy,
StorageSettingsStartSubmenuIndexFactoryReset
};
static void storage_settings_scene_start_submenu_callback(void* context, uint32_t index) {
StorageSettings* app = context;
view_dispatcher_send_custom_event(app->view_dispatcher, index);
}
void storage_settings_scene_start_on_enter(void* context) {
StorageSettings* app = context;
Submenu* submenu = app->submenu;
submenu_add_item(
submenu,
"About internal storage",
StorageSettingsStartSubmenuIndexInternalInfo,
storage_settings_scene_start_submenu_callback,
app);
submenu_add_item(
submenu,
"About SD Card",
StorageSettingsStartSubmenuIndexSDInfo,
storage_settings_scene_start_submenu_callback,
app);
submenu_add_item(
submenu,
"Unmount SD Card",
StorageSettingsStartSubmenuIndexUnmount,
storage_settings_scene_start_submenu_callback,
app);
submenu_add_item(
submenu,
"Format SD Card",
StorageSettingsStartSubmenuIndexFormat,
storage_settings_scene_start_submenu_callback,
app);
submenu_add_item(
submenu,
"Benchmark SD Card",
StorageSettingsStartSubmenuIndexBenchy,
storage_settings_scene_start_submenu_callback,
app);
submenu_add_item(
submenu,
"Factory Reset",
StorageSettingsStartSubmenuIndexFactoryReset,
storage_settings_scene_start_submenu_callback,
app);
submenu_set_selected_item(
submenu, scene_manager_get_scene_state(app->scene_manager, StorageSettingsStart));
view_dispatcher_switch_to_view(app->view_dispatcher, StorageSettingsViewSubmenu);
}
bool storage_settings_scene_start_on_event(void* context, SceneManagerEvent event) {
StorageSettings* app = context;
bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) {
switch(event.event) {
case StorageSettingsStartSubmenuIndexSDInfo:
scene_manager_set_scene_state(
app->scene_manager, StorageSettingsStart, StorageSettingsStartSubmenuIndexSDInfo);
scene_manager_next_scene(app->scene_manager, StorageSettingsSDInfo);
consumed = true;
break;
case StorageSettingsStartSubmenuIndexInternalInfo:
scene_manager_set_scene_state(
app->scene_manager,
StorageSettingsStart,
StorageSettingsStartSubmenuIndexInternalInfo);
scene_manager_next_scene(app->scene_manager, StorageSettingsInternalInfo);
consumed = true;
break;
case StorageSettingsStartSubmenuIndexUnmount:
scene_manager_set_scene_state(
app->scene_manager, StorageSettingsStart, StorageSettingsStartSubmenuIndexUnmount);
scene_manager_next_scene(app->scene_manager, StorageSettingsUnmountConfirm);
consumed = true;
break;
case StorageSettingsStartSubmenuIndexFormat:
scene_manager_set_scene_state(
app->scene_manager, StorageSettingsStart, StorageSettingsStartSubmenuIndexFormat);
scene_manager_next_scene(app->scene_manager, StorageSettingsFormatConfirm);
consumed = true;
break;
case StorageSettingsStartSubmenuIndexBenchy:
scene_manager_set_scene_state(
app->scene_manager, StorageSettingsStart, StorageSettingsStartSubmenuIndexBenchy);
scene_manager_next_scene(app->scene_manager, StorageSettingsBenchmark);
consumed = true;
break;
case StorageSettingsStartSubmenuIndexFactoryReset:
scene_manager_set_scene_state(
app->scene_manager,
StorageSettingsStart,
StorageSettingsStartSubmenuIndexFactoryReset);
scene_manager_next_scene(app->scene_manager, StorageSettingsFactoryReset);
consumed = true;
break;
}
}
return consumed;
}
void storage_settings_scene_start_on_exit(void* context) {
StorageSettings* app = context;
submenu_clean(app->submenu);
}

View File

@@ -0,0 +1,75 @@
#include "storage_settings.h"
static bool storage_settings_custom_event_callback(void* context, uint32_t event) {
furi_assert(context);
StorageSettings* app = context;
return scene_manager_handle_custom_event(app->scene_manager, event);
}
static bool storage_settings_back_event_callback(void* context) {
furi_assert(context);
StorageSettings* app = context;
return scene_manager_handle_back_event(app->scene_manager);
}
static StorageSettings* storage_settings_alloc() {
StorageSettings* app = malloc(sizeof(StorageSettings));
app->gui = furi_record_open("gui");
app->fs_api = furi_record_open("storage");
app->notification = furi_record_open("notification");
app->view_dispatcher = view_dispatcher_alloc();
app->scene_manager = scene_manager_alloc(&storage_settings_scene_handlers, app);
string_init(app->text_string);
view_dispatcher_enable_queue(app->view_dispatcher);
view_dispatcher_set_event_callback_context(app->view_dispatcher, app);
view_dispatcher_set_custom_event_callback(
app->view_dispatcher, storage_settings_custom_event_callback);
view_dispatcher_set_navigation_event_callback(
app->view_dispatcher, storage_settings_back_event_callback);
view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen);
app->submenu = submenu_alloc();
view_dispatcher_add_view(
app->view_dispatcher, StorageSettingsViewSubmenu, submenu_get_view(app->submenu));
app->dialog_ex = dialog_ex_alloc();
view_dispatcher_add_view(
app->view_dispatcher, StorageSettingsViewDialogEx, dialog_ex_get_view(app->dialog_ex));
scene_manager_next_scene(app->scene_manager, StorageSettingsStart);
return app;
}
static void storage_settings_free(StorageSettings* app) {
view_dispatcher_remove_view(app->view_dispatcher, StorageSettingsViewSubmenu);
submenu_free(app->submenu);
view_dispatcher_remove_view(app->view_dispatcher, StorageSettingsViewDialogEx);
dialog_ex_free(app->dialog_ex);
view_dispatcher_free(app->view_dispatcher);
scene_manager_free(app->scene_manager);
furi_record_close("gui");
furi_record_close("storage");
furi_record_close("notification");
string_clear(app->text_string);
free(app);
}
int32_t storage_settings_app(void* p) {
StorageSettings* app = storage_settings_alloc();
view_dispatcher_run(app->view_dispatcher);
storage_settings_free(app);
return 0;
}

View File

@@ -0,0 +1,47 @@
#pragma once
#include <furi.h>
#include <gui/gui.h>
#include <gui/view.h>
#include <gui/view_dispatcher.h>
#include <gui/scene_manager.h>
#include <notification/notification-messages.h>
#include <gui/modules/submenu.h>
#include <gui/modules/dialog_ex.h>
#include <gui/modules/popup.h>
#include <storage/storage.h>
#include <storage/storage-sd-api.h>
#include "scenes/storage_settings_scene.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
// records
Gui* gui;
NotificationApp* notification;
Storage* fs_api;
// view managment
SceneManager* scene_manager;
ViewDispatcher* view_dispatcher;
// view modules
Submenu* submenu;
DialogEx* dialog_ex;
// text
string_t text_string;
} StorageSettings;
typedef enum {
StorageSettingsViewSubmenu,
StorageSettingsViewDialogEx,
} StorageSettingsView;
#ifdef __cplusplus
}
#endif