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

Commit 678a721d authored by Andy Hung's avatar Andy Hung Committed by Automerger Merge Worker
Browse files

Merge "AudioFlinger: Create PatchPanel callback" into udc-dev-plus-aosp am: 25143505

parents 9a1827d7 25143505
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -412,6 +412,7 @@ void AudioFlinger::onFirstRef()
        mAAudioHwBurstMinMicros = getAAudioHardwareBurstMinUsecFromSystemProperty();
    }

    mPatchPanel = IAfPatchPanel::create(sp<IAfPatchPanelCallback>::fromExisting(this));
    mMelReporter = sp<MelReporter>::make(sp<IAfMelReporterCallback>::fromExisting(this));
}

+40 −34
Original line number Diff line number Diff line
@@ -166,10 +166,10 @@ class AudioFlinger
    , public IAfClientCallback
    , public IAfDeviceEffectManagerCallback
    , public IAfMelReporterCallback
    , public IAfPatchPanelCallback
{
    friend class sp<AudioFlinger>;
    // TODO(b/291319167) Create interface and remove friends.
    friend class PatchPanel;
    // TODO(b/291012167) replace the Thread friends with an interface.
    friend class DirectOutputThread;
    friend class MixerThread;
@@ -374,7 +374,7 @@ public:
    // ---- begin IAfDeviceEffectManagerCallback interface

    bool isAudioPolicyReady() const final { return mAudioPolicyReady.load(); }
    // below also used by IAfMelReporterCallback
    // below also used by IAfMelReporterCallback, IAfPatchPanelCallback
    const sp<PatchCommandThread>& getPatchCommandThread() final { return mPatchCommandThread; }
    status_t addEffectToHal(
            const struct audio_port_config* device, const sp<EffectHalInterface>& effect) final;
@@ -390,6 +390,41 @@ public:

    // ---- end of IAfMelReporterCallback interface

    // ---- begin IAfPatchPanelCallback interface

    void closeThreadInternal_l(const sp<IAfPlaybackThread>& thread) final;
    void closeThreadInternal_l(const sp<IAfRecordThread>& thread) final;
    // return thread associated with primary hardware device, or NULL
    IAfPlaybackThread* primaryPlaybackThread_l() const final;
    IAfPlaybackThread* checkPlaybackThread_l(audio_io_handle_t output) const final;
    IAfRecordThread* checkRecordThread_l(audio_io_handle_t input) const final;
    IAfMmapThread* checkMmapThread_l(audio_io_handle_t io) const final;
    void lock() const final ACQUIRE(mLock) { mLock.lock(); }
    void unlock() const final RELEASE(mLock) { mLock.unlock(); }
    sp<IAfThreadBase> openInput_l(audio_module_handle_t module,
            audio_io_handle_t* input,
            audio_config_t* config,
            audio_devices_t device,
            const char* address,
            audio_source_t source,
            audio_input_flags_t flags,
            audio_devices_t outputDevice,
            const String8& outputDeviceAddress) final;
    sp<IAfThreadBase> openOutput_l(audio_module_handle_t module,
            audio_io_handle_t* output,
            audio_config_t* halConfig,
            audio_config_base_t* mixerConfig,
            audio_devices_t deviceType,
            const String8& address,
            audio_output_flags_t flags) final;
    const DefaultKeyedVector<audio_module_handle_t, AudioHwDevice*>&
            getAudioHwDevs_l() const final { return mAudioHwDevs; }
    void updateDownStreamPatches_l(const struct audio_patch* patch,
            const std::set<audio_io_handle_t>& streams) final;
    void updateOutDevicesForRecordThreads_l(const DeviceDescriptorBaseVector& devices) final;

    // ---- end of IAfPatchPanelCallback interface

    /* List available audio ports and their attributes */
    status_t listAudioPorts(unsigned int* num_ports, struct audio_port* ports) const;

@@ -411,9 +446,6 @@ public:
        const sp<os::ExternalVibration>& externalVibration);
    static void onExternalVibrationStop(const sp<os::ExternalVibration>& externalVibration);

    void updateDownStreamPatches_l(const struct audio_patch *patch,
                                   const std::set<audio_io_handle_t>& streams);

    std::optional<media::AudioVibratorInfo> getDefaultVibratorInfo_l();

