Présentation de SDK Runtime

Envoyer un commentaire

La plate-forme Android exploite le concept de bac à sable afin de garantir des limites d'exécution et de sécurité robustes pour le code d'application, tout en respectant les limites de processus. Les applications incluent souvent du code tiers, généralement sous la forme de SDK tels que des SDK publicitaires ou d'analyse. Les développeurs peuvent ainsi se concentrer sur la différenciation de leur application tout en tirant parti du sens de l'innovation d'autres experts, ce qui étend leurs possibilités.

Comme la plupart des systèmes d'exploitation, les SDK Android sont exécutés dans le bac à sable de l'application hôte. Ils héritent de ses droits et autorisations, ainsi que de son accès à la mémoire et au stockage. Bien que cette architecture contribue à la flexibilité de l'intégration entre les SDK et les applications, elle implique également la divulgation et le partage potentiels de données utilisateur. De plus, les développeurs n'ont pas toujours pleinement conscience de l'étendue des fonctionnalités d'un SDK tiers et des données auxquelles il accède. Il est donc difficile de savoir exactement comment la collecte et le partage des données seront gérés dans leur application.

Dans Android 13, nous avons ajouté une nouvelle fonctionnalité de plate-forme qui permet aux SDK tiers de s'exécuter dans un environnement d'exécution dédié appelé SDK Runtime. Le SDK Runtime offre les garanties et protections suivantes concernant la collecte et le partage des données utilisateur:

  • Environnement d'exécution modifié
  • Définition précise des autorisations et des droits d'accès aux données pour les SDK

Nous sollicitons activement les commentaires de la communauté des annonceurs d'applications mobiles sur cette conception. N'hésitez pas à nous faire part de vos commentaires, qui nous aideront à façonner les futures itérations de SDK Runtime, y compris la prise en charge de cas d'utilisation supplémentaires.

Objectifs

Cette proposition vise à atteindre les objectifs suivants :

  • Éviter l'accès et le partage non divulgués des données d'applications d'un utilisateur par les SDK tiers grâce à l'isolement de processus et à un contrôle bien défini des accès aux données et aux API. L'isolement de processus sera traité plus en détail dans une section distincte de ce document.
  • Éviter le suivi non divulgué de l'utilisation des applications par les SDK tiers en limitant leur accès aux identifiants uniques et persistants.
  • Accélérer la distribution sécurisée des mises à jour des SDK dans les applications en facilitant la tâche des développeurs d'applications et des utilisateurs finaux. Vous découvrirez la proposition de modèle de distribution approuvé pour les SDK dans une autre section de ce document.
  • Aider les développeurs d'applications à mieux prendre en compte les pratiques d'accès aux données et de partage au sein de leurs applications.
  • Aider les développeurs de SDK à empêcher toute falsification par d'autres SDK en évitant certaines constructions de langage non sécurisées telles que le code JNI.
  • Aider les SDK publicitaires à détecter et à éviter le trafic non valide et la fraude publicitaire grâce à un contrôle total des vues à distance qui affichent des contenus multimédias.
  • Limiter autant que possible l'impact excessif sur les développeurs d'applications et de SDK.

Les SDK s'exécutent dans un processus isolé

Le SDK Runtime proposé permet aux SDK compatibles, que nous désignerons tout au long de ce document sous le terme de SDK compatibles avec l'environnement d'exécution, de fonctionner dans un processus distinct de l'application. La plate-forme facilite la communication bidirectionnelle entre le processus de l'application et son SDK Runtime. Pour en savoir plus, consultez la section Communication de ce document. Les SDK non compatibles avec cet environnement d'exécution peuvent rester tels quels dans le processus de l'application. Les schémas suivants illustrent ces modifications:

Schéma "Avant" illustrant tous les éléments exécutant le processus de l'application
Avant d'être ajoutés au SDK Runtime, le code d'appel du SDK et les SDK qui reçoivent les appels de ce code se trouvent tous dans le processus de l'application

Schéma "Après" illustrant la division des processus entre le processus d'application et le processus d'exécution du SDK
Après avoir ajouté le code d'appel du SDK au SDK Runtime, dans le processus de premier plan de l'application, le code d'appel du SDK communique avec les interfaces du SDK. Ces interfaces traversent ensuite une limite de processus pour atteindre le processus du SDK Runtime afin d'appeler elles-mêmes les SDK.

Nouveau modèle de distribution approuvé pour les SDK

Cette séparation proposée entre le SDK et l'application motive un autre concept de séparation, celui de la distribution des SDK et de l'application. Cette proposition implique un mécanisme de distribution et d'installation de confiance pour garantir que les SDK appropriés sont installés dans le SDK Runtime d'une application. Cette approche permet de protéger les utilisateurs et les développeurs d'applications contre le chargement de SDK non valides, tout en permettant aux plates-formes de téléchargement d'applications de réduire considérablement la charge liée à distribution des SDK de la part des développeurs.

Dans ce modèle, les SDK n'ont plus besoin d'être liés de manière statique et empaquetés avec leurs applications avant d'être importés sur une plate-forme de téléchargement d'applications pour distribution. Le processus suivant se produit à la place :

  1. Les développeurs de SDK peuvent importer leurs SDK (avec gestion des versions) sur les plates-formes de téléchargement, séparément des applications elles-mêmes.
  2. Les développeurs d'applications peuvent spécifier les dépendances de SDK par version, compiler et importer une version d'application qui n'inclut pas les dépendances de SDK elles-mêmes.
  3. Lorsqu'un utilisateur télécharge cette application, le processus d'installation peut consulter les dépendances de SDK spécifiées pour l'application afin de les télécharger depuis la plate-forme de téléchargement d'applications.

