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