النظام تعليق الخدمة

في نظام التشغيل Android 9 والإصدارات الأقدم، يوجد مؤشر ترابط في 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 بتتبع عدد عمليات قفل التنبيه الصادرة باستخدام عداد التعليق المرحلي. لديها موضوعين للتنفيذ:

  • يجيب الخيط الرئيسي على مكالمات الموثق.
  • يتحكم نظام تعليق الخيط في التعليق.

موضوع الرئيسي

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

تعليق الخيط

ينفذ مؤشر الترابط المرحلي ما يلي في حلقة:

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

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

الشكل 1. تعليق حلقة الخيط

واجهة برمجة التطبيقات SystemSuspend

تتكون واجهة 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.
  • يمكن إعطاء مؤشر الترابط المسؤول عن تعليق النظام رد اتصال.