Introduce SoftInputShowHideHistory

Add SoftInputShowHideHistory class to monitor showSoftInput / hideSoftInput
histories, each entry data contains:
  - ClientState: IME focused client process pid / uid who
  shows / hides soft input
  - Current focused window
  - Target display ID
  - Reason: describes why show / hide input
  - Request show or hide input
  - Timestamp

Bug: 141738570
Test: manual by calling "adb shell dumpsys input_method"
Change-Id: I21ad1708d68eae59dcd3d414248193fb130dadc2
This commit is contained in:
lumark
2019-12-29 20:20:41 +08:00
parent 71bfe434ea
commit 10ecd64cdd
8 changed files with 362 additions and 35 deletions

View File

@@ -16,6 +16,8 @@
package com.android.internal.inputmethod;
import android.annotation.AnyThread;
import android.annotation.NonNull;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams.SoftInputModeFlags;
@@ -25,6 +27,7 @@ import java.util.StringJoiner;
* Provides useful methods for debugging.
*/
public final class InputMethodDebug {
/**
* Not intended to be instantiated.
*/
@@ -174,4 +177,71 @@ public final class InputMethodDebug {
return joiner.setEmptyValue("(none)").toString();
}
/**
* Converts {@link SoftInputShowHideReason} to {@link String} for history dump.
*/
public static String softInputDisplayReasonToString(@SoftInputShowHideReason int reason) {
switch (reason) {
case SoftInputShowHideReason.SHOW_SOFT_INPUT:
return "SHOW_SOFT_INPUT";
case SoftInputShowHideReason.ATTACH_NEW_INPUT:
return "ATTACH_NEW_INPUT";
case SoftInputShowHideReason.SHOW_MY_SOFT_INPUT:
return "SHOW_MY_SOFT_INPUT";
case SoftInputShowHideReason.HIDE_SOFT_INPUT:
return "HIDE_SOFT_INPUT";
case SoftInputShowHideReason.HIDE_MY_SOFT_INPUT:
return "HIDE_MY_SOFT_INPUT";
case SoftInputShowHideReason.SHOW_AUTO_EDITOR_FORWARD_NAV:
return "SHOW_AUTO_EDITOR_FORWARD_NAV";
case SoftInputShowHideReason.SHOW_STATE_VISIBLE_FORWARD_NAV:
return "SHOW_STATE_VISIBLE_FORWARD_NAV";
case SoftInputShowHideReason.SHOW_STATE_ALWAYS_VISIBLE:
return "SHOW_STATE_ALWAYS_VISIBLE";
case SoftInputShowHideReason.SHOW_SETTINGS_ON_CHANGE:
return "SHOW_SETTINGS_ON_CHANGE";
case SoftInputShowHideReason.HIDE_SWITCH_USER:
return "HIDE_SWITCH_USER";
case SoftInputShowHideReason.HIDE_INVALID_USER:
return "HIDE_INVALID_USER";
case SoftInputShowHideReason.HIDE_UNSPECIFIED_WINDOW:
return "HIDE_UNSPECIFIED_WINDOW";
case SoftInputShowHideReason.HIDE_STATE_HIDDEN_FORWARD_NAV:
return "HIDE_STATE_HIDDEN_FORWARD_NAV";
case SoftInputShowHideReason.HIDE_ALWAYS_HIDDEN_STATE:
return "HIDE_ALWAYS_HIDDEN_STATE";
case SoftInputShowHideReason.HIDE_RESET_SHELL_COMMAND:
return "HIDE_RESET_SHELL_COMMAND";
case SoftInputShowHideReason.HIDE_SETTINGS_ON_CHANGE:
return "HIDE_SETTINGS_ON_CHANGE";
case SoftInputShowHideReason.HIDE_POWER_BUTTON_GO_HOME:
return "HIDE_POWER_BUTTON_GO_HOME";
case SoftInputShowHideReason.HIDE_DOCKED_STACK_ATTACHED:
return "HIDE_DOCKED_STACK_ATTACHED";
case SoftInputShowHideReason.HIDE_RECENTS_ANIMATION:
return "HIDE_RECENTS_ANIMATION";
default:
return "Unknown=" + reason;
}
}
/**
* Return a fixed size string of the object.
* TODO(b/141738570): Take & return with StringBuilder to make more memory efficient.
*/
@NonNull
@AnyThread
public static String objToString(Object obj) {
if (obj == null) {
return "null";
}
StringBuilder sb = new StringBuilder(64);
sb.setLength(0);
sb.append(obj.getClass().getName());
sb.append("@");
sb.append(Integer.toHexString(obj.hashCode()));
return sb.toString();
}
}

