• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     case RULE_MATCH_AUDIO_SESSION_ID:
61     case RULE_EXCLUDE_AUDIO_SESSION_ID:
62         mValue.mAudioSessionId = (audio_session_t) parcel->readInt32();
63         break;
64     default:
65         ALOGE("Trying to build AudioMixMatchCriterion from unknown rule %d", mRule);
66         return BAD_VALUE;
67     }
68     return NO_ERROR;
69 }
70 
writeToParcel(Parcel * parcel) const71 status_t AudioMixMatchCriterion::writeToParcel(Parcel *parcel) const
72 {
73     parcel->writeInt32(mRule);
74     parcel->writeInt32(mValue.mUsage);
75     return NO_ERROR;
76 }
77 
isExcludeCriterion() const78 bool AudioMixMatchCriterion::isExcludeCriterion() const {
79     return mRule & RULE_EXCLUSION_MASK;
80 }
81 
82 //
83 //  AudioMix implementation
84 //
85 
readFromParcel(Parcel * parcel)86 status_t AudioMix::readFromParcel(Parcel *parcel)
87 {
88     mMixType = parcel->readInt32();
89     mFormat.sample_rate = (uint32_t)parcel->readInt32();
90     mFormat.channel_mask = (audio_channel_mask_t)parcel->readInt32();
91     mFormat.format = (audio_format_t)parcel->readInt32();
92     mRouteFlags = parcel->readInt32();
93     mDeviceType = (audio_devices_t) parcel->readInt32();
94     mDeviceAddress = parcel->readString8();
95     mCbFlags = (uint32_t)parcel->readInt32();
96     mAllowPrivilegedMediaPlaybackCapture = parcel->readBool();
97     mVoiceCommunicationCaptureAllowed = parcel->readBool();
98     size_t size = (size_t)parcel->readInt32();
99     if (size > MAX_CRITERIA_PER_MIX) {
100         size = MAX_CRITERIA_PER_MIX;
101     }
102     mCriteria.reserve(size);
103     for (size_t i = 0; i < size; i++) {
104         AudioMixMatchCriterion criterion;
105         if (criterion.readFromParcel(parcel) == NO_ERROR) {
106             mCriteria.push_back(criterion);
107         }
108     }
109     return NO_ERROR;
110 }
111 
writeToParcel(Parcel * parcel) const112 status_t AudioMix::writeToParcel(Parcel *parcel) const
113 {
114     parcel->writeInt32(mMixType);
115     parcel->writeInt32(mFormat.sample_rate);
116     parcel->writeInt32(mFormat.channel_mask);
117     parcel->writeInt32(mFormat.format);
118     parcel->writeInt32(mRouteFlags);
119     parcel->writeInt32(mDeviceType);
120     parcel->writeString8(mDeviceAddress);
121     parcel->writeInt32(mCbFlags);
122     parcel->writeBool(mAllowPrivilegedMediaPlaybackCapture);
123     parcel->writeBool(mVoiceCommunicationCaptureAllowed);
124     size_t size = mCriteria.size();
125     if (size > MAX_CRITERIA_PER_MIX) {
126         size = MAX_CRITERIA_PER_MIX;
127     }
128     size_t sizePosition = parcel->dataPosition();
129     parcel->writeInt32(size);
130     size_t finalSize = size;
131     for (size_t i = 0; i < size; i++) {
132         size_t position = parcel->dataPosition();
133         if (mCriteria[i].writeToParcel(parcel) != NO_ERROR) {
134             parcel->setDataPosition(position);
135             finalSize--;
136         }
137     }
138     if (size != finalSize) {
139         size_t position = parcel->dataPosition();
140         parcel->setDataPosition(sizePosition);
141         parcel->writeInt32(finalSize);
142         parcel->setDataPosition(position);
143     }
144     return NO_ERROR;
145 }
146 
setExcludeUid(uid_t uid)147 void AudioMix::setExcludeUid(uid_t uid) {
148     AudioMixMatchCriterion crit;
149     crit.mRule = RULE_EXCLUDE_UID;
150     crit.mValue.mUid = uid;
151     mCriteria.push_back(crit);
152 }
153 
setMatchUid(uid_t uid)154 void AudioMix::setMatchUid(uid_t uid) {
155     AudioMixMatchCriterion crit;
156     crit.mRule = RULE_MATCH_UID;
157     crit.mValue.mUid = uid;
158     mCriteria.push_back(crit);
159 }
160 
hasUidRule(bool match,uid_t uid) const161 bool AudioMix::hasUidRule(bool match, uid_t uid) const {
162     const uint32_t rule = match ? RULE_MATCH_UID : RULE_EXCLUDE_UID;
163     for (size_t i = 0; i < mCriteria.size(); i++) {
164         if (mCriteria[i].mRule == rule
165                 && mCriteria[i].mValue.mUid == uid) {
166             return true;
167         }
168     }
169     return false;
170 }
171 
hasMatchUidRule() const172 bool AudioMix::hasMatchUidRule() const {
173     for (size_t i = 0; i < mCriteria.size(); i++) {
174         if (mCriteria[i].mRule == RULE_MATCH_UID) {
175             return true;
176         }
177     }
178     return false;
179 }
180 
setExcludeUserId(int userId)181 void AudioMix::setExcludeUserId(int userId) {
182     AudioMixMatchCriterion crit;
183     crit.mRule = RULE_EXCLUDE_USERID;
184     crit.mValue.mUserId = userId;
185     mCriteria.push_back(crit);
186 }
187 
setMatchUserId(int userId)188 void AudioMix::setMatchUserId(int userId) {
189     AudioMixMatchCriterion crit;
190     crit.mRule = RULE_MATCH_USERID;
191     crit.mValue.mUserId = userId;
192     mCriteria.push_back(crit);
193 }
194 
hasUserIdRule(bool match,int userId) const195 bool AudioMix::hasUserIdRule(bool match, int userId) const {
196     const uint32_t rule = match ? RULE_MATCH_USERID : RULE_EXCLUDE_USERID;
197     for (size_t i = 0; i < mCriteria.size(); i++) {
198         if (mCriteria[i].mRule == rule
199                 && mCriteria[i].mValue.mUserId == userId) {
200             return true;
201         }
202     }
203     return false;
204 }
205 
hasUserIdRule(bool match) const206 bool AudioMix::hasUserIdRule(bool match) const {
207     const uint32_t rule = match ? RULE_MATCH_USERID : RULE_EXCLUDE_USERID;
208     for (size_t i = 0; i < mCriteria.size(); i++) {
209         if (mCriteria[i].mRule == rule) {
210             return true;
211         }
212     }
213     return false;
214 }
215 
isDeviceAffinityCompatible() const216 bool AudioMix::isDeviceAffinityCompatible() const {
217     return ((mMixType == MIX_TYPE_PLAYERS)
218             && ((mRouteFlags & MIX_ROUTE_FLAG_RENDER) == MIX_ROUTE_FLAG_RENDER));
219 }
220 
221 } // namespace android
222