Créer des packages OTA

Vous pouvez utiliser l'outil ota_from_target_files fourni dans build/make/tools/releasetools pour créer des packages OTA complets et incrémentiels pour les appareils qui utilisent des mises à jour système A/B ou des mises à jour système non A/B. L'outil utilise en entrée le fichier target-files.zip généré par le système de compilation Android.

Pour les appareils équipés d'Android 11 ou version ultérieure, vous pouvez créer un package OTA pour plusieurs appareils avec différents SKU. Cette opération nécessite de configurer les appareils cibles pour qu'ils utilisent des empreintes dynamiques et de mettre à jour les métadonnées OTA pour inclure le nom et l'empreinte de l'appareil dans les entrées de condition préalable et postcondition.

Android 8.0 a abandonné les packages OTA basés sur les fichiers pour les appareils non A/B, qui doivent utiliser à la place des packages OTA basés sur des fichiers. Pour générer des packages OTA basés sur des blocs ou des appareils équipés d'Android 7.x ou version antérieure, transmettez l'option --block au paramètre ota_from_target_files.

Compiler les mises à jour complètes

Une mise à jour complète est un package OTA qui contient l'intégralité de l'état final de l'appareil (partitions système, de démarrage et de récupération). Tant que l'appareil est capable de recevoir et d'appliquer le package, celui-ci peut installer le build quel que soit l'état actuel de l'appareil. Par exemple, les commandes suivantes utilisent des outils de publication pour créer l'archive target-files.zip pour l'appareil tardis.

. build/envsetup.sh && lunch tardis-eng
mkdir dist_output
make dist DIST_DIR=dist_output

make dist crée un package OTA complet (dans $OUT). Le fichier .zip résultant contient tout ce dont vous avez besoin pour créer des packages OTA pour l'appareil tardis. Vous pouvez également compiler ota_from_target_files en tant que binaire Python et l'appeler pour créer des packages complets ou incrémentiels.

ota_from_target_files dist_output/tardis-target_files.zip ota_update.zip

Le chemin d'accès ota_from_target_files est configuré dans $PATH, et le binaire Python obtenu se trouve dans le répertoire out/.

ota_update.zip est maintenant prêt à être envoyé aux appareils de test (tout est signé avec la clé de test). Pour les appareils des utilisateurs, générez et utilisez vos propres clés privées, comme indiqué dans la section Signer des builds pour la publication.

Compiler des mises à jour incrémentielles

Une mise à jour incrémentielle est un package OTA qui contient des correctifs binaires pour les données déjà présentes sur l'appareil. Les packages avec mises à jour incrémentielles sont généralement plus petits, car ils n'ont pas besoin d'inclure des fichiers non modifiés. De plus, comme les fichiers modifiés sont souvent très similaires à leurs versions précédentes, le package ne doit inclure qu'un encodage des différences entre les deux fichiers.

Vous ne pouvez installer un package de mise à jour incrémentielle que sur les appareils sur lesquels le build source est utilisé pour créer le package. Pour compiler une mise à jour incrémentielle, vous avez besoin du fichier target_files.zip de la compilation précédente (celle dont vous souhaitez effectuer la mise à jour à partir de) ainsi que du fichier target_files.zip de la nouvelle compilation. Par exemple, les commandes suivantes utilisent des outils de publication afin de créer une mise à jour incrémentielle pour l'appareil tardis.

ota_from_target_files -i PREVIOUS-tardis-target_files.zip dist_output/tardis-target_files.zip incremental_ota_update.zip

Cette compilation est très semblable à la précédente, et le package de mise à jour incrémentielle (incremental_ota_update.zip) est beaucoup plus petit que la mise à jour complète correspondante (environ 1 Mo au lieu de 60 Mo).

Distribuez un package incrémentiel uniquement aux appareils qui exécutent exactement la même compilation précédente que celle utilisée comme point de départ du package incrémentiel. Vous devez flasher les images dans PREVIOUS-tardis-target_files.zip ou PREVIOUS-tardis-img.zip (toutes les deux créées avec make dist, pour être flashées avec fastboot update) au lieu de celles situées sous le répertoire PRODUCT_OUT (créées avec make, qui seront flashées avec fastboot flashall). Toute tentative d'installation du package incrémentiel sur un appareil avec un autre build entraîne une erreur d'installation. En cas d'échec de l'installation, l'appareil reste dans le même état de fonctionnement (exécutant l'ancien système). Le package vérifie l'état précédent de tous les fichiers qu'il met à jour avant de les toucher, afin que l'appareil ne soit pas bloqué dans un état à moitié mis à niveau.

Pour une expérience utilisateur optimale, proposez une mise à jour complète toutes les trois à quatre mises à jour incrémentielles. Cela permet aux utilisateurs de rattraper leur retard sur la dernière version et d'éviter une longue séquence d'installation de mises à jour incrémentielles.

Créez des packages OTA pour plusieurs SKU.

Android 11 ou version ultérieure prend en charge l'utilisation d'un seul package OTA pour plusieurs appareils avec différents SKU. Cela nécessite de configurer les appareils cibles pour qu'ils utilisent des empreintes dynamiques et de mettre à jour les métadonnées OTA (à l'aide d'outils OTA) pour inclure le nom et l'empreinte de l'appareil dans les entrées de condition avant et après.

À propos des SKU

Le format d'un SKU est une variante des valeurs combinées des paramètres de compilation. Il s'agit généralement d'un sous-ensemble non déclaré des paramètres build_fingerprint actuels. Les OEM peuvent utiliser n'importe quelle combinaison de paramètres de compilation approuvés par le CDD pour un SKU, tout en utilisant une seule image pour ces SKU. Par exemple, le SKU suivant présente plusieurs variantes:

