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

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

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

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

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

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

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

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

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

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

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

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

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

    הפעולה הזו גורמת למסגרת לטעון מחדש את כל יכולות התצוגה.

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

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

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

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

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

אם ל-STB או ל-TV dongle יש חיבורי 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 כדי להודיע על שינוי בקבוצת המצבים הנתמכים.

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

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

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

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

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

  • כש-HAL של Composer מעדכן את הגדרות התצוגה הנתמכות, הוא מקצה מזהי רצף חדשים להגדרות התצוגה החדשות.
  • כשהמסגרת קוראת ל-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 כדי להודיע על שינוי בקבוצת המצבים הנתמכים.

  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 מפרש בצורה נכונה שהמסגרת ביקשה שינוי של ההגדרות ל-1080x1920 60 Hz.

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