ใน Android 9 และต่ำกว่า จะมีเธรดใน libsuspend ที่รับผิดชอบในการเริ่มการระงับระบบ Android 10 ได้เปิดตัวฟังก์ชันการทำงานที่เทียบเท่าในบริการ SystemSuspend HIDL
บริการนี้อยู่ในภาพระบบและแสดงโดยแพลตฟอร์ม Android
ตรรกะจาก libsuspend
ยังคงเหมือนเดิมเกือบทั้งหมด ยกเว้นกระบวนการทุกรายการใน Userspace ที่บล็อกการระงับระบบต้องสื่อสารกับ 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 จะติดตามจํานวนการล็อกการปลุกที่ออกมาพร้อมกับตัวนับการระงับ การดำเนินการมี 2 เทรด ดังนี้
- เทรดหลักจะตอบกลับการเรียก Binder
- ด้าย suspend จะควบคุมการระงับระบบ
เทรดหลัก
เทรดหลักจะตอบคําขอจากไคลเอ็นต์เพื่อจัดสรร Wake Lock ใหม่ โดยเพิ่ม/ลดตัวนับการระงับ
ระงับชุดข้อความ
ด้ายที่หยุดชั่วคราวจะดำเนินการต่อไปนี้ในลูป
- อ่านจาก
/sys/power/wakeup_count
- รับ Mutex วิธีนี้ช่วยให้มั่นใจได้ว่าเธรดการระงับจะไม่แตะตัวนับการระงับขณะที่เธรดหลักพยายามเพิ่มหรือลดตัวนับ เทรดหลักถูกบล็อกไม่ให้ออกหรือนำล็อกการปลุกออกเมื่อตัวนับการหยุดทำงานถึง 0 และเทรดหยุดทำงานพยายามทำงาน
- รอจนกว่าตัวนับจะเท่ากับ 0
- เขียนค่าที่อ่านจาก
/sys/power /wakeup_count
(จากขั้นตอนที่ 1) ลงในไฟล์นี้ หากการเขียนไม่สำเร็จ ให้กลับไปที่จุดเริ่มต้นของลูป - เริ่มการระงับระบบโดยเขียน
mem
ไปยัง/sys/power/state
- ปล่อยมิวเทค
เมื่อคำขอการล็อกการปลุกแสดงผลสำเร็จ ด้ายที่หยุดชั่วคราวจะบล็อก

SystemSuspend API
SystemSuspend API ประกอบด้วยอินเทอร์เฟซ 2 รายการ อินเทอร์เฟซ 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
สิ้นสุดลง โปรแกรมควบคุม Binder และบริการ SystemSuspend จะล้างข้อมูลดังกล่าว
อินเทอร์เฟซ AIDL ของ ISuspendControlService
ISuspendControlService มีไว้สำหรับการใช้งานโดย SystemServer เท่านั้น
interface ISuspendCallback {
void notifyWakeup(boolean success);
}
interface ISuspendControlService {
boolean enableAutosuspend();
boolean registerCallback(ISuspendCallback callback);
boolean forceSuspend();
}
การใช้ Android HIDL มีประโยชน์ดังต่อไปนี้
- หากกระบวนการบล็อกการระงับหยุดทำงาน SystemSuspend จะได้รับแจ้ง
- คุณสามารถเรียกกลับชุดข้อความที่รับผิดชอบการระงับระบบได้