OSDN Git Service

Tell the reason why IMM called startInput().
authorYohei Yukawa <yukawa@google.com>
Wed, 25 Nov 2015 19:07:19 +0000 (11:07 -0800)
committerYohei Yukawa <yukawa@google.com>
Wed, 25 Nov 2015 19:07:19 +0000 (11:07 -0800)
As a preparation to fix Bug 25373872, this CL introduces an additional
int parameter into the following two methods
  - IInputMethodManager.startInput()
  - IInputMethodManager.windowGainedFocus()
so that IMMS can know why IMM needs to start input.  Currently the
"startInputReason" parameter is used only for debug message only when
the OS is rebuilt with flipping IMMS#DEBUG to true.  Basically this
should have no impact in production builds except for a tiny overhead
of having one int parameter in some internal IPC calls.

Note that since 7663d80f6b6fd6ca7a736c3802013a09c0abdeb9 [1] basically
IMMS#windowGainedFocus() has been a superset of IMMS#startInput().
Hence we should pass to "startInputReason" parameter to
IMMS#windowGainedFocus() as well as IMMS#startInput().

  [1]: Icb58bef75ef4bf9979f3e2ba88cea20db2e2c3fb

Bug: 25373872
Change-Id: Ia1fe120af7d71495c5f3a4fc0ec6390efb8240ca

core/java/android/view/inputmethod/InputMethodManager.java
core/java/com/android/internal/view/IInputMethodManager.aidl
core/java/com/android/internal/view/InputMethodClient.java
services/core/java/com/android/server/InputMethodManagerService.java

index 19a98f3..329d1b0 100644 (file)
@@ -436,7 +436,8 @@ public final class InputMethodManager {
                         mCurId = res.id;
                         mBindSequence = res.sequence;
                     }
-                    startInputInner(null, 0, 0, 0);
+                    startInputInner(InputMethodClient.START_INPUT_REASON_BOUND_TO_IMMS,
+                            null, 0, 0, 0);
                     return;
                 }
                 case MSG_UNBIND: {
@@ -461,7 +462,9 @@ public final class InputMethodManager {
                         startInput = mActive;
                     }
                     if (startInput) {
-                        startInputInner(null, 0, 0, 0);
+                        startInputInner(
+                                InputMethodClient.START_INPUT_REASON_UNBOUND_FROM_IMMS, null, 0, 0,
+                                0);
                     }
                     return;
                 }
@@ -494,7 +497,10 @@ public final class InputMethodManager {
                             // In that case, we really should not call
                             // mServedInputConnection.finishComposingText.
                             if (checkFocusNoStartInput(mHasBeenInactive, false)) {
-                                startInputInner(null, 0, 0, 0);
+                                final int reason = active ?
+                                        InputMethodClient.START_INPUT_REASON_ACTIVATED_BY_IMMS :
+                                        InputMethodClient.START_INPUT_REASON_DEACTIVATED_BY_IMMS;
+                                startInputInner(reason, null, 0, 0, 0);
                             }
                         }
                     }
@@ -1118,18 +1124,23 @@ public final class InputMethodManager {
             
             mServedConnecting = true;
         }
-        
-        startInputInner(null, 0, 0, 0);
+
+        startInputInner(InputMethodClient.START_INPUT_REASON_APP_CALLED_RESTART_INPUT_API, null, 0,
+                0, 0);
     }
