toy-hardware/BOOT_BUTTON_NEW_IMPLEMENTATION_TEST.md

6.1 KiB
Raw Permalink Blame History

BOOT按键新实现方案测试指南

概述

本文档描述了BOOT按键新实现方案的测试验证流程。新方案创建了专门的 AbortSpeakingAndReturnToIdle() 函数来处理从说话状态到空闲状态的切换,而不是修改原有的 AbortSpeaking() 函数。

新实现方案特点

1. 专门函数设计

  • 函数名称: AbortSpeakingAndReturnToIdle()
  • 专门用途: 处理BOOT按键在说话状态下的切换需求
  • 独立性: 不影响其他场景下的 AbortSpeaking() 调用

2. 核心功能

  • 状态检查:确保当前处于说话状态
  • 安全性检查:防止重复操作和竞态条件
  • 发送中止消息通知服务器停止TTS
  • 主动关闭连接100ms延迟后强制关闭WebSocket
  • 完整日志:详细记录每个操作步骤

3. 调用路径

BOOT按键点击 → InitializeButtons() → AbortSpeakingAndReturnToIdle() → OnAudioChannelClosed() → SetDeviceState(kDeviceStateIdle) → 播放待机音

测试场景

场景1正常说话状态下的BOOT按键操作

测试步骤

  1. 启动设备,确保连接正常
  2. 触发语音对话让设备进入说话状态播放TTS
  3. 在TTS播放过程中按下BOOT按键
  4. 观察设备行为和日志输出

预期结果

🔴 BOOT按键设备处于说话状态启动专门的中止和切换流程
🔴 AbortSpeakingAndReturnToIdle: Starting transition from speaking to idle state
🔴 AbortSpeakingAndReturnToIdle: Sending abort message to server
🔴 AbortSpeakingAndReturnToIdle: Abort message sent successfully
🔴 AbortSpeakingAndReturnToIdle: Actively closing audio channel
🔴 CloseAudioChannel: Actively closing WebSocket connection
🔴 OnDisconnected: WebSocket connection disconnected
🔴 OnDisconnected: Audio processor stopped immediately
🔴 OnDisconnected: Triggering OnAudioChannelClosed callback
🔴 OnAudioChannelClosed: Audio channel closed, starting cleanup tasks
🔵 SetDeviceState: Entering idle state from speaking, playing standby sound
🔵 SetDeviceState: Standby sound playback initiated

验证要点

  • TTS立即停止播放
  • 设备状态切换到空闲kDeviceStateIdle
  • 播放待机音daiming.p3
  • 显示屏显示"待机"状态
  • LED指示灯切换到空闲状态颜色

场景2非说话状态下的BOOT按键操作

测试步骤

  1. 确保设备处于空闲状态
  2. 按下BOOT按键
  3. 观察设备行为

预期结果

  • 设备应该正常切换到聆听状态
  • 不应该调用 AbortSpeakingAndReturnToIdle() 函数
  • 应该播放"卡卡在呢"提示音

场景3快速连续按键测试

测试步骤

  1. 让设备进入说话状态
  2. 快速连续按下BOOT按键多次间隔小于500ms
  3. 观察防抖机制和安全检查

预期结果

BOOT button clicked too frequently, ignoring this click
🔴 AbortSpeakingAndReturnToIdle: Operation not safe, scheduling retry

场景4网络异常情况测试

测试步骤

  1. 让设备进入说话状态
  2. 断开网络连接
  3. 按下BOOT按键
  4. 观察错误处理

预期结果

🔴 AbortSpeakingAndReturnToIdle: Audio channel not available, forcing close

关键改进点

1. 函数职责分离

  • 原方案: 修改 AbortSpeaking() 函数,影响所有调用场景
  • 新方案: 创建专门函数只处理BOOT按键的特定需求

2. 代码维护性

  • 独立性: 新函数不影响现有的语音打断逻辑
  • 可扩展性: 未来可以为其他按键创建类似的专门函数
  • 可测试性: 单独测试BOOT按键功能不影响其他功能

3. 安全性增强

  • 状态检查:确保只在说话状态下执行
  • 操作安全性:防止重复调用和竞态条件
  • 异常处理:网络异常时的降级处理

日志监控要点

成功流程日志序列

  1. 🔴 BOOT按键设备处于说话状态启动专门的中止和切换流程
  2. 🔴 AbortSpeakingAndReturnToIdle: Starting transition from speaking to idle state
  3. 🔴 AbortSpeakingAndReturnToIdle: Sending abort message to server
  4. 🔴 AbortSpeakingAndReturnToIdle: Abort message sent successfully
  5. 🔴 AbortSpeakingAndReturnToIdle: Actively closing audio channel
  6. 🔴 OnAudioChannelClosed: Audio channel closed, starting cleanup tasks
  7. 🔵 SetDeviceState: Entering idle state from speaking, playing standby sound

异常情况日志

  • 🔴 AbortSpeakingAndReturnToIdle: Device not in speaking state - 状态不匹配
  • 🔴 AbortSpeakingAndReturnToIdle: Operation not safe, scheduling retry - 操作不安全
  • 🔴 AbortSpeakingAndReturnToIdle: Failed to send abort message - 发送失败
  • 🔴 AbortSpeakingAndReturnToIdle: Audio channel not available, forcing close - 连接不可用

性能验证

响应时间测试

  • 目标: BOOT按键按下到TTS停止 < 200ms
  • 目标: 完整状态切换到播放待机音 < 500ms

资源使用测试

  • 监控内存使用情况
  • 检查是否有内存泄漏
  • 验证任务调度的效率

故障排除

问题1待机音不播放

可能原因

  • 音频输出未正确初始化
  • 状态切换未完成
  • 音频文件损坏

排查方法

  • 检查 SetDeviceState 日志
  • 验证音频编解码器状态
  • 测试其他音频播放功能

问题2连接未正确关闭

可能原因

  • WebSocket关闭失败
  • 网络异常
  • 协议层错误

排查方法

  • 检查 CloseAudioChannel 日志
  • 监控网络连接状态
  • 验证协议层实现

问题3状态转换异常

可能原因

  • 竞态条件
  • 重复调用
  • 安全检查失败

排查方法

  • 检查 IsSafeToOperate 返回值
  • 监控操作时间戳
  • 验证防抖机制

总结

新实现方案通过创建专门的 AbortSpeakingAndReturnToIdle() 函数,实现了:

  1. 功能独立性: 不影响现有的 AbortSpeaking() 逻辑
  2. 代码清晰性: 专门处理BOOT按键的特定需求
  3. 维护便利性: 易于测试和调试
  4. 扩展性: 为其他类似需求提供了模板

这种设计方式更符合单一职责原则,提高了代码的可维护性和可靠性。