1 /*
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
22 namespace android {
23
24 //
25 // AudioMixMatchCriterion implementation
26 //
AudioMixMatchCriterion(audio_usage_t usage,audio_source_t source,uint32_t rule)27 AudioMixMatchCriterion::AudioMixMatchCriterion(audio_usage_t usage,
28 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) {
34 mValue.mUsage = usage;
35 } else {
36 mValue.mSource = source;
37 }
38 }
39
readFromParcel(Parcel * parcel)40 status_t AudioMixMatchCriterion::readFromParcel(Parcel *parcel)
41 {
42 mRule = parcel->readInt32();
43 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;
56 case RULE_MATCH_USERID:
57 case RULE_EXCLUDE_USERID:
58 mValue.mUserId = (int) parcel->readInt32();
59 break;
60 default:
61 ALOGE("Trying to build AudioMixMatchCriterion from unknown rule %d", mRule);
62 return BAD_VALUE;
63 }
64 return NO_ERROR;
65 }
66
writeToParcel(Parcel * parcel) const67 status_t AudioMixMatchCriterion::writeToParcel(Parcel *parcel) const
68 {
69 parcel->writeInt32(mRule);
70 parcel->writeInt32(mValue.mUsage);
71 return NO_ERROR;
72 }
73
74 //
75 // AudioMix implementation
76 //
77
readFromParcel(Parcel * parcel)78 status_t AudioMix::readFromParcel(Parcel *parcel)
79 {
80 mMixType = parcel->readInt32();
81 mFormat.sample_rate = (uint32_t)parcel->readInt32();
82 mFormat.channel_mask = (audio_channel_mask_t)parcel->readInt32();
83 mFormat.format = (audio_format_t)parcel->readInt32();
84 mRouteFlags = parcel->readInt32();
85 mDeviceType = (audio_devices_t) parcel->readInt32();
86 mDeviceAddress = parcel->readString8();
87 mCbFlags = (uint32_t)parcel->readInt32();
88 mAllowPrivilegedMediaPlaybackCapture = parcel->readBool();
89 mVoiceCommunicationCaptureAllowed = parcel->readBool();
90 size_t size = (size_t)parcel->readInt32();
91 if (size > MAX_CRITERIA_PER_MIX) {
92 size = MAX_CRITERIA_PER_MIX;
93 }
94 for (size_t i = 0; i < size; i++) {
95 AudioMixMatchCriterion criterion;
96 if (criterion.readFromParcel(parcel) == NO_ERROR) {
97 mCriteria.add(criterion);
98 }
99 }
100 return NO_ERROR;
101 }
102
writeToParcel(Parcel * parcel) const103 status_t AudioMix::writeToParcel(Parcel *parcel) const
104 {
105 parcel->writeInt32(mMixType);
106 parcel->writeInt32(mFormat.sample_rate);
107 parcel->writeInt32(mFormat.channel_mask);
108 parcel->writeInt32(mFormat.format);
109 parcel->writeInt32(mRouteFlags);
110 parcel->writeInt32(mDeviceType);
111 parcel->writeString8(mDeviceAddress);
112 parcel->writeInt32(mCbFlags);
113 parcel->writeBool(mAllowPrivilegedMediaPlaybackCapture);
114 parcel->writeBool(mVoiceCommunicationCaptureAllowed);
115 size_t size = mCriteria.size();
116 if (size > MAX_CRITERIA_PER_MIX) {
117 size = MAX_CRITERIA_PER_MIX;
118 }
119 size_t sizePosition = parcel->dataPosition();
120 parcel->writeInt32(size);
121 size_t finalSize = size;
122 for (size_t i = 0; i < size; i++) {
123 size_t position = parcel->dataPosition();
124 if (mCriteria[i].writeToParcel(parcel) != NO_ERROR) {
125 parcel->setDataPosition(position);
126 finalSize--;
127 }
128 }
129 if (size != finalSize) {
130 size_t position = parcel->dataPosition();
131 parcel->setDataPosition(sizePosition);
132 parcel->writeInt32(finalSize);
133 parcel->setDataPosition(position);
134 }
135 return NO_ERROR;
136 }
137
setExcludeUid(uid_t uid) const138 void AudioMix::setExcludeUid(uid_t uid) const {
139 AudioMixMatchCriterion crit;
140 crit.mRule = RULE_EXCLUDE_UID;
141 crit.mValue.mUid = uid;
142 mCriteria.add(crit);
143 }
144
setMatchUid(uid_t uid) const145 void AudioMix::setMatchUid(uid_t uid) const {
146 AudioMixMatchCriterion crit;
147 crit.mRule = RULE_MATCH_UID;
148 crit.mValue.mUid = uid;
149 mCriteria.add(crit);
150 }
151
hasUidRule(bool match,uid_t uid) const152 bool AudioMix::hasUidRule(bool match, uid_t uid) const {
153 const uint32_t rule = match ? RULE_MATCH_UID : RULE_EXCLUDE_UID;
154 for (size_t i = 0; i < mCriteria.size(); i++) {
155 if (mCriteria[i].mRule == rule
156 && mCriteria[i].mValue.mUid == uid) {
157 return true;
158 }
159 }
160 return false;
161 }
162
hasMatchUidRule() const163 bool AudioMix::hasMatchUidRule() const {
164 for (size_t i = 0; i < mCriteria.size(); i++) {
165 if (mCriteria[i].mRule == RULE_MATCH_UID) {
166 return true;
167 }
168 }
169 return false;
170 }
171
setExcludeUserId(int userId) const172 void AudioMix::setExcludeUserId(int userId) const {
173 AudioMixMatchCriterion crit;
174 crit.mRule = RULE_EXCLUDE_USERID;
175 crit.mValue.mUserId = userId;
176 mCriteria.add(crit);
177 }
178
setMatchUserId(int userId) const179 void AudioMix::setMatchUserId(int userId) const {
180 AudioMixMatchCriterion crit;
181 crit.mRule = RULE_MATCH_USERID;
182 crit.mValue.mUserId = userId;
183 mCriteria.add(crit);
184 }
185
hasUserIdRule(bool match,int userId) const186 bool AudioMix::hasUserIdRule(bool match, int userId) const {
187 const uint32_t rule = match ? RULE_MATCH_USERID : RULE_EXCLUDE_USERID;
188 for (size_t i = 0; i < mCriteria.size(); i++) {
189 if (mCriteria[i].mRule == rule
190 && mCriteria[i].mValue.mUserId == userId) {
191 return true;
192 }
193 }
194 return false;
195 }
196
hasMatchUserIdRule() const197 bool AudioMix::hasMatchUserIdRule() const {
198 for (size_t i = 0; i < mCriteria.size(); i++) {
199 if (mCriteria[i].mRule == RULE_MATCH_USERID) {
200 return true;
201 }
202 }
203 return false;
204 }
205
isDeviceAffinityCompatible() const206 bool AudioMix::isDeviceAffinityCompatible() const {
207 return ((mMixType == MIX_TYPE_PLAYERS)
208 && (mRouteFlags == MIX_ROUTE_FLAG_RENDER));
209 }
210
211 } // namespace android
212