Corresponder às regras

As duas matrizes e manifestos de compatibilidade precisam ser reconciliados para verificar se o framework e a implementação do fornecedor podem funcionar juntos. Essa verificação será bem-sucedida quando houver uma correspondência entre a matriz de compatibilidade do framework e o manifesto do dispositivo, bem como entre o manifesto do framework e a matriz de compatibilidade do dispositivo.

Essa verificação é feita no momento do build, da geração do pacote de atualização OTA, da inicialização e nos testes de compatibilidade do VTS.

As seções a seguir detalham as regras de correspondência usadas por vários componentes.

A versão da matriz de compatibilidade do framework corresponde

Para corresponder um manifesto de dispositivo a uma matriz de compatibilidade de framework, a versão de FCM de envio especificada por manifest.target-level precisa ser exatamente igual à versão de FCM especificada por compatibility-matrix.level. Caso contrário, não há correspondência.

Quando a matriz de compatibilidade de framework é solicitada com libvintf, essa correspondência sempre é bem-sucedida porque libvintf abre o manifesto do dispositivo, recupera a versão de envio do FCM e retorna a matriz de compatibilidade de framework nessa versão de envio do FCM (além de alguns HALs opcionais de matrizes de compatibilidade em versões mais recentes do FCM).

Correspondências de HAL

A regra de correspondência de HAL identifica as versões dos elementos hal em um arquivo de manifesto que são consideradas compatíveis com o proprietário da matriz de compatibilidade correspondente.

HALs nativas e HIDL

As regras de correspondência para HALs nativas e HIDL são as seguintes:

  • Vários elementos <hal> são avaliados com uma única relação AND.
  • Os elementos <hal> podem ter <hal optional="true"> para marcá-los como não obrigatórios.
  • Vários elementos <version> no mesmo elemento <hal> têm a relação OR. Se duas ou mais forem especificadas, apenas uma das versões precisará ser implementada. Consulte Correspondência de HAL bem-sucedida para módulo DRM.
  • Vários elementos <instance> e <regex-instance> dentro do mesmo elemento <hal> são avaliados com uma única relação AND quando o <hal> é obrigatório. Consulte Correspondência bem-sucedida da HAL para o módulo DRM.

Exemplo: correspondência de HAL bem-sucedida para um módulo

Para uma HAL na versão 2.5, a regra de correspondência é a seguinte:

Matriz Manifesto correspondente
2.5 2.5-2.∞. Na matriz de compatibilidade, 2.5 é a abreviação de 2.5-5.
2.5-7 2,5 a 2,∞. Indica o seguinte:
  • A versão mínima necessária é a 2.5, o que significa que um manifesto que fornece HAL 2.0-2.4 não é compatível.
  • 2.7 é a versão máxima que pode ser solicitada. Isso significa que o proprietário da matriz de compatibilidade (framework ou dispositivo) não pode solicitar versões além da 2.7. O proprietário do manifesto correspondente ainda pode veicular a versão 2.10 (como exemplo) quando a 2.7 for solicitada. O proprietário da matriz de compatibilidade sabe apenas que o serviço solicitado é compatível com a versão 2.7 da API.
  • -7 é apenas informativo e não afeta o processo de atualização OTA.
Assim, um dispositivo com um HAL na versão 2.10 no arquivo de manifesto permanece compatível com um framework que declara 2.5-7 na matriz de compatibilidade.

Exemplo: correspondência bem-sucedida da HAL para o módulo DRM

A matriz de compatibilidade do framework informa as seguintes informações de versão para a HAL de DRM:

<hal>
    <name>android.hardware.drm
    <version>1.0</version>
    <version>3.1-2</version>
    <interface>
        <name>IDrmFactory</name>
        <instance>default</instance>
        <instance>specific</instance>
    </interface>
</hal>
<hal>
    <name>android.hardware.drm
    <version>2.0</version>
    <interface>
        <name>ICryptoFactory</name>
        <instance>default</instance>
        <regex-instance>[a-z]+/[0-9]+</regex-instance>
    </interface>
</hal>

