[FL-1308] Add API for starting applications with arguments (#486)
* app-loader: add API for starting applications with arguments * app-loader: add check if application is running * archive: rework starting app with app-loader API Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
		
							parent
							
								
									1cfb16d9a7
								
							
						
					
					
						commit
						63e9207c44
					
				
							
								
								
									
										70
									
								
								applications/app-loader/app-loader.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										70
									
								
								applications/app-loader/app-loader.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							| @ -1,14 +1,11 @@ | ||||
| #include <furi.h> | ||||
| #include <cli/cli.h> | ||||
| #include "menu/menu.h" | ||||
| #include "menu/menu_item.h" | ||||
| #include "applications.h" | ||||
| #include <assets_icons.h> | ||||
| #include <api-hal.h> | ||||
| #include "app-loader.h" | ||||
| 
 | ||||
| #define APP_LOADER_TAG "app_loader" | ||||
| 
 | ||||
| typedef struct { | ||||
|     FuriThread* thread; | ||||
|     const FlipperApplication* current_app; | ||||
|     string_t args; | ||||
|     Cli* cli; | ||||
| } AppLoaderState; | ||||
| 
 | ||||
| @ -21,10 +18,14 @@ static void app_loader_menu_callback(void* _ctx) { | ||||
|     const FlipperApplication* flipper_app = (FlipperApplication*)_ctx; | ||||
|     furi_assert(flipper_app->app); | ||||
|     furi_assert(flipper_app->name); | ||||
| 
 | ||||
|     if(furi_thread_get_state(state.thread) != FuriThreadStateStopped) { | ||||
|         FURI_LOG_E(APP_LOADER_TAG, "Can't start app. %s is running", state.current_app->name); | ||||
|         return; | ||||
|     } | ||||
|     api_hal_power_insomnia_enter(); | ||||
| 
 | ||||
|     state.current_app = flipper_app; | ||||
| 
 | ||||
|     FURI_LOG_I(APP_LOADER_TAG, "Starting furi application: %s", state.current_app->name); | ||||
|     furi_thread_set_name(state.thread, flipper_app->name); | ||||
|     furi_thread_set_stack_size(state.thread, flipper_app->stack_size); | ||||
|     furi_thread_set_callback(state.thread, flipper_app->app); | ||||
| @ -37,19 +38,55 @@ static void app_loader_cli_callback(Cli* cli, string_t args, void* _ctx) { | ||||
|     furi_assert(flipper_app->app); | ||||
|     furi_assert(flipper_app->name); | ||||
| 
 | ||||
|     if(!(furi_thread_get_state(state.thread) == FuriThreadStateStopped)) { | ||||
|     if(furi_thread_get_state(state.thread) != FuriThreadStateStopped) { | ||||
|         printf("Can't start, furi application is running"); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     printf("Starting furi application %s", flipper_app->name); | ||||
|     api_hal_power_insomnia_enter(); | ||||
|     state.current_app = flipper_app; | ||||
|     printf("Starting furi application %s", state.current_app->name); | ||||
|     furi_thread_set_name(state.thread, flipper_app->name); | ||||
|     furi_thread_set_stack_size(state.thread, flipper_app->stack_size); | ||||
|     furi_thread_set_callback(state.thread, flipper_app->app); | ||||
|     furi_thread_start(state.thread); | ||||
| } | ||||
| 
 | ||||
| bool app_loader_start(const char* name, const char* args) { | ||||
|     furi_assert(name); | ||||
| 
 | ||||
|     const FlipperApplication* flipper_app = NULL; | ||||
|     // Search for application
 | ||||
|     for(size_t i = 0; i < FLIPPER_APPS_COUNT; i++) { | ||||
|         if(!strcmp(FLIPPER_APPS[i].name, name)) { | ||||
|             flipper_app = &FLIPPER_APPS[i]; | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
|     if(!flipper_app) { | ||||
|         FURI_LOG_E(APP_LOADER_TAG, "Can't find application with name %s", name); | ||||
|         return false; | ||||
|     } | ||||
|     if(furi_thread_get_state(state.thread) != FuriThreadStateStopped) { | ||||
|         FURI_LOG_E(APP_LOADER_TAG, "Can't start app. %s is running", state.current_app->name); | ||||
|         return false; | ||||
|     } | ||||
|     state.current_app = flipper_app; | ||||
|     if(args) { | ||||
|         string_set_str(state.args, args); | ||||
|         string_strim(state.args); | ||||
|         FURI_LOG_I(APP_LOADER_TAG, "Start %s app with args: %s", name, args); | ||||
|     } else { | ||||
|         string_clean(state.args); | ||||
|         FURI_LOG_I(APP_LOADER_TAG, "Start %s app with no args", name); | ||||
|     } | ||||
|     furi_thread_set_name(state.thread, flipper_app->name); | ||||
|     furi_thread_set_stack_size(state.thread, flipper_app->stack_size); | ||||
|     furi_thread_set_context(state.thread, (void*)string_get_cstr(state.args)); | ||||
|     furi_thread_set_callback(state.thread, flipper_app->app); | ||||
|     return furi_thread_start(state.thread); | ||||
| } | ||||
| 
 | ||||
| void app_loader_thread_state_callback(FuriThreadState state, void* context) { | ||||
|     furi_assert(context); | ||||
|     if(state == FuriThreadStateStopped) { | ||||
| @ -58,16 +95,17 @@ void app_loader_thread_state_callback(FuriThreadState state, void* context) { | ||||
| } | ||||
| 
 | ||||
| int32_t app_loader(void* p) { | ||||
|     FURI_LOG_I("app-loader", "Starting"); | ||||
|     FURI_LOG_I(APP_LOADER_TAG, "Starting"); | ||||
|     state.thread = furi_thread_alloc(); | ||||
|     furi_thread_set_state_context(state.thread, &state); | ||||
|     furi_thread_set_state_callback(state.thread, app_loader_thread_state_callback); | ||||
|     string_init(state.args); | ||||
| 
 | ||||
|     ValueMutex* menu_mutex = furi_record_open("menu"); | ||||
|     state.cli = furi_record_open("cli"); | ||||
| 
 | ||||
|     // Main menu
 | ||||
|     FURI_LOG_I("app-loader", "Building main menu"); | ||||
|     FURI_LOG_I(APP_LOADER_TAG, "Building main menu"); | ||||
|     with_value_mutex( | ||||
|         menu_mutex, (Menu * menu) { | ||||
|             for(size_t i = 0; i < FLIPPER_APPS_COUNT; i++) { | ||||
| @ -94,7 +132,7 @@ int32_t app_loader(void* p) { | ||||
|         }); | ||||
| 
 | ||||
|     // Plugins
 | ||||
|     FURI_LOG_I("app-loader", "Building plugins menu"); | ||||
|     FURI_LOG_I(APP_LOADER_TAG, "Building plugins menu"); | ||||
|     with_value_mutex( | ||||
|         menu_mutex, (Menu * menu) { | ||||
|             MenuItem* menu_plugins = | ||||
| @ -126,7 +164,7 @@ int32_t app_loader(void* p) { | ||||
|         }); | ||||
| 
 | ||||
|     // Debug
 | ||||
|     FURI_LOG_I("app-loader", "Building debug menu"); | ||||
|     FURI_LOG_I(APP_LOADER_TAG, "Building debug menu"); | ||||
|     with_value_mutex( | ||||
|         menu_mutex, (Menu * menu) { | ||||
|             MenuItem* menu_debug = | ||||
| @ -162,7 +200,7 @@ int32_t app_loader(void* p) { | ||||
|         (*FLIPPER_ON_SYSTEM_START[i])(); | ||||
|     } | ||||
| 
 | ||||
|     FURI_LOG_I("app-loader", "Started"); | ||||
|     FURI_LOG_I(APP_LOADER_TAG, "Started"); | ||||
| 
 | ||||
|     while(1) { | ||||
|         osThreadSuspend(osThreadGetId()); | ||||
|  | ||||
							
								
								
									
										15
									
								
								applications/app-loader/app-loader.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								applications/app-loader/app-loader.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,15 @@ | ||||
| #include <furi.h> | ||||
| #include <cli/cli.h> | ||||
| #include "menu/menu.h" | ||||
| #include "menu/menu_item.h" | ||||
| #include "applications.h" | ||||
| #include <assets_icons.h> | ||||
| #include <api-hal.h> | ||||
| 
 | ||||
| /**
 | ||||
|  * Start application | ||||
|  * @param name - application name | ||||
|  * @param args - application arguments | ||||
|  * @retval true on success | ||||
|  */ | ||||
| bool app_loader_start(const char* name, const char* args); | ||||
| @ -290,21 +290,11 @@ static void archive_close_file_menu(ArchiveApp* archive) { | ||||
|     view_commit_model(archive->view_archive_main, true); | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| archive_open_app(ArchiveApp* archive, const FlipperApplication* flipper_app, void* arg) { | ||||
| static void archive_open_app(ArchiveApp* archive, const char* app_name, const char* args) { | ||||
|     furi_assert(archive); | ||||
|     furi_assert(flipper_app); | ||||
|     furi_assert(flipper_app->app); | ||||
|     furi_assert(flipper_app->name); | ||||
|     furi_assert(app_name); | ||||
| 
 | ||||
|     if(arg) { | ||||
|         // pass path to app?
 | ||||
|     } | ||||
| 
 | ||||
|     furi_thread_set_name(archive->app_thread, flipper_app->name); | ||||
|     furi_thread_set_stack_size(archive->app_thread, flipper_app->stack_size); | ||||
|     furi_thread_set_callback(archive->app_thread, flipper_app->app); | ||||
|     furi_thread_start(archive->app_thread); | ||||
|     app_loader_start(app_name, args); | ||||
| } | ||||
| 
 | ||||
| static void archive_delete_file(ArchiveApp* archive, string_t name) { | ||||
| @ -339,7 +329,8 @@ static void archive_file_menu_callback(ArchiveApp* archive) { | ||||
|     switch(model->menu_idx) { | ||||
|     case 0: | ||||
|         if((selected->type != ArchiveFileTypeFolder && selected->type != ArchiveFileTypeUnknown)) { | ||||
|             archive_open_app(archive, &FLIPPER_APPS[selected->type], NULL); | ||||
|             archive_open_app( | ||||
|                 archive, flipper_app_name[selected->type], string_get_cstr(selected->name)); | ||||
|         } | ||||
|         break; | ||||
|     case 1: | ||||
|  | ||||
| @ -6,6 +6,7 @@ | ||||
| #include <gui/gui_i.h> | ||||
| #include <gui/view_dispatcher.h> | ||||
| #include <gui/modules/text_input.h> | ||||
| #include <app-loader/app-loader.h> | ||||
| 
 | ||||
| #include <m-string.h> | ||||
| #include <m-array.h> | ||||
| @ -33,6 +34,14 @@ typedef enum { | ||||
|     ArchiveTabTotal, | ||||
| } ArchiveTabEnum; | ||||
| 
 | ||||
| static const char* flipper_app_name[] = { | ||||
|     [ArchiveFileTypeIButton] = "iButton", | ||||
|     [ArchiveFileTypeNFC] = "NFC", | ||||
|     [ArchiveFileTypeSubOne] = "Sub-1 GHz", | ||||
|     [ArchiveFileTypeLFRFID] = "125 kHz RFID", | ||||
|     [ArchiveFileTypeIrda] = "Infrared", | ||||
| }; | ||||
| 
 | ||||
| static const char* known_ext[] = { | ||||
|     [ArchiveFileTypeIButton] = ".ibtn", | ||||
|     [ArchiveFileTypeNFC] = ".nfc", | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 gornekich
						gornekich