Vous pouvez refactoriser le code compilé de manière conditionnelle pour lire les valeurs de manière dynamique à partir de l'interface HAL. Exemple :
#ifdef TARGET_FORCE_HWC_FOR_VIRTUAL_DISPLAYS // some code fragment #endif
Le code du framework peut ensuite appeler une fonction utilitaire appropriée définie dans <configstore/Utils.h>
en fonction de son type.
Exemple ConfigStore
Cet exemple montre la lecture de TARGET_FORCE_HWC_FOR_VIRTUAL_DISPLAYS
, définie dans le HAL ConfigStore comme forceHwcForVirtualDisplays()
avec le type de retour 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 fonction utilitaire (getBool
dans l'exemple ci-dessus) contacte le service configstore
pour obtenir le handle du proxy de la fonction d'interface, puis récupère la valeur en appelant le handle via HIDL/hwbinder.
Fonctions utilitaires
<configstore/Utils.h>
(configstore/1.0/include/configstore/Utils.h
) fournit des fonctions utilitaires pour chaque type de retour primitif, y compris Optional[Bool|String|Int32|UInt32|Int64|UInt64]
, comme indiqué ci-dessous:
Type | Fonction (paramètres de modèle omis) |
---|---|
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
est une valeur par défaut renvoyée lorsque l'implémentation du HAL ne spécifie pas de valeur pour l'élément de configuration. Chaque fonction utilise deux paramètres de modèle:
I
correspond au nom de la classe d'interface.Func
est le pointeur de fonction membre permettant d'obtenir l'élément de configuration.
Étant donné que la valeur de configuration est en lecture seule et ne change pas, la fonction utilitaire met en cache la valeur de configuration en interne. Les appels ultérieurs sont traités plus efficacement à l'aide de la valeur mise en cache dans la même unité d'association.
Utiliser configstore-utils
Le HAL ConfigStore est conçu pour être rétrocompatible pour les mises à niveau de versions mineures. Cela signifie que lorsque le HAL est révisé et que certains codes de framework utilisent les éléments nouvellement introduits, le service ConfigStore avec une version mineure plus ancienne dans /vendor
peut toujours être utilisé.
Pour assurer la compatibilité ascendante, assurez-vous que votre implémentation respecte les consignes suivantes:
- Les nouveaux éléments utilisent la valeur par défaut lorsque seul le service de l'ancienne version est disponible. Exemple :
service = V1_1::IConfig::getService(); // null if V1_0 is installed value = DEFAULT_VALUE; if(service) { value = service->v1_1API(DEFAULT_VALUE); }
- Le client utilise la première interface qui inclut l'élément ConfigStore.
Exemple :
V1_1::IConfig::getService()->v1_0API(); // NOT ALLOWED V1_0::IConfig::getService()->v1_0API(); // OK
- Le service de la nouvelle version peut être récupéré pour l'interface de l'ancienne version. Dans l'exemple suivant, si la version installée est v1_1, le service v1_1 doit être renvoyé pour
getService()
:V1_0::IConfig::getService()->v1_0API();
Lorsque les fonctions d'accès de la bibliothèque configstore-utils
sont utilisées pour accéder à l'élément ConfigStore, le point 1 est garanti par l'implémentation et le point 2 est garanti par les erreurs de compilation. C'est pourquoi nous vous recommandons vivement d'utiliser configstore-utils
dans la mesure du possible.