AudioSession.cpp revision 56afc7a5cc0f0bfc8021f6413b2e2267050bdc8a
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 "policy.h" 22#include "AudioSession.h" 23#include "AudioGain.h" 24#include "TypeConverter.h" 25#include <cutils/log.h> 26#include <utils/String8.h> 27 28namespace android { 29 30AudioSession::AudioSession(audio_session_t session, 31 audio_source_t inputSource, 32 audio_format_t format, 33 uint32_t sampleRate, 34 audio_channel_mask_t channelMask, 35 audio_input_flags_t flags, 36 uid_t uid, 37 bool isSoundTrigger, 38 AudioMix* policyMix, 39 AudioPolicyClientInterface *clientInterface) : 40 mSession(session), mInputSource(inputSource), 41 mFormat(format), mSampleRate(sampleRate), mChannelMask(channelMask), 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); 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); 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() == mFormat && 98 other->sampleRate() == mSampleRate && 99 other->channelMask() == mChannelMask && 100 other->flags() == mFlags && 101 other->uid() == mUid) { 102 return true; 103 } 104 return false; 105} 106 107 108status_t AudioSession::dump(int fd, int spaces, int index) const 109{ 110 const size_t SIZE = 256; 111 char buffer[SIZE]; 112 String8 result; 113 114 snprintf(buffer, SIZE, "%*sAudio session %d:\n", spaces, "", index+1); 115 result.append(buffer); 116 snprintf(buffer, SIZE, "%*s- session: %2d\n", spaces, "", mSession); 117 result.append(buffer); 118 snprintf(buffer, SIZE, "%*s- owner uid: %2d\n", spaces, "", mUid); 119 result.append(buffer); 120 snprintf(buffer, SIZE, "%*s- input source: %d\n", spaces, "", mInputSource); 121 result.append(buffer); 122 snprintf(buffer, SIZE, "%*s- format: %08x\n", spaces, "", mFormat); 123 result.append(buffer); 124 snprintf(buffer, SIZE, "%*s- sample: %d\n", spaces, "", mSampleRate); 125 result.append(buffer); 126 snprintf(buffer, SIZE, "%*s- channel mask: %08x\n", 127 spaces, "", mChannelMask); 128 result.append(buffer); 129 snprintf(buffer, SIZE, "%*s- is soundtrigger: %s\n", 130 spaces, "", mIsSoundTrigger ? "true" : "false"); 131 result.append(buffer); 132 snprintf(buffer, SIZE, "%*s- open count: %d\n", spaces, "", mOpenCount); 133 result.append(buffer); 134 snprintf(buffer, SIZE, "%*s- active count: %d\n", spaces, "", mActiveCount); 135 result.append(buffer); 136 137 write(fd, result.string(), result.size()); 138 return NO_ERROR; 139} 140 141status_t AudioSessionCollection::addSession(audio_session_t session, 142 const sp<AudioSession>& audioSession) 143{ 144 ssize_t index = indexOfKey(session); 145 146 if (index >= 0) { 147 ALOGW("addSession() session %d already in", session); 148 return ALREADY_EXISTS; 149 } 150 add(session, audioSession); 151 ALOGV("addSession() session %d client %d source %d", 152 session, audioSession->uid(), audioSession->inputSource()); 153 return NO_ERROR; 154} 155 156status_t AudioSessionCollection::removeSession(audio_session_t session) 157{ 158 ssize_t index = indexOfKey(session); 159 160 if (index < 0) { 161 ALOGW("removeSession() session %d not in", session); 162 return ALREADY_EXISTS; 163 } 164 ALOGV("removeSession() session %d", session); 165 removeItemsAt(index); 166 return NO_ERROR; 167} 168 169uint32_t AudioSessionCollection::getOpenCount() const 170{ 171 uint32_t openCount = 0; 172 for (size_t i = 0; i < size(); i++) { 173 openCount += valueAt(i)->openCount(); 174 } 175 return openCount; 176} 177 178AudioSessionCollection AudioSessionCollection::getActiveSessions() const 179{ 180 AudioSessionCollection activeSessions; 181 for (size_t i = 0; i < size(); i++) { 182 if (valueAt(i)->activeCount() != 0) { 183 activeSessions.add(valueAt(i)->session(), valueAt(i)); 184 } 185 } 186 return activeSessions; 187} 188 189size_t AudioSessionCollection::getActiveSessionCount() const 190{ 191 size_t activeCount = 0; 192 for (size_t i = 0; i < size(); i++) { 193 if (valueAt(i)->activeCount() != 0) { 194 activeCount++; 195 } 196 } 197 return activeCount; 198} 199 200bool AudioSessionCollection::hasActiveSession() const 201{ 202 return getActiveSessionCount() != 0; 203} 204 205bool AudioSessionCollection::isSourceActive(audio_source_t source) const 206{ 207 for (size_t i = 0; i < size(); i++) { 208 const sp<AudioSession> audioSession = valueAt(i); 209 // AUDIO_SOURCE_HOTWORD is equivalent to AUDIO_SOURCE_VOICE_RECOGNITION only if it 210 // corresponds to an active capture triggered by a hardware hotword recognition 211 if (audioSession->activeCount() > 0 && 212 ((audioSession->inputSource() == source) || 213 ((source == AUDIO_SOURCE_VOICE_RECOGNITION) && 214 (audioSession->inputSource() == AUDIO_SOURCE_HOTWORD) && 215 audioSession->isSoundTrigger()))) { 216 return true; 217 } 218 } 219 return false; 220} 221 222audio_source_t AudioSessionCollection::getHighestPrioritySource(bool activeOnly) const 223{ 224 audio_source_t source = AUDIO_SOURCE_DEFAULT; 225 int32_t priority = -1; 226 227 for (size_t i = 0; i < size(); i++) { 228 const sp<AudioSession> audioSession = valueAt(i); 229 if (activeOnly && audioSession->activeCount() == 0) { 230 continue; 231 } 232 int32_t curPriority = source_priority(audioSession->inputSource()); 233 if (curPriority > priority) { 234 priority = curPriority; 235 source = audioSession->inputSource(); 236 } 237 } 238 return source; 239} 240 241status_t AudioSessionCollection::dump(int fd, int spaces) const 242{ 243 const size_t SIZE = 256; 244 char buffer[SIZE]; 245 snprintf(buffer, SIZE, "%*sAudio Sessions:\n", spaces, ""); 246 write(fd, buffer, strlen(buffer)); 247 for (size_t i = 0; i < size(); i++) { 248 valueAt(i)->dump(fd, spaces + 2, i); 249 } 250 return NO_ERROR; 251} 252 253}; // namespace android 254