Um fornecedor precisa implementar UMA das seguintes instâncias:

android.hardware.drm@1.x::IDrmFactory/default          // where x >= 0
android.hardware.drm@1.x::IDrmFactory/specific         // where x >= 0

OU:

android.hardware.drm@3.y::IDrmFactory/default          // where y >= 1
android.hardware.drm@3.y::IDrmFactory/specific         // where y >= 1

E precisa implementar todas estas instâncias:

android.hardware.drm@2.z::ICryptoFactory/default       // where z >= 0
android.hardware.drm@2.z::ICryptoFactory/${INSTANCE}
            // where z >= 0 and ${INSTANCE} matches [a-z]+/[0-9]+
            // e.g. legacy/0

HALs do AIDL

O Android e versões mais recentes oferecem suporte a versões para HALs da AIDL no VINTF. As regras de correspondência para HALs AIDL são semelhantes às de HALs HIDL e nativas, exceto que não há versões principais, e há exatamente uma versão por instância de HAL (1 se a versão não for especificada):

  • Vários elementos <hal> são avaliados com uma única relação AND.
  • Os elementos <hal> podem ter <hal optional="true"> para marcar como não obrigatório.
  • Vários elementos <instance> e <regex-instance> dentro do mesmo <hal> são avaliados com uma única relação AND quando o <hal> é obrigatório. Consulte Correspondência de HAL bem-sucedida para vários módulos.

Exemplo: correspondência de HAL bem-sucedida para um módulo

Para uma HAL na versão 5, a regra de correspondência é a seguinte:

Matriz Manifesto correspondente
5 5-∞. Na matriz de compatibilidade, 5 é a abreviação de 5-5.
5-7 5 a ∞. Indica o seguinte:
  • 5 é a versão mínima necessária, o que significa que um manifesto que fornece HAL 1 a 4 não é compatível.
  • 7 é a versão máxima que pode ser solicitada, o que significa que o proprietário da matriz de compatibilidade (framework ou dispositivo) não vai solicitar versões além da 7. O proprietário do manifesto correspondente ainda pode veicular a versão 10 (como exemplo) quando a 7 for solicitada. O proprietário da matriz de compatibilidade sabe apenas que o serviço solicitado é compatível com a versão 7 da API.
  • -7 é apenas informativo e não afeta o processo de atualização OTA.
Assim, um dispositivo com um HAL na versão 10 no arquivo de manifesto continua compatível com um framework que declara 5-7 na matriz de compatibilidade.

Exemplo: correspondência de HAL bem-sucedida para vários módulos

A matriz de compatibilidade de framework informa as seguintes informações de versão para HALs de vibrador e câmera:

<hal>
    <name>android.hardware.vibrator
    <version>1-2</version>
    <interface>
        <name>IVibrator</name>
        <instance>default</instance>
        <instance>specific</instance>
    </interface>
</hal>
<hal>
    <name>android.hardware.camera
    <version>5</version>
    <interface>
        <name>ICamera</name>
        <instance>default</instance>
        <regex-instance>[a-z]+/[0-9]+</regex-instance>
    </interface>
</hal>

Um fornecedor precisa implementar todas estas instâncias:

android.hardware.vibrator.IVibrator/default     // version >= 1
android.hardware.vibrator.IVibrator/specific    // version >= 1
android.hardware.camera.ICamera/default         // version >= 5
android.hardware.camera.ICamera/${INSTANCE}
            // with version >= 5, where ${INSTANCE} matches [a-z]+/[0-9]+
            // e.g. legacy/0

Correspondências de kernel

A seção <kernel> da matriz de compatibilidade da estrutura descreve os requisitos da estrutura do kernel do Linux no dispositivo. Essas informações devem ser comparadas com as informações sobre o kernel que são informadas pelo objeto VINTF do dispositivo.

Fazer correspondência com ramificações do kernel

Cada sufixo de ramificação do kernel (por exemplo, 5.4-r) é mapeado para uma versão exclusiva do FCM do kernel (por exemplo, 5). O mapeamento é o mesmo das letras de lançamento (por exemplo, R) e das versões do FCM (por exemplo, 5).

