Repository navigation
Conversation
When the speech engine, or low-latency audio, reported that an utterance had finished, the speech controller handled it on the thread that reported it: the engine's callback thread or the low-latency audio callback thread. Handling it starts the next fragment, so the speech queue and its reused speech parameters were used from that thread while the main thread could be starting new speech with them. Speech could then go to the engine with another fragment's parameters, or with no utterance id, which crashed (trypsynth#104). The end of an utterance is now handed to the main thread, as its start and its word ranges already were. When Backtalk turns off, the main thread waits for the last announcement, so callbacks are still handled on the engine's thread then, as before.
When the screen turned off, Backtalk worked out what to say on a background thread, as TalkBack does, but it also cleared the speech and event queues and spoke "Screen off" or the ringer state from there. That used the speech queue and its reused speech parameters while the main thread could be using them too. The announcement is still worked out on the background thread, and the queues are now cleared and it is spoken on the main thread. If the screen has come back on by then, neither happens.
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.
The speech queue in
SpeechControllerImpl, including the speech parameters map it reuses for every fragment, was used from more than one thread at a time. This was already the case in TalkBack:UtteranceProgressCallback.onDone,onStopandonErrorcalledhandleUtteranceCompleteddirectly. That runs on the engine's callback thread, or the low-latency audio callback thread, and goes on toonFragmentCompletedandprocessNextFragmentInternal(), which starts the next fragment. The start of an utterance and its word ranges were already handed to the main thread throughSpeechHandler. Now the end is too.RingerModeAndScreenMonitorworks out "Screen off" and the ringer state on a background thread, but it also calledservice.clearQueues()and spoke from there. The announcement is still worked out in the background. The speech and event queues are now cleared, and it is spoken, on the main thread. If the screen has come back on by then, neither happens.Meanwhile the main thread could be starting new speech with the same queue and map. Speech could then reach the engine with another fragment's parameters or with no utterance id, which is the crash in #104.
When Backtalk turns off, the main thread waits for the last announcement, so speech callbacks are still handled on the engine's thread then, as before.