From 6f6df3bb85a220c11bb7f76ebfc3407faa62c18e Mon Sep 17 00:00:00 2001 From: Darcy Wong Date: Mon, 28 Oct 2019 21:50:00 +0700 Subject: [PATCH] fix(android): override `mayPredict` when entering password field --- .../com/keyman/android/SystemKeyboard.java | 20 +++++++++ .../KMEA/app/src/main/assets/keyboard.html | 6 +++ .../java/com/tavultesoft/kmea/KMManager.java | 42 +++++++++++-------- 3 files changed, 50 insertions(+), 18 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 228fcd0527..92abaa2508 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 @@ -9,8 +9,11 @@ import com.tavultesoft.kmea.KMManager; import com.tavultesoft.kmea.KMManager.KeyboardType; import com.tavultesoft.kmea.KMHardwareKeyboardInterpreter; import com.tavultesoft.kmea.KeyboardEventHandler.OnKeyboardEventListener; +import com.tavultesoft.kmea.LanguageSettingsActivity; +import com.tavultesoft.kmea.R; import android.content.Context; +import android.content.SharedPreferences; import android.content.res.Configuration; import android.graphics.Point; import android.inputmethodservice.InputMethodService; @@ -24,6 +27,8 @@ import android.view.inputmethod.ExtractedText; import android.view.inputmethod.ExtractedTextRequest; import android.view.inputmethod.InputConnection; +import java.util.HashMap; + public class SystemKeyboard extends InputMethodService implements OnKeyboardEventListener { private static View inputView = null; @@ -112,6 +117,21 @@ public class SystemKeyboard extends InputMethodService implements OnKeyboardEven KMManager.setNumericLayer(KeyboardType.KEYBOARD_TYPE_SYSTEM); } + // Temporarily disable predictions if entering a hidden password field + if (KMManager.isHiddenPasswordInputType(inputType)) { + KMManager.setBannerOptions(false); + } else { + // Check if predictions needs to be re-enabled per Settings preference + Context appContext = getApplicationContext(); + HashMap kbInfo = KMManager.getCurrentKeyboardInfo(appContext); + if (kbInfo != null) { + String langId = kbInfo.get(KMManager.KMKey_LanguageID); + SharedPreferences prefs = appContext.getSharedPreferences(appContext.getString(R.string.kma_prefs_name), Context.MODE_PRIVATE); + boolean mayPredict = prefs.getBoolean(LanguageSettingsActivity.getLanguagePredictionPreferenceKey(langId), true); + KMManager.setBannerOptions(mayPredict); + } + } + InputConnection ic = getCurrentInputConnection(); if (ic != null) { ExtractedText icText = ic.getExtractedText(new ExtractedTextRequest(), 0); diff --git a/android/KMEA/app/src/main/assets/keyboard.html b/android/KMEA/app/src/main/assets/keyboard.html index a0eebfa92a..41fe205e89 100644 --- a/android/KMEA/app/src/main/assets/keyboard.html +++ b/android/KMEA/app/src/main/assets/keyboard.html @@ -189,6 +189,12 @@ registerModel(model); } + function setBannerOptions(mayPredict) { + keyman.osk.banner.setOptions({ + 'mayPredict': mayPredict + }); + } + function registerModel(model) { var kmw=window['keyman']; //window.console.log('registerModel: ' + model); diff --git a/android/KMEA/app/src/main/java/com/tavultesoft/kmea/KMManager.java b/android/KMEA/app/src/main/java/com/tavultesoft/kmea/KMManager.java index 505a9c1cc3..a81c790861 100644 --- a/android/KMEA/app/src/main/java/com/tavultesoft/kmea/KMManager.java +++ b/android/KMEA/app/src/main/java/com/tavultesoft/kmea/KMManager.java @@ -119,6 +119,11 @@ public final class KMManager { protected static HashMap currentLexicalModel = null; protected static String currentBanner = "blank"; + // Special override for when keyboard is entering a password text field. + // When shouldOverrideMayProtect is true, the option {'mayProtect' = false} is set in the lm-layer + // regardless what the Settings preference is. + private static boolean shouldOverrideMayProtect = false; + // Keyman public keys public static final String KMKey_ID = "id"; public static final String KMKey_Name = "name"; @@ -330,22 +335,9 @@ public final class KMManager { } public static void onStartInput(EditorInfo attribute, boolean restarting) { - int inputType = attribute.inputType; - - // Temporarily disable lm-layer if entering a hidden password field - if (currentLexicalModel != null && isHiddenPasswordInputType(inputType)) { - deregisterLexicalModel(currentLexicalModel.get(KMKey_LexicalModelID)); - } else if (currentLexicalModel == null) { - // Check if lm-layer needs to be re-enabled - HashMap kbInfo = getCurrentKeyboardInfo(appContext); - if (kbInfo != null) { - String langId = kbInfo.get(KMKey_LanguageID); - registerAssociatedLexicalModel(langId); - } - } - if (!restarting) { String packageName = attribute.packageName; + int inputType = attribute.inputType; if (packageName.equals("android") && inputType == (InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD)) { SystemKeyboard.keyboardPickerEnabled = false; } else { @@ -691,12 +683,12 @@ public final class KMManager { * TYPE_TEXT_VARIATION_PASSWORD or TYPE_TEXT_VARIATION_WEB_PASSWORD * but not TYPE_TEXT_VARIATION_VISIBLE_PASSWORD */ - private static boolean isHiddenPasswordInputType(int inputType) { - boolean isHiddenPassword = + public static boolean isHiddenPasswordInputType(int inputType) { + shouldOverrideMayProtect = ((inputType == (InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD)) || (inputType == (InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_WEB_PASSWORD))); - return isHiddenPassword; + return shouldOverrideMayProtect; } /** @@ -757,8 +749,10 @@ public final class KMManager { model = model.replaceAll("\'", "\\\\'"); // Double-escaped-backslash b/c regex. model = model.replaceAll("\"", "'"); + // When entering password field, mayPredict should override to false SharedPreferences prefs = appContext.getSharedPreferences(appContext.getString(R.string.kma_prefs_name), Context.MODE_PRIVATE); - boolean mayPredict = prefs.getBoolean(LanguageSettingsActivity.getLanguagePredictionPreferenceKey(languageID), true); + boolean mayPredict = (shouldOverrideMayProtect) ? false : + prefs.getBoolean(LanguageSettingsActivity.getLanguagePredictionPreferenceKey(languageID), true); boolean mayCorrect = prefs.getBoolean(LanguageSettingsActivity.getLanguageCorrectionPreferenceKey(languageID), true); RelativeLayout.LayoutParams params = getKeyboardLayoutParams(); @@ -790,6 +784,18 @@ public final class KMManager { return true; } + public static boolean setBannerOptions(boolean mayPredict) { + String url = String.format("setBannerOptions(%s)", mayPredict); + if (InAppKeyboard != null) { + InAppKeyboard.loadJavascript(url); + } + + if (SystemKeyboard != null) { + SystemKeyboard.loadJavascript(url); + } + return true; + } + public static boolean addLexicalModel(Context context, HashMap lexicalModelInfo) { return KeyboardPickerActivity.addLexicalModel(context, lexicalModelInfo); }