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