fix(alarm): defer the Dart fade-in until the native handoff confirms
The native service and the Flutter player each ran their own 5%-to- target fade-in, and both could drive audible volume at the handoff, producing a jump or ramp reset. The Dart ramp now starts exactly once from the handoff-confirmation path: the player still pre-starts at 5%, and _confirmarAudioFlutterListo() starts the ramp in a finally block so it runs whether the native confirmation succeeds or fails — the alarm can never stay stuck at 5% if the native side is already gone. Work unit 3/3 of alarm-volume-ramp-restore (fade-in dedup).
This commit is contained in:
@@ -64,7 +64,6 @@ class _PantallaAlarmaSonandoState extends State<PantallaAlarmaSonando> {
|
||||
if (!widget.audioPrearrancado) {
|
||||
unawaited(radio.reproducir(emisora));
|
||||
}
|
||||
_iniciarFadeIn();
|
||||
|
||||
// S7-R4 boundary: only `reproduciendo` cancels the fallback timer —
|
||||
// `reconectando`/`cargando` do NOT count as playing, so the 12-second
|
||||
@@ -94,7 +93,6 @@ class _PantallaAlarmaSonandoState extends State<PantallaAlarmaSonando> {
|
||||
_fallbackActivo = true;
|
||||
await _fallbackPlayer.setAsset(_assetFallback(widget.alarma.sonidoInterno));
|
||||
await _fallbackPlayer.play();
|
||||
_iniciarFadeIn();
|
||||
await _confirmarAudioFlutterListo();
|
||||
if (mounted) setState(() {});
|
||||
}
|
||||
@@ -131,12 +129,28 @@ class _PantallaAlarmaSonandoState extends State<PantallaAlarmaSonando> {
|
||||
await _fallbackPlayer.setVolume(volumen.clamp(0.0, 1.0));
|
||||
}
|
||||
|
||||
/// Confirms the native-to-Flutter audio handoff at most once per screen
|
||||
/// instance, then starts the single audible Dart fade-in ramp (Slice 3:
|
||||
/// fade-in dedup at handoff). The native ramp
|
||||
/// (`PluriWaveAlarmService.startFadeIn`) owns audio until this
|
||||
/// confirmation lands; starting the Dart ramp any earlier would
|
||||
/// interleave both ramps and produce an audible jump/reset. If the
|
||||
/// native confirmation channel call fails (dead or never-there native
|
||||
/// side), the fade-in still starts in the `finally` block below — Dart
|
||||
/// is the only audible source either way, so the ring must never stay
|
||||
/// stuck at [_volumenInicialFadeIn] forever.
|
||||
Future<void> _confirmarAudioFlutterListo() async {
|
||||
if (_audioFlutterConfirmado) return;
|
||||
_audioFlutterConfirmado = true;
|
||||
await context.read<EstadoAlarmas>().android.confirmarAudioFlutter(
|
||||
widget.alarma.id,
|
||||
);
|
||||
try {
|
||||
await context.read<EstadoAlarmas>().android.confirmarAudioFlutter(
|
||||
widget.alarma.id,
|
||||
);
|
||||
} catch (e) {
|
||||
debugPrint('[PluriWave][alarmas] confirmar audio flutter fallo: $e');
|
||||
} finally {
|
||||
_iniciarFadeIn();
|
||||
}
|
||||
}
|
||||
|
||||
/// Restores the ring-scoped `STREAM_MUSIC` override at most once per
|
||||
|
||||
Reference in New Issue
Block a user