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.
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
esystem_ext
) - AIDL estável
- Configurações
- API System Properties
- API Config File Schema
- VNDK
- APIs do SDK do Android
- Biblioteca do SDK Java
- HIDL (o HAL de passagem está disponível apenas para módulos
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
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
.
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
.
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.
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.
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.