تتبُّع عمليات انتقال النوافذ باستخدام Winscope

‫Winscope هي أداة على الويب تتيح للمستخدمين تسجيل حالات العديد من خدمات النظام وإعادة تشغيلها وتحليلها أثناء وبعد الرسوم المتحركة وعمليات الانتقال. تسجّل أداة Winscope جميع حالات خدمة النظام ذات الصلة في ملف تتبُّع. باستخدام واجهة مستخدم Winscope مع ملف التتبُّع، يمكنك فحص حالة هذه الخدمات لكل إطار من إطارات الرسوم المتحركة، مع تسجيل الشاشة أو بدونه، وذلك من خلال إعادة التشغيل والتنقل خطوة بخطوة وتصحيح أخطاء عمليات الانتقال.

عمليات التتبُّع المتوافقة

توفّر أداة Winscope إمكانية جمع عمليات التتبُّع أو تسلسلات حالات خدمة النظام وعرضها بشكل مرئي. يمكنك ضبط عمليات التتبُّع هذه لتناسب حالات استخدام معيّنة، تتراوح بين الحد الأدنى من الحمل الزائد والحد الأقصى من التفصيل. يتوافق Winscope مع عمليات التتبُّع التالية:

  • EventLog: اجمع سجلّ أحداث تشخيص النظام باستخدام EventLog. في Winscope، يتم استخدام هذه المعلومات فقط لتحديد علامات CUJ وعرضها.
  • محرّر أسلوب الإدخال (IME): تتبُّع أحداث من مسار محرر أسلوب الإدخال (IME)، بما في ذلك IMS وIMMS وIME Client
  • الإدخال: تتبُّع أحداث الإدخال من أجزاء مختلفة من مسار أحداث الإدخال
  • ProtoLog: يتم جمع رسائل ProtoLog من خدمات النظام ورمز خدمات النظام التي تعمل في عمليات العميل.
  • تسجيل الشاشة: جمع تسجيل للشاشة إلى جانب عمليات التتبُّع
  • عمليات الانتقال في واجهة المستخدم: تسجيل تفاصيل النظام المتعلقة بعمليات الانتقال بين النوافذ والأنشطة
  • SurfaceFlinger: جمع عمليات تتبُّع SurfaceFlinger التي تحتوي على معلومات حول المساحات (الطبقات)، مثل الموضع والمخزن المؤقت والتركيب
  • المعاملات: تتبُّع مجموعة التغييرات الأساسية التي تلقّاها SurfaceFlinger باستخدام SurfaceControl لإنشاء الصور.
  • ViewCapture: لالتقاط مجموعة من خصائص جميع طرق العرض من نوافذ نظام التشغيل التي تتوافق مع ViewCapture، مثل واجهة مستخدم النظام وLauncher
  • مدير النوافذ: يتتبّع مدير النوافذ الحالات التي تحتوي على تفاصيل متعلقة بالنوافذ، بما في ذلك أحداث الإدخال والتركيز، واتجاه الشاشة، وعمليات الانتقال، والرسوم المتحركة، وتحديد المواضع، وعمليات التحويل.

عمليات التفريغ المسموح بها

يمكن لتطبيق Winscope جمع وعرض عمليات تفريغ الحالة، وهي لقطات لحالة الجهاز يتم التقاطها في لحظات معيّنة يحدّدها المستخدم. على عكس عمليات التتبُّع التي يتم جمعها باستمرار أثناء استخدام الجهاز ويمكن أن تؤثّر في الأداء، يتم أخذ عمليات التفريغ فقط في هذه اللحظات التي يحدّدها المستخدم، ما يضمن عدم التأثير في الأداء ومستوى التفصيل. ويتيح ذلك إجراء تحليل أكثر تركيزًا وفعالية لحالة الجهاز في نقاط زمنية محدّدة. تتوافق أداة Winscope مع عمليات التفريغ التالية:

  • Window Manager: لعرض حالة واحدة من Window Manager.
  • SurfaceFlinger: تفريغ لقطة واحدة من SurfaceFlinger
  • لقطة الشاشة: يتم جمع لقطة شاشة مع عمليات التفريغ.

المراجع

راجِع تشغيل Winscope للحصول على معلومات حول إنشاء Winscope وتشغيله.

راجِع تسجيل عمليات التتبُّع للحصول على معلومات حول جمع عمليات التتبُّع.

راجِع عمليات تحميل عمليات التتبُّع للحصول على معلومات حول كيفية تحميل عمليات التتبُّع باستخدام واجهة مستخدم ويب Winscope.

اطّلِع على تحليل عمليات التتبُّع للحصول على معلومات حول تحليل عمليات التتبُّع.

