Kameraer i tilpassede ROM-er: Hvordan utviklere får maskinvare til å fungere uten kildekode

Uten kildekode, hvordan får utviklere maskinvarekomponenter som kameraer til å fungere i tilpassede ROM-er? Svaret er en BLOB, shim og mye feilsøking.

Med utgivelsen av Android Oreo og mange enheter som Xiaomi Redmi Note 3, Google Nexus 5 og andre som uoffisielt mottar det, er det sannsynligvis rimelig å lure på hvorfor de samme funksjonene (for det meste kameraet) har en tendens til å bli ødelagt når utviklere porterer en Android Open Source Project (AOSP)-basert ROM. Du har sannsynligvis sett XDA-forumtråder med ROM-er med en lang liste med ødelagte funksjoner øverst. "Hva fungerer" etterfulgt av en liste over fungerende funksjoner, så nedenunder det ikoniske "Hva fungerer ikke? Fortell meg!" er to populære refrenger på forumene våre som praktisk talt har blitt et meme på steder som Reddit og Twitter.

Hvorfor er så mye funksjonalitet ødelagt når en utvikler prøver å portere en AOSP ROM til enheten deres? Det grunnleggende svaret er at fordi funksjoner endres på tvers av forskjellige versjoner av Android, vil ikke gamle enhetsdrivere pakket som BLOB-er fungere med nyere versjoner av Android, eller til og med bare med lager AOSP. For å overvinne det, bruker utviklere det som kalles en "shim", men prosessen involvert er vanskelig, tidkrevende og noen ganger veldig vanskelig å feilsøke.

I denne artikkelen vil vi skissere hvordan shims fungerer, spesielt med hensyn til å få kameraet til å fungere ordentlig på AOSP-baserte ROM-er. Vi vil bruke OnePlus 3T som eksempel. Merk at vanskeligheten med å få disse funksjonene til å fungere er svært enhetsspesifikke.

OnePlus 3T som kjører OxygenOS. Selv om OnePlus-telefoner er kjent for sin tilpassede utviklingsvennlighet, er det mye arbeid utviklerne gjør bak kulissene for å lage stabile porter av AOSP.


Hva er en shim eller en BLOB?

For å begynne å forstå en del av hva utviklere gjør, må vi først forklare noen få ting. Selv om Android OS er åpen kildekode (det kalles Android Open Source Project av en grunn), er det ikke programvaren (uten kjernen) som sendes på tusenvis av Android-enheter. Utviklere har ikke tilgang til kildekoden til Samsung Experience, EMUI, OxygenOS, eller noen av de andre tredjepartsvariantene til Android.

Nå bryr utviklere som overfører aksjer AOSP til en ikke-Google-enhet sannsynligvis ikke om kildekoden til disse Android-skallene, siden de ikke kommer til å bli det. modifisere og bygge disse ROM-ene. Det ville være sant, hvis ikke for én stor, stor grunn: delene som er nødvendige for å få kameraet til å fungere som det skal, hovedsakelig de kamera HAL (Maskinvareabstraksjonslag), er også lukket kilde.

Problemet med å ha ikke bare kamera-HAL, men også ROM-lukket kilde, er at utviklere som jobber med å portere AOSP til enheten deres blir jobber blind. Den lukkede kilden OEM ROM er i stand til å kommunisere med kameraets HAL helt fint fordi OEM har tilgang til kameraets HAL-kilde. Kamera-HAL er det som lar ROM-en "snakke med" kameraets maskinvare - uten den ville kameraet ikke fungere. Tenk på kameraet HAL som rattet og pedalene til bilen. Rattet/pedalene gir mulighet for kontroll over de interne komponentene i kjøretøyet ved å tilby et eksternt grensesnitt for sjåføren (ROM-en) for å bruke de interne komponentene.

Grafikk som viser kameraarkitekturen. Kilde: Google

