יישום כיבוי דינמי כרוך בחיבור זרימות נתונים וביצוע תהליכים דינמיים כמפורט בסעיפים הבאים.
שינויים בהגדרות 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
להתחיל את השירותים המבוקשים. באנדרואיד 9, init
כולל שלוש הודעות בקרה נוספות (למשל ctl.start
): ctl.interface_start
, ctl.interface_stop
ו- ctl.interface_restart
. ניתן להשתמש בהודעות אלה כדי לאותת init
להעלות ולהוריד ממשקי חומרה ספציפיים. כאשר שירות מתבקש ואינו רשום, hwservicemanager
מבקש שהשירות יופעל. עם זאת, HALs דינמיים אינם דורשים שימוש באף אחד מאלה.
קבע את יציאת HAL
באנדרואיד 9, יש לקבוע ידנית את יציאת HAL. עבור אנדרואיד 10 ומעלה, ניתן לקבוע זאת גם באמצעות מחזורי חיים אוטומטיים .
כיבוי דינמי דורש מספר מדיניות כדי להחליט מתי להתחיל HAL ומתי לכבות HAL. אם HAL מחליט לצאת מכל סיבה שהיא, הוא יופעל מחדש באופן אוטומטי כאשר יהיה צורך בו שוב באמצעות המידע המסופק בהגדרת HAL והתשתית שסופקו על ידי שינויים ב- init
וב- hwservicemanager
. זה יכול לכלול כמה אסטרטגיות שונות, כולל:
- HAL יכול לבחור לקרוא ליציאה בעצמו אם מישהו קורא אליו API קרוב או דומה. יש לציין התנהגות זו בממשק HAL המתאים.
- HALs יכולים להיסגר כאשר המשימה שלהם הושלמה (מתועדת בקובץ HAL).
מחזורי חיים אוטומטיים
אנדרואיד 10 מוסיפה תמיכה נוספת לקרנל ול- hwservicemanager
, מה שמאפשר ל-HALs להיסגר אוטומטית בכל פעם שאין להם לקוחות. כדי להשתמש בתכונה זו, בצע את כל השלבים בשינויים בהגדרות HAL וכן:
- רשום את השירות ב-C++ עם
LazyServiceRegistrar
במקום פונקציית החברים,registerAsService
, לדוגמה:// only one instance of LazyServiceRegistrar per process LazyServiceRegistrar registrar; registrar.registerAsService(myHidlService /* , "default" */);
- ודא שלקוח HAL שומר הפניה ל-HAL ברמה העליונה (הממשק הרשום ב-
hwservicemanager
) רק כאשר הוא בשימוש. כדי למנוע עיכובים אם הפניה זו נשמטת על שרשור hwbinder שממשיך להפעיל, הלקוח צריך גם לקרוא ל-IPCThreadState::self()->flushCommands()
לאחר שחרור ההפניה כדי לוודא שמנהל ההפניה מקבל הודעה על ספירת ההפניות הקשורה שינויים.