当前位置:   article > 正文

分析Android O的AudioPolicyService服务(一)_audiopolicyservice::onfirstref()

audiopolicyservice::onfirstref()
AudioPolicyManager.cpp:音频策略的管理类,也可以说是服务端;
  • 分析createAudioPolicyManager函数的初始化;
  1. void AudioPolicyService::onFirstRef()
  2. {
  3. .......
  4. mAudioPolicyManager = createAudioPolicyManager(mAudioPolicyClient);
  5. ......
  6. }

createAudioPolicyManager函数在如下文件中进行声明和实现

路径:frameworks/av/services/audiopolicy/manager/AudioPolicyFactory.cpp

  1. #include "managerdefault/AudioPolicyManager.h"
  2. namespace android {
  3. extern "C" AudioPolicyInterface* createAudioPolicyManager(
  4. AudioPolicyClientInterface *clientInterface)
  5. {
  6. return new AudioPolicyManager(clientInterface);
  7. }
  8. extern "C" void destroyAudioPolicyManager(AudioPolicyInterface *interface)
  9. {
  10. delete interface;
  11. }
  12. } // namespace android

通过new 一个AudioPolicyManager对象,

路径:frameworks/av/services/audiopolicy/managerdefault/AudioPolicyManager.cpp

  1. AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface)
  2. : AudioPolicyManager(clientInterface, false /*forTesting*/)
  3. {
  4. loadConfig(); //加载音频的配置文件,配置文件在哪里呢?请看下面
  5. initialize(); //初始化对象
  6. }
  • 接下来就看loadConfig()的函数中具体加载什么样的配置文件呢?
  1. #define AUDIO_POLICY_VENDOR_CONFIG_FILE "/vendor/etc/audio_policy.conf
  2. void AudioPolicyManager::loadConfig() {
  3. #ifdef USE_XML_AUDIO_POLICY_CONF //如果这个宏在Android.mk文件中有定义则执行
  4. if (deserializeAudioPolicyXmlConfig(getConfig()) != NO_ERROR) {
  5. #else
  6.   //加载两个配置文件;
  7. if ((ConfigParsingUtils::loadConfig(AUDIO_POLICY_VENDOR_CONFIG_FILE, getConfig()) != NO_ERROR)
  8. && (ConfigParsingUtils::loadConfig(AUDIO_POLICY_CONFIG_FILE, getConfig()) != NO_ERROR)) {
  9. #endif
  10. ALOGE("could not load audio policy configuration file, setting defaults");
  11. getConfig().setDefault();
  12. }
  13. }

两个配置文件的宏定义如下:
frameworks/av/services/audiopolicy/common/managerdefinitions/include/audio_policy_conf.h

  1. /
  2. // Definitions for audio policy configuration file (audio_policy.conf)
  3. /
  4. #define AUDIO_HARDWARE_MODULE_ID_MAX_LEN 32
  5. #define AUDIO_POLICY_CONFIG_FILE "/system/etc/audio_policy.conf"
  6. #define AUDIO_POLICY_VENDOR_CONFIG_FILE "/vendor/etc/audio_policy.conf"

如果配置不存在,则加载默认的配置;

  • 第二函数就是initialize(),它做了哪些工作呢??
  1. status_t AudioPolicyManager::initialize() {
  2. mVolumeCurves->initializeVolumeCurves(getConfig().isSpeakerDrcEnabled());
  3. // Once policy config has been parsed, retrieve an instance of the engine and initialize it.
  4. //分析完策略配置后,声明引擎的实例并初始化它。
  5. audio_policy::EngineInstance *engineInstance = audio_policy::EngineInstance::getInstance();
  6. if (!engineInstance) {
  7. ALOGE("%s: Could not get an instance of policy engine", __FUNCTION__);
  8. return NO_INIT;
  9. }
  10. // Retrieve the Policy Manager Interface
  11. //通过实例engineInstance查询AudioPolicyManagerInterface接口
  12. mEngine = engineInstance->queryInterface<AudioPolicyManagerInterface>();
  13. if (mEngine == NULL) {
  14. ALOGE("%s: Failed to get Policy Engine Interface", __FUNCTION__);
  15. return NO_INIT;
  16. }
  17. // 将AudioPolicyManager设置观察者
  18. mEngine->setObserver(this);
  19. //检测策略引擎是否初始化成功
  20. status_t status = mEngine->initCheck();
  21. if (status != NO_ERROR) {
  22. LOG_FATAL("Policy engine not initialized(err=%d)", status);
  23. return status;
  24. }
  25. // mAvailableOutputDevices and mAvailableInputDevices now contain all attached devices
  26. // open all output streams needed to access attached devices
  27. //现在mAvailableOutputDevices和mAvailableInputDevices变量包含所有连接的设备
  28. //打开所有输出流必须能访问连接设备
  29. audio_devices_t outputDeviceTypes = mAvailableOutputDevices.types();
  30. audio_devices_t inputDeviceTypes = mAvailableInputDevices.types() & ~AUDIO_DEVICE_BIT_IN;
  31. for (const auto& hwModule : mHwModulesAll) {
  32. ......
  33. //初始化所有的硬件模块
  34. }
  35. // open input streams needed to access attached devices to validate
  36. // mAvailableInputDevices list
  37. //使mAvailableInputDevices列表的设备生效
  38. for (const auto& inProfile : hwModule->getInputProfiles()) {
  39. }
  40. ......
  41. // make sure all attached devices have been allocated a unique ID
  42. // 保证所有的连接设备都有一个独一无二的ID
  43. for (size_t i = 0; i < mAvailableOutputDevices.size();) {
  44. if (!mAvailableOutputDevices[i]->isAttached()) {
  45. ALOGW("Output device %08x unreachable", mAvailableOutputDevices[i]->type());
  46. mAvailableOutputDevices.remove(mAvailableOutputDevices[i]);
  47. continue;
  48. }
  49. // The device is now validated and can be appended to the available devices of the engine
  50. mEngine->setDeviceConnectionState(mAvailableOutputDevices[i],
  51. AUDIO_POLICY_DEVICE_STATE_AVAILABLE);
  52. i++;
  53. }
  54. // 保证所有输入连接设备都有一个独一无二的ID
  55. for (size_t i = 0; i < mAvailableInputDevices.size();) {
  56. if (!mAvailableInputDevices[i]->isAttached()) {
  57. ALOGW("Input device %08x unreachable", mAvailableInputDevices[i]->type());
  58. mAvailableInputDevices.remove(mAvailableInputDevices[i]);
  59. continue;
  60. }
  61. // The device is now validated and can be appended to the available devices of the engine
  62. mEngine->setDeviceConnectionState(mAvailableInputDevices[i],
  63. AUDIO_POLICY_DEVICE_STATE_AVAILABLE);
  64. i++;
  65. }
  66. // make sure default device is reachable
  67. // 保证默认音频设备可用
  68. if (mDefaultOutputDevice == 0 || mAvailableOutputDevices.indexOf(mDefaultOutputDevice) < 0) {
  69. ALOGE("Default device %08x is unreachable", mDefaultOutputDevice->type());
  70. status = NO_INIT;
  71. }
  72. // If microphones address is empty, set it according to device type
  73. // 如果麦克风地址为空,需根据设备类型来设置麦克风的地址
  74. for (size_t i = 0; i < mAvailableInputDevices.size(); i++) {
  75. if (mAvailableInputDevices[i]->mAddress.isEmpty()) {
  76. if (mAvailableInputDevices[i]->type() == AUDIO_DEVICE_IN_BUILTIN_MIC) {
  77. mAvailableInputDevices[i]->mAddress = String8(AUDIO_BOTTOM_MICROPHONE_ADDRESS);
  78. } else if (mAvailableInputDevices[i]->type() == AUDIO_DEVICE_IN_BACK_MIC) {
  79. mAvailableInputDevices[i]->mAddress = String8(AUDIO_BACK_MICROPHONE_ADDRESS);
  80. }
  81. }
  82. }
  83. //更新设备和输出设备,其实就是根据系统的当前状态选择最后的输出设备
  84. updateDevicesAndOutputs();
  85. return status;
  86. }

至此初始化的任务就已经执行完毕,该函数整理来说干了四件事:
第一,获取AudioPolicyManagerInterface的引擎对象mEngine
第二,设置AudioPolicyManager的观察者,允许引擎可获取有关设备、流、hwmodules等集合的信息。
第三,打通音频的输出输入设备
第四,根据音频的输出输入设备类型的策略设置当前的路由策略

 

  • 下面来具体分析EngineInstance的实例对做了什么:
  1. // Once policy config has been parsed, retrieve an instance of the engine and initialize it.
  2. audio_policy::EngineInstance *engineInstance = audio_policy::EngineInstance::getInstance();
  3. if (!engineInstance) {
  4. ALOGE("%s: Could not get an instance of policy engine", __FUNCTION__);
  5. return NO_INIT;
  6. }

通过命名空间的audio_policy得到EngineInstance单例类然后在通过getInstance()获取engineInstance的指针对象;
EngineInstance.cpp的类,路径:
frameworks/av/services/audiopolicy/enginedefault/src/EngineInstance.cpp

  1. #include <AudioPolicyManagerInterface.h>
  2. #include "AudioPolicyEngineInstance.h"
  3. #include "Engine.h"
  4. namespace android
  5. {
  6. namespace audio_policy //命名空间为audio_policy
  7. {
  8. //构造函数,没有做任何事情,因为是单例
  9. EngineInstance::EngineInstance()
  10. {
  11. }
  12. //返回EngineInstance对象的地址
  13. EngineInstance *EngineInstance::getInstance()
  14. {
  15. static EngineInstance instance;
  16. return &instance;
  17. }
  18. //返回Engine对象的地址,也就是指针
  19. Engine *EngineInstance::getEngine() const
  20. {
  21. static Engine engine;
  22. return &engine;
  23. }
  24. //模板函数,返回AudioPolicyManagerInterface对象的指针
  25. template <>
  26. AudioPolicyManagerInterface *EngineInstance::queryInterface() const
  27. {
  28. return getEngine()->queryInterface<AudioPolicyManagerInterface>();
  29. }
  30. } // namespace audio_policy
  31. } // namespace android

既然已经得到了单例,那么有什么作用???
作用就是通过queryInterface函数获取Engine对象指针,如上面的代码,这个Engine的作用就比较大了,稍后分析,
调用下面的代码,首先通过queryInterface函数获取mEngine对象指针,然后再设置AudioPolicyManagerObserver为作为观察者,最后,通过mEngine->initCheck()函数检测观察者模式是否设置成功;

  1. // Retrieve the Policy Manager Interface
  2. mEngine = engineInstance->queryInterface<AudioPolicyManagerInterface>();
  3. if (mEngine == NULL) {
  4. ALOGE("%s: Failed to get Policy Engine Interface", __FUNCTION__);
  5. return NO_INIT;
  6. }
  7. mEngine->setObserver(this);
  8. status_t status = mEngine->initCheck();
  9. if (status != NO_ERROR) {
  10. LOG_FATAL("Policy engine not initialized(err=%d)", status);
  11. return status;
  12. }

所有与音频策略相关的设置和获取都在Engine.cpp类中:
frameworks/av/services/audiopolicy/enginedefault/src/Engine.cpp

  • 再来分析音频设备:
  1. // mAvailableOutputDevices and mAvailableInputDevices now contain all attached devices
  2. // open all output streams needed to access attached devices
  3. audio_devices_t outputDeviceTypes = mAvailableOutputDevices.types();
  4. audio_devices_t inputDeviceTypes = mAvailableInputDevices.types() & ~AUDIO_DEVICE_BIT_IN;

首先从DeviceVector得到输入、输出的设备类型变量:
下面的这个for循环有点长,需要有点耐心:
 

  1. //变量mHwModulesAll的声明在.h文件中:HwModuleCollection mHwModulesAll;
  2. //开始循环遍历所有的音频模块,这些音频模块不一定每个都可用
  3. for (const auto& hwModule : mHwModulesAll) {
  4. //通过模块名称加载硬件模块,如果不能打开相应模块,则继续循环
  5. hwModule->setHandle(mpClientInterface->loadHwModule(hwModule->getName()));
  6. if (hwModule->getHandle() == AUDIO_MODULE_HANDLE_NONE) {
  7. ALOGW("could not open HW module %s", hwModule->getName());
  8. continue;
  9. }
  10. //将加载的模块保存到集合:mHwModules中,声明:HwModuleCollection mHwModules;这个变量只保存加载成功的音频硬件模块
  11. mHwModules.push_back(hwModule);
  12. // open all output streams needed to access attached devices
  13. // except for direct output streams that are only opened when they are actually
  14. // required by an app.
  15. // This also validates mAvailableOutputDevices list
  16. for (const auto& outProfile : hwModule->getOutputProfiles()) {
  17. //得到InputProfileCollection实例,outProfile实质就是IOProfile对象的引用
  18. //判断输出设备是可以打开
  19. if (!outProfile->canOpenNewIo()) {
  20. ALOGE("Invalid Output profile max open count %u for profile %s",
  21. outProfile->maxOpenCount, outProfile->getTagName().c_str());
  22. continue;
  23. }
  24. //是否支持设备
  25. if (!outProfile->hasSupportedDevices()) {
  26. ALOGW("Output profile contains no device on module %s", hwModule->getName());
  27. continue;
  28. }
  29. //得到tts输出设备是否可用
  30. if ((outProfile->getFlags() & AUDIO_OUTPUT_FLAG_TTS) != 0) {
  31. mTtsOutputAvailable = true;
  32. }
  33. if ((outProfile->getFlags() & AUDIO_OUTPUT_FLAG_DIRECT) != 0) {
  34. continue;
  35. }
  36. //获取支持的输出设备类型
  37. audio_devices_t profileType = outProfile->getSupportedDevicesType();
  38. if ((profileType & mDefaultOutputDevice->type()) != AUDIO_DEVICE_NONE) {
  39. profileType = mDefaultOutputDevice->type();
  40. } else {
  41. // chose first device present in profile's SupportedDevices also part of
  42. // outputDeviceTypes
  43. profileType = outProfile->getSupportedDeviceForType(outputDeviceTypes);
  44. }
  45. if ((profileType & outputDeviceTypes) == 0) {
  46. continue;
  47. }
  48. //new 一个输出设备的描述符
  49. sp<SwAudioOutputDescriptor> outputDesc = new SwAudioOutputDescriptor(outProfile,
  50. mpClientInterface);
  51. const DeviceVector &supportedDevices = outProfile->getSupportedDevices();
  52. const DeviceVector &devicesForType = supportedDevices.getDevicesFromType(profileType);
  53. String8 address = devicesForType.size() > 0 ? devicesForType.itemAt(0)->mAddress
  54. : String8("");
  55. audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
  56. //通过描述符打开输出设备的地址
  57. status_t status = outputDesc->open(nullptr, profileType, address,
  58. AUDIO_STREAM_DEFAULT, AUDIO_OUTPUT_FLAG_NONE, &output);
  59. if (status != NO_ERROR) {
  60. ALOGW("Cannot open output stream for device %08x on hw module %s",
  61. outputDesc->mDevice,
  62. hwModule->getName());
  63. } else {
  64.         //循环遍历支持的设备
  65. for (const auto& dev : supportedDevices) {
  66. ssize_t index = mAvailableOutputDevices.indexOf(dev);
  67. // give a valid ID to an attached device once confirmed it is reachable
  68. if (index >= 0 && !mAvailableOutputDevices[index]->isAttached()) {
  69. mAvailableOutputDevices[index]->attach(hwModule);
  70. }
  71. }
  72. if (mPrimaryOutput == 0 &&
  73. outProfile->getFlags() & AUDIO_OUTPUT_FLAG_PRIMARY) {
  74. mPrimaryOutput = outputDesc;
  75. }
  76. //将输出设备添加到列表中mOutputs,然后设备输出设备
  77. addOutput(output, outputDesc);
  78. setOutputDevice(outputDesc,
  79. profileType,
  80. true,
  81. 0,
  82. NULL,
  83. address);
  84. }
  85. }
  86. // open input streams needed to access attached devices to validate
  87. // mAvailableInputDevices list
  88. //获取可用的输入设备,方法同输出设备的方法一样,不做分析
  89. for (const auto& inProfile : hwModule->getInputProfiles()) {
  90. if (!inProfile->canOpenNewIo()) {
  91. ALOGE("Invalid Input profile max open count %u for profile %s",
  92. inProfile->maxOpenCount, inProfile->getTagName().c_str());
  93. continue;
  94. }
  95. if (!inProfile->hasSupportedDevices()) {
  96. ALOGW("Input profile contains no device on module %s", hwModule->getName());
  97. continue;
  98. }
  99. // chose first device present in profile's SupportedDevices also part of
  100. // inputDeviceTypes
  101. audio_devices_t profileType = inProfile->getSupportedDeviceForType(inputDeviceTypes);
  102. if ((profileType & inputDeviceTypes) == 0) {
  103. continue;
  104. }
  105. sp<AudioInputDescriptor> inputDesc =
  106. new AudioInputDescriptor(inProfile, mpClientInterface);
  107. DeviceVector inputDevices = mAvailableInputDevices.getDevicesFromType(profileType);
  108. // the inputs vector must be of size >= 1, but we don't want to crash here
  109. String8 address = inputDevices.size() > 0 ? inputDevices.itemAt(0)->mAddress
  110. : String8("");
  111. ALOGV(" for input device 0x%x using address %s", profileType, address.string());
  112. ALOGE_IF(inputDevices.size() == 0, "Input device list is empty!");
  113. audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
  114. status_t status = inputDesc->open(nullptr,
  115. profileType,
  116. address,
  117. AUDIO_SOURCE_MIC,
  118. AUDIO_INPUT_FLAG_NONE,
  119. &input);
  120. if (status == NO_ERROR) {
  121. for (const auto& dev : inProfile->getSupportedDevices()) {
  122. ssize_t index = mAvailableInputDevices.indexOf(dev);
  123. // give a valid ID to an attached device once confirmed it is reachable
  124. if (index >= 0) {
  125. sp<DeviceDescriptor> devDesc = mAvailableInputDevices[index];
  126. if (!devDesc->isAttached()) {
  127. devDesc->attach(hwModule);
  128. devDesc->importAudioPort(inProfile, true);
  129. }
  130. }
  131. }
  132. inputDesc->close();
  133. } else {
  134. ALOGW("Cannot open input stream for device %08x on hw module %s",
  135. profileType,
  136. hwModule->getName());
  137. }
  138. }
  139. }

接下来就为可用的输入、输出设备分析独一无二的ID:

  1. // make sure all attached devices have been allocated a unique ID
  2. for (size_t i = 0; i < mAvailableOutputDevices.size();) {
  3. //调用的路径:DeviceVector->DeviceDescriptor.h->AudioPort.h->isAttached()
  4. //判断是音频硬件模块是否真的可用
  5. if (!mAvailableOutputDevices[i]->isAttached()) {
  6. ALOGW("Output device %08x unreachable", mAvailableOutputDevices[i]->type());
  7. mAvailableOutputDevices.remove(mAvailableOutputDevices[i]);
  8. continue;
  9. }
  10. // The device is now validated and can be appended to the available devices of the engine
  11. // 该设备现在已经过验证,可以附加到发动机的可用设备上。设置设备的连接状态为:音频策略设备状态可用
  12. mEngine->setDeviceConnectionState(mAvailableOutputDevices[i],
  13. AUDIO_POLICY_DEVICE_STATE_AVAILABLE);
  14. i++;
  15. }
  16. //输入设备同上
  17. for (size_t i = 0; i < mAvailableInputDevices.size();) {
  18. if (!mAvailableInputDevices[i]->isAttached()) {
  19. ALOGW("Input device %08x unreachable", mAvailableInputDevices[i]->type());
  20. mAvailableInputDevices.remove(mAvailableInputDevices[i]);
  21. continue;
  22. }
  23. // The device is now validated and can be appended to the available devices of the engine
  24. mEngine->setDeviceConnectionState(mAvailableInputDevices[i],
  25. AUDIO_POLICY_DEVICE_STATE_AVAILABLE);
  26. i++;
  27. }
  1. // make sure default device is reachable
  2. //确定默认的输出设备是否可用
  3. if (mDefaultOutputDevice == 0 || mAvailableOutputDevices.indexOf(mDefaultOutputDevice) < 0) {
  4. ALOGE("Default device %08x is unreachable", mDefaultOutputDevice->type());
  5. status = NO_INIT;
  6. }
  7. // If microphones address is empty, set it according to device type
  8. //如果麦克风地址为空,则设置
  9. for (size_t i = 0; i < mAvailableInputDevices.size(); i++) {
  10. if (mAvailableInputDevices[i]->mAddress.isEmpty()) {
  11. if (mAvailableInputDevices[i]->type() == AUDIO_DEVICE_IN_BUILTIN_MIC) {
  12. mAvailableInputDevices[i]->mAddress = String8(AUDIO_BOTTOM_MICROPHONE_ADDRESS);
  13. } else if (mAvailableInputDevices[i]->type() == AUDIO_DEVICE_IN_BACK_MIC) {
  14. mAvailableInputDevices[i]->mAddress = String8(AUDIO_BACK_MICROPHONE_ADDRESS);
  15. }
  16. }
  17. }
  • 最后一个方法:updateDevicesAndOutputs(),根据当前系统设备状态设置音频策略:
  1. void AudioPolicyManager::updateDevicesAndOutputs()
  2. {
  3. for (int i = 0; i < NUM_STRATEGIES; i++) {
  4. //为设备获取音频策略
  5. mDeviceForStrategy[i] = getDeviceForStrategy((routing_strategy)i, false /*fromCache*/);
  6. }
  7. mPreviousOutputs = mOutputs;
  8. }

至此分析完成,如有不正确的地方,请指教

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/正经夜光杯/article/detail/875972
推荐阅读
相关标签
  

闽ICP备14008679号