Android 音频子系统(2) ---- AudioServer


前言

本系列文章基于Android14源码进行分析解读,部分框图直接使用了原作者的图片,侵权必删。

我们既生成文章,也是各路文章的搬运工。


一、What&Why AudioFlinger

        AudioHAL(AHAL)提供隔离Vendor硬件差异的抽象,通过tinyalsa实现对底层硬件声卡节点的操作。AHAL作为一个独立的service,在Android系统中肯定有client通过binder与其通信,实现数据流与控制流的交互,完成对声卡节点数据的访问。

        AudioTrack.java和AudioRecord.java是应用层的API,透过GNI访问了Native层的AudioTrack.cpp和AudioRecord.cpp,AudioTrack和AudioRecord又是如何把数据写进和读出底层声卡的呢?

        Linux声卡设备节点是一个互斥的节点,每次只能被一个应用打开,其他应用尝试open一个已经打开的节点会返回device busy的错误。但是在实际Android使用过程中又存在多个音频数据流同时播放的场景,这是如何做到的呢?

        所有这些疑问都会在AudioFlinger服务中解决。AudioFlinger向下访问AudioHardware,实现输出音频数据,控制音频参数;AudioFlinger向上通过IAudioFinger接口对AudioTrack和AudioRecord供服务。AudioFlinger在Android的音频系统框架中起着承上启下的作用,地位相当重要。

AudioFlinger创建PlaybackThread/RecordThread服务线程,实现对AHAL层音频节点的独占操作。多个AudioTrack/AudioRecord作为Clinet端同PlaybackThread/RecordThread服务线程交互,Thread实现音频流的mix/snoop,来实现整个音频框架。

下面通过分析代码,完成对AudioFlinger的深入理解。

二、AudioFlinger初始化

AudioFlinger在audioserver中启动,代码在:

frameworks/av/media/audioserver/main_audioserver.cpp

#define LOG_TAG "audioserver"

int main(int argc __unused, char **argv)
{
     ......
    这里修改了AudioFling和AudioPolicyService的初始化方式,以解决独立初始化模式下引起的
    服务启动时间差,这个时间差会导致部分服务时间检测异常而强行退出。
    // Instantiating AudioFlinger (making it public, e.g. through ::initialize())
    // and then instantiating AudioPolicy (and making it public)
    // leads to situations where AudioFlinger is accessed remotely before
    // AudioPolicy is initialized.  Not only might this
    // cause inaccurate results, but if AudioPolicy has slow audio HAL
    // initialization, it can cause a TimeCheck abort to occur on an AudioFlinger
    // call which tries to access AudioPolicy.
    //
    // We create AudioFlinger and AudioPolicy locally then make it public to ServiceManager.
    // This requires both AudioFlinger and AudioPolicy to be in-proc.
    //

    /* 1、创建AudioFling实例,必须在AudioPolicyService之前,因为aps会访问af中的接口 */
    const auto af = sp<AudioFlinger>::make(); 
    const auto afAdapter = sp<AudioFlingerServerAdapter>::make(af);
   
    /* 2、创建AudioPolicyService实例 */
    const auto aps = sp<AudioPolicyService>::make();

    /* 3、添加AudioFlinger和AudioPolicyService服务到ServiceManager */    
    // Add AudioFlinger and AudioPolicy to ServiceManager.
    sp<IServiceManager> sm = defaultServiceManager();
    sm->addService(String16(IAudioFlinger::DEFAULT_SERVICE_NAME), afAdapter,
            false /* allowIsolated */, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT);
    sm->addService(String16(AudioPolicyService::getServiceName()), aps,
            false /* allowIsolated */, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT);
    
    // AAudioService should only be used in OC-MR1 and later.
    // And only enable the AAudioService if the system MMAP policy explicitly allows it.
    std::vector<AudioMMapPolicyInfo> policyInfos;
    status_t status = af->getMmapPolicyInfos(
            AudioMMapPolicyType::DEFAULT, &policyInfos);
    // Initialize aaudio service when querying mmap policy succeeds and
    // any of the policy supports MMAP.
    if (status == NO_ERROR &&
        std::any_of(policyInfos.begin(), policyInfos.end(), [](const auto& info) {
                return info.mmapPolicy == AudioMMapPolicy::AUTO ||
                       info.mmapPolicy == AudioMMapPolicy::ALWAYS;
        })) {
        
        /* 4、创建AAudioService实例 */
        AAudioService::instantiate();
    }

    ......

    IPCThreadState::self()->joinThreadPool();
    }
}

        主函数里面没有做太多的任务,创建了AudioFlinger和AudioPolicyService两个实例,并将服务注册到servicemanager中,除此之外还检测并创建了AAudioService。


1、AudioFlinger实例构建

AudioFlinger::AudioFlinger() {
    ......

    // reset battery stats.
    // if the audio service has crashed, battery stats could be left
    // in bad state, reset the state upon service start.
    BatteryNotifier::getInstance().noteResetAudio();

    /* 构建音频device和音效effect实例 */
    mDevicesFactoryHal = DevicesFactoryHalInterface::create();
    mEffectsFactoryHal = EffectsFactoryHalInterface::create();
}

AudioFlinger的实例没有做太多的工作:

  1. 完成电池状态的复位;
  2. 构建音频设备Device工厂实例;
  3. 构建音效Effect工厂实例;
sp<DevicesFactoryHalInterface> DevicesFactoryHalInterface::create() {
      return createPreferredImpl<DevicesFactoryHalInterface>(true /* isDevice */);
}


