Obraz wspólnego systemu Android

Na tej stronie przedstawiono kilka mechanizmów, z których mogą korzystać producenci OEM urządzeń z systemem Android w celu posiadania własnego wspólnego obrazu systemu (SSI) dla różnych linii produktów. Proponuje się także procedurę oparcia SSI będącego własnością OEM na ogólnym obrazie systemu (GSI) zbudowanym przez AOSP.

Tło

W Project Treble monolityczny system Android został podzielony na dwie części: część dotyczącą sprzętu (implementacja dostawcy) i część ogólnego systemu operacyjnego (framework systemu operacyjnego Android). Oprogramowanie każdego z nich jest instalowane na osobnej partycji: partycji dostawcy dla oprogramowania specyficznego dla sprzętu i partycji systemowej dla ogólnego oprogramowania systemu operacyjnego. Wersjonowany interfejs, zwany interfejsem dostawcy ( VINTF ), jest zdefiniowany i egzekwowany w obu partycjach. Korzystając z tego systemu partycjonowania, można modyfikować partycję systemową bez modyfikowania partycji dostawcy i odwrotnie.

Motywacja

Kod frameworka wydany w AOSP jest zgodny z architekturą Treble i zachował kompatybilność wsteczną z implementacjami starszych dostawców. Na przykład ogólny obraz systemu zbudowany na podstawie źródeł AOSP systemu Android 10 może działać na dowolnym urządzeniu zgodnym z Treble, które działa na systemie Android 8 lub nowszym. Wersja Androida dostarczana na urządzenia konsumenckie jest modyfikowana przez dostawców SoC i producentów OEM. (Zobacz Życie wersji Androida .) Te zmiany i rozszerzenia wprowadzone do frameworka nie zostały napisane w celu zachowania kompatybilności wstecznej, co przełożyło się na większą złożoność i wyższe koszty aktualizacji systemu operacyjnego. Zmiany i modyfikacje specyficzne dla urządzenia zwiększają koszt i złożoność aktualizacji wersji systemu operacyjnego Android.

Przed Androidem 11 nie było przejrzystej architektury umożliwiającej partnerom tworzenie modułowych rozszerzeń do platformy systemu operacyjnego Android. W tym dokumencie opisano kroki, które dostawcy SoC i producenci OEM mogą podjąć, aby utworzyć SSI. Oznacza to jeden obraz zbudowany na podstawie źródeł platformy systemu operacyjnego Android w celu ponownego wykorzystania na wielu urządzeniach, w celu zachowania zgodności wstecznej z implementacjami dostawców oraz zapewnienia znacznego zmniejszenia złożoności i kosztów aktualizacji systemu operacyjnego Android. Aby zapoznać się z konkretnymi krokami niezbędnymi do utworzenia SSI, zobacz sekcję Sugerowane kroki dla SSI opartej na GSI i pamiętaj, że nie musisz wykonywać wszystkich czterech kroków. To, które kroki wybierzesz (na przykład tylko krok 1), zależy od implementacji.

Przegląd SSI

Dzięki SSI komponenty oprogramowania specyficzne dla produktu i rozszerzenia OEM są umieszczane w nowej partycji /product . Komponenty w partycji /product używają dobrze zdefiniowanego, stabilnego interfejsu do interakcji z komponentami w partycji /system . Producenci OEM mogą zdecydować się na zbudowanie jednego SSI lub posiadanie niewielkiej liczby SSI do użytku w wielu jednostkach SKU urządzeń. Po wydaniu nowej wersji systemu operacyjnego Android producenci OEM inwestują tylko raz w aktualizację swoich systemów SSI do najnowszej wersji systemu Android. Mogą ponownie używać interfejsów SSI do aktualizacji wielu urządzeń bez aktualizacji partycji /product .

Należy pamiętać, że producenci OEM i dostawcy SoC tworzą SSI, które zawierają wszystkie niestandardowe funkcje i modyfikacje potrzebne producentom OEM. Mechanizmy i najlepsze praktyki przedstawione na tej stronie są przeznaczone dla producentów OEM do osiągnięcia następujących kluczowych celów:

  • Wykorzystuj ponownie SSI w wielu jednostkach SKU urządzeń.
  • Zaktualizuj system Android za pomocą rozszerzeń modułowych, aby ułatwić aktualizację systemu operacyjnego.

