Domande frequenti

Google ha utilizzato OTA A/B su qualche dispositivo?

SÌ. Il nome commerciale degli aggiornamenti A/B è aggiornamenti continui . I telefoni Pixel e Pixel XL di ottobre 2016 sono stati forniti con A/B e tutti i Chromebook utilizzano la stessa implementazione update_engine di A/B. L'implementazione del codice della piattaforma necessaria è pubblica in Android 7.1 e versioni successive.

Perché le OTA A/B sono migliori?

Le OTA A/B forniscono un'esperienza utente migliore durante l'acquisizione degli aggiornamenti. Le misurazioni degli aggiornamenti mensili di sicurezza mostrano che questa funzionalità si è già rivelata un successo: a maggio 2017, il 95% dei possessori di Pixel esegue l'ultimo aggiornamento di sicurezza dopo un mese rispetto all'87% degli utenti Nexus, e gli utenti Pixel si aggiornano prima degli utenti Nexus. Gli errori di aggiornamento dei blocchi durante un'OTA non comportano più il mancato avvio del dispositivo; finché la nuova immagine di sistema non viene avviata correttamente, Android mantiene la possibilità di ricorrere all'immagine di sistema funzionante precedente.

In che modo A/B ha influito sulle dimensioni delle partizioni Pixel 2016?

La seguente tabella contiene dettagli sulla configurazione A/B di spedizione rispetto alla configurazione non A/B testata internamente:

Dimensioni delle partizioni in pixel A/B Non A/B
Boot loader 50*2 50
Stivale 32*2 32
Recupero 0 32
Cache 0 100
Radio 70*2 70
Venditore 300*2 300
Sistema 2048*2 4096
Totale 5000 4680

Gli aggiornamenti A/B richiedono un aumento di soli 320 MiB in flash, con un risparmio di 32 MiB rimuovendo la partizione di ripristino e altri 100 MiB preservati rimuovendo la partizione cache. Ciò bilancia il costo delle partizioni B per il bootloader, la partizione di avvio e la partizione radio. La partizione del fornitore è raddoppiata in termini di dimensioni (la stragrande maggioranza delle dimensioni aumenta). L'immagine del sistema A/B di Pixel è grande la metà dell'immagine del sistema non A/B originale.

Per le varianti Pixel A/B e non A/B testate internamente (solo A/B spedite), lo spazio utilizzato differiva di soli 320 MiB. Su un dispositivo da 32 GiB, questo è poco meno dell'1%. Per un dispositivo da 16 GiB questo sarebbe inferiore al 2% e per un dispositivo da 8 GiB quasi il 4% (assumendo che tutti e tre i dispositivi avessero la stessa immagine di sistema).

Perché non hai usato SquashFS?

Abbiamo sperimentato SquashFS ma non siamo riusciti a ottenere le prestazioni desiderate per un dispositivo di fascia alta. Non utilizziamo né consigliamo SquashFS per dispositivi portatili.

