Uso do lado do cliente

É possível refatorar o código compilado condicionalmente para ler valores dinamicamente na interface HAL. Por exemplo:

#ifdef TARGET_FORCE_HWC_FOR_VIRTUAL_DISPLAYS
// some code fragment
#endif

O código do framework pode chamar uma função utilitária adequada definida em <configstore/Utils.h>, dependendo do tipo.

Exemplo de ConfigStore

Este exemplo mostra a leitura de TARGET_FORCE_HWC_FOR_VIRTUAL_DISPLAYS, definida na HAL ConfigStore como forceHwcForVirtualDisplays() com o tipo de retorno OptionalBool:

#include <configstore/Utils.h>
using namespace android::hardware::configstore;
using namespace android::hardware::configstore::V1_0;

static bool vsyncPhaseOffsetNs = getBool<ISurfaceFlingerConfigs,
        ISurfaceFlingerConfigs::forceHwcForVirtualDisplays>(false);

A função utilitária (getBool no exemplo acima) entra em contato com o serviço configstore para conseguir o identificador do proxy da função da interface e recupera o valor invocando o identificador por meio de HIDL/hwbinder.

Funções utilitárias

<configstore/Utils.h> (configstore/1.0/include/configstore/Utils.h) fornece funções de utilitário para cada tipo de retorno primitivo, incluindo Optional[Bool|String|Int32|UInt32|Int64|UInt64], conforme listado abaixo:

Tipo Função (parâmetros de modelo omitidos)
OptionalBool bool getBool(const bool defValue)
OptionalInt32 int32_t getInt32(const int32_t defValue)
OptionalUInt32 uint32_t getUInt32(const uint32_t defValue)
OptionalInt64 int64_t getInt64(const int64_t defValue)
OptionalUInt64 uint64_t getUInt64(const uint64_t defValue)
OptionalString std::string getString(const std::string &defValue)

defValue é um valor padrão retornado quando a implementação da HAL não especifica um valor para o item de configuração. Cada função usa dois parâmetros de modelo:

  • I é o nome da classe da interface.
  • Func é o ponteiro da função de membro para receber o item de configuração.

Como o valor de configuração é somente leitura e não é alterado, a função do utilitário armazena internamente o valor de configuração. As chamadas subsequentes são atendidas com mais eficiência usando o valor armazenado em cache na mesma unidade de vinculação.

Usar o configstore-utils

A HAL ConfigStore foi projetada para ser compatível com versões futuras de upgrades de versões secundárias. Isso significa que, quando ela é revisada e algum código do framework usa os itens recém-introduzidos, o serviço ConfigStore com uma versão secundária mais antiga em /vendor ainda pode ser usado.

Para compatibilidade com versões futuras, verifique se a implementação está de acordo com as diretrizes abaixo:

  1. Os novos itens usarão o valor padrão quando apenas o serviço da versão antiga estiver disponível. Exemplo:
    service = V1_1::IConfig::getService(); // null if V1_0 is installed
    value = DEFAULT_VALUE;
      if(service) {
        value = service->v1_1API(DEFAULT_VALUE);
      }
    
  2. O cliente usa a primeira interface que incluiu o item ConfigStore. Exemplo:
    V1_1::IConfig::getService()->v1_0API(); // NOT ALLOWED
    
    V1_0::IConfig::getService()->v1_0API(); // OK
    
  3. O serviço da nova versão pode ser recuperado para a interface da versão antiga. No exemplo abaixo, se a versão instalada for v1_1, o serviço v1_1 precisará ser retornado para getService():
    V1_0::IConfig::getService()->v1_0API();
    

Quando as funções de acesso na biblioteca configstore-utils são usadas para acessar o item ConfigStore, o item 1 é garantido pela implementação e o item 2 é garantido por erros do compilador. Por esses motivos, recomendamos usar configstore-utils sempre que possível.