Le système compile le binaire du programme de mise à jour à partir de bootable/recovery/updater
et l'utilise dans un package OTA.
ota_update.zip
, incremental_ota_update.zip
) contenant le binaire exécutable META-INF/com/google/android/update-binary
.
Le programme de mise à jour contient plusieurs fonctions intégrées et un interprète pour un langage de script extensible (edify) compatible avec les commandes des tâches de mise à jour typiques. Le programme de mise à jour recherche un script dans le fichier META-INF/com/google/android/updater-script
du fichier .zip du package.
Remarque:L'utilisation du script edify et/ou des fonctions intégrées n'est pas une activité courante, mais elle peut être utile si vous devez déboguer le fichier de mise à jour.
Syntaxe d'édition
Un script edify est une expression unique dans laquelle toutes les valeurs sont des chaînes. Les chaînes vides sont false dans un contexte booléen et toutes les autres chaînes sont true. Edify est compatible avec 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 a-z, A-Z, 0-9, _, :, /, . qui n'est pas un mot réservé est considéré comme une valeur littérale de chaîne. (Les mots réservés sont if else , puis endif.) Les valeurs littérales de chaîne peuvent également apparaître entre guillemets doubles. C'est ainsi que vous créez des valeurs avec des espaces et d'autres caractères qui ne figurent pas dans l'ensemble ci-dessus. \n, \t, \" et \\ servent d'échappement dans les chaînes entre guillemets, tout comme \x##.
Les opérateurs && et || sont des opérateurs de court-circuitage. Le côté droit n'est pas évalué si le résultat logique est déterminé par le côté gauche. Les expressions suivantes sont équivalentes:
e1 && e2 if e1 then e2 endif
L'opérateur ; est un point de séquence. Il signifie que vous devez d'abord évaluer le côté gauche, puis le côté droit. Sa valeur correspond à celle de l'expression de droite. Un point-virgule peut également apparaître après une expression, ce qui simule les 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 les scripts.
(Strictement parlant, il s'agit de macros plutôt que de fonctions au sens Lisp, car elles n'ont pas besoin d'évaluer tous leurs arguments.) Sauf indication contraire, les fonctions renvoient true en cas de réussite et false en cas d'erreur. Si vous souhaitez que les erreurs arrêtent 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])
- Arrête immédiatement l'exécution du script, avec l'option msg facultative. Si l'utilisateur a activé l'affichage du texte, msg s'affiche dans le journal de récupération et à l'écran.
-
assert(expr[, expr, ...])
- Évalue chaque expr à son tour. Si l'une d'elles est fausse, l'exécution est immédiatement interrompue avec le message "assert failed" (échec de l'assertion) 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 correctif binaire au fichier_source pour générer le fichier_cible. Si la cible souhaitée est identique à la source, transmettez "-" pour tgt_file . tgt_sha1 et tgt_size correspondent au hachage SHA1 final et à la taille attendus du fichier cible. Les arguments restants doivent être présentés par paires: un hachage SHA1 (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é.
Le correctif est appliqué de manière sécurisée, ce qui garantit 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 le correctif, le fichier cible peut se trouver dans un état intermédiaire. Une copie existe dans la partition de cache. Le redémarrage de la mise à jour permet donc de mettre à jour le fichier.
Une syntaxe spéciale est prise en charge pour traiter le contenu des partitions MTD (Memory Technology Device) en tant que fichiers, ce qui permet de corriger les partitions brutes telles que le démarrage. Pour lire une partition MTD, vous devez connaître la quantité de données que vous souhaitez lire, car 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 si vous ne savez pas exactement ce que vous voulez lire.
-
apply_patch_check(filename, sha1[, sha1, ...])
-
Renvoie la valeur "true" si le contenu de nom de fichier ou la copie temporaire dans la partition de cache (le cas échéant) ont une somme de contrôle SHA1 égale à l'une des valeurs sha1 données.
Les valeurs sha1 sont spécifiées sous la 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.apply_patch_check()
réussira donc même si le fichier a été corrompu par unapply_patch() update
interrompu. apply_patch_space(bytes)
- Renvoie "true" si au moins octets d'espace de travail sont disponibles pour appliquer les correctifs binaires.
-
concat(expr[, expr, ...])
- Évalue chaque expression et les concatène. L'opérateur + est un sucre syntaxique pour cette fonction dans le cas particulier de deux arguments (mais la forme de la fonction peut prendre un nombre illimité d'expressions). Les expressions doivent être des chaînes. Elles ne peuvent pas concaténer des objets blob.
-
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 clé donnée , ou la chaîne vide si la clé n'est pas présente. -
format(fs_type, partition_type, location, fs_size, mount_point)
-
Reformate une partition donnée. Types de partitions compatibles :
- 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 l'appareil pour la partition. Un système de fichiers ext4 vide est créé à cet endroit. Si fs_size est nul, le système de fichiers occupe toute la partition. Si fs_size est un nombre positif, le système de fichiers prend les premiers fs_size octets de la partition. Si fs_size est un nombre négatif, le système de fichiers occupe tous les octets de la partition, à l'exception des derniers |fs_size| octets.
- fs_type="f2fs" et partition_type="EMMC". L'emplacement doit être le fichier de l'appareil pour la partition. fs_size doit être un nombre non négatif. Si fs_size est nul, le système de fichiers occupe toute la partition. Si fs_size est un nombre positif, le système de fichiers prend les premiers fs_size octets de la partition.
- mount_point doit être le futur point d'installation du système de fichiers.
getprop(key)
- Renvoie la valeur de la propriété système key (ou la chaîne vide, si elle n'est pas définie). Les valeurs de propriété système définies par la partition de récupération ne sont pas nécessairement identiques à celles du système principal. Cette fonction renvoie la valeur en récupération.
-
greater_than_int(a, b)
- Renvoie la valeur "true" si et seulement si a (interprété comme un entier) est supérieur à b (interprété comme un entier).
-
ifelse(cond, e1[, e2])
- Évalue cond. Si la condition est vraie, évalue et renvoie la valeur de e1. Sinon, évalue et renvoie e2 (le cas échéant). La construction "if ... else ... then ... endif" n'est qu'un sucre syntaxique pour cette fonction.
is_mounted(mount_point)
- Renvoie la valeur "true" si un système de fichiers est installé à l'emplacement mount_point.
-
is_substring(needle, haystack)
- Renvoie la valeur "true" si aiguille est une sous-chaîne de pile de foin.
-
less_than_int(a, b)
- Renvoie "true" si a (interprété comme un entier) est inférieur à b (interprété comme un entier).
-
mount(fs_type, partition_type, name, mount_point)
-
Installe un système de fichiers de fs_type à mount_point. partition_type doit être l'un des éléments suivants :
-
MTD "Name" est le nom d'une partition MTD (par exemple, "system", "userdata" ; consultez
/proc/mtd
sur l'appareil pour obtenir la liste complète). - EMMC
La récupération ne monte aucun système de fichiers par défaut (sauf la carte SD si l'utilisateur effectue une installation manuelle d'un paquet à partir de la carte SD). Votre script doit monter toutes les partitions qu'il doit modifier.
-
MTD "Name" est le nom d'une partition MTD (par exemple, "system", "userdata" ; consultez
-
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 de package sous forme de blob binaire.
read_file(filename)
- Lit nom de fichier et renvoie son contenu sous forme d'objet blob binaire.
-
run_program(path[, arg, ...])
- Exécute le binaire au chemin, en transmettant les arguments. Renvoie l'état de sortie du programme.
set_progress(frac)
-
Définit la position de la barre de progression dans le segment défini par l'appel
show_progress()
le plus récent. frac doit être compris dans la plage [0,0, 1,0]. L'indicateur de progression ne recule jamais. Les tentatives de le faire sont ignorées. -
sha1_check(blob[, sha1])
-
L'argument blob est un blob du type renvoyé par
read_file()
ou la forme à un seul argument depackage_extract_file()
. Sans argument sha1, cette fonction renvoie le hachage SHA1 du blob (sous la forme d'une chaîne hexadécimale à 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 s'il ne l'est à aucun d'eux. -
show_progress(frac, secs)
- avance l'indicateur de progression sur les frac suivants de sa longueur sur les secs secondes (doit être un entier). secs peut être égal à 0, auquel cas l'indicateur n'est pas avancé automatiquement, mais à l'aide de la fonction
set_progress()
définie ci-dessus. sleep(secs)
- Met l'unité principale en veille pendant secs secondes (doit être un entier).
-
stdout(expr[, expr, ...])
- Évalue chaque expression et vide sa valeur dans la sortie standard. Utile pour le débogage.
-
tune2fs(device[, arg, …])
- Ajuste les paramètres réglables args sur l'appareil.
ui_print([text, ...])
- Concatène tous les arguments text et imprime le résultat dans l'UI (où il sera visible si l'utilisateur a activé l'affichage du texte).
unmount(mount_point)
- Désinstalle le système de fichiers installé à mount_point.
-
wipe_block_device(block_dev, len)
- Efface les len octets de l'appareil de bloc block_dev donné.
wipe_cache()
- Force 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 désignant 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.