1.AudioServer初始化
AudioServer 是 Android 音頻系統的核心服務,負責管理音頻硬件資源、音頻策略調度、跨進程音頻通信等核心功能。它由 Init 進程啟動,是系統核心服務之一,直接影響音頻播放、錄音、音效處理等功能的正常運行。
1.1AudioServer服務創建過程
Init 進程通過解析/system/bin/audioserver/audioserver.rc
配置文件,完成 AudioServer 的服務定義與啟動參數配置。
service audioserver /system/bin/audioserver class core user audioserver # media gid needed for /dev/fm (radio) and for /data/misc/media (tee) group audio camera drmrpc media mediadrm net_bt net_bt_admin net_bw_acct wakelock capabilities BLOCK_SUSPEND # match rtprio cur / max with sensor service as we handle AR/VR HID sensor data. rlimit rtprio 10 10 ioprio rt 4 task_profiles ProcessCapacityHigh HighPerformance onrestart restart vendor.audio-hal onrestart restart vendor.audio-hal-aidl onrestart restart vendor.audio-effect-hal-aidl onrestart restart vendor.audio-hal-4-0-msd onrestart restart audio_proxy_service
?
on property:vts.native_server.on=1 stop audioserver
on property:vts.native_server.on=0 start audioserver
?
on property:init.svc.audioserver=stopped stop vendor.audio-hal stop vendor.audio-hal-aidl stop vendor.audio-effect-hal-aidl stop vendor.audio-hal-4-0-msd stop audio_proxy_service # See b/155364397. Need to have HAL service running for VTS. # Can't use 'restart' because then HAL service would restart # audioserver bringing it back into running state. start vendor.audio-hal start vendor.audio-hal-aidl start vendor.audio-effect-hal-aidl start vendor.audio-hal-4-0-msd start audio_proxy_service
?
on property:init.svc.audioserver=running && property:vts.native_server.on=1 # See b/378773354. To ensure the audioserver disable when # running test suite, this would cover the double start # request from init that caused test flaky. stop audioserver
?
on property:init.svc.audioserver=running start vendor.audio-hal start vendor.audio-hal-aidl start vendor.audio-effect-hal-aidl start vendor.audio-hal-4-0-msd start audio_proxy_service
?
on property:sys.audio.restart.hal=1 # See b/159966243. Avoid restart loop between audioserver and HAL. # Keep the original service names for backward compatibility stop vendor.audio-hal stop vendor.audio-hal-aidl stop vendor.audio-effect-hal-aidl stop vendor.audio-hal-4-0-msd stop audio_proxy_service start vendor.audio-hal start vendor.audio-hal-aidl start vendor.audio-effect-hal-aidl start vendor.audio-hal-4-0-msd start audio_proxy_service # reset the property setprop sys.audio.restart.hal 0 on init mkdir /dev/socket/audioserver 0775 audioserver audioserver
-
服務定義
service audioserver /system/bin/audioserver
class core
user audioserver
-
定義了
audioserver
服務的啟動路徑/system/bin/audioserver
。 -
class core
表示該服務屬于核心服務類。 -
user audioserver
指定該服務以audioserver
用戶身份運行,確保權限隔離。
-
-
權限組
group audio camera drmrpc media mediadrm net_bt net_bt_admin net_bw_acct wakelock
- 指定了服務所屬的權限組,允許它訪問音頻設備、攝像頭、藍牙功能、網絡帶寬計費等資源。
-
能力與資源限制
capabilities BLOCK_SUSPEND
rlimit rtprio 10 10
ioprio rt 4
task_profiles ProcessCapacityHigh HighPerformance
-
BLOCK_SUSPEND
:允許服務阻止設備進入休眠狀態。 -
rlimit rtprio
和ioprio rt
:設置實時優先級和 I/O 優先級,確保服務在處理音頻任務時具有較高的性能。 -
task_profiles
:定義任務性能配置文件,優化服務的運行效率。
-
-
重啟行為
onrestart restart vendor.audio-hal
onrestart restart vendor.audio-hal-aidl
onrestart restart vendor.audio-effect-hal-aidl
onrestart restart vendor.audio-hal-4-0-msd
onrestart restart audio_proxy_service
- 當
audioserver
服務重啟時,相關的音頻 HAL(硬件抽象層)服務也會被重啟,確保音頻功能的正常運行。
- 當
-
屬性觸發器
on property:vts.native_server.on=1
stop audioserver
on property:vts.native_server.on=0
start audioserver
- 根據系統屬性
vts.native_server.on
的值,控制audioserver
的啟動或停止。這通常用于測試場景。
- 根據系統屬性
-
停止與啟動邏輯
on property:init.svc.audioserver=stopped
stop vendor.audio-hal
stop vendor.audio-hal-aidl
stop vendor.audio-effect-hal-aidl
stop vendor.audio-hal-4-0-msd
stop audio_proxy_service
start vendor.audio-hal
start vendor.audio-hal-aidl
start vendor.audio-effect-hal-aidl
start vendor.audio-hal-4-0-msd
start audio_proxy_service
- 當
audioserver
停止時,相關 HAL 服務也會停止并重新啟動,確保系統的穩定性。
- 當
-
初始化行為
on init
mkdir /dev/socket/audioserver 0775 audioserver audioserver
- 在系統初始化時,創建
/dev/socket/audioserver
目錄,并設置權限和所有者。
- 在系統初始化時,創建
1.2.AudioServer啟動流程
-
audioserver
服務通過/system/bin/audioserver
可執行文件啟動,核心邏輯在main_audioserver.cpp
的main
函數中,流程如下:1. 內存限制與信號處理
-
limitProcessMemory
:通過audio.maxmem
屬性或默認值(512MB)限制進程最大內存,避免音頻服務過度占用資源。 -
signal(SIGPIPE, SIG_IGN)
:忽略管道斷裂信號(避免音頻流中斷時進程異常退出)。
2. 進程分叉
-
父進程:運行
media.log
日志服務,監控子進程狀態并輸出資源使用日志。 -
子進程:執行音頻服務初始化(核心流程),并通過
prctl
設置父進程死亡時自毀(避免孤兒進程)。
3. 線程池初始化
-
configureRpcThreadpool(4, false)
:初始化 HIDL RPC 線程池(4 個線程),用于與音頻 HAL(硬件抽象層)進行跨進程通信(HAL 通常運行在獨立進程)。 -
ProcessState::self()->startThreadPool()
:啟動 Binder 線程池,處理應用層或其他服務通過 Binder IPC 發起的音頻請求(如播放、錄音)。
4. 核心服務創建與注冊
-
創建服務實例:
-
sp<AudioFlinger>::make()
:創建AudioFlinger
實例(負責音頻硬件管理、混音、音量控制等核心功能)。 -
sp<AudioPolicyService>::make()
:創建AudioPolicyService
實例(負責音頻策略決策,如音量策略、設備切換邏輯)。
-
-
注冊服務:
-
本地注冊:通過
AudioSystem::setLocalAudioFlinger
和setLocalAudioPolicyService
將實例注冊到進程內(供本地調用)。 -
系統服務注冊:通過
IServiceManager::addService
將實例注冊到系統服務管理器(servicemanager
),供跨進程調用(服務名稱分別為IAudioFlinger
和AudioPolicyService
)。
-
5. AAudioService 初始化(低延遲音頻)
-
查詢系統 MMAP 策略(
AudioSystem::getMmapPolicyInfos
若策略為AUTO\ALWAYS(允許內存映射),則初始化AAudioService
AAudioService
是 Android O 引入的低延遲音頻服務,基于 MMAP(內存映射)機制,支持實時音頻流(如游戲音效、樂器應用),僅在策略允許時啟動。
6. 完成初始化并進入線程池
- 記錄初始化耗時(
startupFinished
),通過IPCThreadState::self()->joinThreadPool()
進入 Binder 線程池,等待并處理外部音頻請求。
-
frameworks/av/media/audioserver/main_audioserver.cpp
int main(int argc __unused, char **argv) { const auto startTime = std::chrono::steady_clock::now(); limitProcessMemory( "audio.maxmem", /* "ro.audio.maxmem", property that defines limit */ (size_t)512 * (1 << 20), /* SIZE_MAX, upper limit in bytes */ 20 /* upper limit as percentage of physical RAM */); ? signal(SIGPIPE, SIG_IGN); ? #if 1 const bool doLog = false; #else bool doLog = (bool) property_get_bool("ro.test_harness", 0); #endif pid_t childPid; if (doLog && (childPid = fork()) != 0) { strcpy(argv[0], "media.log"); sp<ProcessState> proc(ProcessState::self()); MediaLogService::instantiate(); ProcessState::self()->startThreadPool(); IPCThreadState::self()->joinThreadPool(); for (;;) { siginfo_t info; int ret = TEMP_FAILURE_RETRY(waitid(P_PID, childPid, &info, WEXITED | WSTOPPED | WCONTINUED)); if (ret < 0) { break; } char buffer[32]; const char *code; struct rusage usage; getrusage(RUSAGE_CHILDREN, &usage); ALOG(LOG_ERROR, "media.log", "pid %d status %d code %s user %ld.%03lds sys %ld.%03lds", info.si_pid, info.si_status, code, usage.ru_utime.tv_sec, usage.ru_utime.tv_usec / 1000, usage.ru_stime.tv_sec, usage.ru_stime.tv_usec / 1000); sp<IServiceManager> sm = defaultServiceManager(); sp<IBinder> binder = sm->getService(String16("media.log")); if (binder != 0) { Vector<String16> args; binder->dump(-1, args); } switch (info.si_code) { case CLD_EXITED: case CLD_KILLED: case CLD_DUMPED: { ALOG(LOG_INFO, "media.log", "exiting"); _exit(0); // not reached } default: break; } } } else { // all other services if (doLog) { prctl(PR_SET_PDEATHSIG, SIGKILL); // if parent media.log dies before me, kill me also setpgid(0, 0); // but if I die first, don't kill my parent } android::hardware::configureRpcThreadpool(4, false /*callerWillJoin*/); ProcessState::self()->startThreadPool(); const auto af = sp<AudioFlinger>::make(); const auto afAdapter = sp<AudioFlingerServerAdapter>::make(af); ALOGD("%s: AudioFlinger created", __func__); ALOGW_IF(AudioSystem::setLocalAudioFlinger(af) != OK, "%s: AudioSystem already has an AudioFlinger instance!", __func__); const auto aps = sp<AudioPolicyService>::make(); af->initAudioPolicyLocal(aps); ALOGD("%s: AudioPolicy created", __func__); ALOGW_IF(AudioSystem::setLocalAudioPolicyService(aps) != OK, "%s: AudioSystem already has an AudioPolicyService instance!", __func__); ? // Start initialization of internally managed audio objects such as Device Effects. aps->onAudioSystemReady(); ? // Add AudioFlinger and AudioPolicy to ServiceManager. sp<IServiceManager> sm = defaultServiceManager(); sm->addService(String16(IAudioFlinger::DEFAULT_SERVICE_NAME), afAdapter, false /* allowIsolated */, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT); sm->addService(String16(AudioPolicyService::getServiceName()), aps, false /* allowIsolated */, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT); std::vector<AudioMMapPolicyInfo> policyInfos; status_t status = AudioSystem::getMmapPolicyInfos( AudioMMapPolicyType::DEFAULT, &policyInfos); if (status == NO_ERROR && std::any_of(policyInfos.begin(), policyInfos.end(), [](const auto& info) { return info.mmapPolicy == AudioMMapPolicy::AUTO || info.mmapPolicy == AudioMMapPolicy::ALWAYS; })) { AAudioService::instantiate(); } else { ALOGD("%s: Do not init aaudio service, status %d, policy info size %zu", __func__, status, policyInfos.size()); } const auto endTime = std::chrono::steady_clock::now(); af->startupFinished(); using FloatMillis = std::chrono::duration<float, std::milli>; const float timeTaken = std::chrono::duration_cast<FloatMillis>( endTime - startTime).count(); ALOGI("%s: initialization done in %.3f ms, joining thread pool", __func__, timeTaken); IPCThreadState::self()->joinThreadPool(); } }
?