Skip to content

fix(clipboard): null-safe keyboard icon access and input-view race guard in suggestion callbacks - #434

Open
Lloyd-Jackman-UKPL wants to merge 1 commit into
LeanBitLab:mainfrom
Lloyd-Jackman-UKPL:fix/clipboard-suggestion-npe
Open

fix(clipboard): null-safe keyboard icon access and input-view race guard in suggestion callbacks#434
Lloyd-Jackman-UKPL wants to merge 1 commit into
LeanBitLab:mainfrom
Lloyd-Jackman-UKPL:fix/clipboard-suggestion-npe

Conversation

@Lloyd-Jackman-UKPL

Copy link
Copy Markdown

Bug Description

The IME process dies when a screenshot lands while the keyboard view does not exist. Observed three times in one day on a Pixel-era Samsung (S24+, Android 16) running the debug build:

java.lang.NullPointerException: Attempt to read from field
'helium314.keyboard.keyboard.internal.KeyboardIconsSet helium314.keyboard.keyboard.Keyboard.mIconsSet'
on a null object reference in method
'android.view.View helium314.keyboard.latin.ClipboardHistoryManager.getScreenshotSuggestionView(android.view.ViewGroup)'
  at ClipboardHistoryManager.getScreenshotSuggestionView(ClipboardHistoryManager.kt:659)
  at ClipboardHistoryManager.getClipboardSuggestionView(ClipboardHistoryManager.kt:526)
  at LatinIME.tryShowClipboardSuggestion(LatinIME.java:2038)
  at ClipboardHistoryManager$registerScreenshotObserver$1.onChange$lambda$0(ClipboardHistoryManager.kt:86)

The MediaStore ContentObserver fires as soon as any screenshot appears system-wide, even while the IME service is idle with no input view inflated.

Root Cause

Two independent problems combine:

  1. getScreenshotSuggestionView() / getClipboardSuggestionView() read latinIME.mKeyboardSwitcher.keyboard.mIconsSet unguarded. mKeyboardSwitcher.keyboard is null whenever no keyboard view is currently built, so any callback racing view construction/teardown NPEs on the main thread.
  2. The screenshot observer's onChange calls updateLatestScreenshotCache { latinIME.tryShowClipboardSuggestion() } without checking that an input view exists, guaranteeing that race is reachable in normal use.

Fix

  • New private helper activeKeyboardIcons(): null-safe access to the active keyboard's icon set (KeyboardIconsSet?). All four icon call sites now degrade gracefully - the suggestion renders icon-less instead of crashing.
  • Screenshot observer skips tryShowClipboardSuggestion() while isInputViewShown is false. Nothing is lost: the next input-view show re-runs clipboard/screenshot suggestion logic through the normal path.

No behaviour change when the keyboard view exists (the overwhelmingly common case) - icons resolve exactly as before.

How to Verify

  1. Build and install, enable "Suggest screenshots".
  2. With the keyboard dismissed, take a screenshot from another app (e.g. via quick settings while no editable field is focused).
  3. Before this PR: IME process crashes (FATAL EXCEPTION: main, NPE at getScreenshotSuggestionView). After: no crash; opening an editable field still shows the screenshot suggestion normally.
  4. Regression check: keyboard visible + take a screenshot -> suggestion strip shows the screenshot chip with paste/close icons as usual.

Test Plan

  • No new unit test (crash path involves Android view lifecycle; verified manually on device)
  • :app:compileStandardDebugKotlin passes on the PR branch
  • Manual verification on device (Samsung Galaxy S24+, Android 16) - previously-crashing sequence now clean

Risk Assessment

Low - strictly defensive changes: null-guards that fall back to not drawing two toolbar icons in a transient state, plus skipping a speculative UI refresh that the next input-show repeats anyway. No change to commit paths, gesture handling, or prediction.

…ard in suggestion callbacks

A screenshot arriving while the keyboard view is torn down crashes the
IME: ClipboardHistoryManager.getScreenshotSuggestionView() reads
Keyboard.mIconsSet through mKeyboardSwitcher.keyboard without a null
check, throwing
'NullPointerException: ... Keyboard.mIconsSet on a null object reference'
from the MediaStore ContentObserver callback.

- add activeKeyboardIcons(): null-safe accessor for the active keyboard's
  icon set; all four icon call sites degrade to icon-less suggestions
  instead of crashing when no keyboard view exists
- skip tryShowClipboardSuggestion() from the screenshot observer while
  the input view is not shown; the next input show surfaces it anyway
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