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::AudioOutputDescriptor"
     18 //#define LOG_NDEBUG 0
     19 
     20 #include <AudioPolicyInterface.h>
     21 #include "AudioOutputDescriptor.h"
     22 #include "IOProfile.h"
     23 #include "AudioGain.h"
     24 #include "Volume.h"
     25 #include "HwModule.h"
     26 #include <media/AudioPolicy.h>
     27 
     28 // A device mask for all audio output devices that are considered "remote" when evaluating
     29 // active output devices in isStreamActiveRemotely()
     30 #define APM_AUDIO_OUT_DEVICE_REMOTE_ALL  AUDIO_DEVICE_OUT_REMOTE_SUBMIX
     31 
     32 namespace android {
     33 
     34 AudioOutputDescriptor::AudioOutputDescriptor(const sp<AudioPort>& port,
     35                                              AudioPolicyClientInterface *clientInterface)
     36     : mPort(port), mDevice(AUDIO_DEVICE_NONE),
     37       mClientInterface(clientInterface), mPatchHandle(AUDIO_PATCH_HANDLE_NONE), mId(0)
     38 {
     39     // clear usage count for all stream types
     40     for (int i = 0; i < AUDIO_STREAM_CNT; i++) {
     41         mRefCount[i] = 0;
     42         mCurVolume[i] = -1.0;
     43         mMuteCount[i] = 0;
     44         mStopTime[i] = 0;
     45     }
     46     for (int i = 0; i < NUM_STRATEGIES; i++) {
     47         mStrategyMutedByDevice[i] = false;
     48     }
     49     if (port != NULL) {
     50         port->pickAudioProfile(mSamplingRate, mChannelMask, mFormat);
     51         if (port->mGains.size() > 0) {
     52             port->mGains[0]->getDefaultConfig(&mGain);
     53         }
     54     }
     55 }
     56 
     57 audio_module_handle_t AudioOutputDescriptor::getModuleHandle() const
     58 {
     59     return mPort->getModuleHandle();
     60 }
     61 
     62 audio_port_handle_t AudioOutputDescriptor::getId() const
     63 {
     64     return mId;
     65 }
     66 
     67 audio_devices_t AudioOutputDescriptor::device() const
     68 {
     69     return mDevice;
     70 }
     71 
     72 audio_devices_t AudioOutputDescriptor::supportedDevices()
     73 {
     74     return mDevice;
     75 }
     76 
     77 bool AudioOutputDescriptor::sharesHwModuleWith(
     78         const sp<AudioOutputDescriptor> outputDesc)
     79 {
     80     if (outputDesc->isDuplicated()) {
     81         return sharesHwModuleWith(outputDesc->subOutput1()) ||
     82                     sharesHwModuleWith(outputDesc->subOutput2());
     83     } else {
     84         return (getModuleHandle() == outputDesc->getModuleHandle());
     85     }
     86 }
     87 
     88 void AudioOutputDescriptor::changeRefCount(audio_stream_type_t stream,
     89                                                                    int delta)
     90 {
     91     if ((delta + (int)mRefCount[stream]) < 0) {
     92         ALOGW("changeRefCount() invalid delta %d for stream %d, refCount %d",
     93               delta, stream, mRefCount[stream]);
     94         mRefCount[stream] = 0;
     95         return;
     96     }
     97     mRefCount[stream] += delta;
     98     ALOGV("changeRefCount() stream %d, count %d", stream, mRefCount[stream]);
     99 }
    100 
    101 bool AudioOutputDescriptor::isActive(uint32_t inPastMs) const
    102 {
    103     nsecs_t sysTime = 0;
    104     if (inPastMs != 0) {
    105         sysTime = systemTime();
    106     }
    107     for (int i = 0; i < (int)AUDIO_STREAM_CNT; i++) {
    108         if (i == AUDIO_STREAM_PATCH) {
    109             continue;
    110         }
    111         if (isStreamActive((audio_stream_type_t)i, inPastMs, sysTime)) {
    112             return true;
    113         }
    114     }
    115     return false;
    116 }
    117 
    118 bool AudioOutputDescriptor::isStreamActive(audio_stream_type_t stream,
    119                                            uint32_t inPastMs,
    120                                            nsecs_t sysTime) const
    121 {
    122     if (mRefCount[stream] != 0) {
    123         return true;
    124     }
    125     if (inPastMs == 0) {
    126         return false;
    127     }
    128     if (sysTime == 0) {
    129         sysTime = systemTime();
    130     }
    131     if (ns2ms(sysTime - mStopTime[stream]) < inPastMs) {
    132         return true;
    133     }
    134     return false;
    135 }
    136 
    137 
    138 bool AudioOutputDescriptor::isFixedVolume(audio_devices_t device __unused)
    139 {
    140     return false;
    141 }
    142 
    143 bool AudioOutputDescriptor::setVolume(float volume,
    144                                       audio_stream_type_t stream,
    145                                       audio_devices_t device __unused,
    146                                       uint32_t delayMs,
    147                                       bool force)
    148 {
    149     // We actually change the volume if:
    150     // - the float value returned by computeVolume() changed
    151     // - the force flag is set
    152     if (volume != mCurVolume[stream] || force) {
    153         ALOGV("setVolume() for stream %d, volume %f, delay %d", stream, volume, delayMs);
    154         mCurVolume[stream] = volume;
    155         return true;
    156     }
    157     return false;
    158 }
    159 
    160 void AudioOutputDescriptor::toAudioPortConfig(
    161                                                  struct audio_port_config *dstConfig,
    162                                                  const struct audio_port_config *srcConfig) const
    163 {
    164     dstConfig->config_mask = AUDIO_PORT_CONFIG_SAMPLE_RATE|AUDIO_PORT_CONFIG_CHANNEL_MASK|
    165                             AUDIO_PORT_CONFIG_FORMAT|AUDIO_PORT_CONFIG_GAIN;
    166     if (srcConfig != NULL) {
    167         dstConfig->config_mask |= srcConfig->config_mask;
    168     }
    169     AudioPortConfig::toAudioPortConfig(dstConfig, srcConfig);
    170 
    171     dstConfig->id = mId;
    172     dstConfig->role = AUDIO_PORT_ROLE_SOURCE;
    173     dstConfig->type = AUDIO_PORT_TYPE_MIX;
    174     dstConfig->ext.mix.hw_module = getModuleHandle();
    175     dstConfig->ext.mix.usecase.stream = AUDIO_STREAM_DEFAULT;
    176 }
    177 
    178 void AudioOutputDescriptor::toAudioPort(
    179                                                     struct audio_port *port) const
    180 {
    181     mPort->toAudioPort(port);
    182     port->id = mId;
    183     port->ext.mix.hw_module = getModuleHandle();
    184 }
    185 
    186 status_t AudioOutputDescriptor::dump(int fd)
    187 {
    188     const size_t SIZE = 256;
    189     char buffer[SIZE];
    190     String8 result;
    191 
    192     snprintf(buffer, SIZE, " ID: %d\n", mId);
    193     result.append(buffer);
    194     snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate);
    195     result.append(buffer);
    196     snprintf(buffer, SIZE, " Format: %08x\n", mFormat);
    197     result.append(buffer);
    198     snprintf(buffer, SIZE, " Channels: %08x\n", mChannelMask);
    199     result.append(buffer);
    200     snprintf(buffer, SIZE, " Devices %08x\n", device());
    201     result.append(buffer);
    202     snprintf(buffer, SIZE, " Stream volume refCount muteCount\n");
    203     result.append(buffer);
    204     for (int i = 0; i < (int)AUDIO_STREAM_CNT; i++) {
    205         snprintf(buffer, SIZE, " %02d     %.03f     %02d       %02d\n",
    206                  i, mCurVolume[i], mRefCount[i], mMuteCount[i]);
    207         result.append(buffer);
    208     }
    209     write(fd, result.string(), result.size());
    210 
    211     return NO_ERROR;
    212 }
    213 
    214 void AudioOutputDescriptor::log(const char* indent)
    215 {
    216     ALOGI("%sID: %d,0x%X, [rt:%d fmt:0x%X ch:0x%X]",
    217           indent, mId, mId, mSamplingRate, mFormat, mChannelMask);
    218 }
    219 
    220 // SwAudioOutputDescriptor implementation
    221 SwAudioOutputDescriptor::SwAudioOutputDescriptor(const sp<IOProfile>& profile,
    222                                                  AudioPolicyClientInterface *clientInterface)
    223     : AudioOutputDescriptor(profile, clientInterface),
    224     mProfile(profile), mIoHandle(0), mLatency(0),
    225     mFlags((audio_output_flags_t)0), mPolicyMix(NULL),
    226     mOutput1(0), mOutput2(0), mDirectOpenCount(0), mGlobalRefCount(0)
    227 {
    228     if (profile != NULL) {
    229         mFlags = (audio_output_flags_t)profile->getFlags();
    230     }
    231 }
    232 
    233 void SwAudioOutputDescriptor::setIoHandle(audio_io_handle_t ioHandle)
    234 {
    235     mId = AudioPort::getNextUniqueId();
    236     mIoHandle = ioHandle;
    237 }
    238 
    239 
    240 status_t SwAudioOutputDescriptor::dump(int fd)
    241 {
    242     const size_t SIZE = 256;
    243     char buffer[SIZE];
    244     String8 result;
    245 
    246     snprintf(buffer, SIZE, " Latency: %d\n", mLatency);
    247     result.append(buffer);
    248     snprintf(buffer, SIZE, " Flags %08x\n", mFlags);
    249     result.append(buffer);
    250     write(fd, result.string(), result.size());
    251 
    252     AudioOutputDescriptor::dump(fd);
    253 
    254     return NO_ERROR;
    255 }
    256 
    257 audio_devices_t SwAudioOutputDescriptor::device() const
    258 {
    259     if (isDuplicated()) {
    260         return (audio_devices_t)(mOutput1->mDevice | mOutput2->mDevice);
    261     } else {
    262         return mDevice;
    263     }
    264 }
    265 
    266 bool SwAudioOutputDescriptor::sharesHwModuleWith(
    267         const sp<AudioOutputDescriptor> outputDesc)
    268 {
    269     if (isDuplicated()) {
    270         return mOutput1->sharesHwModuleWith(outputDesc) || mOutput2->sharesHwModuleWith(outputDesc);
    271     } else if (outputDesc->isDuplicated()){
    272         return sharesHwModuleWith(outputDesc->subOutput1()) ||
    273                     sharesHwModuleWith(outputDesc->subOutput2());
    274     } else {
    275         return AudioOutputDescriptor::sharesHwModuleWith(outputDesc);
    276     }
    277 }
    278 
    279 audio_devices_t SwAudioOutputDescriptor::supportedDevices()
    280 {
    281     if (isDuplicated()) {
    282         return (audio_devices_t)(mOutput1->supportedDevices() | mOutput2->supportedDevices());
    283     } else {
    284         return mProfile->getSupportedDevicesType();
    285     }
    286 }
    287 
    288 uint32_t SwAudioOutputDescriptor::latency()
    289 {
    290     if (isDuplicated()) {
    291         return (mOutput1->mLatency > mOutput2->mLatency) ? mOutput1->mLatency : mOutput2->mLatency;
    292     } else {
    293         return mLatency;
    294     }
    295 }
    296 
    297 void SwAudioOutputDescriptor::changeRefCount(audio_stream_type_t stream,
    298                                                                    int delta)
    299 {
    300     // forward usage count change to attached outputs
    301     if (isDuplicated()) {
    302         mOutput1->changeRefCount(stream, delta);
    303         mOutput2->changeRefCount(stream, delta);
    304     }
    305     AudioOutputDescriptor::changeRefCount(stream, delta);
    306 
    307     // handle stream-independent ref count
    308     uint32_t oldGlobalRefCount = mGlobalRefCount;
    309     if ((delta + (int)mGlobalRefCount) < 0) {
    310         ALOGW("changeRefCount() invalid delta %d globalRefCount %d", delta, mGlobalRefCount);
    311         mGlobalRefCount = 0;
    312     } else {
    313         mGlobalRefCount += delta;
    314     }
    315     if ((oldGlobalRefCount == 0) && (mGlobalRefCount > 0)) {
    316         if ((mPolicyMix != NULL) && ((mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0))
    317         {
    318             mClientInterface->onDynamicPolicyMixStateUpdate(mPolicyMix->mDeviceAddress,
    319                     MIX_STATE_MIXING);
    320         }
    321 
    322     } else if ((oldGlobalRefCount > 0) && (mGlobalRefCount == 0)) {
    323         if ((mPolicyMix != NULL) && ((mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0))
    324         {
    325             mClientInterface->onDynamicPolicyMixStateUpdate(mPolicyMix->mDeviceAddress,
    326                     MIX_STATE_IDLE);
    327         }
    328     }
    329 }
    330 
    331 
    332 bool SwAudioOutputDescriptor::isFixedVolume(audio_devices_t device)
    333 {
    334     // unit gain if rerouting to external policy
    335     if (device == AUDIO_DEVICE_OUT_REMOTE_SUBMIX) {
    336         if (mPolicyMix != NULL) {
    337             ALOGV("max gain when rerouting for output=%d", mIoHandle);
    338             return true;
    339         }
    340     }
    341     return false;
    342 }
    343 
    344 void SwAudioOutputDescriptor::toAudioPortConfig(
    345                                                  struct audio_port_config *dstConfig,
    346                                                  const struct audio_port_config *srcConfig) const
    347 {
    348 
    349     ALOG_ASSERT(!isDuplicated(), "toAudioPortConfig() called on duplicated output %d", mIoHandle);
    350     AudioOutputDescriptor::toAudioPortConfig(dstConfig, srcConfig);
    351 
    352     dstConfig->ext.mix.handle = mIoHandle;
    353 }
    354 
    355 void SwAudioOutputDescriptor::toAudioPort(
    356                                                     struct audio_port *port) const
    357 {
    358     ALOG_ASSERT(!isDuplicated(), "toAudioPort() called on duplicated output %d", mIoHandle);
    359 
    360     AudioOutputDescriptor::toAudioPort(port);
    361 
    362     toAudioPortConfig(&port->active_config);
    363     port->ext.mix.handle = mIoHandle;
    364     port->ext.mix.latency_class =
    365             mFlags & AUDIO_OUTPUT_FLAG_FAST ? AUDIO_LATENCY_LOW : AUDIO_LATENCY_NORMAL;
    366 }
    367 
    368 bool SwAudioOutputDescriptor::setVolume(float volume,
    369                                         audio_stream_type_t stream,
    370                                         audio_devices_t device,
    371                                         uint32_t delayMs,
    372                                         bool force)
    373 {
    374     bool changed = AudioOutputDescriptor::setVolume(volume, stream, device, delayMs, force);
    375 
    376     if (changed) {
    377         // Force VOICE_CALL to track BLUETOOTH_SCO stream volume when bluetooth audio is
    378         // enabled
    379         float volume = Volume::DbToAmpl(mCurVolume[stream]);
    380         if (stream == AUDIO_STREAM_BLUETOOTH_SCO) {
    381             mClientInterface->setStreamVolume(
    382                     AUDIO_STREAM_VOICE_CALL, volume, mIoHandle, delayMs);
    383         }
    384         mClientInterface->setStreamVolume(stream, volume, mIoHandle, delayMs);
    385     }
    386     return changed;
    387 }
    388 
    389 // HwAudioOutputDescriptor implementation
    390 HwAudioOutputDescriptor::HwAudioOutputDescriptor(const sp<AudioSourceDescriptor>& source,
    391                                                  AudioPolicyClientInterface *clientInterface)
    392     : AudioOutputDescriptor(source->mDevice, clientInterface),
    393       mSource(source)
    394 {
    395 }
    396 
    397 status_t HwAudioOutputDescriptor::dump(int fd)
    398 {
    399     const size_t SIZE = 256;
    400     char buffer[SIZE];
    401     String8 result;
    402 
    403     AudioOutputDescriptor::dump(fd);
    404 
    405     snprintf(buffer, SIZE, "Source:\n");
    406     result.append(buffer);
    407     write(fd, result.string(), result.size());
    408     mSource->dump(fd);
    409 
    410     return NO_ERROR;
    411 }
    412 
    413 audio_devices_t HwAudioOutputDescriptor::supportedDevices()
    414 {
    415     return mDevice;
    416 }
    417 
    418 void HwAudioOutputDescriptor::toAudioPortConfig(
    419                                                  struct audio_port_config *dstConfig,
    420                                                  const struct audio_port_config *srcConfig) const
    421 {
    422     mSource->mDevice->toAudioPortConfig(dstConfig, srcConfig);
    423 }
    424 
    425 void HwAudioOutputDescriptor::toAudioPort(
    426                                                     struct audio_port *port) const
    427 {
    428     mSource->mDevice->toAudioPort(port);
    429 }
    430 
    431 
    432 bool HwAudioOutputDescriptor::setVolume(float volume,
    433                                         audio_stream_type_t stream,
    434                                         audio_devices_t device,
    435                                         uint32_t delayMs,
    436                                         bool force)
    437 {
    438     bool changed = AudioOutputDescriptor::setVolume(volume, stream, device, delayMs, force);
    439 
    440     if (changed) {
    441       // TODO: use gain controller on source device if any to adjust volume
    442     }
    443     return changed;
    444 }
    445 
    446 // SwAudioOutputCollection implementation
    447 bool SwAudioOutputCollection::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const
    448 {
    449     nsecs_t sysTime = systemTime();
    450     for (size_t i = 0; i < this->size(); i++) {
    451         const sp<SwAudioOutputDescriptor> outputDesc = this->valueAt(i);
    452         if (outputDesc->isStreamActive(stream, inPastMs, sysTime)) {
    453             return true;
    454         }
    455     }
    456     return false;
    457 }
    458 
    459 bool SwAudioOutputCollection::isStreamActiveRemotely(audio_stream_type_t stream,
    460                                                    uint32_t inPastMs) const
    461 {
    462     nsecs_t sysTime = systemTime();
    463     for (size_t i = 0; i < size(); i++) {
    464         const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
    465         if (((outputDesc->device() & APM_AUDIO_OUT_DEVICE_REMOTE_ALL) != 0) &&
    466                 outputDesc->isStreamActive(stream, inPastMs, sysTime)) {
    467             // do not consider re routing (when the output is going to a dynamic policy)
    468             // as "remote playback"
    469             if (outputDesc->mPolicyMix == NULL) {
    470                 return true;
    471             }
    472         }
    473     }
    474     return false;
    475 }
    476 
    477 audio_io_handle_t SwAudioOutputCollection::getA2dpOutput() const
    478 {
    479     for (size_t i = 0; i < size(); i++) {
    480         sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
    481         if (!outputDesc->isDuplicated() && outputDesc->device() & AUDIO_DEVICE_OUT_ALL_A2DP) {
    482             return this->keyAt(i);
    483         }
    484     }
    485     return 0;
    486 }
    487 
    488 sp<SwAudioOutputDescriptor> SwAudioOutputCollection::getPrimaryOutput() const
    489 {
    490     for (size_t i = 0; i < size(); i++) {
    491         const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
    492         if (outputDesc->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) {
    493             return outputDesc;
    494         }
    495     }
    496     return NULL;
    497 }
    498 
    499 sp<SwAudioOutputDescriptor> SwAudioOutputCollection::getOutputFromId(audio_port_handle_t id) const
    500 {
    501     sp<SwAudioOutputDescriptor> outputDesc = NULL;
    502     for (size_t i = 0; i < size(); i++) {
    503         outputDesc = valueAt(i);
    504         if (outputDesc->getId() == id) {
    505             break;
    506         }
    507     }
    508     return outputDesc;
    509 }
    510 
    511 bool SwAudioOutputCollection::isAnyOutputActive(audio_stream_type_t streamToIgnore) const
    512 {
    513     for (size_t s = 0 ; s < AUDIO_STREAM_CNT ; s++) {
    514         if (s == (size_t) streamToIgnore) {
    515             continue;
    516         }
    517         for (size_t i = 0; i < size(); i++) {
    518             const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
    519             if (outputDesc->mRefCount[s] != 0) {
    520                 return true;
    521             }
    522         }
    523     }
    524     return false;
    525 }
    526 
    527 audio_devices_t SwAudioOutputCollection::getSupportedDevices(audio_io_handle_t handle) const
    528 {
    529     sp<SwAudioOutputDescriptor> outputDesc = valueFor(handle);
    530     audio_devices_t devices = outputDesc->mProfile->getSupportedDevicesType();
    531     return devices;
    532 }
    533 
    534 
    535 status_t SwAudioOutputCollection::dump(int fd) const
    536 {
    537     const size_t SIZE = 256;
    538     char buffer[SIZE];
    539 
    540     snprintf(buffer, SIZE, "\nOutputs dump:\n");
    541     write(fd, buffer, strlen(buffer));
    542     for (size_t i = 0; i < size(); i++) {
    543         snprintf(buffer, SIZE, "- Output %d dump:\n", keyAt(i));
    544         write(fd, buffer, strlen(buffer));
    545         valueAt(i)->dump(fd);
    546     }
    547 
    548     return NO_ERROR;
    549 }
    550 
    551 // HwAudioOutputCollection implementation
    552 bool HwAudioOutputCollection::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const
    553 {
    554     nsecs_t sysTime = systemTime();
    555     for (size_t i = 0; i < this->size(); i++) {
    556         const sp<HwAudioOutputDescriptor> outputDesc = this->valueAt(i);
    557         if (outputDesc->isStreamActive(stream, inPastMs, sysTime)) {
    558             return true;
    559         }
    560     }
    561     return false;
    562 }
    563 
    564 bool HwAudioOutputCollection::isAnyOutputActive(audio_stream_type_t streamToIgnore) const
    565 {
    566     for (size_t s = 0 ; s < AUDIO_STREAM_CNT ; s++) {
    567         if (s == (size_t) streamToIgnore) {
    568             continue;
    569         }
    570         for (size_t i = 0; i < size(); i++) {
    571             const sp<HwAudioOutputDescriptor> outputDesc = valueAt(i);
    572             if (outputDesc->mRefCount[s] != 0) {
    573                 return true;
    574             }
    575         }
    576     }
    577     return false;
    578 }
    579 
    580 status_t HwAudioOutputCollection::dump(int fd) const
    581 {
    582     const size_t SIZE = 256;
    583     char buffer[SIZE];
    584 
    585     snprintf(buffer, SIZE, "\nOutputs dump:\n");
    586     write(fd, buffer, strlen(buffer));
    587     for (size_t i = 0; i < size(); i++) {
    588         snprintf(buffer, SIZE, "- Output %d dump:\n", keyAt(i));
    589         write(fd, buffer, strlen(buffer));
    590         valueAt(i)->dump(fd);
    591     }
    592 
    593     return NO_ERROR;
    594 }
    595 
    596 }; //namespace android
    597