Os testes do VTS exigem que o dispositivo especifique explicitamente a versão do FCM do kernel no manifesto do dispositivo, /vendor/etc/vintf/manifest.xml, se uma das seguintes condições for verdadeira:

  • A versão do FCM do kernel é diferente da versão do FCM de destino. Por exemplo, o dispositivo mencionado tem uma versão de destino do FCM 4, e a versão do kernel é 5 (sufixo da ramificação do kernel r).
  • A versão do FCM do kernel é maior ou igual a 5 (sufixo da ramificação do kernel r).

Os testes do VTS exigem que, se a versão do FCM do kernel for especificada, ela seja maior ou igual à versão do FCM de destino no manifesto do dispositivo.

Exemplo: determinar a ramificação do kernel

Se o dispositivo tiver como destino a versão 4 do FCM (lançada no Android 10), mas executar o kernel da ramificação 4.19-r, o manifesto do dispositivo precisará especificar o seguinte:

<manifest version="2.0" type="device" target-level="4">
   <kernel target-level="5" />
</manifest>

O objeto VINTF verifica a compatibilidade do kernel com os requisitos na ramificação 4.19-r do kernel, especificada na versão 5 do FCM. Esses requisitos são criados com base em kernel/configs/r/android-4.19 na árvore de origem do Android.

Exemplo: determinar a ramificação do kernel para GKI

Se o dispositivo usar a imagem genérica do kernel (GKI) e a string de lançamento do kernel de /proc/version for a seguinte:

5.4.42-android12-0-00544-ged21d463f856

Em seguida, o objeto VINTF extrai a versão do Android da versão do kernel e a usa para determinar a versão do FCM do kernel. Neste exemplo, android12 significa a versão 6 do FCM do kernel (lançada no Android 12).

Para detalhes sobre como a string de lançamento do kernel é analisada, consulte Controle de versões do GKI.

Corresponder versões do kernel

Uma matriz pode incluir várias seções <kernel>, cada uma com um atributo version diferente usando o formato:

${ver}.${major_rev}.${kernel_minor_rev}

O objeto VINTF considera apenas a seção <kernel> do FCM com a versão correspondente do FCM com o mesmo ${ver} e ${major_rev} do kernel do dispositivo (ou seja, version="${ver}.${major_rev}.${matrix_minor_rev}"); outras seções são ignoradas. Além disso, a revisão secundária do kernel precisa ser um valor da matriz de compatibilidade (${kernel_minor_rev} >= ${matrix_minor_rev};). Se nenhuma seção <kernel> atender a esses requisitos, não haverá correspondência.

Exemplo: selecionar requisitos para correspondência

Considere o seguinte caso hipotético em que os FCMs em /system/etc/vintf declaram os seguintes requisitos (as tags de cabeçalho e rodapé são omitidas):

<!-- compatibility_matrix.3.xml -->
<kernel version="4.4.107" level="3"/>
<!-- See kernel/configs/p/android-4.4/ for 4.4-p requirements -->
<kernel version="4.9.84" level="3"/>
<!-- See kernel/configs/p/android-4.9/ for 4.9-p requirements -->
<kernel version="4.14.42" level="3"/>
<!-- See kernel/configs/p/android-4.14/ for 4.14-p requirements -->

<!-- compatibility_matrix.4.xml -->
<kernel version="4.9.165" level="4"/>
<!-- See kernel/configs/q/android-4.9/ for 4.9-q requirements -->
<kernel version="4.14.105" level="4"/>
<!-- See kernel/configs/q/android-4.14/ for 4.14-q requirements -->
<kernel version="4.19.42" level="4"/>
<!-- See kernel/configs/q/android-4.19/ for 4.19-q requirements -->

<!-- compatibility_matrix.5.xml -->
<kernel version="4.14.180" level="5"/>
<!-- See kernel/configs/r/android-4.14/ for 4.14-r requirements -->
<kernel version="4.19.123" level="5"/>
<!-- See kernel/configs/r/android-4.19/ for 4.19-r requirements -->
<kernel version="5.4.41" level="5"/>
<!-- See kernel/configs/r/android-5.4/ for 5.4-r requirements -->

