Loading core/java/android/view/ImeFocusController.java +5 −5 Original line number Diff line number Diff line Loading @@ -125,11 +125,11 @@ 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. // Starting new input when the next focused view is same as served view but the // editor is not aligned with the same editor or editor is inactive. final boolean nextFocusIsServedView = mServedView != null && mServedView == focusedView; if (nextFocusIsServedView && immDelegate.isAcceptingText()) { forceFocus = false; if (nextFocusIsServedView && !immDelegate.isSameEditorAndAcceptingText(focusedView)) { forceFocus = true; } immDelegate.startInputAsyncOnWindowFocusGain(viewForWindowFocus, Loading Loading @@ -254,7 +254,7 @@ public final class ImeFocusController { void setCurrentRootView(ViewRootImpl rootView); boolean isCurrentRootView(ViewRootImpl rootView); boolean isRestartOnNextWindowFocus(boolean reset); boolean isAcceptingText(); boolean isSameEditorAndAcceptingText(View view); } public View getServedView() { Loading core/java/android/view/inputmethod/InputMethodManager.java +31 −15 Original line number Diff line number Diff line Loading @@ -633,20 +633,21 @@ public final class InputMethodManager { // we'll just do a window focus gain and call it a day. try { View servedView = controller.getServedView(); boolean nextFocusIsServedView = servedView != null && servedView == focusedView; boolean nextFocusSameEditor = servedView != null && servedView == focusedView && isSameEditorAndAcceptingText(focusedView); if (DEBUG) { Log.v(TAG, "Reporting focus gain, without startInput" + ", nextFocusIsServedView=" + nextFocusIsServedView); + ", nextFocusIsServedView=" + nextFocusSameEditor); } final int startInputReason = nextFocusIsServedView ? WINDOW_FOCUS_GAIN_REPORT_WITH_SAME_EDITOR nextFocusSameEditor ? WINDOW_FOCUS_GAIN_REPORT_WITH_SAME_EDITOR : WINDOW_FOCUS_GAIN_REPORT_WITHOUT_EDITOR; mService.startInputOrWindowGainedFocus( startInputReason, mClient, focusedView.getWindowToken(), startInputFlags, softInputMode, windowFlags, nextFocusIsServedView ? mCurrentTextBoxAttribute : null, nextFocusIsServedView ? mServedInputConnectionWrapper : null, null, null, 0 /* missingMethodFlags */, mCurRootView.mContext.getApplicationInfo().targetSdkVersion); } catch (RemoteException e) { Loading @@ -671,10 +672,6 @@ public final class InputMethodManager { @Override public void setCurrentRootView(ViewRootImpl rootView) { synchronized (mH) { if (mCurRootView != null) { // Restart the input when the next window focus state of the root view changed. mRestartOnNextWindowFocus = true; } mCurRootView = rootView; } } Loading Loading @@ -704,14 +701,33 @@ public final class InputMethodManager { } /** * For {@link ImeFocusController} to check if the currently served view is accepting full * text edits. * For {@link ImeFocusController} to check if the given focused view aligns with the same * editor and the editor is active to accept the text input. * * TODO(b/160968797): Remove this method and move mCurrentTextBoxAttritube to * ImeFocusController. * In the long-term, we should make mCurrentTextBoxAtrtribue as per-window base instance, * so that we we can directly check if the current focused view aligned with the same editor * in the window without using this checking. * * Note that this method is only use for fixing start new input may ignored issue * (e.g. b/160391516), DO NOT leverage this method to do another check. */ @Override public boolean isAcceptingText() { public boolean isSameEditorAndAcceptingText(View view) { synchronized (mH) { return mServedInputConnectionWrapper != null && mServedInputConnectionWrapper.getInputConnection() != null; if (!hasServedByInputMethodLocked(view) || mCurrentTextBoxAttribute == null) { return false; } final EditorInfo ic = mCurrentTextBoxAttribute; // This sameEditor checking is based on using object hash comparison to check if // some fields of the current EditorInfo (e.g. autoFillId, OpPackageName) the // hash code is same as the given focused view. final boolean sameEditor = view.onCheckIsTextEditor() && view.getId() == ic.fieldId && view.getAutofillId() == ic.autofillId && view.getContext().getOpPackageName() == ic.packageName; return sameEditor && mServedInputConnectionWrapper != null && mServedInputConnectionWrapper.isActive(); } } } Loading services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +5 −21 Original line number Diff line number Diff line Loading @@ -18,8 +18,6 @@ package com.android.server.inputmethod; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.INVALID_DISPLAY; import static com.android.internal.inputmethod.StartInputReason.WINDOW_FOCUS_GAIN_REPORT_WITH_SAME_EDITOR; import static java.lang.annotation.RetentionPolicy.SOURCE; import android.Manifest; Loading Loading @@ -719,11 +717,6 @@ public class InputMethodManagerService extends IInputMethodManager.Stub */ int mImeWindowVis; /** * Checks if the client needs to start input. */ private boolean mCurClientNeedStartInput = false; private AlertDialog.Builder mDialogBuilder; private AlertDialog mSwitchingDialog; private IBinder mSwitchingDialogToken = new Binder(); Loading Loading @@ -3467,20 +3460,14 @@ public class InputMethodManagerService extends IInputMethodManager.Stub if (mCurFocusedWindow == windowToken) { if (DEBUG) { Slog.w(TAG, "Window already focused, ignoring focus gain of: " + client + " attribute=" + attribute + ", token = " + windowToken); } // Needs to start input when the same window focus gain but not with the same editor, // or when the current client needs to start input (e.g. when focusing the same // window after device turned screen on). if (attribute != null && (startInputReason != WINDOW_FOCUS_GAIN_REPORT_WITH_SAME_EDITOR || mCurClientNeedStartInput)) { if (mIsInteractive) { mCurClientNeedStartInput = false; + " attribute=" + attribute + ", token = " + windowToken + ", startInputReason=" + InputMethodDebug.startInputReasonToString(startInputReason)); } if (attribute != null) { return startInputUncheckedLocked(cs, inputContext, missingMethods, attribute, startInputFlags, startInputReason); } return new InputBindResult( InputBindResult.ResultCode.SUCCESS_REPORT_WINDOW_FOCUS_ONLY, null, null, null, -1, null); Loading Loading @@ -4459,9 +4446,6 @@ public class InputMethodManagerService extends IInputMethodManager.Stub private void handleSetInteractive(final boolean interactive) { synchronized (mMethodMap) { mIsInteractive = interactive; if (!interactive) { mCurClientNeedStartInput = true; } updateSystemUiLocked(interactive ? mImeWindowVis : 0, mBackDisposition); // Inform the current client of the change in active status Loading Loading
core/java/android/view/ImeFocusController.java +5 −5 Original line number Diff line number Diff line Loading @@ -125,11 +125,11 @@ 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. // Starting new input when the next focused view is same as served view but the // editor is not aligned with the same editor or editor is inactive. final boolean nextFocusIsServedView = mServedView != null && mServedView == focusedView; if (nextFocusIsServedView && immDelegate.isAcceptingText()) { forceFocus = false; if (nextFocusIsServedView && !immDelegate.isSameEditorAndAcceptingText(focusedView)) { forceFocus = true; } immDelegate.startInputAsyncOnWindowFocusGain(viewForWindowFocus, Loading Loading @@ -254,7 +254,7 @@ public final class ImeFocusController { void setCurrentRootView(ViewRootImpl rootView); boolean isCurrentRootView(ViewRootImpl rootView); boolean isRestartOnNextWindowFocus(boolean reset); boolean isAcceptingText(); boolean isSameEditorAndAcceptingText(View view); } public View getServedView() { Loading
core/java/android/view/inputmethod/InputMethodManager.java +31 −15 Original line number Diff line number Diff line Loading @@ -633,20 +633,21 @@ public final class InputMethodManager { // we'll just do a window focus gain and call it a day. try { View servedView = controller.getServedView(); boolean nextFocusIsServedView = servedView != null && servedView == focusedView; boolean nextFocusSameEditor = servedView != null && servedView == focusedView && isSameEditorAndAcceptingText(focusedView); if (DEBUG) { Log.v(TAG, "Reporting focus gain, without startInput" + ", nextFocusIsServedView=" + nextFocusIsServedView); + ", nextFocusIsServedView=" + nextFocusSameEditor); } final int startInputReason = nextFocusIsServedView ? WINDOW_FOCUS_GAIN_REPORT_WITH_SAME_EDITOR nextFocusSameEditor ? WINDOW_FOCUS_GAIN_REPORT_WITH_SAME_EDITOR : WINDOW_FOCUS_GAIN_REPORT_WITHOUT_EDITOR; mService.startInputOrWindowGainedFocus( startInputReason, mClient, focusedView.getWindowToken(), startInputFlags, softInputMode, windowFlags, nextFocusIsServedView ? mCurrentTextBoxAttribute : null, nextFocusIsServedView ? mServedInputConnectionWrapper : null, null, null, 0 /* missingMethodFlags */, mCurRootView.mContext.getApplicationInfo().targetSdkVersion); } catch (RemoteException e) { Loading @@ -671,10 +672,6 @@ public final class InputMethodManager { @Override public void setCurrentRootView(ViewRootImpl rootView) { synchronized (mH) { if (mCurRootView != null) { // Restart the input when the next window focus state of the root view changed. mRestartOnNextWindowFocus = true; } mCurRootView = rootView; } } Loading Loading @@ -704,14 +701,33 @@ public final class InputMethodManager { } /** * For {@link ImeFocusController} to check if the currently served view is accepting full * text edits. * For {@link ImeFocusController} to check if the given focused view aligns with the same * editor and the editor is active to accept the text input. * * TODO(b/160968797): Remove this method and move mCurrentTextBoxAttritube to * ImeFocusController. * In the long-term, we should make mCurrentTextBoxAtrtribue as per-window base instance, * so that we we can directly check if the current focused view aligned with the same editor * in the window without using this checking. * * Note that this method is only use for fixing start new input may ignored issue * (e.g. b/160391516), DO NOT leverage this method to do another check. */ @Override public boolean isAcceptingText() { public boolean isSameEditorAndAcceptingText(View view) { synchronized (mH) { return mServedInputConnectionWrapper != null && mServedInputConnectionWrapper.getInputConnection() != null; if (!hasServedByInputMethodLocked(view) || mCurrentTextBoxAttribute == null) { return false; } final EditorInfo ic = mCurrentTextBoxAttribute; // This sameEditor checking is based on using object hash comparison to check if // some fields of the current EditorInfo (e.g. autoFillId, OpPackageName) the // hash code is same as the given focused view. final boolean sameEditor = view.onCheckIsTextEditor() && view.getId() == ic.fieldId && view.getAutofillId() == ic.autofillId && view.getContext().getOpPackageName() == ic.packageName; return sameEditor && mServedInputConnectionWrapper != null && mServedInputConnectionWrapper.isActive(); } } } Loading
services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +5 −21 Original line number Diff line number Diff line Loading @@ -18,8 +18,6 @@ package com.android.server.inputmethod; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.INVALID_DISPLAY; import static com.android.internal.inputmethod.StartInputReason.WINDOW_FOCUS_GAIN_REPORT_WITH_SAME_EDITOR; import static java.lang.annotation.RetentionPolicy.SOURCE; import android.Manifest; Loading Loading @@ -719,11 +717,6 @@ public class InputMethodManagerService extends IInputMethodManager.Stub */ int mImeWindowVis; /** * Checks if the client needs to start input. */ private boolean mCurClientNeedStartInput = false; private AlertDialog.Builder mDialogBuilder; private AlertDialog mSwitchingDialog; private IBinder mSwitchingDialogToken = new Binder(); Loading Loading @@ -3467,20 +3460,14 @@ public class InputMethodManagerService extends IInputMethodManager.Stub if (mCurFocusedWindow == windowToken) { if (DEBUG) { Slog.w(TAG, "Window already focused, ignoring focus gain of: " + client + " attribute=" + attribute + ", token = " + windowToken); } // Needs to start input when the same window focus gain but not with the same editor, // or when the current client needs to start input (e.g. when focusing the same // window after device turned screen on). if (attribute != null && (startInputReason != WINDOW_FOCUS_GAIN_REPORT_WITH_SAME_EDITOR || mCurClientNeedStartInput)) { if (mIsInteractive) { mCurClientNeedStartInput = false; + " attribute=" + attribute + ", token = " + windowToken + ", startInputReason=" + InputMethodDebug.startInputReasonToString(startInputReason)); } if (attribute != null) { return startInputUncheckedLocked(cs, inputContext, missingMethods, attribute, startInputFlags, startInputReason); } return new InputBindResult( InputBindResult.ResultCode.SUCCESS_REPORT_WINDOW_FOCUS_ONLY, null, null, null, -1, null); Loading Loading @@ -4459,9 +4446,6 @@ public class InputMethodManagerService extends IInputMethodManager.Stub private void handleSetInteractive(final boolean interactive) { synchronized (mMethodMap) { mIsInteractive = interactive; if (!interactive) { mCurClientNeedStartInput = true; } updateSystemUiLocked(interactive ? mImeWindowVis : 0, mBackDisposition); // Inform the current client of the change in active status Loading