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() const66 audio_source_t AudioInputDescriptor::inputSource() const
67 {
68 // TODO: return highest priority input source
69 return mSessions.size() > 0 ? mSessions.valueAt(0)->inputSource() :
70 AUDIO_SOURCE_DEFAULT;
71 }
72
toAudioPortConfig(struct audio_port_config * dstConfig,const struct audio_port_config * srcConfig) const73 void AudioInputDescriptor::toAudioPortConfig(struct audio_port_config *dstConfig,
74 const struct audio_port_config *srcConfig) const
75 {
76 ALOG_ASSERT(mProfile != 0,
77 "toAudioPortConfig() called on input with null profile %d", mIoHandle);
78 dstConfig->config_mask = AUDIO_PORT_CONFIG_SAMPLE_RATE|AUDIO_PORT_CONFIG_CHANNEL_MASK|
79 AUDIO_PORT_CONFIG_FORMAT|AUDIO_PORT_CONFIG_GAIN;
80 if (srcConfig != NULL) {
81 dstConfig->config_mask |= srcConfig->config_mask;
82 }
83
84 AudioPortConfig::toAudioPortConfig(dstConfig, srcConfig);
85
86 dstConfig->id = mId;
87 dstConfig->role = AUDIO_PORT_ROLE_SINK;
88 dstConfig->type = AUDIO_PORT_TYPE_MIX;
89 dstConfig->ext.mix.hw_module = getModuleHandle();
90 dstConfig->ext.mix.handle = mIoHandle;
91 dstConfig->ext.mix.usecase.source = inputSource();
92 }
93
toAudioPort(struct audio_port * port) const94 void AudioInputDescriptor::toAudioPort(struct audio_port *port) const
95 {
96 ALOG_ASSERT(mProfile != 0, "toAudioPort() called on input with null profile %d", mIoHandle);
97
98 mProfile->toAudioPort(port);
99 port->id = mId;
100 toAudioPortConfig(&port->active_config);
101 port->ext.mix.hw_module = getModuleHandle();
102 port->ext.mix.handle = mIoHandle;
103 port->ext.mix.latency_class = AUDIO_LATENCY_NORMAL;
104 }
105
setPreemptedSessions(const SortedVector<audio_session_t> & sessions)106 void AudioInputDescriptor::setPreemptedSessions(const SortedVector<audio_session_t>& sessions)
107 {
108 mPreemptedSessions = sessions;
109 }
110
getPreemptedSessions() const111 SortedVector<audio_session_t> AudioInputDescriptor::getPreemptedSessions() const
112 {
113 return mPreemptedSessions;
114 }
115
hasPreemptedSession(audio_session_t session) const116 bool AudioInputDescriptor::hasPreemptedSession(audio_session_t session) const
117 {
118 return (mPreemptedSessions.indexOf(session) >= 0);
119 }
120
clearPreemptedSessions()121 void AudioInputDescriptor::clearPreemptedSessions()
122 {
123 mPreemptedSessions.clear();
124 }
125
isActive() const126 bool AudioInputDescriptor::isActive() const {
127 return mSessions.hasActiveSession();
128 }
129
isSourceActive(audio_source_t source) const130 bool AudioInputDescriptor::isSourceActive(audio_source_t source) const
131 {
132 return mSessions.isSourceActive(source);
133 }
134
isSoundTrigger() const135 bool AudioInputDescriptor::isSoundTrigger() const {
136 // sound trigger and non sound trigger sessions are not mixed
137 // on a given input
138 return mSessions.valueAt(0)->isSoundTrigger();
139 }
140
getAudioSession(audio_session_t session) const141 sp<AudioSession> AudioInputDescriptor::getAudioSession(
142 audio_session_t session) const {
143 return mSessions.valueFor(session);
144 }
145
getActiveAudioSessions() const146 AudioSessionCollection AudioInputDescriptor::getActiveAudioSessions() const
147 {
148 return mSessions.getActiveSessions();
149 }
150
addAudioSession(audio_session_t session,const sp<AudioSession> & audioSession)151 status_t AudioInputDescriptor::addAudioSession(audio_session_t session,
152 const sp<AudioSession>& audioSession) {
153 return mSessions.addSession(session, audioSession, /*AudioSessionInfoProvider*/this);
154 }
155
removeAudioSession(audio_session_t session)156 status_t AudioInputDescriptor::removeAudioSession(audio_session_t session) {
157 return mSessions.removeSession(session);
158 }
159
getPatchHandle() const160 audio_patch_handle_t AudioInputDescriptor::getPatchHandle() const
161 {
162 return mPatchHandle;
163 }
164
setPatchHandle(audio_patch_handle_t handle)165 void AudioInputDescriptor::setPatchHandle(audio_patch_handle_t handle)
166 {
167 mPatchHandle = handle;
168 mSessions.onSessionInfoUpdate();
169 }
170
getConfig() const171 audio_config_base_t AudioInputDescriptor::getConfig() const
172 {
173 const audio_config_base_t config = { .sample_rate = mSamplingRate, .channel_mask = mChannelMask,
174 .format = mFormat };
175 return config;
176 }
177
dump(int fd)178 status_t AudioInputDescriptor::dump(int fd)
179 {
180 const size_t SIZE = 256;
181 char buffer[SIZE];
182 String8 result;
183
184 snprintf(buffer, SIZE, " ID: %d\n", getId());
185 result.append(buffer);
186 snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate);
187 result.append(buffer);
188 snprintf(buffer, SIZE, " Format: %d\n", mFormat);
189 result.append(buffer);
190 snprintf(buffer, SIZE, " Channels: %08x\n", mChannelMask);
191 result.append(buffer);
192 snprintf(buffer, SIZE, " Devices %08x\n", mDevice);
193 result.append(buffer);
194
195 write(fd, result.string(), result.size());
196
197 mSessions.dump(fd, 1);
198
199 return NO_ERROR;
200 }
201
isSourceActive(audio_source_t source) const202 bool AudioInputCollection::isSourceActive(audio_source_t source) const
203 {
204 for (size_t i = 0; i < size(); i++) {
205 const sp<AudioInputDescriptor> inputDescriptor = valueAt(i);
206 if (inputDescriptor->isSourceActive(source)) {
207 return true;
208 }
209 }
210 return false;
211 }
212
getInputFromId(audio_port_handle_t id) const213 sp<AudioInputDescriptor> AudioInputCollection::getInputFromId(audio_port_handle_t id) const
214 {
215 sp<AudioInputDescriptor> inputDesc = NULL;
216 for (size_t i = 0; i < size(); i++) {
217 inputDesc = valueAt(i);
218 if (inputDesc->getId() == id) {
219 break;
220 }
221 }
222 return inputDesc;
223 }
224
activeInputsCount() const225 uint32_t AudioInputCollection::activeInputsCount() const
226 {
227 uint32_t count = 0;
228 for (size_t i = 0; i < size(); i++) {
229 const sp<AudioInputDescriptor> inputDescriptor = valueAt(i);
230 if (inputDescriptor->isActive()) {
231 count++;
232 }
233 }
234 return count;
235 }
236
getActiveInput(bool ignoreVirtualInputs)237 audio_io_handle_t AudioInputCollection::getActiveInput(bool ignoreVirtualInputs)
238 {
239 for (size_t i = 0; i < size(); i++) {
240 const sp<AudioInputDescriptor> inputDescriptor = valueAt(i);
241 if ((inputDescriptor->isActive())
242 && (!ignoreVirtualInputs ||
243 !is_virtual_input_device(inputDescriptor->mDevice))) {
244 return keyAt(i);
245 }
246 }
247 return 0;
248 }
249
getSupportedDevices(audio_io_handle_t handle) const250 audio_devices_t AudioInputCollection::getSupportedDevices(audio_io_handle_t handle) const
251 {
252 sp<AudioInputDescriptor> inputDesc = valueFor(handle);
253 audio_devices_t devices = inputDesc->mProfile->getSupportedDevicesType();
254 return devices;
255 }
256
dump(int fd) const257 status_t AudioInputCollection::dump(int fd) const
258 {
259 const size_t SIZE = 256;
260 char buffer[SIZE];
261
262 snprintf(buffer, SIZE, "\nInputs dump:\n");
263 write(fd, buffer, strlen(buffer));
264 for (size_t i = 0; i < size(); i++) {
265 snprintf(buffer, SIZE, "- Input %d dump:\n", keyAt(i));
266 write(fd, buffer, strlen(buffer));
267 valueAt(i)->dump(fd);
268 }
269
270 return NO_ERROR;
271 }
272
273 }; //namespace android
274