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 en
<configstore/Utils.h> en fonction de son type.
Exemple de ConfigStore
Cet exemple montre la lecture de TARGET_FORCE_HWC_FOR_VIRTUAL_DISPLAYS, défini dans ConfigStore HAL 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 descripteur du proxy de la fonction d'interface, puis récupère la valeur en appelant le descripteur via HIDL/hwbinder.
Fonctions utilitaires
<configstore/Utils.h>
(configstore/1.0/include/configstore/Utils.h) fournit des fonctions utilitaires pour chaque type renvoyé 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 HAL ne spécifie pas de valeur pour l'élément de configuration. Chaque fonction prend deux paramètres de modèle :
Iest le nom de la classe d'interface.Funcest 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é de liaison.
Utiliser configstore-utils
La HAL ConfigStore est conçue pour être compatible avec les mises à niveau de versions mineures, ce qui signifie que lorsque la HAL est révisée et que du code de framework utilise les nouveaux éléments introduits, le service ConfigStore avec une version mineure antérieure dans /vendor peut toujours être utilisé.
Pour assurer la compatibilité, 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, l'implémentation garantit le point 1 et les erreurs du compilateur garantissent le point 2. Pour ces raisons, nous vous recommandons vivement d'utiliser configstore-utils dans la mesure du possible.