ใน 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 จะติดตามจำนวน Wake Lock ที่ออกโดยใช้ ตัวนับการระงับ โดยมี 2 เธรดของการดำเนินการ ดังนี้
- เทรดหลักจะตอบการเรียกใช้ Binder
- เธรด suspend จะควบคุมการระงับระบบ
เทรดหลัก
เทรดหลักจะตอบคำขอจากไคลเอ็นต์เพื่อจัดสรร Wake Lock ใหม่ เพิ่ม/ลดตัวนับการระงับ
ระงับชุดข้อความ
เธรดระงับจะดำเนินการต่อไปนี้ในลูป
- อ่านจาก
/sys/power/wakeup_count - รับ Mutex ซึ่งช่วยให้มั่นใจว่าเธรดที่ระงับจะไม่แตะต้อง ตัวนับการระงับในขณะที่เธรดหลักพยายาม เพิ่มหรือลดค่า เทรดหลักถูกบล็อก เมื่อออกหรือนำ Wake Lock ออกเมื่อตัวนับการระงับเป็น 0 และเทรดระงับพยายามเรียกใช้
- รอจนกว่าตัวนับจะเท่ากับ 0
- เขียนค่าที่อ่านจาก
/sys/power /wakeup_count(จากขั้นตอนที่ 1) ลงในไฟล์นี้ หากการเขียนไม่สำเร็จ ให้กลับไปที่จุดเริ่มต้นของลูป - เริ่มการระงับระบบโดยเขียน
memไปยัง/sys/power/state - ปล่อย Mutex
เมื่อคำขอสำหรับ Wake Lock แสดงผลสำเร็จ ระบบจะบล็อกเธรดระงับ
SystemSuspend API
SystemSuspend API ประกอบด้วยอินเทอร์เฟซ 2 รายการ กระบวนการดั้งเดิมใช้ HIDL เพื่อรับ Wake Lock และใช้ AIDL เพื่อสื่อสารระหว่าง SystemServer กับ SystemSuspend
อินเทอร์เฟซ HIDL ของ ISystemSuspend
enum WakeLockType : uint32_t {
PARTIAL,
FULL
};
interface IWakeLock {
oneway release();
};
interface ISystemSuspend {
acquireWakeLock(WakeLockType type, string debugName)
generates (IWakeLock lock);
};
ไคลเอ็นต์แต่ละรายที่ขอ Wake Lock จะได้รับอินสแตนซ์IWakeLockที่ไม่ซ้ำกัน
ซึ่งแตกต่างจาก
/sys/power/wake_lockที่อนุญาตให้ไคลเอ็นต์หลายราย
ใช้ Wake Lock ภายใต้ชื่อเดียวกัน หากไคลเอ็นต์ที่มีอินสแตนซ์
IWakeLockสิ้นสุดลง ไดรเวอร์ Binder และบริการ
SystemSuspend จะล้างข้อมูล
อินเทอร์เฟซ AIDL ของ ISuspendControlService
ISuspendControlService มีไว้สำหรับใช้โดย SystemServer เท่านั้น
interface ISuspendCallback {
void notifyWakeup(boolean success);
}
interface ISuspendControlService {
boolean enableAutosuspend();
boolean registerCallback(ISuspendCallback callback);
boolean forceSuspend();
}
การใช้ประโยชน์จาก HIDL ของ Android มีข้อดีดังนี้
- หากกระบวนการบล็อกการระงับสิ้นสุดลง SystemSuspend จะได้รับการแจ้งเตือน
- สามารถกำหนดให้มีการเรียกกลับสำหรับเธรดที่รับผิดชอบการระงับระบบได้