Applica le interfacce di partizione dei prodotti

Android 11 separa la partizione product, rendendola indipendenti dalle partizioni system e vendor. Nell'ambito di queste modifiche, ora puoi controllare l'accesso della partizione product agli asset nativi e Java (simile a come funziona l'applicazione forzata dell'interfaccia per vendor) partizioni di Compute Engine).

Applica le interfacce native

Per attivare l'applicazione forzata dell'interfaccia nativa, imposta PRODUCT_PRODUCT_VNDK_VERSION a current. (La versione viene impostata automaticamente su current quando la spedizione il livello API del target è maggiore di 29). L'applicazione consente di:

  • Moduli nativi nella partizione product da collegare:
    • In modo statico o dinamico rispetto ad altri moduli della partizione product che Includono librerie statiche, condivise o di intestazione.
    • In modo dinamico alle librerie VNDK nella partizione system.
  • Librerie JNI negli APK non raggruppati nella partizione product da collegare a biblioteche in /product/lib o /product/lib64 (oltre alle librerie NDK).

L'applicazione non consente altri link a partizioni diverse da product della partizione di testo.

Applicazione forzata del tempo di creazione (Android.bp)

In Android 11, i moduli di sistema possono creare un prodotto oltre a varianti dell'immagine principali e del fornitore. Se nativo l'applicazione forzata dell'interfaccia è abilitata (PRODUCT_PRODUCT_VNDK_VERSION è impostata su current):

  • I moduli nativi nella partizione product si trovano invece nella variante del prodotto della variante principale.

  • I moduli con product_available: true nei file Android.bp sono disponibili per la variante del prodotto.

  • Le librerie o i file binari che specificano product_specific: true possono collegarsi ad altri librerie che specificano product_specific: true o product_available: true nei file Android.bp.

  • Le librerie VNDK devono includere product_available: true nei file Android.bp in modo che i file binari product possano collegarsi alle librerie VNDK.

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

Proprietà in Android.bp Varianti create
Prima dell'applicazione Dopo l'applicazione
predefinita (nessuna) tronco
(include /system, /system_ext e /product)
tronco
(include /system e /system_ext ma non /product)
system_ext_specific: true nucleo nucleo
product_specific: true nucleo prodotto
vendor: true fornitore fornitore
vendor_available: true principale, fornitore principale, fornitore
product_available: true N/D principale, prodotto
vendor_available: true E product_available: true N/D principale, prodotto, fornitore
system_ext_specific: true E vendor_available: true principale, fornitore principale, fornitore
product_specific: true E vendor_available: true principale, fornitore prodotto, fornitore

Applicazione del tempo di creazione (Android.mk)

Quando l'applicazione forzata dell'interfaccia nativa è abilitata, i moduli nativi installati La partizione product ha un tipo di collegamento native:product che può collegarsi solo a e gli altri moduli native:product o native:vndk. Stai tentando di collegarti a qualsiasi moduli diversi da questi fa sì che il sistema di compilazione generi un controllo del tipo di link .

Applicazione del runtime

Quando l'applicazione forzata dell'interfaccia nativa è abilitata, la configurazione del linker per il linker bionico non consente ai processi di sistema di utilizzare le librerie product, creando una sezione product per i processi product che non possono collegarsi a librerie esterne alla partizione product (tuttavia, questi processi possono collegarsi a librerie VNDK). I tentativi di violare la configurazione del link di runtime causano l'operazione non riesce e genera un messaggio di errore CANNOT LINK EXECUTABLE.

Applica le interfacce Java

Per abilitare l'applicazione forzata dell'interfaccia Java, imposta Da PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE a true. (Il valore è verrà impostato automaticamente su true se il livello API di spedizione per il target è maggiore di 29). Se attivata, l'applicazione consente o non consente quanto segue access:

API /system /system_ext /product /vendor /data
API pubblica
@SystemApi
API @hide

Come nella partizione vendor, un'app o una libreria Java nell'elemento product la partizione può usare solo API pubbliche e di sistema; collegamento a una biblioteca che utilizza API nascoste. Questa limitazione include il collegamento in fase di build in termini di tempo e riflessione.

Applicazione forzata della fase di creazione

In fase di creazione, Make e soong verificano che i moduli Java in product non utilizzano API nascoste, selezionando platform_apis e sdk_version campi. Il valore sdk_version delle app nella partizione product deve essere compilata con current, system_current o versione numerica dell'API e il campo platform_apis deve essere vuoto.

Applicazione del runtime

Il runtime Android verifica che le app nella partizione product non utilizzino API nascoste, inclusa la riflessione. Per maggiori dettagli, consulta l'articolo Limitazioni relative alla non SDK di archiviazione.

Attiva l'applicazione forzata dell'interfaccia del prodotto

Segui i passaggi in questa sezione per attivare l'applicazione forzata dell'interfaccia del prodotto.

