/storage/emulated/0/
насправді /data/media/0/
експонується через емульовану / віртуальну файлову систему, а не фактичну.
Це з посиланням на мою попередню відповідь тут , але з більш релевантними подробицями.
ЗБЕРІГАННЯ АНДРОІДУ:
На Android 5 :
/sdcard >S> /storage/emulated/legacy >S> /mnt/shell/emulated/0
/mnt/shell/emulated >E> /data/media
На 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>
для symlink, >E>
для емуляції та >B>
встановлення прив’язки
* USER-ID
поточного користувача у випадку Multiple Users
або Work Profile
, як правило 0
, власника пристрою
* VIEW
є одним із read
(для додатків з дозволом.READ_EXTERNAL_STORAGE) або write
(дозвіл.WRITE_EXTERNAL_STORAGE) або default
(для процесів, що працюють в root / глобальний простір імен для монтування, тобто поза зиготи)
* У попередніх версіях Android були незначні відмінності, але концепція емуляції була однаковою з тих пір, коли вона була впроваджена.
* Щоб отримати докладнішу інформацію про реалізацію простору імен для кріплення Android, див. Цю відповідь .
Коротше кажучи, /sdcard
і /storage/emulated/0
- які представляють файлову систему FAT / vFAT / FAT32 - вказують на /data/media/0
(або /mnt/expand/[UUID]/media/0
у разі прийнятного сховища ) через FUSE
або sdcardfs
емуляцію.
Будучи не специфічним для Android, але, як правило, пов’язаним з Linux, монтування символьних посилань та зв’язувань (див. "Створення кріплення для зв'язування") не входить у рамки цього питання, оскільки головним чином йдеться про частину емуляції.
ЕМУЛЯЦІЯ:
Чому емуляція тут? Емульована файлова система - це абстракційний шар фактичної файлової системи ( ext4
або f2fs
), який в основному виконує два цілі:
- Збережіть підключення USB-пристроїв Android до ПК (впроваджено через MTP зараз за добу)
- Обмежити несанкціонований доступ програм / процесів до приватних медіа користувачів та інших програм на SD-картці.
Докладніше читайте в Android Store Storage Journey , підсумок:
Ранні пристрої Android не мали внутрішнього зберігання і покладалися на (фізично) зовнішні SD-карти, які традиційно використовують FAT-файли файлової системи для забезпечення сумісності з більшістю ПК (див. Домінування Microsoft у світі ПК).
Коли внутрішній накопичувач збільшився, та сама файлова система перейшла на внутрішню (все ще називається "зовнішню") SD-карту.
Але впровадження FAT / vFAT мало дві основні проблеми, які Google вирішував поступово:
- Пристрої Android підключалися безпосередньо до ПК ( USB Mass Storage ) так само, як ми підключаємо USB-накопичувач сьогодні. UMS виставляє пристрій на рівні блоку та відключає карту SD від рамки Android (не монтується), завдяки чому цілі дані недоступні для додатків і, можливо, порушують багато функціональних можливостей.
- FAT (час для Windows 'фаворитом в дні розвитку) ніколи не був розроблений для забезпечення дозволу UNIX (режим, UID, GID і також символічні посилання , і
ioctls
як FS_IOC_FIEMAP
). Таким чином, усі дані на SD-картці були доступні для всіх програм (оскільки кожен додаток для Android є користувачем UNIX / Linux і має uid) без обмежень, отже, виникають серйозні проблеми щодо конфіденційності та безпеки.
Обидва ці питання були вирішені через емуляцію:
- Фактичне сховище SD-картки було переміщено до
/data
розділу (або незалежного розділу / SDCard на деяких пристроях раніше), який містить ext4
файлову систему (поступово замінюється f2fs
), повністю реалізуючи дозволи UNIX.
- Ця конструкція зробила неможливим використання UMS, оскільки цілий
/data
розділ не міг піддаватися впливу ПК через ще дві причини: (1)
він містить безліч параметрів та даних програм, які слід захищати від інших програм, а також від користувачів користувачів. (2)
Файлові системи Linux не підтримуються Windows.
Так UMS було замінено протоколом Media Transfer, який є розширенням типу клієнт-сервер до PTP - уже встановленим протоколом. MTP не виставляє блокового пристрою, але працює через стек програмного забезпечення. Хост MTP працює на Android як додаток ( android.process.media
), повністю підключений до Android, не здатний виконувати будь-які посилені завдання.
Тепер додатки (і MTP, що також є додатком) взаємодіють із емульованим сховищем замість того /data/media
, щоб одночасно досягати обох цілей, тобто виконувати перевірки дозволів під ними і виглядати як файлова система FAT на верхній поверхні.
Зараз Google реалізує емуляцію через sdcardfs, щоб подолати недоліки FUSE ; одним з основних є вхід / вихід накладних витрат, тобто підвищення швидкості читання / запису.
ВНУТРІШНІ ДОГОВІРИ ЗБЕРІГАННЯ:
Поняття загальнодоступних та приватних файлів на зовнішньому сховищі можна продемонструвати на прикладі:
Установити додаток Termux.
Створюйте каталоги /sdcard/Android/data/com.termux/test_dir
та /sdcard/test_dir
.
Створення файлів /sdcard/Android/data/com.termux/test_file
і /sdcard/Android/data/com.termux/test_file
.
Виконайте такі команди:
* У вас повинен бути встановлений WhatsApp або вибрати приватну папку іншого додатка.
Тепер змушуйте зупинити додаток Termux і надати дозвіл на зберігання . Виконайте команди ще раз:
Перегляньте різницю дозволів тих самих файлів та каталогів. Здається, це не можливо просто без емуляції в рідній файловій системі Linux, коли є сотні додатків (користувачів), з якими можна одночасно працювати. Це емуляція файлової системи, яка дозволяє експонувати один і той же файл із трьома різними наборами дозволів, незалежно від його оригінальних дозволів на фактичну файлову систему:
# 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
Також див. Що таке UID "u # _everybody"?
Пов'язані: