Merge "Fix hiding keyboard animation stuck while dialog dismissing." into rvc-dev am: dac09ee7fe am: 0a49dd38a2 am: 869a1892db
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/12174530 Change-Id: Iac68c18c16c10c794e1f462ccaedeed656fc6a5b
This commit is contained in:
@@ -125,10 +125,10 @@ public final class ImeFocusController {
|
|||||||
final View viewForWindowFocus = focusedView != null ? focusedView : mViewRootImpl.mView;
|
final View viewForWindowFocus = focusedView != null ? focusedView : mViewRootImpl.mView;
|
||||||
onViewFocusChanged(viewForWindowFocus, true);
|
onViewFocusChanged(viewForWindowFocus, true);
|
||||||
|
|
||||||
// Starting new input when the next focused view is same as served view but the
|
// Starting new input when the next focused view is same as served view but the currently
|
||||||
// editor is not aligned with the same editor or editor is inactive.
|
// active connection (if any) is not associated with it.
|
||||||
final boolean nextFocusIsServedView = mServedView != null && mServedView == focusedView;
|
final boolean nextFocusIsServedView = mServedView == viewForWindowFocus;
|
||||||
if (nextFocusIsServedView && !immDelegate.isSameEditorAndAcceptingText(focusedView)) {
|
if (nextFocusIsServedView && !immDelegate.hasActiveConnection(viewForWindowFocus)) {
|
||||||
forceFocus = true;
|
forceFocus = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -254,7 +254,7 @@ public final class ImeFocusController {
|
|||||||
void setCurrentRootView(ViewRootImpl rootView);
|
void setCurrentRootView(ViewRootImpl rootView);
|
||||||
boolean isCurrentRootView(ViewRootImpl rootView);
|
boolean isCurrentRootView(ViewRootImpl rootView);
|
||||||
boolean isRestartOnNextWindowFocus(boolean reset);
|
boolean isRestartOnNextWindowFocus(boolean reset);
|
||||||
boolean isSameEditorAndAcceptingText(View view);
|
boolean hasActiveConnection(View view);
|
||||||
}
|
}
|
||||||
|
|
||||||
public View getServedView() {
|
public View getServedView() {
|
||||||
|
|||||||
@@ -19,8 +19,8 @@ package android.view.inputmethod;
|
|||||||
import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
|
import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
|
||||||
import static android.Manifest.permission.WRITE_SECURE_SETTINGS;
|
import static android.Manifest.permission.WRITE_SECURE_SETTINGS;
|
||||||
|
|
||||||
import static com.android.internal.inputmethod.StartInputReason.WINDOW_FOCUS_GAIN_REPORT_WITHOUT_EDITOR;
|
import static com.android.internal.inputmethod.StartInputReason.WINDOW_FOCUS_GAIN_REPORT_WITHOUT_CONNECTION;
|
||||||
import static com.android.internal.inputmethod.StartInputReason.WINDOW_FOCUS_GAIN_REPORT_WITH_SAME_EDITOR;
|
import static com.android.internal.inputmethod.StartInputReason.WINDOW_FOCUS_GAIN_REPORT_WITH_CONNECTION;
|
||||||
|
|
||||||
import android.annotation.DrawableRes;
|
import android.annotation.DrawableRes;
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
@@ -89,6 +89,7 @@ import com.android.internal.view.InputBindResult;
|
|||||||
|
|
||||||
import java.io.FileDescriptor;
|
import java.io.FileDescriptor;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
import java.lang.reflect.Proxy;
|
import java.lang.reflect.Proxy;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@@ -610,14 +611,13 @@ public final class InputMethodManager {
|
|||||||
@Override
|
@Override
|
||||||
public void startInputAsyncOnWindowFocusGain(View focusedView,
|
public void startInputAsyncOnWindowFocusGain(View focusedView,
|
||||||
@SoftInputModeFlags int softInputMode, int windowFlags, boolean forceNewFocus) {
|
@SoftInputModeFlags int softInputMode, int windowFlags, boolean forceNewFocus) {
|
||||||
final boolean forceNewFocus1 = forceNewFocus;
|
|
||||||
final int startInputFlags = getStartInputFlags(focusedView, 0);
|
final int startInputFlags = getStartInputFlags(focusedView, 0);
|
||||||
|
|
||||||
final ImeFocusController controller = getFocusController();
|
final ImeFocusController controller = getFocusController();
|
||||||
if (controller == null) {
|
if (controller == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (controller.checkFocus(forceNewFocus1, false)) {
|
if (controller.checkFocus(forceNewFocus, false)) {
|
||||||
// We need to restart input on the current focus view. This
|
// We need to restart input on the current focus view. This
|
||||||
// should be done in conjunction with telling the system service
|
// should be done in conjunction with telling the system service
|
||||||
// about the window gaining focus, to help make the transition
|
// about the window gaining focus, to help make the transition
|
||||||
@@ -633,15 +633,15 @@ public final class InputMethodManager {
|
|||||||
// we'll just do a window focus gain and call it a day.
|
// we'll just do a window focus gain and call it a day.
|
||||||
try {
|
try {
|
||||||
View servedView = controller.getServedView();
|
View servedView = controller.getServedView();
|
||||||
boolean nextFocusSameEditor = servedView != null && servedView == focusedView
|
boolean nextFocusHasConnection = servedView != null && servedView == focusedView
|
||||||
&& isSameEditorAndAcceptingText(focusedView);
|
&& hasActiveConnection(focusedView);
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.v(TAG, "Reporting focus gain, without startInput"
|
Log.v(TAG, "Reporting focus gain, without startInput"
|
||||||
+ ", nextFocusIsServedView=" + nextFocusSameEditor);
|
+ ", nextFocusIsServedView=" + nextFocusHasConnection);
|
||||||
}
|
}
|
||||||
final int startInputReason =
|
final int startInputReason =
|
||||||
nextFocusSameEditor ? WINDOW_FOCUS_GAIN_REPORT_WITH_SAME_EDITOR
|
nextFocusHasConnection ? WINDOW_FOCUS_GAIN_REPORT_WITH_CONNECTION
|
||||||
: WINDOW_FOCUS_GAIN_REPORT_WITHOUT_EDITOR;
|
: WINDOW_FOCUS_GAIN_REPORT_WITHOUT_CONNECTION;
|
||||||
mService.startInputOrWindowGainedFocus(
|
mService.startInputOrWindowGainedFocus(
|
||||||
startInputReason, mClient,
|
startInputReason, mClient,
|
||||||
focusedView.getWindowToken(), startInputFlags, softInputMode,
|
focusedView.getWindowToken(), startInputFlags, softInputMode,
|
||||||
@@ -701,33 +701,24 @@ public final class InputMethodManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For {@link ImeFocusController} to check if the given focused view aligns with the same
|
* Checks whether the active input connection (if any) is for the given view.
|
||||||
* editor and the editor is active to accept the text input.
|
|
||||||
*
|
*
|
||||||
* TODO(b/160968797): Remove this method and move mCurrentTextBoxAttritube to
|
* TODO(b/160968797): Remove this method and move mServedInputConnectionWrapper to
|
||||||
* ImeFocusController.
|
* 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
|
* Note that this method is only intended for restarting input after focus gain
|
||||||
* (e.g. b/160391516), DO NOT leverage this method to do another check.
|
* (e.g. b/160391516), DO NOT leverage this method to do another check.
|
||||||
*/
|
*/
|
||||||
public boolean isSameEditorAndAcceptingText(View view) {
|
@Override
|
||||||
|
public boolean hasActiveConnection(View view) {
|
||||||
synchronized (mH) {
|
synchronized (mH) {
|
||||||
if (!hasServedByInputMethodLocked(view) || mCurrentTextBoxAttribute == null) {
|
if (!hasServedByInputMethodLocked(view)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
final EditorInfo ic = mCurrentTextBoxAttribute;
|
return mServedInputConnectionWrapper != null
|
||||||
// This sameEditor checking is based on using object hash comparison to check if
|
&& mServedInputConnectionWrapper.isActive()
|
||||||
// some fields of the current EditorInfo (e.g. autoFillId, OpPackageName) the
|
&& mServedInputConnectionWrapper.mServedView.get() == view;
|
||||||
// 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();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -980,11 +971,13 @@ public final class InputMethodManager {
|
|||||||
|
|
||||||
private static class ControlledInputConnectionWrapper extends IInputConnectionWrapper {
|
private static class ControlledInputConnectionWrapper extends IInputConnectionWrapper {
|
||||||
private final InputMethodManager mParentInputMethodManager;
|
private final InputMethodManager mParentInputMethodManager;
|
||||||
|
private final WeakReference<View> mServedView;
|
||||||
|
|
||||||
public ControlledInputConnectionWrapper(final Looper mainLooper, final InputConnection conn,
|
ControlledInputConnectionWrapper(Looper mainLooper, InputConnection conn,
|
||||||
final InputMethodManager inputMethodManager) {
|
InputMethodManager inputMethodManager, View servedView) {
|
||||||
super(mainLooper, conn);
|
super(mainLooper, conn);
|
||||||
mParentInputMethodManager = inputMethodManager;
|
mParentInputMethodManager = inputMethodManager;
|
||||||
|
mServedView = new WeakReference<>(servedView);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -1007,6 +1000,7 @@ public final class InputMethodManager {
|
|||||||
+ "connection=" + getInputConnection()
|
+ "connection=" + getInputConnection()
|
||||||
+ " finished=" + isFinished()
|
+ " finished=" + isFinished()
|
||||||
+ " mParentInputMethodManager.mActive=" + mParentInputMethodManager.mActive
|
+ " mParentInputMethodManager.mActive=" + mParentInputMethodManager.mActive
|
||||||
|
+ " mServedView=" + mServedView.get()
|
||||||
+ "}";
|
+ "}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1187,7 +1181,8 @@ public final class InputMethodManager {
|
|||||||
mMainLooper = looper;
|
mMainLooper = looper;
|
||||||
mH = new H(looper);
|
mH = new H(looper);
|
||||||
mDisplayId = displayId;
|
mDisplayId = displayId;
|
||||||
mIInputContext = new ControlledInputConnectionWrapper(looper, mDummyInputConnection, this);
|
mIInputContext = new ControlledInputConnectionWrapper(looper, mDummyInputConnection, this,
|
||||||
|
null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1968,7 +1963,7 @@ public final class InputMethodManager {
|
|||||||
icHandler = ic.getHandler();
|
icHandler = ic.getHandler();
|
||||||
}
|
}
|
||||||
servedContext = new ControlledInputConnectionWrapper(
|
servedContext = new ControlledInputConnectionWrapper(
|
||||||
icHandler != null ? icHandler.getLooper() : vh.getLooper(), ic, this);
|
icHandler != null ? icHandler.getLooper() : vh.getLooper(), ic, this, view);
|
||||||
} else {
|
} else {
|
||||||
servedContext = null;
|
servedContext = null;
|
||||||
missingMethodFlags = 0;
|
missingMethodFlags = 0;
|
||||||
|
|||||||
@@ -46,10 +46,10 @@ public final class InputMethodDebug {
|
|||||||
return "UNSPECIFIED";
|
return "UNSPECIFIED";
|
||||||
case StartInputReason.WINDOW_FOCUS_GAIN:
|
case StartInputReason.WINDOW_FOCUS_GAIN:
|
||||||
return "WINDOW_FOCUS_GAIN";
|
return "WINDOW_FOCUS_GAIN";
|
||||||
case StartInputReason.WINDOW_FOCUS_GAIN_REPORT_WITH_SAME_EDITOR:
|
case StartInputReason.WINDOW_FOCUS_GAIN_REPORT_WITH_CONNECTION:
|
||||||
return "WINDOW_FOCUS_GAIN_REPORT_WITH_SAME_EDITOR";
|
return "WINDOW_FOCUS_GAIN_REPORT_WITH_CONNECTION";
|
||||||
case StartInputReason.WINDOW_FOCUS_GAIN_REPORT_WITHOUT_EDITOR:
|
case StartInputReason.WINDOW_FOCUS_GAIN_REPORT_WITHOUT_CONNECTION:
|
||||||
return "WINDOW_FOCUS_GAIN_REPORT_WITHOUT_EDITOR";
|
return "WINDOW_FOCUS_GAIN_REPORT_WITHOUT_CONNECTION";
|
||||||
case StartInputReason.APP_CALLED_RESTART_INPUT_API:
|
case StartInputReason.APP_CALLED_RESTART_INPUT_API:
|
||||||
return "APP_CALLED_RESTART_INPUT_API";
|
return "APP_CALLED_RESTART_INPUT_API";
|
||||||
case StartInputReason.CHECK_FOCUS:
|
case StartInputReason.CHECK_FOCUS:
|
||||||
|
|||||||
@@ -30,8 +30,8 @@ import java.lang.annotation.Retention;
|
|||||||
@IntDef(value = {
|
@IntDef(value = {
|
||||||
StartInputReason.UNSPECIFIED,
|
StartInputReason.UNSPECIFIED,
|
||||||
StartInputReason.WINDOW_FOCUS_GAIN,
|
StartInputReason.WINDOW_FOCUS_GAIN,
|
||||||
StartInputReason.WINDOW_FOCUS_GAIN_REPORT_WITH_SAME_EDITOR,
|
StartInputReason.WINDOW_FOCUS_GAIN_REPORT_WITH_CONNECTION,
|
||||||
StartInputReason.WINDOW_FOCUS_GAIN_REPORT_WITHOUT_EDITOR,
|
StartInputReason.WINDOW_FOCUS_GAIN_REPORT_WITHOUT_CONNECTION,
|
||||||
StartInputReason.APP_CALLED_RESTART_INPUT_API,
|
StartInputReason.APP_CALLED_RESTART_INPUT_API,
|
||||||
StartInputReason.CHECK_FOCUS,
|
StartInputReason.CHECK_FOCUS,
|
||||||
StartInputReason.BOUND_TO_IMMS,
|
StartInputReason.BOUND_TO_IMMS,
|
||||||
@@ -54,13 +54,13 @@ public @interface StartInputReason {
|
|||||||
* view and its input connection remains. {@link android.view.inputmethod.InputMethodManager}
|
* 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.
|
* just reports this window focus change event to sync IME input target for system.
|
||||||
*/
|
*/
|
||||||
int WINDOW_FOCUS_GAIN_REPORT_WITH_SAME_EDITOR = 2;
|
int WINDOW_FOCUS_GAIN_REPORT_WITH_CONNECTION = 2;
|
||||||
/**
|
/**
|
||||||
* {@link android.view.Window} gained focus but there is no {@link android.view.View} that is
|
* {@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
|
* eligible to have IME focus. {@link android.view.inputmethod.InputMethodManager} just reports
|
||||||
* this window focus change event for logging.
|
* this window focus change event for logging.
|
||||||
*/
|
*/
|
||||||
int WINDOW_FOCUS_GAIN_REPORT_WITHOUT_EDITOR = 3;
|
int WINDOW_FOCUS_GAIN_REPORT_WITHOUT_CONNECTION = 3;
|
||||||
/**
|
/**
|
||||||
* {@link android.view.inputmethod.InputMethodManager#restartInput(android.view.View)} is
|
* {@link android.view.inputmethod.InputMethodManager#restartInput(android.view.View)} is
|
||||||
* either explicitly called by the application or indirectly called by some Framework class
|
* either explicitly called by the application or indirectly called by some Framework class
|
||||||
|
|||||||
Reference in New Issue
Block a user