Como adicionar um novo dispositivo

Use as informações apresentadas nesta página para criar os makefiles para seu dispositivo e produto.

Cada novo módulo do Android precisa ter um arquivo de configuração para direcionar o sistema de compilação com metadados do módulo, dependências de tempo de compilação e instruções de empacotamento. O Android usa o sistema de compilação Soong (link em inglês). Consulte Como criar versões no Android para ver mais informações sobre o sistema de compilação do Android.

Compreender as camadas de compilação

A hierarquia de compilação inclui as camadas de abstração que correspondem à composição física de um dispositivo. Essas camadas são descritas na tabela abaixo. Cada camada se relaciona com aquela acima em um relacionamento um para muitos. Por exemplo, uma arquitetura pode ter mais de uma placa, e cada placa pode ter mais de um produto. Você pode definir um elemento em uma determinada camada como uma especialização de um elemento na mesma camada, o que elimina a cópia e simplifica a manutenção.

Camada Exemplo Descrição
Produto myProduct, myProduct_eu, myProduct_eu_fr, j2, sdk A camada de produto define a especificação de recurso de um produto de venda, como os módulos a serem criados, as localidades aceitas e a configuração de várias localidades. Em outras palavras, esse é o nome do produto geral. Variáveis específicas de produto são definidas nos makefiles de definição do produto. Um produto pode ter heranças de outras definições de produtos, o que simplifica a manutenção. Um método comum é criar um produto base contendo recursos aplicáveis a todos os produtos e, em seguida, criar variantes de produto com base nele. Por exemplo, dois produtos que diferem apenas nos rádios (CDMA versus GSM) podem herdar do mesmo produto base que não define um rádio.
Placa/dispositivo marlin, blueline, coral A camada de placa/dispositivo representa a camada física de plástico no dispositivo (ou seja, o design industrial do dispositivo). Essa camada também representa o esquema bruto de um produto. Isso inclui os periféricos na placa e sua configuração. Os nomes usados são meramente códigos para diferentes configurações de placa/dispositivo.
Arch arm, x86, arm64, x86_64 A camada de arquitetura descreve a configuração do processador e a interface binária de aplicativo (ABI, na sigla em inglês) em execução na placa.

Como usar variantes de compilação

Ao criar um produto específico, é conveniente ter pequenas variações na compilação de lançamento. Em uma definição, o módulo pode especificar tags com LOCAL_MODULE_TAGS, que podem ser um ou mais valores de optional (padrão), debug e eng.

Se um módulo não especificar uma tag (por LOCAL_MODULE_TAGS), a tag será optional por padrão. Um módulo opcional será instalado somente se for exigido pela configuração do produto com PRODUCT_PACKAGES.

Estas são as variantes de compilação definidas atualmente:

Variante Descrição
eng Este é o estilo padrão.
  • Instala os módulos marcados com eng ou debug.
  • Instala módulos de acordo com os arquivos de definição do produto, além dos módulos marcados.
  • ro.secure=0
  • ro.debuggable=1
  • ro.kernel.android.checkjni=1
  • adb está ativado por padrão.
user A variante escolhida para ser a versão final.
  • Instala os módulos marcados com user.
  • Instala módulos de acordo com os arquivos de definição do produto, além dos módulos marcados.
  • ro.secure=1
  • ro.debuggable=0
  • adb está desativado por padrão.
userdebug O mesmo que user, com estas exceções:
  • Instala módulos marcados com debug também.
  • ro.debuggable=1
  • adb está ativado por padrão.

Diretrizes de userdebug

A execução de compilações userdebug nos testes ajuda os desenvolvedores de dispositivos a entenderem o desempenho e a potência das versões em desenvolvimento. Para manter a consistência entre as compilações user e userdebug e para receber métricas confiáveis nas compilações usadas para depuração, os desenvolvedores de dispositivos precisam seguir estas diretrizes:

  • O userdebug será definido como uma compilação de usuário com acesso raiz ativado, exceto nestes casos:
    • Apps somente para o userdebug que são executados apenas sob demanda pelo usuário.
    • Operações que são executadas apenas durante a manutenção ociosa (no carregador/totalmente carregado), como o uso de dex2oatd versus dex2oat para compilações em segundo plano.
  • Não deve haver recursos que dependam do tipo de compilação para serem ativados por padrão ou não. Não é recomendável que os desenvolvedores usem qualquer forma de log que afete a vida útil da bateria, como o log de depuração ou o despejo de heap.
  • Quaisquer recursos de depuração ativados por padrão no userdebug precisam ser claramente definidos e compartilhados com todos os desenvolvedores que trabalham no projeto. Você precisa ativar os recursos de depuração somente por tempo limitado, até que o problema que você está tentando depurar seja resolvido.

