SDL
SDL copied to clipboard
Android: `SDL_GetPathInfo` doesn't default to "assets" like other file functions.
The following line will return false, to suggest the file doesn't exist:
SDL_GetPathInfo("example.text", 0);
However, the following line will work, because the file does exist:
SDL_LoadFile("example.text", 0);
The file is in \app\src\main\assets, which seems to be the default for many file operations, but not SDL_GetPathInfo, maybe? Is it unreasonable to assume it should default to assets without a full path specified?
Yeah, that seems like a bug.
Okay, so this happens because SDL_LoadFile is backed by SDL_IOFromFile, which has a ton of Android-specific code.
But SDL_GetPathInfo() is just calling POSIX functions on Android.
So fixing this probably means rolling a bunch of Android code to use AAssetManager in some cases, and POSIX in others.
It's doable, but it's not gonna make it for 3.2.16.
That's fair. It's not a deal breaker because there are plenty of ways around it.
Should we put a note in so it doesn't trip anyone up?
Or, how easy would it be to just insert the current path if a relative path is detected?
SDL_GetPathInfo returns with false and error "Can't stat: No such file or directory" for files selected using SDL_ShowOpenFileDialog as well (and can be loaded successfully using SDL_LoadFile), so it seems that is not working in general.
Okay, this is pushed to main: 515433aa8a8fdeb0be4d0e2e1ee733ad16fc7d6e
It works like SDL_IOStream: it'll try real filesystem accesses, and if that doesn't work out, it'll try the AssetManager. Assets don't have file times, so they always come back as zero in SDL_GetPathInfo() in this case, but I assume most things just want file size and type anyhow.
If it's possible, can you make sure this works for your app before I cherry-pick it over to release-3.2.x?
Only now looking at this, apologise for delay. This still isn't behaving as expected. SDL_GetPathInfo("anything", null) is returning true for everything.
Stepping through the code in SDL_android.c's Android_JNI_GetAssetPathInfo. In the following code, AAssetManager_openDir returns a valid AAssetDir object (not null) even if path isn't a path:
// this is sort of messy, but there isn't a stat()-like interface to the Assets.
AAssetDir *adir = AAssetManager_openDir(asset_manager, path);
if (adir) { // it's a directory!
AAssetDir_close(adir);
info->type = SDL_PATHTYPE_DIRECTORY;
info->size = 0;
return true;
}
Ugh, okay.
Sure enough, it never returns NULL:
https://android.googlesource.com/platform/frameworks/base/+/master/native/android/asset_manager.cpp#94
Okay, so it looks like AAssetManager_open() will return NULL, so we can flip this to look for files first, and directories second, and then check if the directory is empty (AAssetDir_getNextFileName returns NULL)...if empty, we assume the directory doesn't exist.
This isn't perfect, but it's probably good enough...?
(Notably: this never returns NULL because asset dirs are a union of multiple .zip files that might each have the same directory.)
Okay, try the latest in main and see if it works for you!
Sorry, you seem to get all the nice bug-fixes 🤣. Yes, that's done the trick, thank you. Tested exists functionality in assets, and full paths. Shame about empty directories, but looks like the best it's going to be.