Restore the last IME visiblity of the app window when allowed
Since when bring an existing app task to foreground or quick switching
app task with gesture navigation will first see the task snapshot
during app transition,
If the task previously focused and shown IME, even the task may hide
IME when switching to the next task, As the goal of
go/ime-transition-improve-s mentioned, if the task is still focused by
editor, we should keep the original focused IME shown and keep
the input connection focused state when navigating back to the
original task.
Bug: 166736352
Test: atest CtsInputMethodTestcases
Test: manual by focusing app with an editor to show keyboard,
switch the app task to the next with gesture nav and then
switched back, expected the soft-keyboard is still shown.
Change-Id: I63b144bed6c37569d79fba1c2b63dd4f1074f0f6
This commit is contained in:
@@ -116,8 +116,9 @@ public final class ImeFocusController {
|
||||
if (!hasWindowFocus || !mHasImeFocus || isInLocalFocusMode(windowAttribute)) {
|
||||
return;
|
||||
}
|
||||
View viewForWindowFocus = focusedView != null ? focusedView : mViewRootImpl.mView;
|
||||
if (DEBUG) {
|
||||
Log.v(TAG, "onWindowFocus: " + focusedView
|
||||
Log.v(TAG, "onWindowFocus: " + viewForWindowFocus
|
||||
+ " softInputMode=" + InputMethodDebug.softInputModeToString(
|
||||
windowAttribute.softInputMode));
|
||||
}
|
||||
@@ -128,8 +129,8 @@ public final class ImeFocusController {
|
||||
if (DEBUG) Log.v(TAG, "Restarting due to isRestartOnNextWindowFocus as true");
|
||||
forceFocus = true;
|
||||
}
|
||||
|
||||
// Update mNextServedView when focusedView changed.
|
||||
final View viewForWindowFocus = focusedView != null ? focusedView : mViewRootImpl.mView;
|
||||
onViewFocusChanged(viewForWindowFocus, true);
|
||||
|
||||
// Starting new input when the next focused view is same as served view but the currently
|
||||
|
||||
@@ -228,6 +228,8 @@ public final class InputMethodDebug {
|
||||
return "HIDE_SAME_WINDOW_FOCUSED_WITHOUT_EDITOR";
|
||||
case SoftInputShowHideReason.HIDE_REMOVE_CLIENT:
|
||||
return "HIDE_REMOVE_CLIENT";
|
||||
case SoftInputShowHideReason.SHOW_RESTORE_IME_VISIBILITY:
|
||||
return "SHOW_RESTORE_IME_VISIBILITY";
|
||||
default:
|
||||
return "Unknown=" + reason;
|
||||
}
|
||||
|
||||
@@ -49,7 +49,8 @@ import java.lang.annotation.Retention;
|
||||
SoftInputShowHideReason.HIDE_RECENTS_ANIMATION,
|
||||
SoftInputShowHideReason.HIDE_BUBBLES,
|
||||
SoftInputShowHideReason.HIDE_SAME_WINDOW_FOCUSED_WITHOUT_EDITOR,
|
||||
SoftInputShowHideReason.HIDE_REMOVE_CLIENT})
|
||||
SoftInputShowHideReason.HIDE_REMOVE_CLIENT,
|
||||
SoftInputShowHideReason.SHOW_RESTORE_IME_VISIBILITY})
|
||||
public @interface SoftInputShowHideReason {
|
||||
/** Show soft input by {@link android.view.inputmethod.InputMethodManager#showSoftInput}. */
|
||||
int SHOW_SOFT_INPUT = 0;
|
||||
@@ -167,4 +168,10 @@ public @interface SoftInputShowHideReason {
|
||||
* Hide soft input when a {@link com.android.internal.view.IInputMethodClient} is removed.
|
||||
*/
|
||||
int HIDE_REMOVE_CLIENT = 21;
|
||||
|
||||
/**
|
||||
* Show soft input when the system invoking
|
||||
* {@link com.android.server.wm.WindowManagerInternal#shouldRestoreImeVisibility}.
|
||||
*/
|
||||
int SHOW_RESTORE_IME_VISIBILITY = 22;
|
||||
}
|
||||
|
||||
@@ -3537,6 +3537,20 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
|
||||
boolean didStart = false;
|
||||
|
||||
InputBindResult res = null;
|
||||
// We shows the IME when the system allows the IME focused target window to restore the
|
||||
// IME visibility (e.g. switching to the app task when last time the IME is visible).
|
||||
if (isTextEditor && mWindowManagerInternal.shouldRestoreImeVisibility(windowToken)) {
|
||||
if (attribute != null) {
|
||||
res = startInputUncheckedLocked(cs, inputContext, missingMethods,
|
||||
attribute, startInputFlags, startInputReason);
|
||||
showCurrentInputLocked(windowToken, InputMethodManager.SHOW_IMPLICIT, null,
|
||||
SoftInputShowHideReason.SHOW_RESTORE_IME_VISIBILITY);
|
||||
} else {
|
||||
res = InputBindResult.NULL_EDITOR_INFO;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
switch (softInputMode & LayoutParams.SOFT_INPUT_MASK_STATE) {
|
||||
case LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED:
|
||||
if (!sameWindowFocused && (!isTextEditor || !doAutoShow)) {
|
||||
|
||||
@@ -667,4 +667,13 @@ public abstract class WindowManagerInternal {
|
||||
* Moves the {@link WindowToken} {@code binder} to the display specified by {@code displayId}.
|
||||
*/
|
||||
public abstract void moveWindowTokenToDisplay(IBinder binder, int displayId);
|
||||
|
||||
/**
|
||||
* Checks whether the given window should restore the last IME visibility.
|
||||
*
|
||||
* @param imeTargetWindowToken The token of the (IME target) window
|
||||
* @return {@code true} when the system allows to restore the IME visibility,
|
||||
* {@code false} otherwise.
|
||||
*/
|
||||
public abstract boolean shouldRestoreImeVisibility(IBinder imeTargetWindowToken);
|
||||
}
|
||||
|
||||
@@ -8016,6 +8016,11 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
return dc.getImeTarget(IME_TARGET_LAYERING).getWindow().getName();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldRestoreImeVisibility(IBinder imeTargetWindowToken) {
|
||||
return WindowManagerService.this.shouldRestoreImeVisibility(imeTargetWindowToken);
|
||||
}
|
||||
}
|
||||
|
||||
void registerAppFreezeListener(AppFreezeListener listener) {
|
||||
@@ -8673,6 +8678,22 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
boundsInWindow, hashAlgorithm, callback);
|
||||
}
|
||||
|
||||
boolean shouldRestoreImeVisibility(IBinder imeTargetWindowToken) {
|
||||
synchronized (mGlobalLock) {
|
||||
final WindowState imeTargetWindow = mWindowMap.get(imeTargetWindowToken);
|
||||
if (imeTargetWindow == null) {
|
||||
return false;
|
||||
}
|
||||
final Task imeTargetWindowTask = imeTargetWindow.getTask();
|
||||
if (imeTargetWindowTask == null) {
|
||||
return false;
|
||||
}
|
||||
final TaskSnapshot snapshot = mAtmService.getTaskSnapshot(imeTargetWindowTask.mTaskId,
|
||||
false /* isLowResolution */);
|
||||
return snapshot != null && snapshot.hasImeSurface();
|
||||
}
|
||||
}
|
||||
|
||||
private void sendDisplayHashError(RemoteCallback callback, int errorCode) {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putInt(EXTRA_DISPLAY_HASH_ERROR_CODE, errorCode);
|
||||
|
||||
Reference in New Issue
Block a user