Visão geral do Kit de desenvolvimento nativo do fornecedor (VNDK)

O Kit de desenvolvimento nativo do fornecedor (VNDK, na sigla em inglês) é um conjunto de bibliotecas usadas por outras bibliotecas ou binários, na partição do fornecedor ou do produto, no tempo de execução para dlopen.

Previsão de remoção

O NDK do fornecedor foi introduzido no Android 8.0 para fornecer APIs entre o framework e o código do fornecedor. Embora o VNDK seja usado há muitos anos, ele tem algumas desvantagens:
  • Armazenamento
    • Um único APEX do VNDK empacota todas as bibliotecas do VNDK, sejam elas usadas no dispositivo ou não.
    • O GSI contém várias versões de APEXes do VNDK para oferecer suporte a várias versões de imagens do fornecedor.
  • Capacidade de atualização
    • É difícil atualizar os APEXes do VNDK separadamente da atualização da plataforma.
    • As imagens do fornecedor são atualizadas com frequência over the air (OTA), o que reduz os benefícios de ter o VNDK empacotado na imagem do sistema.
Com base nesses problemas, decidimos descontinuar o uso do VNDK a partir do Android 15.

Detalhes sobre a descontinuação do VNDK

Todas as bibliotecas do VNDK são empacotadas no APEX do VNDK e instaladas na imagem do sistema (-ext). Com a descontinuação do VNDK, as bibliotecas anteriores do VNDK são instaladas na imagem do fornecedor (ou do produto), assim como outras bibliotecas disponíveis do fornecedor. Estes recursos são removidos com a descontinuação do VNDK:
  • VNDK APEX para Android 15
  • As propriedades do sistema que indicam a versão do VNDK de destino são removidas se as partições do fornecedor ou do produto forem criadas para o Android 15:
    • ro.vndk.version
    • ro.product.vndk.version
  • As otimizações do VNDK não estarão disponíveis, porque não há um VNDK:
    • TARGET_VNDK_USING_CORE_VARIANT para dispositivos Android Go
    • use_vndk_as_stable para APEXes de fornecedores
  • Snapshot do fornecedor, que é altamente dependente do VNDK

Exceções à descontinuação

Estes recursos não vão mudar com a descontinuação do uso do VNDK:
  • APEXes do VNDK com a versão 14 ou anterior do VNDK, que são necessárias para oferecer suporte a imagens de fornecedores.
  • O LL-NDK não faz parte do VNDK.

Por que usar o VNDK?

O AOSP permite atualizações somente do framework em que a partição do sistema pode ser atualizada para a versão mais recente do framework, enquanto a partição do fornecedor permanece inalterada. Apesar de serem criados em momentos diferentes, os binários em cada partição precisam funcionar entre si.

As atualizações exclusivas do framework incluem os seguintes desafios:

  • Dependência entre módulos de framework e módulos de fornecedores. Antes do Android 8.0, os módulos na partição do fornecedor e do sistema podiam se vincular entre si. No entanto, as dependências dos módulos do fornecedor impuseram restrições indesejáveis ao desenvolvimento de módulos de framework.
  • Extensões para bibliotecas do AOSP. O Android exige que todos os dispositivos Android passem no CTS quando a partição do sistema é substituída por uma imagem genérica do sistema (GSI) padrão. No entanto, como os fornecedores estendem as bibliotecas do AOSP para aumentar o desempenho ou adicionar funcionalidades extras às implementações de HIDL, atualizar a partição do sistema com um GSI padrão pode interromper a implementação de HIDL de um fornecedor. Para ver diretrizes sobre como evitar essas falhas, consulte Extensões do VNDK.

Para resolver esses desafios, o Android contém vários recursos, como o VNDK (descrito nesta seção), HIDL, hwbinder, sobreposição de árvore de dispositivos e sobreposição de sepolicy.

Termos específicos do VNDK

