Bug 1256147 - Fix keyboard swipe function on Galaxy S7. r=esawin, a=ritu
authorJim Chen <nchen@mozilla.com>
Mon, 25 Apr 2016 18:36:00 -0400
changeset 332620 1a7240593dee67e2d5f3a4fc8df6123aaa533f60
parent 332619 923eb590aeb8c653f047fe81e6df3543a6d9ef15
child 332621 3b60d399d4eef579688a499675c337a252a7bcac
push id6048
push userkmoir@mozilla.com
push dateMon, 06 Jun 2016 19:02:08 +0000
treeherdermozilla-beta@46d72a56c57d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersesawin, ritu
bugs1256147
milestone48.0a2
Bug 1256147 - Fix keyboard swipe function on Galaxy S7. r=esawin, a=ritu Showing and hiding the keyboard in onCreatInputConnection avoids a possible race with resetInput in notifyIMEContext, and it replaces the "show keyboard on window refocus" hack that we had before. Make showSoftInput always post to the UI thread for consistency. Initialize the EditorInfo object even when we return null in onCreateInputConnection. This fixes the bug for the Samsung keyboard on Galaxy S7.
mobile/android/base/java/org/mozilla/gecko/GeckoInputConnection.java
mobile/android/base/java/org/mozilla/gecko/GeckoView.java
mobile/android/base/java/org/mozilla/gecko/InputConnectionListener.java
--- a/mobile/android/base/java/org/mozilla/gecko/GeckoInputConnection.java
+++ b/mobile/android/base/java/org/mozilla/gecko/GeckoInputConnection.java
@@ -229,36 +229,31 @@ class GeckoInputConnection
         if (view == null) {
             return null;
         }
         Context context = view.getContext();
         return InputMethods.getInputMethodManager(context);
     }
 
     private void showSoftInput() {
+        final View v = getView();
         final InputMethodManager imm = getInputMethodManager();
-        if (imm != null) {
-            final View v = getView();
+        if (v == null || imm == null) {
+            return;
+        }
 
-            if (v.hasFocus() && !imm.isActive(v)) {
-                // Workaround: The view has focus but it is not the active view for the input method. (Bug 1211848)
-                refocusAndShowSoftInput(imm, v);
-            } else {
-                imm.showSoftInput(v, 0);
-            }
-        }
-    }
-
-    private static void refocusAndShowSoftInput(final InputMethodManager imm, final View v) {
-        ThreadUtils.postToUiThread(new Runnable() {
+        v.post(new Runnable() {
             @Override
             public void run() {
-                v.clearFocus();
-                v.requestFocus();
-
+                if (v.hasFocus() && !imm.isActive(v)) {
+                    // Marshmallow workaround: The view has focus but it is not the active
+                    // view for the input method. (Bug 1211848)
+                    v.clearFocus();
+                    v.requestFocus();
+                }
                 imm.showSoftInput(v, 0);
             }
         });
     }
 
     private void hideSoftInput() {
         final InputMethodManager imm = getInputMethodManager();
         if (imm != null) {
@@ -467,28 +462,28 @@ class GeckoInputConnection
 
         if (isPhysicalKeyboardPresent()) {
             return mEditableClient.setInputConnectionHandler(defHandler);
         }
 
         return mEditableClient.setInputConnectionHandler(getBackgroundHandler());
     }
 
-    private boolean mIsVisible = false;
-
     @Override
     public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
-        if (mIMEState == IME_STATE_DISABLED) {
-            return null;
-        }
-
+        // Some keyboards require us to fill out outAttrs even if we return null.
         outAttrs.inputType = InputType.TYPE_CLASS_TEXT;
         outAttrs.imeOptions = EditorInfo.IME_ACTION_NONE;
         outAttrs.actionLabel = null;
 
+        if (mIMEState == IME_STATE_DISABLED) {
+            hideSoftInput();
+            return null;
+        }
+
         if (mIMEState == IME_STATE_PASSWORD ||
             "password".equalsIgnoreCase(mIMETypeHint))
             outAttrs.inputType |= InputType.TYPE_TEXT_VARIATION_PASSWORD;
         else if (mIMEState == IME_STATE_PLUGIN)
             outAttrs.inputType = InputType.TYPE_NULL; // "send key events" mode
         else if (mIMETypeHint.equalsIgnoreCase("url"))
             outAttrs.inputType |= InputType.TYPE_TEXT_VARIATION_URI;
         else if (mIMETypeHint.equalsIgnoreCase("email"))
@@ -582,22 +577,17 @@ class GeckoInputConnection
             outAttrs.initialSelStart = 0;
             outAttrs.initialSelEnd = 0;
             return mKeyInputConnection;
         }
         Editable editable = getEditable();
         outAttrs.initialSelStart = Selection.getSelectionStart(editable);
         outAttrs.initialSelEnd = Selection.getSelectionEnd(editable);
 
-        if (mIsVisible) {
-            // The app has been brought to the foreground and the Soft Keyboard
-            // was previously visible, so request that it be shown again.
-            showSoftInput();
-        }
-
+        showSoftInput();
         return this;
     }
 
     private boolean replaceComposingSpanWithSelection() {
         final Editable content = getEditable();
         if (content == null) {
             return false;
         }
@@ -793,26 +783,16 @@ class GeckoInputConnection
         return processKey(KeyEvent.ACTION_DOWN, keyCode, event);
     }
 
     @Override
     public boolean onKeyUp(int keyCode, KeyEvent event) {
         return processKey(KeyEvent.ACTION_UP, keyCode, event);
     }
 
-    @Override
-    public void onWindowVisibilityChanged (int visibility) {
-        if (visibility == View.VISIBLE) {
-            mIsVisible = true;
-        } else {
-            mIsVisible = false;
-            hideSoftInput();
-        }
-    }
-
     /**
      * Get a key that represents a given character.
      */
     private KeyEvent getCharKeyEvent(final char c) {
         final long time = SystemClock.uptimeMillis();
         return new KeyEvent(time, time, KeyEvent.ACTION_MULTIPLE,
                             KeyEvent.KEYCODE_UNKNOWN, /* repeat */ 0) {
             @Override
@@ -931,21 +911,16 @@ class GeckoInputConnection
         if (v == null || !v.hasFocus()) {
             // When using Find In Page, we can still receive notifyIMEContext calls due to the
             // selection changing when highlighting. However in this case we don't want to reset/
             // show/hide the keyboard because the find box has the focus and is taking input from
             // the keyboard.
             return;
         }
         restartInput();
-        if (mIMEState == IME_STATE_DISABLED) {
-            hideSoftInput();
-        } else {
-            showSoftInput();
-        }
     }
 }
 
 final class DebugGeckoInputConnection
         extends GeckoInputConnection
         implements InvocationHandler {
 
     private InputConnection mProxy;
--- a/mobile/android/base/java/org/mozilla/gecko/GeckoView.java
+++ b/mobile/android/base/java/org/mozilla/gecko/GeckoView.java
@@ -267,34 +267,18 @@ public class GeckoView extends LayerView
         } else {
             GeckoThread.queueNativeCallUntil(GeckoThread.State.PROFILE_READY,
                     window, "close");
             GeckoThread.queueNativeCallUntil(GeckoThread.State.PROFILE_READY,
                     window, "disposeNative");
         }
     }
 
