summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Nikolas Havrikov <havrikov@google.com> 2021-12-22 15:02:39 +0100
committer Nikolas Havrikov <havrikov@google.com> 2022-01-04 17:53:54 +0100
commit3b5a09c14c631ed64239baaadb4919d1dd46431d (patch)
tree5b50683498d26b0031e5dd50520f258f07a5ff86
parentf724ab4719a0ca1d9f66be026e0440da3dc20273 (diff)
Refactor locking in input method framework
This CL introduces a static global lock ImfLock.class to be used instead of the mMethodMap. This allows to avoid erroneous warnings from the errorprone checker. Also, this CL fixes some cases, in which locked resources were accessed without holding the appropriate lock. Bug: 205676419 Test: atest CtsInputMethodTestCases Test: RUN_ERROR_PRONE=true m services -j | grep -e InputMethod | grep GuardedBy Change-Id: If50984d23410b11eb5f8ae731e1c0c5ca92447c6
-rw-r--r--services/core/java/com/android/server/inputmethod/ImfLock.java45
-rw-r--r--services/core/java/com/android/server/inputmethod/InputMethodBindingController.java80
-rw-r--r--services/core/java/com/android/server/inputmethod/InputMethodManagerService.java326
-rw-r--r--services/core/java/com/android/server/inputmethod/InputMethodMenuController.java12
-rw-r--r--services/core/java/com/android/server/inputmethod/InputMethodSubtypeSwitchingController.java2
5 files changed, 261 insertions, 204 deletions
diff --git a/services/core/java/com/android/server/inputmethod/ImfLock.java b/services/core/java/com/android/server/inputmethod/ImfLock.java
new file mode 100644
index 000000000000..612c14faa571
--- /dev/null
+++ b/services/core/java/com/android/server/inputmethod/ImfLock.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.inputmethod;
+
+/**
+ * The implicit lock of this class serves as the global lock for
+ * the {@link InputMethodManagerService} and its controllers,
+ * which contain the main logic of the input method framework (IMF).
+ *
+ * <p>
+ * This lock can be used as follows in code:
+ * <pre>
+ * synchronized (ImfLock.class) {
+ * ...
+ * }
+ * </pre>
+ *
+ * <p>
+ * For annotations, you can use a similar syntax:
+ * <pre>
+ * &#64;GuardedBy("ImfLock.class")
+ * myMethodDeclaration() {
+ * ...
+ * }
+ * </pre>
+ */
+final class ImfLock {
+ private ImfLock() {
+ // no instances
+ }
+}
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodBindingController.java b/services/core/java/com/android/server/inputmethod/InputMethodBindingController.java
index 8c88d4c48837..8f078158aa5c 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodBindingController.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodBindingController.java
@@ -72,16 +72,16 @@ final class InputMethodBindingController {
@NonNull private final WindowManagerInternal mWindowManagerInternal;
@NonNull private final Resources mRes;
- @GuardedBy("mMethodMap") private long mLastBindTime;
- @GuardedBy("mMethodMap") private boolean mHasConnection;
- @GuardedBy("mMethodMap") @Nullable private String mCurId;
- @GuardedBy("mMethodMap") @Nullable private String mSelectedMethodId;
- @GuardedBy("mMethodMap") @Nullable private Intent mCurIntent;
- @GuardedBy("mMethodMap") @Nullable private IInputMethod mCurMethod;
- @GuardedBy("mMethodMap") private int mCurMethodUid = Process.INVALID_UID;
- @GuardedBy("mMethodMap") private IBinder mCurToken;
- @GuardedBy("mMethodMap") private int mCurSeq;
- @GuardedBy("mMethodMap") private boolean mVisibleBound;
+ @GuardedBy("ImfLock.class") private long mLastBindTime;
+ @GuardedBy("ImfLock.class") private boolean mHasConnection;
+ @GuardedBy("ImfLock.class") @Nullable private String mCurId;
+ @GuardedBy("ImfLock.class") @Nullable private String mSelectedMethodId;
+ @GuardedBy("ImfLock.class") @Nullable private Intent mCurIntent;
+ @GuardedBy("ImfLock.class") @Nullable private IInputMethod mCurMethod;
+ @GuardedBy("ImfLock.class") private int mCurMethodUid = Process.INVALID_UID;
+ @GuardedBy("ImfLock.class") private IBinder mCurToken;
+ @GuardedBy("ImfLock.class") private int mCurSeq;
+ @GuardedBy("ImfLock.class") private boolean mVisibleBound;
private boolean mSupportsStylusHw;
/**
@@ -146,7 +146,7 @@ final class InputMethodBindingController {
* Time that we last initiated a bind to the input method, to determine
* if we should try to disconnect and reconnect to it.
*/
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
long getLastBindTime() {
return mLastBindTime;
}
@@ -155,7 +155,7 @@ final class InputMethodBindingController {
* Set to true if our ServiceConnection is currently actively bound to
* a service (whether or not we have gotten its IBinder back yet).
*/
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
boolean hasConnection() {
return mHasConnection;
}
@@ -168,7 +168,7 @@ final class InputMethodBindingController {
*
* @see #getSelectedMethodId()
*/
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
@Nullable
String getCurId() {
return mCurId;
@@ -187,13 +187,13 @@ final class InputMethodBindingController {
*
* @see #getCurId()
*/
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
@Nullable
String getSelectedMethodId() {
return mSelectedMethodId;
}
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
void setSelectedMethodId(@Nullable String selectedMethodId) {
mSelectedMethodId = selectedMethodId;
}
@@ -202,7 +202,7 @@ final class InputMethodBindingController {
* The token we have made for the currently active input method, to
* identify it in the future.
*/
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
IBinder getCurToken() {
return mCurToken;
}
@@ -210,7 +210,7 @@ final class InputMethodBindingController {
/**
* The Intent used to connect to the current input method.
*/
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
@Nullable
Intent getCurIntent() {
return mCurIntent;
@@ -220,7 +220,7 @@ final class InputMethodBindingController {
* The current binding sequence number, incremented every time there is
* a new bind performed.
*/
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
int getSequenceNumber() {
return mCurSeq;
}
@@ -229,7 +229,7 @@ final class InputMethodBindingController {
* Increase the current binding sequence number by one.
* Reset to 1 on overflow.
*/
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
void advanceSequenceNumber() {
mCurSeq += 1;
if (mCurSeq <= 0) {
@@ -241,7 +241,7 @@ final class InputMethodBindingController {
* If non-null, this is the input method service we are currently connected
* to.
*/
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
@Nullable
IInputMethod getCurMethod() {
return mCurMethod;
@@ -250,7 +250,7 @@ final class InputMethodBindingController {
/**
* If not {@link Process#INVALID_UID}, then the UID of {@link #getCurIntent()}.
*/
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
int getCurMethodUid() {
return mCurMethodUid;
}
@@ -258,7 +258,7 @@ final class InputMethodBindingController {
/**
* Indicates whether {@link #mVisibleConnection} is currently in use.
*/
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
boolean isVisibleBound() {
return mVisibleBound;
}
@@ -266,10 +266,10 @@ final class InputMethodBindingController {
/**
* Used to bring IME service up to visible adjustment while it is being shown.
*/
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
private final ServiceConnection mVisibleConnection = new ServiceConnection() {
@Override public void onBindingDied(ComponentName name) {
- synchronized (mMethodMap) {
+ synchronized (ImfLock.class) {
if (mVisibleBound) {
unbindVisibleConnection();
}
@@ -286,12 +286,12 @@ final class InputMethodBindingController {
/**
* Used to bind the IME while it is not currently being shown.
*/
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
private final ServiceConnection mMainConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMMS.onServiceConnected");
- synchronized (mMethodMap) {
+ synchronized (ImfLock.class) {
if (mCurIntent != null && name.equals(mCurIntent.getComponent())) {
mCurMethod = IInputMethod.Stub.asInterface(service);
updateCurrentMethodUid();
@@ -318,7 +318,7 @@ final class InputMethodBindingController {
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
private void updateCurrentMethodUid() {
final String curMethodPackage = mCurIntent.getComponent().getPackageName();
final int curMethodUid = mPackageManagerInternal.getPackageUid(
@@ -344,7 +344,7 @@ final class InputMethodBindingController {
// refreshed when this method is called back. Running
// adb install -r <APK that implements the current IME>
// would be a good way to trigger such a situation.
- synchronized (mMethodMap) {
+ synchronized (ImfLock.class) {
if (DEBUG) {
Slog.v(TAG, "Service disconnected: " + name + " mCurIntent=" + mCurIntent);
}
@@ -361,7 +361,7 @@ final class InputMethodBindingController {
}
};
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
void unbindCurrentMethod() {
if (mVisibleBound) {
unbindVisibleConnection();
@@ -380,14 +380,14 @@ final class InputMethodBindingController {
clearCurMethodAndSessions();
}
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
private void clearCurMethodAndSessions() {
mService.clearClientSessionsLocked();
mCurMethod = null;
mCurMethodUid = Process.INVALID_UID;
}
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
private void removeCurrentToken() {
int curTokenDisplayId = mService.getCurTokenDisplayIdLocked();
@@ -400,7 +400,7 @@ final class InputMethodBindingController {
mCurToken = null;
}
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
@NonNull
InputBindResult bindCurrentMethod() {
InputMethodInfo info = mMethodMap.get(mSelectedMethodId);
@@ -438,7 +438,7 @@ final class InputMethodBindingController {
return intent;
}
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
private void addFreshWindowToken() {
int displayIdToShowIme = mService.getDisplayIdToShowImeLocked();
mCurToken = new Binder();
@@ -458,19 +458,19 @@ final class InputMethodBindingController {
}
}
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
private void unbindMainConnection() {
mContext.unbindService(mMainConnection);
mHasConnection = false;
}
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
void unbindVisibleConnection() {
mContext.unbindService(mVisibleConnection);
mVisibleBound = false;
}
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
private boolean bindCurrentInputMethodService(ServiceConnection conn, int flags) {
if (mCurIntent == null || conn == null) {
Slog.e(TAG, "--- bind failed: service = " + mCurIntent + ", conn = " + conn);
@@ -480,14 +480,14 @@ final class InputMethodBindingController {
new UserHandle(mSettings.getCurrentUserId()));
}
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
private boolean bindCurrentInputMethodServiceVisibleConnection() {
mVisibleBound = bindCurrentInputMethodService(mVisibleConnection,
IME_VISIBLE_BIND_FLAGS);
return mVisibleBound;
}
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
private boolean bindCurrentInputMethodServiceMainConnection() {
mHasConnection = bindCurrentInputMethodService(mMainConnection,
mImeConnectionBindFlags);
@@ -500,7 +500,7 @@ final class InputMethodBindingController {
* <p>
* Performs a rebind if no binding is achieved in {@link #TIME_TO_RECONNECT} milliseconds.
*/
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
void setCurrentMethodVisible() {
if (mCurMethod != null) {
if (DEBUG) Slog.d(TAG, "setCurrentMethodVisible: mCurToken=" + mCurToken);
@@ -541,7 +541,7 @@ final class InputMethodBindingController {
/**
* Remove the binding needed for the IME to be shown.
*/
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
void setCurrentMethodNotVisible() {
if (mVisibleBound) {
unbindVisibleConnection();
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index 7d1be14d4d31..06ba0e6aeb6b 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -303,9 +303,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
@Nullable
private AudioManagerInternal mAudioManagerInternal = null;
-
- // All known input methods. mMethodMap also serves as the global
- // lock for this class.
+ // All known input methods.
final ArrayList<InputMethodInfo> mMethodList = new ArrayList<>();
final ArrayMap<String, InputMethodInfo> mMethodMap = new ArrayMap<>();
final InputMethodSubtypeSwitchingController mSwitchingController;
@@ -313,18 +311,18 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
/**
* Tracks how many times {@link #mMethodMap} was updated.
*/
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
private int mMethodMapUpdateCount = 0;
/**
* The display id for which the latest startInput was called.
*/
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
int getDisplayIdToShowImeLocked() {
return mDisplayIdToShowIme;
}
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
private int mDisplayIdToShowIme = INVALID_DISPLAY;
// Ongoing notification
@@ -410,7 +408,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
}
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
final ArrayMap<IBinder, ClientState> mClients = new ArrayMap<>();
/**
@@ -431,13 +429,13 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
*
* @see InputMethodBindingController#getCurId()
*/
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
@Nullable
- private String getSelectedMethodIdLocked() {
+ String getSelectedMethodIdLocked() {
return mBindingController.getSelectedMethodId();
}
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
private void setSelectedMethodIdLocked(@Nullable String selectedMethodId) {
mBindingController.setSelectedMethodId(selectedMethodId);
}
@@ -446,7 +444,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
* The current binding sequence number, incremented every time there is
* a new bind performed.
*/
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
private int getSequenceNumberLocked() {
return mBindingController.getSequenceNumber();
}
@@ -455,7 +453,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
* Increase the current binding sequence number by one.
* Reset to 1 on overflow.
*/
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
private void advanceSequenceNumberLocked() {
mBindingController.advanceSequenceNumber();
}
@@ -517,7 +515,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
*
* @see #getSelectedMethodIdLocked()
*/
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
@Nullable
private String getCurIdLocked() {
return mBindingController.getCurId();
@@ -537,7 +535,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
* Set to true if our ServiceConnection is currently actively bound to
* a service (whether or not we have gotten its IBinder back yet).
*/
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
private boolean hasConnectionLocked() {
return mBindingController.hasConnection();
}
@@ -570,7 +568,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
/**
* The Intent used to connect to the current input method.
*/
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
@Nullable
private Intent getCurIntentLocked() {
return mBindingController.getCurIntent();
@@ -580,7 +578,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
* The token we have made for the currently active input method, to
* identify it in the future.
*/
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
private IBinder getCurTokenLocked() {
return mBindingController.getCurToken();
}
@@ -588,23 +586,23 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
/**
* The displayId of current active input method.
*/
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
int getCurTokenDisplayIdLocked() {
return mCurTokenDisplayId;
}
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
void setCurTokenDisplayIdLocked(int curTokenDisplayId) {
mCurTokenDisplayId = curTokenDisplayId;
}
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
private int mCurTokenDisplayId = INVALID_DISPLAY;
/**
* The host input token of the current active input method.
*/
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
@Nullable
private IBinder mCurHostInputToken;
@@ -620,7 +618,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
* If non-null, this is the input method service we are currently connected
* to.
*/
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
@Nullable
private IInputMethod getCurMethodLocked() {
return mBindingController.getCurMethod();
@@ -629,7 +627,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
/**
* If not {@link Process#INVALID_UID}, then the UID of {@link #getCurIntentLocked()}.
*/
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
private int getCurMethodUidLocked() {
return mBindingController.getCurMethodUid();
}
@@ -638,7 +636,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
* Time that we last initiated a bind to the input method, to determine
* if we should try to disconnect and reconnect to it.
*/
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
private long getLastBindTimeLocked() {
return mBindingController.getLastBindTime();
}
@@ -765,7 +763,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
}
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
private final WeakHashMap<IBinder, IBinder> mImeTargetWindowMap = new WeakHashMap<>();
private static final class SoftInputShowHideHistory {
@@ -873,7 +871,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
* {@link InputMethodManager#showSoftInput(View, int)}.
* This map tracks origin of showSoftInput requests.
*/
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
private final WeakHashMap<IBinder, IBinder> mShowRequestWindowMap = new WeakHashMap<>();
/**
@@ -881,7 +879,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
* {@link InputMethodManager#hideSoftInputFromWindow(IBinder, int)}.
* This map tracks origin of hideSoftInput requests.
*/
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
private final WeakHashMap<IBinder, IBinder> mHideRequestWindowMap = new WeakHashMap<>();
/**
@@ -1038,11 +1036,11 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
}
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
@NonNull
private final StartInputHistory mStartInputHistory = new StartInputHistory();
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
@NonNull
private final SoftInputShowHideHistory mSoftInputShowHideHistory =
new SoftInputShowHideHistory();
@@ -1060,7 +1058,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
super(handler);
}
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
public void registerContentObserverLocked(@UserIdInt int userId) {
if (mRegistered && mUserId == userId) {
return;
@@ -1092,7 +1090,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD);
final Uri accessibilityRequestingNoImeUri = Settings.Secure.getUriFor(
Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE);
- synchronized (mMethodMap) {
+ synchronized (ImfLock.class) {
if (showImeUri.equals(uri)) {
mMenuController.updateKeyboardFromSettingsLocked();
} else if (accessibilityRequestingNoImeUri.equals(uri)) {
@@ -1198,7 +1196,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
* <p>Caution: This method must not be called when system is not ready.</p>
*/
void onActionLocaleChanged() {
- synchronized (mMethodMap) {
+ synchronized (ImfLock.class) {
final LocaleList possibleNewLocale = mRes.getConfiguration().getLocales();
if (possibleNewLocale != null && possibleNewLocale.equals(mLastSystemLocales)) {
return;
@@ -1220,7 +1218,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
* dynamically unless the entire package is updated, which also always triggers package
* rescanning.</p>
*/
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
final private ArraySet<String> mKnownImePackageNames = new ArraySet<>();
/**
@@ -1243,17 +1241,17 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
*/
private boolean mImePackageAppeared = false;
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
void clearKnownImePackageNamesLocked() {
mKnownImePackageNames.clear();
}
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
final void addKnownImePackageNameLocked(@NonNull String packageName) {
mKnownImePackageNames.add(packageName);
}
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
private boolean isChangingPackagesOfCurrentUserLocked() {
final int userId = getChangingUserId();
final boolean retval = userId == mSettings.getCurrentUserId();
@@ -1267,7 +1265,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
@Override
public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
- synchronized (mMethodMap) {
+ synchronized (ImfLock.class) {
if (!isChangingPackagesOfCurrentUserLocked()) {
return false;
}
@@ -1355,7 +1353,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
mImePackageAppeared = false;
}
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
private boolean shouldRebuildInputMethodListLocked() {
// This method is guaranteed to be called only by getRegisteredHandler().
@@ -1379,7 +1377,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
private void onFinishPackageChangesInternal() {
- synchronized (mMethodMap) {
+ synchronized (ImfLock.class) {
if (!isChangingPackagesOfCurrentUserLocked()) {
return;
}
@@ -1502,7 +1500,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
@Override
public void run() {
- synchronized (mService.mMethodMap) {
+ synchronized (ImfLock.class) {
if (mService.mUserSwitchHandlerTask != this) {
// This task was already canceled before it is handled here. So do nothing.
return;
@@ -1519,7 +1517,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
* a handler callback. This needs to be set and unset only within the lock.
*/
@Nullable
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
private UserSwitchHandlerTask mUserSwitchHandlerTask;
public static final class Lifecycle extends SystemService {
@@ -1541,7 +1539,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
@Override
public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) {
// Called on ActivityManager thread.
- synchronized (mService.mMethodMap) {
+ synchronized (ImfLock.class) {
mService.scheduleSwitchUserTaskLocked(to.getUserIdentifier(),
/* clientToBeReset= */ null);
}
@@ -1567,7 +1565,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
void onUnlockUser(@UserIdInt int userId) {
- synchronized(mMethodMap) {
+ synchronized (ImfLock.class) {
final int currentUserId = mSettings.getCurrentUserId();
if (DEBUG) {
Slog.d(TAG, "onUnlockUser: userId=" + userId + " curUserId=" + currentUserId);
@@ -1584,7 +1582,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
}
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
void scheduleSwitchUserTaskLocked(@UserIdInt int userId,
@Nullable IInputMethodClient clientToBeReset) {
if (mUserSwitchHandlerTask != null) {
@@ -1677,7 +1675,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
com.android.internal.R.bool.config_preventImeStartupUnlessTextEditor);
}
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
private void resetDefaultImeLocked(Context context) {
// Do not reset the default (current) IME when it is a 3rd-party IME
String selectedMethodId = getSelectedMethodIdLocked();
@@ -1697,7 +1695,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
setSelectedInputMethodAndSubtypeLocked(defIm, NOT_A_SUBTYPE_ID, false);
}
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
private void switchUserOnHandlerLocked(@UserIdInt int newUserId,
IInputMethodClient clientToBeReset) {
if (DEBUG) Slog.d(TAG, "Switching user stage 1/3. newUserId=" + newUserId
@@ -1783,7 +1781,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
public void systemRunning(StatusBarManagerService statusBar) {
- synchronized (mMethodMap) {
+ synchronized (ImfLock.class) {
if (DEBUG) {
Slog.d(TAG, "--- systemReady");
}
@@ -1839,7 +1837,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
// Check whether or not this is a valid IPC. Assumes an IPC is valid when either
// 1) it comes from the system process
// 2) the calling process' user id is identical to the current user id IMMS thinks.
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
private boolean calledFromValidUserLocked() {
final int uid = Binder.getCallingUid();
final int userId = UserHandle.getUserId(uid);
@@ -1883,7 +1881,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
* @param token The window token given to the input method when it was started.
* @return true if and only if non-null valid token is specified.
*/
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
private boolean calledWithValidTokenLocked(@NonNull IBinder token) {
if (token == null) {
throw new InvalidParameterException("token must not be null.");
@@ -1902,7 +1900,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
mContext.enforceCallingPermission(
Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
}
- synchronized (mMethodMap) {
+ synchronized (ImfLock.class) {
final int[] resolvedUserIds = InputMethodUtils.resolveUserId(userId,
mSettings.getCurrentUserId(), null);
if (resolvedUserIds.length != 1) {
@@ -1934,7 +1932,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
mContext.enforceCallingPermission(
Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
}
- synchronized (mMethodMap) {
+ synchronized (ImfLock.class) {
final int[] resolvedUserIds = InputMethodUtils.resolveUserId(userId,
mSettings.getCurrentUserId(), null);
if (resolvedUserIds.length != 1) {
@@ -1949,7 +1947,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
}
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
private List<InputMethodInfo> getInputMethodListLocked(@UserIdInt int userId,
@DirectBootAwareness int directBootAwareness) {
final ArrayList<InputMethodInfo> methodList;
@@ -1969,7 +1967,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
return methodList;
}
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
private List<InputMethodInfo> getEnabledInputMethodListLocked(@UserIdInt int userId) {
if (userId == mSettings.getCurrentUserId()) {
return mSettings.getEnabledInputMethodListLocked();
@@ -1980,7 +1978,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
return settings.getEnabledInputMethodListLocked();
}
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
private void onCreateInlineSuggestionsRequestLocked(@UserIdInt int userId,
InlineSuggestionsRequestInfo requestInfo, IInlineSuggestionsRequestCallback callback) {
final InputMethodInfo imi = mMethodMap.get(getSelectedMethodIdLocked());
@@ -2088,7 +2086,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
* @param hostInputToken the host input token of the current active input method
*/
void setCurHostInputToken(@NonNull IBinder callerImeToken, @Nullable IBinder hostInputToken) {
- synchronized (mMethodMap) {
+ synchronized (ImfLock.class) {
if (!calledWithValidTokenLocked(callerImeToken)) {
return;
}
@@ -2107,7 +2105,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
public List<InputMethodSubtype> getEnabledInputMethodSubtypeList(String imiId,
boolean allowsImplicitlySelectedSubtypes) {
final int callingUserId = UserHandle.getCallingUserId();
- synchronized (mMethodMap) {
+ synchronized (ImfLock.class) {
final int[] resolvedUserIds = InputMethodUtils.resolveUserId(callingUserId,
mSettings.getCurrentUserId(), null);
if (resolvedUserIds.length != 1) {
@@ -2123,7 +2121,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
}
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
private List<InputMethodSubtype> getEnabledInputMethodSubtypeListLocked(String imiId,
boolean allowsImplicitlySelectedSubtypes, @UserIdInt int userId) {
if (userId == mSettings.getCurrentUserId()) {
@@ -2178,7 +2176,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
// actually running.
final int callerUid = Binder.getCallingUid();
final int callerPid = Binder.getCallingPid();
- synchronized (mMethodMap) {
+ synchronized (ImfLock.class) {
// TODO: Optimize this linear search.
final int numClients = mClients.size();
for (int i = 0; i < numClients; ++i) {
@@ -2211,7 +2209,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
void removeClient(IInputMethodClient client) {
- synchronized (mMethodMap) {
+ synchronized (ImfLock.class) {
ClientState cs = mClients.remove(client.asBinder());
if (cs != null) {
client.asBinder().unlinkToDeath(cs.clientDeathRecipient, 0);
@@ -2245,7 +2243,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
}
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
void unbindCurrentClientLocked(@UnbindReason int unbindClientReason) {
if (mCurClient != null) {
if (DEBUG) Slog.v(TAG, "unbindCurrentInputLocked: client="
@@ -2271,13 +2269,13 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
}
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
void clearInputShowRequestLocked() {
mShowRequested = mInputShown;
mInputShown = false;
}
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
private int getImeShowFlagsLocked() {
int flags = 0;
if (mShowForced) {
@@ -2289,7 +2287,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
return flags;
}
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
private int getAppShowFlagsLocked() {
int flags = 0;
if (mShowForced) {
@@ -2300,7 +2298,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
return flags;
}
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
@NonNull
InputBindResult attachNewInputLocked(@StartInputReason int startInputReason, boolean initial) {
if (!mBoundToMethod) {
@@ -2350,7 +2348,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
curId, getSequenceNumberLocked(), suppressesSpellChecker);
}
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
@NonNull
InputBindResult startInputUncheckedLocked(@NonNull ClientState cs, IInputContext inputContext,
@NonNull EditorInfo attribute, @StartInputFlags int startInputFlags,
@@ -2437,14 +2435,14 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
return mBindingController.bindCurrentMethod();
}
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
private boolean isSelectedMethodBoundLocked() {
String curId = getCurIdLocked();
return curId != null && curId.equals(getSelectedMethodIdLocked())
&& mDisplayIdToShowIme == mCurTokenDisplayId;
}
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
private void prepareClientSwitchLocked(ClientState cs) {
// If the client is changing, we need to switch over to the new
// one.
@@ -2456,7 +2454,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
}
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
@Nullable
private InputBindResult tryReuseConnectionLocked(@NonNull ClientState cs) {
if (hasConnectionLocked()) {
@@ -2529,7 +2527,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
void onSessionCreated(IInputMethod method, IInputMethodSession session,
InputChannel channel) {
- synchronized (mMethodMap) {
+ synchronized (ImfLock.class) {
if (mUserSwitchHandlerTask != null) {
// We have a pending user-switching task so it's better to just ignore this session.
channel.dispose();
@@ -2557,7 +2555,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
channel.dispose();
}
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
void resetSystemUiLocked() {
// Set IME window status as invisible when unbinding current method.
mImeWindowVis = 0;
@@ -2567,14 +2565,14 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
mCurHostInputToken = null;
}
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
void resetCurrentMethodAndClientLocked(@UnbindReason int unbindClientReason) {
setSelectedMethodIdLocked(null);
mBindingController.unbindCurrentMethod();
unbindCurrentClientLocked(unbindClientReason);
}
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
void reRequestCurrentClientSessionLocked() {
if (mCurClient != null) {
clearClientSessionLocked(mCurClient);
@@ -2582,7 +2580,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
}
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
void requestClientSessionLocked(ClientState cs) {
if (!cs.sessionRequested) {
if (DEBUG) Slog.v(TAG, "Creating new session for client " + cs);
@@ -2595,14 +2593,14 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
}
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
void clearClientSessionLocked(ClientState cs) {
finishSessionLocked(cs.curSession);
cs.curSession = null;
cs.sessionRequested = false;
}
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
private void finishSessionLocked(SessionState sessionState) {
if (sessionState != null) {
if (sessionState.session != null) {
@@ -2621,7 +2619,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
}
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
void clearClientSessionsLocked() {
if (getCurMethodLocked() != null) {
final int numClients = mClients.size();
@@ -2640,7 +2638,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
@BinderThread
private void updateStatusIcon(@NonNull IBinder token, String packageName,
@DrawableRes int iconId) {
- synchronized (mMethodMap) {
+ synchronized (ImfLock.class) {
if (!calledWithValidTokenLocked(token)) {
return;
}
@@ -2674,14 +2672,14 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
}
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
private void hideStatusBarIconLocked() {
if (mStatusBar != null) {
mStatusBar.setIconVisibility(mSlotIme, false);
}
}
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
private boolean shouldShowImeSwitcherLocked(int visibility) {
if (!mShowOngoingImeSwitcherForPhones) return false;
if (mMenuController.getSwitchingDialogLocked() != null) return false;
@@ -2750,7 +2748,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
private void setImeWindowStatus(@NonNull IBinder token, int vis, int backDisposition) {
final int topFocusedDisplayId = mWindowManagerInternal.getTopFocusedDisplayId();
- synchronized (mMethodMap) {
+ synchronized (ImfLock.class) {
if (!calledWithValidTokenLocked(token)) {
return;
}
@@ -2785,7 +2783,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
@BinderThread
private void reportStartInput(@NonNull IBinder token, IBinder startInputToken) {
- synchronized (mMethodMap) {
+ synchronized (ImfLock.class) {
if (!calledWithValidTokenLocked(token)) {
return;
}
@@ -2798,7 +2796,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
private void updateImeWindowStatus(boolean disableImeIcon) {
- synchronized (mMethodMap) {
+ synchronized (ImfLock.class) {
if (disableImeIcon) {
updateSystemUiLocked(0, mBackDisposition);
} else {
@@ -2807,13 +2805,13 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
}
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
void updateSystemUiLocked() {
updateSystemUiLocked(mImeWindowVis, mBackDisposition);
}
// Caution! This method is called in this class. Handle multi-user carefully
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
private void updateSystemUiLocked(int vis, int backDisposition) {
if (getCurTokenLocked() == null) {
return;
@@ -2882,13 +2880,13 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
}
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
void updateFromSettingsLocked(boolean enabledMayChange) {
updateInputMethodsFromSettingsLocked(enabledMayChange);
mMenuController.updateKeyboardFromSettingsLocked();
}
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
void updateInputMethodsFromSettingsLocked(boolean enabledMayChange) {
if (enabledMayChange) {
List<InputMethodInfo> enabled = mSettings.getEnabledInputMethodListLocked();
@@ -2943,7 +2941,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
void setInputMethodLocked(String id, int subtypeId) {
InputMethodInfo info = mMethodMap.get(id);
if (info == null) {
@@ -3015,7 +3013,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
int uid = Binder.getCallingUid();
ImeTracing.getInstance().triggerManagerServiceDump(
"InputMethodManagerService#showSoftInput");
- synchronized (mMethodMap) {
+ synchronized (ImfLock.class) {
if (!calledFromValidUserLocked()) {
return false;
}
@@ -3051,7 +3049,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
public void reportPerceptibleAsync(IBinder windowToken, boolean perceptible) {
Objects.requireNonNull(windowToken, "windowToken must not be null");
int uid = Binder.getCallingUid();
- synchronized (mMethodMap) {
+ synchronized (ImfLock.class) {
if (!calledFromValidUserLocked()) {
return;
}
@@ -3068,7 +3066,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
}
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
boolean showCurrentInputLocked(IBinder windowToken, int flags, ResultReceiver resultReceiver,
@SoftInputShowHideReason int reason) {
mShowRequested = true;
@@ -3109,7 +3107,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
int uid = Binder.getCallingUid();
ImeTracing.getInstance().triggerManagerServiceDump(
"InputMethodManagerService#hideSoftInput");
- synchronized (mMethodMap) {
+ synchronized (ImfLock.class) {
if (!InputMethodManagerService.this.calledFromValidUserLocked()) {
return false;
}
@@ -3146,7 +3144,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
}
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
boolean hideCurrentInputLocked(IBinder windowToken, int flags, ResultReceiver resultReceiver,
@SoftInputShowHideReason int reason) {
if ((flags&InputMethodManager.HIDE_IMPLICIT_ONLY) != 0
@@ -3240,7 +3238,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
userId = callingUserId;
}
final InputBindResult result;
- synchronized (mMethodMap) {
+ synchronized (ImfLock.class) {
final long ident = Binder.clearCallingIdentity();
try {
result = startInputOrWindowGainedFocusInternalLocked(startInputReason,
@@ -3265,7 +3263,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
}
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
@NonNull
private InputBindResult startInputOrWindowGainedFocusInternalLocked(
@StartInputReason int startInputReason, IInputMethodClient client,
@@ -3538,7 +3536,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
return mWindowManagerInternal.shouldRestoreImeVisibility(windowToken);
}
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
private boolean canShowInputMethodPickerLocked(IInputMethodClient client) {
// TODO(yukawa): multi-display support.
final int uid = Binder.getCallingUid();
@@ -3557,7 +3555,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
@Override
public void showInputMethodPickerFromClient(IInputMethodClient client,
int auxiliarySubtypeMode) {
- synchronized (mMethodMap) {
+ synchronized (ImfLock.class) {
if (!calledFromValidUserLocked()) {
return;
}
@@ -3594,14 +3592,14 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
* A test API for CTS to make sure that the input method menu is showing.
*/
public boolean isInputMethodPickerShownForTest() {
- synchronized(mMethodMap) {
+ synchronized (ImfLock.class) {
return mMenuController.isisInputMethodPickerShownForTestLocked();
}
}
@BinderThread
private void setInputMethod(@NonNull IBinder token, String id) {
- synchronized (mMethodMap) {
+ synchronized (ImfLock.class) {
if (!calledWithValidTokenLocked(token)) {
return;
}
@@ -3612,7 +3610,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
@BinderThread
private void setInputMethodAndSubtype(@NonNull IBinder token, String id,
InputMethodSubtype subtype) {
- synchronized (mMethodMap) {
+ synchronized (ImfLock.class) {
if (!calledWithValidTokenLocked(token)) {
return;
}
@@ -3629,7 +3627,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
@Override
public void showInputMethodAndSubtypeEnablerFromClient(
IInputMethodClient client, String inputMethodId) {
- synchronized (mMethodMap) {
+ synchronized (ImfLock.class) {
// TODO(yukawa): Should we verify the display ID?
if (!calledFromValidUserLocked()) {
return;
@@ -3641,7 +3639,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
@BinderThread
private boolean switchToPreviousInputMethod(@NonNull IBinder token) {
- synchronized (mMethodMap) {
+ synchronized (ImfLock.class) {
if (!calledWithValidTokenLocked(token)) {
return false;
}
@@ -3713,7 +3711,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
@BinderThread
private boolean switchToNextInputMethod(@NonNull IBinder token, boolean onlyCurrentIme) {
- synchronized (mMethodMap) {
+ synchronized (ImfLock.class) {
if (!calledWithValidTokenLocked(token)) {
return false;
}
@@ -3730,7 +3728,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
@BinderThread
private boolean shouldOfferSwitchingToNextInputMethod(@NonNull IBinder token) {
- synchronized (mMethodMap) {
+ synchronized (ImfLock.class) {
if (!calledWithValidTokenLocked(token)) {
return false;
}
@@ -3746,7 +3744,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
@Override
public InputMethodSubtype getLastInputMethodSubtype() {
- synchronized (mMethodMap) {
+ synchronized (ImfLock.class) {
if (!calledFromValidUserLocked()) {
return null;
}
@@ -3784,7 +3782,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
+ subtype.getLocale() + ", " + subtype.getMode());
}
}
- synchronized (mMethodMap) {
+ synchronized (ImfLock.class) {
if (!calledFromValidUserLocked()) {
return;
}
@@ -3835,7 +3833,11 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
@Override
public int getInputMethodWindowVisibleHeight() {
// TODO(yukawa): Should we verify the display ID?
- return mWindowManagerInternal.getInputMethodWindowVisibleHeight(mCurTokenDisplayId);
+ final int curTokenDisplayId;
+ synchronized (ImfLock.class) {
+ curTokenDisplayId = mCurTokenDisplayId;
+ }
+ return mWindowManagerInternal.getInputMethodWindowVisibleHeight(curTokenDisplayId);
}
@Override
@@ -3914,7 +3916,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
public void startImeTrace() {
ImeTracing.getInstance().startTrace(null /* printwriter */);
ArrayMap<IBinder, ClientState> clients;
- synchronized (mMethodMap) {
+ synchronized (ImfLock.class) {
clients = new ArrayMap<>(mClients);
}
for (ClientState state : clients.values()) {
@@ -3933,7 +3935,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
public void stopImeTrace() {
ImeTracing.getInstance().stopTrace(null /* printwriter */);
ArrayMap<IBinder, ClientState> clients;
- synchronized (mMethodMap) {
+ synchronized (ImfLock.class) {
clients = new ArrayMap<>(mClients);
}
for (ClientState state : clients.values()) {
@@ -3948,7 +3950,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
private void dumpDebug(ProtoOutputStream proto, long fieldId) {
- synchronized (mMethodMap) {
+ synchronized (ImfLock.class) {
final long token = proto.start(fieldId);
proto.write(CUR_METHOD_ID, getSelectedMethodIdLocked());
proto.write(CUR_SEQ, getSequenceNumberLocked());
@@ -3989,7 +3991,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
if (DEBUG) {
Slog.d(TAG, "Got the notification of a user action.");
}
- synchronized (mMethodMap) {
+ synchronized (ImfLock.class) {
if (getCurTokenLocked() != token) {
if (DEBUG) {
Slog.d(TAG, "Ignoring the user action notification from IMEs that are no longer"
@@ -4007,7 +4009,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
@BinderThread
private void applyImeVisibility(IBinder token, IBinder windowToken, boolean setVisible) {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMMS.applyImeVisibility");
- synchronized (mMethodMap) {
+ synchronized (ImfLock.class) {
if (!calledWithValidTokenLocked(token)) {
return;
}
@@ -4031,7 +4033,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
private void setInputMethodWithSubtypeIdLocked(IBinder token, String id, int subtypeId) {
if (token == null) {
if (mContext.checkCallingOrSelfPermission(
@@ -4056,6 +4058,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
/** Called right after {@link IInputMethod#showSoftInput}. */
+ @GuardedBy("ImfLock.class")
private void onShowHideSoftInputRequested(boolean show, IBinder requestToken,
@SoftInputShowHideReason int reason) {
final WindowManagerInternal.ImeTargetInfo info =
@@ -4070,7 +4073,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
@BinderThread
private void hideMySoftInput(@NonNull IBinder token, int flags) {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMMS.hideMySoftInput");
- synchronized (mMethodMap) {
+ synchronized (ImfLock.class) {
if (!calledWithValidTokenLocked(token)) {
return;
}
@@ -4090,7 +4093,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
@BinderThread
private void showMySoftInput(@NonNull IBinder token, int flags) {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMMS.showMySoftInput");
- synchronized (mMethodMap) {
+ synchronized (ImfLock.class) {
if (!calledWithValidTokenLocked(token)) {
return;
}
@@ -4188,8 +4191,11 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
final IBinder token = (IBinder) args.arg3;
((IInputMethod) args.arg1).showSoftInput(
token, msg.arg1 /* flags */, (ResultReceiver) args.arg2);
- final IBinder requestToken = mShowRequestWindowMap.get(token);
- onShowHideSoftInputRequested(true /* show */, requestToken, reason);
+ final IBinder requestToken;
+ synchronized (ImfLock.class) {
+ requestToken = mShowRequestWindowMap.get(token);
+ onShowHideSoftInputRequested(true /* show */, requestToken, reason);
+ }
} catch (RemoteException e) {
}
args.recycle();
@@ -4204,14 +4210,17 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
final IBinder token = (IBinder) args.arg3;
((IInputMethod)args.arg1).hideSoftInput(
token, 0 /* flags */, (ResultReceiver) args.arg2);
- final IBinder requestToken = mHideRequestWindowMap.get(token);
- onShowHideSoftInputRequested(false /* show */, requestToken, reason);
+ final IBinder requestToken;
+ synchronized (ImfLock.class) {
+ requestToken = mHideRequestWindowMap.get(token);
+ onShowHideSoftInputRequested(false /* show */, requestToken, reason);
+ }
} catch (RemoteException e) {
}
args.recycle();
return true;
case MSG_HIDE_CURRENT_INPUT_METHOD:
- synchronized (mMethodMap) {
+ synchronized (ImfLock.class) {
final @SoftInputShowHideReason int reason = (int) msg.obj;
hideCurrentInputLocked(mCurFocusedWindow, 0, null, reason);
@@ -4221,8 +4230,10 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
args = (SomeArgs)msg.obj;
try {
if (DEBUG) {
- Slog.v(TAG, "Sending attach of token: " + args.arg2 + " for display: "
- + mCurTokenDisplayId);
+ synchronized (ImfLock.class) {
+ Slog.v(TAG, "Sending attach of token: " + args.arg2 + " for display: "
+ + mCurTokenDisplayId);
+ }
}
final IBinder token = (IBinder) args.arg2;
((IInputMethod) args.arg1).initializeInternal(token,
@@ -4249,7 +4260,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
return true;
}
case MSG_REMOVE_IME_SURFACE: {
- synchronized (mMethodMap) {
+ synchronized (ImfLock.class) {
try {
if (mEnabledSession != null && mEnabledSession.session != null
&& !mShowRequested) {
@@ -4262,7 +4273,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
case MSG_REMOVE_IME_SURFACE_FROM_WINDOW: {
IBinder windowToken = (IBinder) msg.obj;
- synchronized (mMethodMap) {
+ synchronized (ImfLock.class) {
try {
if (windowToken == mCurFocusedWindow
&& mEnabledSession != null && mEnabledSession.session != null) {
@@ -4404,7 +4415,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
private void handleSetInteractive(final boolean interactive) {
- synchronized (mMethodMap) {
+ synchronized (ImfLock.class) {
mIsInteractive = interactive;
updateSystemUiLocked(interactive ? mImeWindowVis : 0, mBackDisposition);
@@ -4428,7 +4439,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
active ? 1 : 0, fullscreen ? 1 : 0, reportToImeController ? 1 : 0, 0, state));
}
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
private boolean chooseNewDefaultIMELocked() {
final InputMethodInfo imi = InputMethodUtils.getMostApplicableDefaultIME(
mSettings.getEnabledInputMethodListLocked());
@@ -4504,7 +4515,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
}
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
void buildInputMethodListLocked(boolean resetDefaultEnabledIme) {
if (DEBUG) {
Slog.d(TAG, "--- re-buildInputMethodList reset = " + resetDefaultEnabledIme
@@ -4612,7 +4623,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
mSettings.getCurrentUserId(), 0 /* unused */, inputMethodList).sendToTarget();
}
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
private void updateDefaultVoiceImeIfNeededLocked() {
final String systemSpeechRecognizer =
mContext.getString(com.android.internal.R.string.config_systemSpeechRecognizer);
@@ -4654,7 +4665,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
intent.putExtra(Settings.EXTRA_INPUT_METHOD_ID, inputMethodId);
}
final int userId;
- synchronized (mMethodMap) {
+ synchronized (ImfLock.class) {
userId = mSettings.getCurrentUserId();
}
mContext.startActivityAsUser(intent, null, UserHandle.of(userId));
@@ -4678,7 +4689,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
* @param enabled {@code true} if {@code id} needs to be enabled.
* @return {@code true} if the IME was previously enabled. {@code false} otherwise.
*/
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
private boolean setInputMethodEnabledLocked(String id, boolean enabled) {
List<Pair<String, ArrayList<String>>> enabledInputMethodsList = mSettings
.getEnabledInputMethodsAndSubtypeListLocked();
@@ -4714,7 +4725,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
}
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
private void setSelectedInputMethodAndSubtypeLocked(InputMethodInfo imi, int subtypeId,
boolean setSubtypeOnly) {
mSettings.saveCurrentInputMethodAndSubtypeToHistory(getSelectedMethodIdLocked(),
@@ -4742,7 +4753,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
}
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
private void resetSelectedInputMethodAndSubtypeLocked(String newDefaultIme) {
InputMethodInfo imi = mMethodMap.get(newDefaultIme);
int lastSubtypeId = NOT_A_SUBTYPE_ID;
@@ -4766,7 +4777,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
*/
@Override
public InputMethodSubtype getCurrentInputMethodSubtype() {
- synchronized (mMethodMap) {
+ synchronized (ImfLock.class) {
// TODO: Make this work even for non-current users?
if (!calledFromValidUserLocked()) {
return null;
@@ -4775,7 +4786,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
}
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
InputMethodSubtype getCurrentInputMethodSubtypeLocked() {
String selectedMethodId = getSelectedMethodIdLocked();
if (selectedMethodId == null) {
@@ -4816,19 +4827,14 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
return mCurrentSubtype;
}
- @Nullable
- String getCurrentMethodId() {
- return getSelectedMethodIdLocked();
- }
-
private List<InputMethodInfo> getInputMethodListAsUser(@UserIdInt int userId) {
- synchronized (mMethodMap) {
+ synchronized (ImfLock.class) {
return getInputMethodListLocked(userId, DirectBootAwareness.AUTO);
}
}
private List<InputMethodInfo> getEnabledInputMethodListAsUser(@UserIdInt int userId) {
- synchronized (mMethodMap) {
+ synchronized (ImfLock.class) {
return getEnabledInputMethodListLocked(userId);
}
}
@@ -4836,7 +4842,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
private void onCreateInlineSuggestionsRequest(@UserIdInt int userId,
InlineSuggestionsRequestInfo requestInfo,
IInlineSuggestionsRequestCallback callback) {
- synchronized (mMethodMap) {
+ synchronized (ImfLock.class) {
onCreateInlineSuggestionsRequestLocked(userId, requestInfo, callback);
}
}
@@ -4853,7 +4859,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
private boolean switchToInputMethod(String imeId, @UserIdInt int userId) {
- synchronized (mMethodMap) {
+ synchronized (ImfLock.class) {
if (userId == mSettings.getCurrentUserId()) {
if (!mMethodMap.containsKey(imeId)
|| !mSettings.getEnabledInputMethodListLocked()
@@ -4879,7 +4885,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
private boolean setInputMethodEnabled(String imeId, boolean enabled, @UserIdInt int userId) {
- synchronized (mMethodMap) {
+ synchronized (ImfLock.class) {
if (userId == mSettings.getCurrentUserId()) {
if (!mMethodMap.containsKey(imeId)) {
return false; // IME is not found.
@@ -4911,7 +4917,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
int displayId) {
//TODO(b/150843766): Check if Input Token is valid.
final IBinder curHostInputToken;
- synchronized (mMethodMap) {
+ synchronized (ImfLock.class) {
if (displayId != mCurTokenDisplayId || mCurHostInputToken == null) {
return false;
}
@@ -4921,7 +4927,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
private void reportImeControl(@Nullable IBinder windowToken, boolean imeParentChanged) {
- synchronized (mMethodMap) {
+ synchronized (ImfLock.class) {
if (mCurFocusedWindow != windowToken) {
// mCurPerceptible was set by the focused window, but it is no longer in control,
// so we reset mCurPerceptible.
@@ -5029,7 +5035,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
throw new InvalidParameterException("contentUri must have content scheme");
}
- synchronized (mMethodMap) {
+ synchronized (ImfLock.class) {
final int uid = Binder.getCallingUid();
if (getSelectedMethodIdLocked() == null) {
return null;
@@ -5068,7 +5074,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
@BinderThread
private void reportFullscreenMode(@NonNull IBinder token, boolean fullscreen) {
- synchronized (mMethodMap) {
+ synchronized (ImfLock.class) {
if (!calledWithValidTokenLocked(token)) {
return;
}
@@ -5151,7 +5157,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
final Printer p = new PrintWriterPrinter(pw);
- synchronized (mMethodMap) {
+ synchronized (ImfLock.class) {
p.println("Current Input Method Manager state:");
int N = mMethodList.size();
p.println(" Input Methods: mMethodMapUpdateCount=" + mMethodMapUpdateCount);
@@ -5436,7 +5442,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
@BinderThread
@ShellCommandResult
private int getLastSwitchUserId(@NonNull ShellCommand shellCommand) {
- synchronized (mMethodMap) {
+ synchronized (ImfLock.class) {
shellCommand.getOutPrintWriter().println(mLastSwitchUserId);
return ShellCommandResult.SUCCESS;
}
@@ -5471,7 +5477,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
break;
}
}
- synchronized (mMethodMap) {
+ synchronized (ImfLock.class) {
final PrintWriter pr = shellCommand.getOutPrintWriter();
final int[] userIds = InputMethodUtils.resolveUserId(userIdToBeResolved,
mSettings.getCurrentUserId(), shellCommand.getErrPrintWriter());
@@ -5513,7 +5519,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
final PrintWriter out = shellCommand.getOutPrintWriter();
final PrintWriter error = shellCommand.getErrPrintWriter();
boolean hasFailed = false;
- synchronized (mMethodMap) {
+ synchronized (ImfLock.class) {
final int[] userIds = InputMethodUtils.resolveUserId(userIdToBeResolved,
mSettings.getCurrentUserId(), shellCommand.getErrPrintWriter());
for (int userId : userIds) {
@@ -5567,7 +5573,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
* @return {@code false} if it fails to enable the IME. {@code false} otherwise.
*/
@BinderThread
- @GuardedBy("mMethodMap")
+ @GuardedBy("ImfLock.class")
private boolean handleShellCommandEnableDisableInputMethodInternalLocked(
@UserIdInt int userId, String imeId, boolean enabled, PrintWriter out,
PrintWriter error) {
@@ -5637,7 +5643,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
final PrintWriter out = shellCommand.getOutPrintWriter();
final PrintWriter error = shellCommand.getErrPrintWriter();
boolean hasFailed = false;
- synchronized (mMethodMap) {
+ synchronized (ImfLock.class) {
final int[] userIds = InputMethodUtils.resolveUserId(userIdToBeResolved,
mSettings.getCurrentUserId(), shellCommand.getErrPrintWriter());
for (int userId : userIds) {
@@ -5675,7 +5681,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
private int handleShellCommandResetInputMethod(@NonNull ShellCommand shellCommand) {
final PrintWriter out = shellCommand.getOutPrintWriter();
final int userIdToBeResolved = handleOptionsForCommandsThatOnlyHaveUserOption(shellCommand);
- synchronized (mMethodMap) {
+ synchronized (ImfLock.class) {
final int[] userIds = InputMethodUtils.resolveUserId(userIdToBeResolved,
mSettings.getCurrentUserId(), shellCommand.getErrPrintWriter());
for (int userId : userIds) {
@@ -5693,11 +5699,15 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
// Also reset the settings of the current IME
mSettings.putSelectedInputMethod(null);
// Disable all enabled IMEs.
- mSettings.getEnabledInputMethodListLocked().forEach(
- imi -> setInputMethodEnabledLocked(imi.getId(), false));
+ for (InputMethodInfo inputMethodInfo :
+ mSettings.getEnabledInputMethodListLocked()) {
+ setInputMethodEnabledLocked(inputMethodInfo.getId(), false);
+ }
// Re-enable with default enabled IMEs.
- InputMethodUtils.getDefaultEnabledImes(mContext, mMethodList).forEach(
- imi -> setInputMethodEnabledLocked(imi.getId(), true));
+ for (InputMethodInfo imi :
+ InputMethodUtils.getDefaultEnabledImes(mContext, mMethodList)) {
+ setInputMethodEnabledLocked(imi.getId(), true);
+ }
updateInputMethodsFromSettingsLocked(true /* enabledMayChange */);
InputMethodUtils.setNonSelectedSystemImesDisabledUntilUsed(mIPackageManager,
mSettings.getEnabledInputMethodListLocked(),
@@ -5766,7 +5776,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
boolean isImeTraceEnabled = ImeTracing.getInstance().isEnabled();
ArrayMap<IBinder, ClientState> clients;
- synchronized (mMethodMap) {
+ synchronized (ImfLock.class) {
clients = new ArrayMap<>(mClients);
}
for (ClientState state : clients.values()) {
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodMenuController.java b/services/core/java/com/android/server/inputmethod/InputMethodMenuController.java
index f70ad0537413..132be7d11ab1 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodMenuController.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodMenuController.java
@@ -46,6 +46,7 @@ import android.widget.RadioButton;
import android.widget.Switch;
import android.widget.TextView;
+import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.LocalServices;
import com.android.server.inputmethod.InputMethodSubtypeSwitchingController.ImeSubtypeListItem;
@@ -98,7 +99,7 @@ public class InputMethodMenuController {
int lastInputMethodSubtypeId = mSettings.getSelectedInputMethodSubtypeId(lastInputMethodId);
if (DEBUG) Slog.v(TAG, "Current IME: " + lastInputMethodId);
- synchronized (mMethodMap) {
+ synchronized (ImfLock.class) {
final List<ImeSubtypeListItem> imList = mSwitchingController
.getSortedInputMethodAndSubtypeListForImeMenuLocked(
showAuxSubtypes, isScreenLocked);
@@ -112,7 +113,7 @@ public class InputMethodMenuController {
final InputMethodSubtype currentSubtype =
mService.getCurrentInputMethodSubtypeLocked();
if (currentSubtype != null) {
- final String curMethodId = mService.getCurrentMethodId();
+ final String curMethodId = mService.getSelectedMethodIdLocked();
final InputMethodInfo currentImi = mMethodMap.get(curMethodId);
lastInputMethodSubtypeId = InputMethodUtils.getSubtypeIdFromHashCode(
currentImi, currentSubtype.hashCode());
@@ -175,7 +176,7 @@ public class InputMethodMenuController {
final ImeSubtypeListAdapter adapter = new ImeSubtypeListAdapter(dialogContext,
com.android.internal.R.layout.input_method_switch_item, imList, checkedItem);
final DialogInterface.OnClickListener choiceListener = (dialog, which) -> {
- synchronized (mMethodMap) {
+ synchronized (ImfLock.class) {
if (mIms == null || mIms.length <= which || mSubtypeIds == null
|| mSubtypeIds.length <= which) {
return;
@@ -250,11 +251,12 @@ public class InputMethodMenuController {
}
void hideInputMethodMenu() {
- synchronized (mMethodMap) {
+ synchronized (ImfLock.class) {
hideInputMethodMenuLocked();
}
}
+ @GuardedBy("ImfLock.class")
void hideInputMethodMenuLocked() {
if (DEBUG) Slog.v(TAG, "Hide switching menu");
@@ -299,7 +301,7 @@ public class InputMethodMenuController {
if (DEBUG) {
Slog.w(TAG, "HardKeyboardStatusChanged: available=" + available);
}
- synchronized (mMethodMap) {
+ synchronized (ImfLock.class) {
if (mSwitchingDialog != null && mSwitchingDialogTitleView != null
&& mSwitchingDialog.isShowing()) {
mSwitchingDialogTitleView.findViewById(
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodSubtypeSwitchingController.java b/services/core/java/com/android/server/inputmethod/InputMethodSubtypeSwitchingController.java
index c340a2b77874..f8894c64304d 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodSubtypeSwitchingController.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodSubtypeSwitchingController.java
@@ -39,7 +39,7 @@ import java.util.Objects;
* InputMethodSubtypeSwitchingController controls the switching behavior of the subtypes.
*
* <p>This class is designed to be used from and only from {@link InputMethodManagerService} by
- * using {@link InputMethodManagerService#mMethodMap} as a global lock.</p>
+ * using {@link ImfLock ImfLock.class} as a global lock.</p>
*/
final class InputMethodSubtypeSwitchingController {
private static final String TAG = InputMethodSubtypeSwitchingController.class.getSimpleName();