Loading bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp +126 −79 Original line number Diff line number Diff line Loading @@ -534,7 +534,8 @@ void LeAudioOffloadAudioProvider::filterRequirementAseDirectionConfiguration( direction_configurations, const std::vector<std::optional<AseDirectionRequirement>>& requirements, std::optional<std::vector<std::optional<AseDirectionConfiguration>>>& valid_direction_configurations) { valid_direction_configurations, bool isExact) { if (!direction_configurations.has_value()) return; if (!valid_direction_configurations.has_value()) { Loading @@ -542,6 +543,7 @@ void LeAudioOffloadAudioProvider::filterRequirementAseDirectionConfiguration( std::vector<std::optional<AseDirectionConfiguration>>(); } if (isExact) { // Exact matching process // Need to respect the number of device for (int i = 0; i < requirements.size(); ++i) { Loading @@ -552,8 +554,8 @@ void LeAudioOffloadAudioProvider::filterRequirementAseDirectionConfiguration( return; } auto cfg = direction_configuration.value(); if (!filterMatchedAseConfiguration(cfg.aseConfiguration, requirement.value().aseConfiguration)) { if (!filterMatchedAseConfiguration( cfg.aseConfiguration, requirement.value().aseConfiguration)) { valid_direction_configurations = std::nullopt; return; // No way to match } Loading @@ -577,7 +579,8 @@ void LeAudioOffloadAudioProvider::filterRequirementAseDirectionConfiguration( if (codec_cfg.getTag() == CodecSpecificConfigurationLtv::Tag::audioChannelAllocation) { codec_cfg .get<CodecSpecificConfigurationLtv::Tag::audioChannelAllocation>() .get<CodecSpecificConfigurationLtv::Tag:: audioChannelAllocation>() .bitmask = req_allocation_bitmask; break; } Loading @@ -592,6 +595,42 @@ void LeAudioOffloadAudioProvider::filterRequirementAseDirectionConfiguration( // Push to list if valid valid_direction_configurations.value().push_back(cfg); } } else { // Loose matching process for (auto& requirement : requirements) { if (!requirement.has_value()) continue; auto req_allocation_bitmask = getLeAudioAseConfigurationAllocationBitmask( requirement.value().aseConfiguration); auto req_channel_count = getCountFromBitmask(req_allocation_bitmask); auto temp = std::vector<AseDirectionConfiguration>(); for (auto direction_configuration : direction_configurations.value()) { if (!direction_configuration.has_value()) continue; if (!filterMatchedAseConfiguration( direction_configuration.value().aseConfiguration, requirement.value().aseConfiguration)) continue; // Valid if match any requirement. temp.push_back(direction_configuration.value()); } // Get the best matching config based on channel allocation auto total_cfg_channel_count = 0; auto req_valid_configs = getValidConfigurationsFromAllocation( req_allocation_bitmask, temp, isExact); // Count and check required channel counts for (auto& cfg : req_valid_configs) { total_cfg_channel_count += getCountFromBitmask( getLeAudioAseConfigurationAllocationBitmask(cfg.aseConfiguration)); valid_direction_configurations.value().push_back(cfg); } if (total_cfg_channel_count != req_channel_count) { valid_direction_configurations = std::nullopt; return; } } } } /* Get a new LeAudioAseConfigurationSetting by matching a setting with a Loading Loading @@ -650,8 +689,8 @@ LeAudioOffloadAudioProvider::getCapabilitiesMatchedAseConfigurationSettings( std::optional<LeAudioAseConfigurationSetting> LeAudioOffloadAudioProvider::getRequirementMatchedAseConfigurationSettings( IBluetoothAudioProvider::LeAudioAseConfigurationSetting& setting, const IBluetoothAudioProvider::LeAudioConfigurationRequirement& requirement) { const IBluetoothAudioProvider::LeAudioConfigurationRequirement& requirement, bool isExact) { // Create a new LeAudioAseConfigurationSetting to return // Make context the same as the requirement LeAudioAseConfigurationSetting filtered_setting{ Loading @@ -664,9 +703,10 @@ LeAudioOffloadAudioProvider::getRequirementMatchedAseConfigurationSettings( // is the number of device. // The exact matching process is as follow: // 1. Setting direction has the same number of cfg (ignore when null require) // 1. Setting direction has the same number of cfg (ignore when null // require) // 2. For each index, it's a 1-1 filter / mapping. if (isExact) { if (requirement.sinkAseRequirement.has_value() && requirement.sinkAseRequirement.value().size() != setting.sinkAseConfiguration.value().size()) { Loading @@ -678,11 +718,12 @@ LeAudioOffloadAudioProvider::getRequirementMatchedAseConfigurationSettings( setting.sourceAseConfiguration.value().size()) { return std::nullopt; } } if (requirement.sinkAseRequirement.has_value()) { filterRequirementAseDirectionConfiguration( setting.sinkAseConfiguration, requirement.sinkAseRequirement.value(), filtered_setting.sinkAseConfiguration); filtered_setting.sinkAseConfiguration, isExact); if (!filtered_setting.sinkAseConfiguration.has_value()) { return std::nullopt; } Loading @@ -692,7 +733,7 @@ LeAudioOffloadAudioProvider::getRequirementMatchedAseConfigurationSettings( filterRequirementAseDirectionConfiguration( setting.sourceAseConfiguration, requirement.sourceAseRequirement.value(), filtered_setting.sourceAseConfiguration); filtered_setting.sourceAseConfiguration, isExact); if (!filtered_setting.sourceAseConfiguration.has_value()) { return std::nullopt; } Loading @@ -706,9 +747,10 @@ LeAudioOffloadAudioProvider::matchWithRequirement( std::vector<IBluetoothAudioProvider::LeAudioAseConfigurationSetting>& matched_ase_configuration_settings, const IBluetoothAudioProvider::LeAudioConfigurationRequirement& requirement, bool isMatchContext) { bool isMatchContext, bool isExact) { LOG(INFO) << __func__ << ": Trying to match for the requirement " << requirement.toString() << ", match context = " << isMatchContext; << requirement.toString() << ", match context = " << isMatchContext << ", match exact = " << isExact; for (auto& setting : matched_ase_configuration_settings) { // Try to match context in metadata. if (isMatchContext) { Loading @@ -720,7 +762,8 @@ LeAudioOffloadAudioProvider::matchWithRequirement( } auto filtered_ase_configuration_setting = getRequirementMatchedAseConfigurationSettings(setting, requirement); getRequirementMatchedAseConfigurationSettings(setting, requirement, isExact); if (filtered_ase_configuration_setting.has_value()) { LOG(INFO) << __func__ << ": Result found: " << getSettingOutputString( Loading Loading @@ -811,28 +854,32 @@ ndk::ScopedAStatus LeAudioOffloadAudioProvider::getLeAudioAseConfiguration( // Matching priority list: // Preferred context - exact match with allocation // Preferred context - loose match with allocation // Any context - exact match with allocation auto matched_setting_with_context = matchWithRequirement( matched_ase_configuration_settings, requirement, true); if (matched_setting_with_context.has_value()) { result.push_back(matched_setting_with_context.value()); } else { auto matched_setting = matchWithRequirement( matched_ase_configuration_settings, requirement, false); // Any context - loose match with allocation bool found = false; for (bool match_context : {true, false}) { for (bool match_exact : {true, false}) { auto matched_setting = matchWithRequirement(matched_ase_configuration_settings, requirement, match_context, match_exact); if (matched_setting.has_value()) { result.push_back(matched_setting.value()); } else { // Cannot find a match for this requirement // Immediately return LOG(ERROR) << __func__ found = true; break; } } if (found) break; } if (!found) { LOG(ERROR) << __func__ << ": Cannot find any match for this requirement, exitting..."; result.clear(); *_aidl_return = result; return ndk::ScopedAStatus::ok(); } } } LOG(INFO) << __func__ << ": Found matches for all requirements!"; *_aidl_return = result; Loading bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.h +5 −3 Original line number Diff line number Diff line Loading @@ -139,7 +139,8 @@ class LeAudioOffloadAudioProvider : public BluetoothAudioProvider { direction_configurations, const std::vector<std::optional<AseDirectionRequirement>>& requirements, std::optional<std::vector<std::optional<AseDirectionConfiguration>>>& valid_direction_configurations); valid_direction_configurations, bool isExact); std::optional<LeAudioAseConfigurationSetting> getCapabilitiesMatchedAseConfigurationSettings( IBluetoothAudioProvider::LeAudioAseConfigurationSetting& setting, Loading @@ -149,7 +150,8 @@ class LeAudioOffloadAudioProvider : public BluetoothAudioProvider { getRequirementMatchedAseConfigurationSettings( IBluetoothAudioProvider::LeAudioAseConfigurationSetting& setting, const IBluetoothAudioProvider::LeAudioConfigurationRequirement& requirement); requirement, bool isExact); bool isMatchedQosRequirement(LeAudioAseQosConfiguration setting_qos, AseQosDirectionRequirement requirement_qos); std::optional<LeAudioBroadcastConfigurationSetting> Loading @@ -173,7 +175,7 @@ class LeAudioOffloadAudioProvider : public BluetoothAudioProvider { matched_ase_configuration_settings, const IBluetoothAudioProvider::LeAudioConfigurationRequirement& requirements, bool isMatchContext); bool isMatchContext, bool isExact); }; class LeAudioOffloadOutputAudioProvider : public LeAudioOffloadAudioProvider { Loading Loading
bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp +126 −79 Original line number Diff line number Diff line Loading @@ -534,7 +534,8 @@ void LeAudioOffloadAudioProvider::filterRequirementAseDirectionConfiguration( direction_configurations, const std::vector<std::optional<AseDirectionRequirement>>& requirements, std::optional<std::vector<std::optional<AseDirectionConfiguration>>>& valid_direction_configurations) { valid_direction_configurations, bool isExact) { if (!direction_configurations.has_value()) return; if (!valid_direction_configurations.has_value()) { Loading @@ -542,6 +543,7 @@ void LeAudioOffloadAudioProvider::filterRequirementAseDirectionConfiguration( std::vector<std::optional<AseDirectionConfiguration>>(); } if (isExact) { // Exact matching process // Need to respect the number of device for (int i = 0; i < requirements.size(); ++i) { Loading @@ -552,8 +554,8 @@ void LeAudioOffloadAudioProvider::filterRequirementAseDirectionConfiguration( return; } auto cfg = direction_configuration.value(); if (!filterMatchedAseConfiguration(cfg.aseConfiguration, requirement.value().aseConfiguration)) { if (!filterMatchedAseConfiguration( cfg.aseConfiguration, requirement.value().aseConfiguration)) { valid_direction_configurations = std::nullopt; return; // No way to match } Loading @@ -577,7 +579,8 @@ void LeAudioOffloadAudioProvider::filterRequirementAseDirectionConfiguration( if (codec_cfg.getTag() == CodecSpecificConfigurationLtv::Tag::audioChannelAllocation) { codec_cfg .get<CodecSpecificConfigurationLtv::Tag::audioChannelAllocation>() .get<CodecSpecificConfigurationLtv::Tag:: audioChannelAllocation>() .bitmask = req_allocation_bitmask; break; } Loading @@ -592,6 +595,42 @@ void LeAudioOffloadAudioProvider::filterRequirementAseDirectionConfiguration( // Push to list if valid valid_direction_configurations.value().push_back(cfg); } } else { // Loose matching process for (auto& requirement : requirements) { if (!requirement.has_value()) continue; auto req_allocation_bitmask = getLeAudioAseConfigurationAllocationBitmask( requirement.value().aseConfiguration); auto req_channel_count = getCountFromBitmask(req_allocation_bitmask); auto temp = std::vector<AseDirectionConfiguration>(); for (auto direction_configuration : direction_configurations.value()) { if (!direction_configuration.has_value()) continue; if (!filterMatchedAseConfiguration( direction_configuration.value().aseConfiguration, requirement.value().aseConfiguration)) continue; // Valid if match any requirement. temp.push_back(direction_configuration.value()); } // Get the best matching config based on channel allocation auto total_cfg_channel_count = 0; auto req_valid_configs = getValidConfigurationsFromAllocation( req_allocation_bitmask, temp, isExact); // Count and check required channel counts for (auto& cfg : req_valid_configs) { total_cfg_channel_count += getCountFromBitmask( getLeAudioAseConfigurationAllocationBitmask(cfg.aseConfiguration)); valid_direction_configurations.value().push_back(cfg); } if (total_cfg_channel_count != req_channel_count) { valid_direction_configurations = std::nullopt; return; } } } } /* Get a new LeAudioAseConfigurationSetting by matching a setting with a Loading Loading @@ -650,8 +689,8 @@ LeAudioOffloadAudioProvider::getCapabilitiesMatchedAseConfigurationSettings( std::optional<LeAudioAseConfigurationSetting> LeAudioOffloadAudioProvider::getRequirementMatchedAseConfigurationSettings( IBluetoothAudioProvider::LeAudioAseConfigurationSetting& setting, const IBluetoothAudioProvider::LeAudioConfigurationRequirement& requirement) { const IBluetoothAudioProvider::LeAudioConfigurationRequirement& requirement, bool isExact) { // Create a new LeAudioAseConfigurationSetting to return // Make context the same as the requirement LeAudioAseConfigurationSetting filtered_setting{ Loading @@ -664,9 +703,10 @@ LeAudioOffloadAudioProvider::getRequirementMatchedAseConfigurationSettings( // is the number of device. // The exact matching process is as follow: // 1. Setting direction has the same number of cfg (ignore when null require) // 1. Setting direction has the same number of cfg (ignore when null // require) // 2. For each index, it's a 1-1 filter / mapping. if (isExact) { if (requirement.sinkAseRequirement.has_value() && requirement.sinkAseRequirement.value().size() != setting.sinkAseConfiguration.value().size()) { Loading @@ -678,11 +718,12 @@ LeAudioOffloadAudioProvider::getRequirementMatchedAseConfigurationSettings( setting.sourceAseConfiguration.value().size()) { return std::nullopt; } } if (requirement.sinkAseRequirement.has_value()) { filterRequirementAseDirectionConfiguration( setting.sinkAseConfiguration, requirement.sinkAseRequirement.value(), filtered_setting.sinkAseConfiguration); filtered_setting.sinkAseConfiguration, isExact); if (!filtered_setting.sinkAseConfiguration.has_value()) { return std::nullopt; } Loading @@ -692,7 +733,7 @@ LeAudioOffloadAudioProvider::getRequirementMatchedAseConfigurationSettings( filterRequirementAseDirectionConfiguration( setting.sourceAseConfiguration, requirement.sourceAseRequirement.value(), filtered_setting.sourceAseConfiguration); filtered_setting.sourceAseConfiguration, isExact); if (!filtered_setting.sourceAseConfiguration.has_value()) { return std::nullopt; } Loading @@ -706,9 +747,10 @@ LeAudioOffloadAudioProvider::matchWithRequirement( std::vector<IBluetoothAudioProvider::LeAudioAseConfigurationSetting>& matched_ase_configuration_settings, const IBluetoothAudioProvider::LeAudioConfigurationRequirement& requirement, bool isMatchContext) { bool isMatchContext, bool isExact) { LOG(INFO) << __func__ << ": Trying to match for the requirement " << requirement.toString() << ", match context = " << isMatchContext; << requirement.toString() << ", match context = " << isMatchContext << ", match exact = " << isExact; for (auto& setting : matched_ase_configuration_settings) { // Try to match context in metadata. if (isMatchContext) { Loading @@ -720,7 +762,8 @@ LeAudioOffloadAudioProvider::matchWithRequirement( } auto filtered_ase_configuration_setting = getRequirementMatchedAseConfigurationSettings(setting, requirement); getRequirementMatchedAseConfigurationSettings(setting, requirement, isExact); if (filtered_ase_configuration_setting.has_value()) { LOG(INFO) << __func__ << ": Result found: " << getSettingOutputString( Loading Loading @@ -811,28 +854,32 @@ ndk::ScopedAStatus LeAudioOffloadAudioProvider::getLeAudioAseConfiguration( // Matching priority list: // Preferred context - exact match with allocation // Preferred context - loose match with allocation // Any context - exact match with allocation auto matched_setting_with_context = matchWithRequirement( matched_ase_configuration_settings, requirement, true); if (matched_setting_with_context.has_value()) { result.push_back(matched_setting_with_context.value()); } else { auto matched_setting = matchWithRequirement( matched_ase_configuration_settings, requirement, false); // Any context - loose match with allocation bool found = false; for (bool match_context : {true, false}) { for (bool match_exact : {true, false}) { auto matched_setting = matchWithRequirement(matched_ase_configuration_settings, requirement, match_context, match_exact); if (matched_setting.has_value()) { result.push_back(matched_setting.value()); } else { // Cannot find a match for this requirement // Immediately return LOG(ERROR) << __func__ found = true; break; } } if (found) break; } if (!found) { LOG(ERROR) << __func__ << ": Cannot find any match for this requirement, exitting..."; result.clear(); *_aidl_return = result; return ndk::ScopedAStatus::ok(); } } } LOG(INFO) << __func__ << ": Found matches for all requirements!"; *_aidl_return = result; Loading
bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.h +5 −3 Original line number Diff line number Diff line Loading @@ -139,7 +139,8 @@ class LeAudioOffloadAudioProvider : public BluetoothAudioProvider { direction_configurations, const std::vector<std::optional<AseDirectionRequirement>>& requirements, std::optional<std::vector<std::optional<AseDirectionConfiguration>>>& valid_direction_configurations); valid_direction_configurations, bool isExact); std::optional<LeAudioAseConfigurationSetting> getCapabilitiesMatchedAseConfigurationSettings( IBluetoothAudioProvider::LeAudioAseConfigurationSetting& setting, Loading @@ -149,7 +150,8 @@ class LeAudioOffloadAudioProvider : public BluetoothAudioProvider { getRequirementMatchedAseConfigurationSettings( IBluetoothAudioProvider::LeAudioAseConfigurationSetting& setting, const IBluetoothAudioProvider::LeAudioConfigurationRequirement& requirement); requirement, bool isExact); bool isMatchedQosRequirement(LeAudioAseQosConfiguration setting_qos, AseQosDirectionRequirement requirement_qos); std::optional<LeAudioBroadcastConfigurationSetting> Loading @@ -173,7 +175,7 @@ class LeAudioOffloadAudioProvider : public BluetoothAudioProvider { matched_ase_configuration_settings, const IBluetoothAudioProvider::LeAudioConfigurationRequirement& requirements, bool isMatchContext); bool isMatchContext, bool isExact); }; class LeAudioOffloadOutputAudioProvider : public LeAudioOffloadAudioProvider { Loading