Layanan SystemSuspend

Di Android 9 dan lebih rendah ada thread di libsuspend yang bertanggung jawab untuk memulai penangguhan sistem. Android 10 memperkenalkan fungsionalitas yang setara dalam layanan SystemSuspend HIDL. Layanan ini terletak di image sistem dan dilayani 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 kembali untuk mengandalkan layanan SystemSuspend alih-alih /sys/ power /wake[un]lock tanpa mengubah C API.

Pseudocode ini menunjukkan cara mengimplementasikan 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. Ini memiliki dua utas eksekusi:

  • Thread utama menjawab panggilan pengikat.
  • Thread penangguhan mengontrol penangguhan sistem.

Utas utama

Thread utama menjawab permintaan dari klien untuk mengalokasikan penguncian layar saat aktif baru, menambah/mengurangi penghitung penangguhan.

Tangguhkan utas

Thread penangguhan melakukan hal berikut dalam satu lingkaran:

  1. Baca dari /sys/ power /wakeup_count .
  2. Dapatkan mutexnya. Hal ini memastikan bahwa thread penangguhan tidak menyentuh penghitung penangguhan saat thread utama mencoba menambah atau menguranginya. Thread utama diblokir saat mengeluarkan atau menghapus penguncian layar saat aktif ketika penghitung penangguhan telah mencapai nol dan thread penangguhan mencoba dijalankan.
  3. Tunggu hingga penghitungnya sama dengan nol.
  4. Tulis nilai yang dibaca dari /sys/ power /wakeup_count (dari langkah 1) ke file ini. Jika penulisan gagal, kembali ke awal perulangan
  5. Mulai penangguhan sistem dengan menulis mem ke /sys/power/ state .
  6. Lepaskan mutexnya.

Ketika permintaan untuk penguncian layar saat aktif berhasil dikembalikan, thread penangguhan diblokir.

Gambar 1. Tangguhkan loop benang

API Penangguhan Sistem

SystemSuspend API terdiri dari dua antarmuka. Antarmuka HIDL digunakan oleh proses asli untuk memperoleh penguncian layar saat 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 penguncian layar saat aktif akan menerima instans IWakeLock unik. Ini berbeda dengan /sys/ power /wake_lock , yang memungkinkan beberapa klien menggunakan penguncian layar saat aktif dengan nama yang sama. Jika klien yang memegang instans IWakeLock berakhir, driver pengikat 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 Android HIDL menawarkan manfaat berikut:

  • Jika proses pemblokiran penangguhan mati, SystemSuspend dapat diberitahukan.
  • Thread yang bertanggung jawab atas penangguhan sistem dapat diberikan panggilan balik.