Bug 447636 - Android 11: scoped storage does not allow to share the root of the filesystem
Summary: Android 11: scoped storage does not allow to share the root of the filesystem
Status: RESOLVED FIXED
Alias: None
Product: kdeconnect
Classification: Applications
Component: android-application (show other bugs)
Version: unspecified
Platform: Android Linux
: NOR normal
Target Milestone: ---
Assignee: Albert Vaca Cintora
URL:
Keywords: junior-jobs
: 439342 447774 (view as bug list)
Depends on:
Blocks:
 
Reported: 2021-12-29 11:04 UTC by Tobias Bora
Modified: 2023-09-03 02:05 UTC (History)
12 users (show)

See Also:
Latest Commit:
Version Fixed In: 1.24.0


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Tobias Bora 2021-12-29 11:04:37 UTC
SUMMARY

On Android 11, the new scoped storage system does not allow filesystem sharing starting from the root folder as the button to select this folder is greyed out and clicking on it outputs an error "To protect your private data, choose another folder".

One solution to avoid this issue would be to use the `MANAGE_EXTERNAL_STORAGE` permission to be able to access all files (this is used for instance by file managers). See more information here https://support.google.com/googleplay/android-developer/answer/10467955?hl=en&visit_id=637763723574032227-672946508&rd=1#zippy=%2Cexceptions%2Cinvalid-uses%2Calternatives-to-common-uses%2Cpermitted-uses-of-the-all-files-access-permission


STEPS TO REPRODUCE
1. Install KDE connect on an Android 11, phone and pair it with any device
2. Enable the "filesystem exposure" module (approximate translation), and add a new folder to share.
3. If you are not already at the root, navigate to the root folder of the internal memory of the device. Try to select this folder: button is greyed and pressing it gives the above error.

OBSERVED RESULT



EXPECTED RESULT

I expect filesystem exposure to work on any folder of my choice. Sharing a sub-folder is pretty useless as when I do a backup I want to backup everything, including files at the root.

SOFTWARE/OS VERSIONS
Android 11
Comment 1 Reuben 2022-01-29 05:57:06 UTC
I face the same issue. Was previously able to select root folder of my phone as mount point, but it doesn't allow anymore in Android 11.0.5.1 on a OnePlus 7T running OxygenOS. 
Kdeconnect app version: 1.19.1
Comment 2 Simon Redman 2022-05-04 12:17:31 UTC
*** Bug 439342 has been marked as a duplicate of this bug. ***
Comment 3 Simon Redman 2022-05-04 12:21:39 UTC
For reference of anyone working on this, here's the Android documentation link for MANAGE_EXTERNAL_STORAGE -- I suspect adding this permission will solve the issue described, though we will have to grovel to Google to let us continue publishing on the Play Store.
https://developer.android.com/training/data-storage/manage-all-files
Comment 4 Simon Redman 2022-05-04 12:26:58 UTC
Set the junior-jobs keyword since this is hopefully we simple as adding the permission and changing the intent action, both described in the documentation linked in my previous comment.
Comment 5 Varisht 2022-05-27 04:24:18 UTC
This bug affects Android 12 (Lineage OS 19.1 on Poco F1) as well. Dunno how I didn't encounter it on Android 11 (Lineage OS 18.1 on Poco F1), maybe because the permissions were carried over from my previous install. I recently did a fresh install of Lineage OS 19.1 on Poco F1 and encountered this bug there.
Comment 6 Andrew Gunnerson 2022-06-05 03:03:53 UTC
I was able to get it working with MANAGE_EXTERNAL_STORAGE, but it's not quite as simple as adding the permission to the manifest. Once the "All files" permission is granted by the user via the Android Settings [1], KDE Connect is immediately allowed access to the root of the storage volume. However, it must do so via standard filesystem APIs, not via SAF's ACTION_OPEN_DOCUMENT_TREE. Even with the permission, accessing the storage root via SAF is not allowed.

I made a very hacky hardcoded proof of concept here: https://invent.kde.org/chenxiaolong/kdeconnect-android/-/commit/53370709d607055a0593a1dd743733858977cf05 It's working fine on a Google Pixel 6 Pro running Android 13 Beta 2.1. I can read and write files from the primary storage root.

For a proper implementation, I believe these are the necessary changes:

* A UI option for selecting the primary storage volume. If the "All files" permission hasn't been granted, the ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION intent can take the user straight to the permissions settings. The file:// URI for the primary storage volume can be retrieved from StorageManager.getPrimaryStorageVolume().getDirectory().
* Adjust some Build.VERSION.SDK_INT checks that enable file:// support to be uri.getScheme().equals(ContentResolver.SCHEME_FILE) instead.
* Maybe refactor the FileSystemView abstraction to allow a mixture of SAF and non-SAF roots? Eg. the user might select the primary storage (non-SAF with MANAGE_EXTERNAL_STORAGE) as well as an SD card (SAF).

I unfortunately don't have time to implement this myself, but hope this information might be useful to others.

[1] Either by sending the user there via the ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION intent or manually going to Settings -> Apps -> Special app access -> All files access -> KDE Connect -> Allow
Comment 7 Jan Rathmann 2023-02-27 13:33:34 UTC
*** Bug 447774 has been marked as a duplicate of this bug. ***
Comment 8 Albert Vaca Cintora 2023-03-19 20:26:42 UTC
Git commit 1ba9e59872e811615a152882469e9b9f07cc7001 by Albert Vaca Cintora, on behalf of Albert Vaca Cintora.
Committed on 19/03/2023 at 20:26.
Pushed by albertvaka into branch 'master'.

SftpPlugin: use MANAGE_EXTERNAL_STORAGE instead of SAF in Android 11+

https://developer.android.com/training/data-storage/manage-all-files
Related: bug 464431

M  +1    -0    AndroidManifest.xml
M  +1    -0    res/values/strings.xml
M  +63   -26   src/org/kde/kdeconnect/Plugins/SftpPlugin/SftpPlugin.java
M  +14   -5    src/org/kde/kdeconnect/Plugins/SftpPlugin/SimpleSftpServer.java
M  +20   -2    src/org/kde/kdeconnect/UserInterface/StartActivityAlertDialogFragment.java

https://invent.kde.org/network/kdeconnect-android/commit/1ba9e59872e811615a152882469e9b9f07cc7001