AudioPolicyService启动过程分析(一)

概述:

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的关键。



 

 

posted @ 2021-01-09 17:53  一代枭雄  阅读(1351)  评论(0编辑  收藏  举报