שירות Systemהשעיה של שירות

ב-Android 9 ומטה יש שרשור ב-lib שמירה אחראי לביצוע השעיית המערכת. 10 Android מציגה פונקציונליות מקבילה בשירות Systemsuspended HIDL. השירות הזה נמצא בתמונת המערכת ומתקבל באמצעות פלטפורמת Android. הלוגיקה של libsuspend כמעט זהה, למעט כל מרחב המשתמשים חסימה של השעיית המערכת צריכה לתקשר עם Systemsuspended.

libtapend ו-libpower

ב-Android 10, השירות System הנוגעות מחליף libsuspend בוצעה הטמעה מחדש של libpower כדי להסתמך על השירות Systemsuspended במקום /sys/power/wake[un]lock בלי לשנות את C API.

הקוד המדומה הזה מראה איך להטמיע את 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;
}

שרשורי ביצוע

השירות SystemDisallow עוקב אחר מספר חסימות מצב השינה שנוצרו באמצעות מונה השעיה. יש בו שני שרשורי הפעלה:

  • ה-thread הראשי עונה לקריאות של binder.
  • השעיה של מערכת ההשעיה של אמצעי הבקרה לשרשורים.

Thread ראשי

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

השעיית השרשור

ה-thread מושעה מבצע את הפעולות הבאות בלולאה:

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

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

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

ממשק API של Systemהשעיית API

ה-System suspended API מורכב משני ממשקים. נעשה שימוש בממשק HIDL באמצעות תהליכים נייטיב ליצירת חסימות מצב שינה, וממשק AIDL משמש תקשורת בין SystemServer ל-Systemsuspended.

ממשק ISystem suspended 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, כדי לאפשר מספר כדי לאפשר ללקוחות להשתמש ב-Wame lock עם אותו השם. אם לקוח אוחז המכונה של IWakeLock מסתיימת, מנהל ההתקן של הקישור ו שירות Systemהשעיה מנקה אותו.

ממשק IsuspendedControlService AIDL

IהשעינוControlService מיועד לשימוש רק על ידי SystemServer.


interface ISuspendCallback {
     void notifyWakeup(boolean success);
}

interface ISuspendControlService {
    boolean enableAutosuspend();
    boolean registerCallback(ISuspendCallback callback);
    boolean forceSuspend();
}

השימוש ב-Android HIDL מעניק את היתרונות הבאים:

  • אם תהליך חסימה של השעיה פג, המערכת יכולה לקבל הודעה על כך.
  • אפשר לתת קריאה חוזרת לשרשור שאחראי להשעיית המערכת.