טיפול בהתקנה בזמן הפעלה (hotplug)

יכולות התצוגה (כמו מצבי תצוגה וסוגי HDR נתמכים) יכולות להשתנות באופן דינמי במכשירים שמחוברים אליהם מסכים חיצוניים (עם HDMI או DisplayPort), כמו ממירים של Android TV ומכשירי OTT. השינוי הזה יכול לקרות כתוצאה מאות HDMI hotplug, למשל כשמשתמש עובר ממסך אחד למסך אחר או מפעיל את המכשיר בלי מסך מחובר. ‫Android מגרסה 12 ואילך כולל שינויים במסגרת לטיפול בהוספה והסרה של רכיבים בזמן שהמערכת פועלת (hotplugging) וביכולות דינמיות של התצוגה.

בדף הזה מוסבר על הטיפול בהחלפה מהירה של צגים ושינויים ביכולות הצגים בהטמעה של Composer HAL. בנוסף, מוסבר איך לנהל את מאגר המסגרות המשויך ולמנוע מרוץ תהליכים במצבים האלה.

עדכון יכולות התצוגה

בקטע הזה מוסבר איך מסגרת Android מטפלת בשינויים ביכולות התצוגה שמופעלים על ידי Composer HAL.

כדי שמערכת Android תוכל לטפל כראוי בשינויים ביכולות התצוגה, יצרן הציוד המקורי צריך להטמיע את Composer HAL כך שישתמש ב-onHotplug(display, connection=CONNECTED) כדי להודיע למסגרת על שינויים ביכולות התצוגה. אחרי ההטמעה, מערכת Android מטפלת בשינויים ביכולות התצוגה באופן הבא:

  1. כשמזוהה שינוי ביכולות התצוגה, ה-Framework מקבל התראה מסוג onHotplug(display, connection=CONNECTED).
  2. כשמתקבלת ההתראה, המסגרת משחררת את מצב התצוגה ויוצרת אותו מחדש עם היכולות החדשות מ-HAL באמצעות השיטות getActiveConfig,‏ getDisplayConfigs,‏ getDisplayAttribute,‏ getColorModes,‏ getHdrCapabilities ו-getDisplayCapabilities.
  3. אחרי שהמסגרת יוצרת מחדש מצב תצוגה חדש, היא שולחת את הקריאה החוזרת (callback) onDisplayChanged לאפליקציות שממתינות לאירועים כאלה.

המסגרת מקצה מחדש את מאגרי המסגרות באירועי onHotplug(display, connection=CONNECTED) הבאים. מידע נוסף על ניהול נכון של זיכרון framebuffer כדי למנוע כשלים במהלך הקצאה של framebuffers חדשים מופיע במאמר בנושא ניהול framebuffer של לקוח.

טיפול בתרחישי חיבור נפוצים

בקטע הזה מוסבר איך לטפל בצורה נכונה בתרחישי חיבור שונים בהטמעות שלכם, כשהמסך הראשי מחובר ומנותק.

מסגרת Android מיועדת למכשירים ניידים, ולכן אין בה תמיכה מובנית במסך ראשי מנותק. במקום זאת, ה-HAL צריך להחליף את התצוגה הראשית בתצוגה של placeholder באינטראקציות שלו עם המסגרת במקרה של ניתוק פיזי של התצוגה הראשית.

התרחישים הבאים יכולים להתרחש בממירים ובמתאמים לטלוויזיה עם מסכים שמחוברים חיצונית וניתנים לניתוק. כדי להטמיע תמיכה בתרחישים האלה, אפשר להיעזר במידע שבטבלה הבאה:

תרחיש שימוש
אין מסך מחובר בזמן האתחול
  • שליחת אות onHotplug(display, connection=CONNECTED) מ-Composer HAL אל המסגרת.
  • מחליפים את מצב התצוגה הפיזי ב-Composer HAL במצב תצוגה של placeholder.
המסך הראשי מחובר פיזית
המסך הראשי מנותק פיזית
  • שליחת אירוע onHotplug(display, connection=CONNECTED) נוסף מ-Composer HAL למסגרת.
  • מחליפים את מצב התצוגה הפיזי ב-Composer HAL במצב תצוגה של placeholder. לפלייסהולדר של התצוגה צריך להיות מצב תצוגה יחיד, כדי שהמסגרת תשלח את הקריאה החוזרת onDisplayChanged לאפליקציות (כי קבוצת המצבים הנתמכים השתנתה). מצב התצוגה היחיד הזה צריך להיות זהה למצב הפעיל האחרון של המסך הפיזי לפני הניתוק, כדי שאפליקציות לא יקבלו אירועים של שינוי ההגדרה.

שיקולים לגבי חיבור שאינו HDMI

ב-Android TV קיימת תמיכה רק ברזולוציות הבאות:

  • ‫720x1280
  • ‫1080x1920
  • ‫2160x3840
  • 4320x7680

כשממיר או מתאם לטלוויזיה מנסים להציג רזולוציה שלא נתמכת, כמו 480i בחיבור CVBS, מוצגת למשתמש הודעת שגיאה.

אם לממיר או לדונגל של הטלוויזיה יש חיבור HDMI וגם חיבור שאינו HDMI, חיבור ה-HDMI הוא המסך הראשי והחיבור שאינו HDMI לא פעיל. כתוצאה מכך, אם חיבור ה-HDMI מנותק בזמן שחיבור שאינו HDMI עדיין מחובר, אירוע נשלח אל SurfaceFlinger והיכולות של המסך שאינו HDMI צריכות להשתקף דרך getDisplayAttribute וממשקי API אחרים של IComposerClient (כמו getHdrCapabilities).

