Como adicionar um novo dispositivo

Use as informações apresentadas nesta página para criar os makefiles para seu dispositivo e produto. Observe que, diferente das outras páginas desta seção, o conteúdo aqui é aplicável somente ao criar um tipo de dispositivo totalmente novo e destina-se apenas às equipes de produto e criação da empresa.

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 agora usa o sistema de compilação Soong. Consulte Como criar versões no Android para ver mais informações sobre o sistema de compilação do Android.

Compreender as camadas de criação

A hierarquia de criaçã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 eliminando, assim, a cópia e simplificando 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, você pode ter dois produtos que diferem apenas nos rádios (CDMA versus GSM) herdados do mesmo produto base que não define um rádio.
Placa/Dispositivo sardine, trout, goldfish A camada de dispositivo/placa representa a camada física de plástico no dispositivo (ou seja, o design industrial do dispositivo). Por exemplo, os dispositivos norte-americanos provavelmente incluem teclados QWERTY, enquanto os dispositivos vendidos na França provavelmente incluem teclados AZERTY. Essa camada também representa o esquema cru 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.
Arquitetura arm, x86, mips, arm64, x86_64, mips64 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.

Usar variantes de criação

Ao criar um produto específico, geralmente é útil ter pequenas variações sobre aquela que será a versão final. Em uma definição de módulo, o módulo pode especificar tags com LOCAL_MODULE_TAGS, que podem ser um ou mais valores entre optional (padrão), debug e eng.

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

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

eng Este é o estilo padrão.
  • Instala os módulos marcados com: eng e/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 é ativado por padrão.
user Este é o estilo escolhido para ser a versão final.
  • Instala os módulos marcados com o 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 é desativado por padrão.
userdebug O mesmo que user, exceto o seguinte:
  • Também instala módulos marcados com debug.
  • ro.debuggable=1
  • adb é ativado por padrão.

Diretrizes de userdebug

A execução de versões do 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 versões de usuário e de userdebug e para receber métricas confiáveis nas versões usadas para depuração, os desenvolvedores de dispositivos precisam seguir estas diretrizes:

  • O userdebug deve ser definido como uma versão de usuário com acesso raiz ativado, exceto:
    • 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 versão para serem habilitados 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 habilitados por padrão no userdebug precisam ser claramente definidos e compartilhados com todos os desenvolvedores que trabalham no projeto. Ative esses recursos de depuração apenas temporariamente até que o problema seja resolvido.

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

O sistema de criação do Android usa sobreposições de recursos para personalizar um produto no momento da criaçã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 criaçã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 criação procura por recursos.

As configurações mais comumente personalizadas estão contidas no arquivo frameworks/base/core/res/res/values/config.xml.

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

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 strings encontradas no arquivo config.xml de sobreposição substituem aquelas encontradas no arquivo original.

Criar um produto

Há muitas maneiras de organizar os arquivos de origem para seu dispositivo. Como exemplo, examinaremos brevemente como a implementação do Nexus 6 foi organizada, mas você pode organizar seus arquivos de origem e versão da maneira que preferir.

O Nexus 6 foi implementado com um configurador de dispositivo principal denominado shamu. 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/moto/shamu para ver como tudo isso é configurado.

Escrever os makefiles

As etapas a seguir descrevem como configurar makefiles de produtos de maneira semelhante à linha de produtos Nexus 6:

  1. Crie um diretório device/<company_name>/<device_name> para seu produto. Por exemplo, device/moto/shamu. 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. Para ver um exemplo, consulte device/moto/shamu/device.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/moto/shamu/aosp_shamu.mk como exemplo. Observe que o produto herda dos arquivos device/moto/shamu/device.mk e vendor/moto/shamu/device-vendor.mk por meio do 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/aosp_base_telephony.mk)
    
    PRODUCT_NAME := aosp_shamu
    PRODUCT_DEVICE := shamu
    PRODUCT_BRAND := Android
    PRODUCT_MODEL := AOSP on Shamu
    PRODUCT_MANUFACTURER := motorola
    PRODUCT_RESTRICT_VENDOR_FILES := true
    
    $(call inherit-product, device/moto/shamu/device.mk)
    $(call inherit-product-if-exists, vendor/moto/shamu/device-vendor.mk)
    
    PRODUCT_NAME := aosp_shamu
    
    PRODUCT_PACKAGES += \
        Launcher3
    

    Consulte Variáveis de definição do produto para ver outras variáveis específicas do produto que você pode incluir nos seus arquivos.

  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 é do device/moto/shamu/AndroidProducts.mk:
    #
    # This file should set PRODUCT_MAKEFILES to a list of product makefiles
    # to expose to the build system.  LOCAL_DIR will already be set to
    # the directory containing this file.
    #
    # This file may not rely on the value of any variable other than
    # LOCAL_DIR; do not use any conditionals, and do not look up the
    # value of any variable that isn't set in this file or in a file that
    # it includes.
    #
    
    PRODUCT_MAKEFILES := \
        $(LOCAL_DIR)/aosp_shamu.mk
    
  5. Crie um makefile BoardConfig.mk contendo as configurações específicas da placa. Para ver um exemplo, consulte device/moto/shamu/BoardConfig.mk.
  6. Crie um arquivo vendorsetup.sh para adicionar seu produto (um "combo de almoço") à versão com uma variante de criaçã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. As variáveis mantidas em um arquivo de definição de produto são:

Parâmetro 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 para 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 criaçã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 os APKs e os módulos a serem instalados. Calendar Contacts
PRODUCT_PACKAGE_OVERLAYS Indique 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 de atribuições de propriedades do sistema no formato "chave=valor".

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 versõ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 no arquivo. A chave pública é armazenada no arquivo .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.

Essa variável é 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 o 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, ele provavelmente será: $HOME/.android. No Windows e Linux, ele será: %USERPOFILE%\.android. No Windows, as chaves de autenticação RSA também podem estar em C:\Windows\System32\config\systemprofile\.android em alguns casos. Quando o servidor ADB precisar de uma chave, ele primeiro pesquisará no diretório de armazenamento de chaves do servidor ADB. Se nenhuma chave for encontrada, ela 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.

Observação: você pode modificar o diretório padrão onde o servidor ADB armazena as chaves RSA configurando a variável de ambiente ANDROID_SDK_HOME. No dispositivo, as chaves são armazenadas no arquivo /data/misc/adb/adb_keys/, e novas chaves autorizadas são anexadas ao mesmo arquivo à medida que você as aceita.