目錄
1、audioserver啟動
2、AudioPolicyService啟動
3、AudioFlinger啟動
audio的核心服務有兩個,AudioPolicyService 和AudioFlinger他們到在audioserver一個進程中
1、audioserver啟動
設備開機,系統啟動時將執行 /system/etc/init/audioserver.rc ,運行 /system/bin/ 目錄下的 audioserver 服務。
機器上路徑
console:/ # ls /system/etc/init/audioserver.rc?
/system/etc/init/audioserver.rc
源碼上路徑
frameworks/av/media/audioserver/audioserver.rc
內容如下:
1 service audioserver /system/bin/audioserver
2 class core
3 user audioserver
4 # media gid needed for /dev/fm (radio) and for /data/misc/media (tee)
5 group audio camera drmrpc media mediadrm net_bt net_bt_admin net_bw_acct wakelock
6 capabilities BLOCK_SUSPEND
7 ioprio rt 4
8 task_profiles ProcessCapacityHigh HighPerformance
9
10 onrestart setprop sys.audio.restart.hal 1
audioserver 進程會依次對 AudioFlinger、AudioPolicyService、RadioService、SoundTriggerHwService 進行實例化。如果設備集成了杜比音效,杜比音效的內存管理服務 DolbyMemoryService 也會在這里進行實例化。
2、AudioPolicyService啟動
AudioPolicyService服務運行在audioserver進程中, 隨著audioserver進程啟動而啟動。
frameworks/av/media/audioserver/main_audioserver.cpp
int main(int argc __unused, char **argv){……sp<ProcessState> proc(ProcessState::self());sp<IServiceManager> sm = defaultServiceManager();ALOGI("ServiceManager: %p", sm.get());AudioFlinger::instantiate();//實例化AudioFlinger服務,AudioFlinger 的實例化先于AudioPolicyServiceAudioPolicyService::instantiate();//實例化AudioPlicyService服務
}
????????其中,AudioPolicyService::instantiate()并不由AudioPolicyService實現,而是BinderService類的一個實現包括AudioFlinger,AudioPolicyservice等在內的幾個服務都繼承自這個統一的Binder的服務類,具體實現在BinderService.h中。如果后續我們需要自己開發一個基于binder的服務那么也可以繼承binderservice來實現。
static void instantiate() { publish(); }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);//注冊服務到servicemanager中}
publish()函數獲取到ServiceManager的代理,然后new一個調用instantiate的service對象并把它添加到ServiceManager中。AudioPolicyService 開始構造并調用 AudioPolicyService::onFirstRef() 方法進行初始化,這個過程中會創建 AudioPolicyManager 對象
frameworks/av/services/audiopolicy/service/AudioPolicyService.cpp
void AudioPolicyService::onFirstRef()
{{Mutex::Autolock _l(mLock);// start audio commands threadmAudioCommandThread = new AudioCommandThread(String8("ApmAudio"), this);//創建ApmAudio線程用于執行audio命令// start output activity command threadmOutputCommandThread = new AudioCommandThread(String8("ApmOutput"), this);//創建ApmOutpur線程用于執行輸出命令mAudioPolicyClient = new AudioPolicyClient(this);//創建AudioPolicyClient對象ALOGE("czhaudio AudioPolicyService createAudioPolicyManager");mAudioPolicyManager = createAudioPolicyManager(mAudioPolicyClient);// 創建 AudioPolicyManager 對象}// load audio processing modules//解析audio_effects.conf 文件,得到并加載系統支持的音效庫。初始化各個音效對應的參數,將各音效和對應的輸入和輸出//流綁定在一起,這樣,當上層要使用音效時,就會在對應的threadloop中調用process_l音效處理函數。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;}uidPolicy->registerSelf();sensorPrivacyPolicy->registerSelf();
}
這里audiopolicyservice為什么要起兩個commandthread?audioflinger和audiopoliyservice是在同一個進程。如果audiopolicymanager直接調用audioflinger的接口就會阻塞住。(也就是同步的)。
而通過線程去調用audioflinger的話或者處理一些耗時的任務,audiopolicymanager就可以很快返回不需要阻塞住createAudioPolicyManager() 函數的實現位于 frameworks/av/services/audiopolicy/manager/AudioPolicyFactory.cpp文件中。
查看源碼后我們會發現它實際上是直接調用了 AudioPolicyManager 的構造函數
extern "C" AudioPolicyInterface* createAudioPolicyManager(AudioPolicyClientInterface *clientInterface)
{AudioPolicyManager *apm = new AudioPolicyManager(clientInterface); // 調用 AudioPolicyManager 的構造函數創建對象status_t status = apm->initialize(); //進行初始化硬件各個模塊if (status != NO_ERROR) {delete apm;apm = nullptr;}return apm;
}
????????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::AudioPolicyManager(AudioPolicyClientInterface *clientInterface): AudioPolicyManager(clientInterface, false /*forTesting*/)
{loadConfig();
}
loadConfig:下片介紹 https://blog.csdn.net/niaohaoge/article/details/147394152
3、AudioFlinger啟動
接1 節的publish,直接分析構造函數
AudioFlinger::instantiate();//實例化AudioFlinger服務,AudioFlinger 的實例化先于AudioPolicyService
?
AudioFlinger::AudioFlinger(): BnAudioFlinger(),mPrimaryHardwareDev(NULL),//...mGlobalEffectEnableTime(0),mPrimaryOutputSampleRate(0)
{getpid_cached = getpid();char value[PROPERTY_VALUE_MAX];//...
}
主要是一些變量的初始化,之后主要看onFirstRef的實現,代碼如下:
void AudioFlinger::onFirstRef()
{int rc = 0;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);} else {mStandbyTimeInNsecs = kDefaultStandbyTimeInNsecs;}}//這里將AudioFlinger傳遞給PatchPanel,其他并沒有做什么mPatchPanel = new PatchPanel(this);mMode = AUDIO_MODE_NORMAL;
}