À l'intérieur des forfaits OTA

Le système crée le binaire de mise à jour à partir de bootable/recovery/updater et l'utilise dans un package OTA.

Le package lui-même est un fichier .zip ( ota_update.zip , incremental_ota_update.zip ) qui contient le binaire exécutable META-INF/com/google/android/update-binary .

Updater contient plusieurs fonctions intégrées et un interpréteur pour un langage de script extensible ( edify ) qui prend en charge les commandes pour les tâches typiques liées à la mise à jour. Le programme de mise à jour recherche dans le fichier .zip du package un script dans le fichier META-INF/com/google/android/updater-script .

Remarque : L'utilisation du script edify et/ou des fonctions intégrées n'est pas une activité courante, mais peut être utile si vous devez déboguer le fichier de mise à jour.

Edifier la syntaxe

Un script edify est une expression unique dans laquelle toutes les valeurs sont des chaînes. Les chaînes vides sont fausses dans un contexte booléen et toutes les autres chaînes sont vraies . Edify prend en charge les opérateurs suivants (avec les significations habituelles) :

(expr )
 expr + expr  # string concatenation, not integer addition
 expr == expr
 expr != expr
 expr && expr
 expr || expr
 ! expr
 if expr then expr endif
 if expr then expr else expr endif
 function_name(expr, expr,...)
 expr; expr

Toute chaîne de caractères az, AZ, 0-9, _, :, /, . ce n'est pas un mot réservé est considéré comme une chaîne littérale. (Les mots réservés sont if else then endif. ) Les chaînes littérales peuvent également apparaître entre guillemets ; voici comment créer des valeurs avec des espaces et d'autres caractères ne figurant pas dans l'ensemble ci-dessus. \n, \t, \", et \\ servent d'échappement dans les chaînes entre guillemets, tout comme \x ## .

Le && et || les opérateurs court-circuitent ; le côté droit n'est pas évalué si le résultat logique est déterminé par le côté gauche. Les éléments suivants sont équivalents :

e1 && e2
if e1 then e2 endif

Le ; l'opérateur est un point de séquence ; cela signifie évaluer d’abord le côté gauche puis le côté droit. Sa valeur est la valeur de l’expression du côté droit. Un point-virgule peut également apparaître après une expression, de sorte que l'effet simule des instructions de style C :

prepare();
do_other_thing("argument");
finish_up();

Fonctions intégrées

La plupart des fonctionnalités de mise à jour sont contenues dans les fonctions disponibles pour l'exécution par des scripts. (À proprement parler, ce sont des macros plutôt que des fonctions au sens Lisp, puisqu'elles n'ont pas besoin d'évaluer tous leurs arguments.) Sauf indication contraire, les fonctions renvoient vrai en cas de succès et faux en cas d'erreur. Si vous souhaitez que des erreurs interrompent l'exécution du script, utilisez les fonctions abort() et/ou assert() . L'ensemble des fonctions disponibles dans le programme de mise à jour peut également être étendu pour fournir des fonctionnalités spécifiques à l'appareil .

abort([ msg ])
Abandonne immédiatement l'exécution du script, avec le msg facultatif. Si l'utilisateur a activé l'affichage du texte, le message apparaît dans le journal de récupération et à l'écran.
assert( expr [, expr , ...])
Évalue chaque expr tour à tour. Si any est faux, abandonne immédiatement l'exécution avec le message « échec de l'affirmation » et le texte source de l'expression ayant échoué.
apply_patch( src_file , tgt_file , tgt_sha1 , tgt_size , patch1_sha1 , patch1_blob , [...])
Applique un patch binaire au src_file pour produire le tgt_file . Si la cible souhaitée est la même que la source, passez "-" pour tgt_file . tgt_sha1 et tgt_size sont le hachage SHA1 final attendu et la taille du fichier cible. Les arguments restants doivent être présentés par paires : un hachage SHA1 (une chaîne hexadécimale de 40 caractères) et un blob. Le blob est le correctif à appliquer lorsque le contenu actuel du fichier source a le SHA1 donné.

