diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_read_success.c b/applications/main/lfrfid/scenes/lfrfid_scene_read_success.c index eb773f41b..b0e373ea5 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_read_success.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_read_success.c @@ -15,8 +15,10 @@ void lfrfid_scene_read_success_on_enter(void* context) { } else { furi_string_printf(display_text, "\e#%s\e#", protocol); } + widget_add_text_box_element( + widget, 16, 2, 112, 14, AlignLeft, AlignTop, furi_string_get_cstr(display_text), true); - furi_string_cat(display_text, "\nHex: "); + furi_string_set(display_text, "Hex: "); const size_t data_size = protocol_dict_get_data_size(app->dict, app->protocol_id); uint8_t* data = malloc(data_size); @@ -40,7 +42,7 @@ void lfrfid_scene_read_success_on_enter(void* context) { furi_string_free(rendered_data); widget_add_text_box_element( - widget, 0, 0, 128, 52, AlignLeft, AlignTop, furi_string_get_cstr(display_text), true); + widget, 0, 16, 128, 52, AlignLeft, AlignTop, furi_string_get_cstr(display_text), true); widget_add_button_element(widget, GuiButtonTypeLeft, "Retry", lfrfid_widget_callback, app); widget_add_button_element(widget, GuiButtonTypeRight, "More", lfrfid_widget_callback, app); diff --git a/applications/services/desktop/desktop.c b/applications/services/desktop/desktop.c index 123b18bdd..a0f64990f 100644 --- a/applications/services/desktop/desktop.c +++ b/applications/services/desktop/desktop.c @@ -33,10 +33,8 @@ static void desktop_loader_callback(const void* message, void* context) { const LoaderEvent* event = message; if(event->type == LoaderEventTypeApplicationBeforeLoad) { - desktop->animation_lock = api_lock_alloc_locked(); view_dispatcher_send_custom_event(desktop->view_dispatcher, DesktopGlobalBeforeAppStarted); - api_lock_wait_unlock_and_free(desktop->animation_lock); - desktop->animation_lock = NULL; + furi_check(furi_semaphore_acquire(desktop->animation_semaphore, 3000) == FuriStatusOk); } else if( event->type == LoaderEventTypeApplicationLoadFailed || event->type == LoaderEventTypeApplicationStopped) { @@ -130,7 +128,7 @@ static bool desktop_custom_event_callback(void* context, uint32_t event) { animation_manager_unload_and_stall_animation(desktop->animation_manager); } desktop_auto_lock_inhibit(desktop); - api_lock_unlock(desktop->animation_lock); + furi_semaphore_release(desktop->animation_semaphore); return true; case DesktopGlobalAfterAppFinished: animation_manager_load_and_continue_animation(desktop->animation_manager); @@ -280,6 +278,7 @@ void desktop_set_stealth_mode_state(Desktop* desktop, bool enabled) { Desktop* desktop_alloc(void) { Desktop* desktop = malloc(sizeof(Desktop)); + desktop->animation_semaphore = furi_semaphore_alloc(1, 0); desktop->animation_manager = animation_manager_alloc(); desktop->gui = furi_record_open(RECORD_GUI); desktop->scene_thread = furi_thread_alloc(); diff --git a/applications/services/desktop/desktop_i.h b/applications/services/desktop/desktop_i.h index 06ca70bda..c0b29f922 100644 --- a/applications/services/desktop/desktop_i.h +++ b/applications/services/desktop/desktop_i.h @@ -20,7 +20,6 @@ #include #include -#include #define STATUS_BAR_Y_SHIFT 13 @@ -82,7 +81,7 @@ struct Desktop { bool in_transition : 1; - FuriApiLock animation_lock; + FuriSemaphore* animation_semaphore; }; Desktop* desktop_alloc(void); diff --git a/applications/services/loader/loader.c b/applications/services/loader/loader.c index eb2dc3aec..87d077de4 100644 --- a/applications/services/loader/loader.c +++ b/applications/services/loader/loader.c @@ -47,10 +47,24 @@ LoaderStatus return result.value; } -static void loader_show_gui_error(LoaderStatus status, FuriString* error_message) { - // TODO FL-3522: we have many places where we can emit a double start, ex: desktop, menu - // so i prefer to not show LoaderStatusErrorAppStarted error message for now - if(status == LoaderStatusErrorUnknownApp || status == LoaderStatusErrorInternal) { +static void + loader_show_gui_error(LoaderStatus status, const char* name, FuriString* error_message) { + if(status == LoaderStatusErrorUnknownApp && + loader_find_external_application_by_name(name) != NULL) { + // Special case for external apps + DialogsApp* dialogs = furi_record_open(RECORD_DIALOGS); + DialogMessage* message = dialog_message_alloc(); + dialog_message_set_header(message, "Update needed", 64, 3, AlignCenter, AlignTop); + dialog_message_set_buttons(message, NULL, NULL, NULL); + dialog_message_set_icon(message, &I_WarningDolphinFlip_45x42, 83, 22); + dialog_message_set_text( + message, "Update firmware\nto run this app", 3, 26, AlignLeft, AlignTop); + dialog_message_show(dialogs, message); + dialog_message_free(message); + furi_record_close(RECORD_DIALOGS); + } else if(status == LoaderStatusErrorUnknownApp || status == LoaderStatusErrorInternal) { + // TODO FL-3522: we have many places where we can emit a double start, ex: desktop, menu + // so i prefer to not show LoaderStatusErrorAppStarted error message for now DialogsApp* dialogs = furi_record_open(RECORD_DIALOGS); DialogMessage* message = dialog_message_alloc(); dialog_message_set_header(message, "Error", 64, 0, AlignCenter, AlignTop); @@ -76,7 +90,7 @@ LoaderStatus loader_start_with_gui_error(Loader* loader, const char* name, const FuriString* error_message = furi_string_alloc(); LoaderStatus status = loader_start(loader, name, args, error_message); - loader_show_gui_error(status, error_message); + loader_show_gui_error(status, name, error_message); furi_string_free(error_message); return status; } @@ -85,11 +99,11 @@ void loader_start_detached_with_gui_error(Loader* loader, const char* name, cons furi_check(loader); furi_check(name); - LoaderMessage message; - - message.type = LoaderMessageTypeStartByNameDetachedWithGuiError; - message.start.name = name ? strdup(name) : NULL; - message.start.args = args ? strdup(args) : NULL; + LoaderMessage message = { + .type = LoaderMessageTypeStartByNameDetachedWithGuiError, + .start.name = name ? strdup(name) : NULL, + .start.args = args ? strdup(args) : NULL, + }; furi_message_queue_put(loader->queue, &message, FuriWaitForever); } @@ -581,7 +595,7 @@ int32_t loader_srv(void* p) { FuriString* error_message = furi_string_alloc(); LoaderStatus status = loader_do_start_by_name( loader, message.start.name, message.start.args, error_message); - loader_show_gui_error(status, error_message); + loader_show_gui_error(status, message.start.name, error_message); if(message.start.name) free((void*)message.start.name); if(message.start.args) free((void*)message.start.args); furi_string_free(error_message); diff --git a/applications/system/js_app/modules/js_badusb.c b/applications/system/js_app/modules/js_badusb.c index 1722f6672..42e677842 100644 --- a/applications/system/js_app/modules/js_badusb.c +++ b/applications/system/js_app/modules/js_badusb.c @@ -133,17 +133,20 @@ static bool setup_parse_params( if(mjs_is_string(layout_obj)) { size_t str_len = 0; const char* str_temp = mjs_get_string(mjs, &layout_obj, &str_len); - File* file = storage_file_alloc(furi_record_open(RECORD_STORAGE)); - size_t size = sizeof(badusb->layout); - - if((str_len == 0) || (str_temp == NULL) || - !storage_file_open(file, str_temp, FSAM_READ, FSOM_OPEN_EXISTING) || - storage_file_read(file, badusb->layout, size) != size) { - memcpy(badusb->layout, hid_asciimap, MIN(sizeof(hid_asciimap), size)); + if((str_len == 0) || (str_temp == NULL)) { + return false; } - + File* file = storage_file_alloc(furi_record_open(RECORD_STORAGE)); + bool layout_loaded = storage_file_open(file, str_temp, FSAM_READ, FSOM_OPEN_EXISTING) && + storage_file_read(file, badusb->layout, sizeof(badusb->layout)) == + sizeof(badusb->layout); storage_file_free(file); furi_record_close(RECORD_STORAGE); + if(!layout_loaded) { + return false; + } + } else { + memcpy(badusb->layout, hid_asciimap, MIN(sizeof(hid_asciimap), sizeof(badusb->layout))); } return true;