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
This commit is contained in:
Ming-Shin Lu
2021-06-01 00:11:19 +08:00
parent 2c52d52f6d
commit ea8a3cd5d5
6 changed files with 33 additions and 15 deletions

View File

@@ -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) {
}
};

View File

@@ -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));
}
}

View File

@@ -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() {

View File

@@ -243,7 +243,7 @@ public final class MultiClientInputMethodManagerService {
}
@Override
public void updateImeWindowStatus() {
public void updateImeWindowStatus(boolean disableImeIcon) {
}
});
}

View File

@@ -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 */);
}
/**

View File

@@ -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*/);