Winscope — это веб-инструмент, позволяющий записывать, воспроизводить и анализировать состояния различных системных служб во время и после анимации и переходов. Winscope записывает все соответствующие состояния системных служб в файл трассировки. Используя пользовательский интерфейс Winscope с файлом трассировки, вы можете проверять состояние этих служб для каждого кадра анимации, с записью экрана или без нее, воспроизводя, пошагово выполняя и отлаживая переходы.
Поддерживаемые трассировки
Winscope предоставляет возможность собирать и визуально отображать различные трассировки , то есть последовательности состояний системных служб. Вы можете настроить эти трассировки в соответствии с конкретными сценариями использования, от низкозатратных до высокодетализированных. Winscope поддерживает следующие типы трассировок:
- Журнал событий: Соберите запись диагностических событий системы с помощью
EventLog. В Winscope эта информация используется только для идентификации и отображения меток CUJ. - IME: Отслеживание событий из конвейера редактора методов ввода (IME), включая IMS, IMMS и IME Client.
- Входные данные: Отслеживание входных событий из различных частей конвейера обработки входных событий.
- ProtoLog: Сбор сообщений ProtoLog от системных служб и кода системных служб, работающих в клиентских процессах.
- Запись экрана: Сделайте запись экрана вместе с трассировкой.
- Переходы между оболочками: подробная информация о системе перехода между окнами и действиями.
- SurfaceFlinger: Собирает трассировки SurfaceFlinger , содержащие информацию о поверхностях (слоях), такую как положение, буфер и состав.
- Транзакции: Отслеживание набора атомарных изменений, полученных SurfaceFlinger, с использованием
SurfaceControlдля композиции. - ViewCapture: Захватывает ряд свойств всех элементов интерфейса Windows, поддерживающих ViewCapture, таких как системный интерфейс и панель запуска.
- Диспетчер окон: Трассировка диспетчера окон содержит подробную информацию об окнах, включая события ввода и фокусировки, ориентацию экрана, переходы, анимацию, позиционирование и преобразования.
Поддерживаемые дампы
Winscope может собирать и отображать дампы состояния, представляющие собой снимки состояния устройства, сделанные в определенные моменты времени, заданные пользователем. В отличие от трассировки, которая непрерывно собирается во время использования устройства и может влиять на производительность, дампы создаются только в эти заданные пользователем моменты, чтобы убедиться, что производительность и детализация не ухудшаются. Это позволяет проводить более целенаправленный и эффективный анализ состояния устройства в определенные моменты времени. Winscope поддерживает следующие типы дампов:
- Менеджер окон: Вывести в память только одно состояние менеджера окон.
- SurfaceFlinger: Создать дамп одного снимка SurfaceFlinger.
- Скриншот: Сделайте скриншот вместе с дампами.
Ресурсы
См. раздел «Запуск Winscope» для получения информации о сборке и запуске Winscope.
См. раздел «Захват трассировок» для получения информации о сборе трассировок.
См. раздел «Загрузка трассировок» для получения информации о том, как загружать трассировки с помощью веб-интерфейса Winscope.
См. раздел «Анализ трассировок» для получения информации об анализе трассировок.
Примеры
В следующем примере описано, как отладить ошибку, возникшую при проверке мерцания, и ошибку, о которой сообщил пользователь.
Сбой теста на мерцание
В этом примере показано, как использовать Winscope для отладки ошибки теста на мерцание.
Изучите причину сбоя теста.
Выполните следующие шаги, чтобы определить тип проблемы и изучить сообщение об ошибке тестирования.
Определите тип проблемы, изучив название теста и класса.
Название теста и класса:
FlickerTestsNotification com.android.server.wm.flicker.notification.OpenAppFromLockscreenNotificationColdTest#appLayerBecomesVisible[ROTATION_0_GESTURAL_NAV]Тип проблемы:
- CUJ обозначает запуск приложения из уведомления на экране блокировки (
OpenAppFromLockscreenNotificationColdTest). - В ходе теста предполагается, что приложение станет видимым (
#appLayerBecomesVisible).
- CUJ обозначает запуск приложения из уведомления на экране блокировки (
Изучите сообщение об ошибке тестирования, которое содержит исчерпывающую информацию о сбое, в том числе:
- Сравнение ожидаемого результата с фактическим видимым результатом.
- Временные метки помогут точно определить, когда произошла ошибка.
- Название артефакта или файла, связанного с ошибкой.
- Дополнительная контекстная информация, имеющая значение для понимания и устранения ошибки.
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)Данный пример выходных данных показывает следующее:
- Проблема возникла
2024-05-10T11:04:14.227572545. - Ожидается, что
NotificationActivityбудет видимым, но это не так. - Имя файла артефакта, содержащего трассировки для отладки, —
FAIL__OpenAppFromLockscreenNotificationColdTest_ROTATION_0_GESTURAL_NAV.
Отлаживать
Выполните следующие шаги, чтобы определить причину мерцания:
Загрузите файлы трассировки и загрузите их в Winscope. Winscope откроется с автоматически выбранным SurfaceFlinger:

Рисунок 1. Главная страница Winscope с представлением SurfaceFlinger.
Перейдите к временной метке, где возникла проблема, скопировав и вставив метку времени из сообщения об исключении в соответствующее поле. Вы можете либо скопировать метку времени в удобочитаемом формате (
2024-05-10T11:04:14.227572545) и вставить ее в первое поле, либо скопировать метку времени в наносекундах (1715339054227572545ns) и вставить ее во второе поле.
Рисунок 2. Диалоговое окно «Отметка времени».
Нажмите клавишу со стрелкой влево, чтобы перейти к предыдущему кадру. В этом состоянии приложение NotificationActivity корректно отображается в видео, и видны как поверхность приложения, так и поверхность заставки, что обозначено их зелеными прямоугольниками в 3D-виде и V- образным чипом на элементах их иерархии.
Названия элементов интерфейса приложения и заставки:
com.android.server.wm.flicker.testapp/com.android.server.wm.flicker.testapp.NotificationActivity#3458` Splash Screen com.android.server.wm.flicker.testapp#3453Это указывает на то, что приложение запускалось в момент, когда экран стал чёрным, и что это событие происходит во время запуска приложения, поскольку заставка всё ещё видна:

Рисунок 3. При запуске приложения.
Нажмите клавишу со стрелкой вправо, чтобы вернуться к следующему кадру, где происходит мерцание. В представлении прямоугольников на экране отображается
NotificationShadeвместо приложения. В этом кадре отображаются следующие поверхности:- Декоративные накладки для экрана (сверху и снизу)
- Панель навигации
- Местоположение указателя (по данным записи экрана)

Рисунок 4. Мерцание.
Выберите активность приложения в иерархическом представлении. Если вы не можете ее найти, снимите флажок « Показывать только V» . Затем изучите свойства приложения.
Название приложения на поверхности:
com.android.server.wm.flicker.testapp/com.android.server.wm.flicker.testapp.NotificationActivity#3458`
Рисунок 5. Свойства приложения.
Несмотря на то, что активность приложения установлена как видимая и непрозрачная, поверхность не отображается из-за ошибки
Invisible due to: null visible region. Это происходит потому, что во время композиции перед ней была размещена другая непрозрачная поверхность. Эта гипотеза основана на том, что прямоугольникNotificationShadeнаходится перед прямоугольникомNotificationActivityв 3D-виде, и видимый (зеленый)NotificationShadeвозможно, является выбранным слоем.Чтобы проверить эту гипотезу, выберите видимую поверхность
NotificationShadeна текущем кадре и проверьте её свойства. Флаги установлены в значениеOPAQUE|ENABLE_BACKPRESSURE (0x102). Имя поверхностиNotificationShade—NotificationShade#3447. Затем нажмите стрелку влево, чтобы вернуться к предыдущему кадру (до мерцания) и снова проверьте свойства поверхностиNotificationShade. Обратите внимание, что вместо значенияOPAQUEповерхность имеет только флагENABLE_BACKPRESSURE (0x100). Это подтверждает, чтоNotificationShadeстановится непрозрачным до полного завершения запуска приложения. ПосколькуNotificationShadeнаходится передNotificationActivity, приложение не отображается.NotificationShadeстановится чёрным, поэтому экран на короткое время гаснет, что и вызывает мерцание.Укажите в коде причину, по которой
NotificationShadeстановится непрозрачным слишком рано.
Ошибка, о которой сообщил пользователь.
Сообщения пользователей об ошибках могут быть сложными для отладки, поскольку им часто не хватает подробной информации. В отличие от ошибок при тестировании мерцания, которые предоставляют конкретные временные метки, сведения об элементах и записи экрана, сообщения пользователей об ошибках обычно содержат лишь краткое описание проблемы.
В нашем исследовании представлена только следующая информация: заголовок « Экран мерцает при повторном открытии приложения в режиме разделенного экрана» и приблизительное время 18 апреля 2024 г., 15:51 GMT-04:00 .
Для отладки ошибки, о которой сообщил пользователь, выполните следующие действия:
Загрузите файл трассировки в Winscope. Winscope откроется с автоматически выбранным SurfaceFlinger.

Рисунок 6. Главная страница Winscope с представлением SurfaceFlinger.
Чтобы перейти к приблизительному времени, указанному пользователем (в данном случае
3:50 PM GMT-04:00, введите15:50:00в поле для ввода времени, понятное человеку.
Рисунок 7. Диалоговое окно «Отметка времени».
Используйте режим просмотра прямоугольников, чтобы определить, что было нарисовано на экране. Для лучшего обзора используйте ползунок «Поворот» , чтобы изменить перспективу прямоугольников. Отметив в режиме просмотра иерархии пункты «Показывать только V» и «Плоский» , вы увидите обои, наложение декора экрана, черные полосы по бокам, панель запуска, контакты и панель набора номера.
Названия пакетов:
- Лаунчер:
com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity#40602 - Контакты:
com.google.android.contacts/com.android.contacts.activities.PeopleActivity#40565 - Номеронабиратель:
com.google.android.dialer/com.google.android.dialer.extensions.GoogleDialtactsActivity#40564
В дополнение к видимым поверхностям (зеленые прямоугольники) отображается серый прямоугольник, представляющий собой поверхность области отображения, с именем «Неизвестный дисплей ». Для улучшения видимости щелкните (
) рядом с поверхностью ScreenDecorHwcOverlay#64чтобы скрыть соответствующий прямоугольник и показать поверхности за ним. Мы удаляем наложение для анализа, поскольку оно не видно пользователю и не будет отображаться как мерцающая анимация.
Рисунок 8. Отчет пользователя.
- Лаунчер:
После определения поверхностей, задействованных в режиме разделенного экрана, используйте трассировку переходов, чтобы пошагово просмотреть различные действия пользователя и найти мерцание. Щелкните вкладку «Переходы» в Winscope, чтобы визуализировать список воспроизведенных переходов:

Рисунок 9. Переходы.
Переход, воспроизводимый в этом кадре, выделен синим цветом. В данном случае флаги перехода включают
TRANSIT_FLAG_IS_RECENTS, что указывает на то, что пользователь переходит на экран последних просмотренных элементов.Щелкните ссылку в столбце «Время отправки» (в данном случае
2024-04-18, 15:50:57.205), чтобы перейти к этому моменту времени и проверить прямоугольники на вкладке Surface Flinger . Подтвердите правильность состояния устройства во время перехода, пошагово выполняя переход с помощью клавиши со стрелкой вправо и наблюдая за прямоугольниками.Панель запуска появляется в 15:50:57.278, но анимация тогда не начинается. Обои уже видны, потому что между приложениями в режиме разделенного экрана ничего не отображается (разделитель). Кадром раньше (15:50:57.212) обои не видны, и отображается разделитель, именно так выглядит разделенный экран, когда анимация не запущена.

Рисунок 10. Экран до появления мерцания.
Чтобы посмотреть следующий переход, щелкните непосредственно по временной шкале. Состояния SurfaceFlinger отображаются рядом светло-голубых блоков. Переходы отображаются рядом розовых блоков.

Рисунок 11. Конец первого перехода.
Щелкните по строке SurfaceFlinger в начальной позиции следующего перехода. На рисунке 11 вертикальное положение курсора обозначено тонкой синей линией. Светло-голубой фон строки SurfaceFlinger показывает ее горизонтальное положение. Пройдите по переходу с помощью клавиши со стрелкой вправо, чтобы проверить, не возникает ли мерцание. Убедитесь, что устройство отображает изображение корректно для этого перехода.
Пропустите следующий переход, так как его продолжительность очень мала, поэтому вряд ли он будет сопровождаться мерцанием. Вместо этого щелкните по временной шкале в строке SurfaceFlinger в начальной позиции следующего более длительного перехода, как указано курсором на следующем изображении.

Рисунок 12. Конец второго перехода.
В этот момент перехода, в
15:51:13.239, обратите внимание, чтоSplash Screenдля обоих приложений, контактов и номеронабирателя, находятся на одной стороне экрана:
Рисунок 13. Заставки.
Уточните, какое приложение находится не с той стороны. Добавьте закладку к текущему положению, щелкнув значок флажка рядом с полем ввода ns , чтобы позже вернуться к этому фрейму.

Рисунок 14. Добавить закладку.
Перейдите к кадру в конце перехода, щелкнув непосредственно по временной шкале, например, к
15:51:13.859. Здесь оба приложения находятся в своем конечном положении: номеронабиратель слева, а контакты справа.
Рисунок 15. Финальное разделение экрана.
Нажмите на флажок закладки на временной шкале, чтобы вернуться к кадру с мерцанием.

Рисунок 16. Хронологическая шкала закладок.
Оба приложения находятся справа, что указывает на неправильное расположение приложения для набора номера.
Чтобы просмотреть свойства программы для набора номера, щелкните по заставке. Обратите особое внимание на свойства преобразования в режиме просмотра свойств .

Рисунок 17. Свойства преобразования.
Вычисленное преобразование применяется к этой поверхности, но не задается на этом уровне. Столбцы «Вычисленное» и «Запрошенное» имеют разные значения, что указывает на то, что преобразование наследуется от родительской поверхности.
Снимите флажок «Плоский» в представлении иерархии, чтобы отобразить все дерево иерархии, и переходите к родительским узлам поверхности приложения, пока значения вычисляемых и запрашиваемых преобразований не совпадут, отображая запрашиваемое преобразование на
Surface(name=Task=7934)/@0x1941191_transition-leash#40670.Укажите, когда и на какое значение было впервые установлено преобразование. Сверните отобранные свойства, щелкнув значок рядом с заголовком:

Рисунок 18. Свернуть отобранные свойства.
Выберите «Показать различия» в окне «Прототип дампа» , чтобы выделить свойства, изменяющиеся в этом окне. Введите
transformв поле поиска, чтобы отфильтровать свойства:
Рисунок 19. Показана разница.
В этом кадре для
transition-leashпреобразование устанавливается сIDENTITYнаSCALE|TRANSLATE|ROT_270.Эта информация показывает, что мерцание произошло, когда преобразование было применено к анимационному ремню приложения для разделенного экрана в приложении для набора номера.

Рисунок 20. Идентификация мерцания.
Укажите в коде, почему для этого преобразования установлен параметр "поводок перехода к разделенному экрану".