Winscope — это веб-инструмент, который позволяет пользователям записывать, воспроизводить и анализировать состояния нескольких системных служб во время и после анимации и переходов. Winscope записывает все соответствующие состояния системных служб в файл трассировки. Используя пользовательский интерфейс Winscope с файлом трассировки, вы можете проверять состояние этих служб для каждого кадра анимации с записью экрана или без нее, воспроизводя, пошагово и отлаживая переходы.
Поддерживаемые трассировки
Winscope предоставляет возможность собирать и визуально представлять различные следы или последовательности состояний системных служб. Вы можете настроить эти трассировки в соответствии с конкретными случаями использования: от низких издержек до высокой детализации. Winscope поддерживает следующие трассировки:
- EventLog: Соберите записи событий диагностики системы с помощью
EventLog
. В Winscope эта информация используется только для идентификации и отображения маркировки CUJ. - IME: отслеживание событий из конвейера редактора метода ввода (IME), включая IMS, IMMS и клиент IME.
- Ввод: отслеживание событий ввода из различных частей конвейера входных событий.
- 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
).
Изучите сообщение о сбое теста, которое содержит исчерпывающую информацию о сбое, включая:
- Сравнение ожидаемого результата и фактического видимого результата.
- Временные метки, помогающие определить, когда произошел сбой
- Имя артефакта или файла, связанного с ошибкой.
- Дополнительная контекстная информация, необходимая для понимания и устранения сбоя.
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 правильно отображается в видео, и видимы поверхности приложения и экрана-заставки, на что указывают их зеленые прямоугольники в трехмерном представлении и значок 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
в трехмерном представлении, а видимый (зеленый)NotificationShade
потенциально является выбранным слоем.Чтобы проверить эту гипотезу, выберите видимую поверхность
NotificationShade
в текущем кадре и проверьте ее свойства. Флаги установлены вOPAQUE|ENABLE_BACKPRESSURE (0x102)
. Имя поверхностиNotificationShade
—NotificationShade#3447
. Затем нажмите стрелку влево, чтобы вернуться к предыдущему кадру (до мерцания) и еще раз проверьте свойства поверхностиNotificationShade
. Обратите внимание, что вместоOPAQUE
поверхность имеет только флагENABLE_BACKPRESSURE (0x100)
. Это подтверждает, чтоNotificationShade
становится непрозрачным до полного завершения запуска приложения. ПосколькуNotificationShade
находится передNotificationActivity
, приложение не отображается.NotificationShade
имеет черный цвет, поэтому экран на короткое время становится черным, что вызывает мерцание.Определите в коде, почему
NotificationShade
становится непрозрачным слишком рано.
Ошибка, о которой сообщил пользователь
Ошибки, о которых сообщают пользователи, может оказаться сложной задачей для отладки, поскольку о них часто не хватает подробной информации. В отличие от неудачных тестов на мерцание, которые предоставляют конкретные временные метки, сведения об элементах и записи экрана, ошибки, о которых сообщают пользователи, обычно включают только краткое описание проблемы.
В нашем примере единственной предоставленной информацией является заголовок « Экран мерцал» при повторном открытии приложения с разделенного экрана и приблизительная отметка времени: 18 апреля 2024 г., 15:51 по Гринвичу-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
В дополнение к видимым поверхностям (зеленым прямоугольникам) отображается серый прямоугольник, представляющий поверхность области отображения, с именем Unknown display . Чтобы улучшить видимость, нажмите значок (
) рядом с поверхностью
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. Идентификация мерцания.
Определите в коде, почему для этого преобразования установлен поводок перехода разделенного экрана.