APEX i Android Q: The Biggest Thing Siden Project Treble?

Google jobber med APEX: oppdatering av systembiblioteker som en standard Linux-distro. Forventet i Android Q, kan APEX være det største siden Project Treble.

Implementering av APEX er sannsynligvis den største hodepinen Google har møtt siden introduksjonen av Project Treble. Hva er APEX, og hvordan vil introduksjonen endre Android?

Ideen bak APEX i seg selv er ganske vanlig i daglige GNU/Linux-distribusjoner: pakkeoppdateringer rettet mot bestemte deler av Linux-biblioteksettet. Men det er noe Google aldri prøvde å gjøre gitt at Android har brukt en RO (skrivebeskyttet) partisjon der alle systembibliotekene og rammeverk lagres i forhold til de vanlige RW-partisjonene (lese-skrive) som brukes i de fleste Linux-distribusjoner, noe som gjengir standard oppgraderingsprosessen passer ikke.

Biblioteker er forhåndskompilert kode som kan brukes i andre programmer. Vanlige metoder kan gjøres om til biblioteker for Android-apper å ringe, og redusere størrelsen på APK-er ettersom den samme koden ikke trenger å implementeres på nytt på tvers av flere apper. Du kan finne mange forhåndsinstallerte systembiblioteker i katalogene /system/lib og /system/lib64. Android-systembiblioteker oppdateres vanligvis ikke individuelt – snarere blir de oppdatert som en del av Android-plattformoppgraderinger via en OTA-oppdatering. På den annen side kan biblioteker i Linux-distros oppdateres individuelt. Med introduksjonen av APEX kan systembiblioteker i Android oppdateres individuelt som Android-apper. Hovedfordelen med dette er at apputviklere vil kunne dra nytte av oppdaterte biblioteker uten å vente på at en OEM skal rulle ut en full systemoppgradering. La oss dykke ned i flere tekniske detaljer om hvordan APEX fungerer.

Hvordan vil APEX endre måten biblioteker oppdateres på?

APEX er et økosystem som tvang (eller rettere sagt, tvinger) Google til å revurdere måten Android laster inn alle biblioteker og filer fra en ikke-standard partisjon som er forskjellig fra /system.

Først av alt må vi spesifisere forskjellen mellom et delt bibliotek og et statisk bibliotek. Et delt bibliotek er et bibliotek (vanligvis en fil som heter libkind.so) som ikke inkluderer all koden som trengs for å kjøre i seg selv, men som faktisk er "lenket" til andre biblioteker gir koden, mens et statisk bibliotek er, som du kan gjette, et bibliotek som ikke er avhengig av noen andre biblioteker og har alt inkludert statisk i fil.

Android har historisk konfigurert bibliotekbanen (kjent som LD_LIBRARY_PATH i Linux-verdenen) med en enkelt fil kalt ld.config.txt [0] for å konfigurere de tillatte søkebanene for de delte bibliotekene som trengs av enten binær eller annen bibliotek. Disse banene er hardkodet i konfigurasjonen og kan ikke utvides. Dette oppsettet, inkludert den skrivebeskyttede systempartisjonen, fører til uoppdaterbare biblioteker med mindre brukeren installerer en OTA Android-oppdatering. Google løste dette problemet og gjorde det mulig å utvide søkebanen ved å la de enkeltstående APEX-pakkene gi sin egen ld.config.txt som inkluderte de ekstra (og oppdaterte) bibliotekbanene som finnes i dem.

Selv om dette grepet løste et av hovedproblemene, var det fortsatt noen alvorlige problemer å overvinne. Først av alt: ABI (application binary interface) stabilitet. Biblioteker bør alltid eksportere et stabilt sett med grensesnitt for å la andre apper og biblioteker fortsette å jobbe med samme protokoll selv med det oppgraderte biblioteket. Google jobber aktivt med det ved å prøve å lage et stabilt C-grensesnitt mellom APEXed-biblioteker.

Men en APEX er ikke begrenset til biblioteker og binærfiler alene. Faktisk kan den inneholde konfigurasjonsfiler, tidssoneoppdateringer og noen Java-rammeverk (konkryptere i skrivende stund).

Her er noen eksempler på de nåværende APEX-pakkene levert av AOSP:

  • com.android.runtime: ART og bionisk kjøretid (binærfiler og biblioteker)
  • com.android.tzdata: TimeZone og ICU-data (biblioteker og konfigurasjonsdata)
  • com.android.resolv: Bibliotek som brukes av Android for å løse nettverksrelaterte forespørsler (biblioteker)
  • com.android.conscrypt: En Java-sikkerhetsleverandør (Java-rammeverk)

