summaryrefslogtreecommitdiffstats
path: root/services/audiopolicy/engineconfigurable/src
diff options
context:
space:
mode:
authorFrançois Gaffie <francois.gaffie@intel.com>2015-03-24 09:01:14 +0100
committerEric Laurent <elaurent@google.com>2015-04-24 14:57:55 -0700
commit65c3781db3443531deacecfbda5c7e7e82868a34 (patch)
tree5560072d1f61a9d76e437ef311ef282976fc253d /services/audiopolicy/engineconfigurable/src
parent21db57282da8b3daba1549f3a8e41c4fbaf80059 (diff)
downloadframeworks_av-65c3781db3443531deacecfbda5c7e7e82868a34.zip
frameworks_av-65c3781db3443531deacecfbda5c7e7e82868a34.tar.gz
frameworks_av-65c3781db3443531deacecfbda5c7e7e82868a34.tar.bz2
Add a configurable version of the policy engine based on PFW
This patch adds a configurable version of the policy engine based on the parameter framework. This configurable engine shall be activated with a flag USE_CONFIGURABLE_AUDIO_POLICY within BoardConfig.mk This patch provides the generic configuration as an example. This configuration provides the same user experience as the default policy engine. Change-Id: Ic8217333ae370b89bfdd2ad11320c5f14ea4da34 Signed-off-by: François Gaffie <francois.gaffie@intel.com>
Diffstat (limited to 'services/audiopolicy/engineconfigurable/src')
-rwxr-xr-xservices/audiopolicy/engineconfigurable/src/Collection.h163
-rwxr-xr-xservices/audiopolicy/engineconfigurable/src/Element.h99
-rwxr-xr-xservices/audiopolicy/engineconfigurable/src/Engine.cpp281
-rwxr-xr-xservices/audiopolicy/engineconfigurable/src/Engine.h225
-rwxr-xr-xservices/audiopolicy/engineconfigurable/src/EngineInstance.cpp63
-rwxr-xr-xservices/audiopolicy/engineconfigurable/src/InputSource.cpp69
-rwxr-xr-xservices/audiopolicy/engineconfigurable/src/InputSource.h88
-rwxr-xr-xservices/audiopolicy/engineconfigurable/src/Strategy.cpp68
-rwxr-xr-xservices/audiopolicy/engineconfigurable/src/Strategy.h89
-rwxr-xr-xservices/audiopolicy/engineconfigurable/src/Stream.cpp158
-rwxr-xr-xservices/audiopolicy/engineconfigurable/src/Stream.h115
-rwxr-xr-xservices/audiopolicy/engineconfigurable/src/Usage.cpp57
-rwxr-xr-xservices/audiopolicy/engineconfigurable/src/Usage.h88
13 files changed, 1563 insertions, 0 deletions
diff --git a/services/audiopolicy/engineconfigurable/src/Collection.h b/services/audiopolicy/engineconfigurable/src/Collection.h
new file mode 100755
index 0000000..8f17b15
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/src/Collection.h
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "Element.h"
+#include "Stream.h"
+#include "Strategy.h"
+#include "Usage.h"
+#include "InputSource.h"
+#include <utils/Errors.h>
+#include <system/audio.h>
+#include <utils/Log.h>
+#include <map>
+#include <stdint.h>
+#include <string>
+
+namespace android
+{
+namespace audio_policy
+{
+
+/**
+ * Collection of policy element as a map indexed with a their UID type.
+ *
+ * @tparam Key type of the policy element indexing the collection.
+ * Policy Element supported are:
+ * - Strategy
+ * - Stream
+ * - InputSource
+ * - Usage.
+ */
+template <typename Key>
+class Collection : public std::map<Key, Element<Key> *>
+{
+private:
+ typedef Element<Key> T;
+ typedef typename std::map<Key, T *>::iterator CollectionIterator;
+ typedef typename std::map<Key, T *>::const_iterator CollectionConstIterator;
+
+public:
+ Collection()
+ {
+ collectionSupported();
+ }
+
+ /**
+ * Add a policy element to the collection. Policy elements are streams, strategies, input
+ * sources, ... Compile time error generated if called with not supported collection.
+ * It also set the key as the unique identifier of the policy element.
+ *
+ * @tparam Key indexing the collection of policy element.
+ * @param[in] name of the policy element to find.
+ * @param[in] key to be used to index this new policy element.
+ *
+ * @return NO_ERROR if the policy element has been successfully added to the collection.
+ */
+ status_t add(const std::string &name, Key key)
+ {
+ if ((*this).find(key) != (*this).end()) {
+ ALOGW("%s: element %s already added", __FUNCTION__, name.c_str());
+ return BAD_VALUE;
+ }
+ (*this)[key] = new T(name);
+ ALOGD("%s: adding element %s to collection", __FUNCTION__, name.c_str());
+ return (*this)[key]->setIdentifier(key);
+ }
+
+ /**
+ * Get a policy element from the collection by its key. Policy elements are streams, strategies,
+ * input sources, ... Compile time error generated if called with not supported collection.
+ *
+ * @tparam Key indexing the collection of policy element.
+ * @param[in] key of the policy element to find.
+ *
+ * @return valid pointer on policy element if found, NULL otherwise.
+ */
+ T *get(Key key) const
+ {
+ CollectionConstIterator it = (*this).find(key);
+ return (it == (*this).end()) ? NULL : it->second;
+ }
+
+ /**
+ * Find a policy element from the collection by its name. Policy elements are streams,
+ * strategies, input sources, ...
+ * Compile time error generated if called with not supported collection.
+ *
+ * @tparam Key indexing the collection of policy element.
+ * @param[in] name of the policy element to find.
+ * @param[in] elementsMap maps of policy elements to search into.
+ *
+ * @return valid pointer on element if found, NULL otherwise.
+ */
+ T *findByName(const std::string &name) const
+ {
+
+ CollectionConstIterator it;
+ for (it = (*this).begin(); it != (*this).end(); ++it) {
+ T *element = it->second;
+ if (element->getName() == name) {
+ return element;
+ }
+ }
+ return NULL;
+ }
+
+ /**
+ * Removes all the elements from the list and destroy them.
+ */
+ void clear()
+ {
+ CollectionIterator it;
+ for (it = (*this).begin(); it != (*this).end(); ++it) {
+ delete it->second;
+ }
+ (*this).clear();
+ }
+
+private:
+ /**
+ * provide a compile time error if no specialization is provided for a given type.
+ *
+ * @tparam T: type of the policyElement. Policy Element supported are:
+ * - Strategy
+ * - Stream
+ * - InputSource
+ * - Usage.
+ */
+ struct collectionSupported;
+};
+
+template <>
+struct Collection<audio_stream_type_t>::collectionSupported {};
+template <>
+struct Collection<std::string>::collectionSupported {};
+template <>
+struct Collection<audio_usage_t>::collectionSupported {};
+template <>
+struct Collection<audio_source_t>::collectionSupported {};
+template <>
+struct Collection<routing_strategy>::collectionSupported {};
+
+typedef Collection<routing_strategy> StrategyCollection;
+typedef Collection<audio_stream_type_t> StreamCollection;
+typedef Collection<audio_usage_t> UsageCollection;
+typedef Collection<audio_source_t> InputSourceCollection;
+
+} // namespace audio_policy
+} // namespace android
diff --git a/services/audiopolicy/engineconfigurable/src/Element.h b/services/audiopolicy/engineconfigurable/src/Element.h
new file mode 100755
index 0000000..52e77e5
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/src/Element.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <stdint.h>
+#include <string>
+#include <utils/Errors.h>
+#include <system/audio.h>
+#include <utils/Log.h>
+
+namespace android
+{
+namespace audio_policy
+{
+
+template <typename Key>
+class Element
+{
+public:
+ Element(const std::string &name)
+ : mName(name)
+ {}
+ ~Element() {}
+
+ /**
+ * Returns identifier of this policy element
+ *
+ * @returns string representing the name of this policy element
+ */
+ const std::string &getName() const { return mName; }
+
+ /**
+ * Set the unique identifier for this policy element.
+ *
+ * @tparam Key type of the unique identifier.
+ * @param[in] identifier to be set.
+ *
+ * @return NO_ERROR if the identifier is valid and set correctly, error code otherwise.
+ */
+ status_t setIdentifier(Key identifier)
+ {
+ mIdentifier = identifier;
+ return NO_ERROR;
+ }
+
+ /**
+ * @return the unique identifier of this policy element.
+ */
+ const Key &getIdentifier() const { return mIdentifier; }
+
+ /**
+ * A Policy element may implement getter/setter function for a given property.
+ * Property may be routing_strategy, audio_stream_type_t, audio_usage_t, audio_source_t
+ * or a string.
+ *
+ * @tparam Property for which this policy element has setter / getter.
+ * @return the property kept track by this policy base element.
+ */
+ template <typename Property>
+ Property get() const;
+
+ /**
+ * A Policy element may implement getter/setter function for a given property.
+ * Property may be routing_strategy, audio_stream_type_t, audio_usage_t, audio_source_t
+ * or a string.
+ *
+ * @tparam Property for which this policy element has setter / getter.
+ *
+ * @param[in] property value to be assigned for this policy base element.
+ *
+ * @return the property kept track by this policy base element.
+ */
+ template <typename Property>
+ status_t set(Property property);
+
+private:
+ /* Copy facilities are put private to disable copy. */
+ Element(const Element &object);
+ Element &operator=(const Element &object);
+
+ std::string mName; /**< Unique literal Identifier of a policy base element*/
+ Key mIdentifier; /**< Unique numerical Identifier of a policy base element*/
+};
+} // namespace audio_policy
+} // namespace android
diff --git a/services/audiopolicy/engineconfigurable/src/Engine.cpp b/services/audiopolicy/engineconfigurable/src/Engine.cpp
new file mode 100755
index 0000000..c5cccfd
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/src/Engine.cpp
@@ -0,0 +1,281 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "APM::AudioPolicyEngine"
+//#define LOG_NDEBUG 0
+
+//#define VERY_VERBOSE_LOGGING
+#ifdef VERY_VERBOSE_LOGGING
+#define ALOGVV ALOGV
+#else
+#define ALOGVV(a...) do { } while(0)
+#endif
+
+#include "Engine.h"
+#include "Strategy.h"
+#include "Stream.h"
+#include "InputSource.h"
+#include "Usage.h"
+#include <policy.h>
+#include <ParameterManagerWrapper.h>
+
+using std::string;
+using std::map;
+
+namespace android
+{
+namespace audio_policy
+{
+template <>
+StrategyCollection &Engine::getCollection<routing_strategy>()
+{
+ return mStrategyCollection;
+}
+template <>
+StreamCollection &Engine::getCollection<audio_stream_type_t>()
+{
+ return mStreamCollection;
+}
+template <>
+UsageCollection &Engine::getCollection<audio_usage_t>()
+{
+ return mUsageCollection;
+}
+template <>
+InputSourceCollection &Engine::getCollection<audio_source_t>()
+{
+ return mInputSourceCollection;
+}
+
+template <>
+const StrategyCollection &Engine::getCollection<routing_strategy>() const
+{
+ return mStrategyCollection;
+}
+template <>
+const StreamCollection &Engine::getCollection<audio_stream_type_t>() const
+{
+ return mStreamCollection;
+}
+template <>
+const UsageCollection &Engine::getCollection<audio_usage_t>() const
+{
+ return mUsageCollection;
+}
+template <>
+const InputSourceCollection &Engine::getCollection<audio_source_t>() const
+{
+ return mInputSourceCollection;
+}
+
+Engine::Engine()
+ : mManagerInterface(this),
+ mPluginInterface(this),
+ mPolicyParameterMgr(new ParameterManagerWrapper()),
+ mApmObserver(NULL)
+{
+ if (mPolicyParameterMgr->start() != NO_ERROR) {
+ ALOGE("%s: could not start Policy PFW", __FUNCTION__);
+ delete mPolicyParameterMgr;
+ mPolicyParameterMgr = NULL;
+ }
+}
+
+Engine::~Engine()
+{
+ mStrategyCollection.clear();
+ mStreamCollection.clear();
+ mInputSourceCollection.clear();
+ mUsageCollection.clear();
+}
+
+
+void Engine::setObserver(AudioPolicyManagerObserver *observer)
+{
+ ALOG_ASSERT(observer != NULL, "Invalid Audio Policy Manager observer");
+ mApmObserver = observer;
+}
+
+status_t Engine::initCheck()
+{
+ return (mPolicyParameterMgr != NULL) &&
+ mPolicyParameterMgr->isStarted() &&
+ (mApmObserver != NULL)?
+ NO_ERROR : NO_INIT;
+}
+
+bool Engine::setVolumeProfileForStream(const audio_stream_type_t &streamType,
+ Volume::device_category deviceCategory,
+ const VolumeCurvePoints &points)
+{
+ Stream *stream = getFromCollection<audio_stream_type_t>(streamType);
+ if (stream == NULL) {
+ ALOGE("%s: stream %d not found", __FUNCTION__, streamType);
+ return false;
+ }
+ return stream->setVolumeProfile(deviceCategory, points) == NO_ERROR;
+}
+
+template <typename Key>
+Element<Key> *Engine::getFromCollection(const Key &key) const
+{
+ const Collection<Key> collection = getCollection<Key>();
+ return collection.get(key);
+}
+
+template <typename Key>
+status_t Engine::add(const std::string &name, const Key &key)
+{
+ Collection<Key> &collection = getCollection<Key>();
+ return collection.add(name, key);
+}
+
+template <>
+routing_strategy Engine::getPropertyForKey<routing_strategy, audio_usage_t>(audio_usage_t usage) const
+{
+ const AudioOutputCollection &outputs = mApmObserver->getOutputs();
+
+ if (usage == AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY &&
+ (outputs.isStreamActive(AUDIO_STREAM_RING) ||
+ outputs.isStreamActive(AUDIO_STREAM_ALARM))) {
+ return STRATEGY_SONIFICATION;
+ }
+ return getPropertyForKey<routing_strategy, audio_usage_t>(usage);
+}
+
+template <typename Property, typename Key>
+Property Engine::getPropertyForKey(Key key) const
+{
+ Element<Key> *element = getFromCollection<Key>(key);
+ if (element == NULL) {
+ ALOGE("%s: Element not found within collection", __FUNCTION__);
+ return static_cast<Property>(0);
+ }
+ return element->template get<Property>();
+}
+
+template <>
+audio_devices_t Engine::getPropertyForKey<audio_devices_t, routing_strategy>(routing_strategy strategy) const
+{
+ const AudioOutputCollection &outputs = mApmObserver->getOutputs();
+
+ /** This is the only case handled programmatically because the PFW is unable to know the
+ * activity of streams.
+ *
+ * -While media is playing on a remote device, use the the sonification behavior.
+ * Note that we test this usecase before testing if media is playing because
+ * the isStreamActive() method only informs about the activity of a stream, not
+ * if it's for local playback. Note also that we use the same delay between both tests
+ *
+ * -When media is not playing anymore, fall back on the sonification behavior
+ */
+ if (strategy == STRATEGY_SONIFICATION_RESPECTFUL &&
+ !is_state_in_call(getPhoneState()) &&
+ !outputs.isStreamActiveRemotely(AUDIO_STREAM_MUSIC,
+ SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY) &&
+ outputs.isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) {
+ return getPropertyForKey<audio_devices_t, routing_strategy>(STRATEGY_MEDIA);
+ }
+ return getPropertyForKey<audio_devices_t, routing_strategy>(strategy);
+}
+
+routing_strategy Engine::ManagerInterfaceImpl::getStrategyForUsage(audio_usage_t usage)
+{
+ return mPolicyEngine->getPropertyForKey<routing_strategy, audio_usage_t>(usage);
+}
+
+audio_devices_t Engine::ManagerInterfaceImpl::getDeviceForStrategy(routing_strategy stategy) const
+{
+ return mPolicyEngine->getPropertyForKey<audio_devices_t, routing_strategy>(stategy);
+}
+
+template <typename Property, typename Key>
+bool Engine::setPropertyForKey(const Property &property, const Key &key)
+{
+ Element<Key> *element = getFromCollection<Key>(key);
+ if (element == NULL) {
+ ALOGE("%s: Element not found within collection", __FUNCTION__);
+ return BAD_VALUE;
+ }
+ return element->template set<Property>(property) == NO_ERROR;
+}
+
+float Engine::volIndexToAmpl(Volume::device_category category,
+ audio_stream_type_t streamType,
+ int indexInUi)
+{
+ Stream *stream = getFromCollection<audio_stream_type_t>(streamType);
+ if (stream == NULL) {
+ ALOGE("%s: Element indexed by key=%d not found", __FUNCTION__, streamType);
+ return 1.0f;
+ }
+ return stream->volIndexToAmpl(category, indexInUi);
+}
+
+status_t Engine::initStreamVolume(audio_stream_type_t streamType,
+ int indexMin, int indexMax)
+{
+ Stream *stream = getFromCollection<audio_stream_type_t>(streamType);
+ if (stream == NULL) {
+ ALOGE("%s: Stream Type %d not found", __FUNCTION__, streamType);
+ return BAD_TYPE;
+ }
+ return stream->initVolume(indexMin, indexMax);
+}
+
+status_t Engine::setPhoneState(audio_mode_t mode)
+{
+ return mPolicyParameterMgr->setPhoneState(mode);
+}
+
+audio_mode_t Engine::getPhoneState() const
+{
+ return mPolicyParameterMgr->getPhoneState();
+}
+
+status_t Engine::setForceUse(audio_policy_force_use_t usage,
+ audio_policy_forced_cfg_t config)
+{
+ return mPolicyParameterMgr->setForceUse(usage, config);
+}
+
+audio_policy_forced_cfg_t Engine::getForceUse(audio_policy_force_use_t usage) const
+{
+ return mPolicyParameterMgr->getForceUse(usage);
+}
+
+status_t Engine::setDeviceConnectionState(audio_devices_t devices, audio_policy_dev_state_t state,
+ const char *deviceAddress)
+{
+ return mPolicyParameterMgr->setDeviceConnectionState(devices, state, deviceAddress);
+}
+
+template <>
+AudioPolicyManagerInterface *Engine::queryInterface()
+{
+ return &mManagerInterface;
+}
+
+template <>
+AudioPolicyPluginInterface *Engine::queryInterface()
+{
+ return &mPluginInterface;
+}
+
+} // namespace audio_policy
+} // namespace android
+
+
diff --git a/services/audiopolicy/engineconfigurable/src/Engine.h b/services/audiopolicy/engineconfigurable/src/Engine.h
new file mode 100755
index 0000000..23ca7d0
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/src/Engine.h
@@ -0,0 +1,225 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+
+#include <AudioPolicyManagerInterface.h>
+#include <AudioPolicyPluginInterface.h>
+#include "Collection.h"
+
+namespace android
+{
+class AudioPolicyManagerObserver;
+
+namespace audio_policy
+{
+
+class ParameterManagerWrapper;
+class VolumeProfile;
+
+class Engine
+{
+public:
+ Engine();
+ virtual ~Engine();
+
+ template <class RequestedInterface>
+ RequestedInterface *queryInterface();
+
+private:
+ /// Interface members
+ class ManagerInterfaceImpl : public AudioPolicyManagerInterface
+ {
+ public:
+ ManagerInterfaceImpl(Engine *policyEngine)
+ : mPolicyEngine(policyEngine) {}
+
+ virtual android::status_t initCheck()
+ {
+ return mPolicyEngine->initCheck();
+ }
+ virtual void setObserver(AudioPolicyManagerObserver *observer)
+ {
+ mPolicyEngine->setObserver(observer);
+ }
+ virtual audio_devices_t getDeviceForInputSource(audio_source_t inputSource) const
+ {
+ return mPolicyEngine->getPropertyForKey<audio_devices_t, audio_source_t>(inputSource);
+ }
+ virtual audio_devices_t getDeviceForStrategy(routing_strategy stategy) const;
+ virtual routing_strategy getStrategyForStream(audio_stream_type_t stream)
+ {
+ return mPolicyEngine->getPropertyForKey<routing_strategy, audio_stream_type_t>(stream);
+ }
+ virtual routing_strategy getStrategyForUsage(audio_usage_t usage);
+ virtual status_t setPhoneState(audio_mode_t mode)
+ {
+ return mPolicyEngine->setPhoneState(mode);
+ }
+ virtual audio_mode_t getPhoneState() const
+ {
+ return mPolicyEngine->getPhoneState();
+ }
+ virtual status_t setForceUse(audio_policy_force_use_t usage,
+ audio_policy_forced_cfg_t config)
+ {
+ return mPolicyEngine->setForceUse(usage, config);
+ }
+ virtual audio_policy_forced_cfg_t getForceUse(audio_policy_force_use_t usage) const
+ {
+ return mPolicyEngine->getForceUse(usage);
+ }
+ virtual android::status_t setDeviceConnectionState(const sp<DeviceDescriptor> devDesc,
+ audio_policy_dev_state_t state)
+ {
+ return mPolicyEngine->setDeviceConnectionState(devDesc->type(), state,
+ devDesc->mAddress);
+ }
+ virtual status_t initStreamVolume(audio_stream_type_t stream,
+ int indexMin, int indexMax)
+ {
+ return mPolicyEngine->initStreamVolume(stream, indexMin, indexMax);
+ }
+
+ virtual void initializeVolumeCurves(bool /*isSpeakerDrcEnabled*/) {}
+
+ virtual float volIndexToAmpl(Volume::device_category deviceCategory,
+ audio_stream_type_t stream,
+ int indexInUi)
+ {
+ return mPolicyEngine->volIndexToAmpl(deviceCategory, stream, indexInUi);
+ }
+
+ private:
+ Engine *mPolicyEngine;
+ } mManagerInterface;
+
+ class PluginInterfaceImpl : public AudioPolicyPluginInterface
+ {
+ public:
+ PluginInterfaceImpl(Engine *policyEngine)
+ : mPolicyEngine(policyEngine) {}
+
+ virtual status_t addStrategy(const std::string &name, routing_strategy strategy)
+ {
+ return mPolicyEngine->add<routing_strategy>(name, strategy);
+ }
+ virtual status_t addStream(const std::string &name, audio_stream_type_t stream)
+ {
+ return mPolicyEngine->add<audio_stream_type_t>(name, stream);
+ }
+ virtual status_t addUsage(const std::string &name, audio_usage_t usage)
+ {
+ return mPolicyEngine->add<audio_usage_t>(name, usage);
+ }
+ virtual status_t addInputSource(const std::string &name, audio_source_t source)
+ {
+ return mPolicyEngine->add<audio_source_t>(name, source);
+ }
+ virtual bool setDeviceForStrategy(const routing_strategy &strategy, audio_devices_t devices)
+ {
+ return mPolicyEngine->setPropertyForKey<audio_devices_t, routing_strategy>(devices,
+ strategy);
+ }
+ virtual bool setStrategyForStream(const audio_stream_type_t &stream,
+ routing_strategy strategy)
+ {
+ return mPolicyEngine->setPropertyForKey<routing_strategy, audio_stream_type_t>(strategy,
+ stream);
+ }
+ virtual bool setVolumeProfileForStream(const audio_stream_type_t &stream,
+ Volume::device_category deviceCategory,
+ const VolumeCurvePoints &points)
+ {
+ return mPolicyEngine->setVolumeProfileForStream(stream, deviceCategory, points);
+ }
+
+ virtual bool setStrategyForUsage(const audio_usage_t &usage, routing_strategy strategy)
+ {
+ return mPolicyEngine->setPropertyForKey<routing_strategy, audio_usage_t>(strategy,
+ usage);
+ }
+ virtual bool setDeviceForInputSource(const audio_source_t &inputSource,
+ audio_devices_t device)
+ {
+ return mPolicyEngine->setPropertyForKey<audio_devices_t, audio_source_t>(device,
+ inputSource);
+ }
+
+ private:
+ Engine *mPolicyEngine;
+ } mPluginInterface;
+
+private:
+ /* Copy facilities are put private to disable copy. */
+ Engine(const Engine &object);
+ Engine &operator=(const Engine &object);
+
+ void setObserver(AudioPolicyManagerObserver *observer);
+
+ bool setVolumeProfileForStream(const audio_stream_type_t &stream,
+ Volume::device_category deviceCategory,
+ const VolumeCurvePoints &points);
+
+ status_t initCheck();
+ status_t setPhoneState(audio_mode_t mode);
+ audio_mode_t getPhoneState() const;
+ status_t setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config);
+ audio_policy_forced_cfg_t getForceUse(audio_policy_force_use_t usage) const;
+ status_t setDeviceConnectionState(audio_devices_t devices, audio_policy_dev_state_t state,
+ const char *deviceAddress);
+
+ float volIndexToAmpl(Volume::device_category category,
+ audio_stream_type_t stream,
+ int indexInUi);
+ status_t initStreamVolume(audio_stream_type_t stream, int indexMin, int indexMax);
+
+ StrategyCollection mStrategyCollection; /**< Strategies indexed by their enum id. */
+ StreamCollection mStreamCollection; /**< Streams indexed by their enum id. */
+ UsageCollection mUsageCollection; /**< Usages indexed by their enum id. */
+ InputSourceCollection mInputSourceCollection; /**< Input sources indexed by their enum id. */
+
+ template <typename Key>
+ status_t add(const std::string &name, const Key &key);
+
+ template <typename Key>
+ Element<Key> *getFromCollection(const Key &key) const;
+
+ template <typename Key>
+ const Collection<Key> &getCollection() const;
+
+ template <typename Key>
+ Collection<Key> &getCollection();
+
+ template <typename Property, typename Key>
+ Property getPropertyForKey(Key key) const;
+
+ template <typename Property, typename Key>
+ bool setPropertyForKey(const Property &property, const Key &key);
+
+ /**
+ * Policy Parameter Manager hidden through a wrapper.
+ */
+ ParameterManagerWrapper *mPolicyParameterMgr;
+
+ AudioPolicyManagerObserver *mApmObserver;
+};
+
+}; // namespace audio_policy
+
+}; // namespace android
+
diff --git a/services/audiopolicy/engineconfigurable/src/EngineInstance.cpp b/services/audiopolicy/engineconfigurable/src/EngineInstance.cpp
new file mode 100755
index 0000000..9aa89b2
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/src/EngineInstance.cpp
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <AudioPolicyManagerInterface.h>
+#include <AudioPolicyPluginInterface.h>
+#include "AudioPolicyEngineInstance.h"
+#include "Engine.h"
+
+using std::string;
+
+namespace android
+{
+namespace audio_policy
+{
+
+EngineInstance::EngineInstance()
+{
+}
+
+EngineInstance *EngineInstance::getInstance()
+{
+ static EngineInstance instance;
+ return &instance;
+}
+
+EngineInstance::~EngineInstance()
+{
+}
+
+Engine *EngineInstance::getEngine() const
+{
+ static Engine engine;
+ return &engine;
+}
+
+template <>
+AudioPolicyManagerInterface *EngineInstance::queryInterface() const
+{
+ return getEngine()->queryInterface<AudioPolicyManagerInterface>();
+}
+
+template <>
+AudioPolicyPluginInterface *EngineInstance::queryInterface() const
+{
+ return getEngine()->queryInterface<AudioPolicyPluginInterface>();
+}
+
+} // namespace audio_policy
+} // namespace android
+
diff --git a/services/audiopolicy/engineconfigurable/src/InputSource.cpp b/services/audiopolicy/engineconfigurable/src/InputSource.cpp
new file mode 100755
index 0000000..9ff1538
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/src/InputSource.cpp
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "APM::AudioPolicyEngine/InputSource"
+
+#include "InputSource.h"
+
+using std::string;
+
+namespace android
+{
+namespace audio_policy
+{
+status_t Element<audio_source_t>::setIdentifier(audio_source_t identifier)
+{
+ if (identifier > AUDIO_SOURCE_MAX && identifier != AUDIO_SOURCE_HOTWORD) {
+ return BAD_VALUE;
+ }
+ mIdentifier = identifier;
+ ALOGD("%s: InputSource %s identifier 0x%X", __FUNCTION__, getName().c_str(), identifier);
+ return NO_ERROR;
+}
+
+/**
+* Set the device associated to this source.
+* It checks if the input device is valid but allows to set a NONE device
+* (i.e. only the IN BIT is set).
+*
+* @param[in] devices selected for the given input source.
+* @tparam audio_devices_t: Applicable input device for this input source.
+*
+* @return NO_ERROR if the device is either valid or none, error code otherwise.
+*/
+template <>
+status_t Element<audio_source_t>::set(audio_devices_t devices)
+{
+ if (!audio_is_input_device(devices) && devices != AUDIO_DEVICE_BIT_IN) {
+ ALOGE("%s: trying to set an invalid device 0x%X for input source %s",
+ __FUNCTION__, devices, getName().c_str());
+ return BAD_VALUE;
+ }
+ ALOGD("%s: 0x%X for input source %s", __FUNCTION__, devices, getName().c_str());
+ mApplicableDevices = devices;
+ return NO_ERROR;
+}
+
+template <>
+audio_devices_t Element<audio_source_t>::get<audio_devices_t>() const
+{
+ ALOGV("%s: 0x%X for inputSource %s", __FUNCTION__, mApplicableDevices, getName().c_str());
+ return mApplicableDevices;
+}
+} // namespace audio_policy
+} // namespace android
+
+
diff --git a/services/audiopolicy/engineconfigurable/src/InputSource.h b/services/audiopolicy/engineconfigurable/src/InputSource.h
new file mode 100755
index 0000000..6c498dc
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/src/InputSource.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "Element.h"
+
+namespace android
+{
+namespace audio_policy
+{
+
+/**
+ * Specialization of policy base class element for audio_source_t
+ * @tparam audio_source_t Policy Base Element identified by the audio_source_t definition.
+ */
+template <>
+class Element<audio_source_t>
+{
+public:
+ Element(const std::string &name)
+ : mName(name),
+ mApplicableDevices(AUDIO_DEVICE_NONE)
+ {}
+ ~Element() {}
+
+ /**
+ * Returns identifier of this policy element
+ *
+ * @returns string representing the name of this policy element
+ */
+ const std::string &getName() const { return mName; }
+
+ /**
+ * Set the unique identifier for this policy element.
+ *
+ * @tparam Key type of the unique identifier.
+ * @param[in] identifier to be set.
+ *
+ * @return NO_ERROR if the identifier is valid and set correctly, error code otherwise.
+ */
+ status_t setIdentifier(audio_source_t identifier);
+
+ /**
+ * @return the unique identifier of this policy element.
+ */
+ audio_source_t getIdentifier() const { return mIdentifier; }
+
+ /**
+ * A Policy element may implement getter/setter function for a given property.
+ * Property may be routing_strategy, audio_stream_type_t, audio_usage_t, audio_source_t
+ * or a string.
+ */
+ template <typename Property>
+ Property get() const;
+
+ template <typename Property>
+ status_t set(Property property);
+
+private:
+ /* Copy facilities are put private to disable copy. */
+ Element(const Element &object);
+ Element &operator=(const Element &object);
+
+ std::string mName; /**< Unique literal Identifier of a policy base element*/
+ audio_source_t mIdentifier; /**< Unique numerical Identifier of a policy base element*/
+
+ audio_devices_t mApplicableDevices; /**< Applicable input device for this input source. */
+};
+
+typedef Element<audio_source_t> InputSource;
+
+} // namespace audio_policy
+} // namespace android
+
diff --git a/services/audiopolicy/engineconfigurable/src/Strategy.cpp b/services/audiopolicy/engineconfigurable/src/Strategy.cpp
new file mode 100755
index 0000000..847443a
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/src/Strategy.cpp
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "APM::AudioPolicyEngine/Strategy"
+
+#include "Strategy.h"
+
+using std::string;
+
+namespace android
+{
+namespace audio_policy
+{
+
+status_t Element<routing_strategy>::setIdentifier(routing_strategy identifier)
+{
+ if (identifier >= NUM_STRATEGIES) {
+ return BAD_VALUE;
+ }
+ mIdentifier = identifier;
+ ALOGD("%s: Strategy %s identifier 0x%X", __FUNCTION__, getName().c_str(), identifier);
+ return NO_ERROR;
+}
+
+/**
+ * Set the device associated to this strategy.
+ * It checks if the output device is valid but allows to set a NONE device
+ *
+ * @param[in] devices selected for the given strategy.
+ *
+ * @return NO_ERROR if the device is either valid or none, error code otherwise.
+ */
+template <>
+status_t Element<routing_strategy>::set<audio_devices_t>(audio_devices_t devices)
+{
+ if (!audio_is_output_devices(devices) && devices != AUDIO_DEVICE_NONE) {
+ ALOGE("%s: trying to set an invalid device 0x%X for strategy %s",
+ __FUNCTION__, devices, getName().c_str());
+ return BAD_VALUE;
+ }
+ ALOGD("%s: 0x%X for strategy %s", __FUNCTION__, devices, getName().c_str());
+ mApplicableDevices = devices;
+ return NO_ERROR;
+}
+
+template <>
+audio_devices_t Element<routing_strategy>::get<audio_devices_t>() const
+{
+ ALOGV("%s: 0x%X for strategy %s", __FUNCTION__, mApplicableDevices, getName().c_str());
+ return mApplicableDevices;
+}
+
+} // namespace audio_policy
+} // namespace android
+
diff --git a/services/audiopolicy/engineconfigurable/src/Strategy.h b/services/audiopolicy/engineconfigurable/src/Strategy.h
new file mode 100755
index 0000000..1157d55
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/src/Strategy.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "Element.h"
+#include <RoutingStrategy.h>
+
+namespace android
+{
+namespace audio_policy
+{
+
+/**
+ * @tparam audio_devices_t: Applicable output device(s) for this strategy.
+ */
+template <>
+class Element<routing_strategy>
+{
+public:
+ Element(const std::string &name)
+ : mName(name),
+ mApplicableDevices(AUDIO_DEVICE_NONE)
+ {}
+ ~Element() {}
+
+ /**
+ * Returns identifier of this policy element
+ *
+ * @returns string representing the name of this policy element
+ */
+ const std::string &getName() const { return mName; }
+
+ /**
+ * Set the unique identifier for this policy element.
+ *
+ * @tparam Key type of the unique identifier.
+ * @param[in] identifier to be set.
+ *
+ * @return NO_ERROR if the identifier is valid and set correctly, error code otherwise.
+ */
+ status_t setIdentifier(routing_strategy identifier);
+
+ /**
+ * @return the unique identifier of this policy element.
+ */
+ routing_strategy getIdentifier() const { return mIdentifier; }
+
+ /**
+ * A Policy element may implement getter/setter function for a given property.
+ * Property may be routing_strategy, audio_stream_type_t, audio_usage_t, audio_source_t
+ * or a string.
+ */
+ template <typename Property>
+ Property get() const;
+
+ template <typename Property>
+ status_t set(Property property);
+
+private:
+ /* Copy facilities are put private to disable copy. */
+ Element(const Element &object);
+ Element &operator=(const Element &object);
+
+ std::string mName; /**< Unique literal Identifier of a policy base element*/
+ routing_strategy mIdentifier; /**< Unique numerical Identifier of a policy base element*/
+
+ audio_devices_t mApplicableDevices; /**< Applicable output device(s) for this strategy. */
+};
+
+typedef Element<routing_strategy> Strategy;
+
+} // namespace audio_policy
+} // namespace android
+
+
diff --git a/services/audiopolicy/engineconfigurable/src/Stream.cpp b/services/audiopolicy/engineconfigurable/src/Stream.cpp
new file mode 100755
index 0000000..7126c27
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/src/Stream.cpp
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "APM::AudioPolicyEngine/Stream"
+
+#include "Stream.h"
+#include <system/audio.h>
+
+using std::string;
+
+namespace android
+{
+namespace audio_policy
+{
+
+status_t Element<audio_stream_type_t>::setIdentifier(audio_stream_type_t identifier)
+{
+ if (identifier > AUDIO_STREAM_CNT) {
+ return BAD_VALUE;
+ }
+ mIdentifier = identifier;
+ ALOGD("%s: Stream %s identifier 0x%X", __FUNCTION__, getName().c_str(), identifier);
+ return NO_ERROR;
+}
+
+/**
+* Set the strategy to follow for this stream.
+* It checks if the strategy is valid.
+*
+* @param[in] strategy to be followed.
+*
+* @return NO_ERROR if the strategy is set correctly, error code otherwise.
+*/
+template <>
+status_t Element<audio_stream_type_t>::set<routing_strategy>(routing_strategy strategy)
+{
+ if (strategy >= NUM_STRATEGIES) {
+ return BAD_VALUE;
+ }
+ mApplicableStrategy = strategy;
+ ALOGD("%s: 0x%X for Stream %s", __FUNCTION__, strategy, getName().c_str());
+ return NO_ERROR;
+}
+
+template <>
+routing_strategy Element<audio_stream_type_t>::get<routing_strategy>() const
+{
+ ALOGV("%s: 0x%X for Stream %s", __FUNCTION__, mApplicableStrategy, getName().c_str());
+ return mApplicableStrategy;
+}
+
+status_t Element<audio_stream_type_t>::setVolumeProfile(Volume::device_category category,
+ const VolumeCurvePoints &points)
+{
+ ALOGD("%s: adding volume profile for %s for device category %d, points nb =%d", __FUNCTION__,
+ getName().c_str(), category, points.size());
+ mVolumeProfiles[category] = points;
+
+ for (size_t i = 0; i < points.size(); i++) {
+ ALOGV("%s: %s cat=%d curve index =%d Index=%d dBAttenuation=%f",
+ __FUNCTION__, getName().c_str(), category, i, points[i].mIndex,
+ points[i].mDBAttenuation);
+ }
+ return NO_ERROR;
+}
+
+status_t Element<audio_stream_type_t>::initVolume(int indexMin, int indexMax)
+{
+ ALOGV("initStreamVolume() stream %s, min %d, max %d", getName().c_str(), indexMin, indexMax);
+ if (indexMin < 0 || indexMin >= indexMax) {
+ ALOGW("initStreamVolume() invalid index limits for stream %s, min %d, max %d",
+ getName().c_str(), indexMin, indexMax);
+ return BAD_VALUE;
+ }
+ mIndexMin = indexMin;
+ mIndexMax = indexMax;
+
+ return NO_ERROR;
+}
+
+float Element<audio_stream_type_t>::volIndexToAmpl(Volume::device_category deviceCategory,
+ int indexInUi)
+{
+ VolumeProfileConstIterator it = mVolumeProfiles.find(deviceCategory);
+ if (it == mVolumeProfiles.end()) {
+ ALOGE("%s: device category %d not found for stream %s", __FUNCTION__, deviceCategory,
+ getName().c_str());
+ return 1.0f;
+ }
+ const VolumeCurvePoints curve = mVolumeProfiles[deviceCategory];
+ if (curve.size() != Volume::VOLCNT) {
+ ALOGE("%s: invalid profile for category %d and for stream %s", __FUNCTION__, deviceCategory,
+ getName().c_str());
+ return 1.0f;
+ }
+
+ // the volume index in the UI is relative to the min and max volume indices for this stream type
+ int nbSteps = 1 + curve[Volume::VOLMAX].mIndex -
+ curve[Volume::VOLMIN].mIndex;
+
+ if (mIndexMax - mIndexMin == 0) {
+ ALOGE("%s: Invalid volume indexes Min=Max=%d", __FUNCTION__, mIndexMin);
+ return 1.0f;
+ }
+ int volIdx = (nbSteps * (indexInUi - mIndexMin)) /
+ (mIndexMax - mIndexMin);
+
+ // find what part of the curve this index volume belongs to, or if it's out of bounds
+ int segment = 0;
+ if (volIdx < curve[Volume::VOLMIN].mIndex) { // out of bounds
+ return 0.0f;
+ } else if (volIdx < curve[Volume::VOLKNEE1].mIndex) {
+ segment = 0;
+ } else if (volIdx < curve[Volume::VOLKNEE2].mIndex) {
+ segment = 1;
+ } else if (volIdx <= curve[Volume::VOLMAX].mIndex) {
+ segment = 2;
+ } else { // out of bounds
+ return 1.0f;
+ }
+
+ // linear interpolation in the attenuation table in dB
+ float decibels = curve[segment].mDBAttenuation +
+ ((float)(volIdx - curve[segment].mIndex)) *
+ ( (curve[segment+1].mDBAttenuation -
+ curve[segment].mDBAttenuation) /
+ ((float)(curve[segment+1].mIndex -
+ curve[segment].mIndex)) );
+
+ float amplification = exp(decibels * 0.115129f); /** exp( dB * ln(10) / 20 ) */
+
+ ALOGV("VOLUME vol index=[%d %d %d], dB=[%.1f %.1f %.1f] ampl=%.5f",
+ curve[segment].mIndex, volIdx,
+ curve[segment+1].mIndex,
+ curve[segment].mDBAttenuation,
+ decibels,
+ curve[segment+1].mDBAttenuation,
+ amplification);
+
+ return amplification;
+}
+
+} // namespace audio_policy
+} // namespace android
+
diff --git a/services/audiopolicy/engineconfigurable/src/Stream.h b/services/audiopolicy/engineconfigurable/src/Stream.h
new file mode 100755
index 0000000..03a9b3e9
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/src/Stream.h
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "Element.h"
+#include "EngineDefinition.h"
+#include <Volume.h>
+#include <RoutingStrategy.h>
+#include <map>
+
+namespace android
+{
+namespace audio_policy
+{
+/**
+ * @tparam routing_strategy: Applicable strategy for this stream.
+ */
+template <>
+class Element<audio_stream_type_t>
+{
+private:
+ typedef std::map<Volume::device_category, VolumeCurvePoints> VolumeProfiles;
+ typedef VolumeProfiles::iterator VolumeProfileIterator;
+ typedef VolumeProfiles::const_iterator VolumeProfileConstIterator;
+
+public:
+ Element(const std::string &name)
+ : mName(name),
+ mApplicableStrategy(STRATEGY_MEDIA),
+ mIndexMin(0),
+ mIndexMax(1)
+ {}
+ ~Element() {}
+
+ /**
+ * Returns identifier of this policy element
+ *
+ * @returns string representing the name of this policy element
+ */
+ const std::string &getName() const { return mName; }
+
+ /**
+ * Set the unique identifier for this policy element.
+ *
+ * @tparam Key type of the unique identifier.
+ * @param[in] identifier to be set.
+ *
+ * @return NO_ERROR if the identifier is valid and set correctly, error code otherwise.
+ */
+ status_t setIdentifier(audio_stream_type_t identifier);
+
+ /**
+ * @return the unique identifier of this policy element.
+ */
+ audio_stream_type_t getIdentifier() const { return mIdentifier; }
+
+ /**
+ * A Policy element may implement getter/setter function for a given property.
+ * Property may be routing_strategy, audio_stream_type_t, audio_usage_t, audio_source_t
+ * or a string.
+ */
+ template <typename Property>
+ Property get() const;
+
+ template <typename Property>
+ status_t set(Property property);
+
+ status_t setVolumeProfile(Volume::device_category category, const VolumeCurvePoints &points);
+
+ float volIndexToAmpl(Volume::device_category deviceCategory, int indexInUi);
+
+ status_t initVolume(int indexMin, int indexMax);
+
+private:
+ /* Copy facilities are put private to disable copy. */
+ Element(const Element &object);
+ Element &operator=(const Element &object);
+
+ std::string mName; /**< Unique literal Identifier of a policy base element*/
+ audio_stream_type_t mIdentifier; /**< Unique numerical Identifier of a policy base element*/
+
+ routing_strategy mApplicableStrategy; /**< Applicable strategy for this stream. */
+
+ /**
+ * Collection of volume profiles indexed by the stream type.
+ * Volume is the only reason why the stream profile was not removed from policy when introducing
+ * attributes.
+ */
+ VolumeProfiles mVolumeProfiles;
+
+ int mIndexMin;
+
+ int mIndexMax;
+};
+
+typedef Element<audio_stream_type_t> Stream;
+
+} // namespace audio_policy
+} // namespace android
+
+
diff --git a/services/audiopolicy/engineconfigurable/src/Usage.cpp b/services/audiopolicy/engineconfigurable/src/Usage.cpp
new file mode 100755
index 0000000..5d20828
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/src/Usage.cpp
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "APM::AudioPolicyEngine/Usage"
+
+#include "Usage.h"
+
+namespace android
+{
+namespace audio_policy
+{
+
+status_t Element<audio_usage_t>::setIdentifier(audio_usage_t identifier)
+{
+ if (identifier > AUDIO_USAGE_MAX) {
+ return BAD_VALUE;
+ }
+ mIdentifier = identifier;
+ ALOGD("%s: Usage %s has identifier 0x%X", __FUNCTION__, getName().c_str(), identifier);
+ return NO_ERROR;
+}
+
+template <>
+status_t Element<audio_usage_t>::set<routing_strategy>(routing_strategy strategy)
+{
+ if (strategy >= NUM_STRATEGIES) {
+ return BAD_VALUE;
+ }
+ ALOGD("%s: %d for Usage %s", __FUNCTION__, strategy, getName().c_str());
+ mApplicableStrategy = strategy;
+ return NO_ERROR;
+}
+
+template <>
+routing_strategy Element<audio_usage_t>::get<routing_strategy>() const
+{
+ ALOGD("%s: %d for Usage %s", __FUNCTION__, mApplicableStrategy, getName().c_str());
+ return mApplicableStrategy;
+}
+
+} // namespace audio_policy
+} // namespace android
+
+
diff --git a/services/audiopolicy/engineconfigurable/src/Usage.h b/services/audiopolicy/engineconfigurable/src/Usage.h
new file mode 100755
index 0000000..d69e0e0
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/src/Usage.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "Element.h"
+#include <RoutingStrategy.h>
+
+namespace android
+{
+namespace audio_policy
+{
+
+/**
+ * @tparam routing_strategy: Applicable strategy for this usage.
+ */
+template <>
+class Element<audio_usage_t>
+{
+public:
+ Element(const std::string &name)
+ : mName(name),
+ mApplicableStrategy(STRATEGY_MEDIA)
+ {}
+ ~Element() {}
+
+ /**
+ * Returns identifier of this policy element
+ *
+ * @returns string representing the name of this policy element
+ */
+ const std::string &getName() const { return mName; }
+
+ /**
+ * Set the unique identifier for this policy element.
+ *
+ * @tparam Key type of the unique identifier.
+ * @param[in] identifier to be set.
+ *
+ * @return NO_ERROR if the identifier is valid and set correctly, error code otherwise.
+ */
+ status_t setIdentifier(audio_usage_t identifier);
+
+ /**
+ * @return the unique identifier of this policy element.
+ */
+ audio_usage_t getIdentifier() const { return mIdentifier; }
+
+ /**
+ * A Policy element may implement getter/setter function for a given property.
+ * Property may be routing_strategy, audio_stream_type_t, audio_usage_t, audio_source_t
+ * or a string.
+ */
+ template <typename Property>
+ Property get() const;
+
+ template <typename Property>
+ status_t set(Property property);
+
+private:
+ /* Copy facilities are put private to disable copy. */
+ Element(const Element &object);
+ Element &operator=(const Element &object);
+
+ std::string mName; /**< Unique literal Identifier of a policy base element*/
+ audio_usage_t mIdentifier; /**< Unique numerical Identifier of a policy base element*/
+ routing_strategy mApplicableStrategy; /**< Applicable strategy for this usage. */
+};
+
+typedef Element<audio_usage_t> Usage;
+
+} // namespace audio_policy
+} // namespace android
+
+