Extensions du gestionnaire de fenêtres

La bibliothèque Jetpack WindowManager permet aux développeurs d'applications de prendre en charge de nouveaux facteurs de forme d'appareil et des environnements multi-fenêtres.

WindowManager Extensions (Extensions) est un module de plate-forme Android opt-in qui active une variété de fonctionnalités de Jetpack WindowManager. Le module est implémenté dans AOSP dans frameworks/base/libs/WindowManager/Jetpack et livré sur des appareils prenant en charge les fonctionnalités de WindowManager.

Distribution des modules d'extensions

Les extensions sont compilées dans une bibliothèque .jar et placées dans la partition system_ext sur un périphérique si les extensions sont activées dans le makefile du périphérique.

Pour activer les extensions sur un appareil, ajoutez les éléments suivants au makefile de l'appareil du produit :

$(call inherit-product, $(SRC_TARGET_DIR)/product/window_extensions.mk)

Cela active les packages androidx.window.extensions et androidx.window.sidecar sur l'appareil et définit la propriété persist.wm.extensions.enabled . L'inclusion de ces packages dans le makefile place également les déclarations dans etc/permissions/ , les rendant disponibles pour les processus d'application. Normalement, les modules sont chargés et exécutés dans le cadre du processus d'application au moment de l'exécution lorsqu'ils sont utilisés par la bibliothèque Jetpack WindowManager, ce qui rend son fonctionnement similaire au code du framework côté client, comme le montre la figure suivante :

Figure 1. Extensions WindowManager chargées dans le processus d'application similaire au code de la plate-forme.

Le module androidx.window.extensions est le module Extensions actuel en développement actif. Le module androidx.window.sidecar est un module hérité inclus pour la compatibilité avec les premières versions de Jetpack WindowManager, mais le side-car n'est plus activement maintenu.

La figure suivante montre la logique permettant de déterminer l'utilisation de androidx.window.extensions ou androidx.window.sidecar .

Figure 2. Arbre de décision pour accéder à androidx.window.extensions ou androidx.window.sidecar .

Modules d'extension

Les extensions fournissent des fonctionnalités de fenêtrage pour les appareils pliables à grand écran et les appareils prenant en charge le fenêtrage sur des écrans externes. Les domaines de fonctionnalités comprennent :

Les implémentations OEM des extensions peuvent fournir des composants nuls ou des composants avec des implémentations par défaut ou stub des méthodes dans l'interface WindowExtensions si le matériel du périphérique ne prend pas en charge les fonctionnalités correspondantes, à moins que la fonctionnalité ne soit spécifiquement demandée dans le document de définition de compatibilité (CDD) 7.1.1.1. .

Extensions et API Jetpack

Le module WindowManager Extensions fournit sa propre surface API en plus des API de la plateforme publique. Le module Extensions est développé publiquement dans une bibliothèque Jetpack androidx.window.extensions non destinée aux développeurs, afin que Jetpack WindowManager ( androidx.window ) puisse établir un lien avec celui-ci au moment de la compilation. La surface de l’API Extensions fournit généralement des API de niveau inférieur.

Les API fournies par les extensions sont destinées à être utilisées uniquement par la bibliothèque Jetpack WindowManager. Les API d'extensions ne sont pas destinées à être appelées directement par les développeurs d'applications. La bibliothèque d'extensions ne doit pas être ajoutée en tant que dépendance d'une application dans le fichier de build Gradle pour garantir une fonctionnalité correcte. Évitez de précompiler la bibliothèque Extensions directement dans une application ; comptez plutôt sur le chargement du runtime pour éviter le cas de chargement d’un mélange de classes d’extensions précompilées et fournies par le runtime.