Os documentos relacionados ao VNDK usam a seguinte terminologia:
  • Módulos se referem a bibliotecas compartilhadas ou executáveis. Os módulos criam dependências no momento do build.
  • Processos são tarefas do sistema operacional geradas por executáveis. Os processos criam dependências de tempo de execução.
  • Os termos qualificados por framework estão relacionados à partição system:
    • Executáveis do framework se referem a executáveis em /system/bin ou /system/xbin.
    • As bibliotecas compartilhadas do framework se referem às bibliotecas compartilhadas em /system/lib[64].
    • Os módulos do framework se referem às bibliotecas compartilhadas do framework e aos executáveis do framework.
    • Os processos do framework são processos gerados a partir de executáveis do framework, como /system/bin/app_process.
  • Os termos qualificados pelo fornecedor estão relacionados às partições vendor:
    • Executáveis do fornecedor se referem a executáveis em /vendor/bin
    • As bibliotecas compartilhadas do fornecedor se referem às bibliotecas compartilhadas em /vendor/lib[64].
    • Os módulos do fornecedor se referem aos executáveis e às bibliotecas compartilhadas do fornecedor.
    • Os processos do fornecedor são processos gerados por executáveis do fornecedor, como /vendor/bin/android.hardware.camera.provider@2.4-service.

Conceitos do VNDK

Em um mundo ideal do Android 8.0 e versões mais recentes, os processos do framework não carregam bibliotecas compartilhadas do fornecedor. Todos os processos do fornecedor carregam apenas bibliotecas compartilhadas do fornecedor (e uma parte das bibliotecas compartilhadas do framework). As comunicações entre processos do framework e do fornecedor são governadas por HIDL e pelo vinculativo de hardware.

Esse mundo inclui a possibilidade de que APIs públicas e estáveis de bibliotecas compartilhadas do framework não sejam suficientes para desenvolvedores de módulos de fornecedores (embora as APIs possam mudar entre as versões do Android), exigindo que parte das bibliotecas compartilhadas do framework seja acessível aos processos do fornecedor. Além disso, como os requisitos de desempenho podem levar a concessões, algumas HALs críticas ao tempo de resposta precisam ser tratadas de maneira diferente.

As seções a seguir detalham como o VNDK lida com bibliotecas compartilhadas de framework para fornecedores e HALs do mesmo processo (SP-HALs, na sigla em inglês).

Bibliotecas compartilhadas do framework para o fornecedor

Esta seção descreve os critérios para classificar bibliotecas compartilhadas que são acessíveis aos processos do fornecedor. Há duas abordagens para oferecer suporte a módulos do fornecedor em várias versões do Android:

  1. Estabilizar as ABIs/APIs das bibliotecas compartilhadas do framework. Os novos módulos do framework e os antigos módulos do fornecedor podem usar a mesma biblioteca compartilhada para reduzir o espaço de memória e o tamanho de armazenamento. Uma biblioteca compartilhada única também evita vários problemas de carregamento duplo. No entanto, o custo de desenvolvimento para manter ABIs/APIs estáveis é alto, e não é realista estabilizar todas as ABIs/APIs exportadas por todas as bibliotecas compartilhadas do framework.
  2. Copie as bibliotecas compartilhadas do framework antigo. Vem com a restrição forte contra canais secundários, definidos como todos os mecanismos para se comunicar entre módulos de framework e módulos de fornecedores, incluindo (mas não se limitando a) binder, soquete, pipe, memória compartilhada, arquivo compartilhado e propriedades do sistema. Não deve haver comunicação, a menos que o protocolo de comunicação esteja congelado e estável (por exemplo, HIDL pelo hwbinder). O carregamento duplo de bibliotecas compartilhadas também pode causar problemas. Por exemplo, se um objeto criado pela nova biblioteca for transmitido para as funções da biblioteca antiga, um erro poderá ocorrer, já que essas bibliotecas podem interpretar o objeto de maneira diferente.