Ce nouveau mécanisme de distribution permettrait aux développeurs de SDK d'apporter des modifications non destructives (à savoir, aucune modification des API ou de leur sémantique) à leurs SDK et de les distribuer aux appareils sans aucune intervention de la part des développeurs d'applications. Ces modifications pourraient être déployées ou annulées, sans avoir à attendre que les développeurs recompilent leur application avec les nouveaux SDK ou que les utilisateurs finaux mettent à jour leur application. Les modifications destructives nécessiteraient toujours une mise à jour de la part des développeurs d'applications. Toutefois, les développeurs de SDK seraient en mesure de publier les dernières modifications non destructives et les corrections plus rapidement et de manière plus uniforme auprès de davantage d'utilisateurs, sans avoir à craindre les problèmes de compatibilité des versions.

Les schémas suivants illustrent les modifications proposées pour la distribution des SDK:

Schéma "Avant"
Avant le lancement de SDK Runtime, les développeurs envoient leurs SDK directement aux applications.

Schéma "Après"
Après l'introduction du SDK Runtime, d, les développeurs de SDK utiliseraient une UI d'importation de SDK pour publier leurs SDK sur une plate-forme de téléchargement d'applications. Cette plate-forme gérerait ensuite la distribution des applications et des dépendances de SDK sur les appareils des utilisateurs finaux.

Modifications apportées à la création, à l'exécution et à la distribution des SDK et des applications

Il s'agit d'une première proposition de technologie d'exécution et de distribution flexibles des SDK. Les sections suivantes suggèrent une série de modifications ayant un impact sur les grandes catégories suivantes :

  • Accès : autorisations, mémoire, stockage
  • Exécution : langages, modifications de l'environnement d'exécution, cycle de vie, rendu multimédia
  • Communications : application/SDK et SDK/SDK
  • Développement : création, débogage et test dans ce modèle
  • Distribution : distribution, mise à jour et rollback entre les versions d'Android, des applications et des SDK

Ce document contient également des questions fréquentes.

Il s'agit d'une proposition de conception initiale, et nous sommes conscients qu'il peut s'agir d'un changement significatif pour certains membres de l'écosystème. C'est pourquoi nous sollicitons activement vos commentaires via cet outil de suivi des problèmes.

Accès

La gestion de la confidentialité d'un système implique la gestion de l'accès des différentes parties aux différentes ressources. Pour répondre aux exigences de notre proposition de valeur en termes de confidentialité, nous suggérons de mettre à jour le modèle d'accès aux applications, aux SDK et aux données utilisateur afin de respecter le principe du moindre privilège, qui permet d'éviter l'accès non divulgué aux données potentiellement sensibles.

Autorisations des SDK

En tant que processus distinct, le SDK Runtime disposerait de son propre ensemble d'autorisations bien défini plutôt que d'hériter de celui que l'utilisateur a accordé à l'application. Suite à une recherche préliminaire sur les autorisations utilisées par les SDK publicitaires, nous proposons que les autorisations suivantes soient accessibles par défaut aux SDK dans le SDK Runtime :

  • INTERNET : accès à Internet pour pouvoir communiquer avec un service Web.
  • ACCESS_NETWORK_STATE : accès aux informations sur les réseaux.
  • Autorisations d'accès aux API préservant la confidentialité, qui fournissent des fonctionnalités publicitaires essentielles sans avoir besoin d'accéder aux identifiants de plusieurs applications.
  • AD_ID : possibilité de demander l'identifiant publicitaire. L'accès de l'application à cette autorisation serait alors contrôlé.
  • BIND_GET_INSTALL_REFERRER_SERVICE : possibilité d'utiliser l'API Google Play Install Referrer pour attribuer la source de l'installation d'une application.

Nous étudions actuellement la possibilité d'ajouter des autorisations et, le cas échéant et de limiter leur impact sur les utilisateurs finaux du point de vue de la confidentialité et de l'usabilité. Vos commentaires sur tous les cas d'utilisation qui peuvent ne pas être satisfaits par cet ensemble d'autorisations sont les bienvenus.

Mémoire

Le SDK Runtime dispose de son propre espace de mémoire isolé, car il a son propre processus. Par défaut, cette structure interdit au SDK d'accéder à l'espace mémoire de l'application. De même, l'application ne peut pas accéder à l'espace mémoire du SDK. Nous vous recommandons de conserver ce comportement par défaut pour respecter le principe du moindre privilège.

Stockage

Cette proposition vise à trouver un juste milieu entre la nécessité pour les SDK d'accéder au stockage dans le cadre de leur fonctionnement normal et le besoin de minimiser le suivi entre applications et entre processus à l'aide du stockage persistant. Nous proposons la mise à jour suivante pour l'accès au stockage par rapport à la solution actuelle :

  • Les applications ne pourront pas accéder directement à l'espace de stockage de leurs SDK, et inversement.
  • Les SDK n'auront pas accès à la mémoire de stockage externe de l'appareil.
  • Chaque SDK Runtime contiendra un espace de stockage accessible à tous les SDK et un autre spécifique à chaque SDK.

Comme pour le modèle de stockage actuel, la taille de l'espace de stockage en lui-même ne sera pas limitée. Les SDK pourront utiliser l'espace de stockage pour la mise en cache des éléments. Cet espace sera effacé régulièrement lorsque le SDK ne sera pas actif.

