Aplicar interfaces de partição de produtos

O Android 11 desagrupa a partição product, tornando-a independentes das partições system e vendor. Como parte dessas mudanças, Agora é possível controlar o acesso da partição product aos recursos nativos e do Java interfaces, que é semelhante a como a aplicação de interface funciona para vendor ou partições.

Aplicar interfaces nativas

Para ativar a aplicação de interface nativa, defina PRODUCT_PRODUCT_VNDK_VERSION para current. A versão é definida automaticamente como current quando o frete O nível da API para o destino é maior que 29. A aplicação permite:

  • Módulos nativos na partição product a serem vinculados:
    • De forma estática ou dinâmica, para outros módulos na partição product que incluem bibliotecas estáticas, compartilhadas ou de cabeçalho.
    • De forma dinâmica, para bibliotecas VNDK na partição system.
  • Bibliotecas JNI em APKs desagrupados na partição product para vincular bibliotecas em /product/lib ou /product/lib64 (além das bibliotecas bibliotecas do NDK).

A aplicação não permite outros links para partições diferentes de product. partição.

Aplicação do tempo de build (Android.bp)

No Android 11, os módulos do sistema podem criar um produto variante de imagem, além das variantes de imagem principal e do fornecedor. Quando o conteúdo nativo a aplicação de interface está ativada (PRODUCT_PRODUCT_VNDK_VERSION é definido como current):

  • Os módulos nativos na partição product estão na variante do produto da variante principal.

  • Os módulos com product_available: true nos arquivos Android.bp são disponível para a variante do produto.

  • Bibliotecas ou binários que especificam product_specific: true podem ser vinculados a outros bibliotecas que especificam product_specific: true ou product_available: true nos arquivos Android.bp.

  • As bibliotecas VNDK precisam ter product_available: true nos arquivos Android.bp. Portanto, os binários product podem ser vinculados a bibliotecas VNDK.

A tabela a seguir resume as propriedades Android.bp usadas para criar imagens variantes.

Propriedades no Android.bp Variantes criadas
Antes da aplicação Após a aplicação
padrão (nenhum) núcleo
(inclui /system, /system_ext e /product).
núcleo
(inclui /system e /system_ext, mas não /product).
system_ext_specific: true core core
product_specific: true core produto
vendor: true fornecedor fornecedor
vendor_available: true núcleo, fornecedor núcleo, fornecedor
product_available: true N/A núcleo, produto
vendor_available: true E product_available: true N/A núcleo, produto, fornecedor
system_ext_specific: true E vendor_available: true núcleo, fornecedor núcleo, fornecedor
product_specific: true E vendor_available: true núcleo, fornecedor produto, fornecedor

Aplicação do tempo de criação (Android.mk)

Quando a aplicação de interface nativa está ativada, os módulos nativos são instalados na product partição tem um tipo de link native:product que pode ser vinculado apenas a outros módulos native:product ou native:vndk. Tentando vincular a qualquer um módulos diferentes deles faz com que o sistema de build gere uma verificação de tipo de link erro.

Aplicação do ambiente de execução

Quando a aplicação de interface nativa estiver ativada, a configuração do vinculador para o vinculador biônico não permite que os processos do sistema usem bibliotecas product. criar uma seção product para os processos do product que não podem ser vinculados; bibliotecas fora da partição product. No entanto, esses processos podem ser vinculados bibliotecas de VNDK). As tentativas de violar a configuração do link de tempo de execução fazem com que o falha no processo e gera uma mensagem de erro CANNOT LINK EXECUTABLE.

Aplicar interfaces Java

Para ativar a aplicação da interface Java, defina PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE para true. (O valor é definido automaticamente como true quando o nível da API de frete para o destino é maior que 29.) Quando ativada, a aplicação permite ou proíbe o seguinte: acesso:

API /system /system_ext /product /vendor /data
API pública
@SystemApi
API @hide

Como na partição vendor, um app ou uma biblioteca Java na product a partição tem permissão para usar apenas APIs públicas e do sistema; vinculando a uma biblioteca que usa APIs ocultas não é permitido. Essa restrição inclui a vinculação no build tempo e reflexão no ambiente de execução.

Aplicação do tempo de build

No tempo de build, o Make e o Soong verificam se os módulos Java no product partição não usam APIs ocultas, verificando platform_apis e Campos sdk_version. O sdk_version dos apps na partição product precisa ser preenchido com current, system_current ou uma versão numérica da API; e o campo platform_apis precisa estar vazio.

Aplicação do ambiente de execução

