From 9df1f523f1193a653df37d27cfc1b91179b5204f Mon Sep 17 00:00:00 2001 From: Adrian Roos Date: Wed, 16 Feb 2022 18:57:24 +0100 Subject: [PATCH] Restrict getInputMethodWindowVisibleHeight Make sure only the app currently interacting with the IME can query this, and restrict the API to apps targeting SDKs before T Fixes: 204906124 Test: atest 'InputMethodManagerTest#getInputMethodWindowVisibleHeight_returnsZeroIfNotFocused' Change-Id: If1da19a3dd8c29542afc970b4b201d87547c27a9 --- .../view/inputmethod/InputMethodManager.java | 5 ++- .../internal/view/IInputMethodManager.aidl | 2 +- .../InputMethodManagerService.java | 37 +++++++++++++++---- 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java index 2359d8d67f672..34107a202a4e8 100644 --- a/core/java/android/view/inputmethod/InputMethodManager.java +++ b/core/java/android/view/inputmethod/InputMethodManager.java @@ -3220,10 +3220,11 @@ public final class InputMethodManager { * @return Something that is not well-defined. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(trackingBug = 204906124, maxTargetSdk = Build.VERSION_CODES.TIRAMISU, + publicAlternatives = "Use {@link android.view.WindowInsets} instead") public int getInputMethodWindowVisibleHeight() { try { - return mService.getInputMethodWindowVisibleHeight(); + return mService.getInputMethodWindowVisibleHeight(mClient); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/core/java/com/android/internal/view/IInputMethodManager.aidl b/core/java/com/android/internal/view/IInputMethodManager.aidl index 0df3e870b80cf..c5346b95440ba 100644 --- a/core/java/com/android/internal/view/IInputMethodManager.aidl +++ b/core/java/com/android/internal/view/IInputMethodManager.aidl @@ -67,7 +67,7 @@ interface IInputMethodManager { void setAdditionalInputMethodSubtypes(String id, in InputMethodSubtype[] subtypes); // This is kept due to @UnsupportedAppUsage. // TODO(Bug 113914148): Consider removing this. - int getInputMethodWindowVisibleHeight(); + int getInputMethodWindowVisibleHeight(in IInputMethodClient client); oneway void reportPerceptibleAsync(in IBinder windowToken, boolean perceptible); /** Remove the IME surface. Requires INTERNAL_SYSTEM_WINDOW permission. */ diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java index 0b7e39136feb3..e9c33489aec89 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java @@ -122,6 +122,7 @@ import android.util.PrintWriterPrinter; import android.util.Printer; import android.util.Slog; import android.util.SparseArray; +import android.util.SparseBooleanArray; import android.util.proto.ProtoOutputStream; import android.view.IWindowManager; import android.view.InputChannel; @@ -276,6 +277,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub final InputMethodSettings mSettings; final SettingsObserver mSettingsObserver; final IWindowManager mIWindowManager; + private final SparseBooleanArray mLoggedDeniedGetInputMethodWindowVisibleHeightForUid = + new SparseBooleanArray(0); final WindowManagerInternal mWindowManagerInternal; final PackageManagerInternal mPackageManagerInternal; final InputManagerInternal mInputManagerInternal; @@ -1381,6 +1384,13 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub clearPackageChangeState(); } + @Override + public void onUidRemoved(int uid) { + synchronized (ImfLock.class) { + mLoggedDeniedGetInputMethodWindowVisibleHeightForUid.delete(uid); + } + } + private void clearPackageChangeState() { // No need to lock them because we access these fields only on getRegisteredHandler(). mChangedPackages.clear(); @@ -4145,13 +4155,26 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub * @return {@link WindowManagerInternal#getInputMethodWindowVisibleHeight(int)} */ @Override - public int getInputMethodWindowVisibleHeight() { - // TODO(yukawa): Should we verify the display ID? - final int curTokenDisplayId; - synchronized (ImfLock.class) { - curTokenDisplayId = mCurTokenDisplayId; - } - return mWindowManagerInternal.getInputMethodWindowVisibleHeight(curTokenDisplayId); + @Deprecated + public int getInputMethodWindowVisibleHeight(@NonNull IInputMethodClient client) { + int callingUid = Binder.getCallingUid(); + return Binder.withCleanCallingIdentity(() -> { + final int curTokenDisplayId; + synchronized (ImfLock.class) { + if (!canInteractWithImeLocked(callingUid, client, + "getInputMethodWindowVisibleHeight")) { + if (!mLoggedDeniedGetInputMethodWindowVisibleHeightForUid.get(callingUid)) { + EventLog.writeEvent(0x534e4554, "204906124", callingUid, ""); + mLoggedDeniedGetInputMethodWindowVisibleHeightForUid.put(callingUid, true); + } + return 0; + } + // This should probably use the caller's display id, but because this is unsupported + // and maintained only for compatibility, there's no point in fixing it. + curTokenDisplayId = mCurTokenDisplayId; + } + return mWindowManagerInternal.getInputMethodWindowVisibleHeight(curTokenDisplayId); + }); } @Override