From f1a82ef0ef906444a03755b56820a679de92c14e Mon Sep 17 00:00:00 2001 From: Prabir Pradhan Date: Thu, 24 Feb 2022 06:32:49 -0800 Subject: [PATCH] Configure handwriting window with the IME's pid and uid for ANRs When starting a handwriting session, update the handwriting input window so that it is configured with the IME's pid and uid. This means any ANRs that occur due to the handwriting input window will be directed to the IME process. Since oneway binder calls do not have pid information, we cannot use Binder.getCallingPid() to get the pid of the IME. Instead, we report the pid from IMS when starting handwriting. Bug: 210978621 Test: manual with custom IME, verify ANR is directed to IME. Change-Id: Ia6963eb02cad22c7f604896e6c78ed31c84e32f6 Merged-In: Ia6963eb02cad22c7f604896e6c78ed31c84e32f6 (cherry picked from commit 58df52232a31ab27fcc995c3223999ba526a8dd1) --- .../inputmethodservice/InputMethodService.java | 3 ++- .../IInputMethodPrivilegedOperations.aidl | 2 +- .../InputMethodPrivilegedOperations.java | 6 +++--- .../HandwritingEventReceiverSurface.java | 13 +++++++------ .../inputmethod/HandwritingModeController.java | 4 ++-- .../inputmethod/InputMethodManagerService.java | 13 ++++++++----- 6 files changed, 23 insertions(+), 18 deletions(-) diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java index c3e3180b6717c..fbc0732affe1c 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -83,6 +83,7 @@ import android.os.Bundle; import android.os.Handler; import android.os.IBinder; import android.os.Looper; +import android.os.Process; import android.os.ResultReceiver; import android.os.SystemClock; import android.os.SystemProperties; @@ -926,7 +927,7 @@ public class InputMethodService extends AbstractInputMethodService { mOnPreparedStylusHwCalled = true; } if (onStartStylusHandwriting()) { - mPrivOps.onStylusHandwritingReady(requestId); + mPrivOps.onStylusHandwritingReady(requestId, Process.myPid()); } else { Log.i(TAG, "IME is not ready. Can't start Stylus Handwriting"); // TODO(b/210039666): see if it's valuable to propagate this back to IMM. diff --git a/core/java/com/android/internal/inputmethod/IInputMethodPrivilegedOperations.aidl b/core/java/com/android/internal/inputmethod/IInputMethodPrivilegedOperations.aidl index 30853bc2ecc54..b18c98b58516d 100644 --- a/core/java/com/android/internal/inputmethod/IInputMethodPrivilegedOperations.aidl +++ b/core/java/com/android/internal/inputmethod/IInputMethodPrivilegedOperations.aidl @@ -42,6 +42,6 @@ oneway interface IInputMethodPrivilegedOperations { void shouldOfferSwitchingToNextInputMethod(in AndroidFuture future /* T=Boolean */); void notifyUserActionAsync(); void applyImeVisibilityAsync(IBinder showOrHideInputToken, boolean setVisible); - void onStylusHandwritingReady(int requestId); + void onStylusHandwritingReady(int requestId, int pid); void finishStylusHandwriting(int requestId); } diff --git a/core/java/com/android/internal/inputmethod/InputMethodPrivilegedOperations.java b/core/java/com/android/internal/inputmethod/InputMethodPrivilegedOperations.java index 2a7e1dcedd436..e8a2d810d563d 100644 --- a/core/java/com/android/internal/inputmethod/InputMethodPrivilegedOperations.java +++ b/core/java/com/android/internal/inputmethod/InputMethodPrivilegedOperations.java @@ -396,16 +396,16 @@ public final class InputMethodPrivilegedOperations { } /** - * Calls {@link IInputMethodPrivilegedOperations#onStylusHandwritingReady()} + * Calls {@link IInputMethodPrivilegedOperations#onStylusHandwritingReady(int, int)} */ @AnyThread - public void onStylusHandwritingReady(int requestId) { + public void onStylusHandwritingReady(int requestId, int pid) { final IInputMethodPrivilegedOperations ops = mOps.getAndWarnIfNull(); if (ops == null) { return; } try { - ops.onStylusHandwritingReady(requestId); + ops.onStylusHandwritingReady(requestId, pid); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java b/services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java index 9846a2ba48a4e..3c454080ef1c2 100644 --- a/services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java +++ b/services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java @@ -82,13 +82,14 @@ final class HandwritingEventReceiverSurface { mIsIntercepting = false; } - void startIntercepting() { - // TODO(b/210978621): Update the spy window's PID and UID to be associated with the IME so - // that ANRs are correctly attributed to the IME. - final SurfaceControl.Transaction t = new SurfaceControl.Transaction(); + void startIntercepting(int imePid, int imeUid) { + mWindowHandle.ownerPid = imePid; + mWindowHandle.ownerUid = imeUid; mWindowHandle.inputFeatures &= ~WindowManager.LayoutParams.INPUT_FEATURE_SPY; - t.setInputWindowInfo(mInputSurface, mWindowHandle); - t.apply(); + + new SurfaceControl.Transaction() + .setInputWindowInfo(mInputSurface, mWindowHandle) + .apply(); mIsIntercepting = true; } diff --git a/services/core/java/com/android/server/inputmethod/HandwritingModeController.java b/services/core/java/com/android/server/inputmethod/HandwritingModeController.java index d31f7c5b07df4..b301d99b00de5 100644 --- a/services/core/java/com/android/server/inputmethod/HandwritingModeController.java +++ b/services/core/java/com/android/server/inputmethod/HandwritingModeController.java @@ -136,7 +136,7 @@ final class HandwritingModeController { */ @UiThread @Nullable - HandwritingSession startHandwritingSession(int requestId) { + HandwritingSession startHandwritingSession(int requestId, int imePid, int imeUid) { if (mHandwritingSurface == null) { Slog.e(TAG, "Cannot start handwriting session: Handwriting was not initialized."); return null; @@ -160,7 +160,7 @@ final class HandwritingModeController { throw new IllegalStateException( "Handwriting surface should not be already intercepting."); } - mHandwritingSurface.startIntercepting(); + mHandwritingSurface.startIntercepting(imePid, imeUid); return new HandwritingSession(mCurrentRequestId, mHandwritingSurface.getInputChannel(), mHandwritingBuffer); diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java index eb1de2a9bf915..efe99d7611f9e 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java @@ -4702,7 +4702,10 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub return true; } final HandwritingModeController.HandwritingSession session = - mHwController.startHandwritingSession(msg.arg1); + mHwController.startHandwritingSession( + msg.arg1 /*requestId*/, + msg.arg2 /*pid*/, + mBindingController.getCurMethodUid()); if (session == null) { Slog.e(TAG, "Failed to start handwriting session for requestId: " + msg.arg1); @@ -4722,8 +4725,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub } @BinderThread - private void onStylusHandwritingReady(int requestId) { - mHandler.obtainMessage(MSG_START_HANDWRITING, requestId, 0 /* unused */).sendToTarget(); + private void onStylusHandwritingReady(int requestId, int pid) { + mHandler.obtainMessage(MSG_START_HANDWRITING, requestId, pid).sendToTarget(); } private void handleSetInteractive(final boolean interactive) { @@ -6304,8 +6307,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub @BinderThread @Override - public void onStylusHandwritingReady(int requestId) { - mImms.onStylusHandwritingReady(requestId); + public void onStylusHandwritingReady(int requestId, int pid) { + mImms.onStylusHandwritingReady(requestId, pid); } @BinderThread