Android 9 और उससे पहले के वर्शन में, libsuspend में एक थ्रेड होती है. यह सिस्टम को निलंबित करने की प्रोसेस शुरू करती है. Android 10 में, SystemSuspend HIDL सेवा में मिलती-जुलती सुविधा उपलब्ध कराई गई है.
यह सेवा, सिस्टम इमेज में मौजूद होती है और इसे Android प्लैटफ़ॉर्म से उपलब्ध कराया जाता है.
libsuspend
के लॉजिक में ज़्यादा बदलाव नहीं हुआ है. हालांकि, सिस्टम को निलंबित करने से रोकने वाली हर यूज़रस्पेस प्रोसेस को SystemSuspend के साथ कम्यूनिकेट करना होगा.
libsuspend और libpower
Android 10 में, SystemSuspend सेवा,
libsuspend
की जगह ले लेती है. C API में बदलाव किए बिना, libpower
को फिर से लागू किया गया, ताकि /sys/power/wake[un]lock
के बजाय, SystemSuspend सेवा पर भरोसा किया जा सके.
इस स्यूडोकोड में, 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 सेवा, सस्पेंड काउंटर की मदद से जारी किए गए वेक लॉक की संख्या को ट्रैक करती है. इसमें दो थ्रेड होती हैं:
- मुख्य थ्रेड, बाइंडर कॉल का जवाब देती है.
- suspend थ्रेड, सिस्टम के निलंबन को कंट्रोल करता है.
मुख्य थ्रेड
मुख्य थ्रेड, नए वेक लॉक को असाइन करने के लिए क्लाइंट के अनुरोधों का जवाब देता है. साथ ही, यह निलंबन काउंटर को बढ़ाता/घटाता है.
थ्रेड को निलंबित करना
निलंबित की गई थ्रेड, लूप में ये काम करती है:
/sys/power/wakeup_count
पढ़ें.- म्यूटेक्स पाएं. इससे यह पक्का होता है कि मुख्य थ्रेड, रोके जाने की संख्या को बढ़ाने या घटाने की कोशिश करते समय, रोके जाने की थ्रेड उस पर असर न डाले. निलंबन काउंटर शून्य पर पहुंचने और निलंबित करें थ्रेड के चलने की कोशिश करने पर, मुख्य थ्रेड को ब्लॉक कर दिया जाता है. ऐसा, वेक लॉक जारी करने या हटाने पर होता है.
- काउंटर के शून्य के बराबर होने तक इंतज़ार करें.
- पहले चरण में
/sys/power /wakeup_count
से पढ़ी गई वैल्यू को इस फ़ाइल में लिखें. अगर डेटा नहीं लिखा जा सका, तो लूप की शुरुआत पर वापस जाएं /sys/power/state
परmem
लिखकर सिस्टम को निलंबित करना शुरू करें.- म्यूटेक्स को छोड़ें.
जब वेक लॉक का अनुरोध पूरा हो जाता है, तो निलंबित की गई थ्रेड को ब्लॉक कर दिया जाता है.
SystemSuspend API
SystemSuspend API में दो इंटरफ़ेस होते हैं. नेटिव प्रोसेस, वॉकी लॉक पाने के लिए HIDL इंटरफ़ेस का इस्तेमाल करती हैं. वहीं, SystemServer और SystemSuspend के बीच कम्यूनिकेशन के लिए, AIDL इंटरफ़ेस का इस्तेमाल किया जाता है.
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 इंटरफ़ेस
IनिलंबितControlService का इस्तेमाल सिर्फ़ SystemServer के लिए किया गया है.
interface ISuspendCallback {
void notifyWakeup(boolean success);
}
interface ISuspendControlService {
boolean enableAutosuspend();
boolean registerCallback(ISuspendCallback callback);
boolean forceSuspend();
}
Android HIDL का इस्तेमाल करने पर ये फ़ायदे मिलते हैं:
- अगर निलंबन को रोकने वाली कोई प्रोसेस बंद हो जाती है, तो SystemSuspend को इसकी सूचना दी जा सकती है.
- सिस्टम को निलंबित करने वाली थ्रेड को कॉलबैक दिया जा सकता है.