APEX i Android F: Det största sedan Project Treble?

click fraud protection

Google arbetar med APEX: uppdatering av systembibliotek som en vanlig Linux-distro. Förväntad i Android Q kan APEX vara det största sedan Project Treble.

Att implementera APEX är förmodligen den största huvudvärk Google har mött sedan introduktionen av Project Treble. Vad är APEX och hur kommer introduktionen att förändra Android?

Tanken bakom APEX i sig är ganska vanlig i vardagliga GNU/Linux-distributioner: paketuppdateringar som riktar sig till specifika delar av Linux-biblioteksuppsättningen. Men det är något Google aldrig försökte göra med tanke på att Android har använt en RO-partition (skrivskyddad) där alla systembibliotek och ramar lagras jämfört med de vanliga RW-partitionerna (läs-skriva) som används i de flesta Linux-distributioner, vilket återger standarduppgraderingsprocessen olämplig.

Bibliotek är förkompilerad kod som kan användas i andra program. Vanligt använda metoder kan göras till bibliotek för Android-appar att anropa, vilket minskar storleken på APK-filer eftersom samma kod inte behöver implementeras om i flera appar. Du kan hitta många förinstallerade systembibliotek i katalogerna /system/lib och /system/lib64. Android-systembibliotek uppdateras vanligtvis inte individuellt – snarare uppdateras de som en del av Android-plattformsuppgraderingar via en OTA-uppdatering. Å andra sidan kan bibliotek i Linux-distros uppdateras individuellt. Med introduktionen av APEX kan systembibliotek i Android uppdateras individuellt som Android-appar. Den största fördelen med detta är att apputvecklare kommer att kunna dra nytta av uppdaterade bibliotek utan att vänta på att en OEM ska rulla ut en fullständig systemuppgradering. Låt oss dyka in i mer tekniska detaljer om hur APEX fungerar.

Hur kommer APEX att förändra hur bibliotek uppdateras?

APEX är ett ekosystem som tvingade (eller snarare, tvingar) Google att ompröva hur Android laddar alla bibliotek och filer från en icke-standardpartition som skiljer sig från /system.

Först och främst måste vi specificera skillnaden mellan ett delat bibliotek och ett statiskt bibliotek. Ett delat bibliotek är ett bibliotek (vanligtvis en fil som heter libkind.so) som inte innehåller all kod som behövs för att köras i sig utan är "länkad" till andra bibliotek faktiskt tillhandahåller koden, medan ett statiskt bibliotek är, som du kan gissa, ett bibliotek som inte är beroende av några andra bibliotek och har allt inkluderat statiskt i fil.

Android har historiskt konfigurerat bibliotekssökvägen (känd som LD_LIBRARY_PATH i Linux-världen) med en enda fil kallas ld.config.txt [0] för att konfigurera de tillåtna sökvägarna för de delade biblioteken som behövs av antingen binär eller annan bibliotek. Dessa sökvägar är hårdkodade i konfigurationen och kan inte utökas. Denna layout, inklusive den skrivskyddade systempartitionen, leder till bibliotek som inte går att uppdatera om inte användaren installerar en OTA Android-uppdatering. Google åtgärdade det här problemet och gjorde det möjligt att utöka sökvägen genom att låta de enskilda APEX-paketen tillhandahålla sin egen ld.config.txt som inkluderade de extra (och uppdaterade) biblioteksvägarna i dem.

Även om detta drag löste ett av huvudproblemen, fanns det fortfarande några allvarliga problem att lösa. Först och främst: ABI (application binary interface) stabilitet. Bibliotek bör alltid exportera en stabil uppsättning gränssnitt så att andra appar och bibliotek kan fortsätta att arbeta med samma protokoll även med det uppgraderade biblioteket. Google arbetar aktivt med det genom att försöka skapa ett stabilt C-gränssnitt mellan APEXed-bibliotek.

Men en APEX är inte begränsad till enbart bibliotek och binärer. Faktum är att den kan innehålla konfigurationsfiler, tidszonsuppdateringar och vissa Java-ramverk (konkryptera i skrivande stund).

Här är några exempel på de nuvarande APEX-paketen som tillhandahålls av AOSP:

  • com.android.runtime: ART och bionisk körtid (binärer och bibliotek)
  • com.android.tzdata: TimeZone och ICU-data (bibliotek och konfigurationsdata)
  • com.android.resolv: Bibliotek som används av Android för att lösa nätverksrelaterade förfrågningar (bibliotek)
  • com.android.conscrypt: En Java-säkerhetsleverantör (Java-ramverk)

