सिस्टम सस्पेंड सेवा

एंड्रॉइड 9 और उससे पहले के संस्करण में libsuspend में एक थ्रेड है जो सिस्टम सस्पेंड शुरू करने के लिए जिम्मेदार है। Android 10 SystemSuspend HIDL सेवा में समतुल्य कार्यक्षमता प्रस्तुत करता है। यह सेवा सिस्टम छवि में स्थित है और एंड्रॉइड प्लेटफ़ॉर्म द्वारा प्रदान की जाती है। libsuspend का तर्क काफी हद तक वही रहता है, सिवाय इसके कि सिस्टम सस्पेंड को ब्लॉक करने वाली प्रत्येक यूजरस्पेस प्रक्रिया को SystemSuspend के साथ संचार करने की आवश्यकता होती है।

libsuspend और libpower

एंड्रॉइड 10 में, SystemSuspend सेवा libsuspend जगह लेती है। C API को बदले बिना /sys/ power /wake[un]lock के बजाय SystemSuspend सेवा पर भरोसा करने के लिए libpower फिर से लागू किया गया था।

यह छद्म कोड दिखाता है कि 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. /sys/power/ state पर mem लिखकर सिस्टम सस्पेंड शुरू करें।
  6. म्यूटेक्स जारी करें.

जब वेक लॉक के लिए अनुरोध सफलतापूर्वक वापस आता है, तो सस्पेंड थ्रेड ब्लॉक हो जाता है।

चित्र 1. थ्रेड लूप को निलंबित करें

सिस्टमसस्पेंड एपीआई

SystemSuspend API में दो इंटरफ़ेस होते हैं। 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();
}

Android HIDL का लाभ उठाने से निम्नलिखित लाभ मिलते हैं:

  • यदि सस्पेंड-ब्लॉकिंग प्रक्रिया समाप्त हो जाती है, तो SystemSuspend को सूचित किया जा सकता है।
  • सिस्टम सस्पेंड के लिए जिम्मेदार थ्रेड को कॉलबैक दिया जा सकता है।