Più specificamente, SquashFS ha consentito un risparmio di circa il 50% sulle dimensioni della partizione di sistema, ma la stragrande maggioranza dei file compressi bene erano file .odex precompilati. Questi file avevano rapporti di compressione molto elevati (avvicinandosi all'80%), ma il rapporto di compressione per il resto della partizione di sistema era molto più basso. Inoltre, SquashFS in Android 7.0 ha sollevato i seguenti problemi di prestazioni:

  • Pixel ha una flash molto veloce rispetto ai dispositivi precedenti ma non un numero enorme di cicli CPU di riserva, quindi leggere meno byte dalla flash ma richiedere più CPU per l'I/O era un potenziale collo di bottiglia.
  • Le modifiche I/O che funzionano bene su un benchmark artificiale eseguito su un sistema senza carico a volte non funzionano bene nei casi d'uso del mondo reale con carico reale (come la crittografia su Nexus 6).
  • Il benchmarking ha mostrato regressioni dell’85% in alcuni luoghi.

Man mano che SquashFS matura e aggiunge funzionalità per ridurre l'impatto sulla CPU (come una lista bianca di file a cui si accede comunemente che non devono essere compressi), continueremo a valutarlo e a offrire consigli ai produttori di dispositivi.

Come hai dimezzato la dimensione della partizione di sistema senza SquashFS?

Le applicazioni sono archiviate in file .apk, che in realtà sono archivi ZIP. Ogni file .apk ha al suo interno uno o più file .dex contenenti bytecode Dalvik portatile. Un file .odex (.dex ottimizzato) vive separatamente dal file .apk e può contenere codice macchina specifico per il dispositivo. Se è disponibile un file .odex, Android può eseguire applicazioni a velocità di compilazione anticipata senza dover attendere la compilazione del codice ogni volta che viene avviata l'applicazione. Un file .odex non è strettamente necessario: Android può effettivamente eseguire il codice .dex direttamente tramite interpretazione o compilazione Just-In-Time (JIT), ma un file .odex fornisce la migliore combinazione di velocità di avvio e velocità di runtime se lo spazio è disponibile.

Esempio: per il file installato-files.txt di un Nexus 6P con Android 7.1 con una dimensione totale dell'immagine del sistema di 2628 MiB (2755792836 byte), la ripartizione dei maggiori contributori alla dimensione complessiva dell'immagine del sistema per tipo di file è la seguente:

.odex 1391770312 byte 50,5%
.apk 846878259 byte 30,7%
.so (codice C/C++ nativo) 202162479 byte 7,3%
file .oat/immagini .art 163892188 byte 5,9%
Caratteri 38952361 byte 1,4%
dati locali dell'icu 27468687 byte 0,9%

Queste cifre sono simili anche per altri dispositivi, quindi sui dispositivi Nexus/Pixel i file .odex occupano circa la metà della partizione di sistema. Ciò significava che potevamo continuare a utilizzare ext4 ma scrivere i file .odex nella partizione B in fabbrica e quindi copiarli in /data al primo avvio. Lo spazio di archiviazione effettivo utilizzato con ext4 A/B è identico a SquashFS A/B, perché se avessimo utilizzato SquashFS avremmo spedito i file .odex preoptati su system_a anziché su system_b.

Copiare i file .odex in /data non significa che lo spazio salvato su /system viene perso su /data?

Non esattamente. Su Pixel, la maggior parte dello spazio occupato dai file .odex è destinato alle app, che in genere si trovano in /data . Queste app accettano gli aggiornamenti di Google Play, quindi i file .apk e .odex sull'immagine di sistema rimangono inutilizzati per gran parte della vita del dispositivo. Tali file possono essere esclusi completamente e sostituiti da piccoli file .odex basati sul profilo quando l'utente utilizza effettivamente ciascuna app (non richiedendo quindi spazio per le app che l'utente non utilizza). Per i dettagli, fare riferimento al discorso di Google I/O 2016 The Evolution of Art .

Il confronto è difficile per alcuni motivi fondamentali:

  • Le app aggiornate da Google Play hanno sempre avuto i propri file .odex su /data non appena ricevono il primo aggiornamento.
  • Le app non eseguite dall'utente non necessitano affatto di un file .odex.
  • La compilazione basata sul profilo genera file .odex più piccoli rispetto alla compilazione anticipata (perché la prima ottimizza solo il codice critico per le prestazioni).

Per dettagli sulle opzioni di ottimizzazione disponibili per gli OEM, vedere Configurazione ART .

Non ci sono due copie dei file .odex su /data?

È un po' più complicato... Dopo che la nuova immagine di sistema è stata scritta, la nuova versione di dex2oat viene eseguita sui nuovi file .dex per generare i nuovi file .odex. Ciò si verifica mentre il vecchio sistema è ancora in esecuzione, quindi il vecchio e il nuovo file .odex sono entrambi su /data contemporaneamente.

Il codice in OtaDexoptService ( frameworks/base/+/main/services/core/java/com/android/server/pm/OtaDexoptService.java ) chiama getAvailableSpace prima di ottimizzare ciascun pacchetto per evitare un riempimento eccessivo /data . Tieni presente che disponibile qui è ancora conservativo: è la quantità di spazio rimasto prima di raggiungere la consueta soglia di spazio basso del sistema (misurata sia come percentuale che come conteggio di byte). Pertanto, se /data è pieno, non ci saranno due copie di ogni file .odex. Lo stesso codice ha anche un BULK_DELETE_THREShold: se il dispositivo arriva così vicino a riempire lo spazio disponibile (come appena descritto), i file .odex appartenenti alle app non utilizzate vengono rimossi. Questo è un altro caso senza due copie di ogni file .odex.

Nel peggiore dei casi, quando /data è completamente pieno, l'aggiornamento attende finché il dispositivo non si riavvia nel nuovo sistema e non necessita più dei file .odex del vecchio sistema. PackageManager gestisce questo: ( frameworks/base/+/main/services/core/java/com/android/server/pm/PackageManagerService.java#7215 ). Dopo che il nuovo sistema si è avviato correttamente, installd ( frameworks/native/+/main/cmds/installd/dexopt.cpp#2422 ) può rimuovere i file .odex utilizzati dal vecchio sistema, riportando il dispositivo allo stato stazionario dove ce n'è una sola copia.

Pertanto, anche se è possibile che /data contenga due copie di tutti i file .odex, (a) questo è temporaneo e (b) si verifica solo se si dispone comunque di molto spazio libero su /data . Tranne durante un aggiornamento, c'è solo una copia. E come parte delle caratteristiche generali di robustezza di ART, non riempirà mai /data con file .odex (perché sarebbe un problema anche su un sistema non A/B).

Tutto questo scrivere/copiare non aumenta l'usura della flash?

Solo una piccola porzione di flash viene riscritta: un aggiornamento completo del sistema Pixel scrive circa 2,3GiB. (Anche le app vengono ricompilate, ma questo vale anche per quelle non A/B.) Tradizionalmente, le OTA complete basate su blocco scrivevano una quantità simile di dati, quindi i tassi di usura della flash dovrebbero essere simili.

Il flashing di due partizioni di sistema aumenta il tempo di flashing di fabbrica?

No. Pixel non ha aumentato le dimensioni dell'immagine del sistema (ha semplicemente diviso lo spazio su due partizioni).

Mantenere i file .odex su B non rallenta il riavvio dopo il ripristino dei dati di fabbrica?

SÌ. Se hai effettivamente utilizzato un dispositivo, preso un OTA ed eseguito un ripristino dei dati di fabbrica, il primo riavvio sarà più lento di quanto sarebbe altrimenti (1 minuto e 40 secondi contro 40 secondi su un Pixel XL) perché i file .odex saranno andati persi B dopo il primo OTA e quindi non può essere copiato in /data . Questo è il compromesso.

Il ripristino dei dati di fabbrica dovrebbe essere un'operazione rara rispetto all'avvio normale, quindi il tempo impiegato è meno importante. (Ciò non influisce sugli utenti o sui revisori che ricevono il dispositivo dalla fabbrica, perché in quel caso è disponibile la partizione B.) L'uso del compilatore JIT significa che non abbiamo bisogno di ricompilare tutto , quindi non è così male come te potrebbe pensare. È anche possibile contrassegnare le app come che richiedono una compilazione anticipata utilizzando coreApp="true" nel manifest: ( frameworks/base/+/main/packages/SystemUI/AndroidManifest.xml#23 ). Questo è attualmente utilizzato da system_server perché non è consentito eseguire il JIT per motivi di sicurezza.

Mantenere i file .odex su /data anziché su /system non rallenta il riavvio dopo un OTA?

No. Come spiegato sopra, il nuovo dex2oat viene eseguito mentre la vecchia immagine del sistema è ancora in esecuzione per generare i file che saranno necessari al nuovo sistema. L'aggiornamento non è considerato disponibile finché il lavoro non è stato completato.

Possiamo (dovremmo) spedire un dispositivo A/B da 32GiB? 16GiB? 8GiB?

32GiB funzionano bene come è stato dimostrato su Pixel e 320MiB su 16GiB significano una riduzione del 2%. Allo stesso modo, 320 MiB su 8 GiB hanno registrato una riduzione del 4%. Ovviamente A/B non sarebbe la scelta consigliata su dispositivi con 4GiB, poiché il sovraccarico di 320MiB rappresenta quasi il 10% dello spazio totale disponibile.

AVB2.0 richiede OTA A/B?

No. L'avvio verificato di Android ha sempre richiesto aggiornamenti basati su blocchi, ma non necessariamente aggiornamenti A/B.

Le OTA A/B richiedono AVB2.0?

NO.

Le OTA A/B interrompono la protezione rollback di AVB2.0?

No. C'è un po' di confusione qui perché se un sistema A/B non riesce ad avviarsi nella nuova immagine di sistema (dopo un certo numero di tentativi determinati dal bootloader) tornerà automaticamente all'immagine di sistema "precedente". Il punto chiave qui però è che "precedente" nel senso A/B è in realtà ancora l'immagine del sistema "attuale". Non appena il dispositivo avvia con successo una nuova immagine, entra in azione la protezione di rollback e garantisce che non si possa tornare indietro. Ma finché non hai effettivamente avviato con successo la nuova immagine, la protezione di rollback non la considera l'immagine del sistema corrente.

Se stai installando un aggiornamento mentre il sistema è in esecuzione, non è lento?

Con gli aggiornamenti non A/B, l'obiettivo è installare l'aggiornamento il più rapidamente possibile perché l'utente è in attesa e non è in grado di utilizzare il proprio dispositivo mentre viene applicato l'aggiornamento. Con gli aggiornamenti A/B, è vero il contrario; poiché l'utente sta ancora utilizzando il proprio dispositivo, l'obiettivo è il minor impatto possibile, quindi l'aggiornamento è volutamente lento. Attraverso la logica nel client di aggiornamento del sistema Java (che per Google è GmsCore, il pacchetto principale fornito da GMS), Android tenta anche di scegliere un momento in cui gli utenti non utilizzano affatto i propri dispositivi. La piattaforma supporta la sospensione/ripresa dell'aggiornamento e il client può utilizzarlo per sospendere l'aggiornamento se l'utente inizia a utilizzare il dispositivo e riprenderlo quando il dispositivo è nuovamente inattivo.

Ci sono due fasi durante l'acquisizione di un'OTA, mostrate chiaramente nell'interfaccia utente come Passaggio 1 di 2 e Passaggio 2 di 2 sotto la barra di avanzamento. Il passo 1 corrisponde alla scrittura dei blocchi di dati, mentre il passo 2 precompila i file .dex. Queste due fasi sono abbastanza diverse in termini di impatto sulle prestazioni. La prima fase è l'I/O semplice. Ciò richiede poche risorse (RAM, CPU, I/O) perché copia lentamente i blocchi.

La seconda fase esegue dex2oat per precompilare la nuova immagine di sistema. Questo ovviamente ha limiti meno chiari sui suoi requisiti perché compila app reali. E ovviamente c'è molto più lavoro da fare nella compilazione di un'app grande e complessa rispetto a un'app piccola e semplice; mentre nella fase 1 non ci sono blocchi di dischi più grandi o più complessi di altri.

Il processo è simile a quando Google Play installa un aggiornamento dell'app in background prima di mostrare la notifica delle 5 app aggiornate , come avviene da anni.

Cosa succede se un utente sta effettivamente aspettando l'aggiornamento?

L'attuale implementazione in GmsCore non distingue tra aggiornamenti in background e aggiornamenti avviati dall'utente, ma potrebbe farlo in futuro. Nel caso in cui l'utente abbia chiesto esplicitamente l'installazione dell'aggiornamento o stia guardando la schermata di avanzamento dell'aggiornamento, daremo priorità al lavoro di aggiornamento partendo dal presupposto che stiano attivamente aspettando che finisca.

Cosa succede se si verifica un errore nell'applicazione di un aggiornamento?

Con gli aggiornamenti non A/B, se un aggiornamento non veniva applicato, l'utente si ritrovava solitamente con un dispositivo inutilizzabile. L'unica eccezione era se l'errore si verificava prima ancora che l'applicazione fosse avviata (perché, ad esempio, il pacchetto non riusciva a verificare). Con gli aggiornamenti A/B, la mancata applicazione di un aggiornamento non influisce sul sistema attualmente in esecuzione. L'aggiornamento può essere semplicemente riprovato in un secondo momento.

Quali sistemi su chip (SoC) supportano A/B?

Al 15-03-2017 disponiamo delle seguenti informazioni:

Android 7.x e versioni precedenti Android 8.x e versioni successive
Qualcomm A seconda delle richieste dell'OEM Tutti i chipset riceveranno supporto
Mediatek A seconda delle richieste OEM Tutti i chipset riceveranno supporto

Per dettagli sugli orari, consulta i tuoi contatti SoC. Per i SoC non elencati sopra, contatta direttamente il tuo SoC.