A implementação do desligamento dinâmico envolve a conexão de fluxos de dados e a execução de processos dinâmicos, conforme detalhado nas seções a seguir.
Mudanças nas definições do HAL
O desligamento dinâmico requer informações sobre quais processos atendem a quais interfaces HAL (essas informações também podem ser úteis mais tarde em outros contextos) e não inicializam processos na inicialização e não os reiniciam (até que sejam solicitados novamente) quando saem.
# some init.rc script associated with the HAL service vendor.some-service-name /vendor/bin/hw/some-binary-service # init language extension, provides information of what service is served # if multiple interfaces are served, they can be specified one on each line interface android.hardware.light@2.0::ILight default # restarted if hwservicemanager dies # would also cause the hal to start early during boot if disabled wasn't set class hal # will not be restarted if it exits until it is requested to be restarted oneshot # will only be started when requested disabled # ... other properties
Mudanças no init e hwservicemanager
O desligamento dinâmico também exige que o hwservicemanager
diga
init
para iniciar os serviços solicitados. No Android 9,
init
inclui três mensagens de controle adicionais (por exemplo,
ctl.start
): ctl.interface_start
, ctl.interface_stop
e ctl.interface_restart
.
Essas mensagens podem ser usadas para sinalizar init
para abrir e fechar
interfaces de hardware específicas. Quando um serviço é solicitado e não está
registrado, o hwservicemanager
solicita que o serviço seja
iniciado. No entanto, as HALs dinâmicas não exigem o uso de nenhuma delas.
Determinar a saída do HAL
No Android 9, a saída da HAL precisa ser determinada manualmente. No Android 10 e versões mais recentes, ele também pode ser determinado com ciclos de vida automáticos.
O desligamento dinâmico exige várias políticas para decidir quando iniciar e desligar uma
HAL. Se um HAL decidir sair por qualquer motivo, ele
será reiniciado automaticamente quando for necessário novamente usando as informações
fornecidas na definição do HAL e a infraestrutura fornecida por mudanças em
init
e hwservicemanager
. Isso pode envolver algumas estratégias diferentes, incluindo:
- Um HAL pode optar por chamar a saída em si mesmo se alguém chamar uma API de fechamento ou semelhante. Esse comportamento precisa ser especificado na interface HAL correspondente.
- Os HALs podem ser encerrados quando a tarefa é concluída (documentado no arquivo HAL).
Ciclos de vida automáticos
O Android 10 adiciona mais suporte ao kernel e
hwservicemanager
, o que permite que as HALs sejam desligadas automaticamente
sempre que não tiverem clientes. Para usar esse recurso, siga todas as etapas em
Alterações nas definições do HAL e
também:
- Registre o serviço em C++ com
LazyServiceRegistrar
em vez da função de membro,registerAsService
, por exemplo:// only one instance of LazyServiceRegistrar per process LazyServiceRegistrar registrar; registrar.registerAsService(myHidlService /* , "default" */);
- Verifique se o cliente HAL mantém uma referência ao HAL de nível superior (a
interface registrada com
hwservicemanager
) somente quando ele está em uso. Para evitar atrasos, se essa referência for descartada em uma linha de execução hwbinder que continue sendo executada, o cliente também precisará chamarIPCThreadState::self()->flushCommands()
após descartar a referência para garantir que o driver de vinculação seja notificado das mudanças associadas à contagem de referências.