toy-hardware/BOOT_BUTTON_NEW_IMPLEMENTATION_TEST.md

185 lines
6.1 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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. **扩展性**: 为其他类似需求提供了模板
这种设计方式更符合单一职责原则提高了代码的可维护性和可靠性