APEX i Android Q: Den største ting siden Project Treble?

click fraud protection

Google arbejder på APEX: opdatering af systembiblioteker som en standard Linux-distro. Forventet i Android Q kan APEX være den største ting siden Project Treble.

Implementering af APEX er sandsynligvis den største hovedpine, Google har været udsat for siden introduktionen af ​​Project Treble. Hvad er APEX, og hvordan vil dets introduktion ændre Android?

Ideen bag APEX i sig selv er ret almindelig i daglige GNU/Linux-distributioner: pakkeopdateringer rettet mod specifikke sektioner af Linux-bibliotekssættet. Men det er noget, Google aldrig har prøvet at gøre, da Android har brugt en RO (skrivebeskyttet) partition, hvor alle systembiblioteker og rammer lagres i forhold til de sædvanlige RW (læse-skrive) partitioner, der bruges i de fleste Linux-distributioner, hvilket gengiver standardopgraderingsprocessen uegnet.

Biblioteker er prækompileret kode, som kan bruges i andre programmer. Ofte brugte metoder kan laves om til biblioteker, som Android-apps kan kalde, hvilket reducerer størrelsen af ​​APK'er, da den samme kode ikke skal genimplementeres på tværs af flere apps. Du kan finde mange forudinstallerede systembiblioteker i mapperne /system/lib og /system/lib64. Android-systembiblioteker opdateres normalt ikke individuelt – snarere bliver de opdateret som en del af Android-platformsopgraderinger via en OTA-opdatering. På den anden side kan biblioteker i Linux-distros opdateres individuelt. Med introduktionen af ​​APEX kan systembiblioteker i Android opdateres individuelt ligesom Android-apps. Den største fordel ved dette er, at app-udviklere vil være i stand til at drage fordel af opdaterede biblioteker uden at vente på, at en OEM udruller en komplet systemopgradering. Lad os dykke ned i flere tekniske detaljer om, hvordan APEX fungerer.

Hvordan vil APEX ændre den måde, biblioteker opdateres på?

APEX er et økosystem, der tvang (eller rettere, tvinger) Google til at genoverveje den måde, Android indlæser alle biblioteker og filer fra en ikke-standard partition, der er forskellig fra /system.

Først og fremmest skal vi specificere forskellen mellem et delt bibliotek og et statisk bibliotek. Et delt bibliotek er et bibliotek (normalt en fil ved navn libkind.so), der ikke indeholder al den kode, der er nødvendig for at køre i sig selv, men som faktisk er "linket" til andre biblioteker leverer koden, mens et statisk bibliotek er, som du kan gætte, et bibliotek, der ikke er afhængigt af andre biblioteker og har alt inkluderet statisk i fil.

Android har historisk konfigureret biblioteksstien (kendt som LD_LIBRARY_PATH i Linux-verdenen) med en enkelt fil kaldet ld.config.txt [0] for at konfigurere de tilladte søgestier for de delte biblioteker, der kræves af enten binær eller en anden bibliotek. Disse stier er hardkodet i konfigurationen og kan ikke udvides. Dette layout, inklusive den skrivebeskyttede systempartition, fører til uopdaterbare biblioteker, medmindre brugeren installerer en OTA Android-opdatering. Google løste dette problem og gjorde det muligt at udvide søgestien ved at lade de enkelte APEX-pakker levere deres egen ld.config.txt, der indeholdt de ekstra (og opdaterede) biblioteksstier indeholdt i dem.

Selvom dette træk løste et af hovedproblemerne, var der stadig et par alvorlige problemer at løse. Først og fremmest: ABI (application binary interface) stabilitet. Biblioteker bør altid eksportere et stabilt sæt grænseflader for at tillade andre apps og biblioteker at fortsætte med at arbejde med den samme protokol selv med det opgraderede bibliotek. Google arbejder aktivt på det ved at forsøge at skabe en stabil C-grænseflade mellem APEXed-biblioteker.

Men en APEX er ikke begrænset til biblioteker og binære filer alene. Faktisk kan det indeholde konfigurationsfiler, tidszoneopdateringer og nogle Java-frameworks (konkryptere i skrivende stund).

Her er et par eksempler på de aktuelle APEX-pakker leveret af AOSP:

  • com.android.runtime: ART og bionisk runtime (binære filer og biblioteker)
  • com.android.tzdata: TimeZone og ICU-data (biblioteker og konfigurationsdata)
  • com.android.resolv: Bibliotek brugt af Android til at løse netværksrelaterede anmodninger (biblioteker)
  • com.android.conscrypt: En Java-sikkerhedsudbyder (Java framework)

