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 "AudioPolicyMix.h"
     23 #include "IOProfile.h"
     24 #include "AudioGain.h"
     25 #include "Volume.h"
     26 #include "HwModule.h"
     27 #include "TypeConverter.h"
     28 #include <media/AudioParameter.h>
     29 #include <media/AudioPolicy.h>
     30 
     31 // A device mask for all audio output devices that are considered "remote" when evaluating
     32 // active output devices in isStreamActiveRemotely()
     33 #define APM_AUDIO_OUT_DEVICE_REMOTE_ALL  AUDIO_DEVICE_OUT_REMOTE_SUBMIX
     34 
     35 namespace android {
     36 
     37 AudioOutputDescriptor::AudioOutputDescriptor(const sp<AudioPort>& port,
     38                                              AudioPolicyClientInterface *clientInterface)
     39     : mPort(port), mClientInterface(clientInterface)
     40 {
     41     if (mPort.get() != nullptr) {
     42         mPort->pickAudioProfile(mSamplingRate, mChannelMask, mFormat);
     43         if (mPort->mGains.size() > 0) {
     44             mPort->mGains[0]->getDefaultConfig(&mGain);
     45         }
     46     }
     47 }
     48 
     49 audio_config_base_t AudioOutputDescriptor::getConfig() const
     50 {
     51     const audio_config_base_t config = { .sample_rate = mSamplingRate, .channel_mask = mChannelMask,
     52             .format = mFormat };
     53     return config;
     54 }
     55 
     56 audio_module_handle_t AudioOutputDescriptor::getModuleHandle() const
     57 {
     58     return mPort.get() != nullptr ? mPort->getModuleHandle() : AUDIO_MODULE_HANDLE_NONE;
     59 }
     60 
     61 audio_patch_handle_t AudioOutputDescriptor::getPatchHandle() const
     62 {
     63     return mPatchHandle;
     64 }
     65 
     66 void AudioOutputDescriptor::setPatchHandle(audio_patch_handle_t handle)
     67 {
     68     mPatchHandle = handle;
     69 }
     70 
     71 audio_port_handle_t AudioOutputDescriptor::getId() const
     72 {
     73     return mId;
     74 }
     75 
     76 bool AudioOutputDescriptor::sharesHwModuleWith(
     77         const sp<AudioOutputDescriptor>& outputDesc)
     78 {
     79     return hasSameHwModuleAs(outputDesc);
     80 }
     81 
     82 void AudioOutputDescriptor::setStopTime(const sp<TrackClientDescriptor>& client, nsecs_t sysTime)
     83 {
     84     mVolumeActivities[client->volumeSource()].setStopTime(sysTime);
     85     mRoutingActivities[client->strategy()].setStopTime(sysTime);
     86 }
     87 
     88 void AudioOutputDescriptor::setClientActive(const sp<TrackClientDescriptor>& client, bool active)
     89 {
     90     auto clientIter = std::find(begin(mActiveClients), end(mActiveClients), client);
     91     if (active == (clientIter != end(mActiveClients))) {
     92         ALOGW("%s(%s): ignored active: %d, current stream count %d", __func__,
     93               client->toShortString().c_str(), active,
     94               mRoutingActivities.at(client->strategy()).getActivityCount());
     95         return;
     96     }
     97     if (active) {
     98         mActiveClients.push_back(client);
     99     } else {
    100         mActiveClients.erase(clientIter);
    101     }
    102     const int delta = active ? 1 : -1;
    103     // If ps is unknown, it is time to track it!
    104     mRoutingActivities[client->strategy()].changeActivityCount(delta);
    105     mVolumeActivities[client->volumeSource()].changeActivityCount(delta);
    106 
    107     // Handle non-client-specific activity ref count
    108     int32_t oldGlobalActiveCount = mGlobalActiveCount;
    109     if (!active && mGlobalActiveCount < 1) {
    110         ALOGW("%s(%s): invalid deactivation with globalRefCount %d",
    111               __func__, client->toShortString().c_str(), mGlobalActiveCount);
    112         mGlobalActiveCount = 1;
    113     }
    114     mGlobalActiveCount += delta;
    115 
    116     sp<AudioPolicyMix> policyMix = mPolicyMix.promote();
    117     if ((policyMix != NULL) && ((policyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0)) {
    118         if ((oldGlobalActiveCount == 0) || (mGlobalActiveCount == 0)) {
    119             mClientInterface->onDynamicPolicyMixStateUpdate(policyMix->mDeviceAddress,
    120                 mGlobalActiveCount > 0 ? MIX_STATE_MIXING : MIX_STATE_IDLE);
    121         }
    122     }
    123     client->setActive(active);
    124 }
    125 
    126 bool AudioOutputDescriptor::isActive(VolumeSource vs, uint32_t inPastMs, nsecs_t sysTime) const
    127 {
    128     return (vs == VOLUME_SOURCE_NONE) ?
    129                 isActive(inPastMs) : (mVolumeActivities.find(vs) != std::end(mVolumeActivities)?
    130                 mVolumeActivities.at(vs).isActive(inPastMs, sysTime) : false);
    131 }
    132 
    133 bool AudioOutputDescriptor::isActive(uint32_t inPastMs) const
    134 {
    135     nsecs_t sysTime = 0;
    136     if (inPastMs != 0) {
    137         sysTime = systemTime();
    138     }
    139     for (const auto &iter : mVolumeActivities) {
    140         if (iter.second.isActive(inPastMs, sysTime)) {
    141             return true;
    142         }
    143     }
    144     return false;
    145 }
    146 
    147 bool AudioOutputDescriptor::isFixedVolume(audio_devices_t device __unused)
    148 {
    149     return false;
    150 }
    151 
    152 bool AudioOutputDescriptor::setVolume(float volumeDb,
    153                                       VolumeSource volumeSource,
    154                                       const StreamTypeVector &/*streams*/,
    155                                       audio_devices_t /*device*/,
    156                                       uint32_t delayMs,
    157                                       bool force)
    158 {
    159     // We actually change the volume if:
    160     // - the float value returned by computeVolume() changed
    161     // - the force flag is set
    162     if (volumeDb != getCurVolume(volumeSource) || force) {
    163         ALOGV("%s for volumeSrc %d, volume %f, delay %d", __func__, volumeSource, volumeDb, delayMs);
    164         setCurVolume(volumeSource, volumeDb);
    165         return true;
    166     }
    167     return false;
    168 }
    169 
    170 void AudioOutputDescriptor::toAudioPortConfig(
    171                                                  struct audio_port_config *dstConfig,
    172                                                  const struct audio_port_config *srcConfig) const
    173 {
    174     dstConfig->config_mask = AUDIO_PORT_CONFIG_SAMPLE_RATE|AUDIO_PORT_CONFIG_CHANNEL_MASK|
    175                             AUDIO_PORT_CONFIG_FORMAT|AUDIO_PORT_CONFIG_GAIN;
    176     if (srcConfig != NULL) {
    177         dstConfig->config_mask |= srcConfig->config_mask;
    178     }
    179     AudioPortConfig::toAudioPortConfig(dstConfig, srcConfig);
    180 
    181     dstConfig->id = mId;
    182     dstConfig->role = AUDIO_PORT_ROLE_SOURCE;
    183     dstConfig->type = AUDIO_PORT_TYPE_MIX;
    184     dstConfig->ext.mix.hw_module = getModuleHandle();
    185     dstConfig->ext.mix.usecase.stream = AUDIO_STREAM_DEFAULT;
    186 }
    187 
    188 void AudioOutputDescriptor::toAudioPort(struct audio_port *port) const
    189 {
    190     // Should not be called for duplicated ports, see SwAudioOutputDescriptor::toAudioPortConfig.
    191     mPort->toAudioPort(port);
    192     port->id = mId;
    193     port->ext.mix.hw_module = getModuleHandle();
    194 }
    195 
    196 TrackClientVector AudioOutputDescriptor::clientsList(bool activeOnly, product_strategy_t strategy,
    197                                                      bool preferredDeviceOnly) const
    198 {
    199     TrackClientVector clients;
    200     for (const auto &client : getClientIterable()) {
    201         if ((!activeOnly || client->active())
    202             && (strategy == PRODUCT_STRATEGY_NONE || strategy == client->strategy())
    203             && (!preferredDeviceOnly ||
    204                 (client->hasPreferredDevice() && !client->isPreferredDeviceForExclusiveUse()))) {
    205             clients.push_back(client);
    206         }
    207     }
    208     return clients;
    209 }
    210 
    211 bool AudioOutputDescriptor::isAnyActive(VolumeSource volumeSourceToIgnore) const
    212 {
    213     return std::find_if(begin(mActiveClients), end(mActiveClients),
    214                         [&volumeSourceToIgnore](const auto &client) {
    215         return client->volumeSource() != volumeSourceToIgnore; }) != end(mActiveClients);
    216 }
    217 
    218 void AudioOutputDescriptor::dump(String8 *dst) const
    219 {
    220     dst->appendFormat(" ID: %d\n", mId);
    221     dst->appendFormat(" Sampling rate: %d\n", mSamplingRate);
    222     dst->appendFormat(" Format: %08x\n", mFormat);
    223     dst->appendFormat(" Channels: %08x\n", mChannelMask);
    224     dst->appendFormat(" Devices: %s\n", devices().toString().c_str());
    225     dst->appendFormat(" Global active count: %u\n", mGlobalActiveCount);
    226     for (const auto &iter : mRoutingActivities) {
    227         dst->appendFormat(" Product Strategy id: %d", iter.first);
    228         iter.second.dump(dst, 4);
    229     }
    230     for (const auto &iter : mVolumeActivities) {
    231         dst->appendFormat(" Volume Activities id: %d", iter.first);
    232         iter.second.dump(dst, 4);
    233     }
    234     dst->append(" AudioTrack Clients:\n");
    235     ClientMapHandler<TrackClientDescriptor>::dump(dst);
    236     dst->append("\n");
    237     if (!mActiveClients.empty()) {
    238         dst->append(" AudioTrack active (stream) clients:\n");
    239         size_t index = 0;
    240         for (const auto& client : mActiveClients) {
    241             client->dump(dst, 2, index++);
    242         }
    243         dst->append(" \n");
    244     }
    245 }
    246 
    247 void AudioOutputDescriptor::log(const char* indent)
    248 {
    249     ALOGI("%sID: %d,0x%X, [rt:%d fmt:0x%X ch:0x%X]",
    250           indent, mId, mId, mSamplingRate, mFormat, mChannelMask);
    251 }
    252 
    253 // SwAudioOutputDescriptor implementation
    254 SwAudioOutputDescriptor::SwAudioOutputDescriptor(const sp<IOProfile>& profile,
    255                                                  AudioPolicyClientInterface *clientInterface)
    256     : AudioOutputDescriptor(profile, clientInterface),
    257     mProfile(profile), mIoHandle(AUDIO_IO_HANDLE_NONE), mLatency(0),
    258     mFlags((audio_output_flags_t)0),
    259     mOutput1(0), mOutput2(0), mDirectOpenCount(0),
    260     mDirectClientSession(AUDIO_SESSION_NONE)
    261 {
    262     if (profile != NULL) {
    263         mFlags = (audio_output_flags_t)profile->getFlags();
    264     }
    265 }
    266 
    267 void SwAudioOutputDescriptor::dump(String8 *dst) const
    268 {
    269     dst->appendFormat(" Latency: %d\n", mLatency);
    270     dst->appendFormat(" Flags %08x\n", mFlags);
    271     AudioOutputDescriptor::dump(dst);
    272 }
    273 
    274 DeviceVector SwAudioOutputDescriptor::devices() const
    275 {
    276     if (isDuplicated()) {
    277         DeviceVector devices = mOutput1->devices();
    278         devices.merge(mOutput2->devices());
    279         return devices;
    280     }
    281     return mDevices;
    282 }
    283 
    284 bool SwAudioOutputDescriptor::sharesHwModuleWith(
    285         const sp<SwAudioOutputDescriptor>& outputDesc)
    286 {
    287     if (isDuplicated()) {
    288         return mOutput1->sharesHwModuleWith(outputDesc) || mOutput2->sharesHwModuleWith(outputDesc);
    289     } else if (outputDesc->isDuplicated()){
    290         return sharesHwModuleWith(outputDesc->subOutput1()) ||
    291                     sharesHwModuleWith(outputDesc->subOutput2());
    292     } else {
    293         return AudioOutputDescriptor::sharesHwModuleWith(outputDesc);
    294     }
    295 }
    296 
    297 DeviceVector SwAudioOutputDescriptor::supportedDevices() const
    298 {
    299     if (isDuplicated()) {
    300         DeviceVector supportedDevices = mOutput1->supportedDevices();
    301         supportedDevices.merge(mOutput2->supportedDevices());
    302         return supportedDevices;
    303     }
    304     return mProfile->getSupportedDevices();
    305 }
    306 
    307 bool SwAudioOutputDescriptor::supportsDevice(const sp<DeviceDescriptor> &device) const
    308 {
    309     return supportedDevices().contains(device);
    310 }
    311 
    312 bool SwAudioOutputDescriptor::supportsAllDevices(const DeviceVector &devices) const
    313 {
    314     return supportedDevices().containsAllDevices(devices);
    315 }
    316 
    317 DeviceVector SwAudioOutputDescriptor::filterSupportedDevices(const DeviceVector &devices) const
    318 {
    319     DeviceVector filteredDevices = supportedDevices();
    320     return filteredDevices.filter(devices);
    321 }
    322 
    323 bool SwAudioOutputDescriptor::deviceSupportsEncodedFormats(audio_devices_t device)
    324 {
    325     if (isDuplicated()) {
    326         return (mOutput1->deviceSupportsEncodedFormats(device)
    327                     || mOutput2->deviceSupportsEncodedFormats(device));
    328     } else {
    329        return mProfile->deviceSupportsEncodedFormats(device);
    330     }
    331 }
    332 
    333 uint32_t SwAudioOutputDescriptor::latency()
    334 {
    335     if (isDuplicated()) {
    336         return (mOutput1->mLatency > mOutput2->mLatency) ? mOutput1->mLatency : mOutput2->mLatency;
    337     } else {
    338         return mLatency;
    339     }
    340 }
    341 
    342 void SwAudioOutputDescriptor::setClientActive(const sp<TrackClientDescriptor>& client, bool active)
    343 {
    344     // forward usage count change to attached outputs
    345     if (isDuplicated()) {
    346         mOutput1->setClientActive(client, active);
    347         mOutput2->setClientActive(client, active);
    348     }
    349     AudioOutputDescriptor::setClientActive(client, active);
    350 }
    351 
    352 bool SwAudioOutputDescriptor::isFixedVolume(audio_devices_t device)
    353 {
    354     // unit gain if rerouting to external policy
    355     if (device == AUDIO_DEVICE_OUT_REMOTE_SUBMIX) {
    356         if (mPolicyMix != NULL) {
    357             ALOGV("max gain when rerouting for output=%d", mIoHandle);
    358             return true;
    359         }
    360     }
    361     if (device == AUDIO_DEVICE_OUT_TELEPHONY_TX) {
    362         ALOGV("max gain when output device is telephony tx");
    363         return true;
    364     }
    365     return false;
    366 }
    367 
    368 void SwAudioOutputDescriptor::toAudioPortConfig(
    369                                                  struct audio_port_config *dstConfig,
    370                                                  const struct audio_port_config *srcConfig) const
    371 {
    372 
    373     ALOG_ASSERT(!isDuplicated(), "toAudioPortConfig() called on duplicated output %d", mIoHandle);
    374     AudioOutputDescriptor::toAudioPortConfig(dstConfig, srcConfig);
    375 
    376     dstConfig->ext.mix.handle = mIoHandle;
    377 }
    378 
    379 void SwAudioOutputDescriptor::toAudioPort(
    380                                                     struct audio_port *port) const
    381 {
    382     ALOG_ASSERT(!isDuplicated(), "toAudioPort() called on duplicated output %d", mIoHandle);
    383 
    384     AudioOutputDescriptor::toAudioPort(port);
    385 
    386     toAudioPortConfig(&port->active_config);
    387     port->ext.mix.handle = mIoHandle;
    388     port->ext.mix.latency_class =
    389             mFlags & AUDIO_OUTPUT_FLAG_FAST ? AUDIO_LATENCY_LOW : AUDIO_LATENCY_NORMAL;
    390 }
    391 
    392 bool SwAudioOutputDescriptor::setVolume(float volumeDb,
    393                                         VolumeSource vs, const StreamTypeVector &streamTypes,
    394                                         audio_devices_t device,
    395                                         uint32_t delayMs,
    396                                         bool force)
    397 {
    398     StreamTypeVector streams = streamTypes;
    399     if (!AudioOutputDescriptor::setVolume(volumeDb, vs, streamTypes, device, delayMs, force)) {
    400         return false;
    401     }
    402     if (streams.empty()) {
    403         streams.push_back(AUDIO_STREAM_MUSIC);
    404     }
    405     for (const auto& devicePort : devices()) {
    406         // APM loops on all group, so filter on active group to set the port gain,
    407         // let the other groups set the stream volume as per legacy
    408         // TODO: Pass in the device address and check against it.
    409         if (device == devicePort->type() &&
    410                 devicePort->hasGainController(true) && isActive(vs)) {
    411             ALOGV("%s: device %s has gain controller", __func__, devicePort->toString().c_str());
    412             // @todo: here we might be in trouble if the SwOutput has several active clients with
    413             // different Volume Source (or if we allow several curves within same volume group)
    414             //
    415             // @todo: default stream volume to max (0) when using HW Port gain?
    416             float volumeAmpl = Volume::DbToAmpl(0);
    417             for (const auto &stream : streams) {
    418                 mClientInterface->setStreamVolume(stream, volumeAmpl, mIoHandle, delayMs);
    419             }
    420 
    421             AudioGains gains = devicePort->getGains();
    422             int gainMinValueInMb = gains[0]->getMinValueInMb();
    423             int gainMaxValueInMb = gains[0]->getMaxValueInMb();
    424             int gainStepValueInMb = gains[0]->getStepValueInMb();
    425             int gainValueMb = ((volumeDb * 100)/ gainStepValueInMb) * gainStepValueInMb;
    426             gainValueMb = std::max(gainMinValueInMb, std::min(gainValueMb, gainMaxValueInMb));
    427 
    428             audio_port_config config = {};
    429             devicePort->toAudioPortConfig(&config);
    430             config.config_mask = AUDIO_PORT_CONFIG_GAIN;
    431             config.gain.values[0] = gainValueMb;
    432             return mClientInterface->setAudioPortConfig(&config, 0) == NO_ERROR;
    433         }
    434     }
    435     // Force VOICE_CALL to track BLUETOOTH_SCO stream volume when bluetooth audio is enabled
    436     float volumeAmpl = Volume::DbToAmpl(getCurVolume(vs));
    437     if (hasStream(streams, AUDIO_STREAM_BLUETOOTH_SCO)) {
    438         mClientInterface->setStreamVolume(AUDIO_STREAM_VOICE_CALL, volumeAmpl, mIoHandle, delayMs);
    439     }
    440     for (const auto &stream : streams) {
    441         ALOGV("%s output %d for volumeSource %d, volume %f, delay %d stream=%s", __func__,
    442               mIoHandle, vs, volumeDb, delayMs, toString(stream).c_str());
    443         mClientInterface->setStreamVolume(stream, volumeAmpl, mIoHandle, delayMs);
    444     }
    445     return true;
    446 }
    447 
    448 status_t SwAudioOutputDescriptor::open(const audio_config_t *config,
    449                                        const DeviceVector &devices,
    450                                        audio_stream_type_t stream,
    451                                        audio_output_flags_t flags,
    452                                        audio_io_handle_t *output)
    453 {
    454     mDevices = devices;
    455     const String8& address = devices.getFirstValidAddress();
    456     audio_devices_t device = devices.types();
    457 
    458     audio_config_t lConfig;
    459     if (config == nullptr) {
    460         lConfig = AUDIO_CONFIG_INITIALIZER;
    461         lConfig.sample_rate = mSamplingRate;
    462         lConfig.channel_mask = mChannelMask;
    463         lConfig.format = mFormat;
    464     } else {
    465         lConfig = *config;
    466     }
    467 
    468     // if the selected profile is offloaded and no offload info was specified,
    469     // create a default one
    470     if ((mProfile->getFlags() & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) &&
    471             lConfig.offload_info.format == AUDIO_FORMAT_DEFAULT) {
    472         flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD);
    473         lConfig.offload_info = AUDIO_INFO_INITIALIZER;
    474         lConfig.offload_info.sample_rate = lConfig.sample_rate;
    475         lConfig.offload_info.channel_mask = lConfig.channel_mask;
    476         lConfig.offload_info.format = lConfig.format;
    477         lConfig.offload_info.stream_type = stream;
    478         lConfig.offload_info.duration_us = -1;
    479         lConfig.offload_info.has_video = true; // conservative
    480         lConfig.offload_info.is_streaming = true; // likely
    481     }
    482 
    483     mFlags = (audio_output_flags_t)(mFlags | flags);
    484 
    485     ALOGV("opening output for device %s profile %p name %s",
    486           mDevices.toString().c_str(), mProfile.get(), mProfile->getName().string());
    487 
    488     status_t status = mClientInterface->openOutput(mProfile->getModuleHandle(),
    489                                                    output,
    490                                                    &lConfig,
    491                                                    &device,
    492                                                    address,
    493                                                    &mLatency,
    494                                                    mFlags);
    495     LOG_ALWAYS_FATAL_IF(mDevices.types() != device,
    496                         "%s openOutput returned device %08x when given device %08x",
    497                         __FUNCTION__, mDevices.types(), device);
    498 
    499     if (status == NO_ERROR) {
    500         LOG_ALWAYS_FATAL_IF(*output == AUDIO_IO_HANDLE_NONE,
    501                             "%s openOutput returned output handle %d for device %08x",
    502                             __FUNCTION__, *output, device);
    503         mSamplingRate = lConfig.sample_rate;
    504         mChannelMask = lConfig.channel_mask;
    505         mFormat = lConfig.format;
    506         mId = AudioPort::getNextUniqueId();
    507         mIoHandle = *output;
    508         mProfile->curOpenCount++;
    509     }
    510 
    511     return status;
    512 }
    513 
    514 status_t SwAudioOutputDescriptor::start()
    515 {
    516     if (isDuplicated()) {
    517         status_t status = mOutput1->start();
    518         if (status != NO_ERROR) {
    519             return status;
    520         }
    521         status = mOutput2->start();
    522         if (status != NO_ERROR) {
    523             mOutput1->stop();
    524             return status;
    525         }
    526         return NO_ERROR;
    527     }
    528     if (!isActive()) {
    529         if (!mProfile->canStartNewIo()) {
    530             return INVALID_OPERATION;
    531         }
    532         mProfile->curActiveCount++;
    533     }
    534     return NO_ERROR;
    535 }
    536 
    537 void SwAudioOutputDescriptor::stop()
    538 {
    539     if (isDuplicated()) {
    540         mOutput1->stop();
    541         mOutput2->stop();
    542         return;
    543     }
    544 
    545     if (!isActive()) {
    546         LOG_ALWAYS_FATAL_IF(mProfile->curActiveCount < 1,
    547                             "%s invalid profile active count %u",
    548                             __func__, mProfile->curActiveCount);
    549         mProfile->curActiveCount--;
    550     }
    551 }
    552 
    553 void SwAudioOutputDescriptor::close()
    554 {
    555     if (mIoHandle != AUDIO_IO_HANDLE_NONE) {
    556         // clean up active clients if any (can happen if close() is called to force
    557         // clients to reconnect
    558         for (const auto &client : getClientIterable()) {
    559             if (client->active()) {
    560                 ALOGW("%s client with port ID %d still active on output %d",
    561                       __func__, client->portId(), mId);
    562                 setClientActive(client, false);
    563                 stop();
    564             }
    565         }
    566 
    567         AudioParameter param;
    568         param.add(String8("closing"), String8("true"));
    569         mClientInterface->setParameters(mIoHandle, param.toString());
    570 
    571         mClientInterface->closeOutput(mIoHandle);
    572 
    573         LOG_ALWAYS_FATAL_IF(mProfile->curOpenCount < 1, "%s profile open count %u",
    574                             __FUNCTION__, mProfile->curOpenCount);
    575         mProfile->curOpenCount--;
    576         mIoHandle = AUDIO_IO_HANDLE_NONE;
    577     }
    578 }
    579 
    580 status_t SwAudioOutputDescriptor::openDuplicating(const sp<SwAudioOutputDescriptor>& output1,
    581                                                   const sp<SwAudioOutputDescriptor>& output2,
    582                                                   audio_io_handle_t *ioHandle)
    583 {
    584     // open a duplicating output thread for the new output and the primary output
    585     // Note: openDuplicateOutput() API expects the output handles in the reverse order from the
    586     // numbering in SwAudioOutputDescriptor mOutput1 and mOutput2
    587     *ioHandle = mClientInterface->openDuplicateOutput(output2->mIoHandle, output1->mIoHandle);
    588     if (*ioHandle == AUDIO_IO_HANDLE_NONE) {
    589         return INVALID_OPERATION;
    590     }
    591 
    592     mId = AudioPort::getNextUniqueId();
    593     mIoHandle = *ioHandle;
    594     mOutput1 = output1;
    595     mOutput2 = output2;
    596     mSamplingRate = output2->mSamplingRate;
    597     mFormat = output2->mFormat;
    598     mChannelMask = output2->mChannelMask;
    599     mLatency = output2->mLatency;
    600 
    601     return NO_ERROR;
    602 }
    603 
    604 // HwAudioOutputDescriptor implementation
    605 HwAudioOutputDescriptor::HwAudioOutputDescriptor(const sp<SourceClientDescriptor>& source,
    606                                                  AudioPolicyClientInterface *clientInterface)
    607     : AudioOutputDescriptor(source->srcDevice(), clientInterface),
    608       mSource(source)
    609 {
    610 }
    611 
    612 void HwAudioOutputDescriptor::dump(String8 *dst) const
    613 {
    614     AudioOutputDescriptor::dump(dst);
    615     dst->append("Source:\n");
    616     mSource->dump(dst, 0, 0);
    617 }
    618 
    619 void HwAudioOutputDescriptor::toAudioPortConfig(
    620                                                  struct audio_port_config *dstConfig,
    621                                                  const struct audio_port_config *srcConfig) const
    622 {
    623     mSource->srcDevice()->toAudioPortConfig(dstConfig, srcConfig);
    624 }
    625 
    626 void HwAudioOutputDescriptor::toAudioPort(
    627                                                     struct audio_port *port) const
    628 {
    629     mSource->srcDevice()->toAudioPort(port);
    630 }
    631 
    632 
    633 bool HwAudioOutputDescriptor::setVolume(float volumeDb,
    634                                         VolumeSource volumeSource, const StreamTypeVector &streams,
    635                                         audio_devices_t device,
    636                                         uint32_t delayMs,
    637                                         bool force)
    638 {
    639     bool changed =
    640         AudioOutputDescriptor::setVolume(volumeDb, volumeSource, streams, device, delayMs, force);
    641 
    642     if (changed) {
    643       // TODO: use gain controller on source device if any to adjust volume
    644     }
    645     return changed;
    646 }
    647 
    648 // SwAudioOutputCollection implementation
    649 bool SwAudioOutputCollection::isActive(VolumeSource volumeSource, uint32_t inPastMs) const
    650 {
    651     nsecs_t sysTime = systemTime();
    652     for (size_t i = 0; i < this->size(); i++) {
    653         const sp<SwAudioOutputDescriptor> outputDesc = this->valueAt(i);
    654         if (outputDesc->isActive(volumeSource, inPastMs, sysTime)) {
    655             return true;
    656         }
    657     }
    658     return false;
    659 }
    660 
    661 bool SwAudioOutputCollection::isActiveLocally(VolumeSource volumeSource, uint32_t inPastMs) const
    662 {
    663     nsecs_t sysTime = systemTime();
    664     for (size_t i = 0; i < this->size(); i++) {
    665         const sp<SwAudioOutputDescriptor> outputDesc = this->valueAt(i);
    666         if (outputDesc->isActive(volumeSource, inPastMs, sysTime)
    667                 && ((outputDesc->devices().types() & APM_AUDIO_OUT_DEVICE_REMOTE_ALL) == 0)) {
    668             return true;
    669         }
    670     }
    671     return false;
    672 }
    673 
    674 bool SwAudioOutputCollection::isActiveRemotely(VolumeSource volumeSource, uint32_t inPastMs) const
    675 {
    676     nsecs_t sysTime = systemTime();
    677     for (size_t i = 0; i < size(); i++) {
    678         const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
    679         if (((outputDesc->devices().types() & APM_AUDIO_OUT_DEVICE_REMOTE_ALL) != 0) &&
    680                 outputDesc->isActive(volumeSource, inPastMs, sysTime)) {
    681             // do not consider re routing (when the output is going to a dynamic policy)
    682             // as "remote playback"
    683             if (outputDesc->mPolicyMix == NULL) {
    684                 return true;
    685             }
    686         }
    687     }
    688     return false;
    689 }
    690 
    691 bool SwAudioOutputCollection::isStrategyActiveOnSameModule(product_strategy_t ps,
    692                                                            const sp<SwAudioOutputDescriptor>& desc,
    693                                                            uint32_t inPastMs, nsecs_t sysTime) const
    694 {
    695     for (size_t i = 0; i < size(); i++) {
    696         const sp<SwAudioOutputDescriptor> otherDesc = valueAt(i);
    697         if (desc->sharesHwModuleWith(otherDesc) &&
    698                 otherDesc->isStrategyActive(ps, inPastMs, sysTime)) {
    699             return true;
    700         }
    701     }
    702     return false;
    703 }
    704 
    705 audio_io_handle_t SwAudioOutputCollection::getA2dpOutput() const
    706 {
    707     for (size_t i = 0; i < size(); i++) {
    708         sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
    709         if (!outputDesc->isDuplicated() &&
    710              outputDesc->devices().types()  & AUDIO_DEVICE_OUT_ALL_A2DP &&
    711              outputDesc->deviceSupportsEncodedFormats(
    712                      AUDIO_DEVICE_OUT_BLUETOOTH_A2DP)) {
    713             return this->keyAt(i);
    714         }
    715     }
    716     return 0;
    717 }
    718 
    719 bool SwAudioOutputCollection::isA2dpOffloadedOnPrimary() const
    720 {
    721     sp<SwAudioOutputDescriptor> primaryOutput = getPrimaryOutput();
    722 
    723     if ((primaryOutput != NULL) && (primaryOutput->mProfile != NULL)
    724         && (primaryOutput->mProfile->getModule() != NULL)) {
    725         sp<HwModule> primaryHwModule = primaryOutput->mProfile->getModule();
    726 
    727         for (const auto &outputProfile : primaryHwModule->getOutputProfiles()) {
    728             if (outputProfile->supportsDeviceTypes(AUDIO_DEVICE_OUT_ALL_A2DP)) {
    729                 return true;
    730             }
    731         }
    732     }
    733     return false;
    734 }
    735 
    736 bool SwAudioOutputCollection::isA2dpSupported() const
    737 {
    738     return (isA2dpOffloadedOnPrimary() || (getA2dpOutput() != 0));
    739 }
    740 
    741 sp<SwAudioOutputDescriptor> SwAudioOutputCollection::getPrimaryOutput() const
    742 {
    743     for (size_t i = 0; i < size(); i++) {
    744         const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
    745         if (outputDesc->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) {
    746             return outputDesc;
    747         }
    748     }
    749     return NULL;
    750 }
    751 
    752 sp<SwAudioOutputDescriptor> SwAudioOutputCollection::getOutputFromId(audio_port_handle_t id) const
    753 {
    754     for (size_t i = 0; i < size(); i++) {
    755         const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
    756         if (outputDesc->getId() == id) {
    757             return outputDesc;
    758         }
    759     }
    760     return NULL;
    761 }
    762 
    763 sp<SwAudioOutputDescriptor> SwAudioOutputCollection::getOutputForClient(audio_port_handle_t portId)
    764 {
    765     for (size_t i = 0; i < size(); i++) {
    766         sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
    767         if (outputDesc->getClient(portId) != nullptr) {
    768             return outputDesc;
    769         }
    770     }
    771     return 0;
    772 }
    773 
    774 void SwAudioOutputCollection::clearSessionRoutesForDevice(
    775         const sp<DeviceDescriptor> &disconnectedDevice)
    776 {
    777     for (size_t i = 0; i < size(); i++) {
    778         sp<AudioOutputDescriptor> outputDesc = valueAt(i);
    779         for (const auto& client : outputDesc->getClientIterable()) {
    780             if (client->preferredDeviceId() == disconnectedDevice->getId()) {
    781                 client->setPreferredDeviceId(AUDIO_PORT_HANDLE_NONE);
    782             }
    783         }
    784     }
    785 }
    786 
    787 void SwAudioOutputCollection::dump(String8 *dst) const
    788 {
    789     dst->append("\nOutputs dump:\n");
    790     for (size_t i = 0; i < size(); i++) {
    791         dst->appendFormat("- Output %d dump:\n", keyAt(i));
    792         valueAt(i)->dump(dst);
    793     }
    794 }
    795 
    796 // HwAudioOutputCollection implementation
    797 bool HwAudioOutputCollection::isActive(VolumeSource volumeSource, uint32_t inPastMs) const
    798 {
    799     nsecs_t sysTime = systemTime();
    800     for (size_t i = 0; i < this->size(); i++) {
    801         const sp<HwAudioOutputDescriptor> outputDesc = this->valueAt(i);
    802         if (outputDesc->isActive(volumeSource, inPastMs, sysTime)) {
    803             return true;
    804         }
    805     }
    806     return false;
    807 }
    808 
    809 void HwAudioOutputCollection::dump(String8 *dst) const
    810 {
    811     dst->append("\nOutputs dump:\n");
    812     for (size_t i = 0; i < size(); i++) {
    813         dst->appendFormat("- Output %d dump:\n", keyAt(i));
    814         valueAt(i)->dump(dst);
    815     }
    816 }
    817 
    818 }; //namespace android
    819