forked from akai/readest
ab628fe258
* fix(android): keep background TTS media controls alive when backgrounded The media-session update commands pushed metadata and playback state to MediaPlaybackService via Context.startService(), which Android 8+ rejects with "app is in background" once the app leaves the foreground. Every per-sentence update then failed, so the lock-screen control went stale and the foreground service lost the notification refresh that keeps it alive, dropping background playback. Deliver updates to the running service in-process (the pattern the existing requestDeactivation() already uses) so they can never trigger a service start. Also request POST_NOTIFICATIONS whenever the session activates, not only when alwaysInForeground is set, so the foreground-service media notification (the lock-screen control) is not suppressed on Android 13+. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * feat(android): show section duration and enable seek on the TTS media session The Edge/WebAudio TTS engine already reports an estimated section timeline (position and duration) to the media session on every sentence, but the Android service never surfaced it: the lock screen had no scrubber and no seek. Set METADATA_KEY_DURATION so the scrubber shows its length, add ACTION_SEEK_TO, and handle onSeekTo by handing the target back to the JS controller (seekToTime) through the existing media-session-seek event. Playback-state updates that only flip play/pause omit position and duration, so the service now preserves the last known values instead of resetting the scrubber to 0. Native TextToSpeech has no timeline (duration stays 0), so the scrubber simply does not appear there. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(android): harden TTS foreground-service promotion + add diagnostics On MIUI the media service was reclaimed on idle ("Stopping service due to app idle"), which means startForeground never promoted it to a real foreground service. Promote with ServiceCompat and an explicit FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK type (robust on targetSdk 34+) and log any failure instead of swallowing it. Decouple the POST_NOTIFICATIONS request from the service start in setActive: a throwing or hung permission request no longer aborts set_media_session_active, so the foreground service always starts. Add trace logging (set_media_session_active, activateSession, startForeground) to pinpoint the promotion path on-device. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(android): drop required keepAppInForeground so the TTS service starts The set_media_session_active payload required keep_app_in_foreground, but the media bridge activates with just { active: true }. Tauri rejected the invoke at the serde layer ("missing field keepAppInForeground") before the command ran, so the foreground service never started: no media notification, and Android 15 audio hardening then muted background playback. The flag was dead everywhere: no platform read it (the foreground service always starts and the POST_NOTIFICATIONS request is now unconditional). Remove it from the Rust, Kotlin, iOS, and TS payloads. Effective behavior is always-foreground. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(tts): fade sentence-buffer edges to stop Edge TTS clicks The silence trim (findSpeechBounds) cuts at an amplitude threshold, not a zero crossing, so each Edge TTS sentence buffer begins and ends on a non-zero sample. An AudioBufferSourceNode steps straight from/to silence at its edges, and that discontinuity clicks/pops between sentences (WSOLA is not involved: it is a no-op at rate 1.0 and cross-fades its internal splices). Apply a ~3ms linear fade to each buffer's own copy after WSOLA so the edges ramp to zero. The trim and the controlled inter-sentence gap are unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * chore(android): remove the dead "Background Read Aloud" setting alwaysInForeground only drove the removed keepAppInForeground flag; nothing reads it now (the foreground service always starts, and POST_NOTIFICATIONS is requested at play time). Remove the setting, its default, the Android library-menu toggle (which just requested the notification permission), and prune the now-unused i18n key from all locales. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>