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

Commit 4ef93454 authored by jiabin's avatar jiabin
Browse files

Make audio port in policy not derive from audio port base

This patch aims to make the structure for libaudiofoundation and policy
stuff simpler, including:
1. Make AudioPortBase as AudioPort in libaudiofoundation. Create
PolicyAudioPort that contains policy related stuff, which is used by
audiopolicy.
2. Make AudioPortConfigBase as AudioPortConfig in libaudiofoundation.
Create PolicyAudioPortConfig that contains policy related stuff.
3. DeviceDescriptor derives from AudioPort, AudioPortConfig, PolicyAudioPort
and PolicyAudioPortConfig. IOProfile derives from AudioPort,
PolicyAudioPort. AudioInputDescriptor/AudioOutputDescriptor derives from
AudioPortConfig, PolicyAudioPortConfig.

Test: atest AudioTrackTest, AudioRecordTest, AudioManagerTest
Test: atest audiopolicy_tests, AudioHostTest
Test: audio smoke test
Bug: 135621476
Change-Id: I40299d95dda3b3fc0ea88b079f2fe38d8f7e5b31
parent 811797a6
Loading
Loading
Loading
Loading
+106 −2
Original line number Original line Diff line number Diff line
@@ -13,6 +13,7 @@
 * See the License for the specific language governing permissions and
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * limitations under the License.
 */
 */
#define LOG_TAG "AudioPortBase"


#include <algorithm>
#include <algorithm>


@@ -22,7 +23,22 @@


namespace android {
namespace android {


void AudioPortBase::toAudioPort(struct audio_port *port) const {
void AudioPort::importAudioPort(const sp<AudioPort>& port, bool force __unused)
{
    for (const auto& profileToImport : port->mProfiles) {
        // Import only valid port, i.e. valid format, non empty rates and channels masks
        if (!profileToImport->isValid()) {
            continue;
        }
        if (std::find_if(mProfiles.begin(), mProfiles.end(),
                [profileToImport](const auto &profile) {
                        return *profile == *profileToImport; }) == mProfiles.end()) {
            addAudioProfile(profileToImport);
        }
    }
}

void AudioPort::toAudioPort(struct audio_port *port) const {
    // TODO: update this function once audio_port structure reflects the new profile definition.
    // TODO: update this function once audio_port structure reflects the new profile definition.
    // For compatibility reason: flatening the AudioProfile into audio_port structure.
    // For compatibility reason: flatening the AudioProfile into audio_port structure.
    FormatSet flatenedFormats;
    FormatSet flatenedFormats;
@@ -64,7 +80,7 @@ void AudioPortBase::toAudioPort(struct audio_port *port) const {
    }
    }
}
}


void AudioPortBase::dump(std::string *dst, int spaces, bool verbose) const {
void AudioPort::dump(std::string *dst, int spaces, bool verbose) const {
    if (!mName.empty()) {
    if (!mName.empty()) {
        dst->append(base::StringPrintf("%*s- name: %s\n", spaces, "", mName.c_str()));
        dst->append(base::StringPrintf("%*s- name: %s\n", spaces, "", mName.c_str()));
    }
    }
@@ -84,4 +100,92 @@ void AudioPortBase::dump(std::string *dst, int spaces, bool verbose) const {
    }
    }
}
}


void AudioPort::log(const char* indent) const
{
    ALOGI("%s Port[nm:%s, type:%d, role:%d]", indent, mName.c_str(), mType, mRole);
}

// --- AudioPortConfig class implementation

status_t AudioPortConfig::applyAudioPortConfig(
        const struct audio_port_config *config,
        struct audio_port_config *backupConfig __unused)
{
    if (config->config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE) {
        mSamplingRate = config->sample_rate;
    }
    if (config->config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK) {
        mChannelMask = config->channel_mask;
    }
    if (config->config_mask & AUDIO_PORT_CONFIG_FORMAT) {
        mFormat = config->format;
    }
    if (config->config_mask & AUDIO_PORT_CONFIG_GAIN) {
        mGain = config->gain;
    }

    return NO_ERROR;
}

