Udostępniony obraz systemu Android

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.

Partycje i interfejsy wokół schematu blokowego SSI

Rysunek 1. Partycje i interfejsy związane z SSI

Obrazy i partycje

Informacje w tej sekcji rozróżniają terminy obrazpartycja.

  • 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 /systemobrazu lub z /system/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/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 systemsystem_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
  • 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_extPartycja utworzona dla poprzedniej wersji Androida nie musi być zgodna z /systempartycją w kolejnej wersji Androida.

Aby zainstalować moduł w partycji /system_ext, dodaj system_ext_specific: truedo 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 /systempartycją. 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/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/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 /systempartycji. 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

Sugerowane partycje 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/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.

Dziedziczenie pliku `generic_system.mk` na potrzeby obrazu systemu OEM

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.

Przenoszenie dodanych plików z GSI OEM

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.

Zdefiniuj listę dozwolonych, aby skrócić listę zmodyfikowanych plików 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.

Spraw, aby GSI OEM miało te same pliki binarne co GSI AOSP

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/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/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_listconfig_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:requiredSystemPropertyNameandroid: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.