Mise en œuvre

Pour garantir un système privé entre les applications, les SDK et les utilisateurs, le contexte d'exécution lui-même (formats de code, structures de langage, API accessibles et données système) doit renforcer ces limites de confidentialité ou, au moins, permettre de les contourner. Parallèlement, nous souhaitons conserver l'accès à la plate-forme et à la majorité des fonctionnalités d'exécution actuellement proposées par les SDK. Nous proposons ici un ensemble de mises à jour de l'environnement d'exécution pour atteindre cet équilibre.

Coder

Le code Android (applications et SDK) est principalement interprété par l'environnement d'exécution Android Runtime (ou "ART"), qu'il ait été écrit en Kotlin ou en Java. La richesse de l'environnement ART et du langage qu'il offre ainsi que sa vérifiabilité par rapport à d'autres options (en particulier le code natif) semblent garantir l'harmonie entre fonctionnalité et confidentialité. Nous proposons que le code du SDK compatible avec l'environnement d'exécution se compose exclusivement du bytecode Dex, au lieu de prendre en charge l'accès via JNI.

Nous sommes conscients qu'il existe des cas d'utilisation, tels que les packages SQLite personnalisés, qui impliquent l'utilisation de code natif et qui devront être remplacés par une alternative telle que la version intégrée de SQLite pour le SDK Android.

SELinux

Sur Android, chaque processus (y compris ceux exécutés en mode racine) s'exécute dans un contexte SELinux spécifique, ce qui permet au noyau de gérer le contrôle des accès aux services système, aux fichiers, aux appareils et à d'autres processus. Afin de préserver la majorité des cas d'utilisation des SDK tout en minimisant le contournement des protections de la confidentialité que nous essayons d'appliquer, nous proposons les mises à jour suivantes dans le contexte SELinux d'une application hors système pour le SDK Runtime :

  • Un ensemble limité de services système serait accessible (fonctionnalité sur laquelle nous travaillons activement).
  • Les SDK ne pourraient charger et exécuter le code que dans leur APK.
  • Un ensemble limité de propriétés système serait accessible (fonctionnalité sur laquelle nous travaillons activement).

API

L'utilisation des API de réflexion et d'appel dans le SDK Runtime est autorisée. Toutefois, un SDK ne sera pas autorisé à utiliser les API de réflexion et d'appel sur un autre SDK compatible avec l'environnement d'exécution. Nous partagerons une proposition complète d'API interdites dans une prochaine mise à jour.

En outre, les versions récentes de la plate-forme Android limitent de plus en plus l'accès aux identifiants persistants afin d'améliorer la confidentialité. Pour l'environnement d'exécution des SDK, nous suggérons de restreindre davantage l'accès aux identifiants permettant le suivi de plusieurs applications.

Les API de SDK Runtime ne sont accessibles que depuis les applications exécutées au premier plan. Toute tentative d'accès aux API SdkSandboxManager depuis des applications en arrière-plan génère une erreur SecurityException.

Enfin, les SDK compatibles avec l'environnement d'exécution ne peuvent pas utiliser les API de notification pour envoyer des notifications utilisateur à tout moment.

Cycle de vie

Les SDK suivent le cycle de vie de leur application hôte. Autrement dit, lorsque l'application s'affiche au premier plan ou passe en arrière-plan, qu'elle se ferme ou que le système d'exploitation l'arrête de force en raison de la charge de la mémoire, les SDK passent par les mêmes étapes. Notre proposition de séparer les SDK d'une application dans un processus distinct implique les modifications suivantes dans le cycle de vie :

  • L'application peut être arrêtée par l'utilisateur ou le système d'exploitation. Le SDK Runtime s'arrête automatiquement juste après.
  • Le SDK Runtime peut être arrêté par le système d'exploitation en raison de la charge de la mémoire ou d'une exception non gérée dans un SDK, par exemple.

    Pour Android 13, lorsqu'une application est au premier plan, le SDK Runtime s'exécute en priorité et a peu de chances d'être arrêté. Lorsque l'application passe en arrière-plan, la priorité du SDK Runtime baisse et il peut donc être arrêté. La priorité du processus du SDK Runtime reste faible même si l'application revient au premier plan. Par conséquent, il est très probable qu'il soit arrêté en raison de la charge de la mémoire par rapport à l'application.

    Pour Android 14 et versions ultérieures, les priorités de processus de l'application et du SDK Runtime sont alignées. Les priorités de processus pour ActivityManager.RunningAppProcessInfo.importance pour l'application et le SDK Runtime devraient être à peu près identiques.

    Si le SDK Runtime se termine pendant que l'application est active (par exemple, en cas d'exception non gérée dans le SDK), son état, y compris tous les SDK déjà chargés et les vues distantes, est perdu. Le développeur de l'application peut gérer l'arrêt du SDK Runtime à l'aide de l'une des méthodes suivantes :

    • La proposition offre aux développeurs d'applications des méthodes de rappel de cycle de vie associées afin qu'ils détectent tout arrêt potentiel du SDK Runtime.
    • Si l'exécution du SDK se termine pendant l'affichage des annonces, celles-ci risquent de ne pas fonctionner comme prévu. Par exemple, les vues peuvent être figées à l'écran et ne plus être interactives. L'application peut supprimer l'affichage de l'annonce si cela n'affecte pas l'expérience utilisateur.
    • L'application peut effectuer une nouvelle tentative de chargement des SDK et de demande d'annonces.
    • Pour Android 14, si le SDK Runtime s'arrête alors que les SDK sont chargés et que le développeur de l'application n'a pas enregistré les méthodes de rappel du cycle de vie susmentionnées, l'application s'arrête par défaut. Seuls les processus d'application qui ont des SDK chargés s'arrêtent et se terminent normalement.
    • Les objets classeurs renvoyés par le SDK pour communiquer avec lui (tels que SandboxedSdk) génèrent une DeadObjectException s'ils sont utilisés par l'application.

    Ce modèle de cycle de vie est susceptible de changer à terme.

    En cas de défaillances persistantes, le développeur de l'application doit planifier une dégradation élégante sans le SDK ou avertir l'utilisateur si le SDK est essentiel à la fonctionnalité de base de l'application. Pour en savoir plus sur cette interaction entre l'application et le SDK, consultez la section Communication de ce document.

