Di Android 9 dan yang lebih lama, ada thread di libsuspend
yang bertanggung jawab untuk memulai penangguhan sistem. Android 10
memperkenalkan fungsi yang setara dalam layanan HIDL SystemSuspend.
Layanan ini terletak di image sistem dan ditayangkan oleh platform Android.
Logika dari libsuspend
sebagian besar tetap sama, kecuali setiap proses
ruang pengguna yang memblokir penangguhan sistem perlu berkomunikasi dengan SystemSuspend.
libsuspend dan libpower
Di Android 10, layanan SystemSuspend menggantikan
libsuspend
. libpower
diimplementasikan ulang untuk mengandalkan layanan SystemSuspend, bukan /sys/power/wake[un]lock
, tanpa mengubah C API.
Kode semu ini menunjukkan cara menerapkan acquire_wake_lock
dan 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;
}
Thread eksekusi
Layanan SystemSuspend melacak jumlah penguncian layar saat aktif yang dikeluarkan dengan penghitung penangguhan. Proses ini memiliki dua thread eksekusi:
- Thread utama menjawab panggilan binder.
- Thread suspend mengontrol penangguhan sistem.
Thread utama
Thread utama menjawab permintaan dari klien untuk mengalokasikan kunci aktif baru, menambah/mengurangi penghitung penangguhan.
Menangguhkan rangkaian pesan
Thread yang ditangguhkan melakukan hal berikut dalam loop:
- Baca dari
/sys/power/wakeup_count
. - Dapatkan mutex. Hal ini memastikan bahwa thread penangguhan tidak menyentuh penghitung penangguhan saat thread utama mencoba menaikkan atau menurunkannya. Thread utama diblokir saat mengeluarkan atau menghapus kunci tetap aktif saat penghitung penangguhan telah mencapai nol dan thread penangguhan mencoba berjalan.
- Tunggu hingga penghitung sama dengan nol.
- Tulis nilai yang dibaca dari
/sys/power /wakeup_count
(dari langkah 1) ke file ini. Jika penulisan gagal, kembali ke awal loop - Mulai penangguhan sistem dengan menulis
mem
ke/sys/power/state
. - Lepaskan mutex.
Saat permintaan penguncian layar saat aktif berhasil ditampilkan, thread penangguhan diblokir.

SystemSuspend API
SystemSuspend API terdiri dari dua antarmuka. Antarmuka HIDL digunakan oleh proses native untuk mendapatkan kunci aktif dan antarmuka AIDL digunakan untuk komunikasi antara SystemServer dan SystemSuspend.
Antarmuka HIDL ISystemSuspend
enum WakeLockType : uint32_t {
PARTIAL,
FULL
};
interface IWakeLock {
oneway release();
};
interface ISystemSuspend {
acquireWakeLock(WakeLockType type, string debugName)
generates (IWakeLock lock);
};
Setiap klien yang meminta kunci tetap aktif akan menerima instance IWakeLock
yang unik. Hal ini berbeda dengan
/sys/power/wake_lock
, yang memungkinkan beberapa
klien menggunakan kunci aktivasi dengan nama yang sama. Jika klien yang memegang instance
IWakeLock
dihentikan, driver binder dan
layanan SystemSuspend akan membersihkannya.
Antarmuka AIDL ISuspendControlService
ISuspendControlService dimaksudkan untuk digunakan hanya oleh SystemServer.
interface ISuspendCallback {
void notifyWakeup(boolean success);
}
interface ISuspendControlService {
boolean enableAutosuspend();
boolean registerCallback(ISuspendCallback callback);
boolean forceSuspend();
}
Memanfaatkan HIDL Android memberikan manfaat berikut:
- Jika proses yang memblokir penangguhan berakhir, SystemSuspend dapat diberi tahu.
- Thread yang bertanggung jawab untuk penangguhan sistem dapat diberi callback.