ระบบระงับบริการ

ใน Android 9 และต่ำกว่าจะมีเธรดใน libsuspend ที่รับผิดชอบในการเริ่มต้นการระงับระบบ Android 10 แนะนำฟังก์ชันการทำงานที่เทียบเท่าในบริการ SystemSuspend HIDL บริการนี้อยู่ในอิมเมจระบบและให้บริการโดยแพลตฟอร์ม Android ตรรกะจาก libsuspend ยังคงเหมือนเดิมเป็นส่วนใหญ่ ยกเว้นทุกกระบวนการของพื้นที่ผู้ใช้ที่บล็อกการระงับระบบจำเป็นต้องสื่อสารกับ SystemSuspend

libsuspend และ libpower

ใน Android 10 บริการ SystemSuspend จะแทนที่ libsuspend libpower ได้รับการปรับใช้ใหม่เพื่อใช้บริการ SystemSuspend แทน /sys/ power /wake[un]lock โดยไม่ต้องเปลี่ยน C API

โค้ดเทียมนี้แสดงวิธีการใช้ 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
  • ระบบควบคุมเธรด แบบ Suspend ถูกระงับ

กระทู้หลัก

เธรดหลักตอบคำขอจากไคลเอ็นต์เพื่อจัดสรรการล็อกการทำงานใหม่ เพิ่ม/ลดตัวนับการระงับ

ระงับเธรด

เธรดที่ระงับดำเนินการต่อไปนี้ในวง:

  1. อ่านจาก /sys/ power /wakeup_count
  2. รับ mutex เพื่อให้แน่ใจว่าเธรดที่หยุดชั่วคราวไม่ได้สัมผัสตัวนับที่หยุดชั่วคราวในขณะที่เธรด หลัก กำลังพยายามเพิ่มหรือลดค่า เธรด หลัก ถูกบล็อกในการออกหรือเอาล็อกการปลุกเมื่อตัวนับการหยุดทำงานชั่วคราวถึงศูนย์ และเธรด การหยุดทำงาน กำลังพยายามเรียกใช้
  3. รอจนกระทั่งตัวนับมีค่าเท่ากับศูนย์
  4. เขียนค่าที่อ่านจาก /sys/ power /wakeup_count (จากขั้นตอนที่ 1) ลงในไฟล์นี้ หากการเขียนล้มเหลว ให้กลับไปยังจุดเริ่มต้นของลูป
  5. เริ่มระบบหยุดชั่วคราวโดยการเขียน mem ไปที่ /sys/power/ state
  6. ปล่อยมิวเท็กซ์

เมื่อการร้องขอการล็อกปลุกกลับสำเร็จ เธรดที่ระงับจะถูกบล็อก

รูปที่ 1. ระงับการวนซ้ำของเธรด

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 ซึ่งอนุญาตให้ไคลเอนต์หลายรายใช้ 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 จะได้รับแจ้ง
  • เธรดที่รับผิดชอบในการระงับระบบสามารถได้รับการติดต่อกลับ