Bound audio lifecycle failures and isolate playback ownership - #2
Merged
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Leaving a review or switching audio sources could let an old native completion change a newer request's state. A native call that never returned could also hold the audio queue indefinitely. The service now captures ownership separately from the UI indicator, gives each media utterance a fresh player, and bounds each native call to eight seconds.
An ambiguous timeout disables audio for the application session and immediately attempts to stop the captured source. Late results remain observed and can trigger additional cleanup, but cannot restore playback. The review displays an accessible text notice while answers and progress continue to work. Unused native position polling is disabled in production; the test factory keeps the real player's default behavior so this path is covered.
The lifecycle tests drive the actual TTSService and AudioPlayer wrapper with controlled per-player events and the FlutterTts method channel. Coverage includes cross-backend callbacks, retired players, page cancellation, failed handoff, hung configuration/source/resume/stop/dispose calls, late errors, and queued callers. Documentation describes the plugins' lack of system utterance IDs and the difference between a stop acknowledgement and actual silence. The eight-second deadline is per call, not a total shutdown guarantee.
Version 0.1.2+3. Local Flutter 3.44.0 analysis and all 119 tests passed, including 26 native lifecycle tests. CI will validate both supported Flutter versions and produce a development/debug Android artifact. Physical-device behavior and store signing are not established by these host tests.