El sistema construye el binario del actualizador desde bootable/recovery/updater
y lo usa en un paquete OTA.
ota_update.zip
, incremental_ota_update.zip
) que contiene el binario ejecutable META-INF/com/google/android/update-binary
. Updater contiene varias funciones integradas y un intérprete para un lenguaje de secuencias de comandos extensible ( edify ) que admite comandos para tareas típicas relacionadas con actualizaciones. El actualizador busca en el archivo .zip del paquete una secuencia de comandos en el archivo META-INF/com/google/android/updater-script
.
Nota: El uso de la secuencia de comandos edify y/o las funciones integradas no es una actividad común, pero puede ser útil si necesita depurar el archivo de actualización.
Edificar sintaxis
Un script de edify es una sola expresión en la que todos los valores son cadenas. Las cadenas vacías son falsas en un contexto booleano y todas las demás cadenas son verdaderas . Edify admite los siguientes operadores (con los significados habituales):
(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
Cualquier cadena de caracteres az, AZ, 0-9, _, :, /, . que no es una palabra reservada se considera un literal de cadena. (Las palabras reservadas son if else y luego endif). Los literales de cadena también pueden aparecer entre comillas dobles; así es como se crean valores con espacios en blanco y otros caracteres que no están en el conjunto anterior. \n, \t, \", y \\ sirven como escapes dentro de las cadenas entre comillas, al igual que \x ## .
El && y || los operadores están cortocircuitando; el lado derecho no se evalúa si el resultado lógico está determinado por el lado izquierdo. Los siguientes son equivalentes:
e1 && e2 if e1 then e2 endif
Los ; operador es un punto de secuencia; significa evaluar primero el lado izquierdo y luego el lado derecho. Su valor es el valor de la expresión del lado derecho. Un punto y coma también puede aparecer después de una expresión, por lo que el efecto simula declaraciones de estilo C:
prepare(); do_other_thing("argument"); finish_up();
Funciones integradas
La mayor parte de la funcionalidad de actualización está contenida en las funciones disponibles para su ejecución mediante scripts. (Estrictamente hablando, estas son macros en lugar de funciones en el sentido de Lisp, ya que no necesitan evaluar todos sus argumentos). A menos que se indique lo contrario, las funciones devuelven verdadero en caso de éxito y falso en caso de error. Si desea que los errores aborten la ejecución del script, use las funciones abort()
y/o assert()
. El conjunto de funciones disponibles en el actualizador también se puede ampliar para proporcionar una funcionalidad específica del dispositivo .
-
abort([ msg ])
- Cancela la ejecución del script inmediatamente, con el mensaje opcional . Si el usuario ha activado la visualización de texto , aparece un mensaje en el registro de recuperación y en la pantalla.
-
assert( expr [, expr , ...])
- Evalúa cada expr a su vez. Si alguno es falso, aborta inmediatamente la ejecución con el mensaje "afirmación fallida" y el texto fuente de la expresión fallida.
-
apply_patch( src_file , tgt_file , tgt_sha1 , tgt_size , patch1_sha1 , patch1_blob , [...])
- Aplica un parche binario al src_file para producir el tgt_file . Si el objetivo deseado es el mismo que el origen, pase "-" para tgt_file . tgt_sha1 y tgt_size son el hash SHA1 final esperado y el tamaño del archivo de destino. Los argumentos restantes deben venir en pares: un hash SHA1 (una cadena hexadecimal de 40 caracteres) y un blob. El blob es el parche que se aplicará cuando el contenido actual del archivo de origen tenga el SHA1 dado.
La aplicación de parches se realiza de una manera segura que garantiza que el archivo de destino tenga el hash y el tamaño SHA1 deseados, o no se toque; no se dejará en un estado intermedio irrecuperable. Si el proceso se interrumpe durante la aplicación de parches, el archivo de destino puede estar en un estado intermedio; existe una copia en la partición de caché, por lo que reiniciar la actualización puede actualizar correctamente el archivo.
Se admite una sintaxis especial para tratar el contenido de las particiones del dispositivo de tecnología de memoria (MTD) como archivos, lo que permite aplicar parches a las particiones sin procesar, como el arranque. Para leer una partición MTD, debe saber cuántos datos desea leer, ya que la partición no tiene una noción de fin de archivo. Puede usar la cadena "MTD: partición : tamaño_1 : sha1_1 : tamaño_2 : sha1_2 " como nombre de archivo para leer la partición dada. Debe especificar al menos un par (tamaño, sha-1) ; puede especificar más de uno si hay varias posibilidades de lo que espera leer.
-
apply_patch_check( filename , sha1 [, sha1 , ...])
- Devuelve verdadero si el contenido del nombre de archivo o la copia temporal en la partición de caché (si está presente) tiene una suma de verificación SHA1 igual a uno de los valores sha1 proporcionados. Los valores sha1 se especifican como 40 dígitos hexadecimales. Esta función difiere de
sha1_check(read_file( filename ), sha1 [, ...])
en que sabe verificar la copia de partición de caché, por lo queapply_patch_check()
tendrá éxito incluso si el archivo se corrompió por una actualización interrumpida deapply_patch() update
. -
apply_patch_space( bytes )
- Devuelve verdadero si hay al menos bytes de espacio disponible para aplicar parches binarios.
-
concat( expr [, expr , ...])
- Evalúa cada expresión y las concatena. El operador + es azúcar sintáctico para esta función en el caso especial de dos argumentos (pero la forma de función puede tomar cualquier número de expresiones). Las expresiones deben ser cadenas; no puede concatenar blobs.
-
file_getprop( filename , key )
- Lee el nombre de archivo dado, lo interpreta como un archivo de propiedades (por ejemplo,
/system/build.prop
) y devuelve el valor de la clave dada, o la cadena vacía si la clave no está presente. -
format( fs_type , partition_type , location , fs_size , mount_point )
- Reformatea una partición dada. Tipos de partición compatibles:
- tipo_fs="yaffs2" y tipo_partición="MTD". La ubicación debe ser el nombre de la partición MTD; allí se construye un sistema de archivos yaffs2 vacío. Los argumentos restantes no se utilizan.
- tipo_fs="ext4" y tipo_partición="EMMC". La ubicación debe ser el archivo del dispositivo para la partición. Allí se construye un sistema de archivos ext4 vacío. Si fs_size es cero, el sistema de archivos ocupa toda la partición. Si fs_size es un número positivo, el sistema de archivos toma los primeros bytes de fs_size de la partición. Si fs_size es un número negativo, el sistema de archivos toma todo excepto el último |fs_size| bytes de la partición.
- tipo_fs="f2fs" y tipo_partición="EMMC". La ubicación debe ser el archivo del dispositivo para la partición. fs_size debe ser un número no negativo. Si fs_size es cero, el sistema de archivos ocupa toda la partición. Si fs_size es un número positivo, el sistema de archivos toma los primeros bytes de fs_size de la partición.
- mount_point debe ser el punto de montaje futuro para el sistema de archivos.
-
getprop( key )
- Devuelve el valor de la clave de propiedad del sistema (o la cadena vacía, si no está definida). Los valores de propiedad del sistema definidos por la partición de recuperación no son necesariamente los mismos que los del sistema principal. Esta función devuelve el valor en recuperación.
-
greater_than_int( a , b )
- Devuelve verdadero si y solo si (iff) a (interpretado como un número entero) es mayor que b (interpretado como un número entero).
-
ifelse( cond , e1 [, e2 ])
- Evalúa cond , y si es verdadero evalúa y devuelve el valor de e1 , de lo contrario evalúa y devuelve e2 (si está presente). La construcción "if... else... then... endif" es simplemente azúcar sintáctica para esta función.
-
is_mounted( mount_point )
- Devuelve verdadero si hay un sistema de archivos montado en punto_de_montaje .
-
is_substring( needle , haystack )
- Devuelve verdadero si la aguja es una subcadena de pajar .
-
less_than_int( a , b )
- Devuelve verdadero si a (interpretado como un número entero) es menor que b (interpretado como un número entero).
-
mount( fs_type , partition_type , name , mount_point )
- Monta un sistema de archivos de fs_type en mount_point . tipo_partición debe ser uno de los siguientes:
- MTD . Nombre es el nombre de una partición MTD (p. ej., sistema, datos de usuario; consulte
/proc/mtd
en el dispositivo para obtener una lista completa). - EMMC.
La recuperación no monta ningún sistema de archivos de forma predeterminada (excepto la tarjeta SD si el usuario está realizando una instalación manual de un paquete desde la tarjeta SD); su secuencia de comandos debe montar cualquier partición que necesite modificar.
- MTD . Nombre es el nombre de una partición MTD (p. ej., sistema, datos de usuario; consulte
-
package_extract_dir( package_dir , dest_dir )
- Extrae todos los archivos del paquete debajo de package_dir y los escribe en el árbol correspondiente debajo de dest_dir . Se sobrescriben todos los archivos existentes.
-
package_extract_file( package_file [, dest_file ])
- Extrae un archivo_paquete único del paquete de actualización y lo escribe en dest_file , sobrescribiendo los archivos existentes si es necesario. Sin el argumento dest_file , devuelve el contenido del archivo del paquete como un blob binario.
-
read_file( filename )
- Lee el nombre del archivo y devuelve su contenido como un blob binario.
-
run_program( path [, arg , ...])
- Ejecuta el binario en path , pasando arg s. Devuelve el estado de salida del programa.
-
set_progress( frac )
- Establece la posición del medidor de progreso dentro del fragmento definido por la llamada
show_progress()
más reciente. frac debe estar en el rango [0.0, 1.0]. El medidor de progreso nunca retrocede; se ignoran los intentos de hacer que lo haga. -
sha1_check( blob [, sha1 ])
- El argumento blob es un blob del tipo devuelto por
read_file()
o la forma de un argumento depackage_extract_file()
. Sin argumentos sha1 , esta función devuelve el hash SHA1 del blob (como una cadena hexadecimal de 40 dígitos). Con uno o más argumentos sha1 , esta función devuelve el hash SHA1 si es igual a uno de los argumentos, o la cadena vacía si no es igual a ninguno de ellos. -
show_progress( frac , secs )
- Avanza el medidor de progreso sobre la siguiente fracción de su longitud sobre los segundos segundos (debe ser un número entero). segundos puede ser 0, en cuyo caso el medidor no avanza automáticamente sino mediante el uso de la función
set_progress()
definida anteriormente. -
sleep( secs )
- Duerme durante segundos segundos (debe ser un número entero).
-
stdout( expr [, expr , ...])
- Evalúa cada expresión y vuelca su valor en la salida estándar. Útil para la depuración.
-
tune2fs( device [, arg , …])
- Ajusta los parámetros ajustables args en el dispositivo .
-
ui_print([ text , ...])
- Concatena todos los argumentos de texto e imprime el resultado en la interfaz de usuario (donde será visible si el usuario ha activado la visualización de texto).
-
unmount( mount_point )
- Desmonta el sistema de archivos montado en mount_point .
-
wipe_block_device( block_dev , len )
- Limpia los len bytes del dispositivo de bloque dado block_dev .
-
wipe_cache()
- Hace que la partición de caché se borre al final de una instalación exitosa.
-
write_raw_image( filename_or_blob , partition )
- Escribe la imagen en filename_or_blob en la partición MTD. filename_or_blob puede ser una cadena que nombra un archivo local o un argumento con valor de blob que contiene los datos para escribir. Para copiar un archivo del paquete OTA a una partición, use:
write_raw_image(package_extract_file("zip_filename"), "partition_name");
Nota: antes de Android 4.1, solo se aceptaban nombres de archivos, por lo que para lograr esto, primero se tenían que descomprimir los datos en un archivo local temporal.