ADFA-5404 | Recover from missing offline language packs - #95
Conversation
…A-5404) Recognize in the host's configured locale, and on error 12/13 retry once with an installed pack for the same language or online while fetching the missing pack, instead of failing the capture with "unknown error 12".
There was a problem hiding this comment.
Claude Code Review
This repository is configured for manual code reviews. Comment @claude review for a one-time review, or @claude review always to subscribe this PR to a review on every future push.
Tip: disable this comment in your organization's Code Review settings.
|
I posted on Slack about strings.xml review |
Teardown conflict resolved: deactivate() now calls teardown(), which releases the capture via endCapture() instead of destroyRecognizer().
Derive STALE_CAPTURE_MS from the generation timeout so the busy guard cannot expire first, and skip the just-failed tag when matching an installed language pack so the retry cannot repeat the same request.
…x/ADFA-5404-language-pack-error-handling
| // lists as installed for it is missing or corrupt and would fail the retry the same way. | ||
| val installed = usableTag(support.installedOnDeviceLanguages, locale, skipRequested = true) | ||
| if (installed != null) { | ||
| val fallback = Locale.forLanguageTag(installed) |
There was a problem hiding this comment.
F31 (Medium) — the recognizer's own tag spelling goes straight into Locale.forLanguageTag, so an underscore tag becomes und.
usableTag returns "the recognizer's own spelling of the tag" by contract, and normalizeTag exists precisely because "services spell tags inconsistently (es_ES, es-es)". That raw tag is then passed to Locale.forLanguageTag(installed), which treats _ as an ill-formed subtag and returns Locale.ROOT.
On a recognizer that reports installedOnDeviceLanguages = ["es_US"] for a failed es-ES:
fallbackisLocale.ROOT, sofallback.displayNameis the empty string and the toast reads "No offline pack for Spanish (Spain), so is being used instead — please speak now."recognitionIntentputsEXTRA_LANGUAGE = "und"in the intent (line 386), so the retry asks for an undetermined language and fails.languageFallbackSpentis alreadytrue, so the capture ends on an error that namesund, and the online retry that would have worked is never reached.
Normalize before constructing the locale:
val fallback = Locale.forLanguageTag(normalizeTag(installed))The same defect is on line 567, where requestLanguagePack(Locale.forLanguageTag(missing)) asks the recognizer to download a pack for und. Normalizing inside usableTag before it returns would fix both call sites at once — nothing downstream needs the service's original spelling.
Description
Replaces the generic "unknown error 12" with clear, actionable UI messages that display the specific missing Locale. Implements an automatic single online retry when an offline language pack is missing, ensuring the user's dictation session stays alive without being prematurely aborted.
Details
ERROR_LANGUAGE_UNAVAILABLEandERROR_LANGUAGE_NOT_SUPPORTEDinSpeechToTextPlugin.kt.preferOfflineand setEXTRA_LANGUAGEto support a single online retry attempt.strings.xmlto inform the user of the exact failing language and the fallback network attempt.index.htmldocumentation to reflect the new language pack recovery behavior.Prompt EN:
Function that reverses a stringPrompt ES:
Función que reversa un stringdocument_4976756881377724759.mp4
Ticket
ADFA-5404
Parent: ADFA-5402
Observation
The plugin now queries
checkRecognitionSupporton API 33+ devices to find regional fallback packs or trigger downloads, defaulting to a direct network retry on older SDKs.