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

Commit efdbe3bf authored by Eric Laurent's avatar Eric Laurent
Browse files

Revert "audiopolicy: moves Stream Volume Curves to Engine"

This reverts commit 53931194.

Bug: 125937703
Test: make
parent 1462a279
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ cc_library_static {
        "src/Serializer.cpp",
        "src/SoundTriggerSession.cpp",
        "src/TypeConverter.cpp",
        "src/VolumeCurve.cpp",
    ],
    shared_libs: [
        "libcutils",
+12 −1
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@
#include <unordered_set>

#include <AudioGain.h>
#include <VolumeCurve.h>
#include <AudioPort.h>
#include <AudioPatch.h>
#include <DeviceDescriptor.h>
@@ -39,11 +40,13 @@ public:
    AudioPolicyConfig(HwModuleCollection &hwModules,
                      DeviceVector &availableOutputDevices,
                      DeviceVector &availableInputDevices,
                      sp<DeviceDescriptor> &defaultOutputDevice)
                      sp<DeviceDescriptor> &defaultOutputDevice,
                      VolumeCurvesCollection *volumes = nullptr)
        : mHwModules(hwModules),
          mAvailableOutputDevices(availableOutputDevices),
          mAvailableInputDevices(availableInputDevices),
          mDefaultOutputDevice(defaultOutputDevice),
          mVolumeCurves(volumes),
          mIsSpeakerDrcEnabled(false)
    {}