Jetpack WindowManager ( androidx.window ) est destiné à être ajouté en tant que dépendance d'application et fournit les API publiques destinées aux développeurs, y compris celles pour les fonctionnalités des extensions WindowManager. La bibliothèque WindowManager charge automatiquement les extensions dans le processus d'application et intègre les API d'extensions de niveau inférieur dans des abstractions de niveau supérieur et des interfaces plus ciblées. Les API WindowManager Jetpack suivent les normes de développement d'applications Android modernes et sont destinées à fournir une interopérabilité pratique en s'intégrant bien aux bases de code qui utilisent d'autres bibliothèques AndroidX.

Versions et mises à jour des extensions

Le module Extensions peut être mis à jour avec les mises à jour annuelles ou trimestrielles de la plateforme Android. Les mises à jour trimestrielles permettent d'augmenter le niveau de l'API des extensions entre les mises à jour de l'API de la plate-forme Android, permettant une itération plus rapide et offrant aux OEM la possibilité d'ajouter un accès API officiel à de nouvelles fonctionnalités proches des lancements de matériel.

Le tableau suivant répertorie les versions de l'API androidx.window.extensions pour différentes versions d'Android.

Version de la plateforme Android Niveau API des extensions WindowManager Version de l'API androidx.window.extensions
Android 14 3 1.2.0
Android 13 QPR3 2 1.1.0
Android 13 1 1.0.0
Android 12L 1 1.0.0

Le niveau de l'API Extensions (colonne centrale) augmente à chaque fois qu'il y a un ajout à la surface de l'API stable existante (colonne de droite).

Compatibilité ascendante et ascendante

Jetpack WindowManager gère la complexité liée aux mises à jour fréquentes au niveau de l'API, à l'évolution rapide de l'API et à la rétrocompatibilité. Lorsque le code de la bibliothèque est exécuté dans le processus d'application, la bibliothèque vérifie le niveau d'API d'extensions déclaré et donne accès aux fonctionnalités en fonction du niveau déclaré.

Pour protéger une application contre le plantage au moment de l'exécution, WindowManager effectue également une vérification de réflexion Java à l'exécution des API d'extensions disponibles en fonction du niveau d'API d'extensions déclaré. En cas de non-concordance, WindowManager peut désactiver l'utilisation des extensions (partiellement ou complètement) et signaler les fonctionnalités pertinentes comme non disponibles pour l'application.

Les extensions WindowManager sont implémentées en tant que module system_ext qui utilise des API de plate-forme privée pour appeler le noyau WindowManager, DeviceStateManager et d'autres services système dans la mise en œuvre des fonctionnalités des extensions.

La compatibilité peut ne pas être maintenue avec les versions préliminaires des Extensions avant la version trimestrielle ou annuelle correspondante de la plateforme Android avec laquelle les versions sont finalisées. L'historique complet des API Extensions peut être trouvé dans la branche de publication window:extensions:extensions API text files .

Les versions plus récentes des extensions doivent continuer à fonctionner avec les anciennes versions de WindowManager compilées dans les applications pour maintenir la compatibilité ascendante. Pour garantir cela, toute nouvelle version de l'API Extensions ajoute uniquement de nouvelles API et ne supprime pas les anciennes. Par conséquent, les applications dotées d'anciennes versions de WindowManager peuvent continuer à utiliser les anciennes API d'extension avec lesquelles les applications ont été compilées.

La vérification CTS garantit que pour toute version déclarée des API d'extensions sur l'appareil, toutes les API de cette version et des versions précédentes sont présentes et fonctionnelles.

Performance

Le module Extensions est mis en cache par défaut dans les chargeurs de classes système non bootclasspath à partir d'Android 14 (niveau d'API 34), il n'y a donc aucun impact sur les performances en raison du chargement du module en mémoire au démarrage de l'application. L'utilisation des fonctionnalités de modules individuels peut avoir une légère influence sur les caractéristiques de performances des applications lorsque des appels IPC supplémentaires sont effectués entre le client et le serveur.

Modules

Intégration d'activité

Le composant d'intégration d'activité fournit un ensemble de fonctionnalités qui permettent aux applications d'organiser la présentation de la fenêtre d'activité dans les limites de l'application parent. Cela inclut l’affichage simultané de deux activités côte à côte dans une présentation à plusieurs volets, facilitant ainsi l’optimisation sur grand écran pour les applications existantes.

