feat(alarm): add musical alarm foundation
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
# Design: alarm-clock-module
|
||||
|
||||
## Architecture
|
||||
- Flutter owns alarm domain data, UX, recurrence calculation, and persistence.
|
||||
- Android owns exact wakeup delivery through AlarmManager/setAlarmClock and notification actions.
|
||||
- Communication uses a MethodChannel, tentatively `pluriwave/alarm_scheduler`.
|
||||
- Existing `ServicioTimer` remains unchanged; a new `ServicioAlarmas` manages alarms.
|
||||
|
||||
## Data model
|
||||
- `AlarmaMusical`: id, name, enabled, hour, minute, scheduleType, weekdays, stationUuid/url snapshot, fallbackStation snapshot, bundledSoundId, volume, snoozeMinutes, soundOnVacation, nextOccurrenceAt.
|
||||
- `RangoVacaciones`: id, name, startDate, endDate, enabled.
|
||||
- `ExcepcionAlarma`: alarmId, occurrenceAt, type (`skipNext`, `snooze`, `vacation`).
|
||||
- `EjecucionAlarma`: scheduledAt, firedAt, status, fallbackUsed, failureReason.
|
||||
|
||||
## Persistence
|
||||
Use JSON files or SharedPreferences for MVP to avoid risky DB migrations. If alarm history grows, migrate to sqflite later.
|
||||
|
||||
## Android native components
|
||||
- `PluriWaveAlarmReceiver`: receives exact alarm and pre-alarm actions.
|
||||
- `PluriWaveAlarmScheduler`: schedules/cancels next alarm and pre-notification.
|
||||
- `PluriWaveAlarmActivity` or full-screen notification target for the ringing UI.
|
||||
- Notification channels:
|
||||
- `alarm_pre_notice`: silent, low/default importance, no sound.
|
||||
- `alarm_ringing`: high importance for active alarms.
|
||||
|
||||
## Audio strategy
|
||||
MVP: when the alarm fires, bring the Flutter app/alarm screen forward and use existing audio_service to play station/fallback. If Flutter/audio startup fails, Android should be able to play a bundled raw sound as last fallback.
|
||||
|
||||
## Reliability diagnostics
|
||||
Expose statuses for:
|
||||
- exact alarm permission (`canScheduleExactAlarms`).
|
||||
- notification permission.
|
||||
- battery optimization warning.
|
||||
- DND policy access for optional override.
|
||||
|
||||
## Key decision
|
||||
Use `setAlarmClock` for actual alarm occurrences because Android treats these as critical and visible user alarms. Use a separate exact/inexact notification alarm for the 30-minute silent pre-notice depending on permission and platform behavior.
|
||||
@@ -0,0 +1,32 @@
|
||||
# Proposal: alarm-clock-module
|
||||
|
||||
## Intent
|
||||
Build an Android-first musical alarm system for PluriWave that can wake the user with radio/music while keeping reliable fallbacks and clear Android permission diagnostics.
|
||||
|
||||
## Scope
|
||||
- Add a new alarm domain separate from the existing sleep timer.
|
||||
- Support one-shot and recurrent alarms by weekday.
|
||||
- Support snooze options: 3, 5, and 10 minutes.
|
||||
- Support a silent pre-alarm notification 30 minutes before the next occurrence, with an action to skip only that next execution.
|
||||
- Support vacation ranges and per-alarm `soundOnVacation` behavior. Default: true.
|
||||
- Support audio fallback chain: selected station, optional fallback station, bundled internal alarm sounds.
|
||||
- Add Android native scheduling using AlarmManager/setAlarmClock via MethodChannel.
|
||||
- Add Flutter UI for listing, editing, enabling/disabling, vacation ranges, and reliability diagnostics.
|
||||
|
||||
## Out of Scope for MVP
|
||||
- Cloud sync.
|
||||
- iOS reliable alarm parity.
|
||||
- Complex alarm-dismiss challenges.
|
||||
- Multiple fallback station chains beyond one optional fallback station.
|
||||
- Full background radio streaming implementation independent from existing audio_service if not needed for MVP.
|
||||
|
||||
## Rollback Plan
|
||||
- Alarm functionality is isolated behind new services/models/screens and Android receivers.
|
||||
- Existing radio playback, timer, favorites, EQ, and recording flows should remain untouched except for navigation entry points.
|
||||
- If native scheduling causes issues, remove Android manifest receiver/service entries and hide the alarms entry point.
|
||||
|
||||
## Risks
|
||||
- Android exact alarms require special permissions on Android 12+ and can be denied by default on Android 14+.
|
||||
- OEM battery managers may still interfere; app must expose diagnostics and guidance.
|
||||
- DND bypass requires Notification Policy Access and cannot be silently forced.
|
||||
- Playing a radio stream at alarm time depends on network; bundled sounds must always be present.
|
||||
@@ -0,0 +1,62 @@
|
||||
# Spec: alarm-clock-module
|
||||
|
||||
## Requirement: Alarm scheduling
|
||||
The app MUST support creating enabled/disabled alarms with a local time, one-shot or recurring schedule, and next occurrence calculation.
|
||||
|
||||
### Scenario: one-shot alarm fires once
|
||||
Given an enabled one-shot alarm for a future date/time
|
||||
When its scheduled occurrence fires
|
||||
Then the app MUST start the alarm flow
|
||||
And the alarm MUST be disabled or marked completed after that occurrence unless snoozed.
|
||||
|
||||
### Scenario: weekday recurring alarm
|
||||
Given an enabled recurring alarm with selected weekdays
|
||||
When the next matching weekday/time arrives
|
||||
Then the app MUST start the alarm flow
|
||||
And MUST schedule the following matching occurrence.
|
||||
|
||||
## Requirement: Snooze
|
||||
The app MUST offer snooze durations of 3, 5, and 10 minutes when an alarm is ringing.
|
||||
|
||||
### Scenario: snooze selected
|
||||
Given an alarm is ringing
|
||||
When the user selects snooze 5 minutes
|
||||
Then the app MUST stop current alarm playback
|
||||
And MUST schedule a one-off snooze occurrence 5 minutes later.
|
||||
|
||||
## Requirement: Pre-alarm notification
|
||||
The app MUST schedule a silent notification 30 minutes before each next alarm occurrence when notification permission is available.
|
||||
|
||||
### Scenario: skip next occurrence from notification
|
||||
Given a pre-alarm notification is visible
|
||||
When the user taps skip next occurrence
|
||||
Then the app MUST record a skip for that alarm occurrence
|
||||
And MUST not fire that specific occurrence
|
||||
And MUST preserve future recurring occurrences.
|
||||
|
||||
## Requirement: Vacation ranges
|
||||
The app MUST support global vacation ranges with start/end dates and per-alarm `soundOnVacation` flag defaulting to true.
|
||||
|
||||
### Scenario: alarm disabled for vacation date
|
||||
Given today is inside an enabled vacation range
|
||||
And an alarm has `soundOnVacation=false`
|
||||
When calculating next occurrence
|
||||
Then the app MUST skip occurrences inside that vacation range.
|
||||
|
||||
## Requirement: Audio fallback
|
||||
The app MUST never depend solely on an internet radio stream to ring.
|
||||
|
||||
### Scenario: selected station fails
|
||||
Given an alarm starts with a selected radio station
|
||||
When the stream fails or does not become ready before timeout
|
||||
Then the app MUST try a fallback station if configured
|
||||
And otherwise MUST play a bundled internal alarm sound.
|
||||
|
||||
## Requirement: Android reliability
|
||||
The app MUST use native Android scheduling for alarm occurrences and expose permission/diagnostic status.
|
||||
|
||||
### Scenario: exact alarm permission missing
|
||||
Given Android denies exact alarm scheduling
|
||||
When the user views alarm diagnostics
|
||||
Then the app MUST show that exact alarm permission is missing
|
||||
And MUST provide guidance to enable it.
|
||||
@@ -0,0 +1,6 @@
|
||||
change: alarm-clock-module
|
||||
status: planned
|
||||
artifact_store: hybrid
|
||||
created: 2026-05-21
|
||||
updated: 2026-05-21
|
||||
phase: tasks-ready
|
||||
@@ -0,0 +1,31 @@
|
||||
# Tasks: alarm-clock-module
|
||||
|
||||
## Phase 1: domain and tests
|
||||
- [ ] Add alarm domain models: alarm, vacation range, skip/exception, execution status.
|
||||
- [ ] Add recurrence calculator with tests for one-shot, weekdays, vacations, skip-next, snooze.
|
||||
- [ ] Add alarm persistence service with tests.
|
||||
|
||||
## Phase 2: Android scheduling bridge
|
||||
- [ ] Add MethodChannel scheduler interface in Flutter.
|
||||
- [ ] Add Kotlin scheduler using AlarmManager/setAlarmClock.
|
||||
- [ ] Add BroadcastReceiver for alarm firing and pre-alarm actions.
|
||||
- [ ] Add manifest permissions and receiver declarations.
|
||||
- [ ] Add diagnostics method for exact alarm permission.
|
||||
|
||||
## Phase 3: app state and UI
|
||||
- [ ] Add `EstadoAlarmas` or integrate alarm slice without bloating `EstadoRadio`.
|
||||
- [ ] Add alarms tab/entry point.
|
||||
- [ ] Add alarm list, editor, vacation ranges UI, and diagnostics panel.
|
||||
- [ ] Add ringing screen with stop/snooze 3/5/10.
|
||||
|
||||
## Phase 4: audio fallback
|
||||
- [ ] Add bundled internal alarm sounds under assets.
|
||||
- [ ] Implement fallback sequence with timeouts.
|
||||
- [ ] Add optional fallback station selection.
|
||||
- [ ] Add volume/fade-in behavior.
|
||||
|
||||
## Phase 5: verification
|
||||
- [ ] Run `dart format`.
|
||||
- [ ] Run `flutter analyze --no-fatal-infos`.
|
||||
- [ ] Run targeted tests if local runner does not hang.
|
||||
- [ ] Document Android limitations and permission flow.
|
||||
Reference in New Issue
Block a user