Podstawowa idea rozdzielenia komponentów specyficznych dla produktu na partycję produktu jest podobna do koncepcji firmy Treble polegającej na rozdzieleniu komponentów specyficznych dla SoC na partycję dostawcy. Interfejs produktu (podobny do VINTF ) umożliwia komunikację pomiędzy SSI a partycją produktu. Należy zauważyć, że w odniesieniu do SSI termin „komponenty” opisuje wszystkie zasoby, pliki binarne, teksty, biblioteki itd. instalowane w obrazach, które zasadniczo stają się partycjami.

Partycje wokół SSI

Rysunek 1 przedstawia partycje wokół SSI oraz wersjonowane interfejsy pomiędzy partycjami i politykami na interfejsach. W tej sekcji szczegółowo opisano każdą partycję i interfejs.

Partitions and interfaces around SSI block diagram

Rysunek 1. Partycje i interfejsy wokół SSI

Obrazy i partycje

Informacje zawarte w tej sekcji rozróżniają terminy obraz i partycja .

  • Obraz to koncepcyjny fragment oprogramowania, który można niezależnie aktualizować.
  • Partycja to fizyczne miejsce przechowywania, które można niezależnie aktualizować.

Sekcje na rysunku 1 są zdefiniowane w następujący sposób:

  • SSI: SSI to obraz wspólny dla producenta OEM i może istnieć na wielu urządzeniach. Nie zawiera żadnych komponentów specyficznych dla sprzętu ani produktu. Wszystko w danym SSI jest z definicji współdzielone pomiędzy wszystkimi urządzeniami korzystającymi z tego SSI. SSI składa się z pojedynczego obrazu /system lub partycji /system i /system_ext , jak pokazano na rysunku 1.

    • Partycja /system zawiera komponenty oparte na AOSP, podczas gdy /system_ext , jeśli jest zaimplementowany, zawiera rozszerzenia i komponenty producentów OEM i SoC, które są ściśle powiązane z komponentami AOSP. Na przykład biblioteka środowiska Java OEM, która udostępnia niestandardowe interfejsy API dla własnych aplikacji producenta OEM, lepiej pasuje do partycji /system_ext niż do partycji /system . Treść partycji /system i /system_ext jest zbudowana ze źródeł Androida zmodyfikowanych przez OEM.

    • Partycja /system_ext jest opcjonalna, ale warto jej używać w przypadku dowolnych niestandardowych funkcji i rozszerzeń, które są ściśle powiązane z komponentami opartymi na AOSP. To rozróżnienie pomaga zidentyfikować zmiany, które należy wprowadzić, aby przenieść takie komponenty z partycji /system_ext do partycji /product przez pewien okres czasu.

  • Produkt: zbiór komponentów specyficznych dla produktu lub urządzenia, które reprezentują dostosowania i rozszerzenia OEM systemu operacyjnego Android. Umieść komponenty specyficzne dla SoC w partycji /vendor . Dostawcy SoC mogą również używać partycji /product dla odpowiednich komponentów, takich jak komponenty niezależne od SoC. Na przykład, jeśli dostawca SoC dostarcza swoim klientom OEM komponent niezależny od SoC (dostarczanie go jest opcjonalne), sprzedawca SoC może umieścić ten komponent na obrazie produktu. Lokalizacja komponentu nie jest określona przez jego własność , jest podyktowana jego przeznaczeniem .

  • Dostawca : zbiór komponentów specyficznych dla SoC.

  • ODM: Zbiór komponentów specyficznych dla płytki, które nie są dostarczane przez SoC. Zazwyczaj dostawca SoC jest właścicielem obrazu dostawcy, podczas gdy producent urządzenia jest właścicielem obrazu ODM. Jeśli nie ma oddzielnej partycji /odm , obrazy dostawcy SoC i ODM są scalane w partycji /vendor .

Interfejsy między obrazami