O ambiente de execução do Android verifica se os apps na partição product não usam escondidas, incluindo reflexão. Para mais detalhes, consulte Restrições de não SDK do Terraform.

Ativar a aplicação obrigatória de interface do produto

Use as etapas desta seção para ativar a aplicação da interface do produto.

Etapa Tarefa Obrigatório
1 Defina seu próprio makefile do sistema que especifica os pacotes para o system. Em seguida, defina a verificação de requisito do caminho de artefatos no device.mk (para evitar que módulos que não sejam do sistema sejam instalados) à partição system). N
2 Limpar a lista de permissões. N
3 Aplicar interfaces nativas e identificar falhas de links no tempo de execução (pode ser executado em em paralelo à aplicação do Java). Y
4 Aplicar interfaces Java e verificar o comportamento do ambiente de execução (pode ser executado em paralelo) com aplicação nativa). Y
5 Verifique os comportamentos do ambiente de execução. Y
6 Atualização de device.mk com a aplicação da interface do produto. Y

Etapa 1: criar o makefile e ativar a verificação de caminho do artefato

Nesta etapa, você vai definir o makefile system.

  1. Crie um makefile que defina os pacotes para a partição system. Para exemplo, crie um arquivo oem_system.mk com o seguinte:

    $(call inherit-product, $(SRC_TARGET_DIR)/product/handheld_system.mk)
    $(call inherit-product, $(SRC_TARGET_DIR)/product/telephony_system.mk)
    
    # Applications
    PRODUCT_PACKAGES += \
        CommonSystemApp1 \
        CommonSystemApp2 \
        CommonSystemApp3 \
    
    # Binaries
    PRODUCT_PACKAGES += \
        CommonSystemBin1 \
        CommonSystemBin2 \
        CommonSystemBin3 \
    
    # Libraries
    PRODUCT_PACKAGES += \
        CommonSystemLib1 \
        CommonSystemLib2 \
        CommonSystemLib3 \
    
    PRODUCT_SYSTEM_NAME := oem_system
    PRODUCT_SYSTEM_BRAND := Android
    PRODUCT_SYSTEM_MANUFACTURER := Android
    PRODUCT_SYSTEM_MODEL := oem_system
    PRODUCT_SYSTEM_DEVICE := generic
    
    # For system-as-root devices, system.img should be mounted at /, so we
    # include ROOT here.
    _my_paths := \
     $(TARGET_COPY_OUT_ROOT)/ \
     $(TARGET_COPY_OUT_SYSTEM)/ \
    
    $(call require-artifacts-in-path, $(_my_paths),)
    
  2. No arquivo device.mk, herde o makefile comum para o system. e ativar a verificação de requisitos do caminho do artefato. Exemplo:

    $(call inherit-product, $(SRC_TARGET_DIR)/product/oem_system.mk)
    
    # Enable artifact path requirements checking
    PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS := strict
    

Sobre os requisitos do caminho de artefato

Quando PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS for definido como true ou strict, o sistema de compilação impede que pacotes definidos em outros makefiles sejam instalados no os caminhos definidos em require-artifacts-in-path e impede que os pacotes definido no makefile atual pela instalação de artefatos fora dos caminhos definido em require-artifacts-in-path.

No exemplo acima, com PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS definido como strict, os makefiles fora de oem_system.mk não podem incluir módulos instalados em a partição root ou system. Para incluir esses módulos, é preciso defina-as no próprio arquivo oem_system.mk ou em um makefile incluído. As tentativas de instalar módulos em caminhos não permitidos causam falhas de build. Para corrigir faça o seguinte:

  • Opção 1:incluir o módulo de sistema nos makefiles incluídos em oem_system.mk Isso faz com que o requisito de caminho do artefato seja atendido (já que o módulos agora existem em um makefile incluído) e, portanto, permite a instalação no conjunto de caminhos em "require-artifacts-in-path".

  • Opção 2:instalar módulos na partição system_ext ou product (e não instale módulos na partição system).

  • Opção 3:adicionar módulos ao PRODUCT_ARTIFACT_PATH_REQUIREMENT_ALLOWED_LIST Isso lista os módulos permitidos precisa ser instalado.

Etapa 2: esvaziar a lista de permissões

Nesta etapa, você vai criar a PRODUCT_ARTIFACT_PATH_REQUIREMENT_ALLOWED_LIST vazio para que todos os dispositivos que compartilham o oem_system.mk também possam compartilhar um único system imagem. Para esvaziar a lista de permissões, mova todos os módulos da lista para o system_ext ou product ou adicione-as a system arquivos. Isso é opcional, porque a definição de uma imagem system comum não é necessária para ativar a aplicação da interface do produto. No entanto, esvaziar a lista de permissões útil para definir o limite de system com system_ext.

