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
  1. 服务定义

    service audioserver /system/bin/audioserver

    class core

    user audioserver

    • 定义了 audioserver 服务的启动路径 /system/bin/audioserver

    • class core 表示该服务属于核心服务类。

    • user audioserver 指定该服务以 audioserver 用户身份运行,确保权限隔离。

  2. 权限组

    group audio camera drmrpc media mediadrm net_bt net_bt_admin net_bw_acct wakelock

    • 指定了服务所属的权限组,允许它访问音频设备、摄像头、蓝牙功能、网络带宽计费等资源。
  3. 能力与资源限制

    capabilities BLOCK_SUSPEND

    rlimit rtprio 10 10

    ioprio rt 4

    task_profiles ProcessCapacityHigh HighPerformance

    • BLOCK_SUSPEND:允许服务阻止设备进入休眠状态。

    • rlimit rtprioioprio rt:设置实时优先级和 I/O 优先级,确保服务在处理音频任务时具有较高的性能。

    • task_profiles:定义任务性能配置文件,优化服务的运行效率。

  4. 重启行为

    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(硬件抽象层)服务也会被重启,确保音频功能的正常运行。
  5. 属性触发器

    on property:vts.native_server.on=1

    stop audioserver

    on property:vts.native_server.on=0

    start audioserver

    • 根据系统属性 vts.native_server.on 的值,控制 audioserver 的启动或停止。这通常用于测试场景。
  6. 停止与启动逻辑

    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 服务也会停止并重新启动,确保系统的稳定性。
  7. 初始化行为

    on init

    mkdir /dev/socket/audioserver 0775 audioserver audioserver

    • 在系统初始化时,创建 /dev/socket/audioserver 目录,并设置权限和所有者。

1.2.AudioServer启动流程

  • audioserver服务通过/system/bin/audioserver可执行文件启动,核心逻辑在main_audioserver.cppmain函数中,流程如下:

    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实例(负责音频策略决策,如音量策略、设备切换逻辑)。

    • 注册服务

      1. 本地注册:通过AudioSystem::setLocalAudioFlingersetLocalAudioPolicyService将实例注册到进程内(供本地调用)。

      2. 系统服务注册:通过IServiceManager::addService将实例注册到系统服务管理器(servicemanager),供跨进程调用(服务名称分别为IAudioFlingerAudioPolicyService)。

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

相关推荐
Lei活在当下14 分钟前
Windows 下 Codex 高效工作流最佳实践
android·openai·ai编程
fatiaozhang952714 分钟前
基于slimBOXtv 9.19.0 v4(通刷晶晨S905L3A/L3AB芯片)ATV-安卓9-完美版线刷固件包
android·电视盒子·刷机固件·机顶盒刷机·晶晨s905l3ab·晶晨s905l3a
私房菜1 小时前
Selinux 及在Android 的使用详解
android·selinux·sepolicy
一只特立独行的Yang2 小时前
Android中的系统级共享库
android
两个人的幸福online2 小时前
php开发者 需要 协程吗
android·开发语言·php
修炼者4 小时前
WindowManager(WMS)构建全局悬浮窗
android
xiaoshiquan12064 小时前
Android Studio里,SDK Manager显示不全问题
android·ide·android studio
Lstone73645 小时前
Bitmap深入分析(一)
android
一起搞IT吧6 小时前
Android功耗系列专题理论之十四:Sensor功耗问题分析方法
android·c++·智能手机·性能优化