feat(eq): add per-device equalizer with 4-level preset resolution
Introduce multi-device EQ support allowing each audio output device (built-in speaker, wired, USB, individual Bluetooth by MAC) to have its own equalizer preset, combined with existing per-station presets for a full station×device matrix. - Add DispositivoAudio model and ServicioDispositivoAudio interface - Add Android platform channel (AudioDeviceCallback) for device detection - Add iOS AudioDevicesPlugin (AVAudioSession route tracking) - Extend ServicioEcualizador with device and matrix persistence keys - Implement 4-level resolution: matrix > station > device > global - Add advanced EQ settings section with feature toggle (off by default) - Extend export/import to v3 with backward compatibility - 184 tests passing, zero analyzer issues
This commit is contained in:
@@ -0,0 +1,172 @@
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:pluriwave/modelos/preset_ecualizador.dart';
|
||||
import 'package:pluriwave/servicios/servicio_ecualizador.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
void main() {
|
||||
setUp(() {
|
||||
SharedPreferences.setMockInitialValues({});
|
||||
});
|
||||
|
||||
group('ServicioEcualizador — multi-device persistence (Phase 4)', () {
|
||||
test('4.1a toggle defaults to false when no SP data', () async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final servicio = ServicioEcualizador(prefs: prefs);
|
||||
final config = await servicio.cargar();
|
||||
expect(config.eqMultiDeviceEnabled, isFalse);
|
||||
});
|
||||
|
||||
test(
|
||||
'4.1b guardarToggleMultiDispositivo persists and cargar restores it',
|
||||
() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final servicio = ServicioEcualizador(prefs: prefs);
|
||||
|
||||
await servicio.guardarToggleMultiDispositivo(true);
|
||||
final config = await servicio.cargar();
|
||||
|
||||
expect(config.eqMultiDeviceEnabled, isTrue);
|
||||
},
|
||||
);
|
||||
|
||||
test('4.1c guardarPresetDispositivo stores a device preset', () async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final servicio = ServicioEcualizador(prefs: prefs);
|
||||
const deviceId = 'bt_a2dp:AA:BB:CC:DD:EE:FF';
|
||||
|
||||
await servicio.guardarPresetDispositivo(deviceId, PresetEcualizador.jazz);
|
||||
final config = await servicio.cargar();
|
||||
|
||||
expect(
|
||||
config.presetsDispositivo[deviceId],
|
||||
equals(PresetEcualizador.jazz),
|
||||
);
|
||||
});
|
||||
|
||||
test(
|
||||
'4.1d obtenerPresetDispositivo returns null for unknown device',
|
||||
() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final servicio = ServicioEcualizador(prefs: prefs);
|
||||
final config = await servicio.cargar();
|
||||
|
||||
expect(config.presetsDispositivo['unknown_device'], isNull);
|
||||
},
|
||||
);
|
||||
|
||||
test('4.1e guardarPresetMatriz stores a matrix entry', () async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final servicio = ServicioEcualizador(prefs: prefs);
|
||||
const clave = 'station-uuid-123:bt_a2dp:AA:BB:CC:DD:EE:FF';
|
||||
|
||||
await servicio.guardarPresetMatriz(clave, PresetEcualizador.rock);
|
||||
final config = await servicio.cargar();
|
||||
|
||||
expect(config.presetsMatriz[clave], equals(PresetEcualizador.rock));
|
||||
});
|
||||
|
||||
test('4.1f multiple device presets persist independently', () async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final servicio = ServicioEcualizador(prefs: prefs);
|
||||
|
||||
await servicio.guardarPresetDispositivo(
|
||||
'bt_a2dp:11:22:33:44:55:66',
|
||||
PresetEcualizador.rock,
|
||||
);
|
||||
await servicio.guardarPresetDispositivo(
|
||||
'wired_headset',
|
||||
PresetEcualizador.jazz,
|
||||
);
|
||||
|
||||
final config = await servicio.cargar();
|
||||
expect(
|
||||
config.presetsDispositivo['bt_a2dp:11:22:33:44:55:66'],
|
||||
equals(PresetEcualizador.rock),
|
||||
);
|
||||
expect(
|
||||
config.presetsDispositivo['wired_headset'],
|
||||
equals(PresetEcualizador.jazz),
|
||||
);
|
||||
});
|
||||
|
||||
test('4.1g multiple matrix entries persist independently', () async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final servicio = ServicioEcualizador(prefs: prefs);
|
||||
|
||||
await servicio.guardarPresetMatriz(
|
||||
'station-A:bt_a2dp:AA:BB:CC:DD:EE:FF',
|
||||
PresetEcualizador.jazz,
|
||||
);
|
||||
await servicio.guardarPresetMatriz(
|
||||
'station-B:wired_headset',
|
||||
PresetEcualizador.bassBoost,
|
||||
);
|
||||
|
||||
final config = await servicio.cargar();
|
||||
expect(
|
||||
config.presetsMatriz['station-A:bt_a2dp:AA:BB:CC:DD:EE:FF'],
|
||||
equals(PresetEcualizador.jazz),
|
||||
);
|
||||
expect(
|
||||
config.presetsMatriz['station-B:wired_headset'],
|
||||
equals(PresetEcualizador.bassBoost),
|
||||
);
|
||||
});
|
||||
|
||||
test(
|
||||
'4.1h existing principal/emisora fields unaffected by new fields',
|
||||
() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final servicio = ServicioEcualizador(prefs: prefs);
|
||||
await servicio.guardarPrincipal(PresetEcualizador.pop);
|
||||
await servicio.guardarPorEmisora('station-X', PresetEcualizador.voz);
|
||||
await servicio.guardarToggleMultiDispositivo(true);
|
||||
await servicio.guardarPresetDispositivo(
|
||||
'builtin_speaker',
|
||||
PresetEcualizador.jazz,
|
||||
);
|
||||
|
||||
final config = await servicio.cargar();
|
||||
expect(config.principal, equals(PresetEcualizador.pop));
|
||||
expect(config.porEmisora['station-X'], equals(PresetEcualizador.voz));
|
||||
expect(config.eqMultiDeviceEnabled, isTrue);
|
||||
expect(
|
||||
config.presetsDispositivo['builtin_speaker'],
|
||||
equals(PresetEcualizador.jazz),
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
test('4.1i guardarConfiguracion with new fields round-trips', () async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final servicio = ServicioEcualizador(prefs: prefs);
|
||||
final config = ConfiguracionEcualizador(
|
||||
principal: PresetEcualizador.rock,
|
||||
porEmisora: {'station-1': PresetEcualizador.jazz},
|
||||
activo: true,
|
||||
eqMultiDeviceEnabled: true,
|
||||
presetsDispositivo: {
|
||||
'bt_a2dp:AA:BB:CC:DD:EE:FF': PresetEcualizador.voz,
|
||||
},
|
||||
presetsMatriz: {
|
||||
'station-1:bt_a2dp:AA:BB:CC:DD:EE:FF': PresetEcualizador.bassBoost,
|
||||
},
|
||||
);
|
||||
|
||||
await servicio.guardarConfiguracion(config);
|
||||
final restored = await servicio.cargar();
|
||||
|
||||
expect(restored.principal, equals(PresetEcualizador.rock));
|
||||
expect(restored.porEmisora['station-1'], equals(PresetEcualizador.jazz));
|
||||
expect(restored.eqMultiDeviceEnabled, isTrue);
|
||||
expect(
|
||||
restored.presetsDispositivo['bt_a2dp:AA:BB:CC:DD:EE:FF'],
|
||||
equals(PresetEcualizador.voz),
|
||||
);
|
||||
expect(
|
||||
restored.presetsMatriz['station-1:bt_a2dp:AA:BB:CC:DD:EE:FF'],
|
||||
equals(PresetEcualizador.bassBoost),
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user