xref: /aosp_15_r20/frameworks/av/media/libaudioclient/AudioPolicy.cpp (revision ec779b8e0859a360c3d303172224686826e6e0e1)
1*ec779b8eSAndroid Build Coastguard Worker /*
2*ec779b8eSAndroid Build Coastguard Worker  * Copyright (C) 2014 The Android Open Source Project
3*ec779b8eSAndroid Build Coastguard Worker  *
4*ec779b8eSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*ec779b8eSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*ec779b8eSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*ec779b8eSAndroid Build Coastguard Worker  *
8*ec779b8eSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*ec779b8eSAndroid Build Coastguard Worker  *
10*ec779b8eSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*ec779b8eSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*ec779b8eSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*ec779b8eSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*ec779b8eSAndroid Build Coastguard Worker  * limitations under the License.
15*ec779b8eSAndroid Build Coastguard Worker  */
16*ec779b8eSAndroid Build Coastguard Worker 
17*ec779b8eSAndroid Build Coastguard Worker #define LOG_TAG "AudioPolicy"
18*ec779b8eSAndroid Build Coastguard Worker //#define LOG_NDEBUG 0
19*ec779b8eSAndroid Build Coastguard Worker #include <utils/Log.h>
20*ec779b8eSAndroid Build Coastguard Worker #include <media/AudioPolicy.h>
21*ec779b8eSAndroid Build Coastguard Worker 
22*ec779b8eSAndroid Build Coastguard Worker namespace android {
23*ec779b8eSAndroid Build Coastguard Worker 
24*ec779b8eSAndroid Build Coastguard Worker //
25*ec779b8eSAndroid Build Coastguard Worker //  AudioMixMatchCriterion implementation
26*ec779b8eSAndroid Build Coastguard Worker //
AudioMixMatchCriterion(audio_usage_t usage,audio_source_t source,uint32_t rule)27*ec779b8eSAndroid Build Coastguard Worker AudioMixMatchCriterion::AudioMixMatchCriterion(audio_usage_t usage,
28*ec779b8eSAndroid Build Coastguard Worker                                                  audio_source_t source,
29*ec779b8eSAndroid Build Coastguard Worker                                                  uint32_t rule)
30*ec779b8eSAndroid Build Coastguard Worker : mRule(rule)
31*ec779b8eSAndroid Build Coastguard Worker {
32*ec779b8eSAndroid Build Coastguard Worker     if (mRule == RULE_MATCH_ATTRIBUTE_USAGE ||
33*ec779b8eSAndroid Build Coastguard Worker             mRule == RULE_EXCLUDE_ATTRIBUTE_USAGE) {
34*ec779b8eSAndroid Build Coastguard Worker         mValue.mUsage = usage;
35*ec779b8eSAndroid Build Coastguard Worker     } else {
36*ec779b8eSAndroid Build Coastguard Worker         mValue.mSource = source;
37*ec779b8eSAndroid Build Coastguard Worker     }
38*ec779b8eSAndroid Build Coastguard Worker }
39*ec779b8eSAndroid Build Coastguard Worker 
readFromParcel(Parcel * parcel)40*ec779b8eSAndroid Build Coastguard Worker status_t AudioMixMatchCriterion::readFromParcel(Parcel *parcel)
41*ec779b8eSAndroid Build Coastguard Worker {
42*ec779b8eSAndroid Build Coastguard Worker     mRule = parcel->readInt32();
43*ec779b8eSAndroid Build Coastguard Worker     switch (mRule) {
44*ec779b8eSAndroid Build Coastguard Worker     case RULE_MATCH_ATTRIBUTE_USAGE:
45*ec779b8eSAndroid Build Coastguard Worker     case RULE_EXCLUDE_ATTRIBUTE_USAGE:
46*ec779b8eSAndroid Build Coastguard Worker         mValue.mUsage = (audio_usage_t) parcel->readInt32();
47*ec779b8eSAndroid Build Coastguard Worker         break;
48*ec779b8eSAndroid Build Coastguard Worker     case RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET:
49*ec779b8eSAndroid Build Coastguard Worker     case RULE_EXCLUDE_ATTRIBUTE_CAPTURE_PRESET:
50*ec779b8eSAndroid Build Coastguard Worker         mValue.mSource = (audio_source_t) parcel->readInt32();
51*ec779b8eSAndroid Build Coastguard Worker         break;
52*ec779b8eSAndroid Build Coastguard Worker     case RULE_MATCH_UID:
53*ec779b8eSAndroid Build Coastguard Worker     case RULE_EXCLUDE_UID:
54*ec779b8eSAndroid Build Coastguard Worker         mValue.mUid = (uid_t) parcel->readInt32();
55*ec779b8eSAndroid Build Coastguard Worker         break;
56*ec779b8eSAndroid Build Coastguard Worker     case RULE_MATCH_USERID:
57*ec779b8eSAndroid Build Coastguard Worker     case RULE_EXCLUDE_USERID:
58*ec779b8eSAndroid Build Coastguard Worker         mValue.mUserId = (int) parcel->readInt32();
59*ec779b8eSAndroid Build Coastguard Worker         break;
60*ec779b8eSAndroid Build Coastguard Worker     case RULE_MATCH_AUDIO_SESSION_ID:
61*ec779b8eSAndroid Build Coastguard Worker     case RULE_EXCLUDE_AUDIO_SESSION_ID:
62*ec779b8eSAndroid Build Coastguard Worker         mValue.mAudioSessionId = (audio_session_t) parcel->readInt32();
63*ec779b8eSAndroid Build Coastguard Worker         break;
64*ec779b8eSAndroid Build Coastguard Worker     default:
65*ec779b8eSAndroid Build Coastguard Worker         ALOGE("Trying to build AudioMixMatchCriterion from unknown rule %d", mRule);
66*ec779b8eSAndroid Build Coastguard Worker         return BAD_VALUE;
67*ec779b8eSAndroid Build Coastguard Worker     }
68*ec779b8eSAndroid Build Coastguard Worker     return NO_ERROR;
69*ec779b8eSAndroid Build Coastguard Worker }
70*ec779b8eSAndroid Build Coastguard Worker 
writeToParcel(Parcel * parcel) const71*ec779b8eSAndroid Build Coastguard Worker status_t AudioMixMatchCriterion::writeToParcel(Parcel *parcel) const
72*ec779b8eSAndroid Build Coastguard Worker {
73*ec779b8eSAndroid Build Coastguard Worker     parcel->writeInt32(mRule);
74*ec779b8eSAndroid Build Coastguard Worker     parcel->writeInt32(mValue.mUsage);
75*ec779b8eSAndroid Build Coastguard Worker     return NO_ERROR;
76*ec779b8eSAndroid Build Coastguard Worker }
77*ec779b8eSAndroid Build Coastguard Worker 
isExcludeCriterion() const78*ec779b8eSAndroid Build Coastguard Worker bool AudioMixMatchCriterion::isExcludeCriterion() const {
79*ec779b8eSAndroid Build Coastguard Worker     return mRule & RULE_EXCLUSION_MASK;
80*ec779b8eSAndroid Build Coastguard Worker }
81*ec779b8eSAndroid Build Coastguard Worker 
82*ec779b8eSAndroid Build Coastguard Worker //
83*ec779b8eSAndroid Build Coastguard Worker //  AudioMix implementation
84*ec779b8eSAndroid Build Coastguard Worker //
85*ec779b8eSAndroid Build Coastguard Worker 
readFromParcel(Parcel * parcel)86*ec779b8eSAndroid Build Coastguard Worker status_t AudioMix::readFromParcel(Parcel *parcel)
87*ec779b8eSAndroid Build Coastguard Worker {
88*ec779b8eSAndroid Build Coastguard Worker     mMixType = parcel->readInt32();
89*ec779b8eSAndroid Build Coastguard Worker     mFormat.sample_rate = (uint32_t)parcel->readInt32();
90*ec779b8eSAndroid Build Coastguard Worker     mFormat.channel_mask = (audio_channel_mask_t)parcel->readInt32();
91*ec779b8eSAndroid Build Coastguard Worker     mFormat.format = (audio_format_t)parcel->readInt32();
92*ec779b8eSAndroid Build Coastguard Worker     mRouteFlags = parcel->readInt32();
93*ec779b8eSAndroid Build Coastguard Worker     mDeviceType = (audio_devices_t) parcel->readInt32();
94*ec779b8eSAndroid Build Coastguard Worker     mDeviceAddress = parcel->readString8();
95*ec779b8eSAndroid Build Coastguard Worker     mCbFlags = (uint32_t)parcel->readInt32();
96*ec779b8eSAndroid Build Coastguard Worker     mAllowPrivilegedMediaPlaybackCapture = parcel->readBool();
97*ec779b8eSAndroid Build Coastguard Worker     mVoiceCommunicationCaptureAllowed = parcel->readBool();
98*ec779b8eSAndroid Build Coastguard Worker     size_t size = (size_t)parcel->readInt32();
99*ec779b8eSAndroid Build Coastguard Worker     if (size > MAX_CRITERIA_PER_MIX) {
100*ec779b8eSAndroid Build Coastguard Worker         size = MAX_CRITERIA_PER_MIX;
101*ec779b8eSAndroid Build Coastguard Worker     }
102*ec779b8eSAndroid Build Coastguard Worker     mCriteria.reserve(size);
103*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < size; i++) {
104*ec779b8eSAndroid Build Coastguard Worker         AudioMixMatchCriterion criterion;
105*ec779b8eSAndroid Build Coastguard Worker         if (criterion.readFromParcel(parcel) == NO_ERROR) {
106*ec779b8eSAndroid Build Coastguard Worker             mCriteria.push_back(criterion);
107*ec779b8eSAndroid Build Coastguard Worker         }
108*ec779b8eSAndroid Build Coastguard Worker     }
109*ec779b8eSAndroid Build Coastguard Worker     return NO_ERROR;
110*ec779b8eSAndroid Build Coastguard Worker }
111*ec779b8eSAndroid Build Coastguard Worker 
writeToParcel(Parcel * parcel) const112*ec779b8eSAndroid Build Coastguard Worker status_t AudioMix::writeToParcel(Parcel *parcel) const
113*ec779b8eSAndroid Build Coastguard Worker {
114*ec779b8eSAndroid Build Coastguard Worker     parcel->writeInt32(mMixType);
115*ec779b8eSAndroid Build Coastguard Worker     parcel->writeInt32(mFormat.sample_rate);
116*ec779b8eSAndroid Build Coastguard Worker     parcel->writeInt32(mFormat.channel_mask);
117*ec779b8eSAndroid Build Coastguard Worker     parcel->writeInt32(mFormat.format);
118*ec779b8eSAndroid Build Coastguard Worker     parcel->writeInt32(mRouteFlags);
119*ec779b8eSAndroid Build Coastguard Worker     parcel->writeInt32(mDeviceType);
120*ec779b8eSAndroid Build Coastguard Worker     parcel->writeString8(mDeviceAddress);
121*ec779b8eSAndroid Build Coastguard Worker     parcel->writeInt32(mCbFlags);
122*ec779b8eSAndroid Build Coastguard Worker     parcel->writeBool(mAllowPrivilegedMediaPlaybackCapture);
123*ec779b8eSAndroid Build Coastguard Worker     parcel->writeBool(mVoiceCommunicationCaptureAllowed);
124*ec779b8eSAndroid Build Coastguard Worker     size_t size = mCriteria.size();
125*ec779b8eSAndroid Build Coastguard Worker     if (size > MAX_CRITERIA_PER_MIX) {
126*ec779b8eSAndroid Build Coastguard Worker         size = MAX_CRITERIA_PER_MIX;
127*ec779b8eSAndroid Build Coastguard Worker     }
128*ec779b8eSAndroid Build Coastguard Worker     size_t sizePosition = parcel->dataPosition();
129*ec779b8eSAndroid Build Coastguard Worker     parcel->writeInt32(size);
130*ec779b8eSAndroid Build Coastguard Worker     size_t finalSize = size;
131*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < size; i++) {
132*ec779b8eSAndroid Build Coastguard Worker         size_t position = parcel->dataPosition();
133*ec779b8eSAndroid Build Coastguard Worker         if (mCriteria[i].writeToParcel(parcel) != NO_ERROR) {
134*ec779b8eSAndroid Build Coastguard Worker             parcel->setDataPosition(position);
135*ec779b8eSAndroid Build Coastguard Worker             finalSize--;
136*ec779b8eSAndroid Build Coastguard Worker         }
137*ec779b8eSAndroid Build Coastguard Worker     }
138*ec779b8eSAndroid Build Coastguard Worker     if (size != finalSize) {
139*ec779b8eSAndroid Build Coastguard Worker         size_t position = parcel->dataPosition();
140*ec779b8eSAndroid Build Coastguard Worker         parcel->setDataPosition(sizePosition);
141*ec779b8eSAndroid Build Coastguard Worker         parcel->writeInt32(finalSize);
142*ec779b8eSAndroid Build Coastguard Worker         parcel->setDataPosition(position);
143*ec779b8eSAndroid Build Coastguard Worker     }
144*ec779b8eSAndroid Build Coastguard Worker     return NO_ERROR;
145*ec779b8eSAndroid Build Coastguard Worker }
146*ec779b8eSAndroid Build Coastguard Worker 
setExcludeUid(uid_t uid)147*ec779b8eSAndroid Build Coastguard Worker void AudioMix::setExcludeUid(uid_t uid) {
148*ec779b8eSAndroid Build Coastguard Worker     AudioMixMatchCriterion crit;
149*ec779b8eSAndroid Build Coastguard Worker     crit.mRule = RULE_EXCLUDE_UID;
150*ec779b8eSAndroid Build Coastguard Worker     crit.mValue.mUid = uid;
151*ec779b8eSAndroid Build Coastguard Worker     mCriteria.push_back(crit);
152*ec779b8eSAndroid Build Coastguard Worker }
153*ec779b8eSAndroid Build Coastguard Worker 
setMatchUid(uid_t uid)154*ec779b8eSAndroid Build Coastguard Worker void AudioMix::setMatchUid(uid_t uid) {
155*ec779b8eSAndroid Build Coastguard Worker     AudioMixMatchCriterion crit;
156*ec779b8eSAndroid Build Coastguard Worker     crit.mRule = RULE_MATCH_UID;
157*ec779b8eSAndroid Build Coastguard Worker     crit.mValue.mUid = uid;
158*ec779b8eSAndroid Build Coastguard Worker     mCriteria.push_back(crit);
159*ec779b8eSAndroid Build Coastguard Worker }
160*ec779b8eSAndroid Build Coastguard Worker 
hasUidRule(bool match,uid_t uid) const161*ec779b8eSAndroid Build Coastguard Worker bool AudioMix::hasUidRule(bool match, uid_t uid) const {
162*ec779b8eSAndroid Build Coastguard Worker     const uint32_t rule = match ? RULE_MATCH_UID : RULE_EXCLUDE_UID;
163*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < mCriteria.size(); i++) {
164*ec779b8eSAndroid Build Coastguard Worker         if (mCriteria[i].mRule == rule
165*ec779b8eSAndroid Build Coastguard Worker                 && mCriteria[i].mValue.mUid == uid) {
166*ec779b8eSAndroid Build Coastguard Worker             return true;
167*ec779b8eSAndroid Build Coastguard Worker         }
168*ec779b8eSAndroid Build Coastguard Worker     }
169*ec779b8eSAndroid Build Coastguard Worker     return false;
170*ec779b8eSAndroid Build Coastguard Worker }
171*ec779b8eSAndroid Build Coastguard Worker 
hasMatchUidRule() const172*ec779b8eSAndroid Build Coastguard Worker bool AudioMix::hasMatchUidRule() const {
173*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < mCriteria.size(); i++) {
174*ec779b8eSAndroid Build Coastguard Worker         if (mCriteria[i].mRule == RULE_MATCH_UID) {
175*ec779b8eSAndroid Build Coastguard Worker             return true;
176*ec779b8eSAndroid Build Coastguard Worker         }
177*ec779b8eSAndroid Build Coastguard Worker     }
178*ec779b8eSAndroid Build Coastguard Worker     return false;
179*ec779b8eSAndroid Build Coastguard Worker }
180*ec779b8eSAndroid Build Coastguard Worker 
setExcludeUserId(int userId)181*ec779b8eSAndroid Build Coastguard Worker void AudioMix::setExcludeUserId(int userId) {
182*ec779b8eSAndroid Build Coastguard Worker     AudioMixMatchCriterion crit;
183*ec779b8eSAndroid Build Coastguard Worker     crit.mRule = RULE_EXCLUDE_USERID;
184*ec779b8eSAndroid Build Coastguard Worker     crit.mValue.mUserId = userId;
185*ec779b8eSAndroid Build Coastguard Worker     mCriteria.push_back(crit);
186*ec779b8eSAndroid Build Coastguard Worker }
187*ec779b8eSAndroid Build Coastguard Worker 
setMatchUserId(int userId)188*ec779b8eSAndroid Build Coastguard Worker void AudioMix::setMatchUserId(int userId) {
189*ec779b8eSAndroid Build Coastguard Worker     AudioMixMatchCriterion crit;
190*ec779b8eSAndroid Build Coastguard Worker     crit.mRule = RULE_MATCH_USERID;
191*ec779b8eSAndroid Build Coastguard Worker     crit.mValue.mUserId = userId;
192*ec779b8eSAndroid Build Coastguard Worker     mCriteria.push_back(crit);
193*ec779b8eSAndroid Build Coastguard Worker }
194*ec779b8eSAndroid Build Coastguard Worker 
hasUserIdRule(bool match,int userId) const195*ec779b8eSAndroid Build Coastguard Worker bool AudioMix::hasUserIdRule(bool match, int userId) const {
196*ec779b8eSAndroid Build Coastguard Worker     const uint32_t rule = match ? RULE_MATCH_USERID : RULE_EXCLUDE_USERID;
197*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < mCriteria.size(); i++) {
198*ec779b8eSAndroid Build Coastguard Worker         if (mCriteria[i].mRule == rule
199*ec779b8eSAndroid Build Coastguard Worker                 && mCriteria[i].mValue.mUserId == userId) {
200*ec779b8eSAndroid Build Coastguard Worker             return true;
201*ec779b8eSAndroid Build Coastguard Worker         }
202*ec779b8eSAndroid Build Coastguard Worker     }
203*ec779b8eSAndroid Build Coastguard Worker     return false;
204*ec779b8eSAndroid Build Coastguard Worker }
205*ec779b8eSAndroid Build Coastguard Worker 
hasUserIdRule(bool match) const206*ec779b8eSAndroid Build Coastguard Worker bool AudioMix::hasUserIdRule(bool match) const {
207*ec779b8eSAndroid Build Coastguard Worker     const uint32_t rule = match ? RULE_MATCH_USERID : RULE_EXCLUDE_USERID;
208*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < mCriteria.size(); i++) {
209*ec779b8eSAndroid Build Coastguard Worker         if (mCriteria[i].mRule == rule) {
210*ec779b8eSAndroid Build Coastguard Worker             return true;
211*ec779b8eSAndroid Build Coastguard Worker         }
212*ec779b8eSAndroid Build Coastguard Worker     }
213*ec779b8eSAndroid Build Coastguard Worker     return false;
214*ec779b8eSAndroid Build Coastguard Worker }
215*ec779b8eSAndroid Build Coastguard Worker 
isDeviceAffinityCompatible() const216*ec779b8eSAndroid Build Coastguard Worker bool AudioMix::isDeviceAffinityCompatible() const {
217*ec779b8eSAndroid Build Coastguard Worker     return ((mMixType == MIX_TYPE_PLAYERS)
218*ec779b8eSAndroid Build Coastguard Worker             && ((mRouteFlags & MIX_ROUTE_FLAG_RENDER) == MIX_ROUTE_FLAG_RENDER));
219*ec779b8eSAndroid Build Coastguard Worker }
220*ec779b8eSAndroid Build Coastguard Worker 
221*ec779b8eSAndroid Build Coastguard Worker } // namespace android
222