概述:
AudioPolicyService做什么事情呢?簡單來說,比如應用程序要播放一段聲音,聲音從哪個設備上播放出來。這些都是通過AudioPolicyService來決定的。
假設android系統中有兩個聲卡設備:
1)問默認聲卡是哪個?
由廠家決定
2)從哪個設備上播放聲音呢?耳機還是喇叭
耳機、喇叭這些硬件配置從驅動中是看不出來的,那么聲卡1中的耳機和喇叭如何告知Android系統呢?
由廠家決定
那廠家是如何決定的呢?
此時AudioPolicyService服務就該出場了,該服務主要做如下幾項工作:
1)讀取解析配置文件,聲卡設備會根據配置文件進行選擇。
對於配置文件有兩個:
對於Android7.0之前,使用audio_policy.conf文件
從Android7.0之后,又出現了一個audio_policy_configuration.xml文件。具體使用哪一個,由一個宏來控制。
2)對於每個聲卡,在Android音頻系統中都會存在一個線程與之對應。從邏輯意義上說,有一個output,一個output對應一個或多個設備,同時一個output還對應一個線程。
3)對於硬件的操作是由AudioFlinger完成的,但是AudioFlinger不能主動做任何事情。
4)AudioPolicyService根據配置文件,調用AudioFlinger的服務,來打開output,創建線程。有了這些線程后,應用程序就可以把聲音數據發給這些線程了。
1. mediaserver加載
AudioPolicyService是android音頻系統的兩大服務之一,另一個服務是AudioFliger。這兩個服務都是在系統啟動時由MediaServer加載。加載的代碼位於:
/frameworks/av/media/audioserver/main_audioserver.cpp
int main(int argc __unused, char** argv) { .......
AudioFlinger::instantiate();//創建AudioFlinger對象,服務名為"media.audio_flinger"
....... AudioPolicyService::instantiate();//創建AudioPolicyService對象,服務名為"media.audio_policy" ....... }
2.可執行文件mediaserver
看一個可執行文件,通常會首先查看其Android.mk文件,位於:
/frameworks/av/media/mediaserver/Android.mk
LOCAL_PATH:= $(call my-dir)
.......
include $(CLEAR_VARS) LOCAL_SRC_FILES:= \ main_mediaserver.cpp ........ LOCAL_MODULE:= mediaserver LOCAL_32_BIT_ONLY := true LOCAL_INIT_RC := mediaserver.rc LOCAL_CFLAGS := -Werror -Wall include $(BUILD_EXECUTABLE)
對於該mk文件,我們重點關注3個地方:
LOCAL_SRC_FILES:= main_mediaserver.cpp //存放源程序的地方
LOCAL_MODULE:= mediaserver //源文件最終被編譯成的可執行文件mediaserver
LOCAL_INIT_RC := mediaserver.rc
2.1 mediaserver.rc
/frameworks/av/media/mediaserver/mediaserver.rc
service media /system/bin/mediaserver class main user media group audio camera inet net_bt net_bt_admin net_bw_acct drmrpc mediadrm ioprio rt 4 writepid /dev/cpuset/foreground/tasks /dev/stune/foreground/tasks
3. AudioPolicyService::instantiate
AudioPlicyService類中並沒有instantiate函數,那么肯定是從父類中繼承得到的。
/frameworks/av/services/audiopolicy/service/AudioPolicyService.h
class AudioPolicyService : public BinderService<AudioPolicyService>, public BnAudioPolicyService, public IBinder::DeathRecipient { friend class BinderService<AudioPolicyService>; public: // for BinderService
static const char *getServiceName() ANDROID_API { return "media.audio_policy"; }
在代碼中搜索,可以發現instantiate函數是在BinderService類中定義的。
/frameworks/native/libs/binder/include/binder/BinderService.h
template<typename SERVICE>
class BinderService { public: static status_t publish(bool allowIsolated = false) { sp<IServiceManager> sm(defaultServiceManager()); return sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated); } ...... static void instantiate() { publish(); } .......
從上面的代碼可以看出,AudioPolicyService::instantiate()實際上調用了publish函數,publish函數實際上調用了addService函數。在addService函數中,實現了3個作用:
3.1 SERVICE::getServiceName()
因為BinderService是類模板,又因為AudioPolicyService::instantiate(),所以此處的SERVICE就是類AudioPolicyService類。
因此SERVICE::getServiceName()實際上調用了AudioPolicyService類中的成員函數getServiceName.
static const char *getServiceName() ANDROID_API { return "media.audio_policy"; }
將返回一個media.audio_policy的服務
3.2 new SERVICE
調用AudioPolicyService的構造函數,創建了一個AudioPolicyService的對象,做一些初始化的工作。
/frameworks/av/services/audiopolicy/service/AudioPolicyService.cpp
AudioPolicyService::AudioPolicyService()
: BnAudioPolicyService(), mpAudioPolicyDev(NULL), mpAudioPolicy(NULL),
mAudioPolicyManager(NULL), mAudioPolicyClient(NULL), mPhoneState(AUDIO_MODE_INVALID)
{
}
3.3 調用AudioPolicyService::onFirstRef()
由於sm是sp<IServiceManager>強引用類型的指針,所以在第一次調用AudioPolicyService模塊時,會調用AudioPolicyService::onFirstRef()
/frameworks/av/services/audiopolicy/service/AudioPolicyService.cpp
void AudioPolicyService::onFirstRef() { { Mutex::Autolock _l(mLock); // start tone playback thread,用於播放tone音,tone是音調的意思
mTonePlaybackThread = new AudioCommandThread(String8("ApmTone"), this); // start audio commands thread,用於執行audio命令
mAudioCommandThread = new AudioCommandThread(String8("ApmAudio"), this); // start output activity command thread,用於執行audio輸出命令
mOutputCommandThread = new AudioCommandThread(String8("ApmOutput"), this); //實例化AudioPolicyClient對象
mAudioPolicyClient = new AudioPolicyClient(this); //實例化AudioPolicyManager對象
mAudioPolicyManager = createAudioPolicyManager(mAudioPolicyClient); } // load audio processing modules //初始化音效相關
sp<AudioPolicyEffects>audioPolicyEffects = new AudioPolicyEffects(); { mAudioPolicyEffects = audioPolicyEffects; } }
3.3.1 new AudioPolicyClient
創建了一個AudioPolicyClient的對象,AudioPolicyClient的構造函數在
/frameworks/av/services/audiopolicy/service/AudioPolicyService.h中。
class AudioPolicyClient : public AudioPolicyClientInterface { public: explicit AudioPolicyClient(AudioPolicyService *service) : mAudioPolicyService(service) {} ..... }
AudioPolicyService *mAudioPolicyService,mAudioPolicyService是類AudioPolicyService的一個指針。在AudioPolicyClient構造函數中,實際上只是將傳進來的service指針
賦值給了mAudioPolicyService。service是什么,就是傳進來的this指針,this指針指代當前的AudioPolicyService類的一個指針。
在這個地方設計到了C++的基本知識,首先會調用父類AudioPolicyClientInterface的構造函數,然后調用成員變量的構造函數,mAudioPolicyService是一個AudioPolicyService的對象,最后
調用自己的構造函數。new AudioPolicyClient對象,會涉及到三個構造函數的調用哦。
3.3.2 createAudioPolicyManager(mAudioPolicyClient)
/frameworks/av/services/audiopolicy/manager/AudioPolicyFactory.cpp
extern "C" AudioPolicyInterface* createAudioPolicyManager( AudioPolicyClientInterface *clientInterface) { return new AudioPolicyManager(clientInterface); }
new AudioPolicyManager(clientInterface)將會調用類AudioPolicyManager的構造函數,接下來將重點分析該構造函數,這是我們分析AudioPolicyService的關鍵。