Implementar o Google Fit 2.1

No Android 11, todo o código healthd é refatorado em libhealthloop e libhealth2impl e modificado para implementar a HAL health@2.1. Essas duas bibliotecas são vinculadas de forma estática por health@2.0-impl-2.1, a implementação de transmissão direta do Health 2.1. As bibliotecas com vinculação estática permitem que o health@2.0-impl-2.1 faça o mesmo trabalho que o healthd, como executar healthd_mainloop e fazer pesquisas. Em init, o health@2.1-service registra uma implementação da interface IHealth para hwservicemanager. Ao fazer upgrade de dispositivos com uma imagem do fornecedor Android 8.x ou 9 e um framework Android 11, a imagem do fornecedor pode não fornecer o serviço health@2.1. A compatibilidade com versões anteriores de imagens antigas de fornecedores é imposta pelo cronograma de descontinuação.

Para garantir a compatibilidade com versões anteriores:

  1. healthd registra IHealth em hwservicemanager apesar de ser um daemon do sistema. IHealth é adicionado ao manifesto do sistema com o nome da instância "backup".
  2. O framework e storaged se comunicam com healthd por hwbinder em vez de binder.
  3. O código para framework e storaged é alterado para buscar a instância "default" (padrão), se disponível, e "backup".
    • O código do cliente C++ usa a lógica definida em libhealthhalutils.
    • O código do cliente Java usa a lógica definida em HealthServiceWrapper.
  4. Depois que o iHealth/default estiver disponível e as imagens do fornecedor do Android 8.1 forem descontinuadas, o iHealth/backup e o healthd poderão ser descontinuados.

Variáveis de build específicas da placa para healthd

BOARD_PERIODIC_CHORES_INTERVAL_* são variáveis específicas da placa usadas para criar healthd. Como parte da divisão de build do sistema/fornecedor, os valores específicos da placa não podem ser definidos para módulos do sistema. Esses valores eram substituídos na função descontinuada healthd_board_init.

No health@2.1, os fornecedores podem substituir esses dois valores de intervalo de tarefas periódicas na struct healthd_config antes de transmitir ao construtor da classe de implementação de integridade. A classe de implementação de integridade precisa herdar de android::hardware::health::V2_1::implementation::Health.

Implementar o serviço Health 2.1

Para informações sobre como implementar o serviço Health 2.1, consulte hardware/interfaces/health/2.1/README.md.

Clientes de saúde

O health@2.x tem os seguintes clientes:

  • charger O uso do código libbatterymonitor e healthd_common é encapsulado em health@2.0-impl.
  • recuperação. A vinculação a libbatterymonitor está envolvida em health@2.0-impl. Todas as chamadas para BatteryMonitor são substituídas por chamadas para a classe de implementação Health.
  • BatteryManager. BatteryManager.queryProperty(int id) era o único cliente de IBatteryPropertiesRegistrar.getProperty. IBatteryPropertiesRegistrar.getProperty foi fornecido por healthd e lido diretamente /sys/class/power_supply.

    Por motivos de segurança, os apps não podem chamar diretamente a HAL de saúde. No Android 9 e versões mais recentes, o serviço binder IBatteryPropertiesRegistrar é fornecido por BatteryService em vez de healthd. BatteryService delega a chamada à HAL de saúde para recuperar as informações solicitadas.

  • BatteryService. No Android 9 e em versões mais recentes, o BatteryService usa o HealthServiceWrapper para determinar se é necessário usar a instância do serviço de integridade padrão do vendor ou a instância do serviço de integridade backup do healthd. Em seguida, BatteryService detecta eventos de saúde usando IHealth.registerCallback.

  • Storaged. No Android 9 e em versões mais recentes, o storaged usa o libhealthhalutils para determinar se é necessário usar a instância do serviço de integridade padrão do vendor ou a instância do serviço de integridade backup do healthd. Em seguida, storaged detecta eventos de saúde usando IHealth.registerCallback e recupera informações de armazenamento.

Mudanças no SELinux

O HAL health@2.1 inclui as seguintes mudanças do SELinux na plataforma:

  • Adiciona android.hardware.health@2.1-service a file_contexts.

Para dispositivos com implementação própria, algumas mudanças no SELinux do fornecedor podem ser necessárias. Exemplo:

# device/<manufacturer>/<device>/sepolicy/vendor/hal_health_default.te
# Add device specific permissions to hal_health_default domain, especially
# if it links to board-specific libhealthd or implements storage APIs.

Interfaces do kernel

