diff options
Diffstat (limited to 'services/audiopolicy/engineconfigurable/src/Engine.cpp')
-rwxr-xr-x | services/audiopolicy/engineconfigurable/src/Engine.cpp | 281 |
1 files changed, 281 insertions, 0 deletions
diff --git a/services/audiopolicy/engineconfigurable/src/Engine.cpp b/services/audiopolicy/engineconfigurable/src/Engine.cpp new file mode 100755 index 0000000..61fae71 --- /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 SwAudioOutputCollection &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 SwAudioOutputCollection &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::volIndexToDb(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->volIndexToDb(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 + + |