Ograniczony dostęp do miejsca na dane ogranicza dostęp aplikacji do pamięci zewnętrznej. W Androidzie 11 lub nowszym aplikacje kierowane na interfejs API na poziomie 30 lub wyższym muszą korzystać z pamięci o ograniczonym zakresie. W Androidzie 10 aplikacje mogły zrezygnować z pamięci o ograniczonym zakresie.
Ograniczenia dostępu do aplikacji
Celem pamięci o ograniczonym zakresie jest ochrona prywatności danych aplikacji i użytkowników. Obejmuje to ochronę informacji o użytkowniku (takich jak metadane zdjęć), uniemożliwianie aplikacjom modyfikowania lub usuwania plików użytkownika bez wyraźnego pozwolenia oraz ochronę poufnych dokumentów użytkownika pobranych do folderu Pobrane lub innych folderów.
Aplikacje korzystające z pamięci o ograniczonym zakresie mogą mieć te poziomy dostępu (rzeczywisty dostęp zależy od implementacji):
- Uprawnienia do odczytu i zapisu własnych plików bez konieczności uzyskiwania uprawnień.
- Odczyt plików multimedialnych innych aplikacji z uprawnieniem
READ_EXTERNAL_STORAGE
- Zapisywanie plików multimedialnych innych aplikacji jest dozwolone tylko za bezpośrednią zgodą użytkownika (wyjątki dotyczą Galerii systemowej i aplikacji, które kwalifikują się do dostępu do wszystkich plików).
- Brak dostępu do odczytu i zapisu w katalogach danych zewnętrznych innych aplikacji.
Korzystanie z pamięci o ograniczonym zakresie dostępu za pomocą FUSE
Android 11 lub nowszy obsługuje system plików w przestrzeni użytkownika (FUSE), który umożliwia modułowi MediaProvider sprawdzanie operacji na plikach w przestrzeni użytkownika i ograniczanie dostępu do plików na podstawie zasad zezwalających, odmawiających lub redagujących dostęp. Aplikacje korzystające z FUSE w przestrzeni ograniczonego dostępu mają funkcje ochrony prywatności tej przestrzeni i mogą uzyskiwać dostęp do plików za pomocą bezpośredniej ścieżki pliku (dzięki czemu interfejsy API plików działają w aplikacjach).
Android 10 wymuszał stosowanie zasad pamięci o ograniczonym zakresie w przypadku dostępu do plików przez MediaProvider, ale nie w przypadku bezpośredniego dostępu do ścieżki pliku (np. przy użyciu interfejsu File API i interfejsów NDK API) ze względu na wysiłek wymagany do przechwytywania wywołań jądra. W rezultacie aplikacje w pamięci o ograniczonym zakresie nie mogły uzyskiwać dostępu do plików za pomocą bezpośredniej ścieżki. To ograniczenie utrudniało deweloperom dostosowywanie aplikacji, ponieważ wymagało wprowadzenia znaczących zmian w kodzie, aby zastąpić dostęp do interfejsu File API dostępem do interfejsu MediaProvider API.
FUSE i SDCardFS
Obsługa FUSE na Androidzie 11 nie jest związana z wycofaniem SDCardFS, ale zapewnia alternatywę dla Media Store na urządzeniach, które wcześniej korzystały z SDCardFS. Urządzenia:
- Urządzenia wprowadzone na rynek z Androidem 11 lub nowszym, które korzystają z jądra w wersji 5.4 lub nowszej, nie mogą używać SDCardFS.
- Aktualizacja do Androida 11 lub nowszego może hostować FUSE na SDCardFS, aby przechwytywać operacje na plikach i realizować cele związane z prywatnością.
Dostrajanie wydajności FUSE
Android obsługiwał wcześniej FUSE w Androidzie 7 lub starszym, w którym pamięć zewnętrzna była montowana jako FUSE. Z powodu problemów z wydajnością i zakleszczeniami w tej implementacji FUSE w Androidzie 8 wprowadzono SDCardFS. Android 11 przywraca obsługę FUSE dzięki ulepszonej i lepiej przetestowanej implementacji libfuse
, którą można dostosować, aby rozwiązać problemy z wydajnością w Androidzie 7 lub starszym.
Dostrajanie FUSE obejmuje te zmiany:
- Omijanie FUSE w przypadku katalogów
Android/data
iAndroid/obb
w celu zwiększenia wydajności aplikacji do gier, które korzystają z tych katalogów. - Optymalizacje (np. dostosowanie współczynników wyprzedzającego odczytu i zmodyfikowanych danych systemu plików FUSE), aby zapewnić wydajność odczytu i płynne odtwarzanie multimediów.
- Korzystanie z pamięci podręcznej zapisu FUSE.
- Uprawnienia do buforowania, aby zmniejszyć liczbę wywołań IPC na serwerze systemowym.
- Optymalizacje aplikacji z dostępem do wszystkich plików, które przyspieszają operacje zbiorcze.
Powyższe zmiany ustawień mogą zapewnić porównywalną wydajność urządzeń FUSE i innych. Na przykład testowanie dostrojonego Pixela 2 za pomocą FUSE i Pixela 2 za pomocą magazynu multimediów wykazało porównywalną wydajność odczytu sekwencyjnego (np. odtwarzania wideo) w przypadku dostępu do ścieżki pliku i magazynu multimediów. Jednak w przypadku FUSE zapisy sekwencyjne były nieco gorsze, a odczyty i zapisy losowe mogły być nawet 2 razy wolniejsze.
Pomiary wydajności mogą się różnić w zależności od urządzenia i konkretnych przypadków użycia. Interfejsy MediaProvider API zapewniają najbardziej spójną wydajność, dlatego deweloperzy aplikacji, którym zależy na wydajności, powinni używać w swoich aplikacjach interfejsów MediaProvider API.
Ograniczanie wpływu FUSE na wydajność
Wpływ na wydajność FUSE jest ograniczony tylko do użytkowników, którzy intensywnie korzystają z plików przechowywanych na zewnętrznej pamięci współdzielonej. Zewnętrzna pamięć prywatna (obejmująca katalogi android/data
i android/obb
) jest pomijana przez FUSE, natomiast pamięć wewnętrzna (np. /data/data
, w której wiele aplikacji przechowuje dane, aby były zaszyfrowane i bezpieczne) nie jest montowana przez FUSE.
Aplikacje, które w niewielkim stopniu korzystają z udostępnionego miejsca zewnętrznego, często wchodzą w interakcje z ograniczoną liczbą plików (zwykle mniej niż 100). Te aplikacje korzystają z dotychczasowych optymalizacji typowych operacji odczytu i zapisu, więc nie powinny odczuwać żadnego wpływu FUSE na wydajność w Androidzie 11.
Aplikacje, które intensywnie korzystają z pamięci zewnętrznej, zwykle wykonują operacje na wielu plikach, takie jak wyświetlanie lub usuwanie katalogu z 1000 plików albo tworzenie lub usuwanie katalogu z milionem plików w systemie plików. Operacje na plikach zbiorczych mogą być w Androidzie 11 objęte FUSE, ale jeśli takie aplikacje kwalifikują się do uzyskania uprawnienia
MANAGE_EXTERNAL_STORAGE
, mogą korzystać z optymalizacji wydajności wprowadzonych w aktualizacji z października 2020 r.
Aby uniknąć obniżenia wydajności FUSE, aplikacje mogą przechowywać dane w zewnętrznej pamięci prywatnej lub używać interfejsów API zbiorczych w klasie ContentProvider
, aby ominąć FUSE i uzyskać ścieżkę zoptymalizowaną pod kątem wydajności. Dodatkowo aktualizacja komponentu systemowego MediaProvider z października 2020 r. zawiera optymalizacje wydajności dla menedżerów plików i podobnych aplikacji (np. do tworzenia kopii zapasowych i przywracania danych czy antywirusowych), które mają uprawnienie MANAGE_EXTERNAL_STORAGE
.
Prywatność ważniejsza niż wydajność
Na urządzeniach dostosowanych do FUSE większość najważniejszych ścieżek użytkownika działa tak samo dobrze w Androidzie 10 i 11. Jednak podczas testowania wyników w przypadku zestawu operacji na plikach Android 11 może działać gorzej niż Android 10. W przypadku wzorców dostępu do plików, które działają gorzej na Androidzie 11 (np. losowe odczyty lub zapisy), zalecamy używanie interfejsów API MediaProvider, aby zapewnić aplikacjom tryb dostępu inny niż FUSE, który jest najlepszą i najbardziej wydajną opcją.
Aktualizacje MediaProvider i FUSE
Działanie komponentu systemowego MediaProvider różni się w zależności od wersji Androida.
W Androidzie 10 i starszych wersjach systemem plików był SDCardFS, a MediaProvider udostępniał interfejs do kolekcji plików (np. obrazów, filmów, plików muzycznych itp.). Gdy aplikacja utworzyła plik za pomocą interfejsu File API, mogła poprosić MediaProvider o zeskanowanie pliku i zarejestrowanie go w bazie danych.
W Androidzie 11 lub nowszym SDCardFS jest przestarzały, a za obsługę systemu plików (FUSE) w pamięci zewnętrznej odpowiada MediaProvider, dzięki czemu system plików w pamięci zewnętrznej i baza danych MediaProvider są spójne. Jako program obsługi przestrzeni użytkownika dla systemu plików FUSE usługa MediaProvider może przechwytywać wywołania jądra i zapewniać, że operacje na plikach są bezpieczne pod względem prywatności.
W Androidzie 11 i nowszym MediaProvider jest też modułem systemowym (modułem Mainline), który można aktualizować niezależnie od wersji Androida. Oznacza to, że problemy z wydajnością, prywatnością lub bezpieczeństwem wykryte w MediaProvider można rozwiązać i dostarczyć bezprzewodowo z Google Play Store lub za pomocą innych mechanizmów dostarczanych przez partnerów. Można też aktualizować wszystko, co mieści się w zakresie oczekiwanym od modułu obsługi FUSE, co umożliwia wprowadzanie poprawek w celu usunięcia regresji wydajności i błędów FUSE.