ב-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 מושעה מבצע את הפעולות הבאות בלולאה:
- הקראה מ-
/sys/power/wakeup_count
. - עליך להשיג את mutex. זה מוודא שהשרשור המושעה לא נוגע מונה ההשעיה בזמן שה-thread הראשי מנסה להגדיל או להקטין אותו. ה-thread הראשי חסום הוצאה או הסרה של חסימות מצב שינה כשמונה ההשעיה מגיע לאפס וה-thread ההשעיה מנסה לפעול.
- ממתינים עד שהמונה יהיה שווה לאפס.
- צריך לכתוב את הערך שנקרא מ-
/sys/power /wakeup_count
(משלב 1) לקובץ הזה. אם הכתיבה נכשלה, חוזרים לתחילת הלולאה - כדי להפעיל את השעיית המערכת, כותבים
mem
עד/sys/power/state
. - משחררים את ההשתקה.
כשבקשה לנעילת מצב שינה חוזרת, שרשור ההשעיה חסמת.
ממשק 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 מעניק את היתרונות הבאים:
- אם תהליך חסימה של השעיה פג, המערכת יכולה לקבל הודעה על כך.
- אפשר לתת קריאה חוזרת לשרשור שאחראי להשעיית המערכת.