From e1921a7b4d58c97570277fe83dbe9206f2db496d Mon Sep 17 00:00:00 2001 From: Tarandeep Singh Date: Thu, 11 Apr 2019 15:55:28 -0700 Subject: [PATCH] Allow MSIME to set inactive when window loses focus. MSIME doesn't work when existing InputConnection is restored. The fix is to allow MSIME to activate connection when window gains focus and set inactive when window loses focus. This mimics single session IME. Bug: 128751901 Test: Manually tested using steps in bug. Change-Id: I22cef6c1dacb0ca402840da94a2bf02b989da447 --- .../MultiClientInputMethodServiceDelegate.java | 11 +++++++++++ ...tiClientInputMethodServiceDelegateImpl.java | 4 ++++ ...iClientInputMethodPrivilegedOperations.aidl | 1 + ...iClientInputMethodPrivilegedOperations.java | 17 +++++++++++++++++ .../MultiClientInputMethodManagerService.java | 18 ++++++++++++++++++ 5 files changed, 51 insertions(+) diff --git a/core/java/android/inputmethodservice/MultiClientInputMethodServiceDelegate.java b/core/java/android/inputmethodservice/MultiClientInputMethodServiceDelegate.java index 0604f6a69d007..4b02085726f1d 100644 --- a/core/java/android/inputmethodservice/MultiClientInputMethodServiceDelegate.java +++ b/core/java/android/inputmethodservice/MultiClientInputMethodServiceDelegate.java @@ -374,4 +374,15 @@ public final class MultiClientInputMethodServiceDelegate { 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 bbe3a7fe1b319..04db8d6258065 100644 --- a/core/java/android/inputmethodservice/MultiClientInputMethodServiceDelegateImpl.java +++ b/core/java/android/inputmethodservice/MultiClientInputMethodServiceDelegateImpl.java @@ -190,4 +190,8 @@ final class MultiClientInputMethodServiceDelegateImpl { 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 69d9ccc9825ba..b5f2147784c09 100644 --- a/core/java/com/android/internal/inputmethod/IMultiClientInputMethodPrivilegedOperations.aidl +++ b/core/java/com/android/internal/inputmethod/IMultiClientInputMethodPrivilegedOperations.aidl @@ -31,4 +31,5 @@ interface IMultiClientInputMethodPrivilegedOperations { 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 922011707c4a3..1cf68872e2cf9 100644 --- a/core/java/com/android/internal/inputmethod/MultiClientInputMethodPrivilegedOperations.java +++ b/core/java/com/android/internal/inputmethod/MultiClientInputMethodPrivilegedOperations.java @@ -212,4 +212,21 @@ public class MultiClientInputMethodPrivilegedOperations { } } + /** + * 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 a2515c8bb8ccb..580150ed887e3 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 final class MultiClientInputMethodManagerService { 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; + } + } + } } /**