void *createPreferredImpl(bool isDevice) {
    ......
    if (...) {
       .....
        /*  1、创建AudioHal服务  */
        if (createHalService(std::max(*ifaceVersionIt, *siblingVersionIt), isDevice,
                             &rawInterface)) {
            return rawInterface;
        } 
    return nullptr;
}


bool createHalService(const AudioHalVersionInfo& version, bool isDevice, void** rawInterface) {
    const std::string libName = "libaudiohal@" + version.toVersionString() + ".so";
    const std::string factoryFunctionName =
            isDevice ? "createIDevicesFactory" : "createIEffectsFactory";
    constexpr int dlMode = RTLD_LAZY;
    void* handle = nullptr;
    dlerror(); // clear
    /*  2、打开 libaudiohal@version.so 动态库 */
    handle = dlopen(libName.c_str(), dlMode);
    ......
    void* (*factoryFunction)();
    /*3、函数进来后首先初始化factoryFunctionName为createIDevicesFactory, 所以这里获取到的factoryFunction句柄为createIDevicesFactory函数 */
    *(void **)(&factoryFunction) = dlsym(handle, factoryFunctionName.c_str());
    if (!factoryFunction) {
       ......
    }
    /* 4、调用libaudiohal动态库的createIDevicesFactory函数,完成AHAL句柄的创建 */
    *rawInterface = (*factoryFunction)();
    return true;
}


extern "C" __attribute__((visibility("default"))) void* createIDevicesFactory() {
    return createIDevicesFactoryImpl();
}

extern "C" __attribute__((visibility("default"))) void* createIDevicesFactoryImpl() {
    auto service = hardware::audio::CPP_VERSION::IDevicesFactory::getService();
    return service ? new DevicesFactoryHalHidl(service) : nullptr;
}
DevicesFactoryHalEntry.cpp::createIDevicesFactory() ->
    DevicesFactoryHalHidl.cpp::createIDevicesFactoryImpl() ->         
         DevicesFactoryHalHidl.cpp::DevicesFactoryHalHidl()

具体逻辑这里不做深入的分析了,后面有机会再展开。

        整个AudioFlinger完成初始化之后,并没有做太多的任务。而是作为一个服务运行在系统中,等待客户端与其进行通信:这也符合AF的功能,我只做一个执行者,不做决策。那谁优势决策者呢?别忘了我们还没有分析AudioPolicyService呢。

2、AudioPolicyService实例构建

AudioPolicyService::AudioPolicyService()
    : BnAudioPolicyService(),
      mAudioPolicyManager(NULL),
      mAudioPolicyClient(NULL),
      mPhoneState(AUDIO_MODE_INVALID),
      mCaptureStateNotifier(false),
     /* 1 - 初始化mCreateAudioPolicyManager为createAudioPolicyManager */
      mCreateAudioPolicyManager(createAudioPolicyManager), 
      mDestroyAudioPolicyManager(destroyAudioPolicyManager) {
      setMinSchedulerPolicy(SCHED_NORMAL, ANDROID_PRIORITY_AUDIO);
}

/* 在完成实例后,首先调用的函数就是onFirstRef,具体原因请搜索其他文章 */
void AudioPolicyService::onFirstRef()
{
     {
        Mutex::Autolock _l(mLock);

        /* 2 - 创建两个命令线程,用于接收并处理其他服务发送的命令 */
        // start audio commands thread
        mAudioCommandThread = new AudioCommandThread(String8("ApmAudio"), this);
        // start output activity command thread
        mOutputCommandThread = new AudioCommandThread(String8("ApmOutput"), this);
        
        /* 3 - 构造AudioPolicyClient实例:APC是AF的clinet端,很多任务都是通过跨进程调用到AF中 */
        mAudioPolicyClient = new AudioPolicyClient(this);

        /* 4 - 加载用户自定义的的AudioPolicyManager实现:libaudiopolicymanagercustom.so */
        loadAudioPolicyManager();

        /* 5 - 调用createAudioPolicyManager接口 */
        mAudioPolicyManager = mCreateAudioPolicyManager(mAudioPolicyClient);
    }

2.1、createAudioPolicyManager

static AudioPolicyInterface* createAudioPolicyManager(AudioPolicyClientInterface *clientInterface)
{
    AudioPolicyManager *apm = nullptr;
    media::AudioPolicyConfig apmConfig;
    /* 1、与AHAL交互获取modules信息,以确定是否存在用户自定义的configurable AudioPolicyConfig */
    if (status_t status = clientInterface->getAudioPolicyConfig(&apmConfig); status == OK) {
        auto config = AudioPolicyConfig::loadFromApmAidlConfigWithFallback(apmConfig);
        LOG_ALWAYS_FATAL_IF(config->getEngineLibraryNameSuffix() !=
                AudioPolicyConfig
Audioserver是一个系统进程,它在系统启动后开始执行。它主要负责启动两个子线程,作为Audio的服务端。这两个子线程分别是AudioFlinger和AudioPolicyService。其中,AudioFlinger是一个重要的组件,它负责处理音频的播放、录制和混音等功能。而AudioPolicyService则负责管理音频策略,例如音频路由和音量控制等。\[1\]在系统启动的过程中,Audioserver的执行涉及到多个步骤,其中包括调用AudioFlinger和AudioPolicyService的相关函数。例如,在第一步中,Audioserver会调用AudioFlinger的函数来创建音频路径。而在第四步中,Audioserver会调用Audio HAL来创建音频补丁。\[2\]\[3\]总的来说,AudioserverAndroid系统中负责处理音频相关功能的重要组件。 #### 引用[.reference_title] - *1* [Android Audio开发——audioserver初始化(四)](https://blog.youkuaiyun.com/c19344881x/article/details/130621774)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [【Android Audio】audioserver与audio hal hidl通信](https://blog.youkuaiyun.com/u013120422/article/details/108388584)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值