Telecamere nelle ROM personalizzate: come gli sviluppatori fanno funzionare l'hardware senza codice sorgente

Con il rilascio di Android Oreo e molti dispositivi come Xiaomi Redmi Note 3, Google Nexus 5 e altri che lo stanno ricevendo ufficiosamente, è probabilmente lecito chiedersi perché le stesse funzionalità (principalmente la fotocamera) tendano a non funzionare quando gli sviluppatori portano un Android Open ROM basata su Project Source (AOSP). Probabilmente hai visto thread del forum di ROM con un lungo elenco di funzionalità rotte in alto. "Cosa funziona" seguito da un elenco di funzioni funzionanti, quindi in basso l'iconico "Cosa non funziona? Dimmelo tu! ”Sono due ritornelli popolari nei nostri forum che sono praticamente diventati meme in luoghi come Reddit e Twitter.

Perché tanta funzionalità viene interrotta ogni volta che uno sviluppatore tenta di trasferire una ROM AOSP sul proprio dispositivo? La risposta di base è che, poiché le funzioni cambiano tra le diverse versioni di Android, i vecchi driver di dispositivo impacchettati come BLOB non funzioneranno con le versioni più recenti di Android, o anche solo con AOSP di serie. Per ovviare a questo, gli sviluppatori fanno uso di quello che viene chiamato "shim", ma il processo in questione è complicato, richiede molto tempo e talvolta è molto difficile eseguire il debug.

In questo articolo, illustreremo come funzionano gli spessori, in particolare per quanto riguarda il corretto funzionamento della fotocamera su ROM basate su AOSP. Useremo OnePlus 3T come esempio. Si noti che la difficoltà di far funzionare queste funzionalità è altamente specifica per il dispositivo.

OnePlus 3T con OxygenOS in esecuzione. Sebbene i telefoni OnePlus siano noti per la loro facilità di sviluppo personalizzata, c'è molto lavoro che gli sviluppatori svolgono dietro le quinte per rendere stabili le porte di AOSP.


Che cos'è uno spessore o un BLOB?

Per iniziare persino a capire parte di ciò che gli sviluppatori stanno facendo, dobbiamo prima spiegare alcune cose. Sebbene il sistema operativo Android sia open source (per un motivo si chiama Android Open Source Project), il software (senza il kernel) fornito su migliaia di dispositivi Android non lo è. Gli sviluppatori non hanno accesso al codice sorgente di Samsung Experience, EMUI, OxygenOS o di qualsiasi altra versione di Android di terze parti.

Ora, gli sviluppatori che effettuano il porting di AOSP di serie su un dispositivo non Google probabilmente non si preoccupano del codice sorgente di queste skin Android in quanto non modificheranno e costruiranno queste ROM. Sarebbe vero, se non per un grande, grande motivo: le parti necessarie per far funzionare correttamente la videocamera, principalmente la videocamera HAL (Hardware Abstraction Layer), sono anch'esse a sorgente chiuso .

Il problema con avere non solo la videocamera HAL ma anche la sorgente chiusa ROM è che gli sviluppatori che lavorano al porting di AOSP sul proprio dispositivo funzioneranno alla cieca . La ROM OEM di origine chiusa è in grado di interfacciarsi con l'HAL della videocamera, poiché l'OEM ha accesso alla sorgente HAL della videocamera. L'HAL della videocamera è ciò che consente alla ROM di "parlare" con l'hardware della videocamera, senza di essa la videocamera non funzionerebbe. Pensa alla videocamera HAL come al volante e ai pedali dell'auto. Il volante / pedali consentono il controllo dei componenti interni del veicolo fornendo un'interfaccia esterna per il conducente (la ROM) per utilizzare i componenti interni.

Grafico che mostra l'architettura della telecamera. Fonte: Google

Man mano che l'hardware della videocamera diventa sempre più complesso (l'avvento delle doppie videocamere, ad esempio), avere accesso alla sorgente HAL della videocamera renderebbe molto più semplice il porting di una ROM AOSP con una videocamera funzionale.

