????????
目錄
一、應(yīng)用API層
二、Java框架層
三、Native核心層
3.1 AudioFlinger模塊
3.2 AudioPolicyService模塊
四、HAL層
????????本文基于AOSP13源碼進(jìn)行分析解讀。所以與各個SoC平臺廠商提供的運行在真實設(shè)備上的源碼會有細(xì)微差異,但核心原理區(qū)別不大。
????????音頻子系統(tǒng)在Android中是一個較為復(fù)雜的子系統(tǒng),橫跨應(yīng)用API層,框架層,Native層和HAL層。使用Java、C++、C語言進(jìn)行編寫。運行在Linux用戶空間的4個進(jìn)程中:APP應(yīng)用進(jìn)程(API層的代碼)、SystemServer進(jìn)程(框架層的代碼)、AudioServer進(jìn)程(Native層的代碼)、AudioHAL進(jìn)程(HAL層的代碼)。其中運行在AudioServer進(jìn)程中的AudioFlinger和AudioPolicyService,以及運行在SystemServer進(jìn)程中的AudioService這三個模塊是Android音頻子系統(tǒng)的核心,也是我后續(xù)分析的重點。而AudioHAL模塊是由各個SoC廠商自行根據(jù)芯片特點實現(xiàn)的,每種平臺的代碼都不一樣,AOSP中只定義了標(biāo)準(zhǔn)接口,并沒有具體的實現(xiàn)代碼。以下是音頻子系統(tǒng)的整體架構(gòu)圖:
一、應(yīng)用API層
? ? ? ? 應(yīng)用API層的源碼位置:/frameworks/base/media/java/android/media/
? ? ? ? 這部分代碼是運行在調(diào)用其代碼的APP進(jìn)程中的,圖中用淺藍(lán)色標(biāo)注的模塊。其中主要的接口模塊有三個:
- AudioTrack.java:為APP提供播放音頻數(shù)據(jù)的接口。
- AudioRecord.java:為APP提供錄制音頻數(shù)據(jù)的接口。
- AudioManager.java:為APP提供管理音頻路由、音量控制、音頻焦點獲取的接口。
? ? ? ? 從上面的整體架構(gòu)圖中可以看出,AudioTrack.java和AudioRecord.java會分別調(diào)用其對應(yīng)的JNI文件:android_media_AudioTrack.cpp、android_media_AudioRecord.cpp(它們位于/frameworks/base/core/jni/目錄中)。而這兩個JNI層的代碼又會調(diào)用Native的客戶端代碼AudioTrack.cpp和AudioRecord.cpp(它們位于/frameworks/av/media/libaudioclient/目錄中)。所以,我們可以看出音頻播放和錄制數(shù)據(jù)的應(yīng)用接口代碼的真正實現(xiàn)是在libaudioclient中的。
? ? ? ? AudioManger.java是AudioService.java的客戶端代理類,它里面的大多數(shù)函數(shù)都是通過Binder方式遠(yuǎn)程調(diào)用AudioService.java來實現(xiàn)的。當(dāng)然一小部分簡單的函數(shù)也會直接調(diào)用AudioSystem.java來實現(xiàn)。而大多數(shù)情況下AudioSystem.java都是被AudioService.java調(diào)用使用的。
????????在上面的整體架構(gòu)圖中,我把AudioSystem.java放在了APP進(jìn)程和SystemServer進(jìn)程這兩個進(jìn)程框線之間,意思是這個java文件會分別運行在兩個不同的進(jìn)程中。我們知道Java的特性是同一個java文件在不同的進(jìn)程中會有不同對象和數(shù)據(jù),不過當(dāng)我們讀一下AudioSystem.java的源碼我們就會發(fā)現(xiàn),它是一個全部通過靜態(tài)方法實現(xiàn)的代碼文件,只有靜態(tài)數(shù)據(jù),比如注冊的一些Callback函數(shù)。所以,APP進(jìn)程中注冊的Callback對象和SystemServer進(jìn)程中注冊的Callback對象并不是同一個。AudioSystem.java文件也位于/frameworks/base/media/java/android/media/目錄中,但是它是一個hide class,所以普通的APP程序是無法直接調(diào)用它的接口的,當(dāng)然Java反射除外。AudioSystem.java和AudioTrack.java類似,它也會通過JNI調(diào)用android_media_AudioSystem.cpp文件,然后JNI文件又會調(diào)用libaudioclient的AudioSystem.cpp文件。所以AudioSystem.cpp才是真正實現(xiàn)代碼邏輯的地方。
????????/frameworks/av/media/libaudioclient/這個目錄中的源碼會被編譯打包成libaudioclient.so,它包含了三個重要客戶端接口類AudioTrack.cpp、AudioRecord.cpp和AudioSystem.cpp。所以,如果我們寫一個native APP,完全可以直接加載libaudioclient這個so庫,調(diào)用它們提供的接口API。? ? ? ? ? ? ? ?前面我們提到AudioManager.java會直接調(diào)用AudioSystem.java的部分函數(shù),而AudioManager.java是運行在APP進(jìn)程中的,AudioSystem.java最終又會調(diào)用libaudioclient.so的AudioSystem.cpp,所以我們可以推斷APP進(jìn)程在初始化時,已經(jīng)加載過了libaudioclient.so庫。我們可以直接使用C++代碼調(diào)用AudioTrack.cpp和AudioRecord.cpp中的接口函數(shù)。
? ? ? ? AudioSystem.cpp也是一個由靜態(tài)函數(shù)實現(xiàn)的類。它的作用是和AudioFilnger、AudioPolicyService通信,通過Binder方式調(diào)用這兩個模塊提供的接口函數(shù)。同時,它提供了直接獲取這兩個模塊的Binder代理接口類的方法:get_audio_flinger()、get_audio_policy_service()。
????????當(dāng)我們查看AudioPolicyService模塊中的源碼時,我們就會看到,AudioPolicyService也是通過AudioSystem.cpp的get_audio_flinger()接口函數(shù),來獲取到AudioFlinger的Binder代理類,然后和AudioFilnger模塊進(jìn)行通信的,雖然AudioPolicyService模塊和AudioFlinger這兩個模塊都是運行在同一進(jìn)程AudioServer中。Binder的機(jī)制是跨進(jìn)程調(diào)用時,被調(diào)用的Server端函數(shù)會運行在Server端的15個Binder線程中的一個,而同一進(jìn)程內(nèi)調(diào)用時,被調(diào)用的Server端函數(shù)就直接運行在客戶端調(diào)用方運行的線程中。所以,AudioPolicyService所調(diào)用的任何AudioFlinger函數(shù),都不是運行在AudioServer進(jìn)程的15個Binder線程中的。順便說一下,基于這個發(fā)現(xiàn),我們可以知道AudioServer進(jìn)程中已經(jīng)加載了libaudioclient.so庫,因為它使用了AudioSystem.cpp文件。所以,在AudioServer進(jìn)程中的模塊代碼是可以直接使用AudioTrack.cpp和AudioRecord.cpp文件的。正是基于這個發(fā)現(xiàn),我之前在解決一個手機(jī)通過藍(lán)牙連接到寶馬車機(jī)播放聲音延遲很大的問題時,就想到了在AudioFlinger模塊中直接通過AudioTrack.cpp和AudioRecord.cpp創(chuàng)建一個超聲播放回路,用于監(jiān)測車內(nèi)的聲音播放延遲大小,實踐證明是可行的。
? ? ? ? 通過上面的分析我們可以發(fā)現(xiàn),Android音頻子系統(tǒng)提供了兩套API接口給客戶端使用,一套是Java代碼實現(xiàn)的,位于/frameworks/base/media/java/android/media/目錄中。一套是C++代碼實現(xiàn)的,位于/frameworks/av/media/libaudioclient/目錄中。
? ? ? ? 應(yīng)用API層除了提供核心的AudioTrack.java、AudioRecord.java和AudioManager.java接口之外,還提供了AudioPatch.java和AudioMix.java這兩類接口,用于客戶端定制音頻路由策略。但是它們兩都是hide class,所以普通應(yīng)用不能使用。我看目前主要是CarAudioService在使用,用于車機(jī)場景。后續(xù)有機(jī)會我會單獨寫一篇文章來介紹這兩個類的作用,因為是和AudioPolicyService模塊強相關(guān),所以要在深入分析完AudioPolicyService模塊后再介紹更為合適。
二、Java框架層
? ? ? ? Java框架層的源碼位置:/frameworks/base/services/core/java/com/android/server/audio/
? ? ? ? 這部分代碼是運行在SystemServer進(jìn)程中的,整體架構(gòu)圖中用綠色標(biāo)注的模塊。
? ? ? ? AudioService.java是音頻設(shè)備路由管理、音量控制、焦點控制的具體實現(xiàn)模塊。它主要包含4個子模塊。具體模塊架構(gòu)圖如下:
? ? ? ? 基本上從文件名稱上我們就可以看出這幾個模塊的用途:
- AudioDeviceBroker.java:用于管理音頻設(shè)備路由策略。它包含兩個子模塊AudioDeviceInventory.java和BtHelper.java。BtHelper用于和藍(lán)牙Java層模塊交互(源碼位于/packages/modules/Bluetooth/目錄),監(jiān)聽藍(lán)牙設(shè)備的連接狀態(tài)和codec配置變更信息等。
- MediaFocusControl.java:音頻焦點控制模塊。
- PlaybackActivityMonitor.java:音頻播放事件監(jiān)聽模塊。
- RecordingActivityMonitor.java:音頻錄制事件監(jiān)聽模塊。
? ? ? ? 在/frameworks/base/services/core/java/com/android/server/audio/這個目錄中,我并沒有看到音量控制相關(guān)的類,因為它是由AudioService.java自己實現(xiàn)的。還有一個類,雖然不在這個目錄中,但需要在這里提一下:
/frameworks/base/services/core/java/com/android/server/WiredAccessoryManager.java
它是監(jiān)聽有線耳機(jī)設(shè)備插拔狀態(tài)的入口。
? ? ? ? 我之前看到這里的代碼,曾產(chǎn)生一個疑問,既然AudioService是用于管理音頻設(shè)備路由策略的,那還要AudioPolicyService干嘛?或者說直接在AudioPolicyService里面實現(xiàn)不就行了,還要AudioService干嘛?我的理解是AudioService是運行在SystemServer進(jìn)程的,它可以直接和ActivityManagerService等其它Android核心服務(wù)交互,可以知道客戶端是哪個package name在播放、在設(shè)置設(shè)備路由等。輔助AudioPolicyService更好的管理。所以,我認(rèn)為基于Android系統(tǒng)結(jié)合當(dāng)?shù)赜脩魬?yīng)用場景來進(jìn)行音頻模塊定制化時,應(yīng)該優(yōu)先考慮修改AudioService模塊,因為它更接近用戶場景,AudioService模塊實現(xiàn)不了的,再考慮修改AudioPolicyService模塊。
三、Native核心層
? ? ? ? 音頻Native核心層分為兩大模塊:AudioFlinger和AudioPolicyService。它們都是注冊在ServiceManager中的Binder服務(wù)。運行在AudioServer進(jìn)程中,整體架構(gòu)圖中橙色部分。下面分開進(jìn)行介紹。
3.1 AudioFlinger模塊
? ? ? ? AudioFlinger模塊的源碼位置:/frameworks/av/services/audioflinger/?
? ? ? ? 我認(rèn)為AudioFlinger主要分為三個遞進(jìn)關(guān)系的子模塊:AudioHwDevice、PlaybackThread/RecordThread、PlaybackTrack/RecordTrack。當(dāng)然我沒有提到音效相關(guān)的類,是因為我認(rèn)為不介紹音效相關(guān)類并不影響整體架構(gòu)的梳理和理解,后續(xù)講到播放時再來介紹也沒關(guān)系。
????????這里的AudioHwDevice并不是指喇叭、聽筒、耳機(jī)這種真實的物理設(shè)備,而是指不同的Audio HAL module,比如primary module、a2dp module等,也可以理解成是音頻框架層定義的一種虛擬設(shè)備。它和Audio HAL層的DeviceHal是對應(yīng)的關(guān)系。
????????PlaybackThread/RecordThread是由AudioFlinger啟動的負(fù)責(zé)音頻數(shù)據(jù)傳輸?shù)木€程。播放和錄制的核心流程都在這里面實現(xiàn)。它和Audio HAL層的StreamHal是對應(yīng)的關(guān)系。
????????PlaybackTrack/RecordTrack對應(yīng)的是API層的AudioTrack/RecordTrack,它相當(dāng)于是服務(wù)端。
????????我還想提一個模塊是PatchPanel.cpp,它是用于管理音頻設(shè)備切換的類。使用AudioPatch類來表示stream和device的連接關(guān)系。之所以在這里提及一下,是因為這個文件中包含了一些AudioFlinger類的實現(xiàn)函數(shù),大家在查看AudioFlinger.h申明的函數(shù)具體實現(xiàn)時,如果在AudioFlinger.cpp中找不到,就可以在PatchPanel.cpp找一下,主要是和音頻設(shè)備切換相關(guān)的,比如createAudioPatch()函數(shù)。
? ? ? ? 以下是AudioFlinger核心子模塊的類圖:
? ? ? ? 從類圖中可以看出,應(yīng)用層libaudioclient中的AudioTrack.cpp有一個成員變量mAudioTrack(BpAudioTrack),它是IAudioTrack.aidl接口的代理端,通過Binder方式與BnAudioTrack進(jìn)行交互。BpAudioTrack和BnAudioTrack都是Android基于IAudioTrack.aidl文件編譯時自動生成的,所以找不到源碼。IAudioTrack.aidl服務(wù)端的實現(xiàn)就是繼承了BnAudioTrack的AudioFlinger.TrackHandle這個內(nèi)部類。所以,AudioTrack.cpp實際上就是和它在進(jìn)行通信交互。AudioTrack.cpp獲取IAudioTrack代理端的方法是調(diào)用AudioFlinger的createTrack()函數(shù)。
????????查看AudioFlinger.TrackHandle的源碼會發(fā)現(xiàn),在AudioFlinger內(nèi)部,TrackHandle只是一個代理,負(fù)責(zé)與客戶端交互,真正的實現(xiàn)邏輯是在AudioFlinger.PlaybackThread.Track這個內(nèi)部類中。
? ? ? ? AudioFlinger模塊的源碼文件個數(shù)不多,但是一個文件中定義了好幾個內(nèi)部類,以下是各種內(nèi)部類所在的源碼文件位置,方法大家查找閱讀:
- 所有Track相關(guān)的源碼都定義在TrackBase.h、PlaybackTacks.h、RecordTracks.h這三個頭文件中,統(tǒng)一在Tracks.cpp文件中實現(xiàn)。但是TrackHandle類和RecordHandle類是定義在AudioFlinger.h頭文件中,實現(xiàn)卻是在Tracks.cpp文件中。
- 所有Thread相關(guān)的源碼都定義在Threads.h文件中,實現(xiàn)是在Threads.cpp文件中。比如PlaybackThread和RecordThread類。
- AudioStreamIn這個類因為比較簡單,它的定義和實現(xiàn)都是在AudioFlinger.h頭文件中。
????????DeviceHalInterface、StreamOutHalInterface和StreamInHalInterface這三個接口類是AudioHAL定義的HAL客戶端接口類,源碼位于/frameworks/av/media/libaudiohal/目錄中,在HAL層架構(gòu)分析時我會進(jìn)一步講。
? ? ? ? 由于Thread和Track這兩種類的繼承關(guān)系較多,所以我畫了兩個類圖來說明它們的結(jié)構(gòu),如下:????????
? ? ? ? 從這個類圖中可以看出,所有的播放和錄制Thread類都是繼承的ThreadBase,而ThreadBase又繼承了Android標(biāo)準(zhǔn)的循環(huán)線程類Thread,所以它們都是可以單獨循環(huán)運行的普通線程。以下是各種Thread的作用介紹:
- MixerThread:包含將上層多個track數(shù)據(jù)進(jìn)行混音操作的播放線程。當(dāng)AudioPolicySerivce請求openOutput時設(shè)置了這些flag,AudioFlinger就會創(chuàng)建此種線程:AUDIO_OUTPUT_FLAG_PRIMARY、AUDIO_OUTPUT_FLAG_FAST、AUDIO_OUTPUT_FLAG_DEEP_BUFFER。它也是AudioFlinger使用頻次最多、默認(rèn)創(chuàng)建的Thread類型。
- DirectOutputThread:不經(jīng)過混音等上層音效處理的直傳播放線程。當(dāng)設(shè)置了AUDIO_OUTPUT_FLAG_DIRECT flag時,會被創(chuàng)建使用。
- OffloadThread:要求通過底層DSP硬件進(jìn)行解碼的播放線程。當(dāng)設(shè)置了AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD flag時,會被創(chuàng)建使用。
- DuplicatingThread:多路輸出播放線程,比如手機(jī)連上藍(lán)牙耳機(jī)后來電時,聲音會從喇叭和耳機(jī)同時輸出。
- SpatializerThread:Android13新增加的空間音頻播放線程。當(dāng)設(shè)置了AUDIO_OUTPUT_FLAG_SPATIALIZER flag時,會被創(chuàng)建使用。
? ? ? ? 所有的Thread類都是AudioFlinger的內(nèi)部類,但是如果我們查看Threads.h源文件,并沒有看到這些類是定義在class AudioFlinger中的?原因是在AudioFlinger.h文件中,定義的AudioFlinger class包含了這句代碼:#include "Threads.h"。Track類的定義也是采用相同的方法,以下是Track的類圖,從這個類圖中可以看到,所有的Track都是Thread的內(nèi)部類。
3.2 AudioPolicyService模塊
????????AudioPolicyService模塊的源碼位置:/frameworks/av/services/audiopolicy/
????????AudioPolicyService模塊的源碼目錄結(jié)構(gòu)比較多,源文件也比較多。但是我認(rèn)為核心的就3個子模塊:AudioPolicyService、AudioPolicyManager和Engine。Engine負(fù)責(zé)存儲設(shè)備路由策略和音量大小配置。AudioPolicyManager負(fù)責(zé)設(shè)備路由和音量控制的具體實現(xiàn)。AudioPolicyService負(fù)責(zé)對外提供Binder接口和其它模塊進(jìn)行交互。它們?nèi)叩恼{(diào)用可以從以下類圖中看出:
? ? ? ? 簡化一下,就可以看出這三者的調(diào)用關(guān)系是:
AudioPolicyService<-->AudioPolicyManager<-->Engine
? ? ? ? 當(dāng)然,在AudioPolicyService模塊中,也會存在device、stream、track的概念,只是它們的命名方式不一樣。這也是我認(rèn)為整個Android音頻子系統(tǒng)代碼實現(xiàn)不好的地方,我猜可能是各個模塊由不同的人編寫的原因吧。比如說streamOutput,AudioFlinger里面叫PlaybackThread,AudioPolicyService里面又叫AudioOutputDescriptor,還有一個叫IOProfile,IOProfile對象保存封裝的是config配置文件中針對stream流的配置,而在配置文件中,又定義成叫mixPort,而mix這個名稱,讓我一開始想到的是AudioFlinger里面的AudioMixer(用于執(zhí)行多個track混音的模塊)。device也是,AudioFlinger里面叫AudioHwDevice,到了AudioPolicyService里面又叫HwModule。在剛開始看這些代碼時,真的是能把人繞暈。下面我就來介紹一下AudioPolicyService模塊里面的核心數(shù)據(jù)結(jié)構(gòu)。
? ? ? ? AudioPolicyService模塊的四個核心數(shù)據(jù)類:HwModule、AudioIODescriptorInterface、DeviceDescriptor、ClientDescriptor。
- HwModule:它代表的是HAL層的虛擬設(shè)備Device,與AudioFlinger中的AudioHwDevice對應(yīng)。在audio_policy_configuration.xml配置文件中對應(yīng)的是<module>節(jié)點。
- AudioIODescriptorInterface:它包含兩個子類,AudioOutputDescriptor和AudioInputDescriptor。代表的是音頻輸入輸出流,對應(yīng)的是AudioFlinger中的Thread,以及HAL層的Stream。同時它還有一個成員變量IOProfile對象,IOProfile對應(yīng)的是audio_policy_configuration.xml配置文件中的<mixPort>節(jié)點。
- DeviceDescriptor:它代表的是真實的物理設(shè)備,比如喇叭、聽筒、Mic等。對應(yīng)的是audio_policy_configuration.xml配置文件中<devicePort>節(jié)點。
- ClientDescriptor:它包含兩個子類,TrackClientDescriptor和RecordClientDescriptor。分別對應(yīng)的是上層的Track和Record對象。
? ? ? ? 下圖是以音頻播放場景舉例,來說明這四種數(shù)據(jù)類型在各個層級中的定義,顏色相同的代表同一種數(shù)據(jù)類型。以及它們四者之間的包含關(guān)系。
????????從這個圖中可以看出,四者之間的關(guān)系是:Module包含多個OutputStream,OutputStream作為中間連接器,包含上層的多個track,也包含底層的多個device。其中AudioPolicyService模塊的關(guān)系定義是最標(biāo)準(zhǔn)的,也最能說明它們四者之間的關(guān)系。
? ? ? ? 同時可以看出,Track是只在上層和框架層存在的概念。到了HAL層就沒有Track這個概念了。HAL層只有outputStream和真實物理設(shè)備Device的概念。
? ? ? ? 下面分別說明一下這四個數(shù)據(jù)結(jié)構(gòu)在各個層級中的定義名稱:
- Module:只存在于框架層和HAL層的概念。代表的是一個HAL模塊,也可以理解成是一個虛擬設(shè)備。它在AudioPolicyService中的定義是HwModule。在AudioFlinger中的定義是AudioHwDevice。在HAL向上接口層的定義是IDevice.aidl。在HAL向下接口層的定義是audio_hw_device。
- OutputStream:代表的是一個音頻輸出流。用于連接上層的track和底層真實的device設(shè)備。它在AudioPolicyService中的定義是AudioOutputDescriptor、OutputProfile。在AudioFlinger中的定義是PlaybackThread、AudioStreamOut。在HAL向上接口層的定義是IStreamOut.aidl。在HAL向下接口層的定義是audio_stream_out。
- Track:代表的是應(yīng)用層的一個播放對象,一個應(yīng)用進(jìn)程中可以創(chuàng)建多個Track。它在應(yīng)用層的定義是AudioTrack.java。在AudioPolicyService中的定義是TrackClientDescriptor。在AudioFlinger中的定義是AudioFlinger.TrackHandle、AudioFlinger.PlaybackThread.Track。
- Device:代表的是一個真實的物理設(shè)備。它在應(yīng)用層的定義是AudioDeviceInfo.java。在AudioPolicyService中的定義是DeviceDescriptor。在AudioFlinger中的定義是AudioDeviceTypeAddr。在HAL層的定義是audio_devices_t。
? ? ? ? 如果我們在/system/media/audio/include/system/audio-hal-enums.h源文件中看一下audio_devices_t的定義,就會發(fā)現(xiàn)它只是一個定義多種常量的枚舉。并沒有包含物理設(shè)備的配置信息:比如支持的samplingRates、format等。原因是Android音頻子系統(tǒng)中還定義了一個叫AudioPort的概念。它代表的是一個音頻流中的節(jié)點,可以是真實物理設(shè)備、也可以是outputstream、還可以是session。AudioPort有兩種角色,一種是sink,比如說代表喇叭設(shè)備時。一種是source,比如說代表PlaybackThread時,或者代表mic設(shè)備時。
? ? ? ? AudioPort是橫跨整個音頻子系統(tǒng)的數(shù)據(jù)類型,它在應(yīng)用層、框架層、HAL層中都有使用。它的定義是在/system/media/audio/include/system/audio.h源文件中,定義了兩個結(jié)構(gòu)體:audio_port和audio_port_config。各個層級也會基于此定義自己的數(shù)據(jù)類型,比如Native層的AudioPort和AudioPortConfig類,它們位于/frameworks/av/media/libaudiofoundation/include/media/AudioPort.h源文件中,供C++世界的代碼使用,比如AudioPolicyService模塊。在Java世界中的定義是:AudioPort.java和AudioPortConfig.java,位于/frameworks/base/media/java/android/media/目錄中。
? ? ? ? 下面我會畫一個AudioPolicyService模塊中的DeviceDescriptor和OutputProfile的繼承關(guān)系類圖,從而更直觀看出AudioPort的定義。
????????這張類圖中,可以直觀的看到DeviceDescriptor和OutputProfile都是繼承了AudioPort類的。其中PolicyAudioPort類和PolicyAudioPortConfig類是AudioPoicyService模塊自己擴(kuò)展定義的AudioPort。位于/frameworks/av/services/audiopolicy/common/managerdefinitions/include/PolicyAudioPort.h源文件中。
? ? ? ? 最后,介紹一下AudioPolicyService模塊的源碼目錄結(jié)構(gòu):
- /frameworks/av/services/audiopolicy/根目錄下,只有一個源文件:AudioPolicyInterface.h,它定義了AudioPolicyService和AudioPolicyManager需要遵循的接口。
- ./service/目錄:定義了AudioPolicyService模塊的代碼實現(xiàn)。
- ./managerdefault/目錄:定義了AudioPolicyManager模塊的代碼實現(xiàn)。這個目錄中的代碼會被編譯打包到libaudiopolicymanagerdefault.so庫中。廠商也可以根據(jù)自己需要完全重寫。
- ./enginedefault/目錄:定義了engine模塊的代碼實現(xiàn)。這個目錄會被編譯打包到libaudiopolicyenginedefault.so庫中。
- ./engineconfigurable/目錄,定義了engine模塊的另外一種實現(xiàn),目前沒有使用,而是用的./enginedefault/目錄中的源碼。
- ./engine/目錄:定義了engine模塊的基礎(chǔ)代碼實現(xiàn),EngineBase類就在其中定義。
- ./config/目錄:定義了audio_policy_configuration.xml文件的參考模版。
- ./common/目錄:定義了AudioPolicyManager模塊所使用的一些數(shù)據(jù)結(jié)構(gòu),比如HwModule、DeviceDescriptor、AudioOutputDescriptor等。會被編譯打包到libaudiopolicycomponents.so庫中。
四、HAL層
? ? ? ? 我認(rèn)為AudioHAL層可以分為三大部分:
- 第一部分是HIDL代理端的實現(xiàn)。源碼位于:/frameworks/av/media/libaudiohal/目錄。它供AudioFlinger來調(diào)用,運行在調(diào)用方AudioServer進(jìn)程中。通過Binder方式與HIDL服務(wù)端通信。
- 第二部分是HIDL服務(wù)端的實現(xiàn)。源碼位于:/hardware/interfaces/audio/目錄。包含了音頻HIDL接口文件的定義和服務(wù)端的實現(xiàn)代碼。
- 第三部分是提供給SoC廠商的實現(xiàn)接口定義。由SoC廠商根據(jù)自己芯片的特點進(jìn)行實現(xiàn)。AOSP不提供實現(xiàn)源碼。接口定義的源碼位于:/hardware/libhardware/include/hardware/audio.h
? ? ? ? 以上是HIDL代理端libaudiohal的代碼實現(xiàn)類圖。從類圖中可以看出,由DevicesFactoryHalHidl負(fù)責(zé)創(chuàng)建Device對象,再由DeviceHalHidl來創(chuàng)建Stream對象。
device的真正實現(xiàn)是在DeviceHalHidl.cpp文件中。stream的真正實現(xiàn)是在StreamHalHidl.cpp文件中。
? ? ? ?HIDL服務(wù)端的啟動代碼是在/hardware/interfaces/audio/common/all-versions/default/service/目錄中,它是Audio HAL進(jìn)程的啟動總?cè)肟?。有對?yīng)的rc文件。文章來源:http://www.zghlxwxcb.cn/news/detail-724723.html
????????HIDL服務(wù)端的實現(xiàn)代碼是在/hardware/interfaces/audio/core/all-versions/default/目錄中,包含了DevicesFactory、Device和Stream的實現(xiàn)。正如前面所說,它們其實也是一個代理,只是調(diào)用audio.h中定義的接口。真正的實現(xiàn)還是由SoC廠商完成的。文章來源地址http://www.zghlxwxcb.cn/news/detail-724723.html
到了這里,關(guān)于Android13音頻子系統(tǒng)分析(一)---整體架構(gòu)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!