[audio] AudioPolicy (一) 分析

av/media/audioserver/main_audioserver.cpp

这里面 makeAudioFlingerAudioPolicyService

cpp 复制代码
int main(int argc __unused, char **argv)
{
    android::hardware::configureRpcThreadpool(4, false /*callerWillJoin*/);

    ProcessState::self()->startThreadPool();
    
    const auto af = sp<AudioFlinger>::make();

    const auto afAdapter = sp<AudioFlingerServerAdapter>::make(af);

    AudioSystem::setLocalAudioFlinger(af)

    const auto aps = sp<AudioPolicyService>::make();

    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);
}

av/services/audiopolicy/service/AudioPolicyService.cpp

看下构造,这边主要是要注意在初始化 mCreateAudioPolicyManager 成员变量事是调了一个函数 createAudioPolicyManager

然后看下 onFirstRef

cpp 复制代码
AudioPolicyService::AudioPolicyService()
    : BnAudioPolicyService(),
      mAudioPolicyManager(NULL),
      mAudioPolicyClient(NULL),
      mPhoneState(AUDIO_MODE_INVALID),
      mCaptureStateNotifier(false),
      mCreateAudioPolicyManager(createAudioPolicyManager),
      mDestroyAudioPolicyManager(destroyAudioPolicyManager),
      mUsecaseValidator(media::createUsecaseValidator()),
      mPermissionController(sp<NativePermissionController>::make())
{
      setMinSchedulerPolicy(SCHED_NORMAL, ANDROID_PRIORITY_AUDIO);
      setInheritRt(true);
}

av/services/audiopolicy/service/AudioPolicyService.cpp onFirstRef

这里可以看到初始化了mCreateAudioPolicyManager

调用createAudioPolicyManager

cpp 复制代码
void AudioPolicyService::onFirstRef()
{

    // start audio commands thread
    mAudioCommandThread = new AudioCommandThread(String8("ApmAudio"), this);

    // start output activity command thread
    mOutputCommandThread = new AudioCommandThread(String8("ApmOutput"), this);

    mAudioPolicyClient = new AudioPolicyClient(this);

    loadAudioPolicyManager();

    mAudioPolicyManager = mCreateAudioPolicyManager(mAudioPolicyClient);

}

av/services/audiopolicy/service/AudioPolicyService.cpp createAudioPolicyManager

xml 装载后构造 AudioPolicyManager

然后调用 initialize

cpp 复制代码
static AudioPolicyInterface* createAudioPolicyManager(AudioPolicyClientInterface *clientInterface)
{
    AudioPolicyManager *apm = nullptr;

    media::AudioPolicyConfig apmConfig;

    if (status_t status = clientInterface->getAudioPolicyConfig(&apmConfig); status == OK) {

        auto config = AudioPolicyConfig::loadFromApmAidlConfigWithFallback(apmConfig);

        apm = new AudioPolicyManager(config,
                loadApmEngineLibraryAndCreateEngine(
                        config->getEngineLibraryNameSuffix(), apmConfig.engineConfig),
                clientInterface);

    } else {

        auto config = AudioPolicyConfig::loadFromApmXmlConfigWithFallback();  // This can't fail.

        apm = new AudioPolicyManager(config,
                loadApmEngineLibraryAndCreateEngine(config->getEngineLibraryNameSuffix()),
                clientInterface);

    }

    status_t status = apm->initialize();

    return apm;
}

av/services/audiopolicy/common/managerdefinitions/src/AudioPolicyConfig.cpp loadFromApmXmlConfigWithFallback

vendor/etc/audio_policy_configuration.xml

cpp 复制代码
sp<const AudioPolicyConfig> AudioPolicyConfig::loadFromApmXmlConfigWithFallback(
        const std::string& xmlFilePath) {
    const std::string filePath =
            xmlFilePath.empty() ? audio_get_audio_policy_config_file() : xmlFilePath;
    auto config = sp<AudioPolicyConfig>::make();
    if (status_t status = config->loadFromXml(filePath, false /*forVts*/); status == NO_ERROR) {
        return config;
    }
    return createDefault();
}

