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 <AudioPolicyInterface.h>
21 #include "AudioInputDescriptor.h"
22 #include "IOProfile.h"
23 #include "AudioGain.h"
24 #include "AudioPolicyMix.h"
25 #include "HwModule.h"
26 #include <media/AudioPolicy.h>
27 #include <policy.h>
28
29 namespace android {
30
AudioInputDescriptor(const sp<IOProfile> & profile,AudioPolicyClientInterface * clientInterface)31 AudioInputDescriptor::AudioInputDescriptor(const sp<IOProfile>& profile,
32 AudioPolicyClientInterface *clientInterface)
33 : mIoHandle(0),
34 mDevice(AUDIO_DEVICE_NONE), mPolicyMix(NULL),
35 mProfile(profile), mPatchHandle(AUDIO_PATCH_HANDLE_NONE), mId(0),
36 mClientInterface(clientInterface)
37 {
38 if (profile != NULL) {
39 profile->pickAudioProfile(mSamplingRate, mChannelMask, mFormat);
40 if (profile->mGains.size() > 0) {
41 profile->mGains[0]->getDefaultConfig(&mGain);
42 }
43 }
44 }
45
getModuleHandle() const46 audio_module_handle_t AudioInputDescriptor::getModuleHandle() const
47 {
48 if (mProfile == 0) {
49 return AUDIO_MODULE_HANDLE_NONE;
50 }
51 return mProfile->getModuleHandle();
52 }
53
getOpenRefCount() const54 uint32_t AudioInputDescriptor::getOpenRefCount() const
55 {
56 return mSessions.getOpenCount();
57 }
58
getId() const59 audio_port_handle_t AudioInputDescriptor::getId() const
60 {
61 return mId;
62 }
63
inputSource(bool activeOnly) const64 audio_source_t AudioInputDescriptor::inputSource(bool activeOnly) const
65 {
66 return getHighestPrioritySource(activeOnly);
67 }
68
toAudioPortConfig(struct audio_port_config * dstConfig,const struct audio_port_config * srcConfig) const69 void AudioInputDescriptor::toAudioPortConfig(struct audio_port_config *dstConfig,
70 const struct audio_port_config *srcConfig) const
71 {
72 ALOG_ASSERT(mProfile != 0,
73 "toAudioPortConfig() called on input with null profile %d", mIoHandle);
74 dstConfig->config_mask = AUDIO_PORT_CONFIG_SAMPLE_RATE|AUDIO_PORT_CONFIG_CHANNEL_MASK|
75 AUDIO_PORT_CONFIG_FORMAT|AUDIO_PORT_CONFIG_GAIN;
76 if (srcConfig != NULL) {
77 dstConfig->config_mask |= srcConfig->config_mask;
78 }
79
80 AudioPortConfig::toAudioPortConfig(dstConfig, srcConfig);
81
82 dstConfig->id = mId;
83 dstConfig->role = AUDIO_PORT_ROLE_SINK;
84 dstConfig->type = AUDIO_PORT_TYPE_MIX;
85 dstConfig->ext.mix.hw_module = getModuleHandle();
86 dstConfig->ext.mix.handle = mIoHandle;
87 dstConfig->ext.mix.usecase.source = inputSource();
88 }
89
toAudioPort(struct audio_port * port) const90 void AudioInputDescriptor::toAudioPort(struct audio_port *port) const
91 {
92 ALOG_ASSERT(mProfile != 0, "toAudioPort() called on input with null profile %d", mIoHandle);
93
94 mProfile->toAudioPort(port);
95 port->id = mId;
96 toAudioPortConfig(&port->active_config);
97 port->ext.mix.hw_module = getModuleHandle();
98 port->ext.mix.handle = mIoHandle;
99 port->ext.mix.latency_class = AUDIO_LATENCY_NORMAL;
100 }
101
setPreemptedSessions(const SortedVector<audio_session_t> & sessions)102 void AudioInputDescriptor::setPreemptedSessions(const SortedVector<audio_session_t>& sessions)
103 {
104 mPreemptedSessions = sessions;
105 }
106
getPreemptedSessions() const107 SortedVector<audio_session_t> AudioInputDescriptor::getPreemptedSessions() const
108 {
109 return mPreemptedSessions;
110 }
111
hasPreemptedSession(audio_session_t session) const112 bool AudioInputDescriptor::hasPreemptedSession(audio_session_t session) const
113 {
114 return (mPreemptedSessions.indexOf(session) >= 0);
115 }
116
clearPreemptedSessions()117 void AudioInputDescriptor::clearPreemptedSessions()
118 {
119 mPreemptedSessions.clear();
120 }
121
isActive() const122 bool AudioInputDescriptor::isActive() const {
123 return mSessions.hasActiveSession();
124 }
125
isSourceActive(audio_source_t source) const126 bool AudioInputDescriptor::isSourceActive(audio_source_t source) const
127 {
128 return mSessions.isSourceActive(source);
129 }
130
getHighestPrioritySource(bool activeOnly) const131 audio_source_t AudioInputDescriptor::getHighestPrioritySource(bool activeOnly) const
132 {
133
134 return mSessions.getHighestPrioritySource(activeOnly);
135 }
136
isSoundTrigger() const137 bool AudioInputDescriptor::isSoundTrigger() const {
138 // sound trigger and non sound trigger sessions are not mixed
139 // on a given input
140 return mSessions.valueAt(0)->isSoundTrigger();
141 }
142
getAudioSession(audio_session_t session) const143 sp<AudioSession> AudioInputDescriptor::getAudioSession(
144 audio_session_t session) const {
145 return mSessions.valueFor(session);
146 }
147
getAudioSessions(bool activeOnly) const148 AudioSessionCollection AudioInputDescriptor::getAudioSessions(bool activeOnly) const
149 {
150 if (activeOnly) {
151 return mSessions.getActiveSessions();
152 } else {
153 return mSessions;
154 }
155 }
156
getAudioSessionCount(bool activeOnly) const157 size_t AudioInputDescriptor::getAudioSessionCount(bool activeOnly) const
158 {
159 if (activeOnly) {
160 return mSessions.getActiveSessionCount();
161 } else {
162 return mSessions.size();
163 }
164 }
165
addAudioSession(audio_session_t session,const sp<AudioSession> & audioSession)166 status_t AudioInputDescriptor::addAudioSession(audio_session_t session,
167 const sp<AudioSession>& audioSession) {
168 return mSessions.addSession(session, audioSession, /*AudioSessionInfoProvider*/this);
169 }
170
removeAudioSession(audio_session_t session)171 status_t AudioInputDescriptor::removeAudioSession(audio_session_t session) {
172 return mSessions.removeSession(session);
173 }
174
getPatchHandle() const175 audio_patch_handle_t AudioInputDescriptor::getPatchHandle() const
176 {
177 return mPatchHandle;
178 }
179
setPatchHandle(audio_patch_handle_t handle)180 void AudioInputDescriptor::setPatchHandle(audio_patch_handle_t handle)
181 {
182 mPatchHandle = handle;
183 mSessions.onSessionInfoUpdate();
184 }
185
getConfig() const186 audio_config_base_t AudioInputDescriptor::getConfig() const
187 {
188 const audio_config_base_t config = { .sample_rate = mSamplingRate, .channel_mask = mChannelMask,
189 .format = mFormat };
190 return config;
191 }
192
open(const audio_config_t * config,audio_devices_t device,const String8 & address,audio_source_t source,audio_input_flags_t flags,audio_io_handle_t * input)193 status_t AudioInputDescriptor::open(const audio_config_t *config,
194 audio_devices_t device,
195 const String8& address,
196 audio_source_t source,
197 audio_input_flags_t flags,
198 audio_io_handle_t *input)
199 {
200 audio_config_t lConfig;
201 if (config == nullptr) {
202 lConfig = AUDIO_CONFIG_INITIALIZER;
203 lConfig.sample_rate = mSamplingRate;
204 lConfig.channel_mask = mChannelMask;
205 lConfig.format = mFormat;
206 } else {
207 lConfig = *config;
208 }
209
210 mDevice = device;
211
212 ALOGV("opening input for device %08x address %s profile %p name %s",
213 mDevice, address.string(), mProfile.get(), mProfile->getName().string());
214
215 status_t status = mClientInterface->openInput(mProfile->getModuleHandle(),
216 input,
217 &lConfig,
218 &mDevice,
219 address,
220 source,
221 flags);
222 LOG_ALWAYS_FATAL_IF(mDevice != device,
223 "%s openInput returned device %08x when given device %08x",
224 __FUNCTION__, mDevice, device);
225
226 if (status == NO_ERROR) {
227 LOG_ALWAYS_FATAL_IF(*input == AUDIO_IO_HANDLE_NONE,
228 "%s openInput returned input handle %d for device %08x",
229 __FUNCTION__, *input, device);
230 mSamplingRate = lConfig.sample_rate;
231 mChannelMask = lConfig.channel_mask;
232 mFormat = lConfig.format;
233 mId = AudioPort::getNextUniqueId();
234 mIoHandle = *input;
235 mProfile->curOpenCount++;
236 }
237
238 return status;
239 }
240
start()241 status_t AudioInputDescriptor::start()
242 {
243 if (getAudioSessionCount(true/*activeOnly*/) == 1) {
244 if (!mProfile->canStartNewIo()) {
245 ALOGI("%s mProfile->curActiveCount %d", __func__, mProfile->curActiveCount);
246 return INVALID_OPERATION;
247 }
248 mProfile->curActiveCount++;
249 }
250 return NO_ERROR;
251 }
252
stop()253 void AudioInputDescriptor::stop()
254 {
255 if (!isActive()) {
256 LOG_ALWAYS_FATAL_IF(mProfile->curActiveCount < 1,
257 "%s invalid profile active count %u",
258 __func__, mProfile->curActiveCount);
259 mProfile->curActiveCount--;
260 }
261 }
262
close()263 void AudioInputDescriptor::close()
264 {
265 if (mIoHandle != AUDIO_IO_HANDLE_NONE) {
266 mClientInterface->closeInput(mIoHandle);
267 LOG_ALWAYS_FATAL_IF(mProfile->curOpenCount < 1, "%s profile open count %u",
268 __FUNCTION__, mProfile->curOpenCount);
269 // do not call stop() here as stop() is supposed to be called after
270 // AudioSession::changeActiveCount(-1) and we don't know how many sessions
271 // are still active at this time
272 if (isActive()) {
273 mProfile->curActiveCount--;
274 }
275 mProfile->curOpenCount--;
276 mIoHandle = AUDIO_IO_HANDLE_NONE;
277 }
278 }
279
dump(int fd)280 status_t AudioInputDescriptor::dump(int fd)
281 {
282 const size_t SIZE = 256;
283 char buffer[SIZE];
284 String8 result;
285
286 snprintf(buffer, SIZE, " ID: %d\n", getId());
287 result.append(buffer);
288 snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate);
289 result.append(buffer);
290 snprintf(buffer, SIZE, " Format: %d\n", mFormat);
291 result.append(buffer);
292 snprintf(buffer, SIZE, " Channels: %08x\n", mChannelMask);
293 result.append(buffer);
294 snprintf(buffer, SIZE, " Devices %08x\n", mDevice);
295 result.append(buffer);
296
297 write(fd, result.string(), result.size());
298
299 mSessions.dump(fd, 1);
300
301 return NO_ERROR;
302 }
303
isSourceActive(audio_source_t source) const304 bool AudioInputCollection::isSourceActive(audio_source_t source) const
305 {
306 for (size_t i = 0; i < size(); i++) {
307 const sp<AudioInputDescriptor> inputDescriptor = valueAt(i);
308 if (inputDescriptor->isSourceActive(source)) {
309 return true;
310 }
311 }
312 return false;
313 }
314
getInputFromId(audio_port_handle_t id) const315 sp<AudioInputDescriptor> AudioInputCollection::getInputFromId(audio_port_handle_t id) const
316 {
317 sp<AudioInputDescriptor> inputDesc = NULL;
318 for (size_t i = 0; i < size(); i++) {
319 inputDesc = valueAt(i);
320 if (inputDesc->getId() == id) {
321 break;
322 }
323 }
324 return inputDesc;
325 }
326
activeInputsCountOnDevices(audio_devices_t devices) const327 uint32_t AudioInputCollection::activeInputsCountOnDevices(audio_devices_t devices) const
328 {
329 uint32_t count = 0;
330 for (size_t i = 0; i < size(); i++) {
331 const sp<AudioInputDescriptor> inputDescriptor = valueAt(i);
332 if (inputDescriptor->isActive() &&
333 ((devices == AUDIO_DEVICE_IN_DEFAULT) ||
334 ((inputDescriptor->mDevice & devices & ~AUDIO_DEVICE_BIT_IN) != 0))) {
335 count++;
336 }
337 }
338 return count;
339 }
340
getActiveInputs(bool ignoreVirtualInputs)341 Vector<sp <AudioInputDescriptor> > AudioInputCollection::getActiveInputs(bool ignoreVirtualInputs)
342 {
343 Vector<sp <AudioInputDescriptor> > activeInputs;
344
345 for (size_t i = 0; i < size(); i++) {
346 const sp<AudioInputDescriptor> inputDescriptor = valueAt(i);
347 if ((inputDescriptor->isActive())
348 && (!ignoreVirtualInputs ||
349 !is_virtual_input_device(inputDescriptor->mDevice))) {
350 activeInputs.add(inputDescriptor);
351 }
352 }
353 return activeInputs;
354 }
355
getSupportedDevices(audio_io_handle_t handle) const356 audio_devices_t AudioInputCollection::getSupportedDevices(audio_io_handle_t handle) const
357 {
358 sp<AudioInputDescriptor> inputDesc = valueFor(handle);
359 audio_devices_t devices = inputDesc->mProfile->getSupportedDevicesType();
360 return devices;
361 }
362
dump(int fd) const363 status_t AudioInputCollection::dump(int fd) const
364 {
365 const size_t SIZE = 256;
366 char buffer[SIZE];
367
368 snprintf(buffer, SIZE, "\nInputs dump:\n");
369 write(fd, buffer, strlen(buffer));
370 for (size_t i = 0; i < size(); i++) {
371 snprintf(buffer, SIZE, "- Input %d dump:\n", keyAt(i));
372 write(fd, buffer, strlen(buffer));
373 valueAt(i)->dump(fd);
374 }
375
376 return NO_ERROR;
377 }
378
379 }; //namespace android
380