fix(alarms): harden native alarm lifecycle
This commit is contained in:
@@ -171,6 +171,61 @@ class ServicioAlarmas {
|
||||
return nuevo;
|
||||
}
|
||||
|
||||
Future<ConfiguracionAlarmas> sincronizarEjecucionesNativas(
|
||||
Map<String, DateTime> ejecuciones,
|
||||
) async {
|
||||
if (ejecuciones.isEmpty) return cargar();
|
||||
|
||||
final config = await cargar();
|
||||
final ahora = _reloj();
|
||||
var huboCambios = false;
|
||||
final alarmas =
|
||||
config.alarmas.map((alarma) {
|
||||
final gestionadaEn = ejecuciones[alarma.id];
|
||||
if (gestionadaEn == null) return alarma;
|
||||
final ultima = alarma.ultimaEjecucionGestionada;
|
||||
if (ultima != null && !gestionadaEn.isAfter(ultima)) return alarma;
|
||||
|
||||
final proxima = alarma.proximaProgramable;
|
||||
if (proxima != null &&
|
||||
proxima.isAfter(
|
||||
gestionadaEn.add(
|
||||
ServicioProgramacionAlarmas.toleranciaDisparoInminente,
|
||||
),
|
||||
)) {
|
||||
return alarma;
|
||||
}
|
||||
|
||||
final siguiente = _programacion.calcularSiguienteDespuesDeEjecucion(
|
||||
alarma: alarma,
|
||||
ejecucion: gestionadaEn,
|
||||
vacaciones: config.vacaciones,
|
||||
excepciones: config.excepciones,
|
||||
);
|
||||
huboCambios = true;
|
||||
return alarma.copyWith(
|
||||
activa:
|
||||
alarma.tipoProgramacion == TipoProgramacionAlarma.unica
|
||||
? false
|
||||
: alarma.activa,
|
||||
proximaEjecucion: siguiente,
|
||||
limpiarProximaEjecucion: true,
|
||||
limpiarSnooze: true,
|
||||
ultimaEjecucionGestionada: gestionadaEn,
|
||||
actualizadaEn: ahora,
|
||||
);
|
||||
}).toList();
|
||||
|
||||
if (!huboCambios) return config;
|
||||
final nuevo = ConfiguracionAlarmas(
|
||||
alarmas: alarmas,
|
||||
vacaciones: config.vacaciones,
|
||||
excepciones: config.excepciones,
|
||||
);
|
||||
await _guardar(nuevo);
|
||||
return nuevo;
|
||||
}
|
||||
|
||||
Future<ConfiguracionAlarmas> saltarProxima(String alarmaId) async {
|
||||
final config = await cargar();
|
||||
final alarma = config.alarmas.firstWhere((a) => a.id == alarmaId);
|
||||
|
||||
@@ -68,6 +68,25 @@ class DiagnosticoAlarmasAndroid {
|
||||
}
|
||||
}
|
||||
|
||||
class EjecucionAlarmaNativa {
|
||||
const EjecucionAlarmaNativa({
|
||||
required this.alarmaId,
|
||||
required this.gestionadaEn,
|
||||
});
|
||||
|
||||
final String alarmaId;
|
||||
final DateTime gestionadaEn;
|
||||
|
||||
factory EjecucionAlarmaNativa.fromMap(Map<Object?, Object?> map) {
|
||||
return EjecucionAlarmaNativa(
|
||||
alarmaId: map['alarmId'] as String? ?? '',
|
||||
gestionadaEn: DateTime.fromMillisecondsSinceEpoch(
|
||||
(map['handledAtMillis'] as num?)?.toInt() ?? 0,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
abstract class PuertoAlarmasAndroid {
|
||||
Stream<EventoAlarmaAndroid> get eventosAlarma;
|
||||
|
||||
@@ -81,6 +100,7 @@ abstract class PuertoAlarmasAndroid {
|
||||
Future<void> confirmarAudioFlutter(String alarmaId);
|
||||
Future<DiagnosticoAlarmasAndroid> diagnostico();
|
||||
Future<EventoAlarmaAndroid?> obtenerEventoInicial();
|
||||
Future<List<EjecucionAlarmaNativa>> obtenerEjecucionesNativasGestionadas();
|
||||
}
|
||||
|
||||
class ServicioAlarmasAndroid implements PuertoAlarmasAndroid {
|
||||
@@ -208,6 +228,24 @@ class ServicioAlarmasAndroid implements PuertoAlarmasAndroid {
|
||||
return evento.alarmaId.isEmpty ? null : evento;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<EjecucionAlarmaNativa>>
|
||||
obtenerEjecucionesNativasGestionadas() async {
|
||||
final raw = await _channel.invokeMethod<List<Object?>>(
|
||||
'getHandledAlarmOccurrences',
|
||||
);
|
||||
if (raw == null || raw.isEmpty) return const [];
|
||||
return raw
|
||||
.whereType<Map<Object?, Object?>>()
|
||||
.map(EjecucionAlarmaNativa.fromMap)
|
||||
.where(
|
||||
(evento) =>
|
||||
evento.alarmaId.isNotEmpty &&
|
||||
evento.gestionadaEn.millisecondsSinceEpoch > 0,
|
||||
)
|
||||
.toList();
|
||||
}
|
||||
|
||||
Future<void> _logAndInvokeVoid(String method, Map<String, Object?> args) {
|
||||
debugPrint('[PluriWave][alarmas] $method $args');
|
||||
return _channel.invokeMethod<void>(method, args);
|
||||
|
||||
Reference in New Issue
Block a user