// av/services/audiopolicy/common/managerdefinitions/include/AudioPolicyConfig.h

class AudioPolicyConfig : public RefBase
{
private:    

    HwModuleCollection mHwModules; /**< Collection of Module, with Profiles, i.e. Mix Ports. */

    DeviceVector mOutputDevices;  // Attached output devices.

    DeviceVector mInputDevices;   // Attached input devices.

    sp<DeviceDescriptor> mDefaultOutputDevice;

};

vendor/etc/audio_policy_configuration.xml

mHwModules = <modules>

hwModule = <module name="primary" halVersion="2.0"> </module>

IOProfile = <mixPort> 输出流就是 OutputProfile 输入流就是 InputProfile

<profile /> 描述 mixPort 和 devicePort 的关系

DeviceDescriptor = <devicePort>

AudioRoute = <routes>描述是 OutputProfile 和 DeviceDescriptor 的关系

<attachedDevices> 表示一开机就能用于输入输出的硬件

XML 复制代码
<audioPolicyConfiguration version="1.0" xmlns:xi="http://www.w3.org/2001/XInclude">

    <modules>

        <!-- Primary Audio HAL -->
        <module name="primary" halVersion="2.0">

            <attachedDevices>
                <item>Speaker</item>
                <item>Built-In Mic</item>
                <item>Built-In Back Mic</item>
            </attachedDevices>

            <defaultOutputDevice>Speaker</defaultOutputDevice>

            <mixPorts>

                <mixPort name="primary output" role="source" flags="AUDIO_OUTPUT_FLAG_FAST|AUDIO_OUTPUT_FLAG_PRIMARY">
                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
                </mixPort>

                <mixPort name="raw" role="source"
                        flags="AUDIO_OUTPUT_FLAG_FAST">
                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
                </mixPort>

            </mixPorts>

            
            <devicePorts>
                <!-- Output devices declaration, i.e. Sink DEVICE PORT -->

                <devicePort tagName="Speaker" role="sink" type="AUDIO_DEVICE_OUT_SPEAKER" address="">
                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
                </devicePort>

                <devicePort tagName="Line" type="AUDIO_DEVICE_OUT_LINE" role="sink">
                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
                </devicePort>

            </devicePorts>

<!-- route declaration, i.e. list all available sources for a given sink -->
            <routes>

                <route type="mix" sink="Speaker"
                       sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,mmap_no_irq_out"/>

                <route type="mix" sink="Line"
                       sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,dsd_compress_passthrough,voip_rx,mmap_no_irq_out"/>
                
            </routes>

        </module>

    </modules>

</audioPolicyConfiguration>

av/services/audiopolicy/managerdefault/AudioPolicyManager.cpp 构造器 initialize

onNewAudioModulesAvailableInt

cpp 复制代码
AudioPolicyManager::AudioPolicyManager(const sp<const AudioPolicyConfig>& config,
                                       EngineInstance&& engine,
                                       AudioPolicyClientInterface *clientInterface)
    :
    mUidCached(AID_AUDIOSERVER), // no need to call getuid(), there's only one of us running.
    mConfig(config),
    mEngine(std::move(engine)),
    mpClientInterface(clientInterface),
    mLimitRingtoneVolume(false), mLastVoiceVolume(-1.0f),
    mA2dpSuspended(false),
    mAudioPortGeneration(1),
    mBeaconMuteRefCount(0),
    mBeaconPlayingRefCount(0),
    mBeaconMuted(false),
    mTtsOutputAvailable(false),
    mMasterMono(false),
    mMusicEffectOutput(AUDIO_IO_HANDLE_NONE)
{
}


status_t AudioPolicyManager::initialize() {

    onNewAudioModulesAvailableInt(nullptr /*newDevices*/);

    // make sure default device is reachable
    if (const auto defaultOutputDevice = mConfig->getDefaultOutputDevice();
            defaultOutputDevice == nullptr ||
            !mAvailableOutputDevices.contains(defaultOutputDevice)) {

        status = NO_INIT;
    }


    updateDevicesAndOutputs();
    return status;
}