שימוש במזהי הגדרות עוקבים כדי למנוע מרוץ תהליכים

מצבי מירוץ יכולים להתרחש אם ה-HAL של Composer מעדכן את תצורות התצוגה הנתמכות במקביל למסגרת שקוראת ל-setActiveConfig או ל-setActiveConfigWithConstraints. הפתרון הוא להטמיע את Composer HAL כדי להשתמש במזהים עוקבים ולמנוע את הבעיה הזו.

בקטע הזה מוסבר איך מרוץ תהליכים עלול להתרחש, ואחריו מפורט איך להטמיע את Composer HAL כך שישתמש במזהים עוקבים כדי למנוע מצבים כאלה.

כדאי לשים לב לרצף האירועים הבא, שבו לא מוקצים מזהים חדשים ורציפים להגדרות התצוגה החדשות, מה שגורם לתנאי מירוץ:

  1. מזהי התצורה הנתמכים של תצוגה הם:

    • id=1, ‏ 1080x1920‏ 60 Hz
    • id=2, ‏ ‎1080x1920 50 Hz
  2. המסגרת קוראת ל-setActiveConfig(display, config=1).

  3. במקביל, ה-HAL של Composer מעבד שינוי בהגדרות התצוגה ומעדכן את המצב הפנימי שלו לקבוצה חדשה של הגדרות תצוגה, כפי שמוצג בהמשך:

    • id=1, ‏ ‎2160x3840 60 Hz
    • id=2, ‏ 2160x3840‏ 50 Hz
    • id=3, ‏ 1080x1920‏ 60 Hz
    • id=4, ‏ ‎1080x1920 50 Hz
  4. ‫Composer HAL שולח אירוע onHotplug ל-framework, כדי להודיע שהשתנה מערך המצבים הנתמכים.

  5. ה-HAL של Composer מקבל את setActiveConfig(display, config=1) (משלב 2).

  6. שכבת ה-HAL מפרשת את הבקשה של המסגרת לשינוי ההגדרה ל-2160x3840 60 Hz, למרות שבפועל נבחרה ההגדרה 1080x1920 60 Hz.

התהליך שבו נעשה שימוש בהקצאות מזהים לא רציפות מסתיים כאן בפרשנות שגויה של שינוי ההגדרה שנבחר.

הגדרת Composer HAL לשימוש במזהים עוקבים

כדי להימנע ממצבי מירוץ כאלה, יצרן הציוד המקורי צריך להטמיע את Composer HAL באופן הבא:

  • כש-Composer HAL מעדכן את תצורות התצוגה הנתמכות, הוא מקצה מזהים חדשים רציפים לתצורות התצוגה החדשות.
  • כשמסגרת העבודה קוראת ל-setActiveConfig או ל-setActiveConfigWithConstraints עם מזהה הגדרה לא תקין, ה-HAL של Composer מתעלם מהקריאה.

השלבים האלה נועדו למנוע מצבי מירוץ, כפי שמוסבר בהמשך.

כדאי לעיין ברצף האירועים הבא, שמתרחש כשמוקצים מזהים חדשים ורציפים להגדרות התצוגה החדשות:

  1. מזהי התצורה הנתמכים של תצוגה הם:

    • id=1, ‏ 1080x1920‏ 60 Hz
    • id=2, ‏ ‎1080x1920 50 Hz
  2. המסגרת קוראת ל-setActiveConfig(display, config=1).

  3. כשמעבדים שינוי בהגדרות התצוגה, המערכת מקצה את קבוצת מזהי ההגדרות הבאה החל מהמספר השלם הבא שלא נמצא בשימוש, כמו שמוצג כאן:

    • id=3, ‏ ‎2160x3840 60 Hz

    • id=4, ‏ 2160x3840‏ 50 Hz

    • id=5, ‏ 1080x1920‏ 60 Hz

    • id=6, ‏ 1080x1920‏ 50 Hz

  4. ה-HAL של Composer שולח אירוע onHotplug ל-framework, כדי להודיע שהשתנה אוסף המצבים הנתמכים.

  5. ה-HAL של Composer מקבל את setActiveConfig(display, config=1) (משלב 2).

  6. ה-HAL של Composer מתעלם מהשיחה כי המזהה כבר לא תקף.

  7. המסגרת מקבלת ומעבדת את האירוע onHotplug משלב 4. היא קוראת ל-HAL של Composer באמצעות הפונקציות getDisplayConfigs ו-getDisplayAttribute. באמצעות הפונקציות האלה, המסגרת מזהה את המזהה החדש (5) עבור הרזולוציה וקצב הרענון שנבחרו, 1080x1920 ו-60 Hz.

  8. המסגרת שולחת אירוע setActiveConfig נוסף עם מזהה מעודכן של 5.

  9. ה-HAL של Composer מקבל setActiveConfig(display, config=5) משלב 5.

  10. ה-HAL מפרש בצורה נכונה שה-framework ביקש שינוי בהגדרה ל-1080x1920 60 Hz.

כפי שמוצג בדוגמה הקודמת, התהליך שמשתמש בהקצאות רציפות של מזהים מוודא שמרוץ התהליכים נמנע ושהעדכון של שינוי הגדרת התצוגה מתבצע בצורה נכונה.