Hur är ett APEX-paket installerat och strukturerat?

Ett APEX-paket är ett enkelt zip-arkiv (som en APK) som kan installeras av vår praktiska ADB (vid denna tidpunkt i utvecklingen) och senare av användaren själv via en pakethanterare (som Google Play eller manuellt via Android-paketet installatör).

ZIP-layouten är som följer:

Låt oss dyka in i det.

apex_manifest.json anger paketnamnet och versionen.

apex_payload.img är en mikrofilsystemavbildning (formaterad som EXT4).

De andra filerna är en del av verifieringsprocessen som används för att installera paketet. Låt oss ta en titt.

Närvaron av AndroidManifest.xml, även om det huvudsakligen används i applikationer, hjälper oss att förstå att det mesta av implementeringen som används för en standard APK-installation återanvänds även för dessa paket. Det är faktiskt bara tillägget som kontrolleras för att skilja mellan dem.

De META-INF/ katalogen har paketcertifikatet och använder samma mekanism som vanliga APK-filer. Alltså dessa paket verifieras av ett privat/offentligt nyckelpar vid körning innan användaren tillåts installera en uppdatering. Men det räckte inte för Google, så de lade till ytterligare två lager av säkerhet. De använder dm-verity för att kontrollera bildens integritet och AVB-verifieringar (Android Verified Boot) för att säkerställa att bilden kommer från en pålitlig källa. I värsta fall kommer APEX-paketet att avvisas.

Om alla verifieringssteg är framgångsrika kommer bilden att markeras som giltig och kommer att ersätta systemvarianten vid nästa omstart.

Hur installeras en bild vid uppstart?

Låt oss börja med att ta en titt på de APEX som för närvarande är installerade på min enhet (en emulator)

Som du kan se lagras de förinstallerade paketen i /system/apex/ och alla finns för närvarande på version 1. Men vad händer när en APEX aktiveras? Vi kommer återigen att använda com.android.tzdata som exempel.

Låt oss starta om enheten och analysera logcat.

De första två raderna ger tillräckligt med information för att förstå paketets ursprung och var det kommer att vara installerad: /apex/, en ny katalog introducerad i Android Q som kommer att användas för att lagra de aktiverade paket.

Efter att paketet har verifierats med AVB och den publika nyckeln matchar, monteras APEX med hjälp av en loopenhet till /dev/block/loop0, vilket gör EXT4-filsystemet tillgängligt för systemet. En loop-enhet är en pseudo-enhet som gör en fil tillgänglig som en blockenhet, vilket gör innehållet i den filen tillgängligt som en monteringspunkt.

Vid det här laget används fortfarande inte APEX på grund av suffixet @1 (som indikerar paketversionen). För att äntligen låta systemet veta att vårt paket har aktiverats framgångsrikt, kommer det att bindas till /apex/com.android.tzdata där Android aktivt förväntar sig att tzdata ska leva. En bindningsmontering överlagrar en befintlig katalog eller fil under en annan punkt. [1]

APEX-implementeringen finns helt och hållet i ett enda arkiv under AOSP. [2] Katalogen apexd (APEX daemon) har koden som körs på Android. Apexer-katalogen har koden som används av byggsystemet för att skapa APEX-paketen.

Vad är syftet?

Vid det här laget kan jag bara spekulera. Min bästa gissning är att Google försöker skapa en kärnuppsättning av APEX-paket som kan uppdateras av Google för att eventuellt skapa en enhetlig baskärna av Android som delas mellan leverantörer, vilket gör "system"-uppdateringar möjliga, men med ett enda paket uppdateringar.

Kommer alla enheter att stödja APEX?

Nej. Till exempel kräver apexd att /data/apex är tillgänglig direkt efter start för att uppdatera alla Android-moduler. Med FDE (Full-Disk Encryption) krypteras /data/apex tills enheten låses upp av användaren, vilket gör APEX i princip värdelös eftersom endast system-APEX-varianterna kommer att laddas vid uppstart. Utöver det borde alla enheter stödja APEX, men de behöver några kärnpatchar (av vilka många är korrigeringar som hittats av Google när de spelar med loop-enheter). [3] [4]


Källor [0], [1], [2], [3], [4]