W SSI istnieją dwa główne interfejsy dla obrazów dostawców i produktów:

  • Interfejs dostawcy (VINTF) : VINTF to interfejs do komponentów znajdujących się w obrazach dostawcy i ODM. Komponenty w obrazach produktów i systemów mogą wchodzić w interakcję z obrazami dostawcy i ODM wyłącznie za pośrednictwem tego interfejsu. Na przykład obraz dostawcy nie może zależeć od prywatnej części obrazu systemu i odwrotnie. Jest to oryginalnie zdefiniowane w Project Treble, który dzieli obrazy na partycje systemowe i dostawcy. Interfejs opisany jest za pomocą następujących mechanizmów:

    • HIDL (Przejście HAL jest dostępne tylko dla modułów system i system_ext )
    • Stabilny AIDL
    • Konfiguracje
      • API właściwości systemu
      • Interfejs API schematu pliku konfiguracyjnego
    • VNDK
    • Interfejsy API SDK systemu Android
    • Biblioteka SDK Java
  • Interfejsy produktu : Interfejs produktu to interfejs pomiędzy SSI a obrazem produktu. Zdefiniowanie stabilnego interfejsu oddziela komponenty produktu od komponentów systemu w SSI. Interfejs produktu wymaga tych samych stabilnych interfejsów co VINTF. Jednak w przypadku urządzeń uruchamianych z systemem Android 11 (i nowszym) wymuszane są tylko interfejsy API VNDK i Android SDK.

Włączanie SSI w Androidzie 11

W tej sekcji wyjaśniono, jak korzystać z nowych funkcji obsługujących SSI w systemie Android 11.

Partycja /system_ext

Partycja /system_ext została wprowadzona w systemie Android 11 jako partycja opcjonalna. (Jest to miejsce na komponenty inne niż AOSP, które są ściśle powiązane z komponentami zdefiniowanymi przez AOSP w partycji /system .) Zakłada się, że partycja /system_ext jest specyficznym dla OEM rozszerzeniem partycji /system , bez interfejsu zdefiniowanego pomiędzy dwie partycje. Komponenty w partycji /system_ext mogą wykonywać prywatne wywołania API do partycji /system , a komponenty w partycji /system mogą wykonywać prywatne wywołania API do partycji /system_ext .

Ponieważ obie partycje są ze sobą ściśle powiązane, obie partycje są aktualizowane razem po wydaniu nowej wersji systemu Android. Partycja /system_ext utworzona dla poprzedniej wersji Androida nie musi być kompatybilna z partycją /system w następnej wersji Androida.

Aby zainstalować moduł na partycji /system_ext , dodaj system_ext_specific: true do pliku Android.bp . W przypadku urządzeń, które nie mają partycji /system_ext , zainstaluj takie moduły w podkatalogu ./system_ext na partycji /system .

Historia

Oto historia partycji /system_ext . Celem projektu było umieszczenie wszystkich komponentów specyficznych dla OEM, niezależnie od tego, czy są wspólne, w partycji /product . Jednak przeniesienie ich wszystkich na raz nie było wykonalne, zwłaszcza gdy niektóre komponenty były ściśle powiązane z partycją /system . Aby przenieść ściśle powiązany komponent do partycji /product , interfejs produktu musi zostać rozszerzony. Często wymagało to gruntownej refaktoryzacji samego komponentu, co pochłaniało dużo czasu i wysiłku. Partycja /system_ext została uruchomiona jako miejsce tymczasowego przechowywania komponentów, które nie są gotowe do przeniesienia na partycję /product . Celem SSI było ostateczne wyeliminowanie partycji /system_ext .

Jednakże partycja /system_ext jest przydatna do utrzymywania partycji /system jak najbliżej AOSP. W przypadku SSI większość wysiłku związanego z aktualizacją jest poświęcana na komponenty w partycjach /system i /system_ext . Kiedy obraz systemu jest zbudowany ze źródeł możliwie najbardziej podobnych do tych w AOSP, można skoncentrować wysiłki związane z aktualizacją na obrazie system_ext .

Rozdzielenie komponentów z /system i /system_ext do partycji /product

