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

Commit 4dbb7193 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "audio_server: Unify audio_patch creation"

parents 815fc56c dc769682
Loading
Loading
Loading
Loading
+103 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ANDROID_PATCH_BUILDER_H
#define ANDROID_PATCH_BUILDER_H

#include <functional>
#include <utility>

#include <system/audio.h>
#include <utils/StrongPointer.h>

// This is a header-only utility.

namespace android {

class PatchBuilder {
  public:
    using mix_usecase_t = decltype(audio_port_config_mix_ext::usecase);

    PatchBuilder() = default;

    // All existing methods operating on audio patches take a pointer to const.
    // It's OK to construct a temporary PatchBuilder while preparing a parameter
    // to such a function because the Builder will be kept alive until the code
    // execution reaches the function call statement semicolon.
    const struct audio_patch* patch() const { return &mPatch; }

    template<typename T, typename... S>
    PatchBuilder& addSink(T&& t, S&&... s) {
        sinks().add(std::forward<T>(t), std::forward<S>(s)...);
        return *this;
    }
    // Explicit type of the second parameter allows clients to provide the struct inline.
    template<typename T>
    PatchBuilder& addSink(T&& t, const mix_usecase_t& update) {
        sinks().add(std::forward<T>(t), update);
        return *this;
    }
    template<typename T, typename... S>
    PatchBuilder& addSource(T&& t, S&&... s) {
        sources().add(std::forward<T>(t), std::forward<S>(s)...);
        return *this;
    }
    // Explicit type of the second parameter allows clients to provide the struct inline.
    template<typename T>
    PatchBuilder& addSource(T&& t, const mix_usecase_t& update) {
        sources().add(std::forward<T>(t), update);
        return *this;
    }

  private:
    struct PortCfgs {
        PortCfgs(unsigned int *countPtr, struct audio_port_config *portCfgs)
                : mCountPtr(countPtr), mPortCfgs(portCfgs) {}
        audio_port_config& add(const audio_port_config& portCfg) {
            return *advance() = portCfg;
        }
        template<typename T>
        audio_port_config& add(const sp<T>& entity) {
            audio_port_config* added = advance();
            entity->toAudioPortConfig(added);
            return *added;
        }
        template<typename T>
        void add(const sp<T>& entity, const mix_usecase_t& usecaseUpdate) {
            add(entity).ext.mix.usecase = usecaseUpdate;
        }
        template<typename T>
        void add(const sp<T>& entity,
                std::function<mix_usecase_t(const mix_usecase_t&)> usecaseUpdater) {
            mix_usecase_t* usecase = &add(entity).ext.mix.usecase;
            *usecase = usecaseUpdater(*usecase);
        }
        struct audio_port_config* advance() {
            return &mPortCfgs[(*mCountPtr)++];
        }
        unsigned int *mCountPtr;
        struct audio_port_config *mPortCfgs;
    };

    PortCfgs sinks() { return PortCfgs(&mPatch.num_sinks, mPatch.sinks); }
    PortCfgs sources() { return PortCfgs(&mPatch.num_sources, mPatch.sources); }

    struct audio_patch mPatch = {};
};

}  // namespace android

#endif  // ANDROID_PATCH_BUILDER_H
+8 −12
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@
#include "AudioFlinger.h"
#include "ServiceUtilities.h"
#include <media/AudioParameter.h>
#include <media/PatchBuilder.h>

// ----------------------------------------------------------------------------

