AudioSession.cpp revision 7281aa9810b33eff47b00104db26c97c77931611
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>
21599c758b258cc5da0dba9b530425381facc37d77Eric Laurent#include "AudioSession.h"
22599c758b258cc5da0dba9b530425381facc37d77Eric Laurent#include "AudioGain.h"
23599c758b258cc5da0dba9b530425381facc37d77Eric Laurent#include "TypeConverter.h"
24599c758b258cc5da0dba9b530425381facc37d77Eric Laurent#include <cutils/log.h>
25599c758b258cc5da0dba9b530425381facc37d77Eric Laurent#include <utils/String8.h>
26599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
27599c758b258cc5da0dba9b530425381facc37d77Eric Laurentnamespace android {
28599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
29599c758b258cc5da0dba9b530425381facc37d77Eric LaurentAudioSession::AudioSession(audio_session_t session,
30599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                           audio_source_t inputSource,
31599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                           audio_format_t format,
32599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                           uint32_t sampleRate,
33599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                           audio_channel_mask_t channelMask,
34599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                           audio_input_flags_t flags,
35599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                           uid_t uid,
362f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi                           bool isSoundTrigger,
372f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi                           AudioMix* policyMix,
382f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi                           AudioPolicyClientInterface *clientInterface) :
39599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    mSession(session), mInputSource(inputSource),
407281aa9810b33eff47b00104db26c97c77931611Jean-Michel Trivi    mConfig({ .format = format, .sample_rate = sampleRate, .channel_mask = channelMask}),
417281aa9810b33eff47b00104db26c97c77931611Jean-Michel Trivi    mDeviceConfig(AUDIO_CONFIG_BASE_INITIALIZER),
42599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    mFlags(flags), mUid(uid), mIsSoundTrigger(isSoundTrigger),
432f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi    mOpenCount(1), mActiveCount(0), mPolicyMix(policyMix), mClientInterface(clientInterface)
44599c758b258cc5da0dba9b530425381facc37d77Eric Laurent{
45599c758b258cc5da0dba9b530425381facc37d77Eric Laurent}
46599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
47599c758b258cc5da0dba9b530425381facc37d77Eric Laurentuint32_t AudioSession::changeOpenCount(int delta)
48599c758b258cc5da0dba9b530425381facc37d77Eric Laurent{
49599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    if ((delta + (int)mOpenCount) < 0) {
50599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        ALOGW("%s invalid delta %d, open count %d",
51599c758b258cc5da0dba9b530425381facc37d77Eric Laurent              __FUNCTION__, delta, mOpenCount);
52599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        mOpenCount = (uint32_t)(-delta);
53599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    }
54599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    mOpenCount += delta;
55599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    ALOGV("%s open count %d", __FUNCTION__, mOpenCount);
56599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    return mOpenCount;
57599c758b258cc5da0dba9b530425381facc37d77Eric Laurent}
58599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
59599c758b258cc5da0dba9b530425381facc37d77Eric Laurentuint32_t AudioSession::changeActiveCount(int delta)
60599c758b258cc5da0dba9b530425381facc37d77Eric Laurent{
612f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi    const uint32_t oldActiveCount = mActiveCount;
62599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    if ((delta + (int)mActiveCount) < 0) {
63599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        ALOGW("%s invalid delta %d, active count %d",
64599c758b258cc5da0dba9b530425381facc37d77Eric Laurent              __FUNCTION__, delta, mActiveCount);
65599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        mActiveCount = (uint32_t)(-delta);
66599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    }
67599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    mActiveCount += delta;
68599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    ALOGV("%s active count %d", __FUNCTION__, mActiveCount);
692f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi
702f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi    if ((oldActiveCount == 0) && (mActiveCount > 0)) {
712f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi        // if input maps to a dynamic policy with an activity listener, notify of state change
722f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi        if ((mPolicyMix != NULL) && ((mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0))
732f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi        {
742f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi            mClientInterface->onDynamicPolicyMixStateUpdate(mPolicyMix->mRegistrationId,
752f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi                    MIX_STATE_MIXING);
762f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi        }
772f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi        mClientInterface->onRecordingConfigurationUpdate(RECORD_CONFIG_EVENT_START,
787281aa9810b33eff47b00104db26c97c77931611Jean-Michel Trivi                mSession, mInputSource, &mConfig, &mDeviceConfig);
792f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi    } else if ((oldActiveCount > 0) && (mActiveCount == 0)) {
802f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi        // if input maps to a dynamic policy with an activity listener, notify of state change
812f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi        if ((mPolicyMix != NULL) && ((mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0))
822f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi        {
832f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi            mClientInterface->onDynamicPolicyMixStateUpdate(mPolicyMix->mRegistrationId,
842f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi                    MIX_STATE_IDLE);
852f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi        }
862f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi        mClientInterface->onRecordingConfigurationUpdate(RECORD_CONFIG_EVENT_STOP,
877281aa9810b33eff47b00104db26c97c77931611Jean-Michel Trivi                mSession, mInputSource, &mConfig, &mDeviceConfig);
882f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi    }
892f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi
90599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    return mActiveCount;
91599c758b258cc5da0dba9b530425381facc37d77Eric Laurent}
92599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
93599c758b258cc5da0dba9b530425381facc37d77Eric Laurentbool AudioSession::matches(const sp<AudioSession> &other) const
94599c758b258cc5da0dba9b530425381facc37d77Eric Laurent{
95599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    if (other->session() == mSession &&
96599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        other->inputSource() == mInputSource &&
977281aa9810b33eff47b00104db26c97c77931611Jean-Michel Trivi        other->format() == mConfig.format &&
987281aa9810b33eff47b00104db26c97c77931611Jean-Michel Trivi        other->sampleRate() == mConfig.sample_rate &&
997281aa9810b33eff47b00104db26c97c77931611Jean-Michel Trivi        other->channelMask() == mConfig.channel_mask &&
100599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        other->flags() == mFlags &&
101599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        other->uid() == mUid) {
102599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        return true;
103599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    }
104599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    return false;
105599c758b258cc5da0dba9b530425381facc37d77Eric Laurent}
106599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
1077281aa9810b33eff47b00104db26c97c77931611Jean-Michel Trivivoid AudioSession::setDeviceConfig(audio_format_t format, uint32_t sampleRate,
1087281aa9810b33eff47b00104db26c97c77931611Jean-Michel Trivi            audio_channel_mask_t channelMask) {
1097281aa9810b33eff47b00104db26c97c77931611Jean-Michel Trivi    mDeviceConfig.format = format;
1107281aa9810b33eff47b00104db26c97c77931611Jean-Michel Trivi    mDeviceConfig.sample_rate = sampleRate;
1117281aa9810b33eff47b00104db26c97c77931611Jean-Michel Trivi    mDeviceConfig.channel_mask = channelMask;
1127281aa9810b33eff47b00104db26c97c77931611Jean-Michel Trivi}
113599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
114599c758b258cc5da0dba9b530425381facc37d77Eric Laurentstatus_t AudioSession::dump(int fd, int spaces, int index) const
115599c758b258cc5da0dba9b530425381facc37d77Eric Laurent{
116599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    const size_t SIZE = 256;
117599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    char buffer[SIZE];
118599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    String8 result;
119599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
120599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    snprintf(buffer, SIZE, "%*sAudio session %d:\n", spaces, "", index+1);
121599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    result.append(buffer);
122599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    snprintf(buffer, SIZE, "%*s- session: %2d\n", spaces, "", mSession);
123599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    result.append(buffer);
124599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    snprintf(buffer, SIZE, "%*s- owner uid: %2d\n", spaces, "", mUid);
125599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    result.append(buffer);
126599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    snprintf(buffer, SIZE, "%*s- input source: %d\n", spaces, "", mInputSource);
127599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    result.append(buffer);
1287281aa9810b33eff47b00104db26c97c77931611Jean-Michel Trivi    snprintf(buffer, SIZE, "%*s- format: %08x\n", spaces, "", mConfig.format);
129599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    result.append(buffer);
1307281aa9810b33eff47b00104db26c97c77931611Jean-Michel Trivi    snprintf(buffer, SIZE, "%*s- sample: %d\n", spaces, "", mConfig.sample_rate);
131599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    result.append(buffer);
132599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    snprintf(buffer, SIZE, "%*s- channel mask: %08x\n",
1337281aa9810b33eff47b00104db26c97c77931611Jean-Michel Trivi             spaces, "", mConfig.channel_mask);
134599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    result.append(buffer);
135599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    snprintf(buffer, SIZE, "%*s- is soundtrigger: %s\n",
136599c758b258cc5da0dba9b530425381facc37d77Eric Laurent             spaces, "", mIsSoundTrigger ? "true" : "false");
137599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    result.append(buffer);
138599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    snprintf(buffer, SIZE, "%*s- open count: %d\n", spaces, "", mOpenCount);
139599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    result.append(buffer);
140599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    snprintf(buffer, SIZE, "%*s- active count: %d\n", spaces, "", mActiveCount);
141599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    result.append(buffer);
142599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
143599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    write(fd, result.string(), result.size());
144599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    return NO_ERROR;
145599c758b258cc5da0dba9b530425381facc37d77Eric Laurent}
146599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
147599c758b258cc5da0dba9b530425381facc37d77Eric Laurentstatus_t AudioSessionCollection::addSession(audio_session_t session,
148599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                                         const sp<AudioSession>& audioSession)
149599c758b258cc5da0dba9b530425381facc37d77Eric Laurent{
150599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    ssize_t index = indexOfKey(session);
151599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
152599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    if (index >= 0) {
153599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        ALOGW("addSession() session %d already in", session);
154599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        return ALREADY_EXISTS;
155599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    }
156599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    add(session, audioSession);
157599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    ALOGV("addSession() session %d  client %d source %d",
158599c758b258cc5da0dba9b530425381facc37d77Eric Laurent            session, audioSession->uid(), audioSession->inputSource());
159599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    return NO_ERROR;
160599c758b258cc5da0dba9b530425381facc37d77Eric Laurent}
161599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
162599c758b258cc5da0dba9b530425381facc37d77Eric Laurentstatus_t AudioSessionCollection::removeSession(audio_session_t session)
163599c758b258cc5da0dba9b530425381facc37d77Eric Laurent{
164599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    ssize_t index = indexOfKey(session);
165599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
166599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    if (index < 0) {
167599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        ALOGW("removeSession() session %d not in", session);
168599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        return ALREADY_EXISTS;
169599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    }
170599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    ALOGV("removeSession() session %d", session);
171599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    removeItemsAt(index);
172599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    return NO_ERROR;
173599c758b258cc5da0dba9b530425381facc37d77Eric Laurent}
174599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
175599c758b258cc5da0dba9b530425381facc37d77Eric Laurentuint32_t AudioSessionCollection::getOpenCount() const
176599c758b258cc5da0dba9b530425381facc37d77Eric Laurent{
177599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    uint32_t openCount = 0;
178599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    for (size_t i = 0; i < size(); i++) {
179599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        openCount += valueAt(i)->openCount();
180599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    }
181599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    return openCount;
182599c758b258cc5da0dba9b530425381facc37d77Eric Laurent}
183599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
184599c758b258cc5da0dba9b530425381facc37d77Eric LaurentAudioSessionCollection AudioSessionCollection::getActiveSessions() const
185599c758b258cc5da0dba9b530425381facc37d77Eric Laurent{
186599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    AudioSessionCollection activeSessions;
187599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    for (size_t i = 0; i < size(); i++) {
188599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        if (valueAt(i)->activeCount() != 0) {
189599c758b258cc5da0dba9b530425381facc37d77Eric Laurent            activeSessions.add(valueAt(i)->session(), valueAt(i));
190599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        }
191599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    }
192599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    return activeSessions;
193599c758b258cc5da0dba9b530425381facc37d77Eric Laurent}
194599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
195599c758b258cc5da0dba9b530425381facc37d77Eric Laurentbool AudioSessionCollection::hasActiveSession() const
196599c758b258cc5da0dba9b530425381facc37d77Eric Laurent{
197232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent    return getActiveSessions().size() != 0;
198599c758b258cc5da0dba9b530425381facc37d77Eric Laurent}
199599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
200599c758b258cc5da0dba9b530425381facc37d77Eric Laurentbool AudioSessionCollection::isSourceActive(audio_source_t source) const
201599c758b258cc5da0dba9b530425381facc37d77Eric Laurent{
202599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    for (size_t i = 0; i < size(); i++) {
203599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        const sp<AudioSession>  audioSession = valueAt(i);
204599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        // AUDIO_SOURCE_HOTWORD is equivalent to AUDIO_SOURCE_VOICE_RECOGNITION only if it
205599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        // corresponds to an active capture triggered by a hardware hotword recognition
206599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        if (audioSession->activeCount() > 0 &&
207599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                ((audioSession->inputSource() == source) ||
208599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                ((source == AUDIO_SOURCE_VOICE_RECOGNITION) &&
209599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                 (audioSession->inputSource() == AUDIO_SOURCE_HOTWORD) &&
210599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                 audioSession->isSoundTrigger()))) {
211599c758b258cc5da0dba9b530425381facc37d77Eric Laurent            return true;
212599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        }
213599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    }
214599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    return false;
215599c758b258cc5da0dba9b530425381facc37d77Eric Laurent}
216599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
217599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
218599c758b258cc5da0dba9b530425381facc37d77Eric Laurentstatus_t AudioSessionCollection::dump(int fd, int spaces) const
219599c758b258cc5da0dba9b530425381facc37d77Eric Laurent{
220599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    const size_t SIZE = 256;
221599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    char buffer[SIZE];
222599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    snprintf(buffer, SIZE, "%*sAudio Sessions:\n", spaces, "");
223599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    write(fd, buffer, strlen(buffer));
224599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    for (size_t i = 0; i < size(); i++) {
225599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        valueAt(i)->dump(fd, spaces + 2, i);
226599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    }
227599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    return NO_ERROR;
228599c758b258cc5da0dba9b530425381facc37d77Eric Laurent}
229599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
230599c758b258cc5da0dba9b530425381facc37d77Eric Laurent}; // namespace android
231