Hvordan er en APEX-pakke installeret og struktureret?

En APEX-pakke er et simpelt zip-arkiv (som en APK), der kan installeres af vores praktiske ADB (på dette tidspunkt i udviklingen) og senere af brugeren selv via en pakkehåndtering (som Google Play eller manuelt gennem Android-pakken installatør).

ZIP-layoutet er som følger:

Lad os dykke ned i det.

apex_manifest.json angiver pakkenavnet og versionen.

apex_payload.img er et mikro-filsystembillede (formateret som EXT4).

De andre filer er en del af verifikationsprocessen, der bruges til at installere pakken. Lad os kigge på det.

Tilstedeværelsen af AndroidManifest.xml, selvom det hovedsageligt bruges i applikationer, hjælper os med at forstå, at det meste af implementeringen, der bruges til en standard APK-installation, genbruges selv til disse pakker. Faktisk er det kun udvidelsen, der kontrolleres for at skelne mellem dem.

Det META-INF/ biblioteket har pakkecertifikatet og bruger den samme mekanisme som normale APK'er. Altså disse pakker verificeres af et privat/offentligt nøglepar under kørsel, før brugeren får lov til at installere en opdatering. Men det var ikke nok for Google, så de tilføjede yderligere 2 sikkerhedslag. De bruger dm-verity til at kontrollere integriteten af ​​billedet og AVB (Android Verified Boot) verifikationer for at sikre, at billedet kommer fra en pålidelig kilde. I værste fald vil APEX-pakken blive afvist.

Hvis alle verifikationstrinene lykkes, vil billedet blive markeret som gyldigt og erstatte systemvarianten ved næste genstart.

Hvordan installeres et image ved opstart?

Lad os starte med at tage et kig på de APEX'er, der i øjeblikket er installeret på min enhed (en emulator)

Som du kan se, er de forudinstallerede pakker gemt i /system/apex/ og alle er i øjeblikket på version nummer 1. Men hvad sker der, når en APEX aktiveres? Vi vil igen bruge com.android.tzdata som eksempel.

Lad os genstarte enheden og analysere logcat.

De første 2 linjer giver nok information til at forstå pakkens oprindelse, og hvor den skal være installeret: /apex/, en ny mappe introduceret i Android Q, som vil blive brugt til at gemme de aktiverede pakker.

Efter at pakken er blevet verificeret med AVB og den offentlige nøgle matcher, monteres APEX ved hjælp af en loop-enhed til /dev/block/loop0, hvilket gør EXT4-filsystemet tilgængeligt for systemet. En loop-enhed er en pseudo-enhed, der gør en fil tilgængelig som en blokenhed, hvilket gør indholdet af denne fil tilgængeligt som et monteringspunkt.

På dette tidspunkt bruges APEX stadig ikke på grund af @1-suffikset (der angiver pakkeversionen). For endelig at lade systemet vide, at vores pakke er blevet aktiveret, bliver den bind-monteret til /apex/com.android.tzdata, hvor Android aktivt forventer, at tzdata lever. Et bind mount overlejrer en eksisterende mappe eller fil under et andet punkt. [1]

APEX-implementeringen er fuldstændig indeholdt i et enkelt lager under AOSP. [2] Apexd (APEX daemon) biblioteket har koden kørende på Android. Apexer-biblioteket har den kode, der bruges af build-systemet til at oprette APEX-pakkerne.

Hvad er formålet?

På dette tidspunkt kan jeg kun spekulere. Mit bedste gæt er, at Google forsøger at skabe et kernesæt af APEX-pakker, der kan opdateres af Google til evt. en samlet basiskerne af Android delt mellem leverandører, hvilket gør "system" kun opdateringer mulige, men ved hjælp af en enkelt pakke opdateringer.

Vil alle enheder understøtte APEX?

Nej. For eksempel kræver apexd, at /data/apex er tilgængelig lige efter opstart for at opdatere alle Android-modulerne. Med FDE (Full-disk Encryption) krypteres /data/apex, indtil enheden låses op af brugeren, hvilket gør APEX dybest set ubrugelig, da kun systemets APEX-varianter vil blive indlæst ved opstart. Bortset fra det burde alle enheder understøtte APEX, men de har brug for et par kernepatches (hvoraf mange er rettelser fundet af Google, mens de spiller med loop-enheder). [3] [4]


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