Consolidate ImeAwareEditText#scheduleShowSoftInput (1/2)

As InputMethodManager#isActive(View) may not always predictable as
reality since the method only check if the given view has been aligned
with the current served view, but not consider if the view has an active
input connection.

Test flakiness may happen when verifying showSoftInput should be invoked
after onStartInput but the event stream shows the reversed sequence.

Consolidate scheduleShowSoftInput by checking
IMM#hasActiveInputConnection to make sure showSoftInput request should
invoked after the input connection activated by the given focus view.

Bug: 176697749
Test: atest --iterations 100 KeyboardVisibilityControlTest#\
      testImeInvisibleWhenForceStopPkgProcess_Full
Change-Id: I466a93e2b4706ae809ac50dc16dc8e4ffa7c2f1c
This commit is contained in:
Ming-Shin Lu
2021-02-01 13:42:32 +08:00
parent c304c1624d
commit 8bcce88c86
3 changed files with 14 additions and 2 deletions

View File

@@ -2568,6 +2568,7 @@ package android.view.inputmethod {
public final class InputMethodManager {
method public int getDisplayId();
method public boolean hasActiveInputConnection(@Nullable android.view.View);
method public boolean isInputMethodPickerShown();
}

View File

@@ -749,7 +749,7 @@ public final class InputMethodManager {
@Override
public boolean hasActiveConnection(View view) {
synchronized (mH) {
if (!hasServedByInputMethodLocked(view)) {
if (!hasServedByInputMethodLocked(view) || mCurMethod == null) {
return false;
}
@@ -765,6 +765,17 @@ public final class InputMethodManager {
return mDelegate;
}
/**
* Checks whether the active input connection (if any) is for the given view.
*
* @hide
* @see ImeFocusController#getImmDelegate()#hasActiveInputConnection(View)
*/
@TestApi
public boolean hasActiveInputConnection(@Nullable View view) {
return mDelegate.hasActiveConnection(view);
}
private View getServedViewLocked() {
return mCurRootView != null ? mCurRootView.getImeFocusController().getServedView() : null;
}

View File

@@ -80,7 +80,7 @@ public class ImeAwareEditText extends EditText {
public void scheduleShowSoftInput() {
final InputMethodManager imm = getContext().getSystemService(InputMethodManager.class);
if (imm.isActive(this)) {
if (imm.hasActiveInputConnection(this)) {
// This means that ImeAwareEditText is already connected to the IME.
// InputMethodManager#showSoftInput() is guaranteed to pass client-side focus check.
mHasPendingShowSoftInputRequest = false;