Passaggio Attività Obbligatorio
1 Definisci il tuo makefile di sistema che specifica i pacchetti per system, quindi imposta il controllo dei requisiti del percorso degli artefatti in device.mk (per impedire l'installazione di moduli non di sistema alla partizione system). N
2 Elimina l'elenco di elementi consentiti. N
3 Applica le interfacce native e identifica gli errori di collegamento del runtime (può essere eseguito in in parallelo con l'applicazione forzata di Java). Y
4 Applica le interfacce Java e verifica il comportamento di runtime (può essere eseguito in parallelo con l'applicazione forzata nativa). Y
5 Controllare i comportamenti di runtime. Y
6 Aggiorna device.mk con l'applicazione forzata dell'interfaccia del prodotto. Y

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

In questo passaggio definirai il makefile di system.

  1. Crea un makefile che definisce i pacchetti per la partizione system. Per Ad esempio, crea un file oem_system.mk con quanto segue:

    $(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 file device.mk, eredita il makefile comune per system della partizione e abilitare il controllo dei requisiti del percorso dell'artefatto. Ad 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 dei percorsi degli artefatti

Quando PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS è impostato su true o strict, il sistema di compilazione impedisce l'installazione di pacchetti definiti in altri makefile i percorsi definiti in require-artifacts-in-path e impedisce ai pacchetti definita nel makefile corrente dall'installazione di artefatti al di fuori dei percorsi definita in require-artifacts-in-path.

Nell'esempio precedente, con PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS impostato su strict, i file creati al di fuori di oem_system.mk non possono includere moduli installati in la partizione root o system. Per includere questi moduli, devi: definiscile nel file oem_system.mk stesso o in un makefile incluso. I tentativi di installare moduli in percorsi non consentiti causano interruzioni della build. Per risolvere il problema eseguire una delle seguenti operazioni:

  • Opzione 1: includi il modulo di sistema nei makefile inclusi in oem_system.mk. Ciò fa sì che il requisito del percorso dell'artefatto sia soddisfatto (come il moduli sono ora presenti in un makefile incluso) e questo consente l'installazione insieme di percorsi in "richiede-artefatti-in-path".

  • Opzione 2: installa i moduli nella partizione system_ext o product (e non installare moduli nella partizione system).

  • Opzione 3: aggiungi moduli alla PRODUCT_ARTIFACT_PATH_REQUIREMENT_ALLOWED_LIST. Qui sono elencati i moduli consentiti da installare.

Passaggio 2: svuota l'elenco delle app consentite

In questo passaggio, implementerai PRODUCT_ARTIFACT_PATH_REQUIREMENT_ALLOWED_LIST vuoto quindi tutti i dispositivi che condividono oem_system.mk possono anche condividere un singolo system dell'immagine. Per svuotare l'elenco di moduli consentiti, sposta tutti i moduli nell'elenco nella system_ext o product o aggiungile a system file di creazione. Questo è facoltativo perché non è necessario definire un'immagine system comune per abilitare l'applicazione forzata dell'interfaccia del prodotto. Tuttavia, lo svuotamento dell'elenco di elementi consentiti utile per definire il confine di system con system_ext.

Passaggio 3: applica le interfacce native

In questo passaggio, devi impostare PRODUCT_PRODUCT_VNDK_VERSION := current, quindi cercare gli errori di build e di runtime e risolverli. Per controllare l'avvio del dispositivo e i log e trovare e correggere gli errori di collegamento del runtime:

  1. Imposta PRODUCT_PRODUCT_VNDK_VERSION := current.

  2. Crea il dispositivo e cerca gli errori di build. È probabile che vedrai alcune build per le varianti di prodotto mancanti o le varianti principali. Interruzioni comuni include:

    • Qualsiasi modulo hidl_interface con product_specific: true non sarà disponibili per i moduli di sistema. Per risolvere il problema, sostituisci product_specific: true con system_ext_specific: true.
    • Nei moduli potrebbe mancare la variante di prodotto richiesta per il prodotto moduli. Per risolvere il problema, rendi il modulo disponibile per la partizione product tramite impostazione product_available: true o sposta il modulo in product partizionata impostando product_specific: true.
  3. Risolvi gli errori di build e assicurati che il dispositivo venga compilato correttamente.

  4. Esegui il flashing dell'immagine e cerca errori di runtime nell'avvio e nei log del dispositivo.

    • Se il tag linker del log di uno scenario di test mostra CANNOT LINK EXECUTABLE nel file di creazione manca una dipendenza (e non è stata acquisita il tempo necessario per la creazione).
    • Per verificarla dal sistema di compilazione, aggiungi la libreria richiesta alla Campo shared_libs: o required:.
  5. Risolvi le dipendenze mancanti utilizzando le indicazioni fornite sopra.

Passaggio 4: forza l'applicazione delle interfacce Java

In questo passaggio, devi impostare PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE := true, quindi trovare e correggere gli errori di build risultanti. Cerca due tipi specifici di errori:

  • Errori del tipo di link. Questo errore indica che un'app è collegata a moduli Java con un valore sdk_version più ampio. Per risolvere il problema, amplia il campo sdk_version o limita sdk_version della raccolta. 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 dei simboli. 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 verificherai che i comportamenti di runtime siano quelli previsti. Per le app con di cui è possibile eseguire il debug, puoi monitorare l'utilizzo nascosto dell'API tramite il log StrictMode.detectNonSdkApiUsage (che genera un log quando l'app utilizza un API nascosta). In alternativa, puoi utilizzare veridex strumento di analisi statico per conoscere il tipo di utilizzo (collegamento o riflessione), livello di limitazione e stack di chiamate.

  • Sintassi 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 informazioni dettagliate sull'utilizzo di veridex, consulta la sezione Test con veridex lo strumento a riga di comando gcloud.

Passaggio 6: aggiorna device.mk

Dopo aver corretto tutti gli errori di build e di runtime e aver verificato il runtime i comportamenti siano quelli previsti, imposta quanto segue in device.mk:

  • PRODUCT_PRODUCT_VNDK_VERSION := current
  • PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE := true