Puede refactorizar código compilado condicionalmente para leer valores dinámicamente desde la interfaz HAL. Por ejemplo:
#ifdef TARGET_FORCE_HWC_FOR_VIRTUAL_DISPLAYS //some code fragment #endif
El código del marco puede llamar a una función de utilidad adecuada definida en <configstore/Utils.h>
dependiendo de su tipo.
Ejemplo de ConfigStore
Este ejemplo muestra la lectura de TARGET_FORCE_HWC_FOR_VIRTUAL_DISPLAYS
, definido en ConfigStore HAL como forceHwcForVirtualDisplays()
con 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);
La función de utilidad ( getBool
en el ejemplo anterior) se pone en contacto con el servicio de almacenamiento de configstore
para obtener el identificador del proxy de la función de interfaz, luego recupera el valor invocando el identificador a través de HIDL/hwbinder.
Funciones de utilidad
<configstore/Utils.h>
( configstore/1.0/include/configstore/Utils.h
) proporciona funciones de utilidad para cada tipo de retorno primitivo, incluido Optional[Bool|String|Int32|UInt32|Int64|UInt64]
, como se indica a continuación:
Escribe | Función (se omiten los parámetros de la plantilla) |
---|---|
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
es un valor predeterminado que se devuelve cuando la implementación de HAL no especifica un valor para el elemento de configuración. Cada función toma dos parámetros de plantilla:
-
I
es el nombre de la clase de interfaz. -
Func
es el puntero de función miembro para obtener el elemento de configuración.
Debido a que el valor de configuración es de solo lectura y no cambia, la función de utilidad almacena internamente en caché el valor de configuración. Las llamadas subsiguientes se atienden de manera más eficiente utilizando el valor almacenado en caché en la misma unidad de enlace.
Usando configstore-utils
La HAL de ConfigStore está diseñada para ser compatible con actualizaciones de versiones secundarias, lo que significa que cuando se revisa la HAL y algún código del marco usa los elementos recién introducidos, aún se puede usar el servicio ConfigStore con una versión secundaria anterior en /vendor
.
Para compatibilidad con versiones anteriores, asegúrese de que su implementación cumpla con las siguientes pautas:
- Los elementos nuevos usan el valor predeterminado cuando solo está disponible el servicio de la versión anterior. Ejemplo:
service = V1_1::IConfig::getService(); // null if V1_0 is installed value = DEFAULT_VALUE; if(service) { value = service->v1_1API(DEFAULT_VALUE); }
- El cliente usa la primera interfaz que incluía el elemento ConfigStore. Ejemplo:
V1_1::IConfig::getService()->v1_0API(); // NOT ALLOWED V1_0::IConfig::getService()->v1_0API(); // OK
- El servicio de la nueva versión se puede recuperar para la interfaz de la versión anterior. En el siguiente ejemplo, si la versión instalada es v1_1, se debe devolver el servicio v1_1 para
getService()
:V1_0::IConfig::getService()->v1_0API();
Cuando las funciones de acceso en la biblioteca configstore-utils
se utilizan para acceder al elemento ConfigStore, la implementación garantiza el n.º 1 y los errores del compilador garantizan el n.º 2. Por estas razones, recomendamos enfáticamente usar configstore-utils
siempre que sea posible.