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 26 #include <log/log.h> 27 #include <utils/String8.h> 28 29 namespace android { 30 31 AudioSession::AudioSession(audio_session_t session, 32 audio_source_t inputSource, 33 audio_format_t format, 34 uint32_t sampleRate, 35 audio_channel_mask_t channelMask, 36 audio_input_flags_t flags, 37 uid_t uid, 38 bool isSoundTrigger, 39 AudioMix* policyMix, 40 AudioPolicyClientInterface *clientInterface) : 41 mSession(session), mInputSource(inputSource), 42 mConfig({ .format = format, .sample_rate = sampleRate, .channel_mask = channelMask}), 43 mFlags(flags), mUid(uid), mIsSoundTrigger(isSoundTrigger), 44 mOpenCount(1), mActiveCount(0), mPolicyMix(policyMix), mClientInterface(clientInterface), 45 mInfoProvider(NULL) 46 { 47 } 48 49 uint32_t AudioSession::changeOpenCount(int delta) 50 { 51 if ((delta + (int)mOpenCount) < 0) { 52 ALOGW("%s invalid delta %d, open count %d", 53 __FUNCTION__, delta, mOpenCount); 54 mOpenCount = (uint32_t)(-delta); 55 } 56 mOpenCount += delta; 57 ALOGV("%s open count %d", __FUNCTION__, mOpenCount); 58 return mOpenCount; 59 } 60 61 uint32_t AudioSession::changeActiveCount(int delta) 62 { 63 const uint32_t oldActiveCount = mActiveCount; 64 if ((delta + (int)mActiveCount) < 0) { 65 ALOGW("%s invalid delta %d, active count %d", 66 __FUNCTION__, delta, mActiveCount); 67 mActiveCount = (uint32_t)(-delta); 68 } 69 mActiveCount += delta; 70 ALOGV("%s active count %d", __FUNCTION__, mActiveCount); 71 int event = RECORD_CONFIG_EVENT_NONE; 72 73 if ((oldActiveCount == 0) && (mActiveCount > 0)) { 74 event = RECORD_CONFIG_EVENT_START; 75 } else if ((oldActiveCount > 0) && (mActiveCount == 0)) { 76 event = RECORD_CONFIG_EVENT_STOP; 77 } 78 79 if (event != RECORD_CONFIG_EVENT_NONE) { 80 // Dynamic policy callback: 81 // if input maps to a dynamic policy with an activity listener, notify of state change 82 if ((mPolicyMix != NULL) && ((mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0)) 83 { 84 mClientInterface->onDynamicPolicyMixStateUpdate(mPolicyMix->mDeviceAddress, 85 (event == RECORD_CONFIG_EVENT_START) ? MIX_STATE_MIXING : MIX_STATE_IDLE); 86 } 87 88 // Recording configuration callback: 89 const AudioSessionInfoProvider* provider = mInfoProvider; 90 const audio_config_base_t deviceConfig = (provider != NULL) ? provider->getConfig() : 91 AUDIO_CONFIG_BASE_INITIALIZER; 92 const audio_patch_handle_t patchHandle = (provider != NULL) ? provider->getPatchHandle() : 93 AUDIO_PATCH_HANDLE_NONE; 94 if (patchHandle != AUDIO_PATCH_HANDLE_NONE) { 95 mClientInterface->onRecordingConfigurationUpdate(event, mSession, mInputSource, 96 &mConfig, &deviceConfig, patchHandle); 97 } 98 } 99 100 return mActiveCount; 101 } 102 103 bool AudioSession::matches(const sp<AudioSession> &other) const 104 { 105 if (other->session() == mSession && 106 other->inputSource() == mInputSource && 107 other->format() == mConfig.format && 108 other->sampleRate() == mConfig.sample_rate && 109 other->channelMask() == mConfig.channel_mask && 110 other->flags() == mFlags && 111 other->uid() == mUid) { 112 return true; 113 } 114 return false; 115 } 116 117 void AudioSession::setInfoProvider(AudioSessionInfoProvider *provider) 118 { 119 mInfoProvider = provider; 120 } 121 122 void AudioSession::onSessionInfoUpdate() const 123 { 124 if (mActiveCount > 0) { 125 // resend the callback after requerying the informations from the info provider 126 const AudioSessionInfoProvider* provider = mInfoProvider; 127 const audio_config_base_t deviceConfig = (provider != NULL) ? provider->getConfig() : 128 AUDIO_CONFIG_BASE_INITIALIZER; 129 const audio_patch_handle_t patchHandle = (provider != NULL) ? provider->getPatchHandle() : 130 AUDIO_PATCH_HANDLE_NONE; 131 if (patchHandle != AUDIO_PATCH_HANDLE_NONE) { 132 mClientInterface->onRecordingConfigurationUpdate(RECORD_CONFIG_EVENT_START, 133 mSession, mInputSource, 134 &mConfig, &deviceConfig, patchHandle); 135 } 136 } 137 } 138 139 status_t AudioSession::dump(int fd, int spaces, int index) const 140 { 141 const size_t SIZE = 256; 142 char buffer[SIZE]; 143 String8 result; 144 145 snprintf(buffer, SIZE, "%*sAudio session %d:\n", spaces, "", index+1); 146 result.append(buffer); 147 snprintf(buffer, SIZE, "%*s- session: %2d\n", spaces, "", mSession); 148 result.append(buffer); 149 snprintf(buffer, SIZE, "%*s- owner uid: %2d\n", spaces, "", mUid); 150 result.append(buffer); 151 snprintf(buffer, SIZE, "%*s- input source: %d\n", spaces, "", mInputSource); 152 result.append(buffer); 153 snprintf(buffer, SIZE, "%*s- format: %08x\n", spaces, "", mConfig.format); 154 result.append(buffer); 155 snprintf(buffer, SIZE, "%*s- sample: %d\n", spaces, "", mConfig.sample_rate); 156 result.append(buffer); 157 snprintf(buffer, SIZE, "%*s- channel mask: %08x\n", 158 spaces, "", mConfig.channel_mask); 159 result.append(buffer); 160 snprintf(buffer, SIZE, "%*s- is soundtrigger: %s\n", 161 spaces, "", mIsSoundTrigger ? "true" : "false"); 162 result.append(buffer); 163 snprintf(buffer, SIZE, "%*s- open count: %d\n", spaces, "", mOpenCount); 164 result.append(buffer); 165 snprintf(buffer, SIZE, "%*s- active count: %d\n", spaces, "", mActiveCount); 166 result.append(buffer); 167 168 write(fd, result.string(), result.size()); 169 return NO_ERROR; 170 } 171 172 status_t AudioSessionCollection::addSession(audio_session_t session, 173 const sp<AudioSession>& audioSession, 174 AudioSessionInfoProvider *provider) 175 { 176 ssize_t index = indexOfKey(session); 177 178 if (index >= 0) { 179 ALOGW("addSession() session %d already in", session); 180 return ALREADY_EXISTS; 181 } 182 audioSession->setInfoProvider(provider); 183 add(session, audioSession); 184 ALOGV("addSession() session %d client %d source %d", 185 session, audioSession->uid(), audioSession->inputSource()); 186 return NO_ERROR; 187 } 188 189 status_t AudioSessionCollection::removeSession(audio_session_t session) 190 { 191 ssize_t index = indexOfKey(session); 192 193 if (index < 0) { 194 ALOGW("removeSession() session %d not in", session); 195 return ALREADY_EXISTS; 196 } 197 ALOGV("removeSession() session %d", session); 198 valueAt(index)->setInfoProvider(NULL); 199 removeItemsAt(index); 200 return NO_ERROR; 201 } 202 203 uint32_t AudioSessionCollection::getOpenCount() const 204 { 205 uint32_t openCount = 0; 206 for (size_t i = 0; i < size(); i++) { 207 openCount += valueAt(i)->openCount(); 208 } 209 return openCount; 210 } 211 212 AudioSessionCollection AudioSessionCollection::getActiveSessions() const 213 { 214 AudioSessionCollection activeSessions; 215 for (size_t i = 0; i < size(); i++) { 216 if (valueAt(i)->activeCount() != 0) { 217 activeSessions.add(valueAt(i)->session(), valueAt(i)); 218 } 219 } 220 return activeSessions; 221 } 222 223 size_t AudioSessionCollection::getActiveSessionCount() const 224 { 225 size_t activeCount = 0; 226 for (size_t i = 0; i < size(); i++) { 227 if (valueAt(i)->activeCount() != 0) { 228 activeCount++; 229 } 230 } 231 return activeCount; 232 } 233 234 bool AudioSessionCollection::hasActiveSession() const 235 { 236 return getActiveSessionCount() != 0; 237 } 238 239 bool AudioSessionCollection::isSourceActive(audio_source_t source) const 240 { 241 for (size_t i = 0; i < size(); i++) { 242 const sp<AudioSession> audioSession = valueAt(i); 243 // AUDIO_SOURCE_HOTWORD is equivalent to AUDIO_SOURCE_VOICE_RECOGNITION only if it 244 // corresponds to an active capture triggered by a hardware hotword recognition 245 if (audioSession->activeCount() > 0 && 246 ((audioSession->inputSource() == source) || 247 ((source == AUDIO_SOURCE_VOICE_RECOGNITION) && 248 (audioSession->inputSource() == AUDIO_SOURCE_HOTWORD) && 249 audioSession->isSoundTrigger()))) { 250 return true; 251 } 252 } 253 return false; 254 } 255 256 audio_source_t AudioSessionCollection::getHighestPrioritySource(bool activeOnly) const 257 { 258 audio_source_t source = AUDIO_SOURCE_DEFAULT; 259 int32_t priority = -1; 260 261 for (size_t i = 0; i < size(); i++) { 262 const sp<AudioSession> audioSession = valueAt(i); 263 if (activeOnly && audioSession->activeCount() == 0) { 264 continue; 265 } 266 int32_t curPriority = source_priority(audioSession->inputSource()); 267 if (curPriority > priority) { 268 priority = curPriority; 269 source = audioSession->inputSource(); 270 } 271 } 272 return source; 273 } 274 275 void AudioSessionCollection::onSessionInfoUpdate() const 276 { 277 for (size_t i = 0; i < size(); i++) { 278 valueAt(i)->onSessionInfoUpdate(); 279 } 280 } 281 282 status_t AudioSessionCollection::dump(int fd, int spaces) const 283 { 284 const size_t SIZE = 256; 285 char buffer[SIZE]; 286 snprintf(buffer, SIZE, "%*sAudio Sessions:\n", spaces, ""); 287 write(fd, buffer, strlen(buffer)); 288 for (size_t i = 0; i < size(); i++) { 289 valueAt(i)->dump(fd, spaces + 2, i); 290 } 291 return NO_ERROR; 292 } 293 294 }; // namespace android 295