private:
@@ -453,9 +485,6 @@ public:

    bool        btNrecIsOff() const { return mBtNrecIsOff.load(); }

    void             lock() ACQUIRE(mLock) { mLock.lock(); }
    void             unlock() RELEASE(mLock) { mLock.unlock(); }

private:

               audio_mode_t getMode() const { return mMode; }
@@ -627,29 +656,11 @@ private:
    }

    IAfThreadBase* checkThread_l(audio_io_handle_t ioHandle) const;
    IAfPlaybackThread* checkPlaybackThread_l(audio_io_handle_t output) const;
    IAfPlaybackThread* checkMixerThread_l(audio_io_handle_t output) const;
    IAfRecordThread* checkRecordThread_l(audio_io_handle_t input) const;
    IAfMmapThread* checkMmapThread_l(audio_io_handle_t io) const;

              sp<VolumeInterface> getVolumeInterface_l(audio_io_handle_t output) const;
              std::vector<sp<VolumeInterface>> getAllVolumeInterfaces_l() const;

    sp<IAfThreadBase> openInput_l(audio_module_handle_t module,
                                           audio_io_handle_t *input,
                                           audio_config_t *config,
                                           audio_devices_t device,
                                           const char* address,
                                           audio_source_t source,
                                           audio_input_flags_t flags,
                                           audio_devices_t outputDevice,
                                           const String8& outputDeviceAddress);
    sp<IAfThreadBase> openOutput_l(audio_module_handle_t module,
                                          audio_io_handle_t *output,
                                          audio_config_t *halConfig,
                                          audio_config_base_t *mixerConfig,
                                          audio_devices_t deviceType,
                                          const String8& address,
                                          audio_output_flags_t flags);

    void closeOutputFinish(const sp<IAfPlaybackThread>& thread);
    void closeInputFinish(const sp<IAfRecordThread>& thread);
@@ -674,14 +685,13 @@ private:
              //       Thus it may fail by returning an ID of the wrong sign,
              //       or by returning a non-unique ID.
              // This is the internal API.  For the binder API see newAudioUniqueId().
    // used by IAfDeviceEffectManagerCallback
    // used by IAfDeviceEffectManagerCallback, IAfPatchPanelCallback
    audio_unique_id_t nextUniqueId(audio_unique_id_use_t use) final;

              status_t moveEffectChain_l(audio_session_t sessionId,
            IAfPlaybackThread* srcThread, IAfPlaybackThread* dstThread);

              // return thread associated with primary hardware device, or NULL
              IAfPlaybackThread* primaryPlaybackThread_l() const;
              DeviceTypeSet primaryOutputDevice_l() const;

              // return the playback thread with smallest HAL buffer size, and prefer fast
@@ -725,7 +735,6 @@ private:
                std::vector< sp<IAfEffectModule> > purgeStaleEffects_l();

                void broadcastParametersToRecordThreads_l(const String8& keyValuePairs);
                void updateOutDevicesForRecordThreads_l(const DeviceDescriptorBaseVector& devices);
                void forwardParametersToDownstreamPatches_l(
                        audio_io_handle_t upStream, const String8& keyValuePairs,
            const std::function<bool(const sp<IAfPlaybackThread>&)>& useThread = nullptr);
@@ -843,9 +852,7 @@ private:

    // for use from destructor
    status_t    closeOutput_nonvirtual(audio_io_handle_t output);
    void closeThreadInternal_l(const sp<IAfPlaybackThread>& thread);
    status_t    closeInput_nonvirtual(audio_io_handle_t input);
    void closeThreadInternal_l(const sp<IAfRecordThread>& thread);
    void setAudioHwSyncForSession_l(IAfPlaybackThread* thread, audio_session_t sessionId);

    status_t    checkStreamType(audio_stream_type_t stream) const;
@@ -872,8 +879,7 @@ private:

    nsecs_t mGlobalEffectEnableTime;  // when a global effect was last enabled

    // protected by mLock
    const sp<IAfPatchPanel> mPatchPanel = IAfPatchPanel::create(this);
    /* const */ sp<IAfPatchPanel> mPatchPanel;

public:
    // TODO(b/291319167) access by getter.
+38 −1
Original line number Diff line number Diff line
@@ -18,12 +18,14 @@