L'application des correctifs est effectuée de manière sûre, garantissant que le fichier cible possède le hachage et la taille SHA1 souhaités ou qu'il est intact : il ne sera pas laissé dans un état intermédiaire irrécupérable. Si le processus est interrompu pendant l'application des correctifs, le fichier cible peut être dans un état intermédiaire ; une copie existe dans la partition de cache, donc le redémarrage de la mise à jour peut mettre à jour le fichier avec succès.

Une syntaxe spéciale est prise en charge pour traiter le contenu des partitions Memory Technology Device (MTD) comme des fichiers, permettant l'application de correctifs aux partitions brutes telles que le démarrage. Pour lire une partition MTD, vous devez savoir combien de données vous souhaitez lire puisque la partition n'a pas de notion de fin de fichier. Vous pouvez utiliser la chaîne "MTD: partition : size_1 : sha1_1 : size_2 : sha1_2 " comme nom de fichier pour lire la partition donnée. Vous devez spécifier au moins une paire (taille, sha-1) ; vous pouvez en spécifier plusieurs s'il existe plusieurs possibilités pour ce que vous attendez de lire.

apply_patch_check( filename , sha1 [, sha1 , ...])
Renvoie vrai si le contenu du nom de fichier ou la copie temporaire dans la partition de cache (si présente) a une somme de contrôle SHA1 égale à l'une des valeurs sha1 données. Les valeurs sha1 sont spécifiées sous forme de 40 chiffres hexadécimaux. Cette fonction diffère de sha1_check(read_file( filename ), sha1 [, ...]) en ce sens qu'elle sait vérifier la copie de la partition de cache, donc apply_patch_check() réussira même si le fichier a été corrompu par une apply_patch() update .
apply_patch_space( bytes )
Renvoie vrai si au moins des octets d'espace de travail sont disponibles pour l'application de correctifs binaires.
concat( expr [, expr , ...])
Évalue chaque expression et les concatène. L'opérateur + est le sucre syntaxique de cette fonction dans le cas particulier de deux arguments (mais la forme de la fonction peut prendre n'importe quel nombre d'expressions). Les expressions doivent être des chaînes ; il ne peut pas concaténer des blobs.
file_getprop( filename , key )
Lit le nom de fichier donné, l'interprète comme un fichier de propriétés (par exemple /system/build.prop ) et renvoie la valeur de la key donnée, ou la chaîne vide si la key n'est pas présente.
format( fs_type , partition_type , location , fs_size , mount_point )
Reformate une partition donnée. Types de partitions pris en charge :
  • fs_type="yaffs2" et partition_type="MTD". L'emplacement doit être le nom de la partition MTD ; un système de fichiers yaffs2 vide y est construit. Les arguments restants ne sont pas utilisés.
  • fs_type="ext4" et partition_type="EMMC". L'emplacement doit être le fichier de périphérique de la partition. Un système de fichiers ext4 vide y est construit. Si fs_size vaut zéro, le système de fichiers occupe la totalité de la partition. Si fs_size est un nombre positif, le système de fichiers prend les premiers octets fs_size de la partition. Si fs_size est un nombre négatif, le système de fichiers prend tout sauf le dernier |fs_size| octets de la partition.
  • fs_type="f2fs" et partition_type="EMMC". L'emplacement doit être le fichier de périphérique de la partition. fs_size doit être un nombre non négatif. Si fs_size vaut zéro, le système de fichiers occupe la totalité de la partition. Si fs_size est un nombre positif, le système de fichiers prend les premiers octets fs_size de la partition.
  • mount_point devrait être le futur point de montage du système de fichiers.