W systemie Android 9 wprowadzono partycję /product połączoną z partycją /system . Moduły w partycji /product wykorzystują zasoby systemowe bez żadnych ograniczeń i odwrotnie. Aby umożliwić obsługę SSI w systemie Android 10, komponenty produktu zostały podzielone na partycje /system_ext i /product . Partycja /system_ext nie musi spełniać ograniczeń w korzystaniu z komponentów systemu, jakie spełniała partycja /product w systemie Android 9. Począwszy od systemu Android 10, partycja /product musi być oddzielona od partycji /system i musi korzystać ze stabilnych interfejsów z partycje /system i /system_ext .

Głównym celem partycji /system_ext jest rozszerzenie funkcji systemu, a nie instalowanie dołączonych modułów produktu, jak opisano w sekcji /system_ext partition . Aby to zrobić, rozłącz moduły specyficzne dla produktu i przenieś je do partycji /product . Rozdzielenie modułów specyficznych dla produktu sprawia, że /system_ext jest wspólny dla urządzeń. (Aby uzyskać więcej szczegółów, zobacz Tworzenie wspólnej partycji /system_ext .)

Aby oddzielić partycję /product od komponentów systemu, partycja /product musi mieć takie same zasady egzekwowania, jak partycja /vendor , która została już oddzielona od Project Treble.

Począwszy od systemu Android 11, interfejsy natywne i Java dla partycji /product są wymuszane w sposób opisany poniżej. Więcej informacji można znaleźć w sekcji Wymuszanie interfejsów partycjonowania produktu .

  • Interfejsy natywne : moduły natywne w partycji /product muszą zostać oddzielone od innych partycji. Jedynymi dozwolonymi zależnościami z modułów produktu są niektóre biblioteki VNDK (w tym LLNDK) z partycji /system . Biblioteki JNI, od których zależą aplikacje produktu, muszą być bibliotekami NDK.
  • Interfejsy Java : Moduły Java (aplikacja) w partycji /product nie mogą używać ukrytych interfejsów API, ponieważ są niestabilne. Moduły te mogą korzystać wyłącznie z publicznych i systemowych interfejsów API z partycji /system oraz bibliotek Java SDK z partycji /system lub /system_ext . Można zdefiniować biblioteki Java SDK dla niestandardowych interfejsów API.

Sugerowane kroki dla SSI opartego na GSI

Suggested partitions for GSI-based SSI

Rysunek 2. Sugerowane partycje dla SSI opartego na GSI

Ogólny obraz systemu (GSI) to obraz systemu zbudowany bezpośrednio z AOSP. Służy do testów zgodności Treble (na przykład CTS-on-GSI) i jako platforma referencyjna, z której twórcy aplikacji mogą korzystać do testowania zgodności swoich aplikacji, gdy nie mają prawdziwego urządzenia z wymaganą wersją Androida.

Producenci OEM mogą również używać GSI do tworzenia swoich SSI. Jak wyjaśniono w Obrazy i partycje , SSI składa się z obrazu systemu dla komponentów zdefiniowanych przez AOSP i obrazu system_ext dla komponentów zdefiniowanych przez OEM. Gdy jako obraz system używany jest GSI, producent OEM może skupić się na obrazie system_ext podczas aktualizacji.

Ta sekcja zawiera przewodnik dla producentów OEM, którzy chcą modularyzować swoje dostosowania w partycjach /system_ext i /product podczas korzystania z obrazu systemu AOSP lub bliskiego AOSP. Jeśli producenci OEM tworzą obraz systemu ze źródeł AOSP, mogą zastąpić utworzony przez siebie obraz systemu GSI dostarczonym przez AOSP. Jednak producenci OEM nie muszą od razu przechodzić do ostatniego etapu (używając GSI w obecnej postaci).

Krok 1. Dziedziczenie pliku Generic_system.mk dla obrazu systemu OEM (OEM GSI)

Dziedzicząc plik generic_system.mk (który w Androidzie 11 nosił nazwę mainline_system.mk i został przemianowany na generic_system.mk w AOSP), obraz systemu (OEM GSI) zawiera wszystkie pliki, które posiada AOSP GSI. Pliki te mogą być modyfikowane przez producentów OEM, tak aby OEM GSI mógł zawierać zastrzeżone pliki OEM oprócz plików AOSP GSI. Jednakże producenci OEM nie mogą modyfikować samego generic_system.mk .

Inheriting `generic_system.mk` for OEM system image

