Merge "Allow MSIME to set inactive when window loses focus." into qt-dev
diff --git a/core/java/android/inputmethodservice/MultiClientInputMethodServiceDelegate.java b/core/java/android/inputmethodservice/MultiClientInputMethodServiceDelegate.java
index 0604f6a..4b02085 100644
--- a/core/java/android/inputmethodservice/MultiClientInputMethodServiceDelegate.java
+++ b/core/java/android/inputmethodservice/MultiClientInputMethodServiceDelegate.java
@@ -374,4 +374,15 @@
     public boolean isUidAllowedOnDisplay(int displayId, int uid) {
         return mImpl.isUidAllowedOnDisplay(displayId, uid);
     }
+
+    /**
+     * Can be called by MSIME to activate/deactivate a client when it is gaining/losing focus
+     * respectively.
+     *
+     * @param clientId client ID to activate/deactivate.
+     * @param active {@code true} to activate a client.
+     */
+    public void setActive(int clientId, boolean active) {
+        mImpl.setActive(clientId, active);
+    }
 }
diff --git a/core/java/android/inputmethodservice/MultiClientInputMethodServiceDelegateImpl.java b/core/java/android/inputmethodservice/MultiClientInputMethodServiceDelegateImpl.java
index bbe3a7f..04db8d6 100644
--- a/core/java/android/inputmethodservice/MultiClientInputMethodServiceDelegateImpl.java
+++ b/core/java/android/inputmethodservice/MultiClientInputMethodServiceDelegateImpl.java
@@ -190,4 +190,8 @@
     boolean isUidAllowedOnDisplay(int displayId, int uid) {
         return mPrivOps.isUidAllowedOnDisplay(displayId, uid);
     }
+
+    void setActive(int clientId, boolean active) {
+        mPrivOps.setActive(clientId, active);
+    }
 }
diff --git a/core/java/com/android/internal/inputmethod/IMultiClientInputMethodPrivilegedOperations.aidl b/core/java/com/android/internal/inputmethod/IMultiClientInputMethodPrivilegedOperations.aidl
index 69d9ccc..b5f2147 100644
--- a/core/java/com/android/internal/inputmethod/IMultiClientInputMethodPrivilegedOperations.aidl
+++ b/core/java/com/android/internal/inputmethod/IMultiClientInputMethodPrivilegedOperations.aidl
@@ -31,4 +31,5 @@
             in IMultiClientInputMethodSession multiClientSession, in InputChannel writeChannel);
     void reportImeWindowTarget(int clientId, int targetWindowHandle, in IBinder imeWindowToken);
     boolean isUidAllowedOnDisplay(int displayId, int uid);
+    void setActive(int clientId, boolean active);
 }
diff --git a/core/java/com/android/internal/inputmethod/MultiClientInputMethodPrivilegedOperations.java b/core/java/com/android/internal/inputmethod/MultiClientInputMethodPrivilegedOperations.java
index 9220117..1cf6887 100644
--- a/core/java/com/android/internal/inputmethod/MultiClientInputMethodPrivilegedOperations.java
+++ b/core/java/com/android/internal/inputmethod/MultiClientInputMethodPrivilegedOperations.java
@@ -212,4 +212,21 @@
         }
     }
 
+    /**
+     * Calls {@link IMultiClientInputMethodPrivilegedOperations#setActive(int, boolean)}.
+     * @param clientId client ID to be set active/inactive
+     * @param active {@code true} set set active.
+     */
+    @AnyThread
+    public void setActive(int clientId, boolean active) {
+        final IMultiClientInputMethodPrivilegedOperations ops = mOps.getAndWarnIfNull();
+        if (ops == null) {
+            return;
+        }
+        try {
+            ops.setActive(clientId, active);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java
index a2515c8..580150e 100644
--- a/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java
@@ -1228,6 +1228,24 @@
         public boolean isUidAllowedOnDisplay(int displayId, int uid) {
             return mIWindowManagerInternal.isUidAllowedOnDisplay(displayId, uid);
         }
+
+        @BinderThread
+        @Override
+        public void setActive(int clientId, boolean active) {
+            synchronized (mPerUserData.mLock) {
+                final InputMethodClientInfo clientInfo =
+                        mPerUserData.getClientFromIdLocked(clientId);
+                if (clientInfo == null) {
+                    Slog.e(TAG, "Unknown clientId=" + clientId);
+                    return;
+                }
+                try {
+                    clientInfo.mClient.setActive(active, false /* fullscreen */);
+                } catch (RemoteException e) {
+                    return;
+                }
+            }
+        }
     }
 
     /**