Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compile-time APP_DATA_PATH() and APP_ASSETS_PATH() #3435

Draft
wants to merge 1 commit into
base: dev
Choose a base branch
from

Conversation

Willy-JL
Copy link
Contributor

@Willy-JL Willy-JL commented Feb 9, 2024

What's new

  • APP_DATA_PATH() and APP_ASSETS_PATH() use appid from compile time instead of runtime thread_id
  • Fixes incorrect paths when these app storage macros are used in timer / service context (eg. timer/draw callback)
  • Less runtime overhead due to less string replacing to generate correct paths
  • Code not compiled as FAP still falls back to /ext/apps_.../system as before
  • No user intervention required, this is drop in fix, only recompile is needed
  • To function, adds C define FURI_APPID, which is FAP appid or "system" outside FAP context, could be useful to app makers aswell

Verification

  • Open app that uses APP_DATA_PATH() or APP_ASSETS_PATH() in draw/timer callback
  • Path is still correct /ext/apps_.../appid, instead of ending as /ext/apps_.../system or /ext/apps_.../gui

Checklist (For Reviewer)

  • PR has description of feature/bug or link to Confluence/Jira task
  • Description contains actions to verify feature/bugfix
  • I've built this code, uploaded it to the device and verified feature/bugfix

@Willy-JL
Copy link
Contributor Author

Willy-JL commented Feb 9, 2024

Just occurred to me that this would need an equivalent in ufbt, I don't use that myself so I forgot... I can make a PR there as well if we go through with this PR

@hedger hedger added the Build System & Scripts fbt, scripts and toolchain-related label Feb 9, 2024
@hedger
Copy link
Member

hedger commented Feb 9, 2024

Thanks for the PR.
Overall, it's well-implemented. However, it has a certain side-effect.

Currently, if a .fap file is renamed or copied on the device, it gets a separate app data folder, according to its new file name. That way, you can create multiple isolated environments for a single app. However, there are no apps that would make use of that at the moment - at least to my knowledge. With current implementation from this PR, app is confined to its appid. Surely, that approach has its own benefits and enables a predictable file location.

This PR also introduces a system-wide define with "system" name at a fairly low level - maybe its scope could also be reduced to app loader level. I'll look into that and see whether that can be adjusted.

@Willy-JL
Copy link
Contributor Author

Willy-JL commented Feb 9, 2024

Agreed on the define in furi.h, the naming was rushed just to get something working lol. As you say yeah maybe Loader or Storage services could handle this. Before making this PR I had originally fully removed furi_thread_get_appid() since it wasn't really used elsewhere, so that's part of why I put it in furi.h, but then chose against removing it so here we are.

As for renaming .fap files, you make a very good point... at the very least then the behavior should be consistent for APP_ASSETS_PATH(). Currently, it extracts to folder based on fap filename, and then the app looks based on compiled appid... easiest solution I see would be making the assets extract to folder based on fap header appid, so after rename it is same folder path. The other option would be finding a way for loader to tell the app what it's appid is based on fap filename, but then we are back to the issue of threads, and it becomes overcomplicated i think.

@hedger hedger added the Core+Services HAL, furi & core system services label Feb 10, 2024
@Willy-JL
Copy link
Contributor Author

easiest solution I see would be making the assets extract to folder based on fap header appid, so after rename it is same folder path

i was looking around to implement this but realized that fap header has app name but not appid... not sure what the best idea would be then...

@skotopes
Copy link
Member

@Willy-JL Some proxy object that is initialized at the app start and got it name and then all your internal references goes to it. That is not something that should be on firmware side, but something that lives in app bss

@Willy-JL
Copy link
Contributor Author

so then APP_ASSETS_PATH() and APP_DATA_PATH() will remain half broken? and apps will need to make their own system?

or do you mean an alternative way of doing it that is not drop-in, but replaces the existing macros?

@Willy-JL
Copy link
Contributor Author

Willy-JL commented Feb 12, 2024

ah i think i get what you mean, i was unfamiliar with the concept of .bss... so then, at app launch, loader would initialize this global static variable that is located in bss with the app's id, and the app code references to it?

sounds like then we could provide helper macros that construct a path using this variable, but still not handled by firmware. like some sort of printf in app code that uses this appid variable, but inside a macro so app developers dontn eed to worry about the variable itself?

would mean this is not strictly drop-in, but close enough, same idea but using a printf or similar under the hood...

@skotopes
Copy link
Member

yep

@Willy-JL Willy-JL marked this pull request as draft February 14, 2024 10:35
@Willy-JL
Copy link
Contributor Author

im new to those concepts but ill try to figure something out, if you have some examples i could look at that would be greatly appreciated!

also i drafted for now, but ill perhaps close this and open a new pr when i have something working

@Willy-JL
Copy link
Contributor Author

Willy-JL commented Feb 22, 2024

@skotopes i was looking into how to implement this with bss, and had a counter argument.

i feel like the behavior of renaming a fap file changing storage location as @hedger described is quite weird. yes it has a very niche use case, but i think it instead leads to a lot more confusion for people messing around with faps installed manually, than the small advantages it provides.

instead, i was considering that maybe a better solution would be sticking with what i have in this PR thus far (save for moving where the define is made), so paths are defined at compile time (and backwards compatible with existing code), and instead add a new elf section (or attribute in fap header) for the appid, so that assets extractor doesnt need to rely on fap name and can instead use the same appid that was used at compile time to hardcode the paths.

this would fix the disjunction between runtime and compile time paths, as well as as avoid unnecessarily complex logic to store the appid in bss and construct paths on app side at runtime with printf. as well as be backwards compatible, requiring one simple recompile.

@CookiePLMonster
Copy link
Contributor

FWIW from the user's point of view this PR is worth it even for this

Fixes incorrect paths when these app storage macros are used in timer / service context (eg. timer/draw callback)

point alone.

@skotopes
Copy link
Member

Put implementation aside for a moment.

Do you guys feel like you want to have ability to have multiple app versions with isolated spaces or not?

@Willy-JL
Copy link
Contributor Author

While I see the value in that option in some niche use cases, to the average user it can be more of a pain when the app doesn't work as intended when they renamed a file. Say the download a fap, and they download it again on a newer version, but they didn't clean the downloads folder. Now it's appid (1).fap. Suddenly, the app lost all its configuration. The user doesn't even have the slightest indication why, since the app itself works, just the configuration is lost.

also, there's the point that compile time macros are easier to use. No need for furi strings or printf to insert appid at runtime, easier to use, and not a breaking change compared to current api.

Personally, I'm 100% for the option of compile time, appid is hardcoded in fap, not chosen by filename.

@Willy-JL
Copy link
Contributor Author

Also, I recently discovered there is compile time macro "FAP_VERSION". It only makes logical sense to offer "FAP_APPID". I wasn't aware at the time of making this PR, hence the "system" and "FURI_APPID". "FAP_APPID" would work great and be super intuitive, and "APP_DATA_PATH()" can rely on FAP_APPID then?

@skotopes
Copy link
Member

Ok, we'll discuss it with @hedger and @DrZlo13 today and then decide

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Build System & Scripts fbt, scripts and toolchain-related Core+Services HAL, furi & core system services
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants