כדי להטמיע כיבוי דינמי, צריך לחבר את זרימות הנתונים ולבצע תהליכים דינמיים, כפי שמתואר בקטעים הבאים.
שינויים בהגדרות 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 יכול לבחור לבצע קריאה ל-exit על עצמו אם מישהו קורא ל-API דומה או קרוב. צריך לציין את ההתנהגות הזו בממשק HAL המתאים.
- HALs יכולים להיסגר כשהמשימה שלהם מסתיימת (מתועד בקובץ HAL).
מחזורי חיים אוטומטיים
ב-Android 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()
אחרי השמטת ההפניה, כדי לוודא שמתקבלת הודעה למנהל ה-binder על השינויים במספר ההפניות המשויך.