Rysunek 3. Dziedziczenie pliku generic_system.mk dla obrazu systemu OEM

Krok 2. Spraw, aby OEM GSI miał tę samą listę plików co AOSP GSI

Na tym etapie OEM GSI nie może mieć dodatkowych plików. Zastrzeżone pliki producenta OEM należy przenieść do partycji system_ext lub partycji product .

Moving added files out of the OEM GSI

Rysunek 4. Przenoszenie dodanych plików z OEM GSI

Krok 3. Zdefiniowanie listy dozwolonych w celu ograniczenia modyfikowanych plików w GSI OEM

Aby sprawdzić zmodyfikowane pliki, producenci OEM mogą skorzystać z narzędzia compare_images i porównać GSI AOSP z GSI OEM. Uzyskaj GSI AOSP z docelowego lunchu AOSP generic_system_* .

Uruchamiając okresowo narzędzie compare_images z allowlist , możesz monitorować różnice poza listą dozwolonych. Zapobiega to konieczności dodatkowych modyfikacji GSI OEM.

Define an allowlist to reduce the list of modified files in OEM GSI

Rysunek 5. Zdefiniuj listę dozwolonych, aby zmniejszyć listę zmodyfikowanych plików w GSI OEM

Krok 4. Spraw, aby OEM GSI miał te same pliki binarne, co AOSP GSI

Oczyszczenie listy dozwolonych umożliwia producentom OEM używanie AOSP GSI jako obrazu systemu dla własnych produktów. Aby wyczyścić listę dozwolonych, producenci OEM mogą albo porzucić zmiany w OEM GSI, albo przesłać swoje zmiany do AOSP, tak aby AOSP GSI uwzględnił ich zmiany.

Make OEM GSI have the same binaries as AOSP GSI

Rysunek 6. Tworzenie OEM GSI z tymi samymi plikami binarnymi, co AOSP GSI

Definiowanie SSI dla producentów OEM

Chroń partycję /system w czasie kompilacji

Aby uniknąć zmian specyficznych dla produktu w partycji /system i zdefiniować GSI OEM, producenci OEM mogą użyć makra pliku makefile o nazwie require-artifacts-in-path aby zapobiec deklaracji modułów systemowych po wywołaniu makra. Zobacz przykład tworzenia pliku makefile i włączania sprawdzania ścieżki artefaktów .

Producenci OEM mogą zdefiniować listę umożliwiającą tymczasową instalację modułów specyficznych dla produktu na partycji /system . Jednakże lista musi być pusta, aby GSI OEM był wspólny dla wszystkich produktów OEM. Proces ten służy do definiowania GSI OEM i może być niezależny od etapów tworzenia GSI AOSP .

Egzekwuj interfejsy produktów

Aby zagwarantować, że partycja /product jest rozdzielona, ​​producenci OEM mogą zapewnić, że ich urządzenia wymuszają interfejsy produktu, ustawiając PRODUCT_PRODUCT_VNDK_VERSION:= current dla modułów natywnych i PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE:= true dla modułów Java. Zmienne te są ustawiane automatycznie, jeśli PRODUCT_SHIPPING_API_LEVEL urządzenia jest większy lub równy 30 . Aby uzyskać szczegółowe informacje, zobacz sekcję Wymuszanie interfejsów partycjonowania produktu .

Ujednolicanie partycji /system_ext

Partycja /system_ext może różnić się w zależności od urządzenia, ponieważ może zawierać moduły specyficzne dla urządzenia i dołączone do systemu. Ponieważ SSI składa się z partycji /system i /system_ext , różnice w partycji /system_ext utrudniają producentom OEM zdefiniowanie SSI. Producenci OEM mogą mieć własne SSI i udostępniać je wielu urządzeniom, usuwając wszelkie różnice i czyniąc partycję /system_ext wspólną.

W tej sekcji znajdują się zalecenia dotyczące wspólnego tworzenia partycji /system_ext .

Ujawnij ukryte interfejsy API na partycji systemowej

Wielu aplikacji specyficznych dla produktu nie można zainstalować na partycji produktu, ponieważ korzystają one z ukrytych interfejsów API, które są zabronione na partycji produktu. Aby przenieść aplikacje specyficzne dla urządzenia na partycję produktu, usuń użycie ukrytych interfejsów API.

