Pliki manifestu

Obiekt VINTF agreguje dane z plików manifestu urządzenia i plików manifestu struktury (XML). Obydwa manifesty mają ten sam format, chociaż nie wszystkie elementy mają zastosowanie do obu (szczegółowe informacje na temat schematu można znaleźć w sekcji Schemat pliku manifestu ).

Manifest urządzenia

Manifest urządzenia (dostarczany przez urządzenie) składa się z manifestu dostawcy i manifestu ODM.

  • Manifest dostawcy określa warstwy HAL, wersje zasad SELinux itp. wspólne dla SoC. Zalecane jest umieszczenie go w drzewie źródłowym Androida pod device/ VENDOR / DEVICE /manifest.xml , ale można używać wielu plików fragmentacyjnych. Aby uzyskać szczegółowe informacje, zobacz Fragmenty manifestu i Generowanie DM z fragmentów .
  • Manifest ODM zawiera listę warstw HAL specyficznych dla produktu znajdującego się na partycji ODM . Obiekt VINTF ładuje manifest ODM w następującej kolejności:
    1. Jeżeli zdefiniowano SKU (gdzie SKU jest wartością właściwości ro.boot.product.hardware.sku ), /odm/etc/vintf/manifest_ SKU .xml
    2. /odm/etc/vintf/manifest.xml
    3. Jeśli zdefiniowano SKU , /odm/etc/manifest_ SKU .xml
    4. /odm/etc/manifest.xml
  • Manifest dostawcy zawiera listę warstw HAL specyficznych dla produktu w partycji dostawcy. Obiekt VINTF ładuje manifest dostawcy w następującej kolejności:
    1. Jeżeli zdefiniowano SKU (gdzie SKU jest wartością właściwości ro.boot.product.vendor.sku ), /vendor/etc/vintf/manifest_ SKU .xml
    2. /vendor/etc/vintf/manifest.xml
  • Obiekt VINTF ładuje manifest urządzenia w następującej kolejności:
    1. Jeśli manifest dostawcy istnieje, połącz następujące elementy:
      1. Manifest dostawcy
      2. Opcjonalne fragmenty manifestu dostawcy
      3. Opcjonalny manifest ODM
      4. Opcjonalne fragmenty manifestu ODM
    2. W przeciwnym razie, jeśli manifest ODM istnieje, połącz manifest ODM z opcjonalnymi fragmentami manifestu ODM.
    3. /vendor/manifest.xml (starsza wersja, bez fragmentów)

    Pamiętaj, że:

    • Na starszych urządzeniach używany jest manifest starszego dostawcy i manifest ODM. Manifest ODM może całkowicie zastąpić manifest starszego dostawcy.
    • Na urządzeniach z systemem Android 9 manifest ODM jest łączony z manifestem dostawcy.
    • Podczas łączenia listy manifestów manifesty pojawiające się później na liście mogą zastąpić tagi w manifestach, które pojawiają się wcześniej na liście, pod warunkiem, że tagi w późniejszym manifeście mają atrybut override="true" . Na przykład manifest ODM może zastąpić niektóre znaczniki <hal> z manifestu dostawcy. Zobacz dokumentację dotyczącą override atrybutów poniżej.

Taka konfiguracja umożliwia wielu produktom wyposażonym w tę samą płytkę współużytkowanie tego samego obrazu dostawcy (co zapewnia wspólne warstwy HAL), a jednocześnie korzystanie z różnych obrazów ODM (które określają warstwy HAL specyficzne dla produktu).

Oto przykładowy manifest dostawcy.

<?xml version="1.0" encoding="UTF-8"?>
<!-- Comments, Legal notices, etc. here -->
<manifest version="2.0" type="device" target-level="1">
    <hal>
        <name>android.hardware.camera</name>
        <transport>hwbinder</transport>
        <version>3.4</version>
        <interface>
            <name>ICameraProvider</name>
            <instance>legacy/0</instance>
            <instance>proprietary/0</instance>
        </interface>
    </hal>
    <hal>
        <name>android.hardware.nfc</name>
        <transport>hwbinder</transport>
        <version>1.0</version>
        <version>2.0</version>
        <interface>
            <name>INfc</name>
            <instance>nfc_nci</instance>
        </interface>
    </hal>
    <hal>
        <name>android.hardware.nfc</name>
        <transport>hwbinder</transport>
        <fqname>@2.0::INfc/default</fqname>
    </hal>
    <hal>
        <name>android.hardware.drm</name>
        <transport>hwbinder</transport>
        <version>1.0</version>
        <interface>
            <name>ICryptoFactory</name>
            <instance>default</instance>
        </interface>
        <interface>
            <name>IDrmFactory</name>
            <instance>default</instance>
        </interface>
        <fqname>@1.1::ICryptoFactory/clearkey</fqname>
        <fqname>@1.1::IDrmFactory/clearkey</fqname>
    </hal>
    <hal format="aidl">
        <name>android.hardware.light</name>
        <version>1</version>
        <fqname>ILights/default</fqname>
    </hal>
    <hal format="aidl">
        <name>android.hardware.power</name>
        <version>2</version>
        <interface>
            <name>IPower</name>
            <instance>default</instance>
        </interface>
    </hal>
    <hal format="native">
        <name>EGL</name>
        <version>1.1</version>
    </hal>
    <hal format="native">
        <name>GLES</name>
        <version>1.1</version>
        <version>2.0</version>
        <version>3.0</version>
    </hal>
    <sepolicy>
        <version>25.0</version>
    </sepolicy>
