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

Commit aca677cf authored by François Gaffie's avatar François Gaffie Committed by Eric Laurent
Browse files

audiopolicy: common: add several helper function on DeviceDesc



-Add another DeviceVector constructor to simplify usage
-report tagname as port name
-migrate API from apm
-search/filter helpers

Test: Audio smoke tests.
Test: CTS tests for AudioRecord, AudioTrack and AudioEffect

Change-Id: Ie37a2d9db2e8a15a37743e7129159fa77a4c6b51
Signed-off-by: default avatarFrançois Gaffie <francois.gaffie@renault.com>
parent 2b167173
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -116,6 +116,7 @@ public:
    audio_module_handle_t getModuleHandle() const;
    uint32_t getModuleVersionMajor() const;
    const char *getModuleName() const;
    sp<HwModule> getModule() const { return mModule; }

    bool useInputChannelMask() const
    {
@@ -137,12 +138,12 @@ public:
    void log(const char* indent) const;

    AudioGainCollection mGains; // gain controllers
    sp<HwModule> mModule;                 // audio HW module exposing this I/O stream

private:
    void pickChannelMask(audio_channel_mask_t &channelMask, const ChannelsVector &channelMasks) const;
    void pickSamplingRate(uint32_t &rate,const SampleRateVector &samplingRates) const;

    sp<HwModule> mModule;                 // audio HW module exposing this I/O stream
    String8  mName;
    audio_port_type_t mType;
    audio_port_role_t mRole;
+82 −6
Original line number Diff line number Diff line
@@ -39,6 +39,8 @@ public:
    virtual const String8 getTagName() const { return mTagName; }

    audio_devices_t type() const { return mDeviceType; }
    String8 address() const { return mAddress; }
    void setAddress(const String8 &address) { mAddress = address; }

    const FormatVector& encodedFormats() const { return mEncodedFormats; }

@@ -57,39 +59,113 @@ public:
    audio_port_handle_t getId() const;
    void dump(String8 *dst, int spaces, int index, bool verbose = true) const;
    void log() const;

    String8 mAddress;
    std::string toString() const;

private:
    String8 mAddress{""};
    String8 mTagName; // Unique human readable identifier for a device port found in conf file.
    audio_devices_t     mDeviceType;
    FormatVector        mEncodedFormats;
    audio_port_handle_t mId;

friend class DeviceVector;
    audio_port_handle_t mId = AUDIO_PORT_HANDLE_NONE;
};

class DeviceVector : public SortedVector<sp<DeviceDescriptor> >
{
public:
    DeviceVector() : SortedVector(), mDeviceTypes(AUDIO_DEVICE_NONE) {}
    explicit DeviceVector(const sp<DeviceDescriptor>& item) : DeviceVector()
    {
        add(item);
    }

    ssize_t add(const sp<DeviceDescriptor>& item);
    void add(const DeviceVector &devices);
    ssize_t remove(const sp<DeviceDescriptor>& item);
    void remove(const DeviceVector &devices);
    ssize_t indexOf(const sp<DeviceDescriptor>& item) const;

    audio_devices_t types() const { return mDeviceTypes; }

    // If 'address' is empty, a device with a non-empty address may be returned
    // if there is no device with the specified 'type' and empty address.
    sp<DeviceDescriptor> getDevice(audio_devices_t type, const String8 &address) const;
    sp<DeviceDescriptor> getDevice(audio_devices_t type, const String8 &address = {}) const;
    DeviceVector getDevicesFromTypeMask(audio_devices_t types) const;

    /**
     * @brief getDeviceFromId
     * @param id of the DeviceDescriptor to seach (aka Port handle).
     * @return DeviceDescriptor associated to port id if found, nullptr otherwise. If the id is
     * equal to AUDIO_PORT_HANDLE_NONE, it also returns a nullptr.
     */
    sp<DeviceDescriptor> getDeviceFromId(audio_port_handle_t id) const;
    sp<DeviceDescriptor> getDeviceFromTagName(const String8 &tagName) const;
    DeviceVector getDevicesFromHwModule(audio_module_handle_t moduleHandle) const;
    audio_devices_t getDeviceTypesFromHwModule(audio_module_handle_t moduleHandle) const;

