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
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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()));
|
||||
|
||||
Reference in New Issue
Block a user