View File

@@ -0,0 +1,143 @@
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.internal.inputmethod;
import static java.lang.annotation.RetentionPolicy.SOURCE;
import android.annotation.IntDef;
import android.view.WindowManager.LayoutParams;
import java.lang.annotation.Retention;
/**
* Describes the reason why Soft input window visible / hidden.
*/
@Retention(SOURCE)
@IntDef(value = {
SoftInputShowHideReason.SHOW_SOFT_INPUT,
SoftInputShowHideReason.ATTACH_NEW_INPUT,
SoftInputShowHideReason.SHOW_MY_SOFT_INPUT,
SoftInputShowHideReason.HIDE_SOFT_INPUT,
SoftInputShowHideReason.HIDE_MY_SOFT_INPUT,
SoftInputShowHideReason.SHOW_AUTO_EDITOR_FORWARD_NAV,
SoftInputShowHideReason.SHOW_STATE_VISIBLE_FORWARD_NAV,
SoftInputShowHideReason.SHOW_STATE_ALWAYS_VISIBLE,
SoftInputShowHideReason.SHOW_SETTINGS_ON_CHANGE,
SoftInputShowHideReason.HIDE_SWITCH_USER,
SoftInputShowHideReason.HIDE_INVALID_USER,
SoftInputShowHideReason.HIDE_UNSPECIFIED_WINDOW,
SoftInputShowHideReason.HIDE_STATE_HIDDEN_FORWARD_NAV,
SoftInputShowHideReason.HIDE_ALWAYS_HIDDEN_STATE,
SoftInputShowHideReason.HIDE_RESET_SHELL_COMMAND,
SoftInputShowHideReason.HIDE_SETTINGS_ON_CHANGE,
SoftInputShowHideReason.HIDE_POWER_BUTTON_GO_HOME,
SoftInputShowHideReason.HIDE_DOCKED_STACK_ATTACHED,
SoftInputShowHideReason.HIDE_RECENTS_ANIMATION})
public @interface SoftInputShowHideReason {
/** Show soft input by {@link android.view.inputmethod.InputMethodManager#showSoftInput}. */
int SHOW_SOFT_INPUT = 0;
/** Show soft input when {@code InputMethodManagerService#attachNewInputLocked} called. */
int ATTACH_NEW_INPUT = 1;
/** Show soft input by {@code InputMethodManagerService#showMySoftInput}. */
int SHOW_MY_SOFT_INPUT = 2;
/**
* Hide soft input by
* {@link android.view.inputmethod.InputMethodManager#hideSoftInputFromWindow}.
*/
int HIDE_SOFT_INPUT = 3;
/** Hide soft input by {@code InputMethodManagerService#hideMySoftInput}. */
int HIDE_MY_SOFT_INPUT = 4;
/**
* Show soft input when navigated forward to the window (with
* {@link LayoutParams#SOFT_INPUT_IS_FORWARD_NAVIGATION}} which the focused view is text
* editor and system will auto-show the IME when the window can resize or running on a large
* screen.
*/
int SHOW_AUTO_EDITOR_FORWARD_NAV = 5;
/**
* Show soft input when navigated forward to the window with
* {@link LayoutParams#SOFT_INPUT_IS_FORWARD_NAVIGATION} and
* {@link LayoutParams#SOFT_INPUT_STATE_VISIBLE}.
*/
int SHOW_STATE_VISIBLE_FORWARD_NAV = 6;
/**
* Show soft input when the window with {@link LayoutParams#SOFT_INPUT_STATE_ALWAYS_VISIBLE}.
*/
int SHOW_STATE_ALWAYS_VISIBLE = 7;
/**
* Show soft input during {@code InputMethodManagerService} receive changes from
* {@code SettingsProvider}.
*/
int SHOW_SETTINGS_ON_CHANGE = 8;
/** Hide soft input during switching user. */
int HIDE_SWITCH_USER = 9;
/** Hide soft input when the user is invalid. */
int HIDE_INVALID_USER = 10;
/**
* Hide soft input when the window with {@link LayoutParams#SOFT_INPUT_STATE_UNSPECIFIED} which
* the focused view is not text editor.
*/
int HIDE_UNSPECIFIED_WINDOW = 11;
/**
* Hide soft input when navigated forward to the window with
* {@link LayoutParams#SOFT_INPUT_IS_FORWARD_NAVIGATION} and
* {@link LayoutParams#SOFT_INPUT_STATE_HIDDEN}.
*/
int HIDE_STATE_HIDDEN_FORWARD_NAV = 12;
/**
* Hide soft input when the window with {@link LayoutParams#SOFT_INPUT_STATE_ALWAYS_HIDDEN}.
*/
int HIDE_ALWAYS_HIDDEN_STATE = 13;
/** Hide soft input when "adb shell ime <command>" called. */
int HIDE_RESET_SHELL_COMMAND = 14;
/**
* Hide soft input during {@code InputMethodManagerService} receive changes from
* {@code SettingsProvider}.
*/
int HIDE_SETTINGS_ON_CHANGE = 15;
/**
* Hide soft input from {@link com.android.server.policy.PhoneWindowManager} when setting
* {@link com.android.internal.R.integer#config_shortPressOnPowerBehavior} in config.xml as
* dismiss IME.
*/
int HIDE_POWER_BUTTON_GO_HOME = 16;
/** Hide soft input when attaching docked stack. */
int HIDE_DOCKED_STACK_ATTACHED = 17;
/**
* Hide soft input when {@link com.android.server.wm.RecentsAnimationController} starts
* intercept touch from app window.
*/
int HIDE_RECENTS_ANIMATION = 18;
}