Hvordan er en APEX-pakke installert og strukturert?

En APEX-pakke er et enkelt zip-arkiv (som en APK) som kan installeres av vår praktiske ADB (på dette tidspunktet i utviklingen) og senere av brukeren selv via en pakkebehandling (som Google Play eller manuelt gjennom Android-pakken installatør).

ZIP-oppsettet er som følger:

La oss dykke ned i det.

apex_manifest.json spesifiserer pakkenavnet og versjonen.

apex_payload.img er et mikrofilsystembilde (formatert som EXT4).

De andre filene er en del av bekreftelsesprosessen som brukes til å installere pakken. La oss se.

Nærværet av AndroidManifest.xml, selv om den hovedsakelig brukes i applikasjoner, hjelper oss å forstå at det meste av implementeringen som brukes for en standard APK-installasjon, gjenbrukes selv for disse pakkene. Faktisk er det bare utvidelsen som blir sjekket for å skille mellom dem.

De META-INF/ katalogen har pakkesertifikatet og bruker samme mekanisme som vanlige APK-er. Altså disse pakkene verifiseres av et privat/offentlig nøkkelpar ved kjøring før brukeren får lov til å installere en oppdatering. Men det var ikke nok for Google, så de la til ytterligere to lag med sikkerhet. De bruker dm-verity for å sjekke integriteten til bildet og AVB (Android Verified Boot)-verifikasjoner for å sikre at bildet kommer fra en pålitelig kilde. I verste fall vil APEX-pakken bli avvist.

Hvis alle bekreftelsestrinn er vellykkede, vil bildet merkes som gyldig og erstatte systemvarianten ved neste omstart.

Hvordan installeres et bilde ved oppstart?

La oss starte med å ta en titt på APEXene som er installert på enheten min (en emulator)

Som du kan se, er de forhåndsinstallerte pakkene lagret i /system/apex/ og alle er for øyeblikket på versjon 1. Men hva skjer når en APEX aktiveres? Vi vil igjen bruke com.android.tzdata som eksempel.

La oss starte enheten på nytt og analysere logcat.

De to første linjene gir nok informasjon til å forstå pakkens opprinnelse og hvor den skal være installert: /apex/, en ny katalog introdusert i Android Q som vil bli brukt til å lagre de aktiverte pakker.

Etter at pakken har blitt verifisert med AVB og den offentlige nøkkelen samsvarer, monteres APEX ved hjelp av en loop-enhet til /dev/block/loop0, noe som gjør EXT4-filsystemet tilgjengelig for systemet. En sløyfeenhet er en pseudoenhet som gjør en fil tilgjengelig som en blokkenhet, og gjør innholdet i den filen tilgjengelig som et monteringspunkt.

På dette tidspunktet er APEX fortsatt ikke brukt på grunn av @1-suffikset (som indikerer pakkeversjonen). For å endelig la systemet få vite at pakken vår har blitt aktivert, blir den bindingsmontert til /apex/com.android.tzdata der Android aktivt forventer at tzdata skal leve. En bindingsmontering overlegger en eksisterende katalog eller fil under et annet punkt. [1]

APEX-implementeringen er fullstendig inneholdt i et enkelt depot under AOSP. [2] Apexd (APEX daemon)-katalogen har koden som kjører på Android. Apexer-katalogen har koden som brukes av byggesystemet for å lage APEX-pakkene.

Hva er hensikten?

På dette tidspunktet er alt jeg kan gjøre å spekulere. Min beste gjetning er at Google prøver å lage et kjernesett med APEX-pakker som kan oppdateres av Google for å muligens lage en enhetlig grunnkjerne av Android som deles mellom leverandører, noe som gjør "system"-oppdateringer bare mulige, men med en enkelt pakke oppdateringer.

Kommer alle enheter til å støtte APEX?

Nei. For eksempel krever apexd at /data/apex er tilgjengelig rett etter oppstart for å oppdatere alle Android-modulene. Med FDE (Full-disk Encryption), er /data/apex kryptert til enheten låses opp av brukeren, noe som gjør APEX i utgangspunktet ubrukelig ettersom bare systemets APEX-varianter vil bli lastet ved oppstart. Bortsett fra det bør alle enheter støtte APEX, men de trenger noen få kjernepatcher (hvorav mange er rettelser funnet av Google mens de spiller med loop-enheter). [3] [4]


Kilder [0], [1], [2], [3], [4]