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

Commit 5babc4f1 authored by Eric Laurent's avatar Eric Laurent
Browse files

audio policy: fix regression with duplicated output handle

Commit fe231127 made that IO Handle for duplicated outputs
were not allocated properly causing volume commands to be sent
with an invalid IO handle to audio flinger.
We then hit another problem with a legacy behavior which broadcasts volume
commands to all output threads if received with IOHandle 0.

Bug: 70332110
Test: manual test.
Change-Id: Ib133abab1575e3c90ba235f0a52d5ab845514719
parent 31832c60
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -133,6 +133,9 @@ public:
            // Note: called after changeRefCount(-1);
            void stop();
            void close();
            status_t openDuplicating(const sp<SwAudioOutputDescriptor>& output1,
                                     const sp<SwAudioOutputDescriptor>& output2,
                                     audio_io_handle_t *ioHandle);

    const sp<IOProfile> mProfile;          // I/O profile this output derives from
    audio_io_handle_t mIoHandle;           // output handle
+25 −1
Original line number Diff line number Diff line
@@ -222,7 +222,7 @@ void AudioOutputDescriptor::log(const char* indent)
SwAudioOutputDescriptor::SwAudioOutputDescriptor(const sp<IOProfile>& profile,
                                                 AudioPolicyClientInterface *clientInterface)
    : AudioOutputDescriptor(profile, clientInterface),
    mProfile(profile), mIoHandle(0), mLatency(0),
    mProfile(profile), mIoHandle(AUDIO_IO_HANDLE_NONE), mLatency(0),
    mFlags((audio_output_flags_t)0), mPolicyMix(NULL),
    mOutput1(0), mOutput2(0), mDirectOpenCount(0),
    mDirectClientSession(AUDIO_SESSION_NONE), mGlobalRefCount(0)
@@ -509,6 +509,30 @@ void SwAudioOutputDescriptor::close()
    }
}

status_t SwAudioOutputDescriptor::openDuplicating(const sp<SwAudioOutputDescriptor>& output1,
                                                  const sp<SwAudioOutputDescriptor>& output2,
                                                  audio_io_handle_t *ioHandle)
{
    // open a duplicating output thread for the new output and the primary output
    // Note: openDuplicateOutput() API expects the output handles in the reverse order from the
    // numbering in SwAudioOutputDescriptor mOutput1 and mOutput2
    *ioHandle = mClientInterface->openDuplicateOutput(output2->mIoHandle, output1->mIoHandle);
    if (*ioHandle == AUDIO_IO_HANDLE_NONE) {
        return INVALID_OPERATION;
    }

    mId = AudioPort::getNextUniqueId();
    mIoHandle = *ioHandle;
    mOutput1 = output1;
    mOutput2 = output2;
    mSamplingRate = output2->mSamplingRate;
    mFormat = output2->mFormat;
    mChannelMask = output2->mChannelMask;
    mLatency = output2->mLatency;

    return NO_ERROR;
}

// HwAudioOutputDescriptor implementation
HwAudioOutputDescriptor::HwAudioOutputDescriptor(const sp<AudioSourceDescriptor>& source,
                                                 AudioPolicyClientInterface *clientInterface)
+5 −12
Original line number Diff line number Diff line
@@ -3930,19 +3930,12 @@ status_t AudioPolicyManager::checkOutputsForDevice(const sp<DeviceDescriptor>& d
                        //TODO: configure audio effect output stage here

                        // open a duplicating output thread for the new output and the primary output
                        duplicatedOutput =
                                mpClientInterface->openDuplicateOutput(output,
                                                                       mPrimaryOutput->mIoHandle);
                        if (duplicatedOutput != AUDIO_IO_HANDLE_NONE) {
                            // add duplicated output descriptor
                        sp<SwAudioOutputDescriptor> dupOutputDesc =
                                new SwAudioOutputDescriptor(NULL, mpClientInterface);
                            dupOutputDesc->mOutput1 = mPrimaryOutput;
                            dupOutputDesc->mOutput2 = desc;
                            dupOutputDesc->mSamplingRate = desc->mSamplingRate;
                            dupOutputDesc->mFormat = desc->mFormat;
                            dupOutputDesc->mChannelMask = desc->mChannelMask;
                            dupOutputDesc->mLatency = desc->mLatency;
                        status_t status = dupOutputDesc->openDuplicating(mPrimaryOutput, desc,
                                                                         &duplicatedOutput);
                        if (status == NO_ERROR) {
                            // add duplicated output descriptor
                            addOutput(duplicatedOutput, dupOutputDesc);
                            applyStreamVolumes(dupOutputDesc, device, 0, true);
                        } else {