/storage/emulated/0/
sebenarnya /data/media/0/
diekspos melalui sistem file emulasi / virtual, bukan yang sebenarnya.
Ini mengacu pada jawaban saya sebelumnya di sini , tetapi dengan perincian yang lebih relevan.
PENYIMPANAN ANDROID:
Di Android 5 :
/sdcard >S> /storage/emulated/legacy >S> /mnt/shell/emulated/0
/mnt/shell/emulated >E> /data/media
Di Android 6+ :
# for (Java) Android apps (running inside zygote virtual machine)
# "/storage to VIEW" bind mount is inside a separate mount namespace for every app
/sdcard >S> /storage/self/primary
/storage/self >B> /mnt/user/USER-ID
/mnt/user/USER-ID/primary >S> /storage/emulated/USER-ID
/storage/emulated >B> /mnt/runtime/VIEW/emulated
/mnt/runtime/VIEW/emulated >E> /data/media
# for services/daemons/processes in root/global namespace (VIEW = default)
/sdcard >S> /storage/self/primary
/storage >B> /mnt/runtime/default
/mnt/runtime/default/self/primary >S> /mnt/user/USER-ID/primary
/mnt/user/USER-ID/primary >S> /storage/emulated/USER-ID
/storage/emulated >B> /mnt/runtime/default/emulated
/mnt/runtime/default/emulated >E> /data/media
* >S>
untuk symlink, >E>
untuk ditiru dan >B>
untuk mount
* USER-ID
pengguna saat ini dalam kasus Multiple Users
atau Work Profile
, biasanya 0
yaitu bahwa pemilik perangkat
* VIEW
adalah salah satu read
(untuk aplikasi dengan izin.READ_EXTERNAL_STORAGE) atau write
(izin.WRITE_EXTERNAL_STORAGE) atau default
(untuk proses yang berjalan di root / global mount namespace yaitu di luar zygote)
* Ada perbedaan kecil pada versi Android sebelumnya tetapi konsep emulasi adalah sama sejak diterapkan.
* Untuk sedikit lebih detail tentang implementasi mount namespace Android, lihat jawaban ini .
Singkatnya, /sdcard
dan /storage/emulated/0
- yang mewakili sistem file FAT / vFAT / FAT32 - menunjuk ke arah /data/media/0
(atau /mnt/expand/[UUID]/media/0
dalam hal Penyimpanan Adoptable ) melalui FUSE
atau sdcardfs
emulasi.
Menjadi bukan Android spesifik tetapi umumnya terkait Linux, symlink dan bind mount (lihat "Membuat bind mount") berada di luar ruang lingkup pertanyaan ini, karena pertanyaannya adalah tentang bagian emulasi terutama.
EMULASI:
Mengapa persaingan ada di sini? Sistem file emulasi adalah lapisan abstraksi pada sistem file aktual ( ext4
atau f2fs
) yang pada dasarnya melayani dua tujuan:
- Pertahankan konektivitas USB perangkat Android ke PC (diimplementasikan melalui MTP sekarang menjadi hari)
- Batasi akses aplikasi / proses yang tidak sah ke media pribadi pengguna dan data aplikasi lain pada kartu SD.
Baca Perjalanan Penyimpanan Android untuk detailnya, ringkasannya adalah:
Perangkat Android awal kekurangan penyimpanan internal dan mengandalkan kartu SD eksternal (fisik) yang secara tradisional menggunakan keluarga sistem file FAT untuk memastikan kompatibilitas dengan sebagian besar PC (lihat dominasi Microsoft pada dunia PC).
Ketika penyimpanan internal bertambah besar, sistem file yang sama dipindahkan ke kartu SD internal (masih disebut "eksternal").
Tetapi implementasi FAT / vFAT memiliki dua masalah besar yang ditangani oleh Google secara bertahap:
- Perangkat Android terhubung ke PC secara langsung ( USB Mass Storage ) sama seperti kita menghubungkan drive USB hari ini. UMS mengekspos perangkat pada level blok dan memutus kartu SD dari kerangka kerja Android (un-mount), sehingga membuat seluruh data tidak tersedia untuk aplikasi dan mungkin melanggar banyak fungsi.
- FAT (menjadi favorit Windows pada hari-hari pengembangan) tidak pernah dirancang untuk menegakkan izin UNIX (mode, uid, gid, dan juga symlink , dan
ioctls
sejenisnya FS_IOC_FIEMAP
). Jadi, semua data pada kartu SD tersedia untuk semua aplikasi (karena setiap aplikasi Android adalah pengguna UNIX / Linux dan memiliki uid) tanpa batasan, sehingga meningkatkan privasi dan masalah keamanan yang serius.
Kedua masalah ini diatasi melalui persaingan:
- Penyimpanan kartu SD yang sebenarnya telah dipindahkan ke
/data
partisi (atau partisi independen / sdcard pada beberapa perangkat sebelumnya) yang menyimpan ext4
sistem file (secara bertahap digantikan oleh f2fs
), sepenuhnya menerapkan izin UNIX.
- Desain ini dibuat menggunakan UMS tidak mungkin karena seluruh
/data
partisi tidak dapat terpapar ke PC karena 2 alasan lagi: (1)
itu berisi banyak pengaturan dan data aplikasi yang harus dilindungi dari aplikasi lain serta pengguna manusia. (2)
Sistem file Linux tidak didukung oleh Windows.
Jadi UMS diganti dengan Media Transfer Protocol yang merupakan ekstensi jenis client-server ke PTP - protokol yang sudah ada. MTP tidak mengekspos perangkat blok tetapi bekerja melalui tumpukan perangkat lunak. Host MTP berjalan pada Android sebagai app ( android.process.media
) sepenuhnya dikotak pasir dalam kerangka Android, tidak mampu melakukan tugas yang meningkat.
Sekarang aplikasi (dan MTP, yang juga merupakan aplikasi) berinteraksi dengan penyimpanan yang ditiru alih-alih /data/media
, mencapai kedua tujuan pada saat yang sama yaitu menegakkan pemeriksaan izin di bawahnya dan tampak seperti sistem file FAT di permukaan atas.
Google sekarang menerapkan emulasi melalui sdcardfs untuk mengatasi kekurangan FUSE ; satu utama adalah input / output overhead yaitu untuk meningkatkan kecepatan baca / tulis.
IZIN PENYIMPANAN EKSTERNAL:
Konsep file Publik dan Pribadi pada penyimpanan eksternal dapat ditunjukkan dengan menggunakan contoh:
Instal aplikasi Termux.
Buat direktori /sdcard/Android/data/com.termux/test_dir
dan /sdcard/test_dir
.
Buat file /sdcard/Android/data/com.termux/test_file
dan /sdcard/Android/data/com.termux/test_file
.
Jalankan perintah berikut:
* Anda harus menginstal WhatsApp atau memilih folder pribadi beberapa aplikasi lain.
Sekarang, Force Stop the Termux app dan beri izin Storage . Jalankan kembali perintah:
Lihat perbedaan dalam izin dari file dan direktori yang sama. Ini sepertinya tidak mungkin dilakukan tanpa emulasi pada sistem file Linux asli ketika ada ratusan aplikasi (pengguna) yang harus ditangani secara bersamaan. Ini adalah emulasi sistem file yang memungkinkan file yang sama terpapar dengan tiga set izin berbeda pada saat yang sama terlepas dari izin aslinya pada sistem file aktual:
# touch /data/media/0/test_file
# stat -c '%a %u %g %n' /data/media/0/test_file
644 1023 1023 /data/media/0/test_file
# stat -c '%a %u %g %n' /mnt/runtime/*/emulated/0/test_file
660 0 1015 /mnt/runtime/default/emulated/0/test_file
640 0 9997 /mnt/runtime/read/emulated/0/test_file
660 0 9997 /mnt/runtime/write/emulated/0/test_file
Lihat juga Apa itu "u # _everybody" UID?
Terkait: