Merge "Clear IMM#mCurRootView when needed" into udc-dev

This commit is contained in:
Adrian Roos
2023-04-26 08:25:15 +00:00
committed by Android (Google) Code Review
3 changed files with 67 additions and 7 deletions

View File

@@ -3783,6 +3783,7 @@ package android.view.inputmethod {
method @NonNull @RequiresPermission(value=android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, conditional=true) public java.util.List<android.view.inputmethod.InputMethodInfo> getInputMethodListAsUser(int);
method public boolean hasActiveInputConnection(@Nullable android.view.View);
method @RequiresPermission(android.Manifest.permission.TEST_INPUT_METHOD) public boolean hasPendingImeVisibilityRequests();
method @RequiresPermission(android.Manifest.permission.TEST_INPUT_METHOD) public boolean isCurrentRootView(@NonNull android.view.View);
method @RequiresPermission(android.Manifest.permission.TEST_INPUT_METHOD) public boolean isInputMethodPickerShown();
method @RequiresPermission(android.Manifest.permission.TEST_INPUT_METHOD) public void setStylusWindowIdleTimeoutForTest(long);
field public static final long CLEAR_SHOW_FORCED_FLAG_WHEN_LEAVING = 214016041L; // 0xcc1a029L

View File

@@ -86,9 +86,12 @@ public final class ImeFocusController {
void onPreWindowFocus(boolean hasWindowFocus, WindowManager.LayoutParams windowAttribute) {
mHasImeFocus = WindowManager.LayoutParams.mayUseInputMethod(windowAttribute.flags);
if (!hasWindowFocus || !mHasImeFocus || isInLocalFocusMode(windowAttribute)) {
return;
if (!hasWindowFocus) {
getImmDelegate().onWindowLostFocus(mViewRootImpl);
}
} else {
getImmDelegate().onPreWindowGainedFocus(mViewRootImpl);
}
getImmDelegate().onPreWindowGainedFocus(mViewRootImpl);
}
@UiThread
@@ -163,6 +166,7 @@ public final class ImeFocusController {
void onPreWindowGainedFocus(ViewRootImpl viewRootImpl);
void onPostWindowGainedFocus(View viewForWindowFocus,
@NonNull WindowManager.LayoutParams windowAttribute);
void onWindowLostFocus(@NonNull ViewRootImpl viewRootImpl);
void onViewFocusChanged(@NonNull View view, boolean hasFocus);
void onScheduledCheckFocus(@NonNull ViewRootImpl viewRootImpl);
void onViewDetachedFromWindow(View view, ViewRootImpl viewRootImpl);

View File

@@ -482,12 +482,20 @@ public final class InputMethodManager {
private View mNextServedView;
/**
* This is the root view of the overall window that currently has input
* method focus.
* The latest {@link ViewRootImpl} that has, or most recently had, input method focus.
*
* <p>This value will be cleared when it becomes inactive and no longer has window focus.
*/
@Nullable
@GuardedBy("mH")
ViewRootImpl mCurRootView;
/**
* Whether the {@link #mCurRootView} currently has window focus.
*/
@GuardedBy("mH")
boolean mCurRootViewWindowFocused;
/**
* This is set when we are in the process of connecting, to determine
* when we have actually finished.
@@ -745,6 +753,7 @@ public final class InputMethodManager {
public void onPreWindowGainedFocus(ViewRootImpl viewRootImpl) {
synchronized (mH) {
setCurrentRootViewLocked(viewRootImpl);
mCurRootViewWindowFocused = true;
}
}
@@ -821,6 +830,17 @@ public final class InputMethodManager {
}
}
@Override
public void onWindowLostFocus(@NonNull ViewRootImpl viewRootImpl) {
synchronized (mH) {
if (mCurRootView == viewRootImpl) {
mCurRootViewWindowFocused = false;
clearCurRootViewIfNeeded();
}
}
}
@Override
public void onViewFocusChanged(@Nullable View view, boolean hasFocus) {
onViewFocusChangedInternal(view, hasFocus);
@@ -1114,6 +1134,10 @@ public final class InputMethodManager {
// Note that finishComposingText() is allowed to run
// even when we are not active.
mFallbackInputConnection.finishComposingTextFromImm();
if (clearCurRootViewIfNeeded()) {
return;
}
}
// Check focus again in case that "onWindowFocus" is called before
// handling this message.
@@ -1756,8 +1780,7 @@ public final class InputMethodManager {
}
/**
* Return true if the given view is the currently active view for the
* input method.
* Return {@code true} if the given view is the currently active view for the input method.
*/
public boolean isActive(View view) {
// Re-dispatch if there is a context mismatch.
@@ -1773,7 +1796,7 @@ public final class InputMethodManager {
}
/**
* Return true if any view is currently active in the input method.
* Return {@code true} if any view is currently active for the input method.
*/
public boolean isActive() {
checkFocus();
@@ -1782,6 +1805,20 @@ public final class InputMethodManager {
}
}
/**
* Returns {@code true} if the given view's {@link ViewRootImpl} is the currently active one
* for the {@code InputMethodManager}.
*
* @hide
*/
@TestApi
@RequiresPermission(Manifest.permission.TEST_INPUT_METHOD)
public boolean isCurrentRootView(@NonNull View attachedView) {
synchronized (mH) {
return mCurRootView == attachedView.getViewRootImpl();
}
}
/**
* Return {@code true} if the currently served view is accepting full text edits.
* If {@code false}, it has no input connection, so it can only handle raw key events.
@@ -1908,6 +1945,24 @@ public final class InputMethodManager {
mImeDispatcher.clear();
}
/**
* Clears the {@link #mCurRootView} if it's no longer window focused and the connection is
* no longer active.
*
* @return {@code} true iff it was cleared.
*/
@GuardedBy("mH")
private boolean clearCurRootViewIfNeeded() {
if (!mActive && !mCurRootViewWindowFocused) {
finishInputLocked();
mDelegate.setCurrentRootViewLocked(null);
return true;
}
return false;
}
public void displayCompletions(View view, CompletionInfo[] completions) {
// Re-dispatch if there is a context mismatch.
final InputMethodManager fallbackImm = getFallbackInputMethodManagerIfNecessary(view);