SKU = <product><device><modifierA><modifierB><modifierC>
  • modifierA est le niveau de l'appareil (Pro, Premium ou Plus, par exemple).
  • modifierB correspond à la variante matérielle (telle que la radio).
  • modifierC correspond à la région, qui peut être générique (par exemple, NA, EMEA ou CHN), ou propre à un pays ou à une langue (par exemple, JPN, ENG ou CHN).

De nombreux OEM utilisent une seule image pour plusieurs SKU, puis extraient le nom final du produit et l'empreinte de l'appareil au moment de l'exécution, après le démarrage de l'appareil. Ce processus simplifie le processus de développement de la plate-forme en permettant aux appareils avec des personnalisations mineures, mais des noms de produits différents de partager des images communes (telles que tardis et tardispro).

Utiliser des empreintes dynamiques

Une empreinte est une concaténation définie de paramètres de compilation tels que ro.product.brand, ro.product.name et ro.product.device. L'empreinte d'un appareil est dérivée de l'empreinte de la partition système et sert d'identifiant unique des images (et des octets) exécutées sur l'appareil. Pour créer une empreinte dynamique, utilisez la logique dynamique dans le fichier build.prop de l'appareil afin d'obtenir la valeur des variables du bootloader au démarrage de l'appareil, puis utilisez ces données pour créer une empreinte dynamique pour cet appareil.

Par exemple, pour utiliser des empreintes dynamiques pour les appareils tardis et tardispro, mettez à jour les fichiers suivants, comme indiqué ci-dessous.

  • Mettez à jour le fichier odm/etc/build_std.prop pour qu'il contienne la ligne suivante.

    ro.odm.product.device=tardis
    
  • Mettez à jour le fichier odm/etc/build_pro.prop pour qu'il contienne la ligne suivante.

    ro.odm.product.device=tardispro
    
  • Mettez à jour le fichier odm/etc/build.prop pour qu'il contienne les lignes suivantes.

    ro.odm.product.device=tardis
    import /odm/etc/build_${ro.boot.product.hardware.sku}.prop
    

Ces lignes définissent de manière dynamique le nom de l'appareil, l'empreinte et les valeurs ro.build.fingerprint en fonction de la valeur de la propriété bootloader ro.boot.product.hardware.sku (qui est en lecture seule).

Mettre à jour les métadonnées du package OTA

Un package OTA contient un fichier de métadonnées (META-INF/com/android/metadata) qui le décrit, y compris la condition préalable et la condition post-condition du package OTA. Par exemple, le code suivant est le fichier de métadonnées d'un package OTA ciblant l'appareil tardis.

post-build=google/tardis/tardis:11/RP1A.200521.001/6516341:userdebug/dev-keys
post-build-incremental=6516341
post-sdk-level=30
post-security-patch-level=2020-07-05
post-timestamp=1590026334
pre-build=google/tardis/tardis:11/RP1A.200519.002.A1/6515794:userdebug/dev-keys
pre-build-incremental=6515794
pre-device=tardis

Les valeurs pre-device, pre-build-incremental et pre-build définissent l'état d'un appareil pour que le package OTA puisse être installé. Les valeurs post-build-incremental et post-build définissent l'état attendu d'un appareil après l'installation du package OTA. Les valeurs des champs pre- et post- sont dérivées des propriétés de compilation correspondantes suivantes.

  • La valeur pre-device est dérivée de la propriété de compilation ro.product.device.
  • Les valeurs pre-build-incremental et post-build-incremental sont dérivées de la propriété de compilation ro.build.version.incremental.
  • Les valeurs pre-build et post-build sont dérivées de la propriété de compilation ro.build.fingerprint.

Sur les appareils équipés d'Android 11 ou version ultérieure, vous pouvez utiliser l'indicateur --boot_variable_file dans les outils OTA pour spécifier un chemin d'accès à un fichier contenant les valeurs des variables d'exécution utilisées pour créer l'empreinte dynamique de l'appareil. Les données sont ensuite utilisées pour mettre à jour les métadonnées OTA afin d'inclure le nom et l'empreinte de l'appareil dans les conditions pre- et post- (en utilisant la barre verticale | comme délimiteur). L'option --boot_variable_file présente la syntaxe et la description suivantes.

  • Syntaxe : --boot_variable_file <path>
  • Description: spécifie le chemin d'accès à un fichier contenant les valeurs possibles des propriétés ro.boot.*. Permet de calculer les empreintes d'exécution possibles lorsque certaines propriétés ro.product.* sont remplacées par l'instruction d'importation. Le fichier attend une propriété par ligne au format suivant: prop_name=value1,value2.

Par exemple, lorsque la propriété est ro.boot.product.hardware.sku=std,pro, les métadonnées OTA pour les appareils tardis et tardispro sont présentées ci-dessous.

post-build=google/tardis/tardis:11/<suffix>|google/tardis/tardispro:11/<suffix>
pre-build=google/tardis/tardis:11/<suffix>|google/tardis/tardispro:11/<suffix>
pre-device=tardis|tardispro

Pour prendre en charge cette fonctionnalité sur les appareils équipés d'Android 10, consultez la mise en œuvre de référence. Cette liste de modifications analyse de manière conditionnelle les instructions import dans le fichier build.prop, ce qui permet de reconnaître les remplacements de propriété et de les refléter dans les métadonnées OTA finales.