原址
AudioPolicyService是策略的制定者,比如什么时候打开音频接口设备、某种Stream类型的音频对应什么设备等等。而AudioFlinger则是策略的执行者,例如具体如何与音频设备通信,如何维护现有系统中的音频设备,以及多个音频流的混音如何处理等等都得由它来完成。AudioPolicyService根据用户配置来指导AudioFlinger加载设备接口,起到路由功能。
![Android音频(三)AudioPolicyService_第1张图片](http://img.e-com-net.com/image/info8/22bc2b6c83cf40db8fc4cb9c330f1bf3.jpg)
AudioPolicyService启动过程
AudioPolicyService服务运行在mediaserver进程中,随着mediaserver进程启动而启动。
frameworks\av\media\mediaserver\ Main_mediaserver.cpp
- int main(int argc, char** argv)
- {
- sp proc(ProcessState::self());
- sp sm = defaultServiceManager();
- ALOGI("ServiceManager: %p", sm.get());
- VolumeManager::instantiate();
- AudioFlinger::instantiate();
- MediaPlayerService::instantiate();
- CameraService::instantiate();
- AudioPolicyService::instantiate();
- ProcessState::self()->startThreadPool();
- IPCThreadState::self()->joinThreadPool();
- }
AudioPolicyService继承了模板类BinderService,该类用于注册native service。
frameworks\native\include\binder\ BinderService.h
- template<typename SERVICE>
- class BinderService
- {
- public:
- static status_t publish(bool allowIsolated = false) {
- sp sm(defaultServiceManager());
- return sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated);
- }
- static void instantiate() { publish(); }
- };
BinderService是一个模板类,该类的publish函数就是完成向ServiceManager注册服务。
- static const char *getServiceName() { return "media.audio_policy"; }
AudioPolicyService注册名为media.audio_policy的服务。
- AudioPolicyService::AudioPolicyService()
- : BnAudioPolicyService() , mpAudioPolicyDev(NULL) , mpAudioPolicy(NULL)
- {
- char value[PROPERTY_VALUE_MAX];
- const struct hw_module_t *module;
- int forced_val;
- int rc;
- Mutex::Autolock _l(mLock);
-
- mTonePlaybackThread = new AudioCommandThread(String8("ApmTone"), this);
-
- mAudioCommandThread = new AudioCommandThread(String8("ApmAudio"), this);
-
- mOutputCommandThread = new AudioCommandThread(String8("ApmOutput"), this);
-
-
- rc = hw_get_module(AUDIO_POLICY_HARDWARE_MODULE_ID, &module);
- if (rc)
- return;
-
- rc = audio_policy_dev_open(module, &mpAudioPolicyDev);
- ALOGE_IF(rc, "couldn't open audio policy device (%s)", strerror(-rc));
- if (rc)
- return;
-
- rc = mpAudioPolicyDev->create_audio_policy(mpAudioPolicyDev, &aps_ops, this,
- &mpAudioPolicy);
- ALOGE_IF(rc, "couldn't create audio policy (%s)", strerror(-rc));
- if (rc)
- return;
- rc = mpAudioPolicy->init_check(mpAudioPolicy);
- ALOGE_IF(rc, "couldn't init_check the audio policy (%s)", strerror(-rc));
- if (rc)
- return;
-
- property_get("ro.camera.sound.forced", value, "1");
- forced_val = strtol(value, NULL, 0);
- ALOGV("setForceUse() !forced_val=%d ",!forced_val);
- mpAudioPolicy->set_can_mute_enforced_audible(mpAudioPolicy, !forced_val);
- ALOGI("Loaded audio policy from %s (%s)", module->name, module->id);
-
- if (access(AUDIO_EFFECT_VENDOR_CONFIG_FILE, R_OK) == 0) {
- loadPreProcessorConfig(AUDIO_EFFECT_VENDOR_CONFIG_FILE);
- } else if (access(AUDIO_EFFECT_DEFAULT_CONFIG_FILE, R_OK) == 0) {
- loadPreProcessorConfig(AUDIO_EFFECT_DEFAULT_CONFIG_FILE);
- }
- }
- 创建AudioCommandThread (ApmTone、ApmAudio、ApmOutput)
- 加载legacy_ap_module
- 打开legacy_ap_device
- 创建legacy_audio_policy
- 读取audio_effects.conf
![Android音频(三)AudioPolicyService_第2张图片](http://img.e-com-net.com/image/info8/14796d79f6eb41e2bfc43628d65d9246.jpg)
创建AudioCommandThread线程
在AudioPolicyService对象构造过程中,分别创建了ApmTone、ApmAudio、ApmOutput三个AudioCommandThread线程:
1、 ApmTone用于播放tone音;
2、 ApmAudio用于执行audio命令;
3、ApmOutput用于执行输出命令;
在第一次强引用AudioCommandThread线程对象时,AudioCommandThread的onFirstRef函数被回调,在此启动线程
- void AudioPolicyService::AudioCommandThread::onFirstRef()
- {
- run(mName.string(), ANDROID_PRIORITY_AUDIO);
- }
这里采用异步方式来执行audio command,当需要执行上表中的命令时,首先将命令投递到AudioCommandThread的mAudioCommands命令向量表中,然后通过mWaitWorkCV.signal()唤醒AudioCommandThread线程,被唤醒的AudioCommandThread线程执行完command后,又通过mWaitWorkCV.waitRelative(mLock, waitTime)睡眠等待命令到来。
加载audio_policy_module模块
audio_policy硬件抽象层动态库位于/system/lib/hw/目录下,命名为:audio_policy.$(TARGET_BOARD_PLATFORM).so。audiopolicy的硬件抽象层定义在hardware\libhardware_legacy\audio\audio_policy_hal.cpp中,AUDIO_POLICY_HARDWARE_MODULE_ID硬件抽象模块定义如下:
hardware\libhardware_legacy\audio\ audio_policy_hal.cpp【audio_policy.scx15.so】
- struct legacy_ap_module HAL_MODULE_INFO_SYM = {
- module: {
- common: {
- tag: HARDWARE_MODULE_TAG,
- version_major: 1,
- version_minor: 0,
- id: AUDIO_POLICY_HARDWARE_MODULE_ID,
- name: "LEGACY Audio Policy HAL",
- author: "The Android Open Source Project",
- methods: &legacy_ap_module_methods,
- dso : NULL,
- reserved : {0},
- },
- },
- };
legacy_ap_module继承于audio_policy_module。
![Android音频(三)AudioPolicyService_第3张图片](http://img.e-com-net.com/image/info8/e318d269d2934532aaf662b11895224b.jpg)
关于hw_get_module函数加载硬件抽象层模块的过程请参考Android硬件抽象Hardware库加载过程源码分析。
打开audio_policy_device设备
hardware\libhardware\include\hardware\ audio_policy.h
- static inline int audio_policy_dev_open(const hw_module_t* module,
- struct audio_policy_device** device)
- {
- return module->methods->open(module, AUDIO_POLICY_INTERFACE,
- (hw_device_t**)device);
- }
通过legacy_ap_module模块的open方法来打开一个legacy_ap_device设备。
hardware\libhardware_legacy\audio\ audio_policy_hal.cpp
- static int legacy_ap_dev_open(const hw_module_t* module, const char* name,
- hw_device_t** device)
- {
- struct legacy_ap_device *dev;
- if (strcmp(name, AUDIO_POLICY_INTERFACE) != 0)
- return -EINVAL;
- dev = (struct legacy_ap_device *)calloc(1, sizeof(*dev));
- if (!dev)
- return -ENOMEM;
- dev->device.common.tag = HARDWARE_DEVICE_TAG;
- dev->device.common.version = 0;
- dev->device.common.module = const_cast(module);
- dev->device.common.close = legacy_ap_dev_close;
- dev->device.create_audio_policy = create_legacy_ap;
- dev->device.destroy_audio_policy = destroy_legacy_ap;
- *device = &dev->device.common;
- return 0;
- }
打开得到一个legacy_ap_device设备,通过该抽象设备可以创建一个audio_policy对象。
![](http://img.e-com-net.com/image/info8/d789540815a94f1dab7fc2ae49434f23.png)
创建audio_policy对象
在打开legacy_ap_device设备时,该设备的create_audio_policy成员初始化为create_legacy_ap函数指针,我们通过legacy_ap_device设备可以创建一个legacy_audio_policy对象。
- rc = mpAudioPolicyDev->create_audio_policy(mpAudioPolicyDev, &aps_ops, this,
- &mpAudioPolicy);
这里通过audio_policy_device设备创建audio策略对象
![Android音频(三)AudioPolicyService_第4张图片](http://img.e-com-net.com/image/info8/35aed141019c49a4b5d946365303e6dc.png)
hardware\libhardware_legacy\audio\ audio_policy_hal.cpp
- static int create_legacy_ap(const struct audio_policy_device *device,
- struct audio_policy_service_ops *aps_ops,
- void *service,
- struct audio_policy **ap)
- {
- struct legacy_audio_policy *lap;
- int ret;
- if (!service || !aps_ops)
- return -EINVAL;
- lap = (struct legacy_audio_policy *)calloc(1, sizeof(*lap));
- if (!lap)
- return -ENOMEM;
- lap->policy.set_device_connection_state = ap_set_device_connection_state;
- …
- lap->policy.dump = ap_dump;
- lap->policy.is_offload_supported = ap_is_offload_supported;
- lap->service = service;
- lap->aps_ops = aps_ops;
- lap->service_client = new AudioPolicyCompatClient(aps_ops, service);
- if (!lap->service_client) {
- ret = -ENOMEM;
- goto err_new_compat_client;
- }
- lap->apm = createAudioPolicyManager(lap->service_client);
- if (!lap->apm) {
- ret = -ENOMEM;
- goto err_create_apm;
- }
- *ap = &lap->policy;
- return 0;
- err_create_apm:
- delete lap->service_client;
- err_new_compat_client:
- free(lap);
- *ap = NULL;
- return ret;
- }
audio_policy实现在audio_policy_hal.cpp中,audio_policy_service_ops实现在AudioPolicyService.cpp中。create_audio_policy()函数就是创建并初始化一个legacy_audio_policy对象。
![Android音频(三)AudioPolicyService_第5张图片](http://img.e-com-net.com/image/info8/cd51d48b34d74221a2327d3c3188585b.png)
![Android音频(三)AudioPolicyService_第6张图片](http://img.e-com-net.com/image/info8/dce22c155c28423e8c413f92f47b7702.png)
audio_policy与AudioPolicyService、AudioPolicyCompatClient之间的关系如下:
![Android音频(三)AudioPolicyService_第7张图片](http://img.e-com-net.com/image/info8/fbe28d11cd914192aa9df502411b8aab.jpg)
AudioPolicyClient创建
hardware\libhardware_legacy\audio\ AudioPolicyCompatClient.h
- AudioPolicyCompatClient(struct audio_policy_service_ops *serviceOps,void *service) :
- mServiceOps(serviceOps) , mService(service) {}
AudioPolicyCompatClient是对audio_policy_service_ops的封装类,对外提供audio_policy_service_ops数据结构中定义的接口。
AudioPolicyManager创建
- extern "C" AudioPolicyInterface* createAudioPolicyManager(AudioPolicyClientInterface *clientInterface)
- {
- ALOGI("SPRD policy manager created.");
- return new AudioPolicyManagerSPRD(clientInterface);
- }
使用AudioPolicyClientInterface对象来构造AudioPolicyManagerSPRD对象,AudioPolicyManagerSPRD继承于AudioPolicyManagerBase,而AudioPolicyManagerBase又继承于AudioPolicyInterface。
![Android音频(三)AudioPolicyService_第8张图片](http://img.e-com-net.com/image/info8/f234908df64c41c7b43c7eb7040d0422.jpg)
hardware\libhardware_legacy\audio\ AudioPolicyManagerBase.cpp
- AudioPolicyManagerBase::AudioPolicyManagerBase(AudioPolicyClientInterface *clientInterface)
- :
- #ifdef AUDIO_POLICY_TEST
- Thread(false),
- #endif //AUDIO_POLICY_TEST
-
- mPrimaryOutput((audio_io_handle_t)0),
- mAvailableOutputDevices(AUDIO_DEVICE_NONE),
- mPhoneState(AudioSystem::MODE_NORMAL),
- mLimitRingtoneVolume(false), mLastVoiceVolume(-1.0f),
- mTotalEffectsCpuLoad(0), mTotalEffectsMemory(0),
- mA2dpSuspended(false), mHasA2dp(false), mHasUsb(false), mHasRemoteSubmix(false),
- mSpeakerDrcEnabled(false), mFmOffGoing(false)
- {
-
- mpClientInterface = clientInterface;
- for (int i = 0; i < AudioSystem::NUM_FORCE_USE; i++) {
- mForceUse[i] = AudioSystem::FORCE_NONE;
- }
- mA2dpDeviceAddress = String8("");
- mScoDeviceAddress = String8("");
- mUsbCardAndDevice = String8("");
-
-
-
-
-
- if (loadAudioPolicyConfig(AUDIO_POLICY_VENDOR_CONFIG_FILE) != NO_ERROR) {
- if (loadAudioPolicyConfig(AUDIO_POLICY_CONFIG_FILE) != NO_ERROR) {
- ALOGE("could not load audio policy configuration file, setting defaults");
- defaultAudioPolicyConfig();
- }
- }
-
- initializeVolumeCurves();
-
- for (size_t i = 0; i < mHwModules.size(); i++) {
-
- mHwModules[i]->mHandle = mpClientInterface->loadHwModule(mHwModules[i]->mName);
- if (mHwModules[i]->mHandle == 0) {
- ALOGW("could not open HW module %s", mHwModules[i]->mName);
- continue;
- }
-
-
-
- for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++)
- {
- const IOProfile *outProfile = mHwModules[i]->mOutputProfiles[j];
-
- if ((outProfile->mSupportedDevices & mAttachedOutputDevices) &&
- ((outProfile->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) == 0)) {
-
- AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor(outProfile);
-
- outputDesc->mDevice = (audio_devices_t)(mDefaultOutputDevice & outProfile->mSupportedDevices);
-
- audio_io_handle_t output = mpClientInterface->openOutput(
- outProfile->mModule->mHandle,
- &outputDesc->mDevice,
- &outputDesc->mSamplingRate,
- &outputDesc->mFormat,
- &outputDesc->mChannelMask,
- &outputDesc->mLatency,
- outputDesc->mFlags);
- if (output == 0) {
- delete outputDesc;
- } else {
-
- mAvailableOutputDevices =(audio_devices_t)(mAvailableOutputDevices | (outProfile->mSupportedDevices & mAttachedOutputDevices));
- if (mPrimaryOutput == 0 && outProfile->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) {
- mPrimaryOutput = output;
- }
-
- addOutput(output, outputDesc);
-
- setOutputDevice(output,(audio_devices_t)(mDefaultOutputDevice & outProfile->mSupportedDevices),true);
- }
- }
- }
- }
- ALOGE_IF((mAttachedOutputDevices & ~mAvailableOutputDevices),
- "Not output found for attached devices %08x",
- (mAttachedOutputDevices & ~mAvailableOutputDevices));
- ALOGE_IF((mPrimaryOutput == 0), "Failed to open primary output");
- updateDevicesAndOutputs();
-
-
- char bootvalue[PROPERTY_VALUE_MAX];
-
- property_get("sys.boot_completed", bootvalue, "");
- if (strncmp("1", bootvalue, 1) != 0) {
- startReadingThread();
- }
-
-
- #ifdef AUDIO_POLICY_TEST
- ...
- #endif //AUDIO_POLICY_TEST
- }
AudioPolicyManagerBase对象构造过程中主要完成以下几个步骤:
1、 loadAudioPolicyConfig(AUDIO_POLICY_CONFIG_FILE)加载audio_policy.conf配置文件;
2、 initializeVolumeCurves()初始化各种音频流对应的音量调节点;
3、 加载audio policy硬件抽象库:mpClientInterface->loadHwModule(mHwModules[i]->mName)
4、 打开attached_output_devices输出:
mpClientInterface->openOutput();
5、 保存输出设备描述符对象:addOutput(output, outputDesc);
![Android音频(三)AudioPolicyService_第9张图片](http://img.e-com-net.com/image/info8/83409aa730cd43239f183d36bda44304.jpg)
读取audio_policy.conf文件
Android为每种音频接口定义了对应的硬件抽象层,且编译为单独的so库。
![](http://img.e-com-net.com/image/info8/f8f20021d6774e47b8d64dfda01a157d.png)
每种音频接口定义了不同的输入输出,一个接口可以具有多个输入或者输出,每个输入输出有可以支持不同的音频设备。通过读取audio_policy.conf文件可以获取系统支持的音频接口参数。
audio_policy.conf文件定义了两种音频配置信息:
1、 当前系统支持的音频输入输出设备及默认输入输出设备;
![](http://img.e-com-net.com/image/info8/d205b42a36a94e7896963e0cbcacf0ee.jpg)
这些信息时通过global_configuration配置项来设置,在global_configuration中定义了三种音频设备信息:
attached_output_devices:已连接的输出设备;
default_output_device:默认输出设备;
attached_input_devices:已连接的输入设备;
1、 系统支持的音频接口信息;
audio_policy.conf定义了系统支持的所有音频接口参数信息,比如primary、a2dp、usb等,对于primary定义如下:
![Android音频(三)AudioPolicyService_第10张图片](http://img.e-com-net.com/image/info8/bb5977d6f47043f4bd9f6bcc86ee570f.jpg)
a2dp定义:
![Android音频(三)AudioPolicyService_第11张图片](http://img.e-com-net.com/image/info8/b69d18b8275e4fecba110836a97ce798.jpg)
usb定义:
![Android音频(三)AudioPolicyService_第12张图片](http://img.e-com-net.com/image/info8/3f48eed4370e4435a47ee5c0535b42ce.jpg)
每种音频接口包含输入输出,每种输入输出又包含多种输入输出配置,每种输入输出配置又支持多种音频设备。AudioPolicyManagerBase首先加载/vendor/etc/audio_policy.conf,如果该文件不存在,则加/system/etc/audio_policy.conf。
- status_t AudioPolicyManagerBase::loadAudioPolicyConfig(const char *path)
- {
- cnode *root;
- char *data;
- data = (char *)load_file(path, NULL);
- if (data == NULL) {
- return -ENODEV;
- }
- root = config_node("", "");
-
- config_load(root, data);
-
- loadGlobalConfig(root);
-
- loadHwModules(root);
- config_free(root);
- free(root);
- free(data);
- ALOGI("loadAudioPolicyConfig() loaded %s\n", path);
- return NO_ERROR;
- }
通过loadGlobalConfig(root)函数来读取这些全局配置信息。
- void AudioPolicyManagerBase::loadGlobalConfig(cnode *root)
- {
- cnode *node = config_find(root, GLOBAL_CONFIG_TAG);
- if (node == NULL) {
- return;
- }
- node = node->first_child;
- while (node) {
-
- if (strcmp(ATTACHED_OUTPUT_DEVICES_TAG, node->name) == 0) {
- mAttachedOutputDevices = parseDeviceNames((char *)node->value);
- ALOGW_IF(mAttachedOutputDevices == AUDIO_DEVICE_NONE,
- "loadGlobalConfig() no attached output devices");
- ALOGV("loadGlobalConfig()mAttachedOutputDevices%04x", mAttachedOutputDevices);
-
- } else if (strcmp(DEFAULT_OUTPUT_DEVICE_TAG, node->name) == 0) {
- mDefaultOutputDevice= (audio_devices_t)stringToEnum(sDeviceNameToEnumTable,ARRAY_SIZE(sDeviceNameToEnumTable),(char *)node->value);
- ALOGW_IF(mDefaultOutputDevice == AUDIO_DEVICE_NON