O daemon healthd e a implementação padrão android.hardware.health@2.0-impl-2.1 acessam as seguintes interfaces do kernel para recuperar informações da bateria:

  • /sys/class/power_supply/*/capacity_level (adicionado no Health 2.1)
  • /sys/class/power_supply/*/capacity
  • /sys/class/power_supply/*/charge_counter
  • /sys/class/power_supply/*/charge_full
  • /sys/class/power_supply/*/charge_full_design (adicionado no Health 2.1)
  • /sys/class/power_supply/*/current_avg
  • /sys/class/power_supply/*/current_max
  • /sys/class/power_supply/*/current_now
  • /sys/class/power_supply/*/cycle_count
  • /sys/class/power_supply/*/health
  • /sys/class/power_supply/*/online
  • /sys/class/power_supply/*/present
  • /sys/class/power_supply/*/status
  • /sys/class/power_supply/*/technology
  • /sys/class/power_supply/*/temp
  • /sys/class/power_supply/*/time_to_full_now (adicionado no Health 2.1)
  • /sys/class/power_supply/*/type
  • /sys/class/power_supply/*/voltage_max
  • /sys/class/power_supply/*/voltage_now

Qualquer implementação de HAL de saúde específica do dispositivo que use libbatterymonitor acessa essas interfaces do kernel por padrão, a menos que seja substituída no construtor da classe de implementação de saúde.

Se esses arquivos estiverem ausentes ou inacessíveis em healthd ou no serviço padrão (por exemplo, o arquivo é um symlink para uma pasta específica do fornecedor que nega o acesso devido a uma política do SELinux configurada incorretamente), eles podem não funcionar corretamente. Portanto, outras mudanças específicas do fornecedor no SELinux podem ser necessárias, mesmo que a implementação padrão seja usada.

Algumas interfaces do kernel usadas no Health 2.1, como /sys/class/power_supply/*/capacity_level e /sys/class/power_supply/*/time_to_full_now, podem ser opcionais. No entanto, para evitar comportamentos incorretos do framework resultantes de interfaces do kernel ausentes, é recomendável fazer cherry-pick do CL 1398913 antes de criar o serviço Health HAL 2.1.

Teste

O Android 11 inclui novos testes VTS escritos especificamente para a HAL health@2.1. Se um dispositivo declarar a HAL health@2.1 no manifesto, ele precisará passar nos testes VTS correspondentes. Os testes são programados para a instância padrão (para garantir que o dispositivo implemente o HAL corretamente) e para a instância de backup (para garantir que healthd continue funcionando corretamente antes de ser removido).

Requisitos de informações da bateria

A HAL Health 2.0 declara um conjunto de requisitos na interface HAL, mas os testes VTS correspondentes são relativamente flexíveis na aplicação deles. No Android 11, novos testes de VTS são adicionados para aplicar os seguintes requisitos em dispositivos lançados com o Android 11 e versões mais recentes:

  • As unidades de corrente instantânea e média da bateria precisam ser microamperes (μA).
  • O sinal da corrente instantânea e média da bateria precisa estar correto. Especificamente:
    • current == 0 quando o status da bateria é UNKNOWN
    • current > 0 quando o status da bateria é CHARGING
    • current <= 0 quando o status da bateria é NOT_CHARGING
    • current < 0 quando o status da bateria é DISCHARGING
    • Não é aplicada quando o status da bateria é FULL
  • O status da bateria precisa estar correto, independente de uma fonte de energia estar conectada ou não. Especificamente:
    • O status da bateria precisa ser CHARGING, NOT_CHARGING ou FULL se e somente se uma fonte de energia estiver conectada.
    • O status da bateria precisa ser DISCHARGING se e somente se uma fonte de energia estiver desconectada.

Se você usa libbatterymonitor na sua implementação e transmite valores de interfaces do kernel, verifique se os nós sysfs estão informando valores corretos:

  • Verifique se a corrente da bateria está sendo informada com o sinal e as unidades corretos. Isso inclui os seguintes nós sysfs:
    • /sys/class/power_supply/*/current_avg
    • /sys/class/power_supply/*/current_max
    • /sys/class/power_supply/*/current_now
    • Valores positivos indicam corrente de entrada na bateria.
    • Os valores precisam estar em microampères (μA).
  • Verifique se a tensão da bateria está em microvolts (μV). Isso inclui os seguintes nós sysfs:
    • /sys/class/power_supply/*/voltage_max
    • /sys/class/power_supply/*/voltage_now
    • A implementação padrão da HAL divide voltage_now por 1.000 e informa valores em milivolts (mV). Consulte @1.0::HealthInfo.

Para mais detalhes, consulte Classe de fonte de alimentação do Linux.