O Google tem o compromisso de promover a igualdade racial para as comunidades negras. Saiba como.
Esta página foi traduzida pela API Cloud Translation.
Switch to English

Serviço SystemSuspend

No Android 9 e inferior, há um thread em libsuspend responsável por iniciar a suspensão do sistema. O Android 10 apresenta uma funcionalidade equivalente em um serviço SystemSuspend HIDL. Este serviço está localizado na imagem do sistema e é servido pela plataforma Android. A lógica de libsuspend permanece praticamente a mesma, exceto que cada processo do espaço do usuário que bloqueia a suspensão do sistema precisa se comunicar com o SystemSuspend.

libsuspend e libpower

No Android 10, o serviço SystemSuspend substitui o libsuspend . libpower foi reimplementado para contar com o serviço SystemSuspend em vez de /sys/ power /wake[un]lock sem alterar a API C.

Este pseudocódigo mostra como implementar 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;
}

Threads de execução

O serviço SystemSuspend controla o número de wake locks emitidos com um contador de suspensão. Possui dois threads de execução:

  • O thread principal atende chamadas de fichário.
  • O encadeamento de suspensão controla a suspensão do sistema.

Tópico principal

O thread principal responde às solicitações dos clientes para alocar novos wake locks, aumentando / diminuindo o contador de suspensão.

Suspender discussão

O thread de suspensão executa o seguinte em um loop:

  1. Leia em /sys/ power /wakeup_count .
  2. Adquira o mutex. Isso garante que o encadeamento suspenso não toque no contador de suspensão enquanto o encadeamento principal está tentando incrementá-lo ou diminuí-lo. O encadeamento principal é bloqueado na emissão ou remoção de wake locks quando o contador de suspensão chega a zero e o encadeamento de suspensão está tentando ser executado.
  3. Espere até que o contador seja igual a zero.
  4. Grave o valor lido de /sys/ power /wakeup_count (da etapa 1) neste arquivo. Se a gravação falhar, retorne ao início do loop
  5. Inicie a suspensão do sistema gravando mem em /sys/power/ state .
  6. Libere o mutex.

Quando uma solicitação de wake lock é retornada com êxito, o thread de suspensão é bloqueado.

Figura 1. Suspender loop de thread

API SystemSuspend

A API SystemSuspend consiste em duas interfaces. A interface HIDL é usada por processos nativos para adquirir wake locks e a interface AIDL é usada para comunicação entre SystemServer e SystemSuspend.

Interface ISystemSuspend HIDL


enum WakeLockType : uint32_t {
    PARTIAL,
    FULL
};

interface IWakeLock {
    oneway release();
};

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

Cada cliente que solicita um wake lock recebe uma instância IWakeLock exclusiva. Isso é diferente de /sys/ power /wake_lock , que permite que vários clientes usem o wake lock com o mesmo nome. Se um cliente que contém uma instância IWakeLock encerrado, o driver do fichário e o serviço SystemSuspend o IWakeLock .

Interface ISuspendControlService AIDL

ISuspendControlService deve ser usado apenas por SystemServer.


interface ISuspendCallback {
     void notifyWakeup(boolean success);
}

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

Alavancar o Android HIDL oferece os seguintes benefícios:

  • Se um processo de bloqueio de suspensão morre, SystemSuspend pode ser notificado.
  • O encadeamento responsável pela suspensão do sistema pode receber um retorno de chamada.