namespace android {

class IAfMmapThread;
class IAfPatchPanel;
class IAfPatchRecord;
class IAfPatchTrack;
class IAfPlaybackThread;
class IAfRecordThread;
class IAfThreadBase;
class PatchCommandThread;

class SoftwarePatch {
public:
@@ -51,9 +53,44 @@ private:
    const audio_io_handle_t mRecordThreadHandle;
};

class IAfPatchPanelCallback : public virtual RefBase {
public:
    virtual void closeThreadInternal_l(const sp<IAfPlaybackThread>& thread) = 0;
    virtual void closeThreadInternal_l(const sp<IAfRecordThread>& thread) = 0;
    virtual IAfPlaybackThread* primaryPlaybackThread_l() const = 0;
    virtual IAfPlaybackThread* checkPlaybackThread_l(audio_io_handle_t output) const = 0;
    virtual IAfRecordThread* checkRecordThread_l(audio_io_handle_t input) const = 0;
    virtual IAfMmapThread* checkMmapThread_l(audio_io_handle_t io) const = 0;
    virtual sp<IAfThreadBase> openInput_l(audio_module_handle_t module,
            audio_io_handle_t* input,
            audio_config_t* config,
            audio_devices_t device,
            const char* address,
            audio_source_t source,
            audio_input_flags_t flags,
            audio_devices_t outputDevice,
            const String8& outputDeviceAddress) = 0;
    virtual sp<IAfThreadBase> openOutput_l(audio_module_handle_t module,
            audio_io_handle_t* output,
            audio_config_t* halConfig,
            audio_config_base_t* mixerConfig,
            audio_devices_t deviceType,
            const String8& address,
            audio_output_flags_t flags) = 0;
    virtual void lock() const = 0;
    virtual void unlock() const = 0;
    virtual const DefaultKeyedVector<audio_module_handle_t, AudioHwDevice*>&
            getAudioHwDevs_l() const = 0;
    virtual audio_unique_id_t nextUniqueId(audio_unique_id_use_t use) = 0;
    virtual const sp<PatchCommandThread>& getPatchCommandThread() = 0;
    virtual void updateDownStreamPatches_l(
            const struct audio_patch* patch, const std::set<audio_io_handle_t>& streams) = 0;
    virtual void updateOutDevicesForRecordThreads_l(const DeviceDescriptorBaseVector& devices) = 0;
};

class IAfPatchPanel : public virtual RefBase {
public:
    static sp<IAfPatchPanel> create(AudioFlinger* audioFlinger);
    static sp<IAfPatchPanel> create(const sp<IAfPatchPanelCallback>& afPatchPanelCallback);

