引言AudioPolicyService是Android音頻系統(tǒng)的兩大服務(wù)之一,另一個(gè)服務(wù)是AudioFlinger,這兩大服務(wù)都在系統(tǒng)啟動(dòng)時(shí)有MediaSever加載,加載的代碼位于:frameworks/base/media/mediaserver/main_mediaserver.cpp。AudioFlinger主要負(fù)責(zé)管理音頻數(shù)據(jù)處理以及和硬件抽象層相關(guān)的工作。本文主要介紹AudioPolicyService。 AudioPolicyServiceAudioPolicyService主要完成以下任務(wù):
AudioPolicyService的構(gòu)成下面這張圖描述了AudioPolicyService的靜態(tài)結(jié)構(gòu):
進(jìn)一步說(shuō)明: 1. AudioPolicyService繼承了IAudioPolicyService接口,這樣AudioPolicyService就可以基于Android的Binder機(jī)制,向外部提供服務(wù); 2. AudioPolicyService同時(shí)也繼承了AudioPolicyClientInterface類,他有一個(gè)AudioPolicyInterface類的成員指針mpPolicyManager,實(shí)際上就是指向了AudioPolicyManager; 3. AudioPolicyManager類繼承了AudioPolicyInterface類以便向AudioPolicyService提供服務(wù),反過(guò)來(lái)同時(shí)還有一個(gè)AudioPolicyClientInterface指針,該指針在構(gòu)造函數(shù)中被初始化,指向了AudioPolicyService,實(shí)際上,AudioPolicyService是通過(guò)成員指針mpPolicyManager訪問(wèn)AudioPolicyManager,而AudioPolicyManager則通過(guò)AudioPolicyClientInterface(mpClientInterface)訪問(wèn)AudioPolicyService; 4. AudioPolicyService有一個(gè)內(nèi)部線程類AudioCommandThread,顧名思義,所有的命令(音量控制,輸入、輸出的切換等)最終都會(huì)在該線程中排隊(duì)執(zhí)行; AudioPolicyManagerAudioPolicyService的很大一部分管理工作都是在AudioPolicyManager中完成的。包括音量管理,音頻策略(strategy)管理,輸入輸出設(shè)備管理。 輸入輸出設(shè)備管理音頻系統(tǒng)為音頻設(shè)備定義了一個(gè)枚舉:AudioSystem::audio_devices,例如:DEVICE_OUT_SPEAKER,DEVICE_OUT_WIRED_HEADPHONE,DEVICE_OUT_BLUETOOTH_A2DP,DEVICE_IN_BUILTIN_MIC,DEVICE_IN_VOICE_CALL等等,每一個(gè)枚舉值其實(shí)對(duì)應(yīng)一個(gè)32bit整數(shù)的某一個(gè)位,所以這些值是可以進(jìn)行位或操作的,例如我希望同時(shí)打開(kāi)揚(yáng)聲器和耳機(jī),那么可以這樣:
AudioPolicyManager中有兩個(gè)成員變量:mAvailableOutputDevices和mAvailableInputDevices,他們記錄了當(dāng)前可用的輸入和輸出設(shè)備,當(dāng)系統(tǒng)檢測(cè)到耳機(jī)或者藍(lán)牙已連接好時(shí),會(huì)調(diào)用AudioPolicyManager的成員函數(shù):
該函數(shù)根據(jù)傳入的device值和state(DEVICE_STATE_AVAILABLE/DEVICE_STATE_UNAVAILABLE)設(shè)置mAvailableOutputDevices或者mAvailableInputDevices,然后選擇相應(yīng)的輸入或者輸出設(shè)備。 其他一些相關(guān)的函數(shù):
音量管理AudioPolicyManager提供了一下幾個(gè)與音量相關(guān)的函數(shù):
AudioService.java中定義了每一種音頻流的最大音量級(jí)別:
由此可見(jiàn),電話鈴聲可以有7個(gè)級(jí)別的音量,而音樂(lè)則可以有15個(gè)音量級(jí)別,java的代碼通過(guò)jni,最后調(diào)用AudioPolicyManager的initStreamVolume(),把這個(gè)數(shù)組的內(nèi)容傳入AudioPolicyManager中,這樣AudioPolicyManager也就記住了每一個(gè)音頻流的音量級(jí)別。應(yīng)用程序可以調(diào)用setStreamVolumeIndex設(shè)置各個(gè)音頻流的音量級(jí)別,setStreamVolumeIndex會(huì)把這個(gè)整數(shù)的音量級(jí)別轉(zhuǎn)化為適合人耳的對(duì)數(shù)級(jí)別,然后通過(guò)AudioPolicyService的AudioCommandThread,最終會(huì)將設(shè)置應(yīng)用到AudioFlinger的相應(yīng)的Track中。 音頻策略管理我想首先要搞清楚stream_type,device,strategy三者之間的關(guān)系:
getStrategy(stream_type)根據(jù)stream type,返回對(duì)應(yīng)的routing strategy值,getDeviceForStrategy()則是根據(jù)routing strategy,返回可用的device。Android把10種stream type歸納為4種路由策略,然后根據(jù)路由策略決定具體的輸出設(shè)備。
成員變量mOutputs
這是AudioPolocyManager用管理輸出的鍵值對(duì)向量(數(shù)組),通常AudioPolocyManager會(huì)打開(kāi)3個(gè)輸出句柄(audio_io_handle_t),關(guān)于audio_io_handle_t,請(qǐng)參考另一編博客:http://blog.csdn.net/DroidPhone/archive/2010/10/14/5941344.aspx,它實(shí)際上就是AudioFlinger中某個(gè)PlaybackTread的ID。這3個(gè)句柄分別是:
可以通過(guò)startOutput()把某一個(gè)stream type放入到相應(yīng)的輸出中。
popCount()這個(gè)函數(shù)主要用來(lái)計(jì)算device變量中有多少個(gè)非0位(計(jì)算32位數(shù)種1的個(gè)數(shù)),例如該函數(shù)返回2,代表同時(shí)有兩個(gè)device要處理。之所以特別介紹它,是因?yàn)檫@個(gè)函數(shù)的實(shí)現(xiàn)很有意思:
不知道各位看懂了么?
AudioCommandThread這是AudioPolicyService中的一個(gè)線程,主要用于處理音頻設(shè)置相關(guān)的命令。包括:
每種命令的參數(shù)有相應(yīng)的包裝:
START_TONE/STOP_TONE:播放電話系統(tǒng)中常用的特殊音調(diào),例如:TONE_DTMF_0,TONE_SUP_BUSY等等。 SET_VOLUME:最終會(huì)調(diào)用AudioFlinger進(jìn)行音量設(shè)置 SET_VOICE_VOLUME:最終會(huì)調(diào)用AudioFlinger進(jìn)行電話音量設(shè)置 SET_PARAMETERS:通過(guò)一個(gè)KeyValuePairs形式的字符串進(jìn)行參數(shù)設(shè)置,KeyValuePairs的格式可以這樣:
這些KeyValuePairs可以通過(guò)AudioPolicyService的成員函數(shù)setParameters()傳入。 |
|
來(lái)自: John.Bouson > 《HAL》