Utilisation côté client

Vous pouvez refactoriser le code compilé de manière conditionnelle pour lire les valeurs de manière dynamique à partir de l'interface HAL. Par 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 TARGET_FORCE_HWC_FOR_VIRTUAL_DISPLAYS, défini dans ConfigStore HAL en tant que forceHwcForVirtualDisplays() avec le type renvoyé 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 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 du HAL ne spécifie pas de valeur pour l'élément de configuration. Chaque fonction nécessite deux paramètres de modèle:

  • I est le nom de la classe de l'interface.
  • Func est le pointeur de fonction membre permettant d'obtenir l'élément de configuration.

Comme la valeur de configuration est en lecture seule et ne change pas, l'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

L'HAL ConfigStore est conçu pour être compatible avec les mises à niveau de versions mineures. Ainsi, lorsque le HAL est révisé et qu'un code de framework utilise les nouveaux éléments, le service ConfigStore avec une ancienne version mineure dans /vendor peut toujours être utilisé.

Pour assurer la compatibilité ascendante, assurez-vous que votre implémentation respecte les consignes suivantes:

  1. 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);
      }
    
  2. Le client utilise la première interface qui incluait l'élément ConfigStore. Exemple :
    V1_1::IConfig::getService()->v1_0API(); // NOT ALLOWED
    
    V1_0::IConfig::getService()->v1_0API(); // OK
    
  3. 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, la valeur 1 est garantie par l'implémentation et la valeur 2 est garantie par les erreurs de compilation. C'est pourquoi nous vous recommandons vivement d'utiliser configstore-utils dans la mesure du possible.