[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:
Sergey Gavrilov
2023-03-01 20:57:27 +03:00
committed by GitHub
parent 9ae58f5462
commit 777a4d109d
52 changed files with 871 additions and 577 deletions

View File

@@ -39,12 +39,6 @@
.file = file, \
}};
#define S_API_DATA_PATH \
SAData data = { \
.path = { \
.path = path, \
}};
#define S_RETURN_BOOL (return_data.bool_value);
#define S_RETURN_UINT16 (return_data.uint16_value);
#define S_RETURN_UINT64 (return_data.uint64_value);
@@ -70,6 +64,7 @@ static bool storage_file_open_internal(
.path = path,
.access_mode = access_mode,
.open_mode = open_mode,
.thread_id = furi_thread_get_current_id(),
}};
file->type = FileTypeOpenFile;
@@ -249,7 +244,7 @@ bool storage_file_exists(Storage* storage, const char* path) {
FileInfo fileinfo;
FS_Error error = storage_common_stat(storage, path, &fileinfo);
if(error == FSE_OK && !(fileinfo.flags & FSF_DIRECTORY)) {
if(error == FSE_OK && !file_info_is_dir(&fileinfo)) {
exist = true;
}
@@ -266,6 +261,7 @@ static bool storage_dir_open_internal(File* file, const char* path) {
.dopen = {
.file = file,
.path = path,
.thread_id = furi_thread_get_current_id(),
}};
file->type = FileTypeOpenDir;
@@ -349,12 +345,28 @@ bool storage_dir_rewind(File* file) {
return S_RETURN_BOOL;
}
bool storage_dir_exists(Storage* storage, const char* path) {
bool exist = false;
FileInfo fileinfo;
FS_Error error = storage_common_stat(storage, path, &fileinfo);
if(error == FSE_OK && file_info_is_dir(&fileinfo)) {
exist = true;
}
return exist;
}
/****************** COMMON ******************/
FS_Error storage_common_timestamp(Storage* storage, const char* path, uint32_t* timestamp) {
S_API_PROLOGUE;
SAData data = {.ctimestamp = {.path = path, .timestamp = timestamp}};
SAData data = {
.ctimestamp = {
.path = path,
.timestamp = timestamp,
.thread_id = furi_thread_get_current_id(),
}};
S_API_MESSAGE(StorageCommandCommonTimestamp);
S_API_EPILOGUE;
@@ -363,8 +375,12 @@ FS_Error storage_common_timestamp(Storage* storage, const char* path, uint32_t*
FS_Error storage_common_stat(Storage* storage, const char* path, FileInfo* fileinfo) {
S_API_PROLOGUE;
SAData data = {.cstat = {.path = path, .fileinfo = fileinfo}};
SAData data = {
.cstat = {
.path = path,
.fileinfo = fileinfo,
.thread_id = furi_thread_get_current_id(),
}};
S_API_MESSAGE(StorageCommandCommonStat);
S_API_EPILOGUE;
@@ -373,7 +389,12 @@ FS_Error storage_common_stat(Storage* storage, const char* path, FileInfo* filei
FS_Error storage_common_remove(Storage* storage, const char* path) {
S_API_PROLOGUE;
S_API_DATA_PATH;
SAData data = {
.path = {
.path = path,
.thread_id = furi_thread_get_current_id(),
}};
S_API_MESSAGE(StorageCommandCommonRemove);
S_API_EPILOGUE;
return S_RETURN_ERROR;
@@ -423,7 +444,7 @@ static FS_Error
furi_string_right(path, strlen(old_path));
furi_string_printf(tmp_new_path, "%s%s", new_path, furi_string_get_cstr(path));
if(fileinfo.flags & FSF_DIRECTORY) {
if(file_info_is_dir(&fileinfo)) {
error = storage_common_mkdir(storage, furi_string_get_cstr(tmp_new_path));
} else {
error = storage_common_copy(
@@ -452,7 +473,7 @@ FS_Error storage_common_copy(Storage* storage, const char* old_path, const char*
error = storage_common_stat(storage, old_path, &fileinfo);
if(error == FSE_OK) {
if(fileinfo.flags & FSF_DIRECTORY) {
if(file_info_is_dir(&fileinfo)) {
error = storage_copy_recursive(storage, old_path, new_path);
} else {
Stream* stream_from = file_stream_alloc(storage);
@@ -479,7 +500,7 @@ FS_Error storage_common_copy(Storage* storage, const char* old_path, const char*
static FS_Error
storage_merge_recursive(Storage* storage, const char* old_path, const char* new_path) {
FS_Error error = storage_common_mkdir(storage, new_path);
FS_Error error = FSE_OK;
DirWalk* dir_walk = dir_walk_alloc(storage);
FuriString *path, *file_basename, *tmp_new_path;
FileInfo fileinfo;
@@ -488,7 +509,7 @@ static FS_Error
tmp_new_path = furi_string_alloc();
do {
if((error != FSE_OK) && (error != FSE_EXIST)) break;
if(!storage_simply_mkdir(storage, new_path)) break;
dir_walk_set_recursive(dir_walk, false);
if(!dir_walk_open(dir_walk, old_path)) {
@@ -508,13 +529,13 @@ static FS_Error
path_extract_basename(furi_string_get_cstr(path), file_basename);
path_concat(new_path, furi_string_get_cstr(file_basename), tmp_new_path);
if(fileinfo.flags & FSF_DIRECTORY) {
if(file_info_is_dir(&fileinfo)) {
if(storage_common_stat(
storage, furi_string_get_cstr(tmp_new_path), &fileinfo) == FSE_OK) {
if(fileinfo.flags & FSF_DIRECTORY) {
if(file_info_is_dir(&fileinfo)) {
error =
storage_common_mkdir(storage, furi_string_get_cstr(tmp_new_path));
if(error != FSE_OK) {
if(error != FSE_OK && error != FSE_EXIST) {
break;
}
}
@@ -548,7 +569,7 @@ FS_Error storage_common_merge(Storage* storage, const char* old_path, const char
error = storage_common_stat(storage, old_path, &fileinfo);
if(error == FSE_OK) {
if(fileinfo.flags & FSF_DIRECTORY) {
if(file_info_is_dir(&fileinfo)) {
error = storage_merge_recursive(storage, old_path, new_path);
} else {
error = storage_common_stat(storage, new_path, &fileinfo);
@@ -556,7 +577,7 @@ FS_Error storage_common_merge(Storage* storage, const char* old_path, const char
furi_string_set(new_path_next, new_path);
FuriString* dir_path;
FuriString* filename;
char extension[MAX_EXT_LEN];
char extension[MAX_EXT_LEN] = {0};
dir_path = furi_string_alloc();
filename = furi_string_alloc();
@@ -608,7 +629,12 @@ FS_Error storage_common_merge(Storage* storage, const char* old_path, const char
FS_Error storage_common_mkdir(Storage* storage, const char* path) {
S_API_PROLOGUE;
S_API_DATA_PATH;
SAData data = {
.path = {
.path = path,
.thread_id = furi_thread_get_current_id(),
}};
S_API_MESSAGE(StorageCommandCommonMkDir);
S_API_EPILOGUE;
return S_RETURN_ERROR;
@@ -626,6 +652,7 @@ FS_Error storage_common_fs_info(
.fs_path = fs_path,
.total_space = total_space,
.free_space = free_space,
.thread_id = furi_thread_get_current_id(),
}};
S_API_MESSAGE(StorageCommandCommonFSInfo);
@@ -633,6 +660,38 @@ FS_Error storage_common_fs_info(
return S_RETURN_ERROR;
}
void storage_common_resolve_path_and_ensure_app_directory(Storage* storage, FuriString* path) {
S_API_PROLOGUE;
SAData data = {
.cresolvepath = {
.path = path,
.thread_id = furi_thread_get_current_id(),
}};
S_API_MESSAGE(StorageCommandCommonResolvePath);
S_API_EPILOGUE;
}
FS_Error storage_common_migrate(Storage* storage, const char* source, const char* dest) {
if(!storage_common_exists(storage, source)) {
return FSE_OK;
}
FS_Error error = storage_common_merge(storage, source, dest);
if(error == FSE_OK) {
storage_simply_remove_recursive(storage, source);
}
return error;
}
bool storage_common_exists(Storage* storage, const char* path) {
FileInfo file_info;
return storage_common_stat(storage, path, &file_info) == FSE_OK;
}
/****************** ERROR ******************/
const char* storage_error_get_desc(FS_Error error_id) {
@@ -750,7 +809,7 @@ bool storage_simply_remove_recursive(Storage* storage, const char* path) {
}
while(storage_dir_read(dir, &fileinfo, name, MAX_NAME_LENGTH)) {
if(fileinfo.flags & FSF_DIRECTORY) {
if(file_info_is_dir(&fileinfo)) {
furi_string_cat_printf(cur_dir, "/%s", name);
go_deeper = true;
break;