AudioPolicyManager.cpp:音频策略的管理类,也可以说是服务端;
- 分析createAudioPolicyManager函数的初始化;
void AudioPolicyService::onFirstRef()
{
.......
mAudioPolicyManager = createAudioPolicyManager(mAudioPolicyClient);
......
}
createAudioPolicyManager函数在如下文件中进行声明和实现
路径:frameworks/av/services/audiopolicy/manager/AudioPolicyFactory.cpp
#include "managerdefault/AudioPolicyManager.h"
namespace android {
extern "C" AudioPolicyInterface* createAudioPolicyManager(
AudioPolicyClientInterface *clientInterface)
{
return new AudioPolicyManager(clientInterface);
}
extern "C" void destroyAudioPolicyManager(AudioPolicyInterface *interface)
{
delete interface;
}
} // namespace android
通过new 一个AudioPolicyManager对象,
路径:frameworks/av/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface)
: AudioPolicyManager(clientInterface, false /*forTesting*/)
{
loadConfig(); //加载音频的配置文件,配置文件在哪里呢?请看下面
initialize(); //初始化对象
}
- 接下来就看loadConfig()的函数中具体加载什么样的配置文件呢?
#define AUDIO_POLICY_VENDOR_CONFIG_FILE "/vendor/etc/audio_policy.conf
void AudioPolicyManager::loadConfig() {
#ifdef USE_XML_AUDIO_POLICY_CONF //如果这个宏在Android.mk文件中有定义则执行
if (deserializeAudioPolicyXmlConfig(getConfig()) != NO_ERROR) {
#else
//加载两个配置文件;
if ((ConfigParsingUtils::loadConfig(AUDIO_POLICY_VENDOR_CONFIG_FILE, getConfig()) != NO_ERROR)
&& (ConfigParsingUtils::loadConfig(AUDIO_POLICY_CONFIG_FILE, getConfig()) != NO_ERROR)) {
#endif
ALOGE("could not load audio policy configuration file, setting defaults");
getConfig().setDefault();
}
}
两个配置文件的宏定义如下:
frameworks/av/services/audiopolicy/common/managerdefinitions/include/audio_policy_conf.h
/
// Definitions for audio policy configuration file (audio_policy.conf)
/
#define AUDIO_HARDWARE_MODULE_ID_MAX_LEN 32
#define AUDIO_POLICY_CONFIG_FILE "/system/etc/audio_policy.conf"
#define AUDIO_POLICY_VENDOR_CONFIG_FILE "/vendor/etc/audio_policy.conf"
如果配置不存在,则加载默认的配置;
- 第二函数就是initialize(),它做了哪些工作呢??
status_t AudioPolicyManager::initialize() {
mVolumeCurves->initializeVolumeCurves(getConfig().isSpeakerDrcEnabled());
// Once policy config has been parsed, retrieve an instance of the engine and initialize it.
//分析完策略配置后,声明引擎的实例并初始化它。
audio_policy::EngineInstance *engineInstance = audio_policy::EngineInstance::getInstance();
if (!engineInstance) {
ALOGE("%s: Could not get an instance of policy engine", __FUNCTION__);
return NO_INIT;
}
// Retrieve the Policy Manager Interface
//通过实例engineInstance查询AudioPolicyManagerInterface接口
mEngine = engineInstance->queryInterface<AudioPolicyManagerInterface>();
if (mEngine == NULL) {
ALOGE("%s: Failed to get Policy Engine Interface", __FUNCTION__);
return NO_INIT;
}
// 将AudioPolicyManager设置观察者
mEngine->setObserver(this);
//检测策略引擎是否初始化成功
status_t status = mEngine->initCheck();
if (status != NO_ERROR) {
LOG_FATAL("Policy engine not initialized(err=%d)", status);
return status;
}
// mAvailableOutputDevices and mAvailableInputDevices now contain all attached devices
// open all output streams needed to access attached devices
//现在mAvailableOutputDevices和mAvailableInputDevices变量包含所有连接的设备
//打开所有输出流必须能访问连接设备
audio_devices_t outputDeviceTypes = mAvailableOutputDevices.types();
audio_devices_t inputDeviceTypes = mAvailableInputDevices.types() & ~AUDIO_DEVICE_BIT_IN;
for (const auto& hwModule : mHwModulesAll) {
......
//初始化所有的硬件模块
}
// open input streams needed to access attached devices to validate
// mAvailableInputDevices list
//使mAvailableInputDevices列表的设备生效
for (const auto& inProfile : hwModule->getInputProfiles()) {
}
......
// make sure all attached devices have been allocated a unique ID
// 保证所有的连接设备都有一个独一无二的ID
for (size_t i = 0; i < mAvailableOutputDevices.size();) {
if (!mAvailableOutputDevices[i]->isAttached()) {
ALOGW("Output device %08x unreachable", mAvailableOutputDevices[i]->type());
mAvailableOutputDevices.remove(mAvailableOutputDevices[i]);
continue;
}
// The device is now validated and can be appended to the available devices of the engine
mEngine->setDeviceConnectionState(mAvailableOutputDevices[i],
AUDIO_POLICY_DEVICE_STATE_AVAILABLE);
i++;
}
// 保证所有输入连接设备都有一个独一无二的ID
for (size_t i = 0; i < mAvailableInputDevices.size();) {
if (!mAvailableInputDevices[i]->isAttached()) {
ALOGW("Input device %08x unreachable", mAvailableInputDevices[i]->type());
mAvailableInputDevices.remove(mAvailableInputDevices[i]);
continue;
}
// The device is now validated and can be appended to the available devices of the engine
mEngine->setDeviceConnectionState(mAvailableInputDevices[i],
AUDIO_POLICY_DEVICE_STATE_AVAILABLE);
i++;
}
// make sure default device is reachable
// 保证默认音频设备可用
if (mDefaultOutputDevice == 0 || mAvailableOutputDevices.indexOf(mDefaultOutputDevice) < 0) {
ALOGE("Default device %08x is unreachable", mDefaultOutputDevice->type());
status = NO_INIT;
}
// If microphones address is empty, set it according to device type
// 如果麦克风地址为空,需根据设备类型来设置麦克风的地址
for (size_t i = 0; i < mAvailableInputDevices.size(); i++) {
if (mAvailableInputDevices[i]->mAddress.isEmpty()) {
if (mAvailableInputDevices[i]->type() == AUDIO_DEVICE_IN_BUILTIN_MIC) {
mAvailableInputDevices[i]->mAddress = String8(AUDIO_BOTTOM_MICROPHONE_ADDRESS);
} else if (mAvailableInputDevices[i]->type() == AUDIO_DEVICE_IN_BACK_MIC) {
mAvailableInputDevices[i]->mAddress = String8(AUDIO_BACK_MICROPHONE_ADDRESS);
}
}
}
//更新设备和输出设备,其实就是根据系统的当前状态选择最后的输出设备
updateDevicesAndOutputs();
return status;
}
至此初始化的任务就已经执行完毕,该函数整理来说干了四件事:
第一,获取AudioPolicyManagerInterface的引擎对象mEngine
第二,设置AudioPolicyManager的观察者,允许引擎可获取有关设备、流、hwmodules等集合的信息。
第三,打通音频的输出输入设备
第四,根据音频的输出输入设备类型的策略设置当前的路由策略
- 下面来具体分析EngineInstance的实例对做了什么:
// Once policy config has been parsed, retrieve an instance of the engine and initialize it.
audio_policy::EngineInstance *engineInstance = audio_policy::EngineInstance::getInstance();
if (!engineInstance) {
ALOGE("%s: Could not get an instance of policy engine", __FUNCTION__);
return NO_INIT;
}
通过命名空间的audio_policy得到EngineInstance单例类然后在通过getInstance()获取engineInstance的指针对象;
EngineInstance.cpp的类,路径:
frameworks/av/services/audiopolicy/enginedefault/src/EngineInstance.cpp
#include <AudioPolicyManagerInterface.h>
#include "AudioPolicyEngineInstance.h"
#include "Engine.h"
namespace android
{
namespace audio_policy //命名空间为audio_policy
{
//构造函数,没有做任何事情,因为是单例
EngineInstance::EngineInstance()
{
}
//返回EngineInstance对象的地址
EngineInstance *EngineInstance::getInstance()
{
static EngineInstance instance;
return &instance;
}
//返回Engine对象的地址,也就是指针
Engine *EngineInstance::getEngine() const
{
static Engine engine;
return &engine;
}
//模板函数,返回AudioPolicyManagerInterface对象的指针
template <>
AudioPolicyManagerInterface *EngineInstance::queryInterface() const
{
return getEngine()->queryInterface<AudioPolicyManagerInterface>();
}
} // namespace audio_policy
} // namespace android
既然已经得到了单例,那么有什么作用???
作用就是通过queryInterface函数获取Engine对象指针,如上面的代码,这个Engine的作用就比较大了,稍后分析,
调用下面的代码,首先通过queryInterface函数获取mEngine对象指针,然后再设置AudioPolicyManagerObserver为作为观察者,最后,通过mEngine->initCheck()函数检测观察者模式是否设置成功;
// Retrieve the Policy Manager Interface
mEngine = engineInstance->queryInterface<AudioPolicyManagerInterface>();
if (mEngine == NULL) {
ALOGE("%s: Failed to get Policy Engine Interface", __FUNCTION__);
return NO_INIT;
}
mEngine->setObserver(this);
status_t status = mEngine->initCheck();
if (status != NO_ERROR) {
LOG_FATAL("Policy engine not initialized(err=%d)", status);
return status;
}
所有与音频策略相关的设置和获取都在Engine.cpp类中:
frameworks/av/services/audiopolicy/enginedefault/src/Engine.cpp
- 再来分析音频设备:
// mAvailableOutputDevices and mAvailableInputDevices now contain all attached devices
// open all output streams needed to access attached devices
audio_devices_t outputDeviceTypes = mAvailableOutputDevices.types();
audio_devices_t inputDeviceTypes = mAvailableInputDevices.types() & ~AUDIO_DEVICE_BIT_IN;
首先从DeviceVector得到输入、输出的设备类型变量:
下面的这个for循环有点长,需要有点耐心:
//变量mHwModulesAll的声明在.h文件中:HwModuleCollection mHwModulesAll;
//开始循环遍历所有的音频模块,这些音频模块不一定每个都可用
for (const auto& hwModule : mHwModulesAll) {
//通过模块名称加载硬件模块,如果不能打开相应模块,则继续循环
hwModule->setHandle(mpClientInterface->loadHwModule(hwModule->getName()));
if (hwModule->getHandle() == AUDIO_MODULE_HANDLE_NONE) {
ALOGW("could not open HW module %s", hwModule->getName());
continue;
}
//将加载的模块保存到集合:mHwModules中,声明:HwModuleCollection mHwModules;这个变量只保存加载成功的音频硬件模块
mHwModules.push_back(hwModule);
// 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()) {
//得到InputProfileCollection实例,outProfile实质就是IOProfile对象的引用
//判断输出设备是可以打开
if (!outProfile->canOpenNewIo()) {
ALOGE("Invalid Output profile max open count %u for profile %s",
outProfile->maxOpenCount, outProfile->getTagName().c_str());
continue;
}
//是否支持设备
if (!outProfile->hasSupportedDevices()) {
ALOGW("Output profile contains no device on module %s", hwModule->getName());
continue;
}
//得到tts输出设备是否可用
if ((outProfile->getFlags() & AUDIO_OUTPUT_FLAG_TTS) != 0) {
mTtsOutputAvailable = true;
}
if ((outProfile->getFlags() & AUDIO_OUTPUT_FLAG_DIRECT) != 0) {
continue;
}
//获取支持的输出设备类型
audio_devices_t profileType = outProfile->getSupportedDevicesType();
if ((profileType & mDefaultOutputDevice->type()) != AUDIO_DEVICE_NONE) {
profileType = mDefaultOutputDevice->type();
} else {
// chose first device present in profile's SupportedDevices also part of
// outputDeviceTypes
profileType = outProfile->getSupportedDeviceForType(outputDeviceTypes);
}
if ((profileType & outputDeviceTypes) == 0) {
continue;
}
//new 一个输出设备的描述符
sp<SwAudioOutputDescriptor> outputDesc = new SwAudioOutputDescriptor(outProfile,
mpClientInterface);
const DeviceVector &supportedDevices = outProfile->getSupportedDevices();
const DeviceVector &devicesForType = supportedDevices.getDevicesFromType(profileType);
String8 address = devicesForType.size() > 0 ? devicesForType.itemAt(0)->mAddress
: String8("");
audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
//通过描述符打开输出设备的地址
status_t status = outputDesc->open(nullptr, profileType, address,
AUDIO_STREAM_DEFAULT, AUDIO_OUTPUT_FLAG_NONE, &output);
if (status != NO_ERROR) {
ALOGW("Cannot open output stream for device %08x on hw module %s",
outputDesc->mDevice,
hwModule->getName());
} else {
//循环遍历支持的设备
for (const auto& dev : supportedDevices) {
ssize_t index = mAvailableOutputDevices.indexOf(dev);
// give a valid ID to an attached device once confirmed it is reachable
if (index >= 0 && !mAvailableOutputDevices[index]->isAttached()) {
mAvailableOutputDevices[index]->attach(hwModule);
}
}
if (mPrimaryOutput == 0 &&
outProfile->getFlags() & AUDIO_OUTPUT_FLAG_PRIMARY) {
mPrimaryOutput = outputDesc;
}
//将输出设备添加到列表中mOutputs,然后设备输出设备
addOutput(output, outputDesc);
setOutputDevice(outputDesc,
profileType,
true,
0,
NULL,
address);
}
}
// open input streams needed to access attached devices to validate
// mAvailableInputDevices list
//获取可用的输入设备,方法同输出设备的方法一样,不做分析
for (const auto& inProfile : hwModule->getInputProfiles()) {
if (!inProfile->canOpenNewIo()) {
ALOGE("Invalid Input profile max open count %u for profile %s",
inProfile->maxOpenCount, inProfile->getTagName().c_str());
continue;
}
if (!inProfile->hasSupportedDevices()) {
ALOGW("Input profile contains no device on module %s", hwModule->getName());
continue;
}
// chose first device present in profile's SupportedDevices also part of
// inputDeviceTypes
audio_devices_t profileType = inProfile->getSupportedDeviceForType(inputDeviceTypes);
if ((profileType & inputDeviceTypes) == 0) {
continue;
}
sp<AudioInputDescriptor> inputDesc =
new AudioInputDescriptor(inProfile, mpClientInterface);
DeviceVector inputDevices = mAvailableInputDevices.getDevicesFromType(profileType);
// the inputs vector must be of size >= 1, but we don't want to crash here
String8 address = inputDevices.size() > 0 ? inputDevices.itemAt(0)->mAddress
: String8("");
ALOGV(" for input device 0x%x using address %s", profileType, address.string());
ALOGE_IF(inputDevices.size() == 0, "Input device list is empty!");
audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
status_t status = inputDesc->open(nullptr,
profileType,
address,
AUDIO_SOURCE_MIC,
AUDIO_INPUT_FLAG_NONE,
&input);
if (status == NO_ERROR) {
for (const auto& dev : inProfile->getSupportedDevices()) {
ssize_t index = mAvailableInputDevices.indexOf(dev);
// give a valid ID to an attached device once confirmed it is reachable
if (index >= 0) {
sp<DeviceDescriptor> devDesc = mAvailableInputDevices[index];
if (!devDesc->isAttached()) {
devDesc->attach(hwModule);
devDesc->importAudioPort(inProfile, true);
}
}
}
inputDesc->close();
} else {
ALOGW("Cannot open input stream for device %08x on hw module %s",
profileType,
hwModule->getName());
}
}
}
接下来就为可用的输入、输出设备分析独一无二的ID:
// make sure all attached devices have been allocated a unique ID
for (size_t i = 0; i < mAvailableOutputDevices.size();) {
//调用的路径:DeviceVector->DeviceDescriptor.h->AudioPort.h->isAttached()
//判断是音频硬件模块是否真的可用
if (!mAvailableOutputDevices[i]->isAttached()) {
ALOGW("Output device %08x unreachable", mAvailableOutputDevices[i]->type());
mAvailableOutputDevices.remove(mAvailableOutputDevices[i]);
continue;
}
// The device is now validated and can be appended to the available devices of the engine
// 该设备现在已经过验证,可以附加到发动机的可用设备上。设置设备的连接状态为:音频策略设备状态可用
mEngine->setDeviceConnectionState(mAvailableOutputDevices[i],
AUDIO_POLICY_DEVICE_STATE_AVAILABLE);
i++;
}
//输入设备同上
for (size_t i = 0; i < mAvailableInputDevices.size();) {
if (!mAvailableInputDevices[i]->isAttached()) {
ALOGW("Input device %08x unreachable", mAvailableInputDevices[i]->type());
mAvailableInputDevices.remove(mAvailableInputDevices[i]);
continue;
}
// The device is now validated and can be appended to the available devices of the engine
mEngine->setDeviceConnectionState(mAvailableInputDevices[i],
AUDIO_POLICY_DEVICE_STATE_AVAILABLE);
i++;
}
// make sure default device is reachable
//确定默认的输出设备是否可用
if (mDefaultOutputDevice == 0 || mAvailableOutputDevices.indexOf(mDefaultOutputDevice) < 0) {
ALOGE("Default device %08x is unreachable", mDefaultOutputDevice->type());
status = NO_INIT;
}
// If microphones address is empty, set it according to device type
//如果麦克风地址为空,则设置
for (size_t i = 0; i < mAvailableInputDevices.size(); i++) {
if (mAvailableInputDevices[i]->mAddress.isEmpty()) {
if (mAvailableInputDevices[i]->type() == AUDIO_DEVICE_IN_BUILTIN_MIC) {
mAvailableInputDevices[i]->mAddress = String8(AUDIO_BOTTOM_MICROPHONE_ADDRESS);
} else if (mAvailableInputDevices[i]->type() == AUDIO_DEVICE_IN_BACK_MIC) {
mAvailableInputDevices[i]->mAddress = String8(AUDIO_BACK_MICROPHONE_ADDRESS);
}
}
}
- 最后一个方法:updateDevicesAndOutputs(),根据当前系统设备状态设置音频策略:
void AudioPolicyManager::updateDevicesAndOutputs()
{
for (int i = 0; i < NUM_STRATEGIES; i++) {
//为设备获取音频策略
mDeviceForStrategy[i] = getDeviceForStrategy((routing_strategy)i, false /*fromCache*/);
}
mPreviousOutputs = mOutputs;
}
至此分析完成,如有不正确的地方,请指教