Loading media/libaudiofoundation/AudioProfile.cpp +15 −6 Original line number Diff line number Diff line Loading @@ -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(); } Loading Loading @@ -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; } } Loading @@ -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, Loading media/libaudiofoundation/include/media/AudioProfile.h +3 −2 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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>, Loading services/audiopolicy/managerdefault/AudioPolicyManager.cpp +47 −15 Original line number Diff line number Diff line Loading @@ -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, Loading Loading @@ -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; } Loading services/audiopolicy/managerdefault/AudioPolicyManager.h +5 −0 Original line number Diff line number Diff line Loading @@ -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, Loading Loading @@ -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); }; }; services/audiopolicy/tests/audiopolicymanager_tests.cpp +50 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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; Loading Loading
media/libaudiofoundation/AudioProfile.cpp +15 −6 Original line number Diff line number Diff line Loading @@ -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(); } Loading Loading @@ -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; } } Loading @@ -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, Loading
media/libaudiofoundation/include/media/AudioProfile.h +3 −2 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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>, Loading
services/audiopolicy/managerdefault/AudioPolicyManager.cpp +47 −15 Original line number Diff line number Diff line Loading @@ -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, Loading Loading @@ -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; } Loading
services/audiopolicy/managerdefault/AudioPolicyManager.h +5 −0 Original line number Diff line number Diff line Loading @@ -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, Loading Loading @@ -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); }; };
services/audiopolicy/tests/audiopolicymanager_tests.cpp +50 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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; Loading