خدمة SystemSuspend

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

libsuspend وlibpower

في الإصدار 10 من Android، تحلّ خدمة 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 عدد أقفال التنبيه التي تم إصدارها باستخدام عدّاد تعليق. وتتضمّن سلسلتَي تعليمات للتنفيذ:

  • تردّ سلسلة التعليمات الرئيسية على طلبات الرابط.
  • تتحكّم سلسلة تعليمات التعليق في تعليق النظام.

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

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

سلسلة تعليمات التعليق

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

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

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

الشكل 1. حلقة سلسلة تعليمات التعليق

SystemSuspend API

تتألّف 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

من المفترض أن تستخدم SystemServer فقط واجهة ISuspendControlService.


interface ISuspendCallback {
     void notifyWakeup(boolean success);
}

interface ISuspendControlService {
    boolean enableAutosuspend();
    boolean registerCallback(ISuspendCallback callback);
    boolean forceSuspend();
}

توفّر الاستفادة من Android HIDL المزايا التالية:

  • إذا توقّفت عملية تحظر التعليق، يمكن إشعار SystemSuspend.
  • يمكن منح سلسلة التعليمات المسؤولة عن تعليق النظام رد اتصال.