São usadas abordagens diferentes, dependendo das características das bibliotecas compartilhadas. Como resultado, as bibliotecas compartilhadas do framework são classificadas em três subcategorias:

  • As bibliotecas LL-NDK são bibliotecas compartilhadas do framework que são conhecidas por serem estáveis. Os desenvolvedores se comprometeram a manter a estabilidade da API/ABI.
    • O LL-NDK inclui as seguintes bibliotecas: libEGL.so, libGLESv1_CM.so, libGLESv2.so, libGLESv3.so, libandroid_net.so, libc.so, libdl.so, liblog.so, libm.so, libnativewindow.so, libneuralnetworks.so, libsync.so, libvndksupport.so e libvulkan.so.
  • As bibliotecas do VNDK (VNDK) qualificadas são bibliotecas compartilhadas do framework que podem ser copiadas com segurança duas vezes. Os módulos do framework e do fornecedor podem ser vinculados às próprias cópias. Uma biblioteca compartilhada do framework só pode se tornar uma biblioteca qualificada do VNDK se atender aos seguintes critérios:
    • Ele não envia/recebe IPCs para/do framework.
    • Não está relacionado à máquina virtual do ART.
    • Ele não lê/grava arquivos/partições com formatos de arquivo instáveis.
    • Ele não tem uma licença de software especial que exige análises jurídicas.
    • O proprietário do código não tem objeções ao uso do fornecedor.
  • As bibliotecas somente para framework (FWK-ONLY) são bibliotecas compartilhadas de framework que não pertencem às categorias mencionadas acima. Estas bibliotecas:
    • São considerados detalhes de implementação internos do framework.
    • Não pode ser acessado por módulos do fornecedor.
    • Têm ABIs/APIs instáveis e não têm garantias de compatibilidade com a API/ABI.
    • Não são copiados.

HAL de mesmo processo (SP-HAL, na sigla em inglês)

A HAL do mesmo processo (SP-HAL) é um conjunto de HALs predeterminadas implementadas como bibliotecas compartilhadas do fornecedor e carregadas em processos de framework. As SP-HALs são isoladas por um namespace de linker (controla as bibliotecas e os símbolos que são visíveis para as bibliotecas compartilhadas). As SP-HALs precisam depender apenas de LL-NDK e VNDK-SP.

O VNDK-SP é um subconjunto predefinido de bibliotecas do VNDK qualificadas. As bibliotecas do VNDK-SP são analisadas com cuidado para garantir que o carregamento duplo de bibliotecas do VNDK-SP nos processos do framework não cause problemas. Tanto os SP-HALs quanto os VNDK-SPs são definidos pelo Google.

As bibliotecas a seguir são SP-HALs aprovadas:

  • libGLESv1_CM_${driver}.so
  • libGLESv2_${driver}.so
  • libGLESv3_${driver}.so
  • libEGL_${driver}.so
  • vulkan.${driver}.so
  • android.hardware.renderscript@1.0-impl.so
  • android.hardware.graphics.mapper@2.0-impl.so

As bibliotecas do VNDK-SP especificam vndk: { support_system_process: true } nos arquivos Android.bp. Se vndk: {private:true} também for especificado, essas bibliotecas serão chamadas de VNDK-SP-Private e serão invisíveis para SP-HALs.

As seguintes são bibliotecas somente de framework com exceções de RS (FWK-ONLY-RS):

  • libft2.so (Renderscript)
  • libmediandk.so (Renderscript)

Controle de versões do VNDK

As bibliotecas compartilhadas do VNDK têm versões:

  • A propriedade do sistema ro.vndk.version é adicionada automaticamente a /vendor/default.prop.
  • As bibliotecas compartilhadas do VNDK e do VNDK-SP são instaladas como um com.android.vndk.v${ro.vndk.version} máximo do VNDK e montadas em /apex/com.android.vndk.v${ro.vndk.version}.

O valor de ro.vndk.version é escolhido pelo algoritmo abaixo:

  • Se BOARD_VNDK_VERSION não for igual a current, use BOARD_VNDK_VERSION.
  • Se BOARD_VNDK_VERSION for igual a current:
    • Se PLATFORM_VERSION_CODENAME for REL, use PLATFORM_SDK_VERSION (por exemplo, 28).
    • Caso contrário, use PLATFORM_VERSION_CODENAME (por exemplo, P).

Teste de fornecedor (VTS)

O Conjunto de teste de fornecedor do Android (VTS) exige uma propriedade ro.vndk.version não vazia. Os dispositivos recém-lançados e os que estão sendo atualizados precisam definir ro.vndk.version. Alguns casos de teste do VNDK (por exemplo, VtsVndkFilesTest e VtsVndkDependencyTest) dependem da propriedade ro.vndk.version para carregar os conjuntos de dados de bibliotecas do VNDK qualificados correspondentes.