赞
踩
AudioPolicyManager.cpp:音频策略的管理类,也可以说是服务端;
- 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(); //初始化对象
- }
- #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"
如果配置不存在,则加载默认的配置;
- 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等集合的信息。
第三,打通音频的输出输入设备
第四,根据音频的输出输入设备类型的策略设置当前的路由策略
- // 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);
- }
- }
- }

- void AudioPolicyManager::updateDevicesAndOutputs()
- {
- for (int i = 0; i < NUM_STRATEGIES; i++) {
- //为设备获取音频策略
- mDeviceForStrategy[i] = getDeviceForStrategy((routing_strategy)i, false /*fromCache*/);
- }
- mPreviousOutputs = mOutputs;
- }
至此分析完成,如有不正确的地方,请指教
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。