Servicio SystemSuspend

En Android 9 y versiones anteriores, hay un subproceso en libsuspend. de iniciar la suspensión del sistema. Android 10 se presenta una funcionalidad equivalente en un servicio SystemSuspend HIDL. Este servicio se encuentra en la imagen del sistema y lo proporciona la plataforma de Android. La lógica de libsuspend sigue siendo casi la misma, excepto que en todos los espacios de usuario el proceso que bloquea la suspensión del sistema debe comunicarse con SystemSuspend.

libsuspend y libpower

En Android 10, el servicio SystemSuspend reemplaza libsuspend Se volvió a implementar libpower en función de lo siguiente: el servicio SystemSuspend en lugar de /sys/power/wake[un]lock sin cambiar la API de C.

En este pseudocódigo, se muestra cómo implementar acquire_wake_lock. y 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;
}

Subprocesos de ejecución

El servicio SystemSuspend lleva un registro del número de bloqueos de activación emitidos por un contador de suspensión. Tiene dos subprocesos de ejecución:

  • El subproceso main responde a las llamadas de Binder.
  • El subproceso suspend controla la suspensión del sistema.

Subproceso principal

El subproceso principal responde las solicitudes de los clientes para asignar nuevos bloqueos de activación aumentando o disminuyendo el contador de suspensión.

Suspender conversación

El subproceso de suspensión realiza lo siguiente dentro de un bucle:

  1. Leer desde /sys/power/wakeup_count.
  2. Adquiere la exclusión mutua. Esto garantiza que el subproceso de suspensión no se toque el contador de suspensión mientras el subproceso main intenta aumentarlo o disminuirlo. El subproceso main está bloqueado para emitir o quitar bloqueos de activación cuando el contador de suspensiones alcanzó cero y el subproceso suspend intenta ejecutarse.
  3. Espera hasta que el contador sea igual a cero.
  4. Escribe el valor leído de /sys/power /wakeup_count (del paso 1) en este archivo. Si la escritura falla, vuelve al principio del bucle.
  5. Para iniciar la suspensión del sistema, escribe mem en /sys/power/state
  6. Libera la exclusión mutua.

Cuando se devuelve correctamente una solicitud de bloqueo de activación, el subproceso de suspensión se se bloqueó.

Figura 1: Suspensión del bucle de subprocesos

API de SystemSuspend

La API de SystemSuspend consta de dos interfaces. Se usa la interfaz HIDL mediante procesos nativos para adquirir bloqueos de activación; además, se usa la interfaz del AIDL para la comunicación entre SystemServer y SystemSuspend.

Interfaz de HIDL de ISystemSuspend


enum WakeLockType : uint32_t {
    PARTIAL,
    FULL
};

interface IWakeLock {
    oneway release();
};

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

Cada cliente que solicita un bloqueo de activación recibe un Instancia IWakeLock. Esto es diferente de /sys/power/wake_lock, que permite varias los clientes usen el bloqueo de activación con el mismo nombre. Si un cliente que tiene un finaliza la instancia IWakeLock, el controlador de Binder y El servicio SystemSuspend lo limpia.

Interfaz del AIDL de ISuspendControlService

ISuspendControlService está diseñado para que lo use solo SystemServer.


interface ISuspendCallback {
     void notifyWakeup(boolean success);
}

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

El uso del HIDL de Android ofrece los siguientes beneficios:

  • Si un proceso de bloqueo de suspensión finaliza, se puede notificar SystemSuspend.
  • El subproceso responsable de la suspensión del sistema puede recibir una devolución de llamada.