Dieses Dokument beschreibt den Entwurf einer APK-Caching-Lösung für die schnelle Installation vorinstallierter Apps auf einem Gerät, das A/B-Partitionen unterstützt.
OEMs können Preloads und beliebte Apps im APK-Cache ablegen, der in der größtenteils leeren B-Partition auf neuen A/B-partitionierten Geräten gespeichert ist, ohne den benutzerseitigen Datenraum zu beeinträchtigen. Da auf dem Gerät ein APK-Cache verfügbar ist, 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
- Speichern Sie vorinstallierte Apps in der B-Partition, um die Einrichtung zu beschleunigen
- Speichern Sie beliebte Apps für eine schnellere Wiederherstellung in der B-Partition
Voraussetzungen
Um diese Funktion nutzen zu können, benötigt das Gerät:
- Version Android 8.1 (O MR1) installiert
- A/B-Partition implementiert
Vorinstallierte Inhalte können nur beim ersten Start kopiert werden. Dies liegt daran, dass auf Geräten, die A/B-Systemaktualisierungen unterstützen, auf der B-Partition keine System-Image-Dateien, sondern vorinstallierte Inhalte wie Demo-Ressourcen für den Einzelhandel, OAT-Dateien und der APK-Cache gespeichert sind. Nachdem Ressourcen auf die /data-Partition kopiert wurden (dies geschieht beim ersten Start), wird die B-Partition von Over-the-Air-Updates (OTA) zum Herunterladen aktualisierter Versionen des Systemabbilds verwendet.
Daher kann der APK-Cache nicht über OTA aktualisiert werden; Es kann nur im Werk vorgeladen werden. Das Zurücksetzen auf die Werkseinstellungen betrifft nur die /data-Partition. Die System-B-Partition verfügt weiterhin über den vorinstallierten Inhalt, bis das OTA-Image heruntergeladen wird. Nach dem Zurücksetzen auf die Werkseinstellungen durchläuft das System erneut den ersten Startvorgang. Dies bedeutet, dass das APK-Caching nicht verfügbar ist, wenn das OTA-Image auf die B-Partition heruntergeladen wird und das Gerät dann auf die Werkseinstellungen zurückgesetzt wird.
Implementierung
Ansatz 1. Inhalt auf system_other-Partition
Vorteil : Vorinstallierte Inhalte gehen nach dem Zurücksetzen auf die Werkseinstellungen nicht verloren – sie werden nach einem Neustart von der B-Partition kopiert.
Nachteil : Benötigt Speicherplatz auf Partition B. Das Starten nach dem Zurücksetzen auf die Werkseinstellungen erfordert zusätzliche Zeit zum Kopieren vorinstallierter Inhalte.
Damit Preloads beim ersten Start kopiert werden können, ruft das System ein Skript in /system/bin/preloads_copy.sh
auf. Das Skript wird mit einem einzigen Argument aufgerufen (Pfad zum schreibgeschützten Mountpunkt für system_b
Partition):
Um diese Funktion zu implementieren, nehmen Sie diese gerätespezifischen Änderungen vor. Hier ist ein Beispiel von Marlin:
- Fügen Sie das Skript, das das Kopieren durchführt, zur Datei
device-common.mk
hinzu (in diesem Falldevice/google/marlin/device-common.mk
“), etwa so:# 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
Die Beispielskriptquelle finden Sie unter: device/google/marlin /preloads_copy.sh - Bearbeiten Sie die Datei
init.common.rc
, damit sie das erforderliche Verzeichnis/data/preloads
und die Unterverzeichnisse erstellt:mkdir /data/preloads 0775 system system
mkdir /data/preloads/media 0775 system system
mkdir /data/preloads/demo 0775 system system
init
Datei finden Sie unter: device/google/marlin/init.common.rc - Definieren Sie eine neue SELinux-Domäne in der Datei
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;
Eine Beispiel-SELinux-Domänendatei finden Sie unter: /device/google/marlin/+/main/sepolicy/preloads_copy.te - Registrieren Sie die Domain neu
/sepolicy/file_contexts
Datei:/system/bin/preloads_copy\.sh u:object_r:preloads_copy_exec:s0
Eine Beispiel-SELinux-Kontextdatei finden Sie unter: device/google/marlin/sepolicy/preloads_copy.te - Zum Zeitpunkt der Erstellung muss das Verzeichnis mit vorinstalliertem Inhalt in die
system_other
Partition kopiert werden:# 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)
Dies ist ein Beispiel für eine Änderung in einem Makefile, die das Kopieren von APK-Cache-Ressourcen aus dem Git-Repository des Anbieters ermöglicht (in unserem Fall war es Vendor/google_devices/). marlin/preloads) an den Speicherort auf der system_other-Partition, der später nach /data/preloads kopiert wird, wenn das Gerät zum ersten Mal startet. Dieses Skript wird zur Erstellungszeit ausgeführt, um das system_other-Image vorzubereiten. Es wird erwartet, dass vorinstallierte Inhalte unter „vendor/google_devices/marlin/preloads“ verfügbar sind. Der OEM kann den tatsächlichen Namen/Pfad des Repositorys frei wählen. - Der APK-Cache befindet sich in
/data/preloads/file_cache
und hat das folgende Layout:/data/preloads/file_cache/ app.package.name.1/ file1 fileN app.package.name.N/
Dies ist die endgültige Verzeichnisstruktur auf den Geräten. OEMs können jeden Implementierungsansatz frei wählen, solange die endgültige Dateistruktur der oben beschriebenen entspricht.
Ansatz 2. Der Inhalt des Benutzerdaten-Images wurde werkseitig geflasht
Bei diesem alternativen Ansatz wird davon ausgegangen, dass vorinstallierte Inhalte bereits im Verzeichnis /data/preloads
auf der Partition /data
enthalten sind.
Pro : Funktioniert sofort – es sind keine Geräteanpassungen erforderlich, um Dateien beim ersten Start zu kopieren. Der Inhalt befindet sich bereits auf der /data
Partition.
Nachteil : Vorinstallierte Inhalte gehen nach einem Zurücksetzen auf die Werkseinstellungen verloren. Während dies für einige akzeptabel sein mag, funktioniert es möglicherweise nicht immer für OEMs, die Geräte nach Durchführung von Qualitätskontrollinspektionen auf die Werkseinstellungen zurücksetzen.
Eine neue @SystemApi-Methode, getPreloadsFileCache()
, wurde zu android.content.Context
hinzugefügt. Es gibt einen absoluten Pfad zu einem App-spezifischen Verzeichnis im vorinstallierten Cache zurück.
Eine neue Methode, IPackageManager.deletePreloadsFileCache
, wurde hinzugefügt, die das Löschen des Preloads-Verzeichnisses ermöglicht, um den gesamten Speicherplatz zurückzugewinnen. Die Methode kann nur von Apps mit SYSTEM_UID aufgerufen werden, also Systemserver oder Einstellungen.
App-Vorbereitung
Nur privilegierte Apps können auf das Preloads-Cache-Verzeichnis zugreifen. Für diesen Zugriff müssen Apps im Verzeichnis /system/priv-app
installiert sein.
Validierung
- Nach dem ersten Start sollte das Gerät über Inhalte im Verzeichnis
/data/preloads/file_cache
verfügen. - Der Inhalt im Verzeichnis
file_cache/
muss gelöscht werden, wenn auf dem Gerät nicht mehr genügend Speicherplatz vorhanden ist.
Verwenden Sie die Beispiel- ApkCacheTest- App zum Testen des APK-Cache.
- 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.) Dies erfordert ein gerootetes Gerät:
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 Datei-Cache-Verzeichnis und seinen Inhalt (erfordern auch Root-Rechte):
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 Verzeichnisses test
file_cache
die ApkCacheTest-App. Es sollte eine Dateitest.txt
und deren Inhalt anzeigen. Sehen Sie sich diesen Screenshot an, um zu sehen, wie diese Ergebnisse auf der Benutzeroberfläche angezeigt werden. Abbildung 1. ApkCacheTest-Ergebnisse.