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