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