Imagem do sistema compartilhado Android

Esta página apresenta vários mecanismos que os OEMs de dispositivos Android podem usar para ter sua própria imagem de sistema compartilhada (SSI) entre linhas de produtos. Ele também propõe um procedimento para basear um SSI de propriedade do OEM em uma imagem de sistema genérica (GSI) construída pelo AOSP.

Fundo

Com o Project Treble , o Android monolítico foi dividido em duas partes: a parte específica do hardware (a implementação do fornecedor) e a parte genérica do sistema operacional (a estrutura do sistema operacional Android). O software de cada um é instalado em uma partição separada: a partição do fornecedor para o software específico do hardware e a partição do sistema para o software genérico do sistema operacional. Uma interface versionada, chamada interface do fornecedor ( VINTF ), é definida e aplicada nas duas partições. Ao usar este sistema de particionamento, você pode modificar a partição do sistema sem modificar a partição do fornecedor e vice-versa.

Motivação

O código da estrutura lançado no AOSP é compatível com a arquitetura Treble e mantém compatibilidade retroativa com implementações de fornecedores mais antigos. Por exemplo, uma imagem de sistema genérica criada a partir de fontes AOSP do Android 10 pode ser executada em qualquer dispositivo compatível com Treble que esteja executando o Android 8 ou superior. A versão do Android fornecida em dispositivos de consumo é modificada por fornecedores de SoC e OEMs. (Consulte Vida de uma versão do Android .) Essas alterações e extensões feitas na estrutura não foram escritas para manter a compatibilidade com versões anteriores, o que se traduziu em maior complexidade e maior custo em uma atualização do sistema operacional. Alterações e modificações específicas do dispositivo aumentam o custo e a complexidade da atualização de uma versão do sistema operacional Android.

Antes do Android 11, não havia uma arquitetura clara que permitisse aos parceiros criar extensões modulares para a estrutura do sistema operacional Android. Este documento descreve as etapas que os fornecedores de SoC e OEMs podem seguir para criar um SSI. Isso significa uma imagem, criada a partir de fontes da estrutura do sistema operacional Android para reutilização em vários dispositivos, para manter a compatibilidade retroativa com implementações de fornecedores e para fornecer uma redução significativa na complexidade e no custo das atualizações do sistema operacional Android. Para obter as etapas específicas necessárias para criar um SSI, consulte a seção Etapas sugeridas para SSI baseado em GSI e observe que você não precisa usar todas as quatro etapas. Quais etapas você escolhe (apenas a Etapa 1, por exemplo) depende da sua implementação.

Visão geral do SSI

Com o SSI, os componentes de software específicos do produto e as extensões OEM são colocados em uma nova partição /product . Os componentes na partição /product usam uma interface estável e bem definida para interagir com os componentes na partição /system . Os OEMs podem optar por criar um SSI ou ter um pequeno número de SSIs para uso em vários SKUs de dispositivos. Quando uma nova versão do sistema operacional Android é lançada, os OEMs investem apenas uma vez na atualização de seus SSIs para a versão mais recente do Android. Eles podem reutilizar os SSIs para atualizar vários dispositivos sem atualizar a partição /product .

Observe que os OEMs e os fornecedores de SoC criam SSIs que incluem todos os recursos personalizados e modificações que um OEM precisa. Os mecanismos e práticas recomendadas fornecidos nesta página destinam-se a serem usados ​​pelos OEMs para atingir estes objetivos principais:

  • Reutilize o SSI em vários SKUs de dispositivos.
  • Atualize o sistema Android com extensões modulares para facilitar as atualizações do sistema operacional.

A ideia central de separar componentes específicos do produto na partição do produto é semelhante à ideia do Treble de separar componentes específicos do SoC na partição do fornecedor. Uma interface de produto (semelhante ao VINTF ) permite a comunicação entre o SSI e a partição do produto. Observe que com relação ao SSI, o termo “componentes” descreve todos os recursos, binários, textos, bibliotecas e assim por diante que são instalados nas imagens, que essencialmente se tornam partições.

Partições em torno do SSI

A Figura 1 mostra partições em torno do SSI e as interfaces com versão nas partições e políticas nas interfaces. Esta seção explica detalhadamente cada uma das partições e interfaces.

Partitions and interfaces around SSI block diagram

