fix(android): override mayPredict when entering password field

This commit is contained in:
Darcy Wong 2019-10-28 21:50:00 +07:00
parent 0f1b2d8d3c
commit 6f6df3bb85
3 changed files with 50 additions and 18 deletions

View file

@ -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<String, String> 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);

View file

@ -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);

View file

@ -119,6 +119,11 @@ public final class KMManager {
protected static HashMap<String, String> 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<String, String> 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<String, String> lexicalModelInfo) {
return KeyboardPickerActivity.addLexicalModel(context, lexicalModelInfo);
}