أمثلة

يوضّح المثال التالي كيفية تصحيح خطأ في اختبار الوميض وخطأ أبلغ عنه أحد المستخدمين.

تعذّر اجتياز اختبار التوهّج

يوضّح هذا المثال كيفية استخدام Winscope لتصحيح خطأ في اختبار التذبذب.

فحص تعذّر الاختبار

اتّبِع الخطوات التالية لتحديد نوع المشكلة وفحص رسالة تعذُّر الاختبار.

  1. حدِّد نوع المشكلة من خلال فحص الاختبار واسم الفئة.

    اسم الاختبار والصف:

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

    نوع المشكلة:

    • يشير CUJ إلى تشغيل تطبيق من إشعار على شاشة القفل (OpenAppFromLockscreenNotificationColdTest).

    • يتوقّع الاختبار أن يصبح التطبيق مرئيًا (#appLayerBecomesVisible).

  2. راجِع رسالة تعذُّر الاختبار التي تقدّم معلومات شاملة عن هذا التعذُّر، بما في ذلك:

    • مقارنة بين النتيجة المتوقّعة والنتيجة المرئية الفعلية
    • طوابع زمنية للمساعدة في تحديد وقت حدوث الخطأ
    • اسم العنصر أو الملف المرتبط بالمشكلة
    • معلومات سياقية إضافية ذات صلة بفهم الخطأ وتصحيحه
    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.

تصحيح الأخطاء

اتّبِع الخطوات التالية لتحديد سبب الوميض:

  1. نزِّل ملفات التتبُّع وحمِّلها في Winscope. يتم فتح Winscope مع تحديد SurfaceFlinger تلقائيًا:

    صفحة Winscope المقصودة مع عرض SurfaceFlinger

    الشكل 1. الصفحة المقصودة في Winscope مع عرض SurfaceFlinger

  2. انتقِل إلى الطابع الزمني الذي تحدث فيه المشكلة من خلال نسخ الطابع الزمني ولصقه من رسالة الخطأ في حقل الطابع الزمني. يمكنك إما نسخ الطابع الزمني بتنسيق قابل للقراءة (2024-05-10T11:04:14.227572545) ولصقه في الحقل الأول، أو نسخ الطابع الزمني بالنانوثانية (1715339054227572545ns) ولصقه في الحقل الثاني.

    مربّع حوار الطابع الزمني

    الشكل 2. مربّع حوار الطابع الزمني

  3. اضغط على مفتاح السهم المتّجه لليسار للانتقال إلى الإطار السابق. في هذه الحالة، يظهر تطبيق 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. عند تشغيل التطبيق

  4. اضغط على مفتاح السهم المتّجه لليمين للانتقال مجددًا إلى الإطار التالي الذي يحدث فيه التوهّج. في عرض المستطيلات، يظهر NotificationShade على الشاشة بدلاً من التطبيق. يتم عرض المساحات التالية في هذا الإطار:

    • تراكبات تزيين الشاشة (أعلى وأسفل)
    • شريط التنقل
    • موقع المؤشر (من تسجيل الشاشة)

      نشاط الوميض

      الشكل 4. نشاط Flicker

  5. اختَر نشاط التطبيق في طريقة العرض الهرمية. إذا لم تتمكّن من العثور عليه، أزِل العلامة من المربّع بجانب عرض 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 المرئي (الأخضر) قد يكون الطبقة المحدّدة.

  6. للتحقّق من صحة هذه الفرضية، اختَر السطح المرئي NotificationShade في الإطار الحالي وتحقّق من خصائصه. تم ضبط العلامات على OPAQUE|ENABLE_BACKPRESSURE (0x102). اسم السطح NotificationShade هو NotificationShade#3447. بعد ذلك، اضغط على السهم المتّجه لليسار للانتقال إلى الإطار السابق (قبل التوهّج) وفحص خصائص عنصر NotificationShade مرة أخرى. يُرجى ملاحظة أنّه بدلاً من أن تكون القيمة OPAQUE، لا تتضمّن مساحة العرض سوى العلامة ENABLE_BACKPRESSURE (0x100). يؤكّد ذلك أنّ NotificationShade يصبح غير شفاف قبل اكتمال عملية إطلاق التطبيق. بما أنّ NotificationShade يظهر قبل NotificationActivity، لا يظهر التطبيق. يكون لون NotificationShade أسود، لذا تصبح الشاشة سوداء لفترة وجيزة، ما يؤدي إلى حدوث الوميض.

  7. حدِّد في الرمز سبب تحوّل NotificationShade إلى اللون الداكن في وقت مبكر جدًا.

خطأ أبلغ عنه المستخدم

قد يكون من الصعب تصحيح الأخطاء التي يبلغ عنها المستخدمون لأنّها غالبًا ما تفتقر إلى معلومات تفصيلية. على عكس حالات تعذُّر اجتياز اختبار التذبذب التي تقدّم طوابع زمنية محددة وتفاصيل العناصر وتسجيلات الشاشة، لا تتضمّن عادةً الأخطاء التي يبلغ عنها المستخدمون سوى وصف موجز للمشكلة.

في دراسة الحالة هذه، المعلومات الوحيدة المقدَّمة هي العنوان شاشة الهاتف تومض عند إعادة فتح التطبيق من وضع تقسيم الشاشة والطابع الزمني التقريبي 18 أبريل 2024، الساعة 3:51 مساءً بتوقيت غرينتش -4:00.

اتّبِع الخطوات التالية لتصحيح خطأ أبلغ عنه أحد المستخدمين:

  1. حمِّل ملف التتبُّع في Winscope. يتم فتح Winscope مع اختيار SurfaceFlinger تلقائيًا.

    صفحة Winscope المقصودة مع عرض SurfaceFlinger

    الشكل 6. الصفحة المقصودة في Winscope مع عرض SurfaceFlinger

  2. انتقِل إلى الطابع الزمني التقريبي الذي أبلغ عنه المستخدم، وهو 3:50 PM GMT-04:00 في هذه الحالة، وذلك عن طريق إدخال 15:50:00 في حقل الطابع الزمني القابل للقراءة.

    مربّع حوار الطابع الزمني

    الشكل 7. مربّع حوار الطابع الزمني

  3. استخدِم طريقة العرض "المستطيلات" لتحديد ما تم رسمه على الشاشة. للحصول على عرض أفضل، استخدِم شريط تمرير التدوير لتغيير منظور المستطيلات. من خلال وضع علامة في المربّعين عرض V فقط ومسطّح في العرض هرمي، ستظهر خلفية الشاشة، والزخرفة على الشاشة، وتأثير Letterbox، والمشغّل، وجهات الاتصال، ولوحة الاتصال.

    أسماء الحِزم هي:

    • المشغّل: 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. تقرير المستخدم

  4. بعد تحديد المساحات المعنيّة بعرض الشاشة المقسّمة، استخدِم تتبُّع عمليات الانتقال لتصفُّح إجراءات المستخدمين المختلفة والعثور على الوميض. انقر على علامة التبويب عمليات الانتقال في Winscope لتصوُّر قائمة عمليات الانتقال التي تم تشغيلها:

    الانتقالات

    الشكل 9. الانتقالات

    يتم تمييز الانتقال الذي يتم تشغيله خلال هذا الإطار باللون الأزرق. في هذه الحالة، تتضمّن علامات الانتقال TRANSIT_FLAG_IS_RECENTS، ما يشير إلى أنّ المستخدم ينتقل إلى شاشة "التطبيقات الحديثة".

  5. انقر على الرابط في عمود وقت الإرسال (2024-04-18, 15:50:57.205 في هذه الحالة) للانتقال إلى تلك النقطة الزمنية والتحقّق من المستطيلات في علامة التبويب Surface Flinger. تأكَّد من صحة حالة الجهاز أثناء الانتقال من خلال التنقّل بين الحالات باستخدام مفتاح السهم المتّجه لليسار ومراقبة المستطيلات.

    يظهر مشغّل التطبيقات في 15:50:57.278، ولكن لا تبدأ الصورة المتحركة في ذلك الوقت. تظهر خلفية الشاشة لأنّه لا يتم عرض أي شيء بين التطبيقات في وضع تقسيم الشاشة (الفاصل). في إطار سابق (15:50:57.212)، لا يظهر خلفية الشاشة، ويظهر الفاصل، وهو الشكل الذي تبدو عليه الشاشة المقسّمة عند عدم تحريكها.

    الشاشة قبل الوميض

    الشكل 10. لقطة شاشة قبل حدث الوميض

  6. للاطّلاع على الانتقال التالي، انقر على المخطط الزمني مباشرةً. يتم تمثيل حالات SurfaceFlinger من خلال صف من المربّعات الزرقاء الفاتحة. يتم تمثيل الانتقالات بصف من المربّعات الوردية.

    نهاية الانتقال الأول

    الشكل 11. نهاية عملية النقل الأولى

    انقر على صف SurfaceFlinger في موضع البداية للانتقال التالي. في الشكل 11، يتم توضيح الموضع الرأسي للمؤشر بواسطة الخط الأزرق الرفيع. يعرض لون الخلفية الأزرق الفاتح لصف SurfaceFlinger موضعها الأفقي. انتقِل إلى الخطوة التالية في عملية الانتقال باستخدام مفتاح السهم المتّجه لليسار لمعرفة ما إذا كان يحدث وميض. يُرجى التأكّد من أنّ الجهاز يبدو صحيحًا لهذا الانتقال.

  7. تخطَّ الانتقال التالي لأنّ مدته قصيرة جدًا، لذا من غير المحتمل أن يتضمّن وميضًا. بدلاً من ذلك، انقر على المخطط الزمني في صف SurfaceFlinger عند موضع البدء للانتقال الأطول التالي، كما هو موضّح بواسطة المؤشر في الصورة التالية.

    نهاية الانتقال الثاني

    الشكل 12: نهاية الانتقال الثاني

    أثناء هذا الانتقال، عند 15:51:13.239، لاحظ أنّ Splash Screen طبقات كل من التطبيقين وجهات الاتصال ولوحة الاتصال تظهر على الجانب نفسه من الشاشة:

    شاشات البداية

    الشكل 13. شاشات البداية

  8. وضِّح التطبيق الذي يظهر على الجانب الخطأ. أضِف إشارة مرجعية إلى موضعك الحالي من خلال النقر على رمز العلم بجانب حقل الإدخال ns، وذلك لتسهيل الرجوع إلى هذا الإطار لاحقًا.

    إضافة إشارة مرجعية

    الشكل 14. إضافة إشارة مرجعية

  9. انتقِل إلى إطار في نهاية الانتقال من خلال النقر على المخطط الزمني مباشرةً، مثلاً، على 15:51:13.859. في ما يلي، يظهر التطبيقان في موضعيهما النهائيين، حيث يظهر تطبيق "لوحة الاتصال" على اليمين وتطبيق "جهات الاتصال" على اليسار:

    تقسيم الشاشة النهائي

    الشكل 15. شاشة مقسّمة نهائية

  10. انقر على علم الإشارة المرجعية في المخطط الزمني للرجوع إلى الإطار الذي يظهر فيه التموّج.

    المخطط الزمني للإشارات المرجعية

    الشكل 16. المخطط الزمني للإشارات

    يظهر كلا التطبيقين على اليمين، ما يشير إلى أنّ تطبيق "لوحة الاتصال" في الموضع الخاطئ.

  11. انقر على شاشة البداية في لوحة الاتصال لعرض خصائصها. ابحث تحديدًا عن خصائص التحويل في عرض الخصائص المنسّق.

    خصائص التحويل

    الشكل 17. خصائص التحويل

    يتم تطبيق عملية التحويل المحسوبة على هذا السطح، ولكن لا يتم ضبطها على هذا المستوى. تتضمّن الأعمدة المحسوبة والمطلوبة قيمًا مختلفة، ما يشير إلى أنّه يتم اكتساب عملية التحويل من مساحة عرض رئيسية.

  12. ألغِ اختيار مسطّح في عرض التدرّج الهرمي لعرض شجرة التدرّج الهرمي بأكملها، وانتقِل إلى العُقد الرئيسية لسطح التطبيق إلى أن تتطابق كل من عمليات التحويل المحسوبة والمطلوبة، ما يشير إلى أنّ عملية التحويل مطلوبة على سطح Surface(name=Task=7934)/@0x1941191_transition-leash#40670.

  13. تأكَّد من وقت ضبط عملية التحويل لأوّل مرّة، والقيمة التي تم ضبطها. يمكنك تصغير السمات المنسّقة من خلال النقر على الرمز بجانب العنوان:

    تصغير العقارات المنسّقة

    الشكل 18. صغِّر العقارات التي تم اختيارها.

  14. اختَر عرض الاختلاف في عرض Proto Dump لتمييز الخصائص التي يتم تغييرها في هذا الإطار. اكتب transform في حقل البحث النصي لفلترة الخصائص:

    عرض الاختلاف

    الشكل 19. عرض الاختلاف

    تم ضبط عملية التحويل من IDENTITY إلى SCALE|TRANSLATE|ROT_270 في هذا الإطار الخاص بـ transition-leash.

    توضّح هذه المعلومات أنّ التقطّع حدث عند تطبيق عملية التحويل على سلسلة الرسوم المتحركة لتطبيق "تقسيم الشاشة" في تطبيق "لوحة الاتصال".

    تحديد الوميض

    الشكل 20. تحديد الوميض

  15. حدِّد في الرمز سبب ضبط عملية التحويل هذه على مقود الانتقال إلى وضع تقسيم الشاشة.