Figura 1. Partições e interfaces em torno de SSI

Imagens e partições

As informações nesta seção distinguem entre os termos imagem e partição .

  • Uma imagem é um software conceitual que pode ser atualizado de forma independente.
  • Uma partição é um local de armazenamento físico que pode ser atualizado de forma independente.

As seções da Figura 1 são definidas da seguinte forma:

  • SSI: O SSI é a imagem comum a um OEM e pode existir em vários dispositivos. Ele não possui componentes específicos de hardware ou de produto. Tudo em um determinado SSI é, por definição, compartilhado entre todos os dispositivos que utilizam esse SSI. O SSI é composto por uma única imagem /system ou por uma partição /system e /system_ext , como visto na Figura 1.

    • A partição /system contém componentes baseados em AOSP, enquanto /system_ext , quando implementado, contém extensões e componentes de fornecedores OEM e SoC que são fortemente acoplados aos componentes AOSP. Por exemplo, uma biblioteca de estrutura OEM Java que fornece APIs personalizadas para os próprios aplicativos do OEM se ajusta melhor na /system_ext do que na partição /system . O conteúdo das partições /system e /system_ext é criado a partir de fontes Android modificadas por OEM.

    • A partição /system_ext é opcional, mas é benéfico usá-la para quaisquer recursos e extensões personalizados que estejam fortemente acoplados a componentes baseados em AOSP. Essa distinção ajuda a identificar as alterações necessárias para mover esses componentes da partição /system_ext para a partição /product durante um período de tempo.

  • Produto: uma coleção de componentes específicos de produtos ou dispositivos que representam personalizações e extensões de OEM para o sistema operacional Android. Coloque componentes específicos do SoC na partição /vendor . Os fornecedores de SoC também podem usar a partição /product para componentes apropriados, como os independentes de SoC. Por exemplo, se um fornecedor de SoC fornecer um componente independente de SoC para seus clientes OEM (que é opcional para envio com o produto), o fornecedor de SoC poderá colocar esse componente na imagem do produto. A localização de um componente não é determinada pela sua propriedade , é ditada pela sua finalidade .

  • Fornecedor : uma coleção de componentes específicos do SoC.

  • ODM: Uma coleção de componentes específicos da placa que não são fornecidos pelo SoC. Normalmente, o fornecedor do SoC possui a imagem do fornecedor, enquanto o fabricante do dispositivo possui a imagem ODM. Quando não há partição /odm separada, o fornecedor SoC e as imagens ODM são mesclados na partição /vendor .

Interfaces entre imagens

Existem duas interfaces principais para imagens de fornecedores e produtos em torno do SSI:

  • Interface do fornecedor (VINTF) : VINTF é a interface para os componentes que residem no fornecedor e nas imagens ODM. Os componentes nas imagens do produto e do sistema só podem interagir com as imagens do fornecedor e do ODM por meio dessa interface. Por exemplo, uma imagem de fornecedor não pode depender de uma parte privada da imagem do sistema e vice-versa. Isso é originalmente definido no Projeto Treble, que divide as imagens em partições de sistema e de fornecedor. A interface é descrita usando os seguintes mecanismos:

    • HIDL (Passthrough HAL está disponível apenas para módulos system e system_ext )
    • AIDL estável
    • Configurações
      • API de propriedades do sistema
      • API de esquema de arquivo de configuração
    • VNDK
    • APIs do Android SDK
    • Biblioteca Java SDK
  • Interfaces do produto : A interface do produto é a interface entre o SSI e a imagem do produto. A definição de uma interface estável separa os componentes do produto dos componentes do sistema em um SSI. A interface do produto requer as mesmas interfaces estáveis ​​que o VINTF. No entanto, apenas as APIs VNDK e Android SDK são aplicadas para dispositivos lançados com Android 11 (e versões posteriores).

Habilitando SSI no Android 11

Esta seção explica como usar os novos recursos implementados para oferecer suporte a SSI no Android 11.

A partição /system_ext

A partição /system_ext foi introduzida no Android 11 como uma partição opcional. (É o local para componentes não-AOSP que possuem forte acoplamento com os componentes definidos pelo AOSP na partição /system .) A partição /system_ext é considerada a extensão específica do OEM para a partição /system , sem uma interface definida entre as duas partições. Os componentes na partição /system_ext podem fazer chamadas de API privadas para a partição /system e os componentes na partição /system podem fazer chamadas de API privadas para a partição /system_ext .

