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

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

Merge "Add MSD support in getDirectProfilesForAttributes"

parents 6cee89b0 94d9441f
Loading
Loading
Loading
Loading
+15 −6
Original line number Diff line number Diff line
@@ -127,16 +127,17 @@ void AudioProfile::dump(std::string *dst, int spaces) const
             "%*s%s\n", spaces, "", audio_encapsulation_type_to_string(mEncapsulationType)));
}

bool AudioProfile::equals(const sp<AudioProfile>& other) const
bool AudioProfile::equals(const sp<AudioProfile>& other, bool ignoreDynamicFlags) const
{
    return other != nullptr &&
           mName.compare(other->mName) == 0 &&
           mFormat == other->getFormat() &&
           mChannelMasks == other->getChannels() &&
           mSamplingRates == other->getSampleRates() &&
           mIsDynamicFormat == other->isDynamicFormat() &&
           (ignoreDynamicFlags ||
               (mIsDynamicFormat == other->isDynamicFormat() &&
               mIsDynamicChannels == other->isDynamicChannels() &&
           mIsDynamicRate == other->isDynamicRate() &&
               mIsDynamicRate == other->isDynamicRate())) &&
           mEncapsulationType == other->getEncapsulationType();
}

@@ -326,10 +327,10 @@ bool AudioProfileVector::hasDynamicRateFor(audio_format_t format) const
    return false;
}

bool AudioProfileVector::contains(const sp<AudioProfile>& profile) const
bool AudioProfileVector::contains(const sp<AudioProfile>& profile, bool ignoreDynamicFlags) const
{
    for (const auto& audioProfile : *this) {
        if (audioProfile->equals(profile)) {
        if (audioProfile->equals(profile, ignoreDynamicFlags)) {
            return true;
        }
    }
@@ -356,6 +357,14 @@ bool AudioProfileVector::equals(const AudioProfileVector& other) const
                      });
}

void AudioProfileVector::addAllValidProfiles(const AudioProfileVector& audioProfiles) {
    for (const auto& audioProfile : audioProfiles) {
        if (audioProfile->isValid() && !contains(audioProfile, true /*ignoreDynamicFlags*/)) {
            add(audioProfile);
        }
    }
}