Les SDK non compatibles avec l'environnement d'exécution peuvent continuer à utiliser les primitives de système d'exploitation standards disponibles pour leur application intégrée, y compris les services, les activités et les diffusions.

Cas particuliers

Les cas suivants ne sont pas pris en charge et peuvent entraîner un comportement inattendu :

  • Si plusieurs applications partagent le même UID, le SDK Runtime peut ne pas fonctionner correctement. La prise en charge des UID partagés pourrait être ajoutée à l'avenir.
  • Pour les applications comportant plusieurs processus, le chargement du SDK doit être effectué dans le processus principal.

Rendu multimédia

Certains SDK affichent du contenu tel que du texte, des images et des vidéos dans une vue spécifiée par l'application. Pour ce faire, nous proposons une approche de rendu à distance où le SDK affiche le contenu multimédia à partir de SDK Runtime, mais utilise l'API SurfaceControlViewHost pour permettre le rendu multimédia dans une vue spécifiée par l'application. Le SDK peut ainsi afficher ce contenu de manière privée, tout en contribuant à empêcher et à détecter les éventuelles interactions utilisateur non valides ou frauduleuses.

Les annonces natives, qui ne sont pas affichées par le SDK, mais par l'application, sont compatibles avec les SDK dans le SDK Runtime. Le processus de collecte des signaux et d'extraction des créations s'effectue de manière cohérente avec les annonces non natives. Il s'agit d'un domaine que nous étudions activement.

Les annonces vidéo InStream sont diffusées dans un lecteur au sein d'une application. Étant donné que la vidéo est lue dans ce contexte, et non dans un lecteur ou une vue du SDK, le modèle de rendu diffère des autres formats d'annonces. Nous étudions activement des moyens d'accepter à la fois l'insertion d'annonces côté serveur et l'insertion d'annonces basée sur un SDK.

État du système

Nous cherchons à réduire l'impact de SDK Runtime en matière d'état du système sur les appareils des utilisateurs finaux, et nous réfléchissons à différents moyens d'y parvenir. Toutefois, il est très probable que certains appareils Android 13 d'entrée de gamme dotés de ressources système très limitées, tels que l'édition Android Go, ne soient pas compatibles avec le SDK Runtime en raison de cet impact. Nous vous communiquerons bientôt les conditions minimales requises pour utiliser le SDK Runtime de manière optimale.

Communication

Étant donné que les applications et les SDK s'exécutent actuellement dans le même processus, la communication entre eux se fait librement et sans intermédiaire. De plus, Android permet la communication entre les applications même si elle commence et se termine par les SDK. Ce modèle de communication fluide permet différents cas d'utilisation tout en offrant la possibilité de partager des données non divulguées entre les applications, ainsi qu'entre les SDK au sein des applications et entre elles. Nous proposons les mises à jour suivantes pour ce modèle de communication. Elles visent à trouver un juste équilibre entre la valeur de ces communications et la réalisation des objectifs annoncés.

Communication entre l'application et le SDK

L'interface entre l'application et le SDK est le chemin de communication le plus courant pour un SDK. L'API d'un SDK est d'ailleurs ce qui permet essentiellement à l'application d'être innovante et de se distinguer aux yeux des utilisateurs. Notre objectif est de préserver l'innovation et la différenciation proposées par les SDK. Par conséquent, notre proposition permet aux SDK d'exposer des API aux applications et de s'assurer que celles-ci peuvent bénéficier de toutes ces innovations.

Compte tenu de la structure des limites de processus de SDK Runtime, nous proposons de créer une couche de marshaling, accessible dans l'application, pour acheminer les appels d'API et les réponses ou rappels via cette limite entre l'application et le SDK. Nous suggérons que l'interface de cette couche de marshaling soit définie par les développeurs de SDK et soit générée par des outils de compilation Open Source officiels que nous développerions.

Avec cette proposition, nous cherchons à supprimer le travail habituel de marshaling des développeurs d'applications et de SDK. Nous voulons aussi offrir une certaine flexibilité aux développeurs de SDK et nous assurer que le code du SDK s'exécute dans le SDK Runtime afin d'atteindre nos objectifs de confidentialité. Si nous adoptions cette approche, votre contribution sera nécessaire pour concevoir l'outil et le langage de définition d'API.

Le modèle général d'interaction serait le suivant :

  • L'application appelle le SDK via l'interface, en transmettant les rappels.
  • Le SDK répond de manière asynchrone aux requêtes et répond à l'aide des rappels.
  • Cette méthode peut être généralisée à n'importe quel modèle Éditeur/Abonné. Autrement dit, une application peut s'abonner à des événements dans le SDK avec des rappels, et lorsque ces événements ont lieu, les rappels sont déclenchés.

