Home | History | Annotate | Download | only in audioflinger
      1 /*
      2 **
      3 ** Copyright 2014, The Android Open Source Project
      4 **
      5 ** Licensed under the Apache License, Version 2.0 (the "License");
      6 ** you may not use this file except in compliance with the License.
      7 ** You may obtain a copy of the License at
      8 **
      9 **     http://www.apache.org/licenses/LICENSE-2.0
     10 **
     11 ** Unless required by applicable law or agreed to in writing, software
     12 ** distributed under the License is distributed on an "AS IS" BASIS,
     13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14 ** See the License for the specific language governing permissions and
     15 ** limitations under the License.
     16 */
     17 
     18 
     19 #define LOG_TAG "AudioFlinger::PatchPanel"
     20 //#define LOG_NDEBUG 0
     21 
     22 #include "Configuration.h"
     23 #include <utils/Log.h>
     24 #include <audio_utils/primitives.h>
     25 
     26 #include "AudioFlinger.h"
     27 #include <media/AudioParameter.h>
     28 #include <media/PatchBuilder.h>
     29 #include <mediautils/ServiceUtilities.h>
     30 
     31 // ----------------------------------------------------------------------------
     32 
     33 // Note: the following macro is used for extremely verbose logging message.  In
     34 // order to run with ALOG_ASSERT turned on, we need to have LOG_NDEBUG set to
     35 // 0; but one side effect of this is to turn all LOGV's as well.  Some messages
     36 // are so verbose that we want to suppress them even when we have ALOG_ASSERT
     37 // turned on.  Do not uncomment the #def below unless you really know what you
     38 // are doing and want to see all of the extremely verbose messages.
     39 //#define VERY_VERY_VERBOSE_LOGGING
     40 #ifdef VERY_VERY_VERBOSE_LOGGING
     41 #define ALOGVV ALOGV
     42 #else
     43 #define ALOGVV(a...) do { } while(0)
     44 #endif
     45 
     46 namespace android {
     47 
     48 /* List connected audio ports and their attributes */
     49 status_t AudioFlinger::listAudioPorts(unsigned int *num_ports,
     50                                 struct audio_port *ports)
     51 {
     52     Mutex::Autolock _l(mLock);
     53     return mPatchPanel.listAudioPorts(num_ports, ports);
     54 }
     55 
     56 /* Get supported attributes for a given audio port */
     57 status_t AudioFlinger::getAudioPort(struct audio_port *port)
     58 {
     59     Mutex::Autolock _l(mLock);
     60     return mPatchPanel.getAudioPort(port);
     61 }
     62 
     63 /* Connect a patch between several source and sink ports */
     64 status_t AudioFlinger::createAudioPatch(const struct audio_patch *patch,
     65                                    audio_patch_handle_t *handle)
     66 {
     67     Mutex::Autolock _l(mLock);
     68     return mPatchPanel.createAudioPatch(patch, handle);
     69 }
     70 
     71 /* Disconnect a patch */
     72 status_t AudioFlinger::releaseAudioPatch(audio_patch_handle_t handle)
     73 {
     74     Mutex::Autolock _l(mLock);
     75     return mPatchPanel.releaseAudioPatch(handle);
     76 }
     77 
     78 /* List connected audio ports and they attributes */
     79 status_t AudioFlinger::listAudioPatches(unsigned int *num_patches,
     80                                   struct audio_patch *patches)
     81 {
     82     Mutex::Autolock _l(mLock);
     83     return mPatchPanel.listAudioPatches(num_patches, patches);
     84 }
     85 
     86 status_t AudioFlinger::PatchPanel::SoftwarePatch::getLatencyMs_l(double *latencyMs) const
     87 {
     88     const auto& iter = mPatchPanel.mPatches.find(mPatchHandle);
     89     if (iter != mPatchPanel.mPatches.end()) {
     90         return iter->second.getLatencyMs(latencyMs);
     91     } else {
     92         return BAD_VALUE;
     93     }
     94 }
     95 
     96 /* List connected audio ports and their attributes */
     97 status_t AudioFlinger::PatchPanel::listAudioPorts(unsigned int *num_ports __unused,
     98                                 struct audio_port *ports __unused)
     99 {
    100     ALOGV(__func__);
    101     return NO_ERROR;
    102 }
    103 
    104 /* Get supported attributes for a given audio port */
    105 status_t AudioFlinger::PatchPanel::getAudioPort(struct audio_port *port __unused)
    106 {
    107     ALOGV(__func__);
    108     return NO_ERROR;
    109 }
    110 
    111 /* Connect a patch between several source and sink ports */
    112 status_t AudioFlinger::PatchPanel::createAudioPatch(const struct audio_patch *patch,
    113                                    audio_patch_handle_t *handle)
    114 {
    115     if (handle == NULL || patch == NULL) {
    116         return BAD_VALUE;
    117     }
    118     ALOGV("%s() num_sources %d num_sinks %d handle %d",
    119             __func__, patch->num_sources, patch->num_sinks, *handle);
    120     status_t status = NO_ERROR;
    121     audio_patch_handle_t halHandle = AUDIO_PATCH_HANDLE_NONE;
    122 
    123     if (!audio_patch_is_valid(patch) || (patch->num_sinks == 0 && patch->num_sources != 2)) {
    124         return BAD_VALUE;
    125     }
    126     // limit number of sources to 1 for now or 2 sources for special cross hw module case.
    127     // only the audio policy manager can request a patch creation with 2 sources.
    128     if (patch->num_sources > 2) {
    129         return INVALID_OPERATION;
    130     }
    131 
    132     if (*handle != AUDIO_PATCH_HANDLE_NONE) {
    133         auto iter = mPatches.find(*handle);
    134         if (iter != mPatches.end()) {
    135             ALOGV("%s() removing patch handle %d", __func__, *handle);
    136             Patch &removedPatch = iter->second;
    137             // free resources owned by the removed patch if applicable
    138             // 1) if a software patch is present, release the playback and capture threads and
    139             // tracks created. This will also release the corresponding audio HAL patches
    140             if (removedPatch.isSoftware()) {
    141                 removedPatch.clearConnections(this);
    142             }
    143             // 2) if the new patch and old patch source or sink are devices from different
    144             // hw modules,  clear the audio HAL patches now because they will not be updated
    145             // by call to create_audio_patch() below which will happen on a different HW module
    146             if (removedPatch.mHalHandle != AUDIO_PATCH_HANDLE_NONE) {
    147                 audio_module_handle_t hwModule = AUDIO_MODULE_HANDLE_NONE;
    148                 const struct audio_patch &oldPatch = removedPatch.mAudioPatch;
    149                 if (oldPatch.sources[0].type == AUDIO_PORT_TYPE_DEVICE &&
    150                         (patch->sources[0].type != AUDIO_PORT_TYPE_DEVICE ||
    151                                 oldPatch.sources[0].ext.device.hw_module !=
    152                                 patch->sources[0].ext.device.hw_module)) {
    153                     hwModule = oldPatch.sources[0].ext.device.hw_module;
    154                 } else if (patch->num_sinks == 0 ||
    155                         (oldPatch.sinks[0].type == AUDIO_PORT_TYPE_DEVICE &&
    156                                 (patch->sinks[0].type != AUDIO_PORT_TYPE_DEVICE ||
    157                                         oldPatch.sinks[0].ext.device.hw_module !=
    158                                         patch->sinks[0].ext.device.hw_module))) {
    159                     // Note on (patch->num_sinks == 0): this situation should not happen as
    160                     // these special patches are only created by the policy manager but just
    161                     // in case, systematically clear the HAL patch.
    162                     // Note that removedPatch.mAudioPatch.num_sinks cannot be 0 here because
    163                     // removedPatch.mHalHandle would be AUDIO_PATCH_HANDLE_NONE in this case.
    164                     hwModule = oldPatch.sinks[0].ext.device.hw_module;
    165                 }
    166                 sp<DeviceHalInterface> hwDevice = findHwDeviceByModule(hwModule);
    167                 if (hwDevice != 0) {
    168                     hwDevice->releaseAudioPatch(removedPatch.mHalHandle);
    169                 }
    170             }
    171             mPatches.erase(iter);
    172             removeSoftwarePatchFromInsertedModules(*handle);
    173         }
    174     }
    175 
    176     Patch newPatch{*patch};
    177     audio_module_handle_t insertedModule = AUDIO_MODULE_HANDLE_NONE;
    178 
    179     switch (patch->sources[0].type) {
    180         case AUDIO_PORT_TYPE_DEVICE: {
    181             audio_module_handle_t srcModule = patch->sources[0].ext.device.hw_module;
    182             AudioHwDevice *audioHwDevice = findAudioHwDeviceByModule(srcModule);
    183             if (!audioHwDevice) {
    184                 status = BAD_VALUE;
    185                 goto exit;
    186             }
    187             for (unsigned int i = 0; i < patch->num_sinks; i++) {
    188                 // support only one sink if connection to a mix or across HW modules
    189                 if ((patch->sinks[i].type == AUDIO_PORT_TYPE_MIX ||
    190                                 (patch->sinks[i].type == AUDIO_PORT_TYPE_DEVICE &&
    191                                         patch->sinks[i].ext.device.hw_module != srcModule)) &&
    192                         patch->num_sinks > 1) {
    193                     ALOGW("%s() multiple sinks for mix or across modules not supported", __func__);
    194                     status = INVALID_OPERATION;
    195                     goto exit;
    196                 }
    197                 // reject connection to different sink types
    198                 if (patch->sinks[i].type != patch->sinks[0].type) {
    199                     ALOGW("%s() different sink types in same patch not supported", __func__);
    200                     status = BAD_VALUE;
    201                     goto exit;
    202                 }
    203             }
    204 
    205             // manage patches requiring a software bridge
    206             // - special patch request with 2 sources (reuse one existing output mix) OR
    207             // - Device to device AND
    208             //    - source HW module != destination HW module OR
    209             //    - audio HAL does not support audio patches creation
    210             if ((patch->num_sources == 2) ||
    211                 ((patch->sinks[0].type == AUDIO_PORT_TYPE_DEVICE) &&
    212                  ((patch->sinks[0].ext.device.hw_module != srcModule) ||
    213                   !audioHwDevice->supportsAudioPatches()))) {
    214                 audio_devices_t outputDevice = patch->sinks[0].ext.device.type;
    215                 String8 outputDeviceAddress = String8(patch->sinks[0].ext.device.address);
    216                 if (patch->num_sources == 2) {
    217                     if (patch->sources[1].type != AUDIO_PORT_TYPE_MIX ||
    218                             (patch->num_sinks != 0 && patch->sinks[0].ext.device.hw_module !=
    219                                     patch->sources[1].ext.mix.hw_module)) {
    220                         ALOGW("%s() invalid source combination", __func__);
    221                         status = INVALID_OPERATION;
    222                         goto exit;
    223                     }
    224 
    225                     sp<ThreadBase> thread =
    226                             mAudioFlinger.checkPlaybackThread_l(patch->sources[1].ext.mix.handle);
    227                     if (thread == 0) {
    228                         ALOGW("%s() cannot get playback thread", __func__);
    229                         status = INVALID_OPERATION;
    230                         goto exit;
    231                     }
    232                     // existing playback thread is reused, so it is not closed when patch is cleared
    233                     newPatch.mPlayback.setThread(
    234                             reinterpret_cast<PlaybackThread*>(thread.get()), false /*closeThread*/);
    235                 } else {
    236                     audio_config_t config = AUDIO_CONFIG_INITIALIZER;
    237                     audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
    238                     audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE;
    239                     if (patch->sinks[0].config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE) {
    240                         config.sample_rate = patch->sinks[0].sample_rate;
    241                     }
    242                     if (patch->sinks[0].config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK) {
    243                         config.channel_mask = patch->sinks[0].channel_mask;
    244                     }
    245                     if (patch->sinks[0].config_mask & AUDIO_PORT_CONFIG_FORMAT) {
    246                         config.format = patch->sinks[0].format;
    247                     }
    248                     if (patch->sinks[0].config_mask & AUDIO_PORT_CONFIG_FLAGS) {
    249                         flags = patch->sinks[0].flags.output;
    250                     }
    251                     sp<ThreadBase> thread = mAudioFlinger.openOutput_l(
    252                                                             patch->sinks[0].ext.device.hw_module,
    253                                                             &output,
    254                                                             &config,
    255                                                             outputDevice,
    256                                                             outputDeviceAddress,
    257                                                             flags);
    258                     ALOGV("mAudioFlinger.openOutput_l() returned %p", thread.get());
    259                     if (thread == 0) {
    260                         status = NO_MEMORY;
    261                         goto exit;
    262                     }
    263                     newPatch.mPlayback.setThread(reinterpret_cast<PlaybackThread*>(thread.get()));
    264                 }
    265                 audio_devices_t device = patch->sources[0].ext.device.type;
    266                 String8 address = String8(patch->sources[0].ext.device.address);
    267                 audio_config_t config = AUDIO_CONFIG_INITIALIZER;
    268                 // open input stream with source device audio properties if provided or
    269                 // default to peer output stream properties otherwise.
    270                 if (patch->sources[0].config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE) {
    271                     config.sample_rate = patch->sources[0].sample_rate;
    272                 } else {
    273                     config.sample_rate = newPatch.mPlayback.thread()->sampleRate();
    274                 }
    275                 if (patch->sources[0].config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK) {
    276                     config.channel_mask = patch->sources[0].channel_mask;
    277                 } else {
    278                     config.channel_mask = audio_channel_in_mask_from_count(
    279                             newPatch.mPlayback.thread()->channelCount());
    280                 }
    281                 if (patch->sources[0].config_mask & AUDIO_PORT_CONFIG_FORMAT) {
    282                     config.format = patch->sources[0].format;
    283                 } else {
    284                     config.format = newPatch.mPlayback.thread()->format();
    285                 }
    286                 audio_input_flags_t flags =
    287                         patch->sources[0].config_mask & AUDIO_PORT_CONFIG_FLAGS ?
    288                         patch->sources[0].flags.input : AUDIO_INPUT_FLAG_NONE;
    289                 audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
    290                 sp<ThreadBase> thread = mAudioFlinger.openInput_l(srcModule,
    291                                                                     &input,
    292                                                                     &config,
    293                                                                     device,
    294                                                                     address,
    295                                                                     AUDIO_SOURCE_MIC,
    296                                                                     flags,
    297                                                                     outputDevice,
    298                                                                     outputDeviceAddress);
    299                 ALOGV("mAudioFlinger.openInput_l() returned %p inChannelMask %08x",
    300                       thread.get(), config.channel_mask);
    301                 if (thread == 0) {
    302                     status = NO_MEMORY;
    303                     goto exit;
    304                 }
    305                 newPatch.mRecord.setThread(reinterpret_cast<RecordThread*>(thread.get()));
    306                 status = newPatch.createConnections(this);
    307                 if (status != NO_ERROR) {
    308                     goto exit;
    309                 }
    310                 if (audioHwDevice->isInsert()) {
    311                     insertedModule = audioHwDevice->handle();
    312                 }
    313             } else {
    314                 if (patch->sinks[0].type == AUDIO_PORT_TYPE_MIX) {
    315                     sp<ThreadBase> thread = mAudioFlinger.checkRecordThread_l(
    316                                                               patch->sinks[0].ext.mix.handle);
    317                     if (thread == 0) {
    318                         thread = mAudioFlinger.checkMmapThread_l(patch->sinks[0].ext.mix.handle);
    319                         if (thread == 0) {
    320                             ALOGW("%s() bad capture I/O handle %d",
    321                                     __func__, patch->sinks[0].ext.mix.handle);
    322                             status = BAD_VALUE;
    323                             goto exit;
    324                         }
    325                     }
    326                     status = thread->sendCreateAudioPatchConfigEvent(patch, &halHandle);
    327                     // remove stale audio patch with same input as sink if any
    328                     for (auto& iter : mPatches) {
    329                         if (iter.second.mAudioPatch.sinks[0].ext.mix.handle == thread->id()) {
    330                             mPatches.erase(iter.first);
    331                             break;
    332                         }
    333                     }
    334                 } else {
    335                     sp<DeviceHalInterface> hwDevice = audioHwDevice->hwDevice();
    336                     status = hwDevice->createAudioPatch(patch->num_sources,
    337                                                         patch->sources,
    338                                                         patch->num_sinks,
    339                                                         patch->sinks,
    340                                                         &halHandle);
    341                     if (status == INVALID_OPERATION) goto exit;
    342                 }
    343             }
    344         } break;
    345         case AUDIO_PORT_TYPE_MIX: {
    346             audio_module_handle_t srcModule =  patch->sources[0].ext.mix.hw_module;
    347             ssize_t index = mAudioFlinger.mAudioHwDevs.indexOfKey(srcModule);
    348             if (index < 0) {
    349                 ALOGW("%s() bad src hw module %d", __func__, srcModule);
    350                 status = BAD_VALUE;
    351                 goto exit;
    352             }
    353             // limit to connections between devices and output streams
    354             audio_devices_t type = AUDIO_DEVICE_NONE;
    355             for (unsigned int i = 0; i < patch->num_sinks; i++) {
    356                 if (patch->sinks[i].type != AUDIO_PORT_TYPE_DEVICE) {
    357                     ALOGW("%s() invalid sink type %d for mix source",
    358                             __func__, patch->sinks[i].type);
    359                     status = BAD_VALUE;
    360                     goto exit;
    361                 }
    362                 // limit to connections between sinks and sources on same HW module
    363                 if (patch->sinks[i].ext.device.hw_module != srcModule) {
    364                     status = BAD_VALUE;
    365                     goto exit;
    366                 }
    367                 type |= patch->sinks[i].ext.device.type;
    368             }
    369             sp<ThreadBase> thread =
    370                             mAudioFlinger.checkPlaybackThread_l(patch->sources[0].ext.mix.handle);
    371             if (thread == 0) {
    372                 thread = mAudioFlinger.checkMmapThread_l(patch->sources[0].ext.mix.handle);
    373                 if (thread == 0) {
    374                     ALOGW("%s() bad playback I/O handle %d",
    375                             __func__, patch->sources[0].ext.mix.handle);
    376                     status = BAD_VALUE;
    377                     goto exit;
    378                 }
    379             }
    380             if (thread == mAudioFlinger.primaryPlaybackThread_l()) {
    381                 AudioParameter param = AudioParameter();
    382                 param.addInt(String8(AudioParameter::keyRouting), (int)type);
    383 
    384                 mAudioFlinger.broacastParametersToRecordThreads_l(param.toString());
    385             }
    386 
    387             status = thread->sendCreateAudioPatchConfigEvent(patch, &halHandle);
    388 
    389             // remove stale audio patch with same output as source if any
    390             for (auto& iter : mPatches) {
    391                 if (iter.second.mAudioPatch.sources[0].ext.mix.handle == thread->id()) {
    392                     mPatches.erase(iter.first);
    393                     break;
    394                 }
    395             }
    396         } break;
    397         default:
    398             status = BAD_VALUE;
    399             goto exit;
    400     }
    401 exit:
    402     ALOGV("%s() status %d", __func__, status);
    403     if (status == NO_ERROR) {
    404         *handle = (audio_patch_handle_t) mAudioFlinger.nextUniqueId(AUDIO_UNIQUE_ID_USE_PATCH);
    405         newPatch.mHalHandle = halHandle;
    406         mPatches.insert(std::make_pair(*handle, std::move(newPatch)));
    407         if (insertedModule != AUDIO_MODULE_HANDLE_NONE) {
    408             addSoftwarePatchToInsertedModules(insertedModule, *handle);
    409         }
    410         ALOGV("%s() added new patch handle %d halHandle %d", __func__, *handle, halHandle);
    411     } else {
    412         newPatch.clearConnections(this);
    413     }
    414     return status;
    415 }
    416 
    417 AudioFlinger::PatchPanel::Patch::~Patch()
    418 {
    419     ALOGE_IF(isSoftware(), "Software patch connections leaked %d %d",
    420             mRecord.handle(), mPlayback.handle());
    421 }
    422 
    423 status_t AudioFlinger::PatchPanel::Patch::createConnections(PatchPanel *panel)
    424 {
    425     // create patch from source device to record thread input
    426     status_t status = panel->createAudioPatch(
    427             PatchBuilder().addSource(mAudioPatch.sources[0]).
    428                 addSink(mRecord.thread(), { .source = AUDIO_SOURCE_MIC }).patch(),
    429             mRecord.handlePtr());
    430     if (status != NO_ERROR) {
    431         *mRecord.handlePtr() = AUDIO_PATCH_HANDLE_NONE;
    432         return status;
    433     }
    434 
    435     // create patch from playback thread output to sink device
    436     if (mAudioPatch.num_sinks != 0) {
    437         status = panel->createAudioPatch(
    438                 PatchBuilder().addSource(mPlayback.thread()).addSink(mAudioPatch.sinks[0]).patch(),
    439                 mPlayback.handlePtr());
    440         if (status != NO_ERROR) {
    441             *mPlayback.handlePtr() = AUDIO_PATCH_HANDLE_NONE;
    442             return status;
    443         }
    444     } else {
    445         *mPlayback.handlePtr() = AUDIO_PATCH_HANDLE_NONE;
    446     }
    447 
    448     // use a pseudo LCM between input and output framecount
    449     size_t playbackFrameCount = mPlayback.thread()->frameCount();
    450     int playbackShift = __builtin_ctz(playbackFrameCount);
    451     size_t recordFrameCount = mRecord.thread()->frameCount();
    452     int shift = __builtin_ctz(recordFrameCount);
    453     if (playbackShift < shift) {
    454         shift = playbackShift;
    455     }
    456     size_t frameCount = (playbackFrameCount * recordFrameCount) >> shift;
    457     ALOGV("%s() playframeCount %zu recordFrameCount %zu frameCount %zu",
    458             __func__, playbackFrameCount, recordFrameCount, frameCount);
    459 
    460     // create a special record track to capture from record thread
    461     uint32_t channelCount = mPlayback.thread()->channelCount();
    462     audio_channel_mask_t inChannelMask = audio_channel_in_mask_from_count(channelCount);
    463     audio_channel_mask_t outChannelMask = mPlayback.thread()->channelMask();
    464     uint32_t sampleRate = mPlayback.thread()->sampleRate();
    465     audio_format_t format = mPlayback.thread()->format();
    466 
    467     audio_format_t inputFormat = mRecord.thread()->format();
    468     if (!audio_is_linear_pcm(inputFormat)) {
    469         // The playbackThread format will say PCM for IEC61937 packetized stream.
    470         // Use recordThread format.
    471         format = inputFormat;
    472     }
    473     audio_input_flags_t inputFlags = mAudioPatch.sources[0].config_mask & AUDIO_PORT_CONFIG_FLAGS ?
    474             mAudioPatch.sources[0].flags.input : AUDIO_INPUT_FLAG_NONE;
    475     if (sampleRate == mRecord.thread()->sampleRate() &&
    476             inChannelMask == mRecord.thread()->channelMask() &&
    477             mRecord.thread()->fastTrackAvailable() &&
    478             mRecord.thread()->hasFastCapture()) {
    479         // Create a fast track if the record thread has fast capture to get better performance.
    480         // Only enable fast mode when there is no resample needed.
    481         inputFlags = (audio_input_flags_t) (inputFlags | AUDIO_INPUT_FLAG_FAST);
    482     } else {
    483         // Fast mode is not available in this case.
    484         inputFlags = (audio_input_flags_t) (inputFlags & ~AUDIO_INPUT_FLAG_FAST);
    485     }
    486     sp<RecordThread::PatchRecord> tempRecordTrack = new (std::nothrow) RecordThread::PatchRecord(
    487                                              mRecord.thread().get(),
    488                                              sampleRate,
    489                                              inChannelMask,
    490                                              format,
    491                                              frameCount,
    492                                              NULL,
    493                                              (size_t)0 /* bufferSize */,
    494                                              inputFlags);
    495     status = mRecord.checkTrack(tempRecordTrack.get());
    496     if (status != NO_ERROR) {
    497         return status;
    498     }
    499 
    500     audio_output_flags_t outputFlags = mAudioPatch.sinks[0].config_mask & AUDIO_PORT_CONFIG_FLAGS ?
    501             mAudioPatch.sinks[0].flags.output : AUDIO_OUTPUT_FLAG_NONE;
    502     audio_stream_type_t streamType = AUDIO_STREAM_PATCH;
    503     if (mAudioPatch.num_sources == 2 && mAudioPatch.sources[1].type == AUDIO_PORT_TYPE_MIX) {
    504         // "reuse one existing output mix" case
    505         streamType = mAudioPatch.sources[1].ext.mix.usecase.stream;
    506     }
    507     if (mPlayback.thread()->hasFastMixer()) {
    508         // Create a fast track if the playback thread has fast mixer to get better performance.
    509         // Note: we should have matching channel mask, sample rate, and format by the logic above.
    510         outputFlags = (audio_output_flags_t) (outputFlags | AUDIO_OUTPUT_FLAG_FAST);
    511     } else {
    512         outputFlags = (audio_output_flags_t) (outputFlags & ~AUDIO_OUTPUT_FLAG_FAST);
    513     }
    514 
    515     // create a special playback track to render to playback thread.
    516     // this track is given the same buffer as the PatchRecord buffer
    517     sp<PlaybackThread::PatchTrack> tempPatchTrack = new (std::nothrow) PlaybackThread::PatchTrack(
    518                                            mPlayback.thread().get(),
    519                                            streamType,
    520                                            sampleRate,
    521                                            outChannelMask,
    522                                            format,
    523                                            frameCount,
    524                                            tempRecordTrack->buffer(),
    525                                            tempRecordTrack->bufferSize(),
    526                                            outputFlags);
    527     status = mPlayback.checkTrack(tempPatchTrack.get());
    528     if (status != NO_ERROR) {
    529         return status;
    530     }
    531 
    532     // tie playback and record tracks together
    533     mRecord.setTrackAndPeer(tempRecordTrack, tempPatchTrack);
    534     mPlayback.setTrackAndPeer(tempPatchTrack, tempRecordTrack);
    535 
    536     // start capture and playback
    537     mRecord.track()->start(AudioSystem::SYNC_EVENT_NONE, AUDIO_SESSION_NONE);
    538     mPlayback.track()->start();
    539 
    540     return status;
    541 }
    542 
    543 void AudioFlinger::PatchPanel::Patch::clearConnections(PatchPanel *panel)
    544 {
    545     ALOGV("%s() mRecord.handle %d mPlayback.handle %d",
    546             __func__, mRecord.handle(), mPlayback.handle());
    547     mRecord.stopTrack();
    548     mPlayback.stopTrack();
    549     mRecord.clearTrackPeer(); // mRecord stop is synchronous. Break PeerProxy sp<> cycle.
    550     mRecord.closeConnections(panel);
    551     mPlayback.closeConnections(panel);
    552 }
    553 
    554 status_t AudioFlinger::PatchPanel::Patch::getLatencyMs(double *latencyMs) const
    555 {
    556     if (!isSoftware()) return INVALID_OPERATION;
    557 
    558     auto recordTrack = mRecord.const_track();
    559     if (recordTrack.get() == nullptr) return INVALID_OPERATION;
    560 
    561     auto playbackTrack = mPlayback.const_track();
    562     if (playbackTrack.get() == nullptr) return INVALID_OPERATION;
    563 
    564     // Latency information for tracks may be called without obtaining
    565     // the underlying thread lock.
    566     //
    567     // We use record server latency + playback track latency (generally smaller than the
    568     // reverse due to internal biases).
    569     //
    570     // TODO: is this stable enough? Consider a PatchTrack synchronized version of this.
    571 
    572     // For PCM tracks get server latency.
    573     if (audio_is_linear_pcm(recordTrack->format())) {
    574         double recordServerLatencyMs, playbackTrackLatencyMs;
    575         if (recordTrack->getServerLatencyMs(&recordServerLatencyMs) == OK
    576                 && playbackTrack->getTrackLatencyMs(&playbackTrackLatencyMs) == OK) {
    577             *latencyMs = recordServerLatencyMs + playbackTrackLatencyMs;
    578             return OK;
    579         }
    580     }
    581 
    582     // See if kernel latencies are available.
    583     // If so, do a frame diff and time difference computation to estimate
    584     // the total patch latency. This requires that frame counts are reported by the
    585     // HAL are matched properly in the case of record overruns and playback underruns.
    586     ThreadBase::TrackBase::FrameTime recordFT{}, playFT{};
    587     recordTrack->getKernelFrameTime(&recordFT);
    588     playbackTrack->getKernelFrameTime(&playFT);
    589     if (recordFT.timeNs > 0 && playFT.timeNs > 0) {
    590         const int64_t frameDiff = recordFT.frames - playFT.frames;
    591         const int64_t timeDiffNs = recordFT.timeNs - playFT.timeNs;
    592 
    593         // It is possible that the patch track and patch record have a large time disparity because
    594         // one thread runs but another is stopped.  We arbitrarily choose the maximum timestamp
    595         // time difference based on how often we expect the timestamps to update in normal operation
    596         // (typical should be no more than 50 ms).
    597         //
    598         // If the timestamps aren't sampled close enough, the patch latency is not
    599         // considered valid.
    600         //
    601         // TODO: change this based on more experiments.
    602         constexpr int64_t maxValidTimeDiffNs = 200 * NANOS_PER_MILLISECOND;
    603         if (std::abs(timeDiffNs) < maxValidTimeDiffNs) {
    604             *latencyMs = frameDiff * 1e3 / recordTrack->sampleRate()
    605                    - timeDiffNs * 1e-6;
    606             return OK;
    607         }
    608     }
    609 
    610     return INVALID_OPERATION;
    611 }
    612 
    613 String8 AudioFlinger::PatchPanel::Patch::dump(audio_patch_handle_t myHandle) const
    614 {
    615     // TODO: Consider table dump form for patches, just like tracks.
    616     String8 result = String8::format("Patch %d: thread %p => thread %p",
    617             myHandle, mRecord.const_thread().get(), mPlayback.const_thread().get());
    618 
    619     // add latency if it exists
    620     double latencyMs;
    621     if (getLatencyMs(&latencyMs) == OK) {
    622         result.appendFormat("  latency: %.2lf ms", latencyMs);
    623     }
    624     return result;
    625 }
    626 
    627 /* Disconnect a patch */
    628 status_t AudioFlinger::PatchPanel::releaseAudioPatch(audio_patch_handle_t handle)
    629 {
    630     ALOGV("%s handle %d", __func__, handle);
    631     status_t status = NO_ERROR;
    632 
    633     auto iter = mPatches.find(handle);
    634     if (iter == mPatches.end()) {
    635         return BAD_VALUE;
    636     }
    637     Patch &removedPatch = iter->second;
    638     const struct audio_patch &patch = removedPatch.mAudioPatch;
    639 
    640     const struct audio_port_config &src = patch.sources[0];
    641     switch (src.type) {
    642         case AUDIO_PORT_TYPE_DEVICE: {
    643             sp<DeviceHalInterface> hwDevice = findHwDeviceByModule(src.ext.device.hw_module);
    644             if (hwDevice == 0) {
    645                 ALOGW("%s() bad src hw module %d", __func__, src.ext.device.hw_module);
    646                 status = BAD_VALUE;
    647                 break;
    648             }
    649 
    650             if (removedPatch.isSoftware()) {
    651                 removedPatch.clearConnections(this);
    652                 break;
    653             }
    654 
    655             if (patch.sinks[0].type == AUDIO_PORT_TYPE_MIX) {
    656                 audio_io_handle_t ioHandle = patch.sinks[0].ext.mix.handle;
    657                 sp<ThreadBase> thread = mAudioFlinger.checkRecordThread_l(ioHandle);
    658                 if (thread == 0) {
    659                     thread = mAudioFlinger.checkMmapThread_l(ioHandle);
    660                     if (thread == 0) {
    661                         ALOGW("%s() bad capture I/O handle %d", __func__, ioHandle);
    662                         status = BAD_VALUE;
    663                         break;
    664                     }
    665                 }
    666                 status = thread->sendReleaseAudioPatchConfigEvent(removedPatch.mHalHandle);
    667             } else {
    668                 status = hwDevice->releaseAudioPatch(removedPatch.mHalHandle);
    669             }
    670         } break;
    671         case AUDIO_PORT_TYPE_MIX: {
    672             if (findHwDeviceByModule(src.ext.mix.hw_module) == 0) {
    673                 ALOGW("%s() bad src hw module %d", __func__, src.ext.mix.hw_module);
    674                 status = BAD_VALUE;
    675                 break;
    676             }
    677             audio_io_handle_t ioHandle = src.ext.mix.handle;
    678             sp<ThreadBase> thread = mAudioFlinger.checkPlaybackThread_l(ioHandle);
    679             if (thread == 0) {
    680                 thread = mAudioFlinger.checkMmapThread_l(ioHandle);
    681                 if (thread == 0) {
    682                     ALOGW("%s() bad playback I/O handle %d", __func__, ioHandle);
    683                     status = BAD_VALUE;
    684                     break;
    685                 }
    686             }
    687             status = thread->sendReleaseAudioPatchConfigEvent(removedPatch.mHalHandle);
    688         } break;
    689         default:
    690             status = BAD_VALUE;
    691     }
    692 
    693     mPatches.erase(iter);
    694     removeSoftwarePatchFromInsertedModules(handle);
    695     return status;
    696 }
    697 
    698 /* List connected audio ports and they attributes */
    699 status_t AudioFlinger::PatchPanel::listAudioPatches(unsigned int *num_patches __unused,
    700                                   struct audio_patch *patches __unused)
    701 {
    702     ALOGV(__func__);
    703     return NO_ERROR;
    704 }
    705 
    706 status_t AudioFlinger::PatchPanel::getDownstreamSoftwarePatches(
    707         audio_io_handle_t stream,
    708         std::vector<AudioFlinger::PatchPanel::SoftwarePatch> *patches) const
    709 {
    710     for (const auto& module : mInsertedModules) {
    711         if (module.second.streams.count(stream)) {
    712             for (const auto& patchHandle : module.second.sw_patches) {
    713                 const auto& patch_iter = mPatches.find(patchHandle);
    714                 if (patch_iter != mPatches.end()) {
    715                     const Patch &patch = patch_iter->second;
    716                     patches->emplace_back(*this, patchHandle,
    717                             patch.mPlayback.const_thread()->id(),
    718                             patch.mRecord.const_thread()->id());
    719                 } else {
    720                     ALOGE("Stale patch handle in the cache: %d", patchHandle);
    721                 }
    722             }
    723             return OK;
    724         }
    725     }
    726     // The stream is not associated with any of inserted modules.
    727     return BAD_VALUE;
    728 }
    729 
    730 void AudioFlinger::PatchPanel::notifyStreamOpened(
    731         AudioHwDevice *audioHwDevice, audio_io_handle_t stream)
    732 {
    733     if (audioHwDevice->isInsert()) {
    734         mInsertedModules[audioHwDevice->handle()].streams.insert(stream);
    735     }
    736 }
    737 
    738 void AudioFlinger::PatchPanel::notifyStreamClosed(audio_io_handle_t stream)
    739 {
    740     for (auto& module : mInsertedModules) {
    741         module.second.streams.erase(stream);
    742     }
    743 }
    744 
    745 AudioHwDevice* AudioFlinger::PatchPanel::findAudioHwDeviceByModule(audio_module_handle_t module)
    746 {
    747     if (module == AUDIO_MODULE_HANDLE_NONE) return nullptr;
    748     ssize_t index = mAudioFlinger.mAudioHwDevs.indexOfKey(module);
    749     if (index < 0) {
    750         ALOGW("%s() bad hw module %d", __func__, module);
    751         return nullptr;
    752     }
    753     return mAudioFlinger.mAudioHwDevs.valueAt(index);
    754 }
    755 
    756 sp<DeviceHalInterface> AudioFlinger::PatchPanel::findHwDeviceByModule(audio_module_handle_t module)
    757 {
    758     AudioHwDevice *audioHwDevice = findAudioHwDeviceByModule(module);
    759     return audioHwDevice ? audioHwDevice->hwDevice() : nullptr;
    760 }
    761 
    762 void AudioFlinger::PatchPanel::addSoftwarePatchToInsertedModules(
    763         audio_module_handle_t module, audio_patch_handle_t handle)
    764 {
    765     mInsertedModules[module].sw_patches.insert(handle);
    766 }
    767 
    768 void AudioFlinger::PatchPanel::removeSoftwarePatchFromInsertedModules(
    769         audio_patch_handle_t handle)
    770 {
    771     for (auto& module : mInsertedModules) {
    772         module.second.sw_patches.erase(handle);
    773     }
    774 }
    775 
    776 void AudioFlinger::PatchPanel::dump(int fd) const
    777 {
    778     String8 patchPanelDump;
    779     const char *indent = "  ";
    780 
    781     // Only dump software patches.
    782     bool headerPrinted = false;
    783     for (const auto& iter : mPatches) {
    784         if (iter.second.isSoftware()) {
    785             if (!headerPrinted) {
    786                 patchPanelDump += "\nSoftware patches:\n";
    787                 headerPrinted = true;
    788             }
    789             patchPanelDump.appendFormat("%s%s\n", indent, iter.second.dump(iter.first).string());
    790         }
    791     }
    792 
    793     headerPrinted = false;
    794     for (const auto& module : mInsertedModules) {
    795         if (!module.second.streams.empty() || !module.second.sw_patches.empty()) {
    796             if (!headerPrinted) {
    797                 patchPanelDump += "\nTracked inserted modules:\n";
    798                 headerPrinted = true;
    799             }
    800             String8 moduleDump = String8::format("Module %d: I/O handles: ", module.first);
    801             for (const auto& stream : module.second.streams) {
    802                 moduleDump.appendFormat("%d ", stream);
    803             }
    804             moduleDump.append("; SW Patches: ");
    805             for (const auto& patch : module.second.sw_patches) {
    806                 moduleDump.appendFormat("%d ", patch);
    807             }
    808             patchPanelDump.appendFormat("%s%s\n", indent, moduleDump.string());
    809         }
    810     }
    811 
    812     if (!patchPanelDump.isEmpty()) {
    813         write(fd, patchPanelDump.string(), patchPanelDump.size());
    814     }
    815 }
    816 
    817 } // namespace android
    818