3. Android音频架构概览
在车载Android系统中,音频链路并不是单一服务完成的,而是由应用层、框架层、HAL层以及车机定制服务共同协作。理解AudioTrack、AudioRecord、AudioFlinger、AudioPolicyService、HAL与CarAudioService之间的关系,是后续排查“为什么没有声音”“为什么音量分区不生效”“为什么录音被抢占”等问题的基础。
可以把整条链路理解为:应用通过AudioTrack/AudioRecord发起播放或录音请求,AudioFlinger负责混音与音频流管理,AudioPolicyService负责路由与策略决策,HAL负责与底层硬件驱动交互,而CarAudioService则在车机场景中扩展了音量分区、音区、焦点与设备上下文管理。
一、核心组件职责与调用关系
AudioTrack是应用播放音频的入口,负责把PCM数据写入共享内存,并通知AudioFlinger进行混音。它本身不决定声音从哪个设备出来,只负责“把数据送进去”。AudioRecord则相反,它从AudioFlinger读取录音数据,常用于语音识别、通话、行车记录等场景。
AudioFlinger是音频系统的“发动机”,它管理多个播放线程和录音线程,完成混音、重采样、音量应用和流状态维护。每个AudioTrack在AudioFlinger中对应一个Track对象,最终被混入某个输出流。
AudioPolicyService是“交通指挥”,它决定音频流走哪个设备、使用什么策略、何时切换路由。例如导航播报时压低音乐、倒车雷达触发时切换音区,都需要AudioPolicyService参与决策。
HAL是框架与硬件之间的抽象层。Audio HAL负责PCM数据进出,AudioControl HAL负责音量与设备控制,Vehicle HAL则提供车辆信号,如车速、挡位、车门状态,供CarAudioService做上下文判断。
CarAudioService是车机定制核心,它基于AudioPolicyService扩展出音量分区、音区、音频焦点和上下文管理。它不直接混音,而是通过策略和HAL控制,让不同座位、不同音源获得正确的音量与路由。
二、一次播放请求的完整流程
- 应用创建AudioTrack,设置采样率、声道、格式和usage。
- AudioTrack通过AudioFlinger创建Track,并写入PCM数据。
- AudioFlinger根据AudioPolicyService给出的输出流进行混音。
- 混音后的数据通过Audio HAL写入DSP/Codec。
- CarAudioService根据音量分区和音区,调整对应输出音量。
- 最终声音从指定扬声器输出。
录音流程方向相反:AudioRecord请求录音,AudioPolicyService选择输入设备,AudioFlinger从Audio HAL读取数据,再回传给应用。
三、关键关系对照表
| 组件 | 主要职责 | 与CarAudioService的关系 |
|---|---|---|
| AudioTrack | 应用播放PCM数据入口 | 受CarAudioService音量分区与焦点策略影响 |
| AudioRecord | 应用录音数据入口 | 受音区与输入设备策略影响 |
| AudioFlinger | 混音、流管理、线程调度 | 执行CarAudioService下发的音量与路由结果 |
| AudioPolicyService | 路由、策略、焦点决策 | CarAudioService在其上扩展车机策略 |
| Audio HAL | PCM与设备控制 | 接收CarAudioService音量控制指令 |
| Vehicle HAL | 车辆信号输入 | 为CarAudioService提供上下文判断依据 |
四、典型场景与常见误区
以“导航播报时音乐自动降低”为例:导航应用创建AudioTrack,AudioPolicyService识别到导航usage,CarAudioService根据音频焦点和音量分区,向AudioFlinger下发降低音乐音量的指令,AudioFlinger调整对应Track增益,最终通过Audio HAL输出。整个过程不是应用直接改音量,而是策略层协同完成。
常见误区:很多开发者认为“调音量就是调AudioTrack的setVolume”。实际上,在车机上音量往往由CarAudioService按分区管理,直接调AudioTrack可能被策略覆盖,或者只影响单个流,无法改变整个音区。
排查建议:遇到无声问题时,可按“应用→AudioTrack/AudioRecord→AudioFlinger→AudioPolicyService→CarAudioService→HAL→硬件”的顺序逐层确认。先看流是否创建成功,再看路由是否正确,最后看HAL与硬件是否响应。
# 常用排查命令示例
adb shell dumpsys audio
adb shell dumpsys car_service
adb shell dumpsys media.audio_flinger
adb shell dumpsys media.audio_policy
# 查看当前音频设备与路由
adb shell dumpsys audio | grep -i "device"
adb shell dumpsys car_service | grep -i "volume"
掌握这些组件的分工与调用方向后,再去看CarAudioService的音量分区、音区、焦点和上下文配置,就能把“声音从哪来、到哪去、谁在控制”这条链路串起来。后续分析具体问题时,也能快速定位是应用层、框架层、策略层还是HAL层出现了偏差。