fix(devices): cache platform device names, dedupe placeholder ids, purge collided EQ entries
Dart half of bt-device-identity. EstadoEcualizador now caches each device's platform-reported name in memory so the settings screen shows the device's own Bluetooth name instead of its raw id when no custom rename exists, and skips auto-creating preset entries for the composite-placeholder sentinel. Enabling multi-device EQ triggers the Bluetooth permission request through the new channel contract. A flag-guarded one-time migration purges only entries keyed by the exact literal placeholder id from the three per-device preference maps, since those collided entries cannot be attributed to a device. Work unit 2/2 of bt-device-identity (Dart state + migration).
This commit is contained in:
@@ -43,6 +43,13 @@ class ServicioEcualizador {
|
||||
static const _keyPresetsMatriz = 'eq_presets_matriz_v1';
|
||||
static const _keyNombresDispositivos = 'eq_nombres_dispositivos_v1';
|
||||
|
||||
/// bt-device-identity ADR-5: guard flag for the one-time placeholder purge.
|
||||
static const _keyPlaceholderPurgaHecha = 'eq_placeholder_purge_done_v1';
|
||||
|
||||
/// bt-device-identity ADR-3: the exact OS placeholder MAC, in the
|
||||
/// `bt_a2dp:`-prefixed id shape used across all device-keyed SP maps.
|
||||
static const _placeholderMacLiteral = 'bt_a2dp:02:00:00:00:00:00';
|
||||
|
||||
final SharedPreferences? _prefs;
|
||||
|
||||
/// Injected startup instance (S3-R4); getInstance() is only a fallback.
|
||||
@@ -50,6 +57,7 @@ class ServicioEcualizador {
|
||||
_prefs ?? SharedPreferences.getInstance();
|
||||
|
||||
Future<ConfiguracionEcualizador> cargar() async {
|
||||
await migrarClavesPlaceholder();
|
||||
final prefs = await _resolverPrefs();
|
||||
final principal = _leerPresetPrincipal(prefs);
|
||||
final porEmisora = _leerPresetsPorEmisora(prefs);
|
||||
@@ -67,6 +75,56 @@ class ServicioEcualizador {
|
||||
);
|
||||
}
|
||||
|
||||
/// One-time guarded migration (bt-device-identity ADR-5): purges entries
|
||||
/// keyed by the exact OS placeholder MAC ([_placeholderMacLiteral]) from
|
||||
/// all three device-keyed SP maps. Idempotent — short-circuits via
|
||||
/// [_keyPlaceholderPurgaHecha] after the first successful run. Every other
|
||||
/// entry (including near-miss keys) is preserved byte-for-byte.
|
||||
Future<void> migrarClavesPlaceholder() async {
|
||||
final prefs = await _resolverPrefs();
|
||||
if (prefs.getBool(_keyPlaceholderPurgaHecha) ?? false) return;
|
||||
|
||||
final presetsPorDispositivo = _leerMapa(prefs, _keyPresetsPorDispositivo);
|
||||
if (presetsPorDispositivo.remove(_placeholderMacLiteral) != null) {
|
||||
await _guardarMapa(
|
||||
prefs,
|
||||
_keyPresetsPorDispositivo,
|
||||
presetsPorDispositivo,
|
||||
);
|
||||
}
|
||||
|
||||
// Matrix keys are "stationUuid:deviceId"; split on the FIRST colon only
|
||||
// (station UUIDs are RFC4122 and contain no colons — multi-device-eq
|
||||
// ADR-3), since deviceId itself may contain colons (e.g. a MAC-based id).
|
||||
final presetsMatriz = _leerMapa(prefs, _keyPresetsMatriz);
|
||||
final clavesMatrizAPurgar = presetsMatriz.keys.where((clave) {
|
||||
final separador = clave.indexOf(':');
|
||||
if (separador == -1) return false;
|
||||
final deviceIdSegmento = clave.substring(separador + 1);
|
||||
return deviceIdSegmento == _placeholderMacLiteral;
|
||||
}).toList();
|
||||
if (clavesMatrizAPurgar.isNotEmpty) {
|
||||
for (final clave in clavesMatrizAPurgar) {
|
||||
presetsMatriz.remove(clave);
|
||||
}
|
||||
await _guardarMapa(prefs, _keyPresetsMatriz, presetsMatriz);
|
||||
}
|
||||
|
||||
final nombresDispositivos = _leerMapaStrings(
|
||||
prefs,
|
||||
_keyNombresDispositivos,
|
||||
);
|
||||
if (nombresDispositivos.remove(_placeholderMacLiteral) != null) {
|
||||
await _guardarMapaStrings(
|
||||
prefs,
|
||||
_keyNombresDispositivos,
|
||||
nombresDispositivos,
|
||||
);
|
||||
}
|
||||
|
||||
await prefs.setBool(_keyPlaceholderPurgaHecha, true);
|
||||
}
|
||||
|
||||
Future<void> guardarPrincipal(PresetEcualizador preset) async {
|
||||
final prefs = await _resolverPrefs();
|
||||
await prefs.setString(_keyPresetPrincipal, jsonEncode(preset.toJson()));
|
||||
|
||||
Reference in New Issue
Block a user