Etter hvert som kameraets maskinvare blir mer og mer kompleks (den bruk av doble kameraer, for eksempel), å ha tilgang til kameraets HAL-kilde ville gjøre portering av en AOSP ROM med et funksjonelt kamera til en mye enklere oppgave.

OEM-er gir imidlertid ikke tilgang til kameraets HAL-kilde av ulike årsaker. For det første, hvis de ikke har alle eierrettighetene til kamera-HAL (for eksempel når de inkorporerer åndsverk fra andre selskaper), kan de ikke distribuere kilden. For det andre kan frigjøring av kameraets HAL-kilde sette deres egen intellektuelle eiendom i fare. Til slutt er selskaper ikke under noen juridisk forpliktelse til å oppgi denne kildekoden (i motsetning til kjernekildekoden som de er forpliktet til å løslate under GPL), og derfor har de ingen insentiv til å frigi den. Så uten tilgang til kameraets HAL-kilde, hvordan får utviklere kameraet til å fungere på AOSP ROM-er? Svaret er en BLOB, shim og massevis av feilsøking.

En gjenstand BLOB (Binary Large OBject) inneholder ferdigpakkede binærfiler som er den kompilerte formen for programvare. I dette tilfellet blir kameraets HAL-kilde kompilert av OEM og sendt på enheter som binærfiler. Når utviklere snakker om BLOB-er, refererer de til de binære filene som sendes på live-enheter som de er i stand til å trekke ut. Nå har temaet "kamera BLOBs". lenge plaget OnePlus i mange måneder, men sannheten i saken er at utviklere alltid har hatt tilgang til kamera-BLOB-ene. De kamera HAL kildekoden er den gylne billetten for utviklere her, men det vil aldri, aldri bli løslatt på grunn av den juridiske faren ville det sette selskaper som OnePlus inn.

Utviklere som ønsker å bringe AOSP inn på en enhet, har derfor kun BLOB-er fra kameraets HAL som de ikke har tilgang til kildekoden for. Sjelden om noen gang kan en utvikler pare AOSP ROM-koden sin med kameraets HAL BLOB og forvente at den skal fungere, så for å bygge bro mellom de to, oppretter utviklere det som kalles en "shim.”

Å "shim" er å "kile (noe) eller fylle opp et mellomrom." Dette er faktisk hva en utvikler gjør når skrive et shim – de legger til kode for å tillate at BLOB-en kommuniserer med AOSP-kildekoden de jobber med med. Shims brukes til å få BLOB-er av alle forskjellige slag til å fungere med AOSP, men vanligvis er det kamera-BLOB som krever mest shimming. Som vi nevnte tidligere, kreves shimming ikke bare for å overføre nyere versjoner av Android til en enhet (som f.eks. alle de uoffisielle Android Oreo ROM-ene), men også nødvendige når AOSP av samme Android-versjon overføres til den enhet.

Anbefalt lesning: Fra butikk til hylle: En grundig kapitulasjon av hvorfor MSM8974-enheter er ekskludert fra Nougat

OnePlus 2, for eksempel, fikk sin siste offisielle store OS-oppdatering i form av Android 6.0 Marshmallow. Enheten har imidlertid faktisk fullt fungerende tilpassede AOSP-baserte ROM-er basert på Android Nougat, og det er takket være det harde arbeidet til utviklere og deres shims. Vi skal bryte ned noen eksempler på shims, men først må vi snakke om nøyaktig hvordan shims fungerer.


Hvordan fungerer shimming?

Siden utviklere ikke har tilgang til kameraets HAL- eller OEM ROM-kilde (og bare de forhåndskompilerte binære filene), kan de ikke vite hvilke funksjoner kamera-HAL forventer. På grunn av dette er det ofte et misforhold mellom navnet på funksjonen som kameraet HAL ser etter og det faktiske navnet på funksjonen i AOSP-koden utvikleren jobber med.

