From 9afcf8f2b0b04eec7c7fc7d9d1bcf4679166f336 Mon Sep 17 00:00:00 2001 From: Darcy Wong Date: Tue, 18 Mar 2025 15:32:23 +0700 Subject: [PATCH 1/7] fix(android): Restore banner after lock screen Fix banner transitions on lock screen and resuming --- .../com/keyman/android/SystemKeyboard.java | 2 ++ .../com/tavultesoft/kmapro/MainActivity.java | 21 +++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/android/KMAPro/kMAPro/src/main/java/com/keyman/android/SystemKeyboard.java b/android/KMAPro/kMAPro/src/main/java/com/keyman/android/SystemKeyboard.java index d1965f41b4..8b7e93956c 100644 --- a/android/KMAPro/kMAPro/src/main/java/com/keyman/android/SystemKeyboard.java +++ b/android/KMAPro/kMAPro/src/main/java/com/keyman/android/SystemKeyboard.java @@ -162,6 +162,8 @@ public class SystemKeyboard extends InputMethodService implements OnKeyboardEven KMManager.setMayPredictOverride(inputType); if (KMManager.getMayPredictOverride()) { KMManager.setBannerOptions(false); + // Set the system keyboard HTML banner + BannerController.setHTMLBanner(this, KeyboardType.KEYBOARD_TYPE_SYSTEM); } else if (KMManager.isKeyboardLoaded(KeyboardType.KEYBOARD_TYPE_SYSTEM)){ // Check if predictions needs to be re-enabled per Settings preference Keyboard kbInfo = KMManager.getCurrentKeyboardInfo(appContext); diff --git a/android/KMAPro/kMAPro/src/main/java/com/tavultesoft/kmapro/MainActivity.java b/android/KMAPro/kMAPro/src/main/java/com/tavultesoft/kmapro/MainActivity.java index f5a3c63cb9..23e69aab64 100644 --- a/android/KMAPro/kMAPro/src/main/java/com/tavultesoft/kmapro/MainActivity.java +++ b/android/KMAPro/kMAPro/src/main/java/com/tavultesoft/kmapro/MainActivity.java @@ -247,6 +247,27 @@ public class MainActivity extends BaseActivity implements OnKeyboardEventListene KMManager.onResume(); KMManager.hideSystemKeyboard(); + if (textView != null) { + // Reset mayPredictOverride + KMManager.setMayPredictOverride(textView.getInputType()); + } + + if (KMManager.getKMKeyboard(KeyboardType.KEYBOARD_TYPE_INAPP) != null) { + // Reset banner + Keyboard kbInfo = KMManager.getCurrentKeyboardInfo(context); + if (kbInfo != null) { + String langId = kbInfo.getLanguageID(); + HashMap currentLexicalModel = KMManager.getAssociatedLexicalModel(langId); + if (currentLexicalModel != null) { + SharedPreferences prefs = context.getSharedPreferences(context.getString(com.keyman.engine.R.string.kma_prefs_name), Context.MODE_PRIVATE); + boolean modelPredictionPref = prefs.getInt(KMManager.getLanguageAutoCorrectionPreferenceKey( + currentLexicalModel.get(KMManager.KMKey_LanguageID)), KMManager.KMDefault_Suggestion) + != KMManager.SuggestionType.SUGGESTIONS_DISABLED.toInt(); + KMManager.setBannerOptions(modelPredictionPref); + } + } + } + // Reset keyboard picker Activity Task flag KMManager.closeParentAppOnShowKeyboardPicker(); From 1da411727a0d6497ec2fd0463fdf28f651e8c612 Mon Sep 17 00:00:00 2001 From: Darcy Wong Date: Thu, 20 Mar 2025 08:50:22 +0700 Subject: [PATCH 2/7] refactor(android): split mayPredictOverride for inapp and system kbd Refactor mayPredictOverride so the banner toggle is handled independently for `KeyboardType.KEYBOARD_TYPE_INAPP` and `KeyboardType.KEYBOARD_TYPE_SYSTEM` keyboards. Pre-existing override API calls are now for `KeyboardType.KEYBOARD_TYPE_SYSTEM` --- .../com/keyman/android/SystemKeyboard.java | 4 +- .../com/tavultesoft/kmapro/MainActivity.java | 21 +---- .../engine/KMKeyboardWebViewClient.java | 4 +- .../java/com/keyman/engine/KMManager.java | 91 ++++++++++++++++--- 4 files changed, 86 insertions(+), 34 deletions(-) diff --git a/android/KMAPro/kMAPro/src/main/java/com/keyman/android/SystemKeyboard.java b/android/KMAPro/kMAPro/src/main/java/com/keyman/android/SystemKeyboard.java index 8b7e93956c..c0fe1e9e1e 100644 --- a/android/KMAPro/kMAPro/src/main/java/com/keyman/android/SystemKeyboard.java +++ b/android/KMAPro/kMAPro/src/main/java/com/keyman/android/SystemKeyboard.java @@ -159,8 +159,8 @@ public class SystemKeyboard extends InputMethodService implements OnKeyboardEven Context appContext = getApplicationContext(); // Temporarily disable predictions on certain fields (e.g. hidden password field or numeric) inputType = attribute.inputType; - KMManager.setMayPredictOverride(inputType); - if (KMManager.getMayPredictOverride()) { + KMManager.setMayPredictOverride(inputType, KeyboardType.KEYBOARD_TYPE_SYSTEM); + if (KMManager.getMayPredictOverride(KeyboardType.KEYBOARD_TYPE_SYSTEM)) { KMManager.setBannerOptions(false); // Set the system keyboard HTML banner BannerController.setHTMLBanner(this, KeyboardType.KEYBOARD_TYPE_SYSTEM); diff --git a/android/KMAPro/kMAPro/src/main/java/com/tavultesoft/kmapro/MainActivity.java b/android/KMAPro/kMAPro/src/main/java/com/tavultesoft/kmapro/MainActivity.java index 23e69aab64..b9349a8769 100644 --- a/android/KMAPro/kMAPro/src/main/java/com/tavultesoft/kmapro/MainActivity.java +++ b/android/KMAPro/kMAPro/src/main/java/com/tavultesoft/kmapro/MainActivity.java @@ -244,29 +244,14 @@ public class MainActivity extends BaseActivity implements OnKeyboardEventListene @Override protected void onResume() { super.onResume(); - KMManager.onResume(); - KMManager.hideSystemKeyboard(); if (textView != null) { // Reset mayPredictOverride - KMManager.setMayPredictOverride(textView.getInputType()); + KMManager.setMayPredictOverride(textView.getInputType(), KeyboardType.KEYBOARD_TYPE_INAPP); } - if (KMManager.getKMKeyboard(KeyboardType.KEYBOARD_TYPE_INAPP) != null) { - // Reset banner - Keyboard kbInfo = KMManager.getCurrentKeyboardInfo(context); - if (kbInfo != null) { - String langId = kbInfo.getLanguageID(); - HashMap currentLexicalModel = KMManager.getAssociatedLexicalModel(langId); - if (currentLexicalModel != null) { - SharedPreferences prefs = context.getSharedPreferences(context.getString(com.keyman.engine.R.string.kma_prefs_name), Context.MODE_PRIVATE); - boolean modelPredictionPref = prefs.getInt(KMManager.getLanguageAutoCorrectionPreferenceKey( - currentLexicalModel.get(KMManager.KMKey_LanguageID)), KMManager.KMDefault_Suggestion) - != KMManager.SuggestionType.SUGGESTIONS_DISABLED.toInt(); - KMManager.setBannerOptions(modelPredictionPref); - } - } - } + KMManager.onResume(); + KMManager.hideSystemKeyboard(); // Reset keyboard picker Activity Task flag KMManager.closeParentAppOnShowKeyboardPicker(); diff --git a/android/KMEA/app/src/main/java/com/keyman/engine/KMKeyboardWebViewClient.java b/android/KMEA/app/src/main/java/com/keyman/engine/KMKeyboardWebViewClient.java index 5ce294909c..65b5003a90 100644 --- a/android/KMEA/app/src/main/java/com/keyman/engine/KMKeyboardWebViewClient.java +++ b/android/KMEA/app/src/main/java/com/keyman/engine/KMKeyboardWebViewClient.java @@ -165,12 +165,12 @@ public final class KMKeyboardWebViewClient extends WebViewClient { // appContext instead of context? SharedPreferences prefs = context.getSharedPreferences(context.getString(R.string.kma_prefs_name), Context.MODE_PRIVATE); boolean modelPredictionPref = false; - if (!KMManager.getMayPredictOverride() && KMManager.currentLexicalModel != null) { + if (!KMManager.getMayPredictOverride(keyboardType) && KMManager.currentLexicalModel != null) { modelPredictionPref = prefs.getInt(KMManager.getLanguageAutoCorrectionPreferenceKey( KMManager.currentLexicalModel.get(KMManager.KMKey_LanguageID)), KMManager.KMDefault_Suggestion) != SuggestionType.SUGGESTIONS_DISABLED.toInt(); } - KMManager.setBannerOptions(modelPredictionPref); + KMManager.setBannerOptions(modelPredictionPref, keyboardType); RelativeLayout.LayoutParams params = KMManager.getKeyboardLayoutParams(); kmKeyboard.setLayoutParams(params); } else if (url.indexOf("suggestPopup") >= 0) { diff --git a/android/KMEA/app/src/main/java/com/keyman/engine/KMManager.java b/android/KMEA/app/src/main/java/com/keyman/engine/KMManager.java index 39fba8db8b..544c321c64 100644 --- a/android/KMEA/app/src/main/java/com/keyman/engine/KMManager.java +++ b/android/KMEA/app/src/main/java/com/keyman/engine/KMManager.java @@ -257,10 +257,11 @@ public final class KMManager { // haptic feedback disabled for hardware keystrokes private static boolean mayHaveHapticFeedback = false; - // Special override for when keyboard is entering a password text field. + // Special overrides for when the inapp/system keyboards are entering a password text field. // When mayPredictOverride is true, the option {'mayPredict' = false} is set in the lm-layer // regardless what the Settings preference is. - private static boolean mayPredictOverride = false; + private static boolean inAppMayPredictOverride = false; + private static boolean systemMayPredictOverride = false; // Determine how system keyboard handles ENTER key public static EnterModeType enterMode = EnterModeType.DEFAULT; @@ -1409,25 +1410,67 @@ public final class KMManager { } /** - * Sets mayPredictOverride true if the InputType field is a hidden password text field + * Determine the override if the InputType field is a hidden password text field + * but not TYPE_TEXT_VARIATION_VISIBLE_PASSWORD) + * Also true for numeric text fields + * @param inputType android.text.InputType + * @return boolean + */ + private static boolean determinePredictOverride(int inputType) { + return ((inputType == (InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD)) || + (inputType == (InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_WEB_PASSWORD)) || + isNumericField(inputType)); + } + + /** + * This API call existed prior to 18.0. Preferred call specifies the KeyboardType. + * Sets systemMayPredictOverride true if the InputType field for system keyboard is a hidden password text field * (either TYPE_TEXT_VARIATION_PASSWORD or TYPE_TEXT_VARIATION_WEB_PASSWORD * but not TYPE_TEXT_VARIATION_VISIBLE_PASSWORD) * Also true for numeric text fields * @param inputType android.text.InputType */ public static void setMayPredictOverride(int inputType) { - mayPredictOverride = - ((inputType == (InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD)) || - (inputType == (InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_WEB_PASSWORD)) || - isNumericField(inputType)); + systemMayPredictOverride = determinePredictOverride(inputType); } /** - * Get the value of mayPredictOverride + * Sets mayPredictOverride true if the InputType field for the keyboard is a hidden password text field + * (either TYPE_TEXT_VARIATION_PASSWORD or TYPE_TEXT_VARIATION_WEB_PASSWORD + * but not TYPE_TEXT_VARIATION_VISIBLE_PASSWORD) + * Also true for numeric text fields + * @param inputType android.text.InputType + * @param {KeyboardType} keyboard + */ + public static void setMayPredictOverride(int inputType, KeyboardType keyboard) { + if (keyboard == KeyboardType.KEYBOARD_TYPE_INAPP) { + inAppMayPredictOverride = determinePredictOverride(inputType); + } else if (keyboard == KeyboardType.KEYBOARD_TYPE_SYSTEM) { + systemMayPredictOverride = determinePredictOverride(inputType); + } + } + + /** + * This API call existed prior to 18.0. Preferred call specifies the KeyboardType. + * Get the value of systemMayPredictOverride * @return boolean */ public static boolean getMayPredictOverride() { - return mayPredictOverride; + return systemMayPredictOverride; + } + + /** + * Get the value of mayPredictOverride based on KeyboardType + * @param {KeyboardType} keyboard + * @return boolean + */ + public static boolean getMayPredictOverride(KeyboardType keyboard) { + if (keyboard == KeyboardType.KEYBOARD_TYPE_INAPP) { + return inAppMayPredictOverride; + } else if (keyboard == KeyboardType.KEYBOARD_TYPE_SYSTEM) { + return systemMayPredictOverride; + } + return false; } /** @@ -1556,20 +1599,23 @@ public final class KMManager { // When entering password field, maySuggest should override to disabled SharedPreferences prefs = appContext.getSharedPreferences(appContext.getString(R.string.kma_prefs_name), Context.MODE_PRIVATE); - int maySuggest = mayPredictOverride ? SuggestionType.SUGGESTIONS_DISABLED.toInt() : - prefs.getInt(getLanguageAutoCorrectionPreferenceKey(languageID), KMDefault_Suggestion); + int suggestionPreference = prefs.getInt(getLanguageAutoCorrectionPreferenceKey(languageID), KMDefault_Suggestion); RelativeLayout.LayoutParams params; if (isKeyboardLoaded(KeyboardType.KEYBOARD_TYPE_INAPP) && !InAppKeyboard.shouldIgnoreTextChange() && modelFileExists) { params = getKeyboardLayoutParams(); // Do NOT re-layout here; it'll be triggered once the banner loads. - InAppKeyboard.loadJavascript(KMString.format("enableSuggestions(%s, %d)", model, maySuggest)); + int inappMaySuggest = inAppMayPredictOverride ? SuggestionType.SUGGESTIONS_DISABLED.toInt() : + suggestionPreference; + InAppKeyboard.loadJavascript(KMString.format("enableSuggestions(%s, %d)", model, inappMaySuggest)); } if (isKeyboardLoaded(KeyboardType.KEYBOARD_TYPE_SYSTEM) && !SystemKeyboard.shouldIgnoreTextChange() && modelFileExists) { params = getKeyboardLayoutParams(); // Do NOT re-layout here; it'll be triggered once the banner loads. + int maySuggest = systemMayPredictOverride ? SuggestionType.SUGGESTIONS_DISABLED.toInt() : + suggestionPreference; SystemKeyboard.loadJavascript(KMString.format("enableSuggestions(%s, %d)", model, maySuggest)); } return true; @@ -1612,15 +1658,36 @@ public final class KMManager { String url = KMString.format("setBannerOptions(%s)", mayPredict); if (InAppKeyboard != null) { InAppKeyboard.loadJavascript(url); + Log.d(TAG, "InApp.setBannerOptions(mayPredict: " + mayPredict + ")"); } if (SystemKeyboard != null) { SystemKeyboard.loadJavascript(url); + Log.d(TAG, "System.setBannerOptions(mayPredict: " + mayPredict + ")"); } return true; } + /** + * setBannerOptions - Update KMW for inapp/system keyboard whether to generate predictions. + * For now, also display banner + * @param mayPredict - boolean whether KMW should generate predictions + * @param {KeyboardType} keyboard + * @return boolean - Success + */ + public static boolean setBannerOptions(boolean mayPredict, KeyboardType keyboard) { + String url = KMString.format("setBannerOptions(%s)", mayPredict); + if (keyboard == KeyboardType.KEYBOARD_TYPE_INAPP && InAppKeyboard != null) { + InAppKeyboard.loadJavascript(url); + } + + if (keyboard == KeyboardType.KEYBOARD_TYPE_SYSTEM && SystemKeyboard != null) { + SystemKeyboard.loadJavascript(url); + } + + return true; + } /** * Update KeymanWeb banner type * @param {KeyboardType} keyboard From 9d8f71a718d5ccd51eda924eb92298ffb2a6d9d9 Mon Sep 17 00:00:00 2001 From: Darcy Wong Date: Mon, 24 Mar 2025 08:19:35 +0700 Subject: [PATCH 3/7] refactor(android): Rename `mayPredictOverrides` APIs Per review comments, rename these API's for Keyman 18.0: inAppMayPredictOverride --> inAppPredictionsSuspendedForSensitiveInput systemMayPredictOverride --> systemPredictionsSuspendedForSensitiveInput getMayPredictOverride() --> getPredictionsSuspended() setMayPredictOverride() --> setPredictionsSuspended() --- .../com/keyman/android/SystemKeyboard.java | 4 +- .../com/tavultesoft/kmapro/MainActivity.java | 2 +- .../engine/KMKeyboardWebViewClient.java | 2 +- .../java/com/keyman/engine/KMManager.java | 64 +++++++------------ 4 files changed, 28 insertions(+), 44 deletions(-) diff --git a/android/KMAPro/kMAPro/src/main/java/com/keyman/android/SystemKeyboard.java b/android/KMAPro/kMAPro/src/main/java/com/keyman/android/SystemKeyboard.java index c0fe1e9e1e..023195d1c4 100644 --- a/android/KMAPro/kMAPro/src/main/java/com/keyman/android/SystemKeyboard.java +++ b/android/KMAPro/kMAPro/src/main/java/com/keyman/android/SystemKeyboard.java @@ -159,8 +159,8 @@ public class SystemKeyboard extends InputMethodService implements OnKeyboardEven Context appContext = getApplicationContext(); // Temporarily disable predictions on certain fields (e.g. hidden password field or numeric) inputType = attribute.inputType; - KMManager.setMayPredictOverride(inputType, KeyboardType.KEYBOARD_TYPE_SYSTEM); - if (KMManager.getMayPredictOverride(KeyboardType.KEYBOARD_TYPE_SYSTEM)) { + KMManager.setPredictionsSuspended(inputType, KeyboardType.KEYBOARD_TYPE_SYSTEM); + if (KMManager.getPredictionsSuspended(KeyboardType.KEYBOARD_TYPE_SYSTEM)) { KMManager.setBannerOptions(false); // Set the system keyboard HTML banner BannerController.setHTMLBanner(this, KeyboardType.KEYBOARD_TYPE_SYSTEM); diff --git a/android/KMAPro/kMAPro/src/main/java/com/tavultesoft/kmapro/MainActivity.java b/android/KMAPro/kMAPro/src/main/java/com/tavultesoft/kmapro/MainActivity.java index b9349a8769..f9bcd0fa2c 100644 --- a/android/KMAPro/kMAPro/src/main/java/com/tavultesoft/kmapro/MainActivity.java +++ b/android/KMAPro/kMAPro/src/main/java/com/tavultesoft/kmapro/MainActivity.java @@ -247,7 +247,7 @@ public class MainActivity extends BaseActivity implements OnKeyboardEventListene if (textView != null) { // Reset mayPredictOverride - KMManager.setMayPredictOverride(textView.getInputType(), KeyboardType.KEYBOARD_TYPE_INAPP); + KMManager.setPredictionsSuspended(textView.getInputType(), KeyboardType.KEYBOARD_TYPE_INAPP); } KMManager.onResume(); diff --git a/android/KMEA/app/src/main/java/com/keyman/engine/KMKeyboardWebViewClient.java b/android/KMEA/app/src/main/java/com/keyman/engine/KMKeyboardWebViewClient.java index 65b5003a90..853d997d7e 100644 --- a/android/KMEA/app/src/main/java/com/keyman/engine/KMKeyboardWebViewClient.java +++ b/android/KMEA/app/src/main/java/com/keyman/engine/KMKeyboardWebViewClient.java @@ -165,7 +165,7 @@ public final class KMKeyboardWebViewClient extends WebViewClient { // appContext instead of context? SharedPreferences prefs = context.getSharedPreferences(context.getString(R.string.kma_prefs_name), Context.MODE_PRIVATE); boolean modelPredictionPref = false; - if (!KMManager.getMayPredictOverride(keyboardType) && KMManager.currentLexicalModel != null) { + if (!KMManager.getPredictionsSuspended(keyboardType) && KMManager.currentLexicalModel != null) { modelPredictionPref = prefs.getInt(KMManager.getLanguageAutoCorrectionPreferenceKey( KMManager.currentLexicalModel.get(KMManager.KMKey_LanguageID)), KMManager.KMDefault_Suggestion) != SuggestionType.SUGGESTIONS_DISABLED.toInt(); diff --git a/android/KMEA/app/src/main/java/com/keyman/engine/KMManager.java b/android/KMEA/app/src/main/java/com/keyman/engine/KMManager.java index 544c321c64..fb74804bc5 100644 --- a/android/KMEA/app/src/main/java/com/keyman/engine/KMManager.java +++ b/android/KMEA/app/src/main/java/com/keyman/engine/KMManager.java @@ -257,11 +257,13 @@ public final class KMManager { // haptic feedback disabled for hardware keystrokes private static boolean mayHaveHapticFeedback = false; - // Special overrides for when the inapp/system keyboards are entering a password text field. - // When mayPredictOverride is true, the option {'mayPredict' = false} is set in the lm-layer + // Special overrides to temporarily disable predictions when editing a password field. + // These are maintained independently for inapp keyboard and system keyboard. + // When true, the suggestion banner passes the option {'mayPredict' = false} to KeymanWeb in the lm-layer // regardless what the Settings preference is. - private static boolean inAppMayPredictOverride = false; - private static boolean systemMayPredictOverride = false; + // API added Keyman 18.0 + private static boolean inAppPredictionsSuspendedForSensitiveInput = false; + private static boolean systemPredictionsSuspendedForSensitiveInput = false; // Determine how system keyboard handles ENTER key public static EnterModeType enterMode = EnterModeType.DEFAULT; @@ -1410,65 +1412,47 @@ public final class KMManager { } /** - * Determine the override if the InputType field is a hidden password text field - * but not TYPE_TEXT_VARIATION_VISIBLE_PASSWORD) + * Determine the predictions should be suspended for a given InputType field: hidden password text field + * (but not TYPE_TEXT_VARIATION_VISIBLE_PASSWORD). * Also true for numeric text fields * @param inputType android.text.InputType * @return boolean */ - private static boolean determinePredictOverride(int inputType) { + private static boolean shouldSuspendPredictions(int inputType) { return ((inputType == (InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD)) || (inputType == (InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_WEB_PASSWORD)) || isNumericField(inputType)); } /** - * This API call existed prior to 18.0. Preferred call specifies the KeyboardType. - * Sets systemMayPredictOverride true if the InputType field for system keyboard is a hidden password text field + * Sets PredictionsSuspended true if the given InputType field for the keyboard is a hidden password text field * (either TYPE_TEXT_VARIATION_PASSWORD or TYPE_TEXT_VARIATION_WEB_PASSWORD * but not TYPE_TEXT_VARIATION_VISIBLE_PASSWORD) - * Also true for numeric text fields - * @param inputType android.text.InputType - */ - public static void setMayPredictOverride(int inputType) { - systemMayPredictOverride = determinePredictOverride(inputType); - } - - /** - * Sets mayPredictOverride true if the InputType field for the keyboard is a hidden password text field - * (either TYPE_TEXT_VARIATION_PASSWORD or TYPE_TEXT_VARIATION_WEB_PASSWORD - * but not TYPE_TEXT_VARIATION_VISIBLE_PASSWORD) - * Also true for numeric text fields + * Also true for numeric text fields. + * This is to temporarily disable suggestions in these text fields. + * API added Keyman 18.0 * @param inputType android.text.InputType * @param {KeyboardType} keyboard */ - public static void setMayPredictOverride(int inputType, KeyboardType keyboard) { + public static void setPredictionsSuspended(int inputType, KeyboardType keyboard) { if (keyboard == KeyboardType.KEYBOARD_TYPE_INAPP) { - inAppMayPredictOverride = determinePredictOverride(inputType); + inAppPredictionsSuspendedForSensitiveInput = shouldSuspendPredictions(inputType); } else if (keyboard == KeyboardType.KEYBOARD_TYPE_SYSTEM) { - systemMayPredictOverride = determinePredictOverride(inputType); + systemPredictionsSuspendedForSensitiveInput = shouldSuspendPredictions(inputType); } } /** - * This API call existed prior to 18.0. Preferred call specifies the KeyboardType. - * Get the value of systemMayPredictOverride - * @return boolean - */ - public static boolean getMayPredictOverride() { - return systemMayPredictOverride; - } - - /** - * Get the value of mayPredictOverride based on KeyboardType + * Get the value of PredictionsSuspendedForSensitiveInput based on KeyboardType. + * API added in Keyman 18.0 * @param {KeyboardType} keyboard - * @return boolean + * @return boolean of inAppPredictionsSuspendedForSensitiveInput or systemPredictionsSuspendedForSensitiveInput */ - public static boolean getMayPredictOverride(KeyboardType keyboard) { + public static boolean getPredictionsSuspended(KeyboardType keyboard) { if (keyboard == KeyboardType.KEYBOARD_TYPE_INAPP) { - return inAppMayPredictOverride; + return inAppPredictionsSuspendedForSensitiveInput; } else if (keyboard == KeyboardType.KEYBOARD_TYPE_SYSTEM) { - return systemMayPredictOverride; + return systemPredictionsSuspendedForSensitiveInput; } return false; } @@ -1606,7 +1590,7 @@ public final class KMManager { params = getKeyboardLayoutParams(); // Do NOT re-layout here; it'll be triggered once the banner loads. - int inappMaySuggest = inAppMayPredictOverride ? SuggestionType.SUGGESTIONS_DISABLED.toInt() : + int inappMaySuggest = inAppPredictionsSuspendedForSensitiveInput ? SuggestionType.SUGGESTIONS_DISABLED.toInt() : suggestionPreference; InAppKeyboard.loadJavascript(KMString.format("enableSuggestions(%s, %d)", model, inappMaySuggest)); } @@ -1614,7 +1598,7 @@ public final class KMManager { params = getKeyboardLayoutParams(); // Do NOT re-layout here; it'll be triggered once the banner loads. - int maySuggest = systemMayPredictOverride ? SuggestionType.SUGGESTIONS_DISABLED.toInt() : + int maySuggest = systemPredictionsSuspendedForSensitiveInput ? SuggestionType.SUGGESTIONS_DISABLED.toInt() : suggestionPreference; SystemKeyboard.loadJavascript(KMString.format("enableSuggestions(%s, %d)", model, maySuggest)); } From edfef5488ac6d37906823fb6f358dd6e310303ee Mon Sep 17 00:00:00 2001 From: Darcy Wong Date: Mon, 24 Mar 2025 08:30:34 +0700 Subject: [PATCH 4/7] fix(oem/fv/android): Apply renames --- .../main/java/com/firstvoices/keyboards/SystemKeyboard.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/oem/firstvoices/android/app/src/main/java/com/firstvoices/keyboards/SystemKeyboard.java b/oem/firstvoices/android/app/src/main/java/com/firstvoices/keyboards/SystemKeyboard.java index 8483f90fe8..66dbe0d922 100644 --- a/oem/firstvoices/android/app/src/main/java/com/firstvoices/keyboards/SystemKeyboard.java +++ b/oem/firstvoices/android/app/src/main/java/com/firstvoices/keyboards/SystemKeyboard.java @@ -135,8 +135,8 @@ public class SystemKeyboard extends InputMethodService implements OnKeyboardEven KMManager.setNumericLayer(KeyboardType.KEYBOARD_TYPE_SYSTEM); } - // Temporarily disable predictions if entering a hidden password field - KMManager.setMayPredictOverride(inputType); + // Temporarily disable predictions on certain fields (e.g. hidden password field or numeric) + KMManager.setPredictionsSuspended(inputType, KeyboardType.KEYBOARD_TYPE_SYSTEM); if (KMManager.getMayPredictOverride()) { KMManager.setBannerOptions(false); } else if (KMManager.isKeyboardLoaded(KeyboardType.KEYBOARD_TYPE_SYSTEM)){ From 009829a842c95cea8372aeef3d8d803d9af0a921 Mon Sep 17 00:00:00 2001 From: Darcy Wong Date: Mon, 24 Mar 2025 08:57:14 +0700 Subject: [PATCH 5/7] docs(android): Update Keyman Engine for Android API Documents added getPredictionsSuspended() and setPredictionsSuspended() API calls for Keyman 18.0 --- .../KMManager/getPredictionsSuspended.md | 29 +++++++++++++++ android/docs/engine/KMManager/index.md | 6 ++++ .../KMManager/setPredictionsSuspended.md | 36 +++++++++++++++++++ 3 files changed, 71 insertions(+) create mode 100644 android/docs/engine/KMManager/getPredictionsSuspended.md create mode 100644 android/docs/engine/KMManager/setPredictionsSuspended.md diff --git a/android/docs/engine/KMManager/getPredictionsSuspended.md b/android/docs/engine/KMManager/getPredictionsSuspended.md new file mode 100644 index 0000000000..c7d356f771 --- /dev/null +++ b/android/docs/engine/KMManager/getPredictionsSuspended.md @@ -0,0 +1,29 @@ +--- +title: KMManager.getPredictionsSuspended() +--- + +## Summary +The **getPredictionsSuspended()** method returns whether whether predictions are temporarily disabled because the currently selected text field is a hidden password text field or a numeric text field. + +## Syntax +```java +KMManager.getPredictionsSuspended(KeyboardType keyboardType) +``` + +### Parameters + +`keyboardType` +: The keyboard type. `KEYBOARD_TYPE_INAPP` or + `KEYBOARD_TYPE_SYSTEM`. + +### Returns +Returns `true` if predictions are temporarily disabled because the currently selected text field is a hidden password text field or a numeric text field. `false` otherwise. + +## Description +Use this method to check if predictions are temporarily disabled because of the type of currently selected text field. This value takes precedence over the user preference in the LanguageSettings menu. + +## History +Added syntax in Keyman Engine for Android 18.0. + +## See also +* [setPredictionsSuspended](setPredictionsSuspended) diff --git a/android/docs/engine/KMManager/index.md b/android/docs/engine/KMManager/index.md index f50adde857..15a2666063 100644 --- a/android/docs/engine/KMManager/index.md +++ b/android/docs/engine/KMManager/index.md @@ -152,6 +152,9 @@ The KMManager is the core class which provides most of the methods and constants [`getOrientation()`](getOrientation) : returns the device's current orientation (Portrait vs Landscape) +[`getPredictionsSuspended()`](getPredictionsSuspended) +: returns whether predictions are temporarily disabled because the currently selected text field is a hidden password text field or a numeric text field. + [`getSpacebarText()`](getSpacebarText) : returns the current text display pattern for the spacebar @@ -257,6 +260,9 @@ The KMManager is the core class which provides most of the methods and constants [`setMaySendCrashReport()`](setMaySendCrashReport) : sets whether Keyman Engine can send crash reports over the network to Sentry +[`setPredictionsSuspended()`](setPredictionsSuspended) +: sets whether predictions are temporarily disabled because the currently selected text field is a hidden password text field or a numeric text field. + [`setShouldAllowSetKeyboard()`](setShouldAllowSetKeyboard) : sets whether Keyman Engine allows setting a keyboard other than the default keyboard diff --git a/android/docs/engine/KMManager/setPredictionsSuspended.md b/android/docs/engine/KMManager/setPredictionsSuspended.md new file mode 100644 index 0000000000..b5b69c6b58 --- /dev/null +++ b/android/docs/engine/KMManager/setPredictionsSuspended.md @@ -0,0 +1,36 @@ +--- +title: KMManager.setPredictionsSuspended() +--- + +## Summary +The **setPredictionsSuspended()** method sets an override to temporarily disable predictions when the currently selected text field is a hidden password text field or a numeric text field. + +## Syntax +```java +KMManager.setPredictionsSuspended(int inputType, KeyboardType keyboardType) +``` + +### Parameters + +[`inputType`](https://developer.android.com/reference/android/text/InputType) +: An integer defining the basic context type of text being edited. If the text is one of the following InputTypes, this methods returns `true`: + +* TYPE_CLASS_TEXT +* TYPE_TEXT_VARIATION_PASSWORD +* TYPE_CLASS_TEXT +* TYPE_TEXT_VARIATION_WEB_PASSWORD +* TYPE_CLASS_NUMBER +* TYPE_CLASS_PHONE + +`keyboardType` +: The keyboard type. `KEYBOARD_TYPE_INAPP` or + `KEYBOARD_TYPE_SYSTEM`. + +## Description +Use this method to temporarily disable predictions because of the currently selected text field. This value takes precedence over the user preference in the LanguageSettings menu. + +## History +Added syntax in Keyman Engine for Android 18.0. + +## See also +* [getPredictionsSuspended](getPredictionsSuspended) From 75bf69bfbfad53a7722a84dccd9cddb40889cea0 Mon Sep 17 00:00:00 2001 From: Darcy Wong Date: Mon, 24 Mar 2025 10:27:50 +0700 Subject: [PATCH 6/7] fix(android): Cleanup comments Cleanup references to mayPredictOverride in comments --- .../src/main/java/com/tavultesoft/kmapro/MainActivity.java | 2 +- android/KMEA/app/src/main/java/com/keyman/engine/KMManager.java | 2 +- android/docs/engine/KMManager/getPredictionsSuspended.md | 2 +- android/docs/engine/KMManager/setPredictionsSuspended.md | 2 +- .../src/main/java/com/firstvoices/keyboards/SystemKeyboard.java | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/android/KMAPro/kMAPro/src/main/java/com/tavultesoft/kmapro/MainActivity.java b/android/KMAPro/kMAPro/src/main/java/com/tavultesoft/kmapro/MainActivity.java index f9bcd0fa2c..07ce5c4cbb 100644 --- a/android/KMAPro/kMAPro/src/main/java/com/tavultesoft/kmapro/MainActivity.java +++ b/android/KMAPro/kMAPro/src/main/java/com/tavultesoft/kmapro/MainActivity.java @@ -246,7 +246,7 @@ public class MainActivity extends BaseActivity implements OnKeyboardEventListene super.onResume(); if (textView != null) { - // Reset mayPredictOverride + // Reset inAppPredictionsSuspendedForSensitiveInput flag KMManager.setPredictionsSuspended(textView.getInputType(), KeyboardType.KEYBOARD_TYPE_INAPP); } diff --git a/android/KMEA/app/src/main/java/com/keyman/engine/KMManager.java b/android/KMEA/app/src/main/java/com/keyman/engine/KMManager.java index fb74804bc5..8cb717587e 100644 --- a/android/KMEA/app/src/main/java/com/keyman/engine/KMManager.java +++ b/android/KMEA/app/src/main/java/com/keyman/engine/KMManager.java @@ -257,7 +257,7 @@ public final class KMManager { // haptic feedback disabled for hardware keystrokes private static boolean mayHaveHapticFeedback = false; - // Special overrides to temporarily disable predictions when editing a password field. + // Special flags to temporarily disable predictions when editing a password field. // These are maintained independently for inapp keyboard and system keyboard. // When true, the suggestion banner passes the option {'mayPredict' = false} to KeymanWeb in the lm-layer // regardless what the Settings preference is. diff --git a/android/docs/engine/KMManager/getPredictionsSuspended.md b/android/docs/engine/KMManager/getPredictionsSuspended.md index c7d356f771..20bb66d4f7 100644 --- a/android/docs/engine/KMManager/getPredictionsSuspended.md +++ b/android/docs/engine/KMManager/getPredictionsSuspended.md @@ -3,7 +3,7 @@ title: KMManager.getPredictionsSuspended() --- ## Summary -The **getPredictionsSuspended()** method returns whether whether predictions are temporarily disabled because the currently selected text field is a hidden password text field or a numeric text field. +The **getPredictionsSuspended()** method returns a flag that determines whether predictions are temporarily disabled because the currently selected text field is a hidden password text field or a numeric text field. ## Syntax ```java diff --git a/android/docs/engine/KMManager/setPredictionsSuspended.md b/android/docs/engine/KMManager/setPredictionsSuspended.md index b5b69c6b58..ebf8fcb37d 100644 --- a/android/docs/engine/KMManager/setPredictionsSuspended.md +++ b/android/docs/engine/KMManager/setPredictionsSuspended.md @@ -3,7 +3,7 @@ title: KMManager.setPredictionsSuspended() --- ## Summary -The **setPredictionsSuspended()** method sets an override to temporarily disable predictions when the currently selected text field is a hidden password text field or a numeric text field. +The **setPredictionsSuspended()** method sets a flag to temporarily disable predictions when the currently selected text field is a hidden password text field or a numeric text field. ## Syntax ```java diff --git a/oem/firstvoices/android/app/src/main/java/com/firstvoices/keyboards/SystemKeyboard.java b/oem/firstvoices/android/app/src/main/java/com/firstvoices/keyboards/SystemKeyboard.java index 66dbe0d922..499e0d498b 100644 --- a/oem/firstvoices/android/app/src/main/java/com/firstvoices/keyboards/SystemKeyboard.java +++ b/oem/firstvoices/android/app/src/main/java/com/firstvoices/keyboards/SystemKeyboard.java @@ -137,7 +137,7 @@ public class SystemKeyboard extends InputMethodService implements OnKeyboardEven // Temporarily disable predictions on certain fields (e.g. hidden password field or numeric) KMManager.setPredictionsSuspended(inputType, KeyboardType.KEYBOARD_TYPE_SYSTEM); - if (KMManager.getMayPredictOverride()) { + if (KMManager.getPredictionsSuspended(KeyboardType.KEYBOARD_TYPE_SYSTEM)) { KMManager.setBannerOptions(false); } else if (KMManager.isKeyboardLoaded(KeyboardType.KEYBOARD_TYPE_SYSTEM)){ // Check if predictions needs to be re-enabled per Settings preference From fee91b379db2844ae9d32bec8e009e69f7613236 Mon Sep 17 00:00:00 2001 From: Darcy Wong Date: Thu, 27 Mar 2025 11:04:30 +0700 Subject: [PATCH 7/7] chore(android): Remove debug statements --- android/KMEA/app/src/main/java/com/keyman/engine/KMManager.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/android/KMEA/app/src/main/java/com/keyman/engine/KMManager.java b/android/KMEA/app/src/main/java/com/keyman/engine/KMManager.java index 8cb717587e..7080f0a1fb 100644 --- a/android/KMEA/app/src/main/java/com/keyman/engine/KMManager.java +++ b/android/KMEA/app/src/main/java/com/keyman/engine/KMManager.java @@ -1642,12 +1642,10 @@ public final class KMManager { String url = KMString.format("setBannerOptions(%s)", mayPredict); if (InAppKeyboard != null) { InAppKeyboard.loadJavascript(url); - Log.d(TAG, "InApp.setBannerOptions(mayPredict: " + mayPredict + ")"); } if (SystemKeyboard != null) { SystemKeyboard.loadJavascript(url); - Log.d(TAG, "System.setBannerOptions(mayPredict: " + mayPredict + ")"); } return true;