From dd378738e31a3577c40cd81b727dd689b19f1796 Mon Sep 17 00:00:00 2001 From: agnostic-apollo Date: Thu, 17 Mar 2022 04:42:28 +0500 Subject: [PATCH] Fixed: Add `media-*` symlinks to `Android/media` for all storages and `external-0` symlink to `Android/media` of primary storage The `~/external-0` and `~/media-0` should point to primary storage and `1+` to others, possibly portable sd cards. Note that one can make portable sd card as primary storage as well instead of internal sd card with adoptable storage, which then links it to `/storage/emulated`, so the concept of `internal` and `external` sd card does not apply to primary storage for all cases. https://android.stackexchange.com/questions/214233/how-to-free-internal-storage-by-moving-data-or-using-symlink-bind-mount-with-a/214706#214706 https://android.stackexchange.com/questions/217741/how-to-bind-mount-a-folder-inside-sdcard-with-correct-permissions/217936#217936 https://android.stackexchange.com/questions/205430/what-is-storage-emulated-0/205494#205494 https://source.android.com/devices/storage/adoptable ``` $ ls -l storage | cut -d ' ' -f 9- audiobooks -> /storage/emulated/0/Audiobooks dcim -> /storage/emulated/0/DCIM documents -> /storage/emulated/0/Documents downloads -> /storage/emulated/0/Download external-0 -> /storage/emulated/0/Android/data/com.termux/files external-1 -> /storage/XXXX-XXXX/Android/data/com.termux/files media-0 -> /storage/emulated/0/Android/media/com.termux media-1 -> /storage/XXXX-XXXX/Android/media/com.termux movies -> /storage/emulated/0/Movies music -> /storage/emulated/0/Music pictures -> /storage/emulated/0/Pictures podcasts -> /storage/emulated/0/Podcasts shared -> /storage/emulated/0 ``` Closes #2481 --- .../java/com/termux/app/TermuxInstaller.java | 27 ++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/termux/app/TermuxInstaller.java b/app/src/main/java/com/termux/app/TermuxInstaller.java index d9980f61..c3d112ad 100644 --- a/app/src/main/java/com/termux/app/TermuxInstaller.java +++ b/app/src/main/java/com/termux/app/TermuxInstaller.java @@ -286,6 +286,7 @@ final class TermuxInstaller { Logger.logInfo(LOG_TAG, "Setting up storage symlinks at ~/storage/shared, ~/storage/downloads, ~/storage/dcim, ~/storage/pictures, ~/storage/music and ~/storage/movies for directories in \"" + Environment.getExternalStorageDirectory().getAbsolutePath() + "\"."); + // Get primary storage root "/storage/emulated/0" symlink File sharedDir = Environment.getExternalStorageDirectory(); Os.symlink(sharedDir.getAbsolutePath(), new File(storageDir, "shared").getAbsolutePath()); @@ -315,9 +316,17 @@ final class TermuxInstaller { Os.symlink(audiobooksDir.getAbsolutePath(), new File(storageDir, "audiobooks").getAbsolutePath()); } - final File[] dirs = context.getExternalFilesDirs(null); - if (dirs != null && dirs.length > 1) { - for (int i = 1; i < dirs.length; i++) { + // Dir 0 should ideally be for primary storage + // https://cs.android.com/android/platform/superproject/+/android-12.0.0_r32:frameworks/base/core/java/android/app/ContextImpl.java;l=818 + // https://cs.android.com/android/platform/superproject/+/android-12.0.0_r32:frameworks/base/core/java/android/os/Environment.java;l=219 + // https://cs.android.com/android/platform/superproject/+/android-12.0.0_r32:frameworks/base/core/java/android/os/Environment.java;l=181 + // https://cs.android.com/android/platform/superproject/+/android-12.0.0_r32:frameworks/base/services/core/java/com/android/server/StorageManagerService.java;l=3796 + // https://cs.android.com/android/platform/superproject/+/android-7.0.0_r36:frameworks/base/services/core/java/com/android/server/MountService.java;l=3053 + + // Create "Android/data/com.termux" symlinks + File[] dirs = context.getExternalFilesDirs(null); + if (dirs != null && dirs.length > 0) { + for (int i = 0; i < dirs.length; i++) { File dir = dirs[i]; if (dir == null) continue; String symlinkName = "external-" + i; @@ -326,6 +335,18 @@ final class TermuxInstaller { } } + // Create "Android/media/com.termux" symlinks + dirs = context.getExternalMediaDirs(); + if (dirs != null && dirs.length > 0) { + for (int i = 0; i < dirs.length; i++) { + File dir = dirs[i]; + if (dir == null) continue; + String symlinkName = "media-" + i; + Logger.logInfo(LOG_TAG, "Setting up storage symlinks at ~/storage/" + symlinkName + " for \"" + dir.getAbsolutePath() + "\"."); + Os.symlink(dir.getAbsolutePath(), new File(storageDir, symlinkName).getAbsolutePath()); + } + } + Logger.logInfo(LOG_TAG, "Storage symlinks created successfully."); } catch (Exception e) { Logger.logErrorAndShowToast(context, LOG_TAG, e.getMessage());