A versão de destino do FCM, a versão do FCM do kernel e a versão do kernel juntas selecionam os requisitos do kernel dos FCMs:

Versão de destino do FCMVersão do FCM do kernelVersão do kernelCorresponder a
3 (P)Não especificado4.4.106Nenhuma correspondência (versões secundárias diferentes)
3 (P)Não especificado4.4.1074.4-p
3 (P)Não especificado4.19.424.19-q (consulte a observação após a tabela)
3 (P)Não especificado5.4.415.4-r (consulte a observação após a tabela)
3 (P)3 (P)4.4.1074.4-p
3 (P)3 (P)4.19.42Nenhuma correspondência (nenhuma ramificação do kernel 4.19-p)
3 (P)4 (Q)4.19.424.19-q
4 (Q)Não especificado4.4.107Nenhuma correspondência (nenhuma ramificação do kernel 4.4-q)
4 (Q)Não especificado4.9.1654.9-q
4 (Q)Não especificado5.4.415.4-r (consulte a observação após a tabela)
4 (Q)4 (Q)4.9.1654.9-q
4 (Q)4 (Q)5.4.41Nenhuma correspondência (nenhuma ramificação do kernel 5.4-q)
4 (Q)5 (R)4.14.1054.14-r
4 (Q)5 (R)5.4.415.4-r
5 (R)Não especificadoqualquerO VTS falha (é necessário especificar a versão do FCM do kernel para a versão 5 do FCM de destino)
5 (R)4 (Q)qualquerFalha do VTS (versão do FCM do kernel < versão do FCM de destino)
5 (R)5 (R)4.14.1804.14-r

Corresponder configurações do kernel

Se a seção <kernel> corresponder, o processo vai tentar corresponder os elementos config a /proc/config.gz. Para cada elemento de configuração na matriz de compatibilidade, ele procura /proc/config.gz para verificar se a configuração está presente. Quando um item de configuração é definido como n na matriz de compatibilidade para a seção <kernel> correspondente, ele precisa estar ausente de /proc/config.gz. Por fim, um item de configuração que não está na matriz de compatibilidade pode ou não estar presente em /proc/config.gz.

Exemplo: corresponder configurações do kernel

  • <value type="string">bar</value> corresponde a "bar". As citações são omitidas na matriz de compatibilidade, mas estão presentes em /proc/config.gz.
  • <value type="int">4096</value> corresponde a 4096, 0x1000 ou 0X1000.
  • <value type="int">0x1000</value> corresponde a 4096, 0x1000 ou 0X1000.
  • <value type="int">0X1000</value> corresponde a 4096, 0x1000 ou 0X1000.
  • <value type="tristate">y</value> corresponde a y.
  • <value type="tristate">m</value> corresponde a m.
  • <value type="tristate">n</value> significa que o item de configuração NÃO pode existir em /proc/config.gz.
  • <value type="range">1-0x3</value> corresponde a 1, 2 ou 3, ou ao equivalente hexadecimal.

Exemplo: correspondência de kernel bem-sucedida

Uma matriz de compatibilidade de framework com a versão 1 do FCM tem as seguintes informações do kernel:

<kernel version="4.14.42">
   <config>
      <key>CONFIG_TRI</key>
      <value type="tristate">y</value>
   </config>
   <config>
      <key>CONFIG_NOEXIST</key>
      <value type="tristate">n</value>
   </config>
   <config>
      <key>CONFIG_DEC</key>
      <value type="int">4096</value>
   </config>
   <config>
      <key>CONFIG_HEX</key>
      <value type="int">0XDEAD</value>
   </config>
   <config>
      <key>CONFIG_STR</key>
      <value type="string">str</value>
   </config>
   <config>
      <key>CONFIG_EMPTY</key>
      <value type="string"></value>
   </config>
</kernel>

