AudioPolicyService启动过程分析(一)

概述:

AudioPolicyService做什么事情呢?简单来说,比如应用程序要播放一段声音,声音从哪个设备上播放出来。这些都是通过AudioPolicyService来决定的。

假设android系统中有两个声卡设备:

AudioPolicyService启动过程分析(一)

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强引用类型的指针,所以在第一次调用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的关键。


原文链接: https://www.cnblogs.com/-glb/p/14255710.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/207148

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月12日 下午10:48
下一篇 2023年2月12日 下午10:49

相关推荐