Android 11 dissocie la partition product
, la rendant indépendante des partitions system
et vendor
. Parmi ces modifications, vous pouvez désormais contrôler l'accès de la partition product
aux interfaces natives et Java (ce qui est semblable au fonctionnement de l'application des interfaces pour les partitions vendor
).
Appliquer des interfaces natives
Pour activer l'application de l'interface native, définissez PRODUCT_PRODUCT_VNDK_VERSION
sur current
. (La version est automatiquement définie sur current
lorsque le niveau de l'API de distribution pour la cible est supérieur à 29.) L'application des règles permet:
- Modules natifs dans la partition
product
à associer :- De manière statique ou dynamique à d'autres modules de la partition
product
qui incluent des bibliothèques statiques, partagées ou d'en-tête. - Dynamiquement aux bibliothèques VNDK dans la partition
system
.
- De manière statique ou dynamique à d'autres modules de la partition
- Bibliothèques JNI dans les APK non groupés de la partition
product
à associer aux bibliothèques de/product/lib
ou/product/lib64
(en plus des bibliothèques NDK).
L'application ne permet pas d'autres liens vers des partitions autres que la partition product
.
Application du délai de compilation (Android.bp)
Dans Android 11, les modules système peuvent créer une variante d'image de produit en plus des variantes d'image de base et du fournisseur. Lorsque l'application de l'interface native est activée (PRODUCT_PRODUCT_VNDK_VERSION
est défini sur current
):
Les modules natifs de la partition
product
se trouvent dans la variante du produit et non dans la variante principale.Les modules avec
product_available: true
dans leurs fichiersAndroid.bp
sont disponibles pour la variante de produit.Les bibliothèques ou binaires qui spécifient
product_specific: true
peuvent associer d'autres bibliothèques qui spécifientproduct_specific: true
ouproduct_available: true
dans leurs fichiersAndroid.bp
.Les bibliothèques VNDK doivent contenir
product_available: true
dans leurs fichiersAndroid.bp
afin que les binairesproduct
puissent s'associer aux bibliothèques VNDK.
Le tableau suivant récapitule les propriétés Android.bp
utilisées pour créer des variantes d'images.
Propriétés dans Android.bp | Variantes créées | |
---|---|---|
Avant l'application | Après l'application | |
par défaut (aucune) | principal(inclut /system , /system_ext et /product ) |
de base(inclut /system et /system_ext , mais pas /product ) |
system_ext_specific: true |
core | core |
product_specific: true |
core | produit |
vendor: true |
fournisseur | fournisseur |
vendor_available: true |
core, vendor | core, vendor |
product_available: true |
N/A | cœur, produit |
vendor_available: true ET product_available:
true |
N/A | core, product, vendor |
system_ext_specific: true ET vendor_available:
true |
cœur, fournisseur | core, vendor |
product_specific: true ET vendor_available:
true |
core, vendor | produit, fournisseur |
Application du moment de compilation (Android.mk)
Lorsque l'application de l'interface native est activée, les modules natifs installés dans la partition product
ont un type de lien native:product
qui ne peut se lier qu'à d'autres modules native:product
ou native:vndk
. Si vous tentez d'associer des modules autres que ceux-ci, le système de compilation génère une erreur de vérification du type de lien.
Application au moment de l'exécution
Lorsque l'application de l'interface native est activée, la configuration du liant pour le liant bionic n'autorise pas les processus système à utiliser les bibliothèques product
, créant ainsi une section product
pour les processus product
qui ne peuvent pas lier les bibliothèques en dehors de la partition product
(ces processus peuvent toutefois lier les bibliothèques VNDK). Les tentatives de non-respect de la configuration du lien d'exécution entraînent l'échec du processus et génèrent un message d'erreur CANNOT LINK EXECUTABLE
.
Appliquer des interfaces Java
Pour activer l'application de l'interface Java, définissez PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE
sur true
. (La valeur est automatiquement définie sur true
lorsque le niveau de l'API de diffusion de la cible est supérieur à 29.) Lorsqu'elle est activée, l'application permet ou interdit l'accès suivant:
API | /system | /system_ext | /product | /vendor | /data |
---|---|---|---|---|---|
API publique | |||||
@SystemApi | |||||
API @hide |
Comme dans la partition vendor
, les applications ou les bibliothèques Java de la partition product
ne sont autorisées à utiliser que des API publiques et système. L'association à une bibliothèque qui utilise des API masquées n'est pas autorisée. Cette restriction inclut l'association au moment de la compilation et la réflexion au moment de l'exécution.
Application forcée de la durée de compilation
Au moment de la compilation, Make et Soong vérifient que les modules Java de la partition product
n'utilisent pas d'API masquées en vérifiant les champs platform_apis
et sdk_version
. Le sdk_version
des applications de la partition product
doit être renseigné avec current
, system_current
ou la version numérique de l'API, et le champ platform_apis
doit être vide.
Application au moment de l'exécution
L'environnement d'exécution Android vérifie que les applications de la partition product
n'utilisent pas d'API masquées, y compris la réflexion. Pour en savoir plus, consultez la section Restrictions concernant les interfaces non SDK.
Activer l'application des règles concernant l'interface produit
Suivez les étapes de cette section pour activer l'application des règles concernant l'interface produit.
Étape | Tâche | Obligatoire |
---|---|---|
1 | Définissez votre propre fichier makefile système qui spécifie les packages pour la partition system , puis définissez la vérification des exigences de chemin d'accès aux artefacts dans le device.mk (pour empêcher l'installation de modules non système sur la partition system ). |
N |
2 | Nettoyez la liste d'autorisations. | N |
3 | Appliquez des interfaces natives et identifiez les échecs de liaison d'exécution (peut s'exécuter en parallèle avec l'application de Java). | O |
4 | Appliquez les interfaces Java et vérifiez le comportement d'exécution (peut s'exécuter en parallèle avec l'application forcée native). | O |
5 | Vérifiez les comportements d'exécution. | O |
6 | Mise à jour de device.mk avec application de l'interface produit. |
O |
Étape 1: Créer un fichier makefile et activer la vérification du chemin d'accès aux artefacts
Au cours de cette étape, vous allez définir le fichier Makefile system
.
Créez un fichier makefile qui définit les packages pour la partition
system
. Par exemple, créez un fichieroem_system.mk
avec les éléments suivants:$(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),)
Dans le fichier
device.mk
, héritez du fichier makefile commun pour la partitionsystem
et activez la vérification des exigences concernant le chemin d'accès aux artefacts. Exemple :$(call inherit-product, $(SRC_TARGET_DIR)/product/oem_system.mk) # Enable artifact path requirements checking PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS := strict
À propos des exigences concernant le chemin d'accès aux artefacts
Lorsque PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS
est défini sur true
ou strict
, le système de compilation empêche les packages définis dans d'autres fichiers makefile de s'installer vers les chemins définis dans require-artifacts-in-path
et empêche les packages définis dans le fichier makefile actuel d'installer des artefacts en dehors des chemins définis dans require-artifacts-in-path
.
Dans l'exemple ci-dessus, avec PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS
défini sur strict
, les fichiers de compilation en dehors de oem_system.mk
ne peuvent pas inclure de modules installés sur la partition root
ou system
. Pour inclure ces modules, vous devez les définir dans le fichier oem_system.mk
lui-même ou dans un fichier makefile inclus.
Les tentatives d'installation de modules sur des chemins d'accès non autorisés entraînent des interruptions de compilation. Pour corriger les coupures, effectuez l'une des opérations suivantes:
Option 1:incluez le module système dans les fichiers de compilation inclus dans
oem_system.mk
. Cela permet de répondre à l'exigence de chemin d'accès des artefacts (car les modules existent désormais dans un fichier makefile inclus) et permet ainsi d'installer l'ensemble de chemins dans "require-artifacts-in-path".Option 2:installez des modules sur la partition
system_ext
ouproduct
(et n'installez pas de modules sur la partitionsystem
).Option 3:Ajouter des modules à
PRODUCT_ARTIFACT_PATH_REQUIREMENT_ALLOWED_LIST
. Cette page liste les modules autorisés à installer.
Étape 2: Videz la liste d'autorisation
À cette étape, vous videz PRODUCT_ARTIFACT_PATH_REQUIREMENT_ALLOWED_LIST
afin que tous les appareils partageant oem_system.mk
puissent également partager une seule image system
. Pour vider la liste des modules autorisés, déplacez les modules de la liste vers la partition system_ext
ou product
, ou ajoutez-les aux fichiers de compilation system
. Cette étape est facultative, car il n'est pas nécessaire de définir une image system
commune pour activer l'application de l'interface produit. Toutefois, vider la liste d'autorisations est utile pour définir la limite system
avec system_ext
.
Étape 3: Appliquez les interfaces natives
Au cours de cette étape, vous définissez PRODUCT_PRODUCT_VNDK_VERSION := current
, puis recherchez les erreurs de compilation et d'exécution, puis corrigez-les. Pour vérifier le démarrage et les journaux de l'appareil, et rechercher et corriger les échecs de liaison d'exécution:
Définissez
PRODUCT_PRODUCT_VNDK_VERSION := current
.Créez l'appareil et recherchez les erreurs de compilation. Vous constaterez probablement quelques interruptions de compilation pour les variantes de produits ou les variantes principales manquantes. Voici quelques exemples de coupures courantes:
- Tout module
hidl_interface
qui possèdeproduct_specific: true
ne sera pas disponible pour les modules système. Pour résoudre ce problème, remplacezproduct_specific: true
parsystem_ext_specific: true
. - Il est possible que les modules ne contiennent pas la variante de produit requise. Pour résoudre ce problème, rendez ce module disponible dans la partition
product
en définissantproduct_available: true
ou déplacez-le vers la partitionproduct
en définissantproduct_specific: true
.
- Tout module
Résolvez les erreurs de compilation et assurez-vous que l'appareil a bien été compilé.
Flashez l'image et recherchez les erreurs d'exécution dans le démarrage et les journaux de l'appareil.
- Si la balise
linker
d'un journal de test affiche un messageCANNOT LINK EXECUTABLE
, une dépendance est manquante dans le fichier de compilation (et n'a pas été capturée au moment de la compilation). - Pour le vérifier à partir du système de compilation, ajoutez la bibliothèque requise au champ
shared_libs:
ourequired:
.
- Si la balise
Résolvez les dépendances manquantes en suivant les instructions ci-dessus.
Étape 4: Appliquer des interfaces Java
Au cours de cette étape, vous allez définir PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE := true
, puis rechercher et corriger les erreurs de compilation qui en résultent. Recherchez deux types d'erreurs spécifiques:
Erreurs de type de lien Cette erreur indique qu'une application est liée à des modules Java ayant un
sdk_version
plus large. Pour résoudre le problème, vous pouvez élargir lesdk_version
de l'application ou limiter lesdk_version
de la bibliothèque. Exemple d'erreur :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.
Erreurs de symbole. Cette erreur indique qu'un symbole est introuvable, car il se trouve dans une API masquée. Pour résoudre ce problème, utilisez une API visible (non masquée) ou trouvez une autre solution. Exemple d'erreur :
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
Étape 5: Vérifier les comportements d'exécution
Au cours de cette étape, vous vérifiez que les comportements d'exécution sont conformes aux attentes. Pour les applications débogables, vous pouvez surveiller l'utilisation des API masquées en créant un journal à l'aide de StrictMode.detectNonSdkApiUsage
(qui génère un journal lorsque l'application utilise une API masquée). Vous pouvez également utiliser l'outil d'analyse statique veridex pour obtenir le type d'utilisation (lien ou réflexion), le niveau de restriction et la pile d'appels.
Syntaxe Veridex:
./art/tools/veridex/appcompat.sh --dex-file={apk file}
Exemple de résultat 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;
Pour en savoir plus sur l'utilisation de Veridex, consultez Tester avec l'outil Veridex.
Étape 6: Mettre à jour device.mk
Après avoir résolu tous les échecs de compilation et d'exécution, et vérifié que les comportements d'exécution sont conformes aux attentes, définissez les éléments suivants dans device.mk
:
PRODUCT_PRODUCT_VNDK_VERSION := current
PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE := true