feat(dev): 기기 배터리 성능 테스트용 임시 부하 버튼 (mim 1s / mbb 10s)

프로브 배터리 소모율 실측을 위해 홈 화면(dev 모드)에 고정 트래픽 부하를
거는 임시 버튼 추가.

- BatteryDrainTester: Handler 기반 루프 소유자. mim? 1초 / mbb? 10초 주기.
  화면 이동·백그라운드와 무관하게 계속 돌고 "정지" 로만 종료.
  mim 은 isMtbBusy 앞에서 skip (imuCollector.reset() 이 mtb/mbb 의 rim 파괴
  방지 · BLE_PROTOCOL_REFERENCE §2.6). 미연결 구간은 송신만 skip 해 auto-
  reconnect 후 부하 자동 재개.
- BatteryDrainTestDialog/Button: 송수신 카운터 · 배터리 전압 delta · 온도 ·
  마지막 응답 경과 · mV/h 소모율 실시간 표시.
- BleManager.onResponseFrame: 계측 전용 수신 프레임 tap 추가 (기존 콜백
  clobber 없이 rim/ric/rbb/rsn 집계). 기능 로직은 이 콜백에 비의존.
- PiezoMonitoringView: 부하 테스트 중이면 자체 mim 폴링 skip (중복 트래픽 방지).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-21 17:02:55 +09:00
parent 1f2fc56008
commit f19a56694b
5 changed files with 425 additions and 1 deletions
@@ -292,6 +292,12 @@ class BleManager private constructor(private val context: Context) {
var onReconnectionFailed: (() -> Unit)? = null
var onImuReceived: ((ByteArray) -> Unit)? = null
var onMbbHeaderReceived: ((ByteArray) -> Unit)? = null
/**
* 모든 수신 프레임 tap (3-char 태그 + raw). 파싱이 끝난 뒤 CommandQueue 완료 판정 직전 호출.
* 계측/진단 전용 (dev 배터리 부하 테스트) — 기능 로직은 이 콜백에 의존하지 않는다.
* ⚠ BLE 콜백 스레드에서 호출됨. 무거운 작업 금지.
*/
var onResponseFrame: ((String, ByteArray) -> Unit)? = null
val isBluetoothReady: Boolean get() = bluetoothAdapter?.isEnabled == true
@@ -1760,6 +1766,7 @@ class BleManager private constructor(private val context: Context) {
// True 면 pending 해제 + 큐에 대기 중이던 다음 명령 dispatch.
if (data.size >= 4) {
val tag3 = prefix.take(3)
try { onResponseFrame?.invoke(tag3, data) } catch (_: Exception) {}
commandQueue.onResponseTag(tag3)
}
}