Você pode refatorar o código compilado condicionalmente para ler valores dinamicamente da interface HAL. Por exemplo:
#ifdef TARGET_FORCE_HWC_FOR_VIRTUAL_DISPLAYS // some code fragment #endif
O código da estrutura pode então chamar uma função de utilitário apropriada definida em <configstore/Utils.h>
dependendo de seu tipo.
Exemplo de ConfigStore
Este exemplo mostra a leitura de TARGET_FORCE_HWC_FOR_VIRTUAL_DISPLAYS
, definido no ConfigStore HAL como forceHwcForVirtualDisplays()
com 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 de utilitário ( getBool
no exemplo acima) entra em contato com o serviço configstore
para obter o identificador do proxy da função de interface e, em seguida, recupera o valor invocando o identificador via HIDL/hwbinder.
Funções utilitárias
<configstore/Utils.h>
( configstore/1.0/include/configstore/Utils.h
) fornece funções utilitárias 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 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 de interface. -
Func
é o ponteiro da função membro para obter o item de configuração.
Como o valor de configuração é somente leitura e não muda, a função de utilitário armazena em cache 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 ligação.
Usando configstore-utils
O HAL do ConfigStore foi projetado para ser compatível com atualizações de versões secundárias, o que significa que quando o HAL for revisado e algum código da estrutura usar os itens recém-introduzidos, o serviço ConfigStore com uma versão secundária mais antiga em /vendor
ainda poderá ser usado.
Para compatibilidade futura, certifique-se de que sua implementação siga as seguintes diretrizes:
- Novos itens usam o valor padrão quando apenas o serviço da versão antiga está 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); }
- O cliente utiliza a primeira interface que inclui o item ConfigStore. Exemplo:
V1_1::IConfig::getService()->v1_0API(); // NOT ALLOWED V1_0::IConfig::getService()->v1_0API(); // OK
- O serviço da nova versão pode ser recuperado para a interface da versão antiga. No exemplo a seguir, se a versão instalada for v1_1, o serviço v1_1 deverá 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, #1 é garantido pela implementação e #2 é garantido por erros do compilador. Por estas razões, recomendamos fortemente o uso configstore-utils
sempre que possível.