@@ -55,6 +58,13 @@ public:
        mSource = file;
    }

    void setVolumes(const VolumeCurvesCollection &volumes)
    {
        if (mVolumeCurves != nullptr) {
            *mVolumeCurves = volumes;
        }
    }

    void setHwModules(const HwModuleCollection &hwModules)
    {
        mHwModules = hwModules;
@@ -172,6 +182,7 @@ private:
    DeviceVector &mAvailableOutputDevices;
    DeviceVector &mAvailableInputDevices;
    sp<DeviceDescriptor> &mDefaultOutputDevice;
    VolumeCurvesCollection *mVolumeCurves;
    // TODO: remove when legacy conf file is removed. true on devices that use DRC on the
    // DEVICE_CATEGORY_SPEAKER path to boost soft sounds, used to adjust volume curves accordingly.
    // Note: remove also speaker_drc_enabled from global configuration of XML config file.
+54 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 The Android Open Source Project
 * Copyright (C) 2015 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.
@@ -20,25 +20,35 @@
#include <Volume.h>
#include <utils/Errors.h>
#include <utils/String8.h>
#include <vector>

namespace android {

class IVolumeCurves
class IVolumeCurvesCollection
{
public:
    virtual ~IVolumeCurves() = default;

    virtual void clearCurrentVolumeIndex() = 0;
    virtual void addCurrentVolumeIndex(audio_devices_t device, int index) = 0;
    virtual bool canBeMuted() const = 0;
    virtual int getVolumeIndexMin() const = 0;
    virtual int getVolumeIndex(audio_devices_t device) const = 0;
    virtual int getVolumeIndexMax() const = 0;
    virtual float volIndexToDb(device_category device, int indexInUi) const = 0;
    virtual bool hasVolumeIndexForDevice(audio_devices_t device) const = 0;
    virtual status_t initVolume(int indexMin, int indexMax) = 0;
    virtual void dump(String8 *dst, int spaces = 0, bool curvePoints = false) const = 0;
    virtual ~IVolumeCurvesCollection() = default;

    virtual void clearCurrentVolumeIndex(audio_stream_type_t stream) = 0;
    virtual void addCurrentVolumeIndex(audio_stream_type_t stream, audio_devices_t device,
                                       int index) = 0;
    virtual bool canBeMuted(audio_stream_type_t stream) = 0;
    virtual int getVolumeIndexMin(audio_stream_type_t stream) const = 0;
    virtual int getVolumeIndex(audio_stream_type_t stream, audio_devices_t device) = 0;
    virtual int getVolumeIndexMax(audio_stream_type_t stream) const = 0;
    virtual float volIndexToDb(audio_stream_type_t stream, device_category device,
                               int indexInUi) const = 0;
    virtual status_t initStreamVolume(audio_stream_type_t stream, int indexMin, int indexMax) = 0;

    virtual void initializeVolumeCurves(bool /*isSpeakerDrcEnabled*/) {}
    virtual void switchVolumeCurve(audio_stream_type_t src, audio_stream_type_t dst) = 0;
    virtual void restoreOriginVolumeCurve(audio_stream_type_t stream)
    {
        switchVolumeCurve(stream, stream);
    }
    virtual bool hasVolumeIndexForDevice(audio_stream_type_t stream,
                                         audio_devices_t device) const = 0;

    virtual void dump(String8 *dst) const = 0;
};

} // namespace android
+239 −0
Original line number Diff line number Diff line
@@ -16,7 +16,7 @@

#pragma once

#include "IVolumeCurves.h"
#include "IVolumeCurvesCollection.h"
#include <policy.h>
#include <utils/RefBase.h>
#include <utils/String8.h>
@@ -25,7 +25,6 @@
#include <system/audio.h>
#include <cutils/config_utils.h>
#include <string>
#include <map>
#include <utility>

namespace android {
@@ -50,43 +49,31 @@ inline bool operator< (const CurvePoint &lhs, const CurvePoint &rhs)
class VolumeCurve : public RefBase
{
public:
    VolumeCurve(device_category device) : mDeviceCategory(device) {}
    VolumeCurve(device_category device, audio_stream_type_t stream) :
        mDeviceCategory(device), mStreamType(stream) {}

    device_category getDeviceCategory() const { return mDeviceCategory; }
    audio_stream_type_t getStreamType() const { return mStreamType; }

    void add(const CurvePoint &point) { mCurvePoints.add(point); }

    float volIndexToDb(int indexInUi, int volIndexMin, int volIndexMax) const;

    void dump(String8 *dst, int spaces = 0, bool curvePoints = false) const;

    device_category getDeviceCategory() const { return mDeviceCategory; }
    void dump(String8 *result) const;

private:
    const device_category mDeviceCategory;
    SortedVector<CurvePoint> mCurvePoints;
    device_category mDeviceCategory;
    audio_stream_type_t mStreamType;
};

// Volume Curves for a given use case indexed by device category
class VolumeCurves : public KeyedVector<device_category, sp<VolumeCurve> >,
                     public IVolumeCurves
class VolumeCurvesForStream : public KeyedVector<device_category, sp<VolumeCurve> >
{
public:
    VolumeCurves(int indexMin = 0, int indexMax = 100) :
        mIndexMin(indexMin), mIndexMax(indexMax), mStream(AUDIO_STREAM_DEFAULT)
    VolumeCurvesForStream() : mIndexMin(0), mIndexMax(1), mCanBeMuted(true)
    {
        addCurrentVolumeIndex(AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME, 0);
    }
    VolumeCurves(audio_stream_type_t stream, int indexMin, int indexMax) :
        mIndexMin(indexMin), mIndexMax(indexMax), mStream(stream)
    {
        addCurrentVolumeIndex(AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME, 0);
    }

    // Once XML has been parsed, must be call first to sanity check table and initialize indexes
    virtual status_t initVolume(int indexMin, int indexMax)
    {
        mIndexMin = indexMin;
        mIndexMax = indexMax;
        return NO_ERROR;
        mIndexCur.add(AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME, 0);
    }

    sp<VolumeCurve> getCurvesFor(device_category device) const
@@ -97,48 +84,30 @@ public:
        return valueFor(device);
    }

    virtual int getVolumeIndex(audio_devices_t device) const
    int getVolumeIndex(audio_devices_t device) const
    {
        device = Volume::getDeviceForVolume(device);
        // there is always a valid entry for AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME
        if (mIndexCur.find(device) == end(mIndexCur)) {
        if (mIndexCur.indexOfKey(device) < 0) {
            device = AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME;
        }
        return mIndexCur.at(device);
        return mIndexCur.valueFor(device);
    }

    virtual bool canBeMuted() const { return mCanBeMuted; }
    virtual void clearCurrentVolumeIndex() { mIndexCur.clear(); }
    void addCurrentVolumeIndex(audio_devices_t device, int index) override
    {
        mIndexCur[device] = index;
    }
    bool canBeMuted() const { return mCanBeMuted; }
    void clearCurrentVolumeIndex() { mIndexCur.clear(); }
    void addCurrentVolumeIndex(audio_devices_t device, int index) { mIndexCur.add(device, index); }

    void setVolumeIndexMin(int volIndexMin) { mIndexMin = volIndexMin; }
    int getVolumeIndexMin() const { return mIndexMin; }

    void setVolumeIndexMax(int volIndexMax) { mIndexMax = volIndexMax; }
    int getVolumeIndexMax() const { return mIndexMax; }

    bool hasVolumeIndexForDevice(audio_devices_t device) const
    {
        device = Volume::getDeviceForVolume(device);
        return mIndexCur.find(device) != end(mIndexCur);
    }

    status_t switchCurvesFrom(const VolumeCurves &referenceCurves)
    {
        if (size() != referenceCurves.size()) {
            ALOGE("%s! device category not aligned, cannot switch", __FUNCTION__);
            return BAD_TYPE;
        }
        for (size_t index = 0; index < size(); index++) {
            device_category cat = keyAt(index);
            setVolumeCurve(cat, referenceCurves.getOriginVolumeCurve(cat));
        }
        return NO_ERROR;
    }
    status_t restoreOriginVolumeCurve()
    {
        return switchCurvesFrom(*this);
        return mIndexCur.indexOfKey(device) >= 0;
    }

    const sp<VolumeCurve> getOriginVolumeCurve(device_category deviceCategory) const
@@ -164,7 +133,7 @@ public:
        return index;
    }

    virtual float volIndexToDb(device_category deviceCat, int indexInUi) const
    float volIndexToDb(device_category deviceCat, int indexInUi) const
    {
        sp<VolumeCurve> vc = getCurvesFor(deviceCat);
        if (vc != 0) {
@@ -175,18 +144,96 @@ public:
        }
    }

    audio_stream_type_t getStreamType() const { return mStream; }

    void dump(String8 *dst, int spaces = 0, bool curvePoints = false) const override;
    void dump(String8 *dst, int spaces, bool curvePoints = false) const;

private:
    KeyedVector<device_category, sp<VolumeCurve> > mOriginVolumeCurves;
    std::map<audio_devices_t, int> mIndexCur; /**< current volume index per device. */
    /*const*/ int mIndexMin; /**< min volume index. */
    /*const*/ int mIndexMax; /**< max volume index. */
    const bool mCanBeMuted = true; /**< true is the stream can be muted. */
    KeyedVector<audio_devices_t, int> mIndexCur; /**< current volume index per device. */
    int mIndexMin; /**< min volume index. */
    int mIndexMax; /**< max volume index. */
    bool mCanBeMuted; /**< true is the stream can be muted. */
};

// Collection of Volume Curves indexed by use case
class VolumeCurvesCollection : public KeyedVector<audio_stream_type_t, VolumeCurvesForStream>,
                               public IVolumeCurvesCollection
{
public:
    VolumeCurvesCollection()
    {
        // Create an empty collection of curves
        for (ssize_t i = 0 ; i < AUDIO_STREAM_CNT; i++) {
            audio_stream_type_t stream = static_cast<audio_stream_type_t>(i);
            KeyedVector::add(stream, VolumeCurvesForStream());
        }
    }

    // Once XML has been parsed, must be call first to sanity check table and initialize indexes
    virtual status_t initStreamVolume(audio_stream_type_t stream, int indexMin, int indexMax)
    {
        editValueAt(stream).setVolumeIndexMin(indexMin);
        editValueAt(stream).setVolumeIndexMax(indexMax);
        return NO_ERROR;
    }
    virtual void clearCurrentVolumeIndex(audio_stream_type_t stream)
    {
        editCurvesFor(stream).clearCurrentVolumeIndex();
    }
    virtual void addCurrentVolumeIndex(audio_stream_type_t stream, audio_devices_t device, int index)
    {
        editCurvesFor(stream).addCurrentVolumeIndex(device, index);
    }
    virtual bool canBeMuted(audio_stream_type_t stream) { return getCurvesFor(stream).canBeMuted(); }

    virtual int getVolumeIndexMin(audio_stream_type_t stream) const
    {
        return getCurvesFor(stream).getVolumeIndexMin();
    }
    virtual int getVolumeIndexMax(audio_stream_type_t stream) const
    {
        return getCurvesFor(stream).getVolumeIndexMax();
    }
    virtual int getVolumeIndex(audio_stream_type_t stream, audio_devices_t device)
    {
        return getCurvesFor(stream).getVolumeIndex(device);
    }
    virtual void switchVolumeCurve(audio_stream_type_t streamSrc, audio_stream_type_t streamDst)
    {
        const VolumeCurvesForStream &sourceCurves = getCurvesFor(streamSrc);
        VolumeCurvesForStream &dstCurves = editCurvesFor(streamDst);
        ALOG_ASSERT(sourceCurves.size() == dstCurves.size(), "device category not aligned");
        for (size_t index = 0; index < sourceCurves.size(); index++) {
            device_category cat = sourceCurves.keyAt(index);
            dstCurves.setVolumeCurve(cat, sourceCurves.getOriginVolumeCurve(cat));
        }
    }
    virtual float volIndexToDb(audio_stream_type_t stream, device_category cat, int indexInUi) const
    {
        return getCurvesFor(stream).volIndexToDb(cat, indexInUi);
    }
    virtual bool hasVolumeIndexForDevice(audio_stream_type_t stream,
                                         audio_devices_t device) const
    {
        return getCurvesFor(stream).hasVolumeIndexForDevice(device);
    }

    void dump(String8 *dst) const override;

    const audio_stream_type_t mStream; /**< Keep it for legacy. */
    ssize_t add(const sp<VolumeCurve> &volumeCurve)
    {
        audio_stream_type_t streamType = volumeCurve->getStreamType();
        return editCurvesFor(streamType).add(volumeCurve);
    }
    VolumeCurvesForStream &editCurvesFor(audio_stream_type_t stream)
    {
        ALOG_ASSERT(indexOfKey(stream) >= 0, "Invalid stream type for Volume Curve");
        return editValueAt(stream);
    }
    const VolumeCurvesForStream &getCurvesFor(audio_stream_type_t stream) const
    {
        ALOG_ASSERT(indexOfKey(stream) >= 0, "Invalid stream type for Volume Curve");
        return valueFor(stream);
    }
};

} // namespace android
+88 −0
Original line number Diff line number Diff line
@@ -201,6 +201,25 @@ struct GlobalConfigTraits
    static status_t deserialize(const xmlNode *root, AudioPolicyConfig *config);
};