ConversionResult<AudioProfileVector>
aidl2legacy_AudioProfileVector(const AudioProfileVector::Aidl& aidl, bool isInput) {
    return convertContainers<AudioProfileVector>(aidl.first, aidl.second,
+3 −2
Original line number Diff line number Diff line
@@ -78,7 +78,7 @@ public:

    void dump(std::string *dst, int spaces) const;

    bool equals(const sp<AudioProfile>& other) const;
    bool equals(const sp<AudioProfile>& other, bool ignoreDynamicFlags = false) const;

    using Aidl = std::pair<media::audio::common::AudioProfile, media::AudioProfileSys>;
    ConversionResult<Aidl> toParcelable(bool isInput) const;
@@ -139,11 +139,12 @@ public:
    bool hasDynamicProfile() const;
    bool hasDynamicRateFor(audio_format_t format) const;

    bool contains(const sp<AudioProfile>& profile) const;
    bool contains(const sp<AudioProfile>& profile, bool ignoreDynamicFlags = false) const;

    virtual void dump(std::string *dst, int spaces) const;

    bool equals(const AudioProfileVector& other) const;
    void addAllValidProfiles(const AudioProfileVector& audioProfiles);

    using Aidl = std::pair<
            std::vector<media::audio::common::AudioProfile>,
+47 −15
Original line number Diff line number Diff line
@@ -1709,6 +1709,28 @@ void AudioPolicyManager::releaseMsdOutputPatches(const DeviceVector& devices) {
    }
}

bool AudioPolicyManager::msdHasPatchesToAllDevices(const AudioDeviceTypeAddrVector& devices) {
    DeviceVector devicesToCheck = mOutputDevicesAll.getDevicesFromDeviceTypeAddrVec(devices);
    AudioPatchCollection msdPatches = getMsdOutputPatches();
    for (size_t i = 0; i < msdPatches.size(); i++) {
        const auto& patch = msdPatches[i];
        for (size_t j = 0; j < patch->mPatch.num_sinks; ++j) {
            const struct audio_port_config *sink = &patch->mPatch.sinks[j];
            if (sink->type == AUDIO_PORT_TYPE_DEVICE) {
                const auto& foundDevice = devicesToCheck.getDevice(
                    sink->ext.device.type, String8(sink->ext.device.address), AUDIO_FORMAT_DEFAULT);
                if (foundDevice != nullptr) {
                    devicesToCheck.remove(foundDevice);
                    if (devicesToCheck.isEmpty()) {
                        return true;
                    }
                }
            }
        }
    }
    return false;
}

audio_io_handle_t AudioPolicyManager::selectOutput(const SortedVector<audio_io_handle_t>& outputs,
                                                   audio_output_flags_t flags,
                                                   audio_format_t format,
@@ -3895,31 +3917,41 @@ status_t AudioPolicyManager::getDirectProfilesForAttributes(const audio_attribut
    }

    for (const auto& hwModule : mHwModules) {
        for (const auto& curProfile : hwModule->getOutputProfiles()) {
            if (!curProfile->asAudioPort()->isDirectOutput()) {
        // the MSD module checks for different conditions
        if (strcmp(hwModule->getName(), AUDIO_HARDWARE_MODULE_ID_MSD) == 0) {
            continue;
        }
            // Allow only profiles that support all the available and routed devices
            DeviceVector supportedDevices = curProfile->getSupportedDevices();
            if (supportedDevices.getDevicesFromDeviceTypeAddrVec(devices).size()
        for (const auto& outputProfile : hwModule->getOutputProfiles()) {
            if (!outputProfile->asAudioPort()->isDirectOutput()) {
                continue;
            }
            // allow only profiles that support all the available and routed devices
            if (outputProfile->getSupportedDevices().getDevicesFromDeviceTypeAddrVec(devices).size()
                    != devices.size()) {
                continue;
            }
            audioProfilesVector.addAllValidProfiles(
                    outputProfile->asAudioPort()->getAudioProfiles());
        }
    }

            const auto audioProfiles = curProfile->asAudioPort()->getAudioProfiles();
            ALOGV("%s: found direct profile (%s) with %zu audio profiles.",
                __func__, curProfile->getTagName().c_str(), audioProfiles.size());
            for (const auto& audioProfile : audioProfiles) {
                if (audioProfile->isValid() && !audioProfilesVector.contains(audioProfile)
                // TODO - why do we have same PCM format with both dynamic and non dynamic format
                    && audioProfile->isDynamicFormat()) {
                    ALOGV("%s: adding audio profile with encoding (%d).",
                        __func__, audioProfile->getFormat());
                    audioProfilesVector.add(audioProfile);
    // add the direct profiles from MSD if present and has audio patches to all the output(s)
    const auto& msdModule = mHwModules.getModuleFromName(AUDIO_HARDWARE_MODULE_ID_MSD);
    if (msdModule != nullptr) {
        if (msdHasPatchesToAllDevices(devices)) {
            ALOGV("%s: MSD audio patches set to all output devices.", __func__);
            for (const auto& outputProfile : msdModule->getOutputProfiles()) {
                if (!outputProfile->asAudioPort()->isDirectOutput()) {
                    continue;
                }
                audioProfilesVector.addAllValidProfiles(
                        outputProfile->asAudioPort()->getAudioProfiles());
            }
        } else {
            ALOGV("%s: MSD audio patches NOT set to all output devices.", __func__);
        }
    }

    return NO_ERROR;
}

+5 −0
Original line number Diff line number Diff line
@@ -909,6 +909,7 @@ protected:
        PatchBuilder buildMsdPatch(bool msdIsSource, const sp<DeviceDescriptor> &device) const;
        status_t setMsdOutputPatches(const DeviceVector *outputDevices = nullptr);
        void releaseMsdOutputPatches(const DeviceVector& devices);
        bool msdHasPatchesToAllDevices(const AudioDeviceTypeAddrVector& devices);

        // Overload of setDeviceConnectionState()
        status_t setDeviceConnectionState(audio_devices_t deviceType,
@@ -1120,6 +1121,10 @@ private:
        bool isOffloadPossible(const audio_offload_info_t& offloadInfo,
                               bool durationIgnored = false);

        // adds the profiles from the outputProfile to the passed audioProfilesVector
        // without duplicating them if already present
        void addPortProfilesToVector(sp<IOProfile> outputProfile,
                                    AudioProfileVector& audioProfilesVector);
};

};
+50 −0
Original line number Diff line number Diff line
@@ -373,6 +373,7 @@ class AudioPolicyManagerTestMsd : public AudioPolicyManagerTest,
  protected:
    void SetUpManagerConfig() override;
    void TearDown() override;
    AudioProfileVector getDirectProfilesForAttributes(const audio_attributes_t& attr);

    sp<DeviceDescriptor> mMsdOutputDevice;
    sp<DeviceDescriptor> mMsdInputDevice;
@@ -502,6 +503,13 @@ void AudioPolicyManagerTestMsd::TearDown() {
    AudioPolicyManagerTest::TearDown();
}

AudioProfileVector AudioPolicyManagerTestMsd::getDirectProfilesForAttributes(
                                                    const audio_attributes_t& attr) {
    AudioProfileVector audioProfilesVector;
    mManager->getDirectProfilesForAttributes(&attr, audioProfilesVector);
    return audioProfilesVector;
}

TEST_P(AudioPolicyManagerTestMsd, InitSuccess) {
    ASSERT_TRUE(mMsdOutputDevice);
    ASSERT_TRUE(mMsdInputDevice);
@@ -642,6 +650,48 @@ TEST_P(AudioPolicyManagerTestMsd, PatchCreationFromHdmiInToMsd) {
    ASSERT_EQ(1, patchCount.deltaFromSnapshot());
}

TEST_P(AudioPolicyManagerTestMsd, GetDirectProfilesForAttributesWithMsd) {
    const audio_attributes_t attr = {
        AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_UNKNOWN,
        AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};

    // count expected direct profiles for the default device
    int countDirectProfilesPrimary = 0;
    const auto& primary = mManager->getConfig().getHwModules()
            .getModuleFromName(AUDIO_HARDWARE_MODULE_ID_PRIMARY);
    for (const auto outputProfile : primary->getOutputProfiles()) {
        if (outputProfile->asAudioPort()->isDirectOutput()) {
            countDirectProfilesPrimary += outputProfile->asAudioPort()->getAudioProfiles().size();
        }
    }

    // count expected direct profiles for the msd device
    int countDirectProfilesMsd = 0;
    const auto& msd = mManager->getConfig().getHwModules()
            .getModuleFromName(AUDIO_HARDWARE_MODULE_ID_MSD);
    for (const auto outputProfile : msd->getOutputProfiles()) {
        if (outputProfile->asAudioPort()->isDirectOutput()) {
            countDirectProfilesMsd += outputProfile->asAudioPort()->getAudioProfiles().size();
        }
    }

    // before setting up MSD audio patches we only have the primary hal direct profiles
    ASSERT_EQ(countDirectProfilesPrimary, getDirectProfilesForAttributes(attr).size());

    DeviceVector outputDevices = mManager->getAvailableOutputDevices();
    // Remove MSD output device to avoid patching to itself
    outputDevices.remove(mMsdOutputDevice);
    mManager->setMsdOutputPatches(&outputDevices);

    // after setting up MSD audio patches the MSD direct profiles are added
    ASSERT_EQ(countDirectProfilesPrimary + countDirectProfilesMsd,
                getDirectProfilesForAttributes(attr).size());

    mManager->releaseMsdOutputPatches(outputDevices);
    // releasing the MSD audio patches gets us back to the primary hal direct profiles only
    ASSERT_EQ(countDirectProfilesPrimary, getDirectProfilesForAttributes(attr).size());
}

class AudioPolicyManagerTestWithConfigurationFile : public AudioPolicyManagerTest {
protected:
    void SetUpManagerConfig() override;