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) em todas as linhas de produtos. Ele também propõe um procedimento para basear um SSI de propriedade do OEM em uma imagem de sistema genérico (GSI) criada 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 do sistema operacional genérico (a estrutura do sistema operacional Android). O software para cada um é instalado em uma partição separada: a partição do fornecedor para o software específico de hardware e a partição do sistema para o software genérico do sistema operacional. Uma interface com versão, denominada interface do fornecedor ( VINTF ), é definida e aplicada nas duas partições. Usando 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 a compatibilidade com versões anteriores de 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 útil 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 custo mais alto 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 das fontes da estrutura do sistema operacional Android para reutilização em vários dispositivos, para manter a compatibilidade com versões anteriores 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 conhecer 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 (somente a Etapa 1, por exemplo) depende de sua implementação.

Visão geral da 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 OEMs e fornecedores de SoC constroem SSIs que incluem todos os recursos personalizados e modificações de que um OEM precisa. Os mecanismos e as práticas recomendadas fornecidas nesta página destinam-se aos OEMs para atingir esses objetivos principais:

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

A ideia central de separar os componentes específicos do produto na partição do produto é semelhante à ideia da Treble de separar os componentes específicos do SoC na partição do fornecedor. Uma interface de produto (semelhante ao VINTF ) permite a comunicação entre 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 em imagens, que se tornam essencialmente partições.

Partições ao redor do SSI

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

Partitions and interfaces around SSI block diagram

Figura 1. Partições e interfaces em torno do 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 independentemente.
  • Uma partição é um local de armazenamento físico que pode ser atualizado independentemente.

As seções na 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 nenhum componente específico de hardware ou específico do produto. Tudo em um determinado SSI é, por definição, compartilhado entre todos os dispositivos que usam esse SSI. O SSI é composto de uma única imagem /system ou de uma partição /system e /system_ext , conforme mostrado 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 Java OEM que fornece APIs personalizadas para os próprios aplicativos do OEM se ajusta melhor em /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 pelo OEM.

    • A partição /system_ext é opcional, mas é útil 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 que você precisa fazer 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 OEM e extensões para o sistema operacional Android. Coloque os 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 (isso é opcional para enviar com o produto), o fornecedor de SoC pode colocar esse componente na imagem do produto. A localização de um componente não é determinada por sua propriedade , é ditada por 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 do ODM. Quando não há partição /odm separada, as imagens do fornecedor SoC e ODM são mescladas 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 Project Treble, que divide as imagens em partições de sistema e 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 SDK do Android
    • biblioteca Java SDK
  • Interfaces do produto : A interface do produto é a interface entre a SSI e a imagem do produto. Definir 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 ​​do VINTF. No entanto, apenas as APIs VNDK e Android SDK são aplicadas para dispositivos iniciados com o Android 11 (e superior).

Habilitando o SSI no Android 11

Esta seção explica como usar os novos recursos para dar suporte ao 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 acoplamento rígido com os componentes definidos por 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 em as duas partições. Os componentes na partição /system_ext podem fazer chamadas API privadas na partição /system , e os componentes na partição /system podem fazer chamadas API privadas na 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 na 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 projeto 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 rígido com a partição /system . Para mover um componente fortemente acoplado para a partição /product , a interface do produto deve ser estendida. Isso geralmente exigia que o próprio componente fosse extensivamente refatorado, o que consome 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 que são 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 usam os recursos do sistema sem nenhuma restrição e vice-versa. Para possibilitar o SSI 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 separada da partição /system e deve usar interfaces estáveis ​​de as partições /system e /system_ext .

A finalidade principal da partição /system_ext é estender os recursos do sistema, em vez de instalar módulos de produtos agrupados, conforme descrito na seção /system_ext partition . Para fazer isso, separe 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 a partição /system_ext comum .)

Para desagregar a partição /product dos componentes do sistema, a partição /product deve ter a mesma política de imposição da 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 separados 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 de 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 do 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. É usado para os 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 o GSI é usado como a 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 criarem a imagem do sistema a partir de fontes AOSP, eles poderão substituir a imagem do sistema que criaram com o GSI fornecido pelo AOSP. No entanto, os OEMs não precisam chegar à etapa final (usando o GSI como está) de uma só vez.

Etapa 1. Herdar generic_system.mk para a 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 por 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 a imagem do sistema do OEM

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

O OEM GSI 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 OEM GSI

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 AOSP GSI com o OEM GSI. Obtenha o AOSP GSI do alvo 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 permitida. Isso evita a necessidade de modificações adicionais no OEM GSI.

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 OEM GSI tenha os mesmos binários do AOSP GSI

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

Make OEM GSI have the same binaries as AOSP GSI

Figura 6. Fazendo o OEM GSI ter os mesmos binários do AOSP GSI

Definindo SSI para OEMs

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

Para evitar alterações específicas do produto na partição /system e definir o OEM GSI, 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 chamada da macro. Consulte o exemplo Criar makefile e ativar a verificação do caminho do artefato .

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

Aplicar interfaces de produtos

Para garantir que a partição /product seja desagregada, os OEMs podem garantir que seus dispositivos imponham 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 os dispositivos, porque pode ter módulos agrupados no sistema específicos do dispositivo. Como o SSI consiste nas 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 podem compartilhar esse SSI entre vários dispositivos removendo quaisquer diferenças e tornando a partição /system_ext comum.

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

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 preferencial de remover APIs ocultas dos aplicativos é encontrar as APIs públicas ou de sistema alternativas para substituí-las. Se não houver APIs para substituir as APIs ocultas, os OEMs podem contribuir com o AOSP para definir as novas APIs do 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 pode fornecer as 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.

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

Certos pacotes que acompanham o sistema não são comuns entre os dispositivos. Desempacotar esses módulos APK para movê-los para o produto ou para a partição do fornecedor pode ser difícil. Como uma solução provisória, os OEMs podem fazer o SSI incluir 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 de estrutura config_disableApkUnlessMatchedSku_skus_list e config_disableApksUnlessMatchedSku_apk_list .

Para configurações mais precisas, declare um broadcast receiver que desabilita pacotes desnecessários. O broadcast receiver chama setApplicationEnabledSetting para desabilitar o pacote ao receber a mensagem ACTION_BOOT_COMPLETED .

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

Uma sobreposição de recurso estático manipula os pacotes sobrepostos. No entanto, pode impedir a definição de um SSI, portanto, certifique-se de que as propriedades para RRO estejam ativadas e definidas corretamente. Definindo as propriedades da seguinte maneira, 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 confiar em um gerado automaticamente. Para obter informações detalhadas, consulte Runtime Resource Overlays (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 OEM GSI?

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

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

Não. A GSI tem 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.