Como as duas partições estão fortemente acopladas, ambas as partições são atualizadas juntas quando uma nova versão do Android é lançada. Uma partição /system_ext criada para a versão anterior do Android não precisa ser compatível com a partição /system da próxima versão do Android.

Para instalar um módulo na partição /system_ext , adicione system_ext_specific: true ao arquivo Android.bp . Para dispositivos que não possuem uma partição /system_ext , instale esses módulos no subdiretório ./system_ext na partição /system .

História

Aqui está um pouco da história sobre a partição /system_ext . O objetivo do design era colocar todos os componentes específicos do OEM, independentemente de serem comuns, na partição /product . No entanto, movê-los todos de uma vez não era viável, especialmente quando alguns componentes tinham um acoplamento forte com a partição /system . Para mover um componente fortemente acoplado para a partição /product , a interface do produto deve ser estendida. Muitas vezes, isso exigia que o próprio componente fosse extensivamente refatorado, o que consumia muito tempo e esforço. A partição /system_ext começou como um local para hospedar temporariamente os componentes que não estão prontos para serem movidos para a partição /product . O objetivo do SSI era eventualmente eliminar a partição /system_ext .

No entanto, a partição /system_ext é útil para manter a partição /system o mais próximo possível do AOSP. Com o SSI, a maior parte do esforço de atualização é gasta nos componentes nas partições /system e /system_ext . Quando a imagem do sistema é construída a partir de fontes tão semelhantes quanto possível às do AOSP, você pode concentrar o esforço de atualização na imagem system_ext .

Desempacotando componentes das partições /system e /system_ext na partição /product

O Android 9 introduziu uma partição /product que é acoplada à partição /system . Os módulos na partição /product utilizam os recursos do sistema sem qualquer restrição e vice-versa. Para tornar o SSI possível no Android 10, os componentes do produto são divididos nas partições /system_ext e /product . A partição /system_ext não precisa aderir às restrições de uso de componentes do sistema que a partição /product fazia no Android 9. A partir do Android 10, a partição /product deve ser desagregada da partição /system e deve usar interfaces estáveis ​​de as partições /system e /system_ext .

O objetivo principal da partição /system_ext é estender os recursos do sistema, em vez de instalar módulos de produto agrupados, conforme descrito na seção /system_ext partition . Para fazer isso, desagrupe os módulos específicos do produto e mova-os para a partição /product . A separação dos módulos específicos do produto torna /system_ext comum aos dispositivos. (Para obter mais detalhes, consulte Tornando comum a partição /system_ext .)

Para desagregar a partição /product dos componentes do sistema, a partição /product deve ter a mesma política de aplicação que a partição /vendor que já foi desagregada com o Project Treble.

A partir do Android 11, as interfaces nativas e Java para a partição /product são aplicadas conforme descrito abaixo. Para obter mais informações, consulte Aplicação de interfaces de partição de produto .

  • Interfaces nativas : os módulos nativos na partição /product devem ser desagregados das outras partições. As únicas dependências permitidas dos módulos do produto são algumas bibliotecas VNDK (incluindo LLNDK) da partição /system . As bibliotecas JNI das quais os aplicativos do produto dependem devem ser bibliotecas NDK.
  • Interfaces Java : os módulos Java (app) na partição /product não podem usar APIs ocultas porque são instáveis. Esses módulos devem usar apenas APIs públicas e APIs de sistema da partição /system e bibliotecas Java SDK na partição /system ou /system_ext . Você pode definir bibliotecas Java SDK para APIs customizadas.

Etapas sugeridas para SSI baseado em GSI

Suggested partitions for GSI-based SSI

Figura 2. Partições sugeridas para SSI baseado em GSI

Uma imagem genérica do sistema (GSI) é a imagem do sistema criada diretamente do AOSP. Ele é usado para testes de conformidade do Treble (por exemplo, CTS-on-GSI) e como uma plataforma de referência que os desenvolvedores de aplicativos podem usar para testar a compatibilidade de seus aplicativos quando não possuem um dispositivo real executando a versão necessária do Android.