Preferowanym sposobem usuwania ukrytych interfejsów API z aplikacji jest znalezienie alternatywnych publicznych lub systemowych interfejsów API w celu ich zastąpienia. Jeśli nie ma interfejsów API zastępujących ukryte interfejsy API, producenci OEM mogą wnieść wkład do AOSP w celu zdefiniowania nowych systemowych interfejsów API dla swoich urządzeń.

Alternatywnie producenci OEM mogą definiować niestandardowe interfejsy API, tworząc własną bibliotekę Java SDK na partycji /system_ext . Może używać ukrytych interfejsów API w partycji systemowej i może udostępniać interfejsy API aplikacjom w partycji produktu lub dostawcy. Producenci OEM muszą zamrozić interfejsy API przeznaczone dla produktu, aby zapewnić kompatybilność wsteczną.

Uwzględnij nadzbiór wszystkich plików APK i pomiń instalację niektórych pakietów dla każdego urządzenia

Niektóre pakiety dołączone do systemu nie są wspólne dla różnych urządzeń. Rozdzielenie tych modułów APK w celu przeniesienia ich do produktu lub partycji dostawcy może być trudne. Jako rozwiązanie tymczasowe, producenci OEM mogą włączyć SSI do wszystkich modułów, a następnie odfiltrować niechciane przy użyciu właściwości SKU ( ro.boot.hardware.sku ). Aby użyć filtra, producenci OEM nakładają zasoby platformy config_disableApkUnlessMatchedSku_skus_list i config_disableApksUnlessMatchedSku_apk_list .

Aby uzyskać bardziej precyzyjne ustawienia, zadeklaruj odbiornik rozgłoszeniowy, który wyłącza niepotrzebne pakiety. Odbiornik transmisji wywołuje setApplicationEnabledSetting , aby wyłączyć pakiet po odebraniu komunikatu ACTION_BOOT_COMPLETED .

Zdefiniuj RRO zamiast używać statycznej nakładki zasobów

Nakładka zasobów statycznych manipuluje nałożonymi pakietami. Może to jednak utrudniać zdefiniowanie SSI, dlatego należy upewnić się, że właściwości RRO są włączone i prawidłowo ustawione. Ustawiając właściwości w następujący sposób, producenci OEM mogą mieć wszystkie automatycznie wygenerowane nakładki jako RRO.

PRODUCT_ENFORCE_RRO_TARGETS := *
PRODUCT_ENFORCE_RRO_EXCLUDED_OVERLAYS := # leave it empty

Jeśli wymagana jest szczegółowa konfiguracja, zdefiniuj RRO ręcznie, zamiast polegać na automatycznie wygenerowanym. Aby uzyskać szczegółowe informacje, zobacz Nakładki zasobów środowiska wykonawczego (RRO) . Producenci OEM mogą również definiować warunkowe RRO zależne od właściwości systemu, używając atrybutów android:requiredSystemPropertyName i android:requiredSystemPropertyValue .

Często zadawane pytania (FAQ)

Czy mogę zdefiniować wiele SSI?

Zależy to od powszechności i charakterystyki urządzeń (lub grupy urządzeń). Producenci OEM mogą próbować ustawić partycję system_ext jako wspólną, jak opisano w sekcji Tworzenie wspólnej partycji system_ext . Jeśli grupa urządzeń ma wiele różnic, lepiej zdefiniować wiele SSI.

Czy mogę zmodyfikować generic_system.mk ( mainline_system.mk ) dla GSI OEM?

Nie. Jednak producenci OEM mogą zdefiniować nowy plik makefile dla GSI OEM, który dziedziczy plik generic_system.mk i zamiast tego używać nowego pliku makefile. Przykład można znaleźć w sekcji Wymuszanie interfejsów partycjonowania produktu .

Czy mogę usunąć moduły z generic_system.mk , które kolidują z moją implementacją?

Nie. GSI posiada minimalny zestaw modułów startowych i testowalnych. Jeśli uważasz, że moduł nie jest niezbędny, zgłoś błąd, aby zaktualizować plik generic_system.mk w AOSP.