blob: 4d2b6b15968ffa1980bf3f17f65c1032e77d51f5 [file] [log] [blame]
Eric Laurent275e8e92014-11-30 15:14:47 -08001/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "AudioPolicy"
18//#define LOG_NDEBUG 0
19#include <utils/Log.h>
20#include <media/AudioPolicy.h>
21
22namespace android {
23
24//
Jean-Michel Trivie8deced2016-02-11 12:50:39 -080025// AudioMixMatchCriterion implementation
Eric Laurent275e8e92014-11-30 15:14:47 -080026//
Jean-Michel Trivie8deced2016-02-11 12:50:39 -080027AudioMixMatchCriterion::AudioMixMatchCriterion(audio_usage_t usage,
Eric Laurent275e8e92014-11-30 15:14:47 -080028 audio_source_t source,
29 uint32_t rule)
30: mRule(rule)
31{
32 if (mRule == RULE_MATCH_ATTRIBUTE_USAGE ||
33 mRule == RULE_EXCLUDE_ATTRIBUTE_USAGE) {
Jean-Michel Trivie8deced2016-02-11 12:50:39 -080034 mValue.mUsage = usage;
Eric Laurent275e8e92014-11-30 15:14:47 -080035 } else {
Jean-Michel Trivie8deced2016-02-11 12:50:39 -080036 mValue.mSource = source;
Eric Laurent275e8e92014-11-30 15:14:47 -080037 }
38}
39
Jean-Michel Trivie8deced2016-02-11 12:50:39 -080040status_t AudioMixMatchCriterion::readFromParcel(Parcel *parcel)
Eric Laurent275e8e92014-11-30 15:14:47 -080041{
42 mRule = parcel->readInt32();
Jean-Michel Trivibda70da2018-12-19 07:30:15 -080043 switch (mRule) {
44 case RULE_MATCH_ATTRIBUTE_USAGE:
45 case RULE_EXCLUDE_ATTRIBUTE_USAGE:
46 mValue.mUsage = (audio_usage_t) parcel->readInt32();
47 break;
48 case RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET:
49 case RULE_EXCLUDE_ATTRIBUTE_CAPTURE_PRESET:
50 mValue.mSource = (audio_source_t) parcel->readInt32();
51 break;
52 case RULE_MATCH_UID:
53 case RULE_EXCLUDE_UID:
54 mValue.mUid = (uid_t) parcel->readInt32();
55 break;
Oscar Azucena90e77632019-11-27 17:12:28 -080056 case RULE_MATCH_USERID:
57 case RULE_EXCLUDE_USERID:
58 mValue.mUserId = (int) parcel->readInt32();
59 break;
Jean-Michel Trivibda70da2018-12-19 07:30:15 -080060 default:
61 ALOGE("Trying to build AudioMixMatchCriterion from unknown rule %d", mRule);
62 return BAD_VALUE;
Eric Laurent275e8e92014-11-30 15:14:47 -080063 }
64 return NO_ERROR;
65}
66
Jean-Michel Trivie8deced2016-02-11 12:50:39 -080067status_t AudioMixMatchCriterion::writeToParcel(Parcel *parcel) const
Eric Laurent275e8e92014-11-30 15:14:47 -080068{
69 parcel->writeInt32(mRule);
Jean-Michel Trivie8deced2016-02-11 12:50:39 -080070 parcel->writeInt32(mValue.mUsage);
Eric Laurent275e8e92014-11-30 15:14:47 -080071 return NO_ERROR;
72}
73
Jan Sebechlebsky0e7b2f12022-08-18 14:40:37 +020074bool AudioMixMatchCriterion::isExcludeCriterion() const {
75 return mRule & RULE_EXCLUSION_MASK;
76}
77
Eric Laurent275e8e92014-11-30 15:14:47 -080078//
79// AudioMix implementation
80//
81
82status_t AudioMix::readFromParcel(Parcel *parcel)
83{
84 mMixType = parcel->readInt32();
85 mFormat.sample_rate = (uint32_t)parcel->readInt32();
86 mFormat.channel_mask = (audio_channel_mask_t)parcel->readInt32();
87 mFormat.format = (audio_format_t)parcel->readInt32();
88 mRouteFlags = parcel->readInt32();
Jean-Michel Trivi7638ca22016-03-04 17:42:44 -080089 mDeviceType = (audio_devices_t) parcel->readInt32();
90 mDeviceAddress = parcel->readString8();
Jean-Michel Trivif613d422015-04-23 18:41:29 -070091 mCbFlags = (uint32_t)parcel->readInt32();
Eric Laurent5f9a6452020-12-22 20:10:10 +010092 mAllowPrivilegedMediaPlaybackCapture = parcel->readBool();
Nadav Bar287d3302020-02-05 14:55:38 +020093 mVoiceCommunicationCaptureAllowed = parcel->readBool();
Eric Laurent275e8e92014-11-30 15:14:47 -080094 size_t size = (size_t)parcel->readInt32();
95 if (size > MAX_CRITERIA_PER_MIX) {
96 size = MAX_CRITERIA_PER_MIX;
97 }
Jan Sebechlebsky069787e2022-08-17 14:07:45 +020098 mCriteria.reserve(size);
Eric Laurent275e8e92014-11-30 15:14:47 -080099 for (size_t i = 0; i < size; i++) {
Jean-Michel Trivie8deced2016-02-11 12:50:39 -0800100 AudioMixMatchCriterion criterion;
Eric Laurent275e8e92014-11-30 15:14:47 -0800101 if (criterion.readFromParcel(parcel) == NO_ERROR) {
Jan Sebechlebsky069787e2022-08-17 14:07:45 +0200102 mCriteria.push_back(criterion);
Eric Laurent275e8e92014-11-30 15:14:47 -0800103 }
104 }
105 return NO_ERROR;
106}
107
108status_t AudioMix::writeToParcel(Parcel *parcel) const
109{
110 parcel->writeInt32(mMixType);
111 parcel->writeInt32(mFormat.sample_rate);
112 parcel->writeInt32(mFormat.channel_mask);
113 parcel->writeInt32(mFormat.format);
114 parcel->writeInt32(mRouteFlags);
Jean-Michel Trivi7638ca22016-03-04 17:42:44 -0800115 parcel->writeInt32(mDeviceType);
116 parcel->writeString8(mDeviceAddress);
Jean-Michel Trivif613d422015-04-23 18:41:29 -0700117 parcel->writeInt32(mCbFlags);
Eric Laurent5f9a6452020-12-22 20:10:10 +0100118 parcel->writeBool(mAllowPrivilegedMediaPlaybackCapture);
Nadav Bar287d3302020-02-05 14:55:38 +0200119 parcel->writeBool(mVoiceCommunicationCaptureAllowed);
Eric Laurent275e8e92014-11-30 15:14:47 -0800120 size_t size = mCriteria.size();
121 if (size > MAX_CRITERIA_PER_MIX) {
122 size = MAX_CRITERIA_PER_MIX;
123 }
124 size_t sizePosition = parcel->dataPosition();
125 parcel->writeInt32(size);
126 size_t finalSize = size;
127 for (size_t i = 0; i < size; i++) {
128 size_t position = parcel->dataPosition();
129 if (mCriteria[i].writeToParcel(parcel) != NO_ERROR) {
130 parcel->setDataPosition(position);
131 finalSize--;
132 }
133 }
134 if (size != finalSize) {
135 size_t position = parcel->dataPosition();
136 parcel->setDataPosition(sizePosition);
137 parcel->writeInt32(finalSize);
138 parcel->setDataPosition(position);
139 }
140 return NO_ERROR;
141}
142
Jan Sebechlebsky069787e2022-08-17 14:07:45 +0200143void AudioMix::setExcludeUid(uid_t uid) {
Jean-Michel Trivibda70da2018-12-19 07:30:15 -0800144 AudioMixMatchCriterion crit;
145 crit.mRule = RULE_EXCLUDE_UID;
146 crit.mValue.mUid = uid;
Jan Sebechlebsky069787e2022-08-17 14:07:45 +0200147 mCriteria.push_back(crit);
Jean-Michel Trivibda70da2018-12-19 07:30:15 -0800148}
149
Jan Sebechlebsky069787e2022-08-17 14:07:45 +0200150void AudioMix::setMatchUid(uid_t uid) {
Jean-Michel Trivi17dc1782019-01-10 19:00:05 -0800151 AudioMixMatchCriterion crit;
152 crit.mRule = RULE_MATCH_UID;
153 crit.mValue.mUid = uid;
Jan Sebechlebsky069787e2022-08-17 14:07:45 +0200154 mCriteria.push_back(crit);
Jean-Michel Trivi17dc1782019-01-10 19:00:05 -0800155}
156
Jean-Michel Trivie2f34be2019-05-09 12:31:06 -0700157bool AudioMix::hasUidRule(bool match, uid_t uid) const {
158 const uint32_t rule = match ? RULE_MATCH_UID : RULE_EXCLUDE_UID;
159 for (size_t i = 0; i < mCriteria.size(); i++) {
160 if (mCriteria[i].mRule == rule
161 && mCriteria[i].mValue.mUid == uid) {
162 return true;
163 }
164 }
165 return false;
166}
167
168bool AudioMix::hasMatchUidRule() const {
169 for (size_t i = 0; i < mCriteria.size(); i++) {
170 if (mCriteria[i].mRule == RULE_MATCH_UID) {
171 return true;
172 }
173 }
174 return false;
175}
176
Jan Sebechlebsky069787e2022-08-17 14:07:45 +0200177void AudioMix::setExcludeUserId(int userId) {
Oscar Azucena90e77632019-11-27 17:12:28 -0800178 AudioMixMatchCriterion crit;
179 crit.mRule = RULE_EXCLUDE_USERID;
180 crit.mValue.mUserId = userId;
Jan Sebechlebsky069787e2022-08-17 14:07:45 +0200181 mCriteria.push_back(crit);
Oscar Azucena90e77632019-11-27 17:12:28 -0800182}
183
Jan Sebechlebsky069787e2022-08-17 14:07:45 +0200184void AudioMix::setMatchUserId(int userId) {
Oscar Azucena90e77632019-11-27 17:12:28 -0800185 AudioMixMatchCriterion crit;
186 crit.mRule = RULE_MATCH_USERID;
187 crit.mValue.mUserId = userId;
Jan Sebechlebsky069787e2022-08-17 14:07:45 +0200188 mCriteria.push_back(crit);
Oscar Azucena90e77632019-11-27 17:12:28 -0800189}
190
191bool AudioMix::hasUserIdRule(bool match, int userId) const {
192 const uint32_t rule = match ? RULE_MATCH_USERID : RULE_EXCLUDE_USERID;
193 for (size_t i = 0; i < mCriteria.size(); i++) {
194 if (mCriteria[i].mRule == rule
195 && mCriteria[i].mValue.mUserId == userId) {
196 return true;
197 }
198 }
199 return false;
200}
201
202bool AudioMix::hasMatchUserIdRule() const {
203 for (size_t i = 0; i < mCriteria.size(); i++) {
204 if (mCriteria[i].mRule == RULE_MATCH_USERID) {
205 return true;
206 }
207 }
208 return false;
209}
210
Jean-Michel Trivie2f34be2019-05-09 12:31:06 -0700211bool AudioMix::isDeviceAffinityCompatible() const {
212 return ((mMixType == MIX_TYPE_PLAYERS)
213 && (mRouteFlags == MIX_ROUTE_FLAG_RENDER));
214}
215
Glenn Kasten40bc9062015-03-20 09:09:33 -0700216} // namespace android