namespace {

template<typename T>
void updateField(
        const T& portConfigField, T audio_port_config::*port_config_field,
        struct audio_port_config *dstConfig, const struct audio_port_config *srcConfig,
        unsigned int configMask, T defaultValue)
{
    if (dstConfig->config_mask & configMask) {
        if ((srcConfig != nullptr) && (srcConfig->config_mask & configMask)) {
            dstConfig->*port_config_field = srcConfig->*port_config_field;
        } else {
            dstConfig->*port_config_field = portConfigField;
        }
    } else {
        dstConfig->*port_config_field = defaultValue;
    }
}

} // namespace

void AudioPortConfig::toAudioPortConfig(
        struct audio_port_config *dstConfig,
        const struct audio_port_config *srcConfig) const
{
    updateField(mSamplingRate, &audio_port_config::sample_rate,
            dstConfig, srcConfig, AUDIO_PORT_CONFIG_SAMPLE_RATE, 0u);
    updateField(mChannelMask, &audio_port_config::channel_mask,
            dstConfig, srcConfig, AUDIO_PORT_CONFIG_CHANNEL_MASK,
            (audio_channel_mask_t)AUDIO_CHANNEL_NONE);
    updateField(mFormat, &audio_port_config::format,
            dstConfig, srcConfig, AUDIO_PORT_CONFIG_FORMAT, AUDIO_FORMAT_INVALID);
    dstConfig->id = mId;

    sp<AudioPort> audioport = getAudioPort();
    if ((dstConfig->config_mask & AUDIO_PORT_CONFIG_GAIN) && audioport != NULL) {
        dstConfig->gain = mGain;
        if ((srcConfig != NULL) && (srcConfig->config_mask & AUDIO_PORT_CONFIG_GAIN)
                && audioport->checkGain(&srcConfig->gain, srcConfig->gain.index) == OK) {
            dstConfig->gain = srcConfig->gain;
        }
    } else {
        dstConfig->gain.index = -1;
    }
    if (dstConfig->gain.index != -1) {
        dstConfig->config_mask |= AUDIO_PORT_CONFIG_GAIN;
    } else {
        dstConfig->config_mask &= ~AUDIO_PORT_CONFIG_GAIN;
    }
}

bool AudioPortConfig::hasGainController(bool canUseForVolume) const
{
    sp<AudioPort> audioport = getAudioPort();
    if (!audioport) {
        return false;
    }
    return canUseForVolume ? audioport->getGains().canUseForVolume()
                           : audioport->getGains().size() > 0;
}

}
}
 No newline at end of file
+20 −9
Original line number Original line Diff line number Diff line
@@ -27,13 +27,13 @@


