• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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