Personalizar a compilação com sobreposições de recursos

O sistema de compilação do Android usa sobreposições de recursos para personalizar um produto no tempo de compilação. As sobreposições de recursos especificam arquivos de recursos aplicados sobre os padrões. Para usar sobreposições de recursos, modifique o arquivo de compilação do projeto para definir o PRODUCT_PACKAGE_OVERLAYS como um caminho relativo para seu diretório de nível superior. Esse caminho se torna uma raiz paralela pesquisada junto com a raiz atual quando o sistema de compilação procura por recursos.

As configurações mais comumente personalizadas estão contidas no arquivo frameworks/base/core/res/res/values/config.xml (links em inglês).

Para configurar uma sobreposição de recurso nesse arquivo, adicione o diretório da sobreposição ao arquivo de compilação do projeto usando:

    PRODUCT_PACKAGE_OVERLAYS := device/device-implementer/device-name/overlay
    

ou

    PRODUCT_PACKAGE_OVERLAYS := vendor/vendor-name/overlay
    

Em seguida, adicione um arquivo de sobreposição ao diretório, por exemplo:

    vendor/foobar/overlay/frameworks/base/core/res/res/config.xml
    

Todas as strings ou matrizes de string encontradas no arquivo de sobreposição config.xml substituem as encontradas no arquivo original.

Criar um produto

É possível organizar os arquivos de origem do dispositivo de várias maneiras diferentes. Veja uma breve descrição de uma maneira de organizar uma implementação do Pixel.

O Pixel é implementado com uma configuração de dispositivo principal chamada marlin. Com base nessa configuração de dispositivo, um produto é criado com um makefile de definição de produto que declara informações específicas do produto sobre o dispositivo, como o nome e o modelo. Consulte o diretório device/google/marlin para ver como tudo isso está configurado.

Escrever os makefiles de produtos

As etapas a seguir descrevem como configurar makefiles de produtos de maneira semelhante à linha de produtos do Pixel:

  1. Crie um diretório device/<company-name>/<device-name> para o produto. Por exemplo, device/google/marlin. Esse diretório conterá o código-fonte do seu dispositivo e os makefiles para criá-los.
  2. Crie um makefile device.mk que declara os arquivos e módulos necessários para o dispositivo. Veja um exemplo em: device/google/marlin/device-marlin.mk.
  3. Crie um makefile de definição de produto para criar um produto específico com base no dispositivo. O makefile a seguir foi retirado de device/google/marlin/aosp_marlin.mk como exemplo. Observe que o produto é herdeiro dos arquivos device/google/marlin/device-marlin.mk e vendor/google/marlin/device-vendor-marlin.mk pelo makefile, além de declarar as informações específicas do produto, como nome, marca e modelo.
        # Inherit from the common Open Source product configuration
        $(call inherit-product, $(SRC_TARGET_DIR)/product/core_64_bit.mk)
        $(call inherit-product, $(SRC_TARGET_DIR)/product/aosp_base_telephony.mk)
    
        PRODUCT_NAME := aosp_marlin
        PRODUCT_DEVICE := marlin
        PRODUCT_BRAND := Android
        PRODUCT_MODEL := AOSP on msm8996
        PRODUCT_MANUFACTURER := Google
        PRODUCT_RESTRICT_VENDOR_FILES := true
    
        PRODUCT_COPY_FILES += device/google/marlin/fstab.common:$(TARGET_COPY_OUT_VENDOR)/etc/fstab.marlin
    
        $(call inherit-product, device/google/marlin/device-marlin.mk)
        $(call inherit-product-if-exists, vendor/google_devices/marlin/device-vendor-marlin.mk)
    
        PRODUCT_PACKAGES += \
            Launcher3QuickStep \
            WallpaperPicker
        

    Consulte Definir variáveis de definição de produto para ver outras variáveis específicas do produto que podem ser adicionadas aos seus makefiles.

  4. Crie um arquivo AndroidProducts.mk que aponte para os makefiles do produto. Neste exemplo, apenas o makefile de definição do produto é necessário. O exemplo abaixo é de device/google/marlin/AndroidProducts.mk, que contémo Pixel (marlin) e o Pixel XL (sailfish) que compartilharam a maioria das configurações:
        PRODUCT_MAKEFILES := \
        	$(LOCAL_DIR)/aosp_marlin.mk \
        	$(LOCAL_DIR)/aosp_sailfish.mk
    
        COMMON_LUNCH_CHOICES := \
        	aosp_marlin-userdebug \
        	aosp_sailfish-userdebug
        
  5. Crie um makefile BoardConfig.mk contendo as configurações específicas da placa. Por exemplo, consulte device/google/marlin/BoardConfig.mk.
  6. Crie um arquivo vendorsetup.sh para adicionar seu produto (um “lunch combo”) à compilação com uma variante de compilação separada por um traço. Exemplo:
        add_lunch_combo <product-name>-userdebug
        
  7. Nesse ponto, você pode criar mais variantes de produtos com base no mesmo dispositivo.

