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 obrazu SSI należącego do OEM-a na podstawie ogólnego obrazu systemu (GSI) utworzonego na podstawie AOSP.
Tło
W ramach projektu 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 wymógnięto interfejs z wersją, zwany interfejsem dostawcy (VINTF). Dzięki temu systemowi partycjonowania możesz modyfikować partycję systemową bez modyfikowania partycji dostawcy i odwrotnie.
Motywacja
Kod frameworku opublikowany w AOSP jest zgodny z architekturą Treble i zachowuje 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. (zobacz Cykl życia wersji Androida). Te zmiany i rozszerzenia w ramach nie były napisane w celu zachowania zgodności wstecznej, co przełożyło się na 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 układów SoC i producenci OEM mogą wykonać, aby utworzyć SSI. Oznacza to jeden obraz utworzony na podstawie źródeł frameworku systemu operacyjnego Androida, który można ponownie wykorzystać na wielu urządzeniach, aby zachować zgodność wsteczną z implementacjami dostawców i znacznie zmniejszyć złożoność i koszt aktualizacji systemu operacyjnego Androida. Szczegółowe instrukcje tworzenia SSI znajdziesz w sekcji Sugerowane czynności związane z tworzeniem 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 ramach SSI komponenty oprogramowania związane z poszczególnymi 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. Gdy zostanie wydana nowa wersja systemu operacyjnego Android, producenci OEM tylko raz muszą zaktualizować swoje 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 zawierają wszystkie funkcje i modyfikacje niestandardowe, których potrzebuje producent OEM. Mechanizmy i sprawdzone metody opisane na tej stronie są przeznaczone dla producentów OEM i mają im pomóc w osiągnięciu tych kluczowych celów:
- Używanie SSI na wielu SKU urządzeń.
- Aktualizuj system Android za pomocą modułowych rozszerzeń, aby ułatwić aktualizację systemu operacyjnego.
Podstawowa koncepcja oddzielania komponentów związanych z poszczególnymi produktami w ramach partycji produktu jest podobna do koncepcji Treble polegającej na oddzielaniu komponentów związanych z poszczególnymi SoC w ramach partycji 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 interfejsy z wersjami w różnych partycjach i zasady dotyczące interfejsów. W tej sekcji szczegółowo omawiamy poszczególne partycje i interfejsy.
Rysunek 1. Partycje i interfejsy dotyczące SSI
Obrazy i partycje
Informacje w tej sekcji odróżniają terminy image (obraz) i partition (partycja).
- Obraz to element koncepcyjny oprogramowania, który można aktualizować niezależnie.
- Partycja to fizyczna lokalizacja pamięci, którą można aktualizować 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 żadnych komponentów związanych ze sprzętem ani produktem. Zgodnie z definicją wszystkie elementy w danym SSI są udostępniane wszystkim urządzeniom, które go używają. 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, a partycja/system_ext
, jeśli jest zaimplementowana, zawiera rozszerzenia i komponenty dostawców OEM i układów 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 danym produktem lub urządzeniem, które reprezentują funkcje i rozszerzenia OEM w systemie Android. Umieść komponenty związane z procesorem SoC na partycji
/vendor
. Dostawcy SoC mogą też używać partycji/product
do odpowiednich komponentów, takich jak komponenty niezależne od SoC. Jeśli na przykład dostawca układów SoC udostępnia klientom OEM komponenty niezależne od SoC (które można opcjonalnie dołączyć do produktu), 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óre nie są dostarczane przez SoC. Zazwyczaj właścicielem obrazu dostawcy jest dostawca SoC, a 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. Jest to pierwotnie zdefiniowane w ramach projektu Treble, który dzieli obrazy na partycje systemowe i partycje dostawców. 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 konfiguracji
- 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. Zdefiniowanie stabilnego interfejsu pozwala oddzielić komponenty produktu od komponentów systemu w SSI. Interfejs usługi wymaga tych samych stabilnych interfejsów co VINTF. Na urządzeniach z Androidem 11 (i nowszym) wymagane są jednak 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 potrzeby 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 kolejne 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-a, 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 do partycji /product
, należy rozszerzyć interfejs usługi. Często wymagało to gruntownej przebudowy samego komponentu, co pochłaniało dużo czasu i wysiłku. Partycja /system_ext
była początkowo miejscem tymczasowego przechowywania tych komponentów, które nie były jeszcze gotowe do przeniesienia do partycji /product
. Celem SSI było wyeliminowanie partycji /system_ext
.
Partycja /system_ext
jest jednak przydatna, ponieważ pozwala utrzymać partycję /system
w stanie jak najbardziej zbliżonym do AOSP. W przypadku SSI większość wysiłku związanego z aktualizacją jest poświęcana na komponenty 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ły w partycji
/product
korzystają 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. Począwszy od Androida 10 partycja /product
musi być odłączona od partycji /system
i musi używać stabilnych interfejsów 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 usług i przenieś je do partycji /product
.
Rozdzielenie 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.
Począwszy od Androida 11, natywne interfejsy i interfejsy w języku Java dla partycji /product
są wymuszane zgodnie z opisem 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.
Producenci OEM mogą też używać GSI do tworzenia 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 zawiera przewodnik dla producentów OEM, którzy chcą podzielić swoje modyfikacje na moduły w partycjach /system_ext
i /product
, korzystając z obrazu systemu AOSP lub zbliżonego do 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 osiągnąć ostatniego etapu (czyli stosować GSI w obecnej formie).
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 zawiera GSI AOSP.
Pliki te mogą być modyfikowane przez producentów OEM, więc pakiet GSI OEM może zawierać pliki firmowe producenta OEM oprócz plików GSI AOSP. Producenci OEM nie mogą jednak modyfikować samego pliku generic_system.mk
.
Rysunek 3. Dziedziczenie pliku generic_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. Przenoszenie 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. Określ listę dozwolonych, aby ograniczyć listę zmodyfikowanych 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, producenci OEM mogą zrezygnować ze zmian w GSI OEM lub przesłać zmiany do AOSP, aby uwzględnić je w AOSP GSI.
Rysunek 6. OEM GSI ma mieć te same pliki binarne co AOSP GSI
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.
Producenci OEM mogą zdefiniować listę, aby umożliwić tymczasowe instalowanie modułów związanych z poszczególnymi produktami 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 definiowania GSI dla OEM-ów i może być niezależny od procedury GSI dla AOSP.
Wymuszanie 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 interfejsów interfejsów partycji produktu.
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ć instalowanych 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ą przyczynić się do utworzenia nowych interfejsów API systemu dla swoich urządzeń.
Producenci OEM mogą też definiować niestandardowe interfejsy API, tworząc własne biblioteki 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 superset wszystkich plików APK i pomiń 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ą nakładać zasoby frameworka 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 rozgłoszeniowy wywołuje funkcję setApplicationEnabledSetting
, aby wyłączyć pakiet, gdy otrzyma wiadomość ACTION_BOOT_COMPLETED
.
Zamiast nakładania statycznych zasobów zdefiniuj RRO
Nakładka statycznego zasobu manipuluje nałożonymi pakietami. Może to jednak utrudniać 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 konfiguracji wygenerowanej automatycznie, zdefiniuj ją ręcznie. Szczegółowe informacje znajdziesz w artykule Nakładki zasobów w czasie wykonywania (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.