diff --git a/app/src/main/java/de/jeanlucmakiola/clockula/ui/settings/SettingsScreen.kt b/app/src/main/java/de/jeanlucmakiola/clockula/ui/settings/SettingsScreen.kt index eaeda0d..9ed7680 100644 --- a/app/src/main/java/de/jeanlucmakiola/clockula/ui/settings/SettingsScreen.kt +++ b/app/src/main/java/de/jeanlucmakiola/clockula/ui/settings/SettingsScreen.kt @@ -385,5 +385,6 @@ private fun selfCheckSummary(problemCount: Int?): String = when { internal fun ringtoneSummary(uri: String?): String = when { uri == null -> stringResource(R.string.ringtone_device_default) Ringtones.isSilent(uri) -> stringResource(R.string.ringtone_silent) + Ringtones.isBundled(uri) -> stringResource(R.string.ringtone_timer_expired) else -> stringResource(R.string.settings_ringtone_custom) } diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index 192ed48..294e9b0 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -106,7 +106,7 @@ kit module: the kit's roadmap keeps schedulers app-local. | `data/zones/` | the ICU seam (M8): `ZoneNames`, `IcuZoneNames` (the only `android.icu` file in the app) and `ZoneDirectory`, the locale-keyed catalog cache and the DST-keyed display-name memo | | `data/stopwatch/` | `LapEntity`, `LapDao` (one `COUNT(*)` added in M7), `LapMapper`, `StopwatchStateStore`, `StopwatchRepository(+Impl)` | | `data/prefs/` | `SettingsPrefs`, `ClockPrefs`, `StopwatchPrefs`, `TimerPrefs`, `UiPrefs` | -| `data/ringtones/` | the two ringtone seams, `RingtoneCatalog` (the device's alarm sounds, titles, playability, a SAF grant) and `RingtonePreviewer`, plus their `System*` implementations, and `MediaLibrary`/`SystemMediaLibrary`, the picker's view of other apps' `MediaBrowserService` libraries | +| `data/ringtones/` | the two ringtone seams, `RingtoneCatalog` (the bundled and device alarm sounds, titles, playability, a SAF grant) and `RingtonePreviewer`, plus their `System*` implementations, and `MediaLibrary`/`SystemMediaLibrary`, the picker's view of other apps' `MediaBrowserService` libraries | | `data/time/` | `SystemWallClock`, `SystemElapsedRealtimeClock`, `SystemZoneProvider`, `AndroidBootIdProvider`, `RealTicker` | | `data/di/` | `DataModule`, `DatabaseModule`, `RepositoryModule`, `TimeModule`, `RingtoneModule`, `ZoneModule` (M8; one `@Binds`, `ZoneNames → IcuZoneNames`), `BackupModule` (M10) | | `data/backup/` | the backup's data-layer half (M10): `BackupDto`/`BackupCodec` (the pure JSON wire format, `ignoreUnknownKeys`, strict on known fields), `BackupDao` (one `@Transaction` replace-all over alarms/timers/world clocks; no schema or version change), `BackupRepository(+Impl)`, mapping through the existing `AlarmMapper`/`TimerMapper`/`WorldClockMapper`, never a second copy | @@ -167,7 +167,7 @@ JSON and M10's JSON backup all read the same vocabulary in a diff. | `enabled` | INTEGER | indexed; `enabled()` filters on it | | `repeat_days` | INTEGER | 7-bit mask, see below | | `skip_next_occurrence` | INTEGER | | -| `ringtone_uri`, `vibrate`, `snooze_minutes`, `snooze_limit`, `volume_ramp_seconds`, `dismiss_challenge` | nullable | **overrides**; `NULL` = inherit `ClockDefaults`. For `ringtone_uri`: `NULL` = inherit, `clockula://silent` = deliberate silence (§13), `clockula://tone/…` = a sound bundled in the APK (resolved by `BundledTones`, never `Uri.parse`d directly), anything else a content URI | +| `ringtone_uri`, `vibrate`, `snooze_minutes`, `snooze_limit`, `volume_ramp_seconds`, `dismiss_challenge` | nullable | **overrides**; `NULL` = inherit `ClockDefaults`. For `ringtone_uri`: `NULL` = inherit, `clockula://silent` = deliberate silence (§13), `clockula://tone/timer_expired` = the sound bundled in the APK (resolved by `BundledTones`, never `Uri.parse`d directly), `clockula://media?…` = another app's track (§13), anything else a content URI | | `delete_after_use` | INTEGER | v3 (M9): a transient alarm the `AlarmClock` contract asked for. Deleted rather than disabled when its cycle closes (§17) | | `created_at`, `updated_at` | INTEGER | wall-clock epoch millis | @@ -270,7 +270,7 @@ occurrence, so skipping it is dismissing it in advance. | `started_at_elapsed_realtime_millis` | INTEGER? | `RUNNING` only | | `ends_at_elapsed_realtime_millis` | INTEGER? | `RUNNING` only; **authoritative** | | `ends_at_wall_clock_millis` | INTEGER? | `RUNNING` only; **post-reboot fallback only** | -| `ringtone_uri` | TEXT? | `NULL` = inherit `ClockDefaults.timerRingtoneUri` | +| `ringtone_uri` | TEXT? | `NULL` = inherit `ClockDefaults.timerRingtoneUri`; otherwise the same values as the alarm's `ringtone_uri` | | `sort_order` | INTEGER | indexed | | `delete_after_use` | INTEGER | v3 (M9): a transient timer the contract asked for. Deleted rather than returned to IDLE when it is dismissed (§17) | | `created_at`, `updated_at` | INTEGER | wall-clock epoch millis |