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