@@ -373,15 +374,10 @@ AudioFlinger::PatchPanel::Patch::~Patch()
status_t AudioFlinger::PatchPanel::Patch::createConnections(PatchPanel *panel)
{
    // create patch from source device to record thread input
    struct audio_patch subPatch;
    subPatch.num_sources = 1;
    subPatch.sources[0] = mAudioPatch.sources[0];
    subPatch.num_sinks = 1;

    mRecord.thread()->getAudioPortConfig(&subPatch.sinks[0]);
    subPatch.sinks[0].ext.mix.usecase.source = AUDIO_SOURCE_MIC;

    status_t status = panel->createAudioPatch(&subPatch, mRecord.handlePtr());
    status_t status = panel->createAudioPatch(
            PatchBuilder().addSource(mAudioPatch.sources[0]).
                addSink(mRecord.thread(), { .source = AUDIO_SOURCE_MIC }).patch(),
            mRecord.handlePtr());
    if (status != NO_ERROR) {
        *mRecord.handlePtr() = AUDIO_PATCH_HANDLE_NONE;
        return status;
@@ -389,9 +385,9 @@ status_t AudioFlinger::PatchPanel::Patch::createConnections(PatchPanel *panel)

    // create patch from playback thread output to sink device
    if (mAudioPatch.num_sinks != 0) {
        mPlayback.thread()->getAudioPortConfig(&subPatch.sources[0]);
        subPatch.sinks[0] = mAudioPatch.sinks[0];
        status = panel->createAudioPatch(&subPatch, mPlayback.handlePtr());
        status = panel->createAudioPatch(
                PatchBuilder().addSource(mPlayback.thread()).addSink(mAudioPatch.sinks[0]).patch(),
                mPlayback.handlePtr());
        if (status != NO_ERROR) {
            *mPlayback.handlePtr() = AUDIO_PATCH_HANDLE_NONE;
            return status;
+7 −7
Original line number Diff line number Diff line
@@ -1527,7 +1527,7 @@ void AudioFlinger::ThreadBase::setMode(audio_mode_t mode)
    }
}

void AudioFlinger::ThreadBase::getAudioPortConfig(struct audio_port_config *config)
void AudioFlinger::ThreadBase::toAudioPortConfig(struct audio_port_config *config)
{
    config->type = AUDIO_PORT_TYPE_MIX;
    config->ext.mix.handle = mId;
@@ -3780,9 +3780,9 @@ void AudioFlinger::PlaybackThread::deletePatchTrack(const sp<PatchTrack>& track)
    destroyTrack_l(track);
}

void AudioFlinger::PlaybackThread::getAudioPortConfig(struct audio_port_config *config)
void AudioFlinger::PlaybackThread::toAudioPortConfig(struct audio_port_config *config)
{
    ThreadBase::getAudioPortConfig(config);
    ThreadBase::toAudioPortConfig(config);
    config->role = AUDIO_PORT_ROLE_SOURCE;
    config->ext.mix.hw_module = mOutput->audioHwDev->handle();
    config->ext.mix.usecase.stream = AUDIO_STREAM_DEFAULT;
@@ -7875,9 +7875,9 @@ void AudioFlinger::RecordThread::deletePatchTrack(const sp<PatchRecord>& record)
    destroyTrack_l(record);
}

void AudioFlinger::RecordThread::getAudioPortConfig(struct audio_port_config *config)
void AudioFlinger::RecordThread::toAudioPortConfig(struct audio_port_config *config)
{
    ThreadBase::getAudioPortConfig(config);
    ThreadBase::toAudioPortConfig(config);
    config->role = AUDIO_PORT_ROLE_SINK;
    config->ext.mix.hw_module = mInput->audioHwDev->handle();
    config->ext.mix.usecase.source = mAudioSource;
@@ -8462,9 +8462,9 @@ status_t AudioFlinger::MmapThread::releaseAudioPatch_l(const audio_patch_handle_
    return status;
}

void AudioFlinger::MmapThread::getAudioPortConfig(struct audio_port_config *config)
void AudioFlinger::MmapThread::toAudioPortConfig(struct audio_port_config *config)
{
    ThreadBase::getAudioPortConfig(config);
    ThreadBase::toAudioPortConfig(config);
    if (isOutput()) {
        config->role = AUDIO_PORT_ROLE_SOURCE;
        config->ext.mix.hw_module = mAudioHwDev->handle();
+4 −4
Original line number Diff line number Diff line
@@ -281,7 +281,7 @@ public:
    virtual     status_t    createAudioPatch_l(const struct audio_patch *patch,
                                               audio_patch_handle_t *handle) = 0;
    virtual     status_t    releaseAudioPatch_l(const audio_patch_handle_t handle) = 0;
    virtual     void        getAudioPortConfig(struct audio_port_config *config) = 0;
    virtual     void        toAudioPortConfig(struct audio_port_config *config) = 0;


                // see note at declaration of mStandby, mOutDevice and mInDevice
@@ -782,7 +782,7 @@ public:
                void        addPatchTrack(const sp<PatchTrack>& track);
                void        deletePatchTrack(const sp<PatchTrack>& track);

    virtual     void        getAudioPortConfig(struct audio_port_config *config);
    virtual     void        toAudioPortConfig(struct audio_port_config *config);

                // Return the asynchronous signal wait time.
    virtual     int64_t     computeWaitTimeNs_l() const { return INT64_MAX; }
@@ -1459,7 +1459,7 @@ public:

    virtual size_t      frameCount() const { return mFrameCount; }
            bool        hasFastCapture() const { return mFastCapture != 0; }
    virtual void        getAudioPortConfig(struct audio_port_config *config);
    virtual void        toAudioPortConfig(struct audio_port_config *config);

    virtual status_t    checkEffectCompatibility_l(const effect_descriptor_t *desc,
                                                   audio_session_t sessionId);
@@ -1602,7 +1602,7 @@ class MmapThread : public ThreadBase
    virtual     status_t    createAudioPatch_l(const struct audio_patch *patch,
                                               audio_patch_handle_t *handle);
    virtual     status_t    releaseAudioPatch_l(const audio_patch_handle_t handle);
    virtual     void        getAudioPortConfig(struct audio_port_config *config);
    virtual     void        toAudioPortConfig(struct audio_port_config *config);

    virtual     sp<StreamHalInterface> stream() const { return mHalStream; }
    virtual     status_t    addEffectChain_l(const sp<EffectChain>& chain);
+8 −7
Original line number Diff line number Diff line
@@ -19,26 +19,27 @@
namespace android {

/**
 * Interface for input descriptors to implement so dependent audio sessions can query information
 * about their context
 * Interface for I/O descriptors to implement so information about their context
 * can be queried and updated.
 */
class AudioSessionInfoProvider
class AudioIODescriptorInterface
{
public:
    virtual ~AudioSessionInfoProvider() {};
    virtual ~AudioIODescriptorInterface() {};

    virtual audio_config_base_t getConfig() const = 0;

    virtual audio_patch_handle_t getPatchHandle() const = 0;

    virtual void setPatchHandle(audio_patch_handle_t handle) = 0;
};

class AudioSessionInfoUpdateListener
class AudioIODescriptorUpdateListener
{
public:
    virtual ~AudioSessionInfoUpdateListener() {};
    virtual ~AudioIODescriptorUpdateListener() {};

    virtual void onSessionInfoUpdate() const = 0;;
    virtual void onIODescriptorUpdate() const = 0;
};

} // namespace android
Loading