[FL-3055] Getter for application data path (#2181)
* Threads: application id * Unit tests: appsdata getter test * Unit tests: moar test cases for appsdata getter * Unit tests: remove folders after test * Storage: dir_is_exist, migrate, + unit_tests * Plugins: migration * Storage: common_exists, moar unit_tests 4 "common_migrate", "common_migrate" and "common_merge" bugfixes * Storage: use FuriString for path handling * Storage API: send caller thread id with path * Storage: remove StorageType field in storage file list * Storage: simplify processing * Storage API: send caller thread id with path everywhere * Storage: /app alias, unit tests and path creation * Storage, path helper: remove unused * Examples: app data example * App plugins: use new VFS path * Storage: file_info_is_dir * Services: handle alias if the service accepts a path. * App plugins: fixes * Make PVS happy * Storage: fix storage_merge_recursive * Storage: rename process_aliases to resolve_path. Rename APPS_DATA to APP_DATA. * Apps: use predefined macro instead of raw paths. Example Apps Data: README fixes. * Storage: rename storage_common_resolve_path to storage_common_resolve_path_and_ensure_app_directory * Api: fix version * Storage: rename alias message * Storage: do not create app folders in path resolving process in certain cases. --------- Co-authored-by: Astra <93453568+Astrrra@users.noreply.github.com> Co-authored-by: Aleksandr Kutuzov <alleteam@gmail.com>
This commit is contained in:
		| @@ -35,6 +35,8 @@ struct FuriThread { | ||||
|     void* state_context; | ||||
|  | ||||
|     char* name; | ||||
|     char* appid; | ||||
|  | ||||
|     configSTACK_DEPTH_TYPE stack_size; | ||||
|     FuriThreadPriority priority; | ||||
|  | ||||
| @@ -122,11 +124,25 @@ FuriThread* furi_thread_alloc() { | ||||
|     thread->output.buffer = furi_string_alloc(); | ||||
|     thread->is_service = false; | ||||
|  | ||||
|     FuriThread* parent = NULL; | ||||
|     if(xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) { | ||||
|         // TLS is not available, if we called not from thread context | ||||
|         parent = pvTaskGetThreadLocalStoragePointer(NULL, 0); | ||||
|  | ||||
|         if(parent && parent->appid) { | ||||
|             furi_thread_set_appid(thread, parent->appid); | ||||
|         } else { | ||||
|             furi_thread_set_appid(thread, "unknown"); | ||||
|         } | ||||
|     } else { | ||||
|         // if scheduler is not started, we are starting driver thread | ||||
|         furi_thread_set_appid(thread, "driver"); | ||||
|     } | ||||
|  | ||||
|     FuriHalRtcHeapTrackMode mode = furi_hal_rtc_get_heap_track_mode(); | ||||
|     if(mode == FuriHalRtcHeapTrackModeAll) { | ||||
|         thread->heap_trace_enabled = true; | ||||
|     } else if(mode == FuriHalRtcHeapTrackModeTree && furi_thread_get_current_id()) { | ||||
|         FuriThread* parent = pvTaskGetThreadLocalStoragePointer(NULL, 0); | ||||
|         if(parent) thread->heap_trace_enabled = parent->heap_trace_enabled; | ||||
|     } else { | ||||
|         thread->heap_trace_enabled = false; | ||||
| @@ -153,6 +169,7 @@ void furi_thread_free(FuriThread* thread) { | ||||
|     furi_assert(thread->state == FuriThreadStateStopped); | ||||
|  | ||||
|     if(thread->name) free((void*)thread->name); | ||||
|     if(thread->appid) free((void*)thread->appid); | ||||
|     furi_string_free(thread->output.buffer); | ||||
|  | ||||
|     free(thread); | ||||
| @@ -165,6 +182,13 @@ void furi_thread_set_name(FuriThread* thread, const char* name) { | ||||
|     thread->name = name ? strdup(name) : NULL; | ||||
| } | ||||
|  | ||||
| void furi_thread_set_appid(FuriThread* thread, const char* appid) { | ||||
|     furi_assert(thread); | ||||
|     furi_assert(thread->state == FuriThreadStateStopped); | ||||
|     if(thread->appid) free((void*)thread->appid); | ||||
|     thread->appid = appid ? strdup(appid) : NULL; | ||||
| } | ||||
|  | ||||
| void furi_thread_mark_as_service(FuriThread* thread) { | ||||
|     thread->is_service = true; | ||||
| } | ||||
| @@ -498,6 +522,20 @@ const char* furi_thread_get_name(FuriThreadId thread_id) { | ||||
|     return (name); | ||||
| } | ||||
|  | ||||
| const char* furi_thread_get_appid(FuriThreadId thread_id) { | ||||
|     TaskHandle_t hTask = (TaskHandle_t)thread_id; | ||||
|     const char* appid = "system"; | ||||
|  | ||||
|     if(!FURI_IS_IRQ_MODE() && (hTask != NULL)) { | ||||
|         FuriThread* thread = (FuriThread*)pvTaskGetThreadLocalStoragePointer(hTask, 0); | ||||
|         if(thread) { | ||||
|             appid = thread->appid; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     return (appid); | ||||
| } | ||||
|  | ||||
| uint32_t furi_thread_get_stack_space(FuriThreadId thread_id) { | ||||
|     TaskHandle_t hTask = (TaskHandle_t)thread_id; | ||||
|     uint32_t sz; | ||||
|   | ||||
| @@ -87,6 +87,16 @@ void furi_thread_free(FuriThread* thread); | ||||
|  */ | ||||
| void furi_thread_set_name(FuriThread* thread, const char* name); | ||||
|  | ||||
| /** | ||||
|  * @brief Set FuriThread appid | ||||
|  * Technically, it is like a "process id", but it is not a system-wide unique identifier. | ||||
|  * All threads spawned by the same app will have the same appid. | ||||
|  *  | ||||
|  * @param thread  | ||||
|  * @param appid  | ||||
|  */ | ||||
| void furi_thread_set_appid(FuriThread* thread, const char* appid); | ||||
|  | ||||
| /** Mark thread as service | ||||
|  * The service cannot be stopped or removed, and cannot exit from the thread body | ||||
|  *  | ||||
| @@ -233,10 +243,37 @@ uint32_t furi_thread_flags_get(void); | ||||
|  | ||||
| uint32_t furi_thread_flags_wait(uint32_t flags, uint32_t options, uint32_t timeout); | ||||
|  | ||||
| /** | ||||
|  * @brief Enumerate threads | ||||
|  *  | ||||
|  * @param thread_array array of FuriThreadId, where thread ids will be stored | ||||
|  * @param array_items array size | ||||
|  * @return uint32_t threads count | ||||
|  */ | ||||
| uint32_t furi_thread_enumerate(FuriThreadId* thread_array, uint32_t array_items); | ||||
|  | ||||
| /** | ||||
|  * @brief Get thread name | ||||
|  *  | ||||
|  * @param thread_id  | ||||
|  * @return const char* name or NULL | ||||
|  */ | ||||
| const char* furi_thread_get_name(FuriThreadId thread_id); | ||||
|  | ||||
| /** | ||||
|  * @brief Get thread appid | ||||
|  *  | ||||
|  * @param thread_id  | ||||
|  * @return const char* appid | ||||
|  */ | ||||
| const char* furi_thread_get_appid(FuriThreadId thread_id); | ||||
|  | ||||
| /** | ||||
|  * @brief Get thread stack watermark | ||||
|  *  | ||||
|  * @param thread_id  | ||||
|  * @return uint32_t  | ||||
|  */ | ||||
| uint32_t furi_thread_get_stack_space(FuriThreadId thread_id); | ||||
|  | ||||
| /** Get STDOUT callback for thead | ||||
|   | ||||
| @@ -41,6 +41,7 @@ void flipper_init() { | ||||
|             FLIPPER_SERVICES[i].app, | ||||
|             NULL); | ||||
|         furi_thread_mark_as_service(thread); | ||||
|         furi_thread_set_appid(thread, FLIPPER_SERVICES[i].appid); | ||||
|  | ||||
|         furi_thread_start(thread); | ||||
|     } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user