Fix issue #5680541: onStartInputView called upon focus loss

We should tell the app that it is inactive, before unbinding.
Otherwise when it is told to unbind it will see that it is still
supposed to be active and immediately re-bind.

Also change the calls to set the active state to go through the
message dispatch path, to ensure ordering is correct.

Change-Id: I246241eac8f7521f42c4c1eee7f46097337e7303
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java
index b979057..48219a4 100644
--- a/services/java/com/android/server/InputMethodManagerService.java
+++ b/services/java/com/android/server/InputMethodManagerService.java
@@ -139,6 +139,7 @@
 
     static final int MSG_UNBIND_METHOD = 3000;
     static final int MSG_BIND_METHOD = 3010;
+    static final int MSG_SET_ACTIVE = 3020;
 
     static final int MSG_HARD_KEYBOARD_SWITCH_CHANGED = 4000;
 
@@ -413,13 +414,9 @@
             }
 
             // Inform the current client of the change in active status
-            try {
-                if (mCurClient != null && mCurClient.client != null) {
-                    mCurClient.client.setActive(mScreenOn);
-                }
-            } catch (RemoteException e) {
-                Slog.w(TAG, "Got RemoteException sending 'screen on/off' notification to pid "
-                        + mCurClient.pid + " uid " + mCurClient.uid);
+            if (mCurClient != null && mCurClient.client != null) {
+                executeOrSendMessage(mCurClient.client, mCaller.obtainMessageIO(
+                        MSG_SET_ACTIVE, mScreenOn ? 1 : 0, mCurClient));
             }
         }
     }
@@ -882,17 +879,12 @@
                             MSG_UNBIND_INPUT, mCurMethod));
                 }
             }
+
+            executeOrSendMessage(mCurClient.client, mCaller.obtainMessageIO(
+                    MSG_SET_ACTIVE, 0, mCurClient));
             executeOrSendMessage(mCurClient.client, mCaller.obtainMessageIO(
                     MSG_UNBIND_METHOD, mCurSeq, mCurClient.client));
             mCurClient.sessionRequested = false;
-
-            // Call setActive(false) on the old client
-            try {
-                mCurClient.client.setActive(false);
-            } catch (RemoteException e) {
-                Slog.w(TAG, "Got RemoteException sending setActive(false) notification to pid "
-                        + mCurClient.pid + " uid " + mCurClient.uid);
-            }
             mCurClient = null;
 
             hideInputMethodMenuLocked();
@@ -987,12 +979,8 @@
 
             // If the screen is on, inform the new client it is active
             if (mScreenOn) {
-                try {
-                    cs.client.setActive(mScreenOn);
-                } catch (RemoteException e) {
-                    Slog.w(TAG, "Got RemoteException sending setActive notification to pid "
-                            + cs.pid + " uid " + cs.uid);
-                }
+                executeOrSendMessage(cs.client, mCaller.obtainMessageIO(
+                        MSG_SET_ACTIVE, mScreenOn ? 1 : 0, cs));
             }
         }
 
@@ -2140,6 +2128,15 @@
                     Slog.w(TAG, "Client died receiving input method " + args.arg2);
                 }
                 return true;
+            case MSG_SET_ACTIVE:
+                try {
+                    ((ClientState)msg.obj).client.setActive(msg.arg1 != 0);
+                } catch (RemoteException e) {
+                    Slog.w(TAG, "Got RemoteException sending setActive(false) notification to pid "
+                            + ((ClientState)msg.obj).pid + " uid "
+                            + ((ClientState)msg.obj).uid);
+                }
+                return true;
 
             // --------------------------------------------------------------
             case MSG_HARD_KEYBOARD_SWITCH_CHANGED: