在 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 服務會追蹤使用暫停計數器發出的喚醒鎖數量。它有兩個執行緒:
- 主執行緒會回應繫結器呼叫。
- suspend 執行緒可控制系統暫停。
主要執行緒
主執行緒會回應來自用戶端的要求,分配新的喚醒鎖定,並遞增/遞減暫停計數器。
暫停執行緒
暫停執行緒會在迴圈中執行下列操作:
- 從
/sys/power/wakeup_count
讀取。 - 取得互斥鎖。這可確保在「主」執行緒嘗試遞增或遞減時,暫停執行緒不會觸碰暫停計數器。當暫停計數器已達零,且「暫停」執行緒嘗試執行時,主執行緒會在發出或移除喚醒鎖定時遭到封鎖。
- 等待計數器等於零。
- 將從
/sys/power /wakeup_count
讀取的值 (來自步驟 1) 寫入此檔案。 如果寫入失敗,請返回迴圈的開頭 - 將
mem
寫入/sys/power/state
,啟動系統暫停。 - 釋放互斥鎖。
喚醒鎖定要求成功傳回後,系統會封鎖暫停執行緒。

SystemSuspend 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
不同,後者允許多個用戶端使用同一個名稱的喚醒鎖定。如果持有 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 可以收到通知。
- 負責系統暫停的執行緒可以提供回呼。