Na tej stronie przedstawiamy kilka mechanizmów, których OEM-y urządzeń z Androidem mogą używać do udostępniania własnego obrazu systemu (SSI) w różnych liniach produktów. Proponuje też procedurę tworzenia SSI należącego do OEM-a na podstawie ogólnego obrazu systemu (GSI) utworzonego na podstawie AOSP.
Tło
W ramach Project Treble monolityczny Android został podzielony na 2 części: część związaną ze sprzętem (implementację przez dostawcę) i część ogólną systemu operacyjnego (ramy systemu operacyjnego Android). Oprogramowanie dla każdego z nich jest instalowane na osobnej partycji: partycji dostawcy dla oprogramowania związanego ze sprzętem i partycji systemowej dla ogólnego oprogramowania systemu operacyjnego. Na obu partycjach zdefiniowano i wdrożony jest interfejs z wersją, zwany interfejsem dostawcy (VINTF). Za pomocą tego systemu partycjonowania możesz modyfikować partycję systemową bez modyfikowania partycji dostawcy i odwrotnie.
Motywacja
Kod platformy wydany w AOSP jest zgodny z architekturą Treble i zachował zgodność wsteczną ze starszymi implementacjami dostawców. Na przykład ogólny obraz systemu utworzony na podstawie źródeł AOSP Androida 10 może działać na dowolnym urządzeniu zgodnym z Treble, które korzysta z Androida 8 lub nowszego. Wersja Androida dostarczana na urządzeniach konsumenckich jest modyfikowana przez dostawców SoC i OEM-ów. (Przeczytaj artykuł Data opublikowania wersji Androida). Te zmiany i rozszerzenia w ramach nie były napisane w celu zachowania zgodności wstecznej, co oznaczało większą złożoność i wyższe koszty uaktualnienia systemu operacyjnego. Zmiany i modyfikacje dotyczące konkretnych urządzeń zwiększają koszty i złożoność aktualizacji wersji systemu Android.
Przed Androidem 11 nie było jasnej architektury, która umożliwiałaby partnerom tworzenie rozszerzeń modułowych do frameworku systemu operacyjnego Android. W tym dokumencie opisano czynności, które dostawcy SoC i OEM mogą wykonać, aby utworzyć SSI. Oznacza to, że jeden obraz został utworzony na podstawie źródeł frameworku systemu operacyjnego Android w celu ponownego użycia na wielu urządzeniach, zachowania wstecznej zgodności z implementacjami dostawców oraz znacznego zmniejszenia złożoności i kosztów aktualizacji systemu operacyjnego Android. Szczegółowe instrukcje tworzenia SSI znajdziesz w sekcji Sugestie dotyczące tworzenia SSI na podstawie GSI. Pamiętaj, że nie musisz wykonywać wszystkich 4 czynności. Wybór kroków (np. tylko krok 1) zależy od implementacji.
Omówienie SSI
W przypadku SSI komponenty oprogramowania związane z konkretnymi produktami i rozszerzenia OEM są umieszczane w nowej partycji /product
. Komponenty w partycji /product
korzystają z dobrze zdefiniowanego, stabilnego interfejsu do interakcji z komponentami w partycji /system
. Producenci OEM mogą utworzyć 1 SSI lub niewielką liczbę SSI do użycia na różnych urządzeniach. Po opublikowaniu nowej wersji systemu operacyjnego Android producent OEM inwestuje tylko raz w aktualizację swoich SSI do najnowszej wersji Androida. Mogą one ponownie używać SSI do aktualizowania wielu urządzeń bez
aktualizowania partycji /product
.
Pamiętaj, że producenci OEM i producenci systemów SoC tworzą SSI, które obejmują wszystkie funkcje i modyfikacje wymagane przez producenta OEM. Mechanizmy i sprawdzone metody przedstawione na tej stronie są przeznaczone dla producentów OEM w celu osiągnięcia tych kluczowych celów:
- Używanie SSI na wielu urządzeniach z użyciem różnych kodów SKU.
- Aktualizuj system Android za pomocą modułowych rozszerzeń, aby ułatwić modernizację systemu operacyjnego.
Podstawowa koncepcja rozdzielenia komponentów specyficznych dla produktu w partycję produktu jest podobna do koncepcji Treble, polegającej na rozdzieleniu komponentów specyficznych dla oprogramowania SoC w partycję dostawcy. Interfejs usługi (podobny do VINTF) umożliwia komunikację między SSI a partycją usługi. Pamiętaj, że w przypadku SSI termin „component” (składnik) odnosi się do wszystkich zasobów, plików binarnych, tekstów, bibliotek itp., które są instalowane w obrazach i które w podstawie stają się partycjami.
Partycje wokół SSI
Rysunek 1 przedstawia partycje wokół SSI oraz różne wersje interfejsów między partycjami i zasadami w interfejsach. W tej sekcji znajdziesz szczegółowe informacje o poszczególnych partycjach i interfejsach.
Rysunek 1. Partycje i interfejsy związane z SSI
Obrazy i partycje
Informacje w tej sekcji pozwalają rozróżnić terminy image (obraz) i partition (partia).
- Obraz to element koncepcyjny oprogramowania, który można aktualizować niezależnie.
- Partia to fizyczna lokalizacja pamięci masowej, która może być aktualizowana niezależnie.
Sekcje na rysunku 1 są zdefiniowane w następujący sposób:
SSI: SSI to obraz wspólny dla OEM, który może występować na wielu urządzeniach. Nie zawiera elementów sprzętowych ani produktów. Zgodnie z definicją wszystkie elementy w danym SSI są udostępniane wszystkim urządzeniom, które korzystają z tego SSI. SSI składa się z jednego obrazu
/system
lub z partycji/system
i/system_ext
, jak widać na rysunku 1.Partycja
/system
zawiera komponenty oparte na AOSP, natomiast po zaimplementowaniu/system_ext
zawiera rozszerzenia i komponenty OEM i SoC, które są ściśle powiązane z komponentami AOSP. Na przykład biblioteka OEM Java framework, która udostępnia niestandardowe interfejsy API dla własnych aplikacji OEM, lepiej pasuje do partycji/system_ext
niż/system
. Treści na partycjach/system
i/system_ext
są tworzone na podstawie źródeł Androida zmodyfikowanych przez OEM.Partycja
/system_ext
jest opcjonalna, ale warto jej używać w przypadku niestandardowych funkcji i rozszerzeń, które są ściśle powiązane ze składnikami opartymi na AOSP. Ta różnica pomoże Ci określić, jakie zmiany należy wprowadzić, aby przenieść takie komponenty z partycji/system_ext
do partycji/product
w danym czasie.
Produkt: zbiór komponentów związanych z konkretnym produktem lub urządzeniem, które reprezentują modyfikacje OEM i rozszerzenia do systemu operacyjnego Android. Umieść komponenty związane z procesorem SoC na partycji
/vendor
. Dostawcy układów SOC mogą też używać partycji/product
na potrzeby odpowiednich komponentów, np. komponentów niezależnych od SOC. Jeśli na przykład dostawca układów SoC udostępnia klientom OEM komponenty niezależne od SoC (które mogą być opcjonalnie dostarczane z produktem), może umieścić te komponenty na zdjęciu produktu. Lokalizacja komponentu nie jest określana przez właściciela, ale przez jego przeznaczenie.Dostawca: zbiór komponentów związanych z procesorem SoC.
ODM: zbiór komponentów związanych z płytką, których nie dostarcza układ SoC. Zwykle właścicielem obrazu ODM jest dostawca układu SOC. Zwykle właścicielem obrazu ODM jest producent urządzenia. Jeśli nie ma osobnej partycji
/odm
, obrazy dostawcy SoC i ODM są łączone w partycji/vendor
.
Interfejsy między obrazami
W ramach SSI istnieją 2 główne interfejsy do obsługi obrazów sprzedawców i produktów:
Interfejs dostawcy (VINTF): VINTF to interfejs komponentów znajdujących się w obrazach dostawcy i ODM. Komponenty w obrazach produktu i systemu mogą wchodzić w interakcje z obrazami dostawcy i ODM tylko za pomocą tego interfejsu. Na przykład obraz dostawcy nie może zależeć od prywatnej części obrazu systemu i odwrotnie. Zostało to zdefiniowane w projekcie Treble, który dzieli obrazy na partycje systemu i dostawcy. Interfejs jest opisywany za pomocą tych mechanizmów:
- HIDL (przesyłający interfejs HAL jest dostępny tylko w przypadku modułów
system
isystem_ext
) - Stabilna wersja AIDL
- Konfiguracje
- Interfejs API Właściwości systemowe
- Interfejs API schematu pliku konfiguracyjnego
- VNDK
- Interfejsy API pakietu Android SDK
- Biblioteka Java SDK
- HIDL (przesyłający interfejs HAL jest dostępny tylko w przypadku modułów
Interfejsy produktów: interfejs produktu to interfejs między SSI a zdjęciem produktu. Definiowanie stabilnego interfejsu pozwala oddzielić komponenty produktu od komponentów systemu w SSI. Interfejs usługi wymaga tych samych stabilnych interfejsów co VINTF. Jednak w przypadku urządzeń z Androidem 11 (lub nowszym) wymuszane są tylko interfejsy API VNDK i Android SDK.
Włączanie SSI w Androidzie 11
W tej sekcji opisano, jak korzystać z nowych funkcji, które obsługują SSI w Androidzie 11.
partycji /system_ext,
Partycja /system_ext
została wprowadzona w Androidzie 11 jako opcjonalna partycja. (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 rozszerzeniem partycji /system
, które jest specyficzne dla OEM-a i nie ma interfejsu zdefiniowanego na poziomie obu partycji. Komponenty w partycji /system_ext
mogą wykonywać prywatne wywołania interfejsu API w partycji /system
, a komponenty w partycji /system
mogą wykonywać prywatne wywołania interfejsu API w partycji /system_ext
.
Te 2 partycje są ze sobą ściśle powiązane, więc gdy zostanie wydana nowa wersja Androida, obie są aktualizowane jednocześnie. Partycja /system_ext
utworzona dla poprzedniej wersji Androida nie musi być zgodna 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
, instaluj 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-ów, niezależnie od tego, czy są one wspólne, w partycji /product
. Przenoszenie ich wszystkich naraz nie było jednak możliwe,
zwłaszcza że niektóre komponenty były ściśle powiązane z partycją /system
. Aby przenieść ściśle powiązany komponent na partycję /product
, interfejs usługi musi być rozszerzony. Często wymagało to gruntownej refaktoryzacji samego komponentu, co pochłaniało dużo czasu i wysiłku. Partycja /system_ext
była początkowo miejscem tymczasowego przechowywania komponentów, które nie były jeszcze gotowe do przeniesienia do partycji /product
. Celem SSI było wyeliminowanie partycji /system_ext
.
Jednak partycja /system_ext
przydaje się do utrzymania partycji /system
jak najbliżej AOSP. W przypadku SSI większość działań związanych z uaktualnieniem jest wykonywana na komponentach w partycjach /system
i /system_ext
.
Gdy obraz systemu jest tworzony ze źródeł, które są jak najbardziej zbliżone do tych w AOSP, możesz skupić się na uaktualnianiu obrazu system_ext
.
Przeniesienie komponentów z partycji /system i /system_ext do partycji /product
Android 9 wprowadził partycję /product
, która jest połączona z partycją /system
. Moduł na partycji /product
korzysta z zasobów systemu bez żadnych ograniczeń i na odwrót. Aby umożliwić SSI w Androidzie 10, komponenty usługi są dzielone na partycje /system_ext
i /product
. Partycja /system_ext
nie musi przestrzegać ograniczeń dotyczących korzystania z komponentów systemu, które obowiązywały w partycji /product
w Androidzie 9. Od Androida 10 partycja /product
musi być odseparowana od partycji /system
i wykorzystywać stabilne interfejsy z partycji /system
i /system_ext
.
Głównym celem partycji /system_ext
jest rozszerzanie funkcji systemu, a nie instalowanie modułów pakietów, jak opisano w sekcji /system_ext partition
. Aby to zrobić, odłącz moduły dotyczące poszczególnych produktów i przenieś je do partycji /product
.
Wyodrębnienie modułów związanych z poszczególnymi usługami powoduje, że /system_ext
jest wspólne dla wszystkich urządzeń. (więcej informacji znajdziesz w artykule Uzyskiwanie dostępu do partycji /system_ext).
Aby odseparować partycję /product
od komponentów systemu, partycja /product
musi mieć te same zasady egzekwowania, co partycja /vendor
, która została już odseparowana w ramach projektu Treble.
Od wersji Androida 11 interfejsy natywne i interfejsy Java dla partycji /product
są egzekwowane w sposób opisany poniżej. Więcej informacji znajdziesz w artykule Egzekwowanie interfejsów partycjonowania usług.
- Natywna obsługa interfejsów: natywne moduły w partycji
/product
muszą być odseparowane od innych partycji. Jedynymi dozwolonymi zależnościami z modułów usługi są niektóre biblioteki VNDK (w tym LLNDK) z partycji/system
. Biblioteki JNI, od których zależą aplikacje usług, muszą być bibliotekami NDK. - Interfejsy Java: moduły Java (aplikacji) w partycji
/product
nie mogą używać ukrytych interfejsów API, ponieważ są one niestabilne. Muszą one używać tylko publicznych interfejsów API i interfejsów API systemowych z partycji/system
oraz bibliotek pakietu SDK Java w partycji/system
lub/system_ext
. Możesz zdefiniować biblioteki pakietu SDK Java na potrzeby niestandardowych interfejsów API.
Sugerowane kroki w przypadku SSI opartego na GSI
Rysunek 2. Sugerowane partycje dla SSI opartego na GSI
Ogólny obraz systemu (GSI) to obraz systemu utworzony bezpośrednio z AOSP. Jest ona używana do testów zgodności Treble (np. CTS-on-GSI) i jako platforma referencyjna, której deweloperzy aplikacji mogą używać do testowania zgodności swoich aplikacji, gdy nie mają dostępu do prawdziwego urządzenia z wymaganym systemem Android.
OEM może też korzystać z GSI do utworzenia własnego wskaźnika SSI. Jak wyjaśniono w artykule Obrazy i partycje, SSI składa się z obrazu systemu dla komponentów zdefiniowanych przez AOSP oraz obrazu system_ext
dla komponentów zdefiniowanych przez OEM. Gdy GSI jest używany jako obraz system
, producent OEM może skupić się na obrazie system_ext
w celu uaktualnienia.
Ta sekcja jest przeznaczona dla producentów OEM, którzy chcą modułowo skonfigurować dostosowania w partycjach /system_ext
i /product
przy użyciu obrazu systemu AOSP lub bliskiego AOSP. Jeśli OEM-y tworzą obraz systemu na podstawie źródeł AOSP, mogą zastąpić utworzony przez siebie obraz systemu obrazem GSI udostępnianym przez AOSP. Producenci OEM nie muszą jednak od razu stosować ostatniego kroku (czyli GSI).
Krok 1. Dziedziczenie pliku generic_system.mk w przypadku obrazu systemu OEM (OEM GSI)
Dziedzicząc generic_system.mk
(który w Androidzie 11 miał nazwę mainline_system.mk
, a w AOSP został przemianowany na generic_system.mk
), obraz systemu (GSI OEM) zawiera wszystkie pliki, które ma obraz AOSP GSI.
Pliki te mogą być modyfikowane przez producentów OEM, tak aby oprócz plików GSI AOSP plik GSI OEM mógł zawierać zastrzeżone pliki OEM. Producenci OEM nie mogą jednak modyfikować samego pliku generic_system.mk
.
Rysunek 3. Dziedziczenie plikugeneral_system.mk w przypadku obrazu systemu OEM
Krok 2. Upewnij się, że GSI OEM ma tę samą listę plików co GSI AOSP.
Na tym etapie pliki OEM GSI nie mogą zawierać dodatkowych plików. Własne pliki OEM muszą zostać przeniesione na partycje system_ext
lub product
.
Rysunek 4. Przeniesienie dodanych plików z GSI OEM
Krok 3. Zdefiniuj listę dozwolonych, aby ograniczyć zmodyfikowane pliki w GSI OEM
Aby sprawdzić zmodyfikowane pliki, OEM może użyć narzędzia compare_images
i porównać GSI AOSP z GSI OEM. Pobierz plik GSI AOSP z adresu AOSP lunch target generic_system_*
.
Jeśli okresowo uruchamiasz narzędzie compare_images
z parametrem allowlist
, możesz sprawdzać różnice spoza listy dozwolonych. Dzięki temu nie trzeba wprowadzać dodatkowych modyfikacji w GSI OEM.
Rysunek 5. Zdefiniuj listę dozwolonych, aby ograniczyć zmodyfikowaną listę plików w GSI OEM
Krok 4. Upewnij się, że GSI OEM ma te same pliki binarne co GSI AOSP.
Oczyszczenie listy dozwolonych pozwala producentom OEM używać obrazu systemu AOSP GSI w swoich własnych produktach. Aby wyczyścić listę dozwolonych, OEM może zrezygnować ze zmian w GSI OEM lub przesłać zmiany do AOSP, aby uwzględnić je w AOSP GSI.
Rysunek 6. Upewnij się, że GSI OEM ma te same pliki binarne co GSI AOSP.
Definiowanie SSI dla OEM
Chroń partycję /system w momencie kompilacji
Aby uniknąć zmian w partycji /system
związanych z konkretnym produktem i zdefiniować GSI OEM, producenci OEM mogą użyć makra makefile o nazwie require-artifacts-in-path
, aby zapobiec deklaracji modułów systemowych po wywołaniu makra. Zapoznaj się z przykładem tworzenia pliku make i włączania sprawdzania ścieżki artefaktu.
OEM może określić listę zezwalającą na tymczasowe instalowanie modułów określonych produktów na partycji /system
. Lista musi być jednak pusta, aby GSI OEM była wspólna dla wszystkich produktów OEM. Ten proces służy do zdefiniowania GSI OEM i może być niezależny od kroków związanych z GSI AOSP.
Egzekwowanie interfejsów usług
Aby mieć pewność, że partycja /product
jest odłączona, OEM-y mogą zapewnić, że ich urządzenia będą egzekwować interfejsy produktów, ustawiając PRODUCT_PRODUCT_VNDK_VERSION:= current
w przypadku modułów natywnych i PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE:= true
w przypadku modułów Java. Te zmienne są ustawiane automatycznie, jeśli PRODUCT_SHIPPING_API_LEVEL
urządzenia jest równe lub większe od 30
. Szczegółowe informacje znajdziesz w artykule Wymuszanie stosowania interfejsów partycji produktów.
Utworzenie wspólnej partycji /system_ext
Partycja /system_ext
może się różnić na różnych urządzeniach, ponieważ może zawierać moduły systemowe przeznaczone dla konkretnego urządzenia. Ponieważ SSI składa się z partycji /system
i /system_ext
, różnice w partycji /system_ext
utrudniają OEM-om zdefiniowanie SSI. Producenci OEM mogą mieć własne SSI i udostępniać je na wielu urządzeniach, usuwając wszelkie różnice i czyniąc partycję /system_ext
wspólną.
W tej sekcji znajdziesz zalecenia dotyczące udostępniania partycji /system_ext
.
Wyświetlanie ukrytych interfejsów API na partycji systemowej
Wiele aplikacji związanych z poszczególnymi usługami nie może być zainstalowanych w partycji usługi, ponieważ korzystają z ukrytych interfejsów API, które są zabronione w tej partycji. Aby przenieść aplikacje na poziomie urządzenia na partycję usługi, usuń użycie ukrytych interfejsów API.
Najlepszym sposobem na usunięcie ukrytych interfejsów API z aplikacji jest znalezienie alternatywnych publicznych lub systemowych interfejsów API, które je zastąpią. Jeśli nie ma interfejsów API, które mogłyby zastąpić ukryte interfejsy API, producenci OEM mogą pomóc AOSP zdefiniować nowe systemowe interfejsy API dla swoich urządzeń.
Producenci OEM mogą też definiować niestandardowe interfejsy API, tworząc własną bibliotekę pakietu Java SDK na partycji /system_ext
. Może ona używać ukrytych interfejsów API w partycji systemowej oraz udostępniać interfejsy API aplikacjom w partycji produktu lub dostawcy.
Producenci OEM muszą zamrozić interfejsy API dla użytkowników w celu zapewnienia zgodności wstecznej.
Uwzględnij superzbiór wszystkich plików APK i pominij instalację niektórych pakietów na poszczególnych urządzeniach.
Niektóre pakiety, które są częścią systemu, nie są wspólne dla wszystkich urządzeń.
Rozpakowanie tych modułów APK w celu przeniesienia ich do partycji produktu lub dostawcy może być trudne. Jako tymczasowe rozwiązanie OEM mogą uwzględnić w SSI wszystkie moduły, a potem odfiltrować te, których nie chcą używać, za pomocą właściwości SKU (ro.boot.hardware.sku
). Aby użyć filtra, OEM mogą nałożyć zasoby frameworka config_disableApkUnlessMatchedSku_skus_list
i config_disableApksUnlessMatchedSku_apk_list
.
Aby uzyskać bardziej precyzyjne ustawienia, zadeklaruj odbiornik transmisji, który wyłącza niepotrzebne pakiety. Odbiornik transmisji wywołuje metodę setApplicationEnabledSetting
, aby wyłączyć pakiet po otrzymaniu wiadomości ACTION_BOOT_COMPLETED
.
Zamiast nakładania statycznych zasobów zdefiniuj RRO
Nakładka zasobu statycznego manipuluje nałożonymi pakietami. Może to jednak utrudnić definiowanie SSI, dlatego upewnij się, że właściwości RRO są włączone i prawidłowo skonfigurowane. Jeśli OEM ustawi te właściwości w ten sposób, wszystkie automatycznie generowane nakładki będą traktowane jako nakładki RRO.
PRODUCT_ENFORCE_RRO_TARGETS := *
PRODUCT_ENFORCE_RRO_EXCLUDED_OVERLAYS := # leave it empty
Jeśli wymagana jest szczegółowa konfiguracja, zamiast korzystać z automatycznie wygenerowanej konfiguracji, zdefiniuj je ręcznie. Szczegółowe informacje znajdziesz w artykule Nakładki zasobów środowiska wykonawczego (RRO).
Producenci OEM mogą też definiować RRO warunkowe, które zależą od właściwości systemu, za pomocą atrybutów android:requiredSystemPropertyName
i android:requiredSystemPropertyValue
.
Najczęstsze pytania
Czy mogę zdefiniować wiele SSI?
Zależy to od podobieństwa i charakterystyk urządzeń (lub grupy urządzeń).
Producenci OEM mogą spróbować utworzyć wspólną partycję system_ext
, jak opisano w artykule Tworzenie wspólnej partycji system_ext. Jeśli grupa urządzeń ma wiele różnic, lepiej zdefiniować kilka SSI.
Czy mogę zmodyfikować plik generic_system.mk (mainline_system.mk) w przypadku GSI OEM?
Nie. Producenci OEM mogą jednak zdefiniować nowy makefile dla GSI, który dziedziczy plik generic_system.mk
i zamiast niego używa nowego makefile. Odpowiedni przykład znajdziesz w artykule Wymuszanie stosowania interfejsów partycji produktu.
Czy mogę usunąć z pliku generic_system.mk moduły, które są w konflikcie z moją implementacją?
Nie. GSI ma minimalny zestaw uruchamialnych i testowalnych modułów. Jeśli uważasz, że dany moduł nie jest niezbędny, prześlij zgłoszenie błędu, aby zaktualizować plik generic_system.mk
w AOSP.