Skip to content

Latest commit

 

History

History
294 lines (207 loc) · 9.63 KB

File metadata and controls

294 lines (207 loc) · 9.63 KB

新车机适配指南

本文档说明如何将 FlymeNeteaseHelper 适配到其他车型或车机系统。

兼容性分级

级别 条件 结论
A:可直接进入实车验证 按键、网易云组件、MediaSession、虚拟显示、特权桥、CarAudio 和 PowerService 均匹配 可按安装指南部署,仍须完成整套验收
B:需要适配 ADB/权限可用,但包名、按键、特权桥、音频 zone 或厂商服务不同 修改源码和脚本后再验证
C:当前方案不可直接用 无 ADB/READ_LOGS、无可替代按键入口、无运行时特权通道,或系统禁止必要显示操作 需要系统权限、厂商支持或重新设计实现路径

必须满足的基础条件

  • Android 8.0(API 26)及以上
  • 允许安装第三方 APK,并允许 Helper 开机自启和后台存活
  • 安装和首次配置阶段能够稳定连接 ADB
  • 能授予 Helper READ_LOGS、精确/粗略定位权限
  • 能开启 Helper 的通知使用权和辅助功能服务
  • 系统允许创建私有虚拟显示和显示非交互式辅助功能遮罩
  • 系统日期、时间和时区准确,建议启用自动时间、自动时区
  • 网易云音乐能在该车机上正常登录、恢复歌曲并取得车载音频焦点

逐项适配清单

1. 实体播放键适配

检查方法

adb -s <设备序列号> shell logcat -c
adb -s <设备序列号> shell logcat -v raw InputServiceLog-KeyCodeActionImpl:I "*:S"

执行第二条命令后短按一次实体播放键,观察输出。

当前银河 L7 的识别特征

日志标签:InputServiceLog-KeyCodeActionImpl
事件:onShortClick
keyCode:200085
softKeyFunction:3

适配方法

若目标车机的按键日志标签、字段或 keyCode 不同,需要修改 KeyLogMonitor.java 中的日志匹配逻辑:

  1. 确认日志中稳定的唯一标识(标签 + 关键字段)
  2. 修改 KeyLogMonitor 中的正则表达式或匹配逻辑
  3. 验证一次短按只产生一次有效事件
  4. 验证长按或连按不会被误判

备选方案

若没有 READ_LOGS 权限或日志中没有可识别的按键事件,需要改用其他按键入口:

  • 厂商广播
  • 输入服务(InputService)
  • KeyEvent 分发
  • 媒体按钮 Intent

这属于较大改动,需要重新设计按键监听模块。


2. 网易云音乐适配

检查包名和 Activity

# 确认包名
adb -s <设备序列号> shell pm path com.netease.cloudmusic.iot

# 确认启动 Activity
adb -s <设备序列号> shell cmd package resolve-activity --brief \
    -a android.intent.action.MAIN \
    -c android.intent.category.LAUNCHER \
    com.netease.cloudmusic.iot

当前适配对象

包名:com.netease.cloudmusic.iot
冷启动入口:com.netease.cloudmusic.iot.app.LoadingActivity
RN 页面:com.netease.cloudmusic.iot.module.rn.CloudMusicRNActivity
实车版本:6.1.20

适配方法

若目标车机使用不同版本的网易云(普通手机版、其他车机版、不同包名等):

  1. 修改 CoreLogic.java 中的包名和 Activity 常量
  2. 修改 HelperCoordinator.java 中相关的组件引用
  3. 修改 TelnetDisplayBridge.java 中的启动和迁移目标
  4. 修改 MediaStateInspector.java 中的包名过滤
  5. 重新验证 MediaSession 状态识别

MediaSession 验证

adb -s <设备序列号> shell dumpsys media_session

必须确认:

  • 网易云能建立可识别的 MediaSession
  • Helper 可判断播放、暂停、连接、缓冲和停止状态
  • 播放状态码与标准 Android PlaybackState 一致

3. 虚拟显示适配

检查方法

# 查看当前显示
adb -s <设备序列号> shell dumpsys display

# 查看虚拟显示支持
adb -s <设备序列号> shell dumpsys display | Select-String "Virtual"

验证项

  • 系统是否允许第三方应用创建私有虚拟显示
  • 虚拟显示的安全层级是否允许 Activity 迁移
  • 虚拟显示的分辨率和密度设置
  • Activity 从物理显示迁移到虚拟显示是否正常

可能的问题

  • 某些车机系统限制第三方应用创建虚拟显示
  • 虚拟显示可能有不同的生命周期行为
  • 迁移 Activity 可能需要不同的 flag 或方法

4. 冷启动特权桥适配

重要:这是实现"冷启动不显示网易云页面"的关键。若目标车机没有持久的本机特权通道,只能采用可见启动的降级路径。

当前实现

银河 L7 使用开机常驻的 root telnetd:

/system/bin/busybox
root telnetd
监听地址:[::1]:23

要求

目标车机在日常运行时必须允许受控执行以下动作:

  • 截取物理主显示
  • 指定物理显示启动明确的网易云 Activity
  • 将明确的网易云 Activity 移到 Helper 创建的虚拟显示
  • 全程不要求 USB 或无线 ADB 在线

