研究Android多媒体已经有一段时间,特撰写关于android多媒体系列的文章,为了加深理解和认识,也希望能为想了解多媒体的同学提供帮助。
AudioPolicyServer看名字也能猜到应该和策略相关的一些功能,不错AudioPolicyServer正是音频策略的制定者,管理和运营所有android手机上的音频硬件,我们可以通过adb shell进入手机终端,进入cd /dev/snd/ 目录查看当前手机都有那些音频设备,会发现手机上的音频设备会很多。播放音乐,来电,响铃究竟是开启的是那个音频设备呢,某种Stream类型的音频应对应什么设备,AudioPolicyServer是怎样维护现有系统中的音频设备,各个设备之间如何切换,调节音量时调节是哪个设备呢,带着这些疑问来看看AudioPolicyServer是如何实现的。
一 首先让我们来看看与AudioPolicyServer相关联类的组织关系
1.1 AudioPolicyServer类继承IAudioPolicyServer类,为其他应用程序提供audio策略相关的功能,对外的唯一接口。
1.2 AudioPolicyManagerCustom或者AudioPolicyManagerBase,有些厂商会定制这个类,继承AudioPolicyManager,AudioPolicyManager是一个非常重要的一个类,策略的具体制定是由此类实施的,AudioPolicyServer调用AudioPolicyManager的实例来实现各种策略的功能
1.3 AudioPolicyClient类继承AudioPolicyClientInterface,AudioPolicyClient类负责与AudioFlinger的交互,AudioPolicyServer是策略的制定者,但策略的具体实施是由AudioFlinger类完成,AudioPolicyServer确定具体策略时,交给AudioPolicyClient,AudioPolicyClient在传达给AudioFlinger,AudioPolicyClient类似一个信使或者中介者。
1.4 EngineInstance类,主要为获取Engine实例提供接口,Engine类规定了具体策略相关的规定,并通过ManagerInterfaceImpl向AudioPolicyManager提供信息。
二 AudioPolicyServer初始化过程
AudioPolicyServer是在开机的时候被初始化的,源码位于
frameworks/av/media/mediaserver/main_mediaserver.cpp 中
int main(int argc __unused, char** argv)
{
signal(SIGPIPE, SIG_IGN);
......................
InitializeIcuOrDie();
sp
proc(ProcessState::self());
sp
sm = defaultServiceManager();
ALOGI("ServiceManager: %p", sm.get());
//首先初始化AudioFlinger
AudioFlinger::instantiate();
MediaPlayerService::instantiate();
ResourceManagerService::instantiate();
CameraService::instantiate();
//在初始化AudioPolicyService
AudioPolicyService::instantiate();
SoundTriggerHwService::instantiate();
RadioService::instantiate();
#ifdef AUDIO_LISTEN_ENABLED
ALOGI("ListenService instantiated");
ListenService::instantiate();
#endif
registerExtensions();
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
}
}
AudioPolicyService::instantiate(), instantiate是父类BinderService的方法,实现在frameworks/native/include/binder/Binder.h,static void instantiate() { publish(); },直接调用 publish,BinderService是个模板类, publish函数中直接new 一个server实例并托管到servermanger中。接下来我们分析一下具体的初始化过程,见时序图
2.1 AudioPolicyService::AudioPolicyService()构造函数
AudioPolicyService::AudioPolicyService()
: BnAudioPolicyService(), mpAudioPolicyDev(NULL), mpAudioPolicy(NULL),
mAudioPolicyManager(NULL), mAudioPolicyClient(NULL), mPhoneState(AUDIO_MODE_INVALID)
{
}
AudioPolicyService构造函数初始化几个变量,其他的就没做啥,当AudioPolicyService第一次别引用时触发AudioPolicyService::onFirstRef()函数,且只有第一次被引用才会被调用,以后的调用中不会在触发此函数。
void AudioPolicyService::onFirstRef()
{
char value[PROPERTY_VALUE_MAX];
const struct hw_module_t *module;
int forced_val;
int rc;
{
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);
#ifdef USE_LEGACY_AUDIO_POLICY
ALOGI("AudioPolicyService CSTOR in legacy mode");
/* instantiate the audio policy manager */
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(mpAudioPol