Hardening token validation in InputMethodManagerService

This CL adds missing token validations in
InputMethodManagerService#switchToNextInputMethod and
InputMethodManagerService#shouldOfferSwitchingToNextInputMethod.

This CL also fixes a possible race condition when validating
the token in InputMethodManagerService#updateStatusIcon.

BUG: 15420379
Change-Id: I043aa30a19c821f33effd57dfd6590b0e3ed817b
diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java
index 7086932..11d6a55 100644
--- a/services/core/java/com/android/server/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/InputMethodManagerService.java
@@ -1442,15 +1442,15 @@
 
     @Override
     public void updateStatusIcon(IBinder token, String packageName, int iconId) {
-        int uid = Binder.getCallingUid();
         long ident = Binder.clearCallingIdentity();
         try {
-            if (!calledWithValidToken(token)) {
-                Slog.e(TAG, "Ignoring updateStatusIcon due to an invalid token. uid:" + uid
-                        + " token:" + token);
-                return;
-            }
             synchronized (mMethodMap) {
+                if (!calledWithValidToken(token)) {
+                    final int uid = Binder.getCallingUid();
+                    Slog.e(TAG, "Ignoring updateStatusIcon due to an invalid token. uid:" + uid
+                            + " token:" + token);
+                    return;
+                }
                 if (iconId == 0) {
                     if (DEBUG) Slog.d(TAG, "hide the small icon for the input method");
                     if (mStatusBar != null) {
@@ -2202,6 +2202,12 @@
             return false;
         }
         synchronized (mMethodMap) {
+            if (!calledWithValidToken(token)) {
+                final int uid = Binder.getCallingUid();
+                Slog.e(TAG, "Ignoring switchToNextInputMethod due to an invalid token. uid:" + uid
+                        + " token:" + token);
+                return false;
+            }
             final ImeSubtypeListItem nextSubtype = mSwitchingController.getNextInputMethodLocked(
                     onlyCurrentIme, mMethodMap.get(mCurMethodId), mCurrentSubtype);
             if (nextSubtype == null) {
@@ -2219,6 +2225,12 @@
             return false;
         }
         synchronized (mMethodMap) {
+            if (!calledWithValidToken(token)) {
+                final int uid = Binder.getCallingUid();
+                Slog.e(TAG, "Ignoring shouldOfferSwitchingToNextInputMethod due to an invalid "
+                        + "token. uid:" + uid + " token:" + token);
+                return false;
+            }
             final ImeSubtypeListItem nextSubtype = mSwitchingController.getNextInputMethodLocked(
                     false /* onlyCurrentIme */, mMethodMap.get(mCurMethodId), mCurrentSubtype);
             if (nextSubtype == null) {