Skip to content

Commit c5aff0d

Browse files
committed
fix: identity-check incognito-listener clear to survive overlapping IME teardown
KeyboardManager is a process singleton; FlorisImeService.onDestroy cleared its incognitoModeChangedListener unconditionally. During an overlapping service teardown/recreate (config change, theme switch, OOM rebind) the framework can run the new service's onCreate (which registers a fresh listener) before the old service's onDestroy, so the old clear() would null the live listener — leaving FLAG_SECURE un-reapplied on a runtime incognito toggle until the next input start. clearIncognitoModeChangedListener now only nulls the field when it still holds the caller's own listener reference.
1 parent 95f8029 commit c5aff0d

2 files changed

Lines changed: 11 additions & 3 deletions

File tree

app/src/main/kotlin/dev/patrickgold/florisboard/FlorisImeService.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -546,7 +546,7 @@ class FlorisImeService : LifecycleInputMethodService() {
546546
try { NlpInlineAutofill.clearInlineSuggestions() } catch (e: Exception) {
547547
flogWarning(LogTopic.IMS_EVENTS) { "NlpInlineAutofill.clearInlineSuggestions() failed: $e" }
548548
}
549-
keyboardManager.clearIncognitoModeChangedListener()
549+
keyboardManager.clearIncognitoModeChangedListener(flagSecureIncognitoModeChangedListener)
550550
FlorisImeServiceReference = WeakReference(null)
551551
super.onDestroy()
552552
}

app/src/main/kotlin/dev/patrickgold/florisboard/ime/keyboard/KeyboardManager.kt

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -253,8 +253,16 @@ class KeyboardManager(context: Context) : InputKeyEventReceiver {
253253
incognitoModeChangedListener = listener
254254
}
255255

256-
fun clearIncognitoModeChangedListener() {
257-
incognitoModeChangedListener = null
256+
fun clearIncognitoModeChangedListener(listener: ((Boolean) -> Unit)? = null) {
257+
// Identity-checked clear: KeyboardManager is a process singleton, so a
258+
// torn-down IME service must not wipe a listener that a newer service
259+
// instance already registered during an overlapping teardown/recreate
260+
// (config change, theme switch, OOM rebind). A null argument keeps the
261+
// legacy unconditional behaviour for any caller that does not track its
262+
// own listener reference.
263+
if (listener == null || incognitoModeChangedListener === listener) {
264+
incognitoModeChangedListener = null
265+
}
258266
}
259267

260268
fun reevaluateInputShiftState() {

0 commit comments

Comments
 (0)