From: AIKeyboard AI Integration Date: Wed, 09 Apr 2025 00:00:00 +0000 Subject: [PATCH 2/3] Wire AI engine lifecycle into LatinIME - Declare AI component fields after existing field declarations - Initialize AiCorrectionEngine, AiSuggestionManager, AiTriggerHook in onCreate() - Clean up (cancel coroutines, close LlmInference) in onDestroy() - Expose getAiTriggerHook() accessor used by InputLogic patch --- .../keyboard/latin/LatinIME.java | 54 ++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/app/src/main/java/helium314/keyboard/latin/LatinIME.java b/app/src/main/java/helium314/keyboard/latin/LatinIME.java index xxxxxxx..xxxxxxx 100644 --- a/app/src/main/java/helium314/keyboard/latin/LatinIME.java +++ b/app/src/main/java/helium314/keyboard/latin/LatinIME.java @@ -133,6 +133,15 @@ public class LatinIME extends InputMethodService implements private RichInputMethodManager mRichImm; final KeyboardSwitcher mKeyboardSwitcher; + // ── AI spell correction components ────────────────────────────────────── + // Lazily initialised in onCreate(); destroyed in onDestroy(). + private helium314.keyboard.latin.ai.AiCorrectionEngine mAiCorrectionEngine; + private helium314.keyboard.latin.ai.AiSuggestionManager mAiSuggestionManager; + private helium314.keyboard.latin.ai.AiTriggerHook mAiTriggerHook; + // CoroutineScope type requires kotlin.coroutines on classpath (satisfied by + // kotlinx-coroutines-android dependency in app/build.gradle.kts). + private kotlinx.coroutines.CoroutineScope mAiScope; + // ──────────────────────────────────────────────────────────────────────── + private final SubtypeState mSubtypeState = new SubtypeState( (InputMethodSubtype subtype) -> { switchToSubtype(subtype); return Unit.INSTANCE; }); private final StatsUtilsManager mStatsUtilsManager; @@ -572,6 +581,21 @@ public class LatinIME extends InputMethodService implements registerReceiver(mRestartAfterDeviceUnlockReceiver, restartAfterUnlockFilter); StatsUtils.onCreate(mSettings.getCurrent(), mRichImm); + + // ── Initialise AI components ───────────────────────────────────────── + // AiSuggestionManager must be attached before AiTriggerHook is created + // so that the first correction result has somewhere to go. + mAiSuggestionManager = new helium314.keyboard.latin.ai.AiSuggestionManager(); + mAiSuggestionManager.attachAccessor(this); + mAiCorrectionEngine = new helium314.keyboard.latin.ai.AiCorrectionEngine(this); + // createImeScope() returns a SupervisorJob-backed CoroutineScope. + // Using @JvmStatic companion factory avoids complex Java↔Kotlin interop. + mAiScope = helium314.keyboard.latin.ai.AiSuggestionManager.createImeScope(); + mAiTriggerHook = new helium314.keyboard.latin.ai.AiTriggerHook( + mAiCorrectionEngine, + mAiSuggestionManager, + mAiScope + ); + // ──────────────────────────────────────────────────────────────────── } @@ -683,6 +697,22 @@ public class LatinIME extends InputMethodService implements @Override public void onDestroy() { mClipboardHistoryManager.onDestroy(); + + // ── Tear down AI components before releasing dictionaries ──────────── + if (mAiTriggerHook != null) { + mAiTriggerHook.cancel(); + } + if (mAiScope != null) { + // Cancel the coroutine scope to stop any in-flight correction jobs. + kotlinx.coroutines.JobKt.cancel( + (kotlinx.coroutines.Job) mAiScope.getCoroutineContext() + .get(kotlinx.coroutines.Job.Key), + null + ); + } + if (mAiCorrectionEngine != null) { + mAiCorrectionEngine.close(); + } + if (mAiSuggestionManager != null) { + mAiSuggestionManager.detachAccessor(); + } + // ──────────────────────────────────────────────────────────────────── + mDictionaryFacilitator.closeDictionaries(); mSettings.onDestroy(); unregisterReceiver(mRingerModeChangeReceiver); @@ -695,4 +725,14 @@ public class LatinIME extends InputMethodService implements mHandler.removeCallbacksAndMessages(null); deallocateMemory(); } + + // ── AI accessor ────────────────────────────────────────────────────────── + /** + * Returns the AiTriggerHook instance for use by InputLogic. + * Returns null if AI initialisation has not yet completed (race-safe). + */ + @androidx.annotation.Nullable + public helium314.keyboard.latin.ai.AiTriggerHook getAiTriggerHook() { + return mAiTriggerHook; + } + // ──────────────────────────────────────────────────────────────────────── }