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