From b869c783808c4d4937727a1672b2fac81bace368 Mon Sep 17 00:00:00 2001 From: Yohei Yukawa Date: Tue, 12 Jul 2022 19:03:26 -0700 Subject: [PATCH] Protect isInputMethodPickerShown() with TEST_INPUT_METHOD permission IInputMethodManager#isInputMethodPickerShownForTest() was introduced in Android P (API 28) to verify IME picker visibility in CTS [1]. To make it clear that that IPC method must be available only for special testing purpose, this CL introduces an @hide permission android.permission.TEST_INPUT_METHOD and requires it in InputMethodManagerService#isInputMethodPickerShownForTest(). This CL grants that permission to the shell process hence CTS tests can still access to the corresponding test API by using UiAutomation#adoptShellPermissionIdentity(). [1]: I4e21625c32a0ca1abc740229efb3c7fcd97141cc eb5706183f62b9230fb1ae9eb22254a062e7869c Bug: 237317525 Test: atest CtsInputMethodTestCases Test: Manually verified as follows. 1. adb logcat -b events | grep 237317525 2. atest CtsInputMethodTestCases:InputMethodManagerTest#testIsInputMethodPickerShownProtection Ignore-AOSP-First: For a security fix Change-Id: Ie79a3e9d41ce22605ae083594d639c37d08b7def --- .../internal/view/IInputMethodManager.aidl | 4 ++++ core/res/AndroidManifest.xml | 5 +++++ packages/Shell/AndroidManifest.xml | 3 +++ .../inputmethod/InputMethodManagerService.java | 15 +++++++++++++++ 4 files changed, 27 insertions(+) diff --git a/core/java/com/android/internal/view/IInputMethodManager.aidl b/core/java/com/android/internal/view/IInputMethodManager.aidl index 4ddbaa6cb0af1..718f36f9a8985 100644 --- a/core/java/com/android/internal/view/IInputMethodManager.aidl +++ b/core/java/com/android/internal/view/IInputMethodManager.aidl @@ -81,7 +81,11 @@ interface IInputMethodManager { int auxiliarySubtypeMode, int displayId); void showInputMethodAndSubtypeEnablerFromClient(in IInputMethodClient client, String topId); + + @JavaPassthrough(annotation="@android.annotation.RequiresPermission(value = " + + "android.Manifest.permission.TEST_INPUT_METHOD)") boolean isInputMethodPickerShownForTest(); + InputMethodSubtype getCurrentInputMethodSubtype(); void setAdditionalInputMethodSubtypes(String id, in InputMethodSubtype[] subtypes); // This is kept due to @UnsupportedAppUsage. diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index c2fcd1d0612af..81808647f18e1 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -4068,6 +4068,11 @@ + + + + + + diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java index 4886e6e14c17c..411bfbe6324a0 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java @@ -294,6 +294,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub final IWindowManager mIWindowManager; private final SparseBooleanArray mLoggedDeniedGetInputMethodWindowVisibleHeightForUid = new SparseBooleanArray(0); + private final SparseBooleanArray mLoggedDeniedIsInputMethodPickerShownForTestForUid = + new SparseBooleanArray(0); final WindowManagerInternal mWindowManagerInternal; final PackageManagerInternal mPackageManagerInternal; final InputManagerInternal mInputManagerInternal; @@ -1465,6 +1467,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub public void onUidRemoved(int uid) { synchronized (ImfLock.class) { mLoggedDeniedGetInputMethodWindowVisibleHeightForUid.delete(uid); + mLoggedDeniedIsInputMethodPickerShownForTestForUid.delete(uid); } } @@ -4038,6 +4041,18 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub * A test API for CTS to make sure that the input method menu is showing. */ public boolean isInputMethodPickerShownForTest() { + if (mContext.checkCallingPermission(android.Manifest.permission.TEST_INPUT_METHOD) + != PackageManager.PERMISSION_GRANTED) { + final int callingUid = Binder.getCallingUid(); + synchronized (ImfLock.class) { + if (!mLoggedDeniedIsInputMethodPickerShownForTestForUid.get(callingUid)) { + EventLog.writeEvent(0x534e4554, "237317525", callingUid, ""); + mLoggedDeniedIsInputMethodPickerShownForTestForUid.put(callingUid, true); + } + } + throw new SecurityException( + "isInputMethodPickerShownForTest requires TEST_INPUT_METHOD permission"); + } synchronized (ImfLock.class) { return mMenuController.isisInputMethodPickerShownForTestLocked(); }