באנדרואיד 9 ומטה יש שרשור ב- libsuspend שאחראי על התחלת השעיית המערכת. אנדרואיד 10 מציגה פונקציונליות מקבילה בשירות SystemSuspend HIDL. שירות זה ממוקם בתמונת המערכת ומוגש על ידי פלטפורמת אנדרואיד. ההיגיון מ- libsuspend
נשאר כמעט זהה, למעט כל תהליך של מרחב משתמש החוסם את ההשעיה של המערכת צריך לתקשר עם SystemSuspend.
libsuspend ו libpower
באנדרואיד 10, שירות SystemSuspend מחליף את libsuspend
. libpower
הוטמע מחדש כדי להסתמך על שירות SystemSuspend במקום /sys/ power /wake[un]lock
מבלי לשנות את ה-API של C.
פסאודוקוד זה מראה כיצד ליישם את acquire_wake_lock
ו- release_wake_lock
.
static std::unordered_map<std::string, sp<IWakeLock>> gWakeLockMap;
int acquire_wake_lock(int, const char* id) {
...
if (!gWakeLockMap[id]) {
gWakeLockMap[id] = suspendService->acquireWakeLock(WakeLockType::PARTIAL, id);
}
...
return 0;
}
int release_wake_lock(const char* id) {
...
if (gWakeLockMap[id]) {
auto ret = gWakeLockMap[id]->release();
gWakeLockMap[id].clear();
return 0;
}
...
return -1;
}
חוטי ביצוע
שירות SystemSuspend עוקב אחר מספר נעילות ההשקה שהונפקו עם מונה השעיה. יש לו שני חוטי ביצוע:
- השרשור הראשי עונה לשיחות קלסר.
- מערכת בקרות ההשעיה ההשעיה .
חוט ראשי
השרשור הראשי עונה לבקשות מלקוחות להקצות נעילות ערות חדשות, תוך הגדלה/הקטנה של מונה ההשעיה.
השעיית חוט
חוט ההשעיה מבצע את הפעולות הבאות בלולאה:
- קרא מתוך
/sys/ power /wakeup_count
. - רכוש את המוטקס. זה מוודא שהחוט ההשעיה לא נוגע במונה ההשעיה בזמן שהשרשור הראשי מנסה להגדיל או להקטין אותו. השרשור הראשי נחסם בהנפקה או הסרה של נעילות התעוררות כאשר מונה ההשעיה הגיע לאפס וההפסקה מנסה לפעול.
- המתן עד שהמונה יהיה שווה לאפס.
- כתוב את הערך שנקרא מ-
/sys/ power /wakeup_count
(משלב 1) לקובץ זה. אם הכתיבה נכשלת, חזור לתחילת הלולאה - הפעל את ההשעיה של המערכת על ידי כתיבת
mem
אל/sys/power/ state
. - שחרר את המוטקס.
כאשר בקשה לנעילת ערה חוזרת בהצלחה, שרשור ההשעיה נחסם.
SystemSuspend API
ה-API של SystemSuspend מורכב משני ממשקים. ממשק HIDL משמש על ידי תהליכים מקוריים לרכישת נעילות ערה וממשק AIDL משמש לתקשורת בין SystemServer ו-SystemSuspend.
ממשק ISystemSuspend HIDL
enum WakeLockType : uint32_t {
PARTIAL,
FULL
};
interface IWakeLock {
oneway release();
};
interface ISystemSuspend {
acquireWakeLock(WakeLockType type, string debugName)
generates (IWakeLock lock);
};
כל לקוח שמבקש נעילת ערה מקבל מופע ייחודי IWakeLock
. זה שונה מ- /sys/ power /wake_lock
, המאפשר למספר לקוחות להשתמש במנעול ההתעוררות תחת אותו שם. אם לקוח שמחזיק מופע IWakeLock
מסתיים, מנהל ההתקן של הקלסר ושירות SystemSuspend מנקים אותו.
ממשק ISuspendControlService AIDL
ISuspendControlService מיועד לשימוש רק על ידי SystemServer.
interface ISuspendCallback {
void notifyWakeup(boolean success);
}
interface ISuspendControlService {
boolean enableAutosuspend();
boolean registerCallback(ISuspendCallback callback);
boolean forceSuspend();
}
מינוף ה-HIDL של אנדרואיד מציע את היתרונות הבאים:
- אם תהליך חסימת השעיה מת, ניתן להודיע ל-SystemSuspend.
- ניתן להתקשר לשרשור האחראי על השעיית המערכת.