Les captures instantanées de tâches sont une infrastructure introduite dans Android 8.0 qui combine des captures d'écran pour les miniatures des applis récentes et les surfaces enregistrées du gestionnaire de fenêtres. Les miniatures des éléments récents représentent le dernier état d'une tâche dans la vue "Éléments récents".
Lorsqu'une activité passait à l'état arrêté, le gestionnaire de fenêtres ne détruisait pas les surfaces de l'activité tant que celle-ci se trouvait en haut de la tâche. Si cette activité devait être affichée à nouveau, le gestionnaire de fenêtres pouvait démarrer l'animation sans attendre que l'activité ait fini de dessiner son premier frame, car il pouvait utiliser cette surface enregistrée.
Architecture
Les deux concepts de miniatures des applications récentes et de surfaces enregistrées sont unifiés avec les instantanés de tâches. Lorsqu'une tâche passe en arrière-plan, le gestionnaire de fenêtres place une capture d'écran de cette tâche dans un GraphicBuffer. Tant que l'application de l'activité principale de la tâche reste en mémoire, ce GraphicBuffer y est conservé. Désormais, lorsque la même activité est ramenée au premier plan, WindowManager crée une fenêtre de démarrage (TaskSnapshotSurface) et associe le GraphicBuffer sans copier de mémoire dans la file d'attente de tampon de la fenêtre de démarrage. Dès que l'activité a dessiné son premier frame, la fenêtre de démarrage de l'instantané de tâche disparaît progressivement comme les écrans de démarrage classiques.
Le même GraphicBuffer est également envoyé via Binder à SystemUI pour être utilisé afin de dessiner l'état d'aperçu d'une tâche dans la vue "Récents". Comme il ne s'agit que d'une référence à un tampon, son envoi via Binder consomme peu de ressources. Lorsque le GraphicBuffer arrive dans SystemUI, il est encapsulé dans un bitmap matériel, puis dessiné à l'écran sans aucun chargement de mémoire dans la mémoire graphique.
Avantages
Cette nouvelle architecture présente trois principaux avantages :
- Si l'instantané de la tâche est utilisé comme fenêtre de départ, un fondu enchaîné fluide est effectué entre l'instantané et le contenu réel.
- Lorsque l'instantané de la tâche est dessiné dans SystemUI, il peut l'être sans aucune copie. Auparavant, le bitmap devait être copié dans Ashmem, puis dans la mémoire graphique. Comme cette méthode stocke l'instantané directement dans la mémoire graphique, aucune copie n'est nécessaire.
- L'état que vous voyez dans "Récents" correspond toujours à l'état que vous verrez en premier lorsque vous rouvrirez l'application. Le fait d'avoir le même tampon ici permet également d'économiser beaucoup de mémoire. C'est pourquoi la section "Récents" peut désormais afficher ces images en haute résolution. Auparavant, il était sous-échantillonné de 64% pour économiser de la mémoire.
Implémentation
Cette fonctionnalité existe entièrement sur la plate-forme Android. Aucune intégration n'est requise et la personnalisation n'est pas prise en charge. Toutefois, les fabricants d'appareils peuvent désactiver complètement la fonctionnalité d'aperçu des tâches.
Pour désactiver cette fonctionnalité, modifiez cette fonction :
frameworks/base/services/core/java/com/android/server/wm/TaskSnapshotController.java#215
Notez que si la fonctionnalité est désactivée, la vue "Récents" n'affichera aucune miniature.
Instantanés haute et basse résolution
Les instantanés de tâches sont écrits sur le disque à deux échelles. Lorsque vous restaurez un instantané de tâche à partir du disque, les instantanés basse résolution sont lus en premier, puis remplacés par leur équivalent haute résolution. Cette optimisation améliore les temps de chargement des images. Sinon, il pourrait y avoir un léger délai lors de la lecture du fichier d'instantané à partir du disque, et l'utilisateur verrait une fiche de tâche vide jusqu'à ce que l'image soit disponible. Vous pouvez configurer les échelles dans le fichier de configuration de superposition de l'appareiloverlay/frameworks/base/core/res/res/values/config.xml en définissant config_highResTaskSnapshotScale et config_lowResTaskSnapshotScale. Par défaut, ces valeurs sont définies sur 1,0 et 0,5, respectivement. Désactivez les instantanés basse résolution en définissant config_lowResTaskSnapshotScale sur 0.0.
Exemples et source
Vous trouverez le reste du code de cette fonctionnalité dans les fichiers TaskSnapshot* :
frameworks/base/+/android17-release/services/core/java/com/android/server/wm/