Prise en charge des décorations système

Vous trouverez ci-dessous les modifications apportées à ces zones spécifiques au Réseau Display:

Décorations système

Android 10 prend désormais en charge la configuration affiche certaines décorations système, comme le fond d'écran, la barre de navigation, et lanceur d'applications. Par défaut, l'écran principal affiche toutes les décorations du système et les écrans secondaires affichent ceux qui sont activés en option. Compatibilité avec un éditeur de mode de saisie (IME) peuvent être définis séparément des autres décorations système.

Utiliser DisplayWindowSettings#setShouldShowSystemDecorsLocked() pour ajouter la prise en charge des décorations système sur un écran spécifique ou fournir une valeur par défaut dans /data/system/display_settings.xml. Par exemple, consultez la section Paramètres de la fenêtre d'affichage.

Implémentation

DisplayWindowSettings#setShouldShowSystemDecorsLocked() est également exposé dans WindowManager#setShouldShowSystemDecors() à des fins de test. Déclenchement de cette méthode avec l'intention d'activer les décors système n'ajoute pas de fenêtres de décoration qui étaient ou les supprimer s'ils étaient présents. Dans la plupart des cas dans certains cas, la prise en charge des décorations système ne prend pleinement effet qu'après de l'appareil.

Vérifie la compatibilité des décorations système dans le code base WindowManager passent généralement par DisplayContent#supportsSystemDecorations() alors que des services externes (tels que l'UI du système, pour vérifier si la barre de navigation à afficher) utilisez WindowManager#shouldShowSystemDecors(). Pour comprendre ce qui est contrôlé par ce paramètre, explorez les points d'appel de ces méthodes.

Fenêtres de décoration de l'UI du système

Android 10 ajoute la prise en charge des fenêtres de décoration système de la barre de navigation uniquement, car celle-ci est essentielle pour naviguer entre les activités et les applications. Par défaut, la barre de navigation affiche affordances "retour" et "domicile". Cette valeur n'est incluse que si l'affichage cible est compatible avec des décorations système (voir DisplayWindowSettings).

La barre d'état est une fenêtre système plus compliquée, car elle contient également le volet des notifications, les Réglages rapides et l'écran de verrouillage. Sur Android 10, la barre d'état n'est pas compatible avec les écrans secondaires. Par conséquent, les notifications, les paramètres et le verrouillage du clavier ne sont disponibles que sur la l'écran principal.

La fenêtre système Aperçu/Éléments récents n'est pas compatible avec les applications secondaires écrans. Sous Android 10, AOSP n'affiche que les éléments récents l'affichage par défaut et contient les activités de tous les affichages. Lorsqu'elle est lancée depuis "Récentes", une activité qui se trouvait sur un écran secondaire est mise au premier plan sur qui s'affichent par défaut. Cette approche présente certains problèmes connus, se mettent à jour immédiatement lorsque les applications apparaissent sur d'autres écrans.

Implémentation

Pour implémenter des fonctionnalités supplémentaires de l'UI du système, les fabricants d'appareils doivent utiliser un composant unique d'UI du système qui écoute l'ajout/la suppression d'écrans et présente un contenu approprié ;

Un composant d'UI du système compatible avec le mode multi-écran doit gérer les cas suivants:

  • Initialisation de plusieurs écrans au démarrage
  • Écran ajouté au moment de l'exécution
  • Écran supprimé au moment de l'exécution

Lorsque l'UI du système détecte l'ajout d'un écran avant WindowManager, elle crée une condition de concurrence. Pour éviter cela, implémentez un rappel personnalisé à partir de WindowManager à l'UI du système lorsqu'un écran est ajouté au lieu de s'abonner à Événements DisplayManager.DisplayListener. Pour une implémentation de référence, Voir CommandQueue.Callbacks#onDisplayReady pour la prise en charge de la barre de navigation et WallpaperManagerInternal#onDisplayReady pour les fonds d'écran.

En outre, Android 10 fournit les mises à jour suivantes:

  • La classe NavigationBarController contrôle toutes les fonctionnalités spécifiques aux barres de navigation.
  • Pour afficher une barre de navigation personnalisée, consultez CarStatusBar.
  • TYPE_NAVIGATION_BAR n'est plus restreint à un seul et peuvent être utilisées par écran.
  • IWindowManager#hasNavigationBar() est mis à jour pour inclure la Paramètre displayId pour l'UI du système uniquement.

Lanceur d'applications

Sous Android 10, chaque écran configuré pour prendre en charge système decorations dispose d'une pile d'accueil dédiée aux activités de lanceur d'applications avec WindowConfiguration#ACTIVITY_TYPE_HOME, par défaut. Chaque écran utilise une instance distincte de l'activité du lanceur d'applications.

Figure 1 : Exemple de lanceur multi-écran pour platform/development/samples/MultiDisplay

La plupart des lanceurs existants ne prennent pas en charge plusieurs instances et ne sont pas optimisés pour les grands écrans. De plus, on s'attend souvent à un type d'expérience différent sur les écrans secondaires ou externes. Pour fournir une activité dédiée aux services écrans, Android 10 introduit la catégorie SECONDARY_HOME dans l'intent des filtres. Les instances de cette activité sont utilisées sur tous les écrans compatibles avec le système une par écran.

