In diesem Dokument wird das Design einer APK-Caching-Lösung für die schnelle Installation vorinstallierter Apps auf einem Gerät mit A/B-Partitionen beschrieben.
Auf neuen A/B-partitionierten Geräten können OEMs Vorabinstallationen und beliebte Apps im APK-Cache platzieren, der sich in der meist leeren B-Partition befindet, ohne den für Nutzer sichtbaren Datenbereich zu beeinträchtigen. Durch den APK-Cache auf dem Gerät sind neue oder kürzlich auf die Werkseinstellungen zurückgesetzte Geräte fast sofort einsatzbereit, ohne dass APK-Dateien von Google Play heruntergeladen werden müssen.
Anwendungsfälle
- Vorab geladene Apps in Partition B speichern, um die Einrichtung zu beschleunigen
- Beliebte Apps in Partition B speichern, um sie schneller wiederherstellen zu können
Voraussetzungen
Damit diese Funktion genutzt werden kann, muss das Gerät Folgendes bieten:
- Android 8.1 (O MR1) ist installiert.
- A/B-Aufteilung implementiert
Vorinstallierte Inhalte können nur beim ersten Start kopiert werden. Das liegt daran, dass auf Geräten, die A/B-Systemupdates unterstützen, auf der B-Partition keine Systemimage-Dateien gespeichert werden, sondern vorab geladene Inhalte wie Ressourcen für die Einzelhandelsdemo, OAT-Dateien und der APK-Cache. Nachdem Ressourcen in die Partition „/data“ kopiert wurden (dies geschieht beim ersten Start), wird die B-Partition von Over-the-Air-Updates (OTA) verwendet, um aktualisierte Versionen des System-Images herunterzuladen.
Daher kann der APK-Cache nicht über OTA aktualisiert werden. Er kann nur in einer Fabrik vorab geladen werden. Das Zurücksetzen auf die Werkseinstellungen wirkt sich nur auf die Partition „/data“ aus. Die B-Partition des Systems enthält weiterhin die vorinstallierten Inhalte, bis das OTA-Image heruntergeladen wurde. Nach dem Zurücksetzen auf die Werkseinstellungen wird das System noch einmal neu gestartet. Das bedeutet, dass das APK-Caching nicht verfügbar ist, wenn das OTA-Image auf 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 aus der B-Partition kopiert.
Nachteil: Erfordert Speicherplatz auf der B-Partition. Das Booten nach dem Zurücksetzen auf die Werkseinstellungen dauert länger, da vorinstallierte Inhalte kopiert werden müssen.
Damit Vorabinstallationen beim ersten Start kopiert werden, ruft das System ein Skript in /system/bin/preloads_copy.sh
auf. Das Script wird mit einem einzelnen Argument aufgerufen (Pfad zum schreibgeschützten Bereitstellungspunkt für die system_b
-Partition):
Um diese Funktion zu implementieren, müssen Sie die folgenden gerätespezifischen Änderungen vornehmen. Hier ist ein Beispiel aus Marlin:
- Fügen Sie das Skript, mit dem die Dateien kopiert werden, der Datei
device-common.mk
(in diesem Falldevice/google/marlin/device-common.mk
) hinzu: Beispielskriptquelle: 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
so, dass das erforderliche Verzeichnis/data/preloads
und die Unterverzeichnisse erstellt werden: Beispiel für diemkdir /data/preloads 0775 system system
mkdir /data/preloads/media 0775 system system
mkdir /data/preloads/demo 0775 system system
init
-Dateiquelle: device/google/marlin/init.common.rc - Definieren Sie eine neue SELinux-Domain in der Datei
preloads_copy.te
: Eine Beispieldatei für die SELinux-Domain finden Sie unter /device/google/marlin/+/android16-release/sepolicy/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;
- Registrieren Sie die Domain in einer neuen
-Datei:/sepolicy/file_contexts Eine Beispielkontextdatei für SELinux finden Sie unter device/google/marlin/sepolicy/preloads_copy.te./system/bin/preloads_copy\.sh u:object_r:preloads_copy_exec:s0
- Zur Build-Zeit muss das Verzeichnis mit vorab geladenen Inhalten in die Partition
system_other
kopiert werden: Dies ist ein Beispiel für eine Änderung in einer Makefile, die das Kopieren von APK-Cache-Ressourcen aus dem Git-Repository des Anbieters (in unserem Fall vendor/google_devices/marlin/preloads) an den Speicherort auf der Partition „system_other“ ermöglicht, der später beim ersten Start des Geräts nach /data/preloads kopiert wird. Dieses Skript wird zur Build-Zeit ausgeführt, um das Image „system_other“ vorzubereiten. Vorinstallierte Inhalte werden unter „vendor/google_devices/marlin/preloads“ erwartet. Der OEM kann den tatsächlichen Repository-Namen bzw. -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 in
/data/preloads/file_cache
und hat das folgende Layout: Dies ist die endgültige Verzeichnisstruktur auf den Geräten. OEMs können einen beliebigen 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 Bild mit Nutzerdaten, das im Werk aufgespielt wurde
Bei diesem alternativen Ansatz wird davon ausgegangen, dass vorab geladene Inhalte bereits im Verzeichnis /data/preloads
auf der Partition /data
enthalten sind.
Vorteil: Funktioniert sofort. Es sind keine Geräteanpassungen erforderlich, um Dateien beim ersten Start zu kopieren. In der Partition /data
sind bereits Inhalte vorhanden.
Nachteil: Vorinstallierte Inhalte gehen nach dem Zurücksetzen auf die Werkseinstellungen verloren. Für einige ist das vielleicht akzeptabel, für OEMs, die Geräte nach der Qualitätskontrolle auf die Werkseinstellungen zurücksetzen, jedoch nicht immer.
Der Klasse android.content.Context
wurde eine neue @SystemApi-Methode, getPreloadsFileCache()
, hinzugefügt. Es wird ein absoluter Pfad zu einem app-spezifischen Verzeichnis im vorab geladenen Cache zurückgegeben.
Es wurde eine neue Methode, IPackageManager.deletePreloadsFileCache
, hinzugefügt, mit der das Vorabladungsverzeichnis gelöscht werden kann, um den gesamten Speicherplatz freizugeben. Die Methode kann nur von Apps mit SYSTEM_UID aufgerufen werden, d.h. vom Systemserver oder von den Einstellungen.
App-Vorbereitung
Nur Apps mit Berechtigungen können auf das Cache-Verzeichnis für Preloads zugreifen. Für diesen Zugriff 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, um den APK-Cache zu testen.
- Erstellen Sie die App, indem Sie diesen Befehl im Stammverzeichnis ausführen:
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 Dateicacheverzeichnis 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. Öffnen Sie nach der Installation der App und dem Erstellen des Testverzeichnisses
file_cache
die App „ApkCacheTest“. Sie sollte eine Dateitest.txt
und deren Inhalt anzeigen. Auf diesem Screenshot sehen Sie, wie diese Ergebnisse in der Benutzeroberfläche angezeigt werden.
Abbildung 1: ApkCacheTest-Ergebnisse.