Tuttavia, gli OEM non forniscono l'accesso alla sorgente HAL della videocamera per vari motivi. In primo luogo, se non dispongono di tutti i diritti di proprietà sulla videocamera HAL (come quando incorporano proprietà intellettuale di altre società), non possono distribuire la fonte. In secondo luogo, il rilascio della sorgente HAL della videocamera può compromettere la propria proprietà intellettuale. Infine, le aziende non hanno alcun obbligo legale di fornire questo codice sorgente (diversamente dal codice sorgente del kernel che sono tenuti a rilasciare ai sensi della GPL), quindi non hanno incentivi a rilasciarlo. Quindi, senza l'accesso alla sorgente HAL della videocamera, come fanno esattamente gli sviluppatori a far funzionare la videocamera su ROM AOSP? La risposta è un BLOB, shim e un sacco di debug.

Un dispositivo BLOB (Binary Large OBject) contiene file binari preconfezionati che sono la forma compilata del software. In questo caso, la sorgente HAL della videocamera viene compilata dall'OEM e spedita su dispositivi come binari. Quando gli sviluppatori parlano di BLOB, si riferiscono a quei file binari forniti su dispositivi live che sono in grado di estrarre. Ora, l'argomento dei "BLOB di telecamere" ha afflitto OnePlus per molti mesi, ma la verità è che gli sviluppatori hanno sempre avuto accesso ai BLOB di telecamere. Il codice sorgente HAL della fotocamera è il biglietto d'oro per gli sviluppatori qui, tuttavia, ma questo non verrà mai, mai rilasciato a causa del pericolo legale che metterebbe aziende come OnePlus.

Pertanto, gli sviluppatori che desiderano portare AOSP su un dispositivo vengono lasciati solo con BLOB dell'HAL della fotocamera per i quali non hanno accesso al codice sorgente. Raramente se mai uno sviluppatore può accoppiare il proprio codice AOSP ROM con la videocamera HAL BLOB e aspettarsi che funzioni, quindi per colmare il divario tra i due, gli sviluppatori creano quello che viene chiamato " shim ".

"Shim" significa "incuneare (qualcosa) o riempire uno spazio". Questo è effettivamente ciò che fa uno sviluppatore quando scrive uno shim: aggiungono codice per consentire al BLOB di interfacciarsi con il codice sorgente AOSP con cui stanno lavorando . Gli spessori vengono utilizzati per far funzionare BLOB di ogni tipo con AOSP, ma di solito è il BLOB della fotocamera che richiede il maggior shimmer. Come accennato in precedenza, lo shimming è necessario non solo per il porting delle versioni più recenti di Android su un dispositivo (come tutte quelle ROM Android Oreo non ufficiali) ma anche per il porting di AOSP della stessa versione di Android su quel dispositivo.

Lettura consigliata: dal negozio allo scaffale: una capitolazione approfondita del perché i dispositivi MSM8974 sono esclusi dal torrone

OnePlus 2, ad esempio, ha ricevuto il suo ultimo aggiornamento ufficiale del sistema operativo sotto forma di Android 6.0 Marshmallow. Il dispositivo, tuttavia, ha in realtà ROM personalizzate basate su AOSP completamente basate su Android Nougat, e questo grazie al duro lavoro degli sviluppatori e dei loro shim. Analizzeremo alcuni esempi di spessori, ma prima dobbiamo parlare di come funzionano esattamente gli spessori.


Come funziona lo shimming?

Poiché gli sviluppatori non hanno accesso all'HAL della videocamera o alla sorgente ROM OEM (e solo ai binari precompilati), non possono sapere quali funzioni si aspetta l'HAL della videocamera. Per questo motivo, spesso esiste una discrepanza tra il nome della funzione che la videocamera HAL sta cercando e il nome effettivo della funzione nel codice AOSP con cui lo sviluppatore sta lavorando.

Per risolvere questo problema, lo sviluppatore crea semplicemente una nuova funzione che utilizza lo stesso nome della funzione che la videocamera HAL BLOB si aspetta, ma questa nuova funzione esegue semplicemente ciò che lo sviluppatore desidera. Questa nuova funzione che funge da intermediario tra BLOB e AOSP è lo spessore. Questo particolare scenario in cui il BLOB non riesce a trovare la funzione che sta cercando è uno dei più comuni in cui è necessario uno spessore.

