Bug 1495985 - Restart input method to remove composition on some IMEs. r=geckoview-reviewers,esawin
authorMakoto Kato <m_kato@ga2.so-net.ne.jp>
Thu, 21 Feb 2019 17:27:07 +0900
changeset 520078 390f162b7d9b04c1c0337aac1149303daad52e02
parent 520066 0d261741c46150c46144dd5ef382d57e40e45279
child 520079 fd67a4332060ea5389d448b3453ea23064e50b5e
push id10862
push userffxbld-merge
push dateMon, 11 Mar 2019 13:01:11 +0000
treeherdermozilla-beta@a2e7f5c935da [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgeckoview-reviewers, esawin
bugs1495985
milestone67.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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
mobile/android/geckoview/src/main/java/org/mozilla/gecko/InputMethods.java
mobile/android/geckoview/src/main/java/org/mozilla/geckoview/SessionTextInput.java
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/InputMethods.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/InputMethods.java
@@ -11,18 +11,21 @@ import android.content.Context;
 import android.os.Build;
 import android.provider.Settings.Secure;
 import android.view.View;
 import android.view.inputmethod.InputMethodInfo;
 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";
     public static final String METHOD_OPENWNN_PLUS = "com.owplus.ime.openwnnplus/.OpenWnnJAJP";
     public static final String METHOD_SAMSUNG = "com.sec.android.inputmethod/.SamsungKeypad";
     public static final String METHOD_SIMEJI = "com.adamrocker.android.input.simeji/.OpenWnnSimeji";
     public static final String METHOD_SONY = "com.sonyericsson.textinput.uxp/.glue.InputMethodServiceGlue";
     public static final String METHOD_SWIFTKEY = "com.touchtype.swiftkey/com.touchtype.KeyboardService";
@@ -54,24 +57,39 @@ final public class InputMethods {
 
     public static void restartInput(Context context, View view) {
         final InputMethodManager imm = getInputMethodManager(context);
         if (imm != null) {
             imm.restartInput(view);
         }
     }
 
-    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);
     }
 
     public static boolean needsRestartOnReplaceRemove(Context context) {
         String inputMethod = getCurrentInputMethod(context);
         return METHOD_SONY.equals(inputMethod);
     }
 
--- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/SessionTextInput.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/SessionTextInput.java
@@ -200,16 +200,29 @@ public final class SessionTextInput {
         @Override
         public void updateSelection(@NonNull final GeckoSession session,
                                     final int selStart, final int selEnd,
                                     final int compositionStart, final int compositionEnd) {
             ThreadUtils.assertOnUiThread();
             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);
             }
         }
 
         @Override
         public void updateExtractedText(@NonNull final GeckoSession session,
                                         @NonNull final ExtractedTextRequest request,
                                         @NonNull final ExtractedText text) {