Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1e447805 authored by Eric Laurent's avatar Eric Laurent Committed by Android (Google) Code Review
Browse files

Merge "audioflinger: fix reused audio patch resource release" into nyc-mr1-dev

parents 1608d7ba b997d3a3
Loading
Loading
Loading
Loading
+34 −0
Original line number Diff line number Diff line
@@ -168,12 +168,46 @@ status_t AudioFlinger::PatchPanel::createAudioPatch(const struct audio_patch *pa
                ALOGV("createAudioPatch() removing patch handle %d", *handle);
                halHandle = mPatches[index]->mHalHandle;
                Patch *removedPatch = mPatches[index];
                // free resources owned by the removed patch if applicable
                // 1) if a software patch is present, release the playback and capture threads and
                // tracks created. This will also release the corresponding audio HAL patches
                if ((removedPatch->mRecordPatchHandle
                        != AUDIO_PATCH_HANDLE_NONE) ||
                        (removedPatch->mPlaybackPatchHandle !=
                                AUDIO_PATCH_HANDLE_NONE)) {
                    clearPatchConnections(removedPatch);
                }
                // 2) if the new patch and old patch source or sink are devices from different
                // hw modules,  clear the audio HAL patches now because they will not be updated
                // by call to create_audio_patch() below which will happen on a different HW module
                if (halHandle != AUDIO_PATCH_HANDLE_NONE) {
                    audio_module_handle_t hwModule = AUDIO_MODULE_HANDLE_NONE;
                    if ((removedPatch->mAudioPatch.sources[0].type == AUDIO_PORT_TYPE_DEVICE) &&
                        ((patch->sources[0].type != AUDIO_PORT_TYPE_DEVICE) ||
                          (removedPatch->mAudioPatch.sources[0].ext.device.hw_module !=
                           patch->sources[0].ext.device.hw_module))) {
                        hwModule = removedPatch->mAudioPatch.sources[0].ext.device.hw_module;
                    } else if ((patch->num_sinks == 0) ||
                            ((removedPatch->mAudioPatch.sinks[0].type == AUDIO_PORT_TYPE_DEVICE) &&
                             ((patch->sinks[0].type != AUDIO_PORT_TYPE_DEVICE) ||
                              (removedPatch->mAudioPatch.sinks[0].ext.device.hw_module !=
                               patch->sinks[0].ext.device.hw_module)))) {
                        // Note on (patch->num_sinks == 0): this situation should not happen as
                        // these special patches are only created by the policy manager but just
                        // in case, systematically clear the HAL patch.
                        // Note that removedPatch->mAudioPatch.num_sinks cannot be 0 here because
                        // halHandle would be AUDIO_PATCH_HANDLE_NONE in this case.
                        hwModule = removedPatch->mAudioPatch.sinks[0].ext.device.hw_module;
                    }
                    if (hwModule != AUDIO_MODULE_HANDLE_NONE) {
                        ssize_t index = audioflinger->mAudioHwDevs.indexOfKey(hwModule);
                        if (index >= 0) {
                            audio_hw_device_t *hwDevice =
                                    audioflinger->mAudioHwDevs.valueAt(index)->hwDevice();
                            hwDevice->release_audio_patch(hwDevice, halHandle);
                        }
                    }
                }
                mPatches.removeAt(index);
                delete removedPatch;
                break;
+12 −0
Original line number Diff line number Diff line
@@ -62,12 +62,24 @@ public:

        struct audio_patch              mAudioPatch;
        audio_patch_handle_t            mHandle;
        // handle for audio HAL patch handle present only when the audio HAL version is >= 3.0
        audio_patch_handle_t            mHalHandle;
        // below members are used by a software audio patch connecting a source device from a
        // given audio HW module to a sink device on an other audio HW module.
        // playback thread created by createAudioPatch() and released by clearPatchConnections() if
        // no existing playback thread can be used by the software patch
        sp<PlaybackThread>              mPlaybackThread;
        // audio track created by createPatchConnections() and released by clearPatchConnections()
        sp<PlaybackThread::PatchTrack>  mPatchTrack;
        // record thread created by createAudioPatch() and released by clearPatchConnections()
        sp<RecordThread>                mRecordThread;
        // audio record created by createPatchConnections() and released by clearPatchConnections()
        sp<RecordThread::PatchRecord>   mPatchRecord;
        // handle for audio patch connecting source device to record thread input.
        // created by createPatchConnections() and released by clearPatchConnections()
        audio_patch_handle_t            mRecordPatchHandle;
        // handle for audio patch connecting playback thread output to sink device
        // created by createPatchConnections() and released by clearPatchConnections()
        audio_patch_handle_t            mPlaybackPatchHandle;

    };