For å løse dette problemet oppretter utvikleren ganske enkelt en ny funksjon som bruker samme navn på funksjon som kameraet HAL BLOB forventer, men denne nye funksjonen utfører bare det utvikleren ønsker det også. Denne nye funksjonen som fungerer som en mellommann mellom BLOB og AOSP er shim. Dette spesielle scenariet der BLOB ikke klarer å finne funksjonen den leter etter er en av de vanligste der det er behov for et mellomlegg.

Veldig enkelt MS malingsdiagram som viser hvor et mellomlegg er nødvendig.

Kanskje ting vil gi litt mer mening med et hypotetisk eksempel som involverer OnePlus 3T. Vi vil lage et eksempel ved å bruke OxygenOS og OnePlus-kameraet. Hvis vi bruker kamera-BLOB-er hentet fra OxygenOS Nougat for OnePlus 3T for å bygge en AOSP-basert Nougat ROM, kan vi få problemer. Dette er fordi kamera-BLOB-ene (som opprinnelig ble kompilert av OEM) vil kunne referere til alle funksjonene den trenger i OxygenOS, men siden kompilert AOSP ROM kanskje ikke har disse funksjonene eller kan ha kompilert dem under et annet navn (som fører til uoverensstemmelse mellom funksjonssymboler), vil det være en feil. Dette kan fikses ved å lage en ny funksjon i AOSP ROM med navnet BLOB forventer – vårt shim.

Symboler i en programmeringskontekst brukes til å referere til spesifikke funksjoner i kode. Symboler er nødvendige fordi posisjonen til en funksjon kan endres når koden redigeres, og dette for å unngå hardkoding referanser til funksjoner, lager kompilatoren en tabell med symboler som andre funksjoner kan bruke for alltid å referere til høyre funksjon. Når du endrer navnet på en funksjon før kompilering, endres symbolet også, så i utgangspunktet endringer som OEM lager til kameraet HAL-kilde før kompilering vil kreve at utviklere oppretter en ny shim.

Vise en symboltabell med trakt. Kilde: Aprioritert

Forklaringen vi har tilbudt så langt gjør at det høres ut som det er enkelt å lage shims. Å endre noen funksjonsnavn her og der høres ikke så vanskelig ut, ikke sant? Hadde det bare vært så enkelt. Virkeligheten med shims involverer mer enn bare funksjonsnavn. Vi snakket med XDA Recognized Developer Sultanxda som var i stand til å gi oss et eksempel på en av de vanskeligere shims han har jobbet med.


Shimming - Ikke så enkelt som det høres ut

For de som ikke er kjent med OnePlus 3T, var frontkameraet ganske ødelagt først på AOSP-baserte tilpassede ROM-er. Til å begynne med vil forsøk på å ta et bilde over 8 MP resultere i krasje. I sitt forsøk på å løse dette problemet, laget Sultanxda flere shims for å la OnePlus 3T-frontkameraet fungere skikkelig.

Shim #1 - Endring av kamerapakkenavn

For å hindre at frontkameraet krasjet hver gang brukeren tok et bilde over 8 MP, tvang Sultanxda kameraet HAL til å identifisere alle kameraer som OnePlus-kameraet. Dette er gjort fordi OnePlus bestemte seg for å dedikere en hjelpefunksjon til visse applikasjoner (isOnePlusCamera, isFacebookCameraosv.) av en eller annen grunn. Sultanxda fikset dette ved å shimming kameraet HAL slik at det peker på en ny funksjon som alltid returnerer "sant" som om brukeren bruker OnePlus-kameraet - selv når de ikke er det.

Shim #2 - Deaktiver QuadraCfa

For sin neste shim måtte han deaktivere QuadraCfa, som antagelig er en proprietær Qualcomm-teknologi knyttet til kameraet. Vi sier antagelig fordi verken meg selv eller Sultanxda er helt sikre på hva QuadraCfa er, men Sultanxda vet at det knuste frontkameraet hver gang det ble aktivert.

