AudioSession.cpp revision 599c758b258cc5da0dba9b530425381facc37d77
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::AudioSession"
18//#define LOG_NDEBUG 0
19
20#include "AudioSession.h"
21#include "AudioGain.h"
22#include "TypeConverter.h"
23#include <cutils/log.h>
24#include <utils/String8.h>
25
26namespace android {
27
28AudioSession::AudioSession(audio_session_t session,
29                           audio_source_t inputSource,
30                           audio_format_t format,
31                           uint32_t sampleRate,
32                           audio_channel_mask_t channelMask,
33                           audio_input_flags_t flags,
34                           uid_t uid,
35                           bool isSoundTrigger) :
36    mSession(session), mInputSource(inputSource),
37    mFormat(format), mSampleRate(sampleRate), mChannelMask(channelMask),
38    mFlags(flags), mUid(uid), mIsSoundTrigger(isSoundTrigger),
39    mOpenCount(1), mActiveCount(0)
40{
41}
42
43uint32_t AudioSession::changeOpenCount(int delta)
44{
45    if ((delta + (int)mOpenCount) < 0) {
46        ALOGW("%s invalid delta %d, open count %d",
47              __FUNCTION__, delta, mOpenCount);
48        mOpenCount = (uint32_t)(-delta);
49    }
50    mOpenCount += delta;
51    ALOGV("%s open count %d", __FUNCTION__, mOpenCount);
52    return mOpenCount;
53}
54
55uint32_t AudioSession::changeActiveCount(int delta)
56{
57    if ((delta + (int)mActiveCount) < 0) {
58        ALOGW("%s invalid delta %d, active count %d",
59              __FUNCTION__, delta, mActiveCount);
60        mActiveCount = (uint32_t)(-delta);
61    }
62    mActiveCount += delta;
63    ALOGV("%s active count %d", __FUNCTION__, mActiveCount);
64    return mActiveCount;
65}
66
67bool AudioSession::matches(const sp<AudioSession> &other) const
68{
69    if (other->session() == mSession &&
70        other->inputSource() == mInputSource &&
71        other->format() == mFormat &&
72        other->sampleRate() == mSampleRate &&
73        other->channelMask() == mChannelMask &&
74        other->flags() == mFlags &&
75        other->uid() == mUid) {
76        return true;
77    }
78    return false;
79}
80
81
82status_t AudioSession::dump(int fd, int spaces, int index) const
83{
84    const size_t SIZE = 256;
85    char buffer[SIZE];
86    String8 result;
87
88    snprintf(buffer, SIZE, "%*sAudio session %d:\n", spaces, "", index+1);
89    result.append(buffer);
90    snprintf(buffer, SIZE, "%*s- session: %2d\n", spaces, "", mSession);
91    result.append(buffer);
92    snprintf(buffer, SIZE, "%*s- owner uid: %2d\n", spaces, "", mUid);
93    result.append(buffer);
94    snprintf(buffer, SIZE, "%*s- input source: %d\n", spaces, "", mInputSource);
95    result.append(buffer);
96    snprintf(buffer, SIZE, "%*s- format: %08x\n", spaces, "", mFormat);
97    result.append(buffer);
98    snprintf(buffer, SIZE, "%*s- sample: %d\n", spaces, "", mSampleRate);
99    result.append(buffer);
100    snprintf(buffer, SIZE, "%*s- channel mask: %08x\n",
101             spaces, "", mChannelMask);
102    result.append(buffer);
103    snprintf(buffer, SIZE, "%*s- is soundtrigger: %s\n",
104             spaces, "", mIsSoundTrigger ? "true" : "false");
105    result.append(buffer);
106    snprintf(buffer, SIZE, "%*s- open count: %d\n", spaces, "", mOpenCount);
107    result.append(buffer);
108    snprintf(buffer, SIZE, "%*s- active count: %d\n", spaces, "", mActiveCount);
109    result.append(buffer);
110
111    write(fd, result.string(), result.size());
112    return NO_ERROR;
113}
114
115status_t AudioSessionCollection::addSession(audio_session_t session,
116                                         const sp<AudioSession>& audioSession)
117{
118    ssize_t index = indexOfKey(session);
119
120    if (index >= 0) {
121        ALOGW("addSession() session %d already in", session);
122        return ALREADY_EXISTS;
123    }
124    add(session, audioSession);
125    ALOGV("addSession() session %d  client %d source %d",
126            session, audioSession->uid(), audioSession->inputSource());
127    return NO_ERROR;
128}
129
130status_t AudioSessionCollection::removeSession(audio_session_t session)
131{
132    ssize_t index = indexOfKey(session);
133
134    if (index < 0) {
135        ALOGW("removeSession() session %d not in", session);
136        return ALREADY_EXISTS;
137    }
138    ALOGV("removeSession() session %d", session);
139    removeItemsAt(index);
140    return NO_ERROR;
141}
142
143uint32_t AudioSessionCollection::getOpenCount() const
144{
145    uint32_t openCount = 0;
146    for (size_t i = 0; i < size(); i++) {
147        openCount += valueAt(i)->openCount();
148    }
149    return openCount;
150}
151
152AudioSessionCollection AudioSessionCollection::getActiveSessions() const
153{
154    AudioSessionCollection activeSessions;
155    for (size_t i = 0; i < size(); i++) {
156        if (valueAt(i)->activeCount() != 0) {
157            activeSessions.add(valueAt(i)->session(), valueAt(i));
158        }
159    }
160    return activeSessions;
161}
162
163bool AudioSessionCollection::hasActiveSession() const
164{
165    return getActiveSessions().size() != 0;
166}
167
168bool AudioSessionCollection::isSourceActive(audio_source_t source) const
169{
170    for (size_t i = 0; i < size(); i++) {
171        const sp<AudioSession>  audioSession = valueAt(i);
172        // AUDIO_SOURCE_HOTWORD is equivalent to AUDIO_SOURCE_VOICE_RECOGNITION only if it
173        // corresponds to an active capture triggered by a hardware hotword recognition
174        if (audioSession->activeCount() > 0 &&
175                ((audioSession->inputSource() == source) ||
176                ((source == AUDIO_SOURCE_VOICE_RECOGNITION) &&
177                 (audioSession->inputSource() == AUDIO_SOURCE_HOTWORD) &&
178                 audioSession->isSoundTrigger()))) {
179            return true;
180        }
181    }
182    return false;
183}
184
185
186status_t AudioSessionCollection::dump(int fd, int spaces) const
187{
188    const size_t SIZE = 256;
189    char buffer[SIZE];
190    snprintf(buffer, SIZE, "%*sAudio Sessions:\n", spaces, "");
191    write(fd, buffer, strlen(buffer));
192    for (size_t i = 0; i < size(); i++) {
193        valueAt(i)->dump(fd, spaces + 2, i);
194    }
195    return NO_ERROR;
196}
197
198}; // namespace android
199