Il sistema crea il binario di aggiornamento da bootable/recovery/updater
e lo usa in un pacchetto OTA.
ota_update.zip
, incremental_ota_update.zip
) che contiene il file binario eseguibile META-INF/com/google/android/update-binary
. Updater contiene diverse funzioni integrate e un interprete per un linguaggio di scripting estensibile ( edify ) che supporta i comandi per le attività tipiche relative all'aggiornamento. Updater cerca nel file .zip del pacchetto uno script nel file META-INF/com/google/android/updater-script
.
Nota: l'utilizzo dello script edify e/o delle funzioni integrate non è un'attività comune, ma può essere utile se è necessario eseguire il debug del file di aggiornamento.
Modifica la sintassi
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 vere . Edify supporta i seguenti operatori (con i soliti significati):
(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 az, AZ, 0-9, _, :, /, . quella non è una parola riservata è considerata una stringa letterale. (Le parole riservate sono se else quindi endif. ) I letterali stringa possono anche apparire tra virgolette; ecco come creare valori con spazi bianchi e altri caratteri non nel set sopra. \n, \t, \", e \\ servono come escape all'interno di stringhe tra virgolette, così come \x ## .
Il && e || gli operatori sono in cortocircuito; il lato destro non viene valutato se il risultato logico è determinato dal lato sinistro. Sono equivalenti:
e1 && e2 if e1 then e2 endif
Il ; l'operatore è un punto di sequenza; significa valutare prima il lato sinistro e poi il lato destro. Il suo valore è il valore dell'espressione di destra. Un punto e virgola può anche apparire dopo un'espressione, quindi l'effetto simula 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. (A rigor di termini, queste sono macro piuttosto che funzioni nel senso Lisp, poiché non devono valutare tutti i loro argomenti.) Se non diversamente specificato, le funzioni restituiscono true in caso di successo e false in caso di errore. Se si desidera che gli errori interrompano l'esecuzione dello script, utilizzare le funzioni abort()
e/o assert()
. Il set di funzioni disponibili in Updater può anche essere esteso per fornire funzionalità specifiche del dispositivo .
-
abort([ msg ])
- Interrompe immediatamente l'esecuzione dello script, con l'opzione msg . Se l'utente ha attivato la visualizzazione del testo, il messaggio viene visualizzato nel registro di ripristino e sullo schermo.
-
assert( expr [, expr , ...])
- Valuta ogni espr a turno. Se any è false, 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 a src_file per produrre tgt_file . Se la destinazione desiderata è la stessa dell'origine, passare "-" per tgt_file . tgt_sha1 e tgt_size sono l'hash SHA1 finale previsto e la dimensione del file di destinazione. Gli argomenti rimanenti devono venire in coppia: un hash SHA1 (una stringa esadecimale di 40 caratteri) e un BLOB. Il BLOB è la patch da applicare quando il contenuto corrente del file di origine ha lo SHA1 specificato.
L'applicazione delle patch viene eseguita in modo sicuro in modo da garantire che il file di destinazione abbia l'hash SHA1 e le dimensioni desiderate o che non venga modificato: non verrà lasciato in uno stato intermedio irrecuperabile. Se il processo viene interrotto durante l'applicazione delle patch, il file di destinazione potrebbe trovarsi in uno stato intermedio; esiste una copia nella partizione della cache, quindi il riavvio dell'aggiornamento può aggiornare correttamente il file.
È supportata una sintassi speciale per trattare il contenuto delle partizioni MTD (Memory Technology Device) come file, consentendo l'applicazione di patch alle partizioni grezze come l'avvio. Per leggere una partizione MTD, devi sapere quanti dati vuoi leggere poiché la partizione non ha una nozione di fine file. È possibile utilizzare la stringa "MTD: partizione : dimensione_1: sha1_1 : dimensione_2 : sha1_2 " come nome file per leggere la partizione data. Devi specificare almeno una coppia (taglia, sha-1) ; puoi specificarne più di uno se ci sono più possibilità per ciò che ti aspetti di leggere.
-
apply_patch_check( filename , sha1 [, sha1 , ...])
- Restituisce true se il contenuto di filename o la copia temporanea nella partizione della cache (se presente) hanno un checksum SHA1 uguale a uno dei valori sha1 forniti. i valori sha1 sono specificati come 40 cifre esadecimali. Questa funzione differisce da
sha1_check(read_file( filename ), sha1 [, ...])
in quanto sa controllare la copia della partizione della cache, quindiapply_patch_check()
avrà esito positivo anche se il file è stato danneggiato da unapply_patch() update
interrotto. -
apply_patch_space( bytes )
- Restituisce true se sono disponibili almeno byte di spazio vuoto per l'applicazione di patch binarie.
-
concat( expr [, expr , ...])
- Valuta ogni espressione e le concatena. L'operatore + è zucchero sintattico per questa funzione nel caso speciale di due argomenti (ma il modulo della funzione può accettare un numero qualsiasi di espressioni). Le espressioni devono essere stringhe; non può concatenare i blob.
-
file_getprop( filename , key )
- Legge il nome file specificato, lo interpreta come un file di proprietà (ad es.
/system/build.prop
) e restituisce il valore della chiave data 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 partizione supportati:
- fs_type="yaffs2" e partition_type="MTD". Location deve essere il nome della partizione MTD; lì viene costruito un filesystem yaffs2 vuoto. Gli argomenti rimanenti sono inutilizzati.
- fs_type="ext4" e partition_type="EMMC". La posizione deve essere il file del dispositivo per la partizione. Lì viene costruito un filesystem ext4 vuoto. Se fs_size è zero, il filesystem occupa l'intera partizione. Se fs_size è un numero positivo, il filesystem prende i primi byte fs_size della partizione. Se fs_size è un numero negativo, il filesystem prende tutto tranne l'ultimo |fs_size| byte della partizione.
- 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 è zero, il filesystem occupa l'intera partizione. Se fs_size è un numero positivo, il filesystem prende i primi byte fs_size della partizione.
- mount_point dovrebbe essere il punto di montaggio futuro per il filesystem.
-
getprop( key )
- Restituisce il valore della chiave della proprietà di sistema (o la stringa vuota, se non è definita). I valori delle proprietà di sistema definiti dalla partizione di ripristino non sono necessariamente gli stessi del sistema principale. Questa funzione restituisce il valore in recovery.
-
greater_than_int( a , b )
- Restituisce vero se e solo se (iff) a (interpretato come intero) è maggiore di b (interpretato come intero).
-
ifelse( cond , e1 [, e2 ])
- Valuta cond , e se è true valuta e restituisce il valore di e1 , altrimenti valuta e restituisce e2 (se presente). Il costrutto "if ... else ... then ... endif" è solo zucchero sintattico per questa funzione.
-
is_mounted( mount_point )
- Restituisce true se è presente un filesystem montato su mount_point .
-
is_substring( needle , haystack )
- Restituisce true se l'ago è una sottostringa di pagliaio .
-
less_than_int( a , b )
- Restituisce true se a (interpretato come intero) è minore di b (interpretato come intero).
-
mount( fs_type , partition_type , name , mount_point )
- Monta un filesystem di fs_type in mount_point . tipo_partizione deve essere uno di:
- MTD . Nome è il nome di una partizione MTD (ad esempio, sistema, dati utente; vedere
/proc/mtd
sul dispositivo per un elenco completo). - EMMC.
Il ripristino non monta alcun filesystem per impostazione predefinita (tranne la scheda SD se l'utente sta eseguendo un'installazione manuale di un pacchetto dalla scheda SD); il tuo script deve montare tutte le partizioni che deve modificare.
- MTD . Nome è il nome di una partizione MTD (ad esempio, sistema, dati utente; vedere
-
package_extract_dir( package_dir , dest_dir )
- Estrae tutti i file dal pacchetto sotto package_dir e li scrive nell'albero corrispondente sotto dest_dir . Tutti i file esistenti vengono sovrascritti.
-
package_extract_file( package_file [, dest_file ])
- Estrae un singolo file_pacchetto dal pacchetto di aggiornamento e lo scrive in dest_file , sovrascrivendo i file esistenti se necessario. Senza l'argomento file_dest , restituisce il contenuto del file del pacchetto come BLOB binario.
-
read_file( filename )
- Legge il nome del file e ne restituisce il contenuto come BLOB binario.
-
run_program( path [, arg , ...])
- Esegue il binario in path , passando arg s. Restituisce lo stato di uscita del programma.
-
set_progress( frac )
- Imposta la posizione dell'indicatore di avanzamento all'interno del blocco definito dalla chiamata
show_progress()
più recente. frac deve essere compreso nell'intervallo [0,0, 1,0]. Il misuratore di avanzamento non si sposta mai indietro; i tentativi di farlo vengono ignorati. -
sha1_check( blob [, sha1 ])
- L'argomento blob è un blob del tipo restituito da
read_file()
o la forma a un argomento dipackage_extract_file()
. Senza argomenti sha1 , questa funzione restituisce l'hash SHA1 del BLOB (come una 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 essi. -
show_progress( frac , secs )
- Avanza il misuratore di avanzamento sulla frazione successiva della sua lunghezza nei secondi secondi (deve essere un numero intero). secs può essere 0, nel qual caso il misuratore non viene fatto avanzare automaticamente ma mediante l'uso della funzione
set_progress()
definita sopra. -
sleep( secs )
- Sostiene per secondi secondi (deve essere un numero intero).
-
stdout( expr [, expr , ...])
- Valuta ogni espressione e scarica il suo valore in stdout. Utile per il debug.
-
tune2fs( device [, arg , …])
- Regola gli argomenti dei parametri sintonizzabili sul dispositivo .
-
ui_print([ text , ...])
- Concatena tutti gli argomenti di testo e stampa il risultato nell'interfaccia utente (dove sarà visibile se l'utente ha attivato la visualizzazione del testo).
-
unmount( mount_point )
- Smonta il filesystem montato in mount_point .
-
wipe_block_device( block_dev , len )
- Cancella i byte len del dispositivo a blocchi specificato block_dev .
-
wipe_cache()
- Fa sì che la partizione della cache venga cancellata 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 denomina un file locale o un argomento con valore BLOB contenente i dati da scrivere. Per copiare un file dal pacchetto OTA in una partizione, utilizzare:
write_raw_image(package_extract_file("zip_filename"), "partition_name");
Nota: prima di Android 4.1, erano accettati solo nomi di file, quindi per fare ciò i dati dovevano essere prima decompressi in un file locale temporaneo.