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