</manifest>

Oto przykładowy manifest ODM.

<?xml version="1.0" encoding="UTF-8"?>
<!-- Comments, Legal notices, etc. here -->
<manifest version="1.0" type="device">
    <!-- camera 3.4 in vendor manifest is ignored -->
    <hal override="true">
        <name>android.hardware.camera</name>
        <transport>hwbinder</transport>
        <version>3.5</version>
        <interface>
            <name>ICameraProvider</name>
            <instance>legacy/0</instance>
        </interface>
    </hal>
    <!-- NFC is declared to be disabled -->
    <hal override="true">
        <name>android.hardware.nfc</name>
        <transport>hwbinder</transport>
    </hal>
    <hal>
        <name>android.hardware.power</name>
        <transport>hwbinder</transport>
        <version>1.1</version>
        <interface>
            <name>IPower</name>
            <instance>default</instance>
        </interface>
    </hal>
</manifest>

Oto przykładowy manifest urządzenia w pakiecie OTA.

<?xml version="1.0" encoding="UTF-8"?>
<!-- Comments, Legal notices, etc. here -->
<manifest version="1.0" type="device" target-level="1">
    <!-- hals ommited -->
    <kernel version="4.4.176">
        <config>
            <key>CONFIG_ANDROID</key>
            <value>y</value>
        </config>
        <config>
            <key>CONFIG_ARM64</key>
            <value>y</value>
        </config>
    <!-- other configs ommited -->
    </kernel>
</manifest>

Aby uzyskać więcej informacji, zobacz Tworzenie manifestu urządzenia .

Manifest ramowy

Plik manifestu struktury składa się z manifestu systemowego, manifestu produktu i manifestu system_ext.

  • Manifest systemowy (dostarczany przez Google) jest generowany ręcznie i znajduje się w drzewie źródeł Androida pod /system/libhidl/manifest.xml .
  • Manifest produktu (dostarczany przez urządzenie) zawiera listę warstw HAL obsługiwanych przez moduły zainstalowane na partycji produktu.
  • Manifest system_ext (dostarczany przez urządzenie) zawiera następujące informacje:
    • HAL obsługiwane przez moduły zainstalowane na partycji system_ext;
    • wersje VNDK;
    • Wersja zestawu SDK systemu.

Podobnie jak w przypadku manifestu urządzenia, można używać wielu plików fragmentacyjnych. Aby uzyskać szczegółowe informacje, zobacz Fragmenty manifestu .

Oto przykładowy manifest struktury.

<?xml version="1.0" encoding="UTF-8"?>
<!-- Comments, Legal notices, etc. here -->
<manifest version="1.0" type="framework">
    <hal>
        <name>android.hidl.allocator</name>
        <transport>hwbinder</transport>
        <version>1.0</version>
        <interface>
            <name>IAllocator</name>
            <instance>ashmem</instance>
        </interface>
    </hal>
    <hal>
        <name>android.hidl.memory</name>
        <transport arch="32+64">passthrough</transport>
        <version>1.0</version>
        <interface>
            <name>IMapper</name>
            <instance>ashmem</instance>
        </interface>
    </hal>
    <hal>
        <name>android.hidl.manager</name>
        <transport>hwbinder</transport>
        <version>1.0</version>
        <interface>
            <name>IServiceManager</name>
            <instance>default</instance>
        </interface>
    </hal>
    <hal>
        <name>android.frameworks.sensorservice</name>
        <transport>hwbinder</transport>
        <version>1.0</version>
        <interface>
            <name>ISensorManager</name>
            <instance>default</instance>
        </interface>
    </hal>
    <hal max-level="5">
        <name>android.frameworks.schedulerservice</name>
        <transport>hwbinder</transport>
        <version>1.0</version>
        <interface>
            <name>ISchedulingPolicyService</name>
            <instance>default</instance>
        </interface>
    </hal>
    <vendor-ndk>
        <version>27</version>
    </vendor-ndk>
    <system-sdk>
        <version>27</version>
    </system-sdk>
