Os dois pares de matrizes e manifestos de compatibilidade devem ser reconciliados para verificar se a estrutura e a implementação do fornecedor podem funcionar entre si. Essa verificação é bem-sucedida em uma correspondência entre a matriz de compatibilidade da estrutura e o manifesto do dispositivo, bem como entre o manifesto da estrutura e a matriz de compatibilidade do dispositivo.
Essa verificação é feita no momento da compilação, no momento da geração do pacote de atualização OTA , no momento 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 da estrutura corresponde
Para corresponder um manifesto de dispositivo com uma matriz de compatibilidade de estrutura, a versão do FCM de envio especificada por manifest.target-level
deve ser exatamente igual à versão do FCM especificada por compatibility-matrix.level
. Caso contrário, não há correspondência.
Quando a matriz de compatibilidade da estrutura é solicitada com libvintf
, essa correspondência é sempre bem-sucedida porque a libvintf
abre o manifesto do dispositivo, recupera a versão do FCM de envio e retorna a matriz de compatibilidade da estrutura nessa versão do FCM de envio (mais alguns HALs opcionais de matrizes de compatibilidade em FCM mais alto Versões).
partidas HAL
A regra de correspondência HAL identifica as versões de elementos hal
em um arquivo de manifesto que são consideradas suportadas pelo proprietário da matriz de compatibilidade correspondente.
HIDL e HALs nativos
As regras de correspondência para HIDL e HALs nativos são as seguintes.
- Vários elementos
<hal>
são avaliados com um único relacionamento AND . - Os elementos
<hal>
podem ter<hal optional="true">
para marcá-los como não obrigatórios. - Vários elementos
<version>
dentro do mesmo<hal>
têm o relacionamento OR . Se duas ou mais forem especificadas, apenas uma das versões precisa ser implementada. (Veja o exemplo de DRM abaixo.) - Vários elementos
<instance>
e<regex-instance>
dentro do mesmo<hal>
são avaliados com um único relacionamento AND quando o<hal>
é necessário. (Veja oExemplo de DRM abaixo.)
Exemplo: correspondência HAL bem-sucedida para um módulo
Para um 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-2.∞. Indica o seguinte:
2.5-7 em sua matriz de compatibilidade. |
Exemplo: correspondência HAL bem-sucedida para o módulo DRM
A matriz de compatibilidade da estrutura indica as seguintes informações de versão para DRM HAL:
<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 deve implementar UMA das seguintes instâncias; qualquer
android.hardware.drm@1.x::IDrmFactory/default // where x >= 0 android.hardware.drm@1.x::IDrmFactory/specific // where x >= 0OU
android.hardware.drm@3.y::IDrmFactory/default // where y >= 1 android.hardware.drm@3.y::IDrmFactory/specific // where y >= 1
AND também deve implementar todas essas 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
AIDL HALs
Todas as versões do Android posteriores ao Android 11 (excluindo o Android 11) são compatíveis com versões para AIDL HALs em VINTF. As regras de correspondência para AIDL HALs são semelhantes às de HIDL e HALs nativas, exceto que não há versões principais e há exatamente uma versão por instância HAL ( 1
se a versão não for especificada).
- Vários elementos
<hal>
são avaliados com um único relacionamento AND . - Os elementos
<hal>
podem ter<hal optional="true">
para marcá-los como não obrigatórios. - Vários elementos
<instance>
e<regex-instance>
dentro do mesmo<hal>
são avaliados com um único relacionamento AND quando o<hal>
é necessário. (Veja oexemplo de vibrador abaixo.)
Exemplo: correspondência HAL bem-sucedida para um módulo
Para um 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-∞. Indica o seguinte:
5-7 em sua matriz de compatibilidade. |
Exemplo: correspondência HAL bem-sucedida para vários módulos
A matriz de compatibilidade da estrutura indica 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 deve implementar todas essas 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 Linux no dispositivo. Essas informações devem ser comparadas com as informações sobre o kernel que são relatadas pelo objeto VINTF do dispositivo.
Combinar 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 que o mapeamento entre as cartas de liberação (por exemplo, R) e as versões do FCM (por exemplo, 5).
Os testes VTS impõem que o dispositivo especifique explicitamente a versão do kernel FCM no manifesto do dispositivo, /vendor/etc/vintf/manifest.xml
, se uma das seguintes condições for verdadeira:
- A versão do kernel FCM é diferente da versão de destino do FCM. Por exemplo, o dispositivo mencionado acima tem um FCM de destino versão 4 e sua versão do kernel FCM é 5 (sufixo de ramificação do kernel
r
). - A versão do kernel FCM é maior ou igual a 5 (sufixo de ramificação do kernel
r
).
Os testes VTS impõem que, se a versão do FCM do kernel for especificada, a versão do FCM do kernel é maior ou igual à versão do FCM de destino no manifesto do dispositivo.
Exemplo: Determinar a ramificação do kernel
Se o dispositivo tiver o FCM de destino versão 4 (lançado no Android 10), mas executar o kernel da ramificação 4.19-r
, o manifesto do dispositivo deverá 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 em relação aos requisitos na ramificação do kernel 4.19-r
, que é especificada no FCM versão 5. Esses requisitos são criados a partir de 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 versão do kernel de /proc/version
for a seguinte:
5.4.42-android12-0-00544-ged21d463f856
Em seguida, o objeto VINTF obtém a versão do Android da versão do kernel e a usa para determinar a versão do kernel FCM. Neste exemplo, android12
significa kernel FCM versão 6 (lançado no Android 12).
Para obter detalhes sobre como a string de lançamento do kernel é analisada, consulte GKI versioning .
Corresponder às versões do kernel
Uma matriz pode incluir várias seções <kernel>
, cada uma com um atributo de 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 FCM correspondente com o mesmo ${ver}
e ${major_rev}
que o 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 deve ser um valor da matriz de compatibilidade ( ${kernel_minor_rev} >= ${matrix_minor_rev}
;). Se nenhuma seção <kernel>
atender a esses requisitos, não há 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 kernel FCM e a versão do kernel juntas selecionam os requisitos do kernel dos FCMs:
Versão de destino do FCM | Versão do kernel FCM | Versão do kernel | Combina com |
---|---|---|---|
3 (P) | não especificado | 4.4.106 | Sem correspondência (incompatibilidade de versão secundária) |
3 (P) | não especificado | 4.4.107 | 4.4-p |
3 (P) | não especificado | 4.19.42 | 4.19-q (veja nota abaixo) |
3 (P) | não especificado | 5.4.41 | 5.4-r (veja nota abaixo) |
3 (P) | 3 (P) | 4.4.107 | 4.4-p |
3 (P) | 3 (P) | 4.19.42 | Sem correspondência (sem ramificação do kernel 4.19-p ) |
3 (P) | 4 (Q) | 4.19.42 | 4.19-q |
4 (Q) | não especificado | 4.4.107 | Sem correspondência (sem ramificação do kernel 4.4-q ) |
4 (Q) | não especificado | 4.9.165 | 4.9-q |
4 (Q) | não especificado | 5.4.41 | 5.4-r (veja nota abaixo) |
4 (Q) | 4 (Q) | 4.9.165 | 4.9-q |
4 (Q) | 4 (Q) | 5.4.41 | Sem correspondência (sem ramificação do kernel 5.4-q ) |
4 (Q) | 5 (R) | 4.14.105 | 4.14-r |
4 (Q) | 5 (R) | 5.4.41 | 5.4-r |
5 (R) | não especificado | algum | Falha no VTS (deve especificar a versão do FCM do kernel para a versão 5 do FCM de destino) |
5 (R) | 4 (Q) | algum | Falha no VTS (versão do FCM do kernel < versão do FCM de destino) |
5 (R) | 5 (R) | 4.14.180 | 4.14-r |
Corresponder às configurações do kernel
Se a seção <kernel>
corresponder, o processo continuará tentando corresponder os elementos de config
com o /proc/config.gz
. Para cada elemento de configuração na matriz de compatibilidade, ele procura /proc/config.gz
para ver 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 deve estar ausente de /proc/config.gz
. Finalmente, 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 às configurações do kernel
-
<value type="string">bar</value>
corresponde a"bar"
. As cotações são omitidas na matriz de compatibilidade, mas estão presentes em/proc/config.gz
. -
<value type="int">4096</value>
corresponde a4096
ou0x1000
ou0X1000
. -
<value type="int">0x1000</value>
corresponde a4096
ou0x1000
ou0X1000
. -
<value type="int">0X1000</value>
corresponde a4096
ou0x1000
ou0X1000
. -
<value type="tristate">y</value>
corresponde ay
. -
<value type="tristate">m</value>
corresponde am
. -
<value type="tristate">n</value>
significa que o item de configuração NÃO deve existir em/proc/config.gz
. -
<value type="range">1-0x3</value>
corresponde a1
,2
ou3
ou equivalente hexadecimal.
Exemplo: correspondência de kernel bem-sucedida
Uma matriz de compatibilidade de estrutura com o FCM versão 1 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
, cujo padrão é manifest.level
se o primeiro não for especificado. Se a ramificação do kernel no manifesto do dispositivo:
- é 1, prossegue para a próxima etapa e verifica a versão do kernel.
- é 2, não corresponde à matriz. Os objetos VINTF lêem os requisitos do kernel da matriz no FCM versão 2.
Em seguida, a versão do kernel é correspondida. Se um dispositivo em uname()
relatar:
- 4.9.84 (sem correspondência com a matriz, a menos que haja uma seção de kernel separada com
<kernel version="4.9.x">
, ondex <= 84
) - 4.14.41 (sem correspondência com a matriz, menor que a
version
) - 4.14.42 (combinar com a matriz)
- 4.14.43 (combinar 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">
ondex <= 22
)
Após a seleção da seção <kernel>
apropriada, para cada item <config>
com valor diferente de n
, esperamos que a entrada correspondente esteja presente em /proc/config.gz
; para cada item <config>
com valor n
, esperamos que a entrada correspondente não esteja presente em /proc/config.gz
. Esperamos que o conteúdo de <value>
corresponda exatamente ao texto após o sinal de igual (incluindo aspas), até o caractere de nova linha ou #
, com espaços em branco iniciais e finais truncados.
A configuração do kernel a seguir é um exemplo de uma 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 do kernel a seguir é um exemplo de uma correspondência malsucedida:
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
A política de SE corresponde
A política SE requer as seguintes correspondências:
-
<sepolicy-version>
define um intervalo fechado de versões secundárias para cada versão principal. A versão de sepolicy informada pelo dispositivo deve estar dentro de um desses intervalos para ser compatível com a estrutura. As regras de correspondência são semelhantes às versões HAL; é uma correspondência se a versão da sepolicy for maior ou igual à versão mínima para o intervalo. A versão máxima é puramente informativa. -
<kernel-sepolicy-version>
ou seja, versão policydb. Deve ser menor que osecurity_policyvers()
relatado pelo dispositivo.
Exemplo: correspondência de política de SE bem-sucedida
A matriz de compatibilidade da estrutura indica as seguintes informações de 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()
deve ser maior ou igual a 30. Caso contrário, não é uma correspondência. Por exemplo:- Se um dispositivo retornar 29, não é uma correspondência.
- Se um dispositivo retornar 31, é uma correspondência.
- A versão da SE Policy deve ser 25.0-∞ ou 26.0-∞. Caso contrário, não é um jogo. (O "
-3
" após "26.0
" é meramente informativo.)
A versão do AVB corresponde
A versão AVB contém uma versão MAJOR e uma versão MINOR, com o formato MAJOR.MINOR (por exemplo, 1.0, 2.1). Para obter detalhes, consulte Controle de versão e compatibilidade . A versão AVB tem as seguintes propriedades do sistema:
-
ro.boot.vbmeta.avb_version
é a versãolibavb
no bootloader -
ro.boot.avb_version
é a versãolibavb
no sistema operacional Android (init/fs_mgr
)
A propriedade do sistema aparece apenas quando o libavb correspondente foi usado para verificar os metadados do AVB (e retorna OK). Está ausente se ocorreu uma falha de verificação (ou nenhuma verificação ocorreu).
Uma correspondência de compatibilidade compara o seguinte:
- sysprop
ro.boot.vbmeta.avb_version
comavb.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
comavb.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 bootloader ou o sistema operacional Android pode conter duas cópias das bibliotecas libavb
, cada uma com uma versão MAJOR diferente para dispositivos de atualização e dispositivos de inicialização. Nesse caso, a mesma imagem de sistema não assinada pode ser compartilhada, mas as imagens finais de sistema assinadas são diferentes (com avb.vbmeta-version
):
![](https://source.android.google.cn/docs/core/architecture/images/treble_vintf_avb_o_p.png?authuser=4&hl=pt-br)
/system
é P, todas as outras partições são O).![](https://source.android.google.cn/docs/core/architecture/images/treble_vintf_avb_p.png?authuser=4&hl=pt-br)
Exemplo: correspondência de versão AVB bem-sucedida
A matriz de compatibilidade da estrutura indica as seguintes informações do 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
Versão AVB correspondente durante OTA
Para dispositivos lançados com o Android 9 ou inferior, ao atualizar para o Android 10, os requisitos de versão do AVB na matriz de compatibilidade da estrutura são comparados com a versão atual do AVB no dispositivo. Se a versão AVB tiver uma atualização de versão principal durante uma OTA (por exemplo, de 0.0 para 1.0), a verificação de compatibilidade VINTF na OTA não refletirá a compatibilidade após a 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:
- Escolha os seguintes CLs para a árvore de origem do Android 9:
- Defina
BOARD_OTA_FRAMEWORK_VBMETA_VERSION_OVERRIDE
para o dispositivo. Seu valor deve ser igual à versão AVB anterior à OTA, ou seja, a versão AVB do dispositivo quando foi lançado. - Reconstrua o pacote OTA.
Essas alterações 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
emcompatibility.zip
no pacote OTA
Essas alterações não afetam outras matrizes de compatibilidade de estrutura, incluindo /system/etc/vintf/compatibility_matrix.xml
. Após o OTA, o novo valor em /system/etc/vintf/compatibility_matrix.xml
é usado para verificações de compatibilidade.
A versão do VNDK corresponde
A matriz de compatibilidade do dispositivo declara a versão VNDK necessária em compatibility-matrix.vendor-ndk.version
. Se a matriz de compatibilidade do dispositivo não tiver uma tag <vendor-ndk>
, nenhum requisito será imposto e, portanto, será sempre considerada uma correspondência.
Se a matriz de compatibilidade do dispositivo tiver uma marca <vendor-ndk>
, uma entrada <vendor-ndk>
com uma <version>
correspondente será pesquisada no conjunto de instantâneos do fornecedor VNDK fornecido pela estrutura no manifesto da estrutura. Se tal entrada não existir, não há correspondência.
Se tal entrada existir, o conjunto de bibliotecas enumeradas na matriz de compatibilidade do dispositivo deve ser um subconjunto do conjunto de bibliotecas indicado no manifesto da estrutura; 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 do dispositivo, a entrada será sempre considerada uma correspondência, pois o conjunto vazio é um subconjunto de qualquer conjunto.
Exemplo: correspondência de versão do VNDK bem-sucedida
Se a matriz de compatibilidade do dispositivo 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 o VNDK versão 27 está no manifesto da estrutura 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. Embora o VNDK versão 27 esteja no manifesto da estrutura, libjpeg.so
não é compatível com a estrutura nesse instantâneo. O VNDK versão 26 é ignorado.
A versão do SDK do sistema corresponde
A matriz de compatibilidade do dispositivo declara um conjunto de versões necessárias do SDK do sistema em compatibility-matrix.system-sdk.version
. Há uma correspondência apenas se o conjunto for um subconjunto das versões do SDK do sistema fornecidas, conforme declarado em manifest.system-sdk.version
no manifesto da estrutura.
- Como um caso especial, se nenhuma versão do SDK do sistema for enumerada na matriz de compatibilidade do dispositivo, sempre será considerada uma correspondência, pois o conjunto vazio é um subconjunto de qualquer conjunto.
Exemplo: correspondência de versão bem-sucedida do SDK do sistema
Se a matriz de compatibilidade do dispositivo indicar o seguinte requisito no SDK do sistema:
<!-- Example Device Compatibility Matrix --> <system-sdk> <version>26</version> <version>27</version> </system-sdk>
Em seguida, a estrutura deve fornecer as versões 26 e 27 do System SDK 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 o System SDK versão 27 não é fornecido.