156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi/*
256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * Copyright (C) 2015 The Android Open Source Project
356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi *
456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * Licensed under the Apache License, Version 2.0 (the "License");
556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * you may not use this file except in compliance with the License.
656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * You may obtain a copy of the License at
756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi *
856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi *      http://www.apache.org/licenses/LICENSE-2.0
956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi *
1056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * Unless required by applicable law or agreed to in writing, software
1156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * distributed under the License is distributed on an "AS IS" BASIS,
1256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * See the License for the specific language governing permissions and
1456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * limitations under the License.
1556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi */
1656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
1756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi#define LOG_TAG "APM::AudioInputDescriptor"
1856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi//#define LOG_NDEBUG 0
1956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
20fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent#include <AudioPolicyInterface.h>
21ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie#include "AudioInputDescriptor.h"
22ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie#include "IOProfile.h"
2398cc191247388132b6fd8a4ecd07abd6e4c5a0edFrançois Gaffie#include "AudioGain.h"
24ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie#include "HwModule.h"
25ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie#include <media/AudioPolicy.h>
2653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie#include <policy.h>
2756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
2856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivinamespace android {
2956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
30fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric LaurentAudioInputDescriptor::AudioInputDescriptor(const sp<IOProfile>& profile,
31fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent                                           AudioPolicyClientInterface *clientInterface)
32322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent    : mIoHandle(0),
338c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi      mDevice(AUDIO_DEVICE_NONE), mPolicyMix(NULL),
34fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent      mProfile(profile), mPatchHandle(AUDIO_PATCH_HANDLE_NONE), mId(0),
35fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent      mClientInterface(clientInterface)
3656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{
3756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    if (profile != NULL) {
38112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie        profile->pickAudioProfile(mSamplingRate, mChannelMask, mFormat);
3956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi        if (profile->mGains.size() > 0) {
4056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi            profile->mGains[0]->getDefaultConfig(&mGain);
4156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi        }
4256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    }
4356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi}
4456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
4553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffieaudio_module_handle_t AudioInputDescriptor::getModuleHandle() const
4653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie{
47322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent    if (mProfile == 0) {
48a13cde98a880341f0a56d91da6364b093fb5d24eGlenn Kasten        return AUDIO_MODULE_HANDLE_NONE;
49322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent    }
5053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    return mProfile->getModuleHandle();
5153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie}
5253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie
5365bfe916ca972b95f41d7f6cc2566c2e12a3eadaJean-Michel Triviuint32_t AudioInputDescriptor::getOpenRefCount() const
5465bfe916ca972b95f41d7f6cc2566c2e12a3eadaJean-Michel Trivi{
55599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    return mSessions.getOpenCount();
5665bfe916ca972b95f41d7f6cc2566c2e12a3eadaJean-Michel Trivi}
5765bfe916ca972b95f41d7f6cc2566c2e12a3eadaJean-Michel Trivi
58322b4d25387a04c9afebe998326d005bbdf17edeEric Laurentaudio_port_handle_t AudioInputDescriptor::getId() const
59322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent{
60322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent    return mId;
61322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent}
62322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent
63bb9480975322b0d1a09f76ef14f3285fc8af4e5fEric Laurentaudio_source_t AudioInputDescriptor::inputSource(bool activeOnly) const
64599c758b258cc5da0dba9b530425381facc37d77Eric Laurent{
65bb9480975322b0d1a09f76ef14f3285fc8af4e5fEric Laurent    return getHighestPrioritySource(activeOnly);
66599c758b258cc5da0dba9b530425381facc37d77Eric Laurent}
67599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
6853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffievoid AudioInputDescriptor::toAudioPortConfig(struct audio_port_config *dstConfig,
6953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                             const struct audio_port_config *srcConfig) const
7056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{
7156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    ALOG_ASSERT(mProfile != 0,
7256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi                "toAudioPortConfig() called on input with null profile %d", mIoHandle);
7356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    dstConfig->config_mask = AUDIO_PORT_CONFIG_SAMPLE_RATE|AUDIO_PORT_CONFIG_CHANNEL_MASK|
7456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi                            AUDIO_PORT_CONFIG_FORMAT|AUDIO_PORT_CONFIG_GAIN;
7556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    if (srcConfig != NULL) {
7656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi        dstConfig->config_mask |= srcConfig->config_mask;
7756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    }
7856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
7956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    AudioPortConfig::toAudioPortConfig(dstConfig, srcConfig);
8056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
8156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    dstConfig->id = mId;
8256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    dstConfig->role = AUDIO_PORT_ROLE_SINK;
8356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    dstConfig->type = AUDIO_PORT_TYPE_MIX;
84322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent    dstConfig->ext.mix.hw_module = getModuleHandle();
8556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    dstConfig->ext.mix.handle = mIoHandle;
86599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    dstConfig->ext.mix.usecase.source = inputSource();
8756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi}
8856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
8953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffievoid AudioInputDescriptor::toAudioPort(struct audio_port *port) const
9056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{
9156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    ALOG_ASSERT(mProfile != 0, "toAudioPort() called on input with null profile %d", mIoHandle);
9256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
9356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    mProfile->toAudioPort(port);
9456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    port->id = mId;
9556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    toAudioPortConfig(&port->active_config);
96322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent    port->ext.mix.hw_module = getModuleHandle();
9756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    port->ext.mix.handle = mIoHandle;
9856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    port->ext.mix.latency_class = AUDIO_LATENCY_NORMAL;
9956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi}
10056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
10164265b2fb8f5be63b6c2ad4fcbec9acf74705bc4Eric Laurentvoid AudioInputDescriptor::setPreemptedSessions(const SortedVector<audio_session_t>& sessions)
10264265b2fb8f5be63b6c2ad4fcbec9acf74705bc4Eric Laurent{
10364265b2fb8f5be63b6c2ad4fcbec9acf74705bc4Eric Laurent    mPreemptedSessions = sessions;
10464265b2fb8f5be63b6c2ad4fcbec9acf74705bc4Eric Laurent}
10564265b2fb8f5be63b6c2ad4fcbec9acf74705bc4Eric Laurent
10664265b2fb8f5be63b6c2ad4fcbec9acf74705bc4Eric LaurentSortedVector<audio_session_t> AudioInputDescriptor::getPreemptedSessions() const
10764265b2fb8f5be63b6c2ad4fcbec9acf74705bc4Eric Laurent{
10864265b2fb8f5be63b6c2ad4fcbec9acf74705bc4Eric Laurent    return mPreemptedSessions;
10964265b2fb8f5be63b6c2ad4fcbec9acf74705bc4Eric Laurent}
11064265b2fb8f5be63b6c2ad4fcbec9acf74705bc4Eric Laurent
11164265b2fb8f5be63b6c2ad4fcbec9acf74705bc4Eric Laurentbool AudioInputDescriptor::hasPreemptedSession(audio_session_t session) const
11264265b2fb8f5be63b6c2ad4fcbec9acf74705bc4Eric Laurent{
11364265b2fb8f5be63b6c2ad4fcbec9acf74705bc4Eric Laurent    return (mPreemptedSessions.indexOf(session) >= 0);
11464265b2fb8f5be63b6c2ad4fcbec9acf74705bc4Eric Laurent}
11564265b2fb8f5be63b6c2ad4fcbec9acf74705bc4Eric Laurent
11664265b2fb8f5be63b6c2ad4fcbec9acf74705bc4Eric Laurentvoid AudioInputDescriptor::clearPreemptedSessions()
11764265b2fb8f5be63b6c2ad4fcbec9acf74705bc4Eric Laurent{
11864265b2fb8f5be63b6c2ad4fcbec9acf74705bc4Eric Laurent    mPreemptedSessions.clear();
11964265b2fb8f5be63b6c2ad4fcbec9acf74705bc4Eric Laurent}
12064265b2fb8f5be63b6c2ad4fcbec9acf74705bc4Eric Laurent
121599c758b258cc5da0dba9b530425381facc37d77Eric Laurentbool AudioInputDescriptor::isActive() const {
122599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    return mSessions.hasActiveSession();
123599c758b258cc5da0dba9b530425381facc37d77Eric Laurent}
124599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
125599c758b258cc5da0dba9b530425381facc37d77Eric Laurentbool AudioInputDescriptor::isSourceActive(audio_source_t source) const
126599c758b258cc5da0dba9b530425381facc37d77Eric Laurent{
127599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    return mSessions.isSourceActive(source);
128599c758b258cc5da0dba9b530425381facc37d77Eric Laurent}
129599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
130fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurentaudio_source_t AudioInputDescriptor::getHighestPrioritySource(bool activeOnly) const
131fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent{
132fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent
133fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    return mSessions.getHighestPrioritySource(activeOnly);
134fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent}
135fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent
136599c758b258cc5da0dba9b530425381facc37d77Eric Laurentbool AudioInputDescriptor::isSoundTrigger() const {
137599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    // sound trigger and non sound trigger sessions are not mixed
138599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    // on a given input
139599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    return mSessions.valueAt(0)->isSoundTrigger();
140599c758b258cc5da0dba9b530425381facc37d77Eric Laurent}
141599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
142599c758b258cc5da0dba9b530425381facc37d77Eric Laurentsp<AudioSession> AudioInputDescriptor::getAudioSession(
143599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                                              audio_session_t session) const {
144599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    return mSessions.valueFor(session);
145599c758b258cc5da0dba9b530425381facc37d77Eric Laurent}
146599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
147fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric LaurentAudioSessionCollection AudioInputDescriptor::getAudioSessions(bool activeOnly) const
148599c758b258cc5da0dba9b530425381facc37d77Eric Laurent{
149fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    if (activeOnly) {
150fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        return mSessions.getActiveSessions();
151fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    } else {
152fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        return mSessions;
153fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    }
154599c758b258cc5da0dba9b530425381facc37d77Eric Laurent}
155599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
15656afc7a5cc0f0bfc8021f6413b2e2267050bdc8aJean-Michel Trivisize_t AudioInputDescriptor::getAudioSessionCount(bool activeOnly) const
15756afc7a5cc0f0bfc8021f6413b2e2267050bdc8aJean-Michel Trivi{
15856afc7a5cc0f0bfc8021f6413b2e2267050bdc8aJean-Michel Trivi    if (activeOnly) {
15956afc7a5cc0f0bfc8021f6413b2e2267050bdc8aJean-Michel Trivi        return mSessions.getActiveSessionCount();
16056afc7a5cc0f0bfc8021f6413b2e2267050bdc8aJean-Michel Trivi    } else {
16156afc7a5cc0f0bfc8021f6413b2e2267050bdc8aJean-Michel Trivi        return mSessions.size();
16256afc7a5cc0f0bfc8021f6413b2e2267050bdc8aJean-Michel Trivi    }
16356afc7a5cc0f0bfc8021f6413b2e2267050bdc8aJean-Michel Trivi}
16456afc7a5cc0f0bfc8021f6413b2e2267050bdc8aJean-Michel Trivi
165599c758b258cc5da0dba9b530425381facc37d77Eric Laurentstatus_t AudioInputDescriptor::addAudioSession(audio_session_t session,
166599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                         const sp<AudioSession>& audioSession) {
1678c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi    return mSessions.addSession(session, audioSession, /*AudioSessionInfoProvider*/this);
168599c758b258cc5da0dba9b530425381facc37d77Eric Laurent}
169599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
170599c758b258cc5da0dba9b530425381facc37d77Eric Laurentstatus_t AudioInputDescriptor::removeAudioSession(audio_session_t session) {
171599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    return mSessions.removeSession(session);
172599c758b258cc5da0dba9b530425381facc37d77Eric Laurent}
173599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
174a13cde98a880341f0a56d91da6364b093fb5d24eGlenn Kastenaudio_patch_handle_t AudioInputDescriptor::getPatchHandle() const
1758c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi{
1768c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi    return mPatchHandle;
1778c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi}
1788c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi
1798c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivivoid AudioInputDescriptor::setPatchHandle(audio_patch_handle_t handle)
1808c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi{
1818c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi    mPatchHandle = handle;
1828c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi    mSessions.onSessionInfoUpdate();
1838c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi}
1848c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi
1858c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Triviaudio_config_base_t AudioInputDescriptor::getConfig() const
1868c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi{
1878c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi    const audio_config_base_t config = { .sample_rate = mSamplingRate, .channel_mask = mChannelMask,
1888c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi            .format = mFormat };
1898c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi    return config;
1908c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi}
1918c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi
192fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurentstatus_t AudioInputDescriptor::open(const audio_config_t *config,
193fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent                                       audio_devices_t device,
194fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent                                       const String8& address,
195fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent                                       audio_source_t source,
196fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent                                       audio_input_flags_t flags,
197fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent                                       audio_io_handle_t *input)
198fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent{
199fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent    audio_config_t lConfig;
200fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent    if (config == nullptr) {
201fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent        lConfig = AUDIO_CONFIG_INITIALIZER;
202fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent        lConfig.sample_rate = mSamplingRate;
203fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent        lConfig.channel_mask = mChannelMask;
204fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent        lConfig.format = mFormat;
205fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent    } else {
206fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent        lConfig = *config;
207fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent    }
208fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent
209fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent    mDevice = device;
210fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent
211fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent    ALOGV("opening input for device %08x address %s profile %p name %s",
21253b810ead5b726994fe6a28c6fa955e7b8799aaaEric Laurent          mDevice, address.string(), mProfile.get(), mProfile->getName().string());
213fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent
214fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent    status_t status = mClientInterface->openInput(mProfile->getModuleHandle(),
215fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent                                                  input,
216fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent                                                  &lConfig,
217fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent                                                  &mDevice,
21853b810ead5b726994fe6a28c6fa955e7b8799aaaEric Laurent                                                  address,
219fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent                                                  source,
220fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent                                                  flags);
221fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent    LOG_ALWAYS_FATAL_IF(mDevice != device,
222fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent                        "%s openInput returned device %08x when given device %08x",
223fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent                        __FUNCTION__, mDevice, device);
224fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent
225fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent    if (status == NO_ERROR) {
226bcbcb1bdda4f1970830fa4924e3a5f24171ae005Mikhail Naganov        LOG_ALWAYS_FATAL_IF(*input == AUDIO_IO_HANDLE_NONE,
227bcbcb1bdda4f1970830fa4924e3a5f24171ae005Mikhail Naganov                            "%s openInput returned input handle %d for device %08x",
228bcbcb1bdda4f1970830fa4924e3a5f24171ae005Mikhail Naganov                            __FUNCTION__, *input, device);
229fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent        mSamplingRate = lConfig.sample_rate;
230fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent        mChannelMask = lConfig.channel_mask;
231fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent        mFormat = lConfig.format;
232fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent        mId = AudioPort::getNextUniqueId();
233fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent        mIoHandle = *input;
2343974e3b22856ef35dd73760056ff38b7a4062176Eric Laurent        mProfile->curOpenCount++;
235fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent    }
236fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent
237fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent    return status;
238fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent}
239fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent
240733ce945741b1fc12cee92d8133c3136b4e6e0e0Eric Laurentstatus_t AudioInputDescriptor::start()
241733ce945741b1fc12cee92d8133c3136b4e6e0e0Eric Laurent{
242733ce945741b1fc12cee92d8133c3136b4e6e0e0Eric Laurent    if (getAudioSessionCount(true/*activeOnly*/) == 1) {
243733ce945741b1fc12cee92d8133c3136b4e6e0e0Eric Laurent        if (!mProfile->canStartNewIo()) {
244733ce945741b1fc12cee92d8133c3136b4e6e0e0Eric Laurent            ALOGI("%s mProfile->curActiveCount %d", __func__, mProfile->curActiveCount);
245733ce945741b1fc12cee92d8133c3136b4e6e0e0Eric Laurent            return INVALID_OPERATION;
246733ce945741b1fc12cee92d8133c3136b4e6e0e0Eric Laurent        }
247733ce945741b1fc12cee92d8133c3136b4e6e0e0Eric Laurent        mProfile->curActiveCount++;
248733ce945741b1fc12cee92d8133c3136b4e6e0e0Eric Laurent    }
249733ce945741b1fc12cee92d8133c3136b4e6e0e0Eric Laurent    return NO_ERROR;
250733ce945741b1fc12cee92d8133c3136b4e6e0e0Eric Laurent}
251733ce945741b1fc12cee92d8133c3136b4e6e0e0Eric Laurent
252733ce945741b1fc12cee92d8133c3136b4e6e0e0Eric Laurentvoid AudioInputDescriptor::stop()
253733ce945741b1fc12cee92d8133c3136b4e6e0e0Eric Laurent{
254733ce945741b1fc12cee92d8133c3136b4e6e0e0Eric Laurent    if (!isActive()) {
255733ce945741b1fc12cee92d8133c3136b4e6e0e0Eric Laurent        LOG_ALWAYS_FATAL_IF(mProfile->curActiveCount < 1,
256733ce945741b1fc12cee92d8133c3136b4e6e0e0Eric Laurent                            "%s invalid profile active count %u",
257733ce945741b1fc12cee92d8133c3136b4e6e0e0Eric Laurent                            __func__, mProfile->curActiveCount);
258733ce945741b1fc12cee92d8133c3136b4e6e0e0Eric Laurent        mProfile->curActiveCount--;
259733ce945741b1fc12cee92d8133c3136b4e6e0e0Eric Laurent    }
260733ce945741b1fc12cee92d8133c3136b4e6e0e0Eric Laurent}
261fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent
262fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurentvoid AudioInputDescriptor::close()
263fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent{
264fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent    if (mIoHandle != AUDIO_IO_HANDLE_NONE) {
265fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent        mClientInterface->closeInput(mIoHandle);
2663974e3b22856ef35dd73760056ff38b7a4062176Eric Laurent        LOG_ALWAYS_FATAL_IF(mProfile->curOpenCount < 1, "%s profile open count %u",
2673974e3b22856ef35dd73760056ff38b7a4062176Eric Laurent                            __FUNCTION__, mProfile->curOpenCount);
268733ce945741b1fc12cee92d8133c3136b4e6e0e0Eric Laurent        // do not call stop() here as stop() is supposed to be called after
269733ce945741b1fc12cee92d8133c3136b4e6e0e0Eric Laurent        // AudioSession::changeActiveCount(-1) and we don't know how many sessions
270733ce945741b1fc12cee92d8133c3136b4e6e0e0Eric Laurent        // are still active at this time
271447d53631b7560eace6016b2711a75533339cbccEric Laurent        if (isActive()) {
272447d53631b7560eace6016b2711a75533339cbccEric Laurent            mProfile->curActiveCount--;
273447d53631b7560eace6016b2711a75533339cbccEric Laurent        }
2743974e3b22856ef35dd73760056ff38b7a4062176Eric Laurent        mProfile->curOpenCount--;
2753974e3b22856ef35dd73760056ff38b7a4062176Eric Laurent        mIoHandle = AUDIO_IO_HANDLE_NONE;
276fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent    }
277fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent}
278fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent
27956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivistatus_t AudioInputDescriptor::dump(int fd)
28056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{
28156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    const size_t SIZE = 256;
28256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    char buffer[SIZE];
28356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    String8 result;
28456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
285322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent    snprintf(buffer, SIZE, " ID: %d\n", getId());
28656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    result.append(buffer);
28756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate);
28856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    result.append(buffer);
28956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    snprintf(buffer, SIZE, " Format: %d\n", mFormat);
29056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    result.append(buffer);
29156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    snprintf(buffer, SIZE, " Channels: %08x\n", mChannelMask);
29256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    result.append(buffer);
29356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    snprintf(buffer, SIZE, " Devices %08x\n", mDevice);
29456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    result.append(buffer);
29556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
29656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    write(fd, result.string(), result.size());
29756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
298599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    mSessions.dump(fd, 1);
299599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
30056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    return NO_ERROR;
30156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi}
30256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
30353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffiebool AudioInputCollection::isSourceActive(audio_source_t source) const
30453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie{
30553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    for (size_t i = 0; i < size(); i++) {
30653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie        const sp<AudioInputDescriptor>  inputDescriptor = valueAt(i);
307599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        if (inputDescriptor->isSourceActive(source)) {
30853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie            return true;
30953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie        }
31053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    }
31153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    return false;
31253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie}
31353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie
31453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffiesp<AudioInputDescriptor> AudioInputCollection::getInputFromId(audio_port_handle_t id) const
31553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie{
31653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    sp<AudioInputDescriptor> inputDesc = NULL;
31753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    for (size_t i = 0; i < size(); i++) {
31853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie        inputDesc = valueAt(i);
319322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent        if (inputDesc->getId() == id) {
32053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie            break;
32153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie        }
32253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    }
32353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    return inputDesc;
32453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie}
32553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie
326271a93e924f46ccaf3f76a8fc38685afea40d3eeEric Laurentuint32_t AudioInputCollection::activeInputsCountOnDevices(audio_devices_t devices) const
32753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie{
32853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    uint32_t count = 0;
32953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    for (size_t i = 0; i < size(); i++) {
330599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        const sp<AudioInputDescriptor>  inputDescriptor = valueAt(i);
331271a93e924f46ccaf3f76a8fc38685afea40d3eeEric Laurent        if (inputDescriptor->isActive() &&
332271a93e924f46ccaf3f76a8fc38685afea40d3eeEric Laurent                ((devices == AUDIO_DEVICE_IN_DEFAULT) ||
333271a93e924f46ccaf3f76a8fc38685afea40d3eeEric Laurent                 ((inputDescriptor->mDevice & devices & ~AUDIO_DEVICE_BIT_IN) != 0))) {
33453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie            count++;
33553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie        }
33653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    }
33753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    return count;
33853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie}
33953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie
340fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric LaurentVector<sp <AudioInputDescriptor> > AudioInputCollection::getActiveInputs(bool ignoreVirtualInputs)
34153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie{
342fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    Vector<sp <AudioInputDescriptor> > activeInputs;
343fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent
34453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    for (size_t i = 0; i < size(); i++) {
345599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        const sp<AudioInputDescriptor>  inputDescriptor = valueAt(i);
346599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        if ((inputDescriptor->isActive())
347599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                && (!ignoreVirtualInputs ||
348599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                    !is_virtual_input_device(inputDescriptor->mDevice))) {
349fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent            activeInputs.add(inputDescriptor);
35053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie        }
35153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    }
352fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    return activeInputs;
35353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie}
35453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie
35553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffieaudio_devices_t AudioInputCollection::getSupportedDevices(audio_io_handle_t handle) const
35653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie{
35753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    sp<AudioInputDescriptor> inputDesc = valueFor(handle);
358a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie    audio_devices_t devices = inputDesc->mProfile->getSupportedDevicesType();
35953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    return devices;
36053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie}
36153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie
36253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffiestatus_t AudioInputCollection::dump(int fd) const
36353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie{
36453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    const size_t SIZE = 256;
36553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    char buffer[SIZE];
36653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie
36753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    snprintf(buffer, SIZE, "\nInputs dump:\n");
36853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    write(fd, buffer, strlen(buffer));
36953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    for (size_t i = 0; i < size(); i++) {
37053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie        snprintf(buffer, SIZE, "- Input %d dump:\n", keyAt(i));
37153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie        write(fd, buffer, strlen(buffer));
37253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie        valueAt(i)->dump(fd);
37353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    }
37453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie
37553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    return NO_ERROR;
37653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie}
37753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie
37856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi}; //namespace android
379