1 /*
2 * Copyright (C) 2015 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 "APM::AudioInputDescriptor"
18 //#define LOG_NDEBUG 0
19
20 #include "AudioInputDescriptor.h"
21 #include "IOProfile.h"
22 #include "AudioGain.h"
23 #include "AudioPolicyMix.h"
24 #include "HwModule.h"
25 #include <media/AudioPolicy.h>
26 #include <policy.h>
27
28 namespace android {
29
AudioInputDescriptor(const sp<IOProfile> & profile)30 AudioInputDescriptor::AudioInputDescriptor(const sp<IOProfile>& profile)
31 : mIoHandle(0),
32 mDevice(AUDIO_DEVICE_NONE), mPolicyMix(NULL),
33 mProfile(profile), mPatchHandle(AUDIO_PATCH_HANDLE_NONE), mId(0)
34 {
35 if (profile != NULL) {
36 profile->pickAudioProfile(mSamplingRate, mChannelMask, mFormat);
37 if (profile->mGains.size() > 0) {
38 profile->mGains[0]->getDefaultConfig(&mGain);
39 }
40 }
41 }
42
setIoHandle(audio_io_handle_t ioHandle)43 void AudioInputDescriptor::setIoHandle(audio_io_handle_t ioHandle)
44 {
45 mId = AudioPort::getNextUniqueId();
46 mIoHandle = ioHandle;
47 }
48
getModuleHandle() const49 audio_module_handle_t AudioInputDescriptor::getModuleHandle() const
50 {
51 if (mProfile == 0) {
52 return AUDIO_MODULE_HANDLE_NONE;
53 }
54 return mProfile->getModuleHandle();
55 }
56
getOpenRefCount() const57 uint32_t AudioInputDescriptor::getOpenRefCount() const
58 {
59 return mSessions.getOpenCount();
60 }
61
getId() const62 audio_port_handle_t AudioInputDescriptor::getId() const
63 {
64 return mId;
65 }
66
inputSource(bool activeOnly) const67 audio_source_t AudioInputDescriptor::inputSource(bool activeOnly) const
68 {
69 return getHighestPrioritySource(activeOnly);
70 }
71
toAudioPortConfig(struct audio_port_config * dstConfig,const struct audio_port_config * srcConfig) const72 void AudioInputDescriptor::toAudioPortConfig(struct audio_port_config *dstConfig,
73 const struct audio_port_config *srcConfig) const
74 {
75 ALOG_ASSERT(mProfile != 0,
76 "toAudioPortConfig() called on input with null profile %d", mIoHandle);
77 dstConfig->config_mask = AUDIO_PORT_CONFIG_SAMPLE_RATE|AUDIO_PORT_CONFIG_CHANNEL_MASK|
78 AUDIO_PORT_CONFIG_FORMAT|AUDIO_PORT_CONFIG_GAIN;
79 if (srcConfig != NULL) {
80 dstConfig->config_mask |= srcConfig->config_mask;
81 }
82
83 AudioPortConfig::toAudioPortConfig(dstConfig, srcConfig);
84
85 dstConfig->id = mId;
86 dstConfig->role = AUDIO_PORT_ROLE_SINK;
87 dstConfig->type = AUDIO_PORT_TYPE_MIX;
88 dstConfig->ext.mix.hw_module = getModuleHandle();
89 dstConfig->ext.mix.handle = mIoHandle;
90 dstConfig->ext.mix.usecase.source = inputSource();
91 }
92
toAudioPort(struct audio_port * port) const93 void AudioInputDescriptor::toAudioPort(struct audio_port *port) const
94 {
95 ALOG_ASSERT(mProfile != 0, "toAudioPort() called on input with null profile %d", mIoHandle);
96
97 mProfile->toAudioPort(port);
98 port->id = mId;
99 toAudioPortConfig(&port->active_config);
100 port->ext.mix.hw_module = getModuleHandle();
101 port->ext.mix.handle = mIoHandle;
102 port->ext.mix.latency_class = AUDIO_LATENCY_NORMAL;
103 }
104
setPreemptedSessions(const SortedVector<audio_session_t> & sessions)105 void AudioInputDescriptor::setPreemptedSessions(const SortedVector<audio_session_t>& sessions)
106 {
107 mPreemptedSessions = sessions;
108 }
109
getPreemptedSessions() const110 SortedVector<audio_session_t> AudioInputDescriptor::getPreemptedSessions() const
111 {
112 return mPreemptedSessions;
113 }
114
hasPreemptedSession(audio_session_t session) const115 bool AudioInputDescriptor::hasPreemptedSession(audio_session_t session) const
116 {
117 return (mPreemptedSessions.indexOf(session) >= 0);
118 }
119
clearPreemptedSessions()120 void AudioInputDescriptor::clearPreemptedSessions()
121 {
122 mPreemptedSessions.clear();
123 }
124
isActive() const125 bool AudioInputDescriptor::isActive() const {
126 return mSessions.hasActiveSession();
127 }
128
isSourceActive(audio_source_t source) const129 bool AudioInputDescriptor::isSourceActive(audio_source_t source) const
130 {
131 return mSessions.isSourceActive(source);
132 }
133
getHighestPrioritySource(bool activeOnly) const134 audio_source_t AudioInputDescriptor::getHighestPrioritySource(bool activeOnly) const
135 {
136
137 return mSessions.getHighestPrioritySource(activeOnly);
138 }
139
isSoundTrigger() const140 bool AudioInputDescriptor::isSoundTrigger() const {
141 // sound trigger and non sound trigger sessions are not mixed
142 // on a given input
143 return mSessions.valueAt(0)->isSoundTrigger();
144 }
145
getAudioSession(audio_session_t session) const146 sp<AudioSession> AudioInputDescriptor::getAudioSession(
147 audio_session_t session) const {
148 return mSessions.valueFor(session);
149 }
150
getAudioSessions(bool activeOnly) const151 AudioSessionCollection AudioInputDescriptor::getAudioSessions(bool activeOnly) const
152 {
153 if (activeOnly) {
154 return mSessions.getActiveSessions();
155 } else {
156 return mSessions;
157 }
158 }
159
getAudioSessionCount(bool activeOnly) const160 size_t AudioInputDescriptor::getAudioSessionCount(bool activeOnly) const
161 {
162 if (activeOnly) {
163 return mSessions.getActiveSessionCount();
164 } else {
165 return mSessions.size();
166 }
167 }
168
addAudioSession(audio_session_t session,const sp<AudioSession> & audioSession)169 status_t AudioInputDescriptor::addAudioSession(audio_session_t session,
170 const sp<AudioSession>& audioSession) {
171 return mSessions.addSession(session, audioSession, /*AudioSessionInfoProvider*/this);
172 }
173
removeAudioSession(audio_session_t session)174 status_t AudioInputDescriptor::removeAudioSession(audio_session_t session) {
175 return mSessions.removeSession(session);
176 }
177
getPatchHandle() const178 audio_patch_handle_t AudioInputDescriptor::getPatchHandle() const
179 {
180 return mPatchHandle;
181 }
182
setPatchHandle(audio_patch_handle_t handle)183 void AudioInputDescriptor::setPatchHandle(audio_patch_handle_t handle)
184 {
185 mPatchHandle = handle;
186 mSessions.onSessionInfoUpdate();
187 }
188
getConfig() const189 audio_config_base_t AudioInputDescriptor::getConfig() const
190 {
191 const audio_config_base_t config = { .sample_rate = mSamplingRate, .channel_mask = mChannelMask,
192 .format = mFormat };
193 return config;
194 }
195
dump(int fd)196 status_t AudioInputDescriptor::dump(int fd)
197 {
198 const size_t SIZE = 256;
199 char buffer[SIZE];
200 String8 result;
201
202 snprintf(buffer, SIZE, " ID: %d\n", getId());
203 result.append(buffer);
204 snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate);
205 result.append(buffer);
206 snprintf(buffer, SIZE, " Format: %d\n", mFormat);
207 result.append(buffer);
208 snprintf(buffer, SIZE, " Channels: %08x\n", mChannelMask);
209 result.append(buffer);
210 snprintf(buffer, SIZE, " Devices %08x\n", mDevice);
211 result.append(buffer);
212
213 write(fd, result.string(), result.size());
214
215 mSessions.dump(fd, 1);
216
217 return NO_ERROR;
218 }
219
isSourceActive(audio_source_t source) const220 bool AudioInputCollection::isSourceActive(audio_source_t source) const
221 {
222 for (size_t i = 0; i < size(); i++) {
223 const sp<AudioInputDescriptor> inputDescriptor = valueAt(i);
224 if (inputDescriptor->isSourceActive(source)) {
225 return true;
226 }
227 }
228 return false;
229 }
230
getInputFromId(audio_port_handle_t id) const231 sp<AudioInputDescriptor> AudioInputCollection::getInputFromId(audio_port_handle_t id) const
232 {
233 sp<AudioInputDescriptor> inputDesc = NULL;
234 for (size_t i = 0; i < size(); i++) {
235 inputDesc = valueAt(i);
236 if (inputDesc->getId() == id) {
237 break;
238 }
239 }
240 return inputDesc;
241 }
242
activeInputsCountOnDevices(audio_devices_t devices) const243 uint32_t AudioInputCollection::activeInputsCountOnDevices(audio_devices_t devices) const
244 {
245 uint32_t count = 0;
246 for (size_t i = 0; i < size(); i++) {
247 const sp<AudioInputDescriptor> inputDescriptor = valueAt(i);
248 if (inputDescriptor->isActive() &&
249 ((devices == AUDIO_DEVICE_IN_DEFAULT) ||
250 ((inputDescriptor->mDevice & devices & ~AUDIO_DEVICE_BIT_IN) != 0))) {
251 count++;
252 }
253 }
254 return count;
255 }
256
getActiveInputs(bool ignoreVirtualInputs)257 Vector<sp <AudioInputDescriptor> > AudioInputCollection::getActiveInputs(bool ignoreVirtualInputs)
258 {
259 Vector<sp <AudioInputDescriptor> > activeInputs;
260
261 for (size_t i = 0; i < size(); i++) {
262 const sp<AudioInputDescriptor> inputDescriptor = valueAt(i);
263 if ((inputDescriptor->isActive())
264 && (!ignoreVirtualInputs ||
265 !is_virtual_input_device(inputDescriptor->mDevice))) {
266 activeInputs.add(inputDescriptor);
267 }
268 }
269 return activeInputs;
270 }
271
getSupportedDevices(audio_io_handle_t handle) const272 audio_devices_t AudioInputCollection::getSupportedDevices(audio_io_handle_t handle) const
273 {
274 sp<AudioInputDescriptor> inputDesc = valueFor(handle);
275 audio_devices_t devices = inputDesc->mProfile->getSupportedDevicesType();
276 return devices;
277 }
278
dump(int fd) const279 status_t AudioInputCollection::dump(int fd) const
280 {
281 const size_t SIZE = 256;
282 char buffer[SIZE];
283
284 snprintf(buffer, SIZE, "\nInputs dump:\n");
285 write(fd, buffer, strlen(buffer));
286 for (size_t i = 0; i < size(); i++) {
287 snprintf(buffer, SIZE, "- Input %d dump:\n", keyAt(i));
288 write(fd, buffer, strlen(buffer));
289 valueAt(i)->dump(fd);
290 }
291
292 return NO_ERROR;
293 }
294
295 }; //namespace android
296