-    private int mLastVisibility = View.GONE;
-
     /* package */ void setInputConnectionListener(final InputConnectionListener icl) {
         mInputConnectionListener = icl;
-        if (mInputConnectionListener != null) {
-            mInputConnectionListener.onWindowVisibilityChanged(mLastVisibility);
-        }
-    }
-
-    @Override
-    protected void onWindowVisibilityChanged (int visibility) {
-        mLastVisibility = visibility;
-
-        if (mInputConnectionListener != null) {
-            mInputConnectionListener.onWindowVisibilityChanged(visibility);
-        }
-
-        super.onWindowVisibilityChanged(visibility);
     }
 
     @Override
     public Handler getHandler() {
         if (mInputConnectionListener != null) {
             return mInputConnectionListener.getHandler(super.getHandler());
         }
         return super.getHandler();
--- a/mobile/android/base/java/org/mozilla/gecko/InputConnectionListener.java
+++ b/mobile/android/base/java/org/mozilla/gecko/InputConnectionListener.java
@@ -16,11 +16,10 @@ interface InputConnectionListener
 {
     Handler getHandler(Handler defHandler);
     InputConnection onCreateInputConnection(EditorInfo outAttrs);
     boolean onKeyPreIme(int keyCode, KeyEvent event);
     boolean onKeyDown(int keyCode, KeyEvent event);
     boolean onKeyLongPress(int keyCode, KeyEvent event);
     boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event);
     boolean onKeyUp(int keyCode, KeyEvent event);
-    void onWindowVisibilityChanged (int visibility);
     boolean isIMEEnabled();
 }