diff options
| author | 2021-11-23 10:26:38 -0800 | |
|---|---|---|
| committer | 2022-02-01 14:09:06 -0800 | |
| commit | c809658285896757e331c869c64d1f01eb129ef9 (patch) | |
| tree | 805605f27c5e535bdb2440156282f86ccfd9e1c8 | |
| parent | 88f9f15233ef1c1debcdea6124496ab32b3968f6 (diff) | |
Use binder tokens to remove its gesture monitors if a process dies
Bug: 162194035
Test: manual: "adb shell am crash com.android.systemui" and observe its
gesture monitors are removed through dumpsys input
Change-Id: I02a480dd8e4b98a9911d976de2684d283c9e7d8b
5 files changed, 37 insertions, 16 deletions
diff --git a/core/java/android/hardware/input/IInputManager.aidl b/core/java/android/hardware/input/IInputManager.aidl index 27403ec4fe59..e1ffd4a6761d 100644 --- a/core/java/android/hardware/input/IInputManager.aidl +++ b/core/java/android/hardware/input/IInputManager.aidl @@ -112,7 +112,7 @@ interface IInputManager { oneway void requestPointerCapture(IBinder inputChannelToken, boolean enabled); /** Create an input monitor for gestures. */ - InputMonitor monitorGestureInput(String name, int displayId); + InputMonitor monitorGestureInput(IBinder token, String name, int displayId); // Add a runtime association between the input port and the display port. This overrides any // static associations. diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java index 979e9dd6a1f6..2fd79cf980c7 100644 --- a/core/java/android/hardware/input/InputManager.java +++ b/core/java/android/hardware/input/InputManager.java @@ -35,6 +35,7 @@ import android.hardware.lights.Light; import android.hardware.lights.LightState; import android.hardware.lights.LightsManager; import android.hardware.lights.LightsRequest; +import android.os.Binder; import android.os.BlockUntrustedTouchesMode; import android.os.Build; import android.os.CombinedVibration; @@ -1211,7 +1212,7 @@ public final class InputManager { */ public InputMonitor monitorGestureInput(String name, int displayId) { try { - return mIm.monitorGestureInput(name, displayId); + return mIm.monitorGestureInput(new Binder(), name, displayId); } catch (RemoteException ex) { throw ex.rethrowFromSystemServer(); } diff --git a/core/java/android/view/InputMonitor.java b/core/java/android/view/InputMonitor.java index ad1f201ba3c1..8801fe0b47c8 100644 --- a/core/java/android/view/InputMonitor.java +++ b/core/java/android/view/InputMonitor.java @@ -79,13 +79,17 @@ public final class InputMonitor implements Parcelable { - // Code below generated by codegen v1.0.7. + // Code below generated by codegen v1.0.23. // // DO NOT MODIFY! // CHECKSTYLE:OFF Generated code // // To regenerate run: // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/view/InputMonitor.java + // + // To exclude the generated code from IntelliJ auto-formatting enable (one-time): + // Settings > Editor > Code Style > Formatter Control + //@formatter:off @DataClass.Generated.Member @@ -126,7 +130,7 @@ public final class InputMonitor implements Parcelable { @Override @DataClass.Generated.Member - public void writeToParcel(Parcel dest, int flags) { + public void writeToParcel(@NonNull Parcel dest, int flags) { // You can override field parcelling by defining methods like: // void parcelFieldName(Parcel dest, int flags) { ... } @@ -141,7 +145,7 @@ public final class InputMonitor implements Parcelable { /** @hide */ @SuppressWarnings({"unchecked", "RedundantCast"}) @DataClass.Generated.Member - /* package-private */ InputMonitor(Parcel in) { + /* package-private */ InputMonitor(@NonNull Parcel in) { // You can override field unparcelling by defining methods like: // static FieldType unparcelFieldName(Parcel in) { ... } @@ -167,17 +171,21 @@ public final class InputMonitor implements Parcelable { } @Override - public InputMonitor createFromParcel(Parcel in) { + public InputMonitor createFromParcel(@NonNull Parcel in) { return new InputMonitor(in); } }; @DataClass.Generated( - time = 1571177265149L, - codegenVersion = "1.0.7", + time = 1637697281750L, + codegenVersion = "1.0.23", sourceFile = "frameworks/base/core/java/android/view/InputMonitor.java", inputSignatures = "private static final java.lang.String TAG\nprivate static final boolean DEBUG\nprivate final @android.annotation.NonNull android.view.InputChannel mInputChannel\nprivate final @android.annotation.NonNull android.view.IInputMonitorHost mHost\npublic void pilferPointers()\npublic void dispose()\nclass InputMonitor extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genToString=true)") @Deprecated private void __metadata() {} + + //@formatter:on + // End of generated code + } diff --git a/services/core/java/com/android/server/input/GestureMonitorSpyWindow.java b/services/core/java/com/android/server/input/GestureMonitorSpyWindow.java index 9d6764eb9cdf..dbd3f3529208 100644 --- a/services/core/java/com/android/server/input/GestureMonitorSpyWindow.java +++ b/services/core/java/com/android/server/input/GestureMonitorSpyWindow.java @@ -18,6 +18,7 @@ package com.android.server.input; import static android.os.InputConstants.DEFAULT_DISPATCHING_TIMEOUT_MILLIS; +import android.os.IBinder; import android.view.InputApplicationHandle; import android.view.InputChannel; import android.view.InputMonitor; @@ -37,12 +38,14 @@ class GestureMonitorSpyWindow { final InputApplicationHandle mApplicationHandle; final InputWindowHandle mWindowHandle; - // The InputChannel and SurfaceControl are owned by this object. + // The token, InputChannel, and SurfaceControl are owned by this object. + final IBinder mMonitorToken; final InputChannel mClientChannel; final SurfaceControl mInputSurface; - GestureMonitorSpyWindow(String name, int displayId, int pid, int uid, SurfaceControl sc, - InputChannel inputChannel) { + GestureMonitorSpyWindow(IBinder token, String name, int displayId, int pid, int uid, + SurfaceControl sc, InputChannel inputChannel) { + mMonitorToken = token; mClientChannel = inputChannel; mInputSurface = sc; diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java index 98c4e9db04e6..64b4da7c5bba 100644 --- a/services/core/java/com/android/server/input/InputManagerService.java +++ b/services/core/java/com/android/server/input/InputManagerService.java @@ -725,8 +725,8 @@ public class InputManagerService extends IInputManager.Stub } @NonNull - private InputChannel createSpyWindowGestureMonitor(String name, int displayId, int pid, - int uid) { + private InputChannel createSpyWindowGestureMonitor(IBinder monitorToken, String name, + int displayId, int pid, int uid) { final SurfaceControl sc = mWindowManagerCallbacks.createSurfaceForGestureMonitor(name, displayId); if (sc == null) { @@ -735,9 +735,16 @@ public class InputManagerService extends IInputManager.Stub } final InputChannel channel = createInputChannel(name); + try { + monitorToken.linkToDeath(() -> removeSpyWindowGestureMonitor(channel.getToken()), 0); + } catch (RemoteException e) { + Slog.i(TAG, "Client died before '" + name + "' could be created."); + return null; + } synchronized (mInputMonitors) { mInputMonitors.put(channel.getToken(), - new GestureMonitorSpyWindow(name, displayId, pid, uid, sc, channel)); + new GestureMonitorSpyWindow(monitorToken, name, displayId, pid, uid, sc, + channel)); } final InputChannel outInputChannel = new InputChannel(); @@ -764,12 +771,14 @@ public class InputManagerService extends IInputManager.Stub * @return The input channel. */ @Override // Binder call - public InputMonitor monitorGestureInput(@NonNull String requestedName, int displayId) { + public InputMonitor monitorGestureInput(IBinder monitorToken, @NonNull String requestedName, + int displayId) { if (!checkCallingPermission(android.Manifest.permission.MONITOR_INPUT, "monitorGestureInput()")) { throw new SecurityException("Requires MONITOR_INPUT permission"); } Objects.requireNonNull(requestedName, "name must not be null."); + Objects.requireNonNull(monitorToken, "token must not be null."); if (displayId < Display.DEFAULT_DISPLAY) { throw new IllegalArgumentException("displayId must >= 0."); @@ -782,7 +791,7 @@ public class InputManagerService extends IInputManager.Stub try { final InputChannel inputChannel = USE_SPY_WINDOW_GESTURE_MONITORS - ? createSpyWindowGestureMonitor(name, displayId, pid, uid) + ? createSpyWindowGestureMonitor(monitorToken, name, displayId, pid, uid) : nativeCreateInputMonitor(mPtr, displayId, true /*isGestureMonitor*/, requestedName, pid); return new InputMonitor(inputChannel, new InputMonitorHost(inputChannel.getToken())); |