对于Audio,系统是如何知道当前设备有哪些可用的output和input device?
首先:系统解析audio_policy_configuration.xml
中的attachedDevices,mixPorts,devicePorts,routes字段来确定有哪些设备!
但是,在audio_policy_configuration.xml
中配置了设备,就一定代表着物理设备也存在吗?
在audio_policy_configuration.xml
中的字段是如何与物理设备一一对应的?
上述问题是本章要厘清的事情。
一切的一切要从audioserver启动开始说起:
main_audioserver.cpp::main
BinderService<AudioPolicyService>::publish
AudioPolicyService::onFirstRef
AudioPolicyService::createAudioPolicyManager
AudioPolicyConfig::loadFromApmXml
AudioPolicyManager::initialize
AudioPolicyManager::onNewAudioModulesAvailableInt
主要关注onNewAudioModulesAvailableInt
方法
void AudioPolicyManager::onNewAudioModulesAvailableInt(DeviceVector *newDevices)
{
for (const auto& hwModule : mConfig->getHwModules()) {
......
if (hwModule->getHandle() == AUDIO_MODULE_HANDLE_NONE) {
if (audio_module_handle_t handle = mpClientInterface->loadHwModule(hwModule->getName());
handle != AUDIO_MODULE_HANDLE_NONE) {
hwModule->setHandle(handle);
}
......
}
mHwModules.push_back(hwModule);
// open all output streams needed to access attached devices.
// direct outputs are closed immediately after checking the availability of attached devices
// This also validates mAvailableOutputDevices list
for (const auto& outProfile : hwModule->getOutputProfiles()) {
......
const DeviceVector &supportedDevices = outProfile->getSupportedDevices();
DeviceVector availProfileDevices = supportedDevices.filter(mConfig->getOutputDevices());
sp<DeviceDescriptor> supportedDevice = 0;
if (supportedDevices.contains(mConfig->getDefaultOutputDevice())) {
supportedDevice = mConfig->getDefaultOutputDevice();
} else {
......
supportedDevice = availProfileDevices.itemAt(0);
}
if (!mConfig->getOutputDevices().contains(supportedDevice)) {
continue;
}
sp<SwAudioOutputDescriptor> outputDesc = new SwAudioOutputDescriptor(outProfile,
mpClientInterface);
audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
status_t status = outputDesc->open(nullptr /* halConfig */, nullptr /* mixerConfig */,
DeviceVector(supportedDevice),
AUDIO_STREAM_DEFAULT,
AUDIO_OUTPUT_FLAG_NONE, &output);
for (const auto &device : availProfileDevices) {
// give a valid ID to an attached device once confirmed it is reachable
if (!device->isAttached()) {
device->attach(hwModule);
mAvailableOutputDevices.add(device);
device->setEncapsulationInfoFromHal(mpClientInterface);
if (newDevices) newDevices->add(device);
setEngineDeviceConnectionState(device, AUDIO_POLICY_DEVICE_STATE_AVAILABLE);
}
}
......
}
// open input streams needed to access attached devices to validate
// mAvailableInputDevices list
for (const auto& inProfile : hwModule->getInputProfiles()) {
......
// chose first device present in profile's SupportedDevices also part of
// available input devices
const DeviceVector &supportedDevices = inProfile->getSupportedDevices();
DeviceVector availProfileDevices = supportedDevices.filter(mConfig->getInputDevices());
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);
for (const auto &device : availProfileDevices) {
// give a valid ID to an attached device once confirmed it is reachable
if (!device->isAttached()) {
device->attach(hwModule);
device->importAudioPortAndPickAudioProfile(inProfile, true);
mAvailableInputDevices.add(device);