Możesz przerobić kod skompilowany warunkowo, aby odczytywać wartości dynamicznie z interfejsu HAL. Na przykład:
#ifdef TARGET_FORCE_HWC_FOR_VIRTUAL_DISPLAYS // some code fragment #endif
Kod platformy może następnie w zależności od typu wywoływać odpowiednią funkcję narzędziową zdefiniowaną w <configstore/Utils.h>
.
Przykład ConfigStore
Ten przykład pokazuje odczyt TARGET_FORCE_HWC_FOR_VIRTUAL_DISPLAYS
zdefiniowany w HAL ConfigStore jako forceHwcForVirtualDisplays()
z zwracanym typem 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);
Funkcja pomocnicza (getBool
w przykładzie powyżej) kontaktuje usługę configstore
, aby uzyskać uchwyt dla funkcji interfejsu zastępczego, a następnie pobiera wartość, wywołując uchwyt za pomocą HIDL/hwbinder.
Funkcje użyteczności
<configstore/Utils.h>
(configstore/1.0/include/configstore/Utils.h
) udostępnia funkcje pomocnicze dla każdego prymitywnego typu zwracanego, w tym Optional[Bool|String|Int32|UInt32|Int64|UInt64]
, jak wymieniono poniżej:
Typ | Funkcja (pominięte parametry szablonu) |
---|---|
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
to wartość domyślna zwracana, gdy implementacja HAL nie określa wartości elementu konfiguracji. Każda funkcja przyjmuje 2 parametry szablonu:
I
to nazwa klasy interfejsu.Func
to wskaźnik funkcji członkowskiej służący do pobierania elementu konfiguracji.
Wartość konfiguracji jest tylko do odczytu i nie zmienia się, więc funkcja narzędzia zapisuje ją w pamięci podręcznej. Kolejne wywołania są obsługiwane wydajniej dzięki użyciu wartości z pamięci podręcznej w tej samej jednostce łączenia.
Używanie narzędzia configstore-utils
Interfejs HAL usługi ConfigStore jest zgodny w górę z aktualizacjami do nowszych wersji. Oznacza to, że gdy interfejs HAL zostanie zmieniony, a część kodu frameworku będzie używać nowo wprowadzonych elementów, nadal można będzie korzystać z usługi ConfigStore w starszej wersji w wersji /vendor
.
Aby zapewnić zgodność wsteczną, upewnij się, że Twoja implementacja jest zgodna z tymi wytycznymi:
- Nowe elementy będą używać wartości domyślnej, jeśli dostępna jest tylko usługa w starej wersji. Przykład:
service = V1_1::IConfig::getService(); // null if V1_0 is installed value = DEFAULT_VALUE; if(service) { value = service->v1_1API(DEFAULT_VALUE); }
- Klient używa pierwszego interfejsu, który zawiera element ConfigStore.
Przykład:
V1_1::IConfig::getService()->v1_0API(); // NOT ALLOWED V1_0::IConfig::getService()->v1_0API(); // OK
- Usługa nowej wersji może być pobierana w starszej wersji interfejsu. W poniższym przykładzie, jeśli zainstalowana wersja to v1_1, dla
getService()
musi być zwracana usługa v1_1:V1_0::IConfig::getService()->v1_0API();
Gdy funkcje dostępu w bibliotece configstore-utils
są używane do uzyskiwania dostępu do elementu ConfigStore, warunek 1 jest gwarantowany przez implementację, a warunek 2 – przez błędy kompilatora. Z tego względu zdecydowanie zalecamy
używanie właściwości configstore-utils
tam, gdzie jest to możliwe.