[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();
}
相关推荐
TheNextByte114 小时前
如何在不使用USB数据线的情况下将文件从电脑传到安卓手机?
android·智能手机·电脑
李小轰14 小时前
把手机变成听诊器!摄像头 30 秒隔空测心率 - 开箱即用
android·视觉检测
走在路上的菜鸟14 小时前
Android学Flutter学习笔记 第三节 Android视角认知Flutter(触摸事件,List,Text,Input)
android·学习·flutter
Android-Flutter14 小时前
android compose Drawer抽屉 使用
android·kotlin
禾叙_1 天前
【canal】canal同步msyql到redis
android·redis·python
下位子1 天前
『OpenGL学习滤镜相机』- Day 12: LUT 滤镜(Look-Up Table)
android·opengl
下位子1 天前
『OpenGL学习滤镜相机』- Day 11: 实时滤镜效果
android·opengl
shankss1 天前
GetX 状态管理详解
android·flutter·ios
坚持学习前端日记1 天前
原生Android开发与JS桥开发对比分析
android·开发语言·javascript