Servizio SystemSuspend

In Android 9 e versioni precedenti è presente un thread in libsuspend responsabile dell'avvio della sospensione del sistema. Android 10 introduce una funzionalità equivalente in un servizio SystemSuspend HIDL. Questo servizio si trova nell'immagine del sistema ed è servito dalla piattaforma Android. La logica di libsuspend rimane sostanzialmente la stessa, tranne che ogni processo dello spazio utente che blocca la sospensione del sistema deve comunicare con SystemSuspend.

libsuspend e libpower

In Android 10, il servizio SystemSuspend sostituisce libsuspend . libpower è stato reimplementato per fare affidamento sul servizio SystemSuspend invece che su /sys/ power /wake[un]lock senza modificare l'API C.

Questo pseudocodice mostra come implementare acquire_wake_lock e 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 di esecuzione

Il servizio SystemSuspend tiene traccia del numero di wakelock emessi con un contatore di sospensione. Ha due thread di esecuzione:

  • Il thread principale risponde alle chiamate del raccoglitore.
  • Il thread di sospensione controlla la sospensione del sistema.

Filo principale

Il thread principale risponde alle richieste dei client di allocare nuovi wakelock, incrementando/diminuendo il contatore di sospensione.

Sospendere il thread

Il thread di sospensione esegue quanto segue in un ciclo:

  1. Leggi da /sys/ power /wakeup_count .
  2. Acquisisci il mutex. Ciò garantisce che il thread di sospensione non tocchi il contatore di sospensione mentre il thread principale tenta di incrementarlo o decrementarlo. Il thread principale viene bloccato durante l'emissione o la rimozione dei wakelock quando il contatore di sospensione ha raggiunto lo zero e il thread di sospensione sta tentando di essere eseguito.
  3. Attendere finché il contatore non sarà uguale a zero.
  4. Scrivere il valore letto da /sys/ power /wakeup_count (dal passaggio 1) in questo file. Se la scrittura fallisce, torna all'inizio del ciclo
  5. Avvia la sospensione del sistema scrivendo mem in /sys/power/ state .
  6. Rilascia il mutex.

Quando una richiesta per un wakelock ritorna con successo, il thread di sospensione viene bloccato.

Figura 1. Sospendere il loop del thread

API SystemSuspend

L'API SystemSuspend è composta da due interfacce. L'interfaccia HIDL viene utilizzata dai processi nativi per acquisire wakelock e l'interfaccia AIDL viene utilizzata per la comunicazione tra SystemServer e SystemSuspend.

Interfaccia HIDL ISystemSuspend


enum WakeLockType : uint32_t {
    PARTIAL,
    FULL
};

interface IWakeLock {
    oneway release();
};

interface ISystemSuspend {
    acquireWakeLock(WakeLockType type, string debugName)
        generates (IWakeLock lock);
};

Ogni client che richiede un wakelock riceve un'istanza IWakeLock univoca. Questo è diverso da /sys/ power /wake_lock , che consente a più client di utilizzare il wakelock con lo stesso nome. Se un client che contiene un'istanza IWakeLock termina, il driver del raccoglitore e il servizio SystemSuspend lo puliscono.

Interfaccia AIDL ISuspendControlService

ISuspendControlService è destinato a essere utilizzato solo da SystemServer.


interface ISuspendCallback {
     void notifyWakeup(boolean success);
}

interface ISuspendControlService {
    boolean enableAutosuspend();
    boolean registerCallback(ISuspendCallback callback);
    boolean forceSuspend();
}

L'utilizzo di Android HIDL offre i seguenti vantaggi:

  • Se un processo di blocco della sospensione termina, è possibile ricevere una notifica su SystemSuspend.
  • È possibile richiamare il thread responsabile della sospensione del sistema.