getprop( key )
Renvoie la valeur de la clé de propriété système (ou la chaîne vide, si elle n'est pas définie). Les valeurs des propriétés système définies par la partition de récupération ne sont pas nécessairement les mêmes que celles du système principal. Cette fonction renvoie la valeur en récupération.
greater_than_int( a , b )
Renvoie vrai si et seulement si (iff) a (interprété comme un entier) est supérieur à b (interprété comme un entier).
ifelse( cond , e1 [, e2 ])
Évalue cond , et si c'est vrai, évalue et renvoie la valeur de e1 , sinon il évalue et renvoie e2 (si présent). La construction "if ... else ... then ... endif" n'est qu'un sucre syntaxique pour cette fonction.
is_mounted( mount_point )
Renvoie vrai si un système de fichiers est monté au point_montage .
is_substring( needle , haystack )
Renvoie vrai si Needle est une sous-chaîne de haystack .
less_than_int( a , b )
Renvoie vrai si a (interprété comme un entier) est inférieur à b (interprété comme un entier).
mount( fs_type , partition_type , name , mount_point )
Monte un système de fichiers de fs_type à mount_point . partition_type doit être l'un des suivants :
  • MTD . Name est le nom d'une partition MTD (par exemple, système, données utilisateur ; voir /proc/mtd sur le périphérique pour une liste complète).
  • EMMC.

La récupération ne monte aucun système de fichiers par défaut (à l'exception de la carte SD si l'utilisateur effectue une installation manuelle d'un package à partir de la carte SD) ; votre script doit monter toutes les partitions qu'il doit modifier.

package_extract_dir( package_dir , dest_dir )
Extrait tous les fichiers du package sous package_dir et les écrit dans l'arborescence correspondante sous dest_dir . Tous les fichiers existants sont écrasés.
package_extract_file( package_file [, dest_file ])
Extrait un seul package_file du package de mise à jour et l'écrit dans dest_file , en écrasant les fichiers existants si nécessaire. Sans l'argument dest_file , renvoie le contenu du fichier du package sous forme de blob binaire.
read_file( filename )
Lit le nom du fichier et renvoie son contenu sous forme de blob binaire.
run_program( path [, arg , ...])
Exécute le binaire à path , en passant arg s. Renvoie l'état de sortie du programme.
set_progress( frac )
Définit la position de la jauge de progression dans le bloc défini par l'appel show_progress() le plus récent. frac doit être compris entre [0,0 et 1,0]. La jauge de progression ne recule jamais ; les tentatives pour y parvenir sont ignorées.
sha1_check( blob [, sha1 ])
L'argument blob est un blob du type renvoyé par read_file() ou la forme à un argument de package_extract_file() . Sans arguments sha1 , cette fonction renvoie le hachage SHA1 du blob (sous forme de chaîne hexadécimale de 40 chiffres). Avec un ou plusieurs arguments sha1 , cette fonction renvoie le hachage SHA1 s'il est égal à l'un des arguments, ou la chaîne vide si elle n'est égale à aucun d'entre eux.
show_progress( frac , secs )
Avance la jauge de progression sur la frac suivante de sa longueur sur les secondes secondes (doit être un nombre entier). secs peut être 0, auquel cas le compteur n'avance pas automatiquement mais en utilisant la fonction set_progress() définie ci-dessus.
sleep( secs )
Dort pendant quelques secondes (doit être un nombre entier).
stdout( expr [, expr , ...])
Évalue chaque expression et vide sa valeur sur la sortie standard. Utile pour le débogage.
tune2fs( device [, arg , …])
Ajuste les paramètres réglables sur l'appareil .
ui_print([ text , ...])
Concatène tous les arguments de texte et imprime le résultat sur l'interface utilisateur (où il sera visible si l'utilisateur a activé l'affichage du texte).
unmount( mount_point )
Démonte le système de fichiers monté à mount_point .
wipe_block_device( block_dev , len )
Efface les octets len du périphérique de bloc donné block_dev .
wipe_cache()
Provoque l'effacement de la partition de cache à la fin d'une installation réussie.
write_raw_image( filename_or_blob , partition )
Écrit l'image dans filename_or_blob sur la partition MTD. filename_or_blob peut être une chaîne nommant un fichier local ou un argument de valeur blob contenant les données à écrire. Pour copier un fichier du package OTA vers une partition, utilisez : write_raw_image(package_extract_file("zip_filename"), "partition_name");

Remarque : Avant Android 4.1, seuls les noms de fichiers étaient acceptés. Pour ce faire, les données devaient d'abord être décompressées dans un fichier local temporaire.