Winscope est un outil Web qui permet aux utilisateurs d'enregistrer, de lire 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 suivi. 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 grande lisibilité. Les traces suivantes sont compatibles avec Winscope:
- EventLog:collecte 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 repères CUJ. - IME:tracez les événements du pipeline de l'éditeur de mode de saisie (IME), y compris IMS, IMMS et le client IME.
- Entrée:permet de suivre les événements d'entrée à partir de différentes parties du pipeline d'événements d'entrée.
- ProtoLog:collecte les messages ProtoLog des services système et le 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 de shell:enregistre les détails du système de transition de fenêtre et d'activité.
- SurfaceFlinger:collecte des traces SurfaceFlinger contenant des informations sur les surfaces (couches), telles que la position, le tampon et la composition.
- Transactions:permet de suivre l'ensemble des modifications atomiques reçues par SurfaceFlinger à l'aide de
SurfaceControl
pour la composition. - ViewCapture:capture une plage de propriétés de toutes les vues à partir des fenêtres système compatibles avec ViewCapture, comme l'UI système et le lanceur.
- Gestionnaire de fenêtres:tracez les états du 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 vidages 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 affecter les performances, les vidages 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 efficace de l'état de l'appareil à des moments spécifiques. Les fichiers de dump suivants sont compatibles avec Winscope:
- Gestionnaire de fenêtres:vidage d'un seul état de gestionnaire de fenêtres.
- SurfaceFlinger:vidage d'un seul instantané SurfaceFlinger.
- Capture d'écran:collectez une capture d'écran avec les vidages.
Ressources
Pour en savoir plus sur la création et l'exécution de Winscope, consultez Exécuter Winscope.
Pour en savoir plus sur la collecte de traces, consultez la section 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 clignotement et un bug signalé par un utilisateur.
Échec du test de clignotement
Cet exemple montre comment utiliser Winscope pour déboguer un échec de test de clignotement.
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 de la classe:
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 de 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 les éléments suivants:
- Comparaison entre le résultat attendu et le résultat visible
- Horodatages pour vous aider à identifier le moment où l'échec s'est produit
- Nom de l'artefact ou du fichier associé à l'échec
- Informations contextuelles supplémentaires utiles pour comprendre et 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 sortie indique ce qui suit:
Le problème se produit à
2024-05-10T11:04:14.227572545
.NotificationActivity
devrait être visible, mais il 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 à l'origine du 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 de code temporel.
Appuyez sur la flèche vers la gauche pour accéder au frame précédent. Dans cet état, l'application NotificationActivity s'affiche correctement dans la vidéo. Les surfaces de l'application et de l'écran de démarrage sont visibles, comme indiqué par leurs rectangles verts dans la vue 3D et le chip V sur leurs éléments de hiérarchie.
Les noms des surfaces de l'application et de l'écran de démarrage sont les suivants:
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 démarrage de l'application.
Appuyez sur la flèche vers la droite pour revenir au frame suivant, où le scintillement se produit. Dans la vue des rectangles, le
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 d'écran)
Figure 4. Activité de scintillement.
Sélectionnez l'activité de l'application dans la vue hiérarchique. Si vous ne la 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 elle 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 leNotificationShade
visible (vert) est potentiellement la couche choisie.Pour valider cette hypothèse, sélectionnez la surface
NotificationShade
visible sur 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 de gauche pour revenir au frame précédent (avant le clignotement) et inspectez à 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é. Étant donné queNotificationShade
se trouve devantNotificationActivity
, l'application ne s'affiche pas.NotificationShade
est noir, donc l'écran passe brièvement au noir, ce qui provoque le scintillement.Identifiez dans le code pourquoi
NotificationShade
devient opaque trop tôt.
Bug signalé par l'utilisateur
Les bugs signalés par les utilisateurs peuvent être difficiles à déboguer, car ils manquent souvent d'informations détaillées. Contrairement aux échecs de test de clignotement, qui fournissent des codes temporels, des détails sur les éléments et des enregistrements d'écran spécifiques, 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, la seule information fournie est le titre Écran clignotant lors de la réouverture de l'application depuis l'écran partagé et un code temporel approximatif de 18 avril 2024 15h51 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 sélectionné automatiquement.
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 d'horodatage lisible par l'homme.Figure 7. Boîte de dialogue de code temporel.
Utilisez la vue rects pour identifier ce qui a été dessiné à l'écran. Pour une meilleure vue, utilisez le curseur Rotation pour modifier la perspective des rectangles. En cochant Afficher uniquement V et Plat dans la vue Hiérarchie, le fond d'écran, la superposition de décoration d'écran, le format letterbox, le lanceur, les surfaces de contacts et le clavier sont visibles.
Les noms des packages sont les suivants:
Lanceur:
com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity#40602
Contacts :
com.google.android.contacts/com.android.contacts.activities.PeopleActivity#40565
Numéroteur:
com.google.android.dialer/com.google.android.dialer.extensions.GoogleDialtactsActivity#40564
En plus des surfaces visibles (rectangles verts), un rectangle gris, qui représente la surface de la zone d'affichage, nommé Écran 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 derrière. Nous supprimons la superposition pour l'analyse, car elle n'est pas visible par l'utilisateur et ne sera pas signalée comme une animation clignotante.Figure 8. Rapport "Utilisateur".
Après avoir identifié les surfaces impliquées dans l'affichage en écran partagé, utilisez la trace des transitions pour passer en revue les différentes actions de l'utilisateur et trouver le scintillement. Cliquez sur l'onglet Transitions dans Winscope pour afficher la liste des transitions jouées:
Figure 9. Transitions.
La transition lue pendant ce frame est mise en surbrillance en bleu. Dans ce cas, les indicateurs de transition incluent
TRANSIT_FLAG_IS_RECENTS
, ce qui indique que l'utilisateur accède à l'écran "Recents" (Éléments récents).Cliquez sur le lien dans la colonne Heure de distribution (
2024-04-18, 15:50:57.205
dans ce cas) pour accéder à ce moment et vérifier les rectangles dans l'onglet Surface Flinger. Vérifiez que l'état de l'appareil est correct pendant la transition en parcourant la transition à l'aide de la touche fléchée vers la droite et en observant les rectangles.Le lanceur d'applications s'affiche à 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 mode écran partagé (séparateur). Une image plus tôt (15:50:57.212), le fond d'écran n'est pas visible et le séparateur est affiché, ce qui correspond à l'apparence de l'écran partagé lorsqu'il n'est pas animé.
Figure 10. Écran avant l'événement de clignotement.
Pour consulter la prochaine transition, cliquez directement sur la chronologie. Les états de SurfaceFlinger sont représentés par une ligne de blocs bleu clair. Les transitions sont représentées par une ligne de blocs roses.
Figure 11 : Fin de la première transition.
Cliquez sur la ligne SurfaceFlinger à la position de début de la prochaine transition. 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. Passez en revue 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 est adapté à cette transition.
Ignorez la transition suivante, car sa durée est très courte et qu'elle est donc peu susceptible de contenir un clignotement. Cliquez plutôt sur la timeline dans la ligne SurfaceFlinger à la position de début de la prochaine transition plus longue, comme indiqué par le curseur dans l'image suivante.
Figure 12. Fin de la deuxième transition.
Au cours de cette transition, à
15:51:13.239
, observez que les calquesSplash Screen
des deux applications, des contacts et du clavier se trouvent du même côté de l'écran:Figure 13. Écrans de démarrage
Indiquez l'application qui se trouve du mauvais côté. Ajoutez un favori à votre position actuelle en cliquant sur l'icône en forme de drapeau à côté du champ de saisie ns pour revenir plus tard à ce cadre.
Figure 14. Ajoutez un favori.
Accédez à un frame à la fin de la transition en cliquant directement sur la timeline, par exemple sur
15:51:13.859
. Les deux applications sont maintenant dans leur position finale, avec le clavier à gauche et les contacts à droite:Figure 15. Écran partagé final.
Cliquez sur l'icône du repère dans la chronologie pour revenir au frame avec le scintillement.
Figure 16. Chronologie des favoris.
Les deux applications se trouvent à droite, ce qui indique que le clavier est mal positionné.
Cliquez sur l'écran de démarrage du clavier pour afficher ses propriétés. Examinez spécifiquement ses propriétés de transformation dans la vue Propriétés sélectionnée.
Figure 17. Propriétés de transformation.
La transformation calculée est appliquée à cette surface, mais n'est pas définie comme ce niveau. Les colonnes calculées et demandées ont des valeurs différentes, ce qui indique que la transformation est héritée d'une surface parente.
Désélectionnez Flat (Plat) dans la vue de hiérarchie pour afficher l'ensemble de l'arborescence de la hiérarchie, puis accédez aux nœuds parents de la surface de l'application jusqu'à ce que les transformations Calculated (Calculées) et Requested (Requêtées) soient identiques, ce qui indique que la transformation est requise sur la surface
Surface(name=Task=7934)/@0x1941191_transition-leash#40670
.Vérifiez quand la transformation a été définie pour la première fois et à quelle valeur. Réduisez les propriétés sélectionnées en cliquant sur l'icône à côté du titre:
Figure 18. Réduire les propriétés sélectionnées
Sélectionnez Afficher le différentiel dans la vue Proto Dump pour mettre en surbrillance les propriétés modifiées dans ce frame. Saisissez
transform
dans le champ de recherche textuelle pour filtrer les propriétés:Figure 19. Afficher le différentiel.
La transformation est définie de
IDENTITY
àSCALE|TRANSLATE|ROT_270
dans ce frame pour letransition-leash
.Ces informations montrent que le scintillement s'est produit lorsque la transformation a été appliquée à la laisse d'animation de l'application du clavier en mode écran partagé.
Figure 20. Identification du scintillement.
Identifiez dans le code pourquoi cette transformation est définie sur la laisse de transition en écran partagé.