</manifest>

Manifestowane fragmenty

W systemie Android 10 i nowszych wersjach można powiązać wpis manifestu z modułem HAL w systemie kompilacji. Ułatwia to warunkowe dołączenie modułu HAL do systemu kompilacji.

Przykład

W pliku Android.bp lub Android.mk dodaj vintf_fragments do dowolnego modułu. Na przykład możesz zmodyfikować moduł za pomocą implementacji warstwy HAL ( my.package.foo@1.0-service-bar ).

... {
    ...
    vintf_fragments: ["manifest_foo.xml"],
    ...
}
LOCAL_MODULE := ...
LOCAL_VINTF_FRAGMENTS := manifest_foo.xml

W pliku o nazwie manifest_foo.xml utwórz manifest dla tego modułu. W czasie kompilacji ten manifest jest dodawany do urządzenia. Dodanie wpisu w tym miejscu jest równoznaczne z dodaniem wpisu w głównym manifeście urządzenia. Umożliwia to klientom korzystanie z interfejsu i pozwala VTS zidentyfikować, które implementacje HAL znajdują się na urządzeniu. Wszystko, co robi zwykły manifest, robi także ten manifest.

Poniższy przykład implementuje android.hardware.foo@1.0::IFoo/default , który jest instalowany na partycji vendor lub odm . Jeśli jest zainstalowany na partycji system , product lub system_ext , użyj typu framework zamiast typu device .

<manifest version="1.0" type="device">
    <hal format="hidl">
        <name>android.hardware.foo</name>
        <transport>hwbinder</transport>
        <fqname>@1.0::IFoo/default</fqname>
    </hal>
</manifest>

Schemat pliku manifestu

W tej sekcji opisano znaczenie tych znaczników XML. W pliku źródłowym w drzewie źródeł Androida może brakować niektórych „wymaganych” tagów i są one zapisywane przez assemble_vintf w czasie kompilacji. Wymagane tagi muszą znajdować się w odpowiednich plikach na urządzeniu.

?xml
Opcjonalny. Dostarcza informacje jedynie do parsera XML.
manifest.version
Wymagany. Metawersja tego manifestu. Opisuje elementy oczekiwane w manifeście. Niezwiązane z wersją XML.
manifest.type
Wymagany. Typ tego manifestu. Ma wartość device dla pliku manifestu urządzenia i framework dla pliku manifestu struktury.
manifest.target-level
Wymagane dla manifestu urządzenia. Określa wersję macierzy zgodności platformy (FCM), z którą ma być zgodny ten manifest urządzenia. Nazywa się to również wysyłkową wersją urządzenia FCM.
manifest.hal
Opcjonalnie, można powtórzyć. Pojedynczy HAL (HIDL lub natywny, taki jak GL), w zależności od atrybutu format .
manifest.hal.format
Opcjonalny. Wartość może być jedną z:
  • hidl : HIDL HAL. To jest ustawienie domyślne.
  • aidl : AIDL HAL . Obowiązuje tylko w metawersji manifestu 2.0 i nowszych.
  • native : Natywne warstwy HAL.
manifest.hal.max-level
Opcjonalny. Obowiązuje tylko w manifestach struktury. Jeśli jest ustawiona, warstwy HAL z maksymalnym poziomem niższym niż docelowa wersja FCM w manifeście platformy są wyłączone.
manifest.hal.override
Opcjonalny. Wartość może być jedną z:
  • true : Zastąp inne elementy <hal> tą samą wersją <name> i główną. Jeśli w elemencie <hal> nie ma <version> ani <fqname> , wówczas element <hal> deklaruje, że ta warstwa HAL jest wyłączona.
  • false : Nie zastępuj innych elementów <hal> tą samą <name> i wersją główną.
manifest.hal.name
Wymagany. W pełni kwalifikowana nazwa pakietu HAL. Wiele wpisów HAL może używać tej samej nazwy. Przykłady:
  • android.hardware.camera (HIDL lub AIDL HAL)
  • GLES (natywny HAL, wymaga tylko nazwy)
manifest.hal.transport
Wymagane, gdy manifest.hal.format == "hidl" . W przeciwnym razie NIE może być obecny. Określa, jaki transport jest używany, gdy menedżer usług pyta o interfejs z tego pakietu. Wartość może być jedną z:
  • hwbinder : Tryb segregacji
  • passthrough : tryb przejścia
Opcjonalne, gdy manifest.hal.format == "aidl" . W przeciwnym razie NIE może być obecny. Określa, jaki transport jest używany, gdy interfejs jest obsługiwany zdalnie. Wartość musi być:
  • inet : gniazdo Inet
