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