Śledzenie przejść między oknami za pomocą narzędzia Winscope

Winscope to narzędzie internetowe, które umożliwia użytkownikom nagrywanie, odtwarzanie i analizowanie stanów kilku usług systemowych podczas animacji i przejść oraz po ich zakończeniu. Winscope rejestruje wszystkie istotne stany usług systemowych w pliku śledzenia. Korzystając z interfejsu Winscope i pliku śledzenia, możesz sprawdzić stan tych usług dla każdej klatki animacji, z nagraniem ekranu lub bez niego, odtwarzając, przeglądając i debugując przejścia.

Obsługiwane ślady

Winscope umożliwia zbieranie i wizualne przedstawianie różnych śladów lub sekwencji stanów usług systemowych. Możesz skonfigurować te ślady tak, aby pasowały do konkretnych przypadków użycia, od niskiego obciążenia po wysoką szczegółowość. Winscope obsługuje te ślady:

  • EventLog: zbierz rekord zdarzenia diagnostycznego systemu za pomocą polecenia EventLog. W Winscope te informacje są używane tylko do identyfikowania i wyświetlania oznaczeń CUJ.
  • IME: śledź zdarzenia z potoku edytora metody wprowadzania (IME), w tym IMS, IMMS i klienta IME.
  • Dane wejściowe: śledzenie zdarzeń wejściowych z różnych części potoku zdarzeń wejściowych.
  • ProtoLog: zbieranie komunikatów ProtoLog z usług systemowych i kodu usług systemowych działających w procesach klienta.
  • Nagrywanie ekranu: zbieraj nagrania ekranu wraz ze śladami.
  • Przejścia powłoki: rejestruje szczegóły systemowe dotyczące przejść między oknami i aktywnościami.
  • SurfaceFlinger: zbieraj ślady SurfaceFlinger zawierające informacje o powierzchniach (warstwach), takie jak pozycja, bufor i kompozycja.
  • Transakcje: śledź zestaw atomowych zmian otrzymanych przez SurfaceFlinger za pomocą SurfaceControl do kompozycji.
  • ViewCapture: przechwytuje zakres właściwości wszystkich widoków z systemu Windows, które obsługują ViewCapture, np. interfejs systemu i program uruchamiający.
  • Menedżer okien: ślady Menedżera okien zawierające szczegóły dotyczące okien, w tym zdarzenia wejścia i skupienia, orientację ekranu, przejścia, animacje, pozycjonowanie i przekształcenia.

Obsługiwane zrzuty

Winscope może zbierać i wyświetlać zrzuty stanu, czyli migawki stanu urządzenia wykonane w określonych momentach zdefiniowanych przez użytkownika. W przeciwieństwie do śladów, które są zbierane w sposób ciągły podczas korzystania z urządzenia i mogą wpływać na wydajność, zrzuty są wykonywane tylko w tych momentach określonych przez użytkownika, co zapewnia, że wydajność i szczegółowość nie są zagrożone. Umożliwia to bardziej ukierunkowaną i wydajną analizę stanu urządzenia w określonych momentach. Winscope obsługuje te zrzuty:

  • Menedżer okien: zrzut stanu pojedynczego menedżera okien.
  • SurfaceFlinger: zrzut pojedynczego zrzutu SurfaceFlinger.
  • Zrzut ekranu: zbieranie zrzutu ekranu wraz z dumpami.

Materiały

Informacje o kompilowaniu i uruchamianiu Winscope znajdziesz w artykule Uruchamianie Winscope.

Informacje o zbieraniu śladów znajdziesz w artykule Przechwytywanie śladów.

Informacje o wczytywaniu śladów za pomocą interfejsu internetowego Winscope znajdziesz w sekcji Wczytywanie śladów.

Więcej informacji o analizowaniu śladów znajdziesz w artykule Analizowanie śladów.

Przykłady

Poniższy przykład pokazuje, jak debugować błąd testu migotania i błąd zgłoszony przez użytkownika.

Niepowodzenie testu migotania

Ten przykład pokazuje, jak za pomocą Winscope debugować błąd testu migotania.

Sprawdź niepowodzenie testu