Definir variáveis de definição de produto

Variáveis específicas de produto são definidas no makefile do produto. A tabela mostra algumas das variáveis mantidas em um arquivo de definição de produto.

Variável Descrição Exemplo
PRODUCT_AAPT_CONFIG Configurações de aapt a serem usadas ao criar pacotes.
PRODUCT_BRAND A marca (por exemplo, da operadora) de personalização do software, se houver.
PRODUCT_CHARACTERISTICS Características do aapt para permitir a inclusão de recursos específicos da variante em um pacote. tablet, nosdcard
PRODUCT_COPY_FILES Lista de palavras como source_path:destination_path. O arquivo no caminho de origem precisa ser copiado para o caminho de destino ao criar esse produto. As regras para as etapas de cópia são definidas em config/makefile.
PRODUCT_DEVICE Nome do design industrial. Esse também é o nome da placa, e o sistema de compilação o utiliza para localizar o BoardConfig.mk. tuna
PRODUCT_LOCALES Uma lista separada por espaço de código de idioma de duas letras, pares de códigos de país de duas letras que descrevem várias configurações para o usuário, como o idioma da IU e a formatação de data, hora e moeda. A primeira localidade listada em PRODUCT_LOCALES é usada como a padrão do produto. en_GB, de_DE, es_ES, fr_CA
PRODUCT_MANUFACTURER Nome do fabricante. acme
PRODUCT_MODEL Nome visível para o usuário final do produto final.
PRODUCT_NAME Nome visível para o usuário final do produto geral. Aparece na tela Configurações > Sobre.
PRODUCT_OTA_PUBLIC_KEYS Lista de chaves públicas Over the Air (OTA) para o produto.
PRODUCT_PACKAGES Lista dos APKs e módulos a serem instalados. Calendar contacts
PRODUCT_PACKAGE_OVERLAYS Indica se os recursos padrão precisam ser usados ou se alguma sobreposição específica do produto precisa ser adicionada. vendor/acme/overlay
PRODUCT_PROPERTY_OVERRIDES Lista das atribuições de propriedades do sistema no formato "key=value".

Definir ANDROID_VENDOR_KEYS para conexão por USB

A variável de ambiente ANDROID_VENDOR_KEYS permite que os fabricantes de dispositivos acessem as compilações de produção por adb. Gere uma chave para cada versão que cada dispositivo aceitará, armazene-as internamente (como em vendor/oem-name/security/adb/) e use ANDROID_VENDOR_KEYS para dizer ao adb para usar essas chaves canônicas em vez de chaves aleatórias.

Use a variável de ambiente ANDROID_VENDOR_KEYS para apontar para o diretório que contém as chaves públicas e privadas adb geradas utilizadas para criptografia. A chave privada é armazenada em file; e a chave pública, em file.pub. A variável de ambiente ANDROID_VENDOR_KEYS aponta para um arquivo ou diretório onde os pares de chaves gerados são armazenados.

A variável ANDROID_VENDOR_KEYS está definida como um arquivo ou diretório que contém pares de chaves de autenticação RSA de 2.048 bits gerados com o comando de arquivo adb keygen. Esses pares de chaves são adicionais aos pares de chaves RSA gerados pelo servidor ADB. Um par de chaves RSA é necessário quando você usa adb para se conectar via USB pela primeira vez.

É preciso aceitar a chave RSA do computador host para conceder explicitamente o acesso adb ao dispositivo. Por padrão, os pares de chaves gerados pelo servidor ADB ficam nos seguintes diretórios de armazenamento de chaves como adbkey (chave privada) e adbkey.pub (chave pública).

Para locais de arquivos, no macOS, geralmente temos $HOME/.android. No Windows, temos %USERPROFILE%\.android, e no Linux, $home\.android. No Windows, as chaves de autenticação RSA também podem estar em C:\Windows\System32\config\systemprofile\.android.

Quando o servidor ADB precisar de uma chave, primeiro ele pesquisará no diretório de armazenamento de chaves do servidor ADB. Se nenhuma chave for encontrada, ele verificará a variável de ambiente ANDROID_VENDOR_KEYS. Se nenhuma chave for encontrada, o servidor local do ADB gerará e salvará um novo par de chaves no diretório de armazenamento de chaves do servidor ADB.