    bool contains(const sp<DeviceDescriptor>& item) const { return indexOf(item) >= 0; }

    /**
     * @brief containsAtLeastOne
     * @param devices vector of devices to check against.
     * @return true if the DeviceVector contains at list one of the devices from the given vector.
     */
    bool containsAtLeastOne(const DeviceVector &devices) const;

    /**
     * @brief containsAllDevices
     * @param devices vector of devices to check against.
     * @return true if the DeviceVector contains all the devices from the given vector
     */
    bool containsAllDevices(const DeviceVector &devices) const;

    /**
     * @brief filter the devices supported by this collection against another collection
     * @param devices to filter against
     * @return
     */
    DeviceVector filter(const DeviceVector &devices) const;

    /**
     * @brief merge two vectors. As SortedVector Implementation is buggy (it does not check the size
     * of the destination vector, only of the source, it provides a safe implementation
     * @param devices source device vector to merge with
     * @return size of the merged vector.
     */
    ssize_t merge(const DeviceVector &devices)
    {
        if (isEmpty()) {
            add(devices);
            return size();
        }
        return SortedVector::merge(devices);
    }

    /**
     * @brief operator == DeviceVector are equals if all the DeviceDescriptor can be found (aka
     * DeviceDescriptor with same type and address) and the vector has same size.
     * @param right DeviceVector to compare to.
     * @return true if right contains the same device and has the same size.
     */
    bool operator==(const DeviceVector &right) const
    {
        if (size() != right.size()) {
            return false;
        }
        for (const auto &device : *this) {
            if (right.indexOf(device) < 0) {
                return false;
            }
        }
        return true;
    }

    bool operator!=(const DeviceVector &right) const
    {
        return !operator==(right);
    }

    std::string toString() const;

    void dump(String8 *dst, const String8 &tag, int spaces = 0, bool verbose = true) const;

private:
+1 −1
Original line number Diff line number Diff line
@@ -88,7 +88,7 @@ public:

    bool supportDeviceAddress(const String8 &address) const
    {
        return mSupportedDevices[0]->mAddress == address;
        return mSupportedDevices[0]->address() == address;
    }

    // chose first device present in mSupportedDevices also part of deviceType
+2 −2
Original line number Diff line number Diff line
@@ -698,8 +698,8 @@ bool SwAudioOutputCollection::isA2dpOffloadedOnPrimary() const
    sp<SwAudioOutputDescriptor> primaryOutput = getPrimaryOutput();

