1599c758b258cc5da0dba9b530425381facc37d77Eric Laurent/*
2599c758b258cc5da0dba9b530425381facc37d77Eric Laurent * Copyright (C) 2015 The Android Open Source Project
3599c758b258cc5da0dba9b530425381facc37d77Eric Laurent *
4599c758b258cc5da0dba9b530425381facc37d77Eric Laurent * Licensed under the Apache License, Version 2.0 (the "License");
5599c758b258cc5da0dba9b530425381facc37d77Eric Laurent * you may not use this file except in compliance with the License.
6599c758b258cc5da0dba9b530425381facc37d77Eric Laurent * You may obtain a copy of the License at
7599c758b258cc5da0dba9b530425381facc37d77Eric Laurent *
8599c758b258cc5da0dba9b530425381facc37d77Eric Laurent *      http://www.apache.org/licenses/LICENSE-2.0
9599c758b258cc5da0dba9b530425381facc37d77Eric Laurent *
10599c758b258cc5da0dba9b530425381facc37d77Eric Laurent * Unless required by applicable law or agreed to in writing, software
11599c758b258cc5da0dba9b530425381facc37d77Eric Laurent * distributed under the License is distributed on an "AS IS" BASIS,
12599c758b258cc5da0dba9b530425381facc37d77Eric Laurent * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13599c758b258cc5da0dba9b530425381facc37d77Eric Laurent * See the License for the specific language governing permissions and
14599c758b258cc5da0dba9b530425381facc37d77Eric Laurent * limitations under the License.
15599c758b258cc5da0dba9b530425381facc37d77Eric Laurent */
16599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
17599c758b258cc5da0dba9b530425381facc37d77Eric Laurent#define LOG_TAG "APM::AudioSession"
18599c758b258cc5da0dba9b530425381facc37d77Eric Laurent//#define LOG_NDEBUG 0
19599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
202f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi#include <AudioPolicyInterface.h>
21fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent#include "policy.h"
22599c758b258cc5da0dba9b530425381facc37d77Eric Laurent#include "AudioSession.h"
23599c758b258cc5da0dba9b530425381facc37d77Eric Laurent#include "AudioGain.h"
24599c758b258cc5da0dba9b530425381facc37d77Eric Laurent#include "TypeConverter.h"
2560d02077d86d2d1092443519290101f503aa6f7aMark Salyzyn
26e74bbf18a6595a914d3c771be08a72077465c51fMark Salyzyn#include <log/log.h>
27599c758b258cc5da0dba9b530425381facc37d77Eric Laurent#include <utils/String8.h>
28599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
29599c758b258cc5da0dba9b530425381facc37d77Eric Laurentnamespace android {
30599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
31599c758b258cc5da0dba9b530425381facc37d77Eric LaurentAudioSession::AudioSession(audio_session_t session,
32599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                           audio_source_t inputSource,
33599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                           audio_format_t format,
34599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                           uint32_t sampleRate,
35599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                           audio_channel_mask_t channelMask,
36599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                           audio_input_flags_t flags,
37599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                           uid_t uid,
382f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi                           bool isSoundTrigger,
392f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi                           AudioMix* policyMix,
402f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi                           AudioPolicyClientInterface *clientInterface) :
41ac4e42982d4537732b30e71c9a00ba0077944984Jean-Michel Trivi    mRecordClientInfo({ .uid = uid, .session = session, .source = inputSource}),
427281aa9810b33eff47b00104db26c97c77931611Jean-Michel Trivi    mConfig({ .format = format, .sample_rate = sampleRate, .channel_mask = channelMask}),
43ac4e42982d4537732b30e71c9a00ba0077944984Jean-Michel Trivi    mFlags(flags), mIsSoundTrigger(isSoundTrigger),
448c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi    mOpenCount(1), mActiveCount(0), mPolicyMix(policyMix), mClientInterface(clientInterface),
458c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi    mInfoProvider(NULL)
46599c758b258cc5da0dba9b530425381facc37d77Eric Laurent{
47599c758b258cc5da0dba9b530425381facc37d77Eric Laurent}
48599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
49599c758b258cc5da0dba9b530425381facc37d77Eric Laurentuint32_t AudioSession::changeOpenCount(int delta)
50599c758b258cc5da0dba9b530425381facc37d77Eric Laurent{
51599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    if ((delta + (int)mOpenCount) < 0) {
52599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        ALOGW("%s invalid delta %d, open count %d",
53599c758b258cc5da0dba9b530425381facc37d77Eric Laurent              __FUNCTION__, delta, mOpenCount);
54599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        mOpenCount = (uint32_t)(-delta);
55599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    }
56599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    mOpenCount += delta;
57599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    ALOGV("%s open count %d", __FUNCTION__, mOpenCount);
58599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    return mOpenCount;
59599c758b258cc5da0dba9b530425381facc37d77Eric Laurent}
60599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
61599c758b258cc5da0dba9b530425381facc37d77Eric Laurentuint32_t AudioSession::changeActiveCount(int delta)
62599c758b258cc5da0dba9b530425381facc37d77Eric Laurent{
632f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi    const uint32_t oldActiveCount = mActiveCount;
64599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    if ((delta + (int)mActiveCount) < 0) {
65599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        ALOGW("%s invalid delta %d, active count %d",
66599c758b258cc5da0dba9b530425381facc37d77Eric Laurent              __FUNCTION__, delta, mActiveCount);
67599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        mActiveCount = (uint32_t)(-delta);
68599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    }
69599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    mActiveCount += delta;
70599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    ALOGV("%s active count %d", __FUNCTION__, mActiveCount);
718c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi    int event = RECORD_CONFIG_EVENT_NONE;
722f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi
732f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi    if ((oldActiveCount == 0) && (mActiveCount > 0)) {
748c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi        event = RECORD_CONFIG_EVENT_START;
752f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi    } else if ((oldActiveCount > 0) && (mActiveCount == 0)) {
768c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi        event = RECORD_CONFIG_EVENT_STOP;
778c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi    }
788c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi
798c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi    if (event != RECORD_CONFIG_EVENT_NONE) {
808c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi        // Dynamic policy callback:
812f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi        // if input maps to a dynamic policy with an activity listener, notify of state change
822f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi        if ((mPolicyMix != NULL) && ((mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0))
832f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi        {
847638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            mClientInterface->onDynamicPolicyMixStateUpdate(mPolicyMix->mDeviceAddress,
858c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi                    (event == RECORD_CONFIG_EVENT_START) ? MIX_STATE_MIXING : MIX_STATE_IDLE);
862f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi        }
878c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi
888c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi        // Recording configuration callback:
898c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi        const AudioSessionInfoProvider* provider = mInfoProvider;
908c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi        const audio_config_base_t deviceConfig = (provider != NULL) ? provider->getConfig() :
918c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi                AUDIO_CONFIG_BASE_INITIALIZER;
928c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi        const audio_patch_handle_t patchHandle = (provider != NULL) ? provider->getPatchHandle() :
938c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi                AUDIO_PATCH_HANDLE_NONE;
9438f86713cbd22caae9fdd4ac2f0bb76ff91df34dJean-Michel Trivi        if (patchHandle != AUDIO_PATCH_HANDLE_NONE) {
95ac4e42982d4537732b30e71c9a00ba0077944984Jean-Michel Trivi            mClientInterface->onRecordingConfigurationUpdate(event, &mRecordClientInfo,
9638f86713cbd22caae9fdd4ac2f0bb76ff91df34dJean-Michel Trivi                    &mConfig, &deviceConfig, patchHandle);
9738f86713cbd22caae9fdd4ac2f0bb76ff91df34dJean-Michel Trivi        }
982f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi    }
992f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi
100599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    return mActiveCount;
101599c758b258cc5da0dba9b530425381facc37d77Eric Laurent}
102599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
103599c758b258cc5da0dba9b530425381facc37d77Eric Laurentbool AudioSession::matches(const sp<AudioSession> &other) const
104599c758b258cc5da0dba9b530425381facc37d77Eric Laurent{
105ac4e42982d4537732b30e71c9a00ba0077944984Jean-Michel Trivi    if (other->session() == mRecordClientInfo.session &&
106ac4e42982d4537732b30e71c9a00ba0077944984Jean-Michel Trivi        other->inputSource() == mRecordClientInfo.source &&
1077281aa9810b33eff47b00104db26c97c77931611Jean-Michel Trivi        other->format() == mConfig.format &&
1087281aa9810b33eff47b00104db26c97c77931611Jean-Michel Trivi        other->sampleRate() == mConfig.sample_rate &&
1097281aa9810b33eff47b00104db26c97c77931611Jean-Michel Trivi        other->channelMask() == mConfig.channel_mask &&
110599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        other->flags() == mFlags &&
111ac4e42982d4537732b30e71c9a00ba0077944984Jean-Michel Trivi        other->uid() == mRecordClientInfo.uid) {
112599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        return true;
113599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    }
114599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    return false;
115599c758b258cc5da0dba9b530425381facc37d77Eric Laurent}
116599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
1178c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivivoid AudioSession::setInfoProvider(AudioSessionInfoProvider *provider)
1188c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi{
1198c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi    mInfoProvider = provider;
1208c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi}
1218c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi
1228c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivivoid AudioSession::onSessionInfoUpdate() const
1238c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi{
1248c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi    if (mActiveCount > 0) {
1258c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi        // resend the callback after requerying the informations from the info provider
1268c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi        const AudioSessionInfoProvider* provider = mInfoProvider;
1278c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi        const audio_config_base_t deviceConfig = (provider != NULL) ? provider->getConfig() :
1288c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi                AUDIO_CONFIG_BASE_INITIALIZER;
1298c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi        const audio_patch_handle_t patchHandle = (provider != NULL) ? provider->getPatchHandle() :
1308c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi                AUDIO_PATCH_HANDLE_NONE;
13138f86713cbd22caae9fdd4ac2f0bb76ff91df34dJean-Michel Trivi        if (patchHandle != AUDIO_PATCH_HANDLE_NONE) {
13238f86713cbd22caae9fdd4ac2f0bb76ff91df34dJean-Michel Trivi            mClientInterface->onRecordingConfigurationUpdate(RECORD_CONFIG_EVENT_START,
133ac4e42982d4537732b30e71c9a00ba0077944984Jean-Michel Trivi                    &mRecordClientInfo, &mConfig, &deviceConfig, patchHandle);
13438f86713cbd22caae9fdd4ac2f0bb76ff91df34dJean-Michel Trivi        }
1358c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi    }
1367281aa9810b33eff47b00104db26c97c77931611Jean-Michel Trivi}
137599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
138599c758b258cc5da0dba9b530425381facc37d77Eric Laurentstatus_t AudioSession::dump(int fd, int spaces, int index) const
139599c758b258cc5da0dba9b530425381facc37d77Eric Laurent{
140599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    const size_t SIZE = 256;
141599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    char buffer[SIZE];
142599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    String8 result;
143599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
144599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    snprintf(buffer, SIZE, "%*sAudio session %d:\n", spaces, "", index+1);
145599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    result.append(buffer);
146ac4e42982d4537732b30e71c9a00ba0077944984Jean-Michel Trivi    snprintf(buffer, SIZE, "%*s- session: %2d\n", spaces, "", mRecordClientInfo.session);
147599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    result.append(buffer);
148ac4e42982d4537732b30e71c9a00ba0077944984Jean-Michel Trivi    snprintf(buffer, SIZE, "%*s- owner uid: %2d\n", spaces, "", mRecordClientInfo.uid);
149599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    result.append(buffer);
150ac4e42982d4537732b30e71c9a00ba0077944984Jean-Michel Trivi    snprintf(buffer, SIZE, "%*s- input source: %d\n", spaces, "", mRecordClientInfo.source);
151599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    result.append(buffer);
1527281aa9810b33eff47b00104db26c97c77931611Jean-Michel Trivi    snprintf(buffer, SIZE, "%*s- format: %08x\n", spaces, "", mConfig.format);
153599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    result.append(buffer);
1547281aa9810b33eff47b00104db26c97c77931611Jean-Michel Trivi    snprintf(buffer, SIZE, "%*s- sample: %d\n", spaces, "", mConfig.sample_rate);
155599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    result.append(buffer);
156599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    snprintf(buffer, SIZE, "%*s- channel mask: %08x\n",
1577281aa9810b33eff47b00104db26c97c77931611Jean-Michel Trivi             spaces, "", mConfig.channel_mask);
158599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    result.append(buffer);
159599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    snprintf(buffer, SIZE, "%*s- is soundtrigger: %s\n",
160599c758b258cc5da0dba9b530425381facc37d77Eric Laurent             spaces, "", mIsSoundTrigger ? "true" : "false");
161599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    result.append(buffer);
162599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    snprintf(buffer, SIZE, "%*s- open count: %d\n", spaces, "", mOpenCount);
163599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    result.append(buffer);
164599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    snprintf(buffer, SIZE, "%*s- active count: %d\n", spaces, "", mActiveCount);
165599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    result.append(buffer);
166599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
167599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    write(fd, result.string(), result.size());
168599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    return NO_ERROR;
169599c758b258cc5da0dba9b530425381facc37d77Eric Laurent}
170599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
171599c758b258cc5da0dba9b530425381facc37d77Eric Laurentstatus_t AudioSessionCollection::addSession(audio_session_t session,
1728c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi                                         const sp<AudioSession>& audioSession,
1738c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi                                         AudioSessionInfoProvider *provider)
174599c758b258cc5da0dba9b530425381facc37d77Eric Laurent{
175599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    ssize_t index = indexOfKey(session);
176599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
177599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    if (index >= 0) {
178599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        ALOGW("addSession() session %d already in", session);
179599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        return ALREADY_EXISTS;
180599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    }
1818c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi    audioSession->setInfoProvider(provider);
182599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    add(session, audioSession);
183599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    ALOGV("addSession() session %d  client %d source %d",
184599c758b258cc5da0dba9b530425381facc37d77Eric Laurent            session, audioSession->uid(), audioSession->inputSource());
185599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    return NO_ERROR;
186599c758b258cc5da0dba9b530425381facc37d77Eric Laurent}
187599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
188599c758b258cc5da0dba9b530425381facc37d77Eric Laurentstatus_t AudioSessionCollection::removeSession(audio_session_t session)
189599c758b258cc5da0dba9b530425381facc37d77Eric Laurent{
190599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    ssize_t index = indexOfKey(session);
191599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
192599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    if (index < 0) {
193599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        ALOGW("removeSession() session %d not in", session);
194599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        return ALREADY_EXISTS;
195599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    }
196599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    ALOGV("removeSession() session %d", session);
1978c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi    valueAt(index)->setInfoProvider(NULL);
198599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    removeItemsAt(index);
199599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    return NO_ERROR;
200599c758b258cc5da0dba9b530425381facc37d77Eric Laurent}
201599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
202599c758b258cc5da0dba9b530425381facc37d77Eric Laurentuint32_t AudioSessionCollection::getOpenCount() const
203599c758b258cc5da0dba9b530425381facc37d77Eric Laurent{
204599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    uint32_t openCount = 0;
205599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    for (size_t i = 0; i < size(); i++) {
206599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        openCount += valueAt(i)->openCount();
207599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    }
208599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    return openCount;
209599c758b258cc5da0dba9b530425381facc37d77Eric Laurent}
210599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
211599c758b258cc5da0dba9b530425381facc37d77Eric LaurentAudioSessionCollection AudioSessionCollection::getActiveSessions() const
212599c758b258cc5da0dba9b530425381facc37d77Eric Laurent{
213599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    AudioSessionCollection activeSessions;
214599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    for (size_t i = 0; i < size(); i++) {
215599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        if (valueAt(i)->activeCount() != 0) {
216599c758b258cc5da0dba9b530425381facc37d77Eric Laurent            activeSessions.add(valueAt(i)->session(), valueAt(i));
217599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        }
218599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    }
219599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    return activeSessions;
220599c758b258cc5da0dba9b530425381facc37d77Eric Laurent}
221599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
22256afc7a5cc0f0bfc8021f6413b2e2267050bdc8aJean-Michel Trivisize_t AudioSessionCollection::getActiveSessionCount() const
22356afc7a5cc0f0bfc8021f6413b2e2267050bdc8aJean-Michel Trivi{
22456afc7a5cc0f0bfc8021f6413b2e2267050bdc8aJean-Michel Trivi    size_t activeCount = 0;
22556afc7a5cc0f0bfc8021f6413b2e2267050bdc8aJean-Michel Trivi    for (size_t i = 0; i < size(); i++) {
22656afc7a5cc0f0bfc8021f6413b2e2267050bdc8aJean-Michel Trivi        if (valueAt(i)->activeCount() != 0) {
22756afc7a5cc0f0bfc8021f6413b2e2267050bdc8aJean-Michel Trivi            activeCount++;
22856afc7a5cc0f0bfc8021f6413b2e2267050bdc8aJean-Michel Trivi        }
22956afc7a5cc0f0bfc8021f6413b2e2267050bdc8aJean-Michel Trivi    }
23056afc7a5cc0f0bfc8021f6413b2e2267050bdc8aJean-Michel Trivi    return activeCount;
23156afc7a5cc0f0bfc8021f6413b2e2267050bdc8aJean-Michel Trivi}
23256afc7a5cc0f0bfc8021f6413b2e2267050bdc8aJean-Michel Trivi
233599c758b258cc5da0dba9b530425381facc37d77Eric Laurentbool AudioSessionCollection::hasActiveSession() const
234599c758b258cc5da0dba9b530425381facc37d77Eric Laurent{
23556afc7a5cc0f0bfc8021f6413b2e2267050bdc8aJean-Michel Trivi    return getActiveSessionCount() != 0;
236599c758b258cc5da0dba9b530425381facc37d77Eric Laurent}
237599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
238599c758b258cc5da0dba9b530425381facc37d77Eric Laurentbool AudioSessionCollection::isSourceActive(audio_source_t source) const
239599c758b258cc5da0dba9b530425381facc37d77Eric Laurent{
240599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    for (size_t i = 0; i < size(); i++) {
241599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        const sp<AudioSession>  audioSession = valueAt(i);
242599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        // AUDIO_SOURCE_HOTWORD is equivalent to AUDIO_SOURCE_VOICE_RECOGNITION only if it
243599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        // corresponds to an active capture triggered by a hardware hotword recognition
244599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        if (audioSession->activeCount() > 0 &&
245599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                ((audioSession->inputSource() == source) ||
246599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                ((source == AUDIO_SOURCE_VOICE_RECOGNITION) &&
247599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                 (audioSession->inputSource() == AUDIO_SOURCE_HOTWORD) &&
248599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                 audioSession->isSoundTrigger()))) {
249599c758b258cc5da0dba9b530425381facc37d77Eric Laurent            return true;
250599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        }
251599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    }
252599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    return false;
253599c758b258cc5da0dba9b530425381facc37d77Eric Laurent}
254599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
255fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurentaudio_source_t AudioSessionCollection::getHighestPrioritySource(bool activeOnly) const
256fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent{
257fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    audio_source_t source = AUDIO_SOURCE_DEFAULT;
258fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    int32_t priority = -1;
259fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent
260fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    for (size_t i = 0; i < size(); i++) {
261fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        const sp<AudioSession>  audioSession = valueAt(i);
262fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        if (activeOnly && audioSession->activeCount() == 0) {
263fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent            continue;
264fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        }
265fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        int32_t curPriority = source_priority(audioSession->inputSource());
266fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        if (curPriority > priority) {
267fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent            priority = curPriority;
268fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent            source = audioSession->inputSource();
269fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        }
270fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    }
271fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    return source;
272fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent}
273599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
2748c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivivoid AudioSessionCollection::onSessionInfoUpdate() const
2758c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi{
2768c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi    for (size_t i = 0; i < size(); i++) {
2778c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi        valueAt(i)->onSessionInfoUpdate();
2788c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi    }
2798c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi}
2808c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi
281599c758b258cc5da0dba9b530425381facc37d77Eric Laurentstatus_t AudioSessionCollection::dump(int fd, int spaces) const
282599c758b258cc5da0dba9b530425381facc37d77Eric Laurent{
283599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    const size_t SIZE = 256;
284599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    char buffer[SIZE];
285599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    snprintf(buffer, SIZE, "%*sAudio Sessions:\n", spaces, "");
286599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    write(fd, buffer, strlen(buffer));
287599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    for (size_t i = 0; i < size(); i++) {
288599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        valueAt(i)->dump(fd, spaces + 2, i);
289599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    }
290599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    return NO_ERROR;
291599c758b258cc5da0dba9b530425381facc37d77Eric Laurent}
292599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
293599c758b258cc5da0dba9b530425381facc37d77Eric Laurent}; // namespace android
294