From ea8a3cd5d5387837892adc0e16cb2eaf485dfdbe Mon Sep 17 00:00:00 2001 From: Ming-Shin Lu Date: Tue, 1 Jun 2021 00:11:19 +0800 Subject: [PATCH] Fix IME icon flicker when switching apps - Add disableImeIcon parameter in IMMSInternal#updateImeWindowStatus to disable back icon & IME switch icon in navigation bar for RecentsAnimatinController when task switching happens. - Fix IME icon flickering when invoking hideInputMethodMenuLocked during unbind current client, ensure updating IME icon only when the IME picker dialog exists. Fix: 189282303 Test: manual as below steps: 1) Launch an app with shown IME 2) Swipe out the app to the launcher, make sure IME icon didn't flicker when going to launcher. 3) Launch step 1) app again, swipe-up to recents, make sure IME icon didn't flicker when going to recents 4) Launch step 1) app again, swipe left or right to the next app task without showing IME. 5) Make sure IME icon didn't flicker when going to the next app. Change-Id: Ib55db60c29abf5b389ad60bfa56e5e8fb2c75f1f --- .../inputmethod/InputMethodManagerInternal.java | 6 ++++-- .../inputmethod/InputMethodManagerService.java | 17 ++++++++++------- .../inputmethod/InputMethodMenuController.java | 8 ++++---- .../MultiClientInputMethodManagerService.java | 2 +- .../android/server/wm/KeyguardController.java | 2 +- .../server/wm/RecentsAnimationController.java | 13 +++++++++++++ 6 files changed, 33 insertions(+), 15 deletions(-) diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerInternal.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerInternal.java index bfb9db8281318..9d80b9c8b93e9 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodManagerInternal.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerInternal.java @@ -126,8 +126,10 @@ public abstract class InputMethodManagerInternal { /** * Updates the IME visibility, back disposition and show IME picker status for SystemUI. + * TODO(b/189923292): Making SystemUI to be true IME icon controller vs. presenter that + * controlled by IMMS. */ - public abstract void updateImeWindowStatus(); + public abstract void updateImeWindowStatus(boolean disableImeIcon); /** * Fake implementation of {@link InputMethodManagerInternal}. All the methods do nothing. @@ -182,7 +184,7 @@ public abstract class InputMethodManagerInternal { } @Override - public void updateImeWindowStatus() { + public void updateImeWindowStatus(boolean disableImeIcon) { } }; diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java index a0004a075cb78..89aabe05b8fbd 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java @@ -2861,9 +2861,13 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } } - private void updateImeWindowStatus() { + private void updateImeWindowStatus(boolean disableImeIcon) { synchronized (mMethodMap) { - updateSystemUiLocked(); + if (disableImeIcon) { + updateSystemUiLocked(0, mBackDisposition); + } else { + updateSystemUiLocked(); + } } } @@ -4412,9 +4416,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub return true; } case MSG_UPDATE_IME_WINDOW_STATUS: { - synchronized (mMethodMap) { - updateSystemUiLocked(); - } + updateImeWindowStatus(msg.arg1 == 1); return true; } // --------------------------------------------------------- @@ -5084,9 +5086,10 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } @Override - public void updateImeWindowStatus() { + public void updateImeWindowStatus(boolean disableImeIcon) { mService.mHandler.sendMessage( - mService.mHandler.obtainMessage(MSG_UPDATE_IME_WINDOW_STATUS)); + mService.mHandler.obtainMessage(MSG_UPDATE_IME_WINDOW_STATUS, + disableImeIcon ? 1 : 0, 0)); } } diff --git a/services/core/java/com/android/server/inputmethod/InputMethodMenuController.java b/services/core/java/com/android/server/inputmethod/InputMethodMenuController.java index 403187bb53ff1..73baf79ea4b1c 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodMenuController.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodMenuController.java @@ -261,11 +261,11 @@ public class InputMethodMenuController { mSwitchingDialog.dismiss(); mSwitchingDialog = null; mSwitchingDialogTitleView = null; - } - mService.updateSystemUiLocked(); - mDialogBuilder = null; - mIms = null; + mService.updateSystemUiLocked(); + mDialogBuilder = null; + mIms = null; + } } HardKeyboardListener getHardKeyboardListener() { diff --git a/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java index 9275c563401a6..c97338ade7e86 100644 --- a/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java @@ -243,7 +243,7 @@ public final class MultiClientInputMethodManagerService { } @Override - public void updateImeWindowStatus() { + public void updateImeWindowStatus(boolean disableImeIcon) { } }); } diff --git a/services/core/java/com/android/server/wm/KeyguardController.java b/services/core/java/com/android/server/wm/KeyguardController.java index df4f2a91a8a5d..0112f797d9379 100644 --- a/services/core/java/com/android/server/wm/KeyguardController.java +++ b/services/core/java/com/android/server/wm/KeyguardController.java @@ -192,7 +192,7 @@ class KeyguardController { // state when evaluating visibilities. updateKeyguardSleepToken(); mRootWindowContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS); - InputMethodManagerInternal.get().updateImeWindowStatus(); + InputMethodManagerInternal.get().updateImeWindowStatus(false /* disableImeIcon */); } /** diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java index 2feb8a7439304..dcb4d60e31259 100644 --- a/services/core/java/com/android/server/wm/RecentsAnimationController.java +++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java @@ -303,6 +303,13 @@ public class RecentsAnimationController implements DeathRecipient { inputMethodManagerInternal.hideCurrentInputMethod( SoftInputShowHideReason.HIDE_RECENTS_ANIMATION); } + } else { + // Disable IME icon explicitly when IME attached to the app in case + // IME icon might flickering while swiping to the next app task still + // in animating before the next app window focused, or IME icon + // persists on the bottom when swiping the task to recents. + InputMethodManagerInternal.get().updateImeWindowStatus( + true /* disableImeIcon */); } } mService.mWindowPlacerLocked.requestTraversal(); @@ -923,6 +930,12 @@ public class RecentsAnimationController implements DeathRecipient { mRecentScreenshotAnimator = null; } + // Restore IME icon only when moving the original app task to front from recents, in case + // IME icon may missing if the moving task has already been the current focused task. + if (reorderMode == REORDER_MOVE_TO_ORIGINAL_POSITION && !mIsAddingTaskToTargets) { + InputMethodManagerInternal.get().updateImeWindowStatus(false /* disableImeIcon */); + } + // Update the input windows after the animation is complete final InputMonitor inputMonitor = mDisplayContent.getInputMonitor(); inputMonitor.updateInputWindowsLw(true /*force*/);