Do dalszego określenia informacji o połączeniu Inet należy użyć manifest.hal.transport.ip i manifest.hal.transport.port .
manifest.hal.transport.arch
Wymagane do passthrough i nie może być obecne dla hwbinder . Opisuje bitowość dostarczanej usługi przekazywania. Wartość może być jedną z:
  • 32 : tryb 32-bitowy
  • 64 : tryb 64-bitowy
  • 32+64 : Obydwa
manifest.hal.transport.ip
Wymagane dla inet i NIE może być obecne w innym przypadku. Opisuje adres IP, z którego obsługiwany jest interfejs zdalny.
manifest.hal.transport.port
Wymagane dla inet i NIE może być obecne w innym przypadku. Opisuje port, z którego obsługiwany jest interfejs zdalny.
manifest.hal.version
Opcjonalnie, można powtórzyć. Wersja tagów hal w manifeście.

W przypadku HIDL i natywnych warstw HAL format to MAJOR . MINOR . Przykłady można znaleźć w hardware/interfaces , vendor/${VENDOR}/interfaces , frameworks/hardware/interfaces lub system/hardware/interfaces .

HIDL i natywne warstwy HAL mogą używać wielu pól wersji, pod warunkiem, że reprezentują odrębne wersje główne , przy czym dla każdej wersji głównej dostępna jest tylko jedna wersja pomocnicza. Na przykład 3.1 i 3.2 nie mogą współistnieć, ale 1.0 i 3.4 mogą. Dotyczy to wszystkich elementów hal o tej samej nazwie, chyba że override="true" . Wartości <version> nie są powiązane z <fqname> , ponieważ <fqname> zawiera wersję.

W przypadku AIDL HAL <version> nie może być obecna na urządzeniach z systemem Android 11 i starszym. <version> musi być pojedynczą liczbą całkowitą na urządzeniach z Androidem 12 i nowszym. Dla każdej krotki (package, interface, instance) musi istnieć co najwyżej jedna <version> . Jeśli nie istnieje, domyślnie 1 . Wartość <version> jest powiązana ze wszystkimi <fqname> w tym samym <hal> , ponieważ <fqname> nie niesie wersji.
manifest.hal.interface
Wymagane, można powtórzyć bez duplikatów. Podaj interfejs w pakiecie, który ma nazwę instancji. W <hal> może znajdować się wiele elementów <interface> ; nazwy muszą być różne.
manifest.hal.interface.name
Wymagany. Nazwa interfejsu.
manifest.hal.interface.instance
Wymagane, można powtórzyć. Nazwa instancji interfejsu. Może mieć wiele instancji interfejsu, ale nie może mieć zduplikowanych elementów <instance> .
manifest.hal.fqname
Opcjonalnie, można powtórzyć. Alternatywny sposób określenia instancji warstwy HAL o nazwie manifest.hal.name .
  • W przypadku HIDL HAL format to @ MAJOR . MINOR :: INTERFACE / INSTANCE .
  • W przypadku AIDL HAL format to INTERFACE / INSTANCE .
manifest.sepolicy
Wymagany. Zawiera wszystkie wpisy związane z sepolicy.
manifest.sepolicy.version
Wymagane dla manifestu urządzenia. Deklaruje wersję SELinux. Ma format SDK_INT . PLAT_INT .
manifest.vendor-ndk
Wymagane, można powtórzyć; wymagane dla manifestu struktury. Nie może być obecny w manifeście urządzenia. Wiele wpisów <vendor-ndk> musi mieć różne wartości <version> . Opisuje zestaw migawek VNDK dostarczonych przez platformę.
manifest.vendor-ndk.version
Wymagany. Jest to dodatnia liczba całkowita reprezentująca wersję migawki VNDK.
manifest.vendor-ndk.library
Opcjonalnie, można powtórzyć, bez duplikatów. Opisuje zestaw bibliotek VNDK dostarczonych przez platformę dla tej migawki dostawcy VNDK. Wartością jest nazwa pliku biblioteki, np. libjpeg.so , łącznie z przedrostkiem lib i przyrostkiem .so . Żadne komponenty ścieżki nie są dozwolone.
manifest.system-sdk.version
Opcjonalnie, można powtórzyć, bez duplikatów; używany tylko przez manifest struktury. Opisuje zestaw wersji systemowego zestawu SDK udostępnianych przez platformę aplikacjom dostawców.
manifest.kernel
Opcjonalny. Opisuje statyczne informacje o jądrze.
manifest.kernel.target-level
Opcjonalny. Opisuje gałąź jądra. Jego wartość domyślna to manifest.target-level jeśli nie jest obecna. Musi być większy lub równy manifest.target-level . Aby uzyskać szczegółowe informacje, zobacz reguły dopasowania jądra .