Core IME Lifecycle
Relevant source files
The following files were used as context for generating this wiki page:
- app/src/main/kotlin/dev/patrickgold/florisboard/FlorisImeService.kt
- app/src/main/kotlin/dev/patrickgold/florisboard/ime/editor/AbstractEditorInstance.kt
- app/src/main/kotlin/dev/patrickgold/florisboard/ime/keyboard/KeyboardManager.kt
- app/src/main/kotlin/dev/patrickgold/florisboard/ime/nlp/NlpManager.kt
- app/src/main/kotlin/dev/patrickgold/florisboard/ime/editor/FlorisEditorInfo.kt
The Core IME Lifecycle in Ownkey Keyboard (derived from FlorisBoard) manages the transition states of the Input Method Editor (IME) from initialization to destruction. It orchestrates interactions between the Android system, the keyboard's internal managers (UI, NLP, Keyboard, and Editor), and the target application’s text fields. The lifecycle ensures that the keyboard appropriately responds to system events such as configuration changes, focus shifts, and user visibility requests.
The central component is FlorisImeService, which extends LifecycleInputMethodService. This service acts as the bridge between the Android IME framework and the keyboard's logic, managing instances of KeyboardManager, NlpManager, and AbstractEditorInstance to maintain a consistent state across different input sessions.
Sources: FlorisImeService.kt:56-65, FlorisImeService.kt:180-200
Service Initialization and Configuration
The lifecycle begins with onCreate(), where the service initializes global references, sets up window properties, and registers system-level listeners like the WallpaperChangeReceiver. A key aspect of initialization is the creation of a resourcesContext, which is dynamically updated based on system locales and user-defined keyboard subtypes to support localization.
Key Initialization Steps
- Weak Reference Setup: A global weak reference to the service is maintained to allow static access to core functions like
currentInputConnection()without leaking memory. - Window Management: Uses
WindowCompatto handle system window decorations andImeWindowControllerto manage window-specific configurations. - Locale Tracking: Collects system and subtype locales to create a specialized
ConfigurationContextfor localized resources.
Sources: FlorisImeService.kt:195-225, FlorisImeService.kt:66-70
The diagram illustrates the sequential initialization steps within the onCreate() method.
Input Session Lifecycle
An input session represents the keyboard's interaction with a specific text field. This is managed through two primary phases: Input Start and Input View Start.
Start Input Phase
When a text field gains focus, onStartInput is triggered. Ownkey Keyboard wraps the system EditorInfo into FlorisEditorInfo and passes it to the editorInstance. This phase prepares the backend logic for the specific constraints of the input field (e.g., email, password, or numeric).
Sources: FlorisImeService.kt:257-263, FlorisEditorInfo.kt:21-35
Start Input View Phase
onStartInputView occurs when the UI is about to be displayed. The KeyboardManager re-evaluates the input shift state (Caps Lock/Shift) and the editorInstance handles the initial selection update. This is where the actual keyboard layout is rendered based on the ImeUiMode.
Sources: FlorisImeService.kt:265-277, KeyboardManager.kt:191-201
Selection and Text Updates
As the user moves the cursor or types, onUpdateSelection keeps the internal EditorContent synchronized with the system's cursor position. The AbstractEditorInstance generates new EditorContent objects to track text before/after the cursor and the current composing region.
Sources: FlorisImeService.kt:285-300, AbstractEditorInstance.kt:151-180
| Function | Purpose | Triggered By |
|---|---|---|
onStartInput | Backend initialization for a text field | Field focus |
onStartInputView | UI layout and state initialization | Keyboard visibility/restart |
onUpdateSelection | Syncs internal text state with cursor | Cursor movement/Text change |
onFinishInputView | Cleans up UI-related states | Keyboard hiding |
onFinishInput | Ends the input session entirely | Field lose focus |
Sources: FlorisImeService.kt:257-315
View Creation and Customization
Ownkey Keyboard overrides standard Android IME view creation to provide a fully custom Compose-based UI.
- Input View:
onCreateInputViewreturnsnullbecause the UI is manually added to the window's content viaImeRootView. - Extract View: In landscape mode,
onCreateExtractTextViewhandles the creation of a specializedExtractedInputRootViewto facilitate full-screen typing. - Inline Suggestions: Supports Android 11+ (API 30) inline autofill suggestions by implementing
onCreateInlineSuggestionsRequestandonInlineSuggestionsResponse.
Sources: FlorisImeService.kt:227-250, FlorisImeService.kt:351-385
Sequence of events during the initialization of an input session.
Manager Orchestration
The FlorisImeService serves as the registry for several critical managers that follow the service's lifecycle:
- KeyboardManager: Manages layout computation, key event dispatching, and state evaluation (enabled/visible status of keys).
- NlpManager: Handles natural language processing, including suggestions (Emoji, Clipboard, and Dictionary-based) and spelling checks.
- ImeWindowController: Manages the physical keyboard window, including insets, offsets, and floating/fixed modes.
- AbstractEditorInstance: Tracks the state of the current text buffer and handles complex text manipulation like composers (e.g., Hangul/Kana rules).
Sources: FlorisImeService.kt:180-193, KeyboardManager.kt:66-100, NlpManager.kt:57-80
Service Termination
The lifecycle concludes in onDestroy(). The service unregisters the wallpaper receiver and clears the global weak reference to prevent memory leaks. The editorInstance is also reset to ensure no stale data remains from the last session.
Sources: FlorisImeService.kt:252-255, AbstractEditorInstance.kt:145-150
Summary
The Core IME Lifecycle in Ownkey Keyboard is a tightly coupled system where FlorisImeService coordinates between Android system callbacks and internal managers. By wrapping standard EditorInfo, tracking selection updates via AbstractEditorInstance, and managing layout state through KeyboardManager, the project provides a responsive and privacy-focused input experience that seamlessly integrates with the Android OS lifecycle.