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