From c5697e457bfc49b5da4107ac46ce58e1ba95b73e Mon Sep 17 00:00:00 2001 From: Makoto Kato Date: Thu, 21 Feb 2019 17:27:07 +0900 Subject: [PATCH] Bug 1495985 - Restart input method to remove composition on some IMEs. r=geckoview-reviewers,esawin When removing composing text, we call `InputMethodManager.updateSelection(start, end, -1, -1)`. But ATOK (Japanese input method by Justsystem) series do nothing. So, shadow text and current text becomes mismatched. As workaround, we need call `restartInput` to remove composing text if using ATOK series. According to ATOK team, ATOK has several packages name since they release several customize version. - `com.justsystems.atokmobile.*` (ATOK, ATOK subscription and etc) - `com.atok.mobile.*` (OEM version) Differential Revision: https://phabricator.services.mozilla.com/D20632 --HG-- extra : amend_source : 3380064eef826666d11c34c303bf1a493750c28e extra : histedit_source : 6038cbccc76cc7295abc5f961745070335e8dcdf --- .../java/org/mozilla/gecko/InputMethods.java | 24 ++++++++++++++++--- .../mozilla/geckoview/SessionTextInput.java | 13 ++++++++++ 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/InputMethods.java b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/InputMethods.java index 51728c081add..8015fa21a5e7 100644 --- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/InputMethods.java +++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/InputMethods.java @@ -16,8 +16,11 @@ import android.view.inputmethod.InputMethodManager; final public class InputMethods { public static final String METHOD_ANDROID_LATINIME = "com.android.inputmethod.latin/.LatinIME"; - public static final String METHOD_ATOK = "com.justsystems.atokmobile.service/.AtokInputMethodService"; + // ATOK has a lot of package names since they release custom versions. + public static final String METHOD_ATOK_PREFIX = "com.justsystems.atokmobile."; + public static final String METHOD_ATOK_OEM_PREFIX = "com.atok.mobile."; public static final String METHOD_GOOGLE_JAPANESE_INPUT = "com.google.android.inputmethod.japanese/.MozcService"; + public static final String METHOD_ATOK_OEM_SOFTBANK = "com.mobiroo.n.justsystems.atok/.AtokInputMethodService"; public static final String METHOD_GOOGLE_LATINIME = "com.google.android.inputmethod.latin/com.android.inputmethod.latin.LatinIME"; public static final String METHOD_HTC_TOUCH_INPUT = "com.htc.android.htcime/.HTCIMEService"; public static final String METHOD_IWNN = "jp.co.omronsoft.iwnnime.ml/.standardcommon.IWnnLanguageSwitcher"; @@ -59,14 +62,29 @@ final public class InputMethods { } } - public static boolean needsSoftResetWorkaround(String inputMethod) { + public static boolean needsSoftResetWorkaround(final String inputMethod) { // Stock latin IME on Android 4.2 and above return Build.VERSION.SDK_INT >= 17 && (METHOD_ANDROID_LATINIME.equals(inputMethod) || METHOD_GOOGLE_LATINIME.equals(inputMethod)); } - public static boolean shouldCommitCharAsKey(String inputMethod) { + /** + * Check input method if we require a workaround to remove composition in + * {@link android.view.inputmethod.InputMethodManager.updateSelection}. + * + * @param inputMethod The input method name by {@link #getCurrentInputMethod}. + * @return true if {@link android.view.inputmethod.InputMethodManager.updateSelection} + * doesn't remove the composition, use {@link android.view.inputmethod.InputMehtodManager.restartInput} + * to remove it in this case. + */ + public static boolean needsRestartInput(final String inputMethod) { + return inputMethod.startsWith(METHOD_ATOK_PREFIX) || + inputMethod.startsWith(METHOD_ATOK_OEM_PREFIX) || + METHOD_ATOK_OEM_SOFTBANK.equals(inputMethod); + } + + public static boolean shouldCommitCharAsKey(final String inputMethod) { return METHOD_HTC_TOUCH_INPUT.equals(inputMethod); } diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/SessionTextInput.java b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/SessionTextInput.java index 74b723d696d3..b37c7ae28869 100644 --- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/SessionTextInput.java +++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/SessionTextInput.java @@ -205,6 +205,19 @@ public final class SessionTextInput { final View view = session.getTextInput().getView(); final InputMethodManager imm = getInputMethodManager(view); if (imm != null) { + // When composition start and end is -1, + // InputMethodManager.updateSelection will remove composition + // on most IMEs. But ATOK series do nothing. So we have to + // restart input method to remove composition as workaround. + if (compositionStart < 0 && compositionEnd < 0 && + InputMethods.needsRestartInput( + InputMethods.getCurrentInputMethod(view.getContext()))) { + try { + imm.restartInput(view); + } catch (RuntimeException e) { + Log.e(LOGTAG, "Error restarting input", e); + } + } imm.updateSelection(view, selStart, selEnd, compositionStart, compositionEnd); } }