Image système partagée

Cette page présente plusieurs mécanismes que les OEM Android peuvent utiliser pour disposer d'une image système partagée (SSI) sur plusieurs gammes de produits. Elle propose également une procédure pour baser une SSI appartenant à un OEM sur une image système générique (GSI) créée par AOSP.

Arrière-plan

Le framework Android Open Source Project (AOSP) est conforme à l'architecture Mainline pour maintenir la rétrocompatibilité avec les anciennes implémentations de fournisseurs. Par exemple, une image système générique (GSI) créée à partir de sources AOSP Android 10 peut s'exécuter sur n'importe quel appareil compatible avec Treble exécutant Android 8 ou une version ultérieure.

Mainline y parvient en divisant Android en deux parties distinctes : l'implémentation du fournisseur spécifique au matériel et le framework générique de l'OS Android. Chaque composant est installé dans une partition distincte : la partition du fournisseur pour les logiciels spécifiques au matériel et la partition système pour l'OS générique. Une interface versionnée, appelée interface du fournisseur (VINTF), est appliquée entre elles. Ce système de partitionnement permet aux OEM de modifier la partition système sans toucher à la partition du fournisseur, et inversement.

Historiquement, les fournisseurs de SoC et les OEM ont fortement modifié la version du framework Android livrée sur les appareils grand public (pour en savoir plus, consultez Cycle de vie d'une version Android Release). Comme ces extensions de framework étaient rarement conçues dans un souci de rétrocompatibilité, les modifications spécifiques aux appareils ont considérablement augmenté la complexité et le coût financier des mises à niveau ultérieures de l'OS. Dans Android 10 (niveau d'API 29) et versions antérieures, l'écosystème ne disposait pas d'une architecture claire et standardisée permettant aux partenaires de créer des extensions modulaires pour le framework Android.

Cette page explique comment les fournisseurs de SoC et les OEM peuvent créer une image système partagée (SSI). Une SSI est une image de framework unifiée créée à partir de sources d'OS Android qui peut être réutilisée sur plusieurs appareils. En maintenant une rétrocompatibilité propre avec les implémentations de fournisseurs grâce à cette architecture partitionnée, une SSI réduit considérablement le coût et la complexité des mises à niveau de l'OS Android.

Pour en savoir plus sur l'implémentation, consultez Étapes suggérées pour une SSI basée sur une GSI. Les étapes sont modulaires. En fonction de votre architecture, vous pouvez choisir d'implémenter des étapes spécifiques (par exemple, l'étape 1 : Hériter de generic_system.mk pour l'image système OEM (GSI OEM)) plutôt que toutes les étapes.

Présentation de la SSI

Avec la SSI, les composants logiciels spécifiques aux produits et les extensions OEM sont placés dans une nouvelle partition /product. Les composants de la partition /product utilisent une interface stable et bien définie pour interagir avec les composants de la partition /system. Les OEM peuvent choisir de créer une seule SSI ou un petit nombre de SSI à utiliser sur plusieurs références d'appareils. Lorsqu'une nouvelle version de l'OS Android est publiée, les OEM n'investissent qu'une seule fois dans la mise à jour de leurs SSI vers la dernière version d'Android. Ils peuvent réutiliser les SSI pour mettre à jour plusieurs appareils sans mettre à jour la partition /product.

Les OEM et les fournisseurs de SoC peuvent créer des SSI incluant des fonctionnalités et des modifications personnalisées. Les mécanismes et les bonnes pratiques présentés sur cette page sont destinés aux OEM afin d'atteindre les objectifs clés suivants :

  • Réutiliser la SSI sur plusieurs références d'appareils.
  • Mettre à jour le système Android avec les extensions modulaires pour simplifier les mises à niveau de l'OS.

L'idée principale de séparer les composants spécifiques aux produits dans la partition produit est similaire à celle de Mainline, qui sépare les composants spécifiques aux SoC dans la partition du fournisseur. Une interface produit (semblable à VINTF) permet la communication entre la SSI et la partition produit. En ce qui concerne la SSI, le terme composants décrit toutes les ressources, les binaires, les textes et les bibliothèques qui sont installés dans les images, qui deviennent des partitions.

Partitions autour de la SSI

La figure 1 montre les partitions autour de la SSI, ainsi que les interfaces versionnées entre les partitions et les règles sur les interfaces. Cette section explique en détail chacune des partitions et interfaces.

Partitions et interfaces autour du schéma bloc SSI

Figure 1. Partitions et interfaces autour de la SSI.

Images et partitions

Les informations de cette section distinguent les termes image et partition.

  • Une image est un élément logiciel conceptuel qui peut être mis à jour indépendamment.
  • Une partition est un emplacement de stockage physique qui peut être mis à jour indépendamment.

Les sections de la figure 1 sont définies comme suit :

  • SSI : image commune à un OEM, qui peut exister sur plusieurs appareils. Elle ne comporte aucun composant spécifique au matériel ou au produit. Tout ce qui se trouve dans une SSI donnée est, par définition, partagé entre tous les appareils qui l'utilisent. La SSI est composée d'une seule /system image ou des partitions /system et /system_ext.

  • Image produit : ensemble de composants spécifiques à un produit ou à un appareil qui représentent les personnalisations et les extensions OEM de l'OS Android. Placez les composants spécifiques au SoC dans la partition /vendor. Les fournisseurs de SoC peuvent également utiliser la partition /product pour les composants appropriés, tels que ceux qui sont indépendants du SoC. Par exemple, si un fournisseur de SoC fournit un composant indépendant du SoC à ses clients OEM (qui est facultatif pour la livraison avec le produit), il peut placer ce composant dans l'image du produit. L'emplacement d'un composant est déterminé par son objectif et non par sa propriété.

  • Image du fournisseur : ensemble de composants spécifiques au SoC.

  • Image ODM : ensemble de composants spécifiques à la carte qui ne sont pas fournis par le SoC. En règle générale, le fournisseur de SoC est propriétaire de l'image du fournisseur, tandis que le fabricant de l'appareil est propriétaire de l'image ODM. Lorsqu'il n'existe pas de partition /odm distincte, les images du fournisseur de SoC et de l'ODM sont fusionnées dans la partition /vendor.

La partition /system_ext

La partition /system_ext est facultative. Utilisez cette partition pour toutes les fonctionnalités et extensions personnalisées étroitement liées aux composants basés sur AOSP. Cette partition est considérée comme l'extension spécifique à l'OEM de la partition /system, sans interface définie entre les deux partitions. Les composants de la partition /system_ext peuvent effectuer des appels d'API privés dans la /system partition, et les composants de la /system partition peuvent effectuer des appels d'API privés dans la /system_ext partition.

Comme les deux partitions sont étroitement liées, elles sont mises à niveau ensemble lorsqu'une nouvelle version d'Android est publiée. Une partition /system_ext créée pour la version précédente d'Android n'a pas besoin d'être compatible avec la partition /system de la version suivante d'Android.

Pour installer un module dans la partition /system_ext, ajoutez system_ext_specific: true au fichier Android.bp. Sur les appareils qui ne disposent pas de /system_ext partition, installez ces modules dans le sous-répertoire ./system_ext de la /system partition.

Historique : l'objectif de conception initial de la partition /system_ext était de placer tous les composants spécifiques à l'OEM, qu'ils soient communs ou non, dans la partition /product. Toutefois, il n'était pas possible de les déplacer tous en même temps, en particulier lorsque certains composants avaient un couplage fort avec la partition /system. Pour déplacer un composant étroitement lié vers la partition /product, l'interface produit doit être étendue. Cela nécessitait souvent une refactorisation importante du composant lui-même, ce qui demandait beaucoup de temps et d'efforts. La partition /system_ext a commencé comme un emplacement pour héberger temporairement les composants qui ne sont pas prêts à être déplacés vers la partition /product. L'objectif de la SSI était d'éliminer à terme la partition /system_ext.

Toutefois, la partition /system_ext est utile pour que la /system partition reste aussi proche que possible d'AOSP. Avec la SSI, la plupart des efforts de mise à niveau sont consacrés aux composants des partitions /system et /system_ext. Lorsque l'image système est créée à partir de sources aussi similaires que possible à celles d'AOSP, vous pouvez concentrer vos efforts de mise à niveau sur l'image system_ext.

Interfaces entre les images

Deux interfaces principales pour les images de fournisseur et de produit existent autour de la SSI :

  • **Interface du fournisseur (VINTF)**: VINTF est l'interface de s composants qui résident dans les images du fournisseur et de l'ODM. Les composants des images produit et système ne peuvent interagir avec les images du fournisseur et de l'ODM que via cette interface. Par exemple, une image de fournisseur ne peut pas dépendre d'une partie privée de l'image système, et inversement. Cela est défini dans l'architecture Treble (qui fait désormais partie de l'architecture Mainline plus large), qui divise les images en partitions système et fournisseur. L'interface est décrite à l'aide des mécanismes suivants :

    • HIDL (Passthrough HAL n'est disponible que pour les system et les system_ext modules)
    • AIDL stable
    • Configurations
      • API des propriétés système
      • API du schéma de fichier de configuration
    • VNDK
    • API du SDK Android
    • Bibliothèque du SDK Java
  • Interfaces produit : l'interface produit est l'interface entre la SSI et l'image du produit. La définition d'une interface stable découple les composants produit des composants système dans une SSI.

Activer la SSI

Cette section explique comment prendre en charge la SSI dans Android 11 et versions ultérieures.

Dissocier les composants

Pour dissocier la partition /product des composants système, elle doit avoir la même règle d'application que la partition /vendor qui a déjà été dissociée avec Mainline./product

  • Interfaces intégrées : les modules intégrés de la partition /product doivent être dissociés des autres partitions. Les seules dépendances autorisées des modules produit sont certaines bibliothèques VNDK (y compris LLNDK) de la partition /system. Les bibliothèques JNI dont dépendent les applications produit doivent être des bibliothèques NDK.
  • Interfaces Java : les modules Java (application) de la partition /product ne peuvent pas utiliser d'API masquées, car elles sont instables. Ces modules ne doivent utiliser que des API publiques et des API système de la partition /system, ainsi que des bibliothèques du SDK Java dans la partition /system ou /system_ext. Vous pouvez définir des bibliothèques du SDK Java pour les API personnalisées.

Appliquer les interfaces produit

Pour s'assurer que la partition /product est dissociée, les OEM peuvent demander à leurs appareils d'appliquer les interfaces produit en définissant PRODUCT_PRODUCT_VNDK_VERSION:= current pour les modules intégrés et PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE:= true pour les modules Java. Ces variables sont automatiquement définies si le PRODUCT_SHIPPING_API_LEVEL de l'appareil est supérieur ou égal à 30. Pour en savoir plus, consultez Appliquer les interfaces de partition produit.

Étapes suggérées pour une SSI basée sur une GSI

Partitions suggérées pour l'SSI basée sur l'identité de connexion Google

Figure 2. Partitions suggérées pour une SSI basée sur une GSI.

Une image système générique (GSI) est l'image système créée directement à partir d'AOSP. Elle est utilisée pour les tests de conformité (par exemple, CTS-on-GSI) et comme plate-forme de référence que les développeurs d'applications peuvent utiliser pour tester la compatibilité de leurs applications lorsqu'ils ne disposent pas d'un appareil réel exécutant la version requise d'Android.

Les OEM peuvent également utiliser une GSI pour créer leur SSI. Comme expliqué dans Images et partitions, la SSI se compose de l'image système pour les composants définis par AOSP et de l'image system_ext pour les composants définis par l'OEM. Lorsque la GSI est utilisée comme image system, l'OEM peut se concentrer sur l'image system_ext pour la mise à niveau.

Cette section fournit des conseils aux OEM qui souhaitent modulariser leurs personnalisations dans les partitions /system_ext et /product tout en utilisant une image système AOSP ou quasi-AOSP. Si les OEM créent l'image système à partir de sources AOSP, ils peuvent remplacer l'image système qu'ils créent par la GSI fournie par AOSP. Toutefois, les OEM n'ont pas besoin d'atteindre l'étape finale (utiliser la GSI telle quelle) en une seule fois.

Étape 1 : Hériter de generic_system.mk pour l'image système OEM (GSI OEM)

En héritant de generic_system.mk (qui s'appelait mainline_system.mk dans Android 11 et a été renommé generic_system.mk dans AOSP), l'image système (GSI OEM) inclut tous les fichiers de la GSI AOSP. Ces fichiers peuvent être modifiés par les OEM, de sorte que la GSI OEM puisse contenir les fichiers propriétaires de l'OEM en plus des fichiers de la GSI AOSP.

Hériter de `generic_system.mk` pour l'image système OEM

Figure 3. Hériter de generic_system.mk pour l'image système de l'OEM.

Étape 2 : Faire en sorte que la GSI OEM ait la même liste de fichiers que la GSI AOSP

La GSI OEM ne peut pas contenir de fichiers supplémentaires à ce stade. Déplacez donc les fichiers propriétaires de l'OEM vers les partitions system_ext ou product.

Déplacer les fichiers ajoutés hors de la GSI OEM

Figure 4. Déplacer les fichiers ajoutés hors de la GSI OEM.

Étape 3 : Définir une liste d'autorisation pour limiter les fichiers modifiés dans la GSI OEM

Pour vérifier les fichiers modifiés, les OEM peuvent utiliser l'outil compare_images et comparer la GSI AOSP à la GSI OEM. Obtenez la GSI AOSP à partir de la cible de lancement AOSP generic_system_*.

En exécutant l'outil compare_images régulièrement avec le paramètre allowlist, vous pouvez surveiller les différences en dehors de la liste autorisée. Cela empêche toute modification supplémentaire de la GSI OEM.

Définir une liste d'autorisation pour réduire la liste des fichiers modifiés dans l'image système générique de l'OEM

Figure 5. Définir une liste d'autorisation pour réduire la liste des fichiers modifiés dans la GSI OEM.

Étape 4 : Faire en sorte que la GSI OEM ait les mêmes binaires que la GSI AOSP

Le nettoyage de la liste d'autorisation permet aux OEM d'utiliser la GSI AOSP comme image système pour leurs propres produits. Pour nettoyer la liste d'autorisation, les OEM peuvent soit abandonner leurs modifications dans la GSI OEM, soit les transférer vers AOSP afin que la GSI AOSP inclue leurs modifications.

Faire en sorte que la GSI OEM ait les mêmes binaires que la GSI AOSP

Figure 6. Faire en sorte que la GSI OEM ait les mêmes binaires que la GSI AOSP.

Définir la SSI

Les OEM peuvent suivre les conseils ci-dessous pour définir leur SSI.

Protéger la partition /system au moment de la compilation

Pour éviter toute modification spécifique au produit dans la partition /system et définir la GSI OEM, les OEM peuvent utiliser une macro makefile appelée require-artifacts-in-path afin d'empêcher toute déclaration de modules système après l'appel de la macro. Consultez l' exemple à l'étape 1 : Créer un makefile et activer la vérification du chemin d'accès aux artefacts.

Les OEM peuvent définir une liste pour autoriser l'installation temporaire de modules spécifiques au produit dans la partition /system. Toutefois, la liste doit être vide pour que la GSI OEM soit commune à tous les produits de l'OEM. Ce processus permet de définir la GSI OEM et peut être indépendant des étapes de la GSI AOSP.

Rendre la partition /system_ext commune

La partition /system_ext peut différer d'un appareil à l'autre, car elle peut contenir des modules spécifiques à l'appareil et regroupés dans le système. Comme la SSI se compose des partitions /system et /system_ext, les différences dans la partition /system_ext empêchent les OEM de définir une SSI. Les OEM peuvent avoir leur propre SSI et la partager entre plusieurs appareils en supprimant toutes les différences et en rendant la partition /system_ext commune.

Cette section fournit des recommandations pour rendre la partition /system_ext commune.

Exposer les API masquées dans la partition système

De nombreuses applications spécifiques à un produit ne peuvent pas être installées dans la partition produit, car elles utilisent des API masquées, qui sont interdites dans la partition produit. Pour déplacer des applications spécifiques à un appareil vers la partition produit, supprimez l'utilisation d'API masquées.

La méthode recommandée pour supprimer les API masquées des applications consiste à trouver les API publiques ou système alternatives pour les remplacer. S'il n'existe aucune API pour remplacer les API masquées, les OEM peuvent contribuer à AOSP pour définir les nouvelles API système de leurs appareils.

Les OEM peuvent également définir des API personnalisées en créant leur propre bibliothèque du SDK Java dans la partition /system_ext. Cette bibliothèque peut utiliser des API masquées dans la partition système et fournir les API aux applications dans la partition produit ou fournisseur. Les OEM doivent geler les API orientées produit pour assurer la rétrocompatibilité.

Remplacer la désactivation d'applications spécifiques à une référence

Android 16 a rendu obsolète et supprimé l'ancien mécanisme de désactivation sélective des APK en fonction de la référence matérielle à l'aide de superpositions de ressources de framework (config_disableApksUnlessMatchedSku_apk_list et config_disableApkUnlessMatchedSku_skus_list). Pour en savoir plus, consultez aosp/3444399.

Le remplacement recommandé consiste à utiliser la configuration système install-in-user-type dans les répertoires spécifiques à une référence. Cette approche empêche l'installation du package pour tout utilisateur d'une référence spécifique, au lieu de simplement le désactiver après l'installation.

  1. Incluez tous les APK (le sur-ensemble de toutes les applications potentielles pour toutes les références dans votre image système) dans l'image, généralement dans la partition /product.

  2. Assurez-vous que la référence de l'appareil est correctement définie dans la propriété système ro.boot.hardware.sku (utilisée par le système pour identifier la référence de l'appareil au démarrage).

  3. Créez des sous-répertoires sysconfig spécifiques à une référence sous /product/etc/sysconfig/ en utilisant la convention d'attribution de noms sku_<SKU_NAME>. Le système charge automatiquement les configurations à partir du répertoire qui correspond à la propriété ro.boot.hardware.sku. Exemple de chemin d'accès : /product/etc/sysconfig/sku_basic_model/.

  4. Configurez la prévention de l'installation d'applications. Dans le répertoire spécifique à une référence, créez un fichier de configuration XML (par exemple, disabled_apps.xml) et utilisez la balise <do-not-install-in> pour exclure des packages spécifiques.

Exemple de code XML (/product/etc/sysconfig/sku_basic_model/disabled_apps.xml) :

<?xml version="1.0" encoding="utf-8"?>
<config>
    <!-- Prevents this package from being installed for ANY user on this SKU -->
    <install-in-user-type package="com.example.premium.feature.app" >
        <do-not-install-in user-type="FULL" />
        <do-not-install-in user-type="SYSTEM" />
    </install-in-user-type>
</config>

Voici une comparaison des deux méthodes :

Fonctionnalité Android 15 ou version antérieure Android 16 ou version ultérieure
Méthode de configuration Superpositions de ressources de framework Fichiers XML SystemConfig
Emplacement de la logique config.xml (superposition de ressources) /product/etc/sysconfig/sku_<name>/
Résultat Désactive l'application à l'aide de PackageManager Empêche l'installation de l'application pour l'utilisateur
Robustesse Peut être réactivé par les services système Le package n'est jamais installé pour l'utilisateur

Dans les cas nécessitant un contrôle plus précis (c'est-à-dire la désactivation d'une application normalement installée par défaut sur toutes les références), Android prend également en charge les balises disabled-in-sku et enabled-in-sku-override dans sysconfig :

  • <disabled-in-sku package="com.example.app" /> désactive l'application globalement.

  • <enabled-in-sku-override package="com.example.app" /> réactive l'application pour une référence spécifique lorsqu'elle est placée dans le répertoire sku_<name> correspondant.

Définir une RRO au lieu d'utiliser une superposition de ressources statique

Une superposition de ressources statique manipule les packages superposés. Toutefois, elle peut empêcher la définition d'une SSI. Assurez-vous donc que les propriétés de la RRO sont activées et correctement définies. En définissant les propriétés comme suit, les OEM peuvent avoir toutes les superpositions générées automatiquement en tant que RRO.

PRODUCT_ENFORCE_RRO_TARGETS := *
PRODUCT_ENFORCE_RRO_EXCLUDED_OVERLAYS := # leave it empty

Si une configuration détaillée est requise, définissez une RRO manuellement au lieu de vous fier à une RRO générée automatiquement. Pour en savoir plus, consultez Modifier la valeur des ressources d'une application au moment de l'exécution. Les OEM peuvent également définir des RRO conditionnelles qui dépendent des propriétés système à l'aide des attributs android:requiredSystemPropertyName et android:requiredSystemPropertyValue.

Questions fréquentes (FAQ)

Vous trouverez ci-dessous les questions fréquentes concernant la SSI.

Puis-je définir plusieurs SSI ?

Cela dépend de la similitude et des caractéristiques des appareils (ou du groupe d'appareils). Les OEM peuvent essayer de rendre la partition system_ext commune, comme décrit dans Rendre la partition system_ext commune. Si un groupe d'appareils présente de nombreuses différences, il est préférable de définir plusieurs SSI.

Puis-je supprimer de generic_system.mk les modules qui sont en conflit avec mon implémentation ?

Non. La GSI comporte un ensemble minimal de modules bootables et testables. Si vous pensez qu'un module n'est pas essentiel, signalez un bug pour mettre à jour le generic_system.mk fichier.