1 /* 2 * Copyright (C) 2024 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "BluetoothHfpCodecsProvider.h" 18 19 #include <unordered_map> 20 21 namespace aidl { 22 namespace android { 23 namespace hardware { 24 namespace bluetooth { 25 namespace audio { 26 27 using hfp::setting::CodecType; 28 using hfp::setting::PathConfiguration; 29 30 static const char* kHfpCodecCapabilitiesFile = 31 "/vendor/etc/aidl/hfp/hfp_codec_capabilities.xml"; 32 33 std::optional<HfpOffloadSetting> ParseFromHfpOffloadSettingFile()34BluetoothHfpCodecsProvider::ParseFromHfpOffloadSettingFile() { 35 auto hfp_offload_setting = 36 hfp::setting::readHfpOffloadSetting(kHfpCodecCapabilitiesFile); 37 if (!hfp_offload_setting.has_value()) { 38 LOG(ERROR) << __func__ << ": Failed to read " << kHfpCodecCapabilitiesFile; 39 } 40 return hfp_offload_setting; 41 } 42 GetHfpAudioCodecInfo(const std::optional<HfpOffloadSetting> & hfp_offload_setting)43std::vector<CodecInfo> BluetoothHfpCodecsProvider::GetHfpAudioCodecInfo( 44 const std::optional<HfpOffloadSetting>& hfp_offload_setting) { 45 std::vector<CodecInfo> result; 46 if (!hfp_offload_setting.has_value()) return result; 47 48 // Convert path configuration into map 49 // Currently transport configuration is unused 50 if (!hfp_offload_setting.value().hasPathConfiguration() || 51 hfp_offload_setting.value().getPathConfiguration().empty()) { 52 LOG(WARNING) << __func__ << ": path configurations is empty"; 53 return result; 54 } 55 auto path_configurations = hfp_offload_setting.value().getPathConfiguration(); 56 std::unordered_map<std::string, PathConfiguration> path_config_map; 57 for (const auto& path_cfg : path_configurations) 58 if (path_cfg.hasName() && path_cfg.hasDataPath()) 59 path_config_map.insert(make_pair(path_cfg.getName(), path_cfg)); 60 61 for (const auto& cfg : hfp_offload_setting.value().getConfiguration()) { 62 auto input_path_cfg = path_config_map.find(cfg.getInputPathConfiguration()); 63 auto output_path_cfg = 64 path_config_map.find(cfg.getOutputPathConfiguration()); 65 if (input_path_cfg == path_config_map.end()) { 66 LOG(WARNING) << __func__ << ": Input path configuration not found: " 67 << cfg.getInputPathConfiguration(); 68 continue; 69 } 70 71 if (output_path_cfg == path_config_map.end()) { 72 LOG(WARNING) << __func__ << ": Output path configuration not found: " 73 << cfg.getOutputPathConfiguration(); 74 continue; 75 } 76 77 CodecInfo codec_info; 78 79 switch (cfg.getCodec()) { 80 case CodecType::LC3: 81 codec_info.id = CodecId::Core::LC3; 82 break; 83 case CodecType::MSBC: 84 codec_info.id = CodecId::Core::MSBC; 85 break; 86 case CodecType::CVSD: 87 codec_info.id = CodecId::Core::CVSD; 88 break; 89 default: 90 LOG(WARNING) << __func__ << ": Unknown codec from " << cfg.getName(); 91 codec_info.id = CodecId::Vendor(); 92 break; 93 } 94 codec_info.name = cfg.getName(); 95 96 codec_info.transport = 97 CodecInfo::Transport::make<CodecInfo::Transport::Tag::hfp>(); 98 99 auto& transport = 100 codec_info.transport.get<CodecInfo::Transport::Tag::hfp>(); 101 transport.useControllerCodec = cfg.getUseControllerCodec(); 102 transport.inputDataPath = input_path_cfg->second.getDataPath(); 103 transport.outputDataPath = output_path_cfg->second.getDataPath(); 104 105 result.push_back(codec_info); 106 } 107 LOG(INFO) << __func__ << ": Has " << result.size() << " codec info"; 108 return result; 109 } 110 111 } // namespace audio 112 } // namespace bluetooth 113 } // namespace hardware 114 } // namespace android 115 } // namespace aidl 116