You can refactor conditionally-compiled code to read values dynamically from the HAL interface. For example:
#ifdef TARGET_FORCE_HWC_FOR_VIRTUAL_DISPLAYS //some code fragment #endif
Framework code can then call an appropriate utility function defined in
<configstore/Utils.h>
depending on its type.
This example shows reading
TARGET_FORCE_HWC_FOR_VIRTUAL_DISPLAYS
, defined in ConfigStore HAL
as forceHwcForVirtualDisplays()
with return type
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);
The utility function (getBool
in the example above) contacts the
configstore
service to get the handle for the proxy of the
interface function, then retrieves the value by invoking the handle via
HIDL/hwbinder.
<configstore/Utils.h>
(configstore/1.0/include/configstore/Utils.h
) provides utility
functions for each primitive return type, including
Optional[Bool|String|Int32|UInt32|Int64|UInt64]
, as listed
below:
Type | Function (template parameters omitted) |
---|---|
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
is a default value returned when the HAL implementation
does not specify a value for the configuration item. Each function takes two
template parameters:
I
. Interface class name.Func
. Member function pointer for getting the
configuration item.Because the configuration value is read-only and does not change, the utility function internally caches the configuration value. Subsequent calls are serviced more efficiently using the cached value in the same linking unit.
The ConfigStore HAL is designed to be forward-compatible for minor version
upgrades, meaning that when the HAL is up-revisioned and some framework code
uses the newly-introduced items, the ConfigStore service with older minor
version in /vendor
can still be used.
For forward-compatibility, ensure your implementation adheres to the following guidelines:
service = V1_1::IConfig::getService(); // null if V1_0 is installed value = DEFAULT_VALUE; if(service) { value = service->v1_1API(DEFAULT_VALUE); }
V1_1::IConfig::getService()->v1_0API(); // NOT ALLOWED V1_0::IConfig::getService()->v1_0API(); // OK
V1_0::IConfig::getService()->v1_0API();
Note: The current AOSP implementation satisfies this requirement.
When the access functions in configstore-utils
library are used
for accessing the ConfigStore item, #1 is guaranteed by the implementation and
#2 is guaranteed by compiler errors. For these reasons we strongly recommend
using configstore-utils
wherever possible.