struct VolumeTraits : public AndroidCollectionTraits<VolumeCurve, VolumeCurvesCollection>
{
    static constexpr const char *tag = "volume";
    static constexpr const char *collectionTag = "volumes";
    static constexpr const char *volumePointTag = "point";
    static constexpr const char *referenceTag = "reference";

    struct Attributes
    {
        static constexpr const char *stream = "stream";
        static constexpr const char *deviceCategory = "deviceCategory";
        static constexpr const char *reference = "ref";
        static constexpr const char *referenceName = "name";
    };

    static Return<Element> deserialize(const xmlNode *cur, PtrSerializingCtx serializingContext);
    // No Children
};

struct SurroundSoundTraits
{
    static constexpr const char *tag = "surroundSound";
@@ -684,6 +703,67 @@ status_t GlobalConfigTraits::deserialize(const xmlNode *root, AudioPolicyConfig
    return NO_ERROR;
}

Return<VolumeTraits::Element> VolumeTraits::deserialize(const xmlNode *cur,
        PtrSerializingCtx /*serializingContext*/)
{
    std::string streamTypeLiteral = getXmlAttribute(cur, Attributes::stream);
    if (streamTypeLiteral.empty()) {
        ALOGE("%s: No %s found", __func__, Attributes::stream);
        return Status::fromStatusT(BAD_VALUE);
    }
    audio_stream_type_t streamType;
    if (!StreamTypeConverter::fromString(streamTypeLiteral, streamType)) {
        ALOGE("%s: Invalid %s", __func__, Attributes::stream);
        return Status::fromStatusT(BAD_VALUE);
    }
    std::string deviceCategoryLiteral = getXmlAttribute(cur, Attributes::deviceCategory);
    if (deviceCategoryLiteral.empty()) {
        ALOGE("%s: No %s found", __func__, Attributes::deviceCategory);
        return Status::fromStatusT(BAD_VALUE);
    }
    device_category deviceCategory;
    if (!DeviceCategoryConverter::fromString(deviceCategoryLiteral, deviceCategory)) {
        ALOGE("%s: Invalid %s=%s", __func__, Attributes::deviceCategory,
              deviceCategoryLiteral.c_str());
        return Status::fromStatusT(BAD_VALUE);
    }

    std::string referenceName = getXmlAttribute(cur, Attributes::reference);
    const xmlNode *ref = NULL;
    if (!referenceName.empty()) {
        ref = getReference<VolumeTraits>(cur->parent, referenceName);
        if (ref == NULL) {
            ALOGE("%s: No reference Ptr found for %s", __func__, referenceName.c_str());
            return Status::fromStatusT(BAD_VALUE);
        }
    }

    Element volCurve = new VolumeCurve(deviceCategory, streamType);

    for (const xmlNode *child = referenceName.empty() ? cur->xmlChildrenNode : ref->xmlChildrenNode;
         child != NULL; child = child->next) {
        if (!xmlStrcmp(child->name, reinterpret_cast<const xmlChar*>(volumePointTag))) {
            auto pointDefinition = make_xmlUnique(xmlNodeListGetString(
                            child->doc, child->xmlChildrenNode, 1));
            if (pointDefinition == nullptr) {
                return Status::fromStatusT(BAD_VALUE);
            }
            ALOGV("%s: %s=%s",
                    __func__, tag, reinterpret_cast<const char*>(pointDefinition.get()));
            std::vector<int32_t> point;
            collectionFromString<DefaultTraits<int32_t>>(
                    reinterpret_cast<const char*>(pointDefinition.get()), point, ",");
            if (point.size() != 2) {
                ALOGE("%s: Invalid %s: %s", __func__, volumePointTag,
                        reinterpret_cast<const char*>(pointDefinition.get()));
                return Status::fromStatusT(BAD_VALUE);
            }
            volCurve->add(CurvePoint(point[0], point[1]));
        }
    }
    return volCurve;
}

status_t SurroundSoundTraits::deserialize(const xmlNode *root, AudioPolicyConfig *config)
{
    config->setDefaultSurroundFormats();
@@ -771,6 +851,14 @@ status_t PolicySerializer::deserialize(const char *configFile, AudioPolicyConfig
    }
    config->setHwModules(modules);

    // deserialize volume section
    VolumeTraits::Collection volumes;
    status = deserializeCollection<VolumeTraits>(root, &volumes, config);
    if (status != NO_ERROR) {
        return status;
    }
    config->setVolumes(volumes);

    // Global Configuration
    GlobalConfigTraits::deserialize(root, config);

Loading