תמיכה ב-HAL זמינה באופן דינמי

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

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

שינויים בהגדרות של HAL

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

# some init.rc script associated with the HAL
service vendor.some-service-name /vendor/bin/hw/some-binary-service
    # init language extension, provides information of what service is served
    # if multiple interfaces are served, they can be specified one on each line
    interface android.hardware.light@2.0::ILight default
    # restarted if hwservicemanager dies
    # would also cause the hal to start early during boot if disabled wasn't set
    class hal
    # will not be restarted if it exits until it is requested to be restarted
    oneshot
    # will only be started when requested
    disabled
    # ... other properties

שינויים ב-init וב-hwservicemanager

הכיבוי הדינמי דורש גם שhwservicemanager יודיע init כדי להפעיל את השירותים המבוקשים. ב-Android 9, init כולל שלוש הודעות בקרה נוספות (למשל, ctl.start): ctl.interface_start, ctl.interface_stop ו-ctl.interface_restart. אפשר להשתמש בהודעות האלה כדי לסמן את init כלפי מעלה או כלפי מטה ממשקי חומרה ספציפיים. כשנשלחת בקשה לשירות ולא נשלחה בקשה לכך רשום, hwservicemanager מבקש שהשירות בתהליך. עם זאת, בערכות HAL דינמי לא נדרש שימוש באף אחד מהכלים האלה.

קביעה של יציאת HAL

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

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

  • פרוטוקול HAL יכול לבחור לקרוא ליציאה בעצמו אם מישהו קורא לסגור או תואם ל-API שלה. יש לציין את ההתנהגות הזו ב-HAL המתאים גרפי.
  • תמיכה ב-HAL יכולה להיכבות כשהמשימה מסתיימת (מתועד ב-HAL ).

מחזורי חיים אוטומטיים

עם Android 10, נוספה תמיכה בליבה (kernel) hwservicemanager, שמאפשר לבצע כיבוי אוטומטי של אפליקציות מבוססות-HAL כשיש להם לקוחות. כדי להשתמש בתכונה הזו, צריך לבצע את כל השלבים שינויים בהגדרות HAL כ:

  • רישום השירות ב-C++ ב-LazyServiceRegistrar במקום הפונקציה registerAsService, דוגמה:
    // only one instance of LazyServiceRegistrar per process
    LazyServiceRegistrar registrar;
    registrar.registerAsService(myHidlService /* , "default" */);
  • מוודאים שלקוח ה-HAL שומר הפניה לפרוטוקול HAL ברמה העליונה רשום ב-hwservicemanager) רק כאשר הוא בשימוש. כדי למנוע עיכובים אם ההפניה נופלת מ-thread של hwbinder שממשיך לפעול, הלקוח צריך גם לקרוא IPCThreadState::self()->flushCommands() לאחר הפלת שמטרתה לוודא שמנהל התקן של הקישור צריך לקבל הודעה על שינויים בספירת ההפניות.