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
Android: Use storage access framework for custom SD card paths #9221
Conversation
8dc013b
to
68ed2ad
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm able to set any file to the SD Card Path now. If we can't limit what is selectable in SAF, perhaps we should add checks after retrieving the file to see if the extension is expected?
|
Also, the path returned by SAF is different from what Dolphin uses for default paths (although they target the same file). Is it possible to convert the path returned by SAF to match the default paths? If not, the default paths could be changed to match what SAF returns, although this may require making the default paths Android-specific. |
I could add a check afterwards, but it seems like there are some content providers where the URIs don't actually contain filename extensions, like Google Drive. So I would be shutting those out by adding a check as far as I understand it. Perhaps there are also cases where you would want to name the extension something other than (For what it's worth, I don't expect Google Drive to have good performance...)
I don't believe there is a reliable way to do this.
I don't believe there is a reliable way to do this either. I don't think that the paths not matching will cause any problems in practice, though. |
I can't look into this right now but is there a native way to tell if the file is actually a virtual SD card? I'd prefer that check over the warning but your suggestion sounds good if that isn't feasible. My other previous concerns were minor and can be ignored / deferred. |
Well, you could look at the part of the URI that specifies which storage provider is being used, but that's hacky and might break in the future and will likely make us shut out storage providers that otherwise would work fine. So I think I'll go with my warning. |
I was thinking about something within the file that identifies it as a virtual SD card. But if that check doesn't already exist in C++ then the warning will be the least worst option. |
|
Oh, sorry, I thought you meant an actual SD card that you put in your phone rather than an SD card file... No, the C++ code doesn't make any assumptions about what data is in a virtual SD card. It's up to the emulated console to do that. |
68ed2ad
to
abba902
Compare
|
Warning added. |
552ee54
to
56b148e
Compare
|
SAF is such a pain... The path of a valid virtual SD card saved by SAF causes a SIGABRT on current master when trying to load a game through Gecko OS. This creates yet another thing to account for when bisecting. Any ideas on preventing this? |
|
A SIGABRT in this PR occured when attempting to load the virtual SD card with Gecko OS.
|
|
Regarding your first crash, I can't retroactively fix the current version of master. The fix is in the "Android: Make the handling of SAF open modes more robust" commit. (For what it's worth, if you use a version of Dolphin that's a few months old, back when Regarding your second crash, that looks pretty weird. I'll try to see if I can reproduce it. |
|
I've added a commit that should fix the second crash. Please test it. |
This is part of my efforts to add support for scoped storage.
0cdbc01
to
e8fdc6a
Compare
e8fdc6a
to
6df543f
Compare
I had a feeling that was the case. I guess we can't do anything more about it.
Instead of not reading from files that raise a |
I'm not aware of any way to do that other than opening the file picker and hoping the user selects the right file, which would be a rather annoying prompt to get at startup.
It's the permission for the specific file. The point of scoped storage is that the user grants permissions on a file-by-file basis. |
|
I should make looking into the specific details of scoped storage a higher priority... Re-requesting the user to select a SD file path sounds like a better option than needing to look at logs to figure out that permission hasn't been granted. How about after running Dolphin's permission checks, run another check to see if we have permission to access the SD card file. If not, alert the user something along the lines of "Dolphin needs permission to access the SD card file. Please select an SD card file.", then open the SAF. Alternatively, this could be done at emulation startup but switching activities during startup may cause more surface destruction issues. |
|
What do you think about just turning the "couldn't open SD card" log message into a panic alert? That way it's clear to the user that something is wrong, but you wouldn't be bothered as soon as the app starts. |
|
I think we should still give the user the ability to set a path without searching for the path in settings if they don't have permission to access their SD card file. What about my previous suggestion except instead of running the check at startup, we run it right before calling the emulation activity (after the user has selected a game). That should address both of our concerns. |
|
I think sending the user straight to the file picker is going to be annoying once we start using SAF for more settings than just the SD card, as the user then would get prompted several times in a row and might not remember which prompt is for which path once the file picker is open (as we can't show any custom UI inside the file picker to remind the user which path they're currently selecting). What do you think about this: If any path in the settings is set to something which is inaccessible (either because it doesn't exist or because of permission reasons), Dolphin asks the user if they want to go to the paths settings when trying to start emulation. In the paths settings, the paths which are inaccessible are highlighted in red so you have a quick overview of what needs to be fixed. This would also make it possible for the user to reset the paths if they would prefer that. |
SGTM |
|
Actually, I shouldn't check for both if it doesn't exist and if we don't have permission, only if we don't have permission. The core will automatically create a 128 MiB SD card image for you if there is none already. Guess I'll have to look up specifically how to check whether we have permission to access a certain file which may or may not exist... |
|
The documentation isn't fantastic on this subject. If all else fails I think we could stick with catching |
|
Actually, it seems like SAF won't let us recreate something we have been granted permission to directly (as opposed to something we have been granted permission to through a parent directory). So we should flag SAF URIs which point to something which doesn't exist. |
|
Sorry if I'm missing something obvious. I haven't looked into this in too much detail but I see we currently request https://developer.android.com/reference/android/Manifest.permission#WRITE_EXTERNAL_STORAGE This permission seems more broad: https://developer.android.com/reference/android/Manifest.permission#MANAGE_EXTERNAL_STORAGE It might be worth looking into seeing if
Sounds worth trying. |
|
|
A "trick" that I see on various SAF-enabled apps is generating a toast message with a reasonably long timeout duration right before calling the File Picker, as the toast will remain on top even after switching activities. It's not an ideal approach as the toast will inevitably be gone after some time, but given the constraints it might still be better than nothing... |
|
I don't know if this is valid but I think we could justify that SAF isn't sufficient because https://developer.android.com/guide/topics/providers/document-provider says: "Documents can be either an openable file (with a specific MIME type), or a directory containing additional documents (with the MIME_TYPE_DIR MIME type)." The files we deal with aren't recognized as a specific MIME type but we want to manipulate them in all of the ways mentioned in the "Document management apps" case for It might be worth requesting this permission if it hasn't already been tried. |
|
The files we want to open do get assigned a MIME type, it's just that the MIME type is uselessly vague. So this only stops us from being able to filter files in the file picker in a useful way, not from opening and otherwise dealing with files. Personally, I'm not willing to go through trying to request this permission from Google, partially because I don't think they'll allow it and partially because I think it's possible to use SAF to make something which is good enough. The only use case that's noticeably impacted so far is reinstalling Dolphin, which is not something the typical user does often. |
|
Ok, a useless MIME type is still a problem that our old file picker didn't need to worry about. Losing the ability to filter files means we need to rely on users to select a valid file, which will definitely lead to problems if they ignore our warning alertmessage. We have the ability to set custom paths for files too, which further complicates our file access permission needs. This will likely create problems down the road when trying to load a path (such as a SD file) from custom game settings that a user will need to resolve. From what I've read it sounds like Dolphin could be considered for |
|
Keep in mind that the core functionality of Dolphin is to run games, and it seems like the core functionality is what Google looks at for determining if we can get an exception. Selecting a game of the wrong file type will just lead to nothing showing up in the game list (if picking a folder) or the game failing to boot (if picking a single game). (This is why I created PR #9229, by the way.) Setting custom paths for the SD card and such is not really something I think they would consider to be core functionality. I do agree that there are annoyances with SAF, but I don't think they are major enough that Google would grant us an exception.
I have no more access to the Google Play Console than you do. |
|
Under the exceptions section of https://support.google.com/googleplay/android-developer/answer/9956427?hl=en: "1. Use of the permission enables the app’s core functionality..." The user will eventually need to pick a directory or file, which will enable Dolphin to launch a game (our core functionality). This is why I think Dolphin qualifies for this. Since their SAF is making our core functionality unnecessarily more complicated, I see no reason not to request Unless I'm missing something about the permissions update process I think this could save both of us time in the future and filling out a form is a small potential waste of time. I don't want to ping the person with Google Play Console access until I've made a convincing argument for But again, if you still think this is a bad idea I'll drop it. |
|
According to that section, SAF would need to have a "substantially detrimental impact" on the core functionality in order for them to grant us an exception. I don't believe something as minor as not being able to filter by file name extension is something that Google would count. Keep in mind that they're treating this as a "high risk or sensitive permission" – it's not something they're happy to hand out to anyone who wants it. Also, using SAF does actually have benefits such as being able to run games from an SD card, so using SAF instead of For the reference, I believe delroth has access to the Google Play Console for Dolphin. |
|
Regarding saving us time, I've actually already implemented full SAF support for the game list in a separate branch which I will create a PR for once this is merged. |
Failing to boot a game from picking an incorrect file could be argued as a "substantially detrimental impact".
I can run games from a physical SD card on master. I don't understand this point. |
I really don't think so. We can display an error message saying that the file isn't supported, and the user can easily pick a new file. It's a very small inconvenience for the user, not a substantial one.
Oh, huh, I thought it didn't work at all in master... Maybe it's something like it only works on certain phones then? I do remember reading something about SAF letting you access SD cards in a way that normal file access doesn't, but I must admit I've never tested it myself in master. EDIT: Perhaps it was that you need SAF if you want to write to the SD card. If so, you can ignore what I said about SD cards. |
I guess I can justify gaining the ability to write to the SD card worth the sacrifice of bisecting inconveniences. Oh well, at least we learned something from this. |
|
I have now added the warning about unavailable paths that we discussed earlier. |
42dc794
to
7d81f34
Compare
Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/FileBrowserHelper.java
Show resolved
Hide resolved
7d81f34
to
765f0b2
Compare
Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/FileBrowserHelper.java
Show resolved
Hide resolved
|
Otherwise, LGTM. |
Content URIs stop working if Dolphin loses permissions, which happens for instance when reinstalling Dolphin.
765f0b2
to
161f8c3
Compare
This is part of my efforts to add support for scoped storage.