En raison de la nouvelle structure multiprocessus de cette proposition, deux cycles de vie de processus devraient être gérés : l'un pour l'application elle-même et l'autre pour le SDK Runtime. Notre proposition vise à recourir autant que possible à l'automatisation, afin de minimiser l'impact pour les développeurs d'applications et de SDK. Le schéma suivant illustre l'approche que nous envisageons d'utiliser:

Schéma
Diagramme séquentiel illustrant les interactions entre l'application et le SDK lors du démarrage de l'application et du SDK

La plate-forme expose de nouvelles API permettant aux applications de charger dynamiquement des SDK dans le processus de SDK Runtime, d'être notifiées en cas de changements d'état du processus et d'interagir avec les SDK chargés dans le SDK Runtime.

Le graphique de la figure précédente illustre la communication entre l'application et le SDK à un niveau inférieur, sans la couche de marshaling.

Pour communiquer avec le SDK s'exécutant dans le processus de SDK Runtime, l'application suit ces étapes :

  1. Pour pouvoir interagir avec un SDK, une application peut demander à la plate-forme de charger ce SDK. Pour garantir l'intégrité du système, les applications doivent spécifier les SDK qu'elles ont l'intention de charger dans leur fichier manifeste. Ces SDK seront alors les seuls qui pourront être chargés.

    L'extrait de code suivant fournit un exemple d'API :

    SdkSandboxManager.loadSdk(String sdkName, Bundle data, Executor executor,
        OutcomeReceiver<SandboxedSdk, LoadSdkException> receiver)
    
  2. Le SDK reçoit une notification indiquant qu'il a été chargé et renvoie son interface. Cette interface est destinée au processus d'application. Pour partager l'interface en dehors de la limite du processus, elle doit être renvoyée en tant qu'objet IBinder.

    Le guide des services liés propose différentes manières de renvoyer un objet IBinder. Quelle que soit la méthode choisie, elle doit être cohérente entre le SDK et l'application qui est à l'origine de l'appel. Les schémas utilisent AIDL comme exemple.

  3. SdkSandboxManager reçoit l'interface IBinder et la renvoie à l'application.

  4. L'application reçoit IBinder et le caste dans l'interface du SDK, en appelant ses fonctions :

    IBinder binder = sandboxSdk.getInterface();
    ISdkInterface mySdkInterface = ISdkInterface.Stub.asInterface(binder);
    mySdkInterface.something();
    

L'application peut également afficher le contenu multimédia à partir du SDK en procédant comme suit :

  1. Comme expliqué dans la section Rendu multimédia de ce document, afin qu'une application permette à un SDK d'afficher le contenu multimédia dans une vue, elle peut appeler requestSurfacePackage() et extraire l'élément SurfaceControlViewHost.SurfacePackage approprié.

    L'extrait de code suivant fournit un exemple d'API :

    SdkSandboxManager.requestSurfacePackage(String sdkName, Bundle extraParams,
            Executor executor,
            OutcomeReceiver<Bundle, RequestSurfacePackageException> receiver)
    
  2. L'application peut ensuite intégrer l'élément SurfacePackage renvoyé dans SurfaceView via l'API setChildSurfacePackage dans SurfaceView.

    L'extrait de code suivant fournit un exemple d'API :

    SurfaceView.setChildSurfacePackage(SurfacePackage surfacePackage)
    

Nous suggérons que les API IBinder et requestSurfacePackage() soient génériques et ne soient pas appelées directement par les applications. Au lieu de cela, elles seraient appelées par la référence d'API générée mentionnée ci-dessus, dans une couche "shim", afin de faciliter la tâche des développeurs d'applications.

Communication entre les SDK

Deux SDK de la même application doivent souvent communiquer. Cela peut se produire lorsqu'un SDK donné est conçu pour être composé de plusieurs "sous-SDK", ou lorsque deux SDK bien distincts doivent collaborer pour répondre à une requête de l'application qui est à l'origine de l'appel.

Voici les deux principaux scénarios à prendre en compte :

  • Les deux SDK sont compatibles avec l'environnement d'exécution. Dans ce cas, ils s'exécutent dans cet environnement, avec toutes ses protections. Les SDK ne pourraient pas communiquer comme ils le font actuellement dans une application. Par conséquent, une API dans SdkSandboxController a été ajoutée pour permettre l'extraction d'objets SandboxedSdk pour tous les SDK chargés compatibles avec l'environnement d'exécution. Ces derniers peuvent ainsi communiquer avec d'autres SDK chargés dans le SDK Runtime.
  • Un seul SDK est compatible avec l'environnement d'exécution.
    • Si le SDK qui est à l'origine de l'appel s'exécute dans l'application, le fonctionnement est le même que pour l'application qui appelle le deuxième SDK au sein du SDK Runtime.
    • Si le SDK qui est à l'origine de l'appel s'exécute dans le SDK Runtime, nous vous proposons d'exposer une méthode utilisant l'objet IBinder décrit dans la section "Communication entre l'application et le SDK". Le code de l'application l'écoutera, le traitera et répondra avec les rappels fournis.
    • Les SDK publicitaires qui ne sont pas compatibles avec l'environnement d'exécution ne peuvent pas toujours s'enregistrer eux-mêmes. Nous proposons donc de créer un SDK de médiation qui inclura tous les SDK de partenaires ou d'applications en tant que dépendances directes de l'application et qui gérera l'enregistrement. Ce SDK de médiation établira la communication entre les SDK non compatibles avec l'environnement d'exécution ou d'autres dépendances d'application et le médiateur compatible avec l'environnement d'exécution, qui jouera le rôle d'adaptateur.

