From 275e8e9de2e11b4b344f5a201f1f0e51fda02d9c Mon Sep 17 00:00:00 2001 From: Eric Laurent Date: Sun, 30 Nov 2014 15:14:47 -0800 Subject: audio policy: add support for custom mixes Add support for custom mixes in AudioPolicyManager. Two methods are added to register or unregister a list of custom mixes with their attributes and format. getOutputForAttr() and getInputForAttr() first look for a match in registered mixes before defaulting to normal output/input selection Remote submix device connection disconnection now takes address into account to identify the correspnoding custom mix. Bug: 16009464. Change-Id: I3f1c2a485a0fb71b1f984ed0adc9b68aa971e408 --- media/libmedia/AudioPolicy.cpp | 115 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 media/libmedia/AudioPolicy.cpp (limited to 'media/libmedia/AudioPolicy.cpp') diff --git a/media/libmedia/AudioPolicy.cpp b/media/libmedia/AudioPolicy.cpp new file mode 100644 index 0000000..d2d0971 --- /dev/null +++ b/media/libmedia/AudioPolicy.cpp @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2014 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 "AudioPolicy" +//#define LOG_NDEBUG 0 +#include +#include + +namespace android { + +// +// AttributeMatchCriterion implementation +// +AttributeMatchCriterion::AttributeMatchCriterion(audio_usage_t usage, + audio_source_t source, + uint32_t rule) +: mRule(rule) +{ + if (mRule == RULE_MATCH_ATTRIBUTE_USAGE || + mRule == RULE_EXCLUDE_ATTRIBUTE_USAGE) { + mAttr.mUsage = usage; + } else { + mAttr.mSource = source; + } +} + +status_t AttributeMatchCriterion::readFromParcel(Parcel *parcel) +{ + mRule = parcel->readInt32(); + if (mRule == RULE_MATCH_ATTRIBUTE_USAGE || + mRule == RULE_EXCLUDE_ATTRIBUTE_USAGE) { + mAttr.mUsage = (audio_usage_t)parcel->readInt32(); + } else { + mAttr.mSource = (audio_source_t)parcel->readInt32(); + } + return NO_ERROR; +} + +status_t AttributeMatchCriterion::writeToParcel(Parcel *parcel) const +{ + parcel->writeInt32(mRule); + parcel->writeInt32(mAttr.mUsage); + return NO_ERROR; +} + +// +// AudioMix implementation +// + +status_t AudioMix::readFromParcel(Parcel *parcel) +{ + mMixType = parcel->readInt32(); + mFormat.sample_rate = (uint32_t)parcel->readInt32(); + mFormat.channel_mask = (audio_channel_mask_t)parcel->readInt32(); + mFormat.format = (audio_format_t)parcel->readInt32(); + mRouteFlags = parcel->readInt32(); + mRegistrationId = parcel->readString8(); + size_t size = (size_t)parcel->readInt32(); + if (size > MAX_CRITERIA_PER_MIX) { + size = MAX_CRITERIA_PER_MIX; + } + for (size_t i = 0; i < size; i++) { + AttributeMatchCriterion criterion; + if (criterion.readFromParcel(parcel) == NO_ERROR) { + mCriteria.add(criterion); + } + } + return NO_ERROR; +} + +status_t AudioMix::writeToParcel(Parcel *parcel) const +{ + parcel->writeInt32(mMixType); + parcel->writeInt32(mFormat.sample_rate); + parcel->writeInt32(mFormat.channel_mask); + parcel->writeInt32(mFormat.format); + parcel->writeInt32(mRouteFlags); + parcel->writeString8(mRegistrationId); + size_t size = mCriteria.size(); + if (size > MAX_CRITERIA_PER_MIX) { + size = MAX_CRITERIA_PER_MIX; + } + size_t sizePosition = parcel->dataPosition(); + parcel->writeInt32(size); + size_t finalSize = size; + for (size_t i = 0; i < size; i++) { + size_t position = parcel->dataPosition(); + if (mCriteria[i].writeToParcel(parcel) != NO_ERROR) { + parcel->setDataPosition(position); + finalSize--; + } + } + if (size != finalSize) { + size_t position = parcel->dataPosition(); + parcel->setDataPosition(sizePosition); + parcel->writeInt32(finalSize); + parcel->setDataPosition(position); + } + return NO_ERROR; +} + +}; // namespace android -- cgit v1.1