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
LazyServiceRegistrarem 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.