A ramificação do kernel é correspondida primeiro. A ramificação do kernel é especificada no manifesto do dispositivo em manifest.kernel.target-level, que tem como padrão manifest.level se o primeiro não for especificado:

  • Se a ramificação do kernel no manifesto do dispositivo for 1, o processo vai para a próxima etapa e verifica a versão do kernel.
  • Se a ramificação do kernel no manifesto do dispositivo for 2, não haverá correspondência com a matriz. Os objetos VINTF leem os requisitos do kernel da matriz na versão 2 do FCM.

Em seguida, a versão do kernel é correspondida. Se um dispositivo em uname() informar:

  • 4.9.84 (não corresponde à matriz, a menos que haja uma seção separada do kernel com <kernel version="4.9.x">, em que x <= 84)
  • 4.14.41 (sem correspondência com a matriz, menor que version)
  • 4.14.42 (correspondência com a matriz)
  • 4.14.43 (correspondência com a matriz)
  • 4.1.22 (sem correspondência com a matriz, a menos que haja uma seção de kernel separada com <kernel version="4.1.x">, em que x <= 22)

Depois que a seção <kernel> apropriada for selecionada, para cada item <config> com valor diferente de n, a entrada correspondente deverá estar presente em /proc/config.gz. Para cada item <config> com valor n, a entrada correspondente não deverá estar presente em /proc/config.gz. O conteúdo de <value> precisa corresponder exatamente ao texto após o sinal de igual (incluindo aspas), até o caractere de nova linha ou #, com espaços em branco à esquerda e à direita truncados.

A configuração de kernel a seguir é um exemplo de correspondência bem-sucedida:

# comments don't matter
CONFIG_TRI=y
# CONFIG_NOEXIST shouldn't exist
CONFIG_DEC = 4096 # trailing comments and whitespaces are fine
CONFIG_HEX=57005  # 0XDEAD == 57005
CONFIG_STR="str"
CONFIG_EMPTY=""   # empty string must have quotes
CONFIG_EXTRA="extra config items are fine too"

A configuração de kernel a seguir é um exemplo de uma correspondência sem sucesso:

CONFIG_TRI="y"   # mismatch: quotes
CONFIG_NOEXIST=y # mismatch: CONFIG_NOEXIST exists
CONFIG_HEX=0x0   # mismatch; value doesn't match
CONFIG_DEC=""    # mismatch; type mismatch (expect int)
CONFIG_EMPTY=1   # mismatch; expects ""
# mismatch: CONFIG_STR is missing

Correspondências de SEPolicy

A SEPolicy exige as seguintes correspondências:

  • <sepolicy-version> define um intervalo fechado de versões secundárias para cada versão principal. A versão da SEPolicy informada pelo dispositivo precisa estar em um destes intervalos para ser compatível com o framework. As regras de correspondência são semelhantes às versões de HAL. Há uma correspondência se a versão da SEPolicy for maior ou igual à versão mínima do intervalo. A versão máxima é apenas informativa.
  • <kernel-sepolicy-version>, ou seja, a versão do banco de dados de políticas, precisa ser menor que security_policyvers() informado pelo dispositivo.

Exemplo: correspondência bem-sucedida da SEPolicy

A matriz de compatibilidade do framework declara as seguintes informações da SEPolicy:

<sepolicy>
    <kernel-sepolicy-version>30</kernel-sepolicy-version>
    <sepolicy-version>25.0</sepolicy-version>
    <sepolicy-version>26.0-3</sepolicy-version>
</sepolicy>

No dispositivo:

  • O valor retornado por security_policyvers() precisa ser maior ou igual a 30. Caso contrário, não será uma correspondência. Por exemplo:
    • Se um dispositivo retornar 29, não será uma correspondência.
    • Se um dispositivo retornar 31, será uma correspondência.
  • A versão da SEPolicy precisa ser 25.0-∞ ou 26.0-∞. Caso contrário, não haverá correspondência. O -3 depois de 26.0 é meramente informativo.

Correspondências de versão do AVB

