Ce document décrit la conception d'une solution de mise en cache APK pour une installation rapide d'applications préchargées sur un appareil prenant en charge les partitions A/B.
Les OEM peuvent placer des préchargements et des applications populaires dans le cache APK stocké dans la partition B pratiquement vide sur les nouveaux appareils partitionnés A/B sans affecter l'espace de données destiné à l'utilisateur. Grâce à un cache APK disponible sur l'appareil, les appareils nouveaux ou récemment réinitialisés aux paramètres d'usine sont prêts à être utilisés presque immédiatement, sans avoir besoin de télécharger des fichiers APK depuis Google Play.
Cas d'utilisation
- Stockez les applications préchargées dans la partition B pour une configuration plus rapide
- Stockez les applications populaires dans la partition B pour une restauration plus rapide
Conditions préalables
Pour utiliser cette fonctionnalité, l'appareil a besoin de :
- Version Android 8.1 (O MR1) installée
- Partition A/B implémentée
Le contenu préchargé ne peut être copié que lors du premier démarrage. En effet, sur les appareils prenant en charge les mises à jour du système A/B, la partition B ne stocke pas réellement les fichiers d'image système, mais plutôt le contenu préchargé comme les ressources de démonstration au détail, les fichiers OAT et le cache APK. Une fois les ressources copiées sur la partition /data (cela se produit au premier démarrage), la partition B sera utilisée par les mises à jour en direct (OTA) pour télécharger les versions mises à jour de l'image système.
Par conséquent, le cache APK ne peut pas être mis à jour via OTA ; il ne peut être préchargé qu'en usine. La réinitialisation d'usine affecte uniquement la partition /data. La partition système B contient toujours le contenu préchargé jusqu'à ce que l'image OTA soit téléchargée. Après la réinitialisation d'usine, le système effectuera à nouveau le premier démarrage. Cela signifie que la mise en cache APK n'est pas disponible si l'image OTA est téléchargée sur la partition B, puis que l'appareil est réinitialisé aux paramètres d'usine.
Mise en œuvre
Approche 1. Contenu sur la partition system_other
Pro : Le contenu préchargé n'est pas perdu après la réinitialisation d'usine - il sera copié depuis la partition B après un redémarrage.
Inconvénient : Nécessite de l'espace sur la partition B. Le démarrage après la réinitialisation d'usine nécessite plus de temps pour copier le contenu préchargé.
Pour que les préchargements soient copiés lors du premier démarrage, le système appelle un script dans /system/bin/preloads_copy.sh
. Le script est appelé avec un seul argument (chemin d'accès au point de montage en lecture seule pour la partition system_b
) :
Pour implémenter cette fonctionnalité, apportez ces modifications spécifiques à l’appareil. Voici un exemple de Marlin :
- Ajoutez le script qui effectue la copie dans le fichier
device-common.mk
(dans ce cas,device/google/marlin/device-common.mk
), comme ceci :# 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
Recherchez un exemple de source de script sur : device/google/marlin /preloads_copy.sh - Modifiez le fichier
init.common.rc
pour qu'il crée le répertoire et les sous-répertoires/data/preloads
nécessaires :mkdir /data/preloads 0775 system system
mkdir /data/preloads/media 0775 system system
mkdir /data/preloads/demo 0775 system system
init
à l'adresse : device/google/marlin/init.common.rc. - Définissez un nouveau domaine SELinux dans le fichier
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;
Trouvez un exemple de fichier de domaine SELinux à l'adresse : /device/google/marlin/+/main/sepolicy/preloads_copy.te - Enregistrez le domaine dans un nouveau
/sepolicy/file_contexts
fichier :/system/bin/preloads_copy\.sh u:object_r:preloads_copy_exec:s0
Recherchez un exemple de fichier de contextes SELinux à l'adresse : device/google/marlin/sepolicy/preloads_copy.te - Au moment de la construction, le répertoire avec le contenu préchargé doit être copié sur la partition
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)
Ceci est un exemple de modification dans un Makefile qui permet de copier les ressources de cache APK à partir du référentiel Git du fournisseur (dans notre cas, il s'agissait de supplier/google_devices/ marlin/preloads) à l'emplacement sur la partition system_other qui sera ensuite copié dans /data/preloads lors du premier démarrage du périphérique. Ce script s'exécute au moment de la construction pour préparer l'image system_other. Il s'attend à ce que le contenu préchargé soit disponible dans supplier/google_devices/marlin/preloads. L'OEM est libre de choisir le nom/chemin d'accès réel du référentiel. - Le cache APK se trouve dans
/data/preloads/file_cache
et présente la disposition suivante :/data/preloads/file_cache/ app.package.name.1/ file1 fileN app.package.name.N/
Il s'agit de la structure de répertoires finale sur les appareils. Les OEM sont libres de choisir n’importe quelle approche de mise en œuvre à condition que la structure de fichier finale reproduise celle décrite ci-dessus.
Approche 2. Le contenu de l'image des données utilisateur flashé en usine
Cette approche alternative suppose que le contenu préchargé est déjà inclus dans le répertoire /data/preloads
sur la partition /data
.
Pro : Fonctionne immédiatement - pas besoin de personnaliser l'appareil pour copier les fichiers au premier démarrage. Le contenu se trouve déjà sur la partition /data
.
Inconvénient : le contenu préchargé est perdu après une réinitialisation d'usine. Bien que cela puisse être acceptable pour certains, cela peut ne pas toujours fonctionner pour les constructeurs OEM qui réinitialisent leurs appareils après avoir effectué des inspections de contrôle qualité.
Une nouvelle méthode @SystemApi, getPreloadsFileCache()
, a été ajoutée à android.content.Context
. Il renvoie un chemin absolu vers un répertoire spécifique à l'application dans le cache préchargé.
Une nouvelle méthode, IPackageManager.deletePreloadsFileCache
, a été ajoutée pour permettre de supprimer le répertoire de préchargement pour récupérer tout l'espace. La méthode ne peut être appelée que par les applications avec SYSTEM_UID, c'est-à-dire le serveur système ou les paramètres.
Préparation de l'application
Seules les applications privilégiées peuvent accéder au répertoire de cache de préchargements. Pour cet accès, les applications doivent être installées dans le répertoire /system/priv-app
.
Validation
- Après le premier démarrage, le périphérique doit avoir du contenu dans le répertoire
/data/preloads/file_cache
. - Le contenu du répertoire
file_cache/
doit être supprimé si l'appareil manque de stockage.
Utilisez l'exemple d'application ApkCacheTest pour tester le cache APK.
- Créez l'application en exécutant cette commande à partir du répertoire racine :
make ApkCacheTest
- Installez l'application en tant qu'application privilégiée. (N'oubliez pas que seules les applications privilégiées peuvent accéder au cache APK.) Cela nécessite un appareil rooté :
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
- Simulez le répertoire du cache de fichiers et son contenu si nécessaire (nécessitant également les privilèges root) :
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"
- Testez l'application. Après avoir installé l'application et créé le répertoire test
file_cache
, ouvrez l'application ApkCacheTest. Il devrait afficher un fichiertest.txt
et son contenu. Consultez cette capture d'écran pour voir comment ces résultats apparaissent dans l'interface utilisateur. Figure 1. Résultats ApkCacheTest.