Etapa 3: aplicar interfaces nativas

Nesta etapa, você vai definir PRODUCT_PRODUCT_VNDK_VERSION := current e conferir para resolver erros de build e ambiente de execução. Para verificar a inicialização e os registros do dispositivo e encontre e corrija falhas em links de tempo de execução:

  1. Defina PRODUCT_PRODUCT_VNDK_VERSION := current.

  2. Crie o dispositivo e procure erros de build. É provável que você veja intervalos para variantes do produto ou variantes principais ausentes. Intervalos comuns incluem:

    • Qualquer módulo hidl_interface que tenha product_specific: true não será disponíveis para módulos do sistema. Para corrigir, substitua product_specific: true com system_ext_specific: true.
    • Talvez os módulos não tenham a variante necessária para o produto módulos. Para corrigir isso, disponibilize esse módulo para a partição product ao configurando product_available: true ou mova o módulo para a product ao definir a partição, configure product_specific: true.
    .
  3. Resolva erros de build e confirme se o dispositivo foi criado.

  4. Atualize a imagem e procure erros de tempo de execução na inicialização e nos registros do dispositivo.

    • Se a tag linker de um registro de caso de teste mostrar um CANNOT LINK EXECUTABLE for exibida, o arquivo do Make não tem uma dependência e não foi capturado tempo de build).
    • Para verificá-lo no sistema de compilação, adicione a biblioteca necessária ao Campo shared_libs: ou required:.
  5. Resolva as dependências que faltam usando as orientações acima.

Etapa 4: aplicar interfaces Java

Nesta etapa, você vai definir PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE := true, e corrigir os erros de build resultantes. Procure dois tipos específicos de erros:

  • Erros de tipo de link. Esse erro indica que um app está vinculado a módulos Java. que têm um sdk_version mais amplo. Para corrigir isso, amplie o alcance sdk_version ou restrinja o sdk_version da biblioteca. Exemplo de erro:

    error: frameworks/base/packages/SystemUI/Android.bp:138:1: module "SystemUI" variant "android_common": compiles against system API, but dependency "telephony-common" is compiling against private API.Adjust sdk_version: property of the source or target module so that target module is built with the same or smaller API set than the source.
    
  • Erros de símbolo. Esse erro indica que não é possível encontrar um símbolo porque ela está em uma API oculta. Para corrigir o problema, use uma API visível (não oculta) ou encontre uma alternativa. Exemplo de erro:

    frameworks/opt/net/voip/src/java/com/android/server/sip/SipSessionGroup.java:1051: error: cannot find symbol
                ProxyAuthenticate proxyAuth = (ProxyAuthenticate)response.getHeader(
                                               ^
      symbol:   class ProxyAuthenticate
      location: class SipSessionGroup.SipSessionImpl
    

Etapa 5: verificar comportamentos de tempo de execução

Nesta etapa, você vai verificar se os comportamentos do ambiente de execução estão conforme o esperado. Para apps que são depurável, é possível monitorar o uso de API oculta por registro usando StrictMode.detectNonSdkApiUsage, que gera um registro quando o app usa uma API oculta). Como alternativa, use o método veridex (link em inglês) ferramenta de análise estática para saber o tipo de uso (link ou reflexão), nível de restrição e pilha de chamadas.

  • Sintaxe Veridex:

    ./art/tools/veridex/appcompat.sh --dex-file={apk file}
    
  • Exemplo de resultado veridex:

    #1: Linking greylist-max-o Landroid/animation/AnimationHandler;-><init>()V use(s):
           Lcom/android/systemui/pip/phone/PipMotionHelper;-><init>(Landroid/content/Context;Landroid/app/IActivityManager;Landroid/app/IActivityTaskManager;Lcom/android/systemui/pip/phone/PipMenuActivityController;Lcom/android/internal/policy/PipSnapAlgorithm;Lcom/android/systemui/statusbar/FlingAnimationUtils;)V
    
    #1332: Reflection greylist Landroid/app/Activity;->mMainThread use(s):
           Landroidx/core/app/ActivityRecreator;->getMainThreadField()Ljava/lang/reflect/Field;
    

Para detalhes sobre o uso do veridex, consulte Testar usando o veridex .

Etapa 6: atualizar device.mk

Depois de corrigir todas as falhas de build e ambiente de execução e verificar forem conforme o esperado, defina o seguinte em device.mk:

  • PRODUCT_PRODUCT_VNDK_VERSION := current
  • PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE := true