Clientseitige Verwendung

Sie können bedingt kompilierten Code refaktorieren, um Werte dynamisch aus der HAL-Schnittstelle zu lesen. Beispiel:

#ifdef TARGET_FORCE_HWC_FOR_VIRTUAL_DISPLAYS
// some code fragment
#endif

Der Framework-Code kann dann je nach Typ eine entsprechende Dienstfunktion aufrufen, die in <configstore/Utils.h> definiert ist.

ConfigStore-Beispiel

In diesem Beispiel wird das Lesen von TARGET_FORCE_HWC_FOR_VIRTUAL_DISPLAYS dargestellt, das in ConfigStore HAL als forceHwcForVirtualDisplays() mit dem Rückgabetyp OptionalBool definiert ist:

#include <configstore/Utils.h>
using namespace android::hardware::configstore;
using namespace android::hardware::configstore::V1_0;

static bool vsyncPhaseOffsetNs = getBool<ISurfaceFlingerConfigs,
        ISurfaceFlingerConfigs::forceHwcForVirtualDisplays>(false);

Die Dienstprogrammfunktion (getBool im Beispiel oben) kontaktiert den Dienst configstore, um den Handle für den Proxy der Schnittstellenfunktion abzurufen, und ruft dann den Wert durch Aufrufen des Handles über HIDL/hwbinder ab.

Dienstprogrammfunktionen

<configstore/Utils.h> (configstore/1.0/include/configstore/Utils.h) bietet Dienstfunktionen für jeden primitiven Rückgabetyp, einschließlich Optional[Bool|String|Int32|UInt32|Int64|UInt64], wie unten aufgeführt:

Typ Funktion (Vorlagenparameter ausgelassen)
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 ist ein Standardwert, der zurückgegeben wird, wenn die HAL-Implementierung keinen Wert für das Konfigurationselement angibt. Jede Funktion verwendet zwei Vorlagenparameter:

  • I ist der Name der Schnittstellenklasse.
  • Func ist der Zeiger der Mitgliederfunktion zum Abrufen des Konfigurationselements.

Da der Konfigurationswert schreibgeschützt ist und sich nicht ändert, speichert die Dienstprogrammfunktion den Konfigurationswert intern im Cache. Nachfolgende Aufrufe werden mithilfe des im Cache gespeicherten Werts in derselben Verknüpfungseinheit effizienter verarbeitet.

configstore-utils verwenden

Der ConfigStore HAL ist so konzipiert, dass er für Nebenversionsupgrades aufwärtskompatibel ist. Das bedeutet, dass der ConfigStore-Dienst mit einer älteren Nebenversion in /vendor weiterhin verwendet werden kann, wenn der HAL überarbeitet wird und ein Teil des Framework-Codes die neu eingeführten Elemente verwendet.

Achte für die Aufwärtskompatibilität darauf, dass deine Implementierung den folgenden Richtlinien entspricht:

  1. Neue Elemente verwenden den Standardwert, wenn nur der Dienst der alten Version verfügbar ist. Beispiel:
    service = V1_1::IConfig::getService(); // null if V1_0 is installed
    value = DEFAULT_VALUE;
      if(service) {
        value = service->v1_1API(DEFAULT_VALUE);
      }
    
  2. Der Client verwendet die erste Schnittstelle, die das ConfigStore-Element enthielt. Beispiel:
    V1_1::IConfig::getService()->v1_0API(); // NOT ALLOWED
    
    V1_0::IConfig::getService()->v1_0API(); // OK
    
  3. Der Dienst der neuen Version kann für die Schnittstelle der alten Version abgerufen werden. Im folgenden Beispiel muss für getService(), wenn die installierte Version v1_1 ist, der v1_1-Dienst zurückgegeben werden:
    V1_0::IConfig::getService()->v1_0API();
    

Wenn die Zugriffsfunktionen in der Bibliothek configstore-utils für den Zugriff auf das ConfigStore-Element verwendet werden, wird #1 durch die Implementierung und #2 durch Compilerfehler garantiert. Aus diesen Gründen empfehlen wir dringend, nach Möglichkeit configstore-utils zu verwenden.