Skip to content

ADFA-5404 | Recover from missing offline language packs - #95

Open
jatezzz wants to merge 4 commits into
fix/ADFA-5403-resolve-llm-from-shared-servicesfrom
fix/ADFA-5404-language-pack-error-handling
Open

ADFA-5404 | Recover from missing offline language packs#95
jatezzz wants to merge 4 commits into
fix/ADFA-5403-resolve-llm-from-shared-servicesfrom
fix/ADFA-5404-language-pack-error-handling

Conversation

@jatezzz

@jatezzz jatezzz commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

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

  • Handled ERROR_LANGUAGE_UNAVAILABLE and ERROR_LANGUAGE_NOT_SUPPORTED in SpeechToTextPlugin.kt.
  • Parameterized preferOffline and set EXTRA_LANGUAGE to support a single online retry attempt.
  • Added detailed UI toasts in strings.xml to inform the user of the exact failing language and the fallback network attempt.
  • Updated index.html documentation to reflect the new language pack recovery behavior.

Prompt EN: Function that reverses a string
Prompt ES: Función que reversa un string

document_4976756881377724759.mp4

Ticket

ADFA-5404
Parent: ADFA-5402

Observation

The plugin now queries checkRecognitionSupport on API 33+ devices to find regional fallback packs or trigger downloads, defaulting to a direct network retry on older SDKs.

…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".

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@hal-eisen-adfa

Copy link
Copy Markdown
Contributor

I posted on Slack about strings.xml review

@hal-eisen-adfa hal-eisen-adfa left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated review (Claude Code, high). The branch compiles clean and every new API symbol resolves in libs/plugin-api.jar; the new %1$s/%2$s positions match their str() call sites. Two findings below.

Not device-verified — build only.

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.
// 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)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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:

  • fallback is Locale.ROOT, so fallback.displayName is the empty string and the toast reads "No offline pack for Spanish (Spain), so is being used instead — please speak now."
  • recognitionIntent puts EXTRA_LANGUAGE = "und" in the intent (line 386), so the retry asks for an undetermined language and fails.
  • languageFallbackSpent is already true, so the capture ends on an error that names und, 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants