Storage: move factory reset to the place it belongs, add gui version. (#822)
This commit is contained in:
@@ -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,
|
||||
};
|
@@ -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
|
@@ -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);
|
||||
}
|
@@ -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)
|
@@ -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);
|
||||
}
|
66
applications/storage_settings/scenes/storage_settings_scene_ejected.c
Executable file
66
applications/storage_settings/scenes/storage_settings_scene_ejected.c
Executable 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);
|
||||
}
|
@@ -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);
|
||||
}
|
@@ -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);
|
||||
}
|
86
applications/storage_settings/scenes/storage_settings_scene_formatting.c
Executable file
86
applications/storage_settings/scenes/storage_settings_scene_formatting.c
Executable 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);
|
||||
}
|
@@ -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);
|
||||
}
|
@@ -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);
|
||||
}
|
@@ -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);
|
||||
}
|
75
applications/storage_settings/storage_settings.c
Normal file
75
applications/storage_settings/storage_settings.c
Normal 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;
|
||||
}
|
47
applications/storage_settings/storage_settings.h
Normal file
47
applications/storage_settings/storage_settings.h
Normal 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
|
Reference in New Issue
Block a user