如何实现手机 App 投屏到车载屏幕?

解读

国内车载场景分“前装”与“后装”两条赛道:前装由主机厂(OEM)与 Tier1 深度定制,系统多为 Android Automotive OS(AAOS)或 QNX+Android 双系统;后装则以 CarLink(ICCOA)、HiCar、CarLife+、亿连、CarWith 等协议盒子为主。面试官想考察的是:候选人能否把“手机端采集→编码→传输→车载端解码→渲染→反向控制”这一条链路讲清楚,同时兼顾国内合规(隐私弹窗、驾驶安全校验)、性能(16 ms 帧率、1080p60)、功耗(<400 mA)与异常降级(弱网、来电、蓝牙抢占)等工程闭环。

知识点

  1. 投屏协议:
    • 有线:USB 2.0/3.0 accessory 模式 + AOAv2(Android Open Accessory),走 bulk 端点 80 Mbps 带宽,延迟 30 ms 内。
    • 无线:Wi-Fi 5/6 P2P(原 Miracast)或 SoftAP+RTSP,ICCOA/CarLink 在 P2P 之上封装私有 RTP/TS 流,AES-CTR 128 加密。
  2. 编码层:MediaCodec 硬编 H.264 High Profile,720p60 用 4 Mbps、1080p60 用 8 Mbps,关键帧间隔 1 s;车载端用 MediaCodec 硬解,零拷贝渲染到 SurfaceFlinger。
  3. 传输层:
    • USB:UVC + UAC 复合设备,手机端通过 UsbDeviceConnection 提交 ASL 2.0 描述符,车载端打开 /dev/video* 节点。
    • Wi-Fi:P2P Group Owner 协商后,手机做 GO,车载做 GC,RTSP SETUP→PLAY,RTP 包 MTU 1420,FEC 前向纠错 10%。
  4. 反向控制:车载触摸屏坐标通过 HID 描述符回传,手机端注册 InputReader 映射为 MotionEvent;语音按键走 Bluetooth HFP AT+CKPD,需申请 android.permission.CAPTURE_AUDIO_OUTPUT(系统签名)。
  5. 安全合规:
    • 隐私:投屏前系统弹窗“正在投屏到 XXX 汽车”,用户点击确认;后台需每 5 min 重新弹窗校验。
    • 驾驶安全:车速 >5 km/h 时,视频层自动切换为驾驶安全模式(仅导航、通话、语音助手),由车载 CAN 总线通过 Vehicle HAL 上报车速。
  6. 性能功耗:
    • 帧率:采用 Choreographer 监听 VSYNC,MediaCodec 配置 KEY_OPERATING_RATE 为 60,防止 GPU 频率抖动。
    • 功耗:USB 投屏时关闭 Wi-Fi/5G 射频,整机电流 <300 mA;无线投屏启用 Wi-Fi 省电模式(IEEE 802.11v BSS Max Idle Period 300 s)。
  7. 异常处理:
    • 来电:TelephonyManager 监听 CALL_STATE_RINGING,立即暂停编码器,发送 RTSP TEARDOWN,车载端显示“通话中”。
    • 弱网:RTP 丢包率 >5% 时,动态降码率到 70%,并插入关键帧;>10% 时降级为 480p30。
  8. 国内适配:华为 HiCar 需集成 HMS Core CarEngine SDK,小米 CarWith 需接入 XiaomiCarService AIDL,OPPO ICCOA 需声明 com.oplus.carlink.permission.PROJECT;各厂商均在 SettingsProvider 中写入不同白名单,需引导用户手动打开“无线投屏”开关。

答案

“我负责的上一个项目是‘亿连车联’投屏模块,目标是把任意 Android 手机画面投射到后装车机。整体方案分四层:

  1. 采集层:用 MediaProjectionManager 创建 VirtualDisplay,分辨率 1080p,DPI 与手机物理屏一致;把 VirtualDisplay 的 Surface 直接喂给 MediaCodec 硬编 H.264,配置为 High Profile、8 Mbps、60 fps,关键帧间隔 1 s。
  2. 传输层:优先走 USB AOAv2,手机端通过 UsbManager 请求 accessory 模式,打开 bulk 端点 1 IN,把编码后的 H.264 裸流每 16 ms 打包一次,头部加 4 字节长度字段;车载端 Linux 用户态进程通过 libusb 轮询,收到完整帧后送入 /dev/video10 V4L2 节点,零拷贝渲染到 SurfaceFlinger。若用户未插线,则回退到 Wi-Fi P2P:手机创建 Group Owner,SSID 前缀 ICCOA_,密码 12345678;车载端用 wpa_supplicant 连接后,RTSP 端口 8554,SETUP 阶段协商 RTP/AVP/TCP 交织模式,防止 UDP 被防火墙丢弃。
  3. 反向控制:车载触摸屏通过 I²C 读到坐标后,封装成 HID 报文(Report ID 0x01,8 字节),经 USB Interrupt IN 回传;手机端在 /system/usr/idc/Vendor_xxxx_Product_xxxx.idc 中配置 touch.deviceType = touchScreen,InputReader 把报文转成 MotionEvent,实现 10 点触控。语音按键走蓝牙 HFP,车载端发 AT+CKPD=200,0,手机侧注册 BluetoothHeadset.ACTION_VENDOR_SPECIFIC_HEADSET_EVENT,解析后分发 KEYCODE_VOICE_ASSIST。
  4. 合规与异常:投屏前弹系统 Dialog,标题“正在投屏到汽车”,用户点击“允许”后把包名写入 Settings.Secure.PROJECTING_PACKAGES;车速 >5 km/h 时,车机通过 Vehicle HAL 属性 ID 0x116002(VehicleProperty.PERF_VEHICLE_SPEED)上报,手机端收到后暂停视频层,仅保留导航浮窗。来电时监听 TelephonyManager.CALL_STATE_RINGING,立即调用 MediaCodec.signalEndOfInputStream() 发送 EOS,车载端收到后显示“通话中”占位图。
    最终指标:USB 延迟 28 ms、Wi-Fi 延迟 65 ms;1080p60 整机功耗 380 mA;在地下停车场弱网(RSSI -80 dBm)下可自动降级到 720p30,丢包率 <1%。该方案已随亿连 5.3.0 版本上线,覆盖 200+ 后装车机型号。”

拓展思考

  1. 如果车载端是 Android Automotive OS 13,如何直接复用 CarService 的 CarProjectionManager?——需系统级权限 android.car.permission.CAR_PROJECTION,宿主 App 必须预装进 /system/priv-app,并在 car_service.xml 中声明 projectionActivity。
  2. 未来做 4K 投屏时,H.264 带宽不足,是否切 H.265?——H.265 硬编在骁龙 8 Gen2 以下机型普及率 <60%,需 fallback 到 H.264;可改用 AV1 硬编(MTK 天玑 9200+ 支持),但车载端需集成 dav1d 软解,CPU 占用 30%,需提前评估车机 SoC 性能。
  3. 隐私沙盒(Android 14)限制 MediaProjection 每个进程只能创建一次 VirtualDisplay,如何支持多任务分屏投屏?——需在 system_server 侧扩展 VirtualDisplayAdapter,允许车载端作为系统应用申请多个 SecureDisplay,普通三方 App 无法直接调用,需与 OEM 联合签名。