Applicazione delle interfacce di partizione del prodotto

Android 11 unbundles il product di partizione, che lo rende indipendente dai system e vendor partizioni. Come parte di questi cambiamenti, è ora possibile controllare il product accesso della partizione di interfacce native e Java (che è simile a come funziona l'applicazione di interfaccia per vendor partizioni).

Applicazione di interfacce native

Per abilitare l'applicazione interfaccia nativa, insieme PRODUCT_PRODUCT_VNDK_VERSION al current . (La versione viene automaticamente impostato current quando il livello di API trasporto per il bersaglio è maggiore di 29.) L'applicazione permette:

  • Moduli nativi del product partizione da collegamento:
    • Statico o dinamico ad altri moduli del product partizione che includono statica, condivisa o librerie di intestazione.
    • Dinamicamente alle librerie VNDK del system partizione.
  • Librerie JNI a APK unbundling nel product partizione di creare un collegamento a librerie in /product/lib o /product/lib64 (questo è in aggiunta alle librerie NDK).

L'applicazione non consente altri collegamenti alle partizioni diverse da quella product partizione.

Imposizione del tempo di compilazione (Android.bp)

In Android 11, i moduli di sistema possono creare una variante dell'immagine del prodotto oltre alle varianti dell'immagine principale e del fornitore. Quando l'applicazione interfaccia nativa è abilitata ( PRODUCT_PRODUCT_VNDK_VERSION è impostato su current ):

  • Moduli nativi del product partizione sono nella variante prodotto invece della variante nucleo.

  • I moduli con vendor_available: true nelle loro Android.bp file sono disponibili per la variante del prodotto e la variante fornitore.

  • Librerie o binari che specificano product_specific: true possibile collegare ad altre biblioteche che specificano product_specific: true o vendor_available: true nelle loro Android.bp file.

  • Biblioteche VNDK devono avere vendor_available: true nelle loro Android.bp file in modo product binari possono collegare a librerie VNDK.

La seguente tabella riassume le Android.bp proprietà utilizzate per creare un'immagine varianti.

Proprietà in Android.bp Varianti create
Prima dell'applicazione Dopo l'applicazione
predefinito (nessuno) nucleo

(include /system , /system_ext e /product )

nucleo

(include /system e /system_ext ma non /product )

system_ext_specific: true nucleo nucleo
product_specific: true nucleo Prodotto
vendor: true venditore venditore
vendor_available: true nucleo, venditore nucleo, prodotto, fornitore
system_ext_specific: true E vendor_available: true nucleo, venditore nucleo, prodotto, fornitore
product_specific: true E vendor_available: true nucleo, venditore prodotto, venditore

Imposizione del tempo di compilazione (Android.mk)

Quando l'applicazione interfaccia nativa è abilitata, moduli nativi installati al product partizione hanno un native:product tipo di collegamento che può collegarsi solo ad altre native:product o native:vndk moduli. Il tentativo di collegarsi a moduli diversi da questi fa sì che il sistema di compilazione generi un errore di controllo del tipo di collegamento.

Applicazione del tempo di esecuzione

Quando l'applicazione interfaccia nativa è attivata, la configurazione linker per il linker bionico non consente processi di sistema per l'uso product librerie, la creazione di un product sezione per i product processi che non possono collegarsi alle librerie al di fuori del product di partizione (tuttavia, tali processi possono collegamento alle librerie VNDK). I tentativi di violare la configurazione del collegamento runtime causa il processo di fallire e generare un CANNOT LINK EXECUTABLE messaggio di errore.

Applicazione delle interfacce Java

Per abilitare l'applicazione interfaccia Java, insieme PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE al true . (Il valore è impostato automaticamente al true quando il livello di API di spedizione per il bersaglio è maggiore di 29) Quando abilitato, l'applicazione consente / non consente il seguente accesso.

API /sistema /system_ext /Prodotto /venditore /dati
API pubblica
@SystemApi
@nascondi API

Come nel vendor di partizione, un'applicazione o una libreria Java nel product partizione è consentito di utilizzare le API esclusivamente pubblici e di sistema; non è consentito il collegamento a una libreria che utilizza API nascoste. Questa restrizione include il collegamento in fase di compilazione e la riflessione in fase di esecuzione.

Applicazione del tempo di costruzione

Al momento della compilazione, Marca e Soong verificare che i moduli Java nel product partizione di non utilizzare le API nascoste controllando i platform_apis e sdk_version campi. La sdk_version di applicazioni del product partizione deve essere riempito con current , system_current , o la versione numerica delle API, e il platform_apis campo deve essere vuoto.

Applicazione del tempo di esecuzione

I verifica runtime Android che le applicazioni del product partizione non utilizzano API nascosti, tra cui la riflessione. Per ulteriori informazioni, fare riferimento a restrizioni sulle interfacce non-SDK .

Abilitazione dell'applicazione dell'interfaccia del prodotto

Utilizzare i passaggi in questa sezione per abilitare l'applicazione dell'interfaccia del prodotto.

Fare un passo Compito Necessario
1 Definire il proprio sistema di makefile che specifica i pacchetti per il system partizione, quindi impostare il controllo requisito manufatti percorso nella device.mk (per evitare che i moduli non di sistema di installare il system partizione). n
2 Pulisci l'elenco consentito. n
3 Applicare interfacce native e identificare errori di collegamento runtime (può essere eseguito in parallelo con l'applicazione Java).
4 Applica le interfacce Java e verifica il comportamento di runtime (può essere eseguito in parallelo con l'applicazione nativa).
5 Controlla i comportamenti di runtime.
6 Aggiornamento device.mk con le forze interfaccia del prodotto.

Passaggio 1: crea un makefile e abilita il controllo del percorso dell'artefatto

In questo passaggio, si definisce il system makefile.

  1. Creare un makefile che definisce i pacchetti per il system partizione. Ad esempio, creare un oem_system.mk file con il seguente:

    $(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. Nel device.mk di file, erediterà il makefile comune per il system partizioni e abilitare il percorso manufatto controllare le esigenze. Per esempio:

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

Informazioni sui requisiti del percorso dell'artefatto

Quando PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS è impostato su true o strict , i pacchetti previene sistema di generazione definiti in altri makefile dall'installazione ai percorsi definiti require-artifacts-in-path e impedisce pacchetti definite nel makefile corrente da installare artefatti fuori dei percorsi definiti nel require-artifacts-in-path .

Nell'esempio sopra, con PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS impostati strict , Makefiles fuori oem_system.mk non può contenere moduli installati alla root o system partizione. Per includere questi moduli, è necessario definirli nel oem_system.mk file stesso o in un makefile inclusi. I tentativi di installare moduli su percorsi non consentiti causano interruzioni della compilazione. Per correggere le interruzioni, eseguire una delle seguenti operazioni:

  • Opzione 1: includere il modulo sistema nelle makefile inclusi in oem_system.mk . Questo fa sì che il requisito del percorso dell'artefatto sia soddisfatto (poiché i moduli ora esistono in un makefile incluso) e quindi consente l'installazione nell'insieme di percorsi in `require-artifacts-in-path.

  • Opzione 2: Installare i moduli al system_ext o product partizione (e non installare i moduli per il system partizione).

  • Opzione 3: Aggiungere moduli al PRODUCT_ARTIFACT_PATH_REQUIREMENT_ALLOWED_LIST . Elenca i moduli consentiti da installare.

Passaggio 2: svuota l'elenco consentito

In questa fase, si effettua la PRODUCT_ARTIFACT_PATH_REQUIREMENT_ALLOWED_LIST svuotare in modo che tutti i dispositivi che condividono oem_system.mk possono anche condividere un unico system immagine. Per svuotare l'elenco consentito, spostare tutti i moduli nella lista per lo system_ext o product partizione o aggiungerli al system file make. Questo passaggio è opzionale perché definire un comune system immagine non è necessaria per consentire l'esecuzione interfaccia del prodotto. Tuttavia, svuotare la lista consentito è utile per la definizione del system confine con la system_ext .

Passaggio 3: applica le interfacce native

In questa fase, è possibile impostare PRODUCT_PRODUCT_VNDK_VERSION := current , quindi cercare errori di generazione e di runtime e risolverli. Per controllare l'avvio e i registri del dispositivo e trovare e correggere gli errori di collegamento in fase di esecuzione:

  1. Set PRODUCT_PRODUCT_VNDK_VERSION := current .

  2. Crea il dispositivo e cerca gli errori di compilazione. È probabile che tu veda alcune interruzioni di build per varianti di prodotto mancanti o varianti principali. Le interruzioni comuni includono:

    • Qualsiasi hidl_interface modulo che ha product_specific: true non sarà disponibile per i moduli del sistema. Per risolvere il problema, sostituire product_specific: true con system_ext_specfic: true .
    • Ai moduli potrebbe mancare la variante di prodotto richiesta per i moduli di prodotto. Per risolvere il problema, fanno si che il modulo a disposizione del product partizione impostando vendor_available: true o spostare il modulo al product partizione impostando product_specific: true .
  3. Risolvi gli errori di compilazione e assicurati che il dispositivo venga compilato correttamente.

  4. Flashare l'immagine e cercare errori di runtime nell'avvio e nei log del dispositivo.

    • Se il linker tag da un registro banco di prova mostra un CANNOT LINK EXECUTABLE messaggio, il file make manca una dipendenza (e non è stato catturato al momento della compilazione).
    • Per controllare dal sistema di compilazione, aggiungere la libreria richiesta per le shared_libs: o required: campo.
  5. Risolvere le dipendenze mancanti utilizzando la guida fornita sopra.

Passaggio 4: applicare le interfacce Java

In questa fase, è possibile impostare PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE := true , quindi trovare e correggere errori di generazione derivano. Cerca due tipi specifici di errori:

  • Errori di tipo collegamento. Questo errore indica che un app collega ai moduli Java che hanno un più ampio sdk_version . Per risolvere il problema, è possibile ampliare l'applicazione del sdk_version o limitare della biblioteca sdk_version . Esempio di errore:

    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.
    
  • Errori di simbolo. Questo errore indica che non è possibile trovare un simbolo perché si trova in un'API nascosta. Per risolvere il problema, utilizza un'API visibile (non nascosta) o trova un'alternativa. Esempio di errore:

    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
    

Passaggio 5: controlla i comportamenti di runtime

In questo passaggio si verifica che i comportamenti di runtime siano quelli previsti. Per le applicazioni che sono debuggable, è possibile monitorare l'utilizzo di API nascosta dal registro utilizzando StrictMode.detectNonSdkApiUsage (che genera un log quando l'applicazione utilizza un'API nascosto). In alternativa, è possibile utilizzare lo Veridex strumento di analisi statica per ottenere il tipo di utilizzo (collegamento o riflessione), livello di restrizione, e stack di chiamate.

  • Sintassi di Veridex:

    ./art/tools/veridex/appcompat.sh --dex-file={apk file}
    
  • Esempio di risultato 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;
    

Per i dettagli sul loro utilizzo Veridex, fare riferimento alla prova con lo strumento Veridex .

Passaggio 6: aggiorna device.mk

Dopo aver sistemato tutti i fallimenti di compilazione e di runtime, e la verifica che i comportamenti di runtime sono come previsto, impostare quanto segue in device.mk :

  • PRODUCT_PRODUCT_VNDK_VERSION := current
  • PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE := true