APK-Caching

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 in 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 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 die system_b Partition):

Um diese Funktion zu implementieren, nehmen Sie diese gerätespezifischen Änderungen vor. Hier ist ein Beispiel von Marlin:

  1. Fügen Sie das Skript, das das Kopieren durchführt, zur Datei device-common.mk hinzu (in diesem Fall device/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
  2. 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
    
    Die Quelle der Beispiel- init -Datei finden Sie unter: device/google/marlin/init.common.rc
  3. 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
  4. 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
  5. Zur Erstellungszeit 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.
  6. 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 anwendungsspezifischen 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 Anwendungen 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.

  1. Erstellen Sie die App, indem Sie diesen Befehl im Stammverzeichnis ausführen:
    make ApkCacheTest
    
  2. Installieren Sie die App als privilegierte Anwendung. (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
    
  3. 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"
    
  4. 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 Datei test.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