ใน 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 ถูกระงับ
กระทู้หลัก
เธรดหลักตอบคำขอจากไคลเอ็นต์เพื่อจัดสรรการล็อกการทำงานใหม่ เพิ่ม/ลดตัวนับการระงับ
ระงับเธรด
เธรดที่ระงับดำเนินการต่อไปนี้ในวง:
- อ่านจาก
/sys/ power /wakeup_count
- รับ mutex เพื่อให้แน่ใจว่าเธรดที่หยุดชั่วคราวไม่ได้สัมผัสตัวนับที่หยุดชั่วคราวในขณะที่เธรด หลัก กำลังพยายามเพิ่มหรือลดค่า เธรด หลัก ถูกบล็อกในการออกหรือเอาล็อกการปลุกเมื่อตัวนับการหยุดทำงานชั่วคราวถึงศูนย์ และเธรด การหยุดทำงาน กำลังพยายามเรียกใช้
- รอจนกระทั่งตัวนับมีค่าเท่ากับศูนย์
- เขียนค่าที่อ่านจาก
/sys/ power /wakeup_count
(จากขั้นตอนที่ 1) ลงในไฟล์นี้ หากการเขียนล้มเหลว ให้กลับไปยังจุดเริ่มต้นของลูป - เริ่มระบบหยุดชั่วคราวโดยการเขียน
mem
ไปที่/sys/power/ state
- ปล่อยมิวเท็กซ์
เมื่อการร้องขอการล็อกปลุกกลับสำเร็จ เธรดที่ระงับจะถูกบล็อก
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 จะได้รับแจ้ง
- เธรดที่รับผิดชอบในการระงับระบบสามารถได้รับการติดต่อกลับ