خدمة SystemSuspend

في الإصدار 9 من نظام التشغيل Android والإصدارات الأقدم، هناك سلسلة محادثات في libsuspend مسؤولة عن بدء تعليق النظام. يقدّم نظام التشغيل Android 10 وظيفة مكافئة في خدمة SystemSuspend HIDL. تتوفّر هذه الخدمة في صورة النظام وتوفّرها منصة Android. تظلّ المنطقية من libsuspend كما هي إلى حد كبير، باستثناء أنّ كل عملية في مساحة المستخدم تحظر تعليق النظام يجب أن تتواصل مع SystemSuspend.

libsuspend وlibpower

في نظام التشغيل Android 10، تحلّ خدمة SystemSuspend محل libsuspend. تمت إعادة تنفيذ libpower للاعتماد على خدمة SystemSuspend بدلاً من /sys/power/wake[un]lock بدون تغيير واجهة برمجة التطبيقات C.

يوضّح هذا الرمز الزائف كيفية تنفيذ 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 عدد عمليات قفل التنشيط التي تم إصدارها باستخدام عدّاد التعليق. يتضمّن مسارين للتنفيذ:

  • تستجيب سلسلة التعليمات الرئيسية لطلبات Binder.
  • يتحكّم مؤشر ترابط تعليق في تعليق النظام.

سلسلة التعليمات الرئيسية

تجيب سلسلة المحادثات الرئيسية على الطلبات الواردة من العملاء لتخصيص أقفال تنبيه جديدة، مع زيادة/إنقاص عدّاد التعليق.

تعليق سلسلة المحادثات

تنفّذ سلسلة التعليمات المعلقة ما يلي في حلقة:

  1. قراءة الرسالة من /sys/power/wakeup_count
  2. احصل على mutex. يضمن ذلك ألا تتأثر سلسلة التعليمات المعلقة بعداد التعليق أثناء محاولة سلسلة التعليمات الرئيسية زيادة العداد أو إنقاصه. تم حظر سلسلة التعليمات الرئيسية عند إصدار أو إزالة أقفال التنشيط عندما وصل عدّاد التعليق إلى الصفر وتحاول سلسلة التعليمات تعليق التشغيل.
  3. انتظِر إلى أن يصبح العداد مساويًا للصفر.
  4. اكتب القيمة التي تمّت قراءتها من /sys/power /wakeup_count (من الخطوة 1) في هذا الملف. إذا تعذّر الكتابة، ارجع إلى بداية الحلقة
  5. ابدأ تعليق النظام مؤقتًا بكتابة mem إلى /sys/power/state.
  6. حرِّر mutex.

عندما يعود طلب قفل التنشيط بنجاح، يتم حظر سلسلة تعليق التنفيذ.

الشكل 1. Suspend thread loop

SystemSuspend API

تتألف واجهة برمجة التطبيقات SystemSuspend من واجهتَين. تستخدم العمليات الأصلية واجهة 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 بذلك.
  • يمكن منح سلسلة التعليمات المسؤولة عن تعليق النظام وظيفة ردّ الاتصال.