A versão do AVB contém uma versão PRINCIPAL e uma versão SECUNDÁRIA, com o formato PRINCIPAL.SECUNDÁRIA (por exemplo, 1.0, 2.1). Para mais detalhes, consulte Controle de versões e compatibilidade. A versão do AVB tem as seguintes propriedades do sistema:

  • ro.boot.vbmeta.avb_version é a versão libavb no carregador de inicialização.
  • ro.boot.avb_version é a versão libavb no SO Android (init/fs_mgr).

A propriedade do sistema só aparece quando o libavb correspondente foi usado para verificar os metadados do AVB (e retorna OK). Ele fica ausente se ocorrer uma falha na verificação ou se nenhuma verificação for feita.

Uma correspondência de compatibilidade compara o seguinte:

  • sysprop ro.boot.vbmeta.avb_version com avb.vbmeta-version da matriz de compatibilidade do framework:
    • ro.boot.vbmeta.avb_version.MAJOR == avb.vbmeta-version.MAJOR
    • ro.boot.vbmeta.avb_version.MINOR >= avb.vbmeta-version.MINOR
  • sysprop ro.boot.avb_version com avb.vbmeta-version da matriz de compatibilidade do framework:
    • ro.boot.avb_version.MAJOR == avb.vbmeta-version.MAJOR
    • ro.boot.avb_version.MINOR >= avb.vbmeta-version.MINOR

O carregador de inicialização ou o SO Android podem conter duas cópias de bibliotecas libavb, cada uma com uma versão PRINCIPAL diferente para dispositivos de upgrade e de lançamento. Nesse caso, a mesma imagem de sistema não assinada pode ser compartilhada, mas as imagens de sistema assinadas finais são diferentes (com avb.vbmeta-version diferentes):

Figura 1. A versão do AVB corresponde (/system é P, todas as outras partições são O).



Figura 2. As versões do AVB são compatíveis (todas as partições são P).

Exemplo: correspondência bem-sucedida da versão do AVB

A matriz de compatibilidade do framework informa o seguinte sobre o AVB:

<avb>
    <vbmeta-version>2.1</vbmeta-version>
</avb>

No dispositivo:

ro.boot.avb_version              == 1.0 &&
ro.boot.vbmeta.avb_version       == 2.1  mismatch 
ro.boot.avb_version              == 2.1 &&
ro.boot.vbmeta.avb_version       == 3.0  mismatch 
ro.boot.avb_version              == 2.1 &&
ro.boot.vbmeta.avb_version       == 2.3  match 
ro.boot.avb_version              == 2.3 &&
ro.boot.vbmeta.avb_version       == 2.1  match 

Corresponder a versão do AVB durante a OTA

Para dispositivos lançados com o Android 9 ou versões anteriores, ao atualizar para o Android 10, os requisitos de versão do AVB na matriz de compatibilidade do framework são comparados com a versão atual do AVB no dispositivo. Se a versão do AVB tiver um upgrade de versão principal durante um OTA (por exemplo, de 0.0 para 1.0), a verificação de compatibilidade do VINTF no OTA não vai refletir a compatibilidade após o OTA.

Para atenuar o problema, um OEM pode colocar uma versão AVB falsa no pacote OTA (compatibility.zip) para passar na verificação. Para fazer isso, siga estas etapas:

  1. Escolha as seguintes CLs para a árvore de origem do Android 9:
  2. Defina BOARD_OTA_FRAMEWORK_VBMETA_VERSION_OVERRIDE para o dispositivo. O valor precisa ser igual à versão do AVB antes do OTA, ou seja, a versão do AVB do dispositivo quando ele foi lançado.
  3. Recrie o pacote OTA.

Essas mudanças colocam automaticamente BOARD_OTA_FRAMEWORK_VBMETA_VERSION_OVERRIDE como compatibility-matrix.avb.vbmeta-version nos seguintes arquivos:

  • /system/compatibility_matrix.xml (que não é usado no Android 9) no dispositivo
  • system_matrix.xml em compatibility.zip no pacote OTA

Essas mudanças não afetam outras matrizes de compatibilidade de framework, incluindo /system/etc/vintf/compatibility_matrix.xml. Após a OTA, o novo valor em /system/etc/vintf/compatibility_matrix.xml será usado para verificações de compatibilidade.

