Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable concurrent multi-IME on InputMethodManagerService #2706

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
From 34cb807ade792a0f1c2c3869385ea75d1e56b0d6 Mon Sep 17 00:00:00 2001
From: Xu Bing <[email protected]>
Date: Fri, 15 Nov 2024 14:30:27 +0800
Subject: [PATCH] Enable concurrent multi-IME on InputMethodManagerService

It's experimental feature, temporarily enable it.

Tracked-On: OAM-127482
Signed-off-by: Xu Bing <[email protected]>
---
.../InputMethodManagerService.java | 51 ++++++++++++-------
1 file changed, 33 insertions(+), 18 deletions(-)

diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index 0e76c3f1e833..d00e38455087 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -1238,8 +1238,9 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
@Nullable ServiceThread ioThreadForTesting,
@Nullable IntFunction<InputMethodBindingController> bindingControllerForTesting) {
synchronized (ImfLock.class) {
- mExperimentalConcurrentMultiUserModeEnabled =
- experimentalConcurrentMultiUserModeEnabled;
+ //enable Concurrent Multi-IME as default
+ mExperimentalConcurrentMultiUserModeEnabled = true;
+ // experimentalConcurrentMultiUserModeEnabled;
mContext = context;
mRes = context.getResources();
SecureSettingsWrapper.onStart(mContext);
@@ -2141,7 +2142,8 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
String selectedMethodId = bindingController.getSelectedMethodId();
final String deviceMethodId = computeCurrentDeviceMethodIdLocked(bindingController.mUserId,
selectedMethodId);
- if (deviceMethodId == null) {
+ //hide ime policy as we can't start IME by windows focus
+ /*if (deviceMethodId == null) {
mVisibilityStateComputer.getImePolicy().setImeHiddenByDisplayPolicy(true);
} else if (!Objects.equals(deviceMethodId, selectedMethodId)) {
setInputMethodLocked(deviceMethodId, NOT_A_SUBTYPE_ID,
@@ -2150,7 +2152,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
}

if (mVisibilityStateComputer.getImePolicy().isImeHiddenByDisplayPolicy()) {
- hideCurrentInputLocked(mImeBindingState.mFocusedWindow, 0 /* flags */,
+ hideCurrentInputLocked(mImeBindingState.mFocusedWindow, 0 ,
SoftInputShowHideReason.HIDE_DISPLAY_IME_POLICY_HIDE);
return InputBindResult.NO_IME;
}
@@ -2159,7 +2161,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
if (selectedMethodId == null) {
return InputBindResult.NO_IME;
}
-
+*/
if (mCurClient != cs) {
prepareClientSwitchLocked(cs);
}
@@ -2232,8 +2234,8 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
return bindResult;
}
}
-
- bindingController.unbindCurrentMethod();
+ //reserve current method as we use the method simultaneously
+ //bindingController.unbindCurrentMethod();
return bindingController.bindCurrentMethod();
}

@@ -2330,7 +2332,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
private void prepareClientSwitchLocked(ClientState cs) {
// If the client is changing, we need to switch over to the new
// one.
- unbindCurrentClientLocked(UnbindReason.SWITCH_CLIENT);
+ //unbindCurrentClientLocked(UnbindReason.SWITCH_CLIENT);
// If the screen is on, inform the new client it is active
if (mIsInteractive) {
cs.mClient.setActive(true /* active */, false /* fullscreen */);
@@ -3156,7 +3158,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
intent.putExtra("input_method_id", id);
mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT);
}
- unbindCurrentClientLocked(UnbindReason.SWITCH_IME);
+ //unbindCurrentClientLocked(UnbindReason.SWITCH_IME);
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -3169,6 +3171,15 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
@SoftInputShowHideReason int reason) {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMMS.showSoftInput");
int uid = Binder.getCallingUid();
+ final int userId = UserHandle.getUserId(uid);
+ //need to use current user (10,11,12...) to show softinput, not system user 0
+ if (mCurrentUserId != userId) {
+ // We need to rebuild IMEs.
+ mCurrentUserId = userId;
+ postInputMethodSettingUpdatedLocked(false /* resetDefaultEnabledIme */);
+ updateInputMethodsFromSettingsLocked(true /* enabledChanged */);
+ }
+
ImeTracing.getInstance().triggerManagerServiceDump(
"InputMethodManagerService#showSoftInput", mDumper);
synchronized (ImfLock.class) {
@@ -3508,9 +3519,11 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
@NonNull ImeTracker.Token statsToken, @InputMethodManager.ShowFlags int flags,
@MotionEvent.ToolType int lastClickToolType, @Nullable ResultReceiver resultReceiver,
@SoftInputShowHideReason int reason) {
- if (!mVisibilityStateComputer.onImeShowFlags(statsToken, flags)) {
- return false;
- }
+ //always show IME when the focus is not on current window
+ //if (!mVisibilityStateComputer.onImeShowFlags(statsToken, flags)) {
+ // Slog.w(TAG, "showCurrentInputLocked statsToken= "+statsToken);
+ // return false;
+ //}

if (!mSystemReady) {
ImeTracker.forLogging().onFailed(statsToken, ImeTracker.PHASE_SERVER_SYSTEM_READY);
@@ -3951,16 +3964,17 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
final var statsToken = createStatsTokenForFocusedClient(isShow, imeVisRes.getReason());
mVisibilityApplier.applyImeVisibility(mImeBindingState.mFocusedWindow, statsToken,
imeVisRes.getState(), imeVisRes.getReason(), bindingController.mUserId);
- if (imeVisRes.getReason() == SoftInputShowHideReason.HIDE_UNSPECIFIED_WINDOW) {
+ //don't hide the IME even the focus lost
+ //if (imeVisRes.getReason() == SoftInputShowHideReason.HIDE_UNSPECIFIED_WINDOW) {
// If focused display changed, we should unbind current method
// to make app window in previous display relayout after Ime
// window token removed.
// Note that we can trust client's display ID as long as it matches
// to the display ID obtained from the window.
- if (cs.mSelfReportedDisplayId != getCurTokenDisplayIdLocked()) {
- bindingController.unbindCurrentMethod();
- }
- }
+ // if (cs.mSelfReportedDisplayId != getCurTokenDisplayIdLocked()) {
+ // bindingController.unbindCurrentMethod();
+ // }
+ // }
}
if (!didStart) {
if (editorInfo != null) {
@@ -3991,7 +4005,8 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_SERVER_CLIENT_KNOWN);
if (!isImeClientFocused(mImeBindingState.mFocusedWindow, cs)) {
Slog.w(TAG, String.format("Ignoring %s of uid %d : %s", methodName, uid, client));
- return false;
+ //always return true as showing IME without focus
+ return true;
}
}
ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_SERVER_CLIENT_FOCUSED);
--
2.34.1