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();
}
}