Le composant d'intégration d'activité doit être disponible sur tous les appareils dotés d'un écran intégré d'une taille égale ou supérieure à sw600 dp . L'intégration d'activités doit également être activée sur les appareils prenant en charge les connexions d'écrans externes, car l'application peut s'afficher dans une taille plus grande lorsque des écrans externes sont connectés au moment de l'exécution.

Configuration de l'appareil

Aucune configuration spécifique de l'appareil n'est nécessaire autre que l'activation du module Extensions comme décrit dans la section Distribution du module Extensions . Il est logique d’activer les extensions sur tous les appareils prenant en charge le mode multi-fenêtres. Les futures versions d'Android nécessiteront probablement des extensions sur les configurations courantes d'appareils portables et à grand écran.

Informations sur la disposition des fenêtres

Le composant d'informations de disposition de fenêtre identifie la position et l'état de la charnière sur un dispositif pliable lorsque la charnière traverse une fenêtre d'application. Les informations sur la disposition des fenêtres permettent aux applications de réagir et d'afficher des dispositions optimisées en mode table sur les pliables. Voir Rendre votre application consciente pour les détails d'utilisation.

Les appareils Android pliables qui incluent une charnière reliant des zones de panneau d'affichage séparées ou continues doivent rendre les informations sur la charnière disponibles pour les applications via WindowLayoutComponent .

La position et les limites de la charnière doivent être signalées par rapport à la fenêtre d'application identifiée par un Context transmis à l'API. Si les limites de la fenêtre d’application ne croisent pas les limites de la charnière, la charnière DisplayFeature ne doit pas être signalée. Il est également acceptable de ne pas signaler les fonctionnalités d'affichage lorsque leur position peut ne pas être signalée de manière fiable, par exemple lorsqu'une fenêtre d'application peut être librement déplacée par l'utilisateur en mode multi-fenêtres ou en mode boîte aux lettres de compatibilité.

Pour les fonctionnalités de pliage , les mises à jour d'état doivent être signalées lorsque la position de la charnière change entre les états stables. Par défaut, dans un état d'affichage plat, l'API doit signaler FoldingFeature.State.FLAT . Si le matériel de l'appareil peut être laissé en mode semi-plié dans un état stable, l'API doit signaler FoldingFeature.State.HALF_OPENED . Il n'y a pas d'état fermé dans l'API, car dans un tel cas, la fenêtre de l'application ne serait pas visible ou ne franchirait pas les limites de la charnière.

Configuration de l'appareil