Os OEMs também podem usar o GSI para fazer seu SSI. Conforme explicado em Imagens e partições , o SSI consiste na imagem do sistema para os componentes definidos pelo AOSP e na imagem system_ext para os componentes definidos pelo OEM. Quando GSI é usado como imagem do system , o OEM pode se concentrar na imagem system_ext para a atualização.

Esta seção fornece um guia para OEMs que desejam modularizar suas personalizações nas partições /system_ext e /product enquanto usam uma imagem de sistema AOSP ou quase AOSP. Se os OEMs construírem a imagem do sistema a partir de fontes AOSP, eles poderão substituir a imagem do sistema que construíram pelo GSI fornecido pelo AOSP. No entanto, os OEMs não precisam chegar à etapa final (usando o GSI como ele é) de uma só vez.

Etapa 1. Herdando generic_system.mk para imagem do sistema OEM (OEM GSI)

Ao herdar generic_system.mk (que foi nomeado mainline_system.mk no Android 11 e renomeado para generic_system.mk no AOSP), a imagem do sistema (OEM GSI) inclui todos os arquivos que o AOSP GSI possui. Esses arquivos podem ser modificados pelos OEMs, para que o OEM GSI possa conter os arquivos proprietários do OEM, além dos arquivos AOSP GSI. No entanto, os OEMs não têm permissão para modificar o próprio arquivo generic_system.mk .

Inheriting `generic_system.mk` for OEM system image

Figura 3. Herdando generic_system.mk para imagem de sistema do OEM

Etapa 2. Fazer com que o GSI OEM tenha a mesma lista de arquivos do GSI AOSP

O GSI OEM não pode ter arquivos adicionais neste estágio. Os arquivos proprietários do OEM devem ser movidos para as partições system_ext ou product .

Moving added files out of the OEM GSI

Figura 4. Movendo arquivos adicionados para fora do GSI OEM

Etapa 3. Definir uma lista de permissões para limitar os arquivos modificados no OEM GSI

Para verificar os arquivos modificados, os OEMs podem usar a ferramenta compare_images e comparar o GSI AOSP com o GSI OEM. Obtenha o GSI AOSP do destino de almoço AOSP generic_system_* .

Ao executar a ferramenta compare_images periodicamente com o parâmetro allowlist , você pode monitorar as diferenças fora da lista de permissões. Isso evita a necessidade de modificações adicionais no GSI OEM.

Define an allowlist to reduce the list of modified files in OEM GSI

Figura 5. Definir uma lista de permissões para reduzir a lista de arquivos modificados no OEM GSI

Etapa 4. Fazer com que o GSI OEM tenha os mesmos binários que o GSI AOSP

A limpeza da lista de permissões permite que os OEMs usem o AOSP GSI como imagem do sistema para seus próprios produtos. Para limpar a lista de permissões, os OEMs podem abandonar suas alterações no GSI OEM ou fazer upload de suas alterações para o AOSP para que o GSI AOSP inclua suas alterações.

Make OEM GSI have the same binaries as AOSP GSI

Figura 6. Fazendo com que o GSI OEM tenha os mesmos binários que o GSI AOSP

Definição de SSI para OEMs

Proteja a partição /system em tempo de compilação

Para evitar quaisquer alterações específicas do produto na partição /system e definir o GSI OEM, os OEMs podem usar uma macro makefile chamada require-artifacts-in-path para evitar qualquer declaração de módulos do sistema após a macro ser chamada. Consulte o exemplo Criar makefile e ativar a verificação do caminho do artefato .

Os OEMs podem definir uma lista para permitir que módulos específicos do produto sejam instalados temporariamente na partição /system . No entanto, a lista deve estar vazia para tornar o GSI OEM comum a todos os produtos do OEM. Este processo serve para definir o GSI OEM e pode ser independente das etapas do GSI AOSP .

Aplicar interfaces de produtos

Para garantir que a partição /product seja desagregada, os OEMs podem garantir que seus dispositivos apliquem as interfaces do produto definindo PRODUCT_PRODUCT_VNDK_VERSION:= current para módulos nativos e PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE:= true para módulos Java. Essas variáveis ​​são definidas automaticamente se o PRODUCT_SHIPPING_API_LEVEL do dispositivo for maior ou igual a 30 . Para obter informações detalhadas, consulte Aplicação de interfaces de partição de produto .

