概述
本文将讲述AudioPolicyService、AudioPolicyManager的初始化过程,解析加载xml文件之后生成的模块,研究AudioPolicyManager是如何根据profile打开对应的模块并构建好输出音频数据的路径。
类简介
1.AudioPolicyService:APS是音频框架的服务,在Main_audioserver.cpp中生成,它在第一次强引用的时候会创建AudioCommandThread和AudioPolicyClient,AudioPolicyManager。它主要由AudioSystem通过binder调用,也可以由AudioPolicyClient,AudioPolicyManager直接调用。它的大部分操作都交给AudioPolicyManager来做
2.AudioPolicyClient:APC是AudioPolicyService的内部类。它用于打开关闭输入输出,设置流音量,传递参数给hal层(如audio_hw.c)等;它主要是通过binder跨进程调用AudioFlinger去完成真正的操作。可以由AudioManager通过mpClientInterface去调用它
3.AudioPolicyManager:APM是AudioPolicyService的码农,AudioPolicyService的大部分操作都由他来执行
4.AudioFlinger:AF主要承担音频混合输出,是Audio系统的核心,从AudioTrack来的数据最终都会在这里处理,并被写入到Audio的HAL。
5.DevicesFactoryHalLocal:根据名字加载对应的hal module。比如传进去a2dp相关的名字,会加载到audio.a2dp.default.so
6.DevicesFactoryHalHidl:跨进行加载hidl hal module。我这边的平台是local的,所以hidl相关就不分析了。
7.DevicesFactoryHalInterface:用于创建子类DevicesFactoryHalHybrid。
8.DevicesFactoryHalHybrid:选择创建DevicesFactoryHalLocal或者DevicesFactoryHalHidl,我这里只创建DevicesFactoryHalLocal。
9.DeviceHalLocal:通过私有成员audio_hw_device_t *mDev,直接调用hal代码,用来设置和获取底层参数,打开和关闭stream。
10.StreamOutHalLocal:通过私有成员audio_stream_out_t *mStream直接调用hal代码,用于操作流,比如start、stop、flush、puse操作;还有调用write函数写音频数据到hal层。
11.AudioStreamOutSink:它其实是StreamOutHalLocal的一个wrapper,它也有write函数,不过是通过StreamOutHalLocal来操作的。
时序图
初始化过程可以分为四部分:
1.加载audio configuration。
2.加载每一个HwModule。
3.初始化默认输出输入设备。找到默认设备对应的IOProfile,为它创建SwAudioOutputDescriptor,然后openOutput。
加载audio configuration
AudioPolicyManager在初始化的时候会去加载xml文件,解析xml文件,然后把解析出来的信息填充到对应的类中。熟悉audio profile相关信息有助于后面分析代码。下图表示的是相关的类信息。
说明:
HwModuleCollection是一个Vector类,用于保存HwModule,我这里有三个module,一个是primary,一个是a2dp,一个是usb。可以看出我这三个module都是从三个xml文件中解析出来的,每个module都包含有对应xml文件的所有信息。可以使用dumpsys media.audio_policy 把所有的policy信息dump出来,这个dump是调用HwModuleCollection::dump之类的函数,把所有的子集都dump出来。下面就是使用这个命令dump出来的部分信息,右半部分是我手动添加的,dump信息结合代码总结出来的。
W Modules dump: HwModuleCollection::dump (HwModuleCollection mHwModules)
- HW Module 1:
- name: primary HwModule::dump (itemAt(i)->dump)
- handle: 10
- version: 2.0
- outputs:
output 0:
IOProfile::dump (mOutputProfiles[i]->dump)(OutputProfileCollection mOutputProfiles)
- name: primary output AudioPort::dump [对应xml中<mixPorts>]
- Profiles: AudioProfileVector::dump (mProfiles.dump)
Profile 0:
- format: AUDIO_FORMAT_PCM_16_BIT AudioProfile::dump(itemAt(i)->dump)
- sampling rates:44100
- channel masks:0x0003
- flags: 0x0002 (AUDIO_OUTPUT_FLAG_PRIMARY) IOProfile::dump
- Supported devices: DeviceVector::dump [对应xml中<devicePorts>] (mSupportedDevices)
Device 1: DeviceDescriptor::dump (itemAt(i))
- id: 1
- tag name: Earpiece
- type: AUDIO_DEVICE_OUT_EARPIECE
Device 2:
- id: 2
- tag name: Speaker
- type: AUDIO_DEVICE_OUT_SPEAKER
Device 5:
- tag name: BT SCO
- type: AUDIO_DEVICE_OUT_BLUETOOTH_SCO
output 2:
- name: voice_tx
- Profiles:
Profile 0:
- format: AUDIO_FORMAT_PCM_16_BIT
- sampling rates:8000, 16000
- channel masks:0x0001
- flags: 0x0000 (AUDIO_OUTPUT_FLAG_NONE)
...........
- inputs: HwModule::dump (itemAt(i)->dump)
input 0:
IOProfile::dump (mInputProfiles[i]->dump)
- name: primary input AudioPort::dump [这个对应xml文件里的<mixPorts>]
- Profiles: AudioProfileVector::dump (mProfiles.dump)
Profile 0:
- format: AUDIO_FORMAT_PCM_16_BIT
- sampling rates:8000,16000,..., 44100, 48000
- channel masks:0x000c, 0x0010, 0x0030