Schema di vernice MS molto semplice che mostra dove è necessario uno spessore.

Forse le cose avranno un po 'più senso con un esempio ipotetico che coinvolge OnePlus 3T. Creeremo un esempio usando OxygenOS e la videocamera OnePlus. Se utilizziamo BLOB per fotocamere presi da OxygenOS Nougat per OnePlus 3T per creare una ROM Nougat basata su AOSP, potremmo incorrere in problemi. Questo perché i BLOB della fotocamera (che sono stati originariamente compilati dall'OEM) saranno in grado di fare riferimento a tutte le funzioni di cui ha bisogno all'interno di OxygenOS, ma poiché la ROM AOSP compilata potrebbe non avere quelle funzioni o potrebbe averle compilate con un nome diverso ( portando così ad una discrepanza tra i simboli delle funzioni), si verificherà un errore. Questo può essere risolto creando una nuova funzione all'interno della ROM AOSP con il nome che BLOB si aspetta: il nostro shim.

I simboli in un contesto di programmazione vengono utilizzati per fare riferimento a funzioni specifiche nel codice. I simboli sono necessari perché la posizione di una funzione può cambiare quando il codice viene modificato, quindi al fine di evitare riferimenti codificati alle funzioni, il compilatore crea una tabella di simboli che altre funzioni possono utilizzare per fare sempre riferimento alla funzione corretta. Quando si modifica il nome di una funzione prima della compilazione, anche il suo simbolo cambia, quindi sostanzialmente qualsiasi modifica apportata dall'OEM alla sorgente HAL della videocamera prima della compilazione richiederà agli sviluppatori di creare un nuovo spessore.

Visualizzazione di una tabella dei simboli con tramoggia. Fonte: Apriorit

La spiegazione che abbiamo offerto finora fa sembrare che creare spessori sia facile. Cambiare alcuni nomi di funzioni qui e là non sembra troppo difficile, giusto? Se solo fosse così facile. La realtà degli spessori coinvolge molto più che semplici rinominazioni di funzioni. Abbiamo parlato con lo sviluppatore riconosciuto Sultanxda che è stato in grado di fornirci un esempio di uno degli spessori più difficili su cui ha lavorato.


Shimmer - Non facile come sembra

Per coloro che non hanno familiarità con OnePlus 3T, la fotocamera frontale era piuttosto rotta inizialmente su ROM personalizzate basate su AOSP. Tanto per cominciare, il tentativo di scattare qualsiasi foto oltre 8 MP comporterebbe un arresto anomalo. Nel suo tentativo di risolvere questo problema, Sultanxda ha effettuato diversi spessori per consentire alla fotocamera frontale OnePlus 3T di funzionare correttamente.

Shim # 1 - Modifica del nome del pacchetto della fotocamera

Al fine di impedire il crash della fotocamera frontale ogni volta che l'utente ha scattato una foto oltre 8 MP, Sultanxda ha costretto l'HAL della fotocamera a identificare tutte le fotocamere come la fotocamera OnePlus. Questo perché OnePlus ha deciso di dedicare una funzione di supporto a determinate applicazioni ( isOnePlusCamera, isFacebookCamera, ecc.) Per qualche motivo. Sultanxda ha risolto il problema spostando l'HAL della videocamera in modo che punti a una nuova funzione che ritorna sempre "vera" come se l'utente stesse utilizzando la videocamera OnePlus, anche quando non lo sono.

Shim # 2 - Disabilita QuadraCfa

Per il suo prossimo shim, ha dovuto disabilitare QuadraCfa che è presumibilmente una tecnologia proprietaria Qualcomm relativa alla telecamera. Diciamo presumibilmente perché né io né Sultanxda siamo esattamente sicuri di cosa sia QuadraCfa, ma Sultanxda sa che ha rotto la fotocamera frontale ogni volta che è stata abilitata.

Ha osservato che QuadraCfa si sarebbe in qualche modo abilitato, ma non era sicuro del perché o di come lo stesse facendo. La sua risoluzione ha richiesto una modifica piuttosto non convenzionale da parte sua. In uno shim convenzionale, la funzione shim, una volta compilata, fornisce il simbolo mancante che BLOB sta cercando. In questo caso, il BLOB aveva già i simboli di cui aveva bisogno, quelli che presumibilmente rappresentavano le funzioni che stavano avviando QuadraCfa.

