docs(openspec): add SDD artifact trail for recent alarm and EQ changes
Persist the exploration, proposal, spec, design, tasks, and verify/archive reports produced during the multi-device EQ, alarm-countdown, and notification-visual-polish SDD cycles.
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
# Proposal: Multi-Device Equalizer
|
||||
|
||||
## Intent
|
||||
|
||||
Users switching between audio outputs (BT headphones, wired headset, car stereo, built-in speaker) must manually re-adjust EQ every time. Each output has different frequency response characteristics, so a flat preset on one device sounds wrong on another. The app should remember per-device EQ preferences and swap them automatically on device change.
|
||||
|
||||
## Scope
|
||||
|
||||
### In Scope
|
||||
- Platform channel `pluriwave/audio_devices` (Android + iOS) for device detection and change events
|
||||
- Dart bridge `ServicioDispositivoAudio` with testable fake
|
||||
- 4-level EQ resolution: station+device > station > device > global
|
||||
- New SharedPreferences keys for device and matrix presets
|
||||
- Feature toggle (off by default) in Settings under "Advanced Equalization Options"
|
||||
- Export/import v3 with device-dimension fields
|
||||
- Copy current preset as starting point when a device is first seen
|
||||
|
||||
### Out of Scope
|
||||
- Per-station per-device UI (matrix editor) -- future phase
|
||||
- iOS EQ engine (no `just_audio` support; state tracked, application is no-op)
|
||||
- Audio device selection/routing (only detection, not forcing output)
|
||||
- Custom device naming or grouping
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
- `audio-device-detection`: Platform channel bridge for enumerating and streaming audio output device changes (Android AudioDeviceCallback, iOS AVAudioSession route notifications)
|
||||
- `multi-device-eq`: Device-aware EQ resolution, persistence of per-device and matrix presets, automatic preset swap on device change
|
||||
|
||||
### Modified Capabilities
|
||||
- `equalizer`: Resolution logic gains device dimension; `_recrearPlayer()` re-applies device-resolved preset instead of `_presetActual`
|
||||
- `export-import`: v3 schema adds `presetsPorDispositivo` and `presetsMatriz` fields with backward-compatible import
|
||||
|
||||
## Approach
|
||||
|
||||
Custom platform channel (`pluriwave/audio_devices`) on both platforms, following the established pattern (alarm, visualizer, file_actions). `ServicioDispositivoAudio` exposes a `Stream<String>` of device IDs. `EstadoEcualizador` subscribes and resolves via the 4-level hierarchy. Feature is gated by `eq_multi_device_enabled_v1` flag.
|
||||
|
||||
## Affected Areas
|
||||
|
||||
| Area | Impact | Description |
|
||||
|------|--------|-------------|
|
||||
| `lib/servicios/servicio_dispositivo_audio.dart` | New | Dart platform channel bridge |
|
||||
| `lib/modelos/dispositivo_audio.dart` | New | Device value model |
|
||||
| `android/.../MainActivity.kt` | Modified | Add `pluriwave/audio_devices` channel |
|
||||
| `ios/Runner/AudioDevicesPlugin.swift` | New | iOS device detection |
|
||||
| `lib/servicios/servicio_ecualizador.dart` | Modified | New SP keys, device/matrix persistence |
|
||||
| `lib/estado/estado_ecualizador.dart` | Modified | 4-level resolution, device stream subscription |
|
||||
| `lib/servicios/servicio_audio.dart` | Modified | Expose current device ID |
|
||||
| `lib/servicios/servicio_export_import.dart` | Modified | v3 schema with device fields |
|
||||
| `lib/pantallas/pantalla_ajustes.dart` | Modified | Advanced EQ toggle + device preset list |
|
||||
| `test/estado/estado_ecualizador_test.dart` | Modified | Device-dimension test cases |
|
||||
| `test/helpers/fakes.dart` | Modified | FakeServicioDispositivoAudio |
|
||||
|
||||
## Risks
|
||||
|
||||
| Risk | Likelihood | Mitigation |
|
||||
|------|------------|------------|
|
||||
| `_recrearPlayer()` resets EQ on source change | High | Re-apply device-resolved preset in `_activarEcualizador()` |
|
||||
| iOS BT device uid instability across restarts | Medium | Use `portType+portName` as fallback key |
|
||||
| v3 import in older app versions | Low | Null-safe handling; ignore unknown keys |
|
||||
| SharedPreferences size with large matrix | Low | ~20KB for 250 entries; well within limits |
|
||||
|
||||
## Rollback Plan
|
||||
|
||||
1. Feature toggle `eq_multi_device_enabled_v1` defaults to `false` -- disable returns to current behavior immediately
|
||||
2. All new SP keys are independent; deleting them restores original EQ state
|
||||
3. Export v3 is backward-compatible; v2 importers ignore new fields
|
||||
4. Native channel can be removed without affecting existing channels
|
||||
5. If critical issues arise, ship a patch setting the toggle to `false` and hiding the Settings section
|
||||
|
||||
## Dependencies
|
||||
|
||||
- Android minSdk >= 23 (already required by `AndroidEqualizer`)
|
||||
- No new pub dependencies
|
||||
|
||||
## Success Criteria
|
||||
|
||||
- [ ] Device change triggers automatic EQ preset swap within 500ms
|
||||
- [ ] Resolution hierarchy produces correct preset for all 4 levels
|
||||
- [ ] Feature toggle off: zero behavioral change from current release
|
||||
- [ ] Export/import round-trips device presets without data loss
|
||||
- [ ] All new logic covered by unit tests (Strict TDD)
|
||||
- [ ] No new permissions required on either platform
|
||||
Reference in New Issue
Block a user