Home | History | Annotate | Download | only in src
      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     mRecordClientInfo({ .uid = uid, .session = session, .source = inputSource}),
     42     mConfig({ .format = format, .sample_rate = sampleRate, .channel_mask = channelMask}),
     43     mFlags(flags), 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, &mRecordClientInfo,
     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() == mRecordClientInfo.session &&
    106         other->inputSource() == mRecordClientInfo.source &&
    107         other->format() == mConfig.format &&
    108         other->sampleRate() == mConfig.sample_rate &&
    109         other->channelMask() == mConfig.channel_mask &&
    110         other->flags() == mFlags &&
    111         other->uid() == mRecordClientInfo.uid) {
    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                     &mRecordClientInfo, &mConfig, &deviceConfig, patchHandle);
    134         }
    135     }
    136 }
    137 
    138 status_t AudioSession::dump(int fd, int spaces, int index) const
    139 {
    140     const size_t SIZE = 256;
    141     char buffer[SIZE];
    142     String8 result;
    143 
    144     snprintf(buffer, SIZE, "%*sAudio session %d:\n", spaces, "", index+1);
    145     result.append(buffer);
    146     snprintf(buffer, SIZE, "%*s- session: %2d\n", spaces, "", mRecordClientInfo.session);
    147     result.append(buffer);
    148     snprintf(buffer, SIZE, "%*s- owner uid: %2d\n", spaces, "", mRecordClientInfo.uid);
    149     result.append(buffer);
    150     snprintf(buffer, SIZE, "%*s- input source: %d\n", spaces, "", mRecordClientInfo.source);
    151     result.append(buffer);
    152     snprintf(buffer, SIZE, "%*s- format: %08x\n", spaces, "", mConfig.format);
    153     result.append(buffer);
    154     snprintf(buffer, SIZE, "%*s- sample: %d\n", spaces, "", mConfig.sample_rate);
    155     result.append(buffer);
    156     snprintf(buffer, SIZE, "%*s- channel mask: %08x\n",
    157              spaces, "", mConfig.channel_mask);
    158     result.append(buffer);
    159     snprintf(buffer, SIZE, "%*s- is soundtrigger: %s\n",
    160              spaces, "", mIsSoundTrigger ? "true" : "false");
    161     result.append(buffer);
    162     snprintf(buffer, SIZE, "%*s- open count: %d\n", spaces, "", mOpenCount);
    163     result.append(buffer);
    164     snprintf(buffer, SIZE, "%*s- active count: %d\n", spaces, "", mActiveCount);
    165     result.append(buffer);
    166 
    167     write(fd, result.string(), result.size());
    168     return NO_ERROR;
    169 }
    170 
    171 status_t AudioSessionCollection::addSession(audio_session_t session,
    172                                          const sp<AudioSession>& audioSession,
    173                                          AudioSessionInfoProvider *provider)
    174 {
    175     ssize_t index = indexOfKey(session);
    176 
    177     if (index >= 0) {
    178         ALOGW("addSession() session %d already in", session);
    179         return ALREADY_EXISTS;
    180     }
    181     audioSession->setInfoProvider(provider);
    182     add(session, audioSession);
    183     ALOGV("addSession() session %d  client %d source %d",
    184             session, audioSession->uid(), audioSession->inputSource());
    185     return NO_ERROR;
    186 }
    187 
    188 status_t AudioSessionCollection::removeSession(audio_session_t session)
    189 {
    190     ssize_t index = indexOfKey(session);
    191 
    192     if (index < 0) {
    193         ALOGW("removeSession() session %d not in", session);
    194         return ALREADY_EXISTS;
    195     }
    196     ALOGV("removeSession() session %d", session);
    197     valueAt(index)->setInfoProvider(NULL);
    198     removeItemsAt(index);
    199     return NO_ERROR;
    200 }
    201 
    202 uint32_t AudioSessionCollection::getOpenCount() const
    203 {
    204     uint32_t openCount = 0;
    205     for (size_t i = 0; i < size(); i++) {
    206         openCount += valueAt(i)->openCount();
    207     }
    208     return openCount;
    209 }
    210 
    211 AudioSessionCollection AudioSessionCollection::getActiveSessions() const
    212 {
    213     AudioSessionCollection activeSessions;
    214     for (size_t i = 0; i < size(); i++) {
    215         if (valueAt(i)->activeCount() != 0) {
    216             activeSessions.add(valueAt(i)->session(), valueAt(i));
    217         }
    218     }
    219     return activeSessions;
    220 }
    221 
    222 size_t AudioSessionCollection::getActiveSessionCount() const
    223 {
    224     size_t activeCount = 0;
    225     for (size_t i = 0; i < size(); i++) {
    226         if (valueAt(i)->activeCount() != 0) {
    227             activeCount++;
    228         }
    229     }
    230     return activeCount;
    231 }
    232 
    233 bool AudioSessionCollection::hasActiveSession() const
    234 {
    235     return getActiveSessionCount() != 0;
    236 }
    237 
    238 bool AudioSessionCollection::isSourceActive(audio_source_t source) const
    239 {
    240     for (size_t i = 0; i < size(); i++) {
    241         const sp<AudioSession>  audioSession = valueAt(i);
    242         // AUDIO_SOURCE_HOTWORD is equivalent to AUDIO_SOURCE_VOICE_RECOGNITION only if it
    243         // corresponds to an active capture triggered by a hardware hotword recognition
    244         if (audioSession->activeCount() > 0 &&
    245                 ((audioSession->inputSource() == source) ||
    246                 ((source == AUDIO_SOURCE_VOICE_RECOGNITION) &&
    247                  (audioSession->inputSource() == AUDIO_SOURCE_HOTWORD) &&
    248                  audioSession->isSoundTrigger()))) {
    249             return true;
    250         }
    251     }
    252     return false;
    253 }
    254 
    255 audio_source_t AudioSessionCollection::getHighestPrioritySource(bool activeOnly) const
    256 {
    257     audio_source_t source = AUDIO_SOURCE_DEFAULT;
    258     int32_t priority = -1;
    259 
    260     for (size_t i = 0; i < size(); i++) {
    261         const sp<AudioSession>  audioSession = valueAt(i);
    262         if (activeOnly && audioSession->activeCount() == 0) {
    263             continue;
    264         }
    265         int32_t curPriority = source_priority(audioSession->inputSource());
    266         if (curPriority > priority) {
    267             priority = curPriority;
    268             source = audioSession->inputSource();
    269         }
    270     }
    271     return source;
    272 }
    273 
    274 void AudioSessionCollection::onSessionInfoUpdate() const
    275 {
    276     for (size_t i = 0; i < size(); i++) {
    277         valueAt(i)->onSessionInfoUpdate();
    278     }
    279 }
    280 
    281 status_t AudioSessionCollection::dump(int fd, int spaces) const
    282 {
    283     const size_t SIZE = 256;
    284     char buffer[SIZE];
    285     snprintf(buffer, SIZE, "%*sAudio Sessions:\n", spaces, "");
    286     write(fd, buffer, strlen(buffer));
    287     for (size_t i = 0; i < size(); i++) {
    288         valueAt(i)->dump(fd, spaces + 2, i);
    289     }
    290     return NO_ERROR;
    291 }
    292 
    293 } // namespace android
    294