Aby określić typ problemu i sprawdzić komunikat o błędzie testu, wykonaj te czynności.

  1. Określ typ problemu, sprawdzając nazwę testu i klasy.

    Nazwa testu i zajęć:

    FlickerTestsNotification com.android.server.wm.flicker.notification.OpenAppFromLockscreenNotificationColdTest#appLayerBecomesVisible[ROTATION_0_GESTURAL_NAV]
    

    Typ problemu:

    • CUJ oznacza uruchamianie aplikacji z poziomu powiadomienia na ekranie blokady (OpenAppFromLockscreenNotificationColdTest).

    • Test oczekuje, że aplikacja stanie się widoczna (#appLayerBecomesVisible).

  2. Sprawdź komunikat o nieudanym teście, który zawiera szczegółowe informacje o błędzie, w tym:

    • porównanie oczekiwanego wyniku z rzeczywistym wynikiem widocznym dla użytkownika;
    • sygnatury czasowe, które pomogą określić, kiedy wystąpił błąd;
    • Nazwa artefaktu lub pliku powiązanego z błędem
    • Dodatkowe informacje kontekstowe, które pomagają zrozumieć i debugować błąd.
    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)
    

    Ten przykładowy wynik oznacza, że:

    • Problem występuje o 2024-05-10T11:04:14.227572545.

    • Element NotificationActivity powinien być widoczny, ale nie jest.

    • Nazwa pliku artefaktu zawierającego ślady do debugowania to FAIL__OpenAppFromLockscreenNotificationColdTest_ROTATION_0_GESTURAL_NAV.

Debuguj

Aby ustalić przyczynę migotania, wykonaj te czynności:

  1. Pobierz pliki śledzenia i wczytaj je w Winscope. Winscope otwiera się z automatycznie wybranym SurfaceFlingerem:

    Strona docelowa Winscope z widokiem SurfaceFlinger

    Rysunek 1. Strona docelowa Winscope z widokiem SurfaceFlinger.

  2. Przejdź do sygnatury czasowej, w której występuje problem, kopiując i wklejając sygnaturę czasową z komunikatu o wyjątku do pola sygnatury czasowej. Możesz skopiować sygnaturę czasową w formacie czytelnym dla człowieka (2024-05-10T11:04:14.227572545) i wkleić ją w pierwszym polu lub skopiować sygnaturę czasową w nanosekundach (1715339054227572545ns) i wkleić ją w drugim polu.

    Okno sygnatury czasowej

    Rysunek 2. Okno sygnatury czasowej.

  3. Aby przejść do poprzedniej ramki, naciśnij klawisz strzałki w lewo. W tym stanie aplikacja NotificationActivity jest prawidłowo wyświetlana na filmie, a zarówno aplikacja, jak i ekran powitalny są widoczne, co jest oznaczone zielonymi prostokątami w widoku 3D i chipem V na elementach hierarchii.

    Nazwy aplikacji i ekranu powitalnego to:

    com.android.server.wm.flicker.testapp/com.android.server.wm.flicker.testapp.NotificationActivity#3458`
    
    Splash Screen com.android.server.wm.flicker.testapp#3453
    

    Oznacza to, że aplikacja była uruchamiana, gdy ekran stał się czarny, i że to zdarzenie występuje podczas uruchamiania aplikacji, ponieważ ekran powitalny jest nadal widoczny:

    Podczas uruchamiania aplikacji

    Rysunek 3. Podczas uruchamiania aplikacji.

  4. Naciśnij klawisz strzałki w prawo, aby wrócić do następnej klatki, w której występuje migotanie. W widoku prostokątów na ekranie wyświetla się NotificationShade zamiast aplikacji. W tej ramce widać te powierzchnie:

    • Nakładki dekoracyjne na ekranie (u góry i u dołu)
    • Pasek nawigacyjny
    • Lokalizacja wskaźnika (z nagrania ekranu)

      Aktywność migotania

      Rysunek 4. Aktywność migotania.

  5. Wybierz aktywność aplikacji w widoku hierarchicznym. Jeśli nie możesz jej znaleźć, wyłącz opcję Pokaż tylko V. Następnie sprawdź widok usług.

    Nazwa platformy aplikacji to:

    com.android.server.wm.flicker.testapp/com.android.server.wm.flicker.testapp.NotificationActivity#3458`
    

    Usługi w aplikacjach

    Rysunek 5. usługi w aplikacjach.

    Aktywność aplikacji jest ustawiona jako widoczna i nieprzezroczysta, ale powierzchnia nie jest wyświetlana z powodu błędu Invisible due to: null visible region. Dzieje się tak, ponieważ podczas kompozycji przed nim umieszczono inną nieprzezroczystą powierzchnię. Ta hipoteza wynika z faktu, że w widoku 3D element NotificationShade znajduje się przed elementem NotificationActivity, a widoczny (zielony) element NotificationShade może być wybraną warstwą.

  6. Aby sprawdzić tę hipotezę, wybierz widoczną powierzchnię NotificationShade w bieżącej klatce i sprawdź jej właściwości. Flagi są ustawione na OPAQUE|ENABLE_BACKPRESSURE (0x102). Nazwa urządzenia NotificationShade to NotificationShade#3447. Następnie naciśnij strzałkę w lewo, aby wrócić do poprzedniej klatki (przed migotaniem) i ponownie sprawdź właściwości powierzchni NotificationShade. Zwróć uwagę, że zamiast OPAQUE powierzchnia ma tylko flagę ENABLE_BACKPRESSURE (0x100). Potwierdza to, że NotificationShade staje się nieprzezroczysty, zanim aplikacja zostanie w pełni uruchomiona. Ponieważ znak NotificationShade znajduje się przed znakiem NotificationActivity, aplikacja nie jest wyświetlana. NotificationShade jest czarny, więc ekran na chwilę gaśnie, co powoduje migotanie.

  7. Określ w kodzie, dlaczego element NotificationShade zbyt wcześnie staje się nieprzezroczysty.