可接受的实现

  • 厂商已存在且仅监听本机回环的 root/特权服务
  • 自建的系统应用、平台签名服务或厂商授权 Binder 服务
  • 其他经过限制、不会暴露远程任意命令能力的本机桥

适配方法

  1. 确认目标车机可用的特权通道类型
  2. 创建新的 Bridge 类(实现与 TelnetDisplayBridge 相同的接口)
  3. 修改 HelperCoordinator 中 Bridge 的初始化
  4. 验证每项操作的正确性和安全性

安全要求

  • 特权桥只执行固定命令,不接受外部任意 shell 文本
  • 所有参数必须经过白名单验证
  • 只能从本机回环访问,不能暴露给外部网络
  • 服务会随车机开机自动恢复

5. CarAudio 适配

检查方法

adb -s <设备序列号> shell dumpsys audio
adb -s <设备序列号> shell dumpsys car_service 2>/dev/null

验证项

  • 物理主屏启动时音频焦点落在有效 CarAudio zone(通常为 zone 0)
  • 迁移到虚拟显示后音频不会中断
  • com.android.car 或厂商音频服务没有 FATAL EXCEPTION

注意事项

⚠️ 不能直接在 Helper 私有虚拟显示冷启动网易云。

部分车机会拒绝跨 UID 的二跳 Activity;即使使用特权启动,网易云也可能把虚拟显示编号当成 CarAudio zone,引起音频服务异常。必须验证"先物理主屏取得有效音频 zone,再迁移"的完整路径。


6. 日夜模式适配

当前银河 L7 接口

包名:com.autolink.powerservice
Service:com.autolink.powerservice.PowerService
Service Action:com.autolink.powerservice.PowerService
Binder 描述符:com.autolink.adapterbinder.IPower
设置模式事务码:7
读取模式事务码:8
夜间模式值:0
日间模式值:1

检查方法

# 确认 PowerService 存在
adb -s <设备序列号> shell pm path com.autolink.powerservice
adb -s <设备序列号> shell cmd package resolve-service --brief -a com.autolink.powerservice.PowerService

# 确认位置服务
adb -s <设备序列号> shell dumpsys location

# 确认自动时间设置
adb -s <设备序列号> shell settings get global auto_time
adb -s <设备序列号> shell settings get global auto_time_zone

适配方法

若目标车机使用不同的主题/电源服务:

  1. 分析目标车机的日夜模式控制接口
  2. 修改 DayNightController.java 中的 Binder 调用逻辑
  3. 验证写入结果与系统 UiModeManager 状态一致
  4. 确认厂商其他服务不会周期性覆盖 Helper 设置

⚠️ 警告

必须确认 Binder 描述符、事务码和取值含义完全一致,且第三方应用确实能绑定。仅仅存在同名包不能证明兼容;未完成核验前必须关闭日夜自动切换,否则错误事务可能调用其他厂商功能。


7. 媒体小窗适配

若目标车机使用不同的媒体小窗实现(非 Flyme 媒体小窗),需要:

  1. 识别媒体小窗的包名和组件
  2. 分析小窗与 MediaSession 的交互方式
  3. 调整 HelperCoordinator 中的小窗相关逻辑
  4. 验证小窗场景下的播放/暂停、续播、任务保护等功能

推荐部署顺序

  1. 记录车型、固件、Android API、网易云版本、显示数量和 CarAudio zone
  2. 确认 ADB 为 device,完成只读状态采集
  3. 核对实体按键日志、网易云包/Activity、MediaSession 和 PowerService
  4. 核对运行时特权桥;确认重启后仍存在且只允许本机访问
  5. 安装 Helper,先保持 observe,关闭日夜自动切换
  6. 授予 READ_LOGS、定位、通知使用权和辅助功能权限
  7. 启用网易云修复,依次验证冷态、热态、桌面、小窗、连续按键和超时恢复
  8. 检查 CarAudio zone 和系统音频服务日志,确认没有崩溃
  9. 单独核验厂商 Binder,完全匹配后再启用日夜自动切换
  10. 完成一次整机重启、一次锁车休眠唤醒,以及至少一次日出/日落边界验证

最终验收标准

网易云播放模块

  • 冷态按键能开始或恢复播放,主屏不出现网易云页面(有特权桥时)
  • 允许的唯一视觉差异是顶部/底部系统栏短暂变化
  • 热态播放与暂停均可直接切换,不要求用户进入网易云页面
  • 返回桌面和打开底部小窗时不退出、不暂停
  • 物理主屏与副屏任务不被网易云占用,RN Activity 位于隐藏显示
  • 音频焦点始终使用有效 zone,车载音频服务无崩溃
  • 重启和休眠唤醒后功能自动恢复
  • 断开电脑和 ADB 后仍能正常运行

日夜模块

  • 位置、时间、时区有效
  • 日出/日落计算和两个精确闹钟正确
  • PowerService 写入结果与系统日夜状态一致
  • 重启、锁车休眠后自动恢复
  • 厂商其他服务不会周期性覆盖 Helper 设置