From 0135405ed5a7832aada2195ff777b67d67738fde Mon Sep 17 00:00:00 2001 From: Yohei Yukawa Date: Tue, 18 Oct 2022 11:29:21 -0700 Subject: [PATCH] Let IMM directly call checkFocusInternal() when possible With this CL, the code paths from IMM#checkFocus() will be drastically simplified as follows. * Before InputMethodManager#checkFocus() -> ImeFocusController#checkFocus() -> InputMethodManager.DelegateImpl#checkFocus() -> InputMethodManager#checkFocusInternal() * After InputMethodManager#checkFocus() -> InputMethodManager#checkFocusInternal() In the end, InputMethodManager.DelegateImpl#checkFocus() is guaranteed to be called only from ViewRootImpl. This is still mechanical refactoring. There must be no observable behavior change. Bug: 234882948 Test: presubmit Change-Id: Ie1c7525ee46db11ccd593c6ed0ac17b4ece41953 --- .../java/android/view/ImeFocusController.java | 6 +-- .../view/inputmethod/InputMethodManager.java | 42 +++++++++---------- 2 files changed, 22 insertions(+), 26 deletions(-) diff --git a/core/java/android/view/ImeFocusController.java b/core/java/android/view/ImeFocusController.java index 4de7c4fdd5134..2aa91bfb18257 100644 --- a/core/java/android/view/ImeFocusController.java +++ b/core/java/android/view/ImeFocusController.java @@ -110,8 +110,8 @@ public final class ImeFocusController { /** * @see InputMethodManager#checkFocus() */ - public boolean checkFocus(boolean forceNewFocus, boolean startInput) { - return getImmDelegate().checkFocus(forceNewFocus, startInput, mViewRootImpl); + void checkFocus(boolean forceNewFocus, boolean startInput) { + getImmDelegate().checkFocus(forceNewFocus, startInput, mViewRootImpl); } @UiThread @@ -163,7 +163,7 @@ public final class ImeFocusController { void onPostWindowGainedFocus(View viewForWindowFocus, @NonNull WindowManager.LayoutParams windowAttribute); void onViewFocusChanged(@NonNull View view, boolean hasFocus); - boolean checkFocus(boolean forceNewFocus, boolean startInput, ViewRootImpl viewRootImpl); + void checkFocus(boolean forceNewFocus, boolean startInput, ViewRootImpl viewRootImpl); void onViewDetachedFromWindow(View view, ViewRootImpl viewRootImpl); void onWindowDismissed(ViewRootImpl viewRootImpl); } diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java index 7840d4cacc255..cd19db4a6d46f 100644 --- a/core/java/android/view/inputmethod/InputMethodManager.java +++ b/core/java/android/view/inputmethod/InputMethodManager.java @@ -777,12 +777,12 @@ public final class InputMethodManager { "InputMethodManager.DelegateImpl#startInputAsyncOnWindowFocusGain", InputMethodManager.this, null /* icProto */); - final ImeFocusController controller = getFocusController(); - if (controller == null) { - return; - } - + final ViewRootImpl viewRootImpl; synchronized (mH) { + if (mCurRootView == null) { + return; + } + viewRootImpl = mCurRootView; if (mRestartOnNextWindowFocus) { if (DEBUG) Log.v(TAG, "Restarting due to mRestartOnNextWindowFocus as true"); mRestartOnNextWindowFocus = false; @@ -790,7 +790,7 @@ public final class InputMethodManager { } } - if (controller.checkFocus(forceNewFocus, false)) { + if (checkFocusInternal(forceNewFocus, false, viewRootImpl)) { // We need to restart input on the current focus view. This // should be done in conjunction with telling the system service // about the window gaining focus, to help make the transition @@ -832,9 +832,9 @@ public final class InputMethodManager { } @Override - public boolean checkFocus(boolean forceNewFocus, boolean startInput, + public void checkFocus(boolean forceNewFocus, boolean startInput, ViewRootImpl viewRootImpl) { - return checkFocusInternal(forceNewFocus, startInput, viewRootImpl); + checkFocusInternal(forceNewFocus, startInput, viewRootImpl); } @Override @@ -931,15 +931,6 @@ public final class InputMethodManager { return mCurRootView != null ? mNextServedView : null; } - private ImeFocusController getFocusController() { - synchronized (mH) { - if (mCurRootView != null) { - return mCurRootView.getImeFocusController(); - } - return null; - } - } - /** * Returns {@code true} when the given view has been served by Input Method. */ @@ -1122,8 +1113,7 @@ public final class InputMethodManager { if (mCurRootView == null) { return; } - if (!mCurRootView.getImeFocusController().checkFocus( - mRestartOnNextWindowFocus, false)) { + if (!checkFocusInternal(mRestartOnNextWindowFocus, false, mCurRootView)) { return; } final int reason = active ? StartInputReason.ACTIVATED_BY_IMMS @@ -2667,19 +2657,25 @@ public final class InputMethodManager { } /** - * Check the next served view from {@link ImeFocusController} if needs to start input. * Note that this method should *NOT* be called inside of {@code mH} lock to prevent start input * background thread may blocked by other methods which already inside {@code mH} lock. * @hide */ @UnsupportedAppUsage public void checkFocus() { - final ImeFocusController controller = getFocusController(); - if (controller != null) { - controller.checkFocus(false /* forceNewFocus */, true /* startInput */); + final ViewRootImpl viewRootImpl; + synchronized (mH) { + if (mCurRootView == null) { + return; + } + viewRootImpl = mCurRootView; } + checkFocusInternal(false /* forceNewFocus */, true /* startInput */, viewRootImpl); } + /** + * Check the next served view if needs to start input. + */ private boolean checkFocusInternal(boolean forceNewFocus, boolean startInput, ViewRootImpl viewRootImpl) { synchronized (mH) {