Tornando a partição /system_ext comum

A partição /system_ext pode diferir entre dispositivos, porque pode ter módulos específicos do dispositivo e agrupados no sistema. Como o SSI consiste em partições /system e /system_ext , as diferenças na partição /system_ext impedem que os OEMs definam um SSI. Os OEMs podem ter seu próprio SSI e compartilhá-lo entre vários dispositivos, removendo quaisquer diferenças e tornando comum a partição /system_ext .

Esta seção fornece recomendações para tornar comum a partição /system_ext .

Expor APIs ocultas na partição do sistema

Muitos aplicativos específicos do produto não podem ser instalados na partição do produto porque usam APIs ocultas, que são proibidas na partição do produto. Para mover aplicativos específicos do dispositivo para a partição do produto, remova o uso de APIs ocultas.

A maneira preferida de remover APIs ocultas dos aplicativos é encontrar APIs públicas ou de sistema alternativas para substituí-las. Se não houver APIs para substituir as APIs ocultas, os OEMs poderão contribuir com o AOSP para definir as novas APIs de sistema para seus dispositivos.

Como alternativa, os OEMs podem definir APIs personalizadas criando sua própria biblioteca Java SDK na partição /system_ext . Ele pode usar APIs ocultas na partição do sistema e fornecer APIs para os aplicativos na partição do produto ou do fornecedor. Os OEMs devem congelar as APIs voltadas para o produto para compatibilidade com versões anteriores.

Incluir o superconjunto de todos os APKs e pular algumas instalações de pacotes para cada dispositivo

Certos pacotes incluídos no sistema não são comuns entre dispositivos. Pode ser difícil desagrupar esses módulos APK para movê-los para a partição do produto ou do fornecedor. Como solução provisória, os OEMs podem fazer com que o SSI inclua todos os módulos e, em seguida, filtrar os indesejados usando uma propriedade SKU ( ro.boot.hardware.sku ). Para usar o filtro, os OEMs sobrepõem os recursos da estrutura config_disableApkUnlessMatchedSku_skus_list e config_disableApksUnlessMatchedSku_apk_list .

Para configurações mais precisas, declare um receptor de transmissão que desabilite pacotes desnecessários. O receptor de transmissão chama setApplicationEnabledSetting para desabilitar o pacote quando recebe a mensagem ACTION_BOOT_COMPLETED .

Defina RRO em vez de usar sobreposição de recursos estáticos

Uma sobreposição de recursos estáticos manipula os pacotes sobrepostos. No entanto, isso pode impedir a definição de um SSI, portanto, certifique-se de que as propriedades do RRO estejam ativadas e definidas corretamente. Ao definir as propriedades da seguinte forma, os OEMs podem ter todas as sobreposições geradas automaticamente como RROs.

PRODUCT_ENFORCE_RRO_TARGETS := *
PRODUCT_ENFORCE_RRO_EXCLUDED_OVERLAYS := # leave it empty

Se for necessária uma configuração detalhada, defina um RRO manualmente em vez de depender de um gerado automaticamente. Para obter informações detalhadas, consulte Sobreposições de recursos de tempo de execução (RROs) . Os OEMs também podem definir RROs condicionais que dependem das propriedades do sistema usando os atributos android:requiredSystemPropertyName e android:requiredSystemPropertyValue .

Perguntas frequentes (FAQ)

Posso definir vários SSIs?

Depende da semelhança e das características dos dispositivos (ou grupo de dispositivos). Os OEMs podem tentar tornar a partição system_ext comum, conforme descrito em Tornando a partição system_ext comum . Se um grupo de dispositivos tiver muitas diferenças, é melhor definir vários SSIs.

Posso modificar generic_system.mk ( mainline_system.mk ) para um GSI OEM?

Não. Mas os OEMs podem definir um novo makefile para um GSI OEM que herda o arquivo generic_system.mk e usar o novo makefile. Por exemplo, consulte Aplicação de interfaces de partição de produto .

Posso remover módulos de generic_system.mk que entrem em conflito com minha implementação?

Não. O GSI possui um conjunto mínimo de módulos inicializáveis ​​e testáveis. Se você acha que um módulo não é essencial, registre um bug para atualizar o arquivo generic_system.mk no AOSP.