Fix for bug #34905789
A call to showInputMethodPickerFromClient should be allowed only if the
caller is:
* The system service, as system services should have the privilege to
show any dialogs
* The current IME client, as it was already enabled by the user
* The app on the foreground, as the user cannot distinguish the source
of the request (i.e., foreground vs background app) and might be
mislead by a background app to change settings
* A process with the android.Manifest.permission.WRITE_SECURE_SETTINGS
permission, as it already has the permission to change settings
Fixes: 34905789
Test: manual
Change-Id: I4f0fc21268200c64d12b31ca54416acfbf62f37b
diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java
index bff39b3..a8e2f32 100644
--- a/services/core/java/com/android/server/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/InputMethodManagerService.java
@@ -2788,6 +2788,27 @@
return res;
}
+ private boolean canShowInputMethodPickerLocked(IInputMethodClient client) {
+ final int uid = Binder.getCallingUid();
+ if (UserHandle.getAppId(uid) == Process.SYSTEM_UID) {
+ return true;
+ } else if (mCurClient != null && client != null
+ && mCurClient.client.asBinder() == client.asBinder()) {
+ return true;
+ } else if (mCurIntent != null && InputMethodUtils.checkIfPackageBelongsToUid(
+ mAppOpsManager,
+ uid,
+ mCurIntent.getComponent().getPackageName())) {
+ return true;
+ } else if (mContext.checkCallingPermission(
+ android.Manifest.permission.WRITE_SECURE_SETTINGS)
+ == PackageManager.PERMISSION_GRANTED) {
+ return true;
+ }
+
+ return false;
+ }
+
@Override
public void showInputMethodPickerFromClient(
IInputMethodClient client, int auxiliarySubtypeMode) {
@@ -2795,10 +2816,10 @@
return;
}
synchronized (mMethodMap) {
- if (mCurClient == null || client == null
- || mCurClient.client.asBinder() != client.asBinder()) {
+ if(!canShowInputMethodPickerLocked(client)) {
Slog.w(TAG, "Ignoring showInputMethodPickerFromClient of uid "
+ Binder.getCallingUid() + ": " + client);
+ return;
}
// Always call subtype picker, because subtype picker is a superset of input method