_onDispositivoCambiado() bootstrapped a device-level preset entry for every never-seen device id, including the built-in speaker. That persistent level-3 entry masked later global-preset edits (level 3 beats level 4 on every resolution), so disconnecting a BT device or cold-starting without one could leave the EQ stuck on an outdated copy instead of the current global preset. The base speaker is now excluded from the first-seen bootstrap: disconnect and cold start always resolve through the live hierarchy. BT/wired/USB devices keep their bootstrap behavior unchanged.
55 lines
2.8 KiB
Markdown
55 lines
2.8 KiB
Markdown
# Tasks: EQ Device Disconnect / Cold-Start Revert
|
|
|
|
## Review Workload Forecast
|
|
|
|
| Field | Value |
|
|
|-------|-------|
|
|
| Estimated changed lines | ~130-160 |
|
|
| 400-line budget risk | Low |
|
|
| Chained PRs recommended | No |
|
|
| Suggested split | Single PR |
|
|
| Delivery strategy | ask-on-risk |
|
|
| Chain strategy | pending |
|
|
|
|
Decision needed before apply: No
|
|
Chained PRs recommended: No
|
|
Chain strategy: pending
|
|
400-line budget risk: Low
|
|
|
|
### Suggested Work Units
|
|
|
|
| Unit | Goal | Likely PR | Notes |
|
|
|------|------|-----------|-------|
|
|
| 1 | Bootstrap guard fix + proof tests (RED-GREEN-REFACTOR) | PR 1 (single PR) | Base: main. One logical change, well under 400-line budget |
|
|
|
|
## Phase 1: RED — Write Failing Tests
|
|
|
|
- [x] 1.1 Add group `'device disconnect / cold-start revert (Phase D)'` to `test/estado/estado_ecualizador_test.dart` after L334, reusing existing fakes (no new fake types)
|
|
- [x] 1.2 D.1 disconnect resolves+applies base preset (spec Req 1, scenario "Disconnect resolves and applies the base preset")
|
|
- [x] 1.3 D.2 disconnect does NOT bootstrap `presetsDispositivo['builtin_speaker']` from the disconnecting device (spec Req 2)
|
|
- [x] 1.4 D.3 cold start with no device applies base resolution via `cargarPersistido()` only, not a stale device preset (spec Req 3)
|
|
- [x] 1.5 D.4 connect→disconnect→reconnect cycle: correct preset at each step, matrix override honored, device preset unchanged by disconnect (spec Req 4, locks 5.5b)
|
|
- [x] 1.6 D.5 station override still wins over global on disconnect-to-base (design Testing Strategy D.5)
|
|
- [x] 1.7 Run `flutter test test/estado/estado_ecualizador_test.dart` — confirm D.1-D.5 FAIL; D.2 must fail on the real bootstrap-collision bug, not a tautology
|
|
|
|
## Phase 2: GREEN — Minimal Fix
|
|
|
|
- [x] 2.1 In `lib/estado/estado_ecualizador.dart` `_onDispositivoCambiado()` (L216-220), gate bootstrap on `dispositivo.tipo != TipoDispositivo.altavozInterno`
|
|
- [x] 2.2 Leave L213 (`_dispositivoActualId` assignment) and L222-226 (resolve+apply) unchanged — single handler, no branching on event type
|
|
- [x] 2.3 Run test suite — confirm D.1-D.5 PASS
|
|
|
|
## Phase 3: Regression Lock
|
|
|
|
- [x] 3.1 Run full `estado_ecualizador_test.dart` — all existing groups green (5.1-5.8, 2.1-2.4, rename API, guardarPresetDispositivo)
|
|
- [x] 3.2 Confirm 5.5a and 2.2 (both `bluetoothA2dp`) unaffected — guard is base-device-scoped only
|
|
- [x] 3.3 Confirm 5.5b and toggle-off 5.7a/5.8b pass unmodified — named consistency locks
|
|
|
|
## Phase 4: REFACTOR
|
|
|
|
- [x] 4.1 Add one-line comment above the bootstrap block explaining the `altavozInterno` exclusion (prevents L3 masking future L4 edits)
|
|
- [x] 4.2 `flutter analyze` on both modified files — zero new warnings
|
|
|
|
## Phase 5: Manual Sanity (light, non-blocking)
|
|
|
|
- [ ] 5.1 On-device: connect BT/USB with own preset, disconnect (reverts to base), reconnect (returns to device preset) — one-time confidence check
|