Na tej stronie przedstawiamy kilka mechanizmów, których producenci OEM urządzeń z Androidem mogą używać, aby mieć własny wspólny obraz systemu (SSI) w różnych liniach produktów. Proponuje też procedurę tworzenia obrazu SSI należącego do producenta OEM na podstawie podstawowego obrazu systemu (GSI) utworzonego w ramach AOSP.
Tło
W ramach Project Treble monolityczny Android został podzielony na 2 części: część specyficzną dla sprzętu (implementacja dostawcy) i ogólną część systemu operacyjnego (struktura systemu operacyjnego Android). Oprogramowanie każdego z nich jest instalowane na osobnej partycji: partycji dostawcy w przypadku oprogramowania specyficznego dla sprzętu i partycji systemowej w przypadku ogólnego oprogramowania systemu operacyjnego. W obu partycjach zdefiniowany i wymagany jest 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 platformy udostępniony 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 ma Androida 8 lub nowszego. Wersja Androida dostarczana na urządzenia konsumenckie jest modyfikowana przez dostawców układów SoC i producentów OEM. (Patrz Cykl życia wersji Androida). Te zmiany i rozszerzenia wprowadzone w ramach nie zostały opracowane z myślą o zachowaniu zgodności wstecznej, co przełożyło się na większą złożoność i wyższy koszt aktualizacji systemu operacyjnego. Zmiany i modyfikacje specyficzne dla urządzenia zwiększają koszt i złożoność aktualizacji wersji systemu Android.
Przed wprowadzeniem Androida 11 nie było jasnej architektury, która umożliwiałaby partnerom tworzenie modułowych rozszerzeń platformy systemu operacyjnego Android. W tym dokumencie opisujemy kroki, które dostawcy układów SOC i producenci OEM mogą wykonać, aby utworzyć SSI. Oznacza to, że jeden obraz, utworzony na podstawie źródeł platformy systemu Android do ponownego wykorzystania na wielu urządzeniach, w celu zachowania zgodności wstecznej z implementacjami dostawców i znacznego zmniejszenia złożoności i kosztów aktualizacji systemu Android. Szczegółowe instrukcje tworzenia SSI znajdziesz w sekcji Sugerowane kroki tworzenia SSI opartego na GSI. Pamiętaj, że nie musisz wykonywać wszystkich 4 kroków. Wybór kroków (np. tylko kroku 1) zależy od Twojej implementacji.
Omówienie SSI
W przypadku 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ą utworzyć jeden identyfikator SSI lub niewielką liczbę identyfikatorów SSI do użycia w przypadku wielu kodów SKU urządzeń. Gdy pojawi się nowa wersja systemu operacyjnego Android, producenci OEM tylko raz inwestują w aktualizację swoich interfejsów SSI do najnowszej wersji Androida. Mogą ponownie używać identyfikatorów SSI do aktualizowania wielu urządzeń bez aktualizowania partycji /product
.
Producenci OEM i dostawcy SoC tworzą SSI, które zawierają wszystkie funkcje niestandardowe i modyfikacje potrzebne producentowi OEM. Mechanizmy i sprawdzone metody podane na tej stronie są przeznaczone dla producentów OEM i mają im pomóc w osiągnięciu tych kluczowych celów:
- Ponowne wykorzystanie identyfikatora SSI na wielu SKU urządzeń.
- Aktualizowanie systemu Android za pomocą modułowych rozszerzeń, aby ułatwić aktualizacje systemu operacyjnego.
Podstawowa idea oddzielenia komponentów specyficznych dla produktu do partycji produktu jest podobna do idei Treble, która polega na oddzieleniu komponentów specyficznych dla SoC do partycji dostawcy. Interfejs produktu (podobny do VINTF) umożliwia komunikację między SSI a partycją produktu. Pamiętaj, że w przypadku SSI termin „komponenty” odnosi się do wszystkich zasobów, plików binarnych, tekstów, bibliotek itp. instalowanych w obrazach, które zasadniczo stają się partycjami.
Partycje wokół SSI
Ilustracja 1 przedstawia podziały wokół SSI oraz interfejsy z wersjami w różnych podziałach i zasady dotyczące interfejsów. W tej sekcji szczegółowo opisujemy poszczególne partycje i interfejsy.
Rysunek 1. Partycje i interfejsy związane z SSI
Obrazy i partycje
Informacje w tej sekcji rozróżniają terminy obraz i partycja.
- Obraz to koncepcyjny element 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 ten sposób:
SSI: SSI to obraz wspólny dla producenta OEM, który może występować na wielu urządzeniach. Nie zawiera żadnych komponentów specyficznych dla sprzętu ani produktu. Wszystkie informacje w danym SSI są z definicji udostępniane wszystkim urządzeniom korzystającym z tego SSI. SSI składa się z pojedynczego
/system
obrazu lub z/system
i/system_ext
partycji, jak widać na rysunku 1.Partycja
/system
zawiera komponenty oparte na AOSP, a/system_ext
(jeśli jest zaimplementowana) zawiera rozszerzenia i komponenty OEM i dostawców układów SoC, które są ściśle powiązane z komponentami AOSP. Na przykład biblioteka frameworka Java OEM, która udostępnia niestandardowe interfejsy API dla aplikacji OEM, lepiej pasuje do partycji/system_ext
niż do partycji/system
. Treści dla partycji/system
i/system_ext
są tworzone na podstawie zmodyfikowanych przez OEM źródeł Androida.Partycja
/system_ext
jest opcjonalna, ale warto jej używać w przypadku niestandardowych funkcji i rozszerzeń, które są ściśle powiązane z komponentami opartymi na AOSP. To rozróżnienie pomoże Ci określić, jakie zmiany musisz wprowadzić, aby z czasem przenieść takie komponenty z partycji/system_ext
do partycji/product
.
Produkt: zbiór komponentów specyficznych dla produktu lub urządzenia, które reprezentują dostosowania i rozszerzenia systemu operacyjnego Android wprowadzone przez producenta OEM. Umieść komponenty specyficzne dla SoC w partycji
/vendor
. Dostawcy SoC mogą też używać partycji/product
w przypadku odpowiednich komponentów, np. niezależnych od SoC. Na przykład jeśli dostawca układów SoC udostępnia niezależny od układu SoC komponent swoim klientom OEM (który można opcjonalnie dołączyć do produktu), może umieścić ten komponent na zdjęciu produktu. Lokalizacja komponentu nie jest określana przez jego własność, ale przez jego przeznaczenie.Dostawca: zbiór komponentów specyficznych dla SoC.
ODM: zbiór komponentów specyficznych dla płyty, które nie są dostarczane przez SoC. Zwykle obraz dostawcy jest własnością dostawcy SoC, a obraz ODM jest własnością producenta urządzenia. Jeśli nie ma osobnej partycji
/odm
, obrazy dostawcy układu SoC i ODM są łączone w partycji/vendor
.
Interfejsy między obrazami
Wokół SSI istnieją 2 główne interfejsy dla zdjęć dostawcó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 pierwotnie zdefiniowane w projekcie Treble, który podzielił obrazy na partycje systemowe i partycje dostawcy. Interfejs jest opisany za pomocą tych mechanizmów:
- HIDL (Passthrough HAL jest dostępny tylko w przypadku modułów
system
isystem_ext
) - Stabilny AIDL
- Konfiguracje
- Interfejs System Properties API
- Interfejs API schematu pliku konfiguracyjnego
- VNDK
- Interfejsy API pakietu SDK na Androida
- Biblioteka pakietu SDK w języku Java
- HIDL (Passthrough HAL jest dostępny tylko w przypadku modułów
Interfejsy produktu: interfejs produktu to interfejs między SSI a zdjęciem produktu. Zdefiniowanie stabilnego interfejsu oddziela komponenty produktu od komponentów systemu w ramach SSI. Interfejs produktu wymaga tych samych stabilnych interfejsów co VINTF. Jednak w przypadku urządzeń wprowadzonych na rynek z Androidem 11 (i nowszym) egzekwowane są tylko interfejsy API VNDK i Android SDK.
Włączanie SSI na urządzeniach z Androidem 11
W tej sekcji opisujemy, jak korzystać z nowych funkcji, które obsługują SSI na Androidzie 11.
Partycja /system_ext
Partycja /system_ext
została wprowadzona w Androidzie 11 jako opcjonalna. (Jest to miejsce na komponenty inne niż AOSP, które są ściśle powiązane z komponentami zdefiniowanymi w AOSP w /system
). Zakłada się, że partycja /system_ext
jest rozszerzeniem partycji /system
, które jest specyficzne dla producenta OEM, bez zdefiniowanego interfejsu między tymi 2 partycjami. Komponenty w /system_ext
mogą wykonywać prywatne wywołania interfejsu API do /system
, a komponenty w /system
mogą wykonywać prywatne wywołania interfejsu API do /system_ext
.
Ponieważ obie partycje są ze sobą ściśle powiązane, są one uaktualniane razem po wydaniu nowej wersji Androida. /system_ext
Partycja
utworzona dla poprzedniej wersji Androida nie musi być zgodna z /system
partycją w kolejnej wersji Androida.
Aby zainstalować moduł w 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 było umieszczenie wszystkich komponentów specyficznych dla producenta OEM, niezależnie od tego, czy są one powszechne, w partycji /product
. Jednak przeniesienie ich wszystkich naraz nie było możliwe, zwłaszcza że niektóre komponenty były ściśle powiązane z /system
partycją. Aby przenieść ściśle powiązany komponent do partycji /product
, należy rozszerzyć interfejs produktu. Często wymagało to gruntownego refaktoryzowania komponentu, co pochłaniało dużo czasu i wysiłku. Partycja
/system_ext
powstała jako miejsce tymczasowego przechowywania komponentów, które nie są jeszcze gotowe do przeniesienia do partycji /product
. Celem SSI było ostateczne wyeliminowanie partycji /system_ext
.
Partycja /system_ext
jest jednak przydatna, ponieważ pozwala utrzymać partycję /system
jak najbliżej AOSP. W przypadku SSI większość pracy związanej z aktualizacją dotyczy komponentów w partycjach /system
i /system_ext
.
Jeśli obraz systemu jest tworzony ze źródeł jak najbardziej podobnych do tych w AOSP, możesz skupić się na uaktualnieniu system_ext
obrazu.
Wyodrębnianie komponentów z partycji /system i /system_ext do partycji /product
W Androidzie 9 wprowadzono /product
partycję, która jest powiązana z partycją /system
. Moduły w partycji /product
korzystają z zasobów systemowych bez ograniczeń i na odwrót. Aby umożliwić SSI w Androidzie 10, komponenty produktu są podzielone 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 przypadku partycji /product
w Androidzie 9. Od Androida 10 partycja /product
musi być oddzielona od partycji /system
i musi korzystać ze stabilnych interfejsów z partycji /system
i /system_ext
.
Głównym celem partycji /system_ext
jest rozszerzanie funkcji systemu, a nie instalowanie modułów produktów w pakiecie, jak opisano w sekcji /system_ext partition
. Aby to zrobić, rozdziel moduły dotyczące konkretnych produktów i przenieś je do partycji /product
.
Rozdzielenie modułów specyficznych dla produktu sprawia, że /system_ext
jest wspólny dla urządzeń. (Więcej informacji znajdziesz w artykule Udostępnianie partycji /system_ext).
Aby oddzielić partycję /product
od komponentów systemu, musi ona mieć takie same zasady egzekwowania jak partycja /vendor
, która została już oddzielona w ramach Project Treble./product
Od Androida 11 interfejsy natywne i Java dla partycji /product
są wymuszane zgodnie z opisem poniżej. Więcej informacji znajdziesz w artykule Wymuszanie interfejsów podziału produktów.
- Interfejsy natywne: moduły natywne w partycji
/product
muszą być oddzielone od innych partycji. Jedynymi dozwolonymi zależnościami modułów produktów są niektóre biblioteki VNDK (w tym LLNDK) z/system
partycji. Biblioteki JNI, od których zależą aplikacje usługi, muszą być bibliotekami NDK. - Interfejsy Java: moduły Java (aplikacji) w
/product
partycji nie mogą używać ukrytych interfejsów API, ponieważ są one niestabilne. Te moduły mogą używać tylko publicznych interfejsów API i interfejsów API systemu z partycji/system
oraz bibliotek pakietu SDK Java z partycji/system
lub/system_ext
. Możesz zdefiniować biblioteki pakietu SDK Java dla niestandardowych interfejsów API.
Sugerowane kroki w przypadku SSI opartego na GSI
Rysunek 2. Sugerowane partycje w przypadku SSI opartego na GSI
Podstawowy obraz systemu (GSI) to obraz systemu utworzony bezpośrednio na podstawie AOSP. Jest ona używana do testów zgodności z 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ą prawdziwego urządzenia z wymaganą wersją Androida.
Producenci OEM mogą też używać GSI do tworzenia SSI. Jak wyjaśniono w sekcji 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 producenta OEM. Gdy GSI jest używany jako obraz system
, producent OEM może skupić się na obrazie system_ext
podczas uaktualniania.
W tej sekcji znajdziesz przewodnik dla producentów OEM, którzy chcą podzielić swoje dostosowania na moduły w partycjach /system_ext
i /product
, używając obrazu systemu AOSP lub zbliżonego do AOSP. Jeśli producenci OEM tworzą obraz systemu ze źródeł AOSP, mogą zastąpić utworzony przez siebie obraz systemu obrazem GSI dostarczonym przez AOSP. Nie muszą jednak od razu przechodzić do ostatniego etapu (używania GSI w obecnej postaci).
Krok 1. Dziedziczenie pliku generic_system.mk dla obrazu systemu OEM (GSI OEM)
Dzięki dziedziczeniu
generic_system.mk
(które w Androidzie 11 nosiło nazwę mainline_system.mk
, a w AOSP zostało zmienione na
generic_system.mk
) obraz systemu (OEM GSI) zawiera wszystkie pliki, które ma AOSP GSI.
Producenci OEM mogą modyfikować te pliki, dzięki czemu GSI OEM może zawierać pliki zastrzeżone przez 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 na potrzeby obrazu systemu OEM
Krok 2. Spraw, aby obraz GSI OEM zawierał tę samą listę plików co obraz GSI AOSP.
Na tym etapie GSI OEM nie może zawierać dodatkowych plików. Pliki własne producenta OEM muszą zostać przeniesione do partycji system_ext
lub product
.
Rysunek 4. Przenoszenie dodanych plików z GSI OEM
Krok 3. Zdefiniuj listę dozwolonych, aby ograniczyć liczbę zmodyfikowanych plików w GSI OEM
Aby sprawdzić zmodyfikowane pliki, producenci OEM mogą użyć narzędzia compare_images
i porównać obraz GSI AOSP z obrazem GSI OEM. Pobierz obraz GSI AOSP z generic_system_*
docelowego środowiska uruchomieniowego AOSP.
Uruchamiając okresowo narzędzie compare_images
z parametrem allowlist
, możesz monitorować różnice poza dozwoloną listą. Dzięki temu nie trzeba wprowadzać dodatkowych modyfikacji w GSI OEM.
Rysunek 5. Zdefiniuj listę dozwolonych, aby skrócić listę zmodyfikowanych plików w GSI OEM
Krok 4. Spraw, aby GSI OEM zawierał te same pliki binarne co GSI AOSP.
Wyczyszczenie listy dozwolonych umożliwia producentom OEM używanie obrazu systemu GSI AOSP jako obrazu systemu dla własnych produktów. Aby wyczyścić listę dozwolonych, producenci OEM mogą porzucić zmiany w GSI OEM lub przesłać je do AOSP, aby GSI AOSP zawierał te zmiany.
Rysunek 6. Ujednolicenie plików binarnych w obrazie GSI OEM i obrazie GSI AOSP
Definiowanie SSI dla producentów OEM
Ochrona partycji /system podczas kompilacji
Aby uniknąć zmian dotyczących konkretnych produktów w partycji /system
i zdefiniować obraz GSI OEM, producenci OEM mogą użyć makra pliku make o nazwie require-artifacts-in-path
, aby zapobiec deklarowaniu modułów systemowych po wywołaniu makra. Zobacz przykład tworzenia pliku makefile i włączania sprawdzania ścieżki artefaktu.
Producenci OEM mogą zdefiniować listę, aby umożliwić tymczasową instalację modułów specyficznych dla produktu w partycji /system
. Aby jednak obraz GSI OEM był wspólny dla wszystkich produktów OEM, lista musi być pusta. Ten proces służy do definiowania obrazu GSI OEM i może być niezależny od kroków dotyczących obrazu GSI AOSP.
Wymuszanie interfejsów usług
Aby zagwarantować, że partycja /product
jest odłączona, producenci OEM mogą zadbać o to, aby urządzenia wymuszały interfejsy produktów, ustawiając PRODUCT_PRODUCT_VNDK_VERSION:= current
dla modułów natywnych i PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE:= true
dla modułów Java. Te zmienne są ustawiane automatycznie, jeśli PRODUCT_SHIPPING_API_LEVEL
urządzenia jest większy lub równy 30
. Szczegółowe informacje znajdziesz w artykule Wymuszanie interfejsów podziału produktów.
Udostępnianie partycji /system_ext
Partycja /system_ext
może się różnić w zależności od urządzenia, ponieważ może zawierać moduły specyficzne dla danego 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łasny SSI i udostępniać go na wielu urządzeniach, usuwając wszelkie różnice i sprawiając, że partycja /system_ext
jest wspólna.
W tej sekcji znajdziesz rekomendacje dotyczące tworzenia wspólnej partycji /system_ext
.
Udostępnianie ukrytych interfejsów API na partycji systemowej
Wiele aplikacji przeznaczonych dla konkretnych produktów nie może być zainstalowanych w partycji produktu, ponieważ korzystają one z ukrytych interfejsów API, które są w niej zabronione. Aby przenieść aplikacje przeznaczone na konkretne urządzenia do partycji produktu, 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 można nimi zastąpić. Jeśli nie ma interfejsów API, które mogłyby zastąpić ukryte interfejsy API, producenci OEM mogą współtworzyć AOSP, aby zdefiniować nowe systemowe interfejsy API dla swoich urządzeń.
Producenci OEM mogą też definiować niestandardowe interfejsy API, tworząc własną bibliotekę pakietu SDK w języku Java w /system_ext
partycji. Może korzystać z ukrytych interfejsów API w partycji systemowej i udostępniać je aplikacjom w partycji produktu lub dostawcy.
Producenci OEM muszą zablokować interfejsy API skierowane do użytkowników, aby zapewnić zgodność wsteczną.
Zawiera nadzbiór wszystkich plików APK i pomija instalację niektórych pakietów na każdym urządzeniu.
Niektóre pakiety dołączone do systemu nie są wspólne dla wszystkich urządzeń.
Rozdzielenie tych modułów APK i przeniesienie ich do partycji produktu lub dostawcy może być trudne. Jako rozwiązanie tymczasowe producenci OEM mogą uwzględnić w SSI wszystkie moduły, a następnie odfiltrować niechciane za pomocą 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, który wyłącza niepotrzebne pakiety. Odbiornik transmisji wywołuje
setApplicationEnabledSetting
w celu wyłączenia pakietu, gdy otrzyma komunikat
ACTION_BOOT_COMPLETED
Definiowanie RRO zamiast korzystania ze statycznej nakładki zasobów
Nakładka zasobu statycznego modyfikuje nakładane pakiety. Może to jednak utrudniać określanie SSI, dlatego upewnij się, że właściwości RRO są włączone i prawidłowo skonfigurowane. Ustawiając właściwości w ten 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 korzystać z automatycznie wygenerowanego pliku. Szczegółowe informacje znajdziesz w artykule Nakładki zasobów środowiska wykonawczego (RRO).
Producenci OEM mogą też definiować warunkowe nakładki RRO, 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 charakterystyki urządzeń (lub grupy urządzeń).
Producenci OEM mogą spróbować utworzyć partycję system_ext
, która będzie wspólna, zgodnie z opisem w artykule Tworzenie wspólnej partycji system_ext. Jeśli grupa urządzeń ma wiele różnic, lepiej zdefiniować kilka identyfikatorów SSI.
Czy mogę zmodyfikować plik generic_system.mk (mainline_system.mk) w przypadku obrazu GSI OEM?
Nie. Producenci OEM mogą jednak zdefiniować nowy plik makefile dla obrazu GSI OEM, który dziedziczy plik generic_system.mk
, i używać nowego pliku makefile. Przykład znajdziesz w artykule Wymuszanie interfejsów podziału produktów.
Czy mogę usunąć z pliku generic_system.mk moduły, które powodują konflikt z moją implementacją?
Nie. GSI ma minimalny zestaw modułów, które można uruchomić i przetestować. Jeśli uważasz, że moduł nie jest niezbędny, zgłoś błąd, aby zaktualizować plik generic_system.mk
w AOSP.