Open Headunit ProjectionWatchdogPolicy投屏看门狗:画面假死如何被检测与重启 📅 发布时间:2026/9/18 16:33:05 👁 浏览次数: Open Headunit ProjectionWatchdogPolicy投屏看门狗画面假死如何被检测与重启【免费下载链接】open-headunitHeadunit App for displaying Android Auto项目地址: https://gitcode.com/GitHub_Trending/he/open-headunitOpen HeadunitHeadunit Revived是一个把 Android 平板变成 Android Auto 中控的开源投屏应用。它的核心组件投屏看门狗 ProjectionWatchdogPolicy专门负责检测投屏画面假死黑屏、卡住不动并自动向手机重新索要视频流让你开车时不再手动折腾。什么是投屏假死先认识这种故障用 Android Auto 投屏时你可能遇到过这类情况 画面突然卡住不动或变黑屏但音乐还在放 导航界面定格在某一张图怎么点都没反应 需要杀 App 重开才能恢复甚至直接重启车机这就是假死手机和车机之间的连接可能还活着但视频流停了画面再也不刷新。对开车的人来说一个不再更新的黑屏比没连接更危险。Open Headunit 的答案是一个常驻的看门狗每隔 2 秒巡逻一次发现画面异常就自动执行恢复动作。核心决策逻辑集中在 ProjectionWatchdogPolicy.kt 这个文件里。看门狗如何检测每秒都在数心跳投屏看门狗并不是简单的超时重连它把画面停没停和连接断没断当成两个独立问题来判断。这是整个设计最聪明的地方。心跳一最后渲染帧距今多久看门狗会记录解码器最后一次把画面渲染到屏幕上的时间戳。如果距今超过10 秒常量FRAME_GAP_MS就判定画面已停。心跳二整条链路静默了多久这里有个 Android Auto 的坑当屏幕上没有任何内容在动时比如暂停的播放器手机会彻底停止发送视频但连接依然健康。如果只看多久没收到帧看门狗会把正常待机误报成断线——这正是历史上 issue #852 的由来音乐暂停 15~30 秒画面就被盖上连接丢失的遮罩。所以第二个心跳测量的是手机在任何通道上最后一次发消息距今多久LINK_QUIET_MS10 秒。只有两个条件同时满足才会向用户显示正在重连现象帧间隔 10s链路静默 10s看门狗的结论音乐暂停待机✅❌正常静默恢复视频流中途死亡✅✅判定断连提示用户画面正常播放❌—什么都不做判断函数 shouldShowReconnecting 就一行两个阈值必须都超过才报警。自动重启恢复黑屏不用等主动要画面检测出来只是第一步真正的价值在于恢复。重新索要视频焦点当画面已停被确认时看门狗会主动向手机发送一条VideoFocusEvent(gain true, unsolicited true)消息——相当于对手机说请把视频再发给我。这条请求受到节流保护见 VideoRecoveryPolicy避免每个 2 秒的 tick 都轰炸手机。注意一个细节恢复动作只看画面停没停不看遮罩显没显示。因为看起来像待机的卡顿流和真正停掉的流长得很像如果恢复动作绑在提示遮罩上恰好会把该救的流漏掉。显示器卡死重建投屏视图另一类假死出在车机端手机还在发视频但某些车机尤其是 MediaTek 芯片的 GLES 模式的显示消费端罢工了画面冻结常见于定格在 Android Auto 启动 Logo 上音频却正常——这是 issue #650。看门狗为此设了双重探测完全冻结连续5 秒DISPLAY_FREEZE_MS没有任何画面被绘制吞吐崩溃滑动窗口10 秒内出现 ≥10 个异常长帧——MediaTek 上表现为掉到 2~5fps单纯5 秒无帧检查抓不到触发后看门狗会自动重建投屏视图等价于手动Home 重新打开。如果重建后仍反复卡顿会升级到 SurfaceView 后端本会话内生效最多尝试 4 次避免无限重建。这段逻辑在 AapProjectionActivity.kt 的maybeRecoverFromDisplayStall中实现。第一帧催促黑屏起步也能被救新会话刚开始、画面还没出来时还有一条首帧催促循环只要会话存活、surface 已就绪、但画面上还没有可信的画面灰屏不算看门狗就每隔 1.5 秒催一次手机发关键帧直到画面出现或升级策略接手见 shouldNudgeForFirstFrame。看门狗自己也死过一段真实修复史值得讲一个小故事因为它解释了为什么看门狗被单独抽成一个 Policy 类。早期的内联检查只认HandshakeComplete这一种连接状态。但握手完成只是视频开始前的短暂窗口整个行驶过程的稳定状态是TransportStarted。结果看门狗在每个会话的第一个 tick 就判自己死亡、不再自我调度——挂在它身上的所有恢复机制重连遮罩、显示卡顿恢复、渲染器确认提示在正常会话里全都不可达。视频流中途挂掉后屏幕就一直黑着再也没人开口要。复活看门狗后它又立刻犯了另一个毛病只凭帧间隔就把 Android Auto 的正常待机叫成断线issue #852。最终方案是把两个决策拆开画面停值一次恢复请求但不一定值得弹遮罩。这些边界条件都被逐条钉死在单元测试里状态表测试ProjectionWatchdogPolicyTest.kt链路静默监测诊断用LinkGapMonitor.kt关键参数一览表常量数值作用WATCHDOG_TICK_MS2 秒看门狗巡检周期FRAME_GAP_MS10 秒画面停摆判定阈值LINK_QUIET_MS10 秒链路静默判定阈值DISPLAY_FREEZE_MS5 秒显示端冻结判定阈值LONG_FRAME_WINDOW_MS10 秒长帧滑动统计窗口所有数值均可在 ProjectionWatchdogPolicy.kt 中查到每个常量旁都有注释说明它从哪次真实故障中得来。投屏卡死时你应该做什么大多数情况下什么都不用做——看门狗会在 10 秒内自行恢复你可能只会看到短暂黑屏或一次正在重连提示。如果问题持续⚙️ 在设置中切换视图模式TextureView / SurfaceView / GLES看门狗升级失败时的兜底就是切到 SurfaceView 通过应用的日志导出功能导出日志LogExporter.kt日志里的看门狗行会写明画面空闲了 Xms但链路 Yms 前还在说话方便定位 极端情况下退出重进投屏界面看门狗会在每次进入时重新武装小结Open Headunit 的投屏看门狗把一个容易看一次算一次的玄学问题变成了一组可测试、可追溯的规则检测帧间隔 链路静默双心跳区分真断线和正常待机恢复主动索要视频焦点、重建投屏视图、升级渲染后端层层递进克制节流、次数上限、冷却期防止看门狗自己变成黑屏的制造者下次投屏黑屏时不妨多等 10 秒——它很可能已经在路上了。【免费下载链接】open-headunitHeadunit App for displaying Android Auto项目地址: https://gitcode.com/GitHub_Trending/he/open-headunit创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考