diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java index 14a5e3bd1417a..15088d2070d23 100644 --- a/core/java/android/view/inputmethod/InputMethodManager.java +++ b/core/java/android/view/inputmethod/InputMethodManager.java @@ -27,6 +27,7 @@ import android.annotation.SystemService; import android.annotation.TestApi; import android.annotation.UnsupportedAppUsage; import android.app.ActivityThread; +import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; import android.content.pm.PackageManager; @@ -2492,11 +2493,48 @@ public final class InputMethodManager { */ @RequiresPermission(WRITE_SECURE_SETTINGS) public boolean setCurrentInputMethodSubtype(InputMethodSubtype subtype) { - try { - return mService.setCurrentInputMethodSubtype(subtype); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + if (Process.myUid() == Process.SYSTEM_UID) { + Log.w(TAG, "System process should not call setCurrentInputMethodSubtype() because " + + "almost always it is a bug under multi-user / multi-profile environment. " + + "Consider directly interacting with InputMethodManagerService " + + "via LocalServices."); + return false; } + if (subtype == null) { + // See the JavaDoc. This is how this method has worked. + return false; + } + final Context fallbackContext = ActivityThread.currentApplication(); + if (fallbackContext == null) { + return false; + } + if (fallbackContext.checkSelfPermission(WRITE_SECURE_SETTINGS) + != PackageManager.PERMISSION_GRANTED) { + return false; + } + final ContentResolver contentResolver = fallbackContext.getContentResolver(); + final String imeId = Settings.Secure.getString(contentResolver, + Settings.Secure.DEFAULT_INPUT_METHOD); + if (ComponentName.unflattenFromString(imeId) == null) { + // Null or invalid IME ID format. + return false; + } + final List enabledSubtypes; + try { + enabledSubtypes = mService.getEnabledInputMethodSubtypeList(imeId, true); + } catch (RemoteException e) { + return false; + } + final int numSubtypes = enabledSubtypes.size(); + for (int i = 0; i < numSubtypes; ++i) { + final InputMethodSubtype enabledSubtype = enabledSubtypes.get(i); + if (enabledSubtype.equals(subtype)) { + Settings.Secure.putInt(contentResolver, + Settings.Secure.SELECTED_INPUT_METHOD_SUBTYPE, enabledSubtype.hashCode()); + return true; + } + } + return false; } /** diff --git a/core/java/com/android/internal/view/IInputMethodManager.aidl b/core/java/com/android/internal/view/IInputMethodManager.aidl index 8194a920d3319..0752efe562a96 100644 --- a/core/java/com/android/internal/view/IInputMethodManager.aidl +++ b/core/java/com/android/internal/view/IInputMethodManager.aidl @@ -64,7 +64,6 @@ interface IInputMethodManager { void showInputMethodAndSubtypeEnablerFromClient(in IInputMethodClient client, String topId); boolean isInputMethodPickerShownForTest(); InputMethodSubtype getCurrentInputMethodSubtype(); - boolean setCurrentInputMethodSubtype(in InputMethodSubtype subtype); void setAdditionalInputMethodSubtypes(String id, in InputMethodSubtype[] subtypes); // This is kept due to @UnsupportedAppUsage. // TODO(Bug 113914148): Consider removing this. diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java index eca371a78750a..3fd3945fc87df 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java @@ -4106,25 +4106,6 @@ public class InputMethodManagerService extends IInputMethodManager.Stub return mCurrentSubtype; } - @Override - public boolean setCurrentInputMethodSubtype(InputMethodSubtype subtype) { - synchronized (mMethodMap) { - // TODO: Make this work even for non-current users? - if (!calledFromValidUserLocked()) { - return false; - } - if (subtype != null && mCurMethodId != null) { - InputMethodInfo imi = mMethodMap.get(mCurMethodId); - int subtypeId = InputMethodUtils.getSubtypeIdFromHashCode(imi, subtype.hashCode()); - if (subtypeId != NOT_A_SUBTYPE_ID) { - setInputMethodLocked(mCurMethodId, subtypeId); - return true; - } - } - return false; - } - } - private List getInputMethodListAsUser(@UserIdInt int userId) { synchronized (mMethodMap) { return getInputMethodListLocked(userId); diff --git a/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java index a31b3b4b3b5aa..3222143fc89f5 100644 --- a/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java @@ -1517,13 +1517,6 @@ public final class MultiClientInputMethodManagerService { return null; } - @BinderThread - @Override - public boolean setCurrentInputMethodSubtype(InputMethodSubtype subtype) { - reportNotSupported(); - return false; - } - @BinderThread @Override public void setAdditionalInputMethodSubtypes(String imiId, InputMethodSubtype[] subtypes) {