概述:
AudioPolicyService做什么事情呢?简单来说,比如应用程序要播放一段声音,声音从哪个设备上播放出来。这些都是通过AudioPolicyService来决定的。
假设android系统中有两个声卡设备:
1)问默认声卡是哪个?
由厂家决定
2)从哪个设备上播放声音呢?耳机还是喇叭
耳机、喇叭这些硬件配置从驱动中是看不出来的,那么声卡1中的耳机和喇叭如何告知Android系统呢?
由厂家决定
那厂家是如何决定的呢?
此时AudioPolicyService服务就该出场了,该服务主要做如下几项工作:
1)读取解析配置文件,声卡设备会根据配置文件进行选择。
对于配置文件有两个:
对于Android7.0之前,使用audio_policy.conf文件
从Android7.0之后,又出现了一个audio_policy_configuration.xml文件。具体使用哪一个,由一个宏来控制。
2)对于每个声卡,在Android音频系统中都会存在一个线程与之对应。从逻辑意义上说,有一个output,一个output对应一个或多个设备,同时一个output还对应一个线程。
3)对于硬件的操作是由AudioFlinger完成的,但是AudioFlinger不能主动做任何事情。
4)AudioPolicyService根据配置文件,调用AudioFlinger的服务,来打开output,创建线程。有了这些线程后,应用程序就可以把声音数据发给这些线程了。
1. mediaserver加载
AudioPolicyService是android音频系统的两大服务之一,另一个服务是AudioFliger。这两个服务都是在系统启动时由MediaServer加载。加载的代码位于:
/frameworks/av/media/audioserver/main_audioserver.cpp
int main(int argc __unused, char** argv)
{
.......
AudioFlinger::instantiate();//创建AudioFlinger对象,服务名为"media.audio_flinger"
.......
AudioPolicyService::instantiate();//创建AudioPolicyService对象,服务名为"media.audio_policy"
.......
}
2.可执行文件mediaserver
看一个可执行文件,通常会首先查看其Android.mk文件,位于:
/frameworks/av/media/mediaserver/Android.mk
LOCAL_PATH:= $(call my-dir)
.......
include $(CLEAR_VARS)
LOCAL_SRC_FILES:=
main_mediaserver.cpp
........
LOCAL_MODULE:= mediaserver
LOCAL_32_BIT_ONLY := true
LOCAL_INIT_RC := mediaserver.rc
LOCAL_CFLAGS := -Werror -Wall
include $(BUILD_EXECUTABLE)
对于该mk文件,我们重点关注3个地方:
LOCAL_SRC_FILES:= main_mediaserver.cpp //存放源程序的地方
LOCAL_MODULE:= mediaserver //源文件最终被编译成的可执行文件mediaserver
LOCAL_INIT_RC := mediaserver.rc
2.1 mediaserver.rc
/frameworks/av/media/mediaserver/mediaserver.rc
service media /system/bin/mediaserver
class main
user media
group audio camera inet net_bt net_bt_admin net_bw_acct drmrpc mediadrm
ioprio rt 4
writepid /dev/cpuset/foreground/tasks /dev/stune/foreground/tasks
3. AudioPolicyService::instantiate
AudioPlicyService类中并没有instantiate函数,那么肯定是从父类中继承得到的。
/frameworks/av/services/audiopolicy/service/AudioPolicyService.h
class AudioPolicyService :
public BinderService<AudioPolicyService>,
public BnAudioPolicyService,
public IBinder::DeathRecipient
{
friend class BinderService<AudioPolicyService>;
public:
// for BinderService
static const char *getServiceName() ANDROID_API { return "media.audio_policy"; }
在代码中搜索,可以发现instantiate函数是在BinderService类中定义的。
/frameworks/native/libs/binder/include/binder/BinderService.h
template<typename SERVICE>
class BinderService
{
public:
static status_t publish(bool allowIsolated = false) {
sp<IServiceManager> sm(defaultServiceManager());
return sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated);
}
......
static void instantiate() { publish(); }
.......
从上面的代码可以看出,AudioPolicyService::instantiate()实际上调用了publish函数,publish函数实际上调用了addService函数。在addService函数中,实现了3个作用:
3.1 SERVICE::getServiceName()
因为BinderService是类模板,又因为AudioPolicyService::instantiate(),所以此处的SERVICE就是类AudioPolicyService类。
因此SERVICE::getServiceName()实际上调用了AudioPolicyService类中的成员函数getServiceName.
static const char *getServiceName() ANDROID_API { return "media.audio_policy"; }
将返回一个media.audio_policy的服务
3.2 new SERVICE
调用AudioPolicyService的构造函数,创建了一个AudioPolicyService的对象,做一些初始化的工作。
/frameworks/av/services/audiopolicy/service/AudioPolicyService.cpp
AudioPolicyService::AudioPolicyService()
: BnAudioPolicyService(), mpAudioPolicyDev(NULL), mpAudioPolicy(NULL),
mAudioPolicyManager(NULL), mAudioPolicyClient(NULL), mPhoneState(AUDIO_MODE_INVALID)
{
}
3.3 调用AudioPolicyService::onFirstRef()
由于sm是sp<IServiceManager>强引用类型的指针,所以在第一次调用AudioPolicyService模块时,会调用AudioPolicyService::onFirstRef()
/frameworks/av/services/audiopolicy/service/AudioPolicyService.cpp
void AudioPolicyService::onFirstRef()
{
{
Mutex::Autolock _l(mLock);
// start tone playback thread,用于播放tone音,tone是音调的意思
mTonePlaybackThread = new AudioCommandThread(String8("ApmTone"), this);
// start audio commands thread,用于执行audio命令
mAudioCommandThread = new AudioCommandThread(String8("ApmAudio"), this);
// start output activity command thread,用于执行audio输出命令
mOutputCommandThread = new AudioCommandThread(String8("ApmOutput"), this);
//实例化AudioPolicyClient对象
mAudioPolicyClient = new AudioPolicyClient(this);
//实例化AudioPolicyManager对象
mAudioPolicyManager = createAudioPolicyManager(mAudioPolicyClient);
}
// load audio processing modules
//初始化音效相关
sp<AudioPolicyEffects>audioPolicyEffects = new AudioPolicyEffects();
{
mAudioPolicyEffects = audioPolicyEffects;
}
}
3.3.1 new AudioPolicyClient
创建了一个AudioPolicyClient的对象,AudioPolicyClient的构造函数在
/frameworks/av/services/audiopolicy/service/AudioPolicyService.h中。
class AudioPolicyClient : public AudioPolicyClientInterface
{
public:
explicit AudioPolicyClient(AudioPolicyService *service) : mAudioPolicyService(service) {}
.....
}
AudioPolicyService *mAudioPolicyService,mAudioPolicyService是类AudioPolicyService的一个指针。在AudioPolicyClient构造函数中,实际上只是将传进来的service指针
赋值给了mAudioPolicyService。service是什么,就是传进来的this指针,this指针指代当前的AudioPolicyService类的一个指针。
在这个地方设计到了C++的基本知识,首先会调用父类AudioPolicyClientInterface的构造函数,然后调用成员变量的构造函数,mAudioPolicyService是一个AudioPolicyService的对象,最后
调用自己的构造函数。new AudioPolicyClient对象,会涉及到三个构造函数的调用哦。
3.3.2 createAudioPolicyManager(mAudioPolicyClient)
/frameworks/av/services/audiopolicy/manager/AudioPolicyFactory.cpp
extern "C" AudioPolicyInterface* createAudioPolicyManager(
AudioPolicyClientInterface *clientInterface)
{
return new AudioPolicyManager(clientInterface);
}
new AudioPolicyManager(clientInterface)将会调用类AudioPolicyManager的构造函数,接下来将重点分析该构造函数,这是我们分析AudioPolicyService的关键。