Pour prendre en charge la mise en œuvre de la fonctionnalité de pliage, les OEM doivent procéder comme suit :

  • Configurez les états des appareils dans device_state_configuration.xml à utiliser par DeviceStateManagerService . Voir DeviceStateProviderImpl.java pour référence.

    Si les implémentations par défaut de DeviceStateProvider ou DeviceStatePolicy ne conviennent pas à l'appareil, une implémentation personnalisée peut être utilisée.

  • Activez le module Extensions comme décrit dans la section Distribution du module Extensions .

  • Spécifiez l'emplacement des fonctionnalités d'affichage dans la ressource de chaîne com.android.internal.R.string.config_display_features (généralement dans frameworks/base/core/res/res/values/config.xml dans la superposition de périphériques).

    Le format attendu pour la chaîne est :

    <type>-[<left>,<top>,<right>,<bottom>]

    Le type peut être fold ou hinge . Les valeurs de left , top , right et bottom sont des coordonnées de pixels entières dans l'espace de coordonnées d'affichage dans l'orientation naturelle de l'affichage. La chaîne de configuration peut contenir plusieurs fonctionnalités d'affichage séparées par des points-virgules.

    Par exemple:

    <!-- Jetpack WindowManager display features -->
    <string name="config_display_features" translatable="false">fold-[1000,0,1000,2000]</string>
    
  • Définissez le mappage entre les identifiants d'état internes de l'appareil utilisés dans DeviceStateManager et les constantes d'état publiques envoyées aux développeurs dans com.android.internal.R.array.config_device_state_postures .

    Le format attendu pour chaque entrée est :

    <device_specific_state_identifier>:<Jetpack WindowManager state identifier>

    Les identifiants d'état pris en charge sont :

    • COMMON_STATE_NO_FOLDING_FEATURES = 1 : l'état n'a aucune fonctionnalité de pliage à signaler. Par exemple, il peut s'agir de l'état fermé d'un dispositif de pliage typique avec l'écran principal sur le côté intérieur.
    • COMMON_STATE_HALF_OPENED = 2 : La fonction de pliage est à moitié ouverte.
    • COMMON_STATE_FLAT = 3 : La fonction de pliage est plate. Par exemple, il peut s'agir de l'état ouvert d'un dispositif de pliage typique avec l'écran principal sur le côté intérieur.
    • COMMON_STATE_USE_BASE_STATE = 1000 : dans Android 14, une valeur qui peut être utilisée pour les états émulés où l'état de charnière est dérivé à l'aide de l'état de base, tel que défini dans CommonFoldingFeature.java

    Voir DeviceStateManager.DeviceStateCallback#onBaseStateChanged(int) pour plus d'informations.

    Par exemple:

    <!-- Map of System DeviceState supplied by DeviceStateManager to WindowManager posture.-->
    <string-array name="config_device_state_postures" translatable="false">
        <item>0:1</item>    <!-- CLOSED       : COMMON_STATE_NO_FOLDING_FEATURES -->
        <item>1:2</item>    <!-- HALF_OPENED  : COMMON_STATE_HALF_OPENED -->
        <item>2:3</item>    <!-- OPENED       : COMMON_STATE_FLAT -->
        <item>3:1</item>    <!-- REAR_DISPLAY : COMMON_STATE_NO_FOLDING_FEATURES -->
        <item>4:1000</item> <!-- CONCURRENT   : COMMON_STATE_USE_BASE_STATE -->
    </string-array>
    

Zone de fenêtre

Le composant de zone de fenêtre fournit un ensemble de fonctionnalités qui permettent aux applications d'accéder à des écrans et des zones d'affichage supplémentaires sur certains appareils pliables et multi-écrans.

Le mode d'affichage arrière permet à une application d'afficher l'interface utilisateur d'aperçu de l'appareil photo sur l'écran de couverture d'un appareil pliable afin de permettre l'utilisation de l'appareil photo principal de l'appareil pour les selfies et les vidéos. Les appareils dotés d'un écran de couverture compatible Android (tel que défini par le CDD Android en termes d'attributs tels que la taille, la densité et les possibilités de navigation disponibles) qui s'aligne avec les caméras arrière de l'appareil doivent donner accès au mode d'affichage arrière.

Sur Android 14, le mode double affichage permet aux applications qui s'exécutent sur l'écran interne d'un appareil pliable d'afficher du contenu supplémentaire sur l'écran de couverture face aux autres utilisateurs ; par exemple, l'écran de couverture peut montrer l'aperçu de l'appareil photo à la personne photographiée ou enregistrée.

Configuration de l'appareil

