Day4.AndroidAudio初始化
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(); } }