    // Extraction of inner Endpoint and Patch classes would require interfaces
    // (in the Endpoint case a templated interface) but that seems
+39 −36
Original line number Diff line number Diff line
@@ -96,8 +96,8 @@ status_t AudioFlinger::listAudioPatches(
}

/* static */
sp<IAfPatchPanel> IAfPatchPanel::create(AudioFlinger* audioFlinger) {
    return sp<PatchPanel>::make(audioFlinger);
sp<IAfPatchPanel> IAfPatchPanel::create(const sp<IAfPatchPanelCallback>& afPatchPanelCallback) {
    return sp<PatchPanel>::make(afPatchPanelCallback);
}

status_t SoftwarePatch::getLatencyMs_l(double* latencyMs) const {
@@ -119,10 +119,10 @@ void PatchPanel::closeThreadInternal_l(const sp<IAfThreadBase>& thread) const
{
    if (const auto recordThread = thread->asIAfRecordThread();
            recordThread) {
        mAudioFlinger.closeThreadInternal_l(recordThread);
        mAfPatchPanelCallback->closeThreadInternal_l(recordThread);
    } else if (const auto playbackThread = thread->asIAfPlaybackThread();
            playbackThread) {
        mAudioFlinger.closeThreadInternal_l(playbackThread);
        mAfPatchPanelCallback->closeThreadInternal_l(playbackThread);
    } else {
        LOG_ALWAYS_FATAL("%s: Endpoints only accept IAfPlayback and IAfRecord threads, "
                "invalid thread, id: %d  type: %d",
@@ -275,8 +275,8 @@ status_t PatchPanel::createAudioPatch(const struct audio_patch* patch,
                        status = INVALID_OPERATION;
                        goto exit;
                    }
                    const sp<IAfThreadBase> thread =
                            mAudioFlinger.checkPlaybackThread_l(patch->sources[1].ext.mix.handle);
                    const sp<IAfThreadBase> thread = mAfPatchPanelCallback->checkPlaybackThread_l(
                            patch->sources[1].ext.mix.handle);
                    if (thread == 0) {
                        ALOGW("%s() cannot get playback thread", __func__);
                        status = INVALID_OPERATION;
@@ -302,7 +302,7 @@ status_t PatchPanel::createAudioPatch(const struct audio_patch* patch,
                    if (patch->sinks[0].config_mask & AUDIO_PORT_CONFIG_FLAGS) {
                        flags = patch->sinks[0].flags.output;
                    }
                    const sp<IAfThreadBase> thread = mAudioFlinger.openOutput_l(
                    const sp<IAfThreadBase> thread = mAfPatchPanelCallback->openOutput_l(
                                                            patch->sinks[0].ext.device.hw_module,
                                                            &output,
                                                            &config,
@@ -310,7 +310,7 @@ status_t PatchPanel::createAudioPatch(const struct audio_patch* patch,
                                                            outputDevice,
                                                            outputDeviceAddress,
                                                            flags);
                    ALOGV("mAudioFlinger.openOutput_l() returned %p", thread.get());
                    ALOGV("mAfPatchPanelCallback->openOutput_l() returned %p", thread.get());
                    if (thread == 0) {
                        status = NO_MEMORY;
                        goto exit;
@@ -349,7 +349,7 @@ status_t PatchPanel::createAudioPatch(const struct audio_patch* patch,
                                == AUDIO_STREAM_VOICE_CALL) {
                    source = AUDIO_SOURCE_VOICE_COMMUNICATION;
                }
                const sp<IAfThreadBase> thread = mAudioFlinger.openInput_l(srcModule,
                const sp<IAfThreadBase> thread = mAfPatchPanelCallback->openInput_l(srcModule,
                                                                    &input,
                                                                    &config,
                                                                    device,
@@ -358,7 +358,7 @@ status_t PatchPanel::createAudioPatch(const struct audio_patch* patch,
                                                                    flags,
                                                                    outputDevice,
                                                                    outputDeviceAddress);
                ALOGV("mAudioFlinger.openInput_l() returned %p inChannelMask %08x",
                ALOGV("mAfPatchPanelCallback->openInput_l() returned %p inChannelMask %08x",
                      thread.get(), config.channel_mask);
                if (thread == 0) {
                    status = NO_MEMORY;
@@ -374,10 +374,11 @@ status_t PatchPanel::createAudioPatch(const struct audio_patch* patch,
                }
            } else {
                if (patch->sinks[0].type == AUDIO_PORT_TYPE_MIX) {
                    sp<IAfThreadBase> thread = mAudioFlinger.checkRecordThread_l(
                    sp<IAfThreadBase> thread = mAfPatchPanelCallback->checkRecordThread_l(
                                                              patch->sinks[0].ext.mix.handle);
                    if (thread == 0) {
                        thread = mAudioFlinger.checkMmapThread_l(patch->sinks[0].ext.mix.handle);
                        thread = mAfPatchPanelCallback->checkMmapThread_l(
                                patch->sinks[0].ext.mix.handle);
                        if (thread == 0) {
                            ALOGW("%s() bad capture I/O handle %d",
                                    __func__, patch->sinks[0].ext.mix.handle);
@@ -385,9 +386,9 @@ status_t PatchPanel::createAudioPatch(const struct audio_patch* patch,
                            goto exit;
                        }
                    }
                    mAudioFlinger.unlock();
                    mAfPatchPanelCallback->unlock();
                    status = thread->sendCreateAudioPatchConfigEvent(patch, &halHandle);
                    mAudioFlinger.lock();
                    mAfPatchPanelCallback->lock();
                    if (status == NO_ERROR) {
                        newPatch.setThread(thread);
                    }
@@ -411,7 +412,7 @@ status_t PatchPanel::createAudioPatch(const struct audio_patch* patch,
        } break;
        case AUDIO_PORT_TYPE_MIX: {
            audio_module_handle_t srcModule =  patch->sources[0].ext.mix.hw_module;
            ssize_t index = mAudioFlinger.mAudioHwDevs.indexOfKey(srcModule);
            ssize_t index = mAfPatchPanelCallback->getAudioHwDevs_l().indexOfKey(srcModule);
            if (index < 0) {
                ALOGW("%s() bad src hw module %d", __func__, srcModule);
                status = BAD_VALUE;
@@ -437,10 +438,11 @@ status_t PatchPanel::createAudioPatch(const struct audio_patch* patch,
                device->applyAudioPortConfig(&patch->sinks[i]);
                devices.push_back(device);
            }
            sp<IAfThreadBase> thread =
                            mAudioFlinger.checkPlaybackThread_l(patch->sources[0].ext.mix.handle);
            sp<IAfThreadBase> thread = mAfPatchPanelCallback->checkPlaybackThread_l(
                    patch->sources[0].ext.mix.handle);
            if (thread == 0) {
                thread = mAudioFlinger.checkMmapThread_l(patch->sources[0].ext.mix.handle);
                thread = mAfPatchPanelCallback->checkMmapThread_l(
                        patch->sources[0].ext.mix.handle);
                if (thread == 0) {
                    ALOGW("%s() bad playback I/O handle %d",
                            __func__, patch->sources[0].ext.mix.handle);
@@ -448,13 +450,13 @@ status_t PatchPanel::createAudioPatch(const struct audio_patch* patch,
                    goto exit;
                }
            }
            if (thread == mAudioFlinger.primaryPlaybackThread_l()) {
                mAudioFlinger.updateOutDevicesForRecordThreads_l(devices);
            if (thread == mAfPatchPanelCallback->primaryPlaybackThread_l()) {
                mAfPatchPanelCallback->updateOutDevicesForRecordThreads_l(devices);
            }

            mAudioFlinger.unlock();
            mAfPatchPanelCallback->unlock();
            status = thread->sendCreateAudioPatchConfigEvent(patch, &halHandle);
            mAudioFlinger.lock();
            mAfPatchPanelCallback->lock();
            if (status == NO_ERROR) {
                newPatch.setThread(thread);
            }
@@ -479,9 +481,10 @@ status_t PatchPanel::createAudioPatch(const struct audio_patch* patch,
exit:
    ALOGV("%s() status %d", __func__, status);
    if (status == NO_ERROR) {
        *handle = (audio_patch_handle_t) mAudioFlinger.nextUniqueId(AUDIO_UNIQUE_ID_USE_PATCH);
        *handle = static_cast<audio_patch_handle_t>(
                mAfPatchPanelCallback->nextUniqueId(AUDIO_UNIQUE_ID_USE_PATCH));
        newPatch.mHalHandle = halHandle;
        mAudioFlinger.mPatchCommandThread->createAudioPatch(*handle, newPatch);
        mAfPatchPanelCallback->getPatchCommandThread()->createAudioPatch(*handle, newPatch);
        if (insertedModule != AUDIO_MODULE_HANDLE_NONE) {
            addSoftwarePatchToInsertedModules(insertedModule, *handle, &newPatch.mAudioPatch);
        }
@@ -793,18 +796,18 @@ status_t PatchPanel::releaseAudioPatch(audio_patch_handle_t handle)

            if (patch.sinks[0].type == AUDIO_PORT_TYPE_MIX) {
                audio_io_handle_t ioHandle = patch.sinks[0].ext.mix.handle;
                sp<IAfThreadBase> thread = mAudioFlinger.checkRecordThread_l(ioHandle);
                sp<IAfThreadBase> thread = mAfPatchPanelCallback->checkRecordThread_l(ioHandle);
                if (thread == 0) {
                    thread = mAudioFlinger.checkMmapThread_l(ioHandle);
                    thread = mAfPatchPanelCallback->checkMmapThread_l(ioHandle);
                    if (thread == 0) {
                        ALOGW("%s() bad capture I/O handle %d", __func__, ioHandle);
                        status = BAD_VALUE;
                        break;
                    }
                }
                mAudioFlinger.unlock();
                mAfPatchPanelCallback->unlock();
                status = thread->sendReleaseAudioPatchConfigEvent(removedPatch.mHalHandle);
                mAudioFlinger.lock();
                mAfPatchPanelCallback->lock();
            } else {
                status = hwDevice->releaseAudioPatch(removedPatch.mHalHandle);
            }
@@ -816,18 +819,18 @@ status_t PatchPanel::releaseAudioPatch(audio_patch_handle_t handle)
                break;
            }
            audio_io_handle_t ioHandle = src.ext.mix.handle;
            sp<IAfThreadBase> thread = mAudioFlinger.checkPlaybackThread_l(ioHandle);
            sp<IAfThreadBase> thread = mAfPatchPanelCallback->checkPlaybackThread_l(ioHandle);
            if (thread == 0) {
                thread = mAudioFlinger.checkMmapThread_l(ioHandle);
                thread = mAfPatchPanelCallback->checkMmapThread_l(ioHandle);
                if (thread == 0) {
                    ALOGW("%s() bad playback I/O handle %d", __func__, ioHandle);
                    status = BAD_VALUE;
                    break;
                }
            }
            mAudioFlinger.unlock();
            mAfPatchPanelCallback->unlock();
            status = thread->sendReleaseAudioPatchConfigEvent(removedPatch.mHalHandle);
            mAudioFlinger.lock();
            mAfPatchPanelCallback->lock();
        } break;
        default:
            status = BAD_VALUE;
@@ -840,7 +843,7 @@ status_t PatchPanel::releaseAudioPatch(audio_patch_handle_t handle)
void PatchPanel::erasePatch(audio_patch_handle_t handle) {
    mPatches.erase(handle);
    removeSoftwarePatchFromInsertedModules(handle);
    mAudioFlinger.mPatchCommandThread->releaseAudioPatch(handle);
    mAfPatchPanelCallback->getPatchCommandThread()->releaseAudioPatch(handle);
}

/* List connected audio ports and they attributes */
@@ -904,12 +907,12 @@ void PatchPanel::notifyStreamClosed(audio_io_handle_t stream)
AudioHwDevice* PatchPanel::findAudioHwDeviceByModule(audio_module_handle_t module)
{
    if (module == AUDIO_MODULE_HANDLE_NONE) return nullptr;
    ssize_t index = mAudioFlinger.mAudioHwDevs.indexOfKey(module);
    ssize_t index = mAfPatchPanelCallback->getAudioHwDevs_l().indexOfKey(module);
    if (index < 0) {
        ALOGW("%s() bad hw module %d", __func__, module);
        return nullptr;
    }
    return mAudioFlinger.mAudioHwDevs.valueAt(index);
    return mAfPatchPanelCallback->getAudioHwDevs_l().valueAt(index);
}

sp<DeviceHalInterface> PatchPanel::findHwDeviceByModule(audio_module_handle_t module)
@@ -924,7 +927,7 @@ void PatchPanel::addSoftwarePatchToInsertedModules(
{
    mInsertedModules[module].sw_patches.insert(handle);
    if (!mInsertedModules[module].streams.empty()) {
        mAudioFlinger.updateDownStreamPatches_l(patch, mInsertedModules[module].streams);
        mAfPatchPanelCallback->updateDownStreamPatches_l(patch, mInsertedModules[module].streams);
    }
}

+3 −2
Original line number Diff line number Diff line
@@ -21,7 +21,8 @@ namespace android {

class PatchPanel : public IAfPatchPanel {
public:
    explicit PatchPanel(AudioFlinger* audioFlinger) : mAudioFlinger(*audioFlinger) {}
    explicit PatchPanel(const sp<IAfPatchPanelCallback>& afPatchPanelCallback)
        : mAfPatchPanelCallback(afPatchPanelCallback) {}

    /* List connected audio ports and their attributes */
    status_t listAudioPorts(unsigned int *num_ports,
@@ -71,7 +72,7 @@ private:
    void removeSoftwarePatchFromInsertedModules(audio_patch_handle_t handle);
    void erasePatch(audio_patch_handle_t handle);

    AudioFlinger &mAudioFlinger;
    const sp<IAfPatchPanelCallback> mAfPatchPanelCallback;
    std::map<audio_patch_handle_t, Patch> mPatches;

    // This map allows going from a thread to "downstream" software patches