APEX în Android Î: Cel mai mare lucru de la Project Treble?

Google lucrează la APEX: actualizarea bibliotecilor de sistem ca o distribuție standard Linux. Așteptată în Android Q, APEX poate fi cel mai mare lucru de la Project Treble.

Implementarea APEX este probabil cea mai mare durere de cap cu care s-a confruntat Google de la introducerea Proiectului Treble. Ce este APEX și cum va schimba introducerea lui Android?

Ideea din spatele APEX în sine este destul de comună în distribuțiile GNU/Linux de zi cu zi: actualizările pachetului vizează secțiuni specifice ale setului de biblioteci Linux. Dar asta este ceva ce Google nu a încercat niciodată să facă, având în vedere că Android a folosit o partiție RO (numai citire) în care toate bibliotecile de sistem și cadrele sunt stocate față de partițiile obișnuite RW (citire-scriere) utilizate în majoritatea distribuțiilor Linux, redând procesul standard de actualizare nepotrivit.

Bibliotecile sunt cod precompilat care poate fi folosit în alte programe. Metodele utilizate în mod obișnuit pot fi transformate în biblioteci pentru ca aplicațiile Android să le apeleze, reducând dimensiunea APK-urilor, deoarece același cod nu va trebui reimplementat în mai multe aplicații. Puteți găsi multe biblioteci de sistem preinstalate în directoarele /system/lib și /system/lib64. Bibliotecile de sistem Android de obicei nu sunt actualizate individual, ci mai degrabă sunt actualizate ca parte a actualizărilor platformelor Android printr-o actualizare OTA. Pe de altă parte, bibliotecile din distribuțiile Linux pot fi actualizate individual. Odată cu introducerea APEX, bibliotecile de sistem din Android pot fi actualizate individual, precum aplicațiile Android. Principalul avantaj al acestui lucru este că dezvoltatorii de aplicații vor putea profita de bibliotecile actualizate fără a aștepta ca un OEM să lanseze o actualizare completă a sistemului. Să ne aprofundăm în mai multe detalii tehnice despre modul în care funcționează APEX.

Cum va schimba APEX modul în care bibliotecile sunt actualizate?

APEX este un ecosistem care a forțat (sau mai bine zis, forțează) Google să reconsidere modul în care Android încarcă toate bibliotecile și fișierele dintr-o partiție non-standard diferită de /system.

În primul rând, trebuie să specificăm diferența dintre o bibliotecă partajată și o bibliotecă statică. O bibliotecă partajată este o bibliotecă (de obicei un fișier numit libkind.so) care nu include tot codul necesar pentru a rula în sine, dar este „legată” la alte biblioteci de fapt furnizarea codului, în timp ce o bibliotecă statică este, după cum puteți ghici, o bibliotecă care nu depinde de nicio altă bibliotecă și are totul inclus static în fişier.

Android a configurat istoric calea bibliotecii (cunoscută ca LD_LIBRARY_PATH în lumea Linux) cu un singur fișier numit ld.config.txt [0] pentru a configura căile de căutare permise pentru bibliotecile partajate necesare fie de binar, fie de altul bibliotecă. Aceste căi sunt codificate în configurație și nu sunt extensibile. Acest aspect, inclusiv partiția de sistem numai pentru citire, duce la biblioteci care nu pot fi actualizate, cu excepția cazului în care utilizatorul instalează o actualizare OTA Android. Google a remediat această problemă, permițând extinderea căii de căutare, permițând pachetelor unice APEX să ofere propriul lor ld.config.txt, care includea căile de biblioteci suplimentare (și actualizate) conținute în ele.

Deși această mișcare a rezolvat una dintre problemele principale, mai erau câteva probleme serioase de depășit. În primul rând: stabilitate ABI (interfață binară a aplicației). Bibliotecile ar trebui să exporte întotdeauna un set stabil de interfețe pentru a permite altor aplicații și biblioteci să continue să funcționeze cu același protocol, chiar și cu biblioteca actualizată. Google lucrează activ la asta încercând să creeze o interfață C stabilă între bibliotecile APEXed.

Dar un APEX nu se limitează doar la biblioteci și binare. De fapt, poate conține fișiere de configurare, actualizări de fus orar și unele cadre Java (conscrypt la momentul scrierii).

Iată câteva exemple de pachete APEX actuale furnizate de AOSP:

  • com.android.runtime: runtime ART și bionic (binare și biblioteci)
  • com.android.tzdata: Date TimeZone și ICU (biblioteci și date de configurare)
  • com.android.resolv: Bibliotecă utilizată de Android pentru a rezolva solicitările legate de rețea (biblioteci)
  • com.android.conscrypt: un furnizor de securitate Java (cadru Java)

