Imagem do sistema compartilhada do Android

Esta página apresenta vários mecanismos que os OEMs de dispositivos Android podem usar para ter a própria imagem compartilhada do sistema (SSI, na sigla em inglês) em todas as linhas de produtos. Ele também propõe um procedimento para basear uma SSI de propriedade do OEM em uma imagem genérica do sistema (GSI) criada pelo AOSP.

Contexto

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 SO (o framework do SO 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 SO. Uma interface com controle de versão, chamada de interface do fornecedor (VINTF), é definida e aplicada nas duas partições. Com esse sistema de particionamento, é possível modificar a partição do sistema sem alterar a partição do fornecedor e vice-versa.

Motivação

O código do framework lançado no AOSP está em conformidade com a arquitetura Treble e manteve a compatibilidade com versões anteriores de implementações de fornecedores mais antigos. Por exemplo, uma imagem genérica do sistema criada com base em fontes do AOSP do Android 10 pode ser executada em qualquer dispositivo compatível com o Treble que esteja usando o Android 8 ou versões mais recentes. A versão do Android enviada em dispositivos do consumidor é modificada por fornecedores de SoC e OEMs. Consulte Ciclo de vida de uma versão do Android. Essas mudanças e extensões feitas no framework não foram escritas para manter a compatibilidade com versões anteriores, o que resultou em maior complexidade e custo mais alto em uma atualização do SO. Mudanças e modificações específicas do dispositivo aumentam o custo e a complexidade da atualização de uma versão do SO Android.

Antes do Android 11, não havia uma arquitetura clara que permitisse aos parceiros criar extensões modulares para o framework do SO Android. Este documento descreve as etapas que fornecedores de SoC e OEMs podem seguir para criar uma SSI. Isso significa uma imagem, criada com base nas fontes do framework do SO Android para reutilização em vários dispositivos, para manter a compatibilidade com versões anteriores de implementações de fornecedores e para reduzir significativamente a complexidade e o custo das atualizações do SO Android. Para saber as etapas específicas necessárias para criar uma SSI, consulte a seção Etapas sugeridas para SSI baseada em GSI. Não é necessário usar todas as quatro etapas. As etapas escolhidas (apenas a etapa 1, por exemplo) dependem da sua implementação.

Visão geral do SSI

Com o SSI, os componentes de software específicos do produto e as extensões do OEM são colocados em uma nova partição /product. Os componentes na partição /product usam uma interface bem definida e estável para interagir com os componentes na partição /system. Os OEMs podem criar uma SSI ou ter um pequeno número de SSIs para uso em vários SKUs de dispositivos. Quando uma nova versão do SO Android é lançada, os OEMs investem apenas uma vez na atualização das 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.

Os OEMs e fornecedores de SoC criam SSIs que incluem todos os recursos e modificações personalizados necessários para um OEM. Os mecanismos e as práticas recomendadas fornecidos nesta página são destinados a OEMs para alcançar estes objetivos principais:

  • Reutilize o SSI em várias SKUs de dispositivos.
  • Atualize o sistema Android com as extensões modulares para facilitar os upgrades do SO.

A ideia principal 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 a SSI e a partição do produto. Em relação ao SSI, o termo "componentes" descreve todos os recursos, binários, textos, bibliotecas etc. instalados nas imagens, que essencialmente se tornam partições.

Partições em torno da SSI

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

Partições e interfaces ao redor do diagrama de blocos de SSI

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

Imagens e partições

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

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

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

  • SSI:a SSI é a imagem comum a um OEM e pode existir em vários dispositivos. Ele não tem componentes específicos de hardware ou de produto. Por definição, tudo em uma determinada SSI é compartilhado entre todos os dispositivos que a usam. O SSI é composto por uma única imagem /system ou por um /system e as partições /system_ext, conforme mostrado na Figura 1.

    • A partição /system contém componentes baseados no AOSP, enquanto /system_ext, quando implementada, contém extensões e componentes de OEM e fornecedor de SoC que são fortemente acoplados aos componentes do AOSP. Por exemplo, uma biblioteca de framework Java OEM que fornece APIs personalizadas para os próprios apps do OEM se encaixa melhor na partição /system_ext do que na /system. O conteúdo das partições /system e /system_ext é criado com base em fontes do Android modificadas pelo OEM.

    • A partição /system_ext é opcional, mas é recomendável usá-la para recursos e extensões personalizados que estão fortemente acoplados a componentes baseados no AOSP. Essa distinção ajuda você a identificar as mudanças necessárias para mover esses componentes da partição /system_ext para a /product ao longo de um período.

  • Produto:uma coleção de componentes específicos do produto ou dispositivo que representam personalizações e extensões do OEM para o SO 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 adequados, como os independentes de SoC. Por exemplo, se um fornecedor de SoC fornecer um componente independente de SoC aos clientes OEM (que é opcional para envio com o produto), ele poderá colocar esse componente na imagem do produto. A localização de um componente não é determinada pela propriedade, mas sim pela finalidade.

  • Fornecedor:um conjunto 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 é proprietário da imagem do fornecedor, enquanto o fabricante do dispositivo é proprietário da imagem do ODM. Quando não há uma partição /odm separada, as imagens do fornecedor do SoC e do ODM são mescladas na partição /vendor.

Interfaces entre imagens

Existem duas interfaces principais para imagens de fornecedores e produtos relacionadas à SSI:

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

    • HIDL (o HAL de passagem está disponível apenas para módulos system e system_ext)
    • AIDL estável
    • Configurações
      • API System Properties
      • API Config File Schema
    • VNDK
    • APIs do SDK do Android
    • Biblioteca do SDK Java
  • Interfaces do produto:a interface do produto é a interface entre a SSI e a imagem do produto. Definir uma interface estável desacopla os componentes do produto dos componentes do sistema em uma SSI. A interface do produto exige as mesmas interfaces estáveis que a VINTF. No entanto, apenas as APIs do VNDK e do SDK do Android são aplicadas em dispositivos lançados com o Android 11 (e versões mais recentes).

Ativar SSI no Android 11

Esta seção explica como usar os novos recursos para oferecer suporte à 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 lugar para componentes não AOSP que têm acoplamento estreito 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 nas duas partições. Os componentes na partição /system_ext podem fazer chamadas de API particulares na partição /system, e os componentes na partição /system podem fazer chamadas de API particulares na partição /system_ext.

Como as duas partições têm acoplamento rígido, elas 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 têm uma partição /system_ext, instale esses módulos no subdiretório ./system_ext na partição /system.

Histórico

Confira um pouco da história da partição /system_ext. O objetivo do design era colocar todos os componentes específicos do OEM, comuns ou não, 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 com acoplamento rígido para a partição /product, a interface do produto precisa ser estendida. Isso geralmente exigia que o próprio componente fosse refatorado extensivamente, o que consome muito tempo e esforço. A partição /system_ext começou como um lugar para hospedar temporariamente os componentes que não estão prontos para serem movidos para a partição /product. O objetivo da SSI era 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 upgrade é gasta nos componentes das partições /system e /system_ext. Quando a imagem do sistema é criada com base em fontes o mais semelhantes possível às do AOSP, você pode concentrar o esforço de upgrade na imagem system_ext.

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

O Android 9 introduziu uma partição /product que está acoplada à partição /system. Os módulos na partição /product usam os recursos do sistema sem restrições, 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 obedecer às restrições de uso de componentes do sistema que a partição /product tinha no Android 9. A partir do Android 10, a partição /product precisa ser desvinculada da partição /system e usar interfaces estáveis das 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 produtos agrupados, conforme descrito na seção /system_ext partition. Para fazer isso, desvincule os módulos específicos do produto e mova-os para a partição /product. A divisão dos módulos específicos do produto torna /system_ext comum aos dispositivos. Para mais detalhes, consulte Como tornar a partição /system_ext comum.

Para separar a partição /product dos componentes do sistema, ela precisa ter a mesma política de aplicação da partição /vendor, que já foi separada com o Project Treble./product

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

  • Interfaces nativas:os módulos nativos na partição /product precisam ser separados das outras partições. As únicas dependências permitidas dos módulos de produto são algumas bibliotecas VNDK (incluindo LLNDK) da partição /system. As bibliotecas JNI de que os apps do produto dependem precisam ser bibliotecas do 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 só podem usar APIs públicas e do sistema da partição /system e bibliotecas do SDK Java na partição /system ou /system_ext. É possível definir bibliotecas do SDK Java para APIs personalizadas.

Etapas sugeridas para SSI baseada em GSI

Partições sugeridas para SSI baseada em GSI

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

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

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

Esta seção oferece um guia para OEMs que querem modularizar as personalizações nas partições /system_ext e /product usando uma imagem do sistema AOSP ou quase AOSP. Se os OEMs criarem a imagem do sistema com base em fontes do AOSP, eles poderão substituir a imagem do sistema criada pela GSI fornecida pelo AOSP. No entanto, os OEMs não precisam chegar à etapa final (usar a GSI como ela é) de uma só vez.

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

Ao herdar generic_system.mk (que era chamado de mainline_system.mk no Android 11 e renomeado para generic_system.mk no AOSP), a imagem do sistema (GSI do OEM) inclui todos os arquivos que a GSI do AOSP tem. Esses arquivos podem ser modificados por OEMs para que a GSI do OEM contenha os arquivos proprietários do OEM, além dos arquivos da GSI do AOSP. No entanto, os OEMs não podem modificar o arquivo generic_system.mk.

Herança de "generic_system.mk" para imagem do sistema OEM

Figura 3. Herança de generic_system.mk para a imagem do sistema do OEM

Etapa 2. Faça com que a GSI do OEM tenha a mesma lista de arquivos da GSI do AOSP.

A GSI do OEM não pode ter outros arquivos nesta fase. Os arquivos proprietários do OEM precisam ser movidos para as partições system_ext ou product.

Mover arquivos adicionados para fora da GSI do OEM

Figura 4. Mover arquivos adicionados para fora da GSI do OEM

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

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

Ao executar a ferramenta compare_images periodicamente com o parâmetro allowlist, é possível monitorar as diferenças fora da lista permitida. Isso evita a necessidade de modificações adicionais na GSI do OEM.

Defina uma lista de permissões para reduzir a lista de arquivos modificados na GSI do OEM

Figura 5. Defina uma lista de permissões para reduzir a lista de arquivos modificados na GSI do OEM

Etapa 4. Faça com que a GSI do OEM tenha os mesmos binários da GSI do AOSP

A limpeza da lista de permissões permite que os OEMs usem a GSI do AOSP como imagem do sistema para os próprios produtos. Para limpar a lista de permissões, os OEMs podem abandonar as mudanças na GSI do OEM ou fazer o upstream delas para o AOSP, para que a GSI do AOSP inclua as mudanças.

Fazer com que a GSI do OEM tenha os mesmos binários da GSI do AOSP

Figura 6. Fazer com que a GSI do OEM tenha os mesmos binários da GSI do AOSP

Definir SSI para OEMs

Proteger a partição /system no momento da build

Para evitar mudanças específicas do produto na partição /system e definir a GSI do OEM, os OEMs podem usar uma macro de makefile chamada require-artifacts-in-path para impedir qualquer declaração de módulos do sistema depois que a macro for chamada. Consulte o exemplo de como criar um arquivo 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 precisa estar vazia para que a GSI do OEM seja comum a todos os produtos dele. Esse processo é para definir a GSI do OEM e pode ser independente das etapas da GSI do AOSP.

Aplicar interfaces de produtos

Para garantir que a partição /product não seja agrupada, os OEMs podem garantir que os dispositivos deles apliquem as interfaces de 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 informações detalhadas, consulte Aplicação de interfaces de Partição de produtos.

Tornar a partição /system_ext comum

A partição /system_ext pode variar entre dispositivos porque pode ter módulos específicos do dispositivo e agrupados pelo 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 a própria SSI e compartilhá-la entre vários dispositivos removendo as diferenças e tornando a partição /system_ext comum.

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

Expor APIs ocultas na partição do sistema

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

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

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

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

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

Para configurações mais precisas, declare um broadcast receiver que desative pacotes desnecessários. O broadcast receiver chama setApplicationEnabledSetting para desativar o pacote quando recebe a mensagem ACTION_BOOT_COMPLETED.

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

Uma sobreposição de recursos estáticos manipula os pacotes sobrepostos. No entanto, isso pode impedir a definição de um SSI. Portanto, verifique se as propriedades do RRO estão 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 uma configuração detalhada for necessária, defina um RRO manualmente em vez de usar um gerado automaticamente. Para informações detalhadas, consulte Sobreposições de recursos de ambiente 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

Posso definir várias SSIs?

Isso depende da frequência e das características dos dispositivos (ou do grupo de dispositivos). Os OEMs podem tentar tornar a partição system_ext comum, conforme descrito em Tornar a partição system_ext comum. Se um grupo de dispositivos tiver muitas diferenças, é melhor definir várias SSIs.

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

Não, mas os OEMs podem definir um novo makefile para uma GSI do OEM que herda o arquivo generic_system.mk e usar o novo makefile. Por exemplo, consulte Aplicação de interfaces de Partição de produtos.

Posso remover módulos de generic_system.mk que conflitam 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.