本文基于 Android 9.0 进行分析

自Android6.0后,Audio模块便和Media模块分离开,成为独立模块。

它的启动入口位于:
frameworks/av/media/audioserver/main_audioserver.cpp
由frameworks/av/media/audioserver/audioserver.rc文件引导.主要作用是调用了AudioFlinger和AudioPolicyService这两大模块的初始化接口。

1.设备开机,系统启动时将执行 /system/etc/init/audioserver.rc ,运行 /system/bin/ 目录下的 audioserver 服务。audioserver.rc 内容如下:

service audioserver /system/bin/audioserver
    class core
    user audioserver
    # media gid needed for /dev/fm (radio) and for /data/misc/media (tee)
    group audio camera drmrpc inet media mediadrm net_bt net_bt_admin net_bw_acct
    ioprio rt 4
    writepid /dev/cpuset/foreground/tasks /dev/stune/foreground/tasks
    onrestart restart vendor.audio-hal-2-0
    # Keep the original service name for backward compatibility when upgrading
    # O-MR1 devices with framework-only.
    onrestart restart audio-hal-2-0
    disabled

on property:vts.native_server.on=1
    stop audioserver
on property:vts.native_server.on=0
    start audioserver

2.进程入口:

int main(int argc __unused, char **argv)
{
	......
	if (doLog && (childPid = fork()) != 0){
	...
	}else{
	...
        // all other services
        if (doLog) {
            prctl(PR_SET_PDEATHSIG, SIGKILL);   // if parent media.log dies before me, kill me also
            setpgid(0, 0);                      // but if I die first, don't kill my parent
        }
        android::hardware::configureRpcThreadpool(4, false /*callerWillJoin*/);
        sp<ProcessState> proc(ProcessState::self());
        sp<IServiceManager> sm = defaultServiceManager();
        ALOGI("ServiceManager: %p", sm.get());
        AudioFlinger::instantiate();
        AudioPolicyService::instantiate();

        // AAudioService should only be used in OC-MR1 and later.
        // And only enable the AAudioService if the system MMAP policy explicitly allows it.
        // This prevents a client from misusing AAudioService when it is not supported.
        aaudio_policy_t mmapPolicy = property_get_int32(AAUDIO_PROP_MMAP_POLICY,
                                                        AAUDIO_POLICY_NEVER);
        if (mmapPolicy == AAUDIO_POLICY_AUTO || mmapPolicy == AAUDIO_POLICY_ALWAYS) {
            AAudioService::instantiate();
        }

        SoundTriggerHwService::instantiate();
        ProcessState::self()->startThreadPool();
        IPCThreadState::self()->joinThreadPool();
   } 
}

audioserver 进程会依次对 AudioFlinger、AudioPolicyService进行实例化
其调用了AudioFlinger和AudioPolicyServer的instantiate()接口,是个单例模式。然后就是启动并加入线程池

3.audiofinger的启动调用流程:

在AudioFlinger类里找不到这个instantiate()接口,按照谷歌的惯性自然要去它的父类寻找,如下:

class AudioFlinger :
    public BinderService<AudioFlinger>,
    public BnAudioFlinger
{
    friend class BinderService<AudioFlinger>;   // for AudioFlinger()
class BinderService
{
public:
    static status_t publish(bool allowIsolated = false,
                            int dumpFlags = IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT) {
        sp<IServiceManager> sm(defaultServiceManager());
        return sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated,
                              dumpFlags);
    }   

    static void publishAndJoinThreadPool(
            bool allowIsolated = false,
            int dumpFlags = IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT) {
        publish(allowIsolated, dumpFlags);
        joinThreadPool();
    }   

    static void instantiate() { publish(); }

new了一个SERVICE(即AudioFlinger),并注册到Manager服务里,方便其他模块申请服务
AudioFlinger的构造函数:

AudioFlinger::AudioFlinger()
    : BnAudioFlinger(),
      mMediaLogNotifier(new AudioFlinger::MediaLogNotifier()),
      mPrimaryHardwareDev(NULL),
      mAudioHwDevs(NULL),
      mHardwareStatus(AUDIO_HW_IDLE),
      mMasterVolume(1.0f),
      mMasterMute(false),
      // mNextUniqueId(AUDIO_UNIQUE_ID_USE_MAX),
      mMode(AUDIO_MODE_INVALID),
      mBtNrecIsOff(false),
      mIsLowRamDevice(true),
      mIsDeviceTypeKnown(false),
      mTotalMemory(0),
      mClientSharedHeapSize(kMinimumClientSharedHeapSizeBytes),
      mGlobalEffectEnableTime(0),
      mSystemReady(false)

所有使用智能指针(继承RefBase)的类在第一次创建时都会调用refBase()函数

void AudioFlinger::onFirstRef()
{
    Mutex::Autolock _l(mLock);

    /* TODO: move all this work into an Init() function */
    char val_str[PROPERTY_VALUE_MAX] = { 0 };
    if (property_get("ro.audio.flinger_standbytime_ms", val_str, NULL) >= 0) {
        uint32_t int_val;
        if (1 == sscanf(val_str, "%u", &int_val)) {
            mStandbyTimeInNsecs = milliseconds(int_val);
            ALOGI("Using %u mSec as standby time.", int_val);
        } else {
            mStandbyTimeInNsecs = kDefaultStandbyTimeInNsecs;
            ALOGI("Using default %u mSec as standby time.",
                    (uint32_t)(mStandbyTimeInNsecs / 1000000));
        }
    }

    mPatchPanel = new PatchPanel(this);

    mMode = AUDIO_MODE_NORMAL;

    gAudioFlinger = this;
}

4.AudioPolicyService的启动调用流程:
同AudioFlinger:
构造函数:

AudioPolicyService::AudioPolicyService()
    : BnAudioPolicyService(), mpAudioPolicyDev(NULL), mpAudioPolicy(NULL),
      mAudioPolicyManager(NULL), mAudioPolicyClient(NULL), mPhoneState(AUDIO_MODE_INVALID)
{
}

onFirstRef:

void AudioPolicyService::onFirstRef()
{
    {
        Mutex::Autolock _l(mLock);

        // start tone playback thread
        mTonePlaybackThread = new AudioCommandThread(String8("ApmTone"), this);
        // 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);
        mAudioPolicyManager = createAudioPolicyManager(mAudioPolicyClient);
    }
    // load audio processing modules
    sp<AudioPolicyEffects>audioPolicyEffects = new AudioPolicyEffects();
    {
        Mutex::Autolock _l(mLock);
        mAudioPolicyEffects = audioPolicyEffects;
    }

    mUidPolicy = new UidPolicy(this);
    mUidPolicy->registerSelf();
}
extern "C" AudioPolicyInterface* createAudioPolicyManager(
        AudioPolicyClientInterface *clientInterface)
{
    return new AudioPolicyManager(clientInterface);
}

AudioPolicyManager 的构造函数将解析音频策略配置文件,从而获取到设备所支持的音频设备信息(包括设备是否支持 Offload、Direct 模式输出,各输入输出 profile 所支持的采样率、通道数、数据格式等),加载全部 HwModule,为之创建所有非 direct 输出类型的 outputStream 和所有 inputStream,并创建相应的 playbackThread 或 recordThread 线程。需要注意的是,Android 7.0上的音频策略配置文件开始使用 XML 格式,其文件名为 audio_policy_configuration.xml,而在之前的版本上音频策略配置文件为 audio_policy.conf。frameworks/av/services/audiopolicy/managerdefault/AudioPolicyManager.cpp 中

AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface)
        : AudioPolicyManager(clientInterface, false /*forTesting*/)
{
    loadConfig();
    initialize();
}
void AudioPolicyManager::loadConfig() {
#ifdef USE_XML_AUDIO_POLICY_CONF
    if (deserializeAudioPolicyXmlConfig(getConfig()) != NO_ERROR) {
#else
    if ((ConfigParsingUtils::loadConfig(AUDIO_POLICY_VENDOR_CONFIG_FILE, getConfig()) != NO_ERROR)
           && (ConfigParsingUtils::loadConfig(AUDIO_POLICY_CONFIG_FILE, getConfig()) != NO_ERROR)) {
#endif
        ALOGE("could not load audio policy configuration file, setting defaults");
        getConfig().setDefault();
    }
}
status_t AudioPolicyManager::initialize(){
mVolumeCurves->initializeVolumeCurves(getConfig().isSpeakerDrcEnabled());
// Once policy config has been parsed, retrieve an instance of the engine and initialize it.
audio_policy::EngineInstance *engineInstance = audio_policy::EngineInstance::getInstance();
if (!engineInstance) {
ALOGE("%s: Could not get an instance of policy engine", __FUNCTION__);
return NO_INIT;
}
// Retrieve the Policy Manager Interface
mEngine = engineInstance->queryInterface<AudioPolicyManagerInterface>();
if (mEngine == NULL) {
ALOGE("%s: Failed to get Policy Engine Interface", __FUNCTION__);
return NO_INIT;
}
mEngine->setObserver(this);
status_t status = mEngine->initCheck();
if (status != NO_ERROR) {
LOG_FATAL("Policy engine not initialized(err=%d)", status);
return status;
}
// mAvailableOutputDevices and mAvailableInputDevices now contain all attached devices
// open all output streams needed to access attached devices
audio_devices_t outputDeviceTypes = mAvailableOutputDevices.types();
audio_devices_t inputDeviceTypes = mAvailableInputDevices.types() & ~AUDIO_DEVICE_BIT_IN;
for (const auto& hwModule : mHwModulesAll) {
hwModule->setHandle(mpClientInterface->loadHwModule(hwModule->getName()));
if (hwModule->getHandle() == AUDIO_MODULE_HANDLE_NONE) {
ALOGW("could not open HW module %s", hwModule->getName());
continue;
}
mHwModules.push_back(hwModule);
// open all output streams needed to access attached devices
// except for direct output streams that are only opened when they are actually
// required by an app.
// This also validates mAvailableOutputDevices list
for (const auto& outProfile : hwModule->getOutputProfiles()) {
if (!outProfile->canOpenNewIo()) {
ALOGE("Invalid Output profile max open count %u for profile %s",
outProfile->maxOpenCount, outProfile->getTagName().c_str());
continue;
}
if (!outProfile->hasSupportedDevices()) {
ALOGW("Output profile contains no device on module %s", hwModule->getName());
continue;
}
if ((outProfile->getFlags() & AUDIO_OUTPUT_FLAG_TTS) != 0) {
mTtsOutputAvailable = true;
}
if ((outProfile->getFlags() & AUDIO_OUTPUT_FLAG_DIRECT) != 0) {
continue;
}
audio_devices_t profileType = outProfile->getSupportedDevicesType();
if ((profileType & mDefaultOutputDevice->type()) != AUDIO_DEVICE_NONE) {
profileType = mDefaultOutputDevice->type();
} else {
// chose first device present in profile's SupportedDevices also part of
// outputDeviceTypes
profileType = outProfile->getSupportedDeviceForType(outputDeviceTypes);
}
if ((profileType & outputDeviceTypes) == 0) {
continue;
}
sp<SwAudioOutputDescriptor> outputDesc = new SwAudioOutputDescriptor(outProfile,
mpClientInterface);
const DeviceVector &supportedDevices = outProfile->getSupportedDevices();
const DeviceVector &devicesForType = supportedDevices.getDevicesFromType(profileType);
String8 address = devicesForType.size() > 0 ? devicesForType.itemAt(0)->mAddress
: String8("");
audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
status_t status = outputDesc->open(nullptr, profileType, address,
AUDIO_STREAM_DEFAULT, AUDIO_OUTPUT_FLAG_NONE, &output);
if (status != NO_ERROR) {
ALOGW("Cannot open output stream for device %08x on hw module %s",
outputDesc->mDevice,
hwModule->getName());
} else {
for (const auto& dev : supportedDevices) {
ssize_t index = mAvailableOutputDevices.indexOf(dev);
// give a valid ID to an attached device once confirmed it is reachable
if (index >= 0 && !mAvailableOutputDevices[index]->isAttached()) {
mAvailableOutputDevices[index]->attach(hwModule);
}
}
if (mPrimaryOutput == 0 &&
outProfile->getFlags() & AUDIO_OUTPUT_FLAG_PRIMARY) {
mPrimaryOutput = outputDesc;
}
addOutput(output, outputDesc);
setOutputDevice(outputDesc,
profileType,
true,
0,
NULL,
address);
}
}
// open input streams needed to access attached devices to validate
// mAvailableInputDevices list
for (const auto& inProfile : hwModule->getInputProfiles()) {
if (!inProfile->canOpenNewIo()) {
ALOGE("Invalid Input profile max open count %u for profile %s",
inProfile->maxOpenCount, inProfile->getTagName().c_str());
continue;
}
if (!inProfile->hasSupportedDevices()) {
ALOGW("Input profile contains no device on module %s", hwModule->getName());
continue;
}
// chose first device present in profile's SupportedDevices also part of
// inputDeviceTypes
audio_devices_t profileType = inProfile->getSupportedDeviceForType(inputDeviceTypes);
if ((profileType & inputDeviceTypes) == 0) {
continue;
}
sp<AudioInputDescriptor> inputDesc =
new AudioInputDescriptor(inProfile, mpClientInterface);
DeviceVector inputDevices = mAvailableInputDevices.getDevicesFromType(profileType);
// the inputs vector must be of size >= 1, but we don't want to crash here
String8 address = inputDevices.size() > 0 ? inputDevices.itemAt(0)->mAddress
: String8("");
ALOGV(" for input device 0x%x using address %s", profileType, address.string());
ALOGE_IF(inputDevices.size() == 0, "Input device list is empty!");
audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
status_t status = inputDesc->open(nullptr,
profileType,
address,
AUDIO_SOURCE_MIC,
AUDIO_INPUT_FLAG_NONE,
&input);
if (status == NO_ERROR) {
for (const auto& dev : inProfile->getSupportedDevices()) {
ssize_t index = mAvailableInputDevices.indexOf(dev);
// give a valid ID to an attached device once confirmed it is reachable
if (index >= 0) {
sp<DeviceDescriptor> devDesc = mAvailableInputDevices[index];
if (!devDesc->isAttached()) {
devDesc->attach(hwModule);
devDesc->importAudioPort(inProfile, true);
}
}
}
inputDesc->close();
} else {
ALOGW("Cannot open input stream for device %08x on hw module %s",
profileType,
hwModule->getName());
}
}
}
// make sure all attached devices have been allocated a unique ID
for (size_t i = 0; i  < mAvailableOutputDevices.size();) {
if (!mAvailableOutputDevices[i]->isAttached()) {
ALOGW("Output device %08x unreachable", mAvailableOutputDevices[i]->type());
mAvailableOutputDevices.remove(mAvailableOutputDevices[i]);
continue;
}
// The device is now validated and can be appended to the available devices of the engine
mEngine->setDeviceConnectionState(mAvailableOutputDevices[i],
AUDIO_POLICY_DEVICE_STATE_AVAILABLE);
i++;
}
for (size_t i = 0; i  < mAvailableInputDevices.size();) {
if (!mAvailableInputDevices[i]->isAttached()) {
ALOGW("Input device %08x unreachable", mAvailableInputDevices[i]->type());
mAvailableInputDevices.remove(mAvailableInputDevices[i]);
continue;
}
// The device is now validated and can be appended to the available devices of the engine
mEngine->setDeviceConnectionState(mAvailableInputDevices[i],
AUDIO_POLICY_DEVICE_STATE_AVAILABLE);
i++;
}
// make sure default device is reachable
if (mDefaultOutputDevice == 0 || mAvailableOutputDevices.indexOf(mDefaultOutputDevice) < 0) {
ALOGE("Default device %08x is unreachable", mDefaultOutputDevice->type());
status = NO_INIT;
}
// If microphones address is empty, set it according to device type
for (size_t i = 0; i  < mAvailableInputDevices.size(); i++) {
if (mAvailableInputDevices[i]->mAddress.isEmpty()) {
if (mAvailableInputDevices[i]->type() == AUDIO_DEVICE_IN_BUILTIN_MIC) {
mAvailableInputDevices[i]->mAddress = String8(AUDIO_BOTTOM_MICROPHONE_ADDRESS);
} else if (mAvailableInputDevices[i]->type() == AUDIO_DEVICE_IN_BACK_MIC) {
mAvailableInputDevices[i]->mAddress = String8(AUDIO_BACK_MICROPHONE_ADDRESS);
}
}
}
if (mPrimaryOutput == 0) {
ALOGE("Failed to open primary output");
status = NO_INIT;
}
updateDevicesAndOutputs();
return status;
}

5.至此,Android 系统中音频模块的启动就完成了,两大关键音频组件 AudioFlinger 和 AudioPolicyService 均已创建并运行,设备所支持的音频输入输出硬件信息也已经被 AudioPolicyManager 所解析。如果此时发生了插入耳机等操作,则 AudioPolicyService 将会接收到底层通知并把 Audio Route 切换到 WiredHeadset 等响应配置;如果此时在 APP 发生了播放音乐的操作,则 AudioFlinger 会接收到上层通知并创建相应 Track。

本文地址:https://blog.csdn.net/weixin_44991625/article/details/107939154