שירות השעיית מערכת

באנדרואיד 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 עוקב אחר מספר נעילות ההשקה שהונפקו עם מונה השעיה. יש לו שני חוטי ביצוע:

  • השרשור הראשי עונה לשיחות קלסר.
  • מערכת בקרות ההשעיה ההשעיה .

חוט ראשי

השרשור הראשי עונה לבקשות מלקוחות להקצות נעילות ערות חדשות, תוך הגדלה/הקטנה של מונה ההשעיה.

השעיית חוט

חוט ההשעיה מבצע את הפעולות הבאות בלולאה:

  1. קרא מתוך /sys/ power /wakeup_count .
  2. רכוש את המוטקס. זה מוודא שהחוט ההשעיה לא נוגע במונה ההשעיה בזמן שהשרשור הראשי מנסה להגדיל או להקטין אותו. השרשור הראשי נחסם בהנפקה או הסרה של נעילות התעוררות כאשר מונה ההשעיה הגיע לאפס וההפסקה מנסה לפעול.
  3. המתן עד שהמונה יהיה שווה לאפס.
  4. כתוב את הערך שנקרא מ- /sys/ power /wakeup_count (משלב 1) לקובץ זה. אם הכתיבה נכשלת, חזור לתחילת הלולאה
  5. הפעל את ההשעיה של המערכת על ידי כתיבת mem אל /sys/power/ state .
  6. שחרר את המוטקס.

כאשר בקשה לנעילת ערה חוזרת בהצלחה, שרשור ההשעיה נחסם.

איור 1. השעה לולאת חוט

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.
  • ניתן להתקשר לשרשור האחראי על השעיית המערכת.