diff --git a/core/java/android/view/ImeFocusController.java b/core/java/android/view/ImeFocusController.java index a4800726bbe8b..825077ffd57a5 100644 --- a/core/java/android/view/ImeFocusController.java +++ b/core/java/android/view/ImeFocusController.java @@ -125,6 +125,13 @@ public final class ImeFocusController { final View viewForWindowFocus = focusedView != null ? focusedView : mViewRootImpl.mView; onViewFocusChanged(viewForWindowFocus, true); + // Skip starting input when the next focused view is same as served view and the served + // input connection still exists. + final boolean nextFocusIsServedView = mServedView != null && mServedView == focusedView; + if (nextFocusIsServedView && immDelegate.isAcceptingText()) { + forceFocus = false; + } + immDelegate.startInputAsyncOnWindowFocusGain(viewForWindowFocus, windowAttribute.softInputMode, windowAttribute.flags, forceFocus); } @@ -247,6 +254,7 @@ public final class ImeFocusController { void setCurrentRootView(ViewRootImpl rootView); boolean isCurrentRootView(ViewRootImpl rootView); boolean isRestartOnNextWindowFocus(boolean reset); + boolean isAcceptingText(); } public View getServedView() { diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java index 71dd6653f6a65..477dd1d132953 100644 --- a/core/java/android/view/inputmethod/InputMethodManager.java +++ b/core/java/android/view/inputmethod/InputMethodManager.java @@ -616,12 +616,19 @@ public final class InputMethodManager { // For some reason we didn't do a startInput + windowFocusGain, so // we'll just do a window focus gain and call it a day. try { - if (DEBUG) Log.v(TAG, "Reporting focus gain, without startInput"); + View servedView = controller.getServedView(); + boolean nextFocusIsServedView = servedView != null && servedView == focusedView; + if (DEBUG) { + Log.v(TAG, "Reporting focus gain, without startInput" + + ", nextFocusIsServedView=" + nextFocusIsServedView); + } mService.startInputOrWindowGainedFocus( StartInputReason.WINDOW_FOCUS_GAIN_REPORT_ONLY, mClient, focusedView.getWindowToken(), startInputFlags, softInputMode, windowFlags, - null, null, 0 /* missingMethodFlags */, + nextFocusIsServedView ? mCurrentTextBoxAttribute : null, + nextFocusIsServedView ? mServedInputConnectionWrapper : null, + 0 /* missingMethodFlags */, mCurRootView.mContext.getApplicationInfo().targetSdkVersion); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -646,8 +653,7 @@ public final class InputMethodManager { public void setCurrentRootView(ViewRootImpl rootView) { synchronized (mH) { if (mCurRootView != null) { - // Reset the last served view and restart window focus state of the root view. - mCurRootView.getImeFocusController().setServedView(null); + // Restart the input when the next window focus state of the root view changed. mRestartOnNextWindowFocus = true; } mCurRootView = rootView; @@ -677,6 +683,18 @@ public final class InputMethodManager { } return result; } + + /** + * For {@link ImeFocusController} to check if the currently served view is accepting full + * text edits. + */ + @Override + public boolean isAcceptingText() { + synchronized (mH) { + return mServedInputConnectionWrapper != null + && mServedInputConnectionWrapper.getInputConnection() != null; + } + } } /** @hide */ diff --git a/core/java/com/android/internal/inputmethod/StartInputReason.java b/core/java/com/android/internal/inputmethod/StartInputReason.java index a01c45919b8fc..a4eaa21538f73 100644 --- a/core/java/com/android/internal/inputmethod/StartInputReason.java +++ b/core/java/com/android/internal/inputmethod/StartInputReason.java @@ -50,8 +50,9 @@ public @interface StartInputReason { int WINDOW_FOCUS_GAIN = 1; /** * {@link android.view.Window} gained focus but there is no {@link android.view.View} that is - * eligible to have IME focus. {@link android.view.inputmethod.InputMethodManager} just reports - * this window focus change event. + * eligible to have IME focus, or the focused view is same as current served view and its + * input connection remains. {@link android.view.inputmethod.InputMethodManager} just reports + * this window focus change event to sync IME input target for system. */ int WINDOW_FOCUS_GAIN_REPORT_ONLY = 2; /**