Cum este instalat și structurat un pachet APEX?

Un pachet APEX este o arhivă zip simplă (cum ar fi un APK) care poate fi instalată de ADB-ul nostru la îndemână (în acest moment al dezvoltării) și, mai târziu, de către utilizator prin intermediul unui manager de pachete (cum ar fi Google Play sau manual prin pachetul Android instalator).

Dispunerea ZIP este după cum urmează:

Să ne aprofundăm în asta.

Apex_manifest.json specifică numele și versiunea pachetului.

Apex_payload.img este o imagine cu micro-sistem de fișiere (formatată ca EXT4).

Celelalte fișiere fac parte din procesul de verificare utilizat pentru instalarea pachetului. Hai să aruncăm o privire.

Prezenta lui AndroidManifest.xml, chiar dacă este folosit în principal în aplicații, ne ajută să înțelegem că cea mai mare parte a implementării utilizate pentru o instalare APK standard este reutilizată chiar și pentru aceste pachete. De fapt, doar extensia este verificată pentru a face diferența între ele.

The META-INF/ directorul are certificatul de pachet și folosește același mecanism ca APK-urile normale. Deci aceste pachete sunt verificate de o pereche de chei private/publice în timpul execuției înainte ca utilizatorului să i se permită să instaleze o actualizare. Dar asta nu a fost suficient pentru Google, așa că au adăugat încă 2 straturi de securitate. Ei folosesc dm-verity pentru a verifica integritatea imaginii și verificări AVB (Android Verified Boot) pentru a se asigura că imaginea provine dintr-o sursă de încredere. În cel mai rău caz, pachetul APEX va fi respins.

Dacă toți pașii de verificare au succes, imaginea va fi marcată ca validă și va înlocui varianta de sistem la următoarea repornire.

Cum se instalează o imagine la pornire?

Să începem prin a arunca o privire la APEX-urile instalate în prezent pe dispozitivul meu (un emulator)

După cum puteți vedea, pachetele preinstalate sunt stocate în /system/apex/ și toate sunt în prezent pe versiunea numărul 1. Dar ce se întâmplă când un APEX este activat? Vom folosi din nou com.android.tzdata ca exemplu.

Să repornim dispozitivul și să analizăm logcat-ul.

Primele 2 rânduri oferă suficiente informații pentru a înțelege originea pachetului și unde va fi acesta instalat: /apex/, un nou director introdus în Android Q care va fi folosit pentru stocarea celor activate pachete.

După ce pachetul a fost verificat cu succes cu AVB și cheia publică se potrivește, APEX-ul este montat folosind un dispozitiv de buclă la /dev/block/loop0, făcând sistemul de fișiere EXT4 accesibil sistemului. Un dispozitiv de buclă este un pseudo-dispozitiv care face un fișier accesibil ca dispozitiv bloc, făcând conținutul acelui fișier accesibil ca punct de montare.

În acest moment, APEX-ul încă nu este utilizat din cauza sufixului @1 (care indică versiunea pachetului). Pentru a informa în sfârșit sistemul că pachetul nostru a fost activat cu succes, acesta va fi montat în legătură cu /apex/com.android.tzdata, unde Android se așteaptă în mod activ să trăiască tzdata. O montare de legătură suprapune un director sau un fișier existent sub un alt punct. [1]

Implementarea APEX este cuprinsă în întregime într-un singur depozit sub AOSP. [2] Directorul apexd (daemon APEX) are codul care rulează pe Android. Directorul apexer are codul folosit de sistemul de compilare pentru a crea pachetele APEX.

Care este scopul?

În acest moment, tot ce pot face este să speculez. Cea mai bună presupunere este că Google încearcă să creeze un set de bază de pachete APEX care poate fi actualizat de Google pentru a putea crea un nucleu de bază unificat al Android partajat între furnizori, făcând posibile doar actualizările „sistemului”, dar folosind un singur pachet actualizări.

Toate dispozitivele vor suporta APEX?

Nu. De exemplu, apexd necesită ca /data/apex să fie disponibil imediat după pornire pentru a actualiza toate modulele Android. Cu FDE (Full-disk Encryption), /data/apex este criptat până când dispozitivul este deblocat de către utilizator, făcând APEX practic inutil, deoarece numai variantele APEX de sistem vor fi încărcate la pornire. În afară de asta, toate dispozitivele ar trebui să accepte APEX, dar au nevoie de câteva corecții ale nucleului (multe dintre acestea sunt remedieri găsite de Google în timp ce se joacă cu dispozitive în buclă). [3] [4]


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