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 // AudioDeviceTypeAddr implementation
26 //
readFromParcel(Parcel * parcel)27 status_t AudioDeviceTypeAddr::readFromParcel(Parcel *parcel) {
28 mType = (audio_devices_t) parcel->readInt32();
29 mAddress = parcel->readString8();
30 return NO_ERROR;
31 }
32
writeToParcel(Parcel * parcel) const33 status_t AudioDeviceTypeAddr::writeToParcel(Parcel *parcel) const {
34 parcel->writeInt32((int32_t) mType);
35 parcel->writeString8(mAddress);
36 return NO_ERROR;
37 }
38
39
40 //
41 // AudioMixMatchCriterion implementation
42 //
AudioMixMatchCriterion(audio_usage_t usage,audio_source_t source,uint32_t rule)43 AudioMixMatchCriterion::AudioMixMatchCriterion(audio_usage_t usage,
44 audio_source_t source,
45 uint32_t rule)
46 : mRule(rule)
47 {
48 if (mRule == RULE_MATCH_ATTRIBUTE_USAGE ||
49 mRule == RULE_EXCLUDE_ATTRIBUTE_USAGE) {
50 mValue.mUsage = usage;
51 } else {
52 mValue.mSource = source;
53 }
54 }
55
readFromParcel(Parcel * parcel)56 status_t AudioMixMatchCriterion::readFromParcel(Parcel *parcel)
57 {
58 mRule = parcel->readInt32();
59 switch (mRule) {
60 case RULE_MATCH_ATTRIBUTE_USAGE:
61 case RULE_EXCLUDE_ATTRIBUTE_USAGE:
62 mValue.mUsage = (audio_usage_t) parcel->readInt32();
63 break;
64 case RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET:
65 case RULE_EXCLUDE_ATTRIBUTE_CAPTURE_PRESET:
66 mValue.mSource = (audio_source_t) parcel->readInt32();
67 break;
68 case RULE_MATCH_UID:
69 case RULE_EXCLUDE_UID:
70 mValue.mUid = (uid_t) parcel->readInt32();
71 break;
72 default:
73 ALOGE("Trying to build AudioMixMatchCriterion from unknown rule %d", mRule);
74 return BAD_VALUE;
75 }
76 return NO_ERROR;
77 }
78
writeToParcel(Parcel * parcel) const79 status_t AudioMixMatchCriterion::writeToParcel(Parcel *parcel) const
80 {
81 parcel->writeInt32(mRule);
82 parcel->writeInt32(mValue.mUsage);
83 return NO_ERROR;
84 }
85
86 //
87 // AudioMix implementation
88 //
89
readFromParcel(Parcel * parcel)90 status_t AudioMix::readFromParcel(Parcel *parcel)
91 {
92 mMixType = parcel->readInt32();
93 mFormat.sample_rate = (uint32_t)parcel->readInt32();
94 mFormat.channel_mask = (audio_channel_mask_t)parcel->readInt32();
95 mFormat.format = (audio_format_t)parcel->readInt32();
96 mRouteFlags = parcel->readInt32();
97 mDeviceType = (audio_devices_t) parcel->readInt32();
98 mDeviceAddress = parcel->readString8();
99 mCbFlags = (uint32_t)parcel->readInt32();
100 mAllowPrivilegedPlaybackCapture = parcel->readBool();
101 size_t size = (size_t)parcel->readInt32();
102 if (size > MAX_CRITERIA_PER_MIX) {
103 size = MAX_CRITERIA_PER_MIX;
104 }
105 for (size_t i = 0; i < size; i++) {
106 AudioMixMatchCriterion criterion;
107 if (criterion.readFromParcel(parcel) == NO_ERROR) {
108 mCriteria.add(criterion);
109 }
110 }
111 return NO_ERROR;
112 }
113
writeToParcel(Parcel * parcel) const114 status_t AudioMix::writeToParcel(Parcel *parcel) const
115 {
116 parcel->writeInt32(mMixType);
117 parcel->writeInt32(mFormat.sample_rate);
118 parcel->writeInt32(mFormat.channel_mask);
119 parcel->writeInt32(mFormat.format);
120 parcel->writeInt32(mRouteFlags);
121 parcel->writeInt32(mDeviceType);
122 parcel->writeString8(mDeviceAddress);
123 parcel->writeInt32(mCbFlags);
124 parcel->writeBool(mAllowPrivilegedPlaybackCapture);
125 size_t size = mCriteria.size();
126 if (size > MAX_CRITERIA_PER_MIX) {
127 size = MAX_CRITERIA_PER_MIX;
128 }
129 size_t sizePosition = parcel->dataPosition();
130 parcel->writeInt32(size);
131 size_t finalSize = size;
132 for (size_t i = 0; i < size; i++) {
133 size_t position = parcel->dataPosition();
134 if (mCriteria[i].writeToParcel(parcel) != NO_ERROR) {
135 parcel->setDataPosition(position);
136 finalSize--;
137 }
138 }
139 if (size != finalSize) {
140 size_t position = parcel->dataPosition();
141 parcel->setDataPosition(sizePosition);
142 parcel->writeInt32(finalSize);
143 parcel->setDataPosition(position);
144 }
145 return NO_ERROR;
146 }
147
setExcludeUid(uid_t uid) const148 void AudioMix::setExcludeUid(uid_t uid) const {
149 AudioMixMatchCriterion crit;
150 crit.mRule = RULE_EXCLUDE_UID;
151 crit.mValue.mUid = uid;
152 mCriteria.add(crit);
153 }
154
setMatchUid(uid_t uid) const155 void AudioMix::setMatchUid(uid_t uid) const {
156 AudioMixMatchCriterion crit;
157 crit.mRule = RULE_MATCH_UID;
158 crit.mValue.mUid = uid;
159 mCriteria.add(crit);
160 }
161
hasUidRule(bool match,uid_t uid) const162 bool AudioMix::hasUidRule(bool match, uid_t uid) const {
163 const uint32_t rule = match ? RULE_MATCH_UID : RULE_EXCLUDE_UID;
164 for (size_t i = 0; i < mCriteria.size(); i++) {
165 if (mCriteria[i].mRule == rule
166 && mCriteria[i].mValue.mUid == uid) {
167 return true;
168 }
169 }
170 return false;
171 }
172
hasMatchUidRule() const173 bool AudioMix::hasMatchUidRule() const {
174 for (size_t i = 0; i < mCriteria.size(); i++) {
175 if (mCriteria[i].mRule == RULE_MATCH_UID) {
176 return true;
177 }
178 }
179 return false;
180 }
181
isDeviceAffinityCompatible() const182 bool AudioMix::isDeviceAffinityCompatible() const {
183 return ((mMixType == MIX_TYPE_PLAYERS)
184 && (mRouteFlags == MIX_ROUTE_FLAG_RENDER));
185 }
186
187 } // namespace android
188