av/services/audiopolicy/managerdefault/AudioPolicyManager.cpp onNewAudioModulesAvailableInt

onNewAudioModulesAvailableInt 遍历 xml 中的 <module>

调用 loadHwModule 装载到 mHwModules

每个具体的 hwModule 调用 outputDesc->open

将创建的 output hwModule 添加到 mAvailableOutputDevices

将创建的 input hwModule添加到 mAvailableInputDevices

primaryhwModule 就赋值给 mPrimaryOutput

cpp 复制代码
void AudioPolicyManager::onNewAudioModulesAvailableInt(DeviceVector *newDevices)
{

    for (const auto& hwModule : mConfig->getHwModules()) {

        if (hwModule->getHandle() == AUDIO_MODULE_HANDLE_NONE) {

            audio_module_handle_t handle = mpClientInterface->loadHwModule(hwModule->getName();

            hwModule->setHandle(handle);
        }

        mHwModules.push_back(hwModule);


        for (const auto& outProfile : hwModule->getOutputProfiles()) {

            const DeviceVector &supportedDevices = outProfile->getSupportedDevices();

            DeviceVector availProfileDevices = supportedDevices.filter(mConfig->getOutputDevices());

            sp<DeviceDescriptor> supportedDevice = 0;

            if (supportedDevices.contains(mConfig->getDefaultOutputDevice())) {

                supportedDevice = mConfig->getDefaultOutputDevice();

            }

            sp<SwAudioOutputDescriptor> outputDesc = new SwAudioOutputDescriptor(outProfile,
                                                                            mpClientInterface);

            audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;

            audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE;

            audio_attributes_t attributes = AUDIO_ATTRIBUTES_INITIALIZER;
            
            // 打开流
            status_t status = outputDesc->open(nullptr /* halConfig */, nullptr /* mixerConfig */,
                                               DeviceVector(supportedDevice),
                                               AUDIO_STREAM_DEFAULT,
                                               &flags, &output, attributes);

            for (const auto &device : availProfileDevices) {
                // give a valid ID to an attached device once confirmed it is reachable
                if (!device->isAttached()) {

                    device->attach(hwModule);

                    mAvailableOutputDevices.add(device);

                    device->setEncapsulationInfoFromHal(mpClientInterface);

                    if (newDevices) newDevices->add(device);

                    setEngineDeviceConnectionState(device, AUDIO_POLICY_DEVICE_STATE_AVAILABLE);

                }
            }

            if (mPrimaryOutput == nullptr &&
                    outProfile->getFlags() & AUDIO_OUTPUT_FLAG_PRIMARY) {
                mPrimaryOutput = outputDesc;
                mPrimaryModuleHandle = mPrimaryOutput->getModuleHandle();
            }
        }



        for (const auto& inProfile : hwModule->getInputProfiles()) {
            sp<AudioInputDescriptor> inputDesc = new AudioInputDescriptor(
                    inProfile, mpClientInterface, false /*isPreemptor*/);

            audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
            status_t status = inputDesc->open(nullptr,
                                              availProfileDevices.itemAt(0),
                                              AUDIO_SOURCE_MIC,
                                              (audio_input_flags_t) inProfile->getFlags(),
                                              &input);
            
            for (const auto &device : availProfileDevices) {
                // give a valid ID to an attached device once confirmed it is reachable
                if (!device->isAttached()) {

                    device->attach(hwModule);

                    device->importAudioPortAndPickAudioProfile(inProfile, true);

                    mAvailableInputDevices.add(device);

                    if (newDevices) newDevices->add(device);

                    setEngineDeviceConnectionState(device, AUDIO_POLICY_DEVICE_STATE_AVAILABLE);
                }
            }

            inputDesc->close();
        }

    }
}

调用 loadHwModule 装载到 mHwModules

av/services/audiopolicy/service/AudioPolicyClientImpl.cpp loadHwModule

cpp 复制代码
audio_module_handle_t AudioPolicyService::AudioPolicyClient::loadHwModule(const char *name)
{
    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();

    return af->loadHwModule(name);
}

av/services/audioflinger/AudioFlinger.cpp loadHwModule

走到这的话后面的 loadHwModule_ll 流程参考

https://blog.csdn.net/we1less/article/details/156506593?spm=1001.2014.3001.5502

主要是注意 namexml 中的 <module name="usb" halVersion="2.0">

cpp 复制代码
audio_module_handle_t AudioFlinger::loadHwModule(const char *name)
{

    AudioHwDevice* module = loadHwModule_ll(name);

    return module != nullptr ? module->handle() : AUDIO_MODULE_HANDLE_NONE;
}


每个具体的 hwModule 调用 outputDesc->open

av/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp open

cpp 复制代码
status_t SwAudioOutputDescriptor::open(const audio_config_t *halConfig,
                                       const audio_config_base_t *mixerConfig,
                                       const DeviceVector &devices,
                                       audio_stream_type_t stream,
                                       audio_output_flags_t *flags,
                                       audio_io_handle_t *output,
                                       audio_attributes_t attributes)
{
    mDevices = devices;

    status_t status = mClientInterface->openOutput(mProfile->getModuleHandle(),
                                                   output,
                                                   &lHalConfig,
                                                   &lMixerConfig,
                                                   device,
                                                   &mLatency,
                                                   &mFlags,
                                                   attributes);

    return status;
}

av/services/audiopolicy/service/AudioPolicyClientImpl.cpp openOutput

cpp 复制代码
status_t AudioPolicyService::AudioPolicyClient::openOutput(audio_module_handle_t module,
                                                           audio_io_handle_t *output,
                                                           audio_config_t *halConfig,
                                                           audio_config_base_t *mixerConfig,
                                                           const sp<DeviceDescriptorBase>& device,
                                                           uint32_t *latencyMs,
                                                           audio_output_flags_t *flags,
                                                           audio_attributes_t attributes)
{
    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();

    status_t status = af->openOutput(request, &response);

    return status;
}

av/services/audioflinger/AudioFlinger.cpp openOutput

走到这的话后面的 openOutput_l 流程参考

https://blog.csdn.net/we1less/article/details/156506593?spm=1001.2014.3001.5502

cpp 复制代码
status_t AudioFlinger::openOutput(const media::OpenOutputRequest& request,
                                media::OpenOutputResponse* response)
{
    const sp<IAfThreadBase> thread = openOutput_l(module, &output, &halConfig,
            &mixerConfig, deviceType, address, &flags, attributes);

    return NO_INIT;
}

av/services/audiopolicy/managerdefault/AudioPolicyManager.cpp addOutput

cpp 复制代码
void AudioPolicyManager::addOutput(audio_io_handle_t output,
                                   const sp<SwAudioOutputDescriptor>& outputDesc)
{
    mOutputs.add(output, outputDesc);
    applyStreamVolumes(outputDesc, DeviceTypeSet(), 0 /* delayMs */, true /* force */);
    updateMono(output); // update mono status when adding to output list
    selectOutputForMusicEffects();
    nextAudioPortGeneration();
}
相关推荐
常利兵9 小时前
2026年,Android开发已死?不,它正迎来黄金时代!
android
Risehuxyc9 小时前
备份三个PHP程序
android·开发语言·php
Doro再努力19 小时前
【Linux操作系统10】Makefile深度解析:从依赖推导到有效编译
android·linux·运维·服务器·编辑器·vim
Daniel李华19 小时前
echarts使用案例
android·javascript·echarts
做人不要太理性20 小时前
CANN Runtime 运行时组件深度解析:任务调度机制、存储管理策略与维测体系构建逻辑
android·运维·魔珐星云
我命由我1234521 小时前
Android 广播 - 静态注册与动态注册对广播接收器实例创建的影响
android·java·开发语言·java-ee·android studio·android-studio·android runtime
朗迹 - 张伟21 小时前
Tauri2 导出 Android 详细教程
android
lpruoyu1 天前
【Android第一行代码学习笔记】Android架构_四大组件_权限_持久化_通知_异步_服务
android·笔记·学习
独自破碎E1 天前
【BISHI15】小红的夹吃棋
android·java·开发语言
李堇1 天前
android滚动列表VerticalRollingTextView
android·java