Correspondências de versão do VNDK

A matriz de compatibilidade de dispositivos declara a versão do VNDK necessária em compatibility-matrix.vendor-ndk.version. Se a matriz de compatibilidade de dispositivos não tiver uma tag <vendor-ndk>, nenhum requisito será imposto, e ela será sempre considerada uma correspondência.

Se a matriz de compatibilidade de dispositivos tiver uma tag <vendor-ndk>, uma entrada <vendor-ndk> com um <version> correspondente será pesquisada no conjunto de snapshots do fornecedor VNDK fornecidos pelo framework no manifesto dele. Se não houver uma entrada assim, não haverá correspondência.

Se essa entrada existir, o conjunto de bibliotecas enumeradas na matriz de compatibilidade de dispositivos precisará ser um subconjunto do conjunto de bibliotecas declarado no manifesto do framework. Caso contrário, a entrada não será considerada uma correspondência.

  • Como um caso especial, se nenhuma biblioteca for enumerada na matriz de compatibilidade de dispositivos, a entrada será sempre considerada uma correspondência, porque um conjunto vazio é um subconjunto de qualquer conjunto.

Exemplo: correspondência bem-sucedida da versão do VNDK

Se a matriz de compatibilidade de dispositivos indicar o seguinte requisito no VNDK:

<!-- Example Device Compatibility Matrix -->
<vendor-ndk>
    <version>27</version>
    <library>libjpeg.so</library>
    <library>libbase.so</library>
</vendor-ndk>

No manifesto do framework, apenas a entrada com a versão 27 é considerada.

<!-- Framework Manifest Example A -->
<vendor-ndk>
    <version>27</version>
    <library>libjpeg.so</library>
    <library>libbase.so</library>
    <library>libfoo.so</library>
</vendor-ndk>

O exemplo A é uma correspondência porque a versão 27 do VNDK está no manifesto do framework e {libjpeg.so, libbase.so, libfoo.so} ⊇ {libjpeg.so, libbase.so}.

<!-- Framework Manifest Example B -->
<vendor-ndk>
    <version>26</version>
    <library>libjpeg.so</library>
    <library>libbase.so</library>
</vendor-ndk>
<vendor-ndk>
    <version>27</version>
    <library>libbase.so</library>
</vendor-ndk>

O exemplo B não é uma correspondência. Mesmo que a versão 27 do VNDK esteja no manifesto do framework, libjpeg.so não é compatível com o framework nesse snapshot. A versão 26 do VNDK é ignorada.

A versão do SDK do sistema corresponde

A matriz de compatibilidade de dispositivos declara um conjunto de versões necessárias do SDK do sistema em compatibility-matrix.system-sdk.version. Só há uma correspondência se o conjunto for um subconjunto das versões do SDK do sistema fornecidas, conforme declarado em manifest.system-sdk.version no manifesto do framework.

  • Como um caso especial, se nenhuma versão do SDK do sistema for enumerada na matriz de compatibilidade do dispositivo, ela sempre será considerada uma correspondência, porque um conjunto vazio é um subconjunto de qualquer conjunto.

Exemplo: correspondência bem-sucedida da versão do SDK do sistema

Se a matriz de compatibilidade de dispositivos indicar o seguinte requisito no SDK do sistema:

<!-- Example Device Compatibility Matrix -->
<system-sdk>
    <version>26</version>
    <version>27</version>
</system-sdk>

Em seguida, o framework precisa fornecer as versões 26 e 27 do SDK do sistema para corresponder:

<!-- Framework Manifest Example A -->
<system-sdk>
    <version>26</version>
    <version>27</version>
</system-sdk>

O exemplo A é uma correspondência:

<!-- Framework Manifest Example B -->
<system-sdk>
    <version>26</version>
    <version>27</version>
    <version>28</version>
</system-sdk>

O exemplo B é uma correspondência:

<!-- Framework Manifest Example C -->
<system-sdk>
    <version>26</version>
</system-sdk>

O exemplo C não é uma correspondência porque a versão 27 do SDK do sistema não foi fornecida.