#include "storage.h" #include "storage-i.h" #include "storage-message.h" #include "storage-processing.h" #include "storage/storage-glue.h" #include "storages/storage-int.h" #include "storages/storage-ext.h" #define STORAGE_TICK 1000 #define ICON_SD_MOUNTED &I_SDcardMounted_11x8 #define ICON_SD_ERROR &I_SDcardFail_11x8 static void storage_app_sd_icon_draw_callback(Canvas* canvas, void* context) { furi_assert(canvas); furi_assert(context); Storage* app = context; // here we don't care about thread race when reading / writing status switch(app->storage[ST_EXT].status) { case StorageStatusNotReady: break; case StorageStatusOK: canvas_draw_icon(canvas, 0, 0, ICON_SD_MOUNTED); break; default: canvas_draw_icon(canvas, 0, 0, ICON_SD_ERROR); break; } } Storage* storage_app_alloc() { Storage* app = malloc(sizeof(Storage)); app->message_queue = osMessageQueueNew(8, sizeof(StorageMessage), NULL); app->pubsub = furi_pubsub_alloc(); for(uint8_t i = 0; i < STORAGE_COUNT; i++) { storage_data_init(&app->storage[i]); } storage_int_init(&app->storage[ST_INT]); storage_ext_init(&app->storage[ST_EXT]); // sd icon gui app->sd_gui.enabled = false; app->sd_gui.view_port = view_port_alloc(); view_port_set_width(app->sd_gui.view_port, icon_get_width(ICON_SD_MOUNTED)); view_port_draw_callback_set(app->sd_gui.view_port, storage_app_sd_icon_draw_callback, app); view_port_enabled_set(app->sd_gui.view_port, false); Gui* gui = furi_record_open("gui"); gui_add_view_port(gui, app->sd_gui.view_port, GuiLayerStatusBarLeft); furi_record_close("gui"); return app; } void storage_tick(Storage* app) { for(uint8_t i = 0; i < STORAGE_COUNT; i++) { StorageApi api = app->storage[i].api; if(api.tick != NULL) { api.tick(&app->storage[i]); } } if(app->storage[ST_EXT].status != app->prev_ext_storage_status) { app->prev_ext_storage_status = app->storage[ST_EXT].status; furi_pubsub_publish(app->pubsub, &app->storage[ST_EXT].status); } // storage not enabled but was enabled (sd card unmount) if(app->storage[ST_EXT].status == StorageStatusNotReady && app->sd_gui.enabled == true) { app->sd_gui.enabled = false; view_port_enabled_set(app->sd_gui.view_port, false); } // storage enabled (or in error state) but was not enabled (sd card mount) if((app->storage[ST_EXT].status == StorageStatusOK || app->storage[ST_EXT].status == StorageStatusNotMounted || app->storage[ST_EXT].status == StorageStatusNoFS || app->storage[ST_EXT].status == StorageStatusNotAccessible || app->storage[ST_EXT].status == StorageStatusErrorInternal) && app->sd_gui.enabled == false) { app->sd_gui.enabled = true; view_port_enabled_set(app->sd_gui.view_port, true); } } int32_t storage_srv(void* p) { Storage* app = storage_app_alloc(); furi_record_create("storage", app); StorageMessage message; while(1) { if(osMessageQueueGet(app->message_queue, &message, NULL, STORAGE_TICK) == osOK) { storage_process_message(app, &message); } else { storage_tick(app); } } return 0; }