<activity>
    ...
    <intent-filter>
        <category android:name="android.intent.category.SECONDARY_HOME" />
        ...
    </intent-filter>
</activity>

L'activité doit avoir un mode de lancement qui n'empêche pas plusieurs et doit s'adapter à différentes tailles d'écran. Mode de lancement ne peut pas être singleInstance ni singleTask.

Implémentation

Sous Android 10, RootActivityContainer#startHomeOnDisplay() sélectionne automatiquement le composant et l'intent souhaités en fonction de l'affichage où l'écran d'accueil est lancé. RootActivityContainer#resolveSecondaryHomeActivity() contient la logique permettant de rechercher le composant d'activité du lanceur d'applications en fonction le lanceur d'applications sélectionné et peut utiliser la valeur par défaut du système, si nécessaire (voir ActivityTaskManagerService#getSecondaryHomeIntent()).

Restrictions de sécurité

Outre les restrictions qui s'appliquent aux activités sur les écrans secondaires, pour éviter qu'une application malveillante crée un affichage virtuel avec l'option Décorations du système et la lecture d'informations sensibles à partir de la surface, le lanceur d'applications n'apparaît sur des écrans virtuels appartenant au système. Le lanceur d'applications n'affiche aucun contenu sur des écrans virtuels non-système.

Fonds d'écran

Sous Android 10 (ou version ultérieure), les fonds d'écran sont compatibles sur les écrans secondaires:

Figure 2. Fond d'écran animé (interne (ci-dessus) et externe) s'affiche (ci-dessous)

Les développeurs peuvent déclarer la prise en charge de la fonctionnalité de fond d'écran en fournissant android:supportsMultipleDisplays="true" dans la Définition XML WallpaperInfo. Les développeurs de fonds d'écran sont également chargé de charger les éléments à l'aide du contexte d'affichage WallpaperService.Engine#getDisplayContext()

Le framework crée une instance WallpaperService.Engine. par écran, afin que chaque moteur dispose de sa propre surface et de son propre contexte d'affichage. La le développeur doit s'assurer que chaque moteur peut dessiner de manière indépendante, différentes fréquences d'images, en respectant VSYNC.

Sélectionner des fonds d'écran pour chaque écran

Android 10 ne prend pas directement en charge la plate-forme pour la sélection des fonds d'écran pour les écrans individuels. Pour ce faire, un identifiant d'affichage stable est nécessaires pour conserver les paramètres de fond d'écran par écran. Display#getDisplayId() est dynamique. Il n'y a donc aucune garantie qu'une l'écran physique aura le même ID après le redémarrage.

Cependant, Android 10 a ajouté DisplayInfo.mAddress, qui contient des identifiants stables pour les écrans physiques et peut être utilisé mise en œuvre à l'avenir. Malheureusement, il est trop tard pour implémenter la logique pour Android 10. Solution suggérée:

  1. Utilisez l'API WallpaperManager pour définir les fonds d'écran.
  2. WallpaperManager est obtenu à partir d'un Context. et chaque objet Context contient des informations sur les l'écran (Context#getDisplay()/getDisplayId()). Par conséquent, vous pouvez obtenir displayId à partir d'une instance WallpaperManager sans ajouter de nouvelles méthodes.
  3. Côté framework, utilisez displayId, obtenu à partir d'un Context et le mapper à un identifiant statique (comme un port de un écran physique). Utilisez l'identifiant statique pour conserver le fond d'écran choisi.

Cette solution utilise des implémentations existantes pour les sélecteurs de fond d'écran. Si a été ouvert sur un écran spécifique et utilise le contexte approprié, pour définir un fond d'écran, le système peut identifier automatiquement l'écran.

S'il est nécessaire de définir un fond d'écran pour un autre écran puis créez un objet Context pour l'écran cible. (Context#createDisplayContext) et d'obtenir la valeur WallpaperManager sur cet écran.

Restrictions de sécurité

Le système n'affiche pas sur les écrans virtuels les fonds d'écran dont il n'est pas propriétaire. Cela est dû à un problème de sécurité : une application malveillante pourrait créer un s'affichent avec les décorations système activées et lisent un contenu informations visibles à l'écran (une photo personnelle, par exemple).

Implémentation

Sous Android 10, le IWallpaperConnection#attachEngine() et IWallpaperService#attach() acceptent les displayId pour créer des connexions par écran. WallpaperManagerService.DisplayConnector encapsule un écran par écran. un moteur de fond d'écran et une connexion. Dans WindowManager, les contrôleurs de fond d'écran est créée pour chaque objet DisplayContent lors de sa construction au lieu d'une une seule WallpaperController pour tous les écrans.

Certaines implémentations publiques de la méthode WallpaperManager (comme WallpaperManager#getDesiredMinimumWidth()) ont été mises à jour pour calculer et de fournir des informations pour les écrans correspondants. WallpaperInfo#supportsMultipleDisplays() et une de ressource ont été ajoutés, afin que les développeurs d'applications puissent signaler les les fonds d'écran sont prêts pour plusieurs écrans.

Si le service de fond d'écran affiché sur l'écran par défaut n'est pas compatible sur plusieurs écrans, le système affiche le fond d'écran par défaut s'affiche.

Figure 3. Logique de remplacement de fond d'écran pour les écrans secondaires