Open Headunit Protobuf消息体系:9个.proto文件定义Android Auto通信语法
【免费下载链接】open-headunitHeadunit App for displaying Android Auto项目地址: https://gitcode.com/GitHub_Trending/he/open-headunit
Open Headunit 是一款开源的 Android Auto 车机接收端应用,能把 Android 平板或手机变成 Android Auto 主机。它背后最容易被忽略、却决定一切的功能,是 proto/ 目录下的9 个文件(8 个.proto协议定义 + 1 个protoc生成脚本)——手机和车机之间的每一条握手、每一帧导航、每一个触摸事件,都用 Protobuf 消息语法精确定义。
为什么是 Protobuf?
Android Auto 的手机端并不公开完整的协议文档,但它的线上传输格式是 Protocol Buffers(简称 Protobuf)。Open Headunit 通过逆向分析,用 9 个文件重建了整套"通信语法":
- 📦跨平台:同一份
.proto定义可生成 Java/Kotlin 代码,App 端直接序列化发送; - ⚡体积小:二进制编码比 JSON 紧凑得多,适合车载实时通道;
- 🔍可读性强:每个消息字段都有编号,注释里还记录了与真实手机抓包交叉验证的结果。
所有文件都声明syntax = "proto2",统一位于包com.andrerinas.openheadunit.aap.protocol.proto下,编译后生成同名 Java 外层类(如Control、Media、Input),供 AapMessageHandler.kt 等消息处理器直接调用。
9个文件全景:一张表看懂分工
| 文件 | 角色 | 典型消息 |
|---|---|---|
| common.proto | 公共错误码与车机身份 | MessageStatus、HeadUnitInfo |
| control.proto | 控制平面:连接生命周期 | 服务发现、开/关通道、Ping |
| wireless.proto | 无线投屏握手(WPP) | Wi-Fi 凭证、协议版本 |
| input.proto | 按键与触摸事件上报 | KeyEvent、TouchEvent |
| media.proto | 音视频流协商 | 编码器、麦克风、视频焦点 |
| navigation.proto | 仪表盘导航显示 | 下一个转弯、剩余距离 |
| playback.proto | 媒体播放状态 | 歌曲元数据、播放状态 |
| sensors.proto | 车辆传感器数据 | 车速、档位、油耗 |
| gen.sh | 用protoc批量生成 Java 类 | — |
逐个拆解:每个文件定义了什么
1️⃣ common.proto:错误码字典
任何响应消息都会带一个MessageStatus,common.proto 第5-39行定义了从STATUS_SUCCESS到STATUS_PING_TIMEOUT等 30 余种状态码,覆盖证书错误、蓝牙配对失败、内存不足等几乎所有异常场景。
它还定义了HeadUnitInfo:车机向手机申报品牌、车型、年份。一个有意思的细节是注释里写明——vehicle_type字段是车机声明"我是摩托车"的唯一途径,手机端会据此决定是否使用自己的麦克风。
2️⃣ control.proto:连接生命周期的"总指挥"
这是最大的文件,定义了ControlMsgType枚举:版本协商(MESSAGE_VERSION_REQUEST)→ 服务发现(MESSAGE_SERVICE_DISCOVERY_*)→ 开通道(MESSAGE_CHANNEL_OPEN_*)→ 心跳(MESSAGE_PING_*)→ 告别(MESSAGE_BYEBYE_*)。
其中 ServiceDiscoveryResponse 是"车机自我介绍"的核心消息,包含车型信息、驾驶员座位位置(左舵/右舵),以及每个服务的"能力卡片":
- MediaSinkService:车机能解码的音视频配置,分辨率从 800x480 到 4K,支持 H.264、HEVC、VP9、AV1 等编码类型;
- InputSourceService:支持哪些按键、触摸屏尺寸;
- BluetoothService/PhoneStatusService/WifiProjectionService等。
3️⃣ wireless.proto:无线连接前的"蓝牙暗号"
投屏开始前,手机和车机先通过蓝牙(RFCOMM)完成 WPP(WiFi Projection Protocol)握手,wireless.proto定义了 11 类消息:
WifiStartRequest(Type 1):车机告知手机"投屏会话的地址和端口";WifiInfoRequest/Response(Type 2/3):手机索取并收到 Wi-Fi SSID 和密码;WifiVersionRequest/Response(Type 4/5):双方交换协议版本与车机身份;WifiConnectStatus(Type 6):手机回报"我连上你的网络了",失败时还附错误提示。
文件头部的注释值得细读:作者说明每个字段都与参考实现和真实抓包交叉核对过,甚至记录了"手机实际回 -8 而非预期值"这类抓包细节——这是逆向工程文档化的典范。
4️⃣ input.proto:你的每一次触摸
车机触摸屏的每个动作都被打包成InputReport消息上报:TouchEvent(按下/抬起/移动/多点触摸)、KeyEvent(物理按键)、AbsoluteEvent与RelativeEvent(摇杆等相对/绝对位移),以及按键绑定请求。手机端正是靠这套语法"知道"你在车机上点了哪里。
5️⃣ media.proto:音视频流的"合同"
media.proto 定义了MEDIA_MESSAGE_START/STOP/SETUP等控制帧,以及MediaCodecType枚举:PCM、AAC、H.264、VP9、AV1、H.265。AudioConfiguration约定采样率、位深、声道数;VideoFocusRequestNotification处理"手机切回原生界面"时的画面焦点移交;MicrophoneRequest甚至细化到回声消除(EC)与降噪(ANC)开关。
投屏成功后车机会用这张测试图校验视频渲染通道:
6️⃣ navigation.proto:让仪表盘学会导航
MsgType定义了INSTRUMENT_CLUSTER_*系列消息:开始/停止导航、下一转向详情(左拐、环岛、上下匝道共 20 余种NextEvent)、转弯距离与时间(含米/英里/码等单位)。手机端据此在方向盘后的仪表屏上显示转向图标。
7️⃣ playback.proto 与 8️⃣ sensors.proto:状态回传
- playback.proto:
MediaMetaData携带歌名、歌手、专辑封面,MediaPlaybackStatus报告播放/暂停/随机模式,车机媒体卡片由此更新; - sensors.proto:
SensorBatch是一个"数据篮",可批量装定位、车速、转速、油耗、档位(含 P/R/N/D)、GPS 卫星数等 21 种传感器,注释还诚实标注了哪些传感器"已可用/尚未支持"。
9️⃣ gen.sh:一行命令生成全部 Java 类
gen.sh 是 9 个文件中的"第 9 位":它调用protoc依次编译 8 个.proto文件,把 Java 类输出到../java/源码目录。这正是"定义即代码"——协议变更时跑一次脚本,序列化/反序列化代码自动就绪。
一次投屏中,这些消息如何流转?
手机 ⇄ 车机(蓝牙/Wi-Fi 通道) 1. WifiVersionRequest —— 交换协议版本 2. WifiInfoResponse —— 下发 SSID 与密码 3. WifiConnectStatus —— 手机回报入网成功 4. Version/ServiceDiscovery —— 车机申报身份与服务能力 5. ChannelOpenRequest —— 按服务打开数据通道 6. 流数据:导航帧、媒体帧、传感器批次…… 7. Ping / ByeBye —— 保活与优雅断开控制平面的消息类型统一由 MsgType.kt 与 Channel.kt 做分发与映射,想深入某条链路的处理逻辑,可以从 aap/ 目录的AapMessageHandler.kt入手。
写在最后
9 个文件、不到 1500 行定义,构成了 Open Headunit 与 Android Auto 手机端的完整"契约"。对于想理解 Android Auto 协议、或为自己车机做协议扩展的开发者,从 common.proto 的错误码读起、再沿 control.proto 的服务发现走一遍,是成本最低的一条学习路径。
【免费下载链接】open-headunitHeadunit App for displaying Android Auto项目地址: https://gitcode.com/GitHub_Trending/he/open-headunit
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考