Repository navigation
Fix a speech crash on a missing utterance id, and the braille keyboard characters echo - #104
thebetterfarhan wants to merge 2 commits into
Conversation
FailoverTextToSpeech.speak() reads the utterance id from the shared speech-parameters map and adds it to recentUtteranceIds, a ConcurrentLinkedDeque that rejects nulls. That map is a single field that processNextFragmentInternal clears and refills, and speech runs from both the handler thread and the low-latency audio callback pool, so a fragment could be spoken while the map was being rebuilt; the id then came back null and the deque threw NullPointerException on the speech thread (fyi.quin.backtalk, thread "LowLatencyAudio callbacks"). Build one parameters map per fragment, and guard addRecentUtteranceId against a null id, matching allowDeviceSleep and the failure path in speak(), which already tolerate a missing id.
In contracted braille the keyboard holds the whole word and commits it in one text event, so with the "characters" echo Backtalk echoed the committed word as added text as well, making "characters" sound the same as "characters and words". The keyboard already announces each character itself whenever the echo includes characters. Report "none" to Backtalk for the on-screen braille keyboard when the echo is "characters" and contracted mode is on, leaving the keyboard's own character announcements as the echo. Uncontracted typing commits a character at a time and relies on Backtalk's echo, so it is unchanged.
|
The two changes are unrelated to each other and should be separate PRs, so each can be reviewed and merged on its own. Braille keyboard "characters" echo The fix is correct. In contracted braille the keyboard commits the whole word in one go and already announces each character itself whenever the echo includes characters, so Backtalk's echo of the committed text made "characters" sound like "characters and words". Reporting "none" to Backtalk in that one case fixes it without touching uncontracted typing or the other echo settings. Side effect: while the braille keyboard reports "none", Backtalk speaks no text added to the field at all, not just the committed word. This includes, for example, an app filling in a suggestion while the braille keyboard is up. Also check on a device that committing a word with space still gives feedback in contracted mode. Crash on a missing utterance id The cause is right, but the race is wider than the params map. The whole speech queue was used from more than one thread: |
|
sorry about that. I thought maybe bundling them together would save time. I will try and recreate these in seperated pr's tomorrow. |
|
It looks like Aaron already did the speech ID bug, so you can just update this pr for the braille stuff. For what its worth, I do not mind prs with a couple things in them, |
* Finish each utterance on the main thread 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 (#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. * Clear the queues and say "Screen off" on the main thread 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.
Two fixes from a log review of today's debug build.
Fix a crash when speech has no utterance id
FailoverTextToSpeech.speak()adds the utterance id torecentUtteranceIds, aConcurrentLinkedDequethat rejects nulls, and the id came from a shared speech-parameters map thatprocessNextFragmentInternalclears and refills while speech also runs on the low-latency audio callback thread. A fragment spoken during a rebuild got a null id and threwNullPointerExceptionon the speech thread. Now each fragment builds its own map, andaddRecentUtteranceIdignores a null id (asallowDeviceSleepand the failure path inspeak()already do).Stop the braille keyboard speaking whole words with the characters echo
In contracted braille the keyboard holds the whole word and commits it in one text event, so with the "characters" echo Backtalk echoed the finished word as added text too, making "characters" sound the same as "characters and words". The keyboard already announces each character itself whenever the echo includes characters, so with "characters" and contracted mode on it now reports "none" to Backtalk and leaves those announcements as the echo. Uncontracted typing commits a character at a time and still uses Backtalk's echo, so it is unchanged.