Bless Hex Editor. Il programma Sultanxda utilizzato.

Pertanto, aveva bisogno di sovrascrivere i simboli usati dalla videocamera HAL e, in sostanza, renderli "mancanti" in modo che i suoi spessori avrebbero fornito quei simboli "mancanti". L'unico modo per farlo è tramite la modifica esadecimale della stessa videocamera HAL . La modifica esadecimale sta fondamentalmente guardando attraverso un mucchio di incomprensibili non organizzati sotto forma di dati binari al fine di trovare un ago nel pagliaio - una funzione o una stringa che stai cercando di modificare.

La modifica esadecimale di una funzione è sostanzialmente più difficile della modifica esadecimale di una stringa, ma fortunatamente Sultanxda è stato in grado di evitare di dover modificare in modo esadecimale le funzioni dietro QuadraCfa invece modificando in esadecimale i nomi dei simboli per annullare quei simboli.

Shim # 3 - Correzione di crash della luce intensa

Successivamente, Sultanxda ha identificato che scattare una foto dalla fotocamera frontale in condizioni di illuminazione intensa causerebbe il crash della fotocamera. Per riprodurre questo bug sul proprio dispositivo, Sultanxda ha effettivamente attivato la funzione torcia del suo OnePlus One e ha acceso la luce di fronte alla fotocamera frontale di OnePlus 3T al fine di bloccarlo e produrre registri utilizzabili! Una volta scoperto quale funzione stava causando l'incidente, ha creato uno spessore per forzare il dispositivo a utilizzare sempre la modalità di scarsa illuminazione per la fotocamera frontale.

Shim # 4 - Immagini della fotocamera frontale a bassa risoluzione

Dopo aver risolto il crollo della luce intensa con lo shim precedente, Sultanxda ha scoperto un altro bug che in realtà è sorto come risultato diretto di quello shim: immagini della fotocamera frontale a bassa risoluzione. Invece di scattare foto alla risoluzione richiesta dall'utente (ad es. 16MP), l'immagine risultante verrebbe scattata a 4MP.

Risolvendo ciò, è necessario che shim le funzioni handleSuperResolution e isSuperResolution sempre vere, ma SOLO quando la fotocamera frontale è attiva (perché altrimenti, la fotocamera si bloccherebbe quando si scattano foto dal sensore posteriore).


Lezione imparata - Lo shimming può essere difficile

Sultanxda ammette che gli spessori che ha dovuto creare per far funzionare la fotocamera frontale OnePlus 3T non rappresentano il tipico esempio di shim. È piuttosto orgoglioso del suo spessore dato la sua complessità e la rara necessità di modificare il BLOB stesso. Ma questo esempio mostra solo quanto sia difficile far funzionare l'hardware della fotocamera su determinati dispositivi.

Possa la tua macchina fotografica evitare le avventure meno dolorose delle mie. -Sultanxda

Registri, registri e altri registri. Senza un modo coerente per riprodurre un arresto anomalo e senza registri, gli sviluppatori hanno poche speranze di trovare l'origine del problema. Anche se trovano ciò che causa il problema, non è sempre una soluzione semplice. L'intero processo di ricerca e eliminazione di questi bug può richiedere giorni o settimane ed è il motivo per cui fissare la videocamera su ROM AOSP è uno dei compiti più difficili.

Se il tuo dispositivo ha una ROM AOSP con hardware completamente funzionante, si spera che tu possa iniziare ad apprezzare la lotta che quegli sviluppatori potrebbero aver attraversato per offrirti quelle funzionalità. Li apprezzo per il loro lavoro, perché non è facile. È un sacco di lavoro che la stragrande maggioranza degli utenti non noterà nemmeno, poiché sviluppatori di talento sui nostri forum si prendono cura delle molte parti invisibili di Android.

Vorremmo ringraziare in particolare Sultanxda per i numerosi contributi che ha suggerito nella realizzazione di questo articolo.