Han observerte at QuadraCfa på en eller annen måte ville aktivere seg selv, men han var ikke sikker på hvorfor eller hvordan det gjorde det. Å løse dette krevde en ganske ukonvensjonell modifikasjon fra hans side. I en konvensjonell shim, gir shim-funksjonen, når den er kompilert, det manglende symbolet som BLOB leter etter. I dette tilfellet hadde BLOB allerede symbolene den trengte - de som antagelig representerte funksjonene som startet QuadraCfa.

Velsigne Hex Editor. Programmet Sultanxda brukte.

Derfor trengte han å overstyre symbolene som ble brukt av kameraets HAL og i hovedsak få dem til å "mangle" så hans shims ville gi de "manglende" symbolene. Den eneste måten å gjøre det på er via hex-redigering av selve kameraets HAL. Hex-redigering er i bunn og grunn å se gjennom en haug med uorganisert sludder i form av binære data for å finne en nål i høystakken – enten en funksjon eller en streng du ønsker å redigere.

Hex-redigering av en funksjon er vesentlig vanskeligere enn hex-redigering av en streng, men heldigvis klarte Sultanxda å unngå å måtte hex-redigere funksjonene bak QuadraCfa ved å i stedet hex-redigering av symbolnavnene for å annullere disse symbolene.

Shim #3 - Bright Light Crash Fix

Deretter identifiserte Sultanxda at å ta et bilde fra frontkameraet under sterkt lysforhold ville føre til at kameraet krasjet. For å reprodusere denne feilen på sin egen enhet, Sultanxda faktisk slått på lommelyktfunksjonen til OnePlus One og skinte lyset foran OnePlus 3Ts frontvendte kamera for å få den til å krasje og produsere brukbare logger! Da han oppdaget hvilken funksjon som forårsaket krasjet, laget han et shim for å tvinge enheten til å bruke modus for svakt lys hele tiden for frontkameraet.

Shim #4 - lavoppløselige frontvendte kamerabilder

Etter å ha fikset det kraftige lyskrasjet med forrige shim, oppdaget Sultanxda en annen feil som faktisk oppsto som et direkte resultat av det shim: lavoppløselige frontvendte kamerabilder. I stedet for å ta bilder med den oppløsningen brukeren ba om (f.eks. 16 MP), vil det resulterende bildet bli tatt med 4 MP.

Å løse dette krevde at han shim funksjonene handleSuperResolution og isSuperResolution for alltid å returnere sann, men KUN når frontkameraet er aktivt (fordi ellers ville kameraet krasje når du tar bilder fra den bakre sensoren).


Leksjon lært - Shimming kan være vanskelig

Sultanxda innrømmer at shimsene han måtte lage for å få OnePlus 3T-frontkameraet til å fungere, ikke representerer ditt typiske eksempel på shim. Han er ganske stolt av mellomlegget sitt gitt dens kompleksitet og den sjeldne nødvendigheten av å hex-redigere selve BLOB. Men dette eksemplet viser bare hvor vanskelig det kan være å få kameraets maskinvare til å fungere på visse enheter.

Måtte dine kamerashim-eventyr være mindre smertefulle enn mine var. -Sultanxda

Logger, logger og flere logger. Uten en konsekvent måte å reprodusere et krasj og uten logger, har utviklere lite håp om å finne kilden til problemet. Selv om de finner hva som forårsaker problemet, er det ikke alltid en enkel løsning. Hele prosessen med å finne og knuse disse feilene kan ta dager eller uker, og er grunnen til at det å fikse kameraet på AOSP ROM-er er en av de vanskeligere oppgavene.

Hvis enheten din har en AOSP ROM portert til den med fullt fungerende maskinvare, kan du forhåpentligvis begynne det setter pris på kampen som disse utviklerne kan ha gått gjennom for å gi deg dem egenskaper. Sett pris på dem for arbeidet deres, for det er ikke lett. Det er mye arbeid som de aller fleste brukere ikke en gang vil legge merke til, ettersom talentfulle utviklere på forumene våre tar seg av de mange usette delene av Android.

Vi vil gjerne gi en spesiell takk til Sultanxda for de mange bidragene han foreslo i utformingen av denne artikkelen.