View File

@@ -23,6 +23,7 @@ import android.view.autofill.AutofillId;
import android.view.inputmethod.InlineSuggestionsRequest;
import android.view.inputmethod.InputMethodInfo;
import com.android.internal.inputmethod.SoftInputShowHideReason;
import com.android.internal.view.IInlineSuggestionsRequestCallback;
import com.android.server.LocalServices;
@@ -52,7 +53,7 @@ public abstract class InputMethodManagerInternal {
/**
* Hides the current input method, if visible.
*/
public abstract void hideCurrentInputMethod();
public abstract void hideCurrentInputMethod(@SoftInputShowHideReason int reason);
/**
* Returns the list of installed input methods for the specified user.
@@ -109,7 +110,7 @@ public abstract class InputMethodManagerInternal {
}
@Override
public void hideCurrentInputMethod() {
public void hideCurrentInputMethod(@SoftInputShowHideReason int reason) {
}
@Override

View File

@@ -132,6 +132,7 @@ import com.android.internal.content.PackageMonitor;
import com.android.internal.inputmethod.IInputContentUriToken;
import com.android.internal.inputmethod.IInputMethodPrivilegedOperations;
import com.android.internal.inputmethod.InputMethodDebug;
import com.android.internal.inputmethod.SoftInputShowHideReason;
import com.android.internal.inputmethod.StartInputFlags;
import com.android.internal.inputmethod.StartInputReason;
import com.android.internal.inputmethod.UnbindReason;
@@ -767,6 +768,75 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
@GuardedBy("mMethodMap")
private final WeakHashMap<IBinder, IBinder> mImeTargetWindowMap = new WeakHashMap<>();
private static final class SoftInputShowHideHistory {
private Entry[] mEntries = new Entry[16];
private int mNextIndex = 0;
private static final AtomicInteger sSequenceNumber = new AtomicInteger(0);
// TODO(b/141738570): add requestWindowToken to track who request show / hide softInput.
private static final class Entry {
ClientState mClientState;
String mFocusedWindowString;
@SoftInputModeFlags
int mFocusedWindowSoftInputMode;
@SoftInputShowHideReason
int mReason;
boolean mRequestShowKeyboard;
// The timing of handling MSG_SHOW_SOFT_INPUT or MSG_HIDE_SOFT_INPUT.
long mTimestamp;
long mWallTime;
int mTargetDisplayId;
Entry(ClientState client, String focusedWindow, @SoftInputModeFlags int softInputMode,
@SoftInputShowHideReason int reason, boolean show) {
mClientState = client;
mFocusedWindowString = focusedWindow;
mFocusedWindowSoftInputMode = softInputMode;
mReason = reason;
mRequestShowKeyboard = show;
mTimestamp = SystemClock.uptimeMillis();
mWallTime = System.currentTimeMillis();
}
}
void addEntry(@NonNull Entry entry) {
final int index = mNextIndex;
mEntries[index] = entry;
mNextIndex = (mNextIndex + 1) % mEntries.length;
}
void dump(@NonNull PrintWriter pw, @NonNull String prefix) {
final SimpleDateFormat dataFormat =
new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.US);
for (int i = 0; i < mEntries.length; ++i) {
final Entry entry = mEntries[(i + mNextIndex) % mEntries.length];
if (entry == null) {
continue;
}
pw.print(prefix);
pw.println("SoftInputShowHideHistory #" + sSequenceNumber.getAndIncrement() + ":");
pw.print(prefix);
pw.println(" time=" + dataFormat.format(new Date(entry.mWallTime))
+ " (timestamp=" + entry.mTimestamp + ")");
pw.print(prefix);
pw.print(" requestShowKeyboard=" + entry.mRequestShowKeyboard);
pw.print(" targetDisplayId=" + entry.mTargetDisplayId);
pw.println(" reason=" + entry.mReason);
pw.print(prefix);
pw.print(" requestClient=" + entry.mClientState);
pw.println(" focusedWindow=" + entry.mFocusedWindowString);
pw.print(prefix);
pw.println(" focusedWindowSoftInputMode=" + InputMethodDebug.softInputModeToString(
entry.mFocusedWindowSoftInputMode));
}
}
}
/**
* Map of generated token to windowToken that is requesting
* {@link InputMethodManager#showSoftInput(View, int)}.
@@ -933,6 +1003,11 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
@NonNull
private final StartInputHistory mStartInputHistory = new StartInputHistory();
@GuardedBy("mMethodMap")
@NonNull
private final SoftInputShowHideHistory mSoftInputShowHideHistory =
new SoftInputShowHideHistory();
class SettingsObserver extends ContentObserver {
int mUserId;
boolean mRegistered = false;
@@ -989,11 +1064,13 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
== AccessibilityService.SHOW_MODE_HIDDEN;
if (mAccessibilityRequestingNoSoftKeyboard) {
final boolean showRequested = mShowRequested;
hideCurrentInputLocked(0, null);
hideCurrentInputLocked(0, null,
SoftInputShowHideReason.HIDE_SETTINGS_ON_CHANGE);
mShowRequested = showRequested;
} else if (mShowRequested) {
showCurrentInputLocked(
mCurFocusedWindow, InputMethodManager.SHOW_IMPLICIT, null);
showCurrentInputLocked(mCurFocusedWindow,
InputMethodManager.SHOW_IMPLICIT, null,
SoftInputShowHideReason.SHOW_SETTINGS_ON_CHANGE);
}
} else {
boolean enabledChanged = false;
@@ -1568,7 +1645,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
// TODO: Is it really possible that switchUserLocked() happens before system ready?
if (mSystemReady) {
hideCurrentInputLocked(0, null);
hideCurrentInputLocked(0, null, SoftInputShowHideReason.HIDE_SWITCH_USER);
resetCurrentMethodAndClient(UnbindReason.SWITCH_USER);
buildInputMethodListLocked(initialUserSwitch);
if (TextUtils.isEmpty(mSettings.getSelectedInputMethod())) {
@@ -2094,7 +2171,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
startInputToken, session, mCurInputContext, mCurAttribute));
if (mShowRequested) {
if (DEBUG) Slog.v(TAG, "Attach new input asks to show input");
showCurrentInputLocked(mCurFocusedWindow, getAppShowFlags(), null);
showCurrentInputLocked(mCurFocusedWindow, getAppShowFlags(), null,
SoftInputShowHideReason.ATTACH_NEW_INPUT);
}
return new InputBindResult(InputBindResult.ResultCode.SUCCESS_WITH_IME_SESSION,
session.session, (session.channel != null ? session.channel.dup() : null),
@@ -2833,7 +2911,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
}
if (DEBUG) Slog.v(TAG, "Client requesting input be shown");
return showCurrentInputLocked(windowToken, flags, resultReceiver);
return showCurrentInputLocked(windowToken, flags, resultReceiver,
SoftInputShowHideReason.SHOW_SOFT_INPUT);
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -2841,7 +2920,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
@GuardedBy("mMethodMap")
boolean showCurrentInputLocked(IBinder windowToken, int flags, ResultReceiver resultReceiver) {
boolean showCurrentInputLocked(IBinder windowToken, int flags, ResultReceiver resultReceiver,
@SoftInputShowHideReason int reason) {
mShowRequested = true;
if (mAccessibilityRequestingNoSoftKeyboard) {
return false;
@@ -2864,9 +2944,9 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
// create a dummy token for IMS so that IMS cannot inject windows into client app.
Binder showInputToken = new Binder();
mShowRequestWindowMap.put(showInputToken, windowToken);
executeOrSendMessage(mCurMethod, mCaller.obtainMessageIOOO(
MSG_SHOW_SOFT_INPUT, getImeShowFlags(), mCurMethod,
resultReceiver, showInputToken));
executeOrSendMessage(mCurMethod, mCaller.obtainMessageIIOOO(
MSG_SHOW_SOFT_INPUT, getImeShowFlags(), reason, mCurMethod, resultReceiver,
showInputToken));
mInputShown = true;
if (mHaveConnection && !mVisibleBound) {
bindCurrentInputMethodServiceLocked(
@@ -2924,14 +3004,16 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
if (DEBUG) Slog.v(TAG, "Client requesting input be hidden");
return hideCurrentInputLocked(flags, resultReceiver);
return hideCurrentInputLocked(flags, resultReceiver,
SoftInputShowHideReason.HIDE_SOFT_INPUT);
} finally {
Binder.restoreCallingIdentity(ident);
}
}
}
boolean hideCurrentInputLocked(int flags, ResultReceiver resultReceiver) {
boolean hideCurrentInputLocked(int flags, ResultReceiver resultReceiver,
@SoftInputShowHideReason int reason) {
if ((flags&InputMethodManager.HIDE_IMPLICIT_ONLY) != 0
&& (mShowExplicitlyRequested || mShowForced)) {
if (DEBUG) Slog.v(TAG, "Not hiding: explicit show not cancelled by non-explicit hide");
@@ -2958,8 +3040,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
// delivered to the IME process as an IPC. Hence the inconsistency between
// IMMS#mInputShown and IMMS#mImeWindowVis should be resolved spontaneously in
// the final state.
executeOrSendMessage(mCurMethod, mCaller.obtainMessageOO(
MSG_HIDE_SOFT_INPUT, mCurMethod, resultReceiver));
executeOrSendMessage(mCurMethod, mCaller.obtainMessageIOO(MSG_HIDE_SOFT_INPUT,
reason, mCurMethod, resultReceiver));
res = true;
} else {
res = false;
@@ -3080,7 +3162,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
Slog.w(TAG, "If you need to impersonate a foreground user/profile from"
+ " a background user, use EditorInfo.targetInputMethodUser with"
+ " INTERACT_ACROSS_USERS_FULL permission.");
hideCurrentInputLocked(0, null);
hideCurrentInputLocked(0, null, SoftInputShowHideReason.HIDE_INVALID_USER);
return InputBindResult.INVALID_USER;
}
@@ -3141,7 +3223,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
// be behind any soft input window, so hide the
// soft input window if it is shown.
if (DEBUG) Slog.v(TAG, "Unspecified window will hide input");
hideCurrentInputLocked(InputMethodManager.HIDE_NOT_ALWAYS, null);
hideCurrentInputLocked(InputMethodManager.HIDE_NOT_ALWAYS, null,
SoftInputShowHideReason.HIDE_UNSPECIFIED_WINDOW);
// If focused display changed, we should unbind current method
// to make app window in previous display relayout after Ime
@@ -3167,7 +3250,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
attribute, startInputFlags, startInputReason);
didStart = true;
}
showCurrentInputLocked(windowToken, InputMethodManager.SHOW_IMPLICIT, null);
showCurrentInputLocked(windowToken, InputMethodManager.SHOW_IMPLICIT, null,
SoftInputShowHideReason.SHOW_AUTO_EDITOR_FORWARD_NAV);
}
break;
case LayoutParams.SOFT_INPUT_STATE_UNCHANGED:
@@ -3176,12 +3260,14 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
case LayoutParams.SOFT_INPUT_STATE_HIDDEN:
if ((softInputMode & LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) != 0) {
if (DEBUG) Slog.v(TAG, "Window asks to hide input going forward");
hideCurrentInputLocked(0, null);
hideCurrentInputLocked(0, null,
SoftInputShowHideReason.HIDE_STATE_HIDDEN_FORWARD_NAV);
}
break;
case LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN:
if (DEBUG) Slog.v(TAG, "Window asks to hide input");
hideCurrentInputLocked(0, null);
hideCurrentInputLocked(0, null,
SoftInputShowHideReason.HIDE_ALWAYS_HIDDEN_STATE);
break;
case LayoutParams.SOFT_INPUT_STATE_VISIBLE:
if ((softInputMode & LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) != 0) {
@@ -3193,7 +3279,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
attribute, startInputFlags, startInputReason);
didStart = true;
}
showCurrentInputLocked(windowToken, InputMethodManager.SHOW_IMPLICIT, null);
showCurrentInputLocked(windowToken, InputMethodManager.SHOW_IMPLICIT, null,
SoftInputShowHideReason.SHOW_STATE_VISIBLE_FORWARD_NAV);
} else {
Slog.e(TAG, "SOFT_INPUT_STATE_VISIBLE is ignored because"
+ " there is no focused view that also returns true from"
@@ -3210,7 +3297,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
attribute, startInputFlags, startInputReason);
didStart = true;
}
showCurrentInputLocked(windowToken, InputMethodManager.SHOW_IMPLICIT, null);
showCurrentInputLocked(windowToken, InputMethodManager.SHOW_IMPLICIT, null,
SoftInputShowHideReason.SHOW_STATE_ALWAYS_VISIBLE);
} else {
Slog.e(TAG, "SOFT_INPUT_STATE_ALWAYS_VISIBLE is ignored because"
+ " there is no focused view that also returns true from"
@@ -3702,7 +3790,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
long ident = Binder.clearCallingIdentity();
try {
hideCurrentInputLocked(flags, null);
hideCurrentInputLocked(flags, null, SoftInputShowHideReason.HIDE_MY_SOFT_INPUT);
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -3717,7 +3805,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
long ident = Binder.clearCallingIdentity();
try {
showCurrentInputLocked(mLastImeTargetWindow, flags, null);
showCurrentInputLocked(mLastImeTargetWindow, flags, null,
SoftInputShowHideReason.SHOW_MY_SOFT_INPUT);
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -3800,10 +3889,16 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
case MSG_SHOW_SOFT_INPUT:
args = (SomeArgs)msg.obj;
try {
final @SoftInputShowHideReason int reason = msg.arg2;
if (DEBUG) Slog.v(TAG, "Calling " + args.arg1 + ".showSoftInput("
+ msg.arg1 + ", " + args.arg2 + ")");
+ msg.arg1 + ", " + args.arg2 + ") for reason: "
+ InputMethodDebug.softInputDisplayReasonToString(reason));
((IInputMethod) args.arg1).showSoftInput(
(IBinder) args.arg3, msg.arg1, (ResultReceiver) args.arg2);
mSoftInputShowHideHistory.addEntry(
new SoftInputShowHideHistory.Entry(mCurClient,
InputMethodDebug.objToString(mCurFocusedWindow),
mCurFocusedWindowSoftInputMode, reason, true /* show */));
} catch (RemoteException e) {
}
args.recycle();
@@ -3811,16 +3906,23 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
case MSG_HIDE_SOFT_INPUT:
args = (SomeArgs)msg.obj;
try {
final @SoftInputShowHideReason int reason = msg.arg1;
if (DEBUG) Slog.v(TAG, "Calling " + args.arg1 + ".hideSoftInput(0, "
+ args.arg2 + ")");
+ args.arg2 + ") for reason: "
+ InputMethodDebug.softInputDisplayReasonToString(reason));
((IInputMethod)args.arg1).hideSoftInput(0, (ResultReceiver)args.arg2);
mSoftInputShowHideHistory.addEntry(
new SoftInputShowHideHistory.Entry(mCurClient,
InputMethodDebug.objToString(mCurFocusedWindow),
mCurFocusedWindowSoftInputMode, reason, false /* show */));
} catch (RemoteException e) {
}
args.recycle();
return true;
case MSG_HIDE_CURRENT_INPUT_METHOD:
synchronized (mMethodMap) {
hideCurrentInputLocked(0, null);
final @SoftInputShowHideReason int reason = (int) msg.obj;
hideCurrentInputLocked(0, null, reason);
}
return true;
case MSG_INITIALIZE_IME:
@@ -4604,9 +4706,9 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
@Override
public void hideCurrentInputMethod() {
public void hideCurrentInputMethod(@SoftInputShowHideReason int reason) {
mService.mHandler.removeMessages(MSG_HIDE_CURRENT_INPUT_METHOD);
mService.mHandler.sendEmptyMessage(MSG_HIDE_CURRENT_INPUT_METHOD);
mService.mHandler.obtainMessage(MSG_HIDE_CURRENT_INPUT_METHOD, reason).sendToTarget();
}
@Override
@@ -4763,6 +4865,9 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
p.println(" mStartInputHistory:");
mStartInputHistory.dump(pw, " ");
p.println(" mSoftInputShowHideHistory:");
mSoftInputShowHideHistory.dump(pw, " ");
}
p.println(" ");
@@ -5222,7 +5327,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
final String nextIme;
final List<InputMethodInfo> nextEnabledImes;
if (userId == mSettings.getCurrentUserId()) {
hideCurrentInputLocked(0, null);
hideCurrentInputLocked(0, null,
SoftInputShowHideReason.HIDE_RESET_SHELL_COMMAND);
unbindCurrentMethodLocked();
// Reset the current IME
resetSelectedInputMethodAndSubtypeLocked(null);

View File

@@ -74,6 +74,7 @@ import com.android.internal.annotations.GuardedBy;
import com.android.internal.inputmethod.IMultiClientInputMethod;
import com.android.internal.inputmethod.IMultiClientInputMethodPrivilegedOperations;
import com.android.internal.inputmethod.IMultiClientInputMethodSession;
import com.android.internal.inputmethod.SoftInputShowHideReason;
import com.android.internal.inputmethod.StartInputFlags;
import com.android.internal.inputmethod.StartInputReason;
import com.android.internal.inputmethod.UnbindReason;
@@ -174,7 +175,7 @@ public final class MultiClientInputMethodManagerService {
}
@Override
public void hideCurrentInputMethod() {
public void hideCurrentInputMethod(@SoftInputShowHideReason int reason) {
reportNotSupported();
}

View File

@@ -186,6 +186,7 @@ import android.view.autofill.AutofillManagerInternal;
import com.android.internal.R;
import com.android.internal.accessibility.AccessibilityShortcutController;
import com.android.internal.inputmethod.SoftInputShowHideReason;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto;
import com.android.internal.os.RoSystemProperties;
@@ -1105,7 +1106,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
LocalServices.getService(InputMethodManagerInternal.class);
}
if (mInputMethodManagerInternal != null) {
mInputMethodManagerInternal.hideCurrentInputMethod();
mInputMethodManagerInternal.hideCurrentInputMethod(
SoftInputShowHideReason.HIDE_POWER_BUTTON_GO_HOME);
}
} else {
shortPressPowerGoHome();

View File

@@ -53,6 +53,7 @@ import android.view.animation.Interpolator;
import android.view.animation.PathInterpolator;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.inputmethod.SoftInputShowHideReason;
import com.android.internal.policy.DividerSnapAlgorithm;
import com.android.internal.policy.DockedDividerUtils;
import com.android.server.LocalServices;
@@ -517,7 +518,8 @@ public class DockedStackDividerController {
// Hide the current IME to avoid problems with animations from IME adjustment when
// attaching the docked stack.
inputMethodManagerInternal.hideCurrentInputMethod();
inputMethodManagerInternal.hideCurrentInputMethod(
SoftInputShowHideReason.HIDE_DOCKED_STACK_ATTACHED);
mImeHideRequested = true;
}

View File

@@ -55,6 +55,7 @@ import android.view.SurfaceControl;
import android.view.SurfaceControl.Transaction;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.inputmethod.SoftInputShowHideReason;
import com.android.internal.util.function.pooled.PooledConsumer;
import com.android.internal.util.function.pooled.PooledFunction;
import com.android.internal.util.function.pooled.PooledLambda;
@@ -301,7 +302,8 @@ public class RecentsAnimationController implements DeathRecipient {
final InputMethodManagerInternal inputMethodManagerInternal =
LocalServices.getService(InputMethodManagerInternal.class);
if (inputMethodManagerInternal != null) {
inputMethodManagerInternal.hideCurrentInputMethod();
inputMethodManagerInternal.hideCurrentInputMethod(
SoftInputShowHideReason.HIDE_RECENTS_ANIMATION);
}
} finally {
Binder.restoreCallingIdentity(token);