audiopolicy: engineconfigurable: Migrate to XML criteria and criterion type defintion
Test: make
Change-Id: Ia7eb6b86dffb31bcb4191f5e265e85135934dc36
Signed-off-by: François Gaffie <francois.gaffie@renault.com>
diff --git a/services/audiopolicy/engineconfigurable/wrapper/ParameterManagerWrapper.cpp b/services/audiopolicy/engineconfigurable/wrapper/ParameterManagerWrapper.cpp
index f8174f8..fc6c1e4 100644
--- a/services/audiopolicy/engineconfigurable/wrapper/ParameterManagerWrapper.cpp
+++ b/services/audiopolicy/engineconfigurable/wrapper/ParameterManagerWrapper.cpp
@@ -18,7 +18,7 @@
//#define LOG_NDEBUG 0
#include "ParameterManagerWrapper.h"
-#include "audio_policy_criteria_conf.h"
+#include "ParameterManagerWrapperConfig.h"
#include <ParameterMgrPlatformConnector.h>
#include <SelectionCriterionTypeInterface.h>
#include <SelectionCriterionInterface.h>
@@ -38,6 +38,7 @@
using std::string;
using std::map;
using std::vector;
+using CriterionTypes = std::map<std::string, ISelectionCriterionTypeInterface *>;
/// PFW related definitions
// Logger
@@ -65,6 +66,27 @@
const char *const ParameterManagerWrapper::mPolicyPfwDefaultConfFileName =
"/etc/parameter-framework/ParameterFrameworkConfigurationPolicy.xml";
+static const char *const gInputDeviceCriterionName = "AvailableInputDevices";
+static const char *const gOutputDeviceCriterionName = "AvailableOutputDevices";
+static const char *const gPhoneStateCriterionName = "TelephonyMode";
+static const char *const gOutputDeviceAddressCriterionName = "AvailableOutputDevicesAddresses";
+static const char *const gInputDeviceAddressCriterionName = "AvailableInputDevicesAddresses";
+
+/**
+ * Order MUST be align with defintiion of audio_policy_force_use_t within audio_policy.h
+ */
+static const char *const gForceUseCriterionTag[AUDIO_POLICY_FORCE_USE_CNT] =
+{
+ [AUDIO_POLICY_FORCE_FOR_COMMUNICATION] = "ForceUseForCommunication",
+ [AUDIO_POLICY_FORCE_FOR_MEDIA] = "ForceUseForMedia",
+ [AUDIO_POLICY_FORCE_FOR_RECORD] = "ForceUseForRecord",
+ [AUDIO_POLICY_FORCE_FOR_DOCK] = "ForceUseForDock",
+ [AUDIO_POLICY_FORCE_FOR_SYSTEM] = "ForceUseForSystem",
+ [AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO] = "ForceUseForHdmiSystemAudio",
+ [AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND] = "ForceUseForEncodedSurround",
+ [AUDIO_POLICY_FORCE_FOR_VIBRATE_RINGING] = "ForceUseForVibrateRinging"
+};
+
template <>
struct ParameterManagerWrapper::parameterManagerElementSupported<ISelectionCriterionInterface> {};
template <>
@@ -79,15 +101,64 @@
// Logger
mPfwConnector->setLogger(mPfwConnectorLogger);
- // Load criteria file
- if ((loadAudioPolicyCriteriaConfig(gAudioPolicyCriteriaVendorConfFilePath) != NO_ERROR) &&
- (loadAudioPolicyCriteriaConfig(gAudioPolicyCriteriaConfFilePath) != NO_ERROR)) {
- ALOGE("%s: Neither vendor conf file (%s) nor system conf file (%s) could be found",
- __FUNCTION__, gAudioPolicyCriteriaVendorConfFilePath,
- gAudioPolicyCriteriaConfFilePath);
+ status_t loadResult = loadConfig();
+ if (loadResult < 0) {
+ ALOGE("Policy Wrapper configuration is partially invalid.");
}
}
+status_t ParameterManagerWrapper::loadConfig()
+{
+ auto result = wrapper_config::parse();
+ if (result.parsedConfig == nullptr) {
+ return -ENOENT;
+ }
+ ALOGE_IF(result.nbSkippedElement != 0, "skipped %zu elements", result.nbSkippedElement);
+
+ CriterionTypes criterionTypes;
+ for (auto criterionType : result.parsedConfig->criterionTypes) {
+ ALOG_ASSERT(criterionTypes.find(criterionType.name) == criterionTypes.end(),
+ "CriterionType %s already added", criterionType.name.c_str());
+ ALOGV("%s: Adding new criterionType %s", __FUNCTION__, criterionType.name.c_str());
+
+ auto criterionTypePfw =
+ mPfwConnector->createSelectionCriterionType(criterionType.isInclusive);
+
+ for (auto pair : criterionType.valuePairs) {
+ std::string error;
+ ALOGV("%s: Adding pair %d,%s for criterionType %s", __FUNCTION__, pair.first,
+ pair.second.c_str(), criterionType.name.c_str());
+ criterionTypePfw->addValuePair(pair.first, pair.second, error);
+ }
+ criterionTypes[criterionType.name] = criterionTypePfw;
+ }
+
+ for (auto criterion : result.parsedConfig->criteria) {
+ ALOG_ASSERT(mPolicyCriteria.find(criterion.name) == mPolicyCriteria.end(),
+ "%s: Criterion %s already added", __FUNCTION__, criterion.name.c_str());
+
+ auto criterionType =
+ getElement<ISelectionCriterionTypeInterface>(criterion.typeName, criterionTypes);
+ ALOG_ASSERT(criterionType != nullptr, "No %s Criterion type found for criterion %s",
+ criterion.typeName.c_str(), criterion.name.c_str());
+
+ auto criterionPfw = mPfwConnector->createSelectionCriterion(criterion.name, criterionType);
+ mPolicyCriteria[criterion.name] = criterionPfw;
+
+ if (not criterion.defaultLiteralValue.empty()) {
+ int numericalValue = 0;
+ if (not criterionType->getNumericalValue(criterion.defaultLiteralValue.c_str(),
+ numericalValue)) {
+ ALOGE("%s; trying to apply invalid default literal value (%s)", __FUNCTION__,
+ criterion.defaultLiteralValue.c_str());
+ continue;
+ }
+ criterionPfw->setCriterionState(numericalValue);
+ }
+ }
+ return result.nbSkippedElement == 0? NO_ERROR : BAD_VALUE;
+}
+
ParameterManagerWrapper::~ParameterManagerWrapper()
{
// Unset logger
@@ -111,112 +182,6 @@
return NO_ERROR;
}
-
-void ParameterManagerWrapper::addCriterionType(const string &typeName, bool isInclusive)
-{
- ALOG_ASSERT(mPolicyCriterionTypes.find(typeName) == mPolicyCriterionTypes.end(),
- "CriterionType %s already added", typeName.c_str());
- ALOGD("%s: Adding new criterionType %s", __FUNCTION__, typeName.c_str());
-
- mPolicyCriterionTypes[typeName] = mPfwConnector->createSelectionCriterionType(isInclusive);
-}
-
-void ParameterManagerWrapper::addCriterionTypeValuePair(
- const string &typeName,
- uint32_t numericValue,
- const string &literalValue)
-{
- ALOG_ASSERT(mPolicyCriterionTypes.find(typeName) != mPolicyCriterionTypes.end(),
- "CriterionType %s not found", typeName.c_str());
- ALOGV("%s: Adding new value pair (%d,%s) for criterionType %s", __FUNCTION__,
- numericValue, literalValue.c_str(), typeName.c_str());
- ISelectionCriterionTypeInterface *criterionType = mPolicyCriterionTypes[typeName];
- std::string error;
- criterionType->addValuePair(numericValue, literalValue, error);
-}
-
-void ParameterManagerWrapper::loadCriterionType(cnode *root, bool isInclusive)
-{
- ALOG_ASSERT(root != NULL, "error in parsing file");
- cnode *node;
- for (node = root->first_child; node != NULL; node = node->next) {
-
- ALOG_ASSERT(node != NULL, "error in parsing file");
- const char *typeName = node->name;
- char *valueNames = strndup(node->value, strlen(node->value));
-
- addCriterionType(typeName, isInclusive);
-
- uint32_t index = 0;
- char *ctx;
- char *valueName = strtok_r(valueNames, ",", &ctx);
- while (valueName != NULL) {
- if (strlen(valueName) != 0) {
-
- // Conf file may use or not pair, if no pair, use incremental index, else
- // use provided index.
- if (strchr(valueName, ':') != NULL) {
-
- char *first = strtok(valueName, ":");
- char *second = strtok(NULL, ":");
- ALOG_ASSERT((first != NULL) && (strlen(first) != 0) &&
- (second != NULL) && (strlen(second) != 0),
- "invalid value pair");
-
- if (!convertTo<string, uint32_t>(first, index)) {
- ALOGE("%s: Invalid index(%s) found", __FUNCTION__, first);
- }
- addCriterionTypeValuePair(typeName, index, second);
- } else {
-
- uint32_t pfwIndex = isInclusive ? 1 << index : index;
- addCriterionTypeValuePair(typeName, pfwIndex, valueName);
- index += 1;
- }
- }
- valueName = strtok_r(NULL, ",", &ctx);
- }
- free(valueNames);
- }
-}
-
-void ParameterManagerWrapper::loadInclusiveCriterionType(cnode *root)
-{
- ALOG_ASSERT(root != NULL, "error in parsing file");
- cnode *node = config_find(root, gInclusiveCriterionTypeTag.c_str());
- if (node == NULL) {
- return;
- }
- loadCriterionType(node, true);
-}
-
-void ParameterManagerWrapper::loadExclusiveCriterionType(cnode *root)
-{
- ALOG_ASSERT(root != NULL, "error in parsing file");
- cnode *node = config_find(root, gExclusiveCriterionTypeTag.c_str());
- if (node == NULL) {
- return;
- }
- loadCriterionType(node, false);
-}
-
-void ParameterManagerWrapper::parseChildren(cnode *root, string &defaultValue, string &type)
-{
- ALOG_ASSERT(root != NULL, "error in parsing file");
- cnode *node;
- for (node = root->first_child; node != NULL; node = node->next) {
- ALOG_ASSERT(node != NULL, "error in parsing file");
-
- if (string(node->name) == gDefaultTag) {
- defaultValue = node->value;
- } else if (string(node->name) == gTypeTag) {
- type = node->value;
- } else {
- ALOGE("%s: Unrecognized %s %s node", __FUNCTION__, node->name, node->value);
- }
- }
-}
-
template <typename T>
T *ParameterManagerWrapper::getElement(const string &name, std::map<string, T *> &elementsMap)
{
@@ -235,97 +200,6 @@
return it != elementsMap.end() ? it->second : NULL;
}
-void ParameterManagerWrapper::loadCriteria(cnode *root)
-{
- ALOG_ASSERT(root != NULL, "error in parsing file");
- cnode *node = config_find(root, gCriterionTag.c_str());
-
- if (node == NULL) {
- ALOGW("%s: no inclusive criteria found", __FUNCTION__);
- return;
- }
- for (node = node->first_child; node != NULL; node = node->next) {
- loadCriterion(node);
- }
-}
-
-void ParameterManagerWrapper::addCriterion(const string &name, const string &typeName,
- const string &defaultLiteralValue)
-{
- ALOG_ASSERT(mPolicyCriteria.find(name) == mPolicyCriteria.end(),
- "Route Criterion %s already added", name.c_str());
-
- ISelectionCriterionTypeInterface *criterionType =
- getElement<ISelectionCriterionTypeInterface>(typeName, mPolicyCriterionTypes);
-
- ISelectionCriterionInterface *criterion =
- mPfwConnector->createSelectionCriterion(name, criterionType);
-
- mPolicyCriteria[name] = criterion;
- int numericalValue = 0;
- if (!criterionType->getNumericalValue(defaultLiteralValue.c_str(), numericalValue)) {
- ALOGE("%s; trying to apply invalid default literal value (%s)", __FUNCTION__,
- defaultLiteralValue.c_str());
- }
- criterion->setCriterionState(numericalValue);
-}
-
-void ParameterManagerWrapper::loadCriterion(cnode *root)
-{
- ALOG_ASSERT(root != NULL, "error in parsing file");
- const char *criterionName = root->name;
-
- ALOG_ASSERT(mPolicyCriteria.find(criterionName) == mPolicyCriteria.end(),
- "Criterion %s already added", criterionName);
-
- string paramKeyName = "";
- string path = "";
- string typeName = "";
- string defaultValue = "";
-
- parseChildren(root, defaultValue, typeName);
-
- addCriterion(criterionName, typeName, defaultValue);
-}
-
-void ParameterManagerWrapper::loadConfig(cnode *root)
-{
- ALOG_ASSERT(root != NULL, "error in parsing file");
- cnode *node = config_find(root, gPolicyConfTag.c_str());
- if (node == NULL) {
- ALOGW("%s: Could not find node for pfw", __FUNCTION__);
- return;
- }
- ALOGD("%s: Loading conf for pfw", __FUNCTION__);
- loadInclusiveCriterionType(node);
- loadExclusiveCriterionType(node);
- loadCriteria(node);
-}
-
-
-status_t ParameterManagerWrapper::loadAudioPolicyCriteriaConfig(const char *path)
-{
- ALOG_ASSERT(path != NULL, "error in parsing file: empty path");
- cnode *root;
- char *data;
- ALOGD("%s", __FUNCTION__);
- data = (char *)load_file(path, NULL);
- if (data == NULL) {
- return -ENODEV;
- }
- root = config_node("", "");
- ALOG_ASSERT(root != NULL, "Unable to allocate a configuration node");
- config_load(root, data);
-
- loadConfig(root);
-
- config_free(root);
- free(root);
- free(data);
- ALOGD("%s: loaded", __FUNCTION__);
- return NO_ERROR;
-}
-
bool ParameterManagerWrapper::isStarted()
{
return mPfwConnector && mPfwConnector->isStarted();
@@ -334,9 +208,9 @@
status_t ParameterManagerWrapper::setPhoneState(audio_mode_t mode)
{
ISelectionCriterionInterface *criterion =
- getElement<ISelectionCriterionInterface>(gPhoneStateCriterionTag, mPolicyCriteria);
+ getElement<ISelectionCriterionInterface>(gPhoneStateCriterionName, mPolicyCriteria);
if (criterion == NULL) {
- ALOGE("%s: no criterion found for %s", __FUNCTION__, gPhoneStateCriterionTag.c_str());
+ ALOGE("%s: no criterion found for %s", __FUNCTION__, gPhoneStateCriterionName);
return BAD_VALUE;
}
if (!isValueValidForCriterion(criterion, static_cast<int>(mode))) {
@@ -350,9 +224,9 @@
audio_mode_t ParameterManagerWrapper::getPhoneState() const
{
const ISelectionCriterionInterface *criterion =
- getElement<ISelectionCriterionInterface>(gPhoneStateCriterionTag, mPolicyCriteria);
+ getElement<ISelectionCriterionInterface>(gPhoneStateCriterionName, mPolicyCriteria);
if (criterion == NULL) {
- ALOGE("%s: no criterion found for %s", __FUNCTION__, gPhoneStateCriterionTag.c_str());
+ ALOGE("%s: no criterion found for %s", __FUNCTION__, gPhoneStateCriterionName);
return AUDIO_MODE_NORMAL;
}
return static_cast<audio_mode_t>(criterion->getCriterionState());
@@ -369,7 +243,7 @@
ISelectionCriterionInterface *criterion =
getElement<ISelectionCriterionInterface>(gForceUseCriterionTag[usage], mPolicyCriteria);
if (criterion == NULL) {
- ALOGE("%s: no criterion found for %s", __FUNCTION__, gForceUseCriterionTag[usage].c_str());
+ ALOGE("%s: no criterion found for %s", __FUNCTION__, gForceUseCriterionTag[usage]);
return BAD_VALUE;
}
if (!isValueValidForCriterion(criterion, static_cast<int>(config))) {
@@ -389,7 +263,7 @@
const ISelectionCriterionInterface *criterion =
getElement<ISelectionCriterionInterface>(gForceUseCriterionTag[usage], mPolicyCriteria);
if (criterion == NULL) {
- ALOGE("%s: no criterion found for %s", __FUNCTION__, gForceUseCriterionTag[usage].c_str());
+ ALOGE("%s: no criterion found for %s", __FUNCTION__, gForceUseCriterionTag[usage]);
return AUDIO_POLICY_FORCE_NONE;
}
return static_cast<audio_policy_forced_cfg_t>(criterion->getCriterionState());
@@ -403,12 +277,45 @@
return interface->getLiteralValue(valueToCheck, literalValue);
}
+status_t ParameterManagerWrapper::setDeviceConnectionState(const sp<DeviceDescriptor> devDesc,
+ audio_policy_dev_state_t state)
+{
+ std::string criterionName = audio_is_output_device(devDesc->type()) ?
+ gOutputDeviceAddressCriterionName : gInputDeviceAddressCriterionName;
+
+ ALOGV("%s: device with address %s %s", __FUNCTION__, devDesc->mAddress.string(),
+ state != AUDIO_POLICY_DEVICE_STATE_AVAILABLE? "disconnected" : "connected");
+ ISelectionCriterionInterface *criterion =
+ getElement<ISelectionCriterionInterface>(criterionName, mPolicyCriteria);
+
+ if (criterion == NULL) {
+ ALOGE("%s: no criterion found for %s", __FUNCTION__, criterionName.c_str());
+ return DEAD_OBJECT;
+ }
+
+ auto criterionType = criterion->getCriterionType();
+ int deviceAddressId;
+ if (not criterionType->getNumericalValue(devDesc->mAddress.string(), deviceAddressId)) {
+ ALOGE("%s: unknown device address reported (%s)", __FUNCTION__, devDesc->mAddress.c_str());
+ return BAD_TYPE;
+ }
+ int currentValueMask = criterion->getCriterionState();
+ if (state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) {
+ currentValueMask |= deviceAddressId;
+ }
+ else {
+ currentValueMask &= ~deviceAddressId;
+ }
+ criterion->setCriterionState(currentValueMask);
+ return NO_ERROR;
+}
+
status_t ParameterManagerWrapper::setAvailableInputDevices(audio_devices_t inputDevices)
{
ISelectionCriterionInterface *criterion =
- getElement<ISelectionCriterionInterface>(gInputDeviceCriterionTag, mPolicyCriteria);
+ getElement<ISelectionCriterionInterface>(gInputDeviceCriterionName, mPolicyCriteria);
if (criterion == NULL) {
- ALOGE("%s: no criterion found for %s", __FUNCTION__, gInputDeviceCriterionTag.c_str());
+ ALOGE("%s: no criterion found for %s", __FUNCTION__, gInputDeviceCriterionName);
return DEAD_OBJECT;
}
criterion->setCriterionState(inputDevices & ~AUDIO_DEVICE_BIT_IN);
@@ -419,9 +326,9 @@
status_t ParameterManagerWrapper::setAvailableOutputDevices(audio_devices_t outputDevices)
{
ISelectionCriterionInterface *criterion =
- getElement<ISelectionCriterionInterface>(gOutputDeviceCriterionTag, mPolicyCriteria);
+ getElement<ISelectionCriterionInterface>(gOutputDeviceCriterionName, mPolicyCriteria);
if (criterion == NULL) {
- ALOGE("%s: no criterion found for %s", __FUNCTION__, gOutputDeviceCriterionTag.c_str());
+ ALOGE("%s: no criterion found for %s", __FUNCTION__, gOutputDeviceCriterionName);
return DEAD_OBJECT;
}
criterion->setCriterionState(outputDevices);