W tym dokumencie opisano projekt rozwiązania do buforowania plików APK umożliwiającego szybką instalację wstępnie załadowanych aplikacji na urządzeniu obsługującym partycje A/B.
Producenci OEM mogą umieszczać wstępnie załadowane aplikacje i popularne aplikacje w pamięci podręcznej APK przechowywanej na przeważnie pustej partycji B na nowych urządzeniach z partycjami A/B bez wpływu na jakąkolwiek przestrzeń danych dostępną dla użytkownika. Dzięki dostępności pamięci podręcznej APK na urządzeniu nowe lub niedawno zresetowane urządzenia są gotowe do użycia niemal natychmiast, bez konieczności pobierania plików APK z Google Play.
Przypadków użycia
- Przechowuj wstępnie załadowane aplikacje na partycji B, aby przyspieszyć konfigurację
- Przechowuj popularne aplikacje na partycji B, aby przyspieszyć ich przywracanie
Warunki wstępne
Aby móc korzystać z tej funkcji, urządzenie potrzebuje:
- Zainstalowana wersja Androida 8.1 (O MR1).
- Zaimplementowano partycję A/B
Wstępnie załadowaną zawartość można skopiować tylko podczas pierwszego uruchomienia. Dzieje się tak, ponieważ na urządzeniach obsługujących aktualizacje systemu A/B partycja B w rzeczywistości nie przechowuje plików obrazu systemu, ale zamiast tego wstępnie załadowaną zawartość, taką jak zasoby demonstracyjne detaliczne, pliki OAT i pamięć podręczna APK. Po skopiowaniu zasobów na partycję /data (dzieje się to przy pierwszym uruchomieniu), partycja B będzie używana przez aktualizacje bezprzewodowe (OTA) do pobierania zaktualizowanych wersji obrazu systemu.
Dlatego nie można zaktualizować pamięci podręcznej APK przez OTA; można go wstępnie załadować tylko fabrycznie. Przywrócenie ustawień fabrycznych dotyczy tylko partycji /data. Partycja systemowa B nadal zawiera wstępnie załadowaną zawartość do czasu pobrania obrazu OTA. Po przywróceniu ustawień fabrycznych system ponownie przejdzie przez pierwsze uruchomienie. Oznacza to, że buforowanie APK nie jest dostępne, jeśli obraz OTA zostanie pobrany na partycję B, a następnie urządzenie zostanie zresetowane do ustawień fabrycznych.
Realizacja
Podejście 1. Zawartość na innej partycji systemowej
Pro : Wstępnie załadowana zawartość nie zostaje utracona po przywróceniu ustawień fabrycznych – zostanie skopiowana z partycji B po ponownym uruchomieniu.
Wada : Wymaga miejsca na partycji B. Uruchomienie po przywróceniu ustawień fabrycznych wymaga dodatkowego czasu na skopiowanie wstępnie załadowanej zawartości.
Aby wstępne załadowania zostały skopiowane podczas pierwszego uruchomienia, system wywołuje skrypt w /system/bin/preloads_copy.sh
. Skrypt jest wywoływany z pojedynczym argumentem (ścieżka do punktu podłączenia tylko do odczytu dla partycji system_b
):
Aby zaimplementować tę funkcję, wprowadź zmiany specyficzne dla urządzenia. Oto przykład od Marlina:
- Dodaj skrypt, który wykona kopiowanie do pliku
device-common.mk
(w tym przypadkudevice/google/marlin/device-common.mk
), w ten sposób:# Script that copies preloads directory from system_other to data partition PRODUCT_COPY_FILES += \ device/google/marlin/preloads_copy.sh:system/bin/preloads_copy.sh
Znajdź przykładowe źródło skryptu pod adresem: urządzenie/google/marlin /preloads_copy.sh - Edytuj plik
init.common.rc
, aby utworzyć niezbędny katalog/data/preloads
i podkatalogi:mkdir /data/preloads 0775 system system
mkdir /data/preloads/media 0775 system system
mkdir /data/preloads/demo 0775 system system
init
pod adresem: urządzenie/google/marlin/init.common.rc - Zdefiniuj nową domenę SELinux w pliku
preloads_copy.te
:type preloads_copy, domain, coredomain; type preloads_copy_exec, exec_type, vendor_file_type, file_type; init_daemon_domain(preloads_copy) allow preloads_copy shell_exec:file rx_file_perms; allow preloads_copy toolbox_exec:file rx_file_perms; allow preloads_copy preloads_data_file:dir create_dir_perms; allow preloads_copy preloads_data_file:file create_file_perms; allow preloads_copy preloads_media_file:dir create_dir_perms; allow preloads_copy preloads_media_file:file create_file_perms; # Allow to copy from /postinstall allow preloads_copy system_file:dir r_dir_perms;
Znajdź przykładowy plik domeny SELinux pod adresem: /device/google/marlin/+/main/sepolicy/preloads_copy.te - Zarejestruj domenę w nowym
/sepolicy/file_contexts
plik:/system/bin/preloads_copy\.sh u:object_r:preloads_copy_exec:s0
Znajdź przykładowy plik kontekstów SELinux pod adresem: urządzenie/google/marlin/sepolicy/preloads_copy.te - W czasie kompilacji katalog z wstępnie załadowaną zawartością musi zostać skopiowany na inną partycję
system_other
:# Copy contents of preloads directory to system_other partition PRODUCT_COPY_FILES += \ $(call find-copy-subdir-files,*,vendor/google_devices/marlin/preloads,system_other/preloads)
To jest przykład zmiany w pliku Makefile, która umożliwia kopiowanie zasobów pamięci podręcznej APK z repozytorium Git dostawcy (w naszym przypadku był to sprzedawca/google_devices/ marlin/preloads) do lokalizacji na innej partycji systemowej, która zostanie później skopiowana do /data/preloads przy pierwszym uruchomieniu urządzenia. Ten skrypt jest uruchamiany w czasie kompilacji w celu przygotowania obrazu system_other. Oczekuje, że wstępnie załadowana zawartość będzie dostępna w dostawcy/google_devices/marlin/preloads. OEM może wybrać rzeczywistą nazwę/ścieżkę repozytorium. - Pamięć podręczna APK znajduje się w
/data/preloads/file_cache
i ma następujący układ:/data/preloads/file_cache/ app.package.name.1/ file1 fileN app.package.name.N/
To jest ostateczna struktura katalogów na urządzeniach. Producenci OEM mogą wybrać dowolne podejście do implementacji, pod warunkiem, że ostateczna struktura plików będzie replikować tę opisaną powyżej.
Podejście 2. Treść obrazu danych użytkownika została flashowana fabrycznie
To alternatywne podejście zakłada, że wstępnie załadowana zawartość jest już zawarta w katalogu /data/preloads
na partycji /data
.
Pro : Działa od razu po wyjęciu z pudełka — nie ma potrzeby dostosowywania urządzenia, aby kopiować pliki przy pierwszym uruchomieniu. Treść znajduje się już na partycji /data
.
Wada : Wstępnie załadowana zawartość zostaje utracona po przywróceniu ustawień fabrycznych. Chociaż może to być akceptowalne dla niektórych, nie zawsze może działać w przypadku producentów OEM, którzy przywracają urządzenia do ustawień fabrycznych po przeprowadzeniu kontroli kontroli jakości.
Do android.content.Context
dodano nową metodę @SystemApi, getPreloadsFileCache()
. Zwraca bezwzględną ścieżkę do katalogu specyficznego dla aplikacji we wstępnie załadowanej pamięci podręcznej.
Dodano nową metodę IPackageManager.deletePreloadsFileCache
, która umożliwia usunięcie katalogu preloads w celu odzyskania całego miejsca. Metodę mogą wywołać tylko aplikacje posiadające SYSTEM_UID, czyli serwer systemowy lub Ustawienia.
Przygotowanie aplikacji
Tylko uprzywilejowane aplikacje mogą uzyskać dostęp do katalogu pamięci podręcznej wstępnego ładowania. Aby uzyskać taki dostęp, aplikacje muszą być zainstalowane w katalogu /system/priv-app
.
Walidacja
- Po pierwszym uruchomieniu urządzenie powinno mieć zawartość w katalogu
/data/preloads/file_cache
. - Jeśli w urządzeniu zaczyna brakować miejsca, zawartość katalogu
file_cache/
musi zostać usunięta.
Użyj przykładowej aplikacji ApkCacheTest do testowania pamięci podręcznej APK.
- Zbuduj aplikację, uruchamiając to polecenie z katalogu głównego:
make ApkCacheTest
- Zainstaluj aplikację jako aplikację uprzywilejowaną. (Pamiętaj, że tylko uprzywilejowane aplikacje mogą uzyskać dostęp do pamięci podręcznej APK). Wymaga to zrootowanego urządzenia:
adb root && adb remount
adb shell mkdir /system/priv-app/ApkCacheTest
adb push $ANDROID_PRODUCT_OUT/data/app/ApkCacheTest/ApkCacheTest.apk /system/priv-app/ApkCacheTest/
adb shell stop && adb shell start
- W razie potrzeby symuluj katalog pamięci podręcznej plików i jego zawartość (wymaga to również uprawnień roota):
adb shell mkdir -p /data/preloads/file_cache/com.android.apkcachetest
adb shell restorecon -r /data/preloads
adb shell "echo "Test File" > /data/preloads/file_cache/com.android.apkcachetest/test.txt"
- Przetestuj aplikację. Po zainstalowaniu aplikacji i utworzeniu testowego katalogu
file_cache
otwórz aplikację ApkCacheTest. Powinien pokazać jeden pliktest.txt
i jego zawartość. Zobacz ten zrzut ekranu, aby zobaczyć, jak te wyniki pojawiają się w interfejsie użytkownika. Rysunek 1. Wyniki testu ApkCacheTest.