From 22a8923368a41cf50adfbc963c02b66302bb2d41 Mon Sep 17 00:00:00 2001 From: Yohei Yukawa Date: Sun, 12 Feb 2017 16:38:59 -0800 Subject: [PATCH] Track the last softInputMode in IMMS A field in WindowManager.LayoutParams softInputMode is something that definitely needs to be kept tracking in historical debugging infrastructure across IME-related processes (Bug 35079353) [1]. As a preparation, this CL enables InputMethodManagerService (IMMS) to include the last softInputMode specified in IMMS#windowGainedFocus() in the dumpsys in human readable format. [1]: As explained in b.android.com/224318, softInputMode misspecified by app developers is a typical root cause of unexpected behavior in keyboard visibility. Bugs such as Bug 23168250, Bug 27275709, and Bug 31770400 fall into this category. Test: `adb shell dumpsys input_method | grep softInputMode=` Bug: 35079353 Change-Id: I485ced030def179dad78b4b811c6eb52b5e5c951 --- .../view/inputmethod/InputMethodManager.java | 2 +- .../internal/view/InputMethodClient.java | 62 +++++++++++++++++++ .../server/InputMethodManagerService.java | 16 ++++- 3 files changed, 76 insertions(+), 4 deletions(-) diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java index 13abe7c6471dc..08f8c65d8611e 100644 --- a/core/java/android/view/inputmethod/InputMethodManager.java +++ b/core/java/android/view/inputmethod/InputMethodManager.java @@ -1495,7 +1495,7 @@ public final class InputMethodManager { boolean forceNewFocus = false; synchronized (mH) { if (DEBUG) Log.v(TAG, "onWindowFocus: " + focusedView - + " softInputMode=" + softInputMode + + " softInputMode=" + InputMethodClient.softInputModeToString(softInputMode) + " first=" + first + " flags=#" + Integer.toHexString(windowFlags)); if (mHasBeenInactive) { diff --git a/core/java/com/android/internal/view/InputMethodClient.java b/core/java/com/android/internal/view/InputMethodClient.java index cea030a3d489b..c847cc2aba653 100644 --- a/core/java/com/android/internal/view/InputMethodClient.java +++ b/core/java/com/android/internal/view/InputMethodClient.java @@ -17,6 +17,7 @@ package com.android.internal.view; import android.annotation.IntDef; +import android.view.WindowManager.LayoutParams; import java.lang.annotation.Retention; @@ -103,4 +104,65 @@ public final class InputMethodClient { return "Unknown=" + reason; } } + + public static String softInputModeToString(final int softInputMode) { + final StringBuilder sb = new StringBuilder(); + final int state = softInputMode & LayoutParams.SOFT_INPUT_MASK_STATE; + final int adjust = softInputMode & LayoutParams.SOFT_INPUT_MASK_ADJUST; + final boolean isForwardNav = + (softInputMode & LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) != 0; + + switch (state) { + case LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED: + sb.append("STATE_UNSPECIFIED"); + break; + case LayoutParams.SOFT_INPUT_STATE_UNCHANGED: + sb.append("STATE_UNCHANGED"); + break; + case LayoutParams.SOFT_INPUT_STATE_HIDDEN: + sb.append("STATE_HIDDEN"); + break; + case LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN: + sb.append("STATE_ALWAYS_HIDDEN"); + break; + case LayoutParams.SOFT_INPUT_STATE_VISIBLE: + sb.append("STATE_VISIBLE"); + break; + case LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE: + sb.append("STATE_ALWAYS_VISIBLE"); + break; + default: + sb.append("STATE_UNKNOWN("); + sb.append(state); + sb.append(")"); + break; + } + + switch (adjust) { + case LayoutParams.SOFT_INPUT_ADJUST_UNSPECIFIED: + sb.append("|ADJUST_UNSPECIFIED"); + break; + case LayoutParams.SOFT_INPUT_ADJUST_RESIZE: + sb.append("|ADJUST_RESIZE"); + break; + case LayoutParams.SOFT_INPUT_ADJUST_PAN: + sb.append("|ADJUST_PAN"); + break; + case LayoutParams.SOFT_INPUT_ADJUST_NOTHING: + sb.append("|ADJUST_NOTHING"); + break; + default: + sb.append("|ADJUST_UNKNOWN("); + sb.append(adjust); + sb.append(")"); + break; + } + + if (isForwardNav) { + // This is a special bit that is set by the system only during the window navigation. + sb.append("|IS_FORWARD_NAVIGATION"); + } + + return sb.toString(); + } } diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java index 2b3d8d4e1fb14..b2b8f8508be55 100644 --- a/services/core/java/com/android/server/InputMethodManagerService.java +++ b/services/core/java/com/android/server/InputMethodManagerService.java @@ -347,6 +347,13 @@ public class InputMethodManagerService extends IInputMethodManager.Stub */ IBinder mCurFocusedWindow; + /** + * {@link WindowManager.LayoutParams#softInputMode} of {@link #mCurFocusedWindow}. + * + * @see #mCurFocusedWindow + */ + int mCurFocusedWindowSoftInputMode; + /** * The client by which {@link #mCurFocusedWindow} was reported. Used only for debugging. */ @@ -2288,7 +2295,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub + InputConnectionInspector.getMissingMethodFlagsAsString(missingMethods) + " attribute=" + attribute + " controlFlags=#" + Integer.toHexString(controlFlags) - + " softInputMode=#" + Integer.toHexString(softInputMode) + + " softInputMode=" + InputMethodClient.softInputModeToString(softInputMode) + " windowFlags=#" + Integer.toHexString(windowFlags)); ClientState cs = mClients.get(client.asBinder()); @@ -2333,6 +2340,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub return null; } mCurFocusedWindow = windowToken; + mCurFocusedWindowSoftInputMode = softInputMode; mCurFocusedWindowClient = cs; // Should we auto-show the IME even if the caller has not @@ -4087,9 +4095,11 @@ public class InputMethodManagerService extends IInputMethodManager.Stub p.println(" mCurMethodId=" + mCurMethodId); client = mCurClient; p.println(" mCurClient=" + client + " mCurSeq=" + mCurSeq); - p.println(" mCurFocusedWindow=" + mCurFocusedWindow); + p.println(" mCurFocusedWindow=" + mCurFocusedWindow + + " softInputMode=" + + InputMethodClient.softInputModeToString(mCurFocusedWindowSoftInputMode) + + " client=" + mCurFocusedWindowClient); focusedWindowClient = mCurFocusedWindowClient; - p.println(" mCurFocusedWindowClient=" + focusedWindowClient); p.println(" mCurId=" + mCurId + " mHaveConnect=" + mHaveConnection + " mBoundToMethod=" + mBoundToMethod); p.println(" mCurToken=" + mCurToken);