Błąd zgłoszony przez użytkownika

Błędy zgłaszane przez użytkowników mogą być trudne do debugowania, ponieważ często brakuje w nich szczegółowych informacji. W przeciwieństwie do błędów wykrytych w testach migotania, które zawierają konkretne sygnatury czasowe, szczegóły elementu i nagrania ekranu, błędy zgłaszane przez użytkowników zwykle zawierają tylko krótki opis problemu.

W naszym studium przypadku podano tylko tytuł Ekran migał przy ponownym otwieraniu aplikacji w trybie podzielonego ekranu i przybliżoną sygnaturę czasową 18 kwietnia 2024 r. 15:51 GMT-04:00.

Aby debugować błąd zgłoszony przez użytkownika:

  1. Załaduj plik śledzenia w Winscope. Otworzy się Winscope z automatycznie wybranym SurfaceFlingerem.

    Strona docelowa Winscope z widokiem SurfaceFlinger

    Rysunek 6. Strona docelowa Winscope z widokiem SurfaceFlinger.

  2. Przejdź do przybliżonej sygnatury czasowej zgłoszonej przez użytkownika, w tym przypadku 3:50 PM GMT-04:00, wpisując 15:50:00 w polu sygnatury czasowej w formacie czytelnym dla człowieka.

    Okno sygnatury czasowej

    Rysunek 7. Okno sygnatury czasowej.

  3. Użyj widoku prostokątów, aby sprawdzić, co zostało narysowane na ekranie. Aby uzyskać lepszy widok, użyj suwaka Obrót, aby zmienić perspektywę prostokątów. W widoku Hierarchia zaznacz opcje Pokaż tylko VPłaski, aby wyświetlić tapetę, nakładkę dekoracyjną ekranu, letterbox, program uruchamiający, kontakty i aplikację do wybierania numerów.

    Nazwy pakietów to:

    • Launcher: com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity#40602

    • Kontakty: com.google.android.contacts/com.android.contacts.activities.PeopleActivity#40565

    • Dialer: com.google.android.dialer/com.google.android.dialer.extensions.GoogleDialtactsActivity#40564

    Oprócz widocznych powierzchni (zielone prostokąty) wyświetlany jest szary prostokąt, który reprezentuje powierzchnię obszaru wyświetlania o nazwie Nieznany wyświetlacz. Aby poprawić widoczność, kliknij ikona widoczności obok powierzchni ScreenDecorHwcOverlay#64, aby ukryć odpowiadający jej prostokąt i odsłonić powierzchnie znajdujące się za nim. Usuwamy nakładkę z analizy, ponieważ nie jest ona widoczna dla użytkownika i nie byłaby zgłaszana jako migocząca animacja.

    Raport Zgłoszenia użytkowników

    Rysunek 8. Raport Zgłoszenia użytkowników.

  4. Po określeniu, które powierzchnie są zaangażowane w widok podzielonego ekranu, użyj śledzenia przejść, aby przeanalizować różne działania użytkownika i znaleźć migotanie. Aby wyświetlić listę odtworzonych przejść, w Winscope kliknij kartę Przejścia:

    przejścia,

    Rysunek 9. Przejścia.

    Przejście odtwarzane w tej klatce jest wyróżnione na niebiesko. W tym przypadku flagi przejścia obejmują TRANSIT_FLAG_IS_RECENTS, co oznacza, że użytkownik przechodzi do ekranu ostatnich aplikacji.

  5. Kliknij link w kolumnie Czas wysyłki (w tym przypadku 2024-04-18, 15:50:57.205), aby przejść do tego momentu i sprawdzić prostokąty na karcie Surface Flinger. Sprawdź poprawność stanu urządzenia podczas przejścia, przechodząc przez nie za pomocą klawisza strzałki w prawo i obserwując prostokąty.

    Launcher pojawia się o 15:50:57.278, ale animacja nie rozpoczyna się w tym momencie. Tapeta jest już widoczna, ponieważ między aplikacjami na podzielonym ekranie nic nie jest rysowane (separator). Klatkę wcześniej (15:50:57.212) tapeta nie jest widoczna, a wyświetlany jest separator. Tak wygląda ekran podzielony, gdy nie jest animowany.

    Ekran przed migotaniem

    Rysunek 10. Ekran przed zdarzeniem migotania.

  6. Aby sprawdzić kolejną zmianę, kliknij bezpośrednio oś czasu. Stany narzędzia SurfaceFlinger są reprezentowane przez wiersz jasnoniebieskich bloków. Przejścia są reprezentowane przez wiersz różowych bloków.

    Koniec pierwszego przejścia

    Rysunek 11. Koniec pierwszego przejścia.

    Kliknij wiersz SurfaceFlinger w pozycji początkowej następnego przejścia. Na rysunku 11 cienka niebieska linia wskazuje położenie kursora w pionie. Jasnoniebieskie tło wiersza SurfaceFlinger pokazuje jego pozycję w poziomie. Przejdź przez przejście za pomocą klawisza strzałki w prawo, aby sprawdzić, czy występuje migotanie. Sprawdź, czy urządzenie wygląda prawidłowo w przypadku tego przejścia.

  7. Pomiń następne przejście, ponieważ jego czas trwania jest bardzo krótki, więc raczej nie będzie zawierać migotania. Zamiast tego kliknij oś czasu w wierszu SurfaceFlinger w pozycji początkowej następnego dłuższego przejścia, jak wskazuje kursor na poniższym obrazie.

    koniec drugiego przejścia,

    Rysunek 12. Koniec drugiego przejścia.

    Podczas tej zmiany, w punkcie 15:51:13.239, zauważ, że Splash Screenwarstwy obu aplikacji, kontaktów i aplikacji do wybierania numerów znajdują się po tej samej stronie wyświetlacza:

    ekrany powitalne,

    Rysunek 13. ekrany powitalne,

  8. Określ, która aplikacja znajduje się po niewłaściwej stronie. Dodaj zakładkę do bieżącej pozycji, klikając ikonę flagi obok pola wprowadzania ns, aby później łatwiej wrócić do tej klatki.

    dodaj zakładkę,

    Rysunek 14. Dodaj zakładkę.

  9. Przejdź do klatki na końcu przejścia, klikając bezpośrednio oś czasu, np. 15:51:13.859. Obie aplikacje są już na swoich miejscach: po lewej stronie znajduje się aplikacja do wybierania numerów, a po prawej – Kontakty:

    końcowy podzielony ekran,

    Rysunek 15. Ostatni podzielony ekran.

  10. Kliknij flagę zakładki na osi czasu, aby wrócić do klatki z migotaniem.

    oś czasu zakładek,

    Rysunek 16. Dodawanie zakładki do osi czasu.

    Obie aplikacje znajdują się po prawej stronie, co oznacza, że aplikacja Telefon jest w niewłaściwym miejscu.

  11. Kliknij ekran powitalny dialera, aby wyświetlić jego właściwości. Sprawdź właściwości przekształcenia w wyselekcjonowanym widoku Właściwości.

    Właściwości przekształcenia

    Rysunek 17. Właściwości przekształcenia.

    Obliczona transformacja jest stosowana do tej powierzchni, ale nie jest ustawiona na tym poziomie. Kolumny obliczone i żądane mają różne wartości, co oznacza, że przekształcenie jest dziedziczone z powierzchni nadrzędnej.

  12. Odznacz Płaski w widoku hierarchii, aby wyświetlić całe drzewo hierarchii, i przejdź do węzłów nadrzędnych powierzchni aplikacji, aż przekształcenia ObliczoneŻądane będą takie same. Wskaże to, że przekształcenie jest żądane na powierzchni Surface(name=Task=7934)/@0x1941191_transition-leash#40670.

  13. sprawdzić, kiedy przekształcenie zostało ustawione po raz pierwszy i na jaką wartość; Zwiń wybrane właściwości, klikając ikonę obok tytułu:

    zwiń wybrane właściwości,

    Rysunek 18. Zwiń wybrane usługi.

  14. W widoku Proto Dump kliknij Show diff, aby wyróżnić właściwości, które są zmieniane w tej klatce. Aby przefiltrować właściwości, w polu wyszukiwania tekstu wpisz transform:

    pokaż różnice,

    Rysunek 19. Pokaż różnice.

    W tym kadrze przekształcenie elementu transition-leash jest ustawione na IDENTITYSCALE|TRANSLATE|ROT_270.

    Te informacje wskazują, że migotanie wystąpiło, gdy transformacja została zastosowana do animacji aplikacji z podzielonym ekranem dialera.

    Identyfikacja migotania

    Rysunek 20. Identyfikacja migotania.

  15. Wskaż w kodzie, dlaczego ta transformacja jest ustawiona na smycz przejścia na podzielony ekran.