-    
-    boolean startInputInner(IBinder windowGainingFocus, int controlFlags, int softInputMode,
+
+    boolean startInputInner(@InputMethodClient.StartInputReason final int startInputReason,
+            IBinder windowGainingFocus, int controlFlags, int softInputMode,
             int windowFlags) {
         final View view;
         synchronized (mH) {
             view = mServedView;
             
             // Make sure we have a window token for the served view.
-            if (DEBUG) Log.v(TAG, "Starting input: view=" + view);
+            if (DEBUG) {
+                Log.v(TAG, "Starting input: view=" + view +
+                        " reason=" + InputMethodClient.getStartInputReason(startInputReason));
+            }
             if (view == null) {
                 if (DEBUG) Log.v(TAG, "ABORT input: no served view!");
                 return false;
@@ -1157,7 +1168,7 @@ public final class InputMethodManager {
             vh.post(new Runnable() {
                 @Override
                 public void run() {
-                    startInputInner(null, 0, 0, 0);
+                    startInputInner(startInputReason, null, 0, 0, 0);
                 }
             });
             return false;
@@ -1221,11 +1232,11 @@ public final class InputMethodManager {
                         + Integer.toHexString(controlFlags));
                 InputBindResult res;
                 if (windowGainingFocus != null) {
-                    res = mService.windowGainedFocus(mClient, windowGainingFocus,
+                    res = mService.windowGainedFocus(startInputReason, mClient, windowGainingFocus,
                             controlFlags, softInputMode, windowFlags,
                             tba, servedContext);
                 } else {
-                    res = mService.startInput(mClient,
+                    res = mService.startInput(startInputReason, mClient,
                             servedContext, tba, controlFlags);
                 }
                 if (DEBUG) Log.v(TAG, "Starting input: Bind result=" + res);
@@ -1352,7 +1363,7 @@ public final class InputMethodManager {
      */
     public void checkFocus() {
         if (checkFocusNoStartInput(false, true)) {
-            startInputInner(null, 0, 0, 0);
+            startInputInner(InputMethodClient.START_INPUT_REASON_CHECK_FOCUS, null, 0, 0, 0);
         }
     }
 
@@ -1440,8 +1451,8 @@ public final class InputMethodManager {
             // should be done in conjunction with telling the system service
             // about the window gaining focus, to help make the transition
             // smooth.
-            if (startInputInner(rootView.getWindowToken(),
-                    controlFlags, softInputMode, windowFlags)) {
+            if (startInputInner(InputMethodClient.START_INPUT_REASON_WINDOW_FOCUS_GAIN,
+                    rootView.getWindowToken(), controlFlags, softInputMode, windowFlags)) {
                 return;
             }
         }
@@ -1451,8 +1462,10 @@ public final class InputMethodManager {
         synchronized (mH) {
             try {
                 if (DEBUG) Log.v(TAG, "Reporting focus gain, without startInput");
-                mService.windowGainedFocus(mClient, rootView.getWindowToken(),
-                        controlFlags, softInputMode, windowFlags, null, null);
+                mService.windowGainedFocus(
+                        InputMethodClient.START_INPUT_REASON_WINDOW_FOCUS_GAIN_REPORT_ONLY, mClient,
+                        rootView.getWindowToken(), controlFlags, softInputMode, windowFlags, null,
+                        null);
             } catch (RemoteException e) {
             }
         }
index 60c5e42..db3ecc6 100644 (file)
@@ -45,9 +45,10 @@ interface IInputMethodManager {
     void addClient(in IInputMethodClient client,
             in IInputContext inputContext, int uid, int pid);
     void removeClient(in IInputMethodClient client);
-            
-    InputBindResult startInput(in IInputMethodClient client,
-            IInputContext inputContext, in EditorInfo attribute, int controlFlags);
+
+    InputBindResult startInput(/* @InputMethodClient.StartInputReason */ int startInputReason,
+            in IInputMethodClient client, IInputContext inputContext, in EditorInfo attribute,
+            int controlFlags);
     void finishInput(in IInputMethodClient client);
     boolean showSoftInput(in IInputMethodClient client, int flags,
             in ResultReceiver resultReceiver);
@@ -55,9 +56,11 @@ interface IInputMethodManager {
             in ResultReceiver resultReceiver);
     // Report that a window has gained focus.  If 'attribute' is non-null,
     // this will also do a startInput.
-    InputBindResult windowGainedFocus(in IInputMethodClient client, in IBinder windowToken,
-            int controlFlags, int softInputMode, int windowFlags,
-            in EditorInfo attribute, IInputContext inputContext);
+    InputBindResult windowGainedFocus(
+            /* @InputMethodClient.StartInputReason */ int startInputReason,
+            in IInputMethodClient client, in IBinder windowToken, int controlFlags,
+            int softInputMode, int windowFlags, in EditorInfo attribute,
+            IInputContext inputContext);
 
     void showInputMethodPickerFromClient(in IInputMethodClient client,
             int auxiliarySubtypeMode);
index a035343..c27e9aa 100644 (file)
@@ -23,6 +23,49 @@ import java.lang.annotation.Retention;
 import static java.lang.annotation.RetentionPolicy.SOURCE;
 
 public final class InputMethodClient {
+    public static final int START_INPUT_REASON_UNSPECIFIED = 0;
+    public static final int START_INPUT_REASON_WINDOW_FOCUS_GAIN = 1;
+    public static final int START_INPUT_REASON_WINDOW_FOCUS_GAIN_REPORT_ONLY = 2;
+    public static final int START_INPUT_REASON_APP_CALLED_RESTART_INPUT_API = 3;
+    public static final int START_INPUT_REASON_CHECK_FOCUS = 4;
+    public static final int START_INPUT_REASON_BOUND_TO_IMMS = 5;
+    public static final int START_INPUT_REASON_UNBOUND_FROM_IMMS = 6;
+    public static final int START_INPUT_REASON_ACTIVATED_BY_IMMS = 7;
+    public static final int START_INPUT_REASON_DEACTIVATED_BY_IMMS = 8;
+
+    @Retention(SOURCE)
+    @IntDef({START_INPUT_REASON_UNSPECIFIED, START_INPUT_REASON_WINDOW_FOCUS_GAIN,
+            START_INPUT_REASON_WINDOW_FOCUS_GAIN_REPORT_ONLY,
+            START_INPUT_REASON_APP_CALLED_RESTART_INPUT_API, START_INPUT_REASON_CHECK_FOCUS,
+            START_INPUT_REASON_BOUND_TO_IMMS, START_INPUT_REASON_ACTIVATED_BY_IMMS,
+            START_INPUT_REASON_DEACTIVATED_BY_IMMS})
+    public @interface StartInputReason {}
+
+    public static String getStartInputReason(@StartInputReason final int reason) {
+        switch (reason) {
+            case START_INPUT_REASON_UNSPECIFIED:
+                return "UNSPECIFIED";
+            case START_INPUT_REASON_WINDOW_FOCUS_GAIN:
+                return "WINDOW_FOCUS_GAIN";
+            case START_INPUT_REASON_WINDOW_FOCUS_GAIN_REPORT_ONLY:
+                return "WINDOW_FOCUS_GAIN_REPORT_ONLY";
+            case START_INPUT_REASON_APP_CALLED_RESTART_INPUT_API:
+                return "APP_CALLED_RESTART_INPUT_API";
+            case START_INPUT_REASON_CHECK_FOCUS:
+                return "CHECK_FOCUS";
+            case START_INPUT_REASON_BOUND_TO_IMMS:
+                return "BOUND_TO_IMMS";
+            case START_INPUT_REASON_UNBOUND_FROM_IMMS:
+                return "UNBOUND_FROM_IMMS";
+            case START_INPUT_REASON_ACTIVATED_BY_IMMS:
+                return "ACTIVATED_BY_IMMS";
+            case START_INPUT_REASON_DEACTIVATED_BY_IMMS:
+                return "DEACTIVATED_BY_IMMS";
+            default:
+                return "Unknown=" + reason;
+        }
+    }
+
     public static final int UNBIND_REASON_UNSPECIFIED = 0;
     public static final int UNBIND_REASON_SWITCH_CLIENT = 1;
     public static final int UNBIND_REASON_SWITCH_IME = 2;
index 5e4f2b2..78a4e35 100644 (file)
@@ -1225,7 +1225,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
     void unbindCurrentClientLocked(
             /* @InputMethodClient.UnbindReason */ final int unbindClientReason) {
         if (mCurClient != null) {
-            if (DEBUG) Slog.v(TAG, "unbindCurrentInputLocked: client = "
+            if (DEBUG) Slog.v(TAG, "unbindCurrentInputLocked: client="
                     + mCurClient.client.asBinder());
             if (mBoundToMethod) {
                 mBoundToMethod = false;
@@ -1290,8 +1290,10 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
                 mCurId, mCurSeq, mCurUserActionNotificationSequenceNumber);
     }
 
-    InputBindResult startInputLocked(IInputMethodClient client,
-            IInputContext inputContext, EditorInfo attribute, int controlFlags) {
+    InputBindResult startInputLocked(
+            /* @InputMethodClient.StartInputReason */ final int startInputReason,
+            IInputMethodClient client, IInputContext inputContext, EditorInfo attribute,
+            int controlFlags) {
         // If no method is currently selected, do nothing.
         if (mCurMethodId == null) {
             return mNoBinding;
@@ -1320,8 +1322,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
         return startInputUncheckedLocked(cs, inputContext, attribute, controlFlags);
     }
 
-    InputBindResult startInputUncheckedLocked(@NonNull ClientState cs,
-            IInputContext inputContext, @NonNull EditorInfo attribute, int controlFlags) {
+    InputBindResult startInputUncheckedLocked(@NonNull ClientState cs, IInputContext inputContext,
+            @NonNull EditorInfo attribute, int controlFlags) {
         // If no method is currently selected, do nothing.
         if (mCurMethodId == null) {
             return mNoBinding;
@@ -1340,7 +1342,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
             // If the client is changing, we need to switch over to the new
             // one.
             unbindCurrentClientLocked(InputMethodClient.UNBIND_REASON_SWITCH_CLIENT);
-            if (DEBUG) Slog.v(TAG, "switching to client: client = "
+            if (DEBUG) Slog.v(TAG, "switching to client: client="
                     + cs.client.asBinder() + " keyguard=" + mCurClientInKeyguard);
 
             // If the screen is on, inform the new client it is active
@@ -1442,15 +1444,26 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
     }
 
     @Override
-    public InputBindResult startInput(IInputMethodClient client,
-            IInputContext inputContext, EditorInfo attribute, int controlFlags) {
+    public InputBindResult startInput(
+            /* @InputMethodClient.StartInputReason */ final int startInputReason,
+            IInputMethodClient client, IInputContext inputContext, EditorInfo attribute,
+            int controlFlags) {
         if (!calledFromValidUser()) {
             return null;
         }
         synchronized (mMethodMap) {
+            if (DEBUG) {
+                Slog.v(TAG, "startInput: reason="
+                        + InputMethodClient.getStartInputReason(startInputReason)
+                        + " client = " + client.asBinder()
+                        + " inputContext=" + inputContext
+                        + " attribute=" + attribute
+                        + " controlFlags=#" + Integer.toHexString(controlFlags));
+            }
             final long ident = Binder.clearCallingIdentity();
             try {
-                return startInputLocked(client, inputContext, attribute, controlFlags);
+                return startInputLocked(startInputReason, client, inputContext, attribute,
+                        controlFlags);
             } finally {
                 Binder.restoreCallingIdentity(ident);
             }
@@ -2151,17 +2164,21 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
     }
 
     @Override
-    public InputBindResult windowGainedFocus(IInputMethodClient client, IBinder windowToken,
-            int controlFlags, int softInputMode, int windowFlags,
-            EditorInfo attribute, IInputContext inputContext) {
+    public InputBindResult windowGainedFocus(
+            /* @InputMethodClient.StartInputReason */ final int startInputReason,
+            IInputMethodClient client, IBinder windowToken, int controlFlags, int softInputMode,
+            int windowFlags, EditorInfo attribute, IInputContext inputContext) {
         // Needs to check the validity before clearing calling identity
         final boolean calledFromValidUser = calledFromValidUser();
-
         InputBindResult res = null;
         long ident = Binder.clearCallingIdentity();
         try {
             synchronized (mMethodMap) {
-                if (DEBUG) Slog.v(TAG, "windowGainedFocus: " + client.asBinder()
+                if (DEBUG) Slog.v(TAG, "windowGainedFocus: reason="
+                        + InputMethodClient.getStartInputReason(startInputReason)
+                        + " client=" + client.asBinder()
+                        + " inputContext=" + inputContext
+                        + " attribute=" + attribute
                         + " controlFlags=#" + Integer.toHexString(controlFlags)
                         + " softInputMode=#" + Integer.toHexString(softInputMode)
                         + " windowFlags=#" + Integer.toHexString(windowFlags));