Google pracuje nad APEX: aktualizuje biblioteki systemowe jak w przypadku standardowej dystrybucji Linuksa. Oczekiwany w Androidzie Q APEX może być największą rzeczą od czasu Project Treble.
Wdrożenie APEX to prawdopodobnie największy ból głowy, z jakim boryka się Google od czasu wprowadzenia Project Treble. Czym jest APEX i jak jego wprowadzenie zmieni Androida?
Idea stojąca za APEXem jest dość powszechna w codziennych dystrybucjach GNU/Linuksa: aktualizacje pakietów ukierunkowane na określone sekcje zestawu bibliotek Linuksa. Ale jest to coś, czego Google nigdy nie próbował robić, biorąc pod uwagę, że Android używał partycji RO (tylko do odczytu), na której znajdują się wszystkie biblioteki systemowe i struktury są przechowywane w porównaniu ze zwykłymi partycjami RW (odczyt i zapis) używanymi w większości dystrybucji Linuksa, co renderuje standardowy proces aktualizacji nieodpowiedni.
Biblioteki to prekompilowany kod, którego można używać w innych programach. Często używane metody można przekształcić w biblioteki, z których będą mogły korzystać aplikacje na Androida, co zmniejszy rozmiar plików APK, ponieważ nie trzeba będzie ponownie implementować tego samego kodu w wielu aplikacjach. Wiele preinstalowanych bibliotek systemowych można znaleźć w katalogach /system/lib i /system/lib64. Biblioteki systemu Android zwykle nie są aktualizowane indywidualnie — raczej są aktualizowane w ramach aktualizacji platform Android za pośrednictwem aktualizacji OTA. Z drugiej strony biblioteki w dystrybucjach Linuksa mogą być aktualizowane indywidualnie. Wraz z wprowadzeniem APEX biblioteki systemowe w systemie Android można aktualizować indywidualnie, podobnie jak aplikacje na Androida. Główną korzyścią jest to, że twórcy aplikacji będą mogli korzystać ze zaktualizowanych bibliotek bez czekania, aż producent OEM przeprowadzi pełną aktualizację systemu. Przyjrzyjmy się bardziej technicznym szczegółom działania APEX.
Jak APEX zmieni sposób aktualizacji bibliotek?
APEX to ekosystem, który zmusił (a raczej zmusza) Google do ponownego rozważenia sposobu, w jaki Android ładuje wszystkie biblioteki i pliki z niestandardowej partycji innej niż /system.
Przede wszystkim musimy określić różnicę pomiędzy biblioteką współdzieloną a biblioteką statyczną. Biblioteka współdzielona to biblioteka (zwykle plik o nazwie libkind.so), która nie zawiera całego kodu potrzebnego do uruchomienia w sobie, ale jest w rzeczywistości „połączona” z innymi bibliotekami udostępnianie kodu, podczas gdy biblioteka statyczna jest, jak można się domyślić, biblioteką, która nie jest zależna od żadnych innych bibliotek i ma wszystko zawarte statycznie w plik.
Android historycznie konfigurował ścieżkę biblioteki (znaną jako LD_LIBRARY_PATH w świecie Linuksa) za pomocą jednego pliku o nazwie ld.config.txt [0], aby skonfigurować dozwolone ścieżki wyszukiwania dla bibliotek współdzielonych potrzebnych w formacie binarnym lub innym biblioteka. Ścieżki te są zakodowane na stałe w konfiguracji i nie można ich rozszerzać. Ten układ, łącznie z partycją systemową tylko do odczytu, prowadzi do bibliotek, których nie można zaktualizować, chyba że użytkownik zainstaluje aktualizację OTA dla Androida. Firma Google naprawiła ten problem, umożliwiając rozszerzenie ścieżki wyszukiwania, umożliwiając pojedynczym pakietom APEX udostępnianie własnego pliku ld.config.txt zawierającego zawarte w nich dodatkowe (i zaktualizowane) ścieżki bibliotek.
Chociaż to posunięcie rozwiązało jeden z głównych problemów, nadal pozostało kilka poważnych problemów do rozwiązania. Po pierwsze: stabilność ABI (interfejs binarny aplikacji). Biblioteki powinny zawsze eksportować stabilny zestaw interfejsów, aby umożliwić innym aplikacjom i bibliotekom dalszą pracę z tym samym protokołem, nawet w przypadku uaktualnionej biblioteki. Google aktywnie nad tym pracuje, próbując stworzyć stabilny interfejs C pomiędzy bibliotekami APEXed.
Ale APEX nie ogranicza się wyłącznie do bibliotek i plików binarnych. W rzeczywistości może zawierać pliki konfiguracyjne, aktualizacje stref czasowych i niektóre frameworki Java (conscrypt w momencie pisania).
Oto kilka przykładów aktualnych pakietów APEX dostarczanych przez AOSP:
- com.android.runtime: ART i bioniczne środowisko wykonawcze (pliki binarne i biblioteki)
- com.android.tzdata: dane TimeZone i ICU (biblioteki i dane konfiguracyjne)
- com.android.resolv: Biblioteka używana przez Androida do rozwiązywania żądań związanych z siecią (biblioteki)
- com.android.conscrypt: dostawca zabezpieczeń Java (framework Java)
Jak jest instalowany i zorganizowany pakiet APEX?
Pakiet APEX to proste archiwum zip (jak APK), które może zostać zainstalowane przez nasz poręczny ADB (w tym momencie opracowywania) i później przez samego użytkownika za pośrednictwem menedżera pakietów (takiego jak Google Play lub ręcznie za pomocą pakietu Android instalator).
Układ ZIP jest następujący:
Zagłębmy się w to.
Plik apex_manifest.json określa nazwę i wersję pakietu.
Apex_payload.img to obraz mikrosystemu plików (w formacie EXT4).
Pozostałe pliki stanowią część procesu weryfikacji stosowanego podczas instalacji pakietu. Spójrzmy.
Obecność AndroidManifest.xml, nawet jeśli jest używany głównie w aplikacjach, pomaga nam zrozumieć, że większość implementacji użytej w standardowej instalacji APK jest ponownie wykorzystywana nawet w przypadku tych pakietów. W rzeczywistości sprawdzane jest tylko rozszerzenie, aby je rozróżnić.
The META-INF/ katalog ma certyfikat pakietu i korzysta z tego samego mechanizmu, co zwykłe pliki APK. Więc te pakiety są weryfikowane przez parę kluczy prywatny/publiczny w czasie wykonywania, zanim użytkownik będzie mógł zainstalować aktualizację. Ale to nie wystarczyło Google, więc dodali 2 kolejne warstwy zabezpieczeń. Używają dm-verity do sprawdzania integralności obrazu i weryfikacji AVB (Android Verified Boot), aby mieć pewność, że obraz pochodzi z zaufanego źródła. W najgorszym przypadku pakiet APEX zostanie odrzucony.
Jeśli wszystkie kroki weryfikacji przejdą pomyślnie, obraz zostanie oznaczony jako prawidłowy i zastąpi wariant systemu przy następnym uruchomieniu.
W jaki sposób obraz jest instalowany podczas rozruchu?
Zacznijmy od przyjrzenia się APEX-om aktualnie zainstalowanym na moim urządzeniu (emulatorze)
Jak widać, preinstalowane pakiety są przechowywane w /system/apex/ i wszystkie są obecnie w wersji nr 1. Ale co się stanie, gdy APEX zostanie aktywowany? Jako przykład ponownie użyjemy com.android.tzdata.
Zrestartujmy urządzenie i przeanalizujmy logcat.
Pierwsze 2 wiersze zawierają wystarczającą ilość informacji, aby zrozumieć pochodzenie paczki i miejsce jej przeznaczenia zainstalowany: /apex/, nowy katalog wprowadzony w Androidzie Q, który będzie używany do przechowywania aktywowanych pakiety.
Po pomyślnej weryfikacji pakietu za pomocą AVB i dopasowaniu klucza publicznego, APEX jest montowany za pomocą urządzenia pętlowego do /dev/block/loop0, dzięki czemu system plików EXT4 jest dostępny dla systemu. Urządzenie pętlowe to pseudourządzenie, które udostępnia plik jako urządzenie blokowe, dzięki czemu zawartość tego pliku jest dostępna jako punkt podłączenia.
W tym momencie APEX nadal nie jest używany ze względu na przyrostek @1 (który wskazuje wersję pakietu). Aby w końcu poinformować system, że nasz pakiet został pomyślnie aktywowany, zostanie on podłączony do /apex/com.android.tzdata, gdzie Android aktywnie oczekuje, że tzdata będzie działać. Montaż powiązania nakłada istniejący katalog lub plik w innym miejscu. [1]
Implementacja APEX jest w całości zawarta w jednym repozytorium w ramach AOSP. [2] W katalogu apexd (demon APEX) znajduje się kod działający na systemie Android. Katalog apexer zawiera kod używany przez system kompilacji do tworzenia pakietów APEX.
Jaki jest cel?
W tym momencie jedyne, co mogę zrobić, to spekulować. Domyślam się, że Google próbuje stworzyć podstawowy zestaw pakietów APEX, które Google może aktualizować w celu ewentualnego utworzenia ujednolicony podstawowy rdzeń Androida współdzielony przez dostawców, dzięki czemu możliwe są tylko aktualizacje „systemu”, ale przy użyciu jednego pakietu aktualizacje.
Czy wszystkie urządzenia będą obsługiwać APEX?
Nie. Na przykład apexd wymaga, aby /data/apex był dostępny zaraz po uruchomieniu, aby zaktualizować wszystkie moduły Androida. Dzięki FDE (szyfrowanie całego dysku) /data/apex jest szyfrowany do momentu odblokowania urządzenia przez użytkownika, co sprawia, że APEX jest w zasadzie bezużyteczny, ponieważ podczas rozruchu ładowane będą tylko systemowe warianty APEX. Poza tym wszystkie urządzenia powinny obsługiwać APEX, ale potrzebują kilku poprawek do jądra (z których wiele to poprawki znalezione przez Google podczas zabawy z urządzeniami pętlowymi). [3] [4]
Źródła [0], [1], [2], [3], [4]