Android 11 separa la partizione product
, rendendola indipendente dalle partizioni 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'applicazione delle interfacce per le partizioni vendor
).
Applica le interfacce native
Per attivare l'applicazione dell'interfaccia nativa, imposta PRODUCT_PRODUCT_VNDK_VERSION
su current
. La versione viene impostata automaticamente su current
quando il livello dell'API di distribuzione per la destinazione è superiore a 29. L'applicazione forzata consente di:
- Moduli nativi nella partizione
product
da collegare:- In modo statico o dinamico ad altri moduli nella partizione
product
che includono librerie statiche, condivise o di intestazione. - In modo dinamico alle librerie VNDK nella partizione
system
.
- In modo statico o dinamico ad altri moduli nella partizione
- Librerie JNI negli APK non raggruppati nella partizione
product
per collegarsi alle librerie in/product/lib
o/product/lib64
(oltre alle librerie NDK).
L'applicazione delle norme non consente altri collegamenti a partizioni diverse dalla partizione product
.
Applicazione forzata del tempo di creazione (Android.bp)
In Android 11, i moduli di sistema possono creare una variante dell'immagine del prodotto, oltre alle varianti di immagini di base e del fornitore. Quando l'applicazione dell'interfaccia nativa è attivata (PRODUCT_PRODUCT_VNDK_VERSION
è impostato su
current
):
I moduli nativi nella partizione
product
si trovano nella variante di 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 fare riferimento ad altre librerie che specificanoproduct_specific: true
oproduct_available: true
nei fileAndroid.bp
.Le librerie VNDK devono avere
product_available: true
nei fileAndroid.bp
in modo che i binariproduct
possano collegarsi alle librerie VNDK.
La seguente tabella riassume le proprietà Android.bp
utilizzate per creare
varianti delle immagini.
Proprietà in Android.bp | Varianti create | |
---|---|---|
Prima dell'applicazione | Dopo l'applicazione | |
predefinito (nessuno) | core
(include /system , /system_ext e
/product ) |
core
(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 |
core, vendor | principale, fornitore |
product_available: true |
N/D | core, prodotto |
vendor_available: true AND product_available:
true |
N/D | core, prodotto, fornitore |
system_ext_specific: true AND vendor_available:
true |
principale, fornitore | principale, fornitore |
product_specific: true AND vendor_available:
true |
core, vendor | prodotto, fornitore |
Applicazione del tempo di creazione (Android.mk)
Quando l'applicazione dell'interfaccia nativa è attivata, 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
. Se provi a collegarti a moduli diversi da questi, il sistema di compilazione genera un errore di controllo del tipo di link.
Applicazione di runtime
Quando l'applicazione dell'interfaccia nativa è attivata, la configurazione del linker per il linker bionic 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 al di fuori della partizione product
(tuttavia, questi processi possono collegarsi 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
.
Applicare le interfacce Java
Per attivare l'applicazione dell'interfaccia Java, imposta
PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE
su true
. Il valore viene impostato automaticamente su true
quando il livello dell'API di spedizione per la destinazione è superiore a 29. Se l'applicazione delle norme è attivata, consente o meno il seguente accesso:
API | /system | /system_ext | /product | /vendor | /data |
---|---|---|---|---|---|
API pubblica | |||||
@SystemApi | |||||
API @hide |
Come nella partizione vendor
, un'app o una libreria Java nella partizione vendor
è autorizzata a utilizzare solo API pubbliche e di sistema. Il collegamento a una libreria che utilizza API nascoste non è consentito.product
Questa limitazione include il collegamento in fase di compilazione e la riflessione in fase di esecuzione.
Applicazione forzata della fase di creazione
In fase di creazione, Make and soong verificano che i moduli Java nella partizione product
non utilizzino API nascoste controllando i campi platform_apis
e sdk_version
. Il sdk_version
delle app nella partizione product
deve
essere compilato con current
, system_current
o una versione numerica dell'API e
il campo platform_apis
deve essere vuoto.
Applicazione del runtime
Il runtime di Android verifica che le app nella partizione product
non utilizzino API nascoste, inclusa la riflessione. Per maggiori dettagli, consulta Limitazioni relative alle interfacce non SDK.
Attivare l'applicazione dell'interfaccia del prodotto
Segui i passaggi descritti in questa sezione per attivare l'applicazione dell'interfaccia del prodotto.
Passaggio | Attività | Obbligatorio |
---|---|---|
1 | Definisci il tuo file makefile di sistema che specifica i pacchetti per la partizione system , quindi imposta il controllo dei requisiti del percorso degli elementi nell'device.mk (per impedire l'installazione di moduli non di sistema nella partizione system ). |
N |
2 | Ripulisci l'elenco consentito. | N |
3 | Applica le interfacce native e identifica gli errori di collegamento del runtime (può essere eseguito in parallelo con l'applicazione forzata di Java). | Y |
4 | Applica le interfacce Java e verifica il comportamento del runtime (può essere eseguito in parallelo con l'applicazione nativa). | Y |
5 | Controlla i comportamenti di runtime. | Y |
6 | Aggiorna device.mk con l'applicazione dell'interfaccia di prodotto. |
Y |
Passaggio 1: crea il file makefile e abilita il controllo del percorso dell'elemento
In questo passaggio, definisci il file makefile system
.
Crea un file 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 file makefile comune per la partizionesystem
e abilita il controllo dei requisiti del percorso dell'elemento. 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 relativi al percorso dell'elemento
Quando PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS
è impostato su true
o strict
,
il sistema di compilazione impedisce l'installazione dei pacchetti definiti in altri file make nei
percorsi definiti in require-artifacts-in-path
e impedisce ai pacchetti
definiti nel file make corrente di installare elementi al di fuori dei percorsi
definiti in require-artifacts-in-path
.
Nell'esempio precedente, con PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS
impostato su
strict
, i file make esterni a oem_system.mk
non possono includere i moduli installati nella
partizione root
o system
. Per includere questi moduli, devi definirli nel file oem_system.mk
stesso o in un file make incluso.
I tentativi di installare moduli in percorsi non consentiti causano interruzioni della build. Per correggere le interruzioni, esegui una delle seguenti operazioni:
Opzione 1: includi il modulo di sistema nei file make inclusi in
oem_system.mk
. In questo modo, il requisito del percorso dell'elemento è soddisfatto (poiché i moduli ora esistono in un file make incluso) e consente l'installazione nell'insieme di percorsi in "require-artifacts-in-path".Opzione 2: installa i moduli nella partizione
system_ext
oproduct
(e non nella partizionesystem
).Opzione 3: aggiungi moduli al
PRODUCT_ARTIFACT_PATH_REQUIREMENT_ALLOWED_LIST
. Questo elenco elenca i moduli consentiti da installare.
Passaggio 2: svuota l'elenco consentito
In questo passaggio, imposti PRODUCT_ARTIFACT_PATH_REQUIREMENT_ALLOWED_LIST
vuoto in modo che tutti i dispositivi che condividono oem_system.mk
possano condividere anche una singola system
immagine. Per svuotare l'elenco consentito, sposta i moduli nell'elenco nella partizione system_ext
o product
oppure aggiungili ai file di creazione system
. Questo
passaggio è facoltativo perché la definizione di un'immagine system
comune non è obbligatoria per attivare l'applicazione dell'interfaccia del prodotto. Tuttavia, svuotare l'elenco consentito è utile per definire il confine di system
con system_ext
.
Passaggio 3: applica le interfacce native
In questo passaggio, imposti PRODUCT_PRODUCT_VNDK_VERSION := current
, poi cerchi gli errori di compilazione e di runtime e li risolvi. Per controllare l'avvio del dispositivo e i log
e trovare e correggere gli errori di collegamento del runtime:
Imposta
PRODUCT_PRODUCT_VNDK_VERSION := current
.Esegui la build del dispositivo e cerca eventuali errori di compilazione. È probabile che vengano visualizzate alcune interruzioni della compilazione per le varianti di prodotto o le varianti principali mancanti. Le interruzioni più comuni includono:
- Qualsiasi modulo
hidl_interface
che contengaproduct_specific: true
non sarà disponibile per i moduli di sistema. Per risolvere il problema, sostituisciproduct_specific: true
consystem_ext_specific: true
. - Nei moduli potrebbe mancare la variante del prodotto richiesta per i moduli
del prodotto. Per risolvere il problema, rendi il modulo disponibile per la partizione
product
impostandoproduct_available: true
o sposta il modulo nella partizioneproduct
impostandoproduct_specific: true
.
- Qualsiasi modulo
Risolvi gli errori di compilazione e assicurati che la compilazione del dispositivo venga eseguita correttamente.
Esegui il flashing dell'immagine e cerca gli errori di runtime nell'avvio e nei log del dispositivo.
- Se il tag
linker
di un log del caso di test mostra un messaggioCANNOT LINK EXECUTABLE
, nel file make manca una dipendenza (che non è stata acquisita al momento della compilazione). - Per controllarlo dal sistema di compilazione, aggiungi la libreria richiesta al
shared_libs:
o al camporequired:
.
- Se il tag
Risolvi le dipendenze mancanti seguendo le indicazioni riportate sopra.
Passaggio 4: applica le interfacce Java
In questo passaggio dovrai impostare PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE := true
,
quindi trovare e correggere gli errori di compilazione risultanti. Cerca due tipi specifici di errori:
Errori relativi al tipo di link. Questo errore indica che un'app si collega a moduli Java con un
sdk_version
più ampio. Per risolvere il problema, puoi ampliare il valoresdk_version
dell'app o limitare isdk_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 relativi ai 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: controlla i comportamenti di runtime
In questo passaggio verificherai che i comportamenti di runtime siano quelli previsti. Per le app debugging, puoi monitorare l'utilizzo delle API nascoste tramite i 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 limitazione e la pila 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 Eseguire il 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 come previsti, imposta quanto segue in device.mk
:
PRODUCT_PRODUCT_VNDK_VERSION := current
PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE := true