1、音频服务初始化流程
当前版本:Android 12
大致的创建流程如下:
1.1 开机启动音频服务
音频服务在frameworks/av/media/audioserver/main_audioserver.cpp
中,这里会启动音频的AudioFlinger
和AudioPolicyService
两大组件,简单的流程如下:
经过上面流程之后,音频系统中会启动AudioFlinger
用于处理后面所有的音频播放,AudioFlinger
具体的功能后面再详细分析,AudioPolicyService
负责后面的音频策略的处理等流程,AudioFlinger
和AudioPolicyService
之间进行交互
frameworks\av\media\audioserver\main_audioserver.cpp
AudioFlinger::instantiate(); AudioPolicyService::instantiate();
1.2 AudioFlinger
模块加载
通过上面流程会调用到AudioFlinger
的构造函数,进行AudioFlinger
模块的处理,流程如下:
AudioFlinger::AudioFlinger() : 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), mPatchPanel(this), mDeviceEffectManager(this), mSystemReady(false) { // Move the audio session unique ID generator start base as time passes to limit risk of // generating the same ID again after an audioserver restart. // This is important because clients will reuse previously allocated audio session IDs // when reconnecting after an audioserver restart and newly allocated IDs may conflict with // active clients. // Moving the base by 1 for each elapsed second is a good compromise between avoiding overlap // between allocation ranges and not reaching wrap around too soon. timespec ts{}; clock_gettime(CLOCK_MONOTONIC, &ts); // zero ID has a special meaning, so start allocation at least at AUDIO_UNIQUE_ID_USE_MAX uint32_t movingBase = (uint32_t)std::max((long)1, ts.tv_sec); // unsigned instead of audio_unique_id_use_t, because ++ operator is unavailable for enum for (unsigned use = AUDIO_UNIQUE_ID_USE_UNSPECIFIED; use < AUDIO_UNIQUE_ID_USE_MAX; use++) { mNextUniqueIds[use] = ((use == AUDIO_UNIQUE_ID_USE_SESSION || use == AUDIO_UNIQUE_ID_USE_CLIENT) ? movingBase : 1) * AUDIO_UNIQUE_ID_USE_MAX; } #if 1 // FIXME See bug 165702394 and bug 168511485 const bool doLog = false; #else const bool doLog = property_get_bool("ro.test_harness", false); #endif if (doLog) { mLogMemoryDealer = new MemoryDealer(kLogMemorySize, "LogWriters", MemoryHeapBase::READ_ONLY); (void) pthread_once(&sMediaLogOnce, sMediaLogInit); } // 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(); mDevicesFactoryHal = DevicesFactoryHalInterface::create(); mEffectsFactoryHal = EffectsFactoryHalInterface::create(); mMediaLogNotifier->run("MediaLogNotifier"); std::vector<pid_t> halPids; mDevicesFactoryHal->getHalPids(&halPids); TimeCheck::setAudioHalPids(halPids); // Notify that we have started (also called when audioserver service restarts) mediametrics::LogItem(mMetricsId) .set(AMEDIAMETRICS_PROP_EVENT, AMEDIAMETRICS_PROP_EVENT_VALUE_CTOR) .record(); } 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)); } } mMode = AUDIO_MODE_NORMAL; gAudioFlinger = this; // we are already refcounted, store into atomic pointer. mDevicesFactoryHalCallback = new DevicesFactoryHalCallbackImpl; mDevicesFactoryHal->setCallbackOnce(mDevicesFactoryHalCallback); }
在上面的构造函数中实例化了设备接口以及音效接口,此时AudioFlinger
模块已经成功创建出来,后面AudioPolicyService
创建出来后就可以和AudioFlinger
之间进行交互了
1.3 AudioPolicyService
模块加载
AudioPolicyService
负责音频的一些策略管理以及命令处理,具体的启动流程如下:
frameworks\av\services\audiopolicy\service\AudioPolicyService.cpp
AudioPolicyService::AudioPolicyService() : BnAudioPolicyService(), mAudioPolicyManager(NULL), mAudioPolicyClient(NULL), mPhoneState(AUDIO_MODE_INVALID), mCaptureStateNotifier(false), mCreateAudioPolicyManager(createAudioPolicyManager), mDestroyAudioPolicyManager(destroyAudioPolicyManager) { }
mCreateAudioPolicyManager是CreateAudioPolicyManagerInstance类型的实例
using CreateAudioPolicyManagerInstance = AudioPolicyInterface* (*)(AudioPolicyClientInterface*); using DestroyAudioPolicyManagerInstance = void (*)(AudioPolicyInterface*);
CreateAudioPolicyManagerInstance是一个函数指针指向 createAudioPolicyManager
mDestroyAudioPolicyManager同理
mAudioPolicyManager = mCreateAudioPolicyManager(mAudioPolicyClient); 就相当于 createAudioPolicyManager(mAudioPolicyClient)
void AudioPolicyService::onFirstRef() { { Mutex::Autolock _l(mLock); // 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); } // load audio processing modules sp<AudioPolicyEffects> audioPolicyEffects = new AudioPolicyEffects(); sp<UidPolicy> uidPolicy = new UidPolicy(this); sp<SensorPrivacyPolicy> sensorPrivacyPolicy = new SensorPrivacyPolicy(this); { Mutex::Autolock _l(mLock); mAudioPolicyEffects = audioPolicyEffects; mUidPolicy = uidPolicy; mSensorPrivacyPolicy = sensorPrivacyPolicy; } // @Rockchip For bootvideo char value[PROPERTY_VALUE_MAX]; property_get("persist.sys.bootvideo.enable", value, "false"); if (!strcmp(value, "true")) { mOutputCommandThread->registerUidCommand(uidPolicy); ALOGD("bootvideo enable,delay run Policy registerSelf"); } else { uidPolicy->registerSelf(); sensorPrivacyPolicy->registerSelf(); } // @end // Create spatializer if supported if (mAudioPolicyManager != nullptr) { Mutex::Autolock _l(mLock); const audio_attributes_t attr = attributes_initializer(AUDIO_USAGE_MEDIA); AudioDeviceTypeAddrVector devices; bool hasSpatializer = mAudioPolicyManager->canBeSpatialized(&attr, nullptr, devices); if (hasSpatializer) { mSpatializer = Spatializer::create(this); } } AudioSystem::audioPolicyReady(); }
1. static AudioPolicyInterface* createAudioPolicyManager(AudioPolicyClientInterface *clientInterface) 2. { 3. AudioPolicyManager *apm = new AudioPolicyManager(clientInterface); 4. status_t status = apm->initialize(); 5. if (status != NO_ERROR) { 6. delete apm; 7. apm = nullptr; 8. } 9. return apm; 10. }
frameworks\av\services\audiopolicy\managerdefault\AudioPolicyManager.cpp
创建AudioPolicyManager
AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface, bool /*forTesting*/) : mUidCached(AID_AUDIOSERVER), // no need to call getuid(), there's only one of us running. mpClientInterface(clientInterface), mLimitRingtoneVolume(false), mLastVoiceVolume(-1.0f), mA2dpSuspended(false), mConfig(mHwModulesAll, mOutputDevicesAll, mInputDevicesAll, mDefaultOutputDevice), mAudioPortGeneration(1), mBeaconMuteRefCount(0), mBeaconPlayingRefCount(0), mBeaconMuted(false), mTtsOutputAvailable(false), mMasterMono(false), mMusicEffectOutput(AUDIO_IO_HANDLE_NONE) { } AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface) : AudioPolicyManager(clientInterface, false /*forTesting*/) { loadConfig(); }
void AudioPolicyManager::loadConfig() { if (deserializeAudioPolicyXmlConfig(getConfig()) != NO_ERROR) { ALOGE("could not load audio policy configuration file, setting defaults"); getConfig().setDefault(); } //TODO: b/193496180 use spatializer flag at audio HAL when available getConfig().convertSpatializerFlag(); }
status_t AudioPolicyManager::initialize() { { auto engLib = EngineLibrary::load( "libaudiopolicyengine" + getConfig().getEngineLibraryNameSuffix() + ".so"); if (!engLib) { ALOGE("%s: Failed to load the engine library", __FUNCTION__); return NO_INIT; } mEngine = engLib->createEngine(); if (mEngine == nullptr) { ALOGE("%s: Failed to instantiate the APM engine", __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; } mCommunnicationStrategy = mEngine->getProductStrategyForAttributes( mEngine->getAttributesForStreamType(AUDIO_STREAM_VOICE_CALL)); // after parsing the config, mOutputDevicesAll and mInputDevicesAll contain all known devices; // open all output streams needed to access attached devices onNewAudioModulesAvailableInt(nullptr /*newDevices*/); // make sure default device is reachable if (mDefaultOutputDevice == 0 || !mAvailableOutputDevices.contains(mDefaultOutputDevice)) { ALOGE_IF(mDefaultOutputDevice != 0, "Default device %s is unreachable", mDefaultOutputDevice->toString().c_str()); 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]->address().empty()) { if (mAvailableInputDevices[i]->type() == AUDIO_DEVICE_IN_BUILTIN_MIC) { mAvailableInputDevices[i]->setAddress(AUDIO_BOTTOM_MICROPHONE_ADDRESS); } else if (mAvailableInputDevices[i]->type() == AUDIO_DEVICE_IN_BACK_MIC) { mAvailableInputDevices[i]->setAddress(AUDIO_BACK_MICROPHONE_ADDRESS); } } } ALOGW_IF(mPrimaryOutput == nullptr, "The policy configuration does not declare a primary output"); // Silence ALOGV statements property_set("log.tag." LOG_TAG, "D"); updateDevicesAndOutputs(); return status; }
- 这里调用的
createAudioPolicyManager
- 解析的配置文件包含
audio_policy_configuration.xml
,用于解析包含音频策略在内的一些配置文件 deserializeAudioPolicyFile
方法定义在frameworks/av/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp
文件中primary_audio_policy_configuration.xml
文件解析流程配置解析- Engine配置分析
总结:
- 首先分析了从
AudioPolicyService
创建AudioPolicyManager
的流程,这里涉及到第三方自己的AudioPolicyManager
,所以中间多了一个AudioPolicyManagerSPRD
的创建- 有了
AudioPolicyManager
对象之后需要加载音频的一些配置文件,包括描述所有外部设备以及设备之间路由情况的primary_audio_policy_configuration.xml
,这个xml
文件解析之后会将内容存放到AudioPolicyManager
持有的AudioPolicyConfig
对象中,具体的作用我们后面分析- 加载完
xml
之后就是进行Engine
对象的创建,这个Engine
对象负责管理音频策略相关的内容Engine
对象创建完毕之后需要对xml
解析出来的内容进行处理,这部分涉及和AudioFlinger
的交互,放在后面一节讲述