Winscope est un outil Web qui permet aux utilisateurs d'enregistrer, de relire et d'analyser les états de plusieurs services système pendant et après les animations et les transitions. Winscope enregistre tous les états de service système pertinents dans un fichier de trace. En utilisant l'interface utilisateur Winscope avec le fichier de trace, vous pouvez inspecter l'état de ces services pour chaque frame d'animation, avec ou sans enregistrement d'écran, en rejouant, en parcourant et en déboguant les transitions.
Traces compatibles
Winscope permet de collecter et de représenter visuellement différentes traces ou séquences d'états de service système. Vous pouvez configurer ces traces en fonction de cas d'utilisation spécifiques, allant d'une faible surcharge à une verbosité élevée. Les traces suivantes sont acceptées par Winscope :
- EventLog : collectez l'enregistrement des événements de diagnostic système à l'aide de
EventLog
. Dans Winscope, ces informations ne sont utilisées que pour identifier et afficher les marquages CUJ. - IME : événements de trace du pipeline de l'éditeur de méthode d'entrée (IME), y compris IMS, IMMS et le client IME.
- Entrée : tracez les événements d'entrée provenant de différentes parties du pipeline d'événements d'entrée.
- ProtoLog : collecte les messages ProtoLog des services système et du code des services système exécutés dans les processus client.
- Enregistrement d'écran : collectez un enregistrement d'écran en plus des traces.
- Transitions du shell : enregistrez les détails du système de transition des fenêtres et des activités.
- SurfaceFlinger : collecte les traces SurfaceFlinger contenant des informations sur les surfaces (calques), telles que la position, la mémoire tampon et la composition.
- Transactions : tracez l'ensemble des modifications atomiques reçues par SurfaceFlinger à l'aide de
SurfaceControl
pour la composition. - ViewCapture : capture une série de propriétés de toutes les vues des fenêtres système compatibles avec ViewCapture, comme l'UI système et le lanceur d'applications.
- Gestionnaire de fenêtres : états Gestionnaire de fenêtres contenant des informations sur les fenêtres, y compris les événements d'entrée et de mise au point, l'orientation de l'écran, les transitions, les animations, le positionnement et les transformations.
Dumps compatibles
Winscope peut collecter et afficher des dumps d'état, qui sont des instantanés de l'état de l'appareil pris à des moments spécifiques définis par l'utilisateur. Contrairement aux traces, qui sont collectées en continu pendant l'utilisation de l'appareil et peuvent avoir un impact sur les performances, les dumps ne sont effectués qu'à ces moments définis par l'utilisateur, ce qui garantit que les performances et la verbosité ne sont pas compromises. Cela permet une analyse plus ciblée et plus efficace de l'état de l'appareil à des moments précis. Les dumps suivants sont acceptés par Winscope :
- Gestionnaire de fenêtres : vider l'état d'un seul gestionnaire de fenêtres.
- SurfaceFlinger : vider un seul instantané SurfaceFlinger.
- Capture d'écran : collectez une capture d'écran en plus des dumps.
Ressources
Pour savoir comment compiler et exécuter Winscope, consultez Exécuter Winscope.
Pour en savoir plus sur la collecte des traces, consultez Capturer des traces.
Pour savoir comment charger des traces à l'aide de l'interface utilisateur Web Winscope, consultez Charger des traces.
Pour en savoir plus sur l'analyse des traces, consultez Analyser les traces.
Exemples
L'exemple suivant décrit comment déboguer un échec de test de scintillement et un bug signalé par un utilisateur.
Échec du test de scintillement
Cet exemple montre comment utiliser Winscope pour déboguer un échec de test de scintillement.
Examiner l'échec du test
Suivez ces étapes pour déterminer le type de problème et examiner le message d'échec du test.
Déterminez le type de problème en examinant le nom du test et de la classe.
Nom du test et du cours :
FlickerTestsNotification com.android.server.wm.flicker.notification.OpenAppFromLockscreenNotificationColdTest#appLayerBecomesVisible[ROTATION_0_GESTURAL_NAV]
Type de problème :
Le CUJ fait référence au lancement d'une application à partir d'une notification sur l'écran de verrouillage (
OpenAppFromLockscreenNotificationColdTest
).Le test s'attend à ce que l'application devienne visible (
#appLayerBecomesVisible
).
Examinez le message d'échec du test, qui fournit des informations complètes sur l'échec, y compris :
- Comparaison entre le résultat attendu et le résultat visible réel
- Codes temporels pour identifier le moment où l'échec s'est produit
- Nom de l'artefact ou du fichier associé à l'échec
- Informations contextuelles supplémentaires permettant de comprendre et de déboguer l'échec
android.tools.flicker.subject.exceptions.IncorrectVisibilityException: com.android.server.wm.flicker.testapp/com.android.server.wm.flicker.testapp.NotificationActivity# should be visible Where? Timestamp(UNIX=2024-05-10T11:04:14.227572545(1715339054227572545ns), UPTIME=37m21s184ms79178ns(2241184079178ns), ELAPSED=0ns) What? Expected: com.android.server.wm.flicker.testapp/com.android.server.wm.flicker.testapp.NotificationActivity# Actual: [e636ecd com.android.server.wm.flicker.testapp/com.android.server.wm.flicker.testapp.NotificationActivity#3457: Buffer is empty, Visible region calculated by Composition Engine is empty, com.android.server.wm.flicker.testapp/com.android.server.wm.flicker.testapp.NotificationActivity#3458: Visible region calculated by Composition Engine is empty] Other information Artifact: FAIL__OpenAppFromLockscreenNotificationColdTest_ROTATION_0_GESTURAL_NAV.zip Check the test run artifacts for trace files at android.tools.flicker.subject.layers.LayerTraceEntrySubject.isVisible(LayerTraceEntrySubject.kt:187) at android.tools.flicker.subject.layers.LayersTraceSubject$isVisible$1$1.invoke(LayersTraceSubject.kt:151) at android.tools.flicker.subject.layers.LayersTraceSubject$isVisible$1$1.invoke(LayersTraceSubject.kt:150) at android.tools.flicker.assertions.NamedAssertion.invoke(NamedAssertion.kt:32) at android.tools.flicker.assertions.CompoundAssertion.invoke(CompoundAssertion.kt:42) at android.tools.flicker.assertions.AssertionsChecker.test(AssertionsChecker.kt:79) at android.tools.flicker.subject.FlickerTraceSubject.forAllEntries(FlickerTraceSubject.kt:59) at android.tools.flicker.assertions.AssertionDataFactory$createTraceAssertion$closedAssertion$1.invoke(AssertionDataFactory.kt:46) at android.tools.flicker.assertions.AssertionDataFactory$createTraceAssertion$closedAssertion$1.invoke(AssertionDataFactory.kt:43) at android.tools.flicker.assertions.AssertionDataImpl.checkAssertion(AssertionDataImpl.kt:33) at android.tools.flicker.assertions.ReaderAssertionRunner.doRunAssertion(ReaderAssertionRunner.kt:35) at android.tools.flicker.assertions.ReaderAssertionRunner.runAssertion(ReaderAssertionRunner.kt:29) at android.tools.flicker.assertions.BaseAssertionRunner.runAssertion(BaseAssertionRunner.kt:36) at android.tools.flicker.legacy.LegacyFlickerTest.doProcess(LegacyFlickerTest.kt:59) at android.tools.flicker.assertions.BaseFlickerTest.assertLayers(BaseFlickerTest.kt:89) at com.android.server.wm.flicker.notification.OpenAppTransition.appLayerBecomesVisible_coldStart(OpenAppTransition.kt:51) at com.android.server.wm.flicker.notification.OpenAppFromNotificationColdTest.appLayerBecomesVisible(OpenAppFromNotificationColdTest.kt:64)
Cet exemple de résultat indique les éléments suivants :
Le problème se produit à
2024-05-10T11:04:14.227572545
.NotificationActivity
doit être visible, mais ne l'est pas.Le nom du fichier d'artefact contenant les traces de débogage est
FAIL__OpenAppFromLockscreenNotificationColdTest_ROTATION_0_GESTURAL_NAV
.
Déboguer
Pour déterminer la cause du scintillement, procédez comme suit :
Téléchargez les fichiers de trace et chargez-les dans Winscope. Winscope s'ouvre avec SurfaceFlinger sélectionné automatiquement :
Figure 1 : Page de destination Winscope avec vue SurfaceFlinger.
Accédez au code temporel où se produit le problème en copiant et en collant le code temporel du message d'exception dans le champ de code temporel. Vous pouvez copier l'horodatage au format lisible (
2024-05-10T11:04:14.227572545
) et le coller dans le premier champ, ou copier l'horodatage en nanosecondes (1715339054227572545ns
) et le coller dans le deuxième champ.Figure 2. Boîte de dialogue "Code temporel".
Appuyez sur la flèche vers la gauche pour accéder à la frame précédente. Dans cet état, l'application NotificationActivity s'affiche correctement dans la vidéo, et les surfaces de l'application et de l'écran de démarrage sont visibles, comme l'indiquent leurs rectangles verts dans la vue 3D et le chip V sur leurs éléments de hiérarchie.
Voici les noms des surfaces de l'application et de l'écran de démarrage :
com.android.server.wm.flicker.testapp/com.android.server.wm.flicker.testapp.NotificationActivity#3458` Splash Screen com.android.server.wm.flicker.testapp#3453
Cela indique que l'application était en cours de lancement lorsque l'écran est devenu noir et que cet événement se produit pendant le lancement de l'application, car l'écran de démarrage est toujours visible :
Figure 3. Au lancement de l'application.
Appuyez sur la flèche vers la droite pour revenir à la prochaine image où le scintillement se produit. Dans la vue des rectangles,
NotificationShade
s'affiche à l'écran au lieu de l'application. Les surfaces suivantes sont affichées dans ce frame :- Superpositions de décoration d'écran (en haut et en bas)
- Barre de navigation
Emplacement du pointeur (à partir de l'enregistrement de l'écran)
Figure 4. Activité de scintillement.
Sélectionnez l'activité de l'application dans la vue hiérarchique. Si vous ne le trouvez pas, désactivez l'option Afficher uniquement V, puis inspectez la vue des propriétés.
Le nom de la surface de l'application est le suivant :
com.android.server.wm.flicker.testapp/com.android.server.wm.flicker.testapp.NotificationActivity#3458`
Figure 5. Propriétés de l'application.
Bien que l'activité de l'application soit définie sur "visible" et "opaque", la surface n'est pas affichée en raison d'une erreur
Invisible due to: null visible region
. Cela se produit parce qu'une autre surface opaque a été placée devant lors de la composition. Cette hypothèse découle du fait que le rectangleNotificationShade
se trouve devant le rectangleNotificationActivity
dans la vue 3D, et que le rectangleNotificationShade
visible (en vert) est potentiellement le calque choisi.Pour valider cette hypothèse, sélectionnez la surface
NotificationShade
visible dans le frame actuel et vérifiez ses propriétés. Les indicateurs sont définis surOPAQUE|ENABLE_BACKPRESSURE (0x102)
. Le nom de la surfaceNotificationShade
estNotificationShade#3447
. Appuyez ensuite sur la flèche vers la gauche pour revenir à l'image précédente (avant le scintillement) et inspecter à nouveau les propriétés de la surfaceNotificationShade
. Notez qu'au lieu d'êtreOPAQUE
, la surface ne comporte que l'indicateurENABLE_BACKPRESSURE (0x100)
. Cela confirme queNotificationShade
devient opaque avant que le lancement de l'application ne soit complètement terminé. CommeNotificationShade
se trouve devantNotificationActivity
, l'application n'est pas affichée. LeNotificationShade
est noir, donc l'écran devient brièvement noir, ce qui provoque le scintillement.Identifiez dans le code pourquoi
NotificationShade
devient opaque trop tôt.
Bug signalé par un utilisateur
Il peut être difficile de déboguer les bugs signalés par les utilisateurs, car ils manquent souvent d'informations détaillées. Contrairement aux échecs des tests de scintillement, qui fournissent des codes temporels spécifiques, des détails sur les éléments et des enregistrements d'écran, les bugs signalés par les utilisateurs n'incluent généralement qu'une brève description du problème.
Dans notre étude de cas, les seules informations fournies sont le titre L'écran a clignoté lors de la réouverture de l'application en mode écran partagé et un code temporel approximatif 18 avr. 2024 à 15:51 GMT-04:00.
Pour déboguer un bug signalé par un utilisateur, procédez comme suit :
Chargez le fichier de trace dans Winscope. Winscope s'ouvre avec SurfaceFlinger automatiquement sélectionné.
Figure 6. Page de destination Winscope avec vue SurfaceFlinger.
Accédez à l'horodatage approximatif signalé par l'utilisateur, ici
3:50 PM GMT-04:00
, en saisissant15:50:00
dans le champ de l'horodatage au format lisible.Figure 7. Boîte de dialogue "Code temporel".
Utilisez la vue "Rects" pour identifier ce qui a été dessiné à l'écran. Pour une meilleure vue, utilisez le curseur Rotation afin de modifier la perspective des rectangles. En cochant les options Afficher uniquement V et Plat dans la vue Hiérarchie, les surfaces fond d'écran, superposition de décoration d'écran, letterbox, lanceur d'applications, contacts et clavier de numérotation sont visibles.
Voici les noms des packages :
Lanceur d'applications :
com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity#40602
Contacts :
com.google.android.contacts/com.android.contacts.activities.PeopleActivity#40565
Application Téléphone :
com.google.android.dialer/com.google.android.dialer.extensions.GoogleDialtactsActivity#40564
En plus des surfaces visibles (rectangles verts), un rectangle gris représentant la surface de la zone d'affichage, nommé Unknown display (Affichage inconnu), s'affiche. Pour améliorer la visibilité, cliquez sur (
) à côté de la surface
ScreenDecorHwcOverlay#64
pour masquer le rectangle correspondant et afficher les surfaces situées derrière. Nous supprimons le calque de l'analyse, car il n'est pas visible par l'utilisateur et ne serait pas signalé comme une animation clignotante.Figure 8. Rapport utilisateur
Une fois que vous avez identifié les surfaces impliquées dans la vue en écran partagé, utilisez la trace des transitions pour parcourir les différentes actions de l'utilisateur et trouver le scintillement. Cliquez sur l'onglet Transitions dans Winscope pour visualiser la liste des transitions lues :
Figure 9. Transitions.
La transition lue pendant cette image est mise en évidence en bleu. Dans ce cas, les indicateurs de transition incluent
TRANSIT_FLAG_IS_RECENTS
, qui indique que l'utilisateur accède à l'écran "Récents".Cliquez sur le lien dans la colonne Heure d'envoi (
2024-04-18, 15:50:57.205
dans le cas présent) pour accéder à ce point temporel et vérifier les rects dans l'onglet Surface Flinger. Vérifiez que l'état de l'appareil est correct pendant la transition en parcourant la transition avec la touche flèche vers la droite et en observant les rectangles.Le lanceur d'applications apparaît à 15:50:57.278, mais l'animation ne démarre pas à ce moment-là. Le fond d'écran est déjà visible, car rien n'est dessiné entre les applications en écran partagé (séparateur). Une frame plus tôt (15:50:57.212), le fond d'écran n'est pas visible et le séparateur s'affiche, ce qui correspond à l'apparence de l'écran partagé lorsqu'il n'est pas animé.
Figure 10. Écran avant l'événement de scintillement.
Pour consulter la transition suivante, cliquez directement sur la timeline. Les états SurfaceFlinger sont représentés par une rangée de blocs bleu clair. Les transitions sont représentées par une rangée de blocs roses.
Figure 11 : Fin de la première transition.
Cliquez sur la ligne SurfaceFlinger au début de la transition suivante. Dans la figure 11, la position verticale du curseur est indiquée par la fine ligne bleue. L'arrière-plan bleu clair de la ligne SurfaceFlinger indique sa position horizontale. Parcourez la transition à l'aide de la touche fléchée vers la droite pour voir si un scintillement se produit. Vérifiez que l'appareil semble correct pour cette transition.
Ignorez la transition suivante, car sa durée est très courte et il est donc peu probable qu'elle contienne un scintillement. Cliquez plutôt sur la timeline dans la ligne SurfaceFlinger, au début de la transition plus longue suivante, comme indiqué par le curseur dans l'image ci-dessous.
Figure 12. Fin de la deuxième transition.
Pendant cette transition, à
15:51:13.239
, notez que les calquesSplash Screen
des deux applications, des contacts et du clavier téléphonique se trouvent du même côté de l'écran :Figure 13. Écrans de démarrage
Précisez quelle application se trouve du mauvais côté. Ajoutez un repère à votre position actuelle en cliquant sur l'icône en forme de drapeau à côté du champ de saisie ns pour vous aider à revenir à ce frame plus tard.
Figure 14. Ajouter un favori.
Accédez à un frame à la fin de la transition en cliquant directement sur la timeline, par exemple sur
15:51:13.859
. Ici, les deux applications sont maintenant dans leur position finale, avec le clavier de numérotation à gauche et les contacts à droite :Figure 15. Écran partagé final.
Cliquez sur le repère dans la timeline pour revenir à la frame où le scintillement se produit.
Figure 16. Ajouter un repère à la timeline.
Les deux applications se trouvent à droite, ce qui indique que le sélecteur est dans la mauvaise position.
Cliquez sur l'écran de démarrage du sélecteur pour afficher ses propriétés. Examinez plus précisément ses propriétés de transformation dans la vue Propriétés.
Figure 17. Propriétés de transformation.
La transformation calculée est appliquée à cette surface, mais n'est pas définie à ce niveau. Les colonnes "Calculé" et "Demandé" ont des valeurs différentes, ce qui indique que la transformation est héritée d'une surface parente.
Désélectionnez Plat dans la vue hiérarchique pour afficher l'intégralité de l'arborescence hiérarchique, puis accédez aux nœuds parents de la surface de l'application jusqu'à ce que les transformations Calculé et Demandé soient identiques, ce qui indique que la transformation est demandée sur la surface
Surface(name=Task=7934)/@0x1941191_transition-leash#40670
.Vérifiez la date à laquelle la transformation a été définie pour la première fois et la valeur qui lui a été attribuée. Réduisez les propriétés sélectionnées en cliquant sur l'icône à côté du titre :
Figure 18. Réduisez les propriétés sélectionnées.
Sélectionnez Afficher le différentiel dans la vue Proto Dump pour mettre en évidence les propriétés qui sont modifiées dans ce frame. Saisissez
transform
dans le champ de recherche de texte pour filtrer les propriétés :Figure 19. Afficher les différences
La transformation est définie de
IDENTITY
àSCALE|TRANSLATE|ROT_270
dans ce frame pourtransition-leash
.Ces informations montrent que le scintillement s'est produit lorsque la transformation a été appliquée à la laisse d'animation de l'application d'écran partagé du clavier de numérotation.
Figure 20. Identification du scintillement.
Identifiez dans le code pourquoi cette transformation est définie sur la laisse de transition en écran partagé.