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