数据成员
AudioPolicyService:service 结构
AudioPolicyManager:manager结构
AudioPolicyClient(继承AudioPolicyClientInterface):为APM提供service调用接口
EngineInstance:Audio Policy Engine Interface,管理设备选择策略和音量配置等
关键函数
初始化流程
1. AudioPolicyService::onFirstRef
{
{
/* 创建两个audio commad线程 */
// start audio commands thread
mAudioCommandThread = new AudioCommandThread(String8("ApmAudio"), this);
// start output activity command thread
mOutputCommandThread = new AudioCommandThread(String8("ApmOutput"), this);
/* 创建APM实例 */
mAudioPolicyClient = new AudioPolicyClient(this);
mAudioPolicyManager = createAudioPolicyManager(mAudioPolicyClient);
}
/* 加载audio effect xml配置 */
// load audio processing modules
sp<AudioPolicyEffects> audioPolicyEffects = new AudioPolicyEffects();
……
}
2. AudioPolicyManager::loadConfig
createAudioPolicyManager函数,创建AudioPolicyManager实例时调用
用于解析audio_policy_configuration.xml文件
mHwModulesAll | 所有audio hw module |
mOutputDevicesAll/mInputDevicesAll | xml配置的所有连接输出/输入设备,xml中attachedDevices提取 |
mAvailableOutputDevices mAvailableInputDevices | 可用的输出/输入设备 |
mDefaultOutputDevice | 默认输出设备,xml中defaultOutputDevice提取 |
mOutputProfiles/mInputProfiles | 音频IO配置,xml中defaultOutputDevice提取mixPort |
mDeclaredDevices | 音频设备端口,xml中defaultOutputDevice提取devicePort |
mRoutes | 音频路径,xml中defaultOutputDevice提取route |
mSupportedDevices | profile连接的设备,根据route提去 refreshSupportedDevices实现 |
3. AudioPolicyManager::initialize
{
/* 加载audio policy engine 库,并创建实例 */
{
auto engLib = EngineLibrary::load(
"libaudiopolicyengine" + getConfig().getEngineLibraryNameSuffix() + ".so");
……
mEngine = engLib->createEngine();
……
}
mEngine->setObserver(this);
status_t status = mEngine->initCheck();
……
/* 根据所有的attach devices,创建output */
// after parsing the config, mOutputDevicesAll and mInputDevicesAll contain all known devices;
// open all output streams needed to access attached devices
onNewAudioModulesAvailableInt(nullptr /*newDevices*/);
……
updateDevicesAndOutputs();
return status;
}
4. EngineBase::loadAudioPolicyEngineConfig
通过createEngineInstance函数,创建Engine::Engine时调用
{
/* 解析engine xml,通常不存在,使用默认配置 */
auto result = engineConfig::parse();
if (result.parsedConfig == nullptr) {
ALOGW("%s: No configuration found, using default matching phone experience.", __FUNCTION__);
engineConfig::Config config = gDefaultEngineConfig;
android::status_t ret = engineConfig::parseLegacyVolumes(config.volumeGroups);
result = {std::make_unique<engineConfig::Config>(config),
static_cast<size_t>(ret == NO_ERROR ? 0 : 1)};
} else {
// Append for internal use only volume groups (e.g. rerouting/patch)
result.parsedConfig->volumeGroups.insert(
std::end(result.parsedConfig->volumeGroups),
std::begin(gSystemVolumeGroups), std::end(gSystemVolumeGroups));
}
// Append for internal use only strategies (e.g. rerouting/patch)
result.parsedConfig->productStrategies.insert(
std::end(result.parsedConfig->productStrategies),
std::begin(gOrderedSystemStrategies), std::end(gOrderedSystemStrategies));
ALOGE_IF(result.nbSkippedElement != 0, "skipped %zu elements", result.nbSkippedElement);
engineConfig::VolumeGroup defaultVolumeConfig;
engineConfig::VolumeGroup defaultSystemVolumeConfig;
for (auto &volumeConfig : result.parsedConfig->volumeGroups) {
// save default volume config for streams not defined in configuration
if (volumeConfig.name.compare("AUDIO_STREAM_MUSIC") == 0) {
defaultVolumeConfig = volumeConfig;
}
if (volumeConfig.name.compare("AUDIO_STREAM_PATCH") == 0) {
defaultSystemVolumeConfig = volumeConfig;
}
loadVolumeConfig(mVolumeGroups, volumeConfig);
}
/* 保存音频策略信息 */
for (auto& strategyConfig : result.parsedConfig->productStrategies) {
sp<ProductStrategy> strategy = new ProductStrategy(strategyConfig.name);
for (const auto &group : strategyConfig.attributesGroups) {
const auto &iter = std::find_if(begin(mVolumeGroups), end(mVolumeGroups),
[&group](const auto &volumeGroup) {
return group.volumeGroup == volumeGroup.second->getName(); });
sp<VolumeGroup> volumeGroup = nullptr;
// If no volume group provided for this strategy, creates a new one using
// Music Volume Group configuration (considered as the default)
if (iter == end(mVolumeGroups)) {
engineConfig::VolumeGroup volumeConfig;
if (group.stream >= AUDIO_STREAM_PUBLIC_CNT) {
volumeConfig = defaultSystemVolumeConfig;
} else {
volumeConfig = defaultVolumeConfig;
}
ALOGW("%s: No configuration of %s found, using default volume configuration"
, __FUNCTION__, group.volumeGroup.c_str());
volumeConfig.name = group.volumeGroup;
volumeGroup = loadVolumeConfig(mVolumeGroups, volumeConfig);
} else {
volumeGroup = iter->second;
}
if (group.stream != AUDIO_STREAM_DEFAULT) {
// A legacy stream can be assigned once to a volume group
LOG_ALWAYS_FATAL_IF(checkStreamForGroups(group.stream, mVolumeGroups),
"stream %s already assigned to a volume group, "
"review the configuration", toString(group.stream).c_str());
volumeGroup->addSupportedStream(group.stream);
}
addSupportedAttributesToGroup(group, volumeGroup, strategy);
}
product_strategy_t strategyId = strategy->getId();
mProductStrategies[strategyId] = strategy;
}
mProductStrategies.initialize();
return result;
}
5. AudioPolicyManager::onNewAudioModulesAvailableInt
打开所有arrached的输出设备对应的输出流(ioprofile)
根据mOutputProfiles/mSupportedDevices和mOutputDevicesAll确定可用设备,并打开输出流
{
for (const auto& hwModule : mHwModulesAll) {
/* 打开audio HW module */
hwModule->setHandle(mpClientInterface->loadHwModule(hwModule->getName()));
mHwModules.push_back(hwModule);
/*打开所有的存在attach 设备的输出流*/
// open all output streams needed to access attached devices
// except for direct output streams that are only opened when they are actually
// required by an app.
// This also validates mAvailableOutputDevices list
for (const auto& outProfile : hwModule->getOutputProfiles()) {
const DeviceVector &supportedDevices = outProfile->getSupportedDevices();
DeviceVector availProfileDevices = supportedDevices.filter(mOutputDevicesAll);
sp<DeviceDescriptor> supportedDevice = 0;
if (supportedDevices.contains(mDefaultOutputDevice)) {
supportedDevice = mDefaultOutputDevice;
} else {
// choose first device present in profile's SupportedDevices also part of
// mAvailableOutputDevices.
if (availProfileDevices.isEmpty()) {
continue;
}
supportedDevice = availProfileDevices.itemAt(0);
}
/* 打开输出流 */
sp<SwAudioOutputDescriptor> outputDesc = new SwAudioOutputDescriptor(outProfile,
mpClientInterface);
audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
status_t status = outputDesc->open(nullptr, DeviceVector(supportedDevice),
AUDIO_STREAM_DEFAULT,
AUDIO_OUTPUT_FLAG_NONE, &output);
/* 保存output 到 outputDesc;设置流的输出设备--setOutputDevices*/
if ((outProfile->getFlags() & AUDIO_OUTPUT_FLAG_DIRECT) != 0) {
outputDesc->close();
} else {
addOutput(output, outputDesc);
setOutputDevices(outputDesc,
DeviceVector(supportedDevice),
true,
0,
NULL);
}
}
// open input streams needed to access attached devices to validate
// mAvailableInputDevices list
for (const auto& inProfile : hwModule->getInputProfiles()) {
// available input devices
const DeviceVector &supportedDevices = inProfile->getSupportedDevices();
DeviceVector availProfileDevices = supportedDevices.filter(mInputDevicesAll);
sp<AudioInputDescriptor> inputDesc =
new AudioInputDescriptor(inProfile, mpClientInterface);
audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
status_t status = inputDesc->open(nullptr,
availProfileDevices.itemAt(0),
AUDIO_SOURCE_MIC,
AUDIO_INPUT_FLAG_NONE,
&input);
/* 关闭输入流 */
inputDesc->close();
}
}
}