mirror of
https://github.com/DarkFlippers/unleashed-firmware
synced 2024-11-23 04:53:08 +00: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
7 changed files with 69 additions and 31 deletions
|
@ -32,10 +32,12 @@ static void desktop_loader_callback(const void* message, void* context) {
|
||||||
Desktop* desktop = context;
|
Desktop* desktop = context;
|
||||||
const LoaderEvent* event = message;
|
const LoaderEvent* event = message;
|
||||||
|
|
||||||
if(event->type == LoaderEventTypeApplicationStarted) {
|
if(event->type == LoaderEventTypeApplicationBeforeLoad) {
|
||||||
view_dispatcher_send_custom_event(desktop->view_dispatcher, DesktopGlobalBeforeAppStarted);
|
view_dispatcher_send_custom_event(desktop->view_dispatcher, DesktopGlobalBeforeAppStarted);
|
||||||
furi_check(furi_semaphore_acquire(desktop->animation_semaphore, 3000) == FuriStatusOk);
|
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);
|
view_dispatcher_send_custom_event(desktop->view_dispatcher, DesktopGlobalAfterAppFinished);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,23 +62,18 @@ static void
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void desktop_scene_main_open_app_or_profile(Desktop* desktop, FavoriteApp* application) {
|
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(strlen(application->name_or_path) > 0) {
|
||||||
if(loader_start(desktop->loader, application->name_or_path, NULL, NULL) ==
|
loader_start_detached_with_gui_error(desktop->loader, application->name_or_path, NULL);
|
||||||
LoaderStatusOk) {
|
} else {
|
||||||
load_ok = true;
|
loader_start_detached_with_gui_error(desktop->loader, "Passport", NULL);
|
||||||
}
|
|
||||||
}
|
|
||||||
if(!load_ok) {
|
|
||||||
loader_start(desktop->loader, "Passport", NULL, NULL);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void desktop_scene_main_start_favorite(Desktop* desktop, FavoriteApp* application) {
|
static void desktop_scene_main_start_favorite(Desktop* desktop, FavoriteApp* application) {
|
||||||
if(strlen(application->name_or_path) > 0) {
|
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 {
|
} 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;
|
break;
|
||||||
|
|
||||||
case DesktopMainEventOpenPowerOff: {
|
case DesktopMainEventOpenPowerOff: {
|
||||||
loader_start(desktop->loader, "Power", "off", NULL);
|
loader_start_detached_with_gui_error(desktop->loader, "Power", "off");
|
||||||
consumed = true;
|
consumed = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,13 +47,8 @@ LoaderStatus
|
||||||
return result.value;
|
return result.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
LoaderStatus loader_start_with_gui_error(Loader* loader, const char* name, const char* args) {
|
static void
|
||||||
furi_check(loader);
|
loader_show_gui_error(LoaderStatus status, const char* name, FuriString* error_message) {
|
||||||
furi_check(name);
|
|
||||||
|
|
||||||
FuriString* error_message = furi_string_alloc();
|
|
||||||
LoaderStatus status = loader_start(loader, name, args, error_message);
|
|
||||||
|
|
||||||
if(status == LoaderStatusErrorUnknownApp &&
|
if(status == LoaderStatusErrorUnknownApp &&
|
||||||
loader_find_external_application_by_name(name) != NULL) {
|
loader_find_external_application_by_name(name) != NULL) {
|
||||||
// Special case for external apps
|
// 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);
|
dialog_message_free(message);
|
||||||
furi_record_close(RECORD_DIALOGS);
|
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);
|
furi_string_free(error_message);
|
||||||
return status;
|
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) {
|
bool loader_lock(Loader* loader) {
|
||||||
furi_check(loader);
|
furi_check(loader);
|
||||||
|
|
||||||
|
@ -166,11 +181,7 @@ static void loader_thread_state_callback(FuriThreadState thread_state, void* con
|
||||||
|
|
||||||
Loader* loader = context;
|
Loader* loader = context;
|
||||||
|
|
||||||
if(thread_state == FuriThreadStateRunning) {
|
if(thread_state == FuriThreadStateStopped) {
|
||||||
LoaderEvent event;
|
|
||||||
event.type = LoaderEventTypeApplicationStarted;
|
|
||||||
furi_pubsub_publish(loader->pubsub, &event);
|
|
||||||
} else if(thread_state == FuriThreadStateStopped) {
|
|
||||||
LoaderMessage message;
|
LoaderMessage message;
|
||||||
message.type = LoaderMessageTypeAppClosed;
|
message.type = LoaderMessageTypeAppClosed;
|
||||||
furi_message_queue_put(loader->queue, &message, FuriWaitForever);
|
furi_message_queue_put(loader->queue, &message, FuriWaitForever);
|
||||||
|
@ -255,6 +266,9 @@ static void loader_start_internal_app(
|
||||||
const FlipperInternalApplication* app,
|
const FlipperInternalApplication* app,
|
||||||
const char* args) {
|
const char* args) {
|
||||||
FURI_LOG_I(TAG, "Starting %s", app->name);
|
FURI_LOG_I(TAG, "Starting %s", app->name);
|
||||||
|
LoaderEvent event;
|
||||||
|
event.type = LoaderEventTypeApplicationBeforeLoad;
|
||||||
|
furi_pubsub_publish(loader->pubsub, &event);
|
||||||
|
|
||||||
// store args
|
// store args
|
||||||
furi_assert(loader->app.args == NULL);
|
furi_assert(loader->app.args == NULL);
|
||||||
|
@ -309,6 +323,9 @@ static LoaderStatus loader_start_external_app(
|
||||||
const char* args,
|
const char* args,
|
||||||
FuriString* error_message) {
|
FuriString* error_message) {
|
||||||
LoaderStatus status = loader_make_success_status(error_message);
|
LoaderStatus status = loader_make_success_status(error_message);
|
||||||
|
LoaderEvent event;
|
||||||
|
event.type = LoaderEventTypeApplicationBeforeLoad;
|
||||||
|
furi_pubsub_publish(loader->pubsub, &event);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
loader->app.fap = flipper_application_alloc(storage, firmware_api_interface);
|
loader->app.fap = flipper_application_alloc(storage, firmware_api_interface);
|
||||||
|
@ -356,6 +373,8 @@ static LoaderStatus loader_start_external_app(
|
||||||
if(status != LoaderStatusOk) {
|
if(status != LoaderStatusOk) {
|
||||||
flipper_application_free(loader->app.fap);
|
flipper_application_free(loader->app.fap);
|
||||||
loader->app.fap = NULL;
|
loader->app.fap = NULL;
|
||||||
|
event.type = LoaderEventTypeApplicationLoadFailed;
|
||||||
|
furi_pubsub_publish(loader->pubsub, &event);
|
||||||
}
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
|
@ -528,6 +547,16 @@ int32_t loader_srv(void* p) {
|
||||||
loader, message.start.name, message.start.args, message.start.error_message);
|
loader, message.start.name, message.start.args, message.start.error_message);
|
||||||
api_lock_unlock(message.api_lock);
|
api_lock_unlock(message.api_lock);
|
||||||
break;
|
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:
|
case LoaderMessageTypeShowMenu:
|
||||||
loader_do_menu_show(loader);
|
loader_do_menu_show(loader);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -18,7 +18,8 @@ typedef enum {
|
||||||
} LoaderStatus;
|
} LoaderStatus;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
LoaderEventTypeApplicationStarted,
|
LoaderEventTypeApplicationBeforeLoad,
|
||||||
|
LoaderEventTypeApplicationLoadFailed,
|
||||||
LoaderEventTypeApplicationStopped
|
LoaderEventTypeApplicationStopped
|
||||||
} LoaderEventType;
|
} LoaderEventType;
|
||||||
|
|
||||||
|
@ -32,7 +33,7 @@ typedef struct {
|
||||||
* @param[in] name application name or id
|
* @param[in] name application name or id
|
||||||
* @param[in] args application arguments
|
* @param[in] args application arguments
|
||||||
* @param[out] error_message detailed error message, can be NULL
|
* @param[out] error_message detailed error message, can be NULL
|
||||||
* @return LoaderStatus
|
* @return LoaderStatus
|
||||||
*/
|
*/
|
||||||
LoaderStatus
|
LoaderStatus
|
||||||
loader_start(Loader* instance, const char* name, const char* args, FuriString* error_message);
|
loader_start(Loader* instance, const char* name, const char* args, FuriString* error_message);
|
||||||
|
@ -42,11 +43,19 @@ LoaderStatus
|
||||||
* @param[in] instance loader instance
|
* @param[in] instance loader instance
|
||||||
* @param[in] name application name or id
|
* @param[in] name application name or id
|
||||||
* @param[in] args application arguments
|
* @param[in] args application arguments
|
||||||
* @return LoaderStatus
|
* @return LoaderStatus
|
||||||
*/
|
*/
|
||||||
LoaderStatus loader_start_with_gui_error(Loader* loader, const char* name, const char* args);
|
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
|
* @brief Lock application start
|
||||||
* @param[in] instance loader instance
|
* @param[in] instance loader instance
|
||||||
* @return true on success
|
* @return true on success
|
||||||
|
|
|
@ -30,6 +30,7 @@ typedef enum {
|
||||||
LoaderMessageTypeLock,
|
LoaderMessageTypeLock,
|
||||||
LoaderMessageTypeUnlock,
|
LoaderMessageTypeUnlock,
|
||||||
LoaderMessageTypeIsLocked,
|
LoaderMessageTypeIsLocked,
|
||||||
|
LoaderMessageTypeStartByNameDetachedWithGuiError,
|
||||||
} LoaderMessageType;
|
} LoaderMessageType;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
entry,status,name,type,params
|
entry,status,name,type,params
|
||||||
Version,+,60.5,,
|
Version,+,60.6,,
|
||||||
Header,+,applications/services/bt/bt_service/bt.h,,
|
Header,+,applications/services/bt/bt_service/bt.h,,
|
||||||
Header,+,applications/services/cli/cli.h,,
|
Header,+,applications/services/cli/cli.h,,
|
||||||
Header,+,applications/services/cli/cli_vcp.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_lock,_Bool,Loader*
|
||||||
Function,+,loader_show_menu,void,Loader*
|
Function,+,loader_show_menu,void,Loader*
|
||||||
Function,+,loader_start,LoaderStatus,"Loader*, const char*, const char*, FuriString*"
|
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_start_with_gui_error,LoaderStatus,"Loader*, const char*, const char*"
|
||||||
Function,+,loader_unlock,void,Loader*
|
Function,+,loader_unlock,void,Loader*
|
||||||
Function,+,loading_alloc,Loading*,
|
Function,+,loading_alloc,Loading*,
|
||||||
|
|
|
|
@ -1,5 +1,5 @@
|
||||||
entry,status,name,type,params
|
entry,status,name,type,params
|
||||||
Version,+,60.5,,
|
Version,+,60.6,,
|
||||||
Header,+,applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h,,
|
Header,+,applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h,,
|
||||||
Header,+,applications/services/bt/bt_service/bt.h,,
|
Header,+,applications/services/bt/bt_service/bt.h,,
|
||||||
Header,+,applications/services/cli/cli.h,,
|
Header,+,applications/services/cli/cli.h,,
|
||||||
|
@ -2139,6 +2139,7 @@ Function,+,loader_is_locked,_Bool,Loader*
|
||||||
Function,+,loader_lock,_Bool,Loader*
|
Function,+,loader_lock,_Bool,Loader*
|
||||||
Function,+,loader_show_menu,void,Loader*
|
Function,+,loader_show_menu,void,Loader*
|
||||||
Function,+,loader_start,LoaderStatus,"Loader*, const char*, const char*, FuriString*"
|
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_start_with_gui_error,LoaderStatus,"Loader*, const char*, const char*"
|
||||||
Function,+,loader_unlock,void,Loader*
|
Function,+,loader_unlock,void,Loader*
|
||||||
Function,+,loading_alloc,Loading*,
|
Function,+,loading_alloc,Loading*,
|
||||||
|
|
|
Loading…
Reference in a new issue