    if ((primaryOutput != NULL) && (primaryOutput->mProfile != NULL)
        && (primaryOutput->mProfile->mModule != NULL)) {
        sp<HwModule> primaryHwModule = primaryOutput->mProfile->mModule;
        && (primaryOutput->mProfile->getModule() != NULL)) {
        sp<HwModule> primaryHwModule = primaryOutput->mProfile->getModule();
        Vector <sp<IOProfile>> primaryHwModuleOutputProfiles =
                                   primaryHwModule->getOutputProfiles();
        for (size_t i = 0; i < primaryHwModuleOutputProfiles.size(); i++) {
+62 −11
Original line number Diff line number Diff line
@@ -35,7 +35,7 @@ DeviceDescriptor::DeviceDescriptor(audio_devices_t type, const FormatVector &enc
    AudioPort(String8(""), AUDIO_PORT_TYPE_DEVICE,
              audio_is_output_device(type) ? AUDIO_PORT_ROLE_SINK :
                                             AUDIO_PORT_ROLE_SOURCE),
    mAddress(""), mTagName(tagName), mDeviceType(type), mEncodedFormats(encodedFormats), mId(0)
    mTagName(tagName), mDeviceType(type), mEncodedFormats(encodedFormats)
{
    if (type == AUDIO_DEVICE_IN_REMOTE_SUBMIX || type == AUDIO_DEVICE_OUT_REMOTE_SUBMIX ) {
        mAddress = String8("0");
@@ -132,6 +132,13 @@ ssize_t DeviceVector::remove(const sp<DeviceDescriptor>& item)
    return ret;
}

void DeviceVector::remove(const DeviceVector &devices)
{
    for (const auto& device : devices) {
        remove(device);
    }
}

DeviceVector DeviceVector::getDevicesFromHwModule(audio_module_handle_t moduleHandle) const
{
    DeviceVector devices;
@@ -159,9 +166,9 @@ sp<DeviceDescriptor> DeviceVector::getDevice(audio_devices_t type, const String8
    sp<DeviceDescriptor> device;
    for (size_t i = 0; i < size(); i++) {
        if (itemAt(i)->type() == type) {
            if (address == "" || itemAt(i)->mAddress == address) {
            if (address == "" || itemAt(i)->address() == address) {
                device = itemAt(i);
                if (itemAt(i)->mAddress == address) {
                if (itemAt(i)->address() == address) {
                    break;
                }
            }
@@ -174,11 +181,13 @@ sp<DeviceDescriptor> DeviceVector::getDevice(audio_devices_t type, const String8

sp<DeviceDescriptor> DeviceVector::getDeviceFromId(audio_port_handle_t id) const
{
    if (id != AUDIO_PORT_HANDLE_NONE) {
        for (const auto& device : *this) {
            if (device->getId() == id) {
                return device;
            }
        }
    }
    return nullptr;
}

@@ -188,8 +197,8 @@ DeviceVector DeviceVector::getDevicesFromTypeMask(audio_devices_t type) const
    bool isOutput = audio_is_output_devices(type);
    type &= ~AUDIO_DEVICE_BIT_IN;
    for (size_t i = 0; (i < size()) && (type != AUDIO_DEVICE_NONE); i++) {
        bool curIsOutput = audio_is_output_devices(itemAt(i)->mDeviceType);
        audio_devices_t curType = itemAt(i)->mDeviceType & ~AUDIO_DEVICE_BIT_IN;
        bool curIsOutput = audio_is_output_devices(itemAt(i)->type());
        audio_devices_t curType = itemAt(i)->type() & ~AUDIO_DEVICE_BIT_IN;
        if ((isOutput == curIsOutput) && ((type & curType) != 0)) {
            devices.add(itemAt(i));
            type &= ~curType;
@@ -251,8 +260,7 @@ void DeviceDescriptor::toAudioPortConfig(struct audio_port_config *dstConfig,
    // without the test?
    // This has been demonstrated to NOT be true (at start up)
    // ALOG_ASSERT(mModule != NULL);
    dstConfig->ext.device.hw_module =
            mModule != 0 ? mModule->getHandle() : AUDIO_MODULE_HANDLE_NONE;
    dstConfig->ext.device.hw_module = getModuleHandle();
    (void)audio_utils_strlcpy_zerofill(dstConfig->ext.device.address, mAddress.string());
}

@@ -263,7 +271,7 @@ void DeviceDescriptor::toAudioPort(struct audio_port *port) const
    port->id = mId;
    toAudioPortConfig(&port->active_config);
    port->ext.device.type = mDeviceType;
    port->ext.device.hw_module = mModule->getHandle();
    port->ext.device.hw_module = getModuleHandle();
    (void)audio_utils_strlcpy_zerofill(port->ext.device.address, mAddress.string());
}

@@ -294,6 +302,49 @@ void DeviceDescriptor::dump(String8 *dst, int spaces, int index, bool verbose) c
    AudioPort::dump(dst, spaces, verbose);
}

std::string DeviceDescriptor::toString() const
{
    std::stringstream sstream;
    sstream << "type:0x" << std::hex << type() << ",@:" << mAddress;
    return sstream.str();
}

std::string DeviceVector::toString() const
{
    if (isEmpty()) {
        return {"AUDIO_DEVICE_NONE"};
    }
    std::string result = {"{"};
    for (const auto &device : *this) {
        if (device != *begin()) {
           result += ";";
        }
        result += device->toString();
    }
    return result + "}";
}

DeviceVector DeviceVector::filter(const DeviceVector &devices) const
{
    DeviceVector filteredDevices;
    for (const auto &device : *this) {
        if (devices.contains(device)) {
            filteredDevices.add(device);
        }
    }
    return filteredDevices;
}

bool DeviceVector::containsAtLeastOne(const DeviceVector &devices) const
{
    return !filter(devices).isEmpty();
}

bool DeviceVector::containsAllDevices(const DeviceVector &devices) const
{
    return filter(devices).size() == devices.size();
}

void DeviceDescriptor::log() const
{
    std::string device;
Loading