diff --git a/applications/main/fap_loader/fap_loader_app.c b/applications/main/fap_loader/fap_loader_app.c index e81a3ce4c..8a9d8fd0d 100644 --- a/applications/main/fap_loader/fap_loader_app.c +++ b/applications/main/fap_loader/fap_loader_app.c @@ -153,6 +153,7 @@ static bool fap_loader_select_app(FapLoader* loader) { .skip_assets = true, .icon = &I_unknown_10px, .hide_ext = true, + .hide_dot_files = true, .item_loader_callback = fap_loader_item_callback, .item_loader_context = loader, .base_path = EXT_PATH("apps"), diff --git a/applications/services/desktop/desktop_settings.h b/applications/services/desktop/desktop_settings.h index 959059cb0..0019f1ef8 100644 --- a/applications/services/desktop/desktop_settings.h +++ b/applications/services/desktop/desktop_settings.h @@ -7,6 +7,7 @@ #include #include #include +#include #define DESKTOP_SETTINGS_VER (7) @@ -36,8 +37,6 @@ #define MIN_PIN_SIZE 4 #define MAX_APP_LENGTH 128 -#define FAP_LOADER_APP_NAME "Applications" - typedef struct { InputKey data[MAX_PIN_SIZE]; uint8_t length; diff --git a/applications/services/loader/loader.c b/applications/services/loader/loader.c index 5f2d8a2e7..c98b4f09d 100644 --- a/applications/services/loader/loader.c +++ b/applications/services/loader/loader.c @@ -1,7 +1,12 @@ #include "applications.h" #include +#include #include "loader/loader.h" #include "loader_i.h" +#include "applications/main/fap_loader/fap_loader_app.h" +#include +#include +#include #define TAG "LoaderSrv" @@ -43,36 +48,6 @@ static bool return true; } -static void loader_menu_callback(void* _ctx, uint32_t index) { - UNUSED(index); - const FlipperApplication* application = _ctx; - - furi_assert(application->app); - furi_assert(application->name); - - if(!loader_lock(loader_instance)) { - FURI_LOG_E(TAG, "Loader is locked"); - return; - } - - loader_start_application(application, NULL); -} - -static void loader_submenu_callback(void* context, uint32_t index) { - UNUSED(index); - uint32_t view_id = (uint32_t)context; - view_dispatcher_switch_to_view(loader_instance->view_dispatcher, view_id); -} - -static void loader_cli_print_usage() { - printf("Usage:\r\n"); - printf("loader \r\n"); - printf("Cmd list:\r\n"); - printf("\tlist\t - List available applications\r\n"); - printf("\topen \t - Open application by name\r\n"); - printf("\tinfo\t - Show loader state\r\n"); -} - static FlipperApplication const* loader_find_application_by_name_in_list( const char* name, const FlipperApplication* list, @@ -108,6 +83,51 @@ const FlipperApplication* loader_find_application_by_name(const char* name) { return application; } +static void loader_menu_callback(void* _ctx, uint32_t index) { + UNUSED(index); + const FlipperApplication* application = _ctx; + + furi_assert(application->app); + furi_assert(application->name); + + if(!loader_lock(loader_instance)) { + FURI_LOG_E(TAG, "Loader is locked"); + return; + } + + loader_start_application(application, NULL); +} + +static void loader_main_callback(void* _ctx, uint32_t index) { + UNUSED(index); + const char* path = _ctx; + const FlipperApplication* app = loader_find_application_by_name_in_list(FAP_LOADER_APP_NAME, FLIPPER_APPS, FLIPPER_APPS_COUNT); + + furi_assert(path); + + if(!loader_lock(loader_instance)) { + FURI_LOG_E(TAG, "Loader is locked"); + return; + } + + loader_start_application(app, path); +} + +static void loader_submenu_callback(void* context, uint32_t index) { + UNUSED(index); + uint32_t view_id = (uint32_t)context; + view_dispatcher_switch_to_view(loader_instance->view_dispatcher, view_id); +} + +static void loader_cli_print_usage() { + printf("Usage:\r\n"); + printf("loader \r\n"); + printf("Cmd list:\r\n"); + printf("\tlist\t - List available applications\r\n"); + printf("\topen \t - Open application by name\r\n"); + printf("\tinfo\t - Show loader state\r\n"); +} + static void loader_cli_open(Cli* cli, FuriString* args, Loader* instance) { UNUSED(cli); if(loader_is_locked(instance)) { @@ -411,6 +431,42 @@ static void loader_build_menu() { loader_menu_callback, (void*)&FLIPPER_APPS[i]); } + Storage* storage = furi_record_open(RECORD_STORAGE); + File* folder = storage_file_alloc(storage); + FileInfo info; + char* name = malloc(100); + if(storage_dir_open(folder, EXT_PATH("apps/.Main"))) { + FuriString* path = furi_string_alloc(); + FuriString* appname = furi_string_alloc(); + while(storage_dir_read(folder, &info, name, 100)) { + if(file_info_is_dir(&info)) continue; + furi_string_printf(path, EXT_PATH("apps/.Main/%s"), name); + uint8_t* icondata = malloc(FAP_MANIFEST_MAX_ICON_SIZE); + if(!fap_loader_load_name_and_icon(path, storage, &icondata, appname)) { + free(icondata); + continue; + } + Icon* icon = malloc(sizeof(Icon)); + FURI_CONST_ASSIGN(icon->frame_count, 1); + FURI_CONST_ASSIGN(icon->frame_rate, 0); + FURI_CONST_ASSIGN(icon->width, 10); + FURI_CONST_ASSIGN(icon->height, 10); + icon->frames = malloc(sizeof(const uint8_t*)); + FURI_CONST_ASSIGN_PTR(icon->frames[0], icondata); + menu_add_item( + loader_instance->primary_menu, + strdup(furi_string_get_cstr(appname)), + icon, + i++, + loader_main_callback, + (void*)strdup(furi_string_get_cstr(path))); + } + furi_string_free(appname); + furi_string_free(path); + } + free(name); + storage_file_free(folder); + furi_record_close(RECORD_STORAGE); if(FLIPPER_PLUGINS_COUNT != 0) { menu_add_item( loader_instance->primary_menu, diff --git a/applications/services/loader/loader.h b/applications/services/loader/loader.h index 8dbc4fc35..2f8203e98 100644 --- a/applications/services/loader/loader.h +++ b/applications/services/loader/loader.h @@ -9,6 +9,8 @@ extern "C" { #define RECORD_LOADER "loader" +#define FAP_LOADER_APP_NAME "Applications" + typedef struct Loader Loader; typedef enum {