mirror of
https://github.com/DarkFlippers/unleashed-firmware.git
synced 2024-11-23 19:00:43 +03:00
Desktop/Loader: Unload animations before loading FAPs (#3573)
* Desktop: Unload animations before FAP is loaded * Loader: Add API to start detached (returns instantly, queues event) * Desktop: Fix early animation unload deadlocks * Loader: remove redundant event * Bump api symbols Co-authored-by: あく <alleteam@gmail.com> Co-authored-by: SG <who.just.the.doctor@gmail.com>
This commit is contained in:
parent
58da27fa91
commit
e3ca293eee
@ -32,10 +32,12 @@ static void desktop_loader_callback(const void* message, void* context) {
|
||||
Desktop* desktop = context;
|
||||
const LoaderEvent* event = message;
|
||||
|
||||
if(event->type == LoaderEventTypeApplicationStarted) {
|
||||
if(event->type == LoaderEventTypeApplicationBeforeLoad) {
|
||||
view_dispatcher_send_custom_event(desktop->view_dispatcher, DesktopGlobalBeforeAppStarted);
|
||||
furi_check(furi_semaphore_acquire(desktop->animation_semaphore, 3000) == FuriStatusOk);
|
||||
} else if(event->type == LoaderEventTypeApplicationStopped) {
|
||||
} else if(
|
||||
event->type == LoaderEventTypeApplicationLoadFailed ||
|
||||
event->type == LoaderEventTypeApplicationStopped) {
|
||||
view_dispatcher_send_custom_event(desktop->view_dispatcher, DesktopGlobalAfterAppFinished);
|
||||
}
|
||||
}
|
||||
|
@ -62,23 +62,18 @@ static void
|
||||
#endif
|
||||
|
||||
static void desktop_scene_main_open_app_or_profile(Desktop* desktop, FavoriteApp* application) {
|
||||
bool load_ok = false;
|
||||
if(strlen(application->name_or_path) > 0) {
|
||||
if(loader_start(desktop->loader, application->name_or_path, NULL, NULL) ==
|
||||
LoaderStatusOk) {
|
||||
load_ok = true;
|
||||
}
|
||||
}
|
||||
if(!load_ok) {
|
||||
loader_start(desktop->loader, "Passport", NULL, NULL);
|
||||
loader_start_detached_with_gui_error(desktop->loader, application->name_or_path, NULL);
|
||||
} else {
|
||||
loader_start_detached_with_gui_error(desktop->loader, "Passport", NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void desktop_scene_main_start_favorite(Desktop* desktop, FavoriteApp* application) {
|
||||
if(strlen(application->name_or_path) > 0) {
|
||||
loader_start_with_gui_error(desktop->loader, application->name_or_path, NULL);
|
||||
loader_start_detached_with_gui_error(desktop->loader, application->name_or_path, NULL);
|
||||
} else {
|
||||
loader_start(desktop->loader, LOADER_APPLICATIONS_NAME, NULL, NULL);
|
||||
loader_start_detached_with_gui_error(desktop->loader, LOADER_APPLICATIONS_NAME, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@ -141,7 +136,7 @@ bool desktop_scene_main_on_event(void* context, SceneManagerEvent event) {
|
||||
break;
|
||||
|
||||
case DesktopMainEventOpenPowerOff: {
|
||||
loader_start(desktop->loader, "Power", "off", NULL);
|
||||
loader_start_detached_with_gui_error(desktop->loader, "Power", "off");
|
||||
consumed = true;
|
||||
break;
|
||||
}
|
||||
|
@ -47,13 +47,8 @@ LoaderStatus
|
||||
return result.value;
|
||||
}
|
||||
|
||||
LoaderStatus loader_start_with_gui_error(Loader* loader, const char* name, const char* args) {
|
||||
furi_check(loader);
|
||||
furi_check(name);
|
||||
|
||||
FuriString* error_message = furi_string_alloc();
|
||||
LoaderStatus status = loader_start(loader, name, args, error_message);
|
||||
|
||||
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
|
||||
@ -86,11 +81,31 @@ LoaderStatus loader_start_with_gui_error(Loader* loader, const char* name, const
|
||||
dialog_message_free(message);
|
||||
furi_record_close(RECORD_DIALOGS);
|
||||
}
|
||||
}
|
||||
|
||||
LoaderStatus loader_start_with_gui_error(Loader* loader, const char* name, const char* args) {
|
||||
furi_check(loader);
|
||||
furi_check(name);
|
||||
|
||||
FuriString* error_message = furi_string_alloc();
|
||||
LoaderStatus status = loader_start(loader, name, args, error_message);
|
||||
loader_show_gui_error(status, name, error_message);
|
||||
furi_string_free(error_message);
|
||||
return status;
|
||||
}
|
||||
|
||||
void loader_start_detached_with_gui_error(Loader* loader, const char* name, const char* args) {
|
||||
furi_check(loader);
|
||||
furi_check(name);
|
||||
|
||||
LoaderMessage message = {
|
||||
.type = LoaderMessageTypeStartByNameDetachedWithGuiError,
|
||||
.start.name = name ? strdup(name) : NULL,
|
||||
.start.args = args ? strdup(args) : NULL,
|
||||
};
|
||||
furi_message_queue_put(loader->queue, &message, FuriWaitForever);
|
||||
}
|
||||
|
||||
bool loader_lock(Loader* loader) {
|
||||
furi_check(loader);
|
||||
|
||||
@ -166,11 +181,7 @@ static void loader_thread_state_callback(FuriThreadState thread_state, void* con
|
||||
|
||||
Loader* loader = context;
|
||||
|
||||
if(thread_state == FuriThreadStateRunning) {
|
||||
LoaderEvent event;
|
||||
event.type = LoaderEventTypeApplicationStarted;
|
||||
furi_pubsub_publish(loader->pubsub, &event);
|
||||
} else if(thread_state == FuriThreadStateStopped) {
|
||||
if(thread_state == FuriThreadStateStopped) {
|
||||
LoaderMessage message;
|
||||
message.type = LoaderMessageTypeAppClosed;
|
||||
furi_message_queue_put(loader->queue, &message, FuriWaitForever);
|
||||
@ -255,6 +266,9 @@ static void loader_start_internal_app(
|
||||
const FlipperInternalApplication* app,
|
||||
const char* args) {
|
||||
FURI_LOG_I(TAG, "Starting %s", app->name);
|
||||
LoaderEvent event;
|
||||
event.type = LoaderEventTypeApplicationBeforeLoad;
|
||||
furi_pubsub_publish(loader->pubsub, &event);
|
||||
|
||||
// store args
|
||||
furi_assert(loader->app.args == NULL);
|
||||
@ -309,6 +323,9 @@ static LoaderStatus loader_start_external_app(
|
||||
const char* args,
|
||||
FuriString* error_message) {
|
||||
LoaderStatus status = loader_make_success_status(error_message);
|
||||
LoaderEvent event;
|
||||
event.type = LoaderEventTypeApplicationBeforeLoad;
|
||||
furi_pubsub_publish(loader->pubsub, &event);
|
||||
|
||||
do {
|
||||
loader->app.fap = flipper_application_alloc(storage, firmware_api_interface);
|
||||
@ -356,6 +373,8 @@ static LoaderStatus loader_start_external_app(
|
||||
if(status != LoaderStatusOk) {
|
||||
flipper_application_free(loader->app.fap);
|
||||
loader->app.fap = NULL;
|
||||
event.type = LoaderEventTypeApplicationLoadFailed;
|
||||
furi_pubsub_publish(loader->pubsub, &event);
|
||||
}
|
||||
|
||||
return status;
|
||||
@ -528,6 +547,16 @@ int32_t loader_srv(void* p) {
|
||||
loader, message.start.name, message.start.args, message.start.error_message);
|
||||
api_lock_unlock(message.api_lock);
|
||||
break;
|
||||
case LoaderMessageTypeStartByNameDetachedWithGuiError: {
|
||||
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, 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);
|
||||
break;
|
||||
}
|
||||
case LoaderMessageTypeShowMenu:
|
||||
loader_do_menu_show(loader);
|
||||
break;
|
||||
|
@ -18,7 +18,8 @@ typedef enum {
|
||||
} LoaderStatus;
|
||||
|
||||
typedef enum {
|
||||
LoaderEventTypeApplicationStarted,
|
||||
LoaderEventTypeApplicationBeforeLoad,
|
||||
LoaderEventTypeApplicationLoadFailed,
|
||||
LoaderEventTypeApplicationStopped
|
||||
} LoaderEventType;
|
||||
|
||||
@ -46,6 +47,14 @@ LoaderStatus
|
||||
*/
|
||||
LoaderStatus loader_start_with_gui_error(Loader* loader, const char* name, const char* args);
|
||||
|
||||
/**
|
||||
* @brief Start application detached with GUI error message
|
||||
* @param[in] instance loader instance
|
||||
* @param[in] name application name or id
|
||||
* @param[in] args application arguments
|
||||
*/
|
||||
void loader_start_detached_with_gui_error(Loader* loader, const char* name, const char* args);
|
||||
|
||||
/**
|
||||
* @brief Lock application start
|
||||
* @param[in] instance loader instance
|
||||
|
@ -30,6 +30,7 @@ typedef enum {
|
||||
LoaderMessageTypeLock,
|
||||
LoaderMessageTypeUnlock,
|
||||
LoaderMessageTypeIsLocked,
|
||||
LoaderMessageTypeStartByNameDetachedWithGuiError,
|
||||
} LoaderMessageType;
|
||||
|
||||
typedef struct {
|
||||
|
@ -1,5 +1,5 @@
|
||||
entry,status,name,type,params
|
||||
Version,+,60.5,,
|
||||
Version,+,60.6,,
|
||||
Header,+,applications/services/bt/bt_service/bt.h,,
|
||||
Header,+,applications/services/cli/cli.h,,
|
||||
Header,+,applications/services/cli/cli_vcp.h,,
|
||||
@ -1748,6 +1748,7 @@ Function,+,loader_is_locked,_Bool,Loader*
|
||||
Function,+,loader_lock,_Bool,Loader*
|
||||
Function,+,loader_show_menu,void,Loader*
|
||||
Function,+,loader_start,LoaderStatus,"Loader*, const char*, const char*, FuriString*"
|
||||
Function,+,loader_start_detached_with_gui_error,void,"Loader*, const char*, const char*"
|
||||
Function,+,loader_start_with_gui_error,LoaderStatus,"Loader*, const char*, const char*"
|
||||
Function,+,loader_unlock,void,Loader*
|
||||
Function,+,loading_alloc,Loading*,
|
||||
|
|
@ -1,5 +1,5 @@
|
||||
entry,status,name,type,params
|
||||
Version,+,60.5,,
|
||||
Version,+,60.6,,
|
||||
Header,+,applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h,,
|
||||
Header,+,applications/services/bt/bt_service/bt.h,,
|
||||
Header,+,applications/services/cli/cli.h,,
|
||||
@ -2139,6 +2139,7 @@ Function,+,loader_is_locked,_Bool,Loader*
|
||||
Function,+,loader_lock,_Bool,Loader*
|
||||
Function,+,loader_show_menu,void,Loader*
|
||||
Function,+,loader_start,LoaderStatus,"Loader*, const char*, const char*, FuriString*"
|
||||
Function,+,loader_start_detached_with_gui_error,void,"Loader*, const char*, const char*"
|
||||
Function,+,loader_start_with_gui_error,LoaderStatus,"Loader*, const char*, const char*"
|
||||
Function,+,loader_unlock,void,Loader*
|
||||
Function,+,loading_alloc,Loading*,
|
||||
|
|
Loading…
Reference in New Issue
Block a user