blob: d61ec5a44b163b401e2686ff2c2839e5026009d2 [file] [log] [blame]
/*
* Copyright (C) 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "BluetoothHfpCodecsProvider.h"
#include <unordered_map>
namespace aidl {
namespace android {
namespace hardware {
namespace bluetooth {
namespace audio {
using hfp::setting::CodecType;
using hfp::setting::PathConfiguration;
static const char* kHfpCodecCapabilitiesFile =
"/vendor/etc/aidl/hfp/hfp_codec_capabilities.xml";
std::optional<HfpOffloadSetting>
BluetoothHfpCodecsProvider::ParseFromHfpOffloadSettingFile() {
auto hfp_offload_setting =
hfp::setting::readHfpOffloadSetting(kHfpCodecCapabilitiesFile);
if (!hfp_offload_setting.has_value()) {
LOG(ERROR) << __func__ << ": Failed to read " << kHfpCodecCapabilitiesFile;
}
return hfp_offload_setting;
}
std::vector<CodecInfo> BluetoothHfpCodecsProvider::GetHfpAudioCodecInfo(
const std::optional<HfpOffloadSetting>& hfp_offload_setting) {
std::vector<CodecInfo> result;
if (!hfp_offload_setting.has_value()) return result;
// Convert path configuration into map
// Currently transport configuration is unused
if (!hfp_offload_setting.value().hasPathConfiguration() ||
hfp_offload_setting.value().getPathConfiguration().empty()) {
LOG(WARNING) << __func__ << ": path configurations is empty";
return result;
}
auto path_configurations = hfp_offload_setting.value().getPathConfiguration();
std::unordered_map<std::string, PathConfiguration> path_config_map;
for (const auto& path_cfg : path_configurations)
if (path_cfg.hasName() && path_cfg.hasDataPath())
path_config_map.insert(make_pair(path_cfg.getName(), path_cfg));
for (const auto& cfg : hfp_offload_setting.value().getConfiguration()) {
auto input_path_cfg = path_config_map.find(cfg.getInputPathConfiguration());
auto output_path_cfg =
path_config_map.find(cfg.getOutputPathConfiguration());
if (input_path_cfg == path_config_map.end()) {
LOG(WARNING) << __func__ << ": Input path configuration not found: "
<< cfg.getInputPathConfiguration();
continue;
}
if (output_path_cfg == path_config_map.end()) {
LOG(WARNING) << __func__ << ": Output path configuration not found: "
<< cfg.getOutputPathConfiguration();
continue;
}
CodecInfo codec_info;
switch (cfg.getCodec()) {
case CodecType::LC3:
codec_info.id = CodecId::Core::LC3;
break;
case CodecType::MSBC:
codec_info.id = CodecId::Core::MSBC;
break;
case CodecType::CVSD:
codec_info.id = CodecId::Core::CVSD;
break;
default:
LOG(WARNING) << __func__ << ": Unknown codec from " << cfg.getName();
codec_info.id = CodecId::Vendor();
break;
}
codec_info.name = cfg.getName();
codec_info.transport =
CodecInfo::Transport::make<CodecInfo::Transport::Tag::hfp>();
auto& transport =
codec_info.transport.get<CodecInfo::Transport::Tag::hfp>();
transport.useControllerCodec = cfg.getUseControllerCodec();
transport.inputDataPath = input_path_cfg->second.getDataPath();
transport.outputDataPath = output_path_cfg->second.getDataPath();
result.push_back(codec_info);
}
LOG(INFO) << __func__ << ": Has " << result.size() << " codec info";
return result;
}
} // namespace audio
} // namespace bluetooth
} // namespace hardware
} // namespace android
} // namespace aidl