Winscope è uno strumento web che consente agli utenti di registrare, riprodurre e analizzare gli stati di diversi servizi di sistema durante e dopo animazioni e transizioni. Winscope registra tutti gli stati dei servizi di sistema pertinenti in un file di traccia. Utilizzando la UI di Winscope con il file di traccia, puoi esaminare lo stato di questi servizi per ogni frame di animazione, con o senza una registrazione dello schermo, riproducendo, eseguendo il debug e passando da una transizione all'altra.
Tracce supportate
Winscope consente di raccogliere e rappresentare visivamente varie tracce o sequenze di stati dei servizi di sistema. Puoi configurare queste tracce in base a casi d'uso specifici, che vanno da un basso overhead a un'elevata verbosità. Le seguenti tracce sono supportate da Winscope:
- EventLog: raccogli il record dell'evento di diagnostica del sistema utilizzando
EventLog
. In Winscope queste informazioni vengono utilizzate solo per identificare e visualizzare i segni CUJ. - IME:traccia gli eventi dalla pipeline dell'Input Method Editor (IME), inclusi IMS, IMMS e client IME.
- Input:traccia gli eventi di input da varie parti della pipeline di eventi di input.
- ProtoLog: raccogli i messaggi ProtoLog dai servizi di sistema e il codice dei servizi di sistema in esecuzione nei processi client.
- Registrazione dello schermo:raccogli una registrazione dello schermo insieme alle tracce.
- Transizioni della shell:registra i dettagli di sistema relativi alle transizioni di finestre e attività.
- SurfaceFlinger:raccogli trace di SurfaceFlinger contenenti informazioni sulle superfici (livelli) come posizione, buffer e composizione.
- Transazioni:traccia l'insieme di modifiche atomiche ricevute da SurfaceFlinger
utilizzando
SurfaceControl
per la composizione. - ViewCapture:acquisisci una serie di proprietà di tutte le visualizzazioni dalle finestre di sistema che supportano ViewCapture, come l'interfaccia utente di sistema e il launcher.
- Window Manager: traccia Window Manager stati contenenti dettagli relativi alle finestre, inclusi eventi di input e messa a fuoco, orientamento dello schermo, transizioni, animazioni, posizionamento e trasformazioni.
Dump supportati
Winscope può raccogliere e visualizzare i dump di stato, ovvero snapshot dello stato del dispositivo acquisiti in momenti specifici definiti dall'utente. A differenza delle tracce, che vengono raccolte continuamente durante l'utilizzo del dispositivo e possono influire sulle prestazioni, i dump vengono eseguiti solo in questi momenti definiti dall'utente, garantendo che le prestazioni e la verbosità non vengano compromesse. Ciò consente un'analisi più mirata ed efficiente dello stato del dispositivo in momenti specifici. I seguenti dump sono supportati da Winscope:
- Window Manager:esegui il dump di un singolo stato di Window Manager.
- SurfaceFlinger:scarica un singolo snapshot di SurfaceFlinger.
- Screenshot: raccogli uno screenshot insieme ai dump.
Risorse
Per informazioni sulla creazione e l'esecuzione di Winscope, consulta Esegui Winscope.
Consulta Acquisire tracce per informazioni sulla raccolta delle tracce.
Consulta Carica tracce per informazioni su come caricare le tracce utilizzando l'interfaccia utente web di Winscope.
Consulta Analizzare le tracce per informazioni sull'analisi delle tracce.
Esempi
Il seguente esempio descrive come eseguire il debug di un test di sfarfallio non riuscito e di un bug segnalato dall'utente.
Test dello sfarfallio non riuscito
Questo esempio mostra come utilizzare Winscope per eseguire il debug di un errore del test di sfarfallio.
Esamina il test non riuscito
Segui questi passaggi per determinare il tipo di problema ed esaminare il messaggio di errore del test.
Determina il tipo di problema esaminando il test e il nome della classe.
Nome del test e del corso:
FlickerTestsNotification com.android.server.wm.flicker.notification.OpenAppFromLockscreenNotificationColdTest#appLayerBecomesVisible[ROTATION_0_GESTURAL_NAV]
Tipo di problema:
Il CUJ si riferisce all'avvio di un'app da una notifica della schermata di blocco (
OpenAppFromLockscreenNotificationColdTest
).Il test prevede che l'app diventi visibile (
#appLayerBecomesVisible
).
Esamina il messaggio di errore del test, che fornisce informazioni complete sull'errore, tra cui:
- Un confronto tra il risultato previsto e quello effettivamente visibile
- Timestamp per individuare il momento in cui si è verificato l'errore
- Il nome dell'artefatto o del file associato all'errore
- Ulteriori informazioni contestuali utili per comprendere ed eseguire il debug dell'errore
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)
Questo esempio di output indica quanto segue:
Il problema si verifica alle ore
2024-05-10T11:04:14.227572545
.NotificationActivity
dovrebbe essere visibile, ma non lo è.Il nome del file artefatto che contiene le tracce per il debug è
FAIL__OpenAppFromLockscreenNotificationColdTest_ROTATION_0_GESTURAL_NAV
.
Debug
Segui questi passaggi per determinare la causa dello sfarfallio:
Scarica i file di traccia e caricali in Winscope. Winscope si apre con SurfaceFlinger selezionato automaticamente:
Figura 1. Pagina di destinazione di Winscope con la visualizzazione di SurfaceFlinger.
Vai al timestamp in cui si verifica il problema copiando e incollando il timestamp del messaggio di eccezione nel campo del timestamp. Puoi copiare il timestamp in formato leggibile (
2024-05-10T11:04:14.227572545
) e incollarlo nel primo campo oppure copiare il timestamp in nanosecondi (1715339054227572545ns
) e incollarlo nel secondo campo.Figura 2. Finestra di dialogo Timestamp.
Premi il tasto Freccia sinistra per passare al frame precedente. In questo stato, l'app NotificationActivity viene visualizzata correttamente nel video e sia l'app che le superfici della schermata iniziale sono visibili, indicate dai rettangoli verdi nella visualizzazione 3D e dal chip V nei relativi elementi della gerarchia.
I nomi delle superfici dell'app e della schermata iniziale sono:
com.android.server.wm.flicker.testapp/com.android.server.wm.flicker.testapp.NotificationActivity#3458` Splash Screen com.android.server.wm.flicker.testapp#3453
Ciò indica che l'app era in fase di avvio quando lo schermo è diventato nero e che questo evento si verifica durante l'avvio dell'app, poiché la schermata iniziale è ancora visibile:
Figura 3. All'avvio dell'app.
Premi il tasto Freccia destra per tornare al fotogramma successivo, in cui si verifica lo sfarfallio. Nella visualizzazione dei rettangoli, sullo schermo viene visualizzato
NotificationShade
anziché l'app. In questo frame vengono mostrate le seguenti superfici:- Overlay decorativi per lo schermo (in alto e in basso)
- Barra di navigazione
Posizione del puntatore (dalla registrazione dello schermo)
Figura 4. Attività di sfarfallio.
Seleziona l'attività dell'app nella visualizzazione gerarchica. Se non riesci a trovarlo, disattiva Mostra solo V. Quindi, esamina la visualizzazione delle proprietà.
Il nome della superficie dell'app è:
com.android.server.wm.flicker.testapp/com.android.server.wm.flicker.testapp.NotificationActivity#3458`
Figura 5. Proprietà dell'app.
Sebbene l'attività dell'app sia impostata su visibile e opaca, la superficie non viene mostrata a causa di un errore
Invisible due to: null visible region
. Ciò si verifica perché durante la composizione è stata posizionata un'altra superficie opaca davanti. Questa ipotesi deriva dal fatto che il rettangoloNotificationShade
si trova davanti al rettangoloNotificationActivity
nella visualizzazione 3D e che il rettangoloNotificationShade
visibile (verde) potrebbe essere il livello scelto.Per convalidare questa ipotesi, seleziona la superficie
NotificationShade
visibile nel frame corrente e controllane le proprietà. I flag sono impostati suOPAQUE|ENABLE_BACKPRESSURE (0x102)
. Il nome della superficieNotificationShade
èNotificationShade#3447
. Poi, premi la freccia sinistra per tornare al frame precedente (prima dello sfarfallio) e ispeziona di nuovo le proprietà della superficieNotificationShade
. Nota che anziché essereOPAQUE
, la superficie ha solo il flagENABLE_BACKPRESSURE (0x100)
. Ciò conferma cheNotificationShade
diventa opaco prima dell'avvio dell'app completamente terminato. PoichéNotificationShade
si trova davanti aNotificationActivity
, l'app non viene mostrata. IlNotificationShade
è nero, quindi lo schermo diventa nero per un attimo, causando lo sfarfallio.Identifica nel codice il motivo per cui
NotificationShade
diventa opaco troppo presto.
Bug segnalato dall'utente
Il debug dei bug segnalati dagli utenti può essere difficile perché spesso mancano informazioni dettagliate. A differenza degli errori del test di sfarfallio, che forniscono timestamp specifici, dettagli degli elementi e registrazioni dello schermo, i bug segnalati dagli utenti in genere includono solo una breve descrizione del problema.
Nel nostro caso di studio, le uniche informazioni fornite sono il titolo Lo schermo ha sfarfallato quando ho riaperto l'app dallo schermo diviso e un timestamp approssimativo di 18 aprile 2024 15:51 GMT-04:00.
Per eseguire il debug di un bug segnalato da un utente:
Carica il file di traccia in Winscope. Winscope si apre con SurfaceFlinger selezionato automaticamente.
Figura 6. Pagina di destinazione di Winscope con la visualizzazione di SurfaceFlinger.
Vai al timestamp approssimativo segnalato dall'utente, in questo caso
3:50 PM GMT-04:00
, inserendo15:50:00
nel campo timestamp leggibile.Figura 7. Finestra di dialogo Timestamp.
Utilizza la visualizzazione Rettangoli per identificare cosa è stato disegnato sullo schermo. Per una visualizzazione migliore, utilizza il cursore Rotazione per modificare la prospettiva dei rettangoli. Se selezioni Mostra solo V e Piatto nella visualizzazione Gerarchia, lo sfondo, la sovrapposizione di decorazione dello schermo, il letterbox, il launcher, i contatti e le superfici del tastierino sono visibili.
I nomi dei pacchetti sono:
Avvio app:
com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity#40602
Contatti:
com.google.android.contacts/com.android.contacts.activities.PeopleActivity#40565
Tastierino:
com.google.android.dialer/com.google.android.dialer.extensions.GoogleDialtactsActivity#40564
Oltre alle superfici visibili (rettangoli verdi), viene visualizzato un rettangolo grigio che rappresenta la superficie dell'area di visualizzazione, denominata Display sconosciuto. Per migliorare la visibilità, fai clic su (
) accanto alla superficie
ScreenDecorHwcOverlay#64
per nascondere il rettangolo corrispondente e rivelare le superfici sottostanti. Rimuoviamo l'overlay per l'analisi perché non è visibile all'utente e non verrebbe segnalato come animazione tremolante.Figura 8. Report utente.
Dopo aver identificato le superfici coinvolte nella visualizzazione a schermo diviso, utilizza la traccia Transizioni per esaminare le varie azioni dell'utente e trovare lo sfarfallio. Fai clic sulla scheda Transizioni in Winscope per visualizzare l'elenco delle transizioni riprodotte:
Figura 9. Transizioni.
La transizione riprodotta durante questo frame è evidenziata in blu. In questo caso, i flag di transizione includono
TRANSIT_FLAG_IS_RECENTS
, che indica che l'utente sta accedendo alla schermata Recenti.Fai clic sul link nella colonna Ora di invio (in questo caso
2024-04-18, 15:50:57.205
) per passare a quel momento e verificare i rettangoli nella scheda Surface Flinger. Verifica la correttezza dello stato del dispositivo durante la transizione scorrendo la transizione con il tasto freccia destra e osservando i rettangoli.L'avvio app viene visualizzato alle 15:50:57.278, ma l'animazione non inizia in quel momento. Lo sfondo è già visibile perché non viene disegnato nulla tra le app in modalità Split Screen (divisore). Un fotogramma prima (15:50:57.212), lo sfondo non è visibile e viene mostrato il divisore, che è l'aspetto della schermata divisa quando non è in animazione.
Figura 10. Schermo prima dell'evento di sfarfallio.
Per visualizzare la transizione successiva, fai clic direttamente sulla cronologia. Gli stati di SurfaceFlinger sono rappresentati da una riga di blocchi azzurri. Le transizioni sono rappresentate da una riga di blocchi rosa.
Figura 11. Fine della prima transizione.
Fai clic sulla riga SurfaceFlinger nella posizione iniziale della transizione successiva. Nella Figura 11, la posizione verticale del cursore è indicata dalla sottile linea blu. Lo sfondo azzurro chiaro della riga SurfaceFlinger mostra la sua posizione orizzontale. Avanza nella transizione con il tasto Freccia destra per verificare se si verifica uno sfarfallio. Verifica che il dispositivo sia corretto per questa transizione.
Salta la transizione successiva perché la sua durata è molto breve, quindi è improbabile che contenga uno sfarfallio. Fai invece clic sulla sequenza temporale nella riga SurfaceFlinger nella posizione iniziale della transizione più lunga successiva, come indicato dal cursore nell'immagine seguente.
Figura 12. Fine della seconda transizione.
Durante questa transizione, a
15:51:13.239
, osserva che i livelliSplash Screen
per entrambe le app, i contatti e il tastierino, si trovano sullo stesso lato del display:Figura 13. Schermate iniziali.
Specifica quale app si trova sul lato sbagliato. Aggiungi un segnalibro alla tua posizione attuale facendo clic sull'icona del flag accanto al campo di input ns, per aiutarti a tornare a questo frame in un secondo momento.
Figura 14. Aggiungi segnalibro.
Passa a un frame alla fine della transizione facendo clic direttamente sulla sequenza temporale, ad esempio per
15:51:13.859
. Ora le due app si trovano nella posizione finale, con il tastierino a sinistra e i contatti a destra:Figura 15. Schermo diviso finale.
Fai clic sul segnalibro nella sequenza temporale per tornare al fotogramma con lo sfarfallio.
Figura 16. Cronologia dei segnalibri.
Entrambe le app si trovano a destra, il che indica che il tastierino si trova nella posizione errata.
Fai clic sulla schermata iniziale del dialer per visualizzarne le proprietà. Esamina in particolare le proprietà di trasformazione nella visualizzazione Proprietà curata.
Figura 17. Proprietà di trasformazione.
La trasformazione calcolata viene applicata a questa superficie, ma non impostata a questo livello. Le colonne calcolate e richieste hanno valori diversi, il che indica che la trasformazione viene ereditata da una superficie principale.
Deseleziona Piattina nella visualizzazione gerarchica per mostrare l'intera struttura ad albero della gerarchia e vai ai nodi principali della superficie dell'app finché le trasformazioni Calcolata e Richiesta non sono uguali, mostrando la trasformazione richiesta sulla superficie
Surface(name=Task=7934)/@0x1941191_transition-leash#40670
.Conferma quando è stata impostata la trasformazione per la prima volta e a quale valore. Comprimi le proprietà curate facendo clic sull'icona accanto al titolo:
Figura 18. Comprimi le proprietà selezionate.
Seleziona Mostra diff nella visualizzazione Proto Dump per evidenziare le proprietà che vengono modificate in questo frame. Digita
transform
nel campo di ricerca di testo per filtrare le proprietà:Figura 19. Mostra diff.
La trasformazione è impostata da
IDENTITY
aSCALE|TRANSLATE|ROT_270
in questo frame pertransition-leash
.Queste informazioni mostrano che lo sfarfallio si è verificato quando la trasformazione è stata applicata al guinzaglio dell'animazione dell'app di divisione dello schermo del dialer.
Figura 20. Identificazione dello sfarfallio.
Identifica nel codice il motivo per cui questa trasformazione è impostata sulla transizione dello schermo diviso.