Android 11 separa la partizione product
, rendendola indipendente dalle partizioni del system
e vendor
. Nell'ambito di queste modifiche, ora puoi controllare l'accesso della partizione product
alle interfacce native e Java (in modo simile al funzionamento dell'imposizione dell'interfaccia per le partizioni vendor
).
Applicazione delle interfacce native
Per abilitare l'applicazione dell'interfaccia nativa, imposta PRODUCT_PRODUCT_VNDK_VERSION
su current
. (La versione viene impostata automaticamente su current
quando il livello API di spedizione per la destinazione è maggiore di 29.) L'applicazione consente:
- Moduli nativi nella partizione
product
da collegare:- Staticamente o dinamicamente ad altri moduli nella partizione
product
che includono librerie statiche, condivise o di intestazione. - Dinamicamente alle librerie VNDK nella partizione
system
.
- Staticamente o dinamicamente ad altri moduli nella partizione
- Librerie JNI negli APK disaggregati nella partizione
product
per collegarsi alle librerie in/product/lib
o/product/lib64
(in aggiunta alle librerie NDK).
L'applicazione non consente altri collegamenti a partizioni diverse dalla partizione product
.
Crea applicazione del tempo (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 dell'interfaccia nativa è abilitata ( PRODUCT_PRODUCT_VNDK_VERSION
è impostato su current
):
I moduli nativi nella partizione
product
si trovano nella variante del prodotto anziché nella variante principale.I moduli con
product_available: true
nei fileAndroid.bp
sono disponibili per la variante del prodotto.Le librerie o i file binari che specificano
product_specific: true
possono collegarsi ad altre librerie che specificanoproduct_specific: true
oproduct_available: true
nei relativi fileAndroid.bp
.Le librerie VNDK devono avere
product_available: true
nei fileAndroid.bp
in modo che i file binariproduct
possano collegarsi alle librerie VNDK.
La tabella seguente riepiloga le proprietà Android.bp
utilizzate per creare varianti di immagine.
Proprietà in Android.bp | Varianti create | |
---|---|---|
Prima dell'esecuzione | Dopo l'esecuzione | |
predefinito (nessuno) | nucleo (include | nucleo (include |
system_ext_specific: true | nucleo | nucleo |
product_specific: true | nucleo | Prodotto |
vendor: true | venditore | venditore |
vendor_available: true | nucleo, venditore | nucleo, venditore |
product_available: true | N / A | prodotto principale |
vendor_available: true E product_available: true | N / A | nucleo, prodotto, fornitore |
system_ext_specific: true E vendor_available: true | nucleo, venditore | nucleo, venditore |
product_specific: true E vendor_available: true | nucleo, venditore | prodotto, venditore |
Crea applicazione del tempo (Android.mk)
Quando l'imposizione dell'interfaccia nativa è abilitata, i moduli nativi installati nella partizione product
hanno un tipo di collegamento native:product
che può collegarsi solo ad altri moduli native:product
o native:vndk
. 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 in fase di esecuzione
Quando è abilitata l'applicazione dell'interfaccia nativa, 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 alle librerie esterne alla partizione product
(tuttavia, tali processi possono collegamento alle librerie VNDK). I tentativi di violare la configurazione del collegamento di runtime causano il fallimento del processo e generano un messaggio di errore CANNOT LINK EXECUTABLE
.
Applicazione delle interfacce Java
Per abilitare l'imposizione dell'interfaccia Java, impostare PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE
su true
. (Il valore viene impostato automaticamente su true
quando il livello API di spedizione per la destinazione è maggiore di 29.) Se abilitata, l'applicazione consente/impedisce il seguente accesso.
API | /sistema | /sistema_est | /Prodotto | /venditore | /dati |
---|---|---|---|---|---|
API pubblica | |||||
@SystemApi | |||||
API @hide |
Come nella partizione vendor
, un'app o una libreria Java nella partizione product
può utilizzare solo API pubbliche 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.
Costruisci l'applicazione del tempo
In fase di compilazione, Make e Soong verificano che i moduli Java nella partizione product
non utilizzino API nascoste controllando i campi platform_apis
e sdk_version
. Il campo sdk_version
delle app nella partizione product
deve essere compilato con la versione current
, system_current
o numerica dell'API e il campo platform_apis
deve essere vuoto.
Applicazione in fase di esecuzione
Il runtime Android verifica che le app nella partizione product
non utilizzino API nascoste, inclusa la riflessione. Per maggiori dettagli, fare riferimento a Restrizioni sulle interfacce non SDK .
Abilitazione dell'applicazione dell'interfaccia del prodotto
Utilizzare i passaggi contenuti in questa sezione per abilitare l'applicazione dell'interfaccia del prodotto.
Fare un passo | Compito | Necessario |
---|---|---|
1 | Definisci il tuo makefile di sistema che specifica i pacchetti per la partizione system , quindi imposta il controllo dei requisiti del percorso degli artefatti in device.mk (per impedire l'installazione di moduli non di sistema nella partizione system ). | N |
2 | Pulisci l'elenco dei consentiti. | N |
3 | Applica interfacce native e identifica gli errori di collegamento in fase di runtime (può essere eseguito in parallelo con l'attuazione Java). | Y |
4 | Applica le interfacce Java e verifica il comportamento in fase di esecuzione (può essere eseguito in parallelo con l'applicazione nativa). | Y |
5 | Controlla i comportamenti in fase di esecuzione. | Y |
6 | Aggiorna device.mk con l'applicazione dell'interfaccia del prodotto. | Y |
Passaggio 1: crea il makefile e abilita il controllo del percorso degli artefatti
In questo passaggio si definisce il makefile system
.
Crea un makefile che definisce i pacchetti per la partizione
system
. Ad esempio, crea un fileoem_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),)
Nel file
device.mk
, eredita il makefile comune per la partizionesystem
e abilita il controllo dei requisiti del percorso dell'artefatto. 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
, il sistema di compilazione impedisce ai pacchetti definiti in altri makefile di installarsi nei percorsi definiti in require-artifacts-in-path
e impedisce ai pacchetti definiti nel makefile corrente di installare artefatti al di fuori dei percorsi definiti in require-artifacts-in-path
.
Nell'esempio precedente, con PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS
impostato su strict
, i makefile esterni oem_system.mk
non possono includere moduli installati nella partizione root
o system
. Per includere questi moduli, è necessario definirli nel file oem_system.mk
stesso o in un makefile incluso. I tentativi di installare moduli su percorsi non consentiti causano interruzioni della compilazione. Per correggere le interruzioni, effettuare una delle seguenti operazioni:
Opzione 1: includere il modulo di sistema nei makefile inclusi in
oem_system.mk
. Ciò 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 nella partizione
system_ext
oproduct
(e non installare i moduli nella partizionesystem
).Opzione 3: aggiungere moduli a
PRODUCT_ARTIFACT_PATH_REQUIREMENT_ALLOWED_LIST
. Elenca i moduli consentiti da installare.
Passaggio 2: svuota l'elenco consentito
In questo passaggio, rendi PRODUCT_ARTIFACT_PATH_REQUIREMENT_ALLOWED_LIST
vuoto in modo che tutti i dispositivi che condividono oem_system.mk
possano condividere anche una singola immagine system
. Per svuotare l'elenco consentito, spostare tutti i moduli nell'elenco nella partizione system_ext
o product
oppure aggiungerli ai file make system
. Questo passaggio è facoltativo perché non è necessaria la definizione di un'immagine system
comune per abilitare l'applicazione dell'interfaccia del prodotto. Tuttavia, svuotare l'elenco consentito è utile per definire il limite system
con system_ext
.
Passaggio 3: applicare le interfacce native
In questo passaggio imposti PRODUCT_PRODUCT_VNDK_VERSION := current
, quindi cerchi gli errori di build e di runtime e li risolvi. Per controllare l'avvio e i registri del dispositivo e individuare e correggere gli errori di collegamento in runtime:
Imposta
PRODUCT_PRODUCT_VNDK_VERSION := current
.Costruisci il dispositivo e cerca gli errori di costruzione. È probabile che vengano visualizzate alcune interruzioni di build per varianti di prodotto mancanti o varianti principali. Le pause comuni includono:
- Qualsiasi modulo
hidl_interface
che abbiaproduct_specific: true
non sarà disponibile per i moduli di sistema. Per risolvere il problema, sostituireproduct_specific: true
consystem_ext_specfic: true
. - Ai moduli potrebbe mancare la variante di prodotto richiesta per i moduli di prodotto. Per risolvere il problema, rendi il modulo disponibile nella partizione
product
impostandoproduct_available: true
oppure sposta il modulo nella partizione delproduct
impostandoproduct_specific: true
.
- Qualsiasi modulo
Risolvi gli errori di creazione e assicurati che il dispositivo venga creato correttamente.
Esegui il flashing dell'immagine e cerca gli errori di runtime nell'avvio e nei log del dispositivo.
- Se il tag
linker
da un registro del test case mostra un messaggioCANNOT LINK EXECUTABLE
, nel file make manca una dipendenza (e non è stato acquisito in fase di compilazione). - Per verificarlo dal sistema di compilazione, aggiungi la libreria richiesta al campo
shared_libs:
orequired:
- Se il tag
Risolvi le dipendenze mancanti utilizzando le indicazioni fornite sopra.
Passaggio 4: applicare le interfacce Java
In questo passaggio imposti PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE := true
, quindi trovi e correggi gli errori di compilazione risultanti. Cerca due tipi specifici di errori:
Errori nel tipo di collegamento. Questo errore indica che un'app si collega a moduli Java con una
sdk_version
più ampia. Per risolvere il problema, puoi ampliaresdk_version
dell'app o limitaresdk_version
della libreria. Errore di esempio: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 nei 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. Errore di esempio:
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: verificare i comportamenti di runtime
In questo passaggio si verifica che i comportamenti di runtime siano quelli previsti. Per le app di cui è possibile eseguire il debug, puoi monitorare l'utilizzo dell'API nascosta tramite log utilizzando StrictMode.detectNonSdkApiUsage
(che genera un log quando l'app utilizza un'API nascosta). In alternativa, puoi utilizzare lo strumento di analisi statica veridex per ottenere il tipo di utilizzo (collegamento o riflessione), il livello di restrizione e lo 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 dettagli sull'utilizzo di Veridex, fare riferimento a Test utilizzando lo strumento Veridex .
Passaggio 6: aggiorna device.mk
Dopo aver corretto tutti gli errori di compilazione e di runtime e aver verificato che i comportamenti di runtime siano quelli previsti, imposta quanto segue in device.mk
:
-
PRODUCT_PRODUCT_VNDK_VERSION := current
-
PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE := true