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:
- Leer desde
/sys/power/wakeup_count
. - 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.
- Espera hasta que el contador sea igual a cero.
- 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. - Para iniciar la suspensión del sistema, escribe
mem
en/sys/power/state
- Libera la exclusión mutua.
Cuando se devuelve correctamente una solicitud de bloqueo de activación, el subproceso de suspensión se se bloqueó.
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 se detiene un proceso de bloqueo de suspensión, se puede notificar SystemSuspend.
- El subproceso responsable de la suspensión del sistema puede recibir una devolución de llamada.