Trong Android 9 trở xuống, có một luồng trong libsuspend chịu trách nhiệm khởi tạo quá trình tạm ngưng hệ thống. Android 10 giới thiệu một chức năng tương đương trong dịch vụ SystemSuspend HIDL.
Dịch vụ này nằm trong hình ảnh hệ thống và do nền tảng Android cung cấp.
Logic từ libsuspend
phần lớn vẫn giữ nguyên, ngoại trừ mọi quy trình chặn hệ thống tạm ngưng của không gian người dùng cần giao tiếp với SystemSuspend.
libsuspend và libpower
Trong Android 10, dịch vụ SystemSuspend sẽ thay thế libsuspend
. libpower
được triển khai lại để dựa vào dịch vụ SystemSuspend thay vì /sys/power/wake[un]lock
mà không thay đổi C API.
Mã giả này cho biết cách triển khai acquire_wake_lock
và 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;
}
Luồng thực thi
Dịch vụ SystemSuspend theo dõi số lượng khoá đánh thức được phát hành bằng bộ đếm tạm ngưng. Nó có 2 luồng thực thi:
- Luồng chính trả lời các lệnh gọi liên kết.
- Luồng suspend kiểm soát trạng thái tạm ngưng của hệ thống.
Luồng chính
Luồng chính trả lời các yêu cầu của ứng dụng để phân bổ khoá đánh thức mới, tăng/giảm bộ đếm tạm ngưng.
Tạm ngưng chuỗi
Luồng tạm ngưng thực hiện những thao tác sau trong một vòng lặp:
- Đọc từ
/sys/power/wakeup_count
. - Thu nạp mutex. Điều này đảm bảo rằng luồng tạm ngưng không chạm vào bộ đếm tạm ngưng trong khi luồng main đang cố gắng tăng hoặc giảm bộ đếm đó. Luồng chính bị chặn khi phát hành hoặc xoá khoá đánh thức khi bộ đếm tạm ngưng đạt đến 0 và luồng tạm ngưng đang cố gắng chạy.
- Chờ cho đến khi bộ đếm bằng 0.
- Ghi giá trị đọc được từ
/sys/power /wakeup_count
(từ bước 1) vào tệp này. Nếu thao tác ghi không thành công, hãy quay lại đầu vòng lặp - Bắt đầu quá trình tạm ngưng hệ thống bằng cách ghi
mem
vào/sys/power/state
. - Giải phóng mutex.
Khi một yêu cầu khoá đánh thức trả về thành công, luồng tạm ngưng sẽ bị chặn.

SystemSuspend API
SystemSuspend API bao gồm 2 giao diện. Các quy trình gốc sử dụng giao diện HIDL để lấy khoá đánh thức và giao diện AIDL được dùng để giao tiếp giữa SystemServer và SystemSuspend.
Giao diện HIDL ISystemSuspend
enum WakeLockType : uint32_t {
PARTIAL,
FULL
};
interface IWakeLock {
oneway release();
};
interface ISystemSuspend {
acquireWakeLock(WakeLockType type, string debugName)
generates (IWakeLock lock);
};
Mỗi ứng dụng yêu cầu khoá đánh thức sẽ nhận được một thực thể IWakeLock
duy nhất. Điều này khác với /sys/power/wake_lock
, cho phép nhiều ứng dụng sử dụng khoá đánh thức có cùng tên. Nếu một ứng dụng khách giữ phiên bản IWakeLock
kết thúc, trình điều khiển liên kết và dịch vụ SystemSuspend sẽ dọn dẹp phiên bản đó.
Giao diện ISuspendControlService AIDL
ISuspendControlService chỉ dành cho SystemServer.
interface ISuspendCallback {
void notifyWakeup(boolean success);
}
interface ISuspendControlService {
boolean enableAutosuspend();
boolean registerCallback(ISuspendCallback callback);
boolean forceSuspend();
}
Việc tận dụng HIDL của Android mang lại những lợi ích sau:
- Nếu một quy trình chặn tạm ngưng bị tắt, SystemSuspend có thể được thông báo.
- Bạn có thể cung cấp một lệnh gọi lại cho luồng chịu trách nhiệm tạm ngưng hệ thống.