AudioPolicyService启动过程分析(android_audio)
Posted we1less
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AudioPolicyService启动过程分析(android_audio)相关的知识,希望对你有一定的参考价值。
此文章部分参考 https://blog.csdn.net/marshal_zsx/article/details/81060100
AudioPolicyService是策略的制定者,
AudioFlinger是策略的执行者,
所以: AudioPolicyService根据配置文件使唤AudioFlinger来创建Thread
管理输入输出设备,包括设备的连接、断开状态,设备的选择和切换等
管理系统的音频策略,比如通话时播放音乐、或者播放音乐时来电话的一系列处理
管理系统的音量
上层的一些音频参数也可以通过AudioPolicyService设置到底层去
godv@godv-OptiPlex-7070:/dev/snd$ ls -la
总用量 0
drwxr-xr-x 3 root root 320 7月 1 21:26 .
drwxr-xr-x 21 root root 4320 7月 1 21:41 ..
drwxr-xr-x 2 root root 60 7月 1 21:26 by-path
crw-rw----+ 1 root audio 116, 2 7月 1 21:26 controlC0
crw-rw----+ 1 root audio 116, 11 7月 1 21:26 hwC0D0
crw-rw----+ 1 root audio 116, 12 7月 1 21:26 hwC0D2
crw-rw----+ 1 root audio 116, 4 7月 1 21:26 pcmC0D0c
crw-rw----+ 1 root audio 116, 3 7月 1 21:39 pcmC0D0p
crw-rw----+ 1 root audio 116, 10 7月 1 21:26 pcmC0D10p
crw-rw----+ 1 root audio 116, 5 7月 1 21:26 pcmC0D2c
crw-rw----+ 1 root audio 116, 6 7月 1 21:26 pcmC0D3p
crw-rw----+ 1 root audio 116, 7 7月 1 21:26 pcmC0D7p
crw-rw----+ 1 root audio 116, 8 7月 1 21:26 pcmC0D8p
crw-rw----+ 1 root audio 116, 9 7月 1 21:26 pcmC0D9p
crw-rw----+ 1 root audio 116, 1 7月 1 21:26 seq
crw-rw----+ 1 root audio 116, 33 7月 1 21:26 timer
默认声卡 & 声卡上存在何种硬件资源(耳机孔/喇叭) 厂家通过配置文件声明
1.读取、解析配置文件
2.AudioPolicyService根据配置文件调用AudioFlinger服务创建线程,打开output
audioserver.rc frameworks/av/media/audioserver/audioserver.rc
service audioserver /system/bin/audioserver
class main
user audioserver
# media gid needed for /dev/fm (radio) and for /data/misc/media (tee)
group audio camera drmrpc inet media mediadrm net_bt net_bt_admin net_bw_acct
ioprio rt 4
writepid /dev/cpuset/foreground/tasks /dev/stune/foreground/tasks
onrestart restart audio-hal-2-0
on property:vts.native_server.on=1
stop audioserver
on property:vts.native_server.on=0
start audioserver
main_audioserver.cpp frameworks/av/media/audioserver/main_audioserver.cpp
int main(int argc __unused, char **argv)
{
signal(SIGPIPE, SIG_IGN);
...
sp<ProcessState> proc(ProcessState::self());
sp<IServiceManager> sm = defaultServiceManager();
ALOGI("ServiceManager: %p", sm.get());
AudioFlinger::instantiate();
AudioPolicyService::instantiate();
...
SoundTriggerHwService::instantiate();
ProcessState::self()->startThreadPool();
// FIXME: remove when BUG 31748996 is fixed
android::hardware::ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
}
}
frameworks/av/services/audiopolicy/service/AudioPolicyService.cpp
void AudioPolicyService::onFirstRef()
{
{
Mutex::Autolock _l(mLock);
// start tone playback thread
mTonePlaybackThread = new AudioCommandThread(String8("ApmTone"), this);
// start audio commands thread
mAudioCommandThread = new AudioCommandThread(String8("ApmAudio"), this);
// start output activity command thread
mOutputCommandThread = new AudioCommandThread(String8("ApmOutput"), this);
mAudioPolicyClient = new AudioPolicyClient(this);
mAudioPolicyManager = createAudioPolicyManager(mAudioPolicyClient);
}
// load audio processing modules
sp<AudioPolicyEffects>audioPolicyEffects = new AudioPolicyEffects();
{
Mutex::Autolock _l(mLock);
mAudioPolicyEffects = audioPolicyEffects;
}
}
frameworks/av/services/audiopolicy/service/AudioPolicyService.h
class AudioPolicyClient : public AudioPolicyClientInterface
{
...
private:
AudioPolicyService *mAudioPolicyService;
};
AudioPolicyClient的实现文件frameworks/av/services/audiopolicy/service/AudioPolicyClientImpl.cpp
createAudioPolicyManager frameworks/av/services/audiopolicy/AudioPolicyInterface.h
// Audio Policy client Interface
class AudioPolicyClientInterface
{
...
extern "C" AudioPolicyInterface* createAudioPolicyManager(AudioPolicyClientInterface *clientInterface);
extern "C" void destroyAudioPolicyManager(AudioPolicyInterface *interface);
}; // namespace android
createAudioPolicyManager的实现frameworks/av/services/audiopolicy/manager/AudioPolicyFactory.cpp
直接new了一个AudioPolicyManager然后把刚才创建的AudioPolicyClient传了进去。
#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
AudioPolicyManager frameworks/av/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
mEngine->setObserver(this)把mApmObserver绑定为AudioPolicyManager对象,所以在frameworks/ av/services/audiopolicy/enginedefault/Engine.cpp中调用mApmObserver->xxx()都是调用的AudioPolicyManager类中的成员函数。 Engine类里要用到AudioPolicyManager类里的成员函数就用mApmObserver->xxx(),AudioPolicyManager类里要使用Engine类的成员函数就用mEngine->xxx()
AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface)
{
......
mEngine->setObserver(this);
......
}
先从 /vendor/etc/audio_policy.conf 加载 或者 /system/etc/audio_policy.conf
关于音频配置 frameworks/av/services/audiopolicy/config/audio_policy_configuration.xml
参考 https://blog.csdn.net/qq_33750826/article/details/97757590
//frameworks/av/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface) :
mLimitRingtoneVolume(false), mLastVoiceVolume(-1.0f),
mA2dpSuspended(false),
mAudioPortGeneration(1),
mBeaconMuteRefCount(0),
mBeaconPlayingRefCount(0),
mBeaconMuted(false),
mTtsOutputAvailable(false),
mMasterMono(false),
mMusicEffectOutput(AUDIO_IO_HANDLE_NONE)
{
//1.加载audio_policy.conf配置文件
//配置文件路径:/vendor/etc/audio_policy.conf 或者 /system/etc/audio_policy.conf
ConfigParsingUtils::loadConfig(....);
//2.初始化各种音频流对应的音量调节点
mVolumeCurves->initializeVolumeCurves(speakerDrcEnabled);
//3.加载audio policy硬件抽象库
mHwModules[i]->mHandle = mpClientInterface->loadHwModule(mHwModules[i]->mName);
//4.打开输出设备
mpClientInterface->openOutput(....);
//5.保存输出设备描述符对象
addOutput(output, outputDesc);
//6.设置输出设备
setOutputDevice(....);
//7.打开输入设备
mpClientInterface->openInput(....);
//8.更新输出设备
updateDevicesAndOutputs();
}
ConfigParsingUtils::loadConfig(....); 解析配置文件
1.加载audio_policy.conf配置文件
frameworks/av/services/audiopolicy/common/managerdefinitions/src/ConfigParsingUtils.cpp
解析配置文件放在这里面说 https://blog.csdn.net/we1less/article/details/118499349
mVolumeCurves->initializeVolumeCurves(mSpeakerDrcEnabled);
frameworks/av/services/audiopolicy/common/managerdefinitions/src/StreamDescriptor.cpp
2.初始化各种音频流对应的音量调节点
void StreamDescriptorCollection::initializeVolumeCurves(bool isSpeakerDrcEnabled)
{
for (int i = 0; i < AUDIO_STREAM_CNT; i++) {
for (int j = 0; j < DEVICE_CATEGORY_CNT; j++) {
//设置音量
setVolumeCurvePoint(static_cast<audio_stream_type_t>(i),
static_cast<device_category>(j),
Gains::sVolumeProfiles[i][j]);
}
}
......
}
mHwModules[i]->mHandle = mpClientInterface->loadHwModule(mHwModules[i]->getName());
总结1 {
mHwModules --> HwModule(集合) --> { .name
.mOutputProfiles(一个/多个Output配置 IOProfile)
.mInputProfiles(一个/多个Input配置) }
IOProfile 来自配置的文件的参数
}
3.加载audio policy硬件抽象库
frameworks/av/services/audiopolicy/service/AudioPolicyClientImpl.cpp
audio_module_handle_t AudioPolicyService::AudioPolicyClient::loadHwModule(const char *name)
{
sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
if (af == 0) {
ALOGW("%s: could not get AudioFlinger", __func__);
return AUDIO_MODULE_HANDLE_NONE;
}
return af->loadHwModule(name);
}
这里直接调用了AudioFlinger::loadHwModule()。
frameworks/av/services/audioflinger/AudioFlinger.cpp
audio_module_handle_t AudioFlinger::loadHwModule(const char *name)
{
if (name == NULL) {
return AUDIO_MODULE_HANDLE_NONE;
}
if (!settingsAllowed()) {
return AUDIO_MODULE_HANDLE_NONE;
}
Mutex::Autolock _l(mLock);
return loadHwModule_l(name);
}
audio_module_handle_t AudioFlinger::loadHwModule_l(const char *name)
{
//1.是否已经加载过这个interface
for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
if (strncmp(mAudioHwDevs.valueAt(i)->moduleName(), name, strlen(name)) == 0) {
ALOGW("loadHwModule() module %s already loaded", name);
return mAudioHwDevs.keyAt(i);
}
}
//2.加载audio interface
int rc = mDevicesFactoryHal->openDevice(name, &dev);
//3.初始化
rc = dev->initCheck();
//4.添加到全局变量中
audio_module_handle_t handle = (audio_module_handle_t) nextUniqueId(AUDIO_UNIQUE_ID_USE_MODULE);
mAudioHwDevs.add(handle, new AudioHwDevice(handle, name, dev, flags));
}
loadHwModule_l是通过调用openDevice方法来打开加载audio设备的,该方法的实现类是DevicesFactoryHalHybrid
frameworks/av/media/libaudiohal/DevicesFactoryHalHybrid.cpp
DevicesFactoryHalHybrid中提供了两种方式加载,本文将介绍hidl的方式加载
status_t DevicesFactoryHalHybrid::openDevice(const char *name, sp<DeviceHalInterface> *device) {
if (mHidlFactory != 0 && strcmp(AUDIO_HARDWARE_MODULE_ID_A2DP, name) != 0) {
return mHidlFactory->openDevice(name, device); //Hidl方式加载
}
return mLocalFactory->openDevice(name, device); //本地加载
}
openDevice frameworks/av/media/libaudiohal/DevicesFactoryHalHidl.cpp
status_t DevicesFactoryHalHidl::openDevice(const char *name, sp<DeviceHalInterface> *device) {
if (mDevicesFactory == 0) return NO_INIT;
IDevicesFactory::Device hidlDevice;
status_t status = nameFromHal(name, &hidlDevice);
if (status != OK) return status;
Result retval = Result::NOT_INITIALIZED;
Return<void> ret = mDevicesFactory->openDevice(
hidlDevice,
[&](Result r, const sp<IDevice>& result) {
retval = r;
if (retval == Result::OK) {
*device = new DeviceHalHidl(result);
}
});
if (ret.isOk()) {
if (retval == Result::OK) return OK;
else if (retval == Result::INVALID_ARGUMENTS) return BAD_VALUE;
else return NO_INIT;
}
return FAILED_TRANSACTION;
}
openDevice hardware/interfaces/audio/2.0/default/DevicesFactory.cpp
总结2 {
从mHwModules中取出每一个HwModule根据.name打开.so文件
}
audio.primary.xxx.so
audio.primary.goldfish.so
Return<void> DevicesFactory::openDevice(IDevicesFactory::Device device, openDevice_cb _hidl_cb) {
audio_hw_device_t *halDevice;
Result retval(Result::INVALID_ARGUMENTS);
sp<IDevice> result;
const char* moduleName = deviceToString(device);
if (moduleName != nullptr) {
int halStatus = loadAudioInterface(moduleName, &halDevice);//加载audio interface
if (halStatus == OK) {
if (device == IDevicesFactory::Device::PRIMARY) {
result = new PrimaryDevice(halDevice);
} else {
result = new ::android::hardware::audio::V2_0::implementation::
Device(halDevice);
}
retval = Result::OK;
} else if (halStatus == -EINVAL) {
retval = Result::NOT_INITIALIZED;
}
}
_hidl_cb(retval, result);//将加载的设备通过回调匿名方法传递回去
return Void();
}
int DevicesFactory::loadAudioInterface(const char *if_name, audio_hw_device_t **dev)
{
const hw_module_t *mod;
int rc;
//在system/lib/hw/等目录下查找对应的动态库并加载
rc = hw_get_module_by_class(AUDIO_HARDWARE_MODULE_ID, if_name, &mod);
//打开对应的device,并获取hw_device_t指针类型的设备对象
rc = audio_hw_device_open(mod, dev);
......
}
hw_get_module_by_class hardware/libhardware/hardware.c
snprintf(prop_name, sizeof(prop_name), "ro.hardware.%s", name);
[ro.hardware.audio.primary]: [goldfish]
openOutput frameworks/av/services/audiopolicy/service/AudioPolicyClientImpl.cpp
打开输出设备
status_t AudioPolicyService::AudioPolicyClient::openOutput(audio_module_handle_t module,
audio_io_handle_t *output,
audio_config_t *config,
audio_devices_t *devices,
const String8& address,
uint32_t *latencyMs,
audio_output_flags_t flags)
{
sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
if (af == 0) {
ALOGW("%s: could not get AudioFlinger", __func__);
return PERMISSION_DENIED;
}
return af->openOutput(module, output, config, devices, address, latencyMs, flags);
}
这里直接调用了AudioFlinger::openOutput()。
frameworks/av/services/audioflinger/AudioFlinger.cpp
总结3 {
构造硬件封装对象
对象中含有 audio_hw_device_t 结构体
}
AudioHwDevice参见 https://mp.csdn.net/mp_blog/creation/editor/118528729 3.对硬件的封装:
MixerThread 表明声明来源是多种多样的混合播放 放入mPlaybackThreads数组中
flags来源 /vendor/etc/audio_policy.conf 加载 或者 /system/etc/audio_policy.conf 中配置
status_t AudioFlinger::openOutput(audio_module_handle_t module,
audio_io_handle_t *output,
audio_config_t *config,
audio_devices_t *devices,
const String8& address,
uint32_t *latencyMs,
audio_output_flags_t flags)
{
......
sp<ThreadBase> thread = openOutput_l(module, output, config, *devices, address, flags);
......
}
sp<AudioFlinger::ThreadBase> AudioFlinger::openOutput_l(audio_module_handle_t module,
audio_io_handle_t *output,
audio_config_t *config,
audio_devices_t devices,
const String8& address,
audio_output_flags_t flags)
{
//查找合适的设备并打开
//关于这个AudioHwDevice参见上方链接
AudioHwDevice *outHwDev = findSuitableHwDev_l(module, devices);
......
AudioStreamOut *outputStream = NULL;
//在硬件设备上打开一个输出流
status_t status = outHwDev->openOutputStream(
&outputStream,
*output,
devices,
flags,
config,
address.string());
mHardwareStatus = AUDIO_HW_IDLE;
if (status == NO_ERROR) {
if (flags & AUDIO_OUTPUT_FLAG_MMAP_NOIRQ) {
sp<MmapPlaybackThread> thread =
new MmapPlaybackThread(this, *output, outHwDev, outputStream,
devices, AUDIO_DEVICE_NONE, mSystemReady);
mMmapThreads.add(*output, thread);
ALOGV("openOutput_l() created mmap playback thread: ID %d thread %p",
*output, thread.get());
return thread;
} else {
sp<PlaybackThread> thread;
if (flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
//AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD音频流,创建OffloadThread实例
thread = new OffloadThread(this, outputStream, *output, devices, mSystemReady);
ALOGV("openOutput_l() created offload output: ID %d thread %p",
*output, thread.get());
} else if ((flags & AUDIO_OUTPUT_FLAG_DIRECT)
|| !isValidPcmSinkFormat(config->format)
|| !isValidPcmSinkChannelMask(config->channel_mask)) {
//若是AUDIO_OUTPUT_FLAG_DIRECT音频,则创建DirectOutputThread实例
thread = new DirectOutputThread(this, outputStream, *output, devices, mSystemReady);
ALOGV("openOutput_l() created direct output: ID %d thread %p",
*output, thread.get());
} else {
//其他音频流,则创建MixerThread实例 一般来说都创建这个线程
thread = new MixerThread(this, outputStream, *output, devices, mSystemReady);
ALOGV("openOutput_l() created mixer output: ID %d thread %p",
*output, thread.get());
}
mPlaybackThreads.add(*output, thread);
return thread;
}
}
return 0;
}
以上是关于AudioPolicyService启动过程分析(android_audio)的主要内容,如果未能解决你的问题,请参考以下文章
Android音频系统之AudioPolicyService
AudioPolicyService的类图和native的典型binder通信方式
AudioPolicyService的类图和native的典型binder通信方式