Pour prendre en charge la mise en œuvre de la fonctionnalité de pliage, les OEM doivent procéder comme suit :

  • Configurez les états des appareils dans device_state_configuration.xml à utiliser par DeviceStateManagerService . Voir DeviceStateProviderImpl.java pour plus d'informations.

    Si l’implémentation par défaut de DeviceStateProvider ou DeviceStatePolicy ne convient pas à l’appareil, une implémentation personnalisée peut être utilisée.

  • Pour les appareils pliables prenant en charge le mode ouvert ou plat, spécifiez les identifiants d'état correspondants dans com.android.internal.R.array.config_openDeviceStates .

  • Pour les appareils pliables prenant en charge les états repliés, répertoriez les identifiants d'état correspondants dans com.android.internal.R.array.config_foldedDeviceStates .

  • Pour les appareils pliables prenant en charge un état à moitié plié (la charnière est à moitié ouverte comme un ordinateur portable), répertoriez les états correspondants dans com.android.internal.R.array.config_halfFoldedDeviceStates .

  • Pour les appareils prenant en charge le mode d'affichage arrière :

    • Répertoriez les états correspondants dans com.android.internal.R.array.config_rearDisplayDeviceStates pour DeviceStateManager .
    • Spécifiez l'adresse d'affichage physique de l'écran arrière dans com.android.internal.R.string.config_rearDisplayPhysicalAddress .
    • Spécifiez l'identifiant d'état dans com.android.internal.R.integer.config_deviceStateRearDisplay à utiliser par les extensions.
    • Ajoutez l'identifiant d'état dans com.android.internal.R.array.config_deviceStatesAvailableForAppRequests pour le rendre disponible aux applications.
  • Sur Android 14, pour les appareils prenant en charge le mode d'affichage double (simultané) :

    • Définissez com.android.internal.R.bool.config_supportsConcurrentInternalDisplays sur true .
    • Spécifiez l'adresse d'affichage physique de l'écran arrière dans com.android.internal.R.config_deviceStateConcurrentRearDisplay .
    • Spécifiez l'identifiant d'état dans com.android.internal.R.integer.config_deviceStateConcurrentRearDisplay à utiliser par les extensions si l'identifiant est destiné à être mis à disposition pour les applications.
    • Ajoutez l'identifiant d'état dans com.android.internal.R.array.config_deviceStatesAvailableForAppRequests pour le rendre disponible aux applications.

Vérification

Les OEM doivent vérifier leurs implémentations pour garantir le comportement attendu dans les scénarios courants. Les tests CTS et les tests utilisant Jetpack WindowManager sont disponibles pour les OEM pour tester les implémentations.

Essais CTS

Pour exécuter les tests CTS, consultez Exécuter les tests CTS . Les tests CTS liés à Jetpack WindowManager se trouvent sous cts/tests/framework/base/windowmanager/jetpack/ . Le nom du module de test est CtsWindowManagerJetpackTestCases .

Tests du gestionnaire de fenêtres

Pour télécharger les tests Jetpack WindowManager, suivez les instructions Android Jetpack . Les tests se trouvent dans la bibliothèque window sous le module window:window window : window/window/src/androidTest/ .

Pour exécuter les tests de périphérique pour le module window:window à partir de la ligne de commande, procédez comme suit :

  1. Branchez un appareil sur lequel les options de développement et le débogage USB sont activés.
  2. Autorisez l'ordinateur à déboguer le périphérique.
  3. Ouvrez un shell dans le répertoire racine du référentiel androidx.
  4. Changez le répertoire en framework/support .
  5. Exécutez la commande suivante : ./gradlew window:window:connectedAndroidTest .
  6. Analysez les résultats.

Pour exécuter les tests depuis Android Studio, procédez comme suit :

  1. Ouvrez Android Studio.
  2. Branchez un appareil sur lequel les options de développement et le débogage USB sont activés.
  3. Autorisez l'ordinateur à déboguer le périphérique.
  4. Accédez à un test dans la bibliothèque de fenêtres du module de fenêtre.
  5. Ouvrez une classe de test et exécutez-la à l'aide des flèches vertes sur le côté droit de l'éditeur.

Vous pouvez également créer une configuration dans Android Studio pour exécuter une méthode de test, une classe de test ou tous les tests d'un module.

Les résultats peuvent être analysés manuellement en examinant la sortie du shell. Certains tests sont ignorés si l'appareil ne répond pas à certaines hypothèses. Les résultats sont enregistrés dans un emplacement standard et les analystes peuvent écrire un script pour automatiser l'analyse des résultats.