All'interno dei pacchetti OTA

Il sistema compila il file binario dell'aggiornamento da bootable/recovery/updater e lo utilizza in un pacchetto OTA.

Il pacchetto stesso è un file ZIP (ota_update.zip, incremental_ota_update.zip) che contiene il file binario eseguibile META-INF/com/google/android/update-binary .

Updater contiene diverse funzioni predefinite e un interprete per un linguaggio di scripting estendibile (edify) che supporta i comandi per le attività di aggiornamento più comuni. Updater cerca uno script nel file META-INF/com/google/android/updater-script del file .zip del pacchetto.

Nota: l'utilizzo dello script edify e/o delle funzioni predefinite non è un'attività comune, ma può essere utile se devi eseguire il debug del file di aggiornamento.

Sintassi di Edify

Uno script edify è una singola espressione in cui tutti i valori sono stringhe. Le stringhe vuote sono false in un contesto booleano e tutte le altre stringhe sono true. Edify supporta i seguenti operatori (con i significati consueti):

(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

Qualsiasi stringa di caratteri a-z, A-Z, 0-9, _, :, /, . che non è una parola riservata è considerata una stringa letterale. (Le parole riservate sono if else then endif.) Le stringhe letterali possono essere visualizzate anche tra virgolette doppie. In questo modo puoi creare valori con spazi vuoti e altri caratteri non presenti nell'insieme precedente. \n, \t, \" e \\ fungono da caratteri di escape all'interno di stringhe tra virgolette, così come \x##.

Gli operatori && e || presentano cortocircuito; il lato destro non viene valutato se il risultato logico è determinato dal lato sinistro. I seguenti valori sono equivalenti:

e1 && e2
if e1 then e2 endif

L'operatore ; è un punto di sequenza; significa valutare prima il lato sinistro e poi il lato destro. Il suo valore è il valore dell'espressione a destra. Un punto e virgola può apparire anche dopo un'espressione, in modo che l'effetto simuli le istruzioni in stile C:

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

Funzioni integrate

La maggior parte delle funzionalità di aggiornamento è contenuta nelle funzioni disponibili per l'esecuzione da parte degli script. (Dal punto di vista formale, si tratta di macro anziché di funzioni nel senso di Lisp, poiché non devono valutare tutti i relativi argomenti.) Se non diversamente indicato, le funzioni restituiscono true in caso di esito positivo e false in caso di errore. Se vuoi che gli errori interrompano l'esecuzione dello script, utilizza le funzioni abort() e/o assert(). L'insieme di funzioni disponibili in Updater può essere esteso anche per fornire funzionalità specifiche del dispositivo.

abort([msg])
Interrompe immediatamente l'esecuzione dello script con il messaggio facoltativo msg. Se l'utente ha attivato la visualizzazione del testo, msg viene visualizzato nel log di recupero e sullo schermo.
assert(expr[, expr, ...])
Valuta ogni expr in sequenza. Se uno è falso, interrompe immediatamente l'esecuzione con il messaggio "assert failed" e il testo di origine dell'espressione non riuscita.
apply_patch(src_file, tgt_file, tgt_sha1, tgt_size, patch1_sha1, patch1_blob, [...])
Applica una patch binaria al file src_file per produrre il file tgt_file. Se la destinazione desiderata è la stessa dell'origine, passa "-" per tgt_file . tgt_sha1 e tgt_size sono l'hash SHA1 finale e le dimensioni previste del file di destinazione. Gli argomenti rimanenti devono essere forniti a coppie: un hash SHA1 (una stringa esadecimale di 40 caratteri) e un blob. Il blob è la patch da applicare quando i contenuti attuali del file di origine hanno l'SHA1 specificato.

L'applicazione dei patch viene eseguita in modo sicuro in modo da garantire che il file di destinazione abbia le dimensioni e l'hash SHA1 desiderati o che non sia modificato, ovvero non verrà lasciato in uno stato intermedio non recuperabile. Se il processo viene interrotto durante l'applicazione dei patch, il file di destinazione potrebbe essere in uno stato intermedio; esiste una copia nella partizione della cache, quindi riavviare l'aggiornamento può aggiornare il file correttamente.

È supportata una sintassi speciale per trattare i contenuti delle partizioni MTD (Memory Technology Device) come file, consentendo la correzione delle partizioni non elaborate come il boot. Per leggere una partizione MTD, devi sapere quanti dati vuoi leggere, poiché la partizione non ha un concetto di fine file. Puoi utilizzare la stringa "MTD:partition:size_1:sha1_1:size_2: sha1_2" come nome file per leggere la partizione specificata. Devi specificare almeno una coppia (size, sha-1); puoi specificarne più di una se esistono più possibili modi per interpretare ciò che ti aspetti di leggere.

apply_patch_check(filename, sha1[, sha1, ...])
Restituisce true se i contenuti di nomefile o della copia temporanea nella partizione della cache (se presente) hanno un checksum SHA1 uguale a uno dei valori sha1 specificati. I valori sha1 sono specificati come 40 cifre esadecimali. Questa funzione è diversa da sha1_check(read_file(filename), sha1 [, ...]) in quanto sa controllare la copia della partizione della cache, pertanto apply_patch_check() avrà esito positivo anche se il file è stato danneggiato da un apply_patch() update interrotto.
apply_patch_space(bytes)
Restituisce true se sono disponibili almeno byte di spazio inutilizzato per l'applicazione di patch binarie.
concat(expr[, expr, ...])
Valuta ogni espressione e le concatena. L'operatore + è una sintassi per questa funzione nel caso speciale di due argomenti (ma la forma della funzione può accettare un numero qualsiasi di espressioni). Le espressioni devono essere stringhe; non è possibile concatenare blob.
file_getprop(filename, key)
Legge il nome file specificato, lo interpreta come file di proprietà (ad es. /system/build.prop) e restituisce il valore della chiave specificata o la stringa vuota se la chiave non è presente.
format(fs_type, partition_type, location, fs_size, mount_point)
Riformatta una determinata partizione. Tipi di partizioni supportati:
  • fs_type="yaffs2" e partition_type="MTD". La posizione deve essere il nome della partizione MTD; qui viene creato un file system yaffs2 vuoto. Gli argomenti rimanenti non vengono utilizzati.
  • fs_type="ext4" e partition_type="EMMC". La posizione deve essere il file del dispositivo per la partizione. Viene creato un file system ext4 vuoto. Se fs_size è pari a zero, il filesystem occupa l'intera partizione. Se fs_size è un numero positivo, il filesystem prende i primi fs_size byte della partizione. Se fs_size è un numero negativo, il file system prende tutti i byte della partizione tranne gli ultimi |fs_size|.
  • fs_type="f2fs" e partition_type="EMMC". La posizione deve essere il file del dispositivo per la partizione. fs_size deve essere un numero non negativo. Se fs_size è pari a zero, il filesystem occupa l'intera partizione. Se fs_size è un numero positivo, il filesystem prende i primi fs_size byte della partizione.
  • mount_point deve essere il punto di montaggio futuro per il file system.
getprop(key)
Restituisce il valore della proprietà di sistema key (o la stringa vuota, se non è definita). I valori delle proprietà di sistema definiti dalla partizione di ripristino non sono necessariamente uguali a quelli del sistema principale. Questa funzione restituisce il valore in fase di recupero.
greater_than_int(a, b)
Restituisce true se e solo se (se e solo se) a (interpretato come numero intero) è maggiore di b (interpretato come numero intero).
ifelse(cond, e1[, e2])
Valuta cond e, se è vera, valuta e restituisce il valore di e1, altrimenti valuta e restituisce e2 (se presente). La struttura "if ... else ... then ... endif" è solo una sintassi più semplice per questa funzione.
is_mounted(mount_point)
Restituisce true se esiste un file system montato in mount_point.
is_substring(needle, haystack)
Restituisce true se e solo se needle è una sottostringa di haystack.
less_than_int(a, b)
Restituisce true se e solo se a (interpretato come numero intero) è minore di b (interpretato come numero intero).
mount(fs_type, partition_type, name, mount_point)
Monta un file system di fs_type in mount_point. partition_type deve essere uno dei seguenti:
  • MTD. Nome è il nome di una partizione MTD (ad es. system, userdata; consulta /proc/mtd sul dispositivo per un elenco completo).
  • EMMC.

Per impostazione predefinita, il recupero non monta alcun file system (tranne la scheda SD se l'utente sta eseguendo un'installazione manuale di un pacchetto dalla scheda SD); lo script deve montare tutte le partizioni che deve modificare.

package_extract_dir(package_dir, dest_dir)
Estrae tutti i file dal pacchetto in package_dir e li scrive nella struttura corrispondente in dest_dir. Eventuali file esistenti vengono sovrascritti.
package_extract_file(package_file[, dest_file])
Estrae un singolo package_file dal pacchetto di aggiornamento e lo scrive in dest_file, sovrascrivendo i file esistenti, se necessario. Senza l'argomento dest_file, restituisce i contenuti del file del pacchetto come blob binario.
read_file(filename)
Leggi nomefile e restituisce i relativi contenuti come blob binario.
run_program(path[, arg, ...])
Esegue il file binario in path, passando gli arg. Restituisce lo stato di uscita del programma.
set_progress(frac)
Imposta la posizione dell'indicatore di avanzamento all'interno del chunk definito dalla chiamata show_progress() più recente. frac deve essere compreso nell'intervallo [0,0, 1,0]. L'indicatore di avanzamento non torna mai indietro; i tentativi di farlo vengono ignorati.
sha1_check(blob[, sha1])
L'argomento blob è un blob del tipo restituito da read_file() o dalla forma con un argomento di package_extract_file() . Senza argomenti sha1, questa funzione restituisce l'hash SHA1 del blob (come stringa esadecimale di 40 cifre). Con uno o più argomenti sha1, questa funzione restituisce l'hash SHA1 se è uguale a uno degli argomenti o la stringa vuota se non è uguale a nessuno di questi.
show_progress(frac, secs)
Avvia il misuratore di avanzamento per la prossima frazione frac della sua lunghezza in secs secondi (deve essere un numero intero). secs può essere 0, nel qual caso il misuratore non viene avanzato automaticamente, ma tramite la funzione set_progress() definita sopra.
sleep(secs)
Sospende l'esecuzione per secs secondi (deve essere un numero intero).
stdout(expr[, expr, ...])
Valuta ogni espressione e ne esegue il dump del valore in stdout. Utile per il debug.
tune2fs(device[, arg, …])
Modifica i parametri regolabili args sul dispositivo.
ui_print([text, ...])
Concatena tutti gli argomenti text e stampa il risultato nell'interfaccia utente (dove sarà visualizzato se l'utente ha attivato la visualizzazione del testo).
unmount(mount_point)
Smonta il file system montato in mount_point.
wipe_block_device(block_dev, len)
Cancella i len byte del dispositivo di blocco specificato block_dev.
wipe_cache()
Consente di cancellare la partizione della cache al termine di un'installazione riuscita.
write_raw_image(filename_or_blob, partition)
Scrive l'immagine in filename_or_blob nella partizione MTD. filename_or_blob può essere una stringa che indica il nome di un file locale o un argomento con valore blob contenente i dati da scrivere. Per copiare un file dal pacchetto OTA a una partizione, utilizza: write_raw_image(package_extract_file("zip_filename"), "partition_name");

Nota:prima di Android 4.1, erano accettati solo i nomi dei file, quindi per eseguire questa operazione i dati dovevano prima essere decompressi in un file locale temporaneo.