Esta página apresenta vários mecanismos que os OEMs de dispositivos Android podem usar para ter a própria imagem do sistema compartilhada (SSI) 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 Android OS). 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 de SO genérico. Uma interface com controle de versão, chamada de interface do fornecedor (VINTF, na sigla em inglês), é definida e aplicada nas duas partições. Ao usar esse sistema de particionamento, é possível modificar a partição do sistema sem modificar a do fornecedor e vice-versa.
Motivação
O código do framework lançado no AOSP é compatível com a arquitetura Treble e mantém a compatibilidade com versões anteriores de implementações de fornecedores. Por exemplo, uma imagem genérica do sistema criada com base nas fontes do AOSP do Android 10 pode ser executada em qualquer dispositivo compatível com o Treble que esteja executando o Android 8 ou mais recente. A versão do Android que é enviada em dispositivos de consumo é modificada por fornecedores de SoC e OEMs. Consulte O ciclo 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 os fornecedores de SoC e OEMs podem seguir para criar uma SSI. Isso significa uma imagem criada com base nas origens 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 oferecer uma redução significativa na complexidade e no custo de upgrades do SO Android. Para saber as etapas específicas necessárias para criar uma SSI, consulte a seção Etapas sugeridas para SSIs baseadas em GSI e observe que você não precisa usar as quatro etapas. As etapas escolhidas (apenas a Etapa 1, por exemplo) dependem da sua implementação.
Visão geral da 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 escolher 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 SO Android
é lançada, os OEMs investem apenas uma vez na atualização dos 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 os fornecedores de SoC criam SSIs que incluem todos os recursos e modificações personalizadas de que um OEM precisa. 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. Com relação à 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 partições.
Partições em torno do SSI
A Figura 1 mostra partições em torno do SSI e as interfaces com versões em todas as 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 da SSI
Imagens e partições
As informações desta seção distinguem 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 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 um determinado SSI é compartilhado entre todos os dispositivos que usam esse SSI. A SSI é composta por uma única imagem
/system
ou por uma/system
e as partições/system_ext
, como mostrado na Figura 1.A partição
/system
contém componentes baseados no AOSP, enquanto/system_ext
, quando implementado, contém extensões de fornecedores de OEM e SoC e componentes que estão intimamente acoplados aos componentes do AOSP. Por exemplo, uma biblioteca de framework Java do OEM que fornece APIs personalizadas para os apps do OEM se encaixa melhor na partição/system_ext
do que na partição/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 é vantajoso usá-la para todos os recursos e extensões personalizados que estão intimamente acoplados a componentes baseados no AOSP. Essa distinção ajuda a identificar as mudanças que precisam ser feitas para mover esses componentes da partição/system_ext
para a/product
em um período.
Produto:uma coleção de componentes específicos do produto ou do 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 apropriados, como os independentes de SoC. Por exemplo, se um fornecedor de SoC fornecer um componente independente de SoC aos clientes OEM (que é opcional no envio com o produto), o fornecedor de SoC poderá colocar esse componente na imagem do produto. O local de um componente não é determinado pela propriedade, mas pelo propósito.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 é 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 de SoC e do ODM são mescladas na partição/vendor
.
Interfaces entre imagens
Há duas interfaces principais para imagens de fornecedores e produtos em torno do SSI:
Interface do fornecedor (VINTF, na sigla em inglês): a VINTF é a interface para os componentes que residem no fornecedor e nas imagens do 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 do fornecedor não pode depender de uma parte privada da imagem do sistema e vice-versa. Isso foi originalmente definido no Project Treble, que dividiu as imagens em partições do sistema e do fornecedor. A interface é descrita usando os seguintes mecanismos:
- HIDL: a HAL de passagem só está disponível para módulos
system
esystem_ext
. - AIDL estável
- Configurações
- API de propriedades do sistema
- API Config File Schema
- VNDK (link em inglês)
- APIs do SDK do Android
- Biblioteca de SDK do Java
- HIDL: a HAL de passagem só está disponível para módulos
Interfaces do produto:a interface do produto é a interface entre a SSI e a imagem do produto. A definição de uma interface estável desepara 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 do VNDK e do SDK do Android são aplicadas a dispositivos lançados com o Android 11 (e versões mais recentes).
Ativar a SSI no Android 11
Esta seção explica como usar os novos recursos em vigor 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 que não são do AOSP que têm acoplamento rígido 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 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 são estritamente acopladas, 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, independentemente de serem comuns, na
partição /product
. No entanto, movê-los todos de uma só vez não era viável,
principalmente quando alguns componentes tinham um acoplamento estreito com a partição
/system
. Para mover um componente acoplado à partição /product
, a
interface do produto precisa ser estendida. Isso geralmente exigia que o componente
fosse refatorado extensivamente, 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 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óxima possível do AOSP. Com o SSI, a maior parte do esforço de upgrade é
gasta nos componentes nas 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
vinculada à partição /system
. Os módulos na
partição /product
usam os recursos do sistema sem nenhuma restrição e vice
versa. Para permitir a SSI no Android 10, os componentes do produto são divididos em
as 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
tinha no Android 9. A partir do Android 10, a partição /product
precisa ser desempacotada 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, desempacote
os módulos específicos do produto e os mova para a partição /product
.
A divisão dos módulos específicos do produto torna o /system_ext
comum para os
dispositivos. Para mais detalhes, consulte Como tornar a partição /system_ext comum.
Para desagrupar a partição /product
dos componentes do sistema, a partição /product
precisa ter a mesma política de aplicação que a partição /vendor
que
já estava desagrupada do Projeto Treble.
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 desempacotados das outras partições. As únicas dependências permitidas dos módulos de produto são algumas bibliotecas do VNDK (incluindo o 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 elas são instáveis. Esses módulos só podem usar APIs públicas e do sistema da partição/system
e bibliotecas do SDK do Java na partição/system
ou/system_ext
. É possível definir bibliotecas do SDK para Java para APIs personalizadas.
Etapas sugeridas para a SSI baseada em GSI
Figura 2. Partições sugeridas para SSI com base em GSI
Uma imagem genérica do sistema (GSI) é a imagem do sistema criada diretamente do AOSP. Ele é usado para os testes de compliance 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 com a versão necessária do Android.
Os OEMs também podem usar o GSI para criar o 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 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
ao usar uma
imagem do sistema AOSP ou semelhante. Se os OEMs criarem a imagem do sistema com base em fontes do
AOSP, eles poderão substituir essa imagem pela GSI
fornecida 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 do OEM (GSI do OEM)
Ao herdar
generic_system.mk
(que foi chamado de mainline_system.mk
no Android 11 e renomeado como
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 pelos OEMs para que o GSI do OEM possa conter os arquivos
proprietários do OEM, além dos arquivos GSI do AOSP. No entanto, os OEMs não têm
permissão para modificar o arquivo generic_system.mk
.
Figura 3. Herdar generic_system.mk para a imagem do sistema do OEM
Etapa 2. Fazer com que a GSI do OEM tenha a mesma lista de arquivos com a GSI do AOSP
O GSI do OEM não pode ter arquivos adicionais 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 do GSI do OEM
Etapa 3. Definir uma lista de permissões para limitar os arquivos modificados no 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. Receba o GSI do AOSP do
destino de lançamento 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 outras modificações na GSI do OEM.
Figura 5. Definir uma lista de permissões para reduzir a lista de arquivos modificados no GSI do OEM
Etapa 4. Fazer com que a GSI do OEM tenha os mesmos binários que a GSI do AOSP
A limpeza da lista de permissões permite que os OEMs usem o GSI do AOSP como a 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 das mudanças no AOSP para que a GSI inclua as mudanças.
Figura 6. Fazer com que a GSI do OEM tenha os mesmos binários que a GSI do AOSP
Definir SSI para OEMs
Proteger a partição /system no momento da compilação
Para evitar mudanças específicas do produto na partição /system
e definir a
GSI do OEM, os OEMs podem usar uma macro do 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 de como criar um makefile e ativar a verificação de caminho de artefato.
Os OEMs podem definir uma lista para permitir que módulos específicos do produto sejam instalados na
partição /system
temporariamente. No entanto, a lista precisa estar vazia para tornar o GSI
do OEM comum a todos os produtos do OEM. Esse 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 desempacotada, os OEMs podem garantir que os
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 a
PRODUCT_SHIPPING_API_LEVEL
do dispositivo for maior ou igual a 30
. Para
informações detalhadas, consulte Como aplicar interfaces de
partição de produtos.
Tornar a partição /system_ext comum
A partição /system_ext
pode ser diferente entre os dispositivos, porque pode ter
módulos agrupados pelo sistema específicos. Como a SSI consiste em partições /system
e /system_ext
, as diferenças na partição /system_ext
impedem que os OEMs definam uma SSI. Os OEMs podem ter a própria SSI e compartilhar essa
SSI entre vários dispositivos removendo quaisquer 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 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 apps específicos do dispositivo para a partição do produto, remova o uso de APIs ocultas.
A melhor maneira 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 APIs ocultas, os OEMs poderão contribuir para o AOSP para definir as novas APIs do sistema para os dispositivos.
Como alternativa, os OEMs podem definir APIs personalizadas criando a própria biblioteca
SDK do 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 fornecedor.
Os OEMs precisam congelar as APIs
do produto
para oferecer compatibilidade com versões anteriores.
Incluir o superconjunto de todos os APKs e pular algumas instalações de pacotes para cada dispositivo
Alguns pacotes que vêm com o sistema não são comuns em todos os dispositivos.
Descompactar esses módulos de APK para movê-los para o produto ou a partição do fornecedor
pode ser difícil. Como solução temporá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
config_disableApkUnlessMatchedSku_skus_list
e
config_disableApksUnlessMatchedSku_apk_list
do framework.
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 a 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, verifique se as propriedades do RRO estão ativadas e definidas corretamente. Ao definir 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 uma configuração detalhada for necessária, defina uma RRO manualmente, em vez de
depender de uma gerada automaticamente. Para informações detalhadas, consulte Sobreposições de
recursos do ambiente de execução (RROs, na sigla em inglês).
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ários SSIs?
Isso depende da semelhança 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
Como tornar a partição system_ext comum. Se um grupo de dispositivos
tiver muitas diferenças, será melhor definir vários SSIs.
Posso modificar o generic_system.mk (mainline_system.mk) para uma GSI OEM?
Não. Mas os OEMs podem definir um novo makefile para um GSI do OEM que herda o
arquivo generic_system.mk
e usar o novo makefile. Por exemplo, consulte
Como aplicar interfaces de
partição de produtos.
Posso remover módulos de general_system.mk que entram em conflito com minha implementação?
Não. O 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.