namespace android {
namespace android {


class AudioPortBase : public virtual RefBase
class AudioPort : public virtual RefBase
{
{
public:
public:
    AudioPortBase(const std::string& name, audio_port_type_t type,  audio_port_role_t role) :
    AudioPort(const std::string& name, audio_port_type_t type,  audio_port_role_t role) :
            mName(name), mType(type), mRole(role) {}
            mName(name), mType(type), mRole(role) {}


    virtual ~AudioPortBase() = default;
    virtual ~AudioPort() = default;


    void setName(const std::string &name) { mName = name; }
    void setName(const std::string &name) { mName = name; }
    const std::string &getName() const { return mName; }
    const std::string &getName() const { return mName; }
@@ -41,8 +41,6 @@ public:
    audio_port_type_t getType() const { return mType; }
    audio_port_type_t getType() const { return mType; }
    audio_port_role_t getRole() const { return mRole; }
    audio_port_role_t getRole() const { return mRole; }


    virtual const std::string getTagName() const = 0;

    void setGains(const AudioGains &gains) { mGains = gains; }
    void setGains(const AudioGains &gains) { mGains = gains; }
    const AudioGains &getGains() const { return mGains; }
    const AudioGains &getGains() const { return mGains; }


@@ -57,9 +55,13 @@ public:


    bool hasValidAudioProfile() const { return mProfiles.hasValidProfile(); }
    bool hasValidAudioProfile() const { return mProfiles.hasValidProfile(); }


    bool hasDynamicAudioProfile() const { return mProfiles.hasDynamicProfile(); }

    void setAudioProfiles(const AudioProfileVector &profiles) { mProfiles = profiles; }
    void setAudioProfiles(const AudioProfileVector &profiles) { mProfiles = profiles; }
    AudioProfileVector &getAudioProfiles() { return mProfiles; }
    AudioProfileVector &getAudioProfiles() { return mProfiles; }


    virtual void importAudioPort(const sp<AudioPort>& port, bool force = false);

    status_t checkGain(const struct audio_gain_config *gainConfig, int index) const {
    status_t checkGain(const struct audio_gain_config *gainConfig, int index) const {
        if (index < 0 || (size_t)index >= mGains.size()) {
        if (index < 0 || (size_t)index >= mGains.size()) {
            return BAD_VALUE;
            return BAD_VALUE;
@@ -75,6 +77,8 @@ public:


    void dump(std::string *dst, int spaces, bool verbose = true) const;
    void dump(std::string *dst, int spaces, bool verbose = true) const;


    void log(const char* indent) const;

    AudioGains mGains; // gain controllers
    AudioGains mGains; // gain controllers
protected:
protected:
    std::string  mName;
    std::string  mName;
@@ -84,24 +88,31 @@ protected:
};
};




class AudioPortConfigBase : public virtual RefBase
class AudioPortConfig : public virtual RefBase
{
{
public:
public:
    virtual ~AudioPortConfigBase() = default;
    virtual ~AudioPortConfig() = default;

    virtual sp<AudioPort> getAudioPort() const = 0;


    virtual status_t applyAudioPortConfig(const struct audio_port_config *config,
    virtual status_t applyAudioPortConfig(const struct audio_port_config *config,
                                          struct audio_port_config *backupConfig = NULL) = 0;
                                          struct audio_port_config *backupConfig = NULL);

    virtual void toAudioPortConfig(struct audio_port_config *dstConfig,
    virtual void toAudioPortConfig(struct audio_port_config *dstConfig,
                                   const struct audio_port_config *srcConfig = NULL) const = 0;
                                   const struct audio_port_config *srcConfig = NULL) const;


    unsigned int getSamplingRate() const { return mSamplingRate; }
    unsigned int getSamplingRate() const { return mSamplingRate; }
    audio_format_t getFormat() const { return mFormat; }
    audio_format_t getFormat() const { return mFormat; }
    audio_channel_mask_t getChannelMask() const { return mChannelMask; }
    audio_channel_mask_t getChannelMask() const { return mChannelMask; }
    audio_port_handle_t getId() const { return mId; }

    bool hasGainController(bool canUseForVolume = false) const;


protected:
protected:
    unsigned int mSamplingRate = 0u;
    unsigned int mSamplingRate = 0u;
    audio_format_t mFormat = AUDIO_FORMAT_INVALID;
    audio_format_t mFormat = AUDIO_FORMAT_INVALID;
    audio_channel_mask_t mChannelMask = AUDIO_CHANNEL_NONE;
    audio_channel_mask_t mChannelMask = AUDIO_CHANNEL_NONE;
    audio_port_handle_t mId = AUDIO_PORT_HANDLE_NONE;
    struct audio_gain_config mGain = { .index = -1 };
    struct audio_gain_config mGain = { .index = -1 };
};
};


+6 −11
Original line number Original line Diff line number Diff line
@@ -25,20 +25,15 @@


namespace android {
namespace android {


class AudioPort;
class PolicyAudioPort;
class AudioRoute;
class AudioRoute;


class AudioPortVector : public Vector<sp<AudioPort> >
using PolicyAudioPortVector = Vector<sp<PolicyAudioPort>>;
{
using AudioRouteVector = Vector<sp<AudioRoute>>;
public:
    sp<AudioPort> findByTagName(const std::string &tagName) const;
};


sp<PolicyAudioPort> findByTagName(const PolicyAudioPortVector& policyAudioPortVector,
                                  const std::string &tagName);


class AudioRouteVector : public Vector<sp<AudioRoute> >
void dumpAudioRouteVector(const AudioRouteVector& audioRouteVector, String8 *dst, int spaces);
{
public:
    void dump(String8 *dst, int spaces) const;
};


} // namespace android
} // namespace android
+18 −6
Original line number Original line Diff line number Diff line
@@ -34,13 +34,17 @@ class AudioPolicyClientInterface;


// descriptor for audio inputs. Used to maintain current configuration of each opened audio input
// descriptor for audio inputs. Used to maintain current configuration of each opened audio input
// and keep track of the usage of this input.
// and keep track of the usage of this input.
class AudioInputDescriptor: public AudioPortConfig, public AudioIODescriptorInterface
class AudioInputDescriptor: public AudioPortConfig,
    , public ClientMapHandler<RecordClientDescriptor>
        public PolicyAudioPortConfig,
        public AudioIODescriptorInterface,
        public ClientMapHandler<RecordClientDescriptor>
{
{
public:
public:
    explicit AudioInputDescriptor(const sp<IOProfile>& profile,
    AudioInputDescriptor(const sp<IOProfile>& profile,
                         AudioPolicyClientInterface *clientInterface);
                         AudioPolicyClientInterface *clientInterface);
    audio_port_handle_t getId() const;

    virtual ~AudioInputDescriptor() = default;

    audio_module_handle_t getModuleHandle() const;
    audio_module_handle_t getModuleHandle() const;


    audio_devices_t getDeviceType() const { return (mDevice != nullptr) ?
    audio_devices_t getDeviceType() const { return (mDevice != nullptr) ?
@@ -56,9 +60,18 @@ public:
    wp<AudioPolicyMix>  mPolicyMix;                   // non NULL when used by a dynamic policy
    wp<AudioPolicyMix>  mPolicyMix;                   // non NULL when used by a dynamic policy
    const sp<IOProfile> mProfile;                     // I/O profile this output derives from
    const sp<IOProfile> mProfile;                     // I/O profile this output derives from


    // PolicyAudioPortConfig
    virtual sp<PolicyAudioPort> getPolicyAudioPort() const {
        return mProfile;
    }

    // AudioPortConfig
    virtual status_t applyAudioPortConfig(const struct audio_port_config *config,
                                          struct audio_port_config *backupConfig = NULL);
    virtual void toAudioPortConfig(struct audio_port_config *dstConfig,
    virtual void toAudioPortConfig(struct audio_port_config *dstConfig,
            const struct audio_port_config *srcConfig = NULL) const;
            const struct audio_port_config *srcConfig = NULL) const;
    virtual sp<AudioPort> getAudioPort() const { return mProfile; }
    virtual sp<AudioPort> getAudioPort() const { return mProfile; }

    void toAudioPort(struct audio_port *port) const;
    void toAudioPort(struct audio_port *port) const;
    void setPreemptedSessions(const SortedVector<audio_session_t>& sessions);
    void setPreemptedSessions(const SortedVector<audio_session_t>& sessions);
    SortedVector<audio_session_t> getPreemptedSessions() const;
    SortedVector<audio_session_t> getPreemptedSessions() const;
@@ -111,7 +124,6 @@ public:
    void updateClientRecordingConfiguration(int event, const sp<RecordClientDescriptor>& client);
    void updateClientRecordingConfiguration(int event, const sp<RecordClientDescriptor>& client);


    audio_patch_handle_t mPatchHandle = AUDIO_PATCH_HANDLE_NONE;
    audio_patch_handle_t mPatchHandle = AUDIO_PATCH_HANDLE_NONE;
    audio_port_handle_t  mId = AUDIO_PORT_HANDLE_NONE;
    sp<DeviceDescriptor> mDevice = nullptr; /**< current device this input is routed to */
    sp<DeviceDescriptor> mDevice = nullptr; /**< current device this input is routed to */


    // Because a preemptible capture session can preempt another one, we end up in an endless loop
    // Because a preemptible capture session can preempt another one, we end up in an endless loop
+17 −7
Original line number Original line Diff line number Diff line
@@ -138,18 +138,19 @@ using RoutingActivities = std::map<product_strategy_t, RoutingActivity>;


// descriptor for audio outputs. Used to maintain current configuration of each opened audio output
// descriptor for audio outputs. Used to maintain current configuration of each opened audio output
// and keep track of the usage of this output by each audio stream type.
// and keep track of the usage of this output by each audio stream type.
class AudioOutputDescriptor: public AudioPortConfig, public AudioIODescriptorInterface
class AudioOutputDescriptor: public AudioPortConfig,
    , public ClientMapHandler<TrackClientDescriptor>
        public PolicyAudioPortConfig,
        public AudioIODescriptorInterface,
        public ClientMapHandler<TrackClientDescriptor>
{
{
public:
public:
    AudioOutputDescriptor(const sp<AudioPort>& port,
    AudioOutputDescriptor(const sp<PolicyAudioPort>& policyAudioPort,
                          AudioPolicyClientInterface *clientInterface);
                          AudioPolicyClientInterface *clientInterface);
    virtual ~AudioOutputDescriptor() {}
    virtual ~AudioOutputDescriptor() {}


    void dump(String8 *dst) const override;
    void dump(String8 *dst) const override;
    void        log(const char* indent);
    void        log(const char* indent);


    audio_port_handle_t getId() const;
    virtual DeviceVector devices() const { return mDevices; }
    virtual DeviceVector devices() const { return mDevices; }
    bool sharesHwModuleWith(const sp<AudioOutputDescriptor>& outputDesc);
    bool sharesHwModuleWith(const sp<AudioOutputDescriptor>& outputDesc);
    virtual DeviceVector supportedDevices() const  { return mDevices; }
    virtual DeviceVector supportedDevices() const  { return mDevices; }
@@ -245,9 +246,19 @@ public:
        mRoutingActivities[ps].setMutedByDevice(isMuted);
        mRoutingActivities[ps].setMutedByDevice(isMuted);
    }
    }


    // PolicyAudioPortConfig
    virtual sp<PolicyAudioPort> getPolicyAudioPort() const
    {
        return mPolicyAudioPort;
    }

    // AudioPortConfig
    virtual status_t applyAudioPortConfig(const struct audio_port_config *config,
                                          struct audio_port_config *backupConfig = NULL);
    virtual void toAudioPortConfig(struct audio_port_config *dstConfig,
    virtual void toAudioPortConfig(struct audio_port_config *dstConfig,
                           const struct audio_port_config *srcConfig = NULL) const;
                           const struct audio_port_config *srcConfig = NULL) const;
    virtual sp<AudioPort> getAudioPort() const { return mPort; }
    virtual sp<AudioPort> getAudioPort() const { return mPolicyAudioPort->asAudioPort(); }

    virtual void toAudioPort(struct audio_port *port) const;
    virtual void toAudioPort(struct audio_port *port) const;


    audio_module_handle_t getModuleHandle() const;
    audio_module_handle_t getModuleHandle() const;
@@ -289,11 +300,10 @@ public:
    wp<AudioPolicyMix> mPolicyMix;  // non NULL when used by a dynamic policy
    wp<AudioPolicyMix> mPolicyMix;  // non NULL when used by a dynamic policy


protected:
protected:
    const sp<AudioPort> mPort;
    const sp<PolicyAudioPort> mPolicyAudioPort;
    AudioPolicyClientInterface * const mClientInterface;
    AudioPolicyClientInterface * const mClientInterface;
    uint32_t mGlobalActiveCount = 0;  // non-client-specific active count
    uint32_t mGlobalActiveCount = 0;  // non-client-specific active count
    audio_patch_handle_t mPatchHandle = AUDIO_PATCH_HANDLE_NONE;
    audio_patch_handle_t mPatchHandle = AUDIO_PATCH_HANDLE_NONE;
    audio_port_handle_t mId = AUDIO_PORT_HANDLE_NONE;


    // The ActiveClients shows the clients that contribute to the @VolumeSource counts
    // The ActiveClients shows the clients that contribute to the @VolumeSource counts
    // and may include upstream clients from a duplicating thread.
    // and may include upstream clients from a duplicating thread.
Loading