সিস্টেম সাসপেন্ড পরিষেবা

অ্যান্ড্রয়েড ৯ এবং এর পূর্ববর্তী সংস্করণগুলোতে libsuspend- এ একটি থ্রেড থাকে যা সিস্টেম সাসপেন্ড শুরু করার জন্য দায়ী। অ্যান্ড্রয়েড ১০-এ SystemSuspend HIDL সার্ভিসের মাধ্যমে একটি সমতুল্য কার্যকারিতা চালু করা হয়েছে। এই সার্ভিসটি সিস্টেম ইমেজে অবস্থিত এবং অ্যান্ড্রয়েড প্ল্যাটফর্ম দ্বারা পরিবেশিত হয়। libsuspend এর লজিক মূলত একই থাকে, তবে পার্থক্য হলো, সিস্টেম সাসপেন্ডকে বাধা দেয় এমন প্রতিটি ইউজারস্পেস প্রসেসকে SystemSuspend-এর সাথে যোগাযোগ করতে হয়।

libsuspend এবং libpower

অ্যান্ড্রয়েড ১০-এ, 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 (ধাপ ১ থেকে) থেকে পড়া মানটি এই ফাইলে লিখুন। যদি লেখা ব্যর্থ হয়, তাহলে লুপের শুরুতে ফিরে যান।
  5. /sys/power/ state ফাইলে mem লিখে সিস্টেম সাসপেন্ড শুরু করুন।
  6. মিউটেক্সটি মুক্ত করুন।

যখন ওয়েক লকের জন্য করা অনুরোধ সফলভাবে ফেরত আসে, তখন সাসপেন্ড থ্রেডটি ব্লক হয়ে যায়।

চিত্র ১. সাসপেন্ড থ্রেড লুপ

সিস্টেমসাসপেন্ড এপিআই

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();
}

অ্যান্ড্রয়েড HIDL ব্যবহারের নিম্নলিখিত সুবিধাগুলো রয়েছে:

  • যদি কোনো সাসপেন্ড-ব্লকিং প্রসেস বন্ধ হয়ে যায়, তাহলে SystemSuspend-কে জানানো যেতে পারে।
  • সিস্টেম সাসপেন্ডের জন্য দায়ী থ্রেডটিকে একটি কলব্যাক দেওয়া যেতে পারে।