In diesem Dokument wird das Design einer APK-Caching-Lösung für die schnelle Installation vorinstallierter Apps auf einem Gerät beschrieben, das A/B-Partitionen unterstützt.
OEMs können Preloads und beliebte Apps im APK-Cache ablegen, der sich auf neuen Geräten mit A/B-Partition in der größtenteils leeren B-Partition befindet, ohne den für Nutzer sichtbaren Datenspeicher zu beeinträchtigen. Wenn auf dem Gerät ein APK-Cache verfügbar ist, können neue oder vor Kurzem auf die Werkseinstellungen zurückgesetzte Geräte fast sofort verwendet werden, ohne dass APK-Dateien von Google Play heruntergeladen werden müssen.
Anwendungsfälle
- Vorab geladene Apps in der B-Partition speichern, um die Einrichtung zu beschleunigen
- Beliebte Apps in der B-Partition speichern, um sie schneller wiederherzustellen
Voraussetzungen
Für die Nutzung dieser Funktion muss das Gerät folgende Voraussetzungen erfüllen:
- Android 8.1 (O MR1) installiert
- A/B-Partition implementiert
Vorab geladene Inhalte können nur beim ersten Start kopiert werden. Das liegt daran, dass auf Geräten, die A/B-Systemupdates unterstützen, in der B-Partition keine System-Imagedateien gespeichert werden, sondern vorab geladene Inhalte wie Demoressourcen für den Einzelhandel, OAT-Dateien und der APK-Cache. Nachdem die Ressourcen in die Partition „/data“ kopiert wurden (dies geschieht beim ersten Start), wird die B-Partition von Over-the-air-Updates (OTA-Updates) zum Herunterladen aktualisierter Versionen des System-Images verwendet.
Daher kann der APK-Cache nicht über OTA aktualisiert werden, sondern nur in der Fabrik vorab geladen werden. Das Zurücksetzen auf die Werkseinstellungen wirkt sich nur auf die Partition „/data“ aus. Die System-B-Partition enthält weiterhin die vorab geladenen Inhalte, bis das OTA-Image heruntergeladen wurde. Nach dem Zurücksetzen auf die Werkseinstellungen wird das System noch einmal gestartet. Das bedeutet, dass das APK-Caching nicht verfügbar ist, wenn das OTA-Image in die B-Partition heruntergeladen und das Gerät dann auf die Werkseinstellungen zurückgesetzt wird.
Implementierung
Ansatz 1. Inhalte auf der Partition „system_other“
Vorteil: Vorinstallierte Inhalte gehen nach dem Zurücksetzen auf die Werkseinstellungen nicht verloren. Sie werden nach einem Neustart von der B-Partition kopiert.
Con: Erfordert Speicherplatz auf der B-Partition. Nach dem Zurücksetzen auf die Werkseinstellungen benötigt das Gerät zusätzliche Zeit, um vorab geladene Inhalte zu kopieren.
Damit Preloads beim ersten Start kopiert werden, ruft das System ein Script in /system/bin/preloads_copy.sh
auf. Das Script wird mit einem einzigen Argument aufgerufen (Pfad zum schreibgeschützten Bereitstellungspunkt für die system_b
-Partition):
Nehmen Sie die folgenden gerätespezifischen Änderungen vor, um diese Funktion zu implementieren. Hier ist ein Beispiel aus Marlin:
- Fügen Sie das Skript, das die Kopie erstellt, der
device-common.mk
-Datei (in diesem Falldevice/google/marlin/device-common.mk
) hinzu: Beispiel-Scriptquelle: device/google/marlin/preloads_copy.sh# 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
- Bearbeiten Sie die Datei
init.common.rc
, damit das erforderliche Verzeichnis/data/preloads
und die erforderlichen Unterverzeichnisse erstellt werden: Beispiel für einemkdir /data/preloads 0775 system system
mkdir /data/preloads/media 0775 system system
mkdir /data/preloads/demo 0775 system system
init
-Dateiquelle finden Sie unter: device/google/marlin/init.common.rc - Definieren Sie in der Datei
preloads_copy.te
eine neue SELinux-Domain: Beispiel für eine SELinux-Domaindatei: /device/google/marlin/+/main/sepolicy/preloads_copy.tetype 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;
- Registrieren Sie die Domain in einer neuen
-Datei:/sepolicy/file_contexts Eine Beispieldatei für SELinux-Kontexte finden Sie unter device/google/marlin/sepolicy/preloads_copy.te./system/bin/preloads_copy\.sh u:object_r:preloads_copy_exec:s0
- Zum Zeitpunkt des Builds muss das Verzeichnis mit den vorab geladenen Inhalten in die Partition
system_other
kopiert werden: Das ist ein Beispiel für eine Änderung in einem Makefile, mit der APK-Cache-Ressourcen aus dem Git-Repository des Anbieters (in unserem Fall war es vendor/google_devices/marlin/preloads) an den Speicherort auf der Partition „system_other“ kopiert werden, von dem aus sie beim ersten Start des Geräts in /data/preloads kopiert werden. Dieses Script wird zum Zeitpunkt des Builds ausgeführt, um das Image „system_other“ vorzubereiten. Es wird davon ausgegangen, dass vorab bereitgestellte Inhalte unter „vendor/google_devices/marlin/preloads“ verfügbar sind. Der OEM kann den tatsächlichen Repository-Namen/-Pfad kostenlos wählen.# 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)
- Der APK-Cache befindet sich unter
/data/preloads/file_cache
und hat das folgende Layout: Dies ist die endgültige Verzeichnisstruktur auf den Geräten. OEMs können jeden Implementierungsansatz wählen, solange die endgültige Dateistruktur der oben beschriebenen entspricht./data/preloads/file_cache/ app.package.name.1/ file1 fileN app.package.name.N/
Ansatz 2. Inhalte auf dem vom Hersteller geflashten Nutzerdaten-Image
Bei diesem alternativen Ansatz wird davon ausgegangen, dass vorinstallierte Inhalte bereits im Verzeichnis /data/preloads
auf der Partition /data
enthalten sind.
Vorteile: Funktioniert sofort – keine Anpassungen am Gerät erforderlich, um Dateien beim ersten Start zu kopieren. Die Inhalte befinden sich bereits auf der Partition /data
.
Nachteil: Vorinstallierte Inhalte gehen nach einem Zurücksetzen auf die Werkseinstellungen verloren. Das ist für einige zwar akzeptabel, funktioniert aber möglicherweise nicht immer für OEMs, die Geräte nach der Qualitätskontrolle auf die Werkseinstellungen zurücksetzen.
android.content.Context
wurde die neue @SystemApi-Methode getPreloadsFileCache()
hinzugefügt. Er gibt einen absoluten Pfad zu einem app-spezifischen Verzeichnis im vorab geladenen Cache zurück.
Die neue Methode IPackageManager.deletePreloadsFileCache
ermöglicht das Löschen des Verzeichnisses „preloads“, um den gesamten Speicherplatz wiederherzustellen. Die Methode kann nur von Apps mit SYSTEM_UID aufgerufen werden, also vom Systemserver oder den Einstellungen.
App-Vorbereitung
Nur Apps mit Berechtigungen können auf das Cache-Verzeichnis für Vorabdaten zugreifen. Dazu müssen Apps im Verzeichnis /system/priv-app
installiert sein.
Zertifizierungsstufe
- Nach dem ersten Start sollte das Gerät Inhalte im Verzeichnis
/data/preloads/file_cache
haben. - Der Inhalt des Verzeichnisses
file_cache/
muss gelöscht werden, wenn der Speicherplatz auf dem Gerät knapp wird.
Verwenden Sie die Beispiel-App ApkCacheTest zum Testen des APK-Caches.
- Erstellen Sie die App mit dem folgenden Befehl im Stammverzeichnis:
make ApkCacheTest
- Installieren Sie die App als privilegierte App. Denken Sie daran, dass nur privilegierte Apps auf den APK-Cache zugreifen können.
Dazu ist ein gerootetes Gerät erforderlich:
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
- Simulieren Sie bei Bedarf das Dateicache-Verzeichnis und seinen Inhalt (erfordert auch Root-Berechtigungen):
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"
- Testen Sie die App. Nachdem Sie die App installiert und das Testverzeichnis
file_cache
erstellt haben, öffnen Sie die ApkCacheTest App. Es sollte eine Dateitest.txt
und deren Inhalt angezeigt werden. Auf diesem Screenshot sehen Sie, wie diese Ergebnisse in der Benutzeroberfläche angezeigt werden.
Abbildung 1: ApkCacheTest-Ergebnisse