All'interno dei pacchetti OTA

Il sistema crea il file binario di 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 l'eseguibile binario 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 agli aggiornamenti. 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.

Modificare 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 if else then endif. ) Le stringhe letterali possono anche apparire tra virgolette doppie; questo è come creare valori con spazi bianchi e altri caratteri non presenti nel set sopra. \n, \t, \", e \\ fungono da escape all'interno di stringhe tra virgolette, così come \x ## .

&& 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 del lato destro. 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 tramite script. (A rigor di termini queste sono macro piuttosto che funzioni nel senso Lisp, poiché non necessitano di valutare tutti i loro argomenti.) Se non diversamente specificato, le funzioni restituiscono vero in caso di successo e falso in caso di errore. Se si desidera che gli errori interrompano l'esecuzione dello script, utilizzare le funzioni abort() e/o assert() . L'insieme 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 ciascuna espressione a turno. Se qualsiasi è falso, interrompe immediatamente l'esecuzione con il messaggio "asserzione non riuscita" 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, passa "-" 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 essere forniti 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 sorgente ha il dato SHA1.

L'applicazione delle patch viene eseguita in modo sicuro, garantendo che il file di destinazione abbia l'hash e le dimensioni SHA1 desiderati oppure che non venga modificato: non verrà lasciato in uno stato intermedio irrecuperabile. Se il processo viene interrotto durante l'applicazione della patch, il file di destinazione potrebbe trovarsi in uno stato intermedio; esiste una copia nella partizione della cache, quindi riavviare l'aggiornamento può aggiornare correttamente il file.

È supportata una sintassi speciale per trattare il contenuto delle partizioni Memory Technology Device (MTD) come file, consentendo l'applicazione di patch a partizioni non elaborate 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 specificata. Devi specificare almeno un paio (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 vero se il contenuto di filename o la copia temporanea nella partizione della cache (se presente) ha un checksum SHA1 uguale a uno dei valori sha1 specificati. 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, quindi apply_patch_check() avrà successo anche se il file è stato danneggiato da un apply_patch() update interrotto.
apply_patch_space( bytes )
Restituisce vero se sono disponibili almeno byte di spazio di lavoro per applicare le patch binarie.
concat( expr [, expr , ...])
Valuta ogni espressione e le concatena. L'operatore + è lo zucchero sintattico per questa funzione nel caso speciale di due argomenti (ma la forma della funzione può assumere un numero qualsiasi di espressioni). Le espressioni devono essere stringhe; non può concatenare BLOB.
file_getprop( filename , key )
Legge il nome file specificato, lo interpreta come un file delle proprietà (ad esempio /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 supportate:
  • fs_type="yaffs2" e partizione_type="MTD". La posizione deve essere il nome della partizione MTD; lì viene costruito un filesystem yaffs2 vuoto. Gli argomenti rimanenti non vengono utilizzati.
  • fs_type="ext4" e partizione_type="EMMC". La posizione deve essere il file di 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 li prende tutti tranne l'ultimo |fs_size| byte della partizione.
  • fs_type="f2fs" e partizione_type="EMMC". La posizione deve essere il file di 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 futuro punto di montaggio 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 è vero valuta e restituisce il valore di e1 , altrimenti valuta e restituisce e2 (se presente). Il costrutto "if... else... then... endif" è solo lo zucchero sintattico per questa funzione.
is_mounted( mount_point )
Restituisce vero se e solo se c'è un filesystem montato su mount_point .
is_substring( needle , haystack )
Restituisce vero se e solo se ago è una sottostringa di pagliaio .
less_than_int( a , b )
Restituisce vero se e solo 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 su mount_point . tipo_partizione deve essere uno di:
  • MTD . Name è il nome di una partizione MTD (ad esempio, system, userdata; vedere /proc/mtd sul dispositivo per un elenco completo).
  • EMMC.

Il ripristino non monta alcun file system 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.

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 verranno 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 il contenuto del file del pacchetto come BLOB binario.
read_file( filename )
Legge il nome 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]. L'indicatore di avanzamento non si sposta mai all'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 a 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 essi.
show_progress( frac , secs )
Fa avanzare l'indicatore di avanzamento della frazione successiva della sua lunghezza nell'arco dei secondi (deve essere un numero intero). secs può essere 0, nel qual caso il contatore non viene avanzato automaticamente ma mediante l'uso della funzione set_progress() definita sopra.
sleep( secs )
Dorme per secondi secondi (deve essere un numero intero).
stdout( expr [, expr , ...])
Valuta ogni espressione e ne scarica il valore su 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 len byte del dispositivo a blocchi specificato block_dev .
wipe_cache()
Causa la cancellazione della 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 denomina un file locale o un argomento con valori BLOB contenente i dati da scrivere. Per copiare un file dal pacchetto OTA a una partizione, utilizzare: write_raw_image(package_extract_file("zip_filename"), "partition_name");

Nota: prima di Android 4.1, venivano accettati solo i nomi di file, quindi per ottenere ciò i dati dovevano prima essere decompressi in un file locale temporaneo.