L'ensemble de fonctionnalités pour la communication entre SDK a été divisé en plusieurs catégories :

  • Communication entre SDK dans le SDK Runtime (disponible dans la dernière version Preview développeur)
  • Communication entre le SDK et le SDK entre l'application et le SDK Runtime (disponible dans la dernière version Preview développeur)
  • Fonctionnement des vues et du rendu à distance pour la médiation (proposition en cours de développement)

Les cas d'utilisation suivants sont pris en compte lors de la conception des primitives :

  1. Médiation et enchères : de nombreux SDK publicitaires proposent une fonctionnalité de médiation ou d'enchères permettant au SDK d'appeler d'autres SDK pour une impression d'annonce (phase de médiation) ou une collecte de signaux afin de lancer une enchère (phase d'enchères). Généralement, le SDK qui se charge de la coordination appelle les autres SDK via un adaptateur qu'il fournit. Compte tenu des primitives ci-dessus, ce SDK (qu'il soit compatible avec l'environnement d'exécution ou non) doit pouvoir accéder à tous les SDK compatibles ou non compatibles avec cet environnement pour les opérations standards. Le rendu dans ce contexte est un domaine que nous étudions activement.
  2. Détection des fonctionnalités : certains produits de SDK sont constitués de SDK plus petits qui, via un processus de détection interSDK, déterminent l'ensemble de fonctionnalités ultime exposé au développeur de l'application. Les primitives d'enregistrement et de découverte doivent permettre ce cas d'utilisation.
  3. Modèles d'abonnement à un éditeur : certains SDK sont conçus pour utiliser un éditeur central d'événements auxquels d'autres SDK ou applications peuvent s'abonner pour recevoir des notifications via des rappels. Les primitives ci-dessus devraient permettre ce cas d'utilisation.

Communication d'une application à une autre

La communication d'une application à une autre désigne les cas de figure où au moins l'un des deux processus impliqués dans la communication est un SDK compatible avec l'environnement d'exécution et qu'il s'agit également d'un vecteur potentiel de partage de données non divulguées. Par conséquent, le SDK Runtime ne peut pas établir de canal de communication directe avec une application autre que l'application cliente, ou avec les SDK d'un autre SDK Runtime créé pour une autre application. Voici comment cela se produit :

  • Le SDK ne peut pas définir de composants tels que <service>, <contentprovider> ou <activity> dans son fichier manifeste.
  • Le SDK ne peut pas publier un ContentProvider ni envoyer une annonce.
  • Le SDK peut lancer une activité appartenant à une autre application, mais avec des limites sur ce qui peut être envoyé dans l'intent. Par exemple, aucun extra ni aucune action personnalisée ne peut être ajouté à cet intent.
  • Le SDK ne peut lancer qu'une liste d'autorisation de services ou s'y associer.
  • Le SDK ne peut accéder qu'à un sous-ensemble du système ContentProvider (tel que com.android.providers.settings.SettingsProvider), dans lequel les données obtenues ne comportent pas d'identifiants et ne peuvent pas être utilisées pour créer une empreinte de l'utilisateur. Ces vérifications s'appliquent également à l'accès au ContentProvider à l'aide de ContentResolver.
  • Le SDK ne peut accéder qu'à un sous-ensemble de broadcast receivers protégés (comme android.intent.action.AIRPLANE_MODE).

Balises du fichier manifeste

Lorsque le SDK est installé, PackageManager analyse son fichier manifeste et ne parvient pas à installer le SDK en cas de balises interdites dans le fichier manifeste. Par exemple, le SDK peut ne pas définir de composants tels que <service>, <activity>, <provider> ou <receiver>, et ne peut pas déclarer de <permission> dans le fichier manifeste. Les balises qui font échouer l'installation ne sont pas prises en charge par le SDK Runtime. Les balises qui ne font pas échouer l'installation, mais qui sont ignorées en mode silencieux peuvent être compatibles avec les futures versions d'Android.

Ces vérifications peuvent également être appliquées par tous les outils de durée de compilation utilisés par le SDK pour créer le bundle du SDK, ainsi que lors de l'importation sur la plate-forme de téléchargement d'applications.

Prise en charge des activités

Les SDK du SDK Runtime ne peuvent pas ajouter de balise d'activité à leur fichier manifeste et ne peuvent pas démarrer leurs propres activités avec Context.startActivity. À la place, la plate-forme crée les activités pour les SDK sur demande et les partage avec eux.

L'activité de la plate-forme est de type android.app.Activity. Elle commence à partir de l'une des activités de l'application et fait partie de la tâche. FLAG_ACTIVITY_NEW_TASK n'est pas compatible.

Pour qu'un SDK démarre une activité, il doit enregistrer une instance de type SdkSandboxActivityHandler qui permet de notifier la création d'activité lorsque l'application appelle SdkSandboxManager::startSdkSandboxActivity(Activity, IBinder) pour démarrer l'activité.

Le processus de demande d'activité est illustré dans le graphique suivant.

Schéma
Schéma de séquence illustrant le processus de démarrage d'une activité

Development

L'un des principes clés de cette proposition consiste à réduire l'impact sur l'écosystème de développeurs au strict minimum. Elle suggère aux développeurs un ensemble complet d'outils de développement permettant d'écrire, de compiler et de déboguer les applications et les SDK compatibles avec l'environnement d'exécution. Pour garantir l'intégrité de cette proposition, des modifications seront apportées à la configuration, à la création et à la compilation de ces applications et de ces SDK.

Création

Android Studio et les outils associés seront mis à jour pour prendre en compte l'environnement d'exécution, ce qui permettra aux développeurs de configurer correctement leurs applications et SDK compatibles avec cet environnement, et de s'assurer que les anciens appels ou les appels non pris en charge passent à leur nouvelle version, le cas échéant. Au cours de la phase de création, certaines étapes devront être suivies par les développeurs conformément à notre proposition.

Développeurs d'applications

Les applications doivent spécifier leurs dépendances aux SDK compatibles avec l'environnement d'exécution et aux certificats de SDK dans leur fichier manifeste. Tout au long de cette proposition, nous considérons ces informations comme la source de référence fournie par le développeur d'applications. Exemple :

  • Nom : nom du package du SDK ou de la bibliothèque.
  • Version majeure : code de la version majeure du SDK.
  • Condensé du certificat : condensé du certificat dans le build du SDK. Pour un build donné, nous proposons que le développeur du SDK obtienne et enregistre cette valeur via la plate-forme de téléchargement d'applications appropriée.

Cela s'applique uniquement aux SDK distribués sur la plate-forme de téléchargement d'applications, qu'ils soient compatibles avec l'environnement d'exécution ou non. Les applications qui associent des SDK de manière statique utiliseront les mécanismes de dépendance actuels.

Étant donné que notre objectif est de minimiser l'impact pour les développeurs, une fois qu'un niveau d'API cible prenant en charge le SDK Runtime est spécifié, les développeurs d'applications ne devraient avoir besoin que d'un seul build, que ce build s'exécute sur des appareils compatibles ou non avec le SDK Runtime.

Développeurs de SDK

Dans la conception proposée, les développeurs de SDK compatibles avec l'environnement d'exécution doivent déclarer explicitement un nouvel élément représentant le SDK ou l'entité de la bibliothèque dans le fichier manifeste. En outre, un ensemble de valeurs semblables à celui de la dépendance doit être fourni, ainsi qu'une version mineure :

  • Nom : nom du package du SDK ou de la bibliothèque.
  • Version majeure : code de la version majeure du SDK.
  • Version mineure : code de la version mineure du SDK.

Si les développeurs de SDK compatibles utilisent d'autres SDK compatibles en tant que dépendances au moment de la compilation, ils devront probablement les déclarer de la même manière qu'un développeur d'applications le ferait avec la même dépendance. Les SDK compatibles qui dépendent d'autres SDK non compatibles avec l'environnement d'exécution les associeraient de manière statique. Cela pourrait entraîner des problèmes qui seront détectés au moment de la compilation ou des tests si les SDK non compatibles nécessitent une fonctionnalité non prise en charge par l'environnement d'exécution ou s'ils doivent s'exécuter dans le processus de l'application.

Il est probable que les développeurs de SDK compatibles continuent de prendre en charge les appareils non compatibles, tels qu'Android 12 ou versions antérieures, et comme indiqué dans la section État du système de ce document, tels que les appareils Android 13 d'entrée de gamme dont les ressources système sont très limitées. Nous travaillons actuellement sur différentes approches pour nous assurer que les développeurs de SDK puissent conserver un codebase unique prenant en charge à la fois les environnements compatibles et les environnements non compatibles.

Builds

Développeurs d'applications

Les développeurs d'applications ne devraient pas constater de changement majeur au cours de l'étape de compilation. Les dépendances du SDK, qu'elles soient distribuées localement ou sur une plate-forme de téléchargement d'applications (compatible ou non avec l'environnement d'exécution) devront se trouver sur la machine pour les fonctions de linting, de compilation et de création de builds. Nous suggérons qu'Android Studio récupère ces informations auprès du développeur d'applications avec une utilisation standard et qu'il fasse en sorte qu'elles soient aussi transparentes que possible.

Bien qu'il soit normal qu'une version de débogage comprenne tout le code et tous les symboles nécessaires pour le débogage, tous les SDK distribués par la plate-forme de téléchargement d'applications (compatibles ou non avec l'environnement d'exécution) devraient pouvoir être supprimés du dernier artefact dans les versions de production.

Nous n'en sommes qu'au début de cette phase de conception et partagerons davantage d'informations à mesure que nous progresserons.

Développeurs de SDK

Nous travaillons à l'élaboration d'une approche qui permettrait l'intégration des versions de SDK compatibles et non compatibles avec l'environnement d'exécution dans un seul artefact pour la distribution. Cela éviterait que les développeurs d'applications n'aient besoin de prendre en charge des versions distinctes selon que le SDK est compatible ou non avec l'environnement d'exécution.

Tout comme pour les applications, les SDK de dépendances distribués par une plate-forme de téléchargement d'applications devront se trouver sur la machine pour le linting, la compilation et la création des builds, et Android Studio devrait faciliter cette opération.

Tests

Développeurs d'applications

Comme décrit dans notre proposition, les développeurs d'applications pourront effectuer leurs tests sur des appareils exécutant Android 13 comme ils le feraient habituellement. Une fois leur application créée, celle-ci pourra être installée sur un appareil ou un émulateur compatible avec l'environnement d'exécution. Ce processus d'installation garantirait que les SDK appropriés sont installés dans l'environnement d'exécution du SDK pour l'appareil ou l'émulateur, qu'ils aient été extraits d'un dépôt de SDK distant ou du cache du système de compilation.

Développeurs de SDK

Les développeurs de SDK utilisent généralement des applications de test internes sur des appareils et des émulateurs pour tester leur développement. Notre proposition ne change pas ce processus. La validation in-app suivra la même procédure que celle décrite pour les développeurs d'applications ci-dessus, avec un seul artefact de compilation pour les applications compatibles, ainsi que pour celles qui ne sont pas compatibles avec l'environnement d'exécution. Les développeurs du SDK pourront parcourir leur code, qu'il soit intégré ou non dans le SDK Runtime, bien que des limites puissent s'appliquer aux outils avancés de débogage et de profilage. Il s'agit d'un domaine que nous étudions activement.

Distribution

Notre proposition de conception pour la séparation d'une application de ses SDK a donné naissance à la possibilité de distribuer les SDK sur une plate-forme de téléchargement d'applications. Cette option est ouverte à toutes les plates-formes de téléchargement d'applications. Les avantages sont clairs :

  • Garantir la qualité et la cohérence des SDK
  • Simplifier la publication pour les développeurs de SDK
  • Accélérer le déploiement des mises à jour mineures de SDK sur les applications installées

Pour permettre la distribution des SDK, une plate-forme de téléchargement d'applications devra probablement fournir la plupart des fonctionnalités suivantes :

  • Mécanisme permettant aux développeurs de SDK d'importer les SDK concernés sur la plate-forme de téléchargement, de les mettre à jour, de les restaurer et éventuellement de les supprimer
  • Mécanisme permettant de garantir l'intégrité d'un SDK et de sa provenance, ainsi que d'une application et de sa provenance, et de résoudre leurs dépendances
  • Mécanisme permettant de les déployer sur des appareils de manière fiable et performante

Évolution des restrictions au fil du temps

Les restrictions auxquelles le code du SDK Runtime est confronté devraient évoluer avec les versions ultérieures d'Android. Pour assurer la compatibilité des applications, nous ne modifierons pas ces restrictions avec les mises à jour du module principal pour un niveau de SDK donné. Le comportement associé à une targetSdkVersion spécifique sera conservé jusqu'à ce que la prise en charge de cette targetSdkVersion soit abandonnée via le règlement de la plate-forme de téléchargement d'applications. L'abandon de targetSdkVersion pourra se produire à un rythme plus rapide que pour les applications. Attendez-vous à des changements fréquents des restrictions entre les versions du SDK Android, en particulier dans les premières versions.

En outre, nous concevons un mécanisme Canary permettant aux testeurs externes et internes de rejoindre un groupe qui recevra l'ensemble de restrictions proposé pour la prochaine version d'Android. Cela nous aidera à recueillir des commentaires sur les modifications proposées pour l'ensemble de restrictions et à recevoir un "vote de confiance" de la part des utilisateurs.

Questions fréquentes

  1. Qu'est-ce qu'un SDK publicitaire ?

    Un SDK publicitaire facilite le ciblage des utilisateurs avec la publication de messages ayant un but commercial sur des applications qui n'appartiennent pas à l'annonceur. Cela inclut, sans s'y limiter, les SDK d'analytique permettant de créer des groupes d'utilisateurs pour le ciblage ultérieur, les SDK de diffusion d'annonces, les SDK de lutte contre les utilisations abusives et la fraude dans les annonces, les SDK d'engagement et les SDK d'attribution.

  2. Un SDK peut-il s'exécuter dans le SDK Runtime ?

    Bien que l'objectif premier soit destiné aux SDK publicitaires, les développeurs de SDK non publicitaires qui cherchent à protéger la confidentialité et qui pensent pouvoir fonctionner dans les conditions décrites ci-dessus peuvent partager des commentaires sur leur SDK s'exécutant dans le SDK Runtime. Toutefois, le SDK Runtime n'est pas conçu pour être compatible avec toutes les conceptions de SDK. Au-delà des limites déjà documentées, cet environnement n'est probablement pas adapté aux SDK qui nécessitent des communications à temps réel ou à haut débit avec l'application hôte.

  3. Pourquoi choisir l'isolement de processus plutôt que l'isolement dans l'environnement d'exécution Java d'un processus ?

    Actuellement, l'environnement d'exécution basé sur Java ne permet pas de respecter facilement les limites de sécurité nécessaires pour garantir la confidentialité souhaitée pour les utilisateurs Android. Toute tentative d'implémentation d'un modèle de ce type nécessiterait probablement plusieurs années, sans garantie de réussite. C'est pourquoi la Privacy Sandbox repose sur les limites de processus, une technologie éprouvée et bien comprise.

  4. Le transfert des SDK vers le SDK Runtime permettrait-il de réduire la taille du téléchargement ou d'économiser de l'espace ?

    Si plusieurs applications sont intégrées à des SDK de même version compatibles avec l'environnement d'exécution, cela peut réduire la taille de téléchargement et l'espace disque.

  5. À quels types d'événements de cycle de vie de l'application, tels que le passage en arrière-plan, les SDK auront-ils accès dans le SDK Runtime ?

    Nous travaillons activement sur la compatibilité de la conception afin de signaler au SDK Runtime les événements de cycle de vie au niveau de l'application cliente (par exemple, lorsque l'application passe en arrière-plan ou au premier plan). La conception et l'exemple de code seront partagés dans une prochaine version Preview développeur.