1036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie/* 2036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie * Copyright (C) 2015 The Android Open Source Project 3036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie * 4036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie * Licensed under the Apache License, Version 2.0 (the "License"); 5036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie * you may not use this file except in compliance with the License. 6036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie * You may obtain a copy of the License at 7036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie * 8036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie * http://www.apache.org/licenses/LICENSE-2.0 9036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie * 10036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie * Unless required by applicable law or agreed to in writing, software 11036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie * distributed under the License is distributed on an "AS IS" BASIS, 12036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie * See the License for the specific language governing permissions and 14036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie * limitations under the License. 15036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie */ 16036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie 175ac8cd425e1a0c4287c0bb84f922fef4fa106411Jean-Michel Trivi#define LOG_TAG "APM_AudioPolicyMix" 18036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie//#define LOG_NDEBUG 0 19036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie 20036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie#include "AudioPolicyMix.h" 21036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie#include "HwModule.h" 22036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie#include "AudioPort.h" 23036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie#include "IOProfile.h" 24036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie#include "AudioGain.h" 25036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie#include <AudioOutputDescriptor.h> 26036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie 27036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffienamespace android { 28036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie 29c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentvoid AudioPolicyMix::setOutput(sp<SwAudioOutputDescriptor> &output) 30036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie{ 31036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie mOutput = output; 32036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie} 33036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie 34c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentconst sp<SwAudioOutputDescriptor> &AudioPolicyMix::getOutput() const 35036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie{ 36036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie return mOutput; 37036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie} 38036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie 39036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffievoid AudioPolicyMix::clearOutput() 40036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie{ 41036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie mOutput.clear(); 42036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie} 43036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie 44036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffievoid AudioPolicyMix::setMix(AudioMix &mix) 45036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie{ 46036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie mMix = mix; 47036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie} 48036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie 49dacc06f5e8d00ace9d16a149fc41ff65323ffbb3Jean-Michel Triviandroid::AudioMix *AudioPolicyMix::getMix() 50036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie{ 51dacc06f5e8d00ace9d16a149fc41ff65323ffbb3Jean-Michel Trivi return &mMix; 52036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie} 53036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie 547638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivistatus_t AudioPolicyMixCollection::registerMix(String8 address, AudioMix mix, 557638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi sp<SwAudioOutputDescriptor> desc) 56036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie{ 57036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie ssize_t index = indexOfKey(address); 58036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie if (index >= 0) { 59036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie ALOGE("registerPolicyMixes(): mix for address %s already registered", address.string()); 60036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie return BAD_VALUE; 61036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie } 62036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie sp<AudioPolicyMix> policyMix = new AudioPolicyMix(); 63036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie policyMix->setMix(mix); 64036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie add(address, policyMix); 657638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi 667638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi if (desc != 0) { 677638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi desc->mPolicyMix = policyMix->getMix(); 687638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi policyMix->setOutput(desc); 697638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi } 70036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie return NO_ERROR; 71036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie} 72036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie 73036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffiestatus_t AudioPolicyMixCollection::unregisterMix(String8 address) 74036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie{ 75036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie ssize_t index = indexOfKey(address); 76036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie if (index < 0) { 77036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie ALOGE("unregisterPolicyMixes(): mix for address %s not registered", address.string()); 78036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie return BAD_VALUE; 79036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie } 80036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie 81036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie removeItemsAt(index); 82036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie return NO_ERROR; 83036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie} 84036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie 85036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffiestatus_t AudioPolicyMixCollection::getAudioPolicyMix(String8 address, 86036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie sp<AudioPolicyMix> &policyMix) const 87036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie{ 88036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie ssize_t index = indexOfKey(address); 89036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie if (index < 0) { 90036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie ALOGE("unregisterPolicyMixes(): mix for address %s not registered", address.string()); 91036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie return BAD_VALUE; 92036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie } 93036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie policyMix = valueAt(index); 94036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie return NO_ERROR; 95036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie} 96036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie 97c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentvoid AudioPolicyMixCollection::closeOutput(sp<SwAudioOutputDescriptor> &desc) 98036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie{ 99036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie for (size_t i = 0; i < size(); i++) { 100036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie sp<AudioPolicyMix> policyMix = valueAt(i); 101036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie if (policyMix->getOutput() == desc) { 102036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie policyMix->clearOutput(); 103036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie } 104036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie } 105036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie} 106036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie 107e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivistatus_t AudioPolicyMixCollection::getOutputForAttr(audio_attributes_t attributes, uid_t uid, 108c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent sp<SwAudioOutputDescriptor> &desc) 109036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie{ 1105ac8cd425e1a0c4287c0bb84f922fef4fa106411Jean-Michel Trivi ALOGV("getOutputForAttr() querying %zu mixes:", size()); 111e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi desc = 0; 112036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie for (size_t i = 0; i < size(); i++) { 113036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie sp<AudioPolicyMix> policyMix = valueAt(i); 114dacc06f5e8d00ace9d16a149fc41ff65323ffbb3Jean-Michel Trivi AudioMix *mix = policyMix->getMix(); 115dacc06f5e8d00ace9d16a149fc41ff65323ffbb3Jean-Michel Trivi 116dacc06f5e8d00ace9d16a149fc41ff65323ffbb3Jean-Michel Trivi if (mix->mMixType == MIX_TYPE_PLAYERS) { 117e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi // TODO if adding more player rules (currently only 2), make rule handling "generic" 118e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi // as there is no difference in the treatment of usage- or uid-based rules 119e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi bool hasUsageMatchRules = false; 120e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi bool hasUsageExcludeRules = false; 121e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi bool usageMatchFound = false; 122e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi bool usageExclusionFound = false; 123e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi 124e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi bool hasUidMatchRules = false; 125e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi bool hasUidExcludeRules = false; 126e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi bool uidMatchFound = false; 127e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi bool uidExclusionFound = false; 128e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi 129e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi bool hasAddrMatch = false; 130e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi 131e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi // iterate over all mix criteria to list what rules this mix contains 132dacc06f5e8d00ace9d16a149fc41ff65323ffbb3Jean-Michel Trivi for (size_t j = 0; j < mix->mCriteria.size(); j++) { 1335ac8cd425e1a0c4287c0bb84f922fef4fa106411Jean-Michel Trivi ALOGV(" getOutputForAttr: mix %zu: inspecting mix criteria %zu of %zu", 1345ac8cd425e1a0c4287c0bb84f922fef4fa106411Jean-Michel Trivi i, j, mix->mCriteria.size()); 135e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi 136e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi // if there is an address match, prioritize that match 137036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie if (strncmp(attributes.tags, "addr=", strlen("addr=")) == 0 && 138036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie strncmp(attributes.tags + strlen("addr="), 1397638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi mix->mDeviceAddress.string(), 140036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - strlen("addr=") - 1) == 0) { 141e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi hasAddrMatch = true; 142036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie break; 143036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie } 144e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi 145e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi switch (mix->mCriteria[j].mRule) { 146e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi case RULE_MATCH_ATTRIBUTE_USAGE: 147e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi ALOGV("\tmix has RULE_MATCH_ATTRIBUTE_USAGE for usage %d", 148e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi mix->mCriteria[j].mValue.mUsage); 149e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi hasUsageMatchRules = true; 150e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi if (mix->mCriteria[j].mValue.mUsage == attributes.usage) { 151e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi // found one match against all allowed usages 152e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi usageMatchFound = true; 153e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi } 154e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi break; 155e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi case RULE_EXCLUDE_ATTRIBUTE_USAGE: 156e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi ALOGV("\tmix has RULE_EXCLUDE_ATTRIBUTE_USAGE for usage %d", 157e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi mix->mCriteria[j].mValue.mUsage); 158e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi hasUsageExcludeRules = true; 159e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi if (mix->mCriteria[j].mValue.mUsage == attributes.usage) { 160e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi // found this usage is to be excluded 161e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi usageExclusionFound = true; 162e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi } 163e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi break; 164e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi case RULE_MATCH_UID: 165e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi ALOGV("\tmix has RULE_MATCH_UID for uid %d", mix->mCriteria[j].mValue.mUid); 166e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi hasUidMatchRules = true; 167e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi if (mix->mCriteria[j].mValue.mUid == uid) { 168e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi // found one UID match against all allowed UIDs 169e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi uidMatchFound = true; 170e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi } 171e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi break; 172e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi case RULE_EXCLUDE_UID: 173e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi ALOGV("\tmix has RULE_EXCLUDE_UID for uid %d", mix->mCriteria[j].mValue.mUid); 174e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi hasUidExcludeRules = true; 175e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi if (mix->mCriteria[j].mValue.mUid == uid) { 176e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi // found this UID is to be excluded 177e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi uidExclusionFound = true; 178e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi } 179e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi break; 180e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi default: 181e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi break; 182e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi } 183e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi 184e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi // consistency checks: for each "dimension" of rules (usage, uid...), we can 185e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi // only have MATCH rules, or EXCLUDE rules in each dimension, not a combination 186e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi if (hasUsageMatchRules && hasUsageExcludeRules) { 187e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi ALOGE("getOutputForAttr: invalid combination of RULE_MATCH_ATTRIBUTE_USAGE" 188e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi " and RULE_EXCLUDE_ATTRIBUTE_USAGE in mix %zu", i); 189e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi return BAD_VALUE; 190e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi } 191e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi if (hasUidMatchRules && hasUidExcludeRules) { 192e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi ALOGE("getOutputForAttr: invalid combination of RULE_MATCH_UID" 193e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi " and RULE_EXCLUDE_UID in mix %zu", i); 194e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi return BAD_VALUE; 195e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi } 196e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi 197e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi if ((hasUsageExcludeRules && usageExclusionFound) 198e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi || (hasUidExcludeRules && uidExclusionFound)) { 199e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi break; // stop iterating on criteria because an exclusion was found (will fail) 200e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi } 201e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi 202e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi }//iterate on mix criteria 203e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi 204e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi // determine if exiting on success (or implicit failure as desc is 0) 205e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi if (hasAddrMatch || 206e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi !((hasUsageExcludeRules && usageExclusionFound) || 207e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi (hasUsageMatchRules && !usageMatchFound) || 208e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi (hasUidExcludeRules && uidExclusionFound) || 209e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi (hasUidMatchRules && !uidMatchFound))) { 210e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi ALOGV("\tgetOutputForAttr will use mix %zu", i); 211e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi desc = policyMix->getOutput(); 212036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie } 213e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi 214dacc06f5e8d00ace9d16a149fc41ff65323ffbb3Jean-Michel Trivi } else if (mix->mMixType == MIX_TYPE_RECORDERS) { 215036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie if (attributes.usage == AUDIO_USAGE_VIRTUAL_SOURCE && 216036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie strncmp(attributes.tags, "addr=", strlen("addr=")) == 0 && 217036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie strncmp(attributes.tags + strlen("addr="), 2187638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi mix->mDeviceAddress.string(), 219036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - strlen("addr=") - 1) == 0) { 220036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie desc = policyMix->getOutput(); 221036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie } 222036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie } 223036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie if (desc != 0) { 224dacc06f5e8d00ace9d16a149fc41ff65323ffbb3Jean-Michel Trivi desc->mPolicyMix = mix; 225036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie return NO_ERROR; 226036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie } 227036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie } 228036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie return BAD_VALUE; 229036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie} 230036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie 231036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffieaudio_devices_t AudioPolicyMixCollection::getDeviceAndMixForInputSource(audio_source_t inputSource, 232036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie audio_devices_t availDevices, 233036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie AudioMix **policyMix) 234036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie{ 235036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie for (size_t i = 0; i < size(); i++) { 236dacc06f5e8d00ace9d16a149fc41ff65323ffbb3Jean-Michel Trivi AudioMix *mix = valueAt(i)->getMix(); 237036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie 238dacc06f5e8d00ace9d16a149fc41ff65323ffbb3Jean-Michel Trivi if (mix->mMixType != MIX_TYPE_RECORDERS) { 239036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie continue; 240036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie } 241dacc06f5e8d00ace9d16a149fc41ff65323ffbb3Jean-Michel Trivi for (size_t j = 0; j < mix->mCriteria.size(); j++) { 242dacc06f5e8d00ace9d16a149fc41ff65323ffbb3Jean-Michel Trivi if ((RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET == mix->mCriteria[j].mRule && 243e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi mix->mCriteria[j].mValue.mSource == inputSource) || 244dacc06f5e8d00ace9d16a149fc41ff65323ffbb3Jean-Michel Trivi (RULE_EXCLUDE_ATTRIBUTE_CAPTURE_PRESET == mix->mCriteria[j].mRule && 245e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi mix->mCriteria[j].mValue.mSource != inputSource)) { 246036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie if (availDevices & AUDIO_DEVICE_IN_REMOTE_SUBMIX) { 247036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie if (policyMix != NULL) { 248dacc06f5e8d00ace9d16a149fc41ff65323ffbb3Jean-Michel Trivi *policyMix = mix; 249036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie } 250036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie return AUDIO_DEVICE_IN_REMOTE_SUBMIX; 251036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie } 252036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie break; 253036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie } 254036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie } 255036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie } 256036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie return AUDIO_DEVICE_NONE; 257036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie} 258036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie 259dacc06f5e8d00ace9d16a149fc41ff65323ffbb3Jean-Michel Trivistatus_t AudioPolicyMixCollection::getInputMixForAttr(audio_attributes_t attr, AudioMix **policyMix) 260036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie{ 261036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie if (strncmp(attr.tags, "addr=", strlen("addr=")) != 0) { 262036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie return BAD_VALUE; 263036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie } 264036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie String8 address(attr.tags + strlen("addr=")); 265036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie 266e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi#ifdef LOG_NDEBUG 267e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi ALOGV("getInputMixForAttr looking for address %s\n mixes available:", address.string()); 268e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi for (size_t i = 0; i < size(); i++) { 269e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi sp<AudioPolicyMix> policyMix = valueAt(i); 270e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi AudioMix *mix = policyMix->getMix(); 2717638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi ALOGV("\tmix %zu address=%s", i, mix->mDeviceAddress.string()); 272e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi } 273e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi#endif 274e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi 275036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie ssize_t index = indexOfKey(address); 276036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie if (index < 0) { 2778c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent ALOGW("getInputMixForAttr() no policy for address %s", address.string()); 278036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie return BAD_VALUE; 279036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie } 280036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie sp<AudioPolicyMix> audioPolicyMix = valueAt(index); 281dacc06f5e8d00ace9d16a149fc41ff65323ffbb3Jean-Michel Trivi AudioMix *mix = audioPolicyMix->getMix(); 282036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie 283dacc06f5e8d00ace9d16a149fc41ff65323ffbb3Jean-Michel Trivi if (mix->mMixType != MIX_TYPE_PLAYERS) { 2848c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent ALOGW("getInputMixForAttr() bad policy mix type for address %s", address.string()); 285036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie return BAD_VALUE; 286036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie } 287dacc06f5e8d00ace9d16a149fc41ff65323ffbb3Jean-Michel Trivi *policyMix = mix; 288036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie return NO_ERROR; 289036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie} 290036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie 291036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie}; //namespace android 292